diff options
author | Akira Kakuto <kakuto@fuk.kindai.ac.jp> | 2015-12-16 14:50:11 +0000 |
---|---|---|
committer | Akira Kakuto <kakuto@fuk.kindai.ac.jp> | 2015-12-16 14:50:11 +0000 |
commit | 621273b5ef8cc9e83d9aca07bf012f727ba26f15 (patch) | |
tree | 0b5cb28eec37e3e0e93a09729cbc30834166a5f9 /Build/source | |
parent | f04f01782aebac8cb2fcde278c02a4fb3be4bb12 (diff) |
web2c/luatexdir: LuaTeX beta-0.86.0 (Sync with the upstream).
git-svn-id: svn://tug.org/texlive/trunk@39116 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source')
167 files changed, 14497 insertions, 15193 deletions
diff --git a/Build/source/texk/web2c/luatexdir/NEWS b/Build/source/texk/web2c/luatexdir/NEWS index d99f071d993..6d643eac977 100644 --- a/Build/source/texk/web2c/luatexdir/NEWS +++ b/Build/source/texk/web2c/luatexdir/NEWS @@ -1,6 +1,33 @@ This file is in the public domain. + + + +Upcoming LuaTeX Release 0.86 + +(major changes) + +- image data no longer stored in format (was fragile anyway) +- pdf backend data no longer stored in format + +- (incomplete) \mag support removed from pdf backend (kept in dvi mode) + +- all kind of (efficiency) improvements +- some pending issues done (behind the screens) + +- \nospace=1 will not inject glue for spaces (not even zero glue) +- \nospace=2 will inject zero glue for spaces + +- no longer keep track of older math character and delimiter definition states + +- only ^^ ^^^^XXXX ^^^^^^XXXXXX supported +- texio.setescape(0) disables escaping to terminal + +- lc codes saved with language + + + ============================================================== Luatex beta-0.85.0 was released 2015111400 (5550) ============================================================== @@ -2564,7 +2591,7 @@ Other news: we probably introduced new problems as well). * Most (all?) files now have a corrected Copyright header, - and link in $Id: NEWS 5550 2015-11-19 13:23:59Z luigi $ and $URL: https://foundry.supelec.fr/svn/luatex/trunk/source/texk/web2c/luatexdir/NEWS $ into the object file. + and link in $Id: NEWS 5624 2015-12-15 21:49:14Z luigi $ and $URL: https://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/libluatex.am b/Build/source/texk/web2c/luatexdir/am/libluatex.am index 6fffb43de4a..b512cffcc11 100644 --- a/Build/source/texk/web2c/luatexdir/am/libluatex.am +++ b/Build/source/texk/web2c/luatexdir/am/libluatex.am @@ -214,8 +214,6 @@ dist_libluatex_sources += \ ## luatex_lua_ctangle = $(ctangle_silent)CWEBINPUTS=$(srcdir)/luatexdir/lua $(ctangle) -luagen.c: ctangle$(EXEEXT) luatexdir/lua/luagen.w - $(luatex_lua_ctangle) luagen.w luainit.c: ctangle$(EXEEXT) luatexdir/lua/luainit.w $(luatex_lua_ctangle) luainit.w luajitstuff.c: ctangle$(EXEEXT) luatexdir/lua/luajitstuff.w @@ -231,11 +229,13 @@ texluac.c: ctangle$(EXEEXT) luatexdir/lua/texluac.w texluajitc.c: ctangle$(EXEEXT) luatexdir/lua/texluajitc.w $(luatex_lua_ctangle) texluajitc.w -libluatex_web += luatexdir/lua/luagen.w luatexdir/lua/luainit.w luatexdir/lua/luajitstuff.w +libluatex_web += luatexdir/lua/luainit.w luatexdir/lua/luajitstuff.w libluatex_web += luatexdir/lua/luanode.w luatexdir/lua/luastuff.w luatexdir/lua/luatoken.w libluatex_web += luatexdir/lua/texluac.w luatexdir/lua/texluajitc.w -nodist_libluatex_sources += luagen.c luainit.c luanode.c luatoken.c +nodist_libluatex_sources += luainit.c luanode.c luatoken.c + + dist_libluatex_sources += \ luatexdir/lua/lcallbacklib.c \ @@ -254,9 +254,7 @@ dist_libluatex_sources += \ luatexdir/lua/lstatslib.c \ luatexdir/lua/ltexiolib.c \ luatexdir/lua/ltexlib.c \ - luatexdir/lua/ltokenlib.c \ luatexdir/lua/lnewtokenlib.c \ - luatexdir/lua/luagen.h \ luatexdir/lua/luatex-api.h ## from luatexdir/pdf @@ -287,8 +285,6 @@ pdflistout.c: ctangle$(EXEEXT) luatexdir/pdf/pdflistout.w $(luatex_pdf_ctangle) pdflistout.w pdfliteral.c: ctangle$(EXEEXT) luatexdir/pdf/pdfliteral.w $(luatex_pdf_ctangle) pdfliteral.w -pdfluaapi.c: ctangle$(EXEEXT) luatexdir/pdf/pdfluaapi.w - $(luatex_pdf_ctangle) pdfluaapi.w pdfobj.c: ctangle$(EXEEXT) luatexdir/pdf/pdfobj.w $(luatex_pdf_ctangle) pdfobj.w pdfoutline.c: ctangle$(EXEEXT) luatexdir/pdf/pdfoutline.w @@ -314,7 +310,7 @@ libluatex_web += luatexdir/pdf/pdfpagetree.w luatexdir/pdf/pdfaction.w luatexdir libluatex_web += luatexdir/pdf/pdfcolorstack.w luatexdir/pdf/pdfdest.w libluatex_web += luatexdir/pdf/pdffont.w luatexdir/pdf/pdfgen.w luatexdir/pdf/pdfglyph.w libluatex_web += luatexdir/pdf/pdfimage.w luatexdir/pdf/pdflink.w luatexdir/pdf/pdflistout.w -libluatex_web += luatexdir/pdf/pdfliteral.w luatexdir/pdf/pdfluaapi.w luatexdir/pdf/pdfobj.w +libluatex_web += luatexdir/pdf/pdfliteral.w luatexdir/pdf/pdfobj.w libluatex_web += luatexdir/pdf/pdfoutline.w luatexdir/pdf/pdfpage.w luatexdir/pdf/pdfrule.w libluatex_web += luatexdir/pdf/pdfsaverestore.w luatexdir/pdf/pdfsetmatrix.w libluatex_web += luatexdir/pdf/pdfshipout.w luatexdir/pdf/pdftables.w @@ -322,7 +318,7 @@ libluatex_web += luatexdir/pdf/pdfthread.w luatexdir/pdf/pdfxform.w nodist_libluatex_sources += pdfpagetree.c pdfaction.c pdfannot.c pdfcolorstack.c pdfdest.c pdffont.c nodist_libluatex_sources += pdfgen.c pdfglyph.c pdfimage.c pdflink.c pdflistout.c pdfliteral.c -nodist_libluatex_sources += pdfluaapi.c pdfobj.c pdfoutline.c pdfpage.c pdfrule.c pdfsaverestore.c +nodist_libluatex_sources += pdfobj.c pdfoutline.c pdfpage.c pdfrule.c pdfsaverestore.c nodist_libluatex_sources += pdfsetmatrix.c pdfshipout.c pdftables.c pdfthread.c pdfxform.c dist_libluatex_sources += \ @@ -338,7 +334,6 @@ dist_libluatex_sources += \ luatexdir/pdf/pdflink.h \ luatexdir/pdf/pdflistout.h \ luatexdir/pdf/pdfliteral.h \ - luatexdir/pdf/pdfluaapi.h \ luatexdir/pdf/pdfobj.h \ luatexdir/pdf/pdfoutline.h \ luatexdir/pdf/pdfpage.h \ @@ -351,36 +346,44 @@ dist_libluatex_sources += \ luatexdir/pdf/pdftypes.h \ luatexdir/pdf/pdfxform.h +################################################################################ +################################################################################ +################################################################################ +## REMOVED +## but still left as example. ## from luatexdir/scripts ## -luatex_luascripts_ctangle = $(ctangle_silent)CWEBINPUTS=$(srcdir)/luatexdir/luascripts $(ctangle) - -txt2zlib.c: ctangle$(EXEEXT) luatexdir/luascripts/txt2zlib.w - $(luatex_luascripts_ctangle) txt2zlib.w - -libluatex_web += \ - luatexdir/luascripts/pdflua.c \ - luatexdir/luascripts/pdflua.lua \ - luatexdir/luascripts/txt2zlib.w - -## We normaly use the auxiliary program txt2zlib to create pdflua.c -## from luatexdir/luascripts/pdflua.lua. When cross compiling we -## use instead the distributed luatexdir/luascripts/pdflua.c. -if cross -pdflua.c: luatexdir/luascripts/pdflua.c - $(AM_V_GEN)rm -f pdflua.c; \ - $(LN_S) $(srcdir)/luatexdir/luascripts/pdflua.c pdflua.c -else !cross -pdflua.c: txt2zlib$(EXEEXT) luatexdir/luascripts/pdflua.lua - $(AM_V_GEN)./txt2zlib $(srcdir)/luatexdir/luascripts/pdflua.lua pdflua.c && \ - cmp -s pdflua.c $(srcdir)/luatexdir/luascripts/pdflua.c || \ - cp -f pdflua.c $(srcdir)/luatexdir/luascripts/pdflua.c -endif !cross - -nodist_libluatex_sources += pdflua.c - -dist_libluatex_sources += \ - luatexdir/luascripts/pdflua.h +# luatex_luascripts_ctangle = $(ctangle_silent)CWEBINPUTS=$(srcdir)/luatexdir/luascripts $(ctangle) + +# txt2zlib.c: ctangle$(EXEEXT) luatexdir/luascripts/txt2zlib.w +# $(luatex_luascripts_ctangle) txt2zlib.w + +# libluatex_web += \ +# luatexdir/luascripts/pdflua.c \ +# luatexdir/luascripts/pdflua.lua \ +# luatexdir/luascripts/txt2zlib.w + +# ## We normaly use the auxiliary program txt2zlib to create pdflua.c +# ## from luatexdir/luascripts/pdflua.lua. When cross compiling we +# ## use instead the distributed luatexdir/luascripts/pdflua.c. +# if cross +# pdflua.c: luatexdir/luascripts/pdflua.c +# $(AM_V_GEN)rm -f pdflua.c; \ +# $(LN_S) $(srcdir)/luatexdir/luascripts/pdflua.c pdflua.c +# else !cross +# pdflua.c: txt2zlib$(EXEEXT) luatexdir/luascripts/pdflua.lua +# $(AM_V_GEN)./txt2zlib $(srcdir)/luatexdir/luascripts/pdflua.lua pdflua.c && \ +# cmp -s pdflua.c $(srcdir)/luatexdir/luascripts/pdflua.c || \ +# cp -f pdflua.c $(srcdir)/luatexdir/luascripts/pdflua.c +# endif !cross + +# nodist_libluatex_sources += pdflua.c + +# dist_libluatex_sources += \ +# luatexdir/luascripts/pdflua.h +################################################################################ +################################################################################ +################################################################################ ## from luatexdir/tex ## diff --git a/Build/source/texk/web2c/luatexdir/am/txt2zlib.am b/Build/source/texk/web2c/luatexdir/am/txt2zlib.am deleted file mode 100644 index 42bc7be964f..00000000000 --- a/Build/source/texk/web2c/luatexdir/am/txt2zlib.am +++ /dev/null @@ -1,20 +0,0 @@ -## texk/web2c/luatexdir/am/txt2zlib.am: Makefile fragment for txt2zlib. -## -## Copyright (C) 2010, 2011 Hartmut Henkel <hartmut@luatex.org> -## You may freely use, modify and/or distribute this file. - -if LUATEX -if !cross -noinst_PROGRAMS += txt2zlib -endif !cross -endif LUATEX -EXTRA_PROGRAMS += txt2zlib - -nodist_txt2zlib_SOURCES = txt2zlib.c - -txt2zlib_CPPFLAGS = $(ZLIB_INCLUDES) -txt2zlib_DEPENDENCIES = $(ZLIB_DEPEND) -txt2zlib_LDADD = $(ZLIB_LIBS) - -DISTCLEANFILES += txt2zlib.c - diff --git a/Build/source/texk/web2c/luatexdir/dvi/dvigen.w b/Build/source/texk/web2c/luatexdir/dvi/dvigen.w index ce38db7c4c2..0a3ca08ea14 100644 --- a/Build/source/texk/web2c/luatexdir/dvi/dvigen.w +++ b/Build/source/texk/web2c/luatexdir/dvi/dvigen.w @@ -43,7 +43,6 @@ #define tracing_output int_par(tracing_output_code) #define tracing_stats int_par(tracing_stats_code) #define tracing_online int_par(tracing_online_code) -#define page_direction int_par(page_direction_code) #define page_width dimen_par(page_width_code) #define page_height dimen_par(page_height_code) #define page_left_offset dimen_par(page_left_offset_code) @@ -1055,7 +1054,7 @@ that a \.{DVI}-reading program will push onto its coordinate stack. void dvi_place_rule(PDF pdf, halfword q, scaledpos size) { synch_dvi_with_pos(pdf->posstruct->pos); - if ((subtype(q) == box_rule) || (subtype(q) == image_rule) || (subtype(q) == empty_rule)) { + if ((subtype(q) >= box_rule) && (subtype(q) <= user_rule)) { /* place nothing, only take space */ if (textdir_is_L(pdf->posstruct->dir)) dvi.h += size.h; diff --git a/Build/source/texk/web2c/luatexdir/font/dofont.w b/Build/source/texk/web2c/luatexdir/font/dofont.w index 28693ac1fc1..db4c2a5ebf0 100644 --- a/Build/source/texk/web2c/luatexdir/font/dofont.w +++ b/Build/source/texk/web2c/luatexdir/font/dofont.w @@ -67,7 +67,7 @@ static int do_define_font(int f, const char *cnom, scaled s, int natural_dir) destroy_saved_callback(callback_id); /* |lua_pop(Luas, 1);| *//* done by |font_from_lua| */ } else if (t == LUA_TNUMBER) { - r=(int)lua_tonumber(Luas, -1); + r = (int) lua_tointeger(Luas, -1); destroy_saved_callback(callback_id); delete_font(f); lua_pop(Luas, 1); diff --git a/Build/source/texk/web2c/luatexdir/font/luafont.w b/Build/source/texk/web2c/luatexdir/font/luafont.w index e72cbc615ed..4c26ca5137d 100644 --- a/Build/source/texk/web2c/luatexdir/font/luafont.w +++ b/Build/source/texk/web2c/luatexdir/font/luafont.w @@ -18,22 +18,27 @@ % with LuaTeX; if not, see <http://www.gnu.org/licenses/>. @ @c - - #include "ptexlib.h" #include "lua/luatex-api.h" #define noVERBOSE -const char *font_type_strings[] = { "unknown", "virtual", "real", NULL }; -const char *font_format_strings[] = - { "unknown", "type1", "type3", "truetype", "opentype", NULL }; -const char *font_embedding_strings[] = - { "unknown", "no", "subset", "full", NULL }; +/* todo: also keys */ + +const char *font_type_strings[] = { + "unknown", "virtual", "real", NULL +}; + +const char *font_format_strings[] = { + "unknown", "type1", "type3", "truetype", "opentype", NULL +}; + +const char *font_embedding_strings[] = { + "unknown", "no", "subset", "full", NULL +}; -const char *ligature_type_strings[] = - { "=:", "=:|", "|=:", "|=:|", "", "=:|>", "|=:>", "|=:|>", "", "", "", - "|=:|>>", NULL +const char *ligature_type_strings[] = { + "=:", "=:|", "|=:", "|=:|", "", "=:|>", "|=:>", "|=:|>", "", "", "", "|=:|>>", NULL }; const char *MATH_param_names[] = { @@ -114,34 +119,39 @@ int ff_checkoption (lua_State *L, int narg, const char *def, const char *const l return -1; } -static void dump_intfield(lua_State * L, const char *n, int c) -{ - lua_pushstring(L, n); - lua_pushnumber(L, c); +#define dump_intfield(L,n,c) \ + lua_push_string_by_name(L,n); \ + lua_pushinteger(L, c); \ + lua_rawset(L, -3); \ + +#define dump_stringfield(L,n,c) \ + lua_push_string_by_name(L,n); \ + lua_pushstring(L, c); \ lua_rawset(L, -3); -} +#define dump_booleanfield(L,n,c) \ + lua_push_string_by_name(L,n); \ + lua_pushboolean(L, c); \ + lua_rawset(L, -3); static void dump_math_kerns(lua_State * L, charinfo * co, int l, int id) { int i; for (i = 0; i < l; i++) { lua_newtable(L); - /* *INDENT-OFF* */ - 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]); - } - /* INDENT-ON */ + 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)); } } @@ -153,165 +163,136 @@ static void font_char_to_lua(lua_State * L, internal_font_number f, charinfo * c lua_createtable(L, 0, 10); - lua_pushstring(L, "width"); - lua_pushnumber(L, get_charinfo_width(co)); - lua_rawset(L, -3); - - lua_pushstring(L, "height"); - lua_pushnumber(L, get_charinfo_height(co)); - lua_rawset(L, -3); - - lua_pushstring(L, "depth"); - lua_pushnumber(L, get_charinfo_depth(co)); - lua_rawset(L, -3); - + dump_intfield(L,width,get_charinfo_width(co)); + dump_intfield(L,height,get_charinfo_height(co)); + dump_intfield(L,depth,get_charinfo_depth(co)); if (get_charinfo_italic(co) != 0) { - lua_pushstring(L, "italic"); - lua_pushnumber(L, get_charinfo_italic(co)); - lua_rawset(L, -3); + dump_intfield(L,italic,get_charinfo_italic(co)); } - if (get_charinfo_vert_italic(co) != 0) { - lua_pushstring(L, "vert_italic"); - lua_pushnumber(L, get_charinfo_vert_italic(co)); - lua_rawset(L, -3); + dump_intfield(L,vert_italic,get_charinfo_vert_italic(co)); } - - if (get_charinfo_top_accent(co) !=0) { - lua_pushstring(L, "top_accent"); - lua_pushnumber(L, get_charinfo_top_accent(co)); - lua_rawset(L, -3); + if (get_charinfo_top_accent(co) !=0 && get_charinfo_top_accent(co) != INT_MIN) { + dump_intfield(L,top_accent,get_charinfo_top_accent(co)); } - - if (get_charinfo_bot_accent(co) != 0) { - lua_pushstring(L, "bot_accent") ; - lua_pushnumber(L, get_charinfo_bot_accent(co)); - lua_rawset(L, -3); + if (get_charinfo_bot_accent(co) != 0 && get_charinfo_bot_accent(co) != INT_MIN) { + dump_intfield(L,bot_accent,get_charinfo_bot_accent(co)); } - - if (get_charinfo_ef(co) != 0) { - lua_pushstring(L, "expansion_factor"); - lua_pushnumber(L, get_charinfo_ef(co)); - lua_rawset(L, -3); + if (get_charinfo_ef(co) != 1000) { + dump_intfield(L,expansion_factor,get_charinfo_ef(co)); } - if (get_charinfo_lp(co) != 0) { - lua_pushstring(L, "left_protruding"); - lua_pushnumber(L, get_charinfo_lp(co)); - lua_rawset(L, -3); + dump_intfield(L,left_protruding,get_charinfo_lp(co)); } - if (get_charinfo_rp(co) != 0) { - lua_pushstring(L, "right_protruding"); - lua_pushnumber(L, get_charinfo_rp(co)); - lua_rawset(L, -3); + dump_intfield(L,right_protruding,get_charinfo_rp(co)); } - if (font_encodingbytes(f) == 2) { - lua_pushstring(L, "index"); - lua_pushnumber(L, get_charinfo_index(co)); - lua_rawset(L, -3); + dump_intfield(L,index,get_charinfo_index(co)); } - if (get_charinfo_name(co) != NULL) { - lua_pushstring(L, "name"); - lua_pushstring(L, get_charinfo_name(co)); - lua_rawset(L, -3); + dump_stringfield(L,name,get_charinfo_name(co)); } - if (get_charinfo_tounicode(co) != NULL) { - lua_pushstring(L, "tounicode"); - lua_pushstring(L, get_charinfo_tounicode(co)); - lua_rawset(L, -3); + dump_stringfield(L,tounicode,get_charinfo_tounicode(co)); } - if (get_charinfo_tag(co) == list_tag) { - lua_pushstring(L, "next"); - lua_pushnumber(L, get_charinfo_remainder(co)); - lua_rawset(L, -3); + dump_intfield(L,next,get_charinfo_remainder(co)); + } + if (get_charinfo_used(co)) { + dump_booleanfield(L,used,(get_charinfo_used(co) ? true : false)); } - - lua_pushstring(L, "used"); - lua_pushboolean(L, (get_charinfo_used(co) ? true : false)); - lua_rawset(L, -3); - if (get_charinfo_tag(co) == ext_tag) { extinfo *h; h = get_charinfo_hor_variants(co); if (h != NULL) { int i = 1; + lua_push_string_by_name(L,horiz_variants); lua_newtable(L); while (h != NULL) { lua_createtable(L, 0, 5); - dump_intfield(L, "glyph", h->glyph); - dump_intfield(L, "extender", h->extender); - dump_intfield(L, "start", h->start_overlap); - dump_intfield(L, "end", h->end_overlap); - dump_intfield(L, "advance", h->advance); + dump_intfield(L, glyph, h->glyph); + dump_intfield(L, extender, h->extender); + dump_intfield(L, start, h->start_overlap); + dump_intfield(L, end, h->end_overlap); + dump_intfield(L, advance, h->advance); lua_rawseti(L, -2, i); i++; h = h->next; } - lua_setfield(L, -2, "horiz_variants"); + lua_rawset(L, -3); } h = get_charinfo_vert_variants(co); if (h != NULL) { int i = 1; + lua_push_string_by_name(L,vert_variants); lua_newtable(L); while (h != NULL) { lua_createtable(L, 0, 5); - dump_intfield(L, "glyph", h->glyph); - dump_intfield(L, "extender", h->extender); - dump_intfield(L, "start", h->start_overlap); - dump_intfield(L, "end", h->end_overlap); - dump_intfield(L, "advance", h->advance); + dump_intfield(L, glyph, h->glyph); + dump_intfield(L, extender, h->extender); + dump_intfield(L, start, h->start_overlap); + dump_intfield(L, end, h->end_overlap); + dump_intfield(L, advance, h->advance); lua_rawseti(L, -2, i); i++; h = h->next; } - lua_setfield(L, -2, "vert_variants"); + lua_rawset(L, -3); } } ki = get_charinfo_kerns(co); if (ki != NULL) { int i; - lua_pushstring(L, "kerns"); + lua_push_string_by_name(L,kerns); lua_createtable(L, 10, 1); for (i = 0; !kern_end(ki[i]); i++) { - if (kern_char(ki[i]) == right_boundarychar) { - lua_pushstring(L, "right_boundary"); + if (kern_disabled(ki[i])) { + /* skip like in lookup */ } else { - lua_pushnumber(L, kern_char(ki[i])); + lua_rawgeti(L, -1, kern_char(ki[i])); + if (lua_type(L,-1) == LUA_TNIL) { + lua_pop(L,1); + if (kern_char(ki[i]) == right_boundarychar) { + lua_push_string_by_name(L,right_boundary); + } else { + lua_pushinteger(L, kern_char(ki[i])); + } + lua_pushinteger(L, kern_kern(ki[i])); + lua_rawset(L, -3); + } else { + /* first one wins */ + lua_pop(L,1); + } } - lua_pushnumber(L, kern_kern(ki[i])); - lua_rawset(L, -3); } lua_rawset(L, -3); } l = get_charinfo_ligatures(co); if (l != NULL) { int i; - lua_pushstring(L, "ligatures"); + lua_push_string_by_name(L,ligatures); lua_createtable(L, 10, 1); for (i = 0; !lig_end(l[i]); i++) { if (lig_char(l[i]) == right_boundarychar) { - lua_pushstring(L, "right_boundary"); + lua_push_string_by_name(L,right_boundary); } else { - lua_pushnumber(L, lig_char(l[i])); + lua_pushinteger(L, lig_char(l[i])); } lua_createtable(L, 0, 2); - lua_pushstring(L, "type"); - lua_pushnumber(L, lig_type(l[i])); + lua_push_string_by_name(L,type); + lua_pushinteger(L, lig_type(l[i])); lua_rawset(L, -3); - lua_pushstring(L, "char"); - lua_pushnumber(L, lig_replacement(l[i])); + lua_push_string_by_name(L,char); + lua_pushinteger(L, lig_replacement(l[i])); lua_rawset(L, -3); lua_rawset(L, -3); } lua_rawset(L, -3); } + lua_push_string_by_name(L,mathkern); lua_newtable(L); { int i, j; @@ -319,91 +300,95 @@ static void font_char_to_lua(lua_State * L, internal_font_number f, charinfo * c j = 0; if (i > 0) { j++; + lua_push_string_by_name(L,top_right); lua_newtable(L); dump_math_kerns(L, co, i, top_right_kern); - lua_setfield(L, -2, "top_right"); + lua_rawset(L, -3); } i = get_charinfo_math_kerns(co, top_left_kern); if (i > 0) { j++; + lua_push_string_by_name(L,top_left); lua_newtable(L); dump_math_kerns(L, co, i, top_left_kern); - lua_setfield(L, -2, "top_left"); + lua_rawset(L, -3); } i = get_charinfo_math_kerns(co, bottom_right_kern); if (i > 0) { j++; + lua_push_string_by_name(L,bottom_right); lua_newtable(L); dump_math_kerns(L, co, i, bottom_right_kern); - lua_setfield(L, -2, "bottom_right"); + lua_rawset(L, -3); } i = get_charinfo_math_kerns(co, bottom_left_kern); if (i > 0) { j++; + lua_push_string_by_name(L,bottom_left); lua_newtable(L); dump_math_kerns(L, co, i, bottom_left_kern); - lua_setfield(L, -2, "bottom_left"); + lua_rawset(L, -3); } if (j > 0) - lua_setfield(L, -2, "mathkern"); + lua_rawset(L, -3); else - lua_pop(L, 1); + lua_pop(L, 2); } } static void write_lua_parameters(lua_State * L, int f) { int k; + lua_push_string_by_name(L,parameters); lua_newtable(L); for (k = 1; k <= font_params(f); k++) { - lua_pushnumber(L, font_param(f, k)); switch (k) { - case slant_code: - lua_setfield(L, -2, "slant"); - break; - case space_code: - lua_setfield(L, -2, "space"); - break; - case space_stretch_code: - lua_setfield(L, -2, "space_stretch"); - break; - case space_shrink_code: - lua_setfield(L, -2, "space_shrink"); - break; - case x_height_code: - lua_setfield(L, -2, "x_height"); - break; - case quad_code: - lua_setfield(L, -2, "quad"); - break; - case extra_space_code: - lua_setfield(L, -2, "extra_space"); - break; - default: - lua_rawseti(L, -2, k); + case slant_code: + dump_intfield(L,slant,font_param(f, k)); + break; + case space_code: + dump_intfield(L,space,font_param(f, k)); + break; + case space_stretch_code: + dump_intfield(L,space_stretch,font_param(f, k)); + break; + case space_shrink_code: + dump_intfield(L,space_shrink,font_param(f, k)); + break; + case x_height_code: + dump_intfield(L,x_height,font_param(f, k)); + break; + case quad_code: + dump_intfield(L,quad,font_param(f, k)); + break; + case extra_space_code: + dump_intfield(L,extra_space,font_param(f, k)); + break; + default: + lua_pushinteger(L, font_param(f, k)); + lua_rawseti(L, -2, k); } } - lua_setfield(L, -2, "parameters"); + lua_rawset(L, -3); } @ @c static void write_lua_math_parameters(lua_State * L, int f) { int k; + lua_push_string_by_name(L,MathConstants); lua_newtable(L); for (k = 1; k <= font_math_params(f); k++) { - lua_pushnumber(L, font_math_param(f, k)); + lua_pushinteger(L, font_math_param(f, k)); if (k <= MATH_param_max) { lua_setfield(L, -2, MATH_param_names[k]); } else { lua_rawseti(L, -2, k); } } - lua_setfield(L, -2, "MathConstants"); + lua_rawset(L, -3); } - - int font_to_lua(lua_State * L, int f) { int k; @@ -418,91 +403,58 @@ int font_to_lua(lua_State * L, int f) } lua_newtable(L); + lua_push_string_by_name(L,name); lua_pushstring(L, font_name(f)); - lua_setfield(L, -2, "name"); + lua_rawset(L, -3); if (font_area(f) != NULL) { - lua_pushstring(L, font_area(f)); - lua_setfield(L, -2, "area"); + dump_stringfield(L,area,font_area(f)); } if (font_filename(f) != NULL) { - lua_pushstring(L, font_filename(f)); - lua_setfield(L, -2, "filename"); + dump_stringfield(L,filename,font_filename(f)); } if (font_fullname(f) != NULL) { - lua_pushstring(L, font_fullname(f)); - lua_setfield(L, -2, "fullname"); + dump_stringfield(L,fullname,font_fullname(f)); } if (font_psname(f) != NULL) { - lua_pushstring(L, font_psname(f)); - lua_setfield(L, -2, "psname"); + dump_stringfield(L,psname,font_psname(f)); } if (font_encodingname(f) != NULL) { - lua_pushstring(L, font_encodingname(f)); - lua_setfield(L, -2, "encodingname"); - } - - lua_pushboolean(L, (font_used(f) ? true : false)); - lua_setfield(L, -2, "used"); - - - lua_pushstring(L, font_type_strings[font_type(f)]); - lua_setfield(L, -2, "type"); - lua_pushstring(L, font_format_strings[font_format(f)]); - lua_setfield(L, -2, "format"); - lua_pushstring(L, font_embedding_strings[font_embedding(f)]); - lua_setfield(L, -2, "embedding"); - - lua_pushnumber(L, font_units_per_em(f)); - lua_setfield(L, -2, "units_per_em"); - lua_pushnumber(L, font_size(f)); - lua_setfield(L, -2, "size"); - lua_pushnumber(L, font_dsize(f)); - lua_setfield(L, -2, "designsize"); - lua_pushnumber(L, font_checksum(f)); - lua_setfield(L, -2, "checksum"); - lua_pushnumber(L, font_slant(f)); - lua_setfield(L, -2, "slant"); - lua_pushnumber(L, font_extend(f)); - lua_setfield(L, -2, "extend"); - lua_pushnumber(L, font_natural_dir(f)); - lua_setfield(L, -2, "direction"); - lua_pushnumber(L, font_encodingbytes(f)); - lua_setfield(L, -2, "encodingbytes"); - lua_pushboolean(L, font_oldmath(f)); - lua_setfield(L, -2, "oldmath"); - lua_pushnumber(L, font_tounicode(f)); - lua_setfield(L, -2, "tounicode"); - - /* pdf parameters */ - /* skip the first four for now, that are very much interal */ -#if 0 - if (pdf_font_num(f) != 0) { - lua_pushnumber(L,pdf_font_num(f)); - lua_setfield(L,-2,"pdf_num"); - } -#endif + dump_stringfield(L,encodingname,font_encodingname(f)); + } + + dump_booleanfield(L,used,(font_used(f) ? true : false)); + dump_stringfield(L,type,font_type_strings[font_type(f)]); + dump_stringfield(L,format,font_format_strings[font_format(f)]); + dump_stringfield(L,embedding,font_embedding_strings[font_embedding(f)]); + + dump_intfield(L,units_per_em,font_units_per_em(f)); + dump_intfield(L,size,font_size(f)); + dump_intfield(L,designsize,font_dsize(f)); + dump_intfield(L,checksum,font_checksum(f)); + dump_intfield(L,slant,font_slant(f)); + dump_intfield(L,extend,font_extend(f)); + dump_intfield(L,direction,font_natural_dir(f)); + dump_intfield(L,encodingbytes,font_encodingbytes(f)); + dump_booleanfield(L,oldmath,font_oldmath(f)); + dump_intfield(L,tounicode,font_tounicode(f)); + /* the next one is read only */ if (font_max_shrink(f) != 0) { - lua_pushnumber(L, font_max_shrink(f)); - lua_setfield(L, -2, "max_shrink"); + dump_intfield(L,shrink,font_max_shrink(f)); } if (font_max_stretch(f) != 0) { - lua_pushnumber(L, font_max_stretch(f)); - lua_setfield(L, -2, "max_stretch"); + dump_intfield(L,stretch,font_max_stretch(f)); } if (font_step(f) != 0) { - lua_pushnumber(L, font_step(f)); - lua_setfield(L, -2, "step"); + dump_intfield(L,step,font_step(f)); } if (font_auto_expand(f) != 0) { - lua_pushboolean(L, font_auto_expand(f)); - lua_setfield(L, -2, "auto_expand"); + dump_booleanfield(L,auto_expand,font_auto_expand(f)); } if (pdf_font_attr(f) != 0) { char *s = makecstring(pdf_font_attr(f)); - lua_pushstring(L, s); + dump_stringfield(L,attributes,s); free(s); - lua_setfield(L, -2, "attributes"); } /* params */ @@ -510,28 +462,29 @@ int font_to_lua(lua_State * L, int f) write_lua_math_parameters(L, f); /* chars */ + lua_push_string_by_name(L,characters); lua_createtable(L, font_tables[f]->charinfo_size, 0); /* all characters */ - if (has_left_boundary(f)) { co = get_charinfo(f, left_boundarychar); + lua_push_string_by_name(L,left_boundary); font_char_to_lua(L, f, co); - lua_setfield(L, -2, "left_boundary"); + lua_rawset(L, -3); } if (has_right_boundary(f)) { co = get_charinfo(f, right_boundarychar); + lua_push_string_by_name(L,right_boundary); font_char_to_lua(L, f, co); - lua_setfield(L, -2, "right_boundary"); + lua_rawset(L, -3); } - for (k = font_bc(f); k <= font_ec(f); k++) { if (quick_char_exists(f, k)) { - lua_pushnumber(L, k); + lua_pushinteger(L, k); co = get_charinfo(f, k); font_char_to_lua(L, f, co); lua_rawset(L, -3); } } - lua_setfield(L, -2, "characters"); + lua_rawset(L, -3); if (font_cache_id(f) == 0) { /* renew */ int r; @@ -542,25 +495,22 @@ int font_to_lua(lua_State * L, int f) return 1; } -static int count_hash_items(lua_State * L, int name_index) -{ - int n = -1; - lua_rawgeti(L, LUA_REGISTRYINDEX, name_index); - lua_rawget(L, -2); - if (!lua_isnil(L, -1)) { - if (lua_istable(L, -1)) { - n = 0; - /* now find the number */ - lua_pushnil(L); /* first key */ - while (lua_next(L, -2) != 0) { - n++; - lua_pop(L, 1); - } - } +#define count_hash_items(L,name_index,n) \ + n = 0; \ + lua_rawgeti(L, LUA_REGISTRYINDEX, name_index); \ + lua_rawget(L, -2); \ + if (lua_type(L, -1) == LUA_TTABLE) { \ + lua_pushnil(L); \ + while (lua_next(L, -2) != 0) { \ + n++; \ + lua_pop(L, 1); \ + } \ + } \ + if (n) { \ + /* keep table on stack */ \ + } else{ \ + lua_pop(L, 1); \ } - lua_pop(L, 1); - return n; -} @ @c #define streq(a,b) (strcmp(a,b)==0) @@ -589,8 +539,6 @@ static void append_float(eight_bits ** cpp, float a) *cpp = cp; } -/*#define lua_roundnumber(a,b) (int)floor((double)lua_tonumber(L,-1)+0.5)*/ - static int n_enum_field(lua_State * L, int name_index, int dflt, const char **values) { int k, t; @@ -600,7 +548,7 @@ static int n_enum_field(lua_State * L, int name_index, int dflt, const char **va lua_rawget(L, -2); t = lua_type(L,-1); if (t == LUA_TNUMBER) { - i=(int)lua_tonumber(L, -1); + i = (int) lua_tointeger(L, -1); } else if (t == LUA_TSTRING) { s = lua_tostring(L, -1); k = 0; @@ -651,6 +599,13 @@ static const char *n_string_field(lua_State * L, int name_index) return lua_tostring(L,-1); } +static int n_some_field(lua_State * L, int name_index) +{ + lua_rawgeti(L, LUA_REGISTRYINDEX, name_index); /* fetch the stringptr */ + lua_rawget(L, -2); + return lua_type(L,-1); +} + /*static void init_font_string_pointers(lua_State * L){}*/ static int count_char_packet_bytes(lua_State * L) @@ -737,11 +692,8 @@ static void read_char_packets(lua_State * L, int *l_fonts, charinfo * co, intern int pc = count_char_packet_bytes(L); if (pc <= 0) return; - assert(l_fonts != NULL); - assert(l_fonts[1] != 0); while (l_fonts[(max_f + 1)] != 0) max_f++; - cp = cpackets = xmalloc((unsigned) (pc + 1)); for (i = 1; i <= (int) lua_rawlen(L, -1); i++) { lua_rawgeti(L, -1, i); @@ -799,98 +751,97 @@ static void read_char_packets(lua_State * L, int *l_fonts, charinfo * co, intern } else if (lua_key_eq(s, lua)) { cmd = packet_lua_code; } - switch (cmd) { - case packet_push_code: - case packet_pop_code: - append_packet(cmd); - break; - case packet_font_code: - append_packet(cmd); - lua_rawgeti(L, -2, 2); - n = (int) luaL_checkinteger(L, -1); - if (n == 0) { - ff = n; - } else { - ff = (n > max_f ? l_fonts[1] : l_fonts[n]); - } - do_store_four(ff); - lua_pop(L, 1); - break; - case packet_node_code: - append_packet(cmd); - lua_rawgeti(L, -2, 2); - n = copy_node_list(nodelist_from_lua(L)); - do_store_four(n); - lua_pop(L, 1); - break; - case packet_char_code: - append_packet(cmd); - lua_rawgeti(L, -2, 2); - n = (int) luaL_checkinteger(L, -1); - do_store_four(n); - lua_pop(L, 1); - break; - case packet_right_code: - case packet_down_code: - append_packet(cmd); - lua_rawgeti(L, -2, 2); - n = (int) luaL_checkinteger(L, -1); - do_store_four(sp_to_dvi(n, atsize)); - lua_pop(L, 1); - break; - case packet_rule_code: - append_packet(cmd); - lua_rawgeti(L, -2, 2); - n = (int) luaL_checkinteger(L, -1); - do_store_four(sp_to_dvi(n, atsize)); - lua_rawgeti(L, -3, 3); - n = (int) luaL_checkinteger(L, -1); - do_store_four(sp_to_dvi(n, atsize)); - lua_pop(L, 2); - break; - case packet_special_code: - case packet_lua_code: - append_packet(cmd); - lua_rawgeti(L, -2, 2); - s = luaL_checklstring(L, -1, &l); - if (l > 0) { - do_store_four(l); - m = (int) l; - while (m > 0) { - n = *s++; - m--; - append_packet(n); + case packet_push_code: + case packet_pop_code: + append_packet(cmd); + break; + case packet_font_code: + append_packet(cmd); + lua_rawgeti(L, -2, 2); + n = (int) luaL_checkinteger(L, -1); + if (n == 0) { + ff = n; + } else { + ff = (n > max_f ? l_fonts[1] : l_fonts[n]); } - } - lua_pop(L, 1); - break; - case packet_image_code: - append_packet(cmd); - lua_rawgeti(L, -2, 2); /* img/imgtable? ... */ - if (lua_istable(L, -1)) { /* imgtable ... */ - lua_getglobal(L, "img"); /* imglib imgtable ... */ - lua_pushstring(L, "new"); /* `new' imglib imgtable ... */ - lua_gettable(L, -2); /* f imglib imgtable ... */ - lua_insert(L, -3); /* imglib imgtable f ... */ - lua_pop(L, 1); /* imgtable f ... */ - lua_call(L, 1, 1); - } /* img ... */ - luaL_checkudata(L, -1, TYPE_IMG); /* img ... --- just typecheck */ - n = luaL_ref(L, LUA_REGISTRYINDEX); /* ... */ - do_store_four(n); - break; - case packet_nop_code: - break; - case packet_scale_code: - append_packet(cmd); - lua_rawgeti(L, -2, 2); - append_float(&cp, (float) luaL_checknumber(L, -1)); - lua_pop(L, 1); - break; - default: - normal_error("vf command","invalid packet code"); - /* fprintf(stdout, "Unknown char packet code %s\n", s); */ + do_store_four(ff); + lua_pop(L, 1); + break; + case packet_node_code: + append_packet(cmd); + lua_rawgeti(L, -2, 2); + n = copy_node_list(nodelist_from_lua(L)); + do_store_four(n); + lua_pop(L, 1); + break; + case packet_char_code: + append_packet(cmd); + lua_rawgeti(L, -2, 2); + n = (int) luaL_checkinteger(L, -1); + do_store_four(n); + lua_pop(L, 1); + break; + case packet_right_code: + case packet_down_code: + append_packet(cmd); + lua_rawgeti(L, -2, 2); + n = (int) luaL_checkinteger(L, -1); + do_store_four(sp_to_dvi(n, atsize)); + lua_pop(L, 1); + break; + case packet_rule_code: + append_packet(cmd); + lua_rawgeti(L, -2, 2); + n = (int) luaL_checkinteger(L, -1); + do_store_four(sp_to_dvi(n, atsize)); + lua_rawgeti(L, -3, 3); + n = (int) luaL_checkinteger(L, -1); + do_store_four(sp_to_dvi(n, atsize)); + lua_pop(L, 2); + break; + case packet_special_code: + case packet_lua_code: + append_packet(cmd); + lua_rawgeti(L, -2, 2); + s = luaL_checklstring(L, -1, &l); + if (l > 0) { + do_store_four(l); + m = (int) l; + while (m > 0) { + n = *s++; + m--; + append_packet(n); + } + } + lua_pop(L, 1); + break; + case packet_image_code: + append_packet(cmd); + lua_rawgeti(L, -2, 2); /* img/imgtable? ... */ + if (lua_istable(L, -1)) { /* imgtable ... */ + lua_getglobal(L, "img"); /* imglib imgtable ... */ + lua_pushstring(L, "new"); /* `new' imglib imgtable ... */ + lua_gettable(L, -2); /* f imglib imgtable ... */ + lua_insert(L, -3); /* imglib imgtable f ... */ + lua_pop(L, 1); /* imgtable f ... */ + lua_call(L, 1, 1); + } /* img ... */ + luaL_checkudata(L, -1, TYPE_IMG); /* img ... --- just typecheck */ + n = luaL_ref(L, LUA_REGISTRYINDEX); /* ... */ + do_store_four(n); + break; + case packet_nop_code: + break; + case packet_scale_code: + append_packet(cmd); + lua_rawgeti(L, -2, 2); + append_float(&cp, (float) luaL_checknumber(L, -1)); + lua_pop(L, 1); + break; + default: + normal_error("vf command","invalid packet code"); + /* fprintf(stdout, "Unknown char packet code %s\n", s); */ } } lua_pop(L, 1); /* command code */ @@ -938,8 +889,8 @@ static void read_lua_parameters(lua_State * L, int f) n = 7; lua_pushnil(L); /* first key */ while (lua_next(L, -2) != 0) { - if (lua_isnumber(L, -2)) { - i=(int)lua_tonumber(L, -2); + if (lua_type(L, -2) == LUA_TNUMBER) { + i = (int) lua_tointeger(L, -2); if (i > n) n = i; } @@ -950,8 +901,8 @@ static void read_lua_parameters(lua_State * L, int f) /* sometimes it is handy to have all integer keys */ for (i = 1; i <= 7; i++) { lua_rawgeti(L, -1, i); - if (lua_isnumber(L, -1)) { - n = lua_roundnumber(L, -1); + if (lua_type(L, -1) == LUA_TNUMBER) { + n = lua_roundnumber(L, -1); /* round ? */ set_font_param(f, i, n); } lua_pop(L, 1); @@ -1010,11 +961,11 @@ static void read_lua_math_parameters(lua_State * L, int f) while (lua_next(L, -2) != 0) { t = lua_type(L,-2); if (t == LUA_TNUMBER) { - i=(int)lua_tonumber(L, -2); + i = (int) lua_tointeger(L, -2); } else if (t == LUA_TSTRING) { i = ff_checkoption(L, -2, NULL, MATH_param_names); } - n=(int)lua_tonumber(L, -1); + n = (int) lua_tointeger(L, -1); if (i > 0) { set_font_math_param(f, i, n); } @@ -1030,7 +981,6 @@ static void read_lua_math_parameters(lua_State * L, int f) @ @c #define MIN_INF -0x7FFFFFFF - static void store_math_kerns(lua_State * L, int index, charinfo * co, int id) { int l, k; @@ -1053,11 +1003,9 @@ static void store_math_kerns(lua_State * L, int index, charinfo * co, int id) } @ @c -static void -font_char_from_lua(lua_State * L, internal_font_number f, int i, - int *l_fonts, boolean has_math) +static void font_char_from_lua(lua_State * L, internal_font_number f, int i, int *l_fonts, boolean has_math) { - int k, r, t, lt; + int k, r, t, lt, u, n; charinfo *co; kerninfo *ckerns; liginfo *cligs; @@ -1082,7 +1030,7 @@ font_char_from_lua(lua_State * L, internal_font_number f, int i, set_charinfo_vert_italic(co, j); j = lua_numeric_field_by_index(L, lua_key_index(index), 0); set_charinfo_index(co, j); - j = lua_numeric_field_by_index(L, lua_key_index(expansion_factor), 0); + j = lua_numeric_field_by_index(L, lua_key_index(expansion_factor), 1000); set_charinfo_ef(co, j); j = lua_numeric_field_by_index(L, lua_key_index(left_protruding), 0); set_charinfo_lp(co, j); @@ -1097,13 +1045,76 @@ font_char_from_lua(lua_State * L, internal_font_number f, int i, set_charinfo_name(co, NULL); /* n_string_field leaves a value on stack*/ lua_pop(L,1); - s = n_string_field(L, lua_key_index(tounicode)); - if (s != NULL) + u = n_some_field(L,lua_key_index(tounicode)); + if (u == LUA_TNUMBER) { + u = lua_tointeger(L,-1); + if (u < 0) { + set_charinfo_tounicode(co, NULL); + } else if (u < 0x10000) { + char *s = malloc(5); + sprintf(s,"%04X",(unsigned int) u); + set_charinfo_tounicode(co,s); + } else if (u < 0x1FFFFFFFFF) { + char *s = malloc(9); + sprintf(s,"%04X%04X",(unsigned int) (floor(u/1024)),(unsigned int) (u%1024+0xDC00)); + set_charinfo_tounicode(co,s); + } else { + set_charinfo_tounicode(co, NULL); + } + } else if (u == LUA_TTABLE) { + n = lua_rawlen(L,-1); + u = 0; + for (k = 1; k <= n; k++) { + lua_rawgeti(L, -1, k); + if (lua_type(L,-1) == LUA_TNUMBER) { + u = lua_tointeger(L,-1); + } else { + lua_pop(L, 1); + break; + } + if (u < 0) { + u = -1; + lua_pop(L, 1); + break; + } else if (u < 0x10000) { + u = u + 4; + } else if (u < 0x1FFFFFFFFF) { + u = u + 8; + } else { + u = -1; + lua_pop(L, 1); + break; + } + lua_pop(L, 1); + } + if (u>0) { + char *s = malloc(u+1); + char *t = s ; + for (k = 1; k <= n; k++) { + lua_rawgeti(L, -1, k); + u = lua_tointeger(L,-1); + if (u < 0x10000) { + sprintf(t,"%04X",(unsigned int) u); + t += 4; + } else { + sprintf(t,"%04X%04X",(unsigned int) (floor(u/1024)),(unsigned int) (u%1024+0xDC00)); + t += 8; + } + lua_pop(L, 1); + } + set_charinfo_tounicode(co,s); + } else { + set_charinfo_tounicode(co, NULL); + } + } else if (u == LUA_TSTRING) { + s = lua_tostring(L,-1); set_charinfo_tounicode(co, xstrdup(s)); - else + } else { set_charinfo_tounicode(co, NULL); - /* n_string_field leaves a value on stack*/ + } + /* ... leaves a value on stack*/ lua_pop(L,1); + if (has_math) { j = lua_numeric_field_by_index(L, lua_key_index(top_accent), INT_MIN); set_charinfo_top_accent(co, j); @@ -1127,9 +1138,8 @@ font_char_from_lua(lua_State * L, internal_font_number f, int i, set_charinfo_tag(co, ext_tag); set_charinfo_extensible(co, top, bot, mid, rep); } else { - luatex_warn - ("lua-loaded font %s char [U+%X] has an invalid extensible field!", - font_name(f), (int) i); + formatted_warning("font", "lua-loaded font %s char U+%X has an invalid extensible field", + font_name(f), (int) i); } } lua_pop(L, 1); @@ -1186,15 +1196,18 @@ font_char_from_lua(lua_State * L, internal_font_number f, int i, } lua_pop(L, 1); -/* Here is a complete example: + /* + 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 } },| + |}| + + */ - |["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, lua_key_index(mathkern)); lua_rawget(L, -2); if (lua_istable(L, -1)) { @@ -1206,49 +1219,44 @@ font_char_from_lua(lua_State * L, internal_font_number f, int i, lua_pop(L, 1); } /* end of |has_math| */ - nk = count_hash_items(L, lua_key_index(kerns)); + count_hash_items(L, lua_key_index(kerns), nk); if (nk > 0) { + /* kerns table still on stack */ ckerns = xcalloc((unsigned) (nk + 1), sizeof(kerninfo)); - lua_rawgeti(L, LUA_REGISTRYINDEX, lua_key_index(kerns)); - lua_rawget(L, -2); - if (lua_istable(L, -1)) { /* there are kerns */ - ctr = 0; - lua_pushnil(L); - while (lua_next(L, -2) != 0) { - k = non_boundarychar; - lt = lua_type(L,-2); - if (lt == LUA_TNUMBER) { - k=(int)lua_tonumber(L, -2); /* adjacent char */ - if (k < 0) - k = non_boundarychar; - } else if (lt == LUA_TSTRING) { - s = lua_tostring(L, -2); - if (lua_key_eq(s, right_boundary)) { - k = right_boundarychar; - if (!has_right_boundary(f)) - set_right_boundary(f, get_charinfo(f, right_boundarychar)); - } - } - j = lua_roundnumber(L, -1); /* movement */ - if (k != non_boundarychar) { - set_kern_item(ckerns[ctr], k, j); - ctr++; - } else { - luatex_warn - ("lua-loaded font %s char [U+%X] has an invalid kern field!", - font_name(f), (int) i); + ctr = 0; + lua_pushnil(L); /* traverse hash */ + while (lua_next(L, -2) != 0) { + k = non_boundarychar; + lt = lua_type(L,-2); + if (lt == LUA_TNUMBER) { + k = (int) lua_tointeger(L, -2); /* adjacent char */ + if (k < 0) + k = non_boundarychar; + } else if (lt == LUA_TSTRING) { + s = lua_tostring(L, -2); + if (lua_key_eq(s, right_boundary)) { + k = right_boundarychar; + if (!has_right_boundary(f)) + set_right_boundary(f, get_charinfo(f, right_boundarychar)); } - lua_pop(L, 1); } - /* guard against empty tables */ - if (ctr > 0) { - set_kern_item(ckerns[ctr], end_kern, 0); - set_charinfo_kerns(co, ckerns); + j = lua_roundnumber(L, -1); /* movement */ + if (k != non_boundarychar) { + set_kern_item(ckerns[ctr], k, j); + ctr++; } else { - luatex_warn - ("lua-loaded font %s char [U+%X] has an invalid kerns field!", - font_name(f), (int) i); + formatted_warning("font", "lua-loaded font %s char U+%X has an invalid kern field", + font_name(f), (int) i); } + lua_pop(L, 1); + } + /* guard against empty tables */ + if (ctr > 0) { + set_kern_item(ckerns[ctr], end_kern, 0); + set_charinfo_kerns(co, ckerns); + } else { + formatted_warning("font", "lua-loaded font %s char U+%X has an invalid kerns field", + font_name(f), (int) i); } lua_pop(L, 1); } @@ -1266,63 +1274,55 @@ font_char_from_lua(lua_State * L, internal_font_number f, int i, lua_pop(L, 1); /* ligatures */ - nl = count_hash_items(L, lua_key_index(ligatures)); - + count_hash_items(L, lua_key_index(ligatures),nl); if (nl > 0) { + /* ligatures table still on stack */ cligs = xcalloc((unsigned) (nl + 1), sizeof(liginfo)); - lua_rawgeti(L, LUA_REGISTRYINDEX, lua_key_index(ligatures)); - lua_rawget(L, -2); - if (lua_istable(L, -1)) { /* do ligs */ - ctr = 0; - lua_pushnil(L); - while (lua_next(L, -2) != 0) { - k = non_boundarychar; - lt = lua_type(L,-2); - if (lt == LUA_TNUMBER) { - k=(int)lua_tonumber(L, -2); /* adjacent char */ - if (k < 0) { - k = non_boundarychar; - } - } else if (lt == LUA_TSTRING) { - s = lua_tostring(L, -2); - if (lua_key_eq(s, right_boundary)) { - k = right_boundarychar; - if (!has_right_boundary(f)) - set_right_boundary(f, get_charinfo(f, right_boundarychar)); - } - } - r = -1; - if (lua_istable(L, -1)) { - r = lua_numeric_field_by_index(L, lua_key_index(char), -1); /* ligature */ + ctr = 0; + lua_pushnil(L); /* traverse hash */ + while (lua_next(L, -2) != 0) { + k = non_boundarychar; + lt = lua_type(L,-2); + if (lt == LUA_TNUMBER) { + k = (int) lua_tointeger(L, -2); /* adjacent char */ + if (k < 0) { + k = non_boundarychar; } - if (r != -1 && k != non_boundarychar) { - t = n_enum_field(L, lua_key_index(type), 0, ligature_type_strings); - set_ligature_item(cligs[ctr], (char) ((t * 2) + 1), k, r); - ctr++; - } else { - luatex_warn - ("lua-loaded font %s char [U+%X] has an invalid ligature field!", - font_name(f), (int) i); + } else if (lt == LUA_TSTRING) { + s = lua_tostring(L, -2); + if (lua_key_eq(s, right_boundary)) { + k = right_boundarychar; + if (!has_right_boundary(f)) + set_right_boundary(f, get_charinfo(f, right_boundarychar)); } - lua_pop(L, 1); /* iterator value */ } - /* guard against empty tables */ - if (ctr > 0) { - set_ligature_item(cligs[ctr], 0, end_ligature, 0); - set_charinfo_ligatures(co, cligs); + r = -1; + if (lua_istable(L, -1)) { + r = lua_numeric_field_by_index(L, lua_key_index(char), -1); /* ligature */ + } + if (r != -1 && k != non_boundarychar) { + t = n_enum_field(L, lua_key_index(type), 0, ligature_type_strings); + set_ligature_item(cligs[ctr], (char) ((t * 2) + 1), k, r); + ctr++; } else { - luatex_warn - ("lua-loaded font %s char [U+%X] has an invalid ligatures field!", - font_name(f), (int) i); + formatted_warning("font", "lua-loaded font %s char U+%X has an invalid ligature field", + font_name(f), (int) i); } + lua_pop(L, 1); /* iterator value */ + } + /* guard against empty tables */ + if (ctr > 0) { + set_ligature_item(cligs[ctr], 0, end_ligature, 0); + set_charinfo_ligatures(co, cligs); + } else { + formatted_warning("font", "lua-loaded font %s char U+%X has an invalid ligatures field", + font_name(f), (int) i); } lua_pop(L, 1); /* ligatures table */ } } } - - @ The caller has to fix the state of the lua stack when there is an error! @c @@ -1351,9 +1351,6 @@ int font_from_lua(lua_State * L, int f) lua_pop(L,1); /* the table is at stack index -1 */ - /*if (luaS_width_index == 0) - init_font_string_pointers(L); - */ s = n_string_field_copy(L,lua_key_index(area), ""); set_font_area(f, s); @@ -1368,7 +1365,7 @@ int font_from_lua(lua_State * L, int f) set_font_fullname(f, s); if (s == NULL) { - luatex_fail("lua-loaded font [%d] has no name!", f); + formatted_error("font","lua-loaded font '%d' has no name!", f); return false; } s = n_string_field_copy(L, lua_key_index(psname), NULL); @@ -1428,25 +1425,24 @@ int font_from_lua(lua_State * L, int f) } /* now fetch the base fonts, if needed */ - n = count_hash_items(L, lua_key_index(fonts)); + count_hash_items(L, lua_key_index(fonts), n); if (n > 0) { + /* font table still on stack */ l_fonts = xmalloc((unsigned) ((unsigned) (n + 2) * sizeof(int))); memset(l_fonts, 0, (size_t) ((unsigned) (n + 2) * sizeof(int))); - lua_rawgeti(L, LUA_REGISTRYINDEX, lua_key_index(fonts)); - lua_rawget(L, -2); for (i = 1; i <= n; i++) { lua_rawgeti(L, -1, i); if (lua_istable(L, -1)) { lua_key_rawgeti(id); if (lua_isnumber(L, -1)) { - l_fonts[i]=(int)lua_tonumber(L, -1); + l_fonts[i] = (int) lua_tointeger(L, -1); if (l_fonts[i] == 0) { l_fonts[i] = (int) f; } - lua_pop(L, 2); /* pop id and entry */ + lua_pop(L, 2); /* pop id and entry */ continue; } - lua_pop(L, 1); /* pop id */ + lua_pop(L, 1); /* pop id */ }; ss = NULL; if (lua_istable(L, -1)) { @@ -1464,20 +1460,18 @@ int font_from_lua(lua_State * L, int f) l_fonts[i] = find_font_id(ss, t); lua_settop(L, s_top); } else { - luatex_fail("Invalid local font in font %s!\n", font_name(f)); + formatted_error("font","invalid local font in lua-loaded font '%s'", font_name(f)); } - lua_pop(L, 1); /* pop list entry */ + lua_pop(L, 1); /* pop list entry */ } - lua_pop(L, 1); /* pop list entry */ + lua_pop(L, 1); /* pop font table */ + } else if (font_type(f) == virtual_font_type) { + formatted_error("font","invalid local fonts in lua-loaded font '%s'", font_name(f)); } else { - if (font_type(f) == virtual_font_type) { - luatex_fail("Invalid local fonts in font %s!\n", font_name(f)); - } else { - l_fonts = xmalloc(3 * sizeof(int)); - l_fonts[0] = 0; - l_fonts[1] = f; - l_fonts[2] = 0; - } + l_fonts = xmalloc(3 * sizeof(int)); + l_fonts[0] = 0; + l_fonts[1] = f; + l_fonts[2] = 0; } /* parameters */ @@ -1522,9 +1516,6 @@ int font_from_lua(lua_State * L, int f) lua_pop(L, 1); } if (bc != -1) { -#if 0 - fprintf(stdout,"defined a font at %d with %d-%d\n",f,bc,ec); -#endif font_malloc_charinfo(f, num); set_font_bc(f, bc); set_font_ec(f, ec); @@ -1532,7 +1523,7 @@ int font_from_lua(lua_State * L, int f) while (lua_next(L, -2) != 0) { lt = lua_type(L,-2); if (lt == LUA_TNUMBER) { - i=(int)lua_tonumber(L, -2); + i = (int) lua_tointeger(L, -2); if (i >= 0) { font_char_from_lua(L, f, i, l_fonts, !no_math); } @@ -1550,10 +1541,13 @@ int font_from_lua(lua_State * L, int f) } lua_pop(L, 1); - /* handle font expansion last: the |copy_font| routine is called eventually, - and that needs to know |bc| and |ec|. */ + /* + Handle font expansion last: the |copy_font| routine is called eventually, + and that needs to know |bc| and |ec|. + */ + if (font_type(f) != virtual_font_type) { - int fstep = lua_numeric_field_by_index(L, lua_key_index(step), 0); + int fstep = lua_numeric_field_by_index(L, lua_key_index(step), 0); if (fstep < 0) fstep = 0; if (fstep > 100) @@ -1582,7 +1576,7 @@ int font_from_lua(lua_State * L, int f) } else { /* jikes, no characters */ - luatex_warn("lua-loaded font [%d] (%s) has no characters!", f, font_name(f)); + formatted_warning("font","lua-loaded font '%d' with name '%s' has no characters", f, font_name(f)); } if (save_ref > 0) { @@ -1594,9 +1588,8 @@ int font_from_lua(lua_State * L, int f) } } else { /* jikes, no characters */ - luatex_warn("lua-loaded font [%d] (%s) has no character table!", f, font_name(f)); + formatted_warning("font","lua-loaded font '%d' with name '%s' has no character table", f, font_name(f)); } - if (l_fonts != NULL) free(l_fonts); return true; @@ -1605,79 +1598,44 @@ int font_from_lua(lua_State * L, int f) @* Ligaturing. @c -#define assert_disc(a) \ - assert(pre_break(a)!=null); /* expect |head_node| */ \ - assert(type(pre_break(a))==nesting_node); \ - assert((vlink_pre_break(a)==null && tlink_pre_break(a)==null) || \ - tail_of_list(vlink_pre_break(a))==tlink_pre_break(a)); \ - assert(post_break(a)!=null); /* expect |head_node| */ \ - assert(type(post_break(a))==nesting_node); \ - assert((vlink_post_break(a)==null && tlink_post_break(a)==null) || \ - tail_of_list(vlink_post_break(a))==tlink_post_break(a)); \ - assert(no_break(a)!=null); /* expect |head_node| */ \ - assert(type(no_break(a))==nesting_node); \ - assert((vlink_no_break(a)==null && tlink_no_break(a)==null) || \ - tail_of_list(vlink_no_break(a))==tlink_no_break(a)); - static void nesting_append(halfword nest1, halfword newn) { halfword tail = tlink(nest1); - assert(alink(nest1) == null); - assert(vlink(newn) == null); - assert(alink(newn) == null); if (tail == null) { - assert(vlink(nest1) == null); couple_nodes(nest1, newn); } else { - assert(vlink(tail) == null); - assert(tail_of_list(vlink(nest1)) == tail); couple_nodes(tail, newn); } tlink(nest1) = newn; } - static void nesting_prepend(halfword nest1, halfword newn) { halfword head = vlink(nest1); - assert(alink(nest1) == null); - assert(vlink(newn) == null); - assert(alink(newn) == null); couple_nodes(nest1, newn); if (head == null) { - assert(tlink(nest1) == null); tlink(nest1) = newn; } else { - assert(alink(head) == nest1); - assert(tail_of_list(head) == tlink(nest1)); couple_nodes(newn, head); } } - static void nesting_prepend_list(halfword nest1, halfword newn) { halfword head = vlink(nest1); - assert(alink(nest1) == null); - assert(alink(newn) == null); couple_nodes(nest1, newn); if (head == null) { - assert(tlink(nest1) == null); tlink(nest1) = tail_of_list(newn); } else { halfword tail = tail_of_list(newn); - assert(alink(head) == nest1); - assert(tail_of_list(head) == tlink(nest1)); couple_nodes(tail, head); } } - static int test_ligature(liginfo * lig, halfword left, halfword right) { if (type(left) != glyph_node) return 0; - assert(type(right) == glyph_node); if (font(left) != font(right)) return 0; if (is_ghost(left) || is_ghost(right)) @@ -1689,7 +1647,6 @@ static int test_ligature(liginfo * lig, halfword left, halfword right) return 0; } - static int try_ligature(halfword * frst, halfword fwd) { halfword cur = *frst; @@ -1742,7 +1699,6 @@ static int try_ligature(halfword * frst, halfword fwd) halfword prev = alink(cur); uncouple_node(cur); lig_ptr(newgl) = cur; - assert(prev != null); couple_nodes(prev, newgl); cur = newgl; /* as cur has disappeared */ } @@ -1765,7 +1721,6 @@ static int try_ligature(halfword * frst, halfword fwd) couple_nodes(newgl, next); } } - /* check and return */ *frst = cur; return 1; @@ -1773,7 +1728,6 @@ static int try_ligature(halfword * frst, halfword fwd) return 0; } - @ there shouldn't be any ligatures here - we only add them at the end of |xxx_break| in a \.{DISC-1 - DISC-2} situation and we stop processing \.{DISC-1} (we continue with \.{DISC-1}'s |post_| and |no_break|. @@ -1786,16 +1740,15 @@ static halfword handle_lig_nest(halfword root, halfword cur) while (vlink(cur) != null) { halfword fwd = vlink(cur); if (type(cur) == glyph_node && type(fwd) == glyph_node && - font(cur) == font(fwd) && try_ligature(&cur, fwd)) + font(cur) == font(fwd) && try_ligature(&cur, fwd)) { continue; + } cur = vlink(cur); - assert(vlink(alink(cur)) == cur); } tlink(root) = cur; return root; } - static halfword handle_lig_word(halfword cur) { halfword right = null; @@ -1834,7 +1787,6 @@ static halfword handle_lig_word(halfword cur) right = null; continue; } - assert(alink(fwd) == cur); if (type(fwd) == glyph_node) { /* |GLYPH - GLYPH| */ if (font(cur) != font(fwd)) break; @@ -1847,7 +1799,6 @@ static halfword handle_lig_word(halfword cur) halfword nob = vlink_no_break(fwd); halfword next, tail; liginfo lig; - assert_disc(fwd); /* Check on: a{b?}{?}{?} and a+b=>B : {B?}{?}{a?} */ /* Check on: a{?}{?}{b?} and a+b=>B : {a?}{?}{B?} */ if ((pre != null && type(pre) == glyph_node @@ -1856,7 +1807,6 @@ static halfword handle_lig_word(halfword cur) && test_ligature(&lig, cur, nob))) { /* move cur from before disc, to skipped part */ halfword prev = alink(cur); - assert(vlink(prev) == cur); uncouple_node(cur); couple_nodes(prev, fwd); nesting_prepend(no_break(fwd), cur); @@ -1871,8 +1821,6 @@ static halfword handle_lig_word(halfword cur) && test_ligature(&lig, cur, next)) { /* move |cur| from before |disc| to |no_break| part */ halfword prev = alink(cur); - assert(alink(next) == fwd); - assert(vlink(prev) == cur); uncouple_node(cur); couple_nodes(prev, fwd); couple_nodes(no_break(fwd), cur); /* we {\it know\/} it's empty */ @@ -1900,7 +1848,8 @@ static halfword handle_lig_word(halfword cur) /* no need to reset |right|, we're going to leave the loop anyway */ } break; - } else { /* fwd is something unknown */ + } else { + /* fwd is something unknown */ if (right == null) break; couple_nodes(cur, right); @@ -1910,8 +1859,6 @@ 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 prev = 0; @@ -1919,11 +1866,8 @@ static halfword handle_lig_word(halfword cur) liginfo lig; if (subtype(cur) == select_disc) { prev = alink(cur); - assert(type(prev) == disc_node - && subtype(prev) == init_disc); if (vlink_post_break(cur) != null) - handle_lig_nest(post_break(prev), - vlink_post_break(prev)); + handle_lig_nest(post_break(prev), vlink_post_break(prev)); if (vlink_no_break(cur) != null) handle_lig_nest(no_break(prev), vlink_no_break(prev)); } @@ -1976,15 +1920,13 @@ static halfword handle_lig_word(halfword cur) 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)))) { + 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' */ @@ -1996,19 +1938,14 @@ static halfword handle_lig_word(halfword cur) 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))); + nesting_prepend(no_break(fwd), copy_node(vlink_pre_break(fwd))); } /* \.{{a-}{b}{AB} {b-}{c}{-}} */ if (vlink_post_break(cur) != null) - nesting_prepend_list(pre_break(fwd), - copy_node_list(vlink_post_break - (cur))); + 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))); + nesting_prepend_list(no_break(fwd), copy_node_list(vlink_no_break(cur))); } /* \.{{a-}{b}{ABC} {b-}{c}{AB-}} */ tail = tlink_no_break(cur); @@ -2025,18 +1962,13 @@ static halfword handle_lig_word(halfword cur) } } - } else { /* NO GLYPH NOR DISC */ + } else { + /* NO GLYPH NOR DISC */ return cur; } /* step-to-next-node */ - { - halfword prev = cur; - /* \.{--\\par} allows |vlink(cur)| to be null */ - cur = vlink(cur); - if (cur != null) { - assert(alink(cur) == prev); - } - } + /* \.{--\\par} allows |vlink(cur)| to be null */ + cur = vlink(cur); } return cur; @@ -2047,7 +1979,7 @@ static halfword handle_lig_word(halfword cur) @c halfword handle_ligaturing(halfword head, halfword tail) { - halfword save_tail1; /* trick to allow explicit |node==null| tests */ + halfword save_tail1; /* trick to allow explicit |node==null| tests */ halfword cur, prev; if (vlink(head) == null) @@ -2067,7 +1999,6 @@ halfword handle_ligaturing(halfword head, halfword tail) } prev = cur; cur = vlink(cur); - assert(cur == null || alink(cur) == prev); } if (prev == null) prev = tail; @@ -2090,7 +2021,6 @@ static void add_kern_before(halfword left, halfword right) if (k != 0) { halfword kern = new_kern(k); halfword prev = alink(right); - assert(vlink(prev) == right); couple_nodes(prev, kern); couple_nodes(kern, right); /* update the attribute list (inherit from left) */ @@ -2101,7 +2031,6 @@ static void add_kern_before(halfword left, halfword right) } } - static void add_kern_after(halfword left, halfword right, halfword aft) { if ((!is_rightghost(right)) && @@ -2110,7 +2039,6 @@ static void add_kern_after(halfword left, halfword right, halfword aft) if (k != 0) { halfword kern = new_kern(k); halfword next = vlink(aft); - assert(next == null || alink(next) == aft); couple_nodes(aft, kern); try_couple_nodes(kern, next); /* update the attribute list (inherit from left == aft) */ @@ -2121,13 +2049,10 @@ static void add_kern_after(halfword left, halfword right, halfword aft) } } - static void do_handle_kerning(halfword root, halfword init_left, halfword init_right) { halfword cur = vlink(root); halfword left = null; - assert(init_left == null || type(init_left) == glyph_node); - assert(init_right == null || type(init_right) == glyph_node); if (cur == null) { if (init_left != null && init_right != null) { add_kern_after(init_left, init_right, root); @@ -2155,8 +2080,7 @@ static void do_handle_kerning(halfword root, halfword init_left, halfword init_r left = cur; } else { if (type(cur) == disc_node) { - halfword right = - type(vlink(cur)) == glyph_node ? vlink(cur) : null; + halfword right = type(vlink(cur)) == glyph_node ? vlink(cur) : null; do_handle_kerning(pre_break(cur), left, null); do_handle_kerning(post_break(cur), null, right); if (vlink_post_break(cur) != null) @@ -2184,8 +2108,6 @@ static void do_handle_kerning(halfword root, halfword init_left, halfword init_r if (next != null) { couple_nodes(prev, next); tlink(root) = next; - assert(vlink(next) == null); - assert(type(next) == kern_node); } else if (prev != root) { vlink(prev) = null; tlink(root) = prev; @@ -2198,7 +2120,6 @@ static void do_handle_kerning(halfword root, halfword init_left, halfword init_r } } - halfword handle_kerning(halfword head, halfword tail) { halfword save_link; @@ -2231,25 +2152,16 @@ static halfword run_lua_ligkern_callback(halfword head, halfword tail, int callb luatex_error(L, (i == LUA_ERRRUN ? 0 : 1)); return tail; } - /* next two lines disabled to be compatible with the manual */ -#if 0 - tail = nodelist_from_lua(L); - if (fix_node_lists) -#endif - fix_node_list(head); + fix_node_list(head); lua_settop(L, top); return tail; } - halfword new_ligkern(halfword head, halfword tail) { int callback_id = 0; - - assert(head != null); if (vlink(head) == null) return tail; - callback_id = callback_defined(ligaturing_callback); if (callback_id > 0) { tail = run_lua_ligkern_callback(head, tail, callback_id); @@ -2258,12 +2170,12 @@ halfword new_ligkern(halfword head, halfword tail) } else if (callback_id == 0) { tail = handle_ligaturing(head, tail); } - callback_id = callback_defined(kerning_callback); if (callback_id > 0) { tail = run_lua_ligkern_callback(head, tail, callback_id); - if (tail == null) + if (tail == null) { tail = tail_of_list(head); + } } else if (callback_id == 0) { halfword nest1 = new_node(nesting_node, 1); halfword cur = vlink(head); diff --git a/Build/source/texk/web2c/luatexdir/font/mapfile.w b/Build/source/texk/web2c/luatexdir/font/mapfile.w index 70abf22bf0d..939468af4d8 100644 --- a/Build/source/texk/web2c/luatexdir/font/mapfile.w +++ b/Build/source/texk/web2c/luatexdir/font/mapfile.w @@ -164,17 +164,13 @@ int avl_do_entry(fm_entry * fm, int mode) if (p != NULL) { switch (mode) { case FM_DUPIGNORE: - luatex_warn - ("fontmap entry for `%s' already exists, duplicates ignored", - fm->tfm_name); + formatted_warning("map file", "entry for '%s' already exists, duplicates ignored", fm->tfm_name); delete_new = 1; break; case FM_REPLACE: case FM_DELETE: if (is_inuse(p)) { - luatex_warn - ("fontmap entry for `%s' has been used, replace/delete not allowed", - fm->tfm_name); + formatted_warning("map file", "entry for '%s' has been used, replace/delete not allowed", fm->tfm_name); delete_new = 1; } else { a = avl_delete(tfm_tree, p); @@ -220,8 +216,8 @@ static int check_fm_entry(fm_entry * fm, boolean warn) if (is_fontfile(fm) && !is_included(fm)) { if (warn) - luatex_warn - ("ambiguous entry for `%s': font file present but not included, " + formatted_warning("map file", + "ambiguous entry for '%s': font file present but not included, " "will be treated as font file not present", fm->tfm_name); xfree(fm->ff_name); /* do not set variable |a| as this entry will be still accepted */ @@ -230,33 +226,27 @@ static int check_fm_entry(fm_entry * fm, boolean warn) /* if both ps_name and font file are missing, drop this entry */ if (fm->ps_name == NULL && !is_fontfile(fm)) { if (warn) - luatex_warn - ("invalid entry for `%s': both ps_name and font file missing", - fm->tfm_name); + formatted_warning("map file", "invalid entry for '%s': both ps_name and font file missing", fm->tfm_name); a += 1; } /* TrueType fonts cannot be reencoded without subsetting */ if (is_truetype(fm) && is_reencoded(fm) && !is_subsetted(fm)) { if (warn) - luatex_warn - ("invalid entry for `%s': only subsetted TrueType font can be reencoded", - fm->tfm_name); + formatted_warning("map file", "invalid entry for '%s': only subsetted TrueType font can be reencoded", fm->tfm_name); a += 2; } /* the value of SlantFont and ExtendFont must be reasonable */ if (fm->slant < FONT_SLANT_MIN || fm->slant > FONT_SLANT_MAX) { if (warn) - luatex_warn - ("invalid entry for `%s': too big value of SlantFont (%g)", + formatted_warning("map file", "invalid entry for '%s': value '%g' is to large for SlantFont", fm->tfm_name, fm->slant / 1000.0); a += 8; } if (fm->extend < FONT_EXTEND_MIN || fm->extend > FONT_EXTEND_MAX) { if (warn) - luatex_warn - ("invalid entry for `%s': too big value of ExtendFont (%g)", + formatted_warning("map file", "invalid entry for '%s': value '%g' is too large for ExtendFont", fm->tfm_name, fm->extend / 1000.0); a += 16; } @@ -265,8 +255,7 @@ static int check_fm_entry(fm_entry * fm, boolean warn) if (fm->pid != -1 && !(is_truetype(fm) && is_subsetted(fm) && !is_reencoded(fm))) { if (warn) - luatex_warn - ("invalid entry for `%s': PidEid can be used only with subsetted non-reencoded TrueType fonts", + formatted_warning("map file", "invalid entry for '%s': PidEid can be used only with subsetted non-reencoded TrueType fonts", fm->tfm_name); a += 32; } @@ -335,7 +324,7 @@ static void fm_scan_line(void) float d; fm_entry *fm; char fm_line[FM_BUF_SIZE], buf[FM_BUF_SIZE]; - char *p, *q, *s; + char *p, *q, *s; char *r = NULL; switch (mitem->type) { case MAPFILE: @@ -405,9 +394,7 @@ static void fm_scan_line(void) for (r = s; *r != ' ' && *r != '"' && *r != '\0'; r++); /* jump over name */ c = *r; /* remember char for temporary end of string */ *r = '\0'; - luatex_warn - ("invalid entry for `%s': unknown name `%s' ignored", - fm->tfm_name, s); + formatted_warning("map file", "invalid entry for '%s': unknown name '%s' ignored", fm->tfm_name, s); *r = (char) c; } } else @@ -417,9 +404,7 @@ static void fm_scan_line(void) if (*r == '"') /* closing quote */ r++; else { - luatex_warn - ("invalid entry for `%s': closing quote missing", - fm->tfm_name); + formatted_warning("map file", "invalid entry for '%s': closing quote missing", fm->tfm_name); goto bad_line; } break; @@ -525,14 +510,14 @@ static void fm_read_info(void) fm_file = NULL; } } else { - luatex_warn("cannot open font map file (%s)", cur_file_name); + formatted_warning("map file", "cannot open font map file '%s'", cur_file_name); } } else { - luatex_warn("cannot open font map file (%s)", cur_file_name); + formatted_warning("map file", "cannot open font map file '%s'", cur_file_name); } } else { if (!fm_open(cur_file_name)) { - luatex_warn("cannot open font map file (%s)", cur_file_name); + formatted_warning("map file", "cannot open font map file '%s'", cur_file_name); } else { fm_read_file(); report_start_file(filetype_map,cur_file_name); @@ -549,7 +534,7 @@ static void fm_read_info(void) } break; case MAPLINE: - cur_file_name = NULL; /* makes luatex_warn() shorter */ + cur_file_name = NULL; fm_scan_line(); break; default: diff --git a/Build/source/texk/web2c/luatexdir/font/pkin.w b/Build/source/texk/web2c/luatexdir/font/pkin.w index 18c96b20edc..a5d3eb4bccb 100644 --- a/Build/source/texk/web2c/luatexdir/font/pkin.w +++ b/Build/source/texk/web2c/luatexdir/font/pkin.w @@ -56,14 +56,14 @@ typedef short shalfword; @ Now we have some routines to get stuff from the pk file. pkbyte returns the next byte from the pk file. - + @c static shalfword pkbyte(void) { register shalfword i; i = t3_getchar(); if (t3_eof()) - luatex_fail("unexpected eof in pk file"); + normal_error("type 3","unexpected EOF in pk file"); return (i); } @@ -200,7 +200,7 @@ static halfword rest(void) return (i); } } else { - luatex_fail("shouldn't happen"); + normal_error("type 3","pk issue that shouldn't happen"); return 0; /*NOTREACHED*/} } @@ -277,12 +277,6 @@ static void unpack(chardesc * cd) bitweight = 0; while (rowsleft > 0) { count = (*realfunc) (); -#ifdef DEBUG - if (turnon) - printf("(%d) ", (int) count); - else - printf("%d ", (int) count); -#endif while (count != 0) { if ((count < wordweight) && (count < hbit)) { if (turnon) @@ -319,7 +313,7 @@ static void unpack(chardesc * cd) turnon = !turnon; } if ((rowsleft != 0) || ((int) hbit != cd->cwidth)) - luatex_fail("error while unpacking; more bits than required"); + normal_error("type 3","error while unpacking, more bits than required"); } } @@ -341,9 +335,9 @@ int readchar(boolean check_preamble, chardesc * cd) */ if (check_preamble) { if (pkbyte() != 247) - luatex_fail("bad pk file, expected pre"); + normal_error("type 3","bad pk file, expected pre"); if (pkbyte() != 89) - luatex_fail("bad version of pk file"); + normal_error("type 3","bad version of pk file"); for (i = pkbyte(); i > 0; i--) /* creator of pkfile */ (void) pkbyte(); (void) pkquad(); /* design size */ @@ -399,7 +393,7 @@ int readchar(boolean check_preamble, chardesc * cd) cd->yoff = pkquad(); } if (length <= 0) - luatex_fail("packet length (%i) too small", (int) length); + formatted_error("type 3","pk packet length '%i' too small", (int) length); unpack(cd); return 1; } else { @@ -424,7 +418,7 @@ int readchar(boolean check_preamble, chardesc * cd) case 246: break; default: - luatex_fail("unexpected command (%i)", (int) flagbyte); + formatted_error("type 3","unexpected pk command '%i'", (int) flagbyte); } } } diff --git a/Build/source/texk/web2c/luatexdir/font/sfnt.h b/Build/source/texk/web2c/luatexdir/font/sfnt.h index 3fbdb001ea4..dce4248e981 100644 --- a/Build/source/texk/web2c/luatexdir/font/sfnt.h +++ b/Build/source/texk/web2c/luatexdir/font/sfnt.h @@ -1,5 +1,5 @@ /* sfnt.h - + Copyright 2002 by Jin-Hwan Cho and Shunsaku Hirata, the dvipdfmx project team <dvipdfmx@project.ktug.or.kr> Copyright 2006-2008 Taco Hoekwater <taco@luatex.org> @@ -27,18 +27,6 @@ # include <w2c/config.h> # endif /* HAVE_CONFIG_H_ */ -# ifndef pdfTeX -# include "mfileio.h" -# include "numbers.h" -# include "pdfobj.h" -# endif - -# ifdef XETEX -# include "ft2build.h" -# include FT_FREETYPE_H -# include FT_TRUETYPE_TABLES_H -# endif - /* Data Types as described in Apple's TTRefMan */ typedef unsigned char BYTE; typedef signed char ICHAR; @@ -49,8 +37,7 @@ typedef signed long LONG; typedef unsigned long Fixed; /* 16.16-bit signed fixed-point number */ typedef short FWord; typedef unsigned short uFWord; -typedef short F2Dot14; /* 16-bit signed fixed number with the low - 14 bits representing fraction. */ +typedef short F2Dot14; /* 16-bit signed fixed number with the low 14 bits representing fraction. */ struct sfnt_table { /* table header */ @@ -182,9 +169,6 @@ typedef struct { # define RELEASE(a) free(a) # define NEW(a,b) xmalloc((unsigned)((unsigned)(a)*sizeof(b))) # define RENEW(a,b,c) xrealloc(a, (unsigned)((unsigned)(b)*sizeof(c))) -# define TT_ERROR luatex_fail -# define WARN printf - # endif diff --git a/Build/source/texk/web2c/luatexdir/font/sfnt.w b/Build/source/texk/web2c/luatexdir/font/sfnt.w index 939fd0bfe0c..83e38990dd9 100644 --- a/Build/source/texk/web2c/luatexdir/font/sfnt.w +++ b/Build/source/texk/web2c/luatexdir/font/sfnt.w @@ -142,7 +142,7 @@ static void convert_tag(char *tag, unsigned long u_tag) @ Computes the max power of 2 <= n - + @c static unsigned max2floor(unsigned n) { @@ -281,7 +281,7 @@ ULONG sfnt_locate_table(sfnt * sfont, const char *tag) offset = sfnt_find_table_pos(sfont, tag); if (offset == 0) - TT_ERROR("sfnt: table not found..."); + normal_error("ttf","sfnt table not found"); sfnt_seek_set(sfont, (long) offset); @@ -429,7 +429,7 @@ pdf_obj *sfnt_create_FontFile_stream(sfnt * sfont) if (!sfont->buffer) { pdf_release_obj(stream); - TT_ERROR("Font file not opened or already closed..."); + normal_error("ttf","file not opened or already closed"); return NULL; } @@ -439,7 +439,7 @@ pdf_obj *sfnt_create_FontFile_stream(sfnt * sfont) nb_read = sfnt_read(wbuf, (int) MIN(length, 1024), sfont); if (nb_read < 0) { pdf_release_obj(stream); - TT_ERROR("Reading file failed..."); + normal_error("ttf","reading file failed"); return NULL; } else if (nb_read > 0) { pdf_add_stream(stream, wbuf, nb_read); diff --git a/Build/source/texk/web2c/luatexdir/font/subfont.w b/Build/source/texk/web2c/luatexdir/font/subfont.w index ea139c4e48c..0616bdad43c 100644 --- a/Build/source/texk/web2c/luatexdir/font/subfont.w +++ b/Build/source/texk/web2c/luatexdir/font/subfont.w @@ -105,7 +105,7 @@ static void sfd_getline(boolean expect_eof) *sfd_line = 10; return; } else - luatex_fail("unexpected end of file"); + normal_error("sub font","unexpected end of file"); } p = sfd_line; do { @@ -146,16 +146,15 @@ static sfd_entry *read_sfd(char *sfd_name) if (cur_file_name) { callback_id = callback_defined(read_sfd_file_callback); if (callback_id > 0) { - if (!(run_callback(callback_id, "S->bSd", cur_file_name, - &file_opened, &sfd_buffer, &sfd_size) && + if (!(run_callback(callback_id, "S->bSd", cur_file_name, &file_opened, &sfd_buffer, &sfd_size) && file_opened && sfd_size > 0)) { - luatex_warn("cannot open SFD file for reading (%s)", cur_file_name); + formatted_warning("ttf font","cannot open SFD file for reading '%s'", cur_file_name); cur_file_name = NULL; return NULL; } } else { if (!sfd_open(cur_file_name)) { - luatex_warn("cannot open SFD file for reading (%s)", cur_file_name); + formatted_warning("ttf font", "cannot open SFD file for reading '%s'", cur_file_name); cur_file_name = NULL; return NULL; } @@ -187,16 +186,16 @@ static sfd_entry *read_sfd(char *sfd_name) } else if (*p == 0) /* end of subfont */ break; if (sscanf(p, " %li %n", &i, &n) == 0) - luatex_fail("invalid token:\n%s", p); + formatted_error("sub font","invalid token: %s", p); p += n; if (*p == ':') { /* offset */ k = i; p++; } else if (*p == '_') { /* range */ if (sscanf(p + 1, " %li %n", &j, &n) == 0) - luatex_fail("invalid token:\n%s", p); + formatted_error("sub font","invalid token: %s", p); if (i > j || k + (j - i) > 255) - luatex_fail("invalid range:\n%s", p); + formatted_error("sub font","invalid range: %s", p); while (i <= j) sf->charcodes[k++] = i++; p += n + 1; diff --git a/Build/source/texk/web2c/luatexdir/font/texfont.h b/Build/source/texk/web2c/luatexdir/font/texfont.h index 682d1d892ad..3b2773109f2 100644 --- a/Build/source/texk/web2c/luatexdir/font/texfont.h +++ b/Build/source/texk/web2c/luatexdir/font/texfont.h @@ -22,8 +22,9 @@ main pascal program. There is a companion list in luatex.defines to keep web2c happy */ -/* this file is read at the end of ptexlib.h, which is called for at - the end of luatexcoerce.h, as well as from the C sources +/* + This file is read at the end of ptexlib.h, which is called for at + the end of luatexcoerce.h, as well as from the C sources. */ #ifndef TEXFONT_H @@ -32,6 +33,7 @@ # define pointer halfword /* these are dumped en block, so they need endianness tests */ + typedef struct liginfo { # ifdef WORDS_BIGENDIAN int adj; @@ -45,6 +47,7 @@ typedef struct liginfo { } liginfo; /* these are dumped en block, so they need endianness tests */ + typedef struct kerninfo { # ifdef WORDS_BIGENDIAN int adj; @@ -63,7 +66,9 @@ typedef struct extinfo { int advance; int extender; } extinfo; + /* todo: maybe create a 'math info structure' */ + typedef struct charinfo { char *name; /* postscript character name */ liginfo *ligatures; /* ligature items */ @@ -108,8 +113,7 @@ extern void add_charinfo_hor_variant(charinfo * ci, extinfo * ext); extern extinfo *copy_variants(extinfo * o); -extern extinfo *new_variant(int glyph, int startconnect, int endconnect, - int advance, int repeater); +extern extinfo *new_variant(int glyph, int startconnect, int endconnect, int advance, int repeater); extern scaled_whd get_charinfo_whd(internal_font_number f, int c); @@ -198,31 +202,31 @@ extern const char *font_type_strings[]; extern const char *font_format_strings[]; extern const char *font_embedding_strings[]; -# define font_checksum(a) font_tables[a]->_font_checksum -# define set_font_checksum(a,b) font_checksum(a) = b +# define font_checksum(a) font_tables[a]->_font_checksum +# define set_font_checksum(a,b) font_checksum(a) = b -# define font_check_0(a) ((font_tables[a]->_font_checksum&0xFF000000)>>24) -# define font_check_1(a) ((font_tables[a]->_font_checksum&0x00FF0000)>>16) -# define font_check_2(a) ((font_tables[a]->_font_checksum&0x0000FF00)>>8) -# define font_check_3(a) (font_tables[a]->_font_checksum&0x000000FF) +# define font_check_0(a) ((font_tables[a]->_font_checksum&0xFF000000)>>24) +# define font_check_1(a) ((font_tables[a]->_font_checksum&0x00FF0000)>>16) +# define font_check_2(a) ((font_tables[a]->_font_checksum&0x0000FF00)>>8) +# define font_check_3(a) (font_tables[a]->_font_checksum&0x000000FF) -# define font_size(a) font_tables[a]->_font_size -# define set_font_size(a,b) font_size(a) = b -# define font_dsize(a) font_tables[a]->_font_dsize -# define set_font_dsize(a,b) font_dsize(a) = b +# define font_size(a) font_tables[a]->_font_size +# define set_font_size(a,b) font_size(a) = b +# define font_dsize(a) font_tables[a]->_font_dsize +# define set_font_dsize(a,b) font_dsize(a) = b -# define font_units_per_em(a) font_tables[a]->_font_units_per_em -# define set_font_units_per_em(a,b) font_units_per_em(a) = b +# define font_units_per_em(a) font_tables[a]->_font_units_per_em +# define set_font_units_per_em(a,b) font_units_per_em(a) = b -# define font_name(a) font_tables[a]->_font_name -# define get_font_name(a) (unsigned char *)font_name(a) -# define set_font_name(f,b) font_name(f) = b -# define tex_font_name(a) maketexstring(font_name(a)) +# define font_name(a) font_tables[a]->_font_name +# define get_font_name(a) (unsigned char *)font_name(a) +# define set_font_name(f,b) font_name(f) = b +# define tex_font_name(a) maketexstring(font_name(a)) -# define font_area(a) font_tables[a]->_font_area -# define get_font_area(a) (unsigned char *)font_area(a) -# define set_font_area(f,b) font_area(f) = b -# define tex_font_area(a) maketexstring(font_area(a)) +# define font_area(a) font_tables[a]->_font_area +# define get_font_area(a) (unsigned char *)font_area(a) +# define set_font_area(f,b) font_area(f) = b +# define tex_font_area(a) maketexstring(font_area(a)) boolean cmp_font_area(int, str_number); @@ -260,8 +264,7 @@ boolean cmp_font_area(int, str_number); # define set_font_touched(a,b) font_touched(a) = b # define font_type(a) font_tables[a]->_font_type -# define set_font_type(a,b) { /* fprintf(stdout,"set font type of %s to %i: %s\n",font_name(a),b,__FILE__); */ \ - font_type(a) = b; } +# define set_font_type(a,b) font_type(a) = b; # define font_format(a) font_tables[a]->_font_format # define font_format_name(a) font_format_strings[font_tables[a]->_font_format] @@ -338,40 +341,42 @@ boolean cmp_font_area(int, str_number); # define left_boundarychar -1 # define right_boundarychar -2 -# define non_boundarychar -3 +# define non_boundarychar -3 -# define left_boundary(a) font_tables[a]->_left_boundary -# define has_left_boundary(a) (left_boundary(a)!=NULL) -# define set_left_boundary(a,b) font_reassign(left_boundary(a),b) +# define left_boundary(a) font_tables[a]->_left_boundary +# define has_left_boundary(a) (left_boundary(a)!=NULL) +# define set_left_boundary(a,b) font_reassign(left_boundary(a),b) -# define right_boundary(a) font_tables[a]->_right_boundary -# define has_right_boundary(a) (right_boundary(a)!=NULL) -# define set_right_boundary(a,b) font_reassign(right_boundary(a),b) +# define right_boundary(a) font_tables[a]->_right_boundary +# define has_right_boundary(a) (right_boundary(a)!=NULL) +# define set_right_boundary(a,b) font_reassign(right_boundary(a),b) -# define font_bchar(a) (right_boundary(a)!=NULL ? right_boundarychar : non_boundarychar) +# define font_bchar(a) (right_boundary(a)!=NULL ? right_boundarychar : non_boundarychar) /* font parameters */ -# define font_params(a) font_tables[a]->_font_params -# define param_base(a) font_tables[a]->_param_base -# define font_param(a,b) font_tables[a]->_param_base[b] +# define font_params(a) font_tables[a]->_font_params +# define param_base(a) font_tables[a]->_param_base +# define font_param(a,b) font_tables[a]->_param_base[b] extern void set_font_params(internal_font_number f, int b); -# define set_font_param(f,n,b) \ - { if (font_params(f)<n) set_font_params(f,n); \ - font_param(f,n) = b; } - - -# define font_math_params(a) font_tables[a]->_font_math_params -# define math_param_base(a) font_tables[a]->_math_param_base -# define font_math_param(a,b) font_tables[a]->_math_param_base[b] +# define set_font_param(f,n,b) { \ + if (font_params(f)<n) \ + set_font_params(f,n); \ + font_param(f,n) = b; \ +} +# define font_math_params(a) font_tables[a]->_font_math_params +# define math_param_base(a) font_tables[a]->_math_param_base +# define font_math_param(a,b) font_tables[a]->_math_param_base[b] extern void set_font_math_params(internal_font_number f, int b); -# define set_font_math_param(f,n,b) \ - { if (font_math_params(f)<n) set_font_math_params(f,n); \ - font_math_param(f,n) = b; } +# define set_font_math_param(f,n,b) { \ + if (font_math_params(f)<n) \ + set_font_math_params(f,n); \ + font_math_param(f,n) = b; \ +} /* Font parameters are sometimes referred to as |slant(f)|, |space(f)|, etc.*/ @@ -409,11 +414,13 @@ extern charinfo *get_charinfo(internal_font_number f, int c); extern int char_exists(internal_font_number f, int c); extern charinfo *char_info(internal_font_number f, int c); -/* Here is a quick way to test if a glyph exists, when you are -already certain the font |f| exists, and that the |c| is a regular -glyph id, not one of the two special boundary objects. +/* + Here is a quick way to test if a glyph exists, when you are + already certain the font |f| exists, and that the |c| is a regular + glyph id, not one of the two special boundary objects. */ -# define quick_char_exists(f,c) get_sa_item(font_tables[f]->characters,c) + +# define quick_char_exists(f,c) (get_sa_item(font_tables[f]->characters,c).int_value) extern void set_charinfo_width(charinfo * ci, scaled val); extern void set_charinfo_height(charinfo * ci, scaled val); @@ -436,14 +443,13 @@ 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 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); \ - } while (0) +# define set_char_used(f,a,b) do { \ + if (char_exists(f,a)) \ + set_charinfo_used(char_info(f,a),b); \ +} while (0) extern scaled get_charinfo_width(charinfo * ci); extern scaled get_charinfo_height(charinfo * ci); @@ -471,35 +477,30 @@ extern int ext_bot(internal_font_number f, int c); extern int ext_rep(internal_font_number f, int c); extern int ext_mid(internal_font_number f, int c); -# define set_ligature_item(f,b,c,d) { f.type = b; f.adj = c; f.lig = d; } - -# define set_kern_item(f,b,c) { f.adj = b; f.sc = c; } - +# define set_ligature_item(f,b,c,d) { f.type = b; f.adj = c; f.lig = d; } +# define set_kern_item(f,b,c) { f.adj = b; f.sc = c; } /* character information */ -# define non_char 65536 /* a code that can't match a real character */ -# define non_address 0 /* a spurious |bchar_label| */ - +# define non_char 65536 /* a code that can't match a real character */ +# define non_address 0 /* a spurious |bchar_label| */ /* character kerns and ligatures */ -# define end_kern 0x7FFFFF - /* otherchar value meaning "stop" */ -# define ignored_kern 0x800000 - /* otherchar value meaning "disabled" */ +# define end_kern 0x7FFFFF /* otherchar value meaning "stop" */ +# define ignored_kern 0x800000 /* otherchar value meaning "disabled" */ -# define charinfo_kern(b,c) b->kerns[c] +# define charinfo_kern(b,c) b->kerns[c] -# define kern_char(b) (b).adj -# define kern_kern(b) (b).sc -# define kern_end(b) ((b).adj == end_kern) -# define kern_disabled(b) ((b).adj > end_kern) +# define kern_char(b) (b).adj +# define kern_kern(b) (b).sc +# define kern_end(b) ((b).adj == end_kern) +# define kern_disabled(b) ((b).adj > end_kern) /* character ligatures */ -# define end_ligature 0x7FFFFF /* otherchar value meaning "stop" */ -# define ignored_ligature 0x800000 /* otherchar value meaning "disabled" */ +# define end_ligature 0x7FFFFF /* otherchar value meaning "stop" */ +# define ignored_ligature 0x800000 /* otherchar value meaning "disabled" */ # define charinfo_ligature(b,c) b->ligatures[c] @@ -510,10 +511,10 @@ extern int ext_mid(internal_font_number f, int c); # define lig_end(a) (lig_char(a) == end_ligature) # define lig_disabled(a) (lig_char(a) > end_ligature) -# define no_tag 0 /* vanilla character */ -# define lig_tag 1 /* character has a ligature/kerning program */ -# define list_tag 2 /* character has a successor in a charlist */ -# define ext_tag 3 /* character is extensible */ +# define no_tag 0 /* vanilla character */ +# define lig_tag 1 /* character has a ligature/kerning program */ +# define list_tag 2 /* character has a successor in a charlist */ +# define ext_tag 3 /* character is extensible */ extern scaled char_height(internal_font_number f, int c); extern scaled calc_char_width(internal_font_number f, int c, int ex); @@ -528,9 +529,9 @@ extern liginfo *char_ligatures(internal_font_number f, int c); extern kerninfo *char_kerns(internal_font_number f, int c); extern eight_bits *char_packets(internal_font_number f, int c); -# define has_lig(f,b) (char_exists(f,b) &&( char_ligatures(f,b) != NULL)) -# define has_kern(f,b) (char_exists(f,b) && (char_kerns(f,b) != NULL)) -# define has_packet(f,b) (char_exists(f,b) && (char_packets(f,b) != NULL)) +# define has_lig(f,b) (char_exists(f,b) &&( char_ligatures(f,b) != NULL)) +# define has_kern(f,b) (char_exists(f,b) && (char_kerns(f,b) != NULL)) +# define has_packet(f,b) (char_exists(f,b) && (char_packets(f,b) != NULL)) extern int char_remainder(internal_font_number f, int c); extern char char_tag(internal_font_number f, int c); @@ -578,7 +579,6 @@ extern void set_ef_code(internal_font_number f, int c, int i); int read_tfm_info(internal_font_number f, const char *nom, scaled s); - /* from dofont.c */ extern int read_font_info(pointer u, char *cnom, scaled s, int ndir); @@ -622,9 +622,7 @@ extern int make_vf_table(lua_State * L, const char *name, scaled s); # define get_charheight(f,c) (char_exists(f,c) ? char_height(f,c) : 0) # define get_chardepth(f,c) (char_exists(f,c) ? char_depth(f,c) : 0) -/* moved from pdffont.h */ - -extern int pk_dpi; /* PK pixel density value from \.{texmf.cnf} */ +extern int pk_dpi; /* PK pixel density value from \.{texmf.cnf} */ extern internal_font_number tfm_lookup(char *s, scaled fs); @@ -640,4 +638,4 @@ extern void make_font_copy(small_number a); extern void glyph_to_unicode(void); -#endif /* TEXFONT_H */ +#endif diff --git a/Build/source/texk/web2c/luatexdir/font/texfont.w b/Build/source/texk/web2c/luatexdir/font/texfont.w index 7cfb52215bc..06926a2f5a1 100644 --- a/Build/source/texk/web2c/luatexdir/font/texfont.w +++ b/Build/source/texk/web2c/luatexdir/font/texfont.w @@ -32,7 +32,6 @@ problematic |if 0 != null|. @c - #include "ptexlib.h" #include "lua/luatex-api.h" @@ -96,6 +95,7 @@ int new_font(void) int k; int id; charinfo *ci; + sa_tree_item sa_value = { 0 }; id = new_font_id(); font_bytes += (int) sizeof(texfont); /* most stuff is zero */ @@ -125,8 +125,7 @@ int new_font(void) set_font_param(id, k, 0); } /* character info zero is reserved for notdef */ - font_tables[id]->characters = new_sa_tree(1, 0); /* stack size 1, default item value 0 */ - + font_tables[id]->characters = new_sa_tree(1, 1, sa_value); /* stack size 1, default item value 0 */ ci = xcalloc(1, sizeof(charinfo)); set_charinfo_name(ci, xstrdup(".notdef")); font_tables[id]->charinfo = ci; @@ -148,23 +147,24 @@ void font_malloc_charinfo(internal_font_number f, int num) } @ @c -#define find_charinfo_id(f,c) get_sa_item(font_tables[f]->characters,c) +#define find_charinfo_id(f,c) (get_sa_item(font_tables[f]->characters,c).int_value) charinfo *get_charinfo(internal_font_number f, int c) { - sa_tree_item glyph; + int glyph; charinfo *ci; if (proper_char_index(c)) { - glyph = get_sa_item(font_tables[f]->characters, c); + glyph = get_sa_item(font_tables[f]->characters, c).int_value; if (!glyph) { - + sa_tree_item sa_value = { 0 }; int tglyph = ++font_tables[f]->charinfo_count; if (tglyph >= font_tables[f]->charinfo_size) { font_malloc_charinfo(f, 256); } font_tables[f]->charinfo[tglyph].ef = 1000; /* init */ - set_sa_item(font_tables[f]->characters, c, (sa_tree_item) tglyph, 1); /* 1= global */ - glyph = (sa_tree_item) tglyph; + sa_value.int_value = tglyph; + set_sa_item(font_tables[f]->characters, c, sa_value, 1); /* 1 = global */ + glyph = tglyph; } return &(font_tables[f]->charinfo[glyph]); } else if (c == left_boundarychar) { @@ -188,13 +188,13 @@ charinfo *get_charinfo(internal_font_number f, int c) @ @c static void set_charinfo(internal_font_number f, int c, charinfo * ci) { - sa_tree_item glyph; + int glyph; if (proper_char_index(c)) { - glyph = get_sa_item(font_tables[f]->characters, c); + glyph = get_sa_item(font_tables[f]->characters, c).int_value; if (glyph) { font_tables[f]->charinfo[glyph] = *ci; } else { - luatex_fail("font: %s", "character insertion failed"); + normal_error("font","character insertion failed"); } } else if (c == left_boundarychar) { set_left_boundary(f, ci); @@ -259,13 +259,10 @@ charinfo *copy_charinfo(charinfo * ci) /* horizontal and vertical extenders */ if (get_charinfo_vert_variants(ci) != NULL) { - set_charinfo_vert_variants(co, - copy_variants(get_charinfo_vert_variants - (ci))); + set_charinfo_vert_variants(co, copy_variants(get_charinfo_vert_variants(ci))); } if (get_charinfo_hor_variants(ci) != NULL) { - set_charinfo_hor_variants(co, - copy_variants(get_charinfo_hor_variants(ci))); + set_charinfo_hor_variants(co, copy_variants(get_charinfo_hor_variants(ci))); } x = ci->top_left_math_kerns; co->top_left_math_kerns = x; @@ -273,10 +270,8 @@ charinfo *copy_charinfo(charinfo * ci) co->top_left_math_kern_array = xmalloc((unsigned) (2 * (int) sizeof(scaled) * x)); for (k = 0; k < co->top_left_math_kerns; k++) { - co->top_left_math_kern_array[(2 * k)] = - ci->top_left_math_kern_array[(2 * k)]; - co->top_left_math_kern_array[(2 * k) + 1] = - ci->top_left_math_kern_array[(2 * k) + 1]; + 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; @@ -285,10 +280,8 @@ charinfo *copy_charinfo(charinfo * ci) co->top_right_math_kern_array = xmalloc((unsigned) (2 * (int) sizeof(scaled) * x)); for (k = 0; k < co->top_right_math_kerns; k++) { - co->top_right_math_kern_array[(2 * k)] = - ci->top_right_math_kern_array[(2 * k)]; - co->top_right_math_kern_array[(2 * k) + 1] = - ci->top_right_math_kern_array[(2 * k) + 1]; + 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; @@ -297,10 +290,8 @@ charinfo *copy_charinfo(charinfo * ci) co->bottom_right_math_kern_array = xmalloc((unsigned) (2 * (int) sizeof(scaled) * x)); for (k = 0; k < co->bottom_right_math_kerns; k++) { - co->bottom_right_math_kern_array[(2 * k)] = - ci->bottom_right_math_kern_array[(2 * k)]; - co->bottom_right_math_kern_array[(2 * k) + 1] = - ci->bottom_right_math_kern_array[(2 * k) + 1]; + 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; @@ -309,14 +300,10 @@ charinfo *copy_charinfo(charinfo * ci) co->bottom_left_math_kern_array = xmalloc((unsigned) (2 * (int) sizeof(scaled) * x)); for (k = 0; k < co->bottom_left_math_kerns; k++) { - co->bottom_left_math_kern_array[(2 * k)] = - ci->bottom_left_math_kern_array[(2 * k)]; - co->bottom_left_math_kern_array[(2 * k) + 1] = - ci->bottom_left_math_kern_array[(2 * k) + 1]; + 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; } @@ -375,8 +362,8 @@ static int lua_char_exists_callback(internal_font_number f, int c) lua_pop(L, 2); return 0; } - lua_pushnumber(L, f); - lua_pushnumber(L, c); + lua_pushinteger(L, f); + lua_pushinteger(L, c); if (lua_pcall(L, 2, 1, 0) != 0) { /* two args, 1 result */ fprintf(stdout, "error: %s\n", lua_tostring(L, -1)); lua_pop(L, 2); @@ -498,7 +485,6 @@ extinfo *copy_variants(extinfo * o) return h; } - @ @c static void dump_charinfo_variants(extinfo * o) { @@ -1098,7 +1084,6 @@ void set_font_math_params(internal_font_number f, int b) } } - @ @c int copy_font(int f) { @@ -1358,7 +1343,6 @@ void set_tag_code(internal_font_number f, int c, int i) } } - @ @c void set_lp_code(internal_font_number f, int c, int i) { @@ -1392,10 +1376,8 @@ void set_no_ligatures(internal_font_number f) { int c; charinfo *co; - if (font_tables[f]->ligatures_disabled) return; - co = char_info(f, left_boundarychar); set_charinfo_ligatures(co, NULL); co = char_info(f, right_boundarychar); /* this is weird */ @@ -1410,7 +1392,7 @@ void set_no_ligatures(internal_font_number f) @ @c liginfo get_ligature(internal_font_number f, int lc, int rc) { - int k; + int k = 0; liginfo t, u; charinfo *co; t.lig = 0; @@ -1418,7 +1400,6 @@ liginfo get_ligature(internal_font_number f, int lc, int rc) t.adj = 0; if (lc == non_boundarychar || rc == non_boundarychar || (!has_lig(f, lc))) return t; - k = 0; co = char_info(f, lc); while (1) { u = charinfo_ligature(co, k); @@ -1436,16 +1417,14 @@ liginfo get_ligature(internal_font_number f, int lc, int rc) return t; } - @ @c scaled raw_get_kern(internal_font_number f, int lc, int rc) { - int k; + int k = 0; kerninfo u; charinfo *co; if (lc == non_boundarychar || rc == non_boundarychar) return 0; - k = 0; co = char_info(f, lc); while (1) { u = charinfo_kern(co, k); @@ -1462,7 +1441,6 @@ scaled raw_get_kern(internal_font_number f, int lc, int rc) return 0; } - @ @c scaled get_kern(internal_font_number f, int lc, int rc) { @@ -1715,12 +1693,14 @@ static int undump_charinfo(int f) return i; } -#define undump_font_string(a) undump_int (x); \ - if (x>0) { \ - font_bytes += x; \ - s = xmalloc((unsigned)x); undump_things(*s,x); \ - a(f,s); } - +#define undump_font_string(a) \ + undump_int (x); \ + if (x>0) { \ + font_bytes += x; \ + s = xmalloc((unsigned)x); \ + undump_things(*s,x); \ + a(f,s); \ + } static void undump_font_entry(texfont * f) { @@ -1759,14 +1739,13 @@ static void undump_font_entry(texfont * f) /* *INDENT-ON* */ } - - void undump_font(int f) { int x, i; texfont *tt; charinfo *ci; char *s; + sa_tree_item sa_value = { 0 }; grow_font_table(f); tt = xmalloc(sizeof(texfont)); memset(tt, 0, sizeof(texfont)); @@ -1796,18 +1775,19 @@ void undump_font(int f) undump_things(*math_param_base(f), (font_math_params(f) + 1)); } - font_tables[f]->characters = new_sa_tree(1, 0); /* stack size 1, default item value 0 */ + /* stack size 1, default item value 0 */ + font_tables[f]->characters = new_sa_tree(1, 1, sa_value); ci = xcalloc(1, sizeof(charinfo)); set_charinfo_name(ci, xstrdup(".notdef")); font_tables[f]->charinfo = ci; undump_int(x); if (x) { - i = undump_charinfo(f); - } /* left boundary */ + i = undump_charinfo(f); /* left boundary */ + } undump_int(x); if (x) { - i = undump_charinfo(f); - } /* right boundary */ + i = undump_charinfo(f); /* right boundary */ + } i = font_bc(f); while (i < font_ec(f)) { @@ -1939,7 +1919,7 @@ void read_expand_font(void) normal_error("font expansion","font has been expanded with different auto expansion value"); } else { if (font_used(f)) - normal_warning("font expansion", "font should be expanded before its first use", true, true); + normal_warning("font expansion", "font should be expanded before its first use"); set_expand_params(f, auto_expand, stretch_limit, shrink_limit, font_step); } @@ -1997,14 +1977,13 @@ void make_font_copy(small_number a) void glyph_to_unicode(void) { str_number s1, s2; - scan_pdf_ext_toks(); + scan_toks(false, true); s1 = tokens_to_string(def_ref); delete_token_ref(def_ref); - scan_pdf_ext_toks(); + scan_toks(false, true); s2 = tokens_to_string(def_ref); delete_token_ref(def_ref); def_tounicode(s1, s2); flush_str(s2); flush_str(s1); } - diff --git a/Build/source/texk/web2c/luatexdir/font/tounicode.w b/Build/source/texk/web2c/luatexdir/font/tounicode.w index fe57bbe7e41..c213eee72c5 100644 --- a/Build/source/texk/web2c/luatexdir/font/tounicode.w +++ b/Build/source/texk/web2c/luatexdir/font/tounicode.w @@ -95,9 +95,8 @@ void def_tounicode(str_number glyph, str_number unistr) break; } } - if (l == 0 || valid_unistr == 0 || strlen(buf) == 0 - || strcmp(buf, notdef) == 0) { - luatex_warn("ToUnicode: invalid parameter(s): `%s' => `%s'", buf, p); + if (l == 0 || valid_unistr == 0 || strlen(buf) == 0 || strcmp(buf, notdef) == 0) { + formatted_warning("tounicode", "invalid parameter(s): %s -> %s", buf, p); return; } if (glyph_unicode_tree == NULL) { @@ -308,9 +307,6 @@ int write_tounicode(PDF pdf, char **glyph_names, char *name) int bfchar_count, bfrange_count, subrange_count; assert(strlen(name) + strlen(builtin_suffix) < SMALL_BUF_SIZE); if (glyph_unicode_tree == NULL) { -#ifdef DEBUG - luatex_warn("no GlyphToUnicode entry has been inserted yet!"); -#endif pdf->gen_tounicode = 0; return 0; } diff --git a/Build/source/texk/web2c/luatexdir/font/tt_glyf.w b/Build/source/texk/web2c/luatexdir/font/tt_glyf.w index 0345db62441..167d8df2038 100644 --- a/Build/source/texk/web2c/luatexdir/font/tt_glyf.w +++ b/Build/source/texk/web2c/luatexdir/font/tt_glyf.w @@ -47,7 +47,7 @@ static USHORT find_empty_slot(struct tt_glyphs *g) break; } if (gid == NUM_GLYPH_LIMIT) - TT_ERROR("No empty glyph slot available."); + normal_error("ttf","no empty glyph slot available."); return gid; } @@ -89,10 +89,10 @@ USHORT tt_add_glyph(struct tt_glyphs * g, USHORT gid, USHORT new_gid) ASSERT(g); if (g->used_slot[new_gid / 8] & (1 << (7 - (new_gid % 8)))) { - WARN("Slot %u already used.", new_gid); + formatted_warning("ttf","slot %u already used", new_gid); } else { if (g->num_glyphs + 1 >= NUM_GLYPH_LIMIT) - TT_ERROR("Too many glyphs."); + normal_error("ttf","too many glyphs"); if (g->num_glyphs >= g->max_glyphs) { g->max_glyphs = (USHORT) (g->max_glyphs + GLYPH_ARRAY_ALLOC_SIZE); @@ -193,20 +193,20 @@ int tt_build_tables(sfnt * sfont, struct tt_glyphs *g) ASSERT(g); if (sfont->type != SFNT_TYPE_TRUETYPE && sfont->type != SFNT_TYPE_TTC) - TT_ERROR("Invalid font type"); + normal_error("ttf","invalid font type"); if (g->num_glyphs > NUM_GLYPH_LIMIT) - TT_ERROR("Too many glyphs."); + normal_error("ttf","too many glyphs"); /* Read head, hhea, maxp, loca: - + unitsPerEm --> head numHMetrics --> hhea indexToLocFormat --> head - + numGlyphs --> maxp */ head = tt_read_head_table(sfont); @@ -214,7 +214,7 @@ int tt_build_tables(sfnt * sfont, struct tt_glyphs *g) maxp = tt_read_maxp_table(sfont); if (hhea->metricDataFormat != 0) - TT_ERROR("Unknown metricDataFormat."); + normal_error("ttf","unknown metricDataFormat"); g->emsize = head->unitsPerEm; @@ -252,7 +252,7 @@ int tt_build_tables(sfnt * sfont, struct tt_glyphs *g) for (i = 0; i <= maxp->numGlyphs; i++) location[i] = sfnt_get_ulong(sfont); } else { - TT_ERROR("Unknown IndexToLocFormat."); + normal_error("ttf","unknown IndexToLocFormat"); } w_stat = NEW(g->emsize + 2, USHORT); @@ -280,7 +280,7 @@ int tt_build_tables(sfnt * sfont, struct tt_glyphs *g) gid = g->gd[i].ogid; if (gid >= maxp->numGlyphs) - TT_ERROR("Invalid glyph index (gid %u)", gid); + formatted_error("ttf","invalid glyph index (gid %u)", gid); loc = location[gid]; len = location[gid + 1] - loc; @@ -304,7 +304,7 @@ int tt_build_tables(sfnt * sfont, struct tt_glyphs *g) if (len == 0) { /* Does not contains any data. */ continue; } else if (len < 10) { - TT_ERROR("Invalid TrueType glyph data (gid %u).", gid); + formatted_error("ttf","invalid glyph data (gid %u)", gid); } g->gd[i].data = p = NEW(len, BYTE); @@ -339,8 +339,7 @@ int tt_build_tables(sfnt * sfont, struct tt_glyphs *g) USHORT flags, cgid, new_gid; /* flag, gid of a component */ do { if (p >= endptr) - TT_ERROR("Invalid TrueType glyph data (gid %u): %u bytes", - gid, (unsigned int) len); + formatted_error("ttf","invalid glyph data (gid %u): %u bytes", gid, (unsigned int) len); /* * Flags and gid of component glyph are both USHORT. */ @@ -348,8 +347,7 @@ int tt_build_tables(sfnt * sfont, struct tt_glyphs *g) p += 2; cgid = (USHORT) (((*p) << 8) | *(p + 1)); if (cgid >= maxp->numGlyphs) { - TT_ERROR("Invalid gid (%u > %u) in composite glyph %u.", - cgid, maxp->numGlyphs, gid); + formatted_error("ttf","invalid gid (%u > %u) in composite glyph %u", cgid, maxp->numGlyphs, gid); } new_gid = tt_find_glyph(g, cgid); if (new_gid == 0) { @@ -371,7 +369,7 @@ int tt_build_tables(sfnt * sfont, struct tt_glyphs *g) TrueType instructions comes here: |length_of_instruction| (|ushort|) - + instruction (|byte * length_of_instruction|) */ } @@ -527,14 +525,14 @@ int tt_get_metrics(sfnt * sfont, struct tt_glyphs *g) sfont->stream == NULL #endif ) - TT_ERROR("File not opened."); + normal_error("ttf","file not opened"); if (sfont->type != SFNT_TYPE_TRUETYPE && sfont->type != SFNT_TYPE_TTC) - TT_ERROR("Invalid font type"); + normal_error("ttf","invalid font type"); /* Read head, hhea, maxp, loca: - + unitsPerEm --> head numHMetrics --> hhea @@ -548,7 +546,7 @@ int tt_get_metrics(sfnt * sfont, struct tt_glyphs *g) maxp = tt_read_maxp_table(sfont); if (hhea->metricDataFormat != 0) - TT_ERROR("Unknown metricDataFormat."); + normal_error("ttf","unknown metricDataFormat"); g->emsize = head->unitsPerEm; @@ -580,7 +578,7 @@ int tt_get_metrics(sfnt * sfont, struct tt_glyphs *g) for (i = 0; i <= maxp->numGlyphs; i++) location[i] = sfnt_get_ulong(sfont); } else { - TT_ERROR("Unknown IndexToLocFormat."); + normal_error("ttf","inknown IndexToLocFormat"); } w_stat = NEW(g->emsize + 2, USHORT); @@ -596,7 +594,7 @@ int tt_get_metrics(sfnt * sfont, struct tt_glyphs *g) gid = g->gd[i].ogid; if (gid >= maxp->numGlyphs) - TT_ERROR("Invalid glyph index (gid %u)", gid); + formatted_error("ttf","invalid glyph index (gid %u)", gid); loc = location[gid]; len = location[gid + 1] - loc; @@ -621,7 +619,7 @@ int tt_get_metrics(sfnt * sfont, struct tt_glyphs *g) if (len == 0) { /* Does not contains any data. */ continue; } else if (len < 10) { - TT_ERROR("Invalid TrueType glyph data (gid %u).", gid); + formatted_error("ttf","invalid glyph data (gid %u)", gid); } sfnt_seek_set(sfont, (long) (offset + loc)); diff --git a/Build/source/texk/web2c/luatexdir/font/tt_table.w b/Build/source/texk/web2c/luatexdir/font/tt_table.w index 3ebce2b99ca..8bd2f3b982d 100644 --- a/Build/source/texk/web2c/luatexdir/font/tt_table.w +++ b/Build/source/texk/web2c/luatexdir/font/tt_table.w @@ -45,7 +45,7 @@ char *tt_pack_head_table(struct tt_head_table *table) char *p, *data; if (table == NULL) - TT_ERROR("passed NULL pointer\n"); + normal_error("ttf","passed NULL pointer"); p = data = NEW(TT_HEAD_TABLE_SIZE, char); p += sfnt_put_ulong(p, (LONG) table->version); @@ -205,13 +205,13 @@ struct tt_hhea_table *tt_read_hhea_table(sfnt * sfont) } table->metricDataFormat = sfnt_get_short(sfont); if (table->metricDataFormat != 0) - TT_ERROR("unknown metricDaraFormat"); + normal_error("ttf","unknown metricDaraFormat"); table->numberOfHMetrics = sfnt_get_ushort(sfont); return table; } -@ vhea +@ vhea @c char *tt_pack_vhea_table(struct tt_vhea_table *table) { @@ -279,7 +279,7 @@ struct tt_VORG_table *tt_read_VORG_table(sfnt * sfont) sfnt_locate_table(sfont, "VORG"); if (sfnt_get_ushort(sfont) != 1 || sfnt_get_ushort(sfont) != 0) - TT_ERROR("Unsupported VORG version."); + normal_error("ttf","unsupported VORG version"); vorg->defaultVertOriginY = sfnt_get_short(sfont); vorg->numVertOriginYMetrics = sfnt_get_ushort(sfont); @@ -325,7 +325,7 @@ struct tt_longMetrics *tt_read_longMetrics(sfnt * sfont, USHORT numGlyphs, @ OS/2 table -this table may not exist +this table may not exist @c struct tt_os2__table *tt_read_os2__table(sfnt * sfont) { @@ -398,7 +398,7 @@ tt_get_name(sfnt * sfont, char *dest, USHORT destlen, name_offset = sfnt_locate_table(sfont, "name"); if (sfnt_get_ushort(sfont)) - TT_ERROR("Expecting zero"); + normal_error("ttf","expecting zero"); num_names = sfnt_get_ushort(sfont); string_offset = sfnt_get_ushort(sfont); @@ -443,7 +443,7 @@ USHORT tt_get_ps_fontname(sfnt * sfont, char *dest, USHORT destlen) (namelen = tt_get_name(sfont, dest, destlen, 3, 5, 0x412u, 6)) != 0) return namelen; - fprintf(stderr, "\n** Warning: No valid PostScript name available **\n"); + normal_warning("ttf","no valid PostScript name available"); /* Wrokaround for some bad TTfonts: Language ID value 0xffffu for `accept any language ID' @@ -452,7 +452,7 @@ USHORT tt_get_ps_fontname(sfnt * sfont, char *dest, USHORT destlen) /* Finally falling back to Mac Roman name field. Warning: Some bad Japanese TTfonts using SJIS encoded string in the - Mac Roman name field. + Mac Roman name field. */ namelen = tt_get_name(sfont, dest, destlen, 1, 0, 0, 1); } diff --git a/Build/source/texk/web2c/luatexdir/font/vfovf.w b/Build/source/texk/web2c/luatexdir/font/vfovf.w index d1054a679ab..714ef0f87a9 100644 --- a/Build/source/texk/web2c/luatexdir/font/vfovf.w +++ b/Build/source/texk/web2c/luatexdir/font/vfovf.w @@ -96,19 +96,21 @@ @ go out \.{VF} processing with an error message @c -#define bad_vf(a) { xfree(vf_buffer); print_nlp(); \ - tprint("Error in processing VF font ("); \ - tprint(font_name(f)); \ - tprint(".vf): "); \ - tprint(a); \ - tprint(", virtual font will be ignored"); \ - print_ln(); return; } - -#define lua_bad_vf(a) { xfree(vf_buffer); \ - lua_settop(L,s_top); \ - lua_pushnil(L); \ - lua_pushstring(L,a); \ - return 2; } +#define bad_vf(a) { \ + xfree(vf_buffer); \ + print_nlp(); \ + formatted_warning("virtual font","file '%s', %s, font will be ignored",font_name(f),a); \ + print_ln(); \ + return; \ +} + +#define lua_bad_vf(a) { \ + xfree(vf_buffer); \ + lua_settop(L,s_top); \ + lua_pushnil(L); \ + lua_pushstring(L,a); \ + return 2; \ +} #define tmp_b0 tmp_w.qqqq.b0 #define tmp_b1 tmp_w.qqqq.b1 @@ -129,9 +131,9 @@ typedef struct vf_stack_record { @c #define vf_byte(a) \ { \ - eight_bits vf_tmp_b; \ + eight_bits vf_tmp_b; \ if (vf_cur >= vf_size) { \ - luatex_fail("unexpected eof on virtual font"); \ + normal_error("virtual font","unexpected eof"); \ } \ vf_tmp_b = vf_buffer[vf_cur++]; \ a = vf_tmp_b; \ @@ -185,8 +187,7 @@ void pdf_check_vf(internal_font_number f) } static void -vf_local_font_warning(internal_font_number f, internal_font_number k, - const char *s, int a, int b) +vf_local_font_warning(internal_font_number f, internal_font_number k, const char *s, int a, int b) { print_nlp(); tprint(s); @@ -267,10 +268,10 @@ vf_def_font(internal_font_number f, unsigned char *vf_buffer, int *vf_cr) append_char(junk); } if (level > 5) { - normal_warning("vf","quitting at recurse depth > 5",true,true); + normal_warning("vf","quitting at recurse depth > 5"); k = f ; } else if ((level > 1) && (fs > 65536*1024)) { - normal_warning("vf","quitting when recursing at size > 65536*1024",true,true); + normal_warning("vf","quitting when recursing at size > 65536*1024"); k = f ; } else { level += 1 ; @@ -284,11 +285,9 @@ vf_def_font(internal_font_number f, unsigned char *vf_buffer, int *vf_cr) if (k != null_font) { if (checksum != 0 && font_checksum(k) != 0 && checksum != font_checksum(k)) - vf_local_font_warning(f, k, "checksum mismatch", (int) checksum, - (int) font_checksum(k)); + vf_local_font_warning(f, k, "checksum mismatch", (int) checksum, (int) font_checksum(k)); if (ds != font_dsize(k)) - vf_local_font_warning(f, k, "design size mismatch", ds, - font_dsize(k)); + vf_local_font_warning(f, k, "design size mismatch", ds, font_dsize(k)); } } return k; @@ -1014,31 +1013,31 @@ void do_vf(internal_font_number f) } @ @c -#define make_command0(N,K) { \ - lua_newtable(L); \ - lua_pushstring(L, N); \ - lua_rawseti(L,-2, 1); \ - lua_rawseti(L,-2, K); \ +#define make_command0(N,K) { \ + lua_newtable(L); \ + lua_pushstring(L, N); \ + lua_rawseti(L,-2, 1); \ + lua_rawseti(L,-2, K); \ K++; } -#define make_command1(N,V,K) { \ - lua_newtable(L); \ - lua_pushstring(L, N); \ - lua_rawseti(L,-2, 1); \ - lua_pushnumber(L, V); \ - lua_rawseti(L,-2, 2); \ - lua_rawseti(L,-2, K); \ +#define make_command1(N,V,K) { \ + lua_newtable(L); \ + lua_pushstring(L, N); \ + lua_rawseti(L,-2, 1); \ + lua_pushinteger(L, V); \ + lua_rawseti(L,-2, 2); \ + lua_rawseti(L,-2, K); \ K++; } -#define make_command2(N,V,W,K) { \ - lua_newtable(L); \ - lua_pushstring(L, N); \ - lua_rawseti(L,-2, 1); \ - lua_pushnumber(L, V); \ - lua_rawseti(L,-2, 2); \ - lua_pushnumber(L, W); \ - lua_rawseti(L,-2, 3); \ - lua_rawseti(L,-2, K); \ +#define make_command2(N,V,W,K) { \ + lua_newtable(L); \ + lua_pushstring(L, N); \ + lua_rawseti(L,-2, 1); \ + lua_pushinteger(L, V); \ + lua_rawseti(L,-2, 2); \ + lua_pushinteger(L, W); \ + lua_rawseti(L,-2, 3); \ + lua_rawseti(L,-2, K); \ K++; } #define make_commands(N,S,V,K) { \ @@ -1111,9 +1110,7 @@ int make_vf_table(lua_State * L, const char *cnom, scaled atsize) vf_byte(cs.b1); vf_byte(cs.b2); vf_byte(cs.b3); - lua_pushnumber(L, - (lua_Number) ((cs.b0 << 24) + (cs.b1 << 16) + - (cs.b2 << 8) + cs.b3)); + lua_pushinteger(L, (lua_Number) ((cs.b0 << 24) + (cs.b1 << 16) + (cs.b2 << 8) + cs.b3)); lua_setfield(L, -2, "checksum"); vf_read(4, k); @@ -1150,7 +1147,7 @@ int make_vf_table(lua_State * L, const char *cnom, scaled atsize) vf_read(4, k); fs = store_scaled_f(k, atsize); lua_pushstring(L, "size"); - lua_pushnumber(L, fs); + lua_pushinteger(L, fs); lua_rawset(L, -3); vf_read(4, k); @@ -1198,16 +1195,10 @@ int make_vf_table(lua_State * L, const char *cnom, scaled atsize) vf_read_u(3, utmp); tfm_width = (int) utmp; } - - - lua_newtable(L); /* for this character */ - - lua_pushnumber(L, tfm_width); + lua_pushinteger(L, tfm_width); lua_setfield(L, -2, "width"); - lua_newtable(L); /* for 'commands' */ - k = 1; vf_nf = 0; w = 0; @@ -1217,14 +1208,12 @@ int make_vf_table(lua_State * L, const char *cnom, scaled atsize) while (packet_length > 0) { vf_byte(cmd); decr(packet_length); - if ((cmd >= set_char_0) && (cmd < set1)) { if (vf_nf == 0) { vf_nf = 1; make_command1("font", vf_nf, k); } make_command1("char", cmd, k); - } else if (((fnt_num_0 <= cmd) && (cmd <= fnt_num_0 + 63)) || ((fnt1 <= cmd) && (cmd <= fnt1 + 3))) { if (cmd >= fnt1) { diff --git a/Build/source/texk/web2c/luatexdir/font/vfpacket.w b/Build/source/texk/web2c/luatexdir/font/vfpacket.w index c885d809c96..32b5e634672 100644 --- a/Build/source/texk/web2c/luatexdir/font/vfpacket.w +++ b/Build/source/texk/web2c/luatexdir/font/vfpacket.w @@ -217,8 +217,8 @@ void do_vf_packet(PDF pdf, internal_font_number vf_f, int c, int ex_glyph) packet_scaled(size.v, vp->fs_f); /* height (where is depth?) */ packet_scaled(size.h, vp->fs_f); if (size.h > 0 && size.v > 0) - pdf_place_rule(pdf, 0, size); /* the 0 is unused */ - mat_p->pos.h += size.h; + backend_out[rule_node](pdf, 0, size); /* the 0 is unused */ + mat_p->pos.h += size.h; break; case packet_right_code: packet_scaled(i, vp->fs_f); @@ -255,7 +255,7 @@ void do_vf_packet(PDF pdf, internal_font_number vf_f, int c, int ex_glyph) break; case packet_node_code: packet_number(k); - hlist_out(pdf, (halfword) k); + hlist_out(pdf, (halfword) k, 0); break; case packet_nop_code: break; diff --git a/Build/source/texk/web2c/luatexdir/font/writecff.w b/Build/source/texk/web2c/luatexdir/font/writecff.w index d6e05bca4db..389eed8db76 100644 --- a/Build/source/texk/web2c/luatexdir/font/writecff.w +++ b/Build/source/texk/web2c/luatexdir/font/writecff.w @@ -49,9 +49,6 @@ static unsigned long get_unsigned(cff_font * cff, int n) } @ @c -#define CFF_ERROR luatex_fail -#undef WARN -#define WARN luatex_warn const char *const cff_stdstr[CFF_STDSTR_MAX] = { ".notdef", "space", "exclam", "quotedbl", "numbersign", @@ -163,18 +160,18 @@ cff_index *cff_get_index_header(cff_font * cff) if (count > 0) { idx->offsize = get_card8(cff); if (idx->offsize < 1 || idx->offsize > 4) - CFF_ERROR("invalid offsize data"); + normal_error("cff","invalid offsize data"); idx->offset = xmalloc((unsigned) (((unsigned) count + 1) * sizeof(l_offset))); for (i = 0; i <count + 1 ; i++) { (idx->offset)[i] = get_offset(cff, idx->offsize); - if (i == USHRT_MAX) + if (i == USHRT_MAX) break; } if (idx->offset[0] != 1) - CFF_ERROR("cff_get_index(): invalid index data"); + normal_error("cff","invalid index data"); idx->data = NULL; } else { @@ -201,7 +198,7 @@ cff_index *cff_get_index(cff_font * cff) if (count > 0) { idx->offsize = get_card8(cff); if (idx->offsize < 1 || idx->offsize > 4) - CFF_ERROR("invalid offsize data"); + normal_error("cff","invalid offsize data"); idx->offset = xmalloc((unsigned) (((unsigned) count + 1) * sizeof(l_offset))); @@ -210,7 +207,7 @@ cff_index *cff_get_index(cff_font * cff) } if (idx->offset[0] != 1) - CFF_ERROR("Invalid CFF Index offset data"); + normal_error("cff","invalid index offset data"); length = (size_t) (idx->offset[count] - idx->offset[0]); @@ -236,7 +233,7 @@ long cff_pack_index(cff_index * idx, card8 * dest, long destlen) if (idx->count < 1) { if (destlen < 2) - CFF_ERROR("Not enough space available..."); + normal_error("cff","not enough space available"); memset(dest, 0, 2); return 2; } @@ -245,7 +242,7 @@ long cff_pack_index(cff_index * idx, card8 * dest, long destlen) datalen = idx->offset[idx->count] - 1; if (destlen < len) - CFF_ERROR("Not enough space available..."); + normal_error("cff","not enough space available"); *(dest++) = (card8) ((idx->count >> 8) & 0xff); *(dest++) = (card8) (idx->count & 0xff); @@ -368,7 +365,7 @@ void cff_release_encoding(cff_encoding * encoding) xfree(encoding->data.range1); break; default: - CFF_ERROR("Unknown Encoding format."); + normal_error("cff","unknown encoding format"); } if (encoding->format & 0x80) xfree(encoding->supp); @@ -486,7 +483,7 @@ long cff_set_name(cff_font * cff, char *name) cff_index *idx; if (strlen(name) > 127) - CFF_ERROR("FontName string length too large..."); + normal_error("cff","FontName string length too large"); if (cff->name) cff_release_index(cff->name); @@ -506,7 +503,7 @@ long cff_set_name(cff_font * cff, char *name) long cff_put_header(cff_font * cff, card8 * dest, long destlen) { if (destlen < 4) - CFF_ERROR("Not enough space available..."); + normal_error("cff","not enough space available"); *(dest++) = cff->header_major; *(dest++) = cff->header_minor; @@ -863,9 +860,9 @@ cff_dict *cff_dict_unpack(card8 * data, card8 * endptr) } if (status != CFF_PARSE_OK) { - luatex_fail("Parsing CFF DICT failed. (error=%d)", status); + formatted_error("cff","parsing DICT failed (error=%d)", status); } else if (stack_top != 0) { - WARN("Garbage in CFF DICT data."); + normal_warning("cff","garbage in DICT data"); stack_top = 0; } @@ -899,13 +896,13 @@ double cff_dict_get(cff_dict * dict, const char *key, int idx) if ((dict->entries)[i].count > idx) value = (dict->entries)[i].values[idx]; else - luatex_fail("Invalid index number."); + normal_error("cff","invalid index number"); break; } } if (i == dict->count) - luatex_fail("DICT entry \"%s\" not found.", key); + formatted_error("cff","DICT entry '%s' not found", key); return value; } @@ -917,12 +914,12 @@ card8 cff_fdselect_lookup(cff_font * cff, card16 gid) cff_fdselect *fdsel; if (cff->fdselect == NULL) - CFF_ERROR("in cff_fdselect_lookup(): FDSelect not available"); + normal_error("cff","FDSelect not available"); fdsel = cff->fdselect; if (gid >= cff->num_glyphs) - CFF_ERROR("in cff_fdselect_lookup(): Invalid glyph index"); + normal_error("cff","invalid glyph index"); switch (fdsel->format) { case 0: @@ -943,12 +940,12 @@ card8 cff_fdselect_lookup(cff_font * cff, card16 gid) } break; default: - CFF_ERROR("in cff_fdselect_lookup(): Invalid FDSelect format"); + normal_error("cff","invalid FDSelect format"); break; } if (fd >= cff->num_fds) - CFF_ERROR("in cff_fdselect_lookup(): Invalid Font DICT index"); + normal_error("cff","invalid Font DICT index"); return fd; } @@ -1017,7 +1014,7 @@ long cff_read_fdarray(cff_font * cff) card16 i; if (cff->topdict == NULL) - CFF_ERROR("in cff_read_fdarray(): Top DICT not found"); + normal_error("cff","top DICT not found"); if (!(cff->flag & FONTTYPE_CIDFONT)) return 0; @@ -1117,12 +1114,12 @@ cff_font *read_cff(unsigned char *buf, long buflength, int n) cff->header_hdr_size = get_card8(cff); cff->header_offsize = get_card8(cff); if (cff->header_offsize < 1 || cff->header_offsize > 4) { - WARN("invalid offsize data"); + normal_warning("cff","invalid offsize data"); cff_close(cff); return NULL; } if (cff->header_major > 1) { - luatex_warn("CFF major version %u not supported.", cff->header_major); + formatted_warning("cff","major version %u not supported", cff->header_major); cff_close(cff); return NULL; } @@ -1131,7 +1128,7 @@ cff_font *read_cff(unsigned char *buf, long buflength, int n) /* Name INDEX */ idx = cff_get_index(cff); if (n > idx->count - 1) { - luatex_warn("Invalid CFF fontset index number."); + normal_warning("cff","invalid fontset index number"); cff_close(cff); return NULL; } @@ -1143,14 +1140,14 @@ cff_font *read_cff(unsigned char *buf, long buflength, int n) /* Top DICT INDEX */ idx = cff_get_index(cff); if (n > idx->count - 1) { - WARN("CFF Top DICT not exist..."); + normal_warning("cff","top DICT not exist"); cff_close(cff); return NULL; } cff->topdict = cff_dict_unpack(idx->data + idx->offset[n] - 1, idx->data + idx->offset[n + 1] - 1); if (!cff->topdict) { - WARN("Parsing CFF Top DICT data failed..."); + normal_warning("cff","parsing top DICT data failed"); cff_close(cff); return NULL; } @@ -1158,13 +1155,13 @@ cff_font *read_cff(unsigned char *buf, long buflength, int n) if (cff_dict_known(cff->topdict, "CharstringType") && cff_dict_get(cff->topdict, "CharstringType", 0) != 2) { - WARN("Only Type 2 Charstrings supported..."); + normal_warning("cff","only type 2 charstrings supported"); cff_close(cff); return NULL; } if (cff_dict_known(cff->topdict, "SyntheticBase")) { - WARN("CFF Synthetic font not supported."); + normal_warning("cff","synthetic font not supported"); cff_close(cff); return NULL; } @@ -1214,33 +1211,33 @@ static long pack_integer(card8 * dest, long destlen, long value) if (value >= -107 && value <= 107) { if (destlen < 1) - CFF_ERROR("Buffer overflow."); + normal_error("cff","buffer overflow"); dest[0] = (card8) ((value + 139) & 0xff); len = 1; } else if (value >= 108 && value <= 1131) { if (destlen < 2) - CFF_ERROR("Buffer overflow."); + normal_error("cff","buffer overflow"); value = (long) 0xf700u + value - 108; dest[0] = (card8) ((value >> 8) & 0xff); dest[1] = (card8) (value & 0xff); len = 2; } else if (value >= -1131 && value <= -108) { if (destlen < 2) - CFF_ERROR("Buffer overflow."); + normal_error("cff","buffer overflow"); value = (long) 0xfb00u - value - 108; dest[0] = (card8) ((value >> 8) & 0xff); dest[1] = (card8) (value & 0xff); len = 2; } else if (value >= -32768 && value <= 32767) { /* shortint */ if (destlen < 3) - CFF_ERROR("Buffer overflow."); + normal_error("cff","buffer overflow"); dest[0] = 28; dest[1] = (card8) ((value >> 8) & 0xff); dest[2] = (card8) (value & 0xff); len = 3; } else { /* longint */ if (destlen < 5) - CFF_ERROR("Buffer overflow."); + normal_error("cff","buffer overflow"); dest[0] = 29; dest[1] = (card8) ((value >> 24) & 0xff); dest[2] = (card8) ((value >> 16) & 0xff); @@ -1260,7 +1257,7 @@ static long pack_real(card8 * dest, long destlen, double value) #define CFF_REAL_MAX_LEN 17 if (destlen < 2) - CFF_ERROR("Buffer overflow."); + normal_error("cff","buffer overflow"); dest[0] = 30; @@ -1289,7 +1286,7 @@ static long pack_real(card8 * dest, long destlen, double value) } res=sprintf(work_buffer, "%1.14g", value); - if (res<0) CFF_ERROR("Invalid conversion."); + if (res<0) normal_error("cff","invalid conversion"); if (res>CFF_REAL_MAX_LEN) res=CFF_REAL_MAX_LEN; for (i = 0; i < res; i++) { @@ -1297,18 +1294,18 @@ static long pack_real(card8 * dest, long destlen, double value) if (work_buffer[i] == '\0') { /* res should prevent this. */ - /* CFF_ERROR("Cannot happen"); */ + /* normal_error("cff","cannot happen"); */ break; } else if (work_buffer[i] == '.') { ch = 0x0a; } else if (work_buffer[i] >= '0' && work_buffer[i] <= '9') { ch = (unsigned char) (work_buffer[i] - '0'); } else { - CFF_ERROR("Invalid character."); + normal_error("cff","invalid character"); } if (destlen < pos / 2 + 1) - CFF_ERROR("Buffer overflow."); + normal_error("cff","buffer overflow"); if (pos % 2) { dest[pos / 2] = (card8) (dest[pos / 2] + ch); @@ -1323,7 +1320,7 @@ static long pack_real(card8 * dest, long destlen, double value) dest[pos / 2] = (card8) (dest[pos / 2] + 0x0b); } else { if (destlen < pos / 2 + 1) - CFF_ERROR("Buffer overflow."); + normal_error("cff","buffer overflow"); dest[pos / 2] = (card8) (0xb0); } pos++; @@ -1332,7 +1329,7 @@ static long pack_real(card8 * dest, long destlen, double value) dest[pos / 2] = (card8) (dest[pos / 2] + 0x0c); } else { if (destlen < pos / 2 + 1) - CFF_ERROR("Buffer overflow."); + normal_error("cff","buffer overflow"); dest[pos / 2] = (card8) (0xc0); } e *= -1; @@ -1350,11 +1347,11 @@ static long pack_real(card8 * dest, long destlen, double value) } else if (work_buffer[i] >= '0' && work_buffer[i] <= '9') { ch = (unsigned char) (work_buffer[i] - '0'); } else { - CFF_ERROR("Invalid character."); + normal_error("cff","invalid character"); } if (destlen < pos / 2 + 1) - CFF_ERROR("Buffer overflow."); + normal_error("cff","buffer overflow"); if (pos % 2) { dest[pos / 2] = (card8) (dest[pos / 2] + ch); @@ -1370,7 +1367,7 @@ static long pack_real(card8 * dest, long destlen, double value) pos++; } else { if (destlen < pos / 2 + 1) - CFF_ERROR("Buffer overflow."); + normal_error("cff","buffer overflow"); dest[pos / 2] = (card8) (0xff); pos += 2; } @@ -1392,7 +1389,7 @@ static long cff_dict_put_number(double value, lvalue = (long) value; if (destlen < 5) - CFF_ERROR("Buffer overflow."); + normal_error("cff","buffer overflow"); dest[0] = 29; dest[1] = (card8) ((lvalue >> 24) & 0xff); dest[2] = (card8) ((lvalue >> 16) & 0xff); @@ -1428,15 +1425,15 @@ static long put_dict_entry(cff_dict_entry * de, card8 * dest, long destlen) } if (id >= 0 && id < CFF_LAST_DICT_OP1) { if (len + 1 > destlen) - CFF_ERROR("Buffer overflow."); + normal_error("cff","buffer overflow"); dest[len++] = (card8) id; } else if (id >= 0 && id < CFF_LAST_DICT_OP) { if (len + 2 > destlen) - CFF_ERROR("in cff_dict_pack(): Buffer overflow"); + normal_error("cff","buffer overflow"); dest[len++] = 12; dest[len++] = (card8) (id - CFF_LAST_DICT_OP1); } else { - CFF_ERROR("Invalid CFF DICT operator ID."); + normal_error("cff","invalid DICT operator ID"); } } @@ -1477,12 +1474,12 @@ void cff_dict_add(cff_dict * dict, const char *key, int count) } if (id == CFF_LAST_DICT_OP) - CFF_ERROR("Unknown CFF DICT operator."); + normal_error("cff","unknown DICT operator"); for (i = 0; i < dict->count; i++) { if ((dict->entries)[i].id == id) { if ((dict->entries)[i].count != count) - CFF_ERROR("Inconsistent DICT argument number."); + normal_error("cff","inconsistent DICT argument number"); return; } } @@ -1534,13 +1531,13 @@ void cff_dict_set(cff_dict * dict, const char *key, int idx, double value) if ((dict->entries)[i].count > idx) (dict->entries)[i].values[idx] = value; else - CFF_ERROR("Invalid index number."); + normal_error("cff","invalid index number"); break; } } if (i == dict->count) - luatex_fail("DICT entry \"%s\" not found.", key); + formatted_error("cff","DICT entry '%s' not found", key); } @@ -1601,7 +1598,7 @@ long cff_get_sid(cff_font * cff, const char *str) void cff_update_string(cff_font * cff) { if (cff == NULL) - CFF_ERROR("CFF font not opened."); + normal_error("cff","CFF font not opened"); if (cff->string) cff_release_index(cff->string); @@ -1618,7 +1615,7 @@ s_SID cff_add_string(cff_font * cff, const char *str) l_offset offset, size; if (cff == NULL) - CFF_ERROR("CFF font not opened."); + normal_error("cff","CFF font not opened"); if (cff->_string == NULL) cff->_string = cff_new_index(0); @@ -1693,7 +1690,7 @@ long cff_read_charsets(cff_font * cff) card16 count, i; if (cff->topdict == NULL) - CFF_ERROR("Top DICT not available"); + normal_error("cff","top DICT not available"); if (!cff_dict_known(cff->topdict, "charset")) { cff->flag |= CHARSETS_ISOADOBE; @@ -1773,13 +1770,13 @@ long cff_read_charsets(cff_font * cff) break; default: xfree(charset); - CFF_ERROR("Unknown Charset format"); + normal_error("cff","unknown charset format"); break; } if (count > 0) { /* fprintf(stdout, "count=%d\n", count); */ - WARN("Charset data possibly broken (num_glyphs too high)"); + normal_warning("cff","charset data possibly broken (too many glyphs)"); } return length; @@ -1796,7 +1793,7 @@ long cff_pack_charsets(cff_font * cff, card8 * dest, long destlen) return 0; if (destlen < 1) - CFF_ERROR("in cff_pack_charsets(): Buffer overflow"); + normal_error("cff","buffer overflow"); charset = cff->charsets; @@ -1804,7 +1801,7 @@ long cff_pack_charsets(cff_font * cff, card8 * dest, long destlen) switch (charset->format) { case 0: if (destlen < len + (charset->num_entries) * 2) - CFF_ERROR("in cff_pack_charsets(): Buffer overflow"); + normal_error("cff","buffer overflow"); for (i = 0; i < (charset->num_entries); i++) { s_SID sid = (charset->data).glyphs[i]; /* or CID */ dest[len++] = (card8) ((sid >> 8) & 0xff); @@ -1814,7 +1811,7 @@ long cff_pack_charsets(cff_font * cff, card8 * dest, long destlen) case 1: { if (destlen < len + (charset->num_entries) * 3) - CFF_ERROR("in cff_pack_charsets(): Buffer overflow"); + normal_error("cff","buffer overflow"); for (i = 0; i < (charset->num_entries); i++) { dest[len++] = (card8) (((charset->data).range1[i].first >> 8) & 0xff); @@ -1826,7 +1823,7 @@ long cff_pack_charsets(cff_font * cff, card8 * dest, long destlen) case 2: { if (destlen < len + (charset->num_entries) * 4) - CFF_ERROR("in cff_pack_charsets(): Buffer overflow"); + normal_error("cff","buffer overflow"); for (i = 0; i < (charset->num_entries); i++) { dest[len++] = (card8) (((charset->data).range2[i].first >> 8) & 0xff); @@ -1838,7 +1835,7 @@ long cff_pack_charsets(cff_font * cff, card8 * dest, long destlen) } break; default: - CFF_ERROR("Unknown Charset format"); + normal_error("cff","unknown charset format"); break; } @@ -2022,7 +2019,7 @@ static void clear_stack(card8 ** dest, card8 * limit) This number cannot be represented as a single operand. We must use `a b mul ...' or `a c div' to represent large values. */ - CFF_ERROR("Argument value too large. (This is bug)"); + normal_error("cff","argument value too large (this is bug)"); } else if (fabs(value - (double) ivalue) > 3.0e-5) { /* 16.16-bit signed fixed value */ DST_NEED(limit, *dest + 5); @@ -2053,7 +2050,7 @@ static void clear_stack(card8 ** dest, card8 * limit) *(*dest)++ = (card8) ((ivalue >> 8) & 0xff); *(*dest)++ = (card8) ((ivalue) & 0xff); } else { /* Shouldn't come here */ - CFF_ERROR("Unexpected error."); + normal_error("cff","unexpected error"); } } @@ -2144,11 +2141,11 @@ do_operator1(card8 ** dest, card8 * limit, card8 ** data, card8 * endptr) width = cs2_arg_stack[0]; clear_stack(dest, limit); } else if (cs2_stack_top == 4 || cs2_stack_top == 5) { - WARN("\"seac\" character deprecated in Type 2 charstring."); + normal_warning("cff","'seac' character deprecated in type 2 charstring"); status = CS_PARSE_CFF_ERROR; return; } else if (cs2_stack_top > 0) { - WARN("Operand stack not empty."); + normal_warning("cff","operand stack not empty"); } DST_NEED(limit, *dest + 1); *(*dest)++ = op; @@ -2166,7 +2163,7 @@ do_operator1(card8 ** dest, card8 * limit, card8 ** data, card8 * endptr) case cs_vhcurveto: case cs_hvcurveto: if (phase < 2) { - WARN("Broken Type 2 charstring."); + normal_warning("cff","broken type 2 charstring"); status = CS_PARSE_CFF_ERROR; return; } @@ -2179,11 +2176,11 @@ do_operator1(card8 ** dest, card8 * limit, card8 ** data, card8 * endptr) case cs_return: case cs_callgsubr: case cs_callsubr: - CFF_ERROR("Unexpected call(g)subr/return"); + normal_error("cff","unexpected call(g)subr/return"); break; default: /* no-op ? */ - WARN("%s: Unknown charstring operator: 0x%02x", CS_TYPE2_DEBUG_STR, op); + formatted_warning("cff","%s: unknown charstring operator: 0x%02x", CS_TYPE2_DEBUG_STR, op); status = CS_PARSE_CFF_ERROR; break; } @@ -2213,7 +2210,7 @@ do_operator2(card8 ** dest, card8 * limit, card8 ** data, card8 * endptr) switch (op) { case cs_dotsection: /* deprecated */ - WARN("Operator \"dotsection\" deprecated in Type 2 charstring."); + normal_warning("cff","Operator 'dotsection' deprecated in type 2 charstring"); status = CS_PARSE_CFF_ERROR; return; break; @@ -2222,7 +2219,7 @@ do_operator2(card8 ** dest, card8 * limit, card8 ** data, card8 * endptr) case cs_hflex1: case cs_flex1: if (phase < 2) { - WARN("%s: Broken Type 2 charstring.", CS_TYPE2_DEBUG_STR); + formatted_warning("cff","%s: broken type 2 charstring", CS_TYPE2_DEBUG_STR); status = CS_PARSE_CFF_ERROR; return; } @@ -2391,14 +2388,13 @@ do_operator2(card8 ** dest, card8 * limit, card8 ** data, card8 * endptr) } break; case cs_random: - WARN("%s: Charstring operator \"random\" found.", CS_TYPE2_DEBUG_STR); + formatted_warning("cff","%s: Charstring operator 'random' found.", CS_TYPE2_DEBUG_STR); NEED(CS_ARG_STACK_MAX, cs2_stack_top + 1); cs2_arg_stack[cs2_stack_top++] = 1.0; break; default: /* no-op ? */ - WARN("%s: Unknown charstring operator: 0x0c%02x", CS_TYPE2_DEBUG_STR, - op); + formatted_warning("cff","%s: unknown charstring operator: 0x0c%02x", CS_TYPE2_DEBUG_STR, op); status = CS_PARSE_CFF_ERROR; break; } @@ -2487,8 +2483,7 @@ static void get_subr(card8 ** subr, long *len, cff_index * subr_idx, long id) card16 count; if (subr_idx == NULL) - CFF_ERROR("%s: Subroutine called but no subroutine found.", - CS_TYPE2_DEBUG_STR); + formatted_error("cff","%s: subroutine called but no subroutine found",CS_TYPE2_DEBUG_STR); count = subr_idx->count; @@ -2502,8 +2497,7 @@ static void get_subr(card8 ** subr, long *len, cff_index * subr_idx, long id) } if (id > count) - CFF_ERROR("%s: Invalid Subr index: %ld (max=%u)", CS_TYPE2_DEBUG_STR, - id, count); + formatted_error("cff","%s: invalid subroutine index: %ld (max=%u)", CS_TYPE2_DEBUG_STR, id, count); *len = (long) ((subr_idx->offset)[id + 1] - (subr_idx->offset)[id]); *subr = subr_idx->data + (subr_idx->offset)[id] - 1; @@ -2527,7 +2521,7 @@ do_charstring(card8 ** dest, card8 * limit, long len; if (cs2_nest > CS_SUBR_NEST_MAX) - CFF_ERROR("%s: Subroutine nested too deeply.", CS_TYPE2_DEBUG_STR); + formatted_error("cff","%s: subroutine nested too deeply", CS_TYPE2_DEBUG_STR); cs2_nest++; @@ -2545,10 +2539,8 @@ do_charstring(card8 ** dest, card8 * limit, get_subr(&subr, &len, gsubr_idx, (long) cs2_arg_stack[cs2_stack_top]); if (*dest + len > limit) - CFF_ERROR("%s: Possible buffer overflow.", - CS_TYPE2_DEBUG_STR); - do_charstring(dest, limit, &subr, subr + len, gsubr_idx, - subr_idx); + formatted_error("cff","%s: possible buffer overflow", CS_TYPE2_DEBUG_STR); + do_charstring(dest, limit, &subr, subr + len, gsubr_idx, subr_idx); *data += 1; } } else if (b0 == cs_callsubr) { @@ -2559,10 +2551,8 @@ do_charstring(card8 ** dest, card8 * limit, get_subr(&subr, &len, subr_idx, (long) cs2_arg_stack[cs2_stack_top]); if (limit < *dest + len) - CFF_ERROR("%s: Possible buffer overflow.", - CS_TYPE2_DEBUG_STR); - do_charstring(dest, limit, &subr, subr + len, gsubr_idx, - subr_idx); + formatted_error("cff","%s: possible buffer overflow", CS_TYPE2_DEBUG_STR); + do_charstring(dest, limit, &subr, subr + len, gsubr_idx, subr_idx); *data += 1; } } else if (b0 == cs_escape) { @@ -2579,10 +2569,9 @@ do_charstring(card8 ** dest, card8 * limit, if (status == CS_SUBR_RETURN) { status = CS_PARSE_OK; } else if (status == CS_CHAR_END && *data < endptr) { - WARN("%s: Garbage after endchar.", CS_TYPE2_DEBUG_STR); + formatted_warning("cff","%s: garbage after endchar", CS_TYPE2_DEBUG_STR); } else if (status < CS_PARSE_OK) { /* error */ - CFF_ERROR("%s: Parsing charstring failed: (status=%d, stack=%d)", - CS_TYPE2_DEBUG_STR, status, cs2_stack_top); + formatted_error("cff","%s: parsing charstring failed: (status=%d, stack=%d)", CS_TYPE2_DEBUG_STR, status, cs2_stack_top); } cs2_nest--; @@ -2645,7 +2634,7 @@ long cff_read_encoding(cff_font * cff) card8 i; if (cff->topdict == NULL) { - CFF_ERROR("Top DICT data not found"); + normal_error("cff","top DICT data not found"); } if (!cff_dict_known(cff->topdict, "Encoding")) { @@ -2694,7 +2683,7 @@ long cff_read_encoding(cff_font * cff) break; default: xfree(encoding); - CFF_ERROR("Unknown Encoding format"); + normal_error("cff","unknown encoding format"); break; } @@ -2727,7 +2716,7 @@ long cff_pack_encoding(cff_font * cff, card8 * dest, long destlen) return 0; if (destlen < 2) - CFF_ERROR("in cff_pack_encoding(): Buffer overflow"); + normal_error("cff","buffer overflow"); encoding = cff->encoding; @@ -2736,7 +2725,7 @@ long cff_pack_encoding(cff_font * cff, card8 * dest, long destlen) switch (encoding->format & (~0x80)) { case 0: if (destlen < len + encoding->num_entries) - CFF_ERROR("in cff_pack_encoding(): Buffer overflow"); + normal_error("cff","buffer overflow"); for (i = 0; i < (encoding->num_entries); i++) { dest[len++] = (encoding->data).codes[i]; } @@ -2744,7 +2733,7 @@ long cff_pack_encoding(cff_font * cff, card8 * dest, long destlen) case 1: { if (destlen < len + (encoding->num_entries) * 2) - CFF_ERROR("in cff_pack_encoding(): Buffer overflow"); + normal_error("cff","buffer overflow"); for (i = 0; i < (encoding->num_entries); i++) { dest[len++] = (card8) ((encoding->data).range1[i].first & 0xff); dest[len++] = (card8) ((encoding->data).range1[i].n_left); @@ -2752,13 +2741,13 @@ long cff_pack_encoding(cff_font * cff, card8 * dest, long destlen) } break; default: - CFF_ERROR("Unknown Encoding format"); + normal_error("cff","unknown encoding format"); break; } if ((encoding->format) & 0x80) { if (destlen < len + (encoding->num_supps) * 3 + 1) - CFF_ERROR("in cff_pack_encoding(): Buffer overflow"); + normal_error("cff","buffer overflow"); dest[len++] = encoding->num_supps; for (i = 0; i < (encoding->num_supps); i++) { dest[len++] = (card8) ((encoding->supp)[i].code); @@ -2779,7 +2768,7 @@ long cff_read_fdselect(cff_font * cff) card16 i; if (cff->topdict == NULL) - CFF_ERROR("Top DICT not available"); + normal_error("cff","top DICT not available"); if (!(cff->flag & FONTTYPE_CIDFONT)) return 0; @@ -2811,15 +2800,15 @@ long cff_read_fdselect(cff_font * cff) ranges[i].fd = get_card8(cff); } if (ranges[0].first != 0) - CFF_ERROR("Range not starting with 0."); + normal_error("cff","range not starting with 0"); if (cff->num_glyphs != get_card16(cff)) - CFF_ERROR("Sentinel value mismatched with number of glyphs."); + normal_error("cff","sentinel value mismatched with number of glyphs"); length += (fdsel->num_entries) * 3 + 4; } break; default: xfree(fdsel); - CFF_ERROR("Unknown FDSelect format."); + normal_error("cff","unknown FDSelect format"); break; } @@ -2838,7 +2827,7 @@ long cff_pack_fdselect(cff_font * cff, card8 * dest, long destlen) return 0; if (destlen < 1) - CFF_ERROR("in cff_pack_fdselect(): Buffur overflow"); + normal_error("cff","buffer overflow"); fdsel = cff->fdselect; @@ -2846,9 +2835,9 @@ long cff_pack_fdselect(cff_font * cff, card8 * dest, long destlen) switch (fdsel->format) { case 0: if (fdsel->num_entries != cff->num_glyphs) - CFF_ERROR("in cff_pack_fdselect(): Invalid data"); + normal_error("cff","invalid data"); if (destlen < len + fdsel->num_entries) - CFF_ERROR("in cff_pack_fdselect(): Buffer overflow"); + normal_error("cff","buffer overflow"); for (i = 0; i < fdsel->num_entries; i++) { dest[len++] = (fdsel->data).fds[i]; } @@ -2856,18 +2845,18 @@ long cff_pack_fdselect(cff_font * cff, card8 * dest, long destlen) case 3: { if (destlen < len + 2) - CFF_ERROR("in cff_pack_fdselect(): Buffer overflow"); + normal_error("cff","buffer overflow"); len += 2; for (i = 0; i < (fdsel->num_entries); i++) { if (destlen < len + 3) - CFF_ERROR("in cff_pack_fdselect(): Buffer overflow"); + normal_error("cff","buffer overflow"); dest[len++] = (card8) (((fdsel->data).ranges[i].first >> 8) & 0xff); dest[len++] = (card8) ((fdsel->data).ranges[i].first & 0xff); dest[len++] = (card8) ((fdsel->data).ranges[i].fd); } if (destlen < len + 2) - CFF_ERROR("in cff_pack_fdselect(): Buffer overflow"); + normal_error("cff","buffer overflow"); dest[len++] = (card8) ((cff->num_glyphs >> 8) & 0xff); dest[len++] = (card8) (cff->num_glyphs & 0xff); dest[1] = (card8) (((len / 3 - 1) >> 8) & 0xff); @@ -2875,7 +2864,7 @@ long cff_pack_fdselect(cff_font * cff, card8 * dest, long destlen) } break; default: - CFF_ERROR("Unknown FDSelect format."); + normal_error("cff","unknown FDSelect format"); break; } @@ -3012,9 +3001,9 @@ static void write_fontfile(PDF pdf, cff_font * cffont, char *fullname) @c #define DO_COPY_CHARSTRING() \ if ((avl_find(fd->gl_tree,glyph) != NULL)) { \ - size = (long)(cs_idx->offset[code+1] - cs_idx->offset[code]); \ + size = (long)(cs_idx->offset[code+1] - cs_idx->offset[code]); \ if (size > CS_STR_LEN_MAX) { \ - luatex_fail("Charstring too long: gid=%u, %ld bytes", code, size); \ + formatted_error("cff","charstring too long: gid=%u, %ld bytes", code, size); \ } \ if (charstring_len + CS_STR_LEN_MAX >= max_len) { \ max_len = (long)(charstring_len + 2 * CS_STR_LEN_MAX); \ @@ -3154,7 +3143,7 @@ void write_cff(PDF pdf, cff_font * cffont, fd_entry * fd) offset = (long) cffont->offset; cs_count1 = cs_idx->count; if (cs_count1 < 2) { - CFF_ERROR("No valid charstring data found."); + normal_error("cff","no valid charstring data found"); } /* build the new charstrings entry */ @@ -3203,7 +3192,7 @@ void write_cff(PDF pdf, cff_font * cffont, fd_entry * fd) /* this happens if the internal metrics do not agree with the actual disk font */ if (gid < num_glyphs) { - WARN("embedded subset is smaller than expected: %d instead of %d glyphs.", gid, num_glyphs); + formatted_warning("cff","embedded subset is smaller than expected: %d instead of %d glyphs", gid, num_glyphs); num_glyphs = gid; } @@ -3268,7 +3257,7 @@ card16 cff_charsets_lookup(cff_font * cff, card16 cid) if (cff->flag & (CHARSETS_ISOADOBE | CHARSETS_EXPERT | CHARSETS_EXPSUB)) { ERROR("Predefined CFF charsets not supported yet"); } else if (cff->charsets == NULL) { - ERROR("Charsets data not available"); + normal_error("cff","charsets data not available"); } if (cid == 0) { @@ -3312,7 +3301,7 @@ card16 cff_charsets_lookup(cff_font * cff, card16 cid) } break; default: - ERROR("Unknown Charset format"); + normal_error("cff","unknown charset format"); } return 0; /* not found */ @@ -3425,7 +3414,7 @@ void write_cid_cff(PDF pdf, cff_font * cffont, fd_entry * fd) offset = (long) cffont->offset; cs_count1 = cs_idx->count; if (cs_count1 < 2) { - CFF_ERROR("No valid charstring data found."); + normal_error("cff","no valid charstring data found"); } charset = xcalloc(1, sizeof(cff_charsets)); @@ -3458,7 +3447,7 @@ void write_cid_cff(PDF pdf, cff_font * cffont, fd_entry * fd) (CIDToGIDMap[2 * cid + 1])); size = (long) (cs_idx->offset[gid_org + 1] - cs_idx->offset[gid_org]); if (size > CS_STR_LEN_MAX) { - luatex_fail("Charstring too long: gid=%u, %ld bytes", cid, size); + formatted_error("cff","charstring too long: gid=%u, %ld bytes", cid, size); } if (charstring_len + CS_STR_LEN_MAX >= max_len) { max_len = charstring_len + 2 * CS_STR_LEN_MAX; @@ -3492,7 +3481,7 @@ void write_cid_cff(PDF pdf, cff_font * cffont, fd_entry * fd) } if (gid != num_glyphs) - CFF_ERROR("Unexpected error: %i != %i", gid, num_glyphs); + formatted_error("cff","unexpected error: %i != %i", gid, num_glyphs); xfree(data); cff_release_index(cs_idx); diff --git a/Build/source/texk/web2c/luatexdir/font/writefont.w b/Build/source/texk/web2c/luatexdir/font/writefont.w index bbe2524b40b..81a8b0f9b04 100644 --- a/Build/source/texk/web2c/luatexdir/font/writefont.w +++ b/Build/source/texk/web2c/luatexdir/font/writefont.w @@ -41,7 +41,7 @@ const key_entry font_key[FONT_KEYS_NUM] = { , {"FontName", "FontName", 1} }; -@ +@ @c struct avl_table *fo_tree = NULL; /* tree of font dictionaries */ struct avl_table *fd_tree = NULL; /* tree of font descriptor objects */ @@ -62,7 +62,7 @@ static int comp_fd_entry(const void *pa, const void *pb, void *p) return strcmp(p1->fm->ff_name, p2->fm->ff_name); } -@ initialize data structure for /Type /Font +@ initialize data structure for /Type /Font @c static fo_entry *new_fo_entry(void) { @@ -187,7 +187,7 @@ static void write_fontmetrics(PDF pdf, fd_entry * fd) pdf_dict_add_int(pdf, font_key[i].pdfname, fd->font_dim[i].val); } -@ +@ @c static void preset_fontname(fo_entry * fo, internal_font_number f) { @@ -217,7 +217,7 @@ static void pdf_dict_add_fontname(PDF pdf, const char *key, fd_entry * fd) xfree(s); } -@ +@ @c fd_entry *lookup_fd_entry(char *s) { @@ -268,7 +268,7 @@ static void create_fontdescriptor(fo_entry * fo, internal_font_number f) assert(fo->fd->gl_tree != NULL); } -@ +@ For all used characters of \TeX font |f|, get corresponding glyph names from external reencoding (.enc) file and collect these in the glyph tree |gl_tree| of font descriptor |fd| referenced by font dictionary |fo|. @@ -431,7 +431,7 @@ static void write_fontfile(PDF pdf, fd_entry * fd) if (is_opentype(fd->fm)) { writetype0(pdf, fd); } else if (is_truetype(fd->fm)) { - if (!writetype2(pdf, fd)) { + if (!writetype2(pdf, fd)) { writetype0(pdf,fd); fd->fm->type |= F_OTF; fd->fm->type ^= F_TRUETYPE; } @@ -529,9 +529,8 @@ static void write_fontdescriptor(PDF pdf, fd_entry * fd) fd_flags = is_std_t1font(fd->fm) ? std_flags[check_std_t1font(fd->fm->ps_name)] : FD_FLAGS_DEFAULT_NON_EMBED; - luatex_warn - ("No flags specified for non-embedded font `%s' (%s) (I'm using %i): " - "fix your map entry.", + formatted_warning("map file", + "No flags specified for non-embedded font '%s' (%s), I'm using %i, fix your map entry", fd->fm->ps_name != NULL ? fd->fm->ps_name : "No name given", fd->fm->tfm_name, fd_flags); } @@ -720,9 +719,8 @@ static void create_fontdictionary(PDF pdf, internal_font_number f) create_fontdescriptor(fo, f); write_fontdescriptor(pdf, fo->fd); if (!is_std_t1font(fo->fm)) - luatex_warn("font `%s' is not a standard font; " - "I suppose it is available to your PDF viewer then", - fo->fm->ps_name); + formatted_warning("map file", "font '%s' is not a standard font; I suppose it is available to your PDF viewer then", + fo->fm->ps_name); } if (is_type1(fo->fm)) register_fo_entry(fo); @@ -784,9 +782,7 @@ void do_pdf_font(PDF pdf, internal_font_number f) fm->ff_name = s; del_file = 1; } else { - luatex_fail - ("writefont.c: The file (%s) does not contain font `%s'", - fm->ff_name, fm->ps_name); + formatted_error("font","file '%s' does not contain font '%s'",fm->ff_name, fm->ps_name); } } fm->encname = font_encodingname(f); /* for the CIDSystemInfo */ @@ -812,9 +808,8 @@ void do_pdf_font(PDF pdf, internal_font_number f) set_type1(fm); break; default: - luatex_fail - ("writefont.c: The file format (%s) for font `%s' is incompatible with wide characters\n", - font_format_name(f), font_name(f)); + formatted_error("font","file format '%s' for '%s' is incompatible with wide characters", + font_format_name(f), font_name(f)); } /* This makes "unknown" default to subsetted inclusion */ if (font_embedding(f) != no_embedding) { @@ -996,7 +991,7 @@ static void create_cid_fontdictionary(PDF pdf, internal_font_number f) avl_destroy(fo->fd->gl_tree,destroy_glw_cid_entry); } xfree(fo->fd); - } + } xfree(fo); } diff --git a/Build/source/texk/web2c/luatexdir/font/writet1.w b/Build/source/texk/web2c/luatexdir/font/writet1.w index 16dff008e73..f328dbd17fc 100644 --- a/Build/source/texk/web2c/luatexdir/font/writet1.w +++ b/Build/source/texk/web2c/luatexdir/font/writet1.w @@ -254,7 +254,7 @@ static void enc_getline(void) char c; restart: if (enc_eof()) - luatex_fail("unexpected end of file"); + normal_error("type 1","unexpected end of file"); p = enc_line; do { c = (char) enc_getchar(); @@ -280,21 +280,20 @@ char **load_enc_file(char *enc_name) cur_file_name = luatex_find_file(enc_name, find_enc_file_callback); if (cur_file_name == NULL) { - luatex_fail("cannot find encoding file '%s' for reading", enc_name); + formatted_error("type 1","cannot find encoding file '%s' for reading", enc_name); } callback_id = callback_defined(read_enc_file_callback); enc_curbyte = 0; enc_size = 0; if (callback_id > 0) { - if (run_callback(callback_id, "S->bSd", cur_file_name, - &file_opened, &enc_buffer, &enc_size)) { + if (run_callback(callback_id, "S->bSd", cur_file_name, &file_opened, &enc_buffer, &enc_size)) { if ((!file_opened) || enc_size == 0) { - luatex_fail("cannot open encoding file '%s' for reading", cur_file_name); + formatted_error("type 1","cannot open encoding file '%s' for reading", cur_file_name); } } } else { if (!enc_open(cur_file_name)) { - luatex_fail("cannot open encoding file '%s' for reading", cur_file_name); + formatted_error("type 1","cannot open encoding file '%s' for reading", cur_file_name); } enc_read_file(); enc_close(); @@ -306,8 +305,7 @@ char **load_enc_file(char *enc_name) enc_getline(); if (*enc_line != '/' || (r = strchr(enc_line, '[')) == NULL) { remove_eol(r, enc_line); - luatex_fail - ("invalid encoding vector (a name or `[' missing): `%s'", enc_line); + formatted_error("type 1","invalid encoding vector (a name or '[' missing): '%s'", enc_line); } names_count = 0; r++; /* skip '[' */ @@ -319,7 +317,7 @@ char **load_enc_file(char *enc_name) *p = 0; skip(r, ' '); if (names_count >= 256) - luatex_fail("encoding vector contains more than 256 names"); + normal_error("type 1","encoding vector contains more than 256 names"); if (strcmp(buf, notdef) != 0) glyph_names[names_count] = xstrdup(buf); names_count++; @@ -329,9 +327,7 @@ char **load_enc_file(char *enc_name) goto done; else { remove_eol(r, enc_line); - luatex_fail - ("invalid encoding vector: a name or `] def' expected: `%s'", - enc_line); + formatted_error("type 1","invalid encoding vector: a name or '] def' expected: `%s'",enc_line); } } enc_getline(); @@ -371,7 +367,7 @@ static int t1_getbyte(void) return c; if (t1_block_length == 0) { if (c != 128) - luatex_fail("invalid marker"); + normal_error("type 1","invalid marker"); c = t1_getchar(); if (c == 3) { while (!t1_eof()) @@ -451,7 +447,7 @@ static float t1_scan_num(char *p, char **r) skip(p, ' '); if (sscanf(p, "%g", &f) != 1) { remove_eol(p, t1_line_array); - luatex_fail("a number expected: `%s'", t1_line_array); + formatted_error("type 1","a number expected: '%s'", t1_line_array); } if (r != NULL) { for (; isdigit((unsigned char)*p) || *p == '.' || @@ -483,7 +479,7 @@ static void t1_getline(void) static int eexec_len = 17; /* |strlen(eexec_str)| */ restart: if (t1_eof()) - luatex_fail("unexpected end of file"); + normal_error("type 1","unexpected end of file"); t1_line_ptr = t1_line_array; alloc_array(t1_line, 1, T1_BUF_SIZE); t1_cslen = 0; @@ -599,7 +595,7 @@ static void t1_check_block_len(boolean decrypt) c = edecrypt((byte) c); l = (int) t1_block_length; if (!(l == 0 && (c == 10 || c == 13))) { - luatex_fail("%i bytes more than expected were ignored", l + 1); + formatted_error("type 1","%i bytes more than expected were ignored", l + 1); } } @@ -636,7 +632,7 @@ static void t1_stop_eexec(PDF pdf) if (last_hexbyte == 0) t1_puts(pdf, "00"); else - luatex_fail("unexpected data after eexec"); + normal_error("type 1","unexpected data after eexec"); } } t1_cs = false; @@ -674,7 +670,7 @@ static void t1_scan_keys(PDF pdf) if (t1_prefix("/FontType")) { p = t1_line_array + strlen("FontType") + 1; if ((i = (int) t1_scan_num(p, 0)) != 1) - luatex_fail("Type%d fonts unsupported by pdfTeX", i); + formatted_error("type 1","Type%d fonts unsupported by backend", i); return; } for (key = (const key_entry *) font_key; key - font_key < FONT_KEYS_NUM; @@ -690,7 +686,7 @@ static void t1_scan_keys(PDF pdf) if ((k = (int) (key - font_key)) == FONTNAME_CODE) { if (*p != '/') { remove_eol(p, t1_line_array); - luatex_fail("a name expected: `%s'", t1_line_array); + formatted_error("type 1","a name expected: '%s'", t1_line_array); } r = ++p; /* skip the slash */ for (q = t1_buf_array; *p != ' ' && *p != 10; *q++ = *p++); @@ -732,7 +728,7 @@ static void t1_scan_param(PDF pdf) if (t1_prefix(lenIV)) { t1_lenIV = (short) t1_scan_num(t1_line_array + strlen(lenIV), 0); if (t1_lenIV < 0) - luatex_fail("negative value of lenIV is not supported"); + normal_error("type 1","negative value of lenIV is not supported"); return; } t1_scan_keys(pdf); @@ -770,9 +766,7 @@ static char **t1_builtin_enc(void) } return glyph_names; } else - luatex_fail - ("cannot subset font (unknown predefined encoding `%s')", - t1_buf_array); + formatted_error("type 1","cannot subset font (unknown predefined encoding '%s')",t1_buf_array); } /* At this moment \.{/Encoding} is the prefix of |t1_line_array|, and the encoding is not a predefined encoding. @@ -802,7 +796,7 @@ static char **t1_builtin_enc(void) *p = 0; skip(r, ' '); if (counter > 255) - luatex_fail("encoding vector contains more than 256 names"); + normal_error("type 1","encoding vector contains more than 256 names"); if (strcmp(t1_buf_array, notdef) != 0) glyph_names[counter] = xstrdup(t1_buf_array); counter++; @@ -812,9 +806,7 @@ static char **t1_builtin_enc(void) break; else { remove_eol(r, t1_line_array); - luatex_fail - ("a name or `] def' or `] readonly def' expected: `%s'", - t1_line_array); + formatted_error("type 1","a name or '] def' or '] readonly def' expected: '%s'", t1_line_array); } } t1_getline(); @@ -900,23 +892,19 @@ static boolean t1_open_fontfile(int open_name_prefix) t1_size = 0; ff = check_ff_exist(fd_cur->fm->ff_name, is_truetype(fd_cur->fm)); if (ff->ff_path == NULL) { - luatex_fail("cannot open Type 1 font file for reading (%s)", - fd_cur->fm->ff_name); + formatted_error("type 1","cannot open file for reading '%s'",fd_cur->fm->ff_name); return false; } cur_file_name = luatex_find_file(ff->ff_path, find_type1_file_callback); if (cur_file_name == NULL) { - luatex_fail("cannot open Type 1 font file for reading (%s)", - ff->ff_path); + formatted_error("type 1","cannot open file for reading '%s'", ff->ff_path); return false; } callback_id = callback_defined(read_type1_file_callback); if (callback_id > 0) { - if (!run_callback(callback_id, "S->bSd", cur_file_name, - &file_opened, &t1_buffer, &t1_size) + if (!run_callback(callback_id, "S->bSd", cur_file_name, &file_opened, &t1_buffer, &t1_size) && file_opened && t1_size > 0) { - luatex_warn("cannot open Type 1 font file for reading (%s)", - cur_file_name); + formatted_warning("type 1","cannot open file for reading '%s'",cur_file_name); return false; } } else { @@ -966,7 +954,7 @@ static void t1_include(PDF pdf) @c #define check_subr(subr) \ if (subr >= subr_size || subr < 0) \ - luatex_fail("Subrs array: entry index out of range (%i)", subr); + formatted_error("type 1","Subrs array: entry index out of range '%i'", subr); static const char **check_cs_token_pair(void) { @@ -992,8 +980,7 @@ static void cs_store(boolean is_subr) } else { ptr = cs_ptr++; if (cs_ptr - cs_tab > cs_size) - luatex_fail - ("CharStrings dict: more entries than dict size (%i)", cs_size); + formatted_error("type 1","CharStrings dict: more entries than dict size '%i'", cs_size); if (strcmp(t1_buf_array + 1, notdef) == 0) /* skip the slash */ ptr->name = (char *) notdef; else @@ -1018,25 +1005,23 @@ static void cs_store(boolean is_subr) @ @c -#define store_subr() cs_store(true) -#define store_cs() cs_store(false) +#define store_subr() cs_store(true) +#define store_cs() cs_store(false) -#define CC_STACK_SIZE 24 +#define CC_STACK_SIZE 24 static int cc_stack[CC_STACK_SIZE], *stack_ptr = cc_stack; static cc_entry cc_tab[CS_MAX]; static boolean is_cc_init = false; - -#define cc_pop(N) \ - if (stack_ptr - cc_stack < (N)) \ - stack_error(N); \ +#define cc_pop(N) \ + if (stack_ptr - cc_stack < (N)) \ + stack_error(N); \ stack_ptr -= N -#define stack_error(N) { \ - luatex_fail("CharString: invalid access (%i) to stack (%i entries)", \ - (int) N, (int)(stack_ptr - cc_stack)); \ - goto cs_error; \ +#define stack_error(N) { \ + formatted_error("type 1","CharString: invalid access '%i' to stack, '%i' entries", (int) N, (int)(stack_ptr - cc_stack)); \ + goto cs_error; \ } #define cc_get(N) ((N) < 0 ? *(stack_ptr + (N)) : *(cc_stack + (N))) @@ -1095,7 +1080,6 @@ static void cc_init(void) #define mark_subr(n) cs_mark(0, n) #define mark_cs(s) cs_mark(s, 0) -__attribute__ ((noreturn, format(printf, 3, 4))) static void cs_fail(const char *cs_name, int subr, const char *fmt, ...) { char buf[SMALL_BUF_SIZE]; @@ -1104,9 +1088,9 @@ static void cs_fail(const char *cs_name, int subr, const char *fmt, ...) vsprintf(buf, fmt, args); va_end(args); if (cs_name == NULL) - luatex_fail("Subr (%i): %s", (int) subr, buf); + formatted_error("type 1","Subr '%i': %s", (int) subr, buf); else - luatex_fail("CharString (/%s): %s", cs_name, buf); + formatted_error("type 1","CharString (/%s): %s", cs_name, buf); } @ fix a return-less subr by appending |CS_RETURN| @@ -1170,7 +1154,7 @@ static void cs_mark(const char *cs_name, int subr) if (strcmp(ptr->name, cs_name) == 0) break; if (ptr == cs_ptr) { - luatex_warn("glyph `%s' undefined", cs_name); + formatted_warning("type 1","glyph '%s' undefined", cs_name); return; } if (ptr->name == notdef) @@ -1215,8 +1199,7 @@ static void cs_mark(const char *cs_name, int subr) cs_len--; } if (b >= CS_MAX) { - cs_fail(cs_name, subr, "command value out of range: %i", - (int) b); + cs_fail(cs_name, subr, "command value out of range: %i", (int) b); goto cs_error; } cc = cc_tab + b; @@ -1227,11 +1210,11 @@ static void cs_mark(const char *cs_name, int subr) if (cc->bottom) { if (stack_ptr - cc_stack < cc->nargs) cs_fail(cs_name, subr, - "less arguments on stack (%i) than required (%i)", + "less arguments on stack '%i' than required '%i'", (int) (stack_ptr - cc_stack), (int) cc->nargs); else if (stack_ptr - cc_stack > cc->nargs) cs_fail(cs_name, subr, - "more arguments on stack (%i) than required (%i)", + "more arguments on stack '%i' than required '%i'", (int) (stack_ptr - cc_stack), (int) cc->nargs); } last_cmd = b; @@ -1241,7 +1224,7 @@ static void cs_mark(const char *cs_name, int subr) cc_pop(1); mark_subr(a1); if (!subr_tab[a1].valid) { - cs_fail(cs_name, subr, "cannot call subr (%i)", (int) a1); + cs_fail(cs_name, subr, "cannot call subr '%i'", (int) a1); goto cs_error; } break; @@ -1276,9 +1259,9 @@ static void cs_mark(const char *cs_name, int subr) } } if (cs_name == NULL && last_cmd != CS_RETURN) { - luatex_warn("last command in subr `%i' is not a RETURN; " - "I will add it now but please consider fixing the font", - (int) subr); + formatted_warning("type 1", + "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; @@ -1676,8 +1659,7 @@ static void t1_subset_charstrings(PDF pdf) if (cs_token_pair == NULL) - luatex_fail - ("This Type 1 font uses mismatched subroutine begin/end token pairs."); + formatted_error("type 1","mismatched subroutine begin/end token pairs"); t1_subr_flush(); } diff --git a/Build/source/texk/web2c/luatexdir/font/writet3.w b/Build/source/texk/web2c/luatexdir/font/writet3.w index 3dda1770409..1d33330716c 100644 --- a/Build/source/texk/web2c/luatexdir/font/writet3.w +++ b/Build/source/texk/web2c/luatexdir/font/writet3.w @@ -48,7 +48,7 @@ int t3_curbyte = 0; #define t3_check_eof() \ if (t3_eof()) \ - luatex_fail("unexpected end of file"); + normal_error("type 3","unexpected end of file"); @ @c @@ -139,16 +139,13 @@ static boolean writepk(PDF pdf, internal_font_number f) if (name == NULL || !FILESTRCASEEQ(cur_file_name, font_ret.name) || !kpse_bitmap_tolerance((float) font_ret.dpi, (float) dpi)) { - luatex_fail("Font %s at %i not found", cur_file_name, (int) dpi); + formatted_error("type 3","font %s at %i not found", cur_file_name, (int) dpi); } } callback_id = callback_defined(read_pk_file_callback); if (callback_id > 0) { - if (! - (run_callback - (callback_id, "S->bSd", name, &file_opened, &t3_buffer, &t3_size) - && file_opened && t3_size > 0)) { - luatex_warn("Font %s at %i not found", cur_file_name, (int) dpi); + if (!(run_callback(callback_id, "S->bSd", name, &file_opened, &t3_buffer, &t3_size) && file_opened && t3_size > 0)) { + formatted_warning("font %s at %i not found", cur_file_name, (int) dpi); cur_file_name = NULL; return false; } diff --git a/Build/source/texk/web2c/luatexdir/font/writettf.w b/Build/source/texk/web2c/luatexdir/font/writettf.w index 77fef925507..e1edea5e2ab 100644 --- a/Build/source/texk/web2c/luatexdir/font/writettf.w +++ b/Build/source/texk/web2c/luatexdir/font/writettf.w @@ -485,7 +485,7 @@ long ttf_getnum(int s) int c; while (s > 0) { if (ttf_eof()) - luatex_fail("unexpected EOF"); + normal_error("ttf font","unexpected EOF"); c = ttf_getchar(); i = (i << 8) + c; s--; @@ -516,7 +516,7 @@ dirtab_entry *ttf_name_lookup(const char *s, boolean required) } if (tab - dir_tab == ntabs) { if (required) - luatex_fail("can't find table `%s'", s); + formatted_error("ttf font","can't find table '%s'", s); else tab = NULL; } @@ -586,9 +586,7 @@ static void ttf_copy_encoding(void) e = ttfenc_tab + *q; e->code = charcodes[*q]; if (e->code == -1) - luatex_warn - ("character %i in subfont %s is not mapped to any charcode", - *q, fd_cur->fm->tfm_name); + formatted_warning("ttf font", "character %i in subfont %s is not mapped to any charcode", *q, fd_cur->fm->tfm_name); else { assert(e->code < 0x10000); sprintf(buf, "/c%4.4X", (int) e->code); @@ -816,8 +814,7 @@ void ttf_read_post(void) } break; default: - luatex_warn("unsupported format (%.8X) of `post' table, assuming 3.0", - (unsigned int) post_format); + formatted_warning("ttf font", "unsupported format '%.8X' of 'post' table, assuming 3.0", (unsigned int) post_format); case 0x00030000: for (glyph = glyph_tab; glyph - glyph_tab < NMACGLYPHS; glyph++) { glyph->name_index = (TTF_USHORT) (glyph - glyph_tab); @@ -915,14 +912,13 @@ static ttf_cmap_entry *ttf_read_cmap(char *ttf_name, int pid, int eid, goto read_cmap_format_4; else { if (warn) - luatex_warn("cmap format %i unsupported", format); + formatted_warning("ttf font", "cmap format %i unsupported", format); return NULL; } } } if (warn) - luatex_warn("cannot find cmap subtable for (pid,eid) = (%i, %i)", - pid, eid); + formatted_warning("ttf font", "cannot find cmap subtable for (pid,eid) = (%i,%i)", pid, eid); return NULL; read_cmap_format_4: /* initialize the new entry */ @@ -972,13 +968,13 @@ static ttf_cmap_entry *ttf_read_cmap(char *ttf_name, int pid, int eid, index = (index + s->idDelta) & 0xFFFF; } if (index >= glyphs_count) - luatex_fail("cmap: glyph index %li out of range [0..%i)", - index, glyphs_count); + formatted_error("ttf font", + "cmap issue, glyph index %li out of range [0..%i)", + index, glyphs_count); if (p->table[i] != -1) - luatex_warn - ("cmap: multiple glyphs are mapped to unicode %.4lX, " - "only %li will be used (glyph %li being ignored)", i, - p->table[i], index); + formatted_warning("ttf font", + "cmap issue, multiple glyphs are mapped to unicode %.4lX, %li will be used, %li is ignored)", + i, p->table[i], index); else p->table[i] = index; } @@ -991,7 +987,7 @@ static ttf_cmap_entry *ttf_read_cmap(char *ttf_name, int pid, int eid, return p; } -@ +@ @c static void ttf_read_font(void) { @@ -1021,7 +1017,7 @@ static void ttf_reset_chksm(PDF pdf, dirtab_entry * tab) tmp_ulong = 0; tab->offset = (TTF_ULONG) ttf_offset(); if (tab->offset % 4 != 0) - luatex_warn("offset of `%4.4s' is not a multiple of 4", tab->tag); + formatted_warning("ttf font","offset of `%4.4s' is not a multiple of 4", tab->tag); } @@ -1041,7 +1037,7 @@ static void ttf_copytab(PDF pdf, const char *name) ttf_set_chksm(pdf, tab); } -@ +@ @c #define BYTE_ENCODING_LENGTH \ ((256)*TTF_BYTE_SIZE + 3*TTF_USHORT_SIZE) @@ -1057,14 +1053,14 @@ static void ttf_byte_encoding(PDF pdf) put_byte(e->newindex); } else { if (e->name != notdef) - luatex_warn - ("glyph `%s' has been mapped to `%s' in `ttf_byte_encoding' cmap table", - e->name, notdef); + formatted_warning("ttf font", + "glyph '%s' has been mapped to '%s' in 'ttf_byte_encoding' cmap table", + e->name, notdef); put_byte(0); /* notdef */ } } -@ +@ @c #define TRIMMED_TABLE_MAP_LENGTH (TTF_USHORT_SIZE*(5 + (256))) @@ -1080,7 +1076,7 @@ static void ttf_trimmed_table_map(PDF pdf) (void) put_ushort(e->newindex); } -@ +@ @c #define SEG_MAP_DELTA_LENGTH ((16 + (256))*TTF_USHORT_SIZE) @@ -1107,7 +1103,7 @@ static void ttf_seg_map_delta(PDF pdf) (void) put_ushort(e->newindex); } -@ +@ @c #define CMAP_ENTRY_LENGTH (2*TTF_USHORT_SIZE + TTF_ULONG_SIZE) @@ -1146,7 +1142,7 @@ static void ttf_write_cmap(PDF pdf) offset += TRIMMED_TABLE_MAP_LENGTH; break; default: - luatex_fail("invalid format (it should not have happened)"); + normal_error("ttf font","invalid format (it should not have happened)"); } (void) put_ushort(ce->platform_id); (void) put_ushort(ce->encoding_id); @@ -1168,7 +1164,7 @@ static void ttf_write_cmap(PDF pdf) ttf_set_chksm(pdf, tab); } -@ +@ @c static int prepend_subset_tags(int index, char *p) { @@ -1249,7 +1245,7 @@ static void ttf_write_name(PDF pdf) xfree(new_name_buf); } -@ +@ @c static void ttf_write_dirtab(PDF pdf) { @@ -1290,7 +1286,7 @@ static void ttf_write_dirtab(PDF pdf) } } if (i % 4 != 0) { - luatex_warn("font length is not a multiple of 4 (%li)", i); + formatted_warning("ttf font","font length '%li' is not a multiple of 4", i); checksum <<= 8 * (4 - i % 4); } k = 0xB1B0AFBA - checksum; @@ -1299,7 +1295,7 @@ static void ttf_write_dirtab(PDF pdf) ttf_seek_outbuf(save_offset); } -@ +@ @c static void ttf_write_glyf(PDF pdf) { @@ -1323,7 +1319,7 @@ static void ttf_write_glyf(PDF pdf) if (glyph_tab[idx].newindex < 0) { glyph_tab[idx].newindex = (TTF_SHORT) new_glyphs_count; glyph_index[new_glyphs_count++] = idx; - /* + /* N.B.: Here we change |new_glyphs_count|, which appears in the condition of the |for| loop */ @@ -1356,7 +1352,7 @@ static void ttf_write_glyf(PDF pdf) while going through |ttfenc_tab|. After appending a new entry to |glyph_index| we set field |newindex| of corresponding entries in both |glyph_tab| and |ttfenc_tab| to the newly created index. - + @c static void ttf_reindex_glyphs(void) { @@ -1387,8 +1383,8 @@ static void ttf_reindex_glyphs(void) t = cmap->table; assert(t != NULL && e->code < 0x10000); if (t[e->code] < 0) { - luatex_warn - ("subfont %s: wrong mapping: character %li --> 0x%4.4lX --> .notdef", + formatted_warning("ttf font", + "subfont %s has a wrong mapping, character %li -> 0x%4.4lX -> .notdef", fd_cur->fm->tfm_name, (long) (e - ttfenc_tab), e->code); continue; } @@ -1403,8 +1399,7 @@ static void ttf_reindex_glyphs(void) /* scan form `index123' */ if (sscanf(e->name, GLYPH_PREFIX_INDEX "%i", &index) == 1) { if (index >= glyphs_count) { - luatex_warn("`%s' out of valid range [0..%i)", - e->name, glyphs_count); + formatted_warning("ttf font","'%s' out of valid range [0..%i)", e->name, glyphs_count); continue; } glyph = glyph_tab + index; @@ -1418,8 +1413,7 @@ static void ttf_reindex_glyphs(void) if (cmap == NULL) cmap = ttf_read_cmap(fd_cur->fm->ff_name, 0, 3, false); if (cmap == NULL) { - luatex_warn - ("no unicode mapping found, all `uniXXXX' names will be ignored"); + normal_warning("ttf font", "no unicode mapping found, all 'uniXXXX' names will be ignored"); cmap_not_found = true; /* once only */ } } @@ -1429,16 +1423,14 @@ static void ttf_reindex_glyphs(void) assert(t != NULL); if (t[index] != -1) { if (t[index] >= glyphs_count) { - luatex_warn - ("`%s' is mapped to index %li which is out of valid range [0..%i)", + formatted_warning("ttf font", "'%s' is mapped to index %li which is out of valid range [0..%i)", e->name, t[index], glyphs_count); continue; } glyph = glyph_tab + t[index]; goto append_new_glyph; } else { - luatex_warn("`unicode %s%.4X' is not mapped to any glyph", - GLYPH_PREFIX_UNICODE, index); + formatted_warning("ttf font","unicode %s%.4X is not mapped to any glyph", GLYPH_PREFIX_UNICODE, index); continue; } } @@ -1447,7 +1439,7 @@ static void ttf_reindex_glyphs(void) if (glyph->name != notdef && strcmp(glyph->name, e->name) == 0) break; if (!(glyph - glyph_tab < glyphs_count)) { - luatex_warn("glyph `%s' not found", e->name); + formatted_warning("ttf font","glyph '%s' not found", e->name); continue; } append_new_glyph: @@ -1502,7 +1494,7 @@ static void ttf_write_head(PDF pdf) ttf_set_chksm(pdf, tab); } -@ +@ @c static void ttf_write_hhea(PDF pdf) { @@ -1515,7 +1507,7 @@ static void ttf_write_hhea(PDF pdf) ttf_set_chksm(pdf, tab); } -@ +@ @c static void ttf_write_htmx(PDF pdf) { @@ -1529,7 +1521,7 @@ static void ttf_write_htmx(PDF pdf) ttf_set_chksm(pdf, tab); } -@ +@ @c static void ttf_write_loca(PDF pdf) { @@ -1557,7 +1549,7 @@ static void ttf_write_loca(PDF pdf) ttf_set_chksm(pdf, tab); } -@ +@ @c static void ttf_write_mapx(PDF pdf) { @@ -1569,7 +1561,7 @@ static void ttf_write_mapx(PDF pdf) ttf_set_chksm(pdf, tab); } -@ +@ @c static void ttf_write_OS2(PDF pdf) { @@ -1578,7 +1570,7 @@ static void ttf_write_OS2(PDF pdf) ttf_reset_chksm(pdf, tab); version = get_ushort(); if (version > 3) - luatex_fail("unknown version of OS/2 table (%.4X)", version); + formatted_error("ttf font","unknown version '%.4X' of OS/2 table", version); (void) put_ushort(0x0001); /* fix version to 1 */ ttf_ncopy(pdf, 2 * TTF_USHORT_SIZE + 13 * TTF_SHORT_SIZE + 10 * TTF_BYTE_SIZE); @@ -1598,7 +1590,7 @@ static void ttf_write_OS2(PDF pdf) ttf_set_chksm(pdf, tab); } -@ +@ @c static boolean unsafe_name(const char *s) { @@ -1647,7 +1639,7 @@ static void ttf_write_post(PDF pdf) ttf_set_chksm(pdf, tab); } -@ +@ @c static void ttf_init_font(PDF pdf, int n) { @@ -1661,7 +1653,7 @@ static void ttf_init_font(PDF pdf, int n) ttf_seek_outbuf(TABDIR_OFF + n * 4 * TTF_ULONG_SIZE); } -@ +@ @c static void ttf_subset_font(PDF pdf) { @@ -1688,7 +1680,7 @@ static void ttf_subset_font(PDF pdf) ttf_write_dirtab(pdf); } -@ +@ @c static void ttf_copy_font(PDF pdf) { @@ -1703,7 +1695,7 @@ static void ttf_copy_font(PDF pdf) ttf_write_dirtab(pdf); } -@ +@ @c void writettf(PDF pdf, fd_entry * fd) { @@ -1714,9 +1706,8 @@ void writettf(PDF pdf, fd_entry * fd) assert(is_truetype(fd_cur->fm)); assert(is_included(fd_cur->fm)); - if (is_subsetted(fd_cur->fm) && (fd_cur->fe == NULL) - && !is_subfont(fd_cur->fm)) { - luatex_fail("Subset TrueType must be a reencoded or a subfont"); + if (is_subsetted(fd_cur->fm) && (fd_cur->fe == NULL) && !is_subfont(fd_cur->fm)) { + normal_error("ttf font","subset must be a reencoded or a subfont"); } ttf_curbyte = 0; ttf_size = 0; @@ -1724,7 +1715,7 @@ void writettf(PDF pdf, fd_entry * fd) cur_file_name = luatex_find_file(fd_cur->fm->ff_name, find_truetype_file_callback); if (cur_file_name == NULL) { - luatex_fail("cannot find TrueType font file for reading (%s)", fd_cur->fm->ff_name); + formatted_error("ttf font","cannot find font file for reading '%s'", fd_cur->fm->ff_name); } callback_id = callback_defined(read_truetype_file_callback); if (callback_id > 0) { @@ -1732,11 +1723,11 @@ void writettf(PDF pdf, fd_entry * fd) &file_opened, &ttf_buffer, &ttf_size) && file_opened && ttf_size > 0) { } else { - luatex_fail("cannot open TrueType font file for reading (%s)", cur_file_name); + formatted_error("ttf font","cannot open font file for reading '%s'", cur_file_name); } } else { if (!ttf_open(cur_file_name)) { - luatex_fail("cannot open TrueType font file for reading (%s)", cur_file_name); + formatted_error("ttf font","cannot open font file for reading '%s'", cur_file_name); } ttf_read_file(); ttf_close(); @@ -1812,7 +1803,7 @@ static void do_writeotf(PDF pdf, fd_entry * fd) tex_printf(">>"); } -@ +@ @c void writeotf(PDF pdf, fd_entry * fd) { @@ -1829,7 +1820,7 @@ void writeotf(PDF pdf, fd_entry * fd) cur_file_name = luatex_find_file(fd_cur->fm->ff_name, find_opentype_file_callback); if (cur_file_name == NULL) { - luatex_fail("cannot find OpenType font file for reading (%s)", fd_cur->fm->ff_name); + formatted_error("otf font","cannot find font file for reading '%s'", fd_cur->fm->ff_name); } callback_id = callback_defined(read_opentype_file_callback); if (callback_id > 0) { @@ -1837,11 +1828,11 @@ void writeotf(PDF pdf, fd_entry * fd) &file_opened, &ttf_buffer, &ttf_size) && file_opened && ttf_size > 0) { } else { - luatex_fail("cannot open OpenType font file for reading (%s)", cur_file_name); + formatted_error("otf font","cannot open font file for reading '%s'", cur_file_name); } } else { if (!otf_open(cur_file_name)) { - luatex_fail("cannot open OpenType font file for reading (%s)", cur_file_name); + formatted_error("otf font","cannot open font file for reading '%s'", cur_file_name); } ttf_read_file(); ttf_close(); diff --git a/Build/source/texk/web2c/luatexdir/font/writetype0.w b/Build/source/texk/web2c/luatexdir/font/writetype0.w index 3f63b02ae12..3053103c524 100644 --- a/Build/source/texk/web2c/luatexdir/font/writetype0.w +++ b/Build/source/texk/web2c/luatexdir/font/writetype0.w @@ -51,8 +51,7 @@ void writetype0(PDF pdf, fd_entry * fd) cur_file_name = luatex_find_file(fd_cur->fm->ff_name, find_truetype_file_callback); if (cur_file_name == NULL) { - luatex_fail("cannot find OpenType font file for reading (%s)", - fd_cur->fm->ff_name); + formatted_error("type 0","cannot find file '%s'", fd_cur->fm->ff_name); } } callback_id = callback_defined(read_opentype_file_callback); @@ -61,13 +60,11 @@ void writetype0(PDF pdf, fd_entry * fd) &file_opened, &ttf_buffer, &ttf_size) && file_opened && ttf_size > 0) { } else { - luatex_fail("cannot open OpenType font file for reading (%s)", - cur_file_name); + formatted_error("type 0","cannot find file '%s'", cur_file_name); } } else { if (!otf_open(cur_file_name)) { - luatex_fail("cannot open OpenType font file for reading (%s)", - cur_file_name); + formatted_error("type 0","cannot find file '%s'", cur_file_name); } ttf_read_file(); ttf_close(); @@ -78,7 +75,7 @@ void writetype0(PDF pdf, fd_entry * fd) sfont = sfnt_open(ttf_buffer, ttf_size); if (sfont->type == SFNT_TYPE_TTC) i = ff_get_ttc_index(fd->fm->ff_name, fd->fm->ps_name); - + if (is_subsetted(fd_cur->fm)) { report_start_file(filetype_subset, cur_file_name); diff --git a/Build/source/texk/web2c/luatexdir/font/writetype2.w b/Build/source/texk/web2c/luatexdir/font/writetype2.w index 8980344afd7..d5ce1aca40a 100644 --- a/Build/source/texk/web2c/luatexdir/font/writetype2.w +++ b/Build/source/texk/web2c/luatexdir/font/writetype2.w @@ -152,7 +152,7 @@ boolean writetype2(PDF pdf, fd_entry * fd) cur_file_name = luatex_find_file(fd_cur->fm->ff_name, find_opentype_file_callback); if (cur_file_name == NULL) { - luatex_fail("cannot find OpenType font file for reading (%s)", fd_cur->fm->ff_name); + formatted_error("type 2","cannot find file '%s'", fd_cur->fm->ff_name); } callback_id = callback_defined(read_opentype_file_callback); if (callback_id > 0) { @@ -160,11 +160,11 @@ boolean writetype2(PDF pdf, fd_entry * fd) &file_opened, &ttf_buffer, &ttf_size) && file_opened && ttf_size > 0) { } else { - luatex_fail("cannot open OpenType font file for reading (%s)", cur_file_name); + formatted_error("type 2","cannot find file '%s'", cur_file_name); } } else { if (!otf_open(cur_file_name)) { - luatex_fail("cannot open OpenType font file for reading (%s)", cur_file_name); + formatted_error("type 2","cannot find file '%s'", cur_file_name); } ttf_read_file(); ttf_close(); diff --git a/Build/source/texk/web2c/luatexdir/image/epdf.h b/Build/source/texk/web2c/luatexdir/image/epdf.h index 09bc7cc84e4..3d4751c4587 100644 --- a/Build/source/texk/web2c/luatexdir/image/epdf.h +++ b/Build/source/texk/web2c/luatexdir/image/epdf.h @@ -121,7 +121,8 @@ extern "C" { extern int pdf_create_obj(PDF pdf, int t, int i); /* pdftoepdf.cc */ - extern void read_pdf_info(image_dict *, int, int, img_readtype_e); + extern void read_pdf_info(image_dict *); + extern void flush_pdf_info(image_dict *); extern void write_epdf(PDF, image_dict *); extern void unrefPdfDocument(char *); extern void unrefMemStreamPdfDocument(char *); diff --git a/Build/source/texk/web2c/luatexdir/image/image.h b/Build/source/texk/web2c/luatexdir/image/image.h index 5a9adfdc9bb..49996947e26 100644 --- a/Build/source/texk/web2c/luatexdir/image/image.h +++ b/Build/source/texk/web2c/luatexdir/image/image.h @@ -18,7 +18,6 @@ You should have received a copy of the GNU General Public License along with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */ - #ifndef IMAGE_H # define IMAGE_H @@ -31,14 +30,13 @@ extern int do_zround(double r); /* from utils.w */ extern scaled one_hundred_bp; /* from pdfgen.w */ + # define bp2sp(p) do_zround(p * (one_hundred_bp / 100.0)) # define sp2bp(i) (i * 100.0 / one_hundred_bp) # define TYPE_IMG "image.meta" # define TYPE_IMG_DICT "image.dict" -/**********************************************************************/ - typedef struct { char *stream; } pdf_stream_struct; @@ -49,41 +47,52 @@ typedef struct { } png_img_struct; typedef struct { - int color_space; /* used color space. See JPG_ constants */ - JPG_UINT32 length; /* length of file/data */ + int color_space; /* used color space. See JPG_ constants */ + JPG_UINT32 length; /* length of file/data */ } jpg_img_struct; typedef struct { - int length; /* length of file/data */ + int length; /* length of file/data */ } jp2_img_struct; # if 0 -typedef struct { /* currently unused */ +typedef struct { /* currently unused */ } jb2_img_struct; # endif -typedef enum { DICT_NEW, /* fresh dictionary */ - DICT_FILESCANNED, /* image file scanned */ - DICT_REFERED, /* pdf_refximage_node in node list --> read-only dict */ - DICT_OUTIMG, /* /Im* appears in pagestream */ - DICT_SCHEDULED, /* image dict scheduled for writing (PONR) */ - DICT_WRITTEN /* image dict written to file */ +typedef enum { + DICT_NEW, /* fresh dictionary */ + DICT_FILESCANNED, /* image file scanned */ + DICT_REFERED, /* pdf_refximage_node in node list --> read-only dict */ + DICT_OUTIMG, /* /Im* appears in pagestream */ + DICT_SCHEDULED, /* image dict scheduled for writing (PONR) */ + DICT_WRITTEN /* image dict written to file */ } dict_state; - -typedef enum { IMG_TYPE_NONE, IMG_TYPE_PDF, IMG_TYPE_PNG, IMG_TYPE_JPG, - IMG_TYPE_JP2, IMG_TYPE_JBIG2, IMG_TYPE_PDFSTREAM, IMG_TYPE_PDFMEMSTREAM, IMG_TYPE_SENTINEL +typedef enum { + IMG_TYPE_NONE, + IMG_TYPE_PDF, + IMG_TYPE_PNG, + IMG_TYPE_JPG, + IMG_TYPE_JP2, + IMG_TYPE_JBIG2, + IMG_TYPE_PDFSTREAM, + IMG_TYPE_PDFMEMSTREAM, + IMG_TYPE_SENTINEL } imgtype_e; typedef enum { IMG_KEEPOPEN, IMG_CLOSEINBETWEEN } img_readtype_e; -typedef enum { PDF_BOX_SPEC_NONE, PDF_BOX_SPEC_MEDIA, PDF_BOX_SPEC_CROP, - PDF_BOX_SPEC_BLEED, PDF_BOX_SPEC_TRIM, PDF_BOX_SPEC_ART, +typedef enum { + PDF_BOX_SPEC_NONE, + PDF_BOX_SPEC_MEDIA, + PDF_BOX_SPEC_CROP, + PDF_BOX_SPEC_BLEED, + PDF_BOX_SPEC_TRIM, + PDF_BOX_SPEC_ART, PDF_BOX_SPEC_SENTINEL } pdfboxspec_e; -/**********************************************************************/ - typedef struct { int objnum; int index; /* /Im1, /Im2, ... */ @@ -113,100 +122,105 @@ typedef struct { int bbox[4]; dict_state state; int flags; + int luaref ; + boolean keepopen; + int errorlevel; + int pdfminorversion; union { pdf_stream_struct *pdfstream; png_img_struct *png; jpg_img_struct *jpg; jp2_img_struct *jp2; - /* jb2_img_struct *jb2; */ + /* jb2_img_struct *jb2; */ } img_struct; } image_dict; -# define img_objnum(N) ((N)->objnum) -# define img_index(N) ((N)->index) -# define img_dimen(N) ((N)->dimen) -# define img_width(N) ((N)->dimen.wd) -# define img_height(N) ((N)->dimen.ht) -# define img_depth(N) ((N)->dimen.dp) -# define img_transform(N) ((N)->transform) -# define img_xsize(N) ((N)->x_size) -# define img_ysize(N) ((N)->y_size) -# define img_xorig(N) ((N)->x_orig) -# define img_yorig(N) ((N)->y_orig) -# define img_xres(N) ((N)->x_res) -# define img_yres(N) ((N)->y_res) -# define img_rotation(N) ((N)->rotation) -# define img_colorspace(N) ((N)->colorspace) -# define img_group_ref(N) ((N)->group_ref) -# define img_totalpages(N) ((N)->total_pages) -# define img_pagenum(N) ((N)->page_num) -# define img_pagename(N) ((N)->pagename) -# define img_filename(N) ((N)->filename) -# define img_visiblefilename(N)((N)->visiblefilename) -# define img_filepath(N) ((N)->filepath) -# define img_attr(N) ((N)->attr) -# define img_file(N) ((N)->file) -# define img_type(N) ((N)->image_type) -# define img_procset(N) ((N)->procset) -# define img_colordepth(N) ((N)->color_depth) -# define img_pagebox(N) ((N)->page_box_spec) -# define img_bbox(N) ((N)->bbox) -# define img_state(N) ((N)->state) -# define img_flags(N) ((N)->flags) - -# define img_pdfstream_ptr(N) ((N)->img_struct.pdfstream) +# define img_objnum(N) ((N)->objnum) +# define img_index(N) ((N)->index) +# define img_dimen(N) ((N)->dimen) +# define img_width(N) ((N)->dimen.wd) +# define img_height(N) ((N)->dimen.ht) +# define img_depth(N) ((N)->dimen.dp) +# define img_transform(N) ((N)->transform) +# define img_xsize(N) ((N)->x_size) +# define img_ysize(N) ((N)->y_size) +# define img_xorig(N) ((N)->x_orig) +# define img_yorig(N) ((N)->y_orig) +# define img_xres(N) ((N)->x_res) +# define img_yres(N) ((N)->y_res) +# define img_rotation(N) ((N)->rotation) +# define img_colorspace(N) ((N)->colorspace) +# define img_group_ref(N) ((N)->group_ref) +# define img_totalpages(N) ((N)->total_pages) +# define img_pagenum(N) ((N)->page_num) +# define img_pagename(N) ((N)->pagename) +# define img_filename(N) ((N)->filename) +# define img_visiblefilename(N) ((N)->visiblefilename) +# define img_filepath(N) ((N)->filepath) +# define img_attr(N) ((N)->attr) +# define img_file(N) ((N)->file) +# define img_type(N) ((N)->image_type) +# define img_procset(N) ((N)->procset) +# define img_colordepth(N) ((N)->color_depth) +# define img_pagebox(N) ((N)->page_box_spec) +# define img_bbox(N) ((N)->bbox) +# define img_state(N) ((N)->state) +# define img_flags(N) ((N)->flags) +# define img_luaref(N) ((N)->luaref) +# define img_keepopen(N) ((N)->keepopen) +# define img_errorlevel(N) ((N)->errorlevel) +# define img_pdfminorversion(N) ((N)->pdfminorversion) + +# define img_pdfstream_ptr(N) ((N)->img_struct.pdfstream) # define img_pdfstream_stream(N) ((N)->img_struct.pdfstream->stream) -# define img_png_ptr(N) ((N)->img_struct.png) -# define img_png_png_ptr(N) ((N)->img_struct.png->png_ptr) -# define img_png_info_ptr(N) ((N)->img_struct.png->info_ptr) - -# define img_jpg_ptr(N) ((N)->img_struct.jpg) -# define img_jpg_color(N) ((N)->img_struct.jpg->color_space) +# define img_png_ptr(N) ((N)->img_struct.png) +# define img_png_png_ptr(N) ((N)->img_struct.png->png_ptr) +# define img_png_info_ptr(N) ((N)->img_struct.png->info_ptr) -# define img_jp2_ptr(N) ((N)->img_struct.jp2) +# define img_jpg_ptr(N) ((N)->img_struct.jpg) +# define img_jpg_color(N) ((N)->img_struct.jpg->color_space) -# define img_jb2_ptr(N) ((N)->img_struct.jb2) +# define img_jp2_ptr(N) ((N)->img_struct.jp2) -# define F_FLAG_BBOX (1 << 0) -# define F_FLAG_GROUP (1 << 1) +# define img_jb2_ptr(N) ((N)->img_struct.jb2) -# define img_set_bbox(N) (img_flags(N) |= F_FLAG_BBOX) -# define img_unset_bbox(N) (img_flags(N) &= ~F_FLAG_BBOX) -# define img_is_bbox(N) ((img_flags(N) & F_FLAG_BBOX) != 0) +# define F_FLAG_BBOX (1 << 0) +# define F_FLAG_GROUP (1 << 1) -# define img_set_group(N) (img_flags(N) |= F_FLAG_GROUP) -# define img_unset_group(N) (img_flags(N) &= ~F_FLAG_GROUP) -# define img_is_group(N) ((img_flags(N) & F_FLAG_GROUP) != 0) +# define img_set_bbox(N) (img_flags(N) |= F_FLAG_BBOX) +# define img_unset_bbox(N) (img_flags(N) &= ~F_FLAG_BBOX) +# define img_is_bbox(N) ((img_flags(N) & F_FLAG_BBOX) != 0) -# define epdf_xsize(a) img_xsize(idict_array[a]) -# define epdf_ysize(a) img_ysize(idict_array[a]) -# define epdf_orig_x(a) img_xorig(idict_array[a]) -# define epdf_orig_y(a) img_yorig(idict_array[a]) +# define img_set_group(N) (img_flags(N) |= F_FLAG_GROUP) +# define img_unset_group(N) (img_flags(N) &= ~F_FLAG_GROUP) +# define img_is_group(N) ((img_flags(N) & F_FLAG_GROUP) != 0) -# define is_pdf_image(a) ((img_type(idict_array[a]) == IMG_TYPE_PDF) || (img_type(idict_array[a]) == IMG_TYPE_PDFMEMSTREAM)) -# define is_png_image(a) (img_type(idict_array[a]) == IMG_TYPE_PNG) +# define epdf_xsize(a) img_xsize(idict_array[a]) +# define epdf_ysize(a) img_ysize(idict_array[a]) +# define epdf_orig_x(a) img_xorig(idict_array[a]) +# define epdf_orig_y(a) img_yorig(idict_array[a]) -# define img_is_refered(N) (img_index(N) != -1) +# define is_pdf_image(a) ((img_type(idict_array[a]) == IMG_TYPE_PDF) || (img_type(idict_array[a]) == IMG_TYPE_PDFMEMSTREAM)) +# define is_png_image(a) (img_type(idict_array[a]) == IMG_TYPE_PNG) -/**********************************************************************/ -/* image structure corresponds to pdfrefximage node */ +# define img_is_refered(N) (img_index(N) != -1) typedef struct { - scaled_whd dimen; /* requested/actual TeX dimensions */ + scaled_whd dimen; /* requested/actual TeX dimensions */ int transform; image_dict *dict; - int dict_ref; /* luaL_ref() reference */ + int dict_ref; /* luaL_ref() reference */ } image; -# define img_dict(N) ((N)->dict) -# define img_dictref(N) ((N)->dict_ref) +# define img_dict(N) ((N)->dict) +# define img_dictref(N) ((N)->dict_ref) -# define set_wd_running(N) (img_width(N) = null_flag) -# define set_ht_running(N) (img_height(N) = null_flag) -# define set_dp_running(N) (img_depth(N) = null_flag) -# define is_wd_running(N) (img_width(N) == null_flag) -# define is_ht_running(N) (img_height(N) == null_flag) -# define is_dp_running(N) (img_depth(N) == null_flag) +# define set_wd_running(N) (img_width(N) = null_flag) +# define set_ht_running(N) (img_height(N) = null_flag) +# define set_dp_running(N) (img_depth(N) = null_flag) +# define is_wd_running(N) (img_width(N) == null_flag) +# define is_ht_running(N) (img_height(N) == null_flag) +# define is_dp_running(N) (img_depth(N) == null_flag) -#endif /* IMAGE_H */ +#endif diff --git a/Build/source/texk/web2c/luatexdir/image/pdftoepdf.h b/Build/source/texk/web2c/luatexdir/image/pdftoepdf.h index 203f85c5c31..12d15121017 100644 --- a/Build/source/texk/web2c/luatexdir/image/pdftoepdf.h +++ b/Build/source/texk/web2c/luatexdir/image/pdftoepdf.h @@ -24,7 +24,9 @@ # include "image.h" -void read_pdf_info(image_dict *, int, int, img_readtype_e); +void read_pdf_info(image_dict *); +void flush_pdf_info(image_dict *); +/* flush_pdfstream_info(image_dict *); */ /* somehow doesn't work due to xfree macro */ void unrefPdfDocument(char *); void unrefMemStreamPdfDocument(char *); void write_epdf(PDF, image_dict *); diff --git a/Build/source/texk/web2c/luatexdir/image/pdftoepdf.w b/Build/source/texk/web2c/luatexdir/image/pdftoepdf.w index 1ece3a2dd48..b9d496ac9f0 100644 --- a/Build/source/texk/web2c/luatexdir/image/pdftoepdf.w +++ b/Build/source/texk/web2c/luatexdir/image/pdftoepdf.w @@ -20,40 +20,40 @@ @ @c - -// define DEBUG #define __STDC_FORMAT_MACROS /* for PRId64 etc. */ #include "image/epdf.h" -// This file is mostly C and not very much C++; it's just used to interface -// the functions of poppler, which happens to be written in C++. +/* + This file is mostly C and not very much C++; it's just used to interface + the functions of poppler, which happens to be written in C++. +*/ extern void md5(Guchar *msg, int msgLen, Guchar *digest); static GBool isInit = gFalse; -//********************************************************************** -// Maintain AVL tree of all PDF files for embedding +/* Maintain AVL tree of all PDF files for embedding */ static avl_table *PdfDocumentTree = NULL; -// AVL sort PdfDocument into PdfDocumentTree by file_path +/* AVL sort PdfDocument into PdfDocumentTree by file_path */ static int CompPdfDocument(const void *pa, const void *pb, void * /*p */ ) { - return strcmp(((const PdfDocument *) pa)->file_path, - ((const PdfDocument *) pb)->file_path); + return strcmp(((const PdfDocument *) pa)->file_path, ((const PdfDocument *) pb)->file_path); } -// Returns pointer to PdfDocument structure for PDF file. +/* Returns pointer to PdfDocument structure for PDF file. */ static PdfDocument *findPdfDocument(char *file_path) { PdfDocument *pdf_doc, tmp; - assert(file_path != NULL); - if (PdfDocumentTree == NULL) + if (file_path == NULL) { + normal_error("pdf backend","empty filename when loading pdf file"); + } else if (PdfDocumentTree == NULL) { return NULL; + } tmp.file_path = file_path; pdf_doc = (PdfDocument *) avl_find(PdfDocumentTree, &tmp); return pdf_doc; @@ -70,22 +70,20 @@ static char *get_file_checksum(const char *a, file_error_mode fe) time_t mtime = finfo.st_mtime; ck = (char *) malloc(PDF_CHECKSUM_SIZE); if (ck == NULL) - luatex_fail("PDF inclusion: out of memory while processing '%s'", - a); - snprintf(ck, PDF_CHECKSUM_SIZE, "%" PRIu64 "_%" PRIu64, (uint64_t) size, - (uint64_t) mtime); + formatted_error("pdf inclusion","out of memory while processing '%s'", a); + snprintf(ck, PDF_CHECKSUM_SIZE, "%" PRIu64 "_%" PRIu64, (uint64_t) size,(uint64_t) mtime); } else { switch (fe) { - case FE_FAIL: - luatex_fail("PDF inclusion: could not stat() file '%s'", a); - break; - case FE_RETURN_NULL: - if (ck != NULL) - free(ck); - ck = NULL; - break; - default: - assert(0); + case FE_FAIL: + formatted_error("pdf inclusion","could not stat() file '%s'", a); + break; + case FE_RETURN_NULL: + if (ck != NULL) + free(ck); + ck = NULL; + break; + default: + assert(0); } } return ck; @@ -93,28 +91,28 @@ static char *get_file_checksum(const char *a, file_error_mode fe) static char *get_stream_checksum (const char *str, unsigned long long str_size){ - /* http://www.cse.yorku.ca/~oz/hash.html */ - /* djb2 */ - unsigned long hash ; - char *ck = NULL; - unsigned int i; - hash = 5381; - ck = (char *) malloc(STRSTREAM_CHECKSUM_SIZE+1); - if (ck == NULL) - luatex_fail("PDF inclusion: out of memory while processing a memstream"); - for(i=0; i<(unsigned int)(str_size); i++) { - hash = ((hash << 5) + hash) + str[i]; /* hash * 33 + str[i] */ - } - snprintf(ck,STRSTREAM_CHECKSUM_SIZE+1,"%lx",hash); - ck[STRSTREAM_CHECKSUM_SIZE]='\0'; - return ck; + /* http://www.cse.yorku.ca/~oz/hash.html */ + /* djb2 */ + unsigned long hash ; + char *ck = NULL; + unsigned int i; + hash = 5381; + ck = (char *) malloc(STRSTREAM_CHECKSUM_SIZE+1); + if (ck == NULL) + normal_error("pdf inclusion","out of memory while processing a memstream"); + for(i=0; i<(unsigned int)(str_size); i++) { + hash = ((hash << 5) + hash) + str[i]; /* hash * 33 + str[i] */ + } + snprintf(ck,STRSTREAM_CHECKSUM_SIZE+1,"%lx",hash); + ck[STRSTREAM_CHECKSUM_SIZE]='\0'; + return ck; } - - -// Returns pointer to PdfDocument structure for PDF file. -// Creates a new PdfDocument structure if it doesn't exist yet. -// When fe = FE_RETURN_NULL, the function returns NULL in error case. +/* + Returns pointer to PdfDocument structure for PDF file. + Creates a new PdfDocument structure if it doesn't exist yet. + When fe = FE_RETURN_NULL, the function returns NULL in error case. +*/ PdfDocument *refPdfDocument(const char *file_path, file_error_mode fe) { @@ -124,15 +122,10 @@ PdfDocument *refPdfDocument(const char *file_path, file_error_mode fe) GooString *docName = NULL; int new_flag = 0; if ((checksum = get_file_checksum(file_path, fe)) == NULL) { - assert(fe == FE_RETURN_NULL); return (PdfDocument *) NULL; } - assert(checksum != NULL); path_copy = xstrdup(file_path); if ((pdf_doc = findPdfDocument(path_copy)) == NULL) { -#ifdef DEBUG - fprintf(stderr, "\nDEBUG: New PdfDocument %s\n", file_path); -#endif new_flag = 1; pdf_doc = new PdfDocument; pdf_doc->file_path = path_copy; @@ -140,38 +133,28 @@ PdfDocument *refPdfDocument(const char *file_path, file_error_mode fe) pdf_doc->doc = NULL; pdf_doc->inObjList = NULL; pdf_doc->ObjMapTree = NULL; - pdf_doc->occurences = 0; // 0 = unreferenced + pdf_doc->occurences = 0; /* 0 = unreferenced */ pdf_doc->pc = 0; } else { -#ifdef DEBUG - fprintf(stderr, "\nDEBUG: Found PdfDocument %s (%d)\n", - pdf_doc->file_path, pdf_doc->occurences); -#endif - assert(pdf_doc->checksum != NULL); if (strncmp(pdf_doc->checksum, checksum, PDF_CHECKSUM_SIZE) != 0) { - luatex_fail("PDF inclusion: file has changed '%s'", file_path); + formatted_error("pdf inclusion","file has changed '%s'", file_path); } free(checksum); free(path_copy); } - assert(pdf_doc != NULL); if (pdf_doc->doc == NULL) { -#ifdef DEBUG - fprintf(stderr, "\nDEBUG: New PDFDoc %s (%d)\n", - pdf_doc->file_path, pdf_doc->occurences); -#endif docName = new GooString(file_path); - doc = new PDFDoc(docName); // takes ownership of docName + doc = new PDFDoc(docName); /* takes ownership of docName */ pdf_doc->pc++; if (!doc->isOk() || !doc->okToPrint()) { switch (fe) { case FE_FAIL: - luatex_fail("PDF inclusion: reading PDF image failed"); + normal_error("pdf inclusion","reading image failed"); break; case FE_RETURN_NULL: delete doc; - // delete docName; + /* delete docName */ if (new_flag == 1) { if (pdf_doc->file_path != NULL) free(pdf_doc->file_path); @@ -187,27 +170,21 @@ PdfDocument *refPdfDocument(const char *file_path, file_error_mode fe) } pdf_doc->doc = doc; } - // PDF file could be opened without problems, checksum ok. + /* PDF file could be opened without problems, checksum ok. */ if (PdfDocumentTree == NULL) PdfDocumentTree = avl_create(CompPdfDocument, NULL, &avl_xallocator); if ((PdfDocument *) avl_find(PdfDocumentTree, pdf_doc) == NULL) { - void **aa = avl_probe(PdfDocumentTree, pdf_doc); - assert(aa != NULL); + avl_probe(PdfDocumentTree, pdf_doc); } pdf_doc->occurences++; -#ifdef DEBUG - fprintf(stderr, "\nDEBUG: Incrementing %s (%d)\n", - pdf_doc->file_path, pdf_doc->occurences); -#endif return pdf_doc; } - - -// Returns pointer to PdfDocument structure for a PDF stream in memory -// of streamsize dimension -// As before, creates a new PdfDocument structure if it doesn't exist yet -// with file_path = file_id +/* + Returns pointer to PdfDocument structure for a PDF stream in memory of streamsize + dimension. As before, creates a new PdfDocument structure if it doesn't exist yet + with file_path = file_id +*/ PdfDocument *refMemStreamPdfDocument(char *docstream, unsigned long long streamsize,const char *file_id) { @@ -219,21 +196,16 @@ PdfDocument *refMemStreamPdfDocument(char *docstream, unsigned long long streams MemStream *docmemstream = NULL; /*int new_flag = 0;*/ size_t cnt = 0; - checksum = get_stream_checksum(docstream, streamsize); - assert(checksum != NULL); cnt = strlen(file_id); - assert(cnt>0 && cnt <STREAM_FILE_ID_LEN); - file_path = (char *) malloc(cnt+STREAM_URI_LEN+STRSTREAM_CHECKSUM_SIZE+1); // 1 for '\0' + assert(cnt>0 && cnt <STREAM_FILE_ID_LEN); + file_path = (char *) malloc(cnt+STREAM_URI_LEN+STRSTREAM_CHECKSUM_SIZE+1); /* 1 for \0 */ assert(file_path != NULL); strcpy(file_path,STREAM_URI); strcat(file_path,file_id); strcat(file_path,checksum); file_path[cnt+STREAM_URI_LEN+STRSTREAM_CHECKSUM_SIZE]='\0'; if ((pdf_doc = findPdfDocument(file_path)) == NULL) { -#ifdef DEBUG - fprintf(stderr, "\nDEBUG: New MemStreamPdfDocument %s\n", file_path); -#endif /*new_flag = 1;*/ pdf_doc = new PdfDocument; pdf_doc->file_path = file_path; @@ -241,61 +213,43 @@ PdfDocument *refMemStreamPdfDocument(char *docstream, unsigned long long streams pdf_doc->doc = NULL; pdf_doc->inObjList = NULL; pdf_doc->ObjMapTree = NULL; - pdf_doc->occurences = 0; // 0 = unreferenced + pdf_doc->occurences = 0; /* 0 = unreferenced */ pdf_doc->pc = 0; } else { -#ifdef DEBUG - fprintf(stderr, "\nDEBUG: Found MemStreamPdfDocument %s (%d)\n", - pdf_doc->file_path, pdf_doc->occurences); -#endif - assert(pdf_doc->checksum != NULL); - // As is now, checksum is in file_path, so this check should be useless. + /* As is now, checksum is in file_path, so this check should be useless. */ if (strncmp(pdf_doc->checksum, checksum, STRSTREAM_CHECKSUM_SIZE) != 0) { - luatex_fail("PDF inclusion: stream has changed '%s'", file_path); + formatted_error("pdf inclusion","stream has changed '%s'", file_path); } - free(file_path); + free(file_path); free(checksum); } - assert(pdf_doc != NULL); if (pdf_doc->doc == NULL) { -#ifdef DEBUG - fprintf(stderr, "\nDEBUG: New PDFDoc %s (%d)\n", - pdf_doc->file_path, pdf_doc->occurences); -#endif - docmemstream = new MemStream( docstream,0,streamsize, obj.initNull() ); - doc = new PDFDoc(docmemstream); // takes ownership of docmemstream + docmemstream = new MemStream( docstream,0,streamsize, obj.initNull() ); + doc = new PDFDoc(docmemstream); /* takes ownership of docmemstream */ pdf_doc->pc++; - if (!doc->isOk() || !doc->okToPrint()) { - luatex_fail("poppler: reading PDF Stream failed"); - } + normal_error("pdf inclusion","reading pdf Stream failed"); + } pdf_doc->doc = doc; } - // PDF file could be opened without problems, checksum ok. + /* PDF file could be opened without problems, checksum ok. */ if (PdfDocumentTree == NULL) PdfDocumentTree = avl_create(CompPdfDocument, NULL, &avl_xallocator); if ((PdfDocument *) avl_find(PdfDocumentTree, pdf_doc) == NULL) { - void **aa = avl_probe(PdfDocumentTree, pdf_doc); - assert(aa != NULL); + avl_probe(PdfDocumentTree, pdf_doc); } pdf_doc->occurences++; -#ifdef DEBUG - fprintf(stderr, "\nDEBUG: Incrementing %s (%d)\n", - pdf_doc->file_path, pdf_doc->occurences); -#endif return pdf_doc; } - - -//********************************************************************** -// AVL sort ObjMap into ObjMapTree by object number and generation - -// keep the ObjMap struct small, as these are accumulated until the end +/* + AVL sort ObjMap into ObjMapTree by object number and generation keep the ObjMap + struct small, as these are accumulated until the end +*/ struct ObjMap { - Ref in; // object num/gen in orig. PDF file - int out_num; // object num after embedding (gen == 0) + Ref in; + int out_num; }; static int CompObjMap(const void *pa, const void *pb, void * /*p */ ) @@ -304,11 +258,11 @@ static int CompObjMap(const void *pa, const void *pb, void * /*p */ ) const Ref *b = &(((const ObjMap *) pb)->in); if (a->num > b->num) return 1; - if (a->num < b->num) + else if (a->num < b->num) return -1; - if (a->gen == b->gen) // most likely gen == 0 anyway + else if (a->gen == b->gen) return 0; - if (a->gen < b->gen) + else if (a->gen < b->gen) return -1; return 1; } @@ -316,7 +270,6 @@ static int CompObjMap(const void *pa, const void *pb, void * /*p */ ) static ObjMap *findObjMap(PdfDocument * pdf_doc, Ref in) { ObjMap *obj_map, tmp; - assert(pdf_doc != NULL); if (pdf_doc->ObjMapTree == NULL) return NULL; tmp.in = in; @@ -327,32 +280,31 @@ static ObjMap *findObjMap(PdfDocument * pdf_doc, Ref in) static void addObjMap(PdfDocument * pdf_doc, Ref in, int out_num) { ObjMap *obj_map = NULL; - assert(findObjMap(pdf_doc, in) == NULL); if (pdf_doc->ObjMapTree == NULL) pdf_doc->ObjMapTree = avl_create(CompObjMap, NULL, &avl_xallocator); obj_map = new ObjMap; obj_map->in = in; obj_map->out_num = out_num; - void **aa = avl_probe(pdf_doc->ObjMapTree, obj_map); - assert(aa != NULL); + avl_probe(pdf_doc->ObjMapTree, obj_map); } -// When copying the Resources of the selected page, all objects are -// copied recursively top-down. The findObjMap() function checks if an -// object has already been copied; if so, instead of copying just the -// new object number will be referenced. The ObjMapTree guarantees, -// that during the entire LuaTeX run any object from any embedded PDF -// file will end up max. once in the output PDF file. Indirect objects -// are not fetched during copying, but get a new object number from -// LuaTeX and then will be appended into a linked list. +/* + When copying the Resources of the selected page, all objects are + copied recursively top-down. The findObjMap() function checks if an + object has already been copied; if so, instead of copying just the + new object number will be referenced. The ObjMapTree guarantees, + that during the entire LuaTeX run any object from any embedded PDF + file will end up max. once in the output PDF file. Indirect objects + are not fetched during copying, but get a new object number from + LuaTeX and then will be appended into a linked list. +*/ static int addInObj(PDF pdf, PdfDocument * pdf_doc, Ref ref) { ObjMap *obj_map; InObj *p, *q, *n; if (ref.num == 0) { - luatex_fail("PDF inclusion: reference to invalid object" - " (is the included pdf broken?)"); + normal_error("pdf inclusion","reference to invalid object (broken pdf)"); } if ((obj_map = findObjMap(pdf_doc, ref)) != NULL) return obj_map->out_num; @@ -361,12 +313,14 @@ static int addInObj(PDF pdf, PdfDocument * pdf_doc, Ref ref) n->next = NULL; n->num = pdf_create_obj(pdf, obj_type_others, 0); addObjMap(pdf_doc, ref, n->num); - if (pdf_doc->inObjList == NULL) + if (pdf_doc->inObjList == NULL) { pdf_doc->inObjList = n; - else { - // it is important to add new objects at the end of the list, - // because new objects are being added while the list is being - // written out by writeRefs(). + } else { + /* + It is important to add new objects at the end of the list, + because new objects are being added while the list is being + written out by writeRefs(). + */ for (p = pdf_doc->inObjList; p != NULL; p = p->next) q = p; q->next = n; @@ -374,15 +328,16 @@ static int addInObj(PDF pdf, PdfDocument * pdf_doc, Ref ref) return n->num; } -//********************************************************************** -// Function converts double to pdffloat; very small and very large numbers -// are NOT converted to scientific notation. -// n must be a number or real conforming to the implementation limits -// of PDF as specified in appendix C.1 of the PDF Ref. -// These are: -// maximum value of ints is +2^32 -// maximum value of reals is +2^15 -// smalles values of reals is 1/(2^16) +/* + Function converts double to pdffloat; very small and very large numbers + are NOT converted to scientific notation. Here n must be a number or real + conforming to the implementation limits of PDF as specified in appendix C.1 + of the PDF Ref. These are: + + maximum value of ints is +2^32 + maximum value of reals is +2^15 + smalles values of reals is 1/(2^16) +*/ static pdffloat conv_double_to_pdffloat(double n) { @@ -493,7 +448,6 @@ static void copyStream(PDF pdf, PdfDocument * pdf_doc, Stream * stream) { copyDict(pdf, pdf_doc, stream->getDict()); pdf_begin_stream(pdf); - assert(pdf->zip_write_state == NO_ZIP); copyStreamStream(pdf, stream->getUndecodedStream()); pdf_end_stream(pdf); } @@ -510,9 +464,11 @@ static void copyObject(PDF pdf, PdfDocument * pdf_doc, Object * obj) case objReal: copyReal(pdf, obj->getReal()); break; - // not needed: - // case objNum: - // GBool isNum() { return type == objInt || type == objReal; } + /* + case objNum: + GBool isNum() { return type == objInt || type == objReal; } + break; + */ case objString: copyString(pdf, obj->getString()); break; @@ -538,16 +494,14 @@ static void copyObject(PDF pdf, PdfDocument * pdf_doc, Object * obj) case objError: case objEOF: case objNone: - luatex_fail("PDF inclusion: type <%s> cannot be copied", - obj->getTypeName()); + formatted_error("pdf inclusion","type '%s' cannot be copied", obj->getTypeName()); break; default: - assert(0); // poppler doesn't have any other types + /* poppler doesn't have any other types */ + assert(0); } } -//********************************************************************** - static void writeRefs(PDF pdf, PdfDocument * pdf_doc) { InObj *r, *n; @@ -560,7 +514,7 @@ static void writeRefs(PDF pdf, PdfDocument * pdf_doc) if (obj1.isStream()) pdf_begin_obj(pdf, r->num, OBJSTM_NEVER); else - pdf_begin_obj(pdf, r->num, 2); // \pdfobjcompresslevel = 2 is for this + pdf_begin_obj(pdf, r->num, 2); copyObject(pdf, pdf_doc, &obj1); obj1.free(); pdf_end_obj(pdf); @@ -570,115 +524,120 @@ static void writeRefs(PDF pdf, PdfDocument * pdf_doc) } } -// get the pagebox coordinates according to the pagebox_spec +/* get the pagebox coordinates according to the pagebox_spec */ static PDFRectangle *get_pagebox(Page * page, int pagebox_spec) { switch (pagebox_spec) { - case PDF_BOX_SPEC_MEDIA: - return page->getMediaBox(); - break; - case PDF_BOX_SPEC_CROP: - return page->getCropBox(); - break; - case PDF_BOX_SPEC_BLEED: - return page->getBleedBox(); - break; - case PDF_BOX_SPEC_TRIM: - return page->getTrimBox(); - break; - case PDF_BOX_SPEC_ART: - return page->getArtBox(); - break; - default: - luatex_fail("PDF inclusion: unknown value of pagebox spec (%i)", - (int) pagebox_spec); + case PDF_BOX_SPEC_MEDIA: + return page->getMediaBox(); + break; + case PDF_BOX_SPEC_CROP: + return page->getCropBox(); + break; + case PDF_BOX_SPEC_BLEED: + return page->getBleedBox(); + break; + case PDF_BOX_SPEC_TRIM: + return page->getTrimBox(); + break; + case PDF_BOX_SPEC_ART: + return page->getArtBox(); + break; + default: + return page->getMediaBox(); + break; } - return page->getMediaBox(); // to make the compiler happy } -// Reads various information about the PDF and sets it up for later inclusion. -// This will fail if the PDF version of the PDF is higher than -// minor_pdf_version_wanted or page_name is given and can not be found. -// It makes no sense to give page_name _and_ page_num. -// Returns the page number. +/* + Reads various information about the PDF and sets it up for later inclusion. + This will fail if the PDF version of the PDF is higher than minor_pdf_version_wanted + or page_name is given and can not be found. It makes no sense to give page_name and + page_num. Returns the page number. +*/ -void -read_pdf_info(image_dict * idict, int minor_pdf_version_wanted, - int pdf_inclusion_errorlevel, img_readtype_e readtype) +void flush_pdf_info(image_dict * idict) { - PdfDocument *pdf_doc; - PDFDoc *doc; + if (img_keepopen(idict)) { + unrefPdfDocument(img_filepath(idict)); + } +} + +/* + void flush_pdfstream_info(image_dict * idict) + { + if (img_pdfstream_ptr(idict) != NULL) { + xfree(img_pdfstream_stream(idict)); + xfree(img_pdfstream_ptr(idict)); + img_pdfstream_stream(idict) = NULL; + img_pdfstream_ptr(idict) = NULL; + } + } +*/ + +void read_pdf_info(image_dict * idict) +{ + PdfDocument *pdf_doc = NULL; + PDFDoc *doc = NULL; Catalog *catalog; Page *page; int rotate; PDFRectangle *pagebox; int pdf_major_version_found, pdf_minor_version_found; float xsize, ysize, xorig, yorig; - assert(idict != NULL); - assert((img_type(idict) == IMG_TYPE_PDF) || (img_type(idict) == IMG_TYPE_PDFMEMSTREAM)); - assert(readtype == IMG_CLOSEINBETWEEN); // only this is implemented - // initialize if (isInit == gFalse) { - if (!(globalParams)) // globalParams could be already created - globalParams = new GlobalParams(); - globalParams->setErrQuiet(gFalse); - isInit = gTrue; - } - // open PDF file - if (img_type(idict) == IMG_TYPE_PDF) - pdf_doc = refPdfDocument(img_filepath(idict), FE_FAIL); + if (!(globalParams)) + globalParams = new GlobalParams(); + globalParams->setErrQuiet(gFalse); + isInit = gTrue; + } + if (img_type(idict) == IMG_TYPE_PDF) + pdf_doc = refPdfDocument(img_filepath(idict), FE_FAIL); else if (img_type(idict) == IMG_TYPE_PDFMEMSTREAM) { - pdf_doc = findPdfDocument(img_filepath(idict)) ; - assert(pdf_doc != NULL); - pdf_doc->occurences++; - } else - luatex_fail("PDF inclusion: unknown document (1)"); + pdf_doc = findPdfDocument(img_filepath(idict)) ; + pdf_doc->occurences++; + } else { + normal_error("pdf inclusion","unknown document"); + } doc = pdf_doc->doc; catalog = doc->getCatalog(); - // check PDF version - // this works only for PDF 1.x -- but since any versions of PDF newer - // than 1.x will not be backwards compatible to PDF 1.x, pdfTeX will - // then have to changed drastically anyway. + /* + Check PDF version. This works only for PDF 1.x but since any versions of + PDF newer than 1.x will not be backwards compatible to PDF 1.x, we will + then have to changed drastically anyway. + */ pdf_major_version_found = doc->getPDFMajorVersion(); pdf_minor_version_found = doc->getPDFMinorVersion(); - if ((pdf_major_version_found > 1) - || (pdf_minor_version_found > minor_pdf_version_wanted)) { - const char *msg = - "PDF inclusion: found PDF version <%d.%d>, but at most version <1.%d> allowed"; - if (pdf_inclusion_errorlevel > 0) { - luatex_fail(msg, pdf_major_version_found, pdf_minor_version_found, - minor_pdf_version_wanted); + if ((pdf_major_version_found > 1) || (pdf_minor_version_found > img_pdfminorversion(idict))) { + const char *msg = "PDF inclusion: found PDF version '%d.%d', but at most version '1.%d' allowed"; + if (img_errorlevel(idict) > 0) { + formatted_error("pdf inclusion",msg, pdf_major_version_found, pdf_minor_version_found, img_pdfminorversion(idict)); } else { - luatex_warn(msg, pdf_major_version_found, pdf_minor_version_found, - minor_pdf_version_wanted); + formatted_warning("pdf inclusion",msg, pdf_major_version_found, pdf_minor_version_found, img_pdfminorversion(idict)); } } img_totalpages(idict) = catalog->getNumPages(); if (img_pagename(idict)) { - // get page by name + /* get page by name */ GooString name(img_pagename(idict)); LinkDest *link = doc->findDest(&name); if (link == NULL || !link->isOk()) - luatex_fail("PDF inclusion: invalid destination <%s>", - img_pagename(idict)); + formatted_error("pdf inclusion","invalid destination '%s'",img_pagename(idict)); Ref ref = link->getPageRef(); img_pagenum(idict) = catalog->findPage(ref.num, ref.gen); if (img_pagenum(idict) == 0) - luatex_fail("PDF inclusion: destination is not a page <%s>", - img_pagename(idict)); + formatted_error("pdf inclusion","destination is not a page '%s'",img_pagename(idict)); delete link; } else { - // get page by number + /* get page by number */ if (img_pagenum(idict) <= 0 || img_pagenum(idict) > img_totalpages(idict)) - luatex_fail("PDF inclusion: required page <%i> does not exist", - (int) img_pagenum(idict)); + formatted_error("pdf inclusion","required page '%i' does not exist",(int) img_pagenum(idict)); } - // get the required page + /* get the required page */ page = catalog->getPage(img_pagenum(idict)); - - // get the pagebox coordinates (media, crop,...) to use. + /* get the pagebox coordinates (media, crop,...) to use. */ pagebox = get_pagebox(page, img_pagebox(idict)); if (pagebox->x2 > pagebox->x1) { xorig = pagebox->x1; @@ -694,51 +653,64 @@ read_pdf_info(image_dict * idict, int minor_pdf_version_wanted, yorig = pagebox->y2; ysize = pagebox->y1 - pagebox->y2; } - // The following 4 parameters are raw. Do _not_ modify by /Rotate! + /* The following 4 parameters are raw. Do _not_ modify by /Rotate! */ img_xsize(idict) = bp2sp(xsize); img_ysize(idict) = bp2sp(ysize); img_xorig(idict) = bp2sp(xorig); img_yorig(idict) = bp2sp(yorig); - - // Handle /Rotate parameter. Only multiples of 90 deg. are allowed - // (PDF Ref. v1.3, p. 78). + /* + Handle /Rotate parameter. Only multiples of 90 deg. are allowed (PDF Ref. v1.3, + p. 78). We also accept negative angles. Beware: PDF counts clockwise! */ rotate = page->getRotate(); - switch (((rotate % 360) + 360) % 360) { // handles also neg. angles - case 0: - img_rotation(idict) = 0; - break; - case 90: - img_rotation(idict) = 3; // PDF counts clockwise! - break; - case 180: - img_rotation(idict) = 2; - break; - case 270: - img_rotation(idict) = 1; - break; - default: - luatex_warn - ("PDF inclusion: " - "/Rotate parameter in PDF file not multiple of 90 degrees."); + switch (((rotate % 360) + 360) % 360) { + case 0: + img_rotation(idict) = 0; + break; + case 90: + img_rotation(idict) = 3; + break; + case 180: + img_rotation(idict) = 2; + break; + case 270: + img_rotation(idict) = 1; + break; + default: + formatted_warning("pdf inclusion","/Rotate parameter in PDF file not multiple of 90 degrees"); } - - // currently unused info whether PDF contains a /Group + /* currently unused info whether PDF contains a /Group */ if (page->getGroup() != NULL) img_set_group(idict); + /* + LuaTeX pre 0.85 versions did this: - if (readtype == IMG_CLOSEINBETWEEN) + if (readtype == IMG_CLOSEINBETWEEN) { + unrefPdfDocument(img_filepath(idict)); + } + + and also unref'd in the finalizer zo we got an extra unrefs when garbage was + collected. However it is more efficient to keep the file open so we do that + now. The (slower) alternative is to unref here (which in most cases forcing a + close of the file) but then we must not call flush_pdf_info. + + A close (unref) can be forced by nilling the dict object at the lua end and + forcing a collectgarbage("collect") after that. + + */ + if (! img_keepopen(idict)) { unrefPdfDocument(img_filepath(idict)); + } } -//********************************************************************** -// Writes the current epf_doc. -// Here the included PDF is copied, so most errors that can happen -// during PDF inclusion will arise here. +/* + Write the current epf_doc. Here the included PDF is copied, so most errors + that can happen during PDF inclusion will arise here. +*/ void write_epdf(PDF pdf, image_dict * idict) { - PdfDocument *pdf_doc; - PDFDoc *doc; + PdfDocument *pdf_doc = NULL; + PDFDoc *doc = NULL; Catalog *catalog; Page *page; Ref *pageref; @@ -748,46 +720,39 @@ void write_epdf(PDF pdf, image_dict * idict) int i, l; double bbox[4]; char s[256]; - const char *pagedictkeys[] = - { "Group", "LastModified", "Metadata", "PieceInfo", "Resources", - "SeparationInfo", NULL + const char *pagedictkeys[] = { + "Group", "LastModified", "Metadata", "PieceInfo", "Resources", "SeparationInfo", NULL }; - assert(idict != NULL); - - // open PDF file - if (img_type(idict) == IMG_TYPE_PDF) - pdf_doc = refPdfDocument(img_filepath(idict), FE_FAIL); - else if (img_type(idict) == IMG_TYPE_PDFMEMSTREAM) { - pdf_doc = findPdfDocument(img_filepath(idict)) ; - assert(pdf_doc != NULL); - pdf_doc->occurences++; - } else - luatex_fail("PDF inclusion: unknown document (2)"); + /* open PDF file */ + if (img_type(idict) == IMG_TYPE_PDF) { + pdf_doc = refPdfDocument(img_filepath(idict), FE_FAIL); + } else if (img_type(idict) == IMG_TYPE_PDFMEMSTREAM) { + pdf_doc = findPdfDocument(img_filepath(idict)) ; + pdf_doc->occurences++; + } else { + normal_error("pdf inclusion","unknown document"); + } doc = pdf_doc->doc; catalog = doc->getCatalog(); page = catalog->getPage(img_pagenum(idict)); pageref = catalog->getPageRef(img_pagenum(idict)); - assert(pageref != NULL); // was checked already in read_pdf_info() doc->getXRef()->fetch(pageref->num, pageref->gen, &pageobj); pageDict = pageobj.getDict(); - - // write the Page header + /* write the Page header */ pdf_begin_obj(pdf, img_objnum(idict), OBJSTM_NEVER); pdf_begin_dict(pdf); pdf_dict_add_name(pdf, "Type", "XObject"); pdf_dict_add_name(pdf, "Subtype", "Form"); - if (img_attr(idict) != NULL && strlen(img_attr(idict)) > 0) pdf_printf(pdf, "\n%s\n", img_attr(idict)); pdf_dict_add_int(pdf, "FormType", 1); - - // write additional information + /* write additional information */ pdf_dict_add_img_filename(pdf, idict); snprintf(s, 30, "%s.PageNumber", pdfkeyprefix); pdf_dict_add_int(pdf, s, (int) img_pagenum(idict)); doc->getDocInfoNF(&obj1); if (obj1.isRef()) { - // the info dict must be indirect (PDF Ref p. 61) + /* the info dict must be indirect (PDF Ref p. 61) */ snprintf(s, 30, "%s.InfoDict", pdfkeyprefix); pdf_dict_add_ref(pdf, s, addInObj(pdf, pdf_doc, obj1.getRef())); } @@ -798,7 +763,7 @@ void write_epdf(PDF pdf, image_dict * idict) bbox[2] = sp2bp(img_bbox(idict)[2]); bbox[3] = sp2bp(img_bbox(idict)[3]); } else { - // get the pagebox coordinates (media, crop,...) to use. + /* get the pagebox coordinates (media, crop,...) to use. */ pagebox = get_pagebox(page, img_pagebox(idict)); bbox[0] = pagebox->x1; bbox[1] = pagebox->y1; @@ -812,30 +777,30 @@ void write_epdf(PDF pdf, image_dict * idict) copyReal(pdf, bbox[2]); copyReal(pdf, bbox[3]); pdf_end_array(pdf); - // The /Matrix calculation is replaced by transforms in out_img(). - - // Now all relevant parts of the Page dictionary are copied: - - // Metadata validity check (as a stream it must be indirect) + /* + Now all relevant parts of the Page dictionary are copied. Metadata validity + check is needed(as a stream it must be indirect). + */ pageDict->lookupNF("Metadata", &obj1); if (!obj1.isNull() && !obj1.isRef()) - luatex_warn("PDF inclusion: /Metadata must be indirect object"); + formatted_warning("pdf inclusion","/Metadata must be indirect object"); obj1.free(); - - // copy selected items in Page dictionary + /* copy selected items in Page dictionary */ for (i = 0; pagedictkeys[i] != NULL; i++) { pageDict->lookupNF(pagedictkeys[i], &obj1); if (!obj1.isNull()) { pdf_add_name(pdf, pagedictkeys[i]); - copyObject(pdf, pdf_doc, &obj1); // preserves indirection + /* preserves indirection */ + copyObject(pdf, pdf_doc, &obj1); } obj1.free(); } - - // If there are no Resources in the Page dict of the embedded page, - // try to inherit the Resources from the Pages tree of the embedded - // PDF file, climbing up the tree until the Resources are found. - // (This fixes a problem with Scribus 1.3.3.14.) + /* + If there are no Resources in the Page dict of the embedded page, + try to inherit the Resources from the Pages tree of the embedded + PDF file, climbing up the tree until the Resources are found. + (This fixes a problem with Scribus 1.3.3.14.) + */ pageDict->lookupNF("Resources", &obj1); if (obj1.isNull()) { op1 = &pagesobj1; @@ -856,30 +821,28 @@ void write_epdf(PDF pdf, image_dict * idict) op2->free(); }; if (!op1->isDict()) - luatex_warn("PDF inclusion: Page /Resources missing."); + formatted_warning("pdf inclusion","Page /Resources missing"); op1->free(); } obj1.free(); - - // write the Page contents + /* Write the Page contents. */ page->getContents(&contents); if (contents.isStream()) { - // Variant A: get stream and recompress under control - // of \pdfcompresslevel - // - // pdf_begin_stream(); - // copyStreamStream(contents->getStream()); - // pdf_end_stream(); - - // Variant B: copy stream without recompressing - // + /* + Variant A: get stream and recompress under control of \pdfcompresslevel + + pdf_begin_stream(); + copyStreamStream(contents->getStream()); + pdf_end_stream(); + + Variant B: copy stream without recompressing + */ contents.streamGetDict()->lookup("F", &obj1); if (!obj1.isNull()) { - luatex_fail("PDF inclusion: Unsupported external stream"); + normal_error("pdf inclusion","unsupported external stream"); } obj1.free(); contents.streamGetDict()->lookup("Length", &obj1); - assert(!obj1.isNull()); pdf_add_name(pdf, "Length"); copyObject(pdf, pdf_doc, &obj1); obj1.free(); @@ -908,46 +871,45 @@ void write_epdf(PDF pdf, image_dict * idict) copyStreamStream(pdf, (contents.arrayGet(i, &obj1))->getStream()); obj1.free(); if (i < (l - 1)) { - // put a space between streams to be on the safe side (streams - // should have a trailing space here, but one never knows) + /* + Put a space between streams to be on the safe side (streams + should have a trailing space here, but one never knows) + */ pdf_out(pdf, ' '); } } pdf_end_stream(pdf); pdf_end_obj(pdf); - } else { // the contents are optional, but we need to include an empty stream + } else { + /* the contents are optional, but we need to include an empty stream */ pdf_dict_add_streaminfo(pdf); pdf_end_dict(pdf); pdf_begin_stream(pdf); pdf_end_stream(pdf); pdf_end_obj(pdf); } - // write out all indirect objects + /* write out all indirect objects */ writeRefs(pdf, pdf_doc); contents.free(); pageobj.free(); - // unrefPdfDocument() must come after contents.free() and pageobj.free()! - // TH: The next line makes repeated pdf inclusion unacceptably slow -#if 0 - unrefPdfDocument(img_filepath(idict)); -#endif + /* + unrefPdfDocument() must come after contents.free() and pageobj.free()! + TH: The next line makes repeated pdf inclusion unacceptably slow + + unrefPdfDocument(img_filepath(idict)); + */ } -//********************************************************************** -// Deallocate a PdfDocument with all its resources +/* Deallocate a PdfDocument with all its resources. */ static void deletePdfDocumentPdfDoc(PdfDocument * pdf_doc) { InObj *r, *n; - assert(pdf_doc != NULL); - // this may be probably needed for an emergency destroyPdfDocument() + /* this may be probably needed for an emergency destroyPdfDocument() */ for (r = pdf_doc->inObjList; r != NULL; r = n) { n = r->next; delete r; } -#ifdef DEBUG - fprintf(stderr, "\nDEBUG: Deleting PDFDoc %s\n", pdf_doc->file_path); -#endif delete pdf_doc->doc; pdf_doc->doc = NULL; pdf_doc->pc++; @@ -957,47 +919,46 @@ static void destroyPdfDocument(void *pa, void * /*pb */ ) { PdfDocument *pdf_doc = (PdfDocument *) pa; deletePdfDocumentPdfDoc(pdf_doc); - // TODO: delete rest of pdf_doc + /* TODO: delete rest of pdf_doc */ } -// Called when an image has been written and its resources in image_tab are -// freed and it's not referenced anymore. +/* + Called when an image has been written and its resources in image_tab are + freed and it's not referenced anymore. +*/ void unrefPdfDocument(char *file_path) { PdfDocument *pdf_doc = findPdfDocument(file_path); - if (pdf_doc == NULL) /* Does the caller break the contract ? */ -return; - if (pdf_doc->occurences == 0) /* Again, does the caller breaks the contract ? */ -return; - /* for the moment we keep these assert here as remind that the code */ - /* should be revisited */ - //assert(pdf_doc != NULL); - //assert(pdf_doc->occurences != 0); // aim for point landing - pdf_doc->occurences--; -#ifdef DEBUG - fprintf(stderr, "\nDEBUG: Decrementing %s (%d)\n", - pdf_doc->file_path, pdf_doc->occurences); -#endif - if (pdf_doc->occurences == 0) { - assert(pdf_doc->inObjList == NULL); // should be eaten up already - deletePdfDocumentPdfDoc(pdf_doc); + if (pdf_doc->occurences > 0) { + pdf_doc->occurences--; + if (pdf_doc->occurences == 0) { + deletePdfDocumentPdfDoc(pdf_doc); + } + } else { + /* + We either have a mismatch in ref and unref or we're somehow out of sync + which can happen when we mess with the same file in lua and tex. + */ + formatted_warning("pdf inclusion","there can be a mismatch in opening and closing file '%s'",file_path); } } - - -// For completeness, but it isn't currently used -// (unreferencing is done by mean of file_path) +/* + For completeness, but it isn't currently used (unreferencing is done by mean + of file_path. +*/ void unrefMemStreamPdfDocument(char *file_id) { (void) unrefPdfDocument(file_id); - + } -// Called when PDF embedding system is finalized. -// Now deallocate all remaining PdfDocuments. +/* + Called when PDF embedding system is finalized. We now deallocate all remaining + PdfDocuments. +*/ void epdf_free() { diff --git a/Build/source/texk/web2c/luatexdir/image/writeimg.h b/Build/source/texk/web2c/luatexdir/image/writeimg.h index 13f2d3642a5..46c42d2657e 100644 --- a/Build/source/texk/web2c/luatexdir/image/writeimg.h +++ b/Build/source/texk/web2c/luatexdir/image/writeimg.h @@ -18,11 +18,10 @@ You should have received a copy of the GNU General Public License along with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */ - #ifndef WRITEIMG_H # define WRITEIMG_H -# include "dvi/dvigen.h" /* for scaled_whd only */ +# include "dvi/dvigen.h" # include "image.h" # include "pdf/pdfpage.h" @@ -31,10 +30,9 @@ idict_entry *idict_array; void new_img_pdfstream_struct(image_dict *); image *new_image(void); -/*void init_image_dict(image_dict *);*/ image_dict *new_image_dict(void); void free_image_dict(image_dict * p); -void read_img(PDF, image_dict *, int, int); +void read_img(image_dict * p); void scan_pdfximage(PDF pdf); void scan_pdfrefximage(PDF pdf); scaled_whd tex_scale(scaled_whd nat, scaled_whd tex); @@ -50,4 +48,4 @@ scaled_whd scan_alt_rule(void); size_t read_file_to_buf(PDF pdf, FILE * f, size_t len); void pdf_dict_add_img_filename(PDF pdf, image_dict * idict); -#endif /* WRITEIMG_H */ +#endif diff --git a/Build/source/texk/web2c/luatexdir/image/writeimg.w b/Build/source/texk/web2c/luatexdir/image/writeimg.w index ff667cfe62e..c002b56dca9 100644 --- a/Build/source/texk/web2c/luatexdir/image/writeimg.w +++ b/Build/source/texk/web2c/luatexdir/image/writeimg.w @@ -21,8 +21,6 @@ @* Image inclusion. @ @c - - #include "ptexlib.h" #include <assert.h> #include <kpathsea/c-auto.h> @@ -40,78 +38,63 @@ @* Patch ImageTypeDetection 2003/02/08 by Heiko Oberdiek. - Function |readimage| performs some basic initializations. - Then it looks at the file extension to determine the - image type and calls specific code/functions. - - The main disadvantage is that standard file extensions - have to be used, otherwise pdfTeX is not able to detect - the correct image type. +Function |readimage| performs some basic initializations. Then it looks at the +file extension to determine the image type and calls specific code/functions. The +main disadvantage is that standard file extensions have to be used, otherwise +pdfTeX is not able to detect the correct image type. The patch now looks at the +file header first regardless of the file extension. This is implemented in +function |check_type_by_header|. If this check fails, the traditional test of +standard file extension is tried, done in function |check_type_by_extension|. - The patch now looks at the file header first regardless of - the file extension. This is implemented in function - |check_type_by_header|. If this check fails, the traditional - test of standard file extension is tried, done in function - |check_type_by_extension|. +Magic headers: - Magic headers: +* "PNG (Portable Network Graphics) Specification", Version 1.2 + (http://www.libpng.org/pub/png): - * "PNG (Portable Network Graphics) Specification", Version 1.2 - (http://www.libpng.org/pub/png): + 3.1. PNG file signature - 3.1. PNG file signature + The first eight bytes of a PNG file always contain the following + (decimal) values: 137 80 78 71 13 10 26 10 - The first eight bytes of a PNG file always contain the following - (decimal) values: +Translation to C: |"\x89PNG\r\n\x1A\n"| - 137 80 78 71 13 10 26 10 +* "JPEG File Interchange Format", Version 1.02: - Translation to C: |"\x89PNG\r\n\x1A\n"| + * you can identify a JFIF file by looking for the following sequence: + X'FF', SOI X'FF', APP0, <2 bytes to be skipped>, "JFIF", X'00'. - * "JPEG File Interchange Format", Version 1.02: +Function |check_type_by_header| only looks at the first two bytes: |"\xFF\xD8"| - o you can identify a JFIF file by looking for the following - sequence: X'FF', SOI X'FF', APP0, <2 bytes to be skipped>, - "JFIF", X'00'. +* ISO/IEC JTC 1/SC 29/WG 1 + (ITU-T SG8) + Coding of Still Pictures + Title: 14492 FCD + Source: JBIG Committee + Project: JTC 1.29.10 + Status: Final Committee Draft - Function |check_type_by_header| only looks at the first two bytes: - |"\xFF\xD8"| + D.4.1, ID string - * ISO/IEC JTC 1/SC 29/WG 1 - (ITU-T SG8) - Coding of Still Pictures - Title: 14492 FCD - Source: JBIG Committee - Project: JTC 1.29.10 - Status: Final Committee Draft + This is an 8-byte sequence containing 0x97 0x4A 0x42 0x32 0x0D 0x0A 0x1A 0x0A. - D.4.1, ID string +* "PDF Reference", third edition: - This is an 8-byte sequence containing 0x97 0x4A 0x42 0x32 0x0D 0x0A - 0x1A 0x0A. + * The first line should contain \%PDF-1.0 -- \%PDF-1.4 (section 3.4.1 "File Header"). + * The "implementation notes" say: - * "PDF Reference", third edition: + 3.4.1, File Header + 12. Acrobat viewers require only that the header appear somewhere within the + first 1024 bytes of the file. + 13. Acrobat viewers will also accept a header of the form \%!PS-Adobe-N.n PDF-M.m - * The first line should contain "\%PDF-1.0" until "\%PDF-1.4" - (section 3.4.1 "File Header"). - * The "implementation notes" say: +The check in function |check_type_by_header| only implements the first issue. The +implementation notes are not considered. Therefore files with garbage at start of +file must have the standard extension. - 3.4.1, File Header - 12. Acrobat viewers require only that the header appear - somewhere within the first 1024 bytes of the file. - 13. Acrobat viewers will also accept a header of the form - \%!PS-Adobe-N.n PDF-M.m - - The check in function |check_type_by_header| only implements - the first issue. The implementation notes are not considered. - Therefore files with garbage at start of file must have the - standard extension. - - Functions |check_type_by_header| and |check_type_by_extension|: - |img_type(img)| is set to |IMG_TYPE_NONE| by |new_image_dict()|. - Both functions try to detect a type and set |img_type(img)|. - Thus a value other than |IMG_TYPE_NONE| indicates that a - type has been found. +Functions |check_type_by_header| and |check_type_by_extension|: |img_type(img)| +is set to |IMG_TYPE_NONE| by |new_image_dict()|. Both functions try to detect a +type and set |img_type(img)|. Thus a value other than |IMG_TYPE_NONE| indicates +that a type has been found. @c #define HEADER_JPG "\xFF\xD8" @@ -121,8 +104,7 @@ #define HEADER_PDF "%PDF-1." #define MAX_HEADER (sizeof(HEADER_PNG)-1) #define HEADER_PDF_MEMSTREAM "data:application/pdf," /* see epdf.h */ -#define LEN_PDF_MEMSTREAM 21 /* see epdf.h */ - +#define LEN_PDF_MEMSTREAM 21 /* see epdf.h */ static void check_type_by_header(image_dict * idict) { @@ -132,17 +114,13 @@ static void check_type_by_header(image_dict * idict) char prefix[LEN_PDF_MEMSTREAM+1]; assert(idict != NULL); - if (img_type(idict) != IMG_TYPE_NONE) /* nothing to do */ + if (img_type(idict) != IMG_TYPE_NONE) return; - - /* read the header */ - /* Like */ - /* file = xfopen(img_filepath(idict), FOPEN_RBIN_MODE);*/ - /* but we also check for a memstream object */ + /* here we read the and also check for a memstream object */ assert(img_filepath(idict) && FOPEN_RBIN_MODE); file = fopen(img_filepath(idict), FOPEN_RBIN_MODE); if (file == NULL) { - /* check the prefix of img_filepath(idict) */ + /* check the prefix of img_filepath(idict) */ for (i = 0; (unsigned) i < LEN_PDF_MEMSTREAM; i++) { prefix[i] = (char) (img_filepath(idict)[i]); } @@ -158,7 +136,7 @@ static void check_type_by_header(image_dict * idict) for (i = 0; (unsigned) i < MAX_HEADER; i++) { header[i] = (char) xgetc(file); if (feof(file)) - luatex_fail("reading image file failed"); + normal_error("pdf backend","reading image file failed"); } xfclose(file, img_filepath(idict)); /* tests */ @@ -178,8 +156,8 @@ static void check_type_by_header(image_dict * idict) static void check_type_by_extension(image_dict * idict) { char *image_suffix; - - assert(idict != NULL); + if (idict != NULL) + return; if (img_type(idict) != IMG_TYPE_NONE) /* nothing to do */ return; /* tests */ @@ -209,28 +187,22 @@ void new_img_pdfstream_struct(image_dict * p) } @ @c -static void init_image(image * p) +image *new_image(void) { - assert(p != NULL); + image *p = xtalloc(1, image); set_wd_running(p); set_ht_running(p); set_dp_running(p); img_transform(p) = 0; img_dict(p) = NULL; img_dictref(p) = LUA_NOREF; -} - -@ @c -image *new_image(void) -{ - image *p = xtalloc(1, image); - init_image(p); return p; } @ @c -static void init_image_dict(image_dict * p) +image_dict *new_image_dict(void) { + image_dict *p = xtalloc(1, image_dict); assert(p != NULL); memset(p, 0, sizeof(image_dict)); set_wd_running(p); @@ -243,14 +215,11 @@ static void init_image_dict(image_dict * p) img_unset_bbox(p); img_unset_group(p); img_state(p) = DICT_NEW; - img_index(p) = -1; /* -1 = unused, used count from 0 */ -} - -@ @c -image_dict *new_image_dict(void) -{ - image_dict *p = xtalloc(1, image_dict); - init_image_dict(p); + img_index(p) = -1; /* -1 = unused, used count from 0 */ + img_luaref(p) = 0; + img_errorlevel(p) = pdf_inclusion_errorlevel; + fix_pdf_minorversion(static_pdf); + img_pdfminorversion(p) = pdf_minor_version; return p; } @@ -271,31 +240,33 @@ void free_image_dict(image_dict * p) /* called from limglib.c */ assert(img_state(p) < DICT_REFERED); switch (img_type(p)) { - case IMG_TYPE_PDFMEMSTREAM: - case IMG_TYPE_PDF: - unrefPdfDocument(img_filepath(p)); - break; - case IMG_TYPE_PNG: /* assuming |IMG_CLOSEINBETWEEN| */ - assert(img_png_ptr(p) == NULL); - break; - case IMG_TYPE_JPG: /* assuming |IMG_CLOSEINBETWEEN| */ - assert(img_jpg_ptr(p) == NULL); - break; - case IMG_TYPE_JP2: /* */ - assert(img_jp2_ptr(p) == NULL); - break; - case IMG_TYPE_JBIG2: /* todo: writejbig2.w cleanup */ - break; - case IMG_TYPE_PDFSTREAM: - if (img_pdfstream_ptr(p) != NULL) { - xfree(img_pdfstream_stream(p)); - xfree(img_pdfstream_ptr(p)); - } - break; - case IMG_TYPE_NONE: - break; - default: - assert(0); + case IMG_TYPE_PDFMEMSTREAM: + case IMG_TYPE_PDF: + flush_pdf_info(p); + break; + case IMG_TYPE_PNG: + flush_png_info(p); + break; + case IMG_TYPE_JPG: + flush_jpg_info(p); + break; + case IMG_TYPE_JP2: + flush_jp2_info(p); + break; + case IMG_TYPE_JBIG2: + flush_jbig2_info(p); + break; + case IMG_TYPE_PDFSTREAM: + /* flush_pdfstream_info(p); */ + if (img_pdfstream_ptr(p) != NULL) { + xfree(img_pdfstream_stream(p)); + xfree(img_pdfstream_ptr(p)); + } + break; + case IMG_TYPE_NONE: + break; + default: + assert(0); } free_dict_strings(p); assert(img_file(p) == NULL); @@ -303,14 +274,13 @@ void free_image_dict(image_dict * p) } @ @c -void read_img(PDF pdf, - image_dict * idict, int minor_version, int inclusion_errorlevel) +void read_img(image_dict * idict) { char *filepath = NULL; int callback_id; assert(idict != NULL); if (img_filename(idict) == NULL) { - luatex_fail("image file name missing"); + normal_error("pdf backend","image file name missing"); } callback_id = callback_defined(find_image_file_callback); if (img_filepath(idict) == NULL) { @@ -324,7 +294,7 @@ void read_img(PDF pdf, img_filepath(idict) = kpse_find_file(img_filename(idict), kpse_tex_format, true); } if (img_filepath(idict) == NULL) { - luatex_fail("cannot find image file '%s'", img_filename(idict)); + formatted_error("pdf backend","cannot find image file '%s'", img_filename(idict)); } } recorder_record_input(img_filename(idict)); @@ -333,31 +303,24 @@ void read_img(PDF pdf, check_type_by_extension(idict); /* read image */ switch (img_type(idict)) { - case IMG_TYPE_PDFMEMSTREAM: - case IMG_TYPE_PDF: - assert(pdf != NULL); /* TODO! */ - read_pdf_info(idict, minor_version, inclusion_errorlevel, - IMG_CLOSEINBETWEEN); - break; - case IMG_TYPE_PNG: - read_png_info(idict, IMG_CLOSEINBETWEEN); - break; - case IMG_TYPE_JPG: - read_jpg_info(pdf, idict, IMG_CLOSEINBETWEEN); - break; - case IMG_TYPE_JP2: - read_jp2_info(idict, IMG_CLOSEINBETWEEN); - break; - case IMG_TYPE_JBIG2: - if (minor_version < 4) { - luatex_fail - ("JBIG2 images only possible with at least PDF 1.4; you are generating PDF 1.%i", - (int) minor_version); - } - read_jbig2_info(idict); - break; - default: - luatex_fail("internal error: unknown image type (2)"); + case IMG_TYPE_PDFMEMSTREAM: + case IMG_TYPE_PDF: + read_pdf_info(idict); + break; + case IMG_TYPE_PNG: + read_png_info(idict); + break; + case IMG_TYPE_JPG: + read_jpg_info(idict); + break; + case IMG_TYPE_JP2: + read_jp2_info(idict); + break; + case IMG_TYPE_JBIG2: + read_jbig2_info(idict); + break; + default: + normal_error("pdf backend","internal error: unknown image type"); } cur_file_name = NULL; if (img_state(idict) < DICT_FILESCANNED) @@ -365,17 +328,14 @@ void read_img(PDF pdf, } @ @c -static image_dict *read_image(PDF pdf, char *file_name, int page_num, - char *page_name, int colorspace, - int page_box, int minor_version, - int inclusion_errorlevel) +static image_dict *read_image(char *file_name, int page_num, char *page_name, int colorspace, int page_box) { image *a = new_image(); image_dict *idict = img_dict(a) = new_image_dict(); - pdf->ximage_count++; - img_objnum(idict) = pdf_create_obj(pdf, obj_type_ximage, pdf->ximage_count); - img_index(idict) = pdf->ximage_count; - set_obj_data_ptr(pdf, img_objnum(idict), img_index(idict)); + static_pdf->ximage_count++; + img_objnum(idict) = pdf_create_obj(static_pdf, obj_type_ximage, static_pdf->ximage_count); + img_index(idict) = static_pdf->ximage_count; + set_obj_data_ptr(static_pdf, img_objnum(idict), img_index(idict)); idict_to_array(idict); img_colorspace(idict) = colorspace; img_pagenum(idict) = page_num; @@ -384,7 +344,7 @@ static image_dict *read_image(PDF pdf, char *file_name, int page_num, cur_file_name = file_name; img_filename(idict) = file_name; img_pagebox(idict) = page_box; - read_img(pdf, idict, minor_version, inclusion_errorlevel); + read_img(idict); return idict; } @@ -402,11 +362,12 @@ static pdfboxspec_e scan_pdf_box_spec(void) return PDF_BOX_SPEC_TRIM; else if (scan_keyword("artbox")) return PDF_BOX_SPEC_ART; - return PDF_BOX_SPEC_NONE; + else + return PDF_BOX_SPEC_NONE; } @ @c -void scan_pdfximage(PDF pdf) +void scan_pdfximage(PDF pdf) /* static_pdf */ { scaled_whd alt_rule; image_dict *idict; @@ -414,12 +375,12 @@ void scan_pdfximage(PDF pdf) char *named = NULL, *attr = NULL, *file_name = NULL; alt_rule = scan_alt_rule(); /* scans |<rule spec>| to |alt_rule| */ if (scan_keyword("attr")) { - scan_pdf_ext_toks(); + scan_toks(false, true); attr = tokenlist_to_cstring(def_ref, true, NULL); delete_token_ref(def_ref); } if (scan_keyword("named")) { - scan_pdf_ext_toks(); + scan_toks(false, true); named = tokenlist_to_cstring(def_ref, true, NULL); delete_token_ref(def_ref); page = 0; @@ -437,13 +398,11 @@ void scan_pdfximage(PDF pdf) if (pagebox == PDF_BOX_SPEC_NONE) pagebox = PDF_BOX_SPEC_CROP; } - scan_pdf_ext_toks(); + scan_toks(false, true); file_name = tokenlist_to_cstring(def_ref, true, NULL); assert(file_name != NULL); delete_token_ref(def_ref); - idict = - read_image(pdf, file_name, page, named, colorspace, pagebox, - pdf_minor_version, pdf_inclusion_errorlevel); + idict = read_image(file_name, page, named, colorspace, pagebox); img_attr(idict) = attr; img_dimen(idict) = alt_rule; img_transform(idict) = transform; @@ -452,7 +411,7 @@ void scan_pdfximage(PDF pdf) } @ @c -#define tail cur_list.tail_field +#define tail cur_list.tail_field void scan_pdfrefximage(PDF pdf) { @@ -559,11 +518,11 @@ scaled_whd scale_img(image_dict * idict, scaled_whd alt_rule, int transform) xr = img_xres(idict); yr = img_yres(idict); if (x <= 0 || y <= 0 || xr < 0 || yr < 0) - luatex_fail("ext1: invalid image dimensions"); + normal_error("pdf backend","invalid image dimensions"); if (xr > 65535 || yr > 65535) { xr = 0; yr = 0; - luatex_warn("ext1: too large image resolution ignored"); + normal_warning("pdf backend","too large image resolution ignored"); } if (((transform - img_rotation(idict)) & 1) == 1) { tmp = x; @@ -622,7 +581,7 @@ void write_img(PDF pdf, image_dict * idict) write_pdfstream(pdf, idict); break; default: - luatex_fail("internal error: unknown image type (1)"); + normal_error("pdf backend","internal error: unknown image type"); } report_stop_file(filetype_image); if (img_type(idict) == IMG_TYPE_PNG) { @@ -645,7 +604,7 @@ void pdf_write_image(PDF pdf, int n) void check_pdfstream_dict(image_dict * idict) { if (!img_is_bbox(idict)) - luatex_fail("image.stream: no bbox given"); + normal_error("pdf backend","image.stream: no bbox given"); if (img_state(idict) < DICT_FILESCANNED) img_state(idict) = DICT_FILESCANNED; } @@ -679,7 +638,6 @@ void write_pdfstream(PDF pdf, image_dict * idict) } @ @c -/* define |idict_ptr|, |idict_array|, and |idict_limit| */ idict_entry *idict_ptr, *idict_array = NULL; size_t idict_limit; @@ -721,6 +679,8 @@ void pdf_dict_add_img_filename(PDF pdf, image_dict * idict) } } +/* hh: why store images in the format ... let's get rid of this */ + @ To allow the use of box resources inside saved boxes in -ini mode, the information in the array has to be (un)dumped with the format. The next two routines take care of that. @@ -731,8 +691,7 @@ the split in two separate runs. There was only one problem remaining: The pdfversion and pdfinclusionerrorlevel can have changed inbetween the call to -|readimage()| and dump time. That is why they are passed as arguments -to undumpimagemeta once more. +|readimage()| and dump time. some of the dumped values are really type int, not integer, but since the macro falls back to |generic_dump| anyway, that @@ -746,121 +705,6 @@ does not matter. by the bytes. The trailing \.{\\0} is dumped as well, because that makes the code simpler. -@c -#define dumpcharptr(a) \ - do { \ - int x; \ - if (a!=NULL) { \ - x = (int)strlen(a)+1; \ - dumpinteger(x); dump_things(*a, x); \ - } else { \ - x = 0; dumpinteger(x); \ - } \ - } while (0) - -#define undumpcharptr(s) \ - do { \ - int x; \ - char *a; \ - undumpinteger (x); \ - if (x>0) { \ - a = xmalloc((unsigned)x); \ - undump_things(*a,x); \ - s = a ; \ - } else { s = NULL; } \ - } while (0) - -@ @c -void dumpimagemeta(void) -{ - int cur_index, i; - image_dict *idict; - - i = (int) idict_limit; - dumpinteger(i); - cur_index = (int) (idict_ptr - idict_array); - dumpinteger(cur_index); - - for (i = 1; i < cur_index; i++) { - idict = idict_array[i]; - assert(idict != NULL); - dumpcharptr(img_filename(idict)); - dumpinteger(img_type(idict)); - dumpinteger(img_procset(idict)); - dumpinteger(img_xsize(idict)); - dumpinteger(img_ysize(idict)); - dumpinteger(img_xres(idict)); - dumpinteger(img_yres(idict)); - dumpinteger(img_totalpages(idict)); - dumpinteger(img_colorspace(idict)); - - /* the |image_struct| is not dumped at all, except for a few - variables that are needed to restore the contents */ - - if ((img_type(idict) == IMG_TYPE_PDF)|| (img_type(idict) == IMG_TYPE_PDFMEMSTREAM)) { - dumpinteger(img_pagebox(idict)); - dumpinteger(img_pagenum(idict)); - } else if (img_type(idict) == IMG_TYPE_JBIG2) { - dumpinteger(img_pagenum(idict)); - } - - } -} - -@ @c -void undumpimagemeta(PDF pdf, int pdfversion, int pdfinclusionerrorlevel) -{ - int cur_index, i; - image_dict *idict; - - assert(pdf != NULL); - undumpinteger(i); - idict_limit = (size_t) i; - - idict_array = xtalloc(idict_limit, idict_entry); - undumpinteger(cur_index); - idict_ptr = idict_array + cur_index; - - for (i = 1; i < cur_index; i++) { - idict = new_image_dict(); - assert(idict != NULL); - assert(img_index(idict) == -1); - idict_to_array(idict); - undumpcharptr(img_filename(idict)); - undumpinteger(img_type(idict)); - undumpinteger(img_procset(idict)); - undumpinteger(img_xsize(idict)); - undumpinteger(img_ysize(idict)); - undumpinteger(img_xres(idict)); - undumpinteger(img_yres(idict)); - undumpinteger(img_totalpages(idict)); - undumpinteger(img_colorspace(idict)); - - switch (img_type(idict)) { - case IMG_TYPE_PDFMEMSTREAM: - case IMG_TYPE_PDF: - undumpinteger(img_pagebox(idict)); - undumpinteger(img_pagenum(idict)); - break; - case IMG_TYPE_PNG: - case IMG_TYPE_JPG: - case IMG_TYPE_JP2: - break; - case IMG_TYPE_JBIG2: - if (pdfversion < 4) { - luatex_fail - ("JBIG2 images only possible with at least PDF 1.4; you are generating PDF 1.%i", - (int) pdfversion); - } - undumpinteger(img_pagenum(idict)); - break; - default: - luatex_fail("unknown type of image"); - } - read_img(pdf, idict, pdfversion, pdfinclusionerrorlevel); - } -} - @ scan rule spec to |alt_rule| @c scaled_whd scan_alt_rule(void) diff --git a/Build/source/texk/web2c/luatexdir/image/writejbig2.h b/Build/source/texk/web2c/luatexdir/image/writejbig2.h index 95019b6c81b..e2c907bf687 100644 --- a/Build/source/texk/web2c/luatexdir/image/writejbig2.h +++ b/Build/source/texk/web2c/luatexdir/image/writejbig2.h @@ -18,7 +18,6 @@ You should have received a copy of the GNU General Public License along with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */ - #ifndef WRITEJBIG2_H # define WRITEJBIG2_H @@ -27,8 +26,10 @@ unsigned int read2bytes(FILE * f); unsigned int read4bytes(FILE * f); -void flush_jbig2_page0_objects(PDF); +boolean supported_jbig2(image_dict *); void read_jbig2_info(image_dict *); +void flush_jbig2_info(image_dict *); void write_jbig2(PDF, image_dict *); +void flush_jbig2_page0_objects(PDF); -#endif /* WRITEJBIG"_H */ +#endif diff --git a/Build/source/texk/web2c/luatexdir/image/writejbig2.w b/Build/source/texk/web2c/luatexdir/image/writejbig2.w index 7b676fb6e87..d1ed0a408d4 100644 --- a/Build/source/texk/web2c/luatexdir/image/writejbig2.w +++ b/Build/source/texk/web2c/luatexdir/image/writejbig2.w @@ -20,7 +20,6 @@ % with LuaTeX; if not, see <http://www.gnu.org/licenses/>. @ - This is experimental JBIG2 image support to pdfTeX. JBIG2 image decoding is part of Adobe PDF-1.4, and requires Acroread 5.0 or later. @@ -80,8 +79,6 @@ object exists, reference it. Else create fresh one. 09 Dec. 2002: JBIG2 seg. page numbers > 0 are now set to 1, see PDF Ref. @ @c - - #undef DEBUG #include "ptexlib.h" @@ -120,7 +117,7 @@ typedef enum { INITIAL, HAVEINFO, WRITEPDF } PHASE; typedef struct _LITEM { struct _LITEM *prev; struct _LITEM *next; - void *d; /* data */ + void *d; /* data */ } LITEM; typedef struct _LIST { @@ -133,26 +130,26 @@ typedef struct _SEGINFO { unsigned long segnum; boolean isrefered; boolean refers; - unsigned int seghdrflags; /* set by readseghdr() */ - boolean pageassocsizeflag; /* set by readseghdr() */ - unsigned int reftosegcount; /* set by readseghdr() */ - unsigned int countofrefered; /* set by readseghdr() */ - unsigned int fieldlen; /* set by readseghdr() */ - unsigned int segnumwidth; /* set by readseghdr() */ - long segpage; /* set by readseghdr() */ - unsigned long segdatalen; /* set by readseghdr() */ - unsigned long hdrstart; /* set by readseghdr() */ - unsigned long hdrend; /* set by readseghdr() */ + unsigned int seghdrflags; /* set by readseghdr() */ + boolean pageassocsizeflag; /* set by readseghdr() */ + unsigned int reftosegcount; /* set by readseghdr() */ + unsigned int countofrefered; /* set by readseghdr() */ + unsigned int fieldlen; /* set by readseghdr() */ + unsigned int segnumwidth; /* set by readseghdr() */ + long segpage; /* set by readseghdr() */ + unsigned long segdatalen; /* set by readseghdr() */ + unsigned long hdrstart; /* set by readseghdr() */ + unsigned long hdrend; /* set by readseghdr() */ unsigned long datastart; unsigned long dataend; - boolean endofstripeflag; /* set by checkseghdrflags() */ - boolean endofpageflag; /* set by checkseghdrflags() */ - boolean pageinfoflag; /* set by checkseghdrflags() */ - boolean endoffileflag; /* set by checkseghdrflags() */ + boolean endofstripeflag; /* set by checkseghdrflags() */ + boolean endofpageflag; /* set by checkseghdrflags() */ + boolean pageinfoflag; /* set by checkseghdrflags() */ + boolean endoffileflag; /* set by checkseghdrflags() */ } SEGINFO; typedef struct _PAGEINFO { - LIST segments; /* segments associated with page */ + LIST segments; /* segments associated with page */ unsigned long pagenum; unsigned int width; unsigned int height; @@ -167,12 +164,12 @@ typedef struct _FILEINFO { FILE *file; char *filepath; long filesize; - LIST pages; /* not including page0 */ + LIST pages; /* not including page0 */ LIST page0; - unsigned int filehdrflags; /* set by readfilehdr() */ - boolean sequentialaccess; /* set by readfilehdr() */ - unsigned long numofpages; /* set by readfilehdr() */ - unsigned long streamstart; /* set by |get_jbig2_info()| */ + unsigned int filehdrflags; /* set by readfilehdr() */ + boolean sequentialaccess; /* set by readfilehdr() */ + unsigned long numofpages; /* set by readfilehdr() */ + unsigned long streamstart; /* set by |get_jbig2_info()| */ unsigned long pdfpage0objnum; PHASE phase; } FILEINFO; @@ -183,22 +180,19 @@ static struct avl_table *file_tree = NULL; static int comp_file_entry(const void *pa, const void *pb, void *p) { (void) p; - return strcmp(((const FILEINFO *) pa)->filepath, - ((const FILEINFO *) pb)->filepath); + return strcmp(((const FILEINFO *) pa)->filepath,((const FILEINFO *) pb)->filepath); } static int comp_page_entry(const void *pa, const void *pb, void *p) { (void) p; - return (int) (((const PAGEINFO *) pa)->pagenum - - ((const PAGEINFO *) pb)->pagenum); + return (int) (((const PAGEINFO *) pa)->pagenum - ((const PAGEINFO *) pb)->pagenum); } static int comp_segment_entry(const void *pa, const void *pb, void *p) { (void) p; - return (int) (((const SEGINFO *) pa)->segnum - - ((const SEGINFO *) pb)->segnum); + return (int) (((const SEGINFO *) pa)->segnum - ((const SEGINFO *) pb)->segnum); } @ @c @@ -207,9 +201,9 @@ static int ygetc(FILE * stream) int c = getc(stream); if (c < 0) { if (c == EOF) - luatex_fail("getc() failed; premature end of JBIG2 image file"); + normal_error("readjbig2","premature end file"); else - luatex_fail("getc() failed (can't happen)"); + normal_error("readjbig2","can't happen"); } return c; } @@ -382,8 +376,7 @@ static void readfilehdr(FILEINFO * fip) xfseek(fip->file, 0, SEEK_SET, fip->filepath); for (i = 0; i < 8; i++) if (ygetc(fip->file) != jbig2_id[i]) - luatex_fail - ("readfilehdr(): reading JBIG2 image file failed: ID string missing"); + normal_error("readjbig2","ID string missing"); /* Annex D.4.2 File header flags */ fip->filehdrflags = (unsigned int) ygetc(fip->file); fip->sequentialaccess = (fip->filehdrflags & 0x01) ? true : false; @@ -407,41 +400,40 @@ static void checkseghdrflags(SEGINFO * sip) sip->endoffileflag = false; /* 7.3 Segment types */ switch (sip->seghdrflags & 0x3f) { - case M_SymbolDictionary: - case M_IntermediateTextRegion: - case M_ImmediateTextRegion: - case M_ImmediateLosslessTextRegion: - case M_PatternDictionary: - case M_IntermediateHalftoneRegion: - case M_ImmediateHalftoneRegion: - case M_ImmediateLosslessHalftoneRegion: - case M_IntermediateGenericRegion: - case M_ImmediateGenericRegion: - case M_ImmediateLosslessGenericRegion: - case M_IntermediateGenericRefinementRegion: - case M_ImmediateGenericRefinementRegion: - case M_ImmediateLosslessGenericRefinementRegion: - break; - case M_PageInformation: - sip->pageinfoflag = true; - break; - case M_EndOfPage: - sip->endofpageflag = true; - break; - case M_EndOfStripe: - sip->endofstripeflag = true; - break; - case M_EndOfFile: - sip->endoffileflag = true; - break; - case M_Profiles: - case M_Tables: - case M_Extension: - break; - default: - luatex_fail - ("checkseghdrflags(): unknown segment type in JBIG2 image file"); - break; + case M_SymbolDictionary: + case M_IntermediateTextRegion: + case M_ImmediateTextRegion: + case M_ImmediateLosslessTextRegion: + case M_PatternDictionary: + case M_IntermediateHalftoneRegion: + case M_ImmediateHalftoneRegion: + case M_ImmediateLosslessHalftoneRegion: + case M_IntermediateGenericRegion: + case M_ImmediateGenericRegion: + case M_ImmediateLosslessGenericRegion: + case M_IntermediateGenericRefinementRegion: + case M_ImmediateGenericRefinementRegion: + case M_ImmediateLosslessGenericRefinementRegion: + break; + case M_PageInformation: + sip->pageinfoflag = true; + break; + case M_EndOfPage: + sip->endofpageflag = true; + break; + case M_EndOfStripe: + sip->endofstripeflag = true; + break; + case M_EndOfFile: + sip->endoffileflag = true; + break; + case M_Profiles: + case M_Tables: + case M_Extension: + break; + default: + normal_error("readjbig2","unknown segment type file"); + break; } } @@ -454,19 +446,10 @@ static boolean readseghdr(FILEINFO * fip, SEGINFO * sip) sip->hdrstart = xftell(fip->file, fip->filepath); if (fip->sequentialaccess && sip->hdrstart == (unsigned) fip->filesize) return false; /* no endoffileflag is ok for sequentialaccess */ -#ifdef DEBUG - printf("\nhdrstart %d\n", sip->hdrstart); -#endif /* 7.2.2 Segment number */ sip->segnum = read4bytes(fip->file); -#ifdef DEBUG - printf(" segnum %d\n", sip->segnum); -#endif /* 7.2.3 Segment header flags */ sip->seghdrflags = (unsigned int) ygetc(fip->file); -#ifdef DEBUG - printf(" hdrflags %d\n", sip->seghdrflags & 0x3f); -#endif checkseghdrflags(sip); if (fip->sequentialaccess && sip->endoffileflag) /* accept shorter segment, */ return true; /* makes it compliant with Example 3.4 of PDFRef. 5th ed. */ @@ -489,15 +472,15 @@ static boolean readseghdr(FILEINFO * fip, SEGINFO * sip) sip->segnumwidth = 4; for (i = 0; i < sip->countofrefered; i++) { switch (sip->segnumwidth) { - case 1: - (void) ygetc(fip->file); - break; - case 2: - (void) read2bytes(fip->file); - break; - case 4: - (void) read4bytes(fip->file); - break; + case 1: + (void) ygetc(fip->file); + break; + case 2: + (void) read2bytes(fip->file); + break; + case 4: + (void) read4bytes(fip->file); + break; } } /* 7.2.6 Segment page association */ @@ -543,22 +526,22 @@ static void writeseghdr(PDF pdf, FILEINFO * fip, SEGINFO * sip) /* 7.2.5 Referred-to segment numbers */ for (i = 0; i < sip->countofrefered; i++) { switch (sip->segnumwidth) { - case 1: - referedseg = (unsigned long) ygetc(fip->file); - pdf_out(pdf, referedseg); - break; - case 2: - referedseg = read2bytes(fip->file); - pdf_out(pdf, (referedseg >> 8) & 0xff); - pdf_out(pdf, referedseg & 0xff); - break; - case 4: - referedseg = read4bytes(fip->file); - pdf_out(pdf, (referedseg >> 24) & 0xff); - pdf_out(pdf, (referedseg >> 16) & 0xff); - pdf_out(pdf, (referedseg >> 8) & 0xff); - pdf_out(pdf, referedseg & 0xff); - break; + case 1: + referedseg = (unsigned long) ygetc(fip->file); + pdf_out(pdf, referedseg); + break; + case 2: + referedseg = read2bytes(fip->file); + pdf_out(pdf, (referedseg >> 8) & 0xff); + pdf_out(pdf, referedseg & 0xff); + break; + case 4: + referedseg = read4bytes(fip->file); + pdf_out(pdf, (referedseg >> 24) & 0xff); + pdf_out(pdf, (referedseg >> 16) & 0xff); + pdf_out(pdf, (referedseg >> 8) & 0xff); + pdf_out(pdf, referedseg & 0xff); + break; } if (fip->page0.last != NULL && !sip->refers) markpage0seg(fip, referedseg); @@ -592,15 +575,15 @@ static void checkseghdr(FILEINFO * fip, SEGINFO * sip) /* 7.2.5 Referred-to segment numbers */ for (i = 0; i < sip->countofrefered; i++) { switch (sip->segnumwidth) { - case 1: - referedseg = (unsigned long) ygetc(fip->file); - break; - case 2: - referedseg = read2bytes(fip->file); - break; - case 4: - referedseg = read4bytes(fip->file); - break; + case 1: + referedseg = (unsigned long) ygetc(fip->file); + break; + case 2: + referedseg = read2bytes(fip->file); + break; + case 4: + referedseg = read4bytes(fip->file); + break; } if (!sip->refers) markpage0seg(fip, referedseg); @@ -620,8 +603,8 @@ static void checkseghdr(FILEINFO * fip, SEGINFO * sip) static unsigned long findstreamstart(FILEINFO * fip) { SEGINFO tmp; - assert(!fip->sequentialaccess); /* D.2 Random-access organisation */ - do /* find random-access stream start */ + assert(!fip->sequentialaccess); /* D.2 Random-access organisation */ + do /* find random-access stream start */ (void) readseghdr(fip, &tmp); while (!tmp.endoffileflag); fip->streamstart = tmp.hdrend; @@ -632,8 +615,8 @@ static unsigned long findstreamstart(FILEINFO * fip) @ @c static void rd_jbig2_info(FILEINFO * fip) { - unsigned long seekdist = 0; /* for sequential-access only */ - unsigned long streampos = 0; /* for random-access only */ + unsigned long seekdist = 0; /* for sequential-access only */ + unsigned long streampos = 0; /* for random-access only */ unsigned long currentpage = 0; boolean sipavail = false; PAGEINFO *pip; @@ -732,16 +715,14 @@ static void wr_jbig2(PDF pdf, image_dict * idict, FILEINFO * fip, pdf_dict_add_int(pdf, "Height", pip->height); pdf_dict_add_name(pdf, "ColorSpace", "DeviceGray"); pdf_dict_add_int(pdf, "BitsPerComponent", 1); - pdf_dict_add_int(pdf, "Length", - getstreamlen(pip->segments.first, true)); + pdf_dict_add_int(pdf, "Length", getstreamlen(pip->segments.first, true)); pdf_add_name(pdf, "Filter"); pdf_begin_array(pdf); pdf_add_name(pdf, "JBIG2Decode"); pdf_end_array(pdf); if (fip->page0.last != NULL) { if (fip->pdfpage0objnum == 0) { - fip->pdfpage0objnum = - (unsigned long) pdf_create_obj(pdf, obj_type_others, 0); + fip->pdfpage0objnum = (unsigned long) pdf_create_obj(pdf, obj_type_others, 0); } pdf_add_name(pdf, "DecodeParms"); pdf_begin_array(pdf); @@ -757,8 +738,7 @@ static void wr_jbig2(PDF pdf, image_dict * idict, FILEINFO * fip, assert(pip != NULL); pdf_begin_obj(pdf, (int) fip->pdfpage0objnum, OBJSTM_NEVER); pdf_begin_dict(pdf); - pdf_dict_add_int(pdf, "Length", - getstreamlen(pip->segments.first, false)); + pdf_dict_add_int(pdf, "Length", getstreamlen(pip->segments.first, false)); pdf_end_dict(pdf); } pdf_begin_stream(pdf); @@ -780,28 +760,43 @@ static void wr_jbig2(PDF pdf, image_dict * idict, FILEINFO * fip, } @ @c +boolean supported_jbig2(image_dict * idict) +{ + if (img_pdfminorversion(idict) < 4) { + normal_error("readjbig2","you need to generate at least PDF 1.4"); + return false; + } else { + return true; + } +} + +@ @c +void flush_jbig2_info(image_dict * idict) +{ + /* todo */ +} + +@ @c void read_jbig2_info(image_dict * idict) { FILEINFO *fip, tmp; PAGEINFO *pip; - void **aa; - assert(idict != NULL); - img_type(idict) = IMG_TYPE_JBIG2; - if (img_pagenum(idict) < 1) - luatex_fail - ("read_jbig2_info(): page %d not in JBIG2 image file; page must be > 0", - (int) img_pagenum(idict)); + img_type(idict) = IMG_TYPE_JBIG2; /* already set probably, see other read_... */ + if (! supported_jbig2(idict)) { + /* already an error done */ + } + if (img_pagenum(idict) < 1) { + normal_error("readjbig2","page must be > 0"); + } if (file_tree == NULL) { file_tree = avl_create(comp_file_entry, NULL, &avl_xallocator); - assert(file_tree != NULL); } tmp.filepath = img_filepath(idict); fip = (FILEINFO *) avl_find(file_tree, &tmp); if (fip == NULL) { fip = new_fileinfo(); fip->filepath = xstrdup(img_filepath(idict)); - aa = avl_probe(file_tree, fip); - assert(aa != NULL); + avl_probe(file_tree, fip); } if (fip->phase == INITIAL) { rd_jbig2_info(fip); @@ -813,9 +808,9 @@ void read_jbig2_info(image_dict * idict) } } pip = find_pageinfo(&(fip->pages), (unsigned long) img_pagenum(idict)); - if (pip == NULL) - luatex_fail("read_jbig2_info(): page %d not found in JBIG2 image file", - (int) img_pagenum(idict)); + if (pip == NULL) { + formatted_error("readjbig2","page %d not found in image file",(int) img_pagenum(idict)); + } img_totalpages(idict) = (int) fip->numofpages; img_xsize(idict) = (int) pip->width; img_ysize(idict) = (int) pip->height; diff --git a/Build/source/texk/web2c/luatexdir/image/writejp2.h b/Build/source/texk/web2c/luatexdir/image/writejp2.h index ed9bbe47c72..aa8248fd25a 100644 --- a/Build/source/texk/web2c/luatexdir/image/writejp2.h +++ b/Build/source/texk/web2c/luatexdir/image/writejp2.h @@ -18,13 +18,13 @@ You should have received a copy of the GNU General Public License along with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */ - #ifndef WRITEJP2_H # define WRITEJP2_H # include "image.h" -void read_jp2_info(image_dict *, img_readtype_e); +void read_jp2_info(image_dict *); +void flush_jp2_info(image_dict *); void write_jp2(PDF, image_dict *); #endif /* WRITEJP2_H */ diff --git a/Build/source/texk/web2c/luatexdir/image/writejp2.w b/Build/source/texk/web2c/luatexdir/image/writejp2.w index 8ea537e9f75..cb317e11928 100644 --- a/Build/source/texk/web2c/luatexdir/image/writejp2.w +++ b/Build/source/texk/web2c/luatexdir/image/writejp2.w @@ -20,7 +20,6 @@ @ @c - @ Basic JPEG~2000 image support. Section and Table references below: Information technology --- JPEG~2000 image coding system: Core coding system. ISO/IEC 15444-1, Second edition, 2004-09-15, file |15444-1annexi.pdf|. @@ -66,8 +65,9 @@ static hdr_struct read_boxhdr(image_dict * idict) hdr.tbox = read4bytes(img_file(idict)); if (hdr.lbox == 1) hdr.lbox = read8bytes(img_file(idict)); - if (hdr.lbox == 0 && hdr.tbox != BOX_JP2C) - luatex_fail("reading JP2 image failed (LBox == 0)"); + if (hdr.lbox == 0 && hdr.tbox != BOX_JP2C) { + normal_error("readjp2","LBox == 0"); + } return hdr; } @@ -90,6 +90,7 @@ static void scan_ihdr(image_dict * idict) /* 1.5.3.7.1 Capture Resolution box */ /* 1.5.3.7.2 Default Display Resolution box */ + static void scan_resc_resd(image_dict * idict) { unsigned int vr_n, vr_d, hr_n, hr_d; @@ -108,6 +109,7 @@ static void scan_resc_resd(image_dict * idict) } /* 1.5.3.7 Resolution box (superbox) */ + static void scan_res(image_dict * idict, uint64_t epos_s) { hdr_struct hdr; @@ -118,25 +120,23 @@ static void scan_res(image_dict * idict, uint64_t epos_s) hdr = read_boxhdr(idict); epos = spos + hdr.lbox; switch (hdr.tbox) { - case (BOX_RESC): - /* arbitrarily: let BOX_RESD have precedence */ - if (img_xres(idict) == 0 && img_yres(idict) == 0) { + case (BOX_RESC): + /* arbitrarily: let BOX_RESD have precedence */ + if (img_xres(idict) == 0 && img_yres(idict) == 0) { + scan_resc_resd(idict); + if (xftell(img_file(idict), img_filepath(idict)) != (long)epos) + normal_error("readjp2","resc box size inconsistent"); + } + break; + case (BOX_RESD): scan_resc_resd(idict); if (xftell(img_file(idict), img_filepath(idict)) != (long)epos) - luatex_fail - ("reading JP2 image failed (resc box size inconsistent)"); - } - break; - case (BOX_RESD): - scan_resc_resd(idict); - if (xftell(img_file(idict), img_filepath(idict)) != (long)epos) - luatex_fail - ("reading JP2 image failed (resd box size inconsistent)"); - break; - default:; + normal_error("readjp2","resd box size inconsistent"); + break; + default:; } if (epos > epos_s) - luatex_fail("reading JP2 image failed (res box size inconsistent)"); + normal_error("readjp2","res box size inconsistent"); if (epos == epos_s) break; xfseek(img_file(idict), (long) epos, SEEK_SET, img_filepath(idict)); @@ -144,6 +144,7 @@ static void scan_res(image_dict * idict, uint64_t epos_s) } /* 1.5.3 JP2 Header box (superbox) */ + static boolean scan_jp2h(image_dict * idict, uint64_t epos_s) { boolean ihdr_found = false; @@ -158,8 +159,7 @@ static boolean scan_jp2h(image_dict * idict, uint64_t epos_s) case (BOX_IHDR): scan_ihdr(idict); if (xftell(img_file(idict), img_filepath(idict)) != (long)epos) - luatex_fail - ("reading JP2 image failed (ihdr box size inconsistent)"); + normal_error("readjp2","ihdr box size inconsistent"); ihdr_found = true; break; case (BOX_RES): @@ -168,8 +168,7 @@ static boolean scan_jp2h(image_dict * idict, uint64_t epos_s) default:; } if (epos > epos_s) - luatex_fail - ("reading JP2 image failed (jp2h box size inconsistent)"); + normal_error("readjp2","jp2h box size inconsistent"); if (epos == epos_s) break; xfseek(img_file(idict), (long) epos, SEEK_SET, img_filepath(idict)); @@ -179,50 +178,56 @@ static boolean scan_jp2h(image_dict * idict, uint64_t epos_s) static void close_and_cleanup_jp2(image_dict * idict) { - assert(idict != NULL); - assert(img_file(idict) != NULL); - assert(img_filepath(idict) != NULL); - xfclose(img_file(idict), img_filepath(idict)); - img_file(idict) = NULL; - assert(img_jp2_ptr(idict) != NULL); - xfree(img_jp2_ptr(idict)); + /* if one of then is not NULL we already cleaned up */ + if (img_file(idict) != NULL) { + xfclose(img_file(idict), img_filepath(idict)); + img_file(idict) = NULL; + } + if (img_jp2_ptr(idict) != NULL) { + xfree(img_jp2_ptr(idict)); + } +} + +void flush_jp2_info(image_dict * idict) +{ + close_and_cleanup_jp2(idict); } -void read_jp2_info(image_dict * idict, img_readtype_e readtype) +void read_jp2_info(image_dict * idict) { boolean ihdr_found = false; hdr_struct hdr; uint64_t spos, epos; - assert(img_type(idict) == IMG_TYPE_JP2); + if (img_type(idict) != IMG_TYPE_JP2) { + normal_error("readjp2","conflicting image dictionary"); + } + if (img_file(idict) != NULL) { + normal_error("readjp2","image data already read"); + } img_totalpages(idict) = 1; img_pagenum(idict) = 1; img_xres(idict) = img_yres(idict) = 0; - assert(img_file(idict) == NULL); img_file(idict) = xfopen(img_filepath(idict), FOPEN_RBIN_MODE); - assert(img_jp2_ptr(idict) == NULL); img_jp2_ptr(idict) = xtalloc(1, jp2_img_struct); xfseek(img_file(idict), 0, SEEK_END, img_filepath(idict)); - img_jp2_ptr(idict)->length = - (int) xftell(img_file(idict), img_filepath(idict)); + img_jp2_ptr(idict)->length = (int) xftell(img_file(idict), img_filepath(idict)); xfseek(img_file(idict), 0, SEEK_SET, img_filepath(idict)); - - assert(sizeof(uint64_t) >= 8); + if (sizeof(uint64_t) < 8) { + normal_error("readjp2","size problem"); + } spos = epos = 0; - /* 1.5.1 JPEG 2000 Signature box */ hdr = read_boxhdr(idict); - assert(hdr.tbox == BOX_JP); /* has already been checked */ epos = spos + hdr.lbox; xfseek(img_file(idict), (long) epos, SEEK_SET, img_filepath(idict)); - /* 1.5.2 File Type box */ spos = epos; hdr = read_boxhdr(idict); - if (hdr.tbox != BOX_FTYP) - luatex_fail("reading JP2 image failed (missing ftyp box)"); + if (hdr.tbox != BOX_FTYP) { + normal_error("readjp2","missing ftyp box"); + } epos = spos + hdr.lbox; xfseek(img_file(idict), (long) epos, SEEK_SET, img_filepath(idict)); - while (!ihdr_found) { spos = epos; hdr = read_boxhdr(idict); @@ -233,14 +238,15 @@ void read_jp2_info(image_dict * idict, img_readtype_e readtype) break; case BOX_JP2C: if (!ihdr_found) - luatex_fail("reading JP2 image failed (no ihdr box found)"); + normal_error("readjp2","no ihdr box found"); break; default:; } xfseek(img_file(idict), (long) epos, SEEK_SET, img_filepath(idict)); } - if (readtype == IMG_CLOSEINBETWEEN) + if (! img_keepopen(idict)) { close_and_cleanup_jp2(idict); + } } static void reopen_jp2(image_dict * idict) @@ -250,19 +256,23 @@ static void reopen_jp2(image_dict * idict) height = img_ysize(idict); xres = img_xres(idict); yres = img_yres(idict); - read_jp2_info(idict, IMG_KEEPOPEN); + /* + we need to make sure that the file kept open + */ + img_keepopen(idict) = 1; + read_jp2_info(idict); if (width != img_xsize(idict) || height != img_ysize(idict) - || xres != img_xres(idict) || yres != img_yres(idict)) - luatex_fail("writejp2: image dimensions have changed"); + || xres != img_xres(idict) || yres != img_yres(idict)) { + normal_error("writejp2","image dimensions have changed"); + } } void write_jp2(PDF pdf, image_dict * idict) { long unsigned l; - assert(idict != NULL); - if (img_file(idict) == NULL) + if (img_file(idict) == NULL) { reopen_jp2(idict); - assert(img_jp2_ptr(idict) != NULL); + } pdf_begin_obj(pdf, img_objnum(idict), OBJSTM_NEVER); pdf_begin_dict(pdf); pdf_dict_add_name(pdf, "Type", "XObject"); @@ -279,8 +289,9 @@ void write_jp2(PDF pdf, image_dict * idict) l = (long unsigned int) img_jp2_ptr(idict)->length; xfseek(img_file(idict), 0, SEEK_SET, img_filepath(idict)); if (read_file_to_buf(pdf, img_file(idict), l) != l) - luatex_fail("writejp2: fread failed"); + normal_error("writejp2","fread failed"); pdf_end_stream(pdf); pdf_end_obj(pdf); + /* always */ close_and_cleanup_jp2(idict); } diff --git a/Build/source/texk/web2c/luatexdir/image/writejpg.h b/Build/source/texk/web2c/luatexdir/image/writejpg.h index 8ef290d4746..96bf961246f 100644 --- a/Build/source/texk/web2c/luatexdir/image/writejpg.h +++ b/Build/source/texk/web2c/luatexdir/image/writejpg.h @@ -18,13 +18,13 @@ You should have received a copy of the GNU General Public License along with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */ - #ifndef WRITEJPG_H # define WRITEJPG_H # include "image.h" -void read_jpg_info(PDF, image_dict *, img_readtype_e); +void read_jpg_info(image_dict *); +void flush_jpg_info(image_dict *); void write_jpg(PDF, image_dict *); -#endif /* WRITEJPG_H */ +#endif diff --git a/Build/source/texk/web2c/luatexdir/image/writejpg.w b/Build/source/texk/web2c/luatexdir/image/writejpg.w index 7780f312922..07c51f5e1d0 100644 --- a/Build/source/texk/web2c/luatexdir/image/writejpg.w +++ b/Build/source/texk/web2c/luatexdir/image/writejpg.w @@ -20,87 +20,85 @@ @ @c - #include "ptexlib.h" #include <assert.h> #include "image/image.h" #include "image/writejpg.h" @ @c -#define JPG_GRAY 1 /* Gray color space, use /DeviceGray */ -#define JPG_RGB 3 /* RGB color space, use /DeviceRGB */ -#define JPG_CMYK 4 /* CMYK color space, use /DeviceCMYK */ +#define JPG_GRAY 1 /* Gray color space, use /DeviceGray */ +#define JPG_RGB 3 /* RGB color space, use /DeviceRGB */ +#define JPG_CMYK 4 /* CMYK color space, use /DeviceCMYK */ -typedef enum { /* JPEG marker codes */ - M_SOF0 = 0xc0, /* baseline DCT */ - M_SOF1 = 0xc1, /* extended sequential DCT */ - M_SOF2 = 0xc2, /* progressive DCT */ - M_SOF3 = 0xc3, /* lossless (sequential) */ +typedef enum { + M_SOF0 = 0xc0, /* baseline DCT */ + M_SOF1 = 0xc1, /* extended sequential DCT */ + M_SOF2 = 0xc2, /* progressive DCT */ + M_SOF3 = 0xc3, /* lossless (sequential) */ - M_SOF5 = 0xc5, /* differential sequential DCT */ - M_SOF6 = 0xc6, /* differential progressive DCT */ - M_SOF7 = 0xc7, /* differential lossless (sequential) */ + M_SOF5 = 0xc5, /* differential sequential DCT */ + M_SOF6 = 0xc6, /* differential progressive DCT */ + M_SOF7 = 0xc7, /* differential lossless (sequential) */ - M_JPG = 0xc8, /* reserved for JPEG extensions */ - M_SOF9 = 0xc9, /* extended sequential DCT */ - M_SOF10 = 0xca, /* progressive DCT */ - M_SOF11 = 0xcb, /* lossless (sequential) */ + M_JPG = 0xc8, /* reserved for JPEG extensions */ + M_SOF9 = 0xc9, /* extended sequential DCT */ + M_SOF10 = 0xca, /* progressive DCT */ + M_SOF11 = 0xcb, /* lossless (sequential) */ - M_SOF13 = 0xcd, /* differential sequential DCT */ - M_SOF14 = 0xce, /* differential progressive DCT */ - M_SOF15 = 0xcf, /* differential lossless (sequential) */ + M_SOF13 = 0xcd, /* differential sequential DCT */ + M_SOF14 = 0xce, /* differential progressive DCT */ + M_SOF15 = 0xcf, /* differential lossless (sequential) */ - M_DHT = 0xc4, /* define Huffman table(s) */ + M_DHT = 0xc4, /* define Huffman table(s) */ - M_DAC = 0xcc, /* define arithmetic conditioning table */ + M_DAC = 0xcc, /* define arithmetic conditioning table */ - M_RST0 = 0xd0, /* restart */ - M_RST1 = 0xd1, /* restart */ - M_RST2 = 0xd2, /* restart */ - M_RST3 = 0xd3, /* restart */ - M_RST4 = 0xd4, /* restart */ - M_RST5 = 0xd5, /* restart */ - M_RST6 = 0xd6, /* restart */ - M_RST7 = 0xd7, /* restart */ + M_RST0 = 0xd0, /* restart */ + M_RST1 = 0xd1, /* restart */ + M_RST2 = 0xd2, /* restart */ + M_RST3 = 0xd3, /* restart */ + M_RST4 = 0xd4, /* restart */ + M_RST5 = 0xd5, /* restart */ + M_RST6 = 0xd6, /* restart */ + M_RST7 = 0xd7, /* restart */ - M_SOI = 0xd8, /* start of image */ - M_EOI = 0xd9, /* end of image */ - M_SOS = 0xda, /* start of scan */ - M_DQT = 0xdb, /* define quantization tables */ - M_DNL = 0xdc, /* define number of lines */ - M_DRI = 0xdd, /* define restart interval */ - M_DHP = 0xde, /* define hierarchical progression */ - M_EXP = 0xdf, /* expand reference image(s) */ + M_SOI = 0xd8, /* start of image */ + M_EOI = 0xd9, /* end of image */ + M_SOS = 0xda, /* start of scan */ + M_DQT = 0xdb, /* define quantization tables */ + M_DNL = 0xdc, /* define number of lines */ + M_DRI = 0xdd, /* define restart interval */ + M_DHP = 0xde, /* define hierarchical progression */ + M_EXP = 0xdf, /* expand reference image(s) */ - M_APP0 = 0xe0, /* application marker, used for JFIF */ - M_APP1 = 0xe1, /* application marker */ - M_APP2 = 0xe2, /* application marker */ - M_APP3 = 0xe3, /* application marker */ - M_APP4 = 0xe4, /* application marker */ - M_APP5 = 0xe5, /* application marker */ - M_APP6 = 0xe6, /* application marker */ - M_APP7 = 0xe7, /* application marker */ - M_APP8 = 0xe8, /* application marker */ - M_APP9 = 0xe9, /* application marker */ - M_APP10 = 0xea, /* application marker */ - M_APP11 = 0xeb, /* application marker */ - M_APP12 = 0xec, /* application marker */ - M_APP13 = 0xed, /* application marker */ - M_APP14 = 0xee, /* application marker, used by Adobe */ - M_APP15 = 0xef, /* application marker */ + M_APP0 = 0xe0, /* application marker, used for JFIF */ + M_APP1 = 0xe1, /* application marker */ + M_APP2 = 0xe2, /* application marker */ + M_APP3 = 0xe3, /* application marker */ + M_APP4 = 0xe4, /* application marker */ + M_APP5 = 0xe5, /* application marker */ + M_APP6 = 0xe6, /* application marker */ + M_APP7 = 0xe7, /* application marker */ + M_APP8 = 0xe8, /* application marker */ + M_APP9 = 0xe9, /* application marker */ + M_APP10 = 0xea, /* application marker */ + M_APP11 = 0xeb, /* application marker */ + M_APP12 = 0xec, /* application marker */ + M_APP13 = 0xed, /* application marker */ + M_APP14 = 0xee, /* application marker, used by Adobe */ + M_APP15 = 0xef, /* application marker */ - M_JPG0 = 0xf0, /* reserved for JPEG extensions */ - M_JPG13 = 0xfd, /* reserved for JPEG extensions */ - M_COM = 0xfe, /* comment */ + M_JPG0 = 0xf0, /* reserved for JPEG extensions */ + M_JPG13 = 0xfd, /* reserved for JPEG extensions */ + M_COM = 0xfe, /* comment */ - M_TEM = 0x01, /* temporary use */ + M_TEM = 0x01, /* temporary use */ - M_ERROR = 0x100 /* dummy marker, internal use only */ + M_ERROR = 0x100 /* dummy marker, internal use only */ } JPEG_MARKER; @ @c -static unsigned char -myget_unsigned_byte (FILE *file) +static unsigned char myget_unsigned_byte (FILE *file) { int ch; ch = fgetc (file); @@ -108,8 +106,7 @@ myget_unsigned_byte (FILE *file) } @ @c -static unsigned short -myget_unsigned_pair (FILE *file) +static unsigned short myget_unsigned_pair (FILE *file) { unsigned short pair = myget_unsigned_byte(file); pair = (pair << 8) | myget_unsigned_byte(file); @@ -117,31 +114,30 @@ myget_unsigned_pair (FILE *file) } @ @c -static unsigned int -read_exif_bytes(unsigned char **p, int n, int b) +static unsigned int read_exif_bytes(unsigned char **p, int n, int b) { unsigned int rval = 0; unsigned char *pp = *p; if (b) { switch (n) { - case 4: - rval += *pp++; rval <<= 8; - rval += *pp++; rval <<= 8; - case 2: - rval += *pp++; rval <<= 8; - rval += *pp; - break; + case 4: + rval += *pp++; rval <<= 8; + rval += *pp++; rval <<= 8; + case 2: + rval += *pp++; rval <<= 8; + rval += *pp; + break; } } else { pp += n; switch (n) { - case 4: - rval += *--pp; rval <<= 8; - rval += *--pp; rval <<= 8; - case 2: - rval += *--pp; rval <<= 8; - rval += *--pp; - break; + case 4: + rval += *--pp; rval <<= 8; + rval += *--pp; rval <<= 8; + case 2: + rval += *--pp; rval <<= 8; + rval += *--pp; + break; } } *p += n; @@ -149,8 +145,7 @@ read_exif_bytes(unsigned char **p, int n, int b) } @ @c -static void -read_APP1_Exif (FILE *fp, unsigned short length, int *xx, int *yy) +static void read_APP1_Exif (FILE *fp, unsigned short length, int *xx, int *yy) { /* this doesn't save the data, just reads the tags we need */ /* based on info from http://www.exif.org/Exif2-2.PDF */ @@ -160,7 +155,7 @@ read_APP1_Exif (FILE *fp, unsigned short length, int *xx, int *yy) char bigendian; int i; int num_fields, tag, type; - int value = 0, num = 0, den = 0; /* silence uninitialized warnings */ + int value = 0, num = 0, den = 0; /* silence uninitialized warnings */ double xres = 72.0; double yres = 72.0; double res_unit = 1.0; @@ -190,133 +185,156 @@ read_APP1_Exif (FILE *fp, unsigned short length, int *xx, int *yy) type = read_exif_bytes(&p, 2, bigendian); read_exif_bytes(&p, 4, bigendian); switch (type) { - case 1: /* byte */ - value = *p++; - p += 3; - break; - case 3: /* short */ - value = read_exif_bytes(&p, 2, bigendian); - p += 2; - break; - case 4: /* long */ - case 9: /* slong */ - value = read_exif_bytes(&p, 4, bigendian); - break; - case 5: /* rational */ - case 10: /* srational */ - value = read_exif_bytes(&p, 4, bigendian); - rp = tiff_header + value; - num = read_exif_bytes(&rp, 4, bigendian); - den = read_exif_bytes(&rp, 4, bigendian); - break; - case 7: /* undefined */ - value = *p++; - p += 3; - break; - case 2: /* ascii */ - default: - p += 4; - break; - } + case 1: /* byte */ + value = *p++; + p += 3; + break; + case 3: /* short */ + value = read_exif_bytes(&p, 2, bigendian); + p += 2; + break; + case 4: /* long */ + case 9: /* slong */ + value = read_exif_bytes(&p, 4, bigendian); + break; + case 5: /* rational */ + case 10: /* srational */ + value = read_exif_bytes(&p, 4, bigendian); + rp = tiff_header + value; + num = read_exif_bytes(&rp, 4, bigendian); + den = read_exif_bytes(&rp, 4, bigendian); + break; + case 7: /* undefined */ + value = *p++; + p += 3; + break; + case 2: /* ascii */ + default: + p += 4; + break; + } switch (tag) { - case 282: /* x res */ - if (den != 0) - xres = num / den; - break; - case 283: /* y res */ - if (den != 0) - yres = num / den; - break; - case 296: /* res unit */ - switch (value) { - case 2: - res_unit = 1.0; + case 282: /* x res */ + if (den != 0) + xres = num / den; break; - case 3: - res_unit = 2.54; + case 283: /* y res */ + if (den != 0) + yres = num / den; break; - } + case 296: /* res unit */ + switch (value) { + case 2: + res_unit = 1.0; + break; + case 3: + res_unit = 2.54; + break; + } } } *xx = (int)(xres * res_unit); *yy = (int)(yres * res_unit); - err: free(buffer); return; } +/* + + Contrary to pdf where several parallel usage can happen (epdf, tex, lua) with + bitmaps we care less about keeping files open. So, we can keep files open in + the img lib but then they are closed after inclusion anyway. + +*/ + @ @c static void close_and_cleanup_jpg(image_dict * idict) { - assert(idict != NULL); - assert(img_file(idict) != NULL); - assert(img_filepath(idict) != NULL); - xfclose(img_file(idict), img_filepath(idict)); - img_file(idict) = NULL; - assert(img_jpg_ptr(idict) != NULL); - xfree(img_jpg_ptr(idict)); + /* if one of then is not NULL we already cleaned up */ + if (img_file(idict) != NULL) { + xfclose(img_file(idict), img_filepath(idict)); + img_file(idict) = NULL; + } + if (img_jpg_ptr(idict) != NULL) { + xfree(img_jpg_ptr(idict)); + } +} + +@ @c +void flush_jpg_info(image_dict * idict) +{ + close_and_cleanup_jpg(idict); } @ @c -void read_jpg_info(PDF pdf, image_dict * idict, img_readtype_e readtype) +void read_jpg_info(image_dict * idict) { int i, units = 0; unsigned short appmk, length; unsigned char jpg_id[] = "JFIF"; - assert(idict != NULL); - assert(img_type(idict) == IMG_TYPE_JPG); + if (img_type(idict) != IMG_TYPE_JPG) { + normal_error("readjpg","conflicting image dictionary"); + } + if (img_file(idict) != NULL) { + normal_error("readjpg","image data already read"); + } img_totalpages(idict) = 1; img_pagenum(idict) = 1; img_xres(idict) = img_yres(idict) = 0; - assert(img_file(idict) == NULL); img_file(idict) = xfopen(img_filepath(idict), FOPEN_RBIN_MODE); - assert(img_jpg_ptr(idict) == NULL); + if (img_file(idict) == NULL) { + normal_error("readjpg","unable to read image file"); + } img_jpg_ptr(idict) = xtalloc(1, jpg_img_struct); xfseek(img_file(idict), 0, SEEK_END, img_filepath(idict)); img_jpg_ptr(idict)->length = xftell(img_file(idict), img_filepath(idict)); xfseek(img_file(idict), 0, SEEK_SET, img_filepath(idict)); - if ((unsigned int) read2bytes(img_file(idict)) != 0xFFD8) - luatex_fail("reading JPEG image failed (no JPEG header found)"); + if ((unsigned int) read2bytes(img_file(idict)) != 0xFFD8) { + normal_error("readjpg","no header found"); + } /* currently JFIF and Exif files allow extracting |img_xres| and |img_yres| */ appmk = read2bytes(img_file(idict)); - if (appmk == 0xFFE0) { /* check for JFIF */ + if (appmk == 0xFFE0) { + /* check for JFIF */ (void) read2bytes(img_file(idict)); for (i = 0; i < 5; i++) { if (xgetc(img_file(idict)) != jpg_id[i]) break; } - if (i == 5) { /* it's JFIF */ + if (i == 5) { + /* it's JFIF */ (void) read2bytes(img_file(idict)); units = xgetc(img_file(idict)); img_xres(idict) = (int) read2bytes(img_file(idict)); img_yres(idict) = (int) read2bytes(img_file(idict)); switch (units) { case 1: + /* pixels per inch */ if ((img_xres(idict) == 1) || (img_yres(idict) == 1)) { - luatex_warn("The image specifies an unusual resolution of %ddpi by %ddpi. ", - img_xres(idict), img_yres(idict)); + formatted_warning("readjpg","unusual resolution of %ddpi by %ddpi", img_xres(idict), img_yres(idict)); } - break; /* pixels per inch */ + break; case 2: + /* pixels per cm */ img_xres(idict) = (int) ((double) img_xres(idict) * 2.54); img_yres(idict) = (int) ((double) img_yres(idict) * 2.54); - break; /* pixels per cm */ + break; default: img_xres(idict) = img_yres(idict) = 0; break; } } - /* if either xres or yres is 0 but the other isn't, - set it to the value of the other */ + /* if either xres or yres is 0 but the other isn't, set it to the value of the other */ if ((img_xres(idict) == 0) && (img_yres(idict) != 0)) { img_xres(idict) = img_yres(idict); } if ((img_yres(idict) == 0) && (img_xres(idict) != 0)) { img_yres(idict) = img_xres(idict); } - } else if (appmk == 0xFFE1) { /* check for Exif */ + } else if (appmk == 0xFFE1) { + /* check for Exif */ FILE *fp = img_file(idict); int xxres = 0; int yyres = 0; @@ -335,102 +353,111 @@ void read_jpg_info(PDF pdf, image_dict * idict, img_readtype_e readtype) } xfseek(img_file(idict), 0, SEEK_SET, img_filepath(idict)); while (1) { - if (feof(img_file(idict))) - luatex_fail("reading JPEG image failed (premature file end)"); - if (fgetc(img_file(idict)) != 0xFF) - luatex_fail("reading JPEG image failed (no marker found)"); + if (feof(img_file(idict))) { + normal_error("readjpg","premature file end"); + } else if (fgetc(img_file(idict)) != 0xFF) { + normal_error("readjpg","no marker found"); + } i = xgetc(img_file(idict)); switch (i) { - case M_SOF3: /* lossless */ - case M_SOF5: - case M_SOF6: - case M_SOF7: /* lossless */ - case M_SOF9: - case M_SOF10: - case M_SOF11: /* lossless */ - case M_SOF13: - case M_SOF14: - case M_SOF15: /* lossless */ - luatex_fail("unsupported type of compression (SOF_%d)", i - M_SOF0); - break; - case M_SOF2: - if (pdf->minor_version <= 2) - luatex_fail("cannot use progressive DCT with PDF-1.2"); - case M_SOF0: - case M_SOF1: - (void) read2bytes(img_file(idict)); /* read segment length */ - img_colordepth(idict) = xgetc(img_file(idict)); - img_ysize(idict) = (int) read2bytes(img_file(idict)); - img_xsize(idict) = (int) read2bytes(img_file(idict)); - img_jpg_color(idict) = xgetc(img_file(idict)); - xfseek(img_file(idict), 0, SEEK_SET, img_filepath(idict)); - switch (img_jpg_color(idict)) { - case JPG_GRAY: - img_procset(idict) |= PROCSET_IMAGE_B; + case M_SOF3: /* lossless */ + case M_SOF5: + case M_SOF6: + case M_SOF7: /* lossless */ + case M_SOF9: + case M_SOF10: + case M_SOF11: /* lossless */ + case M_SOF13: + case M_SOF14: + case M_SOF15: /* lossless */ + formatted_error("readjpg","unsupported compression SOF_%d", i - M_SOF0); break; - case JPG_RGB: - img_procset(idict) |= PROCSET_IMAGE_C; - break; - case JPG_CMYK: - img_procset(idict) |= PROCSET_IMAGE_C; + case M_SOF2: + if (img_pdfminorversion(idict) <= 2) { + normal_error("readjpg","progressive DCT with PDF-1.2 is not permitted"); + } + case M_SOF0: + case M_SOF1: + (void) read2bytes(img_file(idict)); /* read segment length */ + img_colordepth(idict) = xgetc(img_file(idict)); + img_ysize(idict) = (int) read2bytes(img_file(idict)); + img_xsize(idict) = (int) read2bytes(img_file(idict)); + img_jpg_color(idict) = xgetc(img_file(idict)); + xfseek(img_file(idict), 0, SEEK_SET, img_filepath(idict)); + switch (img_jpg_color(idict)) { + case JPG_GRAY: + img_procset(idict) |= PROCSET_IMAGE_B; + break; + case JPG_RGB: + img_procset(idict) |= PROCSET_IMAGE_C; + break; + case JPG_CMYK: + img_procset(idict) |= PROCSET_IMAGE_C; + break; + default: + formatted_error("readjpg","unsupported color space %i", (int) img_jpg_color(idict)); + } + /* + So we can optionally keep open a file in img. + */ + if (! img_keepopen(idict)) { + close_and_cleanup_jpg(idict); + } + return; + /* ignore markers without parameters */ + case M_SOI: + case M_EOI: + case M_TEM: + case M_RST0: + case M_RST1: + case M_RST2: + case M_RST3: + case M_RST4: + case M_RST5: + case M_RST6: + case M_RST7: break; default: - luatex_fail("Unsupported color space %i", - (int) img_jpg_color(idict)); - } - if (readtype == IMG_CLOSEINBETWEEN) - close_and_cleanup_jpg(idict); - return; - case M_SOI: /* ignore markers without parameters */ - case M_EOI: - case M_TEM: - case M_RST0: - case M_RST1: - case M_RST2: - case M_RST3: - case M_RST4: - case M_RST5: - case M_RST6: - case M_RST7: - break; - default: /* skip variable length markers */ - xfseek(img_file(idict), (int) read2bytes(img_file(idict)) - 2, - SEEK_CUR, img_filepath(idict)); - break; + /* skip variable length markers */ + xfseek(img_file(idict), (int) read2bytes(img_file(idict)) - 2, SEEK_CUR, img_filepath(idict)); + break; } } - assert(0); + normal_error("readjpg","unknown fatal error"); } @ @c -static void reopen_jpg(PDF pdf, image_dict * idict) +static void reopen_jpg(image_dict * idict) { - int width, height, xres, yres; - width = img_xsize(idict); - height = img_ysize(idict); - xres = img_xres(idict); - yres = img_yres(idict); - read_jpg_info(pdf, idict, IMG_KEEPOPEN); - if (width != img_xsize(idict) || height != img_ysize(idict) - || xres != img_xres(idict) || yres != img_yres(idict)) - luatex_fail("writejpg: image dimensions have changed"); + int width = img_xsize(idict); + int height = img_ysize(idict); + int xres = img_xres(idict); + int yres = img_yres(idict); + /* + we need to make sure that the file kept open + */ + img_keepopen(idict) = 1; + read_jpg_info(idict); + if (width != img_xsize(idict) || height != img_ysize(idict) || xres != img_xres(idict) || yres != img_yres(idict)) { + normal_error("writejpg","image dimensions have changed"); + } } @ @c void write_jpg(PDF pdf, image_dict * idict) { size_t l; - assert(idict != NULL); - if (img_file(idict) == NULL) - reopen_jpg(pdf, idict); - assert(img_jpg_ptr(idict) != NULL); + if (img_file(idict) == NULL) { + reopen_jpg(idict); + } pdf_begin_obj(pdf, img_objnum(idict), OBJSTM_NEVER); pdf_begin_dict(pdf); pdf_dict_add_name(pdf, "Type", "XObject"); pdf_dict_add_name(pdf, "Subtype", "Image"); pdf_dict_add_img_filename(pdf, idict); - if (img_attr(idict) != NULL && strlen(img_attr(idict)) > 0) + if (img_attr(idict) != NULL && strlen(img_attr(idict)) > 0) { pdf_printf(pdf, "\n%s\n", img_attr(idict)); + } pdf_dict_add_int(pdf, "Width", (int) img_xsize(idict)); pdf_dict_add_int(pdf, "Height", (int) img_ysize(idict)); pdf_dict_add_int(pdf, "BitsPerComponent", (int) img_colordepth(idict)); @@ -439,40 +466,40 @@ void write_jpg(PDF pdf, image_dict * idict) pdf_dict_add_ref(pdf, "ColorSpace", (int) img_colorspace(idict)); } else { switch (img_jpg_color(idict)) { - case JPG_GRAY: - pdf_dict_add_name(pdf, "ColorSpace", "DeviceGray"); - break; - case JPG_RGB: - pdf_dict_add_name(pdf, "ColorSpace", "DeviceRGB"); - break; - case JPG_CMYK: - pdf_dict_add_name(pdf, "ColorSpace", "DeviceCMYK"); - pdf_add_name(pdf, "Decode"); - pdf_begin_array(pdf); - pdf_add_int(pdf, 1); - pdf_add_int(pdf, 0); - pdf_add_int(pdf, 1); - pdf_add_int(pdf, 0); - pdf_add_int(pdf, 1); - pdf_add_int(pdf, 0); - pdf_add_int(pdf, 1); - pdf_add_int(pdf, 0); - pdf_end_array(pdf); - break; - default: - luatex_fail("Unsupported color space %i", - (int) img_jpg_color(idict)); + case JPG_GRAY: + pdf_dict_add_name(pdf, "ColorSpace", "DeviceGray"); + break; + case JPG_RGB: + pdf_dict_add_name(pdf, "ColorSpace", "DeviceRGB"); + break; + case JPG_CMYK: + pdf_dict_add_name(pdf, "ColorSpace", "DeviceCMYK"); + pdf_add_name(pdf, "Decode"); + pdf_begin_array(pdf); + pdf_add_int(pdf, 1); + pdf_add_int(pdf, 0); + pdf_add_int(pdf, 1); + pdf_add_int(pdf, 0); + pdf_add_int(pdf, 1); + pdf_add_int(pdf, 0); + pdf_add_int(pdf, 1); + pdf_add_int(pdf, 0); + pdf_end_array(pdf); + break; + default: + formatted_error("writejpg","unsupported JPEG color space %i", (int) img_jpg_color(idict)); } } pdf_dict_add_name(pdf, "Filter", "DCTDecode"); pdf_end_dict(pdf); pdf_begin_stream(pdf); - assert(pdf->zip_write_state == NO_ZIP); l = (size_t) img_jpg_ptr(idict)->length; xfseek(img_file(idict), 0, SEEK_SET, img_filepath(idict)); - if (read_file_to_buf(pdf, img_file(idict), l) != l) - luatex_fail("writejpg: fread failed"); + if (read_file_to_buf(pdf, img_file(idict), l) != l) { + normal_error("writejpg","fread failed"); + } pdf_end_stream(pdf); pdf_end_obj(pdf); + /* always */ close_and_cleanup_jpg(idict); } diff --git a/Build/source/texk/web2c/luatexdir/image/writepng.h b/Build/source/texk/web2c/luatexdir/image/writepng.h index 4dd425c0405..2af2a3fa2fb 100644 --- a/Build/source/texk/web2c/luatexdir/image/writepng.h +++ b/Build/source/texk/web2c/luatexdir/image/writepng.h @@ -18,14 +18,15 @@ You should have received a copy of the GNU General Public License along with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */ - #ifndef WRITEPNG_H # define WRITEPNG_H # include "image.h" -void read_png_info(image_dict *, img_readtype_e); +void read_png_info(image_dict *); +void flush_png_info(image_dict *); + void write_additional_png_objects(PDF); void write_png(PDF, image_dict *); -#endif /* WRITEPNG_H */ +#endif diff --git a/Build/source/texk/web2c/luatexdir/image/writepng.w b/Build/source/texk/web2c/luatexdir/image/writepng.w index 40f8e0e2635..412000c427f 100644 --- a/Build/source/texk/web2c/luatexdir/image/writepng.w +++ b/Build/source/texk/web2c/luatexdir/image/writepng.w @@ -20,7 +20,6 @@ @ @c - #include "ptexlib.h" #include <assert.h> #include "image/image.h" @@ -31,45 +30,55 @@ static int transparent_page_group = -1; static void close_and_cleanup_png(image_dict * idict) { - assert(idict != NULL); - assert(img_file(idict) != NULL); - assert(img_filepath(idict) != NULL); - xfclose(img_file(idict), img_filepath(idict)); - img_file(idict) = NULL; - assert(img_png_ptr(idict) != NULL); - png_destroy_read_struct(&(img_png_png_ptr(idict)), - &(img_png_info_ptr(idict)), NULL); - xfree(img_png_ptr(idict)); + /* if one of then is not NULL we already cleaned up */ + if (img_file(idict) != NULL) { + xfclose(img_file(idict), img_filepath(idict)); + img_file(idict) = NULL; + } + if (img_png_ptr(idict) != NULL) { + png_destroy_read_struct(&(img_png_png_ptr(idict)), &(img_png_info_ptr(idict)), NULL); + xfree(img_png_ptr(idict)); + } +} + +@ @c +void flush_png_info(image_dict * idict) +{ + close_and_cleanup_png(idict); } @ @c static void warn(png_structp png_ptr, png_const_charp msg) { - (void)png_ptr; (void)msg; /* Make compiler happy */ + (void)png_ptr; (void)msg; /* Make compiler happy */ } -void read_png_info(image_dict * idict, img_readtype_e readtype) +void read_png_info(image_dict * idict) { png_structp png_p; png_infop info_p; - assert(idict != NULL); - assert(img_type(idict) == IMG_TYPE_PNG); + if (img_type(idict) != IMG_TYPE_PNG) { + normal_error("readpng","conflicting image dictionary"); + } + if (img_file(idict) != NULL) { + normal_error("readpng","image data already read"); + } img_totalpages(idict) = 1; img_pagenum(idict) = 1; img_xres(idict) = img_yres(idict) = 0; - assert(img_file(idict) == NULL); img_file(idict) = xfopen(img_filepath(idict), FOPEN_RBIN_MODE); - assert(img_png_ptr(idict) == NULL); img_png_ptr(idict) = xtalloc(1, png_img_struct); - if ((png_p = png_create_read_struct(PNG_LIBPNG_VER_STRING, - NULL, NULL, warn)) == NULL) - luatex_fail("libpng: png_create_read_struct() failed"); + if ((png_p = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, warn)) == NULL) { + normal_error("readpng","png_create_read_struct() failed"); + } img_png_png_ptr(idict) = png_p; - if ((info_p = png_create_info_struct(png_p)) == NULL) - luatex_fail("libpng: png_create_info_struct() failed"); + if ((info_p = png_create_info_struct(png_p)) == NULL) { + normal_error("readpng","png_create_info_struct() failed"); + } img_png_info_ptr(idict) = info_p; - if (setjmp(png_jmpbuf(png_p))) - luatex_fail("libpng: internal error"); + if (setjmp(png_jmpbuf(png_p))) { + normal_error("readpng","internal error"); + } #if PNG_LIBPNG_VER >= 10603 /* ignore possibly incorrect CMF bytes */ png_set_option(png_p, PNG_MAXIMUM_INFLATE_WINDOW, PNG_OPTION_ON); @@ -80,10 +89,8 @@ void read_png_info(image_dict * idict, img_readtype_e readtype) img_xsize(idict) = (int) png_get_image_width(png_p, info_p); img_ysize(idict) = (int) png_get_image_height(png_p, info_p); if (png_get_valid(png_p, info_p, PNG_INFO_pHYs)) { - img_xres(idict) = - round(0.0254 * (double) png_get_x_pixels_per_meter(png_p, info_p)); - img_yres(idict) = - round(0.0254 * (double) png_get_y_pixels_per_meter(png_p, info_p)); + img_xres(idict) = round(0.0254 * (double) png_get_x_pixels_per_meter(png_p, info_p)); + img_yres(idict) = round(0.0254 * (double) png_get_y_pixels_per_meter(png_p, info_p)); } switch (png_get_color_type(png_p, info_p)) { case PNG_COLOR_TYPE_PALETTE: @@ -98,12 +105,15 @@ void read_png_info(image_dict * idict, img_readtype_e readtype) img_procset(idict) |= PROCSET_IMAGE_C; break; default: - luatex_fail("unsupported type of color_type <%i>", - (int) png_get_color_type(png_p, info_p)); + formatted_error("readpng","unsupported type of color_type '%i'",(int) png_get_color_type(png_p, info_p)); } img_colordepth(idict) = png_get_bit_depth(png_p, info_p); - if (readtype == IMG_CLOSEINBETWEEN) + /* + So we can optionally keep open a file in img. + */ + if (! img_keepopen(idict)) { close_and_cleanup_png(idict); + } } @ @c @@ -164,8 +174,7 @@ void read_png_info(image_dict * idict, img_readtype_e readtype) } @ @c -static void write_palette_streamobj(PDF pdf, int palette_objnum, - png_colorp palette, int num_palette) +static void write_palette_streamobj(PDF pdf, int palette_objnum, png_colorp palette, int num_palette) { int i; if (palette_objnum == 0) @@ -187,8 +196,7 @@ static void write_palette_streamobj(PDF pdf, int palette_objnum, } @ @c -static void write_smask_streamobj(PDF pdf, image_dict * idict, int smask_objnum, - png_bytep smask, int smask_size) +static void write_smask_streamobj(PDF pdf, image_dict * idict, int smask_objnum, png_bytep smask, int smask_size) { int i; png_structp png_p = img_png_png_ptr(idict); @@ -235,13 +243,13 @@ static void write_png_gray(PDF pdf, image_dict * idict) write_noninterlaced(write_simple_pixel(r)); xfree(row); } else { - if (png_get_image_height(png_p, info_p) * - png_get_rowbytes(png_p, info_p) >= 10240000L) - luatex_warn - ("large interlaced PNG might cause out of memory (use non-interlaced PNG to fix this)"); + if (png_get_image_height(png_p, info_p) * png_get_rowbytes(png_p, info_p) >= 10240000L) { + formatted_warning("pngwrite","large interlaced bitmap might cause out of memory"); + } rows = xtalloc(png_get_image_height(png_p, info_p), png_bytep); - for (i = 0; i < (int) png_get_image_height(png_p, info_p); i++) + for (i = 0; i < (int) png_get_image_height(png_p, info_p); i++) { rows[i] = xtalloc(png_get_rowbytes(png_p, info_p), png_byte); + } png_read_image(png_p, rows); write_interlaced(write_simple_pixel(row)); xfree(rows); @@ -264,33 +272,29 @@ static void write_png_gray_alpha(PDF pdf, image_dict * idict) int smask_size = 0; smask_objnum = pdf_create_obj(pdf, obj_type_others, 0); pdf_dict_add_ref(pdf, "SMask", (int) smask_objnum); - smask_size = - (int) ((png_get_rowbytes(png_p, info_p) / 2) * - png_get_image_height(png_p, info_p)); + smask_size = (int) ((png_get_rowbytes(png_p, info_p) / 2) * png_get_image_height(png_p, info_p)); smask = xtalloc((unsigned) smask_size, png_byte); pdf_dict_add_streaminfo(pdf); pdf_end_dict(pdf); pdf_begin_stream(pdf); if (png_get_interlace_type(png_p, info_p) == PNG_INTERLACE_NONE) { row = xtalloc(png_get_rowbytes(png_p, info_p), png_byte); - if ((png_get_bit_depth(png_p, info_p) == 16) - && (pdf->image_hicolor != 0)) { + if ((png_get_bit_depth(png_p, info_p) == 16) && (pdf->image_hicolor != 0)) { write_noninterlaced(write_gray_pixel_16(r)); } else { write_noninterlaced(write_gray_pixel_8(r)); } xfree(row); } else { - if (png_get_image_height(png_p, info_p) * - png_get_rowbytes(png_p, info_p) >= 10240000L) - luatex_warn - ("large interlaced PNG might cause out of memory (use non-interlaced PNG to fix this)"); + if (png_get_image_height(png_p, info_p) * png_get_rowbytes(png_p, info_p) >= 10240000L) { + formatted_warning("pngwrite","large interlaced bitmap might cause out of memory"); + } rows = xtalloc(png_get_image_height(png_p, info_p), png_bytep); - for (i = 0; i < (int) png_get_image_height(png_p, info_p); i++) + for (i = 0; i < (int) png_get_image_height(png_p, info_p); i++) { rows[i] = xtalloc(png_get_rowbytes(png_p, info_p), png_byte); + } png_read_image(png_p, rows); - if ((png_get_bit_depth(png_p, info_p) == 16) - && (pdf->image_hicolor != 0)) { + if ((png_get_bit_depth(png_p, info_p) == 16) && (pdf->image_hicolor != 0)) { write_interlaced(write_gray_pixel_16(row)); } else { write_interlaced(write_gray_pixel_8(row)); @@ -317,33 +321,29 @@ static void write_png_rgb_alpha(PDF pdf, image_dict * idict) int smask_size = 0; smask_objnum = pdf_create_obj(pdf, obj_type_others, 0); pdf_dict_add_ref(pdf, "SMask", (int) smask_objnum); - smask_size = - (int) ((png_get_rowbytes(png_p, info_p) / 4) * - png_get_image_height(png_p, info_p)); + smask_size = (int) ((png_get_rowbytes(png_p, info_p) / 4) * png_get_image_height(png_p, info_p)); smask = xtalloc((unsigned) smask_size, png_byte); pdf_dict_add_streaminfo(pdf); pdf_end_dict(pdf); pdf_begin_stream(pdf); if (png_get_interlace_type(png_p, info_p) == PNG_INTERLACE_NONE) { row = xtalloc(png_get_rowbytes(png_p, info_p), png_byte); - if ((png_get_bit_depth(png_p, info_p) == 16) - && (pdf->image_hicolor != 0)) { + if ((png_get_bit_depth(png_p, info_p) == 16) && (pdf->image_hicolor != 0)) { write_noninterlaced(write_rgb_pixel_16(r)); } else { write_noninterlaced(write_rgb_pixel_8(r)); } xfree(row); } else { - if (png_get_image_height(png_p, info_p) * - png_get_rowbytes(png_p, info_p) >= 10240000L) - luatex_warn - ("large interlaced PNG might cause out of memory (use non-interlaced PNG to fix this)"); + if (png_get_image_height(png_p, info_p) * png_get_rowbytes(png_p, info_p) >= 10240000L) { + formatted_warning("pngwrite","large interlaced bitmap might cause out of memory"); + } rows = xtalloc(png_get_image_height(png_p, info_p), png_bytep); - for (i = 0; i < (int) png_get_image_height(png_p, info_p); i++) + for (i = 0; i < (int) png_get_image_height(png_p, info_p); i++) { rows[i] = xtalloc(png_get_rowbytes(png_p, info_p), png_byte); + } png_read_image(png_p, rows); - if ((png_get_bit_depth(png_p, info_p) == 16) - && (pdf->image_hicolor != 0)) { + if ((png_get_bit_depth(png_p, info_p) == 16) && (pdf->image_hicolor != 0)) { write_interlaced(write_rgb_pixel_16(row)); } else { write_interlaced(write_rgb_pixel_8(row)); @@ -373,8 +373,9 @@ the ``PNG Copy'' function must be skipped; therefore the lengthy tests. static int spng_getint(FILE * f) { unsigned char buf[4]; - if (fread(buf, 1, 4, f) != 4) - luatex_fail("writepng: reading chunk type failed"); + if (fread(buf, 1, 4, f) != 4) { + normal_error("writepng", "reading chunk type failed"); + } return ((((((int) buf[0] << 8) + buf[1]) << 8) + buf[2]) << 8) + buf[3]; } @@ -395,7 +396,7 @@ static void copy_png(PDF pdf, image_dict * idict) f = (FILE *) png_get_io_ptr(png_p); /* 1st pass to find overall stream /Length */ if (fseek(f, 8, SEEK_SET) != 0) - luatex_fail("writepng: fseek in PNG file failed (1)"); + normal_error("writepng", "fseek in file failed"); do { len = spng_getint(f); type = spng_getint(f); @@ -406,49 +407,52 @@ static void copy_png(PDF pdf, image_dict * idict) case SPNG_CHUNK_IDAT: streamlength += len; default: - if (fseek(f, len + 4, SEEK_CUR) != 0) - luatex_fail("writepng: fseek in PNG file failed (2)"); + if (fseek(f, len + 4, SEEK_CUR) != 0) { + normal_error("writepng", "fseek in file failed"); + } } } while (endflag == false); pdf_dict_add_int(pdf, "Length", streamlength); pdf_dict_add_name(pdf, "Filter", "FlateDecode"); pdf_add_name(pdf, "DecodeParms"); pdf_begin_dict(pdf); - pdf_dict_add_int(pdf, "Colors", - png_get_color_type(png_p, - info_p) == PNG_COLOR_TYPE_RGB ? 3 : 1); + pdf_dict_add_int(pdf, "Colors", png_get_color_type(png_p,info_p) == PNG_COLOR_TYPE_RGB ? 3 : 1); pdf_dict_add_int(pdf, "Columns", png_get_image_width(png_p, info_p)); pdf_dict_add_int(pdf, "BitsPerComponent", png_get_bit_depth(png_p, info_p)); pdf_dict_add_int(pdf, "Predictor", 10); pdf_end_dict(pdf); pdf_end_dict(pdf); pdf_begin_stream(pdf); - assert(pdf->zip_write_state == NO_ZIP); /* the PNG stream is already compressed */ + assert(pdf->zip_write_state == NO_ZIP); /* the PNG stream is already compressed */ /* 2nd pass to copy data */ endflag = false; if (fseek(f, 8, SEEK_SET) != 0) - luatex_fail("writepng: fseek in PNG file failed (3)"); + normal_error("writepng", "fseek in file failed"); do { len = spng_getint(f); type = spng_getint(f); switch (type) { - case SPNG_CHUNK_IDAT: /* do copy */ - if (idat == 2) - luatex_fail("writepng: IDAT chunk sequence broken"); + case SPNG_CHUNK_IDAT: + /* do copy */ + if (idat == 2) { + normal_error("writepng", "IDAT chunk sequence broken"); + } idat = 1; - if (read_file_to_buf(pdf, f, len) != len) - luatex_fail("writepng: fread failed"); - if (fseek(f, 4, SEEK_CUR) != 0) - luatex_fail("writepng: fseek in PNG file failed (4)"); + if (read_file_to_buf(pdf, f, len) != len) { + normal_error("writepng", "fread failed"); + } else if (fseek(f, 4, SEEK_CUR) != 0) { + normal_error("writepng", "fseek in file failed"); + } break; - case SPNG_CHUNK_IEND: /* done */ + case SPNG_CHUNK_IEND: + /* done */ endflag = true; break; default: if (idat == 1) idat = 2; if (fseek(f, len + 4, SEEK_CUR) != 0) - luatex_fail("writepng: fseek in PNG file failed (5)"); + normal_error("writepng", "fseek in file failed"); } } while (endflag == false); pdf_end_stream(pdf); @@ -463,10 +467,14 @@ static void reopen_png(image_dict * idict) height = img_ysize(idict); xres = img_xres(idict); yres = img_yres(idict); - read_png_info(idict, IMG_KEEPOPEN); - if (width != img_xsize(idict) || height != img_ysize(idict) - || xres != img_xres(idict) || yres != img_yres(idict)) - luatex_fail("writepng: image dimensions have changed"); + /* + we need to ake sure that the file kept open + */ + img_keepopen(idict) = 1; + read_png_info(idict); + if (width != img_xsize(idict) || height != img_ysize(idict) || xres != img_xres(idict) || yres != img_yres(idict)) { + normal_error("writepng", "image dimensions have changed"); + } } @ @c @@ -526,53 +534,51 @@ void write_png(PDF pdf, image_dict * idict) /* reset structure */ (void) png_set_interlace_handling(png_p); png_read_update_info(png_p, info_p); - pdf_begin_obj(pdf, img_objnum(idict), OBJSTM_NEVER); pdf_begin_dict(pdf); pdf_dict_add_name(pdf, "Type", "XObject"); pdf_dict_add_name(pdf, "Subtype", "Image"); pdf_dict_add_img_filename(pdf, idict); - if (img_attr(idict) != NULL && strlen(img_attr(idict)) > 0) + if (img_attr(idict) != NULL && strlen(img_attr(idict)) > 0) { pdf_printf(pdf, "\n%s\n", img_attr(idict)); + } pdf_dict_add_int(pdf, "Width", (int) png_get_image_width(png_p, info_p)); pdf_dict_add_int(pdf, "Height", (int) png_get_image_height(png_p, info_p)); - pdf_dict_add_int(pdf, "BitsPerComponent", - (int) png_get_bit_depth(png_p, info_p)); + pdf_dict_add_int(pdf, "BitsPerComponent", (int) png_get_bit_depth(png_p, info_p)); if (img_colorspace(idict) != 0) { pdf_dict_add_ref(pdf, "ColorSpace", (int) img_colorspace(idict)); } else { switch (png_get_color_type(png_p, info_p)) { - case PNG_COLOR_TYPE_PALETTE: - png_get_PLTE(png_p, info_p, &palette, &num_palette); - palette_objnum = pdf_create_obj(pdf, obj_type_others, 0); - pdf_add_name(pdf, "ColorSpace"); - pdf_begin_array(pdf); - pdf_add_name(pdf, "Indexed"); - pdf_add_name(pdf, "DeviceRGB"); /* base; PDFRef. 4.5.5 */ - pdf_add_int(pdf, (int) (num_palette - 1)); /* hival */ - pdf_add_ref(pdf, (int) palette_objnum); /* lookup */ - pdf_end_array(pdf); - break; - case PNG_COLOR_TYPE_GRAY: - case PNG_COLOR_TYPE_GRAY_ALPHA: - pdf_dict_add_name(pdf, "ColorSpace", "DeviceGray"); - break; - case PNG_COLOR_TYPE_RGB: - case PNG_COLOR_TYPE_RGB_ALPHA: - pdf_dict_add_name(pdf, "ColorSpace", "DeviceRGB"); - break; - default: - luatex_fail("unsupported type of color_type <%i>", - png_get_color_type(png_p, info_p)); + case PNG_COLOR_TYPE_PALETTE: + png_get_PLTE(png_p, info_p, &palette, &num_palette); + palette_objnum = pdf_create_obj(pdf, obj_type_others, 0); + pdf_add_name(pdf, "ColorSpace"); + pdf_begin_array(pdf); + pdf_add_name(pdf, "Indexed"); + pdf_add_name(pdf, "DeviceRGB"); /* base; PDFRef. 4.5.5 */ + pdf_add_int(pdf, (int) (num_palette - 1)); /* hival */ + pdf_add_ref(pdf, (int) palette_objnum); /* lookup */ + pdf_end_array(pdf); + break; + case PNG_COLOR_TYPE_GRAY: + case PNG_COLOR_TYPE_GRAY_ALPHA: + pdf_dict_add_name(pdf, "ColorSpace", "DeviceGray"); + break; + case PNG_COLOR_TYPE_RGB: + case PNG_COLOR_TYPE_RGB_ALPHA: + pdf_dict_add_name(pdf, "ColorSpace", "DeviceRGB"); + break; + default: + formatted_error("writepng", "unsupported color_type '%i'", png_get_color_type(png_p, info_p)); } } - if (png_copy && pdf->minor_version > 1 + if (png_copy + && pdf->minor_version > 1 && png_get_interlace_type(png_p, info_p) == PNG_INTERLACE_NONE && (png_get_color_type(png_p, info_p) == PNG_COLOR_TYPE_GRAY - || png_get_color_type(png_p, info_p) == PNG_COLOR_TYPE_RGB) + || png_get_color_type(png_p, info_p) == PNG_COLOR_TYPE_RGB) && !pdf->image_apply_gamma - && (!png_get_valid(png_p, info_p, PNG_INFO_gAMA) - || int_file_gamma == PNG_FP_1) + && (!png_get_valid(png_p, info_p, PNG_INFO_gAMA) || int_file_gamma == PNG_FP_1) && !png_get_valid(png_p, info_p, PNG_INFO_cHRM) && !png_get_valid(png_p, info_p, PNG_INFO_iCCP) && !png_get_valid(png_p, info_p, PNG_INFO_sBIT) @@ -583,64 +589,63 @@ void write_png(PDF pdf, image_dict * idict) && !png_get_valid(png_p, info_p, PNG_INFO_sPLT)) { copy_png(pdf, idict); } else { - if (0) { - tex_printf(" *** PNG copy skipped because: "); + if (img_errorlevel(idict) > 1) { if (!png_copy) - tex_printf("!png_copy "); + normal_warning("pngcopy","failed"); if (!(pdf->minor_version > 1)) - tex_printf("minorversion=%d ", pdf->minor_version); + formatted_warning("pngcopy","skipped because minorversion is '%d'", pdf->minor_version); if (!(png_get_interlace_type(png_p, info_p) == PNG_INTERLACE_NONE)) - tex_printf("interlaced "); + normal_warning("pngcopy","skipped because of interlacing"); if (!((png_get_color_type(png_p, info_p) == PNG_COLOR_TYPE_GRAY) - || (png_get_color_type(png_p, info_p) == PNG_COLOR_TYPE_RGB))) - tex_printf("colortype "); + || (png_get_color_type(png_p, info_p) == PNG_COLOR_TYPE_RGB))) + normal_warning("pngcopy","skipped because of colortype"); if (pdf->image_apply_gamma) - tex_printf("apply gamma "); - if (!(!png_get_valid(png_p, info_p, PNG_INFO_gAMA) - || int_file_gamma == PNG_FP_1)) - tex_printf("gamma "); + normal_warning("pngcopy","skipped because of gamma (1)"); + if (!(!png_get_valid(png_p, info_p, PNG_INFO_gAMA) || int_file_gamma == PNG_FP_1)) + normal_warning("pngcopy","skipped because of gamma (2)"); if (png_get_valid(png_p, info_p, PNG_INFO_cHRM)) - tex_printf("cHRM "); + normal_warning("pngcopy","skipped because of cHRM"); if (png_get_valid(png_p, info_p, PNG_INFO_iCCP)) - tex_printf("iCCP "); + normal_warning("pngcopy","skipped because of iCCP"); if (png_get_valid(png_p, info_p, PNG_INFO_sBIT)) - tex_printf("sBIT "); + normal_warning("pngcopy","skipped because of sBIT"); if (png_get_valid(png_p, info_p, PNG_INFO_sRGB)) - tex_printf("sRGB "); + normal_warning("pngcopy","skipped because of sRGB"); if (png_get_valid(png_p, info_p, PNG_INFO_bKGD)) - tex_printf("bKGD "); + normal_warning("pngcopy","skipped because of bKGD"); if (png_get_valid(png_p, info_p, PNG_INFO_hIST)) - tex_printf("hIST "); + normal_warning("pngcopy","skipped because of hIST"); if (png_get_valid(png_p, info_p, PNG_INFO_tRNS)) - tex_printf("tRNS "); + normal_warning("pngcopy","skipped because of tRNS"); if (png_get_valid(png_p, info_p, PNG_INFO_sPLT)) - tex_printf("sPLT "); + normal_warning("pngcopy","skipped because of sPLT"); } switch (png_get_color_type(png_p, info_p)) { - case PNG_COLOR_TYPE_PALETTE: - case PNG_COLOR_TYPE_GRAY: - case PNG_COLOR_TYPE_RGB: - write_png_gray(pdf, idict); - break; - case PNG_COLOR_TYPE_GRAY_ALPHA: - if (pdf->minor_version >= 4) { - write_png_gray_alpha(pdf, idict); - last_png_needs_page_group = true; - } else + case PNG_COLOR_TYPE_PALETTE: + case PNG_COLOR_TYPE_GRAY: + case PNG_COLOR_TYPE_RGB: write_png_gray(pdf, idict); - break; - case PNG_COLOR_TYPE_RGB_ALPHA: - if (pdf->minor_version >= 4) { - write_png_rgb_alpha(pdf, idict); - last_png_needs_page_group = true; - } else - write_png_gray(pdf, idict); - break; - default: - assert(0); + break; + case PNG_COLOR_TYPE_GRAY_ALPHA: + if (pdf->minor_version >= 4) { + write_png_gray_alpha(pdf, idict); + last_png_needs_page_group = true; + } else + write_png_gray(pdf, idict); + break; + case PNG_COLOR_TYPE_RGB_ALPHA: + if (pdf->minor_version >= 4) { + write_png_rgb_alpha(pdf, idict); + last_png_needs_page_group = true; + } else + write_png_gray(pdf, idict); + break; + default: + assert(0); } } write_palette_streamobj(pdf, palette_objnum, palette, num_palette); + /* always */ close_and_cleanup_png(idict); } @@ -649,13 +654,15 @@ static boolean transparent_page_group_was_written = false; @ Called after the xobject generated by |write_png| has been finished; used to write out additional objects + @c void write_additional_png_objects(PDF pdf) { (void) pdf; (void) transparent_page_group; (void) transparent_page_group_was_written; - return; /* this interferes with current macro-based usage and cannot be configured */ + return; + /* this interferes with current macro-based usage and cannot be configured */ #if 0 if (last_png_needs_page_group) { if (!transparent_page_group_was_written && transparent_page_group > 1) { diff --git a/Build/source/texk/web2c/luatexdir/lang/texlang.h b/Build/source/texk/web2c/luatexdir/lang/texlang.h index 9a8534b3996..0920dc9f740 100644 --- a/Build/source/texk/web2c/luatexdir/lang/texlang.h +++ b/Build/source/texk/web2c/luatexdir/lang/texlang.h @@ -53,7 +53,7 @@ extern int hyphenate_string(struct tex_language *lang, char *w, char **ret); extern void new_hyphenation(halfword h, halfword t); extern void clear_patterns(struct tex_language *lang); extern void clear_hyphenation(struct tex_language *lang); -extern const char *clean_hyphenation(const char *buffer, char **cleaned); +extern const char *clean_hyphenation(int id, const char *buffer, char **cleaned); extern void hnj_hyphenation(halfword head, halfword tail); extern void set_pre_hyphen_char(int lan, int val); @@ -82,6 +82,7 @@ extern void new_post_hyphen_char(void); extern void new_pre_exhyphen_char(void); extern void new_post_exhyphen_char(void); extern void new_hyphenation_min(void); +extern void new_hj_code(void); #endif diff --git a/Build/source/texk/web2c/luatexdir/lang/texlang.w b/Build/source/texk/web2c/luatexdir/lang/texlang.w index 4e9282e5f3f..170770bfeed 100644 --- a/Build/source/texk/web2c/luatexdir/lang/texlang.w +++ b/Build/source/texk/web2c/luatexdir/lang/texlang.w @@ -19,7 +19,6 @@ @ @c - #include "ptexlib.h" #include <string.h> #include "lua/luatex-api.h" @@ -62,6 +61,9 @@ struct tex_language *new_language(int n) lang->pre_exhyphen_char = 0; lang->post_exhyphen_char = 0; lang->hyphenation_min = -1; + if (int_par(saving_hyph_codes_code)) { + hj_codes_from_lc_codes(l); /* for now, we might just use specific value for whatever task */ + } return lang; } else { return NULL; @@ -96,7 +98,6 @@ void set_post_hyphen_char(int n, int v) l->post_hyphen_char = (int) v; } - void set_pre_exhyphen_char(int n, int v) { struct tex_language *l = get_language((int) n); @@ -111,7 +112,6 @@ void set_post_exhyphen_char(int n, int v) l->post_exhyphen_char = (int) v; } - int get_pre_hyphen_char(int n) { struct tex_language *l = get_language((int) n); @@ -128,7 +128,6 @@ int get_post_hyphen_char(int n) return (int) l->post_hyphen_char; } - int get_pre_exhyphen_char(int n) { struct tex_language *l = get_language((int) n); @@ -145,7 +144,6 @@ int get_post_exhyphen_char(int n) return (int) l->post_exhyphen_char; } - void set_hyphenation_min(int n, int v) { struct tex_language *l = get_language((int) n); @@ -161,7 +159,6 @@ int get_hyphenation_min(int n) return (int) l->hyphenation_min; } -@ @c void load_patterns(struct tex_language *lang, const unsigned char *buff) { if (lang == NULL || buff == NULL || strlen((const char *) buff) == 0) @@ -187,18 +184,23 @@ void load_tex_patterns(int curlang, halfword head) load_patterns(get_language(curlang), (unsigned char *) s); } - @ @c -#define STORE_CHAR(x) do { \ - unsigned xx = get_lc_code(x); \ - if (!xx) xx = x; \ - uindex = uni2string(uindex, xx); \ - } while (0) +#define STORE_CHAR(l,x) do { \ + unsigned xx = get_hj_code(l,x); \ + if (!xx) { \ + xx = x; \ + } \ + uindex = uni2string(uindex, xx); \ +} while (0) -/* Cleans one word which is returned in |cleaned|, - returns the new offset into |buffer| */ +#define hj_char_code(l,c) \ + (l>=0 && get_hj_code(l,c)) -const char *clean_hyphenation(const char *buff, char **cleaned) +@ Cleans one word which is returned in |cleaned|, returns the new offset +into |buffer| + +@c +const char *clean_hyphenation(int id, const char *buff, char **cleaned) { int items = 0; unsigned char word[MAX_WORD_LEN + 1]; /* work buffer for bytes */ @@ -209,8 +211,8 @@ const char *clean_hyphenation(const char *buff, char **cleaned) const char *s = buff; while (*s && !isspace((unsigned char)*s)) { - word[i++] = (unsigned)*s; - s++; + word[i++] = (unsigned)*s; + s++; if ((s-buff)>MAX_WORD_LEN) { /* todo: this is too strict, should count unicode, not bytes */ *cleaned = NULL; @@ -228,7 +230,7 @@ const char *clean_hyphenation(const char *buff, char **cleaned) u = uword[i++]; if (u == '-') { /* skip */ } else if (u == '=') { - STORE_CHAR('-'); + STORE_CHAR(id,'-'); } else if (u == '{') { u = uword[i++]; items = 0; @@ -250,7 +252,7 @@ const char *clean_hyphenation(const char *buff, char **cleaned) u = uword[i++];; } while (u && u != '}') { - STORE_CHAR(u); + STORE_CHAR(id,u); u = uword[i++]; } if (u == '}') { @@ -262,7 +264,7 @@ const char *clean_hyphenation(const char *buff, char **cleaned) return s; } } else { - STORE_CHAR(u); + STORE_CHAR(id,u); } } *uindex = '\0'; @@ -276,6 +278,7 @@ void load_hyphenation(struct tex_language *lang, const unsigned char *buff) const char *s; const char *value; char *cleaned; + int id ; lua_State *L = Luas; if (lang == NULL) return; @@ -285,12 +288,13 @@ void load_hyphenation(struct tex_language *lang, const unsigned char *buff) } lua_rawgeti(L, LUA_REGISTRYINDEX, lang->exceptions); s = (const char *) buff; + id = lang->id; while (*s) { while (isspace((unsigned char)*s)) s++; if (*s) { value = s; - s = clean_hyphenation(s, &cleaned); + s = clean_hyphenation(id, s, &cleaned); if (cleaned != NULL) { if ((s - value) > 0) { lua_pushstring(L, cleaned); @@ -300,8 +304,7 @@ void load_hyphenation(struct tex_language *lang, const unsigned char *buff) free(cleaned); } else { #ifdef VERBOSE - fprintf(stderr, "skipping invalid hyphenation exception: %s\n", - value); + formatted_warning("hyphenation","skipping invalid hyphenation exception: %s", value); #endif } } @@ -442,7 +445,6 @@ halfword compound_word_break(halfword t, int clang) return disc; } - halfword insert_complex_discretionary(halfword t, lang_variables * lan, halfword pre, halfword pos, halfword replace) @@ -451,7 +453,6 @@ halfword insert_complex_discretionary(halfword t, lang_variables * lan, return insert_discretionary(t, pre, pos, replace,int_par(hyphen_penalty_code)); } - halfword insert_character(halfword t, int c) { halfword p; @@ -476,8 +477,6 @@ void set_disc_field(halfword f, halfword t) } } - - @ @c static char *hyphenation_exception(int exceptions, char *w) { @@ -498,7 +497,6 @@ static char *hyphenation_exception(int exceptions, char *w) return ret; } - @ @c char *exception_strings(struct tex_language *lang) { @@ -519,8 +517,7 @@ char *exception_strings(struct tex_language *lang) if (current + 2 + l > size) { ret = xrealloc(ret, - (unsigned) ((size + size / 5) + current + l + - 1024)); + (unsigned) ((size + size / 5) + current + l + 1024)); size = (size + size / 5) + current + l + 1024; } *(ret + current) = ' '; @@ -532,7 +529,6 @@ char *exception_strings(struct tex_language *lang) return ret; } - @ the sequence from |wordstart| to |r| can contain only normal characters it could be faster to modify a halfword pointer and return an integer @@ -570,7 +566,6 @@ static int count_exception_part(unsigned int *j, unsigned int *uword, int len) return ret; } - @ @c static const char *PAT_ERROR[] = { "Exception discretionaries should contain three pairs of braced items.", @@ -706,14 +701,12 @@ Algorithms} was typeset by \TeX, only about 1.2 hyphenations needed to be tried per paragraph, since the line breaking algorithm needed to use two passes on only about 5 per cent of the paragraphs. - When a word been set up to contain a candidate for hyphenation, \TeX\ first looks to see if it is in the user's exception dictionary. If not, hyphens are inserted based on patterns that appear within the given word, using an algorithm due to Frank~M. Liang. @^Liang, Franklin Mark@> - @ This is incompatible with TEX because the first word of a paragraph can be hyphenated, but most european users seem to agree that prohibiting hyphenation there was not the best idea ever. @@ -752,12 +745,14 @@ static halfword find_next_wordstart(halfword r) if (is_simple_character(r)) { chr = character(r) ; if (chr == ex_hyphen_char) { - /* We only accept an explicit hyphen when there is a preceding glyph and */ - /* we skip a sequence of explicit hyphens as that normally indicates a */ - /* -- or --- ligature in which case we can in a worse case usage get bad */ - /* node lists later on due to messed up ligature building as these dashes */ - /* ligatures in base fonts. This is a side effect of the separating the */ - /* hyphenation, ligaturing and kerning steps. A test is cmr with ------. */ + /* + We only accept an explicit hyphen when there is a preceding glyph and + we skip a sequence of explicit hyphens as that normally indicates a + -- or --- ligature in which case we can in a worse case usage get bad + node lists later on due to messed up ligature building as these dashes + are ligatures in base fonts. This is a side effect of the separating the + hyphenation, ligaturing and kerning steps. A test is cmr with ------. + */ t = vlink(r) ; if ((start_ok > 0) && (t!=null) && (type(t) == glyph_node) && (character(t) != ex_hyphen_char)) { t = compound_word_break(r, char_lang(r)); @@ -766,7 +761,7 @@ static halfword find_next_wordstart(halfword r) } else { start_ok = 0; } - } else if (start_ok && (l = get_lc_code(chr)) > 0) { + } else if (start_ok && (l = hj_char_code(char_lang(r),chr)) > 0) { if (char_uchyph(r) || l == chr) { return r; } else { @@ -859,7 +854,7 @@ void hnj_hyphenation(halfword head, halfword tail) langdata.pre_hyphen_char = get_pre_hyphen_char(clang); langdata.post_hyphen_char = get_post_hyphen_char(clang); while (r != null && type(r) == glyph_node && is_simple_character(r) && clang == char_lang(r) && - (((lchar = get_lc_code(character(r))) > 0) || (character(r) == ex_hyphen_char && (lchar = ex_hyphen_char)))) { + (((lchar = hj_char_code(clang,character(r))) > 0) || (character(r) == ex_hyphen_char && (lchar = ex_hyphen_char)))) { if (character(r) == ex_hyphen_char) explicit_hyphen = true; wordlen++; @@ -876,8 +871,7 @@ void hnj_hyphenation(halfword head, halfword tail) (replacement = hyphenation_exception(lang->exceptions, utf8word)) != NULL) { #ifdef VERBOSE - fprintf(stderr, "replacing %s (c=%d) by %s\n", utf8word, clang, - replacement); + formatted_warning("hyphenation","replacing %s (c=%d) by %s", utf8word, clang, replacement); #endif do_exception(wordstart, r, replacement); free(replacement); @@ -887,7 +881,7 @@ void hnj_hyphenation(halfword head, halfword tail) halfword rr = r; halfword t = null; #ifdef VERBOSE - fprintf(stderr, "explicit hyphen(s) found in %s (c=%d)\n", utf8word, clang); + formatted_warning("hyphenation","explicit hyphen(s) found in %s (c=%d)", utf8word, clang); #endif while (rr != wordstart) { if (is_simple_character(rr)) { @@ -919,12 +913,11 @@ void hnj_hyphenation(halfword head, halfword tail) } #ifdef VERBOSE - fprintf(stderr, "hyphenate %s (c=%d,l=%d,r=%d) from %c to %c\n", - utf8word, clang, lhmin, rhmin, character(left), - character(right)); + formatted_warning("hyphenation","hyphenate %s (c=%d,l=%d,r=%d) from %c to %c", + utf8word, clang, lhmin, rhmin, character(left), + character(right)); #endif - (void) hnj_hyphen_hyphenate(lang->patterns, wordstart, end_word, - wordlen, left, right, &langdata); + (void) hnj_hyphen_hyphenate(lang->patterns, wordstart, end_word, wordlen, left, right, &langdata); } } explicit_hyphen = false; @@ -938,7 +931,6 @@ void hnj_hyphenation(halfword head, halfword tail) vlink(tail) = save_tail1; } - @ @c void new_hyphenation(halfword head, halfword tail) { @@ -956,7 +948,7 @@ void new_hyphenation(halfword head, halfword tail) nodelist_to_lua(L, head); nodelist_to_lua(L, tail); if (lua_pcall(L, 2, 0, 0) != 0) { - fprintf(stdout, "error: %s\n", lua_tostring(L, -1)); + formatted_warning("hyphenation","bad specification: %s",lua_tostring(L, -1)); lua_pop(L, 2); lua_error(L); return; @@ -970,15 +962,14 @@ void new_hyphenation(halfword head, halfword tail) @ dumping and undumping languages @c -#define dump_string(a) \ - if (a!=NULL) { \ - x = (int)strlen(a)+1; \ - dump_int(x); dump_things(*a, x); \ - } else { \ - x = 0; dump_int(x); \ +#define dump_string(a) \ + if (a!=NULL) { \ + x = (int)strlen(a)+1; \ + dump_int(x); dump_things(*a, x); \ + } else { \ + x = 0; dump_int(x); \ } - static void dump_one_language(int i) { char *s = NULL; @@ -1022,7 +1013,6 @@ void dump_language_data(void) } } - static void undump_one_language(int i) { char *s = NULL; @@ -1071,7 +1061,6 @@ void undump_language_data(void) } } - @ When \TeX\ has scanned `\.{\\hyphenation}', it calls on a procedure named |new_hyph_exceptions| to do the right thing. @@ -1113,7 +1102,6 @@ void new_post_hyphen_char(void) set_post_hyphen_char(int_par(language_code), cur_val); } - @ `\.{\\preexhyphenchar}', sets the |pre_break| character, and `\.{\\postexhyphenchar}' the |post_break| character. Their defaults are both zero (nul). @@ -1133,10 +1121,19 @@ void new_post_exhyphen_char(void) set_post_exhyphen_char(int_par(language_code), cur_val); } - void new_hyphenation_min(void) { scan_optional_equals(); scan_int(); set_hyphenation_min(int_par(language_code), cur_val); } + +void new_hj_code(void) +{ + int i ; + scan_int(); + i = cur_val; + scan_optional_equals(); + scan_int(); + set_hj_code(int_par(language_code), i, cur_val, -1); +} diff --git a/Build/source/texk/web2c/luatexdir/lua/lcallbacklib.c b/Build/source/texk/web2c/luatexdir/lua/lcallbacklib.c index dee8057bb7b..3abe333ec60 100644 --- a/Build/source/texk/web2c/luatexdir/lua/lcallbacklib.c +++ b/Build/source/texk/web2c/luatexdir/lua/lcallbacklib.c @@ -51,7 +51,6 @@ static const char *const callbacknames[] = { "start_page_number", "stop_page_number", "start_run", "stop_run", "define_font", - "token_filter", "pre_output_filter", "buildpage_filter", "hpack_filter", "vpack_filter", @@ -70,6 +69,7 @@ static const char *const callbacknames[] = { "show_error_message","show_lua_error_hook", "show_warning_message", "hpack_quality", "vpack_quality", + "process_rule", NULL }; @@ -83,18 +83,17 @@ int debug_callback_defined(int i) void get_lua_boolean(const char *table, const char *name, boolean * target) { - int stacktop; - int t; - stacktop = lua_gettop(Luas); + int stacktop = lua_gettop(Luas); luaL_checkstack(Luas, 2, "out of stack space"); lua_getglobal(Luas, table); if (lua_istable(Luas, -1)) { + int t; lua_getfield(Luas, -1, name); t = lua_type(Luas, -1); if (t == LUA_TBOOLEAN) { *target = (boolean) (lua_toboolean(Luas, -1)); } else if (t == LUA_TNUMBER) { - *target = (boolean) (lua_tonumber(Luas, -1) == 0 ? 0 : 1); + *target = (boolean) (lua_tointeger(Luas, -1) == 0 ? 0 : 1); } } lua_settop(Luas, stacktop); @@ -103,18 +102,17 @@ void get_lua_boolean(const char *table, const char *name, boolean * target) void get_saved_lua_boolean(int r, const char *name, boolean * target) { - int stacktop; - int t; - stacktop = lua_gettop(Luas); + int stacktop = lua_gettop(Luas); luaL_checkstack(Luas, 2, "out of stack space"); lua_rawgeti(Luas, LUA_REGISTRYINDEX, r); if (lua_istable(Luas, -1)) { + int t; lua_getfield(Luas, -1, name); t = lua_type(Luas, -1); if (t == LUA_TBOOLEAN) { *target = (boolean) lua_toboolean(Luas, -1); } else if (t == LUA_TNUMBER) { - *target = (boolean) (lua_tonumber(Luas, -1) == 0 ? 0 : 1); + *target = (boolean) (lua_tointeger(Luas, -1) == 0 ? 0 : 1); } } lua_settop(Luas, stacktop); @@ -123,14 +121,13 @@ void get_saved_lua_boolean(int r, const char *name, boolean * target) void get_lua_number(const char *table, const char *name, int *target) { - int stacktop; - stacktop = lua_gettop(Luas); + int stacktop = lua_gettop(Luas); luaL_checkstack(Luas, 2, "out of stack space"); lua_getglobal(Luas, table); if (lua_istable(Luas, -1)) { lua_getfield(Luas, -1, name); if (lua_type(Luas, -1) == LUA_TNUMBER) { - *target = (int)lua_tonumber(Luas, -1); + *target = (int) lua_tointeger(Luas, -1); } } lua_settop(Luas, stacktop); @@ -139,14 +136,13 @@ void get_lua_number(const char *table, const char *name, int *target) void get_saved_lua_number(int r, const char *name, int *target) { - int stacktop; - stacktop = lua_gettop(Luas); + int stacktop = lua_gettop(Luas); luaL_checkstack(Luas, 2, "out of stack space"); lua_rawgeti(Luas, LUA_REGISTRYINDEX, r); if (lua_istable(Luas, -1)) { lua_getfield(Luas, -1, name); if (lua_type(Luas, -1) == LUA_TNUMBER) { - *target=(int)lua_tonumber(Luas, -1); + *target = (int) lua_tointeger(Luas, -1); } } lua_settop(Luas, stacktop); @@ -155,8 +151,7 @@ void get_saved_lua_number(int r, const char *name, int *target) void get_lua_string(const char *table, const char *name, char **target) { - int stacktop; - stacktop = lua_gettop(Luas); + int stacktop = lua_gettop(Luas); luaL_checkstack(Luas, 2, "out of stack space"); lua_getglobal(Luas, table); if (lua_type(Luas, -1) == LUA_TTABLE) { @@ -171,8 +166,7 @@ void get_lua_string(const char *table, const char *name, char **target) void get_saved_lua_string(int r, const char *name, char **target) { - int stacktop; - stacktop = lua_gettop(Luas); + int stacktop = lua_gettop(Luas); luaL_checkstack(Luas, 2, "out of stack space"); lua_rawgeti(Luas, LUA_REGISTRYINDEX, r); if (lua_type(Luas, -1) == LUA_TTABLE) { @@ -190,6 +184,7 @@ void get_saved_lua_string(int r, const char *name, char **target) #define CALLBACK_LINE 'l' #define CALLBACK_STRNUMBER 's' #define CALLBACK_STRING 'S' +#define CALLBACK_RESULT 'R' /* a string but nil is also ok */ #define CALLBACK_CHARNUM 'c' #define CALLBACK_LSTRING 'L' #define CALLBACK_NODE 'N' @@ -279,49 +274,48 @@ int do_run_callback(int special, const char *values, va_list vl) lua_pushvalue(L, -2); } ss = strchr(values, '>'); - assert(ss); luaL_checkstack(L, (int) (ss - values + 1), "out of stack space"); ss = NULL; for (narg = 0; *values; narg++) { switch (*values++) { - case CALLBACK_CHARNUM: /* an ascii char! */ - cs = (char) va_arg(vl, int); - lua_pushlstring(L, &cs, 1); - break; - case CALLBACK_STRING: /* C string */ - s = va_arg(vl, char *); - lua_pushstring(L, s); - break; - case CALLBACK_LSTRING: /* 'lstring' */ - lstr = va_arg(vl, lstring *); - lua_pushlstring(L, (const char *)lstr->s, lstr->l); - break; - case CALLBACK_INTEGER: /* int */ - lua_pushnumber(L, va_arg(vl, int)); - break; - case CALLBACK_STRNUMBER: /* TeX string */ - s = makeclstring(va_arg(vl, int), &len); - lua_pushlstring(L, s, len); - break; - case CALLBACK_BOOLEAN: /* boolean */ - lua_pushboolean(L, va_arg(vl, int)); - break; - case CALLBACK_LINE: /* a buffer section, with implied start */ - lua_pushlstring(L, (char *) (buffer + first), (size_t) va_arg(vl, int)); - break; - case CALLBACK_NODE: - lua_nodelib_push_fast(L,va_arg(vl, int)); - break; - case CALLBACK_DIR: - lua_push_dir_par(L,va_arg(vl, int)); - break; - case '-': - narg--; - break; - case '>': - goto ENDARGS; - default: - ; + case CALLBACK_CHARNUM: /* an ascii char! */ + cs = (char) va_arg(vl, int); + lua_pushlstring(L, &cs, 1); + break; + case CALLBACK_STRING: /* C string */ + s = va_arg(vl, char *); + lua_pushstring(L, s); + break; + case CALLBACK_LSTRING: /* 'lstring' */ + lstr = va_arg(vl, lstring *); + lua_pushlstring(L, (const char *)lstr->s, lstr->l); + break; + case CALLBACK_INTEGER: /* int */ + lua_pushinteger(L, va_arg(vl, int)); + break; + case CALLBACK_STRNUMBER: /* TeX string */ + s = makeclstring(va_arg(vl, int), &len); + lua_pushlstring(L, s, len); + break; + case CALLBACK_BOOLEAN: /* boolean */ + lua_pushboolean(L, va_arg(vl, int)); + break; + case CALLBACK_LINE: /* a buffer section, with implied start */ + lua_pushlstring(L, (char *) (buffer + first), (size_t) va_arg(vl, int)); + break; + case CALLBACK_NODE: + lua_nodelib_push_fast(L,va_arg(vl, int)); + break; + case CALLBACK_DIR: + lua_push_dir_par(L,va_arg(vl, int)); + break; + case '-': + narg--; + break; + case '>': + goto ENDARGS; + default: + ; } } ENDARGS: @@ -343,7 +337,7 @@ int do_run_callback(int special, const char *values, va_list vl) * TeX initialization is complete */ if (!log_opened_global) { - fprintf(stderr, "This went wrong: %s\n", lua_tostring(L, -1)); + fprintf(stderr, "error in callback: %s\n", lua_tostring(L, -1)); error(); } else { lua_gc(L, LUA_GCCOLLECT, 0); @@ -359,102 +353,130 @@ int do_run_callback(int special, const char *values, va_list vl) while (*values) { int b, t; halfword p; + t = lua_type(L, nres); switch (*values++) { - case CALLBACK_BOOLEAN: - if (lua_type(L, nres) != LUA_TBOOLEAN) { - fprintf(stderr, "Expected a boolean, not: %s\n", lua_typename(L, lua_type(L, nres))); - goto EXIT; - } - b = lua_toboolean(L, nres); - *va_arg(vl, boolean *) = (boolean) b; - break; - case CALLBACK_INTEGER: - if (lua_type(L, nres) != LUA_TNUMBER) { - fprintf(stderr, "Expected a number, not: %s\n", lua_typename(L, lua_type(L, nres))); - goto EXIT; - } - b = (int) lua_tonumber(L, nres); - *va_arg(vl, int *) = b; - break; - case CALLBACK_LINE: /* TeX line ... happens frequently when we have a plug-in */ - t = lua_type(L, nres); - if (t == LUA_TNIL) { - bufloc = 0; - goto EXIT; - } else if (t == LUA_TSTRING) { - s = lua_tolstring(L, nres, &len); - if (s == NULL) { /* |len| can be zero */ - bufloc = 0; - } else if (len == 0) { + case CALLBACK_BOOLEAN: + if (t == LUA_TNIL) { + b = 0; + } else if (t != LUA_TBOOLEAN) { + fprintf(stderr, "callback should return a boolean, not: %s\n", lua_typename(L, t)); + goto EXIT; + } else { + b = lua_toboolean(L, nres); + } + *va_arg(vl, boolean *) = (boolean) b; + break; + case CALLBACK_INTEGER: + if (t != LUA_TNUMBER) { + fprintf(stderr, "callback should return a number, not: %s\n", lua_typename(L, t)); + goto EXIT; + } + b = lua_tointeger(L, nres); + *va_arg(vl, int *) = b; + break; + case CALLBACK_LINE: /* TeX line ... happens frequently when we have a plug-in */ + if (t == LUA_TNIL) { bufloc = 0; + goto EXIT; + } else if (t == LUA_TSTRING) { + s = lua_tolstring(L, nres, &len); + if (s == NULL) { /* |len| can be zero */ + bufloc = 0; + } else if (len == 0) { + bufloc = 0; + } else { + bufloc = va_arg(vl, int *); + ret = *bufloc; + check_buffer_overflow(ret + (int) len); + strncpy((char *) (buffer + ret), s, len); + *bufloc += (int) len; + /* while (len--) { buffer[(*bufloc)++] = *s++; } */ + while ((*bufloc) - 1 > ret && buffer[(*bufloc) - 1] == ' ') + (*bufloc)--; + } } else { - bufloc = va_arg(vl, int *); - ret = *bufloc; - check_buffer_overflow(ret + (int) len); - strncpy((char *) (buffer + ret), s, len); - *bufloc += (int) len; - /* while (len--) { buffer[(*bufloc)++] = *s++; } */ - while ((*bufloc) - 1 > ret && buffer[(*bufloc) - 1] == ' ') - (*bufloc)--; + fprintf(stderr, "callback should return a string, not: %s\n", lua_typename(L, t)); + goto EXIT; } - } else { - fprintf(stderr, "Expected a string for (l), not: %s\n", lua_typename(L, lua_type(L, nres))); - goto EXIT; - } - break; - case CALLBACK_STRNUMBER: /* TeX string */ - if (lua_type(L, nres) != LUA_TSTRING) { - fprintf(stderr, "Expected a string for (s), not: %s\n", lua_typename(L, lua_type(L, nres))); - goto EXIT; - } - s = lua_tolstring(L, nres, &len); - if (s == NULL) /* |len| can be zero */ - *va_arg(vl, int *) = 0; - else { - *va_arg(vl, int *) = maketexlstring(s, len); - } - break; - case CALLBACK_STRING: /* C string aka buffer */ - if (lua_type(L, nres) != LUA_TSTRING) { - fprintf(stderr, "Expected a string for (S), not: %s\n", lua_typename(L, lua_type(L, nres))); - goto EXIT; - } - s = lua_tolstring(L, nres, &len); - if (s == NULL) /* |len| can be zero */ - *va_arg(vl, int *) = 0; - else { - ss = xmalloc((unsigned) (len + 1)); - (void) memcpy(ss, s, (len + 1)); - *va_arg(vl, char **) = ss; - } - break; - case CALLBACK_LSTRING: /* lstring */ - if (lua_type(L, nres) != LUA_TSTRING) { - fprintf(stderr, "Expected a string for (S), not: %s\n", lua_typename(L, lua_type(L, nres))); + break; + case CALLBACK_STRNUMBER: /* TeX string */ + if (t != LUA_TSTRING) { + fprintf(stderr, "callback should return a string, not: %s\n", lua_typename(L, t)); + goto EXIT; + } + s = lua_tolstring(L, nres, &len); + if (s == NULL) /* |len| can be zero */ + *va_arg(vl, int *) = 0; + else { + *va_arg(vl, int *) = maketexlstring(s, len); + } + break; + case CALLBACK_STRING: /* C string aka buffer */ + if (t != LUA_TSTRING) { + fprintf(stderr, "callback should return a string, not: %s\n", lua_typename(L, t)); + goto EXIT; + } + s = lua_tolstring(L, nres, &len); + if (s == NULL) /* |len| can be zero */ + *va_arg(vl, int *) = 0; + else { + ss = xmalloc((unsigned) (len + 1)); + (void) memcpy(ss, s, (len + 1)); + *va_arg(vl, char **) = ss; + } + break; + case CALLBACK_RESULT: /* C string aka buffer */ + if (t == LUA_TNIL) { + *va_arg(vl, int *) = 0; + } else if (t == LUA_TBOOLEAN) { + b = lua_toboolean(L, nres); + if (b == 0) { + *va_arg(vl, int *) = 0; + } else { + fprintf(stderr, "callback should return a string, false or nil, not: %s\n", lua_typename(L, t)); + goto EXIT; + } + } else if (t != LUA_TSTRING) { + fprintf(stderr, "callback should return a string, false or nil, not: %s\n", lua_typename(L, t)); + goto EXIT; + } else { + s = lua_tolstring(L, nres, &len); + if (s == NULL) /* |len| can be zero */ + *va_arg(vl, int *) = 0; + else { + ss = xmalloc((unsigned) (len + 1)); + (void) memcpy(ss, s, (len + 1)); + *va_arg(vl, char **) = ss; + } + } + break; + case CALLBACK_LSTRING: /* lstring */ + if (t != LUA_TSTRING) { + fprintf(stderr, "callback should return a string, not: %s\n", lua_typename(L, t)); + goto EXIT; + } + s = lua_tolstring(L, nres, &len); + if (s == NULL) /* |len| can be zero */ + *va_arg(vl, int *) = 0; + else { + lstring *ret = xmalloc(sizeof(lstring)); + ret->s = xmalloc((unsigned) (len + 1)); + (void) memcpy(ret->s, s, (len + 1)); + ret->l = len; + *va_arg(vl, lstring **) = ret; + } + break; + case CALLBACK_NODE: + if (t == LUA_TNIL) { + p = null; + } else { + p = *check_isnode(L,nres); + } + *va_arg(vl, int *) = p; + break; + default: + fprintf(stdout, "callback returned an invalid value type"); goto EXIT; - } - s = lua_tolstring(L, nres, &len); - if (s == NULL) /* |len| can be zero */ - *va_arg(vl, int *) = 0; - else { - lstring *ret = xmalloc(sizeof(lstring)); - ret->s = xmalloc((unsigned) (len + 1)); - (void) memcpy(ret->s, s, (len + 1)); - ret->l = len; - *va_arg(vl, lstring **) = ret; - } - break; - case CALLBACK_NODE: - if (lua_type(L,nres) == LUA_TNIL) { - p = null; - } else { - p = *check_isnode(L,nres); - } - *va_arg(vl, int *) = p; - break; - default: - fprintf(stdout, "invalid return value type"); - goto EXIT; } nres++; } @@ -472,14 +494,13 @@ static int callback_register(lua_State * L) { int cb; const char *s; - int t1, t2; - t1 = lua_type(L,1); + int t1 = lua_type(L,1); + int t2 = lua_type(L,2); if (t1 != LUA_TSTRING) { lua_pushnil(L); lua_pushstring(L, "Invalid arguments to callback.register, first argument must be string."); return 2; } - t2 = lua_type(L,2); if ((t2 != LUA_TFUNCTION) && (t2 != LUA_TNIL) && ((t2 != LUA_TBOOLEAN) && (lua_toboolean(L, 2) == 0))) { lua_pushnil(L); lua_pushstring(L, "Invalid arguments to callback.register."); @@ -507,7 +528,7 @@ static int callback_register(lua_State * L) lua_pushvalue(L, 2); /* the function or nil */ lua_rawseti(L, -2, cb); lua_rawseti(L, LUA_REGISTRYINDEX, callback_callbacks_id); - lua_pushnumber(L, cb); + lua_pushinteger(L, cb); return 1; } diff --git a/Build/source/texk/web2c/luatexdir/lua/lepdflib.cc b/Build/source/texk/web2c/luatexdir/lua/lepdflib.cc index b26f268feb4..00e27863a2c 100644 --- a/Build/source/texk/web2c/luatexdir/lua/lepdflib.cc +++ b/Build/source/texk/web2c/luatexdir/lua/lepdflib.cc @@ -153,17 +153,17 @@ static int l_open_MemStreamPDFDoc(lua_State * L) docstream = luaL_checkstring(L, 1); // stream as Lua string break; case LUA_TLIGHTUSERDATA: - docstream = (const char *) lua_touserdata(L, 1); // stream as sequence of bytes + docstream = (const char *) lua_touserdata(L, 1); // stream as sequence of bytes break; default: - luaL_error(L, "bad argument: string or lightuserdata expected"); + luaL_error(L, "bad argument: string or lightuserdata expected"); } - if (docstream==NULL) - luaL_error(L, "bad document"); + if (docstream==NULL) + luaL_error(L, "bad document"); stream_size = (unsigned long long) luaL_checkint(L, 2);// size of the stream file_id = luaL_checkstring(L, 3); // a symbolic name for this stream, mandatory if (file_id == NULL) - luaL_error(L, "PDFDoc has an invalid id"); + luaL_error(L, "PDFDoc has an invalid id"); if (strlen(file_id) >STREAM_FILE_ID_LEN ) // a limit to the length of the string luaL_error(L, "PDFDoc has a too long id"); docstream_usr = (char *)gmalloc((unsigned) (stream_size + 1)); @@ -183,7 +183,7 @@ static int l_open_MemStreamPDFDoc(lua_State * L) lua_pushnil(L); } else { - if (!(globalParams)) // globalParams could be already created + if (!(globalParams)) // globalParams could be already created globalParams = new GlobalParams(); uout = new_PDFDoc_userdata(L); uout->d = d; @@ -243,20 +243,20 @@ static int l_new_Attribute(lua_State * L) uout->pc = uobj->pc; uout->pd = uobj->pd; } else - lua_pushnil(L); + lua_pushnil(L); return 1; } #define ATTRIBUTE_TYPE_ENTRY(name) \ lua_pushstring(L, #name); \ lua_pushinteger(L, Attribute::name); \ - lua_settable(L,-3) + lua_settable(L,-3) #define STRUCTELEMENT_TYPE_ENTRY(name) \ lua_pushstring(L, #name); \ lua_pushinteger(L, StructElement::name); \ - lua_settable(L,-3) + lua_settable(L,-3) static int l_Attribute_Type(lua_State * L) { @@ -308,74 +308,74 @@ static int l_Attribute_Type(lua_State * L) { static int l_StructElement_Type(lua_State * L) { lua_createtable (L, 0, 50); - STRUCTELEMENT_TYPE_ENTRY(Document); - STRUCTELEMENT_TYPE_ENTRY(Part); - STRUCTELEMENT_TYPE_ENTRY(Art); - STRUCTELEMENT_TYPE_ENTRY(Sect); - STRUCTELEMENT_TYPE_ENTRY(Div); - STRUCTELEMENT_TYPE_ENTRY(BlockQuote); - STRUCTELEMENT_TYPE_ENTRY(Caption); - STRUCTELEMENT_TYPE_ENTRY(NonStruct); - STRUCTELEMENT_TYPE_ENTRY(Index); - STRUCTELEMENT_TYPE_ENTRY(Private); - STRUCTELEMENT_TYPE_ENTRY(Span); - STRUCTELEMENT_TYPE_ENTRY(Quote); - STRUCTELEMENT_TYPE_ENTRY(Note); - STRUCTELEMENT_TYPE_ENTRY(Reference); - STRUCTELEMENT_TYPE_ENTRY(BibEntry); - STRUCTELEMENT_TYPE_ENTRY(Code); - STRUCTELEMENT_TYPE_ENTRY(Link); - STRUCTELEMENT_TYPE_ENTRY(Annot); - STRUCTELEMENT_TYPE_ENTRY(Ruby); - STRUCTELEMENT_TYPE_ENTRY(RB); - STRUCTELEMENT_TYPE_ENTRY(RT); - STRUCTELEMENT_TYPE_ENTRY(RP); - STRUCTELEMENT_TYPE_ENTRY(Warichu); - STRUCTELEMENT_TYPE_ENTRY(WT); - STRUCTELEMENT_TYPE_ENTRY(WP); - STRUCTELEMENT_TYPE_ENTRY(P); - STRUCTELEMENT_TYPE_ENTRY(H); - STRUCTELEMENT_TYPE_ENTRY(H1); - STRUCTELEMENT_TYPE_ENTRY(H2); - STRUCTELEMENT_TYPE_ENTRY(H3); - STRUCTELEMENT_TYPE_ENTRY(H4); - STRUCTELEMENT_TYPE_ENTRY(H5); - STRUCTELEMENT_TYPE_ENTRY(H6); - STRUCTELEMENT_TYPE_ENTRY(L); - STRUCTELEMENT_TYPE_ENTRY(LI); - STRUCTELEMENT_TYPE_ENTRY(Lbl); - STRUCTELEMENT_TYPE_ENTRY(LBody); - STRUCTELEMENT_TYPE_ENTRY(Table); - STRUCTELEMENT_TYPE_ENTRY(TR); - STRUCTELEMENT_TYPE_ENTRY(TH); - STRUCTELEMENT_TYPE_ENTRY(TD); - STRUCTELEMENT_TYPE_ENTRY(THead); - STRUCTELEMENT_TYPE_ENTRY(TFoot); - STRUCTELEMENT_TYPE_ENTRY(TBody); - STRUCTELEMENT_TYPE_ENTRY(Figure); - STRUCTELEMENT_TYPE_ENTRY(Formula); - STRUCTELEMENT_TYPE_ENTRY(Form); - STRUCTELEMENT_TYPE_ENTRY(TOC); - STRUCTELEMENT_TYPE_ENTRY(TOCI); + STRUCTELEMENT_TYPE_ENTRY(Document); + STRUCTELEMENT_TYPE_ENTRY(Part); + STRUCTELEMENT_TYPE_ENTRY(Art); + STRUCTELEMENT_TYPE_ENTRY(Sect); + STRUCTELEMENT_TYPE_ENTRY(Div); + STRUCTELEMENT_TYPE_ENTRY(BlockQuote); + STRUCTELEMENT_TYPE_ENTRY(Caption); + STRUCTELEMENT_TYPE_ENTRY(NonStruct); + STRUCTELEMENT_TYPE_ENTRY(Index); + STRUCTELEMENT_TYPE_ENTRY(Private); + STRUCTELEMENT_TYPE_ENTRY(Span); + STRUCTELEMENT_TYPE_ENTRY(Quote); + STRUCTELEMENT_TYPE_ENTRY(Note); + STRUCTELEMENT_TYPE_ENTRY(Reference); + STRUCTELEMENT_TYPE_ENTRY(BibEntry); + STRUCTELEMENT_TYPE_ENTRY(Code); + STRUCTELEMENT_TYPE_ENTRY(Link); + STRUCTELEMENT_TYPE_ENTRY(Annot); + STRUCTELEMENT_TYPE_ENTRY(Ruby); + STRUCTELEMENT_TYPE_ENTRY(RB); + STRUCTELEMENT_TYPE_ENTRY(RT); + STRUCTELEMENT_TYPE_ENTRY(RP); + STRUCTELEMENT_TYPE_ENTRY(Warichu); + STRUCTELEMENT_TYPE_ENTRY(WT); + STRUCTELEMENT_TYPE_ENTRY(WP); + STRUCTELEMENT_TYPE_ENTRY(P); + STRUCTELEMENT_TYPE_ENTRY(H); + STRUCTELEMENT_TYPE_ENTRY(H1); + STRUCTELEMENT_TYPE_ENTRY(H2); + STRUCTELEMENT_TYPE_ENTRY(H3); + STRUCTELEMENT_TYPE_ENTRY(H4); + STRUCTELEMENT_TYPE_ENTRY(H5); + STRUCTELEMENT_TYPE_ENTRY(H6); + STRUCTELEMENT_TYPE_ENTRY(L); + STRUCTELEMENT_TYPE_ENTRY(LI); + STRUCTELEMENT_TYPE_ENTRY(Lbl); + STRUCTELEMENT_TYPE_ENTRY(LBody); + STRUCTELEMENT_TYPE_ENTRY(Table); + STRUCTELEMENT_TYPE_ENTRY(TR); + STRUCTELEMENT_TYPE_ENTRY(TH); + STRUCTELEMENT_TYPE_ENTRY(TD); + STRUCTELEMENT_TYPE_ENTRY(THead); + STRUCTELEMENT_TYPE_ENTRY(TFoot); + STRUCTELEMENT_TYPE_ENTRY(TBody); + STRUCTELEMENT_TYPE_ENTRY(Figure); + STRUCTELEMENT_TYPE_ENTRY(Formula); + STRUCTELEMENT_TYPE_ENTRY(Form); + STRUCTELEMENT_TYPE_ENTRY(TOC); + STRUCTELEMENT_TYPE_ENTRY(TOCI); lua_pushstring(L, "Unknown"); - lua_pushinteger(L, 0); + lua_pushinteger(L, 0); lua_settable(L,-3); return 1; } static int l_AttributeOwner_Type(lua_State * L) { lua_createtable (L, 0, 12); - lua_pushstring(L, "XML-1.00"); lua_pushinteger(L, Attribute::XML_1_00); lua_settable(L,-3); - lua_pushstring(L, "HTML-3.20"); lua_pushinteger(L, Attribute::HTML_3_20); lua_settable(L,-3); - lua_pushstring(L, "HTML-4.01"); lua_pushinteger(L, Attribute::HTML_4_01); lua_settable(L,-3); - lua_pushstring(L, "OEB-1.00"); lua_pushinteger(L, Attribute::OEB_1_00); lua_settable(L,-3); - lua_pushstring(L, "RTF-1.05"); lua_pushinteger(L, Attribute::RTF_1_05); lua_settable(L,-3); - lua_pushstring(L, "CSS-1.00"); lua_pushinteger(L, Attribute::CSS_1_00); lua_settable(L,-3); - lua_pushstring(L, "CSS-2.00"); lua_pushinteger(L, Attribute::CSS_2_00); lua_settable(L,-3); - lua_pushstring(L, "Layout"); lua_pushinteger(L, Attribute::Layout); lua_settable(L,-3); - lua_pushstring(L, "PrintField"); lua_pushinteger(L, Attribute::PrintField); lua_settable(L,-3); - lua_pushstring(L, "Table"); lua_pushinteger(L, Attribute::Table); lua_settable(L,-3); - lua_pushstring(L, "List"); lua_pushinteger(L, Attribute::List); lua_settable(L,-3); + lua_pushstring(L, "XML-1.00"); lua_pushinteger(L, Attribute::XML_1_00); lua_settable(L,-3); + lua_pushstring(L, "HTML-3.20"); lua_pushinteger(L, Attribute::HTML_3_20); lua_settable(L,-3); + lua_pushstring(L, "HTML-4.01"); lua_pushinteger(L, Attribute::HTML_4_01); lua_settable(L,-3); + lua_pushstring(L, "OEB-1.00"); lua_pushinteger(L, Attribute::OEB_1_00); lua_settable(L,-3); + lua_pushstring(L, "RTF-1.05"); lua_pushinteger(L, Attribute::RTF_1_05); lua_settable(L,-3); + lua_pushstring(L, "CSS-1.00"); lua_pushinteger(L, Attribute::CSS_1_00); lua_settable(L,-3); + lua_pushstring(L, "CSS-2.00"); lua_pushinteger(L, Attribute::CSS_2_00); lua_settable(L,-3); + lua_pushstring(L, "Layout"); lua_pushinteger(L, Attribute::Layout); lua_settable(L,-3); + lua_pushstring(L, "PrintField"); lua_pushinteger(L, Attribute::PrintField); lua_settable(L,-3); + lua_pushstring(L, "Table"); lua_pushinteger(L, Attribute::Table); lua_settable(L,-3); + lua_pushstring(L, "List"); lua_pushinteger(L, Attribute::List); lua_settable(L,-3); lua_pushstring(L, "UserProperties"); lua_pushinteger(L, Attribute::UserProperties);lua_settable(L,-3); return 1; } @@ -496,7 +496,7 @@ static int m_##in##_##function(lua_State * L) \ } #define m_poppler_get_UINT(in, function) \ -m_poppler_get_GUINT(in, function) +m_poppler_get_GUINT(in, function) @@ -509,7 +509,7 @@ static int m_##in##_##function(lua_State * L) \ if (uin->pd != NULL && uin->pd->pc != uin->pc) \ pdfdoc_changed_error(L); \ d = (double) ((in *) uin->d)->function(); \ - lua_pushnumber(L, d); \ + lua_pushnumber(L, d); /* float */ \ return 1; \ } @@ -1619,7 +1619,7 @@ static int m_Object_getInt(lua_State * L) if (uin->pd != NULL && uin->pd->pc != uin->pc) pdfdoc_changed_error(L); if (((Object *) uin->d)->isInt()) - lua_pushnumber(L, ((Object *) uin->d)->getInt()); + lua_pushinteger(L, ((Object *) uin->d)->getInt()); else lua_pushnil(L); return 1; @@ -1632,7 +1632,7 @@ static int m_Object_getReal(lua_State * L) if (uin->pd != NULL && uin->pd->pc != uin->pc) pdfdoc_changed_error(L); if (((Object *) uin->d)->isReal()) - lua_pushnumber(L, ((Object *) uin->d)->getReal()); + lua_pushnumber(L, ((Object *) uin->d)->getReal()); /* float */ else lua_pushnil(L); return 1; @@ -1645,7 +1645,7 @@ static int m_Object_getNum(lua_State * L) if (uin->pd != NULL && uin->pd->pc != uin->pc) pdfdoc_changed_error(L); if (((Object *) uin->d)->isNum()) - lua_pushnumber(L, ((Object *) uin->d)->getNum()); + lua_pushnumber(L, ((Object *) uin->d)->getNum()); /* integer or float */ else lua_pushnil(L); return 1; @@ -1798,7 +1798,7 @@ static int m_Object_arrayGetLength(lua_State * L) pdfdoc_changed_error(L); if (((Object *) uin->d)->isArray()) { len = ((Object *) uin->d)->arrayGetLength(); - lua_pushnumber(L, len); + lua_pushinteger(L, len); } else lua_pushnil(L); return 1; @@ -1877,7 +1877,7 @@ static int m_Object_dictGetLength(lua_State * L) pdfdoc_changed_error(L); if (((Object *) uin->d)->isDict()) { len = ((Object *) uin->d)->dictGetLength(); - lua_pushnumber(L, len); + lua_pushinteger(L, len); } else lua_pushnil(L); return 1; @@ -2385,7 +2385,7 @@ static int m_PDFDoc_##function(lua_State * L) \ pages = ((PdfDocument *) uin->d)->doc->getNumPages(); \ if (i > 0 && i <= pages) { \ d = (double) ((PdfDocument *) uin->d)->doc->function(i); \ - lua_pushnumber(L, d); \ + lua_pushnumber(L, d); /* float */ \ } else \ lua_pushnil(L); \ return 1; \ @@ -2618,16 +2618,16 @@ static int m_PDFRectangle__index(lua_State * L) if (strlen(s) == 2) { if (s[0] == 'x') { if (s[1] == '1') - lua_pushnumber(L, ((PDFRectangle *) uin->d)->x1); + lua_pushnumber(L, ((PDFRectangle *) uin->d)->x1); /* float */ else if (s[1] == '2') - lua_pushnumber(L, ((PDFRectangle *) uin->d)->x2); + lua_pushnumber(L, ((PDFRectangle *) uin->d)->x2); /* float */ else lua_pushnil(L); } else if (s[0] == 'y') { if (s[1] == '1') - lua_pushnumber(L, ((PDFRectangle *) uin->d)->y1); + lua_pushnumber(L, ((PDFRectangle *) uin->d)->y1); /* float */ else if (s[1] == '2') - lua_pushnumber(L, ((PDFRectangle *) uin->d)->y2); + lua_pushnumber(L, ((PDFRectangle *) uin->d)->y2); /* float */ else lua_pushnil(L); } else @@ -2792,7 +2792,7 @@ static const struct luaL_Reg Stream_m[] = { //********************************************************************** // TextSpan -m_poppler_get_GOOSTRING(TextSpan, getText); +m_poppler_get_GOOSTRING(TextSpan, getText); m_poppler__tostring(TextSpan); static const struct luaL_Reg TextSpan_m[] = { @@ -2858,7 +2858,7 @@ static int m_Attribute_getDefaultValue(lua_State * L) pdfdoc_changed_error(L); t = (Attribute::Type) luaL_checkint(L, 2); uout = new_Object_userdata(L); - uout->d = ((Attribute *)uin->d)->getDefaultValue(t) ; + uout->d = ((Attribute *)uin->d)->getDefaultValue(t) ; //uout->atype = ALLOC_LEPDF; uout->pc = uin->pc; uout->pd = uin->pd; @@ -2977,12 +2977,12 @@ m_poppler_get_INT(StructElement, getNumChildren); m_poppler_get_GUINT(StructElement,getRevision); m_poppler_get_UINT(StructElement,getNumAttributes); -m_poppler_get_GOOSTRING(StructElement, getID); -m_poppler_get_GOOSTRING(StructElement, getLanguage); -m_poppler_get_GOOSTRING(StructElement, getTitle); +m_poppler_get_GOOSTRING(StructElement, getID); +m_poppler_get_GOOSTRING(StructElement, getLanguage); +m_poppler_get_GOOSTRING(StructElement, getTitle); m_poppler_get_GOOSTRING(StructElement, getExpandedAbbr); -m_poppler_get_GOOSTRING(StructElement, getAltText); -m_poppler_get_GOOSTRING(StructElement, getActualText); +m_poppler_get_GOOSTRING(StructElement, getAltText); +m_poppler_get_GOOSTRING(StructElement, getActualText); m_poppler_get_poppler(StructElement, StructTreeRoot, getStructTreeRoot); m_poppler__tostring(StructElement); @@ -3021,7 +3021,7 @@ static int m_StructElement_getParentRef(lua_State * L) return 1; } -// Not exactly as the header: +// Not exactly as the header: // Ref = StructElement:getPageRef() // Ref is false if the C++ functione return false static int m_StructElement_getPageRef(lua_State * L) @@ -3073,17 +3073,17 @@ static int m_StructElement_setRevision(lua_State * L) static int m_StructElement_getText(lua_State * L) { GBool i; - GooString *gs; + GooString *gs; udstruct *uin; uin = (udstruct *) luaL_checkudata(L, 1, M_StructElement); if (uin->pd != NULL && uin->pd->pc != uin->pc) pdfdoc_changed_error(L); i = (GBool) lua_toboolean(L, 2); gs = ((StructElement *) uin->d)->getText(i); - if (gs != NULL) - lua_pushlstring(L, gs->getCString(), gs->getLength()); - else - lua_pushnil(L); + if (gs != NULL) + lua_pushlstring(L, gs->getCString(), gs->getLength()); + else + lua_pushnil(L); return 1; } @@ -3098,15 +3098,15 @@ static int m_StructElement_getChild(lua_State * L) pdfdoc_changed_error(L); i = (int) luaL_checkint(L, 2); c = ((StructElement *) uin->d)->getChild(i-1); - if (c != NULL) { + if (c != NULL) { uout = new_StructElement_userdata(L); uout->d = c ; //uout->atype = ALLOC_LEPDF; uout->pc = uin->pc; uout->pd = uin->pd; - } - else - lua_pushnil(L); + } + else + lua_pushnil(L); return 1; } @@ -3135,14 +3135,14 @@ static int m_StructElement_getAttribute(lua_State * L) pdfdoc_changed_error(L); i = (int) luaL_checkint(L, 2); a = ((StructElement *) uin->d)->getAttribute(i-1); - if (a != NULL) { + if (a != NULL) { uout = new_Attribute_userdata(L); uout->d = a ; uout->pc = uin->pc; uout->pd = uin->pd; - } - else - lua_pushnil(L); + } + else + lua_pushnil(L); return 1; } @@ -3177,15 +3177,15 @@ static int m_StructElement_findAttribute(lua_State * L) o = (Attribute::Owner) luaL_checkint(L,2); g = (GBool) lua_toboolean(L, 3); a = ((StructElement *) uin->d)->findAttribute(t,g,o); - + if (a!=NULL){ uout = new_Attribute_userdata(L); uout->d = new Attribute(a->getType(),a->getValue()); uout->atype = ALLOC_LEPDF; uout->pc = uin->pc; uout->pd = uin->pd; - } else - lua_pushnil(L); + } else + lua_pushnil(L); return 1; } @@ -3193,14 +3193,14 @@ static int m_StructElement_findAttribute(lua_State * L) static int m_StructElement_getTextSpans(lua_State * L) { int i ; - udstruct *uin, *uout; + udstruct *uin, *uout; uin = (udstruct *) luaL_checkudata(L, 1, M_StructElement); - if (uin->pd != NULL && uin->pd->pc != uin->pc) - pdfdoc_changed_error(L); - + if (uin->pd != NULL && uin->pd->pc != uin->pc) + pdfdoc_changed_error(L); + if ((((StructElement *) uin->d)->getTextSpans()).size()>0) { - lua_createtable (L, - (int) (((StructElement *) uin->d)->getTextSpans()).size(), + lua_createtable (L, + (int) (((StructElement *) uin->d)->getTextSpans()).size(), 0); for(i=0;i<(int) (((StructElement *) uin->d)->getTextSpans()).size(); i++){ uout = new_TextSpan_userdata(L); @@ -3209,9 +3209,9 @@ static int m_StructElement_getTextSpans(lua_State * L) uout->pc = uin->pc; uout->pd = uin->pd; lua_rawseti(L,-2,i+1); - } - } else - lua_pushnil(L); + } + } else + lua_pushnil(L); return 1; } @@ -3268,8 +3268,8 @@ static int m_StructTreeRoot_getChild(lua_State * L) unsigned int i; udstruct *uin, *uout; StructElement *child ; - StructTreeRoot *root ; - + StructTreeRoot *root ; + uin = (udstruct *) luaL_checkudata(L, 1, M_StructTreeRoot); if (uin->pd != NULL && uin->pd->pc != uin->pc) pdfdoc_changed_error(L); @@ -3291,7 +3291,7 @@ static int m_StructTreeRoot_appendChild(lua_State * L) { udstruct *uin, *uin_child; StructElement *child ; - StructTreeRoot *root ; + StructTreeRoot *root ; uin = (udstruct *) luaL_checkudata(L, 1, M_StructTreeRoot); if (uin->pd != NULL && uin->pd->pc != uin->pc) pdfdoc_changed_error(L); @@ -3310,8 +3310,8 @@ static int m_StructTreeRoot_findParentElement(lua_State * L) unsigned int i; udstruct *uin, *uout; const StructElement *parent ; - StructTreeRoot *root ; - + StructTreeRoot *root ; + uin = (udstruct *) luaL_checkudata(L, 1, M_StructTreeRoot); if (uin->pd != NULL && uin->pd->pc != uin->pc) pdfdoc_changed_error(L); @@ -3324,7 +3324,7 @@ static int m_StructTreeRoot_findParentElement(lua_State * L) uout->atype = ALLOC_LEPDF; uout->pc = uin->pc; uout->pd = uin->pd; - } else + } else lua_pushnil(L); return 1; } diff --git a/Build/source/texk/web2c/luatexdir/lua/lfontlib.c b/Build/source/texk/web2c/luatexdir/lua/lfontlib.c index fa40150370c..2e05f5f3327 100644 --- a/Build/source/texk/web2c/luatexdir/lua/lfontlib.c +++ b/Build/source/texk/web2c/luatexdir/lua/lfontlib.c @@ -37,18 +37,14 @@ static int get_fontid(void) static int font_read_tfm(lua_State * L) { - internal_font_number f; - scaled s; - int k; - const char *cnom; if (lua_type(L, 1) == LUA_TSTRING) { - cnom = lua_tostring(L, 1); + const char *cnom = lua_tostring(L, 1); if (lua_type(L, 2) == LUA_TNUMBER) { - s = (int) lua_tonumber(L, 2); + scaled s = (int) lua_tointeger(L, 2); if (strlen(cnom)) { - f = get_fontid(); + internal_font_number f = get_fontid(); if (read_tfm_info(f, cnom, s)) { - k = font_to_lua(L, f); + int k = font_to_lua(L, f); delete_font(f); return k; } else { @@ -70,13 +66,11 @@ static int font_read_tfm(lua_State * L) static int font_read_vf(lua_State * L) { - int i; - const char *cnom; if (lua_type(L, 1) == LUA_TSTRING) { - cnom = lua_tostring(L, 1); + const char *cnom = lua_tostring(L, 1); if (strlen(cnom)) { if (lua_type(L, 2) == LUA_TNUMBER) { - i = (int) lua_tonumber(L, 2); + int i = lua_tointeger(L, 2); return make_vf_table(L, cnom, (scaled) i); } else { luaL_error(L, "expected an integer size as second argument"); @@ -90,8 +84,7 @@ static int font_read_vf(lua_State * L) static int tex_current_font(lua_State * L) { - int i; - i = (int) luaL_optinteger(L, 1, 0); + int i = luaL_optinteger(L, 1, 0); if (i > 0) { if (is_valid_font(i)) { zset_cur_font(i); @@ -101,23 +94,22 @@ static int tex_current_font(lua_State * L) return 2; /* not reached */ } } else { - lua_pushnumber(L, get_cur_font()); + lua_pushinteger(L, get_cur_font()); return 1; } } static int tex_max_font(lua_State * L) { - lua_pushnumber(L, max_font_id()); + lua_pushinteger(L, max_font_id()); return 1; } static int tex_each_font_next(lua_State * L) { - int i, m; /* id */ - m = (int) lua_tonumber(L, 1); - i = (int) lua_tonumber(L, 2); + int m = lua_tointeger(L, 1); + int i = lua_tointeger(L, 2); i++; while (i <= m && !is_valid_font(i)) i++; @@ -125,7 +117,7 @@ static int tex_each_font_next(lua_State * L) lua_pushnil(L); return 1; } else { - lua_pushnumber(L, i); + lua_pushinteger(L, i); if (!font_to_lua(L, i)) lua_pushnil(L); return 2; @@ -135,15 +127,14 @@ static int tex_each_font_next(lua_State * L) static int tex_each_font(lua_State * L) { lua_pushcclosure(L, tex_each_font_next, 0); - lua_pushnumber(L, max_font_id()); - lua_pushnumber(L, 0); + lua_pushinteger(L, max_font_id()); + lua_pushinteger(L, 0); return 3; } static int frozenfont(lua_State * L) { - int i; - i = (int) luaL_checkinteger(L, 1); + int i = luaL_checkinteger(L, 1); if (i) { if (is_valid_font(i)) { if (font_touched(i) || font_used(i)) { @@ -164,8 +155,7 @@ static int frozenfont(lua_State * L) static int setfont(lua_State * L) { - int i; - i = (int) luaL_checkinteger(L, -2); + int i = luaL_checkinteger(L, -2); if (i) { luaL_checktype(L, -1, LUA_TTABLE); if (is_valid_font(i)) { @@ -185,29 +175,10 @@ 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 + int i = get_fontid(); luaL_checktype(L, -1, LUA_TTABLE); - i = get_fontid(); -#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); + lua_pushinteger(L, i); return 1; } else { lua_pop(L, 1); /* pop the broken table */ @@ -221,7 +192,7 @@ static int deffont(lua_State * L) static int nextfontid(lua_State * L) { int i = get_fontid(); - lua_pushnumber(L, i); + lua_pushinteger(L, i); delete_font(i); return 1; } @@ -229,8 +200,7 @@ static int nextfontid(lua_State * L) static int getfont(lua_State * L) { - int i; - i = (int) luaL_checkinteger(L, -1); + int i = luaL_checkinteger(L, -1); if (i && is_valid_font(i) && font_to_lua(L, i)) return 1; lua_pushnil(L); @@ -240,21 +210,18 @@ static int getfont(lua_State * L) static int getfontid(lua_State * L) { - const char *s; - size_t ff; - int cs; - int f; if (lua_type(L, 1) == LUA_TSTRING) { - s = lua_tolstring(L, 1, &ff); - cs = string_lookup(s, ff); - if (cs == undefined_control_sequence || cs == undefined_cs_cmd - || eq_type(cs) != set_font_cmd) { + size_t ff; + const char *s = lua_tolstring(L, 1, &ff); + int cs = string_lookup(s, ff); + int f; + if (cs == undefined_control_sequence || cs == undefined_cs_cmd || eq_type(cs) != set_font_cmd) { lua_pushstring(L, "not a valid font csname"); f = -1; } else { f = equiv(cs); } - lua_pushnumber(L, f); + lua_pushinteger(L, f); } else { luaL_error(L, "expected font csname string as argument"); } @@ -290,24 +257,23 @@ int luaopen_font(lua_State * L) static int l_vf_char(lua_State * L) { int k, w; - /*int ex = 0;*/ /* Wrong! TODO */ vf_struct *vsp = static_pdf->vfstruct; packet_stack_record *mat_p; internal_font_number lf = vsp->lf; int ex_glyph = vsp->ex_glyph/1000; if (!vsp->vflua) normal_error("vf", "vf.char() outside virtual font"); - k = (int) luaL_checkinteger(L, 1); - if (!char_exists(lf, (int) k)) { - char_warning(lf, (int) k); + k = luaL_checkinteger(L, 1); + if (!char_exists(lf, k)) { + char_warning(lf, k); } else { - if (has_packet(lf, (int) k)) - do_vf_packet(static_pdf, lf, (int) k, ex_glyph); + if (has_packet(lf, k)) + do_vf_packet(static_pdf, lf, k, ex_glyph); else - backend_out[glyph_node] (static_pdf, lf, (int) k, ex_glyph); + backend_out[glyph_node] (static_pdf, lf, k, ex_glyph); } mat_p = &(vsp->packet_stack[vsp->packet_stack_level]); - w = char_width(lf, (int) k); + w = char_width(lf, k); mat_p->pos.h += round_xn_over_d(w, 1000 + ex_glyph, 1000); synch_pos_with_cur(static_pdf->posstruct, vsp->refpos, mat_p->pos); return 0; @@ -355,7 +321,7 @@ static int l_vf_node(lua_State * L) if (!vsp->vflua) normal_error("vf", "vf.node() outside virtual font"); k = (int) luaL_checkinteger(L, 1); - hlist_out(static_pdf, (halfword) k); + hlist_out(static_pdf, (halfword) k, 0); return 0; } @@ -423,7 +389,7 @@ static int l_vf_rule(lua_State * L) size.h = store_scaled_f(size.h, vsp->fs_f); size.v = store_scaled_f(size.v, vsp->fs_f); if (size.h > 0 && size.v > 0) - pdf_place_rule(static_pdf, 0, size); /* the 0 is unused */ + backend_out[rule_node](static_pdf, 0, size); /* the 0 is unused */ mat_p = &(vsp->packet_stack[vsp->packet_stack_level]); mat_p->pos.h += size.h; synch_pos_with_cur(static_pdf->posstruct, vsp->refpos, mat_p->pos); diff --git a/Build/source/texk/web2c/luatexdir/lua/limglib.c b/Build/source/texk/web2c/luatexdir/lua/limglib.c index 5a1943b5245..22dc80e38d6 100644 --- a/Build/source/texk/web2c/luatexdir/lua/limglib.c +++ b/Build/source/texk/web2c/luatexdir/lua/limglib.c @@ -25,78 +25,9 @@ #include "lua.h" #include "lauxlib.h" -#define IMG_ENV "image.env" +#define img_types_max 7 -/**********************************************************************/ - -#ifdef DEBUG -void stackDump(lua_State * L, char *s) -{ - int i, t, top = lua_gettop(L); - printf("\n=== stackDump <%s>: ", s); - for (i = top; i >= 1; i--) { - t = lua_type(L, i); - printf("%d: ", i); - switch (t) { - case LUA_TSTRING: - printf("`%s'", lua_tostring(L, i)); - break; - case LUA_TBOOLEAN: - printf(lua_toboolean(L, i) ? "true" : "false"); - break; - case LUA_TNUMBER: - printf("%g", (double) lua_tonumber(L, i)); - break; - default: - printf("%s", lua_typename(L, t)); - break; - } - /* insert a separator */ - printf(" "); - } - printf("\n"); -} -#endif - -/**********************************************************************/ - -typedef enum { P__ZERO, P_ATTR, P_BBOX, P_COLORDEPTH, P_COLORSPACE, P_DEPTH, - P_FILENAME, P_FILEPATH, P_HEIGHT, P_IMAGETYPE, P_INDEX, P_OBJNUM, - P_PAGEBOX, P_PAGE, P_TOTALPAGES, P_ROTATION, P_STREAM, P_TRANSFORM, - P_VISIBLEFILENAME, P_WIDTH, P_XRES, P_XSIZE, P_YRES, P_YSIZE, P__SENTINEL -} parm_idx; - -static const parm_struct img_parms[] = { - {NULL, P__ZERO}, /* dummy; lua indices run from 1 */ - {"attr", P_ATTR}, - {"bbox", P_BBOX}, - {"colordepth", P_COLORDEPTH}, - {"colorspace", P_COLORSPACE}, - {"depth", P_DEPTH}, - {"filename", P_FILENAME}, - {"filepath", P_FILEPATH}, - {"height", P_HEIGHT}, - {"imagetype", P_IMAGETYPE}, - {"index", P_INDEX}, - {"objnum", P_OBJNUM}, - {"pagebox", P_PAGEBOX}, - {"page", P_PAGE}, - {"pages", P_TOTALPAGES}, - {"rotation", P_ROTATION}, - {"stream", P_STREAM}, - {"transform", P_TRANSFORM}, - {"visiblefilename", P_VISIBLEFILENAME}, - {"width", P_WIDTH}, - {"xres", P_XRES}, - {"xsize", P_XSIZE}, - {"yres", P_YRES}, - {"ysize", P_YSIZE}, - {NULL, P__SENTINEL} -}; - -#define imgtype_max 7 - -const char *imgtype_s[] = { +const char *img_types[] = { "none", "pdf", "png", @@ -108,368 +39,18 @@ const char *imgtype_s[] = { NULL }; -#define pagebox_max 5 - -const char *pdfboxspec_s[] = { - "none", - "media", - "crop", - "bleed", - "trim", - "art", - NULL -}; - -/**********************************************************************/ - -static void image_to_lua(lua_State * L, image * a) -{ /* key user ... */ - int i, j; - image_dict *d = img_dict(a); - assert(d != NULL); - lua_pushstring(L, IMG_ENV); /* s k u ... */ - lua_gettable(L, LUA_REGISTRYINDEX); /* t k u ... */ - lua_pushvalue(L, -2); /* k t k u ... */ - lua_gettable(L, -2); /* i? t k u ... */ - if (lua_type(L, -1) != LUA_TNUMBER) /* !i t k u ... */ - luaL_error(L, "image_to_lua(): %s is not a valid image key", lua_tostring(L, -3)); - i = (int) lua_tointeger(L, -1); /* i t k u ... */ - lua_pop(L, 3); /* u ... */ - switch (i) { - case P_WIDTH: - if (is_wd_running(a)) - lua_pushnil(L); - else - lua_pushinteger(L, img_width(a)); - break; - case P_HEIGHT: - if (is_ht_running(a)) - lua_pushnil(L); - else - lua_pushinteger(L, img_height(a)); - break; - case P_DEPTH: - if (is_dp_running(a)) - lua_pushnil(L); - else - lua_pushinteger(L, img_depth(a)); - break; - case P_TRANSFORM: - lua_pushinteger(L, img_transform(a)); - break; - /* now follow all image_dict entries */ - case P_FILENAME: - if (img_filename(d) == NULL || strlen(img_filename(d)) == 0) - lua_pushnil(L); - else - lua_pushstring(L, img_filename(d)); - break; - case P_VISIBLEFILENAME: - if (img_visiblefilename(d) == NULL - || strlen(img_visiblefilename(d)) == 0) - lua_pushnil(L); - else - lua_pushstring(L, img_visiblefilename(d)); - break; - case P_FILEPATH: - if (img_filepath(d) == NULL || strlen(img_filepath(d)) == 0) - lua_pushnil(L); - else - lua_pushstring(L, img_filepath(d)); - break; - case P_ATTR: - if (img_attr(d) == NULL || strlen(img_attr(d)) == 0) - lua_pushnil(L); - else - lua_pushstring(L, img_attr(d)); - break; - case P_PAGE: - if (img_pagename(d) != NULL && strlen(img_pagename(d)) != 0) - lua_pushstring(L, img_pagename(d)); - else - lua_pushinteger(L, img_pagenum(d)); - break; - case P_TOTALPAGES: - lua_pushinteger(L, img_totalpages(d)); - break; - case P_XSIZE: /* Modify by /Rotate only for output */ - if ((img_rotation(d) & 1) == 0) - lua_pushinteger(L, img_xsize(d)); - else - lua_pushinteger(L, img_ysize(d)); - break; - case P_YSIZE: /* Modify by /Rotate only for output */ - if ((img_rotation(d) & 1) == 0) - lua_pushinteger(L, img_ysize(d)); - else - lua_pushinteger(L, img_xsize(d)); - break; - case P_XRES: - lua_pushinteger(L, img_xres(d)); - break; - case P_YRES: - lua_pushinteger(L, img_yres(d)); - break; - case P_ROTATION: - lua_pushinteger(L, img_rotation(d)); - break; - case P_COLORSPACE: - if (img_colorspace(d) == 0) - lua_pushnil(L); - else - lua_pushinteger(L, img_colorspace(d)); - break; - case P_COLORDEPTH: - if (img_colordepth(d) == 0) - lua_pushnil(L); - else - lua_pushinteger(L, img_colordepth(d)); - break; - case P_IMAGETYPE: - j = img_type(d); - if (j >= 0 && j <= imgtype_max) { - if (j == IMG_TYPE_NONE) - lua_pushnil(L); - else - lua_pushstring(L, imgtype_s[j]); - } else - assert(0); - break; - case P_PAGEBOX: - j = img_pagebox(d); - if (j >= 0 && j <= pagebox_max) { - if (j == PDF_BOX_SPEC_NONE) - lua_pushnil(L); - else - lua_pushstring(L, pdfboxspec_s[j]); - } else - assert(0); - break; - case P_BBOX: - if (!img_is_bbox(d)) { - img_bbox(d)[0] = img_xorig(d); - img_bbox(d)[1] = img_yorig(d); - img_bbox(d)[2] = img_xorig(d) + img_xsize(d); - img_bbox(d)[3] = img_yorig(d) + img_ysize(d); - } - lua_newtable(L); - lua_pushinteger(L, 1); - lua_pushinteger(L, img_bbox(d)[0]); - lua_settable(L, -3); - lua_pushinteger(L, 2); - lua_pushinteger(L, img_bbox(d)[1]); - lua_settable(L, -3); - lua_pushinteger(L, 3); - lua_pushinteger(L, img_bbox(d)[2]); - lua_settable(L, -3); - lua_pushinteger(L, 4); - lua_pushinteger(L, img_bbox(d)[3]); - lua_settable(L, -3); - break; - case P_OBJNUM: - if (img_objnum(d) == 0) - lua_pushnil(L); - else - lua_pushinteger(L, img_objnum(d)); - break; - case P_INDEX: - if (img_index(d) == 0) - lua_pushnil(L); - else - lua_pushinteger(L, img_index(d)); - break; - case P_STREAM: - if (img_type(d) != IMG_TYPE_PDFSTREAM || img_pdfstream_ptr(d) == NULL - || img_pdfstream_stream(d) == NULL - || strlen(img_pdfstream_stream(d)) == 0) - lua_pushnil(L); - else - lua_pushstring(L, img_pdfstream_stream(d)); - break; - default: - assert(0); - } /* v u ... */ -} - -static void lua_to_image(lua_State * L, image * a) -{ /* value key table ... */ - int i; - image_dict *d = img_dict(a); - assert(d != NULL); - lua_pushstring(L, IMG_ENV); /* s v k t ... */ - lua_gettable(L, LUA_REGISTRYINDEX); /* t v k t ... */ - lua_pushvalue(L, -3); /* k t v k t ... */ - lua_gettable(L, -2); /* i? t v k t ... */ - if (lua_type(L, -1) != LUA_TNUMBER) /* !i t v k t ... */ - luaL_error(L, "lua_to_image(): %s is not a valid image key", lua_tostring(L, -4)); - i = (int) lua_tointeger(L, -1); /* i t v k t ... */ - lua_pop(L, 2); /* v k t ... */ - switch (i) { - case P_WIDTH: - if (lua_isnil(L, -1)) - set_wd_running(a); - else if (lua_type(L, -1) == LUA_TNUMBER) - img_width(a) = (int) lua_tointeger(L, -1); - else if (lua_type(L, -1) == LUA_TSTRING) - img_width(a) = dimen_to_number(L, lua_tostring(L, -1)); - else - luaL_error(L, "image.width needs integer or nil value or dimension string"); - break; - case P_HEIGHT: - if (lua_isnil(L, -1)) - set_ht_running(a); - else if (lua_type(L, -1) == LUA_TNUMBER) - img_height(a) = (int) lua_tointeger(L, -1); - else if (lua_type(L, -1) == LUA_TSTRING) - img_height(a) = dimen_to_number(L, lua_tostring(L, -1)); - else - luaL_error(L, "image.height needs integer or nil value or dimension string"); - break; - case P_DEPTH: - if (lua_isnil(L, -1)) - set_dp_running(a); - else if (lua_type(L, -1) == LUA_TNUMBER) - img_depth(a) = (int) lua_tointeger(L, -1); - else if (lua_type(L, -1) == LUA_TSTRING) - img_depth(a) = dimen_to_number(L, lua_tostring(L, -1)); - else - luaL_error(L, "image.depth needs integer or nil value or dimension string"); - break; - case P_TRANSFORM: - if (lua_type(L, -1) == LUA_TNUMBER) - img_transform(a) = (int) lua_tointeger(L, -1); - else - luaL_error(L, "image.transform needs integer value"); - break; - /* now follow all image_dict entries */ - case P_FILENAME: - if (img_state(d) >= DICT_FILESCANNED) - luaL_error(L, "image.filename is now read-only"); - if (img_type(d) == IMG_TYPE_PDFSTREAM) - luaL_error(L, "image.filename can't be used with image.stream"); - if (lua_type(L, -1) == LUA_TSTRING) { - xfree(img_filename(d)); - img_filename(d) = xstrdup(lua_tostring(L, -1)); - } else - luaL_error(L, "image.filename needs string value"); - break; - case P_VISIBLEFILENAME: - if (img_state(d) >= DICT_FILESCANNED) - luaL_error(L, "image.visiblefilename is now read-only"); - if (img_type(d) == IMG_TYPE_PDFSTREAM) - luaL_error(L, "image.visiblefilename can't be used with image.stream"); - if (lua_type(L, -1) == LUA_TSTRING) { - xfree(img_visiblefilename(d)); - img_visiblefilename(d) = xstrdup(lua_tostring(L, -1)); - } else - luaL_error(L, "image.visiblefilename needs string value"); - break; - case P_ATTR: - if (img_state(d) >= DICT_FILESCANNED) - luaL_error(L, "image.attr is now read-only"); - if (lua_type(L, -1) == LUA_TSTRING) { - xfree(img_attr(d)); - img_attr(d) = xstrdup(lua_tostring(L, -1)); - } else if (lua_type(L, -1) == LUA_TNIL) { - xfree(img_attr(d)); - } else - luaL_error(L, "image.attr needs string or nil value"); - break; - case P_PAGE: - if (img_state(d) >= DICT_FILESCANNED) - luaL_error(L, "image.page is now read-only"); - if (lua_type(L, -1) == LUA_TSTRING) { - xfree(img_pagename(d)); - img_pagename(d) = xstrdup(lua_tostring(L, -1)); - img_pagenum(d) = 0; - } else if (lua_type(L, -1) == LUA_TNUMBER) { - img_pagenum(d) = (int) lua_tointeger(L, -1); - xfree(img_pagename(d)); - } else - luaL_error(L, "image.page needs integer or string value"); - break; - case P_COLORSPACE: - if (img_state(d) >= DICT_FILESCANNED) - luaL_error(L, "image.colorspace is now read-only"); - if (lua_isnil(L, -1)) - img_colorspace(d) = 0; - else if (lua_type(L, -1) == LUA_TNUMBER) - img_colorspace(d) = (int) lua_tointeger(L, -1); - else - luaL_error(L, "image.colorspace needs integer or nil value"); - break; - case P_PAGEBOX: - if (img_state(d) >= DICT_FILESCANNED) - luaL_error(L, "image.pagebox is now read-only"); - if (lua_type(L, -1) == LUA_TNIL) - img_pagebox(d) = PDF_BOX_SPEC_NONE; - else if (lua_type(L, -1) == LUA_TSTRING) - img_pagebox(d) = luaL_checkoption(L, -1, "none", pdfboxspec_s); - else - luaL_error(L, "image.pagebox needs string or nil value"); - break; - case P_BBOX: - if (img_state(d) >= DICT_FILESCANNED) - luaL_error(L, "image.bbox is now read-only"); - if (!lua_istable(L, -1)) - luaL_error(L, "image.bbox needs table value"); - if (lua_rawlen(L, -1) != 4) - luaL_error(L, "image.bbox table must have exactly 4 elements"); - for (i = 1; i <= 4; i++) { /* v k t ... */ - lua_pushinteger(L, i); /* idx v k t ... */ - lua_gettable(L, -2); /* int v k t ... */ - if (lua_type(L, -1) == LUA_TNUMBER) - img_bbox(d)[i - 1] = (int) lua_tointeger(L, -1); - else if (lua_type(L, -1) == LUA_TSTRING) - img_bbox(d)[i - 1] = dimen_to_number(L, lua_tostring(L, -1)); - else - luaL_error(L, "image.bbox table needs integer value or dimension string elements"); - lua_pop(L, 1); /* v k t ... */ - } - img_set_bbox(d); - break; - case P_STREAM: - if (img_filename(d) != NULL) - luaL_error(L, "image.stream can't be used with image.filename"); - if (img_state(d) >= DICT_FILESCANNED) - luaL_error(L, "image.stream is now read-only"); - if (img_pdfstream_ptr(d) == NULL) - new_img_pdfstream_struct(d); - xfree(img_pdfstream_stream(d)); - img_pdfstream_stream(d) = xstrdup(lua_tostring(L, -1)); - img_type(d) = IMG_TYPE_PDFSTREAM; - break; - case P_FILEPATH: - case P_TOTALPAGES: - case P_XSIZE: - case P_YSIZE: - case P_XRES: - case P_YRES: - case P_ROTATION: - case P_IMAGETYPE: - case P_OBJNUM: - case P_INDEX: - case P_COLORDEPTH: - luaL_error(L, "image.%s is a read-only variable", img_parms[i].name); - break; - default: - assert(0); - } /* v k t ... */ -} - -/**********************************************************************/ - static void copy_image(lua_State * L, lua_Number scale) { image *a, **aa, *b, **bb; - if (lua_gettop(L) != 1) - luaL_error(L, "img.copy() needs exactly 1 argument"); - aa = (image **) luaL_checkudata(L, 1, TYPE_IMG); /* a */ - lua_pop(L, 1); /* - */ + image_dict *d; + if (lua_gettop(L) == 0) + luaL_error(L, "img.copy needs an image as argument"); + aa = (image **) luaL_checkudata(L, 1, TYPE_IMG); /* a */ + lua_pop(L, 1); /* - */ a = *aa; - bb = (image **) lua_newuserdata(L, sizeof(image *)); /* b */ - luaL_getmetatable(L, TYPE_IMG); /* m b */ - lua_setmetatable(L, -2); /* b */ + bb = (image **) lua_newuserdata(L, sizeof(image *)); /* b */ + luaL_getmetatable(L, TYPE_IMG); /* m b */ + lua_setmetatable(L, -2); /* b */ b = *bb = new_image(); if (!is_wd_running(a)) img_width(b) = do_zround(img_width(a) * scale); @@ -480,101 +61,115 @@ static void copy_image(lua_State * L, lua_Number scale) img_transform(b) = img_transform(a); img_dict(b) = img_dict(a); if (img_dictref(a) != LUA_NOREF) { - lua_rawgeti(L, LUA_REGISTRYINDEX, img_dictref(a)); /* ad b */ - img_dictref(b) = luaL_ref(L, LUA_REGISTRYINDEX); /* b */ + lua_rawgeti(L, LUA_REGISTRYINDEX, img_dictref(a)); /* ad b */ + img_dictref(b) = luaL_ref(L, LUA_REGISTRYINDEX); /* b */ + d = img_dict(*aa); + img_luaref(d) += 1; } else assert(img_state(img_dict(a)) >= DICT_REFERED); } -/**********************************************************************/ +static void lua_to_image(lua_State * L, image * a, image_dict * d); int l_new_image(lua_State * L) { image *a, **aa; image_dict **add; - if (lua_gettop(L) > 1) - luaL_error(L, "img.new() needs maximum 1 argument"); - if (lua_gettop(L) == 1 && !lua_istable(L, -1)) - luaL_error(L, "img.new() needs table as optional argument"); /* (t) */ - aa = (image **) lua_newuserdata(L, sizeof(image *)); /* i (t) */ - luaL_getmetatable(L, TYPE_IMG); /* m i (t) */ - lua_setmetatable(L, -2); /* i (t) */ + if (lua_gettop(L) > 0 && ! lua_istable(L, -1)) + luaL_error(L, "img.new needs table as optional argument"); /* (t) */ + aa = (image **) lua_newuserdata(L, sizeof(image *)); /* i (t) */ + luaL_getmetatable(L, TYPE_IMG); /* m i (t) */ + lua_setmetatable(L, -2); /* i (t) */ a = *aa = new_image(); - add = (image_dict **) lua_newuserdata(L, sizeof(image_dict *)); /* ad i (t) */ - luaL_getmetatable(L, TYPE_IMG_DICT); /* m ad i (t) */ - lua_setmetatable(L, -2); /* ad i (t) */ + add = (image_dict **) lua_newuserdata(L, sizeof(image_dict *)); /* ad i (t) */ + luaL_getmetatable(L, TYPE_IMG_DICT); /* m ad i (t) */ + lua_setmetatable(L, -2); /* ad i (t) */ img_dict(a) = *add = new_image_dict(); - img_dictref(a) = luaL_ref(L, LUA_REGISTRYINDEX); /* i (t) */ - if (lua_gettop(L) == 2) { /* i t, else just i */ - lua_insert(L, -2); /* t i */ - lua_pushnil(L); /* n t i (1st key for iterator) */ - while (lua_next(L, -2) != 0) { /* v k t i */ - lua_to_image(L, a); /* v k t i */ - lua_pop(L, 1); /* k t i */ - } /* t i */ - lua_pop(L, 1); /* i */ - } /* i */ - return 1; /* i */ + img_dictref(a) = luaL_ref(L, LUA_REGISTRYINDEX); /* i (t) */ + img_luaref(*add) += 1; + if (lua_gettop(L) == 2) { /* i t, else just i */ + lua_insert(L, -2); /* t i */ + lua_pushnil(L); /* n t i (1st key for iterator) */ + while (lua_next(L, -2) != 0) { /* v k t i */ + lua_to_image(L, a, *add); /* v k t i */ + lua_pop(L, 1); /* k t i */ + } /* t i */ + lua_pop(L, 1); /* i */ + } /* i */ + return 1; /* i */ } static int l_copy_image(lua_State * L) { - if (lua_gettop(L) != 1) - luaL_error(L, "img.copy() needs exactly 1 argument"); - if (lua_istable(L, 1)) - (void) l_new_image(L); /* image --- if everything worked well */ - else - (void) copy_image(L, 1.0); /* image */ - return 1; /* image */ + if (lua_gettop(L) != 1) { + luaL_error(L, "img.copy needs an image as argument"); + } else if (lua_istable(L, 1)) { + (void) l_new_image(L); + } else { + (void) copy_image(L, 1.0); + } + return 1; } static void read_scale_img(image * a) { image_dict *ad; - assert(a != NULL); - ad = img_dict(a); - assert(ad != NULL); - if (img_state(ad) == DICT_NEW) { - if (img_type(ad) == IMG_TYPE_PDFSTREAM) - check_pdfstream_dict(ad); - else { - fix_pdf_minorversion(static_pdf); - read_img(static_pdf, ad, pdf_minor_version, pdf_inclusion_errorlevel); + if (a == NULL) { + luaL_error(Luas, "the image scaler needs a valid image"); + } else { + ad = img_dict(a); + if (a == NULL) { + luaL_error(Luas, "the image scaler needs a valid dictionary"); + } else { + if (img_state(ad) == DICT_NEW) { + if (img_type(ad) == IMG_TYPE_PDFSTREAM) + check_pdfstream_dict(ad); + else { + read_img(ad); + } + } + if (is_wd_running(a) || is_ht_running(a) || is_dp_running(a)) { + img_dimen(a) = scale_img(ad, img_dimen(a), img_transform(a)); + } } } - if (is_wd_running(a) || is_ht_running(a) || is_dp_running(a)) - img_dimen(a) = scale_img(ad, img_dimen(a), img_transform(a)); } static int l_scan_image(lua_State * L) { image *a, **aa; if (lua_gettop(L) != 1) - luaL_error(L, "img.scan() needs exactly 1 argument"); + luaL_error(L, "img.scan needs exactly 1 argument"); if (lua_istable(L, 1)) - (void) l_new_image(L); /* image --- if everything worked well */ - aa = (image **) luaL_checkudata(L, 1, TYPE_IMG); /* image */ + (void) l_new_image(L); + aa = (image **) luaL_checkudata(L, 1, TYPE_IMG); a = *aa; - check_o_mode(static_pdf, "img.scan()", 1 << OMODE_PDF, false); - /* flush_str(last_tex_string); *//* ?? */ + check_o_mode(static_pdf, "img.scan", 1 << OMODE_PDF, false); read_scale_img(a); - return 1; /* image */ + return 1; } -static halfword img_to_node(image * a) +static halfword img_to_node(lua_State * L, image * a) { image_dict *ad; - halfword n; - assert(a != NULL); - ad = img_dict(a); - assert(ad != NULL); - assert(img_objnum(ad) != 0); - n = new_rule(image_rule); - rule_index(n) = img_index(ad); - width(n) = img_width(a); - height(n) = img_height(a); - depth(n) = img_depth(a); - rule_transform(n) = img_transform(a); + halfword n = null; + if (a == NULL) { + luaL_error(L, "img.tonode needs a valid image"); + } else { + ad = img_dict(a); + if (a == NULL) { + luaL_error(L, "img.tonode image has no dictionary"); + } else if (img_objnum(ad) == 0) { + luaL_error(L, "img.tonode got image without object number"); + } else { + n = new_rule(image_rule); + rule_index(n) = img_index(ad); + width(n) = img_width(a); + height(n) = img_height(a); + depth(n) = img_depth(a); + rule_transform(n) = img_transform(a); + } + } return n; } @@ -586,22 +181,25 @@ typedef enum { } wrtype_e; const char *wrtype_s[] = { - "img.write()", "img.immediatewrite()", "img.node()", "write vf image" + "img.write()", + "img.immediatewrite()", + "img.node()", + "write vf image" }; static void setup_image(PDF pdf, image * a, wrtype_e writetype) { image_dict *ad; - assert(a != NULL); + if (a == NULL) + luaL_error(Luas, "no valid image passed"); /* todo, also check in caller */ ad = img_dict(a); check_o_mode(pdf, wrtype_s[writetype], 1 << OMODE_PDF, false); - /* flush_str(last_tex_string); *//* ?? */ read_scale_img(a); - if (img_objnum(ad) == 0) { /* latest needed just before out_img() */ + if (img_objnum(ad) == 0) { /* latest needed just before out_img() */ pdf->ximage_count++; img_objnum(ad) = pdf_create_obj(pdf, obj_type_ximage, pdf->ximage_count); img_index(ad) = pdf->ximage_count; - idict_to_array(ad); /* now ad is read-only */ + idict_to_array(ad); /* from now on ad is read-only */ obj_data_ptr(pdf, pdf->obj_ptr) = img_index(ad); } } @@ -612,28 +210,28 @@ static void write_image_or_node(lua_State * L, wrtype_e writetype) image_dict *ad; halfword n; if (lua_gettop(L) != 1) - luaL_error(L, "%s needs exactly 1 argument", wrtype_s[writetype]); + luaL_error(L, "%s expects an argument", wrtype_s[writetype]); if (lua_istable(L, 1)) - (void) l_new_image(L); /* image --- if everything worked well */ - aa = (image **) luaL_checkudata(L, 1, TYPE_IMG); /* image */ + (void) l_new_image(L); + aa = (image **) luaL_checkudata(L, 1, TYPE_IMG); a = *aa; ad = img_dict(a); setup_image(static_pdf, a, writetype); switch (writetype) { - case WR_WRITE: - n = img_to_node(a); - tail_append(n); - break; /* image */ - case WR_IMMEDIATEWRITE: - write_img(static_pdf, ad); - break; /* image */ - case WR_NODE: /* image */ - lua_pop(L, 1); /* - */ - n = img_to_node(a); - lua_nodelib_push_fast(L, n); - break; /* node */ - default: - assert(0); + case WR_WRITE: + n = img_to_node(L, a); + tail_append(n); + break; + case WR_IMMEDIATEWRITE: + write_img(static_pdf, ad); + break; + case WR_NODE: + lua_pop(L, 1); /* - */ + n = img_to_node(L, a); + lua_nodelib_push_fast(L, n); + break; + default: + assert(0); } if (img_state(ad) < DICT_REFERED) img_state(ad) = DICT_REFERED; @@ -642,129 +240,429 @@ static void write_image_or_node(lua_State * L, wrtype_e writetype) static int l_write_image(lua_State * L) { write_image_or_node(L, WR_WRITE); - return 1; /* image */ + return 1; } static int l_immediatewrite_image(lua_State * L) { - check_o_mode(static_pdf, "img.immediatewrite()", 1 << OMODE_PDF, true); + check_o_mode(static_pdf, "img.immediatewrite", 1 << OMODE_PDF, true); if (global_shipping_mode != NOT_SHIPPING) { - luaL_error(L, "pdf.immediatewrite() can not be used with \\latelua"); + luaL_error(L, "img.immediatewrite can not be used with \\latelua"); } else { write_image_or_node(L, WR_IMMEDIATEWRITE); } - return 1; /* image */ + return 1; } static int l_image_node(lua_State * L) { write_image_or_node(L, WR_NODE); - return 1; /* node */ + return 1; } static int l_image_keys(lua_State * L) { - const parm_struct *p = img_parms + 1; - if (lua_gettop(L) != 0) - luaL_error(L, "img.keys() goes without argument"); - lua_newtable(L); /* t */ - for (; p->name != NULL; p++) { - lua_pushinteger(L, (int) p->idx); /* k t */ - lua_pushstring(L, p->name); /* v k t */ - lua_settable(L, -3); /* t */ - } - return 1; + return lua_show_valid_keys(L, img_parms, img_parms_max); } static int l_image_types(lua_State * L) { - int i; - const char **p; - if (lua_gettop(L) != 0) - luaL_error(L, "img.types() goes without argument"); - lua_newtable(L); /* t */ - for (i = 1, p = (const char **) (imgtype_s + 1); *p != NULL; p++, i++) { - lua_pushinteger(L, (int) i); /* k t */ - lua_pushstring(L, *p); /* v k t */ - lua_settable(L, -3); /* t */ - } - return 1; + return lua_show_valid_list(L, img_types, img_types_max); } static int l_image_boxes(lua_State * L) { - int i; - const char **p; - if (lua_gettop(L) != 0) - luaL_error(L, "img.boxes() goes without argument"); - lua_newtable(L); /* t */ - for (i = 1, p = (const char **) (pdfboxspec_s + 1); *p != NULL; p++, i++) { - lua_pushinteger(L, (int) i); /* k t */ - lua_pushstring(L, *p); /* v k t */ - lua_settable(L, -3); /* t */ - } - return 1; + return lua_show_valid_keys(L, img_pageboxes, img_pageboxes_max); } static const struct luaL_Reg imglib_f[] = { - {"new", l_new_image}, - {"copy", l_copy_image}, - {"scan", l_scan_image}, - {"write", l_write_image}, - {"immediatewrite", l_immediatewrite_image}, - {"node", l_image_node}, - {"keys", l_image_keys}, - {"types", l_image_types}, - {"boxes", l_image_boxes}, - {NULL, NULL} /* sentinel */ + { "new", l_new_image }, + { "copy", l_copy_image }, + { "scan", l_scan_image }, + { "write", l_write_image }, + { "immediatewrite", l_immediatewrite_image }, + { "node", l_image_node }, + { "keys", l_image_keys }, + { "types", l_image_types }, + { "boxes", l_image_boxes }, + { NULL, NULL } }; -/**********************************************************************/ - void vf_out_image(PDF pdf, unsigned i) { image *a, **aa; image_dict *ad; - lua_State *L = Luas; /* ... */ - lua_rawgeti(L, LUA_REGISTRYINDEX, (int) i); /* image ... */ + lua_State *L = Luas; + lua_rawgeti(L, LUA_REGISTRYINDEX, (int) i); aa = (image **) luaL_checkudata(L, -1, TYPE_IMG); a = *aa; ad = img_dict(a); assert(ad != NULL); - setup_image(pdf, a, WR_VF_IMG); /* image ... */ + setup_image(pdf, a, WR_VF_IMG); place_img(pdf, ad, img_dimen(a), img_transform(a)); - lua_pop(L, 1); /* ... */ + lua_pop(L, 1); } -/**********************************************************************/ -/* Metamethods for image */ +/* metamethods for image */ static int m_img_get(lua_State * L) { - image **aa = (image **) luaL_checkudata(L, 1, TYPE_IMG); /* k u */ - image_to_lua(L, *aa); /* v u */ + int j; + const char *s; + image **a = (image **) luaL_checkudata(L, 1, TYPE_IMG); /* k u */ + image_dict *d = img_dict(*a); + if (d == NULL) { + luaL_error(L, "invalid image dictionary"); + } + s = lua_tostring(L, 2); + if (lua_key_eq(s,width)) { + if (is_wd_running(*a)) { + lua_pushnil(L); + } else { + lua_pushinteger(L, img_width(*a)); + } + } else if (lua_key_eq(s,height)) { + if (is_ht_running(*a)) { + lua_pushnil(L); + } else { + lua_pushinteger(L, img_height(*a)); + } + } else if (lua_key_eq(s,depth)) { + if (is_dp_running(*a)) { + lua_pushnil(L); + } else { + lua_pushinteger(L, img_depth(*a)); + } + } else if (lua_key_eq(s,transform)) { + lua_pushinteger(L, img_transform(*a)); + } else if (lua_key_eq(s,filename)) { + if (img_filename(d) == NULL || strlen(img_filename(d)) == 0) { + lua_pushnil(L); + } else { + lua_pushstring(L, img_filename(d)); + } + } else if (lua_key_eq(s,visiblefilename)) { + if (img_visiblefilename(d) == NULL || strlen(img_visiblefilename(d)) == 0) { + lua_pushnil(L); + } else { + lua_pushstring(L, img_visiblefilename(d)); + } + } else if (lua_key_eq(s,keepopen)) { + lua_pushboolean(L, img_keepopen(d)); + } else if (lua_key_eq(s,filepath)) { + if (img_filepath(d) == NULL || strlen(img_filepath(d)) == 0) { + lua_pushnil(L); + } else { + lua_pushstring(L, img_filepath(d)); + } + } else if (lua_key_eq(s,attr)) { + if (img_attr(d) == NULL || strlen(img_attr(d)) == 0) { + lua_pushnil(L); + } else { + lua_pushstring(L, img_attr(d)); + } + } else if (lua_key_eq(s,page)) { + if (img_pagename(d) != NULL && strlen(img_pagename(d)) != 0) { + lua_pushstring(L, img_pagename(d)); + } else { + lua_pushinteger(L, img_pagenum(d)); + } + } else if (lua_key_eq(s,pages)) { + lua_pushinteger(L, img_totalpages(d)); + } else if (lua_key_eq(s,xsize)) { + if ((img_rotation(d) & 1) == 0) { + lua_pushinteger(L, img_xsize(d)); + } else { + lua_pushinteger(L, img_ysize(d)); + } + } else if (lua_key_eq(s,ysize)) { + if ((img_rotation(d) & 1) == 0) { + lua_pushinteger(L, img_ysize(d)); + } else { + lua_pushinteger(L, img_xsize(d)); + } + } else if (lua_key_eq(s,xres)) { + lua_pushinteger(L, img_xres(d)); + } else if (lua_key_eq(s,yres)) { + lua_pushinteger(L, img_yres(d)); + } else if (lua_key_eq(s,rotation)) { + lua_pushinteger(L, img_rotation(d)); + } else if (lua_key_eq(s,colorspace)) { + if (img_colorspace(d) == 0) { + lua_pushnil(L); + } else { + lua_pushinteger(L, img_colorspace(d)); + } + } else if (lua_key_eq(s,colordepth)) { + if (img_colordepth(d) == 0) { + lua_pushnil(L); + } else { + lua_pushinteger(L, img_colordepth(d)); + } + } else if (lua_key_eq(s,imagetype)) { + j = img_type(d); + if (j >= 0 && j <= img_types_max) { + if (j == IMG_TYPE_NONE) { + lua_pushnil(L); + } else { + lua_pushstring(L, img_types[j]); + } + } else { + lua_pushnil(L); + } + } else if (lua_key_eq(s,pagebox)) { + j = img_pagebox(d); + if (j < 0 || j >= img_pageboxes_max) { + j = 0; + } + lua_push_img_pagebox(L, j); + } else if (lua_key_eq(s,bbox)) { + if (!img_is_bbox(d)) { + img_bbox(d)[0] = img_xorig(d); + img_bbox(d)[1] = img_yorig(d); + img_bbox(d)[2] = img_xorig(d) + img_xsize(d); + img_bbox(d)[3] = img_yorig(d) + img_ysize(d); + } + lua_newtable(L); + lua_pushinteger(L, 1); + lua_pushinteger(L, img_bbox(d)[0]); + lua_settable(L, -3); + lua_pushinteger(L, 2); + lua_pushinteger(L, img_bbox(d)[1]); + lua_settable(L, -3); + lua_pushinteger(L, 3); + lua_pushinteger(L, img_bbox(d)[2]); + lua_settable(L, -3); + lua_pushinteger(L, 4); + lua_pushinteger(L, img_bbox(d)[3]); + lua_settable(L, -3); + } else if (lua_key_eq(s,objnum)) { + if (img_objnum(d) == 0) { + lua_pushnil(L); + } else { + lua_pushinteger(L, img_objnum(d)); + } + } else if (lua_key_eq(s,index)) { + if (img_index(d) == 0) { + lua_pushnil(L); + } else { + lua_pushinteger(L, img_index(d)); + } + } else if (lua_key_eq(s,stream)) { + if (img_type(d) != IMG_TYPE_PDFSTREAM + || img_pdfstream_ptr(d) == NULL + || img_pdfstream_stream(d) == NULL + || strlen(img_pdfstream_stream(d)) == 0) { + lua_pushnil(L); + } else { + lua_pushstring(L, img_pdfstream_stream(d)); + } + } else if (lua_key_eq(s,ref_count)) { + lua_pushinteger(L, img_luaref(d)); + } else { + lua_pushnil(L); + } return 1; } +static void lua_to_image(lua_State * L, image * a, image_dict * d) +{ + int i, t; + const char *s; + s = lua_tostring(L,-2); + t = lua_type(L, -1); + if (lua_key_eq(s,width)) { + if (t == LUA_TNIL) { + set_wd_running(a); + } else if (t == LUA_TNUMBER) { + img_width(a) = (int) lua_tointeger(L, -1); + } else if (t == LUA_TSTRING) { + img_width(a) = dimen_to_number(L, lua_tostring(L, -1)); + } else { + luaL_error(L, "image.width needs integer or nil value or dimension string"); + } + } else if (lua_key_eq(s,height)) { + if (t == LUA_TNIL) { + set_ht_running(a); + } else if (t == LUA_TNUMBER) { + img_height(a) = (int) lua_tointeger(L, -1); + } else if (t == LUA_TSTRING) { + img_height(a) = dimen_to_number(L, lua_tostring(L, -1)); + } else { + luaL_error(L, "image.height needs integer or nil value or dimension string"); + } + } else if (lua_key_eq(s,depth)) { + if (t == LUA_TNIL) { + set_dp_running(a); + } else if (t == LUA_TNUMBER) { + img_depth(a) = (int) lua_tointeger(L, -1); + } else if (t == LUA_TSTRING) { + img_depth(a) = dimen_to_number(L, lua_tostring(L, -1)); + } else { + luaL_error(L, "image.depth needs integer or nil value or dimension string"); + } + } else if (lua_key_eq(s,transform)) { + if (t == LUA_TNUMBER) { + img_transform(a) = (int) lua_tointeger(L, -1); + } else { + luaL_error(L, "image.transform needs integer value"); + } + } else if (lua_key_eq(s,filename)) { + if (img_state(d) >= DICT_FILESCANNED) { + luaL_error(L, "image.filename is now read-only"); + } else if (img_type(d) == IMG_TYPE_PDFSTREAM) { + luaL_error(L, "image.filename can't be used with image.stream"); + } else if (t == LUA_TSTRING) { + xfree(img_filename(d)); + img_filename(d) = xstrdup(lua_tostring(L, -1)); + } else { + luaL_error(L, "image.filename needs string value"); + } + } else if (lua_key_eq(s,visiblefilename)) { + if (img_state(d) >= DICT_FILESCANNED) { + luaL_error(L, "image.visiblefilename is now read-only"); + } else if (img_type(d) == IMG_TYPE_PDFSTREAM) { + luaL_error(L, "image.visiblefilename can't be used with image.stream"); + } else if (t == LUA_TSTRING) { + xfree(img_visiblefilename(d)); + img_visiblefilename(d) = xstrdup(lua_tostring(L, -1)); + } else { + luaL_error(L, "image.visiblefilename needs string value"); + } + } else if (lua_key_eq(s,attr)) { + if (img_state(d) >= DICT_FILESCANNED) { + luaL_error(L, "image.attr is now read-only"); + } else if (t == LUA_TSTRING) { + xfree(img_attr(d)); + img_attr(d) = xstrdup(lua_tostring(L, -1)); + } else if (t == LUA_TNIL) { + xfree(img_attr(d)); + } else { + luaL_error(L, "image.attr needs string or nil value"); + } + } else if (lua_key_eq(s,page)) { + if (img_state(d) >= DICT_FILESCANNED) { + luaL_error(L, "image.page is now read-only"); + } else if (t == LUA_TSTRING) { + xfree(img_pagename(d)); + img_pagename(d) = xstrdup(lua_tostring(L, -1)); + img_pagenum(d) = 0; + } else if (t == LUA_TNUMBER) { + img_pagenum(d) = (int) lua_tointeger(L, -1); + xfree(img_pagename(d)); + } else { + luaL_error(L, "image.page needs integer or string value"); + } + } else if (lua_key_eq(s,colorspace)) { + if (img_state(d) >= DICT_FILESCANNED) { + luaL_error(L, "image.colorspace is now read-only"); + } else if (t == LUA_TNIL) { + img_colorspace(d) = 0; + } else if (t == LUA_TNUMBER) { + img_colorspace(d) = (int) lua_tointeger(L, -1); + } else { + luaL_error(L, "image.colorspace needs integer or nil value"); + } + } else if (lua_key_eq(s,pagebox)) { + if (img_state(d) >= DICT_FILESCANNED) { + luaL_error(L, "image.pagebox is now read-only"); + } else if (t == LUA_TNIL) { + img_pagebox(d) = PDF_BOX_SPEC_MEDIA; + } else if (t == LUA_TNUMBER) { + i = lua_tointeger(L,-1); + if (i < 0 || i >= img_pageboxes_max) { + img_pagebox(d) = PDF_BOX_SPEC_MEDIA; + } else { + img_pagebox(d) = i; + } + } else if (t == LUA_TSTRING) { + img_pagebox(d) = PDF_BOX_SPEC_MEDIA; + for (i = 0; i < img_pageboxes_max; i++) { + lua_rawgeti(L, LUA_REGISTRYINDEX, img_pageboxes[i]); + if (lua_rawequal(L,-1,-2)) { + img_pagebox(d) = i; + lua_pop(L, 1); + break; + } else { + lua_pop(L, 1); + } + } + } else { + luaL_error(L, "image.pagebox needs string, number or nil value"); + } + } else if (lua_key_eq(s,keepopen)) { + if (img_state(d) >= DICT_FILESCANNED) { + luaL_error(L, "image.keepopen is now read-only"); + } else if (t != LUA_TBOOLEAN) { + luaL_error(L, "image.bbox needs boolean value"); + } else { + img_keepopen(d) = lua_toboolean(L, -1); + } + } else if (lua_key_eq(s,bbox)) { + if (img_state(d) >= DICT_FILESCANNED) { + luaL_error(L, "image.bbox is now read-only"); + } else if (t != LUA_TTABLE) { + luaL_error(L, "image.bbox needs table value"); + } else if (lua_rawlen(L, -1) != 4) { + luaL_error(L, "image.bbox table must have exactly 4 elements"); + } else { + for (i = 1; i <= 4; i++) { /* v k t ... */ + lua_pushinteger(L, i); /* idx v k t ... */ + lua_gettable(L, -2); /* int v k t ... */ + t = lua_type(L, -1); + if (t == LUA_TNUMBER) { + img_bbox(d)[i - 1] = (int) lua_tointeger(L, -1); + } else if (t == LUA_TSTRING) { + img_bbox(d)[i - 1] = dimen_to_number(L, lua_tostring(L, -1)); + } else { + luaL_error(L, "image.bbox table needs integer value or dimension string elements"); + } + lua_pop(L, 1); /* v k t ... */ + } + img_set_bbox(d); + } + } else if (lua_key_eq(s,stream)) { + if (img_filename(d) != NULL) { + luaL_error(L, "image.stream can't be used with image.filename"); + } else if (img_state(d) >= DICT_FILESCANNED) { + luaL_error(L, "image.stream is now read-only"); + } else { + if (img_pdfstream_ptr(d) == NULL) { + new_img_pdfstream_struct(d); + } + xfree(img_pdfstream_stream(d)); + img_pdfstream_stream(d) = xstrdup(lua_tostring(L, -1)); + img_type(d) = IMG_TYPE_PDFSTREAM; + } + } else { + luaL_error(L, "image.%s can not be set", s); + } +} + static int m_img_set(lua_State * L) { - image **aa = (image **) luaL_checkudata(L, 1, TYPE_IMG); /* value key user */ - lua_to_image(L, *aa); /* v k u */ + image **a = (image **) luaL_checkudata(L, 1, TYPE_IMG); /* v k u */ + image_dict *d = img_dict(*a); + if (d == NULL) { + luaL_error(L, "invalid image dictionary"); + } else { + lua_to_image(L, *a, d); + } return 0; } static int m_img_mul(lua_State * L) { lua_Number scale; - if (lua_type(L, 1) == LUA_TNUMBER) { /* u? n */ - (void) luaL_checkudata(L, 2, TYPE_IMG); /* u n */ - lua_insert(L, -2); /* n a */ - } else if (lua_type(L, 2) != LUA_TNUMBER) { /* n u? */ - (void) luaL_checkudata(L, 1, TYPE_IMG); /* n a */ - } /* n a */ - scale = lua_tonumber(L, 2); /* n a */ - lua_pop(L, 1); /* a */ - copy_image(L, scale); /* b */ + if (lua_type(L, 1) == LUA_TNUMBER) { /* u? n */ + (void) luaL_checkudata(L, 2, TYPE_IMG); /* u n */ + lua_insert(L, -2); /* n a */ + } else if (lua_type(L, 2) != LUA_TNUMBER) { /* n u? */ + (void) luaL_checkudata(L, 1, TYPE_IMG); /* n a */ + } /* n a */ + scale = lua_tonumber(L, 2); /* float */ /* n a */ + lua_pop(L, 1); /* a */ + copy_image(L, scale); /* b */ return 1; } @@ -774,13 +672,25 @@ static int m_img_print(lua_State * L) image_dict *d; aa = (image **) luaL_checkudata(L, 1, TYPE_IMG); d = img_dict(*aa); - if (img_pagename(d) != NULL && strlen(img_pagename(d)) != 0) - lua_pushfstring(L, "<img{filename=\"%s\", page=\"%s\"}>", img_filename(d), img_pagename(d)); - else - lua_pushfstring(L, "<img{filename=\"%s\", page=%d}>", img_filename(d), img_pagenum(d)); + /* formatted a bit like a node */ + if (img_filename(d) == NULL) { + if (img_pagename(d) != NULL && strlen(img_pagename(d)) != 0) { + lua_pushfstring(L, "<img unset : %d >", img_dictref(*aa)); + } else { + lua_pushfstring(L, "<img unset : %d >", img_dictref(*aa)); + } + } else { + if (img_pagename(d) != NULL && strlen(img_pagename(d)) != 0) { + lua_pushfstring(L, "<img %s : %s : %d >", img_filename(d), img_pagename(d), img_dictref(*aa)); + } else { + lua_pushfstring(L, "<img %s : %d : %d >", img_filename(d), img_pagenum(d), img_dictref(*aa)); + } + } return 1; } +/* this finalizes instance */ + static int m_img_gc(lua_State * L) { image *a, **aa; @@ -788,50 +698,55 @@ static int m_img_gc(lua_State * L) aa = (image **) luaL_checkudata(L, 1, TYPE_IMG); a = *aa; d = img_dict(*aa); -#ifdef DEBUG - printf("\n===== IMG GC ===== a=%d ad=%d\n", a, img_dict(a)); -#endif luaL_unref(L, LUA_REGISTRYINDEX, img_dictref(a)); - if (!img_is_refered(d)) + img_luaref(d) -= 1; + /* we need to check this */ + if (!img_is_refered(d)) { xfree(a); + } + /* till here */ return 0; } +/* the instance */ + static const struct luaL_Reg img_m[] = { {"__index", m_img_get}, {"__newindex", m_img_set}, {"__mul", m_img_mul}, {"__tostring", m_img_print}, - {"__gc", m_img_gc}, /* finalizer */ - {NULL, NULL} /* sentinel */ + {"__gc", m_img_gc}, + {NULL, NULL} }; -/**********************************************************************/ -/* Metamethods for image_dict */ +/* this finalizes the dict */ static int m_img_dict_gc(lua_State * L) { image_dict *ad, **add; add = (image_dict **) luaL_checkudata(L, 1, TYPE_IMG_DICT); ad = *add; -#ifdef DEBUG - printf("\n===== IMG_DICT GC FREE ===== ad=%d\n", ad); -#endif - if (img_state(ad) < DICT_REFERED) - free_image_dict(ad); + if (img_luaref(ad) > 0) { + luaL_error(L, "disposing image dict that has references"); + } else { + /* we need to check this */ + if (img_state(ad) < DICT_REFERED) { + free_image_dict(ad); + } + /* till here */ + } return 0; } +/* the (shared) dict */ + static const struct luaL_Reg img_dict_m[] = { - {"__gc", m_img_dict_gc}, /* finalizer */ - {NULL, NULL} /* sentinel */ + {"__gc", m_img_dict_gc}, + {NULL, NULL} }; -/**********************************************************************/ - int luaopen_img(lua_State * L) { - preset_environment(L, img_parms, IMG_ENV); luaL_newmetatable(L, TYPE_IMG); #ifdef LuajitTeX luaL_register(L, NULL, img_m); @@ -846,5 +761,3 @@ int luaopen_img(lua_State * L) #endif return 1; } - -/**********************************************************************/ diff --git a/Build/source/texk/web2c/luatexdir/lua/liolibext.c b/Build/source/texk/web2c/luatexdir/lua/liolibext.c index edf094d4187..630562228d9 100644 --- a/Build/source/texk/web2c/luatexdir/lua/liolibext.c +++ b/Build/source/texk/web2c/luatexdir/lua/liolibext.c @@ -1,5 +1,5 @@ /* liolibext.c - + Copyright 2014 Taco Hoekwater <taco@luatex.org> This file is part of LuaTeX. @@ -81,7 +81,7 @@ #define l_fseek(f,o,w) fseeko64(f,o,w) #define l_ftell(f) ftello64(f) -#define l_seeknum int64_t +#define l_seeknum int64_t #else @@ -196,7 +196,7 @@ static void opencheck (lua_State *L, const char *fname, const char *mode) { #ifdef WIN32 _setmode (fileno (p->f), _O_BINARY); #endif - if (mode[0]=='r') + if (mode[0]=='r') recorder_record_input(fname); else recorder_record_output(fname); @@ -223,7 +223,7 @@ static int io_open (lua_State *L) { #ifdef WIN32 _setmode (fileno (p->f), _O_BINARY); #endif - if (mode[0]=='r') + if (mode[0]=='r') recorder_record_input(filename); else recorder_record_output(filename); @@ -377,7 +377,7 @@ static int io_lines (lua_State *L) { static int read_number (lua_State *L, FILE *f) { lua_Number d; if (fscanf(f, LUA_NUMBER_SCAN, &d) == 1) { - lua_pushnumber(L, d); + lua_pushnumber(L, d); /* integer or float */ return 1; } else { @@ -394,7 +394,7 @@ static int test_eof (lua_State *L, FILE *f) { return (c != EOF); } -/* this version does not care wether the file has +/* this version does not care wether the file has line endings using an 'alien' convention */ static int read_line(lua_State * L, FILE * f, int chop) @@ -439,7 +439,7 @@ static void read_all (lua_State *L, FILE *f) { luaL_buffinit(L, &b); /* speed up loading of not too large files: */ old = l_ftell(f); - if ((l_fseek(f, 0, SEEK_END) >= 0) && + if ((l_fseek(f, 0, SEEK_END) >= 0) && ((nrlen = l_ftell(f)) > 0) && nrlen < 1000 * 1000 * 100) { rlen = nrlen; } @@ -603,7 +603,7 @@ static int f_seek (lua_State *L) { if (op) return luaL_fileresult(L, 0, NULL); /* error */ else { - lua_pushnumber(L, (lua_Number)l_ftell(f)); + lua_pushinteger(L, (lua_Number)l_ftell(f)); return 1; } } diff --git a/Build/source/texk/web2c/luatexdir/lua/lkpselib.c b/Build/source/texk/web2c/luatexdir/lua/lkpselib.c index d2fadcbfc26..e45cda0af6f 100644 --- a/Build/source/texk/web2c/luatexdir/lua/lkpselib.c +++ b/Build/source/texk/web2c/luatexdir/lua/lkpselib.c @@ -199,7 +199,7 @@ static int find_file(lua_State * L) if (t == LUA_TBOOLEAN) { mexist = lua_toboolean(L, i); } else if (t == LUA_TNUMBER) { - mexist=(int)lua_tonumber(L, i); + mexist = (int) lua_tointeger(L, i); } else if (t == LUA_TSTRING) { int op = luaL_checkoption(L, i, NULL, filetypenames); ftype = filetypes[op]; @@ -237,7 +237,7 @@ static int lua_kpathsea_find_file(lua_State * L) if (t == LUA_TBOOLEAN) { mexist = (boolean) lua_toboolean(L, i); } else if (t == LUA_TNUMBER) { - mexist=(int)lua_tonumber(L, i); + mexist = (int) lua_tointeger(L, i); } else if (t == LUA_TSTRING) { int op = luaL_checkoption(L, i, NULL, filetypenames); ftype = filetypes[op]; @@ -366,14 +366,16 @@ static unsigned find_dpi(const_string s) return dpi_number; } -/* Return newly-allocated NULL-terminated list of strings from MATCHES - that are prefixed with any of the subdirectories in SUBDIRS. That - is, for a string S in MATCHES, its dirname must end with one of the - elements in SUBDIRS. For instance, if subdir=foo/bar, that will - match a string foo/bar/baz or /some/texmf/foo/bar/baz. +/* + Return newly-allocated NULL-terminated list of strings from MATCHES + that are prefixed with any of the subdirectories in SUBDIRS. That + is, for a string S in MATCHES, its dirname must end with one of the + elements in SUBDIRS. For instance, if subdir=foo/bar, that will + match a string foo/bar/baz or /some/texmf/foo/bar/baz. - We don't reallocate the actual strings, just the list elements. - Perhaps later we will implement wildcards or // or something. */ + We don't reallocate the actual strings, just the list elements. + Perhaps later we will implement wildcards or "//" or something. +*/ static string *subdir_match(str_list_type subdirs, string * matches) { @@ -538,14 +540,14 @@ static int do_lua_kpathsea_lookup(lua_State * L, kpathsea kpse, int idx) lua_pushstring(L, "dpi"); lua_gettable(L, idx + 1); if (lua_type(L, -1) == LUA_TNUMBER) { - dpi=(int)lua_tonumber(L, -1); + dpi = (int) lua_tointeger(L, -1); } lua_pop(L, 1); lua_pushstring(L, "debug"); lua_gettable(L, idx + 1); if (lua_type(L, -1) == LUA_TNUMBER) { int d = 0; - d=(int)lua_tonumber(L, -1); + d = (int) lua_tointeger(L, -1); kpse->debug |= d; } lua_pop(L, 1); diff --git a/Build/source/texk/web2c/luatexdir/lua/llanglib.c b/Build/source/texk/web2c/luatexdir/lua/llanglib.c index 645780ca1c7..3356e734189 100644 --- a/Build/source/texk/web2c/luatexdir/lua/llanglib.c +++ b/Build/source/texk/web2c/luatexdir/lua/llanglib.c @@ -37,11 +37,10 @@ static int lang_new(lua_State * L) } else { int lualang; lang = lua_newuserdata(L, sizeof(struct tex_language *)); - lualang=(int)lua_tonumber(L, 1); + lualang = lua_tointeger(L, 1); *lang = get_language(lualang); if (!*lang) { - return luaL_error(L, "lang.new(%d): undefined language", - lua_tonumber(L, 1)); + return luaL_error(L, "lang.new(%d): undefined language", lualang); } } luaL_getmetatable(L, LANG_METATABLE); @@ -53,7 +52,7 @@ static int lang_id(lua_State * L) { struct tex_language **lang_ptr; lang_ptr = check_islang(L, 1); - lua_pushnumber(L, (*lang_ptr)->id); + lua_pushinteger(L, (*lang_ptr)->id); return 1; } @@ -92,8 +91,7 @@ static int lang_hyphenation(lua_State * L) lang_ptr = check_islang(L, 1); if (lua_gettop(L) != 1) { if (lua_type(L, 2) != LUA_TSTRING) { - return luaL_error(L, - "lang.hyphenation(): argument should be a string"); + return luaL_error(L, "lang.hyphenation(): argument should be a string"); } load_hyphenation(*lang_ptr, (const unsigned char *) lua_tostring(L, 2)); return 0; @@ -115,10 +113,10 @@ static int lang_pre_hyphen_char(lua_State * L) if (lua_type(L, 2) != LUA_TNUMBER) { return luaL_error(L, "lang.prehyphenchar(): argument should be a character number"); } - (*lang_ptr)->pre_hyphen_char=(int)lua_tonumber(L, 2); + (*lang_ptr)->pre_hyphen_char = (int) lua_tointeger(L, 2); return 0; } else { - lua_pushnumber(L, (*lang_ptr)->pre_hyphen_char); + lua_pushinteger(L, (*lang_ptr)->pre_hyphen_char); return 1; } } @@ -131,10 +129,10 @@ static int lang_post_hyphen_char(lua_State * L) if (lua_type(L, 2) != LUA_TNUMBER) { return luaL_error(L, "lang.posthyphenchar(): argument should be a character number"); } - (*lang_ptr)->post_hyphen_char=(int)lua_tonumber(L, 2); + (*lang_ptr)->post_hyphen_char = (int) lua_tointeger(L, 2); return 0; } else { - lua_pushnumber(L, (*lang_ptr)->post_hyphen_char); + lua_pushinteger(L, (*lang_ptr)->post_hyphen_char); return 1; } } @@ -148,14 +146,43 @@ static int lang_pre_exhyphen_char(lua_State * L) if (lua_type(L, 2) != LUA_TNUMBER) { return luaL_error(L, "lang.preexhyphenchar(): argument should be a character number"); } - (*lang_ptr)->pre_exhyphen_char=(int)lua_tonumber(L, 2); + (*lang_ptr)->pre_exhyphen_char = (int) lua_tointeger(L, 2); return 0; } else { - lua_pushnumber(L, (*lang_ptr)->pre_exhyphen_char); + lua_pushinteger(L, (*lang_ptr)->pre_exhyphen_char); return 1; } } +static int lang_sethjcode(lua_State * L) +{ + struct tex_language **lang_ptr; + lang_ptr = check_islang(L, 1); + if (lua_type(L, 2) != LUA_TNUMBER) { + return luaL_error(L, "lang.sethjcode(): argument should be a character number"); + } else { + int i = (int) lua_tointeger(L, 2) ; + if (lua_type(L, 3) == LUA_TNUMBER) { + set_hj_code((*lang_ptr)->id,i,(int) lua_tointeger(L, 3),-1); + } else { + set_hj_code((*lang_ptr)->id,i,i,-1); + } + } + return 0; +} + +static int lang_gethjcode(lua_State * L) +{ + struct tex_language **lang_ptr; + lang_ptr = check_islang(L, 1); + if (lua_type(L, 2) != LUA_TNUMBER) { + return luaL_error(L, "lang.gethjcode(): argument should be a character number"); + } else { + lua_pushinteger(L, get_hj_code((*lang_ptr)->id,lua_tointeger(L, 2))); + } + return 1; +} + static int lang_post_exhyphen_char(lua_State * L) { struct tex_language **lang_ptr; @@ -164,15 +191,14 @@ static int lang_post_exhyphen_char(lua_State * L) if (lua_type(L, 2) != LUA_TNUMBER) { return luaL_error(L, "lang.postexhyphenchar(): argument should be a character number"); } - (*lang_ptr)->post_exhyphen_char=(int)lua_tonumber(L, 2); + (*lang_ptr)->post_exhyphen_char = (int) lua_tointeger(L, 2); return 0; } else { - lua_pushnumber(L, (*lang_ptr)->post_exhyphen_char); + lua_pushinteger(L, (*lang_ptr)->post_exhyphen_char); return 1; } } - static int lang_hyphenation_min(lua_State * L) { struct tex_language **lang_ptr; @@ -181,10 +207,10 @@ static int lang_hyphenation_min(lua_State * L) if (lua_type(L, 2) != LUA_TNUMBER) { return luaL_error(L, "lang.hyphenationmin(): argument should be a number"); } - (*lang_ptr)->hyphenation_min=(int)lua_tonumber(L, 2); + (*lang_ptr)->hyphenation_min = (int) lua_tointeger(L, 2); return 0; } else { - lua_pushnumber(L, (*lang_ptr)->hyphenation_min); + lua_pushinteger(L, (*lang_ptr)->hyphenation_min); return 1; } } @@ -197,14 +223,22 @@ static int lang_clear_hyphenation(lua_State * L) return 0; } - static int do_lang_clean(lua_State * L) { char *cleaned; - if (lua_type(L, 1) != LUA_TSTRING) { - return luaL_error(L, "lang.clean(): argument should be a string"); + if (lua_type(L, 1) == LUA_TSTRING) { + (void) clean_hyphenation(int_par(cur_lang_code), lua_tostring(L, 1), &cleaned); + } else { + struct tex_language **lang_ptr; + lang_ptr = check_islang(L, 1); + if (lang_ptr == NULL) { + return luaL_error(L, "lang.clean(): first argument should be a string or language"); + } else if (lua_type(L, 2) != LUA_TSTRING) { + return luaL_error(L, "lang.clean(): second argument should be a string"); + } else { + (void) clean_hyphenation((*lang_ptr)->id,lua_tostring(L, 2), &cleaned); + } } - (void) clean_hyphenation(lua_tostring(L, 1), &cleaned); lua_pushstring(L, cleaned); return 1; } @@ -227,7 +261,6 @@ static int do_lang_hyphenate(lua_State * L) return 1; } - static const struct luaL_Reg langlib_d[] = { /* *INDENT-OFF* */ {"clear_patterns", lang_clear_patterns}, @@ -239,6 +272,8 @@ static const struct luaL_Reg langlib_d[] = { {"preexhyphenchar", lang_pre_exhyphen_char}, {"postexhyphenchar", lang_post_exhyphen_char}, {"hyphenationmin", lang_hyphenation_min}, + {"sethjcode", lang_sethjcode}, + {"gethjcode", lang_gethjcode}, {"id", lang_id}, /* *INDENT-ON* */ {NULL, NULL} /* sentinel */ @@ -256,6 +291,8 @@ static const struct luaL_Reg langlib[] = { {"preexhyphenchar", lang_pre_exhyphen_char}, {"postexhyphenchar", lang_post_exhyphen_char}, {"hyphenationmin", lang_hyphenation_min}, + {"sethjcode", lang_sethjcode}, + {"gethjcode", lang_gethjcode}, {"id", lang_id}, {"clean", do_lang_clean}, {"hyphenate", do_lang_hyphenate}, diff --git a/Build/source/texk/web2c/luatexdir/lua/lnewtokenlib.c b/Build/source/texk/web2c/luatexdir/lua/lnewtokenlib.c index f51e1e47bff..08ca9e9a1ba 100644 --- a/Build/source/texk/web2c/luatexdir/lua/lnewtokenlib.c +++ b/Build/source/texk/web2c/luatexdir/lua/lnewtokenlib.c @@ -74,6 +74,17 @@ static lua_token *check_istoken(lua_State * L, int ud); #define is_active_string(s) (strlen((char *)s)>3 && *s==0xEF && *(s+1)==0xBF && *(s+2)==0xBF) +void make_token_table(lua_State * L, int cmd, int chr, int cs) +{ + lua_createtable(L, 3, 0); + lua_pushinteger(L, cmd); + lua_rawseti(L, -2, 1); + lua_pushinteger(L, chr); + lua_rawseti(L, -2, 2); + lua_pushinteger(L, cs); + lua_rawseti(L, -2, 3); +} + static unsigned char *get_cs_text(int cs) { if (cs == null_cs) @@ -108,7 +119,7 @@ lua_token *check_istoken(lua_State * L, int ud) lua_token *p = maybe_istoken(L, ud); if (p != NULL) return p; - luatex_fail("There should have been a lua <token> here, not an object with type %s!", luaL_typename(L, ud)); + formatted_error("token lib","lua <token> expected, not an object with type %s", luaL_typename(L, ud)); return NULL; } @@ -139,7 +150,7 @@ static void push_token(lua_State * L, int tok) /* static int run_get_cs_offset(lua_State * L) */ /* { */ -/* lua_pushnumber(L, cs_token_flag); */ +/* lua_pushinteger(L, cs_token_flag); */ /* return 1; */ /* } */ @@ -149,7 +160,7 @@ static void push_token(lua_State * L, int tok) /* if (lua_type(L, -1) == LUA_TSTRING) { */ /* cs = get_command_id(lua_tostring(L, -1)); */ /* } */ -/* lua_pushnumber(L, cs); */ +/* lua_pushinteger(L, cs); */ /* return 1; */ /* } */ @@ -161,7 +172,7 @@ static void push_token(lua_State * L, int tok) /* s = lua_tolstring(L, -1, &k); */ /* cs = (size_t) string_lookup(s, k); */ /* } */ -/* lua_pushnumber(L, (lua_Number) cs); */ +/* lua_pushinteger(L, (lua_Number) cs); */ /* return 1; */ /* } */ @@ -219,7 +230,7 @@ static int run_scan_int(lua_State * L) scan_int(); v = cur_val; unsave_tex_scanner(texstate); - lua_pushnumber(L,(lua_Number)v); + lua_pushinteger(L,(int)v); return 1; } @@ -238,9 +249,9 @@ static int run_scan_dimen(lua_State * L) v = cur_val; o = cur_order; unsave_tex_scanner(texstate); - lua_pushnumber(L,(lua_Number)v); + lua_pushinteger(L,v); if (inf) { - lua_pushnumber(L,(lua_Number)o); + lua_pushinteger(L,(lua_Number)o); return 2; } else { return 1; @@ -379,7 +390,7 @@ static int run_scan_code(lua_State * L) /* HH */ } } if (cc & (1<<(cur_cmd))) { - lua_pushnumber(L,(lua_Number)cur_chr); + lua_pushinteger(L,(int)cur_chr); } else { lua_pushnil(L); back_input(); @@ -426,11 +437,10 @@ static int run_lookup(lua_State * L) static int run_build(lua_State * L) { - int cmd, chr, cs; if (lua_type(L, 1) == LUA_TNUMBER) { - cs = 0; - chr = (int) lua_tointeger(L, 1); - cmd = (int) luaL_optinteger(L, 2, get_cat_code(int_par(cat_code_table_code),chr)); + int cs = 0; + int chr = (int) lua_tointeger(L, 1); + int cmd = (int) luaL_optinteger(L, 2, get_cat_code(int_par(cat_code_table_code),chr)); if (cmd == 0 || cmd == 9 || cmd == 14 || cmd == 15) { fprintf(stdout, "\n\nluatex error: not a good token.\nCatcode %i can not be returned, so I replaced it by 12 (other)", @@ -461,105 +471,188 @@ static int lua_tokenlib_free(lua_State * L) return 1; } -static int lua_tokenlib_getfield(lua_State * L) +/* fast accessors */ + +inline static int lua_tokenlib_get_command(lua_State * L) { - lua_token *n; - const char *s; - halfword t, e ; - n = check_istoken(L, 1); - s = lua_tostring(L, 2); - t = token_info(n->token); - if (lua_key_eq(s, command)) { - if (t >= cs_token_flag) { - lua_pushnumber(L, eq_type((t - cs_token_flag))); + lua_token *n = check_istoken(L, 1); + halfword t = token_info(n->token); + if (t >= cs_token_flag) { + lua_pushinteger(L,(int) eq_type((t - cs_token_flag))); + } else { + lua_pushinteger(L, token_cmd(t)); + } + return 1; +} + +inline static int lua_tokenlib_get_index(lua_State * L) +{ + lua_token *n = check_istoken(L, 1); + halfword t = token_info(n->token); + int cmd = (t >= cs_token_flag ? eq_type(t - cs_token_flag) : token_cmd(t)); + halfword e = equiv(t - cs_token_flag); + switch (cmd) { + case assign_int_cmd: + e -= count_base; + break; + case assign_attr_cmd: + e -= attribute_base; + break; + case assign_dimen_cmd: + e -= dimen_base; + break; + case assign_glue_cmd: + e -= skip_base; + break; + case assign_mu_glue_cmd: + e -= mu_skip_base; + break; + case assign_toks_cmd: + e -= toks_base; + break; + default: + e = -1; + break; + } + if ((e >= 0) && (e <= 65535)) { + lua_pushinteger(L, e); + } else { + lua_pushnil(L); + } + return 1; +} + +inline static int lua_tokenlib_get_mode(lua_State * L) +{ + lua_token *n = check_istoken(L, 1); + halfword t = token_info(n->token); + if (t >= cs_token_flag) { + lua_pushinteger(L, equiv(t - cs_token_flag)); + } else { + lua_pushinteger(L, token_chr(t)); + } + return 1; +} + +inline static int lua_tokenlib_get_cmdname(lua_State * L) +{ + lua_token *n = check_istoken(L, 1); + halfword t = token_info(n->token); + int cmd = (t >= cs_token_flag ? eq_type(t - cs_token_flag) : token_cmd(t)); + lua_pushstring(L, command_names[cmd].cmd_name); /* can be sped up */ + return 1; +} + +inline static int lua_tokenlib_get_csname(lua_State * L) +{ + lua_token *n = check_istoken(L, 1); + halfword t = token_info(n->token); + unsigned char *s; + if (t >= cs_token_flag && ((s = get_cs_text(t - cs_token_flag)) != (unsigned char *) NULL)) { + if (is_active_string(s)) + lua_pushstring(L, (char *) (s + 3)); + else + lua_pushstring(L, (char *) s); + } else { + lua_pushnil(L); + } + return 1; +} + +inline static int lua_tokenlib_get_id(lua_State * L) +{ + lua_token *n = check_istoken(L, 1); + lua_pushinteger(L, n->token); + return 1; +} + +inline static int lua_tokenlib_get_tok(lua_State * L) +{ + lua_token *n = check_istoken(L, 1); + halfword t = token_info(n->token); + lua_pushinteger(L, t); + return 1; +} + +inline static int lua_tokenlib_get_active(lua_State * L) +{ + lua_token *n = check_istoken(L, 1); + halfword t = token_info(n->token); + unsigned char *s; + if (t >= cs_token_flag && ((s = get_cs_text(t - cs_token_flag)) != (unsigned char *) NULL)) { + if (is_active_string(s)) + lua_pushboolean(L,1); + else + lua_pushboolean(L,0); + free(s); + } else { + lua_pushboolean(L,0); + } + return 1; +} + +inline static int lua_tokenlib_get_expandable(lua_State * L) +{ + lua_token *n = check_istoken(L, 1); + halfword t = token_info(n->token); + int cmd = (t >= cs_token_flag ? eq_type(t - cs_token_flag) : token_cmd(t)); + if (cmd > max_command_cmd) { + lua_pushboolean(L, 1); + } else { + lua_pushboolean(L, 0); + } + return 1; +} + +inline static int lua_tokenlib_get_protected(lua_State * L) +{ + lua_token *n = check_istoken(L, 1); + halfword t = token_info(n->token); + int cmd = (t >= cs_token_flag ? eq_type(t - cs_token_flag) : token_cmd(t)); + if (cmd > max_command_cmd && (cmd >= call_cmd) && (cmd < end_template_cmd)) { + int chr = (t >= cs_token_flag ? equiv(t - cs_token_flag) : token_chr(t)); + if (token_info(token_link(chr)) == protected_token) { + lua_pushboolean(L, 1); } else { - lua_pushnumber(L, token_cmd(t)); + lua_pushboolean(L, 0); } + } else { + lua_pushboolean(L, 0); + } + return 1; +} + +static int lua_tokenlib_getfield(lua_State * L) +{ + const char *s = lua_tostring(L, 2); + if (lua_key_eq(s, command)) { + return lua_tokenlib_get_command(L); } else if (lua_key_eq(s, index)) { - int cmd = (t >= cs_token_flag ? eq_type(t - cs_token_flag) : token_cmd(t)); - e = equiv(t - cs_token_flag); - switch (cmd) { - case assign_int_cmd: - e -= count_base; - break; - case assign_attr_cmd: - e -= attribute_base; - break; - case assign_dimen_cmd: - e -= dimen_base; - break; - case assign_glue_cmd: - e -= skip_base; - break; - case assign_mu_glue_cmd: - e -= mu_skip_base; - break; - case assign_toks_cmd: - e -= toks_base; - break; - default: - e = -1; - break; - } - if ((e >= 0) && (e <= 65535)) { - lua_pushnumber(L, e); - } else { - lua_pushnil(L); - } + return lua_tokenlib_get_index(L); } else if (lua_key_eq(s, mode)) { - if (t >= cs_token_flag) { - lua_pushnumber(L, equiv(t - cs_token_flag)); - } else { - lua_pushnumber(L, token_chr(t)); - } + return lua_tokenlib_get_mode(L); } else if (lua_key_eq(s, cmdname)) { - int cmd = (t >= cs_token_flag ? eq_type(t - cs_token_flag) : token_cmd(t)); - lua_pushstring(L, command_names[cmd].cmd_name); /* can be sped up */ + return lua_tokenlib_get_cmdname(L); } else if (lua_key_eq(s, csname)) { - unsigned char *s; - if (t >= cs_token_flag && ((s = get_cs_text(t - cs_token_flag)) != (unsigned char *) NULL)) { - if (is_active_string(s)) - lua_pushstring(L, (char *) (s + 3)); - else - lua_pushstring(L, (char *) s); - } else { - lua_pushnil(L); - } + return lua_tokenlib_get_csname(L); } else if (lua_key_eq(s, id)) { - lua_pushnumber(L, n->token); + return lua_tokenlib_get_id(L); } else if (lua_key_eq(s, tok)) { - lua_pushnumber(L, t); + return lua_tokenlib_get_tok(L); } else if (lua_key_eq(s, active)) { - unsigned char *s; - if (t >= cs_token_flag && ((s = get_cs_text(t - cs_token_flag)) != (unsigned char *) NULL)) { - if (is_active_string(s)) - lua_pushboolean(L,1); - else - lua_pushboolean(L,0); - free(s); - } else { - lua_pushboolean(L,0); - } + return lua_tokenlib_get_active(L); } else if (lua_key_eq(s, expandable)) { - int cmd = (t >= cs_token_flag ? eq_type(t - cs_token_flag) : token_cmd(t)); - if (cmd > max_command_cmd) { - lua_pushboolean(L, 1); - } else { - lua_pushboolean(L, 0); - } + return lua_tokenlib_get_expandable(L); } else if (lua_key_eq(s, protected)) { - int cmd = (t >= cs_token_flag ? eq_type(t - cs_token_flag) : token_cmd(t)); - int chr = (t >= cs_token_flag ? equiv(t - cs_token_flag) : token_chr(t)); - if (cmd > max_command_cmd && ((cmd >= call_cmd) && (cmd < end_template_cmd)) && - token_info(token_link(chr)) == protected_token) { - lua_pushboolean(L, 1); - } else { - lua_pushboolean(L, 0); - } + return lua_tokenlib_get_protected(L); + } else { + lua_pushnil(L); } return 1; } +/* end */ + static int lua_tokenlib_equal(lua_State * L) { lua_token *n, *m; @@ -733,26 +826,44 @@ static int set_macro(lua_State * L) } static const struct luaL_Reg tokenlib[] = { - {"is_token", lua_tokenlib_is_token}, - {"get_next", run_get_next}, - {"scan_keyword", run_scan_keyword}, - {"scan_int", run_scan_int}, - {"scan_dimen", run_scan_dimen}, - {"scan_glue", run_scan_glue}, - {"scan_toks", run_scan_toks}, - {"scan_code", run_scan_code}, - {"scan_string", run_scan_string}, - {"scan_word", run_scan_word}, - {"scan_csname", run_scan_csname}, - {"type", lua_tokenlib_type}, - {"create", run_build}, - {"scan_token", run_scan_token}, /* expands next token if needed */ - {"set_macro", set_macro}, + { "type", lua_tokenlib_type }, + { "create", run_build }, + { "is_token", lua_tokenlib_is_token }, + /* scanners */ + { "get_next", run_get_next }, + { "scan_keyword", run_scan_keyword }, + { "scan_int", run_scan_int }, + { "scan_dimen", run_scan_dimen }, + { "scan_glue", run_scan_glue }, + { "scan_toks", run_scan_toks }, + { "scan_code", run_scan_code }, + { "scan_string", run_scan_string }, + { "scan_word", run_scan_word }, + { "scan_csname", run_scan_csname }, + { "scan_token", run_scan_token }, /* expands next token if needed */ + /* push into input stream */ + /* + { "write",luatwrite }, + */ + /* getters */ + { "get_command", lua_tokenlib_get_command }, + { "get_index", lua_tokenlib_get_index }, + { "get_mode", lua_tokenlib_get_mode }, + { "get_cmdname", lua_tokenlib_get_cmdname }, + { "get_csname", lua_tokenlib_get_csname }, + { "get_id", lua_tokenlib_get_id }, + { "get_tok", lua_tokenlib_get_tok }, + { "get_active", lua_tokenlib_get_active }, + { "get_expandable", lua_tokenlib_get_expandable }, + { "get_protected", lua_tokenlib_get_protected }, + /* maybe more setters */ + { "set_macro", set_macro }, + /* probably never */ /* {"expand", run_expand}, */ /* does not work yet! */ /* {"csname_id", run_get_csname_id}, */ /* yes or no */ /* {"command_id", run_get_command_id}, */ /* yes or no */ /* {"cs_offset", run_get_cs_offset}, */ /* not that useful */ - {NULL, NULL} /* sentinel */ + {NULL, NULL} }; static const struct luaL_Reg tokenlib_m[] = { diff --git a/Build/source/texk/web2c/luatexdir/lua/lnodelib.c b/Build/source/texk/web2c/luatexdir/lua/lnodelib.c index fed975719c8..fcd5d994baa 100644 --- a/Build/source/texk/web2c/luatexdir/lua/lnodelib.c +++ b/Build/source/texk/web2c/luatexdir/lua/lnodelib.c @@ -98,7 +98,6 @@ */ - #include "ptexlib.h" #include "lua/luatex-api.h" #ifdef LuajitTeX @@ -114,7 +113,6 @@ */ - /* When the first argument to an accessor is a node, we can use it's metatable @@ -172,14 +170,14 @@ */ -#define nodelib_pushdirect(n) lua_pushnumber(L,n) +#define nodelib_pushdirect(n) lua_pushinteger(L,n) #define nodelib_popdirect(n) lua_tointeger(L,n) #define nodelib_pushdirect_or_nil(n) do { \ if (n==null) { \ lua_pushnil(L); \ } else { \ - lua_pushnumber(L,n); \ + lua_pushinteger(L,n); \ } \ } while (0) @@ -188,43 +186,29 @@ lua_pushnil(L); \ } else { \ alink(n) = null; \ - lua_pushnumber(L,n); \ + lua_pushinteger(L,n); \ } \ } while (0) -#define nodelib_check_glue_spec(n) do { \ - n = glue_ptr(n); \ - if ((!n) || (!valid_node(n))) { \ - n = new_node(glue_spec_node,0); \ - glue_ptr(n) = n; \ +#define nodelib_check_glue_spec(n,g,field) do { \ + g = glue_ptr(n); \ + v = (halfword) lua_tointeger(L, 3); \ + if ((!g) || (!valid_node(g))) { \ + g = new_node(glue_spec_node,0); \ + glue_ptr(n) = g; \ + field(g) = v; \ + } else if (field(g) != v) { \ + if (glue_ref_count(g) > 1) { \ + c = new_spec(g); \ + delete_glue_ref(g); \ + g = c; \ + add_glue_ref(g); \ + glue_ptr(n) = g; \ + } \ + field(g) = v; \ } \ } while (0) -/* handy sometimes: */ - -/* static void stackDump (lua_State * L) { */ -/* int i; */ -/* int top = lua_gettop(L); */ -/* for (i = top; i >= 1; i--) { */ -/* int t = lua_type(L, i); */ -/* switch (t) { */ -/* case LUA_TSTRING: */ -/* printf("[%d] '%s'\n", i, lua_tostring(L, i)); */ -/* break; */ -/* case LUA_TBOOLEAN: */ -/* printf("[%d] %s\n",i, lua_toboolean(L, i) ? "true" : "false"); */ -/* break; */ -/* case LUA_TNUMBER: */ -/* printf("[%d] %g\n", i, lua_tonumber(L, i)); */ -/* break; */ -/* default: */ -/* printf("[%d][%d] %s &d=0x%x *d=%d\n",i-top-1, i, lua_typename(L, t), lua_touserdata(L,i), *((int *)lua_touserdata(L,i))); */ -/* break; */ -/* } */ -/* } */ -/* } */ - - #define nodelib_setattr(L, s, n) reassign_attribute(n,nodelib_getlist(L,s)) #define nodelib_gettoks(L,a) tokenlist_from_lua(L) @@ -234,10 +218,10 @@ /* fetching a field from a node .. we can often use the reuse bot-of-stack metatable */ -#define nodelib_pushlist(L,n) { lua_pushnumber(L,n); lua_nodelib_push(L); } /* can be: fast_metatable_or_nil(n) */ -#define nodelib_pushattr(L,n) { lua_pushnumber(L,n); lua_nodelib_push(L); } /* can be: fast_metatable_or_nil(n) */ -#define nodelib_pushspec(L,n) { lua_pushnumber(L,n); lua_nodelib_push_spec(L); } /* can be: fast_metatable_or_nil(n) - different criterium? */ -#define nodelib_pushaction(L,n) { lua_pushnumber(L,n); lua_nodelib_push(L); } /* can be: fast_metatable_or_nil(n) */ +#define nodelib_pushlist(L,n) { lua_pushinteger(L,n); lua_nodelib_push(L); } /* can be: fast_metatable_or_nil(n) */ +#define nodelib_pushattr(L,n) { lua_pushinteger(L,n); lua_nodelib_push(L); } /* can be: fast_metatable_or_nil(n) */ +#define nodelib_pushspec(L,n) { lua_pushinteger(L,n); lua_nodelib_push_spec(L); } /* can be: fast_metatable_or_nil(n) - different criterium? */ +#define nodelib_pushaction(L,n) { lua_pushinteger(L,n); lua_nodelib_push(L); } /* can be: fast_metatable_or_nil(n) */ #define nodelib_pushstring(L,n) { char *ss=makecstring(n); lua_pushstring(L,ss); free(ss); } /* find prev, and fix backlinks .. can be a macro instead (only used a few times) */ @@ -250,9 +234,6 @@ while (vlink(t)!=current && t != null) { \ t = vlink(t); \ } -#define get_node_type_id(L,n) do_get_node_type_id(L,n,node_data) -#define get_node_subtype_id(L,n) do_get_node_type_id(L,n,whatsit_node_data) - #define box(A) eqtb[box_base+(A)].hh.rh #define direct_check_index_range(j,s) \ if (j<0 || j > 65535) { \ @@ -288,7 +269,7 @@ halfword *check_isnode(lua_State * L, int i) halfword *p = maybe_isnode(L, i); if (p != NULL) return p; - luatex_fail("There should have been a lua <node> here, not an object with type %s!", luaL_typename(L, i)); + formatted_error("node lib","lua <node> expected, not an object with type %s", luaL_typename(L, i)); return NULL; } @@ -297,56 +278,15 @@ halfword *check_isnode(lua_State * L, int i) This routine finds the numerical value of a string (or number) at lua stack index |n|. If it is not a valid node type, returns -1 - Todo: create a lua table instead at initialization time and then - use that hash, so that we don't need to loop for each lookup. - - HH: can crash on noad 9 - */ -static int do_get_node_type_id(lua_State * L, int n, node_info * data) +static int get_node_type_id_from_name(lua_State * L, int n, node_info * data) { int j; - /* switch (lua_type(L, n)) { */ - /* case LUA_TNIL: */ - /* printf("LUA_TNIL\n"); */ - /* break; */ - /* case LUA_TNUMBER: */ - /* printf("LUA_TNUMBER\n"); */ - /* break; */ - /* case LUA_TBOOLEAN: */ - /* printf("LUA_TBOOLEAN\n"); */ - /* break; */ - /* case LUA_TSTRING: */ - /* printf("LUA_TSTRING\n"); */ - /* break; */ - /* case LUA_TTABLE: */ - /* printf("LUA_TTABLE\n"); */ - /* break; */ - /* case LUA_TFUNCTION: */ - /* printf("LUA_TFUNCTION\n"); */ - /* break; */ - /* case LUA_TUSERDATA: */ - /* printf("LUA_TUSERDATA\n"); */ - /* break; */ - /* case LUA_TTHREAD: */ - /* printf("LUA_TTHREAD\n"); */ - /* break; */ - /* case LUA_TLIGHTUSERDATA: */ - /* printf("LUA_TLIGHTUSERDATA\n"); */ - /* break; */ - /* } */ - if (lua_type(L, n) == LUA_TSTRING) { - const char *s = lua_tostring(L, n); - for (j = 0; data[j].id != -1; j++) { - if (strcmp(s, data[j].name) == 0) - return j; - } - } else if (lua_type(L, n) == LUA_TNUMBER) { - int i = (int) lua_tointeger(L, n); - for (j = 0; data[j].id != -1; j++) { - if (data[j].id == i) - return j; + const char *s = lua_tostring(L, n); + for (j = 0; data[j].id != -1; j++) { + if (strcmp(s, data[j].name) == 0) { + return j; } } return -1; @@ -354,26 +294,40 @@ static int do_get_node_type_id(lua_State * L, int n, node_info * data) static int get_valid_node_type_id(lua_State * L, int n) { - int i = get_node_type_id(L, n); - if (i == -1) { - if (lua_type(L, n) == LUA_TSTRING) { - luaL_error(L, "Invalid node type id: %s", lua_tostring(L, n)); - } else { - luaL_error(L, "Invalid node type id: %d", lua_tonumber(L, n)); + int i = -1; + int t = lua_type(L, n); + if (t == LUA_TSTRING) { + i = get_node_type_id_from_name(L,n,node_data); + if (i<0) { + luaL_error(L, "invalid node type id: %s", lua_tostring(L, n)); + } + } else if (t == LUA_TNUMBER) { + i = lua_tointeger(L,n); + if (! known_node_type(i)) { + luaL_error(L, "invalid node type id: %d", i); } + } else { + luaL_error(L, "invalid node type id"); } return i; } static int get_valid_node_subtype_id(lua_State * L, int n) { - int i = get_node_subtype_id(L, n); - if (i == -1) { - if (lua_type(L, n) == LUA_TSTRING) { - luaL_error(L, "Invalid whatsit node id: %s", lua_tostring(L, n)); - } else { - luaL_error(L, "Invalid whatsit node id: %d", lua_tonumber(L, n)); + int i = -1; + int t = lua_type(L, n); + if (t == LUA_TSTRING) { + i = get_node_type_id_from_name(L,n,whatsit_node_data); + if (i<0) { + luaL_error(L, "invalid whatsit type id: %s", lua_tostring(L, n)); } + } else if (t == LUA_TNUMBER) { + i = lua_tointeger(L,n); + if (! known_whatsit_type(i)) { + luaL_error(L, "invalid whatsit type id: %d", i); + } + } else { + luaL_error(L, "invalid whatsit type id"); } return i; } @@ -486,9 +440,13 @@ void lua_nodelib_push_fast(lua_State * L, halfword n) static int lua_nodelib_id(lua_State * L) { - int i = get_node_type_id(L, 1); - if (i >= 0) { - lua_pushnumber(L, i); + if (lua_type(L,1) == LUA_TSTRING) { + int i = get_node_type_id_from_name(L, 1, node_data); + if (i >= 0) { + lua_pushinteger(L, i); + } else { + lua_pushnil(L); + } } else { lua_pushnil(L); } @@ -512,7 +470,7 @@ static int lua_nodelib_getid(lua_State * L) if (!lua_rawequal(L, -1, -2)) { lua_pushnil(L); } else { - lua_pushnumber(L, type(*p)); + lua_pushinteger(L, type(*p)); } return 1; } @@ -523,7 +481,7 @@ static int lua_nodelib_getid(lua_State * L) { halfword *n; n = (halfword *) lua_touserdata(L, 1); - lua_pushnumber(L, type(*n)); + lua_pushinteger(L, type(*n)); return 1; } @@ -533,12 +491,11 @@ static int lua_nodelib_getid(lua_State * L) static int lua_nodelib_direct_getid(lua_State * L) { - halfword n; - n = (halfword) lua_tonumber(L, 1); + halfword n = lua_tointeger(L, 1); if (n == null) { lua_pushnil(L); } else { - lua_pushnumber(L, type(n)); + lua_pushinteger(L, type(n)); } return 1; } @@ -555,7 +512,7 @@ static int lua_nodelib_getsubtype(lua_State * L) if ( (!lua_rawequal(L, -1, -2)) || (! nodetype_has_subtype(*p))) { lua_pushnil(L); } else { - lua_pushnumber(L, subtype(*p)); + lua_pushinteger(L, subtype(*p)); } } return 1; @@ -567,7 +524,7 @@ static int lua_nodelib_getsubtype(lua_State * L) { halfword *n; n = (halfword *) lua_touserdata(L, 1); - lua_pushnumber(L, subtype(*n)); + lua_pushinteger(L, subtype(*n)); return 1; } @@ -577,12 +534,11 @@ static int lua_nodelib_getsubtype(lua_State * L) static int lua_nodelib_direct_getsubtype(lua_State * L) { - halfword n; - n = (halfword) lua_tonumber(L, 1); + halfword n = lua_tointeger(L, 1); if (n == null) { /* no check, we assume sane use */ lua_pushnil(L); } else { - lua_pushnumber(L, subtype(n)); + lua_pushinteger(L, subtype(n)); } return 1; } @@ -599,7 +555,7 @@ static int lua_nodelib_getfont(lua_State * L) if ( (!lua_rawequal(L, -1, -2)) || (type(*p) != glyph_node) ) { lua_pushnil(L); } else { - lua_pushnumber(L, font(*p)); + lua_pushinteger(L, font(*p)); } } return 1; @@ -614,7 +570,7 @@ static int lua_nodelib_getfont(lua_State * L) if (type(*n) != glyph_node) { lua_pushnil(L); } else { - lua_pushnumber(L, font(*n)); + lua_pushinteger(L, font(*n)); } return 1; } @@ -628,11 +584,11 @@ static int lua_nodelib_getfont(lua_State * L) static int lua_nodelib_direct_getfont(lua_State * L) { halfword n; - n = (halfword) lua_tonumber(L, 1); + n = (halfword) lua_tointeger(L, 1); if ((n == null) || (type(n) != glyph_node)) { lua_pushnil(L); } else { - lua_pushnumber(L, font(n)); + lua_pushinteger(L, font(n)); } return 1; } @@ -641,14 +597,13 @@ static int lua_nodelib_direct_getfont(lua_State * L) static int lua_nodelib_direct_getfont(lua_State * L) /* family_font is not yet in manual, what does arg 2 do */ { - halfword n, t; - n = (halfword) lua_tonumber(L, 1); + halfword n = lua_tointeger(L, 1); if (n != null) { - t = type(n); + halfword t = type(n); if (t == glyph_node) { - lua_pushnumber(L, font(n)); + lua_pushinteger(L, font(n)); } else if ((t == math_char_node) || (t == math_text_char_node)) { - lua_pushnumber(L, fam_fnt(math_fam(n), 0)); + lua_pushinteger(L, fam_fnt(math_fam(n), 0)); } else { lua_pushnil(L); } @@ -666,9 +621,9 @@ static int lua_nodelib_getcharacter(lua_State * L) if ( (n == NULL) || (! lua_getmetatable(L,1)) ) { lua_pushnil(L); } else if (type(*n) == glyph_node) { - lua_pushnumber(L, character(*n)); + lua_pushinteger(L, character(*n)); } else if ((type(*n) == math_char_node) || (type(*n) == math_text_char_node)) { - lua_pushnumber(L, math_character(*n)); + lua_pushinteger(L, math_character(*n)); } return 1; } @@ -680,9 +635,9 @@ static int lua_nodelib_getcharacter(lua_State * L) halfword *n; n = (halfword *) lua_touserdata(L, 1); if (type(*n) == glyph_node) { - lua_pushnumber(L, character(*n)); + lua_pushinteger(L, character(*n)); } else if ((type(*n) == math_char_node) || (type(*n) == math_text_char_node)) { - lua_pushnumber(L, math_character(*n)); + lua_pushinteger(L, math_character(*n)); } else { lua_pushnil(L); } @@ -695,14 +650,13 @@ static int lua_nodelib_getcharacter(lua_State * L) static int lua_nodelib_direct_getcharacter(lua_State * L) { - halfword n; - n = (halfword) lua_tonumber(L, 1); + halfword n = lua_tointeger(L, 1); if (n == null) { lua_pushnil(L); } else if (type(n) == glyph_node) { - lua_pushnumber(L, character(n)); + lua_pushinteger(L, character(n)); } else if ((type(n) == math_char_node) || (type(n) == math_text_char_node)) { - lua_pushnumber(L, math_character(n)); + lua_pushinteger(L, math_character(n)); } else { lua_pushnil(L); } @@ -714,8 +668,7 @@ static int lua_nodelib_direct_getcharacter(lua_State * L) static int lua_nodelib_direct_getdiscretionary(lua_State * L) { - halfword n; - n = (halfword) lua_tonumber(L, 1); + halfword n = lua_tointeger(L, 1); if (n != null) { if (type(n) == disc_node) { nodelib_pushdirect_or_nil(vlink(pre_break(n))); @@ -756,9 +709,8 @@ static int lua_nodelib_getlist(lua_State * L) static int lua_nodelib_direct_getlist(lua_State * L) { - halfword n; - n = (halfword) lua_tonumber(L, 1); - if ( n == null) { + halfword n = lua_tointeger(L, 1); + if (n == null) { lua_pushnil(L); } else if ((type(n) == hlist_node) || (type(n) == vlist_node)) { nodelib_pushdirect_or_nil_alink(list_ptr(n)); @@ -788,9 +740,8 @@ static int lua_nodelib_getleader(lua_State * L) static int lua_nodelib_direct_getleader(lua_State * L) { - halfword n; - n = (halfword) lua_tonumber(L, 1); - if ( n == null) { + halfword n = lua_tointeger(L, 1); + if (n == null) { lua_pushnil(L); } else if (type(n) == glue_node) { nodelib_pushdirect_or_nil(leader_ptr(n)); @@ -828,22 +779,16 @@ static int lua_nodelib_getnext(lua_State * L) static int lua_nodelib_fast_getnext(lua_State * L) { halfword *a; - // [given-node] [...] halfword *p = lua_touserdata(L, 1); if ((p == NULL) || (!vlink(*p))){ lua_pushnil(L); } else { lua_settop(L,1); - // [given-node] lua_getmetatable(L,1); - // [given-node] [mt-node] a = lua_newuserdata(L, sizeof(halfword)); - // [given-node] [mt-node] [next-node] *a = vlink(*p); lua_replace(L,1); - // [next-node] [mt-node] lua_setmetatable(L,1); - // [next-node-with-mt] } return 1; } @@ -854,8 +799,7 @@ static int lua_nodelib_getnext(lua_State * L) static int lua_nodelib_direct_getnext(lua_State * L) { - halfword p; - p = (halfword) lua_tonumber(L, 1); + halfword p = lua_tointeger(L, 1); if (p == null) { lua_pushnil(L); } else { @@ -910,22 +854,16 @@ static int lua_nodelib_getboth(lua_State * L) static int lua_nodelib_fast_getprev(lua_State * L) { halfword *a; - // [given-node] [...] halfword *p = lua_touserdata(L, 1); if ((p == NULL) || (!alink(*p))) { lua_pushnil(L); } else { lua_settop(L,1); - // [given-node] lua_getmetatable(L,1); - // [given-node] [mt-node] a = lua_newuserdata(L, sizeof(halfword)); - // [given-node] [mt-node] [next-node] *a = alink(*p); lua_replace(L,1); - // [next-node] [mt-node] lua_setmetatable(L,1); - // [next-node-with-mt] } return 1; } @@ -936,8 +874,7 @@ static int lua_nodelib_getboth(lua_State * L) static int lua_nodelib_direct_getprev(lua_State * L) { - halfword p; - p = (halfword) lua_tonumber(L, 1); + halfword p = lua_tointeger(L, 1); if (p == null) { lua_pushnil(L); } else { @@ -950,8 +887,7 @@ static int lua_nodelib_direct_getprev(lua_State * L) static int lua_nodelib_direct_getboth(lua_State * L) { - halfword p; - p = (halfword) lua_tonumber(L, 1); + halfword p = lua_tointeger(L, 1); if (p == null) { lua_pushnil(L); lua_pushnil(L); @@ -962,13 +898,13 @@ static int lua_nodelib_direct_getboth(lua_State * L) return 2; } -/* node.subtype */ +/* node.subtype (maybe also return them for other node types now) */ static int lua_nodelib_subtype(lua_State * L) { - int i = get_node_subtype_id(L, 1); + int i = get_node_type_id_from_name(L,1,whatsit_node_data); if (i >= 0) { - lua_pushnumber(L, i); + lua_pushinteger(L, i); } else { lua_pushnil(L); /* return 0; */ } @@ -980,8 +916,8 @@ static int lua_nodelib_subtype(lua_State * L) static int lua_nodelib_type(lua_State * L) { if (lua_type(L,1) == LUA_TNUMBER) { - int i = get_node_type_id(L, 1); - if (i >= 0) { + int i = lua_tointeger(L, 1); + if (known_node_type(i)) { lua_pushstring(L, node_data[i].name); return 1; } @@ -999,17 +935,39 @@ static int lua_nodelib_new(lua_State * L) { int i, j; halfword n = null; - i = get_valid_node_type_id(L, 1); + int t = lua_type(L, 1); + if (t == LUA_TNUMBER) { + i = lua_tointeger(L,1); + if (! known_node_type(i)) { + i = -1; + } + } else if (t == LUA_TSTRING) { + i = get_node_type_id_from_name(L,1,node_data); + } else { + i = -1; + } + if (i < 0) { + luaL_error(L, "invalid node id for creating new node"); + } + t = lua_type(L, 2); if (i == whatsit_node) { - j = -1; - if (lua_gettop(L) > 1) - j = get_valid_node_subtype_id(L, 2); - if (j < 0) - luaL_error(L, "Creating a whatsit requires the subtype number as a second argument"); + if (t == LUA_TNUMBER) { + j = lua_tointeger(L,2); + if (! known_whatsit_type(j)) { + j = -1; + } + } else if (t == LUA_TSTRING) { + j = get_node_type_id_from_name(L,2,whatsit_node_data); + } else { + j = -1; + } + if (j < 0) { + luaL_error(L, "creating a whatsit requires the subtype number as a second argument"); + } + } else if (t == LUA_TNUMBER) { + j = (int) lua_tointeger(L, 2); } else { j = 0; - if (lua_gettop(L) > 1) - j = (int) lua_tointeger(L, 2); } n = new_node(i, j); lua_nodelib_push_fast(L, n); @@ -1020,9 +978,9 @@ static int lua_nodelib_new(lua_State * L) static int lua_nodelib_direct_new(lua_State * L) { - int i, j; + int j; halfword n ; - i = get_valid_node_type_id(L, 1); + int i = get_valid_node_type_id(L, 1); if (i == whatsit_node) { j = -1; if (lua_gettop(L) > 1) @@ -1035,7 +993,7 @@ static int lua_nodelib_direct_new(lua_State * L) j = (int) lua_tointeger(L, 2); } n = new_node(i, j); - lua_pushnumber(L,n); + lua_pushinteger(L,n); return 1; } @@ -1043,7 +1001,7 @@ static int lua_nodelib_direct_new(lua_State * L) static int lua_nodelib_free(lua_State * L) { - halfword *n; + halfword n; halfword p; if (lua_gettop(L) < 1) { lua_pushnil(L); @@ -1051,11 +1009,11 @@ static int lua_nodelib_free(lua_State * L) } else if (lua_isnil(L, 1)) { return 1; /* the nil itself */ } - n = check_isnode(L, 1); - p = vlink(*n); - flush_node(*n); + n = *(check_isnode(L, 1)); + p = vlink(n); + flush_node(n); /* can be: lua_nodelib_push_fast(L, p); */ - lua_pushnumber(L, p); + lua_pushinteger(L, p); lua_nodelib_push(L); return 1; } @@ -1064,18 +1022,16 @@ static int lua_nodelib_free(lua_State * L) static int lua_nodelib_direct_free(lua_State * L) { - halfword n; - halfword p; - n = (halfword) lua_tonumber(L,1); + halfword n = lua_tointeger(L,1); if (n == null) { lua_pushnil(L); } else { - p = vlink(n); + halfword p = vlink(n); flush_node(n); if (p == 0) { lua_pushnil(L); } else { - lua_pushnumber(L,p); + lua_pushinteger(L,p); } } return 1; @@ -1085,21 +1041,20 @@ static int lua_nodelib_direct_free(lua_State * L) static int lua_nodelib_flush_node(lua_State * L) { - halfword *n; - if ((lua_gettop(L) < 1) || lua_isnil(L, 1)) + if ((lua_gettop(L) < 1) || lua_isnil(L, 1)) { return 0; - n = check_isnode(L, 1); - // no check if n? - flush_node(*n); - return 0; + } else { + halfword n = *(check_isnode(L, 1)); + flush_node(n); + return 0; + } } /* node.direct.flush_node */ static int lua_nodelib_direct_flush_node(lua_State * L) { - halfword n; - n = (halfword) lua_tonumber(L,1); + halfword n = lua_tointeger(L,1); if (n == null) return 0; flush_node(n); @@ -1110,20 +1065,20 @@ static int lua_nodelib_direct_flush_node(lua_State * L) static int lua_nodelib_flush_list(lua_State * L) { - halfword *n_ptr; - if ((lua_gettop(L) < 1) || lua_isnil(L, 1)) + if ((lua_gettop(L) < 1) || lua_isnil(L, 1)) { return 0; - n_ptr = check_isnode(L, 1); - flush_node_list(*n_ptr); - return 0; + } else { + halfword n_ptr = *check_isnode(L, 1); + flush_node_list(n_ptr); + return 0; + } } /* node.direct.flush_list */ static int lua_nodelib_direct_flush_list(lua_State * L) { - halfword n; - n = (halfword) lua_tonumber(L,1); + halfword n = lua_tointeger(L,1); if (n == null) return 0; flush_node_list(n); @@ -1153,23 +1108,20 @@ static int lua_nodelib_remove(lua_State * L) if (lua_gettop(L) < 2) luaL_error(L, "Not enough arguments for node.remove()"); head = *(check_isnode(L, 1)); -#if DEBUG - show_node_links(head, "before"); -#endif if (lua_isnil(L, 2)) return 2; /* the arguments, as they are */ current = *(check_isnode(L, 2)); if (head == current) { if (alink(current)){ - vlink(alink(current)) = vlink(current); // vlink(prev) = next + vlink(alink(current)) = vlink(current); } if (vlink(current)){ - alink( vlink(current)) = alink(current); // alink(next) = prev + alink( vlink(current)) = alink(current); } - head = vlink(current); //head = next - current = vlink(current); //current = next - } else { /* head != current */ + head = vlink(current); + current = vlink(current); + } else { t = alink(current); if (t == null || vlink(t) != current) { set_t_to_prev(head, current); @@ -1186,10 +1138,10 @@ static int lua_nodelib_remove(lua_State * L) show_node_links(head, "after"); #endif /* can be: lua_nodelib_push_fast(L, head); */ - lua_pushnumber(L, head); + lua_pushinteger(L, head); lua_nodelib_push(L); /* can be: lua_nodelib_push_fast(L, current); */ - lua_pushnumber(L, current); + lua_pushinteger(L, current); lua_nodelib_push(L); return 2; } @@ -1198,28 +1150,28 @@ static int lua_nodelib_remove(lua_State * L) static int lua_nodelib_direct_remove(lua_State * L) { - halfword head, current , t; - head = (halfword) lua_tonumber(L,1); + halfword current, t; + halfword head = lua_tointeger(L,1); if (head == null) { lua_pushnil(L); lua_pushnil(L); return 2 ; } - current = (halfword) lua_tonumber(L,2); + current = (halfword) lua_tointeger(L,2); if (current == null) { - lua_pushnumber(L, head); + lua_pushinteger(L, head); lua_pushnil(L); return 2 ; } if (head == current) { if (alink(current)){ - vlink( alink(current) ) = vlink(current); // vlink(prev) = next + vlink( alink(current) ) = vlink(current); } if (vlink(current)){ - alink( vlink(current) ) = alink(current); // alink(next) = prev + alink( vlink(current) ) = alink(current); } - head = vlink(current); //head = next - current = vlink(current); //current = next + head = vlink(current); + current = vlink(current); } else { t = alink(current); if (t == null || vlink(t) != current) { @@ -1236,12 +1188,12 @@ static int lua_nodelib_direct_remove(lua_State * L) if (head == null) { lua_pushnil(L); } else { - lua_pushnumber(L, head); + lua_pushinteger(L, head); } if (current == null) { lua_pushnil(L); } else { - lua_pushnumber(L, current); + lua_pushinteger(L, current); } return 2; } @@ -1298,20 +1250,20 @@ static int lua_nodelib_insert_before(lua_State * L) static int lua_nodelib_direct_insert_before(lua_State * L) { - halfword head, current, n, t; - n = (halfword) lua_tonumber(L,3); + halfword head, current; + halfword n = lua_tointeger(L,3); if (n == null){ /* no node */ lua_pop(L, 1); return 2 ; } - head = (halfword) lua_tonumber(L,1); - current = (halfword) lua_tonumber(L,2); + head = (halfword) lua_tointeger(L,1); + current = (halfword) lua_tointeger(L,2); /* no head, ignore current */ if (head == null) { vlink(n) = null; alink(n) = null; - lua_pushnumber(L, n); + lua_pushinteger(L, n); lua_pushvalue(L, -1); /* n, n */ return 2; @@ -1320,18 +1272,18 @@ static int lua_nodelib_direct_insert_before(lua_State * L) if (current == null) current = tail_of_list(head); if (head != current) { - t = alink(current); + halfword t = alink(current); if (t == null || vlink(t) != current) set_t_to_prev(head, current); couple_nodes(t, n); } couple_nodes(n, current); if (head == current) { - lua_pushnumber(L, n); + lua_pushinteger(L, n); } else { - lua_pushnumber(L, head); + lua_pushinteger(L, head); } - lua_pushnumber(L, n); + lua_pushinteger(L, n); return 2; } @@ -1377,20 +1329,20 @@ static int lua_nodelib_insert_after(lua_State * L) static int lua_nodelib_direct_insert_after(lua_State * L) { - halfword head, current, n; + halfword head, current; /*[head][current][new]*/ - n = (halfword) lua_tonumber(L,3); + halfword n = lua_tointeger(L,3); if (n == null) { /* no node */ return 2 ; } - head = (halfword) lua_tonumber(L,1); - current = (halfword) lua_tonumber(L,2); + head = (halfword) lua_tointeger(L,1); + current = (halfword) lua_tointeger(L,2); if (head == null) { /* no head, ignore current */ vlink(n) = null; alink(n) = null; - lua_pushnumber(L,n); + lua_pushinteger(L,n); lua_pushvalue(L, -1); /* n, n */ return 2; @@ -1404,14 +1356,18 @@ static int lua_nodelib_direct_insert_after(lua_State * L) try_couple_nodes(n, vlink(current)); couple_nodes(current, n); lua_pop(L, 2); - lua_pushnumber(L, n); + lua_pushinteger(L, n); return 2; } /* node.copy_list */ -/* hh-ls: we need to use an intermediate variable as otherwise target is used in the loop -and subfields get overwritten (or something like that) which results in crashes and -unexpected side effects */ + +/* + we need to use an intermediate variable as otherwise target is used in the loop + and subfields get overwritten (or something like that) which results in crashes + and unexpected side effects +*/ + static int lua_nodelib_copy_list(lua_State * L) { halfword n, s = null; @@ -1427,23 +1383,22 @@ static int lua_nodelib_copy_list(lua_State * L) } - /* node.direct.copy_list */ static int lua_nodelib_direct_copy_list(lua_State * L) { - halfword n, s, m; - n = (halfword) lua_tonumber(L,1); + halfword n = lua_tointeger(L,1); if (n == null) { lua_pushnil(L); } else { - s = (halfword) lua_tonumber(L,2); + halfword s = lua_tointeger(L,2); + halfword m; if (s == null) { m = do_copy_node_list(n,null); } else { m = do_copy_node_list(n,s); } - lua_pushnumber(L,m); + lua_pushinteger(L,m); } return 1; } @@ -1452,13 +1407,12 @@ static int lua_nodelib_direct_copy_list(lua_State * L) static int lua_nodelib_copy(lua_State * L) { - halfword *n; - halfword m; + halfword n; if (lua_isnil(L, 1)) return 1; /* the nil itself */ - n = check_isnode(L, 1); - m = copy_node(*n); - lua_nodelib_push_fast(L, m); + n = *check_isnode(L, 1); + n = copy_node(n); + lua_nodelib_push_fast(L, n); return 1; } @@ -1466,15 +1420,15 @@ static int lua_nodelib_copy(lua_State * L) static int lua_nodelib_direct_copy(lua_State * L) { - halfword n; - halfword m; - if (lua_isnil(L, 1)) + if (lua_isnil(L, 1)) { return 1; /* the nil itself */ - /* beware, a glue node can have number 0 (zeropt) so we cannot test for null) */ - n = (halfword) lua_tonumber(L, 1); - m = copy_node(n); - lua_pushnumber(L, m); - return 1; + } else { + /* beware, a glue node can have number 0 (zeropt) so we cannot test for null) */ + halfword n = lua_tointeger(L, 1); + n = copy_node(n); + lua_pushinteger(L, n); + return 1; + } } @@ -1482,17 +1436,15 @@ static int lua_nodelib_direct_copy(lua_State * L) static int lua_nodelib_append(lua_State * L) { - halfword *n; - halfword m; - int i, j; - j = lua_gettop(L); + halfword n; + int i; + int j = lua_gettop(L); for (i = 1; i <= j; i++) { - n = check_isnode(L, i); - m = *n; - tail_append(m); - while (vlink(m) != null) { - m = vlink(m); - tail_append(m); + n = *check_isnode(L, i); + tail_append(n); + while (vlink(n) != null) { + n = vlink(n); + tail_append(n); } } return 0; @@ -1502,12 +1454,11 @@ static int lua_nodelib_append(lua_State * L) static int lua_nodelib_direct_append(lua_State * L) { - halfword n; halfword m; - int i, j; - j = lua_gettop(L); + int i; + int j = lua_gettop(L); for (i = 1; i <= j; i++) { - n = (halfword) lua_tonumber(L,i); /*lua_getnumber(L, i);*/ + halfword n = lua_tointeger(L,i); /*lua_getnumber(L, i);*/ if (n != null) { m = n ; tail_append(m); @@ -1524,10 +1475,9 @@ static int lua_nodelib_direct_append(lua_State * L) static int lua_nodelib_last_node(lua_State * L) { - halfword m; - m = pop_tail(); + halfword m = pop_tail(); /* can be: lua_nodelib_push_fast(L, m); */ - lua_pushnumber(L, m); + lua_pushinteger(L, m); lua_nodelib_push(L); return 1; } @@ -1536,9 +1486,8 @@ static int lua_nodelib_last_node(lua_State * L) static int lua_nodelib_direct_last_node(lua_State * L) { - halfword m; - m = pop_tail(); - lua_pushnumber(L, m); + halfword m = pop_tail(); + lua_pushinteger(L, m); return 1; } @@ -1546,12 +1495,12 @@ static int lua_nodelib_direct_last_node(lua_State * L) static int lua_nodelib_hpack(lua_State * L) { - halfword n, p; + halfword p; const char *s; int w = 0; int m = 1; int d = -1; - n = *(check_isnode(L, 1)); + halfword n = *(check_isnode(L, 1)); if (lua_gettop(L) > 1) { w = (int) lua_tointeger(L, 2); if (lua_gettop(L) > 2) { @@ -1569,7 +1518,7 @@ static int lua_nodelib_hpack(lua_State * L) luaL_error(L, "3rd argument should be either additional or exactly"); } } else if (lua_type(L, 3) == LUA_TNUMBER) { - m=(int)lua_tonumber(L, 3); + m = (int) lua_tointeger(L, 3); } else { lua_pushstring(L, "incorrect 3rd argument"); } @@ -1584,7 +1533,7 @@ static int lua_nodelib_hpack(lua_State * L) } p = hpack(n, w, m, d); lua_nodelib_push_fast(L, p); - lua_pushnumber(L, last_badness); + lua_pushinteger(L, last_badness); return 2; } @@ -1592,12 +1541,12 @@ static int lua_nodelib_hpack(lua_State * L) static int lua_nodelib_direct_hpack(lua_State * L) { - halfword n, p; + halfword p; const char *s; int w = 0; int m = 1; int d = -1; - n = (halfword) lua_tonumber(L,1); + halfword n = lua_tointeger(L,1); /* could be macro */ if (lua_gettop(L) > 1) { w = (int) lua_tointeger(L, 2); @@ -1616,7 +1565,7 @@ static int lua_nodelib_direct_hpack(lua_State * L) luaL_error(L, "3rd argument should be either additional or exactly"); } } else if (lua_type(L, 3) == LUA_TNUMBER) { - m=(int)lua_tonumber(L, 3); + m = (int) lua_tointeger(L, 3); } else { lua_pushstring(L, "incorrect 3rd argument"); } @@ -1631,8 +1580,8 @@ static int lua_nodelib_direct_hpack(lua_State * L) } /* till here */ p = hpack(n, w, m, d); - lua_pushnumber(L, p); - lua_pushnumber(L, last_badness); + lua_pushinteger(L, p); + lua_pushinteger(L, last_badness); return 2; } @@ -1640,12 +1589,12 @@ static int lua_nodelib_direct_hpack(lua_State * L) static int lua_nodelib_vpack(lua_State * L) { - halfword n, p; + halfword p; const char *s; int w = 0; int m = 1; int d = -1; - n = *(check_isnode(L, 1)); + halfword n = *(check_isnode(L, 1)); if (lua_gettop(L) > 1) { w = (int) lua_tointeger(L, 2); if (lua_gettop(L) > 2) { @@ -1669,7 +1618,7 @@ static int lua_nodelib_vpack(lua_State * L) } else if (lua_type(L, 3) == LUA_TNUMBER) { - m=(int)lua_tonumber(L, 3); + m= (int) lua_tointeger(L, 3); } else { lua_pushstring(L, "incorrect 3rd argument"); } @@ -1677,7 +1626,7 @@ static int lua_nodelib_vpack(lua_State * L) } p = vpackage(n, w, m, max_dimen, d); lua_nodelib_push_fast(L, p); - lua_pushnumber(L, last_badness); + lua_pushinteger(L, last_badness); return 2; } @@ -1685,12 +1634,12 @@ static int lua_nodelib_vpack(lua_State * L) static int lua_nodelib_direct_vpack(lua_State * L) { - halfword n, p; + halfword p; const char *s; int w = 0; int m = 1; int d = -1; - n = (halfword) lua_tonumber(L,1); + halfword n = (halfword) lua_tointeger(L,1); if (lua_gettop(L) > 1) { w = (int) lua_tointeger(L, 2); if (lua_gettop(L) > 2) { @@ -1714,15 +1663,15 @@ static int lua_nodelib_direct_vpack(lua_State * L) } else if (lua_type(L, 3) == LUA_TNUMBER) { - m=(int)lua_tonumber(L, 3); + m= (int) lua_tointeger(L, 3); } else { lua_pushstring(L, "incorrect 3rd argument"); } } } p = vpackage(n, w, m, max_dimen, d); - lua_pushnumber(L, p); - lua_pushnumber(L, last_badness); + lua_pushinteger(L, p); + lua_pushinteger(L, last_badness); return 2; } @@ -1730,8 +1679,7 @@ static int lua_nodelib_direct_vpack(lua_State * L) static int lua_nodelib_dimensions(lua_State * L) { - int top; - top = lua_gettop(L); + int top = lua_gettop(L); if (top > 0) { scaled_whd siz; glue_ratio g_mult = 1.0; @@ -1746,9 +1694,9 @@ static int lua_nodelib_dimensions(lua_State * L) return 1; } i += 3; - g_mult = (glue_ratio) lua_tonumber(L, 1); - g_sign=(int)lua_tonumber(L, 2); - g_order=(int)lua_tonumber(L, 3); + g_mult = (glue_ratio) lua_tonumber(L, 1); /* integer or float */ + g_sign = (int) lua_tointeger(L, 2); + g_order = (int) lua_tointeger(L, 3); } n = *(check_isnode(L, i)); if (lua_gettop(L) > i && !lua_isnil(L, (i + 1))) { @@ -1762,9 +1710,9 @@ static int lua_nodelib_dimensions(lua_State * L) d = nodelib_getdir(L, (i + 2), 1); } siz = natural_sizes(n, p, g_mult, g_sign, g_order, d); - lua_pushnumber(L, siz.wd); - lua_pushnumber(L, siz.ht); - lua_pushnumber(L, siz.dp); + lua_pushinteger(L, siz.wd); + lua_pushinteger(L, siz.ht); + lua_pushinteger(L, siz.dp); return 3; } else { luaL_error(L, "missing argument to 'dimensions' (node expected)"); @@ -1776,8 +1724,7 @@ static int lua_nodelib_dimensions(lua_State * L) static int lua_nodelib_direct_dimensions(lua_State * L) { - int top; - top = lua_gettop(L); + int top = lua_gettop(L); if (top > 0) { scaled_whd siz; glue_ratio g_mult = 1.0; @@ -1788,24 +1735,24 @@ static int lua_nodelib_direct_dimensions(lua_State * L) halfword n = null, p = null; if (top > 3) { i += 3; - g_mult = (glue_ratio) lua_tonumber(L, 1); - g_sign=(int)lua_tonumber(L, 2); - g_order=(int)lua_tonumber(L, 3); + g_mult = (glue_ratio) lua_tonumber(L, 1); /* integer or float */ + g_sign = (int) lua_tointeger(L, 2); + g_order = (int) lua_tointeger(L, 3); } - n = (halfword) lua_tonumber(L,i); + n = (halfword) lua_tointeger(L,i); if (lua_gettop(L) > i && !lua_isnil(L, (i + 1))) { if (lua_type(L, (i + 1)) == LUA_TSTRING) { d = nodelib_getdir(L, (i + 1), 1); } else { - p = (halfword) lua_tonumber(L,i+1); + p = (halfword) lua_tointeger(L,i+1); } } if (lua_gettop(L) > (i + 1) && lua_type(L, (i + 2)) == LUA_TSTRING) d = nodelib_getdir(L, (i + 2), 1); siz = natural_sizes(n, p, g_mult, g_sign, g_order, d); - lua_pushnumber(L, siz.wd); - lua_pushnumber(L, siz.ht); - lua_pushnumber(L, siz.dp); + lua_pushinteger(L, siz.wd); + lua_pushinteger(L, siz.ht); + lua_pushinteger(L, siz.dp); return 3; } else { luaL_error(L, "missing argument to 'dimensions' (node expected)"); @@ -1817,15 +1764,13 @@ static int lua_nodelib_direct_dimensions(lua_State * L) static int lua_nodelib_mlist_to_hlist(lua_State * L) { - halfword n; int w; boolean m; - n = *(check_isnode(L, 1)); - //w = luaL_checkoption(L, 2, "text", math_style_names); + halfword n = *(check_isnode(L, 1)); assign_math_style(L,2,w); luaL_checkany(L, 3); m = lua_toboolean(L, 3); - mlist_to_hlist_args(n, w, m); + mlist_to_hlist(n, m, w); alink(vlink(temp_head)) = null; /*hh-ls */ lua_nodelib_push_fast(L, vlink(temp_head)); return 1; @@ -1835,13 +1780,13 @@ static int lua_nodelib_mlist_to_hlist(lua_State * L) static int lua_nodelib_mfont(lua_State * L) { - int f, s; - f = (int) luaL_checkinteger(L, 1); + int s; + int f = luaL_checkinteger(L, 1); if (lua_gettop(L) == 2) - s = (int) lua_tointeger(L, 2); /* this should be a multiple of 256 ! */ + s = lua_tointeger(L, 2); /* this should be a multiple of 256 ! */ else s = 0; - lua_pushnumber(L, fam_fnt(f, s)); + lua_pushinteger(L, fam_fnt(f,s)); return 1; } @@ -1911,13 +1856,34 @@ static int lua_nodelib_has_field(lua_State * L) return 1; } +/* node.is_char (node[,font]) */ + +static int lua_nodelib_is_char(lua_State * L) +{ + halfword f; + halfword n = *(check_isnode(L, 1)); + if ((type(n) == glyph_node) && (subtype(n) < 256)) { /* <= 256 */ + if (lua_type(L,2) == LUA_TNUMBER) { + f = (halfword) lua_tointeger(L, 2); + if (f && f == font(n)) { + lua_pushinteger(L,character(n)); + return 1; + } + } else { + lua_pushinteger(L,character(n)); + return 1; + } + } + lua_pushboolean(L,0); + return 1; +} + /* node.direct.has_field */ static int lua_nodelib_direct_has_field(lua_State * L) { int i = -2; - halfword n; - n = (halfword) lua_tonumber(L, 1); + halfword n = lua_tointeger(L, 1); if (n != null) i = get_node_field_id(L, 2, n); lua_pushboolean(L, (i != -2)); @@ -1993,10 +1959,9 @@ static int lua_nodelib_subtypes(lua_State * L) { int i = -1; int l = 0; - int t; const char **subtypes = NULL; const char *s ; - t = lua_type(L,1); + int t = lua_type(L,1); if (t == LUA_TSTRING) { /* official accessors */ s = lua_tostring(L,1); @@ -2020,7 +1985,7 @@ static int lua_nodelib_subtypes(lua_State * L) else if (lua_key_eq(s,pdf_literal)) subtypes = node_subtypes_pdf_literal; } else if (t == LUA_TNUMBER) { /* maybe */ - t = lua_tonumber(L,1); + t = lua_tointeger(L,1); if (t == glyph_node) subtypes = node_subtypes_glyph; else if (t == glue_node) { subtypes = node_subtypes_glue; l = 1; } else if (t == penalty_node) subtypes = node_subtypes_penalty; @@ -2066,20 +2031,18 @@ static int lua_nodelib_subtypes(lua_State * L) static int lua_nodelib_slide(lua_State * L) { - halfword *n; - halfword t; + halfword n; if (lua_isnil(L, 1)) return 1; /* the nil itself */ - n = check_isnode(L, 1); - t = *n; - if (t == null) + n = *check_isnode(L, 1); + if (n == null) return 1; /* the old userdata */ /* alink(t) = null; */ /* don't do this, |t|'s |alink| may be a valid pointer */ - while (vlink(t) != null) { - alink(vlink(t)) = t; - t = vlink(t); + while (vlink(n) != null) { + alink(vlink(n)) = n; + n = vlink(n); } - lua_nodelib_push_fast(L, t); + lua_nodelib_push_fast(L, n); return 1; } @@ -2087,8 +2050,7 @@ static int lua_nodelib_slide(lua_State * L) static int lua_nodelib_direct_slide(lua_State * L) { - halfword n; - n = (halfword) lua_tonumber(L, 1); + halfword n = lua_tointeger(L, 1); if (n == null) { lua_pushnil(L); } else { @@ -2096,7 +2058,7 @@ static int lua_nodelib_direct_slide(lua_State * L) alink(vlink(n)) = n; n = vlink(n); } - lua_pushnumber(L, n); + lua_pushinteger(L, n); } return 1; } @@ -2105,17 +2067,15 @@ static int lua_nodelib_direct_slide(lua_State * L) static int lua_nodelib_tail(lua_State * L) { - halfword *n; - halfword t; + halfword n; if (lua_isnil(L, 1)) return 1; /* the nil itself */ - n = check_isnode(L, 1); - t = *n; - if (t == null) + n = *check_isnode(L, 1); + if (n == null) return 1; /* the old userdata */ - while (vlink(t) != null) - t = vlink(t); - lua_nodelib_push_fast(L, t); + while (vlink(n) != null) + n = vlink(n); + lua_nodelib_push_fast(L, n); return 1; } @@ -2123,14 +2083,13 @@ static int lua_nodelib_tail(lua_State * L) static int lua_nodelib_direct_tail(lua_State * L) { - halfword n; - n = (halfword) lua_tonumber(L, 1); + halfword n = lua_tointeger(L, 1); if (n == null) { lua_pushnil(L); } else { while (vlink(n) != null) n = vlink(n); - lua_pushnumber(L, n); + lua_pushinteger(L, n); } return 1; } @@ -2139,22 +2098,20 @@ static int lua_nodelib_direct_tail(lua_State * L) static int lua_nodelib_end_of_math(lua_State * L) { - halfword *n; - halfword t; + halfword n; if (lua_isnil(L, 1)) return 0; - n = check_isnode(L, 1); - t = *n; - if (t == null) + n = *check_isnode(L, 1); + if (n == null) return 0; - if (type(t)==math_node && (subtype(t)==1)) { - lua_nodelib_push_fast(L, t); + if (type(n) == math_node && (subtype(n) == 1)) { + lua_nodelib_push_fast(L, n); return 1; } - while (vlink(t) != null) { - t = vlink(t); - if (t && (type(t)==math_node) && (subtype(t)==1)) { - lua_nodelib_push_fast(L, t); + while (vlink(n) != null) { + n = vlink(n); + if (n && (type(n) == math_node) && (subtype(n) == 1)) { + lua_nodelib_push_fast(L, n); return 1; } } @@ -2165,18 +2122,17 @@ static int lua_nodelib_end_of_math(lua_State * L) static int lua_nodelib_direct_end_of_math(lua_State * L) { - halfword n; - n = (halfword) lua_tonumber(L, 1); + halfword n = lua_tointeger(L, 1); if (n == null) return 0; if ((type(n)==math_node && (subtype(n)==1))) { - lua_pushnumber(L, n); + lua_pushinteger(L, n); return 1; } while (vlink(n) != null) { n = vlink(n); if (n && (type(n)==math_node) && (subtype(n)==1)) { - lua_pushnumber(L, n); + lua_pushinteger(L, n); return 1; } } @@ -2188,14 +2144,13 @@ static int lua_nodelib_direct_end_of_math(lua_State * L) static int lua_nodelib_has_attribute(lua_State * L) { - halfword *n; int i, val; - n = check_isnode(L, 1); - if (n != NULL) { - i = (int) lua_tointeger(L, 2); - val = (int) luaL_optinteger(L, 3, UNUSED_ATTRIBUTE); - if ((val = has_attribute(*n, i, val)) > UNUSED_ATTRIBUTE) { - lua_pushnumber(L, val); + halfword n = *check_isnode(L, 1); + if (n != null) { + i = lua_tointeger(L, 2); + val = luaL_optinteger(L, 3, UNUSED_ATTRIBUTE); + if ((val = has_attribute(n, i, val)) > UNUSED_ATTRIBUTE) { + lua_pushinteger(L, val); return 1; } } @@ -2207,14 +2162,13 @@ static int lua_nodelib_has_attribute(lua_State * L) static int lua_nodelib_direct_has_attribute(lua_State * L) { - halfword n; int i, val; - n = (halfword) lua_tonumber(L, 1); + halfword n = lua_tointeger(L, 1); if (n != null) { - i = (int) lua_tointeger(L, 2); - val = (int) luaL_optinteger(L, 3, UNUSED_ATTRIBUTE); + i = lua_tointeger(L, 2); + val = luaL_optinteger(L, 3, UNUSED_ATTRIBUTE); if ((val = has_attribute(n, i, val)) > UNUSED_ATTRIBUTE) { - lua_pushnumber(L, val); + lua_pushinteger(L, val); return 1; } } @@ -2222,20 +2176,83 @@ static int lua_nodelib_direct_has_attribute(lua_State * L) return 1; } +/* node.get_attribute */ + +static int lua_nodelib_get_attribute(lua_State * L) +{ + halfword p; + p = *check_isnode(L, 1); + if (nodetype_has_attributes(type(p))) { + p = node_attr(p); + if (p != null) { + p = vlink(p); + if (p != null) { + int i = lua_tointeger(L, 2); + while (p != null) { + if (attribute_id(p) == i) { + int ret = attribute_value(p); + if (ret == UNUSED_ATTRIBUTE) { + break; + } else { + lua_pushinteger(L,ret); + return 1; + } + } else if (attribute_id(p) > i) { + break; + } + p = vlink(p); + } + } + } + } + lua_pushnil(L); + return 1; +} + +/* node.direct.get_attribute */ + +static int lua_nodelib_direct_get_attribute(lua_State * L) +{ + register halfword p = lua_tointeger(L, 1); + if (nodetype_has_attributes(type(p))) { + p = node_attr(p); + if (p != null) { + p = vlink(p); + if (p != null) { + int i = lua_tointeger(L, 2); + while (p != null) { + if (attribute_id(p) == i) { + int ret = attribute_value(p); + if (ret == UNUSED_ATTRIBUTE) { + break; + } else { + lua_pushinteger(L,ret); + return 1; + } + } else if (attribute_id(p) > i) { + break; + } + p = vlink(p); + } + } + } + } + lua_pushnil(L); + return 1; +} + /* node.set_attribute */ static int lua_nodelib_set_attribute(lua_State * L) { - halfword *n; - int i, val; if (lua_gettop(L) == 3) { - i = (int) lua_tointeger(L, 2); - val = (int) lua_tointeger(L, 3); - n = check_isnode(L, 1); + int i = lua_tointeger(L, 2); + int val = lua_tointeger(L, 3); + halfword n = *check_isnode(L, 1); if (val == UNUSED_ATTRIBUTE) { - (void) unset_attribute(*n, i, val); + (void) unset_attribute(n, i, val); } else { - set_attribute(*n, i, val); + set_attribute(n, i, val); } } else { luaL_error(L, "incorrect number of arguments"); @@ -2247,9 +2264,8 @@ static int lua_nodelib_set_attribute(lua_State * L) static int lua_nodelib_direct_set_attribute(lua_State * L) { - halfword n; int i, val; - n = (halfword) lua_tonumber(L, 1); + halfword n = lua_tointeger(L, 1); if (n == null) return 0; if (lua_gettop(L) == 3) { @@ -2270,15 +2286,13 @@ static int lua_nodelib_direct_set_attribute(lua_State * L) static int lua_nodelib_unset_attribute(lua_State * L) { - halfword *n; - int i, val, ret; if (lua_gettop(L) <= 3) { - i=(int)luaL_checknumber(L, 2); - val=(int)luaL_optnumber(L, 3, UNUSED_ATTRIBUTE); - n = check_isnode(L, 1); - ret = unset_attribute(*n, i, val); + int i = luaL_checknumber(L, 2); + int val = luaL_optnumber(L, 3, UNUSED_ATTRIBUTE); + halfword n = *check_isnode(L, 1); + int ret = unset_attribute(n, i, val); if (ret > UNUSED_ATTRIBUTE) { - lua_pushnumber(L, ret); + lua_pushinteger(L, ret); } else { lua_pushnil(L); } @@ -2292,9 +2306,8 @@ static int lua_nodelib_unset_attribute(lua_State * L) static int lua_nodelib_direct_unset_attribute(lua_State * L) { - halfword n; int i, val, ret; - n = (halfword) lua_tonumber(L, 1); + halfword n = lua_tointeger(L, 1); if (n == null) { lua_pushnil(L); } else if (lua_gettop(L) <= 3) { /* a useless test, we never test for that elsewhere */ @@ -2302,7 +2315,7 @@ static int lua_nodelib_direct_unset_attribute(lua_State * L) val=(int)luaL_optnumber(L, 3, UNUSED_ATTRIBUTE); ret = unset_attribute(n, i, val); if (ret > UNUSED_ATTRIBUTE) { - lua_pushnumber(L, ret); + lua_pushinteger(L, ret); } else { lua_pushnil(L); } @@ -2353,7 +2366,7 @@ static int lua_nodelib_traverse_filtered(lua_State * L) lua_pushcclosure(L, nodelib_aux_nil, 0); return 1; } - n = *(check_isnode(L, 2)); + n = *check_isnode(L, 2); lua_pop(L, 1); /* the node, integer remains */ lua_pushcclosure(L, nodelib_aux_next_filtered, 1); lua_nodelib_push_fast(L, n); @@ -2368,21 +2381,24 @@ static int nodelib_direct_aux_next_filtered(lua_State * L) halfword t; /* traverser */ int i = (int) lua_tointeger(L, lua_upvalueindex(1)); if (lua_isnil(L, 2)) { /* first call */ - t = lua_tonumber(L,1) ; + t = lua_tointeger(L,1) ; lua_settop(L,1); } else { - t = lua_tonumber(L,2) ; + t = lua_tointeger(L,2) ; t = vlink(t); lua_settop(L,2); } - while (t != null && type(t) != i) { - t = vlink(t); - } - if (t == null) { - lua_pushnil(L); - } else { - lua_pushnumber(L,t); + while (1) { + if (t == null) { + break; + } else if (type(t) == i) { + lua_pushinteger(L,t); + return 1; + } else { + t = vlink(t); + } } + lua_pushnil(L); return 1; } @@ -2393,13 +2409,61 @@ static int lua_nodelib_direct_traverse_filtered(lua_State * L) lua_pushcclosure(L, nodelib_aux_nil, 0); return 1; } - n = (halfword) lua_tonumber(L, 2); + n = (halfword) lua_tointeger(L, 2); if (n == null) return 0; - n = (halfword) lua_tonumber(L, 2); + /* funny duplicate check + n = (halfword) lua_tointeger(L, 2); + */ lua_pop(L, 1); lua_pushcclosure(L, nodelib_direct_aux_next_filtered, 1); - lua_pushnumber(L,n); + lua_pushinteger(L,n); + lua_pushnil(L); + return 3; +} + +/* node.direct.traverse_char */ + +static int nodelib_direct_aux_next_char(lua_State * L) +{ + halfword t; /* traverser */ + /*int i = (int) lua_tointeger(L, lua_upvalueindex(1));*/ + if (lua_isnil(L, 2)) { /* first call */ + t = lua_tointeger(L,1) ; + lua_settop(L,1); + } else { + t = lua_tointeger(L,2) ; + t = vlink(t); + lua_settop(L,2); + } + while (1) { + if (t == null) { + break; + } else if ((type(t) == glyph_node) && (subtype(t) < 256)){ + lua_pushinteger(L,t); + return 1; + } else { + t = vlink(t); + } + } + lua_pushnil(L); + return 1; +} + +static int lua_nodelib_direct_traverse_char(lua_State * L) +{ + halfword n; + if (lua_isnil(L, 1)) { + lua_pushcclosure(L, nodelib_aux_nil, 0); + return 1; + } + n = (halfword) lua_tointeger(L, 1); + if (n == null) { + lua_pushcclosure(L, nodelib_aux_nil, 0); + return 1; + } + lua_pushcclosure(L, nodelib_direct_aux_next_char, 0); + lua_pushinteger(L,n); lua_pushnil(L); return 3; } @@ -2433,13 +2497,54 @@ static int lua_nodelib_traverse(lua_State * L) lua_pushcclosure(L, nodelib_aux_nil, 0); return 1; } - n = *(check_isnode(L, 1)); + n = *check_isnode(L, 1); lua_pushcclosure(L, nodelib_aux_next, 0); lua_nodelib_push_fast(L, n); lua_pushnil(L); return 3; } +/* node.traverse_char */ + +static int nodelib_aux_next_char(lua_State * L) +{ + halfword t; /* traverser */ + halfword *a; + if (lua_isnil(L, 2)) { /* first call */ + t = *check_isnode(L, 1); + lua_settop(L,1); + } else { + t = *check_isnode(L, 2); + t = vlink(t); + lua_settop(L,2); + } + while (1) { + if (t == null) { + break; + } else if ((type(t) == glyph_node) && (subtype(t) < 256)){ + fast_metatable_top(t); + return 1; + } else { + t = vlink(t); + } + } + return 1; +} + +static int lua_nodelib_traverse_char(lua_State * L) +{ + halfword n; + if (lua_isnil(L, 1)) { + lua_pushcclosure(L, nodelib_aux_nil, 0); + return 1; + } + n = *check_isnode(L, 1); + lua_pushcclosure(L, nodelib_aux_next_char, 0); + lua_nodelib_push_fast(L, n); + lua_pushnil(L); + return 3; +} + /* node.direct.traverse */ static int nodelib_direct_aux_next(lua_State * L) @@ -2447,17 +2552,17 @@ static int nodelib_direct_aux_next(lua_State * L) halfword t; /* traverser */ /*int i = (int) lua_tointeger(L, lua_upvalueindex(1));*/ if (lua_isnil(L, 2)) { /* first call */ - t = lua_tonumber(L,1) ; + t = lua_tointeger(L,1) ; lua_settop(L,1); } else { - t = lua_tonumber(L,2) ; + t = lua_tointeger(L,2) ; t = vlink(t); lua_settop(L,2); } if (t == null) { lua_pushnil(L); } else { - lua_pushnumber(L,t); + lua_pushinteger(L,t); } return 1; } @@ -2469,18 +2574,17 @@ static int lua_nodelib_direct_traverse(lua_State * L) lua_pushcclosure(L, nodelib_aux_nil, 0); return 1; } - n = (halfword) lua_tonumber(L, 1); + n = (halfword) lua_tointeger(L, 1); if (n == null) { lua_pushcclosure(L, nodelib_aux_nil, 0); return 1; } lua_pushcclosure(L, nodelib_direct_aux_next, 0); - lua_pushnumber(L,n); + lua_pushinteger(L,n); lua_pushnil(L); return 3; } - /* counting */ static int do_lua_nodelib_count(lua_State * L, halfword match, int i, halfword first1) @@ -2492,7 +2596,7 @@ static int do_lua_nodelib_count(lua_State * L, halfword match, int i, halfword f count++; t = vlink(t); } - lua_pushnumber(L, count); + lua_pushinteger(L, count); return 1; } @@ -2503,12 +2607,12 @@ static int lua_nodelib_length(lua_State * L) halfword n; halfword m = null; if (lua_isnil(L, 1)) { - lua_pushnumber(L, 0); + lua_pushinteger(L, 0); return 1; } - n = *(check_isnode(L, 1)); + n = *check_isnode(L, 1); if (lua_gettop(L) == 2) - m = *(check_isnode(L, 2)); + m = *check_isnode(L, 2); return do_lua_nodelib_count(L, m, -1, n); } @@ -2516,13 +2620,13 @@ static int lua_nodelib_length(lua_State * L) static int lua_nodelib_direct_length(lua_State * L) { - halfword n, m; - n = (halfword) lua_tonumber(L, 1); + halfword m; + halfword n = lua_tointeger(L, 1); if (n == 0) { - lua_pushnumber(L, 0); + lua_pushinteger(L, 0); return 1; } - m = (halfword) lua_tonumber(L, 2); + m = (halfword) lua_tointeger(L, 2); return do_lua_nodelib_count(L, m, -1, n); } @@ -2532,15 +2636,14 @@ static int lua_nodelib_count(lua_State * L) { halfword n; halfword m = null; - int i = -1; - i = (int) lua_tointeger(L, 1); + int i = lua_tointeger(L, 1); if (lua_isnil(L, 2)) { - lua_pushnumber(L, 0); + lua_pushinteger(L, 0); return 1; } - n = *(check_isnode(L, 2)); + n = *check_isnode(L, 2); if (lua_gettop(L) == 3) - m = *(check_isnode(L, 3)); + m = *check_isnode(L, 3); return do_lua_nodelib_count(L, m, i, n); } @@ -2549,9 +2652,9 @@ static int lua_nodelib_count(lua_State * L) static int lua_nodelib_direct_count(lua_State * L) { return do_lua_nodelib_count(L, - (halfword) lua_tonumber(L, 3), /* m */ + (halfword) lua_tointeger(L, 3), /* m */ (int) lua_tointeger(L, 1), /* i */ - (halfword) lua_tonumber(L, 2) /* n */ + (halfword) lua_tointeger(L, 2) /* n */ ); } @@ -2559,10 +2662,9 @@ static int lua_nodelib_direct_count(lua_State * L) int nodelib_getlist(lua_State * L, int n) { - halfword *m; if (lua_isuserdata(L, n)) { - m = check_isnode(L, n); - return *m; + halfword m = *check_isnode(L, n); + return m; } else { return null; } @@ -2606,21 +2708,19 @@ static int nodelib_nonwritable(lua_State * L, int n, const char *s) static void lua_nodelib_getfield_whatsit(lua_State * L, int n, const char *s) { - int t ; - t = subtype(n); - + int t = subtype(n); if (t == user_defined_node) { if (lua_key_eq(s, user_id)) { - lua_pushnumber(L, user_node_id(n)); + lua_pushinteger(L, user_node_id(n)); } else if (lua_key_eq(s, type)) { - lua_pushnumber(L, user_node_type(n)); + lua_pushinteger(L, user_node_type(n)); } else if (lua_key_eq(s, value)) { switch (user_node_type(n)) { case 'a': nodelib_pushlist(L, user_node_value(n)); break; case 'd': - lua_pushnumber(L, user_node_value(n)); + lua_pushinteger(L, user_node_value(n)); break; case 'l': if (user_node_value(n) != 0) { @@ -2639,7 +2739,7 @@ static void lua_nodelib_getfield_whatsit(lua_State * L, int n, const char *s) tokenlist_to_lua(L, user_node_value(n)); break; default: - lua_pushnumber(L, user_node_value(n)); + lua_pushinteger(L, user_node_value(n)); break; } } else { @@ -2647,7 +2747,7 @@ static void lua_nodelib_getfield_whatsit(lua_State * L, int n, const char *s) } } else if (t == pdf_literal_node) { if (lua_key_eq(s, mode)) { - lua_pushnumber(L, pdf_literal_mode(n)); + lua_pushinteger(L, pdf_literal_mode(n)); } else if (lua_key_eq(s, data)) { if (pdf_literal_type(n) == lua_refid_literal) { lua_rawgeti(L, LUA_REGISTRYINDEX, pdf_literal_data(n)); @@ -2671,13 +2771,13 @@ static void lua_nodelib_getfield_whatsit(lua_State * L, int n, const char *s) } } else if (t == pdf_annot_node) { if (lua_key_eq(s, width)) { - lua_pushnumber(L, width(n)); + lua_pushinteger(L, width(n)); } else if (lua_key_eq(s, depth)) { - lua_pushnumber(L, depth(n)); + lua_pushinteger(L, depth(n)); } else if (lua_key_eq(s, height)) { - lua_pushnumber(L, height(n)); + lua_pushinteger(L, height(n)); } else if (lua_key_eq(s, objnum)) { - lua_pushnumber(L, pdf_annot_objnum(n)); + lua_pushinteger(L, pdf_annot_objnum(n)); } else if (lua_key_eq(s, data)) { tokenlist_to_luastring(L, pdf_annot_data(n)); } else { @@ -2685,24 +2785,24 @@ static void lua_nodelib_getfield_whatsit(lua_State * L, int n, const char *s) } } else if (t == pdf_dest_node) { if (lua_key_eq(s, width)) { - lua_pushnumber(L, width(n)); + lua_pushinteger(L, width(n)); } else if (lua_key_eq(s, depth)) { - lua_pushnumber(L, depth(n)); + lua_pushinteger(L, depth(n)); } else if (lua_key_eq(s, height)) { - lua_pushnumber(L, height(n)); + lua_pushinteger(L, height(n)); } else if (lua_key_eq(s, named_id)) { - lua_pushnumber(L, pdf_dest_named_id(n)); + lua_pushinteger(L, pdf_dest_named_id(n)); } else if (lua_key_eq(s, dest_id)) { if (pdf_dest_named_id(n) == 1) tokenlist_to_luastring(L, pdf_dest_id(n)); else - lua_pushnumber(L, pdf_dest_id(n)); + lua_pushinteger(L, pdf_dest_id(n)); } else if (lua_key_eq(s, dest_type)) { - lua_pushnumber(L, pdf_dest_type(n)); + lua_pushinteger(L, pdf_dest_type(n)); } else if (lua_key_eq(s, xyz_zoom)) { - lua_pushnumber(L, pdf_dest_xyz_zoom(n)); + lua_pushinteger(L, pdf_dest_xyz_zoom(n)); } else if (lua_key_eq(s, objnum)) { - lua_pushnumber(L, pdf_dest_objnum(n)); + lua_pushinteger(L, pdf_dest_objnum(n)); } else { lua_pushnil(L); } @@ -2714,9 +2814,9 @@ static void lua_nodelib_getfield_whatsit(lua_State * L, int n, const char *s) } } else if (t == pdf_colorstack_node) { if (lua_key_eq(s, stack)) { - lua_pushnumber(L, pdf_colorstack_stack(n)); + lua_pushinteger(L, pdf_colorstack_stack(n)); } else if (lua_key_eq(s, command)) { - lua_pushnumber(L, pdf_colorstack_cmd(n)); + lua_pushinteger(L, pdf_colorstack_cmd(n)); } else if (lua_key_eq(s, data)) { tokenlist_to_luastring(L, pdf_colorstack_data(n)); } else { @@ -2724,13 +2824,13 @@ static void lua_nodelib_getfield_whatsit(lua_State * L, int n, const char *s) } } else if (t == pdf_refobj_node) { if (lua_key_eq(s, objnum)) { - lua_pushnumber(L, pdf_obj_objnum(n)); + lua_pushinteger(L, pdf_obj_objnum(n)); } else { lua_pushnil(L); } } else if (t == write_node) { if (lua_key_eq(s, stream)) { - lua_pushnumber(L, write_stream(n)); + lua_pushinteger(L, write_stream(n)); } else if (lua_key_eq(s, data)) { tokenlist_to_lua(L, write_tokens(n)); } else { @@ -2744,13 +2844,13 @@ static void lua_nodelib_getfield_whatsit(lua_State * L, int n, const char *s) } } else if (t == pdf_start_link_node) { if (lua_key_eq(s, width)) { - lua_pushnumber(L, width(n)); + lua_pushinteger(L, width(n)); } else if (lua_key_eq(s, depth)) { - lua_pushnumber(L, depth(n)); + lua_pushinteger(L, depth(n)); } else if (lua_key_eq(s, height)) { - lua_pushnumber(L, height(n)); + lua_pushinteger(L, height(n)); } else if (lua_key_eq(s, objnum)) { - lua_pushnumber(L, pdf_link_objnum(n)); + lua_pushinteger(L, pdf_link_objnum(n)); } else if (lua_key_eq(s, link_attr)) { tokenlist_to_luastring(L, pdf_link_attr(n)); } else if (lua_key_eq(s, action)) { @@ -2760,40 +2860,40 @@ static void lua_nodelib_getfield_whatsit(lua_State * L, int n, const char *s) } } else if (t == pdf_action_node) { if (lua_key_eq(s, action_type)) { - lua_pushnumber(L, pdf_action_type(n)); + lua_pushinteger(L, pdf_action_type(n)); } else if (lua_key_eq(s, named_id)) { - lua_pushnumber(L, pdf_action_named_id(n)); + lua_pushinteger(L, pdf_action_named_id(n)); } else if (lua_key_eq(s, action_id)) { if (pdf_action_named_id(n) == 1) { tokenlist_to_luastring(L, pdf_action_id(n)); } else { - lua_pushnumber(L, pdf_action_id(n)); + lua_pushinteger(L, pdf_action_id(n)); } } else if (lua_key_eq(s, file)) { tokenlist_to_luastring(L, pdf_action_file(n)); } else if (lua_key_eq(s, new_window)) { - lua_pushnumber(L, pdf_action_new_window(n)); + lua_pushinteger(L, pdf_action_new_window(n)); } else if (lua_key_eq(s, data)) { tokenlist_to_luastring(L, pdf_action_tokens(n)); } else if (lua_key_eq(s, ref_count)) { - lua_pushnumber(L, pdf_action_refcount(n)); + lua_pushinteger(L, pdf_action_refcount(n)); } else { lua_pushnil(L); } } else if ((t == pdf_thread_node) || (t == pdf_start_thread_node)) { if (lua_key_eq(s, width)) { - lua_pushnumber(L, width(n)); + lua_pushinteger(L, width(n)); } else if (lua_key_eq(s, depth)) { - lua_pushnumber(L, depth(n)); + lua_pushinteger(L, depth(n)); } else if (lua_key_eq(s, height)) { - lua_pushnumber(L, height(n)); + lua_pushinteger(L, height(n)); } else if (lua_key_eq(s, named_id)) { - lua_pushnumber(L, pdf_thread_named_id(n)); + lua_pushinteger(L, pdf_thread_named_id(n)); } else if (lua_key_eq(s, thread_id)) { if (pdf_thread_named_id(n) == 1) { tokenlist_to_luastring(L, pdf_thread_id(n)); } else { - lua_pushnumber(L, pdf_thread_id(n)); + lua_pushinteger(L, pdf_thread_id(n)); } } else if (lua_key_eq(s, thread_attr)) { tokenlist_to_luastring(L, pdf_thread_attr(n)); @@ -2802,7 +2902,7 @@ static void lua_nodelib_getfield_whatsit(lua_State * L, int n, const char *s) } } else if (t == open_node) { if (lua_key_eq(s, stream)) { - lua_pushnumber(L, write_stream(n)); + lua_pushinteger(L, write_stream(n)); } else if (lua_key_eq(s, name)) { nodelib_pushstring(L, open_name(n)); } else if (lua_key_eq(s, area)) { @@ -2814,7 +2914,7 @@ static void lua_nodelib_getfield_whatsit(lua_State * L, int n, const char *s) } } else if (t == close_node) { if (lua_key_eq(s, stream)) { - lua_pushnumber(L, write_stream(n)); + lua_pushinteger(L, write_stream(n)); } else { lua_pushnil(L); } @@ -2830,13 +2930,11 @@ static int lua_nodelib_fast_getfield(lua_State * L) importance of fields */ - halfword n; halfword *a; const char *s; - int t ; - n = *((halfword *) lua_touserdata(L, 1)); - t = type(n); + halfword n = *((halfword *) lua_touserdata(L, 1)); + int t = type(n); /* @@ -2867,7 +2965,7 @@ static int lua_nodelib_fast_getfield(lua_State * L) while (p != null) { if (attribute_id(p) == i) { if ((int) attribute_value(p) > UNUSED_ATTRIBUTE) { - lua_pushnumber(L, (int) attribute_value(p)); + lua_pushinteger(L, (int) attribute_value(p)); } else { lua_pushnil(L); } @@ -2885,7 +2983,7 @@ static int lua_nodelib_fast_getfield(lua_State * L) s = lua_tostring(L, 2); if (lua_key_eq(s, id)) { - lua_pushnumber(L, t); + lua_pushinteger(L, t); } else if (lua_key_eq(s, next)) { fast_metatable_or_nil(vlink(n)); } else if (lua_key_eq(s, prev)) { @@ -2899,64 +2997,64 @@ static int lua_nodelib_fast_getfield(lua_State * L) } else if (t == glyph_node) { /* candidates: fontchar (font,char) whd (width,height,depth) */ if (lua_key_eq(s, subtype)) { - lua_pushnumber(L, subtype(n)); + lua_pushinteger(L, subtype(n)); } else if (lua_key_eq(s, font)) { - lua_pushnumber(L, font(n)); + lua_pushinteger(L, font(n)); } else if (lua_key_eq(s, char)) { - lua_pushnumber(L, character(n)); + lua_pushinteger(L, character(n)); } else if (lua_key_eq(s, xoffset)) { - lua_pushnumber(L, x_displace(n)); + lua_pushinteger(L, x_displace(n)); } else if (lua_key_eq(s, yoffset)) { - lua_pushnumber(L, y_displace(n)); + lua_pushinteger(L, y_displace(n)); } else if (lua_key_eq(s, width)) { - lua_pushnumber(L, char_width(font(n),character(n))); + lua_pushinteger(L, char_width(font(n),character(n))); } else if (lua_key_eq(s, height)) { - lua_pushnumber(L, char_height(font(n),character(n))); + lua_pushinteger(L, char_height(font(n),character(n))); } else if (lua_key_eq(s, depth)) { - lua_pushnumber(L, char_depth(font(n),character(n))); + lua_pushinteger(L, char_depth(font(n),character(n))); } else if (lua_key_eq(s, expansion_factor)) { - lua_pushnumber(L, ex_glyph(n)); + lua_pushinteger(L, ex_glyph(n)); } else if (lua_key_eq(s, components)) { fast_metatable_or_nil(lig_ptr(n)); } else if (lua_key_eq(s, lang)) { - lua_pushnumber(L, char_lang(n)); + lua_pushinteger(L, char_lang(n)); } else if (lua_key_eq(s, left)) { - lua_pushnumber(L, char_lhmin(n)); + lua_pushinteger(L, char_lhmin(n)); } else if (lua_key_eq(s, right)) { - lua_pushnumber(L, char_rhmin(n)); + lua_pushinteger(L, char_rhmin(n)); } else if (lua_key_eq(s, uchyph)) { - lua_pushnumber(L, char_uchyph(n)); + lua_pushinteger(L, char_uchyph(n)); } else { lua_pushnil(L); } } else if ((t == hlist_node) || (t == vlist_node)) { /* candidates: whd (width,height,depth) */ if (lua_key_eq(s, subtype)) { - lua_pushnumber(L, subtype(n)); + lua_pushinteger(L, subtype(n)); } else if (lua_key_eq(s, list) || lua_key_eq(s, head)) { fast_metatable_or_nil_alink(list_ptr(n)); } else if (lua_key_eq(s, width)) { - lua_pushnumber(L, width(n)); + lua_pushinteger(L, width(n)); } else if (lua_key_eq(s, height)) { - lua_pushnumber(L, height(n)); + lua_pushinteger(L, height(n)); } else if (lua_key_eq(s, depth)) { - lua_pushnumber(L, depth(n)); + lua_pushinteger(L, depth(n)); } else if (lua_key_eq(s, dir)) { lua_push_dir_par(L, box_dir(n)); } else if (lua_key_eq(s, shift)) { - lua_pushnumber(L, shift_amount(n)); + lua_pushinteger(L, shift_amount(n)); } else if (lua_key_eq(s, glue_order)) { - lua_pushnumber(L, glue_order(n)); + lua_pushinteger(L, glue_order(n)); } else if (lua_key_eq(s, glue_sign)) { - lua_pushnumber(L, glue_sign(n)); + lua_pushinteger(L, glue_sign(n)); } else if (lua_key_eq(s, glue_set)) { - lua_pushnumber(L, (double) glue_set(n)); + lua_pushnumber(L, (double) glue_set(n)); /* float */ } else { lua_pushnil(L); } } else if (t == disc_node) { if (lua_key_eq(s, subtype)) { - lua_pushnumber(L, subtype(n)); + lua_pushinteger(L, subtype(n)); } else if (lua_key_eq(s, pre)) { fast_metatable_or_nil(vlink(pre_break(n))); } else if (lua_key_eq(s, post)) { @@ -2968,7 +3066,7 @@ static int lua_nodelib_fast_getfield(lua_State * L) } } else if (t == glue_node) { if (lua_key_eq(s, subtype)) { - lua_pushnumber(L, subtype(n)); + lua_pushinteger(L, subtype(n)); } else if (lua_key_eq(s, spec)) { nodelib_pushspec(L, glue_ptr(n)); } else if (lua_key_eq(s, leader)) { @@ -2976,36 +3074,36 @@ static int lua_nodelib_fast_getfield(lua_State * L) } else { n = glue_ptr(n); if (!n) { - lua_pushnil(L); + lua_pushinteger(L, 0); /* zero skip constant */ } else if (lua_key_eq(s, width)) { - lua_pushnumber(L, width(n)); + lua_pushinteger(L, width(n)); } else if (lua_key_eq(s, stretch)) { - lua_pushnumber(L, stretch(n)); + lua_pushinteger(L, stretch(n)); } else if (lua_key_eq(s, shrink)) { - lua_pushnumber(L, shrink(n)); + lua_pushinteger(L, shrink(n)); } else if (lua_key_eq(s, stretch_order)) { - lua_pushnumber(L, stretch_order(n)); + lua_pushinteger(L, stretch_order(n)); } else if (lua_key_eq(s, shrink_order)) { - lua_pushnumber(L, shrink_order(n)); + lua_pushinteger(L, shrink_order(n)); } else { lua_pushnil(L); } } } else if (t == glue_spec_node) { if (lua_key_eq(s, subtype)) { - lua_pushnumber(L, 0); /* dummy, the only one that prevents move up */ + lua_pushinteger(L, 0); /* dummy, the only one that prevents move up */ } else if (lua_key_eq(s, width)) { - lua_pushnumber(L, width(n)); + lua_pushinteger(L, width(n)); } else if (lua_key_eq(s, stretch)) { - lua_pushnumber(L, stretch(n)); + lua_pushinteger(L, stretch(n)); } else if (lua_key_eq(s, shrink)) { - lua_pushnumber(L, shrink(n)); + lua_pushinteger(L, shrink(n)); } else if (lua_key_eq(s, stretch_order)) { - lua_pushnumber(L, stretch_order(n)); + lua_pushinteger(L, stretch_order(n)); } else if (lua_key_eq(s, shrink_order)) { - lua_pushnumber(L, shrink_order(n)); + lua_pushinteger(L, shrink_order(n)); } else if (lua_key_eq(s, ref_count)) { - lua_pushnumber(L, glue_ref_count(n)); + lua_pushinteger(L, glue_ref_count(n)); } else if (lua_key_eq(s, writable)) { lua_pushboolean(L, valid_node(n)); } else { @@ -3013,83 +3111,82 @@ static int lua_nodelib_fast_getfield(lua_State * L) } } else if (t == kern_node) { if (lua_key_eq(s, subtype)) { - lua_pushnumber(L, subtype(n)); + lua_pushinteger(L, subtype(n)); } else if (lua_key_eq(s, kern)) { - lua_pushnumber(L, width(n)); + lua_pushinteger(L, width(n)); } else if (lua_key_eq(s, expansion_factor)) { - lua_pushnumber(L, ex_kern(n)); + lua_pushinteger(L, ex_kern(n)); } else { lua_pushnil(L); } } else if (t == penalty_node) { if (lua_key_eq(s, subtype)) { - lua_pushnumber(L, subtype(n)); + lua_pushinteger(L, subtype(n)); } else if (lua_key_eq(s, penalty)) { - lua_pushnumber(L, penalty(n)); + lua_pushinteger(L, penalty(n)); } else { lua_pushnil(L); } } else if (t == rule_node) { /* candidates: whd (width,height,depth) */ if (lua_key_eq(s, subtype)) { - lua_pushnumber(L, subtype(n)); + lua_pushinteger(L, subtype(n)); } else if (lua_key_eq(s, width)) { - lua_pushnumber(L, width(n)); + lua_pushinteger(L, width(n)); } else if (lua_key_eq(s, height)) { - lua_pushnumber(L, height(n)); + lua_pushinteger(L, height(n)); } else if (lua_key_eq(s, depth)) { - lua_pushnumber(L, depth(n)); + lua_pushinteger(L, depth(n)); } else if (lua_key_eq(s, dir)) { lua_push_dir_par(L, rule_dir(n)); } else if (lua_key_eq(s, index)) { - lua_pushnumber(L, rule_index(n)); + lua_pushinteger(L, rule_index(n)); } else if (lua_key_eq(s, transform)) { - lua_pushnumber(L,rule_transform(n)); + lua_pushinteger(L,rule_transform(n)); } else { lua_pushnil(L); } } else if (t == dir_node) { if (lua_key_eq(s, dir)) { - // nodelib_pushdir(L, dir_dir(n), true); lua_push_dir_text(L, dir_dir(n)); } else if (lua_key_eq(s, level)) { - lua_pushnumber(L, dir_level(n)); + lua_pushinteger(L, dir_level(n)); } else if (lua_key_eq(s, dvi_ptr)) { - lua_pushnumber(L, dir_dvi_ptr(n)); + lua_pushinteger(L, dir_dvi_ptr(n)); } else if (lua_key_eq(s, dir_h)) { - lua_pushnumber(L, dir_dvi_h(n)); + lua_pushinteger(L, dir_dvi_h(n)); } else { lua_pushnil(L); } } else if (t == local_par_node) { if (lua_key_eq(s, pen_inter)) { - lua_pushnumber(L, local_pen_inter(n)); + lua_pushinteger(L, local_pen_inter(n)); } else if (lua_key_eq(s, pen_broken)) { - lua_pushnumber(L, local_pen_broken(n)); + lua_pushinteger(L, local_pen_broken(n)); } else if (lua_key_eq(s, dir)) { lua_push_dir_par(L, local_par_dir(n)); } else if (lua_key_eq(s, box_left)) { /* can be: fast_metatable_or_nil(local_box_left(n)) */ nodelib_pushlist(L, local_box_left(n)); } else if (lua_key_eq(s, box_left_width)) { - lua_pushnumber(L, local_box_left_width(n)); + lua_pushinteger(L, local_box_left_width(n)); } else if (lua_key_eq(s, box_right)) { /* can be: fast_metatable_or_nil(local_box_right(n)) */ nodelib_pushlist(L, local_box_right(n)); } else if (lua_key_eq(s, box_right_width)) { - lua_pushnumber(L, local_box_right_width(n)); + lua_pushinteger(L, local_box_right_width(n)); } else { lua_pushnil(L); } } else if (t == whatsit_node) { if (lua_key_eq(s, subtype)) { - lua_pushnumber(L, subtype(n)); + lua_pushinteger(L, subtype(n)); } else { lua_nodelib_getfield_whatsit(L, n, s); } } else if (t == simple_noad) { if (lua_key_eq(s, subtype)) { - lua_pushnumber(L, subtype(n)); + lua_pushinteger(L, subtype(n)); } else if (lua_key_eq(s, nucleus)) { fast_metatable_or_nil(nucleus(n)); } else if (lua_key_eq(s, sub)) { @@ -3102,19 +3199,19 @@ static int lua_nodelib_fast_getfield(lua_State * L) } else if ((t == math_char_node) || (t == math_text_char_node)) { /* candidates: famchar (fam,char) */ if (lua_key_eq(s, subtype)) { - lua_pushnumber(L, subtype(n)); + lua_pushinteger(L, subtype(n)); } else if (lua_key_eq(s, fam)) { - lua_pushnumber(L, math_fam(n)); + lua_pushinteger(L, math_fam(n)); } else if (lua_key_eq(s, char)) { - lua_pushnumber(L, math_character(n)); + lua_pushinteger(L, math_character(n)); } else { lua_pushnil(L); } } else if (t == mark_node) { if (lua_key_eq(s, subtype)) { - lua_pushnumber(L, subtype(n)); + lua_pushinteger(L, subtype(n)); } else if (lua_key_eq(s, class)) { - lua_pushnumber(L, mark_class(n)); + lua_pushinteger(L, mark_class(n)); } else if (lua_key_eq(s, mark)) { tokenlist_to_lua(L, mark_ptr(n)); } else { @@ -3122,13 +3219,13 @@ static int lua_nodelib_fast_getfield(lua_State * L) } } else if (t == ins_node) { if (lua_key_eq(s, subtype)) { - lua_pushnumber(L, subtype(n)); + lua_pushinteger(L, subtype(n)); } else if (lua_key_eq(s, cost)) { - lua_pushnumber(L, float_cost(n)); + lua_pushinteger(L, float_cost(n)); } else if (lua_key_eq(s, depth)) { - lua_pushnumber(L, depth(n)); + lua_pushinteger(L, depth(n)); } else if (lua_key_eq(s, height)) { - lua_pushnumber(L, height(n)); + lua_pushinteger(L, height(n)); } else if (lua_key_eq(s, spec)) { nodelib_pushspec(L, split_top_ptr(n)); } else if ((lua_key_eq(s, list)) || (lua_key_eq(s, head))) { @@ -3138,17 +3235,17 @@ static int lua_nodelib_fast_getfield(lua_State * L) } } else if (t == math_node) { if (lua_key_eq(s, subtype)) { - lua_pushnumber(L, subtype(n)); + lua_pushinteger(L, subtype(n)); } else if (lua_key_eq(s, surround)) { - lua_pushnumber(L, surround(n)); + lua_pushinteger(L, surround(n)); } else { lua_pushnil(L); } } else if (t == fraction_noad) { if (lua_key_eq(s, subtype)) { - lua_pushnumber(L, subtype(n)); + lua_pushinteger(L, subtype(n)); } else if (lua_key_eq(s, width)) { - lua_pushnumber(L, thickness(n)); + lua_pushinteger(L, thickness(n)); } else if (lua_key_eq(s, num)) { fast_metatable_or_nil(numerator(n)); } else if (lua_key_eq(s, denom)) { @@ -3162,7 +3259,7 @@ static int lua_nodelib_fast_getfield(lua_State * L) } } else if (t == style_node) { if (lua_key_eq(s, subtype)) { - lua_pushnumber(L, subtype(n)); + lua_pushinteger(L, subtype(n)); } else if (lua_key_eq(s, style)) { lua_push_math_style_name(L,subtype(n)); } else { @@ -3170,7 +3267,7 @@ static int lua_nodelib_fast_getfield(lua_State * L) } } else if (t == accent_noad) { if (lua_key_eq(s, subtype)) { - lua_pushnumber(L, subtype(n)); + lua_pushinteger(L, subtype(n)); } else if (lua_key_eq(s, nucleus)) { fast_metatable_or_nil(nucleus(n)); } else if (lua_key_eq(s, sub)) { @@ -3188,7 +3285,7 @@ static int lua_nodelib_fast_getfield(lua_State * L) } } else if (t == fence_noad) { if (lua_key_eq(s, subtype)) { - lua_pushnumber(L, subtype(n)); + lua_pushinteger(L, subtype(n)); } else if (lua_key_eq(s, delim)) { fast_metatable_or_nil(delimiter(n)); } else { @@ -3196,21 +3293,21 @@ static int lua_nodelib_fast_getfield(lua_State * L) } } else if (t == delim_node) { if (lua_key_eq(s, subtype)) { - lua_pushnumber(L, subtype(n)); + lua_pushinteger(L, subtype(n)); } else if (lua_key_eq(s, small_fam)) { - lua_pushnumber(L, small_fam(n)); + lua_pushinteger(L, small_fam(n)); } else if (lua_key_eq(s, small_char)) { - lua_pushnumber(L, small_char(n)); + lua_pushinteger(L, small_char(n)); } else if (lua_key_eq(s, large_fam)) { - lua_pushnumber(L, large_fam(n)); + lua_pushinteger(L, large_fam(n)); } else if (lua_key_eq(s, large_char)) { - lua_pushnumber(L, large_char(n)); + lua_pushinteger(L, large_char(n)); } else { lua_pushnil(L); } } else if ((t == sub_box_node) || (t == sub_mlist_node)) { if (lua_key_eq(s, subtype)) { - lua_pushnumber(L, subtype(n)); + lua_pushinteger(L, subtype(n)); } else if ((lua_key_eq(s, list)) || (lua_key_eq(s, head))){ fast_metatable_or_nil_alink(math_list(n)); } else { @@ -3218,7 +3315,7 @@ static int lua_nodelib_fast_getfield(lua_State * L) } } else if (t == radical_noad) { if (lua_key_eq(s, subtype)) { - lua_pushnumber(L, subtype(n)); + lua_pushinteger(L, subtype(n)); } else if (lua_key_eq(s, nucleus)) { fast_metatable_or_nil(nucleus(n)); } else if (lua_key_eq(s, sub)) { @@ -3234,9 +3331,9 @@ static int lua_nodelib_fast_getfield(lua_State * L) } } else if (t == margin_kern_node) { if (lua_key_eq(s, subtype)) { - lua_pushnumber(L, subtype(n)); + lua_pushinteger(L, subtype(n)); } else if (lua_key_eq(s, width)) { - lua_pushnumber(L, width(n)); + lua_pushinteger(L, width(n)); } else if (lua_key_eq(s, glyph)) { fast_metatable_or_nil(margin_char(n)); } else { @@ -3244,7 +3341,7 @@ static int lua_nodelib_fast_getfield(lua_State * L) } } else if (t == split_up_node) { if (lua_key_eq(s, subtype)) { - lua_pushnumber(L, subtype(n)); + lua_pushinteger(L, subtype(n)); } else if (lua_key_eq(s, last_ins_ptr)) { fast_metatable_or_nil(last_ins_ptr(n)); } else if (lua_key_eq(s, best_ins_ptr)) { @@ -3258,7 +3355,7 @@ static int lua_nodelib_fast_getfield(lua_State * L) } } else if (t == choice_node) { if (lua_key_eq(s, subtype)) { - lua_pushnumber(L, subtype(n)); + lua_pushinteger(L, subtype(n)); } else if (lua_key_eq(s, display)) { fast_metatable_or_nil(display_mlist(n)); } else if (lua_key_eq(s, text)) { @@ -3272,7 +3369,7 @@ static int lua_nodelib_fast_getfield(lua_State * L) } } else if (t == inserting_node) { if (lua_key_eq(s, subtype)) { - lua_pushnumber(L, subtype(n)); + lua_pushinteger(L, subtype(n)); } else if (lua_key_eq(s, last_ins_ptr)) { fast_metatable_or_nil(last_ins_ptr(n)); } else if (lua_key_eq(s, best_ins_ptr)) { @@ -3282,17 +3379,17 @@ static int lua_nodelib_fast_getfield(lua_State * L) } } else if (t == attribute_node) { if (lua_key_eq(s, subtype)) { - lua_pushnumber(L, subtype(n)); + lua_pushinteger(L, subtype(n)); } else if (lua_key_eq(s, number)) { - lua_pushnumber(L, attribute_id(n)); + lua_pushinteger(L, attribute_id(n)); } else if (lua_key_eq(s, value)) { - lua_pushnumber(L, attribute_value(n)); + lua_pushinteger(L, attribute_value(n)); } else { lua_pushnil(L); } } else if (t == adjust_node) { if (lua_key_eq(s, subtype)) { - lua_pushnumber(L, subtype(n)); + lua_pushinteger(L, subtype(n)); } else if ((lua_key_eq(s, list)) || (lua_key_eq(s, head))) { fast_metatable_or_nil_alink(adjust_ptr(n)); } else { @@ -3300,25 +3397,25 @@ static int lua_nodelib_fast_getfield(lua_State * L) } } else if (t == unset_node) { if (lua_key_eq(s, subtype)) { - lua_pushnumber(L, subtype(n)); + lua_pushinteger(L, subtype(n)); } else if (lua_key_eq(s, width)) { - lua_pushnumber(L, width(n)); + lua_pushinteger(L, width(n)); } else if (lua_key_eq(s, height)) { - lua_pushnumber(L, height(n)); + lua_pushinteger(L, height(n)); } else if (lua_key_eq(s, depth)) { - lua_pushnumber(L, depth(n)); + lua_pushinteger(L, depth(n)); } else if (lua_key_eq(s, dir)) { lua_push_dir_par(L, box_dir(n)); } else if (lua_key_eq(s, shrink)) { - lua_pushnumber(L, glue_shrink(n)); + lua_pushinteger(L, glue_shrink(n)); } else if (lua_key_eq(s, glue_order)) { - lua_pushnumber(L, glue_order(n)); + lua_pushinteger(L, glue_order(n)); } else if (lua_key_eq(s, glue_sign)) { - lua_pushnumber(L, glue_sign(n)); + lua_pushinteger(L, glue_sign(n)); } else if (lua_key_eq(s, stretch)) { - lua_pushnumber(L, glue_stretch(n)); + lua_pushinteger(L, glue_stretch(n)); } else if (lua_key_eq(s, count)) { - lua_pushnumber(L, span_count(n)); + lua_pushinteger(L, span_count(n)); } else if ((lua_key_eq(s, list)) || (lua_key_eq(s, head))){ fast_metatable_or_nil_alink(list_ptr(n)); } else { @@ -3326,15 +3423,15 @@ static int lua_nodelib_fast_getfield(lua_State * L) } } else if (t == attribute_list_node) { if (lua_key_eq(s, subtype)) { - lua_pushnumber(L, subtype(n)); + lua_pushinteger(L, subtype(n)); } else { lua_pushnil(L); } } else if (t == boundary_node) { if (lua_key_eq(s, subtype)) { - lua_pushnumber(L, subtype(n)); + lua_pushinteger(L, subtype(n)); } else if (lua_key_eq(s, value)) { - lua_pushnumber(L, boundary_value(n)); + lua_pushinteger(L, boundary_value(n)); } else { lua_pushnil(L); } @@ -3369,21 +3466,19 @@ static int lua_nodelib_getfield(lua_State * L) static void lua_nodelib_direct_getfield_whatsit(lua_State * L, int n, const char *s) { - int t ; - t = subtype(n); - + int t = subtype(n); if (t == user_defined_node) { if (lua_key_eq(s, user_id)) { - lua_pushnumber(L, user_node_id(n)); + lua_pushinteger(L, user_node_id(n)); } else if (lua_key_eq(s, type)) { - lua_pushnumber(L, user_node_type(n)); + lua_pushinteger(L, user_node_type(n)); } else if (lua_key_eq(s, value)) { switch (user_node_type(n)) { case 'a': nodelib_pushdirect(user_node_value(n)); break; case 'd': - lua_pushnumber(L, user_node_value(n)); + lua_pushinteger(L, user_node_value(n)); break; case 'l': if (user_node_value(n) != 0) { @@ -3402,7 +3497,7 @@ static void lua_nodelib_direct_getfield_whatsit(lua_State * L, int n, const char tokenlist_to_lua(L, user_node_value(n)); break; default: - lua_pushnumber(L, user_node_value(n)); + lua_pushinteger(L, user_node_value(n)); break; } } else { @@ -3410,7 +3505,7 @@ static void lua_nodelib_direct_getfield_whatsit(lua_State * L, int n, const char } } else if (t == pdf_literal_node) { if (lua_key_eq(s, mode)) { - lua_pushnumber(L, pdf_literal_mode(n)); + lua_pushinteger(L, pdf_literal_mode(n)); } else if (lua_key_eq(s, data)) { if (pdf_literal_type(n) == lua_refid_literal) { lua_rawgeti(L, LUA_REGISTRYINDEX, pdf_literal_data(n)); @@ -3434,13 +3529,13 @@ static void lua_nodelib_direct_getfield_whatsit(lua_State * L, int n, const char } } else if (t == pdf_annot_node) { if (lua_key_eq(s, width)) { - lua_pushnumber(L, width(n)); + lua_pushinteger(L, width(n)); } else if (lua_key_eq(s, depth)) { - lua_pushnumber(L, depth(n)); + lua_pushinteger(L, depth(n)); } else if (lua_key_eq(s, height)) { - lua_pushnumber(L, height(n)); + lua_pushinteger(L, height(n)); } else if (lua_key_eq(s, objnum)) { - lua_pushnumber(L, pdf_annot_objnum(n)); + lua_pushinteger(L, pdf_annot_objnum(n)); } else if (lua_key_eq(s, data)) { tokenlist_to_luastring(L, pdf_annot_data(n)); } else { @@ -3448,24 +3543,24 @@ static void lua_nodelib_direct_getfield_whatsit(lua_State * L, int n, const char } } else if (t == pdf_dest_node) { if (lua_key_eq(s, width)) { - lua_pushnumber(L, width(n)); + lua_pushinteger(L, width(n)); } else if (lua_key_eq(s, depth)) { - lua_pushnumber(L, depth(n)); + lua_pushinteger(L, depth(n)); } else if (lua_key_eq(s, height)) { - lua_pushnumber(L, height(n)); + lua_pushinteger(L, height(n)); } else if (lua_key_eq(s, named_id)) { - lua_pushnumber(L, pdf_dest_named_id(n)); + lua_pushinteger(L, pdf_dest_named_id(n)); } else if (lua_key_eq(s, dest_id)) { if (pdf_dest_named_id(n) == 1) tokenlist_to_luastring(L, pdf_dest_id(n)); else - lua_pushnumber(L, pdf_dest_id(n)); + lua_pushinteger(L, pdf_dest_id(n)); } else if (lua_key_eq(s, dest_type)) { - lua_pushnumber(L, pdf_dest_type(n)); + lua_pushinteger(L, pdf_dest_type(n)); } else if (lua_key_eq(s, xyz_zoom)) { - lua_pushnumber(L, pdf_dest_xyz_zoom(n)); + lua_pushinteger(L, pdf_dest_xyz_zoom(n)); } else if (lua_key_eq(s, objnum)) { - lua_pushnumber(L, pdf_dest_objnum(n)); + lua_pushinteger(L, pdf_dest_objnum(n)); } else { lua_pushnil(L); } @@ -3477,9 +3572,9 @@ static void lua_nodelib_direct_getfield_whatsit(lua_State * L, int n, const char } } else if (t == pdf_colorstack_node) { if (lua_key_eq(s, stack)) { - lua_pushnumber(L, pdf_colorstack_stack(n)); + lua_pushinteger(L, pdf_colorstack_stack(n)); } else if (lua_key_eq(s, command)) { - lua_pushnumber(L, pdf_colorstack_cmd(n)); + lua_pushinteger(L, pdf_colorstack_cmd(n)); } else if (lua_key_eq(s, data)) { tokenlist_to_luastring(L, pdf_colorstack_data(n)); } else { @@ -3487,13 +3582,13 @@ static void lua_nodelib_direct_getfield_whatsit(lua_State * L, int n, const char } } else if (t == pdf_refobj_node) { if (lua_key_eq(s, objnum)) { - lua_pushnumber(L, pdf_obj_objnum(n)); + lua_pushinteger(L, pdf_obj_objnum(n)); } else { lua_pushnil(L); } } else if (t == write_node) { if (lua_key_eq(s, stream)) { - lua_pushnumber(L, write_stream(n)); + lua_pushinteger(L, write_stream(n)); } else if (lua_key_eq(s, data)) { tokenlist_to_lua(L, write_tokens(n)); } else { @@ -3507,13 +3602,13 @@ static void lua_nodelib_direct_getfield_whatsit(lua_State * L, int n, const char } } else if (t == pdf_start_link_node) { if (lua_key_eq(s, width)) { - lua_pushnumber(L, width(n)); + lua_pushinteger(L, width(n)); } else if (lua_key_eq(s, depth)) { - lua_pushnumber(L, depth(n)); + lua_pushinteger(L, depth(n)); } else if (lua_key_eq(s, height)) { - lua_pushnumber(L, height(n)); + lua_pushinteger(L, height(n)); } else if (lua_key_eq(s, objnum)) { - lua_pushnumber(L, pdf_link_objnum(n)); + lua_pushinteger(L, pdf_link_objnum(n)); } else if (lua_key_eq(s, link_attr)) { tokenlist_to_luastring(L, pdf_link_attr(n)); } else if (lua_key_eq(s, action)) { @@ -3523,40 +3618,40 @@ static void lua_nodelib_direct_getfield_whatsit(lua_State * L, int n, const char } } else if (t == pdf_action_node) { if (lua_key_eq(s, action_type)) { - lua_pushnumber(L, pdf_action_type(n)); + lua_pushinteger(L, pdf_action_type(n)); } else if (lua_key_eq(s, named_id)) { - lua_pushnumber(L, pdf_action_named_id(n)); + lua_pushinteger(L, pdf_action_named_id(n)); } else if (lua_key_eq(s, action_id)) { if (pdf_action_named_id(n) == 1) { tokenlist_to_luastring(L, pdf_action_id(n)); } else { - lua_pushnumber(L, pdf_action_id(n)); + lua_pushinteger(L, pdf_action_id(n)); } } else if (lua_key_eq(s, file)) { tokenlist_to_luastring(L, pdf_action_file(n)); } else if (lua_key_eq(s, new_window)) { - lua_pushnumber(L, pdf_action_new_window(n)); + lua_pushinteger(L, pdf_action_new_window(n)); } else if (lua_key_eq(s, data)) { tokenlist_to_luastring(L, pdf_action_tokens(n)); } else if (lua_key_eq(s, ref_count)) { - lua_pushnumber(L, pdf_action_refcount(n)); + lua_pushinteger(L, pdf_action_refcount(n)); } else { lua_pushnil(L); } } else if ((t == pdf_thread_node) || (t == pdf_start_thread_node)) { if (lua_key_eq(s, width)) { - lua_pushnumber(L, width(n)); + lua_pushinteger(L, width(n)); } else if (lua_key_eq(s, depth)) { - lua_pushnumber(L, depth(n)); + lua_pushinteger(L, depth(n)); } else if (lua_key_eq(s, height)) { - lua_pushnumber(L, height(n)); + lua_pushinteger(L, height(n)); } else if (lua_key_eq(s, named_id)) { - lua_pushnumber(L, pdf_thread_named_id(n)); + lua_pushinteger(L, pdf_thread_named_id(n)); } else if (lua_key_eq(s, thread_id)) { if (pdf_thread_named_id(n) == 1) { tokenlist_to_luastring(L, pdf_thread_id(n)); } else { - lua_pushnumber(L, pdf_thread_id(n)); + lua_pushinteger(L, pdf_thread_id(n)); } } else if (lua_key_eq(s, thread_attr)) { tokenlist_to_luastring(L, pdf_thread_attr(n)); @@ -3565,7 +3660,7 @@ static void lua_nodelib_direct_getfield_whatsit(lua_State * L, int n, const char } } else if (t == open_node) { if (lua_key_eq(s, stream)) { - lua_pushnumber(L, write_stream(n)); + lua_pushinteger(L, write_stream(n)); } else if (lua_key_eq(s, name)) { nodelib_pushstring(L, open_name(n)); } else if (lua_key_eq(s, area)) { @@ -3577,7 +3672,7 @@ static void lua_nodelib_direct_getfield_whatsit(lua_State * L, int n, const char } } else if (t == close_node) { if (lua_key_eq(s, stream)) { - lua_pushnumber(L, write_stream(n)); + lua_pushinteger(L, write_stream(n)); } else { lua_pushnil(L); } @@ -3589,24 +3684,16 @@ static void lua_nodelib_direct_getfield_whatsit(lua_State * L, int n, const char static int lua_nodelib_direct_getfield(lua_State * L) { - halfword n; const char *s; - int t ; - - n = (halfword) lua_tonumber(L, 1); - - t = type(n); - + halfword n = lua_tointeger(L, 1); + int t = type(n); if (lua_type(L, 2) == LUA_TNUMBER) { - halfword p; int i; - if (! nodetype_has_attributes(t)) { lua_pushnil(L) ; return 1; } - p = node_attr(n); if (p == null || vlink(p) == null) { lua_pushnil(L) ; @@ -3617,7 +3704,7 @@ static int lua_nodelib_direct_getfield(lua_State * L) while (p != null) { if (attribute_id(p) == i) { if ((int) attribute_value(p) > UNUSED_ATTRIBUTE) { - lua_pushnumber(L, (int) attribute_value(p)); + lua_pushinteger(L, (int) attribute_value(p)); } else { lua_pushnil(L); } @@ -3635,50 +3722,50 @@ static int lua_nodelib_direct_getfield(lua_State * L) s = lua_tostring(L, 2); if (lua_key_eq(s, id)) { - lua_pushnumber(L, t); + lua_pushinteger(L, t); } else if (lua_key_eq(s, next)) { nodelib_pushdirect_or_nil(vlink(n)); } else if (lua_key_eq(s, prev)) { nodelib_pushdirect_or_nil(alink(n)); + } else if (lua_key_eq(s, subtype)) { + if (t == glue_spec_node) { + lua_pushinteger(L, 0); /* dummy, the only one */ + } else { + lua_pushinteger(L, subtype(n)); + } } else if (lua_key_eq(s, attr)) { if (! nodetype_has_attributes(t)) { lua_pushnil(L); } else { nodelib_pushattr(L, node_attr(n)); } - } else if (lua_key_eq(s, subtype)) { - if (t == glue_spec_node) { - lua_pushnumber(L, 0); /* dummy, the only one */ - } else { - lua_pushnumber(L, subtype(n)); - } } else if (t == glyph_node) { if (lua_key_eq(s, font)) { - lua_pushnumber(L, font(n)); + lua_pushinteger(L, font(n)); } else if (lua_key_eq(s, char)) { - lua_pushnumber(L, character(n)); + lua_pushinteger(L, character(n)); } else if (lua_key_eq(s, xoffset)) { - lua_pushnumber(L, x_displace(n)); + lua_pushinteger(L, x_displace(n)); } else if (lua_key_eq(s, yoffset)) { - lua_pushnumber(L, y_displace(n)); + lua_pushinteger(L, y_displace(n)); } else if (lua_key_eq(s, width)) { - lua_pushnumber(L, char_width(font(n),character(n))); + lua_pushinteger(L, char_width(font(n),character(n))); } else if (lua_key_eq(s, height)) { - lua_pushnumber(L, char_height(font(n),character(n))); + lua_pushinteger(L, char_height(font(n),character(n))); } else if (lua_key_eq(s, depth)) { - lua_pushnumber(L, char_depth(font(n),character(n))); + lua_pushinteger(L, char_depth(font(n),character(n))); } else if (lua_key_eq(s, expansion_factor)) { - lua_pushnumber(L, ex_glyph(n)); + lua_pushinteger(L, ex_glyph(n)); } else if (lua_key_eq(s, components)) { nodelib_pushdirect_or_nil(lig_ptr(n)); } else if (lua_key_eq(s, lang)) { - lua_pushnumber(L, char_lang(n)); + lua_pushinteger(L, char_lang(n)); } else if (lua_key_eq(s, left)) { - lua_pushnumber(L, char_lhmin(n)); + lua_pushinteger(L, char_lhmin(n)); } else if (lua_key_eq(s, right)) { - lua_pushnumber(L, char_rhmin(n)); + lua_pushinteger(L, char_rhmin(n)); } else if (lua_key_eq(s, uchyph)) { - lua_pushnumber(L, char_uchyph(n)); + lua_pushinteger(L, char_uchyph(n)); } else { lua_pushnil(L); } @@ -3687,21 +3774,21 @@ static int lua_nodelib_direct_getfield(lua_State * L) if (lua_key_eq(s, list) || lua_key_eq(s, head)) { nodelib_pushdirect_or_nil_alink(list_ptr(n)); } else if (lua_key_eq(s, width)) { - lua_pushnumber(L, width(n)); + lua_pushinteger(L, width(n)); } else if (lua_key_eq(s, height)) { - lua_pushnumber(L, height(n)); + lua_pushinteger(L, height(n)); } else if (lua_key_eq(s, depth)) { - lua_pushnumber(L, depth(n)); + lua_pushinteger(L, depth(n)); } else if (lua_key_eq(s, dir)) { lua_push_dir_par(L, box_dir(n)); } else if (lua_key_eq(s, shift)) { - lua_pushnumber(L, shift_amount(n)); + lua_pushinteger(L, shift_amount(n)); } else if (lua_key_eq(s, glue_order)) { - lua_pushnumber(L, glue_order(n)); + lua_pushinteger(L, glue_order(n)); } else if (lua_key_eq(s, glue_sign)) { - lua_pushnumber(L, glue_sign(n)); + lua_pushinteger(L, glue_sign(n)); } else if (lua_key_eq(s, glue_set)) { - lua_pushnumber(L, (double) glue_set(n)); + lua_pushnumber(L, (double) glue_set(n)); /* float */ } else { lua_pushnil(L); } @@ -3723,34 +3810,34 @@ static int lua_nodelib_direct_getfield(lua_State * L) } else { n = glue_ptr(n); if (!n) { - lua_pushnil(L); + lua_pushinteger(L, 0); /* zero skip constant */ } else if (lua_key_eq(s, width)) { - lua_pushnumber(L, width(n)); + lua_pushinteger(L, width(n)); } else if (lua_key_eq(s, stretch)) { - lua_pushnumber(L, stretch(n)); + lua_pushinteger(L, stretch(n)); } else if (lua_key_eq(s, shrink)) { - lua_pushnumber(L, shrink(n)); + lua_pushinteger(L, shrink(n)); } else if (lua_key_eq(s, stretch_order)) { - lua_pushnumber(L, stretch_order(n)); + lua_pushinteger(L, stretch_order(n)); } else if (lua_key_eq(s, shrink_order)) { - lua_pushnumber(L, shrink_order(n)); + lua_pushinteger(L, shrink_order(n)); } else { lua_pushnil(L); } } } else if (t == glue_spec_node) { if (lua_key_eq(s, width)) { - lua_pushnumber(L, width(n)); + lua_pushinteger(L, width(n)); } else if (lua_key_eq(s, stretch)) { - lua_pushnumber(L, stretch(n)); + lua_pushinteger(L, stretch(n)); } else if (lua_key_eq(s, shrink)) { - lua_pushnumber(L, shrink(n)); + lua_pushinteger(L, shrink(n)); } else if (lua_key_eq(s, stretch_order)) { - lua_pushnumber(L, stretch_order(n)); + lua_pushinteger(L, stretch_order(n)); } else if (lua_key_eq(s, shrink_order)) { - lua_pushnumber(L, shrink_order(n)); + lua_pushinteger(L, shrink_order(n)); } else if (lua_key_eq(s, ref_count)) { - lua_pushnumber(L, glue_ref_count(n)); + lua_pushinteger(L, glue_ref_count(n)); } else if (lua_key_eq(s, writable)) { lua_pushboolean(L, valid_node(n)); } else { @@ -3758,63 +3845,62 @@ static int lua_nodelib_direct_getfield(lua_State * L) } } else if (t == kern_node) { if (lua_key_eq(s, kern)) { - lua_pushnumber(L, width(n)); + lua_pushinteger(L, width(n)); } else if (lua_key_eq(s, expansion_factor)) { - lua_pushnumber(L, ex_kern(n)); + lua_pushinteger(L, ex_kern(n)); } else { lua_pushnil(L); } } else if (t == penalty_node) { if (lua_key_eq(s, penalty)) { - lua_pushnumber(L, penalty(n)); + lua_pushinteger(L, penalty(n)); } else { lua_pushnil(L); } } else if (t == rule_node) { /* candidates: whd (width,height,depth) */ if (lua_key_eq(s, width)) { - lua_pushnumber(L, width(n)); + lua_pushinteger(L, width(n)); } else if (lua_key_eq(s, height)) { - lua_pushnumber(L, height(n)); + lua_pushinteger(L, height(n)); } else if (lua_key_eq(s, depth)) { - lua_pushnumber(L, depth(n)); + lua_pushinteger(L, depth(n)); } else if (lua_key_eq(s, dir)) { lua_push_dir_par(L, rule_dir(n)); } else if (lua_key_eq(s, index)) { - lua_pushnumber(L, rule_index(n)); + lua_pushinteger(L, rule_index(n)); } else if (lua_key_eq(s, transform)) { - lua_pushnumber(L,rule_transform(n)); + lua_pushinteger(L,rule_transform(n)); } else { lua_pushnil(L); } } else if (t == dir_node) { if (lua_key_eq(s, dir)) { - // nodelib_pushdir(L, dir_dir(n), true); lua_push_dir_text(L, dir_dir(n)); } else if (lua_key_eq(s, level)) { - lua_pushnumber(L, dir_level(n)); + lua_pushinteger(L, dir_level(n)); } else if (lua_key_eq(s, dvi_ptr)) { - lua_pushnumber(L, dir_dvi_ptr(n)); + lua_pushinteger(L, dir_dvi_ptr(n)); } else if (lua_key_eq(s, dir_h)) { - lua_pushnumber(L, dir_dvi_h(n)); + lua_pushinteger(L, dir_dvi_h(n)); } else { lua_pushnil(L); } } else if (t == local_par_node) { if (lua_key_eq(s, pen_inter)) { - lua_pushnumber(L, local_pen_inter(n)); + lua_pushinteger(L, local_pen_inter(n)); } else if (lua_key_eq(s, pen_broken)) { - lua_pushnumber(L, local_pen_broken(n)); + lua_pushinteger(L, local_pen_broken(n)); } else if (lua_key_eq(s, dir)) { lua_push_dir_par(L, local_par_dir(n)); } else if (lua_key_eq(s, box_left)) { nodelib_pushdirect_or_nil(local_box_left(n)); } else if (lua_key_eq(s, box_left_width)) { - lua_pushnumber(L, local_box_left_width(n)); + lua_pushinteger(L, local_box_left_width(n)); } else if (lua_key_eq(s, box_right)) { nodelib_pushdirect_or_nil(local_box_right(n)); } else if (lua_key_eq(s, box_right_width)) { - lua_pushnumber(L, local_box_right_width(n)); + lua_pushinteger(L, local_box_right_width(n)); } else { lua_pushnil(L); } @@ -3832,15 +3918,15 @@ static int lua_nodelib_direct_getfield(lua_State * L) } } else if ((t == math_char_node) || (t == math_text_char_node)) { if (lua_key_eq(s, fam)) { - lua_pushnumber(L, math_fam(n)); + lua_pushinteger(L, math_fam(n)); } else if (lua_key_eq(s, char)) { - lua_pushnumber(L, math_character(n)); + lua_pushinteger(L, math_character(n)); } else { lua_pushnil(L); } } else if (t == mark_node) { if (lua_key_eq(s, class)) { - lua_pushnumber(L, mark_class(n)); + lua_pushinteger(L, mark_class(n)); } else if (lua_key_eq(s, mark)) { tokenlist_to_lua(L, mark_ptr(n)); } else { @@ -3848,11 +3934,11 @@ static int lua_nodelib_direct_getfield(lua_State * L) } } else if (t == ins_node) { if (lua_key_eq(s, cost)) { - lua_pushnumber(L, float_cost(n)); + lua_pushinteger(L, float_cost(n)); } else if (lua_key_eq(s, depth)) { - lua_pushnumber(L, depth(n)); + lua_pushinteger(L, depth(n)); } else if (lua_key_eq(s, height)) { - lua_pushnumber(L, height(n)); + lua_pushinteger(L, height(n)); } else if (lua_key_eq(s, spec)) { nodelib_pushdirect_or_nil(split_top_ptr(n)); } else if ((lua_key_eq(s, list)) || (lua_key_eq(s, head))) { @@ -3862,13 +3948,13 @@ static int lua_nodelib_direct_getfield(lua_State * L) } } else if (t == math_node) { if (lua_key_eq(s, surround)) { - lua_pushnumber(L, surround(n)); + lua_pushinteger(L, surround(n)); } else { lua_pushnil(L); } } else if (t == fraction_noad) { if (lua_key_eq(s, width)) { - lua_pushnumber(L, thickness(n)); + lua_pushinteger(L, thickness(n)); } else if (lua_key_eq(s, num)) { nodelib_pushdirect_or_nil(numerator(n)); } else if (lua_key_eq(s, denom)) { @@ -3910,13 +3996,13 @@ static int lua_nodelib_direct_getfield(lua_State * L) } } else if (t == delim_node) { if (lua_key_eq(s, small_fam)) { - lua_pushnumber(L, small_fam(n)); + lua_pushinteger(L, small_fam(n)); } else if (lua_key_eq(s, small_char)) { - lua_pushnumber(L, small_char(n)); + lua_pushinteger(L, small_char(n)); } else if (lua_key_eq(s, large_fam)) { - lua_pushnumber(L, large_fam(n)); + lua_pushinteger(L, large_fam(n)); } else if (lua_key_eq(s, large_char)) { - lua_pushnumber(L, large_char(n)); + lua_pushinteger(L, large_char(n)); } else { lua_pushnil(L); } @@ -3942,7 +4028,7 @@ static int lua_nodelib_direct_getfield(lua_State * L) } } else if (t == margin_kern_node) { if (lua_key_eq(s, width)) { - lua_pushnumber(L, width(n)); + lua_pushinteger(L, width(n)); } else if (lua_key_eq(s, glyph)) { nodelib_pushdirect_or_nil(margin_char(n)); } else { @@ -3982,9 +4068,9 @@ static int lua_nodelib_direct_getfield(lua_State * L) } } else if (t == attribute_node) { if (lua_key_eq(s, number)) { - lua_pushnumber(L, attribute_id(n)); + lua_pushinteger(L, attribute_id(n)); } else if (lua_key_eq(s, value)) { - lua_pushnumber(L, attribute_value(n)); + lua_pushinteger(L, attribute_value(n)); } else { lua_pushnil(L); } @@ -3996,23 +4082,23 @@ static int lua_nodelib_direct_getfield(lua_State * L) } } else if (t == unset_node) { if (lua_key_eq(s, width)) { - lua_pushnumber(L, width(n)); + lua_pushinteger(L, width(n)); } else if (lua_key_eq(s, height)) { - lua_pushnumber(L, height(n)); + lua_pushinteger(L, height(n)); } else if (lua_key_eq(s, depth)) { - lua_pushnumber(L, depth(n)); + lua_pushinteger(L, depth(n)); } else if (lua_key_eq(s, dir)) { lua_push_dir_par(L, box_dir(n)); } else if (lua_key_eq(s, shrink)) { - lua_pushnumber(L, glue_shrink(n)); + lua_pushinteger(L, glue_shrink(n)); } else if (lua_key_eq(s, glue_order)) { - lua_pushnumber(L, glue_order(n)); + lua_pushinteger(L, glue_order(n)); } else if (lua_key_eq(s, glue_sign)) { - lua_pushnumber(L, glue_sign(n)); + lua_pushinteger(L, glue_sign(n)); } else if (lua_key_eq(s, stretch)) { - lua_pushnumber(L, glue_stretch(n)); + lua_pushinteger(L, glue_stretch(n)); } else if (lua_key_eq(s, count)) { - lua_pushnumber(L, span_count(n)); + lua_pushinteger(L, span_count(n)); } else if ((lua_key_eq(s, list)) || (lua_key_eq(s, head))){ nodelib_pushdirect_or_nil_alink(list_ptr(n)); } else { @@ -4022,9 +4108,9 @@ static int lua_nodelib_direct_getfield(lua_State * L) /* lua_pushnil(L); */ } else if (t == boundary_node) { if (lua_key_eq(s, subtype)) { - lua_pushnumber(L, subtype(n)); + lua_pushinteger(L, subtype(n)); } else if (lua_key_eq(s, value)) { - lua_pushnumber(L, boundary_value(n)); + lua_pushinteger(L, boundary_value(n)); } else { lua_pushnil(L); } @@ -4042,7 +4128,6 @@ static void lua_nodelib_do_tostring(lua_State * L, halfword n, const char *tag) char a[7] = { ' ', ' ', ' ', 'n', 'i', 'l', 0 }; char v[7] = { ' ', ' ', ' ', 'n', 'i', 'l', 0 }; msg = xmalloc(256); - if ((alink(n) != null) && (type(n) != attribute_node)) snprintf(a, 7, "%6d", (int) alink(n)); if (vlink(n) != null) @@ -4057,9 +4142,8 @@ static void lua_nodelib_do_tostring(lua_State * L, halfword n, const char *tag) static int lua_nodelib_tostring(lua_State * L) { - halfword *n; - n = check_isnode(L, 1); - lua_nodelib_do_tostring(L, *n, "node"); + halfword n = *check_isnode(L, 1); + lua_nodelib_do_tostring(L, n, "node"); return 1; } @@ -4067,7 +4151,7 @@ static int lua_nodelib_tostring(lua_State * L) static int lua_nodelib_direct_tostring(lua_State * L) { - halfword n = (halfword) lua_tonumber(L,1); + halfword n = lua_tointeger(L,1); if (n==0) { lua_pushnil(L); } else { @@ -4080,9 +4164,8 @@ static int lua_nodelib_direct_tostring(lua_State * L) static int lua_nodelib_equal(lua_State * L) { - halfword n, m; - n = *((halfword *) lua_touserdata(L, 1)); - m = *((halfword *) lua_touserdata(L, 2)); + halfword n = *((halfword *) lua_touserdata(L, 1)); + halfword m = *((halfword *) lua_touserdata(L, 2)); lua_pushboolean(L, (n == m)); return 1; } @@ -4094,39 +4177,74 @@ static int font_tex_ligaturing(lua_State * L) /* on the stack are two nodes and a direction */ /* hh-ls: we need to deal with prev nodes when a range starts with a ligature */ halfword tmp_head; - halfword *h; + halfword h; halfword t = null; - halfword p ; /* hh-ls */ + halfword p ; if (lua_gettop(L) < 1) { lua_pushnil(L); lua_pushboolean(L, 0); return 2; } - h = check_isnode(L, 1); + h = *check_isnode(L, 1); if (lua_gettop(L) > 1) { - t = *(check_isnode(L, 2)); + t = *check_isnode(L, 2); } tmp_head = new_node(nesting_node, 1); - p = alink(*h); /* hh-ls */ - couple_nodes(tmp_head, *h); + p = alink(h); + couple_nodes(tmp_head, h); tlink(tmp_head) = t; t = handle_ligaturing(tmp_head, t); if (p != null) { - vlink(p) = vlink(tmp_head) ; /* hh-ls */ + vlink(p) = vlink(tmp_head) ; } - alink(vlink(tmp_head)) = p ; /* hh-ls */ - lua_pushnumber(L, vlink(tmp_head)); - /* can be: lua_nodelib_push_fast(L, head); */ - flush_node(tmp_head); + alink(vlink(tmp_head)) = p ; + /* + lua_pushinteger(L, vlink(tmp_head)); lua_nodelib_push(L); - /* can be: lua_nodelib_push_fast(L, t); */ - lua_pushnumber(L, t); + */ + lua_nodelib_push_fast(L, vlink(tmp_head)); + /* + lua_pushinteger(L, t); lua_nodelib_push(L); + */ + lua_nodelib_push_fast(L, t); lua_pushboolean(L, 1); + flush_node(tmp_head); return 3; } - +static int font_tex_direct_ligaturing(lua_State * L) +{ + /* on the stack are two nodes and a direction */ + /* hh-ls: we need to deal with prev nodes when a range starts with a ligature */ + halfword tmp_head; + halfword h; + halfword t = null; + halfword p ; + if (lua_gettop(L) < 1) { + lua_pushnil(L); + lua_pushboolean(L, 0); + return 2; + } + h = lua_tointeger(L, 1); + if (lua_gettop(L) > 1) { + t = lua_tointeger(L, 2); + } + tmp_head = new_node(nesting_node, 1); + p = alink(h); + couple_nodes(tmp_head, h); + tlink(tmp_head) = t; + t = handle_ligaturing(tmp_head, t); + if (p != null) { + vlink(p) = vlink(tmp_head) ; + } + alink(vlink(tmp_head)) = p ; + lua_pushinteger(L, vlink(tmp_head)); + lua_pushinteger(L, t); + lua_pushboolean(L, 1); + flush_node(tmp_head); + return 3; +} /* node.kerning */ @@ -4135,35 +4253,72 @@ static int font_tex_kerning(lua_State * L) /* on the stack are two nodes and a direction */ halfword tmp_head; - halfword *h; + halfword h; halfword t = null; - halfword p ; /* hh-ls */ + halfword p ; if (lua_gettop(L) < 1) { lua_pushnil(L); lua_pushboolean(L, 0); return 2; } - h = check_isnode(L, 1); + h = *check_isnode(L, 1); if (lua_gettop(L) > 1) { - t = *(check_isnode(L, 2)); + t = *check_isnode(L, 2); } tmp_head = new_node(nesting_node, 1); - p = alink(*h); /* hh-ls */ - couple_nodes(tmp_head, *h); + p = alink(h); + couple_nodes(tmp_head, h); tlink(tmp_head) = t; t = handle_kerning(tmp_head, t); if (p != null) { - vlink(p) = vlink(tmp_head) ; /* hh-ls */ + vlink(p) = vlink(tmp_head) ; } - alink(vlink(tmp_head)) = p ; /* hh-ls */ - lua_pushnumber(L, vlink(tmp_head)); - /* can be: lua_nodelib_push_fast(L, head); */ - flush_node(tmp_head); + alink(vlink(tmp_head)) = p ; + /* + lua_pushinteger(L, vlink(tmp_head)); lua_nodelib_push(L); - /* can be: lua_nodelib_push_fast(L, t); */ - lua_pushnumber(L, t); + */ + lua_nodelib_push_fast(L, vlink(tmp_head)); + /* + lua_pushinteger(L, t); lua_nodelib_push(L); + */ + lua_nodelib_push_fast(L, t); lua_pushboolean(L, 1); + flush_node(tmp_head); + return 3; +} + +static int font_tex_direct_kerning(lua_State * L) +{ + /* on the stack are two nodes and a direction */ + + halfword tmp_head; + halfword h; + halfword t = null; + halfword p ; + if (lua_gettop(L) < 1) { + lua_pushnil(L); + lua_pushboolean(L, 0); + return 2; + } + h = lua_tointeger(L, 1); + if (lua_gettop(L) > 1) { + t = lua_tointeger(L, 2); + } + tmp_head = new_node(nesting_node, 1); + p = alink(h); + couple_nodes(tmp_head, h); + tlink(tmp_head) = t; + t = handle_kerning(tmp_head, t); + if (p != null) { + vlink(p) = vlink(tmp_head) ; + } + alink(vlink(tmp_head)) = p ; + lua_pushinteger(L, vlink(tmp_head)); + lua_pushinteger(L, t); + lua_pushboolean(L, 1); + flush_node(tmp_head); return 3; } @@ -4172,7 +4327,7 @@ static int font_tex_kerning(lua_State * L) static int lua_nodelib_protect_glyphs(lua_State * L) { int t = 0; - halfword head = *(check_isnode(L, 1)); + halfword head = *check_isnode(L, 1); while (head != null) { if (type(head) == glyph_node) { int s = subtype(head); @@ -4188,12 +4343,24 @@ static int lua_nodelib_protect_glyphs(lua_State * L) return 2; } +static int lua_nodelib_protect_glyph(lua_State * L) +{ + halfword n = *check_isnode(L, 1); + if (type(n) == glyph_node) { + int s = subtype(n); + if (s <= 256) { + subtype(n) = (quarterword) (s == 1 ? 256 : 256 + s); + } + } + return 0; +} + /* node.direct.protect_glyphs */ static int lua_nodelib_direct_protect_glyphs(lua_State * L) { int t = 0; - halfword head = (halfword) lua_tonumber(L,1); + halfword head = (halfword) lua_tointeger(L,1); while (head != null) { if (type(head) == glyph_node) { int s = subtype(head); @@ -4209,6 +4376,18 @@ static int lua_nodelib_direct_protect_glyphs(lua_State * L) return 2; } +static int lua_nodelib_direct_protect_glyph(lua_State * L) +{ + halfword n = (halfword) lua_tointeger(L,1); + if ((n != null) && (type(n) == glyph_node)) { + int s = subtype(n); + if (s <= 256) { + subtype(n) = (quarterword) (s == 1 ? 256 : 256 + s); + } + } + return 0; +} + /* node.unprotect_glyphs (returns also boolean because that signals callback) */ static int lua_nodelib_unprotect_glyphs(lua_State * L) @@ -4235,7 +4414,7 @@ static int lua_nodelib_unprotect_glyphs(lua_State * L) static int lua_nodelib_direct_unprotect_glyphs(lua_State * L) { int t = 0; - halfword head = (halfword) lua_tonumber(L,1); + halfword head = (halfword) lua_tointeger(L,1); while (head != null) { if (type(head) == glyph_node) { int s = subtype(head); @@ -4274,7 +4453,7 @@ static int lua_nodelib_first_glyph(lua_State * L) if (savetail != null) { vlink(t) = savetail; } - lua_pushnumber(L, h); + lua_pushinteger(L, h); lua_nodelib_push(L); lua_pushboolean(L, (h == null ? 0 : 1)); return 2; @@ -4287,12 +4466,12 @@ static int lua_nodelib_direct_first_glyph(lua_State * L) halfword h,savetail,t; savetail = null; t = null; - h = (halfword) lua_tonumber(L,1); + h = (halfword) lua_tointeger(L,1); if (h == null) { lua_pushnil(L); return 1; } - t = (halfword) lua_tonumber(L,2); + t = (halfword) lua_tointeger(L,2); if (t != null) { savetail = vlink(t); vlink(t) = null; @@ -4301,7 +4480,7 @@ static int lua_nodelib_direct_first_glyph(lua_State * L) h = vlink(h); if (savetail != null) vlink(t) = savetail; - lua_pushnumber(L, h); + lua_pushinteger(L, h); return 1; /* no need to also push a boolean if we have nil */ } @@ -4340,7 +4519,7 @@ static int lua_nodelib_has_glyph(lua_State * L) static int lua_nodelib_direct_has_glyph(lua_State * L) { - halfword h = (halfword) lua_tonumber(L,1) ; + halfword h = (halfword) lua_tointeger(L,1) ; while (h != null) { if ((type(h) == glyph_node) || (type(h) == disc_node)) { nodelib_pushdirect(h); @@ -4353,15 +4532,6 @@ static int lua_nodelib_direct_has_glyph(lua_State * L) return 1; } - -/* depricated */ - -static int lua_nodelib_first_character(lua_State * L) -{ - luatex_warn("node.first_character() is deprecated, please update to node.first_glyph()"); - return lua_nodelib_first_glyph(L); -} - /* this is too simplistic, but it helps Hans to get going */ static halfword do_ligature_n(halfword prev, halfword stop, halfword lig) @@ -4377,19 +4547,19 @@ static halfword do_ligature_n(halfword prev, halfword stop, halfword lig) static int lua_nodelib_do_ligature_n(lua_State * L) { - halfword n, m, o, p, tmp_head; - n = *(check_isnode(L, 1)); - m = *(check_isnode(L, 2)); - o = *(check_isnode(L, 3)); + halfword p; + halfword n = *check_isnode(L, 1); + halfword m = *check_isnode(L, 2); + halfword o = *check_isnode(L, 3); if (alink(n) == null || vlink(alink(n)) != n) { - tmp_head = new_node(temp_node, 0); + halfword tmp_head = new_node(temp_node, 0); couple_nodes(tmp_head, n); p = do_ligature_n(tmp_head, m, o); flush_node(tmp_head); } else { p = do_ligature_n(alink(n), m, o); } - lua_pushnumber(L, p); + lua_pushinteger(L, p); lua_nodelib_push(L); return 1; } @@ -4398,22 +4568,22 @@ static int lua_nodelib_do_ligature_n(lua_State * L) static int lua_nodelib_direct_do_ligature_n(lua_State * L) { - halfword n, m, o, p, tmp_head; - n = (halfword) lua_tonumber(L, 1); - m = (halfword) lua_tonumber(L, 2); - o = (halfword) lua_tonumber(L, 3); + halfword p; + halfword n = (halfword) lua_tointeger(L, 1); + halfword m = (halfword) lua_tointeger(L, 2); + halfword o = (halfword) lua_tointeger(L, 3); if ((n == null) || (m == null) || (o == null)) { lua_pushnil(L); } else { if (alink(n) == null || vlink(alink(n)) != n) { - tmp_head = new_node(temp_node, 0); + halfword tmp_head = new_node(temp_node, 0); couple_nodes(tmp_head, n); p = do_ligature_n(tmp_head, m, o); flush_node(tmp_head); } else { p = do_ligature_n(alink(n), m, o); } - lua_pushnumber(L, p); + lua_pushinteger(L, p); } return 1; } @@ -4422,7 +4592,7 @@ static int lua_nodelib_direct_do_ligature_n(lua_State * L) static int lua_nodelib_usedlist(lua_State * L) { - lua_pushnumber(L, list_node_mem_usage()); + lua_pushinteger(L, list_node_mem_usage()); lua_nodelib_push(L); return 1; } @@ -4431,7 +4601,7 @@ static int lua_nodelib_usedlist(lua_State * L) static int lua_nodelib_direct_usedlist(lua_State * L) { - lua_pushnumber(L, list_node_mem_usage()); + lua_pushinteger(L, list_node_mem_usage()); return 1; } @@ -4439,8 +4609,7 @@ static int lua_nodelib_direct_usedlist(lua_State * L) static int lua_nodelib_cp_skipable(lua_State * L) { - halfword n; - n = *(check_isnode(L, 1)); + halfword n = *check_isnode(L, 1); lua_pushboolean(L, cp_skipable(n)); return 1; } @@ -4449,8 +4618,7 @@ static int lua_nodelib_cp_skipable(lua_State * L) static int lua_nodelib_direct_cp_skipable(lua_State * L) { - halfword n; - n = (halfword) lua_tonumber(L, 1); + halfword n = lua_tointeger(L, 1); if (n == null) { lua_pushnil(L); } else { @@ -4472,7 +4640,7 @@ static int lua_nodelib_currentattr(lua_State * L) /* or null (attr_list_cache can also be null) */ n = current_attribute_list(); if (n) { - lua_pushnumber(L, n); + lua_pushinteger(L, n); lua_nodelib_push(L); } else @@ -4480,7 +4648,7 @@ static int lua_nodelib_currentattr(lua_State * L) return 1; } else { /* assign */ - luatex_warn("Assignment via node.current_attr(<list>) is not supported (yet)"); + normal_warning("node lib","assignment via node.current_attr(<list>) is not supported (yet)"); return 0; } } @@ -4490,12 +4658,11 @@ static int lua_nodelib_currentattr(lua_State * L) static int lua_nodelib_direct_currentattr(lua_State * L) { - halfword n ; /* current_attribute_list() return attr_list_cache */ /* or null (attr_list_cache can also be null) */ - n = current_attribute_list(); + halfword n = current_attribute_list(); if (n) - lua_pushnumber(L, n); + lua_pushinteger(L, n); else lua_pushnil(L); return 1; @@ -4513,7 +4680,7 @@ static int lua_nodelib_direct_todirect(lua_State * L) if (n == null) { lua_pushnil(L); } else { - lua_pushnumber(L, *((halfword *)n) ); + lua_pushinteger(L, *((halfword *)n) ); } } /* else assume direct and returns argument */ return 1; @@ -4525,8 +4692,7 @@ static int lua_nodelib_direct_todirect(lua_State * L) static int lua_nodelib_direct_tonode(lua_State * L) { halfword *a; - halfword n; - n = (halfword) lua_tonumber(L, 1); + halfword n = lua_tointeger(L, 1); if (n != null) { a = (halfword *) lua_newuserdata(L, sizeof(halfword)); *a=n; @@ -4558,8 +4724,7 @@ static int lua_nodelib_direct_tonode(lua_State * L) static int lua_nodelib_setfield_whatsit(lua_State * L, int n, const char *s) { - int t ; - t = subtype(n); + int t = subtype(n); if (t == pdf_literal_node) { if (lua_key_eq(s, mode)) { @@ -4794,20 +4959,15 @@ static int lua_nodelib_setfield_whatsit(lua_State * L, int n, const char *s) static int lua_nodelib_fast_setfield(lua_State * L) { - halfword n; + halfword g, c, v; const char *s; - int t ; - - n = *((halfword *) lua_touserdata(L, 1)); - t = type(n); + halfword n = *((halfword *) lua_touserdata(L, 1)); + int t = type(n); if (lua_type(L, 2) == LUA_TNUMBER) { - - int i, val; - if (lua_gettop(L) == 3) { - i = (int) lua_tointeger(L, 2); - val = (int) lua_tointeger(L, 3); + int i = lua_tointeger(L, 2); + int val = lua_tointeger(L, 3); if (val == UNUSED_ATTRIBUTE) { (void) unset_attribute(n, i, val); } else { @@ -4892,7 +5052,7 @@ static int lua_nodelib_fast_setfield(lua_State * L) } else if (lua_key_eq(s, glue_sign)) { glue_sign(n) = (quarterword) lua_tointeger(L, 3); } else if (lua_key_eq(s, glue_set)) { - glue_set(n) = (glue_ratio) lua_tonumber(L, 3); + glue_set(n) = (glue_ratio) lua_tonumber(L, 3); /* integer or float */ } else { return nodelib_cantset(L, n, s); } @@ -4916,20 +5076,15 @@ static int lua_nodelib_fast_setfield(lua_State * L) } else if (lua_key_eq(s, leader)) { leader_ptr(n) = nodelib_getlist(L, 3); } else if (lua_key_eq(s, width)) { - nodelib_check_glue_spec(n); - width(n) = (halfword) lua_tointeger(L, 3); + nodelib_check_glue_spec(n, g, width); } else if (lua_key_eq(s, stretch)) { - nodelib_check_glue_spec(n); - stretch(n) = (halfword) lua_tointeger(L, 3); + nodelib_check_glue_spec(n, g, stretch); } else if (lua_key_eq(s, shrink)) { - nodelib_check_glue_spec(n); - shrink(n) = (halfword) lua_tointeger(L, 3); + nodelib_check_glue_spec(n, g, shrink); } else if (lua_key_eq(s, stretch_order)) { - nodelib_check_glue_spec(n); - stretch_order(n) = (quarterword) lua_tointeger(L, 3); + nodelib_check_glue_spec(n, g, stretch_order); } else if (lua_key_eq(s, shrink_order)) { - nodelib_check_glue_spec(n); - shrink_order(n) = (quarterword) lua_tointeger(L, 3); + nodelib_check_glue_spec(n, g, shrink_order); } else { return nodelib_cantset(L, n, s); } @@ -5100,7 +5255,6 @@ static int lua_nodelib_fast_setfield(lua_State * L) /* dummy subtype */ } else if (lua_key_eq(s, style)) { assign_math_style(L,3,subtype(n)); - //subtype(n) = (quarterword) luaL_checkoption(L, 3, "text", math_style_names); /* not 2? */ } else { /* return nodelib_cantset(L, n, s); */ } @@ -5303,9 +5457,7 @@ static int lua_nodelib_setfield(lua_State * L) static int lua_nodelib_direct_setfield_whatsit(lua_State * L, int n, const char *s) { - int t ; - t = subtype(n); - + int t = subtype(n); if (t == pdf_literal_node) { if (lua_key_eq(s, mode)) { pdf_literal_mode(n) = (quarterword) lua_tointeger(L, 3); @@ -5538,8 +5690,7 @@ static int lua_nodelib_direct_setfield_whatsit(lua_State * L, int n, const char static int lua_nodelib_direct_setcharacter(lua_State * L) { - halfword n; - n = (halfword ) lua_tonumber(L, 1); + halfword n = lua_tointeger(L, 1); if ((n) && (lua_type(L, 2) == LUA_TNUMBER)) { if (type(n) == glyph_node) { character(n) = (halfword) lua_tointeger(L, 2); @@ -5552,8 +5703,7 @@ static int lua_nodelib_direct_setcharacter(lua_State * L) static int lua_nodelib_direct_setnext(lua_State * L) { - halfword n; - n = (halfword ) lua_tonumber(L, 1); + halfword n = lua_tointeger(L, 1); if (n) { if (lua_type(L, 2) == LUA_TNUMBER) { vlink(n) = (halfword) lua_tointeger(L, 2); @@ -5566,8 +5716,7 @@ static int lua_nodelib_direct_setnext(lua_State * L) static int lua_nodelib_direct_setprev(lua_State * L) { - halfword n; - n = (halfword ) lua_tonumber(L, 1); + halfword n = lua_tointeger(L, 1); if (n) { if (lua_type(L, 2) == LUA_TNUMBER) { alink(n) = (halfword) lua_tointeger(L, 2); @@ -5580,8 +5729,7 @@ static int lua_nodelib_direct_setprev(lua_State * L) static int lua_nodelib_direct_setboth(lua_State * L) { - halfword n; - n = (halfword ) lua_tonumber(L, 1); + halfword n = lua_tointeger(L, 1); if (n) { if (lua_type(L, 2) == LUA_TNUMBER) { alink(n) = (halfword) lua_tointeger(L, 2); @@ -5599,18 +5747,17 @@ static int lua_nodelib_direct_setboth(lua_State * L) static int lua_nodelib_direct_setlink(lua_State * L) { - halfword a, b; if (lua_type(L, 1) == LUA_TNUMBER) { - a = (halfword ) lua_tonumber(L, 1); + halfword a = lua_tointeger(L, 1); if (lua_type(L, 2) == LUA_TNUMBER) { - b = (halfword ) lua_tonumber(L, 2); + halfword b = lua_tointeger(L, 2); vlink(a) = b; alink(b) = a; } else { vlink(a) = null; } } else if (lua_type(L, 2) == LUA_TNUMBER) { - b = (halfword ) lua_tonumber(L, 2); + halfword b = lua_tointeger(L, 2); alink(b) = null; } return 0; @@ -5618,13 +5765,16 @@ static int lua_nodelib_direct_setlink(lua_State * L) static int lua_nodelib_direct_is_char(lua_State * L) { - halfword n; - halfword f; - n = (halfword ) lua_tointeger(L, 1); - if ((type(n) == glyph_node) && (subtype(n) < 256)) { - f = (halfword ) lua_tointeger(L, 2); - if (f && f == font(n)) { - lua_pushboolean(L,1); + halfword n = lua_tointeger(L, 1); + if ((type(n) == glyph_node) && (subtype(n) < 256)) { /* <= 256 */ + if (lua_type(L,2) == LUA_TNUMBER) { + halfword f = lua_tointeger(L, 2); + if (f && f == font(n)) { + lua_pushinteger(L,character(n)); + return 1; + } + } else { + lua_pushinteger(L,character(n)); return 1; } } @@ -5634,11 +5784,9 @@ static int lua_nodelib_direct_is_char(lua_State * L) static int lua_nodelib_direct_setdiscretionary(lua_State * L) { - int t ; - halfword n; - n = (halfword ) lua_tonumber(L, 1); + halfword n = lua_tointeger(L, 1); if (type(n) == disc_node) { - t = lua_gettop(L) ; + int t = lua_gettop(L) ; if (t > 1) { set_disc_field(pre_break(n), lua_tointeger(L,2)); if (t > 2) { @@ -5670,20 +5818,16 @@ static int lua_nodelib_direct_setdiscretionary(lua_State * L) static int lua_nodelib_direct_setfield(lua_State * L) { - halfword n; + halfword g, c, v; const char *s; - int t ; - n = (halfword ) lua_tonumber(L, 1); - t = type(n); + halfword n = lua_tointeger(L, 1); + int t = type(n); if (lua_type(L, 2) == LUA_TNUMBER) { - - int i, val; - if (lua_gettop(L) == 3) { - i = (int) lua_tointeger(L, 2); - val = (int) lua_tointeger(L, 3); + int i = lua_tointeger(L, 2); + int val = lua_tointeger(L, 3); if (val == UNUSED_ATTRIBUTE) { (void) unset_attribute(n, i, val); } else { @@ -5768,7 +5912,7 @@ static int lua_nodelib_direct_setfield(lua_State * L) } else if (lua_key_eq(s, glue_sign)) { glue_sign(n) = (quarterword) lua_tointeger(L, 3); } else if (lua_key_eq(s, glue_set)) { - glue_set(n) = (glue_ratio) lua_tonumber(L, 3); + glue_set(n) = (glue_ratio) lua_tonumber(L, 3); /* integer or float */ } else { return nodelib_cantset(L, n, s); } @@ -5792,20 +5936,15 @@ static int lua_nodelib_direct_setfield(lua_State * L) } else if (lua_key_eq(s, leader)) { leader_ptr(n) = nodelib_popdirect(3); } else if (lua_key_eq(s, width)) { - nodelib_check_glue_spec(n); - width(n) = (halfword) lua_tointeger(L, 3); + nodelib_check_glue_spec(n, g, width); } else if (lua_key_eq(s, stretch)) { - nodelib_check_glue_spec(n); - stretch(n) = (halfword) lua_tointeger(L, 3); + nodelib_check_glue_spec(n, g, stretch); } else if (lua_key_eq(s, shrink)) { - nodelib_check_glue_spec(n); - shrink(n) = (halfword) lua_tointeger(L, 3); + nodelib_check_glue_spec(n, g, shrink); } else if (lua_key_eq(s, stretch_order)) { - nodelib_check_glue_spec(n); - stretch_order(n) = (quarterword) lua_tointeger(L, 3); + nodelib_check_glue_spec(n, g, stretch_order); } else if (lua_key_eq(s, shrink_order)) { - nodelib_check_glue_spec(n); - shrink_order(n) = (quarterword) lua_tointeger(L, 3); + nodelib_check_glue_spec(n, g, shrink_order); } else { return nodelib_cantset(L, n, s); } @@ -5976,7 +6115,6 @@ static int lua_nodelib_direct_setfield(lua_State * L) /* dummy subtype */ } else if (lua_key_eq(s, style)) { assign_math_style(L,2,subtype(n)); - //subtype(n) = (quarterword) luaL_checkoption(L, 2, "text", math_style_names); /* was 3 */ } else { /* return nodelib_cantset(L, n, s); */ } @@ -6165,21 +6303,21 @@ static int direct_get_box_id(lua_State * L, int i) size_t k = 0; int j = -1; switch (lua_type(L, i)) { - case LUA_TSTRING: - s = lua_tolstring(L, i, &k); - cur_cs1 = string_lookup(s, k); - cur_cmd1 = eq_type(cur_cs1); - if (cur_cmd1 == char_given_cmd || - cur_cmd1 == math_given_cmd) { - j = equiv(cur_cs1); - } - break; - case LUA_TNUMBER: - j=(int)lua_tonumber(L, (i)); - break; - default: - luaL_error(L, "argument must be a string or a number"); - j = -1; /* not a valid box id */ + case LUA_TSTRING: + s = lua_tolstring(L, i, &k); + cur_cs1 = string_lookup(s, k); + cur_cmd1 = eq_type(cur_cs1); + if (cur_cmd1 == char_given_cmd || + cur_cmd1 == math_given_cmd) { + j = equiv(cur_cs1); + } + break; + case LUA_TNUMBER: + j = lua_tointeger(L, (i)); + break; + default: + luaL_error(L, "argument must be a string or a number"); + j = -1; /* not a valid box id */ } return j; } @@ -6190,11 +6328,11 @@ static int direct_get_box_id(lua_State * L, int i) static int lua_nodelib_direct_getbox(lua_State * L) { - int k, t; - k = direct_get_box_id(L, -1); + int t; + int k = direct_get_box_id(L, -1); direct_check_index_range(k, "getbox"); t = get_tex_box_register(k); - lua_pushnumber(L, t); + lua_pushinteger(L, t); return 1; } @@ -6313,12 +6451,11 @@ static int lua_nodelib_direct_is_node(lua_State * L) /* if really needed we can provide this: -static int lua_nodelib_attributes_to_table(lua_State * L) // hh -{ // <node|direct> - halfword n; +static int lua_nodelib_attributes_to_table(lua_State * L) +{ halfword n; register halfword attribute; if (lua_type(L,1) == LUA_TNUMBER) { - n = lua_tonumber(L,1); + n = lua_tointeger(L,1); } else { n = *((halfword *) lua_touserdata(L, 1)); } @@ -6333,8 +6470,8 @@ static int lua_nodelib_attributes_to_table(lua_State * L) // hh lua_newtable(L); } while (attribute != null) { - lua_pushnumber(L,(int)attribute_id(attribute)); - lua_pushnumber(L,(int)attribute_value(attribute)); + lua_pushinteger(L,(int)attribute_id(attribute)); + lua_pushinteger(L,(int)attribute_value(attribute)); lua_rawset(L,-3); attribute = vlink(attribute) ; } @@ -6348,11 +6485,10 @@ static int lua_nodelib_attributes_to_table(lua_State * L) // hh /* There is no gain here but let's keep it around: static int lua_nodelib_attributes_to_properties(lua_State * L) -{ // <node|direct> - halfword n; +{ halfword n; register halfword attribute; if (lua_type(L,1) == LUA_TNUMBER) { - n = lua_tonumber(L,1); + n = lua_tointeger(L,1); } else { n = *((halfword *) lua_touserdata(L, 1)); } @@ -6373,8 +6509,8 @@ static int lua_nodelib_attributes_to_properties(lua_State * L) lua_pushnil(L); } else { while (attribute != null) { - lua_pushnumber(L,(int)attribute_id(attribute)); - lua_pushnumber(L,(int)attribute_value(attribute)); + lua_pushinteger(L,(int)attribute_id(attribute)); + lua_pushinteger(L,(int)attribute_value(attribute)); lua_rawset(L,-3); attribute = vlink(attribute) ; } @@ -6423,8 +6559,7 @@ static int lua_nodelib_properties_flush_table(lua_State * L) /* hh */ static int lua_nodelib_get_property(lua_State * L) /* hh */ { /* <node> */ - halfword n; - n = *((halfword *) lua_touserdata(L, 1)); + halfword n = *((halfword *) lua_touserdata(L, 1)); if (n == null) { lua_pushnil(L); } else { @@ -6437,7 +6572,7 @@ static int lua_nodelib_get_property(lua_State * L) /* hh */ static int lua_nodelib_direct_get_property(lua_State * L) /* hh */ { /* <direct> */ - halfword n = lua_tonumber(L, 1); + halfword n = lua_tointeger(L, 1); if (n == null) { lua_pushnil(L); } else { @@ -6451,8 +6586,7 @@ static int lua_nodelib_direct_get_property(lua_State * L) /* hh */ static int lua_nodelib_set_property(lua_State * L) /* hh */ { /* <node> <value> */ - halfword n; - n = *((halfword *) lua_touserdata(L, 1)); + halfword n = *((halfword *) lua_touserdata(L, 1)); if (n != null) { lua_settop(L,2); lua_rawgeti(L, LUA_REGISTRYINDEX, lua_key_index(node_properties)); @@ -6468,8 +6602,8 @@ static int lua_nodelib_set_property(lua_State * L) /* hh */ static int lua_nodelib_direct_set_property(lua_State * L) /* hh */ { /* <direct> <value> */ - halfword n = lua_tonumber(L, 1); - if (n != null) { // we could store in node instead */ + halfword n = lua_tointeger(L, 1); + if (n != null) { lua_settop(L,2); lua_rawgeti(L, LUA_REGISTRYINDEX, lua_key_index(node_properties)); lua_gettable(L, LUA_REGISTRYINDEX); @@ -6481,9 +6615,6 @@ static int lua_nodelib_direct_set_property(lua_State * L) /* hh */ return 0; } - - - static int lua_nodelib_direct_properties_get_table(lua_State * L) /* hh */ { /* <node|direct> */ lua_rawgeti(L, LUA_REGISTRYINDEX, lua_key_index(node_properties)); @@ -6502,8 +6633,7 @@ static int lua_nodelib_properties_get_table(lua_State * L) /* hh */ static int lua_nodelib_get_property_t(lua_State * L) /* hh */ { /* <table> <node> */ - halfword n; - n = *((halfword *) lua_touserdata(L, 2)); + halfword n = *((halfword *) lua_touserdata(L, 2)); if (n == null) { lua_pushnil(L); } else { @@ -6515,8 +6645,7 @@ static int lua_nodelib_get_property_t(lua_State * L) /* hh */ static int lua_nodelib_set_property_t(lua_State * L) /* hh */ { /* <table> <node> <value> */ - halfword n; - n = *((halfword *) lua_touserdata(L, 2)); + halfword n = *((halfword *) lua_touserdata(L, 2)); if (n != null) { lua_settop(L,3); lua_rawseti(L,1,n); @@ -6530,14 +6659,12 @@ static int lua_nodelib_effective_glue(lua_State * L) { halfword *glue; halfword *parent; - halfword s; - int w; glue = lua_touserdata(L, 1); if ((glue == NULL) || (type(*glue) != glue_node)) { lua_pushnil(L) ; } else { - s = glue_ptr(*glue); - w = width(s) ; + halfword s = glue_ptr(*glue); + int w = width(s) ; parent = lua_touserdata(L, 2); if ((parent != NULL) && ((type(*parent) == hlist_node) || (type(*parent) == vlist_node))) { if ((int)glue_sign(*parent) == 1) { @@ -6550,7 +6677,7 @@ static int lua_nodelib_effective_glue(lua_State * L) } } } - lua_pushnumber(L,w); + lua_pushinteger(L,w); } return 1; } @@ -6558,17 +6685,13 @@ static int lua_nodelib_effective_glue(lua_State * L) static int lua_nodelib_direct_effective_glue(lua_State * L) { - halfword glue; - halfword parent; - halfword s; - int w; - glue = (halfword)lua_tonumber(L, 1); + halfword glue = lua_tointeger(L, 1); if ((glue == null) || (type(glue) != glue_node)) { lua_pushnil(L) ; } else { - s = glue_ptr(glue); - w = width(s) ; - parent = (halfword)lua_tonumber(L, 2); + halfword s = glue_ptr(glue); + int w = width(s) ; + halfword parent = lua_tointeger(L, 2); if ((parent != null) && ((type(parent) == hlist_node) || (type(parent) == vlist_node))) { if ((int)glue_sign(parent) == 1) { if (stretch_order(s) == glue_order(parent)) { @@ -6580,7 +6703,7 @@ static int lua_nodelib_direct_effective_glue(lua_State * L) } } } - lua_pushnumber(L,w); + lua_pushinteger(L,w); } return 1; } @@ -6592,7 +6715,7 @@ static const struct luaL_Reg nodelib_p[] = { {NULL, NULL} /* sentinel */ }; -static void lua_new_properties_table(lua_State * L) /* hh */ +static void lua_new_properties_table(lua_State * L) { lua_pushstring(L,"node.properties"); lua_newtable(L); @@ -6606,8 +6729,6 @@ static void lua_new_properties_table(lua_State * L) /* hh */ lua_settable(L,LUA_REGISTRYINDEX); } -/* end of properties experiment */ - /* node.direct.* */ static const struct luaL_Reg direct_nodelib_f[] = { @@ -6618,9 +6739,8 @@ static const struct luaL_Reg direct_nodelib_f[] = { {"dimensions", lua_nodelib_direct_dimensions}, {"do_ligature_n", lua_nodelib_direct_do_ligature_n}, {"end_of_math", lua_nodelib_direct_end_of_math}, - /* {"family_font", lua_nodelib_mfont}, */ /* no node argument */ - /* {"fields", lua_nodelib_fields}, */ /* no node argument */ - /* {"first_character", lua_nodelib_first_character}, */ /* obsolete */ + /* {"family_font", lua_nodelib_mfont}, */ /* no node argument */ + /* {"fields", lua_nodelib_fields}, */ /* no node argument */ {"first_glyph", lua_nodelib_direct_first_glyph}, {"flush_list", lua_nodelib_direct_flush_list}, {"flush_node", lua_nodelib_direct_flush_node}, @@ -6639,24 +6759,24 @@ static const struct luaL_Reg direct_nodelib_f[] = { {"getsubtype", lua_nodelib_direct_getsubtype}, {"has_glyph", lua_nodelib_direct_has_glyph}, {"has_attribute", lua_nodelib_direct_has_attribute}, + {"get_attribute", lua_nodelib_direct_get_attribute}, {"has_field", lua_nodelib_direct_has_field}, {"is_char", lua_nodelib_direct_is_char}, {"hpack", lua_nodelib_direct_hpack}, - /* {"id", lua_nodelib_id}, */ /* no node argument */ + /* {"id", lua_nodelib_id}, */ /* no node argument */ {"insert_after", lua_nodelib_direct_insert_after}, {"insert_before", lua_nodelib_direct_insert_before}, {"is_direct", lua_nodelib_direct_is_direct}, {"is_node", lua_nodelib_direct_is_node}, - /* {"kerning", font_tex_kerning}, */ /* maybe direct too (rather basic callback exposure) */ + {"kerning", font_tex_direct_kerning}, {"last_node", lua_nodelib_direct_last_node}, {"length", lua_nodelib_direct_length}, - /* {"ligaturing", font_tex_ligaturing}, */ /* maybe direct too (rather basic callback exposure) */ - /* {"mlist_to_hlist", lua_nodelib_mlist_to_hset_properties_modelist}, */ /* maybe direct too (rather basic callback exposure) */ + {"ligaturing", font_tex_direct_ligaturing}, + /* {"mlist_to_hlist", lua_nodelib_mlist_to_hset_properties_modelist}, */ {"new", lua_nodelib_direct_new}, - /* {"next", lua_nodelib_next}, */ /* replaced by getnext */ - /* {"prev", lua_nodelib_prev}, */ /* replaced by getprev */ {"tostring", lua_nodelib_direct_tostring}, {"protect_glyphs", lua_nodelib_direct_protect_glyphs}, + {"protect_glyph", lua_nodelib_direct_protect_glyph}, {"protrusion_skippable", lua_nodelib_direct_cp_skipable}, {"remove", lua_nodelib_direct_remove}, {"set_attribute", lua_nodelib_direct_set_attribute}, @@ -6669,28 +6789,26 @@ static const struct luaL_Reg direct_nodelib_f[] = { {"setboth", lua_nodelib_direct_setboth}, {"setlink", lua_nodelib_direct_setlink}, {"slide", lua_nodelib_direct_slide}, - /* {"subtype", lua_nodelib_subtype}, */ /* no node argument */ + /* {"subtype", lua_nodelib_subtype}, */ /* no node argument */ {"tail", lua_nodelib_direct_tail}, - {"todirect", lua_nodelib_direct_todirect}, /* not in node.* */ - {"tonode", lua_nodelib_direct_tonode}, /* similar to node.* */ + {"todirect", lua_nodelib_direct_todirect}, + {"tonode", lua_nodelib_direct_tonode}, {"traverse", lua_nodelib_direct_traverse}, {"traverse_id", lua_nodelib_direct_traverse_filtered}, - /* {"type", lua_nodelib_type}, */ /* no node argument */ - /* {"types", lua_nodelib_types}, */ /* no node argument */ + {"traverse_char", lua_nodelib_direct_traverse_char}, + /* {"type", lua_nodelib_type}, */ /* no node argument */ + /* {"types", lua_nodelib_types}, */ /* no node argument */ {"unprotect_glyphs", lua_nodelib_direct_unprotect_glyphs}, {"unset_attribute", lua_nodelib_direct_unset_attribute}, {"usedlist", lua_nodelib_direct_usedlist}, {"vpack", lua_nodelib_direct_vpack}, - /* {"whatsits", lua_nodelib_whatsits}, */ /* no node argument */ + /* {"whatsits", lua_nodelib_whatsits}, */ /* no node argument */ {"write", lua_nodelib_direct_append}, - /* an experiment */ - /* {"attributes_to_table",lua_nodelib_attributes_to_table}, */ /* hh experiment */ - /* an experiment */ - {"set_properties_mode",lua_nodelib_properties_set_mode}, /* hh experiment */ + {"set_properties_mode",lua_nodelib_properties_set_mode}, {"flush_properties_table",lua_nodelib_properties_flush_table}, /* hh experiment */ {"get_properties_table",lua_nodelib_direct_properties_get_table}, /* hh experiment */ - {"getproperty", lua_nodelib_direct_get_property}, /* bonus */ /* hh experiment */ - {"setproperty", lua_nodelib_direct_set_property}, /* bonus */ /* hh experiment */ + {"getproperty", lua_nodelib_direct_get_property}, + {"setproperty", lua_nodelib_direct_set_property}, {"effective_glue", lua_nodelib_direct_effective_glue}, /* done */ {NULL, NULL} /* sentinel */ @@ -6709,7 +6827,6 @@ static const struct luaL_Reg nodelib_f[] = { {"family_font", lua_nodelib_mfont}, {"fields", lua_nodelib_fields}, {"subtypes", lua_nodelib_subtypes}, - {"first_character", lua_nodelib_first_character}, {"first_glyph", lua_nodelib_first_glyph}, {"flush_list", lua_nodelib_flush_list}, {"flush_node", lua_nodelib_flush_node}, @@ -6728,7 +6845,9 @@ static const struct luaL_Reg nodelib_f[] = { {"getchar", lua_nodelib_getcharacter}, {"has_glyph", lua_nodelib_has_glyph}, {"has_attribute", lua_nodelib_has_attribute}, + {"get_attribute", lua_nodelib_get_attribute}, {"has_field", lua_nodelib_has_field}, + {"is_char", lua_nodelib_is_char}, {"hpack", lua_nodelib_hpack}, {"id", lua_nodelib_id}, {"insert_after", lua_nodelib_insert_after}, @@ -6744,6 +6863,7 @@ static const struct luaL_Reg nodelib_f[] = { {"prev", lua_nodelib_prev}, /* getprev is somewhat more efficient, and get* fits better in direct compatibility */ {"tostring", lua_nodelib_tostring}, {"protect_glyphs", lua_nodelib_protect_glyphs}, + {"protect_glyph", lua_nodelib_protect_glyph}, {"protrusion_skippable", lua_nodelib_cp_skipable}, {"remove", lua_nodelib_remove}, /* {"setbox", lua_nodelib_setbox}, */ /* tex.setbox */ @@ -6753,6 +6873,7 @@ static const struct luaL_Reg nodelib_f[] = { {"tail", lua_nodelib_tail}, {"traverse", lua_nodelib_traverse}, {"traverse_id", lua_nodelib_traverse_filtered}, + {"traverse_char", lua_nodelib_traverse_char}, {"type", lua_nodelib_type}, {"types", lua_nodelib_types}, {"unprotect_glyphs", lua_nodelib_unprotect_glyphs}, @@ -6810,15 +6931,16 @@ int luaopen_node(lua_State * L) void nodelist_to_lua(lua_State * L, int n) { - lua_pushnumber(L, n); + lua_pushinteger(L, n); lua_nodelib_push(L); } int nodelist_from_lua(lua_State * L) { - halfword *n; - if (lua_isnil(L, -1)) + if (lua_isnil(L, -1)) { return null; - n = check_isnode(L, -1); - return (n ? *n : null); + } else { + halfword n= *check_isnode(L, -1); + return (n ? n : null); + } } diff --git a/Build/source/texk/web2c/luatexdir/lua/loslibext.c b/Build/source/texk/web2c/luatexdir/lua/loslibext.c index 5a20a63e440..76dd527c0bf 100644 --- a/Build/source/texk/web2c/luatexdir/lua/loslibext.c +++ b/Build/source/texk/web2c/luatexdir/lua/loslibext.c @@ -1,5 +1,5 @@ /* loslibext.c - + Copyright 2006-2012 Taco Hoekwater <taco@luatex.org> This file is part of LuaTeX. @@ -33,8 +33,8 @@ /* 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 - successfully compile without major prorting effort + and ignores platforms where luatex is unlikely to + successfully compile without major prorting effort (amiga|mac|os2|vms) */ #if defined(_WIN32) || defined(__NT__) @@ -111,14 +111,14 @@ /* Note: under WIN32, |environ| is nothing but a copy of the actual environment as it was during program startup. That variable - can then be changed (which is a little odd), but such changes + can then be changed (which is a little odd), but such changes do not survive in the actual environment *unless* they are passed on down in e.g. |_execvpe|, when they would be inherited - by the child process. + by the child process. - This gives trouble because some parts of the texk code actually - change the contents of the |environ| variable as a side-effect - of other processing, and that explains why the current code does + This gives trouble because some parts of the texk code actually + change the contents of the |environ| variable as a side-effect + of other processing, and that explains why the current code does not use |environ| at all for the moment. The API is kept in place for now, just in case. Thanks to Tomek @@ -205,21 +205,21 @@ static int exec_command(const char *file, char *const *av, char *const *envp) return -1; } -/* +/* It is not possible to mimic |spawnve()| completely. The main problem is - that the |fork|--|waitpid| combination cannot really do identical error + that the |fork|--|waitpid| combination cannot really do identical error reporting to the parent process, because it has to pass all the possible - error conditions as well as the actual process return status through a + error conditions as well as the actual process return status through a single 8-bit value. The current implementation tries to give back meaningful results for |execve()| errors in the child, for the cases that could also be returned by |spawnve()|, and for |ETXTBSY|, because that can be triggered by our path searching routine. - This implementation does not differentiate abnormal status conditions reported + This implementation does not differentiate abnormal status conditions reported by |waitpid()|, but will simply return a single error indication value. - For all this, hyjacking a bunch of numbers in the range 1...255 is needed. + For all this, hyjacking a bunch of numbers in the range 1...255 is needed. The chance of collisions is hopefully diminished by using a rather random range in the 8-bit section. */ @@ -284,7 +284,7 @@ static int spawn_command(const char *file, char *const *av, char *const *envp) #ifdef _WIN32 static char *get_command_name(char *maincmd) { - /* retrieve argv[0] part from the command string, + /* retrieve argv[0] part from the command string, it will be truncated to MAX_PATH if it's too long */ char *cmdname = (char *) malloc(sizeof(char) * MAX_PATH); int i, k, quoted; @@ -307,10 +307,10 @@ static char **do_split_command(const char *maincmd, char **runcmd) { char **cmdline = NULL; #ifdef _WIN32 - /* On WIN32 don't split anything, because - _spawnvpe can't put it back together properly - if there are quoted arguments with spaces. - Instead, dump everything into one argument + /* On WIN32 don't split anything, because + _spawnvpe can't put it back together properly + if there are quoted arguments with spaces. + Instead, dump everything into one argument and it will be passed through as is */ cmdline = malloc(sizeof(char *) * 2); cmdline[0] = xstrdup(maincmd); @@ -325,7 +325,7 @@ static char **do_split_command(const char *maincmd, char **runcmd) int quoted = 0; if (strlen(maincmd) == 0) return NULL; - /* allocate the array of options first. it will probably be + /* allocate the array of options first. it will probably be be a little bit too big, but better too much than to little */ j = 2; for (i = 0; i < strlen(maincmd); i++) { @@ -434,7 +434,7 @@ static int os_exec(lua_State * L) char *safecmd = NULL, *cmdname = NULL; char **cmdline = NULL; char **envblock = NULL; - + if (lua_gettop(L) != 1) { lua_pushnil(L); lua_pushliteral(L, "invalid arguments passed"); @@ -480,7 +480,7 @@ static int os_exec(lua_State * L) if (r == -1) { lua_pushnil(L); lua_pushfstring(L, "%s: %s", runcmd, strerror(errno)); - lua_pushnumber(L, errno); + lua_pushinteger(L, errno); return 3; } } @@ -503,7 +503,7 @@ static int os_exec(lua_State * L) #define do_error_return(A,B) do { \ lua_pushnil(L); \ lua_pushfstring(L,"%s: %s",runcmd,(A)); \ - lua_pushnumber(L, B); \ + lua_pushinteger(L, B); \ return 3; \ } while (0) @@ -555,7 +555,7 @@ static int os_spawn(lua_State * L) if (cmdname) free(cmdname); if (i == 0) { - lua_pushnumber(L, i); + lua_pushinteger(L, i); return 1; } else if (i == -1) { /* this branch covers WIN32 as well as fork() and waitpid() errors */ @@ -577,7 +577,7 @@ static int os_spawn(lua_State * L) do_error_return("execution interrupted", i); #endif } else { - lua_pushnumber(L, i); + lua_pushinteger(L, i); return 1; } } @@ -723,7 +723,7 @@ static int uname(struct utsname *uts) strcpy(uts->sysname, "Windows Vista"); /* Vista */ /* else - strcpy (uts->sysname, "Windows Server 2008"); + strcpy (uts->sysname, "Windows Server 2008"); */ } os = WinNT; @@ -775,9 +775,9 @@ static int uname(struct utsname *uts) strcpy(uts->machine, "mips"); break; case PROCESSOR_ARCHITECTURE_INTEL: - /* + /* * dwProcessorType is only valid in Win95 and Win98 and WinME - * wProcessorLevel is only valid in WinNT + * wProcessorLevel is only valid in WinNT */ switch (os) { case Win95: @@ -841,19 +841,19 @@ static int os_times(lua_State * L) struct tms r; (void) times(&r); lua_newtable(L); - lua_pushnumber(L, + lua_pushnumber(L, /* float */ ((lua_Number) (r.tms_utime)) / (lua_Number) sysconf(_SC_CLK_TCK)); lua_setfield(L, -2, "utime"); - lua_pushnumber(L, + lua_pushnumber(L, /* float */ ((lua_Number) (r.tms_stime)) / (lua_Number) sysconf(_SC_CLK_TCK)); lua_setfield(L, -2, "stime"); - lua_pushnumber(L, + lua_pushnumber(L, /* float */ ((lua_Number) (r.tms_cutime)) / (lua_Number) sysconf(_SC_CLK_TCK)); lua_setfield(L, -2, "cutime"); - lua_pushnumber(L, + lua_pushnumber(L, /* float */ ((lua_Number) (r.tms_cstime)) / (lua_Number) sysconf(_SC_CLK_TCK)); lua_setfield(L, -2, "cstime"); @@ -889,7 +889,7 @@ static int os_gettimeofday(lua_State * L) tmpres -= DELTA_EPOCH_IN_MICROSECS; /*converting file time to unix epoch */ v = (double) tmpres / 1000000.0; # endif - lua_pushnumber(L, v); + lua_pushnumber(L, v); /* float */ return 1; } #endif diff --git a/Build/source/texk/web2c/luatexdir/lua/lpdflib.c b/Build/source/texk/web2c/luatexdir/lua/lpdflib.c index b1dca1b5c1e..3a1c58f2ed4 100644 --- a/Build/source/texk/web2c/luatexdir/lua/lpdflib.c +++ b/Build/source/texk/web2c/luatexdir/lua/lpdflib.c @@ -100,7 +100,7 @@ static int l_immediateobj(lua_State * L) n = lua_gettop(L); if ((n > 0) && (lua_type(L, 1) == LUA_TNUMBER)) { first_arg++; - k=(int)lua_tonumber(L, 1); + k = (int) lua_tointeger(L, 1); check_obj_type(static_pdf, obj_type_obj, k); if (is_obj_scheduled(static_pdf, k) || obj_data_ptr(static_pdf, k) != 0) luaL_error(L, "pdf.immediateobj() object in use"); @@ -379,7 +379,7 @@ static int orig_obj(lua_State * L) n = lua_gettop(L); if ((n > 0) && (lua_type(L, 1) == LUA_TNUMBER)) { first_arg++; - k=(int)lua_tonumber(L, 1); + k = (int) lua_tointeger(L, 1); check_obj_type(static_pdf, obj_type_obj, k); if (is_obj_scheduled(static_pdf, k) || obj_data_ptr(static_pdf, k) != 0) luaL_error(L, "pdf.obj() object in use"); @@ -565,10 +565,10 @@ static int getpdf(lua_State * L) if (lua_type(L,-1) == LUA_TSTRING) { s = lua_tostring(L, -1); if (lua_key_eq(s,h)) { - lua_pushnumber(L, static_pdf->posstruct->pos.h); + lua_pushinteger(L, static_pdf->posstruct->pos.h); return 1; } else if (lua_key_eq(s,v)) { - lua_pushnumber(L, static_pdf->posstruct->pos.v); + lua_pushinteger(L, static_pdf->posstruct->pos.v); return 1; } else if (valid_pdf_key) { lua_rawgeti(L, LUA_REGISTRYINDEX, luaS_index(pdf_data)); @@ -703,26 +703,26 @@ static int l_pageref(lua_State * L) if (n <= 0) luaL_error(L, "pdf.pageref() needs page number > 0"); n = pdf_get_obj(static_pdf, obj_type_page, n, false); - lua_pushnumber(L, n); + lua_pushinteger(L, n); return 1; } static int l_getpos(lua_State * L) { - lua_pushnumber(L, static_pdf->posstruct->pos.h); - lua_pushnumber(L, static_pdf->posstruct->pos.v); + lua_pushinteger(L, static_pdf->posstruct->pos.h); + lua_pushinteger(L, static_pdf->posstruct->pos.v); return 2; } static int l_gethpos(lua_State * L) { - lua_pushnumber(L, static_pdf->posstruct->pos.h); + lua_pushinteger(L, static_pdf->posstruct->pos.h); return 1; } static int l_getvpos(lua_State * L) { - lua_pushnumber(L, static_pdf->posstruct->pos.v); + lua_pushinteger(L, static_pdf->posstruct->pos.v); return 1; } @@ -730,19 +730,19 @@ static int l_getmatrix(lua_State * L) { if (matrix_stack_used > 0) { matrix_entry *m = &matrix_stack[matrix_stack_used - 1]; - lua_pushnumber(L, m->a); - lua_pushnumber(L, m->b); - lua_pushnumber(L, m->c); - lua_pushnumber(L, m->d); - lua_pushnumber(L, m->e); - lua_pushnumber(L, m->f); + lua_pushinteger(L, m->a); + lua_pushinteger(L, m->b); + lua_pushinteger(L, m->c); + lua_pushinteger(L, m->d); + lua_pushinteger(L, m->e); + lua_pushinteger(L, m->f); } else { - lua_pushnumber(L, 1); - lua_pushnumber(L, 0); - lua_pushnumber(L, 0); - lua_pushnumber(L, 1); - lua_pushnumber(L, 0); - lua_pushnumber(L, 0); + lua_pushinteger(L, 1); + lua_pushinteger(L, 0); + lua_pushinteger(L, 0); + lua_pushinteger(L, 1); + lua_pushinteger(L, 0); + lua_pushinteger(L, 0); } return 6 ; } @@ -755,25 +755,25 @@ static int l_hasmatrix(lua_State * L) static int l_get_lastlink(lua_State * L) { - lua_pushnumber(L, (pdf_last_link)); + lua_pushinteger(L, (pdf_last_link)); return 1 ; } static int l_get_retval(lua_State * L) { - lua_pushnumber(L, (pdf_retval)); + lua_pushinteger(L, (pdf_retval)); return 1 ; } static int l_get_lastobj(lua_State * L) { - lua_pushnumber(L, (pdf_last_obj)); + lua_pushinteger(L, (pdf_last_obj)); return 1 ; } static int l_get_lastannot(lua_State * L) { - lua_pushnumber(L, (pdf_last_annot)); + lua_pushinteger(L, (pdf_last_annot)); return 1 ; } @@ -788,13 +788,13 @@ static int l_get_lastannot(lua_State * L) static int l_get_compresslevel(lua_State * L) { - lua_pushnumber(L, (pdf_compress_level)); + lua_pushinteger(L, (pdf_compress_level)); return 1 ; } static int l_get_objcompresslevel(lua_State * L) { - lua_pushnumber(L, (pdf_objcompresslevel)); + lua_pushinteger(L, (pdf_objcompresslevel)); return 1 ; } @@ -826,6 +826,27 @@ static int l_set_objcompresslevel(lua_State * L) return 0 ; } +/* accuracy */ + +static int l_get_decimal_digits(lua_State * L) +{ + lua_pushinteger(L, (pdf_decimal_digits)); + return 1 ; +} + + +static int l_set_decimal_digits(lua_State * L) +{ + int c ; + if (lua_type(L, 1) == LUA_TNUMBER) { + c = (int) lua_tointeger(L, 1); + if (c<0) + c = 0 ; + set_pdf_decimal_digits(c); + } + return 0 ; +} + /* pdf stuff */ static int getpdffontname(lua_State * L) @@ -837,7 +858,7 @@ static int getpdffontname(lua_State * L) if (!font_used(c)) pdf_init_font(static_pdf,c); set_ff(c); - lua_pushnumber(L, (obj_info(static_pdf, pdf_font_num(ff)))); + lua_pushinteger(L, (obj_info(static_pdf, pdf_font_num(ff)))); } else { lua_pushnil(L); } @@ -853,7 +874,7 @@ static int getpdffontobjnum(lua_State * L) if (!font_used(c)) pdf_init_font(static_pdf,c); set_ff(c); - lua_pushnumber(L, (pdf_font_num(ff))); + lua_pushinteger(L, (pdf_font_num(ff))); } else { lua_pushnil(L); } @@ -865,7 +886,7 @@ static int getpdffontsize(lua_State * L) int c; if (lua_type(L, 1) == LUA_TNUMBER) { c = (int) lua_tointeger(L, 1); - lua_pushnumber(L, (font_size(c))); + lua_pushinteger(L, (font_size(c))); } else { lua_pushnil(L); } @@ -877,7 +898,7 @@ static int getpdfpageref(lua_State * L) int c ; if (lua_type(L, 1) == LUA_TNUMBER) { c = (int) lua_tointeger(L, 1); - lua_pushnumber(L, (pdf_get_obj(static_pdf, obj_type_page, c, false))); + lua_pushinteger(L, (pdf_get_obj(static_pdf, obj_type_page, c, false))); } else { lua_pushnil(L); } @@ -890,7 +911,7 @@ static int getpdfxformname(lua_State * L) if (lua_type(L, 1) == LUA_TNUMBER) { c = (int) lua_tointeger(L, 1); check_obj_type(static_pdf, obj_type_xform, c); - lua_pushnumber(L, (obj_info(static_pdf, c))); + lua_pushinteger(L, (obj_info(static_pdf, c))); } else { lua_pushnil(L); } @@ -899,14 +920,14 @@ static int getpdfxformname(lua_State * L) static int getpdfversion(lua_State * L) { - lua_pushnumber(L,1); + lua_pushinteger(L,1); return 1 ; } static int getpdfminorversion(lua_State * L) { - /* lua_pushnumber(L,static_pdf->minor_version); */ - lua_pushnumber(L,pdf_minor_version); + /* lua_pushinteger(L,static_pdf->minor_version); */ + lua_pushinteger(L,pdf_minor_version); return 1 ; } @@ -923,6 +944,23 @@ static int setpdfminorversion(lua_State * L) return 0 ; } +static int setpdforigin(lua_State * L) +{ + int h = 0 ; + int v = 0 ; + if (lua_type(L, 1) == LUA_TNUMBER) { + h = (int) lua_tointeger(L, 1); + if (lua_type(L, 2) == LUA_TNUMBER) { + v = (int) lua_tointeger(L, 1); + } else { + v = h; + } + } + set_tex_extension_dimen_register(d_pdf_h_origin,h); + set_tex_extension_dimen_register(d_pdf_v_origin,v); + return 0 ; +} + static int newpdfcolorstack(lua_State * L) { const char *s = NULL; @@ -950,7 +988,7 @@ static int newpdfcolorstack(lua_State * L) page_start = lua_toboolean(L, 3); } id = newcolorstack(s, literal_mode, page_start); - lua_pushnumber(L, id); + lua_pushinteger(L, id); return 1 ; } @@ -997,6 +1035,8 @@ static const struct luaL_Reg pdflib[] = { { "getobjcompresslevel", l_get_objcompresslevel }, { "setcompresslevel", l_set_compresslevel }, { "setobjcompresslevel", l_set_objcompresslevel }, + { "getdecimaldigits", l_get_decimal_digits }, + { "setdecimaldigits", l_set_decimal_digits }, /* moved from tex table */ { "fontname", getpdffontname}, { "fontobjnum", getpdffontobjnum}, @@ -1007,6 +1047,7 @@ static const struct luaL_Reg pdflib[] = { { "getminorversion", getpdfminorversion}, { "setminorversion", setpdfminorversion}, { "newcolorstack", newpdfcolorstack}, + { "setorigin",setpdforigin}, /* sentinel */ {NULL, NULL} }; diff --git a/Build/source/texk/web2c/luatexdir/lua/lpdfscannerlib.cc b/Build/source/texk/web2c/luatexdir/lua/lpdfscannerlib.cc index 7fa6c4438c7..cc311daebee 100644 --- a/Build/source/texk/web2c/luatexdir/lua/lpdfscannerlib.cc +++ b/Build/source/texk/web2c/luatexdir/lua/lpdfscannerlib.cc @@ -1,5 +1,5 @@ /* lpdfscannerlib.c - + Copyright 2013 Taco Hoekwater <taco@luatex.org> This file is part of LuaTeX. @@ -162,7 +162,7 @@ static scannerdata *scanner_check (lua_State *L, int index) return bar; } -static void free_token (Token *token) +static void free_token (Token *token) { if (token->string) { free(token->string); @@ -419,10 +419,10 @@ static Token *_parseInlineImage (scannerdata *self, int c) /* remove end-of-line before EI */ if (found[foundindex-1] == '\n') { found[--foundindex] = '\0'; - } + } if (found[foundindex-1] == '\r') { found[--foundindex] = '\0'; - } + } break; } else { c = streamGetChar(self); @@ -433,7 +433,7 @@ static Token *_parseInlineImage (scannerdata *self, int c) c = streamGetChar(self); check_overflow(found, foundindex); found[foundindex++] = c; - } + } } else { c = streamGetChar(self); check_overflow(found, foundindex); @@ -454,7 +454,7 @@ static Token *_parseOperator (scannerdata *self, int c) found[foundindex++] = c; c = streamLookChar(self); if ((c<0) || (c == ' ' || c == '\n' || c == '\r' || c == '\t' || - c == '/' || c == '[' || c == '(' || c == '<')) + c == '/' || c == '[' || c == '(' || c == '<')) break ; c = streamGetChar(self); } @@ -480,7 +480,7 @@ static Token *_parseOperator (scannerdata *self, int c) } -static Token * _parseComment (scannerdata *self, int c) +static Token * _parseComment (scannerdata *self, int c) { do { c = streamGetChar(self); @@ -488,7 +488,7 @@ static Token * _parseComment (scannerdata *self, int c) return _parseToken(self,streamGetChar(self)); } -static Token *_parseLt (scannerdata *self, int c) +static Token *_parseLt (scannerdata *self, int c) { c = streamGetChar(self); if (c == '<') { @@ -496,9 +496,9 @@ static Token *_parseLt (scannerdata *self, int c) } else { return _parseHexstring(self,c); } -} +} -static Token * _parseGt (scannerdata *self, int c) +static Token * _parseGt (scannerdata *self, int c) { c = streamGetChar(self); if (c== '>') { @@ -510,24 +510,24 @@ static Token * _parseGt (scannerdata *self, int c) } -static Token *_parseError (int c) +static Token *_parseError (int c) { fprintf(stderr, "stray %c [%d] in stream", c, c); return NULL; } -static Token *_parseStartarray () +static Token *_parseStartarray () { return new_operand (pdf_startarray); } -static Token *_parseStoparray () +static Token *_parseStoparray () { return new_operand (pdf_stoparray); } -static Token *_parseToken (scannerdata *self, int c) +static Token *_parseToken (scannerdata *self, int c) { if (self->_ininlineimage==1) { self->_ininlineimage = 2; @@ -548,23 +548,23 @@ static Token *_parseToken (scannerdata *self, int c) case '<': return _parseLt(self,c); break; case '>': return _parseGt(self,c); break; case '%': return _parseComment(self,c); break; - case ' ': - case '\r': - case '\n': - case '\t': + case ' ': + case '\r': + case '\n': + case '\t': return _parseSpace(self); break; - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - case '-': - case '.': + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + case '-': + case '.': return _parseNumber(self,c); break; default: if (c<=127) { @@ -662,7 +662,7 @@ static int scanner_scan(lua_State * L) while (token) { if (token->type == pdf_operator) { lua_pushstring(L, token->string); - free_token(token); + free_token(token); lua_rawget(L,2); // operator table if (lua_isfunction(L,-1)) { lua_pushvalue(L,4); @@ -671,7 +671,7 @@ static int scanner_scan(lua_State * L) } else { lua_pop(L,1); // nil } - clear_operand_stack(self,0); + clear_operand_stack(self,0); } else { push_operand(self, token); } @@ -775,12 +775,12 @@ static void push_dict (lua_State *L, scannerdata *self) } } -const char *typenames[pdf_stopdict+1] = - { "unknown", "integer", "real", "boolean", "name", "operator", +const char *typenames[pdf_stopdict+1] = + { "unknown", "integer", "real", "boolean", "name", "operator", "string", "array", "array", "dict", "dict" }; static void push_token (lua_State *L, scannerdata *self) -{ +{ Token *token = self->_operandstack[self->_nextoperand-1]; lua_createtable(L,2,0); lua_pushstring (L, typenames[token->type]); @@ -788,7 +788,7 @@ static void push_token (lua_State *L, scannerdata *self) if (token->type == pdf_string || token->type == pdf_name) { lua_pushlstring(L, token->string, token->value); } else if (token->type == pdf_real || token->type == pdf_integer) { - lua_pushnumber(L, token->value); + lua_pushnumber(L, token->value); /* integer or float */ } else if (token->type == pdf_boolean) { lua_pushboolean(L, (int)token->value); } else if (token->type == pdf_startarray) { @@ -820,7 +820,7 @@ static int scanner_popsingular (lua_State * L, int token_type) { push_token(L, self); lua_rawgeti(L,-1,2); } else if (token_type == pdf_real || token_type == pdf_integer) { - lua_pushnumber(L, token->value); + lua_pushnumber(L, token->value); /* integer or float */ } else if (token_type == pdf_boolean) { lua_pushboolean(L,(int)token->value); } else if (token_type == pdf_name || token_type == pdf_string) { @@ -860,7 +860,7 @@ static int scanner_popanything (lua_State * L) { static int scanner_popnumber(lua_State * L) { - if(scanner_popsingular(L,pdf_real)) + if(scanner_popsingular(L,pdf_real)) return 1; if (scanner_popsingular(L,pdf_integer)) return 1; @@ -870,7 +870,7 @@ static int scanner_popnumber(lua_State * L) static int scanner_popboolean(lua_State * L) { - if(scanner_popsingular(L,pdf_boolean)) + if(scanner_popsingular(L,pdf_boolean)) return 1; lua_pushnil(L); return 1; diff --git a/Build/source/texk/web2c/luatexdir/lua/lstatslib.c b/Build/source/texk/web2c/luatexdir/lua/lstatslib.c index 74781cbd6af..7c6e1bda2b8 100644 --- a/Build/source/texk/web2c/luatexdir/lua/lstatslib.c +++ b/Build/source/texk/web2c/luatexdir/lua/lstatslib.c @@ -48,17 +48,43 @@ static const char *get_output_file_name(void) return NULL; } +/* static const char *getfilename(void) { int t = 0; int level = in_open; while ((level > 0)) { t = input_stack[level--].name_field; - if (t >= STRING_OFFSET) + if (t >= STRING_OFFSET) { return (const char *) str_string(t); + } } return ""; } +*/ + +static const char *getfilename(void) +{ + const char * s; + int level, t; + level = in_open; + while ((level > 0)) { + s = full_source_filename_stack[level--]; + if (s != NULL) { + return s; + } + } + /* old method */ + level = in_open; + while ((level > 0)) { + t = input_stack[level--].name_field; + if (t >= STRING_OFFSET) { + return (const char *) str_string(t); + } + } + return ""; +} + static const char *getlasterror(void) { @@ -147,7 +173,6 @@ static lua_Number get_pdf_mem_ptr(void) return (lua_Number) 0; } - static lua_Number get_obj_ptr(void) { if (static_pdf != NULL) @@ -181,6 +206,17 @@ static int get_hash_size(void) return hash_size; /* is a #define */ } +static lua_Number shell_escape_state(void) +{ + if (shellenabledp <= 0) { + return (lua_Number) 0; + } else if (restrictedshell == 0) { + return (lua_Number) 1; + } else { + return (lua_Number) 2; + } +} + static int luastate_max = 1; /* fixed value */ /* temp, for backward compat */ @@ -213,13 +249,14 @@ static struct statistic stats[] = { {"output_file_name", 'S', (void *) &get_output_file_name}, {"log_name", 'S', (void *) &getlogname}, {"banner", 'S', (void *) &getbanner}, - {"luatex_svn", 'G', &get_luatexsvn}, {"luatex_version", 'G', &get_luatexversion}, {"luatex_revision", 'S', (void *) &luatexrevision}, {"luatex_hashtype", 'S', (void *) &get_luatexhashtype}, {"luatex_hashchars", 'N', &get_luatexhashchars}, {"ini_version", 'b', &ini_version}, + + {"shell_escape", 'N', &shell_escape_state}, /* be easy on old time usage */ /* * mem stat */ @@ -254,7 +291,6 @@ static struct statistic stats[] = { {"buf_size", 'g', &buf_size}, {"save_size", 'g', &save_size}, {"input_ptr", 'g', &input_ptr}, - /* pdf stats */ {"obj_ptr", 'N', &get_obj_ptr}, {"obj_tab_size", 'N', &get_obj_tab_size}, {"pdf_os_cntr", 'N', &get_pdf_os_cntr}, @@ -263,9 +299,7 @@ static struct statistic stats[] = { {"dest_names_size", 'N', &get_dest_names_size}, {"pdf_mem_ptr", 'N', &get_pdf_mem_ptr}, {"pdf_mem_size", 'N', &get_pdf_mem_size}, - {"largest_used_mark", 'g', &biggest_used_mark}, - {"luabytecodes", 'g', &luabytecode_max}, {"luabytecode_bytes", 'g', &luabytecode_bytes}, {"luastates", 'g', &luastate_max}, @@ -313,14 +347,14 @@ static int do_getstat(lua_State * L, int i) break; case 'N': n = stats[i].value; - lua_pushnumber(L, n()); + lua_pushinteger(L, n()); break; case 'G': g = stats[i].value; - lua_pushnumber(L, g()); + lua_pushinteger(L, g()); break; case 'g': - lua_pushnumber(L, *(int *) (stats[i].value)); + lua_pushinteger(L, *(int *) (stats[i].value)); break; case 'B': g = stats[i].value; diff --git a/Build/source/texk/web2c/luatexdir/lua/ltexiolib.c b/Build/source/texk/web2c/luatexdir/lua/ltexiolib.c index 2ae5812af22..37c8fc79336 100644 --- a/Build/source/texk/web2c/luatexdir/lua/ltexiolib.c +++ b/Build/source/texk/web2c/luatexdir/lua/ltexiolib.c @@ -44,7 +44,7 @@ static boolean get_selector_value(lua_State * L, int i, int *l) r = true; } } else if (t == LUA_TNUMBER) { - int n = lua_tonumber(L,i); + int n = lua_tointeger(L,i); if (file_can_be_written(n)) { *l = n; r = true; @@ -71,7 +71,7 @@ static int do_texio_print(lua_State * L, texio_printer printfunction) if (get_selector_value(L, i, &selector)) i++; } - if (selector != log_only && selector != term_only && selector != term_and_log) { + if (selector != term_and_log && selector != log_only && selector != term_only) { if (! valid_write_file(selector)) { normalize_selector(); /* sets selector */ } @@ -145,9 +145,16 @@ void flush_loggable_info(void) } } +static int texio_setescape(lua_State * L) +{ + escape_controls = lua_tointeger(L,-1); + return 0 ; +} + static const struct luaL_Reg texiolib[] = { {"write", texio_print}, {"write_nl", texio_printnl}, + {"setescape", texio_setescape}, {NULL, NULL} }; diff --git a/Build/source/texk/web2c/luatexdir/lua/ltexlib.c b/Build/source/texk/web2c/luatexdir/lua/ltexlib.c index 2c292afa40a..2f4aa10230b 100644 --- a/Build/source/texk/web2c/luatexdir/lua/ltexlib.c +++ b/Build/source/texk/web2c/luatexdir/lua/ltexlib.c @@ -43,6 +43,7 @@ typedef struct { void *next; boolean partial; int cattable; + /* halfword tok; */ } rope; typedef struct { @@ -63,8 +64,8 @@ static int spindle_index = 0; static void luac_store(lua_State * L, int i, int partial, int cattable) { - char *st; const char *sttemp; + char *st; size_t tsize; rope *rn = NULL; sttemp = lua_tolstring(L, i, &tsize); @@ -78,6 +79,7 @@ static void luac_store(lua_State * L, int i, int partial, int cattable) rn->partial = partial; rn->cattable = cattable; rn->next = NULL; + /* rn->tok = 0; */ if (write_spindle.head == NULL) { assert(write_spindle.tail == NULL); write_spindle.head = rn; @@ -91,13 +93,12 @@ static void luac_store(lua_State * L, int i, int partial, int cattable) static int do_luacprint(lua_State * L, int partial, int deftable) { - int i, n; int cattable = deftable; int startstrings = 1; - n = lua_gettop(L); + int n = lua_gettop(L); if (cattable != NO_CAT_TABLE) { if (lua_type(L, 1) == LUA_TNUMBER && n > 1) { - cattable=(int)lua_tonumber(L, 1); + cattable = lua_tointeger(L, 1); startstrings = 2; if (cattable != -1 && cattable != -2 && !valid_catcode_table(cattable)) { cattable = DEFAULT_CAT_TABLE; @@ -105,6 +106,7 @@ static int do_luacprint(lua_State * L, int partial, int deftable) } } if (lua_type(L, startstrings) == LUA_TTABLE) { + int i; for (i = 1;; i++) { lua_rawgeti(L, startstrings, i); if (lua_isstring(L,-1)) { /* or number */ @@ -115,6 +117,7 @@ static int do_luacprint(lua_State * L, int partial, int deftable) } } } else { + int i; for (i = startstrings; i <= n; i++) { if (!lua_isstring(L,1)) { /* or number */ luaL_error(L, "no string to print"); @@ -136,6 +139,54 @@ static int do_luacprint(lua_State * L, int partial, int deftable) return 0; } +/* + +// some first experiments .. somewhat tricky at the other end + +int luatwrite(lua_State * L) +{ + int top = lua_gettop(L); + if (top>0) { + rope *rn = xmalloc(sizeof(rope)); // overkill + int i = 1 ; + luacstrings++; // should be luactokens + rn->text = NULL; + rn->tsize = 0; + rn->partial = 0; + rn->cattable = DEFAULT_CAT_TABLE; + rn->next = NULL; + rn->tok = 0; + if (write_spindle.head == NULL) { + write_spindle.head = rn; + } else { + write_spindle.tail->next = rn; + } + write_spindle.tail = rn; + write_spindle.complete = 0; + while (1) { + rn->tok = lua_tointeger(L,i); + if (i<top) { + rope *r = xmalloc(sizeof(rope)); // overkill + r->text = NULL; + r->tsize = 0; + r->partial = 0; + r->cattable = DEFAULT_CAT_TABLE; + r->next = NULL; + r->tok = 0; + rn->next = r; + rn = r; + write_spindle.tail = rn; + i++; + } else { + break; + } + } + } + return 0; +} + +*/ + static int luacwrite(lua_State * L) { return do_luacprint(L, FULL_LINE, NO_CAT_TABLE); @@ -153,9 +204,9 @@ static int luacsprint(lua_State * L) static int luactprint(lua_State * L) { - int i, j, n; + int i, j; int cattable, startstrings; - n = lua_gettop(L); + int n = lua_gettop(L); for (i = 1; i <= n; i++) { cattable = DEFAULT_CAT_TABLE; startstrings = 1; @@ -163,19 +214,18 @@ static int luactprint(lua_State * L) luaL_error(L, "no string to print"); } lua_pushvalue(L, i); /* push the table */ - lua_pushnumber(L, 1); + lua_pushinteger(L, 1); lua_gettable(L, -2); if (lua_type(L, -1) == LUA_TNUMBER) { - cattable=(int)lua_tonumber(L, -1); + cattable = lua_tointeger(L, -1); startstrings = 2; if (cattable != -1 && cattable != -2 && !valid_catcode_table(cattable)) { cattable = DEFAULT_CAT_TABLE; } } lua_pop(L, 1); - for (j = startstrings;; j++) { - lua_pushnumber(L, j); + lua_pushinteger(L, j); lua_gettable(L, -2); if (lua_isstring(L, -1)) { /* or number */ luac_store(L, -1, PARTIAL_LINE, cattable); @@ -190,7 +240,6 @@ static int luactprint(lua_State * L) return 0; } - int luacstring_cattable(void) { return (int) read_spindle.tail->cattable; @@ -208,9 +257,8 @@ int luacstring_final_line(void) int luacstring_input(void) { - char *st; - int ret; rope *t = read_spindle.head; + int ret = 1 ; if (!read_spindle.complete) { read_spindle.complete = 1; read_spindle.tail = NULL; @@ -222,12 +270,11 @@ int luacstring_input(void) return 0; } if (t->text != NULL) { - st = t->text; /* put that thing in the buffer */ + char *st = t->text; + int ret = first; last = first; - ret = last; check_buffer_overflow(last + (int) t->tsize); - while (t->tsize-- > 0) buffer[last++] = (packed_ASCII_code) * st++; if (!t->partial) { @@ -236,13 +283,17 @@ int luacstring_input(void) } free(t->text); t->text = NULL; + /* + } else if (t->tok > 0) { + ret = - t->tok; + */ } if (read_spindle.tail != NULL) { /* not a one-liner */ free(read_spindle.tail); } read_spindle.tail = t; read_spindle.head = t->next; - return 1; + return ret; } /* open for reading, and make a new one for writing */ @@ -272,8 +323,8 @@ void luacstring_close(int n) t = next; next = next->next; if (t==read_spindle.tail) { - read_spindle.tail = NULL; // prevent double-free - } + read_spindle.tail = NULL; + } free(t); } read_spindle.head = NULL; @@ -293,7 +344,7 @@ void luacstring_close(int n) #define check_register(base) do { \ int k = get_item_index(L, lua_gettop(L), base); \ if ((k>=0) && (k <= 65535)) { \ - lua_pushnumber(L,k); \ + lua_pushinteger(L,k); \ } else { \ lua_pushboolean(L,false); \ } \ @@ -303,14 +354,14 @@ void luacstring_close(int n) static const char *scan_integer_part(lua_State * L, const char *ss, int *ret, int *radix_ret) { boolean negative = false; /* should the answer be negated? */ - int m; /* |$2^{31}$ / radix|, the threshold of danger */ + int m = 214748364; /* |$2^{31}$ / radix|, the threshold of danger */ int d; /* the digit just scanned */ - boolean vacuous; /* have no digits appeared? */ - boolean OK_so_far; /* has an error message been issued? */ - int radix1 = 0; /* the radix of the integer */ + boolean vacuous = true; /* have no digits appeared? */ + boolean OK_so_far = true; /* has an error message been issued? */ + int radix1 = 10; /* the radix of the integer */ int c = 0; /* the current character */ const char *s; /* where we stopped in the string |ss| */ - integer val = 0; /* return value */ + integer val = 0; /* return value */ s = ss; do { do { @@ -321,10 +372,6 @@ static const char *scan_integer_part(lua_State * L, const char *ss, int *ret, in c = '+'; } } while (c == '+'); - - - radix1 = 10; - m = 214748364; if (c == '\'') { radix1 = 8; m = 02000000000; @@ -334,10 +381,6 @@ static const char *scan_integer_part(lua_State * L, const char *ss, int *ret, in m = 01000000000; c = *s++; } - vacuous = true; - val = 0; - OK_so_far = true; - /* Accumulate the constant until |cur_tok| is not a suitable digit */ while (1) { if ((c < '0' + radix1) && (c >= '0') && (c <= '0' + 9)) { @@ -411,7 +454,6 @@ static const char *scan_dimen_part(lua_State * L, const char *ss, int *ret) c = '+'; } } while (c == '+'); - if (c == ',') { c = '.'; } @@ -449,7 +491,6 @@ static const char *scan_dimen_part(lua_State * L, const char *ss, int *ret) negative = !negative; cur_val = -cur_val; } - /* Scan for (u)units that are internal dimensions; |goto attach_sign| with |cur_val| set if found */ save_cur_val = cur_val; @@ -478,7 +519,6 @@ static const char *scan_dimen_part(lua_State * L, const char *ss, int *ret) cur_val = nx_plus_y(save_cur_val, v, xn_over_d(v, f, 0200000)); goto ATTACH_SIGN; NOT_FOUND: - /* Scan for (m)\.{mu} units and |goto attach_fraction| */ if (strncmp(s, "mu", 2) == 0) { s += 2; @@ -487,12 +527,14 @@ static const char *scan_dimen_part(lua_State * L, const char *ss, int *ret) if (strncmp(s, "true", 4) == 0) { /* Adjust (f)for the magnification ratio */ s += 4; - prepare_mag(); - if (int_par(mag_code) != 1000) { - cur_val = xn_over_d(cur_val, 1000, int_par(mag_code)); - f = (1000 * f + 0200000 * tex_remainder) / int_par(mag_code); - cur_val = cur_val + (f / 0200000); - f = f % 0200000; + if (output_mode_used == OMODE_DVI) { + prepare_mag(); + if (int_par(mag_code) != 1000) { + cur_val = xn_over_d(cur_val, 1000, int_par(mag_code)); + f = (1000 * f + 0200000 * tex_remainder) / int_par(mag_code); + cur_val = cur_val + (f / 0200000); + f = f % 0200000; + } } do { c = *s++; @@ -505,37 +547,36 @@ static const char *scan_dimen_part(lua_State * L, const char *ss, int *ret) } /* Scan for (a)all other units and adjust |cur_val| and |f| accordingly; |goto done| in the case of scaled points */ - - if (strncmp(s, "in", 2) == 0) { + if (strncmp(s, "mm", 2) == 0) { s += 2; - set_conversion(7227, 100); - } else if (strncmp(s, "pc", 2) == 0) { - s += 2; - set_conversion(12, 1); + set_conversion(7227, 2540); } else if (strncmp(s, "cm", 2) == 0) { s += 2; set_conversion(7227, 254); - } else if (strncmp(s, "mm", 2) == 0) { + } else if (strncmp(s, "sp", 2) == 0) { s += 2; - set_conversion(7227, 2540); + goto DONE; } else if (strncmp(s, "bp", 2) == 0) { s += 2; set_conversion(7227, 7200); + } else if (strncmp(s, "in", 2) == 0) { + s += 2; + set_conversion(7227, 100); } else if (strncmp(s, "dd", 2) == 0) { s += 2; set_conversion(1238, 1157); } else if (strncmp(s, "cc", 2) == 0) { s += 2; set_conversion(14856, 1157); + } else if (strncmp(s, "pc", 2) == 0) { + s += 2; + set_conversion(12, 1); } else if (strncmp(s, "nd", 2) == 0) { s += 2; set_conversion(685, 642); } else if (strncmp(s, "nc", 2) == 0) { s += 2; set_conversion(1370, 107); - } else if (strncmp(s, "sp", 2) == 0) { - s += 2; - goto DONE; } else { /* Complain about unknown unit and |goto done2| */ luaL_error(L, "Illegal unit of measure (pt inserted)"); @@ -587,25 +628,25 @@ static int tex_scaledimen(lua_State * L) int sp; int t = lua_type(L, 1); if (t == LUA_TNUMBER) { - sp = (int) lua_tonumber(L, 1); + sp = lua_tointeger(L, 1); } else if (t == LUA_TSTRING) { sp = dimen_to_number(L, lua_tostring(L, 1)); } else { luaL_error(L, "argument must be a string or a number"); return 0; } - lua_pushnumber(L, sp); + lua_pushinteger(L, sp); return 1; } static int texerror (lua_State * L) { - int i, n, l; const char **errhlp = NULL; const char *error = luaL_checkstring(L,1); - n = lua_gettop(L); + int n = lua_gettop(L); if (n==2 && lua_type(L, n) == LUA_TTABLE) { - l = 1; /* |errhlp| is terminated by a NULL entry */ + int i; + int l = 1; /* |errhlp| is terminated by a NULL entry */ for (i = 1;; i++) { lua_rawgeti(L, n, i); if (lua_type(L,-1) == LUA_TSTRING) { @@ -654,7 +695,7 @@ static int get_item_index(lua_State * L, int i, int base) k = (equiv(cur_cs1) - base); break; case LUA_TNUMBER: - k = (int) luaL_checkinteger(L, i); + k = luaL_checkinteger(L, i); break; default: luaL_error(L, "argument must be a string or a number"); @@ -705,7 +746,7 @@ static int get_item_index(lua_State * L, int i, int base) } \ break; \ case LUA_TNUMBER: \ - key = (int) luaL_checkinteger(L, where); \ + key = luaL_checkinteger(L, where); \ if (key>=0 && key <= 65535) { \ err = set_register(key, value); \ if (err) { \ @@ -745,7 +786,7 @@ static int gettex(lua_State * L); } \ break; \ case LUA_TNUMBER: \ - key = (int) luaL_checkinteger(L, where); \ + key = luaL_checkinteger(L, where); \ if (key>=0 && key <= 65535) { \ value = get_register(key); \ } else { \ @@ -770,7 +811,7 @@ static int setdimen(lua_State * L) int t = lua_type(L, top); check_item_global(L,top,isglobal); if (t == LUA_TNUMBER) { - value = (int) lua_tonumber(L, top); + value = lua_tointeger(L, top); } else if (t == LUA_TSTRING) { value = dimen_to_number(L, lua_tostring(L, top)); } else { @@ -784,7 +825,7 @@ static int getdimen(lua_State * L) { int value = 0; get_item_index_plus(L, lua_gettop(L), scaled_base, "dimen", value, is_dim_assign, get_tex_dimen_register, false); - lua_pushnumber(L, value); + lua_pushinteger(L, value); return 1; } @@ -853,8 +894,8 @@ static int setcount(lua_State * L) int top = lua_gettop(L); check_item_global(L,top,isglobal); t = lua_type(L,top); - if (t == LUA_TNUMBER || t == LUA_TSTRING) { - value = (int) lua_tonumber(L, top); + if (t == LUA_TNUMBER) { + value = lua_tointeger(L, top); } else { luaL_error(L, "unsupported %s value type","count"); } @@ -866,7 +907,7 @@ static int getcount(lua_State * L) { int value = 0; get_item_index_plus(L, lua_gettop(L), count_base, "count", value, is_int_assign, get_tex_count_register, false); - lua_pushnumber(L, value); + lua_pushinteger(L, value); return 1; } @@ -885,8 +926,8 @@ static int setattribute(lua_State * L) int top = lua_gettop(L); check_item_global(L,top,isglobal); t = lua_type(L,top); - if (t == LUA_TNUMBER || t == LUA_TSTRING) { - value = (int) lua_tonumber(L, top); + if (t == LUA_TNUMBER) { + value = lua_tointeger(L, top); } else { luaL_error(L, "unsupported %s value type","attribute"); } @@ -898,7 +939,7 @@ static int getattribute(lua_State * L) { int value = 0; get_item_index_plus(L, lua_gettop(L), attribute_base, "attribute", value, is_attr_assign, get_tex_attribute_register, false); - lua_pushnumber(L, value); + lua_pushinteger(L, value); return 1; } @@ -972,7 +1013,7 @@ static int scantoks(lua_State * L) memcpy (s, ss, str.l+1); str.s = (unsigned char *)s; k = get_item_index(L, (i - 2), toks_base); - c = (int) luaL_checkinteger(L, i - 1); + c = luaL_checkinteger(L, i - 1); check_index_range(k, "settoks"); err = scan_tex_toks_register(k, c, str); xfree(str.s); @@ -985,10 +1026,9 @@ static int scantoks(lua_State * L) static int gettoks(lua_State * L) { - int k; - str_number t; char *ss; - k = get_item_index(L, lua_gettop(L), toks_base); + str_number t; + int k = get_item_index(L, lua_gettop(L), toks_base); check_index_range(k, "gettoks"); t = get_tex_toks_register(k); ss = makecstring(t); @@ -1005,31 +1045,31 @@ static int get_box_id(lua_State * L, int i, boolean report) size_t k = 0; int j = -1; switch (lua_type(L, i)) { - case LUA_TSTRING: - s = lua_tolstring(L, i, &k); - cur_cs1 = string_lookup(s, k); - cur_cmd1 = eq_type(cur_cs1); - if (cur_cmd1 == char_given_cmd || - cur_cmd1 == math_given_cmd) { - j = equiv(cur_cs1); - } - break; - case LUA_TNUMBER: - j=(int)lua_tonumber(L, (i)); - break; - default: - if (report) { - luaL_error(L, "argument must be a string or a number"); - } - j = -1; /* not a valid box id */ + case LUA_TSTRING: + s = lua_tolstring(L, i, &k); + cur_cs1 = string_lookup(s, k); + cur_cmd1 = eq_type(cur_cs1); + if (cur_cmd1 == char_given_cmd || + cur_cmd1 == math_given_cmd) { + j = equiv(cur_cs1); + } + break; + case LUA_TNUMBER: + j = lua_tointeger(L, (i)); + break; + default: + if (report) { + luaL_error(L, "argument must be a string or a number"); + } + j = -1; /* not a valid box id */ } return j; } static int getbox(lua_State * L) { - int k, t; - k = get_box_id(L, -1, true); + int t; + int k = get_box_id(L, -1, true); check_index_range(k, "getbox"); t = get_tex_box_register(k); nodelist_to_lua(L, t); @@ -1085,14 +1125,13 @@ static int setbox(lua_State * L) return vsetbox(L, isglobal); } -#define check_char_range(j,s,lim) \ - if (j<0 || j >= lim) { \ - luaL_error(L, "incorrect character value %d for tex.%s()", (int)j, s); \ +#define check_char_range(j,s,lim) \ + if (j<0 || j >= lim) { \ + luaL_error(L, "incorrect character value %d for tex.%s()", (int) j, s); \ } - static int setcode (lua_State *L, void (*setone)(int,halfword,quarterword), - void (*settwo)(int,halfword,quarterword), const char *name, int lim) + void (*settwo)(int,halfword,quarterword), const char *name, int lim) { int ch; halfword val, ucval; @@ -1100,7 +1139,7 @@ static int setcode (lua_State *L, void (*setone)(int,halfword,quarterword), int n = lua_gettop(L); int f = 1; if (n>1 && lua_type(L,1) == LUA_TTABLE) - f++; + f++; if (n>2 && (lua_type(L,f) == LUA_TSTRING)) { const char *s = lua_tostring(L, f); if (lua_key_eq(s,global)) { @@ -1108,13 +1147,13 @@ static int setcode (lua_State *L, void (*setone)(int,halfword,quarterword), f++; } } - ch = (int) luaL_checkinteger(L, f); + ch = luaL_checkinteger(L, f); check_char_range(ch, name, 65536*17); val = (halfword) luaL_checkinteger(L, f+1); check_char_range(val, name, lim); (setone)(ch, val, level); if (settwo != NULL && n-f == 2) { - ucval = (halfword) luaL_checkinteger(L, f+2); + ucval = (halfword) luaL_checkinteger(L, f+2); check_char_range(ucval, name, lim); (settwo)(ch, ucval, level); } @@ -1128,9 +1167,9 @@ static int setlccode(lua_State * L) static int getlccode(lua_State * L) { - int ch = (int) luaL_checkinteger(L, -1); + int ch = luaL_checkinteger(L, -1); check_char_range(ch, "getlccode", 65536*17); - lua_pushnumber(L, get_lc_code(ch)); + lua_pushinteger(L, get_lc_code(ch)); return 1; } @@ -1141,9 +1180,9 @@ static int setuccode(lua_State * L) static int getuccode(lua_State * L) { - int ch = (int) luaL_checkinteger(L, -1); + int ch = luaL_checkinteger(L, -1); check_char_range(ch, "getuccode", 65536*17); - lua_pushnumber(L, get_uc_code(ch)); + lua_pushinteger(L, get_uc_code(ch)); return 1; } @@ -1154,9 +1193,9 @@ static int setsfcode(lua_State * L) static int getsfcode(lua_State * L) { - int ch = (int) luaL_checkinteger(L, -1); + int ch = luaL_checkinteger(L, -1); check_char_range(ch, "getsfcode", 65536*17); - lua_pushnumber(L, get_sf_code(ch)); + lua_pushinteger(L, get_sf_code(ch)); return 1; } @@ -1178,9 +1217,9 @@ static int setcatcode(lua_State * L) } } if (n-f == 2) { - cattable = (int) luaL_checkinteger(L, -3); + cattable = luaL_checkinteger(L, -3); } - ch = (int) luaL_checkinteger(L, -2); + ch = luaL_checkinteger(L, -2); check_char_range(ch, "setcatcode", 65536*17); val = (halfword) luaL_checkinteger(L, -1); check_char_range(val, "setcatcode", 16); @@ -1191,12 +1230,12 @@ static int setcatcode(lua_State * L) static int getcatcode(lua_State * L) { int cattable = int_par(cat_code_table_code); - int ch = (int) luaL_checkinteger(L, -1); + int ch = luaL_checkinteger(L, -1); if (lua_gettop(L)>=2 && lua_type(L,-2)==LUA_TNUMBER) { cattable = luaL_checkinteger(L, -2); } check_char_range(ch, "getcatcode", 65536*17); - lua_pushnumber(L, get_cat_code(cattable, ch)); + lua_pushinteger(L, get_cat_code(cattable, ch)); return 1; } @@ -1220,7 +1259,7 @@ static int setmathcode(lua_State * L) if (n-f!=1 || lua_type(L,f+1) != LUA_TTABLE) { luaL_error(L, "Bad arguments for tex.setmathcode()"); } - ch = (int) luaL_checkinteger(L, -2); + ch = luaL_checkinteger(L, -2); check_char_range(ch, "setmathcode", 65536*17); lua_rawgeti(L, -1, 1); @@ -1234,35 +1273,35 @@ static int setmathcode(lua_State * L) check_char_range(cval, "setmathcode", 8); check_char_range(fval, "setmathcode", 256); check_char_range(chval, "setmathcode", 65536*17); - set_math_code(ch, umath_mathcode, cval,fval, chval, (quarterword) (level)); + set_math_code(ch, cval,fval, chval, (quarterword) (level)); return 0; } static int getmathcode(lua_State * L) { - mathcodeval mval = { 0, 0, 0, 0 }; - int ch = (int) luaL_checkinteger(L, -1); + mathcodeval mval = { 0, 0, 0 }; + int ch = luaL_checkinteger(L, -1); check_char_range(ch, "getmathcode", 65536*17); mval = get_math_code(ch); lua_newtable(L); - lua_pushnumber(L,mval.class_value); + lua_pushinteger(L,mval.class_value); lua_rawseti(L, -2, 1); - lua_pushnumber(L,mval.family_value); + lua_pushinteger(L,mval.family_value); lua_rawseti(L, -2, 2); - lua_pushnumber(L,mval.character_value); + lua_pushinteger(L,mval.character_value); lua_rawseti(L, -2, 3); return 1; } static int getmathcodes(lua_State * L) { - mathcodeval mval = { 0, 0, 0, 0 }; - int ch = (int) luaL_checkinteger(L, -1); + mathcodeval mval = { 0, 0, 0 }; + int ch = luaL_checkinteger(L, -1); check_char_range(ch, "getmathcodes", 65536*17); mval = get_math_code(ch); - lua_pushnumber(L,mval.class_value); - lua_pushnumber(L,mval.family_value); - lua_pushnumber(L,mval.character_value); + lua_pushinteger(L,mval.class_value); + lua_pushinteger(L,mval.family_value); + lua_pushinteger(L,mval.character_value); return 3; } @@ -1285,7 +1324,7 @@ static int setdelcode(lua_State * L) if (n-f!=1 || lua_type(L,f+1) != LUA_TTABLE) { luaL_error(L, "Bad arguments for tex.setdelcode()"); } - ch = (int) luaL_checkinteger(L, -2); + ch = luaL_checkinteger(L, -2); check_char_range(ch, "setdelcode", 65536*17); lua_rawgeti(L, -1, 1); sfval = (halfword) luaL_checkinteger(L, -1); @@ -1301,59 +1340,56 @@ static int setdelcode(lua_State * L) check_char_range(scval, "setdelcode", 65536*17); check_char_range(lfval, "setdelcode", 256); check_char_range(lcval, "setdelcode", 65536*17); - set_del_code(ch, umath_mathcode, sfval, scval, lfval, lcval, (quarterword) (level)); + set_del_code(ch, sfval, scval, lfval, lcval, (quarterword) (level)); return 0; } static int getdelcode(lua_State * L) { - delcodeval mval = { 0, 0, 0, 0, 0, 0 }; - int ch = (int) luaL_checkinteger(L, -1); + delcodeval mval = { 0, 0, 0, 0, 0 }; + int ch = luaL_checkinteger(L, -1); check_char_range(ch, "getdelcode", 65536*17); mval = get_del_code(ch); - /* lua_pushnumber(L, mval.class_value); */ - /* lua_pushnumber(L, mval.origin_value); */ lua_newtable(L); - lua_pushnumber(L,mval.small_family_value); + lua_pushinteger(L,mval.small_family_value); lua_rawseti(L, -2, 1); - lua_pushnumber(L,mval.small_character_value); + lua_pushinteger(L,mval.small_character_value); lua_rawseti(L, -2, 2); - lua_pushnumber(L,mval.large_family_value); + lua_pushinteger(L,mval.large_family_value); lua_rawseti(L, -2, 3); - lua_pushnumber(L,mval.large_character_value); + lua_pushinteger(L,mval.large_character_value); lua_rawseti(L, -2, 4); return 1; } static int getdelcodes(lua_State * L) { - delcodeval mval = { 0, 0, 0, 0, 0, 0 }; - int ch = (int) luaL_checkinteger(L, -1); + delcodeval mval = { 0, 0, 0, 0, 0 }; + int ch = luaL_checkinteger(L, -1); check_char_range(ch, "getdelcodes", 65536*17); mval = get_del_code(ch); - lua_pushnumber(L,mval.small_family_value); - lua_pushnumber(L,mval.small_character_value); - lua_pushnumber(L,mval.large_family_value); - lua_pushnumber(L,mval.large_character_value); + lua_pushinteger(L,mval.small_family_value); + lua_pushinteger(L,mval.small_character_value); + lua_pushinteger(L,mval.large_family_value); + lua_pushinteger(L,mval.large_character_value); return 4; } static int settex(lua_State * L) { const char *st; - int i, j, texstr; + int texstr; size_t k; int cur_cs1, cur_cmd1; int isglobal = 0; - j = 0; - i = lua_gettop(L); + int j = 0; + int i = lua_gettop(L); if (lua_type(L,i-1) == LUA_TSTRING) { st = lua_tolstring(L, (i - 1), &k); - if (lua_key_eq(st,prevdepth)) { if (lua_type(L, i) == LUA_TNUMBER) { - cur_list.prev_depth_field = lua_tonumber(L, i); + cur_list.prev_depth_field = lua_tointeger(L, i); } else if (lua_type(L, i) == LUA_TSTRING) { cur_list.prev_depth_field = dimen_to_number(L, lua_tostring(L, i)); } else { @@ -1361,22 +1397,20 @@ static int settex(lua_State * L) } return 0; } else if (lua_key_eq(st,prevgraf)) { - if (lua_type(L, i) != LUA_TNUMBER) { - cur_list.pg_field = lua_tonumber(L, i); + if (lua_type(L, i) == LUA_TNUMBER) { + cur_list.pg_field = lua_tointeger(L, i); } else { luaL_error(L, "unsupported value type"); } return 0; } else if (lua_key_eq(st,spacefactor)) { - if (lua_type(L, i) != LUA_TNUMBER) { - cur_list.space_factor_field = lua_tonumber(L, i); + if (lua_type(L, i) == LUA_TNUMBER) { + cur_list.space_factor_field = lua_tointeger(L, i); } else { luaL_error(L, "unsupported value type"); } return 0; } - - texstr = maketexlstring(st, k); if (is_primitive(texstr)) { if (i == 3 && (lua_type(L,1) == LUA_TSTRING)) { @@ -1389,16 +1423,14 @@ static int settex(lua_State * L) cur_cmd1 = eq_type(cur_cs1); if (is_int_assign(cur_cmd1)) { if (lua_type(L, i) == LUA_TNUMBER) { - int luai; - luai=(int)lua_tonumber(L, i); - assign_internal_value((isglobal ? 4 : 0), - equiv(cur_cs1), luai); + int luai = lua_tointeger(L, i); + assign_internal_value((isglobal ? 4 : 0), equiv(cur_cs1), luai); } else { luaL_error(L, "unsupported value type"); } } else if (is_dim_assign(cur_cmd1)) { if (lua_type(L, i) == LUA_TNUMBER) { - j=(int)lua_tonumber(L, i); + j = lua_tointeger(L, i); } else if (lua_type(L, i) == LUA_TSTRING) { j = dimen_to_number(L, lua_tostring(L, i)); } else { @@ -1452,6 +1484,7 @@ static int do_convert(lua_State * L, int cur_code) case left_margin_kern_code: /* arg box */ case right_margin_kern_code: /* arg box */ case string_code: /* arg token */ + case cs_string_code: /* arg token */ case meaning_code: /* arg token */ break; @@ -1466,7 +1499,7 @@ static int do_convert(lua_State * L, int cur_code) if (lua_gettop(L) < 1) { /* error */ } - i=(int)lua_tonumber(L, 1); + i = lua_tointeger(L, 1); /* these fall through! */ @@ -1502,7 +1535,7 @@ static int do_scan_internal(lua_State * L, int cur_cmd1, int cur_code) case int_val_level: case dimen_val_level: case attr_val_level: - lua_pushnumber(L, cur_val); + lua_pushinteger(L, cur_val); break; case glue_val_level: case mu_val_level: @@ -1596,11 +1629,9 @@ static int tex_setmathparm(lua_State * L) { int i, j; int k; - int n; int l = cur_level; void *p; - n = lua_gettop(L); - + int n = lua_gettop(L); if ((n == 3) || (n == 4)) { if (n == 4 && (lua_type(L,1) == LUA_TSTRING)) { const char *s = lua_tostring(L, 1); @@ -1615,11 +1646,11 @@ static int tex_setmathparm(lua_State * L) p = lua_touserdata(L, n); k = *((halfword *)p); def_math_param(i, j, (scaled) k, l); - } else { - if (lua_type(L, n) == LUA_TNUMBER) - luaL_error(L, "argument must be a number"); - k=(int)lua_tonumber(L, n); + } else if (lua_type(L, n) == LUA_TNUMBER) { + k = lua_tointeger(L, n); def_math_param(i, j, (scaled) k, l); + } else { + luaL_error(L, "argument must be a number"); } } return 0; @@ -1627,12 +1658,10 @@ static int tex_setmathparm(lua_State * L) 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); + int i = luaL_checkoption(L, 1, NULL, math_param_names); + int j = luaL_checkoption(L, 2, NULL, math_style_names); + scaled k = get_math_param(i, j); if (i<0 && i>=math_param_last) { lua_pushnil(L); } else if (i>=math_param_first_mu_glue) { @@ -1641,7 +1670,7 @@ static int tex_getmathparm(lua_State * L) } lua_nodelib_push_fast(L, k); } else { - lua_pushnumber(L, k); + lua_pushinteger(L, k); } } return 1; @@ -1674,17 +1703,16 @@ static int getromannumeral(lua_State * L) static int get_parshape(lua_State * L) { - int n; halfword par_shape_ptr = equiv(par_shape_loc); if (par_shape_ptr != 0) { int m = 1; - n = vinfo(par_shape_ptr + 1); + int n = vinfo(par_shape_ptr + 1); lua_createtable(L, n, 0); while (m <= n) { lua_createtable(L, 2, 0); - lua_pushnumber(L, vlink((par_shape_ptr) + (2 * (m - 1)) + 2)); + lua_pushinteger(L, vlink((par_shape_ptr) + (2 * (m - 1)) + 2)); lua_rawseti(L, -2, 1); - lua_pushnumber(L, vlink((par_shape_ptr) + (2 * (m - 1)) + 3)); + lua_pushinteger(L, vlink((par_shape_ptr) + (2 * (m - 1)) + 3)); lua_rawseti(L, -2, 2); lua_rawseti(L, -2, m); m++; @@ -1704,54 +1732,51 @@ static int gettex(lua_State * L) int texstr; size_t k; const char *st = lua_tolstring(L, t, &k); - if (lua_key_eq(st,prevdepth)) { - lua_pushnumber(L, cur_list.prev_depth_field); + lua_pushinteger(L, cur_list.prev_depth_field); return 1; } else if (lua_key_eq(st,prevgraf)) { - lua_pushnumber(L, cur_list.pg_field); + lua_pushinteger(L, cur_list.pg_field); return 1; } else if (lua_key_eq(st,spacefactor)) { - lua_pushnumber(L, cur_list.space_factor_field); + lua_pushinteger(L, cur_list.space_factor_field); return 1; } - texstr = maketexlstring(st, k); cur_cs1 = prim_lookup(texstr); /* not found == relax == 0 */ flush_str(texstr); } if (cur_cs1 > 0) { - int cur_cmd1, cur_code; - cur_cmd1 = get_prim_eq_type(cur_cs1); - cur_code = get_prim_equiv(cur_cs1); + int cur_cmd1 = get_prim_eq_type(cur_cs1); + int cur_code = get_prim_equiv(cur_cs1); switch (cur_cmd1) { - case last_item_cmd: - retval = do_lastitem(L, cur_code); - break; - case convert_cmd: - retval = do_convert(L, cur_code); - break; - case assign_toks_cmd: - case assign_int_cmd: - case assign_attr_cmd: - case assign_dir_cmd: - case assign_dimen_cmd: - case assign_glue_cmd: - case assign_mu_glue_cmd: - case set_aux_cmd: - case set_prev_graf_cmd: - case set_page_int_cmd: - case set_page_dimen_cmd: - case char_given_cmd: - case math_given_cmd: - retval = do_scan_internal(L, cur_cmd1, cur_code); - break; - case set_tex_shape_cmd: - retval = get_parshape(L); - break; - default: - lua_pushnil(L); - break; + case last_item_cmd: + retval = do_lastitem(L, cur_code); + break; + case convert_cmd: + retval = do_convert(L, cur_code); + break; + case assign_toks_cmd: + case assign_int_cmd: + case assign_attr_cmd: + case assign_dir_cmd: + case assign_dimen_cmd: + case assign_glue_cmd: + case assign_mu_glue_cmd: + case set_aux_cmd: + case set_prev_graf_cmd: + case set_page_int_cmd: + case set_page_dimen_cmd: + case char_given_cmd: + case math_given_cmd: + retval = do_scan_internal(L, cur_cmd1, cur_code); + break; + case set_tex_shape_cmd: + retval = get_parshape(L); + break; + default: + lua_pushnil(L); + break; } } else if (t == 2) { lua_rawget(L, 1); @@ -1766,44 +1791,44 @@ static int getlist(lua_State * L) str = lua_tostring(L, 2); if (lua_key_eq(str,page_ins_head)) { if (vlink(page_ins_head) == page_ins_head) - lua_pushnumber(L, null); + lua_pushinteger(L, null); else - lua_pushnumber(L, vlink(page_ins_head)); + lua_pushinteger(L, vlink(page_ins_head)); lua_nodelib_push(L); } else if (lua_key_eq(str,contrib_head)) { alink(vlink(contrib_head)) = null ; - lua_pushnumber(L, vlink(contrib_head)); + lua_pushinteger(L, vlink(contrib_head)); lua_nodelib_push(L); } else if (lua_key_eq(str,page_head)) { alink(vlink(page_head)) = null ;/*hh-ls */ - lua_pushnumber(L, vlink(page_head)); + lua_pushinteger(L, vlink(page_head)); lua_nodelib_push(L); } else if (lua_key_eq(str,temp_head)) { alink(vlink(temp_head)) = null ;/*hh-ls */ - lua_pushnumber(L, vlink(temp_head)); + lua_pushinteger(L, vlink(temp_head)); lua_nodelib_push(L); } else if (lua_key_eq(str,hold_head)) { alink(vlink(hold_head)) = null ;/*hh-ls */ - lua_pushnumber(L, vlink(hold_head)); + lua_pushinteger(L, vlink(hold_head)); lua_nodelib_push(L); } else if (lua_key_eq(str,adjust_head)) { alink(vlink(adjust_head)) = null ;/*hh-ls */ - lua_pushnumber(L, vlink(adjust_head)); + lua_pushinteger(L, vlink(adjust_head)); lua_nodelib_push(L); } else if (lua_key_eq(str,best_page_break)) { - lua_pushnumber(L, best_page_break); + lua_pushinteger(L, best_page_break); lua_nodelib_push(L); } else if (lua_key_eq(str,least_page_cost)) { - lua_pushnumber(L, least_page_cost); + lua_pushinteger(L, least_page_cost); } else if (lua_key_eq(str,best_size)) { - lua_pushnumber(L, best_size); + lua_pushinteger(L, best_size); } else if (lua_key_eq(str,pre_adjust_head)) { alink(vlink(pre_adjust_head)) = null ;/*hh-ls */ - lua_pushnumber(L, vlink(pre_adjust_head)); + lua_pushinteger(L, vlink(pre_adjust_head)); lua_nodelib_push(L); } else if (lua_key_eq(str,align_head)) { alink(vlink(align_head)) = null ;/*hh-ls */ - lua_pushnumber(L, vlink(align_head)); + lua_pushinteger(L, vlink(align_head)); lua_nodelib_push(L); } else { lua_pushnil(L); @@ -1816,16 +1841,15 @@ static int getlist(lua_State * L) static int setlist(lua_State * L) { - halfword *n_ptr; - const char *str; - halfword n = 0; if (lua_type(L,2) == LUA_TSTRING) { - str = lua_tostring(L, 2); + const char *str = lua_tostring(L, 2); if (lua_key_eq(str,best_size)) { best_size = (int) lua_tointeger(L, 3); } else if (lua_key_eq(str,least_page_cost)) { least_page_cost = (int) lua_tointeger(L, 3); } else { + halfword *n_ptr; + halfword n = 0; if (!lua_isnil(L, 3)) { n_ptr = check_isnode(L, 3); n = *n_ptr; @@ -1875,32 +1899,32 @@ static int lua_nest_getfield(lua_State * L) const char *field = lua_tostring(L, -1); r = *rv; if (lua_key_eq(field,mode)) { - lua_pushnumber(L, r->mode_field); + lua_pushinteger(L, r->mode_field); } else if (lua_key_eq(field,head)) { lua_nodelib_push_fast(L, r->head_field); } else if (lua_key_eq(field,tail)) { lua_nodelib_push_fast(L, r->tail_field); } else if (lua_key_eq(field,delimptr)) { - lua_pushnumber(L, r->eTeX_aux_field); + lua_pushinteger(L, r->eTeX_aux_field); lua_nodelib_push(L); } else if (lua_key_eq(field,prevgraf)) { - lua_pushnumber(L, r->pg_field); + lua_pushinteger(L, r->pg_field); } else if (lua_key_eq(field,modeline)) { - lua_pushnumber(L, r->ml_field); + lua_pushinteger(L, r->ml_field); } else if (lua_key_eq(field,prevdepth)) { - lua_pushnumber(L, r->prev_depth_field); + lua_pushinteger(L, r->prev_depth_field); } else if (lua_key_eq(field,spacefactor)) { - lua_pushnumber(L, r->space_factor_field); + lua_pushinteger(L, r->space_factor_field); } else if (lua_key_eq(field,noad)) { - lua_pushnumber(L, r->incompleat_noad_field); + lua_pushinteger(L, r->incompleat_noad_field); lua_nodelib_push(L); } else if (lua_key_eq(field,dirs)) { - lua_pushnumber(L, r->dirs_field); + lua_pushinteger(L, r->dirs_field); lua_nodelib_push(L); } else if (lua_key_eq(field,mathdir)) { lua_pushboolean(L, r->math_field); } else if (lua_key_eq(field,mathstyle)) { - lua_pushnumber(L, r->math_style_field); + lua_pushinteger(L, r->math_style_field); } else { lua_pushnil(L); } @@ -1915,7 +1939,7 @@ static int lua_nest_setfield(lua_State * L) const char *field = lua_tostring(L, -2); r = *rv; if (lua_key_eq(field,mode)) { - i=(int)lua_tonumber(L, -1); + i = lua_tointeger(L, -1); r->mode_field = i; } else if (lua_key_eq(field,head)) { n = check_isnode(L, -1); @@ -1927,16 +1951,16 @@ static int lua_nest_setfield(lua_State * L) n = check_isnode(L, -1); r->eTeX_aux_field = *n; } else if (lua_key_eq(field,prevgraf)) { - i=(int)lua_tonumber(L, -1); + i = lua_tointeger(L, -1); r->pg_field = i; } else if (lua_key_eq(field,modeline)) { - i=(int)lua_tonumber(L, -1); + i = lua_tointeger(L, -1); r->ml_field = i; } else if (lua_key_eq(field,prevdepth)) { - i=(int)lua_tonumber(L, -1); + i = lua_tointeger(L, -1); r->prev_depth_field = i; } else if (lua_key_eq(field,spacefactor)) { - i=(int)lua_tonumber(L, -1); + i = lua_tointeger(L, -1); r->space_factor_field = i; } else if (lua_key_eq(field,noad)) { n = check_isnode(L, -1); @@ -1947,7 +1971,7 @@ static int lua_nest_setfield(lua_State * L) } else if (lua_key_eq(field,mathdir)) { r->math_field = lua_toboolean(L, -1); } else if (lua_key_eq(field,mathstyle)) { - i=(int)lua_tonumber(L, -1); + i = lua_tointeger(L, -1); r->math_style_field = i; } return 0; @@ -1968,11 +1992,10 @@ static void init_nest_lib(lua_State * L) static int getnest(lua_State * L) { - int ptr; list_state_record **nestitem; int t = lua_type(L, 2); if (t == LUA_TNUMBER) { - ptr=(int)lua_tonumber(L, 2); + int ptr = lua_tointeger(L, 2); if (ptr >= 0 && ptr <= nest_ptr) { nestitem = lua_newuserdata(L, sizeof(list_state_record *)); *nestitem = &nest[ptr]; @@ -1984,7 +2007,7 @@ static int getnest(lua_State * L) } else if (t == LUA_TSTRING) { const char *s = lua_tostring(L, 2); if (lua_key_eq(s,ptr)) { - lua_pushnumber(L, nest_ptr); + lua_pushinteger(L, nest_ptr); } else { lua_pushnil(L); } @@ -2013,11 +2036,11 @@ static int do_integer_error(double m) static int tex_roundnumber(lua_State * L) { - double m = (double) lua_tonumber(L, 1) + 0.5; + double m = (double) lua_tonumber(L, 1) + 0.5; /* integer or float */ if (abs(m) > (double) infinity) - lua_pushnumber(L, do_integer_error(m)); + lua_pushinteger(L, do_integer_error(m)); else - lua_pushnumber(L, floor(m)); + lua_pushinteger(L, floor(m)); return 1; } @@ -2031,21 +2054,21 @@ static int tex_scaletable(lua_State * L) lua_pushvalue(L, -2); lua_insert(L, -2); if (lua_type(L,-2) == LUA_TNUMBER) { - double m = (double) lua_tonumber(L, -1) * delta + 0.5; + double m = (double) lua_tonumber(L, -1) * delta + 0.5; /* integer or float */ lua_pop(L, 1); if (abs(m) > (double) infinity) - lua_pushnumber(L, do_integer_error(m)); + lua_pushinteger(L, do_integer_error(m)); else - lua_pushnumber(L, floor(m)); + lua_pushinteger(L, floor(m)); } lua_rawset(L, 3); } } else if (lua_type(L,1) == LUA_TNUMBER) { - double m = (double) lua_tonumber(L, 1) * delta + 0.5; + double m = (double) lua_tonumber(L, 1) * delta + 0.5; /* integer or float */ if (abs(m) > (double) infinity) - lua_pushnumber(L, do_integer_error(m)); + lua_pushinteger(L, do_integer_error(m)); else - lua_pushnumber(L, floor(m)); + lua_pushinteger(L, floor(m)); } else { lua_pushnil(L); } @@ -2071,7 +2094,7 @@ static int tex_definefont(lua_State * L) i = 2; } csname = luaL_checklstring(L, i, &l); - f = (int) luaL_checkinteger(L, (i + 1)); + f = luaL_checkinteger(L, (i + 1)); t = maketexlstring(csname, l); no_new_control_sequence = 0; u = string_lookup(csname, l); @@ -2136,10 +2159,7 @@ static int tex_extraprimitives(lua_State * L) int cs = 0; n = lua_gettop(L); if (n == 0) { - mask = etex_command - + pdftex_command /* obsolete */ - + umath_command /* obsolete */ - + luatex_command; + mask = etex_command + luatex_command; } else { for (i = 1; i <= n; i++) { if (lua_type(L,i) == LUA_TSTRING) { @@ -2150,13 +2170,8 @@ static int tex_extraprimitives(lua_State * L) mask |= tex_command; } else if (lua_key_eq(s,core)) { mask |= core_command; - } else if (lua_key_eq(s,pdftex)) { /* obsolete */ - mask |= pdftex_command; } else if (lua_key_eq(s,luatex)) { - mask |= luatex_command - | umath_command; /* obsolete */ - } else if (lua_key_eq(s,umath)) { /* obsolete */ - mask |= umath_command; + mask |= luatex_command; } } } @@ -2238,57 +2253,55 @@ static int tex_enableprimitives(lua_State * L) return 0; } -#define get_int_par(A,B,C) do { \ - lua_pushstring(L,(A)); \ - lua_gettable(L,-2); \ - if (lua_type(L, -1) == LUA_TNUMBER) { \ - B=(int)lua_tonumber(L, -1); \ - } else { \ - B = (C); \ - } \ - lua_pop(L,1); \ - } while (0) - - -#define get_intx_par(A,B,C,D,E) do { \ - lua_pushstring(L,(A)); \ - lua_gettable(L,-2); \ - if (lua_type(L, -1) == LUA_TNUMBER) { \ - B=(int)lua_tonumber(L, -1); \ - D = null; \ - } else if (lua_type(L, -1) == LUA_TTABLE){ \ - B = 0; \ - D = nodelib_topenalties(L, lua_gettop(L)); \ - } else { \ - B = (C); \ - D = (E); \ - } \ - lua_pop(L,1); \ - } while (0) - -#define get_dimen_par(A,B,C) do { \ +#define get_int_par(A,B,C) do { \ lua_pushstring(L,(A)); \ - lua_gettable(L,-2); \ - if (lua_type(L, -1) == LUA_TNUMBER) { \ - B=(int)lua_tonumber(L, -1); \ - } else { \ - B = (C); \ - } \ - lua_pop(L,1); \ - } while (0) - + lua_gettable(L,-2); \ + if (lua_type(L, -1) == LUA_TNUMBER) { \ + B = (int) lua_tointeger(L, -1); \ + } else { \ + B = (C); \ + } \ + lua_pop(L,1); \ +} while (0) + + +#define get_intx_par(A,B,C,D,E) do { \ + lua_pushstring(L,(A)); \ + lua_gettable(L,-2); \ + if (lua_type(L, -1) == LUA_TNUMBER) { \ + B = (int) lua_tointeger(L, -1); \ + D = null; \ + } else if (lua_type(L, -1) == LUA_TTABLE){ \ + B = 0; \ + D = nodelib_topenalties(L, lua_gettop(L)); \ + } else { \ + B = (C); \ + D = (E); \ + } \ + lua_pop(L,1); \ +} while (0) + +#define get_dimen_par(A,B,C) do { \ + lua_pushstring(L,(A)); \ + lua_gettable(L,-2); \ + if (lua_type(L, -1) == LUA_TNUMBER) { \ + B = (int) lua_tointeger(L, -1); \ + } else { \ + B = (C); \ + } \ + lua_pop(L,1); \ +} while (0) #define get_glue_par(A,B,C) do { \ - lua_pushstring(L,(A)); \ - lua_gettable(L,-2); \ - if (lua_type(L, -1) != LUA_TNIL) { \ - B = *check_isnode(L, -1); \ - } else { \ - B = (C); \ - } \ - lua_pop(L,1); \ - } while (0) - + lua_pushstring(L,(A)); \ + lua_gettable(L,-2); \ + if (lua_type(L, -1) != LUA_TNIL) { \ + B = *check_isnode(L, -1); \ + } else { \ + B = (C); \ + } \ + lua_pop(L,1); \ +} while (0) static halfword nodelib_toparshape(lua_State * L, int i) { @@ -2314,11 +2327,11 @@ static halfword nodelib_toparshape(lua_State * L, int i) if (lua_type(L, i) == LUA_TTABLE) { lua_rawgeti(L, -1, 1); /* indent */ if (lua_type(L, -1) == LUA_TNUMBER) { - indent=(int)lua_tonumber(L, -1); + indent = lua_tointeger(L, -1); lua_pop(L, 1); lua_rawgeti(L, -1, 2); /* width */ if (lua_type(L, -1) == LUA_TNUMBER) { - width=(int)lua_tonumber(L, -1); + width = lua_tointeger(L, -1); lua_pop(L, 1); varmem[p + 2 * j].cint = indent; varmem[p + 2 * j + 1].cint = width; @@ -2351,16 +2364,15 @@ static halfword nodelib_topenalties(lua_State * L, int i) lua_pushnil(L); j = 2; while (lua_next(L, i) != 0) { - j++; - if (lua_type(L, -1) == LUA_TNUMBER) { - int pen = 0; - pen=(int)lua_tonumber(L, -1); - varmem[p+j].cint = pen; - } - lua_pop(L, 1); + j++; + if (lua_type(L, -1) == LUA_TNUMBER) { + int pen = lua_tointeger(L, -1); + varmem[p+j].cint = pen; + } + lua_pop(L, 1); } if (!odd(n)) - varmem[p+j+1].cint = 0; + varmem[p+j+1].cint = 0; return p; } @@ -2481,16 +2493,16 @@ static int tex_run_linebreak(lua_State * L) lua_nodelib_push_fast(L, vlink(cur_list.head_field)); lua_newtable(L); lua_pushstring(L, "demerits"); - lua_pushnumber(L, fewest_demerits); + lua_pushinteger(L, fewest_demerits); lua_settable(L, -3); lua_pushstring(L, "looseness"); - lua_pushnumber(L, actual_looseness); + lua_pushinteger(L, actual_looseness); lua_settable(L, -3); lua_pushstring(L, "prevdepth"); - lua_pushnumber(L, cur_list.prev_depth_field); + lua_pushinteger(L, cur_list.prev_depth_field); lua_settable(L, -3); lua_pushstring(L, "prevgraf"); - lua_pushnumber(L, cur_list.pg_field); + lua_pushinteger(L, cur_list.pg_field); lua_settable(L, -3); /* restore nest stack */ @@ -2511,10 +2523,9 @@ static int tex_shipout(lua_State * L) static int tex_badness(lua_State * L) { - scaled t,s; - t=(int)lua_tonumber(L,1); - s=(int)lua_tonumber(L,2); - lua_pushnumber(L, badness(t,s)); + scaled t = lua_tointeger(L,1); + scaled s = lua_tointeger(L,2); + lua_pushinteger(L, badness(t,s)); return 1; } @@ -2574,7 +2585,7 @@ static int tex_init_rand(lua_State * L) luaL_error(L, "argument must be a number"); return 0; } - sp=(int)lua_tonumber(L, 1); + sp = lua_tointeger(L, 1); init_randoms(sp); return 0; } @@ -2586,14 +2597,14 @@ static int tex_unif_rand(lua_State * L) luaL_error(L, "argument must be a number"); return 0; } - sp=(int)lua_tonumber(L, 1); - lua_pushnumber(L, unif_rand(sp)); + sp = lua_tointeger(L, 1); + lua_pushinteger(L, unif_rand(sp)); return 1; } static int tex_norm_rand(lua_State * L) { - lua_pushnumber(L, norm_rand()); + lua_pushinteger(L, norm_rand()); return 1; } @@ -2607,20 +2618,20 @@ static int tex_norm_rand(lua_State * L) r = r / rand_max; switch (lua_gettop(L)) { /* check number of arguments */ case 0: { /* no arguments */ - lua_pushnumber(L, r); /* Number between 0 and 1 */ + lua_pushnumber(L, r); /* float: [0, 1] */ break; } case 1: { /* only upper limit */ lua_Number u = luaL_checknumber(L, 1); luaL_argcheck(L, (lua_Number)1.0 <= u, 1, "interval is empty"); - lua_pushnumber(L, floor(r*u) + (lua_Number)(1.0)); /* [1, u] */ + lua_pushnumber(L, floor(r*u) + (lua_Number)(1.0)); /* float: [1, u] */ break; } case 2: { /* lower and upper limits */ lua_Number l = luaL_checknumber(L, 1); lua_Number u = luaL_checknumber(L, 2); luaL_argcheck(L, l <= u, 2, "interval is empty"); - lua_pushnumber(L, floor(r*(u-l+1)) + l); /* [l, u] */ + lua_pushnumber(L, floor(r*(u-l+1)) + l); /* float: [l, u] */ break; } default: @@ -2654,10 +2665,10 @@ static int tex_show_context(lua_State * L) static int tex_save_box_resource(lua_State * L) { - halfword boxnumber, boxdata; + halfword boxdata; int index, attributes, resources; /* box attributes resources */ - boxnumber = (halfword) lua_tonumber(L,1); + halfword boxnumber = lua_tointeger(L,1); if (lua_type(L,2) == LUA_TSTRING) { lua_pushvalue(L, 2); attributes = luaL_ref(L, LUA_REGISTRYINDEX); @@ -2687,7 +2698,7 @@ static int tex_save_box_resource(lua_State * L) set_obj_xform_depth(static_pdf, index, depth(boxdata)); box(boxnumber) = null; last_saved_box_index = index; - lua_pushnumber(L, index); + lua_pushinteger(L, index); return 1; } @@ -2702,18 +2713,18 @@ static int tex_use_box_resource(lua_State * L) lua_pushnil(L); lua_pushnil(L); } else { - index = lua_tonumber(L,1); + index = lua_tointeger(L,1); alt.wd = null_flag; alt.ht = null_flag; alt.dp = null_flag; if (lua_type(L,2) == LUA_TNUMBER) { - alt.wd = (scaled) lua_tonumber(L,2); + alt.wd = (scaled) lua_tointeger(L,2); } if (lua_type(L,3) == LUA_TNUMBER) { - alt.ht = (scaled) lua_tonumber(L,3); + alt.ht = (scaled) lua_tointeger(L,3); } if (lua_type(L,4) == LUA_TNUMBER) { - alt.dp = (scaled) lua_tonumber(L,4); + alt.dp = (scaled) lua_tointeger(L,4); } /* sort of the same as backend */ check_obj_type(static_pdf, obj_type_xform, index); @@ -2731,9 +2742,9 @@ static int tex_use_box_resource(lua_State * L) height(rule) = dim.ht; depth(rule) = dim.dp; nodelist_to_lua(L, rule); - lua_pushnumber(L, (int) dim.wd); - lua_pushnumber(L, (int) dim.ht); - lua_pushnumber(L, (int) dim.dp); + lua_pushinteger(L, (int) dim.wd); + lua_pushinteger(L, (int) dim.ht); + lua_pushinteger(L, (int) dim.dp); } return 4; } @@ -2746,11 +2757,11 @@ static int tex_get_box_resource_dimensions(lua_State * L) lua_pushnil(L); lua_pushnil(L); } else { - index = lua_tonumber(L,1); + index = lua_tointeger(L,1); check_obj_type(static_pdf, obj_type_xform, index); - lua_pushnumber(L, (int) obj_xform_width(static_pdf, index)); - lua_pushnumber(L, (int) obj_xform_height(static_pdf, index)); - lua_pushnumber(L, (int) obj_xform_depth(static_pdf, index)); + lua_pushinteger(L, (int) obj_xform_width(static_pdf, index)); + lua_pushinteger(L, (int) obj_xform_height(static_pdf, index)); + lua_pushinteger(L, (int) obj_xform_depth(static_pdf, index)); } return 3; } diff --git a/Build/source/texk/web2c/luatexdir/lua/ltokenlib.c b/Build/source/texk/web2c/luatexdir/lua/ltokenlib.c deleted file mode 100644 index 21686c6c3ec..00000000000 --- a/Build/source/texk/web2c/luatexdir/lua/ltokenlib.c +++ /dev/null @@ -1,288 +0,0 @@ -/* ltokenlib.c - - Copyright 2006-2012 Taco Hoekwater <taco@luatex.org> - - This file is part of LuaTeX. - - LuaTeX is free software; you can redistribute it and/or modify it under - the terms of the GNU General Public License as published by the Free - Software Foundation; either version 2 of the License, or (at your - option) any later version. - - LuaTeX is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU General Public License along - with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */ - -#include "ptexlib.h" -#include "lua/luatex-api.h" - - -#define is_valid_token(L,i) (lua_istable(L,i) && lua_rawlen(L,i)==3) -#define get_token_cmd(L,i) lua_rawgeti(L,i,1) -#define get_token_chr(L,i) lua_rawgeti(L,i,2) -#define get_token_cs(L,i) lua_rawgeti(L,i,3) -#define is_active_string(s) (strlen((char *)s)>3 && *s==0xEF && *(s+1)==0xBF && *(s+2)==0xBF) - - -static unsigned char *get_cs_text(int cs) -{ - if (cs == null_cs) - return (unsigned char *) xstrdup("\\csname\\endcsname"); - else if ((cs_text(cs) < 0) || (cs_text(cs) >= str_ptr)) - return (unsigned char *) xstrdup(""); - else - return (unsigned char *) makecstring(cs_text(cs)); -} - - -static int test_expandable(lua_State * L) -{ - int cmd = -1; - int t; - if (is_valid_token(L, -1)) { - get_token_cmd(L, -1); - t = lua_type(L, -1); - if (t == LUA_TNUMBER) { - cmd = (int) lua_tointeger(L, -1); - } else if (t == LUA_TSTRING) { - cmd = get_command_id(lua_tostring(L, -1)); - } - if (cmd > max_command_cmd) { - lua_pushboolean(L, 1); - } else { - lua_pushboolean(L, 0); - } - } else { - lua_pushnil(L); - } - return 1; -} - - -static int test_protected(lua_State * L) -{ - int chr = -1; - int t; - if (is_valid_token(L, -1)) { - get_token_chr(L, -1); - t = lua_type(L, -1); - if (t == LUA_TNUMBER) { - chr = (int) lua_tointeger(L, -1); - } else if (t == LUA_TSTRING) { - chr = get_command_id(lua_tostring(L, -1)); - } - if (token_info(token_link(chr)) == protected_token) { - lua_pushboolean(L, 1); - } else { - lua_pushboolean(L, 0); - } - } else { - lua_pushnil(L); - } - return 1; -} - -static int test_activechar(lua_State * L) -{ - if (is_valid_token(L, -1)) { - unsigned char *s; - int cs = 0; - get_token_cs(L, -1); - if (lua_type(L, -1) == LUA_TNUMBER) { - cs = (int) lua_tointeger(L, -1); - } - lua_pop(L, 1); - if (cs != 0 && ((s = get_cs_text(cs)) != (unsigned char *) NULL)) { - if (is_active_string(s)) { - free(s); - lua_pushboolean(L, 1); - return 1; - } - free(s); - } - } - lua_pushboolean(L, 0); - return 1; -} - - -static int run_get_command_name(lua_State * L) -{ - int cs; - if (is_valid_token(L, -1)) { - get_token_cmd(L, -1); - if (lua_type(L, -1) == LUA_TNUMBER) { - cs = (int) lua_tointeger(L, -1); - lua_pushstring(L, command_names[cs].cmd_name); - } else { - lua_pushstring(L, ""); - } - } else { - lua_pushnil(L); - } - return 1; -} - - -static int run_get_csname_name(lua_State * L) -{ - int cs /*, cmd*/; - unsigned char *s; - if (is_valid_token(L, -1)) { - get_token_cmd(L, -1); - /* - if (lua_type(L, -1) == LUA_TNUMBER) { - cmd = (int) lua_tointeger(L, -1); - } - */ - lua_pop(L, 1); - cs = 0; - get_token_cs(L, -1); - if (lua_type(L, -1) == LUA_TNUMBER) { - cs = (int) lua_tointeger(L, -1); - } - lua_pop(L, 1); - - if (cs != 0 && ((s = get_cs_text(cs)) != (unsigned char *) NULL)) { - if (is_active_string(s)) - lua_pushstring(L, (char *) (s + 3)); - else - lua_pushstring(L, (char *) s); - } else { - lua_pushstring(L, ""); - } - } else { - lua_pushnil(L); - } - return 1; -} - -static int run_get_command_id(lua_State * L) -{ - int cs = -1; - if (lua_type(L, -1) == LUA_TSTRING) { - cs = get_command_id(lua_tostring(L, -1)); - } - lua_pushnumber(L, cs); - return 1; -} - - -static int run_get_csname_id(lua_State * L) -{ - const char *s; - size_t k, cs = 0; - if (lua_type(L, -1) == LUA_TSTRING) { - s = lua_tolstring(L, -1, &k); - cs = (size_t) string_lookup(s, k); - } - lua_pushnumber(L, (lua_Number) cs); - return 1; -} - - -void make_token_table(lua_State * L, int cmd, int chr, int cs) -{ - lua_createtable(L, 3, 0); - lua_pushnumber(L, cmd); - lua_rawseti(L, -2, 1); - lua_pushnumber(L, chr); - lua_rawseti(L, -2, 2); - lua_pushnumber(L, cs); - lua_rawseti(L, -2, 3); -} - -static int run_get_next(lua_State * L) -{ - int save_nncs; - save_nncs = no_new_control_sequence; - no_new_control_sequence = 0; - get_next(); - no_new_control_sequence = save_nncs; - make_token_table(L, cur_cmd, cur_chr, cur_cs); - return 1; -} - -static int run_expand(lua_State * L) -{ - (void) L; - expand(); - return 0; -} - - -static int run_lookup(lua_State * L) -{ - const char *s; - size_t l; - int cs, cmd, chr; - int save_nncs; - if (lua_type(L, -1) == LUA_TSTRING) { - s = lua_tolstring(L, -1, &l); - if (l > 0) { - save_nncs = no_new_control_sequence; - no_new_control_sequence = true; - cs = id_lookup((last + 1), (int) l); /* cleans up the lookup buffer */ - cs = string_lookup(s, l); - cmd = eq_type(cs); - chr = equiv(cs); - make_token_table(L, cmd, chr, cs); - no_new_control_sequence = save_nncs; - return 1; - } - } - lua_newtable(L); - return 1; -} - -static int run_build(lua_State * L) -{ - int cmd, chr, cs; - if (lua_type(L, 1) == LUA_TNUMBER) { - cs = 0; - chr = (int) lua_tointeger(L, 1); - cmd = (int) luaL_optinteger(L, 2, get_char_cat_code(chr)); - if (cmd == 0 || cmd == 9 || cmd == 14 || cmd == 15) { - fprintf(stdout, - "\n\nluatex error: not a good token.\nCatcode %i can not be returned, so I replaced it by 12 (other)", - (int) cmd); - error(); - cmd = 12; - } - if (cmd == 13) { - cs = active_to_cs(chr, false); - cmd = eq_type(cs); - chr = equiv(cs); - } - make_token_table(L, cmd, chr, cs); - return 1; - } else { - return run_lookup(L); - } -} - - -static const struct luaL_Reg tokenlib[] = { - {"get_next", run_get_next}, - {"expand", run_expand}, - {"lookup", run_lookup}, - {"create", run_build}, - {"is_expandable", test_expandable}, - {"is_activechar", test_activechar}, - {"is_protected", test_protected}, - {"csname_id", run_get_csname_id}, - {"csname_name", run_get_csname_name}, - {"command_name", run_get_command_name}, - {"command_id", run_get_command_id}, - {NULL, NULL} /* sentinel */ -}; - -int luaopen_oldtoken(lua_State * L) -{ - luaL_register(L, "oldtoken", tokenlib); - return 1; -} diff --git a/Build/source/texk/web2c/luatexdir/lua/luagen.h b/Build/source/texk/web2c/luatexdir/lua/luagen.h deleted file mode 100644 index d49f60f02b8..00000000000 --- a/Build/source/texk/web2c/luatexdir/lua/luagen.h +++ /dev/null @@ -1,20 +0,0 @@ -/* luagen.h - - Copyright 2009-2013 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/>. */ - -/* obsolete, one can intercept nodelist and flush as lua if needed */ diff --git a/Build/source/texk/web2c/luatexdir/lua/luagen.w b/Build/source/texk/web2c/luatexdir/lua/luagen.w deleted file mode 100644 index f5b01df8505..00000000000 --- a/Build/source/texk/web2c/luatexdir/lua/luagen.w +++ /dev/null @@ -1,20 +0,0 @@ -% luagen.w -% -% Copyright 2009-2013 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/>. - -/* obsolete */ diff --git a/Build/source/texk/web2c/luatexdir/lua/luainit.w b/Build/source/texk/web2c/luatexdir/lua/luainit.w index c95c29d5aaf..fb9d2c72909 100644 --- a/Build/source/texk/web2c/luatexdir/lua/luainit.w +++ b/Build/source/texk/web2c/luatexdir/lua/luainit.w @@ -19,7 +19,6 @@ @ @c - #include "ptexlib.h" #include <kpathsea/c-stat.h> @@ -29,10 +28,7 @@ /* internalized strings: see luatex-api.h */ set_make_keys; - @ -TH: TODO - This file is getting a bit messy, but it is not simple to fix unilaterally. Better to wait until Karl has some time (after texlive 2008) so we can @@ -150,12 +146,8 @@ static char *ex_selfdir(char *argv0) #endif } - - - @ @c -static void -prepare_cmdline(lua_State * L, char **av, int ac, int zero_offset) +static void prepare_cmdline(lua_State * L, char **av, int ac, int zero_offset) { int i; char *s; @@ -289,8 +281,6 @@ unsigned int lua_unsigned_numeric_field_by_index(lua_State * L, int name_index, return i; } - - @ @c static void parse_options(int ac, char **av) { @@ -338,52 +328,41 @@ static void parse_options(int ac, char **av) } else if (ARGUMENT_IS("jiton")) { luajiton = 1; } else if (ARGUMENT_IS("jithash")) { - size_t len = strlen(optarg); - if (len<16) - jithash_hashname = optarg; - else{ - WARNING2("hash name truncated to 15 characters from %d. (%s)", - (int) len, optarg); - jithash_hashname = (string) xmalloc(16); - strncpy(jithash_hashname, optarg, 15); - jithash_hashname[15] = 0; - } + size_t len = strlen(optarg); + if (len<16) { + jithash_hashname = optarg; + } else { + WARNING2("hash name truncated to 15 characters from %d. (%s)", (int) len, optarg); + jithash_hashname = (string) xmalloc(16); + strncpy(jithash_hashname, optarg, 15); + jithash_hashname[15] = 0; + } #endif - } else if (ARGUMENT_IS("luahashchars")) { show_luahashchars = 1; - } else if (ARGUMENT_IS("kpathsea-debug")) { kpathsea_debug |= atoi(optarg); - } else if (ARGUMENT_IS("progname")) { user_progname = optarg; - } else if (ARGUMENT_IS("jobname")) { c_job_name = optarg; - } else if (ARGUMENT_IS("fmt")) { dump_name = optarg; - } else if (ARGUMENT_IS("output-directory")) { output_directory = optarg; - } else if (ARGUMENT_IS("output-comment")) { size_t len = strlen(optarg); if (len < 256) { output_comment = optarg; } else { - WARNING2("Comment truncated to 255 characters from %d. (%s)", - (int) len, optarg); + WARNING2("Comment truncated to 255 characters from %d. (%s)", (int) len, optarg); output_comment = (string) xmalloc(256); strncpy(output_comment, optarg, 255); output_comment[255] = 0; } - } else if (ARGUMENT_IS("shell-restricted")) { shellenabledp = 1; restrictedshell = 1; - } else if (ARGUMENT_IS("output-format")) { output_mode_option = 1; if (strcmp(optarg, "dvi") == 0) { @@ -394,17 +373,13 @@ static void parse_options(int ac, char **av) WARNING1("Ignoring unknown value `%s' for --output-format",optarg); output_mode_option = 0; } - } else if (ARGUMENT_IS("draftmode")) { draft_mode_option = 1; draft_mode_value = 1; - } else if (ARGUMENT_IS("mktex")) { kpse_maketex_option(optarg, true); - } else if (ARGUMENT_IS("no-mktex")) { kpse_maketex_option(optarg, false); - } else if (ARGUMENT_IS("interaction")) { /* These numbers match CPP defines */ if (STREQ(optarg, "batchmode")) { @@ -416,17 +391,13 @@ static void parse_options(int ac, char **av) } else if (STREQ(optarg, "errorstopmode")) { interactionoption = 3; } else { - WARNING1("Ignoring unknown argument `%s' to --interaction", - optarg); + WARNING1("Ignoring unknown argument `%s' to --interaction", optarg); } - } else if (ARGUMENT_IS("synctex")) { /* Synchronize TeXnology: catching the command line option as a long */ synctexoption = (int) strtol(optarg, NULL, 0); - } else if (ARGUMENT_IS("help")) { usagehelp(LUATEX_IHELP, BUG_ADDRESS); - } else if (ARGUMENT_IS("version")) { print_version_banner(); /* *INDENT-OFF* */ @@ -463,9 +434,9 @@ static void parse_options(int ac, char **av) } /* attempt to find |input_name| / |dump_name| */ if (lua_only) { - if (argv[optind]) { - startup_filename = xstrdup(argv[optind]); - lua_offset = optind; + if (argv[optind]) { + startup_filename = xstrdup(argv[optind]); + lua_offset = optind; } } else if (argv[optind] && argv[optind][0] == '&') { dump_name = xstrdup(argv[optind] + 1); @@ -482,11 +453,11 @@ static void parse_options(int ac, char **av) firstfile + strlen(firstfile) - 4) || (strstr(firstfile, ".LUC") == firstfile + strlen(firstfile) - 4)) { - if (startup_filename == NULL) { - startup_filename = firstfile; - lua_offset = optind; - lua_only = 1; - luainit = 1; + if (startup_filename == NULL) { + startup_filename = firstfile; + lua_offset = optind; + lua_only = 1; + luainit = 1; } } else { input_name = firstfile; @@ -521,7 +492,6 @@ static void parse_options(int ac, char **av) } if (safer_option) /* --safer implies --nosocket */ nosocket_option = 1; - /* Finalize the input filename. */ if (input_name != NULL) { argv[optind] = normalize_quotes(input_name, "argument"); @@ -561,11 +531,9 @@ static char *find_filename(char *name, const char *envkey) return NULL; } - @ @c static void init_kpse(void) { - if (!user_progname) { user_progname = dump_name; } else if (!dump_name) { @@ -637,8 +605,7 @@ static const char *luatex_kpse_find_aux(lua_State *L, const char *name, filename = kpse_find_file(name, format, false); } if (filename == NULL) { - lua_pushfstring(L, "\n\t[kpse %s searcher] file not found: " LUA_QS, - errname, name); + lua_pushfstring(L, "\n\t[kpse %s searcher] file not found: " LUA_QS, errname, name); } return filename; } @@ -662,9 +629,9 @@ static int luatex_kpse_lua_find(lua_State * L) name = luaL_checkstring(L, 1); if (program_name_set == 0) { lua_rawgeti(L, LUA_REGISTRYINDEX, lua_loader_function); - lua_pushvalue(L, -2); - lua_call(L, 1, 1); - return 1; + lua_pushvalue(L, -2); + lua_call(L, 1, 1); + return 1; } filename = luatex_kpse_find_aux(L, name, kpse_lua_format, "lua"); if (filename == NULL) @@ -691,9 +658,9 @@ static int luatex_kpse_clua_find(lua_State * L) name = luaL_checkstring(L, 1); if (program_name_set == 0) { lua_rawgeti(L, LUA_REGISTRYINDEX, clua_loader_function); - lua_pushvalue(L, -2); - lua_call(L, 1, 1); - return 1; + lua_pushvalue(L, -2); + lua_call(L, 1, 1); + return 1; } else { const char *path_saved; char *prefix, *postfix, *p, *total; @@ -701,11 +668,12 @@ static int luatex_kpse_clua_find(lua_State * L) char *temp_name; int j; filename = luatex_kpse_find_aux(L, name, kpse_clua_format, "C"); - if (filename == NULL) + if (filename == NULL) return 1; /* library not found in this path */ - extensionless = strdup(filename); - if (!extensionless) return 1; /* allocation failure */ - /* Fix Issue 850: replace '.' with LUA_DIRSEP */ + extensionless = strdup(filename); + if (!extensionless) + return 1; /* allocation failure */ + /* Fix Issue 850: replace '.' with LUA_DIRSEP */ temp_name = strdup(name); for(j=0; ; j++){ if ((unsigned char)temp_name[j]=='\0') { @@ -715,36 +683,36 @@ static int luatex_kpse_clua_find(lua_State * L) temp_name[j]=LUA_DIRSEP[0]; } } - p = strstr(extensionless, temp_name); - if (!p) return 1; /* this would be exceedingly weird */ - *p = '\0'; - prefix = strdup(extensionless); - if (!prefix) return 1; /* allocation failure */ - postfix = strdup(p+strlen(name)); - if (!postfix) return 1; /* allocation failure */ - total = malloc(strlen(prefix)+strlen(postfix)+2); - if (!total) return 1; /* allocation failure */ - snprintf(total,strlen(prefix)+strlen(postfix)+2, "%s?%s", prefix, postfix); - /* save package.path */ - lua_getglobal(L,"package"); + p = strstr(extensionless, temp_name); + if (!p) return 1; /* this would be exceedingly weird */ + *p = '\0'; + prefix = strdup(extensionless); + if (!prefix) return 1; /* allocation failure */ + postfix = strdup(p+strlen(name)); + if (!postfix) return 1; /* allocation failure */ + total = malloc(strlen(prefix)+strlen(postfix)+2); + if (!total) return 1; /* allocation failure */ + snprintf(total,strlen(prefix)+strlen(postfix)+2, "%s?%s", prefix, postfix); + /* save package.path */ + lua_getglobal(L,"package"); lua_getfield(L,-1,"cpath"); - path_saved = lua_tostring(L,-1); - lua_pop(L,1); + path_saved = lua_tostring(L,-1); + lua_pop(L,1); /* set package.path = "?" */ - lua_pushstring(L,total); - lua_setfield(L,-2,"cpath"); - lua_pop(L,1); /* pop "package" */ + lua_pushstring(L,total); + lua_setfield(L,-2,"cpath"); + lua_pop(L,1); /* pop "package" */ /* run function */ lua_rawgeti(L, LUA_REGISTRYINDEX, clua_loader_function); - lua_pushstring(L, name); - lua_call(L, 1, 1); + lua_pushstring(L, name); + lua_call(L, 1, 1); /* restore package.path */ - lua_getglobal(L,"package"); - lua_pushstring(L,path_saved); - lua_setfield(L,-2,"cpath"); - lua_pop(L,1); /* pop "package" */ - free(extensionless); - free(total); + lua_getglobal(L,"package"); + lua_pushstring(L,path_saved); + lua_setfield(L,-2,"cpath"); + lua_pop(L,1); /* pop "package" */ + free(extensionless); + free(total); free(temp_name); return 1; } @@ -793,6 +761,33 @@ int l_math_style_name_index [MATH_STYLE_NAME_SIZE]; int l_dir_par_index [DIR_PAR_SIZE]; int l_dir_text_index [DIR_TEXT_SIZE]; +int img_parms [img_parms_max]; +int img_pageboxes [img_pageboxes_max]; + +int lua_show_valid_list(lua_State *L, const char **list, int max) +{ + int i; + lua_newtable(L); + for (i = 0; i < max; i++) { + lua_pushinteger(L,i+1); + lua_pushstring(L, list[i]); + lua_settable(L, -3); + } + return 1; +} + +int lua_show_valid_keys(lua_State *L, int *list, int max) +{ + int i; + lua_newtable(L); + for (i = 0; i < max; i++) { + lua_pushinteger(L,i+1); + lua_rawgeti(L, LUA_REGISTRYINDEX, list[i]); + lua_settable(L, -3); + } + return 1; +} + #if defined(WIN32) || defined(__MINGW32__) || defined(__CYGWIN__) char **suffixlist; @@ -846,37 +841,24 @@ static void mk_suffixlist(void) } #endif - @ @c void lua_initialize(int ac, char **av) { - char *given_file = NULL; char *banner; int kpse_init; + size_t len; static char LC_CTYPE_C[] = "LC_CTYPE=C"; static char LC_COLLATE_C[] = "LC_COLLATE=C"; static char LC_NUMERIC_C[] = "LC_NUMERIC=C"; static char engine_luatex[] = "engine=" my_name; /* Save to pass along to topenin. */ + const char *fmt = "This is " MyName ", Version %s" WEB2CVERSION; argc = ac; argv = av; - - - if (luatex_svn < 0) { - const char *fmt = "This is " MyName ", Version %s" WEB2CVERSION; - size_t len; - len = strlen(fmt) + strlen(luatex_version_string) ; - - banner = xmalloc(len); - sprintf(banner, fmt, luatex_version_string); - } else { - const char *fmt = "This is " MyName ", Version %s" WEB2CVERSION " (rev %d)"; - size_t len; - len = strlen(fmt) + strlen(luatex_version_string) + 6; - banner = xmalloc(len); - sprintf(banner, fmt, luatex_version_string, luatex_svn); - } + len = strlen(fmt) + strlen(luatex_version_string) ; + banner = xmalloc(len); + sprintf(banner, fmt, luatex_version_string); luatex_banner = banner; kpse_invocation_name = kpse_program_basename(argv[0]); @@ -946,6 +928,9 @@ void lua_initialize(int ac, char **av) set_l_dir_par_index; set_l_dir_text_index; + set_l_img_keys_index; + set_l_img_pageboxes_index; + prepare_cmdline(Luas, argv, argc, lua_offset); /* collect arguments */ setup_lua_path(Luas); @@ -974,7 +959,7 @@ void lua_initialize(int ac, char **av) init_tex_table(Luas); if (lua_pcall(Luas, 0, 0, 0)) { fprintf(stdout, "%s\n", lua_tostring(Luas, -1)); - lua_traceback(Luas); + lua_traceback(Luas); exit(1); } /* no filename? quit now! */ @@ -1028,7 +1013,7 @@ void lua_initialize(int ac, char **av) shellenabledp = 1; restrictedshell = 1; } - free(v1); + free(v1); } /* If shell escapes are restricted, get allowed cmds from cnf. */ if (shellenabledp && restrictedshell == 1) { @@ -1036,21 +1021,18 @@ void lua_initialize(int ac, char **av) get_lua_string("texconfig", "shell_escape_commands", &v1); if (v1) { mk_shellcmdlist(v1); - free(v1); + free(v1); } } fix_dumpname(); - } else { if (luainit) { if (given_file) { - fprintf(stdout, "%s file %s not found\n", - (lua_only ? "Script" : "Configuration"), given_file); + fprintf(stdout, "%s file %s not found\n", (lua_only ? "Script" : "Configuration"), given_file); free(given_file); } else { - fprintf(stdout, "No %s file given\n", - (lua_only ? "script" : "configuration")); + fprintf(stdout, "No %s file given\n", (lua_only ? "script" : "configuration")); } exit(1); } else { @@ -1072,30 +1054,10 @@ void check_texconfig_init(void) 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)); + fprintf(stderr, "This went wrong: %s\n", lua_tostring(Luas, -1)); error(); } } } } } - -@ @c -void write_svnversion(char *v) -{ - char *a_head, *n; - char *a = xstrdup(v); - size_t 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/luajitstuff.w b/Build/source/texk/web2c/luatexdir/lua/luajitstuff.w index 8e0953fa0ab..e19338027b0 100644 --- a/Build/source/texk/web2c/luatexdir/lua/luajitstuff.w +++ b/Build/source/texk/web2c/luatexdir/lua/luajitstuff.w @@ -100,7 +100,7 @@ void luafunctioncall(int slot) lua_rawgeti(Luas, -1,slot); if (lua_isfunction(Luas,-1)) { int base = lua_gettop(Luas); /* function index */ - lua_pushnumber(Luas, slot); + lua_pushinteger(Luas, slot); lua_pushcfunction(Luas, lua_traceback); /* push traceback function */ lua_insert(Luas, base); /* put it under chunk */ i = lua_pcall(Luas, 1, 0, base); @@ -302,7 +302,6 @@ void luainterpreter(void) luaopen_ff(L); luaopen_tex(L); luaopen_token(L); - luaopen_oldtoken(L); luaopen_node(L); luaopen_texio(L); luaopen_kpse(L); @@ -587,7 +586,7 @@ lua_State *luatex_error(lua_State * L, int is_fatal) lua_close(L); return (lua_State *) NULL; } else { - normal_warning("lua",err,true,true); + normal_warning("lua",err); return L; } } diff --git a/Build/source/texk/web2c/luatexdir/lua/luanode.w b/Build/source/texk/web2c/luatexdir/lua/luanode.w index c1da8f2d1ca..bd328b8c2f2 100644 --- a/Build/source/texk/web2c/luatexdir/lua/luanode.w +++ b/Build/source/texk/web2c/luatexdir/lua/luanode.w @@ -152,7 +152,7 @@ int lua_appendtovlist_callback(halfword box, int location, halfword prev_depth, } nodelist_to_lua(L, box); lua_push_string_by_index(L,location); - lua_pushnumber(L, (int) prev_depth); + lua_pushinteger(L, (int) prev_depth); lua_pushboolean(L, is_mirrored); if (lua_pcall(L, 4, 2, 0) != 0) { fprintf(stdout, "error: %s\n", lua_tostring(L, -1)); @@ -161,7 +161,7 @@ int lua_appendtovlist_callback(halfword box, int location, halfword prev_depth, return 0; } if (lua_type(L,-1) == LUA_TNUMBER) { - *next_depth = lua_tonumber(L,-1); + *next_depth = lua_tointeger(L,-1); *prev_set = true; if (lua_type(L, -2) != LUA_TNIL) { p = check_isnode(L, -2); @@ -193,7 +193,7 @@ halfword lua_hpack_filter(halfword head_node, scaled size, int pack_type, int ex alink(head_node) = null ; /* hh-ls */ nodelist_to_lua(L, head_node); lua_push_group_code(L,extrainfo); - lua_pushnumber(L, size); + lua_pushinteger(L, size); lua_push_pack_type(L,pack_type); if (pack_direction >= 0) lua_push_dir_par(L, pack_direction); @@ -251,9 +251,9 @@ halfword lua_vpack_filter(halfword head_node, scaled size, int pack_type, scaled alink(head_node) = null ; /* hh-ls */ nodelist_to_lua(L, head_node); lua_push_group_code(L,extrainfo); - lua_pushnumber(L, size); + lua_pushinteger(L, size); lua_push_pack_type(L,pack_type); - lua_pushnumber(L, maxd); + lua_pushinteger(L, maxd); if (pack_direction >= 0) lua_push_dir_par(L, pack_direction); else @@ -383,17 +383,17 @@ 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: - confusion("literal2"); - break; + case set_origin: + break; + case direct_page: + tprint(" page"); + break; + case direct_always: + tprint(" direct"); + break; + default: + confusion("literal2"); + break; } if (pdf_literal_type(p) == normal) { print_mark(pdf_literal_data(p)); diff --git a/Build/source/texk/web2c/luatexdir/lua/luastuff.w b/Build/source/texk/web2c/luatexdir/lua/luastuff.w index 4214675cd19..6fac3afbf32 100644 --- a/Build/source/texk/web2c/luatexdir/lua/luastuff.w +++ b/Build/source/texk/web2c/luatexdir/lua/luastuff.w @@ -96,7 +96,7 @@ void luafunctioncall(int slot) lua_rawgeti(Luas, -1,slot); if (lua_isfunction(Luas,-1)) { int base = lua_gettop(Luas); /* function index */ - lua_pushnumber(Luas, slot); + lua_pushinteger(Luas, slot); lua_pushcfunction(Luas, lua_traceback); /* push traceback function */ lua_insert(Luas, base); /* put it under chunk */ i = lua_pcall(Luas, 1, 0, base); @@ -255,7 +255,6 @@ void luainterpreter(void) /* our own libraries */ luaopen_ff(L); luaopen_tex(L); - luaopen_oldtoken(L); luaopen_token(L); luaopen_node(L); luaopen_texio(L); @@ -535,7 +534,7 @@ lua_State *luatex_error(lua_State * L, int is_fatal) lua_close(L); return (lua_State *) NULL; } else { - normal_warning("lua",err,true,true); + normal_warning("lua",err); return L; } } diff --git a/Build/source/texk/web2c/luatexdir/lua/luatex-api.h b/Build/source/texk/web2c/luatexdir/lua/luatex-api.h index 8c99cf72519..c67522c06fc 100644 --- a/Build/source/texk/web2c/luatexdir/lua/luatex-api.h +++ b/Build/source/texk/web2c/luatexdir/lua/luatex-api.h @@ -156,7 +156,6 @@ extern int luajiton; extern char *jithash_hashname ; #endif - #if !defined(LUAI_HASHLIMIT) #define LUAI_HASHLIMIT 5 #endif @@ -245,6 +244,8 @@ extern char **environ; } #endif +extern int luatwrite(lua_State * L); + /* Same as in lnodelib.c, but with prefix G_ for now. These macros create and access pointers (indices) to keys which is faster. The @@ -318,14 +319,14 @@ extern int l_math_style_name_index [MATH_STYLE_NAME_SIZE]; extern int l_dir_par_index [DIR_PAR_SIZE]; extern int l_dir_text_index [DIR_TEXT_SIZE]; -#define lua_push_pack_type(L,pack_type) lua_rawgeti(L, LUA_REGISTRYINDEX, l_pack_type_index[pack_type] ); -#define lua_push_group_code(L,group_code) lua_rawgeti(L, LUA_REGISTRYINDEX, l_group_code_index[group_code]); +#define lua_push_pack_type(L,pack_type) lua_rawgeti(L, LUA_REGISTRYINDEX, l_pack_type_index[pack_type] ); +#define lua_push_group_code(L,group_code) lua_rawgeti(L, LUA_REGISTRYINDEX, l_group_code_index[group_code]); #define lua_push_math_style_name(L,style_name) lua_rawgeti(L, LUA_REGISTRYINDEX, l_math_style_name_index[style_name]); -#define lua_push_dir_par(L,dir) lua_rawgeti(L, LUA_REGISTRYINDEX, l_dir_par_index[dir+dir_swap]) -#define lua_push_dir_text(L,dir) lua_rawgeti(L, LUA_REGISTRYINDEX, l_dir_text_index[dir+dir_swap]) +#define lua_push_dir_par(L,dir) lua_rawgeti(L, LUA_REGISTRYINDEX, l_dir_par_index[dir+dir_swap]) +#define lua_push_dir_text(L,dir) lua_rawgeti(L, LUA_REGISTRYINDEX, l_dir_text_index[dir+dir_swap]) -#define lua_push_string_by_index(L,index) lua_rawgeti(L, LUA_REGISTRYINDEX, index) -#define lua_push_string_by_name(L,index) lua_rawgeti(L, LUA_REGISTRYINDEX, lua_key_index(index)) +#define lua_push_string_by_index(L,index) lua_rawgeti(L, LUA_REGISTRYINDEX, index) +#define lua_push_string_by_name(L,index) lua_rawgeti(L, LUA_REGISTRYINDEX, lua_key_index(index)) #define set_l_pack_type_index \ l_pack_type_index[0] = lua_key_index(exactly); \ @@ -388,6 +389,53 @@ l_dir_text_index[5] = lua_key_index(pTRT);\ l_dir_text_index[6] = lua_key_index(pLTL);\ l_dir_text_index[7] = lua_key_index(pRTT);\ +#define img_parms_max 25 +#define img_pageboxes_max 6 + +extern int img_parms [img_parms_max]; +extern int img_pageboxes [img_pageboxes_max]; + +# define set_l_img_keys_index \ +img_parms[ 0] = lua_key_index(attr); \ +img_parms[ 1] = lua_key_index(bbox); \ +img_parms[ 2] = lua_key_index(colordepth); \ +img_parms[ 3] = lua_key_index(colorspace); \ +img_parms[ 4] = lua_key_index(depth); \ +img_parms[ 5] = lua_key_index(filename); \ +img_parms[ 6] = lua_key_index(filepath); \ +img_parms[ 7] = lua_key_index(height); \ +img_parms[ 8] = lua_key_index(imagetype); \ +img_parms[ 9] = lua_key_index(index); \ +img_parms[10] = lua_key_index(keepopen); \ +img_parms[11] = lua_key_index(objnum); \ +img_parms[12] = lua_key_index(pagebox); \ +img_parms[13] = lua_key_index(page); \ +img_parms[14] = lua_key_index(pages); \ +img_parms[15] = lua_key_index(ref_count); \ +img_parms[16] = lua_key_index(rotation); \ +img_parms[17] = lua_key_index(stream); \ +img_parms[18] = lua_key_index(transform); \ +img_parms[19] = lua_key_index(visiblefilename); \ +img_parms[20] = lua_key_index(width); \ +img_parms[21] = lua_key_index(xres); \ +img_parms[22] = lua_key_index(xsize); \ +img_parms[23] = lua_key_index(yres); \ +img_parms[24] = lua_key_index(ysize); \ + +# define set_l_img_pageboxes_index \ +img_pageboxes[0] = lua_key_index(none); \ +img_pageboxes[1] = lua_key_index(media); \ +img_pageboxes[2] = lua_key_index(crop); \ +img_pageboxes[3] = lua_key_index(bleed); \ +img_pageboxes[4] = lua_key_index(trim); \ +img_pageboxes[5] = lua_key_index(art); \ + +#define lua_push_img_key(L,key) lua_rawgeti(L, LUA_REGISTRYINDEX, img_parms[key] ); +#define lua_push_img_pagebox(L,box) lua_rawgeti(L, LUA_REGISTRYINDEX, img_pageboxes[box]); + +extern int lua_show_valid_list(lua_State *L, const char **list, int max); +extern int lua_show_valid_keys(lua_State *L, int *list, int max); + #define set_make_keys \ make_lua_key(cmdname);make_lua_key(expandable);make_lua_key(protected);\ make_lua_key(LTL);\ @@ -413,13 +461,16 @@ make_lua_key(align_set);\ make_lua_key(alignment);\ make_lua_key(annot);\ make_lua_key(area);\ +make_lua_key(art);\ make_lua_key(attr);\ make_lua_key(attributes);\ make_lua_key(auto_expand);\ +make_lua_key(bbox);\ make_lua_key(before_display);\ make_lua_key(best_ins_ptr);\ make_lua_key(best_page_break);\ make_lua_key(best_size);\ +make_lua_key(bleed);\ make_lua_key(bot);\ make_lua_key(bot_accent);\ make_lua_key(bottom_left);\ @@ -439,6 +490,8 @@ make_lua_key(characters);\ make_lua_key(checksum);\ make_lua_key(cidinfo);\ make_lua_key(class);\ +make_lua_key(colordepth);\ +make_lua_key(colorspace);\ make_lua_key(command);\ make_lua_key(commands);\ make_lua_key(comment);\ @@ -452,6 +505,7 @@ make_lua_key(crampeddisplay);\ make_lua_key(crampedscript);\ make_lua_key(crampedscriptscript);\ make_lua_key(crampedtext);\ +make_lua_key(crop);\ make_lua_key(csname);\ make_lua_key(data);\ make_lua_key(degree);\ @@ -491,6 +545,7 @@ make_lua_key(fast);\ make_lua_key(fence);\ make_lua_key(file);\ make_lua_key(filename);\ +make_lua_key(filepath);\ make_lua_key(fill);\ make_lua_key(fin_row);\ make_lua_key(font);\ @@ -513,11 +568,13 @@ make_lua_key(horiz_variants);\ make_lua_key(hyphenchar);\ make_lua_key(id);\ make_lua_key(image);\ +make_lua_key(imagetype);\ make_lua_key(immediate);\ make_lua_key(index);\ make_lua_key(info);\ make_lua_key(insert);\ make_lua_key(italic);\ +make_lua_key(keepopen);\ make_lua_key(kern);\ make_lua_key(kerns);\ make_lua_key(lang);\ @@ -554,6 +611,7 @@ make_lua_key(math_shift);\ make_lua_key(mathdir);\ make_lua_key(mathkern);\ make_lua_key(mathstyle);\ +make_lua_key(media);\ make_lua_key(mid);\ make_lua_key(mode);\ make_lua_key(modeline);\ @@ -570,6 +628,7 @@ make_lua_key(node);\ make_lua_key(node_properties);\ make_lua_key(node_properties_indirect);\ make_lua_key(nomath);\ +make_lua_key(none);\ make_lua_key(nop);\ make_lua_key(nucleus);\ make_lua_key(num);\ @@ -586,9 +645,11 @@ make_lua_key(pRTT);\ make_lua_key(pTLT);\ make_lua_key(pTRT);\ make_lua_key(page);\ +make_lua_key(pages);\ make_lua_key(page_head);\ make_lua_key(page_ins_head);\ make_lua_key(pageattributes);\ +make_lua_key(pagebox);\ make_lua_key(pageresources);\ make_lua_key(pagesattributes);\ make_lua_key(parameters);\ @@ -627,6 +688,7 @@ make_lua_key(resources);\ make_lua_key(right);\ make_lua_key(right_boundary);\ make_lua_key(right_protruding);\ +make_lua_key(rotation);\ make_lua_key(rule);\ make_lua_key(scale);\ make_lua_key(script);\ @@ -682,6 +744,7 @@ make_lua_key(top_right);\ make_lua_key(tounicode);\ make_lua_key(trailer);\ make_lua_key(transform);\ +make_lua_key(trim);\ make_lua_key(type);\ make_lua_key(uchyph);\ make_lua_key(umath);\ @@ -696,6 +759,7 @@ make_lua_key(version);\ make_lua_key(vert_italic);\ make_lua_key(vert_variants);\ make_lua_key(vmode_par);\ +make_lua_key(visiblefilename);\ make_lua_key(vtop);\ make_lua_key(width);\ make_lua_key(writable);\ @@ -703,8 +767,12 @@ make_lua_key(x_height);\ make_lua_key(xformresources);\ make_lua_key(xformattributes);\ make_lua_key(xoffset);\ +make_lua_key(xres);\ +make_lua_key(xsize);\ make_lua_key(xyz_zoom);\ -make_lua_key(yoffset) +make_lua_key(yoffset); \ +make_lua_key(yres); \ +make_lua_key(ysize) #define set_init_keys \ init_lua_key(cmdname);init_lua_key(expandable);init_lua_key(protected);\ @@ -731,13 +799,16 @@ init_lua_key(align_set);\ init_lua_key(alignment);\ init_lua_key(annot);\ init_lua_key(area);\ +init_lua_key(art);\ init_lua_key(attr);\ init_lua_key(attributes);\ init_lua_key(auto_expand);\ +init_lua_key(bbox);\ init_lua_key(before_display);\ init_lua_key(best_ins_ptr);\ init_lua_key(best_page_break);\ init_lua_key(best_size);\ +init_lua_key(bleed);\ init_lua_key(bot);\ init_lua_key(bot_accent);\ init_lua_key(bottom_left);\ @@ -757,6 +828,8 @@ init_lua_key(characters);\ init_lua_key(checksum);\ init_lua_key(cidinfo);\ init_lua_key(class);\ +init_lua_key(colordepth);\ +init_lua_key(colorspace);\ init_lua_key(command);\ init_lua_key(commands);\ init_lua_key(comment);\ @@ -770,6 +843,7 @@ init_lua_key(crampeddisplay);\ init_lua_key(crampedscript);\ init_lua_key(crampedscriptscript);\ init_lua_key(crampedtext);\ +init_lua_key(crop);\ init_lua_key(csname);\ init_lua_key(data);\ init_lua_key(degree);\ @@ -808,6 +882,7 @@ init_lua_key(fast);\ init_lua_key(fence);\ init_lua_key(file);\ init_lua_key(filename);\ +init_lua_key(filepath);\ init_lua_key(fill);\ init_lua_key(fin_row);\ init_lua_key(font);\ @@ -830,11 +905,13 @@ init_lua_key(horiz_variants);\ init_lua_key(hyphenchar);\ init_lua_key(id);\ init_lua_key(image);\ +init_lua_key(imagetype);\ init_lua_key(immediate);\ init_lua_key(index);\ init_lua_key(info);\ init_lua_key(insert);\ init_lua_key(italic);\ +init_lua_key(keepopen);\ init_lua_key(kern);\ init_lua_key(kerns);\ init_lua_key(lang);\ @@ -867,6 +944,7 @@ init_lua_key(math_shift);\ init_lua_key(mathdir);\ init_lua_key(mathkern);\ init_lua_key(mathstyle);\ +init_lua_key(media);\ init_lua_key(mid);\ init_lua_key(mode);\ init_lua_key(modeline);\ @@ -881,6 +959,7 @@ init_lua_key(no_align);\ init_lua_key(noad);\ init_lua_key(node);\ init_lua_key(nomath);\ +init_lua_key(none);\ init_lua_key(nop);\ init_lua_key(nucleus);\ init_lua_key(num);\ @@ -893,9 +972,11 @@ init_lua_key(ordering);\ init_lua_key(output);\ init_lua_key(overlay_accent);\ init_lua_key(page);\ +init_lua_key(pages);\ init_lua_key(page_head);\ init_lua_key(page_ins_head);\ init_lua_key(pageattributes);\ +init_lua_key(pagebox);\ init_lua_key(pageresources);\ init_lua_key(pagesattributes);\ init_lua_key(parameters);\ @@ -933,6 +1014,7 @@ init_lua_key(resources);\ init_lua_key(right);\ init_lua_key(right_boundary);\ init_lua_key(right_protruding);\ +init_lua_key(rotation);\ init_lua_key(rule);\ init_lua_key(scale);\ init_lua_key(script);\ @@ -987,6 +1069,7 @@ init_lua_key(top_right);\ init_lua_key(tounicode);\ init_lua_key(trailer);\ init_lua_key(transform);\ +init_lua_key(trim);\ init_lua_key(type);\ init_lua_key(uchyph);\ init_lua_key(umath);\ @@ -1001,6 +1084,7 @@ init_lua_key(version);\ init_lua_key(vert_italic);\ init_lua_key(vert_variants);\ init_lua_key(vmode_par);\ +init_lua_key(visiblefilename);\ init_lua_key(vtop);\ init_lua_key(width);\ init_lua_key(writable);\ @@ -1008,8 +1092,12 @@ init_lua_key(x_height);\ init_lua_key(xformresources);\ init_lua_key(xformattributes);\ init_lua_key(xoffset);\ +init_lua_key(xres);\ +init_lua_key(xsize);\ init_lua_key(xyz_zoom);\ init_lua_key(yoffset);\ +init_lua_key(yres);\ +init_lua_key(ysize);\ init_lua_key_alias(empty_string,"");\ init_lua_key_alias(lua_functions,"lua.functions");\ init_lua_key_alias(luatex_node, "luatex.node");\ @@ -1029,7 +1117,7 @@ init_lua_key_alias(term_and_log,"term and log") #define assign_math_style(L,n,target) do { \ if (lua_type(L,n) == LUA_TNUMBER) { \ /* new, often same as subtype anyway */ \ - target = lua_tonumber(L,n); \ + target = lua_tointeger(L,n); \ } else if (lua_type(L,n) == LUA_TSTRING) { \ const char *s = lua_tostring(L, n); \ if (lua_key_eq(s,display)) { \ @@ -1092,13 +1180,16 @@ use_lua_key(align_set); use_lua_key(alignment); use_lua_key(annot); use_lua_key(area); +use_lua_key(art); use_lua_key(attr); use_lua_key(attributes); use_lua_key(auto_expand); +use_lua_key(bbox); use_lua_key(before_display); use_lua_key(best_ins_ptr); use_lua_key(best_page_break); use_lua_key(best_size); +use_lua_key(bleed); use_lua_key(bot); use_lua_key(bot_accent); use_lua_key(bottom_left); @@ -1118,6 +1209,8 @@ use_lua_key(characters); use_lua_key(checksum); use_lua_key(cidinfo); use_lua_key(class); +use_lua_key(colordepth); +use_lua_key(colorspace); use_lua_key(command); use_lua_key(commands); use_lua_key(comment); @@ -1131,6 +1224,7 @@ use_lua_key(crampeddisplay); use_lua_key(crampedscript); use_lua_key(crampedscriptscript); use_lua_key(crampedtext); +use_lua_key(crop); use_lua_key(csname); use_lua_key(data); use_lua_key(degree); @@ -1170,6 +1264,7 @@ use_lua_key(fast); use_lua_key(fence); use_lua_key(file); use_lua_key(filename); +use_lua_key(filepath); use_lua_key(fill); use_lua_key(fin_row); use_lua_key(font); @@ -1192,11 +1287,13 @@ use_lua_key(horiz_variants); use_lua_key(hyphenchar); use_lua_key(id); use_lua_key(image); +use_lua_key(imagetype); use_lua_key(immediate); use_lua_key(index); use_lua_key(info); use_lua_key(insert); use_lua_key(italic); +use_lua_key(keepopen); use_lua_key(kern); use_lua_key(kerns); use_lua_key(lang); @@ -1233,6 +1330,7 @@ use_lua_key(math_shift); use_lua_key(mathdir); use_lua_key(mathkern); use_lua_key(mathstyle); +use_lua_key(media); use_lua_key(mid); use_lua_key(mode); use_lua_key(modeline); @@ -1249,6 +1347,7 @@ use_lua_key(node); use_lua_key(node_properties); use_lua_key(node_properties_indirect); use_lua_key(nomath); +use_lua_key(none); use_lua_key(nop); use_lua_key(nucleus); use_lua_key(num); @@ -1265,8 +1364,10 @@ use_lua_key(pRTT); use_lua_key(pTLT); use_lua_key(pTRT); use_lua_key(page); +use_lua_key(pages); use_lua_key(page_head); use_lua_key(page_ins_head); +use_lua_key(pagebox); use_lua_key(pageattributes); use_lua_key(pageresources); use_lua_key(pagesattributes); @@ -1306,6 +1407,7 @@ use_lua_key(resources); use_lua_key(right); use_lua_key(right_boundary); use_lua_key(right_protruding); +use_lua_key(rotation); use_lua_key(rule); use_lua_key(scale); use_lua_key(script); @@ -1361,6 +1463,7 @@ use_lua_key(top_right); use_lua_key(tounicode); use_lua_key(trailer); use_lua_key(transform); +use_lua_key(trim); use_lua_key(type); use_lua_key(uchyph); use_lua_key(umath); @@ -1375,6 +1478,7 @@ use_lua_key(version); use_lua_key(vert_italic); use_lua_key(vert_variants); use_lua_key(vmode_par); +use_lua_key(visiblefilename); use_lua_key(vtop); use_lua_key(width); use_lua_key(writable); @@ -1382,5 +1486,9 @@ use_lua_key(x_height); use_lua_key(xformresources); use_lua_key(xformattributes); use_lua_key(xoffset); +use_lua_key(xres); +use_lua_key(xsize); use_lua_key(xyz_zoom); use_lua_key(yoffset); +use_lua_key(yres); +use_lua_key(ysize); diff --git a/Build/source/texk/web2c/luatexdir/lua/luatoken.w b/Build/source/texk/web2c/luatexdir/lua/luatoken.w index d8ac7eebca8..9001026ca45 100644 --- a/Build/source/texk/web2c/luatexdir/lua/luatoken.w +++ b/Build/source/texk/web2c/luatexdir/lua/luatoken.w @@ -158,6 +158,7 @@ command_item command_names[] = { {"variable", variable_cmd, NULL}, {"feedback", feedback_cmd, NULL}, {"the", the_cmd, NULL}, + {"combinetoks", combine_toks_cmd, NULL}, {"top_bot_mark", top_bot_mark_cmd, NULL}, {"call", call_cmd, NULL}, {"long_call", long_call_cmd, NULL}, @@ -188,7 +189,7 @@ int get_command_id(const char *s) return cmd; } -@ @c +/* static int get_cur_cmd(lua_State * L) { int r = 0; @@ -212,7 +213,7 @@ static int get_cur_cmd(lua_State * L) } return r; } - +*/ @ @c static int token_from_lua(lua_State * L) @@ -239,7 +240,7 @@ static int token_from_lua(lua_State * L) return -1; } -@ @c +/* static int get_cur_cs(lua_State * L) { const char *s; @@ -272,6 +273,7 @@ static int get_cur_cs(lua_State * L) lua_pop(L, 1); return ret; } +*/ @ @c void tokenlist_to_lua(lua_State * L, int p) @@ -357,28 +359,28 @@ int tokenlist_from_lua(lua_State * L) } } -@ @c -void do_get_token_lua(int callback_id) +/* + +static void do_get_token_lua(int callback_id) { lua_State *L = Luas; while (1) { if (!get_callback(L, callback_id)) { get_next(); - lua_pop(L, 2); /* the not-a-function callback and the container */ + lua_pop(L, 2); break; } - if (lua_pcall(L, 0, 1, 0) != 0) { /* no arg, 1 result */ + if (lua_pcall(L, 0, 1, 0) != 0) { tex_error(lua_tostring(L, -1), NULL); - lua_pop(L, 2); /* container and result */ + lua_pop(L, 2); break; } if (lua_istable(L, -1)) { lua_rawgeti(L, -1, 1); - if (lua_istable(L, -1)) { /* container, result, result[1] */ + if (lua_istable(L, -1)) { int p, q, r; size_t i, j; - lua_pop(L, 1); /* container, result */ - /* build a token list */ + lua_pop(L, 1); r = get_avail(); p = r; j = lua_rawlen(L, -1); @@ -403,8 +405,8 @@ void do_get_token_lua(int callback_id) } lua_pop(L, 2); break; - } else { /* container, result, whatever */ - lua_pop(L, 1); /* container, result */ + } else { + lua_pop(L, 1); if (get_cur_cmd(L) || get_cur_cs(L)) { lua_pop(L, 2); break; @@ -414,8 +416,10 @@ void do_get_token_lua(int callback_id) } } } else { - lua_pop(L, 2); /* container, result */ + lua_pop(L, 2); } } return; } + +*/ diff --git a/Build/source/texk/web2c/luatexdir/luafilesystem/src/lfs.c b/Build/source/texk/web2c/luatexdir/luafilesystem/src/lfs.c index a0b967df193..2b1b06cf1db 100644 --- a/Build/source/texk/web2c/luatexdir/luafilesystem/src/lfs.c +++ b/Build/source/texk/web2c/luatexdir/luafilesystem/src/lfs.c @@ -374,10 +374,8 @@ static int make_dir (lua_State *L) { const char *path = luaL_checkstring (L, 1); int fail; #ifdef _WIN32 - int oldmask = umask (0); fail = _mkdir (path); #else - mode_t oldmask = umask( (mode_t)0 ); fail = mkdir (path, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH | S_IXOTH ); #endif @@ -386,7 +384,6 @@ static int make_dir (lua_State *L) { lua_pushfstring (L, "%s", strerror(errno)); return 2; } - umask (oldmask); lua_pushboolean (L, 1); return 1; } diff --git a/Build/source/texk/web2c/luatexdir/luascripts/pdflua.c b/Build/source/texk/web2c/luatexdir/luascripts/pdflua.c deleted file mode 100644 index 05fe351cb7e..00000000000 --- a/Build/source/texk/web2c/luatexdir/luascripts/pdflua.c +++ /dev/null @@ -1,37 +0,0 @@ -/* pdflua.c - - Copyright 2010 Taco Hoekwater <taco@luatex.org> - Copyright 2010 Hartmut Henkel <hartmut@luatex.org> - - This file is part of LuaTeX. - - LuaTeX is free software; you can redistribute it and/or modify it under - the terms of the GNU General Public License as published by the Free - Software Foundation; either version 2 of the License, or (at your - option) any later version. - - LuaTeX is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU General Public License along - with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */ - -#include "ptexlib.h" - -static const Byte compr[139] = { - 0x78, 0x9c, 0xad, 0x4e, 0x5b, 0x0a, 0xc3, 0x30, 0x0c, 0xfb, 0xd7, 0x29, 0xfc, 0xb9, 0x41, 0x93, - 0x1b, 0xec, 0x30, 0x59, 0xeb, 0x76, 0x61, 0xc1, 0x09, 0x4e, 0xc2, 0x18, 0x63, 0x77, 0x5f, 0x0a, - 0x61, 0x4f, 0xf6, 0x57, 0x23, 0x8c, 0x90, 0x04, 0x12, 0x8c, 0xa1, 0x72, 0xf2, 0x99, 0x1a, 0xd8, - 0x69, 0xb8, 0xd2, 0x25, 0xea, 0x99, 0xbc, 0x50, 0xd2, 0xb8, 0x28, 0xe7, 0x6c, 0xad, 0x05, 0xcc, - 0x46, 0x07, 0x1c, 0x79, 0xf1, 0x92, 0xdc, 0xc2, 0x74, 0xa0, 0xb9, 0xca, 0x58, 0x7c, 0x94, 0x9d, - 0xdb, 0x83, 0x65, 0xc2, 0xfa, 0xfe, 0x59, 0xb1, 0x96, 0xd4, 0xd0, 0xdc, 0x5c, 0x94, 0x3f, 0x22, - 0x3d, 0xb1, 0xdd, 0xc6, 0x10, 0x47, 0x17, 0x28, 0x4d, 0x73, 0xa8, 0xae, 0x15, 0xdd, 0x40, 0xf4, - 0x3e, 0xfb, 0xc9, 0x87, 0x66, 0xbc, 0x26, 0x77, 0xb6, 0x8a, 0xbf, 0x63, 0xbf, 0x94, 0x01, 0x77, - 0x40, 0xb9, 0x54, 0x95, 0xde, 0x83, 0x07, 0x1c, 0xdd, 0x6c, 0x66 -}; - -static const zlib_struct compr_struct = { 394, 139, compr }; - -const zlib_struct *pdflua_zlib_struct_ptr = &compr_struct; diff --git a/Build/source/texk/web2c/luatexdir/luascripts/pdflua.h b/Build/source/texk/web2c/luatexdir/luascripts/pdflua.h deleted file mode 100644 index d80f55006ef..00000000000 --- a/Build/source/texk/web2c/luatexdir/luascripts/pdflua.h +++ /dev/null @@ -1,33 +0,0 @@ -/* pdflua.h - - Copyright 2010 Taco Hoekwater <taco@luatex.org> - Copyright 2010 Hartmut Henkel <hartmut@luatex.org> - - This file is part of LuaTeX. - - LuaTeX is free software; you can redistribute it and/or modify it under - the terms of the GNU General Public License as published by the Free - Software Foundation; either version 2 of the License, or (at your - option) any later version. - - LuaTeX is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU General Public License along - with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */ - - -#ifndef PDFLUA_H -# define PDFLUA_H - -typedef struct _zlib_struct { - uLong uncomprLen; - uLong comprLen; - const Byte *compr; -} zlib_struct; - -extern const zlib_struct *pdflua_zlib_struct_ptr; - -#endif /* PDFLUA_H */ diff --git a/Build/source/texk/web2c/luatexdir/luascripts/pdflua.lua b/Build/source/texk/web2c/luatexdir/luascripts/pdflua.lua deleted file mode 100644 index c8164367d75..00000000000 --- a/Build/source/texk/web2c/luatexdir/luascripts/pdflua.lua +++ /dev/null @@ -1,23 +0,0 @@ - --- this is early work in progress... - ------------------------------------------------------------------------- - -beginpage = function(a) -end - -endpage = function(a) -end - -outputpagestree = function() -end - ------------------------------------------------------------------------- - -local pdflua = { - beginpage = beginpage, - endpage = endpage, - outputpagestree = outputpagestree, -} - -return pdflua diff --git a/Build/source/texk/web2c/luatexdir/luascripts/txt2zlib.w b/Build/source/texk/web2c/luatexdir/luascripts/txt2zlib.w deleted file mode 100644 index 669125b7f26..00000000000 --- a/Build/source/texk/web2c/luatexdir/luascripts/txt2zlib.w +++ /dev/null @@ -1,143 +0,0 @@ -% txt2zlib.w -% -% Copyright 2010 Taco Hoekwater <taco@@luatex.org> -% Copyright 2010 Hartmut Henkel <hartmut@@luatex.org> -% -% This file is part of LuaTeX. -% -% LuaTeX is free software; you can redistribute it and/or modify it under -% the terms of the GNU General Public License as published by the Free -% Software Foundation; either version 2 of the License, or (at your -% option) any later version. -% -% LuaTeX is distributed in the hope that it will be useful, but WITHOUT -% ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -% FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public -% License for more details. -% -% You should have received a copy of the GNU General Public License along -% with LuaTeX; if not, see <http://www.gnu.org/licenses/>. - - -@ -@c - -#include<stdlib.h> -#include<stdio.h> -#include<string.h> -#include<zlib.h> - -#define INBUFINITLEN 10 -#define LINELEN 16 - -char header[] = - " Copyright 2010 Taco Hoekwater <taco@@luatex.org>\n" - " Copyright 2010 Hartmut Henkel <hartmut@@luatex.org>\n" - "\n" - " This file is part of LuaTeX.\n" - "\n" - " LuaTeX is free software; you can redistribute it and/or modify it under\n" - " the terms of the GNU General Public License as published by the Free\n" - " Software Foundation; either version 2 of the License, or (at your\n" - " option) any later version.\n" - "\n" - " LuaTeX is distributed in the hope that it will be useful, but WITHOUT\n" - " ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n" - " FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public\n" - " License for more details.\n" - "\n" - " You should have received a copy of the GNU General Public License along\n" - " with LuaTeX; if not, see <http://www.gnu.org/licenses/>."; - -#define NAMELEN 100 - -int main(int argc, char *argv[]) -{ - int i, j, c, err; - Byte *inbuf = NULL, *outbuf; - FILE *fin, *fout; - char ptrname[NAMELEN]; - uLong inbuflen, uncomprLen = 0, outbuflen, comprLen; - - if (argc != 3) { - fprintf(stderr, - "%s: need exactly two arguments (input file name, output file name).\n", - argv[0]); - exit(EXIT_FAILURE); - } - fin = fopen(argv[1], "r"); - if (fin == NULL) { - fprintf(stderr, "%s: can't open %s for reading.\n", argv[0], argv[1]); - exit(EXIT_FAILURE); - } - fout = fopen(argv[2], "wb"); - if (fout == NULL) { - fprintf(stderr, "%s: can't open %s for writing.\n", argv[0], argv[2]); - exit(EXIT_FAILURE); - } - if ((inbuf = malloc(INBUFINITLEN * sizeof(Byte))) == NULL) - exit(EXIT_FAILURE); - inbuflen = INBUFINITLEN; - while ((c = fgetc(fin)) != EOF) { - if (uncomprLen == inbuflen - 1) { - inbuflen = (uLong) ((double) inbuflen * 1.5 + 1); - if ((inbuf = realloc(inbuf, inbuflen)) == NULL) - exit(EXIT_FAILURE); - } - inbuf[uncomprLen] = (Byte) c; - uncomprLen++; - } - - outbuflen = comprLen = (uLong) ((double) uncomprLen * 1.1 + 50); - if ((outbuf = malloc(outbuflen * sizeof(Byte))) == NULL) - exit(EXIT_FAILURE); - - err = compress(outbuf, &comprLen, inbuf, uncomprLen); - - if (err != Z_OK) { - fprintf(stderr, "compress error: %d\n", err); - exit(EXIT_FAILURE); - } - - fprintf(fout, "/* %s\n\n", argv[2]); - fprintf(fout, "%s */\n\n", header); - fprintf(fout, "#include \"ptexlib.h\"\n\n"); - - fprintf(fout, "static const Byte compr[%ld] = {\n", comprLen); - for (i = 0, j = 0; (uLong) i < comprLen; i++) { - if (j == 0) - fprintf(fout, " "); - fprintf(fout, "0x%02x", outbuf[i]); - if ((uLong) i < comprLen - 1) { - fprintf(fout, ","); - if (j == LINELEN - 1) { - fprintf(fout, "\n"); - j = 0; - } else { - fprintf(fout, " "); - j++; - } - } - } - fprintf(fout, "\n};\n\n"); - - strncpy(ptrname, argv[2], NAMELEN - 20); - for (i = (int) strlen(ptrname) - 1; i > 0; i--) { - if (ptrname[i] == '.') { - ptrname[i] = '\0'; - break; - } - } - - strcat(ptrname, "_zlib_struct_ptr"); - - fprintf(fout, - "static const zlib_struct compr_struct = { %ld, %ld, compr };\n\n", - uncomprLen, comprLen); - - fprintf(fout, "const zlib_struct *%s = &compr_struct;\n", ptrname); - - fclose(fin); - fclose(fout); - return EXIT_SUCCESS; -} diff --git a/Build/source/texk/web2c/luatexdir/luatex-common.h b/Build/source/texk/web2c/luatexdir/luatex-common.h index 379c7b2f43c..073d6ad1c5b 100644 --- a/Build/source/texk/web2c/luatexdir/luatex-common.h +++ b/Build/source/texk/web2c/luatexdir/luatex-common.h @@ -25,9 +25,11 @@ # define LUATEX_COMMON_H /* utils.c */ -__attribute__ ((format(printf, 1, 2))) -extern void luatex_warn(const char *fmt, ...); -__attribute__ ((noreturn, format(printf, 1, 2))) -extern void luatex_fail(const char *fmt, ...); + +extern void tex_error(const char *msg, const char **hlp); +extern void normal_error(const char *t, const char *p); +extern void normal_warning(const char *t, const char *p); +extern void formatted_error(const char *t, const char *fmt, ...); +extern void formatted_warning(const char *t, const char *fmt, ...); #endif /* LUATEX_COMMON_H */ diff --git a/Build/source/texk/web2c/luatexdir/luatex.c b/Build/source/texk/web2c/luatexdir/luatex.c index 64393bad697..279d46faa50 100644 --- a/Build/source/texk/web2c/luatexdir/luatex.c +++ b/Build/source/texk/web2c/luatexdir/luatex.c @@ -2,7 +2,7 @@ written by Tim Morgan, drawing from other Unix ports of TeX. This is a collection of miscellany, everything that's easier (or only possible) to do in C. - + This file is public domain. */ /* This file is used to create texextra.c etc., with this line @@ -21,16 +21,17 @@ #include "ptexlib.h" #include "luatex.h" #include "lua/luatex-api.h" +/* #include "luatex_svnversion.h" +*/ #define TeX -int luatex_svn = luatex_svn_revision; -int luatex_version = 85; /* \.{\\luatexversion} */ +int luatex_version = 86; /* \.{\\luatexversion} */ int luatex_revision = '0'; /* \.{\\luatexrevision} */ -int luatex_date_info = 2015111900; /* the compile date is now hardwired */ -const char *luatex_version_string = "beta-0.85.0"; +int luatex_date_info = 2015120800; /* the compile date is now hardwired */ +const char *luatex_version_string = "beta-0.86.0"; const char *engine_name = my_name; /* the name of this engine */ #include <kpathsea/c-ctype.h> @@ -204,7 +205,7 @@ static int Isspace(char c) -1 : invalid quotation of an argument 0 : command is not allowed 2 : restricted shell escape, CMD is allowed. - + We set *SAFECMD to a safely-quoted version of *CMD; this is what should get executed. And we set CMDNAME to its first word; this is what is checked against the shell_escape_commands list. */ @@ -379,7 +380,7 @@ int shell_cmd_is_allowed(const char *cmd, char **safecmd, char **cmdname) strcat (q, (p + 2)); free (*safecmd); *safecmd = q; - } else if (!IS_DIR_SEP (p[0]) && !(p[1] == ':' && IS_DIR_SEP (p[2]))) { + } else if (!IS_DIR_SEP (p[0]) && !(p[1] == ':' && IS_DIR_SEP (p[2]))) { p = kpse_var_value ("SELFAUTOLOC"); if (p) { r = *safecmd; @@ -432,15 +433,15 @@ int runsystem(const char *cmd) allow = 1; else allow = shell_cmd_is_allowed(cmd, &safecmd, &cmdname); - + if (allow == 1) status = system(cmd); else if (allow == 2) status = system(safecmd); /* Not really meaningful, but we have to manage the return value of system. */ if (status==-1) - fprintf(stderr,"system returned with code -1\n"); - + fprintf(stderr,"system returned with code -1\n"); + if (safecmd) free(safecmd); if (cmdname) @@ -480,7 +481,7 @@ static void myInvalidParameterHandler(const wchar_t * expression, /* I return silently to avoid an exit with the error 0xc0000417 (invalid parameter) when we use non-embedded fonts in luatex-ja, - which works without any problem on Unix systems. + which works without any problem on Unix systems. I hope it is not dangerous. */ return; @@ -628,7 +629,7 @@ struct msg int namelength; /* length of auxiliary data */ int eof; /* new eof for dvi file */ #if 0 /* see usage of struct msg below */ - char more_data[0]; /* where the rest of the stuff goes */ + char more_data[0]; /* where the rest of the stuff goes */ #endif }; @@ -799,7 +800,7 @@ ipcpage (int is_eof) if (!begun) { string name; /* Just the filename. */ string cwd = xgetcwd (); - + ipc_open_out (); /* Have to pass whole filename to the other end, since it may have @@ -824,7 +825,7 @@ ipcpage (int is_eof) begun = true; } ipc_snd (len, is_eof, p); - + if (p) free (p); } diff --git a/Build/source/texk/web2c/luatexdir/luatexcallbackids.h b/Build/source/texk/web2c/luatexdir/luatexcallbackids.h index 368a0234014..e2010282075 100644 --- a/Build/source/texk/web2c/luatexdir/luatexcallbackids.h +++ b/Build/source/texk/web2c/luatexdir/luatexcallbackids.h @@ -44,7 +44,6 @@ typedef enum { start_page_number_callback, stop_page_number_callback, start_run_callback, stop_run_callback, define_font_callback, - token_filter_callback, pre_output_filter_callback, buildpage_filter_callback, hpack_filter_callback, vpack_filter_callback, @@ -64,6 +63,7 @@ typedef enum { show_error_message_callback, show_lua_error_hook_callback, show_warning_message_callback, hpack_quality_callback, vpack_quality_callback, + process_rule_callback, total_callbacks } callback_callback_types; @@ -91,6 +91,8 @@ extern void get_lua_boolean(const char *table, const char *name, boolean * targe extern void get_lua_number(const char *table, const char *name, int *target); extern void get_lua_string(const char *table, const char *name, char **target); +extern int lua_reader_callback(int callback_id, pointer *buffloc); + extern char *get_lua_name(int i); /* texfileio.c */ diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdfaction.h b/Build/source/texk/web2c/luatexdir/pdf/pdfaction.h index ed9ba48a2ce..3d7751351df 100644 --- a/Build/source/texk/web2c/luatexdir/pdf/pdfaction.h +++ b/Build/source/texk/web2c/luatexdir/pdf/pdfaction.h @@ -15,25 +15,30 @@ 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/>. */ + with LuaTeX; if not, see <http://www.gnu.org/licenses/>. +*/ #ifndef PDFACTION_H # define PDFACTION_H -/* increase count of references to this action. this is used to speed up - copy_node() */ +/* + Increase count of references to this action. this is used to speed up + copy_node(). +*/ # define add_action_ref(a) pdf_action_refcount((a))++ -/* decrease count of references to this action; free it if there is no reference - to this action */ +/* + Decrease count of references to this action; free it if there is no reference + to this action. +*/ -# define delete_action_ref(a) { \ +# define delete_action_ref(a) { \ if (pdf_action_refcount(a) == null) { \ - flush_node(a); \ - } else { \ - pdf_action_refcount(a)--; \ - } \ + flush_node(a); \ + } else { \ + pdf_action_refcount(a)--; \ + } \ } # define set_pdf_action_type(A,B) pdf_action_type(A)=B diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdfaction.w b/Build/source/texk/web2c/luatexdir/pdf/pdfaction.w index 65c1afcc352..bb0d6e06d50 100644 --- a/Build/source/texk/web2c/luatexdir/pdf/pdfaction.w +++ b/Build/source/texk/web2c/luatexdir/pdf/pdfaction.w @@ -19,16 +19,14 @@ @ @c - #include "ptexlib.h" @ read an action specification -@c -halfword scan_action(PDF pdf) + +@c halfword scan_action(PDF pdf) { - int p; + int p = new_node(whatsit_node, pdf_action_node); (void) pdf; - p = new_node(whatsit_node, pdf_action_node); if (scan_keyword("user")) set_pdf_action_type(p, pdf_action_user); else if (scan_keyword("goto")) @@ -38,12 +36,12 @@ halfword scan_action(PDF pdf) else normal_error("pdf backend", "action type missing"); if (pdf_action_type(p) == pdf_action_user) { - scan_pdf_ext_toks(); + scan_toks(false, true); set_pdf_action_tokens(p, def_ref); return p; } if (scan_keyword("file")) { - scan_pdf_ext_toks(); + scan_toks(false, true); set_pdf_action_file(p, def_ref); } if (scan_keyword("page")) { @@ -55,10 +53,10 @@ halfword scan_action(PDF pdf) normal_error("pdf backend", "page number must be positive"); set_pdf_action_id(p, cur_val); set_pdf_action_named_id(p, 0); - scan_pdf_ext_toks(); + scan_toks(false, true); set_pdf_action_tokens(p, def_ref); } else if (scan_keyword("name")) { - scan_pdf_ext_toks(); + scan_toks(false, true); set_pdf_action_named_id(p, 1); set_pdf_action_id(p, def_ref); } else if (scan_keyword("num")) { @@ -97,8 +95,8 @@ halfword scan_action(PDF pdf) } @ write an action specification -@c -void write_action(PDF pdf, halfword p) + +@c void write_action(PDF pdf, halfword p) { char *s; int d = 0; @@ -124,44 +122,30 @@ void write_action(PDF pdf, halfword p) } } switch (pdf_action_type(p)) { - case pdf_action_page: - pdf_dict_add_name(pdf, "S", "GoTo"); - if (pdf_action_file(p) == null) { - pdf_add_name(pdf, "D"); - pdf_begin_array(pdf); - pdf_add_ref(pdf, pdf_get_obj(pdf, obj_type_page, pdf_action_id(p), false)); - } else { - pdf_add_name(pdf, "D"); - pdf_begin_array(pdf); - pdf_print_int(pdf, pdf_action_id(p) - 1); - } - { - char *tokstr = tokenlist_to_cstring(pdf_action_tokens(p), true, NULL); - pdf_printf(pdf, " %s", tokstr); - pdf_end_array(pdf); - xfree(tokstr); - } - break; - case pdf_action_goto: - if (pdf_action_file(p) == null) { + case pdf_action_page: pdf_dict_add_name(pdf, "S", "GoTo"); - d = pdf_get_obj(pdf, obj_type_dest, pdf_action_id(p), pdf_action_named_id(p)); - } else - pdf_dict_add_name(pdf, "S", "GoToR"); - if (pdf_action_named_id(p) > 0) { - char *tokstr = tokenlist_to_cstring(pdf_action_id(p), true, NULL); - pdf_dict_add_string(pdf, "D", tokstr); - xfree(tokstr); - } else if (pdf_action_file(p) == null) { - pdf_dict_add_ref(pdf, "D", d); - } else { - normal_error("pdf backend","'goto' option cannot be used with both 'file' and 'num'"); - } - break; - case pdf_action_thread: - pdf_dict_add_name(pdf, "S", "Thread"); - if (pdf_action_file(p) == null) { - d = pdf_get_obj(pdf, obj_type_thread, pdf_action_id(p), pdf_action_named_id(p)); + if (pdf_action_file(p) == null) { + pdf_add_name(pdf, "D"); + pdf_begin_array(pdf); + pdf_add_ref(pdf, pdf_get_obj(pdf, obj_type_page, pdf_action_id(p), false)); + } else { + pdf_add_name(pdf, "D"); + pdf_begin_array(pdf); + pdf_print_int(pdf, pdf_action_id(p) - 1); + } + { + char *tokstr = tokenlist_to_cstring(pdf_action_tokens(p), true, NULL); + pdf_printf(pdf, " %s", tokstr); + pdf_end_array(pdf); + xfree(tokstr); + } + break; + case pdf_action_goto: + if (pdf_action_file(p) == null) { + pdf_dict_add_name(pdf, "S", "GoTo"); + d = pdf_get_obj(pdf, obj_type_dest, pdf_action_id(p), pdf_action_named_id(p)); + } else + pdf_dict_add_name(pdf, "S", "GoToR"); if (pdf_action_named_id(p) > 0) { char *tokstr = tokenlist_to_cstring(pdf_action_id(p), true, NULL); pdf_dict_add_string(pdf, "D", tokstr); @@ -169,10 +153,24 @@ void write_action(PDF pdf, halfword p) } else if (pdf_action_file(p) == null) { pdf_dict_add_ref(pdf, "D", d); } else { - pdf_dict_add_int(pdf, "D", pdf_action_id(p)); + normal_error("pdf backend","'goto' option cannot be used with both 'file' and 'num'"); } - } - break; + break; + case pdf_action_thread: + pdf_dict_add_name(pdf, "S", "Thread"); + if (pdf_action_file(p) == null) { + d = pdf_get_obj(pdf, obj_type_thread, pdf_action_id(p), pdf_action_named_id(p)); + if (pdf_action_named_id(p) > 0) { + char *tokstr = tokenlist_to_cstring(pdf_action_id(p), true, NULL); + pdf_dict_add_string(pdf, "D", tokstr); + xfree(tokstr); + } else if (pdf_action_file(p) == null) { + pdf_dict_add_ref(pdf, "D", d); + } else { + pdf_dict_add_int(pdf, "D", pdf_action_id(p)); + } + } + break; } pdf_end_dict(pdf); } diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdfannot.h b/Build/source/texk/web2c/luatexdir/pdf/pdfannot.h index 0b9ce5b9c12..2c862975db0 100644 --- a/Build/source/texk/web2c/luatexdir/pdf/pdfannot.h +++ b/Build/source/texk/web2c/luatexdir/pdf/pdfannot.h @@ -15,7 +15,8 @@ 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/>. */ + with LuaTeX; if not, see <http://www.gnu.org/licenses/>. +*/ #ifndef PDFANNOT_H @@ -23,10 +24,10 @@ /* data structure of annotations; words 1..4 represent the coordinates of the annotation */ -# define obj_annot_ptr obj_aux /* pointer to corresponding whatsit node */ +# define obj_annot_ptr obj_aux /* pointer to corresponding whatsit node */ # define set_pdf_annot_objnum(A,B) pdf_annot_objnum(A)=B -# define set_pdf_annot_data(A,B) pdf_annot_data(A)=B +# define set_pdf_annot_data(A,B) pdf_annot_data(A)=B extern void do_annot(PDF pdf, halfword p, halfword parent_box, scaledpos cur); extern void new_annot_whatsit(small_number w); diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdfannot.w b/Build/source/texk/web2c/luatexdir/pdf/pdfannot.w index 67bcc69a40c..6bbfec226e7 100644 --- a/Build/source/texk/web2c/luatexdir/pdf/pdfannot.w +++ b/Build/source/texk/web2c/luatexdir/pdf/pdfannot.w @@ -19,18 +19,17 @@ @ @c - #include "ptexlib.h" @ @c -#define tail cur_list.tail_field +#define tail cur_list.tail_field void do_annot(PDF pdf, halfword p, halfword parent_box, scaledpos cur) { scaled_whd alt_rule; int k; if (global_shipping_mode == SHIPPING_FORM) - normal_error("pdf backend", "annotations cannot be inside an XForm"); + normal_error("pdf backend", "annotations cannot be inside an xform"); if (doing_leaders) return; if (is_obj_scheduled(pdf, pdf_annot_objnum(p))) { @@ -47,8 +46,8 @@ void do_annot(PDF pdf, halfword p, halfword parent_box, scaledpos cur) } @ create a new whatsit node for annotation -@c -void new_annot_whatsit(small_number w) + +@c void new_annot_whatsit(small_number w) { scaled_whd alt_rule; new_whatsit(w); @@ -58,7 +57,7 @@ void new_annot_whatsit(small_number w) set_depth(tail, alt_rule.dp); if ((w == pdf_thread_node) || (w == pdf_start_thread_node)) { if (scan_keyword("attr")) { - scan_pdf_ext_toks(); + scan_toks(false, true); set_pdf_thread_attr(tail, def_ref); } else { set_pdf_thread_attr(tail, null); @@ -66,8 +65,9 @@ void new_annot_whatsit(small_number w) } } -@ @c -void scan_annot(PDF pdf) +@ scanning at the \TeX\ end + +@c void scan_annot(PDF pdf) { int k; if (scan_keyword("reserveobjnum")) { @@ -89,7 +89,7 @@ void scan_annot(PDF pdf) new_annot_whatsit(pdf_annot_node); obj_annot_ptr(pdf, k) = tail; set_pdf_annot_objnum(tail, k); - scan_pdf_ext_toks(); + scan_toks(false, true); set_pdf_annot_data(tail, def_ref); } pdf_last_annot = k; diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdfcolorstack.h b/Build/source/texk/web2c/luatexdir/pdf/pdfcolorstack.h index cab0a4cb0ae..dfd955c5e2c 100644 --- a/Build/source/texk/web2c/luatexdir/pdf/pdfcolorstack.h +++ b/Build/source/texk/web2c/luatexdir/pdf/pdfcolorstack.h @@ -15,15 +15,16 @@ 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/>. */ + with LuaTeX; if not, see <http://www.gnu.org/licenses/>. +*/ #ifndef PDFCOLORSTACK_H # define PDFCOLORSTACK_H # define set_pdf_colorstack_stack(A,B) pdf_colorstack_stack(A)=B -# define set_pdf_colorstack_cmd(A,B) pdf_colorstack_cmd(A)=B -# define set_pdf_colorstack_data(A,B) pdf_colorstack_data(A)=B +# define set_pdf_colorstack_cmd(A,B) pdf_colorstack_cmd(A)=B +# define set_pdf_colorstack_data(A,B) pdf_colorstack_data(A)=B # define STACK_INCREMENT 8 diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdfcolorstack.w b/Build/source/texk/web2c/luatexdir/pdf/pdfcolorstack.w index eb48ab89ca6..bcc7145c6ce 100644 --- a/Build/source/texk/web2c/luatexdir/pdf/pdfcolorstack.w +++ b/Build/source/texk/web2c/luatexdir/pdf/pdfcolorstack.w @@ -19,36 +19,36 @@ @ @c - #include "ptexlib.h" @* Color Stack and Matrix Transformation Support. - @ In the following array and especially stack data structures are used. They have the following properties: - \item{-} They automatically grow dynamically. - \item{-} The size never decreases. - \item{-} The variable with name ending in "size" contains the number how many - entries the data structure can hold. - \item{-} The variable with name ending in "used" contains the number of - actually used entries. - \item{-} Memory of strings in stack entries must be allocated and - freed if the stack is cleared. - +\item{-} They automatically grow dynamically. +\item{-} The size never decreases. +\item{-} The variable with name ending in "size" contains the number how many + entries the data structure can hold. +\item{-} The variable with name ending in "used" contains the number of + actually used entries. +\item{-} Memory of strings in stack entries must be allocated and + freed if the stack is cleared. @ Color Stack @c + #define MAX_COLORSTACKS 32768 -/* The colorstack number is stored in two bytes (info field of the node) */ -/* Condition (newcolorstack): |MAX_COLORSTACKS mod STACK_INCREMENT = 0| */ + +/* + The colorstack number is stored in two bytes (info field of the node); + condition (newcolorstack): |MAX_COLORSTACKS mod STACK_INCREMENT = 0| +*/ #define COLOR_DEFAULT "0 g 0 G" -/* |literal_mode|s, see pdftex.web */ -#define SET_ORIGIN 0 -#define DIRECT_PAGE 1 +#define SET_ORIGIN 0 +#define DIRECT_PAGE 1 #define DIRECT_ALWAYS 2 typedef struct { @@ -69,9 +69,9 @@ static colstack_type *colstacks = NULL; static int colstacks_size = 0; static int colstacks_used = 0; -@ Initialization is done, if the color stacks are used, - |init_colorstacks()| is defined as macro to avoid unnecessary - procedure calls. +@ Initialization is done, if the color stacks are used, |init_colorstacks()| is defined +as macro to avoid unnecessary procedure calls. + @c #define init_colorstacks() if (colstacks_size == 0) colstacks_first_init(); @@ -100,27 +100,26 @@ int colorstackused(void) return colstacks_used; } -@ |newcolorstack()| - A new color stack is setup with the given parameters. - The stack number is returned or -1 in case of error (no room). +@ A new color stack is setup with the given parameters. The stack number is returned +or -1 in case of error (no room). + @c int newcolorstack(const char *str, int literal_mode, boolean page_start) { colstack_type *colstack; int colstack_num; - init_colorstacks(); - /* make room */ if (colstacks_used == MAX_COLORSTACKS) { return -1; } if (colstacks_used == colstacks_size) { colstacks_size += STACK_INCREMENT; - /* If |(MAX_COLORSTACKS mod STACK_INCREMENT = 0)| then we don't - need to check the case that size overruns |MAX_COLORSTACKS|. */ - colstacks = - xreallocarray(colstacks, colstack_type, (unsigned) colstacks_size); + /* + If |(MAX_COLORSTACKS mod STACK_INCREMENT = 0)| then we don't + need to check the case that size overruns |MAX_COLORSTACKS|. + */ + colstacks = xreallocarray(colstacks, colstack_type, (unsigned) colstacks_size); } /* claim new color stack */ colstack_num = colstacks_used++; @@ -149,8 +148,8 @@ int newcolorstack(const char *str, int literal_mode, boolean page_start) #define get_colstack(n) (&colstacks[n]) @ Puts a string on top of the string pool and updates |pool_ptr|. -@c -static void put_cstring_on_str_pool(char *str) + +@c static void put_cstring_on_str_pool(char *str) { int save_selector = selector; selector = new_string; @@ -197,8 +196,7 @@ static int colorstackpush(int colstack_no, str_number s) if (global_shipping_mode == SHIPPING_PAGE) { if (colstack->page_used == colstack->page_size) { colstack->page_size += STACK_INCREMENT; - xretalloc(colstack->page_stack, (unsigned) colstack->page_size, - char *); + xretalloc(colstack->page_stack, (unsigned) colstack->page_size, char *); } colstack->page_stack[colstack->page_used++] = colstack->page_current; str = makecstring(s); @@ -211,8 +209,7 @@ static int colorstackpush(int colstack_no, str_number s) } else { if (colstack->form_used == colstack->form_size) { colstack->form_size += STACK_INCREMENT; - xretalloc(colstack->form_stack, (unsigned) colstack->form_size, - char *); + xretalloc(colstack->form_stack, (unsigned) colstack->form_size, char *); } colstack->form_stack[colstack->form_used++] = colstack->form_current; str = makecstring(s); @@ -230,11 +227,9 @@ static int colorstackpush(int colstack_no, str_number s) int colorstackpop(int colstack_no) { colstack_type *colstack = get_colstack(colstack_no); - if (global_shipping_mode == SHIPPING_PAGE) { if (colstack->page_used == 0) { - luatex_warn("pop empty color page stack %u", - (unsigned int) colstack_no); + formatted_warning("pdf backend","pop empty color page stack %u",(unsigned int) colstack_no); return colstack->literal_mode; } xfree(colstack->page_current); @@ -242,8 +237,7 @@ int colorstackpop(int colstack_no) put_cstring_on_str_pool(colstack->page_current); } else { if (colstack->form_used == 0) { - luatex_warn("pop empty color form stack %u", - (unsigned int) colstack_no); + formatted_warning("pdf backend","pop empty color form stack %u",(unsigned int) colstack_no); return colstack->literal_mode; } xfree(colstack->form_current); @@ -258,7 +252,6 @@ void colorstackpagestart(void) { int i, j; colstack_type *colstack; - if (global_shipping_mode == SHIPPING_PAGE) { /* see procedure |pdf_out_colorstack_startpage| */ return; @@ -283,7 +276,6 @@ void colorstackpagestart(void) int colorstackskippagestart(int colstack_no) { colstack_type *colstack = get_colstack(colstack_no); - if (!colstack->page_start) { return 1; } @@ -302,12 +294,9 @@ void pdf_out_colorstack(PDF pdf, halfword p) { int old_setting; str_number s; - int cmd; - int stack_no; - int literal_mode; - cmd = pdf_colorstack_cmd(p); - stack_no = pdf_colorstack_stack(p); - literal_mode = 0; + int cmd = pdf_colorstack_cmd(p); + int stack_no = pdf_colorstack_stack(p); + int literal_mode = 0; if (stack_no >= colorstackused()) { tprint_nl(""); tprint("Color stack "); @@ -317,30 +306,30 @@ void pdf_out_colorstack(PDF pdf, halfword p) return; } switch (cmd) { - case colorstack_set: - case colorstack_push: - old_setting = selector; - selector = new_string; - show_token_list(token_link(pdf_colorstack_data(p)), null, -1); - selector = old_setting; - s = make_string(); - if (cmd == colorstack_set) - literal_mode = colorstackset(stack_no, s); - else - literal_mode = colorstackpush(stack_no, s); - if (str_length(s) > 0) - pdf_literal(pdf, s, literal_mode, false); - flush_str(s); - return; - break; - case colorstack_pop: - literal_mode = colorstackpop(stack_no); - break; - case colorstack_current: - literal_mode = colorstackcurrent(stack_no); - break; - default: - break; + case colorstack_set: + case colorstack_push: + old_setting = selector; + selector = new_string; + show_token_list(token_link(pdf_colorstack_data(p)), null, -1); + selector = old_setting; + s = make_string(); + if (cmd == colorstack_set) + literal_mode = colorstackset(stack_no, s); + else + literal_mode = colorstackpush(stack_no, s); + if (str_length(s) > 0) + pdf_literal(pdf, s, literal_mode, false); + flush_str(s); + return; + break; + case colorstack_pop: + literal_mode = colorstackpop(stack_no); + break; + case colorstack_current: + literal_mode = colorstackcurrent(stack_no); + break; + default: + break; } if (cur_length > 0) { s = make_string(); @@ -352,13 +341,11 @@ void pdf_out_colorstack(PDF pdf, halfword p) @ @c void pdf_out_colorstack_startpage(PDF pdf) { - int i; - int max; int start_status; int literal_mode; str_number s; - i = 0; - max = colorstackused(); + int i = 0; + int max = colorstackused(); while (i < max) { start_status = colorstackskippagestart(i); if (start_status == 0) { diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdfdest.h b/Build/source/texk/web2c/luatexdir/pdf/pdfdest.h index 4c2f1911931..576baea0434 100644 --- a/Build/source/texk/web2c/luatexdir/pdf/pdfdest.h +++ b/Build/source/texk/web2c/luatexdir/pdf/pdfdest.h @@ -15,7 +15,8 @@ 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/>. */ + with LuaTeX; if not, see <http://www.gnu.org/licenses/>. +*/ #ifndef PDFDEST_H @@ -24,17 +25,18 @@ /* types of destinations */ typedef enum { - pdf_dest_xyz = 0, - pdf_dest_fit = 1, - pdf_dest_fith = 2, - pdf_dest_fitv = 3, - pdf_dest_fitb = 4, + pdf_dest_xyz = 0, + pdf_dest_fit = 1, + pdf_dest_fith = 2, + pdf_dest_fitv = 3, + pdf_dest_fitb = 4, pdf_dest_fitbh = 5, pdf_dest_fitbv = 6, - pdf_dest_fitr = 7 + pdf_dest_fitr = 7 } pdf_destination_types; /* max number of kids for balanced trees */ + # define name_tree_kids_max 32 /* max number of kids of node of name tree for name destinations */ /* data structure of destinations */ @@ -42,18 +44,16 @@ typedef enum { # define obj_dest_ptr obj_aux /* pointer to |pdf_dest_node| */ # define set_obj_dest_ptr(pdf,A,B) obj_dest_ptr(pdf,A)=B -# define set_pdf_dest_id(A,B) pdf_dest_id(A)=B +# define set_pdf_dest_id(A,B) pdf_dest_id(A)=B # define set_pdf_dest_named_id(A,B) pdf_dest_named_id(A)=B -# define set_pdf_dest_type(A,B) pdf_dest_type(A)=B +# define set_pdf_dest_type(A,B) pdf_dest_type(A)=B # define set_pdf_dest_xyz_zoom(A,B) pdf_dest_xyz_zoom(A)=B -# define inf_dest_names_size 1000 /* min size of the destination names table for PDF output */ -# define sup_dest_names_size 131072 /* max size of the destination names table for PDF output */ +# define inf_dest_names_size 1000 /* min size of the destination names table for PDF output */ +# define sup_dest_names_size 131072 /* max size of the destination names table for PDF output */ extern void append_dest_name(PDF, char *, int); extern void do_dest(PDF pdf, halfword p, halfword parent_box, scaledpos cur); -extern void warn_dest_dup(int id, small_number byname, const char *s1, - const char *s2); extern void write_out_pdf_mark_destinations(PDF); extern void scan_pdfdest(PDF); @@ -61,5 +61,4 @@ extern void init_dest_names(PDF); extern void sort_dest_names(PDF); extern int output_name_tree(PDF); - #endif diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdfdest.w b/Build/source/texk/web2c/luatexdir/pdf/pdfdest.w index 7aefc45288f..74e8e4b1f13 100644 --- a/Build/source/texk/web2c/luatexdir/pdf/pdfdest.w +++ b/Build/source/texk/web2c/luatexdir/pdf/pdfdest.w @@ -19,18 +19,16 @@ @ @c - #include "ptexlib.h" -@ Here we implement subroutines for work with objects and related things. -Some of them are used in former parts too, so we need to declare them -forward. +@ Here we implement subroutines for work with objects and related things. Some of +them are used in former parts too, so we need to declare them forward. @c void init_dest_names(PDF pdf) { pdf->dest_names_size = inf_dest_names_size; - pdf->dest_names = xmallocarray(dest_name_entry, inf_dest_names_size); /* will grow dynamically */ + pdf->dest_names = xmallocarray(dest_name_entry, inf_dest_names_size); /* will grow dynamically */ } @ @c @@ -38,45 +36,35 @@ void append_dest_name(PDF pdf, char *s, int n) { int a; if (pdf->dest_names_ptr == sup_dest_names_size) - overflow("number of destination names (dest_names_size)", - (unsigned) pdf->dest_names_size); + overflow("number of destination names (dest_names_size)",(unsigned) pdf->dest_names_size); if (pdf->dest_names_ptr == pdf->dest_names_size) { a = pdf->dest_names_size / 5; if (pdf->dest_names_size < sup_dest_names_size - a) pdf->dest_names_size = pdf->dest_names_size + a; else pdf->dest_names_size = sup_dest_names_size; - pdf->dest_names = - xreallocarray(pdf->dest_names, dest_name_entry, - (unsigned) pdf->dest_names_size); + pdf->dest_names = xreallocarray(pdf->dest_names, dest_name_entry, (unsigned) pdf->dest_names_size); } pdf->dest_names[pdf->dest_names_ptr].objname = xstrdup(s); pdf->dest_names[pdf->dest_names_ptr].objnum = n; pdf->dest_names_ptr++; } - @ When a destination is created we need to check whether another destination with the same identifier already exists and give a warning if needed. @c -void warn_dest_dup(int id, small_number byname, const char *s1, const char *s2) +static void warn_dest_dup(int id, small_number byname) { - normal_warning(s1, "destination with the same identifier (", false, false); if (byname > 0) { - tprint("name"); - print_mark(id); + char *ss = tokenlist_to_cstring(id, true, NULL); + formatted_warning("pdf backend", "ignoring duplicate destination with the name '%s'",ss); } else { - tprint("num"); - print_int(id); + formatted_warning("pdf backend", "ignoring duplicate destination with the num '%d'",id); } - tprint(") "); - tprint(s2); - print_ln(); - show_context(); + /* no longer the annoying context */ } - @ @c void do_dest(PDF pdf, halfword p, halfword parent_box, scaledpos cur) { @@ -84,13 +72,12 @@ void do_dest(PDF pdf, halfword p, halfword parent_box, scaledpos cur) scaled_whd alt_rule; int k; if (global_shipping_mode == SHIPPING_FORM) - normal_error("pdf backend", "destinations cannot be inside an XForm"); + normal_error("pdf backend", "destinations cannot be inside an xform"); if (doing_leaders) return; k = pdf_get_obj(pdf, obj_type_dest, pdf_dest_id(p), pdf_dest_named_id(p)); if (obj_dest_ptr(pdf, k) != null) { - warn_dest_dup(pdf_dest_id(p), (small_number) pdf_dest_named_id(p), - "pdf backend", "has been already used, duplicate ignored"); + warn_dest_dup(pdf_dest_id(p), (small_number) pdf_dest_named_id(p)); return; } obj_dest_ptr(pdf, k) = p; @@ -149,50 +136,50 @@ void write_out_pdf_mark_destinations(PDF pdf) pdf_begin_array(pdf); pdf_add_ref(pdf, pdf->last_page); switch (pdf_dest_type(i)) { - case pdf_dest_xyz: - pdf_add_name(pdf, "XYZ"); - pdf_add_mag_bp(pdf, pdf_ann_left(i)); - pdf_add_mag_bp(pdf, pdf_ann_top(i)); - if (pdf_dest_xyz_zoom(i) == null) { - pdf_add_null(pdf); - } else { - if (pdf->cave == 1) - pdf_out(pdf, ' '); - pdf_print_int(pdf, pdf_dest_xyz_zoom(i) / 1000); - pdf_out(pdf, '.'); - pdf_print_int(pdf, (pdf_dest_xyz_zoom(i) % 1000)); - pdf->cave = 1; - } - break; - case pdf_dest_fit: - pdf_add_name(pdf, "Fit"); - break; - case pdf_dest_fith: - pdf_add_name(pdf, "FitH"); - pdf_add_mag_bp(pdf, pdf_ann_top(i)); - break; - case pdf_dest_fitv: - pdf_add_name(pdf, "FitV"); - pdf_add_mag_bp(pdf, pdf_ann_left(i)); - break; - case pdf_dest_fitb: - pdf_add_name(pdf, "FitB"); - break; - case pdf_dest_fitbh: - pdf_add_name(pdf, "FitBH"); - pdf_add_mag_bp(pdf, pdf_ann_top(i)); - break; - case pdf_dest_fitbv: - pdf_add_name(pdf, "FitBV"); - pdf_add_mag_bp(pdf, pdf_ann_left(i)); - break; - case pdf_dest_fitr: - pdf_add_name(pdf, "FitR"); - pdf_add_rect_spec(pdf, i); - break; - default: - normal_error("pdf backend", "unknown dest type"); - break; + case pdf_dest_xyz: + pdf_add_name(pdf, "XYZ"); + pdf_add_bp(pdf, pdf_ann_left(i)); + pdf_add_bp(pdf, pdf_ann_top(i)); + if (pdf_dest_xyz_zoom(i) == null) { + pdf_add_null(pdf); + } else { + if (pdf->cave == 1) + pdf_out(pdf, ' '); + pdf_print_int(pdf, pdf_dest_xyz_zoom(i) / 1000); + pdf_out(pdf, '.'); + pdf_print_int(pdf, (pdf_dest_xyz_zoom(i) % 1000)); + pdf->cave = 1; + } + break; + case pdf_dest_fit: + pdf_add_name(pdf, "Fit"); + break; + case pdf_dest_fith: + pdf_add_name(pdf, "FitH"); + pdf_add_bp(pdf, pdf_ann_top(i)); + break; + case pdf_dest_fitv: + pdf_add_name(pdf, "FitV"); + pdf_add_bp(pdf, pdf_ann_left(i)); + break; + case pdf_dest_fitb: + pdf_add_name(pdf, "FitB"); + break; + case pdf_dest_fitbh: + pdf_add_name(pdf, "FitBH"); + pdf_add_bp(pdf, pdf_ann_top(i)); + break; + case pdf_dest_fitbv: + pdf_add_name(pdf, "FitBV"); + pdf_add_bp(pdf, pdf_ann_left(i)); + break; + case pdf_dest_fitr: + pdf_add_name(pdf, "FitR"); + pdf_add_rect_spec(pdf, i); + break; + default: + normal_error("pdf backend", "unknown dest type"); + break; } pdf_end_array(pdf); if (pdf_dest_named_id(i) > 0) @@ -222,7 +209,7 @@ void scan_pdfdest(PDF pdf) set_pdf_dest_id(cur_list.tail_field, cur_val); set_pdf_dest_named_id(cur_list.tail_field, 0); } else if (scan_keyword("name")) { - scan_pdf_ext_toks(); + scan_toks(false, true); set_pdf_dest_id(cur_list.tail_field, def_ref); set_pdf_dest_named_id(cur_list.tail_field, 1); } else { @@ -271,13 +258,10 @@ void scan_pdfdest(PDF pdf) k = find_obj(pdf, obj_type_dest, i, true); flush_str(i); } else { - k = find_obj(pdf, obj_type_dest, pdf_dest_id(cur_list.tail_field), - false); + k = find_obj(pdf, obj_type_dest, pdf_dest_id(cur_list.tail_field), false); } if ((k != 0) && (obj_dest_ptr(pdf, k) != null)) { - warn_dest_dup(pdf_dest_id(cur_list.tail_field), - (small_number) pdf_dest_named_id(cur_list.tail_field), - "pdf backend", "has been already used, duplicate ignored"); + warn_dest_dup(pdf_dest_id(cur_list.tail_field),(small_number) pdf_dest_named_id(cur_list.tail_field)); flush_node_list(cur_list.tail_field); cur_list.tail_field = q; vlink(q) = null; @@ -296,8 +280,7 @@ static int dest_cmp(const void *a, const void *b) @ @c void sort_dest_names(PDF pdf) { - qsort(pdf->dest_names, (size_t) pdf->dest_names_ptr, - sizeof(dest_name_entry), dest_cmp); + qsort(pdf->dest_names, (size_t) pdf->dest_names_ptr, sizeof(dest_name_entry), dest_cmp); } @ Output the name tree. The tree nature of the destination list forces the @@ -309,18 +292,18 @@ pointers. int output_name_tree(PDF pdf) { boolean is_names = true; /* flag for name tree output: is it Names or Kids? */ - int b = 0, j, l; int k = 0; /* index of current child of |l|; if |k < pdf_dest_names_ptr| then this is pointer to |dest_names| array; otherwise it is the pointer to |obj_tab| (object number) */ - int m; + int b = 0; + int m, j, l; int dests = 0; - int names_head = 0, names_tail = 0; + int names_head = 0; + int names_tail = 0; if (pdf->dest_names_ptr == 0) { goto DONE; } sort_dest_names(pdf); - while (true) { do { l = pdf_create_obj(pdf, obj_type_others, 0); /* create a new node */ @@ -385,7 +368,6 @@ int output_name_tree(PDF pdf) goto DONE; } } - DONE: if ((dests != 0) || (pdf_names_toks != null)) { m = pdf_create_obj(pdf, obj_type_others, 0); diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdffont.h b/Build/source/texk/web2c/luatexdir/pdf/pdffont.h index 78726a0aa9e..47f987dd685 100644 --- a/Build/source/texk/web2c/luatexdir/pdf/pdffont.h +++ b/Build/source/texk/web2c/luatexdir/pdf/pdffont.h @@ -15,7 +15,8 @@ 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/>. */ + with LuaTeX; if not, see <http://www.gnu.org/licenses/>. +*/ #ifndef PDFFONT_H diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdffont.w b/Build/source/texk/web2c/luatexdir/pdf/pdffont.w index 4a7319db8a3..b3f1605154c 100644 --- a/Build/source/texk/web2c/luatexdir/pdf/pdffont.w +++ b/Build/source/texk/web2c/luatexdir/pdf/pdffont.w @@ -21,7 +21,6 @@ @ @c - #include "ptexlib.h" @ As \pdfTeX{} should also act as a back-end driver, it needs to support virtual @@ -37,38 +36,38 @@ The |has_packet()| C macro checks for this condition. @c scaled_whd output_one_char(PDF pdf, halfword p) { - scaled_whd ci; /* the real width, height and depth of the character */ internal_font_number f = font(p); int c = character(p); int ex_glyph = ex_glyph(p)/1000; - ci = get_charinfo_whd(f, c); + scaled_whd ci = get_charinfo_whd(f, c); /* the real width, height and depth of the character */ if (!(char_exists(f,c))) { char_warning(f,c); return ci; } - //ci.wd = round_xn_over_d(ci.wd, 1000 + ex_glyph, 1000); ci.wd = ext_xn_over_d(ci.wd, 1000000 + ex_glyph(p), 1000000); switch (pdf->posstruct->dir) { - case dir_TLT: - break; - case dir_TRT: - pos_left(ci.wd); - break; - case dir_LTL: - pos_down(ci.ht); - pos_left(ci.wd); - break; - case dir_RTT: - pos_down(ci.ht); - pos_left(ci.wd / 2); - break; - default: - assert(0); + case dir_TLT: + break; + case dir_TRT: + pos_left(ci.wd); + break; + case dir_LTL: + pos_down(ci.ht); + pos_left(ci.wd); + break; + case dir_RTT: + pos_down(ci.ht); + pos_left(ci.wd / 2); + break; + default: + formatted_warning("pdf backend","ignoring bad dir %i when outputting a character",pdf->posstruct->dir); } if (has_packet(f, c)) { do_vf_packet(pdf, f, c, ex_glyph); - } else - backend_out[glyph_node] (pdf, f, c, ex_glyph); /* |pdf_place_glyph(pdf, f, c, ex_glyph);| */ + } else { + /* |pdf_place_glyph(pdf, f, c, ex_glyph);| */ + backend_out[glyph_node] (pdf, f, c, ex_glyph); + } return ci; } @@ -77,72 +76,59 @@ scaled_whd output_one_char(PDF pdf, halfword p) static void pdf_use_font(internal_font_number f, int fontnum) { set_font_used(f, true); - assert((fontnum > 0) || ((fontnum < 0) && (pdf_font_num(-fontnum) > 0))); - set_pdf_font_num(f, fontnum); + if ((fontnum > 0) || ((fontnum < 0) && (pdf_font_num(-fontnum) > 0))) { + set_pdf_font_num(f, fontnum); + } else { + normal_error("pdf backend","bad font id"); + } } -@ To set PDF font we need to find out fonts with the same name, because \TeX\ -can load the same font several times for various sizes. For such fonts we -define only one font resource. The array |pdf_font_num| holds the object -number of font resource. A negative value of an entry of |pdf_font_num| -indicates that the corresponding font shares the font resource with the font +@ To set PDF font we need to find out fonts with the same name, because \TeX\ can +load the same font several times for various sizes. For such fonts we define only +one font resource. The array |pdf_font_num| holds the object number of font +resource. A negative value of an entry of |pdf_font_num| indicates that the +corresponding font shares the font resource with the font @c #define same(n,f,k) (n(f) != NULL && n(k) != NULL && strcmp(n(f), n(k)) == 0) +/* + For some lua-loaded (for instance AFM) fonts, it is normal to have + a zero cidregistry, and such fonts do not have a fontmap entry yet + at this point, so the test should use the other branch +*/ + static boolean font_shareable(internal_font_number f, internal_font_number k) { - int ret = 0; - /* For some lua-loaded (for instance AFM) fonts, it is normal to have - a zero cidregistry, and such fonts do not have a fontmap entry yet - at this point, so the test should use the other branch */ - if (font_cidregistry(f) == NULL && font_cidregistry(k) == NULL && - font_encodingbytes(f) != 2 && font_encodingbytes(k) != 2) { - if (font_map(k) != NULL && - font_map(f) != NULL && (same(font_name, k, f))) { - ret = 1; + if (font_cidregistry(f) == NULL && font_cidregistry(k) == NULL && font_encodingbytes(f) != 2 && font_encodingbytes(k) != 2) { + if (font_map(k) != NULL && font_map(f) != NULL && (same(font_name, k, f))) { + return 1; } - } else { - if ((same(font_filename, k, f) && same(font_fullname, k, f))) { - ret = 1; - } -#ifdef DEBUG - printf("\nfont_shareable(%d:%s:%s,%d:%s:%s): => %d\n", - f, font_filename(f), font_fullname(f), - k, font_filename(k), font_fullname(k), ret); -#endif + } else if ((same(font_filename, k, f) && same(font_fullname, k, f))) { + return 1; } - return ret; + return 0; } @ create a font object @c void pdf_init_font(PDF pdf, internal_font_number f) { - internal_font_number k/*, b*/; + internal_font_number k; fm_entry *fm; int i, l; - assert(!font_used(f)); - - ///* if |f| is auto expanded then ensure the base font is initialized */ - // - // if (font_auto_expand(f) && ((b = pdf_font_blink(f)) != null_font)) { - // if (!font_used(b)) - // pdf_init_font(pdf, b); - // set_font_map(f, font_map(b)); - // /* propagate slant and extend from unexpanded base font */ - // set_font_slant(f, font_slant(b)); - // set_font_extend(f, font_extend(b)); - //} - /* check whether |f| can share the font object with some |k|: we have 2 cases - here: 1) |f| and |k| have the same tfm name (so they have been loaded at - different sizes, eg 'cmr10' and 'cmr10 at 11pt'); 2) |f| has been auto - expanded from |k| - */ - - /* take over slant and extend from map entry, if not already set; - this should also be the only place where getfontmap() may be called. */ - + if (font_used(f)) { + formatted_error("pdf backend","font %i gets initialized twice",(int) f); + } + /* + check whether |f| can share the font object with some |k|: we have 2 cases + here: 1) |f| and |k| have the same tfm name (so they have been loaded at + different sizes, eg 'cmr10' and 'cmr10 at 11pt'); 2) |f| has been auto + expanded from |k| + + take over slant and extend from map entry, if not already set; + this should also be the only place where getfontmap() may be called. + */ fm = getfontmap(font_name(f)); if (font_map(f) == NULL && fm != NULL) { font_map(f) = fm; @@ -155,7 +141,6 @@ void pdf_init_font(PDF pdf, internal_font_number f) while (i != 0) { k = obj_info(pdf, i); if (font_shareable(f, k)) { - assert(pdf_font_num(k) != 0); if (pdf_font_num(k) < 0) pdf_use_font(f, pdf_font_num(k)); else @@ -169,20 +154,18 @@ void pdf_init_font(PDF pdf, internal_font_number f) pdf_use_font(f, l); } -@ set the actual font on PDF page +@ set the actual font on PDF page; sets |ff| to the tfm number of the base font +sharing the font object with |f|; |ff| is either |f| itself (then it is its own +base font), or some font with the same tfm name at different size and/or +expansion. + @c internal_font_number pdf_set_font(PDF pdf, internal_font_number f) { - int ff; /* for use with |set_ff| */ + int ff; /* for use with |set_ff| */ if (!font_used(f)) pdf_init_font(pdf, f); - /* - set |ff| to the tfm number of the base font sharing the font object with |f|; - |ff| is either |f| itself (then it is its own base font), - or some font with the same tfm name at different size and/or expansion. - */ - ff = pdf_font_num(f) < 0 ? -pdf_font_num(f) : f; /* aka |set_ff(f)| */ - assert(pdf_font_num(ff) > 0); /* base font object number */ + ff = pdf_font_num(f) < 0 ? -pdf_font_num(f) : f; /* aka |set_ff(f)| */ addto_page_resources(pdf, obj_type_font, pdf_font_num(ff)); return ff; } @@ -191,7 +174,7 @@ internal_font_number pdf_set_font(PDF pdf, internal_font_number f) void pdf_include_chars(PDF pdf) { str_number s; - unsigned char *k, *j; /* running index */ + unsigned char *k, *j; /* running index */ internal_font_number f; scan_font_ident(); f = cur_val; @@ -200,7 +183,7 @@ void pdf_include_chars(PDF pdf) pdf_check_vf(cur_val); if (!font_used(f)) pdf_init_font(pdf, f); - scan_pdf_ext_toks(); + scan_toks(false, true); s = tokens_to_string(def_ref); delete_token_ref(def_ref); j = str_string(s) + str_length(s); diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdfgen.h b/Build/source/texk/web2c/luatexdir/pdf/pdfgen.h index d0677c1748f..0a8e099b177 100644 --- a/Build/source/texk/web2c/luatexdir/pdf/pdfgen.h +++ b/Build/source/texk/web2c/luatexdir/pdf/pdfgen.h @@ -15,8 +15,8 @@ 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/>. */ - + with LuaTeX; if not, see <http://www.gnu.org/licenses/>. +*/ #ifndef PDFGEN_H # define PDFGEN_H @@ -27,46 +27,49 @@ # define PROCSET_IMAGE_C (1 << 3) # define PROCSET_IMAGE_I (1 << 4) -# define inf_pdf_mem_size 10000/* min size of the |mem| array */ -# define sup_pdf_mem_size 10000000 /* max size of the |mem| array */ +# define inf_pdf_mem_size 10000 /* min size of the |mem| array */ +# define sup_pdf_mem_size 10000000 /* max size of the |mem| array */ extern PDF static_pdf; extern int pdf_get_mem(PDF pdf, int s); /* -We use the similiar subroutines to handle the output buffer for -PDF output. When compress is used, the state of writing to buffer -is held in |zip_write_state|. We must write the header of PDF -output file in initialization to ensure that it will be the first -written bytes. + +We use the similiar subroutines to handle the output buffer for PDF output. When +compress is used, the state of writing to buffer is held in |zip_write_state|. We +must write the header of PDF output file in initialization to ensure that it will +be the first written bytes. + */ -# define inf_pdfout_buf_size 16384 /* initial value of |pdf->buf| size */ -# define sup_pdfout_buf_size 16384 /* arbitrary upper hard limit of |pdf->buf| size */ -# define inf_objstm_buf_size 1 /* initial value of |os->buf[OBJSTM_BUF]| size */ -# define sup_objstm_buf_size 5000000 /* arbitrary upper hard limit of |os->buf[OBJSTM_BUF]| size */ +# define inf_pdfout_buf_size 16384 /* initial value of |pdf->buf| size */ +# define sup_pdfout_buf_size 16384 /* arbitrary upper hard limit of |pdf->buf| size */ +# define inf_objstm_buf_size 1 /* initial value of |os->buf[OBJSTM_BUF]| size */ +# define sup_objstm_buf_size 5000000 /* arbitrary upper hard limit of |os->buf[OBJSTM_BUF]| size */ -# define PDF_OS_MAX_OBJS 100 /* maximum number of objects in object stream */ +# define PDF_OS_MAX_OBJS 100 /* maximum number of objects in object stream */ -# define inf_obj_tab_size 1000 /* min size of the cross-reference table for PDF output */ -# define sup_obj_tab_size 8388607 /* max size of the cross-reference table for PDF output */ +# define inf_obj_tab_size 1000 /* min size of the cross-reference table for PDF output */ +# define sup_obj_tab_size 8388607 /* max size of the cross-reference table for PDF output */ /* The following macros are similar as for \.{DVI} buffer handling */ # define pdf_offset(pdf) (pdf->gone + (off_t)(pdf->buf->p - pdf->buf->data)) - /* the file offset of last byte in PDF - buffer that |pdf_ptr| points to */ # define pdf_save_offset(pdf) pdf->save_offset = (pdf->gone + (off_t)(pdf->buf->p - pdf->buf->data)) -# define set_ff(A) do { \ - if (pdf_font_num(A) < 0) \ - ff = -pdf_font_num(A); \ - else \ - ff = A; \ - } while (0) +# define set_ff(A) do { \ + if (pdf_font_num(A) < 0) \ + ff = -pdf_font_num(A); \ + else \ + ff = A; \ +} while (0) -typedef enum { NOT_SHIPPING, SHIPPING_PAGE, SHIPPING_FORM } shipping_mode_e; /* needs pdf_prefix */ +typedef enum { /* needs pdf_prefix */ + NOT_SHIPPING, + SHIPPING_PAGE, + SHIPPING_FORM +} shipping_mode_e; extern scaled one_hundred_inch; extern scaled one_inch; @@ -80,29 +83,36 @@ extern void pdf_room(PDF, int); extern void fix_pdf_minorversion(PDF); - /* output a byte to PDF buffer without checking of overflow */ +/* output a byte to PDF buffer without checking of overflow */ + # define pdf_quick_out(pdf,A) * (pdf->buf->p++) = (unsigned char) (A) /* do the same as |pdf_quick_out| and flush the PDF buffer if necessary */ -# define pdf_out(pdf,A) do { pdf_room(pdf, 1); pdf_quick_out(pdf, A); } while (0) + +# define pdf_out(pdf,A) do { \ + pdf_room(pdf, 1); \ + pdf_quick_out(pdf, A); \ +} while (0) /* + Basic printing procedures for PDF output are very similiar to \TeX\ basic -printing ones but the output is going to PDF buffer. Subroutines with -suffix |_ln| append a new-line character to the PDF output. +printing ones but the output is going to PDF buffer. Subroutines with suffix +|_ln| append a new-line character to the PDF output. + */ -/* print out a string to PDF buffer followed by a new-line character */ -# define pdf_print_ln(pdf,A) do { \ - pdf_print(pdf,A); \ - pdf_out(pdf, '\n'); \ - } while (0) +# define pdf_print_ln(pdf,A) do { \ + pdf_print(pdf,A); \ + pdf_out(pdf, '\n'); \ +} while (0) /* print out an integer to PDF buffer followed by a new-line character */ -# define pdf_print_int_ln(pdf,A) do { \ - pdf_print_int(pdf,A); \ - pdf_out(pdf, '\n'); \ - } while (0) + +# define pdf_print_int_ln(pdf,A) do { \ + pdf_print_int(pdf,A); \ + pdf_out(pdf, '\n'); \ +} while (0) extern __attribute__ ((format(printf, 2, 3))) void pdf_printf(PDF, const char *, ...); @@ -131,7 +141,6 @@ extern void pdf_begin_stream(PDF); extern void pdf_end_stream(PDF); extern void pdf_add_bp(PDF, scaled); -extern void pdf_add_mag_bp(PDF, scaled); extern strbuf_s *new_strbuf(size_t size, size_t limit); extern void strbuf_seek(strbuf_s * b, off_t offset); @@ -149,10 +158,10 @@ extern void pdf_out_block(PDF pdf, const char *s, size_t n); # define pdf_puts(pdf, s) pdf_out_block((pdf), (s), strlen(s)) -# define pdf_print_resname_prefix(pdf) do { \ - if (pdf->resname_prefix != NULL) \ - pdf_puts(pdf, pdf->resname_prefix); \ - } while (0) +# define pdf_print_resname_prefix(pdf) do { \ + if (pdf->resname_prefix != NULL) \ + pdf_puts(pdf, pdf->resname_prefix); \ +} while (0) extern void pdf_print_str_ln(PDF, const char *); @@ -195,15 +204,14 @@ extern int get_pdf_table_bool(PDF, const char *, int); extern void ensure_output_state(PDF pdf, output_state s); extern PDF init_pdf_struct(PDF pdf); -extern halfword pdf_info_toks; /* additional keys of Info dictionary */ +extern halfword pdf_info_toks; /* additional keys of Info dictionary */ extern halfword pdf_catalog_toks; /* additional keys of Catalog dictionary */ extern halfword pdf_catalog_openaction; -extern halfword pdf_names_toks; /* additional keys of Names dictionary */ +extern halfword pdf_names_toks; /* additional keys of Names dictionary */ extern halfword pdf_trailer_toks; /* additional keys of Trailer dictionary */ extern void scan_pdfcatalog(PDF pdf); -extern void finish_pdf_file(PDF pdf, int luatex_version, - str_number luatex_revision); +extern void finish_pdf_file(PDF pdf, int luatex_version, str_number luatex_revision); extern shipping_mode_e global_shipping_mode; -#endif /* PDFGEN_H */ +#endif diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdfgen.w b/Build/source/texk/web2c/luatexdir/pdf/pdfgen.w index f9a96aac808..94bfbaddcbf 100644 --- a/Build/source/texk/web2c/luatexdir/pdf/pdfgen.w +++ b/Build/source/texk/web2c/luatexdir/pdf/pdfgen.w @@ -30,11 +30,12 @@ #define check_nprintf(size_get, size_want) \ if ((unsigned)(size_get) >= (unsigned)(size_want)) \ - luatex_fail ("snprintf failed: file %s, line %d", __FILE__, __LINE__); + formatted_error("pdf backend","snprintf() failed in file %s at line %d", __FILE__, __LINE__); PDF static_pdf = NULL; @ commandline interface + @c int output_mode_used; int output_mode_option; @@ -42,12 +43,12 @@ int output_mode_value; int draft_mode_option; int draft_mode_value; -halfword pdf_info_toks; /* additional keys of Info dictionary */ -halfword pdf_catalog_toks; /* additional keys of Catalog dictionary */ +halfword pdf_info_toks; /* additional keys of Info dictionary */ +halfword pdf_catalog_toks; /* additional keys of Catalog dictionary */ halfword pdf_catalog_openaction; -halfword pdf_names_toks; /* additional keys of Names dictionary */ -halfword pdf_trailer_toks; /* additional keys of Trailer dictionary */ -shipping_mode_e global_shipping_mode = NOT_SHIPPING; /* set to |shipping_mode| when |ship_out| starts */ +halfword pdf_names_toks; /* additional keys of Names dictionary */ +halfword pdf_trailer_toks; /* additional keys of Trailer dictionary */ +shipping_mode_e global_shipping_mode = NOT_SHIPPING; /* set to |shipping_mode| when |ship_out| starts */ @ Create a new buffer |strbuf_s| of size |size| and maximum allowed size |limit|. Initialize it and set |p| to begin of data. @@ -56,14 +57,13 @@ Initialize it and set |p| to begin of data. strbuf_s *new_strbuf(size_t size, size_t limit) { strbuf_s *b; - assert(limit >= size); b = xtalloc(1, strbuf_s); b->size = size; b->limit = limit; if (size > 0) b->p = b->data = xtalloc(b->size, unsigned char); else - b->p = b->data = NULL; /* for other alloc */ + b->p = b->data = NULL; /* for other alloc */ return b; } @@ -94,7 +94,6 @@ static void strbuf_room(strbuf_s * b, size_t n) @c void strbuf_seek(strbuf_s * b, off_t offset) { - assert(offset >= 0 && offset < (off_t) b->size); b->p = b->data + offset; } @@ -140,12 +139,11 @@ void strbuf_free(strbuf_s * b) PDF init_pdf_struct(PDF pdf) { os_struct *os; - assert(pdf == NULL); pdf = xtalloc(1, pdf_output_file); memset(pdf, 0, sizeof(pdf_output_file)); pdf->job_name = makecstring(job_name); - output_mode_used = OMODE_NONE; /* will be set by |fix_o_mode()| */ + output_mode_used = OMODE_NONE; /* will be set by |fix_o_mode()| */ pdf->o_mode = output_mode_used; /* used by synctex, we need to use output_mode_used there */ pdf->o_state = ST_INITIAL; @@ -159,20 +157,27 @@ PDF init_pdf_struct(PDF pdf) os->curbuf = PDFOUT_BUF; pdf->buf = os->buf[os->curbuf]; - - /* Later ttf_seek_outbuf(TABDIR_OFF + n * 4 * TTF_ULONG_SIZE) */ - /* in ttf_init_font will need 236 bytes, so we start with 256 bytes as in pdftex. */ + /* + Later ttf_seek_outbuf(TABDIR_OFF + n * 4 * TTF_ULONG_SIZE); in ttf_init_font + we need 236 bytes, so we start with 256 bytes as in pdftex. + */ pdf->fb = new_strbuf(256, 100000000); pdf->stream_deflate = false; pdf->stream_writing = false; - /* Sometimes it is neccesary to allocate memory for PDF output that cannot - be deallocated then, so we use |mem| for this purpose. */ - pdf->mem_size = inf_pdf_mem_size; /* allocated size of |mem| array */ + /* + Sometimes it is neccesary to allocate memory for PDF output that cannot be + deallocated then, so we use |mem| for this purpose. + */ + pdf->mem_size = inf_pdf_mem_size; pdf->mem = xtalloc(pdf->mem_size, int); - pdf->mem_ptr = 1; /* the first word is not used so we can use zero as a value for testing - whether a pointer to |mem| is valid */ + /* + The first word is not used so we can use zero as a value for testing + whether a pointer to |mem| is valid. + */ + pdf->mem_ptr = 1; + pdf->pstruct = NULL; pdf->posstruct = xtalloc(1, posstructure); @@ -180,11 +185,12 @@ PDF init_pdf_struct(PDF pdf) pdf->posstruct->pos.v = 0; pdf->posstruct->dir = dir_TLT; - pdf->obj_tab_size = (unsigned) inf_obj_tab_size; /* allocated size of |obj_tab| array */ + /* allocated size of |obj_tab| array */ + pdf->obj_tab_size = (unsigned) inf_obj_tab_size; pdf->obj_tab = xtalloc(pdf->obj_tab_size + 1, obj_entry); memset(pdf->obj_tab, 0, sizeof(obj_entry)); - pdf->minor_version = -1; /* unset */ + pdf->minor_version = -1; pdf->decimal_digits = 4; pdf->gamma = 65536; pdf->image_gamma = 65536; @@ -194,7 +200,6 @@ PDF init_pdf_struct(PDF pdf) pdf->compress_level = 0; pdf->draftmode = 0; pdf->inclusion_copy_font = 1; - pdf->replace_font = 0; pdf->pk_resolution = 0; pdf->pk_scale_factor = 0; @@ -202,7 +207,6 @@ PDF init_pdf_struct(PDF pdf) pdf->page_resources = NULL; init_pdf_pagecalculations(pdf); - pdf->pdflua_ref = new_pdflua(); pdf->vfstruct = new_vfstruct(); @@ -213,11 +217,11 @@ PDF init_pdf_struct(PDF pdf) @c int pdf_get_mem(PDF pdf, int s) -{ /* allocate |s| words in |mem| */ +{ int a; int ret; if (s > sup_pdf_mem_size - pdf->mem_ptr) - overflow("PDF memory size (pdf_mem_size)", (unsigned) pdf->mem_size); + overflow("pdf memory size (pdf_mem_size)", (unsigned) pdf->mem_size); if (pdf->mem_ptr + s > pdf->mem_size) { a = pdf->mem_size >> 2; if (pdf->mem_ptr + s > pdf->mem_size + a) { @@ -258,10 +262,10 @@ void fix_o_mode(void) } } -@ This ensures that |pdfminorversion| is set only before any bytes have -been written to the generated \.{PDF} file. Here also all variables for -\.{PDF} output are initialized, the \.{PDF} file is opened by |ensure_pdf_open|, -and the \.{PDF} header is written. +@ This ensures that |pdfminorversion| is set only before any bytes have been +written to the generated \.{PDF} file. Here also all variables for \.{PDF} output +are initialized, the \.{PDF} file is opened by |ensure_pdf_open|, and the \.{PDF} +header is written. @c void fix_pdf_minorversion(PDF pdf) @@ -292,9 +296,9 @@ void fix_pdf_minorversion(PDF pdf) @ @c #define ZIP_BUF_SIZE 32768 -#define check_err(f, fn) \ - if (f != Z_OK) \ - luatex_fail("zlib: %s() failed (error code %d)", fn, f) +#define check_err(f, fn) \ + if (f != Z_OK) \ + formatted_error("pdf backend","zlib %s() failed (error code %d)", fn, f) @ @c static void write_zip(PDF pdf) @@ -304,15 +308,6 @@ static void write_zip(PDF pdf) strbuf_s *buf = pdf->buf; z_stream *s = pdf->c_stream; boolean finish = pdf->zip_write_state == ZIP_FINISH; - assert(pdf->compress_level > 0); - /* This was just to suppress the filename report in |luatex_fail| - but zlib errors are rare enough (especially now that the - compress level is fixed) that I don't care about the slightly - ugly error message that could result. - */ -#if 0 - cur_file_name = NULL; -#endif if (pdf->stream_length == 0) { if (s == NULL) { s = pdf->c_stream = xtalloc(1, z_stream); @@ -320,15 +315,12 @@ static void write_zip(PDF pdf) s->zfree = (free_func) 0; s->opaque = (voidpf) 0; check_err(deflateInit(s, pdf->compress_level), "deflateInit"); - assert(pdf->zipbuf == NULL); pdf->zipbuf = xtalloc(ZIP_BUF_SIZE, char); } else check_err(deflateReset(s), "deflateReset"); s->next_out = (Bytef *) pdf->zipbuf; s->avail_out = ZIP_BUF_SIZE; } - assert(s != NULL); - assert(pdf->zipbuf != NULL); s->next_in = buf->data; s->avail_in = (uInt) (buf->p - buf->data); while (true) { @@ -341,8 +333,6 @@ static void write_zip(PDF pdf) } if (finish) { if (err == Z_STREAM_END) { - assert(s->avail_in == 0); - assert(s->avail_out == ZIP_BUF_SIZE); xfflush(pdf->file); pdf->zip_write_state = NO_ZIP; break; @@ -355,7 +345,7 @@ static void write_zip(PDF pdf) } err = deflate(s, flush); if (err != Z_OK && err != Z_STREAM_END) - luatex_fail("zlib: deflate() failed (error code %d)", err); + formatted_error("pdf backend","zlib deflate() failed (error code %d)", err); } pdf->stream_length = (off_t) s->total_out; } @@ -378,8 +368,7 @@ static void write_nozip(PDF pdf) if (l == 0) return; pdf->stream_length = pdf_offset(pdf) - pdf->save_offset; - pdf->gone += - (off_t) xfwrite((char *) buf->data, sizeof(char), l, pdf->file); + pdf->gone += (off_t) xfwrite((char *) buf->data, sizeof(char), l, pdf->file); pdf->last_byte = *(buf->p - 1); } @@ -390,34 +379,33 @@ to finish it. The stream contents will be compressed if compression is turn on. @c void pdf_flush(PDF pdf) -{ /* flush out the |pdf->buf| */ +{ os_struct *os = pdf->os; off_t saved_pdf_gone = pdf->gone; - assert(pdf->buf == os->buf[os->curbuf]); switch (os->curbuf) { - case PDFOUT_BUF: - if (pdf->draftmode == 0) { - switch (pdf->zip_write_state) { - case NO_ZIP: - write_nozip(pdf); - break; - case ZIP_WRITING: - case ZIP_FINISH: - write_zip(pdf); - break; - default: - assert(0); - } - } else - pdf->zip_write_state = NO_ZIP; - strbuf_seek(pdf->buf, 0); - if (saved_pdf_gone > pdf->gone) - normal_error("pdf backend", "file size exceeds architectural limits (pdf_gone wraps around)"); - break; - case OBJSTM_BUF: - break; - default: - assert(0); + case PDFOUT_BUF: + if (pdf->draftmode == 0) { + switch (pdf->zip_write_state) { + case NO_ZIP: + write_nozip(pdf); + break; + case ZIP_WRITING: + case ZIP_FINISH: + write_zip(pdf); + break; + default: + normal_error("pdf backend", "bad zip state"); + } + } else + pdf->zip_write_state = NO_ZIP; + strbuf_seek(pdf->buf, 0); + if (saved_pdf_gone > pdf->gone) + normal_error("pdf backend", "file size exceeds architectural limits (pdf_gone wraps around)"); + break; + case OBJSTM_BUF: + break; + default: + normal_error("pdf backend", "bad buffer state"); } } @@ -426,9 +414,9 @@ static void pdf_buffer_select(PDF pdf, buffer_e buf) { os_struct *os = pdf->os; if (pdf->os_enable && buf == OBJSTM_BUF) - os->curbuf = OBJSTM_BUF; /* switch to object stream */ + os->curbuf = OBJSTM_BUF; /* switch to object stream */ else - os->curbuf = PDFOUT_BUF; /* switch to PDF stream */ + os->curbuf = PDFOUT_BUF; /* switch to PDF stream */ pdf->buf = os->buf[pdf->os->curbuf]; } @@ -439,64 +427,53 @@ static void pdf_prepare_obj(PDF pdf, int k, int pdf_os_threshold) { os_struct *os = pdf->os; strbuf_s *obuf = os->buf[OBJSTM_BUF]; - assert(pdf_os_threshold >= OBJSTM_ALWAYS); if (pdf->objcompresslevel >= pdf_os_threshold) pdf_buffer_select(pdf, OBJSTM_BUF); else pdf_buffer_select(pdf, PDFOUT_BUF); - assert(pdf->buf == os->buf[os->curbuf]); switch (os->curbuf) { - case PDFOUT_BUF: - obj_offset(pdf, k) = pdf_offset(pdf); - obj_os_idx(pdf, k) = PDF_OS_MAX_OBJS; /* mark it as not included in any ObjStm */ - break; - case OBJSTM_BUF: - if (os->cur_objstm == 0) { - os->cur_objstm = - (unsigned int) pdf_create_obj(pdf, obj_type_objstm, 0); - os->idx = 0; - obuf->p = obuf->data; /* start fresh object stream */ - os->ostm_ctr++; /* only for statistics */ - } - assert(os->idx < PDF_OS_MAX_OBJS); /* for marking below */ - obj_os_idx(pdf, k) = (int) os->idx; - obj_os_objnum(pdf, k) = (int) os->cur_objstm; - os->obj[os->idx].num = k; - os->obj[os->idx].off = obuf->p - obuf->data; - break; - default: - assert(0); + case PDFOUT_BUF: + obj_offset(pdf, k) = pdf_offset(pdf); + obj_os_idx(pdf, k) = PDF_OS_MAX_OBJS; /* mark it as not included in any ObjStm */ + break; + case OBJSTM_BUF: + if (os->cur_objstm == 0) { + os->cur_objstm = + (unsigned int) pdf_create_obj(pdf, obj_type_objstm, 0); + os->idx = 0; + obuf->p = obuf->data; /* start fresh object stream */ + os->ostm_ctr++; /* only for statistics */ + } + obj_os_idx(pdf, k) = (int) os->idx; + obj_os_objnum(pdf, k) = (int) os->cur_objstm; + os->obj[os->idx].num = k; + os->obj[os->idx].off = obuf->p - obuf->data; + break; + default: + normal_error("pdf backend", "bad object state"); } } @* Low-level buffer checkers. -@ Set the active buffer pointer. -Make sure that there are at least |n| bytes free in that buffer, -flush if needed. +@ Set the active buffer pointer. Make sure that there are at least |n| bytes free +in that buffer, flush if needed. @c -void pdf_room(PDF pdf, int n) +inline void pdf_room(PDF pdf, int n) { - os_struct *os = pdf->os; strbuf_s *buf = pdf->buf; if ((size_t) (n + buf->p - buf->data) <= buf->size) return; - assert(buf == os->buf[os->curbuf]); - switch (os->curbuf) { - case PDFOUT_BUF: + if (pdf->os->curbuf == PDFOUT_BUF) { if ((size_t) n > buf->size) overflow("PDF output buffer", (unsigned) buf->size); if ((size_t) (n + buf->p - buf->data) < buf->limit) - strbuf_room(buf, (size_t) n); /* grow it if possible */ + strbuf_room(buf, (size_t) n); else pdf_flush(pdf); - break; - case OBJSTM_BUF: - strbuf_room(buf, (size_t) n); /* just grow it */ - break; - default: - assert(0); + } else { + strbuf_room(buf, (size_t) n); } } @@ -543,7 +520,6 @@ void pdf_print(PDF pdf, str_number s) l = str_length(s); pdf_out_block(pdf, ss, l); } else { - assert(s < 256); pdf_out(pdf, s); } } @@ -564,7 +540,7 @@ void pdf_print_int(PDF pdf, longinteger n) void print_pdffloat(PDF pdf, pdffloat f) { char a[24]; - int e = f.e, i, j, l; + int e = f.e, i, l; int64_t m = f.m; if (m < 0) { pdf_out(pdf, '-'); @@ -575,8 +551,7 @@ void print_pdffloat(PDF pdf, pdffloat f) l = m % ten_pow[e]; if (l != 0) { pdf_out(pdf, '.'); - j = snprintf(a, 23, "%d", l + ten_pow[e]); - assert(j < 23); + snprintf(a, 23, "%d", l + ten_pow[e]); for (i = e; i > 0; i--) { if (a[i] != '0') break; @@ -592,7 +567,7 @@ void print_pdffloat(PDF pdf, pdffloat f) void pdf_print_str(PDF pdf, const char *s) { const char *orig = s; - int l = (int) strlen(s) - 1; /* last string index */ + int l = (int) strlen(s) - 1; /* last string index */ if (l < 0) { pdf_puts(pdf, "()"); return; @@ -617,7 +592,7 @@ void pdf_print_str(PDF pdf, const char *s) pdf_out(pdf, ')'); return; } - pdf_puts(pdf, orig); /* it was a hex string after all */ + pdf_puts(pdf, orig); /* it was a hex string after all */ } @ begin a stream (needs to have a stream dictionary also) @@ -625,15 +600,10 @@ void pdf_print_str(PDF pdf, const char *s) @c void pdf_begin_stream(PDF pdf) { - os_struct *os = pdf->os; - assert(os->curbuf == PDFOUT_BUF); - assert(pdf->buf == os->buf[os->curbuf]); - assert(pdf->zip_write_state == NO_ZIP); pdf_puts(pdf, "\nstream\n"); pdf_save_offset(pdf); pdf_flush(pdf); if (pdf->stream_deflate) { - assert(pdf->compress_level > 0); pdf->zip_write_state = ZIP_WRITING; } pdf->stream_writing = true; @@ -647,30 +617,25 @@ void pdf_begin_stream(PDF pdf) void pdf_end_stream(PDF pdf) { os_struct *os = pdf->os; - assert(pdf->buf == os->buf[os->curbuf]); switch (os->curbuf) { - case PDFOUT_BUF: - if (pdf->zip_write_state == ZIP_WRITING) - pdf->zip_write_state = ZIP_FINISH; - pdf_flush(pdf); /* sets pdf->last_byte */ - break; - case OBJSTM_BUF: - assert(0); - break; - default: - assert(0); - } - assert(pdf->zip_write_state == NO_ZIP); - assert(os->curbuf == PDFOUT_BUF); - assert(pdf->buf == os->buf[os->curbuf]); + case PDFOUT_BUF: + if (pdf->zip_write_state == ZIP_WRITING) + pdf->zip_write_state = ZIP_FINISH; + pdf_flush(pdf); /* sets pdf->last_byte */ + break; + case OBJSTM_BUF: + normal_error("pdf backend", "bad buffer in end stream, case 1"); + break; + default: + normal_error("pdf backend", "bad buffer in end stream, case 2"); + } pdf->stream_deflate = false; pdf->stream_writing = false; pdf_out(pdf, '\n'); /* doesn't really belong to the stream */ pdf_puts(pdf, "endstream"); /* write stream /Length */ if (pdf->seek_write_length && pdf->draftmode == 0) { - xfseeko(pdf->file, (off_t)pdf->stream_length_offset, SEEK_SET, - pdf->job_name); + xfseeko(pdf->file, (off_t)pdf->stream_length_offset, SEEK_SET, pdf->job_name); fprintf(pdf->file, "%" LONGINTEGER_PRI "i", (LONGINTEGER_TYPE) pdf->stream_length); xfseeko(pdf->file, 0, SEEK_END, pdf->job_name); } @@ -705,8 +670,8 @@ for optimizations that are not possible in pascal. @c scaled round_xn_over_d(scaled x, int n, unsigned int d) { - boolean positive = true; /* was |x>=0|, |n>=0| ? */ - unsigned t, u, v; /* intermediate quantities */ + boolean positive = true; + unsigned t, u, v; if (x < 0) { positive = !positive; x = -(x); @@ -733,10 +698,9 @@ scaled round_xn_over_d(scaled x, int n, unsigned int d) @ @c void pdf_add_bp(PDF pdf, scaled s) -{ /* print scaled as |bp| */ +{ pdffloat a; pdfstructure *p = pdf->pstruct; - assert(p != NULL); a.m = i64round(s * p->k1); a.e = pdf->decimal_digits; if (pdf->cave > 0) @@ -745,22 +709,6 @@ void pdf_add_bp(PDF pdf, scaled s) pdf->cave = 1; } -void pdf_add_mag_bp(PDF pdf, scaled s) -{ /* take |mag| into account */ - pdffloat a; - pdfstructure *p = pdf->pstruct; - prepare_mag(); - if (int_par(mag_code) != 1000) - a.m = i64round(s * (double) int_par(mag_code) / 1000.0 * p->k1); - else - a.m = i64round(s * p->k1); - a.e = pdf->decimal_digits; - if (pdf->cave > 0) - pdf_out(pdf, ' '); - print_pdffloat(pdf, a); - pdf->cave = 1; -} - @* handling page resources. @c @@ -772,10 +720,9 @@ typedef struct { @ @c static int comp_page_resources(const void *pa, const void *pb, void *p) { - int a, b; + int a = ((const pr_entry *) pa)->obj_type; + int b = ((const pr_entry *) pb)->obj_type; (void) p; - a = ((const pr_entry *) pa)->obj_type; - b = ((const pr_entry *) pb)->obj_type; if (a > b) return 1; if (a < b) @@ -790,16 +737,11 @@ void addto_page_resources(PDF pdf, pdf_obj_type t, int k) pr_entry *pr, tmp; void **pp; pdf_object_list *p, *item = NULL; - assert(pdf != NULL); re = pdf->page_resources; - assert(re != NULL); - assert(t <= PDF_OBJ_TYPE_MAX); if (re->resources_tree == NULL) { - re->resources_tree = - avl_create(comp_page_resources, NULL, &avl_xallocator); + re->resources_tree = avl_create(comp_page_resources, NULL, &avl_xallocator); if (re->resources_tree == NULL) - luatex_fail - ("addto_page_resources(): avl_create() page_resource_tree failed"); + formatted_error("pdf backend","addto_page_resources(): avl_create() page_resource_tree failed"); } tmp.obj_type = t; pr = (pr_entry *) avl_find(re->resources_tree, &tmp); @@ -809,8 +751,7 @@ void addto_page_resources(PDF pdf, pdf_obj_type t, int k) pr->list = NULL; pp = avl_probe(re->resources_tree, pr); if (pp == NULL) - luatex_fail - ("addto_page_resources(): avl_probe() out of memory in insertion"); + formatted_error("pdf backend","addto_page_resources(): avl_probe() out of memory in insertion"); } if (pr->list == NULL) { item = xtalloc(1, pdf_object_list); @@ -949,10 +890,10 @@ void pdf_print_toks(PDF pdf, halfword p) @c void pdf_add_rect_spec(PDF pdf, halfword r) { - pdf_add_mag_bp(pdf, pdf_ann_left(r)); - pdf_add_mag_bp(pdf, pdf_ann_bottom(r)); - pdf_add_mag_bp(pdf, pdf_ann_right(r)); - pdf_add_mag_bp(pdf, pdf_ann_top(r)); + pdf_add_bp(pdf, pdf_ann_left(r)); + pdf_add_bp(pdf, pdf_ann_bottom(r)); + pdf_add_bp(pdf, pdf_ann_right(r)); + pdf_add_bp(pdf, pdf_ann_top(r)); } @ output a rectangle specification to PDF file @@ -960,7 +901,6 @@ void pdf_add_rect_spec(PDF pdf, halfword r) @c void pdf_rectangle(PDF pdf, halfword r) { - prepare_mag(); pdf_add_name(pdf, "Rect"); pdf_begin_array(pdf); pdf_add_rect_spec(pdf, r); @@ -971,7 +911,6 @@ void pdf_rectangle(PDF pdf, halfword r) static void init_pdf_outputparameters(PDF pdf) { int pk_mode; - assert(output_mode_used == OMODE_PDF); pdf->draftmode = fix_int(int_par(draft_mode_code), 0, 1); pdf->compress_level = fix_int(pdf_compress_level, 0, 9); pdf->decimal_digits = fix_int(pdf_decimal_digits, 0, 4); @@ -981,21 +920,19 @@ static void init_pdf_outputparameters(PDF pdf) pdf->image_apply_gamma = fix_int(pdf_image_apply_gamma, 0, 1); pdf->objcompresslevel = fix_int(pdf_objcompresslevel, 0, MAX_OBJ_COMPRESS_LEVEL); pdf->inclusion_copy_font = fix_int(pdf_inclusion_copy_font, 0, 1); - pdf->replace_font = fix_int(pdf_replace_font, 0, 1); pdf->pk_resolution = fix_int(pdf_pk_resolution, 72, 8000); if ((pdf->minor_version >= 5) && (pdf->objcompresslevel > 0)) { pdf->os_enable = true; } else { if (pdf->objcompresslevel > 0) { - normal_warning("pdf backend","objcompresslevel > 0 requires minorversion > 4", true, true); + normal_warning("pdf backend","objcompresslevel > 0 requires minorversion > 4"); pdf->objcompresslevel = 0; } pdf->os_enable = false; } if (pdf->pk_resolution == 0) /* if not set from format file or by user */ pdf->pk_resolution = pk_dpi; /* take it from \.{texmf.cnf} */ - pdf->pk_scale_factor = - divide_scaled(72, pdf->pk_resolution, 5 + pdf->decimal_digits); + pdf->pk_scale_factor = divide_scaled(72, pdf->pk_resolution, 5 + pdf->decimal_digits); if (!callback_defined(read_pk_file_callback)) { pk_mode = pdf_pk_mode; /* lookup once */ if (pk_mode != null) { @@ -1008,8 +945,7 @@ static void init_pdf_outputparameters(PDF pdf) if (!kpse_var_value("MKTEXPK")) kpse_set_program_enabled(kpse_pk_format, 1, kpse_src_cmdline); } - set_job_id(pdf, int_par(year_code), - int_par(month_code), int_par(day_code), int_par(time_code)); + set_job_id(pdf, int_par(year_code), int_par(month_code), int_par(day_code), int_par(time_code)); if ((pdf_unique_resname > 0) && (pdf->resname_prefix == NULL)) pdf->resname_prefix = get_resname_prefix(pdf); } @@ -1035,8 +971,6 @@ static void ensure_output_file_open(PDF pdf, const char *ext) @ @c static void ensure_pdf_header_written(PDF pdf) { - assert(pdf->o_state == ST_FILE_OPEN); - assert(output_mode_used == OMODE_PDF); /* Initialize variables for \.{PDF} output */ fix_pdf_minorversion(pdf); init_pdf_outputparameters(pdf); @@ -1057,39 +991,39 @@ void ensure_output_state(PDF pdf, output_state s) if (s > ST_INITIAL) ensure_output_state(pdf, s - 1); switch (s - 1) { - case ST_INITIAL: - fix_o_mode(); - break; - case ST_OMODE_FIX: - switch (output_mode_used) { - case OMODE_DVI: - ensure_output_file_open(pdf, ".dvi"); + case ST_INITIAL: + fix_o_mode(); break; - case OMODE_PDF: - ensure_output_file_open(pdf, ".pdf"); + case ST_OMODE_FIX: + switch (output_mode_used) { + case OMODE_DVI: + ensure_output_file_open(pdf, ".dvi"); + break; + case OMODE_PDF: + ensure_output_file_open(pdf, ".pdf"); + break; + default: + normal_error("pdf backend","weird output state"); + } break; - default: - assert(0); - } - break; - case ST_FILE_OPEN: - switch (output_mode_used) { - case OMODE_DVI: - ensure_dvi_header_written(pdf); + case ST_FILE_OPEN: + switch (output_mode_used) { + case OMODE_DVI: + ensure_dvi_header_written(pdf); + break; + case OMODE_PDF: + ensure_pdf_header_written(pdf); + break; + default: + normal_error("pdf backend","weird output state"); + } break; - case OMODE_PDF: - ensure_pdf_header_written(pdf); + case ST_HEADER_WRITTEN: + break; + case ST_FILE_CLOSED: break; default: - assert(0); - } - break; - case ST_HEADER_WRITTEN: - break; - case ST_FILE_CLOSED: - break; - default: - assert(0); + normal_error("pdf backend","weird output state"); } pdf->o_state++; } @@ -1097,12 +1031,11 @@ void ensure_output_state(PDF pdf, output_state s) @ Write out an accumulated object stream. -First the object number and byte offset pairs are generated -and appended to the ready buffered object stream. -By this the value of \.{/First} can be calculated. -Then a new \.{/ObjStm} object is generated, and everything is -copied to the PDF output buffer, where also compression is done. -When calling this procedure, |pdf_os_mode| must be |true|. +First the object number and byte offset pairs are generated and appended to the +ready buffered object stream. By this the value of \.{/First} can be calculated. +Then a new \.{/ObjStm} object is generated, and everything is copied to the PDF +output buffer, where also compression is done. When calling this procedure, +|pdf_os_mode| must be |true|. @c static void pdf_os_write_objstream(PDF pdf) @@ -1112,8 +1045,6 @@ static void pdf_os_write_objstream(PDF pdf) strbuf_s *obuf = os->buf[OBJSTM_BUF]; if (os->cur_objstm == 0) /* no object stream started */ return; - assert(pdf->buf == obuf); /* yes, pdf_out() still goes into ObjStm */ - assert(os->idx > 0); /* yes, there are objects for the ObjStm */ n1 = (unsigned int) strbuf_offset(obuf); /* remember end of collected object stream contents */ /* this is needed here to calculate /First for the ObjStm dict */ for (i = 0, j = 0; i < os->idx; i++) { /* add object-number/byte-offset list to buffer */ @@ -1282,11 +1213,10 @@ remember file position for seek @c void pdf_dict_add_streaminfo(PDF pdf) { - assert(pdf->buf == pdf->os->buf[PDFOUT_BUF]); pdf_add_name(pdf, "Length"); pdf->stream_length_offset = pdf_offset(pdf) + 1; - pdf->seek_write_length = true; /* fill in length at |pdf_end_stream| call */ - pdf_puts(pdf, " x "); /* space for 10 decimal digits */ + pdf->seek_write_length = true; /* fill in length at |pdf_end_stream| call */ + pdf_puts(pdf, " x "); /* space for 10 decimal digits */ pdf->cave = 1; if (pdf->compress_level > 0) { pdf_dict_add_name(pdf, "Filter", "FlateDecode"); @@ -1320,17 +1250,16 @@ void pdf_begin_obj(PDF pdf, int i, int pdf_os_threshold) os_struct *os = pdf->os; ensure_output_state(pdf, ST_HEADER_WRITTEN); pdf_prepare_obj(pdf, i, pdf_os_threshold); - assert(pdf->buf == os->buf[os->curbuf]); switch (os->curbuf) { - case PDFOUT_BUF: - pdf_printf(pdf, "%d 0 obj\n", (int) i); - break; - case OBJSTM_BUF: - if (pdf->compress_level == 0) - pdf_printf(pdf, "%% %d 0 obj\n", (int) i); /* debugging help */ - break; - default: - assert(0); + case PDFOUT_BUF: + pdf_printf(pdf, "%d 0 obj\n", (int) i); + break; + case OBJSTM_BUF: + if (pdf->compress_level == 0) + pdf_printf(pdf, "%% %d 0 obj\n", (int) i); /* debugging help */ + break; + default: + normal_error("pdf backend","weird begin object"); } pdf->cave = 0; } @@ -1341,21 +1270,20 @@ void pdf_begin_obj(PDF pdf, int i, int pdf_os_threshold) void pdf_end_obj(PDF pdf) { os_struct *os = pdf->os; - assert(pdf->buf == os->buf[os->curbuf]); switch (os->curbuf) { - case PDFOUT_BUF: - pdf_puts(pdf, "\nendobj\n"); /* end a PDF object */ - break; - case OBJSTM_BUF: - os->idx++; /* = number of objects collected so far in ObjStm */ - os->o_ctr++; /* only for statistics */ - if (os->idx == PDF_OS_MAX_OBJS) - pdf_os_write_objstream(pdf); - else - pdf_out(pdf, '\n'); /* Adobe Reader seems to need this */ - break; - default: - assert(0); + case PDFOUT_BUF: + pdf_puts(pdf, "\nendobj\n"); /* end a PDF object */ + break; + case OBJSTM_BUF: + os->idx++; /* = number of objects collected so far in ObjStm */ + os->o_ctr++; /* only for statistics */ + if (os->idx == PDF_OS_MAX_OBJS) + pdf_os_write_objstream(pdf); + else + pdf_out(pdf, '\n'); /* Adobe Reader seems to need this */ + break; + default: + normal_error("pdf backend","weird end object"); } } @@ -1400,16 +1328,15 @@ char *convertStringToPDFString(const char *in, int len) return pstrbuf; } -@ Converts any string given in in in an allowed PDF string which is - hexadecimal encoded; - |sizeof(out)| should be at least $|lin|*2+1$. +@ Converts any string given in in in an allowed PDF string which is hexadecimal +encoded; |sizeof(out)| should be at least $|lin|*2+1$. @c static void convertStringToHexString(const char *in, char *out, int lin) { - int i, j, k; + int i, k; char buf[3]; - j = 0; + int j = 0; for (i = 0; i < lin; i++) { k = snprintf(buf, sizeof(buf), "%02X", (unsigned int) (unsigned char) in[i]); check_nprintf(k, sizeof(buf)); @@ -1420,37 +1347,32 @@ static void convertStringToHexString(const char *in, char *out, int lin) } @ Compute the ID string as per PDF1.4 9.3: -\medskip -{\obeylines\obeyspaces - File identifers are defined by the optional ID entry in a PDF file's - trailer dictionary (see Section 3.4.4, "File Trailer"; see also - implementation note 105 in Appendix H). The value of this entry is an - array of two strings. The first string is a permanent identifier based - on the contents of the file at the time it was originally created, and - does not change when the file is incrementally updated. The second - string is a changing identifier based on the file's contents at the - time it was last updated. When a file is first written, both - identifiers are set to the same value. If both identifiers match when a - file reference is resolved, it is very likely that the correct file has - been found; if only the first identifier matches, then a different - version of the correct file has been found. - To help ensure the uniqueness of file identifiers, it is recommend - that they be computed using a message digest algorithm such as MD5 - (described in Internet RFC 1321, The MD5 Message-Digest Algorithm; see - the Bibliography), using the following information (see implementation - note 106 in Appendix H): - - The current time - - A string representation of the file's location, usually a pathname - - The size of the file in bytes - - The values of all entries in the file's document information - dictionary (see Section 9.2.1, Document Information Dictionary ) -} -\medskip - This stipulates only that the two IDs must be identical when the file is - created and that they should be reasonably unique. Since it's difficult - to get the file size at this point in the execution of pdfTeX and - scanning the info dict is also difficult, we start with a simpler - implementation using just the first two items. + +File identifers are defined by the optional ID entry in a PDF file's trailer +dictionary (see Section 3.4.4, "File Trailer"; see also implementation note 105 +in Appendix H). The value of this entry is an array of two strings. The first +string is a permanent identifier based on the contents of the file at the time it +was originally created, and does not change when the file is incrementally +updated. The second string is a changing identifier based on the file's contents +at the time it was last updated. When a file is first written, both identifiers +are set to the same value. If both identifiers match when a file reference is +resolved, it is very likely that the correct file has been found; if only the +first identifier matches, then a different version of the correct file has been +found. To help ensure the uniqueness of file identifiers, it is recommend that +they be computed using a message digest algorithm such as MD5 (described in +Internet RFC 1321, The MD5 Message-Digest Algorithm; see the Bibliography), using +the following information (see implementation note 106 in Appendix H): - The +current time + +- A string representation of the file's location, usually a pathname +- The size of the file in bytes +- The values of all entries in the file's document information + dictionary (see Section 9.2.1, Document Information Dictionary ) + +This stipulates only that the two IDs must be identical when the file is created +and that they should be reasonably unique. Since it's difficult to get the file +size at this point in the execution of pdfTeX and scanning the info dict is also +difficult, we start with a simpler implementation using just the first two items. @c static void print_ID(PDF pdf) @@ -1470,7 +1392,7 @@ static void print_ID(PDF pdf) md5_append(&state, (const md5_byte_t *) time_str, (int) size); /* get the file name */ if (getcwd(pwd, sizeof(pwd)) == NULL) - luatex_fail("getcwd() failed (%s), (path too long?)", strerror(errno)); + formatted_error("pdf backend","getcwd() failed (%s), (path too long?)", strerror(errno)); #ifdef WIN32 { char *p; @@ -1498,56 +1420,50 @@ static void print_ID(PDF pdf) @ Print the /CreationDate entry. - PDF Reference, third edition says about the expected date format: -\medskip -{\obeylines\obeyspaces - 3.8.2 Dates - - PDF defines a standard date format, which closely follows that of - the international standard ASN.1 (Abstract Syntax Notation One), - defined in ISO/IEC 8824 (see the Bibliography). A date is a string - of the form - - (D:YYYYMMDDHHmmSSOHH'mm') - - where - - YYYY is the year - MM is the month - DD is the day (01-31) - HH is the hour (00-23) - mm is the minute (00-59) - SS is the second (00-59) - O is the relationship of local time to Universal Time (UT), - denoted by one of the characters +, -, or Z (see below) - HH followed by ' is the absolute value of the offset from UT - in hours (00-23) - mm followed by ' is the absolute value of the offset from UT - in minutes (00-59) - - The apostrophe character (') after HH and mm is part of the syntax. - All fields after the year are optional. (The prefix D:, although also - optional, is strongly recommended.) The default values for MM and DD - are both 01; all other numerical fields default to zero values. A plus - sign (+) as the value of the O field signifies that local time is - later than UT, a minus sign (-) that local time is earlier than UT, - and the letter Z that local time is equal to UT. If no UT information - is specified, the relationship of the specified time to UT is - considered to be unknown. Whether or not the time zone is known, the - rest of the date should be specified in local time. - - For example, December 23, 1998, at 7:52 PM, U.S. Pacific Standard - Time, is represented by the string - - D:199812231952-08'00' -} - - The main difficulty is get the time zone offset. |strftime()| does this in ISO - C99 (e.g. newer glibc) with \%z, but we have to work with other systems (e.g. - Solaris 2.5). +PDF Reference, third edition says about the expected date format: + +3.8.2 Dates + +PDF defines a standard date format, which closely follows that of the +international standard ASN.1 (Abstract Syntax Notation One), defined in ISO/IEC +8824 (see the Bibliography). A date is a string of the form + +(D:YYYYMMDDHHmmSSOHH'mm') + +where + +YYYY is the year +MM is the month +DD is the day (01-31) +HH is the hour (00-23) +mm is the minute (00-59) +SS is the second (00-59) +O is the relationship of local time to Universal Time (UT), denoted by one + of the characters +, -, or Z (see below) +HH followed by ' is the absolute value of the offset from UT in hours (00-23) +mm followed by ' is the absolute value of the offset from UT in minutes (00-59) + +The apostrophe character (') after HH and mm is part of the syntax. All fields +after the year are optional. (The prefix D:, although also optional, is strongly +recommended.) The default values for MM and DD are both 01; all other numerical +fields default to zero values. A plus sign (+) as the value of the O field +signifies that local time is later than UT, a minus sign (-) that local time is +earlier than UT, and the letter Z that local time is equal to UT. If no UT +information is specified, the relationship of the specified time to UT is +considered to be unknown. Whether or not the time zone is known, the rest of the +date should be specified in local time. + +For example, December 23, 1998, at 7:52 PM, U.S. Pacific Standard Time, is +represented by the string + +D:199812231952-08'00' + +The main difficulty is get the time zone offset. |strftime()| does this in ISO +C99 (e.g. newer glibc) with \%z, but we have to work with other systems (e.g. +Solaris 2.5). @c -#define TIME_STR_SIZE 30 /* minimum size for |time_str| is 24: |"D:YYYYmmddHHMMSS+HH'MM'"| */ +#define TIME_STR_SIZE 30 /* minimum size for |time_str| is 24: |"D:YYYYmmddHHMMSS+HH'MM'"| */ static void makepdftime(PDF pdf) { @@ -1556,7 +1472,6 @@ static void makepdftime(PDF pdf) int i, off, off_hours, off_mins; time_t t = pdf->start_time; char *time_str = pdf->start_time_str; - /* get the time */ lt = *localtime(&t); size = strftime(time_str, TIME_STR_SIZE, "D:%Y%m%d%H%M%S", <); @@ -1566,19 +1481,18 @@ static void makepdftime(PDF pdf) time_str[0] = '\0'; return; } - - /* correction for seconds: \%S can be in range 00..61, - the PDF reference expects 00..59, - therefore we map "60" and "61" to "59" */ + /* + correction for seconds: \%S can be in range 00..61, the PDF reference + expects 00..59, therefore we map "60" and "61" to "59" + */ if (time_str[14] == '6') { time_str[14] = '5'; time_str[15] = '9'; - time_str[16] = '\0'; /* for safety */ + /* for safety */ + time_str[16] = '\0'; } - /* get the time zone offset */ gmt = *gmtime(&t); - /* this calculation method was found in exim's tod.c */ off = 60 * (lt.tm_hour - gmt.tm_hour) + lt.tm_min - gmt.tm_min; if (lt.tm_year != gmt.tm_year) { @@ -1586,7 +1500,6 @@ static void makepdftime(PDF pdf) } else if (lt.tm_yday != gmt.tm_yday) { off += (lt.tm_yday > gmt.tm_yday) ? 1440 : -1440; } - if (off == 0) { time_str[size++] = 'Z'; time_str[size] = 0; @@ -1602,7 +1515,6 @@ static void makepdftime(PDF pdf) @ @c void init_start_time(PDF pdf) { - assert(pdf); if (pdf->start_time == 0) { pdf->start_time = time((time_t *) NULL); pdf->start_time_str = xtalloc(TIME_STR_SIZE, char); @@ -1613,7 +1525,6 @@ void init_start_time(PDF pdf) @ @c char *getcreationdate(PDF pdf) { - assert(pdf); init_start_time(pdf); return pdf->start_time_str; } @@ -1635,20 +1546,16 @@ void remove_pdffile(PDF pdf) void check_o_mode(PDF pdf, const char *s, int o_mode_bitpattern, boolean strict) /* s ignored now */ { - char warn_string[100]; output_mode o_mode; const char *m = NULL; - if (lua_only) { normal_error("lua only","no backend present, needed for what you asked for"); return ; } - - /* in warn mode (strict == false): - only check, don't do |fix_o_mode()| here! |output_mode_used| is left - in possibly wrong state until real output, ok. - */ - + /* + in warn mode (strict == false): only check, don't do |fix_o_mode()| here! |output_mode_used| + is left in possibly wrong state until real output, ok. + */ if (output_mode_used == OMODE_NONE) o_mode = get_o_mode(); else @@ -1656,21 +1563,19 @@ void check_o_mode(PDF pdf, const char *s, int o_mode_bitpattern, boolean strict) pdf->o_mode = output_mode_used; /* used by synctex, we need to use output_mode_used there */ if (!((1 << o_mode) & o_mode_bitpattern)) { /* warning or error */ switch (o_mode) { - case OMODE_DVI: - m = "DVI"; - break; - case OMODE_PDF: - m = "PDF"; - break; - default: - assert(0); - } - snprintf(warn_string, 99, "%s not allowed in %s mode (outputmode = %d)", - s, m, (int) int_par(output_mode_code)); + case OMODE_DVI: + m = "DVI"; + break; + case OMODE_PDF: + m = "PDF"; + break; + default: + normal_error("pdf backend","weird output state"); + } if (strict) - normal_error("pdf backend", warn_string); + formatted_error("pdf backend", "%s not allowed in %s mode (outputmode = %d)",s, m, (int) int_par(output_mode_code)); else - normal_warning("pdf backend", warn_string, true, true); + formatted_warning("pdf backend", "%s not allowed in %s mode (outputmode = %d)",s, m, (int) int_par(output_mode_code)); } else if (strict) ensure_output_state(pdf, ST_HEADER_WRITTEN); } @@ -1681,20 +1586,14 @@ void set_job_id(PDF pdf, int year, int month, int day, int time) char *name_string, *format_string, *s; size_t slen; int i; - if (pdf->job_id_string != NULL) return; - name_string = makecstring(job_name); format_string = makecstring(format_ident); - slen = SMALL_BUF_SIZE + - strlen(name_string) + strlen(format_string) + strlen(luatex_banner); + slen = SMALL_BUF_SIZE + strlen(name_string) + strlen(format_string) + strlen(luatex_banner); s = xtalloc(slen, char); /* The Web2c version string starts with a space. */ - i = snprintf(s, slen, - "%.4d/%.2d/%.2d %.2d:%.2d %s %s %s", - year, month, day, time / 60, time % 60, - name_string, format_string, luatex_banner); + i = snprintf(s, slen, "%.4d/%.2d/%.2d %.2d:%.2d %s %s %s", year, month, day, time / 60, time % 60, name_string, format_string, luatex_banner); check_nprintf(i, slen); pdf->job_id_string = xstrdup(s); xfree(s); @@ -1705,16 +1604,12 @@ void set_job_id(PDF pdf, int year, int month, int day, int time) @ @c char *get_resname_prefix(PDF pdf) { - static char name_str[] = - "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; - static char prefix[7]; /* make a tag of 6 chars long */ - unsigned long crc; + static char name_str[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; + static char prefix[7]; /* make a tag of 6 chars long */ short i; size_t base = strlen(name_str); - crc = crc32(0L, Z_NULL, 0); - crc = - crc32(crc, (Bytef *) pdf->job_id_string, - (uInt) strlen(pdf->job_id_string)); + unsigned long crc = crc32(0L, Z_NULL, 0); + crc = crc32(crc, (Bytef *) pdf->job_id_string, (uInt) strlen(pdf->job_id_string)); for (i = 0; i < 6; i++) { prefix[i] = name_str[crc % base]; crc /= base; @@ -1730,15 +1625,14 @@ void pdf_begin_page(PDF pdf) { pdffloat f; int xform_attributes; - scaled form_margin = 0; /* was one_bp until SVN4066 */ + scaled form_margin = 0; /* was one_bp until SVN4066 */ ensure_output_state(pdf, ST_HEADER_WRITTEN); init_pdf_pagecalculations(pdf); if (pdf->page_resources == NULL) { pdf->page_resources = xtalloc(1, pdf_resource_struct); pdf->page_resources->resources_tree = NULL; } - pdf->page_resources->last_resources = - pdf_create_obj(pdf, obj_type_others, 0); + pdf->page_resources->last_resources = pdf_create_obj(pdf, obj_type_others, 0); reset_page_resources(pdf); if (global_shipping_mode == SHIPPING_PAGE) { @@ -1748,12 +1642,9 @@ void pdf_begin_page(PDF pdf) pdf_begin_obj(pdf, pdf->last_stream, OBJSTM_NEVER); pdf->last_thread = null; pdf_begin_dict(pdf); - pdflua_begin_page(pdf); } else { - assert(global_shipping_mode == SHIPPING_FORM); pdf_begin_obj(pdf, pdf_cur_form, OBJSTM_NEVER); pdf->last_stream = pdf_cur_form; - /* Write out Form stream header */ pdf_begin_dict(pdf); pdf_dict_add_name(pdf, "Type", "XObject"); @@ -1804,8 +1695,7 @@ void pdf_begin_page(PDF pdf) pdf_puts(pdf, " 0 0 cm\n"); } } - pos_stack_used = 0; /* start with empty stack */ - + pos_stack_used = 0; /* start with empty stack */ if (global_shipping_mode == SHIPPING_PAGE) { colorstackpagestart(); } @@ -1820,9 +1710,9 @@ void print_pdf_table_string(PDF pdf, const char *s) const char *ls; lua_rawgeti(Luas, LUA_REGISTRYINDEX, lua_key_index(pdf_data)); lua_rawget(Luas, LUA_REGISTRYINDEX); - lua_pushstring(Luas, s); /* s t ... */ - lua_rawget(Luas, -2); /* s? t ... */ - if (lua_type(Luas, -1) == LUA_TSTRING) { /* s t ... */ + lua_pushstring(Luas, s); /* s t ... */ + lua_rawget(Luas, -2); /* s? t ... */ + if (lua_type(Luas, -1) == LUA_TSTRING) { /* s t ... */ ls = lua_tolstring(Luas, -1, &len); if (len > 0) { if (pdf->cave == 1) @@ -1831,7 +1721,7 @@ void print_pdf_table_string(PDF pdf, const char *s) pdf->cave = 1; } } - lua_pop(Luas, 2); /* ... */ + lua_pop(Luas, 2); } @ @c @@ -1840,25 +1730,22 @@ const char *get_pdf_table_string(const char *s) const_lstring ls; lua_rawgeti(Luas, LUA_REGISTRYINDEX, lua_key_index(pdf_data)); lua_rawget(Luas, LUA_REGISTRYINDEX); - lua_pushstring(Luas, s); /* s t ... */ - lua_rawget(Luas, -2); /* s? t ... */ - if (lua_type(Luas, -1) == LUA_TSTRING) { /* s t ... */ + lua_pushstring(Luas, s); /* s t ... */ + lua_rawget(Luas, -2); /* s? t ... */ + if (lua_type(Luas, -1) == LUA_TSTRING) { /* s t ... */ ls.s = lua_tolstring(Luas, -1, &ls.l); /* s is supposed to be anchored (e.g in the registry) so it's not garbage collected */ - lua_pop(Luas, 2); /* ... */ + lua_pop(Luas, 2); return ls.s; } - lua_pop(Luas, 2); /* ... */ + lua_pop(Luas, 2); return NULL ; } @ @c -// #define pdf_page_attr equiv(pdf_page_attr_loc) -// #define pdf_page_resources equiv(pdf_page_resources_loc) - void pdf_end_page(PDF pdf) { char s[64], *p; @@ -1866,29 +1753,24 @@ void pdf_end_page(PDF pdf) pdf_resource_struct *res_p = pdf->page_resources; pdf_resource_struct local_page_resources; pdf_object_list *annot_list, *bead_list, *link_list, *ol, *ol1; - scaledpos save_cur_page_size; /* to save |pdf->page_size| during flushing pending forms */ + scaledpos save_cur_page_size; /* to save |pdf->page_size| during flushing pending forms */ shipping_mode_e save_shipping_mode; int xform_resources; int page_resources, page_attributes; int procset = PROCSET_PDF; - /* Finish stream of page/form contents */ pdf_goto_pagemode(pdf); if (pos_stack_used > 0) { - luatex_fail("%u unmatched 'save' after %s shipout", (unsigned int) pos_stack_used, + formatted_error("pdf backend","%u unmatched 'save' after %s shipout", (unsigned int) pos_stack_used, ((global_shipping_mode == SHIPPING_PAGE) ? "page" : "form")); } pdf_end_stream(pdf); pdf_end_obj(pdf); - /* hh-ls : new call back finish_pdfpage_callback */ callback_id = callback_defined(finish_pdfpage_callback); if (callback_id > 0) run_callback(callback_id, "b->",(global_shipping_mode == SHIPPING_PAGE)); - if (global_shipping_mode == SHIPPING_PAGE) { - pdf->last_pages = pdf_do_page_divert(pdf, pdf->last_page, 0); - /* Write out /Page object */ pdf_begin_obj(pdf, pdf->last_page, OBJSTM_ALWAYS); pdf_begin_dict(pdf); @@ -1899,8 +1781,8 @@ void pdf_end_page(PDF pdf) pdf_begin_array(pdf); pdf_add_int(pdf, 0); pdf_add_int(pdf, 0); - pdf_add_mag_bp(pdf, pdf->page_size.h); - pdf_add_mag_bp(pdf, pdf->page_size.v); + pdf_add_bp(pdf, pdf->page_size.h); + pdf_add_bp(pdf, pdf->page_size.v); pdf_end_array(pdf); page_attributes = pdf_page_attr ; /* lookup once */ if (page_attributes != null) @@ -1908,7 +1790,6 @@ void pdf_end_page(PDF pdf) print_pdf_table_string(pdf, "pageattributes"); pdf_dict_add_ref(pdf, "Parent", pdf->last_pages); if (pdf->img_page_group_val != 0) { - assert(pdf->img_page_group_val > 0); pdf_dict_add_ref(pdf, "Group", pdf->img_page_group_val); } annot_list = get_page_resources_list(pdf, obj_type_annot); @@ -1924,16 +1805,12 @@ void pdf_end_page(PDF pdf) } pdf_end_dict(pdf); pdf_end_obj(pdf); - pdflua_end_page(pdf, annots, beads); - pdf->img_page_group_val = 0; - /* Generate array of annotations or beads in page */ if (annot_list != NULL || link_list != NULL) { pdf_begin_obj(pdf, annots, OBJSTM_ALWAYS); pdf_begin_array(pdf); while (annot_list != NULL) { - assert(annot_list->info > 0); pdf_add_ref(pdf, annot_list->info); annot_list = annot_list->link; } @@ -1955,9 +1832,7 @@ void pdf_end_page(PDF pdf) pdf_end_obj(pdf); } } - - /* Write out resource lists */ - /* Write out pending raw objects */ + /* Write out resource lists and pending raw objects */ ol = get_page_resources_list(pdf, obj_type_obj); while (ol != NULL) { if (!is_obj_written(pdf, ol->info)) @@ -1965,11 +1840,11 @@ void pdf_end_page(PDF pdf) ol = ol->link; } - /* Write out pending forms */ - /* When flushing pending forms we need to save and restore resource lists - which are also used by page shipping. - Saving and restoring |pdf->page_size| is needed for proper - writing out pending PDF marks. */ + /* + When flushing pending forms we need to save and restore resource lists + which are also used by page shipping. Saving and restoring + |pdf->page_size| is needed for proper writing out pending PDF marks. + */ ol = get_page_resources_list(pdf, obj_type_xform); while (ol != NULL) { if (!is_obj_written(pdf, ol->info)) { @@ -1987,7 +1862,6 @@ void pdf_end_page(PDF pdf) } ol = ol->link; } - /* Write out pending images */ ol = get_page_resources_list(pdf, obj_type_ximage); while (ol != NULL) { @@ -1995,14 +1869,12 @@ void pdf_end_page(PDF pdf) pdf_write_image(pdf, ol->info); ol = ol->link; } - if (global_shipping_mode == SHIPPING_PAGE) { - /* Write out pending PDF marks */ - /* Write out PDF annotations */ + /* Write out pending PDF marks and annotations */ ol = get_page_resources_list(pdf, obj_type_annot); while (ol != NULL) { if (ol->info > 0 && obj_type(pdf, ol->info) == obj_type_annot) { - j = obj_annot_ptr(pdf, ol->info); /* |j| points to |pdf_annot_node| */ + j = obj_annot_ptr(pdf, ol->info); /* |j| points to |pdf_annot_node| */ pdf_begin_obj(pdf, ol->info, OBJSTM_ALWAYS); pdf_begin_dict(pdf); pdf_dict_add_name(pdf, "Type", "Annot"); @@ -2013,7 +1885,6 @@ void pdf_end_page(PDF pdf) } ol = ol->link; } - /* Write out PDF link annotations */ if ((ol = get_page_resources_list(pdf, obj_type_link)) != NULL) { while (ol != NULL) { @@ -2037,19 +1908,19 @@ void pdf_end_page(PDF pdf) ol = get_page_resources_list(pdf, obj_type_link); while (ol != NULL) { j = obj_annot_ptr(pdf, ol->info); - /* nodes with |subtype = pdf_link_data_node| were created by |append_link| and - must be flushed here, as they are not linked in any list */ + /* + nodes with |subtype = pdf_link_data_node| were created by |append_link| and + must be flushed here, as they are not linked in any list + */ if (subtype(j) == pdf_link_data_node) flush_node(j); ol = ol->link; } } - /* Write out PDF mark destinations */ write_out_pdf_mark_destinations(pdf); /* Write out PDF bead rectangle specifications */ print_bead_rectangles(pdf); - } /* Write out resources dictionary */ pdf_begin_obj(pdf, res_p->last_resources, OBJSTM_ALWAYS); @@ -2075,13 +1946,11 @@ void pdf_end_page(PDF pdf) set_obj_xform_resources_str(pdf, pdf_cur_form, null); } } - /* Generate font resources */ if ((ol = get_page_resources_list(pdf, obj_type_font)) != NULL) { pdf_add_name(pdf, "Font"); pdf_begin_dict(pdf); while (ol != NULL) { - assert(ol->info > 0); /* always base font: an object number */ p = s; p += snprintf(p, 20, "F%i", obj_info(pdf, ol->info)); if (pdf->resname_prefix != NULL) @@ -2092,7 +1961,6 @@ void pdf_end_page(PDF pdf) pdf_end_dict(pdf); procset |= PROCSET_TEXT; } - /* Generate XObject resources */ ol = get_page_resources_list(pdf, obj_type_xform); ol1 = get_page_resources_list(pdf, obj_type_ximage); @@ -2118,7 +1986,6 @@ void pdf_end_page(PDF pdf) } pdf_end_dict(pdf); } - /* Generate ProcSet */ pdf_add_name(pdf, "ProcSet"); pdf_begin_array(pdf); @@ -2140,8 +2007,8 @@ void pdf_end_page(PDF pdf) @* Finishing the PDF output file. @ Destinations that have been referenced but don't exists have -|obj_dest_ptr=null|. Leaving them undefined might cause troubles for -PDF browsers, so we need to fix them; they point to the last page. +|obj_dest_ptr=null|. Leaving them undefined might cause troubles for PDF +browsers, so we need to fix them; they point to the last page. @c static void check_nonexisting_destinations(PDF pdf) @@ -2149,19 +2016,12 @@ static void check_nonexisting_destinations(PDF pdf) int k; for (k = pdf->head_tab[obj_type_dest]; k != 0; k = obj_link(pdf, k)) { if (obj_dest_ptr(pdf, k) == null) { - normal_warning("pdf backend", "dest ", false, false); if (obj_info(pdf, k) < 0) { - tprint("name{"); - print(-obj_info(pdf, k)); - tprint("}"); + char *ss = makecstring(-obj_info(pdf, k)); + formatted_warning("pdf backend", "unreferenced destination with name '%s'",ss); } else { - tprint("num"); - print_int(obj_info(pdf, k)); + formatted_warning("pdf backend", "unreferenced destination with num '%d'",obj_info(pdf,k)); } - tprint - (" has been referenced but does not exist, replaced by a fixed one"); - print_ln(); - print_ln(); pdf_begin_obj(pdf, k, OBJSTM_ALWAYS); pdf_begin_array(pdf); @@ -2181,20 +2041,15 @@ static void check_nonexisting_pages(PDF pdf) struct avl_table *page_tree = pdf->obj_tree[obj_type_page]; avl_t_init(&t, page_tree); /* search from the end backward until the last real page is found */ - for (p = avl_t_last(&t, page_tree); - p != NULL && obj_aux(pdf, p->objptr) == 0; p = avl_t_prev(&t)) { - normal_warning("pdf backend", "Page ", false, false); - print_int(obj_info(pdf, p->objptr)); - tprint(" has been referenced but does not exist!"); - print_ln(); - print_ln(); + for (p = avl_t_last(&t, page_tree); p != NULL && obj_aux(pdf, p->objptr) == 0; p = avl_t_prev(&t)) { + formatted_warning("pdf backend", "page %s has been referenced but does not exist",obj_info(pdf, p->objptr)); } } @ If the same keys in a dictionary are given several times, then it is not -defined which value is choosen by an application. Therefore the keys -|/Producer| and |/Creator| are only set if the token list -|pdf_info_toks| converted to a string does not contain these key strings. +defined which value is choosen by an application. Therefore the keys |/Producer| +and |/Creator| are only set if the token list |pdf_info_toks| converted to a +string does not contain these key strings. @c static boolean substr_of_str(const char *s, const char *t) @@ -2207,18 +2062,16 @@ static boolean substr_of_str(const char *s, const char *t) static int pdf_print_info(PDF pdf, int luatexversion, str_number luatexrevision) { /* print info object */ - boolean creator_given, producer_given, creationdate_given, moddate_given, - trapped_given; + boolean creator_given = false; + boolean producer_given = false; + boolean creationdate_given = false; + boolean moddate_given = false; + boolean trapped_given = false; char *s = NULL; const char *p = NULL; int k, len = 0; k = pdf_create_obj(pdf, obj_type_info, 0); pdf_begin_obj(pdf, k, 3); /* keep Info readable unless explicitely forced */ - creator_given = false; - producer_given = false; - creationdate_given = false; - moddate_given = false; - trapped_given = false; pdf_begin_dict(pdf); if (pdf_info_toks != 0) { s = tokenlist_to_cstring(pdf_info_toks, true, &len); @@ -2283,8 +2136,8 @@ static int pdf_print_info(PDF pdf, int luatexversion, static void build_free_object_list(PDF pdf) { - int k, l; - l = 0; + int k; + int l = 0; set_obj_fresh(pdf, l); /* null object at begin of list of free objects */ for (k = 1; k <= pdf->obj_ptr; k++) { if (!is_obj_written(pdf, k)) { @@ -2306,53 +2159,35 @@ void finish_pdf_file(PDF pdf, int luatexversion, str_number luatexrevision) size_t xref_offset_width; int callback_id = callback_defined(stop_run_callback); int callback_id1 = callback_defined(finish_pdffile_callback); - if (total_pages == 0) { if (callback_id == 0) { - tprint_nl("No pages of output."); - print_ln(); + normal_warning("pdf backend","no pages of output."); } else if (callback_id > 0) { run_callback(callback_id, "->"); } if (pdf->gone > 0) - garbage_warning(); + normal_error("pdf backend","dangling objects discarded, no output file produced."); } else { if (pdf->draftmode == 0) { - pdf_flush(pdf); /* to make sure that the output file name has been already created */ - flush_jbig2_page0_objects(pdf); /* flush page 0 objects from JBIG2 images, if any */ + pdf_flush(pdf); /* to make sure that the output file name has been already created */ + flush_jbig2_page0_objects(pdf); /* flush page 0 objects from JBIG2 images, if any */ if (callback_id1 > 0) run_callback(callback_id1, "->"); - check_nonexisting_pages(pdf); check_nonexisting_destinations(pdf); - /* Output fonts definition */ for (k = 1; k <= max_font_id(); k++) { if (font_used(k) && (pdf_font_num(k) < 0)) { i = -pdf_font_num(k); - assert(pdf_font_num(i) > 0); for (j = font_bc(k); j <= font_ec(k); j++) if (quick_char_exists(k, j) && pdf_char_marked(k, j)) pdf_mark_char(i, j); if ((pdf_font_attr(i) == 0) && (pdf_font_attr(k) != 0)) { set_pdf_font_attr(i, pdf_font_attr(k)); - } else if ((pdf_font_attr(k) == 0) - && (pdf_font_attr(i) != 0)) { + } else if ((pdf_font_attr(k) == 0) && (pdf_font_attr(i) != 0)) { set_pdf_font_attr(k, pdf_font_attr(i)); - } else if ((pdf_font_attr(i) != 0) - && (pdf_font_attr(k) != 0) - && - (!str_eq_str - (pdf_font_attr(i), pdf_font_attr(k)))) { - normal_warning("pdf backend","fontattr in ", false, false); - print_font_identifier(i); - tprint(" and "); - print_font_identifier(k); - tprint(" have conflicting attributes; the attributes assigned to "); - print_font_identifier(i); - tprint(" are ignored"); - print_ln(); - print_ln(); + } else if ((pdf_font_attr(i) != 0) && (pdf_font_attr(k) != 0) && (!str_eq_str(pdf_font_attr(i), pdf_font_attr(k)))) { + formatted_warning("pdf backend","fontattr of font %d and %d are conflicting, %k is used",i,k,i); } } } @@ -2360,25 +2195,22 @@ void finish_pdf_file(PDF pdf, int luatexversion, str_number luatexrevision) k = pdf->head_tab[obj_type_font]; while (k != 0) { int f = obj_info(pdf, k); - assert(pdf_font_num(f) > 0); - assert(pdf_font_num(f) == k); do_pdf_font(pdf, f); k = obj_link(pdf, k); } write_fontstuff(pdf); - pdf->last_pages = output_pages_tree(pdf); - pdflua_output_pages_tree(pdf); /* Output outlines */ outlines = print_outlines(pdf); - - /* Output name tree */ - /* The name tree is very similiar to Pages tree so its construction should be - certain from Pages tree construction. For intermediate node |obj_info| will be - the first name and |obj_link| will be the last name in \.{\\Limits} array. - Note that |pdf_dest_names_ptr| will be less than |obj_ptr|, so we test if - |k < pdf_dest_names_ptr| then |k| is index of leaf in |dest_names|; else - |k| will be index in |obj_tab| of some intermediate node. + /* + Output name tree. The name tree is very similiar to Pages tree so + its construction should be certain from Pages tree construction. + For intermediate node |obj_info| will be the first name and + |obj_link| will be the last name in \.{\\Limits} array. Note that + |pdf_dest_names_ptr| will be less than |obj_ptr|, so we test if + |k < pdf_dest_names_ptr| then |k| is index of leaf in + |dest_names|; else |k| will be index in |obj_tab| of some + intermediate node. */ names_tree = output_name_tree(pdf); @@ -2402,7 +2234,6 @@ void finish_pdf_file(PDF pdf, int luatexversion, str_number luatexrevision) } else { threads = 0; } - /* Output the /Catalog object */ root = pdf_create_obj(pdf, obj_type_catalog, 0); pdf_begin_obj(pdf, root, OBJSTM_ALWAYS); @@ -2425,10 +2256,9 @@ void finish_pdf_file(PDF pdf, int luatexversion, str_number luatexrevision) pdf_dict_add_ref(pdf, "OpenAction", pdf_catalog_openaction); pdf_end_dict(pdf); pdf_end_obj(pdf); - /* last candidate for object stream */ - info = pdf_print_info(pdf, luatexversion, luatexrevision); /* final object for pdf->os_enable == false */ - + info = pdf_print_info(pdf, luatexversion, luatexrevision); + /* final object for pdf->os_enable == false */ if (pdf->os_enable) { pdf_buffer_select(pdf, OBJSTM_BUF); pdf_os_write_objstream(pdf); @@ -2492,14 +2322,10 @@ void finish_pdf_file(PDF pdf, int luatexversion, str_number luatexrevision) } pdf_end_stream(pdf); pdf_end_obj(pdf); - /* TODO: generate a debug version of the crossref */ - pdf_flush(pdf); } else { - /* Output the |obj_tab| */ - /* Build a linked list of free objects */ + /* Output the |obj_tab| and build a linked list of free objects */ build_free_object_list(pdf); - pdf_save_offset(pdf); pdf_puts(pdf, "xref\n"); pdf_puts(pdf, "0 "); @@ -2515,9 +2341,7 @@ void finish_pdf_file(PDF pdf, int luatexversion, str_number luatexrevision) pdf_puts(pdf, " 00000 n \n"); } } - } - /* Output the trailer */ if (!pdf->os_enable) { pdf_puts(pdf, "trailer\n"); @@ -2541,9 +2365,7 @@ void finish_pdf_file(PDF pdf, int luatexversion, str_number luatexrevision) else pdf_add_longint(pdf, (longinteger) pdf->save_offset); pdf_puts(pdf, "\n%%EOF\n"); - pdf_flush(pdf); - if (callback_id == 0) { tprint_nl("Output written on "); tprint(pdf->file_name); @@ -2564,28 +2386,24 @@ void finish_pdf_file(PDF pdf, int luatexversion, str_number luatexrevision) if (pdf->draftmode == 0) close_file(pdf->file); else - normal_warning("pdf backend","draftmode enabled, not changing output pdf",true, true); + normal_warning("pdf backend","draftmode enabled, not changing output pdf"); } - if (callback_id == 0) { if (log_opened_global) { - fprintf(log_file, - "\nPDF statistics: %d PDF objects out of %d (max. %d)\n", - (int) pdf->obj_ptr, (int) pdf->obj_tab_size, - (int) sup_obj_tab_size); + fprintf(log_file, "\nPDF statistics: %d PDF objects out of %d (max. %d)\n", + (int) pdf->obj_ptr, (int) pdf->obj_tab_size, + (int) sup_obj_tab_size); if (pdf->os->ostm_ctr > 0) { - fprintf(log_file, - " %d compressed objects within %d object stream%s\n", - (int) pdf->os->o_ctr, (int) pdf->os->ostm_ctr, - (pdf->os->ostm_ctr > 1 ? "s" : "")); + fprintf(log_file, " %d compressed objects within %d object stream%s\n", + (int) pdf->os->o_ctr, (int) pdf->os->ostm_ctr, + (pdf->os->ostm_ctr > 1 ? "s" : "")); } fprintf(log_file, " %d named destinations out of %d (max. %d)\n", - (int) pdf->dest_names_ptr, (int) pdf->dest_names_size, - (int) sup_dest_names_size); - fprintf(log_file, - " %d words of extra memory for PDF output out of %d (max. %d)\n", - (int) pdf->mem_ptr, (int) pdf->mem_size, - (int) sup_pdf_mem_size); + (int) pdf->dest_names_ptr, (int) pdf->dest_names_size, + (int) sup_dest_names_size); + fprintf(log_file, " %d words of extra memory for PDF output out of %d (max. %d)\n", + (int) pdf->mem_ptr, (int) pdf->mem_size, + (int) sup_pdf_mem_size); } } } @@ -2594,7 +2412,7 @@ void finish_pdf_file(PDF pdf, int luatexversion, str_number luatexrevision) void scan_pdfcatalog(PDF pdf) { halfword p; - scan_pdf_ext_toks(); + scan_toks(false, true); pdf_catalog_toks = concat_tokens(pdf_catalog_toks, def_ref); if (scan_keyword("openaction")) { if (pdf_catalog_openaction != 0) { diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdfglyph.h b/Build/source/texk/web2c/luatexdir/pdf/pdfglyph.h index 37766d26c8f..2d04e944c6e 100644 --- a/Build/source/texk/web2c/luatexdir/pdf/pdfglyph.h +++ b/Build/source/texk/web2c/luatexdir/pdf/pdfglyph.h @@ -15,8 +15,8 @@ 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/>. */ - + with LuaTeX; if not, see <http://www.gnu.org/licenses/>. +*/ #ifndef PDFGLYPH_H # define PDFGLYPH_H diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdfglyph.w b/Build/source/texk/web2c/luatexdir/pdf/pdfglyph.w index 1f8319484e2..93096d025e5 100644 --- a/Build/source/texk/web2c/luatexdir/pdf/pdfglyph.w +++ b/Build/source/texk/web2c/luatexdir/pdf/pdfglyph.w @@ -19,24 +19,22 @@ @ @c - #include "ptexlib.h" #include "pdf/pdfpage.h" #define pdf2double(a) ((double) (a).m / ten_pow[(a).e]) @ eternal constants + @c -#define one_bp ((double) 65536 * (double) 72.27 / 72) /* number of sp per 1bp */ -#define e_tj 3 /* must be 3; movements in []TJ are in fontsize/$10^3$ units */ +#define one_bp ((double) 65536 * (double) 72.27 / 72) /* number of sp per 1bp */ +#define e_tj 3 /* must be 3; movements in []TJ are in fontsize/$10^3$ units */ @ @c static int64_t pdf_char_width(pdfstructure * p, internal_font_number f, int i) { /* use exactly this formula also for calculating the /Width array values */ - return - i64round((double) char_width(f, i) / font_size(f) * - ten_pow[e_tj + p->cw.e]); + return i64round((double) char_width(f, i) / font_size(f) * ten_pow[e_tj + p->cw.e]); } @ @c @@ -56,9 +54,7 @@ static void setup_fontparameters(PDF pdf, internal_font_number f, int ex_glyph) float u = 1.0; pdfstructure *p = pdf->pstruct; /* fix mantis bug \# 0000200 (acroread "feature") */ - if ((font_format(f) == opentype_format || - (font_format(f) == type1_format && font_encodingbytes(f) == 2)) - && font_units_per_em(f) > 0) + if ((font_format(f) == opentype_format || (font_format(f) == type1_format && font_encodingbytes(f) == 2)) && font_units_per_em(f) > 0) u = font_units_per_em(f) / 1000.0; pdf->f_cur = f; p->f_pdf = pdf_set_font(pdf, f); @@ -68,19 +64,14 @@ static void setup_fontparameters(PDF pdf, internal_font_number f, int ex_glyph) expand = 1.0 + (ex_glyph/1) / 1000.0; p->tj_delta.e = p->cw.e - 1; /* "- 1" makes less corrections inside []TJ */ /* no need to be more precise than TeX (1sp) */ - while (p->tj_delta.e > 0 - && (double) font_size(f) / ten_pow[p->tj_delta.e + e_tj] < 0.5) + while (p->tj_delta.e > 0 && (double) font_size(f) / ten_pow[p->tj_delta.e + e_tj] < 0.5) p->tj_delta.e--; /* happens for very tiny fonts */ - assert(p->cw.e >= p->tj_delta.e); /* else we would need, e. g., |ten_pow[-1]| */ p->tm[0].m = i64round(scale * expand * extend * ten_pow[p->tm[0].e]); p->tm[2].m = i64round(slant * ten_pow[p->tm[2].e]); p->tm[3].m = i64round(scale * ten_pow[p->tm[3].e]); - p->k2 = - ten_pow[e_tj + - p->cw.e] * scale / (ten_pow[p->pdf.h.e] * pdf2double(p->fs) * - pdf2double(p->tm[0])); + p->k2 = ten_pow[e_tj + p->cw.e] * scale / (ten_pow[p->pdf.h.e] * pdf2double(p->fs) * pdf2double(p->tm[0])); p->cur_ex = ex_glyph ; /* we keep track of the state of ex */ -} +} @ @c @@ -95,7 +86,7 @@ static void set_font(PDF pdf) p->f_pdf_cur = p->f_pdf; p->fs_cur.m = p->fs.m; p->need_tf = false; - p->need_tm = true; /* always follow Tf by Tm */ + p->need_tm = true; /* always follow Tf by Tm */ } @ @c @@ -103,12 +94,13 @@ static void set_textmatrix(PDF pdf, scaledpos pos) { boolean move; pdfstructure *p = pdf->pstruct; - assert(is_textmode(p)); + if (!is_textmode(p)) + normal_error("pdf backend","text mode expected in set_textmatrix"); move = calc_pdfpos(p, pos); if (p->need_tm || move) { print_pdf_matrix(pdf, p->tm); pdf_puts(pdf, " Tm "); - p->pdf.h.m = p->pdf_bt_pos.h.m + p->tm[4].m; /* Tm replaces */ + p->pdf.h.m = p->pdf_bt_pos.h.m + p->tm[4].m; /* Tm replaces */ p->pdf.v.m = p->pdf_bt_pos.v.m + p->tm[5].m; p->need_tm = false; } @@ -118,6 +110,7 @@ static void set_textmatrix(PDF pdf, scaledpos pos) @ Print out a character to PDF buffer; the character will be printed in octal form in the following cases: chars <= 32, backslash (92), left parenthesis (40), and right parenthesis (41). + @c static void pdf_print_char(PDF pdf, int c) { @@ -144,7 +137,8 @@ static void pdf_print_wide_char(PDF pdf, int c) @ @c static void begin_charmode(PDF pdf, internal_font_number f, pdfstructure * p) { - assert(is_chararraymode(p)); + if (!is_chararraymode(p)) + normal_error("pdf backend","char array mode expected in begin_char_mode"); if (font_encodingbytes(f) == 2) { p->ishex = 1; pdf_out(pdf, '<'); @@ -159,7 +153,8 @@ static void begin_charmode(PDF pdf, internal_font_number f, pdfstructure * p) void end_charmode(PDF pdf) { pdfstructure *p = pdf->pstruct; - assert(is_charmode(p)); + if (!is_charmode(p)) + normal_error("pdf backend","char mode expected in end_char_mode"); if (p->ishex == 1) { p->ishex = 0; pdf_out(pdf, '>'); @@ -173,7 +168,8 @@ void end_charmode(PDF pdf) static void begin_chararray(PDF pdf) { pdfstructure *p = pdf->pstruct; - assert(is_textmode(p)); + if (!is_textmode(p)) + normal_error("pdf backend","text mode expected in begin_char_array"); p->pdf_tj_pos = p->pdf; p->cw.m = 0; pdf_out(pdf, '['); @@ -184,58 +180,28 @@ static void begin_chararray(PDF pdf) void end_chararray(PDF pdf) { pdfstructure *p = pdf->pstruct; - assert(is_chararraymode(p)); + if (!is_chararraymode(p)) + normal_error("pdf backend","char array mode expected in end_char_array"); pdf_puts(pdf, "]TJ\n"); p->pdf = p->pdf_tj_pos; p->mode = PMODE_TEXT; } -@ @c +@ We need to adapt the tm when a font changes. A change can be a change in id +(frontend) or pdf reference (backend, as we share font resources). At such a +change we also need to adapt to the slant and extend. Initially we also need to +take the exfactor of a glyph into account. When the font is unchanged, we still +need to check each glyph for a change in exfactor. We store the current one on +the state record so that we can minimize testing. + +@c void pdf_place_glyph(PDF pdf, internal_font_number f, int c, int ex) { boolean move; pdfstructure *p = pdf->pstruct; scaledpos pos = pdf->posstruct->pos; - if (!char_exists(f, c)) return; - -/* - p->need_tf : okay, set somewhere else - f != pdf->f_cur : font change - p->f_pdf != p->f_pdf_cur : font change - p->fs.m ~= p->fs_cur.m : move - is_pagemode(p) -> stream change - p->tm0_cur.m -> p->tm[0].m : also move -*/ - - /* fix issue 857 */ - /* /\* ensure to be within BT...ET *\/ */ - /* if (is_pagemode(p)) { */ - /* pdf_goto_textmode(pdf); */ - /* p->need_tf = true; */ - /* } */ - /* /\* all font setup *\/ */ - /* if (true || f != pdf->f_cur || p->need_tf) { */ - /* setup_fontparameters(pdf, f, ex); */ - /* if (p->need_tf || p->f_pdf != p->f_pdf_cur || p->fs.m != p->fs_cur.m) { */ - /* pdf_goto_textmode(pdf); */ - /* set_font(pdf); */ - /* } else if (p->tm0_cur.m != p->tm[0].m) { */ - /* /\* catch in-line HZ expand change due to efcode *\/ */ - /* p->need_tm = true; */ - /* } */ - /* } */ - - - /* LS/HH: We need to adapt the tm when a font changes. A change can be a change in - id (frontend) or pdf reference (backend, as we share font resources). At - such a change we also need to adapt to the slant and extend. Initially - we also need to take the exfactor of a glyph into account. When the font is - unchanged, we still need to check each glyph for a change in exfactor. We - store the current one on the state record so that we can minimize testing. */ - - /* is the p->need_tf test really needed ? */ if (p->need_tf || f != pdf->f_cur || p->f_pdf != p->f_pdf_cur || p->fs.m != p->fs_cur.m || is_pagemode(p)) { pdf_goto_textmode(pdf); setup_fontparameters(pdf, f, ex); @@ -243,37 +209,30 @@ void pdf_place_glyph(PDF pdf, internal_font_number f, int c, int ex) } else if (p->tm0_cur.m != p->tm[0].m || p->cur_ex != ex) { setup_fontparameters(pdf, f, ex); p->need_tm = true; - } - + } /* all movements */ move = calc_pdfpos(p, pos); /* within text or chararray or char mode */ if (move || p->need_tm) { - if (p->need_tm || (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) { + if (p->need_tm || (p->wmode == WMODE_H && (p->pdf_bt_pos.v.m + p->tm[5].m) != p->pdf.v.m) + || (p->wmode == WMODE_V && (p->pdf_bt_pos.h.m + p->tm[4].m) != p->pdf.h.m) + || abs(p->tj_delta.m) >= 1000000) { pdf_goto_textmode(pdf); set_textmatrix(pdf, pos); begin_chararray(pdf); move = calc_pdfpos(p, pos); /* for fine adjustment */ } if (move) { - assert((p->wmode == WMODE_H - && (p->pdf_bt_pos.v.m + p->tm[5].m) == p->pdf.v.m) - || (p->wmode == WMODE_V - && (p->pdf_bt_pos.h.m + p->tm[4].m) == p->pdf.h.m)); if (is_charmode(p)) end_charmode(pdf); - assert(p->tj_delta.m != 0); print_pdffloat(pdf, p->tj_delta); p->cw.m -= p->tj_delta.m * ten_pow[p->cw.e - p->tj_delta.e]; } } /* glyph output */ - assert(is_chararraymode(p) || is_charmode(p)); if (is_chararraymode(p)) begin_charmode(pdf, f, p); + else if (!is_charmode(p)) + normal_error("pdf backend","char (array) mode expected in place_glyph"); pdf_mark_char(f, c); if (font_encodingbytes(f) == 2) pdf_print_wide_char(pdf, char_index(f, c)); diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdfimage.h b/Build/source/texk/web2c/luatexdir/pdf/pdfimage.h index c4f5f53aecb..b5b8718393e 100644 --- a/Build/source/texk/web2c/luatexdir/pdf/pdfimage.h +++ b/Build/source/texk/web2c/luatexdir/pdf/pdfimage.h @@ -15,8 +15,9 @@ 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/>. */ + with LuaTeX; if not, see <http://www.gnu.org/licenses/>. +*/ #ifndef PDFIMAGE_H # define PDFIMAGE_H diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdfimage.w b/Build/source/texk/web2c/luatexdir/pdf/pdfimage.w index 29795990eab..fd364243804 100644 --- a/Build/source/texk/web2c/luatexdir/pdf/pdfimage.w +++ b/Build/source/texk/web2c/luatexdir/pdf/pdfimage.w @@ -19,7 +19,6 @@ @ @c - #include "ptexlib.h" @ @c @@ -34,8 +33,6 @@ void place_img(PDF pdf, image_dict * idict, scaled_whd dim, int transform) scaledpos tmppos; pdffloat cm[6]; int groupref; /* added from web for 1.40.8 */ - assert(idict != 0); - assert(p != NULL); a[0] = a[3] = 1.0e6; a[1] = a[2] = 0; if (img_type(idict) == IMG_TYPE_PDF || img_type(idict) == IMG_TYPE_PDFMEMSTREAM @@ -58,7 +55,7 @@ void place_img(PDF pdf, image_dict * idict, scaled_whd dim, int transform) xoff = yoff = 0; r = 4; } - if ((transform & 7) > 3) { // mirror cases + if ((transform & 7) > 3) { /* mirror cases */ a[0] *= -1; xoff *= -1; } @@ -146,7 +143,6 @@ void pdf_place_image(PDF pdf, halfword p) { scaled_whd dim; image_dict *idict = idict_array[rule_index(p)]; - assert(idict != NULL); dim.wd = width(p); dim.ht = height(p); dim.dp = depth(p); diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdflink.h b/Build/source/texk/web2c/luatexdir/pdf/pdflink.h index b7103aec56e..5b3d2042a80 100644 --- a/Build/source/texk/web2c/luatexdir/pdf/pdflink.h +++ b/Build/source/texk/web2c/luatexdir/pdf/pdflink.h @@ -15,13 +15,13 @@ 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/>. */ - + with LuaTeX; if not, see <http://www.gnu.org/licenses/>. +*/ #ifndef PDFLINK_H # define PDFLINK_H -# define set_pdf_link_attr(A,B) pdf_link_attr(A)=B +# define set_pdf_link_attr(A,B) pdf_link_attr(A)=B # define set_pdf_link_action(A,B) pdf_link_action(A)=B # define set_pdf_link_objnum(A,B) pdf_link_objnum(A)=B @@ -29,9 +29,7 @@ extern void push_link_level(PDF pdf, halfword p); extern void pop_link_level(PDF pdf); extern void do_link(PDF pdf, halfword p, halfword parent_box, scaledpos cur); extern void end_link(PDF pdf, halfword p); -extern void append_link(PDF pdf, halfword parent_box, scaledpos cur, - small_number i); - +extern void append_link(PDF pdf, halfword parent_box, scaledpos cur, small_number i); extern void scan_startlink(PDF pdf); diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdflink.w b/Build/source/texk/web2c/luatexdir/pdf/pdflink.w index 89fb1057567..b21d0774ecd 100644 --- a/Build/source/texk/web2c/luatexdir/pdf/pdflink.w +++ b/Build/source/texk/web2c/luatexdir/pdf/pdflink.w @@ -19,7 +19,6 @@ @ @c - #include "ptexlib.h" @ To implement nested link annotations, we need a stack to hold copy of @@ -31,7 +30,6 @@ void push_link_level(PDF pdf, halfword p) { if (pdf->link_stack_ptr >= pdf_max_link_level) overflow("pdf link stack size", pdf_max_link_level); - assert(((type(p) == whatsit_node) && (subtype(p) == pdf_start_link_node))); pdf->link_stack_ptr++; pdf->link_stack[pdf->link_stack_ptr].nesting_level = cur_s; pdf->link_stack[pdf->link_stack_ptr].link_node = copy_node_list(p); @@ -41,7 +39,6 @@ void push_link_level(PDF pdf, halfword p) @ @c void pop_link_level(PDF pdf) { - assert(pdf->link_stack_ptr > 0); flush_node_list(pdf->link_stack[pdf->link_stack_ptr].link_node); pdf->link_stack_ptr--; } @@ -54,8 +51,7 @@ void do_link(PDF pdf, halfword p, halfword parent_box, scaledpos cur) if (type(p) == vlist_node) normal_error("pdf backend", "'startlink' ended up in vlist"); if (global_shipping_mode == SHIPPING_FORM) - normal_error("pdf backend", "link annotations cannot be inside an XForm"); - assert(type(parent_box) == hlist_node); + normal_error("pdf backend", "link annotations cannot be inside an xform"); if (is_obj_scheduled(pdf, pdf_link_objnum(p))) pdf_link_objnum(p) = pdf_create_obj(pdf, obj_type_others, 0); push_link_level(pdf, p); @@ -80,32 +76,34 @@ void end_link(PDF pdf, halfword p) normal_error("pdf backend","pdf link_stack empty, 'endlink' used without 'startlink'"); if (pdf->link_stack[pdf->link_stack_ptr].nesting_level != cur_s) normal_error("pdf backend","'endlink' ended up in different nesting level than 'startlink'"); - - /* N.B.: test for running link must be done on |link_node| and not |ref_link_node|, - as |ref_link_node| can be set by |do_link| or |append_link| already */ - + /* + NOTA BENE: test for running link must be done on |link_node| and not + |ref_link_node|, as |ref_link_node| can be set by |do_link| or + |append_link| already + */ if (is_running(width(pdf->link_stack[pdf->link_stack_ptr].link_node))) { q = pdf->link_stack[pdf->link_stack_ptr].ref_link_node; if (global_shipping_mode == SHIPPING_PAGE && matrixused()) { - matrixrecalculate(pos.h + pdf_link_margin); + matrixrecalculate(pos.h + pdf_link_margin); pdf_ann_left(q) = getllx() - pdf_link_margin; pdf_ann_top(q) = getlly() - pdf_link_margin; pdf_ann_right(q) = geturx() + pdf_link_margin; pdf_ann_bottom(q) = getury() + pdf_link_margin; } else { switch (pdf->posstruct->dir) { - case dir_TLT: - pdf_ann_right(q) = pos.h + pdf_link_margin; - break; - case dir_TRT: - pdf_ann_left(q) = pos.h - pdf_link_margin; - break; - case dir_LTL: - case dir_RTT: - pdf_ann_bottom(q) = pos.v - pdf_link_margin; - break; - default: - assert(0); + case dir_TLT: + pdf_ann_right(q) = pos.h + pdf_link_margin; + break; + case dir_TRT: + pdf_ann_left(q) = pos.h - pdf_link_margin; + break; + case dir_LTL: + case dir_RTT: + pdf_ann_bottom(q) = pos.v - pdf_link_margin; + break; + default: + pdf_ann_right(q) = pos.h + pdf_link_margin; + formatted_warning("pdf backend","forcing bad dir %i to TLT in link",pdf->posstruct->dir); } } } @@ -114,10 +112,9 @@ void end_link(PDF pdf, halfword p) @ For ``running'' annotations we must append a new node when the end of annotation is in other box than its start. The new created node is identical to -corresponding whatsit node representing the start of annotation, but its -|info| field is |max_halfword|. We set |info| field just before destroying the -node, in order to use |flush_node_list| to do the job. - +corresponding whatsit node representing the start of annotation, but its |info| +field is |max_halfword|. We set |info| field just before destroying the node, in +order to use |flush_node_list| to do the job. @ Append a new pdf annot to |pdf_link_list|. @@ -127,7 +124,6 @@ void append_link(PDF pdf, halfword parent_box, scaledpos cur, small_number i) halfword p; int k; scaled_whd alt_rule; - assert(type(parent_box) == hlist_node); p = copy_node(pdf->link_stack[(int) i].link_node); pdf->link_stack[(int) i].ref_link_node = p; subtype(p) = pdf_link_data_node; /* this node is not a normal link node */ @@ -152,14 +148,17 @@ void scan_startlink(PDF pdf) new_annot_whatsit(pdf_start_link_node); set_pdf_link_attr(cur_list.tail_field, null); if (scan_keyword("attr")) { - scan_pdf_ext_toks(); + scan_toks(false, true); set_pdf_link_attr(cur_list.tail_field, def_ref); } r = scan_action(pdf); set_pdf_link_action(cur_list.tail_field, r); set_pdf_link_objnum(cur_list.tail_field, k); pdf_last_link = k; - /* N.B.: although it is possible to set |obj_annot_ptr(k) := tail| here, it - is not safe if nodes are later copied/destroyed/moved; a better place - to do this is inside |do_link|, when the whatsit node is written out */ + /* + NOTA BENE: although it is possible to set |obj_annot_ptr(k) := tail| + here, it is not safe if nodes are later copied/destroyed/moved; a better + place to do this is inside |do_link|, when the whatsit node is written + out + */ } diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdflistout.h b/Build/source/texk/web2c/luatexdir/pdf/pdflistout.h index 646a26b855a..76c1d552f1a 100644 --- a/Build/source/texk/web2c/luatexdir/pdf/pdflistout.h +++ b/Build/source/texk/web2c/luatexdir/pdf/pdflistout.h @@ -15,24 +15,23 @@ 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/>. */ - + with LuaTeX; if not, see <http://www.gnu.org/licenses/>. +*/ #ifndef PDFLISTOUT_H # define PDFLISTOUT_H -/* a few small helpers */ # define pos_right(A) pdf->posstruct->pos.h = pdf->posstruct->pos.h + (A) # define pos_left(A) pdf->posstruct->pos.h = pdf->posstruct->pos.h - (A) # define pos_up(A) pdf->posstruct->pos.v = pdf->posstruct->pos.v + (A) # define pos_down(A) pdf->posstruct->pos.v = pdf->posstruct->pos.v - (A) -typedef void (*backend_function) (); /* variadic arguments */ +typedef void (*backend_function) (); /* variadic arguments */ typedef struct { - char *name; /* name of the backend */ - backend_function *node_fu; /* array of node output functions */ - backend_function *whatsit_fu; /* array of whatsit output functions */ + char *name; /* name of the backend */ + backend_function *node_fu; /* array of node output functions */ + backend_function *whatsit_fu; /* array of whatsit output functions */ } backend_struct; extern pos_info_structure pos_info; @@ -42,8 +41,8 @@ extern backend_function *backend_out_whatsit; extern void init_backend_functionpointers(output_mode o_mode); -extern void hlist_out(PDF pdf, halfword this_box); -extern void vlist_out(PDF pdf, halfword this_box); +extern void hlist_out(PDF pdf, halfword this_box, int rule_callback_id); +extern void vlist_out(PDF pdf, halfword this_box, int rule_callback_id); extern void out_what(PDF pdf, halfword p); #endif diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdflistout.w b/Build/source/texk/web2c/luatexdir/pdf/pdflistout.w index bf32cb8c629..2bd15f3cedf 100644 --- a/Build/source/texk/web2c/luatexdir/pdf/pdflistout.w +++ b/Build/source/texk/web2c/luatexdir/pdf/pdflistout.w @@ -31,21 +31,11 @@ backend_function *backend_out, *backend_out_whatsit; @ @c static void missing_backend_function(PDF pdf, halfword p) { - char *b; - const char *s; - const char *n; - char backend_string[15]; - char err_string[60]; - assert(backend != NULL); + const char *n = get_node_name(type(p), subtype(p)); if (type(p) == whatsit_node) - s = "whatsit"; + formatted_error("pdf backend","no output function for whatsit %s",n); else - s = "node"; - n = get_node_name(type(p), subtype(p)); - b = backend[output_mode_used].name; - snprintf(backend_string, strlen(b) + 10, "%s back-end", b); - snprintf(err_string, 59, "no output function for \"%s\" %s", n, s); - normal_error(backend_string, err_string); + formatted_error("pdf backend","no output function for node %s",n); } @ @c @@ -89,7 +79,6 @@ static void init_dvi_backend_functions(void) p->whatsit_fu[late_lua_node] = &late_lua; } - @ @c void init_backend_functionpointers(output_mode o_mode) { @@ -126,22 +115,22 @@ static scaled simple_advance_width(halfword p) while ((q != null) && (vlink(q) != null)) { q = vlink(q); switch (type(q)) { - case glyph_node: - w += glyph_width(q); - break; - case hlist_node: - case vlist_node: - case rule_node: - case margin_kern_node: - case kern_node: - w += width(q); - break; - case disc_node: - /* hh: the frontend should append already */ - if (vlink(no_break(q)) != null) - w += simple_advance_width(no_break(q)); - default: - break; + case glyph_node: + w += glyph_width(q); + break; + case hlist_node: + case vlist_node: + case rule_node: + case margin_kern_node: + case kern_node: + w += width(q); + break; + case disc_node: + /* hh: the frontend should append already */ + if (vlink(no_break(q)) != null) + w += simple_advance_width(no_break(q)); + default: + break; } } return w; @@ -163,60 +152,60 @@ static halfword calculate_width_to_enddir(halfword p, real cur_glue, scaled cur_ w += pack_width(box_dir(this_box), dir_TRT, q, true); else { switch (type(q)) { - case hlist_node: - case vlist_node: - w += pack_width(box_dir(this_box), box_dir(q), q, false); - break; - case rule_node: - case margin_kern_node: - case kern_node: - w += width(q); - break; - case math_node: - /* begin mathskip code */ - if (glue_ptr(q) == zero_glue) { - w += surround(q); + case hlist_node: + case vlist_node: + w += pack_width(box_dir(this_box), box_dir(q), q, false); break; - } else { - /* fall through: mathskip */ - } - /* end mathskip code */ - case glue_node: - g = glue_ptr(q); - w += width(g) - cur_g; - if (g_sign != normal) { - if (g_sign == stretching) { - if (stretch_order(g) == g_order) { - cur_glue = cur_glue + stretch(g); + case rule_node: + case margin_kern_node: + case kern_node: + w += width(q); + break; + case math_node: + /* begin mathskip code */ + if (glue_ptr(q) == zero_glue) { + w += surround(q); + break; + } else { + /* fall through: mathskip */ + } + /* end mathskip code */ + case glue_node: + g = glue_ptr(q); + w += width(g) - cur_g; + if (g_sign != normal) { + if (g_sign == stretching) { + if (stretch_order(g) == g_order) { + cur_glue = cur_glue + stretch(g); + vet_glue(float_cast(glue_set(this_box)) * cur_glue); + cur_g = float_round(glue_temp); + } + } else if (shrink_order(g) == g_order) { + cur_glue = cur_glue - shrink(g); vet_glue(float_cast(glue_set(this_box)) * cur_glue); cur_g = float_round(glue_temp); } - } else if (shrink_order(g) == g_order) { - cur_glue = cur_glue - shrink(g); - vet_glue(float_cast(glue_set(this_box)) * cur_glue); - cur_g = float_round(glue_temp); } - } - w += cur_g; - break; - case disc_node: - /* hh: the frontend should append already */ - if (vlink(no_break(q)) != null) - w += simple_advance_width(no_break(q)); - break; - case dir_node: - if (dir_dir(q) >= 0) - dir_nest++; - else - dir_nest--; - if (dir_nest == 0) { - enddir_ptr = q; - dir_cur_h(enddir_ptr) = w; - q = null; - } - break; - default: - break; + w += cur_g; + break; + case disc_node: + /* hh: the frontend should append already */ + if (vlink(no_break(q)) != null) + w += simple_advance_width(no_break(q)); + break; + case dir_node: + if (dir_dir(q) >= 0) + dir_nest++; + else + dir_nest--; + if (dir_nest == 0) { + enddir_ptr = q; + dir_cur_h(enddir_ptr) = w; + q = null; + } + break; + default: + break; } } } @@ -237,56 +226,55 @@ implementations, due to machine-dependent rounding in the glue calculations.) @c void out_what(PDF pdf, halfword p) { - switch (subtype(p)) { /* function(pdf, p) */ - case special_node: /* |pdf_special(pdf, p)|; */ - case late_lua_node: /* |late_lua(pdf, p)|; */ - case pdf_save_node: /* |pdf_out_save(pdf, p)|; */ - case pdf_restore_node: /* |pdf_out_restore(pdf, p)|; */ - case pdf_end_link_node: /* |end_link(pdf, p)|; */ - case pdf_end_thread_node: /* |end_thread(pdf, p)|; */ - case pdf_literal_node: /* |pdf_out_literal(pdf, p)|; */ - case pdf_colorstack_node: /* |pdf_out_colorstack(pdf, p)|; */ - case pdf_setmatrix_node: /* |pdf_out_setmatrix(pdf, p)|; */ - case pdf_refobj_node: /* |pdf_ref_obj(pdf, p)| */ - backend_out_whatsit[subtype(p)] (pdf, p); - break; - case open_node: - case write_node: - case close_node: - /* do some work that has been queued up for \.{\\write} */ - if (!doing_leaders) { - int j = write_stream(p); - if (subtype(p) == write_node) { - write_out(p); - } else if (subtype(p) == close_node) { - close_write_file(j); - } else if (valid_write_file(j)) { - char *fn; - close_write_file(j); - cur_name = open_name(p); - cur_area = open_area(p); - cur_ext = open_ext(p); - if (cur_ext == get_nullstr()) - cur_ext = maketexstring(".tex"); - fn = pack_file_name(cur_name, cur_area, cur_ext); - while (! open_write_file(j,fn)) { - fn = prompt_file_name("output file name", ".tex"); + switch (subtype(p)) { + case special_node: /* |pdf_special(pdf, p)|; */ + case late_lua_node: /* |late_lua(pdf, p)|; */ + case pdf_save_node: /* |pdf_out_save(pdf, p)|; */ + case pdf_restore_node: /* |pdf_out_restore(pdf, p)|; */ + case pdf_end_link_node: /* |end_link(pdf, p)|; */ + case pdf_end_thread_node: /* |end_thread(pdf, p)|; */ + case pdf_literal_node: /* |pdf_out_literal(pdf, p)|; */ + case pdf_colorstack_node: /* |pdf_out_colorstack(pdf, p)|; */ + case pdf_setmatrix_node: /* |pdf_out_setmatrix(pdf, p)|; */ + case pdf_refobj_node: /* |pdf_ref_obj(pdf, p)| */ + backend_out_whatsit[subtype(p)] (pdf, p); + break; + case open_node: + case write_node: + case close_node: + /* do some work that has been queued up for \.{\\write} */ + if (!doing_leaders) { + int j = write_stream(p); + if (subtype(p) == write_node) { + write_out(p); + } else if (subtype(p) == close_node) { + close_write_file(j); + } else if (valid_write_file(j)) { + char *fn; + close_write_file(j); + cur_name = open_name(p); + cur_area = open_area(p); + cur_ext = open_ext(p); + if (cur_ext == get_nullstr()) + cur_ext = maketexstring(".tex"); + fn = pack_file_name(cur_name, cur_area, cur_ext); + while (! open_write_file(j,fn)) { + fn = prompt_file_name("output file name", ".tex"); + } } } - } - break; - case user_defined_node: - break; - default: - /* this should give an error about missing whatsit backend function */ - backend_out_whatsit[subtype(p)] (pdf, p); + break; + case user_defined_node: + break; + default: + /* this should give an error about missing whatsit backend function */ + backend_out_whatsit[subtype(p)] (pdf, p); } } @ @c -void hlist_out(PDF pdf, halfword this_box) +void hlist_out(PDF pdf, halfword this_box, int rule_callback_id) { - posstructure localpos; /* the position structure local within this function */ posstructure *refpos; /* the list origin pos. on the page, provided by the caller */ scaledpos cur = { 0, 0 }, tmpcur, basepoint; @@ -333,7 +321,6 @@ void hlist_out(PDF pdf, halfword this_box) } for (i = 1; i <= pdf->link_stack_ptr; i++) { - assert(is_running(width(pdf->link_stack[i].link_node))); if (pdf->link_stack[i].nesting_level == cur_s) append_link(pdf, this_box, cur, (small_number) i); } @@ -362,302 +349,305 @@ void hlist_out(PDF pdf, halfword this_box) } else { /* output the non-|char_node| |p| for |hlist_out| and move to the next node */ switch (type(p)) { - case hlist_node: - case vlist_node: - if (textdir_parallel(box_dir(p), localpos.dir)) { - effective_horizontal = width(p); - basepoint.v = 0; - if (textdir_opposite(box_dir(p), localpos.dir)) - basepoint.h = width(p); - else - basepoint.h = 0; - } else { - effective_horizontal = height(p) + depth(p); - if (!is_mirrored(box_dir(p))) { - if (partextdir_eq(box_dir(p), localpos.dir)) - basepoint.h = height(p); + case hlist_node: + case vlist_node: + if (textdir_parallel(box_dir(p), localpos.dir)) { + effective_horizontal = width(p); + basepoint.v = 0; + if (textdir_opposite(box_dir(p), localpos.dir)) + basepoint.h = width(p); else - basepoint.h = depth(p); + basepoint.h = 0; } else { - if (partextdir_eq(box_dir(p), localpos.dir)) - basepoint.h = depth(p); - else - basepoint.h = height(p); + effective_horizontal = height(p) + depth(p); + if (!is_mirrored(box_dir(p))) { + if (partextdir_eq(box_dir(p), localpos.dir)) + basepoint.h = height(p); + else + basepoint.h = depth(p); + } else { + if (partextdir_eq(box_dir(p), localpos.dir)) + basepoint.h = depth(p); + else + basepoint.h = height(p); + } + if (is_rotated(localpos.dir)) { + if (partextdir_eq(localpos.dir, box_dir(p))) + basepoint.v = -width(p) / 2; /* up */ + else + basepoint.v = width(p) / 2; /* down */ + } else if (is_mirrored(localpos.dir)) { + if (partextdir_eq(localpos.dir, box_dir(p))) + basepoint.v = 0; + else + basepoint.v = width(p); /* down */ + } else { + if (partextdir_eq(localpos.dir, box_dir(p))) + basepoint.v = -width(p); /* up */ + else + basepoint.v = 0; + } } - if (is_rotated(localpos.dir)) { - if (partextdir_eq(localpos.dir, box_dir(p))) - basepoint.v = -width(p) / 2; /* up */ - else - basepoint.v = width(p) / 2; /* down */ - } else if (is_mirrored(localpos.dir)) { - if (partextdir_eq(localpos.dir, box_dir(p))) - basepoint.v = 0; - else - basepoint.v = width(p); /* down */ + if (!is_mirrored(localpos.dir)) + basepoint.v = basepoint.v + shift_amount(p); /* shift the box down */ + else + basepoint.v = basepoint.v - shift_amount(p); /* shift the box up */ + if (list_ptr(p) == null) { + if (synctex) { + if (type(p) == vlist_node) + synctexvoidvlist(p, this_box); + else + synctexvoidhlist(p, this_box); + } } else { - if (partextdir_eq(localpos.dir, box_dir(p))) - basepoint.v = -width(p); /* up */ - else - basepoint.v = 0; - } - } - if (!is_mirrored(localpos.dir)) - basepoint.v = basepoint.v + shift_amount(p); /* shift the box down */ - else - basepoint.v = basepoint.v - shift_amount(p); /* shift the box up */ - if (list_ptr(p) == null) { - if (synctex) { + tmpcur.h = cur.h + basepoint.h; + tmpcur.v = basepoint.v; + synch_pos_with_cur(pdf->posstruct, refpos, tmpcur); if (type(p) == vlist_node) - synctexvoidvlist(p, this_box); + vlist_out(pdf, p, rule_callback_id); else - synctexvoidhlist(p, this_box); + hlist_out(pdf, p, rule_callback_id); } - } else { - assert(cur.v == 0); - tmpcur.h = cur.h + basepoint.h; - tmpcur.v = basepoint.v; - synch_pos_with_cur(pdf->posstruct, refpos, tmpcur); - if (type(p) == vlist_node) - vlist_out(pdf, p); - else - hlist_out(pdf, p); - } - cur.h += effective_horizontal; - break; - case disc_node: - /* hh: the frontend should append already */ - if (vlink(no_break(p)) != null) { - if (subtype(p) != select_disc) { - q = tail_of_list(vlink(no_break(p))); /* this could be a tlink */ - vlink(q) = vlink(p); - q = vlink(no_break(p)); - vlink(no_break(p)) = null; - vlink(p) = q; - } - } - break; - case rule_node: - if (rule_dir(p) < 0) - rule_dir(p) = localpos.dir; - if (pardir_parallel(rule_dir(p), localpos.dir)) { - rule.ht = height(p); - rule.dp = depth(p); - rule.wd = width(p); - } else { - rule.ht = width(p) / 2; - rule.dp = width(p) / 2; - rule.wd = height(p) + depth(p); - } - goto FIN_RULE; - break; - case dir_node: - /* output a reflection instruction if the direction has changed */ - if (dir_dir(p) >= 0) { - /* - Calculate the needed width to the matching |enddir|, return the - |enddir| node, with width info - */ - enddir_ptr = calculate_width_to_enddir(p, cur_glue, cur_g, this_box); - if (textdir_parallel(dir_dir(p), localpos.dir)) { - dir_cur_h(enddir_ptr) += cur.h; - if (textdir_opposite(dir_dir(p), localpos.dir)) - cur.h = dir_cur_h(enddir_ptr); - } else - dir_cur_h(enddir_ptr) = cur.h; - if (enddir_ptr != p) { - /* only if it is an enddir */ - dir_cur_v(enddir_ptr) = cur.v; - dir_refpos_h(enddir_ptr) = refpos->pos.h; - dir_refpos_v(enddir_ptr) = refpos->pos.v; - /* negative: mark it as |enddir| */ - dir_dir(enddir_ptr) = localpos.dir - dir_swap; - } - /* fake a nested |hlist_out| */ - synch_pos_with_cur(pdf->posstruct, refpos, cur); - refpos->pos = pdf->posstruct->pos; - localpos.dir = dir_dir(p); - cur.h = 0; - cur.v = 0; - } else { - refpos->pos.h = dir_refpos_h(p); - refpos->pos.v = dir_refpos_v(p); - localpos.dir = dir_dir(p) + dir_swap; - cur.h = dir_cur_h(p); - cur.v = dir_cur_v(p); - } - break; - case whatsit_node: - /* output the whatsit node |p| in |hlist_out| */ - switch (subtype(p)) { - case save_pos_node: - last_position = pdf->posstruct->pos; - pos_info.curpos = pdf->posstruct->pos; - pos_info.boxpos.pos = refpos->pos; - pos_info.boxpos.dir = localpos.dir; - pos_info.boxdim.wd = width(this_box); - pos_info.boxdim.ht = height(this_box); - pos_info.boxdim.dp = depth(this_box); - break; - case pdf_annot_node: - case pdf_start_link_node: - case pdf_dest_node: - case pdf_start_thread_node: - case pdf_thread_node: - backend_out_whatsit[subtype(p)] (pdf, p, this_box, cur); + cur.h += effective_horizontal; break; - default: - out_what(pdf, p); - } - break; - case math_node: - if (synctex) { - synctexmath(p, this_box); - } - /* begin mathskip code */ - if (glue_ptr(p) == zero_glue) { - cur.h += surround(p); + case disc_node: + /* hh: the frontend should append already */ + if (vlink(no_break(p)) != null) { + if (subtype(p) != select_disc) { + q = tail_of_list(vlink(no_break(p))); /* this could be a tlink */ + vlink(q) = vlink(p); + q = vlink(no_break(p)); + vlink(no_break(p)) = null; + vlink(p) = q; + } + } break; - } else { - /* fall through: mathskip */ - } - /* end mathskip code */ - case glue_node: - { - /* move right or output leaders, we use real multiplication */ - halfword g = glue_ptr(p); - rule.wd = width(g) - cur_g; - if (g_sign != normal) { - if (g_sign == stretching) { - if (stretch_order(g) == g_order) { - cur_glue = cur_glue + stretch(g); + case glue_node: + { + /* move right or output leaders, we use real multiplication */ + halfword g = glue_ptr(p); + rule.wd = width(g) - cur_g; + if (g_sign != normal) { + if (g_sign == stretching) { + if (stretch_order(g) == g_order) { + cur_glue = cur_glue + stretch(g); + vet_glue(float_cast(glue_set(this_box)) * cur_glue); + cur_g = float_round(glue_temp); + } + } else if (shrink_order(g) == g_order) { + cur_glue = cur_glue - shrink(g); vet_glue(float_cast(glue_set(this_box)) * cur_glue); cur_g = float_round(glue_temp); } - } else if (shrink_order(g) == g_order) { - cur_glue = cur_glue - shrink(g); - vet_glue(float_cast(glue_set(this_box)) * cur_glue); - cur_g = float_round(glue_temp); - } - } - rule.wd = rule.wd + cur_g; - if (subtype(p) >= a_leaders) { - /* output leaders in an hlist, |goto fin_rule| if a rule or to |next_p| if done */ - leader_box = leader_ptr(p); - if (type(leader_box) == rule_node) { - rule.ht = height(leader_box); - rule.dp = depth(leader_box); - goto FIN_RULE; } - if (textdir_parallel(box_dir(leader_box), localpos.dir)) - leader_wd = width(leader_box); - else - leader_wd = height(leader_box) + depth(leader_box); - if ((leader_wd > 0) && (rule.wd > 0)) { - rule.wd = rule.wd + 10; /* compensate for floating-point rounding */ - edge = cur.h + rule.wd; - lx = 0; - /* - let |cur.h| be the position of the first box, and set |leader_wd+lx| - to the spacing between corresponding parts of boxes - */ - if (subtype(p) == g_leaders) { - save_h = cur.h; - switch (localpos.dir) { - case dir_TLT: - cur.h += refpos->pos.h - shipbox_refpos.h; - cur.h = leader_wd * (cur.h / leader_wd); - cur.h -= refpos->pos.h - shipbox_refpos.h; - break; - case dir_TRT: - cur.h = refpos->pos.h - shipbox_refpos.h - cur.h; - cur.h = leader_wd * (cur.h / leader_wd); - cur.h = refpos->pos.h - shipbox_refpos.h - cur.h; - break; - case dir_LTL: - case dir_RTT: - cur.h = refpos->pos.v - shipbox_refpos.v - cur.h; + rule.wd = rule.wd + cur_g; + if (subtype(p) >= a_leaders) { + /* output leaders in an hlist, |goto fin_rule| if a rule or to |next_p| if done */ + leader_box = leader_ptr(p); + if (type(leader_box) == rule_node) { + rule.ht = height(leader_box); + rule.dp = depth(leader_box); + goto FIN_RULE; + } + if (textdir_parallel(box_dir(leader_box), localpos.dir)) + leader_wd = width(leader_box); + else + leader_wd = height(leader_box) + depth(leader_box); + if ((leader_wd > 0) && (rule.wd > 0)) { + rule.wd = rule.wd + 10; /* compensate for floating-point rounding */ + edge = cur.h + rule.wd; + lx = 0; + /* + let |cur.h| be the position of the first box, and set |leader_wd+lx| + to the spacing between corresponding parts of boxes + */ + if (subtype(p) == g_leaders) { + save_h = cur.h; + switch (localpos.dir) { + case dir_TLT: + cur.h += refpos->pos.h - shipbox_refpos.h; + cur.h = leader_wd * (cur.h / leader_wd); + cur.h -= refpos->pos.h - shipbox_refpos.h; + break; + case dir_TRT: + cur.h = refpos->pos.h - shipbox_refpos.h - cur.h; + cur.h = leader_wd * (cur.h / leader_wd); + cur.h = refpos->pos.h - shipbox_refpos.h - cur.h; + break; + case dir_LTL: + case dir_RTT: + cur.h = refpos->pos.v - shipbox_refpos.v - cur.h; + cur.h = leader_wd * (cur.h / leader_wd); + cur.h = refpos->pos.v - shipbox_refpos.v - cur.h; + break; + default: + formatted_warning("pdf backend","forcing bad dir %i to TLT in hlist case 1",localpos.dir); + localpos.dir = dir_TLT; + cur.h += refpos->pos.h - shipbox_refpos.h; + cur.h = leader_wd * (cur.h / leader_wd); + cur.h -= refpos->pos.h - shipbox_refpos.h; + break; + } + if (cur.h < save_h) + cur.h += leader_wd; + } else if (subtype(p) == a_leaders) { + save_h = cur.h; cur.h = leader_wd * (cur.h / leader_wd); - cur.h = refpos->pos.v - shipbox_refpos.v - cur.h; - break; - default: - assert(0); - } - if (cur.h < save_h) - cur.h += leader_wd; - } else if (subtype(p) == a_leaders) { - save_h = cur.h; - cur.h = leader_wd * (cur.h / leader_wd); - if (cur.h < save_h) - cur.h += leader_wd; - } else { - lq = rule.wd / leader_wd; /* the number of box copies */ - lr = rule.wd % leader_wd; /* the remaining space */ - if (subtype(p) == c_leaders) { - cur.h += lr / 2; + if (cur.h < save_h) + cur.h += leader_wd; } else { - lx = lr / (lq + 1); - cur.h += (lr - (lq - 1) * lx) / 2; + lq = rule.wd / leader_wd; /* the number of box copies */ + lr = rule.wd % leader_wd; /* the remaining space */ + if (subtype(p) == c_leaders) { + cur.h += lr / 2; + } else { + lx = lr / (lq + 1); + cur.h += (lr - (lq - 1) * lx) / 2; + } } - } - while (cur.h + leader_wd <= edge) { - /* output a leader box at |cur.h|, then advance |cur.h| by |leader_wd+lx| */ - if (pardir_parallel(box_dir(leader_box), localpos.dir)) { - basepoint.v = 0; - if (textdir_opposite(box_dir(leader_box), localpos.dir)) - basepoint.h = width(leader_box); - else - basepoint.h = 0; - } else { - if (!is_mirrored(box_dir(leader_box))) { - if (partextdir_eq(box_dir(leader_box), localpos.dir)) - basepoint.h = height(leader_box); + while (cur.h + leader_wd <= edge) { + /* output a leader box at |cur.h|, then advance |cur.h| by |leader_wd+lx| */ + if (pardir_parallel(box_dir(leader_box), localpos.dir)) { + basepoint.v = 0; + if (textdir_opposite(box_dir(leader_box), localpos.dir)) + basepoint.h = width(leader_box); else - basepoint.h = depth(leader_box); + basepoint.h = 0; } else { - if (partextdir_eq(box_dir(leader_box), localpos.dir)) - basepoint.h = depth(leader_box); + if (!is_mirrored(box_dir(leader_box))) { + if (partextdir_eq(box_dir(leader_box), localpos.dir)) + basepoint.h = height(leader_box); + else + basepoint.h = depth(leader_box); + } else { + if (partextdir_eq(box_dir(leader_box), localpos.dir)) + basepoint.h = depth(leader_box); + else + basepoint.h = height(leader_box); + } + if (partextdir_eq(localpos.dir, box_dir(leader_box))) + basepoint.v = -(width(leader_box) / 2); else - basepoint.h = height(leader_box); + basepoint.v = (width(leader_box) / 2); } - if (partextdir_eq(localpos.dir, box_dir(leader_box))) - basepoint.v = -(width(leader_box) / 2); + if (!is_mirrored(localpos.dir)) + basepoint.v = basepoint.v + shift_amount(leader_box); /* shift the box down */ + else + basepoint.v = basepoint.v - shift_amount(leader_box); /* shift the box up */ + tmpcur.h = cur.h + basepoint.h; + tmpcur.v = basepoint.v; + synch_pos_with_cur(pdf->posstruct, refpos, tmpcur); + outer_doing_leaders = doing_leaders; + doing_leaders = true; + if (type(leader_box) == vlist_node) + vlist_out(pdf, leader_box, rule_callback_id); else - basepoint.v = (width(leader_box) / 2); + hlist_out(pdf, leader_box, rule_callback_id); + doing_leaders = outer_doing_leaders; + cur.h += leader_wd + lx; } - if (!is_mirrored(localpos.dir)) - basepoint.v = basepoint.v + shift_amount(leader_box); /* shift the box down */ - else - basepoint.v = basepoint.v - shift_amount(leader_box); /* shift the box up */ - assert(cur.v == 0); - tmpcur.h = cur.h + basepoint.h; - tmpcur.v = basepoint.v; - synch_pos_with_cur(pdf->posstruct, refpos, tmpcur); - outer_doing_leaders = doing_leaders; - doing_leaders = true; - if (type(leader_box) == vlist_node) - vlist_out(pdf, leader_box); - else - hlist_out(pdf, leader_box); - doing_leaders = outer_doing_leaders; - cur.h += leader_wd + lx; + cur.h = edge - 10; + goto NEXTP; } - cur.h = edge - 10; - goto NEXTP; } - } - } - goto MOVE_PAST; - break; - case margin_kern_node: - cur.h += width(p); - break; - case kern_node: - if (synctex) - synctexkern(p, this_box); - cur.h += width(p); - break; - default: - break; + } + goto MOVE_PAST; + break; + case kern_node: + if (synctex) + synctexkern(p, this_box); + cur.h += width(p); + break; + case rule_node: + if (rule_dir(p) < 0) + rule_dir(p) = localpos.dir; + if (pardir_parallel(rule_dir(p), localpos.dir)) { + rule.ht = height(p); + rule.dp = depth(p); + rule.wd = width(p); + } else { + rule.ht = width(p) / 2; + rule.dp = width(p) / 2; + rule.wd = height(p) + depth(p); + } + goto FIN_RULE; + break; + case dir_node: + /* output a reflection instruction if the direction has changed */ + if (dir_dir(p) >= 0) { + /* + Calculate the needed width to the matching |enddir|, return the + |enddir| node, with width info + */ + enddir_ptr = calculate_width_to_enddir(p, cur_glue, cur_g, this_box); + if (textdir_parallel(dir_dir(p), localpos.dir)) { + dir_cur_h(enddir_ptr) += cur.h; + if (textdir_opposite(dir_dir(p), localpos.dir)) + cur.h = dir_cur_h(enddir_ptr); + } else + dir_cur_h(enddir_ptr) = cur.h; + if (enddir_ptr != p) { + /* only if it is an enddir */ + dir_cur_v(enddir_ptr) = cur.v; + dir_refpos_h(enddir_ptr) = refpos->pos.h; + dir_refpos_v(enddir_ptr) = refpos->pos.v; + /* negative: mark it as |enddir| */ + dir_dir(enddir_ptr) = localpos.dir - dir_swap; + } + /* fake a nested |hlist_out| */ + synch_pos_with_cur(pdf->posstruct, refpos, cur); + refpos->pos = pdf->posstruct->pos; + localpos.dir = dir_dir(p); + cur.h = 0; + cur.v = 0; + } else { + refpos->pos.h = dir_refpos_h(p); + refpos->pos.v = dir_refpos_v(p); + localpos.dir = dir_dir(p) + dir_swap; + cur.h = dir_cur_h(p); + cur.v = dir_cur_v(p); + } + break; + case whatsit_node: + /* output the whatsit node |p| in |hlist_out| */ + switch (subtype(p)) { + case save_pos_node: + last_position = pdf->posstruct->pos; + pos_info.curpos = pdf->posstruct->pos; + pos_info.boxpos.pos = refpos->pos; + pos_info.boxpos.dir = localpos.dir; + pos_info.boxdim.wd = width(this_box); + pos_info.boxdim.ht = height(this_box); + pos_info.boxdim.dp = depth(this_box); + break; + case pdf_annot_node: + case pdf_start_link_node: + case pdf_dest_node: + case pdf_start_thread_node: + case pdf_thread_node: + backend_out_whatsit[subtype(p)] (pdf, p, this_box, cur); + break; + default: + out_what(pdf, p); + } + break; + case math_node: + if (synctex) { + synctexmath(p, this_box); + } + /* begin mathskip code */ + if (glue_ptr(p) == zero_glue) { + cur.h += surround(p); + break; + } else { + /* fall through: mathskip */ + } + /* end mathskip code */ + case margin_kern_node: + cur.h += width(p); + break; + default: + break; } goto NEXTP; FIN_RULE: @@ -669,39 +659,44 @@ void hlist_out(PDF pdf, halfword this_box) /* we don't output empty rules */ if ((rule.ht + rule.dp) > 0 && rule.wd > 0) { switch (localpos.dir) { - case dir_TLT: - size.h = rule.wd; - size.v = rule.ht + rule.dp; - pos_down(rule.dp); - break; - case dir_TRT: - size.h = rule.wd; - size.v = rule.ht + rule.dp; - pos_left(size.h); - pos_down(rule.dp); - break; - case dir_LTL: - size.h = rule.ht + rule.dp; - size.v = rule.wd; - pos_left(rule.ht); - pos_down(size.v); - break; - case dir_RTT: - size.h = rule.ht + rule.dp; - size.v = rule.wd; - pos_left(rule.dp); - pos_down(size.v); - break; - default: - assert(0); + case dir_TLT: + size.h = rule.wd; + size.v = rule.ht + rule.dp; + pos_down(rule.dp); + break; + case dir_TRT: + size.h = rule.wd; + size.v = rule.ht + rule.dp; + pos_left(size.h); + pos_down(rule.dp); + break; + case dir_LTL: + size.h = rule.ht + rule.dp; + size.v = rule.wd; + pos_left(rule.ht); + pos_down(size.v); + break; + case dir_RTT: + size.h = rule.ht + rule.dp; + size.v = rule.wd; + pos_left(rule.dp); + pos_down(size.v); + break; + default: + formatted_warning("pdf backend","forcing bad dir %i to TLT in hlist case 2",localpos.dir); + localpos.dir = dir_TLT; + size.h = rule.wd; + size.v = rule.ht + rule.dp; + pos_down(rule.dp); + break; } if (type(p) == glue_node) { q = leader_ptr(p); if ((q) && (type(q) == rule_node)) { - backend_out[rule_node] (pdf, q, size); + backend_out[rule_node] (pdf, q, size, rule_callback_id); } } else { - backend_out[rule_node] (pdf, p, size); + backend_out[rule_node] (pdf, p, size, rule_callback_id); } } MOVE_PAST: @@ -715,10 +710,8 @@ void hlist_out(PDF pdf, halfword this_box) synch_pos_with_cur(pdf->posstruct, refpos, cur); } } - if (synctex) synctextsilh(this_box); - if (output_mode_used == OMODE_DVI) { prune_movements(save_loc); if (cur_s > 0) { @@ -731,7 +724,7 @@ void hlist_out(PDF pdf, halfword this_box) } @ @c -void vlist_out(PDF pdf, halfword this_box) +void vlist_out(PDF pdf, halfword this_box, int rule_callback_id) { posstructure localpos; /* the position structure local within this function */ posstructure *refpos; /* the list origin pos. on the page, provided by the caller */ @@ -790,11 +783,7 @@ void vlist_out(PDF pdf, halfword this_box) check_running_thread(pdf, this_box, cur); while (p != null) { - if (is_char_node(p)) { - confusion("vlistout"); /* this can't happen */ - } else { - /* output the non-|char_node| |p| for |vlist_out| */ - switch (type(p)) { + switch (type(p)) { case hlist_node: case vlist_node: /* @@ -846,14 +835,13 @@ void vlist_out(PDF pdf, halfword this_box) synctexvoidhlist(p, this_box); } } else { - assert(cur.h == 0); tmpcur.h = basepoint.h; tmpcur.v = cur.v + basepoint.v; synch_pos_with_cur(pdf->posstruct, refpos, tmpcur); if (type(p) == vlist_node) - vlist_out(pdf, p); + vlist_out(pdf, p, rule_callback_id); else - hlist_out(pdf, p); + hlist_out(pdf, p, rule_callback_id); cur.v += effective_vertical; } break; @@ -871,29 +859,6 @@ void vlist_out(PDF pdf, halfword this_box) } goto FIN_RULE; break; - case whatsit_node: - /* output the whatsit node |p| in |vlist_out| */ - switch (subtype(p)) { - case save_pos_node: - last_position = pdf->posstruct->pos; - pos_info.curpos = pdf->posstruct->pos; - pos_info.boxpos.pos = refpos->pos; - pos_info.boxpos.dir = localpos.dir; - pos_info.boxdim.wd = width(this_box); - pos_info.boxdim.ht = height(this_box); - pos_info.boxdim.dp = depth(this_box); - break; - case pdf_annot_node: - case pdf_start_link_node: - case pdf_dest_node: - case pdf_start_thread_node: - case pdf_thread_node: - backend_out_whatsit[subtype(p)] (pdf, p, this_box, cur); - break; - default: - out_what(pdf, p); - } - break; case glue_node: { /* move down or output leaders, we use real multiplication */ @@ -933,24 +898,29 @@ void vlist_out(PDF pdf, halfword this_box) if (subtype(p) == g_leaders) { save_v = cur.v; switch (localpos.dir) { - case dir_LTL: - cur.v += refpos->pos.h - shipbox_refpos.h; - cur.v = leader_ht * (cur.v / leader_ht); - cur.v -= refpos->pos.h - shipbox_refpos.h; - break; - case dir_RTT: - cur.v = refpos->pos.h - shipbox_refpos.h - cur.v; - cur.v = leader_ht * (cur.v / leader_ht); - cur.v = refpos->pos.h - shipbox_refpos.h - cur.v; - break; - case dir_TLT: - case dir_TRT: - cur.v = refpos->pos.v - shipbox_refpos.v - cur.v; - cur.v = leader_ht * (cur.v / leader_ht); - cur.v = refpos->pos.v - shipbox_refpos.v - cur.v; - break; - default: - assert(0); + case dir_LTL: + cur.v += refpos->pos.h - shipbox_refpos.h; + cur.v = leader_ht * (cur.v / leader_ht); + cur.v -= refpos->pos.h - shipbox_refpos.h; + break; + case dir_RTT: + cur.v = refpos->pos.h - shipbox_refpos.h - cur.v; + cur.v = leader_ht * (cur.v / leader_ht); + cur.v = refpos->pos.h - shipbox_refpos.h - cur.v; + break; + case dir_TLT: + case dir_TRT: + cur.v = refpos->pos.v - shipbox_refpos.v - cur.v; + cur.v = leader_ht * (cur.v / leader_ht); + cur.v = refpos->pos.v - shipbox_refpos.v - cur.v; + break; + default: + formatted_warning("pdf backend","forcing bad dir %i to TLT in vlist case 1",localpos.dir); + localpos.dir = dir_TLT; + cur.v += refpos->pos.h - shipbox_refpos.h; + cur.v = leader_ht * (cur.v / leader_ht); + cur.v -= refpos->pos.h - shipbox_refpos.h; + break; } if (cur.v < save_v) cur.v += leader_ht; @@ -972,16 +942,15 @@ void vlist_out(PDF pdf, halfword this_box) while (cur.v + leader_ht <= edge) { /* output a leader box at |cur.v|, then advance |cur.v| by |leader_ht+lx| */ - assert(cur.h == 0); tmpcur.h = shift_amount(leader_box); tmpcur.v = cur.v + height(leader_box); synch_pos_with_cur(pdf->posstruct, refpos, tmpcur); outer_doing_leaders = doing_leaders; doing_leaders = true; if (type(leader_box) == vlist_node) - vlist_out(pdf, leader_box); + vlist_out(pdf, leader_box, rule_callback_id); else - hlist_out(pdf, leader_box); + hlist_out(pdf, leader_box, rule_callback_id); doing_leaders = outer_doing_leaders; cur.v += leader_ht + lx; } @@ -995,17 +964,44 @@ void vlist_out(PDF pdf, halfword this_box) case kern_node: cur.v += width(p); break; + case whatsit_node: + /* output the whatsit node |p| in |vlist_out| */ + switch (subtype(p)) { + case save_pos_node: + last_position = pdf->posstruct->pos; + pos_info.curpos = pdf->posstruct->pos; + pos_info.boxpos.pos = refpos->pos; + pos_info.boxpos.dir = localpos.dir; + pos_info.boxdim.wd = width(this_box); + pos_info.boxdim.ht = height(this_box); + pos_info.boxdim.dp = depth(this_box); + break; + case pdf_annot_node: + case pdf_start_link_node: + case pdf_dest_node: + case pdf_start_thread_node: + case pdf_thread_node: + backend_out_whatsit[subtype(p)] (pdf, p, this_box, cur); + break; + default: + out_what(pdf, p); + } + break; + case glyph_node: + case disc_node: + confusion("vlistout"); /* this can't happen */ + break; default: break; - } - goto NEXTP; - FIN_RULE: - /* output a rule in a vlist, |goto next_p| */ - if (is_running(rule.wd)) - rule.wd = width(this_box); - /* we don't output empty rules */ - if ((rule.ht + rule.dp) > 0 && rule.wd > 0) { - switch (localpos.dir) { + } + goto NEXTP; + FIN_RULE: + /* output a rule in a vlist, |goto next_p| */ + if (is_running(rule.wd)) + rule.wd = width(this_box); + /* we don't output empty rules */ + if ((rule.ht + rule.dp) > 0 && rule.wd > 0) { + switch (localpos.dir) { case dir_TLT: size.h = rule.wd; size.v = rule.ht + rule.dp; @@ -1029,24 +1025,28 @@ void vlist_out(PDF pdf, halfword this_box) pos_down(size.v); break; default: - assert(0); - } - if (type(p) == glue_node) { - q = leader_ptr(p); - if ((q) && (type(q) == rule_node)) { - backend_out[rule_node] (pdf, q, size); - } - } else { - backend_out[rule_node] (pdf, p, size); + formatted_warning("pdf backend","forcing bad dir %i to TLT in vlist case 2",localpos.dir); + localpos.dir = dir_TLT; + size.h = rule.wd; + size.v = rule.ht + rule.dp; + pos_down(size.v); + break; + } + if (type(p) == glue_node) { + q = leader_ptr(p); + if ((q) && (type(q) == rule_node)) { + backend_out[rule_node] (pdf, q, size, rule_callback_id); } + } else { + backend_out[rule_node] (pdf, p, size, rule_callback_id); } - cur.v += rule.ht + rule.dp; - goto NEXTP; - MOVE_PAST: - cur.v += rule.ht; - NEXTP: - p = vlink(p); } + cur.v += rule.ht + rule.dp; + goto NEXTP; + MOVE_PAST: + cur.v += rule.ht; + NEXTP: + p = vlink(p); synch_pos_with_cur(pdf->posstruct, refpos, cur); } if (synctex) diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdfliteral.h b/Build/source/texk/web2c/luatexdir/pdf/pdfliteral.h index 134bca44a24..14c197d0f72 100644 --- a/Build/source/texk/web2c/luatexdir/pdf/pdfliteral.h +++ b/Build/source/texk/web2c/luatexdir/pdf/pdfliteral.h @@ -15,13 +15,13 @@ 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/>. */ + with LuaTeX; if not, see <http://www.gnu.org/licenses/>. +*/ #ifndef PDFLITERAL_H # define PDFLITERAL_H - # define set_pdf_literal_mode(A,B) pdf_literal_mode(A)=B # define set_pdf_literal_type(A,B) pdf_literal_type(A)=B # define set_pdf_literal_data(A,B) pdf_literal_data(A)=B diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdfliteral.w b/Build/source/texk/web2c/luatexdir/pdf/pdfliteral.w index dae67234a51..3c6b6f6efbf 100644 --- a/Build/source/texk/web2c/luatexdir/pdf/pdfliteral.w +++ b/Build/source/texk/web2c/luatexdir/pdf/pdfliteral.w @@ -19,15 +19,13 @@ @ @c - #include "ptexlib.h" @ @c void pdf_special(PDF pdf, halfword p) { - int old_setting; /* holds print |selector| */ + int old_setting = selector; str_number s; - old_setting = selector; selector = new_string; show_token_list(token_link(write_tokens(p)), null, -1); selector = old_setting; @@ -36,11 +34,10 @@ void pdf_special(PDF pdf, halfword p) flush_str(s); } - @ To ship out a \TeX\ box to PDF page description we need to implement -|hlist_out|, |vlist_out| and |ship_out|, which are equivalent to -the \TeX' original |hlist_out|, |vlist_out| and |ship_out| resp. But first we -need to declare some procedures needed in |hlist_out| and |vlist_out|. +|hlist_out|, |vlist_out| and |ship_out|, which are equivalent to the \TeX' +original |hlist_out|, |vlist_out| and |ship_out| resp. But first we need to +declare some procedures needed in |hlist_out| and |vlist_out|. @c void pdf_out_literal(PDF pdf, halfword p) @@ -57,22 +54,21 @@ void pdf_out_literal(PDF pdf, halfword p) pdf_literal(pdf, s, pdf_literal_mode(p), false); flush_str(s); } else { - assert(pdf_literal_mode(p) != scan_special); switch (pdf_literal_mode(p)) { - case set_origin: - pdf_goto_pagemode(pdf); - pdf_set_pos(pdf, pdf->posstruct->pos); - break; - case direct_page: - pdf_goto_pagemode(pdf); - break; - case direct_always: - pdf_end_string_nl(pdf); - ps->need_tm = true; - break; - default: - confusion("literal1"); - break; + case set_origin: + pdf_goto_pagemode(pdf); + pdf_set_pos(pdf, pdf->posstruct->pos); + break; + case direct_page: + pdf_goto_pagemode(pdf); + break; + case direct_always: + pdf_end_string_nl(pdf); + ps->need_tm = true; + break; + default: + normal_error("pdf backend","bad literal mode"); + break; } lua_pdf_literal(pdf, pdf_literal_data(p)); } @@ -101,7 +97,8 @@ void pdf_literal(PDF pdf, str_number s, int literal_mode, boolean warn) size_t l; pool_pointer j = 0; /* current character code position, initialized to make the compiler happy */ pdfstructure *p = pdf->pstruct; - if (s >= STRING_OFFSET) { /* needed for |out_save| */ + if (s >= STRING_OFFSET) { + /* needed for |out_save| */ j = 0; /* the next is obsolete, in fact, specials are obsolete in pdf mode */ if (literal_mode == scan_special) { @@ -123,27 +120,26 @@ void pdf_literal(PDF pdf, str_number s, int literal_mode, boolean warn) } } switch (literal_mode) { - case set_origin: - pdf_goto_pagemode(pdf); - pdf_set_pos(pdf, pdf->posstruct->pos); - break; - case direct_page: - pdf_goto_pagemode(pdf); - break; - case direct_always: - pdf_end_string_nl(pdf); - p->need_tm = true; - break; - default: - confusion("literal1"); - break; + case set_origin: + pdf_goto_pagemode(pdf); + pdf_set_pos(pdf, pdf->posstruct->pos); + break; + case direct_page: + pdf_goto_pagemode(pdf); + break; + case direct_always: + pdf_end_string_nl(pdf); + p->need_tm = true; + break; + default: + normal_error("pdf backend","bad literal mode"); + break; } if (s >= STRING_OFFSET) { ss = str_string(s); l = str_length(s) - (size_t) j; pdf_out_block(pdf, (const char *) (ss + j), l); } else { - assert(s < 256); pdf_out(pdf, s); } pdf_out(pdf, '\n'); diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdfluaapi.h b/Build/source/texk/web2c/luatexdir/pdf/pdfluaapi.h deleted file mode 100644 index 3d8652ecc67..00000000000 --- a/Build/source/texk/web2c/luatexdir/pdf/pdfluaapi.h +++ /dev/null @@ -1,29 +0,0 @@ -/* pdfluaapi.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/>. */ - - -#ifndef PDFLUAAPI_H -# define PDFLUAAPI_H - -extern int new_pdflua(void); -extern void pdflua_begin_page(PDF pdf); -extern void pdflua_end_page(PDF pdf, int annots, int beads); -extern void pdflua_output_pages_tree(PDF pdf); - -#endif /* PDFLUAAPI_H */ diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdfluaapi.w b/Build/source/texk/web2c/luatexdir/pdf/pdfluaapi.w deleted file mode 100644 index ebd20d6e20d..00000000000 --- a/Build/source/texk/web2c/luatexdir/pdf/pdfluaapi.w +++ /dev/null @@ -1,113 +0,0 @@ -% pdfluaapi.w -% -% Copyright 2010 Taco Hoekwater <taco@@luatex.org> -% -% This file is part of LuaTeX. -% -% LuaTeX is free software; you can redistribute it and/or modify it under -% the terms of the GNU General Public License as published by the Free -% Software Foundation; either version 2 of the License, or (at your -% option) any later version. -% -% LuaTeX is distributed in the hope that it will be useful, but WITHOUT -% ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -% FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public -% License for more details. -% -% You should have received a copy of the GNU General Public License along -% with LuaTeX; if not, see <http://www.gnu.org/licenses/>. - -@ @c - - -#include "ptexlib.h" - -@ @c -int new_pdflua(void) -{ - int i, err; - Byte *uncompr; - const zlib_struct *zp = pdflua_zlib_struct_ptr; - uLong uncomprLen = zp->uncomprLen; - if ((uncompr = xtalloc(zp->uncomprLen, Byte)) == NULL) - luatex_fail("new_pdflua(): xtalloc()"); - err = uncompress(uncompr, &uncomprLen, zp->compr, zp->comprLen); - if (err != Z_OK) - luatex_fail("new_pdflua(): uncompress()"); - assert(uncomprLen == zp->uncomprLen); - if (luaL_loadbuffer(Luas, (const char *) uncompr, uncomprLen, "pdflua") - || lua_pcall(Luas, 0, 1, 0)) - luatex_fail("new_pdflua(): lua_pcall()"); - luaL_checktype(Luas, -1, LUA_TTABLE); /* t */ - i = luaL_ref(Luas, LUA_REGISTRYINDEX); /* - */ - xfree(uncompr); - return i; -} - -@ @c -void pdflua_begin_page(PDF pdf) -{ - int err; /* ... */ - lua_rawgeti(Luas, LUA_REGISTRYINDEX, pdf->pdflua_ref); /* t ... */ - lua_pushstring(Luas, "beginpage"); /* s t ... */ - lua_gettable(Luas, -2); /* f t ... */ - lua_newtable(Luas); /* t f t ... */ - lua_pushnumber(Luas, total_pages + 1); /* i t f t ... */ - lua_setfield(Luas, -2, "pagenum"); /* t f t ... */ - lua_pushnumber(Luas, pdf->last_page); /* i t f t ... */ - lua_setfield(Luas, -2, "page_objnum"); /* t f t ... */ - lua_pushnumber(Luas, pdf->last_stream); /* i t f t ... */ - lua_setfield(Luas, -2, "stream_objnum"); /* t f t ... */ - lua_pushnumber(Luas, pdf->page_resources->last_resources); /* i t f t ... */ - lua_setfield(Luas, -2, "resources_objnum"); /* t f t ... */ - err = lua_pcall(Luas, 1, 0, 0); /* (e) t ... */ - if (err != 0) - luatex_fail("pdflua.lua: beginpage()"); - /* t ... */ - lua_pop(Luas, 1); /* ... */ -} - -@ @c -void pdflua_end_page(PDF pdf, int annots, int beads) -{ - int err; /* ... */ - lua_rawgeti(Luas, LUA_REGISTRYINDEX, pdf->pdflua_ref); /* t ... */ - lua_pushstring(Luas, "endpage"); /* s t ... */ - lua_gettable(Luas, -2); /* f t ... */ - lua_newtable(Luas); /* t f t ... */ - lua_pushnumber(Luas, total_pages); /* i t f t ... */ - lua_setfield(Luas, -2, "pagenum"); /* t f t ... */ - lua_pushnumber(Luas, pdf->page_size.h); /* i t f t ... */ - lua_setfield(Luas, -2, "hsize"); /* t f t ... */ - lua_pushnumber(Luas, pdf->page_size.v); /* i t f t ... */ - lua_setfield(Luas, -2, "vsize"); /* t f t ... */ - if (annots != 0) { - lua_pushnumber(Luas, annots); /* i t f t ... */ - lua_setfield(Luas, -2, "annots"); /* t f t ... */ - } - if (beads != 0) { - lua_pushnumber(Luas, beads); /* i t f t ... */ - lua_setfield(Luas, -2, "beads"); /* t f t ... */ - } - if (pdf->img_page_group_val != 0) { - lua_pushnumber(Luas, pdf->img_page_group_val); /* i t f t ... */ - lua_setfield(Luas, -2, "imggroup"); /* t f t ... */ - } - err = lua_pcall(Luas, 1, 0, 0); /* (e) t ... */ - if (err != 0) - luatex_fail("pdflua.lua: endpage()"); - /* t ... */ - lua_pop(Luas, 1); /* ... */ -} - -@ @c -void pdflua_output_pages_tree(PDF pdf) -{ - int err; - lua_rawgeti(Luas, LUA_REGISTRYINDEX, pdf->pdflua_ref); /* t */ - lua_pushstring(Luas, "outputpagestree"); /* s t */ - lua_gettable(Luas, -2); /* f */ - err = lua_pcall(Luas, 0, 0, 0); /* - */ - if (err != 0) - luatex_fail("pdflua.lua: outputpagestree()"); -} diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdfobj.h b/Build/source/texk/web2c/luatexdir/pdf/pdfobj.h index ad392338509..f8fac35eea7 100644 --- a/Build/source/texk/web2c/luatexdir/pdf/pdfobj.h +++ b/Build/source/texk/web2c/luatexdir/pdf/pdfobj.h @@ -15,8 +15,8 @@ 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/>. */ - + with LuaTeX; if not, see <http://www.gnu.org/licenses/>. +*/ #ifndef PDFOBJ_H # define PDFOBJ_H @@ -25,21 +25,13 @@ # define set_pdf_obj_objnum(A, B) pdf_obj_objnum(A) = (B) -# define pdfmem_obj_size 5 /* size of memory in |mem| which |obj_data_ptr| holds */ - -# define obj_obj_data(pdf, A) pdf->mem[obj_data_ptr((pdf), (A)) + 0] /* object data */ -# define obj_obj_stream_attr(pdf, A) pdf->mem[obj_data_ptr((pdf), (A)) + 1] /* additional attributes into stream dict */ -# define obj_obj_flags(pdf, A) pdf->mem[obj_data_ptr((pdf), (A)) + 2] /* stream/file flags */ -# define obj_obj_pdfcompresslevel(pdf, A) pdf->mem[obj_data_ptr((pdf), (A)) + 3] /* overrides \pdfcompresslevel */ -# define obj_obj_objstm_threshold(pdf, A) pdf->mem[obj_data_ptr((pdf), (A)) + 4] /* for object stream compression */ +# define pdfmem_obj_size 5 /* size of memory in |mem| which |obj_data_ptr| holds */ -/* define set_obj_obj_data(pdf, A, B) obj_obj_data((pdf), (A)) = (B) */ -/* define set_obj_obj_flags(pdf, A, B) obj_obj_flags((pdf), (A)) = (B) */ -/* define set_obj_obj_stream_attr(pdf, A, B) obj_obj_stream_attr((pdf), (A)) = (B) */ -/* define set_obj_obj_pdfcompresslevel(pdf, A, B) obj_obj_pdfcompresslevel((pdf), (A)) = (B) */ -/* define set_obj_obj_objstm_threshold(pdf, A, B) obj_obj_objstm_threshold((pdf), (A)) = (B) */ - -/**********************************************************************/ +# define obj_obj_data(pdf, A) pdf->mem[obj_data_ptr((pdf), (A)) + 0] /* object data */ +# define obj_obj_stream_attr(pdf, A) pdf->mem[obj_data_ptr((pdf), (A)) + 1] /* additional attributes into stream dict */ +# define obj_obj_flags(pdf, A) pdf->mem[obj_data_ptr((pdf), (A)) + 2] /* stream/file flags */ +# define obj_obj_pdfcompresslevel(pdf, A) pdf->mem[obj_data_ptr((pdf), (A)) + 3] /* overrides \pdfcompresslevel */ +# define obj_obj_objstm_threshold(pdf, A) pdf->mem[obj_data_ptr((pdf), (A)) + 4] /* for object stream compression */ # define OBJ_FLAG_ISSTREAM (1 << 0) # define OBJ_FLAG_ISFILE (1 << 1) @@ -52,8 +44,6 @@ # define set_obj_obj_is_file(pdf,A) ((obj_obj_flags((pdf), (A)) |= OBJ_FLAG_ISFILE)) # define unset_obj_obj_is_file(pdf,A) ((obj_obj_flags((pdf), (A)) &= ~OBJ_FLAG_ISFILE)) -/**********************************************************************/ - extern void init_obj_obj(PDF pdf, int k); extern void pdf_write_obj(PDF pdf, int n); extern void scan_obj(PDF pdf); diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdfobj.w b/Build/source/texk/web2c/luatexdir/pdf/pdfobj.w index a3aa09f3860..7dd51061595 100644 --- a/Build/source/texk/web2c/luatexdir/pdf/pdfobj.w +++ b/Build/source/texk/web2c/luatexdir/pdf/pdfobj.w @@ -67,8 +67,8 @@ void pdf_write_obj(PDF pdf, int k) st.l = li; lua_pop(Luas, 1); if (obj_obj_is_file(pdf, k)) { - boolean res = false; /* callback status value */ - const char *fnam = NULL; /* callback found filename */ + boolean res = false; /* callback status value */ + const char *fnam = NULL; /* callback found filename */ int callback_id; /* st.s is also |\0|-terminated, even as lstring */ fnam = luatex_find_file(st.s, find_data_file_callback); @@ -96,18 +96,10 @@ void pdf_write_obj(PDF pdf, int k) tprint("<<"); tprint(st.s); pdf_out_block(pdf, (const char *) data.s, data.l); - /* already happens in pdf_end_obj: - if (!obj_obj_is_stream(pdf, k) && data.s[data.l - 1] != '\n') - pdf_out(pdf, '\n'); - */ xfree(data.s); tprint(">>"); } else { pdf_out_block(pdf, st.s, st.l); - /* already happens in pdf_end_obj: - if (!obj_obj_is_stream(pdf, k) && st.s[st.l - 1] != '\n') - pdf_out(pdf, '\n'); - */ } if (obj_obj_is_stream(pdf, k)) { pdf_end_stream(pdf); @@ -126,16 +118,16 @@ void init_obj_obj(PDF pdf, int k) obj_obj_data(pdf, k) = LUA_NOREF; unset_obj_obj_is_stream(pdf, k); unset_obj_obj_is_file(pdf, k); - obj_obj_pdfcompresslevel(pdf, k) = -1; /* unset */ - obj_obj_objstm_threshold(pdf, k) = OBJSTM_UNSET; /* unset */ + obj_obj_pdfcompresslevel(pdf, k) = -1; /* unset */ + obj_obj_objstm_threshold(pdf, k) = OBJSTM_UNSET; /* unset */ } -@ The \.{\\pdfextension obj} primitive is used to create a ``raw'' object in the PDF - output file. The object contents will be hold in memory and will be written - out only when the object is referenced by \.{\\pdfextension refobj}. When - \.{\\pdfextension obj} is used with \.{\\immediate}, the object contents will be - written out immediately. Objects referenced in the current page are appended into - |pdf_obj_list|. +@ The \.{\\pdfextension obj} primitive is used to create a ``raw'' object in the +PDF output file. The object contents will be hold in memory and will be written +out only when the object is referenced by \.{\\pdfextension refobj}. When +\.{\\pdfextension obj} is used with \.{\\immediate}, the object contents will be +written out immediately. Objects referenced in the current page are appended into +|pdf_obj_list|. @c void scan_obj(PDF pdf) @@ -143,7 +135,6 @@ void scan_obj(PDF pdf) int k; lstring *st = NULL; if (scan_keyword("reserveobjnum")) { - /* Scan an optional space */ get_x_token(); if (cur_cmd != spacer_cmd) back_input(); @@ -163,13 +154,13 @@ void scan_obj(PDF pdf) obj_data_ptr(pdf, k) = pdf_get_mem(pdf, pdfmem_obj_size); init_obj_obj(pdf, k); if (scan_keyword("uncompressed")) { - obj_obj_pdfcompresslevel(pdf, k) = 0; /* \pdfcompresslevel = 0 */ + obj_obj_pdfcompresslevel(pdf, k) = 0; obj_obj_objstm_threshold(pdf, k) = OBJSTM_NEVER; } if (scan_keyword("stream")) { set_obj_obj_is_stream(pdf, k); if (scan_keyword("attr")) { - scan_pdf_ext_toks(); + scan_toks(false, true); st = tokenlist_to_lstring(def_ref, true); flush_list(def_ref); lua_pushlstring(Luas, (char *) st->s, st->l); @@ -180,7 +171,7 @@ void scan_obj(PDF pdf) } if (scan_keyword("file")) set_obj_obj_is_file(pdf, k); - scan_pdf_ext_toks(); + scan_toks(false, true); st = tokenlist_to_lstring(def_ref, true); flush_list(def_ref); lua_pushlstring(Luas, (char *) st->s, st->l); @@ -192,7 +183,7 @@ void scan_obj(PDF pdf) } @ @c -#define tail cur_list.tail_field +#define tail cur_list.tail_field void scan_refobj(PDF pdf) { diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdfoutline.h b/Build/source/texk/web2c/luatexdir/pdf/pdfoutline.h index 79002329953..a1c42df936e 100644 --- a/Build/source/texk/web2c/luatexdir/pdf/pdfoutline.h +++ b/Build/source/texk/web2c/luatexdir/pdf/pdfoutline.h @@ -15,7 +15,8 @@ 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/>. */ + with LuaTeX; if not, see <http://www.gnu.org/licenses/>. +*/ #ifndef PDFOUTLINE_H diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdfoutline.w b/Build/source/texk/web2c/luatexdir/pdf/pdfoutline.w index 922428da951..6c0a30a88d9 100644 --- a/Build/source/texk/web2c/luatexdir/pdf/pdfoutline.w +++ b/Build/source/texk/web2c/luatexdir/pdf/pdfoutline.w @@ -19,46 +19,44 @@ @ @c - #include "ptexlib.h" -@ Data structure of outlines; it's not able to write out outline entries -before all outline entries are defined, so memory allocated for outline -entries can't not be deallocated and will stay in memory. For this reason we -will store data of outline entries in |pdf->mem| instead of |mem| +@ Data structure of outlines; it's not able to write out outline entries before +all outline entries are defined, so memory allocated for outline entries can't +not be deallocated and will stay in memory. For this reason we will store data of +outline entries in |pdf->mem| instead of |mem| @c -#define pdfmem_outline_size 8 /* size of memory in |pdf->mem| which |obj_outline_ptr| points to */ - -#define obj_outline_count obj_info /* count of all opened children */ -#define set_obj_outline_count(pdf,A,B) obj_outline_count(pdf,A)=B -#define obj_outline_ptr obj_aux /* pointer to |pdf->mem| */ -#define set_obj_outline_ptr(pdf,A,B) obj_outline_ptr(pdf,A)=B - -#define obj_outline_title(pdf,A) pdf->mem[obj_outline_ptr(pdf,A)] -#define obj_outline_parent(pdf,A) pdf->mem[obj_outline_ptr(pdf,A) + 1] -#define obj_outline_prev(pdf,A) pdf->mem[obj_outline_ptr(pdf,A) + 2] -#define obj_outline_next(pdf,A) pdf->mem[obj_outline_ptr(pdf,A) + 3] -#define obj_outline_first(pdf,A) pdf->mem[obj_outline_ptr(pdf,A) + 4] -#define obj_outline_last(pdf,A) pdf->mem[obj_outline_ptr(pdf,A) + 5] -#define obj_outline_action_objnum(pdf,A) pdf->mem[obj_outline_ptr(pdf,A) + 6] /* object number of action */ -#define obj_outline_attr(pdf,A) pdf->mem[obj_outline_ptr(pdf,A) + 7] - +#define pdfmem_outline_size 8 /* size of memory in |pdf->mem| which |obj_outline_ptr| points to */ + +#define obj_outline_count obj_info /* count of all opened children */ +#define obj_outline_ptr obj_aux /* pointer to |pdf->mem| */ + +#define obj_outline_title(pdf,A) pdf->mem[obj_outline_ptr(pdf,A)] +#define obj_outline_parent(pdf,A) pdf->mem[obj_outline_ptr(pdf,A) + 1] +#define obj_outline_prev(pdf,A) pdf->mem[obj_outline_ptr(pdf,A) + 2] +#define obj_outline_next(pdf,A) pdf->mem[obj_outline_ptr(pdf,A) + 3] +#define obj_outline_first(pdf,A) pdf->mem[obj_outline_ptr(pdf,A) + 4] +#define obj_outline_last(pdf,A) pdf->mem[obj_outline_ptr(pdf,A) + 5] +#define obj_outline_action_objnum(pdf,A) pdf->mem[obj_outline_ptr(pdf,A) + 6] /* object number of action */ +#define obj_outline_attr(pdf,A) pdf->mem[obj_outline_ptr(pdf,A) + 7] + +#define set_obj_outline_count(pdf,A,B) obj_outline_count(pdf,A)=B +#define set_obj_outline_ptr(pdf,A,B) obj_outline_ptr(pdf,A)=B #define set_obj_outline_action_objnum(pdf,A,B) obj_outline_action_objnum(pdf,A)=B -#define set_obj_outline_title(pdf,A,B) obj_outline_title(pdf,A)=B -#define set_obj_outline_prev(pdf,A,B) obj_outline_prev(pdf,A)=B -#define set_obj_outline_next(pdf,A,B) obj_outline_next(pdf,A)=B -#define set_obj_outline_first(pdf,A,B) obj_outline_first(pdf,A)=B -#define set_obj_outline_last(pdf,A,B) obj_outline_last(pdf,A)=B -#define set_obj_outline_parent(pdf,A,B) obj_outline_parent(pdf,A)=B -#define set_obj_outline_attr(pdf,A,B) obj_outline_attr(pdf,A)=B +#define set_obj_outline_title(pdf,A,B) obj_outline_title(pdf,A)=B +#define set_obj_outline_prev(pdf,A,B) obj_outline_prev(pdf,A)=B +#define set_obj_outline_next(pdf,A,B) obj_outline_next(pdf,A)=B +#define set_obj_outline_first(pdf,A,B) obj_outline_first(pdf,A)=B +#define set_obj_outline_last(pdf,A,B) obj_outline_last(pdf,A)=B +#define set_obj_outline_parent(pdf,A,B) obj_outline_parent(pdf,A)=B +#define set_obj_outline_attr(pdf,A,B) obj_outline_attr(pdf,A)=B @ @c static int open_subentries(PDF pdf, halfword p) { - int k, c; - int l, r; - k = 0; + int c, l, r; + int k = 0; if (obj_outline_first(pdf, p) != 0) { l = obj_outline_first(pdf, p); do { @@ -101,7 +99,7 @@ void scan_pdfoutline(PDF pdf) int j = 0; halfword p = null; if (scan_keyword("attr")) { - scan_pdf_ext_toks(); + scan_toks(false, true); r = def_ref; } else { r = 0; @@ -118,7 +116,7 @@ void scan_pdfoutline(PDF pdf) } else { i = 0; } - scan_pdf_ext_toks(); + scan_toks(false, true); q = def_ref; if (j == 0) { j = pdf_create_obj(pdf, obj_type_others, 0); @@ -180,8 +178,8 @@ void scan_pdfoutline(PDF pdf) } } -@ In the end we must flush PDF objects that cannot be written out -immediately after shipping out pages. +@ In the end we must flush PDF objects that cannot be written out immediately +after shipping out pages. @c int print_outlines(PDF pdf) diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdfpage.h b/Build/source/texk/web2c/luatexdir/pdf/pdfpage.h index 6d9fcc0e0b1..175fbcc6c7e 100644 --- a/Build/source/texk/web2c/luatexdir/pdf/pdfpage.h +++ b/Build/source/texk/web2c/luatexdir/pdf/pdfpage.h @@ -15,8 +15,8 @@ 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/>. */ - + with LuaTeX; if not, see <http://www.gnu.org/licenses/>. +*/ #ifndef PDFPAGE_H # define PDFPAGE_H @@ -33,11 +33,7 @@ # undef hz # endif -/**********************************************************************/ - -void synch_pos_with_cur(posstructure * pos, posstructure * refpos, - scaledpos cur); - +void synch_pos_with_cur(posstructure * pos, posstructure * refpos, scaledpos cur); boolean calc_pdfpos(pdfstructure * p, scaledpos pos); void pdf_end_string_nl(PDF pdf); void pdf_goto_pagemode(PDF pdf); diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdfpage.w b/Build/source/texk/web2c/luatexdir/pdf/pdfpage.w index 3fc698a9ec7..73c83c64234 100644 --- a/Build/source/texk/web2c/luatexdir/pdf/pdfpage.w +++ b/Build/source/texk/web2c/luatexdir/pdf/pdfpage.w @@ -19,7 +19,6 @@ @ @c - #include "ptexlib.h" #include <stdlib.h> @@ -27,16 +26,16 @@ #include <assert.h> #include <math.h> -@ eternal constants +@ eternal constant: number of sp per 1bp + @c -#define one_bp ((double) 65536 * (double) 72.27 / 72) /* number of sp per 1bp */ +#define one_bp ((double) 65536 * (double) 72.27 / 72) @ @c void init_pdf_pagecalculations(PDF pdf) { pdfstructure *p; int decimal_digits = pdf->decimal_digits; - assert(pdf != NULL); if (pdf->pstruct == NULL) pdf->pstruct = xmalloc(sizeof(pdfstructure)); p = pdf->pstruct; @@ -52,10 +51,10 @@ void init_pdf_pagecalculations(PDF pdf) setpdffloat(p->cm[4], 0, decimal_digits); /* horizontal movement on page */ setpdffloat(p->cm[5], 0, decimal_digits); /* vertical movement on page */ /* for placement inside BT...ET */ - setpdffloat(p->tm0_cur, 0, 6); /* mantissa holds HZ expand * ExtendFont */ + setpdffloat(p->tm0_cur, 0, 6); /* mantissa holds HZ expand * ExtendFont */ setpdffloat(p->tm[0], ten_pow[6], 6); /* mantissa holds HZ expand * ExtendFont */ setpdffloat(p->tm[1], 0, 0); - setpdffloat(p->tm[2], 0, 3); /* mantissa holds SlantFont, 0 = default */ + setpdffloat(p->tm[2], 0, 3); /* mantissa holds SlantFont, 0 = default */ setpdffloat(p->tm[3], ten_pow[6], 6); setpdffloat(p->tm[4], 0, decimal_digits); /* mantissa holds delta from |pdf_bt_pos.h| */ setpdffloat(p->tm[5], 0, decimal_digits); /* mantissa holds delta from |pdf_bt_pos.v| */ @@ -71,28 +70,31 @@ void init_pdf_pagecalculations(PDF pdf) } @ @c -void synch_pos_with_cur(posstructure * pos, posstructure * refpos, - scaledpos cur) +void synch_pos_with_cur(posstructure * pos, posstructure * refpos, scaledpos cur) { switch (pos->dir) { - case dir_TLT: - pos->pos.h = refpos->pos.h + cur.h; - pos->pos.v = refpos->pos.v - cur.v; - break; - case dir_TRT: - pos->pos.h = refpos->pos.h - cur.h; - pos->pos.v = refpos->pos.v - cur.v; - break; - case dir_LTL: - pos->pos.h = refpos->pos.h + cur.v; - pos->pos.v = refpos->pos.v - cur.h; - break; - case dir_RTT: - pos->pos.h = refpos->pos.h - cur.v; - pos->pos.v = refpos->pos.v - cur.h; - break; - default: - assert(0); + case dir_TLT: + pos->pos.h = refpos->pos.h + cur.h; + pos->pos.v = refpos->pos.v - cur.v; + break; + case dir_TRT: + pos->pos.h = refpos->pos.h - cur.h; + pos->pos.v = refpos->pos.v - cur.v; + break; + case dir_LTL: + pos->pos.h = refpos->pos.h + cur.v; + pos->pos.v = refpos->pos.v - cur.h; + break; + case dir_RTT: + pos->pos.h = refpos->pos.h - cur.v; + pos->pos.v = refpos->pos.v - cur.h; + break; + default: + formatted_warning("pdf backend","forcing bad dir %i to TLT in synch_pos_with_cur",pos->dir); + pos->dir = dir_TLT; + pos->pos.h = refpos->pos.h + cur.h; + pos->pos.v = refpos->pos.v - cur.v; + break; } } @@ -102,55 +104,48 @@ boolean calc_pdfpos(pdfstructure * p, scaledpos pos) scaledpos new; boolean move_pdfpos = false; switch (p->mode) { - case PMODE_PAGE: - new.h = i32round(pos.h * p->k1); - new.v = i32round(pos.v * p->k1); - p->cm[4].m = new.h - p->pdf.h.m; /* cm is concatenated */ - p->cm[5].m = new.v - p->pdf.v.m; - if (new.h != p->pdf.h.m || new.v != p->pdf.v.m) - move_pdfpos = true; - break; - case PMODE_TEXT: - new.h = i32round(pos.h * p->k1); - new.v = i32round(pos.v * p->k1); - p->tm[4].m = new.h - p->pdf_bt_pos.h.m; /* Tm replaces */ - p->tm[5].m = new.v - p->pdf_bt_pos.v.m; - if (new.h != p->pdf.h.m || new.v != p->pdf.v.m) - move_pdfpos = true; - break; - case PMODE_CHAR: - case PMODE_CHARARRAY: - switch (p->wmode) { - case WMODE_H: - new.h = - i32round((pos.h * p->k1 - (double) p->pdf_tj_pos.h.m) * p->k2); + case PMODE_PAGE: + new.h = i32round(pos.h * p->k1); new.v = i32round(pos.v * p->k1); - p->tj_delta.m = -i64round((double) - ((new.h - p->cw.m) / ten_pow[p->cw.e - - p->tj_delta. - e])); - p->tm[5].m = new.v - p->pdf_bt_pos.v.m; /* p->tm[4] is meaningless */ - if (p->tj_delta.m != 0 || new.v != p->pdf.v.m) + p->cm[4].m = new.h - p->pdf.h.m; /* cm is concatenated */ + p->cm[5].m = new.v - p->pdf.v.m; + if (new.h != p->pdf.h.m || new.v != p->pdf.v.m) move_pdfpos = true; break; - case WMODE_V: + case PMODE_TEXT: new.h = i32round(pos.h * p->k1); - new.v = - i32round(((double) p->pdf_tj_pos.v.m - pos.v * p->k1) * p->k2); - p->tm[4].m = new.h - p->pdf_bt_pos.h.m; /* p->tm[5] is meaningless */ - p->tj_delta.m = -i64round((double) - ((new.v - p->cw.m) / ten_pow[p->cw.e - - p->tj_delta. - e])); - if (p->tj_delta.m != 0 || new.h != p->pdf.h.m) + new.v = i32round(pos.v * p->k1); + p->tm[4].m = new.h - p->pdf_bt_pos.h.m; /* Tm replaces */ + p->tm[5].m = new.v - p->pdf_bt_pos.v.m; + if (new.h != p->pdf.h.m || new.v != p->pdf.v.m) move_pdfpos = true; break; + case PMODE_CHAR: + case PMODE_CHARARRAY: + switch (p->wmode) { + case WMODE_H: + new.h = i32round((pos.h * p->k1 - (double) p->pdf_tj_pos.h.m) * p->k2); + new.v = i32round(pos.v * p->k1); + p->tj_delta.m = -i64round((double) ((new.h - p->cw.m) / ten_pow[p->cw.e - p->tj_delta.e])); + p->tm[5].m = new.v - p->pdf_bt_pos.v.m; /* p->tm[4] is meaningless */ + if (p->tj_delta.m != 0 || new.v != p->pdf.v.m) + move_pdfpos = true; + break; + case WMODE_V: + new.h = i32round(pos.h * p->k1); + new.v = i32round(((double) p->pdf_tj_pos.v.m - pos.v * p->k1) * p->k2); + p->tm[4].m = new.h - p->pdf_bt_pos.h.m; /* p->tm[5] is meaningless */ + p->tj_delta.m = -i64round((double) ((new.v - p->cw.m) / ten_pow[p->cw.e - p->tj_delta.e])); + if (p->tj_delta.m != 0 || new.h != p->pdf.h.m) + move_pdfpos = true; + break; + default: + normal_error("pdf backend","unknown mode in char array in calc_pos"); + break; + } + break; default: - assert(0); - } - break; - default: - assert(0); + normal_error("pdf backend","unknown mode in calc_pos"); } return move_pdfpos; } @@ -178,7 +173,8 @@ void pdf_set_pos(PDF pdf, scaledpos pos) { boolean move; pdfstructure *p = pdf->pstruct; - assert(is_pagemode(p)); + if (!is_pagemode(p)) + normal_error("pdf backend","page mode expected in set_pos"); move = calc_pdfpos(p, pos); if (move) { pdf_print_cm(pdf, p->cm); @@ -192,17 +188,20 @@ void pdf_set_pos_temp(PDF pdf, scaledpos pos) { boolean move; pdfstructure *p = pdf->pstruct; - assert(is_pagemode(p)); + if (!is_pagemode(p)) + normal_error("pdf backend","page mode expected in set_pos_temp"); move = calc_pdfpos(p, pos); - if (move) + if (move) { pdf_print_cm(pdf, p->cm); + } } @ @c static void begin_text(PDF pdf) { pdfstructure *p = pdf->pstruct; - assert(is_pagemode(p)); + if (!is_pagemode(p)) + normal_error("pdf backend","page mode expected in begin_text"); p->pdf_bt_pos = p->pdf; pdf_puts(pdf, "BT\n"); p->mode = PMODE_TEXT; @@ -212,7 +211,8 @@ static void begin_text(PDF pdf) static void end_text(PDF pdf) { pdfstructure *p = pdf->pstruct; - assert(is_textmode(p)); + if (!is_textmode(p)) + normal_error("pdf backend","text mode expected in end_text"); pdf_puts(pdf, "ET\n"); p->pdf = p->pdf_bt_pos; p->mode = PMODE_PAGE; @@ -231,7 +231,6 @@ void pdf_end_string_nl(PDF pdf) void pdf_goto_pagemode(PDF pdf) { pdfstructure *p = pdf->pstruct; - assert(p != NULL); if (!is_pagemode(p)) { if (is_charmode(p)) end_charmode(pdf); @@ -239,8 +238,9 @@ void pdf_goto_pagemode(PDF pdf) end_chararray(pdf); if (is_textmode(p)) end_text(pdf); + if (!is_pagemode(p)) + normal_error("pdf backend","page mode expected in goto_page_mode"); } - assert(is_pagemode(p)); } void pdf_goto_textmode(PDF pdf) @@ -249,16 +249,16 @@ void pdf_goto_textmode(PDF pdf) const scaledpos origin = { 0, 0 }; - if (!is_textmode(p)) { - if (is_pagemode(p)) { - pdf_set_pos(pdf, origin); /* reset to page origin */ - begin_text(pdf); - } else { - if (is_charmode(p)) - end_charmode(pdf); - if (is_chararraymode(p)) - end_chararray(pdf); - } + if (is_pagemode(p)) { + /* reset to page origin */ + pdf_set_pos(pdf, origin); + begin_text(pdf); + } else if (!is_textmode(p)) { + if (is_charmode(p)) + end_charmode(pdf); + if (is_chararraymode(p)) + end_chararray(pdf); + if (!is_textmode(p)) + normal_error("pdf backend","text mode expected in goto_text_mode"); } - assert(is_textmode(p)); } diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdfpagetree.h b/Build/source/texk/web2c/luatexdir/pdf/pdfpagetree.h index b00fc0476a1..9fdb0ac83d3 100644 --- a/Build/source/texk/web2c/luatexdir/pdf/pdfpagetree.h +++ b/Build/source/texk/web2c/luatexdir/pdf/pdfpagetree.h @@ -15,8 +15,8 @@ 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/>. */ - + with LuaTeX; if not, see <http://www.gnu.org/licenses/>. +*/ #ifndef PAGETREE_H # define PAGETREE_H @@ -25,4 +25,4 @@ int output_pages_tree(PDF); int pdf_do_page_divert(PDF, int, int); void pdf_do_page_undivert(int, int); -#endif /* PAGETREE_H */ +#endif diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdfpagetree.w b/Build/source/texk/web2c/luatexdir/pdf/pdfpagetree.w index 4470e53cbfb..76d008c4359 100644 --- a/Build/source/texk/web2c/luatexdir/pdf/pdfpagetree.w +++ b/Build/source/texk/web2c/luatexdir/pdf/pdfpagetree.w @@ -19,25 +19,20 @@ @ @c - #include "ptexlib.h" @* Page diversions. @ @c -#ifdef DEBUG -# define PAGES_TREE_KIDSMAX 3 -#else -# define PAGES_TREE_KIDSMAX 10 -#endif +# define PAGES_TREE_KIDSMAX 10 static struct avl_table *divert_list_tree = NULL; typedef struct pages_entry_ { - int objnum; /* object number of this /Pages object */ - int number_of_pages; /* total number of all pages below */ - int number_of_kids; /* number of direct kid objects */ - int kids[PAGES_TREE_KIDSMAX]; /* array of kid object numbers */ + int objnum; /* object number of this /Pages object */ + int number_of_pages; /* total number of all pages below */ + int number_of_kids; /* number of direct kid objects */ + int kids[PAGES_TREE_KIDSMAX]; /* array of kid object numbers */ struct pages_entry_ *next; } pages_entry; @@ -50,11 +45,9 @@ typedef struct divert_list_entry_ { static int comp_divert_list_entry(const void *pa, const void *pb, void *p) { (void) p; - if (((const divert_list_entry *) pa)->divnum > - ((const divert_list_entry *) pb)->divnum) + if (((const divert_list_entry *) pa)->divnum > ((const divert_list_entry *) pb)->divnum) return 1; - if (((const divert_list_entry *) pa)->divnum < - ((const divert_list_entry *) pb)->divnum) + if (((const divert_list_entry *) pa)->divnum < ((const divert_list_entry *) pb)->divnum) return -1; return 0; } @@ -62,9 +55,8 @@ static int comp_divert_list_entry(const void *pa, const void *pb, void *p) @ @c static pages_entry *new_pages_entry(PDF pdf) { - pages_entry *p; int i; - p = xtalloc(1, pages_entry); + pages_entry *p = xtalloc(1, pages_entry); p->number_of_pages = p->number_of_kids = 0; for (i = 0; i < PAGES_TREE_KIDSMAX; i++) p->kids[i] = 0; @@ -86,9 +78,7 @@ static divert_list_entry *new_divert_list_entry(void) static void ensure_list_tree(void) { if (divert_list_tree == NULL) { - divert_list_tree = - avl_create(comp_divert_list_entry, NULL, &avl_xallocator); - assert(divert_list_tree != NULL); + divert_list_tree = avl_create(comp_divert_list_entry, NULL, &avl_xallocator); } } @@ -102,8 +92,11 @@ static divert_list_entry *get_divert_list(int divnum) if (d == NULL) { d = new_divert_list_entry(); d->divnum = divnum; + /* the next bit of code can actually be removed */ aa = avl_probe(divert_list_tree, d); - assert(aa != NULL); + if (aa==NULL) { + normal_error("pdf backend","page list lookup error"); + } } return d; } @@ -114,11 +107,6 @@ int pdf_do_page_divert(PDF pdf, int objnum, int divnum) { divert_list_entry *d; pages_entry *p; -#ifdef DEBUG - pages_entry *q; - struct avl_traverser t; - int i; -#endif /* initialize the tree */ ensure_list_tree(); /* make sure we have a list for this diversion */ @@ -135,34 +123,21 @@ int pdf_do_page_divert(PDF pdf, int objnum, int divnum) p = d->last; p->kids[p->number_of_kids++] = objnum; p->number_of_pages++; -#ifdef DEBUG - printf("\n"); - avl_t_init(&t, divert_list_tree); - for (d = avl_t_first(&t, divert_list_tree); d != NULL; d = avl_t_next(&t)) { - printf("===== D-LIST %d: ", d->divnum); - for (q = d->first; q != NULL; q = q->next) { - printf("P=%d NK=%d (", q->objnum, q->number_of_kids); - for (i = 0; i < q->number_of_kids; i++) - printf("%d ", q->kids[i]); - printf(") "); - } - printf("\n"); - } - printf("\n"); -#endif return p->objnum; } @ @c static void movelist(divert_list_entry * d, divert_list_entry * dto) { - if (d != NULL && d->first != NULL && d->divnum != dto->divnum) { /* no undivert of empty list or into self */ + if (d != NULL && d->first != NULL && d->divnum != dto->divnum) { + /* no undivert of empty list or into self */ if (dto->first == NULL) dto->first = d->first; else dto->last->next = d->first; dto->last = d->last; - d->first = d->last = NULL; /* one could as well remove this |divert_list_entry| */ + /* one could as well remove this |divert_list_entry| */ + d->first = d->last = NULL; } } @@ -172,15 +147,12 @@ void pdf_do_page_undivert(int divnum, int curdivnum) { divert_list_entry *d, *dto, tmp; struct avl_traverser t; -#ifdef DEBUG - pages_entry *p; - int i; -#endif /* initialize the tree */ ensure_list_tree(); /* find the diversion |curdivnum| list where diversion |divnum| should go */ dto = get_divert_list(curdivnum); - if (divnum == 0) { /* 0 = special case: undivert {\it all\/} lists */ + if (divnum == 0) { + /* 0 = special case: undivert {\it all\/} lists */ avl_t_init(&t, divert_list_tree); for (d = avl_t_first(&t, divert_list_tree); d != NULL; d = avl_t_next(&t)) @@ -190,21 +162,6 @@ void pdf_do_page_undivert(int divnum, int curdivnum) d = (divert_list_entry *) avl_find(divert_list_tree, &tmp); movelist(d, dto); } -#ifdef DEBUG - printf("\n"); - avl_t_init(&t, divert_list_tree); - for (d = avl_t_first(&t, divert_list_tree); d != NULL; d = avl_t_next(&t)) { - printf("===== U-LIST %d: ", d->divnum); - for (p = d->first; p != NULL; p = p->next) { - printf("P=%d NK=%d (", p->objnum, p->number_of_kids); - for (i = 0; i < p->number_of_kids; i++) - printf("%d ", p->kids[i]); - printf(") "); - } - printf("\n"); - } - printf("\n"); -#endif } @ write a /Pages object @@ -214,11 +171,11 @@ static void write_pages(PDF pdf, pages_entry * p, int parent) { int i; int pages_attributes ; - assert(p != NULL); pdf_begin_obj(pdf, p->objnum, OBJSTM_ALWAYS); pdf_begin_dict(pdf); pdf_dict_add_name(pdf, "Type", "Pages"); - if (parent == 0) { /* it's root */ + if (parent == 0) { + /* it's root */ pages_attributes = pdf_pages_attr; /* lookup once */ if (pages_attributes != null) { pdf_print_toks(pdf, pages_attributes); @@ -240,16 +197,17 @@ static void write_pages(PDF pdf, pages_entry * p, int parent) @ loop over all /Pages objects, output them, create their parents, recursing bottom up, return the /Pages root object number + @c static int output_pages_list(PDF pdf, pages_entry * pe) { pages_entry *p, *q, *r; - assert(pe != NULL); - if (pe->next == NULL) { /* everything fits into one |pages_entry| */ - write_pages(pdf, pe, 0); /* --> /Pages root found */ + if (pe->next == NULL) { + /* everything fits into one |pages_entry| */ + write_pages(pdf, pe, 0); /* /Pages root found */ return pe->objnum; } - q = r = new_pages_entry(pdf); /* one level higher needed */ + q = r = new_pages_entry(pdf); /* one level higher needed */ for (p = pe; p != NULL; p = p->next) { if (q->number_of_kids == PAGES_TREE_KIDSMAX) { q->next = new_pages_entry(pdf); @@ -259,7 +217,7 @@ static int output_pages_list(PDF pdf, pages_entry * pe) q->number_of_pages += p->number_of_pages; write_pages(pdf, p, q->objnum); } - return output_pages_list(pdf, r); /* recurse through next higher level */ + return output_pages_list(pdf, r); /* recurse through next higher level */ } @ @c diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdfrule.h b/Build/source/texk/web2c/luatexdir/pdf/pdfrule.h index 3770b2cbbe5..c0d68fd44b0 100644 --- a/Build/source/texk/web2c/luatexdir/pdf/pdfrule.h +++ b/Build/source/texk/web2c/luatexdir/pdf/pdfrule.h @@ -15,12 +15,13 @@ 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/>. */ + with LuaTeX; if not, see <http://www.gnu.org/licenses/>. +*/ #ifndef PDFRULE_H # define PDFRULE_H -void pdf_place_rule(PDF pdf, halfword p, scaledpos size); +void pdf_place_rule(PDF pdf, halfword p, scaledpos size, int callback_id); #endif diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdfrule.w b/Build/source/texk/web2c/luatexdir/pdf/pdfrule.w index a9d670c1154..e4897dfb04b 100644 --- a/Build/source/texk/web2c/luatexdir/pdf/pdfrule.w +++ b/Build/source/texk/web2c/luatexdir/pdf/pdfrule.w @@ -18,13 +18,14 @@ % with LuaTeX; if not, see <http://www.gnu.org/licenses/>. @ @c - - #include "ptexlib.h" #include "pdf/pdfpage.h" @ @c -void pdf_place_rule(PDF pdf, halfword q, scaledpos size) + +/* maybe we should have an extra callback on normal rules or on any rule in 2.0+ */ + +void pdf_place_rule(PDF pdf, halfword q, scaledpos size, int callback_id) { pdfpos dim; pdfstructure *p = pdf->pstruct; @@ -36,6 +37,14 @@ void pdf_place_rule(PDF pdf, halfword q, scaledpos size) pdf_place_image(pdf,q); } else if (subtype(q) == empty_rule) { /* place nothing, only take space */ + } else if (subtype(q) == user_rule) { + if (callback_id != 0) { + pdf_goto_pagemode(pdf); + pdf_puts(pdf, "q\n"); + pdf_set_pos_temp(pdf, pos); + run_callback(callback_id, "Ndd->",q,size.h,size.v); + pdf_puts(pdf, "\nQ\n"); + } } else { /* normal_rule or >= 100 being a leader rule */ pdf_goto_pagemode(pdf); diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdfsaverestore.h b/Build/source/texk/web2c/luatexdir/pdf/pdfsaverestore.h index e45902328c8..3e1e1ef061e 100644 --- a/Build/source/texk/web2c/luatexdir/pdf/pdfsaverestore.h +++ b/Build/source/texk/web2c/luatexdir/pdf/pdfsaverestore.h @@ -15,20 +15,22 @@ 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/>. */ - + with LuaTeX; if not, see <http://www.gnu.org/licenses/>. +*/ #ifndef PDFSAVERESTORE_H # define PDFSAVERESTORE_H /* stack for positions of \pdfsave */ + typedef struct { scaledpos pos; int matrix_stack; } pos_entry; -extern pos_entry *pos_stack; /* the stack */ -extern int pos_stack_size; /* initially empty */ -extern int pos_stack_used; /* used entries */ + +extern pos_entry *pos_stack; /* the stack */ +extern int pos_stack_size; /* initially empty */ +extern int pos_stack_used; /* used entries */ extern void pdf_out_save(PDF pdf, halfword p); extern void pdf_out_restore(PDF pdf, halfword p); diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdfsaverestore.w b/Build/source/texk/web2c/luatexdir/pdf/pdfsaverestore.w index 4c88dec6182..0d91de54496 100644 --- a/Build/source/texk/web2c/luatexdir/pdf/pdfsaverestore.w +++ b/Build/source/texk/web2c/luatexdir/pdf/pdfsaverestore.w @@ -19,24 +19,21 @@ @ @c - #include "ptexlib.h" @ @c -pos_entry *pos_stack = 0; /* the stack */ -int pos_stack_size = 0; /* initially empty */ -int pos_stack_used = 0; /* used entries */ +pos_entry *pos_stack = 0; /* the stack */ +int pos_stack_size = 0; /* initially empty */ +int pos_stack_used = 0; /* used entries */ @ @c static void checkpdfsave(scaledpos pos) { pos_entry *new_stack; - if (pos_stack_used >= pos_stack_size) { pos_stack_size += STACK_INCREMENT; new_stack = xtalloc((unsigned) pos_stack_size, pos_entry); - memcpy((void *) new_stack, (void *) pos_stack, - (unsigned) pos_stack_used * sizeof(pos_entry)); + memcpy((void *) new_stack, (void *) pos_stack, (unsigned) pos_stack_used * sizeof(pos_entry)); xfree(pos_stack); pos_stack = new_stack; } @@ -53,21 +50,20 @@ static void checkpdfrestore(scaledpos pos) { scaledpos diff; if (pos_stack_used == 0) { - luatex_warn("%s", "'restore' is missing a 'save'"); + normal_warning("pdf backend", "'restore' is missing a 'save'"); return; } pos_stack_used--; diff.h = pos.h - pos_stack[pos_stack_used].pos.h; diff.v = pos.v - pos_stack[pos_stack_used].pos.v; if (diff.h != 0 || diff.v != 0) { - luatex_warn("misplaced 'restore' by (%dsp, %dsp)", (int) diff.h, (int) diff.v); + formatted_warning("pdf backend","misplaced 'restore' by (%dsp, %dsp)", (int) diff.h, (int) diff.v); } if (global_shipping_mode == SHIPPING_PAGE) { matrix_stack_used = pos_stack[pos_stack_used].matrix_stack; } } - @ @c void pdf_out_save(PDF pdf, halfword p) { diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdfsetmatrix.h b/Build/source/texk/web2c/luatexdir/pdf/pdfsetmatrix.h index c65e0ea8b8a..59fd1f69cdc 100644 --- a/Build/source/texk/web2c/luatexdir/pdf/pdfsetmatrix.h +++ b/Build/source/texk/web2c/luatexdir/pdf/pdfsetmatrix.h @@ -15,8 +15,8 @@ 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/>. */ - + with LuaTeX; if not, see <http://www.gnu.org/licenses/>. +*/ #ifndef PDFSETMATRIX_H # define PDFSETMATRIX_H @@ -36,7 +36,6 @@ extern matrix_entry *matrix_stack; extern int matrix_stack_size; extern int matrix_stack_used; - scaled getllx(void); scaled getlly(void); scaled geturx(void); diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdfsetmatrix.w b/Build/source/texk/web2c/luatexdir/pdf/pdfsetmatrix.w index ba9317e776d..b107033b984 100644 --- a/Build/source/texk/web2c/luatexdir/pdf/pdfsetmatrix.w +++ b/Build/source/texk/web2c/luatexdir/pdf/pdfsetmatrix.w @@ -19,7 +19,6 @@ @ @c - #include "ptexlib.h" @ stack for \.{\\pdfextension setmatrix} @@ -38,34 +37,28 @@ boolean matrixused(void) static void matrix_stack_room(void) { matrix_entry *new_stack; - if (matrix_stack_used >= matrix_stack_size) { matrix_stack_size += STACK_INCREMENT; new_stack = xtalloc((unsigned) matrix_stack_size, matrix_entry); - memcpy((void *) new_stack, (void *) matrix_stack, - (unsigned) matrix_stack_used * sizeof(matrix_entry)); + memcpy((void *) new_stack, (void *) matrix_stack, (unsigned) matrix_stack_used * sizeof(matrix_entry)); xfree(matrix_stack); matrix_stack = new_stack; } } -@ \.{\\pdfextension setmatrix{a b c d}} +@ \.{\\pdfextension setmatrix{a b c d}} - |e| := pos.h +|e| := pos.h - |f| := pos.v +|f| := pos.v - |M_top|: current active matrix at the top of - the matrix stack +|M_top|: current active matrix at the top of the matrix stack - The origin of \.{\\pdfextension setmatrix} is the current point. - The annotation coordinate system is the original - page coordinate system. When pdfTeX calculates - annotation rectangles it does not take into - account this transformations, it uses the original - coordinate system. To get the corrected values, - first we go back to the origin, perform the - transformation and go back: +The origin of \.{\\pdfextension setmatrix} is the current point. The annotation +coordinate system is the original page coordinate system. When pdfTeX calculates +annotation rectangles it does not take into account this transformations, it uses +the original coordinate system. To get the corrected values, first we go back to +the origin, perform the transformation and go back: {\obeylines\obeyspaces\tt ( 1 0 0 ) ( a b 0 ) ( 1 0 0 ) @@ -84,15 +77,14 @@ static void matrix_stack_room(void) @c static void pdfsetmatrix(const char *in, scaledpos pos) { - /* Argument of \.{\\pdfextension setmatrix} starts with |str_pool[in]| and ends - before |str_pool[pool_ptr]|. */ - + /* + Argument of \.{\\pdfextension setmatrix} starts with |str_pool[in]| and ends + before |str_pool[pool_ptr]|. + */ matrix_entry x, *y, *z; - if (global_shipping_mode == SHIPPING_PAGE) { - if (sscanf((const char *) in, " %lf %lf %lf %lf ", - &x.a, &x.b, &x.c, &x.d) != 4) { - luatex_warn("unrecognized format of setmatrix: {%s}", in); + if (sscanf((const char *) in, " %lf %lf %lf %lf ", &x.a, &x.b, &x.c, &x.d) != 4) { + formatted_warning("pdf backend","unrecognized format of setmatrix: %s", in); return; } /* calculate this transformation matrix */ @@ -130,8 +122,9 @@ static void pdfsetmatrix(const char *in, scaledpos pos) If \.{\\pdfextension setmatrix} wasn't used, then return the value unchanged. +@ Return values for matrix tranform functions: + @c -/* Return values for matrix tranform functions */ static scaled ret_llx; static scaled ret_lly; static scaled ret_urx; @@ -181,7 +174,6 @@ static void do_matrixtransform(scaled x, scaled y, scaled * retx, scaled * rety) void matrixtransformrect(scaled llx, scaled lly, scaled urx, scaled ury) { scaled x1, x2, x3, x4, y1, y2, y3, y4; - if (global_shipping_mode == SHIPPING_PAGE && matrix_stack_used > 0) { last_llx = llx; last_lly = lly; diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdfshipout.h b/Build/source/texk/web2c/luatexdir/pdf/pdfshipout.h index b341f818099..8fb073da4c2 100644 --- a/Build/source/texk/web2c/luatexdir/pdf/pdfshipout.h +++ b/Build/source/texk/web2c/luatexdir/pdf/pdfshipout.h @@ -15,14 +15,15 @@ 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/>. */ + with LuaTeX; if not, see <http://www.gnu.org/licenses/>. +*/ #ifndef PDFSHIPOUT_H # define PDFSHIPOUT_H -extern shipping_mode_e global_shipping_mode; /* set to |shipping_mode| when |ship_out| starts */ -extern scaledpos shipbox_refpos; /* for \gleaders */ +extern shipping_mode_e global_shipping_mode; /* set to |shipping_mode| when |ship_out| starts */ +extern scaledpos shipbox_refpos; /* for \gleaders */ extern void ship_out(PDF pdf, halfword p, shipping_mode_e shipping_mode); diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdfshipout.w b/Build/source/texk/web2c/luatexdir/pdf/pdfshipout.w index b75cb339c13..d60b4a0dc75 100644 --- a/Build/source/texk/web2c/luatexdir/pdf/pdfshipout.w +++ b/Build/source/texk/web2c/luatexdir/pdf/pdfshipout.w @@ -23,48 +23,46 @@ @ @c #define count(A) eqtb[count_base+(A)].cint -#define h_offset dimen_par(h_offset_code) -#define mag int_par(mag_code) + +#define mag int_par(mag_code) +#define h_offset dimen_par(h_offset_code) #define page_bottom_offset dimen_par(page_bottom_offset_code) -#define page_direction int_par(page_direction_code) -#define page_height dimen_par(page_height_code) -#define page_left_offset dimen_par(page_left_offset_code) -#define page_right_offset dimen_par(page_right_offset_code) -#define page_top_offset dimen_par(page_top_offset_code) -#define page_width dimen_par(page_width_code) -#define tracing_output int_par(tracing_output_code) -#define tracing_stats int_par(tracing_stats_code) -#define v_offset dimen_par(v_offset_code) +#define page_height dimen_par(page_height_code) +#define page_left_offset dimen_par(page_left_offset_code) +#define page_right_offset dimen_par(page_right_offset_code) +#define page_top_offset dimen_par(page_top_offset_code) +#define page_width dimen_par(page_width_code) +#define tracing_output int_par(tracing_output_code) +#define tracing_stats int_par(tracing_stats_code) +#define v_offset dimen_par(v_offset_code) scaledpos shipbox_refpos; -@ |ship_out| is used to shipout a box to PDF or DVI mode. -If |shipping_mode| is set to |SHIPPING_FORM| then the output will be a Form object -(only PDF), and if it is set to |SHIPPING_PAGE| it will be a Page object. +@ |ship_out| is used to shipout a box to PDF or DVI mode. If |shipping_mode| is +set to |SHIPPING_FORM| then the output will be a Form object (only PDF), and if +it is set to |SHIPPING_PAGE| it will be a Page object. @c void ship_out(PDF pdf, halfword p, shipping_mode_e shipping_mode) { - /* output the box |p| */ - int j, k; /* indices to first ten count registers */ + int j, k; /* indices to first ten count registers */ int post_callback_id; int pre_callback_id; - posstructure refpoint; /* the origin pos. on the page */ + posstructure refpoint; /* the origin pos. on the page */ + int rule_callback_id = 0; scaledpos cur = { 0, 0 }; refpoint.pos.h = 0; refpoint.pos.v = 0; - ensure_output_state(pdf, ST_HEADER_WRITTEN); - fix_o_mode(); /* this is only for complaining if \.{\\outputmode} has changed */ + fix_o_mode(); /* this is only for complaining if \.{\\outputmode} has changed */ init_backend_functionpointers(output_mode_used); - pdf->f_cur = null_font; - - /* Start sheet {\sl Sync\TeX} information record */ - /* {\sl Sync\TeX}: we assume that |pdf_output| is properly set up */ + /* + Start sheet {\sl Sync\TeX} information record; we assume that |pdf_output| is + properly set up. + */ if (int_par(synctex_code)) synctexsheet(mag); - pre_callback_id = callback_defined(start_page_number_callback); post_callback_id = callback_defined(stop_page_number_callback); if ((tracing_output > 0) && (pre_callback_id == 0)) { @@ -99,20 +97,18 @@ void ship_out(PDF pdf, halfword p, shipping_mode_e shipping_mode) show_box(p); end_diagnostic(true); } - /* Ship box |p| out */ if (shipping_mode == SHIPPING_PAGE && box_dir(p) != page_direction) - normal_warning("backend","pagedir differs from bodydir, the output may be placed wrongly on the page", true, true); - /* Update the values of |max_h| and |max_v|; but if the page is too large, |goto done| */ - /* Sometimes the user will generate a huge page because other error messages - are being ignored. Such pages are not output to the \.{dvi} file, since they - may confuse the printing software. */ - - if ((height(p) > max_dimen) || (depth(p) > max_dimen) - || (height(p) + depth(p) + v_offset > max_dimen) - || (width(p) + h_offset > max_dimen)) { - const char *hlp[] = - { "The page just created is more than 18 feet tall or", + normal_warning("backend","pagedir differs from bodydir, the output may be placed wrongly on the page"); + /* + Update the values of |max_h| and |max_v|; but if the page is too large, + |goto done|. Sometimes the user will generate a huge page because other + error messages are being ignored. Such pages are not output to the + \.{dvi} file, since they may confuse the printing software. + */ + if ((height(p) > max_dimen) || (depth(p) > max_dimen) || (height(p) + depth(p) + v_offset > max_dimen) || (width(p) + h_offset > max_dimen)) { + const char *hlp[] = { + "The page just created is more than 18 feet tall or", "more than 18 feet wide, so I suspect something went wrong.", NULL }; @@ -129,136 +125,139 @@ void ship_out(PDF pdf, halfword p, shipping_mode_e shipping_mode) max_v = height(p) + depth(p) + v_offset; if (width(p) + h_offset > max_h) max_h = width(p) + h_offset; - /* Calculate page dimensions and margins */ if (global_shipping_mode == SHIPPING_PAGE) { if (page_width > 0) pdf->page_size.h = page_width; else { switch (page_direction) { - case dir_TLT: - pdf->page_size.h = width(p) + 2 * page_left_offset; - break; - case dir_TRT: - pdf->page_size.h = width(p) + 2 * page_right_offset; - break; - case dir_LTL: - pdf->page_size.h = height(p) + depth(p) + 2 * page_left_offset; - break; - case dir_RTT: - pdf->page_size.h = height(p) + depth(p) + 2 * page_right_offset; - break; - default: - assert(0); + case dir_TLT: + pdf->page_size.h = width(p) + 2 * page_left_offset; + break; + case dir_TRT: + pdf->page_size.h = width(p) + 2 * page_right_offset; + break; + case dir_LTL: + pdf->page_size.h = height(p) + depth(p) + 2 * page_left_offset; + break; + case dir_RTT: + pdf->page_size.h = height(p) + depth(p) + 2 * page_right_offset; + break; + default: + pdf->page_size.h = width(p) + 2 * page_left_offset; + normal_warning("pdf backend","bad page direction, assuming TLT, case 1"); } } if (page_height > 0) pdf->page_size.v = page_height; else { switch (page_direction) { - case dir_TLT: - case dir_TRT: - pdf->page_size.v = height(p) + depth(p) + 2 * page_top_offset; + case dir_TLT: + case dir_TRT: + pdf->page_size.v = height(p) + depth(p) + 2 * page_top_offset; + break; + case dir_LTL: + case dir_RTT: + pdf->page_size.v = width(p) + 2 * page_top_offset; + break; + default: + pdf->page_size.v = height(p) + depth(p) + 2 * page_top_offset; + normal_warning("pdf backend","bad page direction, assuming TLT, case 2"); + } + } + /* + Think in upright page/paper coordinates (page origin = lower left edge). + First preset |refpoint.pos| to the DVI origin (near upper left page edge). + */ + switch (output_mode_used) { + case OMODE_DVI: + /* hh: how can we end up here? */ + refpoint.pos.h = one_true_inch; + refpoint.pos.v = pdf->page_size.v - one_true_inch; + dvi = refpoint.pos; break; - case dir_LTL: - case dir_RTT: - pdf->page_size.v = width(p) + 2 * page_top_offset; + case OMODE_PDF: + refpoint.pos.h = pdf_h_origin; + refpoint.pos.v = pdf->page_size.v - pdf_v_origin; break; default: - assert(0); - } - } - - /* Think in upright page/paper coordinates (page origin = lower left edge). - First preset |refpoint.pos| to the DVI origin (near upper left page edge). */ - - switch (output_mode_used) { - case OMODE_DVI: - /* hh: how can we end up here? */ - refpoint.pos.h = one_true_inch; - refpoint.pos.v = pdf->page_size.v - one_true_inch; - dvi = refpoint.pos; - break; - case OMODE_PDF: - refpoint.pos.h = pdf_h_origin; - refpoint.pos.v = pdf->page_size.v - pdf_v_origin; - break; - default: - assert(0); + normal_error("pdf backend", "unknown output mode"); } - /* Then shift |refpoint.pos| of the DVI origin depending on the - |page_direction| within the upright (TLT) page coordinate system */ - + /* + Then shift |refpoint.pos| of the DVI origin depending on the + |page_direction| within the upright (TLT) page coordinate system + */ switch (page_direction) { - case dir_TLT: - case dir_LTL: - refpoint.pos.h += h_offset; - refpoint.pos.v -= v_offset; - break; - case dir_TRT: - case dir_RTT: - refpoint.pos.h += - pdf->page_size.h - page_right_offset - one_true_inch; - refpoint.pos.v -= v_offset; - break; - default: - assert(0); + case dir_TLT: + case dir_LTL: + refpoint.pos.h += h_offset; + refpoint.pos.v -= v_offset; + break; + case dir_TRT: + case dir_RTT: + refpoint.pos.h += pdf->page_size.h - page_right_offset - one_true_inch; + refpoint.pos.v -= v_offset; + break; + default: + refpoint.pos.h += h_offset; + refpoint.pos.v -= v_offset; + normal_warning("pdf backend","bad page direction, assuming TLT, case 3"); } - - /* Then switch to page box coordinate system; do |height(p)| movement, - to get the location of the box origin. */ - + /* + Then switch to page box coordinate system; do |height(p)| movement, + to get the location of the box origin. + */ pdf->posstruct->dir = page_direction; cur.h = 0; cur.v = height(p); synch_pos_with_cur(pdf->posstruct, &refpoint, cur); - } else { /* shipping a /Form */ - assert(output_mode_used == OMODE_PDF); + } else { + /* shipping a /Form */ pdf->posstruct->dir = box_dir(p); switch (pdf->posstruct->dir) { - case dir_TLT: - case dir_TRT: - pdf->page_size.h = width(p); - pdf->page_size.v = height(p) + depth(p); - break; - case dir_LTL: - case dir_RTT: - pdf->page_size.h = height(p) + depth(p); - pdf->page_size.v = width(p); - break; - default: - assert(0); - } + case dir_TLT: + case dir_TRT: + pdf->page_size.h = width(p); + pdf->page_size.v = height(p) + depth(p); + break; + case dir_LTL: + case dir_RTT: + pdf->page_size.h = height(p) + depth(p); + pdf->page_size.v = width(p); + break; + default: + pdf->page_size.h = width(p); + pdf->page_size.v = height(p) + depth(p); + normal_warning("pdf backend","bad page direction, assuming TLT, case 4"); + } switch (pdf->posstruct->dir) { - case dir_TLT: - pdf->posstruct->pos.h = 0; - pdf->posstruct->pos.v = depth(p); - break; - case dir_TRT: - pdf->posstruct->pos.h = width(p); - pdf->posstruct->pos.v = depth(p); - break; - case dir_LTL: - pdf->posstruct->pos.h = height(p); - pdf->posstruct->pos.v = width(p); - break; - case dir_RTT: - pdf->posstruct->pos.h = depth(p); - pdf->posstruct->pos.v = width(p); - break; - default: - assert(0); + case dir_TLT: + pdf->posstruct->pos.h = 0; + pdf->posstruct->pos.v = depth(p); + break; + case dir_TRT: + pdf->posstruct->pos.h = width(p); + pdf->posstruct->pos.v = depth(p); + break; + case dir_LTL: + pdf->posstruct->pos.h = height(p); + pdf->posstruct->pos.v = width(p); + break; + case dir_RTT: + pdf->posstruct->pos.h = depth(p); + pdf->posstruct->pos.v = width(p); + break; + default: + pdf->posstruct->pos.h = 0; + pdf->posstruct->pos.v = depth(p); + normal_warning("pdf backend","bad page direction, assuming TLT, case 5"); } } - /* Now we are at the point on the page where the origin of the page box should go. */ - - shipbox_refpos = pdf->posstruct->pos; /* for \.{\\gleaders} */ - + shipbox_refpos = pdf->posstruct->pos; /* for \.{\\gleaders} */ switch (output_mode_used) { case OMODE_DVI: - assert(shipping_mode == SHIPPING_PAGE); dvi_begin_page(pdf); break; case OMODE_PDF: @@ -267,24 +266,21 @@ void ship_out(PDF pdf, halfword p, shipping_mode_e shipping_mode) default: normal_error("pdf backend", "unknown output mode"); } - + rule_callback_id = callback_defined(process_rule_callback); switch (type(p)) { case vlist_node: - vlist_out(pdf, p); + vlist_out(pdf, p, rule_callback_id); break; case hlist_node: - hlist_out(pdf, p); + hlist_out(pdf, p, rule_callback_id); break; default: normal_error("pdf backend", "no vlist or hlist in (xform) shipout"); } - if (shipping_mode == SHIPPING_PAGE) total_pages++; cur_s = -1; - /* Finish shipping */ - switch (output_mode_used) { case OMODE_DVI: dvi_end_page(pdf); @@ -295,10 +291,8 @@ void ship_out(PDF pdf, halfword p, shipping_mode_e shipping_mode) default: normal_error("pdf backend", "unknown output mode"); } - DONE: - if ((tracing_output <= 0) && (post_callback_id == 0) - && shipping_mode == SHIPPING_PAGE) { + if ((tracing_output <= 0) && (post_callback_id == 0) && shipping_mode == SHIPPING_PAGE) { print_char(']'); update_terminal(); } @@ -321,10 +315,8 @@ void ship_out(PDF pdf, halfword p, shipping_mode_e shipping_mode) } if (shipping_mode == SHIPPING_PAGE && (post_callback_id > 0)) (void) run_callback(post_callback_id, "->"); - /* Finish sheet {\sl Sync\TeX} information record */ if (int_par(synctex_code)) synctexteehs(); - global_shipping_mode = NOT_SHIPPING; } diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdftables.h b/Build/source/texk/web2c/luatexdir/pdf/pdftables.h index adcff69964c..f08195b4e04 100644 --- a/Build/source/texk/web2c/luatexdir/pdf/pdftables.h +++ b/Build/source/texk/web2c/luatexdir/pdf/pdftables.h @@ -15,8 +15,8 @@ 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/>. */ - + with LuaTeX; if not, see <http://www.gnu.org/licenses/>. +*/ #ifndef PDFTABLES_H # define PDFTABLES_H @@ -33,52 +33,49 @@ typedef struct { int int0; char *str0; } u; - union_type u_type; /* integer or char * in union above */ + union_type u_type; /* integer or char * in union above */ int objptr; } oentry; /* -The cross-reference table |obj_tab| is an array of |obj_tab_size| of -|obj_entry|. Each entry contains five integer fields and represents an object -in PDF file whose object number is the index of this entry in |obj_tab|. -Objects in |obj_tab| maybe linked into list; objects in such a linked list have -the same type. -*/ -/* -The first field contains information representing identifier of this object. -It is usally a number for most of object types, but it may be a string number -for named destination or named thread. +The cross-reference table |obj_tab| is an array of |obj_tab_size| of |obj_entry|. +Each entry contains five integer fields and represents an object in PDF file +whose object number is the index of this entry in |obj_tab|. Objects in |obj_tab| +maybe linked into list; objects in such a linked list have the same type. -The second field of |obj_entry| contains link to the next -object in |obj_tab| if this object is linked in a list. +The first field contains information representing identifier of this object. It +is usally a number for most of object types, but it may be a string number for +named destination or named thread. -The third field holds the byte offset of the object in the output PDF file, -or its byte offset within an object stream. As long as the object is not -written, this field is used for flags about the write status of the object; -then it has a negative value. +The second field of |obj_entry| contains link to the next object in |obj_tab| if +this object is linked in a list. -The fourth field holds the object number of the object stream, into which -the object is included. +The third field holds the byte offset of the object in the output PDF file, or +its byte offset within an object stream. As long as the object is not written, +this field is used for flags about the write status of the object; then it has a +negative value. + +The fourth field holds the object number of the object stream, into which the +object is included. + +The last field usually represents the pointer to some auxiliary data structure +depending on the object type; however it may be used as a counter as well. -The last field usually represents the pointer to some auxiliary data -structure depending on the object type; however it may be used as a counter as -well. */ -# define obj_info(pdf,A) pdf->obj_tab[(A)].u.int0 /* information representing identifier of this object */ -# define obj_start(pdf,A) pdf->obj_tab[(A)].u.str0 -# define obj_link(pdf,A) pdf->obj_tab[(A)].int1 /* link to the next entry in linked list */ +# define obj_info(pdf,A) pdf->obj_tab[(A)].u.int0 /* information representing identifier of this object */ +# define obj_start(pdf,A) pdf->obj_tab[(A)].u.str0 +# define obj_link(pdf,A) pdf->obj_tab[(A)].int1 /* link to the next entry in linked list */ -# define obj_offset(pdf,A) pdf->obj_tab[(A)].int2 /* negative (flags), or byte offset for this object in PDF - output file, or ... */ -# define obj_os_objnum(pdf,A) pdf->obj_tab[(A)].int2 /* ... object stream number for this object */ -# define obj_os_idx(pdf,A) pdf->obj_tab[(A)].int3 /* index of this object in object stream */ -# define obj_aux(pdf,A) pdf->obj_tab[(A)].v.int4 /* auxiliary pointer */ -# define obj_stop(pdf,A) pdf->obj_tab[(A)].v.str4 -# define obj_type(pdf,A) pdf->obj_tab[(A)].objtype +# define obj_offset(pdf,A) pdf->obj_tab[(A)].int2 /* negative (flags), or byte offset for this object in PDF output file, or ... */ +# define obj_os_objnum(pdf,A) pdf->obj_tab[(A)].int2 /* ... object stream number for this object */ +# define obj_os_idx(pdf,A) pdf->obj_tab[(A)].int3 /* index of this object in object stream */ +# define obj_aux(pdf,A) pdf->obj_tab[(A)].v.int4 /* auxiliary pointer */ +# define obj_stop(pdf,A) pdf->obj_tab[(A)].v.str4 +# define obj_type(pdf,A) pdf->obj_tab[(A)].objtype -# define obj_data_ptr obj_aux /* pointer to |pdf->mem| */ +# define obj_data_ptr obj_aux /* pointer to |pdf->mem| */ # define set_obj_link(pdf,A,B) obj_link(pdf,A)=(B) # define set_obj_start(pdf,A,B) obj_start(pdf,A)=(B) @@ -94,30 +91,25 @@ well. # define is_obj_scheduled(pdf,A) ((obj_offset(pdf,A))>(off_t)-2) # define is_obj_written(pdf,A) ((obj_offset(pdf,A))>(off_t)-1) -/* NOTE: The data structure definitions for the nodes on the typesetting side are - inside |nodes.h| */ +/* + NOTE: The data structure definitions for the nodes on the typesetting side are + inside |nodes.h| +*/ -/* Some constants */ -# define inf_pk_dpi 72 /* min PK pixel density value from \.{texmf.cnf} */ -# define sup_pk_dpi 8000 /* max PK pixel density value from \.{texmf.cnf} */ +# define inf_pk_dpi 72 /* min PK pixel density value from \.{texmf.cnf} */ +# define sup_pk_dpi 8000 /* max PK pixel density value from \.{texmf.cnf} */ extern int find_obj(PDF pdf, int t, int i, boolean byname); extern void check_obj_exists(PDF pdf, int objnum); extern void check_obj_type(PDF pdf, int t, int objnum); extern int pdf_get_obj(PDF pdf, int t, int i, boolean byname); extern int pdf_create_obj(PDF pdf, int t, int i); - -extern void set_rect_dimens(PDF pdf, halfword p, halfword parent_box, - scaledpos cur, scaled_whd alt_rule, scaled margin); - +extern void set_rect_dimens(PDF pdf, halfword p, halfword parent_box, scaledpos cur, scaled_whd alt_rule, scaled margin); extern void libpdffinish(PDF); -extern void dump_pdftex_data(PDF pdf); -extern void undump_pdftex_data(PDF pdf); - -# define set_width(A, B) width(A) = (B) -# define set_height(A, B) height(A) = (B) -# define set_depth(A, B) depth(A) = (B) +# define set_width(A,B) width(A)=(B) +# define set_height(A,B) height(A)=(B) +# define set_depth(A,B) depth(A)=(B) /* pdf backend definitions */ @@ -138,7 +130,6 @@ typedef enum { c_pdf_objcompresslevel, c_pdf_inclusion_copy_font, c_pdf_gen_tounicode, - c_pdf_replace_font, } pdf_backend_counters ; typedef enum { @@ -158,6 +149,11 @@ typedef enum { t_pdf_pk_mode, } pdf_backend_tokenlists ; +extern int pdf_last_annot; +extern int pdf_last_link; +extern int pdf_last_obj; +extern int pdf_retval; + # define pdf_compress_level get_tex_extension_count_register(c_pdf_compress_level) # define pdf_decimal_digits get_tex_extension_count_register(c_pdf_decimal_digits) # define pdf_image_resolution get_tex_extension_count_register(c_pdf_image_resolution) @@ -174,7 +170,6 @@ typedef enum { # define pdf_objcompresslevel get_tex_extension_count_register(c_pdf_objcompresslevel) # define pdf_inclusion_copy_font get_tex_extension_count_register(c_pdf_inclusion_copy_font) # define pdf_gen_tounicode get_tex_extension_count_register(c_pdf_gen_tounicode) -# define pdf_replace_font get_tex_extension_count_register(c_pdf_replace_font) # define pdf_h_origin get_tex_extension_dimen_register(d_pdf_h_origin) # define pdf_v_origin get_tex_extension_dimen_register(d_pdf_v_origin) @@ -193,4 +188,6 @@ typedef enum { # define set_pdf_compress_level(i) set_tex_extension_count_register(c_pdf_compress_level,i) # define set_pdf_objcompresslevel(i) set_tex_extension_count_register(c_pdf_objcompresslevel,i) -#endif /* PDFTABLES_H */ +# define set_pdf_decimal_digits(i) set_tex_extension_count_register(c_pdf_decimal_digits,i) + +#endif diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdftables.w b/Build/source/texk/web2c/luatexdir/pdf/pdftables.w index 72f0474e922..d8b5cf10321 100644 --- a/Build/source/texk/web2c/luatexdir/pdf/pdftables.w +++ b/Build/source/texk/web2c/luatexdir/pdf/pdftables.w @@ -19,54 +19,55 @@ @ @c - #include "ptexlib.h" @ @c -const char *pdf_obj_typenames[PDF_OBJ_TYPE_MAX + 1] = - { "font", "outline", "dest", "obj", "xform", "ximage", "thread", +const char *pdf_obj_typenames[PDF_OBJ_TYPE_MAX + 1] = { + "font", "outline", "dest", "obj", "xform", "ximage", "thread", "pagestream", "page", "pages", "catalog", "info", "link", "annot", "annots", "bead", "beads", "objstm", "others" }; +int pdf_last_annot; +int pdf_last_link; +int pdf_last_obj; +int pdf_retval; /* global multi-purpose return value */ + @ AVL sort entry into |avl_table[]| @c static int compare_info(const void *pa, const void *pb, void *param) { - const oentry *a, *b; + const oentry *a = (const oentry *) pa; + const oentry *b = (const oentry *) pb; (void) param; - a = (const oentry *) pa; - b = (const oentry *) pb; if (a->u_type == b->u_type) { if (a->u_type == union_type_int) - return ((a->u.int0 < - b->u.int0 ? -1 : (a->u.int0 > b->u.int0 ? 1 : 0))); - else /* string type */ + return ((a->u.int0 < b->u.int0 ? -1 : (a->u.int0 > b->u.int0 ? 1 : 0))); + else /* string type */ return strcmp(a->u.str0, b->u.str0); - } else if (a->u_type == union_type_int) + } else if (a->u_type == union_type_int) { return -1; - else + } else { return 1; + } } static void avl_put_obj(PDF pdf, int t, oentry * oe) { void **pp; - assert(t >= 0 && t <= PDF_OBJ_TYPE_MAX); if (pdf->obj_tree[t] == NULL) { pdf->obj_tree[t] = avl_create(compare_info, NULL, &avl_xallocator); if (pdf->obj_tree[t] == NULL) - luatex_fail("avlstuff.c: avl_create() pdf->obj_tree failed"); + formatted_error("pdf backend","avl_create() pdf->obj_tree failed"); } pp = avl_probe(pdf->obj_tree[t], oe); if (pp == NULL) - luatex_fail("avlstuff.c: avl_probe() out of memory in insertion"); + formatted_error("pdf backend","avl_probe() out of memory in insertion"); } static void avl_put_int_obj(PDF pdf, int int0, int objptr, int t) { - oentry *oe; - oe = xtalloc(1, oentry); + oentry *oe = xtalloc(1, oentry); oe->u.int0 = int0; oe->u_type = union_type_int; oe->objptr = objptr; @@ -75,8 +76,7 @@ static void avl_put_int_obj(PDF pdf, int int0, int objptr, int t) static void avl_put_str_obj(PDF pdf, char *str0, int objptr, int t) { - oentry *oe; - oe = xtalloc(1, oentry); + oentry *oe = xtalloc(1, oentry); oe->u.str0 = str0; /* no xstrdup() here */ oe->u_type = union_type_cstring; oe->objptr = objptr; @@ -87,7 +87,6 @@ static int avl_find_int_obj(PDF pdf, int t, int i) { oentry *p; oentry tmp; - assert(t >= 0 && t <= PDF_OBJ_TYPE_MAX); tmp.u.int0 = i; tmp.u_type = union_type_int; if (pdf->obj_tree[t] == NULL) @@ -102,7 +101,6 @@ static int avl_find_str_obj(PDF pdf, int t, char *s) { oentry *p; oentry tmp; - assert(t >= 0 && t <= PDF_OBJ_TYPE_MAX); tmp.u.str0 = s; tmp.u_type = union_type_cstring; if (pdf->obj_tree[t] == NULL) @@ -128,9 +126,7 @@ int pdf_create_obj(PDF pdf, int t, int i) pdf->obj_tab_size = pdf->obj_tab_size + a; else pdf->obj_tab_size = sup_obj_tab_size; - pdf->obj_tab = - xreallocarray(pdf->obj_tab, obj_entry, - (unsigned) pdf->obj_tab_size); + pdf->obj_tab = xreallocarray(pdf->obj_tab, obj_entry, (unsigned) pdf->obj_tab_size); } pdf->obj_ptr++; obj_info(pdf, pdf->obj_ptr) = i; @@ -146,8 +142,7 @@ int pdf_create_obj(PDF pdf, int t, int i) obj_link(pdf, pdf->obj_ptr) = pdf->head_tab[t]; pdf->head_tab[t] = pdf->obj_ptr; if ((t == obj_type_dest) && (i < 0)) - append_dest_name(pdf, makecstring(-obj_info(pdf, pdf->obj_ptr)), - pdf->obj_ptr); + append_dest_name(pdf, makecstring(-obj_info(pdf, pdf->obj_ptr)), pdf->obj_ptr); /* why not just -i */ } return pdf->obj_ptr; } @@ -157,7 +152,6 @@ int find_obj(PDF pdf, int t, int i, boolean byname) { char *ss = NULL; int ret; - assert(i >= 0); /* no tricks */ if (byname) { ss = makecstring(i); ret = avl_find_str_obj(pdf, t, ss); @@ -169,19 +163,17 @@ int find_obj(PDF pdf, int t, int i, boolean byname) } @ The following function finds an object with identifier |i| and type |t|. - Identifier |i| is either an integer or a token list index. If no - such object exists then it will be created. This function is used mainly to - find destination for link annotations and outlines; however it is also used - in |ship_out| (to check whether a Page object already exists) so we need - to declare it together with subroutines needed in |hlist_out| and - |vlist_out|. +Identifier |i| is either an integer or a token list index. If no such object +exists then it will be created. This function is used mainly to find destination +for link annotations and outlines; however it is also used in |ship_out| (to +check whether a Page object already exists) so we need to declare it together +with subroutines needed in |hlist_out| and |vlist_out|. @c int pdf_get_obj(PDF pdf, int t, int i, boolean byname) { int r; str_number s; - assert(i >= 0); if (byname > 0) { s = tokens_to_string(i); r = find_obj(pdf, t, s, true); @@ -215,28 +207,22 @@ void check_obj_exists(PDF pdf, int objnum) void check_obj_type(PDF pdf, int t, int objnum) { int u; - char *s; check_obj_exists(pdf, objnum); u = obj_type(pdf, objnum); if (t != u) { - assert(t >= 0 && t <= PDF_OBJ_TYPE_MAX); - assert(u >= 0 && u <= PDF_OBJ_TYPE_MAX); - s = (char *) xtalloc(128, char); - snprintf(s, 127, "referenced object has wrong type %s; should be %s", - pdf_obj_typenames[u], pdf_obj_typenames[t]); - normal_error("pdf backend", s); + formatted_error("pdf backend", "referenced object has wrong type %s; should be %s", + pdf_obj_typenames[u], pdf_obj_typenames[t]); } } @ @c -void set_rect_dimens(PDF pdf, halfword p, halfword parent_box, scaledpos cur, - scaled_whd alt_rule, scaled margin) +void set_rect_dimens(PDF pdf, halfword p, halfword parent_box, scaledpos cur, scaled_whd alt_rule, scaled margin) { - scaledpos ll, ur; /* positions relative to cur */ + scaledpos ll, ur; /* positions relative to cur */ scaledpos pos_ll, pos_ur, tmp; posstructure localpos; localpos.dir = pdf->posstruct->dir; - ll.h = 0; /* pdf contains current point on page */ + ll.h = 0; /* pdf contains current point on page */ if (is_running(alt_rule.dp)) ll.v = depth(parent_box) - cur.v; else @@ -249,12 +235,10 @@ void set_rect_dimens(PDF pdf, halfword p, halfword parent_box, scaledpos cur, ur.v = -height(parent_box) - cur.v; else ur.v = -alt_rule.ht; - synch_pos_with_cur(&localpos, pdf->posstruct, ll); pos_ll = localpos.pos; synch_pos_with_cur(&localpos, pdf->posstruct, ur); pos_ur = localpos.pos; - if (pos_ll.h > pos_ur.h) { tmp.h = pos_ll.h; pos_ll.h = pos_ur.h; @@ -292,148 +276,3 @@ void libpdffinish(PDF pdf) glyph_unicode_free(); zip_free(pdf); } - -@ Store some of the pdftex data structures in the format. The idea here is -to ensure that any data structures referenced from pdftex-specific whatsit -nodes are retained. For the sake of simplicity and speed, all the filled parts -of |pdf->mem| and |obj_tab| are retained, in the present implementation. We also -retain three of the linked lists that start from |head_tab|, so that it is -possible to, say, load an image in the \.{INITEX} run and then reference it in a -\.{VIRTEX} run that uses the dumped format. - -@c -void dump_pdftex_data(PDF pdf) -{ - int k, x; - pdf_object_list *l; - dumpimagemeta(); /* the image information array */ - dump_int(pdf->mem_size); - dump_int(pdf->mem_ptr); - for (k = 1; k <= pdf->mem_ptr - 1; k++) { - x = pdf->mem[k]; - dump_int(x); - } - print_ln(); - print_int(pdf->mem_ptr - 1); - tprint(" words of pdf memory"); - x = pdf->obj_tab_size; - dump_int(x); - x = pdf->obj_ptr; - dump_int(x); - for (k = 1; k <= pdf->obj_ptr; k++) { - x = obj_info(pdf, k); - dump_int(x); - x = obj_link(pdf, k); - dump_int(x); - x = obj_os_idx(pdf, k); - dump_int(x); - x = obj_aux(pdf, k); - dump_int(x); - x = obj_type(pdf, k); - dump_int(x); - } - print_ln(); - print_int(pdf->obj_ptr); - tprint(" indirect objects"); - dump_int(pdf->obj_count); - dump_int(pdf->xform_count); - dump_int(pdf->ximage_count); - if ((l = get_page_resources_list(pdf, obj_type_obj)) != NULL) { - while (l != NULL) { - dump_int(l->info); - l = l->link; - } - } - dump_int(0); /* signal end of |obj_list| */ - if ((l = get_page_resources_list(pdf, obj_type_xform)) != NULL) { - while (l != NULL) { - dump_int(l->info); - l = l->link; - } - } - dump_int(0); /* signal end of |xform_list| */ - if ((l = get_page_resources_list(pdf, obj_type_ximage)) != NULL) { - while (l != NULL) { - dump_int(l->info); - l = l->link; - } - } - dump_int(0); /* signal end of |ximage_list| */ - x = pdf->head_tab[obj_type_obj]; - dump_int(x); - x = pdf->head_tab[obj_type_xform]; - dump_int(x); - x = pdf->head_tab[obj_type_ximage]; - dump_int(x); - dump_int(pdf_last_obj); - dump_int(last_saved_box_index); - dump_int(last_saved_image_index); -} - -@ And restoring the pdftex data structures from the format. The -two function arguments to |undumpimagemeta| have been restored -already in an earlier module. - -@c -void undump_pdftex_data(PDF pdf) -{ - int k, x; - undumpimagemeta(pdf, pdf_minor_version, pdf_inclusion_errorlevel); /* the image information array */ - undump_int(pdf->mem_size); - pdf->mem = xreallocarray(pdf->mem, int, (unsigned) pdf->mem_size); - undump_int(pdf->mem_ptr); - for (k = 1; k <= pdf->mem_ptr - 1; k++) { - undump_int(x); - pdf->mem[k] = (int) x; - } - undump_int(x); - pdf->obj_tab_size = x; - undump_int(x); - pdf->obj_ptr = x; - for (k = 1; k <= pdf->obj_ptr; k++) { - undump_int(x); - obj_info(pdf, k) = x; - undump_int(x); - obj_link(pdf, k) = x; - set_obj_offset(pdf, k, -1); - undump_int(x); - obj_os_idx(pdf, k) = x; - undump_int(x); - obj_aux(pdf, k) = x; - undump_int(x); - obj_type(pdf, k) = x; - } - - undump_int(x); - pdf->obj_count = x; - undump_int(x); - pdf->xform_count = x; - undump_int(x); - pdf->ximage_count = x; - /* todo : the next 3 loops can be done much more efficiently */ - undump_int(x); - while (x != 0) { - addto_page_resources(pdf, obj_type_obj, x); - undump_int(x); - } - undump_int(x); - while (x != 0) { - addto_page_resources(pdf, obj_type_xform, x); - undump_int(x); - } - undump_int(x); - while (x != 0) { - addto_page_resources(pdf, obj_type_ximage, x); - undump_int(x); - } - - undump_int(x); - pdf->head_tab[obj_type_obj] = x; - undump_int(x); - pdf->head_tab[obj_type_xform] = x; - undump_int(x); - pdf->head_tab[obj_type_ximage] = x; - undump_int(pdf_last_obj); - undump_int(last_saved_box_index); - undump_int(last_saved_image_index); -} diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdfthread.h b/Build/source/texk/web2c/luatexdir/pdf/pdfthread.h index 5719803b86f..dd9078444fc 100644 --- a/Build/source/texk/web2c/luatexdir/pdf/pdfthread.h +++ b/Build/source/texk/web2c/luatexdir/pdf/pdfthread.h @@ -15,7 +15,8 @@ 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/>. */ + with LuaTeX; if not, see <http://www.gnu.org/licenses/>. +*/ #ifndef PDFTHREAD_H @@ -23,34 +24,36 @@ /* data structure of threads; words 1..4 represent the coordinates of the corners */ -# define obj_thread_first obj_aux /* pointer to the first bead */ +# define obj_thread_first obj_aux /* pointer to the first bead */ /* data structure of beads */ -# define pdfmem_bead_size 5 /* size of memory in |pdf->mem| which |obj_bead_ptr| points to */ +# define pdfmem_bead_size 5 /* size of memory in |pdf->mem| which |obj_bead_ptr| points to */ -# define set_pdf_thread_attr(A,B) pdf_thread_attr(A)=B -# define set_pdf_thread_id(A,B) pdf_thread_id(A)=B -# define set_pdf_thread_named_id(A,B) pdf_thread_named_id(A)=B +# define set_pdf_thread_attr(A,B) pdf_thread_attr(A)=B +# define set_pdf_thread_id(A,B) pdf_thread_id(A)=B +# define set_pdf_thread_named_id(A,B) pdf_thread_named_id(A)=B -# define obj_bead_ptr obj_aux /* pointer to |pdf->mem| */ +# define obj_bead_ptr obj_aux /* pointer to |pdf->mem| */ # define obj_bead_rect(pdf,A) pdf->mem[obj_bead_ptr(pdf,A)] # define obj_bead_page(pdf,A) pdf->mem[obj_bead_ptr(pdf,A) + 1] # define obj_bead_next(pdf,A) pdf->mem[obj_bead_ptr(pdf,A) + 2] # define obj_bead_prev(pdf,A) pdf->mem[obj_bead_ptr(pdf,A) + 3] # define obj_bead_attr(pdf,A) pdf->mem[obj_bead_ptr(pdf,A) + 4] +# define obj_bead_data obj_bead_rect +# define set_obj_bead_data set_obj_bead_rect -# define set_obj_bead_rect(pdf,A,B) obj_bead_rect(pdf,A)=B -# define set_obj_bead_page(pdf,A,B) obj_bead_page(pdf,A)=B -# define set_obj_bead_next(pdf,A,B) obj_bead_next(pdf,A)=B -# define set_obj_bead_prev(pdf,A,B) obj_bead_prev(pdf,A)=B -# define set_obj_bead_attr(pdf,A,B) obj_bead_attr(pdf,A)=B +# define set_obj_bead_rect(pdf,A,B) obj_bead_rect(pdf,A)=B +# define set_obj_bead_page(pdf,A,B) obj_bead_page(pdf,A)=B +# define set_obj_bead_next(pdf,A,B) obj_bead_next(pdf,A)=B +# define set_obj_bead_prev(pdf,A,B) obj_bead_prev(pdf,A)=B +# define set_obj_bead_attr(pdf,A,B) obj_bead_attr(pdf,A)=B -/* pointer to the corresponding whatsit node; |obj_bead_rect| is needed only when the bead - rectangle has been written out and after that |obj_bead_data| is not needed any more - so we can use this field for both */ -# define obj_bead_data obj_bead_rect -# define set_obj_bead_data set_obj_bead_rect +/* + pointer to the corresponding whatsit node; |obj_bead_rect| is needed only when the bead + rectangle has been written out and after that |obj_bead_data| is not needed any more + so we can use this field for both +*/ extern void append_bead(PDF pdf, halfword p); extern void do_thread(PDF pdf, halfword parent_box, halfword p, scaledpos cur); diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdfthread.w b/Build/source/texk/web2c/luatexdir/pdf/pdfthread.w index 85f7007aa67..b11e48c5fc0 100644 --- a/Build/source/texk/web2c/luatexdir/pdf/pdfthread.w +++ b/Build/source/texk/web2c/luatexdir/pdf/pdfthread.w @@ -19,7 +19,6 @@ @ @c - #include "ptexlib.h" @ @c @@ -32,9 +31,8 @@ void append_bead(PDF pdf, halfword p) { int a, b, c, t; if (global_shipping_mode == SHIPPING_FORM) - normal_error("pdf backend", "threads cannot be inside an XForm"); - t = pdf_get_obj(pdf, obj_type_thread, pdf_thread_id(p), - pdf_thread_named_id(p)); + normal_error("pdf backend", "threads cannot be inside an xform"); + t = pdf_get_obj(pdf, obj_type_thread, pdf_thread_id(p), pdf_thread_named_id(p)); b = pdf_create_obj(pdf, obj_type_others, 0); obj_bead_ptr(pdf, b) = pdf_get_mem(pdf, pdfmem_bead_size); set_obj_bead_page(pdf, b, pdf->last_page); @@ -87,9 +85,8 @@ void do_thread(PDF pdf, halfword p, halfword parent_box, scaledpos cur) @ @c void append_thread(PDF pdf, halfword parent_box, scaledpos cur) { - halfword p; scaled_whd alt_rule; - p = new_node(whatsit_node, pdf_thread_data_node); + halfword p = new_node(whatsit_node, pdf_thread_data_node); width(p) = pdf->thread.wd; height(p) = pdf->thread.ht; depth(p) = pdf->thread.dp; @@ -119,18 +116,18 @@ void end_thread(PDF pdf, halfword p) normal_error("pdf backend", "'endthread' ended up in different nesting level than 'startthread'"); if (is_running(pdf->thread.dp) && (pdf->last_thread != null)) { switch (pdf->posstruct->dir) { - case dir_TLT: - case dir_TRT: - pdf_ann_bottom(pdf->last_thread) = pos.v - pdf_thread_margin; - break; - case dir_LTL: - pdf_ann_right(pdf->last_thread) = pos.h + pdf_thread_margin; - break; - case dir_RTT: - pdf_ann_left(pdf->last_thread) = pos.h - pdf_thread_margin; - break; - default: - assert(0); + case dir_TLT: + case dir_TRT: + pdf_ann_bottom(pdf->last_thread) = pos.v - pdf_thread_margin; + break; + case dir_LTL: + pdf_ann_right(pdf->last_thread) = pos.h + pdf_thread_margin; + break; + case dir_RTT: + pdf_ann_left(pdf->last_thread) = pos.h - pdf_thread_margin; + break; + default: + formatted_warning("pdf backend","forcing bad dir %i to TLT in end tread",pdf->posstruct->dir); } } if (pdf->last_thread_named_id) @@ -154,18 +151,12 @@ void thread_title(PDF pdf, int t) void pdf_fix_thread(PDF pdf, int t) { halfword a; - normal_warning("pdf backend", "thread destination", false, false); if (obj_info(pdf, t) < 0) { - tprint("name{"); - print(-obj_info(pdf, t)); - tprint("}"); + char *ss = makecstring(-obj_info(pdf, t)); + formatted_warning("pdf backend", "unknown thread destination name '%s'",ss); } else { - tprint("num"); - print_int(obj_info(pdf, t)); + formatted_warning("pdf backend", "unknown thread destination num '%d'",obj_info(pdf, t)); } - tprint(" has been referenced but does not exist, replaced by a fixed one"); - print_ln(); - print_ln(); a = pdf_create_obj(pdf, obj_type_others, 0); pdf_begin_obj(pdf, a, OBJSTM_ALWAYS); pdf_begin_dict(pdf); @@ -182,7 +173,6 @@ void pdf_fix_thread(PDF pdf, int t) pdf_end_array(pdf); pdf_end_dict(pdf); pdf_end_obj(pdf); - pdf_begin_obj(pdf, t, OBJSTM_ALWAYS); pdf_begin_dict(pdf); pdf_add_name(pdf, "I"); @@ -250,7 +240,7 @@ void scan_thread_id(void) set_pdf_thread_id(cur_list.tail_field, cur_val); set_pdf_thread_named_id(cur_list.tail_field, 0); } else if (scan_keyword("name")) { - scan_pdf_ext_toks(); + scan_toks(false, true); set_pdf_thread_id(cur_list.tail_field, def_ref); set_pdf_thread_named_id(cur_list.tail_field, 1); } else { @@ -276,9 +266,9 @@ void print_bead_rectangles(PDF pdf) l = pdf_create_obj(pdf, obj_type_others, 0); pdf_begin_obj(pdf, l, OBJSTM_ALWAYS); pdf_begin_array(pdf); - i = obj_bead_data(pdf, k->info); /* pointer to a whatsit or whatsit-like node */ + i = obj_bead_data(pdf, k->info); /* pointer to a whatsit or whatsit-like node */ pdf_add_rect_spec(pdf, i); - if (subtype(i) == pdf_thread_data_node) /* thanh says it mis be destroyed here */ + if (subtype(i) == pdf_thread_data_node) flush_node(i); pdf_end_array(pdf); pdf_end_obj(pdf); diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdftypes.h b/Build/source/texk/web2c/luatexdir/pdf/pdftypes.h index b25d74d1cc9..f3dafb0ce35 100644 --- a/Build/source/texk/web2c/luatexdir/pdf/pdftypes.h +++ b/Build/source/texk/web2c/luatexdir/pdf/pdftypes.h @@ -15,7 +15,9 @@ 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/>. */ + with LuaTeX; if not, see <http://www.gnu.org/licenses/>. + +*/ #ifndef PDFTYPES_H # define PDFTYPES_H @@ -26,26 +28,27 @@ # include <zlib.h> # include "lua/luatex-api.h" -/* The prefix "PTEX" for the PDF keys is special to pdfTeX; - this has been registered with Adobe by Hans Hagen. */ +/* + The prefix "PTEX" for the PDF keys is special to pdfTeX and has been registered with + Adobe by Hans Hagen. +*/ # define pdfkeyprefix "PTEX" # define i32round(a) (int) floor((a) + 0.5) # define i64round(a) (int64_t) floor((a) + 0.5) -# define MAX_OBJ_COMPRESS_LEVEL 3 /* maximum/clipping value for \pdfobjcompresslevel */ -# define OBJSTM_UNSET -1 /* initial value */ -# define OBJSTM_ALWAYS 1 /* \pdfobjcompresslevel >= OBJSTM_ALWAYS: put object into object stream */ -# define OBJSTM_NEVER (MAX_OBJ_COMPRESS_LEVEL + 1) - /* above maximum/clipping value for \pdfobjcompresslevel */ +# define MAX_OBJ_COMPRESS_LEVEL 3 /* maximum/clipping value for \pdfobjcompresslevel */ +# define OBJSTM_UNSET -1 /* initial value */ +# define OBJSTM_ALWAYS 1 /* \pdfobjcompresslevel >= OBJSTM_ALWAYS: put object into object stream */ +# define OBJSTM_NEVER (MAX_OBJ_COMPRESS_LEVEL + 1) /* above maximum/clipping value for \pdfobjcompresslevel */ -typedef int internal_font_number; /* |font| in a |char_node| */ +typedef int internal_font_number; /* |font| in a |char_node| */ typedef enum { - NO_ZIP, /* no \.{ZIP} compression */ - ZIP_WRITING, /* \.{ZIP} compression being used */ - ZIP_FINISH /* finish \.{ZIP} compression */ + NO_ZIP, /* no \.{ZIP} compression */ + ZIP_WRITING, /* \.{ZIP} compression being used */ + ZIP_FINISH /* finish \.{ZIP} compression */ } zip_write_state_e; typedef enum { @@ -53,19 +56,21 @@ typedef enum { OBJSTM_BUF, } buffer_e; -/* This stucture holds everything that is needed for the actual pdf generation. +/* + This stucture holds everything that is needed for the actual pdf generation. + + Because this structure interfaces with C++, it is not wise to use |boolean| + here (C++ has a boolean type built-in that is not compatible). Also, I have + plans to convert the backend code into a C library for use with e.g. standalone + lua. Together, this means that it is best only to use the standard C types and + the types explicitly defined in this header, and stay away from types like + |integer| and |eight_bits| that are used elsewhere in the \LUATEX\ sources. -Because this structure interfaces with C++, it is not wise to use |boolean| -here (C++ has a boolean type built-in that is not compatible). Also, I have -plans to convert the backend code into a C library for use with e.g. standalone -lua. Together, this means that it is best only to use the standard C types and -the types explicitly defined in this header, and stay away from types like -|integer| and |eight_bits| that are used elsewhere in the \LUATEX\ sources. */ typedef struct { - int64_t m; /* mantissa (significand) */ - int e; /* exponent * -1 */ + int64_t m; /* mantissa (significand) */ + int e; /* exponent * -1 */ } pdffloat; typedef struct { @@ -81,26 +86,35 @@ typedef struct scaledpos_ { } scaledpos; typedef struct scaled_whd_ { - scaled wd; /* TeX width */ - scaled ht; /* TeX height */ - scaled dp; /* TeX depth */ + scaled wd; /* TeX width */ + scaled ht; /* TeX height */ + scaled dp; /* TeX depth */ } scaled_whd; typedef struct posstructure_ { - scaledpos pos; /* position on the page */ - int dir; /* direction of stuff to be put onto the page */ + scaledpos pos; /* position on the page */ + int dir; /* direction of stuff to be put onto the page */ } posstructure; typedef struct { - scaledpos curpos; /* \pdflastpos position */ - posstructure boxpos; /* box dir and position of the box origin on the page */ - scaled_whd boxdim; /* box dimensions (in hlist/vlist coordinate system) */ + scaledpos curpos; /* \pdflastpos position */ + posstructure boxpos; /* box dir and position of the box origin on the page */ + scaled_whd boxdim; /* box dimensions (in hlist/vlist coordinate system) */ } pos_info_structure; -typedef enum { PMODE_NONE, PMODE_PAGE, PMODE_TEXT, PMODE_CHARARRAY, PMODE_CHAR +typedef enum { + PMODE_NONE, + PMODE_PAGE, + PMODE_TEXT, + PMODE_CHARARRAY, + PMODE_CHAR } pos_mode; -typedef enum { ST_INITIAL, ST_OMODE_FIX, ST_FILE_OPEN, ST_HEADER_WRITTEN, +typedef enum { + ST_INITIAL, + ST_OMODE_FIX, + ST_FILE_OPEN, + ST_HEADER_WRITTEN, ST_FILE_CLOSED } output_state; @@ -109,14 +123,16 @@ typedef struct pdf_object_list_ { struct pdf_object_list_ *link; } pdf_object_list; -typedef enum { WMODE_H, WMODE_V } writing_mode; /* []TJ runs horizontal or vertical */ +typedef enum { /* []TJ runs horizontal or vertical */ + WMODE_H, + WMODE_V +} writing_mode; 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 cw; /* pos. within [(..)..]TJ array (glyph raster); cw.e = fractional digits in /Widths array */ pdffloat tj_delta; /* rel. movement in [(..)..]TJ array (glyph raster) */ pdffloat fs; /* font size in PDF units */ pdffloat fs_cur; /* to check if fs.m has changed and Tf needed */ @@ -155,7 +171,7 @@ typedef struct dest_name_entry_ { int objnum; /* destination object number */ } dest_name_entry; -# define pdf_max_link_level 10/* maximum depth of link nesting */ +# define pdf_max_link_level 10 /* maximum depth of link nesting */ typedef struct pdf_link_stack_record { int nesting_level; @@ -166,6 +182,12 @@ typedef struct pdf_link_stack_record { } pdf_link_stack_record; /* types of objects */ + +/* + NB: |obj_type_thread| is the highest entry in |head_tab|, but there are a few + more linked lists that are handy. +*/ + typedef enum { obj_type_font = 0, /* index of linked list of Fonts objects */ obj_type_outline = 1, /* index of linked list of outline objects */ @@ -174,8 +196,6 @@ typedef enum { obj_type_xform = 4, /* index of linked list of XObject forms */ obj_type_ximage = 5, /* index of linked list of XObject images */ obj_type_thread = 6, /* index of linked list of num article threads */ - /* |obj_type_thread| is the highest entry in |head_tab|, but there are a few - more linked lists that are handy: */ obj_type_pagestream = 7, /* Page stream objects */ obj_type_page = 8, /* /Page objects */ obj_type_pages = 9, /* /Pages objects */ @@ -198,7 +218,6 @@ typedef struct pdf_resource_struct_ { int last_resources; /* halfword to most recently generated Resources object. */ } pdf_resource_struct; -/**********************************************************************/ typedef struct os_obj_data_ { int num; @@ -222,10 +241,9 @@ typedef struct os_struct_ { unsigned int o_ctr; /* statistics: counter for objects within object streams */ } os_struct; -/**********************************************************************/ -# define packet_max_recursion 100 /* see |packet_cur_s| */ -# define packet_stack_size 100 +# define packet_max_recursion 100 /* see |packet_cur_s| */ +# define packet_stack_size 100 typedef struct packet_stack_record_ { float c0; @@ -247,8 +265,6 @@ typedef struct vf_struct_ { int vflua; /* flag, whether vf.*() functions are allowed */ } vf_struct; -/**********************************************************************/ - typedef struct pdf_output_file_ { FILE *file; /* the PDF output file handle */ char *file_name; /* the PDF output file name */ @@ -265,7 +281,6 @@ typedef struct pdf_output_file_ { int decimal_digits; int gen_tounicode; int inclusion_copy_font; - int replace_font; int minor_version; /* fixed minor part of the PDF version */ int compress_level; /* level for zlib object stream compression */ int objcompresslevel; /* fixed level for activating PDF object streams */ @@ -292,8 +307,7 @@ typedef struct pdf_output_file_ { int stream_deflate; /* true, if stream dict has /Filter/FlateDecode */ int stream_writing; /* true while writing stream */ - int pk_scale_factor; /* this is just a preprocessed value that depends on - |pk_resolution| and |decimal_digits| */ + int pk_scale_factor; /* this is just a preprocessed value that depends on |pk_resolution| and |decimal_digits| */ int img_page_group_val; /* page group information pointer from included pdf or png images */ char *resname_prefix; /* global prefix of resources name */ @@ -320,10 +334,6 @@ typedef struct pdf_output_file_ { int seek_write_length; /* flag whether to seek back and write \.{/Length} */ int last_byte; /* byte most recently written to PDF file; for \.{endstream} in new line */ - /* integer last_resources; halfword to most recently generated Resources object. - TH: this used to be a local in pdf_shipout, but I would like to - be able to split that function into a pre- and post part */ - int obj_count; int xform_count; int ximage_count; @@ -351,7 +361,6 @@ typedef struct pdf_output_file_ { int thread_level; /* depth of nesting of box containing the last thread */ int f_cur; /* TeX font number */ - int pdflua_ref; int cave; /* stay away from previous PDF object */ vf_struct *vfstruct; @@ -359,4 +368,4 @@ typedef struct pdf_output_file_ { typedef pdf_output_file *PDF; -#endif /* PDFTYPES_H */ +#endif diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdfxform.h b/Build/source/texk/web2c/luatexdir/pdf/pdfxform.h index 9c62f71c0a2..f7f6e54d68f 100644 --- a/Build/source/texk/web2c/luatexdir/pdf/pdfxform.h +++ b/Build/source/texk/web2c/luatexdir/pdf/pdfxform.h @@ -15,44 +15,37 @@ 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/>. */ + with LuaTeX; if not, see <http://www.gnu.org/licenses/>. +*/ #ifndef PDFXFORM_H # define PDFXFORM_H -/* data structure for box resources */ - -# define pdfmem_xform_size 8 /* size of memory in |pdf->mem| which |obj_data_ptr| holds */ - -# define set_pdf_xform_objnum(A,B) pdf_xform_objnum(A)=B - -# define obj_xform_width(pdf,A) pdf->mem[obj_data_ptr(pdf,A) + 0] -# define obj_xform_height(pdf,A) pdf->mem[obj_data_ptr(pdf,A) + 1] -# define obj_xform_depth(pdf,A) pdf->mem[obj_data_ptr(pdf,A) + 2] -# define obj_xform_box(pdf,A) pdf->mem[obj_data_ptr(pdf,A) + 3] /* this field holds - pointer to the corresponding box */ -# define obj_xform_attr(pdf,A) pdf->mem[obj_data_ptr(pdf,A) + 4] /* additional xform - attributes */ -# define obj_xform_resources(pdf,A) pdf->mem[obj_data_ptr(pdf,A) + 5] /* additional xform - Resources */ -# define obj_xform_attr_str(pdf,A) pdf->mem[obj_data_ptr(pdf,A) + 6] -# define obj_xform_resources_str(pdf,A) pdf->mem[obj_data_ptr(pdf,A) + 7] - - -# define set_obj_xform_width(pdf,A,B) obj_xform_width(pdf,A)=B -# define set_obj_xform_height(pdf,A,B) obj_xform_height(pdf,A)=B -# define set_obj_xform_depth(pdf,A,B) obj_xform_depth(pdf,A)=B -# define set_obj_xform_box(pdf,A,B) obj_xform_box(pdf,A)=B -# define set_obj_xform_attr(pdf,A,B) obj_xform_attr(pdf,A)=B -# define set_obj_xform_resources(pdf,A,B) obj_xform_resources(pdf,A)=B -# define set_obj_xform_attr_str(pdf,A,B) obj_xform_attr_str(pdf,A)=B +# define pdfmem_xform_size 8 /* size of memory in |pdf->mem| which |obj_data_ptr| holds */ + +# define obj_xform_width(pdf,A) pdf->mem[obj_data_ptr(pdf,A) + 0] +# define obj_xform_height(pdf,A) pdf->mem[obj_data_ptr(pdf,A) + 1] +# define obj_xform_depth(pdf,A) pdf->mem[obj_data_ptr(pdf,A) + 2] +# define obj_xform_box(pdf,A) pdf->mem[obj_data_ptr(pdf,A) + 3] /* this field holds pointer to the corresponding box */ +# define obj_xform_attr(pdf,A) pdf->mem[obj_data_ptr(pdf,A) + 4] /* additional xform attributes */ +# define obj_xform_resources(pdf,A) pdf->mem[obj_data_ptr(pdf,A) + 5] /* additional xform Resources */ +# define obj_xform_attr_str(pdf,A) pdf->mem[obj_data_ptr(pdf,A) + 6] +# define obj_xform_resources_str(pdf,A) pdf->mem[obj_data_ptr(pdf,A) + 7] + +# define set_pdf_xform_objnum(A,B) pdf_xform_objnum(A)=B +# define set_obj_xform_width(pdf,A,B) obj_xform_width(pdf,A)=B +# define set_obj_xform_height(pdf,A,B) obj_xform_height(pdf,A)=B +# define set_obj_xform_depth(pdf,A,B) obj_xform_depth(pdf,A)=B +# define set_obj_xform_box(pdf,A,B) obj_xform_box(pdf,A)=B +# define set_obj_xform_attr(pdf,A,B) obj_xform_attr(pdf,A)=B +# define set_obj_xform_resources(pdf,A,B) obj_xform_resources(pdf,A)=B +# define set_obj_xform_attr_str(pdf,A,B) obj_xform_attr_str(pdf,A)=B # define set_obj_xform_resources_str(pdf,A,B) obj_xform_resources_str(pdf,A)=B -extern int pdf_cur_form; /* the form being output */ +extern int pdf_cur_form; /* the form being output */ void pdf_place_form(PDF pdf, halfword p); - void scan_pdfxform(PDF pdf); void scan_pdfrefxform(PDF pdf); diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdfxform.w b/Build/source/texk/web2c/luatexdir/pdf/pdfxform.w index 46a0910f6f7..962acb0f031 100644 --- a/Build/source/texk/web2c/luatexdir/pdf/pdfxform.w +++ b/Build/source/texk/web2c/luatexdir/pdf/pdfxform.w @@ -73,14 +73,14 @@ void scan_pdfxform(PDF pdf) k = pdf_create_obj(pdf, obj_type_xform, pdf->xform_count); set_obj_data_ptr(pdf, k, pdf_get_mem(pdf, pdfmem_xform_size)); if (scan_keyword("attr")) { - scan_pdf_ext_toks(); + scan_toks(false, true); set_obj_xform_attr(pdf, k, def_ref); } else { set_obj_xform_attr(pdf, k, null); } set_obj_xform_attr_str(pdf, k, null); if (scan_keyword("resources")) { - scan_pdf_ext_toks(); + scan_toks(false, true); set_obj_xform_resources(pdf, k, def_ref); } else { set_obj_xform_resources(pdf, k, null); diff --git a/Build/source/texk/web2c/luatexdir/ptexlib.h b/Build/source/texk/web2c/luatexdir/ptexlib.h index 3d05b8661c5..e282e1774cc 100644 --- a/Build/source/texk/web2c/luatexdir/ptexlib.h +++ b/Build/source/texk/web2c/luatexdir/ptexlib.h @@ -80,7 +80,7 @@ extern char **suffixlist; /* in luainit.w */ # define check_buf(size, buf_size) \ if ((unsigned)(size) > (unsigned)(buf_size)) \ - luatex_fail("buffer overflow: %d > %d at file %s, line %d", \ + formatted_error("internal","buffer overflow: %d > %d at file %s, line %d", \ (int)(size), (int)(buf_size), __FILE__, __LINE__ ) # define append_char_to_buf(c, p, buf, buf_size) do { \ @@ -178,7 +178,6 @@ size_t T##_limit # include "pdf/pdflink.h" # include "pdf/pdflistout.h" # include "pdf/pdfliteral.h" -# include "pdf/pdfluaapi.h" # include "pdf/pdfobj.h" # include "pdf/pdfoutline.h" # include "pdf/pdfrule.h" @@ -188,9 +187,6 @@ size_t T##_limit # include "pdf/pdfthread.h" # include "pdf/pdfxform.h" -# include "lua/luagen.h" - -# include "luascripts/pdflua.h" # include "font/luatexfont.h" # include "font/mapfile.h" @@ -237,9 +233,6 @@ size_t T##_limit # include "tex/filename.h" -/* lua/luainit.c */ -extern void write_svnversion(char *a); - /**********************************************************************/ extern halfword new_ligkern(halfword head, halfword tail); @@ -288,9 +281,6 @@ int luacstring_input(void); int luacstring_partial(void); int luacstring_final_line(void); -/* lua/luatoken.c */ -void do_get_token_lua(int callback_id); - /* lua/luanode.c */ int visible_last_node_type(int n); void print_node_mem_stats(void); @@ -326,7 +316,6 @@ extern boolean get_callback(lua_State * L, int i); /* test whether a char in font is marked */ # define pdf_char_marked char_used -# define pdfassert assert # define voidcast(a) (void *)(a) # define fixmemcast(a) (smemory_word *)(a) diff --git a/Build/source/texk/web2c/luatexdir/tex/align.w b/Build/source/texk/web2c/luatexdir/tex/align.w index 75c3f932252..f1984a88c50 100644 --- a/Build/source/texk/web2c/luatexdir/tex/align.w +++ b/Build/source/texk/web2c/luatexdir/tex/align.w @@ -671,15 +671,15 @@ boolean fin_col(void) adjust_tail = cur_tail; pre_adjust_tail = cur_pre_tail; u = filtered_hpack(cur_list.head_field, cur_list.tail_field, 0, - additional, align_set_group, -1); + additional, align_set_group, -1, 0); w = width(u); cur_tail = adjust_tail; adjust_tail = null; cur_pre_tail = pre_adjust_tail; pre_adjust_tail = null; } else { - u = filtered_vpackage(vlink(cur_list.head_field), 0, additional, 0, - align_set_group, -1); + u = filtered_vpackage(vlink(cur_list.head_field), + 0, additional, 0, align_set_group, -1, 0); w = height(u); } n = min_quarterword; /* this represents a span count of 1 */ @@ -772,7 +772,7 @@ void fin_row(void) pointer p; /* the new unset box */ if (cur_list.mode_field == -hmode) { p = filtered_hpack(cur_list.head_field, cur_list.tail_field, 0, - additional, fin_row_group, -1); + additional, fin_row_group, -1, 0); pop_nest(); if (cur_pre_head != cur_pre_tail) append_list(cur_pre_head, cur_pre_tail); @@ -780,8 +780,8 @@ void fin_row(void) if (cur_head != cur_tail) append_list(cur_head, cur_tail); } else { - p = filtered_vpackage(vlink(cur_list.head_field), 0, additional, - max_depth, fin_row_group, -1); + p = filtered_vpackage(vlink(cur_list.head_field), + 0, additional, max_depth, fin_row_group, -1, 0); pop_nest(); vlink(cur_list.tail_field) = p; cur_list.tail_field = p; @@ -932,8 +932,8 @@ value is changed to zero and so is the next tabskip. width(q) = 0; q = vlink(vlink(q)); } while (q != null); - p = filtered_vpackage(preamble, saved_value(0), saved_level(0), - max_depth, preamble_group, -1); + p = filtered_vpackage(preamble, + saved_value(0), saved_level(0), max_depth, preamble_group, -1, 0); q = vlink(preamble); do { width(q) = height(q); diff --git a/Build/source/texk/web2c/luatexdir/tex/buildpage.w b/Build/source/texk/web2c/luatexdir/tex/buildpage.w index a1807b91993..409a10c33ba 100644 --- a/Build/source/texk/web2c/luatexdir/tex/buildpage.w +++ b/Build/source/texk/web2c/luatexdir/tex/buildpage.w @@ -19,7 +19,6 @@ @ @c - #include "ptexlib.h" @ @c @@ -32,7 +31,6 @@ #define vbadness int_par(vbadness_code) #define max_dead_cycles int_par(max_dead_cycles_code) #define output_box int_par(output_box_code) -#define body_direction int_par(body_direction_code) #define holding_inserts int_par(holding_inserts_code) #define vsize dimen_par(vsize_code) @@ -95,7 +93,6 @@ halfword best_page_break; /* break here to get the best page known so far int least_page_cost; /* the score for this currently best page */ scaled best_size; /* its |page_goal| */ - @ The page builder has another data structure to keep track of insertions. This is a list of four-word nodes, starting and ending at |page_ins_head|. That is, the first element of the list is node |r@t$_1$@>=vlink(page_ins_head)|; @@ -128,8 +125,6 @@ minimum badness among all page breaks considered so far. We have |best_ins_ptr(r)=null| if and only if no insertion for this box should be made to produce this optimum page. - - @ Pages are built by appending nodes to the current list in \TeX's vertical mode, which is at the outermost level of the semantic nest. This vlist is split into two parts; the ``current page'' that we have been @@ -195,13 +190,13 @@ scaled last_kern; /* used to implement \.{\\lastkern} */ int last_node_type; /* used to implement \.{\\lastnodetype} */ int insert_penalties; /* sum of the penalties for held-over insertions */ -#define print_plus(A,B) do { \ - if (page_so_far[(A)]!=0) { \ - tprint(" plus "); \ - print_scaled(page_so_far[(A)]); \ - tprint((B)); \ - } \ - } while (0) +#define print_plus(A,B) do { \ + if (page_so_far[(A)]!=0) { \ + tprint(" plus "); \ + print_scaled(page_so_far[(A)]); \ + tprint((B)); \ + } \ +} while (0) void print_totals(void) { @@ -216,7 +211,6 @@ void print_totals(void) } } - @ Here is a procedure that is called when the |page_contents| is changing from |empty| to |inserts_only| or |box_there|. @@ -242,14 +236,12 @@ void freeze_page_specs(int s) } } - @ The global variable |output_active| is true during the time the user's output routine is driving \TeX. @c boolean output_active; /* are we in the midst of an output routine? */ - @ The page builder is ready to start a fresh page if we initialize the following state variables. (However, the page insertion list is initialized elsewhere.) @@ -268,7 +260,6 @@ void start_new_page(void) page_max_depth = 0; } - @ At certain times box \.{\\outputbox} is supposed to be void (i.e., |null|), or an insertion box is supposed to be ready to accept a vertical list. If not, an error message is printed, and the following subroutine @@ -286,7 +277,6 @@ static void box_error(int n) box(n) = null; } - @ The following procedure guarantees that a given box register does not contain an \.{\\hbox}. @@ -304,7 +294,6 @@ static void ensure_vbox(int n) } } - @ \TeX\ is not always in vertical mode at the time |build_page| is called; the current mode reflects what \TeX\ should return to, after the contribution list has been emptied. A call on |build_page| should @@ -317,10 +306,9 @@ void build_page(void) halfword p; /* the node being appended */ halfword q, r; /* nodes being examined */ int b, c; /* badness and cost of current page */ - int pi; /* penalty to be added to the badness */ + int pi = 0; /* penalty to be added to the badness */ int n; /* insertion box number */ scaled delta, h, w; /* sizes used for insertion calculations */ - pi = 0; if ((vlink(contrib_head) == null) || output_active) return; do { @@ -917,9 +905,8 @@ void fire_up(halfword c) vbadness = inf_bad; save_vfuzz = vfuzz; vfuzz = max_dimen; /* inhibit error messages */ - box(output_box) = - filtered_vpackage(vlink(page_head), best_size, exactly, page_max_depth, - output_group, body_direction); + box(output_box) = filtered_vpackage(vlink(page_head), + best_size, exactly, page_max_depth, output_group, body_direction, 0); vbadness = save_vbadness; vfuzz = save_vfuzz; if (last_glue != max_halfword) @@ -993,7 +980,6 @@ void fire_up(halfword c) box(output_box) = null; } - @ When the user's output routine finishes, it has constructed a vlist in internal vertical mode, and \TeX\ will do the following: @@ -1045,5 +1031,4 @@ void resume_after_output(void) pop_nest(); lua_node_filter_s(buildpage_filter_callback,lua_key_index(after_output)); build_page(); - } diff --git a/Build/source/texk/web2c/luatexdir/tex/commands.h b/Build/source/texk/web2c/luatexdir/tex/commands.h index ef0e5d796df..d2a7779a0e1 100644 --- a/Build/source/texk/web2c/luatexdir/tex/commands.h +++ b/Build/source/texk/web2c/luatexdir/tex/commands.h @@ -207,6 +207,7 @@ typedef enum { variable_cmd, feedback_cmd, the_cmd, /* expand an internal quantity ( \.{\\the} or \.{\\unexpanded}, \.{\\detokenize} ) */ + combine_toks_cmd, top_bot_mark_cmd, /* inserted mark ( \.{\\topmark}, etc.~) */ call_cmd, /* non-long, non-outer control sequence */ long_call_cmd, /* long, non-outer control sequence */ @@ -234,33 +235,34 @@ typedef enum { typedef enum { number_code = 0, /* command code for \.{\\number} */ - roman_numeral_code, /* command code for \.{\\romannumeral} */ + lua_function_code, /* command code for \.{\\luafunction} */ + lua_code, /* command code for \.{\\directlua} */ + expanded_code, /* command code for \.{\\expanded} */ + math_style_code, /* command code for \.{\\mathstyle} */ string_code, /* command code for \.{\\string} */ + cs_string_code, /* command code for \.{\\csstring} */ + roman_numeral_code, /* command code for \.{\\romannumeral} */ meaning_code, /* command code for \.{\\meaning} */ + uchar_code, /* command code for \.{\\Uchar} */ + lua_escape_string_code, /* command code for \.{\\luaescapestring} */ + font_id_code, /* command code for \.{\\fontid} */ font_name_code, /* command code for \.{\\fontname} */ - etex_code, /* command code for \.{\\eTeXVersion} */ - format_name_code, /* command code for \.{\\AlephVersion} */ - luatex_banner_code, /* command code for \.{\\luatexbanner}: */ left_margin_kern_code, /* command code for \.{\\leftmarginkern} */ right_margin_kern_code, /* command code for \.{\\rightmarginkern} */ uniform_deviate_code, /* command code for \.{\\uniformdeviate} */ normal_deviate_code, /* command code for \.{\\normaldeviate} */ - lua_code, /* command code for \.{\\directlua} */ - lua_escape_string_code, /* command code for \.{\\luaescapestring} */ + math_char_class_code, + math_char_fam_code, + math_char_slot_code, + insert_ht_code, /* command code for \.{\\insertht} */ + job_name_code, /* command code for \.{\\jobname} */ + format_name_code, /* command code for \.{\\AlephVersion} */ + luatex_banner_code, /* command code for \.{\\luatexbanner}: */ luatex_revision_code, /* command code for \.{\\luatexrevision} */ luatex_date_code, /* command code for \.{\\luatexdate} */ - math_style_code, /* command code for \.{\\mathstyle} */ - expanded_code, /* command code for \.{\\expanded} */ - job_name_code, /* command code for \.{\\jobname} */ + etex_code, /* command code for \.{\\eTeXVersion} */ eTeX_revision_code, /* command code for \.{\\eTeXrevision} */ font_identifier_code, /* command code for \.{tex.fontidentifier} (virtual) */ - font_id_code, /* command code for \.{\\fontid} */ - uchar_code, /* command code for \.{\\Uchar} */ - lua_function_code, /* command code for \.{\\luafunction} */ - insert_ht_code, /* command code for \.{\\insertht} */ - math_char_class_code, - math_char_fam_code, - math_char_slot_code, /* backend */ dvi_feedback_code, pdf_feedback_code, diff --git a/Build/source/texk/web2c/luatexdir/tex/commands.w b/Build/source/texk/web2c/luatexdir/tex/commands.w index 8cd6128b54d..02c2e4a74ae 100644 --- a/Build/source/texk/web2c/luatexdir/tex/commands.w +++ b/Build/source/texk/web2c/luatexdir/tex/commands.w @@ -1,4 +1,4 @@ - % commands.w +% commands.w % % Copyright 2009-2010 Taco Hoekwater <taco@@luatex.org> % @@ -123,6 +123,7 @@ void initialize_commands(void) primitive_luatex("luastartup", assign_int_cmd, int_base + luastartup_id_code, int_base); primitive_luatex("nokerns", assign_int_cmd, int_base + disable_kern_code, int_base); primitive_luatex("noligs", assign_int_cmd, int_base + disable_lig_code, int_base); + primitive_luatex("nospaces", assign_int_cmd, int_base + disable_space_code, int_base); primitive_luatex("catcodetable", assign_int_cmd, int_base + cat_code_table_code, int_base); primitive_luatex("outputbox", assign_int_cmd, int_base + output_box_code, int_base); primitive_luatex("outputmode", assign_int_cmd, int_base + output_mode_code, int_base); @@ -168,6 +169,8 @@ void initialize_commands(void) primitive_tex("begingroup", begin_group_cmd, 0, 0); primitive_tex("char", char_num_cmd, 0, 0); primitive_tex("csname", cs_name_cmd, 0, 0); + primitive_luatex("lastnamedcs", cs_name_cmd, 1, 0); + primitive_luatex("begincsname", cs_name_cmd, 2, 0); primitive_tex("delimiter", delim_num_cmd, 0, 0); primitive_luatex("Udelimiter", delim_num_cmd, 1, 0); primitive_tex("divide", divide_cmd, 0, 0); @@ -184,6 +187,7 @@ void initialize_commands(void) primitive_tex("fontdimen", assign_font_dimen_cmd, 0, 0); primitive_tex("halign", halign_cmd, 0, 0); primitive_tex("hrule", hrule_cmd, 0, 0); + primitive_luatex("nohrule", no_vrule_cmd, 0, 0); primitive_tex("ignorespaces", ignore_spaces_cmd, 0, 0); primitive_tex("insert", insert_cmd, 0, 0); primitive_luatex("leftghost", char_ghost_cmd, 0, 0); @@ -197,8 +201,6 @@ void initialize_commands(void) primitive_luatex("Ustack", math_choice_cmd, 1, 0); primitive_tex("multiply", multiply_cmd, 0, 0); primitive_tex("noalign", no_align_cmd, 0, 0); - primitive_luatex("nohrule", no_vrule_cmd, 0, 0); - primitive_luatex("novrule", no_hrule_cmd, 0, 0); primitive_tex("boundary", boundary_cmd, 0, 0); primitive_tex("noboundary", no_boundary_cmd, 0, 0); primitive_tex("noexpand", no_expand_cmd, 0, 0); @@ -223,11 +225,16 @@ void initialize_commands(void) primitive_luatex("rightghost", char_ghost_cmd, 1, 0); primitive_tex("setbox", set_box_cmd, 0, 0); primitive_tex("the", the_cmd, 0, 0); + primitive_luatex("toksapp", combine_toks_cmd, 0, 0); + primitive_luatex("tokspre", combine_toks_cmd, 1, 0); + primitive_luatex("etoksapp", combine_toks_cmd, 2, 0); + primitive_luatex("etokspre", combine_toks_cmd, 3, 0); primitive_tex("toks", toks_register_cmd, 0, 0); primitive_tex("vadjust", vadjust_cmd, 0, 0); primitive_tex("valign", valign_cmd, 0, 0); primitive_tex("vcenter", vcenter_cmd, 0, 0); primitive_tex("vrule", vrule_cmd, 0, 0); + primitive_luatex("novrule", no_hrule_cmd, 0, 0); primitive_tex("par", par_end_cmd, too_big_char, too_big_char); /* cf.\ |scan_file_name| */ par_loc = cur_val; par_token = cs_token_flag + par_loc; @@ -297,6 +304,7 @@ void initialize_commands(void) primitive_tex("number", convert_cmd, number_code, 0); primitive_tex("romannumeral", convert_cmd, roman_numeral_code, 0); primitive_tex("string", convert_cmd, string_code, 0); + primitive_tex("csstring", convert_cmd, cs_string_code, 0); primitive_tex("meaning", convert_cmd, meaning_code, 0); primitive_etex("eTeXVersion", convert_cmd, etex_code, 0); primitive_tex("fontname", convert_cmd, font_name_code, 0); @@ -408,6 +416,9 @@ void initialize_commands(void) primitive_tex("copy", make_box_cmd, copy_code, 0); primitive_tex("lastbox", make_box_cmd, last_box_code, 0); primitive_tex("vsplit", make_box_cmd, vsplit_code, 0); + primitive_tex("tpack", make_box_cmd, tpack_code, 0); + primitive_tex("vpack", make_box_cmd, vpack_code, 0); + primitive_tex("hpack", make_box_cmd, hpack_code, 0); primitive_tex("vtop", make_box_cmd, vtop_code, 0); primitive_tex("vbox", make_box_cmd, vtop_code + vmode, 0); primitive_tex("hbox", make_box_cmd, vtop_code + hmode, 0); @@ -488,6 +499,7 @@ void initialize_commands(void) primitive_tex("xdef", def_cmd, 3, 0); primitive_tex("let", let_cmd, normal, 0); primitive_tex("futurelet", let_cmd, normal + 1, 0); + primitive_luatex("letcharcode", let_cmd, normal + 2, 0); primitive_tex("chardef", shorthand_def_cmd, char_def_code, 0); primitive_tex("mathchardef", shorthand_def_cmd, math_char_def_code, 0); primitive_luatex("Umathchardef", shorthand_def_cmd, xmath_char_def_code, 0); @@ -637,6 +649,7 @@ void initialize_commands(void) primitive_luatex("preexhyphenchar", hyph_data_cmd, 4, 0); primitive_luatex("postexhyphenchar", hyph_data_cmd, 5, 0); primitive_luatex("hyphenationmin", hyph_data_cmd, 6, 0); + primitive_luatex("hjcode", hyph_data_cmd, 7, 0); primitive_tex("hyphenchar", assign_font_int_cmd, 0, 0); primitive_tex("skewchar", assign_font_int_cmd, 1, 0); primitive_luatex("lpcode", assign_font_int_cmd, lp_code_base, 0); diff --git a/Build/source/texk/web2c/luatexdir/tex/conditional.h b/Build/source/texk/web2c/luatexdir/tex/conditional.h index 13e822a1bf9..b6abe7578d3 100644 --- a/Build/source/texk/web2c/luatexdir/tex/conditional.h +++ b/Build/source/texk/web2c/luatexdir/tex/conditional.h @@ -1,5 +1,5 @@ /* conditional.h - + Copyright 2009 Taco Hoekwater <taco@luatex.org> This file is part of LuaTeX. @@ -15,61 +15,57 @@ 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/>. */ - + with LuaTeX; if not, see <http://www.gnu.org/licenses/>. +*/ #ifndef CONDITIONAL_H # define CONDITIONAL_H - # define unless_code 32 /* amount added for `\.{\\unless}' prefix */ typedef enum { - if_char_code = 0, /* `\.{\\if}' */ - if_cat_code = 1, /* `\.{\\ifcat}' */ - if_int_code = 2, /* `\.{\\ifnum}' */ - if_dim_code = 3, /* `\.{\\ifdim}' */ - if_odd_code = 4, /* `\.{\\ifodd}' */ - if_vmode_code = 5, /* `\.{\\ifvmode}' */ - if_hmode_code = 6, /* `\.{\\ifhmode}' */ - if_mmode_code = 7, /* `\.{\\ifmmode}' */ - if_inner_code = 8, /* `\.{\\ifinner}' */ - if_void_code = 9, /* `\.{\\ifvoid}' */ - if_hbox_code = 10, /* `\.{\\ifhbox}' */ - if_vbox_code = 11, /* `\.{\\ifvbox}' */ - ifx_code = 12, /* `\.{\\ifx}' */ - if_eof_code = 13, /* `\.{\\ifeof}' */ - if_true_code = 14, /* `\.{\\iftrue}' */ - if_false_code = 15, /* `\.{\\iffalse}' */ - if_case_code = 16, /* `\.{\\ifcase}' */ - if_def_code = 17, /* `\.{\\ifdefined}' */ - if_cs_code = 18, /* `\.{\\ifcsname}' */ - if_font_char_code = 19, /* `\.{\\iffontchar}' */ - if_in_csname_code = 20, /* `\.{\\ifincsname}' */ - if_primitive_code = 21, /* `\.{\\ifprimitive}' */ - if_abs_num_code = 22, /* `\.{\\ifabsnum}' */ - if_abs_dim_code = 23, /* `\.{\\ifabsdim}' */ + if_char_code = 0, /* \.{\\if} */ + if_cat_code = 1, /* \.{\\ifcat} */ + if_int_code = 2, /* \.{\\ifnum} */ + if_dim_code = 3, /* \.{\\ifdim} */ + if_odd_code = 4, /* \.{\\ifodd} */ + if_vmode_code = 5, /* \.{\\ifvmode} */ + if_hmode_code = 6, /* \.{\\ifhmode} */ + if_mmode_code = 7, /* \.{\\ifmmode} */ + if_inner_code = 8, /* \.{\\ifinner} */ + if_void_code = 9, /* \.{\\ifvoid} */ + if_hbox_code = 10, /* \.{\\ifhbox} */ + if_vbox_code = 11, /* \.{\\ifvbox} */ + ifx_code = 12, /* \.{\\ifx} */ + if_eof_code = 13, /* \.{\\ifeof} */ + if_true_code = 14, /* \.{\\iftrue} */ + if_false_code = 15, /* \.{\\iffalse} */ + if_case_code = 16, /* \.{\\ifcase} */ + if_def_code = 17, /* \.{\\ifdefined} */ + if_cs_code = 18, /* \.{\\ifcsname} */ + if_font_char_code = 19, /* \.{\\iffontchar} */ + if_in_csname_code = 20, /* \.{\\ifincsname} */ + if_primitive_code = 21, /* \.{\\ifprimitive} */ + if_abs_num_code = 22, /* \.{\\ifabsnum} */ + if_abs_dim_code = 23, /* \.{\\ifabsdim} */ } if_type_codes; - - - # define if_limit_subtype(A) subtype((A)+1) # define if_limit_type(A) type((A)+1) # define if_line_field(A) vlink((A)+1) typedef enum { - if_code = 1, /* code for \.{\\if...} being evaluated */ - fi_code = 2, /* code for \.{\\fi} */ - else_code = 3, /* code for \.{\\else} */ - or_code = 4, /* code for \.{\\or} */ + if_code = 1, /* \.{\\if...} */ + fi_code = 2, /* \.{\\fi} */ + else_code = 3, /* \.{\\else} */ + or_code = 4, /* \.{\\or} */ } else_type_codes; -extern halfword cond_ptr; /* top of the condition stack */ -extern int if_limit; /* upper bound on |fi_or_else| codes */ -extern int cur_if; /* type of conditional being worked on */ -extern int if_line; /* line where that conditional began */ -extern int skip_line; /* skipping began here */ +extern halfword cond_ptr; /* top of the condition stack */ +extern int if_limit; /* upper bound on |fi_or_else| codes */ +extern int cur_if; /* type of conditional being worked on */ +extern int if_line; /* line where that conditional began */ +extern int skip_line; /* skipping began here */ extern void pass_text(void); extern void push_condition_stack(void); diff --git a/Build/source/texk/web2c/luatexdir/tex/conditional.w b/Build/source/texk/web2c/luatexdir/tex/conditional.w index 53967087102..fa4e73b49cb 100644 --- a/Build/source/texk/web2c/luatexdir/tex/conditional.w +++ b/Build/source/texk/web2c/luatexdir/tex/conditional.w @@ -19,7 +19,6 @@ @ @c - #include "ptexlib.h" @ @c @@ -49,14 +48,12 @@ int if_limit; /* upper bound on |fi_or_else| codes */ int cur_if; /* type of conditional being worked on */ int if_line; /* line where that conditional began */ - @ When we skip conditional text, we keep track of the line number where skipping began, for use in error messages. @c int skip_line; /* skipping began here */ - @ Here is a procedure that ignores text until coming to an \.{\\or}, \.{\\else}, or \.{\\fi} at level zero of $\.{\\if}\ldots\.{\\fi}$ nesting. After it has acted, |cur_chr| will indicate the token that @@ -66,14 +63,12 @@ procedure run faster). @c void pass_text(void) { - int l; /* level of $\.{\\if}\ldots\.{\\fi}$ nesting */ - int save_scanner_status; /* |scanner_status| upon entry */ - save_scanner_status = scanner_status; + int l = 0; /* level of $\.{\\if}\ldots\.{\\fi}$ nesting */ + int save_scanner_status = scanner_status; /* |scanner_status| upon entry */ scanner_status = skipping; - l = 0; skip_line = line; while (1) { - get_next(); /* get_token_lua(); */ + get_next(); if (cur_cmd == fi_or_else_cmd) { if (l == 0) break; @@ -88,7 +83,6 @@ void pass_text(void) show_cur_cmd_chr(); } - @ When we begin to process a new \.{\\if}, we set |if_limit:=if_code|; then if\/ \.{\\or} or \.{\\else} or \.{\\fi} occurs before the current \.{\\if} condition has been evaluated, \.{\\relax} will be inserted. @@ -123,18 +117,17 @@ void pop_condition_stack(void) flush_node(p); } - @ Here's a procedure that changes the |if_limit| code corresponding to a given value of |cond_ptr|. @c void change_if_limit(int l, halfword p) { - halfword q; if (p == cond_ptr) { - if_limit = l; /* that's the easy case */ + /* that's the easy case */ + if_limit = l; } else { - q = cond_ptr; + halfword q = cond_ptr; while (1) { if (q == null) confusion("if"); @@ -147,21 +140,21 @@ void change_if_limit(int l, halfword p) } } - @ The conditional \.{\\ifcsname} is equivalent to \.{\\expandafter} \.{\\expandafter} \.{\\ifdefined} \.{\\csname}, except that no new control sequence will be entered into the hash table (once all tokens preceding the mandatory \.{\\endcsname} have been expanded). @c +static halfword last_tested_cs ; + static boolean test_for_cs(void) { - boolean b; /*is the condition true? */ + boolean b = false; /*is the condition true? */ int m, s; /*to be tested against the second operand */ - halfword n, p, q; /*for traversing token lists in \.{\\ifx} tests */ - n = get_avail(); - p = n; /*head of the list of characters */ - b = false; + halfword q; /*for traversing token lists in \.{\\ifx} tests */ + halfword n = get_avail(); + halfword p = n; /*head of the list of characters */ while (1) { get_x_token(); if (cur_cs != 0) @@ -169,6 +162,7 @@ static boolean test_for_cs(void) store_new_token(cur_tok); } if (cur_cmd != end_cs_name_cmd) { + last_tested_cs = null_cs; if (int_par(suppress_ifcsname_error_code)) { do { get_x_token(); @@ -201,41 +195,35 @@ static boolean test_for_cs(void) } else { buffer[m++] = (packed_ASCII_code) (0xF0 + s / 0x40000); buffer[m++] = (packed_ASCII_code) (0x80 + (s % 0x40000) / 0x1000); - buffer[m++] = - (packed_ASCII_code) (0x80 + ((s % 0x40000) % 0x1000) / 0x40); - buffer[m++] = - (packed_ASCII_code) (0x80 + ((s % 0x40000) % 0x1000) % 0x40); + buffer[m++] = (packed_ASCII_code) (0x80 + ((s % 0x40000) % 0x1000) / 0x40); + buffer[m++] = (packed_ASCII_code) (0x80 + ((s % 0x40000) % 0x1000) % 0x40); } p = token_link(p); } if (m > first) { - cur_cs = id_lookup(first, m - first); /*|no_new_control_sequence| is |true| */ + cur_cs = id_lookup(first, m - first); /* |no_new_control_sequence| is |true| */ } else if (m == first) { - cur_cs = null_cs; /*the list is empty */ + cur_cs = null_cs; /* the list is empty */ } b = (eq_type(cur_cs) != undefined_cs_cmd); flush_list(n); + last_cs_name = cur_cs; return b; } - @ An active character will be treated as category 13 following \.{\\if\\noexpand} or following \.{\\ifcat\\noexpand}. @c -#define get_x_token_or_active_char() do { \ - get_x_token(); \ - if (cur_cmd==relax_cmd && cur_chr==no_expand_flag) { \ - if (is_active_cs(cs_text(cur_cs))) { \ - cur_cmd=active_char_cmd; \ - cur_chr=active_cs_value(cs_text(cur_tok-cs_token_flag)); \ - } \ - } \ - } while (0) - - - - +#define get_x_token_or_active_char() do { \ + get_x_token(); \ + if (cur_cmd==relax_cmd && cur_chr==no_expand_flag) { \ + if (is_active_cs(cs_text(cur_cs))) { \ + cur_cmd=active_char_cmd; \ + cur_chr=active_cs_value(cs_text(cur_tok-cs_token_flag)); \ + } \ + } \ +} while (0) @ A condition is started when the |expand| procedure encounters an |if_test| command; in that case |expand| reduces to |conditional|, @@ -245,7 +233,7 @@ which is a recursive procedure. @c void conditional(void) { - boolean b; /*is the condition true? */ + boolean b = false; /*is the condition true? */ int r; /*relation to be evaluated */ int m, n; /*to be tested against the second operand */ halfword p, q; /*for traversing token lists in \.{\\ifx} tests */ @@ -253,245 +241,271 @@ void conditional(void) halfword save_cond_ptr; /*|cond_ptr| corresponding to this conditional */ int this_if; /*type of this conditional */ boolean is_unless; /*was this if preceded by `\.{\\unless}' ? */ - b = false; /*default is false, just in case */ - if (int_par(tracing_ifs_code) > 0) - if (int_par(tracing_commands_code) <= 1) - show_cur_cmd_chr(); + if ((int_par(tracing_ifs_code) > 0) && (int_par(tracing_commands_code) <= 1)) + show_cur_cmd_chr(); push_condition_stack(); save_cond_ptr = cond_ptr; is_unless = (cur_chr >= unless_code); this_if = cur_chr % unless_code; /* Either process \.{\\ifcase} or set |b| to the value of a boolean condition */ switch (this_if) { - case if_char_code: - case if_cat_code: - /* Test if two characters match */ - get_x_token_or_active_char(); - if ((cur_cmd > active_char_cmd) || (cur_chr > biggest_char)) { /*not a character */ - m = relax_cmd; - n = too_big_char; - } else { - m = cur_cmd; - n = cur_chr; - } - get_x_token_or_active_char(); - if ((cur_cmd > active_char_cmd) || (cur_chr > biggest_char)) { - cur_cmd = relax_cmd; - cur_chr = too_big_char; - } - if (this_if == if_char_code) - b = (n == cur_chr); - else - b = (m == cur_cmd); - break; - case if_int_code: - case if_dim_code: - case if_abs_dim_code: - case if_abs_num_code: - /* Test relation between integers or dimensions */ - /* Here we use the fact that |"<"|, |"="|, and |">"| are consecutive ASCII - codes. */ - if (this_if == if_int_code || this_if == if_abs_num_code) - scan_int(); - else - scan_normal_dimen(); - n = cur_val; - if (n < 0) - if (this_if == if_abs_dim_code || this_if == if_abs_num_code) + case if_char_code: + case if_cat_code: + /* Test if two characters match */ + get_x_token_or_active_char(); + if ((cur_cmd > active_char_cmd) || (cur_chr > biggest_char)) { + /*not a character */ + m = relax_cmd; + n = too_big_char; + } else { + m = cur_cmd; + n = cur_chr; + } + get_x_token_or_active_char(); + if ((cur_cmd > active_char_cmd) || (cur_chr > biggest_char)) { + cur_cmd = relax_cmd; + cur_chr = too_big_char; + } + if (this_if == if_char_code) + b = (n == cur_chr); + else + b = (m == cur_cmd); + break; + case if_int_code: + case if_dim_code: + case if_abs_dim_code: + case if_abs_num_code: + /* Test relation between integers or dimensions */ + /* Here we use the fact that |"<"|, |"="|, and |">"| are consecutive ASCII codes. */ + if (this_if == if_int_code || this_if == if_abs_num_code) + scan_int(); + else + scan_normal_dimen(); + n = cur_val; + if ((n < 0) && (this_if == if_abs_dim_code || this_if == if_abs_num_code)) negate(n); - - /* Get the next non-blank non-call... */ - do { - get_x_token(); - } while (cur_cmd == spacer_cmd); - - if ((cur_tok >= other_token + '<') && (cur_tok <= other_token + '>')) { + /* Get the next non-blank non-call... */ + do { + get_x_token(); + } while (cur_cmd == spacer_cmd); + /* + if ((cur_tok >= other_token + '<') && (cur_tok <= other_token + '>')) { + r = cur_tok - other_token; + } else { + */ r = cur_tok - other_token; - } else { - print_err("Missing = inserted for "); - print_cmd_chr(if_test_cmd, this_if); - help1("I was expecting to see `<', `=', or `>'. Didn't."); - back_error(); - r = '='; - } - if (this_if == if_int_code || this_if == if_abs_num_code) - scan_int(); - else - scan_normal_dimen(); - - if (cur_val < 0) - if (this_if == if_abs_dim_code || this_if == if_abs_num_code) + if ((r < '<') || (r > '>')) { + print_err("Missing = inserted for "); + print_cmd_chr(if_test_cmd, this_if); + help1("I was expecting to see `<', `=', or `>'. Didn't."); + back_error(); + r = '='; + } + if (this_if == if_int_code || this_if == if_abs_num_code) + scan_int(); + else + scan_normal_dimen(); + if ((cur_val < 0) && (this_if == if_abs_dim_code || this_if == if_abs_num_code)) negate(cur_val); - - switch (r) { - case '<': - b = (n < cur_val); + switch (r) { + case '<': + b = (n < cur_val); + break; + case '=': + b = (n == cur_val); + break; + case '>': + b = (n > cur_val); + break; + default: + /* can't happen */ + b = false; + break; + } + break; + case if_odd_code: + /* Test if an integer is odd */ + scan_int(); + b = odd(cur_val); break; - case '=': - b = (n == cur_val); + case if_vmode_code: + b = (abs(cur_list.mode_field) == vmode); break; - case '>': - b = (n > cur_val); + case if_hmode_code: + b = (abs(cur_list.mode_field) == hmode); break; - default: - b = false; - break; /*can't happen */ - } - break; - case if_odd_code: - /* Test if an integer is odd */ - scan_int(); - b = odd(cur_val); - break; - case if_vmode_code: - b = (abs(cur_list.mode_field) == vmode); - break; - case if_hmode_code: - b = (abs(cur_list.mode_field) == hmode); - break; - case if_mmode_code: - b = (abs(cur_list.mode_field) == mmode); - break; - case if_inner_code: - b = (cur_list.mode_field < 0); - break; - case if_void_code: - case if_hbox_code: - case if_vbox_code: - /* Test box register status */ - scan_register_num(); - p = box(cur_val); - if (this_if == if_void_code) + case if_mmode_code: + b = (abs(cur_list.mode_field) == mmode); + break; + case if_inner_code: + b = (cur_list.mode_field < 0); + break; + /* + case if_void_code: + case if_hbox_code: + case if_vbox_code: + scan_register_num(); + p = box(cur_val); + if (this_if == if_void_code) + b = (p == null); + else if (p == null) + b = false; + else if (this_if == if_hbox_code) + b = (type(p) == hlist_node); + else + b = (type(p) == vlist_node); + break; + */ + case if_void_code: + scan_register_num(); + p = box(cur_val); b = (p == null); - else if (p == null) - b = false; - else if (this_if == if_hbox_code) - b = (type(p) == hlist_node); - else - b = (type(p) == vlist_node); - break; - case ifx_code: - /* Test if two tokens match */ - /* Note that `\.{\\ifx}' will declare two macros different if one is \\{long} - or \\{outer} and the other isn't, even though the texts of the macros are - the same. - - We need to reset |scanner_status|, since \.{\\outer} control sequences - are allowed, but we might be scanning a macro definition or preamble. - */ - save_scanner_status = scanner_status; - scanner_status = normal; - get_next(); /* get_token_lua(); */ - n = cur_cs; - p = cur_cmd; - q = cur_chr; - get_next(); /* get_token_lua(); */ - if (cur_cmd != p) { - b = false; - } else if (cur_cmd < call_cmd) { - b = (cur_chr == q); - } else { - /* Test if two macro texts match */ - /* Note also that `\.{\\ifx}' decides that macros \.{\\a} and \.{\\b} are - different in examples like this: - $$\vbox{\halign{\.{#}\hfil&\qquad\.{#}\hfil\cr - {}\\def\\a\{\\c\}& - {}\\def\\c\{\}\cr - {}\\def\\b\{\\d\}& - {}\\def\\d\{\}\cr}}$$ */ - p = token_link(cur_chr); - q = token_link(equiv(n)); /*omit reference counts */ - if (p == q) { - b = true; + break; + case if_hbox_code: + scan_register_num(); + p = box(cur_val); + b = (p != null) && (type(p) == hlist_node); + break; + case if_vbox_code: + scan_register_num(); + p = box(cur_val); + b = (p != null) && (type(p) == vlist_node); + break; + case ifx_code: + /* + Test if two tokens match + + Note that `\.{\\ifx}' will declare two macros different if one is \\{long} + or \\{outer} and the other isn't, even though the texts of the macros are + the same. + + We need to reset |scanner_status|, since \.{\\outer} control sequences + are allowed, but we might be scanning a macro definition or preamble. + */ + save_scanner_status = scanner_status; + scanner_status = normal; + get_next(); + n = cur_cs; + p = cur_cmd; + q = cur_chr; + get_next(); + if (cur_cmd != p) { + b = false; + } else if (cur_cmd < call_cmd) { + b = (cur_chr == q); } else { - while ((p != null) && (q != null)) { - if (token_info(p) != token_info(q)) { - p = null; - } else { - p = token_link(p); - q = token_link(q); + /* + Test if two macro texts match + + Note also that `\.{\\ifx}' decides that macros \.{\\a} and \.{\\b} are + different in examples like this: + + $$\vbox{\halign{\.{#}\hfil&\qquad\.{#}\hfil\cr + {}\\def\\a\{\\c\}& + {}\\def\\c\{\}\cr + {}\\def\\b\{\\d\}& + {}\\def\\d\{\}\cr}}$$ + */ + p = token_link(cur_chr); + /*omit reference counts */ + q = token_link(equiv(n)); + if (p == q) { + b = true; + } else { + while ((p != null) && (q != null)) { + if (token_info(p) != token_info(q)) { + p = null; + break; + } else { + p = token_link(p); + q = token_link(q); + } } + b = ((p == null) && (q == null)); } - b = ((p == null) && (q == null)); } - } - scanner_status = save_scanner_status; - break; - case if_eof_code: - scan_four_bit_int(); - b = (read_open[cur_val] == closed); - break; - case if_true_code: - b = true; - break; - case if_false_code: - b = false; - break; - case if_case_code: - /* Select the appropriate case - and |return| or |goto common_ending| */ - scan_int(); - n = cur_val; /*|n| is the number of cases to pass */ - if (int_par(tracing_commands_code) > 1) { - begin_diagnostic(); - tprint("{case "); - print_int(n); - print_char('}'); - end_diagnostic(false); - } - while (n != 0) { - pass_text(); - if (cond_ptr == save_cond_ptr) { - if (cur_chr == or_code) - decr(n); - else - goto COMMON_ENDING; - } else if (cur_chr == fi_code) { - pop_condition_stack(); + scanner_status = save_scanner_status; + break; + case if_eof_code: + scan_four_bit_int(); + b = (read_open[cur_val] == closed); + break; + case if_true_code: + b = true; + break; + case if_false_code: + b = false; + break; + case if_case_code: + /* Select the appropriate case and |return| or |goto common_ending| */ + scan_int(); + /* |n| is the number of cases to pass */ + n = cur_val; + if (int_par(tracing_commands_code) > 1) { + begin_diagnostic(); + tprint("{case "); + print_int(n); + print_char('}'); + end_diagnostic(false); } - } - change_if_limit(or_code, save_cond_ptr); - return; /*wait for \.{\\or}, \.{\\else}, or \.{\\fi} */ - break; - case if_primitive_code: - save_scanner_status = scanner_status; - scanner_status = normal; - get_next(); /* get_token_lua(); */ - scanner_status = save_scanner_status; - m = prim_lookup(cs_text(cur_cs)); - b = ((cur_cmd != undefined_cs_cmd) && - (m != undefined_primitive) && - (cur_cmd == get_prim_eq_type(m)) && - (cur_chr == get_prim_equiv(m))); - break; - case if_def_code: - /* The conditional \.{\\ifdefined} tests if a control sequence is defined. */ - /* We need to reset |scanner_status|, since \.{\\outer} control sequences - are allowed, but we might be scanning a macro definition or preamble. */ - save_scanner_status = scanner_status; - scanner_status = normal; - get_next(); /* get_token_lua(); */ - b = (cur_cmd != undefined_cs_cmd); - scanner_status = save_scanner_status; - break; - case if_cs_code: - b = test_for_cs(); - break; - case if_in_csname_code: - b = is_in_csname; - break; - case if_font_char_code: - /* The conditional \.{\\iffontchar} tests the existence of a character in - a font. */ - scan_font_ident(); - n = cur_val; - scan_char_num(); - b = char_exists(n, cur_val); - break; - default: /* there are no other cases, but for -Wall: */ - b = false; + while (n != 0) { + pass_text(); + if (cond_ptr == save_cond_ptr) { + if (cur_chr == or_code) + decr(n); + else + goto COMMON_ENDING; + } else if (cur_chr == fi_code) { + pop_condition_stack(); + } + } + change_if_limit(or_code, save_cond_ptr); + /*wait for \.{\\or}, \.{\\else}, or \.{\\fi} */ + return; + break; + case if_primitive_code: + save_scanner_status = scanner_status; + scanner_status = normal; + get_next(); + scanner_status = save_scanner_status; + m = prim_lookup(cs_text(cur_cs)); + b = ((cur_cmd != undefined_cs_cmd) && + (m != undefined_primitive) && + (cur_cmd == get_prim_eq_type(m)) && + (cur_chr == get_prim_equiv(m))); + break; + case if_def_code: + /* + The conditional \.{\\ifdefined} tests if a control sequence is defined. + We need to reset |scanner_status|, since \.{\\outer} control sequences + are allowed, but we might be scanning a macro definition or preamble. + */ + save_scanner_status = scanner_status; + scanner_status = normal; + get_next(); + b = (cur_cmd != undefined_cs_cmd); + scanner_status = save_scanner_status; + break; + case if_cs_code: + b = test_for_cs(); + break; + case if_in_csname_code: + b = is_in_csname; + break; + case if_font_char_code: + /* + The conditional \.{\\iffontchar} tests the existence of a character in + a font. + */ + scan_font_ident(); + n = cur_val; + scan_char_num(); + b = char_exists(n, cur_val); + break; + default: + /* there are no other cases, but for -Wall: */ + b = false; } - if (is_unless) b = !b; if (int_par(tracing_commands_code) > 1) { @@ -505,14 +519,16 @@ void conditional(void) } if (b) { change_if_limit(else_code, save_cond_ptr); - return; /*wait for \.{\\else} or \.{\\fi} */ + /*wait for \.{\\else} or \.{\\fi} */ + return; } - /* Skip to \.{\\else} or \.{\\fi}, then |goto common_ending| */ /* - In a construction like `\.{\\if\\iftrue abc\\else d\\fi}', the first - \.{\\else} that we come to after learning that the \.{\\if} is false is - not the \.{\\else} we're looking for. Hence the following curious - logic is needed. + Skip to \.{\\else} or \.{\\fi}, then |goto common_ending| + + In a construction like `\.{\\if\\iftrue abc\\else d\\fi}', the first + \.{\\else} that we come to after learning that the \.{\\if} is false is + not the \.{\\else} we're looking for. Hence the following curious + logic is needed. */ while (1) { pass_text(); @@ -527,8 +543,10 @@ void conditional(void) } } COMMON_ENDING: - if (cur_chr == fi_code) + if (cur_chr == fi_code) { pop_condition_stack(); - else - if_limit = fi_code; /*wait for \.{\\fi} */ + } else { + /*wait for \.{\\fi} */ + if_limit = fi_code; + } } diff --git a/Build/source/texk/web2c/luatexdir/tex/directions.h b/Build/source/texk/web2c/luatexdir/tex/directions.h index 34a89cc29a2..e4cea9014dd 100644 --- a/Build/source/texk/web2c/luatexdir/tex/directions.h +++ b/Build/source/texk/web2c/luatexdir/tex/directions.h @@ -31,7 +31,7 @@ */ # define dir_TLT 0 /* maybe use this one as unset value */ -# define dir_TRT 1 /* or swhould we avoid that one because it's a signal too */ +# define dir_TRT 1 /* or should we avoid that one because it's a signal too */ # define dir_LTL 2 # define dir_RTT 3 @@ -56,14 +56,52 @@ extern int dir_swap; # define is_rotated(a) (a == dir_RTT) +/* + + # define textdir_parallel(a,b) ( \ + ((a == dir_TLT || a == dir_TRT) && (b == dir_TLT || b == dir_TRT)) || \ + ((a == dir_LTL || a == dir_RTT) && (b == dir_LTL || b == dir_RTT)) \ + ) + + # define pardir_parallel(a,b) ( \ + ((a == dir_TLT || a == dir_TRT) && (b == dir_TLT || b == dir_TRT)) || \ + ((a == dir_LTL || a == dir_RTT) && (b == dir_LTL || b == dir_RTT)) \ + ) + + # define pardir_eq(a,b) ( \ + ((a == dir_TLT || a == dir_TRT) && (b == dir_TLT || b == dir_TRT)) || \ + (a == dir_LTL && b == dir_LTL) || \ + (a == dir_RTT && b == dir_RTT) \ + ) + + # define textdir_eq(a,b) ( \ + (a == dir_TLT && b == dir_TLT) || \ + (a == dir_TRT && b == dir_TRT) || \ + (a == dir_LTL && (b == dir_LTL || b == dir_RTT)) || \ + (a == dir_RTT && (b == dir_LTL || b == dir_RTT)) + + # define partextdir_eq(a,b) ( \ + ((a == dir_TLT || a == dir_TRT) && (b == dir_LTL || b == dir_RTT)) || \ + (a == dir_LTL && b == dir_TLT) || \ + (a == dir_RTT && b == dir_TRT) \ + ) + +*/ + +/* # define dir_TLT_or_TRT(a) (a == dir_TLT || a == dir_TRT) */ +/* # define dir_LTL_or_RTT(a) (a == dir_LTL || a == dir_RTT) */ + +# define dir_TLT_or_TRT(a) (a < 2) +# define dir_LTL_or_RTT(a) (a > 1) + # define textdir_parallel(a,b) ( \ - ((a == dir_TLT || a == dir_TRT) && (b == dir_TLT || b == dir_TRT)) || \ - ((a == dir_LTL || a == dir_RTT) && (b == dir_LTL || b == dir_RTT)) \ + (dir_TLT_or_TRT(a) && dir_TLT_or_TRT(b)) || \ + (dir_LTL_or_RTT(a) && dir_LTL_or_RTT(b)) \ ) # define pardir_parallel(a,b) ( \ - ((a == dir_TLT || a == dir_TRT) && (b == dir_TLT || b == dir_TRT)) || \ - ((a == dir_LTL || a == dir_RTT) && (b == dir_LTL || b == dir_RTT)) \ + (dir_TLT_or_TRT(a) && dir_TLT_or_TRT(b)) || \ + (dir_LTL_or_RTT(a) && dir_LTL_or_RTT(b)) \ ) # define pardir_opposite(a,b) ( \ @@ -79,7 +117,7 @@ extern int dir_swap; # define glyphdir_opposite(a,b) 0 # define pardir_eq(a,b) ( \ - ((a == dir_TLT || a == dir_TRT) && (b == dir_TLT || b == dir_TRT)) || \ + (dir_TLT_or_TRT(a) && dir_TLT_or_TRT(b)) || \ (a == dir_LTL && b == dir_LTL) || \ (a == dir_RTT && b == dir_RTT) \ ) @@ -87,8 +125,8 @@ extern int dir_swap; # define textdir_eq(a,b) ( \ (a == dir_TLT && b == dir_TLT) || \ (a == dir_TRT && b == dir_TRT) || \ - (a == dir_LTL && (b == dir_LTL || b == dir_RTT)) || \ - (a == dir_RTT && (b == dir_LTL || b == dir_RTT) \ + (a == dir_LTL && dir_LTL_or_RTT(b)) || \ + (a == dir_RTT && dir_LTL_or_RTT(b)) \ ) # define glyphdir_eq(a,b) ( \ @@ -97,7 +135,7 @@ extern int dir_swap; ) # define partextdir_eq(a,b) ( \ - ((a == dir_TLT || a == dir_TRT)&&(b == dir_LTL || b == dir_RTT)) || \ + (dir_TLT_or_TRT(a) && dir_LTL_or_RTT(b)) || \ (a == dir_LTL && b == dir_TLT) || \ (a == dir_RTT && b == dir_TRT) \ ) @@ -106,21 +144,21 @@ extern int dir_swap; # define textdir_is_L(a) (a == dir_TLT) -# define push_dir(a,b) { \ +# define push_dir(p,a) { \ halfword dir_tmp=new_dir((a)); \ - vlink(dir_tmp)=b; \ - b=dir_tmp; \ + vlink(dir_tmp)=p; \ + p=dir_tmp; \ } -# define push_dir_node(a,b) { \ +# define push_dir_node(p,a) { \ halfword dir_tmp=copy_node((a)); \ - vlink(dir_tmp)=b; \ - b=dir_tmp; \ + vlink(dir_tmp)=p; \ + p=dir_tmp; \ } -# define pop_dir_node(b) { \ - halfword dir_tmp=b; \ - b=vlink(dir_tmp); \ +# define pop_dir_node(p) { \ + halfword dir_tmp=p; \ + p=vlink(dir_tmp); \ flush_node(dir_tmp); \ } diff --git a/Build/source/texk/web2c/luatexdir/tex/directions.w b/Build/source/texk/web2c/luatexdir/tex/directions.w index addde937df7..b010eb4a9cc 100644 --- a/Build/source/texk/web2c/luatexdir/tex/directions.w +++ b/Build/source/texk/web2c/luatexdir/tex/directions.w @@ -19,7 +19,6 @@ @ @c - #include "ptexlib.h" @ @c @@ -59,8 +58,7 @@ void scan_direction(void) @c halfword do_push_dir_node(halfword p, halfword a) { - halfword n; - n = copy_node(a); + halfword n = copy_node(a); vlink(n) = p; return n; } @@ -86,8 +84,7 @@ void initialize_directions(void) @ @c halfword new_dir(int s) { - halfword p; /* the new node */ - p = new_node(dir_node, 0); + halfword p = new_node(dir_node, 0); dir_dir(p) = s; dir_dvi_ptr(p) = -1; dir_level(p) = cur_level; @@ -150,10 +147,10 @@ scaled pack_width(int curdir, int pdir, halfword p, boolean isglyph) if (textdir_parallel(curdir, pdir) == textglyphdir_orthogonal(pdir)) { wd = glyph_width(p); if (ex_glyph(p) != 0) { - //wd = round_xn_over_d(wd, 1000 + ex_glyph(p)/1000, 1000); - wd = ext_xn_over_d(wd, 1000000+ex_glyph(p), 1000000); + /* wd = round_xn_over_d(wd, 1000 + ex_glyph(p)/1000, 1000); */ + wd = ext_xn_over_d(wd, 1000000+ex_glyph(p), 1000000); - } + } } else { wd = glyph_depth(p) + glyph_height(p); } @@ -178,22 +175,20 @@ scaled_whd pack_width_height_depth(int curdir, int pdir, halfword p, whd.ht = whd.dp = (glyph_height(p) + glyph_depth(p)) / 2; else whd.ht = whd.dp = glyph_width(p) / 2; + } else if (is_rotated(pdir)) { + if (textdir_parallel(curdir, pdir)) + whd.ht = whd.dp = (glyph_height(p) + glyph_depth(p)) / 2; + else + whd.ht = glyph_width(p); } else { - if (is_rotated(pdir)) { - if (textdir_parallel(curdir, pdir)) - whd.ht = whd.dp = (glyph_height(p) + glyph_depth(p)) / 2; - else - whd.ht = glyph_width(p); - } else { - if (glyphdir_eq(curdir, pdir)) { - whd.ht = glyph_height(p); - whd.dp = glyph_depth(p); - } else if (glyphdir_opposite(curdir, pdir)) { - whd.ht = glyph_depth(p); - whd.dp = glyph_height(p); - } else - whd.ht = glyph_width(p); - } + if (glyphdir_eq(curdir, pdir)) { + whd.ht = glyph_height(p); + whd.dp = glyph_depth(p); + } else if (glyphdir_opposite(curdir, pdir)) { + whd.ht = glyph_depth(p); + whd.dp = glyph_height(p); + } else + whd.ht = glyph_width(p); } } else { if (is_rotated(curdir)) { @@ -201,16 +196,14 @@ scaled_whd pack_width_height_depth(int curdir, int pdir, halfword p, whd.ht = whd.dp = (height(p) + depth(p)) / 2; else whd.ht = whd.dp = width(p) / 2; - } else { - if (pardir_eq(curdir, pdir)) { - whd.ht = height(p); - whd.dp = depth(p); - } else if (pardir_opposite(curdir, pdir)) { - whd.ht = depth(p); - whd.dp = height(p); - } else - whd.ht = width(p); - } + } else if (pardir_eq(curdir, pdir)) { + whd.ht = height(p); + whd.dp = depth(p); + } else if (pardir_opposite(curdir, pdir)) { + whd.ht = depth(p); + whd.dp = height(p); + } else + whd.ht = width(p); } return whd; } diff --git a/Build/source/texk/web2c/luatexdir/tex/dumpdata.w b/Build/source/texk/web2c/luatexdir/tex/dumpdata.w index 727951b9f32..ea882a74040 100644 --- a/Build/source/texk/web2c/luatexdir/tex/dumpdata.w +++ b/Build/source/texk/web2c/luatexdir/tex/dumpdata.w @@ -26,8 +26,9 @@ #define prev_depth cur_list.prev_depth_field /* 907 = sum of the values of the bytes of "don knuth" */ -/* The next FORMAT_ID will be 907+7 */ -#define FORMAT_ID (907+6) +/* The next FORMAT_ID will be 907+10 */ + +#define FORMAT_ID (907+10) #if ((FORMAT_ID>=0) && (FORMAT_ID<=256)) #error Wrong value for FORMAT_ID. #endif @@ -47,8 +48,8 @@ after the |banner| line when \TeX\ is ready to start. For \.{INITEX} this string says simply `\.{(INITEX)}'; for other versions of \TeX\ it says, for example, `\.{(preloaded format=plain 1982.11.19)}', showing the year, month, and day that the format file was created. We have |format_ident=0| -before \TeX's tables are loaded. |FORMAT_ID| is a new field of type int -suitable for the identification of a format: values between 0 and 256 +before \TeX's tables are loaded. |FORMAT_ID| is a new field of type int +suitable for the identification of a format: values between 0 and 256 (included) can not be used because in the previous format they are used for the length of the name of the engine. @c @@ -81,7 +82,7 @@ void store_fmt_file(void) succumb(); } - /* Create the |format_ident|, open the format file, and inform the user + /* Create the |format_ident|, open the format file, and inform the user that dumping has begun */ callback_id = callback_defined(pre_dump_callback); if (callback_id > 0) { @@ -121,7 +122,7 @@ void store_fmt_file(void) dump/undump macros. */ dump_int(0x57325458); /* Web2C \TeX's magic constant: "W2TX" */ - dump_int(FORMAT_ID); + dump_int(FORMAT_ID); /* Align engine to 4 bytes with one or more trailing NUL */ x = (int) strlen(engine_name); @@ -150,7 +151,7 @@ void store_fmt_file(void) /* Dump the dynamic memory */ /* By sorting the list of available spaces in the variable-size portion of |mem|, we are usually able to get by without having to dump very much - of the dynamic memory. + of the dynamic memory. We recompute |var_used| and |dyn_used|, so that \.{INITEX} dumps valid information even when it has not been gathering statistics. @@ -301,9 +302,6 @@ void store_fmt_file(void) /* Dump the hyphenation tables */ dump_language_data(); - /* Dump pdftex data */ - dump_pdftex_data(static_pdf); - /* Dump a couple more things and the closing check word */ dump_int(interaction); dump_int(format_ident); @@ -387,7 +385,7 @@ boolean load_fmt_file(const char *fmtname) format_debug("engine name size", x); if ((x < 0) || (x > 256)) goto BAD_FMT; /* corrupted format file */ - + format_engine = xmalloc((unsigned) x); undump_things(format_engine[0], x); format_engine[x - 1] = 0; /* force string termination, just in case */ @@ -510,9 +508,6 @@ boolean load_fmt_file(const char *fmtname) /* Undump the hyphenation tables */ undump_language_data(); - /* Undump pdftex data */ - undump_pdftex_data(static_pdf); - /* Undump a couple more things and the closing check word */ undump(batch_mode, error_stop_mode, interaction); if (interactionoption != unspecified_mode) diff --git a/Build/source/texk/web2c/luatexdir/tex/equivalents.h b/Build/source/texk/web2c/luatexdir/tex/equivalents.h index 8a7debe8345..9f604ab8be6 100644 --- a/Build/source/texk/web2c/luatexdir/tex/equivalents.h +++ b/Build/source/texk/web2c/luatexdir/tex/equivalents.h @@ -15,104 +15,97 @@ 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/>. */ - + with LuaTeX; if not, see <http://www.gnu.org/licenses/>. +*/ #ifndef EQUIVALENTS_H # define EQUIVALENTS_H /* -Like the preceding parameters, the following quantities can be changed -at compile time to extend or reduce \TeX's capacity. But if they are changed, -it is necessary to rerun the initialization program \.{INITEX} -@.INITEX@> -to generate new tables for the production \TeX\ program. -One can't simply make helter-skelter changes to the following constants, -since certain rather complex initialization -numbers are computed from them. They are defined here using -\.{WEB} macros, instead of being put into \PASCAL's |const| list, in order to -emphasize this distinction. + +Like the preceding parameters, the following quantities can be changed at compile +time to extend or reduce \TeX's capacity. But if they are changed, it is +necessary to rerun the initialization program \.{INITEX} @.INITEX@> to generate +new tables for the production \TeX\ program. One can't simply make helter-skelter +changes to the following constants, since certain rather complex initialization +numbers are computed from them. They are defined here using \.{WEB} macros, +instead of being put into \PASCAL's |const| list, in order to emphasize this +distinction. + */ -# define font_base 0 /* smallest internal font number; must not be less than |min_quarterword| */ -# define biggest_reg 65535 /* the largest allowed register number; must be |< max_quarterword| */ -# define number_regs 65536 /* |biggest_reg+1| */ -# define number_attrs 65536 /* total numbeer of attributes */ -# define biggest_char 1114111 /* the largest allowed character number; must be |< max_halfword| */ -# define too_big_char 1114112 /* |biggest_char+1| */ -# define special_char 1114113 /* |biggest_char+2| */ -# define number_chars 1114112 /* |biggest_char+1| */ +# define font_base 0 /* smallest internal font number; must not be less than |min_quarterword| */ +# define biggest_reg 65535 /* the largest allowed register number; must be |< max_quarterword| */ +# define number_regs 65536 /* |biggest_reg+1| */ +# define number_attrs 65536 /* total numbeer of attributes */ +# define biggest_char 1114111 /* the largest allowed character number; must be |< max_halfword| */ +# define too_big_char 1114112 /* |biggest_char+1| */ +# define special_char 1114113 /* |biggest_char+2| */ +# define number_chars 1114112 /* |biggest_char+1| */ # define number_fonts (5535-font_base+1) -# define biggest_lang 32767 -# define too_big_lang 32768 -# define text_size 0 /* size code for the largest size in a family */ -# define script_size 1 /* size code for the medium size in a family */ -# define script_script_size 2 /* size code for the smallest size in a family */ +# define biggest_lang 32767 +# define too_big_lang 32768 +# define text_size 0 /* size code for the largest size in a family */ +# define script_size 1 /* size code for the medium size in a family */ +# define script_script_size 2 /* size code for the smallest size in a family */ /* + Each entry in |eqtb| is a |memory_word|. Most of these words are of type |two_halves|, and subdivided into three fields: -\yskip\hangg 1) The |eq_level| (a quarterword) is the level of grouping at -which this equivalent was defined. If the level is |level_zero|, the -equivalent has never been defined; |level_one| refers to the outer level -(outside of all groups), and this level is also used for global -definitions that never go away. Higher levels are for equivalents that -will disappear at the end of their group. @^global definitions@> - -\yskip\hangg 2) The |eq_type| (another quarterword) specifies what kind of -entry this is. There are many types, since each \TeX\ primitive like -\.{\\hbox}, \.{\\def}, etc., has its own special code. The list of -command codes above includes all possible settings of the |eq_type| field. - -\yskip\hangg 3) The |equiv| (a halfword) is the current equivalent value. -This may be a font number, a pointer into |mem|, or a variety of other -things. -*/ +\yskip\hangg 1) The |eq_level| (a quarterword) is the level of grouping at which +this equivalent was defined. If the level is |level_zero|, the equivalent has +never been defined; |level_one| refers to the outer level (outside of all +groups), and this level is also used for global definitions that never go away. +Higher levels are for equivalents that will disappear at the end of their group. +@^global definitions@> + +\yskip\hangg 2) The |eq_type| (another quarterword) specifies what kind of entry +this is. There are many types, since each \TeX\ primitive like \.{\\hbox}, +\.{\\def}, etc., has its own special code. The list of command codes above +includes all possible settings of the |eq_type| field. + +\yskip\hangg 3) The |equiv| (a halfword) is the current equivalent value. This +may be a font number, a pointer into |mem|, or a variety of other things. + +Many locations in |eqtb| have symbolic names. The purpose of the next paragraphs +is to define these names, and to set up the initial values of the equivalents. + +In the first region we have a single entry for the `null csname' of length zero. +In luatex, the active characters and and single-letter control sequence names are +part of the next region. + +Then comes region~2, which corresponds to the hash table that we will define +later. The maximum address in this region is used for a dummy control sequence +that is perpetually undefined. There also are several locations for control +sequences that are perpetually defined (since they are used in error recovery). + +@ Region 3 of |eqtb| contains the |number_regs| \.{\\skip} registers, as well as +the glue parameters defined here. It is important that the ``muskip'' parameters +have larger numbers than the others. + +@ Region 4 of |eqtb| contains the local quantities defined here. The bulk of this +region is taken up by five tables that are indexed by eight-bit characters; these +tables are important to both the syntactic and semantic portions of \TeX. There +are also a bunch of special things like font and token parameters, as well as the +tables of \.{\\toks} and \.{\\box} registers. + +@ Region 5 of |eqtb| contains the integer parameters and registers defined here, +as well as the |del_code| table. The latter table differs from the +|cat_code..math_code| tables that precede it, since delimiter codes are fullword +integers while the other kinds of codes occupy at most a halfword. This is what +makes region~5 different from region~4. We will store the |eq_level| information +in an auxiliary array of quarterwords that will be defined later. + +@ The integer parameters should really be initialized by a macro package; the +following initialization does the minimum to keep \TeX\ from complete failure. -/* -Many locations in |eqtb| have symbolic names. The purpose of the next -paragraphs is to define these names, and to set up the initial values of the -equivalents. - -In the first region we have a single entry for the `null csname' of -length zero. In luatex, the active characters and and single-letter -control sequence names are part of the next region. - -Then comes region~2, which corresponds to the hash table that we will -define later. The maximum address in this region is used for a dummy -control sequence that is perpetually undefined. There also are several -locations for control sequences that are perpetually defined -(since they are used in error recovery). -*/ - -/* -@ Region 3 of |eqtb| contains the |number_regs| \.{\\skip} registers, as well as the -glue parameters defined here. It is important that the ``muskip'' -parameters have larger numbers than the others. - -@ Region 4 of |eqtb| contains the local quantities defined here. The -bulk of this region is taken up by five tables that are indexed by eight-bit -characters; these tables are important to both the syntactic and semantic -portions of \TeX. There are also a bunch of special things like font and -token parameters, as well as the tables of \.{\\toks} and \.{\\box} -registers. - -@ Region 5 of |eqtb| contains the integer parameters and registers defined -here, as well as the |del_code| table. The latter table differs from the -|cat_code..math_code| tables that precede it, since delimiter codes are -fullword integers while the other kinds of codes occupy at most a -halfword. This is what makes region~5 different from region~4. We will -store the |eq_level| information in an auxiliary array of quarterwords -that will be defined later. - -@ The integer parameters should really be initialized by a macro package; -the following initialization does the minimum to keep \TeX\ from -complete failure. @^null delimiter@> -@ The final region of |eqtb| contains the dimension parameters defined -here, and the |number_regs| \.{\\dimen} registers. +@ The final region of |eqtb| contains the dimension parameters defined here, and +the |number_regs| \.{\\dimen} registers. + */ # define null_cs 1 /* equivalent of \.{\\csname\\endcsname} */ @@ -258,45 +251,46 @@ here, and the |number_regs| \.{\\dimen} registers. # define luastartup_id_code 60 # define disable_lig_code 61 # define disable_kern_code 62 -# define cat_code_table_code 63 -# define output_box_code 64 -# define cur_lang_code 65 /* current language id */ -# define ex_hyphen_char_code 66 -# define hyphenation_min_code 67 /* minimum word length */ -# define adjust_spacing_code 68 /* level of spacing adjusting */ -# define protrude_chars_code 69 /* protrude chars at left/right edge of paragraphs */ -# define output_mode_code 70 /* switch on PDF output if positive */ -# define draft_mode_code 71 -# define tracing_fonts_code 72 -# define tracing_assigns_code 73 /* show assignments */ -# define tracing_groups_code 74 /* show save/restore groups */ -# define tracing_ifs_code 75 /* show conditionals */ -# define tracing_scan_tokens_code 76 /* show pseudo file open and close */ -# define tracing_nesting_code 77 /* show incomplete groups and ifs within files */ -# define pre_display_direction_code 78 /* text direction preceding a display */ -# define last_line_fit_code 79 /* adjustment for last line of paragraph */ -# define saving_vdiscards_code 80 /* save items discarded from vlists */ -# define saving_hyph_codes_code 81 /* save hyphenation codes for languages */ -# define suppress_fontnotfound_error_code 82 /* suppress errors for missing fonts */ -# define suppress_long_error_code 83 /* suppress errors for missing fonts */ -# define suppress_ifcsname_error_code 84 /* suppress errors for failed \.{\\ifcsname} */ -# define suppress_outer_error_code 85 /* suppress errors for \.{\\outer} */ -# define suppress_mathpar_error_code 86 /* suppress errors for \.{\\par}} in math */ -# define math_eqno_gap_step_code 87 /* factor/1000 used for distance between eq and eqno */ -# define math_display_skip_mode_code 88 -# define math_scripts_mode_code 89 -# define synctex_code 90 /* is synctex file generation enabled ? */ - -# define math_no_italic_compensation_code 91 /* just for tracing, can change */ -# define math_no_char_italic_code 92 /* just for tracing, can change */ -# define math_use_old_fraction_scaling_code 93 /* just for tracing, can change */ -# define math_old_code 94 /* this one is stable */ -# define math_option_code 95 - -# define backend_int_base (int_base+96) -# define backend_int_last (int_base+115) - -# define tex_int_pars (116) /* total number of integer parameters */ +# define disable_space_code 63 +# define cat_code_table_code 64 +# define output_box_code 65 +# define cur_lang_code 66 /* current language id */ +# define ex_hyphen_char_code 67 +# define hyphenation_min_code 68 /* minimum word length */ +# define adjust_spacing_code 69 /* level of spacing adjusting */ +# define protrude_chars_code 70 /* protrude chars at left/right edge of paragraphs */ +# define output_mode_code 71 /* switch on PDF output if positive */ +# define draft_mode_code 72 +# define tracing_fonts_code 73 +# define tracing_assigns_code 74 /* show assignments */ +# define tracing_groups_code 75 /* show save/restore groups */ +# define tracing_ifs_code 76 /* show conditionals */ +# define tracing_scan_tokens_code 77 /* show pseudo file open and close */ +# define tracing_nesting_code 78 /* show incomplete groups and ifs within files */ +# define pre_display_direction_code 79 /* text direction preceding a display */ +# define last_line_fit_code 80 /* adjustment for last line of paragraph */ +# define saving_vdiscards_code 81 /* save items discarded from vlists */ +# define saving_hyph_codes_code 82 /* save hyphenation codes for languages */ +# define suppress_fontnotfound_error_code 83 /* suppress errors for missing fonts */ +# define suppress_long_error_code 84 /* suppress errors for missing fonts */ +# define suppress_ifcsname_error_code 85 /* suppress errors for failed \.{\\ifcsname} */ +# define suppress_outer_error_code 86 /* suppress errors for \.{\\outer} */ +# define suppress_mathpar_error_code 87 /* suppress errors for \.{\\par}} in math */ +# define math_eqno_gap_step_code 88 /* factor/1000 used for distance between eq and eqno */ +# define math_display_skip_mode_code 89 +# define math_scripts_mode_code 90 +# define synctex_code 91 /* is synctex file generation enabled ? */ + +# define math_no_italic_compensation_code 92 /* just for tracing, can change */ +# define math_no_char_italic_code 93 /* just for tracing, can change */ +# define math_use_old_fraction_scaling_code 94 /* just for tracing, can change */ +# define math_old_code 95 /* this one is stable */ +# define math_option_code 96 + +# define backend_int_base (int_base+97) +# define backend_int_last (int_base+116) + +# define tex_int_pars (117) /* total number of integer parameters */ # define page_direction_code (tex_int_pars) # define body_direction_code (tex_int_pars+1) @@ -339,7 +333,7 @@ here, and the |number_regs| \.{\\dimen} registers. # define page_bottom_offset_code 24 # define px_dimen_code 25 # define page_width_code 26 /* page width of the output */ -# define page_height_code 27 /* page height of the output */ /* total number of dimension parameters */ +# define page_height_code 27 /* page height of the output */ # define backend_dimen_base (dimen_base+28) # define backend_dimen_last (dimen_base+37) @@ -387,8 +381,10 @@ extern int cur_boundary; /* where # define save_word(A) save_stack[(A)].word_ /* |eqtb| entry */ /* -We use the notation |saved(k)| to stand for an item that -appears in location |save_ptr+k| of the save stack. + +We use the notation |saved(k)| to stand for an item that appears in location +|save_ptr+k| of the save stack. + */ # define saved_type(A) save_stack[save_ptr+(A)].type_ @@ -418,58 +414,59 @@ appears in location |save_ptr+k| of the save stack. # define saved_boxspec 14 # define saved_boxdir 15 # define saved_boxattr 16 -# define saved_eqtb 17 +# define saved_boxpack 18 +# define saved_eqtb 19 extern void print_save_stack(void); -# define assign_trace(A,B) if (int_par(tracing_assigns_code)>0) restore_trace((A),(B)) - # define int_par(A) eqtb[int_base+(A)].cint # define dimen_par(A) eqtb[dimen_base+(A)].cint # define loc_par(A) equiv(local_base+(A)) # define glue_par(A) equiv(glue_base+(A)) -extern int mag_set; /* if nonzero, this magnification should be used henceforth */ +/* if nonzero, this magnification should be used henceforth */ + +extern int mag_set; extern void prepare_mag(void); /* -@ Here are the group codes that are used to discriminate between different -kinds of groups. They allow \TeX\ to decide what special actions, if any, -should be performed when a group ends. -\def\grp{\.{\char'173...\char'175}} -Some groups are not supposed to be ended by right braces. For example, -the `\.\$' that begins a math formula causes a |math_shift_group| to -be started, and this should be terminated by a matching `\.\$'. Similarly, -a group that starts with \.{\\left} should end with \.{\\right}, and -one that starts with \.{\\begingroup} should end with \.{\\endgroup}. +@ Here are the group codes that are used to discriminate between different kinds +of groups. They allow \TeX\ to decide what special actions, if any, should be +performed when a group ends. \def\grp{\.{\char'173...\char'175}} + +Some groups are not supposed to be ended by right braces. For example, the `\.\$' +that begins a math formula causes a |math_shift_group| to be started, and this +should be terminated by a matching `\.\$'. Similarly, a group that starts with +\.{\\left} should end with \.{\\right}, and one that starts with \.{\\begingroup} +should end with \.{\\endgroup}. */ typedef enum { - bottom_level = 0, /* group code for the outside world */ - simple_group, /* group code for local structure only */ - hbox_group, /* code for `\.{\\hbox}\grp' */ - adjusted_hbox_group, /* code for `\.{\\hbox}\grp' in vertical mode */ - vbox_group, /* code for `\.{\\vbox}\grp' */ - vtop_group, /* code for `\.{\\vtop}\grp' */ - align_group, /* code for `\.{\\halign}\grp', `\.{\\valign}\grp' */ - no_align_group, /* code for `\.{\\noalign}\grp' */ - output_group, /* code for output routine */ - math_group, /* code for, e.g., `\.{\char'136}\grp' */ - disc_group, /* code for `\.{\\discretionary}\grp\grp\grp' */ - insert_group, /* code for `\.{\\insert}\grp', `\.{\\vadjust}\grp' */ - vcenter_group, /* code for `\.{\\vcenter}\grp' */ - math_choice_group, /* code for `\.{\\mathchoice}\grp\grp\grp\grp' */ - semi_simple_group, /* code for `\.{\\begingroup...\\endgroup}' */ - math_shift_group, /* code for `\.{\$...\$}' */ - math_left_group, /* code for `\.{\\left...\\right}' */ - local_box_group, /* code for `\.{\\localleftbox...\\localrightbox}' */ - split_off_group, /* box code for the top part of a \.{\\vsplit} */ - split_keep_group, /* box code for the bottom part of a \.{\\vsplit} */ - preamble_group, /* box code for the preamble processing in an alignment */ - align_set_group, /* box code for the final item pass in an alignment */ - fin_row_group /* box code for a provisory line in an alignment */ + bottom_level = 0, /* group code for the outside world */ + simple_group, /* group code for local structure only */ + hbox_group, /* code for `\.{\\hbox}\grp' */ + adjusted_hbox_group, /* code for `\.{\\hbox}\grp' in vertical mode */ + vbox_group, /* code for `\.{\\vbox}\grp' */ + vtop_group, /* code for `\.{\\vtop}\grp' */ + align_group, /* code for `\.{\\halign}\grp', `\.{\\valign}\grp' */ + no_align_group, /* code for `\.{\\noalign}\grp' */ + output_group, /* code for output routine */ + math_group, /* code for, e.g., `\.{\char'136}\grp' */ + disc_group, /* code for `\.{\\discretionary}\grp\grp\grp' */ + insert_group, /* code for `\.{\\insert}\grp', `\.{\\vadjust}\grp' */ + vcenter_group, /* code for `\.{\\vcenter}\grp' */ + math_choice_group, /* code for `\.{\\mathchoice}\grp\grp\grp\grp' */ + semi_simple_group, /* code for `\.{\\begingroup...\\endgroup}' */ + math_shift_group, /* code for `\.{\$...\$}' */ + math_left_group, /* code for `\.{\\left...\\right}' */ + local_box_group, /* code for `\.{\\localleftbox...\\localrightbox}' */ + split_off_group, /* box code for the top part of a \.{\\vsplit} */ + split_keep_group, /* box code for the bottom part of a \.{\\vsplit} */ + preamble_group, /* box code for the preamble processing in an alignment */ + align_set_group, /* box code for the final item pass in an alignment */ + fin_row_group /* box code for a provisory line in an alignment */ } tex_group_codes; # define max_group_code local_box_group /* which is wrong, but is what the web says */ @@ -490,7 +487,6 @@ extern void geq_define(halfword p, quarterword t, halfword e); /* global |eq_de extern void geq_word_define(halfword p, int w); /* global |eq_word_define| */ extern void save_for_after(halfword t); extern void unsave(void); /* pops the top level off the save stack */ -extern void restore_trace(halfword p, const char *s); /* |eqtb[p]| has just been restored or retained */ extern void show_save_groups(void); # define level_zero 0 /* level for undefined quantities */ @@ -498,10 +494,20 @@ extern void show_save_groups(void); extern void show_eqtb(halfword n); +/* \csname \ifcsname */ + +extern halfword last_cs_name; + /* more will move here */ #define space_skip glue_par(space_skip_code) #define xspace_skip glue_par(xspace_skip_code) #define math_skip glue_par(math_skip_code) +#define body_direction int_par(body_direction_code) +#define page_direction int_par(page_direction_code) +#define par_direction int_par(par_direction_code) +#define text_direction int_par(text_direction_code) +#define math_direction int_par(math_direction_code) + #endif diff --git a/Build/source/texk/web2c/luatexdir/tex/equivalents.w b/Build/source/texk/web2c/luatexdir/tex/equivalents.w index 5fe8b4ec500..d88b7322a76 100644 --- a/Build/source/texk/web2c/luatexdir/tex/equivalents.w +++ b/Build/source/texk/web2c/luatexdir/tex/equivalents.w @@ -19,9 +19,23 @@ @ @c - #include "ptexlib.h" +halfword last_cs_name = null_cs; + +/* |eqtb[p]| has just been restored or retained */ + +static void diagnostic_trace(halfword p, const char *s) +{ + begin_diagnostic(); + print_char('{'); + tprint(s); + print_char(' '); + show_eqtb(p); + print_char('}'); + end_diagnostic(false); +} + @ @c #define par_shape_ptr equiv(par_shape_loc) @@ -85,7 +99,6 @@ void initialize_equivalents(void) xeq_level[k] = level_one; } - @ The nested structure provided by `$\.{\char'173}\ldots\.{\char'175}$' groups in \TeX\ means that |eqtb| entries valid in outer groups should be saved and restored later if they are overridden inside the braces. When a new |eqtb| @@ -105,9 +118,9 @@ interpreted in one of four ways: |save_value(p)| is a location in |eqtb| whose current value should be destroyed at the end of the current group and replaced by |save_word(p-1)| (|save_type(p-1)==saved_eqtb|). -Furthermore if |save_value(p)>=int_base|, then |save_level(p)| should +Furthermore if |save_value(p)>=int_base|, then |save_level(p)| should replace the corresponding entry in |xeq_level| (if |save_value(p)<int_base|, -then the level is part of |save_word(p-1)|). +then the level is part of |save_word(p-1)|). \yskip\hang 2) If |save_type(p)=restore_zero|, then |save_value(p)| is a location in |eqtb| whose current value should be destroyed at the end @@ -125,7 +138,6 @@ the entries for that group. Furthermore, |save_value(p-1)| contains the source line number at which the current level of grouping was entered, this field has itself a type: |save_type(p-1)==saved_line|. - Besides this `official' use, various subroutines push temporary variables on the save stack when it is handy to do so. These all have an explicit |save_type|, and they are: @@ -141,7 +153,8 @@ an explicit |save_type|, and they are: |saved_boxcontext| the box context value, |saved_boxspec| the box \.{to} or \.{spread} specification, |saved_boxdir| the box \.{dir} specification, -|saved_boxattr| the box \.{attr} specification. +|saved_boxattr| the box \.{attr} specification, +|saved_boxpack| the box \.{pack} specification. @ The global variable |cur_group| keeps track of what sort of group we are currently in. Another global variable, |cur_boundary|, points to the @@ -151,12 +164,11 @@ in the |save_stack| or in |eqtb| ever has a level greater than |cur_level|. @c save_record *save_stack; -int save_ptr; /* first unused entry on |save_stack| */ -int max_save_stack; /* maximum usage of save stack */ -quarterword cur_level = level_one; /* current nesting level for groups */ -group_code cur_group = bottom_level; /* current group type */ -int cur_boundary; /* where the current level begins */ - +int save_ptr; /* first unused entry on |save_stack| */ +int max_save_stack; /* maximum usage of save stack */ +quarterword cur_level = level_one; /* current nesting level for groups */ +group_code cur_group = bottom_level; /* current group type */ +int cur_boundary; /* where the current level begins */ @ At this time it might be a good idea for the reader to review the introduction to |eqtb| that was given above just before the long lists of parameter names. @@ -170,14 +182,13 @@ entries on |save_stack|. By making a conservative test like this, we can get by with testing for overflow in only a few places. @c -#define check_full_save_stack() do { \ - if (save_ptr>max_save_stack) { \ - max_save_stack=save_ptr; \ - if (max_save_stack>save_size-8) \ - overflow("save size",(unsigned)save_size); \ - } \ - } while (0) - +#define check_full_save_stack() do { \ + if (save_ptr>max_save_stack) { \ + max_save_stack=save_ptr; \ + if (max_save_stack>save_size-8) \ + overflow("save size",(unsigned)save_size); \ + } \ +} while (0) @ Procedure |new_save_level| is called when a group begins. The argument is a group identification code like `|hbox_group|'. After @@ -193,7 +204,7 @@ called. @c void new_save_level(group_code c) -{ /* begin a new level of grouping */ +{ /* begin a new level of grouping */ check_full_save_stack(); set_saved_record(0, saved_line, 0, line); incr(save_ptr); @@ -216,27 +227,26 @@ static const char *save_stack_type(int v) { const char *s = ""; switch (save_type(v)) { -/* *INDENT-OFF* */ - case restore_old_value: s = "restore_old_value"; break; - case restore_zero: s = "restore_zero"; break; - case insert_token: s = "insert_token"; break; - case level_boundary: s = "level_boundary"; break; - case saved_line: s = "saved_line"; break; - case saved_adjust: s = "saved_adjust"; break; - case saved_insert: s = "saved_insert"; break; - case saved_disc: s = "saved_disc"; break; - case saved_boxtype: s = "saved_boxtype"; break; - case saved_textdir: s = "saved_textdir"; break; - case saved_eqno: s = "saved_eqno"; break; - case saved_choices: s = "saved_choices"; break; - case saved_math: s = "saved_math"; break; - case saved_boxcontext: s = "saved_boxcontext"; break; - case saved_boxspec: s = "saved_boxspec"; break; - case saved_boxdir: s = "saved_boxdir"; break; - case saved_boxattr: s = "saved_boxattr"; break; - case saved_eqtb: s = "saved_eqtb"; break; - default: break; -/* *INDENT-ON* */ + case restore_old_value: s = "restore_old_value"; break; + case restore_zero: s = "restore_zero"; break; + case insert_token: s = "insert_token"; break; + case level_boundary: s = "level_boundary"; break; + case saved_line: s = "saved_line"; break; + case saved_adjust: s = "saved_adjust"; break; + case saved_insert: s = "saved_insert"; break; + case saved_disc: s = "saved_disc"; break; + case saved_boxtype: s = "saved_boxtype"; break; + case saved_textdir: s = "saved_textdir"; break; + case saved_eqno: s = "saved_eqno"; break; + case saved_choices: s = "saved_choices"; break; + case saved_math: s = "saved_math"; break; + case saved_boxcontext: s = "saved_boxcontext"; break; + case saved_boxspec: s = "saved_boxspec"; break; + case saved_boxdir: s = "saved_boxdir"; break; + case saved_boxattr: s = "saved_boxattr"; break; + case saved_boxpack: s = "saved_boxpack"; break; + case saved_eqtb: s = "saved_eqtb"; break; + default: break; } return s; } @@ -258,106 +268,105 @@ void print_save_stack(void) tprint("]: "); tprint(save_stack_type(i)); switch (save_type(i)) { - case restore_old_value: - tprint(", "); - show_eqtb_meaning(save_value(i)); - tprint("="); - if (save_value(i) >= int_base) { - print_int(save_word(i - 1).cint); - } else { - print_int(eq_type_field(save_word(i - 1))); - print_char(','); /* |print_int(eq_level_field(save_word(i-1)));| */ - print_int(equiv_field(save_word(i - 1))); - } - i--; - break; - case restore_zero: - tprint(", "); - show_eqtb_meaning(save_value(i)); - break; - case insert_token: - tprint(", "); - { - halfword p = get_avail(); - set_token_info(p, save_value(i)); - show_token_list(p, null, 1); - free_avail(p); - } - break; - case level_boundary: - tprint(", old group="); - print_int(save_level(i)); - tprint(", boundary = "); - print_int(save_value(i)); - tprint(", line = "); - print_int(save_value(i - 1)); - i--; - break; - case saved_adjust: - tprint(", "); - print_int(save_level(i)); /* vadjust vs vadjust pre */ - break; - case saved_insert: - tprint(", "); - print_int(save_value(i)); /* insert number */ - break; - case saved_boxtype: /* \.{\\localleftbox} vs \.{\\localrightbox} */ - tprint(", "); - print_int(save_value(i)); - break; - case saved_eqno: /* \.{\\eqno} vs \.{\\leqno} */ - tprint(", "); - print_int(save_value(i)); - break; - case saved_disc: - case saved_choices: - tprint(", "); - print_int(save_value(i)); - break; - case saved_math: - tprint(", listptr="); - print_int(save_value(i)); - break; - case saved_boxcontext: - tprint(", "); - print_int(save_value(i)); - break; - case saved_boxspec: - tprint(", spec="); - print_int(save_level(i)); - tprint(", dimen="); - print_int(save_value(i)); - break; - case saved_textdir: - case saved_boxdir: - tprint(", "); - print_dir(dir_dir(save_value(i))); - break; - case saved_boxattr: - tprint(", "); - print_int(save_value(i)); - break; - case saved_line: - case saved_eqtb: - break; - default: - break; + case restore_old_value: + tprint(", "); + show_eqtb_meaning(save_value(i)); + tprint("="); + if (save_value(i) >= int_base) { + print_int(save_word(i - 1).cint); + } else { + print_int(eq_type_field(save_word(i - 1))); + print_char(','); /* |print_int(eq_level_field(save_word(i-1)));| */ + print_int(equiv_field(save_word(i - 1))); + } + i--; + break; + case restore_zero: + tprint(", "); + show_eqtb_meaning(save_value(i)); + break; + case insert_token: + tprint(", "); + { + halfword p = get_avail(); + set_token_info(p, save_value(i)); + show_token_list(p, null, 1); + free_avail(p); + } + break; + case level_boundary: + tprint(", old group="); + print_int(save_level(i)); + tprint(", boundary = "); + print_int(save_value(i)); + tprint(", line = "); + print_int(save_value(i - 1)); + i--; + break; + case saved_adjust: + tprint(", "); + print_int(save_level(i)); /* vadjust vs vadjust pre */ + break; + case saved_insert: + tprint(", "); + print_int(save_value(i)); /* insert number */ + break; + case saved_boxtype: /* \.{\\localleftbox} vs \.{\\localrightbox} */ + tprint(", "); + print_int(save_value(i)); + break; + case saved_eqno: /* \.{\\eqno} vs \.{\\leqno} */ + tprint(", "); + print_int(save_value(i)); + break; + case saved_disc: + case saved_choices: + tprint(", "); + print_int(save_value(i)); + break; + case saved_math: + tprint(", listptr="); + print_int(save_value(i)); + break; + case saved_boxcontext: + tprint(", "); + print_int(save_value(i)); + break; + case saved_boxspec: + tprint(", spec="); + print_int(save_level(i)); + tprint(", dimen="); + print_int(save_value(i)); + break; + case saved_textdir: + case saved_boxdir: + tprint(", "); + print_dir(dir_dir(save_value(i))); + break; + case saved_boxattr: + case saved_boxpack: + tprint(", "); + print_int(save_value(i)); + break; + case saved_line: + case saved_eqtb: + break; + default: + break; } print_ln(); } end_diagnostic(true); } - @ The \.{\\showgroups} command displays all currently active grouping levels. - @ The modifications of \TeX\ required for the display produced by the |show_save_groups| procedure were first discussed by Donald~E. Knuth in {\sl TUGboat\/} {\bf 11}, 165--170 and 499--511, 1990. @^Knuth, Donald Ervin@> - + In order to understand a group type we also have to know its mode. Since unrestricted horizontal modes are not associated with grouping, they are skipped when traversing the semantic nest. @@ -365,26 +374,17 @@ void print_save_stack(void) @c void show_save_groups(void) { - int p; /* index into |nest| */ + int p = nest_ptr; /* index into |nest| */ int m; /* mode */ - save_pointer v; /* saved value of |save_ptr| */ - quarterword l; /* saved value of |cur_level| */ - group_code c; /* saved value of |cur_group| */ - int a; /* to keep track of alignments */ + save_pointer v = save_ptr; /* saved value of |save_ptr| */ + quarterword l = cur_level; /* saved value of |cur_level| */ + group_code c = cur_group; /* saved value of |cur_group| */ + int a = 1; /* to keep track of alignments */ int i; quarterword j; - const char *s; -#ifdef DEBUG - print_save_stack(); -#endif - p = nest_ptr; - v = save_ptr; - l = cur_level; - c = cur_group; + const char *s = NULL; save_ptr = cur_boundary; decr(cur_level); - a = 1; - s = NULL; tprint_nl(""); print_ln(); while (1) { @@ -401,106 +401,106 @@ void show_save_groups(void) } while (m == hmode); tprint(" ("); switch (cur_group) { - case simple_group: - incr(p); - goto FOUND2; - break; - case hbox_group: - case adjusted_hbox_group: - s = "hbox"; - break; - case vbox_group: - s = "vbox"; - break; - case vtop_group: - s = "vtop"; - break; - case align_group: - if (a == 0) { - if (m == -vmode) - s = "halign"; - else - s = "valign"; - a = 1; + case simple_group: + incr(p); + goto FOUND2; + break; + case hbox_group: + case adjusted_hbox_group: + s = "hbox"; + break; + case vbox_group: + s = "vbox"; + break; + case vtop_group: + s = "vtop"; + break; + case align_group: + if (a == 0) { + if (m == -vmode) + s = "halign"; + else + s = "valign"; + a = 1; + goto FOUND1; + } else { + if (a == 1) + tprint("align entry"); + else + tprint_esc("cr"); + if (p >= a) + p = p - a; + a = 0; + goto FOUND; + } + break; + case no_align_group: + incr(p); + a = -1; + tprint_esc("noalign"); + goto FOUND2; + break; + case output_group: + tprint_esc("output"); + goto FOUND; + break; + case math_group: + goto FOUND2; + break; + case disc_group: + tprint_esc("discretionary"); + for (i = 1; i < 3; i++) + if (i <= saved_value(-2)) + tprint("{}"); + goto FOUND2; + break; + case math_choice_group: + tprint_esc("mathchoice"); + for (i = 1; i < 4; i++) + if (i <= saved_value(-3)) /* different offset because |-2==saved_textdir| */ + tprint("{}"); + goto FOUND2; + break; + case insert_group: + if (saved_type(-1) == saved_adjust) { + tprint_esc("vadjust"); + if (saved_level(-1) != 0) + tprint(" pre"); + } else { + tprint_esc("insert"); + print_int(saved_value(-1)); + } + goto FOUND2; + break; + case vcenter_group: + s = "vcenter"; goto FOUND1; - } else { - if (a == 1) - tprint("align entry"); - else - tprint_esc("cr"); - if (p >= a) - p = p - a; - a = 0; + break; + case semi_simple_group: + incr(p); + tprint_esc("begingroup"); goto FOUND; - } - break; - case no_align_group: - incr(p); - a = -1; - tprint_esc("noalign"); - goto FOUND2; - break; - case output_group: - tprint_esc("output"); - goto FOUND; - break; - case math_group: - goto FOUND2; - break; - case disc_group: - tprint_esc("discretionary"); - for (i = 1; i < 3; i++) - if (i <= saved_value(-2)) - tprint("{}"); - goto FOUND2; - break; - case math_choice_group: - tprint_esc("mathchoice"); - for (i = 1; i < 4; i++) - if (i <= saved_value(-3)) /* different offset because |-2==saved_textdir| */ - tprint("{}"); - goto FOUND2; - break; - case insert_group: - if (saved_type(-1) == saved_adjust) { - tprint_esc("vadjust"); - if (saved_level(-1) != 0) - tprint(" pre"); - } else { - tprint_esc("insert"); - print_int(saved_value(-1)); - } - goto FOUND2; - break; - case vcenter_group: - s = "vcenter"; - goto FOUND1; - break; - case semi_simple_group: - incr(p); - tprint_esc("begingroup"); - goto FOUND; - break; - case math_shift_group: - if (m == mmode) { + break; + case math_shift_group: + if (m == mmode) { + print_char('$'); + } else if (nest[p].mode_field == mmode) { + print_cmd_chr(eq_no_cmd, saved_value(-2)); + goto FOUND; + } print_char('$'); - } else if (nest[p].mode_field == mmode) { - print_cmd_chr(eq_no_cmd, saved_value(-2)); goto FOUND; - } - print_char('$'); - goto FOUND; - break; - case math_left_group: - if (subtype(nest[p + 1].eTeX_aux_field) == left_noad_side) - tprint_esc("left"); - else - tprint_esc("middle"); - goto FOUND; - break; - default: - confusion("showgroups"); - break; + break; + case math_left_group: + if (subtype(nest[p + 1].eTeX_aux_field) == left_noad_side) + tprint_esc("left"); + else + tprint_esc("middle"); + goto FOUND; + break; + default: + confusion("showgroups"); + break; } /* Show the box context */ i = saved_value(-5); @@ -560,8 +560,6 @@ void show_save_groups(void) cur_group = c; } - - @ Just before an entry of |eqtb| is changed, the following procedure should be called to update the other data structures properly. It is important to keep in mind that reference counts in |mem| include references from @@ -573,29 +571,28 @@ void eq_destroy(memory_word w) { /* gets ready to forget |w| */ halfword q; /* |equiv| field of |w| */ switch (eq_type_field(w)) { - case call_cmd: - case long_call_cmd: - case outer_call_cmd: - case long_outer_call_cmd: - delete_token_ref(equiv_field(w)); - break; - case glue_ref_cmd: - delete_glue_ref(equiv_field(w)); - break; - case shape_ref_cmd: - q = equiv_field(w); /* we need to free a \.{\\parshape} block */ - if (q != null) - flush_node(q); - break; /* such a block is |2n+1| words long, where |n=vinfo(q)| */ - case box_ref_cmd: - flush_node_list(equiv_field(w)); - break; - default: - break; + case call_cmd: + case long_call_cmd: + case outer_call_cmd: + case long_outer_call_cmd: + delete_token_ref(equiv_field(w)); + break; + case glue_ref_cmd: + delete_glue_ref(equiv_field(w)); + break; + case shape_ref_cmd: + q = equiv_field(w); /* we need to free a \.{\\parshape} block */ + if (q != null) + flush_node(q); + break; /* such a block is |2n+1| words long, where |n=vinfo(q)| */ + case box_ref_cmd: + flush_node_list(equiv_field(w)); + break; + default: + break; } } - @ To save a value of |eqtb[p]| that was established at level |l|, we can use the following subroutine. @@ -616,7 +613,6 @@ void eq_save(halfword p, quarterword l) incr(save_ptr); } - @ The procedure |eq_define| defines an |eqtb| entry having specified |eq_type| and |equiv| fields, and saves the former value if appropriate. This procedure is used only for entries in the first four regions of |eqtb|, @@ -625,15 +621,19 @@ After calling this routine, it is safe to put four more entries on |save_stack|, provided that there was room for four more entries before the call, since |eq_save| makes the necessary test. +@ new data for |eqtb| @c void eq_define(halfword p, quarterword t, halfword e) -{ /* new data for |eqtb| */ +{ + boolean trace = int_par(tracing_assigns_code) > 0; if ((eq_type(p) == t) && (equiv(p) == e)) { - assign_trace(p, "reassigning"); + if (trace) + diagnostic_trace(p, "reassigning"); eq_destroy(eqtb[p]); return; } - assign_trace(p, "changing"); + if (trace) + diagnostic_trace(p, "changing"); if (eq_level(p) == cur_level) eq_destroy(eqtb[p]); else if (cur_level > level_one) @@ -641,10 +641,10 @@ void eq_define(halfword p, quarterword t, halfword e) set_eq_level(p, cur_level); set_eq_type(p, t); set_equiv(p, e); - assign_trace(p, "into"); + if (trace) + diagnostic_trace(p, "into"); } - @ The counterpart of |eq_define| for the remaining (fullword) positions in |eqtb| is called |eq_word_define|. Since |xeq_level[p]>=level_one| for all |p|, a `|restore_zero|' will never be used in this case. @@ -652,17 +652,21 @@ void eq_define(halfword p, quarterword t, halfword e) @c void eq_word_define(halfword p, int w) { + boolean trace = int_par(tracing_assigns_code) > 0; if (eqtb[p].cint == w) { - assign_trace(p, "reassigning"); + if (trace) + diagnostic_trace(p, "reassigning"); return; } - assign_trace(p, "changing"); + if (trace) + diagnostic_trace(p, "changing"); if (xeq_level[p] != cur_level) { eq_save(p, xeq_level[p]); xeq_level[p] = cur_level; } eqtb[p].cint = w; - assign_trace(p, "into"); + if (trace) + diagnostic_trace(p, "into"); } @@ -674,24 +678,29 @@ to save old values, and the new value is associated with |level_one|. @c void geq_define(halfword p, quarterword t, halfword e) { /* global |eq_define| */ - assign_trace(p, "globally changing"); + boolean trace = int_par(tracing_assigns_code) > 0; + if (trace) + diagnostic_trace(p, "globally changing"); eq_destroy(eqtb[p]); set_eq_level(p, level_one); set_eq_type(p, t); set_equiv(p, e); - assign_trace(p, "into"); + if (trace) + diagnostic_trace(p, "into"); } void geq_word_define(halfword p, int w) { /* global |eq_word_define| */ - assign_trace(p, "globally changing"); + boolean trace = int_par(tracing_assigns_code) > 0; + if (trace) + diagnostic_trace(p, "globally changing"); eqtb[p].cint = w; xeq_level[p] = level_one; - assign_trace(p, "into"); + if (trace) + diagnostic_trace(p, "into"); } - -@ Subroutine |save_for_after| puts a token on the stack for save-keeping. +@ Subroutine |save_for_after| puts a token on the stack for save-keeping. @c void save_for_after(halfword t) @@ -705,7 +714,6 @@ void save_for_after(halfword t) } } - @ The |unsave| routine goes the other way, taking items off of |save_stack|. This routine takes care of restoration when a level ends; everything belonging to the topmost group is cleared off of the save stack. @@ -714,15 +722,14 @@ belonging to the topmost group is cleared off of the save stack. void unsave(void) { /* pops the top level off the save stack */ halfword p; /* position to be restored */ - quarterword l; /* saved level, if in fullword regions of |eqtb| */ - boolean a; /* have we already processed an \.{\\aftergroup} ? */ - a = false; - l = level_one; /* just in case */ + quarterword l = level_one; /* saved level, if in fullword regions of |eqtb| */ + boolean a = false; /* have we already processed an \.{\\aftergroup} ? */ unsave_math_codes(cur_level); unsave_cat_codes(int_par(cat_code_table_code), cur_level); unsave_text_codes(cur_level); unsave_math_data(cur_level); if (cur_level > level_one) { + boolean trace = int_par(tracing_restores_code) > 0; decr(cur_level); /* Clear off top level from |save_stack| */ while (true) { @@ -731,7 +738,8 @@ void unsave(void) break; p = save_value(save_ptr); if (save_type(save_ptr) == insert_token) { - a = reinsert_token(a, p); + reinsert_token(a, p); + a = true; /* always ... always etex now */ } else { if (save_type(save_ptr) == restore_old_value) { l = save_level(save_ptr); @@ -749,24 +757,23 @@ void unsave(void) if (p < int_base || p > eqtb_size) { if (eq_level(p) == level_one) { eq_destroy(save_word(save_ptr)); /* destroy the saved value */ - if (int_par(tracing_restores_code) > 0) - restore_trace(p, "retaining"); + if (trace) + diagnostic_trace(p, "retaining"); } else { eq_destroy(eqtb[p]); /* destroy the current value */ eqtb[p] = save_word(save_ptr); /* restore the saved value */ - if (int_par(tracing_restores_code) > 0) - restore_trace(p, "restoring"); + if (trace) + diagnostic_trace(p, "restoring"); } } else if (xeq_level[p] != level_one) { eqtb[p] = save_word(save_ptr); xeq_level[p] = l; - if (int_par(tracing_restores_code) > 0) - restore_trace(p, "restoring"); + if (trace) + diagnostic_trace(p, "restoring"); } else { - if (int_par(tracing_restores_code) > 0) - restore_trace(p, "retaining"); + if (trace) + diagnostic_trace(p, "retaining"); } - } } if (int_par(tracing_groups_code) > 0) @@ -776,26 +783,12 @@ void unsave(void) cur_group = save_level(save_ptr); cur_boundary = save_value(save_ptr); decr(save_ptr); - } else { confusion("curlevel"); /* |unsave| is not used when |cur_group=bottom_level| */ } attr_list_cache = cache_disabled; } -@ @c -void restore_trace(halfword p, const char *s) -{ /* |eqtb[p]| has just been restored or retained */ - begin_diagnostic(); - print_char('{'); - tprint(s); - print_char(' '); - show_eqtb(p); - print_char('}'); - end_diagnostic(false); -} - - @ Most of the parameters kept in |eqtb| can be changed freely, but there's an exception: The magnification should not be used with two different values during any \TeX\ job, since a single magnification is applied to an @@ -803,8 +796,7 @@ entire run. The global variable |mag_set| is set to the current magnification whenever it becomes necessary to ``freeze'' it at a particular value. @c -int mag_set; /* if nonzero, this magnification should be used henceforth */ - +int mag_set; /* if nonzero, this magnification should be used henceforth */ @ The |prepare_mag| subroutine is called whenever \TeX\ wants to use |mag| for magnification. @@ -839,7 +831,6 @@ void prepare_mag(void) mag_set = mag; } - @ Let's pause a moment now and try to look at the Big Picture. The \TeX\ program consists of three main parts: syntactic routines, semantic routines, and output routines. The chief purpose of the @@ -892,7 +883,7 @@ halfword cur_chr; /* operand of current command */ halfword cur_cs; /* control sequence found here, zero if none found */ halfword cur_tok; /* packed representative of |cur_cmd| and |cur_chr| */ -@ Here is a procedure that displays the current command. +@ Here is a procedure that displays the current command. @c #define mode cur_list.mode_field @@ -939,20 +930,22 @@ void show_cur_cmd_chr(void) end_diagnostic(false); } - -@ Here is a procedure that displays the contents of |eqtb[n]| - symbolically. +@ Here is a procedure that displays the contents of |eqtb[n]| symbolically. @c void show_eqtb(halfword n) { if (n < null_cs) { - print_char('?'); /* this can't happen */ + /* this can't happen */ + print_char('?'); } else if ((n < glue_base) || ((n > eqtb_size) && (n <= eqtb_top))) { - /* Show equivalent |n|, in region 1 or 2 */ - /* Here is a routine that displays the current meaning of an |eqtb| entry - in region 1 or~2. (Similar routines for the other regions will appear - below.) */ + /* + Show equivalent |n|, in region 1 or 2 + + Here is a routine that displays the current meaning of an |eqtb| entry + in region 1 or~2. (Similar routines for the other regions will appear + below.) + */ sprint_cs(n); print_char('='); @@ -962,8 +955,11 @@ void show_eqtb(halfword n) show_token_list(token_link(equiv(n)), null, 32); } } else if (n < local_base) { - /* Show equivalent |n|, in region 3 */ - /* All glue parameters and registers are initially `\.{0pt plus0pt minus0pt}'. */ + /* + Show equivalent |n|, in region 3 + + All glue parameters and registers are initially `\.{0pt plus0pt minus0pt}'. + */ if (n < skip_base) { if (n < glue_base + thin_mu_skip_code) print_cmd_chr(assign_glue_cmd, n); @@ -987,16 +983,19 @@ void show_eqtb(halfword n) } } else if (n < int_base) { - /* Show equivalent |n|, in region 4 */ - /* We initialize most things to null or undefined values. An undefined font - is represented by the internal code |font_base|. - - However, the character code tables are given initial values based on the - conventional interpretation of ASCII code. These initial values should - not be changed when \TeX\ is adapted for use with non-English languages; - all changes to the initialization conventions should be made in format - packages, not in \TeX\ itself, so that global interchange of formats is - possible. */ + /* + Show equivalent |n|, in region 4 + + We initialize most things to null or undefined values. An undefined font + is represented by the internal code |font_base|. + + However, the character code tables are given initial values based on the + conventional interpretation of ASCII code. These initial values should + not be changed when \TeX\ is adapted for use with non-English languages; + all changes to the initialization conventions should be made in format + packages, not in \TeX\ itself, so that global interchange of formats is + possible. + */ if ((n == par_shape_loc) || ((n >= etex_pen_base) && (n < etex_pens))) { if (n == par_shape_loc) print_cmd_chr(set_tex_shape_cmd, n); @@ -1042,7 +1041,6 @@ void show_eqtb(halfword n) print_char('='); print_esc(hash[font_id_base + equiv(n)].rh); /* that's |font_id_text(equiv(n))| */ } - } else if (n < dimen_base) { /* Show equivalent |n|, in region 5 */ if (n < dir_base) { @@ -1064,7 +1062,6 @@ void show_eqtb(halfword n) print_char('='); print_int(eqtb[n].cint); } - } else if (n <= eqtb_size) { /* Show equivalent |n|, in region 6 */ if (n < scaled_base) { @@ -1076,9 +1073,9 @@ void show_eqtb(halfword n) print_char('='); print_scaled(eqtb[n].cint); tprint("pt"); - } else { - print_char('?'); /* this can't happen either */ + /* this can't happen either */ + print_char('?'); } } @@ -1086,17 +1083,23 @@ void show_eqtb(halfword n) void show_eqtb_meaning(halfword n) { if (n < null_cs) { - print_char('?'); /* this can't happen */ + /* this can't happen */ + print_char('?'); } else if ((n < glue_base) || ((n > eqtb_size) && (n <= eqtb_top))) { - /* Show equivalent |n|, in region 1 or 2 */ - /* Here is a routine that displays the current meaning of an |eqtb| entry - in region 1 or~2. (Similar routines for the other regions will appear - below.) */ + /* + Show equivalent |n|, in region 1 or 2 + Here is a routine that displays the current meaning of an |eqtb| entry + in region 1 or~2. (Similar routines for the other regions will appear + below.) + */ sprint_cs(n); } else if (n < local_base) { - /* Show equivalent |n|, in region 3 */ - /* All glue parameters and registers are initially `\.{0pt plus0pt minus0pt}'. */ + /* + Show equivalent |n|, in region 3 + + All glue parameters and registers are initially `\.{0pt plus0pt minus0pt}'. + */ if (n < skip_base) { if (n < glue_base + thin_mu_skip_code) print_cmd_chr(assign_glue_cmd, n); @@ -1111,16 +1114,19 @@ void show_eqtb_meaning(halfword n) } } else if (n < int_base) { - /* Show equivalent |n|, in region 4 */ - /* We initialize most things to null or undefined values. An undefined font - is represented by the internal code |font_base|. - - However, the character code tables are given initial values based on the - conventional interpretation of ASCII code. These initial values should - not be changed when \TeX\ is adapted for use with non-English languages; - all changes to the initialization conventions should be made in format - packages, not in \TeX\ itself, so that global interchange of formats is - possible. */ + /* + Show equivalent |n|, in region 4 + + We initialize most things to null or undefined values. An undefined font + is represented by the internal code |font_base|. + + However, the character code tables are given initial values based on the + conventional interpretation of ASCII code. These initial values should + not be changed when \TeX\ is adapted for use with non-English languages; + all changes to the initialization conventions should be made in format + packages, not in \TeX\ itself, so that global interchange of formats is + possible. + */ if ((n == par_shape_loc) || ((n >= etex_pen_base) && (n < etex_pens))) { if (n == par_shape_loc) print_cmd_chr(set_tex_shape_cmd, n); @@ -1138,7 +1144,6 @@ void show_eqtb_meaning(halfword n) /* Show the font identifier in |eqtb[n]| */ tprint("current font"); } - } else if (n < dimen_base) { /* Show equivalent |n|, in region 5 */ if (n < dir_base) { @@ -1152,7 +1157,6 @@ void show_eqtb_meaning(halfword n) tprint_esc("attribute"); print_int(n - attribute_base); } - } else if (n <= eqtb_size) { /* Show equivalent |n|, in region 6 */ if (n < scaled_base) { @@ -1162,6 +1166,7 @@ void show_eqtb_meaning(halfword n) print_int(n - scaled_base); } } else { - print_char('?'); /* this can't happen either */ + /* this can't happen either */ + print_char('?'); } } diff --git a/Build/source/texk/web2c/luatexdir/tex/errors.h b/Build/source/texk/web2c/luatexdir/tex/errors.h index 101e78adb71..3eae1c8a927 100644 --- a/Build/source/texk/web2c/luatexdir/tex/errors.h +++ b/Build/source/texk/web2c/luatexdir/tex/errors.h @@ -99,7 +99,9 @@ extern void pause_for_instructions(void); extern void tex_error(const char *msg, const char **hlp); extern void normal_error(const char *t, const char *p); -extern void normal_warning(const char *t, const char *p, boolean pr, boolean ap); +extern void normal_warning(const char *t, const char *p); +extern void formatted_error(const char *t, const char *fmt, ...); +extern void formatted_warning(const char *t, const char *fmt, ...); extern void back_error(void); extern void ins_error(void); @@ -107,4 +109,6 @@ extern void flush_err(void); extern void char_warning(internal_font_number f, int c); +extern void wrapup_backend(void); + #endif diff --git a/Build/source/texk/web2c/luatexdir/tex/errors.w b/Build/source/texk/web2c/luatexdir/tex/errors.w index e11fcd908fe..227095d3f09 100644 --- a/Build/source/texk/web2c/luatexdir/tex/errors.w +++ b/Build/source/texk/web2c/luatexdir/tex/errors.w @@ -659,10 +659,41 @@ void char_warning(internal_font_number f, int c) } @ @c + +void wrapup_backend(void) { + ensure_output_state(static_pdf, ST_OMODE_FIX); + switch (output_mode_used) { + case OMODE_NONE: + print_err(" ==> Fatal error occurred, no FMT file produced!"); + break; + case OMODE_PDF: + if (history == fatal_error_stop) { + remove_pdffile(static_pdf); /* will become remove_output_file */ + print_err(" ==> Fatal error occurred, no output PDF file produced!"); + } else { + finish_pdf_file(static_pdf, luatex_version, get_luatexrevision()); + } + break; + case OMODE_DVI: + if (history == fatal_error_stop) { + print_err(" ==> Fatal error occurred, bad output DVI file produced!"); + finish_dvi_file(static_pdf, luatex_version, get_luatexrevision()); + } else { + finish_dvi_file(static_pdf, luatex_version, get_luatexrevision()); + } + break; + } +} + void normal_error(const char *t, const char *p) { normalize_selector(); print_err("error "); + if (cur_file_name) { + tprint(" (file "); + tprint(cur_file_name); + tprint(")"); + } if (t != NULL) { tprint(" ("); tprint(t); @@ -671,11 +702,14 @@ void normal_error(const char *t, const char *p) tprint(": "); if (p != NULL) tprint(p); - succumb(); + /* quit */ + history = fatal_error_stop; + wrapup_backend(); + exit(EXIT_FAILURE); } @ @c -void normal_warning(const char *t, const char *p, boolean prepend_nl, boolean append_nl) +void normal_warning(const char *t, const char *p) { int report_id ; if (strcmp(t,"lua") == 0) { @@ -704,9 +738,13 @@ void normal_warning(const char *t, const char *p, boolean prepend_nl, boolean ap strcpy(last_warning_tag,t); run_callback(report_id, "->"); } else { - if (prepend_nl) - print_ln(); + print_ln(); tprint("warning "); + if (cur_file_name) { + tprint(" (file "); + tprint(cur_file_name); + tprint(")"); + } if (t != NULL) { tprint(" ("); tprint(t); @@ -715,10 +753,30 @@ void normal_warning(const char *t, const char *p, boolean prepend_nl, boolean ap tprint(": "); if (p != NULL) tprint(p); - if (append_nl) - print_ln(); + print_ln(); } if (history == spotless) history = warning_issued; } } + +@ @c +static char print_buf[PRINTF_BUF_SIZE]; + +void formatted_error(const char *t, const char *fmt, ...) +{ + va_list args; + va_start(args, fmt); + vsnprintf(print_buf, PRINTF_BUF_SIZE, fmt, args); + normal_error(t,print_buf); + va_end(args); +} + +void formatted_warning(const char *t, const char *fmt, ...) +{ + va_list args; + va_start(args, fmt); + vsnprintf(print_buf, PRINTF_BUF_SIZE, fmt, args); + normal_warning(t,print_buf); + va_end(args); +} diff --git a/Build/source/texk/web2c/luatexdir/tex/expand.h b/Build/source/texk/web2c/luatexdir/tex/expand.h index 713901986a3..18c0514e317 100644 --- a/Build/source/texk/web2c/luatexdir/tex/expand.h +++ b/Build/source/texk/web2c/luatexdir/tex/expand.h @@ -1,5 +1,5 @@ /* expand.h - + Copyright 2009 Taco Hoekwater <taco@luatex.org> This file is part of LuaTeX. @@ -24,7 +24,8 @@ extern boolean is_in_csname; extern void expand(void); extern void complain_missing_csname(void); -extern void manufacture_csname(void); +extern void manufacture_csname(boolean use); +extern void inject_last_tested_cs(void); extern void insert_relax(void); extern void get_x_token(void); extern void x_token(void); diff --git a/Build/source/texk/web2c/luatexdir/tex/expand.w b/Build/source/texk/web2c/luatexdir/tex/expand.w index 098b6808373..46c8622b491 100644 --- a/Build/source/texk/web2c/luatexdir/tex/expand.w +++ b/Build/source/texk/web2c/luatexdir/tex/expand.w @@ -221,7 +221,13 @@ void expand(void) break; case cs_name_cmd: /* Manufacture a control sequence name; */ - manufacture_csname(); + if (cur_chr == 0) { + manufacture_csname(0); + } else if (cur_chr == 1) { + inject_last_tested_cs(); + } else { + manufacture_csname(1); + } break; case convert_cmd: conv_toks(); /* this procedure is discussed in Part 27 below */ @@ -229,6 +235,9 @@ void expand(void) case the_cmd: ins_the_toks(); /* this procedure is discussed in Part 27 below */ break; + case combine_toks_cmd: + combine_the_toks(cur_chr); + break; case if_test_cmd: conditional(); /* this procedure is discussed in Part 28 below */ break; @@ -320,7 +329,7 @@ void complain_missing_csname(void) } @ @c -void manufacture_csname(void) +void manufacture_csname(boolean use) { halfword p, q, r; lstring *ss; @@ -339,22 +348,50 @@ void manufacture_csname(void) /* Look up the characters of list |r| in the hash table, and set |cur_cs| */ ss = tokenlist_to_lstring(r, true); is_in_csname -= 1; - if (ss->l > 0) { - no_new_control_sequence = false; - cur_cs = string_lookup((char *) ss->s, ss->l); - no_new_control_sequence = true; + if (use) { + if (ss->l > 0) { + cur_cs = string_lookup((char *) ss->s, ss->l); + } else { + cur_cs = null_cs; + } + last_cs_name = cur_cs ; + free_lstring(ss); + flush_list(r); + if (cur_cs == null_cs) { + /* skip */ + } else if (eq_type(cur_cs) == undefined_cs_cmd) { + /* skip */ + } else { + cur_tok = cur_cs + cs_token_flag; + back_input(); + } } else { - cur_cs = null_cs; /* the list is empty */ + if (ss->l > 0) { + no_new_control_sequence = false; + cur_cs = string_lookup((char *) ss->s, ss->l); + no_new_control_sequence = true; + } else { + cur_cs = null_cs; /* the list is empty */ + } + last_cs_name = cur_cs ; + free_lstring(ss); + flush_list(r); + if (eq_type(cur_cs) == undefined_cs_cmd) { + eq_define(cur_cs, relax_cmd, too_big_char); /* N.B.: The |save_stack| might change */ + }; /* the control sequence will now match `\.{\\relax}' */ + cur_tok = cur_cs + cs_token_flag; + back_input(); } - free_lstring(ss); - flush_list(r); - if (eq_type(cur_cs) == undefined_cs_cmd) { - eq_define(cur_cs, relax_cmd, too_big_char); /* N.B.: The |save_stack| might change */ - }; /* the control sequence will now match `\.{\\relax}' */ - cur_tok = cur_cs + cs_token_flag; - back_input(); } +void inject_last_tested_cs(void) +{ + if (last_cs_name != null_cs) { + cur_cs = last_cs_name; + cur_tok = last_cs_name + cs_token_flag; + back_input(); + } +} @ Sometimes the expansion looks too far ahead, so we want to insert a harmless \.{\\relax} into the user's input. @@ -378,7 +415,7 @@ common cases. void get_x_token(void) { /* sets |cur_cmd|, |cur_chr|, |cur_tok|, and expands macros */ RESTART: - get_next(); /* get_token_lua(); */ + get_next(); if (cur_cmd <= max_command_cmd) goto DONE; if (cur_cmd >= call_cmd) { @@ -409,7 +446,7 @@ void x_token(void) { /* |get_x_token| without the initial |get_next| */ while (cur_cmd > max_command_cmd) { expand(); - get_next(); /* get_token_lua(); */ + get_next(); } if (cur_cs == 0) cur_tok = token_val(cur_cmd, cur_chr); @@ -750,9 +787,10 @@ void macro_call(void) /* Before we put a new token list on the input stack, it is wise to clean off all token lists that have recently been depleted. Then a user macro that ends with a call to itself will not require unbounded stack space. */ - while ((istate == token_list) && (iloc == null) - && (token_type != v_template)) - end_token_list(); /* conserve stack space */ + while ((istate == token_list) && (iloc == null) && (token_type != v_template)) { + /* conserve stack space */ + end_token_list(); + } begin_token_list(ref_count, macro); iname = warning_index; iloc = token_link(r); diff --git a/Build/source/texk/web2c/luatexdir/tex/extensions.h b/Build/source/texk/web2c/luatexdir/tex/extensions.h index 4909b9b95f6..01a75b7e387 100644 --- a/Build/source/texk/web2c/luatexdir/tex/extensions.h +++ b/Build/source/texk/web2c/luatexdir/tex/extensions.h @@ -44,13 +44,6 @@ extern halfword write_loc; extern void do_extension(int immediate); -extern int pdf_last_annot; -extern int pdf_last_link; -extern int pdf_last_obj; -extern int pdf_retval; - -/* Three extra node types carry information from |main_control|. */ - /* User defined whatsits can be inserted into node lists to pass data along from one lua call to another without interference from the @@ -59,7 +52,6 @@ type of the value depends on the |user_node_type| field. */ extern void new_whatsit(int s); -extern void scan_pdf_ext_toks(void); extern halfword concat_tokens(halfword q, halfword r); diff --git a/Build/source/texk/web2c/luatexdir/tex/extensions.w b/Build/source/texk/web2c/luatexdir/tex/extensions.w index 37736cc5a1a..0e178f01516 100644 --- a/Build/source/texk/web2c/luatexdir/tex/extensions.w +++ b/Build/source/texk/web2c/luatexdir/tex/extensions.w @@ -152,7 +152,7 @@ static void do_extension_pdf(int immediate) set_pdf_literal_mode(tail, direct_page); else set_pdf_literal_mode(tail, set_origin); - scan_pdf_ext_toks(); + scan_toks(false, true); set_pdf_literal_type(tail, normal); set_pdf_literal_data(tail, def_ref); } else if (scan_keyword("dest")) { @@ -165,7 +165,7 @@ static void do_extension_pdf(int immediate) new_whatsit(pdf_restore_node); } else if (scan_keyword("setmatrix")) { new_whatsit(pdf_setmatrix_node); - scan_pdf_ext_toks(); + scan_toks(false, true); set_pdf_setmatrix_data(tail, def_ref); } else if (scan_keyword("obj")) { scan_obj(static_pdf); @@ -211,7 +211,7 @@ static void do_extension_pdf(int immediate) set_pdf_colorstack_cmd(tail, i); set_pdf_colorstack_data(tail, null); if (i <= colorstack_data) { - scan_pdf_ext_toks(); + scan_toks(false, true); set_pdf_colorstack_data(tail, def_ref); } } else { @@ -251,30 +251,30 @@ static void do_extension_pdf(int immediate) i = cur_val; if (i == null_font) normal_error("pdf backend", "invalid font identifier"); - scan_pdf_ext_toks(); + scan_toks(false, true); set_pdf_font_attr(i, tokens_to_string(def_ref)); if (str_length(pdf_font_attr(i)) == 0) { flush_str((str_ptr - 1)); /* from |tokens_to_string| */ set_pdf_font_attr(i, 0); } } else if (scan_keyword("mapfile")) { - scan_pdf_ext_toks(); + scan_toks(false, true); pdfmapfile(def_ref); delete_token_ref(def_ref); } else if (scan_keyword("mapline")) { - scan_pdf_ext_toks(); + scan_toks(false, true); pdfmapline(def_ref); delete_token_ref(def_ref); } else if (scan_keyword("includechars")) { pdf_include_chars(static_pdf); } else if (scan_keyword("info")) { - scan_pdf_ext_toks(); + scan_toks(false, true); pdf_info_toks = concat_tokens(pdf_info_toks, def_ref); } else if (scan_keyword("names")) { - scan_pdf_ext_toks(); + scan_toks(false, true); pdf_names_toks = concat_tokens(pdf_names_toks, def_ref); } else if (scan_keyword("trailer")) { - scan_pdf_ext_toks(); + scan_toks(false, true); pdf_trailer_toks = concat_tokens(pdf_trailer_toks, def_ref); } else { tex_error("unexpected use of \\pdfextension",null); @@ -463,8 +463,7 @@ and appends it to the current list. @c void new_whatsit(int s) { - halfword p; /* the new node */ - p = new_node(whatsit_node, s); + halfword p = new_node(whatsit_node, s); couple_nodes(tail, p); tail = p; } @@ -482,11 +481,10 @@ single page, the stack would overflow. void expand_macros_in_tokenlist(halfword p) { - int old_mode; /* saved |mode| */ - pointer q, r; /* temporary variables for list manipulation */ - q = get_avail(); + int old_mode; + pointer q = get_avail(); + pointer r = get_avail(); token_info(q) = right_brace_token + '}'; - r = get_avail(); token_link(q) = r; token_info(r) = end_write_token; begin_token_list(q, inserted); @@ -588,22 +586,6 @@ boolean open_write_file(int id, char *fn) { } } -@ We have to check whether \.{\\outputmode} is set for using \pdfTeX{} - extensions. - -@c -void scan_pdf_ext_toks(void) -{ - (void) scan_toks(false, true); /* like \.{\\special} */ -} - -@ the pdflast* need extra global variables - -@c -int pdf_last_annot; -int pdf_last_link; -int pdf_last_obj; -int pdf_retval; /* global multi-purpose return value */ @ To implement primitives as \.{\\pdfextension info}, \.{\\pdfextension catalog} or \.{\\pdfextension names} we need to concatenate tokens lists. @@ -644,58 +626,58 @@ the name corresponding to |cur_group|. void print_group(boolean e) { switch (cur_group) { - case bottom_level: - tprint("bottom level"); - return; - break; - case simple_group: - case semi_simple_group: - if (cur_group == semi_simple_group) - tprint("semi "); - tprint("simple"); - break;; - case hbox_group: - case adjusted_hbox_group: - if (cur_group == adjusted_hbox_group) - tprint("adjusted "); - tprint("hbox"); - break; - case vbox_group: - tprint("vbox"); - break; - case vtop_group: - tprint("vtop"); - break; - case align_group: - case no_align_group: - if (cur_group == no_align_group) - tprint("no "); - tprint("align"); - break; - case output_group: - tprint("output"); - break; - case disc_group: - tprint("disc"); - break; - case insert_group: - tprint("insert"); - break; - case vcenter_group: - tprint("vcenter"); - break; - case math_group: - case math_choice_group: - case math_shift_group: - case math_left_group: - tprint("math"); - if (cur_group == math_choice_group) - tprint(" choice"); - else if (cur_group == math_shift_group) - tprint(" shift"); - else if (cur_group == math_left_group) - tprint(" left"); - break; + case bottom_level: + tprint("bottom level"); + return; + break; + case simple_group: + case semi_simple_group: + if (cur_group == semi_simple_group) + tprint("semi "); + tprint("simple"); + break;; + case hbox_group: + case adjusted_hbox_group: + if (cur_group == adjusted_hbox_group) + tprint("adjusted "); + tprint("hbox"); + break; + case vbox_group: + tprint("vbox"); + break; + case vtop_group: + tprint("vtop"); + break; + case align_group: + case no_align_group: + if (cur_group == no_align_group) + tprint("no "); + tprint("align"); + break; + case output_group: + tprint("output"); + break; + case disc_group: + tprint("disc"); + break; + case insert_group: + tprint("insert"); + break; + case vcenter_group: + tprint("vcenter"); + break; + case math_group: + case math_choice_group: + case math_shift_group: + case math_left_group: + tprint("math"); + if (cur_group == math_choice_group) + tprint(" choice"); + else if (cur_group == math_shift_group) + tprint(" shift"); + else if (cur_group == math_left_group) + tprint(" left"); + break; } /* there are no other cases */ tprint(" group (level "); print_int(cur_level); @@ -751,12 +733,10 @@ synchronized with the |in_open| variable indexing |grp_stack|. @c void group_warning(void) { - int i; /* index into |grp_stack| */ - boolean w; /* do we need a warning? */ + boolean w = false; /* do we need a warning? */ + int i = in_open; /* index into |grp_stack| */ base_ptr = input_ptr; input_stack[base_ptr] = cur_input; /* store current state */ - i = in_open; - w = false; while ((grp_stack[i] == cur_boundary) && (i > 0)) { /* Set variable |w| to indicate if this case should be reported */ /* This code scans the input stack in order to determine the type of the @@ -792,12 +772,10 @@ give a warning message (with the same complications as above). @c void if_warning(void) { - int i; /* index into |if_stack| */ - boolean w; /* do we need a warning? */ + boolean w = false; /* do we need a warning? */ + int i = in_open; base_ptr = input_ptr; input_stack[base_ptr] = cur_input; /* store current state */ - i = in_open; - w = false; while (if_stack[i] == cond_ptr) { /* Set variable |w| to... */ if (tracing_nesting > 0) { @@ -832,13 +810,10 @@ file are still incomplete. @c void file_warning(void) { - halfword p; /* saved value of |save_ptr| or |cond_ptr| */ - int l; /* saved value of |cur_level| or |if_limit| */ - int c; /* saved value of |cur_group| or |cur_if| */ - int i; /* saved value of |if_line| */ - p = save_ptr; - l = cur_level; - c = cur_group; + halfword p = save_ptr; /* saved value of |save_ptr| or |cond_ptr| */ + int l = cur_level; /* saved value of |cur_level| or |if_limit| */ + int c = cur_group; /* saved value of |cur_group| or |cur_if| */ + int i; /* saved value of |if_line| */ save_ptr = cur_boundary; while (grp_stack[in_open] != save_ptr) { decr(cur_level); @@ -999,8 +974,7 @@ int set_tex_attribute_register(int j, scaled v) int get_tex_toks_register(int j) { - str_number s; - s = get_nullstr(); + str_number s = get_nullstr(); if (toks(j) != null) { s = tokens_to_string(toks(j)); } @@ -1009,9 +983,8 @@ int get_tex_toks_register(int j) int set_tex_toks_register(int j, lstring s) { - halfword ref; int a; - ref = get_avail(); + halfword ref = get_avail(); (void) str_toks(s); set_token_ref_count(ref, 0); set_token_link(ref, token_link(temp_token_head)); @@ -1025,9 +998,8 @@ int set_tex_toks_register(int j, lstring s) int scan_tex_toks_register(int j, int c, lstring s) { - halfword ref; int a; - ref = get_avail(); + halfword ref = get_avail(); (void) str_scan_toks(c,s); set_token_ref_count(ref, 0); set_token_link(ref, token_link(temp_token_head)); diff --git a/Build/source/texk/web2c/luatexdir/tex/inputstack.h b/Build/source/texk/web2c/luatexdir/tex/inputstack.h index 390fb169198..378fabe24b8 100644 --- a/Build/source/texk/web2c/luatexdir/tex/inputstack.h +++ b/Build/source/texk/web2c/luatexdir/tex/inputstack.h @@ -1,5 +1,5 @@ /* inputstack.h - + Copyright 2009 Taco Hoekwater <taco@luatex.org> This file is part of LuaTeX. @@ -24,7 +24,7 @@ /* The state of \TeX's input mechanism appears in the input stack, whose entries are records with six fields, called |state|, |index|, |start|, |loc|, - |limit|, and |name|. + |limit|, and |name|. */ typedef struct in_state_record { @@ -273,7 +273,7 @@ the text expansion of a \.{\\count} or similar variable; \yskip\noindent The codes for |output_text|, |every_par_text|, etc., are equal to a constant plus the corresponding codes for token list parameters |output_routine_loc|, -|every_par_loc|, etc. +|every_par_loc|, etc. The token list begins with a reference count if and only if |token_type>=macro|. @@ -319,18 +319,13 @@ extern int base_ptr; extern void show_context(void); extern void set_trick_count(void); -/* leave an input level, re-enter the old */ -# define pop_input() cur_input=input_stack[--input_ptr] - -extern void push_input(void); - # define back_list(A) begin_token_list(A,backed_up) /* backs up a simple token list */ # define ins_list(A) begin_token_list(A,inserted) /* inserts a simple token list */ extern void begin_token_list(halfword p, quarterword t); extern void end_token_list(void); extern void back_input(void); -extern int reinsert_token(boolean a, halfword pp); +extern void reinsert_token(boolean a, halfword pp); extern void begin_file_reading(void); extern void end_file_reading(void); extern void clear_for_error_prompt(void); diff --git a/Build/source/texk/web2c/luatexdir/tex/inputstack.w b/Build/source/texk/web2c/luatexdir/tex/inputstack.w index aaeec71e65f..273863d2042 100644 --- a/Build/source/texk/web2c/luatexdir/tex/inputstack.w +++ b/Build/source/texk/web2c/luatexdir/tex/inputstack.w @@ -19,14 +19,12 @@ @ @c - #include "ptexlib.h" @ @c #define end_line_char int_par(end_line_char_code) #define error_context_lines int_par(error_context_lines_code) - in_state_record *input_stack = NULL; int input_ptr = 0; /* first unused location of |input_stack| */ int max_in_stack = 0; /* largest value of |input_ptr| when pushing */ @@ -46,15 +44,13 @@ int scanner_status = 0; /* can a subfile end now? */ pointer warning_index = null; /* identifier relevant to non-|normal| scanner status */ pointer def_ref = null; /* reference count of token list being defined */ - - @ Here is a procedure that uses |scanner_status| to print a warning message when a subfile has ended, and at certain other crucial times: @c void runaway(void) { - pointer p = null; /* head of runaway list */ + pointer p = null; /* head of runaway list */ if (scanner_status > skipping) { switch (scanner_status) { case defining: @@ -73,7 +69,8 @@ void runaway(void) tprint_nl("Runaway text"); p = def_ref; break; - default: /* there are no other cases */ + default: + /* there are no other cases */ break; } print_char('?'); @@ -82,7 +79,6 @@ void runaway(void) } } - @ The |param_stack| is an auxiliary array used to hold pointers to the token lists for parameters at the current level and subsidiary levels of input. This stack is maintained with convention (2), and it grows at a different @@ -106,7 +102,6 @@ $v_j$ template begins when a tab mark or \.{\\cr} occurs at a time that @c int align_state = 0; /* group level with respect to current alignment */ - @ Thus, the ``current input state'' can be very complicated indeed; there can be many levels and each level can arise in a variety of ways. The |show_context| procedure, which is used by \TeX's error-reporting routine to @@ -118,7 +113,6 @@ displayed by this procedure. @c int base_ptr = 0; /* shallowest level shown by |show_context| */ - @ The status at each level is indicated by printing two lines, where the first line indicates what was read so far and the second line shows what remains to be read. The context is cropped, if necessary, so that the first line @@ -130,66 +124,66 @@ at most |error_line|. Non-current input levels whose |token_type| is static void print_token_list_type(int t) { switch (t) { - case parameter: - tprint_nl("<argument> "); - break; - case u_template: - case v_template: - tprint_nl("<template> "); - break; - case backed_up: - if (iloc == null) - tprint_nl("<recently read> "); - else - tprint_nl("<to be read again> "); - break; - case inserted: - tprint_nl("<inserted text> "); - break; - case macro: - print_ln(); - print_cs(iname); - break; - case output_text: - tprint_nl("<output> "); - break; - case every_par_text: - tprint_nl("<everypar> "); - break; - case every_math_text: - tprint_nl("<everymath> "); - break; - case every_display_text: - tprint_nl("<everydisplay> "); - break; - case every_hbox_text: - tprint_nl("<everyhbox> "); - break; - case every_vbox_text: - tprint_nl("<everyvbox> "); - break; - case every_job_text: - tprint_nl("<everyjob> "); - break; - case every_cr_text: - tprint_nl("<everycr> "); - break; - case mark_text: - tprint_nl("<mark> "); - break; - case every_eof_text: - tprint_nl("<everyeof> "); - break; - case write_text: - tprint_nl("<write> "); - break; - default: - tprint_nl("?"); - break; /* this should never happen */ + case parameter: + tprint_nl("<argument> "); + break; + case u_template: + case v_template: + tprint_nl("<template> "); + break; + case backed_up: + if (iloc == null) + tprint_nl("<recently read> "); + else + tprint_nl("<to be read again> "); + break; + case inserted: + tprint_nl("<inserted text> "); + break; + case macro: + print_ln(); + print_cs(iname); + break; + case output_text: + tprint_nl("<output> "); + break; + case every_par_text: + tprint_nl("<everypar> "); + break; + case every_math_text: + tprint_nl("<everymath> "); + break; + case every_display_text: + tprint_nl("<everydisplay> "); + break; + case every_hbox_text: + tprint_nl("<everyhbox> "); + break; + case every_vbox_text: + tprint_nl("<everyvbox> "); + break; + case every_job_text: + tprint_nl("<everyjob> "); + break; + case every_cr_text: + tprint_nl("<everycr> "); + break; + case mark_text: + tprint_nl("<mark> "); + break; + case every_eof_text: + tprint_nl("<everyeof> "); + break; + case write_text: + tprint_nl("<write> "); + break; + default: + tprint_nl("?"); + /* this should never happen */ + break; } } - @ Here it is necessary to explain a little trick. We don't want to store a long string that corresponds to a token list, because that string might take up lots of memory; and we are printing during a time when an error message is @@ -220,8 +214,6 @@ second line consists of |n|~spaces followed by |trick_buf[k..(k+m-1)]|, unless |n+m>error_line|; in the latter case, further cropping is done. This is easier to program than to explain. - - @ The following code sets up the print routines so that they will gather the desired information. @@ -259,7 +251,7 @@ void set_trick_count(void) /* We don't care too much if we stay a bit too much below the max error_line even if we have more room on the line. If length is really an issue then - any length is. After all on can set the length larger. + any length is. After all one can set the length larger. */ #define print_valid_utf8(q) do { \ @@ -287,44 +279,40 @@ void set_trick_count(void) @ @c void show_context(void) -{ /* prints where the scanner is */ - int old_setting; /* saved |selector| setting */ - int nn; /* number of contexts shown so far, less one */ - boolean bottom_line; /* have we reached the final context to be shown? */ - int i; /* index into |buffer| */ - int j; /* end of current line in |buffer| */ - int l; /* length of descriptive information on line 1 */ - int m; /* context information gathered for line 2 */ - int n; /* length of line 1 */ - int p; /* starting or ending place in |trick_buf| */ - int q; /* temporary index */ - int c; /* used in sanitizer */ - +{ /* prints where the scanner is */ + int old_setting; /* saved |selector| setting */ + int nn = -1; /* number of contexts shown so far, less one */ + boolean bottom_line = false; /* have we reached the final context to be shown? */ + int i; /* index into |buffer| */ + int j; /* end of current line in |buffer| */ + int l; /* length of descriptive information on line 1 */ + int m; /* context information gathered for line 2 */ + int n; /* length of line 1 */ + int p; /* starting or ending place in |trick_buf| */ + int q; /* temporary index */ + int c; /* used in sanitizer */ base_ptr = input_ptr; input_stack[base_ptr] = cur_input; /* store current state */ - nn = -1; - bottom_line = false; while (true) { cur_input = input_stack[base_ptr]; /* enter into the context */ if (istate != token_list) { if ((iname > 21) || (base_ptr == 0)) bottom_line = true; } - if ((base_ptr == input_ptr) || bottom_line - || (nn < error_context_lines)) { + if ((base_ptr == input_ptr) || bottom_line || (nn < error_context_lines)) { /* Display the current context */ - if ((base_ptr == input_ptr) || (istate != token_list) || - (token_type != backed_up) || (iloc != null)) { + if ((base_ptr == input_ptr) || (istate != token_list) || (token_type != backed_up) || (iloc != null)) { /* we omit backed-up token lists that have already been read */ tally = 0; /* get ready to count characters */ old_setting = selector; if (istate != token_list) { - /* Print location of current line */ /* - This routine should be changed, if necessary, to give the best possible - indication of where the current line resides in the input file. - For example, on some systems it is best to print both a page and line number. + Print location of current line + + This routine should be changed, if necessary, to give the best possible + indication of where the current line resides in the input file. For example, + on some systems it is best to print both a page and line number. */ if (iname <= 17) { if (terminal_input) { @@ -359,7 +347,8 @@ void show_context(void) else show_token_list(token_link(istart), iloc, 100000); /* avoid reference count */ } - selector = old_setting; /* stop pseudoprinting */ + /* stop pseudoprinting */ + selector = old_setting; /* Print two lines using the tricky pseudoprinted information */ if (trick_count == 1000000) set_trick_count(); @@ -379,8 +368,9 @@ void show_context(void) for (q = p; q <= first_count - 1; q++) print_valid_utf8(q); print_ln(); + /* print |n| spaces to begin line~2 */ for (q = 1; q <= n; q++) - print_char(' '); /* print |n| spaces to begin line~2 */ + print_char(' '); if (m + n <= error_line) p = first_count + m; else @@ -389,40 +379,42 @@ void show_context(void) print_valid_utf8(q); if (m + n > error_line) tprint("..."); - incr(nn); } } else if (nn == error_context_lines) { tprint_nl("..."); - incr(nn); /* omitted if |error_context_lines<0| */ + incr(nn); + /* omitted if |error_context_lines<0| */ } if (bottom_line) break; decr(base_ptr); } - cur_input = input_stack[input_ptr]; /* restore original state */ + /* restore original state */ + cur_input = input_stack[input_ptr]; } - @ The following subroutines change the input status in commonly needed ways. First comes |push_input|, which stores the current state and creates a new level (having, initially, the same properties as the old). @c + /* enter a new input level, save the old */ -void push_input(void) -{ - if (input_ptr > max_in_stack) { - max_in_stack = input_ptr; - if (input_ptr == stack_size) - overflow("input stack size", (unsigned) stack_size); - } - input_stack[input_ptr] = cur_input; /* stack the record */ - nofilter = false; +# define pop_input() \ + cur_input=input_stack[--input_ptr] + +# define push_input() \ + if (input_ptr > max_in_stack) { \ + max_in_stack = input_ptr; \ + if (input_ptr == stack_size) \ + overflow("input stack size", (unsigned) stack_size); \ + } \ + input_stack[input_ptr] = cur_input; \ + nofilter = false; \ incr(input_ptr); -} @ Here is a procedure that starts a new level of token-list input, given @@ -436,7 +428,8 @@ void begin_token_list(halfword p, quarterword t) istate = token_list; istart = p; token_type = (unsigned char) t; - if (t >= macro) { /* the token list starts with a reference count */ + if (t >= macro) { + /* the token list starts with a reference count */ add_token_ref(p); if (t == macro) { param_start = param_ptr; @@ -462,7 +455,6 @@ void begin_token_list(halfword p, quarterword t) } } - @ When a token list has been fully scanned, the following computations should be done as we leave that level of input. The |token_type| tends to be equal to either |backed_up| or |inserted| about 2/3 of the time. @@ -470,13 +462,17 @@ to be equal to either |backed_up| or |inserted| about 2/3 of the time. @c void end_token_list(void) -{ /* leave a token-list input level */ - if (token_type >= backed_up) { /* token list to be deleted */ +{ + /* leave a token-list input level */ + if (token_type >= backed_up) { + /* token list to be deleted */ if (token_type <= inserted) { flush_list(istart); } else { - delete_token_ref(istart); /* update reference count */ - if (token_type == macro) { /* parameters must be flushed */ + /* update reference count */ + delete_token_ref(istart); + if (token_type == macro) { + /* parameters must be flushed */ while (param_ptr > param_start) { decr(param_ptr); flush_list(param_stack[param_ptr]); @@ -493,7 +489,6 @@ void end_token_list(void) check_interrupt(); } - @ Sometimes \TeX\ has read too far and wants to ``unscan'' what it has seen. The |back_input| procedure takes care of this by putting the token just scanned back into the input stream, ready to be read again. This @@ -503,12 +498,16 @@ so it has been slightly optimized for speed. @^inner loop@> @c + +/* undoes one token of input */ + void back_input(void) -{ /* undoes one token of input */ - halfword p; /* a token list of length one */ - while ((istate == token_list) && (iloc == null) - && (token_type != v_template)) - end_token_list(); /* conserve stack space */ +{ + halfword p; /* a token list of length one */ + while ((istate == token_list) && (iloc == null) && (token_type != v_template)) { + /* conserve stack space */ + end_token_list(); + } p = get_avail(); set_token_info(p, cur_tok); if (cur_tok < right_brace_limit) { @@ -526,7 +525,8 @@ void back_input(void) @ Insert token |p| into \TeX's input @c -int reinsert_token(boolean a, halfword pp) + +void reinsert_token(boolean a, halfword pp) { halfword t; t = cur_tok; @@ -546,13 +546,10 @@ int reinsert_token(boolean a, halfword pp) } } else { back_input(); - a = true; /* etex is always on */ } cur_tok = t; - return a; } - @ The |begin_file_reading| procedure starts a new level of input for lines of characters to be read from a file, or as an insertion from the terminal. It does not take care of opening the file, nor does it set |loc| @@ -584,7 +581,6 @@ void begin_file_reading(void) synctex_tag = 0; } - @ Conversely, the variables must be downdated when such a level of input is finished: @@ -603,7 +599,6 @@ void end_file_reading(void) decr(in_open); } - @ In order to keep the stack from overflowing during a long sequence of inserted `\.{\\show}' commands, the following routine removes completed error-inserted lines from memory. @@ -618,8 +613,7 @@ void clear_for_error_prompt(void) clear_terminal(); } -@ To get \TeX's whole input mechanism going, we perform the following - actions. +@ To get \TeX's whole input mechanism going, we perform the following actions. @c void initialize_inputstack(void) @@ -662,9 +656,6 @@ void initialize_inputstack(void) first = last + 1; /* |init_terminal| has set |loc| and |last| */ } - - - @ The global variable |pseudo_files| is used to maintain a stack of pseudo files. The |pseudo_lines| field of each pseudo file points to a linked list of variable size nodes representing lines not yet @@ -672,7 +663,7 @@ processed: the |subtype| field contains the size of this node, all the following words contain ASCII codes. @c -halfword pseudo_files; /* stack of pseudo files */ +halfword pseudo_files; /* stack of pseudo files */ static halfword string_to_pseudo(str_number str, int nl) { @@ -685,7 +676,7 @@ static halfword string_to_pseudo(str_number str, int nl) len = (unsigned) str_length(str); l = 0; while (l < len) { - unsigned m = l; /* start of current line */ + unsigned m = l; /* start of current line */ while ((l < len) && (s[l] != nl)) l++; sz = (int) (l - m + 7) / 4; @@ -718,14 +709,13 @@ static halfword string_to_pseudo(str_number str, int nl) return h; } - @ The |pseudo_start| procedure initiates reading from a pseudo file. @c void pseudo_from_string(void) { - str_number s; /* string to be converted into a pseudo file */ - halfword p; /* for list construction */ + str_number s; /* string to be converted into a pseudo file */ + halfword p; /* for list construction */ s = make_string(); /* Convert string |s| into a new pseudo file */ p = string_to_pseudo(s, int_par(new_line_char_code)); @@ -733,10 +723,10 @@ void pseudo_from_string(void) pseudo_files = p; flush_str(s); /* Initiate input from new pseudo file */ - begin_file_reading(); /* set up |cur_file| and new level of input */ + begin_file_reading(); /* set up |cur_file| and new level of input */ line = 0; ilimit = istart; - iloc = ilimit + 1; /* force line read */ + iloc = ilimit + 1; /* force line read */ if (int_par(tracing_scan_tokens_code) > 0) { if (term_offset > max_print_line - 3) print_ln(); @@ -755,7 +745,7 @@ void pseudo_from_string(void) void pseudo_start(void) { - int old_setting; /* holds |selector| setting */ + int old_setting; scan_general_text(); old_setting = selector; selector = new_string; @@ -769,10 +759,10 @@ void pseudo_start(void) @ @c void lua_string_start(void) { - begin_file_reading(); /* set up |cur_file| and new level of input */ + begin_file_reading(); /* set up |cur_file| and new level of input */ line = 0; ilimit = istart; - iloc = ilimit + 1; /* force line read */ + iloc = ilimit + 1; /* force line read */ iname = 21; luacstring_start(iindex); } @@ -780,13 +770,15 @@ void lua_string_start(void) @ Here we read a line from the current pseudo file into |buffer|. @c +/* inputs the next line or returns |false| */ + boolean pseudo_input(void) -{ /* inputs the next line or returns |false| */ - halfword p; /* current line from pseudo file */ - int sz; /* size of node |p| */ - four_quarters w; /* four ASCII codes */ - halfword r; /* loop index */ - last = first; /* cf.\ Matthew 19\thinspace:\thinspace30 */ +{ + halfword p; /* current line from pseudo file */ + int sz; /* size of node |p| */ + four_quarters w; /* four ASCII codes */ + halfword r; /* loop index */ + last = first; /* cf.\ Matthew 19\thinspace:\thinspace30 */ p = pseudo_lines(pseudo_files); if (p == null) { return false; @@ -798,7 +790,7 @@ boolean pseudo_input(void) last = first; for (r = p + 1; r <= p + sz - 1; r++) { w = varmem[r].qqqq; - buffer[last] = (packed_ASCII_code) w.b0; + buffer[last] = (packed_ASCII_code) w.b0; buffer[last + 1] = (packed_ASCII_code) w.b1; buffer[last + 2] = (packed_ASCII_code) w.b2; buffer[last + 3] = (packed_ASCII_code) w.b3; @@ -816,8 +808,10 @@ boolean pseudo_input(void) @ When we are done with a pseudo file we `close' it. @c +/* close the top level pseudo file */ + void pseudo_close(void) -{ /* close the top level pseudo file */ +{ halfword p; p = vlink(pseudo_files); flush_node(pseudo_files); diff --git a/Build/source/texk/web2c/luatexdir/tex/linebreak.h b/Build/source/texk/web2c/luatexdir/tex/linebreak.h index 9ac444b7a37..1b5d1da96ca 100644 --- a/Build/source/texk/web2c/luatexdir/tex/linebreak.h +++ b/Build/source/texk/web2c/luatexdir/tex/linebreak.h @@ -17,7 +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/>. */ - #ifndef LINEBREAK_H # define LINEBREAK_H @@ -83,21 +82,20 @@ extern halfword find_protchar_right(halfword l, halfword r); ) # define cp_skipable(a) ( (! is_char_node((a))) && ( \ - (type((a)) == ins_node) \ + ((type((a)) == glue_node) && (glue_ptr((a)) == zero_glue)) \ + || (type((a)) == penalty_node) \ + || ((type((a)) == disc_node) && empty_disc(a)) \ + || ((type((a)) == kern_node) && ((width((a)) == 0) || (subtype((a)) == normal))) \ + || ((type((a)) == rule_node) && zero_dimensions(a)) \ + || ((type((a)) == math_node) && (surround((a)) == 0)) \ + || (type((a)) == dir_node) \ + || ((type((a)) == hlist_node) && (list_ptr((a)) == null) && zero_dimensions(a)) \ + || (type((a)) == local_par_node) \ + || (type((a)) == ins_node) \ || (type((a)) == mark_node) \ || (type((a)) == adjust_node) \ - || (type((a)) == penalty_node) \ || (type((a)) == boundary_node) \ || (type((a)) == whatsit_node) \ - || (type((a)) == dir_node) \ - || (type((a)) == local_par_node) \ - || ((type((a)) == rule_node) && zero_dimensions(a)) \ - || ((type((a)) == disc_node) && empty_disc(a)) \ - || ((type((a)) == math_node) && (surround((a)) == 0)) \ - || ((type((a)) == kern_node) && ((width((a)) == 0) || (subtype((a)) == normal))) \ - || ((type((a)) == glue_node) && (glue_ptr((a)) == zero_glue)) \ - || ((type((a)) == hlist_node) && (list_ptr((a)) == null) && zero_dimensions(a)) \ ) ) - #endif diff --git a/Build/source/texk/web2c/luatexdir/tex/linebreak.w b/Build/source/texk/web2c/luatexdir/tex/linebreak.w index 90167e43938..3947abfa6cd 100644 --- a/Build/source/texk/web2c/luatexdir/tex/linebreak.w +++ b/Build/source/texk/web2c/luatexdir/tex/linebreak.w @@ -19,10 +19,8 @@ @ @c - #include "ptexlib.h" - @ We come now to what is probably the most interesting algorithm of \TeX: the mechanism for choosing the ``best possible'' breakpoints that yield the individual lines of a paragraph. \TeX's line-breaking algorithm takes @@ -75,7 +73,6 @@ line can be ascertained when it is necessary to decide whether to use @c halfword just_box; /* the |hlist_node| for the last line of the new paragraph */ - @ In it's complete form, |line_break| is a rather lengthy procedure---sort of a small world unto itself---we must build it up little by little. Below you see only the general outline. @@ -120,39 +117,16 @@ void line_break(boolean d, int line_break_context) final_par_glue = new_param_glue(par_fill_skip_code); couple_nodes(cur_list.tail_field, final_par_glue); cur_list.tail_field = vlink(cur_list.tail_field); -#ifdef DEBUG - { - int n = temp_head; - fprintf(stdout, "pre_linebreak_filter status:\n"); - while (n) { - fprintf(stdout, " %s node %d\n", - get_node_name(type(n), subtype(n)), (int) n); - n = vlink(n); - } - } -#endif lua_node_filter(pre_linebreak_filter_callback, - line_break_context, temp_head, + line_break_context, + temp_head, addressof(cur_list.tail_field)); last_line_fill = cur_list.tail_field; pop_nest(); start_of_par = cur_list.tail_field; -#ifdef DEBUG - { - int n = temp_head; - fprintf(stdout, "pre_linebreak_filter returned:\n"); - while (n) { - fprintf(stdout, " %s node %d\n", - get_node_name(type(n), subtype(n)), (int) n); - n = vlink(n); - } - } -#endif callback_id = callback_defined(linebreak_filter_callback); if (callback_id > 0) { - callback_id = - lua_linebreak_callback(d, temp_head, - addressof(cur_list.tail_field)); + callback_id = lua_linebreak_callback(d, temp_head, addressof(cur_list.tail_field)); if (callback_id > 0) { /* find the correct value for the |just_box| */ halfword box_search = cur_list.tail_field; @@ -182,10 +156,11 @@ void line_break(boolean d, int line_break_context) } } if (callback_id == 0) { - if ((!is_char_node(vlink(temp_head))) && ((type(vlink(temp_head)) == local_par_node))) + if ((!is_char_node(vlink(temp_head))) && ((type(vlink(temp_head)) == local_par_node))) { paragraph_dir = local_par_dir(vlink(temp_head)); - else - assert(0); /* |paragraph_dir = 0|; */ + } else { + confusion("weird par dir"); /* assert(0); */ /* |paragraph_dir = 0|; */ + } ext_do_line_break(paragraph_dir, int_par(pretolerance_code), int_par(tracing_paragraphs_code), @@ -220,7 +195,6 @@ void line_break(boolean d, int line_break_context) pack_begin_line = 0; } - @ Glue nodes in a horizontal list that is being paragraphed are not supposed to include ``infinite'' shrinkability; that is why the algorithm maintains four registers for stretching but only one for shrinking. If the user tries to @@ -229,9 +203,9 @@ void line_break(boolean d, int line_break_context) prevents this error message from appearing more than once per paragraph. @c -#define check_shrinkage(a) \ - if ((shrink_order((a))!=normal)&&(shrink((a))!=0)) \ - a=finite_shrink((a)) +#define check_shrinkage(a) \ + if ((shrink_order((a))!=normal)&&(shrink((a))!=0)) \ + a=finite_shrink((a)) static boolean no_shrink_error_yet; /*have we complained about infinite shrinkage? */ @@ -314,7 +288,6 @@ static int max_stretch_ratio = 0; /*maximal stretch ratio of expanded font static int max_shrink_ratio = 0; /*maximal shrink ratio of expanded fonts */ static int cur_font_step = 0; /*the current step of expanded fonts */ - static boolean check_expand_pars(internal_font_number f) { int m; @@ -391,18 +364,16 @@ static boolean check_expand_pars(internal_font_number f) return l; } - @ searches right to left from list tail |r| to head |l|, returns 1st non-skipable item @c /*public*/ halfword find_protchar_right(halfword l, halfword r) { halfword t; - boolean run; + boolean run = true; if (r == null) return null; hlist_stack_level = 0; - run = true; do { t = r; while (run && (type(r) == hlist_node) && (list_ptr(r) != null)) { @@ -538,7 +509,6 @@ static halfword passive; /* most recent node on passive list */ static halfword printed_node; /*most recent node that has been printed */ static halfword pass_number; /*the number of passive nodes allocated on this pass */ - @ The active list also contains ``delta'' nodes that help the algorithm compute the badness of individual lines. Such nodes appear only between two active nodes, and they have |type=delta_node|. If |p| and |r| are active nodes @@ -557,7 +527,6 @@ is not used. Actually, we have two more fields that are used by |pdftex|. - As the algorithm runs, it maintains a set of seven delta-like registers for the length of the line following the first active breakpoint to the current position in the given hlist. When it makes a pass through the @@ -618,7 +587,6 @@ static boolean auto_breaking; /*make |auto_breaking| accessible out of |line_b will be used to calculate values of new delta nodes when the active list is being updated. - @ The heart of the line-breaking procedure is `|try_break|', a subroutine that tests if the current breakpoint |cur_p| is feasible, by running through the active list to see what lines of text can be made from active @@ -635,7 +603,6 @@ static boolean auto_breaking; /*make |auto_breaking| accessible out of |line_b end of a paragraph is also regarded as `|hyphenated_node|'; this case is distinguishable by the condition |cur_p=null|. - @c static int internal_pen_inter; /* running \.{\\localinterlinepenalty} */ static int internal_pen_broken; /* running \.{\\localbrokenpenalty} */ @@ -668,8 +635,6 @@ static int minimum_demerits; /* best total demerits known for current line cl static halfword best_place[4]; /* how to achieve |minimal_demerits| */ static halfword best_pl_line[4]; /*corresponding line number */ - - @ The length of lines depends on whether the user has specified \.{\\parshape} or \.{\\hangindent}. If |par_shape_ptr| is not null, it points to a $(2n+1)$-word record in |mem|, where the |vinfo| in the first @@ -687,23 +652,21 @@ Note that if |hang_indent=0|, the value of |hang_after| is irrelevant. @^length of lines@> @^hanging indentation@> @c -static halfword easy_line; /*line numbers |>easy_line| are equivalent in break nodes */ -static halfword last_special_line; /*line numbers |>last_special_line| all have the same width */ -static scaled first_width; /*the width of all lines |<=last_special_line|, if - no \.{\\parshape} has been specified */ -static scaled second_width; /*the width of all lines |>last_special_line| */ -static scaled first_indent; /*left margin to go with |first_width| */ -static scaled second_indent; /*left margin to go with |second_width| */ - -static halfword best_bet; /*use this passive node and its predecessors */ -static int fewest_demerits; /*the demerits associated with |best_bet| */ -static halfword best_line; /*line number following the last line of the new paragraph */ -static int actual_looseness; /*the difference between |line_number(best_bet)| - and the optimum |best_line| */ -static int line_diff; /*the difference between the current line number and - the optimum |best_line| */ - - +static halfword easy_line; /*line numbers |>easy_line| are equivalent in break nodes */ +static halfword last_special_line; /*line numbers |>last_special_line| all have the same width */ +static scaled first_width; /*the width of all lines |<=last_special_line|, if + no \.{\\parshape} has been specified */ +static scaled second_width; /*the width of all lines |>last_special_line| */ +static scaled first_indent; /*left margin to go with |first_width| */ +static scaled second_indent; /*left margin to go with |second_width| */ + +static halfword best_bet; /*use this passive node and its predecessors */ +static int fewest_demerits; /*the demerits associated with |best_bet| */ +static halfword best_line; /*line number following the last line of the new paragraph */ +static int actual_looseness; /*the difference between |line_number(best_bet)| + and the optimum |best_line| */ +static int line_diff; /*the difference between the current line number and + the optimum |best_line| */ @ \TeX\ makes use of the fact that |hlist_node|, |vlist_node|, |rule_node|, |ins_node|, |mark_node|, |adjust_node|, @@ -720,33 +683,46 @@ static int line_diff; /*the difference between the current line number #define store_background(a) {active_width[a]=background[a];} -#define kern_break() { \ - if ((!is_char_node(vlink(cur_p))) && auto_breaking) \ - if (type(vlink(cur_p))==glue_node) \ - ext_try_break(0,unhyphenated_node, line_break_dir, adjust_spacing, \ - par_shape_ptr, adj_demerits, \ - tracing_paragraphs, protrude_chars, \ - line_penalty, last_line_fit, \ - double_hyphen_demerits, final_hyphen_demerits,first_p,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() { \ - q=vlink(active); \ - while (q!=active) { \ - cur_p=vlink(q); \ - if (type(q)==delta_node) flush_node(q); \ - else flush_node(q); \ - q=cur_p; \ - } \ - q=passive; \ - while (q!=null) { \ - cur_p=vlink(q); \ - flush_node(q); \ - q=cur_p; \ - } \ - } +#define kern_break() { \ + if ((!is_char_node(vlink(cur_p))) && auto_breaking) \ + if (type(vlink(cur_p))==glue_node) \ + ext_try_break(0, \ + unhyphenated_node, \ + line_break_dir, \ + adjust_spacing, \ + par_shape_ptr, \ + adj_demerits, \ + tracing_paragraphs, \ + protrude_chars, \ + line_penalty, \ + last_line_fit, \ + double_hyphen_demerits, \ + final_hyphen_demerits, \ + first_p, \ + 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() { \ + q=vlink(active); \ + while (q!=active) { \ + cur_p = vlink(q); \ + if (type(q)==delta_node) \ + flush_node(q); \ + else \ + flush_node(q); \ + q = cur_p; \ + } \ + q = passive; \ + while (q!=null) { \ + cur_p = vlink(q); \ + flush_node(q); \ + q = cur_p; \ + } \ +} static boolean do_last_line_fit; /* special algorithm for last line of paragraph? */ static scaled fill_width[4]; /* infinite stretch components of |par_fill_skip| */ @@ -768,11 +744,9 @@ static scaled best_pl_glue[4]; /*corresponding glue stretch or shrink */ #define sub_kern_shrink(a,b) a -= kern_shrink((b)) #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. @@ -789,23 +763,23 @@ static void add_to_widths(halfword s, int line_break_dir, int adjust_spacing, sc }; } else { switch (type(s)) { - case hlist_node: - case vlist_node: - widths[1] += pack_width(line_break_dir, box_dir(s), s, false); - break; - case kern_node: - if ((adjust_spacing == 2) && (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: - confusion("invalid node found in discretionary"); /* todo: report type */ + case hlist_node: + case vlist_node: + widths[1] += pack_width(line_break_dir, box_dir(s), s, false); + break; + case kern_node: + if ((adjust_spacing == 2) && (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: + confusion("invalid node found in discretionary"); /* todo: report type */ } } s = vlink(s); @@ -831,31 +805,30 @@ static void sub_from_widths(halfword s, int line_break_dir, int adjust_spacing, } } else { switch (type(s)) { - case hlist_node: - case vlist_node: - widths[1] -= pack_width(line_break_dir, box_dir(s), s, false); - break; - case kern_node: - if ((adjust_spacing == 2) && (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: - confusion("invalid node found in discretionary"); /* todo: report type */ - break; + case hlist_node: + case vlist_node: + widths[1] -= pack_width(line_break_dir, box_dir(s), s, false); + break; + case kern_node: + if ((adjust_spacing == 2) && (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: + confusion("invalid node found in discretionary"); /* todo: report type */ + 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 @@ -876,12 +849,10 @@ static void sub_from_widths(halfword s, int line_break_dir, int adjust_spacing, Kern nodes do not disappear at a line break unless they are |explicit|. @c -static void -compute_break_width(int break_type, int line_break_dir, int adjust_spacing, halfword p) +static void compute_break_width(int break_type, int line_break_dir, int adjust_spacing, halfword p) { - halfword s; /* glue and other 'whitespace' to be skipped after a break - * used if unhyphenated, or |post_break==empty| */ - s = p; + halfword s = p; /* glue and other 'whitespace' to be skipped after a break; + used if unhyphenated, or |post_break==empty| */ if (break_type > unhyphenated_node && p != null) { /*Compute the discretionary |break_width| values; */ /* When |p| is a discretionary break, the length of a line @@ -921,43 +892,42 @@ compute_break_width(int break_type, int line_break_dir, int adjust_spacing, half } while (s != null) { switch (type(s)) { - case math_node: - /* begin mathskip code */ - if (math_skip == zero_glue) { - break_width[1] -= surround(s); + case math_node: + /* begin mathskip code */ + if (math_skip == zero_glue) { + break_width[1] -= surround(s); + break; + } else { + /* fall through */ + } + /* end mathskip code */ + case glue_node: + /*Subtract glue from |break_width|; */ + { + halfword v = glue_ptr(s); + break_width[1] -= width(v); + break_width[2 + stretch_order(v)] -= stretch(v); + break_width[7] -= shrink(v); + } break; - } else { - /* fall through */ - } - /* end mathskip code */ - case glue_node: - /*Subtract glue from |break_width|; */ - { - halfword v = glue_ptr(s); - break_width[1] -= width(v); - break_width[2 + stretch_order(v)] -= stretch(v); - break_width[7] -= shrink(v); - } - break; - case penalty_node: - break; - case kern_node: - if (subtype(s) != explicit) + case penalty_node: + break; + case kern_node: + if (subtype(s) != explicit) + return; + else + break_width[1] -= width(s); + break; + default: return; - else - break_width[1] -= width(s); - break; - default: - return; }; s = vlink(s); } } @ @c -static void -print_break_node(halfword q, fitness_value fit_class, - quarterword break_type, halfword cur_p) +static void print_break_node(halfword q, fitness_value fit_class, + quarterword break_type, halfword cur_p) { /* Print a symbolic description of the new break node */ tprint_nl("@@@@"); @@ -988,9 +958,8 @@ print_break_node(halfword q, fitness_value fit_class, } @ @c -static void -print_feasible_break(halfword cur_p, pointer r, halfword b, int pi, - int d, boolean artificial_demerits) +static void print_feasible_break(halfword cur_p, pointer r, halfword b, int pi, + int d, boolean artificial_demerits) { /* Print a symbolic description of this feasible break; */ if (printed_node != cur_p) { @@ -1046,15 +1015,15 @@ print_feasible_break(halfword cur_p, pointer r, halfword b, int pi, #define set_break_width_to_background(a) break_width[a]=background[(a)] -#define convert_to_break_width(a) \ +#define convert_to_break_width(a) \ varmem[(prev_r+(a))].cint = varmem[(prev_r+(a))].cint-cur_active_width[(a)]+break_width[(a)] -#define store_break_width(a) active_width[(a)]=break_width[(a)] +#define store_break_width(a) active_width[(a)]=break_width[(a)] -#define new_delta_to_break_width(a) \ +#define new_delta_to_break_width(a) \ varmem[(q+(a))].cint=break_width[(a)]-cur_active_width[(a)] -#define new_delta_from_break_width(a) \ +#define new_delta_from_break_width(a) \ varmem[(q+(a))].cint=cur_active_width[(a)]-break_width[(a)] #define copy_to_cur_active(a) cur_active_width[(a)]=active_width[(a)] @@ -1066,57 +1035,53 @@ print_feasible_break(halfword cur_p, pointer r, halfword b, int pi, #define total_font_stretch cur_active_width[8] #define total_font_shrink cur_active_width[9] -#define cal_margin_kern_var(a) { \ - character(cp) = character((a)); \ - font(cp) = font((a)); \ - do_subst_font(cp, 1000); \ - if (font(cp) != font((a))) \ - margin_kern_stretch += (left_pw((a)) - left_pw(cp)); \ - font(cp) = font((a)); \ - do_subst_font(cp, -1000); \ - if (font(cp) != font((a))) \ - margin_kern_shrink += (left_pw(cp) - left_pw((a))); \ - } - -static void -ext_try_break(int pi, - quarterword break_type, - int line_break_dir, - int adjust_spacing, - int par_shape_ptr, - int adj_demerits, - int tracing_paragraphs, - int protrude_chars, - int line_penalty, - int last_line_fit, - int double_hyphen_demerits, - int final_hyphen_demerits, halfword first_p, halfword cur_p) +#define cal_margin_kern_var(a) { \ + character(cp) = character((a)); \ + font(cp) = font((a)); \ + do_subst_font(cp, 1000); \ + if (font(cp) != font((a))) \ + margin_kern_stretch += (left_pw((a)) - left_pw(cp)); \ + font(cp) = font((a)); \ + do_subst_font(cp, -1000); \ + if (font(cp) != font((a))) \ + margin_kern_shrink += (left_pw(cp) - left_pw((a))); \ +} + +static void ext_try_break(int pi, + quarterword break_type, + int line_break_dir, + int adjust_spacing, + int par_shape_ptr, + int adj_demerits, + int tracing_paragraphs, + int protrude_chars, + int line_penalty, + int last_line_fit, + int double_hyphen_demerits, + int final_hyphen_demerits, halfword first_p, halfword cur_p) { /* labels: |CONTINUE,DEACTIVATE,FOUND,NOT_FOUND|; */ pointer r; /* runs through the active list */ scaled margin_kern_stretch; scaled margin_kern_shrink; halfword lp, rp, cp; - halfword prev_r; /* stays a step behind |r| */ - halfword prev_prev_r; /*a step behind |prev_r|, if |type(prev_r)=delta_node| */ - halfword old_l; /* maximum line number in current equivalence class of lines */ - boolean no_break_yet; /* have we found a feasible break at |cur_p|? */ - halfword q; /*points to a new node being created */ - halfword l; /*line number of current active node */ - boolean node_r_stays_active; /*should node |r| remain in the active list? */ - scaled line_width; /*the current line will be justified to this width */ - fitness_value fit_class; /*possible fitness class of test line */ - halfword b; /*badness of test line */ - int d; /*demerits of test line */ - boolean artificial_demerits; /*has |d| been forced to zero? */ + halfword prev_r = active; /* stays a step behind |r| */ + halfword prev_prev_r = null; /*a step behind |prev_r|, if |type(prev_r)=delta_node| */ + halfword old_l = 0; /* maximum line number in current equivalence class of lines */ + boolean no_break_yet = true; /* have we found a feasible break at |cur_p|? */ + halfword q; /*points to a new node being created */ + halfword l; /*line number of current active node */ + boolean node_r_stays_active; /*should node |r| remain in the active list? */ + scaled line_width = 0; /*the current line will be justified to this width */ + fitness_value fit_class; /*possible fitness class of test line */ + halfword b; /*badness of test line */ + int d; /*demerits of test line */ + boolean artificial_demerits; /*has |d| been forced to zero? */ scaled shortfall; /*used in badness calculations */ - scaled g; /*glue stretch or shrink of test line, adjustment for last line */ - scaled cur_active_width[10] = { 0 }; /*distance from current active node */ + scaled g = 0; /*glue stretch or shrink of test line, adjustment for last line */ + scaled cur_active_width[10] = { 0 }; /*distance from current active node */ - line_width = 0; - g = 0; - prev_prev_r = null; /*Make sure that |pi| is in the proper range; */ if (pi >= inf_penalty) { return; /* this breakpoint is inhibited by infinite penalty */ @@ -1124,9 +1089,6 @@ ext_try_break(int pi, pi = eject_penalty; /*this breakpoint will be forced */ } - no_break_yet = true; - prev_r = active; - old_l = 0; do_all_eight(copy_to_cur_active); while (1) { @@ -1619,34 +1581,33 @@ ext_try_break(int pi, } @ @c -void -ext_do_line_break(int paragraph_dir, - int pretolerance, - int tracing_paragraphs, - int tolerance, - scaled emergency_stretch, - int looseness, - int adjust_spacing, - halfword par_shape_ptr, - int adj_demerits, - int protrude_chars, - int line_penalty, - int last_line_fit, - int double_hyphen_demerits, - int final_hyphen_demerits, - int hang_indent, - int hsize, - int hang_after, - halfword left_skip, - halfword right_skip, - halfword inter_line_penalties_ptr, - int inter_line_penalty, - int club_penalty, - halfword club_penalties_ptr, - halfword widow_penalties_ptr, - int widow_penalty, - int broken_penalty, - halfword final_par_glue) +void ext_do_line_break(int paragraph_dir, + int pretolerance, + int tracing_paragraphs, + int tolerance, + scaled emergency_stretch, + int looseness, + int adjust_spacing, + halfword par_shape_ptr, + int adj_demerits, + int protrude_chars, + int line_penalty, + int last_line_fit, + int double_hyphen_demerits, + int final_hyphen_demerits, + int hang_indent, + int hsize, + int hang_after, + halfword left_skip, + halfword right_skip, + halfword inter_line_penalties_ptr, + int inter_line_penalty, + int club_penalty, + halfword club_penalties_ptr, + halfword widow_penalties_ptr, + int widow_penalty, + int broken_penalty, + halfword final_par_glue) { /* DONE,DONE1,DONE2,DONE3,DONE4,DONE5,CONTINUE; */ halfword cur_p, q, r, s; /* miscellaneous nodes of temporary interest */ @@ -1749,7 +1710,7 @@ ext_do_line_break(int paragraph_dir, dir_ptr = null; } #if 0 - push_dir(paragraph_dir,dir_ptr); /* TODO what was the point of this? */ + push_dir(dir_ptr,paragraph_dir); /* TODO what was the point of this? */ #endif /* Find optimal breakpoints; */ @@ -1768,7 +1729,6 @@ ext_do_line_break(int paragraph_dir, if (tracing_paragraphs > 0) begin_diagnostic(); } - while (1) { halfword first_p; halfword nest_stack[10]; @@ -1828,8 +1788,7 @@ ext_do_line_break(int paragraph_dir, `\.{\\parfillskip}' glue appears at the end of each paragraph; it is therefore unnecessary to check if |vlink(cur_p)=null| when |cur_p| is a character node. */ - active_width[1] += - pack_width(line_break_dir, dir_TRT, cur_p, true); + active_width[1] += pack_width(line_break_dir, dir_TRT, cur_p, true); if ((adjust_spacing > 1) && check_expand_pars(font(cur_p))) { set_prev_char_p(cur_p); add_char_stretch(active_width[8], cur_p); @@ -1838,9 +1797,6 @@ ext_do_line_break(int paragraph_dir, cur_p = vlink(cur_p); while (cur_p == null && nest_index > 0) { cur_p = nest_stack[--nest_index]; -#ifdef DEBUG - fprintf(stderr,"Node Pop %d [%d]\n",nest_index,(int)cur_p); -#endif } } if (cur_p == null) { @@ -1853,218 +1809,211 @@ ext_do_line_break(int paragraph_dir, real width as opposed to glue. */ switch (type(cur_p)) { - case hlist_node: - case vlist_node: - active_width[1] += - pack_width(line_break_dir, box_dir(cur_p), cur_p, false); - break; - case rule_node: - active_width[1] += width(cur_p); - break; - 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,dir_ptr); /* adds to |dir_ptr| */ - } else { - pop_dir_node(dir_ptr); - if (dir_ptr != null) - line_break_dir = dir_dir(dir_ptr); - } - break; - case local_par_node: /* LOCAL: Advance past a |local_paragraph| node; */ - internal_pen_inter = local_pen_inter(cur_p); - internal_pen_broken = local_pen_broken(cur_p); - internal_left_box = local_box_left(cur_p); - internal_left_box_width = local_box_left_width(cur_p); - internal_right_box = local_box_right(cur_p); - internal_right_box_width = local_box_right_width(cur_p); - break; - case math_node: - auto_breaking = (subtype(cur_p) == after); - /* begin mathskip code */ - if (math_skip == zero_glue) { - kern_break(); + case hlist_node: + case vlist_node: + active_width[1] += pack_width(line_break_dir, box_dir(cur_p), cur_p, false); break; - } else { - /* fall through */ - } - /* end mathskip code */ - case glue_node: - /* If node |cur_p| is a legal breakpoint, call |try_break|; - then update the active widths by including the glue in - |glue_ptr(cur_p)|; */ - /* When node |cur_p| is a glue node, we look at the previous to - see whether or not a breakpoint is legal at |cur_p|, as - explained above. */ - /* *INDENT-OFF* */ - if (auto_breaking) { - halfword prev_p = alink(cur_p); - if (prev_p != temp_head && - (is_char_node(prev_p) || - precedes_break(prev_p) || - ((type(prev_p) == kern_node) - && (subtype(prev_p) != explicit)))) { - ext_try_break(0, unhyphenated_node, line_break_dir, adjust_spacing, - par_shape_ptr, adj_demerits, - tracing_paragraphs, protrude_chars, - line_penalty, last_line_fit, - double_hyphen_demerits, - final_hyphen_demerits, first_p, cur_p); - } - } - /* *INDENT-ON* */ - check_shrinkage(glue_ptr(cur_p)); - q = glue_ptr(cur_p); - active_width[1] += width(q); - active_width[2 + stretch_order(q)] += stretch(q); - active_width[7] += shrink(q); - /* begin mathskip code */ - if (type(cur_p)==math_node) { - active_width[1]+=surround(cur_p); - } - /* end mathskip code */ - break; - case kern_node: - if (subtype(cur_p) == explicit) { - kern_break(); - } else { + case rule_node: active_width[1] += width(cur_p); - if ((adjust_spacing == 2) && (subtype(cur_p) == normal)) { - add_kern_stretch(active_width[8], cur_p); - add_kern_shrink(active_width[9], cur_p); + break; + 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(dir_ptr,cur_p); /* adds to |dir_ptr| */ + } else { + pop_dir_node(dir_ptr); + if (dir_ptr != null) { + line_break_dir = dir_dir(dir_ptr); + } } - } - break; - case disc_node: - /* |select_disc|s are handled by the leading |init_disc| */ - if (subtype(cur_p) == select_disc) break; - /* Try to break after a discretionary fragment, then |goto done5|; */ - /* The following code knows that discretionary texts contain - only character nodes, kern nodes, box nodes, and rule - nodes. This branch differs a bit from older engines because in LuaTeX we - already have hyphenated the list. This means that we need to skip - automatic disc nodes. Of better, we need to treat discretionaries - and explicit hyphens always, even in the first pass (HH). */ - if (second_pass || subtype(cur_p) <= automatic_disc) { - /* - int actual_penalty = hyphen_penalty; - if (disc_penalty(cur_p) != 0) { - actual_penalty = (int) disc_penalty(cur_p); - } else if (subtype(cur_p) == automatic_disc) { - actual_penalty = ex_hyphen_penalty; + case local_par_node: /* LOCAL: Advance past a |local_paragraph| node; */ + internal_pen_inter = local_pen_inter(cur_p); + internal_pen_broken = local_pen_broken(cur_p); + internal_left_box = local_box_left(cur_p); + internal_left_box_width = local_box_left_width(cur_p); + internal_right_box = local_box_right(cur_p); + internal_right_box_width = local_box_right_width(cur_p); + break; + case math_node: + auto_breaking = (subtype(cur_p) == after); + /* begin mathskip code */ + if (math_skip == zero_glue) { + kern_break(); + break; + } else { + /* fall through */ } - */ - int actual_penalty = (int) disc_penalty(cur_p); - s = vlink_pre_break(cur_p); - do_one_seven_eight(reset_disc_width); - if (s == null) { /* trivial pre-break */ - ext_try_break(actual_penalty, hyphenated_node, - line_break_dir, adjust_spacing, - par_shape_ptr, adj_demerits, - tracing_paragraphs, protrude_chars, - line_penalty, last_line_fit, - double_hyphen_demerits, - final_hyphen_demerits, first_p, cur_p); + /* end mathskip code */ + case glue_node: + /* If node |cur_p| is a legal breakpoint, call |try_break|; + then update the active widths by including the glue in + |glue_ptr(cur_p)|; */ + /* When node |cur_p| is a glue node, we look at the previous to + see whether or not a breakpoint is legal at |cur_p|, as + explained above. */ + /* *INDENT-OFF* */ + if (auto_breaking) { + halfword prev_p = alink(cur_p); + if (prev_p != temp_head && + (is_char_node(prev_p) || + precedes_break(prev_p) || + ((type(prev_p) == kern_node) + && (subtype(prev_p) != explicit)))) { + ext_try_break(0, unhyphenated_node, line_break_dir, adjust_spacing, + par_shape_ptr, adj_demerits, + tracing_paragraphs, protrude_chars, + line_penalty, last_line_fit, + double_hyphen_demerits, + final_hyphen_demerits, first_p, cur_p); + } + } + /* *INDENT-ON* */ + check_shrinkage(glue_ptr(cur_p)); + q = glue_ptr(cur_p); + active_width[1] += width(q); + active_width[2 + stretch_order(q)] += stretch(q); + active_width[7] += shrink(q); + /* begin mathskip code */ + if (type(cur_p)==math_node) { + active_width[1]+=surround(cur_p); + } + /* end mathskip code */ + break; + case kern_node: + if (subtype(cur_p) == explicit) { + kern_break(); } else { - add_to_widths(s, line_break_dir, adjust_spacing, disc_width); - do_one_seven_eight(add_disc_width_to_active_width); - ext_try_break(actual_penalty, hyphenated_node, - line_break_dir, adjust_spacing, - par_shape_ptr, adj_demerits, - tracing_paragraphs, protrude_chars, - line_penalty, last_line_fit, - double_hyphen_demerits, - final_hyphen_demerits, first_p, cur_p); - if (subtype(cur_p) == init_disc) { - /* we should at two break points after the one we - added above: - \item1 which does a possible break in INIT's |post_break| - \item2 which means the |no_break| actually was broken - just a character later */ - /* do the select-0 case 'f-f-i' */ - assert(type(vlink(cur_p)) == disc_node && - subtype(vlink(cur_p)) == select_disc); - s = vlink_pre_break(vlink(cur_p)); - add_to_widths(s, line_break_dir, adjust_spacing, disc_width); + active_width[1] += width(cur_p); + if ((adjust_spacing == 2) && (subtype(cur_p) == normal)) { + add_kern_stretch(active_width[8], cur_p); + add_kern_shrink(active_width[9], cur_p); + } + } + break; + case disc_node: + /* |select_disc|s are handled by the leading |init_disc| */ + if (subtype(cur_p) == select_disc) + break; + /* Try to break after a discretionary fragment, then |goto done5|; */ + /* The following code knows that discretionary texts contain + only character nodes, kern nodes, box nodes, and rule + nodes. This branch differs a bit from older engines because in LuaTeX we + already have hyphenated the list. This means that we need to skip + automatic disc nodes. Of better, we need to treat discretionaries + and explicit hyphens always, even in the first pass (HH). */ + if (second_pass || subtype(cur_p) <= automatic_disc) { + /* + int actual_penalty = hyphen_penalty; + if (disc_penalty(cur_p) != 0) { + actual_penalty = (int) disc_penalty(cur_p); + } else if (subtype(cur_p) == automatic_disc) { + actual_penalty = ex_hyphen_penalty; + } + */ + int actual_penalty = (int) disc_penalty(cur_p); + s = vlink_pre_break(cur_p); + do_one_seven_eight(reset_disc_width); + if (s == null) { /* trivial pre-break */ ext_try_break(actual_penalty, hyphenated_node, line_break_dir, adjust_spacing, par_shape_ptr, adj_demerits, - tracing_paragraphs, - 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)); + tracing_paragraphs, protrude_chars, + line_penalty, last_line_fit, + double_hyphen_demerits, + final_hyphen_demerits, first_p, cur_p); + } else { add_to_widths(s, line_break_dir, adjust_spacing, disc_width); + do_one_seven_eight(add_disc_width_to_active_width); ext_try_break(actual_penalty, hyphenated_node, line_break_dir, adjust_spacing, par_shape_ptr, adj_demerits, - tracing_paragraphs, - protrude_chars, line_penalty, - last_line_fit, double_hyphen_demerits, - final_hyphen_demerits, first_p, - vlink(cur_p)); + tracing_paragraphs, protrude_chars, + line_penalty, last_line_fit, + double_hyphen_demerits, + final_hyphen_demerits, first_p, cur_p); + if (subtype(cur_p) == init_disc) { + /* we should at two break points after the one we + added above: + \item1 which does a possible break in INIT's |post_break| + \item2 which means the |no_break| actually was broken + just a character later */ + /* do the select-0 case 'f-f-i' */ + s = vlink_pre_break(vlink(cur_p)); + add_to_widths(s, line_break_dir, adjust_spacing, disc_width); + ext_try_break(actual_penalty, hyphenated_node, + line_break_dir, adjust_spacing, + par_shape_ptr, adj_demerits, + tracing_paragraphs, + 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, adjust_spacing, disc_width); + ext_try_break(actual_penalty, hyphenated_node, + line_break_dir, adjust_spacing, + par_shape_ptr, adj_demerits, + tracing_paragraphs, + protrude_chars, line_penalty, + last_line_fit, double_hyphen_demerits, + final_hyphen_demerits, first_p, + vlink(cur_p)); #endif + } + do_one_seven_eight(sub_disc_width_from_active_width); } - do_one_seven_eight(sub_disc_width_from_active_width); } - } - s = vlink_no_break(cur_p); - add_to_widths(s, line_break_dir, adjust_spacing, active_width); - break; - case penalty_node: - ext_try_break(penalty(cur_p), unhyphenated_node, line_break_dir, - adjust_spacing, par_shape_ptr, adj_demerits, - tracing_paragraphs, protrude_chars, - line_penalty, last_line_fit, - double_hyphen_demerits, final_hyphen_demerits, - first_p, cur_p); - break; - case boundary_node: - case whatsit_node: - /* / Advance past a whatsit node in the |line_break| loop/; */ - 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)); - confusion("paragraph"); + s = vlink_no_break(cur_p); + add_to_widths(s, line_break_dir, adjust_spacing, active_width); + break; + case penalty_node: + ext_try_break(penalty(cur_p), unhyphenated_node, line_break_dir, + adjust_spacing, par_shape_ptr, adj_demerits, + tracing_paragraphs, protrude_chars, + line_penalty, last_line_fit, + double_hyphen_demerits, final_hyphen_demerits, + first_p, cur_p); + break; + case boundary_node: + case whatsit_node: + /* / Advance past a whatsit node in the |line_break| loop/; */ + case mark_node: + case ins_node: + case adjust_node: + break; + case glue_spec_node: + normal_warning("parbuilder","found a glue_spec in a paragraph"); + break; + default: + formatted_error("parbuilder","weird node %d in paragraph",type(cur_p)); } cur_p = vlink(cur_p); while (cur_p == null && nest_index > 0) { cur_p = nest_stack[--nest_index]; -#ifdef DEBUG - fprintf(stderr,"Node Pop %d [%d]\n",nest_index,(int)cur_p); -#endif } } 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 */ - - /* The forced line break at the paragraph's end will reduce the list of - breakpoints so that all active nodes represent breaks at |cur_p=null|. - On the first pass, we insist on finding an active node that has the - correct ``looseness.'' On the final pass, there will be at least one active - node, and we will match the desired looseness as well as we can. - - The global variable |best_bet| will be set to the active node for the best - way to break the paragraph, and a few other variables are used to - help determine what is best. - */ - + /* + Try the final line break at the end of the paragraph, + and |goto done| if the desired breakpoints have been found + + The forced line break at the paragraph's end will reduce the list of + breakpoints so that all active nodes represent breaks at |cur_p=null|. + On the first pass, we insist on finding an active node that has the + correct ``looseness.'' On the final pass, there will be at least one active + node, and we will match the desired looseness as well as we can. + + The global variable |best_bet| will be set to the active node for the best + way to break the paragraph, and a few other variables are used to + help determine what is best. + */ ext_try_break(eject_penalty, hyphenated_node, line_break_dir, adjust_spacing, par_shape_ptr, adj_demerits, tracing_paragraphs, protrude_chars, line_penalty, @@ -2084,16 +2033,18 @@ ext_do_line_break(int paragraph_dir, r = vlink(r); } while (r != active); best_line = line_number(best_bet); - - /* /Find an active node with fewest demerits; */ + /* + Find an active node with fewest demerits; + */ if (looseness == 0) goto DONE; - /*Find the best active node for the desired looseness; */ + /* + Find the best active node for the desired looseness; - /* The adjustment for a desired looseness is a slightly more complicated - version of the loop just considered. Note that if a paragraph is broken - into segments by displayed equations, each segment will be subject to the - looseness calculation, independently of the other segments. + 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; @@ -2116,24 +2067,24 @@ ext_do_line_break(int paragraph_dir, r = vlink(r); } while (r != active); best_line = line_number(best_bet); - - /* /Find the best active node for the desired looseness; */ + /* + 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 */ + } else { + /* if at first you do not succeed, \dots */ if (tracing_paragraphs > 0) tprint_nl("@@emergencypass"); background[2] += emergency_stretch; @@ -2147,9 +2098,10 @@ ext_do_line_break(int paragraph_dir, normalize_selector(); } if (do_last_line_fit) { - /* Adjust the final line of the paragraph; */ - /* Here we either reset |do_last_line_fit| or adjust the |par_fill_skip| glue. - */ + /* + Adjust the final line of the paragraph; here we either reset + |do_last_line_fit| or adjust the |par_fill_skip| glue. + */ if (active_short(best_bet) == 0) { do_last_line_fit = false; } else { @@ -2161,12 +2113,12 @@ ext_do_line_break(int paragraph_dir, } } - /* 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.) - */ + /* + 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); @@ -2189,8 +2141,10 @@ ext_do_line_break(int paragraph_dir, last_special_line, second_width, second_indent, first_width, first_indent, best_line); - /* /Break the paragraph at the chosen... */ - /* Clean up the memory by removing the break nodes; */ + /* + 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/mainbody.h b/Build/source/texk/web2c/luatexdir/tex/mainbody.h index 1cbd214e016..046dd212152 100644 --- a/Build/source/texk/web2c/luatexdir/tex/mainbody.h +++ b/Build/source/texk/web2c/luatexdir/tex/mainbody.h @@ -21,7 +21,6 @@ #ifndef MAINBODY_H # define MAINBODY_H -extern int luatex_svn; extern int luatex_version; extern int luatex_revision; extern int luatex_date_info; @@ -218,7 +217,6 @@ is conditionally compiled in the C code. # define fix_date_and_time() dateandtime(int_par(time_code),int_par(day_code),int_par(month_code),int_par(year_code)) -extern int get_luatexsvn(void); extern int get_luatexversion(void); extern str_number get_luatexrevision(void); extern int get_luatex_date_info(void); diff --git a/Build/source/texk/web2c/luatexdir/tex/mainbody.w b/Build/source/texk/web2c/luatexdir/tex/mainbody.w index 745a1531019..5936def5b9f 100644 --- a/Build/source/texk/web2c/luatexdir/tex/mainbody.w +++ b/Build/source/texk/web2c/luatexdir/tex/mainbody.w @@ -225,11 +225,6 @@ int get_luatexversion(void) return luatex_version; } -int get_luatexsvn(void) -{ - return luatex_svn; -} - str_number get_luatexrevision(void) { return luatex_revision; @@ -409,7 +404,7 @@ void main_body(void) if (bad > 0) { goto FINAL_END; } - print_banner(luatex_version_string, luatex_svn); + print_banner(luatex_version_string); /* Get the first line of input and prepare to start */ /* When we begin the following code, \TeX's tables may still contain garbage; @@ -441,10 +436,7 @@ void main_body(void) if (draft_mode_option != 0) { int_par(draft_mode_code) = draft_mode_value; } - /* this is specific for the pdf backend */ - if (int_par(draft_mode_code) != 0) { /* should move */ - static_pdf->draftmode = int_par(draft_mode_code); - } + /* can this be moved? */ pdf_init_map_file((char *) pdftex_map); /* */ if (end_line_char_inactive) @@ -493,7 +485,6 @@ This program doesn't bother to close the input files that may still be open. void close_files_and_terminate(void) { int callback_id; - PDF pdf = static_pdf; callback_id = callback_defined(stop_run_callback); finalize_write_files(); if (int_par(tracing_stats_code) > 0) { @@ -532,26 +523,9 @@ void close_files_and_terminate(void) } wake_up_terminal(); /* rubish, these pdf arguments, passed, needs to be fixed, e.g. with a dummy in dvi */ - ensure_output_state(pdf, ST_OMODE_FIX); - switch (output_mode_used) { - case OMODE_NONE: /* during initex run */ - break; - case OMODE_PDF: - if (history == fatal_error_stop) { - remove_pdffile(pdf); - print_err(" ==> Fatal error occurred, no output PDF file produced!"); - } else - finish_pdf_file(pdf, luatex_version, get_luatexrevision()); - break; - case OMODE_DVI: - finish_dvi_file(pdf, luatex_version, get_luatexrevision()); - break; - default: - assert(0); - } + wrapup_backend(); /* Close {\sl Sync\TeX} file and write status */ synctexterminate(log_opened_global); /* Let the {\sl Sync\TeX} controller close its files. */ - free_text_codes(); free_math_codes(); if (log_opened_global) { diff --git a/Build/source/texk/web2c/luatexdir/tex/maincontrol.w b/Build/source/texk/web2c/luatexdir/tex/maincontrol.w index 0219320ec41..c6b30b09921 100644 --- a/Build/source/texk/web2c/luatexdir/tex/maincontrol.w +++ b/Build/source/texk/web2c/luatexdir/tex/maincontrol.w @@ -19,7 +19,6 @@ @ @c - #include "ptexlib.h" #include "lua/luatex-api.h" @@ -49,9 +48,7 @@ #define no_local_whatsits int_par(no_local_whatsits_code) #define no_local_dirs int_par(no_local_dirs_code) #define err_help equiv(err_help_loc) -#define text_direction int_par(text_direction_code) #define every_par equiv(every_par_loc) -#define par_direction int_par(par_direction_code) #define page_left_offset dimen_par(page_left_offset_code) #define page_top_offset dimen_par(page_top_offset_code) @@ -142,7 +139,6 @@ with particular care. static halfword main_p; /* temporary register for list manipulation */ static halfword main_s; /* space factor value */ - @ We leave the |space_factor| unchanged if |sf_code(cur_chr)=0|; otherwise we set it equal to |sf_code(cur_chr)|, except that it should never change from a value less than 1000 to a value exceeding 1000. The most common @@ -164,7 +160,6 @@ void adjust_space_factor(void) } } - @ From Knuth: ``Having |font_glue| allocated for each text font saves both time and memory.'' That may be true, but it also punches through the API wall for fonts, so I removed that -- Taco. But a bit of caching @@ -185,7 +180,6 @@ its values. static int main_control_state; - @* Main control helpers. Here are all the functions that are called from |main_control| that @@ -217,11 +211,16 @@ see to it later that the corresponding glue specification is precisely to be full of zeroes. Therefore it is simple to test whether a glue parameter is zero or~not. - @c static void run_app_space (void) { - if ((abs(mode) + cur_cmd == hmode + spacer_cmd) - && (!(space_factor == 1000))) { + int method = int_par(disable_space_code) ; + if (method == 1) { + /* don't inject anything, not even zero skip */ + } else if (method == 2) { + temp_ptr = new_glue(zero_glue); + couple_nodes(tail,temp_ptr); + tail = temp_ptr; + } else if ((abs(mode) + cur_cmd == hmode + spacer_cmd) && (!(space_factor == 1000))) { app_space(); } else { /* Append a normal inter-word space to the current list */ @@ -238,14 +237,12 @@ static void run_app_space (void) { space_spec_font = cur_font; } main_p = space_spec_cache; - temp_ptr = new_glue(main_p); } else { temp_ptr = new_param_glue(space_skip_code); } couple_nodes(tail,temp_ptr); tail = temp_ptr; - } } @@ -266,7 +263,6 @@ static void run_boundary (void) { tail = n; } - @ @c static void run_char_ghost (void) { int t; @@ -300,12 +296,11 @@ static void run_ignore_spaces (void) { do { get_x_token(); } while (cur_cmd == spacer_cmd); - main_control_state = goto_skip_token; } else { int t = scanner_status; scanner_status = normal; - get_next(); /* get_token_lua(); */ + get_next(); scanner_status = t; cur_cs = prim_lookup(cs_text(cur_cs)); if (cur_cs != undefined_primitive) { @@ -729,7 +724,7 @@ static void run_option(void) { scan_int(); word_define(int_base+math_use_old_fraction_scaling_code, cur_val); } else { - normal_warning("mathoption","unknown key",false,false); + normal_warning("mathoption","unknown key"); } break; default: @@ -1026,7 +1021,6 @@ void app_space(void) width(main_p) = width(main_p) + extra_space(cur_font); stretch(main_p) = xn_over_d(stretch(main_p), space_factor, 1000); shrink(main_p) = xn_over_d(shrink(main_p), 1000, space_factor); - q = new_glue(main_p); glue_ref_count(main_p) = null; } @@ -1055,10 +1049,6 @@ void insert_dollar_sign_par_end(void) } } - - - - @ The `|you_cant|' procedure prints a line saying that the current command is illegal in the current mode; it identifies these things symbolically. @@ -1092,7 +1082,6 @@ void report_illegal_case(void) error(); } - @ Some operations are allowed only in privileged modes, i.e., in cases that |mode>0|. The |privileged| function is used to detect violations of this rule; it issues an error message and returns |false| if the @@ -1109,7 +1098,6 @@ boolean privileged(void) } } - @ We don't want to leave |main_control| immediately when a |stop| command is sensed, because it may be necessary to invoke an \.{\\output} routine several times before things really grind to a halt. (The output routine @@ -1151,24 +1139,24 @@ void append_glue(void) int s; /* modifier of skip command */ s = cur_chr; switch (s) { - case fil_code: - cur_val = fil_glue; - break; - case fill_code: - cur_val = fill_glue; - break; - case ss_code: - cur_val = ss_glue; - break; - case fil_neg_code: - cur_val = fil_neg_glue; - break; - case skip_code: - scan_glue(glue_val_level); - break; - case mskip_code: - scan_glue(mu_val_level); - break; + case fil_code: + cur_val = fil_glue; + break; + case fill_code: + cur_val = fill_glue; + break; + case ss_code: + cur_val = ss_glue; + break; + case fil_neg_code: + cur_val = fil_neg_glue; + break; + case skip_code: + scan_glue(glue_val_level); + break; + case mskip_code: + scan_glue(mu_val_level); + break; } /* now |cur_val| points to the glue specification */ tail_append(new_glue(cur_val)); if (s >= skip_code) { @@ -1188,7 +1176,6 @@ void append_kern(void) subtype(tail) = (quarterword) s; } - @ We have to deal with errors in which braces and such things are not properly nested. Sometimes the user makes an error of commission by inserting an extra symbol, but sometimes the user makes an error of omission. @@ -1218,28 +1205,27 @@ void off_save(void) /* Prepare to insert a token that matches |cur_group|, and print what it is */ /* At this point, |link(temp_token_head)=p|, a pointer to an empty one-word node. */ switch (cur_group) { - case semi_simple_group: - set_token_info(p, cs_token_flag + frozen_end_group); - tprint_esc("endgroup"); - break; - case math_shift_group: - set_token_info(p, math_shift_token + '$'); - print_char('$'); - break; - case math_left_group: - set_token_info(p, cs_token_flag + frozen_right); - q = get_avail(); - set_token_link(p, q); - p = token_link(p); - set_token_info(p, other_token + '.'); - tprint_esc("right."); - break; - default: - set_token_info(p, right_brace_token + '}'); - print_char('}'); - break; + case semi_simple_group: + set_token_info(p, cs_token_flag + frozen_end_group); + tprint_esc("endgroup"); + break; + case math_shift_group: + set_token_info(p, math_shift_token + '$'); + print_char('$'); + break; + case math_left_group: + set_token_info(p, cs_token_flag + frozen_right); + q = get_avail(); + set_token_link(p, q); + p = token_link(p); + set_token_info(p, other_token + '.'); + tprint_esc("right."); + break; + default: + set_token_info(p, right_brace_token + '}'); + print_char('}'); + break; } - tprint(" inserted"); ins_list(token_link(temp_token_head)); help5("I've inserted something that you may have forgotten.", @@ -1251,7 +1237,6 @@ void off_save(void) } } - @ The routine for a |right_brace| character branches into many subcases, since a variety of things may happen, depending on |cur_group|. Some types of groups are not supposed to be ended by a right brace; error @@ -1267,112 +1252,112 @@ void handle_right_brace(void) int f; /* holds |floating_penalty| in |insert_group| */ p = null; switch (cur_group) { - case simple_group: - fixup_directions(); - break; - case bottom_level: - print_err("Too many }'s"); - help2("You've closed more groups than you opened.", - "Such booboos are generally harmless, so keep going."); - error(); - break; - case semi_simple_group: - case math_shift_group: - case math_left_group: - extra_right_brace(); - break; - case hbox_group: - /* When the right brace occurs at the end of an \.{\\hbox} or \.{\\vbox} or - \.{\\vtop} construction, the |package| routine comes into action. We might - also have to finish a paragraph that hasn't ended. */ - package(0); - break; - case adjusted_hbox_group: - adjust_tail = adjust_head; - pre_adjust_tail = pre_adjust_head; - package(0); - break; - case vbox_group: - end_graf(vbox_group); - package(0); - break; - case vtop_group: - end_graf(vtop_group); - package(vtop_code); - break; - case insert_group: - end_graf(insert_group); - q = split_top_skip; - add_glue_ref(q); - d = split_max_depth; - f = floating_penalty; - unsave(); - save_ptr--; - /* now |saved_value(0)| is the insertion number, or the |vadjust| subtype */ - p = vpack(vlink(head), 0, additional, -1); - pop_nest(); - if (saved_type(0) == saved_insert) { - tail_append(new_node(ins_node, saved_value(0))); - height(tail) = height(p) + depth(p); - ins_ptr(tail) = list_ptr(p); - split_top_ptr(tail) = q; - depth(tail) = d; - float_cost(tail) = f; - } else if (saved_type(0) == saved_adjust) { - tail_append(new_node(adjust_node, saved_value(0))); - adjust_ptr(tail) = list_ptr(p); - delete_glue_ref(q); - } else { - confusion("insert_group"); - } - list_ptr(p) = null; - flush_node(p); - if (nest_ptr == 0) { - check_filter(insert); - build_page(); - } - break; - case output_group: - /* this is needed in case the \.{\\output} executes a \.{\\textdir} command. */ - if (dir_level(text_dir_ptr) == cur_level) { - /* DIR: Remove from |text_dir_ptr| */ - halfword text_dir_tmp = vlink(text_dir_ptr); - flush_node(text_dir_ptr); - text_dir_ptr = text_dir_tmp; - } - resume_after_output(); - break; - case disc_group: - build_discretionary(); - break; - case local_box_group: - build_local_box(); - break; - case align_group: - back_input(); - cur_tok = cs_token_flag + frozen_cr; - print_err("Missing \\cr inserted"); - help1("I'm guessing that you meant to end an alignment here."); - ins_error(); - break; - case no_align_group: - end_graf(no_align_group); - unsave(); - align_peek(); - break; - case vcenter_group: - end_graf(vcenter_group); - finish_vcenter(); - break; - case math_choice_group: - build_choices(); - break; - case math_group: - close_math_group(p); - break; - default: - confusion("rightbrace"); - break; + case simple_group: + fixup_directions(); + break; + case bottom_level: + print_err("Too many }'s"); + help2("You've closed more groups than you opened.", + "Such booboos are generally harmless, so keep going."); + error(); + break; + case semi_simple_group: + case math_shift_group: + case math_left_group: + extra_right_brace(); + break; + case hbox_group: + /* When the right brace occurs at the end of an \.{\\hbox} or \.{\\vbox} or + \.{\\vtop} construction, the |package| routine comes into action. We might + also have to finish a paragraph that hasn't ended. */ + package(0); + break; + case adjusted_hbox_group: + adjust_tail = adjust_head; + pre_adjust_tail = pre_adjust_head; + package(0); + break; + case vbox_group: + end_graf(vbox_group); + package(0); + break; + case vtop_group: + end_graf(vtop_group); + package(vtop_code); + break; + case insert_group: + end_graf(insert_group); + q = split_top_skip; + add_glue_ref(q); + d = split_max_depth; + f = floating_penalty; + unsave(); + save_ptr--; + /* now |saved_value(0)| is the insertion number, or the |vadjust| subtype */ + p = vpack(vlink(head), 0, additional, -1); + pop_nest(); + if (saved_type(0) == saved_insert) { + tail_append(new_node(ins_node, saved_value(0))); + height(tail) = height(p) + depth(p); + ins_ptr(tail) = list_ptr(p); + split_top_ptr(tail) = q; + depth(tail) = d; + float_cost(tail) = f; + } else if (saved_type(0) == saved_adjust) { + tail_append(new_node(adjust_node, saved_value(0))); + adjust_ptr(tail) = list_ptr(p); + delete_glue_ref(q); + } else { + confusion("insert_group"); + } + list_ptr(p) = null; + flush_node(p); + if (nest_ptr == 0) { + check_filter(insert); + build_page(); + } + break; + case output_group: + /* this is needed in case the \.{\\output} executes a \.{\\textdir} command. */ + if (dir_level(text_dir_ptr) == cur_level) { + /* DIR: Remove from |text_dir_ptr| */ + halfword text_dir_tmp = vlink(text_dir_ptr); + flush_node(text_dir_ptr); + text_dir_ptr = text_dir_tmp; + } + resume_after_output(); + break; + case disc_group: + build_discretionary(); + break; + case local_box_group: + build_local_box(); + break; + case align_group: + back_input(); + cur_tok = cs_token_flag + frozen_cr; + print_err("Missing \\cr inserted"); + help1("I'm guessing that you meant to end an alignment here."); + ins_error(); + break; + case no_align_group: + end_graf(no_align_group); + unsave(); + align_peek(); + break; + case vcenter_group: + end_graf(vcenter_group); + finish_vcenter(); + break; + case math_choice_group: + build_choices(); + break; + case math_group: + close_math_group(p); + break; + default: + confusion("rightbrace"); + break; } } @@ -1381,15 +1366,15 @@ void extra_right_brace(void) { print_err("Extra }, or forgotten "); switch (cur_group) { - case semi_simple_group: - tprint_esc("endgroup"); - break; - case math_shift_group: - print_char('$'); - break; - case math_left_group: - tprint_esc("right"); - break; + case semi_simple_group: + tprint_esc("endgroup"); + break; + case math_shift_group: + print_char('$'); + break; + case math_left_group: + tprint_esc("right"); + break; } help5("I've deleted a group-closing symbol because it seems to be", "spurious, as in `$x}$'. But perhaps the } is legitimate and", @@ -1400,7 +1385,6 @@ void extra_right_brace(void) incr(align_state); } - @ Here is where we clear the parameters that are supposed to revert to their default values after every paragraph and when internal vertical mode is entered. @@ -1419,7 +1403,6 @@ void normal_paragraph(void) eq_define(inter_line_penalties_loc, shape_ref_cmd, null); } - @ The global variable |cur_box| will point to a newly-made box. If the box is void, we will have |cur_box=null|. Otherwise we will have |type(cur_box)=hlist_node| or |vlist_node| or |rule_node|; the |rule_node| @@ -1428,7 +1411,6 @@ case can occur only with leaders. @c halfword cur_box; /* box to be placed into its context */ - @ The |box_end| procedure does the right thing with |cur_box|, if |box_context| represents the context as explained above. @@ -1456,7 +1438,7 @@ void box_end(int box_context) append_list(adjust_head, adjust_tail); adjust_tail = null; } - if (mode > 0) { + if (mode > 0) { check_filter(box); build_page(); } @@ -1469,15 +1451,12 @@ void box_end(int box_context) tail = cur_box; } } - } else if (box_context < ship_out_flag) { /* Store |cur_box| in a box register */ if (box_context < global_box_flag) eq_define(box_base + box_context - box_flag, box_ref_cmd, cur_box); else - geq_define(box_base + box_context - global_box_flag, box_ref_cmd, - cur_box); - + geq_define(box_base + box_context - global_box_flag, box_ref_cmd, cur_box); } else if (cur_box != null) { if (box_context > ship_out_flag) { /* Append a new leader node that uses |cur_box| */ @@ -1485,12 +1464,10 @@ void box_end(int box_context) do { get_x_token(); } while ((cur_cmd == spacer_cmd) || (cur_cmd == relax_cmd)); - if (((cur_cmd == hskip_cmd) && (abs(mode) != vmode)) || ((cur_cmd == vskip_cmd) && (abs(mode) == vmode))) { append_glue(); - subtype(tail) = - (quarterword) (box_context - (leader_flag - a_leaders)); + subtype(tail) = (quarterword) (box_context - (leader_flag - a_leaders)); leader_ptr(tail) = cur_box; } else { print_err("Leaders not followed by proper glue"); @@ -1501,9 +1478,9 @@ void box_end(int box_context) back_error(); flush_node_list(cur_box); } - - } else + } else { ship_out(static_pdf, cur_box, SHIPPING_PAGE); + } } } @@ -1516,7 +1493,6 @@ void scan_box(int box_context) do { get_x_token(); } while ((cur_cmd == spacer_cmd) || (cur_cmd == relax_cmd)); - if (cur_cmd == make_box_cmd) { begin_box(box_context); } else if ((box_context >= leader_flag) && @@ -1547,7 +1523,6 @@ void new_graf(boolean indented) space_factor = 1000; /* LOCAL: Add local paragraph node */ tail_append(make_local_par_node()); - if (indented) { p = new_null_box(); box_dir(p) = par_direction; @@ -1598,7 +1573,7 @@ void indent_in_hmode(void) void head_for_vmode(void) { if (mode < 0) { - if (cur_cmd != hrule_cmd) { + if ((cur_cmd != hrule_cmd) && (cur_cmd != no_hrule_cmd)) { off_save(); } else { print_err("You can't use `\\hrule' here except with leaders"); @@ -1614,7 +1589,6 @@ void head_for_vmode(void) } } - @ TODO (BUG?): |dir_save| would have been set by |line_break| by means of |post_line_break|, but this is not done right now, as it introduces pretty heavy memory leaks. This means the current code is probably @@ -1640,7 +1614,6 @@ void end_graf(int line_break_context) } } - @ @c void begin_insert_or_adjust(void) { @@ -1668,7 +1641,6 @@ void begin_insert_or_adjust(void) prev_depth = ignore_depth; } - @ I (TH)'ve renamed the |make_mark| procedure to this, because if the current chr code is 1, then the actual command was \.{\\clearmarks}, which does not generate a mark node but instead destroys the current @@ -1705,7 +1677,6 @@ void handle_mark(void) } } - @ @c void append_penalty(void) { @@ -1717,7 +1688,6 @@ void append_penalty(void) } } - @ When |delete_last| is called, |cur_chr| is the |type| of node that will be deleted, if present. @@ -1752,7 +1722,6 @@ void delete_last(void) } error(); } - } else { /* todo: clean this up */ if (!is_char_node(tail)) { @@ -1845,7 +1814,6 @@ void append_italic_correction(void) } } - @ @c void append_local_box(int kind) { @@ -1858,7 +1826,6 @@ void append_local_box(int kind) space_factor = 1000; } - @ Discretionary nodes are easy in the common case `\.{\\-}', but in the general case we must process three braces full of items. @@ -1930,7 +1897,6 @@ void build_local_box(void) eq_word_define(int_base + no_local_whatsits_code, no_local_whatsits + 1); } - @ The three discretionary lists are constructed somewhat as if they were hboxes. A~subroutine called |build_discretionary| handles the transitions. (This is sort of fun.) @@ -2014,7 +1980,6 @@ void build_discretionary(void) space_factor = 1000; } - @ The positioning of accents is straightforward but tedious. Given an accent of width |a|, designed for characters of height |x| and slant |s|; and given a character of width |w|, height |h|, and slant |t|: We will shift @@ -2085,7 +2050,6 @@ void make_accent(void) } } - @ When `\.{\\cr}' or `\.{\\span}' or a tab mark comes through the scanner into |main_control|, it might be that the user has foolishly inserted one of them into something that has nothing to do with alignment. But it is @@ -2135,7 +2099,6 @@ void align_error(void) } } - @ The help messages here contain a little white lie, since \.{\\noalign} and \.{\\omit} are allowed also after `\.{\\noalign\{...\}}'. @@ -2156,7 +2119,6 @@ void omit_error(void) error(); } - @ We've now covered most of the abuses of \.{\\halign} and \.{\\valign}. Let's take a look at what happens when they are used correctly. @@ -2199,7 +2161,6 @@ void cs_error(void) error(); } - @ Assignments to values in |eqtb| can be global or local. Furthermore, a control sequence can be defined to be `\.{\\long}', `\.{\\protected}', @@ -2215,8 +2176,6 @@ void cs_error(void) a sequence of prefixes until coming to a non-prefix, then it carries out the command. - - @ If the user says, e.g., `\.{\\global\\global}', the redundancy is silently accepted. @@ -2238,8 +2197,7 @@ following program is careful to check each case properly. error(); \ cur_val=0; \ } \ - } while (0) - +} while (0) @ @c void prefixed_command(void) @@ -2288,7 +2246,6 @@ void prefixed_command(void) help1("I'll pretend you didn't say \\long or \\outer or \\protected here."); error(); } - /* Adjust for the setting of \.{\\globaldefs} */ if (global_defs != 0) { if (global_defs < 0) { @@ -2300,226 +2257,250 @@ void prefixed_command(void) } } switch (cur_cmd) { - case set_font_cmd: - /* Here's an example of the way many of the following routines operate. - (Unfortunately, they aren't all as simple as this.) */ - define(cur_font_loc, data_cmd, cur_chr); - break; - case def_cmd: - /* When a |def| command has been scanned, - |cur_chr| is odd if the definition is supposed to be global, and - |cur_chr>=2| if the definition is supposed to be expanded. */ - - if (odd(cur_chr) && !is_global(a) && (global_defs >= 0)) - a = a + 4; - e = (cur_chr >= 2); - get_r_token(); - p = cur_cs; - q = scan_toks(true, e); - if (j != 0) { - q = get_avail(); - set_token_info(q, j); - set_token_link(q, token_link(def_ref)); - set_token_link(def_ref, q); - } - define(p, call_cmd + (a % 4), def_ref); - break; - case let_cmd: - n = cur_chr; - get_r_token(); - p = cur_cs; - if (n == normal) { - do { + case set_font_cmd: + /* Here's an example of the way many of the following routines operate. + (Unfortunately, they aren't all as simple as this.) */ + define(cur_font_loc, data_cmd, cur_chr); + break; + case def_cmd: + /* When a |def| command has been scanned, + |cur_chr| is odd if the definition is supposed to be global, and + |cur_chr>=2| if the definition is supposed to be expanded. */ + + if (odd(cur_chr) && !is_global(a) && (global_defs >= 0)) + a = a + 4; + e = (cur_chr >= 2); + get_r_token(); + p = cur_cs; + q = scan_toks(true, e); + if (j != 0) { + q = get_avail(); + set_token_info(q, j); + set_token_link(q, token_link(def_ref)); + set_token_link(def_ref, q); + } + define(p, call_cmd + (a % 4), def_ref); + break; + case let_cmd: + n = cur_chr; + if (n == normal) { + get_r_token(); + p = cur_cs; + do { + get_token(); + } while (cur_cmd == spacer_cmd); + if (cur_tok == other_token + '=') { + get_token(); + if (cur_cmd == spacer_cmd) + get_token(); + } + } else if (n == normal + 1) { + /* futurelet */ + get_r_token(); + p = cur_cs; get_token(); - } while (cur_cmd == spacer_cmd); - if (cur_tok == other_token + '=') { + q = cur_tok; get_token(); - if (cur_cmd == spacer_cmd) - get_token(); + back_input(); + cur_tok = q; + /* look ahead, then back up */ + /* note that |back_input| doesn't affect |cur_cmd|, |cur_chr| */ + back_input(); + } else { + /* letcharcode */ + scan_int(); + if (cur_val > 0) { + cur_cs = active_to_cs(cur_val, true); + set_token_info(cur_cs, cur_cs + cs_token_flag); + p = cur_cs; + do { + get_token(); + } while (cur_cmd == spacer_cmd); + if (cur_tok == other_token + '=') { + get_token(); + if (cur_cmd == spacer_cmd) + get_token(); + } + } else { + p = null; + tex_error("invalid number for \\letcharcode",NULL); + } } - } else { - get_token(); - q = cur_tok; - get_token(); - back_input(); - cur_tok = q; - back_input(); /* look ahead, then back up */ - } /* note that |back_input| doesn't affect |cur_cmd|, |cur_chr| */ - if (cur_cmd >= call_cmd) - add_token_ref(cur_chr); - define(p, cur_cmd, cur_chr); - break; - case shorthand_def_cmd: - /* We temporarily define |p| to be |relax|, so that an occurrence of |p| - while scanning the definition will simply stop the scanning instead of - producing an ``undefined control sequence'' error or expanding the - previous meaning. This allows, for instance, `\.{\\chardef\\foo=123\\foo}'. - */ - n = cur_chr; - get_r_token(); - p = cur_cs; - define(p, relax_cmd, too_big_char); - scan_optional_equals(); - switch (n) { - case char_def_code: - scan_char_num(); - define(p, char_given_cmd, cur_val); - break; - case math_char_def_code: - mval = scan_mathchar(tex_mathcode); - cur_val = - (mval.class_value * 16 + mval.family_value) * 256 + - mval.character_value; - define(p, math_given_cmd, cur_val); - break; - case xmath_char_def_code: - mval = scan_mathchar(umath_mathcode); - cur_val = - (mval.class_value + (8 * mval.family_value)) * (65536 * 32) + - mval.character_value; - define(p, xmath_given_cmd, cur_val); - break; - case umath_char_def_code: - mval = scan_mathchar(umathnum_mathcode); - cur_val = - (mval.class_value + (8 * mval.family_value)) * (65536 * 32) + - mval.character_value; - define(p, xmath_given_cmd, cur_val); + if (cur_cmd >= call_cmd) + add_token_ref(cur_chr); + define(p, cur_cmd, cur_chr); break; - default: - scan_register_num(); + case shorthand_def_cmd: + /* We temporarily define |p| to be |relax|, so that an occurrence of |p| + while scanning the definition will simply stop the scanning instead of + producing an ``undefined control sequence'' error or expanding the + previous meaning. This allows, for instance, `\.{\\chardef\\foo=123\\foo}'. + */ + n = cur_chr; + get_r_token(); + p = cur_cs; + define(p, relax_cmd, too_big_char); + scan_optional_equals(); switch (n) { - case count_def_code: - define(p, assign_int_cmd, count_base + cur_val); - break; - case attribute_def_code: - define(p, assign_attr_cmd, attribute_base + cur_val); + case char_def_code: + scan_char_num(); + define(p, char_given_cmd, cur_val); break; - case dimen_def_code: - define(p, assign_dimen_cmd, scaled_base + cur_val); + case math_char_def_code: + mval = scan_mathchar(tex_mathcode); + cur_val = + (mval.class_value * 16 + mval.family_value) * 256 + + mval.character_value; + define(p, math_given_cmd, cur_val); break; - case skip_def_code: - define(p, assign_glue_cmd, skip_base + cur_val); + case xmath_char_def_code: + mval = scan_mathchar(umath_mathcode); + cur_val = + (mval.class_value + (8 * mval.family_value)) * (65536 * 32) + + mval.character_value; + define(p, xmath_given_cmd, cur_val); break; - case mu_skip_def_code: - define(p, assign_mu_glue_cmd, mu_skip_base + cur_val); - break; - case toks_def_code: - define(p, assign_toks_cmd, toks_base + cur_val); + case umath_char_def_code: + mval = scan_mathchar(umathnum_mathcode); + cur_val = + (mval.class_value + (8 * mval.family_value)) * (65536 * 32) + + mval.character_value; + define(p, xmath_given_cmd, cur_val); break; default: - confusion("shorthand_def"); + scan_register_num(); + switch (n) { + case count_def_code: + define(p, assign_int_cmd, count_base + cur_val); + break; + case attribute_def_code: + define(p, assign_attr_cmd, attribute_base + cur_val); + break; + case dimen_def_code: + define(p, assign_dimen_cmd, scaled_base + cur_val); + break; + case skip_def_code: + define(p, assign_glue_cmd, skip_base + cur_val); + break; + case mu_skip_def_code: + define(p, assign_mu_glue_cmd, mu_skip_base + cur_val); + break; + case toks_def_code: + define(p, assign_toks_cmd, toks_base + cur_val); + break; + default: + confusion("shorthand_def"); + break; + } break; } break; - } - break; - case read_to_cs_cmd: - j = cur_chr; - scan_int(); - n = cur_val; - if (!scan_keyword("to")) { - print_err("Missing `to' inserted"); - help2("You should have said `\\read<number> to \\cs'.", - "I'm going to look for the \\cs now."); - error(); - } - get_r_token(); - p = cur_cs; - read_toks(n, p, j); - define(p, call_cmd, cur_val); - break; - case toks_register_cmd: - case assign_toks_cmd: - /* The token-list parameters, \.{\\output} and \.{\\everypar}, etc., receive - their values in the following way. (For safety's sake, we place an - enclosing pair of braces around an \.{\\output} list.) */ - q = cur_cs; - if (cur_cmd == toks_register_cmd) { - scan_register_num(); - p = toks_base + cur_val; - } else { - p = cur_chr; /* |p=every_par_loc| or |output_routine_loc| or \dots */ - } - scan_optional_equals(); - /* Get the next non-blank non-relax non-call token */ - do { - get_x_token(); - } while ((cur_cmd == spacer_cmd) || (cur_cmd == relax_cmd)); - - if (cur_cmd != left_brace_cmd) { - /* If the right-hand side is a token parameter - or token register, finish the assignment and |goto done| */ + case read_to_cs_cmd: + j = cur_chr; + scan_int(); + n = cur_val; + if (!scan_keyword("to")) { + print_err("Missing `to' inserted"); + help2("You should have said `\\read<number> to \\cs'.", + "I'm going to look for the \\cs now."); + error(); + } + get_r_token(); + p = cur_cs; + read_toks(n, p, j); + define(p, call_cmd, cur_val); + break; + case toks_register_cmd: + case assign_toks_cmd: + /* The token-list parameters, \.{\\output} and \.{\\everypar}, etc., receive + their values in the following way. (For safety's sake, we place an + enclosing pair of braces around an \.{\\output} list.) */ + q = cur_cs; if (cur_cmd == toks_register_cmd) { scan_register_num(); - cur_cmd = assign_toks_cmd; - cur_chr = toks_base + cur_val; + p = toks_base + cur_val; + } else { + p = cur_chr; /* |p=every_par_loc| or |output_routine_loc| or \dots */ } - if (cur_cmd == assign_toks_cmd) { - q = equiv(cur_chr); - if (q == null) { - define(p, undefined_cs_cmd, null); - } else { - add_token_ref(q); - define(p, call_cmd, q); + scan_optional_equals(); + /* Get the next non-blank non-relax non-call token */ + do { + get_x_token(); + } while ((cur_cmd == spacer_cmd) || (cur_cmd == relax_cmd)); + + if (cur_cmd != left_brace_cmd) { + /* If the right-hand side is a token parameter + or token register, finish the assignment and |goto done| */ + if (cur_cmd == toks_register_cmd) { + scan_register_num(); + cur_cmd = assign_toks_cmd; + cur_chr = toks_base + cur_val; + } + if (cur_cmd == assign_toks_cmd) { + q = equiv(cur_chr); + if (q == null) { + define(p, undefined_cs_cmd, null); + } else { + add_token_ref(q); + define(p, call_cmd, q); + } + goto DONE; } - goto DONE; } - } - back_input(); - cur_cs = q; - q = scan_toks(false, false); - if (token_link(def_ref) == null) { /* empty list: revert to the default */ - define(p, undefined_cs_cmd, null); - free_avail(def_ref); - } else { - if (p == output_routine_loc) { /* enclose in curlies */ - p = get_avail(); - set_token_link(q, p); - p = output_routine_loc; - q = token_link(q); - set_token_info(q, right_brace_token + '}'); - q = get_avail(); - set_token_info(q, left_brace_token + '{'); - set_token_link(q, token_link(def_ref)); - set_token_link(def_ref, q); + back_input(); + cur_cs = q; + q = scan_toks(false, false); + if (token_link(def_ref) == null) { /* empty list: revert to the default */ + define(p, undefined_cs_cmd, null); + free_avail(def_ref); + } else { + if (p == output_routine_loc) { /* enclose in curlies */ + p = get_avail(); + set_token_link(q, p); + p = output_routine_loc; + q = token_link(q); + set_token_info(q, right_brace_token + '}'); + q = get_avail(); + set_token_info(q, left_brace_token + '{'); + set_token_link(q, token_link(def_ref)); + set_token_link(def_ref, q); + } + define(p, call_cmd, def_ref); } - define(p, call_cmd, def_ref); - } - break; - case assign_int_cmd: - /* Similar routines are used to assign values to the numeric parameters. */ - p = cur_chr; - scan_optional_equals(); - scan_int(); - assign_internal_value(a, p, cur_val); - break; - case assign_attr_cmd: - p = cur_chr; - scan_optional_equals(); - scan_int(); - if ((p - attribute_base) > max_used_attr) - max_used_attr = (p - attribute_base); - attr_list_cache = cache_disabled; - word_define(p, cur_val); - break; - case assign_dir_cmd: - /* DIR: Assign direction codes */ - scan_direction(); - switch (cur_chr) { - case int_base + page_direction_code: - eq_word_define(int_base + page_direction_code, cur_val); break; - case int_base + body_direction_code: - eq_word_define(int_base + body_direction_code, cur_val); - break; - case int_base + par_direction_code: - eq_word_define(int_base + par_direction_code, cur_val); + case assign_int_cmd: + /* Similar routines are used to assign values to the numeric parameters. */ + p = cur_chr; + scan_optional_equals(); + scan_int(); + assign_internal_value(a, p, cur_val); break; - case int_base + math_direction_code: - eq_word_define(int_base + math_direction_code, cur_val); + case assign_attr_cmd: + p = cur_chr; + scan_optional_equals(); + scan_int(); + if ((p - attribute_base) > max_used_attr) + max_used_attr = (p - attribute_base); + attr_list_cache = cache_disabled; + word_define(p, cur_val); break; - case int_base + text_direction_code: + case assign_dir_cmd: + /* DIR: Assign direction codes */ + scan_direction(); + switch (cur_chr) { + case int_base + page_direction_code: + eq_word_define(int_base + page_direction_code, cur_val); + break; + case int_base + body_direction_code: + eq_word_define(int_base + body_direction_code, cur_val); + break; + case int_base + par_direction_code: + eq_word_define(int_base + par_direction_code, cur_val); + break; + case int_base + math_direction_code: + eq_word_define(int_base + math_direction_code, cur_val); + break; + case int_base + text_direction_code: #if 0 /* various tests hint that this is unnecessary and * sometimes even produces weird results, eg @@ -2528,319 +2509,322 @@ void prefixed_command(void) * (DEFCBA) * in the output */ - if ((no_local_dirs > 0) && (abs(mode) == hmode)) { - /* DIR: Add local dir node */ - tail_append(new_dir(text_direction)); - } + if ((no_local_dirs > 0) && (abs(mode) == hmode)) { + /* DIR: Add local dir node */ + tail_append(new_dir(text_direction)); + } #endif - update_text_dir_ptr(cur_val); - if (abs(mode) == hmode) { - /* DIR: Add local dir node */ - tail_append(new_dir(cur_val)); - dir_level(tail) = cur_level; + update_text_dir_ptr(cur_val); + if (abs(mode) == hmode) { + /* DIR: Add local dir node */ + tail_append(new_dir(cur_val)); + dir_level(tail) = cur_level; + } + eq_word_define(int_base + text_direction_code, cur_val); + eq_word_define(int_base + no_local_dirs_code, no_local_dirs + 1); + break; } - eq_word_define(int_base + text_direction_code, cur_val); - eq_word_define(int_base + no_local_dirs_code, no_local_dirs + 1); break; - } - break; - case assign_dimen_cmd: - p = cur_chr; - scan_optional_equals(); - scan_normal_dimen(); - assign_internal_value(a, p, cur_val); - break; - case assign_glue_cmd: - case assign_mu_glue_cmd: - p = cur_chr; - n = cur_cmd; - scan_optional_equals(); - if (n == assign_mu_glue_cmd) - scan_glue(mu_val_level); - else - scan_glue(glue_val_level); - trap_zero_glue(); - define(p, glue_ref_cmd, cur_val); - break; - case def_char_code_cmd: - case def_del_code_cmd: - /* Let |n| be the largest legal code value, based on |cur_chr| */ - if (cur_chr == cat_code_base) - n = max_char_code; - else if (cur_chr == sf_code_base) - n = 077777; - else - n = biggest_char; + case assign_dimen_cmd: + p = cur_chr; + scan_optional_equals(); + scan_normal_dimen(); + assign_internal_value(a, p, cur_val); + break; + case assign_glue_cmd: + case assign_mu_glue_cmd: + p = cur_chr; + n = cur_cmd; + scan_optional_equals(); + if (n == assign_mu_glue_cmd) + scan_glue(mu_val_level); + else + scan_glue(glue_val_level); + trap_zero_glue(); + define(p, glue_ref_cmd, cur_val); + break; + case def_char_code_cmd: + case def_del_code_cmd: + /* Let |n| be the largest legal code value, based on |cur_chr| */ + if (cur_chr == cat_code_base) + n = max_char_code; + else if (cur_chr == sf_code_base) + n = 077777; + else + n = biggest_char; - p = cur_chr; - if (cur_chr == math_code_base) { + p = cur_chr; + if (cur_chr == math_code_base) { + if (is_global(a)) + cur_val1 = level_one; + else + cur_val1 = cur_level; + scan_extdef_math_code(cur_val1, tex_mathcode); + } else if (cur_chr == lc_code_base) { + scan_char_num(); + p = cur_val; + scan_optional_equals(); + scan_int(); + check_def_code(lc_code_base); + define_lc_code(p, cur_val); + } else if (cur_chr == uc_code_base) { + scan_char_num(); + p = cur_val; + scan_optional_equals(); + scan_int(); + check_def_code(uc_code_base); + define_uc_code(p, cur_val); + } else if (cur_chr == sf_code_base) { + scan_char_num(); + p = cur_val; + scan_optional_equals(); + scan_int(); + check_def_code(sf_code_base); + define_sf_code(p, cur_val); + } else if (cur_chr == cat_code_base) { + scan_char_num(); + p = cur_val; + scan_optional_equals(); + scan_int(); + check_def_code(cat_code_base); + define_cat_code(p, cur_val); + } else if (cur_chr == del_code_base) { + if (is_global(a)) + cur_val1 = level_one; + else + cur_val1 = cur_level; + scan_extdef_del_code(cur_val1, tex_mathcode); + } + break; + case extdef_math_code_cmd: + case extdef_del_code_cmd: if (is_global(a)) cur_val1 = level_one; else cur_val1 = cur_level; - scan_extdef_math_code(cur_val1, tex_mathcode); - } else if (cur_chr == lc_code_base) { - scan_char_num(); - p = cur_val; - scan_optional_equals(); - scan_int(); - check_def_code(lc_code_base); - define_lc_code(p, cur_val); - } else if (cur_chr == uc_code_base) { - scan_char_num(); - p = cur_val; - scan_optional_equals(); - scan_int(); - check_def_code(uc_code_base); - define_uc_code(p, cur_val); - } else if (cur_chr == sf_code_base) { - scan_char_num(); - p = cur_val; + if (cur_chr == math_code_base) + scan_extdef_math_code(cur_val1, umath_mathcode); + else if (cur_chr == math_code_base + 1) + scan_extdef_math_code(cur_val1, umathnum_mathcode); + else if (cur_chr == del_code_base) + scan_extdef_del_code(cur_val1, umath_mathcode); + else if (cur_chr == del_code_base + 1) + scan_extdef_del_code(cur_val1, umathnum_mathcode); + break; + case def_family_cmd: + p = cur_chr; + scan_math_family_int(); + cur_val1 = cur_val; scan_optional_equals(); - scan_int(); - check_def_code(sf_code_base); - define_sf_code(p, cur_val); - } else if (cur_chr == cat_code_base) { - scan_char_num(); - p = cur_val; + scan_font_ident(); + define_fam_fnt(cur_val1, p, cur_val); + break; + case set_math_param_cmd: + p = cur_chr; + get_token(); + if (cur_cmd != math_style_cmd) { + print_err("Missing math style, treated as \\displaystyle"); + help1 + ("A style should have been here; I inserted `\\displaystyle'."); + cur_val1 = display_style; + back_error(); + } else { + cur_val1 = cur_chr; + } scan_optional_equals(); - scan_int(); - check_def_code(cat_code_base); - define_cat_code(p, cur_val); - } else if (cur_chr == del_code_base) { + if (p < math_param_first_mu_glue) { + if (p == math_param_radical_degree_raise) + scan_int(); + else + scan_dimen(false, false, false); + } else { + scan_glue(mu_val_level); + trap_zero_glue(); + if (cur_val == glue_par(thin_mu_skip_code)) + cur_val = thin_mu_skip_code; + else if (cur_val == glue_par(med_mu_skip_code)) + cur_val = med_mu_skip_code; + else if (cur_val == glue_par(thick_mu_skip_code)) + cur_val = thick_mu_skip_code; + } + define_math_param(p, cur_val1, cur_val); + break; + case register_cmd: + case advance_cmd: + case multiply_cmd: + case divide_cmd: + do_register_command(a); + break; + case set_box_cmd: + /* The processing of boxes is somewhat different, because we may need + to scan and create an entire box before we actually change the value + of the old one. */ + scan_register_num(); if (is_global(a)) - cur_val1 = level_one; - else - cur_val1 = cur_level; - scan_extdef_del_code(cur_val1, tex_mathcode); - } - break; - case extdef_math_code_cmd: - case extdef_del_code_cmd: - if (is_global(a)) - cur_val1 = level_one; - else - cur_val1 = cur_level; - if (cur_chr == math_code_base) - scan_extdef_math_code(cur_val1, umath_mathcode); - else if (cur_chr == math_code_base + 1) - scan_extdef_math_code(cur_val1, umathnum_mathcode); - else if (cur_chr == del_code_base) - scan_extdef_del_code(cur_val1, umath_mathcode); - else if (cur_chr == del_code_base + 1) - scan_extdef_del_code(cur_val1, umathnum_mathcode); - break; - case def_family_cmd: - p = cur_chr; - scan_math_family_int(); - cur_val1 = cur_val; - scan_optional_equals(); - scan_font_ident(); - define_fam_fnt(cur_val1, p, cur_val); - break; - case set_math_param_cmd: - p = cur_chr; - get_token(); - if (cur_cmd != math_style_cmd) { - print_err("Missing math style, treated as \\displaystyle"); - help1 - ("A style should have been here; I inserted `\\displaystyle'."); - cur_val1 = display_style; - back_error(); - } else { - cur_val1 = cur_chr; - } - scan_optional_equals(); - if (p < math_param_first_mu_glue) { - if (p == math_param_radical_degree_raise) - scan_int(); + n = global_box_flag + cur_val; else - scan_dimen(false, false, false); - } else { - scan_glue(mu_val_level); - trap_zero_glue(); - if (cur_val == glue_par(thin_mu_skip_code)) - cur_val = thin_mu_skip_code; - else if (cur_val == glue_par(med_mu_skip_code)) - cur_val = med_mu_skip_code; - else if (cur_val == glue_par(thick_mu_skip_code)) - cur_val = thick_mu_skip_code; - } - define_math_param(p, cur_val1, cur_val); - break; - case register_cmd: - case advance_cmd: - case multiply_cmd: - case divide_cmd: - do_register_command(a); - break; - case set_box_cmd: - /* The processing of boxes is somewhat different, because we may need - to scan and create an entire box before we actually change the value - of the old one. */ - scan_register_num(); - if (is_global(a)) - n = global_box_flag + cur_val; - else - n = box_flag + cur_val; - scan_optional_equals(); - if (set_box_allowed) { - scan_box(n); - } else { - print_err("Improper \\setbox"); - help2("Sorry, \\setbox is not allowed after \\halign in a display,", - "or between \\accent and an accented character."); - error(); - } - break; - case set_aux_cmd: - /* The |space_factor| or |prev_depth| settings are changed when a |set_aux| - command is sensed. Similarly, |prev_graf| is changed in the presence of - |set_prev_graf|, and |dead_cycles| or |insert_penalties| in the presence of - |set_page_int|. These definitions are always global. */ - alter_aux(); - break; - case set_prev_graf_cmd: - alter_prev_graf(); - break; - case set_page_dimen_cmd: - alter_page_so_far(); - break; - case set_page_int_cmd: - alter_integer(); - break; - case set_box_dimen_cmd: - /* When some dimension of a box register is changed, the change isn't exactly - global; but \TeX\ does not look at the \.{\\global} switch. */ - alter_box_dimen(); - break; - case set_tex_shape_cmd: - q = cur_chr; - scan_optional_equals(); - scan_int(); - n = cur_val; - if (n <= 0) { - p = null; - } else { - p = new_node(shape_node, 2 * (n + 1) + 1); - vinfo(p + 1) = n; - for (j = 1; j <= n; j++) { - scan_normal_dimen(); - varmem[p + 2 * j].cint = cur_val; /* indentation */ - scan_normal_dimen(); - varmem[p + 2 * j + 1].cint = cur_val; /* width */ - } - } - define(q, shape_ref_cmd, p); - break; - case set_etex_shape_cmd: - q = cur_chr; - scan_optional_equals(); - scan_int(); - n = cur_val; - if (n <= 0) { - p = null; - } else { - n = (cur_val / 2) + 1; - p = new_node(shape_node, 2 * n + 1 + 1); - vinfo(p + 1) = n; - n = cur_val; - varmem[p + 2].cint = n; /* number of penalties */ - for (j = p + 3; j <= p + n + 2; j++) { - scan_int(); - varmem[j].cint = cur_val; /* penalty values */ + n = box_flag + cur_val; + scan_optional_equals(); + if (set_box_allowed) { + scan_box(n); + } else { + print_err("Improper \\setbox"); + help2("Sorry, \\setbox is not allowed after \\halign in a display,", + "or between \\accent and an accented character."); + error(); } - if (!odd(n)) - varmem[p + n + 3].cint = 0; /* unused */ - } - define(q, shape_ref_cmd, p); - break; - case hyph_data_cmd: - /* All of \TeX's parameters are kept in |eqtb| except the font information, - the interaction mode, and the hyphenation tables; these are strictly global. - */ - switch (cur_chr) { - case 0: - new_hyph_exceptions(); - break; - case 1: - new_patterns(); break; - case 2: - new_pre_hyphen_char(); + case set_aux_cmd: + /* The |space_factor| or |prev_depth| settings are changed when a |set_aux| + command is sensed. Similarly, |prev_graf| is changed in the presence of + |set_prev_graf|, and |dead_cycles| or |insert_penalties| in the presence of + |set_page_int|. These definitions are always global. */ + alter_aux(); break; - case 3: - new_post_hyphen_char(); + case set_prev_graf_cmd: + alter_prev_graf(); break; - case 4: - new_pre_exhyphen_char(); + case set_page_dimen_cmd: + alter_page_so_far(); break; - case 5: - new_post_exhyphen_char(); + case set_page_int_cmd: + alter_integer(); break; - case 6: - new_hyphenation_min(); + case set_box_dimen_cmd: + /* When some dimension of a box register is changed, the change isn't exactly + global; but \TeX\ does not look at the \.{\\global} switch. */ + alter_box_dimen(); break; - } - break; - case assign_font_dimen_cmd: - set_font_dimen(); - break; - case assign_font_int_cmd: - n = cur_chr; - scan_font_ident(); - f = cur_val; - if (n == no_lig_code) { - set_no_ligatures(f); - } else if (n < lp_code_base) { + case set_tex_shape_cmd: + q = cur_chr; scan_optional_equals(); scan_int(); - if (n == 0) - set_hyphen_char(f, cur_val); - else - set_skew_char(f, cur_val); - } else { - scan_char_num(); - p = cur_val; + n = cur_val; + if (n <= 0) { + p = null; + } else { + p = new_node(shape_node, 2 * (n + 1) + 1); + vinfo(p + 1) = n; + for (j = 1; j <= n; j++) { + scan_normal_dimen(); + varmem[p + 2 * j].cint = cur_val; /* indentation */ + scan_normal_dimen(); + varmem[p + 2 * j + 1].cint = cur_val; /* width */ + } + } + define(q, shape_ref_cmd, p); + break; + case set_etex_shape_cmd: + q = cur_chr; scan_optional_equals(); scan_int(); - switch (n) { - case lp_code_base: - set_lp_code(f, p, cur_val); - break; - case rp_code_base: - set_rp_code(f, p, cur_val); - break; - case ef_code_base: - set_ef_code(f, p, cur_val); - break; - case tag_code: - set_tag_code(f, p, cur_val); - break; + n = cur_val; + if (n <= 0) { + p = null; + } else { + n = (cur_val / 2) + 1; + p = new_node(shape_node, 2 * n + 1 + 1); + vinfo(p + 1) = n; + n = cur_val; + varmem[p + 2].cint = n; /* number of penalties */ + for (j = p + 3; j <= p + n + 2; j++) { + scan_int(); + varmem[j].cint = cur_val; /* penalty values */ + } + if (!odd(n)) + varmem[p + n + 3].cint = 0; /* unused */ } - } - break; - case def_font_cmd: - /* Here is where the information for a new font gets loaded. */ - tex_def_font((small_number) a); - break; - case letterspace_font_cmd: - new_letterspaced_font((small_number) a); - break; - case copy_font_cmd: - make_font_copy((small_number) a); - break; - case set_font_id_cmd: - scan_int(); - if (is_valid_font(cur_val)) - zset_cur_font(cur_val); - break ; - case set_interaction_cmd: - new_interaction(); - break; - default: - confusion("prefix"); - break; + define(q, shape_ref_cmd, p); + break; + case hyph_data_cmd: + /* All of \TeX's parameters are kept in |eqtb| except the font information, + the interaction mode, and the hyphenation tables; these are strictly global. + */ + switch (cur_chr) { + case 0: + new_hyph_exceptions(); + break; + case 1: + new_patterns(); + break; + case 2: + new_pre_hyphen_char(); + break; + case 3: + new_post_hyphen_char(); + break; + case 4: + new_pre_exhyphen_char(); + break; + case 5: + new_post_exhyphen_char(); + break; + case 6: + new_hyphenation_min(); + break; + case 7: + new_hj_code(); + break; + } + break; + case assign_font_dimen_cmd: + set_font_dimen(); + break; + case assign_font_int_cmd: + n = cur_chr; + scan_font_ident(); + f = cur_val; + if (n == no_lig_code) { + set_no_ligatures(f); + } else if (n < lp_code_base) { + scan_optional_equals(); + scan_int(); + if (n == 0) + set_hyphen_char(f, cur_val); + else + set_skew_char(f, cur_val); + } else { + scan_char_num(); + p = cur_val; + scan_optional_equals(); + scan_int(); + switch (n) { + case lp_code_base: + set_lp_code(f, p, cur_val); + break; + case rp_code_base: + set_rp_code(f, p, cur_val); + break; + case ef_code_base: + set_ef_code(f, p, cur_val); + break; + case tag_code: + set_tag_code(f, p, cur_val); + break; + } + } + break; + case def_font_cmd: + /* Here is where the information for a new font gets loaded. */ + tex_def_font((small_number) a); + break; + case letterspace_font_cmd: + new_letterspaced_font((small_number) a); + break; + case copy_font_cmd: + make_font_copy((small_number) a); + break; + case set_font_id_cmd: + scan_int(); + if (is_valid_font(cur_val)) + zset_cur_font(cur_val); + break ; + case set_interaction_cmd: + new_interaction(); + break; + default: + confusion("prefix"); + break; } /* end of Assignments cases */ DONE: /* Insert a token saved by \.{\\afterassignment}, if any */ @@ -2854,36 +2838,29 @@ void prefixed_command(void) @ @c void fixup_directions(void) { - int temp_no_whatsits; - int temp_no_dirs; - int temporary_dir; - temp_no_whatsits = no_local_whatsits; - temp_no_dirs = no_local_dirs; - temporary_dir = text_direction; + int temp_no_whatsits = no_local_whatsits; + int temp_no_dirs = no_local_dirs; + int temporary_dir = text_direction; if (dir_level(text_dir_ptr) == cur_level) { /* DIR: Remove from |text_dir_ptr| */ halfword text_dir_tmp = vlink(text_dir_ptr); flush_node(text_dir_ptr); text_dir_ptr = text_dir_tmp; - } unsave(); if (abs(mode) == hmode) { if (temp_no_dirs != 0) { /* DIR: Add local dir node */ tail_append(new_dir(text_direction)); - dir_dir(tail) = temporary_dir - dir_swap; } if (temp_no_whatsits != 0) { /* LOCAL: Add local paragraph node */ tail_append(make_local_par_node()); - } } } - @ When a control sequence is to be defined, by \.{\\def} or \.{\\let} or something similar, the |get_r_token| routine will substitute a special control sequence for a token that is not redefinable. @@ -2963,7 +2940,7 @@ void assign_internal_value(int a, halfword p, int val) break; case language_code: if (val < 0) { - word_define(int_base + cur_lang_code, -1); + word_define(int_base + cur_lang_code, -1); word_define(p, -1); } else if (val > 16383) { print_err("Invalid \\language"); @@ -2972,7 +2949,7 @@ void assign_internal_value(int a, halfword p, int val) "Your invalid assignment will be ignored."); error(); } else { - word_define(int_base + cur_lang_code, val); + word_define(int_base + cur_lang_code, val); word_define(p, val); } break; @@ -2994,7 +2971,6 @@ void assign_internal_value(int a, halfword p, int val) eq_word_define(int_base + no_local_whatsits_code, no_local_whatsits + 1); } - } else if ((p >= dimen_base) && (p <= eqtb_size)) { if (p == (dimen_base + page_left_offset_code)) { n = val - one_true_inch; @@ -3010,7 +2986,6 @@ void assign_internal_value(int a, halfword p, int val) word_define(dimen_base + page_top_offset_code, n); } word_define(p, val); - } else if ((p >= local_base) && (p < toks_base)) { /* internal locals */ define(p, call_cmd, val); } else { @@ -3018,7 +2993,6 @@ void assign_internal_value(int a, halfword p, int val) } } - @ When a glue register or parameter becomes zero, it will always point to |zero_glue| because of the following procedure. (Exception: The tabskip glue isn't trapped while preambles are being scanned.) @@ -3036,16 +3010,16 @@ void trap_zero_glue(void) @ We use the fact that |register<advance<multiply<divide| +Compute the register location |l| and its type |p|; but |return| if invalid +Here we use the fact that the consecutive codes |int_val..mu_val| and +|assign_int..assign_mu_glue| correspond to each other nicely. + @c void do_register_command(int a) { - halfword l, q, r, s; /* for list manipulation */ - int p; /* type of register involved */ - q = cur_cmd; - /* Compute the register location |l| and its type |p|; but |return| if invalid */ - /* Here we use the fact that the consecutive codes |int_val..mu_val| and - |assign_int..assign_mu_glue| correspond to each other nicely. */ - l = 0; + int p; + halfword q = cur_cmd; + halfword l = 0; if (q != register_cmd) { get_x_token(); if ((cur_cmd >= assign_int_cmd) && (cur_cmd <= assign_mu_glue_cmd)) { @@ -3075,12 +3049,11 @@ void do_register_command(int a) l = cur_val + skip_base; else if (p == mu_val_level) l = cur_val + mu_skip_base; - FOUND: if (q == register_cmd) { scan_optional_equals(); } else if (scan_keyword("by")) { - ; /* optional `\.{by}' */ + /* optional `\.{by}' */ } arith_error = false; if (q < multiply_cmd) { @@ -3096,8 +3069,8 @@ void do_register_command(int a) scan_glue(p); if (q == advance_cmd) { /* Compute the sum of two glue specs */ + halfword r = equiv(l); q = new_spec(cur_val); - r = equiv(l); delete_glue_ref(cur_val); width(q) = width(q) + width(r); if (stretch(q) == 0) { @@ -3123,7 +3096,6 @@ void do_register_command(int a) cur_val = q; } } - } else { /* Compute result of |multiply| or |divide|, put it in |cur_val| */ scan_int(); @@ -3138,8 +3110,8 @@ void do_register_command(int a) cur_val = x_over_n(eqtb[l].cint, cur_val); } } else { - s = equiv(l); - r = new_spec(s); + halfword s = equiv(l); + halfword r = new_spec(s); if (q == multiply_cmd) { width(r) = nx_plus_y(width(s), cur_val, 0); stretch(r) = nx_plus_y(stretch(s), cur_val, 0); @@ -3151,7 +3123,6 @@ void do_register_command(int a) } cur_val = r; } - } if (arith_error) { print_err("Arithmetic overflow"); @@ -3178,7 +3149,6 @@ void do_register_command(int a) } } - @ @c void alter_aux(void) { @@ -3270,7 +3240,6 @@ void alter_box_dimen(void) varmem[box(b) + c].cint = cur_val; } - @ @c void new_interaction(void) { @@ -3283,7 +3252,6 @@ void new_interaction(void) fixup_selector(log_opened_global); } - @ The \.{\\afterassignment} command puts a token into the global variable |after_token|. This global variable is examined just after every assignment has been performed. @@ -3291,7 +3259,6 @@ every assignment has been performed. @c halfword after_token; /* zero, or a saved token */ - @ Here is a procedure that might be called `Get the next non-blank non-relax non-call non-assignment token'. @@ -3303,7 +3270,6 @@ void do_assignments(void) do { get_x_token(); } while ((cur_cmd == spacer_cmd) || (cur_cmd == relax_cmd)); - if (cur_cmd <= max_non_prefixed_command) return; set_box_allowed = false; @@ -3397,7 +3363,6 @@ void issue_message(void) flush_str(s); } - @ The |error| routine calls on |give_err_help| if help is requested from the |err_help| parameter. @@ -3407,8 +3372,6 @@ void give_err_help(void) token_show(err_help); } - - @ The \.{\\uppercase} and \.{\\lowercase} commands are implemented by building a token list and then changing the cases of the letters in it. @@ -3453,7 +3416,6 @@ void shift_case(void) free_avail(def_ref); /* omit reference count */ } - @ We come finally to the last pieces missing from |main_control|, namely the `\.{\\show}' commands that are useful when debugging. @@ -3534,7 +3496,6 @@ void show_whatever(void) } while (p != null); } break; - default: /* Show the current value of some parameter or register, then |goto common_ending| */ @@ -3557,7 +3518,6 @@ void show_whatever(void) selector = term_and_log; } } - COMMON_ENDING: if (interaction < error_stop_mode) { help0(); @@ -3576,7 +3536,6 @@ void show_whatever(void) error(); } - @ @c void initialize(void) { /* this procedure gets things started properly */ @@ -3610,8 +3569,7 @@ void initialize(void) initialize_marks(); initialize_read(); - assert(static_pdf == NULL); - static_pdf = init_pdf_struct(static_pdf); + static_pdf = init_pdf_struct(static_pdf); /* should be init_backend() */ format_ident = 0; format_name = get_nullstr(); @@ -3675,11 +3633,10 @@ void initialize(void) initialize_text_codes(); initex_cat_codes(0); for (k = '0'; k <= '9'; k++) - set_math_code(k, tex_mathcode, var_code, 0, k, level_one); + set_math_code(k, var_code, 0, k, level_one); for (k = 'A'; k <= 'Z'; k++) { - set_math_code(k, tex_mathcode, var_code, 1, k, level_one); - set_math_code((k + 32), tex_mathcode, var_code, 1, (k + 32), - level_one); + set_math_code(k, var_code, 1, k, level_one); + set_math_code((k + 32), var_code, 1, (k + 32), level_one); set_lc_code(k, k + 32, level_one); set_lc_code(k + 32, k + 32, level_one); set_uc_code(k, k, level_one); @@ -3696,7 +3653,7 @@ void initialize(void) max_dead_cycles = 25; escape_char = '\\'; end_line_char = carriage_return; - set_del_code('.', tex_mathcode, 0, 0, 0, 0, level_one); /* this null delimiter is used in error recovery */ + set_del_code('.', 0, 0, 0, 0, level_one); /* this null delimiter is used in error recovery */ ex_hyphen_char = '-'; output_box = 255; for (k = dimen_base; k <= eqtb_size; k++) diff --git a/Build/source/texk/web2c/luatexdir/tex/mathcodes.h b/Build/source/texk/web2c/luatexdir/tex/mathcodes.h index a2f84eb8411..1742e43cfd5 100644 --- a/Build/source/texk/web2c/luatexdir/tex/mathcodes.h +++ b/Build/source/texk/web2c/luatexdir/tex/mathcodes.h @@ -1,5 +1,5 @@ /* mathcodes.h - + Copyright 2009-2012 Taco Hoekwater <taco@luatex.org> This file is part of LuaTeX. @@ -15,33 +15,30 @@ 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/>. */ + with LuaTeX; if not, see <http://www.gnu.org/licenses/>. +*/ #ifndef MATHCODES_H # define MATHCODES_H -/* mathcodes.c */ +/* this is a flag for |scan_delimiter| */ -# define no_mathcode 0 /* this is a flag for |scan_delimiter| */ -# define tex_mathcode 8 -# define umath_mathcode 21 +# define no_mathcode 0 +# define tex_mathcode 8 +# define umath_mathcode 21 # define umathnum_mathcode 22 typedef struct mathcodeval { int class_value; - int origin_value; int family_value; int character_value; } mathcodeval; -void set_math_code(int n, - int commandorigin, - int mathclass, - int mathfamily, int mathcharacter, quarterword gl); +void set_math_code(int n, int mathclass, int mathfamily, int mathcharacter, quarterword gl); mathcodeval get_math_code(int n); -int get_math_code_num(int n, boolean compat); +int get_math_code_num(int n); int get_del_code_num(int n); mathcodeval scan_mathchar(int extcode); mathcodeval scan_delimiter_as_mathchar(int extcode); @@ -51,18 +48,13 @@ void show_mathcode_value(mathcodeval d); typedef struct delcodeval { int class_value; - int origin_value; int small_family_value; int small_character_value; int large_family_value; int large_character_value; } delcodeval; -void set_del_code(int n, - int commandorigin, - int smathfamily, - int smathcharacter, - int lmathfamily, int lmathcharacter, quarterword gl); +void set_del_code(int n, int smathfamily, int smathcharacter, int lmathfamily, int lmathcharacter, quarterword gl); delcodeval get_del_code(int n); diff --git a/Build/source/texk/web2c/luatexdir/tex/mathcodes.w b/Build/source/texk/web2c/luatexdir/tex/mathcodes.w index ac26fc75d9d..b9ac4905f7d 100644 --- a/Build/source/texk/web2c/luatexdir/tex/mathcodes.w +++ b/Build/source/texk/web2c/luatexdir/tex/mathcodes.w @@ -20,19 +20,12 @@ @ @c - #include "ptexlib.h" -@ math codes +@ math codes @c static sa_tree mathcode_head = NULL; -#define MATHCODEHEAP 8 - -static mathcodeval *mathcode_heap = NULL; -static int mathcode_heapsize = MATHCODEHEAP; -static int mathcode_heapptr = 0; - /* the 0xFFFFFFFF is a flag value */ #define MATHCODESTACK 8 #define MATHCODEDEFAULT 0xFFFFFFFF @@ -41,12 +34,6 @@ static int mathcode_heapptr = 0; @c static sa_tree delcode_head = NULL; -#define DELCODEHEAP 8 - -static delcodeval *delcode_heap = NULL; -static int delcode_heapsize = DELCODEHEAP; -static int delcode_heapptr = 0; - #define DELCODESTACK 4 #define DELCODEDEFAULT 0xFFFFFFFF @@ -75,48 +62,38 @@ static int delcode_heapptr = 0; } while (0) @ @c -void show_mathcode_value(mathcodeval c) +mathcodeval mathchar_from_integer(int value, int extcode) { - if (c.origin_value == umath_mathcode) { - print_char('"'); - print_hex_digit(c.class_value); - print_char('"'); - two_hex(c.family_value); - print_char('"'); - six_hex(c.character_value); - } else if (c.origin_value == umathnum_mathcode) { - int m; - m = (c.class_value + (c.family_value * 8)) * 2097152 + - c.character_value; - print_int(m); - } else { - print_char('"'); - if (c.class_value) { - print_hex_digit(c.class_value); - print_hex_digit(c.family_value); - two_hex(c.character_value); - } else if (c.family_value) { - print_hex_digit(c.family_value); - two_hex(c.character_value); - } else if (c.character_value >= 16) { - two_hex(c.character_value); - } else { - print_hex_digit(c.character_value); - } + mathcodeval mval; + if (extcode == tex_mathcode) { + mval.class_value = (value / 0x1000); + mval.family_value = ((value % 0x1000) / 0x100); + mval.character_value = (value % 0x100); + } else { /* some xetexended xetex thing */ + int mfam = (value / 0x200000) & 0x7FF; + mval.class_value = mfam % 0x08; + mval.family_value = mfam / 0x08; + mval.character_value = value & 0x1FFFFF; } + return mval; +} + +@ @c +void show_mathcode_value(mathcodeval c) +{ + print_char('"'); + print_hex_digit(c.class_value); + print_char('"'); + two_hex(c.family_value); + print_char('"'); + six_hex(c.character_value); } @ @c static void show_mathcode(int n) { mathcodeval c = get_math_code(n); - if (c.origin_value == umath_mathcode) { - tprint_esc("Umathcode"); - } else if (c.origin_value == umathnum_mathcode) { - tprint_esc("Umathcodenum"); - } else { - tprint_esc("mathcode"); - } + tprint_esc("Umathcode"); print_int(n); print_char('='); show_mathcode_value(c); @@ -128,14 +105,11 @@ static void unsavemathcode(quarterword gl) sa_stack_item st; if (mathcode_head->stack == NULL) return; - while (mathcode_head->stack_ptr > 0 && - abs(mathcode_head->stack[mathcode_head->stack_ptr].level) - >= (int) gl) { + while (mathcode_head->stack_ptr > 0 && abs(mathcode_head->stack[mathcode_head->stack_ptr].level) >= gl) { st = mathcode_head->stack[mathcode_head->stack_ptr]; if (st.level > 0) { rawset_sa_item(mathcode_head, st.code, st.value); - /* now do a trace message, if requested */ - if (int_par(tracing_restores_code) > 0) { + if (int_par(tracing_restores_code) > 1) { begin_diagnostic(); print_char('{'); tprint("restoring"); @@ -150,25 +124,14 @@ static void unsavemathcode(quarterword gl) } @ @c -void set_math_code(int n, - int commandorigin, - int mathclass, - int mathfamily, int mathcharacter, quarterword level) +void set_math_code(int n, int mathclass, int mathfamily, int mathcharacter, quarterword level) { - mathcodeval d; - d.origin_value = commandorigin; - d.class_value = mathclass; - d.family_value = mathfamily; - d.character_value = mathcharacter; - if (mathcode_heapptr == mathcode_heapsize) { - mathcode_heapsize += MATHCODEHEAP; - mathcode_heap = - Mxrealloc_array(mathcode_heap, mathcodeval, mathcode_heapsize); - } - mathcode_heap[mathcode_heapptr] = d; - set_sa_item(mathcode_head, n, (sa_tree_item) mathcode_heapptr, level); - mathcode_heapptr++; - if (int_par(tracing_assigns_code) > 0) { + sa_tree_item v; + v.math_code_value.class_value = mathclass; + v.math_code_value.family_value = mathfamily; + v.math_code_value.character_value = mathcharacter; + set_sa_item(mathcode_head, n, v, level); + if (int_par(tracing_assigns_code) > 1) { begin_diagnostic(); print_char('{'); tprint("assigning"); @@ -180,95 +143,47 @@ void set_math_code(int n, } @ @c +/* we could use two structs ... tex and umath */ + mathcodeval get_math_code(int n) { - unsigned int ret; - ret = get_sa_item(mathcode_head, n); - if (ret == MATHCODEDEFAULT) { - mathcodeval d; + mathcodeval d; + sa_tree_item v = get_sa_item(mathcode_head, n); + if (v.uint_value == MATHCODEDEFAULT) { d.class_value = 0; d.family_value = 0; - d.origin_value = (n < 256 ? tex_mathcode : umath_mathcode); d.character_value = n; - return d; } else { - return mathcode_heap[ret]; + d.class_value = v.math_code_value.class_value; + d.family_value = v.math_code_value.family_value; + d.character_value = v.math_code_value.character_value; } + return d; } - @ @c -int get_math_code_num(int n, boolean compat) +int get_math_code_num(int n) { - mathcodeval mval; - mval = get_math_code(n); - if (compat) { /* \.{\\the\\mathcode} */ - if (mval.class_value > 8 - || mval.family_value > 15 - || mval.character_value > 255) { - print_err("Extended mathchar used as mathchar"); - help2("A mathchar number must be between 0 and \"8000.", - "I changed this one to zero."); - int_error(get_math_code_num(n, false)); - return 0; - } else - return mval.class_value * 4096 + mval.family_value * 256 + mval.character_value; - } else { /* \.{\\the\\Umathcodenum} */ - return (mval.class_value + (mval.family_value * 8)) * (65536 * 32) + mval.character_value; - } - return 0; + mathcodeval d = get_math_code(n); + return (d.class_value + (d.family_value * 8)) * (65536 * 32) + d.character_value; } @ @c static void initializemathcode(void) { - mathcode_head = new_sa_tree(MATHCODESTACK, MATHCODEDEFAULT); - mathcode_heap = Mxmalloc_array(mathcodeval, MATHCODEHEAP); + sa_tree_item sa_value = { 0 }; + sa_value.uint_value = MATHCODEDEFAULT; + mathcode_head = new_sa_tree(MATHCODESTACK, 1, sa_value); } -@ @c static void dumpmathcode(void) { - int k; - mathcodeval d; dump_sa_tree(mathcode_head); - dump_int(mathcode_heapsize); - dump_int(mathcode_heapptr); - for (k = 0; k < mathcode_heapptr; k++) { - d = mathcode_heap[k]; - dump_int(d.origin_value); - dump_int(d.class_value); - dump_int(d.family_value); - dump_int(d.character_value); - } } static void undumpmathcode(void) { - int 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(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; - d.class_value = 0; - d.family_value = 0; - d.character_value = 0; - for (k = mathcode_heapptr; k < mathcode_heapsize; k++) { - mathcode_heap[k] = d; - } } @ @c @@ -276,54 +191,30 @@ static void show_delcode(int n) { delcodeval c; c = get_del_code(n); - if (c.origin_value == tex_mathcode) { - tprint_esc("delcode"); - } else if (c.origin_value == umath_mathcode) { - tprint_esc("Udelcode"); - } else if (c.origin_value == umathnum_mathcode) { - tprint_esc("Udelcodenum"); - } + tprint_esc("Udelcode"); print_int(n); print_char('='); if (c.small_family_value < 0) { print_char('-'); print_char('1'); } else { - if (c.origin_value == tex_mathcode) { - print_char('"'); - print_hex_digit(c.small_family_value); - two_hex(c.small_character_value); - print_hex_digit(c.large_family_value); - two_hex(c.large_character_value); - } else if (c.origin_value == umath_mathcode) { - print_char('"'); - two_hex(c.small_family_value); - six_hex(c.small_character_value); - } else if (c.origin_value == umathnum_mathcode) { - int m; - m = c.small_family_value * 2097152 + c.small_character_value; - print_int(m); - } + print_char('"'); + two_hex(c.small_family_value); + six_hex(c.small_character_value); } } - - -@ TODO: clean up the heap -@c +@ @c static void unsavedelcode(quarterword gl) { sa_stack_item st; if (delcode_head->stack == NULL) return; - while (delcode_head->stack_ptr > 0 && - abs(delcode_head->stack[delcode_head->stack_ptr].level) - >= (int) gl) { + while (delcode_head->stack_ptr > 0 && abs(delcode_head->stack[delcode_head->stack_ptr].level) >= gl) { st = delcode_head->stack[delcode_head->stack_ptr]; if (st.level > 0) { rawset_sa_item(delcode_head, st.code, st.value); - /* now do a trace message, if requested */ - if (int_par(tracing_restores_code) > 0) { + if (int_par(tracing_restores_code) > 1) { begin_diagnostic(); print_char('{'); tprint("restoring"); @@ -333,33 +224,22 @@ static void unsavedelcode(quarterword gl) end_diagnostic(false); } } - (delcode_head->stack_ptr)--; + (mathcode_head->stack_ptr)--; } - } @ @c -void set_del_code(int n, - int commandorigin, - int smathfamily, - int smathcharacter, - int lmathfamily, int lmathcharacter, quarterword gl) +void set_del_code(int n, int smathfamily, int smathcharacter, int lmathfamily, int lmathcharacter, quarterword gl) { - delcodeval d; - d.class_value = 0; - d.origin_value = commandorigin; - d.small_family_value = smathfamily; - d.small_character_value = smathcharacter; - d.large_family_value = lmathfamily; - d.large_character_value = lmathcharacter; - if (delcode_heapptr == delcode_heapsize) { - delcode_heapsize += DELCODEHEAP; - delcode_heap = - Mxrealloc_array(delcode_heap, delcodeval, delcode_heapsize); - } - delcode_heap[delcode_heapptr] = d; - set_sa_item(delcode_head, n, (sa_tree_item) delcode_heapptr, gl); - if (int_par(tracing_assigns_code) > 0) { + sa_tree_item v; + v.del_code_value.class_value = 0; + v.del_code_value.small_family_value = smathfamily; + v.del_code_value.small_character_value = smathcharacter; + v.del_code_value.dummy_value = 0; + v.del_code_value.large_family_value = lmathfamily; + v.del_code_value.large_character_value = lmathcharacter; + set_sa_item(delcode_head, n, v, gl); /* always global */ + if (int_par(tracing_assigns_code) > 1) { begin_diagnostic(); print_char('{'); tprint("assigning"); @@ -368,26 +248,27 @@ void set_del_code(int n, print_char('}'); end_diagnostic(false); } - delcode_heapptr++; } @ @c delcodeval get_del_code(int n) { - unsigned ret; - ret = get_sa_item(delcode_head, n); - if (ret == DELCODEDEFAULT) { - delcodeval d; + delcodeval d; + sa_tree_item v = get_sa_item(delcode_head, n); + if (v.uint_value == DELCODEDEFAULT) { d.class_value = 0; - d.origin_value = tex_mathcode; d.small_family_value = -1; d.small_character_value = 0; d.large_family_value = 0; d.large_character_value = 0; - return d; } else { - return delcode_heap[ret]; + d.class_value = v.del_code_value.class_value; + d.small_family_value = v.del_code_value.small_family_value; + d.small_character_value = v.del_code_value.small_character_value; + d.large_family_value = v.del_code_value.large_family_value; + d.large_character_value = v.del_code_value.large_character_value; } + return d; } @ this really only works for old-style delcodes! @@ -395,74 +276,32 @@ delcodeval get_del_code(int n) @c int get_del_code_num(int n) { - unsigned ret; - ret = get_sa_item(delcode_head, n); - if (ret == DELCODEDEFAULT) { + delcodeval d = get_del_code(n); + if (d.small_family_value < 0) { return -1; } else { - delcodeval d = delcode_heap[ret]; - if (d.origin_value == tex_mathcode) { - return ((d.small_family_value * 256 + - d.small_character_value) * 4096 + - (d.large_family_value * 256) + d.large_character_value); - } else { - return -1; - } + return ((d.small_family_value * 256 + d.small_character_value) * 4096 + + (d.large_family_value * 256) + d.large_character_value); } } @ @c static void initializedelcode(void) { - delcode_head = new_sa_tree(DELCODESTACK, DELCODEDEFAULT); - delcode_heap = Mxmalloc_array(delcodeval, DELCODEHEAP); + sa_tree_item sa_value = { 0 }; + sa_value.uint_value = DELCODEDEFAULT; + delcode_head = new_sa_tree(DELCODESTACK, 2, sa_value); } @ @c static void dumpdelcode(void) { - int k; - delcodeval d; dump_sa_tree(delcode_head); - dump_int(delcode_heapsize); - dump_int(delcode_heapptr); - for (k = 0; k < delcode_heapptr; k++) { - d = delcode_heap[k]; - dump_int(d.origin_value); - dump_int(d.class_value); - dump_int(d.small_family_value); - dump_int(d.small_character_value); - dump_int(d.large_family_value); - dump_int(d.large_character_value); - } } static void undumpdelcode(void) { - int k; - delcodeval d; delcode_head = undump_sa_tree(); - undump_int(delcode_heapsize); - undump_int(delcode_heapptr); - delcode_heap = Mxmalloc_array(delcodeval, delcode_heapsize); - for (k = 0; k < delcode_heapptr; k++) { - undump_int(d.origin_value); - undump_int(d.class_value); - undump_int(d.small_family_value); - undump_int(d.small_character_value); - undump_int(d.large_family_value); - undump_int(d.large_character_value); - delcode_heap[k] = d; - } - d.origin_value = tex_mathcode; - d.class_value = 0; - d.small_family_value = -1; - d.small_character_value = 0; - d.large_family_value = 0; - d.large_character_value = 0; - for (k = delcode_heapptr; k < delcode_heapsize; k++) { - delcode_heap[k] = d; - } } @ @c @@ -483,9 +322,7 @@ void initialize_math_codes(void) void free_math_codes(void) { destroy_sa_tree(mathcode_head); - xfree(mathcode_heap); destroy_sa_tree(delcode_head); - xfree(delcode_heap); } @ @c diff --git a/Build/source/texk/web2c/luatexdir/tex/mlist.h b/Build/source/texk/web2c/luatexdir/tex/mlist.h index 1f6551cea69..b2600bcff1b 100644 --- a/Build/source/texk/web2c/luatexdir/tex/mlist.h +++ b/Build/source/texk/web2c/luatexdir/tex/mlist.h @@ -27,11 +27,11 @@ extern int cur_size; /* extern int math_no_italic_compensation ; */ /* $$\int\limits_{|}^{|}$$ */ /* extern int math_no_char_italic ; */ /* catcode"1D443=12 $$P( PP$$ \catcode"1D443=11 $$P( PP$$ */ -extern void run_mlist_to_hlist(halfword, int, boolean); +extern void run_mlist_to_hlist(halfword, boolean, int); +extern void mlist_to_hlist(halfword, boolean, int); extern void fixup_math_parameters(int fam_id, int size_id, int f, int lvl); extern scaled get_math_quad(int a); -extern void mlist_to_hlist_args(halfword, int, boolean); #endif diff --git a/Build/source/texk/web2c/luatexdir/tex/mlist.w b/Build/source/texk/web2c/luatexdir/tex/mlist.w index a948d42b1a1..035ef6340dd 100644 --- a/Build/source/texk/web2c/luatexdir/tex/mlist.w +++ b/Build/source/texk/web2c/luatexdir/tex/mlist.w @@ -76,6 +76,7 @@ already apply that shift. #define script_space dimen_par(script_space_code) #define disable_lig int_par(disable_lig_code) #define disable_kern int_par(disable_kern_code) +#define disable_space int_par(disable_space_code) #define scripts_mode int_par(math_scripts_mode_code) #define nDEBUG @@ -1571,7 +1572,7 @@ static void math_kern(pointer p, scaled m) } @ @c -void run_mlist_to_hlist(halfword p, int mstyle, boolean penalties) +void run_mlist_to_hlist(halfword p, boolean penalties, int mstyle) { int callback_id; int a, sfix; @@ -1605,7 +1606,7 @@ void run_mlist_to_hlist(halfword p, int mstyle, boolean penalties) lua_settop(L, sfix); vlink(temp_head) = a; } else if (callback_id == 0) { - mlist_to_hlist_args(p, mstyle, penalties); + mlist_to_hlist(p, penalties, mstyle); } else { vlink(temp_head) = null; } @@ -1644,7 +1645,7 @@ static pointer clean_box(pointer p, int s, int cur_style) q = new_null_box(); goto FOUND; } - mlist_to_hlist_args(mlist, s, false); + mlist_to_hlist(mlist, false, s); q = vlink(temp_head); /* recursive call */ setup_cur_size(cur_style); FOUND: @@ -3758,7 +3759,7 @@ static pointer check_nucleus_complexity(halfword q, scaled * delta, int cur_styl p = math_list(nucleus(q)); break; case sub_mlist_node: - mlist_to_hlist_args(math_list(nucleus(q)), cur_style, false); /* recursive call */ + mlist_to_hlist(math_list(nucleus(q)), false, cur_style); /* recursive call */ setup_cur_size(cur_style); p = hpack(vlink(temp_head), 0, additional, -1); reset_attributes(p, node_attr(nucleus(q))); @@ -3773,29 +3774,25 @@ static pointer check_nucleus_complexity(halfword q, scaled * delta, int cur_styl local variables. @c -static void mlist_to_hlist(pointer mlist, boolean penalties, int cur_style) +void mlist_to_hlist(pointer mlist, boolean penalties, int cur_style) { - pointer q; /* runs through the mlist */ - pointer r; /* the most recent noad preceding |q| */ - int style; - int r_type; /* the |type| of noad |r|, or |op_noad| if |r=null| */ - int r_subtype; /* the |subtype| of noad |r| if |r_type| is |fence_noad| */ - int t; /* the effective |type| of noad |q| during the second pass */ - int t_subtype; /* the effective |subtype| of noad |q| during the second pass */ - pointer p, x, y, z; /* temporary registers for list construction */ - int pen; /* a penalty to be inserted */ - scaled max_hl, max_d; /* maximum height and depth of the list translated so far */ - scaled delta; /* italic correction offset for subscript and superscript */ - scaled cur_mu; /* the math unit width corresponding to |cur_size| */ - style = cur_style; /* tuck global parameter away as local variable */ - q = mlist; - r = null; - r_type = simple_noad; + pointer q = mlist; /* runs through the mlist */ + pointer r = null; /* the most recent noad preceding |q| */ + int style = cur_style; /* tuck global parameter away as local variable */ + int r_type = simple_noad; /* the |type| of noad |r|, or |op_noad| if |r=null| */ + int r_subtype = op_noad_type_normal; /* the |subtype| of noad |r| if |r_type| is |fence_noad| */ + int t; /* the effective |type| of noad |q| during the second pass */ + int t_subtype; /* the effective |subtype| of noad |q| during the second pass */ + pointer p = null; + pointer x = null; + pointer y = null; + pointer z = null; + int pen; /* a penalty to be inserted */ + scaled max_hl = 0; /* maximum height of the list translated so far */ + scaled max_d = 0; /* maximum depth of the list translated so far */ + scaled delta; /* italic correction offset for subscript and superscript */ + scaled cur_mu; /* the math unit width corresponding to |cur_size| */ r_subtype = op_noad_type_normal; - max_hl = 0; - max_d = 0; - x = null; - p = null; setup_cur_size(cur_style); cur_mu = x_over_n(get_math_quad(cur_size), 18); while (q != null) { @@ -4171,12 +4168,3 @@ static void mlist_to_hlist(pointer mlist, boolean penalties, int cur_style) free_node(r, get_node_size(type(r), subtype(r))); } } - -@ This used to be needed when |mlist_to_hlist| communicated via global -variables. - -@c -void mlist_to_hlist_args(pointer n, int w, boolean m) -{ - mlist_to_hlist(n, m, w); -} diff --git a/Build/source/texk/web2c/luatexdir/tex/packaging.h b/Build/source/texk/web2c/luatexdir/tex/packaging.h index c431ed15396..c3af41a123b 100644 --- a/Build/source/texk/web2c/luatexdir/tex/packaging.h +++ b/Build/source/texk/web2c/luatexdir/tex/packaging.h @@ -15,8 +15,8 @@ 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/>. */ - + with LuaTeX; if not, see <http://www.gnu.org/licenses/>. +*/ #ifndef PACKAGING_H # define PACKAGING_H @@ -24,28 +24,27 @@ /* We define some constants used when calling |hpack| to deal with font expansion. */ typedef enum { - exactly = 0, /*a box dimension is pre-specified */ - additional, /*a box dimension is increased from the natural one */ - cal_expand_ratio, /* calculate amount for font expansion after breaking - paragraph into lines */ - subst_ex_font /* substitute fonts */ + exactly = 0, /*a box dimension is pre-specified */ + additional, /*a box dimension is increased from the natural one */ + cal_expand_ratio, /* calculate amount for font expansion after breaking paragraph into lines */ + subst_ex_font /* substitute fonts */ } hpack_subtypes; -# define substituted 3 /* |subtype| of kern nodes that should be substituted */ +# define substituted 3 /* |subtype| of kern nodes that should be substituted */ extern void scan_spec(group_code c); -extern void scan_full_spec(group_code c, int spec_direction); +extern void scan_full_spec(group_code c, int spec_direction, int justpack); extern scaled total_stretch[5]; -extern scaled total_shrink[5]; /* glue found by |hpack| or |vpack| */ -extern int last_badness; /* badness of the most recently packaged box */ -extern halfword adjust_tail; /* tail of adjustment list */ +extern scaled total_shrink[5]; /* glue found by |hpack| or |vpack| */ +extern int last_badness; /* badness of the most recently packaged box */ +extern halfword adjust_tail; /* tail of adjustment list */ extern halfword pre_adjust_tail; -extern int font_expand_ratio; /* current expansion ratio */ +extern int font_expand_ratio; /* current expansion ratio */ extern halfword last_leftmost_char; extern halfword last_rightmost_char; -extern halfword next_char_p; /* pointer to the next char of an implicit kern */ -extern halfword prev_char_p; /* pointer to the previous char of an implicit kern */ +extern halfword next_char_p; /* pointer to the next char of an implicit kern */ +extern halfword prev_char_p; /* pointer to the previous char of an implicit kern */ extern void set_prev_char_p(halfword p); extern scaled char_stretch(halfword p); @@ -56,95 +55,95 @@ extern void do_subst_font(halfword p, int ex_ratio); extern scaled char_pw(halfword p, int side); extern halfword new_margin_kern(scaled w, halfword p, int side); -# define update_adjust_list(A) do { \ - if (A == null) \ - normal_error("pre vadjust", "adjust_tail or pre_adjust_tail is null"); \ - vlink(A) = adjust_ptr(p); \ - while (vlink(A) != null) \ - A = vlink(A); \ +# define update_adjust_list(A) do { \ + if (A == null) \ + normal_error("pre vadjust", "adjust_tail or pre_adjust_tail is null"); \ + vlink(A) = adjust_ptr(p); \ + while (vlink(A) != null) \ + A = vlink(A); \ } while (0) +extern halfword filtered_hpack(halfword p, halfword qt, scaled w, int m, int grp, int d, int just_pack); +extern scaled_whd natural_sizes(halfword p, halfword pp, glue_ratio g_mult, int g_sign, int g_order, int d); extern halfword hpack(halfword p, scaled w, int m, int d); -extern halfword filtered_hpack(halfword p, halfword qt, scaled w, int m, - int grp, int d); - -extern scaled_whd natural_sizes(halfword p, halfword pp, glue_ratio g_mult, - int g_sign, int g_order, int d); extern int pack_begin_line; -# define vpack(A,B,C,D) vpackage(A,B,C,max_dimen,D) /* special case of unconstrained depth */ - extern halfword vpackage(halfword p, scaled h, int m, scaled l, int d); -extern halfword filtered_vpackage(halfword p, scaled h, int m, scaled l, - int grp, int d); +extern halfword filtered_vpackage(halfword p, scaled h, int m, scaled l, int grp, int d, int just_pack); extern void finish_vcenter(void); extern void package(int c); extern void append_to_vlist(halfword b, int location); +# define vpack(A,B,C,D) vpackage(A,B,C,max_dimen,D) /* special case of unconstrained depth */ + extern halfword prune_page_top(halfword p, boolean s); extern scaled active_height[10]; /* distance from first active node to~|cur_p| */ # define cur_height active_height[1] /* the natural height */ -# define awful_bad 07777777777 /* more than a billion demerits */ -# define deplorable 100000 /* more than |inf_bad|, but less than |awful_bad| */ +# define awful_bad 07777777777 /* more than a billion demerits */ +# define deplorable 100000 /* more than |inf_bad|, but less than |awful_bad| */ extern scaled best_height_plus_depth; /* height of the best box, without stretching or shrinking */ extern halfword vert_break(halfword p, scaled h, scaled d); -extern halfword vsplit(halfword n, scaled h); /* extracts a page of height |h| from box |n| */ +extern halfword vsplit(halfword n, scaled h); /* extracts a page of height |h| from box |n| */ -# define box_code 0 /* |chr_code| for `\.{\\box}' */ -# define copy_code 1 /* |chr_code| for `\.{\\copy}' */ -# define last_box_code 2 /* |chr_code| for `\.{\\lastbox}' */ -# define vsplit_code 3 /* |chr_code| for `\.{\\vsplit}' */ -# define vtop_code 4 /* |chr_code| for `\.{\\vtop}' */ +# define box_code 0 /* |chr_code| for `\.{\\box}' */ +# define copy_code 1 /* |chr_code| for `\.{\\copy}' */ +# define last_box_code 2 /* |chr_code| for `\.{\\lastbox}' */ +# define vsplit_code 3 /* |chr_code| for `\.{\\vsplit}' */ +# define tpack_code 4 +# define vpack_code 5 +# define hpack_code 6 +# define vtop_code 7 /* |chr_code| for `\.{\\vtop}' */ -# define tail_page_disc disc_ptr[copy_code] /* last item removed by page builder */ -# define page_disc disc_ptr[last_box_code] /* first item removed by page builder */ -# define split_disc disc_ptr[vsplit_code] /* first item removed by \.{\\vsplit} */ +# define tail_page_disc disc_ptr[copy_code] /* last item removed by page builder */ +# define page_disc disc_ptr[last_box_code] /* first item removed by page builder */ +# define split_disc disc_ptr[vsplit_code] /* first item removed by \.{\\vsplit} */ -extern halfword disc_ptr[(vsplit_code + 1)]; /* list pointers */ +extern halfword disc_ptr[(vsplit_code + 1)]; /* list pointers */ /* -Now let's turn to the question of how \.{\\hbox} is treated. We actually -need to consider also a slightly larger context, since constructions like + +Now let's turn to the question of how \.{\\hbox} is treated. We actually need to +consider also a slightly larger context, since constructions like + `\.{\\setbox3=}\penalty0\.{\\hbox...}' and `\.{\\leaders}\penalty0\.{\\hbox...}' and `\.{\\lower3.8pt\\hbox...}' -are supposed to invoke quite -different actions after the box has been packaged. Conversely, -constructions like `\.{\\setbox3=}' can be followed by a variety of -different kinds of boxes, and we would like to encode such things in an -efficient way. - -In other words, there are two problems: To represent the context of a box, -and to represent its type. - -The first problem is solved by putting a ``context code'' on the |save_stack|, -just below the two entries that give the dimensions produced by |scan_spec|. -The context code is either a (signed) shift amount, or it is a large + +are supposed to invoke quite different actions after the box has been packaged. +Conversely, constructions like `\.{\\setbox3=}' can be followed by a variety of +different kinds of boxes, and we would like to encode such things in an efficient +way. + +In other words, there are two problems: To represent the context of a box, and to +represent its type. The first problem is solved by putting a ``context code'' on +the |save_stack|, just below the two entries that give the dimensions produced by +|scan_spec|. The context code is either a (signed) shift amount, or it is a large integer |>=box_flag|, where |box_flag=@t$2^{30}$@>|. Codes |box_flag| through |box_flag+biggest_reg| represent `\.{\\setbox0}' through `\.{\\setbox}|biggest_reg|'; codes |box_flag+biggest_reg+1| through -|box_flag+2*biggest_reg| represent `\.{\\global\\setbox0}' -through `\.{\\global\\setbox}|biggest_reg|'; code |box_flag+2*number_regs| -represents `\.{\\shipout}'; and codes |box_flag+2*number_regs+1| -through |box_flag+2*number_regs+3| represent `\.{\\leaders}', `\.{\\cleaders}', -and `\.{\\xleaders}'. - -The second problem is solved by giving the command code |make_box| to all -control sequences that produce a box, and by using the following |chr_code| -values to distinguish between them: |box_code|, |copy_code|, |last_box_code|, -|vsplit_code|, |vtop_code|, |vtop_code+vmode|, and |vtop_code+hmode|, -where the latter two are used denote \.{\\vbox} and \.{\\hbox}, respectively. +|box_flag+2*biggest_reg| represent `\.{\\global\\setbox0}' through +`\.{\\global\\setbox}|biggest_reg|'; code |box_flag+2*number_regs| represents +`\.{\\shipout}'; and codes |box_flag+2*number_regs+1| through +|box_flag+2*number_regs+3| represent `\.{\\leaders}', `\.{\\cleaders}', and +`\.{\\xleaders}'. + +The second problem is solved by giving the command code |make_box| to all control +sequences that produce a box, and by using the following |chr_code| values to +distinguish between them: |box_code|, |copy_code|, |last_box_code|, +|vsplit_code|, |vtop_code|, |vtop_code+vmode|, and |vtop_code+hmode|, where the +latter two are used denote \.{\\vbox} and \.{\\hbox}, respectively. + */ -# define box_flag 010000000000 /* context code for `\.{\\setbox0}' */ -# define global_box_flag (box_flag+number_regs) /* context code for `\.{\\global\\setbox0}' */ +# define box_flag 010000000000 /* context code for `\.{\\setbox0}' */ +# define global_box_flag (box_flag+number_regs) /* context code for `\.{\\global\\setbox0}' */ # define max_global_box_flag (global_box_flag+number_regs) -# define ship_out_flag (max_global_box_flag+1) /* context code for `\.{\\shipout}' */ -# define leader_flag ship_out_flag+1 /* context code for `\.{\\leaders}' */ +# define ship_out_flag (max_global_box_flag+1) /* context code for `\.{\\shipout}' */ +# define leader_flag ship_out_flag+1 /* context code for `\.{\\leaders}' */ extern void begin_box(int box_context); diff --git a/Build/source/texk/web2c/luatexdir/tex/packaging.w b/Build/source/texk/web2c/luatexdir/tex/packaging.w index 173b7894cb2..b1e8c44425e 100644 --- a/Build/source/texk/web2c/luatexdir/tex/packaging.w +++ b/Build/source/texk/web2c/luatexdir/tex/packaging.w @@ -1,4 +1,4 @@ -4% packaging.w +% packaging.w % % Copyright 2009-2010 Taco Hoekwater <taco@@luatex.org> % @@ -19,7 +19,6 @@ @ @c - #include "ptexlib.h" @ @c @@ -29,101 +28,210 @@ #define space_factor cur_list.space_factor_field #define box(A) eqtb[box_base+(A)].hh.rh -#define text_direction int_par(text_direction_code) -#define body_direction int_par(body_direction_code) #define every_hbox equiv(every_hbox_loc) #define every_vbox equiv(every_vbox_loc) #define box_max_depth dimen_par(box_max_depth_code) - -@ We're essentially done with the parts of \TeX\ that are concerned with -the input (|get_next|) and the output (|ship_out|). So it's time to -get heavily into the remaining part, which does the real work of typesetting. - -After lists are constructed, \TeX\ wraps them up and puts them into boxes. -Two major subroutines are given the responsibility for this task: |hpack| -applies to horizontal lists (hlists) and |vpack| applies to vertical lists -(vlists). The main duty of |hpack| and |vpack| is to compute the dimensions -of the resulting boxes, and to adjust the glue if one of those dimensions -is pre-specified. The computed sizes normally enclose all of the material -inside the new box; but some items may stick out if negative glue is used, -if the box is overfull, or if a \.{\\vbox} includes other boxes that have -been shifted left. - -The subroutine call |hpack(p,w,m)| returns a pointer to an |hlist_node| -for a box containing the hlist that starts at |p|. Parameter |w| specifies -a width; and parameter |m| is either `|exactly|' or `|additional|'. Thus, -|hpack(p,w,exactly)| produces a box whose width is exactly |w|, while -|hpack(p,w,additional)| yields a box whose width is the natural width plus -|w|. It is convenient to define a macro called `|natural|' to cover the -most common case, so that we can say |hpack(p,natural)| to get a box that -has the natural width of list |p|. - -Similarly, |vpack(p,w,m)| returns a pointer to a |vlist_node| for a -box containing the vlist that starts at |p|. In this case |w| represents -a height instead of a width; the parameter |m| is interpreted as in |hpack|. - - -@ The parameters to |hpack| and |vpack| correspond to \TeX's primitives -like `\.{\\hbox} \.{to} \.{300pt}', `\.{\\hbox} \.{spread} \.{10pt}'; note -that `\.{\\hbox}' with no dimension following it is equivalent to -`\.{\\hbox} \.{spread} \.{0pt}'. The |scan_spec| subroutine scans such -constructions in the user's input, including the mandatory left brace that -follows them, and it puts the specification onto |save_stack| so that the -desired box can later be obtained by executing the following code: -$$\vbox{\halign{#\hfil\cr -|save_ptr:=save_ptr-1;|\cr -|hpack(p,saved_value(0),saved_level(0)).|\cr}}$$ +@ We're essentially done with the parts of \TeX\ that are concerned with the +input (|get_next|) and the output (|ship_out|). So it's time to get heavily into +the remaining part, which does the real work of typesetting. + +After lists are constructed, \TeX\ wraps them up and puts them into boxes. Two +major subroutines are given the responsibility for this task: |hpack| applies to +horizontal lists (hlists) and |vpack| applies to vertical lists (vlists). The +main duty of |hpack| and |vpack| is to compute the dimensions of the resulting +boxes, and to adjust the glue if one of those dimensions is pre-specified. The +computed sizes normally enclose all of the material inside the new box; but some +items may stick out if negative glue is used, if the box is overfull, or if a +\.{\\vbox} includes other boxes that have been shifted left. + +The subroutine call |hpack(p,w,m)| returns a pointer to an |hlist_node| for a box +containing the hlist that starts at |p|. Parameter |w| specifies a width; and +parameter |m| is either `|exactly|' or `|additional|'. Thus, |hpack(p,w,exactly)| +produces a box whose width is exactly |w|, while |hpack(p,w,additional)| yields a +box whose width is the natural width plus |w|. It is convenient to define a macro +called `|natural|' to cover the most common case, so that we can say +|hpack(p,natural)| to get a box that has the natural width of list |p|. + +Similarly, |vpack(p,w,m)| returns a pointer to a |vlist_node| for a box +containing the vlist that starts at |p|. In this case |w| represents a height +instead of a width; the parameter |m| is interpreted as in |hpack|. + +@ The parameters to |hpack| and |vpack| correspond to \TeX's primitives like +`\.{\\hbox} \.{to} \.{300pt}', `\.{\\hbox} \.{spread} \.{10pt}'; note that +`\.{\\hbox}' with no dimension following it is equivalent to `\.{\\hbox} +\.{spread} \.{0pt}'. The |scan_spec| subroutine scans such constructions in the +user's input, including the mandatory left brace that follows them, and it puts +the specification onto |save_stack| so that the desired box can later be obtained +by executing the following code: $$\vbox{\halign{#\hfil\cr +|save_ptr:=save_ptr-1;|\cr |hpack(p,saved_value(0),saved_level(0)).|\cr}}$$ @c +/* + void scan_spec(group_code c) + { + int spec_code; + if (scan_keyword("to")) { + spec_code = exactly; + scan_normal_dimen(); + } else if (scan_keyword("spread")) { + spec_code = additional; + scan_normal_dimen(); + } else { + spec_code = additional; + cur_val = 0; + } + set_saved_record(0, saved_boxspec, spec_code, cur_val); + save_ptr++; + new_save_level(c); + scan_left_brace(); + } +*/ + void scan_spec(group_code c) { /* scans a box specification and left brace */ int spec_code; - if (scan_keyword("to")) { - spec_code = exactly; - scan_normal_dimen(); - } else if (scan_keyword("spread")) { - spec_code = additional; - scan_normal_dimen(); - } else { + boolean done = false ; + do { + get_x_token(); + } while ((cur_cmd == spacer_cmd) || (cur_cmd == relax_cmd)); + if (cur_cmd == left_brace_cmd) { spec_code = additional; cur_val = 0; + done = true; + } else { + /* todo: attr */ + back_input(); + if (scan_keyword("to")) { + spec_code = exactly; + scan_normal_dimen(); + } else if (scan_keyword("spread")) { + spec_code = additional; + scan_normal_dimen(); + } else { + spec_code = additional; + cur_val = 0; + } } set_saved_record(0, saved_boxspec, spec_code, cur_val); save_ptr++; new_save_level(c); - scan_left_brace(); + if (!done) { + scan_left_brace(); + } } - @ When scanning, special care is necessary to ensure that the special -|save_stack| codes are placed just below the new group code, because -scanning can change |save_stack| when \.{\\csname} appears. +|save_stack| codes are placed just below the new group code, because scanning can +change |save_stack| when \.{\\csname} appears. -This coincides with the text on |dir| and |attr| keywords, as these -are exaclty the uses of \.{\\hbox}, \.{\\vbox}, and \.{\\vtop} in the -input stream (the others are \.{\\vcenter}, \.{\\valign}, and -\.{\\halign}). +This coincides with the text on |dir| and |attr| keywords, as these are exaclty +the uses of \.{\\hbox}, \.{\\vbox}, and \.{\\vtop} in the input stream (the +others are \.{\\vcenter}, \.{\\valign}, and \.{\\halign}). @c -void scan_full_spec(group_code c, int spec_direction) -{ /* scans a box specification and left brace */ - int s; /* temporarily saved value */ +/* + void scan_full_spec(group_code c, int spec_direction) + { + int s; + int i; + int v; + int spec_code; + halfword attr_list; + if (attr_list_cache == cache_disabled) + update_attribute_cache(); + attr_list = attr_list_cache; + s = saved_value(0); + CONTINUE: + while (cur_cmd == relax_cmd || cur_cmd == spacer_cmd) { + get_x_token(); + if (cur_cmd != relax_cmd && cur_cmd != spacer_cmd) + back_input(); + } + if (scan_keyword("attr")) { + scan_register_num(); + i = cur_val; + scan_optional_equals(); + scan_int(); + v = cur_val; + if ((attr_list != null) && (attr_list == attr_list_cache)) { + attr_list = copy_attribute_list(attr_list_cache); + add_node_attr_ref(attr_list); + } + attr_list = do_set_attribute(attr_list, i, v); + goto CONTINUE; + } + if (scan_keyword("dir")) { + scan_direction(); + spec_direction = cur_val; + goto CONTINUE; + } + if (attr_list == attr_list_cache) { + add_node_attr_ref(attr_list); + } + if (scan_keyword("to")) { + spec_code = exactly; + } else if (scan_keyword("spread")) { + spec_code = additional; + } else { + spec_code = additional; + cur_val = 0; + goto FOUND; + } + scan_normal_dimen(); + FOUND: + set_saved_record(0, saved_boxcontext, 0, s); + set_saved_record(1, saved_boxspec, spec_code, cur_val); + if (spec_direction != -1) { + set_saved_record(2, saved_boxdir, spec_direction, text_dir_ptr); + text_dir_ptr = new_dir(spec_direction); + } else { + set_saved_record(2, saved_boxdir, spec_direction, null); + } + set_saved_record(3, saved_boxattr, 0, attr_list); + save_ptr += 4; + new_save_level(c); + scan_left_brace(); + eq_word_define(int_base + body_direction_code, spec_direction); + eq_word_define(int_base + par_direction_code, spec_direction); + eq_word_define(int_base + text_direction_code, spec_direction); + } +*/ + +/* scans a box specification and left brace */ + +void scan_full_spec(group_code c, int spec_direction, int just_pack) +{ + int s; int i; int v; int spec_code; + boolean done = false ; halfword attr_list; if (attr_list_cache == cache_disabled) update_attribute_cache(); attr_list = attr_list_cache; - assert(saved_type(0) == saved_boxcontext); - s = saved_value(0); /* the box context */ + s = saved_value(0); /* the box context */ + do { + get_x_token(); + } while ((cur_cmd == spacer_cmd) || (cur_cmd == relax_cmd)); + if (cur_cmd == left_brace_cmd) { + goto QUICK; + } else { + back_input(); + goto KEYWORDS; + } CONTINUE: while (cur_cmd == relax_cmd || cur_cmd == spacer_cmd) { get_x_token(); - if (cur_cmd != relax_cmd && cur_cmd != spacer_cmd) + if (cur_cmd == left_brace_cmd) { + goto QUICK; + } else if (cur_cmd != relax_cmd && cur_cmd != spacer_cmd) { back_input(); + break; + } } + KEYWORDS: if (scan_keyword("attr")) { scan_register_num(); i = cur_val; @@ -132,7 +240,7 @@ void scan_full_spec(group_code c, int spec_direction) v = cur_val; if ((attr_list != null) && (attr_list == attr_list_cache)) { attr_list = copy_attribute_list(attr_list_cache); - add_node_attr_ref(attr_list); /* will be used once */ + add_node_attr_ref(attr_list); /* will be used once */ } attr_list = do_set_attribute(attr_list, i, v); goto CONTINUE; @@ -155,6 +263,12 @@ void scan_full_spec(group_code c, int spec_direction) goto FOUND; } scan_normal_dimen(); + goto FOUND; + QUICK: + spec_code = additional; + cur_val = 0; + add_node_attr_ref(attr_list); + done = true; FOUND: set_saved_record(0, saved_boxcontext, 0, s); set_saved_record(1, saved_boxspec, spec_code, cur_val); @@ -166,42 +280,43 @@ void scan_full_spec(group_code c, int spec_direction) set_saved_record(2, saved_boxdir, spec_direction, null); } set_saved_record(3, saved_boxattr, 0, attr_list); - save_ptr += 4; + set_saved_record(4, saved_boxpack, 0, just_pack); + save_ptr += 5; new_save_level(c); - scan_left_brace(); + if (! done) { + scan_left_brace(); + } + /* no gain: if (body_direction != spec_direction) etc */ eq_word_define(int_base + body_direction_code, spec_direction); eq_word_define(int_base + par_direction_code, spec_direction); eq_word_define(int_base + text_direction_code, spec_direction); } - @ To figure out the glue setting, |hpack| and |vpack| determine how much -stretchability and shrinkability are present, considering all four orders -of infinity. The highest order of infinity that has a nonzero coefficient -is then used as if no other orders were present. - -For example, suppose that the given list contains six glue nodes with -the respective stretchabilities 3pt, 8fill, 5fil, 6pt, $-3$fil, $-8$fill. -Then the total is essentially 2fil; and if a total additional space of 6pt -is to be achieved by stretching, the actual amounts of stretch will be -0pt, 0pt, 15pt, 0pt, $-9$pt, and 0pt, since only `fil' glue will be -considered. (The `fill' glue is therefore not really stretching infinitely -with respect to `fil'; nobody would actually want that to happen.) - -The arrays |total_stretch| and |total_shrink| are used to determine how much -glue of each kind is present. A global variable |last_badness| is used -to implement \.{\\badness}. +stretchability and shrinkability are present, considering all four orders of +infinity. The highest order of infinity that has a nonzero coefficient is then +used as if no other orders were present. + +For example, suppose that the given list contains six glue nodes with the +respective stretchabilities 3pt, 8fill, 5fil, 6pt, $-3$fil, $-8$fill. Then the +total is essentially 2fil; and if a total additional space of 6pt is to be +achieved by stretching, the actual amounts of stretch will be 0pt, 0pt, 15pt, +0pt, $-9$pt, and 0pt, since only `fil' glue will be considered. (The `fill' glue +is therefore not really stretching infinitely with respect to `fil'; nobody would +actually want that to happen.) + +The arrays |total_stretch| and |total_shrink| are used to determine how much glue +of each kind is present. A global variable |last_badness| is used to implement +\.{\\badness}. @c scaled total_stretch[5]; scaled total_shrink[5]; /* glue found by |hpack| or |vpack| */ int last_badness; /* badness of the most recently packaged box */ - -@ If the global variable |adjust_tail| is non-null, the |hpack| routine -also removes all occurrences of |ins_node|, |mark_node|, and |adjust_node| -items and appends the resulting material onto the list that ends at -location |adjust_tail|. +@ If the global variable |adjust_tail| is non-null, the |hpack| routine also +removes all occurrences of |ins_node|, |mark_node|, and |adjust_node| items and +appends the resulting material onto the list that ends at location |adjust_tail|. @c halfword adjust_tail; /* tail of adjustment list */ @@ -213,7 +328,6 @@ halfword adjust_tail; /* tail of adjustment list */ @c halfword pre_adjust_tail; -int font_expand_ratio; /* current expansion ratio */ halfword last_leftmost_char; halfword last_rightmost_char; @@ -230,18 +344,17 @@ void set_prev_char_p(halfword p) @ @c scaled char_stretch(halfword p) { - scaled dw; - int ef; - internal_font_number f; - int c, m; - f = font(p); - c = character(p); - m = font_max_stretch(f); - ef = get_ef_code(f, c); - if ((m > 0) && (ef > 0)) { - dw = calc_char_width(f, c, m) - char_width(f, c); - if (dw > 0) - return round_xn_over_d(dw, ef, 1000); + internal_font_number f = font(p); + int m = font_max_stretch(f); + if (m > 0) { + int c = character(p); + int ef = get_ef_code(f, c); + if (ef > 0) { + scaled dw = calc_char_width(f, c, m) - char_width(f, c); + if (dw > 0) { + return round_xn_over_d(dw, ef, 1000); + } + } } return 0; } @@ -249,18 +362,17 @@ scaled char_stretch(halfword p) @ @c scaled char_shrink(halfword p) { - scaled dw; - int ef; - internal_font_number f; - int c, m; - f = font(p); - c = character(p); - m = font_max_shrink(f); - ef = get_ef_code(f, c); - if ((m > 0) && (ef > 0)) { - dw = char_width(f, c) - calc_char_width(f, c, -m); - if (dw > 0) - return round_xn_over_d(dw, ef, 1000); + internal_font_number f = font(p); + int m = font_max_shrink(f); + if (m > 0) { + int c = character(p); + int ef = get_ef_code(f, c); + if (ef > 0) { + scaled dw = char_width(f, c) - calc_char_width(f, c, -m); + if (dw > 0) { + return round_xn_over_d(dw, ef, 1000); + } + } } return 0; } @@ -271,19 +383,23 @@ scaled kern_stretch(halfword p) halfword l, r; scaled d; int m; - if ((prev_char_p == null) || (vlink(prev_char_p) != p) - || (vlink(p) == null)) + if ((prev_char_p == null) || (vlink(prev_char_p) != p) || (vlink(p) == null)) return 0; l = prev_char_p; + /* we need a left char */ + if (!is_char_node(l)) + return 0; r = vlink(p); - if (!((is_char_node(l) && is_char_node(r) && - (font(l) == font(r)) && (font_max_stretch(font(l)) != 0)))) + /* and a right char */ + if (!is_char_node(r)) + return 0; + /* and a reason to kern */ + if ((font(l) != font(r)) || (font_max_stretch(font(l)) == 0)) return 0; m = font_max_stretch(font(l)); d = get_kern(font(l), character(l), character(r)); d = round_xn_over_d(d, 1000 + m, 1000); - return round_xn_over_d(d - width(p), - get_ef_code(font(l), character(l)), 1000); + return round_xn_over_d(d - width(p), get_ef_code(font(l), character(l)), 1000); } @ @c @@ -292,29 +408,30 @@ scaled kern_shrink(halfword p) halfword l, r; scaled d; int m; - if ((prev_char_p == null) || (vlink(prev_char_p) != p) - || (vlink(p) == null)) + if ((prev_char_p == null) || (vlink(prev_char_p) != p) || (vlink(p) == null)) return 0; l = prev_char_p; + /* we need a left char */ + if (!is_char_node(l)) + return 0; r = vlink(p); - if (!((is_char_node(l) && is_char_node(r) && - (font(l) == font(r)) && (font_max_shrink(font(l)) != 0)))) + /* and a right char */ + if (!is_char_node(r)) + return 0; + /* and a reason to kern */ + if ((font(l) != font(r)) || (font_max_shrink(font(l)) == 0)) return 0; m = font_max_stretch(font(l)); d = get_kern(font(l), character(l), character(r)); d = round_xn_over_d(d, 1000 - m, 1000); - return round_xn_over_d(width(p) - d, - get_ef_code(font(l), character(l)), 1000); + return round_xn_over_d(width(p) - d, get_ef_code(font(l), character(l)), 1000); } @ @c void do_subst_font(halfword p, int ex_ratio) { - internal_font_number f; - halfword r; - int ef, ex_shrink, ex_stretch; if (type(p) == disc_node) { - r = vlink(pre_break(p)); + halfword r = vlink(pre_break(p)); while (r != null) { if (is_char_node(r)) do_subst_font(r, ex_ratio); @@ -334,22 +451,21 @@ void do_subst_font(halfword p, int ex_ratio) } return; } - if (is_char_node(p)) { - r = p; - } else { + if (! is_char_node(p)) { normal_error("font expansion", "invalid node type"); return; - } - f = font(r); - ef = get_ef_code(f, character(r)); - if (ef == 0) - return; - if ((font_max_stretch(f) > 0) && (ex_ratio > 0)) { - ex_stretch = ext_xn_over_d(ex_ratio * ef, font_max_stretch(f), 1000000); - ex_glyph(p) = fix_expand_value(f, ex_stretch)*1000; - } else if ((font_max_shrink(f) > 0) && (ex_ratio < 0)) { - ex_shrink = ext_xn_over_d(ex_ratio * ef, font_max_shrink(f), 1000000); - ex_glyph(p) = fix_expand_value(f, ex_shrink)*1000; + } else { + internal_font_number f = font(p); + int ef = get_ef_code(f, character(p)); + if (ef == 0) + return; + if ((font_max_stretch(f) > 0) && (ex_ratio > 0)) { + int ex_stretch = ext_xn_over_d(ex_ratio * ef, font_max_stretch(f), 1000000); + ex_glyph(p) = fix_expand_value(f, ex_stretch)*1000; + } else if ((font_max_shrink(f) > 0) && (ex_ratio < 0)) { + int ex_shrink = ext_xn_over_d(ex_ratio * ef, font_max_shrink(f), 1000000); + ex_glyph(p) = fix_expand_value(f, ex_shrink)*1000; + } } } @@ -393,49 +509,52 @@ halfword new_margin_kern(scaled w, halfword p, int side) return k; } - -@ Here is |hpack|, which is place where we do font substituting when -font expansion is being used. +@ Here is |hpack|, which is place where we do font substituting when font +expansion is being used. @c halfword hpack(halfword p, scaled w, int m, int pack_direction) { halfword r; /* the box node that will be returned */ halfword q; /* trails behind |p| */ - scaled h, d, x; /* height, depth, and natural width */ + scaled h = 0; /* height */ + scaled d = 0; /* depth */ + scaled x = 0; /* natural width */ scaled_whd whd; scaled s; /* shift amount */ halfword g; /* points to a glue specification */ int o; /* order of infinity */ - halfword dir_ptr1; /* for managing the direction stack */ + halfword dir_ptr1 = null; /* for managing the direction stack */ int hpack_dir; /* the current direction */ - int disc_level; + int disc_level = 0; halfword pack_interrupt[8]; scaled font_stretch = 0; scaled font_shrink = 0; + int font_expand_ratio = 0; /* current expansion ratio */ scaled k = 0; last_badness = 0; - r = new_node(hlist_node, min_quarterword); + r = new_node(hlist_node, min_quarterword); /* the box node that will be returned */ if (pack_direction == -1) { - box_dir(r) = text_direction; + hpack_dir = text_direction; } else { - box_dir(r) = pack_direction; + hpack_dir = pack_direction; } - hpack_dir = box_dir(r); - dir_ptr1 = null; - push_dir(hpack_dir,dir_ptr1); - q = r + list_offset; + box_dir(r) = hpack_dir; + /* + potential optimimization, save a little but neglectable in practice (not so + many empty boxes are used) + + if (p == null) { + width(r) = w; + return r; + } + */ + push_dir(dir_ptr1,hpack_dir); /* push null */ + q = r + list_offset; /* hm, adding something to a node address? */ vlink(q) = p; if (m == cal_expand_ratio) { - prev_char_p = null; - font_stretch = 0; - font_shrink = 0; - font_expand_ratio = 0; + prev_char_p = null; /* why not always */ } - h = 0; - /* Clear dimensions to zero */ - d = 0; - x = 0; total_stretch[normal] = 0; total_shrink[normal] = 0; total_stretch[sfi] = 0; @@ -447,7 +566,6 @@ halfword hpack(halfword p, scaled w, int m, int pack_direction) total_stretch[filll] = 0; total_shrink[filll] = 0; - disc_level = 0; RESWITCH: while ((p != null) || (disc_level > 0)) { if (p == null) { @@ -455,15 +573,19 @@ halfword hpack(halfword p, scaled w, int m, int pack_direction) p = pack_interrupt[disc_level]; goto RESWITCH; } - /* Examine node |p| in the hlist, taking account of its effect - on the dimensions of the new box, or moving it to the adjustment list; - then advance |p| to the next node */ + /* + Examine node |p| in the hlist, taking account of its effect + on the dimensions of the new box, or moving it to the adjustment list; + then advance |p| to the next node + */ while (is_char_node(p)) { - /* Incorporate character dimensions into the dimensions of - the hbox that will contain~it, then move to the next node */ - /* The following code is part of \TeX's inner loop; i.e., adding another - character of text to the user's input will cause each of these instructions - to be exercised one more time. + /* + Incorporate character dimensions into the dimensions of the hbox + that will contain~it, then move to the next node. + + The following code is part of \TeX's inner loop; i.e., adding + another character of text to the user's input will cause each of + these instructions to be exercised one more time. */ if (m >= cal_expand_ratio) { prev_char_p = p; @@ -484,151 +606,160 @@ halfword hpack(halfword p, scaled w, int m, int pack_direction) } if (p != null) { switch (type(p)) { - case hlist_node: - case vlist_node: - /* Incorporate box dimensions into the dimensions of the hbox that will contain~it */ - /* The code here implicitly uses the fact that running dimensions are - indicated by |null_flag|, which will be ignored in the calculations - because it is a highly negative number. */ - s = shift_amount(p); - whd = pack_width_height_depth(hpack_dir, box_dir(p), p, false); - x += whd.wd; - if (whd.ht - s > h) - h = whd.ht - s; - if (whd.dp + s > d) - d = whd.dp + s; - break; - case rule_node: - case unset_node: - x += width(p); - if (type(p) >= rule_node) - s = 0; - else - s = shift_amount(p); - if (height(p) - s > h) - h = height(p) - s; - if (depth(p) + s > d) - d = depth(p) + s; - break; - case ins_node: - case mark_node: - case adjust_node: - if (adjust_tail != null || pre_adjust_tail != null) { - /* Transfer node |p| to the adjustment list */ + case hlist_node: + case vlist_node: /* - Although node |q| is not necessarily the immediate predecessor of node |p|, - it always points to some node in the list preceding |p|. Thus, we can delete - nodes by moving |q| when necessary. The algorithm takes linear time, and the - extra computation does not intrude on the inner loop unless it is necessary - to make a deletion. - */ - while (vlink(q) != p) - q = vlink(q); - if (type(p) == adjust_node) { - if (adjust_pre(p) != 0) - update_adjust_list(pre_adjust_tail); - else - update_adjust_list(adjust_tail); - p = vlink(p); - adjust_ptr(vlink(q)) = null; - flush_node(vlink(q)); + Incorporate box dimensions into the dimensions of the hbox + that will contain~it + + The code here implicitly uses the fact that running dimensions are + indicated by |null_flag|, which will be ignored in the calculations + because it is a highly negative number. + */ + s = shift_amount(p); + whd = pack_width_height_depth(hpack_dir, box_dir(p), p, false); + x += whd.wd; + if (whd.ht - s > h) + h = whd.ht - s; + if (whd.dp + s > d) + d = whd.dp + s; + break; + /* + case rule_node: + case unset_node: + x += width(p); + if (type(p) >= rule_node) // always + s = 0; + else + s = shift_amount(p); + if (height(p) - s > h) + h = height(p) - s; + if (depth(p) + s > d) + d = depth(p) + s; + break; + */ + case rule_node: + case unset_node: + x += width(p); + if (height(p) > h) + h = height(p); + if (depth(p) > d) + d = depth(p); + break; + /* */ + case glue_node: + /* Incorporate glue into the horizontal totals */ + g = glue_ptr(p); + x += width(g); + o = stretch_order(g); + total_stretch[o] = total_stretch[o] + stretch(g); + o = shrink_order(g); + total_shrink[o] = total_shrink[o] + shrink(g); + if (subtype(p) >= a_leaders) { + g = leader_ptr(p); + if (height(g) > h) + h = height(g); + if (depth(g) > d) + d = depth(g); + } + break; + case kern_node: + if (subtype(p) == normal) { + if (m == cal_expand_ratio) { + font_stretch = font_stretch + kern_stretch(p); + font_shrink = font_shrink + kern_shrink(p); + } else if (m == subst_ex_font) { + if (font_expand_ratio > 0) + k = kern_stretch(p); + else if (font_expand_ratio < 0) + k = kern_shrink(p); + if (k != 0) + width(p) = get_kern(font(prev_char_p), character(prev_char_p), character(vlink(p))); + } + } + x += width(p); + break; + case disc_node: + if (m == subst_ex_font) + do_subst_font(p, font_expand_ratio); + if ((subtype(p) != select_disc) && (vlink(no_break(p)) != null)) { + pack_interrupt[disc_level] = vlink(p); + incr(disc_level); + p = no_break(p); + } + break; + case dir_node: + /* Adjust the dir stack for the |hpack| routine */ + if (dir_dir(p) >= 0) { + hpack_dir = dir_dir(p); + push_dir_node(dir_ptr1,p); } else { - vlink(adjust_tail) = p; - adjust_tail = p; - p = vlink(p); + pop_dir_node(dir_ptr1); + if (dir_ptr1 != null) + hpack_dir = dir_dir(dir_ptr1); } - vlink(q) = p; - p = q; - } - break; - case dir_node: - /* DIR: Adjust the dir stack for the |hpack| routine */ - if (dir_dir(p) >= 0) { - hpack_dir = dir_dir(p); - push_dir_node(p,dir_ptr1); - } else { - pop_dir_node(dir_ptr1); - if (dir_ptr1 != null) - hpack_dir = dir_dir(dir_ptr1); - } - break; - case math_node: - /* begin mathskip code */ - if (glue_ptr(p) == zero_glue) { - x += surround(p); break; - } else { - /* fall through: mathskip */ - } - /* end mathskip code */ - case glue_node: - /* Incorporate glue into the horizontal totals */ - g = glue_ptr(p); - x += width(g); - o = stretch_order(g); - total_stretch[o] = total_stretch[o] + stretch(g); - o = shrink_order(g); - total_shrink[o] = total_shrink[o] + shrink(g); - if (subtype(p) >= a_leaders) { - g = leader_ptr(p); - if (height(g) > h) - h = height(g); - if (depth(g) > d) - d = depth(g); - } - break; - case margin_kern_node: - if (m == cal_expand_ratio) { - int f = font(margin_char(p)); - do_subst_font(margin_char(p), 1000); - if (f != font(margin_char(p))) - font_stretch = - font_stretch - width(p) - char_pw(margin_char(p), - subtype(p)); - font(margin_char(p)) = f; - do_subst_font(margin_char(p), -1000); - if (f != font(margin_char(p))) - font_shrink = - font_shrink - width(p) - char_pw(margin_char(p), - subtype(p)); - font(margin_char(p)) = f; - } else if (m == subst_ex_font) { - do_subst_font(margin_char(p), font_expand_ratio); - width(p) = -char_pw(margin_char(p), subtype(p)); - } - x += width(p); - break; - case kern_node: - if (subtype(p) == normal) { + case math_node: + /* begin mathskip code */ + if (glue_ptr(p) == zero_glue) { + x += surround(p); + break; + } else { + /* fall through: mathskip */ + } + /* end mathskip code */ + case margin_kern_node: if (m == cal_expand_ratio) { - font_stretch = font_stretch + kern_stretch(p); - font_shrink = font_shrink + kern_shrink(p); + int f = font(margin_char(p)); + do_subst_font(margin_char(p), 1000); + if (f != font(margin_char(p))) + font_stretch = font_stretch - width(p) - char_pw(margin_char(p), subtype(p)); + font(margin_char(p)) = f; + do_subst_font(margin_char(p), -1000); + if (f != font(margin_char(p))) + font_shrink = font_shrink - width(p) - char_pw(margin_char(p), subtype(p)); + font(margin_char(p)) = f; } else if (m == subst_ex_font) { - if (font_expand_ratio > 0) - k = kern_stretch(p); - else if (font_expand_ratio < 0) - k = kern_shrink(p); - else - pdfassert(0); - if (k != 0) - width(p) = get_kern(font(prev_char_p), - character(prev_char_p), - character(vlink(p))); + do_subst_font(margin_char(p), font_expand_ratio); + width(p) = -char_pw(margin_char(p), subtype(p)); } - } - x += width(p); - break; - case disc_node: - if (m == subst_ex_font) - do_subst_font(p, font_expand_ratio); - if ((subtype(p) != select_disc) && (vlink(no_break(p)) != null)) { - pack_interrupt[disc_level] = vlink(p); - incr(disc_level); - p = no_break(p); - } - break; - default: - break; + x += width(p); + break; + case ins_node: + case mark_node: + case adjust_node: + /* + Transfer node |p| to the adjustment list. + + Although node |q| is not necessarily the immediate predecessor of node |p|, + it always points to some node in the list preceding |p|. Thus, we can delete + nodes by moving |q| when necessary. The algorithm takes linear time, and the + extra computation does not intrude on the inner loop unless it is necessary + to make a deletion. + */ + if (adjust_tail != null || pre_adjust_tail != null) { + while (vlink(q) != p) + q = vlink(q); + if (type(p) == adjust_node) { + if (adjust_pre(p) != 0) + update_adjust_list(pre_adjust_tail); + else + update_adjust_list(adjust_tail); + p = vlink(p); + adjust_ptr(vlink(q)) = null; + flush_node(vlink(q)); + } else { + vlink(adjust_tail) = p; + adjust_tail = p; + p = vlink(p); + } + vlink(q) = p; + p = q; + } + break; + /* */ + default: + break; } p = vlink(p); } @@ -641,27 +772,32 @@ halfword hpack(halfword p, scaled w, int m, int pack_direction) vlink(pre_adjust_tail) = null; height(r) = h; depth(r) = d; - /* Determine the value of |width(r)| and the appropriate glue setting; - then |return| or |goto common_ending| */ - /* When we get to the present part of the program, |x| is the natural width - of the box being packaged. */ + /* + Determine the value of |width(r)| and the appropriate glue setting; then + |return| or |goto common_ending|. + + When we get to the present part of the program, |x| is the natural width + of the box being packaged. + */ if (m == additional) w = x + w; width(r) = w; - x = w - x; /* now |x| is the excess to be made up */ + x = w - x; + /* now |x| is the excess to be made up */ if (x == 0) { glue_sign(r) = normal; glue_order(r) = normal; set_glue_ratio_zero(glue_set(r)); goto EXIT; } else if (x > 0) { - /* Determine horizontal glue stretch setting, then |return| - or \hbox{|goto common_ending|} */ - - /* If |hpack| is called with |m=cal_expand_ratio| we calculate - |font_expand_ratio| and return without checking for overfull or underfull box. */ - - /* Determine the stretch order */ + /* + Determine horizontal glue stretch setting, then |return| + or \hbox{|goto common_ending|}. + + If |hpack| is called with |m=cal_expand_ratio| we calculate + |font_expand_ratio| and return without checking for overfull or + underfull box. + */ if (total_stretch[filll] != 0) o = filll; else if (total_stretch[fill] != 0) @@ -682,13 +818,16 @@ halfword hpack(halfword p, scaled w, int m, int pack_direction) if (total_stretch[o] != 0) { glue_set(r) = unfloat((double) x / total_stretch[o]); } else { + /* there's nothing to stretch */ glue_sign(r) = normal; - set_glue_ratio_zero(glue_set(r)); /* there's nothing to stretch */ + set_glue_ratio_zero(glue_set(r)); } if (o == normal) { if (list_ptr(r) != null) { - /* Report an underfull hbox and |goto common_ending|, if this box - is sufficiently bad */ + /* + Report an underfull hbox and |goto common_ending|, if this box + is sufficiently bad. + */ last_badness = badness(x, total_stretch[normal]); if (last_badness > int_par(hbadness_code)) { int callback_id = callback_defined(hpack_quality_callback); @@ -720,9 +859,10 @@ halfword hpack(halfword p, scaled w, int m, int pack_direction) } goto EXIT; } else { - /* Determine horizontal glue shrink setting, then |return| - or \hbox{|goto common_ending|} */ - /* Determine the shrink order */ + /* + Determine horizontal glue shrink setting, then |return| + or \hbox{|goto common_ending|}, + */ if (total_shrink[filll] != 0) o = filll; else if (total_shrink[fill] != 0) @@ -743,15 +883,19 @@ halfword hpack(halfword p, scaled w, int m, int pack_direction) if (total_shrink[o] != 0) { glue_set(r) = unfloat((double) (-x) / (double) total_shrink[o]); } else { + /* there's nothing to shrink */ glue_sign(r) = normal; - set_glue_ratio_zero(glue_set(r)); /* there's nothing to shrink */ + set_glue_ratio_zero(glue_set(r)); } if ((total_shrink[o] < -x) && (o == normal) && (list_ptr(r) != null)) { int overshoot = -x - total_shrink[normal] ; last_badness = 1000000; - set_glue_ratio_one(glue_set(r)); /* use the maximum shrinkage */ - /* Report an overfull hbox and |goto common_ending|, if this box - is sufficiently bad */ + /* use the maximum shrinkage */ + set_glue_ratio_one(glue_set(r)); + /* + Report an overfull hbox and |goto common_ending|, if this box + is sufficiently bad. + */ if ((overshoot > dimen_par(hfuzz_code)) || (int_par(hbadness_code) < 100)) { int callback_id = callback_defined(hpack_quality_callback); halfword rule = null; @@ -778,7 +922,10 @@ halfword hpack(halfword p, scaled w, int m, int pack_direction) } } else if (o == normal) { if (list_ptr(r) != null) { - /* Report a tight hbox and |goto common_ending|, if this box is sufficiently bad */ + /* + Report a tight hbox and |goto common_ending|, if this box is + sufficiently bad. + */ last_badness = badness(-x, total_shrink[normal]); if (last_badness > int_par(hbadness_code)) { int callback_id = callback_defined(hpack_quality_callback); @@ -804,7 +951,10 @@ halfword hpack(halfword p, scaled w, int m, int pack_direction) } COMMON_ENDING: - /* Finish issuing a diagnostic message for an overfull or underfull hbox */ + /* + Finish issuing a diagnostic message for an overfull or underfull + hbox. + */ if (output_active) { tprint(") has occurred while \\output is active"); } else { @@ -829,7 +979,6 @@ halfword hpack(halfword p, scaled w, int m, int pack_direction) begin_diagnostic(); show_box(r); end_diagnostic(true); - EXIT: if ((m == cal_expand_ratio) && (font_expand_ratio != 0)) { font_expand_ratio = fix_int(font_expand_ratio, -1000, 1000); @@ -844,16 +993,40 @@ halfword hpack(halfword p, scaled w, int m, int pack_direction) } @ @c -halfword filtered_hpack(halfword p, halfword qt, scaled w, int m, int grp, - int pac) +/* +halfword filtered_hpack(halfword p, halfword qt, scaled w, int m, int grp, int pac) { halfword q; new_hyphenation(p, qt); - (void) new_ligkern(p, qt); /* don't care about the tail in this case */ + (void) new_ligkern(p, qt); // we don't care about the tail in this case q = vlink(p); q = lua_hpack_filter(q, w, m, grp, pac); return hpack(q, w, m, pac); } +*/ + +halfword filtered_hpack(halfword p, halfword qt, scaled w, int m, int grp, int pac, int just_pack) +{ + halfword q; + if (just_pack) { + q = vlink(p); + } else if (type(p) == temp_node && vlink(p) == null) { + q = vlink(p); + /* + q = new_node(hlist_node, min_quarterword); + box_dir(q) = (pac == -1) ? text_direction : pac; + width(q) = w; + return q; + */ + } else { + new_hyphenation(p, qt); + (void) new_ligkern(p, qt); /* we don't care about the tail in this case */ + q = vlink(p); + /* maybe here: alink(p) = null */ + q = lua_hpack_filter(q, w, m, grp, pac); /* ignores empty anyway */ /* maybe also pass tail */ + } + return hpack(q, w, m, pac); +} @ here is a function to calculate the natural whd of a (horizontal) node list @@ -861,10 +1034,10 @@ halfword filtered_hpack(halfword p, halfword qt, scaled w, int m, int grp, scaled_whd natural_sizes(halfword p, halfword pp, glue_ratio g_mult, int g_sign, int g_order, int pack_direction) { - scaled s; /* shift amount */ - halfword g; /* points to a glue specification */ + scaled s; /* shift amount */ + halfword g; /* points to a glue specification */ int hpack_dir; - scaled_whd xx; /* for recursion */ + scaled_whd xx; /* for recursion */ scaled_whd whd, siz = { 0, 0, 0 }; if (pack_direction == -1) { hpack_dir = text_direction; @@ -883,76 +1056,82 @@ scaled_whd natural_sizes(halfword p, halfword pp, glue_ratio g_mult, } if (p != pp && p != null) { switch (type(p)) { - case hlist_node: - case vlist_node: - s = shift_amount(p); - whd = pack_width_height_depth(hpack_dir, box_dir(p), p, false); - siz.wd += whd.wd; - if (whd.ht - s > siz.ht) - siz.ht = whd.ht - s; - if (whd.dp + s > siz.dp) - siz.dp = whd.dp + s; - break; - case rule_node: - case unset_node: - siz.wd += width(p); - if (type(p) >= rule_node) - s = 0; - else + case hlist_node: + case vlist_node: s = shift_amount(p); - if (height(p) - s > siz.ht) - siz.ht = height(p) - s; - if (depth(p) + s > siz.dp) - siz.dp = depth(p) + s; - break; - case math_node: - /* begin mathskip code */ - if (glue_ptr(p) == zero_glue) { - siz.wd += surround(p); + whd = pack_width_height_depth(hpack_dir, box_dir(p), p, false); + siz.wd += whd.wd; + if (whd.ht - s > siz.ht) + siz.ht = whd.ht - s; + if (whd.dp + s > siz.dp) + siz.dp = whd.dp + s; break; - } else { - /* fall through: mathskip */ - } - /* end mathskip code */ - case glue_node: - g = glue_ptr(p); - siz.wd += width(g); - if (g_sign != normal) { - if (g_sign == stretching) { - if (stretch_order(g) == g_order) { - siz.wd += - float_round(float_cast(g_mult) * - float_cast(stretch(g))); + /* + case rule_node: + case unset_node: + siz.wd += width(p); + if (type(p) >= rule_node) // always true + s = 0; + else + s = shift_amount(p); + if (height(p) - s > siz.ht) + siz.ht = height(p) - s; + if (depth(p) + s > siz.dp) + siz.dp = depth(p) + s; + break; + */ + case rule_node: + case unset_node: + siz.wd += width(p); + if (height(p) > siz.ht) + siz.ht = height(p); + if (depth(p) > siz.dp) + siz.dp = depth(p); + break; + /* */ + case math_node: + /* begin mathskip code */ + if (glue_ptr(p) == zero_glue) { + siz.wd += surround(p); + break; + } else { + /* fall through: mathskip */ + } + /* end mathskip code */ + case glue_node: + g = glue_ptr(p); + siz.wd += width(g); + if (g_sign != normal) { + if (g_sign == stretching) { + if (stretch_order(g) == g_order) { + siz.wd += float_round(float_cast(g_mult) * float_cast(stretch(g))); + } + } else if (shrink_order(g) == g_order) { + siz.wd -= float_round(float_cast(g_mult) * float_cast(shrink(g))); } - } else if (shrink_order(g) == g_order) { - siz.wd -= - float_round(float_cast(g_mult) * - float_cast(shrink(g))); } - } - if (subtype(p) >= a_leaders) { - g = leader_ptr(p); - if (height(g) > siz.ht) - siz.ht = height(g); - if (depth(g) > siz.dp) - siz.dp = depth(g); - } - break; - case margin_kern_node: - case kern_node: - siz.wd += width(p); - break; - case disc_node: - xx = natural_sizes(no_break(p), null, g_mult, g_sign, g_order, - hpack_dir); - siz.wd += xx.wd; - if (xx.ht > siz.ht) - siz.ht = xx.ht; - if (xx.dp > siz.dp) - siz.dp = xx.dp; - break; - default: - break; + if (subtype(p) >= a_leaders) { + g = leader_ptr(p); + if (height(g) > siz.ht) + siz.ht = height(g); + if (depth(g) > siz.dp) + siz.dp = depth(g); + } + break; + case margin_kern_node: + case kern_node: + siz.wd += width(p); + break; + case disc_node: + xx = natural_sizes(no_break(p), null, g_mult, g_sign, g_order, hpack_dir); + siz.wd += xx.wd; + if (xx.ht > siz.ht) + siz.ht = xx.ht; + if (xx.dp > siz.dp) + siz.dp = xx.dp; + break; + default: + break; } p = vlink(p); } @@ -961,29 +1140,31 @@ scaled_whd natural_sizes(halfword p, halfword pp, glue_ratio g_mult, return siz; } +@ In order to provide a decent indication of where an overfull or underfull box +originated, we use a global variable |pack_begin_line| that is set nonzero only +when |hpack| is being called by the paragraph builder or the alignment finishing +routine. -@ In order to provide a decent indication of where an overfull or underfull -box originated, we use a global variable |pack_begin_line| that is -set nonzero only when |hpack| is being called by the paragraph builder -or the alignment finishing routine. +@ The source file line where the current paragraph or alignment began; a negative +value denotes alignment: @c -int pack_begin_line; /* source file line where the current paragraph - or alignment began; a negative value denotes alignment */ - +int pack_begin_line; -@ The |vpack| subroutine is actually a special case of a slightly more -general routine called |vpackage|, which has four parameters. The fourth -parameter, which is |max_dimen| in the case of |vpack|, specifies the -maximum depth of the page box that is constructed. The depth is first -computed by the normal rules; if it exceeds this limit, the reference -point is simply moved down until the limiting depth is attained. +@ The |vpack| subroutine is actually a special case of a slightly more general +routine called |vpackage|, which has four parameters. The fourth parameter, which +is |max_dimen| in the case of |vpack|, specifies the maximum depth of the page +box that is constructed. The depth is first computed by the normal rules; if it +exceeds this limit, the reference point is simply moved down until the limiting +depth is attained. @c halfword vpackage(halfword p, scaled h, int m, scaled l, int pack_direction) { halfword r; /* the box node that will be returned */ - scaled w, d, x; /* width, depth, and natural height */ + scaled w = 0; /* width */ + scaled d = 0; /* depth */ + scaled x = 0; /* natural height */ scaled_whd whd; scaled s; /* shift amount */ halfword g; /* points to a glue specification */ @@ -998,10 +1179,6 @@ halfword vpackage(halfword p, scaled h, int m, scaled l, int pack_direction) subtype(r) = min_quarterword; shift_amount(r) = 0; list_ptr(r) = p; - w = 0; - /* Clear dimensions to zero */ - d = 0; - x = 0; total_stretch[normal] = 0; total_shrink[normal] = 0; total_stretch[sfi] = 0; @@ -1014,16 +1191,21 @@ halfword vpackage(halfword p, scaled h, int m, scaled l, int pack_direction) total_shrink[filll] = 0; while (p != null) { - /* Examine node |p| in the vlist, taking account of its effect - on the dimensions of the new box; then advance |p| to the next node */ + /* + Examine node |p| in the vlist, taking account of its effect + on the dimensions of the new box; then advance |p| to the next + node. + */ if (is_char_node(p)) { confusion("vpack"); } else { switch (type(p)) { case hlist_node: case vlist_node: - /* Incorporate box dimensions into the dimensions of - the vbox that will contain~it */ + /* + Incorporate box dimensions into the dimensions of + the vbox that will contain it. + */ s = shift_amount(p); whd = pack_width_height_depth(box_dir(r), box_dir(p), p, false); if (whd.wd + s > w) @@ -1031,17 +1213,27 @@ halfword vpackage(halfword p, scaled h, int m, scaled l, int pack_direction) x += d + whd.ht; d = whd.dp; break; + /* case rule_node: case unset_node: x += d + height(p); d = depth(p); - if (type(p) >= rule_node) + if (type(p) >= rule_node) // always s = 0; else s = shift_amount(p); if (width(p) + s > w) w = width(p) + s; break; + */ + case rule_node: + case unset_node: + x += d + height(p); + d = depth(p); + if (width(p) > w) + w = width(p); + break; + /* */ case glue_node: /* Incorporate glue into the vertical totals */ x += d; @@ -1075,23 +1267,28 @@ halfword vpackage(halfword p, scaled h, int m, scaled l, int pack_direction) } else { depth(r) = d; } - /* Determine the value of |height(r)| and the appropriate glue setting; - then |return| or |goto common_ending| */ - /* When we get to the present part of the program, |x| is the natural height - of the box being packaged. */ + /* + Determine the value of |height(r)| and the appropriate glue setting; + then |return| or |goto common_ending|. + + When we get to the present part of the program, |x| is the natural + height of the box being packaged. + */ if (m == additional) h = x + h; height(r) = h; - x = h - x; /* now |x| is the excess to be made up */ + x = h - x; + /* now |x| is the excess to be made up */ if (x == 0) { glue_sign(r) = normal; glue_order(r) = normal; set_glue_ratio_zero(glue_set(r)); return r; } else if (x > 0) { - /* Determine vertical glue stretch setting, then |return| - or \hbox{|goto common_ending|} */ - /* Determine the stretch order */ + /* + Determine vertical glue stretch setting, then |return| + or \hbox{|goto common_ending|}. + */ if (total_stretch[filll] != 0) o = filll; else if (total_stretch[fill] != 0) @@ -1113,8 +1310,10 @@ halfword vpackage(halfword p, scaled h, int m, scaled l, int pack_direction) } if (o == normal) { if (list_ptr(r) != null) { - /* Report an underfull vbox and |goto common_ending|, if this box - is sufficiently bad */ + /* + Report an underfull vbox and |goto common_ending|, if this box + is sufficiently bad. + */ last_badness = badness(x, total_stretch[normal]); if (last_badness > int_par(vbadness_code)) { int callback_id = callback_defined(vpack_quality_callback); @@ -1141,9 +1340,10 @@ halfword vpackage(halfword p, scaled h, int m, scaled l, int pack_direction) return r; } else { - /* Determine vertical glue shrink setting, then |return| - or \hbox{|goto common_ending|} */ - /* Determine the shrink order */ + /* + Determine vertical glue shrink setting, then |return| + or \hbox{|goto common_ending|}. + */ if (total_shrink[filll] != 0) o = filll; else if (total_shrink[fill] != 0) @@ -1160,14 +1360,19 @@ halfword vpackage(halfword p, scaled h, int m, scaled l, int pack_direction) if (total_shrink[o] != 0) { glue_set(r) = unfloat((double) (-x) / total_shrink[o]); } else { + /* there's nothing to shrink */ glue_sign(r) = normal; - set_glue_ratio_zero(glue_set(r)); /* there's nothing to shrink */ + set_glue_ratio_zero(glue_set(r)); } if ((total_shrink[o] < -x) && (o == normal) && (list_ptr(r) != null)) { int overshoot = -x - total_shrink[normal]; last_badness = 1000000; - set_glue_ratio_one(glue_set(r)); /* use the maximum shrinkage */ - /* Report an overfull vbox and |goto common_ending|, if this box is sufficiently bad */ + /* use the maximum shrinkage */ + set_glue_ratio_one(glue_set(r)); + /* + Report an overfull vbox and |goto common_ending|, if this box + is sufficiently bad. + */ if ((overshoot > dimen_par(vfuzz_code)) || (int_par(vbadness_code) < 100)) { int callback_id = callback_defined(vpack_quality_callback); if (callback_id > 0) { @@ -1183,7 +1388,10 @@ halfword vpackage(halfword p, scaled h, int m, scaled l, int pack_direction) } } else if (o == normal) { if (list_ptr(r) != null) { - /* Report a tight vbox and |goto common_ending|, if this box is sufficiently bad */ + /* + Report a tight vbox and |goto common_ending|, if this box is + sufficiently bad. + */ last_badness = badness(-x, total_shrink[normal]); if (last_badness > int_par(vbadness_code)) { int callback_id = callback_defined(vpack_quality_callback); @@ -1207,7 +1415,8 @@ halfword vpackage(halfword p, scaled h, int m, scaled l, int pack_direction) if (output_active) { tprint(") has occurred while \\output is active"); } else { - if (pack_begin_line != 0) { /* it's actually negative */ + if (pack_begin_line != 0) { + /* it's actually negative */ tprint(") in alignment at lines "); print_int(abs(pack_begin_line)); tprint("--"); @@ -1225,12 +1434,12 @@ halfword vpackage(halfword p, scaled h, int m, scaled l, int pack_direction) } @ @c -halfword filtered_vpackage(halfword p, scaled h, int m, scaled l, int grp, - int pack_direction) +halfword filtered_vpackage(halfword p, scaled h, int m, scaled l, int grp, int pack_direction, int just_pack) { - halfword q; - q = p; - q = lua_vpack_filter(q, h, m, l, grp, pack_direction); + halfword q = p; + if (!just_pack) + /* if (q != null) */ + q = lua_vpack_filter(q, h, m, l, grp, pack_direction); return vpackage(q, h, m, l, pack_direction); } @@ -1249,42 +1458,37 @@ void finish_vcenter(void) @ @c void package(int c) { - scaled h; /* height of box */ - halfword p; /* first node in a box */ - scaled d; /* max depth */ - int grp; - halfword saved0, saved2, saved3; - grp = cur_group; - d = box_max_depth; + halfword saved0, saved2, saved3, saved4; + int grp = cur_group; + scaled d = box_max_depth; /* max depth */ unsave(); - save_ptr -= 4; + save_ptr -= 5; saved0 = saved_value(0); saved2 = saved_value(2); saved3 = saved_value(3); + saved4 = saved_value(4); if (cur_list.mode_field == -hmode) { - cur_box = filtered_hpack(cur_list.head_field, - cur_list.tail_field, saved_value(1), - saved_level(1), grp, saved_level(2)); + cur_box = filtered_hpack(cur_list.head_field, cur_list.tail_field, + saved_value(1), saved_level(1), grp, saved_level(2), saved4); subtype(cur_box) = hbox_list; } else { cur_box = filtered_vpackage(vlink(cur_list.head_field), - saved_value(1), saved_level(1), d, grp, - saved_level(2)); + saved_value(1), saved_level(1), d, grp, saved_level(2), saved4); if (c == vtop_code) { - /* Readjust the height and depth of |cur_box|, for \.{\\vtop} */ - /* The height of a `\.{\\vtop}' box is inherited from the first item on its list, - if that item is an |hlist_node|, |vlist_node|, or |rule_node|; otherwise - the \.{\\vtop} height is zero. - */ - - h = 0; - p = list_ptr(cur_box); - if (p != null) - if (type(p) <= rule_node) - h = height(p); + /* + Read just the height and depth of |cur_box|, for \.{\\vtop}. The + height of a `\.{\\vtop}' box is inherited from the first item on + its list, if that item is an |hlist_node|, |vlist_node|, or + |rule_node|; otherwise the \.{\\vtop} height is zero. + */ + scaled h = 0; + halfword p = list_ptr(cur_box); + if ((p != null) && (type(p) <= rule_node)) { + /* hlist, vlist, rule */ + h = height(p); + } depth(cur_box) = depth(cur_box) - h + height(cur_box); height(cur_box) = h; - } } if (saved2 != null) { @@ -1298,10 +1502,8 @@ void package(int c) box_end(saved0); } - - -@ When a box is being appended to the current vertical list, the -baselineskip calculation is handled by the |append_to_vlist| routine. +@ When a box is being appended to the current vertical list, the baselineskip +calculation is handled by the |append_to_vlist| routine. @c void append_to_vlist(halfword b, int location) @@ -1332,7 +1534,8 @@ void append_to_vlist(halfword b, int location) p = new_param_glue(line_skip_code); } else { p = new_skip_param(baseline_skip_code); - width(temp_ptr) = d; /* |temp_ptr=glue_ptr(p)| */ + /* |temp_ptr=glue_ptr(p)| */ + width(temp_ptr) = d; } couple_nodes(cur_list.tail_field, p); cur_list.tail_field = p; @@ -1347,31 +1550,29 @@ void append_to_vlist(halfword b, int location) } } - -@ When |saving_vdiscards| is positive then the glue, kern, and penalty -nodes removed by the page builder or by \.{\\vsplit} from the top of a -vertical list are saved in special lists instead of being discarded. +@ When |saving_vdiscards| is positive then the glue, kern, and penalty nodes +removed by the page builder or by \.{\\vsplit} from the top of a vertical list +are saved in special lists instead of being discarded. @c -#define tail_page_disc disc_ptr[copy_code] /* last item removed by page builder */ -#define page_disc disc_ptr[last_box_code] /* first item removed by page builder */ -#define split_disc disc_ptr[vsplit_code] /* first item removed by \.{\\vsplit} */ +#define tail_page_disc disc_ptr[copy_code] /* last item removed by page builder */ +#define page_disc disc_ptr[last_box_code] /* first item removed by page builder */ +#define split_disc disc_ptr[vsplit_code] /* first item removed by \.{\\vsplit} */ -halfword disc_ptr[(vsplit_code + 1)]; /* list pointers */ +halfword disc_ptr[(vsplit_code + 1)]; /* list pointers */ +@ The |vsplit| procedure, which implements \TeX's \.{\\vsplit} operation, is +considerably simpler than |line_break| because it doesn't have to worry about +hyphenation, and because its mission is to discover a single break instead of an +optimum sequence of breakpoints. But before we get into the details of |vsplit|, +we need to consider a few more basic things. -@ The |vsplit| procedure, which implements \TeX's \.{\\vsplit} operation, -is considerably simpler than |line_break| because it doesn't have to -worry about hyphenation, and because its mission is to discover a single -break instead of an optimum sequence of breakpoints. But before we get -into the details of |vsplit|, we need to consider a few more basic things. - -A subroutine called |prune_page_top| takes a pointer to a vlist and -returns a pointer to a modified vlist in which all glue, kern, and penalty nodes -have been deleted before the first box or rule node. However, the first -box or rule is actually preceded by a newly created glue node designed so that -the topmost baseline will be at distance |split_top_skip| from the top, -whenever this is possible without backspacing. +A subroutine called |prune_page_top| takes a pointer to a vlist and returns a +pointer to a modified vlist in which all glue, kern, and penalty nodes have been +deleted before the first box or rule node. However, the first box or rule is +actually preceded by a newly created glue node designed so that the topmost +baseline will be at distance |split_top_skip| from the top, whenever this is +possible without backspacing. When the second argument |s| is |false| the deleted nodes are destroyed, otherwise they are collected in a list starting at |split_disc|. @@ -1379,11 +1580,10 @@ otherwise they are collected in a list starting at |split_disc|. @c halfword prune_page_top(halfword p, boolean s) { - halfword prev_p; /* lags one step behind |p| */ - halfword q, r; /* temporary variables for list manipulation */ - prev_p = temp_head; + halfword q; + halfword prev_p = temp_head; /* lags one step behind |p| */ + halfword r = null; vlink(temp_head) = p; - r = null; while (p != null) { switch (type(p)) { case hlist_node: @@ -1392,7 +1592,8 @@ halfword prune_page_top(halfword p, boolean s) /* Insert glue for |split_top_skip| and set~|p:=null| */ q = new_skip_param(split_top_skip_code); vlink(prev_p) = q; - vlink(q) = p; /* now |temp_ptr=glue_ptr(q)| */ + vlink(q) = p; + /* now |temp_ptr=glue_ptr(q)| */ if (width(temp_ptr) > height(p)) width(temp_ptr) = width(temp_ptr) - height(p); else @@ -1431,52 +1632,49 @@ halfword prune_page_top(halfword p, boolean s) return vlink(temp_head); } - -@ The next subroutine finds the best place to break a given vertical list -so as to obtain a box of height~|h|, with maximum depth~|d|. -A pointer to the beginning of the vertical list is given, -and a pointer to the optimum breakpoint is returned. The list is effectively -followed by a forced break, i.e., a penalty node with the |eject_penalty|; -if the best break occurs at this artificial node, the value |null| is returned. +@ The next subroutine finds the best place to break a given vertical list so as +to obtain a box of height~|h|, with maximum depth~|d|. A pointer to the beginning +of the vertical list is given, and a pointer to the optimum breakpoint is +returned. The list is effectively followed by a forced break, i.e., a penalty +node with the |eject_penalty|; if the best break occurs at this artificial node, +the value |null| is returned. @c -scaled active_height[10]; /* distance from first active node to~|cur_p| */ - +scaled active_height[10]; /* distance from first active node to~|cur_p| */ -@ An array of six |scaled| distances is used to keep track of the height -from the beginning of the list to the current place, just as in |line_break|. -In fact, we use one of the same arrays, only changing its name to reflect -its new significance. +@ An array of six |scaled| distances is used to keep track of the height from the +beginning of the list to the current place, just as in |line_break|. In fact, we +use one of the same arrays, only changing its name to reflect its new +significance. @c #define do_all_six(A) A(1);A(2);A(3);A(4);A(5);A(6);A(7) #define set_height_zero(A) active_height[A]=0 /* initialize the height to zero */ +@ A global variable |best_height_plus_depth| will be set to the natural size of +the box that corresponds to the optimum breakpoint found by |vert_break|. (This +value is used by the insertion-splitting algorithm of the page builder.) -@ A global variable |best_height_plus_depth| will be set to the natural size -of the box that corresponds to the optimum breakpoint found by |vert_break|. -(This value is used by the insertion-splitting algorithm of the page builder.) +@ height of the best box, without stretching or shrinking @c -scaled best_height_plus_depth; /* height of the best box, without stretching or shrinking */ +scaled best_height_plus_depth; + +/* finds optimum page break */ halfword vert_break(halfword p, scaled h, scaled d) -{ /* finds optimum page break */ - halfword prev_p; /* if |p| is a glue node, |type(prev_p)| determines - whether |p| is a legal breakpoint */ +{ + halfword prev_p = p; /* if |p| is a glue node, |type(prev_p)| determines whether |p| is a + legal breakpoint, an initial glue node is not a legal breakpoint */ halfword q, r; /* glue specifications */ - int pi; /* penalty value */ + int pi = 0; /* penalty value */ int b; /* badness at a trial breakpoint */ - int least_cost; /* the smallest badness plus penalties found so far */ - halfword best_place; /* the most recent break that leads to |least_cost| */ - scaled prev_dp; /* depth of previous box in the list */ int t; /* |type| of the node following a kern */ - prev_p = p; /* an initial glue node is not a legal breakpoint */ + int least_cost; /* the smallest badness plus penalties found so far */ + halfword best_place = null; /* the most recent break that leads to |least_cost| */ + scaled prev_dp = 0; /* depth of previous box in the list */ least_cost = awful_bad; do_all_six(set_height_zero); - prev_dp = 0; - best_place = null; - pi = 0; while (1) { /* If node |p| is a legal breakpoint, check if this break is the best known, and |goto done| if |p| is null or @@ -1596,13 +1794,11 @@ halfword vert_break(halfword p, scaled h, scaled d) } cur_height = cur_height + prev_dp + width(q); prev_dp = 0; - NOT_FOUND: if (prev_dp > d) { cur_height = cur_height + prev_dp - d; prev_dp = d; } - prev_p = p; p = vlink(prev_p); } @@ -1610,30 +1806,31 @@ halfword vert_break(halfword p, scaled h, scaled d) return best_place; } +@ Now we are ready to consider |vsplit| itself. Most of its work is accomplished +by the two subroutines that we have just considered. -@ Now we are ready to consider |vsplit| itself. Most of -its work is accomplished by the two subroutines that we have just considered. +Given the number of a vlist box |n|, and given a desired page height |h|, the +|vsplit| function finds the best initial segment of the vlist and returns a box +for a page of height~|h|. The remainder of the vlist, if any, replaces the +original box, after removing glue and penalties and adjusting for +|split_top_skip|. Mark nodes in the split-off box are used to set the values of +|split_first_mark| and |split_bot_mark|; we use the fact that +|split_first_mark(x)=null| if and only if |split_bot_mark(x)=null|. -Given the number of a vlist box |n|, and given a desired page height |h|, -the |vsplit| function finds the best initial segment of the vlist and -returns a box for a page of height~|h|. The remainder of the vlist, if -any, replaces the original box, after removing glue and penalties and -adjusting for |split_top_skip|. Mark nodes in the split-off box are used to -set the values of |split_first_mark| and |split_bot_mark|; we use the -fact that |split_first_mark(x)=null| if and only if |split_bot_mark(x)=null|. - -The original box becomes ``void'' if and only if it has been entirely -extracted. The extracted box is ``void'' if and only if the original -box was void (or if it was, erroneously, an hlist box). +The original box becomes ``void'' if and only if it has been entirely extracted. +The extracted box is ``void'' if and only if the original box was void (or if it +was, erroneously, an hlist box). @c +/* extracts a page of height |h| from box |n| */ + halfword vsplit(halfword n, scaled h) -{ /* extracts a page of height |h| from box |n| */ - halfword v; /* the box to be split */ - int vdir; /* the direction of the box to be split */ - halfword p; /* runs through the vlist */ - halfword q; /* points to where the break occurs */ - halfword i; /* for traversing marks lists */ +{ + halfword v; /* the box to be split */ + int vdir; /* the direction of the box to be split */ + halfword p; /* runs through the vlist */ + halfword q; /* points to where the break occurs */ + halfword i; /* for traversing marks lists */ v = box(n); vdir = box_dir(v); flush_node_list(split_disc); @@ -1653,13 +1850,13 @@ halfword vsplit(halfword n, scaled h) error(); return null; } - q = vert_break(list_ptr(v), h, dimen_par(split_max_depth_code)); - /* Look at all the marks in nodes before the break, and set the final - link to |null| at the break */ - /* It's possible that the box begins with a penalty node that is the - ``best'' break, so we must be careful to handle this special case correctly. */ - + /* + Look at all the marks in nodes before the break, and set the final + link to |null| at the break. It's possible that the box begins with + a penalty node that is the ``best'' break, so we must be careful to + handle this special case correctly. + */ p = list_ptr(v); if (p == q) { list_ptr(v) = null; @@ -1668,11 +1865,9 @@ halfword vsplit(halfword n, scaled h) if (type(p) == mark_node) { if (split_first_mark(mark_class(p)) == null) { set_split_first_mark(mark_class(p), mark_ptr(p)); - set_split_bot_mark(mark_class(p), - split_first_mark(mark_class(p))); + set_split_bot_mark(mark_class(p), split_first_mark(mark_class(p))); set_token_ref_count(split_first_mark(mark_class(p)), - token_ref_count(split_first_mark - (mark_class(p))) + 2); + token_ref_count(split_first_mark(mark_class(p))) + 2); } else { delete_token_ref(split_bot_mark(mark_class(p))); set_split_bot_mark(mark_class(p), mark_ptr(p)); @@ -1686,137 +1881,161 @@ halfword vsplit(halfword n, scaled h) p = vlink(p); } } - q = prune_page_top(q, int_par(saving_vdiscards_code) > 0); p = list_ptr(v); list_ptr(v) = null; flush_node(v); - if (q == null) - box(n) = null; /* the |eq_level| of the box stays the same */ - else + if (q == null) { + /* the |eq_level| of the box stays the same */ + box(n) = null; + } else { box(n) = - filtered_vpackage(q, 0, additional, dimen_par(max_depth_code), - split_keep_group, vdir); - return filtered_vpackage(p, h, exactly, - dimen_par(split_max_depth_code), split_off_group, - vdir); + filtered_vpackage(q, 0, additional, dimen_par(max_depth_code), split_keep_group, vdir, 0); + } + return filtered_vpackage(p, h, exactly, dimen_par(split_max_depth_code), split_off_group, vdir, 0); } - -@ Now that we can see what eventually happens to boxes, we can consider -the first steps in their creation. The |begin_box| routine is called when -|box_context| is a context specification, |cur_chr| specifies the type of -box desired, and |cur_cmd=make_box|. +@ Now that we can see what eventually happens to boxes, we can consider the first +steps in their creation. The |begin_box| routine is called when |box_context| is +a context specification, |cur_chr| specifies the type of box desired, and +|cur_cmd=make_box|. @c void begin_box(int box_context) { - halfword q; /* run through the current list */ - halfword k; /* 0 or |vmode| or |hmode| */ - int n; /* a box number */ + halfword q; /* run through the current list */ + halfword k; /* 0 or |vmode| or |hmode| */ + int n; /* a box number */ int spec_direction = -1; + int just_pack = 0; switch (cur_chr) { - case box_code: - scan_register_num(); - cur_box = box(cur_val); - box(cur_val) = null; /* the box becomes void, at the same level */ - break; - case copy_code: - scan_register_num(); - cur_box = copy_node_list(box(cur_val)); - break; - case last_box_code: - /* If the current list ends with a box node, delete it from - the list and make |cur_box| point to it; otherwise set |cur_box:=null| */ - cur_box = null; - if (abs(cur_list.mode_field) == mmode) { - you_cant(); - help1("Sorry; this \\lastbox will be void."); - error(); - } else if ((cur_list.mode_field == vmode) - && (cur_list.head_field == cur_list.tail_field)) { - you_cant(); - help2("Sorry...I usually can't take things from the current page.", - "This \\lastbox will therefore be void."); - error(); - } else { - if (cur_list.head_field != cur_list.tail_field) { /* todo: new code, needs testing */ - if ((type(cur_list.tail_field) == hlist_node) - || (type(cur_list.tail_field) == vlist_node)) { - /* Remove the last box ... */ - q = alink(cur_list.tail_field); - if (q == null || vlink(q) != cur_list.tail_field) { - q = cur_list.head_field; - while (vlink(q) != cur_list.tail_field) - q = vlink(q); + case box_code: + scan_register_num(); + cur_box = box(cur_val); + /* the box becomes void, at the same level */ + box(cur_val) = null; + break; + case copy_code: + scan_register_num(); + cur_box = copy_node_list(box(cur_val)); + break; + case last_box_code: + /* + If the current list ends with a box node, delete it from + the list and make |cur_box| point to it; otherwise set + |cur_box:=null|. + */ + cur_box = null; + if (abs(cur_list.mode_field) == mmode) { + you_cant(); + help1("Sorry; this \\lastbox will be void."); + error(); + } else if ((cur_list.mode_field == vmode) && (cur_list.head_field == cur_list.tail_field)) { + you_cant(); + help2("Sorry...I usually can't take things from the current page.", + "This \\lastbox will therefore be void."); + error(); + } else { + if (cur_list.head_field != cur_list.tail_field) { + /* todo: new code, needs testing */ + + /* maybe: ((type(cur_list.tail_field) == hlist_node) < rule_node) */ + + if ((type(cur_list.tail_field) == hlist_node) || (type(cur_list.tail_field) == vlist_node)) { + /* Remove the last box ... */ + q = alink(cur_list.tail_field); + if (q == null || vlink(q) != cur_list.tail_field) { + q = cur_list.head_field; + while (vlink(q) != cur_list.tail_field) + q = vlink(q); + } + uncouple_node(cur_list.tail_field); + cur_box = cur_list.tail_field; + shift_amount(cur_box) = 0; + cur_list.tail_field = q; + vlink(cur_list.tail_field) = null; } - uncouple_node(cur_list.tail_field); - cur_box = cur_list.tail_field; - shift_amount(cur_box) = 0; - cur_list.tail_field = q; - vlink(cur_list.tail_field) = null; } } - } - break; - case vsplit_code: - /* Split off part of a vertical box, make |cur_box| point to it */ - /* Here we deal with things like `\.{\\vsplit 13 to 100pt}'. */ - scan_register_num(); - n = cur_val; - if (!scan_keyword("to")) { - print_err("Missing `to' inserted"); - help2("I'm working on `\\vsplit<box number> to <dimen>';", - "will look for the <dimen> next."); - error(); - } - scan_normal_dimen(); - cur_box = vsplit(n, cur_val); - break; - default: - /* Initiate the construction of an hbox or vbox, then |return| */ - /* Here is where we enter restricted horizontal mode or internal vertical - mode, in order to make a box. */ - k = cur_chr - vtop_code; - set_saved_record(0, saved_boxcontext, 0, box_context); - switch (abs(cur_list.mode_field)) { - case vmode: - spec_direction = body_direction; - break; - case hmode: - spec_direction = text_direction; break; - case mmode: - spec_direction = math_direction; + case vsplit_code: + /* + Split off part of a vertical box, make |cur_box| point to it. Here we + deal with things like `\.{\\vsplit 13 to 100pt}'. + */ + scan_register_num(); + n = cur_val; + if (!scan_keyword("to")) { + print_err("Missing `to' inserted"); + help2("I'm working on `\\vsplit<box number> to <dimen>';", + "will look for the <dimen> next."); + error(); + } + scan_normal_dimen(); + cur_box = vsplit(n, cur_val); break; - } - if (k == hmode) { - if ((box_context < box_flag) && (abs(cur_list.mode_field) == vmode)) - scan_full_spec(adjusted_hbox_group, spec_direction); - else - scan_full_spec(hbox_group, spec_direction); - } else { + default: + /* + Initiate the construction of an hbox or vbox, then |return|. Here is + where we enter restricted horizontal mode or internal vertical mode, + in order to make a box. + */ + switch (cur_chr) { + case tpack_code: + cur_chr = vtop_code; + just_pack = 1; + break; + case vpack_code: + cur_chr = vtop_code + vmode; + just_pack = 1; + break; + case hpack_code: + cur_chr = vtop_code + hmode; + just_pack = 1; + break; + } + /* */ + k = cur_chr - vtop_code; + set_saved_record(0, saved_boxcontext, 0, box_context); + switch (abs(cur_list.mode_field)) { + case vmode: + spec_direction = body_direction; + break; + case hmode: + spec_direction = text_direction; + break; + case mmode: + spec_direction = math_direction; + break; + } + if (k == hmode) { + if ((box_context < box_flag) && (abs(cur_list.mode_field) == vmode)) + scan_full_spec(adjusted_hbox_group, spec_direction,just_pack); + else + scan_full_spec(hbox_group, spec_direction,just_pack); + } else { + if (k == vmode) { + scan_full_spec(vbox_group, spec_direction,just_pack); + } else { + scan_full_spec(vtop_group, spec_direction,just_pack); + k = vmode; + } + normal_paragraph(); + } + push_nest(); + cur_list.mode_field = -k; if (k == vmode) { - scan_full_spec(vbox_group, spec_direction); + prev_depth = ignore_depth; + if (every_vbox != null) + begin_token_list(every_vbox, every_vbox_text); } else { - scan_full_spec(vtop_group, spec_direction); - k = vmode; + space_factor = 1000; + if (every_hbox != null) + begin_token_list(every_hbox, every_hbox_text); } - normal_paragraph(); - } - push_nest(); - cur_list.mode_field = -k; - if (k == vmode) { - prev_depth = ignore_depth; - if (every_vbox != null) - begin_token_list(every_vbox, every_vbox_text); - } else { - space_factor = 1000; - if (every_hbox != null) - begin_token_list(every_hbox, every_hbox_text); - } - return; - break; + return; + break; } - box_end(box_context); /* in simple cases, we use the box immediately */ + /* in simple cases, we use the box immediately */ + box_end(box_context); } diff --git a/Build/source/texk/web2c/luatexdir/tex/printing.h b/Build/source/texk/web2c/luatexdir/tex/printing.h index 838e87e5bde..1619c6072de 100644 --- a/Build/source/texk/web2c/luatexdir/tex/printing.h +++ b/Build/source/texk/web2c/luatexdir/tex/printing.h @@ -36,6 +36,7 @@ typedef enum { new_string = last_file_selector + 6, /* 21 */ /* printing is deflected to the string pool */ } selector_settings; +extern int escape_controls; extern int new_string_line; # define ssup_error_line 255 @@ -69,8 +70,8 @@ extern void print(int s); extern void lprint (lstring *ss); extern void print_nl(str_number s); extern void print_nlp(void); -extern void print_banner(const char *, int); -extern void log_banner(const char *, int); +extern void print_banner(const char *); +extern void log_banner(const char *); extern void print_version_banner(void); extern void print_esc(str_number s); extern void print_the_digs(eight_bits k); @@ -84,6 +85,7 @@ extern void print_current_string(void); extern void print_cs(int p); extern void sprint_cs(pointer p); +extern void sprint_cs_name(pointer p); extern void tprint(const char *s); extern void tprint_nl(const char *s); extern void tprint_esc(const char *s); diff --git a/Build/source/texk/web2c/luatexdir/tex/printing.w b/Build/source/texk/web2c/luatexdir/tex/printing.w index 2f11e7836dd..baafa24a8af 100644 --- a/Build/source/texk/web2c/luatexdir/tex/printing.w +++ b/Build/source/texk/web2c/luatexdir/tex/printing.w @@ -18,18 +18,17 @@ % with LuaTeX; if not, see <http://www.gnu.org/licenses/>. @ @c - - #include "ptexlib.h" -#include "lua/luatex-api.h" /* for luatex_banner */ +#include "lua/luatex-api.h" /* for luatex_banner */ @ @c #define font_id_text(A) cs_text(font_id_base+(A)) -#define wlog(A) fputc(A,log_file) -#define wterm(A) fputc(A,term_out) +#define wlog(A) fputc(A,log_file) +#define wterm(A) fputc(A,term_out) int new_string_line = 0; +int escape_controls = 1; @ Messages that are sent to a user's terminal and to the transcript-log file are produced by several `|print|' procedures. These procedures will @@ -71,89 +70,118 @@ have appeared so far on the current line that has been output to the terminal or to the transcript file, respectively. @c -alpha_file log_file; /* transcript of \TeX\ session */ -int selector = term_only; /* where to print a message */ -int dig[23]; /* digits in a number being output */ -int tally = 0; /* the number of characters recently printed */ -int term_offset = 0; /* the number of characters on the current terminal line */ -int file_offset = 0; /* the number of characters on the current file line */ -packed_ASCII_code trick_buf[(ssup_error_line + 1)]; /* circular buffer for pseudoprinting */ -int trick_count; /* threshold for pseudoprinting, explained later */ -int first_count; /* another variable for pseudoprinting */ -boolean inhibit_par_tokens = false; /* for minor adjustments to |show_token_list| */ +alpha_file log_file; /* transcript of \TeX\ session */ +int selector = term_only; /* where to print a message */ +int dig[23]; /* digits in a number being output */ +int tally = 0; /* the number of characters recently printed */ +int term_offset = 0; /* the number of characters on the current terminal line */ +int file_offset = 0; /* the number of characters on the current file line */ +packed_ASCII_code trick_buf[(ssup_error_line + 1)]; /* circular buffer for pseudoprinting */ +int trick_count; /* threshold for pseudoprinting, explained later */ +int first_count; /* another variable for pseudoprinting */ +boolean inhibit_par_tokens = false; /* for minor adjustments to |show_token_list| */ @ To end a line of text output, we call |print_ln| + @c void print_ln(void) -{ /* prints an end-of-line */ +{ switch (selector) { - case term_and_log: - wterm_cr(); - wlog_cr(); - term_offset = 0; - file_offset = 0; - break; - case log_only: - wlog_cr(); - file_offset = 0; - break; - case term_only: - wterm_cr(); - term_offset = 0; - break; - case no_print: - break; - case pseudo: - break; - case new_string: - if (new_string_line > 0) - print_char(new_string_line); - break; - default: - fprintf(write_file[selector], "\n"); - break; + case no_print: + break; + case term_only: + wterm_cr(); + term_offset = 0; + break; + case log_only: + wlog_cr(); + file_offset = 0; + break; + case term_and_log: + wterm_cr(); + wlog_cr(); + term_offset = 0; + file_offset = 0; + break; + case pseudo: + break; + case new_string: + if (new_string_line > 0) + print_char(new_string_line); + break; + default: + fprintf(write_file[selector], "\n"); + break; } -} /* |tally| is not affected */ - + /* |tally| is not affected */ +} @ The |print_char| procedure sends one byte to the desired destination. - All printing comes through |print_ln| or |print_char|, except for the - case of |tprint| (see below). +All printing comes through |print_ln| or |print_char|, except for the +case of |tprint| (see below). + +The checking of the line length is an inheritance from previosu engines +and we might drop it after release 1.0. We're not too picky about the exact +match of that length because we have utf output so length is then a bit +fuzzy anyway. @c -#define wterm_char(A) do { \ - if ((A>=0x20)||(A==0x0A)||(A==0x0D)||(A==0x09)) { \ - wterm(A); \ - } else { \ - if (term_offset+2>=max_print_line) { \ - wterm_cr(); term_offset=0; \ - } \ - incr(term_offset); wterm('^'); \ - incr(term_offset); wterm('^'); \ - wterm(A+64); \ - } \ - } while (0) - -#define needs_wrapping(A,B) \ - (((A>=0xF0)&&(B+4>=max_print_line))|| \ - ((A>=0xE0)&&(B+3>=max_print_line))|| \ +#define needs_escaping(A) \ + ((! escape_controls) || (A>=0x20) || (A==0x0A) || (A==0x0D) || (A==0x09)) + +#define escaped_char(A) \ + A+64 + +#define wterm_char(A) \ + if (needs_escaping(A)) { \ + wterm(A); \ + } else { \ + if (term_offset+2>=max_print_line) { \ + wterm_cr(); \ + term_offset=0; \ + } \ + wterm('^'); \ + wterm('^'); \ + wterm(escaped_char(A)); \ + term_offset += 2; \ + } + +/* + +#define needs_wrapping(A,B) \ + (((A>=0xF0)&&(B+4>=max_print_line)) || \ + ((A>=0xE0)&&(B+3>=max_print_line)) || \ ((A>=0xC0)&&(B+2>=max_print_line))) -#define fix_term_offset(A) do { \ - if (needs_wrapping(A,term_offset)){ \ - wterm_cr(); term_offset=0; \ - } \ - } while (0) +we have mostly ascii in logs, so ... + +*/ -#define fix_log_offset(A) do { \ - if (needs_wrapping(A,file_offset)){ \ - wlog_cr(); file_offset=0; \ - } \ - } while (0) +#define needs_wrapping(A,B) \ + ( (A>=0xC0) && \ + (((A>=0xF0) && (B+4>=max_print_line)) || \ + ((A>=0xE0) && (B+3>=max_print_line)) || \ + ( (B+2>=max_print_line))) \ + ) + +#define fix_term_offset(A) \ + if (needs_wrapping(A,term_offset)){ \ + wterm_cr(); \ + term_offset=0; \ + } + +#define fix_log_offset(A) \ + if (needs_wrapping(A,file_offset)){ \ + wlog_cr(); \ + file_offset=0; \ + } void print_char(int s) -{ /* prints a single byte */ - assert(s >= 0 && s < 256); +{ + if (s < 0 || s > 255) { + formatted_warning("print","weird character %i",s); + return; + } if (s == int_par(new_line_char_code)) { if (selector < pseudo) { print_ln(); @@ -161,62 +189,62 @@ void print_char(int s) } } switch (selector) { - case term_and_log: - fix_term_offset(s); - fix_log_offset(s); - wterm_char(s); - wlog(s); - incr(term_offset); - incr(file_offset); - if (term_offset == max_print_line) { - wterm_cr(); - term_offset = 0; - } - if (file_offset == max_print_line) { - wlog_cr(); - file_offset = 0; - } - break; - case log_only: - fix_log_offset(s); - wlog(s); - incr(file_offset); - if (file_offset == max_print_line) { - wlog_cr(); - file_offset = 0; - } - break; - case term_only: - fix_term_offset(s); - wterm_char(s); - incr(term_offset); - if (term_offset == max_print_line) { - wterm_cr(); - term_offset = 0; - } - break; - case no_print: - break; - case pseudo: - if (tally < trick_count) - trick_buf[tally % error_line] = (packed_ASCII_code) s; - break; - case new_string: - append_char(s); - break; /* we drop characters if the string space is full */ - default: - fprintf(write_file[selector], "%c", s); + case no_print: + break; + case term_only: + fix_term_offset(s); + wterm_char(s); + incr(term_offset); + if (term_offset == max_print_line) { + wterm_cr(); + term_offset = 0; + } + break; + case log_only: + fix_log_offset(s); + wlog(s); + incr(file_offset); + if (file_offset == max_print_line) { + wlog_cr(); + file_offset = 0; + } + break; + case term_and_log: + fix_term_offset(s); + fix_log_offset(s); + wterm_char(s); + wlog(s); + incr(term_offset); + incr(file_offset); + if (term_offset == max_print_line) { + wterm_cr(); + term_offset = 0; + } + if (file_offset == max_print_line) { + wlog_cr(); + file_offset = 0; + } + break; + case pseudo: + if (tally < trick_count) + trick_buf[tally % error_line] = (packed_ASCII_code) s; + break; + case new_string: + append_char(s); + break; + default: + fprintf(write_file[selector], "%c", s); } incr(tally); } - @ An entire string is output by calling |print|. Note that if we are outputting the single standard ASCII character \.c, we could call |print("c")|, since |"c"=99| is the number of a single-character string, as explained above. But |print_char("c")| is quicker, so \TeX\ goes directly to the |print_char| routine when it knows that this is safe. (The present implementation assumes that it is always safe to print a visible ASCII character.) + @^system dependencies@> The first 256 entries above the 17th unicode plane are used for a @@ -228,24 +256,19 @@ to do the same substraction while typesetting. @c void print(int s) -{ /* prints string |s| */ +{ if (s >= str_ptr) { - /* this can't happen */ - print_char('?'); - print_char('?'); - print_char('?'); + normal_warning("print","bad string pointer"); return; } else if (s < STRING_OFFSET) { if (s < 0) { - /* can't happen */ - print_char('?'); - print_char('?'); - print_char('?'); + normal_warning("print","bad string offset"); } else { /* TH not sure about this, disabled for now! */ if ((false) && (selector > pseudo)) { + /* internal strings are not expanded */ print_char(s); - return; /* internal strings are not expanded */ + return; } if (s == int_par(new_line_char_code)) { if (selector < pseudo) { @@ -265,10 +288,7 @@ void print(int s) } else if (s >= 0x110000) { int c = s - 0x110000; if (c >= 256) { - normal_warning("print", "bad raw byte to print (c=", true, false); - print_int(c); - tprint("), skipped."); - print_ln(); + formatted_warning("print", "bad raw byte to print (c=%d), skipped",c); } else { print_char(c); } @@ -332,6 +352,14 @@ different because it uses buffering, which works well because most of the output actually comes through |tprint|. @c +#define t_flush_buffer(target,offset) \ + buffer[i++] = '\n'; \ + buffer[i++] = '\0';\ + fputs(buffer, target); \ + i = 0; \ + buffer[0] = '\0'; \ + offset=0; + void tprint(const char *sss) { char *buffer = NULL; @@ -340,115 +368,101 @@ void tprint(const char *sss) int dolog = 0; int doterm = 0; switch (selector) { - case new_string: - append_string((const unsigned char *)sss, (unsigned) strlen(sss)); - return; - break; - case pseudo: - while (*sss) { - if (tally < trick_count) { - trick_buf[tally % error_line] = (packed_ASCII_code) *sss++; - tally++; - } else { - return; - } - } - return; - break; - case no_print: - return; - break; - case term_and_log: - dolog = 1; - doterm = 1; - break; - case log_only: - dolog = 1; - break; - case term_only: - doterm = 1; - break; - default: - { - char *newstr = xstrdup(sss); - char *s; - for (s=newstr;*s;s++) { - if (*s == newlinechar) { - *s = '\n'; - } + case no_print: + return; + break; + case term_only: + doterm = 1; + break; + case log_only: + dolog = 1; + break; + case term_and_log: + dolog = 1; + doterm = 1; + break; + case pseudo: + while (*sss) { + if (tally < trick_count) { + trick_buf[tally % error_line] = (packed_ASCII_code) *sss++; + tally++; + } else { + return; + } } - fputs(newstr, write_file[selector]); - free(newstr); return; - } - break; + break; + case new_string: + append_string((const unsigned char *)sss, (unsigned) strlen(sss)); + return; + break; + default: + { + char *newstr = xstrdup(sss); + char *s; + for (s=newstr;*s;s++) { + if (*s == newlinechar) { + *s = '\n'; + } + } + fputs(newstr, write_file[selector]); + free(newstr); + return; + } + break; } /* what is left is the 3 term/log settings */ - buffer = xmalloc(strlen(sss)*3); - if (dolog) { - const unsigned char *ss = (const unsigned char *) sss; - while (*ss) { - int s = *ss++; - if (needs_wrapping(s,file_offset) || s == newlinechar) { - buffer[i++] = '\n'; + if (dolog || doterm) { + buffer = xmalloc(strlen(sss)*3); + if (dolog) { + const unsigned char *ss = (const unsigned char *) sss; + while (*ss) { + int s = *ss++; + if (needs_wrapping(s,file_offset) || s == newlinechar) { + t_flush_buffer(log_file,file_offset); + } + if (s != newlinechar) { + buffer[i++] = s; + if (file_offset++ == max_print_line) { + t_flush_buffer(log_file,file_offset); + } + } + } + if (*buffer) { buffer[i++] = '\0'; fputs(buffer, log_file); - i = 0; buffer[0] = '\0'; - file_offset=0; + buffer[0] = '\0'; } - if (s != newlinechar) { - buffer[i++] = s; - if (file_offset++ == max_print_line) { - buffer[i++] = '\n'; - buffer[i++] = '\0'; - fputs(buffer, log_file); - i = 0; buffer[0] = '\0'; - file_offset = 0; + i = 0; + } + if (doterm) { + const unsigned char *ss = (const unsigned char *) sss; + while (*ss) { + int s = *ss++; + if (needs_wrapping(s,term_offset) || s == newlinechar) { + t_flush_buffer(term_out,term_offset); + } + if (s != newlinechar) { + if (needs_escaping(s)) { + buffer[i++] = s; + } else { + buffer[i++] = '^'; + buffer[i++] = '^'; + buffer[i++] = escaped_char(s); + term_offset += 2; + } + if (++term_offset == max_print_line) { + t_flush_buffer(term_out,term_offset); + } } } - } - if (*buffer) { - buffer[i++] = '\0'; - fputs(buffer, log_file); - buffer[0] = '\0'; - } - i = 0; - } - if (doterm) { - const unsigned char *ss = (const unsigned char *) sss; - while (*ss) { - int s = *ss++; - if (needs_wrapping(s,term_offset) || s == newlinechar) { - buffer[i++] = '\n'; + if (*buffer) { buffer[i++] = '\0'; fputs(buffer, term_out); - i = 0; buffer[0] = '\0'; - term_offset=0; - } - if (s != newlinechar) { - if ((s>=0x20)||(s==0x0A)||(s==0x0D)||(s==0x09)) { - buffer[i++] = s; - } else { - buffer[i++] = '^'; - buffer[i++] = '^'; - buffer[i++] = s+64; - term_offset += 2; - } - if (++term_offset == max_print_line) { - buffer[i++] = '\n'; - buffer[i++] = '\0'; - fputs(buffer, term_out); - i = 0; buffer[0] = '\0'; - term_offset = 0; - } } } - if (*buffer) { - buffer[i++] = '\0'; - fputs(buffer, term_out); - } + free(buffer); } - free(buffer); } void tprint_nl(const char *s) @@ -464,16 +478,11 @@ and format identifier together will occupy at most |max_print_line| character positions. @c -void print_banner(const char *v, int ver) +void print_banner(const char *v) { - int callback_id; - callback_id = callback_defined(start_run_callback); + int callback_id = callback_defined(start_run_callback); if (callback_id == 0) { - if (ver < 0) - fprintf(term_out, "This is " MyName ", Version %s ", v); - else - fprintf(term_out, "This is " MyName ", Version %s%s (rev %d) ", v, - WEB2CVERSION, ver); + fprintf(term_out, "This is " MyName ", Version %s%s ", v, WEB2CVERSION); if (format_ident > 0) print(format_ident); print_ln(); @@ -494,7 +503,7 @@ void print_banner(const char *v, int ver) } @ @c -void log_banner(const char *v, int ver) +void log_banner(const char *v) { const char *months[] = { " ", "JAN", "FEB", "MAR", "APR", "MAY", "JUN", @@ -503,11 +512,7 @@ void log_banner(const char *v, int ver) unsigned month = (unsigned) int_par(month_code); if (month > 12) month = 0; - if (ver < 0) - fprintf(log_file, "This is " MyName ", Version %s ", v); - else - fprintf(log_file, "This is " MyName ", Version %s%s (rev %d) ", v, - WEB2CVERSION, ver); + fprintf(log_file, "This is " MyName ", Version %s%s ", v, WEB2CVERSION); print(format_ident); print_char(' '); print_char(' '); @@ -544,21 +549,19 @@ the user's escape character (which is usually a backslash). @c void print_esc(str_number s) -{ /* prints escape character, then |s| */ - int c; /* the escape character code */ - /* Set variable |c| to the current escape character */ - c = int_par(escape_char_code); +{ + int c = int_par(escape_char_code); /* Set variable |c| to the current escape character */ if (c >= 0 && c < STRING_OFFSET) print(c); print(s); } -@ @c +@ This prints escape character, then |s|. + +@c void tprint_esc(const char *s) -{ /* prints escape character, then |s| */ - int c; /* the escape character code */ - /* Set variable |c| to the current escape character */ - c = int_par(escape_char_code); +{ + int c = int_par(escape_char_code); /* Set variable |c| to the current escape character */ if (c >= 0 && c < STRING_OFFSET) print(c); tprint(s); @@ -586,10 +589,9 @@ by all PASCAL compilers. @c void print_int(longinteger n) -{ /* prints an integer in decimal form */ - int k; /* index to current digit; we assume that $|n|<10^{23}$ */ - longinteger m; /* used to negate |n| in possibly dangerous cases */ - k = 0; +{ + int k = 0; /* index to current digit; we assume that $|n|<10^{23}$ */ + longinteger m; /* used to negate |n| in possibly dangerous cases */ if (n < 0) { print_char('-'); if (n > -100000000) { @@ -621,20 +623,18 @@ a parameter in the range |0<=n<=99|. @c void print_two(int n) -{ /* prints two least significant digits */ +{ n = abs(n) % 100; print_char('0' + (n / 10)); print_char('0' + (n % 10)); } - @ Hexadecimal printing of nonnegative integers is accomplished by |print_hex|. @c void print_hex(int n) -{ /* prints a positive integer in hexadecimal form */ - int k; /* index to current digit; we assume that $0\L n<16^{22}$ */ - k = 0; +{ + int k = 0 ; /* index to current digit; we assume that $0\L n<16^{22}$ */ print_char('"'); do { dig[k] = n % 16; @@ -644,7 +644,6 @@ void print_hex(int n) print_the_digs((eight_bits) k); } - @ Roman numerals are produced by the |print_roman_int| routine. Readers who like puzzles might enjoy trying to figure out how this tricky code works; therefore no explanation will be given. Notice that 1990 yields @@ -653,8 +652,8 @@ works; therefore no explanation will be given. Notice that 1990 yields @c void print_roman_int(int n) { - char *j, *k; /* mysterious indices */ - int u, v; /* mysterious numbers */ + char *j, *k; /* mysterious indices */ + int u, v; /* mysterious numbers */ char mystery[] = "m2d5c2l5x2v5i"; j = (char *) mystery; v = 1000; @@ -663,8 +662,10 @@ void print_roman_int(int n) print_char(*j); n = n - v; } - if (n <= 0) - return; /* nonpositive input produces no output */ + if (n <= 0) { + /* nonpositive input produces no output */ + return; + } k = j + 2; u = v / (*(k - 1) - '0'); if (*(k - 1) == '2') { @@ -681,14 +682,13 @@ void print_roman_int(int n) } } - @ The |print| subroutine will not print a string that is still being created. The following procedure will. @c void print_current_string(void) -{ /* prints a yet-unmade string */ - unsigned j = 0; /* points to current character code */ +{ + unsigned j = 0; /* points to current character code */ while (j < cur_length) print_char(cur_string[j++]); } @@ -702,9 +702,10 @@ they may be unprintable. @c void print_cs(int p) -{ /* prints a purported control sequence */ +{ str_number t = cs_text(p); - if (p < hash_base) { /* nullcs */ + if (p < hash_base) { + /* nullcs */ if (p == null_cs) { tprint_esc("csname"); tprint_esc("endcsname"); @@ -733,13 +734,12 @@ void print_cs(int p) } } - @ Here is a similar procedure; it avoids the error checks, and it never prints a space after the control sequence. @c void sprint_cs(pointer p) -{ /* prints a control sequence */ +{ str_number t; if (p == null_cs) { tprint_esc("csname"); @@ -753,8 +753,20 @@ void sprint_cs(pointer p) } } +void sprint_cs_name(pointer p) +{ + str_number t; + if (p != null_cs) { + t = cs_text(p); + if (is_active_cs(t)) + print(active_cs_value(t)); + else + print(t); + } +} @ This procedure is never called when |interaction<scroll_mode|. + @c void prompt_input(const char *s) { @@ -763,13 +775,12 @@ void prompt_input(const char *s) term_input(); } - @ Then there is a subroutine that prints glue stretch and shrink, possibly followed by the name of finite units: @c void print_glue(scaled d, int order, const char *s) -{ /* prints a glue component */ +{ print_scaled(d); if ((order < normal) || (order > filll)) { tprint("foul"); @@ -785,9 +796,10 @@ void print_glue(scaled d, int order, const char *s) } @ The next subroutine prints a whole glue specification + @c void print_spec(int p, const char *s) -{ /* prints a glue specification */ +{ if (p < 0) { print_char('*'); } else { @@ -805,7 +817,6 @@ void print_spec(int p, const char *s) } } - @ We can reinforce our knowledge of the data structures just introduced by considering two procedures that display a list in symbolic form. The first of these, called |short_display|, is used in ``overfull box'' @@ -824,8 +835,7 @@ is assumed to be present when |short_display| begins; deviations from this font will be printed. @c -int font_in_short_display; /* an internal font number */ - +int font_in_short_display; /* an internal font number */ @ Boxes, rules, inserts, whatsits, marks, and things in general that are sort of ``complicated'' are indicated only by printing `\.{[]}'. @@ -853,9 +863,11 @@ void print_font_identifier(internal_font_number f) } } -@ @c +@ This prints highlights of list |p|. + +@c void short_display(int p) -{ /* prints highlights of list |p| */ +{ while (p != null) { if (is_char_node(p)) { if (lig_ptr(p) != null) { @@ -879,14 +891,15 @@ void short_display(int p) } } - @ The |show_node_list| routine requires some auxiliary subroutines: one to print a font-and-character combination, one to print a token list without its reference count, and one to print a rule dimension. +@ This prints |char_node| data. + @c void print_font_and_char(int p) -{ /* prints |char_node| data */ +{ if (!is_valid_font(font(p))) print_char('*'); else @@ -895,9 +908,11 @@ void print_font_and_char(int p) print(character(p)); } -@ @c +@ This prints token list data in braces + +@c void print_mark(int p) -{ /* prints token list data in braces */ +{ print_char('{'); if ((p < (int) fix_mem_min) || (p > (int) fix_mem_end)) tprint_esc("CLOBBERED."); @@ -906,16 +921,17 @@ void print_mark(int p) print_char('}'); } -@ @c +@ This prints dimensions of a rule node. + +@c void print_rule_dimen(scaled d) -{ /* prints dimension in rule node */ +{ if (is_running(d)) print_char('*'); else print_scaled(d); } - @ Since boxes can be inside of boxes, |show_node_list| is inherently recursive, @^recursion@> up to a given maximum number of levels. The history of nesting is indicated @@ -930,32 +946,29 @@ be given and no sublists will be traversed. Another global variable, called |breadth_max| had better be positive, or you won't see anything. @c -int depth_threshold; /* maximum nesting depth in box displays */ -int breadth_max; /* maximum number of items shown at the same list level */ - +int depth_threshold; /* maximum nesting depth in box displays */ +int breadth_max; /* maximum number of items shown at the same list level */ -@ The recursive machinery is started by calling |show_box|. +@ The recursive machinery is started by calling |show_box|. Assign the values +|depth_threshold:=show_box_depth| and |breadth_max:=show_box_breadth| @c void show_box(halfword p) { - /* Assign the values |depth_threshold:=show_box_depth| and - |breadth_max:=show_box_breadth| */ depth_threshold = int_par(show_box_depth_code); breadth_max = int_par(show_box_breadth_code); - if (breadth_max <= 0) breadth_max = 5; - show_node_list(p); /* the show starts at |p| */ + /* the show starts at |p| */ + show_node_list(p); print_ln(); } - -@ Helper for debugging purposes +@ Helper for debugging purposes. It prints highlights of list |p| @c void short_display_n(int p, int m) -{ /* prints highlights of list |p| */ +{ int i = 0; font_in_short_display = null_font; if (p == null) @@ -999,7 +1012,6 @@ void short_display_n(int p, int m) update_terminal(); } - @ When debugging a macro package, it can be useful to see the exact control sequence names in the format file. For example, if ten new csnames appear, it's nice to know what they are, to help pinpoint where @@ -1011,21 +1023,21 @@ void print_csnames(int hstart, int hfinish) { int h; unsigned char *c, *l; - fprintf(stderr, "fmtdebug:csnames from %d to %d:", (int) hstart, - (int) hfinish); + fprintf(stderr, "fmtdebug:csnames from %d to %d:", (int) hstart, (int) hfinish); for (h = hstart; h <= hfinish; h++) { - if (cs_text(h) > 0) { /* if have anything at this position */ + if (cs_text(h) > 0) { + /* we have anything at this position */ c = str_string(cs_text(h)); l = c + str_length(cs_text(h)); while (c < l) { - fputc(*c++, stderr); /* print the characters */ + /* print the characters */ + fputc(*c++, stderr); } fprintf(stderr, "|"); } } } - @ A helper for printing file:line:error style messages. Look for a filename in |full_source_filename_stack|, and if we fail to find one fall back on the non-file:line:error style. @@ -1033,8 +1045,7 @@ one fall back on the non-file:line:error style. @c void print_file_line(void) { - int level; - level = in_open; + int level = in_open; while ((level > 0) && (full_source_filename_stack[level] == 0)) decr(level); if (level == 0) { @@ -1051,14 +1062,13 @@ void print_file_line(void) } } - @ \TeX\ is occasionally supposed to print diagnostic information that goes only into the transcript file, unless |tracing_online| is positive. Here are two routines that adjust the destination of print commands: @c void begin_diagnostic(void) -{ /* prepare to do some tracing */ +{ global_old_setting = selector; if ((int_par(tracing_online_code) <= 0) && (selector == term_and_log)) { decr(selector); @@ -1067,16 +1077,17 @@ void begin_diagnostic(void) } } -@ @c +@ Restore proper conditions after tracing. + +@c void end_diagnostic(boolean blank_line) -{ /* restore proper conditions after tracing */ +{ tprint_nl(""); if (blank_line) print_ln(); selector = global_old_setting; } - @ Of course we had better declare another global variable, if the previous routines are going to work. diff --git a/Build/source/texk/web2c/luatexdir/tex/scanning.h b/Build/source/texk/web2c/luatexdir/tex/scanning.h index 8831901c303..729fcda20ef 100644 --- a/Build/source/texk/web2c/luatexdir/tex/scanning.h +++ b/Build/source/texk/web2c/luatexdir/tex/scanning.h @@ -15,8 +15,9 @@ 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/>. */ + with LuaTeX; if not, see <http://www.gnu.org/licenses/>. +*/ #ifndef SCANNING_H # define SCANNING_H @@ -42,7 +43,6 @@ extern int cur_val_level; /* the ``level'' of this value */ extern void scan_something_simple(halfword cmd, halfword subitem); extern void scan_something_internal(int level, boolean negative); - extern void scan_limited_int(int max, const char *name); # define scan_register_num() scan_limited_int(65535,"register code") @@ -57,17 +57,15 @@ extern void scan_limited_int(int max, const char *name); extern void scan_fifteen_bit_int(void); extern void scan_fifty_one_bit_int(void); -# define octal_token (other_token+'\'') /* apostrophe, indicates an octal constant */ -# define hex_token (other_token+'"') /* double quote, indicates a hex constant */ -# define alpha_token (other_token+'`') /* reverse apostrophe, precedes alpha constants */ -# define point_token (other_token+'.') /* decimal point */ -# define continental_point_token (other_token+',') /* decimal point, Eurostyle */ -# define infinity 017777777777 /* the largest positive value that \TeX\ knows */ -# define zero_token (other_token+'0') /* zero, the smallest digit */ -# define A_token (letter_token+'A') /* the smallest special hex digit */ -# define other_A_token (other_token+'A') - /* special hex digit of type |other_char| */ - +# define octal_token (other_token+'\'') /* apostrophe, indicates an octal constant */ +# define hex_token (other_token+'"') /* double quote, indicates a hex constant */ +# define alpha_token (other_token+'`') /* reverse apostrophe, precedes alpha constants */ +# define point_token (other_token+'.') /* decimal point */ +# define continental_point_token (other_token+',') /* decimal point, Eurostyle */ +# define infinity 017777777777 /* the largest positive value that \TeX\ knows */ +# define zero_token (other_token+'0') /* zero, the smallest digit */ +# define A_token (letter_token+'A') /* the smallest special hex digit */ +# define other_A_token (other_token+'A') /* special hex digit of type |other_char| */ extern int radix; extern void scan_int(void); @@ -94,15 +92,13 @@ extern void scan_general_text(void); extern void get_x_or_protected(void); extern halfword scan_toks(boolean macrodef, boolean xpand); - extern void scan_normal_glue(void); extern void scan_mu_glue(void); -extern int add_or_sub(int x, int y, int max_answer, boolean negative); -extern int quotient(int n, int d); +/* extern int add_or_sub(int x, int y, int max_answer, boolean negative); */ +/* extern int quotient(int n, int d); */ extern int fract(int x, int n, int d, int max_answer); -extern void scan_expr(void); - +/* extern void scan_expr(void); */ #endif diff --git a/Build/source/texk/web2c/luatexdir/tex/scanning.w b/Build/source/texk/web2c/luatexdir/tex/scanning.w index 120d361922e..635ea03e2e2 100644 --- a/Build/source/texk/web2c/luatexdir/tex/scanning.w +++ b/Build/source/texk/web2c/luatexdir/tex/scanning.w @@ -35,8 +35,7 @@ #define count(A) eqtb[count_base+(A)].hh.rh #define box(A) equiv(box_base+(A)) -#define text_direction int_par(text_direction_code) -#define body_direction int_par(body_direction_code) +static void scan_expr(void); @ Let's turn now to some procedures that \TeX\ calls upon frequently to digest certain kinds of patterns in the input. Most of these are quite simple; @@ -602,7 +601,7 @@ void scan_something_internal(int level, boolean negative) /* Fetch a character code from some table */ scan_char_num(); if (m == math_code_base) { - cur_val1 = get_math_code_num(cur_val, true); + cur_val1 = get_math_code_num(cur_val); scanned_result(cur_val1, int_val_level); } else if (m == lc_code_base) { cur_val1 = get_lc_code(cur_val); @@ -621,6 +620,7 @@ void scan_something_internal(int level, boolean negative) } break; case def_del_code_cmd: + case extdef_del_code_cmd: /* bonus */ /* Fetch a character code from some table */ scan_char_num(); cur_val1 = get_del_code_num(cur_val); @@ -629,7 +629,7 @@ void scan_something_internal(int level, boolean negative) case extdef_math_code_cmd: /* Fetch an extended math code table value */ scan_char_num(); - cur_val1 = get_math_code_num(cur_val, false); + cur_val1 = get_math_code_num(cur_val); scanned_result(cur_val1, int_val_level); break; case toks_register_cmd: @@ -1102,26 +1102,73 @@ $|cur_val|+|f|/2^{16}$. At the end of the routine, this ``unpacked'' representation is put into the single word |cur_val|, which suddenly switches significance from |integer| to |scaled|. +@ +The necessary conversion factors can all be specified exactly as +fractions whose numerator and denominator add to 32768 or less. +According to the definitions here, $\rm2660\,dd\approx1000.33297\,mm$; +this agrees well with the value $\rm1000.333\,mm$ cited by Bosshard +\^{Bosshard, Hans Rudolf} +in {\sl Technische Grundlagen zur Satzherstellung\/} (Bern, 1980). +The Didot point has been newly standardized in 1978; +it's now exactly $\rm 1\,nd=0.375\,mm$. +Conversion uses the equation $0.375=21681/20320/72.27\cdot25.4$. +The new Cicero follows the new Didot point; $\rm 1\,nc=12\,nd$. +These would lead to the ratios $21681/20320$ and $65043/5080$, +respectively. +The closest approximations supported by the algorithm would be +$11183/10481$ and $1370/107$. In order to maintain the +relation $\rm 1\,nc=12\,nd$, we pick the ratio $685/642$ for +$\rm nd$, however. + @c + +static void scan_dimen_mu_error(void) { + print_err("Illegal unit of measure (mu inserted)"); + help4("The unit of measurement in math glue must be mu.", + "To recover gracefully from this error, it's best to", + "delete the erroneous units; e.g., type `2' to delete", + "two letters. (See Chapter 27 of The TeXbook.)"); + error(); +} + +static void scan_dimen_unknown_unit_error(void) { + print_err("Illegal unit of measure (pt inserted)"); + help6("Dimensions can be in units of em, ex, in, pt, pc,", + "cm, mm, dd, cc, nd, nc, bp, or sp; but yours is a new one!", + "I'll assume that you meant to say pt, for printer's points.", + "To recover gracefully from this error, it's best to", + "delete the erroneous units; e.g., type `2' to delete", + "two letters. (See Chapter 27 of The TeXbook.)"); + error(); +} + +static void scan_dimen_out_of_range_error(void) { + print_err("Dimension too large"); + help2("I can't work with sizes bigger than about 19 feet.", + "Continue and I'll use the largest value I can."); + error(); +} + +#define set_conversion(A,B) do { num=(A); denom=(B); } while(0) + +/* + This function sets |cur_val| to a dimension. It could be optimized a bit + more (but not now, something for luatex > 1). +*/ + void scan_dimen(boolean mu, boolean inf, boolean shortcut) -/* sets |cur_val| to a dimension */ { - boolean negative; /* should the answer be negated? */ - int f; /* numerator of a fraction whose denominator is $2^{16}$ */ - /* Local variables for dimension calculations */ - int num, denom; /* conversion ratio for the scanned units */ - int k, kk; /* number of digits in a decimal fraction */ - halfword p, q; /* top of decimal digit stack */ - scaled v; /* an internal dimension */ - int save_cur_val; /* temporary storage of |cur_val| */ - - f = 0; + boolean negative; /* should the answer be negated? */ + int f = 0; /* numerator of a fraction whose denominator is $2^{16}$ */ + int num, denom; /* conversion ratio for the scanned units */ + halfword q; /* top of decimal digit stack */ + scaled v; /* an internal dimension */ + int save_cur_val; /* temporary storage of |cur_val| */ arith_error = false; cur_order = normal; negative = false; if (!shortcut) { /* Get the next non-blank non-sign... */ - negative = false; do { /* Get the next non-blank non-call token */ do { @@ -1132,23 +1179,22 @@ void scan_dimen(boolean mu, boolean inf, boolean shortcut) cur_tok = other_token + '+'; } } while (cur_tok == other_token + '+'); - if ((cur_cmd >= min_internal_cmd) && (cur_cmd <= max_internal_cmd)) { - /* Fetch an internal dimension and |goto attach_sign|, - or fetch an internal integer */ + /* Fetch an internal dimension and |goto attach_sign|, or fetch an internal integer */ if (mu) { scan_something_internal(mu_val_level, false); coerce_glue(); - if (cur_val_level == mu_val_level) + if (cur_val_level == mu_val_level) { goto ATTACH_SIGN; - if (cur_val_level != int_val_level) + } else if (cur_val_level != int_val_level) { mu_error(); + } } else { scan_something_internal(dimen_val_level, false); - if (cur_val_level == dimen_val_level) + if (cur_val_level == dimen_val_level) { goto ATTACH_SIGN; + } } - } else { back_input(); if (cur_tok == continental_point_token) { @@ -1160,24 +1206,26 @@ void scan_dimen(boolean mu, boolean inf, boolean shortcut) radix = 10; cur_val = 0; } - if (cur_tok == continental_point_token) + if (cur_tok == continental_point_token) { cur_tok = point_token; + } if ((radix == 10) && (cur_tok == point_token)) { - /* Scan decimal fraction */ - /* When the following code is executed, we have |cur_tok=point_token|, but this - token has been backed up using |back_input|; we must first discard it. - - It turns out that a decimal point all by itself is equivalent to `\.{0.0}'. - Let's hope people don't use that fact. */ - - k = 0; - p = null; - get_token(); /* |point_token| is being re-scanned */ + /* + Scan decimal fraction. When the following code is executed, we have + |cur_tok=point_token|, but this token has been backed up using |back_input|; + we must first discard it. It turns out that a decimal point all by itself + is equivalent to `\.{0.0}'. Let's hope people don't use that fact. + */ + int k = 0; + halfword p = null; + int kk; + get_token(); /* |point_token| is being re-scanned */ while (1) { get_x_token(); if ((cur_tok > zero_token + 9) || (cur_tok < zero_token)) break; - if (k < 17) { /* digits for |k>=17| cannot affect the result */ + if (k < 17) { + /* digits for |k>=17| cannot affect the result */ q = get_avail(); set_token_link(q, p); set_token_info(q, cur_tok - zero_token); @@ -1192,31 +1240,33 @@ void scan_dimen(boolean mu, boolean inf, boolean shortcut) free_avail(q); } f = round_decimals(k); - if (cur_cmd != spacer_cmd) + if (cur_cmd != spacer_cmd) { back_input(); + } } } } - if (cur_val < 0) { /* in this case |f=0| */ + if (cur_val < 0) { + /* in this case |f=0| */ negative = !negative; negate(cur_val); } - /* Scan units and set |cur_val| to $x\cdot(|cur_val|+f/2^{16})$, where there - are |x| sp per unit; |goto attach_sign| if the units are internal */ - /* Now comes the harder part: At this point in the program, |cur_val| is a - nonnegative integer and $f/2^{16}$ is a nonnegative fraction less than 1; - we want to multiply the sum of these two quantities by the appropriate - factor, based on the specified units, in order to produce a |scaled| - result, and we want to do the calculation with fixed point arithmetic that - does not overflow. - */ - + /* + Scan units and set |cur_val| to $x\cdot(|cur_val|+f/2^{16})$, where there + are |x| sp per unit; |goto attach_sign| if the units are internal. Now comes + the harder part: At this point in the program, |cur_val| is a nonnegative + integer and $f/2^{16}$ is a nonnegative fraction less than 1; we want to + multiply the sum of these two quantities by the appropriate factor, based + on the specified units, in order to produce a |scaled| result, and we want + to do the calculation with fixed point arithmetic that does not overflow. + */ if (inf) { - /* Scan for (f)\.{fil} units; |goto attach_fraction| if found */ - /* In traditional TeX, a specification like `\.{filllll}' or `\.{fill L L - L}' will lead to two error messages (one for each additional keyword - \.{"l"}). - Not so for luatex, it just parses the construct in reverse. */ + /* + Scan for (f)\.{fil} units; |goto attach_fraction| if found. In traditional + \TeX, a specification like `\.{filllll}' or `\.{fill L L L}' will lead to + two error messages (one for each additional keyword \.{"l"}). Not so for + \LuaTeX, it just parses the construct in reverse. + */ if (scan_keyword("filll")) { cur_order = filll; goto ATTACH_FRACTION; @@ -1230,12 +1280,13 @@ void scan_dimen(boolean mu, boolean inf, boolean shortcut) cur_order = sfi; goto ATTACH_FRACTION; } - } - /* Scan for (u)units that are internal dimensions; - |goto attach_sign| with |cur_val| set if found */ + /* + Scan for (u)units that are internal dimensions; |goto attach_sign| with + |cur_val| set if found + */ save_cur_val = cur_val; - /* Get the next non-blank non-call... */ + /* Get the next non-blank non-call... a pitty if just backed up the input */ do { get_x_token(); } while (cur_cmd == spacer_cmd); @@ -1243,146 +1294,124 @@ void scan_dimen(boolean mu, boolean inf, boolean shortcut) if ((cur_cmd < min_internal_cmd) || (cur_cmd > max_internal_cmd)) { back_input(); } else { + /* math_given_cmd xmath_given_cmd last_item_cmd */ if (mu) { scan_something_internal(mu_val_level, false); coerce_glue(); - if (cur_val_level != mu_val_level) + if (cur_val_level != mu_val_level) { mu_error(); + } } else { scan_something_internal(dimen_val_level, false); } v = cur_val; goto FOUND; } - if (mu) - goto NOT_FOUND; - if (scan_keyword("em")) { - v = (quad(get_cur_font())); + /* bah ... true forces to split the unit scanner */ + if (mu) { + /* Scan for (m)\.{mu} units and |goto attach_fraction| */ + if (! scan_keyword("mu")) { + scan_dimen_mu_error(); + } + goto ATTACH_FRACTION; + } else if (scan_keyword("em")) { + v = quad(get_cur_font()); } else if (scan_keyword("ex")) { - v = (x_height(get_cur_font())); + v = x_height(get_cur_font()); } else if (scan_keyword("px")) { v = dimen_par(px_dimen_code); } else { - goto NOT_FOUND; + goto PICKUP_UNIT; } - /* Scan an optional space */ + /* Scan an optional space (after em, ex or px) */ get_x_token(); - if (cur_cmd != spacer_cmd) + if (cur_cmd != spacer_cmd) { back_input(); - + } FOUND: cur_val = nx_plus_y(save_cur_val, v, xn_over_d(v, f, 0200000)); goto ATTACH_SIGN; - NOT_FOUND: - - if (mu) { - /* Scan for (m)\.{mu} units and |goto attach_fraction| */ - if (scan_keyword("mu")) { - goto ATTACH_FRACTION; - } else { - print_err("Illegal unit of measure (mu inserted)"); - help4("The unit of measurement in math glue must be mu.", - "To recover gracefully from this error, it's best to", - "delete the erroneous units; e.g., type `2' to delete", - "two letters. (See Chapter 27 of The TeXbook.)"); - error(); - goto ATTACH_FRACTION; - } - } - if (scan_keyword("true")) { - /* Adjust (f)for the magnification ratio */ - prepare_mag(); - if (int_par(mag_code) != 1000) { - cur_val = xn_over_d(cur_val, 1000, int_par(mag_code)); - f = (1000 * f + 0200000 * tex_remainder) / int_par(mag_code); - cur_val = cur_val + (f / 0200000); - f = f % 0200000; - } - } - if (scan_keyword("pt")) + /* + Scan for (a)all other units and adjust |cur_val| and |f| accordingly; + |goto done| in the case of scaled points + */ + PICKUP_UNIT: + if (scan_keyword("pt")) { goto ATTACH_FRACTION; /* the easy case */ - /* Scan for (a)all other units and adjust |cur_val| and |f| accordingly; - |goto done| in the case of scaled points */ - - /* The necessary conversion factors can all be specified exactly as - fractions whose numerator and denominator add to 32768 or less. - According to the definitions here, $\rm2660\,dd\approx1000.33297\,mm$; - this agrees well with the value $\rm1000.333\,mm$ cited by Bosshard - \^{Bosshard, Hans Rudolf} - in {\sl Technische Grundlagen zur Satzherstellung\/} (Bern, 1980). - The Didot point has been newly standardized in 1978; - it's now exactly $\rm 1\,nd=0.375\,mm$. - Conversion uses the equation $0.375=21681/20320/72.27\cdot25.4$. - The new Cicero follows the new Didot point; $\rm 1\,nc=12\,nd$. - These would lead to the ratios $21681/20320$ and $65043/5080$, - respectively. - The closest approximations supported by the algorithm would be - $11183/10481$ and $1370/107$. In order to maintain the - relation $\rm 1\,nc=12\,nd$, we pick the ratio $685/642$ for - $\rm nd$, however. - */ - -#define set_conversion(A,B) do { num=(A); denom=(B); } while(0) - - if (scan_keyword("mm")) { + } else if (scan_keyword("mm")) { set_conversion(7227, 2540); + goto SCALE_VALUE; } else if (scan_keyword("cm")) { set_conversion(7227, 254); + goto SCALE_VALUE; } else if (scan_keyword("sp")) { goto DONE; } else if (scan_keyword("bp")) { set_conversion(7227, 7200); + goto SCALE_VALUE; } else if (scan_keyword("in")) { set_conversion(7227, 100); + goto SCALE_VALUE; } else if (scan_keyword("dd")) { set_conversion(1238, 1157); + goto SCALE_VALUE; } else if (scan_keyword("cc")) { set_conversion(14856, 1157); + goto SCALE_VALUE; + } else if (scan_keyword("pc")) { + set_conversion(12, 1); + goto SCALE_VALUE; } else if (scan_keyword("nd")) { set_conversion(685, 642); + goto SCALE_VALUE; } else if (scan_keyword("nc")) { set_conversion(1370, 107); - } else if (scan_keyword("pc")) { - set_conversion(12, 1); + goto SCALE_VALUE; + } else if (scan_keyword("true")) { + /* Adjust (f)for the magnification ratio */ + if (output_mode_used == OMODE_DVI) { + prepare_mag(); + if (int_par(mag_code) != 1000) { + cur_val = xn_over_d(cur_val, 1000, int_par(mag_code)); + f = (1000 * f + 0200000 * tex_remainder) / int_par(mag_code); + cur_val = cur_val + (f / 0200000); + f = f % 0200000; + } + } + goto PICKUP_UNIT; } else { /* Complain about unknown unit and |goto done2| */ - print_err("Illegal unit of measure (pt inserted)"); - help6("Dimensions can be in units of em, ex, in, pt, pc,", - "cm, mm, dd, cc, nd, nc, bp, or sp; but yours is a new one!", - "I'll assume that you meant to say pt, for printer's points.", - "To recover gracefully from this error, it's best to", - "delete the erroneous units; e.g., type `2' to delete", - "two letters. (See Chapter 27 of The TeXbook.)"); - error(); - goto DONE2; + scan_dimen_unknown_unit_error(); + goto BAD_NEWS; } + SCALE_VALUE: cur_val = xn_over_d(cur_val, num, denom); f = (num * f + 0200000 * tex_remainder) / denom; cur_val = cur_val + (f / 0200000); f = f % 0200000; - DONE2: + BAD_NEWS: ATTACH_FRACTION: - if (cur_val >= 040000) + if (cur_val >= 040000) { arith_error = true; - else + } else { cur_val = cur_val * unity + f; + } DONE: - /* Scan an optional space */ + /* Scan an optional space */ /* happens too often */ get_x_token(); - if (cur_cmd != spacer_cmd) + if (cur_cmd != spacer_cmd) { back_input(); + } ATTACH_SIGN: if (arith_error || (abs(cur_val) >= 010000000000)) { /* Report that this dimension is out of range */ - print_err("Dimension too large"); - help2("I can't work with sizes bigger than about 19 feet.", - "Continue and I'll use the largest value I can."); - error(); + scan_dimen_out_of_range_error(); cur_val = max_dimen; arith_error = false; } - if (negative) + if (negative) { negate(cur_val); + } } @ The final member of \TeX's value-scanning trio is |scan_glue|, which @@ -1991,7 +2020,7 @@ halfword scan_toks(boolean macro_def, boolean xpand) /* Here we insert an entire token list created by |the_toks| without expanding it further. */ while (1) { - get_next(); /* get_token_lua(); */ + get_next(); if (cur_cmd >= call_cmd) { if (token_info(token_link(cur_chr)) == protected_token) { cur_cmd = relax_cmd; @@ -2096,25 +2125,24 @@ typedef enum { @ clear a number or dimension and set |arith_error| @c -#define num_error(A) do { \ - arith_error=true; \ - A=0; \ - } while (0) - +#define num_error(A) do { \ + arith_error=true; \ + A=0; \ +} while (0) @ clear a glue spec and set |arith_error| @c -#define glue_error(A) do { \ - arith_error=true; \ - delete_glue_ref(A); \ - A=new_spec(zero_glue); \ - } while (0) +#define glue_error(A) do { \ + arith_error=true; \ + delete_glue_ref(A); \ + A=new_spec(zero_glue); \ +} while (0) -#define normalize_glue(A) do { \ - if (stretch(A)==0) stretch_order(A)=normal; \ - if (shrink(A)==0) shrink_order(A)=normal; \ - } while (0) +#define normalize_glue(A) do { \ + if (stretch(A)==0) stretch_order(A)=normal; \ + if (shrink(A)==0) shrink_order(A)=normal; \ +} while (0) @ Parenthesized subexpressions can be inside expressions, and this nesting has a stack. Seven local variables represent the top of the @@ -2141,7 +2169,7 @@ numerator for a combined multiplication and division, if any. |max_answer|. @c -int add_or_sub(int x, int y, int max_answer, boolean negative) +inline static int add_or_sub(int x, int y, int max_answer, boolean negative) { int a; /* the answer */ if (negative) @@ -2166,7 +2194,7 @@ int add_or_sub(int x, int y, int max_answer, boolean negative) $q=\lfloor n/d+{1\over2}\rfloor$, when $n$ and $d$ are positive. @c -int quotient(int n, int d) +inline static int quotient(int n, int d) { boolean negative; /* should the answer be negated? */ int a; /* the answer */ @@ -2252,8 +2280,6 @@ int fract(int x, int n, int d, int max_answer) x = n; n = t; } - - /* now |0<n<=x<d| */ /* Compute $f=\lfloor xn/d+{1\over2}\rfloor$; */ /* The loop here preserves the following invariant relations @@ -2307,7 +2333,7 @@ int fract(int x, int n, int d, int max_answer) } @ @c -void scan_expr(void) +static void scan_expr(void) { /* scans and evaluates an expression */ boolean a, b; /* saved values of |arith_error| */ int l; /* type of expression */ @@ -2402,8 +2428,7 @@ void scan_expr(void) if (abs(f) > max_dimen) num_error(f); } else { - if ((abs(width(f)) > max_dimen) || - (abs(stretch(f)) > max_dimen) || (abs(shrink(f)) > max_dimen)) + if ((abs(width(f)) > max_dimen) || (abs(stretch(f)) > max_dimen) || (abs(shrink(f)) > max_dimen)) glue_error(f); } @@ -2464,7 +2489,6 @@ void scan_expr(void) expr_s(shrink(t)); } break; - } /* there are no other cases */ if (o > expr_sub) { s = o; @@ -2486,8 +2510,7 @@ void scan_expr(void) width(e) = expr_a(width(e), width(t)); if (stretch_order(e) == stretch_order(t)) { stretch(e) = expr_a(stretch(e), stretch(t)); - } else if ((stretch_order(e) < stretch_order(t)) - && (stretch(t) != 0)) { + } else if ((stretch_order(e) < stretch_order(t)) && (stretch(t) != 0)) { stretch(e) = stretch(t); stretch_order(e) = stretch_order(t); } diff --git a/Build/source/texk/web2c/luatexdir/tex/texfileio.w b/Build/source/texk/web2c/luatexdir/tex/texfileio.w index 76ae365f735..d274f6d3439 100644 --- a/Build/source/texk/web2c/luatexdir/tex/texfileio.w +++ b/Build/source/texk/web2c/luatexdir/tex/texfileio.w @@ -138,7 +138,7 @@ char *luatex_find_file(const char *s, int callback_index) char *ftemp = NULL; int callback_id = callback_defined(callback_index); if (callback_id > 0) { - (void) run_callback(callback_id, "S->S", s, &ftemp); + (void) run_callback(callback_id, "S->R", s, &ftemp); } else { /* use kpathsea here */ @@ -839,7 +839,7 @@ void open_log_file(void) log_opened_global = true; if (callback_defined(start_run_callback) == 0) { /* Print the banner line, including current date and time */ - log_banner(luatex_version_string, luatex_svn); + log_banner(luatex_version_string); input_stack[input_ptr] = cur_input; /* make sure bottom level is in memory */ tprint_nl("**"); diff --git a/Build/source/texk/web2c/luatexdir/tex/texmath.w b/Build/source/texk/web2c/luatexdir/tex/texmath.w index 77c6161f475..676f4262b21 100644 --- a/Build/source/texk/web2c/luatexdir/tex/texmath.w +++ b/Build/source/texk/web2c/luatexdir/tex/texmath.w @@ -33,7 +33,6 @@ #define incompleat_noad cur_list.incompleat_noad_field #define cur_fam int_par(cur_fam_code) -#define text_direction int_par(text_direction_code) /* @@ -194,15 +193,17 @@ static sa_tree math_fam_head = NULL; int fam_fnt(int fam_id, int size_id) { int n = fam_id + (256 * size_id); - return (int) get_sa_item(math_fam_head, n); + return (int) get_sa_item(math_fam_head, n).int_value; } void def_fam_fnt(int fam_id, int size_id, int f, int lvl) { int n = fam_id + (256 * size_id); - set_sa_item(math_fam_head, n, (sa_tree_item) f, lvl); + sa_tree_item sa_value = { 0 }; + sa_value.int_value = f; + set_sa_item(math_fam_head, n, sa_value, lvl); fixup_math_parameters(fam_id, size_id, f, lvl); - if (int_par(tracing_assigns_code) > 0) { + if (int_par(tracing_assigns_code) > 1) { begin_diagnostic(); tprint("{assigning"); print_char(' '); @@ -228,7 +229,7 @@ static void unsave_math_fam_data(int gl) if (st.level > 0) { rawset_sa_item(math_fam_head, st.code, st.value); /* now do a trace message, if requested */ - if (int_par(tracing_restores_code) > 0) { + if (int_par(tracing_restores_code) > 1) { int size_id = st.code / 256; int fam_id = st.code % 256; begin_diagnostic(); @@ -258,8 +259,10 @@ static sa_tree math_param_head = NULL; void def_math_param(int param_id, int style_id, scaled value, int lvl) { int n = param_id + (256 * style_id); - set_sa_item(math_param_head, n, (sa_tree_item) value, lvl); - if (int_par(tracing_assigns_code) > 0) { + sa_tree_item sa_value = { 0 }; + sa_value.int_value = (int) value; + set_sa_item(math_param_head, n, sa_value, lvl); + if (int_par(tracing_assigns_code) > 1) { begin_diagnostic(); tprint("{assigning"); print_char(' '); @@ -275,7 +278,7 @@ void def_math_param(int param_id, int style_id, scaled value, int lvl) scaled get_math_param(int param_id, int style_id) { int n = param_id + (256 * style_id); - return (scaled) get_sa_item(math_param_head, n); + return (scaled) get_sa_item(math_param_head, n).int_value; } @ @c @@ -291,7 +294,7 @@ static void unsave_math_param_data(int gl) if (st.level > 0) { rawset_sa_item(math_param_head, st.code, st.value); /* now do a trace message, if requested */ - if (int_par(tracing_restores_code) > 0) { + if (int_par(tracing_restores_code) > 1) { int param_id = st.code % 256; int style_id = st.code / 256; begin_diagnostic(); @@ -322,11 +325,16 @@ void unsave_math_data(int gl) @c void dump_math_data(void) { - if (math_fam_head == NULL) - math_fam_head = new_sa_tree(MATHFONTSTACK, MATHFONTDEFAULT); + sa_tree_item sa_value = { 0 }; + if (math_fam_head == NULL) { + sa_value.int_value = MATHFONTDEFAULT; + math_fam_head = new_sa_tree(MATHFONTSTACK, 1, sa_value); + } dump_sa_tree(math_fam_head); - if (math_param_head == NULL) - math_param_head = new_sa_tree(MATHPARAMSTACK, MATHPARAMDEFAULT); + if (math_param_head == NULL) { + sa_value.int_value = MATHPARAMDEFAULT; + math_param_head = new_sa_tree(MATHPARAMSTACK, 1, sa_value); + } dump_sa_tree(math_param_head); } @@ -339,10 +347,14 @@ void undump_math_data(void) @ @c void initialize_math(void) { - if (math_fam_head == NULL) - math_fam_head = new_sa_tree(MATHFONTSTACK, MATHFONTDEFAULT); + sa_tree_item sa_value = { 0 }; + if (math_fam_head == NULL) { + sa_value.int_value = MATHFONTDEFAULT; + math_fam_head = new_sa_tree(MATHFONTSTACK, 1, sa_value); + } if (math_param_head == NULL) { - math_param_head = new_sa_tree(MATHPARAMSTACK, MATHPARAMDEFAULT); + sa_value.int_value = MATHPARAMDEFAULT; + math_param_head = new_sa_tree(MATHPARAMSTACK, 1, sa_value); initialize_math_spacing(); } return; @@ -1144,7 +1156,6 @@ static delcodeval do_scan_extdef_del_code(int extcode, boolean doclass) /* something's gone wrong */ confusion("unknown_extcode"); } - d.origin_value = extcode; d.class_value = mcls; d.small_family_value = msfam; d.small_character_value = mschr; @@ -1162,7 +1173,7 @@ void scan_extdef_del_code(int level, int extcode) p = cur_val; scan_optional_equals(); d = do_scan_extdef_del_code(extcode, false); - set_del_code(p, extcode, d.small_family_value, d.small_character_value, + set_del_code(p, d.small_family_value, d.small_character_value, d.large_family_value, d.large_character_value, (quarterword) (level)); } @@ -1229,7 +1240,6 @@ mathcodeval scan_mathchar(int extcode) } d.class_value = mcls; d.family_value = mfam; - d.origin_value = extcode; d.character_value = mchr; return d; } @@ -1243,7 +1253,7 @@ void scan_extdef_math_code(int level, int extcode) p = cur_val; scan_optional_equals(); d = scan_mathchar(extcode); - set_math_code(p, extcode, d.class_value, + set_math_code(p, d.class_value, d.family_value, d.character_value, (quarterword) (level)); } @@ -1254,34 +1264,12 @@ mathcodeval scan_delimiter_as_mathchar(int extcode) delcodeval dval; mathcodeval mval; dval = do_scan_extdef_del_code(extcode, true); - mval.origin_value = 0; mval.class_value = dval.class_value; mval.family_value = dval.small_family_value; mval.character_value = dval.small_character_value; return mval; } -@ this has to match the inverse routine in the pascal code - where the \.{\\Umathchardef} is executed - -@c -mathcodeval mathchar_from_integer(int value, int extcode) -{ - mathcodeval mval; - mval.origin_value = extcode; - if (extcode == tex_mathcode) { - mval.class_value = (value / 0x1000); - mval.family_value = ((value % 0x1000) / 0x100); - mval.character_value = (value % 0x100); - } else { /* some xetexended xetex thing */ - int mfam = (value / 0x200000) & 0x7FF; - mval.class_value = mfam % 0x08; - mval.family_value = mfam / 0x08; - mval.character_value = value & 0x1FFFFF; - } - return mval; -} - @ Recall that the |nucleus|, |subscr|, and |supscr| fields in a noad are broken down into subfields called |type| and either |math_list| or |(math_fam,math_character)|. The job of |scan_math| is to figure out @@ -1306,7 +1294,7 @@ int scan_math_style(pointer p, int mstyle) int scan_math(pointer p, int mstyle) { /* label restart,reswitch,exit; */ - mathcodeval mval = { 0, 0, 0, 0 }; + mathcodeval mval = { 0, 0, 0 }; assert(p != null); RESTART: get_next_nb_nr(); @@ -1404,15 +1392,15 @@ void set_math_char(mathcodeval mval) subtype(p) = ord_noad_type; } else { switch (mval.class_value) { - /* *INDENT-OFF* */ - 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) = punct_noad_type; break; - /* *INDENT-ON* */ + /* *INDENT-OFF* */ + 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) = punct_noad_type; break; + /* *INDENT-ON* */ } } vlink(tail) = p; @@ -1484,7 +1472,7 @@ delimiter is to be placed; the second tells if this delimiter follows @c static void scan_delimiter(pointer p, int r) { - delcodeval dval = { 0, 0, 0, 0, 0, 0 }; + delcodeval dval = { 0, 0, 0, 0, 0 }; if (r == tex_mathcode) { /* \.{\\radical} */ dval = do_scan_extdef_del_code(tex_mathcode, true); } else if (r == umath_mathcode) { /* \.{\\Uradical} */ @@ -1606,9 +1594,9 @@ void math_radical(void) void math_ac(void) { halfword q; - mathcodeval t = { 0, 0, 0, 0 }; - mathcodeval b = { 0, 0, 0, 0 }; - mathcodeval o = { 0, 0, 0, 0 }; + mathcodeval t = { 0, 0, 0 }; + mathcodeval b = { 0, 0, 0 }; + mathcodeval o = { 0, 0, 0 }; if (cur_cmd == accent_cmd) { const char *hlp[] = { "I'm changing \\accent to \\mathaccent here; wish me luck.", @@ -2430,7 +2418,7 @@ void after_math(void) } else { check_display_math_end(); } - run_mlist_to_hlist(p, text_style, false); + run_mlist_to_hlist(p, false, text_style); a = hpack(vlink(temp_head), 0, additional, -1); build_attribute_list(a); unsave_math(); @@ -2462,7 +2450,7 @@ void after_math(void) if (dir_math_save) { tail_append(new_dir(math_direction)); } - run_mlist_to_hlist(p, text_style, (mode > 0)); + run_mlist_to_hlist(p, (mode > 0), text_style); vlink(tail) = vlink(temp_head); while (vlink(tail) != null) tail = vlink(tail); @@ -2487,7 +2475,7 @@ void after_math(void) check_display_math_end(); } } - run_mlist_to_hlist(p, display_style, false); + run_mlist_to_hlist(p, false, display_style); finish_displayed_math(l, a, vlink(temp_head)); } } diff --git a/Build/source/texk/web2c/luatexdir/tex/texnodes.h b/Build/source/texk/web2c/luatexdir/tex/texnodes.h index ae6a38929c9..618902b58fd 100644 --- a/Build/source/texk/web2c/luatexdir/tex/texnodes.h +++ b/Build/source/texk/web2c/luatexdir/tex/texnodes.h @@ -222,6 +222,7 @@ typedef enum { box_rule, image_rule, empty_rule, + user_rule, } rule_subtypes; # define rule_node_size 8 @@ -301,6 +302,10 @@ typedef enum { boundary_node, disc_node, whatsit_node, +#define last_preceding_break_node whatsit_node + local_par_node, + dir_node, +#define last_non_discardable_node dir_node math_node, glue_node, kern_node, @@ -340,11 +345,32 @@ typedef enum { delta_node, passive_node, shape_node, - dir_node, - local_par_node, } node_types; -# define MAX_NODE_TYPE 60 +# define MAX_NODE_TYPE shape_node /* 60 */ + +/* + TH: these two defines still need checking. The node ordering in luatex is not + quite the same as in tex82, HH: but it's probably ok +*/ + +/* + + # define precedes_break(a) \ + # (type(a)<math_node && \ + # (type(a)!=whatsit_node || (subtype(a)!=dir_node && subtype(a)!=local_par_node))) + +*/ + +/* + # define precedes_break(a) (type(a)<math_node) + # define non_discardable(a) (type(a)<math_node || type(a) == dir_node || type(a) == local_par_node) +*/ + +# define precedes_break(a) (type(a)<=last_preceding_break_node) +# define non_discardable(a) (type(a)<=last_non_discardable_node) + +# define known_node_type(i) ( i >= 0 && i <= MAX_NODE_TYPE) # define last_known_node temp_node /* used by \lastnodetype */ @@ -527,6 +553,8 @@ typedef enum { pdf_restore_node, } whatsit_types; +# define first_common_whatsit 0 +# define last_common_whatsit user_defined_node # define backend_first_dvi_whatsit 15 # define backend_last_dvi_whatsit 15 # define backend_first_pdf_whatsit 16 @@ -534,7 +562,13 @@ typedef enum { # define MAX_WHATSIT_TYPE 32 -# define get_node_size(i,j) (i!=whatsit_node ? node_data[i].size : whatsit_node_data[j].size) +# define known_whatsit_type(i) ( \ + (i >= first_common_whatsit && i <= last_common_whatsit) || \ + (i >= backend_first_dvi_whatsit && i <= backend_last_dvi_whatsit) || \ + (i >= backend_first_pdf_whatsit && i <= backend_last_pdf_whatsit) \ +) + +# define get_node_size(i,j) (i!=whatsit_node ? node_data[i].size : whatsit_node_data[j].size) # define get_node_name(i,j) (i!=whatsit_node ? node_data[i].name : whatsit_node_data[j].name) # define get_etex_code(i) (node_data[i].etex) @@ -781,26 +815,6 @@ extern void print_short_node_contents(halfword n); extern void show_node_list(int i); extern pointer actual_box_width(pointer r, scaled base_width); -/* - TH: these two defines still need checking. The node ordering in luatex is not - quite the same as in tex82 -*/ - -/* - -# define precedes_break(a) \ -# (type((a))<math_node && (type(a)!=whatsit_node || (subtype(a)!=dir_node && subtype(a)!=local_par_node))) - -*/ - -/* - so what comes before math (as we have put dir_node and local_par_node to the end) -*/ - -# define precedes_break(a) (type((a))<math_node) - -# define non_discardable(a) (type((a))<math_node) - /* from luanode.c */ typedef struct _node_info { @@ -840,7 +854,6 @@ extern halfword do_copy_node_list(halfword, halfword); extern halfword copy_node_list(halfword); extern halfword copy_node(const halfword); extern void check_node(halfword); -extern void check_node_mem(void); extern void fix_node_list(halfword); extern int fix_node_lists; extern char *sprint_node_mem_usage(void); @@ -852,8 +865,8 @@ extern void flush_node_wrapup_dvi(halfword); extern void flush_node_wrapup_pdf(halfword); extern void copy_node_wrapup_dvi(halfword, halfword); /* original target */ extern void copy_node_wrapup_pdf(halfword, halfword); /* original target */ -extern void check_node_wrapup_dvi(halfword); -extern void check_node_wrapup_pdf(halfword); +extern void check_node_wrapup_dvi(halfword); /* DEBUG_NODES mode */ +extern void check_node_wrapup_pdf(halfword); /* DEBUG_NODES mode */ extern void show_node_wrapup_dvi(halfword); extern void show_node_wrapup_pdf(halfword); @@ -926,7 +939,6 @@ extern int lua_properties_use_metatable ; #define local_broken_penalty int_par(local_broken_penalty_code) #define local_left_box equiv(local_left_box_base) #define local_right_box equiv(local_right_box_base) -#define par_direction int_par(par_direction_code) extern halfword make_local_par_node(void); diff --git a/Build/source/texk/web2c/luatexdir/tex/texnodes.w b/Build/source/texk/web2c/luatexdir/tex/texnodes.w index 5dac909c7b9..931b43b8d10 100644 --- a/Build/source/texk/web2c/luatexdir/tex/texnodes.w +++ b/Build/source/texk/web2c/luatexdir/tex/texnodes.w @@ -17,21 +17,22 @@ % You should have received a copy of the GNU General Public License along % with LuaTeX; if not, see <http://www.gnu.org/licenses/>. -% hh: Here the backend nodes are still interwoven .. when I'm in the mood... - @ @c - #include "ptexlib.h" #include "lua/luatex-api.h" -@ @c -#undef name +/* we can consider less mode sizes: 2 4 6 8 */ -#define noDEBUG -#define DEBUG_OUT stdout +@ +This module started out using NDEBUG to trigger checking invalid node usage, +something that is needed because users can mess up nodes in Lua. At some point +that code was always enabled so it is now always on but still can be recognized +as additional code. And as the performance hit is close to zero so disabling +makes no sense, not even to make it configureable. There is a little more memory +used but that is neglectable compared to other memory usage. -#define adjust_pre subtype +@c #define attribute(A) eqtb[attribute_base+(A)].cint #define uc_hyph int_par(uc_hyph_code) @@ -39,14 +40,14 @@ #define left_hyphen_min int_par(left_hyphen_min_code) #define right_hyphen_min int_par(right_hyphen_min_code) -#define text_direction int_par(text_direction_code) +#define MAX_CHAIN_SIZE 13 /* why not a bit larger */ -#define MAX_CHAIN_SIZE 13 +#define CHECK_NODE_USAGE 1 /* this triggers checking */ memory_word *volatile varmem = NULL; -#ifndef NDEBUG -char *varmem_sizes = NULL; +#ifdef CHECK_NODE_USAGE + char *varmem_sizes = NULL; #endif halfword var_mem_max = 0; @@ -56,13 +57,9 @@ halfword free_chain[MAX_CHAIN_SIZE] = { null }; static int my_prealloc = 0; -int fix_node_lists = 1; - -int free_error_seen = 0; -int copy_error_seen = 0; +int fix_node_lists = 1; /* used in font and lang */ halfword slow_get_node(int s); /* defined below */ -int copy_error(halfword p); /* define below */ #define fake_node 100 #define fake_node_size 2 @@ -286,7 +283,7 @@ const char *node_subtypes_kern[] = { "fontkern", "userkern", "accentkern", NULL }; const char *node_subtypes_rule[] = { - "normal", "box", "image", "empty", NULL + "normal", "box", "image", "empty", "user", NULL }; const char *node_subtypes_glyph[] = { "character", "glyph", "ligature", "ghost", "left", "right", NULL @@ -328,6 +325,8 @@ node_info node_data[] = { /* the last entry in a row is the etex number */ { boundary_node, boundary_size, node_fields_boundary, "boundary", -1 }, { disc_node, disc_node_size, node_fields_disc, "disc", 8 }, { whatsit_node, -1, NULL, "whatsit", 9 }, + { local_par_node, local_par_size, node_fields_local_par, "local_par", -1 }, + { dir_node, dir_node_size, node_fields_dir, "dir", -1 }, { math_node, math_node_size, node_fields_math, "math", 10 }, { glue_node, glue_node_size, node_fields_glue, "glue", 11 }, { kern_node, kern_node_size, node_fields_kern, "kern", 12 }, @@ -367,8 +366,6 @@ node_info node_data[] = { /* the last entry in a row is the etex number */ { delta_node, delta_node_size, NULL, "delta", -1 }, { passive_node, passive_node_size, NULL, "passive", -1 }, { shape_node, variable_node_size, NULL, "shape", -1 }, - { dir_node, dir_node_size, node_fields_dir, "dir", -1 }, - { local_par_node, local_par_size, node_fields_local_par, "local_par", -1 }, { -1, -1, NULL, NULL, -1 }, }; @@ -423,8 +420,7 @@ node_info whatsit_node_data[] = { #define last_whatsit_node pdf_restore_node -/* - +@ When we copy a node list, there are several possibilities: we do the same as a new node, we copy the entry to the table in properties (a reference), we do a deep copy of a table in the properties, we create a new table and give it the original one as a metatable. @@ -446,9 +442,10 @@ only small lists. So, in the end this is what we ended up with. For the record, I also experimented with the following: -- copy attributes to the properties so that we hav efast access at the lua end: in the end +- copy attributes to the properties so that we have fast access at the lua end: in the end the overhead is not compensated by speed and convenience, in fact, attributes are not that slow when it comes to accessing them + - a bitset in the node but again the gain compared to attributes is neglectable and it also demands a pretty string agreement over what bit represents what, and this is unlikely to succeed in the tex community (I could use it for font handling, which is cross package, @@ -462,15 +459,16 @@ alternative is to store a reference in the node itself but that is complicated b that the register has some limitations (no numeric keys) and we also don't want to mess with it too much. -*/ - +@c int lua_properties_level = 0 ; /* can be private */ int lua_properties_enabled = 0 ; int lua_properties_use_metatable = 0 ; -/* We keep track of nesting so that we don't oveflow the stack, and, what is more important, -don't keep resolving the registry index. */ +@ +We keep track of nesting so that we don't oveflow the stack, and, what is more +important, don't keep resolving the registry index. +@c #define lua_properties_push do { \ if (lua_properties_enabled) { \ lua_properties_level = lua_properties_level + 1 ; \ @@ -511,37 +509,38 @@ don't keep resolving the registry index. */ } \ } while(0) -/* For a moment I considered supporting all kind of data types but in practice -that makes no sense. So we stick to a cheap shallow copy with as option a -metatable. Btw, a deep copy would look like this: - -static void copy_lua_table(lua_State* L, int index) { - lua_newtable(L); - lua_pushnil(L); - while(lua_next(L, index-1) != 0) { - lua_pushvalue(L, -2); - lua_insert(L, -2); - if (lua_type(L,-1)==LUA_TTABLE) - copy_lua_table(L,-1); - lua_settable(L, -4); +/* + For a moment I considered supporting all kind of data types but in practice + that makes no sense. So we stick to a cheap shallow copy with as option a + metatable. Btw, a deep copy would look like this: + + static void copy_lua_table(lua_State* L, int index) { + lua_newtable(L); + lua_pushnil(L); + while(lua_next(L, index-1) != 0) { + lua_pushvalue(L, -2); + lua_insert(L, -2); + if (lua_type(L,-1)==LUA_TTABLE) + copy_lua_table(L,-1); + lua_settable(L, -4); + } + lua_pop(L,1); } - lua_pop(L,1); -} -#define lua_properties_copy(target, source) do { \ - if (lua_properties_enabled) { \ - lua_pushnumber(Luas,source); \ - lua_rawget(Luas,-2); \ - if (lua_type(Luas,-1)==LUA_TTABLE) { \ - copy_lua_table(Luas,-1); \ - lua_pushnumber(Luas,target); \ - lua_insert(Luas,-2); \ - lua_rawset(Luas,-3); \ - } else { \ - lua_pop(Luas,1); \ + #define lua_properties_copy(target, source) do { \ + if (lua_properties_enabled) { \ + lua_pushinteger(Luas,source); \ + lua_rawget(Luas,-2); \ + if (lua_type(Luas,-1)==LUA_TTABLE) { \ + copy_lua_table(Luas,-1); \ + lua_pushinteger(Luas,target); \ + lua_insert(Luas,-2); \ + lua_rawset(Luas,-3); \ + } else { \ + lua_pop(Luas,1); \ + } \ } \ - } \ -} while(0) + } while(0) */ @@ -589,97 +588,297 @@ static void copy_lua_table(lua_State* L, int index) { /* Here end the property handlers. */ @ @c -halfword new_node(int i, int j) +int valid_node(halfword p) { - int s; - halfword n; - s = get_node_size(i, j); - n = get_node(s); - /* it should be possible to do this memset at |free_node()| */ - /* type() and subtype() will be set below, and vlink() is - set to null by |get_node()|, so we can do we clearing one - word less than |s| */ - (void) memset((void *) (varmem + n + 1), 0, - (sizeof(memory_word) * ((unsigned) s - 1))); - switch (i) { - case glyph_node: - init_lang_data(n); - break; - case hlist_node: - case vlist_node: - box_dir(n) = -1; - break; - case whatsit_node: - if (j == open_node) { - open_name(n) = get_nullstr(); - open_area(n) = open_name(n); - open_ext(n) = open_name(n); + if (p > my_prealloc && p < var_mem_max) { +#ifdef CHECK_NODE_USAGE + if (varmem_sizes[p] > 0) { + return 1; + } +#else + return 1; +#endif + } + return 0; +} + +@ @c +static int test_count = 1; + +#define dorangetest(a,b,c) do { \ + if (!(b>=0 && b<c)) { \ + fprintf(stdout,"For node p:=%d, 0<=%d<%d (l.%d,r.%d)\n", \ + (int)a, (int)b, (int)c, __LINE__,test_count); \ + confusion("node range test failed"); \ + } } while (0) + +#define dotest(a,b,c) do { \ + if (b!=c) { \ + fprintf(stdout,"For node p:=%d, %d==%d (l.%d,r.%d)\n", \ + (int)a, (int)b, (int)c, __LINE__,test_count); \ + confusion("node test failed"); \ + } } while (0) + +#define check_action_ref(a) { dorangetest(p,a,var_mem_max); } +#define check_glue_ref(a) { dorangetest(p,a,var_mem_max); } +#define check_attribute_ref(a) { dorangetest(p,a,var_mem_max); } +#define check_token_ref(a) { confusion("fuzzy token cleanup in node"); } + +#ifdef CHECK_NODE_USAGE + +static void check_static_node_mem(void) +{ + dotest(zero_glue, width(zero_glue), 0); + dotest(zero_glue, type(zero_glue), glue_spec_node); + dotest(zero_glue, vlink(zero_glue), null); + dotest(zero_glue, stretch(zero_glue), 0); + dotest(zero_glue, stretch_order(zero_glue), normal); + dotest(zero_glue, shrink(zero_glue), 0); + dotest(zero_glue, shrink_order(zero_glue), normal); + + dotest(sfi_glue, width(sfi_glue), 0); + dotest(sfi_glue, type(sfi_glue), glue_spec_node); + dotest(sfi_glue, vlink(sfi_glue), null); + dotest(sfi_glue, stretch(sfi_glue), 0); + dotest(sfi_glue, stretch_order(sfi_glue), sfi); + dotest(sfi_glue, shrink(sfi_glue), 0); + dotest(sfi_glue, shrink_order(sfi_glue), normal); + + dotest(fil_glue, width(fil_glue), 0); + dotest(fil_glue, type(fil_glue), glue_spec_node); + dotest(fil_glue, vlink(fil_glue), null); + dotest(fil_glue, stretch(fil_glue), unity); + dotest(fil_glue, stretch_order(fil_glue), fil); + dotest(fil_glue, shrink(fil_glue), 0); + dotest(fil_glue, shrink_order(fil_glue), normal); + + dotest(fill_glue, width(fill_glue), 0); + dotest(fill_glue, type(fill_glue), glue_spec_node); + dotest(fill_glue, vlink(fill_glue), null); + dotest(fill_glue, stretch(fill_glue), unity); + dotest(fill_glue, stretch_order(fill_glue), fill); + dotest(fill_glue, shrink(fill_glue), 0); + dotest(fill_glue, shrink_order(fill_glue), normal); + + dotest(ss_glue, width(ss_glue), 0); + dotest(ss_glue, type(ss_glue), glue_spec_node); + dotest(ss_glue, vlink(ss_glue), null); + dotest(ss_glue, stretch(ss_glue), unity); + dotest(ss_glue, stretch_order(ss_glue), fil); + dotest(ss_glue, shrink(ss_glue), unity); + dotest(ss_glue, shrink_order(ss_glue), fil); + + dotest(fil_neg_glue, width(fil_neg_glue), 0); + dotest(fil_neg_glue, type(fil_neg_glue), glue_spec_node); + dotest(fil_neg_glue, vlink(fil_neg_glue), null); + dotest(fil_neg_glue, stretch(fil_neg_glue), -unity); + dotest(fil_neg_glue, stretch_order(fil_neg_glue), fil); + dotest(fil_neg_glue, shrink(fil_neg_glue), 0); + dotest(fil_neg_glue, shrink_order(fil_neg_glue), normal); +} + +static void node_mem_dump(halfword p) +{ + halfword r; + for (r = my_prealloc + 1; r < var_mem_max; r++) { + if (vlink(r) == p) { + halfword s = r; + while (s > my_prealloc && varmem_sizes[s] == 0) { + s--; + } + if (s != null + && s != my_prealloc + && s != var_mem_max + && (r - s) < get_node_size(type(s), subtype(s)) + && alink(s) != p) { + if (type(s) == disc_node) { + fprintf(stdout," pointed to from %s node %d (vlink %d, alink %d): ", + get_node_name(type(s), subtype(s)), (int) s, + (int) vlink(s), (int) alink(s)); + fprintf(stdout, "pre_break(%d,%d,%d), ", + (int) vlink_pre_break(s), (int) tlink(pre_break(s)), + (int) alink(pre_break(s))); + fprintf(stdout, "post_break(%d,%d,%d), ", + (int) vlink_post_break(s), + (int) tlink(post_break(s)), + (int) alink(post_break(s))); + fprintf(stdout, "no_break(%d,%d,%d)", + (int) vlink_no_break(s), (int) tlink(no_break(s)), + (int) alink(no_break(s))); + fprintf(stdout, "\n"); + } else { + if (vlink(s) == p + || (type(s) == glyph_node && lig_ptr (s) == p) + || (type(s) == vlist_node && list_ptr(s) == p) + || (type(s) == hlist_node && list_ptr(s) == p) + || (type(s) == unset_node && list_ptr(s) == p) + || (type(s) == ins_node && ins_ptr (s) == p) + ) { + fprintf(stdout," pointed to from %s node %d (vlink %d, alink %d): ", + get_node_name(type(s), subtype(s)), (int) s, + (int) vlink(s), (int) alink(s)); + if (type(s) == glyph_node) { + fprintf(stdout, "lig_ptr(%d)", (int) lig_ptr(s)); + } else if (type(s) == vlist_node || type(s) == hlist_node) { + fprintf(stdout, "list_ptr(%d)", (int) list_ptr(s)); + } + fprintf(stdout, "\n"); + } else { + if ((type(s) != penalty_node) && (type(s) != math_node) && (type(s) != kern_node)) { + fprintf(stdout, " pointed to from %s node %d\n", + get_node_name(type(s), subtype(s)), (int) s); + } + } + } + } } - break; - case disc_node: - pre_break(n) = pre_break_head(n); - type(pre_break(n)) = nesting_node; - subtype(pre_break(n)) = pre_break_head(0); - post_break(n) = post_break_head(n); - type(post_break(n)) = nesting_node; - subtype(post_break(n)) = post_break_head(0); - no_break(n) = no_break_head(n); - type(no_break(n)) = nesting_node; - subtype(no_break(n)) = no_break_head(0); - break; - case rule_node: - depth(n) = null_flag; - height(n) = null_flag; - rule_dir(n) = -1; - rule_index(n) = 0; - rule_transform(n) = 0; - /* fall through */ - case unset_node: - width(n) = null_flag; - break; - case pseudo_line_node: - case shape_node: - /* this is a trick that makes |pseudo_files| slightly slower, - but the overall allocation faster then an explicit test - at the top of |new_node()|. - */ - if (j>0) { - free_node(n, variable_node_size); - n = slow_get_node(j); - (void) memset((void *) (varmem + n + 1), 0, - (sizeof(memory_word) * ((unsigned) j - 1))); + } +} + +#endif + +static int free_error(halfword p) +{ + if (p > my_prealloc && p < var_mem_max) { +#ifdef CHECK_NODE_USAGE + int i; + if (varmem_sizes[p] == 0) { + check_static_node_mem(); + for (i = (my_prealloc + 1); i < var_mem_max; i++) { + if (varmem_sizes[i] > 0) { + check_node(i); + } + } + test_count++; + if (type(p) == glyph_node) { + formatted_error("nodes", "attempt to double-free glyph (%c) node %d, ignored", (int) character(p), (int) p); + } else { + formatted_error("nodes", "attempt to double-free %s node %d, ignored", get_node_name(type(p), subtype(p)), (int) p); + } + node_mem_dump(p); + return 1; } - break; - default: - break; +#endif + } else { + formatted_error("nodes", "attempt to free an impossible node %d", (int) p); + return 1; } - if (int_par(synctex_code)) { - /* handle synctex extension */ - switch (i) { - case math_node: - synctex_tag_math(n) = cur_input.synctex_tag_field; - synctex_line_math(n) = line; - break; - case glue_node: - synctex_tag_glue(n) = cur_input.synctex_tag_field; - synctex_line_glue(n) = line; - break; - case kern_node: - if (j != 0) { - synctex_tag_kern(n) = cur_input.synctex_tag_field; - synctex_line_kern(n) = line; + return 0; +} + +@ @c +static int copy_error(halfword p) +{ + if (p >= 0 && p < var_mem_max) { +#ifdef CHECK_NODE_USAGE + if (p > my_prealloc && varmem_sizes[p] == 0) { + if (type(p) == glyph_node) { + formatted_warning("nodes", "attempt to copy free glyph (%c) node %d, ignored", (int) character(p), (int) p); + } else { + formatted_warning("nodes", "attempt to copy free %s node %d, ignored", get_node_name(type(p), subtype(p)), (int) p); } + return 1; + } +#endif + } else { + formatted_error("nodes", "attempt to copy an impossible node %d", (int) p); + return 1; + } + return 0; +} + +@ @c +halfword new_node(int i, int j) +{ + int s = get_node_size(i, j); + halfword n = get_node(s); + /* + It should be possible to do this memset at |free_node()|. + + Both type() and subtype() will be set below, and vlink() is + set to null by |get_node()|, so we can do we clearing one + word less than |s| + */ + (void) memset((void *) (varmem + n + 1), 0, (sizeof(memory_word) * ((unsigned) s - 1))); + switch (i) { + case glyph_node: + init_lang_data(n); break; case hlist_node: case vlist_node: - case unset_node: - synctex_tag_box(n) = cur_input.synctex_tag_field; - synctex_line_box(n) = line; + box_dir(n) = -1; + break; + case disc_node: + pre_break(n) = pre_break_head(n); + type(pre_break(n)) = nesting_node; + subtype(pre_break(n)) = pre_break_head(0); + post_break(n) = post_break_head(n); + type(post_break(n)) = nesting_node; + subtype(post_break(n)) = post_break_head(0); + no_break(n) = no_break_head(n); + type(no_break(n)) = nesting_node; + subtype(no_break(n)) = no_break_head(0); break; case rule_node: - synctex_tag_rule(n) = cur_input.synctex_tag_field; - synctex_line_rule(n) = line; + depth(n) = null_flag; + height(n) = null_flag; + width(n) = null_flag; + rule_dir(n) = -1; + rule_index(n) = 0; + rule_transform(n) = 0; + break; + case whatsit_node: + if (j == open_node) { + open_name(n) = get_nullstr(); + open_area(n) = open_name(n); + open_ext(n) = open_name(n); + } break; + case unset_node: + width(n) = null_flag; + break; + case pseudo_line_node: + case shape_node: + /* this is a trick that makes |pseudo_files| slightly slower, + but the overall allocation faster then an explicit test + at the top of |new_node()|. + */ + if (j>0) { + free_node(n, variable_node_size); + n = slow_get_node(j); + (void) memset((void *) (varmem + n + 1), 0, (sizeof(memory_word) * ((unsigned) j - 1))); + } + break; + default: + break; + } + if (int_par(synctex_code)) { + /* handle synctex extension */ + switch (i) { + case math_node: + synctex_tag_math(n) = cur_input.synctex_tag_field; + synctex_line_math(n) = line; + break; + case glue_node: + synctex_tag_glue(n) = cur_input.synctex_tag_field; + synctex_line_glue(n) = line; + break; + case kern_node: + if (j != 0) { + synctex_tag_kern(n) = cur_input.synctex_tag_field; + synctex_line_kern(n) = line; + } + break; + case hlist_node: + case vlist_node: + case unset_node: + synctex_tag_box(n) = cur_input.synctex_tag_field; + synctex_line_box(n) = line; + break; + case rule_node: + synctex_tag_rule(n) = cur_input.synctex_tag_field; + synctex_line_rule(n) = line; + break; } } /* take care of attributes */ @@ -689,19 +888,13 @@ halfword new_node(int i, int j) } type(n) = (quarterword) i; subtype(n) = (quarterword) j; -#ifdef DEBUG - fprintf(DEBUG_OUT, "Alloc-ing %s node %d\n", - get_node_name(type(n), subtype(n)), (int) n); -#endif return n; } halfword raw_glyph_node(void) { - register halfword n; - n = get_node(glyph_node_size); - (void) memset((void *) (varmem + n + 1), 0, - (sizeof(memory_word) * (glyph_node_size - 1))); + register halfword n = get_node(glyph_node_size); + (void) memset((void *) (varmem + n + 1), 0, (sizeof(memory_word) * (glyph_node_size - 1))); type(n) = glyph_node; subtype(n) = 0; return n; @@ -709,10 +902,8 @@ halfword raw_glyph_node(void) halfword new_glyph_node(void) { - register halfword n; - n = get_node(glyph_node_size); - (void) memset((void *) (varmem + n + 1), 0, - (sizeof(memory_word) * (glyph_node_size - 1))); + register halfword n = get_node(glyph_node_size); + (void) memset((void *) (varmem + n + 1), 0, (sizeof(memory_word) * (glyph_node_size - 1))); type(n) = glyph_node; subtype(n) = 0; build_attribute_list(n); @@ -720,16 +911,15 @@ halfword new_glyph_node(void) return n; } - @ makes a duplicate of the node list that starts at |p| and returns a - pointer to the new list +pointer to the new list + @c halfword do_copy_node_list(halfword p, halfword end) { - halfword q = null; /* previous position in new list */ - halfword h = null; /* head of the list */ + halfword q = null; /* previous position in new list */ + halfword h = null; /* head of the list */ register halfword s ; - copy_error_seen = 0; lua_properties_push; /* saves stack and time */ while (p != end) { s = copy_node(p); @@ -750,31 +940,6 @@ halfword copy_node_list(halfword p) return do_copy_node_list(p, null); } -/* There is no gain in using a temp var: - - #define copy_sub_list(target,source) do { \ - l = source; \ - if (l != null) { \ - s = copy_node_list(l); \ - target = s; \ - } else { \ - target = null; \ - } \ - } while (0) - - #define copy_sub_node(target,source) do { \ - l = source; \ - if (l != null) { \ - s = copy_node(l); \ - target = s ; \ - } else { \ - target = null; \ - } \ - } while (0) - - So we use: -*/ - #define copy_sub_list(target,source) do { \ if (source != null) { \ s = do_copy_node_list(source, null); \ @@ -796,15 +961,6 @@ halfword copy_node_list(halfword p) @ make a dupe of a single node @c - -/* - at some point we can use function pointers as in the backend itself: - - typedef void (*copy_function) (); - copy_function *copy_functions; - xmalloc((MAX_WHATSIT_TYPE + 1) * sizeof(copy_function)); -*/ - static void copy_node_wrapup_core(halfword p, halfword r) { halfword s ; @@ -829,7 +985,7 @@ static void copy_node_wrapup_core(halfword p, halfword r) user_node_value(r) = s; break; case 's': - /* |add_string_ref(user_node_value(p));| *//* if this was mpost .. */ + /* |add_string_ref(user_node_value(p));| */ break; case 't': add_token_ref(user_node_value(p)); @@ -895,20 +1051,19 @@ halfword copy_node(const halfword p) i = get_node_size(type(p), subtype(p)); r = get_node(i); - (void) memcpy((void *) (varmem + r), (void *) (varmem + p), - (sizeof(memory_word) * (unsigned) i)); + (void) memcpy((void *) (varmem + r), (void *) (varmem + p), (sizeof(memory_word) * (unsigned) i)); if (int_par(synctex_code)) { /* handle synctex extension */ switch (type(p)) { - case math_node: - synctex_tag_math(r) = cur_input.synctex_tag_field; - synctex_line_math(r) = line; - break; - case kern_node: - synctex_tag_kern(r) = cur_input.synctex_tag_field; - synctex_line_kern(r) = line; - break; + case math_node: + synctex_tag_math(r) = cur_input.synctex_tag_field; + synctex_line_math(r) = line; + break; + case kern_node: + synctex_tag_kern(r) = cur_input.synctex_tag_field; + synctex_line_kern(r) = line; + break; } } if (nodetype_has_attributes(type(p))) { @@ -919,319 +1074,129 @@ halfword copy_node(const halfword p) vlink(r) = null; switch (type(p)) { - case glyph_node: - copy_sub_list(lig_ptr(r),lig_ptr(p)) ; - break; - case glue_node: - add_glue_ref(glue_ptr(p)); - copy_sub_list(leader_ptr(r),leader_ptr(p)) ; - break; - case hlist_node: - case vlist_node: - case unset_node: - copy_sub_list(list_ptr(r),list_ptr(p)) ; - break; - case disc_node: - pre_break(r) = pre_break_head(r); - if (vlink_pre_break(p) != null) { - s = copy_node_list(vlink_pre_break(p)); - alink(s) = pre_break(r); - tlink_pre_break(r) = tail_of_list(s); - vlink_pre_break(r) = s; - } else { - assert(tlink(pre_break(r)) == null); - } - post_break(r) = post_break_head(r); - if (vlink_post_break(p) != null) { - s = copy_node_list(vlink_post_break(p)); - alink(s) = post_break(r); - tlink_post_break(r) = tail_of_list(s); - vlink_post_break(r) = s; - } else { - assert(tlink_post_break(r) == null); - } - no_break(r) = no_break_head(r); - if (vlink(no_break(p)) != null) { - s = copy_node_list(vlink_no_break(p)); - alink(s) = no_break(r); - tlink_no_break(r) = tail_of_list(s); - vlink_no_break(r) = s; - } else { - assert(tlink_no_break(r) == null); - } - break; - case math_node: - if (glue_ptr(p) != zero_glue) { + case glyph_node: + copy_sub_list(lig_ptr(r),lig_ptr(p)) ; + break; + case glue_node: add_glue_ref(glue_ptr(p)); - } - break; - case ins_node: - add_glue_ref(split_top_ptr(p)); - copy_sub_list(ins_ptr(r),ins_ptr(p)) ; - break; - case margin_kern_node: - copy_sub_node(margin_char(r),margin_char(p)); - break; - case mark_node: - add_token_ref(mark_ptr(p)); - break; - case adjust_node: - copy_sub_list(adjust_ptr(r),adjust_ptr(p)); - break; - case choice_node: - copy_sub_list(display_mlist(r),display_mlist(p)) ; - copy_sub_list(text_mlist(r),text_mlist(p)) ; - copy_sub_list(script_mlist(r),script_mlist(p)) ; - copy_sub_list(script_script_mlist(r),script_script_mlist(p)) ; - break; - case simple_noad: - copy_sub_list(nucleus(r),nucleus(p)) ; - copy_sub_list(subscr(r),subscr(p)) ; - copy_sub_list(supscr(r),supscr(p)) ; - break; - case radical_noad: - copy_sub_list(nucleus(r),nucleus(p)) ; - copy_sub_list(subscr(r),subscr(p)) ; - copy_sub_list(supscr(r),supscr(p)) ; - copy_sub_node(left_delimiter(r),left_delimiter(p)) ; - copy_sub_list(degree(r),degree(p)) ; - break; - case accent_noad: - copy_sub_list(nucleus(r),nucleus(p)) ; - copy_sub_list(subscr(r),subscr(p)) ; - copy_sub_list(supscr(r),supscr(p)) ; - copy_sub_list(top_accent_chr(r),top_accent_chr(p)) ; - copy_sub_list(bot_accent_chr(r),bot_accent_chr(p)) ; - copy_sub_list(overlay_accent_chr(r),overlay_accent_chr(p)) ; - break; - case fence_noad: - copy_sub_node(delimiter(r),delimiter(p)) ; - break; - case sub_box_node: - case sub_mlist_node: - copy_sub_list(math_list(r),math_list(p)) ; - break; - case fraction_noad: - copy_sub_list(numerator(r),numerator(p)) ; - copy_sub_list(denominator(r),denominator(p)) ; - copy_sub_node(left_delimiter(r),left_delimiter(p)) ; - copy_sub_node(right_delimiter(r),right_delimiter(p)) ; - break; - case glue_spec_node: - glue_ref_count(r) = null; - break; - case dir_node: - case local_par_node: - case boundary_node: - break; - case whatsit_node: - w = subtype(p) ; - if (w >= backend_first_pdf_whatsit) { - copy_node_wrapup_pdf(p,r); - } else if (w >= backend_first_dvi_whatsit) { - copy_node_wrapup_dvi(p,r); - } else { - copy_node_wrapup_core(p,r); - } - break; - } -#ifdef DEBUG - fprintf(DEBUG_OUT, "Alloc-ing %s node %d (copy of %d)\n", - get_node_name(type(r), subtype(r)), (int) r, (int) p); -#endif - return r; -} - -@ @c -int valid_node(halfword p) -{ - if (p > my_prealloc) { - if (p < var_mem_max) { -#ifndef NDEBUG - if (varmem_sizes[p] > 0) -#endif - return 1; - } - } else { - return 0; - } - return 0; -} - -@ @c -static void do_free_error(halfword p) -{ - halfword r; - char errstr[255] = { 0 }; - const char *errhlp[] = { - "When I tried to free the node mentioned in the error message, it turned", - "out it was not (or no longer) actually in use.", - "Errors such as these are often caused by Lua node list alteration,", - "but could also point to a bug in the executable. It should be safe to continue.", - NULL - }; - - check_node_mem(); - if (free_error_seen) - return; - - r = null; - free_error_seen = 1; - if (type(p) == glyph_node) { - snprintf(errstr, 255, - "Attempt to double-free glyph (%c) node %d, ignored", - (int) character(p), (int) p); - } else { - snprintf(errstr, 255, "Attempt to double-free %s node %d, ignored", - get_node_name(type(p), subtype(p)), (int) p); - } - tex_error(errstr, errhlp); -#ifndef NDEBUG - for (r = my_prealloc + 1; r < var_mem_max; r++) { - if (vlink(r) == p) { - halfword s = r; - while (s > my_prealloc && varmem_sizes[s] == 0) - s--; - if (s != null - && s != my_prealloc - && s != var_mem_max - && (r - s) < get_node_size(type(s), subtype(s)) - && alink(s) != p) { - - if (type(s) == disc_node) { - fprintf(stdout, - " pointed to from %s node %d (vlink %d, alink %d): ", - get_node_name(type(s), subtype(s)), (int) s, - (int) vlink(s), (int) alink(s)); - fprintf(stdout, "pre_break(%d,%d,%d), ", - (int) vlink_pre_break(s), (int) tlink(pre_break(s)), - (int) alink(pre_break(s))); - fprintf(stdout, "post_break(%d,%d,%d), ", - (int) vlink_post_break(s), - (int) tlink(post_break(s)), - (int) alink(post_break(s))); - fprintf(stdout, "no_break(%d,%d,%d)", - (int) vlink_no_break(s), (int) tlink(no_break(s)), - (int) alink(no_break(s))); - fprintf(stdout, "\n"); - } else { - if (vlink(s) == p - || (type(s) == glyph_node && lig_ptr(s) == p) - || (type(s) == vlist_node && list_ptr(s) == p) - || (type(s) == hlist_node && list_ptr(s) == p) - || (type(s) == unset_node && list_ptr(s) == p) - || (type(s) == ins_node && ins_ptr(s) == p) - ) { - fprintf(stdout, - " pointed to from %s node %d (vlink %d, alink %d): ", - get_node_name(type(s), subtype(s)), (int) s, - (int) vlink(s), (int) alink(s)); - if (type(s) == glyph_node) { - fprintf(stdout, "lig_ptr(%d)", (int) lig_ptr(s)); - } else if (type(s) == vlist_node - || type(s) == hlist_node) { - fprintf(stdout, "list_ptr(%d)", (int) list_ptr(s)); - } - fprintf(stdout, "\n"); - } else { - if ((type(s) != penalty_node) - && (type(s) != math_node) - && (type(s) != kern_node) - ) { - fprintf(stdout, " pointed to from %s node %d\n", - get_node_name(type(s), subtype(s)), - (int) s); - } - } - } + copy_sub_list(leader_ptr(r),leader_ptr(p)) ; + break; + case hlist_node: + case vlist_node: + case unset_node: + copy_sub_list(list_ptr(r),list_ptr(p)) ; + break; + case disc_node: + pre_break(r) = pre_break_head(r); + if (vlink_pre_break(p) != null) { + s = copy_node_list(vlink_pre_break(p)); + alink(s) = pre_break(r); + tlink_pre_break(r) = tail_of_list(s); + vlink_pre_break(r) = s; + } else { + assert(tlink(pre_break(r)) == null); } - } + post_break(r) = post_break_head(r); + if (vlink_post_break(p) != null) { + s = copy_node_list(vlink_post_break(p)); + alink(s) = post_break(r); + tlink_post_break(r) = tail_of_list(s); + vlink_post_break(r) = s; + } else { + assert(tlink_post_break(r) == null); + } + no_break(r) = no_break_head(r); + if (vlink(no_break(p)) != null) { + s = copy_node_list(vlink_no_break(p)); + alink(s) = no_break(r); + tlink_no_break(r) = tail_of_list(s); + vlink_no_break(r) = s; + } else { + assert(tlink_no_break(r) == null); + } + break; + case math_node: + if (glue_ptr(p) != zero_glue) { + add_glue_ref(glue_ptr(p)); + } + break; + case ins_node: + add_glue_ref(split_top_ptr(p)); + copy_sub_list(ins_ptr(r),ins_ptr(p)) ; + break; + case margin_kern_node: + copy_sub_node(margin_char(r),margin_char(p)); + break; + case mark_node: + add_token_ref(mark_ptr(p)); + break; + case adjust_node: + copy_sub_list(adjust_ptr(r),adjust_ptr(p)); + break; + case choice_node: + copy_sub_list(display_mlist(r),display_mlist(p)) ; + copy_sub_list(text_mlist(r),text_mlist(p)) ; + copy_sub_list(script_mlist(r),script_mlist(p)) ; + copy_sub_list(script_script_mlist(r),script_script_mlist(p)) ; + break; + case simple_noad: + copy_sub_list(nucleus(r),nucleus(p)) ; + copy_sub_list(subscr(r),subscr(p)) ; + copy_sub_list(supscr(r),supscr(p)) ; + break; + case radical_noad: + copy_sub_list(nucleus(r),nucleus(p)) ; + copy_sub_list(subscr(r),subscr(p)) ; + copy_sub_list(supscr(r),supscr(p)) ; + copy_sub_node(left_delimiter(r),left_delimiter(p)) ; + copy_sub_list(degree(r),degree(p)) ; + break; + case accent_noad: + copy_sub_list(nucleus(r),nucleus(p)) ; + copy_sub_list(subscr(r),subscr(p)) ; + copy_sub_list(supscr(r),supscr(p)) ; + copy_sub_list(top_accent_chr(r),top_accent_chr(p)) ; + copy_sub_list(bot_accent_chr(r),bot_accent_chr(p)) ; + copy_sub_list(overlay_accent_chr(r),overlay_accent_chr(p)) ; + break; + case fence_noad: + copy_sub_node(delimiter(r),delimiter(p)) ; + break; + case sub_box_node: + case sub_mlist_node: + copy_sub_list(math_list(r),math_list(p)) ; + break; + case fraction_noad: + copy_sub_list(numerator(r),numerator(p)) ; + copy_sub_list(denominator(r),denominator(p)) ; + copy_sub_node(left_delimiter(r),left_delimiter(p)) ; + copy_sub_node(right_delimiter(r),right_delimiter(p)) ; + break; + case glue_spec_node: + glue_ref_count(r) = null; + break; + case dir_node: + case local_par_node: + case boundary_node: + break; + case whatsit_node: + w = subtype(p) ; + if (w >= backend_first_pdf_whatsit) { + copy_node_wrapup_pdf(p,r); + } else if (w >= backend_first_dvi_whatsit) { + copy_node_wrapup_dvi(p,r); + } else { + copy_node_wrapup_core(p,r); + } + break; } -#endif + return r; } -static int free_error(halfword p) -{ - assert(p > my_prealloc); - assert(p < var_mem_max); -#ifndef NDEBUG - if (varmem_sizes[p] == 0) { - do_free_error(p); - return 1; /* double free */ - } -#endif - return 0; -} +/* x */ - -@ @c -static void do_copy_error(halfword p) -{ - char errstr[255] = { 0 }; - const char *errhlp[] = { - "When I tried to copy the node mentioned in the error message, it turned", - "out it was not (or no longer) actually in use.", - "Errors such as these are often caused by Lua node list alteration,", - "but could also point to a bug in the executable. It should be safe to continue.", - NULL - }; - - if (copy_error_seen) - return; - - copy_error_seen = 1; - if (type(p) == glyph_node) { - snprintf(errstr, 255, - "Attempt to copy free glyph (%c) node %d, ignored", - (int) character(p), (int) p); - } else { - snprintf(errstr, 255, "Attempt to copy free %s node %d, ignored", - get_node_name(type(p), subtype(p)), (int) p); - } - tex_error(errstr, errhlp); -} - - -int copy_error(halfword p) -{ - assert(p >= 0); - assert(p < var_mem_max); -#ifndef NDEBUG - if (p > my_prealloc && varmem_sizes[p] == 0) { - do_copy_error(p); - return 1; /* copy free node */ - } -#endif - return 0; -} - -/* No gain in a helper: - - #define free_sub_list(source) do { \ - l = source; \ - if (l != null) \ - flush_node_list(l); \ - } while (0) - - #define free_sub_node(source) do { \ - l = source; \ - if (l != null) \ - flush_node(l); \ - } while (0) - - So: - -*/ - -#define free_sub_list(source) do { \ - if (source != null) \ - flush_node_list(source); \ -} while (0) - -#define free_sub_node(source) do { \ - if (source != null) \ - flush_node(source); \ -} while (0) +#define free_sub_list(source) if (source != null) flush_node_list(source); +#define free_sub_node(source) if (source != null) flush_node(source); @ @c @@ -1348,155 +1313,148 @@ void flush_node(halfword p) halfword w; if (p == null) /* legal, but no-op */ return; - -#ifdef DEBUG - fprintf(DEBUG_OUT, "Free-ing %s node %d\n", - get_node_name(type(p), subtype(p)), (int) p); -#endif if (free_error(p)) return; - switch (type(p)) { - case glyph_node: - free_sub_list(lig_ptr(p)); - break; - case glue_node: - delete_glue_ref(glue_ptr(p)); - free_sub_list(leader_ptr(p)); - break; - case hlist_node: - case vlist_node: - case unset_node: - free_sub_list(list_ptr(p)); - break; - case disc_node: - /* watch the start at temp node hack */ - free_sub_list(vlink(pre_break(p))); - free_sub_list(vlink(post_break(p))); - free_sub_list(vlink(no_break(p))); - break; - case rule_node: - case kern_node: - case penalty_node: - break; - case math_node: - /* begin mathskip code */ - if (glue_ptr(p) != zero_glue) { + case glyph_node: + free_sub_list(lig_ptr(p)); + break; + case glue_node: delete_glue_ref(glue_ptr(p)); - } - /* end mathskip code */ - break; - case glue_spec_node: - /* this allows free-ing of lua-allocated glue specs */ - if (valid_node(p)) { - if (glue_ref_count(p)!=null) { - decr(glue_ref_count(p)); + free_sub_list(leader_ptr(p)); + break; + case hlist_node: + case vlist_node: + case unset_node: + free_sub_list(list_ptr(p)); + break; + case disc_node: + /* watch the start at temp node hack */ + free_sub_list(vlink(pre_break(p))); + free_sub_list(vlink(post_break(p))); + free_sub_list(vlink(no_break(p))); + break; + case rule_node: + case kern_node: + case penalty_node: + break; + case math_node: + /* begin mathskip code */ + if (glue_ptr(p) != zero_glue) { + delete_glue_ref(glue_ptr(p)); + } + /* end mathskip code */ + break; + case glue_spec_node: + /* this allows free-ing of lua-allocated glue specs */ + if (valid_node(p)) { + if (glue_ref_count(p)!=null) { + decr(glue_ref_count(p)); + } else { + free_node(p, get_node_size(type(p), subtype(p))); + } + } + return ; + break ; + case dir_node: + case local_par_node: + case boundary_node: + break; + case whatsit_node: + w = subtype(p) ; + if (w >= backend_first_pdf_whatsit) { + flush_node_wrapup_pdf(p); + } else if (w >= backend_first_dvi_whatsit) { + flush_node_wrapup_dvi(p); } else { - free_node(p, get_node_size(type(p), subtype(p))); + flush_node_wrapup_core(p); } - } - return ; - break ; - case dir_node: - case local_par_node: - case boundary_node: - break; - case whatsit_node: - w = subtype(p) ; - if (w >= backend_first_pdf_whatsit) { - flush_node_wrapup_pdf(p); - } else if (w >= backend_first_dvi_whatsit) { - flush_node_wrapup_dvi(p); - } else { - flush_node_wrapup_core(p); - } - break; - case ins_node: - flush_node_list(ins_ptr(p)); - delete_glue_ref(split_top_ptr(p)); - break; - case margin_kern_node: - flush_node(margin_char(p)); - break; - case mark_node: - delete_token_ref(mark_ptr(p)); - break; - case adjust_node: - flush_node_list(adjust_ptr(p)); - break; - case style_node: /* nothing to do */ - break; - case choice_node: - free_sub_list(display_mlist(p)); - free_sub_list(text_mlist(p)); - free_sub_list(script_mlist(p)); - free_sub_list(script_script_mlist(p)); - break; - case simple_noad: - free_sub_list(nucleus(p)); - free_sub_list(subscr(p)); - free_sub_list(supscr(p)); - break; - case radical_noad: - free_sub_list(nucleus(p)); - free_sub_list(subscr(p)); - free_sub_list(supscr(p)); - free_sub_node(left_delimiter(p)); - free_sub_list(degree(p)); - break; - case accent_noad: - free_sub_list(nucleus(p)); - free_sub_list(subscr(p)); - free_sub_list(supscr(p)); - free_sub_list(top_accent_chr(p)); - free_sub_list(bot_accent_chr(p)); - free_sub_list(overlay_accent_chr(p)); - break; - case fence_noad: - free_sub_list(delimiter(p)); - break; - case delim_node: /* nothing to do */ - case math_char_node: - case math_text_char_node: - break; - case sub_box_node: - case sub_mlist_node: - free_sub_list(math_list(p)); - break; - case fraction_noad: - free_sub_list(numerator(p)); - free_sub_list(denominator(p)); - free_sub_node(left_delimiter(p)); - free_sub_node(right_delimiter(p)); - break; - case pseudo_file_node: - free_sub_list(pseudo_lines(p)); - break; - case pseudo_line_node: - case shape_node: - free_node(p, subtype(p)); - return; - break; - case align_stack_node: - case span_node: - case movement_node: - case if_node: - case nesting_node: - case unhyphenated_node: - case hyphenated_node: - case delta_node: - case passive_node: - case inserting_node: - case split_up_node: - case expr_node: - case attribute_node: - case attribute_list_node: - case temp_node: - break; - default: - fprintf(stdout, "flush_node: type is %d\n", type(p)); - return; - + break; + case ins_node: + flush_node_list(ins_ptr(p)); + delete_glue_ref(split_top_ptr(p)); + break; + case margin_kern_node: + flush_node(margin_char(p)); + break; + case mark_node: + delete_token_ref(mark_ptr(p)); + break; + case adjust_node: + flush_node_list(adjust_ptr(p)); + break; + case style_node: /* nothing to do */ + break; + case choice_node: + free_sub_list(display_mlist(p)); + free_sub_list(text_mlist(p)); + free_sub_list(script_mlist(p)); + free_sub_list(script_script_mlist(p)); + break; + case simple_noad: + free_sub_list(nucleus(p)); + free_sub_list(subscr(p)); + free_sub_list(supscr(p)); + break; + case radical_noad: + free_sub_list(nucleus(p)); + free_sub_list(subscr(p)); + free_sub_list(supscr(p)); + free_sub_node(left_delimiter(p)); + free_sub_list(degree(p)); + break; + case accent_noad: + free_sub_list(nucleus(p)); + free_sub_list(subscr(p)); + free_sub_list(supscr(p)); + free_sub_list(top_accent_chr(p)); + free_sub_list(bot_accent_chr(p)); + free_sub_list(overlay_accent_chr(p)); + break; + case fence_noad: + free_sub_list(delimiter(p)); + break; + case delim_node: /* nothing to do */ + case math_char_node: + case math_text_char_node: + break; + case sub_box_node: + case sub_mlist_node: + free_sub_list(math_list(p)); + break; + case fraction_noad: + free_sub_list(numerator(p)); + free_sub_list(denominator(p)); + free_sub_node(left_delimiter(p)); + free_sub_node(right_delimiter(p)); + break; + case pseudo_file_node: + free_sub_list(pseudo_lines(p)); + break; + case pseudo_line_node: + case shape_node: + free_node(p, subtype(p)); + return; + break; + case align_stack_node: + case span_node: + case movement_node: + case if_node: + case nesting_node: + case unhyphenated_node: + case hyphenated_node: + case delta_node: + case passive_node: + case inserting_node: + case split_up_node: + case expr_node: + case attribute_node: + case attribute_list_node: + case temp_node: + break; + default: + formatted_error("nodes","flushing weird node type %d", type(p)); + return; } if (nodetype_has_attributes(type(p))) { delete_attribute_ref(node_attr(p)); @@ -1510,7 +1468,6 @@ void flush_node(halfword p) void flush_node_list(halfword pp) { /* erase list of nodes starting at |p| */ register halfword p = pp; - free_error_seen = 0; if (p == null) /* legal, but no-op */ return; if (free_error(p)) @@ -1525,27 +1482,6 @@ void flush_node_list(halfword pp) } @ @c -static int test_count = 1; - -#define dorangetest(a,b,c) do { \ - if (!(b>=0 && b<c)) { \ - fprintf(stdout,"For node p:=%d, 0<=%d<%d (l.%d,r.%d)\n", \ - (int)a, (int)b, (int)c, __LINE__,test_count); \ - confusion("dorangetest"); \ - } } while (0) - -#define dotest(a,b,c) do { \ - if (b!=c) { \ - fprintf(stdout,"For node p:=%d, %d==%d (l.%d,r.%d)\n", \ - (int)a, (int)b, (int)c, __LINE__,test_count); \ - confusion("dotest"); \ - } } while (0) - -#define check_action_ref(a) { dorangetest(p,a,var_mem_max); } -#define check_glue_ref(a) { dorangetest(p,a,var_mem_max); } -#define check_attribute_ref(a) { dorangetest(p,a,var_mem_max); } -#define check_token_ref(a) assert(1) - static void check_node_wrapup_core(halfword p) { switch (subtype(p)) { @@ -1555,28 +1491,27 @@ static void check_node_wrapup_core(halfword p) break; case user_defined_node: switch (user_node_type(p)) { - case 'a': - check_attribute_ref(user_node_value(p)); - break; - case 't': - check_token_ref(user_node_value(p)); - break; - case 'n': - dorangetest(p, user_node_value(p), var_mem_max); - break; - case 's': - case 'd': - break; - default: - confusion("extuser"); - break; + case 'a': + check_attribute_ref(user_node_value(p)); + break; + case 't': + check_token_ref(user_node_value(p)); + break; + case 'n': + dorangetest(p, user_node_value(p), var_mem_max); + break; + case 's': + case 'd': + break; + default: + confusion("unknown user node type"); + break; } break; case open_node: case write_node: case close_node: case save_pos_node: - confusion("ext3"); /* why */ break; } } @@ -1631,7 +1566,7 @@ void check_node_wrapup_pdf(halfword p) case pdf_end_thread_node: break; default: - confusion("ext3"); + confusion("wrapup pdf nodes"); break; } } @@ -1640,185 +1575,120 @@ void check_node(halfword p) { halfword w ; switch (type(p)) { - case glyph_node: - dorangetest(p, lig_ptr(p), var_mem_max); - break; - case glue_node: - check_glue_ref(glue_ptr(p)); - dorangetest(p, leader_ptr(p), var_mem_max); - break; - case hlist_node: - case vlist_node: - case unset_node: - case align_record_node: - dorangetest(p, list_ptr(p), var_mem_max); - break; - case ins_node: - dorangetest(p, ins_ptr(p), var_mem_max); - check_glue_ref(split_top_ptr(p)); - break; - case whatsit_node: - w = subtype(p) ; - if (w >= backend_first_pdf_whatsit) { - check_node_wrapup_pdf(p); - } else if (w >= backend_first_dvi_whatsit) { - check_node_wrapup_dvi(p); - } else { - check_node_wrapup_core(p); - } - break; - case margin_kern_node: - check_node(margin_char(p)); - break; - case math_node: - /* begin mathskip code */ - if (glue_ptr(p) != zero_glue) { + case glyph_node: + dorangetest(p, lig_ptr(p), var_mem_max); + break; + case glue_node: check_glue_ref(glue_ptr(p)); - } - /* end mathskip code */ - break; - case disc_node: - dorangetest(p, vlink(pre_break(p)), var_mem_max); - dorangetest(p, vlink(post_break(p)), var_mem_max); - dorangetest(p, vlink(no_break(p)), var_mem_max); - break; - case adjust_node: - dorangetest(p, adjust_ptr(p), var_mem_max); - break; - case pseudo_file_node: - dorangetest(p, pseudo_lines(p), var_mem_max); - break; - case pseudo_line_node: - case shape_node: - break; - case choice_node: - dorangetest(p, display_mlist(p), var_mem_max); - dorangetest(p, text_mlist(p), var_mem_max); - dorangetest(p, script_mlist(p), var_mem_max); - dorangetest(p, script_script_mlist(p), var_mem_max); - break; - case fraction_noad: - dorangetest(p, numerator(p), var_mem_max); - dorangetest(p, denominator(p), var_mem_max); - dorangetest(p, left_delimiter(p), var_mem_max); - dorangetest(p, right_delimiter(p), var_mem_max); - break; - case simple_noad: - dorangetest(p, nucleus(p), var_mem_max); - dorangetest(p, subscr(p), var_mem_max); - dorangetest(p, supscr(p), var_mem_max); - break; - case radical_noad: - dorangetest(p, nucleus(p), var_mem_max); - dorangetest(p, subscr(p), var_mem_max); - dorangetest(p, supscr(p), var_mem_max); - dorangetest(p, degree(p), var_mem_max); - dorangetest(p, left_delimiter(p), var_mem_max); - break; - case accent_noad: - dorangetest(p, nucleus(p), var_mem_max); - dorangetest(p, subscr(p), var_mem_max); - dorangetest(p, supscr(p), var_mem_max); - dorangetest(p, top_accent_chr(p), var_mem_max); - dorangetest(p, bot_accent_chr(p), var_mem_max); - dorangetest(p, overlay_accent_chr(p), var_mem_max); - break; - case fence_noad: - dorangetest(p, delimiter(p), var_mem_max); - break; - case rule_node: - case kern_node: - case penalty_node: - case mark_node: - case style_node: - case attribute_list_node: - case attribute_node: - case glue_spec_node: - case temp_node: - case align_stack_node: - case movement_node: - case if_node: - case nesting_node: - case span_node: - case unhyphenated_node: - case hyphenated_node: - case delta_node: - case passive_node: - case expr_node: - case dir_node: - case boundary_node: - case local_par_node: - break; - default: - fprintf(stdout, "check_node: type is %d\n", type(p)); - } -} - -@ @c -static void check_static_node_mem(void) -{ - dotest(zero_glue, width(zero_glue), 0); - dotest(zero_glue, type(zero_glue), glue_spec_node); - dotest(zero_glue, vlink(zero_glue), null); - dotest(zero_glue, stretch(zero_glue), 0); - dotest(zero_glue, stretch_order(zero_glue), normal); - dotest(zero_glue, shrink(zero_glue), 0); - dotest(zero_glue, shrink_order(zero_glue), normal); - - dotest(sfi_glue, width(sfi_glue), 0); - dotest(sfi_glue, type(sfi_glue), glue_spec_node); - dotest(sfi_glue, vlink(sfi_glue), null); - dotest(sfi_glue, stretch(sfi_glue), 0); - dotest(sfi_glue, stretch_order(sfi_glue), sfi); - dotest(sfi_glue, shrink(sfi_glue), 0); - dotest(sfi_glue, shrink_order(sfi_glue), normal); - - dotest(fil_glue, width(fil_glue), 0); - dotest(fil_glue, type(fil_glue), glue_spec_node); - dotest(fil_glue, vlink(fil_glue), null); - dotest(fil_glue, stretch(fil_glue), unity); - dotest(fil_glue, stretch_order(fil_glue), fil); - dotest(fil_glue, shrink(fil_glue), 0); - dotest(fil_glue, shrink_order(fil_glue), normal); - - dotest(fill_glue, width(fill_glue), 0); - dotest(fill_glue, type(fill_glue), glue_spec_node); - dotest(fill_glue, vlink(fill_glue), null); - dotest(fill_glue, stretch(fill_glue), unity); - dotest(fill_glue, stretch_order(fill_glue), fill); - dotest(fill_glue, shrink(fill_glue), 0); - dotest(fill_glue, shrink_order(fill_glue), normal); - - dotest(ss_glue, width(ss_glue), 0); - dotest(ss_glue, type(ss_glue), glue_spec_node); - dotest(ss_glue, vlink(ss_glue), null); - dotest(ss_glue, stretch(ss_glue), unity); - dotest(ss_glue, stretch_order(ss_glue), fil); - dotest(ss_glue, shrink(ss_glue), unity); - dotest(ss_glue, shrink_order(ss_glue), fil); - - dotest(fil_neg_glue, width(fil_neg_glue), 0); - dotest(fil_neg_glue, type(fil_neg_glue), glue_spec_node); - dotest(fil_neg_glue, vlink(fil_neg_glue), null); - dotest(fil_neg_glue, stretch(fil_neg_glue), -unity); - dotest(fil_neg_glue, stretch_order(fil_neg_glue), fil); - dotest(fil_neg_glue, shrink(fil_neg_glue), 0); - dotest(fil_neg_glue, shrink_order(fil_neg_glue), normal); -} - -@ @c -void check_node_mem(void) -{ - int i; - check_static_node_mem(); -#ifndef NDEBUG - for (i = (my_prealloc + 1); i < var_mem_max; i++) { - if (varmem_sizes[i] > 0) { - check_node(i); - } + dorangetest(p, leader_ptr(p), var_mem_max); + break; + case hlist_node: + case vlist_node: + case unset_node: + case align_record_node: + dorangetest(p, list_ptr(p), var_mem_max); + break; + case ins_node: + dorangetest(p, ins_ptr(p), var_mem_max); + check_glue_ref(split_top_ptr(p)); + break; + case whatsit_node: + w = subtype(p) ; + if (w >= backend_first_pdf_whatsit) { + check_node_wrapup_pdf(p); + } else if (w >= backend_first_dvi_whatsit) { + check_node_wrapup_dvi(p); + } else { + check_node_wrapup_core(p); + } + break; + case margin_kern_node: + check_node(margin_char(p)); + break; + case math_node: + /* begin mathskip code */ + if (glue_ptr(p) != zero_glue) { + check_glue_ref(glue_ptr(p)); + } + /* end mathskip code */ + break; + case disc_node: + dorangetest(p, vlink(pre_break(p)), var_mem_max); + dorangetest(p, vlink(post_break(p)), var_mem_max); + dorangetest(p, vlink(no_break(p)), var_mem_max); + break; + case adjust_node: + dorangetest(p, adjust_ptr(p), var_mem_max); + break; + case pseudo_file_node: + dorangetest(p, pseudo_lines(p), var_mem_max); + break; + case pseudo_line_node: + case shape_node: + break; + case choice_node: + dorangetest(p, display_mlist(p), var_mem_max); + dorangetest(p, text_mlist(p), var_mem_max); + dorangetest(p, script_mlist(p), var_mem_max); + dorangetest(p, script_script_mlist(p), var_mem_max); + break; + case fraction_noad: + dorangetest(p, numerator(p), var_mem_max); + dorangetest(p, denominator(p), var_mem_max); + dorangetest(p, left_delimiter(p), var_mem_max); + dorangetest(p, right_delimiter(p), var_mem_max); + break; + case simple_noad: + dorangetest(p, nucleus(p), var_mem_max); + dorangetest(p, subscr(p), var_mem_max); + dorangetest(p, supscr(p), var_mem_max); + break; + case radical_noad: + dorangetest(p, nucleus(p), var_mem_max); + dorangetest(p, subscr(p), var_mem_max); + dorangetest(p, supscr(p), var_mem_max); + dorangetest(p, degree(p), var_mem_max); + dorangetest(p, left_delimiter(p), var_mem_max); + break; + case accent_noad: + dorangetest(p, nucleus(p), var_mem_max); + dorangetest(p, subscr(p), var_mem_max); + dorangetest(p, supscr(p), var_mem_max); + dorangetest(p, top_accent_chr(p), var_mem_max); + dorangetest(p, bot_accent_chr(p), var_mem_max); + dorangetest(p, overlay_accent_chr(p), var_mem_max); + break; + case fence_noad: + dorangetest(p, delimiter(p), var_mem_max); + break; + /* + case rule_node: + case kern_node: + case penalty_node: + case mark_node: + case style_node: + case attribute_list_node: + case attribute_node: + case glue_spec_node: + case temp_node: + case align_stack_node: + case movement_node: + case if_node: + case nesting_node: + case span_node: + case unhyphenated_node: + case hyphenated_node: + case delta_node: + case passive_node: + case expr_node: + case dir_node: + case boundary_node: + case local_par_node: + break; + default: + fprintf(stdout, "check_node: type is %d\n", type(p)); + */ } -#endif - test_count++; } @ @c @@ -1840,49 +1710,34 @@ void fix_node_list(halfword head) halfword get_node(int s) { register halfword r; -#if 0 - check_static_node_mem(); -#endif - assert(s < MAX_CHAIN_SIZE); - r = free_chain[s]; - if (r != null) { - free_chain[s] = vlink(r); -#ifndef NDEBUG - varmem_sizes[r] = (char) s; + if (s < MAX_CHAIN_SIZE) { + r = free_chain[s]; + if (r != null) { + free_chain[s] = vlink(r); +#ifdef CHECK_NODE_USAGE + varmem_sizes[r] = (char) s; #endif - vlink(r) = null; - var_used += s; /* maintain usage statistics */ - return r; - } - /* this is the end of the 'inner loop' */ - return slow_get_node(s); -} - -@ @c -#ifdef DEBUG -static void print_free_chain(int c) -{ - halfword p = free_chain[c]; - fprintf(stdout, "\nfree chain[%d] =\n ", c); - while (p != null) { - fprintf(stdout, "%d,", (int) p); - p = vlink(p); + vlink(r) = null; + var_used += s; /* maintain usage statistics */ + return r; + } + /* this is the end of the 'inner loop' */ + return slow_get_node(s); + } else { + normal_error("nodes","there is a problem in getting a node, case 1"); + return null; } - fprintf(stdout, "null;\n"); } -#endif @ @c void free_node(halfword p, int s) { - if (p <= my_prealloc) { - fprintf(stdout, "node %d (type %d) should not be freed!\n", (int) p, - type(p)); + formatted_error("nodes", "node number %d of type %d should not be freed", (int) p, type(p)); return; } -#ifndef NDEBUG +#ifdef CHECK_NODE_USAGE varmem_sizes[p] = 0; #endif if (s < MAX_CHAIN_SIZE) { @@ -1897,7 +1752,8 @@ void free_node(halfword p, int s) } vlink(rover) = p; } - var_used -= s; /* maintain statistics */ + /* maintain statistics */ + var_used -= s; } @ @c @@ -1905,37 +1761,37 @@ static void free_node_chain(halfword q, int s) { register halfword p = q; while (vlink(p) != null) { -#ifndef NDEBUG +#ifdef CHECK_NODE_USAGE varmem_sizes[p] = 0; #endif var_used -= s; p = vlink(p); } var_used -= s; -#ifndef NDEBUG +#ifdef CHECK_NODE_USAGE varmem_sizes[p] = 0; #endif vlink(p) = free_chain[s]; free_chain[s] = q; } - @ @c void init_node_mem(int t) { my_prealloc = var_mem_stat_max; - assert(whatsit_node_data[user_defined_node].id == user_defined_node); - assert(node_data[passive_node].id == passive_node); - varmem = - (memory_word *) realloc((void *) varmem, - sizeof(memory_word) * (unsigned) t); + /* message ? + + assert(whatsit_node_data[user_defined_node].id == user_defined_node); + assert(node_data[passive_node].id == passive_node); + */ + + varmem = (memory_word *) realloc((void *) varmem, sizeof(memory_word) * (unsigned) t); if (varmem == NULL) { overflow("node memory size", (unsigned) var_mem_max); } memset((void *) (varmem), 0, (unsigned) t * sizeof(memory_word)); - -#ifndef NDEBUG +#ifdef CHECK_NODE_USAGE varmem_sizes = (char *) realloc(varmem_sizes, sizeof(char) * (unsigned) t); if (varmem_sizes == NULL) { overflow("node memory size", (unsigned) var_mem_max); @@ -2067,7 +1923,7 @@ void dump_node_mem(void) dump_int(var_mem_max); dump_int(rover); dump_things(varmem[0], var_mem_max); -#ifndef NDEBUG +#ifdef CHECK_NODE_USAGE dump_things(varmem_sizes[0], var_mem_max); #endif dump_things(free_chain[0], MAX_CHAIN_SIZE); @@ -2077,6 +1933,7 @@ void dump_node_mem(void) @ it makes sense to enlarge the varmem array immediately @c + void undump_node_mem(void) { int x; @@ -2084,11 +1941,8 @@ void undump_node_mem(void) undump_int(rover); var_mem_max = (x < 100000 ? 100000 : x); varmem = xmallocarray(memory_word, (unsigned) var_mem_max); -#if 0 - memset ((void *)varmem,0,x*sizeof(memory_word)); -#endif undump_things(varmem[0], x); -#ifndef NDEBUG +#ifdef CHECK_NODE_USAGE varmem_sizes = xmallocarray(char, (unsigned) var_mem_max); memset((void *) varmem_sizes, 0, (unsigned) var_mem_max * sizeof(char)); undump_things(varmem_sizes[0], x); @@ -2107,24 +1961,6 @@ void undump_node_mem(void) } } -#if 0 -void test_rovers(char *s) -{ - int q = rover; - int r = q; - fprintf(stdout, "%s: {rover=%d,size=%d,link=%d}", s, r, node_size(r), - vlink(r)); - while (vlink(r) != q) { - r = vlink(r); - fprintf(stdout, ",{rover=%d,size=%d,link=%d}", r, node_size(r), - vlink(r)); - } - fprintf(stdout, "\n"); -} -#else -# define test_rovers(a) -#endif - @ @c halfword slow_get_node(int s) { @@ -2132,105 +1968,99 @@ halfword slow_get_node(int s) RETRY: t = node_size(rover); - assert(vlink(rover) < var_mem_max); - assert(vlink(rover) != 0); - test_rovers("entry"); - if (t > s) { - register halfword r; - /* allocating from the bottom helps decrease page faults */ - r = rover; - rover += s; - vlink(rover) = vlink(r); - node_size(rover) = node_size(r) - s; - if (vlink(rover) != r) { /* list is longer than one */ - halfword q = r; - while (vlink(q) != r) { - q = vlink(q); + if (vlink(rover) < var_mem_max && vlink(rover) != 0) { + if (t > s) { + /* allocating from the bottom helps decrease page faults */ + register halfword r = rover; + rover += s; + vlink(rover) = vlink(r); + node_size(rover) = node_size(r) - s; + if (vlink(rover) != r) { /* list is longer than one */ + halfword q = r; + while (vlink(q) != r) { + q = vlink(q); + } + vlink(q) += s; + } else { + vlink(rover) += s; } - vlink(q) += s; - } else { - vlink(rover) += s; - } - test_rovers("taken"); - assert(vlink(rover) < var_mem_max); -#ifndef NDEBUG - varmem_sizes[r] = (char) (s > 127 ? 127 : s); + if (vlink(rover) < var_mem_max) { +#ifdef CHECK_NODE_USAGE + varmem_sizes[r] = (char) (s > 127 ? 127 : s); #endif - vlink(r) = null; - var_used += s; /* maintain usage statistics */ - return r; /* this is the only exit */ - } else { - int x; - /* attempt to keep the free list small */ - if (vlink(rover) != rover) { - if (t < MAX_CHAIN_SIZE) { - halfword l = vlink(rover); - vlink(rover) = free_chain[t]; - free_chain[t] = rover; - rover = l; - while (vlink(l) != free_chain[t]) { - l = vlink(l); - } - vlink(l) = rover; - test_rovers("outtake"); - goto RETRY; + vlink(r) = null; + var_used += s; /* maintain usage statistics */ + return r; /* this is the only exit */ } else { - halfword l = rover; - while (vlink(rover) != l) { - if (node_size(rover) > s) { - goto RETRY; + normal_error("nodes","there is a problem in getting a node, case 2"); + return null; + } + } else { + /* attempt to keep the free list small */ + int x; + if (vlink(rover) != rover) { + if (t < MAX_CHAIN_SIZE) { + halfword l = vlink(rover); + vlink(rover) = free_chain[t]; + free_chain[t] = rover; + rover = l; + while (vlink(l) != free_chain[t]) { + l = vlink(l); + } + vlink(l) = rover; + goto RETRY; + } else { + halfword l = rover; + while (vlink(rover) != l) { + if (node_size(rover) > s) { + goto RETRY; + } + rover = vlink(rover); } - rover = vlink(rover); } } - } - /* if we are still here, it was apparently impossible to get a match */ - x = (var_mem_max >> 2) + s; - varmem = - (memory_word *) realloc((void *) varmem, - sizeof(memory_word) * - (unsigned) (var_mem_max + x)); - if (varmem == NULL) { - overflow("node memory size", (unsigned) var_mem_max); - } - memset((void *) (varmem + var_mem_max), 0, - (unsigned) x * sizeof(memory_word)); - -#ifndef NDEBUG - varmem_sizes = - (char *) realloc(varmem_sizes, - sizeof(char) * (unsigned) (var_mem_max + x)); - if (varmem_sizes == NULL) { - overflow("node memory size", (unsigned) var_mem_max); - } - memset((void *) (varmem_sizes + var_mem_max), 0, - (unsigned) (x) * sizeof(char)); + /* if we are still here, it was apparently impossible to get a match */ + x = (var_mem_max >> 2) + s; + varmem = (memory_word *) realloc((void *) varmem, sizeof(memory_word) * (unsigned) (var_mem_max + x)); + if (varmem == NULL) { + overflow("node memory size", (unsigned) var_mem_max); + } + memset((void *) (varmem + var_mem_max), 0, (unsigned) x * sizeof(memory_word)); +#ifdef CHECK_NODE_USAGE + varmem_sizes = (char *) realloc(varmem_sizes, sizeof(char) * (unsigned) (var_mem_max + x)); + if (varmem_sizes == NULL) { + overflow("node memory size", (unsigned) var_mem_max); + } + memset((void *) (varmem_sizes + var_mem_max), 0, (unsigned) (x) * sizeof(char)); #endif - - /* todo ? it is perhaps possible to merge the new memory with an existing rover */ - vlink(var_mem_max) = rover; - node_size(var_mem_max) = x; - while (vlink(rover) != vlink(var_mem_max)) { - rover = vlink(rover); + /* todo ? it is perhaps possible to merge the new memory with an existing rover */ + vlink(var_mem_max) = rover; + node_size(var_mem_max) = x; + while (vlink(rover) != vlink(var_mem_max)) { + rover = vlink(rover); + } + vlink(rover) = var_mem_max; + rover = var_mem_max; + var_mem_max += x; + goto RETRY; } - vlink(rover) = var_mem_max; - rover = var_mem_max; - test_rovers("realloc"); - var_mem_max += x; - goto RETRY; + } else { + normal_error("nodes","there is a problem in getting a node, case 3"); + return null; } } @ @c char *sprint_node_mem_usage(void) { - int i, b; - - char *s, *ss; -#ifndef NDEBUG + char *s; +#ifdef CHECK_NODE_USAGE + char *ss; + int i; + int b = 0; char msg[256]; int node_counts[last_normal_node + last_whatsit_node + 2] = { 0 }; - + s = strdup(""); for (i = (var_mem_max - 1); i > my_prealloc; i--) { if (varmem_sizes[i] > 0) { if (type(i) > last_normal_node + last_whatsit_node) { @@ -2242,15 +2072,12 @@ char *sprint_node_mem_usage(void) } } } - s = strdup(""); - b = 0; for (i = 0; i < last_normal_node + last_whatsit_node + 2; i++) { if (node_counts[i] > 0) { int j = (i > (last_normal_node + 1) ? (i - last_normal_node - 1) : 0); snprintf(msg, 255, "%s%d %s", (b ? ", " : ""), (int) node_counts[i], - get_node_name((i > last_normal_node ? whatsit_node : i), - j)); + get_node_name((i > last_normal_node ? whatsit_node : i), j)); ss = xmalloc((unsigned) (strlen(s) + strlen(msg) + 1)); strcpy(ss, s); strcat(ss, msg); @@ -2268,9 +2095,10 @@ char *sprint_node_mem_usage(void) @ @c halfword list_node_mem_usage(void) { + halfword q = null; +#ifdef CHECK_NODE_USAGE + halfword p = null; halfword i, j; - halfword p = null, q = null; -#ifndef NDEBUG char *saved_varmem_sizes = xmallocarray(char, (unsigned) var_mem_max); memcpy(saved_varmem_sizes, varmem_sizes, (size_t) var_mem_max); for (i = my_prealloc + 1; i < (var_mem_max - 1); i++) { @@ -2297,8 +2125,7 @@ void print_node_mem_stats(void) char msg[256]; char *s; int free_chain_counts[MAX_CHAIN_SIZE] = { 0 }; - snprintf(msg, 255, " %d words of node memory still in use:", - (int) (var_used + my_prealloc)); + snprintf(msg, 255, " %d words of node memory still in use:", (int) (var_used + my_prealloc)); tprint_nl(msg); s = sprint_node_mem_usage(); tprint_nl(" "); @@ -2311,13 +2138,13 @@ void print_node_mem_stats(void) for (j = free_chain[i]; j != null; j = vlink(j)) free_chain_counts[i]++; if (free_chain_counts[i] > 0) { - snprintf(msg, 255, "%s%d:%d", (b ? "," : ""), i, - (int) free_chain_counts[i]); + snprintf(msg, 255, "%s%d:%d", (b ? "," : ""), i, (int) free_chain_counts[i]); tprint(msg); b = 1; } } - print_nlp(); /* newline, if needed */ + /* newline, if needed */ + print_nlp(); } /* this belongs in the web but i couldn't find the correct syntactic place */ @@ -2400,14 +2227,9 @@ void build_attribute_list(halfword b) } attr_list_ref(attr_list_cache)++; node_attr(b) = attr_list_cache; -#ifdef DEBUG - fprintf(DEBUG_OUT, "Added attrlist (%d) to node %d (count=%d)\n", - node_attr(b), b, attr_list_ref(attr_list_cache)); -#endif } } - @ @c halfword current_attribute_list(void) { @@ -2442,26 +2264,24 @@ void reassign_attribute(halfword n, halfword new) node_attr(n) = new ; } - - @ @c void delete_attribute_ref(halfword b) { if (b != null) { - assert(type(b) == attribute_list_node); - attr_list_ref(b)--; -#ifdef DEBUG - fprintf(DEBUG_OUT, "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; - free_node_chain(b, attribute_node_size); + if (type(b) == attribute_list_node){ + attr_list_ref(b)--; + if (attr_list_ref(b) == 0) { + if (b == attr_list_cache) + attr_list_cache = cache_disabled; + free_node_chain(b, attribute_node_size); + } + /* maintain sanity */ + if (attr_list_ref(b) < 0) { + attr_list_ref(b) = 0; + } + } else { + normal_error("nodes","trying to delete an attribute reference of a non attribute node"); } - /* maintain sanity */ - if (attr_list_ref(b) < 0) - attr_list_ref(b) = 0; } } @@ -2487,28 +2307,32 @@ halfword do_set_attribute(halfword p, int i, int val) return q; } q = p; - assert(vlink(p) != null); - while (vlink(p) != null) { - int t = attribute_id(vlink(p)); - if (t == i && attribute_value(vlink(p)) == val) - return q; /* no need to do anything */ - if (t >= i) - break; - j++; - p = vlink(p); - } + if (vlink(p) != null) { + while (vlink(p) != null) { + int t = attribute_id(vlink(p)); + if (t == i && attribute_value(vlink(p)) == val) + return q; /* no need to do anything */ + if (t >= i) + break; + j++; + p = vlink(p); + } - p = q; - while (j-- > 0) - p = vlink(p); - if (attribute_id(vlink(p)) == i) { - attribute_value(vlink(p)) = val; - } else { /* add a new node */ - halfword r = new_attribute_node((unsigned) i, val); - vlink(r) = vlink(p); - vlink(p) = r; + p = q; + while (j-- > 0) + p = vlink(p); + if (attribute_id(vlink(p)) == i) { + attribute_value(vlink(p)) = val; + } else { /* add a new node */ + halfword r = new_attribute_node((unsigned) i, val); + vlink(r) = vlink(p); + vlink(p) = r; + } + return q; + } else { + normal_error("nodes","trying to set an attribute fails, case 1"); + return null ; } - return q; } @ @c @@ -2531,61 +2355,62 @@ void set_attribute(halfword n, int i, int val) return; } /* we check if we have this attribute already and quit if the value stays the same */ - assert(vlink(p) != null); - while (vlink(p) != null) { - int t = attribute_id(vlink(p)); - if (t == i && attribute_value(vlink(p)) == val) - return; - if (t >= i) - break; - j++; - p = vlink(p); - } - /* j has now the position (if found) .. we assume a sorted list ! */ - p = node_attr(n); + if (vlink(p) != null) { + while (vlink(p) != null) { + int t = attribute_id(vlink(p)); + if (t == i && attribute_value(vlink(p)) == val) + return; + if (t >= i) + break; + j++; + p = vlink(p); + } + /* j has now the position (if found) .. we assume a sorted list ! */ + p = node_attr(n); - if (attr_list_ref(p) == 0 ) { - /* the list is invalid i.e. freed already */ - fprintf(stdout,"Node %d has an attribute list that is free already\n",(int) n); - /* the still dangling list gets ref count 1 */ - attr_list_ref(p) = 1; - } else if (attr_list_ref(p) == 1) { - /* this can really happen HH-LS */ - if (p == attr_list_cache) { - /* we can invalidate the cache setting */ - /* attr_list_cache = cache_disabled */ - /* or save the list, as done below */ + if (attr_list_ref(p) == 0 ) { + /* the list is invalid i.e. freed already */ + formatted_warning("nodes","node %d has an attribute list that is free already, case 1",(int) n); + /* the still dangling list gets ref count 1 */ + attr_list_ref(p) = 1; + } else if (attr_list_ref(p) == 1) { + /* this can really happen HH-LS */ + if (p == attr_list_cache) { + /* we can invalidate the cache setting */ + /* attr_list_cache = cache_disabled */ + /* or save the list, as done below */ + p = copy_attribute_list(p); + node_attr(n) = p; + /* the copied list gets ref count 1 */ + attr_list_ref(p) = 1; + } + } else { + /* the list is used multiple times so we make a copy */ p = copy_attribute_list(p); + /* we decrement the ref count or the original */ + delete_attribute_ref(node_attr(n)); node_attr(n) = p; /* the copied list gets ref count 1 */ attr_list_ref(p) = 1; } - } else { - /* the list is used multiple times so we make a copy */ - p = copy_attribute_list(p); - /* we decrement the ref count or the original */ - delete_attribute_ref(node_attr(n)); - node_attr(n) = p; - /* the copied list gets ref count 1 */ - attr_list_ref(p) = 1; - } - /* we go to position j in the list */ - while (j-- > 0) - p = vlink(p); - /* if we have a hit we just set the value otherwise we add a new node */ - if (attribute_id(vlink(p)) == i) { - attribute_value(vlink(p)) = val; - } else { /* add a new node */ - halfword r = new_attribute_node((unsigned) i, val); - vlink(r) = vlink(p); - vlink(p) = r; + /* we go to position j in the list */ + while (j-- > 0) + p = vlink(p); + /* if we have a hit we just set the value otherwise we add a new node */ + if (attribute_id(vlink(p)) == i) { + attribute_value(vlink(p)) = val; + } else { /* add a new node */ + halfword r = new_attribute_node((unsigned) i, val); + vlink(r) = vlink(p); + vlink(p) = r; + } + } else { + normal_error("nodes","trying to set an attribute fails, case 2"); } - return; } - @ @c int unset_attribute(halfword n, int i, int val) { @@ -2599,43 +2424,45 @@ int unset_attribute(halfword n, int i, int val) if (p == null) return UNUSED_ATTRIBUTE; if (attr_list_ref(p) == 0) { - fprintf(stdout, - "Node %d has an attribute list that is free already\n", - (int) n); + formatted_warning("nodes","node %d has an attribute list that is free already, case 2", (int) n); return UNUSED_ATTRIBUTE; } - assert(vlink(p) != null); - while (vlink(p) != null) { - t = attribute_id(vlink(p)); - if (t > i) - return UNUSED_ATTRIBUTE; - if (t == i) { + if (vlink(p) != null) { + while (vlink(p) != null) { + t = attribute_id(vlink(p)); + if (t > i) + return UNUSED_ATTRIBUTE; + if (t == i) { + p = vlink(p); + break; + } + j++; p = vlink(p); - break; } - j++; - p = vlink(p); - } - if (attribute_id(p) != i) - return UNUSED_ATTRIBUTE; - /* if we are still here, the attribute exists */ - p = node_attr(n); - if (attr_list_ref(p) > 1 || p == attr_list_cache) { - halfword q = copy_attribute_list(p); - if (attr_list_ref(p) > 1) { - delete_attribute_ref(node_attr(n)); + if (attribute_id(p) != i) + return UNUSED_ATTRIBUTE; + /* if we are still here, the attribute exists */ + p = node_attr(n); + if (attr_list_ref(p) > 1 || p == attr_list_cache) { + halfword q = copy_attribute_list(p); + if (attr_list_ref(p) > 1) { + delete_attribute_ref(node_attr(n)); + } + attr_list_ref(q) = 1; + node_attr(n) = q; } - attr_list_ref(q) = 1; - node_attr(n) = q; - } - p = vlink(node_attr(n)); - while (j-- > 0) - p = vlink(p); - t = attribute_value(p); - if (val == UNUSED_ATTRIBUTE || t == val) { - attribute_value(p) = UNUSED_ATTRIBUTE; + p = vlink(node_attr(n)); + while (j-- > 0) + p = vlink(p); + t = attribute_value(p); + if (val == UNUSED_ATTRIBUTE || t == val) { + attribute_value(p) = UNUSED_ATTRIBUTE; + } + return t; + } else { + normal_error("nodes","trying to unset an attribute fails"); + return null; } - return t; } @ @c @@ -2666,37 +2493,33 @@ int has_attribute(halfword n, int i, int val) void print_short_node_contents(halfword p) { switch (type(p)) { - case hlist_node: - case vlist_node: - case ins_node: - case whatsit_node: - case mark_node: - case adjust_node: - case unset_node: - print_char('['); - print_char(']'); - break; - case rule_node: - print_char('|'); - break; - case glue_node: - if (glue_ptr(p) != zero_glue) - print_char(' '); - break; - case math_node: - print_char('$'); - break; - case disc_node: - short_display(vlink(pre_break(p))); - short_display(vlink(post_break(p))); - break; - default: - assert(1); - break; + case hlist_node: + case vlist_node: + case ins_node: + case whatsit_node: + case mark_node: + case adjust_node: + case unset_node: + print_char('['); + print_char(']'); + break; + case rule_node: + print_char('|'); + break; + case glue_node: + if (glue_ptr(p) != zero_glue) + print_char(' '); + break; + case math_node: + print_char('$'); + break; + case disc_node: + short_display(vlink(pre_break(p))); + short_display(vlink(post_break(p))); + break; } } - @ @c static void show_pdftex_whatsit_rule_spec(int p) { @@ -2708,8 +2531,6 @@ static void show_pdftex_whatsit_rule_spec(int p) print_rule_dimen(width(p)); } - - @ Each new type of node that appears in our data structure must be capable of being displayed, copied, destroyed, and so on. The routines that we need for write-oriented whatsits are somewhat like those for mark nodes; @@ -2727,9 +2548,7 @@ static void print_write_whatsit(const char *s, pointer p) print_char('-'); } - @ @c - static void show_node_wrapup_core(int p) { switch (subtype(p)) { @@ -2811,7 +2630,7 @@ void show_node_wrapup_pdf(int p) tprint(" current"); break; default: - confusion("pdfcolorstack"); + confusion("colorstack"); break; } if (pdf_colorstack_cmd(p) <= colorstack_data) @@ -2997,15 +2816,17 @@ void show_node_wrapup_pdf(int p) @ Recursive calls on |show_node_list| therefore use the following pattern: @c -#define node_list_display(A) do { \ - append_char('.'); \ - show_node_list(A); \ - flush_char(); \ +#define node_list_display(A) do { \ + append_char('.'); \ + show_node_list(A); \ + flush_char(); \ } while (0) +/* prints a node list symbolically */ + void show_node_list(int p) -{ /* prints a node list symbolically */ - int n; /* the number of items already printed at this level */ +{ + int n = 0; /* the number of items already printed at this level */ halfword w; real g; /* a glue ratio, as a floating point number */ if ((int) cur_length > depth_threshold) { @@ -3013,7 +2834,6 @@ void show_node_list(int p) tprint(" []"); /* indicate that there's been some truncation */ return; } - n = 0; while (p != null) { print_ln(); print_current_string(); /* display the nesting history */ @@ -3111,6 +2931,10 @@ void show_node_list(int p) /* Display rule |p|; */ if (subtype(p) == normal_rule) { tprint_esc("rule("); + } else if (subtype(p) == empty_rule) { + tprint_esc("norule("); + } else if (subtype(p) == user_rule) { + tprint_esc("userrule("); } else if (subtype(p) == box_rule) { tprint_esc("box("); } else if (subtype(p) == image_rule) { @@ -3221,7 +3045,7 @@ void show_node_list(int p) print_char('g'); break; default: - assert(0); + normal_warning("nodes","weird glue leader subtype ignored"); } tprint("leaders "); print_spec(glue_ptr(p), NULL); @@ -3321,7 +3145,7 @@ void show_node_list(int p) case adjust_node: /* Display adjustment |p|; */ tprint_esc("vadjust"); - if (adjust_pre(p) != 0) + if (subtype(p) != 0) tprint(" pre "); node_list_display(adjust_ptr(p)); /* recursive call */ break; @@ -3345,70 +3169,67 @@ void show_node_list(int p) @c pointer actual_box_width(pointer r, scaled base_width) { - scaled w; /* calculated |size| */ - pointer p; /* current node when calculating |pre_display_size| */ - pointer q; /* glue specification when calculating |pre_display_size| */ - scaled d; /* increment to |v| */ - scaled v; /* |w| plus possible glue amount */ - w = -max_dimen; - v = shift_amount(r) + base_width; - p = list_ptr(r); + pointer q; /* glue specification when calculating |pre_display_size| */ + scaled d; /* increment to |v| */ + scaled w = -max_dimen; /* calculated |size| */ + scaled v = shift_amount(r) + base_width; /* |w| plus possible glue amount */ + pointer p = list_ptr(r); /* current node when calculating |pre_display_size| */ while (p != null) { if (is_char_node(p)) { d = glyph_width(p); - goto found; + goto FOUND; } switch (type(p)) { - case hlist_node: - case vlist_node: - case rule_node: - d = width(p); - goto found; - break; - case margin_kern_node: - d = width(p); - break; - case kern_node: - d = width(p); - break; - case math_node: - /* begin mathskip code */ - if (glue_ptr(p) == zero_glue) { - d = surround(p); + case hlist_node: + case vlist_node: + case rule_node: + d = width(p); + goto FOUND; + break; + case margin_kern_node: + d = width(p); + break; + case kern_node: + d = width(p); + break; + case math_node: + /* begin mathskip code */ + if (glue_ptr(p) == zero_glue) { + d = surround(p); + break; + } else { + /* fall through */ + } + /* end mathskip code */ + case glue_node: + /* We need to be careful that |w|, |v|, and |d| do not depend on any |glue_set| + values, since such values are subject to system-dependent rounding. + System-dependent numbers are not allowed to infiltrate parameters like + |pre_display_size|, since \TeX82 is supposed to make the same decisions on all + machines. + */ + q = glue_ptr(p); + d = width(q); + if (glue_sign(r) == stretching) { + if ((glue_order(r) == stretch_order(q)) + && (stretch(q) != 0)) + v = max_dimen; + } else if (glue_sign(r) == shrinking) { + if ((glue_order(r) == shrink_order(q)) + && (shrink(q) != 0)) + v = max_dimen; + } + if (subtype(p) >= a_leaders) + goto FOUND; + break; + default: + d = 0; break; - } else { - /* fall through */ - } - /* end mathskip code */ - case glue_node: - /* We need to be careful that |w|, |v|, and |d| do not depend on any |glue_set| - values, since such values are subject to system-dependent rounding. - System-dependent numbers are not allowed to infiltrate parameters like - |pre_display_size|, since \TeX82 is supposed to make the same decisions on all - machines. - */ - q = glue_ptr(p); - d = width(q); - if (glue_sign(r) == stretching) { - if ((glue_order(r) == stretch_order(q)) - && (stretch(q) != 0)) - v = max_dimen; - } else if (glue_sign(r) == shrinking) { - if ((glue_order(r) == shrink_order(q)) - && (shrink(q) != 0)) - v = max_dimen; - } - if (subtype(p) >= a_leaders) - goto found; - break; - default: - d = 0; - break; } if (v < max_dimen) v = v + d; - goto not_found; - found: + goto NOT_FOUND; + FOUND: if (v < max_dimen) { v = v + d; w = v; @@ -3416,13 +3237,12 @@ pointer actual_box_width(pointer r, scaled base_width) w = max_dimen; break; } - not_found: + NOT_FOUND: p = vlink(p); } return w; } - @ @c halfword tail_of_list(halfword p) { @@ -3432,29 +3252,26 @@ halfword tail_of_list(halfword p) return q; } - @ |delete_glue_ref| is called when a pointer to a glue specification is being withdrawn. @c -#define fast_delete_glue_ref(A) do { \ - if (glue_ref_count(A)==null) { \ - flush_node(A); \ - } else { \ - decr(glue_ref_count(A)); \ - } \ - } while (0) - void delete_glue_ref(halfword p) -{ /* |p| points to a glue specification */ - assert(type(p) == glue_spec_node); - fast_delete_glue_ref(p); +{ /* |p| points to a glue specification */ + if (type(p) == glue_spec_node) { + if (glue_ref_count(p) == null) { + flush_node(p); + } else { + decr(glue_ref_count(p)); + } + } else { + normal_error("nodes","invalid glue spec node"); + } } @ @c int var_used; -halfword temp_ptr; /* a pointer variable for occasional emergency use */ - +halfword temp_ptr; /* a pointer variable for occasional emergency use */ @ Attribute lists need two extra globals to increase processing efficiency. |max_used_attr| limits the test loop that checks for set attributes, and @@ -3464,7 +3281,7 @@ trusted: after an assignment to an attribute register, and after a group has ended. @c -int max_used_attr; /* maximum assigned attribute id */ +int max_used_attr; /* maximum assigned attribute id */ halfword attr_list_cache; @ From the computer's standpoint, \TeX's chief mission is to create @@ -3478,7 +3295,6 @@ variety, some nodes are longer than others, and we must distinguish different kinds of nodes. We do this by putting a `|type|' field in the first word, together with the link and an optional `|subtype|'. - @ Character nodes appear only in horizontal lists, never in vertical lists. An |hlist_node| stands for a box that was made from a horizontal list. @@ -3507,17 +3323,14 @@ The |subtype| field is set to |min_quarterword|, since that's the desired @c halfword new_null_box(void) { /* creates a new box node */ - halfword p; /* the new node */ - p = new_node(hlist_node, min_quarterword); + halfword p = new_node(hlist_node, min_quarterword); box_dir(p) = text_direction; return p; } - @ A |vlist_node| is like an |hlist_node| in all respects except that it contains a vertical list. - @ A |rule_node| stands for a solid black rectangle; it has |width|, |depth|, and |height| fields just as in an |hlist_node|. However, if any of these dimensions is $-2^{30}$, the actual value will be determined @@ -3532,12 +3345,10 @@ ones that are not allowed to run. @c halfword new_rule(int s) { - halfword p; /* the new node */ - p = new_node(rule_node,s); + halfword p = new_node(rule_node,s); return p; } - @ Insertions are represented by |ins_node| records, where the |subtype| indicates the corresponding box number. For example, `\.{\\insert 250}' leads to an |ins_node| whose |subtype| is |250+min_quarterword|. @@ -3593,7 +3404,6 @@ halfword new_glyph(int f, int c) return p; } - @ A subset of the glyphs nodes represent ligatures: characters fabricated from the interaction of two or more actual characters. The characters that generated the ligature have not been forgotten, since @@ -3631,12 +3441,10 @@ halfword new_char(int f, int c) set_to_character(p); font(p) = f; character(p) = c; - lang_data(p) = - make_lang_data(uc_hyph, cur_lang, left_hyphen_min, right_hyphen_min); + lang_data(p) = make_lang_data(uc_hyph, cur_lang, left_hyphen_min, right_hyphen_min); return p; } - @ Left and right ghost glyph nodes are the result of \.{\\leftghost} and \.{\\rightghost}, respectively. They are going to be removed by |new_ligkern|, at the end of which they are no longer needed. @@ -3646,15 +3454,13 @@ and \.{\\rightghost}, respectively. They are going to be removed by @c scaled glyph_width(halfword p) { - scaled w; - w = char_width(font(p), character(p)); + scaled w = char_width(font(p), character(p)); return w; } scaled glyph_height(halfword p) { - scaled w; - w = char_height(font(p), character(p)) + y_displace(p); + scaled w = char_height(font(p), character(p)) + y_displace(p); if (w < 0) w = 0; return w; @@ -3662,8 +3468,7 @@ scaled glyph_height(halfword p) scaled glyph_depth(halfword p) { - scaled w; - w = char_depth(font(p), character(p)); + scaled w = char_depth(font(p), character(p)); if (y_displace(p) > 0) w = w - y_displace(p); if (w < 0) @@ -3671,7 +3476,6 @@ scaled glyph_depth(halfword p) return w; } - @ A |disc_node|, which occurs only in horizontal lists, specifies a ``dis\-cretion\-ary'' line break. If such a break occurs at node |p|, the text that starts at |pre_break(p)| will precede the break, the text that starts at @@ -3694,8 +3498,7 @@ not chosen. @c halfword new_disc(void) { /* creates an empty |disc_node| */ - halfword p; /* the new node */ - p = new_node(disc_node, 0); + halfword p = new_node(disc_node, 0); disc_penalty(p) = int_par(hyphen_penalty_code); return p; } @@ -3724,8 +3527,7 @@ the amount of surrounding space inserted by \.{\\mathsurround}. @c halfword new_math(scaled w, int s) { - halfword p; /* the new node */ - p = new_node(math_node, s); + halfword p = new_node(math_node, s); surround(p) = w; return p; } @@ -3784,8 +3586,7 @@ to be exactly one reference to the new specification. @c halfword new_spec(halfword p) { /* duplicates a glue specification */ - halfword q; /* the new spec */ - q = copy_node(p); + halfword q = copy_node(p); glue_ref_count(q) = null; return q; } @@ -3798,10 +3599,8 @@ current \.{\\lineskip}. @c halfword new_param_glue(int n) { - halfword p; /* the new node */ - halfword q; /* the glue specification */ - p = new_node(glue_node, n + 1); - q = glue_par(n); + halfword p = new_node(glue_node, n + 1); + halfword q = glue_par(n); glue_ptr(p) = q; incr(glue_ref_count(q)); return p; @@ -3813,8 +3612,7 @@ whose argument points to a glue specification. @c halfword new_glue(halfword q) { - halfword p; /* the new node */ - p = new_node(glue_node, normal); + halfword p = new_node(glue_node, normal); glue_ptr(p) = q; incr(glue_ref_count(q)); return p; @@ -3854,8 +3652,7 @@ inserted from \.{\\mkern} specifications in math formulas). @c halfword new_kern(scaled w) { - halfword p; /* the new node */ - p = new_node(kern_node, normal); + halfword p = new_node(kern_node, normal); width(p) = w; return p; } @@ -3873,8 +3670,7 @@ be able to guess what comes next. @c halfword new_penalty(int m) { - halfword p; /* the new node */ - p = new_node(penalty_node, 0); /* the |subtype| is not used */ + halfword p = new_node(penalty_node, 0); /* the |subtype| is not used */ penalty(p) = m; return p; } @@ -3908,12 +3704,14 @@ the \.{WEB} macro definitions above, so that format changes will leave \TeX's other algorithms intact. @^system dependencies@> -@ @c +@ This function creates a |local_paragraph| node + +@c + halfword make_local_par_node(void) -/* This function creates a |local_paragraph| node */ { - halfword p, q; - p = new_node(local_par_node,0); + halfword q; + halfword p = new_node(local_par_node,0); local_pen_inter(p) = local_inter_line_penalty; local_pen_broken(p) = local_broken_penalty; if (local_left_box != null) { @@ -3929,5 +3727,3 @@ halfword make_local_par_node(void) local_par_dir(p) = par_direction; return p; } - - diff --git a/Build/source/texk/web2c/luatexdir/tex/textcodes.h b/Build/source/texk/web2c/luatexdir/tex/textcodes.h index 4249ce631b1..759d9ee740e 100644 --- a/Build/source/texk/web2c/luatexdir/tex/textcodes.h +++ b/Build/source/texk/web2c/luatexdir/tex/textcodes.h @@ -1,5 +1,5 @@ /* textcodes.h - + Copyright 2009 Taco Hoekwater <taco@luatex.org> This file is part of LuaTeX. @@ -15,31 +15,40 @@ 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/>. */ + with LuaTeX; if not, see <http://www.gnu.org/licenses/>. +*/ #ifndef TEXTCODES_H # define TEXTCODES_H +void set_cat_code(int h, int n, halfword v, quarterword gl); +halfword get_cat_code(int h, int n); +int valid_catcode_table(int h); +void unsave_cat_codes(int h, quarterword gl); +void copy_cat_codes(int from, int to); +void initex_cat_codes(int h); void set_lc_code(int n, halfword v, quarterword gl); halfword get_lc_code(int n); + void set_uc_code(int n, halfword v, quarterword gl); halfword get_uc_code(int n); + void set_sf_code(int n, halfword v, quarterword gl); halfword get_sf_code(int n); -void set_cat_code(int h, int n, halfword v, quarterword gl); -halfword get_cat_code(int h, int n); -void unsave_cat_codes(int h, quarterword gl); -int valid_catcode_table(int h); -void initex_cat_codes(int h); -void unsave_text_codes(quarterword grouplevel); + +void set_hj_code(int l, int n, halfword v, quarterword gl); +halfword get_hj_code(int l, int n); +void hj_codes_from_lc_codes(int h); + void initialize_text_codes(void); +void unsave_text_codes(quarterword grouplevel); + void dump_text_codes(void); void undump_text_codes(void); -void copy_cat_codes(int from, int to); + void free_math_codes(void); void free_text_codes(void); - #endif diff --git a/Build/source/texk/web2c/luatexdir/tex/textcodes.w b/Build/source/texk/web2c/luatexdir/tex/textcodes.w index 6487e821c70..8a4fbb949c5 100644 --- a/Build/source/texk/web2c/luatexdir/tex/textcodes.w +++ b/Build/source/texk/web2c/luatexdir/tex/textcodes.w @@ -19,37 +19,178 @@ @ @c - #include "ptexlib.h" -@ @c -#define LCCODESTACK 8 -#define LCCODEDEFAULT 0 +@ catcodes @c -static sa_tree lccode_head = NULL; +#define CATCODESTACK 8 +#define CATCODEDEFAULT 12 +#define CATCODE_MAX 32767 -#define UCCODESTACK 8 -#define UCCODEDEFAULT 0 +static sa_tree *catcode_heads = NULL; +static int catcode_max = 0; +static unsigned char *catcode_valid = NULL; -static sa_tree uccode_head = NULL; +void set_cat_code(int h, int n, halfword v, quarterword gl) +{ + sa_tree_item sa_value = { 0 }; + sa_tree s = catcode_heads[h]; + if (h > catcode_max) + catcode_max = h; + if (s == NULL) { + sa_value.int_value = CATCODEDEFAULT; + s = new_sa_tree(CATCODESTACK, 1, sa_value); + catcode_heads[h] = s; + } + sa_value.int_value = (int) v; + set_sa_item(s, n, sa_value, gl); +} -#define SFCODESTACK 8 -#define SFCODEDEFAULT 1000 +halfword get_cat_code(int h, int n) +{ + sa_tree_item sa_value = { 0 }; + sa_tree s = catcode_heads[h]; + if (h > catcode_max) + catcode_max = h; + if (s == NULL) { + sa_value.int_value = CATCODEDEFAULT; + s = new_sa_tree(CATCODESTACK, 1, sa_value); + catcode_heads[h] = s; + } + return (halfword) get_sa_item(s, n).int_value; +} -static sa_tree sfcode_head = NULL; +void unsave_cat_codes(int h, quarterword gl) +{ + int k; + if (h > catcode_max) + catcode_max = h; + for (k = 0; k <= catcode_max; k++) { + if (catcode_heads[k] != NULL) + restore_sa_stack(catcode_heads[k], gl); + } +} -#define CATCODESTACK 8 -#define CATCODEDEFAULT 12 +static void initializecatcodes(void) +{ + sa_tree_item sa_value = { 0 }; + catcode_max = 0; + catcode_heads = Mxmalloc_array(sa_tree, (CATCODE_MAX + 1)); + catcode_valid = Mxmalloc_array(unsigned char, (CATCODE_MAX + 1)); + memset(catcode_heads, 0, sizeof(sa_tree) * (CATCODE_MAX + 1)); + memset(catcode_valid, 0, sizeof(unsigned char) * (CATCODE_MAX + 1)); + catcode_valid[0] = 1; + sa_value.int_value = CATCODEDEFAULT; + catcode_heads[0] = new_sa_tree(CATCODESTACK, 1, sa_value); +} +static void dumpcatcodes(void) +{ + int total = 0; + int k; + for (k = 0; k <= catcode_max; k++) { + if (catcode_valid[k]) { + total++; + } + } + dump_int(catcode_max); + dump_int(total); + for (k = 0; k <= catcode_max; k++) { + if (catcode_valid[k]) { + dump_int(k); + dump_sa_tree(catcode_heads[k]); + } + } +} + +static void undumpcatcodes(void) +{ + int total, k, x; + xfree(catcode_heads); + xfree(catcode_valid); + catcode_heads = Mxmalloc_array(sa_tree, (CATCODE_MAX + 1)); + catcode_valid = Mxmalloc_array(unsigned char, (CATCODE_MAX + 1)); + memset(catcode_heads, 0, sizeof(sa_tree) * (CATCODE_MAX + 1)); + memset(catcode_valid, 0, sizeof(unsigned char) * (CATCODE_MAX + 1)); + undump_int(catcode_max); + undump_int(total); + for (k = 0; k < total; k++) { + undump_int(x); + catcode_heads[x] = undump_sa_tree(); + catcode_valid[x] = 1; + } +} + +int valid_catcode_table(int h) +{ + if (h <= CATCODE_MAX && h >= 0 && catcode_valid[h]) { + return 1; + } + return 0; +} + +void copy_cat_codes(int from, int to) +{ + if (from < 0 || from > CATCODE_MAX || catcode_valid[from] == 0) { + uexit(1); + } + if (to > catcode_max) + catcode_max = to; + destroy_sa_tree(catcode_heads[to]); + catcode_heads[to] = copy_sa_tree(catcode_heads[from]); + catcode_valid[to] = 1; +} + +void initex_cat_codes(int h) +{ + int k; + if (h > catcode_max) + catcode_max = h; + destroy_sa_tree(catcode_heads[h]); + catcode_heads[h] = NULL; + set_cat_code(h, '\r', car_ret_cmd, 1); + set_cat_code(h, ' ', spacer_cmd, 1); + set_cat_code(h, '\\', escape_cmd, 1); + set_cat_code(h, '%', comment_cmd, 1); + set_cat_code(h, 127, invalid_char_cmd, 1); + set_cat_code(h, 0, ignore_cmd, 1); + set_cat_code(h, 0xFEFF, ignore_cmd, 1); + for (k = 'A'; k <= 'Z'; k++) { + set_cat_code(h, k, letter_cmd, 1); + set_cat_code(h, k + 'a' - 'A', letter_cmd, 1); + } + catcode_valid[h] = 1; +} + +static void freecatcodes(void) +{ + int k; + for (k = 0; k <= catcode_max; k++) { + if (catcode_valid[k]) { + destroy_sa_tree(catcode_heads[k]); + } + } + xfree(catcode_heads); + xfree(catcode_valid); +} + +@ lccodes @c + +#define LCCODESTACK 8 +#define LCCODEDEFAULT 0 + +static sa_tree lccode_head = NULL; void set_lc_code(int n, halfword v, quarterword gl) { - set_sa_item(lccode_head, n, (sa_tree_item) v, gl); + sa_tree_item sa_value = { 0 }; + sa_value.int_value = (int) v; + set_sa_item(lccode_head, n, sa_value, gl); } halfword get_lc_code(int n) { - return (halfword) get_sa_item(lccode_head, n); + return (halfword) get_sa_item(lccode_head, n).int_value; } static void unsavelccodes(quarterword gl) @@ -59,7 +200,9 @@ static void unsavelccodes(quarterword gl) static void initializelccodes(void) { - lccode_head = new_sa_tree(LCCODESTACK, LCCODEDEFAULT); + sa_tree_item sa_value = { 0 }; + sa_value.int_value = LCCODEDEFAULT; + lccode_head = new_sa_tree(LCCODESTACK, 1, sa_value); } static void dumplccodes(void) @@ -72,14 +215,28 @@ static void undumplccodes(void) lccode_head = undump_sa_tree(); } +static void freelccodes(void) +{ + destroy_sa_tree(lccode_head); +} + +@ uccodes @c + +#define UCCODESTACK 8 +#define UCCODEDEFAULT 0 + +static sa_tree uccode_head = NULL; + void set_uc_code(int n, halfword v, quarterword gl) { - set_sa_item(uccode_head, n, (sa_tree_item) v, gl); + sa_tree_item sa_value = { 0 }; + sa_value.int_value = (int) v; + set_sa_item(uccode_head, n, sa_value, gl); } halfword get_uc_code(int n) { - return (halfword) get_sa_item(uccode_head, n); + return (halfword) get_sa_item(uccode_head, n).int_value; } static void unsaveuccodes(quarterword gl) @@ -89,7 +246,9 @@ static void unsaveuccodes(quarterword gl) static void initializeuccodes(void) { - uccode_head = new_sa_tree(UCCODESTACK, UCCODEDEFAULT); + sa_tree_item sa_value = { 0 }; + sa_value.int_value = UCCODEDEFAULT; + uccode_head = new_sa_tree(UCCODESTACK, 1, sa_value); } static void dumpuccodes(void) @@ -102,14 +261,28 @@ static void undumpuccodes(void) uccode_head = undump_sa_tree(); } +static void freeuccodes(void) +{ + destroy_sa_tree(uccode_head); +} + +@ sfcodes @c + +#define SFCODESTACK 8 +#define SFCODEDEFAULT 1000 + +static sa_tree sfcode_head = NULL; + void set_sf_code(int n, halfword v, quarterword gl) { - set_sa_item(sfcode_head, n, (sa_tree_item) v, gl); + sa_tree_item sa_value = { 0 }; + sa_value.int_value = (int) v; + set_sa_item(sfcode_head, n, sa_value, gl); } halfword get_sf_code(int n) { - return (halfword) get_sa_item(sfcode_head, n); + return (halfword) get_sa_item(sfcode_head, n).int_value; } static void unsavesfcodes(quarterword gl) @@ -119,7 +292,9 @@ static void unsavesfcodes(quarterword gl) static void initializesfcodes(void) { - sfcode_head = new_sa_tree(SFCODESTACK, SFCODEDEFAULT); + sa_tree_item sa_value = { 0 }; + sa_value.int_value = SFCODEDEFAULT; + sfcode_head = new_sa_tree(SFCODESTACK, 1, sa_value); } static void dumpsfcodes(void) @@ -132,188 +307,180 @@ static void undumpsfcodes(void) sfcode_head = undump_sa_tree(); } +static void freesfcodes(void) +{ + destroy_sa_tree(sfcode_head); +} -static sa_tree *catcode_heads = NULL; -static int catcode_max = 0; -static unsigned char *catcode_valid = NULL; +@ hjcodes @c -#define CATCODE_MAX 32767 +#define HJCODESTACK 8 +#define HJCODEDEFAULT 0 +#define HJCODE_MAX 16383 /* number of languages */ -#define update_catcode_max(h) if (h > catcode_max) catcode_max = h +static sa_tree *hjcode_heads = NULL; +static int hjcode_max = 0; +static unsigned char *hjcode_valid = NULL; -void set_cat_code(int h, int n, halfword v, quarterword gl) +@ Here we set codes but we don't initialize from lccodes. + +@c void set_hj_code(int h, int n, halfword v, quarterword gl) { - sa_tree s = catcode_heads[h]; - update_catcode_max(h); + sa_tree_item sa_value = { 0 }; + sa_tree s = hjcode_heads[h]; + if (h > hjcode_max) + hjcode_max = h; if (s == NULL) { - s = new_sa_tree(CATCODESTACK, CATCODEDEFAULT); - catcode_heads[h] = s; + sa_value.int_value = HJCODEDEFAULT; + s = new_sa_tree(HJCODESTACK, 1, sa_value); + hjcode_heads[h] = s; } - set_sa_item(s, n, (sa_tree_item) v, gl); + sa_value.int_value = (int) v; + set_sa_item(s, n, sa_value, gl); } -halfword get_cat_code(int h, int n) +@ We just return the lccodes when nothing is set. + +@c halfword get_hj_code(int h, int n) { - sa_tree s = catcode_heads[h]; - update_catcode_max(h); + sa_tree s = hjcode_heads[h]; if (s == NULL) { - s = new_sa_tree(CATCODESTACK, CATCODEDEFAULT); - catcode_heads[h] = s; + s = lccode_head; } - return (halfword) get_sa_item(s, n); + return (halfword) get_sa_item(s, n).int_value; } -void unsave_cat_codes(int h, quarterword gl) -{ - int k; - update_catcode_max(h); - for (k = 0; k <= catcode_max; k++) { - if (catcode_heads[k] != NULL) - restore_sa_stack(catcode_heads[k], gl); - } -} +@ We don't restore as we can have more languages in a paragraph +and hyphenation takes place at a later stage so we would get +weird grouping side effects .. so, one can overload settings +but management is then upto the used, so no: + +@c +/* + static void unsavehjcodes(quarterword gl) { } +*/ -#if 0 -static void clearcatcodestack(int h) +static void initializehjcodes(void) { - clear_sa_stack(catcode_heads[h]); + sa_tree_item sa_value = { 0 }; + hjcode_max = 0; + hjcode_heads = Mxmalloc_array(sa_tree, (HJCODE_MAX + 1)); + hjcode_valid = Mxmalloc_array(unsigned char, (HJCODE_MAX + 1)); + memset(hjcode_heads, 0, sizeof(sa_tree) * (HJCODE_MAX + 1)); + memset(hjcode_valid, 0, sizeof(unsigned char) * (HJCODE_MAX + 1)); + hjcode_valid[0] = 1; + sa_value.int_value = HJCODEDEFAULT; + hjcode_heads[0] = new_sa_tree(HJCODESTACK, 1, sa_value); } -#endif -static void initializecatcodes(void) +void hj_codes_from_lc_codes(int h) { - catcode_max = 0; -#if 0 - xfree(catcode_heads); /* not needed */ - xfree(catcode_valid); -#endif - catcode_heads = Mxmalloc_array(sa_tree, (CATCODE_MAX + 1)); - catcode_valid = Mxmalloc_array(unsigned char, (CATCODE_MAX + 1)); - memset(catcode_heads, 0, sizeof(sa_tree) * (CATCODE_MAX + 1)); - memset(catcode_valid, 0, sizeof(unsigned char) * (CATCODE_MAX + 1)); - catcode_valid[0] = 1; - catcode_heads[0] = new_sa_tree(CATCODESTACK, CATCODEDEFAULT); + sa_tree_item sa_value = { 0 }; + sa_tree s = hjcode_heads[h]; + if (s != NULL) { + destroy_sa_tree(s); + } else if (h > hjcode_max) { + hjcode_max = h; + } + if (s == NULL) { + sa_value.int_value = HJCODEDEFAULT; + s = new_sa_tree(HJCODESTACK, 1, sa_value); + hjcode_heads[h] = s; + } + hjcode_heads[h] = copy_sa_tree(lccode_head); + hjcode_valid[h] = 1; } -static void dumpcatcodes(void) +static void dumphjcodes(void) { - int k, total; - dump_int(catcode_max); - total = 0; - for (k = 0; k <= catcode_max; k++) { - if (catcode_valid[k]) { + int total = 0; + int k; + for (k = 0; k <= hjcode_max; k++) { + if (hjcode_valid[k]) { total++; } } + dump_int(hjcode_max); dump_int(total); - for (k = 0; k <= catcode_max; k++) { - if (catcode_valid[k]) { + for (k = 0; k <= hjcode_max; k++) { + if (hjcode_valid[k]) { dump_int(k); - dump_sa_tree(catcode_heads[k]); + dump_sa_tree(hjcode_heads[k]); } } } -static void undumpcatcodes(void) +static void undumphjcodes(void) { int total, k, x; - xfree(catcode_heads); - xfree(catcode_valid); - catcode_heads = Mxmalloc_array(sa_tree, (CATCODE_MAX + 1)); - catcode_valid = Mxmalloc_array(unsigned char, (CATCODE_MAX + 1)); - memset(catcode_heads, 0, sizeof(sa_tree) * (CATCODE_MAX + 1)); - memset(catcode_valid, 0, sizeof(unsigned char) * (CATCODE_MAX + 1)); - undump_int(catcode_max); + xfree(hjcode_heads); + xfree(hjcode_valid); + hjcode_heads = Mxmalloc_array(sa_tree, (HJCODE_MAX + 1)); + hjcode_valid = Mxmalloc_array(unsigned char, (HJCODE_MAX + 1)); + memset(hjcode_heads, 0, sizeof(sa_tree) * (HJCODE_MAX + 1)); + memset(hjcode_valid, 0, sizeof(unsigned char) * (HJCODE_MAX + 1)); + undump_int(hjcode_max); undump_int(total); for (k = 0; k < total; k++) { undump_int(x); - catcode_heads[x] = undump_sa_tree(); - catcode_valid[x] = 1; + hjcode_heads[x] = undump_sa_tree(); + hjcode_valid[x] = 1; } } -int valid_catcode_table(int h) -{ - if (h <= CATCODE_MAX && h >= 0 && catcode_valid[h]) { - return 1; - } - return 0; -} - -void copy_cat_codes(int from, int to) -{ - if (from < 0 || from > CATCODE_MAX || catcode_valid[from] == 0) { - uexit(1); - } - update_catcode_max(to); - destroy_sa_tree(catcode_heads[to]); - catcode_heads[to] = copy_sa_tree(catcode_heads[from]); - catcode_valid[to] = 1; -} - -void initex_cat_codes(int h) +static void freehjcodes(void) { int k; - update_catcode_max(h); - destroy_sa_tree(catcode_heads[h]); - catcode_heads[h] = NULL; - set_cat_code(h, '\r', car_ret_cmd, 1); - set_cat_code(h, ' ', spacer_cmd, 1); - set_cat_code(h, '\\', escape_cmd, 1); - set_cat_code(h, '%', comment_cmd, 1); - set_cat_code(h, 127, invalid_char_cmd, 1); - set_cat_code(h, 0, ignore_cmd, 1); - set_cat_code(h, 0xFEFF, ignore_cmd, 1); - for (k = 'A'; k <= 'Z'; k++) { - set_cat_code(h, k, letter_cmd, 1); - set_cat_code(h, k + 'a' - 'A', letter_cmd, 1); + for (k = 0; k <= hjcode_max; k++) { + if (hjcode_valid[k]) { + destroy_sa_tree(hjcode_heads[k]); + } } - catcode_valid[h] = 1; + xfree(hjcode_heads); + xfree(hjcode_valid); } +/* management */ + void unsave_text_codes(quarterword grouplevel) { - unsavesfcodes(grouplevel); - unsaveuccodes(grouplevel); unsavelccodes(grouplevel); + unsaveuccodes(grouplevel); + unsavesfcodes(grouplevel); } void initialize_text_codes(void) { - initializesfcodes(); - initializeuccodes(); initializecatcodes(); initializelccodes(); + initializeuccodes(); + initializesfcodes(); + initializehjcodes(); } void free_text_codes(void) { - int k; - destroy_sa_tree(lccode_head); - destroy_sa_tree(uccode_head); - destroy_sa_tree(sfcode_head); - for (k = 0; k <= catcode_max; k++) { - if (catcode_valid[k]) { - destroy_sa_tree(catcode_heads[k]); - } - } - xfree(catcode_heads); - xfree(catcode_valid); + freecatcodes(); + freelccodes(); + freeuccodes(); + freesfcodes(); + freehjcodes(); } - void dump_text_codes(void) { - dumpsfcodes(); - dumpuccodes(); - dumplccodes(); dumpcatcodes(); + dumplccodes(); + dumpuccodes(); + dumpsfcodes(); + dumphjcodes(); } void undump_text_codes(void) { - undumpsfcodes(); - undumpuccodes(); - undumplccodes(); undumpcatcodes(); + undumplccodes(); + undumpuccodes(); + undumpsfcodes(); + undumphjcodes(); } diff --git a/Build/source/texk/web2c/luatexdir/tex/textoken.h b/Build/source/texk/web2c/luatexdir/tex/textoken.h index 241d672264f..71c5777e1dc 100644 --- a/Build/source/texk/web2c/luatexdir/tex/textoken.h +++ b/Build/source/texk/web2c/luatexdir/tex/textoken.h @@ -151,6 +151,7 @@ extern void get_token(void); extern halfword str_toks(lstring b); extern halfword str_scan_toks(int c, lstring b); extern void ins_the_toks(void); +extern void combine_the_toks(int how); extern int scan_lua_state(void); diff --git a/Build/source/texk/web2c/luatexdir/tex/textoken.w b/Build/source/texk/web2c/luatexdir/tex/textoken.w index 43445721435..0c11bb0f290 100644 --- a/Build/source/texk/web2c/luatexdir/tex/textoken.w +++ b/Build/source/texk/web2c/luatexdir/tex/textoken.w @@ -31,6 +31,7 @@ #define every_eof equiv(every_eof_loc) #define box(A) equiv(box_base+(A)) +#define toks(A) equiv(toks_base+(A)) #define detokenized_line() (line_catcode_table==NO_CAT_TABLE) @@ -42,19 +43,18 @@ } while (0) -@ The \TeX\ system does nearly all of its own memory allocation, so that it -can readily be transported into environments that do not have automatic -facilities for strings, garbage collection, etc., and so that it can be in -control of what error messages the user receives. The dynamic storage -requirements of \TeX\ are handled by providing two large arrays called -|fixmem| and |varmem| in which consecutive blocks of words are used as -nodes by the \TeX\ routines. +@ The \TeX\ system does nearly all of its own memory allocation, so that it can +readily be transported into environments that do not have automatic facilities +for strings, garbage collection, etc., and so that it can be in control of what +error messages the user receives. The dynamic storage requirements of \TeX\ are +handled by providing two large arrays called |fixmem| and |varmem| in which +consecutive blocks of words are used as nodes by the \TeX\ routines. -Pointer variables are indices into this array, or into another array -called |eqtb| that will be explained later. A pointer variable might -also be a special flag that lies outside the bounds of |mem|, so we -allow pointers to assume any |halfword| value. The minimum halfword -value represents a null pointer. \TeX\ does not assume that |mem[null]| exists. +Pointer variables are indices into this array, or into another array called +|eqtb| that will be explained later. A pointer variable might also be a special +flag that lies outside the bounds of |mem|, so we allow pointers to assume any +|halfword| value. The minimum halfword value represents a null pointer. \TeX\ +does not assume that |mem[null]| exists. @ Locations in |fixmem| are used for storing one-word records; a conventional \.{AVAIL} stack is used for allocation in this array. @@ -64,11 +64,11 @@ smemory_word *fixmem; /* the big dynamic storage area */ unsigned fix_mem_min; /* the smallest location of one-word memory in use */ unsigned fix_mem_max; /* the largest location of one-word memory in use */ -@ In order to study the memory requirements of particular applications, it -is possible to prepare a version of \TeX\ that keeps track of current and -maximum memory usage. When code between the delimiters |@!stat| $\ldots$ -|tats| is not ``commented out,'' \TeX\ will run a bit slower but it will -report these statistics when |tracing_stats| is sufficiently large. +@ In order to study the memory requirements of particular applications, it is +possible to prepare a version of \TeX\ that keeps track of current and maximum +memory usage. When code between the delimiters |@!stat| $\ldots$ |tats| is not +commented out, \TeX\ will run a bit slower but it will report these statistics +when |tracing_stats| is sufficiently large. @c int var_used, dyn_used; /* how much memory is in use */ @@ -110,14 +110,14 @@ void initialize_tokens(void) dyn_used = 0; /* initialize statistics */ } -@ The function |get_avail| returns a pointer to a new one-word node whose -|link| field is null. However, \TeX\ will halt if there is no more room left. +@ The function |get_avail| returns a pointer to a new one-word node whose |link| +field is null. However, \TeX\ will halt if there is no more room left. @^inner loop@> -If the available-space list is empty, i.e., if |avail=null|, -we try first to increase |fix_mem_end|. If that cannot be done, i.e., if -|fix_mem_end=fix_mem_max|, we try to reallocate array |fixmem|. -If, that doesn't work, we have to quit. +If the available-space list is empty, i.e., if |avail=null|, we try first to +increase |fix_mem_end|. If that cannot be done, i.e., if +|fix_mem_end=fix_mem_max|, we try to reallocate array |fixmem|. If, that doesn't +work, we have to quit. @c halfword get_avail(void) @@ -151,8 +151,8 @@ halfword get_avail(void) return (halfword) p; } -@ The procedure |flush_list(p)| frees an entire linked list of -one-word nodes that starts at position |p|. +@ The procedure |flush_list(p)| frees an entire linked list of one-word nodes +that starts at position |p|. @^inner loop@> @c @@ -171,46 +171,45 @@ void flush_list(halfword p) } } -@ A \TeX\ token is either a character or a control sequence, and it is -@^token@> -represented internally in one of two ways: (1)~A character whose ASCII -code number is |c| and whose command code is |m| is represented as the -number $2^{21}m+c$; the command code is in the range |1<=m<=14|. (2)~A control -sequence whose |eqtb| address is |p| is represented as the number -|cs_token_flag+p|. Here |cs_token_flag=@t$2^{25}-1$@>| is larger than -$2^{21}m+c$, yet it is small enough that |cs_token_flag+p< max_halfword|; -thus, a token fits comfortably in a halfword. +@ A \TeX\ token is either a character or a control sequence, and it is @^token@> +represented internally in one of two ways: (1)~A character whose ASCII code +number is |c| and whose command code is |m| is represented as the number +$2^{21}m+c$; the command code is in the range |1<=m<=14|. (2)~A control sequence +whose |eqtb| address is |p| is represented as the number |cs_token_flag+p|. Here +|cs_token_flag=@t$2^{25}-1$@>| is larger than $2^{21}m+c$, yet it is small enough +that |cs_token_flag+p< max_halfword|; thus, a token fits comfortably in a +halfword. A token |t| represents a |left_brace| command if and only if -|t<left_brace_limit|; it represents a |right_brace| command if and only if -we have |left_brace_limit<=t<right_brace_limit|; and it represents a |match| or -|end_match| command if and only if |match_token<=t<=end_match_token|. -The following definitions take care of these token-oriented constants -and a few others. - -@ A token list is a singly linked list of one-word nodes in |mem|, where -each word contains a token and a link. Macro definitions, output-routine -definitions, marks, \.{\\write} texts, and a few other things -are remembered by \TeX\ in the form -of token lists, usually preceded by a node with a reference count in its -|token_ref_count| field. The token stored in location |p| is called -|info(p)|. - -Three special commands appear in the token lists of macro definitions. -When |m=match|, it means that \TeX\ should scan a parameter -for the current macro; when |m=end_match|, it means that parameter -matching should end and \TeX\ should start reading the macro text; and -when |m=out_param|, it means that \TeX\ should insert parameter -number |c| into the text at this point. - -The enclosing \.{\char'173} and \.{\char'175} characters of a macro -definition are omitted, but the final right brace of an output routine -is included at the end of its token list. - -Here is an example macro definition that illustrates these conventions. -After \TeX\ processes the text +|t<left_brace_limit|; it represents a |right_brace| command if and only if we +have |left_brace_limit<=t<right_brace_limit|; and it represents a |match| or +|end_match| command if and only if |match_token<=t<=end_match_token|. The +following definitions take care of these token-oriented constants and a few +others. + +@ A token list is a singly linked list of one-word nodes in |mem|, where each +word contains a token and a link. Macro definitions, output-routine definitions, +marks, \.{\\write} texts, and a few other things are remembered by \TeX\ in the +form of token lists, usually preceded by a node with a reference count in its +|token_ref_count| field. The token stored in location |p| is called |info(p)|. + +Three special commands appear in the token lists of macro definitions. When +|m=match|, it means that \TeX\ should scan a parameter for the current macro; +when |m=end_match|, it means that parameter matching should end and \TeX\ should +start reading the macro text; and when |m=out_param|, it means that \TeX\ should +insert parameter number |c| into the text at this point. + +The enclosing \.{\char'173} and \.{\char'175} characters of a macro definition +are omitted, but the final right brace of an output routine is included at the +end of its token list. + +Here is an example macro definition that illustrates these conventions. After +\TeX\ processes the text + $$\.{\\def\\mac a\#1\#2 \\b \{\#1\\-a \#\#1\#2 \#2\}}$$ + the definition of \.{\\mac} is represented as a token list containing + $$\def\,{\hskip2pt} \vbox{\halign{\hfil#\hfil\cr (reference count), |letter|\,\.a, |match|\,\#, |match|\,\#, |spacer|\,\.\ , @@ -218,25 +217,23 @@ $$\def\,{\hskip2pt} |out_param|\,1, \.{\\-}, |letter|\,\.a, |spacer|\,\.\ , |mac_param|\,\#, |other_char|\,\.1,\cr |out_param|\,2, |spacer|\,\.\ , |out_param|\,2.\cr}}$$ -The procedure |scan_toks| builds such token lists, and |macro_call| -does the parameter matching. -@^reference counts@> -Examples such as -$$\.{\\def\\m\{\\def\\m\{a\}\ b\}}$$ -explain why reference counts would be needed even if \TeX\ had no \.{\\let} -operation: When the token list for \.{\\m} is being read, the redefinition of -\.{\\m} changes the |eqtb| entry before the token list has been fully -consumed, so we dare not simply destroy a token list when its -control sequence is being redefined. +The procedure |scan_toks| builds such token lists, and |macro_call| does the +parameter matching. @^reference counts@> + +Examples such as $$\.{\\def\\m\{\\def\\m\{a\}\ b\}}$$ explain why reference +counts would be needed even if \TeX\ had no \.{\\let} operation: When the token +list for \.{\\m} is being read, the redefinition of \.{\\m} changes the |eqtb| +entry before the token list has been fully consumed, so we dare not simply +destroy a token list when its control sequence is being redefined. -If the parameter-matching part of a definition ends with `\.{\#\{}', -the corresponding token list will have `\.\{' just before the `|end_match|' -and also at the very end. The first `\.\{' is used to delimit the parameter; the -second one keeps the first from disappearing. +If the parameter-matching part of a definition ends with `\.{\#\{}', the +corresponding token list will have `\.\{' just before the `|end_match|' and also +at the very end. The first `\.\{' is used to delimit the parameter; the second +one keeps the first from disappearing. -The |print_meaning| subroutine displays |cur_cmd| and |cur_chr| in -symbolic form, including the expansion of a macro or mark. +The |print_meaning| subroutine displays |cur_cmd| and |cur_chr| in symbolic form, +including the expansion of a macro or mark. @c void print_meaning(void) @@ -272,31 +269,29 @@ void print_meaning(void) } } -@ The procedure |show_token_list|, which prints a symbolic form of -the token list that starts at a given node |p|, illustrates these -conventions. The token list being displayed should not begin with a reference -count. However, the procedure is intended to be robust, so that if the -memory links are awry or if |p| is not really a pointer to a token list, -nothing catastrophic will happen. - -An additional parameter |q| is also given; this parameter is either null -or it points to a node in the token list where a certain magic computation -takes place that will be explained later. (Basically, |q| is non-null when -we are printing the two-line context information at the time of an error -message; |q| marks the place corresponding to where the second line -should begin.) - -For example, if |p| points to the node containing the first \.a in the -token list above, then |show_token_list| will print the string -$$\hbox{`\.{a\#1\#2\ \\b\ ->\#1\\-a\ \#\#1\#2\ \#2}';}$$ -and if |q| points to the node containing the second \.a, -the magic computation will be performed just before the second \.a is printed. - -The generation will stop, and `\.{\\ETC.}' will be printed, if the length -of printing exceeds a given limit~|l|. Anomalous entries are printed in the -form of control sequences that are not followed by a blank space, e.g., -`\.{\\BAD.}'; this cannot be confused with actual control sequences because -a real control sequence named \.{BAD} would come out `\.{\\BAD\ }'. +@ The procedure |show_token_list|, which prints a symbolic form of the token list +that starts at a given node |p|, illustrates these conventions. The token list +being displayed should not begin with a reference count. However, the procedure +is intended to be robust, so that if the memory links are awry or if |p| is not +really a pointer to a token list, nothing catastrophic will happen. + +An additional parameter |q| is also given; this parameter is either null or it +points to a node in the token list where a certain magic computation takes place +that will be explained later. (Basically, |q| is non-null when we are printing +the two-line context information at the time of an error message; |q| marks the +place corresponding to where the second line should begin.) + +For example, if |p| points to the node containing the first \.a in the token list +above, then |show_token_list| will print the string $$\hbox{`\.{a\#1\#2\ \\b\ +->\#1\\-a\ \#\#1\#2\ \#2}';}$$ and if |q| points to the node containing the +second \.a, the magic computation will be performed just before the second \.a is +printed. + +The generation will stop, and `\.{\\ETC.}' will be printed, if the length of +printing exceeds a given limit~|l|. Anomalous entries are printed in the form of +control sequences that are not followed by a blank space, e.g., `\.{\\BAD.}'; +this cannot be confused with actual control sequences because a real control +sequence named \.{BAD} would come out `\.{\\BAD\ }'. @c #define not_so_bad(p) \ @@ -320,11 +315,9 @@ a real control sequence named \.{BAD} would come out `\.{\\BAD\ }'. void show_token_list(int p, int q, int l) { - int m, c; /* pieces of a token */ - ASCII_code match_chr; /* character used in a `|match|' */ - ASCII_code n; /* the highest parameter number, as an ASCII digit */ - match_chr = '#'; - n = '0'; + int m, c; /* pieces of a token */ + ASCII_code match_chr = '#'; /* character used in a `|match|' */ + ASCII_code n = '0'; /* the highest parameter number, as an ASCII digit */ tally = 0; if (l < 0) l = 0x3FFFFFFF; @@ -347,51 +340,54 @@ void show_token_list(int p, int q, int l) if (token_info(p) < 0) { tprint_esc("BAD"); } else { - /* Display the token $(|m|,|c|)$ */ - /* The procedure usually ``learns'' the character code used for macro - parameters by seeing one in a |match| command before it runs into any - |out_param| commands. */ + /* + Display the token $(|m|,|c|)$ + + The procedure usually ``learns'' the character code used for macro + parameters by seeing one in a |match| command before it runs into any + |out_param| commands. + */ switch (m) { - case left_brace_cmd: - case right_brace_cmd: - case math_shift_cmd: - case tab_mark_cmd: - case sup_mark_cmd: - case sub_mark_cmd: - case spacer_cmd: - case letter_cmd: - case other_char_cmd: - print(c); - break; - case mac_param_cmd: - if (!in_lua_escape && (is_in_csname==0)) + case left_brace_cmd: + case right_brace_cmd: + case math_shift_cmd: + case tab_mark_cmd: + case sup_mark_cmd: + case sub_mark_cmd: + case spacer_cmd: + case letter_cmd: + case other_char_cmd: print(c); - print(c); - break; - case out_param_cmd: - print(match_chr); - if (c <= 9) { - print_char(c + '0'); - } else { - print_char('!'); - return; - } - break; - case match_cmd: - match_chr = c; - print(c); - incr(n); - print_char(n); - if (n > '9') - return; - break; - case end_match_cmd: - if (c == 0) - tprint("->"); - break; - default: - not_so_bad(tprint); - break; + break; + case mac_param_cmd: + if (!in_lua_escape && (is_in_csname==0)) + print(c); + print(c); + break; + case out_param_cmd: + print(match_chr); + if (c <= 9) { + print_char(c + '0'); + } else { + print_char('!'); + return; + } + break; + case match_cmd: + match_chr = c; + print(c); + incr(n); + print_char(n); + if (n > '9') + return; + break; + case end_match_cmd: + if (c == 0) + tprint("->"); + break; + default: + not_so_bad(tprint); + break; } } } @@ -402,14 +398,13 @@ void show_token_list(int p, int q, int l) } @ @c -#define do_buffer_to_unichar(a,b) do { \ - a = (halfword)str2uni(buffer+b); \ - b += utf8_size(a); \ - } while (0) - +#define do_buffer_to_unichar(a,b) do { \ + a = (halfword)str2uni(buffer+b); \ + b += utf8_size(a); \ +} while (0) -@ Here's the way we sometimes want to display a token list, given a pointer -to its reference count; the pointer may be null. +@ Here's the way we sometimes want to display a token list, given a pointer to +its reference count; the pointer may be null. @c void token_show(halfword p) @@ -418,17 +413,17 @@ void token_show(halfword p) show_token_list(token_link(p), null, 10000000); } -@ |delete_token_ref|, is called when -a pointer to a token list's reference count is being removed. This means -that the token list should disappear if the reference count was |null|, -otherwise the count should be decreased by one. +@ |delete_token_ref|, is called when a pointer to a token list's reference count +is being removed. This means that the token list should disappear if the +reference count was |null|, otherwise the count should be decreased by one. @^reference counts@> +@ |p| points to the reference count of a token list that is losing one +reference. + @c void delete_token_ref(halfword p) -{ /* |p| points to the reference count - of a token list that is losing one reference */ - assert(token_ref_count(p) >= 0); +{ if (token_ref_count(p) == 0) flush_list(p); else @@ -446,8 +441,8 @@ int get_char_cat_code(int curchr) @ @c static void invalid_character_error(void) { - const char *hlp[] = - { "A funny symbol that I can't read has just been input.", + const char *hlp[] = { + "A funny symbol that I can't read has just been input.", "Continue, and I'll forget that it ever happened.", NULL }; @@ -461,26 +456,26 @@ static boolean process_sup_mark(void); /* below */ static int scan_control_sequence(void); /* below */ -typedef enum { next_line_ok, next_line_return, +typedef enum { + next_line_ok, + next_line_return, next_line_restart } next_line_retval; -static next_line_retval next_line(void); /* below */ +static next_line_retval next_line(void); /* below */ -@ In case you are getting bored, here is a slightly less trivial routine: - Given a string of lowercase letters, like `\.{pt}' or `\.{plus}' or - `\.{width}', the |scan_keyword| routine checks to see whether the next - tokens of input match this string. The match must be exact, except that - uppercase letters will match their lowercase counterparts; uppercase - equivalents are determined by subtracting |"a"-"A"|, rather than using the - |uc_code| table, since \TeX\ uses this routine only for its own limited - set of keywords. +@ In case you are getting bored, here is a slightly less trivial routine: Given a +string of lowercase letters, like `\.{pt}' or `\.{plus}' or `\.{width}', the +|scan_keyword| routine checks to see whether the next tokens of input match this +string. The match must be exact, except that uppercase letters will match their +lowercase counterparts; uppercase equivalents are determined by subtracting +|"a"-"A"|, rather than using the |uc_code| table, since \TeX\ uses this routine +only for its own limited set of keywords. - If a match is found, the characters are effectively removed from the input - and |true| is returned. Otherwise |false| is returned, and the input - is left essentially unchanged (except for the fact that some macros - may have been expanded, etc.). - @^inner loop@> +If a match is found, the characters are effectively removed from the input and +|true| is returned. Otherwise |false| is returned, and the input is left +essentially unchanged (except for the fact that some macros may have been +expanded, etc.). @^inner loop@> @c boolean scan_keyword(const char *s) @@ -509,7 +504,7 @@ boolean scan_keyword(const char *s) token_link(p) = q; begin_token_list(token_link(backup_head), backed_up); if (cur_cmd != endv_cmd) - align_state = saved_align_state; + align_state = saved_align_state; } else { back_input(); } @@ -517,7 +512,8 @@ boolean scan_keyword(const char *s) return false; } } - flush_list(token_link(backup_head)); + if (token_link(backup_head) != null) + flush_list(token_link(backup_head)); cur_cs = save_cur_cs; if (cur_cmd != endv_cmd) align_state = saved_align_state; @@ -528,36 +524,119 @@ boolean scan_keyword(const char *s) (inside |shift_case|, for example). This needs thinking. @c + +/* + halfword active_to_cs(int curchr, int force) + { + halfword curcs; + char *a, *b; + char *utfbytes = xmalloc(8); + int nncs = no_new_control_sequence; + a = (char *) uni2str(0xFFFF); + utfbytes = strcpy(utfbytes, a); + if (force) + no_new_control_sequence = false; + if (curchr > 0) { + b = (char *) uni2str((unsigned) curchr); + utfbytes = strcat(utfbytes, b); + free(b); + curcs = string_lookup(utfbytes, strlen(utfbytes)); + } else { + utfbytes[3] = '\0'; + curcs = string_lookup(utfbytes, 4); + } + no_new_control_sequence = nncs; + free(a); + free(utfbytes); + return curcs; + } +*/ + +/*static char * FFFF = "\xEF\xBF\xBF";*/ /* 0xFFFF */ + halfword active_to_cs(int curchr, int force) { halfword curcs; - char *a, *b; - char *utfbytes = xmalloc(10); int nncs = no_new_control_sequence; - a = (char *) uni2str(0xFFFF); - utfbytes = strcpy(utfbytes, a); - if (force) + if (force) { no_new_control_sequence = false; + } if (curchr > 0) { - b = (char *) uni2str((unsigned) curchr); + char *b = (char *) uni2str((unsigned) curchr); + char *utfbytes = xmalloc(8); + utfbytes = strcpy(utfbytes, "\xEF\xBF\xBF"); utfbytes = strcat(utfbytes, b); free(b); - curcs = string_lookup(utfbytes, strlen(utfbytes)); + curcs = string_lookup(utfbytes, utf8_size(curchr)+3); + free(utfbytes); } else { - utfbytes[3] = '\0'; - curcs = string_lookup(utfbytes, 4); + curcs = string_lookup("\xEF\xBF\xBF", 4); /* 0xFFFF ... why not 3 ? */ } no_new_control_sequence = nncs; - free(a); - free(utfbytes); return curcs; } +/* + + static unsigned char *uni2csstr(unsigned unic) + { + unsigned char *buf = xmalloc(8); + unsigned char *pt = buf; + *pt++ = 239; *pt++ = 191; *pt++ = 191; // 0xFFFF + if (unic < 0x80) + *pt++ = (unsigned char) unic; + else if (unic < 0x800) { + *pt++ = (unsigned char) (0xc0 | (unic >> 6)); + *pt++ = (unsigned char) (0x80 | (unic & 0x3f)); + } else if (unic >= 0x110000) { + *pt++ = (unsigned char) (unic - 0x110000); + } else if (unic < 0x10000) { + *pt++ = (unsigned char) (0xe0 | (unic >> 12)); + *pt++ = (unsigned char) (0x80 | ((unic >> 6) & 0x3f)); + *pt++ = (unsigned char) (0x80 | (unic & 0x3f)); + } else { + int u, z, y, x; + unsigned val = unic - 0x10000; + u = (int) (((val & 0xf0000) >> 16) + 1); + z = (int) ((val & 0x0f000) >> 12); + y = (int) ((val & 0x00fc0) >> 6); + x = (int) (val & 0x0003f); + *pt++ = (unsigned char) (0xf0 | (u >> 2)); + *pt++ = (unsigned char) (0x80 | ((u & 3) << 4) | z); + *pt++ = (unsigned char) (0x80 | y); + *pt++ = (unsigned char) (0x80 | x); + } + *pt = '\0'; + return buf; + } + + halfword active_to_cs(int curchr, int force) + { + halfword curcs; + int nncs = no_new_control_sequence; + if (force) { + no_new_control_sequence = false; + } + if (curchr > 0) { + char * utfbytes = (char *) uni2csstr((unsigned) curchr); + curcs = string_lookup(utfbytes, utf8_size(curchr)+3); + free(utfbytes); + } else { + curcs = string_lookup(FFFF, 4); // 0xFFFF ... why not 3 ? + } + no_new_control_sequence = nncs; + return curcs; + } + +*/ + @ TODO this function should listen to \.{\\escapechar} +@ prints a control sequence + @c static char *cs_to_string(halfword p) -{ /* prints a control sequence */ +{ const char *s; char *sh; int k = 0; @@ -614,57 +693,51 @@ static char *cmd_chr_to_string(int cmd, int chr) return s; } -@ The heart of \TeX's input mechanism is the |get_next| procedure, which -we shall develop in the next few sections of the program. Perhaps we -shouldn't actually call it the ``heart,'' however, because it really acts -as \TeX's eyes and mouth, reading the source files and gobbling them up. -And it also helps \TeX\ to regurgitate stored token lists that are to be -processed again. -@^eyes and mouth@> +@ The heart of \TeX's input mechanism is the |get_next| procedure, which we shall +develop in the next few sections of the program. Perhaps we shouldn't actually +call it the ``heart,'' however, because it really acts as \TeX's eyes and mouth, +reading the source files and gobbling them up. And it also helps \TeX\ to +regurgitate stored token lists that are to be processed again. @^eyes and mouth@> -The main duty of |get_next| is to input one token and to set |cur_cmd| -and |cur_chr| to that token's command code and modifier. Furthermore, if -the input token is a control sequence, the |eqtb| location of that control -sequence is stored in |cur_cs|; otherwise |cur_cs| is set to zero. +The main duty of |get_next| is to input one token and to set |cur_cmd| and +|cur_chr| to that token's command code and modifier. Furthermore, if the input +token is a control sequence, the |eqtb| location of that control sequence is +stored in |cur_cs|; otherwise |cur_cs| is set to zero. -Underlying this simple description is a certain amount of complexity -because of all the cases that need to be handled. -However, the inner loop of |get_next| is reasonably short and fast. +Underlying this simple description is a certain amount of complexity because of +all the cases that need to be handled. However, the inner loop of |get_next| is +reasonably short and fast. When |get_next| is asked to get the next token of a \.{\\read} line, it sets |cur_cmd=cur_chr=cur_cs=0| in the case that no more tokens appear on that line. (There might not be any tokens at all, if the |end_line_char| has |ignore| as its catcode.) -@ The value of |par_loc| is the |eqtb| address of `\.{\\par}'. This quantity -is needed because a blank line of input is supposed to be exactly equivalent -to the appearance of \.{\\par}; we must set |cur_cs:=par_loc| -when detecting a blank line. +The value of |par_loc| is the |eqtb| address of `\.{\\par}'. This quantity is +needed because a blank line of input is supposed to be exactly equivalent to the +appearance of \.{\\par}; we must set |cur_cs:=par_loc| when detecting a blank +line. @c -halfword par_loc; /* location of `\.{\\par}' in |eqtb| */ -halfword par_token; /* token representing `\.{\\par}' */ - +halfword par_loc; /* location of `\.{\\par}' in |eqtb| */ +halfword par_token; /* token representing `\.{\\par}' */ @ Parts |get_next| are executed more often than any other instructions of \TeX. @^mastication@>@^inner loop@> - - -@ The global variable |force_eof| is normally |false|; it is set |true| -by an \.{\\endinput} command. |luacstrings| is the number of lua print -statements waiting to be input, it is changed by |luatokencall|. +The global variable |force_eof| is normally |false|; it is set |true| by an +\.{\\endinput} command. |luacstrings| is the number of lua print statements +waiting to be input, it is changed by |luatokencall|. @c -boolean force_eof; /* should the next \.{\\input} be aborted early? */ -int luacstrings; /* how many lua strings are waiting to be input? */ +boolean force_eof; /* should the next \.{\\input} be aborted early? */ +int luacstrings; /* how many lua strings are waiting to be input? */ -@ If the user has set the |pausing| parameter to some positive value, -and if nonstop mode has not been selected, each line of input is displayed -on the terminal and the transcript file, followed by `\.{=>}'. -\TeX\ waits for a response. If the response is simply |carriage_return|, the -line is accepted as it stands, otherwise the line typed is -used instead of the line in the file. +@ If the user has set the |pausing| parameter to some positive value, and if +nonstop mode has not been selected, each line of input is displayed on the +terminal and the transcript file, followed by `\.{=>}'. \TeX\ waits for a +response. If the response is simply |carriage_return|, the line is accepted as it +stands, otherwise the line typed is used instead of the line in the file. @c void firm_up_the_line(void) @@ -690,10 +763,10 @@ void firm_up_the_line(void) } } -@ Before getting into |get_next|, let's consider the subroutine that - is called when an `\.{\\outer}' control sequence has been scanned or - when the end of a file has been reached. These two cases are distinguished - by |cur_cs|, which is zero at the end of a file. +@ Before getting into |get_next|, let's consider the subroutine that is called +when an `\.{\\outer}' control sequence has been scanned or when the end of a file +has been reached. These two cases are distinguished by |cur_cs|, which is zero at +the end of a file. @c void check_outer_validity(void) @@ -717,8 +790,8 @@ void check_outer_validity(void) cur_chr = ' '; /* replace it by a space */ } if (scanner_status > skipping) { - const char *errhlp[] = - { "I suspect you have forgotten a `}', causing me", + const char *errhlp[] = { + "I suspect you have forgotten a `}', causing me", "to read past where you wanted me to stop.", "I'll try to recover; but if the error is serious,", "you'd better type `E' or `X' now and fix your file.", @@ -777,14 +850,14 @@ void check_outer_validity(void) tex_error(errmsg, errhlp); } else { char errmsg[256]; - const char *errhlp_no[] = - { "The file ended while I was skipping conditional text.", + const char *errhlp_no[] = { + "The file ended while I was skipping conditional text.", "This kind of error happens when you say `\\if...' and forget", "the matching `\\fi'. I've inserted a `\\fi'; this might work.", NULL }; - const char *errhlp_cs[] = - { "A forbidden control sequence occurred in skipped text.", + const char *errhlp_cs[] = { + "A forbidden control sequence occurred in skipped text.", "This kind of error happens when you say `\\if...' and forget", "the matching `\\fi'. I've inserted a `\\fi'; this might work.", NULL @@ -796,9 +869,8 @@ void check_outer_validity(void) cur_cs = 0; } ss = cmd_chr_to_string(if_test_cmd, cur_if); - snprintf(errmsg, 255, - "Incomplete %s; all text was ignored after line %d", - ss, (int) skip_line); + snprintf(errmsg, 255, "Incomplete %s; all text was ignored after line %d", + ss, (int) skip_line); free(ss); /* Incomplete \\if... */ cur_tok = cs_token_flag + frozen_fi; @@ -816,10 +888,19 @@ void check_outer_validity(void) } @ @c + +#if 0 + +/* + The other variant gives less clutter in tracing cache usage when profiling and for + some files (like the manual) also a bit of a speedup. +*/ + static boolean get_next_file(void) { SWITCH: - if (iloc <= ilimit) { /* current line not yet finished */ + if (iloc <= ilimit) { + /* current line not yet finished */ do_buffer_to_unichar(cur_chr, iloc); RESWITCH: @@ -829,127 +910,160 @@ static boolean get_next_file(void) do_get_cat_code(cur_cmd, cur_chr); } /* - Change state if necessary, and |goto switch| if the current - character should be ignored, or |goto reswitch| if the current - character changes to another; - */ - /* The following 48-way switch accomplishes the scanning quickly, assuming - that a decent C compiler has translated the code. Note that the numeric - values for |mid_line|, |skip_blanks|, and |new_line| are spaced - apart from each other by |max_char_code+1|, so we can add a character's - command code to the state to get a single number that characterizes both. - */ + Change state if necessary, and |goto switch| if the current + character should be ignored, or |goto reswitch| if the current + character changes to another; + + The following 48-way switch accomplishes the scanning quickly, assuming + that a decent C compiler has translated the code. Note that the numeric + values for |mid_line|, |skip_blanks|, and |new_line| are spaced + apart from each other by |max_char_code+1|, so we can add a character's + command code to the state to get a single number that characterizes both. + + Remark [ls/hh]: checking performance indicated that this switch was the + cause of many branch prediction errors but changing it to: + + c = istate + cur_cmd; + if (c == (mid_line + letter_cmd) || c == (mid_line + other_char_cmd)) { + return true; + } else if (c >= new_line) { + switch (c) { + } + } else if (c >= skip_blanks) { + switch (c) { + } + } else if (c >= mid_line) { + switch (c) { + } + } else { + istate = mid_line; + return true; + } + + gives as many prediction errors. So, we can indeed assume that the compiler + does the right job, or that there is simply no other way. + */ + switch (istate + cur_cmd) { - case mid_line + ignore_cmd: - case skip_blanks + ignore_cmd: - case new_line + ignore_cmd: - case skip_blanks + spacer_cmd: - case new_line + spacer_cmd: /* Cases where character is ignored */ - goto SWITCH; - break; - case mid_line + escape_cmd: - case new_line + escape_cmd: - case skip_blanks + escape_cmd: /* Scan a control sequence ...; */ - istate = (unsigned char) scan_control_sequence(); - if (cur_cmd >= outer_call_cmd) - check_outer_validity(); - break; - case mid_line + active_char_cmd: - case new_line + active_char_cmd: - case skip_blanks + active_char_cmd: /* Process an active-character */ - cur_cs = active_to_cs(cur_chr, false); - cur_cmd = eq_type(cur_cs); - cur_chr = equiv(cur_cs); - istate = mid_line; - if (cur_cmd >= outer_call_cmd) - check_outer_validity(); - break; - case mid_line + sup_mark_cmd: - case new_line + sup_mark_cmd: - case skip_blanks + sup_mark_cmd: /* If this |sup_mark| starts */ - if (process_sup_mark()) - goto RESWITCH; - else + case mid_line + ignore_cmd: + case skip_blanks + ignore_cmd: + case new_line + ignore_cmd: + case skip_blanks + spacer_cmd: + case new_line + spacer_cmd: + /* Cases where character is ignored */ + goto SWITCH; + break; + case mid_line + escape_cmd: + case new_line + escape_cmd: + case skip_blanks + escape_cmd: + /* Scan a control sequence ...; */ + istate = (unsigned char) scan_control_sequence(); + if (! suppress_outer_error && cur_cmd >= outer_call_cmd) + check_outer_validity(); + break; + case mid_line + active_char_cmd: + case new_line + active_char_cmd: + case skip_blanks + active_char_cmd: + /* Process an active-character */ + cur_cs = active_to_cs(cur_chr, false); + cur_cmd = eq_type(cur_cs); + cur_chr = equiv(cur_cs); istate = mid_line; - break; - case mid_line + invalid_char_cmd: - case new_line + invalid_char_cmd: - case skip_blanks + invalid_char_cmd: /* Decry the invalid character and |goto restart|; */ - invalid_character_error(); - return false; /* because state may be |token_list| now */ - break; - case mid_line + spacer_cmd: /* Enter |skip_blanks| state, emit a space; */ - istate = skip_blanks; - cur_chr = ' '; - break; - case mid_line + car_ret_cmd: /* Finish line, emit a space; */ - /* When a character of type |spacer| gets through, its character code is - changed to $\.{"\ "}=040$. This means that the ASCII codes for tab and space, - and for the space inserted at the end of a line, will - be treated alike when macro parameters are being matched. We do this - since such characters are indistinguishable on most computer terminal displays. - */ - iloc = ilimit + 1; - cur_cmd = spacer_cmd; - cur_chr = ' '; - break; - case skip_blanks + car_ret_cmd: - case mid_line + comment_cmd: - case new_line + comment_cmd: - case skip_blanks + comment_cmd: /* Finish line, |goto switch|; */ - iloc = ilimit + 1; - goto SWITCH; - break; - case new_line + car_ret_cmd: /* Finish line, emit a \.{\\par}; */ - iloc = ilimit + 1; - cur_cs = par_loc; - cur_cmd = eq_type(cur_cs); - cur_chr = equiv(cur_cs); - if (cur_cmd >= outer_call_cmd) - check_outer_validity(); - break; - case skip_blanks + left_brace_cmd: - case new_line + left_brace_cmd: - istate = mid_line; /* fall through */ - case mid_line + left_brace_cmd: - align_state++; - break; - case skip_blanks + right_brace_cmd: - case new_line + right_brace_cmd: - istate = mid_line; /* fall through */ - case mid_line + right_brace_cmd: - align_state--; - break; - case mid_line + math_shift_cmd: - case mid_line + tab_mark_cmd: - case mid_line + mac_param_cmd: - case mid_line + sub_mark_cmd: - case mid_line + letter_cmd: - case mid_line + other_char_cmd: - break; -#if 0 - case skip_blanks + math_shift: - case skip_blanks + tab_mark: - case skip_blanks + mac_param: - case skip_blanks + sub_mark: - case skip_blanks + letter: - case skip_blanks + other_char: - case new_line + math_shift: - case new_line + tab_mark: - case new_line + mac_param: - case new_line + sub_mark: - case new_line + letter: - case new_line + other_char: -#else - default: -#endif - istate = mid_line; - break; + if (! suppress_outer_error && cur_cmd >= outer_call_cmd) + check_outer_validity(); + break; + case mid_line + sup_mark_cmd: + case new_line + sup_mark_cmd: + case skip_blanks + sup_mark_cmd: + /* If this |sup_mark| starts */ + if (process_sup_mark()) + goto RESWITCH; + else + istate = mid_line; + break; + case mid_line + invalid_char_cmd: + case new_line + invalid_char_cmd: + case skip_blanks + invalid_char_cmd: + /* Decry the invalid character and |goto restart|; */ + invalid_character_error(); + return false; /* because state may be |token_list| now */ + break; + case mid_line + spacer_cmd: + /* Enter |skip_blanks| state, emit a space; */ + istate = skip_blanks; + cur_chr = ' '; + break; + case mid_line + car_ret_cmd: + /* + Finish line, emit a space. When a character of type |spacer| gets through, its + character code is changed to $\.{"\ "}=040$. This means that the ASCII codes + for tab and space, and for the space inserted at the end of a line, will be + treated alike when macro parameters are being matched. We do this since such + characters are indistinguishable on most computer terminal displays. + */ + iloc = ilimit + 1; + cur_cmd = spacer_cmd; + cur_chr = ' '; + break; + case skip_blanks + car_ret_cmd: + case mid_line + comment_cmd: + case new_line + comment_cmd: + case skip_blanks + comment_cmd: + /* Finish line, |goto switch|; */ + iloc = ilimit + 1; + goto SWITCH; + break; + case new_line + car_ret_cmd: + /* Finish line, emit a \.{\\par}; */ + iloc = ilimit + 1; + cur_cs = par_loc; + cur_cmd = eq_type(cur_cs); + cur_chr = equiv(cur_cs); + if (! suppress_outer_error && cur_cmd >= outer_call_cmd) + check_outer_validity(); + break; + case skip_blanks + left_brace_cmd: + case new_line + left_brace_cmd: + istate = mid_line; + /* fall through */ + case mid_line + left_brace_cmd: + align_state++; + break; + case skip_blanks + right_brace_cmd: + case new_line + right_brace_cmd: + istate = mid_line; + /* fall through */ + case mid_line + right_brace_cmd: + align_state--; + break; + case mid_line + math_shift_cmd: + case mid_line + tab_mark_cmd: + case mid_line + mac_param_cmd: + case mid_line + sub_mark_cmd: + case mid_line + letter_cmd: + case mid_line + other_char_cmd: + break; + /* + case skip_blanks + math_shift: + case skip_blanks + tab_mark: + case skip_blanks + mac_param: + case skip_blanks + sub_mark: + case skip_blanks + letter: + case skip_blanks + other_char: + case new_line + math_shift: + case new_line + tab_mark: + case new_line + mac_param: + case new_line + sub_mark: + case new_line + letter: + case new_line + other_char: + */ + default: + istate = mid_line; + break; } } else { if (iname != 21) istate = new_line; - /* Move to next line of file, or |goto restart| if there is no next line, @@ -969,108 +1083,389 @@ static boolean get_next_file(void) return true; } -@ @c -#define is_hex(a) ((a>='0'&&a<='9')||(a>='a'&&a<='f')) - -#define add_nybble(a) do { \ - if (a<='9') cur_chr=(cur_chr<<4)+a-'0'; \ - else cur_chr=(cur_chr<<4)+a-'a'+10; \ - } while (0) - -#define hex_to_cur_chr do { \ - if (c<='9') cur_chr=c-'0'; \ - else cur_chr=c-'a'+10; \ - add_nybble(cc); \ - } while (0) +#else -#define four_hex_to_cur_chr do { \ - hex_to_cur_chr; \ - add_nybble(ccc); add_nybble(cccc); \ - } while (0) +/* 10 times less Bim in callgrind */ -#define five_hex_to_cur_chr do { \ - four_hex_to_cur_chr; \ - add_nybble(ccccc); \ - } while (0) +/* + escape_cmd left_brace_cmd right_brace_cmd math_shift_cmd + tab_mark_cmd car_ret_cmd mac_param_cmd sup_mark_cmd + sub_mark_cmd ignore_cmd spacer_cmd letter_cmd + other_char_cmd active_char_cmd comment_cmd invalid_char_cmd +*/ -#define six_hex_to_cur_chr do { \ - five_hex_to_cur_chr; \ - add_nybble(cccccc); \ - } while (0) +static boolean get_next_file(void) +{ + int c = 0; + SWITCH: + if (iloc <= ilimit) { + /* current line not yet finished */ + do_buffer_to_unichar(cur_chr, iloc); + RESWITCH: + if (detokenized_line()) { + cur_cmd = (cur_chr == ' ' ? 10 : 12); + } else { + do_get_cat_code(cur_cmd, cur_chr); + } + /* + Change state if necessary, and |goto switch| if the current + character should be ignored, or |goto reswitch| if the current + character changes to another; + */ + c = istate + cur_cmd; + if (c == (mid_line + letter_cmd) || c == (mid_line + other_char_cmd)) { + return true; + } else if (c >= new_line) { + switch (c-new_line) { + case escape_cmd: + istate = (unsigned char) scan_control_sequence(); + if (! suppress_outer_error && cur_cmd >= outer_call_cmd) + check_outer_validity(); + return true; + case left_brace_cmd: + istate = mid_line; + align_state++; + return true; + case right_brace_cmd: + istate = mid_line; + align_state--; + return true; + case math_shift_cmd: + istate = mid_line; + return true; + case tab_mark_cmd: + istate = mid_line; + return true; + case car_ret_cmd: + /* Finish line, emit a \.{\\par}; */ + iloc = ilimit + 1; + cur_cs = par_loc; + cur_cmd = eq_type(cur_cs); + cur_chr = equiv(cur_cs); + if (! suppress_outer_error && cur_cmd >= outer_call_cmd) + check_outer_validity(); + return true; + case mac_param_cmd: + istate = mid_line; + return true; + case sup_mark_cmd: + if (process_sup_mark()) + goto RESWITCH; + else + istate = mid_line; + return true; + case sub_mark_cmd: + istate = mid_line; + return true; + case ignore_cmd: + goto SWITCH; + return true; + case spacer_cmd: + /* Cases where character is ignored */ + goto SWITCH; + case letter_cmd: + istate = mid_line; + return true; + case other_char_cmd: + istate = mid_line; + return true; + case active_char_cmd: + cur_cs = active_to_cs(cur_chr, false); + cur_cmd = eq_type(cur_cs); + cur_chr = equiv(cur_cs); + istate = mid_line; + if (! suppress_outer_error && cur_cmd >= outer_call_cmd) + check_outer_validity(); + return true; + case comment_cmd: + iloc = ilimit + 1; + goto SWITCH; + case invalid_char_cmd: + invalid_character_error(); + return false; /* because state may be |token_list| now */ + default: + istate = mid_line; + return true; + } + } else if (c >= skip_blanks) { + switch (c-skip_blanks) { + case escape_cmd: + /* Scan a control sequence ...; */ + istate = (unsigned char) scan_control_sequence(); + if (! suppress_outer_error && cur_cmd >= outer_call_cmd) + check_outer_validity(); + return true; + case left_brace_cmd: + istate = mid_line; + align_state++; + return true; + case right_brace_cmd: + istate = mid_line; + align_state--; + return true; + case math_shift_cmd: + istate = mid_line; + return true; + case tab_mark_cmd: + istate = mid_line; + return true; + case car_ret_cmd: + iloc = ilimit + 1; + goto SWITCH; + case mac_param_cmd: + istate = mid_line; + return true; + case sup_mark_cmd: + /* If this |sup_mark| starts */ + if (process_sup_mark()) + goto RESWITCH; + else + istate = mid_line; + return true; + case sub_mark_cmd: + istate = mid_line; + return true; + case ignore_cmd: + goto SWITCH; + case spacer_cmd: + goto SWITCH; + case letter_cmd: + istate = mid_line; + return true; + case other_char_cmd: + istate = mid_line; + return true; + case active_char_cmd: + cur_cs = active_to_cs(cur_chr, false); + cur_cmd = eq_type(cur_cs); + cur_chr = equiv(cur_cs); + istate = mid_line; + if (! suppress_outer_error && cur_cmd >= outer_call_cmd) + check_outer_validity(); + return true; + case comment_cmd: + /* Finish line, |goto switch|; */ + iloc = ilimit + 1; + goto SWITCH; + case invalid_char_cmd: + /* Decry the invalid character and |goto restart|; */ + invalid_character_error(); + return false; /* because state may be |token_list| now */ + default: + istate = mid_line; + return true; + } + } else if (c >= mid_line) { + switch (c-mid_line) { + case escape_cmd: + istate = (unsigned char) scan_control_sequence(); + if (! suppress_outer_error && cur_cmd >= outer_call_cmd) + check_outer_validity(); + return true; + case left_brace_cmd: + align_state++; + return true; + case right_brace_cmd: + align_state--; + return true; + case math_shift_cmd: + return true; + case tab_mark_cmd: + return true; + case car_ret_cmd: + /* + Finish line, emit a space. When a character of type |spacer| gets through, its + character code is changed to $\.{"\ "}=040$. This means that the ASCII codes + for tab and space, and for the space inserted at the end of a line, will be + treated alike when macro parameters are being matched. We do this since such + characters are indistinguishable on most computer terminal displays. + */ + iloc = ilimit + 1; + cur_cmd = spacer_cmd; + cur_chr = ' '; + return true; + case mac_param_cmd: + return true; + case sup_mark_cmd: + if (process_sup_mark()) + goto RESWITCH; + else + istate = mid_line; + return true; + case sub_mark_cmd: + return true; + case ignore_cmd: + goto SWITCH; + case spacer_cmd: + /* Enter |skip_blanks| state, emit a space; */ + istate = skip_blanks; + cur_chr = ' '; + return true; + case letter_cmd: + istate = mid_line; + return true; + case other_char_cmd: + istate = mid_line; + return true; + case active_char_cmd: + cur_cs = active_to_cs(cur_chr, false); + cur_cmd = eq_type(cur_cs); + cur_chr = equiv(cur_cs); + istate = mid_line; + if (! suppress_outer_error && cur_cmd >= outer_call_cmd) + check_outer_validity(); + return true; + case comment_cmd: + iloc = ilimit + 1; + goto SWITCH; + case invalid_char_cmd: + invalid_character_error(); + return false; /* because state may be |token_list| now */ + default: + istate = mid_line; + return true; + } + } else { + istate = mid_line; + return true; + } + } else { + if (iname != 21) { + istate = new_line; + } + /* + Move to next line of file, or |goto restart| if there is no next line, + or |return| if a \.{\\read} line has finished; + */ + do { + next_line_retval r = next_line(); + if (r == next_line_return) { + return true; + } else if (r == next_line_restart) { + return false; + } + } while (0); + check_interrupt(); + goto SWITCH; + } + return true; +} +#endif @ Notice that a code like \.{\^\^8} becomes \.x if not followed by a hex digit. +We only support a limited set: + +^^^^^^XXXXXX +^^^^XXXXXX +^^XX ^^<char> @c + +#define is_hex(a) ((a>='0'&&a<='9')||(a>='a'&&a<='f')) + +#define add_nybble(c) \ + if (c<='9') { \ + cur_chr=(cur_chr<<4)+c-'0'; \ + } else { \ + cur_chr=(cur_chr<<4)+c-'a'+10; \ + } + +#define set_nybble(c) \ + if (c<='9') { \ + cur_chr=c-'0'; \ + } else { \ + cur_chr=c-'a'+10; \ + } + +#define one_hex_to_cur_chr(c1) \ + set_nybble(c1); + +#define two_hex_to_cur_chr(c1,c2) \ + set_nybble(c1); \ + add_nybble(c2); + +#define four_hex_to_cur_chr(c1,c2,c3,c4) \ + two_hex_to_cur_chr(c1,c2); \ + add_nybble(c3); \ + add_nybble(c4); + +#define six_hex_to_cur_chr(c1,c2,c3,c4,c5,c6) \ + four_hex_to_cur_chr(c1,c2,c3,c4); \ + add_nybble(c5); \ + add_nybble(c6); + static boolean process_sup_mark(void) { if (cur_chr == buffer[iloc]) { - int c, cc; if (iloc < ilimit) { - if ( (cur_chr == buffer[iloc + 1]) - && (cur_chr == buffer[iloc + 2]) - && (cur_chr == buffer[iloc + 3]) - && (cur_chr == buffer[iloc + 4]) - && ((iloc + 10) <= ilimit)) { - int ccc, cccc, ccccc, cccccc; /* constituents of a possible expanded code */ - c = buffer[iloc + 5]; - cc = buffer[iloc + 6]; - ccc = buffer[iloc + 7]; - cccc = buffer[iloc + 8]; - ccccc = buffer[iloc + 9]; - cccccc = buffer[iloc + 10]; - if ((is_hex(c)) && (is_hex(cc)) && (is_hex(ccc)) - && (is_hex(cccc)) - && (is_hex(ccccc)) && (is_hex(cccccc))) { - iloc = iloc + 11; - six_hex_to_cur_chr; - return true; - } - } - if ( (cur_chr == buffer[iloc + 1]) - && (cur_chr == buffer[iloc + 2]) - && (cur_chr == buffer[iloc + 3]) - && ((iloc + 8) <= ilimit)) { - int ccc, cccc, ccccc; /* constituents of a possible expanded code */ - c = buffer[iloc + 4]; - cc = buffer[iloc + 5]; - ccc = buffer[iloc + 6]; - cccc = buffer[iloc + 7]; - ccccc = buffer[iloc + 8]; - if ((is_hex(c)) && (is_hex(cc)) && (is_hex(ccc)) - && (is_hex(cccc)) && (is_hex(ccccc))) { - iloc = iloc + 9; - five_hex_to_cur_chr; - return true; + if ((cur_chr == buffer[iloc + 1]) && (cur_chr == buffer[iloc + 2])) { + if ((cur_chr == buffer[iloc + 3]) && (cur_chr == buffer[iloc + 4])) { + /* ^^^^^^XXXXXX */ + if ((iloc + 10) <= ilimit) { + int c1 = buffer[iloc + 5]; + int c2 = buffer[iloc + 6]; + int c3 = buffer[iloc + 7]; + int c4 = buffer[iloc + 8]; + int c5 = buffer[iloc + 9]; + int c6 = buffer[iloc + 10]; + if (is_hex(c1) && is_hex(c2) && is_hex(c3) && + is_hex(c4) && is_hex(c5) && is_hex(c6)) { + iloc = iloc + 11; + six_hex_to_cur_chr(c1,c2,c3,c4,c5,c6); + return true; + } else { + tex_error("^^^^^^ needs six hex digits", NULL); + } + } else { + tex_error("^^^^^^ needs six hex digits, end of input", NULL); + } + } else { + /* ^^^^XXXX */ + if ((iloc + 6) <= ilimit) { + int c1 = buffer[iloc + 3]; + int c2 = buffer[iloc + 4]; + int c3 = buffer[iloc + 5]; + int c4 = buffer[iloc + 6]; + if (is_hex(c1) && is_hex(c2) && is_hex(c3) && is_hex(c4)) { + iloc = iloc + 7; + four_hex_to_cur_chr(c1,c2,c3,c4); + return true; + } else { + tex_error("^^^^ needs four hex digits", NULL); + } + } else { + tex_error("^^^^ needs four hex digits, end of input", NULL); + } } - } - if ( (cur_chr == buffer[iloc + 1]) - && (cur_chr == buffer[iloc + 2]) - && ((iloc + 6) <= ilimit)) { - int ccc, cccc; /* constituents of a possible expanded code */ - c = buffer[iloc + 3]; - cc = buffer[iloc + 4]; - ccc = buffer[iloc + 5]; - cccc = buffer[iloc + 6]; - if ((is_hex(c)) && (is_hex(cc)) && (is_hex(ccc)) - && (is_hex(cccc))) { - iloc = iloc + 7; - four_hex_to_cur_chr; - return true; + } else { + /* ^^XX */ + if ((iloc + 2) <= ilimit) { + int c1 = buffer[iloc + 1]; + int c2 = buffer[iloc + 2]; + if (is_hex(c1) && is_hex(c2)) { + iloc = iloc + 3; + two_hex_to_cur_chr(c1,c2); + return true; + } } + /* go on, no error, good old tex */ } - c = buffer[iloc + 1]; - if (c < 0200) { /* yes we have an expanded char */ + } + /* the rest */ + { + int c1 = buffer[iloc + 1]; + if (c1 < 0200) { iloc = iloc + 2; - if (is_hex(c) && iloc <= ilimit) { - cc = buffer[iloc]; - if (is_hex(cc)) { + if (is_hex(c1) && (iloc <= ilimit)) { + int c2 = buffer[iloc]; + if (is_hex(c2)) { incr(iloc); - hex_to_cur_chr; + two_hex_to_cur_chr(c1,c2); return true; } } - cur_chr = (c < 0100 ? c + 0100 : c - 0100); + cur_chr = (c1 < 0100 ? c1 + 0100 : c1 - 0100); return true; } } @@ -1078,20 +1473,19 @@ static boolean process_sup_mark(void) return false; } -@ Control sequence names are scanned only when they appear in some line of - a file; once they have been scanned the first time, their |eqtb| location - serves as a unique identification, so \TeX\ doesn't need to refer to the - original name any more except when it prints the equivalent in symbolic form. +@ Control sequence names are scanned only when they appear in some line of a +file; once they have been scanned the first time, their |eqtb| location serves as +a unique identification, so \TeX\ doesn't need to refer to the original name any +more except when it prints the equivalent in symbolic form. - The program that scans a control sequence has been written carefully - in order to avoid the blowups that might otherwise occur if a malicious - user tried something like `\.{\\catcode\'15=0}'. The algorithm might - look at |buffer[ilimit+1]|, but it never looks at |buffer[ilimit+2]|. +The program that scans a control sequence has been written carefully in order to +avoid the blowups that might otherwise occur if a malicious user tried something +like `\.{\\catcode\'15=0}'. The algorithm might look at |buffer[ilimit+1]|, but +it never looks at |buffer[ilimit+2]|. - If expanded characters like `\.{\^\^A}' or `\.{\^\^df}' - appear in or just following - a control sequence name, they are converted to single characters in the - buffer and the process is repeated, slowly but surely. +If expanded characters like `\.{\^\^A}' or `\.{\^\^df}' appear in or just +following a control sequence name, they are converted to single characters in the +buffer and the process is repeated, slowly but surely. @c static boolean check_expanded_code(int *kk); /* below */ @@ -1121,6 +1515,8 @@ static int scan_control_sequence(void) if (cat == sup_mark_cmd && check_expanded_code(&k)) /* If an expanded...; */ continue; if (cat != letter_cmd) { + /* backtrack one character which can be utf */ + /* decr(k); if (cur_chr > 0xFFFF) decr(k); @@ -1128,7 +1524,18 @@ static int scan_control_sequence(void) decr(k); if (cur_chr > 0x7F) decr(k); - } /* now |k| points to first nonletter */ + */ + if (cur_chr <= 0x7F) { + k -= 1; /* in most cases */ + } else if (cur_chr > 0xFFFF) { + k -= 4; + } else if (cur_chr > 0x7FF) { + k -= 3; + } else /* if (cur_chr > 0x7F) */ { + k -= 2; + } + /* now |k| points to first nonletter */ + } } cur_cs = id_lookup(iloc, k - iloc); iloc = k; @@ -1141,60 +1548,67 @@ static int scan_control_sequence(void) } @ Whenever we reach the following piece of code, we will have - |cur_chr=buffer[k-1]| and |k<=ilimit+1| and |cat=get_cat_code(cat_code_table,cur_chr)|. If an - expanded code like \.{\^\^A} or \.{\^\^df} appears in |buffer[(k-1)..(k+1)]| - or |buffer[(k-1)..(k+2)]|, we - will store the corresponding code in |buffer[k-1]| and shift the rest of - the buffer left two or three places. +|cur_chr=buffer[k-1]| and |k<=ilimit+1| and +|cat=get_cat_code(cat_code_table,cur_chr)|. If an expanded code like \.{\^\^A} or +\.{\^\^df} appears in |buffer[(k-1)..(k+1)]| or |buffer[(k-1)..(k+2)]|, we will +store the corresponding code in |buffer[k-1]| and shift the rest of the buffer +left two or three places. @c static boolean check_expanded_code(int *kk) { int l; int k = *kk; - int d = 1; /* number of excess characters in an expanded code */ - int c, cc, ccc, cccc, ccccc, cccccc; /* constituents of a possible expanded code */ + int d = 1; if (buffer[k] == cur_chr && k < ilimit) { - if ((cur_chr == buffer[k + 1]) && (cur_chr == buffer[k + 2]) - && ((k + 6) <= ilimit)) { - d = 4; - if ((cur_chr == buffer[k + 3]) && ((k + 8) <= ilimit)) - d = 5; - if ((cur_chr == buffer[k + 4]) && ((k + 10) <= ilimit)) - d = 6; - c = buffer[k + d - 1]; - cc = buffer[k + d]; - ccc = buffer[k + d + 1]; - cccc = buffer[k + d + 2]; - if (d == 6) { - ccccc = buffer[k + d + 3]; - cccccc = buffer[k + d + 4]; - if (is_hex(c) && is_hex(cc) && is_hex(ccc) && is_hex(cccc) - && is_hex(ccccc) && is_hex(cccccc)) - six_hex_to_cur_chr; - } else if (d == 5) { - ccccc = buffer[k + d + 3]; - if (is_hex(c) && is_hex(cc) && is_hex(ccc) && is_hex(cccc) - && is_hex(ccccc)) - five_hex_to_cur_chr; + if ((cur_chr == buffer[k + 1]) && (cur_chr == buffer[k + 2])) { + if ((cur_chr == buffer[k + 3]) && (cur_chr == buffer[k + 4])) { + if ((k + 10) <= ilimit) { + int c1 = buffer[k + 6 - 1]; + int c2 = buffer[k + 6]; + int c3 = buffer[k + 6 + 1]; + int c4 = buffer[k + 6 + 2]; + int c5 = buffer[k + 6 + 3]; + int c6 = buffer[k + 6 + 4]; + if (is_hex(c1) && is_hex(c2) && is_hex(c3) && is_hex(c4) && is_hex(c5) && is_hex(c6)) { + d = 6; + six_hex_to_cur_chr(c1,c2,c3,c4,c5,c6); + } else { + tex_error("^^^^^^ needs six hex digits", NULL); + } + } else { + tex_error("^^^^^^ needs six hex digits, end of input", NULL); + } } else { - if (is_hex(c) && is_hex(cc) && is_hex(ccc) && is_hex(cccc)) - four_hex_to_cur_chr; + if ((k + 6) <= ilimit) { + int c1 = buffer[k + 4 - 1]; + int c2 = buffer[k + 4]; + int c3 = buffer[k + 4 + 1]; + int c4 = buffer[k + 4 + 2]; + if (is_hex(c1) && is_hex(c2) && is_hex(c3) && is_hex(c4)) { + d = 4; + four_hex_to_cur_chr(c1,c2,c3,c4); + } else { + tex_error("^^^^ needs four hex digits", NULL); + } + } else { + tex_error("^^^^ needs four hex digits, end of input", NULL); + } } } else { - c = buffer[k + 1]; - if (c < 0200) { + int c1 = buffer[k + 1]; + if (c1 < 0200) { d = 1; - if (is_hex(c) && (k + 2) <= ilimit) { - cc = buffer[k + 2]; - if (is_hex(c) && is_hex(cc)) { + if (is_hex(c1) && (k + 2) <= ilimit) { + int c2 = buffer[k + 2]; + if (is_hex(c2)) { d = 2; - hex_to_cur_chr; + two_hex_to_cur_chr(c1,c2); + } else { + cur_chr = (c1 < 0100 ? c1 + 0100 : c1 - 0100); } - } else if (c < 0100) { - cur_chr = c + 0100; } else { - cur_chr = c - 0100; + cur_chr = (c1 < 0100 ? c1 + 0100 : c1 - 0100); } } } @@ -1213,28 +1627,21 @@ static boolean check_expanded_code(int *kk) buffer[k - 1] = (packed_ASCII_code) (0xE0 + cur_chr / 0x1000); k++; d--; - buffer[k - 1] = - (packed_ASCII_code) (0x80 + (cur_chr % 0x1000) / 0x40); + buffer[k - 1] = (packed_ASCII_code) (0x80 + (cur_chr % 0x1000) / 0x40); k++; d--; - buffer[k - 1] = - (packed_ASCII_code) (0x80 + (cur_chr % 0x1000) % 0x40); + buffer[k - 1] = (packed_ASCII_code) (0x80 + (cur_chr % 0x1000) % 0x40); } else { buffer[k - 1] = (packed_ASCII_code) (0xF0 + cur_chr / 0x40000); k++; d--; - buffer[k - 1] = - (packed_ASCII_code) (0x80 + (cur_chr % 0x40000) / 0x1000); + buffer[k - 1] = (packed_ASCII_code) (0x80 + (cur_chr % 0x40000) / 0x1000); k++; d--; - buffer[k - 1] = - (packed_ASCII_code) (0x80 + - ((cur_chr % 0x40000) % 0x1000) / 0x40); + buffer[k - 1] = (packed_ASCII_code) (0x80 + ((cur_chr % 0x40000) % 0x1000) / 0x40); k++; d--; - buffer[k - 1] = - (packed_ASCII_code) (0x80 + - ((cur_chr % 0x40000) % 0x1000) % 0x40); + buffer[k - 1] = (packed_ASCII_code) (0x80 + ((cur_chr % 0x40000) % 0x1000) % 0x40); } l = k; ilimit = ilimit - d; @@ -1248,13 +1655,12 @@ static boolean check_expanded_code(int *kk) return false; } -@ All of the easy branches of |get_next| have now been taken care of. - There is one more branch. +@ All of the easy branches of |get_next| have now been taken care of. There is +one more branch. -@c -static next_line_retval next_line(void) +@c static next_line_retval next_line(void) { - boolean inhibit_eol = false; /* a way to end a pseudo file without trailing space */ + boolean inhibit_eol = false; /* a way to end a pseudo file without trailing space */ if (iname > 17) { /* Read next line of file into |buffer|, or |goto restart| if the file has ended */ incr(line); @@ -1268,7 +1674,7 @@ static next_line_retval next_line(void) inhibit_eol = true; } else if ((every_eof != null) && !eof_seen[iindex]) { ilimit = first - 1; - eof_seen[iindex] = true; /* fake one empty line */ + eof_seen[iindex] = true; /* fake one empty line */ if (iname != 19) begin_token_list(every_eof, every_eof_text); return next_line_restart; @@ -1277,7 +1683,7 @@ static next_line_retval next_line(void) } } else { if (iname == 21) { - if (luacstring_input()) { /* not end of strings */ + if (luacstring_input()) { /* not end of strings */ firm_up_the_line(); line_catcode_table = (short) luacstring_cattable(); line_partial = (signed char) luacstring_partial(); @@ -1290,12 +1696,12 @@ static next_line_retval next_line(void) force_eof = true; } } else { - if (lua_input_ln(cur_file, 0, true)) { /* not end of file */ - firm_up_the_line(); /* this sets |ilimit| */ + if (lua_input_ln(cur_file, 0, true)) { /* not end of file */ + firm_up_the_line(); /* this sets |ilimit| */ line_catcode_table = DEFAULT_CAT_TABLE; } else if ((every_eof != null) && (!eof_seen[iindex])) { ilimit = first - 1; - eof_seen[iindex] = true; /* fake one empty line */ + eof_seen[iindex] = true; /* fake one empty line */ begin_token_list(every_eof, every_eof_text); return next_line_restart; } else { @@ -1306,24 +1712,23 @@ static next_line_retval next_line(void) } if (force_eof) { if (tracing_nesting > 0) - if ((grp_stack[in_open] != cur_boundary) - || (if_stack[in_open] != cond_ptr)) - if (!((iname == 19) || (iname == 21))) - file_warning(); /* give warning for some unfinished groups and/or conditionals */ + if ((grp_stack[in_open] != cur_boundary) || (if_stack[in_open] != cond_ptr)) + if (!((iname == 19) || (iname == 21))) { + /* give warning for some unfinished groups and/or conditionals */ + file_warning(); + } if ((iname > 21) || (iname == 20)) { report_stop_file(filetype_tex); decr(open_parens); -#if 0 - update_terminal(); /* show user that file has been read */ -#endif } force_eof = false; - if (iname == 21 || /* lua input */ - iname == 19) { /* \.{\\scantextokens} */ + /* lua input or \.{\\scantextokens} */ + if (iname == 21 || iname == 19) { end_file_reading(); } else { end_file_reading(); - check_outer_validity(); + if (! suppress_outer_error) + check_outer_validity(); } return next_line_restart; } @@ -1332,28 +1737,31 @@ static next_line_retval next_line(void) else buffer[ilimit] = (packed_ASCII_code) end_line_char; first = ilimit + 1; - iloc = istart; /* ready to read */ + iloc = istart; /* ready to read */ } else { - if (!terminal_input) { /* \.{\\read} line has ended */ + if (!terminal_input) { + /* \.{\\read} line has ended */ cur_cmd = 0; cur_chr = 0; return next_line_return; /* OUTER */ } - if (input_ptr > 0) { /* text was inserted during error recovery */ + if (input_ptr > 0) { + /* text was inserted during error recovery */ end_file_reading(); - return next_line_restart; /* resume previous level */ + return next_line_restart; /* resume previous level */ } if (selector < log_only) open_log_file(); if (interaction > nonstop_mode) { if (end_line_char_inactive) ilimit++; - if (ilimit == istart) { /* previous line was empty */ + if (ilimit == istart) { + /* previous line was empty */ tprint_nl("(Please type a command or say `\\end')"); } print_ln(); first = istart; - prompt_input("*"); /* input on-line into |buffer| */ + prompt_input("*"); /* input on-line into |buffer| */ ilimit = last; if (end_line_char_inactive) ilimit--; @@ -1362,9 +1770,11 @@ static next_line_retval next_line(void) first = ilimit + 1; iloc = istart; } else { + /* + Nonstop mode, which is intended for overnight batch processing, + never waits for on-line input. + */ fatal_error("*** (job aborted, no legal \\end found)"); - /* nonstop mode, which is intended for overnight batch processing, - never waits for on-line input */ } } return next_line_ok; @@ -1375,18 +1785,20 @@ static next_line_retval next_line(void) @c static boolean get_next_tokenlist(void) { - register halfword t; /* a token */ - t = token_info(iloc); - iloc = token_link(iloc); /* move to next */ - if (t >= cs_token_flag) { /* a control sequence token */ + register halfword t = token_info(iloc); + iloc = token_link(iloc); /* move to next */ + if (t >= cs_token_flag) { + /* a control sequence token */ cur_cs = t - cs_token_flag; cur_cmd = eq_type(cur_cs); if (cur_cmd >= outer_call_cmd) { - if (cur_cmd == dont_expand_cmd) { /* Get the next token, suppressing expansion */ - /* The present point in the program is reached only when the |expand| - routine has inserted a special marker into the input. In this special - case, |token_info(iloc)| is known to be a control sequence token, and |token_link(iloc)=null|. - */ + if (cur_cmd == dont_expand_cmd) { + /* + Get the next token, suppressing expansion. The present point in the program + is reached only when the |expand| routine has inserted a special marker into + the input. In this special case, |token_info(iloc)| is known to be a control + sequence token, and |token_link(iloc)=null|. + */ cur_cs = token_info(iloc) - cs_token_flag; iloc = null; cur_cmd = eq_type(cur_cs); @@ -1395,7 +1807,7 @@ static boolean get_next_tokenlist(void) cur_chr = no_expand_flag; return true; } - } else { + } else if (! suppress_outer_error) { check_outer_validity(); } } @@ -1404,24 +1816,25 @@ static boolean get_next_tokenlist(void) cur_cmd = token_cmd(t); cur_chr = token_chr(t); switch (cur_cmd) { - case left_brace_cmd: - align_state++; - break; - case right_brace_cmd: - align_state--; - break; - case out_param_cmd: /* Insert macro parameter and |goto restart|; */ - begin_token_list(param_stack[param_start + cur_chr - 1], parameter); - return false; - break; + case left_brace_cmd: + align_state++; + break; + case right_brace_cmd: + align_state--; + break; + case out_param_cmd: + /* Insert macro parameter and |goto restart|; */ + begin_token_list(param_stack[param_start + cur_chr - 1], parameter); + return false; + break; } } return true; } -@ Now we're ready to take the plunge into |get_next| itself. Parts of - this routine are executed more often than any other instructions of \TeX. - @^mastication@>@^inner loop@> +@ Now we're ready to take the plunge into |get_next| itself. Parts of this +routine are executed more often than any other instructions of \TeX. +@^mastication@>@^inner loop@> @ sets |cur_cmd|, |cur_chr|, |cur_cs| to next token @@ -1449,34 +1862,35 @@ void get_next(void) } } -@ Since |get_next| is used so frequently in \TeX, it is convenient -to define three related procedures that do a little more: +@ Since |get_next| is used so frequently in \TeX, it is convenient to define +three related procedures that do a little more: + +\yskip\hang|get_token| not only sets |cur_cmd| and |cur_chr|, it also sets +|cur_tok|, a packed halfword version of the current token. -\yskip\hang|get_token| not only sets |cur_cmd| and |cur_chr|, it -also sets |cur_tok|, a packed halfword version of the current token. +\yskip\hang|get_x_token|, meaning ``get an expanded token,'' is like |get_token|, +but if the current token turns out to be a user-defined control sequence (i.e., a +macro call), or a conditional, or something like \.{\\topmark} or +\.{\\expandafter} or \.{\\csname}, it is eliminated from the input by beginning +the expansion of the macro or the evaluation of the conditional. -\yskip\hang|get_x_token|, meaning ``get an expanded token,'' is like -|get_token|, but if the current token turns out to be a user-defined -control sequence (i.e., a macro call), or a conditional, -or something like \.{\\topmark} or \.{\\expandafter} or \.{\\csname}, -it is eliminated from the input by beginning the expansion of the macro -or the evaluation of the conditional. +\yskip\hang|x_token| is like |get_x_token| except that it assumes that |get_next| +has already been called. -\yskip\hang|x_token| is like |get_x_token| except that it assumes that -|get_next| has already been called. +\yskip\noindent In fact, these three procedures account for almost every use of +|get_next|. -\yskip\noindent -In fact, these three procedures account for almost every use of |get_next|. +No new control sequences will be defined except during a call of |get_token|, or +when \.{\\csname} compresses a token list, because |no_new_control_sequence| is +always |true| at other times. -No new control sequences will be defined except during a call of -|get_token|, or when \.{\\csname} compresses a token list, because -|no_new_control_sequence| is always |true| at other times. +@ sets |cur_cmd|, |cur_chr|, |cur_tok| @c void get_token(void) -{ /* sets |cur_cmd|, |cur_chr|, |cur_tok| */ +{ no_new_control_sequence = false; - get_next(); /* get_token_lua(); */ + get_next(); no_new_control_sequence = true; if (cur_cs == 0) cur_tok = token_val(cur_cmd, cur_chr); @@ -1484,32 +1898,14 @@ void get_token(void) cur_tok = cs_token_flag + cur_cs; } -@ @c -void get_token_lua(void) -{ - register int callback_id; - callback_id = callback_defined(token_filter_callback); - if (callback_id > 0) { - while (istate == token_list && iloc == null && iindex != v_template) - end_token_list(); - /* there is some stuff we don't want to see inside the callback */ - if (!(istate == token_list && - ((nofilter == true) || (iindex == backed_up && iloc != null)))) { - do_get_token_lua(callback_id); - return; - } - } - get_next(); -} - - @ changes the string |s| to a token list + @c halfword string_to_toks(const char *ss) { - halfword p; /* tail of the token list */ - halfword q; /* new node being added to the token list via |store_new_token| */ - halfword t; /* token being appended */ + halfword p; /* tail of the token list */ + halfword q; /* new node being added to the token list via |store_new_token| */ + halfword t; /* token being appended */ const char *s = ss; const char *se = ss + strlen(s); p = temp_token_head; @@ -1526,27 +1922,29 @@ halfword string_to_toks(const char *ss) return token_link(temp_token_head); } -@ The token lists for macros and for other things like \.{\\mark} and \.{\\output} -and \.{\\write} are produced by a procedure called |scan_toks|. +@ The token lists for macros and for other things like \.{\\mark} and +\.{\\output} and \.{\\write} are produced by a procedure called |scan_toks|. -Before we get into the details of |scan_toks|, let's consider a much -simpler task, that of converting the current string into a token list. -The |str_toks| function does this; it classifies spaces as type |spacer| -and everything else as type |other_char|. +Before we get into the details of |scan_toks|, let's consider a much simpler +task, that of converting the current string into a token list. The |str_toks| +function does this; it classifies spaces as type |spacer| and everything else as +type |other_char|. The token list created by |str_toks| begins at |link(temp_token_head)| and ends at the value |p| that is returned. (If |p=temp_token_head|, the list is empty.) -|lua_str_toks| is almost identical, but it also escapes the three -symbols that |lua| considers special while scanning a literal string +|lua_str_toks| is almost identical, but it also escapes the three symbols that +|lua| considers special while scanning a literal string + +@ changes the string |str_pool[b..pool_ptr]| to a token list @c halfword lua_str_toks(lstring b) -{ /* changes the string |str_pool[b..pool_ptr]| to a token list */ - halfword p; /* tail of the token list */ - halfword q; /* new node being added to the token list via |store_new_token| */ - halfword t; /* token being appended */ - unsigned char *k; /* index into string */ +{ + halfword p; /* tail of the token list */ + halfword q; /* new node being added to the token list via |store_new_token| */ + halfword t; /* token being appended */ + unsigned char *k; /* index into string */ p = temp_token_head; set_token_link(p, null); k = (unsigned char *) b.s; @@ -1569,16 +1967,18 @@ halfword lua_str_toks(lstring b) return p; } -@ Incidentally, the main reason for wanting |str_toks| is the function |the_toks|, -which has similar input/output characteristics. +@ Incidentally, the main reason for wanting |str_toks| is the function +|the_toks|, which has similar input/output characteristics. + +@ changes the string |str_pool[b..pool_ptr]| to a token list @c halfword str_toks(lstring s) -{ /* changes the string |str_pool[b..pool_ptr]| to a token list */ - halfword p; /* tail of the token list */ - halfword q; /* new node being added to the token list via |store_new_token| */ - halfword t; /* token being appended */ - unsigned char *k, *l; /* index into string */ +{ + halfword p; /* tail of the token list */ + halfword q; /* new node being added to the token list via |store_new_token| */ + halfword t; /* token being appended */ + unsigned char *k, *l; /* index into string */ p = temp_token_head; set_token_link(p, null); k = s.s; @@ -1602,11 +2002,11 @@ halfword str_toks(lstring s) */ halfword str_scan_toks(int ct, lstring s) -{ /* changes the string |str_pool[b..pool_ptr]| to a token list */ - halfword p; /* tail of the token list */ - halfword q; /* new node being added to the token list via |store_new_token| */ - halfword t; /* token being appended */ - unsigned char *k, *l; /* index into string */ +{ /* changes the string |str_pool[b..pool_ptr]| to a token list */ + halfword p; /* tail of the token list */ + halfword q; /* new node being added to the token list via |store_new_token| */ + halfword t; /* token being appended */ + unsigned char *k, *l; /* index into string */ int cc; p = temp_token_head; set_token_link(p, null); @@ -1667,6 +2067,7 @@ halfword str_scan_toks(int ct, lstring s) } @ Here's part of the |expand| subroutine that we are now ready to complete: + @c void ins_the_toks(void) { @@ -1674,8 +2075,133 @@ void ins_the_toks(void) ins_list(token_link(temp_token_head)); } -@ This routine, used in the next one, prints the job name, possibly -modified by the |process_jobname| callback. +#define set_toks_register(n,t,g) { \ + int a = (g>0) ? 4 : 0; \ + halfword ref = get_avail(); \ + set_token_ref_count(ref, 0); \ + set_token_link(ref, token_link(t)); \ + define(n + toks_base, call_cmd, ref); \ +} + +void combine_the_toks(int how) +{ + halfword nt; + get_x_token(); + /* target */ + if (cur_cmd == assign_toks_cmd) { + nt = equiv(cur_cs) - toks_base; + /* check range */ + } else { + back_input(); + scan_int(); + nt = cur_val; + } + /* source */ + do { + get_x_token(); + } while (cur_cmd == spacer_cmd); + if (cur_cmd == left_brace_cmd) { + halfword x, source; + back_input(); + x = scan_toks(false,how > 1); /* expanded or not */ + source = def_ref; + /* action */ + if (source != null) { + halfword target = toks(nt); + if (target == null) { + set_toks_register(nt,source,0); + } else { + halfword s = token_link(source); + if (s != null) { + halfword t = token_link(target); + if (t == null) { + /* can this happen ? */ + set_token_link(target, s); + } else if (odd(how)) { + /* prepend */ + if (cur_level != eq_level_field(eqtb[toks_base+nt])) { + halfword p = temp_token_head; + halfword q; + set_token_link(p, s); /* s = head, x = tail */ + p = x; + while (t != null) { + fast_store_new_token(token_info(t)); + t = token_link(t); + } + set_toks_register(nt,temp_token_head,0); + } else { + set_token_link(x,t); + set_token_link(target,s); + } + } else { + /* append */ + if (cur_level != eq_level_field(eqtb[toks_base+nt])) { + halfword p = temp_token_head; + halfword q; + set_token_link(p, null); + while (t != null) { + fast_store_new_token(token_info(t)); + t = token_link(t); + } + set_token_link(p,s); + set_toks_register(nt,temp_token_head,0); + } else { + while (token_link(t) != null) { + t = token_link(t); + } + set_token_link(t,s); + } + } + } + } + } + } else { + halfword source, ns; + if (cur_cmd == assign_toks_cmd) { + ns = equiv(cur_cs) - toks_base; + /* check range */ + } else { + back_input(); + scan_int(); + ns = cur_val; + } + /* action */ + source = toks(ns); + if (source != null) { + halfword target = toks(nt); + if (target == null) { + equiv(toks_base+nt) = source; + equiv(toks_base+ns) = null; + } else { + halfword s = token_link(source); + if (s != null) { + halfword t = token_link(target); + if (t == null) { + set_token_link(target, s); + } else if (odd(how)) { + /* prepend */ + halfword x = s; + while (token_link(x) != null) { + x = token_link(x); + } + set_token_link(x,t); + set_token_link(target,s); + } else { + /* append */ + while (token_link(t) != null) { + t = token_link(t); + } + set_token_link(t,s); + } + equiv(toks_base+ns) = null; + } + } + } + } +} + +@ This routine, used in the next one, prints the job name, possibly modified by +the |process_jobname| callback. @c static void print_job_name(void) @@ -1696,21 +2222,23 @@ static void print_job_name(void) } } -@ Here is a routine that print the result of a convert command, using - the argument |i|. It returns |false | if it does not know to print - the code |c|. The function exists because lua code and tex code can - both call it to convert something. +@ Here is a routine that print the result of a convert command, using the +argument |i|. It returns |false | if it does not know to print the code |c|. The +function exists because lua code and tex code can both call it to convert +something. -@ @c -int scan_lua_state(void) /* hh-ls: optional name or number (not optional name optional number) */ +@ Parse optional lua state integer, or an instance name to be stored in |sn| and +get the next non-blank non-relax non-call token. + +@c + +int scan_lua_state(void) { - /* Parse optional lua state integer, or an instance name to be stored in |sn| */ - /* Get the next non-blank non-relax non-call token */ int sn = 0; do { get_x_token(); } while ((cur_cmd == spacer_cmd) || (cur_cmd == relax_cmd)); - back_input(); /* have to push it back, whatever it is */ + back_input(); if (cur_cmd != left_brace_cmd) { if (scan_keyword("name")) { (void) scan_toks(false, true); @@ -1724,13 +2252,13 @@ int scan_lua_state(void) /* hh-ls: optional name or number (not optional name op return sn; } -@ The procedure |conv_toks| uses |str_toks| to insert the token list -for |convert| functions into the scanner; `\.{\\outer}' control sequences -are allowed to follow `\.{\\string}' and `\.{\\meaning}'. +@ The procedure |conv_toks| uses |str_toks| to insert the token list for +|convert| functions into the scanner; `\.{\\outer}' control sequences are allowed +to follow `\.{\\string}' and `\.{\\meaning}'. -The extra temp string |u| is needed because |pdf_scan_ext_toks| incorporates -any pending string in its output. In order to save such a pending string, -we have to create a temporary string that is destroyed immediately after. +The extra temp string |u| is needed because |pdf_scan_ext_toks| incorporates any +pending string in its output. In order to save such a pending string, we have to +create a temporary string that is destroyed immediately after. @c #define push_selector { \ @@ -1783,7 +2311,6 @@ static int do_variable_pdf(halfword c) else if (scan_keyword("objcompresslevel")) { do_variable_backend_int(c_pdf_objcompresslevel); } else if (scan_keyword("inclusioncopyfonts")) { do_variable_backend_int(c_pdf_inclusion_copy_font); } else if (scan_keyword("gentounicode")) { do_variable_backend_int(c_pdf_gen_tounicode); } - else if (scan_keyword("replacefont")) { do_variable_backend_int(c_pdf_replace_font); } else if (scan_keyword("horigin")) { do_variable_backend_dimen(d_pdf_h_origin); } else if (scan_keyword("vorigin")) { do_variable_backend_dimen(d_pdf_v_origin); } @@ -1900,7 +2427,7 @@ static int do_feedback_pdf(halfword c) save_warning_index = warning_index; save_def_ref = def_ref; u = save_cur_string(); - scan_toks(false, true); /*hh-ls was scan_pdf_ext_toks();*/ + scan_toks(false, true); s = tokens_to_string(def_ref); delete_token_ref(def_ref); def_ref = save_def_ref; @@ -1951,313 +2478,306 @@ void conv_toks(void) int i = 0; /* Scan the argument for command |c| */ switch (c) { - case uchar_code: - scan_char_num(); - push_selector; - print(cur_val); - pop_selector; - break; - case number_code: - scan_int(); - push_selector; - print_int(cur_val); - pop_selector; - break; - case roman_numeral_code: - scan_int(); - push_selector; - print_roman_int(cur_val); - pop_selector; - break; - case string_code: - save_scanner_status = scanner_status; - scanner_status = normal; - get_token(); - scanner_status = save_scanner_status; - push_selector; - if (cur_cs != 0) - sprint_cs(cur_cs); - else - print(cur_chr); - pop_selector; - break; - case meaning_code: - save_scanner_status = scanner_status; - scanner_status = normal; - get_token(); - scanner_status = save_scanner_status; - push_selector; - print_meaning(); - pop_selector; - break; - case etex_code: - push_selector; - tprint(eTeX_version_string); - pop_selector; - break; - case font_name_code: - scan_font_ident(); - push_selector; - append_string((unsigned char *) font_name(cur_val),(unsigned) strlen(font_name(cur_val))); - if (font_size(cur_val) != font_dsize(cur_val)) { - tprint(" at "); - print_scaled(font_size(cur_val)); - tprint("pt"); - } - pop_selector; - break; - case font_id_code: - scan_font_ident(); - push_selector; - print_int(cur_val); - pop_selector; - break; - case luatex_revision_code: - push_selector; - print(get_luatexrevision()); - pop_selector; - break; - case luatex_date_code: - push_selector; - print_int(get_luatex_date_info()); - pop_selector; - break; - case luatex_banner_code: - push_selector; - tprint(luatex_banner); - pop_selector; - break; - case left_margin_kern_code: - scan_int(); - if ((box(cur_val) == null) || (type(box(cur_val)) != hlist_node)) - normal_error("marginkern", "a non-empty hbox expected"); - push_selector; - p = list_ptr(box(cur_val)); - while ((p != null) && (type(p) == glue_node)) { - p = vlink(p); - } - if ((p != null) && (type(p) == margin_kern_node) && (subtype(p) == left_side)) - print_scaled(width(p)); - else - print_char('0'); - tprint("pt"); - pop_selector; - break; - case right_margin_kern_code: - scan_int(); - if ((box(cur_val) == null) || (type(box(cur_val)) != hlist_node)) - normal_error("marginkern", "a non-empty hbox expected"); - push_selector; - p = list_ptr(box(cur_val)); - if (p != null) { - p = tail_of_list(p); - /* - there can be a leftskip, rightskip, penalty and yes, also a disc node with a nesting - node that points to glue spec ... and we don't want to analyze that messy lot - */ - while ((p != null) && (type(p) == glue_node)) { - p = alink(p); - } - if ((p != null) && ! ((type(p) == margin_kern_node) && (subtype(p) == right_side))) { - if (type(p) == disc_node) { - q = alink(p); - if ((q != null) && ((type(q) == margin_kern_node) && (subtype(q) == right_side))) { - p = q; - } else { - /* - officially we should look in the replace but currently protrusion doesn't - work anyway with "foo\discretionary{}{}{bar-} " (no following char) so we - don't need it now - */ - } - } + case number_code: + scan_int(); + push_selector; + print_int(cur_val); + pop_selector; + break; + case lua_function_code: + scan_int(); + if (cur_val <= 0) { + normal_error("luafunction", "invalid number"); + } else { + u = save_cur_string(); + luacstrings = 0; + luafunctioncall(cur_val); + restore_cur_string(u); + if (luacstrings > 0) + lua_string_start(); } - } - if ((p != null) && (type(p) == margin_kern_node) && (subtype(p) == right_side)) - print_scaled(width(p)); - else - print_char('0'); - tprint("pt"); - pop_selector; - break; - case format_name_code: - if (job_name == 0) - open_log_file(); - push_selector; - print(format_name); - pop_selector; - break; - case job_name_code: - if (job_name == 0) - open_log_file(); - push_selector; - print_job_name(); - pop_selector; - break; - case uniform_deviate_code: - scan_int(); - push_selector; - print_int(unif_rand(cur_val)); - pop_selector; - break; - case normal_deviate_code: - scan_int(); - push_selector; - print_int(norm_rand()); - pop_selector; - break; - case lua_escape_string_code: - { - lstring escstr; - int l = 0; + /* no further action */ + return; + break; + case lua_code: + u = save_cur_string(); save_scanner_status = scanner_status; save_def_ref = def_ref; save_warning_index = warning_index; - scan_toks(false, true); /*hh-ls was scan_pdf_ext_toks();*/ - bool = in_lua_escape; - in_lua_escape = true; - escstr.s = (unsigned char *) tokenlist_to_cstring(def_ref, false, &l); - escstr.l = (unsigned) l; - in_lua_escape = bool; - delete_token_ref(def_ref); + sn = scan_lua_state(); + scan_toks(false, true); + s = def_ref; + warning_index = save_warning_index; def_ref = save_def_ref; + scanner_status = save_scanner_status; + luacstrings = 0; + luatokencall(s, sn); + delete_token_ref(s); + restore_cur_string(u); /* TODO: check this, was different */ + if (luacstrings > 0) + lua_string_start(); + /* no further action */ + return; + break; + case expanded_code: + save_scanner_status = scanner_status; + save_warning_index = warning_index; + save_def_ref = def_ref; + u = save_cur_string(); + scan_toks(false, true); warning_index = save_warning_index; scanner_status = save_scanner_status; - (void) lua_str_toks(escstr); - ins_list(token_link(temp_token_head)); - free(escstr.s); + ins_list(token_link(def_ref)); + def_ref = save_def_ref; + restore_cur_string(u); + /* no further action */ return; - } - /* no further action */ - break; - case math_style_code: - push_selector; - print_math_style(); - pop_selector; - break; - case math_char_class_code: - { - mathcodeval mval; + break; + case math_style_code: + push_selector; + print_math_style(); + pop_selector; + break; + case string_code: + save_scanner_status = scanner_status; + scanner_status = normal; + get_token(); + scanner_status = save_scanner_status; + push_selector; + if (cur_cs != 0) + sprint_cs(cur_cs); + else + print(cur_chr); + pop_selector; + break; + case cs_string_code: + save_scanner_status = scanner_status; + scanner_status = normal; + get_token(); + scanner_status = save_scanner_status; + push_selector; + if (cur_cs != 0) + sprint_cs_name(cur_cs); + else + print(cur_chr); + pop_selector; + break; + case roman_numeral_code: scan_int(); - mval = get_math_code(cur_val); push_selector; - print_int(mval.class_value); + print_roman_int(cur_val); pop_selector; - } - break; - case math_char_fam_code: - { - mathcodeval mval; + break; + case meaning_code: + save_scanner_status = scanner_status; + scanner_status = normal; + get_token(); + scanner_status = save_scanner_status; + push_selector; + print_meaning(); + pop_selector; + break; + case uchar_code: + scan_char_num(); + push_selector; + print(cur_val); + pop_selector; + break; + case lua_escape_string_code: + { + lstring escstr; + int l = 0; + save_scanner_status = scanner_status; + save_def_ref = def_ref; + save_warning_index = warning_index; + scan_toks(false, true); + bool = in_lua_escape; + in_lua_escape = true; + escstr.s = (unsigned char *) tokenlist_to_cstring(def_ref, false, &l); + escstr.l = (unsigned) l; + in_lua_escape = bool; + delete_token_ref(def_ref); + def_ref = save_def_ref; + warning_index = save_warning_index; + scanner_status = save_scanner_status; + (void) lua_str_toks(escstr); + ins_list(token_link(temp_token_head)); + free(escstr.s); + return; + } + /* no further action */ + break; + case font_id_code: + scan_font_ident(); + push_selector; + print_int(cur_val); + pop_selector; + break; + case font_name_code: + scan_font_ident(); + push_selector; + append_string((unsigned char *) font_name(cur_val),(unsigned) strlen(font_name(cur_val))); + if (font_size(cur_val) != font_dsize(cur_val)) { + tprint(" at "); + print_scaled(font_size(cur_val)); + tprint("pt"); + } + pop_selector; + break; + case left_margin_kern_code: scan_int(); - mval = get_math_code(cur_val); + if ((box(cur_val) == null) || (type(box(cur_val)) != hlist_node)) + normal_error("marginkern", "a non-empty hbox expected"); push_selector; - print_int(mval.family_value); + p = list_ptr(box(cur_val)); + while ((p != null) && (type(p) == glue_node)) { + p = vlink(p); + } + if ((p != null) && (type(p) == margin_kern_node) && (subtype(p) == left_side)) + print_scaled(width(p)); + else + print_char('0'); + tprint("pt"); pop_selector; - } - break; - case math_char_slot_code: - { - mathcodeval mval; + break; + case right_margin_kern_code: scan_int(); - mval = get_math_code(cur_val); + if ((box(cur_val) == null) || (type(box(cur_val)) != hlist_node)) + normal_error("marginkern", "a non-empty hbox expected"); push_selector; - print_int(mval.character_value); + p = list_ptr(box(cur_val)); + if (p != null) { + p = tail_of_list(p); + /* + there can be a leftskip, rightskip, penalty and yes, also a disc node with a nesting + node that points to glue spec ... and we don't want to analyze that messy lot + */ + while ((p != null) && (type(p) == glue_node)) { + p = alink(p); + } + if ((p != null) && ! ((type(p) == margin_kern_node) && (subtype(p) == right_side))) { + if (type(p) == disc_node) { + q = alink(p); + if ((q != null) && ((type(q) == margin_kern_node) && (subtype(q) == right_side))) { + p = q; + } else { + /* + officially we should look in the replace but currently protrusion doesn't + work anyway with "foo\discretionary{}{}{bar-} " (no following char) so we + don't need it now + */ + } + } + } + } + if ((p != null) && (type(p) == margin_kern_node) && (subtype(p) == right_side)) + print_scaled(width(p)); + else + print_char('0'); + tprint("pt"); pop_selector; - } - break; - case expanded_code: - save_scanner_status = scanner_status; - save_warning_index = warning_index; - save_def_ref = def_ref; - u = save_cur_string(); - scan_toks(false, true); /*hh-ls was scan_pdf_ext_toks();*/ - warning_index = save_warning_index; - scanner_status = save_scanner_status; - ins_list(token_link(def_ref)); - def_ref = save_def_ref; - restore_cur_string(u); - /* no further action */ - return; - break; - case lua_code: - u = save_cur_string(); - save_scanner_status = scanner_status; - save_def_ref = def_ref; - save_warning_index = warning_index; - sn = scan_lua_state(); - scan_toks(false, true); /*hh-ls was scan_pdf_ext_toks();*/ - s = def_ref; - warning_index = save_warning_index; - def_ref = save_def_ref; - scanner_status = save_scanner_status; - luacstrings = 0; - luatokencall(s, sn); - delete_token_ref(s); - restore_cur_string(u); /* TODO: check this, was different */ - if (luacstrings > 0) - lua_string_start(); - /* no further action */ - return; - break; - case lua_function_code: - scan_int(); - if (cur_val <= 0) { - normal_error("luafunction", "invalid number"); - } else { - u = save_cur_string(); - luacstrings = 0; - luafunctioncall(cur_val); - restore_cur_string(u); - if (luacstrings > 0) - lua_string_start(); - } - /* no further action */ - return; - break; - case eTeX_revision_code: - push_selector; - tprint(eTeX_revision); - pop_selector; - break; - case insert_ht_code: - scan_register_num(); - push_selector; - i = cur_val; - p = page_ins_head; - while (i >= subtype(vlink(p))) - p = vlink(p); - if (subtype(p) == i) - print_scaled(height(p)); - else - print_char('0'); - tprint("pt"); - pop_selector; - break; - /* - case dvi_feedback_code: - if (get_o_mode() == OMODE_DVI) - done = do_feedback_dvi(c); - else - done = 0; - if (done==0) - tex_error("unexpected use of \\dvifeedback",null); - else if (done==2) - return; - break; - case pdf_feedback_code: - if (get_o_mode() == OMODE_PDF) - done = conv_toks_pdf(c); - else - done = 0; - if (done==0) - tex_error("unexpected use of \\pdffeedback",null); - else if (done==2) - return; - break; - */ - default: - confusion("convert"); - break; + break; + case uniform_deviate_code: + scan_int(); + push_selector; + print_int(unif_rand(cur_val)); + pop_selector; + break; + case normal_deviate_code: + scan_int(); + push_selector; + print_int(norm_rand()); + pop_selector; + break; + case math_char_class_code: + { + mathcodeval mval; + scan_int(); + mval = get_math_code(cur_val); + push_selector; + print_int(mval.class_value); + pop_selector; + } + break; + case math_char_fam_code: + { + mathcodeval mval; + scan_int(); + mval = get_math_code(cur_val); + push_selector; + print_int(mval.family_value); + pop_selector; + } + break; + case math_char_slot_code: + { + mathcodeval mval; + scan_int(); + mval = get_math_code(cur_val); + push_selector; + print_int(mval.character_value); + pop_selector; + } + break; + case insert_ht_code: + scan_register_num(); + push_selector; + i = cur_val; + p = page_ins_head; + while (i >= subtype(vlink(p))) + p = vlink(p); + if (subtype(p) == i) + print_scaled(height(p)); + else + print_char('0'); + tprint("pt"); + pop_selector; + break; + case job_name_code: + if (job_name == 0) + open_log_file(); + push_selector; + print_job_name(); + pop_selector; + break; + case format_name_code: + if (job_name == 0) + open_log_file(); + push_selector; + print(format_name); + pop_selector; + break; + case luatex_banner_code: + push_selector; + tprint(luatex_banner); + pop_selector; + break; + case luatex_revision_code: + push_selector; + print(get_luatexrevision()); + pop_selector; + break; + case luatex_date_code: + push_selector; + print_int(get_luatex_date_info()); + pop_selector; + break; + case etex_code: + push_selector; + tprint(eTeX_version_string); + pop_selector; + break; + case eTeX_revision_code: + push_selector; + tprint(eTeX_revision); + pop_selector; + break; + case font_identifier_code: + confusion("convert"); + break; + default: + confusion("convert"); + break; } str = make_string(); (void) str_toks(str_lstring(str)); @@ -2380,49 +2900,62 @@ str_number the_convert_string(halfword c, int i) case number_code: print_int(i); break; - case uchar_code: - print(i); + /* case lua_function_code: */ + /* case lua_code: */ + /* case expanded_code: */ + case math_style_code: + print_math_style(); break; + /* case string_code: */ + /* case cs_string_code: */ case roman_numeral_code: print_roman_int(i); break; - case etex_code: - tprint(eTeX_version_string); - break; - case luatex_revision_code: - print(get_luatexrevision()); + /* case meaning_code: */ + case uchar_code: + print(i); break; - case luatex_date_code: - print_int(get_luatex_date_info()); + /* lua_escape_string_code: */ + case font_id_code: + print_int(i); break; - case luatex_banner_code: - tprint(luatex_banner); + case font_name_code: + append_string((unsigned char *) font_name(i),(unsigned) strlen(font_name(i))); + if (font_size(i) != font_dsize(i)) { + tprint(" at "); + print_scaled(font_size(i)); + tprint("pt"); + } break; + /* left_margin_kern_code: */ + /* right_margin_kern_code: */ case uniform_deviate_code: print_int(unif_rand(i)); break; case normal_deviate_code: print_int(norm_rand()); break; + /* math_char_class_code: */ + /* math_char_fam_code: */ + /* math_char_slot_code: */ + /* insert_ht_code: */ + case job_name_code: + print_job_name(); + break; case format_name_code: print(format_name); break; - case job_name_code: - print_job_name(); + case luatex_banner_code: + tprint(luatex_banner); break; - case font_name_code: - append_string((unsigned char *) font_name(i),(unsigned) strlen(font_name(i))); - if (font_size(i) != font_dsize(i)) { - tprint(" at "); - print_scaled(font_size(i)); - tprint("pt"); - } + case luatex_revision_code: + print(get_luatexrevision()); break; - case font_id_code: - print_int(i); + case luatex_date_code: + print_int(get_luatex_date_info()); break; - case math_style_code: - print_math_style(); + case etex_code: + tprint(eTeX_version_string); break; case eTeX_revision_code: tprint(eTeX_revision); @@ -2449,16 +2982,16 @@ str_number the_convert_string(halfword c, int i) return ret; } -@ Another way to create a token list is via the \.{\\read} command. The -sixteen files potentially usable for reading appear in the following -global variables. The value of |read_open[n]| will be |closed| if -stream number |n| has not been opened or if it has been fully read; -|just_open| if an \.{\\openin} but not a \.{\\read} has been done; -and |normal| if it is open and ready to read the next line. +@ Another way to create a token list is via the \.{\\read} command. The sixteen +files potentially usable for reading appear in the following global variables. +The value of |read_open[n]| will be |closed| if stream number |n| has not been +opened or if it has been fully read; |just_open| if an \.{\\openin} but not a +\.{\\read} has been done; and |normal| if it is open and ready to read the next +line. @c -FILE *read_file[16]; /* used for \.{\\read} */ -int read_open[17]; /* state of |read_file[n]| */ +FILE *read_file[16]; /* used for \.{\\read} */ +int read_open[17]; /* state of |read_file[n]| */ void initialize_read(void) { @@ -2467,17 +3000,17 @@ void initialize_read(void) read_open[k] = closed; } -@ The |read_toks| procedure constructs a token list like that for any -macro definition, and makes |cur_val| point to it. Parameter |r| points -to the control sequence that will receive this token list. +@ The |read_toks| procedure constructs a token list like that for any macro +definition, and makes |cur_val| point to it. Parameter |r| points to the control +sequence that will receive this token list. @c void read_toks(int n, halfword r, halfword j) { - halfword p; /* tail of the token list */ - halfword q; /* new node being added to the token list via |store_new_token| */ - int s; /* saved value of |align_state| */ - int m; /* stream number */ + halfword p; /* tail of the token list */ + halfword q; /* new node being added to the token list via |store_new_token| */ + int s; /* saved value of |align_state| */ + int m; /* stream number */ scanner_status = defining; warning_index = r; p = get_avail(); @@ -2496,10 +3029,13 @@ void read_toks(int n, halfword r, halfword j) begin_file_reading(); iname = m + 1; if (read_open[m] == closed) { - /* Input for \.{\\read} from the terminal */ - /* Here we input on-line into the |buffer| array, prompting the user explicitly - if |n>=0|. The value of |n| is set negative so that additional prompts - will not be given in the case of multi-line input. */ + /* + Input for \.{\\read} from the terminal + + Here we input on-line into the |buffer| array, prompting the user explicitly + if |n>=0|. The value of |n| is set negative so that additional prompts + will not be given in the case of multi-line input. + */ if (interaction > nonstop_mode) { if (n < 0) { prompt_input(""); @@ -2516,9 +3052,12 @@ void read_toks(int n, halfword r, halfword j) } } else if (read_open[m] == just_open) { - /* Input the first line of |read_file[m]| */ - /* The first line of a file must be treated specially, since |lua_input_ln| - must be told not to start with |get|. */ + /* + Input the first line of |read_file[m]| + + The first line of a file must be treated specially, since |lua_input_ln| + must be told not to start with |get|. + */ if (lua_input_ln(read_file[m], (m + 1), false)) { read_open[m] = normal; } else { @@ -2527,8 +3066,11 @@ void read_toks(int n, halfword r, halfword j) } } else { - /* Input the next line of |read_file[m]| */ - /* An empty line is appended at the end of a |read_file|. */ + /* + Input the next line of |read_file[m]| + + An empty line is appended at the end of a |read_file|. + */ if (!lua_input_ln(read_file[m], (m + 1), true)) { lua_a_close_in(read_file[m], (m + 1)); read_open[m] = closed; @@ -2552,8 +3094,9 @@ void read_toks(int n, halfword r, halfword j) istate = new_line; /* Handle \.{\\readline} and |goto done|; */ if (j == 1) { - while (iloc <= ilimit) { /* current line not yet finished */ - do_buffer_to_unichar(cur_chr, iloc); + while (iloc <= ilimit) { + /* current line not yet finished */ + do_buffer_to_unichar(cur_chr, iloc); if (cur_chr == ' ') cur_tok = space_token; else @@ -2563,9 +3106,12 @@ void read_toks(int n, halfword r, halfword j) } else { while (1) { get_token(); - if (cur_tok == 0) - break; /* |cur_cmd=cur_chr=0| will occur at the end of the line */ - if (align_state < 1000000) { /* unmatched `\.\}' aborts the line */ + if (cur_tok == 0) { + /* |cur_cmd=cur_chr=0| will occur at the end of the line */ + break; + } + if (align_state < 1000000) { + /* unmatched `\.\}' aborts the line */ do { get_token(); } while (cur_tok != 0); @@ -2583,9 +3129,11 @@ void read_toks(int n, halfword r, halfword j) align_state = s; } -@ @c +@ return a string from tokens list + +@c str_number tokens_to_string(halfword p) -{ /* return a string from tokens list */ +{ int old_setting; if (selector == new_string) normal_error("tokens","tokens_to_string() called while selector = new_string"); @@ -2627,7 +3175,6 @@ str_number tokens_to_string(halfword p) append_i_byte(0x80 + (((s % 0x40000) % 0x1000) % 0x40)); \ } } - #define Print_esc(b) { \ const char *v = b; \ if (e>0 && e<STRING_OFFSET) { \ @@ -2646,10 +3193,9 @@ str_number tokens_to_string(halfword p) #define is_cat_letter(a) \ (get_char_cat_code(pool_to_unichar(str_string((a)))) == 11) -@ the actual token conversion in this function is now functionally - equivalent to |show_token_list|, except that it always prints the - whole token list. - TODO: check whether this causes problems in the lua library. +@ the actual token conversion in this function is now functionally equivalent to +|show_token_list|, except that it always prints the whole token list. TODO: check +whether this causes problems in the lua library. @c char *tokenlist_to_cstring(int pp, int inhibit_par, int *siz) @@ -2691,9 +3237,7 @@ char *tokenlist_to_cstring(int pp, int inhibit_par, int *siz) } else { Print_esc("IMPOSSIBLE."); } - } else if ((q >= undefined_control_sequence) - && ((q <= eqtb_size) - || (q > eqtb_size + hash_extra))) { + } else if ((q >= undefined_control_sequence) && ((q <= eqtb_size) || (q > eqtb_size + hash_extra))) { Print_esc("IMPOSSIBLE."); } else if ((cs_text(q) < 0) || (cs_text(q) >= str_ptr)) { Print_esc("NONEXISTENT."); @@ -2727,48 +3271,48 @@ char *tokenlist_to_cstring(int pp, int inhibit_par, int *siz) m = token_cmd(infop); c = token_chr(infop); switch (m) { - case left_brace_cmd: - case right_brace_cmd: - case math_shift_cmd: - case tab_mark_cmd: - case sup_mark_cmd: - case sub_mark_cmd: - case spacer_cmd: - case letter_cmd: - case other_char_cmd: - Print_uchar(c); - break; - case mac_param_cmd: - if (!in_lua_escape && (is_in_csname==0)) + case left_brace_cmd: + case right_brace_cmd: + case math_shift_cmd: + case tab_mark_cmd: + case sup_mark_cmd: + case sub_mark_cmd: + case spacer_cmd: + case letter_cmd: + case other_char_cmd: Print_uchar(c); - Print_uchar(c); - break; - case out_param_cmd: - Print_uchar(match_chr); - if (c <= 9) { - Print_char(c + '0'); - } else { - Print_char('!'); - goto EXIT; - } - break; - case match_cmd: - match_chr = c; - Print_uchar(c); - n++; - Print_char(n); - if (n > '9') - goto EXIT; - break; - case end_match_cmd: - if (c == 0) { - Print_char('-'); - Print_char('>'); - } - break; - default: - not_so_bad(Print_esc); - break; + break; + case mac_param_cmd: + if (!in_lua_escape && (is_in_csname==0)) + Print_uchar(c); + Print_uchar(c); + break; + case out_param_cmd: + Print_uchar(match_chr); + if (c <= 9) { + Print_char(c + '0'); + } else { + Print_char('!'); + goto EXIT; + } + break; + case match_cmd: + match_chr = c; + Print_uchar(c); + n++; + Print_char(n); + if (n > '9') + goto EXIT; + break; + case end_match_cmd: + if (c == 0) { + Print_char('-'); + Print_char('>'); + } + break; + default: + not_so_bad(Print_esc); + break; } } } diff --git a/Build/source/texk/web2c/luatexdir/utils/managed-sa.h b/Build/source/texk/web2c/luatexdir/utils/managed-sa.h index 2b96caf0283..0a17a642c8a 100644 --- a/Build/source/texk/web2c/luatexdir/utils/managed-sa.h +++ b/Build/source/texk/web2c/luatexdir/utils/managed-sa.h @@ -36,7 +36,31 @@ # define Mxcalloc_array(a,b) xcalloc((b),sizeof(a)) # define Mxrealloc_array(a,b,c) xrealloc((a),(unsigned)((unsigned)(c)*sizeof(b))) -typedef unsigned int sa_tree_item; +typedef union { + unsigned int uint_value; + int int_value; + struct { + int value_1; + int value_2; + } dump_int; + struct { + unsigned int value_1; + unsigned int value_2; + } dump_uint; + struct { + unsigned int character_value:21; + unsigned int family_value:8; + unsigned int class_value:3; + } math_code_value; + struct { + unsigned int small_character_value:21; + unsigned int small_family_value:8; + unsigned int class_value:3; + unsigned int large_character_value:21; + unsigned int large_family_value:8; + unsigned int dummy_value:3; + } del_code_value; +} sa_tree_item; typedef struct { int code; @@ -48,6 +72,7 @@ typedef struct { typedef struct { int stack_size; /* initial stack size */ int stack_step; /* increment stack step */ + int stack_type; int stack_ptr; /* current stack point */ sa_tree_item dflt; /* default item value */ sa_tree_item ***tree; /* item tree head */ @@ -60,7 +85,7 @@ extern sa_tree_item get_sa_item(const sa_tree head, const int n); extern void set_sa_item(sa_tree head, int n, sa_tree_item v, int gl); extern void rawset_sa_item(sa_tree head, int n, sa_tree_item v); -extern sa_tree new_sa_tree(int size, sa_tree_item dflt); +extern sa_tree new_sa_tree(int size, int type, sa_tree_item dflt); extern sa_tree copy_sa_tree(sa_tree head); extern void destroy_sa_tree(sa_tree head); diff --git a/Build/source/texk/web2c/luatexdir/utils/managed-sa.w b/Build/source/texk/web2c/luatexdir/utils/managed-sa.w index 85bb058352a..857b2d42e9f 100644 --- a/Build/source/texk/web2c/luatexdir/utils/managed-sa.w +++ b/Build/source/texk/web2c/luatexdir/utils/managed-sa.w @@ -19,8 +19,14 @@ @* Sparse arrays with an embedded save stack. -@ @c +These functions are called very often but a few days of experimenting proved that +there is not much to gain (if at all) from using macros or optimizations like +preallocating and fast access to the first 128 entries. In practice the overhead +is mostly in accessing memory and not in (probably inlined) calls. So, we should +accept fate and wait for faster memory. It's the price we pay for being unicode +on the one hand and sparse on the other. +@ @c #include "ptexlib.h" @@ -58,12 +64,10 @@ static void skip_in_stack(sa_tree a, int n) @ @c sa_tree_item get_sa_item(const sa_tree head, const int n) { - register int h; - register int m; if (head->tree != NULL) { - h = HIGHPART_PART(n); + register int h = HIGHPART_PART(n); if (head->tree[h] != NULL) { - m = MIDPART_PART(n); + register int m = MIDPART_PART(n); if (head->tree[h][m] != NULL) { return head->tree[h][m][LOWPART_PART(n)]; } @@ -75,22 +79,18 @@ sa_tree_item get_sa_item(const sa_tree head, const int n) @ @c void set_sa_item(sa_tree head, int n, sa_tree_item v, int gl) { - int h, m, l; - int i; - h = HIGHPART_PART(n); - m = MIDPART_PART(n); - l = LOWPART_PART(n); + int h = HIGHPART_PART(n); + int m = MIDPART_PART(n); + int l = LOWPART_PART(n); if (head->tree == NULL) { - head->tree = - (sa_tree_item ***) Mxcalloc_array(sa_tree_item **, HIGHPART); + head->tree = (sa_tree_item ***) Mxcalloc_array(sa_tree_item **, HIGHPART); } if (head->tree[h] == NULL) { - head->tree[h] = - (sa_tree_item **) Mxcalloc_array(sa_tree_item *, MIDPART); + head->tree[h] = (sa_tree_item **) Mxcalloc_array(sa_tree_item *, MIDPART); } if (head->tree[h][m] == NULL) { - head->tree[h][m] = - (sa_tree_item *) Mxmalloc_array(sa_tree_item, LOWPART); + int i; + head->tree[h][m] = (sa_tree_item *) Mxmalloc_array(sa_tree_item, LOWPART); for (i = 0; i < LOWPART; i++) { head->tree[h][m][i] = head->dflt; } @@ -120,10 +120,10 @@ void clear_sa_stack(sa_tree a) @ @c void destroy_sa_tree(sa_tree a) { - int h, m; if (a == NULL) return; if (a->tree != NULL) { + int h, m; for (h = 0; h < HIGHPART; h++) { if (a->tree[h] != NULL) { for (m = 0; m < MIDPART; m++) { @@ -141,7 +141,6 @@ void destroy_sa_tree(sa_tree a) @ @c sa_tree copy_sa_tree(sa_tree b) { - int h, m; sa_tree a = (sa_tree) Mxmalloc_array(sa_tree_head, 1); a->stack_step = b->stack_step; a->stack_size = b->stack_size; @@ -150,6 +149,7 @@ sa_tree copy_sa_tree(sa_tree b) a->stack_ptr = 0; a->tree = NULL; if (b->tree != NULL) { + int h, m; a->tree = (sa_tree_item ***) Mxcalloc_array(void *, HIGHPART); for (h = 0; h < HIGHPART; h++) { if (b->tree[h] != NULL) { @@ -168,13 +168,16 @@ sa_tree copy_sa_tree(sa_tree b) } @ The main reason to fill in the lowest entry branches here immediately -is that most of the sparse arrays have a bias toward ASCII values. +is that most of the sparse arrays have a bias toward ASCII values. Allocating those here immediately improves the chance of the structure -|a->tree[0][0][x]| being close together in actual memory locations +|a->tree[0][0][x]| being close together in actual memory locations @c -sa_tree new_sa_tree(int size, sa_tree_item dflt) + +/* we could save less for type 0 stacks */ + +sa_tree new_sa_tree(int size, int type, sa_tree_item dflt) { sa_tree_head *a; a = (sa_tree_head *) xmalloc(sizeof(sa_tree_head)); @@ -184,6 +187,7 @@ sa_tree new_sa_tree(int size, sa_tree_item dflt) a->tree[0] = (sa_tree_item **) Mxcalloc_array(sa_tree_item *, MIDPART); a->stack_size = size; a->stack_step = size; + a->stack_type = type; a->stack_ptr = 0; return (sa_tree) a; } @@ -203,19 +207,19 @@ void restore_sa_stack(sa_tree head, int gl) } } - @ @c void dump_sa_tree(sa_tree a) { boolean f; - int x; + int x, n; int h, m, l; - assert(a != NULL); dump_int(a->stack_step); - x = (int) a->dflt; + x = a->dflt.int_value; dump_int(x); if (a->tree != NULL) { dump_int(1); + n = a->stack_type; + dump_int(n); for (h = 0; h < HIGHPART; h++) { if (a->tree[h] != NULL) { f = 1; @@ -225,8 +229,12 @@ void dump_sa_tree(sa_tree a) f = 1; dump_qqqq(f); for (l = 0; l < LOWPART; l++) { - x = (int) a->tree[h][m][l]; + x = a->tree[h][m][l].dump_uint.value_1; dump_int(x); + if (n == 1) { + x = a->tree[h][m][l].dump_uint.value_2; + dump_int(x); + } } } else { f = 0; @@ -246,7 +254,7 @@ void dump_sa_tree(sa_tree a) @ @c sa_tree undump_sa_tree(void) { - int x; + int x, n; int h, m, l; boolean f; sa_tree a = (sa_tree) Mxmalloc_array(sa_tree_head, 1); @@ -254,7 +262,7 @@ sa_tree undump_sa_tree(void) a->stack_step = x; a->stack_size = x; undump_int(x); - a->dflt = (sa_tree_item) x; + a->dflt.int_value = x; a->stack = Mxmalloc_array(sa_stack_item, a->stack_size); a->stack_ptr = 0; a->tree = NULL; @@ -262,6 +270,8 @@ sa_tree undump_sa_tree(void) if (x == 0) return a; a->tree = (sa_tree_item ***) Mxcalloc_array(void *, HIGHPART); + undump_int(n); + a->stack_type = n; for (h = 0; h < HIGHPART; h++) { undump_qqqq(f); if (f > 0) { @@ -272,7 +282,11 @@ 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] = (unsigned int) x; + a->tree[h][m][l].dump_uint.value_1 = x; + if (n == 1) { + undump_int(x); + a->tree[h][m][l].dump_uint.value_2 = x; + } } } } diff --git a/Build/source/texk/web2c/luatexdir/utils/unistring.w b/Build/source/texk/web2c/luatexdir/utils/unistring.w index 3e8d82d0c1d..a5b365a5f2e 100644 --- a/Build/source/texk/web2c/luatexdir/utils/unistring.w +++ b/Build/source/texk/web2c/luatexdir/utils/unistring.w @@ -64,9 +64,9 @@ unsigned str2uni(const unsigned char *k) *text >= 0xc0 || text[1] >= 0xc0 || text[2] >= 0xc0) val = 0xFFFD; } else { - /* the 5- and 6-byte UTF-8 sequences generate integers + /* the 5- and 6-byte UTF-8 sequences generate integers that are outside of the valid UCS range, and therefore - unsupported + unsupported */ } if (val == 0xFFFD) @@ -74,7 +74,7 @@ unsigned str2uni(const unsigned char *k) return (val); } -@ This is a very basic helper +@ This is a very basic helper @c unsigned char *uni2str(unsigned unic) { @@ -92,12 +92,11 @@ unsigned char *uni2str(unsigned unic) *pt++ = (unsigned char) (0x80 | ((unic >> 6) & 0x3f)); *pt++ = (unsigned char) (0x80 | (unic & 0x3f)); } else { - int u, z, y, x; unsigned val = unic - 0x10000; - u = (int) (((val & 0xf0000) >> 16) + 1); - z = (int) ((val & 0x0f000) >> 12); - y = (int) ((val & 0x00fc0) >> 6); - x = (int) (val & 0x0003f); + int u = (int) (((val & 0xf0000) >> 16) + 1); + int z = (int) ((val & 0x0f000) >> 12); + int y = (int) ((val & 0x00fc0) >> 6); + int x = (int) (val & 0x0003f); *pt++ = (unsigned char) (0xf0 | (u >> 2)); *pt++ = (unsigned char) (0x80 | ((u & 3) << 4) | z); *pt++ = (unsigned char) (0x80 | y); @@ -109,7 +108,7 @@ unsigned char *uni2str(unsigned unic) @ |buffer_to_unichar| converts a sequence of bytes in the |buffer| into a unicode character value. It does not check for overflow -of the |buffer|, but it is careful to check the validity of the +of the |buffer|, but it is careful to check the validity of the UTF-8 encoding. @c @@ -120,7 +119,7 @@ int buffer_to_unichar(int k) @ These came from texlang.w -@c +@c char *uni2string(char *utf8_text, unsigned ch) { /* Increment and deposit character */ diff --git a/Build/source/texk/web2c/luatexdir/utils/utils.w b/Build/source/texk/web2c/luatexdir/utils/utils.w index 75bd143ef44..2c23b1d3268 100644 --- a/Build/source/texk/web2c/luatexdir/utils/utils.w +++ b/Build/source/texk/web2c/luatexdir/utils/utils.w @@ -47,7 +47,7 @@ @ @c #define check_nprintf(size_get, size_want) \ if ((unsigned)(size_get) >= (unsigned)(size_want)) \ - luatex_fail ("snprintf failed: file %s, line %d", __FILE__, __LINE__); + formatted_error("internal","snprintf failed: file %s, line %d", __FILE__, __LINE__); char *cur_file_name = NULL; static char print_buf[PRINTF_BUF_SIZE]; @@ -113,9 +113,7 @@ void make_subset_tag(fd_entry * fd) aa = avl_probe(st_tree, fd->subset_tag); assert(aa != NULL); if (j > 2) - luatex_warn - ("\nmake_subset_tag(): subset-tag collision, resolved in round %d.\n", - j); + formatted_warning("subsets","subset-tag collision, resolved in round %d",j); } @ @c @@ -130,77 +128,11 @@ void tex_printf(const char *fmt, ...) va_end(args); } -@ |luatex_fail| may be called when a buffer overflow has happened/is - happening, therefore may not call mktexstring. However, with the - current implementation it appears that error messages are misleading, - possibly because pool overflows are detected too late. - - The output format of this fuction must be the same as |normal_error| in - pdftex.web! - -@c -__attribute__ ((noreturn, format(printf, 1, 2))) -void luatex_fail(const char *fmt, ...) -{ - va_list args; - va_start(args, fmt); - print_ln(); - tprint("!LuaTeX error"); - if (cur_file_name) { - tprint(" (file "); - tprint(cur_file_name); - tprint(")"); - } - tprint(": "); - vsnprintf(print_buf, PRINTF_BUF_SIZE, fmt, args); - tprint(print_buf); - va_end(args); - print_ln(); - remove_pdffile(static_pdf); - tprint(" ==> Fatal error occurred, no output PDF file produced!"); - print_ln(); - if (kpathsea_debug) { - abort(); - } else { - exit(EXIT_FAILURE); - } -} - -@ The output format of this fuction must be the same as |normal_warn| in - pdftex.web! -@c -__attribute__ ((format(printf, 1, 2))) -void luatex_warn(const char *fmt, ...) -{ - int old_selector = selector; - va_list args; - va_start(args, fmt); - selector = term_and_log; - print_ln(); - tex_printf("warning"); - if (cur_file_name) - tex_printf(" (file %s)", cur_file_name); - tex_printf(": "); - vsnprintf(print_buf, PRINTF_BUF_SIZE, fmt, args); - tprint(print_buf); - va_end(args); - print_ln(); - selector = old_selector; -} - -@ @c -void garbage_warning(void) -{ - luatex_warn("dangling objects discarded, no output file produced."); - remove_pdffile(static_pdf); -} - - @ @c size_t xfwrite(void *ptr, size_t size, size_t nmemb, FILE * stream) { if (fwrite(ptr, size, nmemb, stream) != nmemb) - luatex_fail("fwrite() failed"); + formatted_error("file io","fwrite() failed"); return nmemb; } @@ -208,7 +140,7 @@ size_t xfwrite(void *ptr, size_t size, size_t nmemb, FILE * stream) int xfflush(FILE * stream) { if (fflush(stream) != 0) - luatex_fail("fflush() failed (%s)", strerror(errno)); + formatted_error("file io","fflush() failed (%s)", strerror(errno)); return 0; } @@ -217,7 +149,7 @@ int xgetc(FILE * stream) { int c = getc(stream); if (c < 0 && c != EOF) - luatex_fail("getc() failed (%s)", strerror(errno)); + formatted_error("file io","getc() failed (%s)", strerror(errno)); return c; } @@ -226,7 +158,7 @@ int xputc(int c, FILE * stream) { int i = putc(c, stream); if (i < 0) - luatex_fail("putc() failed (%s)", strerror(errno)); + formatted_error("file io","putc() failed (%s)", strerror(errno)); return i; } @@ -239,7 +171,7 @@ scaled ext_xn_over_d(scaled x, scaled n, scaled d) else r -= 0.5; if (r >= (double) max_integer || r <= -(double) max_integer) - luatex_warn("arithmetic number too big"); + normal_warning("internal","arithmetic number too big"); return (scaled) r; } |