diff options
Diffstat (limited to 'Build/source/texk/web2c/luatexdir/lua')
24 files changed, 4225 insertions, 1986 deletions
diff --git a/Build/source/texk/web2c/luatexdir/lua/lcallbacklib.c b/Build/source/texk/web2c/luatexdir/lua/lcallbacklib.c index adbbd43becb..c29f2de0e96 100644 --- a/Build/source/texk/web2c/luatexdir/lua/lcallbacklib.c +++ b/Build/source/texk/web2c/luatexdir/lua/lcallbacklib.c @@ -17,13 +17,11 @@ You should have received a copy of the GNU General Public License along with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */ -#include "luatex-api.h" -#include <ptexlib.h> +#include "lua/luatex-api.h" +#include "ptexlib.h" static const char _svn_version[] = - "$Id: lcallbacklib.c 2448 2009-06-08 07:43:50Z taco $ $URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.40.6/source/texk/web2c/luatexdir/lua/lcallbacklib.c $"; - -static int do_run_callback(int special, const char *values, va_list vl); + "$Id: lcallbacklib.c 3404 2010-01-28 11:17:10Z taco $ $URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/lua/lcallbacklib.c $"; int callback_count = 0; int saved_callback_count = 0; @@ -49,7 +47,7 @@ static const char *const callbacknames[] = { "find_sfd_file", "read_sfd_file", "find_pk_file", "read_pk_file", "show_error_hook", - "process_input_buffer", + "process_input_buffer", "process_output_buffer", "start_page_number", "stop_page_number", "start_run", "stop_run", "define_font", @@ -79,9 +77,9 @@ void get_lua_boolean(const char *table, const char *name, boolean * target) if (lua_istable(Luas, -1)) { lua_getfield(Luas, -1, name); if (lua_isboolean(Luas, -1)) { - *target = (lua_toboolean(Luas, -1)); + *target = (boolean) (lua_toboolean(Luas, -1)); } else if (lua_isnumber(Luas, -1)) { - *target = (lua_tonumber(Luas, -1) == 0 ? 0 : 1); + *target = (boolean) (lua_tonumber(Luas, -1) == 0 ? 0 : 1); } } lua_settop(Luas, stacktop); @@ -97,16 +95,16 @@ void get_saved_lua_boolean(int r, const char *name, boolean * target) if (lua_istable(Luas, -1)) { lua_getfield(Luas, -1, name); if (lua_isboolean(Luas, -1)) { - *target = lua_toboolean(Luas, -1); + *target = (boolean) lua_toboolean(Luas, -1); } else if (lua_isnumber(Luas, -1)) { - *target = (lua_tonumber(Luas, -1) == 0 ? 0 : 1); + *target = (boolean) (lua_tonumber(Luas, -1) == 0 ? 0 : 1); } } lua_settop(Luas, stacktop); return; } -void get_lua_number(const char *table, const char *name, integer * target) +void get_lua_number(const char *table, const char *name, int *target) { int stacktop; stacktop = lua_gettop(Luas); @@ -115,14 +113,14 @@ void get_lua_number(const char *table, const char *name, integer * target) if (lua_istable(Luas, -1)) { lua_getfield(Luas, -1, name); if (lua_isnumber(Luas, -1)) { - *target = lua_tonumber(Luas, -1); + lua_number2int(*target, lua_tonumber(Luas, -1)); } } lua_settop(Luas, stacktop); return; } -void get_saved_lua_number(int r, const char *name, integer * target) +void get_saved_lua_number(int r, const char *name, int *target) { int stacktop; stacktop = lua_gettop(Luas); @@ -131,7 +129,7 @@ void get_saved_lua_number(int r, const char *name, integer * target) if (lua_istable(Luas, -1)) { lua_getfield(Luas, -1, name); if (lua_isnumber(Luas, -1)) { - *target = lua_tonumber(Luas, -1); + lua_number2int(*target, lua_tonumber(Luas, -1)); } } lua_settop(Luas, stacktop); @@ -139,7 +137,7 @@ void get_saved_lua_number(int r, const char *name, integer * target) } -void get_lua_string(const char *table, const char *name, const char **target) +void get_lua_string(const char *table, const char *name, char **target) { int stacktop; stacktop = lua_gettop(Luas); @@ -148,14 +146,14 @@ void get_lua_string(const char *table, const char *name, const char **target) if (lua_istable(Luas, -1)) { lua_getfield(Luas, -1, name); if (lua_isstring(Luas, -1)) { - *target = lua_tostring(Luas, -1); + *target = xstrdup(lua_tostring(Luas, -1)); } } lua_settop(Luas, stacktop); return; } -void get_saved_lua_string(int r, const char *name, const char **target) +void get_saved_lua_string(int r, const char *name, char **target) { int stacktop; stacktop = lua_gettop(Luas); @@ -164,7 +162,7 @@ void get_saved_lua_string(int r, const char *name, const char **target) if (lua_istable(Luas, -1)) { lua_getfield(Luas, -1, name); if (lua_isstring(Luas, -1)) { - *target = lua_tostring(Luas, -1); + *target = xstrdup(lua_tostring(Luas, -1)); } } lua_settop(Luas, stacktop); @@ -266,7 +264,7 @@ int do_run_callback(int special, const char *values, va_list vl) } ss = index(values, '>'); assert(ss); - luaL_checkstack(L, (ss - values + 1), "out of stack space"); + luaL_checkstack(L, (int) (ss - values + 1), "out of stack space"); ss = NULL; for (narg = 0; *values; narg++) { switch (*values++) { @@ -289,7 +287,8 @@ int do_run_callback(int special, const char *values, va_list vl) lua_pushboolean(L, va_arg(vl, int)); break; case CALLBACK_LINE: /* a buffer section, with implied start */ - lua_pushlstring(L, (char *) (buffer + first), va_arg(vl, int)); + lua_pushlstring(L, (char *) (buffer + first), + (size_t) va_arg(vl, int)); break; case '-': narg--; @@ -301,7 +300,7 @@ int do_run_callback(int special, const char *values, va_list vl) } } ENDARGS: - nres = strlen(values); + nres = (int) strlen(values); if (special == 1) { nres++; } @@ -350,7 +349,7 @@ int do_run_callback(int special, const char *values, va_list vl) lua_typename(L, lua_type(L, nres))); goto EXIT; } - b = lua_tonumber(L, nres); + lua_number2int(b, lua_tonumber(L, nres)); *va_arg(vl, int *) = b; break; case CALLBACK_LINE: /* TeX line */ @@ -365,9 +364,9 @@ int do_run_callback(int special, const char *values, va_list vl) bufloc = va_arg(vl, int *); if (len != 0) { ret = *bufloc; - check_buffer_overflow(ret + len); + check_buffer_overflow(ret + (int) len); strncpy((char *) (buffer + ret), s, len); - *bufloc += len; + *bufloc += (int) len; /* while (len--) { buffer[(*bufloc)++] = *s++; } */ while ((*bufloc) - 1 > ret && buffer[(*bufloc) - 1] == ' ') (*bufloc)--; @@ -404,7 +403,7 @@ int do_run_callback(int special, const char *values, va_list vl) if (s == NULL) /* |len| can be zero */ *va_arg(vl, int *) = 0; else { - ss = xmalloc(len + 1); + ss = xmalloc((unsigned) (len + 1)); (void) memcpy(ss, s, (len + 1)); *va_arg(vl, char **) = ss; } diff --git a/Build/source/texk/web2c/luatexdir/lua/lepdflib.cc b/Build/source/texk/web2c/luatexdir/lua/lepdflib.cc new file mode 100644 index 00000000000..551cc2d1ee3 --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/lua/lepdflib.cc @@ -0,0 +1,58 @@ +/* lepdflib.cc + + Copyright 2009-2010 Taco Hoekwater <taco@luatex.org> + + This file is part of LuaTeX. + + LuaTeX is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your + option) any later version. + + LuaTeX is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. + + You should have received a copy of the GNU General Public License along + with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */ + +static const char _svn_version[] = + "$Id: lepdflib.cc 3366 2010-01-20 14:49:31Z taco $ " + "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/lua/lepdflib.cc $"; + +#include "image/epdf.h" + +//********************************************************************** + +int l_new_pdfdoc(lua_State * L) +{ + PdfDocument *pdf_doc; + char *file_path; + if (lua_gettop(L) != 1) + luaL_error(L, "epdf.new() needs exactly 1 argument"); + if (!lua_isstring(L, -1)) + luaL_error(L, "epdf.new() needs filename (string)"); + file_path = (char *) lua_tostring(L, -1); + + printf("\n======================== 1 <%s>\n", file_path); + + pdf_doc = refPdfDocument(file_path); + + return 0; +} + +//********************************************************************** + +static const struct luaL_Reg epdflib[] = { + // {"new", l_new_pdfdoc}, + {NULL, NULL} /* sentinel */ +}; + +int luaopen_epdf(lua_State * L) +{ + luaL_register(L, "epdf", epdflib); + return 1; +} + +//********************************************************************** diff --git a/Build/source/texk/web2c/luatexdir/lua/lfontlib.c b/Build/source/texk/web2c/luatexdir/lua/lfontlib.c index c07da9d0717..32b9e776fc1 100644 --- a/Build/source/texk/web2c/luatexdir/lua/lfontlib.c +++ b/Build/source/texk/web2c/luatexdir/lua/lfontlib.c @@ -1,6 +1,6 @@ /* lfontlib.c - Copyright 2006-2008 Taco Hoekwater <taco@luatex.org> + Copyright 2006-2010 Taco Hoekwater <taco@luatex.org> This file is part of LuaTeX. @@ -17,12 +17,12 @@ You should have received a copy of the GNU General Public License along with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */ -#include "luatex-api.h" -#include <ptexlib.h> -#include "nodes.h" +#include "lua/luatex-api.h" +#include "ptexlib.h" + static const char _svn_version[] = - "$Id: lfontlib.c 2448 2009-06-08 07:43:50Z taco $ $URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.40.6/source/texk/web2c/luatexdir/lua/lfontlib.c $"; + "$Id: lfontlib.c 3551 2010-03-26 14:43:50Z taco $ $URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/lua/lfontlib.c $"; #define TIMERS 0 @@ -30,7 +30,6 @@ static const char _svn_version[] = # include <sys/time.h> #endif -#include "inc-vfovf.h" static int get_fontid(void) { @@ -42,14 +41,14 @@ static int get_fontid(void) static int font_read_tfm(lua_State * L) { - internalfontnumber f; + internal_font_number f; scaled s; int k; const char *cnom; if (lua_isstring(L, 1)) { cnom = lua_tostring(L, 1); if (lua_isnumber(L, 2)) { - s = (integer) lua_tonumber(L, 2); + lua_number2int(s, lua_tonumber(L, 2)); if (strlen(cnom)) { f = get_fontid(); if (read_tfm_info(f, cnom, s)) { @@ -58,20 +57,16 @@ static int font_read_tfm(lua_State * L) return k; } else { delete_font(f); - lua_pushstring(L, "font loading failed"); - lua_error(L); + luaL_error(L, "font loading failed"); } } else { - lua_pushstring(L, "expected tfm name as first argument"); - lua_error(L); + luaL_error(L, "expected tfm name as first argument"); } } else { - lua_pushstring(L, "expected an integer size as second argument"); - lua_error(L); + luaL_error(L, "expected an integer size as second argument"); } } else { - lua_pushstring(L, "expected tfm name as first argument"); - lua_error(L); + luaL_error(L, "expected tfm name as first argument"); } return 2; /* not reached */ } @@ -79,24 +74,22 @@ static int font_read_tfm(lua_State * L) static int font_read_vf(lua_State * L) { - scaled s; + int i; const char *cnom; if (lua_isstring(L, 1)) { cnom = lua_tostring(L, 1); if (strlen(cnom)) { if (lua_isnumber(L, 2)) { - s = lua_tonumber(L, 2); - return make_vf_table(L, cnom, s); + lua_number2int(i, lua_tonumber(L, 2)); + return make_vf_table(L, cnom, (scaled) i); } else { - lua_pushstring(L, + luaL_error(L, "expected an integer size as second argument"); - lua_error(L); return 2; } } } - lua_pushstring(L, "expected vf name as first argument"); - lua_error(L); + luaL_error(L, "expected vf name as first argument"); return 2; /* not reached */ } @@ -109,8 +102,7 @@ static int tex_current_font(lua_State * L) zset_cur_font(i); return 0; } else { - lua_pushstring(L, "expected a valid font id"); - lua_error(L); + luaL_error(L, "expected a valid font id"); return 2; /* not reached */ } } else { @@ -129,8 +121,8 @@ static int tex_max_font(lua_State * L) static int tex_each_font_next(lua_State * L) { int i, m; /* id */ - m = lua_tonumber(L, 1); - i = lua_tonumber(L, 2); + lua_number2int(m, lua_tonumber(L, 1)); + lua_number2int(i, lua_tonumber(L, 2)); i++; while (i <= m && !is_valid_font(i)) i++; @@ -139,7 +131,8 @@ static int tex_each_font_next(lua_State * L) return 1; } else { lua_pushnumber(L, i); - font_to_lua(L, i); + if (!font_to_lua(L, i)) + lua_pushnil(L); return 2; } } @@ -168,8 +161,7 @@ static int frozenfont(lua_State * L) } return 1; } else { - lua_pushstring(L, "expected an integer argument"); - lua_error(L); + luaL_error(L, "expected an integer argument"); } return 0; /* not reached */ } @@ -185,13 +177,11 @@ static int setfont(lua_State * L) if (!(font_touched(i) || font_used(i))) { font_from_lua(L, i); } else { - lua_pushstring(L, + luaL_error(L, "that font has been accessed already, changing it is forbidden"); - lua_error(L); } } else { - lua_pushstring(L, "that integer id is not a valid font"); - lua_error(L); + luaL_error(L, "that integer id is not a valid font"); } } return 0; @@ -227,8 +217,7 @@ static int deffont(lua_State * L) } else { lua_pop(L, 1); /* pop the broken table */ delete_font(i); - lua_pushstring(L, "font creation failed"); - lua_error(L); + luaL_error(L, "font creation failed"); } return 0; /* not reached */ } @@ -254,6 +243,30 @@ static int getfont(lua_State * L) } +static int getfontid(lua_State * L) +{ + const char *s; + size_t ff; + int cur_cs; + int f; + if (lua_type(L, 1) == LUA_TSTRING) { + s = lua_tolstring(L, 1, &ff); + cur_cs = string_lookup(s, ff); + if (cur_cs == undefined_control_sequence || cur_cs == undefined_cs_cmd + || eq_type(cur_cs) != set_font_cmd) { + lua_pushstring(L, "not a valid font csname"); + f = -1; + } else { + f = equiv(cur_cs); + } + lua_pushnumber(L, f); + } else { + luaL_error(L, "expected font csname string as argument"); + } + return 1; +} + + static const struct luaL_reg fontlib[] = { {"read_tfm", font_read_tfm}, {"read_vf", font_read_vf}, @@ -264,6 +277,7 @@ static const struct luaL_reg fontlib[] = { {"setfont", setfont}, {"define", deffont}, {"nextid", nextfontid}, + {"id", getfontid}, {"frozen", frozenfont}, {NULL, NULL} /* sentinel */ }; diff --git a/Build/source/texk/web2c/luatexdir/lua/limglib.c b/Build/source/texk/web2c/luatexdir/lua/limglib.c index 7663d022c03..0c2d7e4d65e 100644 --- a/Build/source/texk/web2c/luatexdir/lua/limglib.c +++ b/Build/source/texk/web2c/luatexdir/lua/limglib.c @@ -1,6 +1,6 @@ /* limglib.c - Copyright 2006-2008 Taco Hoekwater <taco@luatex.org> + Copyright 2006-2010 Taco Hoekwater <taco@luatex.org> This file is part of LuaTeX. @@ -17,18 +17,17 @@ You should have received a copy of the GNU General Public License along with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */ +static const char _svn_version[] = + "$Id: limglib.c 3404 2010-01-28 11:17:10Z taco $ " + "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/lua/limglib.c $"; + #include <stdio.h> #include <string.h> #include <assert.h> -#include <../lua51/lua.h> -#include <../lua51/lauxlib.h> -#include <ptexlib.h> -#include "luatex-api.h" -#include "inc-extra.h" - -static const char _svn_version[] = - "$Id: limglib.c 2329 2009-04-18 14:25:30Z hhenkel $ " - "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.40.6/source/texk/web2c/luatexdir/lua/limglib.c $"; +#include "lua51/lua.h" +#include "lua51/lauxlib.h" +#include "ptexlib.h" +#include "lua/luatex-api.h" /**********************************************************************/ @@ -48,7 +47,7 @@ void stackDump(lua_State * L, char *s) printf(lua_toboolean(L, i) ? "true" : "false"); break; case LUA_TNUMBER: /* numbers */ - printf("%g", lua_tonumber(L, i)); + printf("%g", (double) lua_tonumber(L, i)); break; default: /* other values */ printf("%s", lua_typename(L, t)); @@ -68,12 +67,7 @@ typedef enum { P__ZERO, P_ATTR, P_BBOX, P_COLORDEPTH, P_COLORSPACE, P_DEPTH, P_WIDTH, P_XRES, P_XSIZE, P_YRES, P_YSIZE, P__SENTINEL } parm_idx; -typedef struct { - const char *name; /* parameter name */ - parm_idx idx; /* index within img_parms array */ -} parm_struct; - -const parm_struct img_parms[] = { +static const parm_struct img_parms[] = { {NULL, P__ZERO}, /* dummy; lua indices run from 1 */ {"attr", P_ATTR}, {"bbox", P_BBOX}, @@ -120,7 +114,7 @@ static void image_to_lua(lua_State * L, image * a) if (!lua_isnumber(L, -1)) /* !i k u ... */ luaL_error(L, "image_to_lua(): %s is not a valid image key", lua_tostring(L, -2)); - i = lua_tointeger(L, -1); /* i k u ... */ + i = (int) lua_tointeger(L, -1); /* i k u ... */ lua_pop(L, 2); /* u ... */ switch (i) { case P_WIDTH: @@ -281,59 +275,47 @@ static void lua_to_image(lua_State * L, image * a) if (!lua_isnumber(L, -1)) /* !i v k t ... */ luaL_error(L, "lua_to_image(): %s is not a valid image key", lua_tostring(L, -3)); - i = lua_tointeger(L, -1); /* i v k t ... */ + i = (int) lua_tointeger(L, -1); /* i v k t ... */ lua_pop(L, 1); /* v k t ... */ switch (i) { case P_WIDTH: - if (img_is_refered(a)) - luaL_error(L, "image.width is now read-only"); if (lua_isnil(L, -1)) set_wd_running(a); else if (lua_type(L, -1) == LUA_TNUMBER) - img_width(a) = lua_tointeger(L, -1); + img_width(a) = (int) lua_tointeger(L, -1); else if (lua_type(L, -1) == LUA_TSTRING) img_width(a) = dimen_to_number(L, lua_tostring(L, -1)); else luaL_error(L, "image.width needs integer or nil value or dimension string"); - img_unset_scaled(a); break; case P_HEIGHT: - if (img_is_refered(a)) - luaL_error(L, "image.height is now read-only"); if (lua_isnil(L, -1)) set_ht_running(a); else if (lua_type(L, -1) == LUA_TNUMBER) - img_height(a) = lua_tointeger(L, -1); + img_height(a) = (int) lua_tointeger(L, -1); else if (lua_type(L, -1) == LUA_TSTRING) img_height(a) = dimen_to_number(L, lua_tostring(L, -1)); else luaL_error(L, "image.height needs integer or nil value or dimension string"); - img_unset_scaled(a); break; case P_DEPTH: - if (img_is_refered(a)) - luaL_error(L, "image.depth is now read-only"); if (lua_isnil(L, -1)) set_dp_running(a); else if (lua_type(L, -1) == LUA_TNUMBER) - img_depth(a) = lua_tointeger(L, -1); + img_depth(a) = (int) lua_tointeger(L, -1); else if (lua_type(L, -1) == LUA_TSTRING) img_depth(a) = dimen_to_number(L, lua_tostring(L, -1)); else luaL_error(L, "image.depth needs integer or nil value or dimension string"); - img_unset_scaled(a); break; case P_TRANSFORM: - if (img_is_refered(a)) - luaL_error(L, "image.transform is now read-only"); if (lua_isnumber(L, -1)) - img_transform(a) = lua_tointeger(L, -1); + img_transform(a) = (int) lua_tointeger(L, -1); else luaL_error(L, "image.transform needs integer value"); - img_unset_scaled(a); break; /* now follow all image_dict entries */ case P_FILENAME: @@ -342,8 +324,7 @@ static void lua_to_image(lua_State * L, image * a) if (img_type(d) == IMG_TYPE_PDFSTREAM) luaL_error(L, "image.filename can't be used with image.stream"); if (lua_isstring(L, -1)) { - if (img_filename(d) != NULL) - xfree(img_filename(d)); + xfree(img_filename(d)); img_filename(d) = xstrdup(lua_tostring(L, -1)); } else luaL_error(L, "image.filename needs string value"); @@ -352,8 +333,7 @@ static void lua_to_image(lua_State * L, image * a) if (img_state(d) >= DICT_FILESCANNED) luaL_error(L, "image.attr is now read-only"); if (lua_isstring(L, -1) || lua_isnil(L, -1)) { - if (img_attr(d) != NULL) - xfree(img_attr(d)); + xfree(img_attr(d)); if (lua_isstring(L, -1)) img_attr(d) = xstrdup(lua_tostring(L, -1)); } else @@ -363,15 +343,12 @@ static void lua_to_image(lua_State * L, image * a) if (img_state(d) >= DICT_FILESCANNED) luaL_error(L, "image.page is now read-only"); if (lua_type(L, -1) == LUA_TSTRING) { - if (img_pagename(d) != NULL) - xfree(img_pagename(d)); + xfree(img_pagename(d)); img_pagename(d) = xstrdup(lua_tostring(L, -1)); img_pagenum(d) = 0; } else if (lua_type(L, -1) == LUA_TNUMBER) { - img_pagenum(d) = lua_tointeger(L, -1); - if (img_pagename(d) != NULL) - xfree(img_pagename(d)); - img_pagename(d) = NULL; + img_pagenum(d) = (int) lua_tointeger(L, -1); + xfree(img_pagename(d)); } else luaL_error(L, "image.page needs integer or string value"); break; @@ -381,7 +358,7 @@ static void lua_to_image(lua_State * L, image * a) if (lua_isnil(L, -1)) img_colorspace(d) = 0; else if (lua_isnumber(L, -1)) - img_colorspace(d) = lua_tointeger(L, -1); + img_colorspace(d) = (int) lua_tointeger(L, -1); else luaL_error(L, "image.colorspace needs integer or nil value"); break; @@ -406,17 +383,15 @@ static void lua_to_image(lua_State * L, image * a) lua_pushinteger(L, i); /* idx v k t ... */ lua_gettable(L, -2); /* int v k t ... */ if (lua_type(L, -1) == LUA_TNUMBER) - img_bbox(d)[i - 1] = lua_tointeger(L, -1); + img_bbox(d)[i - 1] = (int) lua_tointeger(L, -1); else if (lua_type(L, -1) == LUA_TSTRING) - img_bbox(d)[i - 1] = - dimen_to_number(L, lua_tostring(L, -1)); + img_bbox(d)[i - 1] = dimen_to_number(L, lua_tostring(L, -1)); else luaL_error(L, "image.bbox table needs integer value or dimension string elements"); lua_pop(L, 1); /* v k t ... */ } img_set_bbox(d); - img_unset_scaled(a); break; case P_STREAM: if (img_filename(d) != NULL) @@ -425,11 +400,9 @@ static void lua_to_image(lua_State * L, image * a) luaL_error(L, "image.stream is now read-only"); if (img_pdfstream_ptr(d) == NULL) new_img_pdfstream_struct(d); - if (img_pdfstream_stream(d) != NULL) - xfree(img_pdfstream_stream(d)); + xfree(img_pdfstream_stream(d)); img_pdfstream_stream(d) = xstrdup(lua_tostring(L, -1)); img_type(d) = IMG_TYPE_PDFSTREAM; - img_unset_scaled(a); break; case P_FILEPATH: case P_TOTALPAGES: @@ -451,17 +424,7 @@ static void lua_to_image(lua_State * L, image * a) /**********************************************************************/ -static void fix_image_size(lua_State * L, image * a) -{ - if (!img_is_scaled(a) || is_wd_running(a) || is_ht_running(a) - || is_dp_running(a)) { - if (img_is_refered(a)) - luaL_error(L, "image is read-only"); - scale_img(a); - } -} - -static void copy_image(lua_State * L, lua_Number scale) +void copy_image(lua_State * L, lua_Number scale) { image *a, **aa, *b, **bb; if (lua_gettop(L) != 1) @@ -474,11 +437,11 @@ static void copy_image(lua_State * L, lua_Number scale) lua_setmetatable(L, -2); /* b */ b = *bb = new_image(); if (!is_wd_running(a)) - img_width(b) = zround(img_width(a) * scale); + img_width(b) = do_zround(img_width(a) * scale); if (!is_ht_running(a)) - img_height(b) = zround(img_height(a) * scale); + img_height(b) = do_zround(img_height(a) * scale); if (!is_dp_running(a)) - img_depth(b) = zround(img_depth(a) * scale); + img_depth(b) = do_zround(img_depth(a) * scale); img_transform(b) = img_transform(a); img_dict(b) = img_dict(a); if (img_dictref(a) != LUA_NOREF) { @@ -530,7 +493,7 @@ static int l_copy_image(lua_State * L) return 1; /* image */ } -static void read_scale_img(lua_State * L, image * a) +static void read_scale_img(image * a) { image_dict *ad; assert(a != NULL); @@ -540,18 +503,13 @@ static void read_scale_img(lua_State * L, image * a) if (img_type(ad) == IMG_TYPE_PDFSTREAM) check_pdfstream_dict(ad); else { - /* check_pdfminorversion() should not be here, as it belongs - * to the output functions, and it is too early here to start - * already the PDF file only for image file scanning; but - * it's needed as several fixed_* parameters are used early, - * e. g. by read_png_info(). */ - check_pdfminorversion(); - read_img(ad, get_pdf_minor_version(), - get_pdf_inclusion_errorlevel()); - img_unset_scaled(a); + fix_pdf_minorversion(static_pdf); + read_img(static_pdf, + ad, pdf_minor_version, pdf_inclusion_errorlevel); } } - fix_image_size(L, a); + if (is_wd_running(a) || is_ht_running(a) || is_dp_running(a)) + img_dimen(a) = scale_img(ad, img_dimen(a), img_transform(a)); } static int l_scan_image(lua_State * L) @@ -563,13 +521,13 @@ static int l_scan_image(lua_State * L) (void) l_new_image(L); /* image --- if everything worked well */ aa = (image **) luaL_checkudata(L, 1, TYPE_IMG); /* image */ a = *aa; - check_pdfoutput(maketexstring("img.scan()"), true); - flush_str(last_tex_string); - read_scale_img(L, a); + check_o_mode(static_pdf, "img.scan()", 1 << OMODE_PDF, false); + /* flush_str(last_tex_string); *//* ?? */ + read_scale_img(a); return 1; /* image */ } -static halfword img_to_node(image * a, integer ref) +static halfword img_to_node(image * a) { image_dict *ad; halfword n; @@ -578,10 +536,11 @@ static halfword img_to_node(image * a, integer ref) assert(ad != NULL); assert(img_objnum(ad) != 0); n = new_node(whatsit_node, pdf_refximage_node); - pdf_ximage_ref(n) = ref; - pdf_width(n) = img_width(a); - pdf_height(n) = img_height(a); - pdf_depth(n) = img_depth(a); + pdf_ximage_index(n) = img_index(ad); + width(n) = img_width(a); + height(n) = img_height(a); + depth(n) = img_depth(a); + pdf_ximage_transform(n) = img_transform(a); return n; } @@ -589,22 +548,21 @@ typedef enum { WR_WRITE, WR_IMMEDIATEWRITE, WR_NODE, WR_VF_IMG } wrtype_e; const char *wrtype_s[] = { "img.write()", "img.immediatewrite()", "img.node()", "write vf image" }; -static void setup_image(lua_State * L, image * a, wrtype_e writetype) +static void setup_image(PDF pdf, image * a, wrtype_e writetype) { image_dict *ad; assert(a != NULL); ad = img_dict(a); - check_pdfoutput(maketexstring(wrtype_s[writetype]), true); - flush_str(last_tex_string); - read_scale_img(L, a); - if (img_arrayidx(a) == -1) - img_arrayidx(a) = img_to_array(a); /* now a is read-only */ + check_o_mode(pdf, wrtype_s[writetype], 1 << OMODE_PDF, false); + /* flush_str(last_tex_string); *//* ?? */ + read_scale_img(a); if (img_objnum(ad) == 0) { /* latest needed just before out_img() */ - pdf_ximage_count++; - pdf_create_obj(obj_type_ximage, pdf_ximage_count); - img_objnum(ad) = obj_ptr; - img_index(ad) = pdf_ximage_count; - obj_data_ptr(obj_ptr) = img_arrayidx(a); + pdf->ximage_count++; + pdf_create_obj(pdf, obj_type_ximage, pdf->ximage_count); + img_objnum(ad) = pdf->obj_ptr; + img_index(ad) = pdf->ximage_count; + idict_to_array(ad); /* now ad is read-only */ + obj_data_ptr(pdf, pdf->obj_ptr) = img_index(ad); } } @@ -620,20 +578,19 @@ static void write_image_or_node(lua_State * L, wrtype_e writetype) aa = (image **) luaL_checkudata(L, 1, TYPE_IMG); /* image */ a = *aa; ad = img_dict(a); - setup_image(L, a, writetype); + setup_image(static_pdf, a, writetype); switch (writetype) { case WR_WRITE: - n = img_to_node(a, img_arrayidx(a)); - new_tail_append(n); + n = img_to_node(a); + tail_append(n); break; /* image */ case WR_IMMEDIATEWRITE: - check_pdfminorversion(); /* does initialization stuff */ - pdf_begin_dict(img_objnum(ad), 0); - write_img(ad); + pdf_begin_dict(static_pdf, img_objnum(ad), 0); + write_img(static_pdf, ad); break; /* image */ case WR_NODE: /* image */ lua_pop(L, 1); /* - */ - n = img_to_node(a, img_arrayidx(a)); + n = img_to_node(a); lua_nodelib_push_fast(L, n); break; /* node */ default: @@ -651,6 +608,7 @@ static int l_write_image(lua_State * L) static int l_immediatewrite_image(lua_State * L) { + check_o_mode(static_pdf, "img.immediatewrite()", 1 << OMODE_PDF, true); write_image_or_node(L, WR_IMMEDIATEWRITE); return 1; /* image */ } @@ -720,16 +678,18 @@ static const struct luaL_Reg imglib[] = { /**********************************************************************/ -void vf_out_image(unsigned i) +void vf_out_image(PDF pdf, unsigned i) { image *a, **aa; + image_dict *ad; lua_State *L = Luas; /* ... */ - lua_rawgeti(L, LUA_GLOBALSINDEX, i); /* image ... */ + lua_rawgeti(L, LUA_GLOBALSINDEX, (int) i); /* image ... */ aa = (image **) luaL_checkudata(L, -1, TYPE_IMG); a = *aa; - setup_image(L, a, WR_VF_IMG); /* image ... */ - assert(img_is_refered(a)); - output_image(img_arrayidx(a)); + ad = img_dict(a); + assert(ad != NULL); + setup_image(pdf, a, WR_VF_IMG); /* image ... */ + place_img(pdf, ad, img_dimen(a), img_transform(a)); lua_pop(L, 1); /* ... */ } @@ -784,13 +744,15 @@ static int m_img_print(lua_State * L) static int m_img_gc(lua_State * L) { image *a, **aa; + image_dict *d; aa = (image **) luaL_checkudata(L, 1, TYPE_IMG); a = *aa; + d = img_dict(*aa); #ifdef DEBUG printf("\n===== IMG GC ===== a=%d ad=%d\n", a, img_dict(a)); #endif luaL_unref(L, LUA_GLOBALSINDEX, img_dictref(a)); - if (!img_is_refered(a)) + if (!img_is_refered(d)) xfree(a); return 0; } @@ -827,19 +789,6 @@ static const struct luaL_Reg img_dict_m[] = { /**********************************************************************/ -static void preset_environment(lua_State * L, const parm_struct * p) -{ - int i; - lua_newtable(L); /* t */ - for (i = 1, ++p; p->name != NULL; i++, p++) { - assert(i == (int) p->idx); - lua_pushstring(L, p->name); /* k t */ - lua_pushinteger(L, (int) p->idx); /* v k t */ - lua_settable(L, -3); /* t */ - } - lua_replace(L, LUA_ENVIRONINDEX); /* - */ -} - int luaopen_img(lua_State * L) { preset_environment(L, img_parms); diff --git a/Build/source/texk/web2c/luatexdir/lua/liolib.c b/Build/source/texk/web2c/luatexdir/lua/liolib.c index 28cfced022e..93d21b23697 100644 --- a/Build/source/texk/web2c/luatexdir/lua/liolib.c +++ b/Build/source/texk/web2c/luatexdir/lua/liolib.c @@ -1,5 +1,5 @@ /* -** $Id: liolib.c 2376 2009-05-08 08:40:13Z taco $ +** $Id: liolib.c 3404 2010-01-28 11:17:10Z taco $ ** Standard I/O (and system) library ** See Copyright Notice in lua.h */ @@ -22,7 +22,7 @@ #include "lauxlib.h" #include "lualib.h" -#include <ptexlib.h> +#include "ptexlib.h" #define IO_INPUT 1 #define IO_OUTPUT 2 @@ -203,7 +203,7 @@ static int io_popen(lua_State * L) if (restrictedshell == 0) allow = 1; else - allow = shell_cmd_is_allowed(cmd, &safecmd, &cmdname); + allow = shell_cmd_is_allowed(&cmd, &safecmd, &cmdname); if (allow == 1) { *pf = lua_popen(L, cmd, mode); @@ -415,16 +415,16 @@ static int read_chars(lua_State * L, FILE * f, size_t n) static int read_all(lua_State * L, FILE * f) { /* attempt to speed up reading whole files */ - size_t rlen; /* how much to read */ + long rlen; /* how much to read */ size_t nr; /* number of chars actually read */ - size_t old; /* old file location */ + long old; /* old file location */ char *p; old = ftell(f); if (old > 0 && (fseek(f, 0, SEEK_END) >= 0) && ((rlen = ftell(f)) > 0) && rlen < 1000 * 1000 * 100) { /* 100 MB */ fseek(f, old, SEEK_SET); - p = malloc(rlen); + p = malloc((size_t) rlen); if (p != NULL) { - nr = fread(p, sizeof(char), rlen, f); + nr = fread(p, sizeof(char), (size_t) rlen, f); lua_pushlstring(L, p, nr); free(p); return 1; @@ -565,12 +565,13 @@ static int f_seek(lua_State * L) static int f_setvbuf(lua_State * L) { + int sz, op, res; static const int mode[] = { _IONBF, _IOFBF, _IOLBF }; static const char *const modenames[] = { "no", "full", "line", NULL }; FILE *f = tofile(L); - int op = luaL_checkoption(L, 2, NULL, modenames); - lua_Integer sz = luaL_optinteger(L, 3, LUAL_BUFFERSIZE); - int res = setvbuf(f, NULL, mode[op], sz); + op = luaL_checkoption(L, 2, NULL, modenames); + lua_number2int(sz, luaL_optinteger(L, 3, LUAL_BUFFERSIZE)); + res = setvbuf(f, NULL, mode[op], (size_t) sz); return pushresult(L, res == 0, NULL); } diff --git a/Build/source/texk/web2c/luatexdir/lua/lkpselib.c b/Build/source/texk/web2c/luatexdir/lua/lkpselib.c index 71c772eb732..16c6a4ba23a 100644 --- a/Build/source/texk/web2c/luatexdir/lua/lkpselib.c +++ b/Build/source/texk/web2c/luatexdir/lua/lkpselib.c @@ -17,17 +17,20 @@ You should have received a copy of the GNU General Public License along with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */ -#include "luatex-api.h" -#include <ptexlib.h> +#include "lua/luatex-api.h" +#include "ptexlib.h" #include <kpathsea/expand.h> #include <kpathsea/variable.h> #include <kpathsea/tex-glyph.h> #include <kpathsea/readable.h> +#include <kpathsea/pathsearch.h> +#include <kpathsea/str-list.h> +#include <kpathsea/tex-file.h> static const char _svn_version[] = - "$Id: lkpselib.c 2414 2009-06-03 12:57:01Z taco $ $URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.40.6/source/texk/web2c/luatexdir/lua/lkpselib.c $"; + "$Id: lkpselib.c 3551 2010-03-26 14:43:50Z taco $ $URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/lua/lkpselib.c $"; -static const int filetypes[] = { +static const unsigned filetypes[] = { kpse_gf_format, kpse_pk_format, kpse_any_glyph_format, @@ -83,7 +86,8 @@ static const int filetypes[] = { kpse_fea_format, kpse_cid_format, kpse_mlbib_format, - kpse_mlbst_format + kpse_mlbst_format, + kpse_clua_format }; static const char *const filetypenames[] = { @@ -143,6 +147,7 @@ static const char *const filetypenames[] = { "cid maps", "mlbib", "mlbst", + "clua", NULL }; @@ -155,8 +160,7 @@ int program_name_set = 0; #define TEST_PROGRAM_NAME_SET do { \ if (! program_name_set) { \ - lua_pushstring(L, "Please call kpse.set_program_name() before using the library"); \ - return lua_error(L); \ + return luaL_error(L, "Please call kpse.set_program_name() before using the library"); \ } \ } while (0) @@ -164,12 +168,11 @@ static int find_file(lua_State * L) { int i; const char *st; - int ftype = kpse_tex_format; + unsigned ftype = kpse_tex_format; int mexist = 0; TEST_PROGRAM_NAME_SET; if (!lua_isstring(L, 1)) { - lua_pushstring(L, "not a file name"); - lua_error(L); + luaL_error(L, "not a file name"); } st = lua_tostring(L, 1); i = lua_gettop(L); @@ -177,7 +180,7 @@ static int find_file(lua_State * L) if (lua_isboolean(L, i)) { mexist = lua_toboolean(L, i); } else if (lua_isnumber(L, i)) { - mexist = lua_tonumber(L, i); + lua_number2int(mexist, lua_tonumber(L, i)); } else if (lua_isstring(L, i)) { int op = luaL_checkoption(L, i, NULL, filetypenames); ftype = filetypes[op]; @@ -188,7 +191,7 @@ static int find_file(lua_State * L) ftype == kpse_gf_format || ftype == kpse_any_glyph_format) { /* ret.format, ret.name, ret.dpi */ kpse_glyph_file_type ret; - lua_pushstring(L, kpse_find_glyph(st, mexist, ftype, &ret)); + lua_pushstring(L, kpse_find_glyph(st, (unsigned) mexist, ftype, &ret)); } else { if (mexist > 0) mexist = 1; @@ -203,16 +206,16 @@ static int find_file(lua_State * L) static int lua_kpathsea_find_file(lua_State * L) { int i; - int ftype = kpse_tex_format; + unsigned ftype = kpse_tex_format; int mexist = 0; kpathsea *kp = (kpathsea *) luaL_checkudata(L, 1, KPATHSEA_METATABLE); const char *st = luaL_checkstring(L, 2); i = lua_gettop(L); while (i > 2) { if (lua_isboolean(L, i)) { - mexist = lua_toboolean(L, i); + mexist = (boolean) lua_toboolean(L, i); } else if (lua_isnumber(L, i)) { - mexist = lua_tonumber(L, i); + lua_number2int(mexist, lua_tonumber(L, i)); } else if (lua_isstring(L, i)) { int op = luaL_checkoption(L, i, NULL, filetypenames); ftype = filetypes[op]; @@ -223,7 +226,9 @@ static int lua_kpathsea_find_file(lua_State * L) ftype == kpse_gf_format || ftype == kpse_any_glyph_format) { /* ret.format, ret.name, ret.dpi */ kpse_glyph_file_type ret; - lua_pushstring(L, kpathsea_find_glyph(*kp, st, mexist, ftype, &ret)); + lua_pushstring(L, + kpathsea_find_glyph(*kp, st, (unsigned) mexist, ftype, + &ret)); } else { if (mexist > 0) mexist = 1; @@ -238,7 +243,7 @@ static int lua_kpathsea_find_file(lua_State * L) static int show_path(lua_State * L) { int op = luaL_checkoption(L, -1, "tex", filetypenames); - int user_format = filetypes[op]; + unsigned user_format = filetypes[op]; TEST_PROGRAM_NAME_SET; if (!kpse_format_info[user_format].type) /* needed if arg was numeric */ kpse_init_format(user_format); @@ -250,7 +255,7 @@ static int lua_kpathsea_show_path(lua_State * L) { kpathsea *kp = (kpathsea *) luaL_checkudata(L, 1, KPATHSEA_METATABLE); int op = luaL_checkoption(L, -1, "tex", filetypenames); - int user_format = filetypes[op]; + unsigned user_format = filetypes[op]; if (!(*kp)->format_info[user_format].type) /* needed if arg was numeric */ kpathsea_init_format(*kp, user_format); lua_pushstring(L, (*kp)->format_info[user_format].path); @@ -323,6 +328,374 @@ static int lua_kpathsea_var_value(lua_State * L) return 1; } +static unsigned find_dpi(const_string s) +{ + unsigned dpi_number = 0; + string extension = find_suffix(s); + + if (extension != NULL) + sscanf(extension, "%u", &dpi_number); + + return dpi_number; +} + +/* Return newly-allocated NULL-terminated list of strings from MATCHES + that are prefixed with any of the subdirectories in SUBDIRS. That + is, for a string S in MATCHES, its dirname must end with one of the + elements in SUBDIRS. For instance, if subdir=foo/bar, that will + match a string foo/bar/baz or /some/texmf/foo/bar/baz. + + We don't reallocate the actual strings, just the list elements. + Perhaps later we will implement wildcards or // or something. */ + +static string *subdir_match(str_list_type subdirs, string * matches) +{ + string *ret = XTALLOC1(string); + unsigned len = 1; + unsigned m; + + for (m = 0; matches[m]; m++) { + size_t loc; + unsigned e; + string s = xstrdup(matches[m]); + for (loc = strlen(s); loc > 0 && !IS_DIR_SEP(s[loc - 1]); loc--); + while (loc > 0 && IS_DIR_SEP(s[loc - 1])) { + loc--; + } + s[loc] = 0; /* wipe out basename */ + + for (e = 0; e < STR_LIST_LENGTH(subdirs); e++) { + string subdir = STR_LIST_ELT(subdirs, e); + size_t subdir_len = strlen(subdir); + while (subdir_len > 0 && IS_DIR_SEP(subdir[subdir_len - 1])) { + subdir_len--; + subdir[subdir_len] = 0; /* remove trailing slashes from subdir spec */ + } + if (FILESTRCASEEQ(subdir, s + loc - subdir_len)) { + /* matched, save this one. */ + XRETALLOC(ret, len + 1, string); + ret[len - 1] = matches[m]; + len++; + } + } + free(s); + } + ret[len - 1] = NULL; + return ret; +} + +/* Use the file type from -format if that was specified (i.e., the + user_format global variable), else guess dynamically from NAME. + Return kpse_last_format if undeterminable. This function is also + used to parse the -format string, a case which we distinguish by + setting is_filename to false. + + A few filenames have been hard-coded for format types that + differ from what would be inferred from their extensions. */ + +static kpse_file_format_type +find_format(kpathsea kpse, const_string name, boolean is_filename) +{ + kpse_file_format_type ret; + + if (FILESTRCASEEQ(name, "config.ps")) { + ret = kpse_dvips_config_format; + } else if (FILESTRCASEEQ(name, "dvipdfmx.cfg")) { + ret = kpse_program_text_format; + } else if (FILESTRCASEEQ(name, "fmtutil.cnf")) { + ret = kpse_web2c_format; + } else if (FILESTRCASEEQ(name, "glyphlist.txt")) { + ret = kpse_fontmap_format; + } else if (FILESTRCASEEQ(name, "mktex.cnf")) { + ret = kpse_web2c_format; + } else if (FILESTRCASEEQ(name, "pdfglyphlist.txt")) { + ret = kpse_fontmap_format; + } else if (FILESTRCASEEQ(name, "pdftex.cfg")) { + ret = kpse_pdftex_config_format; + } else if (FILESTRCASEEQ(name, "texmf.cnf")) { + ret = kpse_cnf_format; + } else if (FILESTRCASEEQ(name, "updmap.cfg")) { + ret = kpse_web2c_format; + } else if (FILESTRCASEEQ(name, "XDvi")) { + ret = kpse_program_text_format; + } else { + int f = 0; /* kpse_file_format_type */ + size_t name_len = strlen(name); + +/* Have to rely on `try_len' being declared here, since we can't assume + GNU C and statement expressions. */ +#define TRY_SUFFIX(ftry) (\ + try_len = (ftry) ? strlen (ftry) : 0, \ + (ftry) && try_len <= name_len \ + && FILESTRCASEEQ (ftry, name + name_len - try_len)) + + while (f != kpse_last_format) { + size_t try_len; + const_string *ext; + const_string ftry; + boolean found = false; + + if (!kpse->format_info[f].type) + kpathsea_init_format(kpse, (kpse_file_format_type) f); + + if (!is_filename) { + /* Allow the long name, but only in the -format option. We don't + want a filename confused with a format name. */ + ftry = kpse->format_info[f].type; + found = TRY_SUFFIX(ftry); + } + for (ext = kpse->format_info[f].suffix; !found && ext && *ext; + ext++) { + found = TRY_SUFFIX(*ext); + } + for (ext = kpse->format_info[f].alt_suffix; !found && ext && *ext; + ext++) { + found = TRY_SUFFIX(*ext); + } + + if (found) + break; + + /* Some trickery here: the extensions for kpse_fmt_format can + * clash with other extensions in use, and we prefer for those + * others to be preferred. And we don't want to change the + * integer value of kpse_fmt_format. So skip it when first + * enountered, then use it when we've done everything else, + * and use it as the end-guard. + */ + if (f == kpse_fmt_format) { + f = kpse_last_format; + } else if (++f == kpse_fmt_format) { + f++; + } else if (f == kpse_last_format) { + f = kpse_fmt_format; + } + } + + /* If there was a match, f will be one past the correct value. */ + ret = f; + } + + return ret; +} + +/* kpse:lookup("plain.tex", {}) */ +static int do_lua_kpathsea_lookup(lua_State * L, kpathsea kpse, int idx) +{ + int i; + string ret = NULL; + string *ret_list = NULL; + const_string name = NULL; + string user_path = NULL; + boolean show_all = false; + boolean must_exist = false; + kpse_file_format_type user_format = kpse_last_format; + int dpi = 600; + str_list_type subdir_paths = { 0, NULL }; + unsigned saved_debug = kpse->debug; + int saved_mktexpk = kpse->format_info[kpse_pk_format].program_enabled_p; + int saved_mktexmf = kpse->format_info[kpse_mf_format].program_enabled_p; + int saved_mktextex = kpse->format_info[kpse_tex_format].program_enabled_p; + int saved_mktextfm = kpse->format_info[kpse_tfm_format].program_enabled_p; + name = luaL_checkstring(L, idx); + /* todo: fetch parameter values */ + + if (lua_type(L, idx + 1) == LUA_TTABLE) { + lua_pushstring(L, "format"); + lua_gettable(L, idx + 1); + if (lua_type(L, -1) == LUA_TSTRING) { + int op = luaL_checkoption(L, -1, NULL, filetypenames); + user_format = filetypes[op]; + } + lua_pop(L, 1); + lua_pushstring(L, "dpi"); + lua_gettable(L, idx + 1); + if (lua_type(L, -1) == LUA_TNUMBER) { + lua_number2int(dpi, lua_tonumber(L, -1)); + } + lua_pop(L, 1); + lua_pushstring(L, "debug"); + lua_gettable(L, idx + 1); + if (lua_type(L, -1) == LUA_TNUMBER) { + int d = 0; + lua_number2int(d, lua_tonumber(L, -1)); + kpse->debug |= d; + } + lua_pop(L, 1); + lua_pushstring(L, "path"); + lua_gettable(L, idx + 1); + if (lua_type(L, -1) == LUA_TSTRING) { + user_path = xstrdup(lua_tostring(L, -1)); + } + lua_pop(L, 1); + lua_pushstring(L, "all"); + lua_gettable(L, idx + 1); + if (lua_type(L, -1) == LUA_TBOOLEAN) { + show_all = lua_toboolean(L, -1); + } + lua_pop(L, 1); + + lua_pushstring(L, "mktexpk"); + lua_gettable(L, idx + 1); + if (lua_type(L, -1) == LUA_TBOOLEAN) { + kpathsea_maketex_option(kpse, "pk", lua_toboolean(L, -1)); + } + lua_pop(L, 1); + + lua_pushstring(L, "mktextex"); + lua_gettable(L, idx + 1); + if (lua_type(L, -1) == LUA_TBOOLEAN) { + kpathsea_maketex_option(kpse, "tex", lua_toboolean(L, -1)); + } + lua_pop(L, 1); + + lua_pushstring(L, "mktexmf"); + lua_gettable(L, idx + 1); + if (lua_type(L, -1) == LUA_TBOOLEAN) { + kpathsea_maketex_option(kpse, "mf", lua_toboolean(L, -1)); + } + lua_pop(L, 1); + + lua_pushstring(L, "mktextfm"); + lua_gettable(L, idx + 1); + if (lua_type(L, -1) == LUA_TBOOLEAN) { + kpathsea_maketex_option(kpse, "tfm", lua_toboolean(L, -1)); + } + lua_pop(L, 1); + + + lua_pushstring(L, "must-exist"); + lua_gettable(L, idx + 1); + if (lua_type(L, -1) == LUA_TBOOLEAN) { + must_exist = lua_toboolean(L, -1); + } + lua_pop(L, 1); + lua_pushstring(L, "subdir"); + lua_gettable(L, idx + 1); + if (lua_istable(L, -1)) { + lua_pushnil(L); + while (lua_next(L, -2) != 0) { /* numeric value */ + if (lua_isstring(L, -1)) { + char *s = xstrdup(lua_tostring(L, -1)); + str_list_add(&subdir_paths, s); + xfree(s); + } + lua_pop(L, 1); + } + } else if (lua_isstring(L, -1)) { + char *s = xstrdup(lua_tostring(L, -1)); + str_list_add(&subdir_paths, s); + xfree(s); + } + lua_pop(L, 1); + if (STR_LIST_LENGTH(subdir_paths) > 0) { + show_all = 1; + } + } + if (user_path) { + /* Translate ; to : if that's our ENV_SEP. See cnf.c. */ + if (IS_ENV_SEP(':')) { + string loc; + for (loc = user_path; *loc; loc++) { + if (*loc == ';') + *loc = ':'; + } + } + user_path = kpathsea_path_expand(kpse, user_path); + if (show_all) { + ret_list = kpathsea_all_path_search(kpse, user_path, name); + } else { + ret = kpathsea_path_search(kpse, user_path, name, must_exist); + } + free(user_path); + } else { + /* No user-specified search path, check user format or guess from NAME. */ + kpse_file_format_type fmt; + if (user_format != kpse_last_format) + fmt = user_format; + else + fmt = find_format(kpse, name, true); + + switch (fmt) { + case kpse_pk_format: + case kpse_gf_format: + case kpse_any_glyph_format: + { + kpse_glyph_file_type glyph_ret; + /* Try to extract the resolution from the name. */ + unsigned local_dpi = find_dpi(name); + if (!local_dpi) + local_dpi = (unsigned) dpi; + ret = + kpathsea_find_glyph(kpse, remove_suffix(name), local_dpi, + fmt, &glyph_ret); + } + break; + + case kpse_last_format: + /* If the suffix isn't recognized, assume it's a tex file. */ + fmt = kpse_tex_format; + /* fall through */ + + default: + if (show_all) { + ret_list = + kpathsea_find_file_generic(kpse, name, fmt, must_exist, + true); + } else { + ret = kpathsea_find_file(kpse, name, fmt, must_exist); + } + } + } + + /* Turn single return into a null-terminated list for uniform treatment. */ + if (ret) { + ret_list = XTALLOC(2, string); + ret_list[0] = ret; + ret_list[1] = NULL; + } + + /* Filter by subdirectories, if specified. */ + if (STR_LIST_LENGTH(subdir_paths) > 0) { + string *new_list = subdir_match(subdir_paths, ret_list); + free(ret_list); + ret_list = new_list; + } + kpse->debug = saved_debug; + kpse->format_info[kpse_pk_format].program_enabled_p = saved_mktexpk; + kpse->format_info[kpse_mf_format].program_enabled_p = saved_mktexmf; + kpse->format_info[kpse_tex_format].program_enabled_p = saved_mktextex; + kpse->format_info[kpse_tfm_format].program_enabled_p = saved_mktextfm; + + /* Print output. */ + i = 0; + if (ret_list) { + for (; ret_list[i]; i++) { + lua_pushstring(L, ret_list[i]); + } + free(ret_list); + } + if (i == 0) { + i++; + lua_pushnil(L); + } + return i; +} + + +static int lua_kpathsea_lookup(lua_State * L) +{ + kpathsea *kpsep = (kpathsea *) luaL_checkudata(L, 1, KPATHSEA_METATABLE); + kpathsea kpse = *kpsep; + return do_lua_kpathsea_lookup(L, kpse, 2); +} + +static int lua_kpse_lookup(lua_State * L) +{ + TEST_PROGRAM_NAME_SET; + return do_lua_kpathsea_lookup(L, kpse_def, 1); +} + /* Engine support is a bit of a problem, because we do not want * to interfere with the normal format discovery of |luatex|. @@ -354,7 +727,7 @@ static int set_program_name(lua_State * L) static int init_prog(lua_State * L) { const char *prefix = luaL_checkstring(L, 1); - unsigned dpi = luaL_checkinteger(L, 2); + unsigned dpi = (unsigned) luaL_checkinteger(L, 2); const char *mode = luaL_checkstring(L, 3); const char *fallback = luaL_optstring(L, 4, NULL); TEST_PROGRAM_NAME_SET; @@ -366,18 +739,24 @@ static int lua_kpathsea_init_prog(lua_State * L) { kpathsea *kp = (kpathsea *) luaL_checkudata(L, 1, KPATHSEA_METATABLE); const char *prefix = luaL_checkstring(L, 2); - unsigned dpi = luaL_checkinteger(L, 3); + unsigned dpi = (unsigned) luaL_checkinteger(L, 3); const char *mode = luaL_checkstring(L, 4); const char *fallback = luaL_optstring(L, 5, NULL); kpathsea_init_prog(*kp, prefix, dpi, mode, fallback); return 0; } +static int lua_kpse_version(lua_State * L) +{ + lua_pushstring(L, kpathsea_version_string); + return 1; +} + static int readable_file(lua_State * L) { const char *name = luaL_checkstring(L, 1); TEST_PROGRAM_NAME_SET; - lua_pushstring(L, kpse_readable_file(name)); + lua_pushstring(L, (char *) kpse_readable_file(name)); return 1; } @@ -385,7 +764,7 @@ static int lua_kpathsea_readable_file(lua_State * L) { kpathsea *kp = (kpathsea *) luaL_checkudata(L, 1, KPATHSEA_METATABLE); const char *name = luaL_checkstring(L, 2); - lua_pushstring(L, kpathsea_readable_file(*kp, name)); + lua_pushstring(L, (char *) kpathsea_readable_file(*kp, name)); return 1; } @@ -422,6 +801,8 @@ static const struct luaL_reg kpselib_m[] = { {"expand_braces", lua_kpathsea_expand_braces}, {"var_value", lua_kpathsea_var_value}, {"show_path", lua_kpathsea_show_path}, + {"lookup", lua_kpathsea_lookup}, + {"version", lua_kpse_version}, {NULL, NULL} /* sentinel */ }; @@ -436,6 +817,8 @@ static const struct luaL_reg kpselib_l[] = { {"expand_braces", expand_braces}, {"var_value", var_value}, {"show_path", show_path}, + {"lookup", lua_kpse_lookup}, + {"version", lua_kpse_version}, {NULL, NULL} /* sentinel */ }; diff --git a/Build/source/texk/web2c/luatexdir/lua/llanglib.c b/Build/source/texk/web2c/luatexdir/lua/llanglib.c index 2e5544ca37f..093593d1301 100644 --- a/Build/source/texk/web2c/luatexdir/lua/llanglib.c +++ b/Build/source/texk/web2c/luatexdir/lua/llanglib.c @@ -17,20 +17,18 @@ You should have received a copy of the GNU General Public License along with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */ -#include "luatex-api.h" -#include <ptexlib.h> +#include "lua/luatex-api.h" +#include "ptexlib.h" + -#include "nodes.h" -#include "inc-extra.h" static const char _svn_version[] = - "$Id: llanglib.c 2271 2009-04-12 23:42:21Z oneiros $ $URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.40.6/source/texk/web2c/luatexdir/lua/llanglib.c $"; + "$Id: llanglib.c 3551 2010-03-26 14:43:50Z taco $ $URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/lua/llanglib.c $"; #define LANG_METATABLE "luatex.lang" #define check_islang(L,b) (struct tex_language **)luaL_checkudata(L,b,LANG_METATABLE) - static int lang_new(lua_State * L) { struct tex_language **lang; @@ -38,16 +36,16 @@ static int lang_new(lua_State * L) lang = lua_newuserdata(L, sizeof(struct tex_language *)); *lang = new_language(-1); if (!*lang) { - lua_pushstring(L, "lang.new(): no room for a new language"); - return lua_error(L); + return luaL_error(L, "lang.new(): no room for a new language"); } } else { + int lualang; lang = lua_newuserdata(L, sizeof(struct tex_language *)); - *lang = get_language(lua_tonumber(L, 1)); + lua_number2int(lualang, lua_tonumber(L, 1)); + *lang = get_language(lualang); if (!*lang) { - lua_pushfstring(L, "lang.new(%d): undefined language", + return luaL_error(L, "lang.new(%d): undefined language", lua_tonumber(L, 1)); - return lua_error(L); } } luaL_getmetatable(L, LANG_METATABLE); @@ -69,8 +67,7 @@ static int lang_patterns(lua_State * L) lang_ptr = check_islang(L, 1); if (lua_gettop(L) != 1) { if (!lua_isstring(L, 2)) { - lua_pushstring(L, "lang.patterns(): argument should be a string"); - return lua_error(L); + return luaL_error(L, "lang.patterns(): argument should be a string"); } load_patterns(*lang_ptr, (const unsigned char *) lua_tostring(L, 2)); return 0; @@ -99,9 +96,8 @@ static int lang_hyphenation(lua_State * L) lang_ptr = check_islang(L, 1); if (lua_gettop(L) != 1) { if (!lua_isstring(L, 2)) { - lua_pushstring(L, + return luaL_error(L, "lang.hyphenation(): argument should be a string"); - return lua_error(L); } load_hyphenation(*lang_ptr, (const unsigned char *) lua_tostring(L, 2)); return 0; @@ -121,11 +117,10 @@ static int lang_pre_hyphen_char(lua_State * L) lang_ptr = check_islang(L, 1); if (lua_gettop(L) != 1) { if (!lua_isnumber(L, 2)) { - lua_pushstring(L, + return luaL_error(L, "lang.prehyphenchar(): argument should be a character number"); - return lua_error(L); } - (*lang_ptr)->pre_hyphen_char = lua_tonumber(L, 2); + lua_number2int((*lang_ptr)->pre_hyphen_char, lua_tonumber(L, 2)); return 0; } else { lua_pushnumber(L, (*lang_ptr)->pre_hyphen_char); @@ -139,11 +134,10 @@ static int lang_post_hyphen_char(lua_State * L) lang_ptr = check_islang(L, 1); if (lua_gettop(L) != 1) { if (!lua_isnumber(L, 2)) { - lua_pushstring(L, + return luaL_error(L, "lang.posthyphenchar(): argument should be a character number"); - return lua_error(L); } - (*lang_ptr)->post_hyphen_char = lua_tonumber(L, 2); + lua_number2int((*lang_ptr)->post_hyphen_char, lua_tonumber(L, 2)); return 0; } else { lua_pushnumber(L, (*lang_ptr)->post_hyphen_char); @@ -158,11 +152,10 @@ static int lang_pre_exhyphen_char(lua_State * L) lang_ptr = check_islang(L, 1); if (lua_gettop(L) != 1) { if (!lua_isnumber(L, 2)) { - lua_pushstring(L, + return luaL_error(L, "lang.preexhyphenchar(): argument should be a character number"); - return lua_error(L); } - (*lang_ptr)->pre_exhyphen_char = lua_tonumber(L, 2); + lua_number2int((*lang_ptr)->pre_exhyphen_char, lua_tonumber(L, 2)); return 0; } else { lua_pushnumber(L, (*lang_ptr)->pre_exhyphen_char); @@ -176,11 +169,10 @@ static int lang_post_exhyphen_char(lua_State * L) lang_ptr = check_islang(L, 1); if (lua_gettop(L) != 1) { if (!lua_isnumber(L, 2)) { - lua_pushstring(L, + return luaL_error(L, "lang.postexhyphenchar(): argument should be a character number"); - return lua_error(L); } - (*lang_ptr)->post_exhyphen_char = lua_tonumber(L, 2); + lua_number2int((*lang_ptr)->post_exhyphen_char, lua_tonumber(L, 2)); return 0; } else { lua_pushnumber(L, (*lang_ptr)->post_exhyphen_char); @@ -202,8 +194,7 @@ static int do_lang_clean(lua_State * L) { char *cleaned; if (!lua_isstring(L, 1)) { - lua_pushstring(L, "lang.clean(): argument should be a string"); - return lua_error(L); + return luaL_error(L, "lang.clean(): argument should be a string"); } (void) clean_hyphenation(lua_tostring(L, 1), &cleaned); lua_pushstring(L, cleaned); @@ -212,17 +203,18 @@ static int do_lang_clean(lua_State * L) static int do_lang_hyphenate(lua_State * L) { - halfword *h, *t; + halfword *h, *t, tt; h = check_isnode(L, 1); if (lua_isuserdata(L, 2)) { t = check_isnode(L, 2); + tt = *t; lua_pop(L, 1); } else { - t = h; - while (vlink(*t) != null) - *t = vlink(*t); + tt = *h; + while (vlink(tt) != null) + tt = vlink(tt); } - hnj_hyphenation(*h, *t); + hnj_hyphenation(*h, tt); lua_pushboolean(L, 1); return 1; } diff --git a/Build/source/texk/web2c/luatexdir/lua/llualib.c b/Build/source/texk/web2c/luatexdir/lua/llualib.c index 57cffe36ab1..eded8dd8f25 100644 --- a/Build/source/texk/web2c/luatexdir/lua/llualib.c +++ b/Build/source/texk/web2c/luatexdir/lua/llualib.c @@ -17,11 +17,11 @@ You should have received a copy of the GNU General Public License along with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */ -#include "luatex-api.h" -#include <ptexlib.h> +#include "lua/luatex-api.h" +#include "ptexlib.h" static const char _svn_version[] = - "$Id: llualib.c 2271 2009-04-12 23:42:21Z oneiros $ $URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.40.6/source/texk/web2c/luatexdir/lua/llualib.c $"; + "$Id: llualib.c 3551 2010-03-26 14:43:50Z taco $ $URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/lua/llualib.c $"; #define LOAD_BUF_SIZE 256 #define UINT_MAX32 0xFFFFFFFF @@ -38,7 +38,7 @@ static bytecode *lua_bytecode_registers = NULL; int luabytecode_max = -1; unsigned int luabytecode_bytes = 0; -static char *luanames[65536] = { NULL }; +char *luanames[65536] = { NULL }; char *get_lua_name(int i) { @@ -49,8 +49,8 @@ char *get_lua_name(int i) void dump_luac_registers(void) { - integer x; - integer k, n; + int x; + int k, n; bytecode b; dump_int(luabytecode_max); if (lua_bytecode_registers != NULL) { @@ -72,7 +72,7 @@ void dump_luac_registers(void) for (k = 0; k < 65536; k++) { char *a = luanames[k]; if (a != NULL) { - x = strlen(a) + 1; + x = (int) strlen(a) + 1; dump_int(x); dump_things(*a, x); } else { @@ -84,18 +84,18 @@ void dump_luac_registers(void) void undump_luac_registers(void) { - integer x; - integer k, n; + int x; + int k, n; unsigned int i; bytecode b; undump_int(luabytecode_max); if (luabytecode_max >= 0) { - i = (luabytecode_max + 1); - if ((int) (UINT_MAX32 / sizeof(bytecode) + 1) <= i) { - lua_fatal_error(maketexstring("Corrupt format file")); + i = (unsigned) (luabytecode_max + 1); + if ((int) (UINT_MAX32 / (int) sizeof(bytecode) + 1) <= i) { + lua_fatal_error("Corrupt format file"); } - lua_bytecode_registers = xmalloc(i * sizeof(bytecode)); - luabytecode_bytes = i * sizeof(bytecode); + lua_bytecode_registers = xmalloc((unsigned) (i * sizeof(bytecode))); + luabytecode_bytes = (unsigned) (i * sizeof(bytecode)); for (i = 0; i <= (unsigned) luabytecode_max; i++) { lua_bytecode_registers[i].done = 0; lua_bytecode_registers[i].size = 0; @@ -106,9 +106,9 @@ void undump_luac_registers(void) undump_int(k); undump_int(x); b.size = x; - b.buf = xmalloc(b.size); - luabytecode_bytes += b.size; - memset(b.buf, 0, b.size); + b.buf = xmalloc((unsigned) b.size); + luabytecode_bytes += (unsigned) b.size; + memset(b.buf, 0, (size_t) b.size); do_zundump((char *) b.buf, 1, b.size, DUMP_FILE); lua_bytecode_registers[k].size = b.size; lua_bytecode_registers[k].alloc = b.size; @@ -118,7 +118,7 @@ void undump_luac_registers(void) for (k = 0; k < 65536; k++) { undump_int(x); if (x > 0) { - char *s = xmalloc(x); + char *s = xmalloc((unsigned) x); undump_things(*s, x); luanames[k] = s; } @@ -157,21 +157,23 @@ static int bytecode_register_shadow_get(lua_State * L, int k) } -static int writer(lua_State * L, const void *b, size_t size, void *B) +int writer(lua_State * L, const void *b, size_t size, void *B) { bytecode *buf = (bytecode *) B; (void) L; /* for -Wunused */ - if ((int) (buf->size + size) > buf->alloc) { - buf->buf = xrealloc(buf->buf, buf->alloc + size + LOAD_BUF_SIZE); - buf->alloc = buf->alloc + size + LOAD_BUF_SIZE; + if ((int) (buf->size + (int) size) > buf->alloc) { + buf->buf = + xrealloc(buf->buf, + (unsigned) (buf->alloc + (int) size + LOAD_BUF_SIZE)); + buf->alloc = buf->alloc + (int) size + LOAD_BUF_SIZE; } memcpy(buf->buf + buf->size, b, size); - buf->size += size; - luabytecode_bytes += size; + buf->size += (int) size; + luabytecode_bytes += (unsigned) size; return 0; } -static const char *reader(lua_State * L, void *ud, size_t * size) +const char *reader(lua_State * L, void *ud, size_t * size) { bytecode *buf = (bytecode *) ud; (void) L; /* for -Wunused */ @@ -180,12 +182,12 @@ static const char *reader(lua_State * L, void *ud, size_t * size) buf->done = 0; return NULL; } - *size = buf->size; + *size = (size_t) buf->size; buf->done = buf->size; return (const char *) buf->buf; } -static int get_bytecode(lua_State * L) +int get_bytecode(lua_State * L) { int k; k = (int) luaL_checkinteger(L, -1); @@ -196,8 +198,7 @@ static int get_bytecode(lua_State * L) if (lua_load (L, reader, (void *) (lua_bytecode_registers + k), "bytecode")) { - lua_error(L); - lua_pushnil(L); + return luaL_error(L, "bad bytecode register"); } else { lua_pushvalue(L, -1); bytecode_register_shadow_set(L, k); @@ -209,34 +210,34 @@ static int get_bytecode(lua_State * L) return 1; } -static int set_bytecode(lua_State * L) +int set_bytecode(lua_State * L) { int k, ltype; unsigned int i; k = (int) luaL_checkinteger(L, -2); - i = k + 1; + i = (unsigned) k + 1; if ((int) (UINT_MAX32 / sizeof(bytecode) + 1) < i) { - lua_pushstring(L, "value too large"); - lua_error(L); + luaL_error(L, "value too large"); } if (k < 0) { - lua_pushstring(L, "negative values not allowed"); - lua_error(L); + luaL_error(L, "negative values not allowed"); } ltype = lua_type(L, -1); if (ltype != LUA_TFUNCTION && ltype != LUA_TNIL) { - lua_pushstring(L, "unsupported type"); - lua_error(L); + luaL_error(L, "unsupported type"); } if (k > luabytecode_max) { - i = sizeof(bytecode) * (k + 1); + i = (unsigned) (sizeof(bytecode) * ((unsigned) k + 1)); lua_bytecode_registers = xrealloc(lua_bytecode_registers, i); if (luabytecode_max == -1) { - luabytecode_bytes += sizeof(bytecode) * (k + 1); + luabytecode_bytes += + (unsigned) (sizeof(bytecode) * (unsigned) (k + 1)); } else { - luabytecode_bytes += sizeof(bytecode) * (k + 1 - luabytecode_max); + luabytecode_bytes += + (unsigned) (sizeof(bytecode) * + (unsigned) (k + 1 - luabytecode_max)); } - for (i = (luabytecode_max + 1); i <= (unsigned) k; i++) { + for (i = (unsigned) (luabytecode_max + 1); i <= (unsigned) k; i++) { lua_bytecode_registers[i].buf = NULL; lua_bytecode_registers[i].size = 0; lua_bytecode_registers[i].done = 0; @@ -245,8 +246,7 @@ static int set_bytecode(lua_State * L) } if (lua_bytecode_registers[k].buf != NULL) { xfree(lua_bytecode_registers[k].buf); - luabytecode_bytes -= lua_bytecode_registers[k].size; - lua_bytecode_registers[k].buf = NULL; + luabytecode_bytes -= (unsigned) lua_bytecode_registers[k].size; lua_bytecode_registers[k].size = 0; lua_bytecode_registers[k].done = 0; lua_pushnil(L); @@ -263,7 +263,7 @@ static int set_bytecode(lua_State * L) } -static int set_luaname(lua_State * L) +int set_luaname(lua_State * L) { int k; const char *s; @@ -286,7 +286,7 @@ static int set_luaname(lua_State * L) return 0; } -static int get_luaname(lua_State * L) +int get_luaname(lua_State * L) { int k; k = (int) luaL_checkinteger(L, 2); @@ -314,7 +314,7 @@ static const struct luaL_reg lualib[] = { {NULL, NULL} /* sentinel */ }; -int luaopen_lua(lua_State * L, const char *fname) +int luaopen_lua(lua_State * L, char *fname) { luaL_register(L, "lua", lualib); make_table(L, "bytecode", "getbytecode", "setbytecode"); diff --git a/Build/source/texk/web2c/luatexdir/lua/lnodelib.c b/Build/source/texk/web2c/luatexdir/lua/lnodelib.c index 4b5738da4be..3b626826e58 100644 --- a/Build/source/texk/web2c/luatexdir/lua/lnodelib.c +++ b/Build/source/texk/web2c/luatexdir/lua/lnodelib.c @@ -1,6 +1,6 @@ /* lnodelib.c - Copyright 2006-2008 Taco Hoekwater <taco@luatex.org> + Copyright 2006-2010 Taco Hoekwater <taco@luatex.org> This file is part of LuaTeX. @@ -17,20 +17,16 @@ You should have received a copy of the GNU General Public License along with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */ -#include "luatex-api.h" -#include <ptexlib.h> - -#include "nodes.h" -#include "inc-extra.h" - -#include "commands.h" - static const char _svn_version[] = - "$Id: lnodelib.c 2476 2009-06-12 19:39:05Z taco $ $URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.40.6/source/texk/web2c/luatexdir/lua/lnodelib.c $"; + "$Id: lnodelib.c 3560 2010-03-29 09:27:08Z taco $ " + "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/lua/lnodelib.c $"; + +#include "lua/luatex-api.h" +#include "ptexlib.h" #define init_luaS_index(a) do { \ lua_pushliteral(L,#a); \ - luaS_##a##_ptr = lua_tostring(L,-1); \ + luaS_##a##_ptr = lua_tostring(L,-1); \ luaS_##a##_index = luaL_ref (L,LUA_REGISTRYINDEX); \ } while (0) @@ -77,7 +73,7 @@ int do_get_node_type_id(lua_State * L, int n, node_info * data) return j; } } else if (lua_type(L, n) == LUA_TNUMBER) { - register int i = lua_tointeger(L, n); + register int i = (int) lua_tointeger(L, n); for (j = 0; data[j].id != -1; j++) { if (data[j].id == i) return j; @@ -95,13 +91,10 @@ int get_valid_node_type_id(lua_State * L, int n) int i = get_node_type_id(L, n); if (i == -1) { if (lua_type(L, n) == LUA_TSTRING) { - lua_pushfstring(L, "Invalid node type id: %s", - (const char *) lua_tostring(L, n)); + luaL_error(L, "Invalid node type id: %s", lua_tostring(L, n)); } else { - lua_pushfstring(L, "Invalid node type id: %d", - (int) lua_tonumber(L, n)); + luaL_error(L, "Invalid node type id: %d", lua_tonumber(L, n)); } - return lua_error(L); } return i; } @@ -112,13 +105,12 @@ int get_valid_node_subtype_id(lua_State * L, int n) int i = get_node_subtype_id(L, n); if (i == -1) { if (lua_type(L, n) == LUA_TSTRING) { - lua_pushfstring(L, "Invalid whatsit node id: %s", - (const char *) lua_tostring(L, n)); + luaL_error(L, "Invalid whatsit node id: %s", + lua_tostring(L, n)); } else { - lua_pushfstring(L, "Invalid whatsit node id: %d", - (int) lua_tonumber(L, n)); + luaL_error(L, "Invalid whatsit node id: %d", + lua_tonumber(L, n)); } - return lua_error(L); } return i; } @@ -138,7 +130,7 @@ void lua_nodelib_push(lua_State * L) halfword *a; n = -1; if (lua_isnumber(L, -1)) { - n = lua_tointeger(L, -1); + n = (int) lua_tointeger(L, -1); } lua_pop(L, 1); if ((n == null) || (n < 0) || (n > var_mem_max)) { @@ -153,6 +145,29 @@ void lua_nodelib_push(lua_State * L) return; } +/* |spec_ptr| fields can legally be zero, which is why there is a special function. */ + +static void lua_nodelib_push_spec(lua_State * L) +{ + halfword n; + halfword *a; + n = -1; + if (lua_isnumber(L, -1)) { + n = (halfword) lua_tointeger(L, -1); + } + lua_pop(L, 1); + if ((n < 0) || (n > var_mem_max)) { + lua_pushnil(L); + } else { + a = lua_newuserdata(L, sizeof(halfword)); + *a = n; + lua_rawgeti(L, LUA_REGISTRYINDEX, luaS_index(luatex_node)); + lua_gettable(L, LUA_REGISTRYINDEX); + lua_setmetatable(L, -2); + } + return; +} + void lua_nodelib_push_fast(lua_State * L, halfword n) { halfword *a; @@ -169,7 +184,7 @@ void lua_nodelib_push_fast(lua_State * L, halfword n) static int lua_nodelib_id(lua_State * L) { - integer i = get_node_type_id(L, 1); + int i = get_node_type_id(L, 1); if (i >= 0) { lua_pushnumber(L, i); } else { @@ -181,7 +196,7 @@ static int lua_nodelib_id(lua_State * L) static int lua_nodelib_subtype(lua_State * L) { - integer i = get_node_subtype_id(L, 1); + int i = get_node_subtype_id(L, 1); if (i >= 0) { lua_pushnumber(L, i); } else { @@ -194,7 +209,7 @@ static int lua_nodelib_subtype(lua_State * L) static int lua_nodelib_type(lua_State * L) { - integer i = get_node_type_id(L, 1); + int i = get_node_type_id(L, 1); if (i >= 0) { lua_pushstring(L, node_data[i].name); } else { @@ -218,14 +233,13 @@ static int lua_nodelib_new(lua_State * L) j = get_valid_node_subtype_id(L, 2); } if (j < 0) { - lua_pushstring(L, + luaL_error(L, "Creating a whatsit requires the subtype number as a second argument"); - lua_error(L); } } else { j = 0; if (lua_gettop(L) > 1) { - j = lua_tointeger(L, 2); + j = (int) lua_tointeger(L, 2); } } n = new_node(i, j); @@ -284,8 +298,7 @@ static int lua_nodelib_remove(lua_State * L) { halfword head, current, t; if (lua_gettop(L) < 2) { - lua_pushstring(L, "Not enough arguments for node.remove()"); - lua_error(L); + luaL_error(L, "Not enough arguments for node.remove()"); } head = *(check_isnode(L, 1)); if (lua_isnil(L, 2)) { @@ -304,9 +317,8 @@ static int lua_nodelib_remove(lua_State * L) if (t == null || vlink(t) != current) { set_t_to_prev(head, current); if (t == null) { /* error! */ - lua_pushstring(L, + luaL_error(L, "Attempt to node.remove() a non-existing node"); - lua_error(L); } } /* t is now the previous node */ @@ -329,8 +341,7 @@ static int lua_nodelib_insert_before(lua_State * L) { halfword head, current, n, t; if (lua_gettop(L) < 3) { - lua_pushstring(L, "Not enough arguments for node.insert_before()"); - lua_error(L); + luaL_error(L, "Not enough arguments for node.insert_before()"); } if (lua_isnil(L, 3)) { lua_pop(L, 1); @@ -357,9 +368,8 @@ static int lua_nodelib_insert_before(lua_State * L) if (t == null || vlink(t) != current) { set_t_to_prev(head, current); if (t == null) { /* error! */ - lua_pushstring(L, + luaL_error(L, "Attempt to node.insert_before() a non-existing node"); - lua_error(L); } } couple_nodes(t, n); @@ -379,8 +389,7 @@ static int lua_nodelib_insert_after(lua_State * L) { halfword head, current, n; if (lua_gettop(L) < 3) { - lua_pushstring(L, "Not enough arguments for node.insert_after()"); - lua_error(L); + luaL_error(L, "Not enough arguments for node.insert_after()"); } if (lua_isnil(L, 3)) { lua_pop(L, 1); @@ -417,13 +426,17 @@ static int lua_nodelib_insert_after(lua_State * L) static int lua_nodelib_copy_list(lua_State * L) { - halfword *n; + halfword n, s = null; halfword m; if (lua_isnil(L, 1)) return 1; /* the nil itself */ - n = check_isnode(L, 1); - m = copy_node_list(*n); - lua_nodelib_push_fast(L, m); + n = *check_isnode(L, 1); + if ((lua_gettop(L) > 1) && (!lua_isnil(L,2))) { + s = *check_isnode(L, 2); + } + m = do_copy_node_list(n, s); + lua_pushnumber(L, m); + lua_nodelib_push(L); return 1; } @@ -452,10 +465,10 @@ static int lua_nodelib_append(lua_State * L) for (i = 1; i <= j; i++) { n = check_isnode(L, i); m = *n; - new_tail_append(m); + tail_append(m); while (vlink(m) != null) { m = vlink(m); - new_tail_append(m); + tail_append(m); } } return 0; @@ -478,11 +491,12 @@ static int lua_nodelib_hpack(lua_State * L) { halfword n, p; const char *s; - integer w = 0; + int w = 0; int m = 1; + int d = -1; n = *(check_isnode(L, 1)); if (lua_gettop(L) > 1) { - w = lua_tointeger(L, 2); + w = (int) lua_tointeger(L, 2); if (lua_gettop(L) > 2) { if (lua_type(L, 3) == LUA_TSTRING) { s = lua_tostring(L, 3); @@ -490,23 +504,78 @@ static int lua_nodelib_hpack(lua_State * L) m = 1; else if (strcmp(s, "exactly") == 0) m = 0; + else if (strcmp(s, "cal_expand_ratio") == 0) + m = 2; + else if (strcmp(s, "subst_ex_font") == 0) + m = 3; else { - lua_pushstring(L, + luaL_error(L, "3rd argument should be either additional or exactly"); - lua_error(L); } - } - - else if (lua_type(L, 3) == LUA_TNUMBER) { - m = lua_tonumber(L, 3); + } else if (lua_type(L, 3) == LUA_TNUMBER) { + lua_number2int(m, lua_tonumber(L, 3)); } else { lua_pushstring(L, "incorrect 3rd argument"); } + if (lua_gettop(L) > 3) { + if (lua_type(L, 4) == LUA_TSTRING) { + d = nodelib_getdir(L, 4); + } else { + lua_pushstring(L, "incorrect 4th argument"); + } + } } } - p = hpack(n, w, m); + p = hpack(n, w, m, d); lua_nodelib_push_fast(L, p); - return 1; + lua_pushnumber(L, last_badness); + return 2; +} + + +static int lua_nodelib_dimensions(lua_State * L) +{ + int top; + top = lua_gettop(L); + if (top > 0) { + scaled_whd siz; + glue_ratio g_mult = 1.0; + int g_sign = normal; + int g_order = normal; + int i = 1; + int d = -1; + halfword n = null, p = null; + if (lua_isnumber(L, 1)) { + if (top < 4) { + lua_pushnil(L); + return 1; + } + i += 3; + g_mult = (glue_ratio) lua_tonumber(L, 1); + lua_number2int(g_sign, lua_tonumber(L, 2)); + lua_number2int(g_order, lua_tonumber(L, 3)); + } + n = *(check_isnode(L, i)); + if (lua_gettop(L) > i && !lua_isnil(L, (i + 1))) { + if (lua_type(L, (i + 1)) == LUA_TSTRING) { + d = nodelib_getdir(L, (i + 1)); + } else { + p = *(check_isnode(L, (i + 1))); + } + } + if (lua_gettop(L) > (i + 1) && lua_type(L, (i + 2)) == LUA_TSTRING) { + d = nodelib_getdir(L, (i + 2)); + } + siz = natural_sizes(n, p, g_mult, g_sign, g_order, d); + lua_pushnumber(L, siz.wd); + lua_pushnumber(L, siz.ht); + lua_pushnumber(L, siz.dp); + return 3; + } else { + luaL_error(L, + "missing argument to 'dimensions' (luatex_node expected)"); + } + return 0; /* not reached */ } @@ -515,11 +584,12 @@ static int lua_nodelib_vpack(lua_State * L) { halfword n, p; const char *s; - integer w = 0; + int w = 0; int m = 1; + int d = -1; n = *(check_isnode(L, 1)); if (lua_gettop(L) > 1) { - w = lua_tointeger(L, 2); + w = (int) lua_tointeger(L, 2); if (lua_gettop(L) > 2) { if (lua_type(L, 3) == LUA_TSTRING) { s = lua_tostring(L, 3); @@ -528,22 +598,29 @@ static int lua_nodelib_vpack(lua_State * L) else if (strcmp(s, "exactly") == 0) m = 0; else { - lua_pushstring(L, + luaL_error(L, "3rd argument should be either additional or exactly"); - lua_error(L); + } + if (lua_gettop(L) > 3) { + if (lua_type(L, 4) == LUA_TSTRING) { + d = nodelib_getdir(L, 4); + } else { + lua_pushstring(L, "incorrect 4th argument"); + } } } else if (lua_type(L, 3) == LUA_TNUMBER) { - m = lua_tonumber(L, 3); + lua_number2int(m, lua_tonumber(L, 3)); } else { lua_pushstring(L, "incorrect 3rd argument"); } } } - p = vpackage(n, w, m, max_dimen); + p = vpackage(n, w, m, max_dimen, d); lua_nodelib_push_fast(L, p); - return 1; + lua_pushnumber(L, last_badness); + return 2; } @@ -558,10 +635,7 @@ static int lua_nodelib_mlist_to_hlist(lua_State * L) w = luaL_checkoption(L, 2, "text", math_style_names); luaL_checkany(L, 3); m = lua_toboolean(L, 3); - cur_mlist = n; - cur_style = w; - mlist_penalties = m; - mlist_to_hlist(); + mlist_to_hlist_args(n, w, m); lua_nodelib_push_fast(L, vlink(temp_head)); return 1; } @@ -569,9 +643,9 @@ static int lua_nodelib_mlist_to_hlist(lua_State * L) static int lua_nodelib_mfont(lua_State * L) { int f, s; - f = luaL_checkinteger(L, 1); + f = (int) luaL_checkinteger(L, 1); if (lua_gettop(L) == 2) - s = lua_tointeger(L, 2); /* this should be a multiple of 256 ! */ + s = (int) lua_tointeger(L, 2); /* this should be a multiple of 256 ! */ else s = 0; lua_pushnumber(L, fam_fnt(f, s)); @@ -605,9 +679,13 @@ make_luaS_index(uchyph); make_luaS_index(components); make_luaS_index(xoffset); make_luaS_index(yoffset); +make_luaS_index(width); +make_luaS_index(height); +make_luaS_index(depth); +make_luaS_index(expansion_factor); -static void initialize_luaS_indexes(lua_State * L) +void initialize_luaS_indexes(lua_State * L) { init_luaS_index(id); init_luaS_index(next); @@ -623,6 +701,10 @@ static void initialize_luaS_indexes(lua_State * L) init_luaS_index(components); init_luaS_index(xoffset); init_luaS_index(yoffset); + init_luaS_index(width); + init_luaS_index(height); + init_luaS_index(depth); + init_luaS_index(expansion_factor); } static int get_node_field_id(lua_State * L, int n, int node) @@ -658,6 +740,14 @@ static int get_node_field_id(lua_State * L, int n, int node) return 11; } else if (luaS_ptr_eq(s, yoffset)) { return 12; + } else if (luaS_ptr_eq(s, width)) { + return 13; + } else if (luaS_ptr_eq(s, height)) { + return 14; + } else if (luaS_ptr_eq(s, depth)) { + return 15; + } else if (luaS_ptr_eq(s, expansion_factor)) { + return 16; } } else if (luaS_ptr_eq(s, prev)) { return -1; @@ -683,9 +773,8 @@ static int get_valid_node_field_id(lua_State * L, int n, int node) int i = get_node_field_id(L, n, node); if (i == -2) { const char *s = lua_tostring(L, n); - lua_pushfstring(L, "Invalid field id %s for node type %s (%d)", s, + luaL_error(L, "Invalid field id %s for node type %s (%d)", s, node_data[type(node)].name, subtype(node)); - lua_error(L); } return i; } @@ -778,6 +867,24 @@ static int lua_nodelib_tail(lua_State * L) return 1; } +static int lua_nodelib_tail_only(lua_State * L) +{ + halfword *n; + halfword t; + if (lua_isnil(L, 1)) + return 1; /* the nil itself */ + n = check_isnode(L, 1); + t = *n; + if (t == null) + return 1; /* the old userdata */ + while (vlink(t) != null) { + t = vlink(t); + } + lua_nodelib_push_fast(L, t); + return 1; +} + + /* a few utility functions for attribute stuff */ static int lua_nodelib_has_attribute(lua_State * L) @@ -786,8 +893,8 @@ static int lua_nodelib_has_attribute(lua_State * L) int i, val; n = check_isnode(L, 1); if (n != NULL) { - i = lua_tointeger(L, 2); - val = luaL_optinteger(L, 3, UNUSED_ATTRIBUTE); + i = (int) lua_tointeger(L, 2); + val = (int) luaL_optinteger(L, 3, UNUSED_ATTRIBUTE); if ((val = has_attribute(*n, i, val)) > UNUSED_ATTRIBUTE) { lua_pushnumber(L, val); return 1; @@ -802,8 +909,8 @@ static int lua_nodelib_set_attribute(lua_State * L) halfword *n; int i, val; if (lua_gettop(L) == 3) { - i = lua_tointeger(L, 2); - val = lua_tointeger(L, 3); + i = (int) lua_tointeger(L, 2); + val = (int) lua_tointeger(L, 3); n = check_isnode(L, 1); if (val == UNUSED_ATTRIBUTE) { (void) unset_attribute(*n, i, val); @@ -811,8 +918,7 @@ static int lua_nodelib_set_attribute(lua_State * L) set_attribute(*n, i, val); } } else { - lua_pushstring(L, "incorrect number of arguments"); - lua_error(L); + luaL_error(L, "incorrect number of arguments"); } return 0; } @@ -823,8 +929,8 @@ static int lua_nodelib_unset_attribute(lua_State * L) halfword *n; int i, val, ret; if (lua_gettop(L) <= 3) { - i = luaL_checknumber(L, 2); - val = luaL_optnumber(L, 3, UNUSED_ATTRIBUTE); + lua_number2int(i, luaL_checknumber(L, 2)); + lua_number2int(val, luaL_optnumber(L, 3, UNUSED_ATTRIBUTE)); n = check_isnode(L, 1); ret = unset_attribute(*n, i, val); if (ret > UNUSED_ATTRIBUTE) { @@ -834,8 +940,7 @@ static int lua_nodelib_unset_attribute(lua_State * L) } return 1; } else { - lua_pushstring(L, "incorrect number of arguments"); - return lua_error(L); + return luaL_error(L, "incorrect number of arguments"); } } @@ -851,7 +956,7 @@ static int nodelib_aux_nil(lua_State * L) static int nodelib_aux_next_filtered(lua_State * L) { register halfword t; /* traverser */ - register int i = lua_tointeger(L, lua_upvalueindex(1)); + register int i = (int) lua_tointeger(L, lua_upvalueindex(1)); if (lua_isnil(L, 2)) { /* first call */ t = *check_isnode(L, 1); } else { @@ -955,7 +1060,7 @@ static int lua_nodelib_count(lua_State * L) halfword n; halfword m = null; int i = -1; - i = lua_tointeger(L, 1); + i = (int) lua_tointeger(L, 1); if (lua_isnil(L, 2)) { lua_pushnumber(L, 0); return 1; @@ -970,23 +1075,32 @@ static int lua_nodelib_count(lua_State * L) #define nodelib_pushlist(L,n) { lua_pushnumber(L,n); lua_nodelib_push(L); } #define nodelib_pushattr(L,n) { lua_pushnumber(L,n); lua_nodelib_push(L); } -#define nodelib_pushspec(L,n) { lua_pushnumber(L,n); lua_nodelib_push(L); } +#define nodelib_pushspec(L,n) { lua_pushnumber(L,n); lua_nodelib_push_spec(L); } #define nodelib_pushaction(L,n) { lua_pushnumber(L,n); lua_nodelib_push(L); } -#define nodelib_pushstring(L,n) { lua_pushstring(L,makecstring(n)); } +#define nodelib_pushstring(L,n) { char *ss=makecstring(n); lua_pushstring(L,ss); free(ss); } static void nodelib_pushdir(lua_State * L, int n, boolean dirnode) { - int f = 0; - char dirstring[5] = { 0 }; + char s[2]; if (dirnode) { - dirstring[f++] = (n < 0 ? '-' : '+'); + s[0] = (char) (n < 0 ? '-' : '+'); + s[1] = 0; + } else { + s[0] = 0; } if (n < 0) n += 64; - dirstring[f++] = dir_names[(int) dir_primary[n]]; - dirstring[f++] = dir_names[(int) dir_secondary[n]]; - dirstring[f++] = dir_names[(int) dir_tertiary[n]]; - lua_pushstring(L, dirstring); + if (n == dir_TLT) { + lua_pushfstring(L, "%sTLT", s); + } else if (n == dir_TRT) { + lua_pushfstring(L, "%sTRT", s); + } else if (n == dir_LTL) { + lua_pushfstring(L, "%sLTL", s); + } else if (n == dir_RTT) { + lua_pushfstring(L, "%sRTT", s); + } else { + lua_pushstring(L, "???"); + } } static void lua_nodelib_getfield_whatsit(lua_State * L, int n, int field) @@ -1116,13 +1230,13 @@ static void lua_nodelib_getfield_whatsit(lua_State * L, int n, int field) case pdf_refxform_node: switch (field) { case 4: - lua_pushnumber(L, pdf_width(n)); + lua_pushnumber(L, width(n)); break; case 5: - lua_pushnumber(L, pdf_height(n)); + lua_pushnumber(L, depth(n)); break; case 6: - lua_pushnumber(L, pdf_depth(n)); + lua_pushnumber(L, height(n)); break; case 7: lua_pushnumber(L, pdf_xform_objnum(n)); @@ -1134,16 +1248,19 @@ static void lua_nodelib_getfield_whatsit(lua_State * L, int n, int field) case pdf_refximage_node: switch (field) { case 4: - lua_pushnumber(L, pdf_width(n)); + lua_pushnumber(L, width(n)); break; case 5: - lua_pushnumber(L, pdf_height(n)); + lua_pushnumber(L, depth(n)); break; case 6: - lua_pushnumber(L, pdf_depth(n)); + lua_pushnumber(L, height(n)); break; case 7: - lua_pushnumber(L, pdf_ximage_objnum(n)); + lua_pushnumber(L, pdf_ximage_transform(n)); + break; + case 8: + lua_pushnumber(L, pdf_ximage_index(n)); break; default: lua_pushnil(L); @@ -1152,13 +1269,13 @@ static void lua_nodelib_getfield_whatsit(lua_State * L, int n, int field) case pdf_annot_node: switch (field) { case 4: - lua_pushnumber(L, pdf_width(n)); + lua_pushnumber(L, width(n)); break; case 5: - lua_pushnumber(L, pdf_height(n)); + lua_pushnumber(L, depth(n)); break; case 6: - lua_pushnumber(L, pdf_depth(n)); + lua_pushnumber(L, height(n)); break; case 7: lua_pushnumber(L, pdf_annot_objnum(n)); @@ -1173,13 +1290,13 @@ static void lua_nodelib_getfield_whatsit(lua_State * L, int n, int field) case pdf_start_link_node: switch (field) { case 4: - lua_pushnumber(L, pdf_width(n)); + lua_pushnumber(L, width(n)); break; case 5: - lua_pushnumber(L, pdf_height(n)); + lua_pushnumber(L, depth(n)); break; case 6: - lua_pushnumber(L, pdf_depth(n)); + lua_pushnumber(L, height(n)); break; case 7: lua_pushnumber(L, pdf_link_objnum(n)); @@ -1197,13 +1314,13 @@ static void lua_nodelib_getfield_whatsit(lua_State * L, int n, int field) case pdf_dest_node: switch (field) { case 4: - lua_pushnumber(L, pdf_width(n)); + lua_pushnumber(L, width(n)); break; case 5: - lua_pushnumber(L, pdf_height(n)); + lua_pushnumber(L, depth(n)); break; case 6: - lua_pushnumber(L, pdf_depth(n)); + lua_pushnumber(L, height(n)); break; case 7: lua_pushnumber(L, pdf_dest_named_id(n)); @@ -1231,13 +1348,13 @@ static void lua_nodelib_getfield_whatsit(lua_State * L, int n, int field) case pdf_start_thread_node: switch (field) { case 4: - lua_pushnumber(L, pdf_width(n)); + lua_pushnumber(L, width(n)); break; case 5: - lua_pushnumber(L, pdf_height(n)); + lua_pushnumber(L, depth(n)); break; case 6: - lua_pushnumber(L, pdf_depth(n)); + lua_pushnumber(L, height(n)); break; case 7: lua_pushnumber(L, pdf_thread_named_id(n)); @@ -1588,6 +1705,9 @@ static int lua_nodelib_getfield(lua_State * L) case 8: lua_pushnumber(L, glue_ref_count(n)); break; + case 9: + lua_pushboolean(L, valid_node(n)); + break; default: lua_pushnil(L); } @@ -1600,6 +1720,8 @@ static int lua_nodelib_getfield(lua_State * L) case 4: lua_pushnumber(L, width(n)); break; + case 5: + lua_pushnumber(L, ex_kern(n)); default: lua_pushnil(L); } @@ -1648,6 +1770,18 @@ static int lua_nodelib_getfield(lua_State * L) case 12: lua_pushnumber(L, y_displace(n)); break; + case 13: + lua_pushnumber(L, char_width(font(n),character(n))); + break; + case 14: + lua_pushnumber(L, char_height(font(n),character(n))); + break; + case 15: + lua_pushnumber(L, char_depth(font(n),character(n))); + break; + case 16: + lua_pushnumber(L, ex_glyph(n)); + break; default: lua_pushnil(L); } @@ -1878,10 +2012,10 @@ static int lua_nodelib_getfield(lua_State * L) case 2: lua_pushnumber(L, subtype(n)); break; - case 3: + case 4: lua_pushnumber(L, width(n)); break; - case 4: + case 5: nodelib_pushlist(L, margin_char(n)); break; default: @@ -1970,11 +2104,10 @@ static int nodelib_getlist(lua_State * L, int n) } } -static int nodelib_getdir(lua_State * L, int n) +int nodelib_getdir(lua_State * L, int n) { const char *s = NULL; int d = 32; /* invalid number */ - int a = -1, b = -1, c = -1; if (lua_type(L, n) == LUA_TSTRING) { s = lua_tostring(L, n); if (strlen(s) == 3) { @@ -1988,42 +2121,22 @@ static int nodelib_getdir(lua_State * L, int n) s++; } if (strlen(s) == 3) { - switch (*s) { - /* *INDENT-OFF* */ - case 'T': a=0; break; - case 'L': a=1; break; - case 'B': a=2; break; - case 'R': a=3; break; - /* *INDENT-ON* */ - } - switch (*(s + 1)) { - /* *INDENT-OFF* */ - case 'T': b=0; break; - case 'L': b=1; break; - case 'B': b=2; break; - case 'R': b=3; break; - /* *INDENT-ON* */ + if (strcmp(s, "TLT") == 0) { + d += dir_TLT; + } else if (strcmp(s, "TRT") == 0) { + d += dir_TRT; + } else if (strcmp(s, "LTL") == 0) { + d += dir_LTL; + } else if (strcmp(s, "RTT") == 0) { + d += dir_RTT; } - switch (*(s + 2)) { - /* *INDENT-OFF* */ - case 'T': c=0; break; - case 'L': c=1; break; - case 'B': c=2; break; - case 'R': c=3; break; - /* *INDENT-ON* */ - } - } - if (a != -1 && b != -1 && c != -1 && !dir_parallel(a, b)) { - d += (a * 8 + dir_rearrange[b] * 4 + c); } - } else if (lua_isnumber(L, n)) { - d = lua_tonumber(L, n); + } else { + luaL_error(L, "Direction specifiers have to be strings"); } if ((d > 31) || (d < -64) || (d < 0 && (d + 64) > 31)) { d = 0; - lua_pushfstring(L, "Bad direction specifier %s", - (const char *) lua_tostring(L, n)); - lua_error(L); + luaL_error(L, "Bad direction specifier %s", lua_tostring(L, n)); } return d; } @@ -2056,9 +2169,8 @@ static void nodelib_setattr(lua_State * L, int stackindex, halfword n) static int nodelib_cantset(lua_State * L, int field, int n) { - lua_pushfstring(L, "You cannot set field %d in a node of type %s", + luaL_error(L, "You cannot set field %d in a node of type %s", field, node_data[type(n)].name); - lua_error(L); return 0; } @@ -2068,7 +2180,7 @@ static int lua_nodelib_setfield_whatsit(lua_State * L, int n, int field) case open_node: switch (field) { case 4: - write_stream(n) = lua_tointeger(L, 3); + write_stream(n) = (halfword) lua_tointeger(L, 3); break; case 5: open_name(n) = nodelib_getstring(L, 3); @@ -2086,7 +2198,7 @@ static int lua_nodelib_setfield_whatsit(lua_State * L, int n, int field) case write_node: switch (field) { case 4: - write_stream(n) = lua_tointeger(L, 3); + write_stream(n) = (halfword) lua_tointeger(L, 3); break; case 5: write_tokens(n) = nodelib_gettoks(L, 3); @@ -2098,7 +2210,7 @@ static int lua_nodelib_setfield_whatsit(lua_State * L, int n, int field) case close_node: switch (field) { case 4: - write_stream(n) = lua_tointeger(L, 3); + write_stream(n) = (halfword) lua_tointeger(L, 3); break; default: return nodelib_cantset(L, field, n); @@ -2116,10 +2228,10 @@ static int lua_nodelib_setfield_whatsit(lua_State * L, int n, int field) case local_par_node: switch (field) { case 4: - local_pen_inter(n) = lua_tointeger(L, 3); + local_pen_inter(n) = (halfword) lua_tointeger(L, 3); break; case 5: - local_pen_broken(n) = lua_tointeger(L, 3); + local_pen_broken(n) = (halfword) lua_tointeger(L, 3); break; case 6: local_par_dir(n) = nodelib_getdir(L, 3); @@ -2128,13 +2240,13 @@ static int lua_nodelib_setfield_whatsit(lua_State * L, int n, int field) local_box_left(n) = nodelib_getlist(L, 3); break; case 8: - local_box_left_width(n) = lua_tointeger(L, 3); + local_box_left_width(n) = (halfword) lua_tointeger(L, 3); break; case 9: local_box_right(n) = nodelib_getlist(L, 3); break; case 10: - local_box_right_width(n) = lua_tointeger(L, 3); + local_box_right_width(n) = (halfword) lua_tointeger(L, 3); break; default: return nodelib_cantset(L, field, n); @@ -2146,13 +2258,13 @@ static int lua_nodelib_setfield_whatsit(lua_State * L, int n, int field) dir_dir(n) = nodelib_getdir(L, 3); break; case 5: - dir_level(n) = lua_tointeger(L, 3); + dir_level(n) = (halfword) lua_tointeger(L, 3); break; case 6: - dir_dvi_ptr(n) = lua_tointeger(L, 3); + dir_dvi_ptr(n) = (halfword) lua_tointeger(L, 3); break; case 7: - dir_dvi_h(n) = lua_tointeger(L, 3); + dir_dvi_h(n) = (halfword) lua_tointeger(L, 3); break; default: return nodelib_cantset(L, field, n); @@ -2161,7 +2273,7 @@ static int lua_nodelib_setfield_whatsit(lua_State * L, int n, int field) case pdf_literal_node: switch (field) { case 4: - pdf_literal_mode(n) = lua_tointeger(L, 3); + pdf_literal_mode(n) = (quarterword) lua_tointeger(L, 3); break; case 5: if (ini_version) { @@ -2179,7 +2291,7 @@ static int lua_nodelib_setfield_whatsit(lua_State * L, int n, int field) case pdf_refobj_node: switch (field) { case 4: - pdf_obj_objnum(n) = lua_tointeger(L, 3); + pdf_obj_objnum(n) = (halfword) lua_tointeger(L, 3); break; default: return nodelib_cantset(L, field, n); @@ -2188,16 +2300,16 @@ static int lua_nodelib_setfield_whatsit(lua_State * L, int n, int field) case pdf_refxform_node: switch (field) { case 4: - pdf_width(n) = lua_tointeger(L, 3); + width(n) = (halfword) lua_tointeger(L, 3); break; case 5: - pdf_height(n) = lua_tointeger(L, 3); + depth(n) = (halfword) lua_tointeger(L, 3); break; case 6: - pdf_depth(n) = lua_tointeger(L, 3); + height(n) = (halfword) lua_tointeger(L, 3); break; case 7: - pdf_xform_objnum(n) = lua_tointeger(L, 3); + pdf_xform_objnum(n) = (halfword) lua_tointeger(L, 3); break; default: return nodelib_cantset(L, field, n); @@ -2206,16 +2318,19 @@ static int lua_nodelib_setfield_whatsit(lua_State * L, int n, int field) case pdf_refximage_node: switch (field) { case 4: - pdf_width(n) = lua_tointeger(L, 3); + width(n) = (halfword) lua_tointeger(L, 3); break; case 5: - pdf_height(n) = lua_tointeger(L, 3); + depth(n) = (halfword) lua_tointeger(L, 3); break; case 6: - pdf_depth(n) = lua_tointeger(L, 3); + height(n) = (halfword) lua_tointeger(L, 3); break; case 7: - pdf_ximage_objnum(n) = lua_tointeger(L, 3); + pdf_ximage_transform(n) = (halfword) lua_tointeger(L, 3); + break; + case 8: + pdf_ximage_index(n) = (halfword) lua_tointeger(L, 3); break; default: return nodelib_cantset(L, field, n); @@ -2224,16 +2339,16 @@ static int lua_nodelib_setfield_whatsit(lua_State * L, int n, int field) case pdf_annot_node: switch (field) { case 4: - pdf_width(n) = lua_tointeger(L, 3); + width(n) = (halfword) lua_tointeger(L, 3); break; case 5: - pdf_height(n) = lua_tointeger(L, 3); + depth(n) = (halfword) lua_tointeger(L, 3); break; case 6: - pdf_depth(n) = lua_tointeger(L, 3); + height(n) = (halfword) lua_tointeger(L, 3); break; case 7: - pdf_annot_objnum(n) = lua_tointeger(L, 3); + pdf_annot_objnum(n) = (halfword) lua_tointeger(L, 3); break; case 8: pdf_annot_data(n) = nodelib_gettoks(L, 3); @@ -2245,16 +2360,16 @@ static int lua_nodelib_setfield_whatsit(lua_State * L, int n, int field) case pdf_start_link_node: switch (field) { case 4: - pdf_width(n) = lua_tointeger(L, 3); + width(n) = (halfword) lua_tointeger(L, 3); break; case 5: - pdf_height(n) = lua_tointeger(L, 3); + depth(n) = (halfword) lua_tointeger(L, 3); break; case 6: - pdf_depth(n) = lua_tointeger(L, 3); + height(n) = (halfword) lua_tointeger(L, 3); break; case 7: - pdf_link_objnum(n) = lua_tointeger(L, 3); + pdf_link_objnum(n) = (halfword) lua_tointeger(L, 3); break; case 8: pdf_link_attr(n) = nodelib_gettoks(L, 3); @@ -2275,31 +2390,31 @@ static int lua_nodelib_setfield_whatsit(lua_State * L, int n, int field) case pdf_dest_node: switch (field) { case 4: - pdf_width(n) = lua_tointeger(L, 3); + width(n) = (halfword) lua_tointeger(L, 3); break; case 5: - pdf_height(n) = lua_tointeger(L, 3); + depth(n) = (halfword) lua_tointeger(L, 3); break; case 6: - pdf_depth(n) = lua_tointeger(L, 3); + height(n) = (halfword) lua_tointeger(L, 3); break; case 7: - pdf_dest_named_id(n) = lua_tointeger(L, 3); + pdf_dest_named_id(n) = (quarterword) lua_tointeger(L, 3); break; case 8: if (pdf_dest_named_id(n) == 1) pdf_dest_id(n) = nodelib_gettoks(L, 3); else - pdf_dest_id(n) = lua_tointeger(L, 3); + pdf_dest_id(n) = (halfword) lua_tointeger(L, 3); break; case 9: - pdf_dest_type(n) = lua_tointeger(L, 3); + pdf_dest_type(n) = (quarterword) lua_tointeger(L, 3); break; case 10: - pdf_dest_xyz_zoom(n) = lua_tointeger(L, 3); + pdf_dest_xyz_zoom(n) = (halfword) lua_tointeger(L, 3); break; case 11: - pdf_dest_objnum(n) = lua_tointeger(L, 3); + pdf_dest_objnum(n) = (halfword) lua_tointeger(L, 3); break; default: return nodelib_cantset(L, field, n); @@ -2309,22 +2424,22 @@ static int lua_nodelib_setfield_whatsit(lua_State * L, int n, int field) case pdf_start_thread_node: switch (field) { case 4: - pdf_width(n) = lua_tointeger(L, 3); + width(n) = (halfword) lua_tointeger(L, 3); break; case 5: - pdf_height(n) = lua_tointeger(L, 3); + depth(n) = (halfword) lua_tointeger(L, 3); break; case 6: - pdf_depth(n) = lua_tointeger(L, 3); + height(n) = (halfword) lua_tointeger(L, 3); break; case 7: - pdf_thread_named_id(n) = lua_tointeger(L, 3); + pdf_thread_named_id(n) = (quarterword) lua_tointeger(L, 3); break; case 8: if (pdf_thread_named_id(n) == 1) pdf_thread_id(n) = nodelib_gettoks(L, 3); else - pdf_thread_id(n) = lua_tointeger(L, 3); + pdf_thread_id(n) = (halfword) lua_tointeger(L, 3); break; case 9: pdf_thread_attr(n) = nodelib_gettoks(L, 3); @@ -2340,7 +2455,7 @@ static int lua_nodelib_setfield_whatsit(lua_State * L, int n, int field) case late_lua_node: switch (field) { case 4: - late_lua_reg(n) = lua_tointeger(L, 3); + late_lua_reg(n) = (halfword) lua_tointeger(L, 3); break; case 5: late_lua_data(n) = nodelib_gettoks(L, 3); @@ -2355,7 +2470,7 @@ static int lua_nodelib_setfield_whatsit(lua_State * L, int n, int field) case close_lua_node: switch (field) { case 4: - late_lua_reg(n) = lua_tointeger(L, 3); + late_lua_reg(n) = (halfword) lua_tointeger(L, 3); break; default: return nodelib_cantset(L, field, n); @@ -2364,10 +2479,10 @@ static int lua_nodelib_setfield_whatsit(lua_State * L, int n, int field) case pdf_colorstack_node: switch (field) { case 4: - pdf_colorstack_stack(n) = lua_tointeger(L, 3); + pdf_colorstack_stack(n) = (halfword) lua_tointeger(L, 3); break; case 5: - pdf_colorstack_cmd(n) = lua_tointeger(L, 3); + pdf_colorstack_cmd(n) = (halfword) lua_tointeger(L, 3); break; case 6: pdf_colorstack_data(n) = nodelib_gettoks(L, 3); @@ -2393,10 +2508,10 @@ static int lua_nodelib_setfield_whatsit(lua_State * L, int n, int field) case user_defined_node: switch (field) { case 4: - user_node_id(n) = lua_tointeger(L, 3); + user_node_id(n) = (halfword) lua_tointeger(L, 3); break; case 5: - user_node_type(n) = lua_tointeger(L, 3); + user_node_type(n) = (halfword) lua_tointeger(L, 3); break; case 6: switch (user_node_type(n)) { @@ -2404,7 +2519,7 @@ static int lua_nodelib_setfield_whatsit(lua_State * L, int n, int field) user_node_value(n) = nodelib_getlist(L, 3); break; case 'd': - user_node_value(n) = lua_tointeger(L, 3); + user_node_value(n) = (halfword) lua_tointeger(L, 3); break; case 'n': user_node_value(n) = nodelib_getlist(L, 3); @@ -2416,7 +2531,7 @@ static int lua_nodelib_setfield_whatsit(lua_State * L, int n, int field) user_node_value(n) = nodelib_gettoks(L, 3); break; default: - user_node_value(n) = lua_tointeger(L, 3); + user_node_value(n) = (halfword) lua_tointeger(L, 3); break; } break; @@ -2439,6 +2554,11 @@ static int lua_nodelib_setfield(lua_State * L) field = get_valid_node_field_id(L, 2, n); if (field < -1) return 0; + if (field !=0 && /* .next assignments are always allowed */ + !valid_node(n)) { + return luaL_error(L, "You can't assign to this %s node (%d)\n", node_data[type(n)].name, n); + /* return implied */ + } if (field == 0) { vlink(n) = nodelib_getlist(L, 3); } else if (field == -1) { @@ -2448,34 +2568,38 @@ static int lua_nodelib_setfield(lua_State * L) } else if (type(n) == glyph_node) { switch (field) { case 2: - subtype(n) = lua_tointeger(L, 3); + subtype(n) = (quarterword) lua_tointeger(L, 3); break; case 4: - character(n) = lua_tointeger(L, 3); + character(n) = (halfword) lua_tointeger(L, 3); break; case 5: - font(n) = lua_tointeger(L, 3); + font(n) = (halfword) lua_tointeger(L, 3); break; case 6: - set_char_lang(n, lua_tointeger(L, 3)); + set_char_lang(n, (halfword) lua_tointeger(L, 3)); break; case 7: - set_char_lhmin(n, lua_tointeger(L, 3)); + set_char_lhmin(n, (halfword) lua_tointeger(L, 3)); break; case 8: - set_char_rhmin(n, lua_tointeger(L, 3)); + set_char_rhmin(n, (halfword) lua_tointeger(L, 3)); break; case 9: - set_char_uchyph(n, lua_tointeger(L, 3)); + set_char_uchyph(n, (halfword) lua_tointeger(L, 3)); break; case 10: lig_ptr(n) = nodelib_getlist(L, 3); break; case 11: - x_displace(n) = lua_tointeger(L, 3); + x_displace(n) = (halfword) lua_tointeger(L, 3); break; case 12: - y_displace(n) = lua_tointeger(L, 3); + y_displace(n) = (halfword) lua_tointeger(L, 3); + break; + /* 13,14,15 are virtual width, height, depth */ + case 16: + ex_glyph(n) = (halfword) lua_tointeger(L, 3); break; default: return nodelib_cantset(L, field, n); @@ -2486,31 +2610,31 @@ static int lua_nodelib_setfield(lua_State * L) case vlist_node: switch (field) { case 2: - subtype(n) = lua_tointeger(L, 3); + subtype(n) = (quarterword) lua_tointeger(L, 3); break; case 4: - width(n) = lua_tointeger(L, 3); + width(n) = (halfword) lua_tointeger(L, 3); break; case 5: - depth(n) = lua_tointeger(L, 3); + depth(n) = (halfword) lua_tointeger(L, 3); break; case 6: - height(n) = lua_tointeger(L, 3); + height(n) = (halfword) lua_tointeger(L, 3); break; case 7: box_dir(n) = nodelib_getdir(L, 3); break; case 8: - shift_amount(n) = lua_tointeger(L, 3); + shift_amount(n) = (halfword) lua_tointeger(L, 3); break; case 9: - glue_order(n) = lua_tointeger(L, 3); + glue_order(n) = (quarterword) lua_tointeger(L, 3); break; case 10: - glue_sign(n) = lua_tointeger(L, 3); + glue_sign(n) = (quarterword) lua_tointeger(L, 3); break; case 11: - glue_set(n) = (double) lua_tonumber(L, 3); + glue_set(n) = (glue_ratio) lua_tonumber(L, 3); break; case 12: list_ptr(n) = nodelib_getlist(L, 3); @@ -2524,31 +2648,31 @@ static int lua_nodelib_setfield(lua_State * L) case 2: /* dummy subtype */ break; case 4: - width(n) = lua_tointeger(L, 3); + width(n) = (halfword) lua_tointeger(L, 3); break; case 5: - depth(n) = lua_tointeger(L, 3); + depth(n) = (halfword) lua_tointeger(L, 3); break; case 6: - height(n) = lua_tointeger(L, 3); + height(n) = (halfword) lua_tointeger(L, 3); break; case 7: - box_dir(n) = lua_tointeger(L, 3); + box_dir(n) = (halfword) lua_tointeger(L, 3); break; case 8: - glue_shrink(n) = lua_tointeger(L, 3); + glue_shrink(n) = (halfword) lua_tointeger(L, 3); break; case 9: - glue_order(n) = lua_tointeger(L, 3); + glue_order(n) = (quarterword) lua_tointeger(L, 3); break; case 10: - glue_sign(n) = lua_tointeger(L, 3); + glue_sign(n) = (quarterword) lua_tointeger(L, 3); break; case 11: - glue_stretch(n) = lua_tointeger(L, 3); + glue_stretch(n) = (halfword) lua_tointeger(L, 3); break; case 12: - span_count(n) = lua_tointeger(L, 3); + span_count(n) = (quarterword) lua_tointeger(L, 3); break; case 13: list_ptr(n) = nodelib_getlist(L, 3); @@ -2562,13 +2686,13 @@ static int lua_nodelib_setfield(lua_State * L) case 2: /* dummy subtype */ break; case 4: - width(n) = lua_tointeger(L, 3); + width(n) = (halfword) lua_tointeger(L, 3); break; case 5: - depth(n) = lua_tointeger(L, 3); + depth(n) = (halfword) lua_tointeger(L, 3); break; case 6: - height(n) = lua_tointeger(L, 3); + height(n) = (halfword) lua_tointeger(L, 3); break; case 7: rule_dir(n) = nodelib_getdir(L, 3); @@ -2580,16 +2704,16 @@ static int lua_nodelib_setfield(lua_State * L) case ins_node: switch (field) { case 2: - subtype(n) = lua_tointeger(L, 3); + subtype(n) = (quarterword) lua_tointeger(L, 3); break; case 4: - float_cost(n) = lua_tointeger(L, 3); + float_cost(n) = (halfword) lua_tointeger(L, 3); break; case 5: - depth(n) = lua_tointeger(L, 3); + depth(n) = (halfword) lua_tointeger(L, 3); break; case 6: - height(n) = lua_tointeger(L, 3); + height(n) = (halfword) lua_tointeger(L, 3); break; case 7: split_top_ptr(n) = nodelib_getspec(L, 3); @@ -2604,10 +2728,10 @@ static int lua_nodelib_setfield(lua_State * L) case mark_node: switch (field) { case 2: - subtype(n) = lua_tointeger(L, 3); + subtype(n) = (quarterword) lua_tointeger(L, 3); break; case 4: - mark_class(n) = lua_tointeger(L, 3); + mark_class(n) = (halfword) lua_tointeger(L, 3); break; case 5: mark_ptr(n) = nodelib_gettoks(L, 3); @@ -2619,7 +2743,7 @@ static int lua_nodelib_setfield(lua_State * L) case adjust_node: switch (field) { case 2: - subtype(n) = lua_tointeger(L, 3); + subtype(n) = (quarterword) lua_tointeger(L, 3); break; case 4: adjust_ptr(n) = nodelib_getlist(L, 3); @@ -2631,7 +2755,7 @@ static int lua_nodelib_setfield(lua_State * L) case disc_node: switch (field) { case 2: - subtype(n) = lua_tointeger(L, 3); + subtype(n) = (quarterword) lua_tointeger(L, 3); break; case 4: set_disc_field(pre_break(n), nodelib_getlist(L, 3)); @@ -2649,10 +2773,10 @@ static int lua_nodelib_setfield(lua_State * L) case math_node: switch (field) { case 2: - subtype(n) = lua_tointeger(L, 3); + subtype(n) = (quarterword) lua_tointeger(L, 3); break; case 4: - surround(n) = lua_tointeger(L, 3); + surround(n) = (halfword) lua_tointeger(L, 3); break; default: return nodelib_cantset(L, field, n); @@ -2661,7 +2785,7 @@ static int lua_nodelib_setfield(lua_State * L) case glue_node: switch (field) { case 2: - subtype(n) = lua_tointeger(L, 3); + subtype(n) = (quarterword) lua_tointeger(L, 3); break; case 4: glue_ptr(n) = nodelib_getspec(L, 3); @@ -2678,34 +2802,38 @@ static int lua_nodelib_setfield(lua_State * L) case 2: /* dummy subtype */ break; case 3: - width(n) = lua_tointeger(L, 3); + width(n) = (halfword) lua_tointeger(L, 3); break; case 4: - stretch(n) = lua_tointeger(L, 3); + stretch(n) = (halfword) lua_tointeger(L, 3); break; case 5: - shrink(n) = lua_tointeger(L, 3); + shrink(n) = (halfword) lua_tointeger(L, 3); break; case 6: - stretch_order(n) = lua_tointeger(L, 3); + stretch_order(n) = (quarterword) lua_tointeger(L, 3); break; case 7: - shrink_order(n) = lua_tointeger(L, 3); + shrink_order(n) = (quarterword) lua_tointeger(L, 3); break; case 8: - glue_ref_count(n) = lua_tointeger(L, 3); + glue_ref_count(n) = (halfword) lua_tointeger(L, 3); break; default: return nodelib_cantset(L, field, n); + } break; case kern_node: switch (field) { case 2: - subtype(n) = lua_tointeger(L, 3); + subtype(n) = (quarterword) lua_tointeger(L, 3); break; case 4: - width(n) = lua_tointeger(L, 3); + width(n) = (halfword) lua_tointeger(L, 3); + break; + case 5: + ex_kern(n) = (halfword) lua_tointeger(L, 3); break; default: return nodelib_cantset(L, field, n); @@ -2716,7 +2844,7 @@ static int lua_nodelib_setfield(lua_State * L) case 2: /* dummy subtype */ break; case 4: - penalty(n) = lua_tointeger(L, 3); + penalty(n) = (halfword) lua_tointeger(L, 3); break; default: return nodelib_cantset(L, field, n); @@ -2727,29 +2855,29 @@ static int lua_nodelib_setfield(lua_State * L) case 2: /* dummy subtype */ break; case 3: - pdf_action_type(n) = lua_tointeger(L, 3); + pdf_action_type(n) = (quarterword) lua_tointeger(L, 3); break; case 4: - pdf_action_named_id(n) = lua_tointeger(L, 3); + pdf_action_named_id(n) = (quarterword) lua_tointeger(L, 3); break; case 5: if (pdf_action_named_id(n) == 1) { pdf_action_id(n) = nodelib_gettoks(L, 3); } else { - pdf_action_id(n) = lua_tointeger(L, 3); + pdf_action_id(n) = (halfword) lua_tointeger(L, 3); } break; case 6: pdf_action_file(n) = nodelib_gettoks(L, 3); break; case 7: - pdf_action_new_window(n) = lua_tointeger(L, 3); + pdf_action_new_window(n) = (halfword) lua_tointeger(L, 3); break; case 8: pdf_action_tokens(n) = nodelib_gettoks(L, 3); break; case 9: - pdf_action_refcount(n) = lua_tointeger(L, 3); + pdf_action_refcount(n) = (halfword) lua_tointeger(L, 3); break; default: return nodelib_cantset(L, field, n); @@ -2760,7 +2888,9 @@ static int lua_nodelib_setfield(lua_State * L) case 2: /* dummy subtype */ break; case 4: - subtype(n) = luaL_checkoption(L, 3, "text", math_style_names); + subtype(n) = + (quarterword) luaL_checkoption(L, 3, "text", + math_style_names); break; default: return nodelib_cantset(L, field, n); @@ -2769,7 +2899,7 @@ static int lua_nodelib_setfield(lua_State * L) case choice_node: switch (field) { case 2: - subtype(n) = lua_tointeger(L, 3); + subtype(n) = (quarterword) lua_tointeger(L, 3); break; case 4: display_mlist(n) = nodelib_getlist(L, 3); @@ -2790,7 +2920,7 @@ static int lua_nodelib_setfield(lua_State * L) case simple_noad: switch (field) { case 2: - subtype(n) = lua_tointeger(L, 3); + subtype(n) = (quarterword) lua_tointeger(L, 3); break; case 4: nucleus(n) = nodelib_getlist(L, 3); @@ -2808,7 +2938,7 @@ static int lua_nodelib_setfield(lua_State * L) case radical_noad: switch (field) { case 2: - subtype(n) = lua_tointeger(L, 3); + subtype(n) = (quarterword) lua_tointeger(L, 3); break; case 4: nucleus(n) = nodelib_getlist(L, 3); @@ -2832,10 +2962,10 @@ static int lua_nodelib_setfield(lua_State * L) case fraction_noad: switch (field) { case 2: - subtype(n) = lua_tointeger(L, 3); + subtype(n) = (quarterword) lua_tointeger(L, 3); break; case 4: - thickness(n) = lua_tointeger(L, 3); + thickness(n) = (halfword) lua_tointeger(L, 3); break; case 5: numerator(n) = nodelib_getlist(L, 3); @@ -2856,7 +2986,7 @@ static int lua_nodelib_setfield(lua_State * L) case accent_noad: switch (field) { case 2: - subtype(n) = lua_tointeger(L, 3); + subtype(n) = (quarterword) lua_tointeger(L, 3); break; case 4: nucleus(n) = nodelib_getlist(L, 3); @@ -2880,7 +3010,7 @@ static int lua_nodelib_setfield(lua_State * L) case fence_noad: switch (field) { case 2: - subtype(n) = lua_tointeger(L, 3); + subtype(n) = (quarterword) lua_tointeger(L, 3); break; case 4: delimiter(n) = nodelib_getlist(L, 3); @@ -2893,13 +3023,13 @@ static int lua_nodelib_setfield(lua_State * L) case math_text_char_node: switch (field) { case 2: - subtype(n) = lua_tointeger(L, 3); + subtype(n) = (quarterword) lua_tointeger(L, 3); break; case 4: - math_fam(n) = lua_tointeger(L, 3); + math_fam(n) = (halfword) lua_tointeger(L, 3); break; case 5: - math_character(n) = lua_tointeger(L, 3); + math_character(n) = (halfword) lua_tointeger(L, 3); break; default: return nodelib_cantset(L, field, n); @@ -2909,7 +3039,7 @@ static int lua_nodelib_setfield(lua_State * L) case sub_mlist_node: switch (field) { case 2: - subtype(n) = lua_tointeger(L, 3); + subtype(n) = (quarterword) lua_tointeger(L, 3); break; case 4: math_list(n) = nodelib_getlist(L, 3); @@ -2921,19 +3051,19 @@ static int lua_nodelib_setfield(lua_State * L) case delim_node: switch (field) { case 2: - subtype(n) = lua_tointeger(L, 3); + subtype(n) = (quarterword) lua_tointeger(L, 3); break; case 4: - small_fam(n) = lua_tointeger(L, 3); + small_fam(n) = (halfword) lua_tointeger(L, 3); break; case 5: - small_char(n) = lua_tointeger(L, 3); + small_char(n) = (halfword) lua_tointeger(L, 3); break; case 6: - large_fam(n) = lua_tointeger(L, 3); + large_fam(n) = (halfword) lua_tointeger(L, 3); break; case 7: - large_char(n) = lua_tointeger(L, 3); + large_char(n) = (halfword) lua_tointeger(L, 3); break; default: return nodelib_cantset(L, field, n); @@ -2942,12 +3072,12 @@ static int lua_nodelib_setfield(lua_State * L) case margin_kern_node: switch (field) { case 2: - subtype(n) = lua_tointeger(L, 3); - break; - case 3: - width(n) = lua_tointeger(L, 3); + subtype(n) = (quarterword) lua_tointeger(L, 3); break; case 4: + width(n) = (halfword) lua_tointeger(L, 3); + break; + case 5: margin_char(n) = nodelib_getlist(L, 3); break; default: @@ -2957,7 +3087,7 @@ static int lua_nodelib_setfield(lua_State * L) case inserting_node: switch (field) { case 2: - subtype(n) = lua_tointeger(L, 3); + subtype(n) = (quarterword) lua_tointeger(L, 3); break; case 3: last_ins_ptr(n) = nodelib_getlist(L, 3); @@ -2972,7 +3102,7 @@ static int lua_nodelib_setfield(lua_State * L) case split_up_node: switch (field) { case 2: - subtype(n) = lua_tointeger(L, 3); + subtype(n) = (quarterword) lua_tointeger(L, 3); break; case 3: last_ins_ptr(n) = nodelib_getlist(L, 3); @@ -3003,10 +3133,10 @@ static int lua_nodelib_setfield(lua_State * L) case 2: /* dummy subtype */ break; case 3: - attribute_id(n) = lua_tointeger(L, 3); + attribute_id(n) = (halfword) lua_tointeger(L, 3); break; case 4: - attribute_value(n) = lua_tointeger(L, 3); + attribute_value(n) = (halfword) lua_tointeger(L, 3); break; default: return nodelib_cantset(L, field, n); @@ -3118,7 +3248,7 @@ static int lua_nodelib_protect_glyphs(lua_State * L) register int s = subtype(head); if (s <= 256) { t = 1; - subtype(head) = (s == 1 ? 256 : 256 + s); + subtype(head) = (quarterword) (s == 1 ? 256 : 256 + s); } } head = vlink(head); @@ -3137,7 +3267,7 @@ static int lua_nodelib_unprotect_glyphs(lua_State * L) register int s = subtype(head); if (s > 256) { t = 1; - subtype(head) = s - 256; + subtype(head) = (quarterword) (s - 256); } } head = vlink(head); @@ -3178,7 +3308,7 @@ static int lua_nodelib_first_character(lua_State * L) /* this is too simplistic, but it helps Hans to get going */ -static halfword do_ligature_n(halfword prev, halfword stop, halfword lig) +halfword do_ligature_n(halfword prev, halfword stop, halfword lig) { vlink(lig) = vlink(stop); vlink(stop) = null; @@ -3216,6 +3346,14 @@ static int lua_nodelib_usedlist(lua_State * L) return 1; } +/* node.protrusion_skipable(node m) */ +static int lua_nodelib_cp_skipable(lua_State * L) +{ + halfword n; + n = *(check_isnode(L, 1)); + lua_pushboolean(L, cp_skipable(n)); + return 1; +} static const struct luaL_reg nodelib_f[] = { {"id", lua_nodelib_id}, @@ -3226,6 +3364,7 @@ static const struct luaL_reg nodelib_f[] = { {"count", lua_nodelib_count}, {"traverse", lua_nodelib_traverse}, {"traverse_id", lua_nodelib_traverse_filtered}, + {"tail", lua_nodelib_tail_only}, {"slide", lua_nodelib_tail}, {"types", lua_nodelib_types}, {"whatsits", lua_nodelib_whatsits}, @@ -3240,6 +3379,7 @@ static const struct luaL_reg nodelib_f[] = { {"last_node", lua_nodelib_last_node}, {"copy", lua_nodelib_copy}, {"copy_list", lua_nodelib_copy_list}, + {"dimensions", lua_nodelib_dimensions}, {"hpack", lua_nodelib_hpack}, {"vpack", lua_nodelib_vpack}, {"mlist_to_hlist", lua_nodelib_mlist_to_hlist}, @@ -3254,7 +3394,8 @@ static const struct luaL_reg nodelib_f[] = { {"usedlist", lua_nodelib_usedlist}, {"protect_glyphs", lua_nodelib_protect_glyphs}, {"unprotect_glyphs", lua_nodelib_unprotect_glyphs}, - {NULL, NULL} /* sentinel */ + {"protrusion_skipable", lua_nodelib_cp_skipable}, + {NULL, NULL} /* sentinel */ }; static const struct luaL_reg nodelib_m[] = { diff --git a/Build/source/texk/web2c/luatexdir/lua/loslibext.c b/Build/source/texk/web2c/luatexdir/lua/loslibext.c index f79b0f0daf0..9130f488d59 100644 --- a/Build/source/texk/web2c/luatexdir/lua/loslibext.c +++ b/Build/source/texk/web2c/luatexdir/lua/loslibext.c @@ -17,17 +17,17 @@ You should have received a copy of the GNU General Public License along with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */ -#include "luatex-api.h" -#include <ptexlib.h> +#include "lua/luatex-api.h" +#include "ptexlib.h" -#include <sys/stat.h> -#include <sys/types.h> +#include <kpathsea/c-stat.h> +#include <kpathsea/c-dir.h> #include <time.h> static const char _svn_version[] = - "$Id: loslibext.c 2376 2009-05-08 08:40:13Z taco $ $URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.40.6/source/texk/web2c/luatexdir/lua/loslibext.c $"; + "$Id: loslibext.c 3518 2010-03-17 09:57:13Z taco $ $URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/lua/loslibext.c $"; -#if defined(_WIN32) || defined(WIN32) || defined(__NT__) +#if defined(_WIN32) || defined(__NT__) # define MKDIR(a,b) mkdir(a) #else # define MKDIR(a,b) mkdir(a,b) @@ -39,7 +39,7 @@ static const char _svn_version[] = successfully compile without major prorting effort (amiga|mac|os2|vms) */ -#if defined(_WIN32) || defined(WIN32) || defined(__NT__) +#if defined(_WIN32) || defined(__NT__) # define OS_PLATTYPE "windows" # define OS_PLATNAME "windows" #elif defined(__GO32__) || defined(__DJGPP__) || defined(__DOS__) @@ -51,6 +51,8 @@ static const char _svn_version[] = /* this is just a first guess */ # if defined(__BSD__) # define OS_PLATNAME "bsd" +# elif defined(__CYGWIN__) +# define OS_PLATNAME "cygwin" # elif defined(__SYSV__) # define OS_PLATNAME "sysv" # else @@ -63,6 +65,9 @@ static const char _svn_version[] = # elif defined(__FREEBSD__) || defined(__FreeBSD__) || defined(__FreeBSD) # undef OS_PLATNAME # define OS_PLATNAME "freebsd" +# elif defined(__FreeBSD_kernel__) +# undef OS_PLATNAME +# define OS_PLATNAME "kfreebsd" # elif defined(__OPENBSD__) || defined(__OpenBSD) # undef OS_PLATNAME # define OS_PLATNAME "openbsd" @@ -81,6 +86,9 @@ static const char _svn_version[] = # elif defined(__MACH__) && defined(__APPLE__) # undef OS_PLATNAME # define OS_PLATNAME "macosx" +# elif defined(__GNU__) +# undef OS_PLATNAME +# define OS_PLATNAME "gnu" # endif #endif @@ -93,7 +101,7 @@ static const char _svn_version[] = * gettimeofday() for win32 is using an alternative definition */ -#if (! defined(WIN32)) && (! defined(__SUNOS__)) +#if (! defined(_WIN32)) && (! defined(__SUNOS__)) # include <sys/time.h> /* gettimeofday() */ # include <sys/times.h> /* times() */ # include <sys/wait.h> @@ -103,7 +111,7 @@ static const char _svn_version[] = #define DONT_REALLY_EXIT 1 -#ifdef WIN32 +#ifdef _WIN32 # include <process.h> # define spawn_command(a,b,c) _spawnvpe(_P_WAIT,(const char *)a,(const char* const*)b,(const char* const*)c) # if DONT_REALLY_EXIT @@ -117,7 +125,7 @@ static const char _svn_version[] = static int exec_command(const char *file, char *const *argv, char *const *envp) { - char path[PATH_MAX]; + char *path; const char *searchpath, *esp; size_t prefixlen, filelen, totallen; @@ -125,6 +133,7 @@ static int exec_command(const char *file, char *const *argv, char *const *envp) return execve(file, argv, envp); filelen = strlen(file); + path = NULL; searchpath = getenv("PATH"); if (!searchpath) @@ -135,20 +144,26 @@ static int exec_command(const char *file, char *const *argv, char *const *envp) do { esp = strchr(searchpath, ':'); if (esp) - prefixlen = esp - searchpath; + prefixlen = (size_t) (esp - searchpath); else prefixlen = strlen(searchpath); if (prefixlen == 0 || searchpath[prefixlen - 1] == '/') { totallen = prefixlen + filelen; +# ifdef PATH_MAX if (totallen >= PATH_MAX) continue; +# endif + path = malloc(totallen + 1); memcpy(path, searchpath, prefixlen); memcpy(path + prefixlen, file, filelen); } else { totallen = prefixlen + filelen + 1; +# ifdef PATH_MAX if (totallen >= PATH_MAX) continue; +# endif + path = malloc(totallen + 1); memcpy(path, searchpath, prefixlen); path[prefixlen] = '/'; memcpy(path + prefixlen + 1, file, filelen); @@ -156,6 +171,8 @@ static int exec_command(const char *file, char *const *argv, char *const *envp) path[totallen] = '\0'; execve(path, argv, envp); + free(path); + path = NULL; if (errno == E2BIG || errno == ENOEXEC || errno == ENOMEM || errno == ETXTBSY) break; /* Report this as an error, no more search */ @@ -242,13 +259,44 @@ static int spawn_command(const char *file, char *const *argv, char *const *envp) #endif -extern char **environ; +#ifdef _WIN32 +static char *get_command_name(char *maincmd) +{ + /* retrieve argv[0] part from the command string, + it will be truncated to MAX_PATH if it's too long */ + char *cmdname = (char *) malloc(sizeof(char) * MAX_PATH); + int i, k, quoted; + quoted = k = 0; + for (i = 0; (i < MAX_PATH) && maincmd[i] && + (maincmd[i] != ' ' && maincmd[i] != '\t' || quoted); i++) { + if (maincmd[i] == '"') { + quoted = !quoted; + } else { + cmdname[k] = maincmd[i]; + k++; + } + } + cmdname[k] = '\0'; + return cmdname; +} +#endif -static char **do_split_command(const char *maincmd) +static char **do_split_command(const char *maincmd, char **runcmd) { + char **cmdline = NULL; +#ifdef _WIN32 + /* On WIN32 don't split anything, because + _spawnvpe can't put it back together properly + if there are quoted arguments with spaces. + Instead, dump everything into one argument + and it will be passed through as is */ + cmdline = malloc(sizeof(char *) * 2); + cmdline[0] = xstrdup(maincmd); + cmdline[1] = NULL; + *runcmd = get_command_name(cmdline[0]); +#else char *piece, *start_piece; const char *cmd; - char **cmdline = NULL; unsigned int i, j; int ret = 0; int in_string = 0; @@ -298,12 +346,15 @@ static char **do_split_command(const char *maincmd) quoted = 0; } xfree(start_piece); + *runcmd = cmdline[0]; +#endif return cmdline; } static char **do_flatten_command(lua_State * L, char **runcmd) { - unsigned int i, j; + unsigned int i; + int j; const char *s; char **cmdline = NULL; *runcmd = NULL; @@ -318,10 +369,10 @@ static char **do_flatten_command(lua_State * L, char **runcmd) } if (j == 1) return NULL; - cmdline = malloc(sizeof(char *) * (j + 1)); - for (i = 1; i <= j; i++) { + cmdline = malloc(sizeof(char *) * (unsigned) (j + 1)); + for (i = 1; i <= (unsigned) j; i++) { cmdline[i] = NULL; - lua_rawgeti(L, -1, i); + lua_rawgeti(L, -1, (int) i); if (lua_isnil(L, -1) || (s = lua_tostring(L, -1)) == NULL) { lua_pop(L, 1); if (i == 1) { @@ -339,7 +390,11 @@ static char **do_flatten_command(lua_State * L, char **runcmd) lua_rawgeti(L, -1, 0); if (lua_isnil(L, -1) || (s = lua_tostring(L, -1)) == NULL) { +#ifdef _WIN32 + *runcmd = get_command_name(cmdline[0]); +#else *runcmd = cmdline[0]; +#endif } else { *runcmd = xstrdup(s); } @@ -369,8 +424,7 @@ static int os_exec(lua_State * L) } if (lua_type(L, 1) == LUA_TSTRING) { maincmd = lua_tostring(L, 1); - cmdline = do_split_command(maincmd); - runcmd = cmdline[0]; + cmdline = do_split_command(maincmd, &runcmd); } else if (lua_type(L, 1) == LUA_TTABLE) { cmdline = do_flatten_command(L, &runcmd); } @@ -380,13 +434,15 @@ static int os_exec(lua_State * L) * but I am not so eager to attempt to fix that. Just document * that os.exec() checks only the command name. */ - if (restrictedshell == 0) + if (restrictedshell == 0) { allow = 1; - else - allow = shell_cmd_is_allowed(runcmd, &safecmd, &cmdname); + } else { + const char *theruncmd = runcmd; + allow = shell_cmd_is_allowed(&theruncmd, &safecmd, &cmdname); + } if (allow > 0 && cmdline != NULL && runcmd != NULL) { -#if defined(WIN32) && DONT_REALLY_EXIT +#if defined(_WIN32) && DONT_REALLY_EXIT if (allow == 2) exec_command(safecmd, cmdline, environ); else @@ -449,8 +505,7 @@ static int os_spawn(lua_State * L) } if (lua_type(L, 1) == LUA_TSTRING) { maincmd = lua_tostring(L, 1); - cmdline = do_split_command(maincmd); - runcmd = cmdline[0]; + cmdline = do_split_command(maincmd, &runcmd); } else if (lua_type(L, 1) == LUA_TTABLE) { cmdline = do_flatten_command(L, &runcmd); } @@ -460,10 +515,12 @@ static int os_spawn(lua_State * L) * but I am not so eager to attempt to fix that. Just document * that os.exec() checks only the command name. */ - if (restrictedshell == 0) + if (restrictedshell == 0) { allow = 1; - else - allow = shell_cmd_is_allowed(runcmd, &safecmd, &cmdname); + } else { + const char *theruncmd = runcmd; + allow = shell_cmd_is_allowed(&theruncmd, &safecmd, &cmdname); + } if (allow > 0 && cmdline != NULL && runcmd != NULL) { if (allow == 2) i = spawn_command(safecmd, cmdline, environ); @@ -479,7 +536,7 @@ static int os_spawn(lua_State * L) } else if (i == -1) { /* this branch covers WIN32 as well as fork() and waitpid() errors */ do_error_return(strerror(errno), errno); -#ifndef WIN32 +#ifndef _WIN32 } else if (i == INVALID_RET_E2BIG) { do_error_return(strerror(E2BIG), i); } else if (i == INVALID_RET_ENOENT) { @@ -518,19 +575,19 @@ static int os_spawn(lua_State * L) static int os_setenv(lua_State * L) { - char *value; const char *key, *val; + char *value; key = luaL_optstring(L, 1, NULL); val = luaL_optstring(L, 2, NULL); if (key) { if (val) { - value = xmalloc(strlen(key) + strlen(val) + 2); + value = xmalloc((unsigned) (strlen(key) + strlen(val) + 2)); sprintf(value, "%s=%s", key, val); if (putenv(value)) { return luaL_error(L, "unable to change environment"); } } else { -#if defined(WIN32) || defined(__sun__) || defined(__sun) || defined(_AIX) +#if defined(_WIN32) || defined(__sun__) || defined(__sun) || defined(_AIX) value = xmalloc(strlen(key) + 2); sprintf(value, "%s=", key); if (putenv(value)) { @@ -546,7 +603,7 @@ static int os_setenv(lua_State * L) } -static void find_env(lua_State * L) +void find_env(lua_State * L) { char *envitem, *envitem_orig; char *envkey; @@ -583,17 +640,17 @@ static int ex_sleep(lua_State * L) { lua_Number interval = luaL_checknumber(L, 1); lua_Number units = luaL_optnumber(L, 2, 1); -#ifdef WIN32 - Sleep(1e3 * interval / units); +#ifdef _WIN32 + Sleep((DWORD) (1e3 * interval / units)); #else /* assumes posix or bsd */ - usleep(1e6 * interval / units); + usleep((unsigned) (1e6 * interval / units)); #endif return 0; } -#ifdef WIN32 +#ifdef _WIN32 # define _UTSNAME_LENGTH 65 /* Structure describing the system and machine. */ @@ -754,7 +811,7 @@ static int ex_uname(lua_State * L) } -#if (! defined (WIN32)) && (! defined (__SUNOS__)) +#if (! defined (_WIN32)) && (! defined (__SUNOS__)) static int os_times(lua_State * L) { struct tms r; @@ -791,7 +848,7 @@ static int os_times(lua_State * L) static int os_gettimeofday(lua_State * L) { double v; -# ifndef WIN32 +# ifndef _WIN32 struct timeval tv; gettimeofday(&tv, NULL); v = (double) tv.tv_sec + (double) tv.tv_usec / 1000000.0; @@ -813,21 +870,20 @@ static int os_gettimeofday(lua_State * L) } #endif -#ifndef HAVE_MKDTEMP static const char repl[] = "0123456789abcdefghijklmnopqrstuvwxyz"; static int dirs_made = 0; #define MAXTRIES 36*36*36 -static char *do_mkdtemp(char *tmpl) +char *do_mkdtemp(char *tmpl) { int count; int value; char *xes = &tmpl[strlen(tmpl) - 6]; /* this is not really all that random, but it will do */ if (dirs_made == 0) { - srand(time(NULL)); + srand((unsigned) time(NULL)); } value = rand(); for (count = 0; count < MAXTRIES; value += 8413, ++count) { @@ -852,7 +908,6 @@ static char *do_mkdtemp(char *tmpl) } return NULL; } -#endif static int os_tmpdir(lua_State * L) { @@ -900,7 +955,7 @@ static int os_execute(lua_State * L) if (restrictedshell == 0) allow = 1; else - allow = shell_cmd_is_allowed(cmd, &safecmd, &cmdname); + allow = shell_cmd_is_allowed(&cmd, &safecmd, &cmdname); if (allow == 1) { lua_pushinteger(L, system(cmd)); @@ -937,7 +992,7 @@ void open_oslibext(lua_State * L, int safer_option) lua_setfield(L, -2, "name"); lua_pushcfunction(L, ex_uname); lua_setfield(L, -2, "uname"); -#if (! defined (WIN32)) && (! defined (__SUNOS__)) +#if (! defined (_WIN32)) && (! defined (__SUNOS__)) lua_pushcfunction(L, os_times); lua_setfield(L, -2, "times"); #endif diff --git a/Build/source/texk/web2c/luatexdir/lua/lpdflib.c b/Build/source/texk/web2c/luatexdir/lua/lpdflib.c index 6de1ae112a9..b715f02b24b 100644 --- a/Build/source/texk/web2c/luatexdir/lua/lpdflib.c +++ b/Build/source/texk/web2c/luatexdir/lua/lpdflib.c @@ -1,6 +1,6 @@ /* lpdflib.c - - Copyright 2006-2008 Taco Hoekwater <taco@luatex.org> + + Copyright 2006-2010 Taco Hoekwater <taco@luatex.org> This file is part of LuaTeX. @@ -17,151 +17,751 @@ You should have received a copy of the GNU General Public License along with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */ -#include "luatex-api.h" -#include <ptexlib.h> - static const char _svn_version[] = - "$Id: lpdflib.c 2329 2009-04-18 14:25:30Z hhenkel $ " - "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.40.6/source/texk/web2c/luatexdir/lua/lpdflib.c $"; + "$Id: lpdflib.c 3582 2010-04-02 16:37:08Z hhenkel $ " + "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/lua/lpdflib.c $"; -static int findcurv(lua_State * L) -{ - int j; - j = get_cur_v(); - lua_pushnumber(L, j); - return 1; -} +#include "lua/luatex-api.h" +#include "ptexlib.h" -static int findcurh(lua_State * L) -{ - int j; - j = get_cur_h(); - lua_pushnumber(L, j); - return 1; +#define buf_to_pdfbuf_macro(p, s, l) \ +for (i = 0; i < (l); i++) { \ + if (i % 16 == 0) \ + pdf_room(p, 16); \ + pdf_quick_out(p, ((const unsigned char *) (s))[i]); \ } -static int luapdfprint(lua_State * L) +int luapdfprint(lua_State * L) { int n; unsigned i; - size_t len; - const char *outputstr, *st; + const_lstring st, modestr; ctm_transform_modes literal_mode; + st.s = modestr.s = NULL; n = lua_gettop(L); if (!lua_isstring(L, -1)) { - lua_pushstring(L, "no string to print"); - lua_error(L); + luaL_error(L, "no string to print"); } literal_mode = set_origin; if (n == 2) { if (!lua_isstring(L, -2)) { - lua_pushstring(L, "invalid argument for print literal mode"); - lua_error(L); + luaL_error(L, "invalid argument for print literal mode"); } else { - outputstr = lua_tostring(L, -2); - if (strcmp(outputstr, "direct") == 0) + modestr.s = lua_tolstring(L, -2, &modestr.l); + if (modestr.l == 6 && strncmp(modestr.s, "direct", 6) == 0) literal_mode = direct_always; - else if (strcmp(outputstr, "page") == 0) + else if (modestr.l == 4 && strncmp(modestr.s, "page", 4) == 0) literal_mode = direct_page; else { - lua_pushstring(L, "invalid argument for print literal mode"); - lua_error(L); + luaL_error(L, "invalid argument for print literal mode"); } } } else { if (n != 1) { - lua_pushstring(L, "invalid number of arguments"); - lua_error(L); + luaL_error(L, "invalid number of arguments"); } } - check_pdfminorversion(); + check_o_mode(static_pdf, "pdf.print()", 1 << OMODE_PDF, true); switch (literal_mode) { case (set_origin): - pdf_goto_pagemode(); - pos = synch_p_with_c(cur); - pdf_set_pos(pos.h, pos.v); + pdf_goto_pagemode(static_pdf); + pdf_set_pos(static_pdf, static_pdf->posstruct->pos); + (void) calc_pdfpos(static_pdf->pstruct, static_pdf->posstruct->pos); break; case (direct_page): - pdf_goto_pagemode(); + pdf_goto_pagemode(static_pdf); + (void) calc_pdfpos(static_pdf->pstruct, static_pdf->posstruct->pos); break; case (direct_always): - pdf_end_string_nl(); + pdf_end_string_nl(static_pdf); break; default: assert(0); } - st = lua_tolstring(L, n, &len); - for (i = 0; i < len; i++) { - if (i % 16 == 0) - pdfroom(16); - pdf_buf[pdf_ptr++] = st[i]; - } + st.s = lua_tolstring(L, n, &st.l); + buf_to_pdfbuf_macro(static_pdf, st.s, st.l); return 0; } +unsigned char *fread_to_buf(lua_State * L, const char *filename, size_t * len) +{ + int i = 0; + int ilen = 0; + FILE *f; + unsigned char *buf = NULL; + if ((f = fopen(filename, "rb")) == NULL) + luaL_error(L, "pdf.immediateobj() cannot open input file"); + if ((i = readbinfile(f, &buf, &ilen)) == 0) + luaL_error(L, "pdf.immediateobj() cannot read input file"); + fclose(f); + *len = (size_t) ilen; + return buf; +} + static int l_immediateobj(lua_State * L) { + int n, first_arg = 1; unsigned i; - size_t len; - const char *st; - if (!lua_isstring(L, -1)) - luaL_error(L, "pdf.immediateobj needs string value"); - pdf_create_obj(obj_type_others, 0); - pdf_begin_obj(obj_ptr, 1); - st = lua_tolstring(L, -1, &len); - for (i = 0; i < len; i++) { - if (i % 16 == 0) - pdfroom(16); - pdf_buf[pdf_ptr++] = st[i]; - } - pdf_puts("\n"); - pdf_end_obj(); - lua_pop(L, 1); - lua_pushinteger(L, obj_ptr); + int k; + lstring buf; + const_lstring st1, st2, st3; + st1.s = st2.s = st3.s = NULL; + check_o_mode(static_pdf, "immediateobj()", 1 << OMODE_PDF, true); + n = lua_gettop(L); + if (n > 0 && lua_type(L, 1) == LUA_TNUMBER) { + first_arg++; + lua_number2int(k, lua_tonumber(L, 1)); + check_obj_exists(static_pdf, obj_type_obj, k); + if (is_obj_scheduled(static_pdf, k) || obj_data_ptr(static_pdf, k) != 0) + luaL_error(L, "pdf.immediateobj() object in use"); + } else { + incr(static_pdf->obj_count); + pdf_create_obj(static_pdf, obj_type_obj, static_pdf->sys_obj_ptr + 1); + k = static_pdf->sys_obj_ptr; + } + pdf_last_obj = k; + switch (n - first_arg + 1) { + case 0: + luaL_error(L, "pdf.immediateobj() needs at least one argument"); + break; + case 1: + if (!lua_isstring(L, first_arg)) + luaL_error(L, "pdf.immediateobj() 1st argument must be string"); + pdf_begin_obj(static_pdf, k, 1); + st1.s = lua_tolstring(L, first_arg, &st1.l); + buf_to_pdfbuf_macro(static_pdf, st1.s, st1.l); + if (st1.s[st1.l - 1] != '\n') + pdf_puts(static_pdf, "\n"); + pdf_end_obj(static_pdf); + break; + case 2: + case 3: + if (!lua_isstring(L, first_arg)) + luaL_error(L, "pdf.immediateobj() 1st argument must be string"); + if (!lua_isstring(L, first_arg + 1)) + luaL_error(L, "pdf.immediateobj() 2nd argument must be string"); + st1.s = lua_tolstring(L, first_arg, &st1.l); + st2.s = lua_tolstring(L, first_arg + 1, &st2.l); + if (st1.l == 4 && strncmp((const char *) st1.s, "file", 4) == 0) { + if (n == first_arg + 2) + luaL_error(L, + "pdf.immediateobj() 3rd argument forbidden in file mode"); + pdf_begin_obj(static_pdf, k, 1); + buf.s = fread_to_buf(L, st2.s, &buf.l); + buf_to_pdfbuf_macro(static_pdf, buf.s, buf.l); + if (buf.s[buf.l - 1] != '\n') + pdf_puts(static_pdf, "\n"); + xfree(buf.s); + pdf_end_obj(static_pdf); + } else { + pdf_begin_dict(static_pdf, k, 0); /* 0 = not an object stream candidate! */ + if (n == first_arg + 2) { /* write attr text */ + if (!lua_isstring(L, first_arg + 2)) + luaL_error(L, + "pdf.immediateobj() 3rd argument must be string"); + st3.s = lua_tolstring(L, first_arg + 2, &st3.l); + buf_to_pdfbuf_macro(static_pdf, st3.s, st3.l); + if (st3.s[st3.l - 1] != '\n') + pdf_puts(static_pdf, "\n"); + } + pdf_begin_stream(static_pdf); + if (st1.l == 6 && strncmp((const char *) st1.s, "stream", 6) == 0) { + buf_to_pdfbuf_macro(static_pdf, st2.s, st2.l); + } else if (st1.l == 10 + && strncmp((const char *) st1.s, "streamfile", + 10) == 0) { + buf.s = fread_to_buf(L, st2.s, &buf.l); + buf_to_pdfbuf_macro(static_pdf, buf.s, buf.l); + xfree(buf.s); + } else + luaL_error(L, "pdf.immediateobj() invalid argument"); + pdf_end_stream(static_pdf); + } + break; + default: + luaL_error(L, "pdf.immediateobj() allows max. 3 arguments"); + } + lua_pushinteger(L, k); return 1; } +/**********************************************************************/ +/* for LUA_ENVIRONINDEX table lookup (instead of repeated strcmp()) */ + +typedef enum { P__ZERO, + P_CATALOG, + P_H, + P_INFO, + P_NAMES, + P_PAGEATTRIBUTES, + P_PAGERESOURCES, + P_PAGESATTRIBUTES, + P_PDFCATALOG, + P_PDFINFO, + P_PDFNAMES, + P_PDFTRAILER, + P_RAW, + P_STREAM, + P_TRAILER, + P_V, + P__SENTINEL +} parm_idx; + +static const parm_struct pdf_parms[] = { + {NULL, P__ZERO}, /* dummy; lua indices run from 1 */ + {"catalog", P_CATALOG}, + {"h", P_H}, + {"info", P_INFO}, + {"names", P_NAMES}, + {"pageattributes", P_PAGEATTRIBUTES}, + {"pageresources", P_PAGERESOURCES}, + {"pagesattributes", P_PAGESATTRIBUTES}, + {"pdfcatalog", P_PDFCATALOG}, /* obsolescent */ + {"pdfinfo", P_PDFINFO}, /* obsolescent */ + {"pdfnames", P_PDFNAMES}, /* obsolescent */ + {"pdftrailer", P_PDFTRAILER}, /* obsolescent */ + {"raw", P_RAW}, + {"stream", P_STREAM}, + {"trailer", P_TRAILER}, + {"v", P_V}, + {NULL, P__SENTINEL} +}; + +/**********************************************************************/ + +static int table_obj(lua_State * L) +{ + int k, type; + int compress_level = -1; /* unset */ + int os_level = 1; /* default: put non-stream objects into object streams */ + int saved_compress_level = static_pdf->compress_level; + const_lstring attr, st; + lstring buf; + size_t i; + int immediate = 0; /* default: not immediate */ + attr.s = st.s = NULL; + attr.l = 0; + assert(lua_istable(L, 1)); /* t */ + + /* get object "type" */ + + lua_pushstring(L, "type"); /* ks t */ + lua_gettable(L, -2); /* vs? t */ + if (lua_isnil(L, -1)) /* !vs t */ + luaL_error(L, "pdf.obj(): object \"type\" missing"); + if (!lua_isstring(L, -1)) /* !vs t */ + luaL_error(L, "pdf.obj(): object \"type\" must be string"); + lua_pushvalue(L, -1); /* vs vs t */ + lua_gettable(L, LUA_ENVIRONINDEX); /* i? vs t */ + if (!lua_isnumber(L, -1)) /* !i vs t */ + luaL_error(L, "pdf.obj(): \"%s\" is not a valid object type", + lua_tostring(L, -2)); + type = (int) lua_tointeger(L, -1); /* i vs t */ + switch (type) { + case P_RAW: + case P_STREAM: + break; + default: + luaL_error(L, "pdf.obj(): \"%s\" is not a valid object type", lua_tostring(L, -2)); /* i vs t */ + } + lua_pop(L, 2); /* t */ + + /* get optional "immediate" */ + + lua_pushstring(L, "immediate"); /* ks t */ + lua_gettable(L, -2); /* b? t */ + if (!lua_isnil(L, -1)) { /* b? t */ + if (!lua_isboolean(L, -1)) /* !b t */ + luaL_error(L, "pdf.obj(): \"immediate\" must be boolean"); + immediate = lua_toboolean(L, -1); /* 0 or 1 */ + } + lua_pop(L, 1); /* t */ + + /* is a reserved object referenced by "objnum"? */ + + lua_pushstring(L, "objnum"); /* ks t */ + lua_gettable(L, -2); /* vi? t */ + if (!lua_isnil(L, -1)) { /* vi? t */ + if (!lua_isnumber(L, -1)) /* !vi t */ + luaL_error(L, "pdf.obj(): \"objnum\" must be integer"); + k = (int) lua_tointeger(L, -1); /* vi t */ + check_obj_exists(static_pdf, obj_type_obj, k); + if (is_obj_scheduled(static_pdf, k) || obj_data_ptr(static_pdf, k) != 0) + luaL_error(L, "pdf.obj() object in use"); + } else { + incr(static_pdf->obj_count); + pdf_create_obj(static_pdf, obj_type_obj, static_pdf->sys_obj_ptr + 1); + k = static_pdf->sys_obj_ptr; + } + pdf_last_obj = k; + if (immediate == 0) { + obj_data_ptr(static_pdf, k) = pdf_get_mem(static_pdf, pdfmem_obj_size); + init_obj_obj(static_pdf, k); + } + lua_pop(L, 1); /* t */ + + /* get optional "attr" (allowed only for stream case) */ + + lua_pushstring(L, "attr"); /* ks t */ + lua_gettable(L, -2); /* attr-s? t */ + if (!lua_isnil(L, -1)) { /* attr-s? t */ + if (type != P_STREAM) + luaL_error(L, + "pdf.obj(): \"attr\" key not allowed for non-stream object"); + if (!lua_isstring(L, -1)) /* !attr-s t */ + luaL_error(L, "pdf.obj(): object \"attr\" must be string"); + if (immediate == 1) { + attr.s = lua_tolstring(L, -1, &attr.l); /* attr-s t */ + lua_pop(L, 1); /* t */ + } else + obj_obj_stream_attr(static_pdf, k) = luaL_ref(Luas, LUA_REGISTRYINDEX); /* t */ + } else + lua_pop(L, 1); /* t */ + + /* get optional "compresslevel" (allowed only for stream case) */ + + lua_pushstring(L, "compresslevel"); /* ks t */ + lua_gettable(L, -2); /* vi? t */ + if (!lua_isnil(L, -1)) { /* vi? t */ + if (type == P_RAW) + luaL_error(L, + "pdf.obj(): \"compresslevel\" key not allowed for raw object"); + if (!lua_isnumber(L, -1)) /* !vi t */ + luaL_error(L, "pdf.obj(): \"compresslevel\" must be integer"); + compress_level = (int) lua_tointeger(L, -1); /* vi t */ + if (compress_level > 9) + luaL_error(L, "pdf.obj(): \"compresslevel\" must be <= 9"); + else if (compress_level < 0) + luaL_error(L, "pdf.obj(): \"compresslevel\" must be >= 0"); + if (immediate == 0) + obj_obj_pdfcompresslevel(static_pdf, k) = compress_level; + } + lua_pop(L, 1); /* t */ + + /* get optional "objcompression" (allowed only for non-stream case) */ + + lua_pushstring(L, "objcompression"); /* ks t */ + lua_gettable(L, -2); /* b? t */ + if (!lua_isnil(L, -1)) { /* b? t */ + if (type == P_STREAM) + luaL_error(L, + "pdf.obj(): \"objcompression\" key not allowed for stream object"); + if (!lua_isboolean(L, -1)) /* !b t */ + luaL_error(L, "pdf.obj(): \"objcompression\" must be boolean"); + os_level = lua_toboolean(L, -1); /* 0 or 1 */ + /* 0: never compress; 1: depends then on \pdfobjcompresslevel */ + if (immediate == 0) + obj_obj_pdfoslevel(static_pdf, k) = os_level; + } + lua_pop(L, 1); /* t */ + + /* now the object contents for all cases are handled */ + + lua_pushstring(L, "string"); /* ks t */ + lua_gettable(L, -2); /* string-s? t */ + lua_pushstring(L, "file"); /* ks string-s? t */ + lua_gettable(L, -3); /* file-s? string-s? t */ + if (!lua_isnil(L, -1) && !lua_isnil(L, -2)) /* file-s? string-s? t */ + luaL_error(L, + "pdf.obj(): \"string\" and \"file\" must not be given together"); + if (lua_isnil(L, -1) && lua_isnil(L, -2)) /* nil nil t */ + luaL_error(L, "pdf.obj(): no \"string\" or \"file\" given"); + + switch (type) { + case P_RAW: + if (immediate == 1) + pdf_begin_obj(static_pdf, k, os_level); + if (!lua_isnil(L, -2)) { /* file-s? string-s? t */ + /* from string */ + lua_pop(L, 1); /* string-s? t */ + if (!lua_isstring(L, -1)) /* !string-s t */ + luaL_error(L, + "pdf.obj(): \"string\" must be string for raw object"); + if (immediate == 1) { + st.s = lua_tolstring(L, -1, &st.l); + buf_to_pdfbuf_macro(static_pdf, st.s, st.l); + if (st.s[st.l - 1] != '\n') + pdf_puts(static_pdf, "\n"); + } else + obj_obj_data(static_pdf, k) = luaL_ref(L, LUA_REGISTRYINDEX); /* t */ + } else { + /* from file */ + if (!lua_isstring(L, -1)) /* !file-s nil t */ + luaL_error(L, + "pdf.obj(): \"file\" name must be string for raw object"); + if (immediate == 1) { + st.s = lua_tolstring(L, -1, &st.l); /* file-s nil t */ + buf.s = fread_to_buf(L, st.s, &buf.l); + buf_to_pdfbuf_macro(static_pdf, buf.s, buf.l); + if (buf.s[buf.l - 1] != '\n') + pdf_puts(static_pdf, "\n"); + xfree(buf.s); + } else { + set_obj_obj_is_file(static_pdf, k); + obj_obj_data(static_pdf, k) = luaL_ref(L, LUA_REGISTRYINDEX); /* nil t */ + } + } + if (immediate == 1) + pdf_end_obj(static_pdf); + break; + case P_STREAM: + if (immediate == 1) { + pdf_begin_dict(static_pdf, k, 0); /* 0 = not an object stream candidate! */ + if (attr.s != NULL) { + buf_to_pdfbuf_macro(static_pdf, attr.s, attr.l); + if (attr.s[attr.l - 1] != '\n') + pdf_puts(static_pdf, "\n"); + } + if (compress_level > -1) + static_pdf->compress_level = compress_level; + pdf_begin_stream(static_pdf); + } else { + set_obj_obj_is_stream(static_pdf, k); + if (compress_level > -1) + obj_obj_pdfcompresslevel(static_pdf, k) = compress_level; + } + if (!lua_isnil(L, -2)) { /* file-s? string-s? t */ + /* from string */ + lua_pop(L, 1); /* string-s? t */ + if (!lua_isstring(L, -1)) /* !string-s t */ + luaL_error(L, + "pdf.obj(): \"string\" must be string for stream object"); + if (immediate == 1) { + st.s = lua_tolstring(L, -1, &st.l); /* string-s t */ + buf_to_pdfbuf_macro(static_pdf, st.s, st.l); + } else + obj_obj_data(static_pdf, k) = luaL_ref(L, LUA_REGISTRYINDEX); /* t */ + } else { + /* from file */ + if (!lua_isstring(L, -1)) /* !file-s nil t */ + luaL_error(L, + "pdf.obj(): \"file\" name must be string for stream object"); + if (immediate == 1) { + st.s = lua_tolstring(L, -1, &st.l); /* file-s nil t */ + buf.s = fread_to_buf(L, st.s, &buf.l); + buf_to_pdfbuf_macro(static_pdf, buf.s, buf.l); + xfree(buf.s); + } else { + set_obj_obj_is_file(static_pdf, k); + obj_obj_data(static_pdf, k) = luaL_ref(L, LUA_REGISTRYINDEX); /* nil t */ + } + } + if (immediate == 1) + pdf_end_stream(static_pdf); + break; + default: + assert(0); + } + static_pdf->compress_level = saved_compress_level; + return k; +} + +static int orig_obj(lua_State * L) +{ + int n, first_arg = 1; + int k; + const_lstring st; + st.s = NULL; + n = lua_gettop(L); + if (n > 0 && lua_type(L, 1) == LUA_TNUMBER) { + first_arg++; + lua_number2int(k, lua_tonumber(L, 1)); + check_obj_exists(static_pdf, obj_type_obj, k); + if (is_obj_scheduled(static_pdf, k) || obj_data_ptr(static_pdf, k) != 0) + luaL_error(L, "pdf.obj() object in use"); + } else { + incr(static_pdf->obj_count); + pdf_create_obj(static_pdf, obj_type_obj, static_pdf->sys_obj_ptr + 1); + k = static_pdf->sys_obj_ptr; + } + pdf_last_obj = k; + obj_data_ptr(static_pdf, k) = pdf_get_mem(static_pdf, pdfmem_obj_size); + init_obj_obj(static_pdf, k); + switch (n - first_arg + 1) { + case 0: + luaL_error(L, "pdf.obj() needs at least one argument"); + break; + case 1: + if (!lua_isstring(L, first_arg)) + luaL_error(L, "pdf.obj() 1st argument must be string"); + break; + case 2: + case 3: + if (!lua_isstring(L, first_arg)) + luaL_error(L, "pdf.obj() 1st argument must be string"); + if (!lua_isstring(L, first_arg + 1)) + luaL_error(L, "pdf.obj() 2nd argument must be string"); + st.s = lua_tolstring(L, first_arg, &st.l); + if (st.l == 4 && strncmp((const char *) st.s, "file", 4) == 0) { + if (n == first_arg + 2) + luaL_error(L, "pdf.obj() 3rd argument forbidden in file mode"); + set_obj_obj_is_file(static_pdf, k); + } else { + if (n == first_arg + 2) { /* write attr text */ + if (!lua_isstring(L, -1)) + luaL_error(L, "pdf.obj() 3rd argument must be string"); + obj_obj_stream_attr(static_pdf, k) = + luaL_ref(Luas, LUA_REGISTRYINDEX); + } + if (st.l == 6 && strncmp((const char *) st.s, "stream", 6) == 0) { + set_obj_obj_is_stream(static_pdf, k); + } else if (st.l == 10 + && strncmp((const char *) st.s, "streamfile", 10) == 0) { + set_obj_obj_is_stream(static_pdf, k); + set_obj_obj_is_file(static_pdf, k); + } else + luaL_error(L, "pdf.obj() invalid argument"); + } + break; + default: + luaL_error(L, "pdf.obj() allows max. 3 arguments"); + } + obj_obj_data(static_pdf, k) = luaL_ref(L, LUA_REGISTRYINDEX); + return k; +} + +static int l_obj(lua_State * L) +{ + int n; + int k; + ensure_output_state(static_pdf, ST_HEADER_WRITTEN); + n = lua_gettop(L); + if (n == 1 && lua_istable(L, 1)) + k = table_obj(L); /* new */ + else + k = orig_obj(L); + lua_pushinteger(L, k); + return 1; +} + +static int l_reserveobj(lua_State * L) +{ + int n; + const_lstring st; + st.s = 0; + n = lua_gettop(L); + switch (n) { + case 0: + incr(static_pdf->obj_count); + pdf_create_obj(static_pdf, obj_type_obj, static_pdf->sys_obj_ptr + 1); + pdf_last_obj = static_pdf->sys_obj_ptr; + break; + case 1: + if (!lua_isstring(L, -1)) + luaL_error(L, "pdf.reserveobj() optional argument must be string"); + st.s = lua_tolstring(L, 1, &st.l); + if (st.l == 5 && strncmp((const char *) st.s, "annot", 5) == 0) { + pdf_create_obj(static_pdf, obj_type_annot, 0); + pdf_last_annot = static_pdf->sys_obj_ptr; + } else { + luaL_error(L, "pdf.reserveobj() optional string must be \"annot\""); + } + lua_pop(L, 1); + break; + default: + luaL_error(L, "pdf.reserveobj() allows max. 1 argument"); + } + lua_pushinteger(L, static_pdf->obj_ptr); + return 1; +} + +static int l_registerannot(lua_State * L) +{ + int n, i; + n = lua_gettop(L); + switch (n) { + case 1: + if (!is_shipping_page) + luaL_error(L, "pdf.registerannot() can only be used in late lua"); + i = (int) luaL_checkinteger(L, 1); + if (i <= 0) + luaL_error(L, + "pdf.registerannot() can only register positive object numbers"); + addto_page_resources(static_pdf, obj_type_annot, -i); + break; + default: + luaL_error(L, "pdf.registerannot() needs exactly 1 argument"); + } + return 0; +} + static int getpdf(lua_State * L) { + char *s; const char *st; - if (lua_isstring(L, 2)) { - st = lua_tostring(L, 2); - if (st && *st) { - if (*st == 'h') - return findcurh(L); - else if (*st == 'v') - return findcurv(L); + int i, l; + if (lua_isstring(L, 2) && (st = lua_tostring(L, 2)) != NULL) { + lua_pushvalue(L, 2); /* st ... */ + lua_gettable(L, LUA_ENVIRONINDEX); /* i? ... */ + if (lua_isnumber(L, -1)) { /* i ... */ + i = (int) lua_tointeger(L, -1); /* i ... */ + lua_pop(L, 1); /* ... */ + switch (i) { + case P_PAGEATTRIBUTES: + s = tokenlist_to_cstring(pdf_pageattributes_toks, true, &l); + lua_pushlstring(L, s, (size_t) l); + break; + case P_PAGERESOURCES: + s = tokenlist_to_cstring(pdf_pageresources_toks, true, &l); + lua_pushlstring(L, s, (size_t) l); + break; + case P_PAGESATTRIBUTES: + s = tokenlist_to_cstring(pdf_pagesattributes_toks, true, &l); + lua_pushlstring(L, s, (size_t) l); + break; + case P_PDFCATALOG: + case P_CATALOG: + s = tokenlist_to_cstring(pdf_catalog_toks, true, &l); + lua_pushlstring(L, s, (size_t) l); + break; + case P_PDFINFO: + case P_INFO: + s = tokenlist_to_cstring(pdf_info_toks, true, &l); + lua_pushlstring(L, s, (size_t) l); + break; + case P_PDFNAMES: + case P_NAMES: + s = tokenlist_to_cstring(pdf_names_toks, true, &l); + lua_pushlstring(L, s, (size_t) l); + break; + case P_PDFTRAILER: + case P_TRAILER: + s = tokenlist_to_cstring(pdf_trailer_toks, true, &l); + lua_pushlstring(L, s, (size_t) l); + break; + case P_H: + lua_pushnumber(L, static_pdf->posstruct->pos.h); + break; + case P_V: + lua_pushnumber(L, static_pdf->posstruct->pos.v); + break; + default: + lua_rawget(L, -2); + } + } else { + lua_pop(L, 1); /* ... */ + lua_rawget(L, -2); } + } else { + lua_pushnil(L); } - lua_pushnil(L); return 1; } static int setpdf(lua_State * L) { - return (L == NULL ? 0 : 0); /* for -Wall */ + int i; + if (lua_gettop(L) != 3) { + return 0; + } + (void) luaL_checkstring(L, 2); /* ... */ + lua_pushvalue(L, 2); /* st ... */ + lua_gettable(L, LUA_ENVIRONINDEX); /* i? ... */ + if (lua_isnumber(L, -1)) { /* i ... */ + i = (int) lua_tointeger(L, -1); /* i ... */ + lua_pop(L, 1); /* ... */ + switch (i) { + case P_PAGEATTRIBUTES: + pdf_pageattributes_toks = tokenlist_from_lua(L); + break; + case P_PAGERESOURCES: + pdf_pageresources_toks = tokenlist_from_lua(L); + break; + case P_PAGESATTRIBUTES: + pdf_pagesattributes_toks = tokenlist_from_lua(L); + break; + case P_PDFCATALOG: + case P_CATALOG: + pdf_catalog_toks = tokenlist_from_lua(L); + break; + case P_PDFINFO: + case P_INFO: + pdf_info_toks = tokenlist_from_lua(L); + break; + case P_PDFNAMES: + case P_NAMES: + pdf_names_toks = tokenlist_from_lua(L); + break; + case P_PDFTRAILER: + case P_TRAILER: + pdf_trailer_toks = tokenlist_from_lua(L); + break; + case P_H: + case P_V: + /* can't set |h| and |v| yet */ + default: + lua_rawset(L, -3); + } + } else { + lua_pop(L, 1); /* ... */ + lua_rawset(L, -3); + } + return 0; +} + +static int l_mapfile(lua_State * L) +{ + char *s; + const char *st; + if (lua_isstring(L, -1) && (st = lua_tostring(L, -1)) != NULL) { + s = xstrdup(st); + process_map_item(s, MAPFILE); + free(s); + } + return 0; +} + +static int l_mapline(lua_State * L) +{ + char *s; + const char *st; + if (lua_isstring(L, -1) && (st = lua_tostring(L, -1)) != NULL) { + s = xstrdup(st); + process_map_item(s, MAPLINE); + free(s); + } + return 0; +} + +static int l_pdfmapfile(lua_State * L) +{ + luaL_error(L, "pdf.pdfmapfile() is obsolete. Use pdf.mapfile() instead."); + return 0; +} + +static int l_pdfmapline(lua_State * L) +{ + luaL_error(L, "pdf.pdfmapline() is obsolete. Use pdf.mapline() instead."); + return 0; } static const struct luaL_reg pdflib[] = { - {"print", luapdfprint}, {"immediateobj", l_immediateobj}, + {"mapfile", l_mapfile}, + {"mapline", l_mapline}, + {"obj", l_obj}, + {"pdfmapfile", l_pdfmapfile}, /* obsolete */ + {"pdfmapline", l_pdfmapline}, /* obsolete */ + {"print", luapdfprint}, + {"registerannot", l_registerannot}, + {"reserveobj", l_reserveobj}, {NULL, NULL} /* sentinel */ }; +/**********************************************************************/ int luaopen_pdf(lua_State * L) { + preset_environment(L, pdf_parms); luaL_register(L, "pdf", pdflib); /* build meta table */ luaL_newmetatable(L, "pdf_meta"); lua_pushstring(L, "__index"); lua_pushcfunction(L, getpdf); /* do these later, NYI */ - if (0) { - lua_settable(L, -3); - lua_pushstring(L, "__newindex"); - lua_pushcfunction(L, setpdf); - } + lua_settable(L, -3); + lua_pushstring(L, "__newindex"); + lua_pushcfunction(L, setpdf); lua_settable(L, -3); lua_setmetatable(L, -2); /* meta to itself */ return 1; diff --git a/Build/source/texk/web2c/luatexdir/lua/lstatslib.c b/Build/source/texk/web2c/luatexdir/lua/lstatslib.c index 1f264cd55bb..4d233c43e4a 100644 --- a/Build/source/texk/web2c/luatexdir/lua/lstatslib.c +++ b/Build/source/texk/web2c/luatexdir/lua/lstatslib.c @@ -1,6 +1,6 @@ /* lstatslib.c - Copyright 2006-2008 Taco Hoekwater <taco@luatex.org> + Copyright 2006-2009 Taco Hoekwater <taco@luatex.org> This file is part of LuaTeX. @@ -17,13 +17,12 @@ You should have received a copy of the GNU General Public License along with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */ -#include "luatex-api.h" -#include <ptexlib.h> -#include "inc-extra.h" - - static const char _svn_version[] = - "$Id: lstatslib.c 2448 2009-06-08 07:43:50Z taco $ $URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.40.6/source/texk/web2c/luatexdir/lua/lstatslib.c $"; + "$Id: lstatslib.c 3477 2010-03-12 13:59:34Z taco $ " + "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/lua/lstatslib.c $"; + +#include "lua/luatex-api.h" +#include "ptexlib.h" typedef struct statistic { const char *name; @@ -32,48 +31,147 @@ typedef struct statistic { } statistic; typedef const char *(*charfunc) (void); -typedef integer(*intfunc) (void); +typedef lua_Number(*numfunc) (void); +typedef int (*intfunc) (void); static const char *getbanner(void) { - return ptexbanner; + return (const char *) ptexbanner; +} + +static const char *getlogname(void) +{ + return (const char *) texmf_log_name; +} + +static const char *get_pdftex_banner(void) +{ + return (const char *) pdftex_banner; +} + +static const char *get_output_file_name(void) +{ + if (static_pdf != NULL) + return (const char *) static_pdf->file_name; + return NULL; +} + +static const char *getfilename(void) +{ + int t = 0; + int level = in_open; + while ((level > 0)) { + t = input_stack[level--].name_field; + if (t >= STRING_OFFSET) + return (const char *) str_string(t); + } + return ""; +} + +static const char *getlasterror(void) +{ + return last_error; +} + +static const char *luatexrevision(void) +{ + return (const char *) (strrchr(luatex_version_string, '.') + 1); +} + +static lua_Number get_pdf_gone(void) +{ + if (static_pdf != NULL) + return (lua_Number) static_pdf->gone; + return (lua_Number) 0; } -/* hack, I really should implement the makecstring */ -static char *getfilename(void) +static lua_Number get_pdf_ptr(void) { - integer t; - t = get_current_name(); - if (t > (1 << 21)) - return makecstring(t); - else - return xstrdup(""); + if (static_pdf != NULL) + return (lua_Number) static_pdf->ptr; + return (lua_Number) 0; } -static char *getlasterror(void) +static lua_Number get_pdf_os_cntr(void) { - return makecstring(last_error); + if (static_pdf != NULL) + return (lua_Number) static_pdf->os_cntr; + return (lua_Number) 0; } -static char *luatexrevision(void) +static lua_Number get_pdf_os_objidx(void) { - return makecstring(get_luatexrevision()); + if (static_pdf != NULL) + return (lua_Number) static_pdf->os_idx; + return (lua_Number) 0; +} + +static lua_Number get_pdf_mem_size(void) +{ + if (static_pdf != NULL) + return (lua_Number) static_pdf->mem_size; + return (lua_Number) 0; +} + +static lua_Number get_pdf_mem_ptr(void) +{ + if (static_pdf != NULL) + return (lua_Number) static_pdf->mem_ptr; + return (lua_Number) 0; +} + + +static lua_Number get_obj_ptr(void) +{ + if (static_pdf != NULL) + return (lua_Number) static_pdf->obj_ptr; + return (lua_Number) 0; +} + +static lua_Number get_obj_tab_size(void) +{ + if (static_pdf != NULL) + return (lua_Number) static_pdf->obj_tab_size; + return (lua_Number) 0; +} + +static lua_Number get_dest_names_size(void) +{ + if (static_pdf != NULL) + return (lua_Number) static_pdf->dest_names_size; + return (lua_Number) 0; +} + +static lua_Number get_dest_names_ptr(void) +{ + if (static_pdf != NULL) + return (lua_Number) static_pdf->dest_names_ptr; + return (lua_Number) 0; +} + +static int get_hash_size(void) +{ + return hash_size; /* is a #define */ } static int luastate_max = 1; /* fixed value */ +/* temp, for backward compat */ +static int init_pool_ptr = 0; + static struct statistic stats[] = { - {"pdf_gone", 'g', &pdf_gone}, - {"pdf_ptr", 'g', &pdf_ptr}, + {"pdf_gone", 'N', &get_pdf_gone}, + {"pdf_ptr", 'N', &get_pdf_ptr}, {"dvi_gone", 'g', &dvi_offset}, {"dvi_ptr", 'g', &dvi_ptr}, {"total_pages", 'g', &total_pages}, - {"output_file_name", 's', &output_file_name}, - {"log_name", 's', &texmf_log_name}, /* weird */ - {"banner", 'S', &getbanner}, - {"pdftex_banner", 's', &pdftex_banner}, + {"output_file_name", 'S', (void *) &get_output_file_name}, + {"log_name", 'S', (void *) &getlogname}, + {"banner", 'S', (void *) &getbanner}, + {"pdftex_banner", 'S', (void *) &get_pdftex_banner}, + {"luatex_svn", 'G', &get_luatexsvn}, {"luatex_version", 'G', &get_luatexversion}, - {"luatex_revision", 'S', &luatexrevision}, + {"luatex_revision", 'S', (void *) &luatexrevision}, {"ini_version", 'b', &ini_version}, /* * mem stat @@ -86,7 +184,7 @@ static struct statistic stats[] = { {"str_ptr", 'g', &str_ptr}, {"init_str_ptr", 'g', &init_str_ptr}, {"max_strings", 'g', &max_strings}, - {"pool_ptr", 'g', &pool_ptr}, + {"pool_ptr", 'g', &pool_size}, {"init_pool_ptr", 'g', &init_pool_ptr}, {"pool_size", 'g', &pool_size}, {"var_mem_max", 'g', &var_mem_max}, @@ -109,21 +207,21 @@ static struct statistic stats[] = { {"buf_size", 'g', &buf_size}, {"save_size", 'g', &save_size}, /* pdf stats */ - {"obj_ptr", 'g', &obj_ptr}, - {"obj_tab_size", 'g', &obj_tab_size}, - {"pdf_os_cntr", 'g', &pdf_os_cntr}, - {"pdf_os_objidx", 'g', &pdf_os_objidx}, - {"pdf_dest_names_ptr", 'g', &pdf_dest_names_ptr}, - {"dest_names_size", 'g', &dest_names_size}, - {"pdf_mem_ptr", 'g', &pdf_mem_ptr}, - {"pdf_mem_size", 'g', &pdf_mem_size}, + {"obj_ptr", 'N', &get_obj_ptr}, + {"obj_tab_size", 'N', &get_obj_tab_size}, + {"pdf_os_cntr", 'N', &get_pdf_os_cntr}, + {"pdf_os_objidx", 'N', &get_pdf_os_objidx}, + {"pdf_dest_names_ptr", 'N', &get_dest_names_ptr}, + {"dest_names_size", 'N', &get_dest_names_size}, + {"pdf_mem_ptr", 'N', &get_pdf_mem_ptr}, + {"pdf_mem_size", 'N', &get_pdf_mem_size}, {"largest_used_mark", 'g', &biggest_used_mark}, - {"filename", 'S', &getfilename}, - {"inputid", 'G', &get_current_name}, + {"filename", 'S', (void *) &getfilename}, + {"inputid", 'g', &(iname)}, {"linenumber", 'g', &line}, - {"lasterrorstring", 'S', &getlasterror}, + {"lasterrorstring", 'S', (void *) &getlasterror}, {"luabytecodes", 'g', &luabytecode_max}, {"luabytecode_bytes", 'g', &luabytecode_bytes}, @@ -137,7 +235,6 @@ static struct statistic stats[] = { {NULL, 0, 0} }; - static int stats_name_to_id(const char *name) { int i; @@ -154,6 +251,7 @@ static int do_getstat(lua_State * L, int i) const char *st; charfunc f; intfunc g; + numfunc n; int str; t = stats[i].type; switch (t) { @@ -163,19 +261,25 @@ static int do_getstat(lua_State * L, int i) lua_pushstring(L, st); break; case 's': - str = *(integer *) (stats[i].value); + str = *(int *) (stats[i].value); if (str) { - lua_pushstring(L, makecstring(str)); + char *ss = makecstring(str); + lua_pushstring(L, ss); + free(ss); } else { lua_pushnil(L); } break; + case 'N': + n = stats[i].value; + lua_pushnumber(L, n()); + break; case 'G': g = stats[i].value; lua_pushnumber(L, g()); break; case 'g': - lua_pushnumber(L, *(integer *) (stats[i].value)); + lua_pushnumber(L, *(int *) (stats[i].value)); break; case 'B': g = stats[i].value; @@ -188,7 +292,7 @@ static int do_getstat(lua_State * L, int i) lua_pushnil(L); break; case 'b': - lua_pushboolean(L, *(integer *) (stats[i].value)); + lua_pushboolean(L, *(int *) (stats[i].value)); break; default: lua_pushnil(L); diff --git a/Build/source/texk/web2c/luatexdir/lua/ltexiolib.c b/Build/source/texk/web2c/luatexdir/lua/ltexiolib.c index 458b4e240bc..79f92f83d53 100644 --- a/Build/source/texk/web2c/luatexdir/lua/ltexiolib.c +++ b/Build/source/texk/web2c/luatexdir/lua/ltexiolib.c @@ -1,6 +1,6 @@ /* ltexiolib.c - Copyright 2006-2008 Taco Hoekwater <taco@luatex.org> + Copyright 2006-2010 Taco Hoekwater <taco@luatex.org> This file is part of LuaTeX. @@ -17,17 +17,17 @@ You should have received a copy of the GNU General Public License along with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */ -#include "luatex-api.h" -#include <ptexlib.h> +#include "lua/luatex-api.h" +#include "ptexlib.h" static const char _svn_version[] = - "$Id: ltexiolib.c 2321 2009-04-18 09:17:13Z hhenkel $ $URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.40.6/source/texk/web2c/luatexdir/lua/ltexiolib.c $"; + "$Id: ltexiolib.c 3550 2010-03-26 14:37:09Z taco $ $URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/lua/ltexiolib.c $"; -typedef void (*texio_printer) (str_number s); +typedef void (*texio_printer) (const char *); static char *loggable_info = NULL; -static boolean get_selector_value(lua_State * L, int i, char *l) +static boolean get_selector_value(lua_State * L, int i, int *l) { boolean r = false; if (lua_isstring(L, i)) { @@ -43,24 +43,19 @@ static boolean get_selector_value(lua_State * L, int i, char *l) r = true; } } else { - lua_pushstring(L, "first argument is not a string"); - lua_error(L); + luaL_error(L, "first argument is not a string"); } return r; } static int do_texio_print(lua_State * L, texio_printer printfunction) { - str_number texs; const char *s; - size_t k; int i = 1; - str_number u = 0; - char save_selector = selector; + int save_selector = selector; int n = lua_gettop(L); if (n == 0 || !lua_isstring(L, -1)) { - lua_pushstring(L, "no string to print"); - lua_error(L); + luaL_error(L, "no string to print"); } if (n > 1) { if (get_selector_value(L, i, &selector)) @@ -70,23 +65,15 @@ static int do_texio_print(lua_State * L, texio_printer printfunction) && selector != term_and_log) { normalize_selector(); /* sets selector */ } - /* just in case there is a string in progress */ - if (str_start[str_ptr - 0x200000] < pool_ptr) - u = make_string(); for (; i <= n; i++) { if (lua_isstring(L, i)) { - s = lua_tolstring(L, i, &k); - texs = maketexlstring(s, k); - printfunction(texs); - flush_str(texs); + s = lua_tostring(L, i); + printfunction(s); } else { - lua_pushstring(L, "argument is not a string"); - lua_error(L); + luaL_error(L, "argument is not a string"); } } selector = save_selector; - if (u != 0) - str_ptr--; return 0; } @@ -94,7 +81,7 @@ static void do_texio_ini_print(lua_State * L, const char *extra) { const char *s; int i = 1; - char l = term_and_log; + int l = term_and_log; int n = lua_gettop(L); if (n > 1) { if (get_selector_value(L, i, &l)) @@ -120,20 +107,20 @@ static void do_texio_ini_print(lua_State * L, const char *extra) static int texio_print(lua_State * L) { - if (ready_already != 314159 || pool_ptr == 0 || job_name == 0) { + if (ready_already != 314159 || job_name == 0) { do_texio_ini_print(L, ""); return 0; } - return do_texio_print(L, zprint); + return do_texio_print(L, tprint); } static int texio_printnl(lua_State * L) { - if (ready_already != 314159 || pool_ptr == 0 || job_name == 0) { + if (ready_already != 314159 || job_name == 0) { do_texio_ini_print(L, "\n"); return 0; } - return do_texio_print(L, zprint_nl); + return do_texio_print(L, tprint_nl); } /* at the point this function is called, the selector is log_only */ diff --git a/Build/source/texk/web2c/luatexdir/lua/ltexlib.c b/Build/source/texk/web2c/luatexdir/lua/ltexlib.c index 82a54cc35bc..fa0544a1853 100644 --- a/Build/source/texk/web2c/luatexdir/lua/ltexlib.c +++ b/Build/source/texk/web2c/luatexdir/lua/ltexlib.c @@ -1,6 +1,6 @@ /* ltexlib.c - Copyright 2006-2009 Taco Hoekwater <taco@luatex.org> + Copyright 2006-2010 Taco Hoekwater <taco@luatex.org> This file is part of LuaTeX. @@ -17,22 +17,29 @@ You should have received a copy of the GNU General Public License along with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */ -#include "luatex-api.h" -#include <ptexlib.h> -#include "nodes.h" -#include "inc-extra.h" -#include "commands.h" -#include "tokens.h" +#include "lua/luatex-api.h" +#include "ptexlib.h" + + static const char _svn_version[] = - "$Id: ltexlib.c 2448 2009-06-08 07:43:50Z taco $ $URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.40.6/source/texk/web2c/luatexdir/lua/ltexlib.c $"; + "$Id: ltexlib.c 3550 2010-03-26 14:37:09Z taco $ $URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/lua/ltexlib.c $"; + +#define attribute(A) eqtb[attribute_base+(A)].hh.rh +#define dimen(A) eqtb[scaled_base+(A)].hh.rh +#undef skip +#define skip(A) eqtb[skip_base+(A)].hh.rh +#define mu_skip(A) eqtb[mu_skip_base+(A)].hh.rh +#define count(A) eqtb[count_base+(A)].hh.rh +#define box(A) equiv(box_base+(A)) + typedef struct { char *text; unsigned int tsize; void *next; boolean partial; - integer cattable; + int cattable; } rope; typedef struct { @@ -51,20 +58,20 @@ static int spindle_size = 0; static spindle *spindles = NULL; static int spindle_index = 0; -static void luac_store(lua_State * L, int i, int partial, integer cattable) +static void luac_store(lua_State * L, int i, int partial, int cattable) { char *st; const char *sttemp; size_t tsize; rope *rn = NULL; sttemp = lua_tolstring(L, i, &tsize); - st = xmalloc((tsize + 1)); + st = xmalloc((unsigned) (tsize + 1)); memcpy(st, sttemp, (tsize + 1)); if (st) { luacstrings++; rn = (rope *) xmalloc(sizeof(rope)); rn->text = st; - rn->tsize = tsize; + rn->tsize = (unsigned) tsize; rn->partial = partial; rn->cattable = cattable; rn->next = NULL; @@ -83,12 +90,12 @@ static void luac_store(lua_State * L, int i, int partial, integer cattable) static int do_luacprint(lua_State * L, int partial, int deftable) { int i, n; - integer cattable = (integer) deftable; + int cattable = deftable; int startstrings = 1; n = lua_gettop(L); if (cattable != NO_CAT_TABLE) { if (lua_type(L, 1) == LUA_TNUMBER && n > 1) { - cattable = lua_tonumber(L, 1); + lua_number2int(cattable, lua_tonumber(L, 1)); startstrings = 2; } } @@ -105,8 +112,7 @@ static int do_luacprint(lua_State * L, int partial, int deftable) } else { for (i = startstrings; i <= n; i++) { if (!lua_isstring(L, i)) { - lua_pushstring(L, "no string to print"); - lua_error(L); + luaL_error(L, "no string to print"); } luac_store(L, i, partial, cattable); } @@ -114,24 +120,61 @@ static int do_luacprint(lua_State * L, int partial, int deftable) return 0; } -static int luacwrite(lua_State * L) +int luacwrite(lua_State * L) { return do_luacprint(L, FULL_LINE, NO_CAT_TABLE); } -static int luacprint(lua_State * L) +int luacprint(lua_State * L) { return do_luacprint(L, FULL_LINE, DEFAULT_CAT_TABLE); } -static int luacsprint(lua_State * L) +int luacsprint(lua_State * L) { return do_luacprint(L, PARTIAL_LINE, DEFAULT_CAT_TABLE); } -integer luacstring_cattable(void) +int luactprint(lua_State * L) { - return (integer) read_spindle.tail->cattable; + int i, j, n; + int cattable, startstrings; + n = lua_gettop(L); + for (i = 1; i <= n; i++) { + cattable = DEFAULT_CAT_TABLE; + startstrings = 1; + if (lua_type(L, i) != LUA_TTABLE) { + luaL_error(L, "no string to print"); + } + lua_pushvalue(L, i); /* push the table */ + lua_pushnumber(L, 1); + lua_gettable(L, -2); + if (lua_type(L, -1) == LUA_TNUMBER) { + lua_number2int(cattable, lua_tonumber(L, -1)); + startstrings = 2; + } + lua_pop(L, 1); + + for (j = startstrings;; j++) { + lua_pushnumber(L, j); + lua_gettable(L, -2); + if (lua_type(L, -1) == LUA_TSTRING) { + luac_store(L, -1, PARTIAL_LINE, cattable); + lua_pop(L, 1); + } else { + lua_pop(L, 1); + break; + } + } + lua_pop(L, 1); /* pop the table */ + } + return 0; +} + + +int luacstring_cattable(void) +{ + return (int) read_spindle.tail->cattable; } int luacstring_partial(void) @@ -164,11 +207,10 @@ int luacstring_input(void) /* put that thing in the buffer */ last = first; ret = last; - check_buffer_overflow(last + t->tsize); - /* make sure it fits in the pool as well (for show_token_list c.s) */ - check_pool_overflow(pool_ptr + t->tsize); + check_buffer_overflow(last + (int) t->tsize); + while (t->tsize-- > 0) - buffer[last++] = *st++; + buffer[last++] = (packed_ASCII_code) * st++; if (!t->partial) { while (last - 1 > ret && buffer[last - 1] == ' ') last--; @@ -190,7 +232,10 @@ void luacstring_start(int n) (void) n; /* for -W */ spindle_index++; if (spindle_size == spindle_index) { /* add a new one */ - spindles = xrealloc(spindles, sizeof(spindle) * (spindle_size + 1)); + spindles = + xrealloc(spindles, + (unsigned) (sizeof(spindle) * + (unsigned) (spindle_size + 1))); spindles[spindle_index].head = NULL; spindles[spindle_index].tail = NULL; spindles[spindle_index].complete = 0; @@ -222,70 +267,330 @@ void luacstring_close(int n) /* local (static) versions */ -#define width_offset 1 -#define depth_offset 2 -#define height_offset 3 - #define check_index_range(j,s) \ if (j<0 || j > 65535) { \ - lua_pushfstring(L, "incorrect index value %d for tex.%s()", (int)j, s); \ - lua_error(L); } + luaL_error(L, "incorrect index value %d for tex.%s()", (int)j, s); } + + +static const char *scan_integer_part(lua_State * L, const char *ss, int *ret, + int *radix_ret) +{ + boolean negative = false; /* should the answer be negated? */ + int m; /* |$2^{31}$ / radix|, the threshold of danger */ + int d; /* the digit just scanned */ + boolean vacuous; /* have no digits appeared? */ + boolean OK_so_far; /* has an error message been issued? */ + int radix = 0; /* the radix of the integer */ + int c = 0; /* the current character */ + const char *s; /* where we stopped in the string |ss| */ + integer cur_val = 0; /* return value */ + s = ss; + do { + do { + c = *s++; + } while (c && c == ' '); + if (c == '-') { + negative = !negative; + c = '+'; + } + } while (c == '+'); + + + radix = 10; + m = 214748364; + if (c == '\'') { + radix = 8; + m = 02000000000; + c = *s++; + } else if (c == '"') { + radix = 16; + m = 01000000000; + c = *s++; + } + vacuous = true; + cur_val = 0; + OK_so_far = true; + + /* Accumulate the constant until |cur_tok| is not a suitable digit */ + while (1) { + if ((c < '0' + radix) && (c >= '0') && (c <= '0' + 9)) { + d = c - '0'; + } else if (radix == 16) { + if ((c <= 'A' + 5) && (c >= 'A')) { + d = c - 'A' + 10; + } else if ((c <= 'a' + 5) && (c >= 'a')) { + d = c - 'a' + 10; + } else { + break; + } + } else { + break; + } + vacuous = false; + if ((cur_val >= m) && ((cur_val > m) || (d > 7) || (radix != 10))) { + if (OK_so_far) { + luaL_error(L, "Number too big"); + cur_val = infinity; + OK_so_far = false; + } + } else { + cur_val = cur_val * radix + d; + } + c = *s++; + } + if (vacuous) { + /* Express astonishment that no number was here */ + luaL_error(L, "Missing number, treated as zero"); + } + if (negative) + cur_val = -cur_val; + *ret = cur_val; + *radix_ret = radix; + if (c != ' ' && s > ss) + s--; + return s; +} + +#define set_conversion(A,B) do { num=(A); denom=(B); } while(0) + + +static const char *scan_dimen_part(lua_State * L, const char *ss, int *ret) +/* sets |cur_val| to a dimension */ +{ + boolean negative = false; /* should the answer be negated? */ + int f = 0; /* numerator of a fraction whose denominator is $2^{16}$ */ + int num, denom; /* conversion ratio for the scanned units */ + int k; /* number of digits in a decimal fraction */ + scaled v; /* an internal dimension */ + int save_cur_val; /* temporary storage of |cur_val| */ + int arith_error = false; + int c; /* the current character */ + const char *s = ss; /* where we are in the string */ + int radix = 0; /* the current radix */ + int rdig[18]; /* to save the |dig[]| array */ + int saved_tex_remainder; /* to save |tex_remainder| */ + int saved_arith_error; /* to save |arith_error| */ + int saved_cur_val; /* to save the global |cur_val| */ + saved_tex_remainder = tex_remainder; + saved_arith_error = arith_error; + saved_cur_val = cur_val; + /* Get the next non-blank non-sign... */ + do { + /* Get the next non-blank non-call token */ + do { + c = *s++; + } while (c && c == ' '); + if (c == '-') { + negative = !negative; + c = '+'; + } + } while (c == '+'); + if (c == ',') { + c = '.'; + } + if (c != '.') { + s = scan_integer_part(L, (s > ss ? (s - 1) : ss), &cur_val, &radix); + c = *s; + } else { + radix = 10; + cur_val = 0; + c = *(--s); + } + if (c == ',') + c = '.'; + if ((radix == 10) && (c == '.')) { + /* Scan decimal fraction */ + for (k = 0; k < 18; k++) + rdig[k] = dig[k]; + k = 0; + s++; /* get rid of the '.' */ + while (1) { + c = *s++; + if ((c > '0' + 9) || (c < '0')) + break; + if (k < 17) { /* digits for |k>=17| cannot affect the result */ + dig[k++] = c - '0'; + } + } + f = round_decimals(k); + if (c != ' ') + c = *(--s); + for (k = 0; k < 18; k++) + dig[k] = rdig[k]; + } + if (cur_val < 0) { /* in this case |f=0| */ + negative = !negative; + cur_val = -cur_val; + } + + /* Scan for (u)units that are internal dimensions; + |goto attach_sign| with |cur_val| set if found */ + save_cur_val = cur_val; + /* Get the next non-blank non-call... */ + do { + c = *s++; + } while (c && c == ' '); + if (c != ' ') + c = *(--s); + if (strncmp(s, "em", 2) == 0) { + s += 2; + v = (quad(get_cur_font())); + } else if (strncmp(s, "ex", 2) == 0) { + s += 2; + v = (x_height(get_cur_font())); + } else if (strncmp(s, "px", 2) == 0) { + s += 2; + v = dimen_par(pdf_px_dimen_code); + } else { + goto NOT_FOUND; + } + c = *s++; + if (c != ' ') { + c = *(--s); + } + cur_val = nx_plus_y(save_cur_val, v, xn_over_d(v, f, 0200000)); + goto ATTACH_SIGN; + NOT_FOUND: + + /* Scan for (m)\.{mu} units and |goto attach_fraction| */ + if (strncmp(s, "mu", 2) == 0) { + s += 2; + goto ATTACH_FRACTION; + } + if (strncmp(s, "true", 4) == 0) { + /* Adjust (f)for the magnification ratio */ + s += 4; + prepare_mag(); + if (int_par(mag_code) != 1000) { + cur_val = xn_over_d(cur_val, 1000, int_par(mag_code)); + f = (1000 * f + 0200000 * tex_remainder) / int_par(mag_code); + cur_val = cur_val + (f / 0200000); + f = f % 0200000; + } + do { + c = *s++; + } while (c && c == ' '); + c = *(--s); + } + if (strncmp(s, "pt", 2) == 0) { + s += 2; + goto ATTACH_FRACTION; /* the easy case */ + } + /* Scan for (a)all other units and adjust |cur_val| and |f| accordingly; + |goto done| in the case of scaled points */ + + if (strncmp(s, "in", 2) == 0) { + s += 2; + set_conversion(7227, 100); + } else if (strncmp(s, "pc", 2) == 0) { + s += 2; + set_conversion(12, 1); + } else if (strncmp(s, "cm", 2) == 0) { + s += 2; + set_conversion(7227, 254); + } else if (strncmp(s, "mm", 2) == 0) { + s += 2; + set_conversion(7227, 2540); + } else if (strncmp(s, "bp", 2) == 0) { + s += 2; + set_conversion(7227, 7200); + } else if (strncmp(s, "dd", 2) == 0) { + s += 2; + set_conversion(1238, 1157); + } else if (strncmp(s, "cc", 2) == 0) { + s += 2; + set_conversion(14856, 1157); + } else if (strncmp(s, "nd", 2) == 0) { + s += 2; + set_conversion(685, 642); + } else if (strncmp(s, "nc", 2) == 0) { + s += 2; + set_conversion(1370, 107); + } else if (strncmp(s, "sp", 2) == 0) { + s += 2; + goto DONE; + } else { + /* Complain about unknown unit and |goto done2| */ + luaL_error(L, "Illegal unit of measure (pt inserted)"); + goto DONE2; + } + cur_val = xn_over_d(cur_val, num, denom); + f = (num * f + 0200000 * tex_remainder) / denom; + cur_val = cur_val + (f / 0200000); + f = f % 0200000; + DONE2: + ATTACH_FRACTION: + if (cur_val >= 040000) + arith_error = true; + else + cur_val = cur_val * 65536 + f; + DONE: + /* Scan an optional space */ + c = *s++; + if (c != ' ') + s--; + ATTACH_SIGN: + if (arith_error || (abs(cur_val) >= 010000000000)) { + /* Report that this dimension is out of range */ + luaL_error(L, "Dimension too large"); + cur_val = max_dimen; + } + if (negative) + cur_val = -cur_val; + *ret = cur_val; + tex_remainder = saved_tex_remainder; + arith_error = saved_arith_error; + cur_val = saved_cur_val; + return s; +} int dimen_to_number(lua_State * L, const char *s) { - double v; - char *d; - int j; - v = strtod(s, &d); - if (strcmp(d, "in") == 0) { - j = (int) (((v * 7227) / 100) * 65536); - } else if (strcmp(d, "pc") == 0) { - j = (int) ((v * 12) * 65536); - } else if (strcmp(d, "cm") == 0) { - j = (int) (((v * 7227) / 254) * 65536); - } else if (strcmp(d, "mm") == 0) { - j = (int) (((v * 7227) / 2540) * 65536); - } else if (strcmp(d, "bp") == 0) { - j = (int) (((v * 7227) / 7200) * 65536); - } else if (strcmp(d, "dd") == 0) { - j = (int) (((v * 1238) / 1157) * 65536); - } else if (strcmp(d, "cc") == 0) { - j = (int) (((v * 14856) / 1157) * 65536); - } else if (strcmp(d, "nd") == 0) { - j = (int) (((v * 21681) / 20320) * 65536); - } else if (strcmp(d, "nc") == 0) { - j = (int) (((v * 65043) / 5080) * 65536); - } else if (strcmp(d, "pt") == 0) { - j = (int) (v * 65536); - } else if (strcmp(d, "sp") == 0) { - j = (int) (v); - } else { - lua_pushstring(L, "unknown dimension specifier"); - lua_error(L); + int j = 0; + const char *d = scan_dimen_part(L, s, &j); + if (*d) { + luaL_error(L, "conversion failed (trailing junk?)"); j = 0; } return j; } -static integer get_item_index(lua_State * L, int i, integer base) +static int tex_scaledimen(lua_State * L) +{ /* following vsetdimen() */ + int sp; + if (!lua_isnumber(L, 1)) { + if (lua_isstring(L, 1)) { + sp = dimen_to_number(L, lua_tostring(L, 1)); + } else { + luaL_error(L, "argument must be a string or a number"); + return 0; + } + } else { + lua_number2int(sp, lua_tonumber(L, 1)); + } + lua_pushnumber(L, sp); + return 1; +} + + +int get_item_index(lua_State * L, int i, int base) { size_t kk; - integer k; + int k; int cur_cs; const char *s; if (lua_type(L, i) == LUA_TSTRING) { s = lua_tolstring(L, i, &kk); cur_cs = string_lookup(s, kk); - if (cur_cs == static_undefined_control_sequence || - is_undefined_cs(cur_cs)) { + if (cur_cs == undefined_control_sequence || cur_cs == undefined_cs_cmd) { k = -1; /* guarandeed invalid */ } else { - k = (zget_equiv(cur_cs) - base); + k = (equiv(cur_cs) - base); } } else { - k = (integer) luaL_checkinteger(L, i); + k = (int) luaL_checkinteger(L, i); } return k; } @@ -294,28 +599,28 @@ static integer get_item_index(lua_State * L, int i, integer base) static int vsetdimen(lua_State * L, int is_global) { int i, j, err; - integer k; - integer save_global_defs = int_par(param_global_defs_code); + int k; + int save_global_defs = int_par(global_defs_code); if (is_global) - int_par(param_global_defs_code) = 1; + int_par(global_defs_code) = 1; i = lua_gettop(L); j = 0; /* find the value */ - if (!lua_isnumber(L, i)) + if (!lua_isnumber(L, i)) { if (lua_isstring(L, i)) { j = dimen_to_number(L, lua_tostring(L, i)); } else { - lua_pushstring(L, "unsupported value type"); - lua_error(L); - } else - j = (int) lua_tonumber(L, i); - k = get_item_index(L, (i - 1), get_scaled_base()); + luaL_error(L, "unsupported value type"); + } + } else { + lua_number2int(j, lua_tonumber(L, i)); + } + k = get_item_index(L, (i - 1), scaled_base); check_index_range(k, "setdimen"); err = set_tex_dimen_register(k, j); - int_par(param_global_defs_code) = save_global_defs; + int_par(global_defs_code) = save_global_defs; if (err) { - lua_pushstring(L, "incorrect value"); - lua_error(L); + luaL_error(L, "incorrect value"); } return 0; } @@ -335,8 +640,8 @@ static int setdimen(lua_State * L) static int getdimen(lua_State * L) { int j; - integer k; - k = get_item_index(L, lua_gettop(L), get_scaled_base()); + int k; + k = get_item_index(L, lua_gettop(L), scaled_base); check_index_range(k, "getdimen"); j = get_tex_dimen_register(k); lua_pushnumber(L, j); @@ -347,19 +652,18 @@ static int vsetskip(lua_State * L, int is_global) { int i, err; halfword *j; - integer k; - integer save_global_defs = int_par(param_global_defs_code); + int k; + int save_global_defs = int_par(global_defs_code); if (is_global) - int_par(param_global_defs_code) = 1; + int_par(global_defs_code) = 1; i = lua_gettop(L); j = check_isnode(L, i); /* the value */ - k = get_item_index(L, (i - 1), get_skip_base()); + k = get_item_index(L, (i - 1), skip_base); check_index_range(k, "setskip"); /* the index */ err = set_tex_skip_register(k, *j); - int_par(param_global_defs_code) = save_global_defs; + int_par(global_defs_code) = save_global_defs; if (err) { - lua_pushstring(L, "incorrect value"); - lua_error(L); + luaL_error(L, "incorrect value"); } return 0; } @@ -376,11 +680,11 @@ static int setskip(lua_State * L) return vsetskip(L, isglobal); } -static int getskip(lua_State * L) +int getskip(lua_State * L) { halfword j; - integer k; - k = get_item_index(L, lua_gettop(L), get_skip_base()); + int k; + k = get_item_index(L, lua_gettop(L), skip_base); check_index_range(k, "getskip"); j = get_tex_skip_register(k); lua_nodelib_push_fast(L, j); @@ -392,19 +696,18 @@ static int getskip(lua_State * L) static int vsetcount(lua_State * L, int is_global) { int i, j, err; - integer k; - integer save_global_defs = int_par(param_global_defs_code); + int k; + int save_global_defs = int_par(global_defs_code); if (is_global) - int_par(param_global_defs_code) = 1; + int_par(global_defs_code) = 1; i = lua_gettop(L); j = (int) luaL_checkinteger(L, i); - k = get_item_index(L, (i - 1), get_count_base()); + k = get_item_index(L, (i - 1), count_base); check_index_range(k, "setcount"); err = set_tex_count_register(k, j); - int_par(param_global_defs_code) = save_global_defs; + int_par(global_defs_code) = save_global_defs; if (err) { - lua_pushstring(L, "incorrect value"); - lua_error(L); + luaL_error(L, "incorrect value"); } return 0; } @@ -424,8 +727,8 @@ static int setcount(lua_State * L) static int getcount(lua_State * L) { int j; - integer k; - k = get_item_index(L, lua_gettop(L), get_count_base()); + int k; + k = get_item_index(L, lua_gettop(L), count_base); check_index_range(k, "getcount"); j = get_tex_count_register(k); lua_pushnumber(L, j); @@ -436,19 +739,18 @@ static int getcount(lua_State * L) static int vsetattribute(lua_State * L, int is_global) { int i, j, err; - integer k; - integer save_global_defs = int_par(param_global_defs_code); + int k; + int save_global_defs = int_par(global_defs_code); if (is_global) - int_par(param_global_defs_code) = 1; + int_par(global_defs_code) = 1; i = lua_gettop(L); j = (int) luaL_checkinteger(L, i); - k = get_item_index(L, (i - 1), get_attribute_base()); + k = get_item_index(L, (i - 1), attribute_base); check_index_range(k, "setattribute"); err = set_tex_attribute_register(k, j); - int_par(param_global_defs_code) = save_global_defs; + int_par(global_defs_code) = save_global_defs; if (err) { - lua_pushstring(L, "incorrect value"); - lua_error(L); + luaL_error(L, "incorrect value"); } return 0; } @@ -468,38 +770,34 @@ static int setattribute(lua_State * L) static int getattribute(lua_State * L) { int j; - integer k; - k = get_item_index(L, lua_gettop(L), get_attribute_base()); + int k; + k = get_item_index(L, lua_gettop(L), attribute_base); check_index_range(k, "getattribute"); j = get_tex_attribute_register(k); lua_pushnumber(L, j); return 1; } -static int vsettoks(lua_State * L, int is_global) +int vsettoks(lua_State * L, int is_global) { - int i, j, err; - size_t len; - integer k; - const char *st; - integer save_global_defs = int_par(param_global_defs_code); + int i, err; + int k; + lstring str; + int save_global_defs = int_par(global_defs_code); if (is_global) - int_par(param_global_defs_code) = 1; + int_par(global_defs_code) = 1; i = lua_gettop(L); if (!lua_isstring(L, i)) { - lua_pushstring(L, "unsupported value type"); - lua_error(L); + luaL_error(L, "unsupported value type"); } - st = lua_tolstring(L, i, &len); - k = get_item_index(L, (i - 1), get_toks_base()); + str.s = (unsigned char *) xstrdup(lua_tolstring(L, i, &str.l)); + k = get_item_index(L, (i - 1), toks_base); check_index_range(k, "settoks"); - j = maketexlstring(st, len); - err = zset_tex_toks_register(k, j); - int_par(param_global_defs_code) = save_global_defs; + err = set_tex_toks_register(k, str); + xfree(str.s); + int_par(global_defs_code) = save_global_defs; if (err) { - flush_str(j); - lua_pushstring(L, "incorrect value"); - lua_error(L); + luaL_error(L, "incorrect value"); } return 0; } @@ -518,12 +816,15 @@ static int settoks(lua_State * L) static int gettoks(lua_State * L) { - integer k; + int k; str_number t; - k = get_item_index(L, lua_gettop(L), get_toks_base()); + char *ss; + k = get_item_index(L, lua_gettop(L), toks_base); check_index_range(k, "gettoks"); t = get_tex_toks_register(k); - lua_pushstring(L, makecstring(t)); + ss = makecstring(t); + lua_pushstring(L, ss); + free(ss); flush_str(t); return 1; } @@ -531,19 +832,19 @@ static int gettoks(lua_State * L) static int get_box_id(lua_State * L, int i) { const char *s; - integer cur_cs, cur_cmd; + int cur_cs, cur_cmd; size_t k = 0; int j = -1; if (lua_type(L, i) == LUA_TSTRING) { s = lua_tolstring(L, i, &k); cur_cs = string_lookup(s, k); - cur_cmd = zget_eq_type(cur_cs); + cur_cmd = eq_type(cur_cs); if (cur_cmd == char_given_cmd || cur_cmd == math_given_cmd || cur_cmd == omath_given_cmd) { - j = zget_equiv(cur_cs); + j = equiv(cur_cs); } } else { - j = (int) lua_tonumber(L, (i)); + lua_number2int(j, lua_tonumber(L, (i))); } return j; } @@ -561,9 +862,9 @@ static int getbox(lua_State * L) static int vsetbox(lua_State * L, int is_global) { int i, j, k, err; - integer save_global_defs = int_par(param_global_defs_code); + int save_global_defs = int_par(global_defs_code); if (is_global) - int_par(param_global_defs_code) = 1; + int_par(global_defs_code) = 1; k = get_box_id(L, -2); check_index_range(k, "setbox"); i = get_tex_box_register(k); @@ -575,12 +876,17 @@ static int vsetbox(lua_State * L, int is_global) return 0; } else { j = nodelist_from_lua(L); + if (j != null && type(j) != hlist_node && type(j) != vlist_node) { + luaL_error(L, "setbox: incompatible node type (%s)\n", + get_node_name(type(j), subtype(j))); + return 0; + } + } err = set_tex_box_register(k, j); - int_par(param_global_defs_code) = save_global_defs; + int_par(global_defs_code) = save_global_defs; if (err) { - lua_pushstring(L, "incorrect value"); - lua_error(L); + luaL_error(L, "incorrect value"); } return 0; } @@ -604,8 +910,7 @@ static int getboxdim(lua_State * L, int whichdim) j = get_box_id(L, i); lua_settop(L, (i - 2)); /* table at -1 */ if (j < 0 || j > 65535) { - lua_pushstring(L, "incorrect index"); - lua_error(L); + luaL_error(L, "incorrect index"); } switch (whichdim) { case width_offset: @@ -620,17 +925,17 @@ static int getboxdim(lua_State * L, int whichdim) return 1; } -static int getboxwd(lua_State * L) +int getboxwd(lua_State * L) { return getboxdim(L, width_offset); } -static int getboxht(lua_State * L) +int getboxht(lua_State * L) { return getboxdim(L, height_offset); } -static int getboxdp(lua_State * L) +int getboxdp(lua_State * L) { return getboxdim(L, depth_offset); } @@ -638,20 +943,19 @@ static int getboxdp(lua_State * L) static int vsetboxdim(lua_State * L, int whichdim, int is_global) { int i, j, k, err; - integer save_global_defs = int_par(param_global_defs_code); + int save_global_defs = int_par(global_defs_code); if (is_global) - int_par(param_global_defs_code) = 1; + int_par(global_defs_code) = 1; i = lua_gettop(L); if (!lua_isnumber(L, i)) { j = dimen_to_number(L, lua_tostring(L, i)); } else { - j = (int) lua_tonumber(L, i); + lua_number2int(j, lua_tonumber(L, i)); } k = get_box_id(L, (i - 1)); lua_settop(L, (i - 3)); /* table at -2 */ if (k < 0 || k > 65535) { - lua_pushstring(L, "incorrect index"); - lua_error(L); + luaL_error(L, "incorrect index"); } err = 0; switch (whichdim) { @@ -664,10 +968,9 @@ static int vsetboxdim(lua_State * L, int whichdim, int is_global) case depth_offset: err = set_tex_box_depth(k, j); } - int_par(param_global_defs_code) = save_global_defs; + int_par(global_defs_code) = save_global_defs; if (err) { - lua_pushstring(L, "not a box"); - lua_error(L); + luaL_error(L, "not a box"); } return 0; } @@ -708,7 +1011,7 @@ static int setboxdp(lua_State * L) return vsetboxdim(L, depth_offset, isglobal); } -static int settex(lua_State * L) +int settex(lua_State * L) { const char *st; int i, j, texstr; @@ -728,94 +1031,84 @@ static int settex(lua_State * L) } cur_cs = string_lookup(st, k); flush_str(texstr); - cur_cmd = zget_eq_type(cur_cs); + cur_cmd = eq_type(cur_cs); if (is_int_assign(cur_cmd)) { if (lua_isnumber(L, i)) { + int luai; + lua_number2int(luai, lua_tonumber(L, i)); assign_internal_value((isglobal ? 4 : 0), - zget_equiv(cur_cs), lua_tonumber(L, - i)); + equiv(cur_cs), luai); } else { - lua_pushstring(L, "unsupported value type"); - lua_error(L); + luaL_error(L, "unsupported value type"); } } else if (is_dim_assign(cur_cmd)) { if (!lua_isnumber(L, i)) { if (lua_isstring(L, i)) { j = dimen_to_number(L, lua_tostring(L, i)); } else { - lua_pushstring(L, "unsupported value type"); - lua_error(L); + luaL_error(L, "unsupported value type"); } } else { - j = (int) lua_tonumber(L, i); + lua_number2int(j, lua_tonumber(L, i)); } - assign_internal_value((isglobal ? 4 : 0), zget_equiv(cur_cs), - j); + assign_internal_value((isglobal ? 4 : 0), equiv(cur_cs), j); + } else if (is_toks_assign(cur_cmd)) { + if (lua_isstring(L, i)) { + j = tokenlist_from_lua(L); /* uses stack -1 */ + assign_internal_value((isglobal ? 4 : 0), equiv(cur_cs), j); + + } else { + luaL_error(L, "unsupported value type"); + } + } else { - lua_pushstring(L, "unsupported tex internal assignment"); - lua_error(L); + luaL_error(L, "unsupported tex internal assignment"); } } else { - lua_rawset(L, (i - 2)); + if (lua_istable(L, (i - 2))) + lua_rawset(L, (i - 2)); } } else { - lua_rawset(L, (i - 2)); + if (lua_istable(L, (i - 2))) + lua_rawset(L, (i - 2)); } return 0; } -#if 0 /* unused */ -static char *get_something_internal(int cur_cmd, int cur_code) -{ - int texstr; - char *str; - int save_cur_val, save_cur_val_level; - save_cur_val = cur_val; - save_cur_val_level = cur_val_level; - zscan_something_simple(cur_cmd, cur_code); - texstr = the_scanned_result(); - cur_val = save_cur_val; - cur_val_level = save_cur_val_level; - str = makecstring(texstr); - flush_str(texstr); - return str; -} -#endif - -static int do_convert(lua_State * L, int cur_code) +int do_convert(lua_State * L, int cur_code) { int texstr; - integer i = -1; + int i = -1; char *str = NULL; switch (cur_code) { - case convert_pdf_creation_date_code: /* ? */ - case convert_pdf_insert_ht_code: /* arg <register int> */ - case convert_pdf_ximage_bbox_code: /* arg 2 ints */ - case convert_lua_code: /* arg complex */ - case convert_lua_escape_string_code: /* arg token list */ - case convert_pdf_colorstack_init_code: /* arg complex */ - case convert_left_margin_kern_code: /* arg box */ - case convert_right_margin_kern_code: /* arg box */ + case pdf_creation_date_code: /* ? */ + case pdf_insert_ht_code: /* arg <register int> */ + case pdf_ximage_bbox_code: /* arg 2 ints */ + case lua_code: /* arg complex */ + case lua_escape_string_code: /* arg token list */ + case pdf_colorstack_init_code: /* arg complex */ + case left_margin_kern_code: /* arg box */ + case right_margin_kern_code: /* arg box */ break; - case convert_string_code: /* arg token */ - case convert_meaning_code: /* arg token */ + case string_code: /* arg token */ + case meaning_code: /* arg token */ break; /* the next fall through, and come from 'official' indices! */ - case convert_font_name_code: /* arg fontid */ - case convert_font_identifier_code: /* arg fontid */ - case convert_pdf_font_name_code: /* arg fontid */ - case convert_pdf_font_objnum_code: /* arg fontid */ - case convert_pdf_font_size_code: /* arg fontid */ - case convert_uniform_deviate_code: /* arg int */ - case convert_number_code: /* arg int */ - case convert_roman_numeral_code: /* arg int */ - case convert_pdf_page_ref_code: /* arg int */ - case convert_pdf_xform_name_code: /* arg int */ + case font_name_code: /* arg fontid */ + case font_identifier_code: /* arg fontid */ + case pdf_font_name_code: /* arg fontid */ + case pdf_font_objnum_code: /* arg fontid */ + case pdf_font_size_code: /* arg fontid */ + case uniform_deviate_code: /* arg int */ + case number_code: /* arg int */ + case roman_numeral_code: /* arg int */ + case pdf_page_ref_code: /* arg int */ + case pdf_xform_name_code: /* arg int */ if (lua_gettop(L) < 1) { /* error */ } - i = lua_tonumber(L, 1); /* these fall through! */ + lua_number2int(i, lua_tonumber(L, 1)); /* these fall through! */ default: texstr = the_convert_string(cur_code, i); if (texstr) { @@ -823,22 +1116,24 @@ static int do_convert(lua_State * L, int cur_code) flush_str(texstr); } } - if (str) + if (str) { lua_pushstring(L, str); - else + free(str); + } else { lua_pushnil(L); + } return 1; } -static int do_scan_internal(lua_State * L, int cur_cmd, int cur_code) +int do_scan_internal(lua_State * L, int cur_cmd, int cur_code) { int texstr; char *str = NULL; int save_cur_val, save_cur_val_level; save_cur_val = cur_val; save_cur_val_level = cur_val_level; - zscan_something_simple(cur_cmd, cur_code); + scan_something_simple(cur_cmd, cur_code); if (cur_val_level == int_val_level || cur_val_level == dimen_val_level || cur_val_level == attr_val_level) { @@ -848,10 +1143,12 @@ static int do_scan_internal(lua_State * L, int cur_cmd, int cur_code) } else { /* dir_val_level, mu_val_level, tok_val_level */ texstr = the_scanned_result(); str = makecstring(texstr); - if (str) + if (str) { lua_pushstring(L, str); - else + free(str); + } else { lua_pushnil(L); + } flush_str(texstr); } cur_val = save_cur_val; @@ -859,74 +1156,74 @@ static int do_scan_internal(lua_State * L, int cur_cmd, int cur_code) return 1; } -static int do_lastitem(lua_State * L, int cur_code) +int do_lastitem(lua_State * L, int cur_code) { int retval = 1; switch (cur_code) { /* the next two do not actually exist */ - case last_item_lastattr_code: - case last_item_attrexpr_code: + case lastattr_code: + case attrexpr_code: lua_pushnil(L); break; /* the expressions do something complicated with arguments, yuck */ - case last_item_numexpr_code: - case last_item_dimexpr_code: - case last_item_glueexpr_code: - case last_item_muexpr_code: + case numexpr_code: + case dimexpr_code: + case glueexpr_code: + case muexpr_code: lua_pushnil(L); break; /* these read a glue or muglue, todo */ - case last_item_mu_to_glue_code: - case last_item_glue_to_mu_code: - case last_item_glue_stretch_order_code: - case last_item_glue_shrink_order_code: - case last_item_glue_stretch_code: - case last_item_glue_shrink_code: + case mu_to_glue_code: + case glue_to_mu_code: + case glue_stretch_order_code: + case glue_shrink_order_code: + case glue_stretch_code: + case glue_shrink_code: lua_pushnil(L); break; /* these read a fontid and a char, todo */ - case last_item_font_char_wd_code: - case last_item_font_char_ht_code: - case last_item_font_char_dp_code: - case last_item_font_char_ic_code: + case font_char_wd_code: + case font_char_ht_code: + case font_char_dp_code: + case font_char_ic_code: lua_pushnil(L); break; /* these read an integer, todo */ - case last_item_par_shape_length_code: - case last_item_par_shape_indent_code: - case last_item_par_shape_dimen_code: + case par_shape_length_code: + case par_shape_indent_code: + case par_shape_dimen_code: lua_pushnil(L); break; - case last_item_lastpenalty_code: - case last_item_lastkern_code: - case last_item_lastskip_code: - case last_item_last_node_type_code: - case last_item_input_line_no_code: - case last_item_badness_code: - case last_item_pdftex_version_code: - case last_item_pdf_last_obj_code: - case last_item_pdf_last_xform_code: - case last_item_pdf_last_ximage_code: - case last_item_pdf_last_ximage_pages_code: - case last_item_pdf_last_annot_code: - case last_item_pdf_last_x_pos_code: - case last_item_pdf_last_y_pos_code: - case last_item_pdf_retval_code: - case last_item_pdf_last_ximage_colordepth_code: - case last_item_random_seed_code: - case last_item_pdf_last_link_code: - case last_item_luatex_version_code: - case last_item_Aleph_version_code: - case last_item_Omega_version_code: - case last_item_Aleph_minor_version_code: - case last_item_Omega_minor_version_code: - case last_item_eTeX_minor_version_code: - case last_item_eTeX_version_code: - case last_item_current_group_level_code: - case last_item_current_group_type_code: - case last_item_current_if_level_code: - case last_item_current_if_type_code: - case last_item_current_if_branch_code: + case lastpenalty_code: + case lastkern_code: + case lastskip_code: + case last_node_type_code: + case input_line_no_code: + case badness_code: + case pdftex_version_code: + case pdf_last_obj_code: + case pdf_last_xform_code: + case pdf_last_ximage_code: + case pdf_last_ximage_pages_code: + case pdf_last_annot_code: + case pdf_last_x_pos_code: + case pdf_last_y_pos_code: + case pdf_retval_code: + case pdf_last_ximage_colordepth_code: + case random_seed_code: + case pdf_last_link_code: + case luatex_version_code: + case Aleph_version_code: + case Omega_version_code: + case Aleph_minor_version_code: + case Omega_minor_version_code: + case eTeX_minor_version_code: + case eTeX_version_code: + case current_group_level_code: + case current_group_type_code: + case current_if_level_code: + case current_if_type_code: + case current_if_branch_code: retval = do_scan_internal(L, last_item_cmd, cur_code); break; default: @@ -939,7 +1236,7 @@ static int do_lastitem(lua_State * L, int cur_code) static int tex_setmathparm(lua_State * L) { int i, j; - scaled k; + int k; int n; int l = cur_level; n = lua_gettop(L); @@ -952,8 +1249,8 @@ static int tex_setmathparm(lua_State * L) } i = luaL_checkoption(L, (n - 2), NULL, math_param_names); j = luaL_checkoption(L, (n - 1), NULL, math_style_names); - k = (scaled) lua_tonumber(L, n); - def_math_param(i, j, k, l); + lua_number2int(k, lua_tonumber(L, n)); + def_math_param(i, j, (scaled) k, l); } return 0; } @@ -973,59 +1270,59 @@ static int tex_getmathparm(lua_State * L) static int getfontname(lua_State * L) { - return do_convert(L, convert_font_name_code); + return do_convert(L, font_name_code); } static int getfontidentifier(lua_State * L) { - return do_convert(L, convert_font_identifier_code); + return do_convert(L, font_identifier_code); } static int getpdffontname(lua_State * L) { - return do_convert(L, convert_pdf_font_name_code); + return do_convert(L, pdf_font_name_code); } static int getpdffontobjnum(lua_State * L) { - return do_convert(L, convert_pdf_font_objnum_code); + return do_convert(L, pdf_font_objnum_code); } static int getpdffontsize(lua_State * L) { - return do_convert(L, convert_pdf_font_size_code); + return do_convert(L, pdf_font_size_code); } static int getuniformdeviate(lua_State * L) { - return do_convert(L, convert_uniform_deviate_code); + return do_convert(L, uniform_deviate_code); } static int getnumber(lua_State * L) { - return do_convert(L, convert_number_code); + return do_convert(L, number_code); } static int getromannumeral(lua_State * L) { - return do_convert(L, convert_roman_numeral_code); + return do_convert(L, roman_numeral_code); } static int getpdfpageref(lua_State * L) { - return do_convert(L, convert_pdf_page_ref_code); + return do_convert(L, pdf_page_ref_code); } static int getpdfxformname(lua_State * L) { - return do_convert(L, convert_pdf_xform_name_code); + return do_convert(L, pdf_xform_name_code); } -static int get_parshape(lua_State * L) +int get_parshape(lua_State * L) { int n; - halfword par_shape_ptr = get_par_shape_ptr(); + halfword par_shape_ptr = equiv(par_shape_loc); if (par_shape_ptr != 0) { int m = 1; n = vinfo(par_shape_ptr + 1); @@ -1046,7 +1343,7 @@ static int get_parshape(lua_State * L) } -static int gettex(lua_State * L) +int gettex(lua_State * L) { int cur_cs = -1; int retval = 1; /* default is to return nil */ @@ -1100,7 +1397,7 @@ static int gettex(lua_State * L) } -static int getlist(lua_State * L) +int getlist(lua_State * L) { const char *str; if (lua_isstring(L, 2)) { @@ -1148,7 +1445,7 @@ static int getlist(lua_State * L) return 1; } -static int setlist(lua_State * L) +int setlist(lua_State * L) { halfword *n_ptr; const char *str; @@ -1156,9 +1453,9 @@ static int setlist(lua_State * L) if (lua_isstring(L, 2)) { str = lua_tostring(L, 2); if (strcmp(str, "best_size") == 0) { - best_size = lua_tointeger(L, 3); + best_size = (int) lua_tointeger(L, 3); } else if (strcmp(str, "least_page_cost") == 0) { - least_page_cost = lua_tointeger(L, 3); + least_page_cost = (int) lua_tointeger(L, 3); } else { if (!lua_isnil(L, 3)) { n_ptr = check_isnode(L, 3); @@ -1176,10 +1473,7 @@ static int setlist(lua_State * L) } else if (strcmp(str, "contrib_head") == 0) { vlink(contrib_head) = n; if (n == 0) { - if (nest_ptr == 0) - cur_list.tail_field = contrib_head; /* vertical mode */ - else - nest[0].tail_field = contrib_head; /* other modes */ + contrib_tail = contrib_head; } } else if (strcmp(str, "best_page_break") == 0) { best_page_break = n; @@ -1204,11 +1498,142 @@ static int setlist(lua_State * L) return 0; } -#define infinity 2147483647 +#define NEST_METATABLE "luatex.nest" + +static int lua_nest_getfield(lua_State * L) +{ + list_state_record *r, **rv = lua_touserdata(L, -2); + const char *field = lua_tostring(L, -1); + r = *rv; + if (strcmp(field, "mode") == 0) { + lua_pushnumber(L, r->mode_field); + } else if (strcmp(field, "head") == 0) { + lua_nodelib_push_fast(L, r->head_field); + } else if (strcmp(field, "tail") == 0) { + lua_nodelib_push_fast(L, r->tail_field); + } else if (strcmp(field, "delimptr") == 0) { + lua_pushnumber(L, r->eTeX_aux_field); + lua_nodelib_push(L); + } else if (strcmp(field, "prevgraf") == 0) { + lua_pushnumber(L, r->pg_field); + } else if (strcmp(field, "modeline") == 0) { + lua_pushnumber(L, r->ml_field); + } else if (strcmp(field, "prevdepth") == 0) { + lua_pushnumber(L, r->prev_depth_field); + } else if (strcmp(field, "spacefactor") == 0) { + lua_pushnumber(L, r->space_factor_field); + } else if (strcmp(field, "noad") == 0) { + lua_pushnumber(L, r->incompleat_noad_field); + lua_nodelib_push(L); + } else if (strcmp(field, "dirs") == 0) { + lua_pushnumber(L, r->dirs_field); + lua_nodelib_push(L); + } else if (strcmp(field, "mathdir") == 0) { + lua_pushboolean(L, r->math_field); + } else if (strcmp(field, "mathstyle") == 0) { + lua_pushnumber(L, r->math_style_field); + } else { + lua_pushnil(L); + } + return 1; +} + +static int lua_nest_setfield(lua_State * L) +{ + halfword *n; + int i; + list_state_record *r, **rv = lua_touserdata(L, -3); + const char *field = lua_tostring(L, -2); + r = *rv; + if (strcmp(field, "mode") == 0) { + lua_number2int(i, lua_tonumber(L, -1)); + r->mode_field = i; + } else if (strcmp(field, "head") == 0) { + n = check_isnode(L, -1); + r->head_field = *n; + } else if (strcmp(field, "tail") == 0) { + n = check_isnode(L, -1); + r->tail_field = *n; + } else if (strcmp(field, "delimptr") == 0) { + n = check_isnode(L, -1); + r->eTeX_aux_field = *n; + } else if (strcmp(field, "prevgraf") == 0) { + lua_number2int(i, lua_tonumber(L, -1)); + r->pg_field = i; + } else if (strcmp(field, "modeline") == 0) { + lua_number2int(i, lua_tonumber(L, -1)); + r->ml_field = i; + } else if (strcmp(field, "prevdepth") == 0) { + lua_number2int(i, lua_tonumber(L, -1)); + r->prev_depth_field = i; + } else if (strcmp(field, "spacefactor") == 0) { + lua_number2int(i, lua_tonumber(L, -1)); + r->space_factor_field = i; + } else if (strcmp(field, "noad") == 0) { + n = check_isnode(L, -1); + r->incompleat_noad_field = *n; + } else if (strcmp(field, "dirs") == 0) { + n = check_isnode(L, -1); + r->dirs_field = *n; + } else if (strcmp(field, "mathdir") == 0) { + r->math_field = lua_toboolean(L, -1); + } else if (strcmp(field, "mathstyle") == 0) { + lua_number2int(i, lua_tonumber(L, -1)); + r->math_style_field = i; + } + return 0; +} + +static const struct luaL_reg nest_m[] = { + {"__index", lua_nest_getfield}, + {"__newindex", lua_nest_setfield}, + {NULL, NULL} /* sentinel */ +}; + +static void init_nest_lib(lua_State * L) +{ + luaL_newmetatable(L, NEST_METATABLE); + luaL_register(L, NULL, nest_m); + lua_pop(L, 1); +} + +static int getnest(lua_State * L) +{ + int ptr; + list_state_record **nestitem; + if (lua_isnumber(L, 2)) { + lua_number2int(ptr, lua_tonumber(L, 2)); + if (ptr >= 0 && ptr <= nest_ptr) { + nestitem = lua_newuserdata(L, sizeof(list_state_record *)); + *nestitem = &nest[ptr]; + luaL_getmetatable(L, NEST_METATABLE); + lua_setmetatable(L, -2); + } else { + lua_pushnil(L); + } + } else if (lua_isstring(L, 2)) { + const char *s = lua_tostring(L, 2); + if (strcmp(s, "ptr") == 0) { + lua_pushnumber(L, nest_ptr); + } else { + lua_pushnil(L); + } + } else { + lua_pushnil(L); + } + return 1; +} + +static int setnest(lua_State * L) +{ + luaL_error(L, "You can't modify the semantic nest array directly"); + return 2; +} static int do_integer_error(double m) { - const char *help[] = { "I can only go up to 2147483647='17777777777=" "7FFFFFFF,", + const char *help[] = + { "I can only go up to 2147483647='17777777777=" "7FFFFFFF,", "so I'm using that number instead of yours.", NULL }; @@ -1219,7 +1644,7 @@ static int do_integer_error(double m) static int tex_roundnumber(lua_State * L) { - double m = lua_tonumber(L, 1) + 0.5; + double m = (double) lua_tonumber(L, 1) + 0.5; if (abs(m) > (double) infinity) lua_pushnumber(L, do_integer_error(m)); else @@ -1237,7 +1662,7 @@ static int tex_scaletable(lua_State * L) lua_pushvalue(L, -2); lua_insert(L, -2); if (lua_isnumber(L, -1)) { - double m = lua_tonumber(L, -1) * delta + 0.5; + double m = (double) lua_tonumber(L, -1) * delta + 0.5; lua_pop(L, 1); if (abs(m) > (double) infinity) lua_pushnumber(L, do_integer_error(m)); @@ -1247,7 +1672,7 @@ static int tex_scaletable(lua_State * L) lua_rawset(L, 3); } } else if (lua_isnumber(L, 1)) { - double m = lua_tonumber(L, 1) * delta + 0.5; + double m = (double) lua_tonumber(L, 1) * delta + 0.5; if (abs(m) > (double) infinity) lua_pushnumber(L, do_integer_error(m)); else @@ -1280,7 +1705,7 @@ static int tex_definefont(lua_State * L) i = 2; } csname = luaL_checklstring(L, i, &l); - f = luaL_checkinteger(L, (i + 1)); + f = (int) luaL_checkinteger(L, (i + 1)); t = maketexlstring(csname, l); no_new_control_sequence = 0; u = string_lookup(csname, l); @@ -1289,8 +1714,8 @@ static int tex_definefont(lua_State * L) geq_define(u, set_font_cmd, f); else eq_define(u, set_font_cmd, f); - zeqtb[get_font_id_base() + f] = zeqtb[u]; - hash_text(get_font_id_base() + f) = t; + eqtb[font_id_base + f] = eqtb[u]; + hash_text(font_id_base + f) = t; return 0; } @@ -1299,14 +1724,15 @@ static int tex_hashpairs(lua_State * L) int cmd, chr; str_number s = 0; int cs = 1; - int eqtb_size = get_eqtb_size(); lua_newtable(L); while (cs < eqtb_size) { s = hash_text(cs); if (s > 0) { - lua_pushstring(L, makecstring(s)); - cmd = zget_eq_type(cs); - chr = zget_equiv(cs); + char *ss = makecstring(s); + lua_pushstring(L, ss); + free(ss); + cmd = eq_type(cs); + chr = equiv(cs); make_token_table(L, cmd, chr, cs); lua_rawset(L, -3); } @@ -1324,7 +1750,9 @@ static int tex_primitives(lua_State * L) while (cs < prim_size) { s = get_prim_text(cs); if (s > 0) { - lua_pushstring(L, makecstring(s)); + char *ss = makecstring(s); + lua_pushstring(L, ss); + free(ss); cmd = get_prim_eq_type(cs); chr = get_prim_equiv(cs); make_token_table(L, cmd, chr, 0); @@ -1373,7 +1801,9 @@ static int tex_extraprimitives(lua_State * L) s = get_prim_text(cs); if (s > 0) { if (get_prim_origin(cs) & mask) { - lua_pushstring(L, makecstring(s)); + char *ss = makecstring(s); + lua_pushstring(L, ss); + free(ss); lua_rawseti(L, -2, i++); } } @@ -1386,8 +1816,7 @@ static int tex_enableprimitives(lua_State * L) { int n = lua_gettop(L); if (n != 2) { - lua_pushstring(L, "wrong number of arguments"); - lua_error(L); + luaL_error(L, "wrong number of arguments"); } else { size_t l; int i; @@ -1404,24 +1833,25 @@ static int tex_enableprimitives(lua_State * L) halfword prim_val = prim_lookup(s); if (prim_val != undefined_primitive) { char *newprim; - integer val; + int val; size_t newl; halfword cur_cmd = get_prim_eq_type(prim_val); halfword cur_chr = get_prim_equiv(prim_val); if (strncmp(pre, prim, l) != 0) { /* not a prefix */ newl = strlen(prim) + l; - newprim = (char *) xmalloc(newl + 1); + newprim = (char *) xmalloc((unsigned) (newl + 1)); strcpy(newprim, pre); strcat(newprim + l, prim); } else { newl = strlen(prim); - newprim = (char *) xmalloc(newl + 1); + newprim = (char *) xmalloc((unsigned) (newl + 1)); strcpy(newprim, prim); } val = string_lookup(newprim, newl); - if (val == static_undefined_control_sequence || - zget_eq_type(val) == undefined_cs_cmd) { - primitive_def(newprim, newl, cur_cmd, cur_chr); + if (val == undefined_control_sequence || + eq_type(val) == undefined_cs_cmd) { + primitive_def(newprim, newl, (quarterword) cur_cmd, + cur_chr); } free(newprim); } @@ -1436,17 +1866,390 @@ static int tex_enableprimitives(lua_State * L) lua_pop(L, 1); /* the table */ no_new_control_sequence = nncs; } else { - lua_pushstring(L, "Expected an array of names as second argument"); - lua_error(L); + luaL_error(L, "Expected an array of names as second argument"); + } + } + return 0; +} + +#define get_int_par(A,B,C) do { \ + lua_pushstring(L,(A)); \ + lua_gettable(L,-2); \ + if (lua_type(L, -1) == LUA_TNUMBER) { \ + lua_number2int(B,lua_tonumber(L, -1)); \ + } else { \ + B = (C); \ + } \ + lua_pop(L,1); \ + } while (0) + + +#define get_intx_par(A,B,C,D,E) do { \ + lua_pushstring(L,(A)); \ + lua_gettable(L,-2); \ + if (lua_type(L, -1) == LUA_TNUMBER) { \ + lua_number2int(B,lua_tonumber(L, -1)); \ + D = null; \ + } else if (lua_type(L, -1) == LUA_TTABLE){ \ + B = 0; \ + D = nodelib_topenalties(L, lua_gettop(L)); \ + } else { \ + B = (C); \ + D = (E); \ + } \ + lua_pop(L,1); \ + } while (0) + +#define get_dimen_par(A,B,C) do { \ + lua_pushstring(L,(A)); \ + lua_gettable(L,-2); \ + if (lua_type(L, -1) == LUA_TNUMBER) { \ + lua_number2int(B,lua_tonumber(L, -1)); \ + } else { \ + B = (C); \ + } \ + lua_pop(L,1); \ + } while (0) + + +#define get_glue_par(A,B,C) do { \ + lua_pushstring(L,(A)); \ + lua_gettable(L,-2); \ + if (lua_type(L, -1) != LUA_TNIL) { \ + B = *check_isnode(L, -1); \ + } else { \ + B = (C); \ + } \ + lua_pop(L,1); \ + } while (0) + + +static halfword nodelib_toparshape(lua_State * L, int i) +{ + halfword p; + int n = 0; + int width, indent, j; + /* find |n| */ + lua_pushnil(L); + while (lua_next(L, i) != 0) { + n++; + lua_pop(L, 1); + } + if (n == 0) + return null; + p = new_node(shape_node, 2 * (n + 1) + 1); + vinfo(p + 1) = n; + /* fill |p| */ + lua_pushnil(L); + j = 0; + while (lua_next(L, i) != 0) { + /* don't give an error for non-tables, we may add special syntaxes at some point */ + j++; + if (lua_type(L, i) == LUA_TTABLE) { + lua_rawgeti(L, -1, 1); /* indent */ + if (lua_type(L, -1) == LUA_TNUMBER) { + lua_number2int(indent, lua_tonumber(L, -1)); + lua_pop(L, 1); + lua_rawgeti(L, -1, 2); /* width */ + if (lua_type(L, -1) == LUA_TNUMBER) { + lua_number2int(width, lua_tonumber(L, -1)); + lua_pop(L, 1); + varmem[p + 2 * j].cint = indent; + varmem[p + 2 * j + 1].cint = width; + } + } + } + lua_pop(L, 1); + } + return p; +} + +/* penalties */ + +static halfword nodelib_topenalties(lua_State * L, int i) +{ + halfword p; + int n = 0; + int j; + /* find |n| */ + lua_pushnil(L); + while (lua_next(L, i) != 0) { + n++; + lua_pop(L, 1); + } + if (n == 0) + return null; + p = new_node(shape_node, 2 * ((n / 2) + 1) + 1 + 1); + vinfo(p + 1) = (n / 2) + 1; + varmem[p + 2].cint = n; + lua_pushnil(L); + j = 2; + while (lua_next(L, i) != 0) { + j++; + if (lua_isnumber(L, -1)) { + int pen = 0; + lua_number2int(pen, lua_tonumber(L, -1)); + varmem[p+j].cint = pen; + } + lua_pop(L, 1); + } + if (!odd(n)) + varmem[p+j+1].cint = 0; + return p; +} + + + + +static int tex_run_linebreak(lua_State * L) +{ + + halfword *j; + halfword p; + halfword final_par_glue; + int paragraph_dir = 0; + /* locally initialized parameters for line breaking */ + int pretolerance, tracingparagraphs, tolerance, looseness, hyphenpenalty, + exhyphenpenalty, pdfadjustspacing, adjdemerits, pdfprotrudechars, + linepenalty, lastlinefit, doublehyphendemerits, finalhyphendemerits, + hangafter, interlinepenalty, widowpenalty, clubpenalty, brokenpenalty; + halfword emergencystretch, hangindent, hsize, leftskip, rightskip, + pdfeachlineheight, pdfeachlinedepth, pdffirstlineheight, + pdflastlinedepth, pdfignoreddimen, parshape; + int fewest_demerits = 0, actual_looseness = 0; + halfword clubpenalties, interlinepenalties, widowpenalties; + + /* push a new nest level */ + push_nest(); + /* save_vlink_cur_head = vlink(cur_list.head_field); */ + + j = check_isnode(L, 1); /* the value */ + vlink(temp_head) = *j; + p = *j; + if ((!is_char_node(vlink(*j))) + && ((type(vlink(*j)) == whatsit_node) + && (subtype(vlink(*j)) == local_par_node))) { + paragraph_dir = local_par_dir(vlink(*j)); + } + + while (vlink(p) != null) + p = vlink(p); + final_par_glue = p; + + /* initialize local parameters */ + + if (lua_gettop(L) != 2 || lua_type(L, 2) != LUA_TTABLE) { + lua_checkstack(L, 3); + lua_newtable(L); + } + lua_pushstring(L, "pardir"); + lua_gettable(L, -2); + if (lua_type(L, -1) == LUA_TSTRING) { + paragraph_dir = nodelib_getdir(L, -1); + } + lua_pop(L, 1); + + lua_pushstring(L, "parshape"); + lua_gettable(L, -2); + if (lua_type(L, -1) == LUA_TTABLE) { + parshape = nodelib_toparshape(L, lua_gettop(L)); + } else { + parshape = equiv(par_shape_loc); + } + lua_pop(L, 1); + + get_int_par("pretolerance", pretolerance, int_par(pretolerance_code)); + get_int_par("tracingparagraphs", tracingparagraphs, + int_par(tracing_paragraphs_code)); + get_int_par("tolerance", tolerance, int_par(tolerance_code)); + get_int_par("looseness", looseness, int_par(looseness_code)); + get_int_par("hyphenpenalty", hyphenpenalty, int_par(hyphen_penalty_code)); + get_int_par("exhyphenpenalty", exhyphenpenalty, + int_par(ex_hyphen_penalty_code)); + get_int_par("pdfadjustspacing", pdfadjustspacing, + int_par(pdf_adjust_spacing_code)); + get_int_par("adjdemerits", adjdemerits, int_par(adj_demerits_code)); + get_int_par("pdfprotrudechars", pdfprotrudechars, + int_par(pdf_protrude_chars_code)); + get_int_par("linepenalty", linepenalty, int_par(line_penalty_code)); + get_int_par("lastlinefit", lastlinefit, int_par(last_line_fit_code)); + get_int_par("doublehyphendemerits", doublehyphendemerits, + int_par(double_hyphen_demerits_code)); + get_int_par("finalhyphendemerits", finalhyphendemerits, + int_par(final_hyphen_demerits_code)); + get_int_par("hangafter", hangafter, int_par(hang_after_code)); + get_intx_par("interlinepenalty", interlinepenalty,int_par(inter_line_penalty_code), + interlinepenalties, equiv(inter_line_penalties_loc)); + get_intx_par("clubpenalty", clubpenalty, int_par(club_penalty_code), + clubpenalties, equiv(club_penalties_loc)); + get_intx_par("widowpenalty", widowpenalty, int_par(widow_penalty_code), + widowpenalties, equiv(widow_penalties_loc)); + get_int_par("brokenpenalty", brokenpenalty, int_par(broken_penalty_code)); + get_dimen_par("emergencystretch", emergencystretch, + dimen_par(emergency_stretch_code)); + get_dimen_par("hangindent", hangindent, dimen_par(hang_indent_code)); + get_dimen_par("hsize", hsize, dimen_par(hsize_code)); + get_glue_par("leftskip", leftskip, glue_par(left_skip_code)); + get_glue_par("rightskip", rightskip, glue_par(right_skip_code)); + get_dimen_par("pdfeachlineheight", pdfeachlineheight, + dimen_par(pdf_each_line_height_code)); + get_dimen_par("pdfeachlinedepth", pdfeachlinedepth, + dimen_par(pdf_each_line_depth_code)); + get_dimen_par("pdffirstlineheight", pdffirstlineheight, + dimen_par(pdf_first_line_height_code)); + get_dimen_par("pdflastlinedepth", pdflastlinedepth, + dimen_par(pdf_last_line_depth_code)); + get_dimen_par("pdfignoreddimen", pdfignoreddimen, + dimen_par(pdf_ignored_dimen_code)); + + ext_do_line_break(paragraph_dir, + pretolerance, tracingparagraphs, tolerance, + emergencystretch, + looseness, hyphenpenalty, exhyphenpenalty, + pdfadjustspacing, + parshape, + adjdemerits, pdfprotrudechars, + linepenalty, lastlinefit, + doublehyphendemerits, finalhyphendemerits, + hangindent, hsize, hangafter, leftskip, rightskip, + pdfeachlineheight, pdfeachlinedepth, + pdffirstlineheight, pdflastlinedepth, + interlinepenalties, + interlinepenalty, clubpenalty, + clubpenalties, + widowpenalties, + widowpenalty, brokenpenalty, + final_par_glue, pdfignoreddimen); + + /* return the generated list, and its prevdepth */ + get_linebreak_info (&fewest_demerits, &actual_looseness) ; + lua_nodelib_push_fast(L, vlink(cur_list.head_field)); + lua_newtable(L); + lua_pushstring(L, "demerits"); + lua_pushnumber(L, fewest_demerits); + lua_settable(L, -3); + lua_pushstring(L, "looseness"); + lua_pushnumber(L, actual_looseness); + lua_settable(L, -3); + lua_pushstring(L, "prevdepth"); + lua_pushnumber(L, cur_list.prev_depth_field); + lua_settable(L, -3); + lua_pushstring(L, "prevgraf"); + lua_pushnumber(L, cur_list.pg_field); + lua_settable(L, -3); + + /* restore nest stack */ + pop_nest(); + if (parshape != equiv(par_shape_loc)) + flush_node(parshape); + return 2; +} + +static int tex_shipout(lua_State * L) +{ + int boxnum = get_box_id(L, 1); + ship_out(static_pdf, box(boxnum), true); + box(boxnum) = null; + return 0; +} + +static int tex_badness(lua_State * L) +{ + scaled t,s; + lua_number2int(t,lua_tonumber(L,1)); + lua_number2int(s,lua_tonumber(L,2)); + lua_pushnumber(L, badness(t,s)); + return 1; +} + + +static int tex_run_boot(lua_State * L) +{ + int n = lua_gettop(L); + const char *format = NULL; + if (n >= 1) { + ini_version = 0; + format = luaL_checkstring(L, 1); + } else { + ini_version = 1; + } + if (main_initialize()) { /* > 0 = failure */ + lua_pushboolean(L, 0); /* false */ + return 1; + } + if (format) { + if (!zopen_w_input(&fmt_file, format, DUMP_FORMAT, FOPEN_RBIN_MODE)) { + lua_pushboolean(L, 0); /* false */ + return 1; } + if (!load_fmt_file(format)) { + zwclose(fmt_file); + lua_pushboolean(L, 0); /* false */ + return 1; + } + zwclose(fmt_file); } + fix_date_and_time(); + if (format == NULL) + make_pdftex_banner(); + random_seed = (microseconds * 1000) + (epochseconds % 1000000); + init_randoms(random_seed); + initialize_math(); + fixup_selector(log_opened); + check_texconfig_init(); + text_dir_ptr = new_dir(0); + history = spotless; /* ready to go! */ + /* Initialize synctex primitive */ + synctexinitcommand(); + /* tex is ready to go, now */ + unhide_lua_table(Luas, "tex", tex_table_id); + unhide_lua_table(Luas, "pdf", pdf_table_id); + unhide_lua_table(Luas, "token", token_table_id); + unhide_lua_table(Luas, "node", node_table_id); + + lua_pushboolean(L, 1); /* true */ + return 1; + +} + +static int tex_run_main(lua_State * L) +{ + (void) L; + main_control(); return 0; } +static int tex_run_end(lua_State * L) +{ + (void) L; + final_cleanup(); /* prepare for death */ + close_files_and_terminate(); + do_final_end(); + return 0; +} + +void init_tex_table(lua_State * L) +{ + lua_createtable(L, 0, 3); + lua_pushcfunction(L, tex_run_boot); + lua_setfield(L, -2, "initialize"); + lua_pushcfunction(L, tex_run_main); + lua_setfield(L, -2, "run"); + lua_pushcfunction(L, tex_run_end); + lua_setfield(L, -2, "finish"); + lua_setglobal(L, "tex"); +} + + + static const struct luaL_reg texlib[] = { + {"run", tex_run_main}, /* may be needed */ + {"finish", tex_run_end}, /* may be needed */ + {"write", luacwrite}, {"write", luacwrite}, {"print", luacprint}, + {"tprint", luactprint}, {"sprint", luacsprint}, {"set", settex}, {"get", gettex}, @@ -1470,8 +2273,11 @@ static const struct luaL_reg texlib[] = { {"getboxht", getboxht}, {"setboxdp", setboxdp}, {"getboxdp", getboxdp}, + {"setnest", setnest}, + {"getnest", getnest}, {"round", tex_roundnumber}, {"scale", tex_scaletable}, + {"sp", tex_scaledimen}, {"fontname", getfontname}, {"fontidentifier", getfontidentifier}, {"pdffontname", getpdffontname}, @@ -1487,8 +2293,11 @@ static const struct luaL_reg texlib[] = { {"primitives", tex_primitives}, {"extraprimitives", tex_extraprimitives}, {"enableprimitives", tex_enableprimitives}, + {"shipout", tex_shipout}, + {"badness", tex_badness}, {"setmath", tex_setmathparm}, {"getmath", tex_getmathparm}, + {"linebreak", tex_run_linebreak}, {NULL, NULL} /* sentinel */ }; @@ -1506,7 +2315,9 @@ int luaopen_tex(lua_State * L) make_table(L, "ht", "getboxht", "setboxht"); make_table(L, "dp", "getboxdp", "setboxdp"); make_table(L, "lists", "getlist", "setlist"); + make_table(L, "nest", "getnest", "setnest"); /* *INDENT-ON* */ + init_nest_lib(L); /* make the meta entries */ /* fetch it back */ luaL_newmetatable(L, "tex_meta"); @@ -1525,6 +2336,5 @@ int luaopen_tex(lua_State * L) spindle_size = 1; /* a somewhat odd place for this assert, maybe */ assert(command_names[data_cmd].command_offset == data_cmd); - assert(param_int_pars == (get_count_base() - get_int_base())); return 1; } diff --git a/Build/source/texk/web2c/luatexdir/lua/ltokenlib.c b/Build/source/texk/web2c/luatexdir/lua/ltokenlib.c index 1ba1e609aef..02e6d84dff6 100644 --- a/Build/source/texk/web2c/luatexdir/lua/ltokenlib.c +++ b/Build/source/texk/web2c/luatexdir/lua/ltokenlib.c @@ -17,17 +17,11 @@ You should have received a copy of the GNU General Public License along with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */ -#include "luatex-api.h" -#include <ptexlib.h> -#include "tokens.h" +#include "lua/luatex-api.h" +#include "ptexlib.h" static const char _svn_version[] = - "$Id: ltokenlib.c 2448 2009-06-08 07:43:50Z taco $ $URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.40.6/source/texk/web2c/luatexdir/lua/ltokenlib.c $"; - -static int max_command = 0; -static int null_cs = 0; - -#define protected_token 0x1C00001 + "$Id: ltokenlib.c 3404 2010-01-28 11:17:10Z taco $ $URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/lua/ltokenlib.c $"; #define is_valid_token(L,i) (lua_istable(L,i) && lua_objlen(L,i)==3) #define get_token_cmd(L,i) lua_rawgeti(L,i,1) @@ -36,17 +30,28 @@ static int null_cs = 0; #define is_active_string(s) (strlen((char *)s)>3 && *s==0xEF && *(s+1)==0xBF && *(s+2)==0xBF) +static unsigned char *get_cs_text(int cs) +{ + if (cs == null_cs) + return (unsigned char *) xstrdup("\\csname\\endcsname"); + else if ((cs_text(cs) < 0) || (cs_text(cs) >= str_ptr)) + return (unsigned char *) xstrdup(""); + else + return (unsigned char *) makecstring(cs_text(cs)); +} + + static int test_expandable(lua_State * L) { - integer cmd = -1; + int cmd = -1; if (is_valid_token(L, -1)) { get_token_cmd(L, -1); if (lua_isnumber(L, -1)) { - cmd = lua_tointeger(L, -1); + cmd = (int) lua_tointeger(L, -1); } else if (lua_isstring(L, -1)) { cmd = get_command_id(lua_tostring(L, -1)); } - if (cmd > max_command) { + if (cmd > max_command_cmd) { lua_pushboolean(L, 1); } else { lua_pushboolean(L, 0); @@ -60,15 +65,15 @@ static int test_expandable(lua_State * L) static int test_protected(lua_State * L) { - integer chr = -1; + int chr = -1; if (is_valid_token(L, -1)) { get_token_chr(L, -1); if (lua_isnumber(L, -1)) { - chr = lua_tointeger(L, -1); + chr = (int) lua_tointeger(L, -1); } else if (lua_isstring(L, -1)) { chr = get_command_id(lua_tostring(L, -1)); } - if (fixmem[fixmem[chr].hhrh].hhlh == protected_token) { + if (token_info(token_link(chr)) == protected_token) { lua_pushboolean(L, 1); } else { lua_pushboolean(L, 0); @@ -82,15 +87,14 @@ static int test_protected(lua_State * L) static int test_activechar(lua_State * L) { if (is_valid_token(L, -1)) { - str_number n; - integer cs = 0; + unsigned char *s; + int cs = 0; get_token_cs(L, -1); if (lua_isnumber(L, -1)) { - cs = lua_tointeger(L, -1); + cs = (int) lua_tointeger(L, -1); } lua_pop(L, 1); - if (cs != 0 && (n = zget_cs_text(cs)) && n > 0) { - unsigned char *s = (unsigned char *) makecstring(n); + if (cs != 0 && ((s = get_cs_text(cs)) != (unsigned char *) NULL)) { if (is_active_string(s)) { free(s); lua_pushboolean(L, 1); @@ -110,7 +114,7 @@ static int run_get_command_name(lua_State * L) if (is_valid_token(L, -1)) { get_token_cmd(L, -1); if (lua_isnumber(L, -1)) { - cs = lua_tointeger(L, -1); + cs = (int) lua_tointeger(L, -1); lua_pushstring(L, command_names[cs].cmd_name); } else { lua_pushstring(L, ""); @@ -124,23 +128,22 @@ static int run_get_command_name(lua_State * L) static int run_get_csname_name(lua_State * L) { - int cs, cmd, n; - + int cs, cmd; + unsigned char *s; if (is_valid_token(L, -1)) { get_token_cmd(L, -1); if (lua_isnumber(L, -1)) { - cmd = lua_tointeger(L, -1); + cmd = (int) lua_tointeger(L, -1); } lua_pop(L, 1); cs = 0; get_token_cs(L, -1); if (lua_isnumber(L, -1)) { - cs = lua_tointeger(L, -1); + cs = (int) lua_tointeger(L, -1); } lua_pop(L, 1); - if (cs != 0 && (n = zget_cs_text(cs)) && n >= 0) { - unsigned char *s = (unsigned char *) makecstring(n); + if (cs != 0 && ((s = get_cs_text(cs)) != (unsigned char *) NULL)) { if (is_active_string(s)) lua_pushstring(L, (char *) (s + 3)); else @@ -171,9 +174,9 @@ static int run_get_csname_id(lua_State * L) size_t k, cs = 0; if (lua_isstring(L, -1)) { s = lua_tolstring(L, -1, &k); - cs = string_lookup(s, k); + cs = (size_t) string_lookup(s, k); } - lua_pushnumber(L, cs); + lua_pushnumber(L, (lua_Number) cs); return 1; } @@ -212,17 +215,17 @@ static int run_lookup(lua_State * L) { const char *s; size_t l; - integer cs, cmd, chr; + int cs, cmd, chr; int save_nncs; if (lua_isstring(L, -1)) { s = lua_tolstring(L, -1, &l); if (l > 0) { save_nncs = no_new_control_sequence; no_new_control_sequence = true; - cs = id_lookup((last + 1), l); /* cleans up the lookup buffer */ + cs = id_lookup((last + 1), (int) l); /* cleans up the lookup buffer */ cs = string_lookup(s, l); - cmd = zget_eq_type(cs); - chr = zget_equiv(cs); + cmd = eq_type(cs); + chr = equiv(cs); make_token_table(L, cmd, chr, cs); no_new_control_sequence = save_nncs; return 1; @@ -234,11 +237,11 @@ static int run_lookup(lua_State * L) static int run_build(lua_State * L) { - integer cmd, chr, cs; + int cmd, chr, cs; if (lua_isnumber(L, 1)) { cs = 0; - chr = lua_tointeger(L, 1); - cmd = luaL_optinteger(L, 2, get_char_cat_code(chr)); + chr = (int) lua_tointeger(L, 1); + cmd = (int) luaL_optinteger(L, 2, get_char_cat_code(chr)); if (cmd == 0 || cmd == 9 || cmd == 14 || cmd == 15) { fprintf(stdout, "\n\nluatex error: not a good token.\nCatcode %i can not be returned, so I replaced it by 12 (other)", @@ -248,8 +251,8 @@ static int run_build(lua_State * L) } if (cmd == 13) { cs = active_to_cs(chr, false); - cmd = zget_eq_type(cs); - chr = zget_equiv(cs); + cmd = eq_type(cs); + chr = equiv(cs); } make_token_table(L, cmd, chr, cs); return 1; @@ -277,7 +280,5 @@ static const struct luaL_reg tokenlib[] = { int luaopen_token(lua_State * L) { luaL_register(L, "token", tokenlib); - max_command = get_max_command(); - null_cs = get_nullcs(); return 1; } diff --git a/Build/source/texk/web2c/luatexdir/lua/luagen.h b/Build/source/texk/web2c/luatexdir/lua/luagen.h new file mode 100644 index 00000000000..9ab2e8e8c2f --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/lua/luagen.h @@ -0,0 +1,27 @@ +/* luagen.h + + Copyright 2009 Taco Hoekwater <taco@luatex.org> + + This file is part of LuaTeX. + + LuaTeX is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your + option) any later version. + + LuaTeX is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. + + You should have received a copy of the GNU General Public License along + with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */ + +/* $Id: luagen.h 3261 2009-12-18 11:38:21Z taco $ */ + +extern void lua_begin_page(PDF pdf); +extern void lua_end_page(PDF pdf); + +extern void lua_place_glyph(PDF pdf, internal_font_number f, int c); +extern void lua_place_rule(PDF pdf, scaledpos size); +extern void finish_lua_file(PDF pdf); diff --git a/Build/source/texk/web2c/luatexdir/lua/luagen.w b/Build/source/texk/web2c/luatexdir/lua/luagen.w new file mode 100644 index 00000000000..292176575c0 --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/lua/luagen.w @@ -0,0 +1,55 @@ +% luagen.w +% +% Copyright 2009 Taco Hoekwater <taco@@luatex.org> + +% This file is part of LuaTeX. + +% LuaTeX is free software; you can redistribute it and/or modify it under +% the terms of the GNU General Public License as published by the Free +% Software Foundation; either version 2 of the License, or (at your +% option) any later version. + +% LuaTeX is distributed in the hope that it will be useful, but WITHOUT +% ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +% FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +% License for more details. + +% You should have received a copy of the GNU General Public License along +% with LuaTeX; if not, see <http://www.gnu.org/licenses/>. + +@ @c +static const char _svn_version[] = + "$Id: luagen.w 3583 2010-04-02 17:40:44Z hhenkel $ " + "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/lua/luagen.w $"; + +#include "ptexlib.h" +#include "pdf/pdfpage.h" + +@ @c +void lua_begin_page(PDF pdf) +{ + (void) pdf; +} + +void lua_end_page(PDF pdf) +{ + (void) pdf; +} + +void lua_place_glyph(PDF pdf, internal_font_number f, int c) +{ + (void) pdf; + (void) f; + printf("%c", (int) c); +} + +void lua_place_rule(PDF pdf, scaledpos size) +{ + (void) pdf; + (void) size; +} + +void finish_lua_file(PDF pdf) +{ + (void) pdf; +} diff --git a/Build/source/texk/web2c/luatexdir/lua/luainit.c b/Build/source/texk/web2c/luatexdir/lua/luainit.w index 917cf462f7e..cd8c8872a7f 100644 --- a/Build/source/texk/web2c/luatexdir/lua/luainit.c +++ b/Build/source/texk/web2c/luatexdir/lua/luainit.w @@ -1,49 +1,55 @@ -/* luainit.c - - Copyright 2006-2008 Taco Hoekwater <taco@luatex.org> +% luainit.w +% +% Copyright 2006-2010 Taco Hoekwater <taco@@luatex.org> - This file is part of LuaTeX. +% This file is part of LuaTeX. - LuaTeX is free software; you can redistribute it and/or modify it under - the terms of the GNU General Public License as published by the Free - Software Foundation; either version 2 of the License, or (at your - option) any later version. +% LuaTeX is free software; you can redistribute it and/or modify it under +% the terms of the GNU General Public License as published by the Free +% Software Foundation; either version 2 of the License, or (at your +% option) any later version. - LuaTeX is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. +% LuaTeX is distributed in the hope that it will be useful, but WITHOUT +% ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +% FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +% License for more details. - You should have received a copy of the GNU General Public License along - with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */ +% You should have received a copy of the GNU General Public License along +% with LuaTeX; if not, see <http://www.gnu.org/licenses/>. -#include <sys/stat.h> - -#include "luatex-api.h" -#include <ptexlib.h> +@ @c +#include "openbsd-compat.h" +#ifdef HAVE_ASPRINTF /* asprintf is not defined in openbsd-compat.h, but in stdio.h */ +# include <stdio.h> +#endif +#include <kpathsea/c-stat.h> -#include <luatexdir/luatexextra.h> +#include "lua/luatex-api.h" +#include "ptexlib.h" static const char _svn_version[] = - "$Id: luainit.c 2448 2009-06-08 07:43:50Z taco $ $URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.40.6/source/texk/web2c/luatexdir/lua/luainit.c $"; - -/* TH: TODO - * - * This file is getting a bit messy, but it is not simple to fix unilaterally. - * - * Better to wait until Karl has some time (after texlive 2008) so we can - * synchronize with kpathsea. One problem, for instance, is that I would - * like to resolve the full executable path. kpse_set_program_name() does - * that, indirectly (by setting SELFAUTOLOC in the environment), but it - * does much more, making it hard to use for our purpose. - * - * In fact, it sets three C variables: - * program_invocation_name program_invocation_short_name kpse->program_name - * and four environment variables: - * SELFAUTOLOC SELFAUTODIR SELFAUTOPARENT progname - * - */ + "$Id: luainit.w 3583 2010-04-02 17:40:44Z hhenkel $ $URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/lua/luainit.w $"; + +@ +TH: TODO + +This file is getting a bit messy, but it is not simple to fix unilaterally. + +Better to wait until Karl has some time (after texlive 2008) so we can +synchronize with kpathsea. One problem, for instance, is that I would +like to resolve the full executable path. |kpse_set_program_name()| does +that, indirectly (by setting SELFAUTOLOC in the environment), but it +does much more, making it hard to use for our purpose. + +In fact, it sets three C variables: + + |program_invocation_name| |program_invocation_short_name| |kpse->program_name| + +and four environment variables: + + SELFAUTOLOC SELFAUTODIR SELFAUTOPARENT progname +@c const_string LUATEX_IHELP[] = { "Usage: luatex --lua=FILE [OPTION]... [TEXNAME[.tex]] [COMMANDS]", " or: luatex --lua=FILE [OPTION]... \\FIRST-LINE", @@ -60,22 +66,52 @@ const_string LUATEX_IHELP[] = { "", " If no arguments or options are specified, prompt for input.", "", - " --lua=FILE the lua initialization file", - " --nosocket disable the luasocket (network) library", - " --safer disable easily exploitable lua commands", - " --fmt=FORMAT load the format file FORMAT", - " --ini be initex, for dumping formats", - " --help display this help and exit", - " --version output version information and exit", + " The following regular options are understood: ", "", - " Alternate behaviour models can be obtained by special switches", + " --8bit ignored, input is assumed to be in UTF-8 encoding", + " --credits display credits and exit", + " --debug-format enable format debugging", + " --default-translate-file= ignored, input is assumed to be in UTF-8 encoding", + " --disable-write18 disable \\write18{SHELL COMMAND}", + " --draftmode switch on draft mode (generates no output PDF)", + " --enable-write18 enable \\write18{SHELL COMMAND}", + " --etex ignored, the etex extensions are always active", + " --[no-]file-line-error disable/enable file:line:error style messages", + " --[no-]file-line-error-style aliases of --[no-]file-line-error", + " --fmt=FORMAT load the format file FORMAT", + " --halt-on-error stop processing at the first error", + " --help display help and exit", + " --ini be iniluatex, for dumping formats", + " --interaction=STRING set interaction mode (STRING=batchmode/nonstopmode/scrollmode/errorstopmode)", + " --jobname=STRING set the job name to STRING", + " --kpathsea-debug=NUMBER set path searching debugging flags according to the bits of NUMBER", + " --lua=s load and execute a lua initialization script", + " --[no-]mktex=FMT disable/enable mktexFMT generation (FMT=tex/tfm)", + " --nosocket disable the lua socket library", + " --output-comment=STRING use STRING for DVI file comment instead of date (no effect for PDF)", + " --output-directory=DIR use DIR as the directory to write files to", + " --output-format=FORMAT use FORMAT for job output; FORMAT is 'dvi' or 'pdf'", + " --[no-]parse-first-line disable/enable parsing of the first line of the input file", + " --progname=STRING set the program name to STRING", + " --recorder enable filename recorder", + " --safer disable easily exploitable lua commands", + " --[no-]shell-escape disable/enable \\write18{SHELL COMMAND}", + " --shell-restricted restrict \\write18 to a list of commands given in texmf.cnf", + " --synctex=NUMBER enable synctex", + " --translate-file= ignored, input is assumed to be in UTF-8 encoding", + " --version display version and exit", + "", + "Alternate behaviour models can be obtained by special switches", "", " --luaonly run a lua file, then exit", " --luaconly byte-compile a lua file, then exit", + "", + "See the reference manual for more information about the startup process.", NULL }; -static char *ex_selfdir(char *argv0) +@ @c +char *ex_selfdir(char *argv0) { #if defined(WIN32) char short_path[PATH_MAX], path[PATH_MAX], *fp; @@ -83,9 +119,6 @@ static char *ex_selfdir(char *argv0) /* SearchPath() always gives back an absolute directory */ if (SearchPath(NULL, argv0, ".exe", PATH_MAX, short_path, &fp) == 0) FATAL1("Can't determine where the executable %s is.\n", argv0); - if (!win32_get_long_filename(short_path, path, sizeof(path))) { - FATAL1("This path points to an invalid file : %s\n", short_path); - } /* slashify the dirname */ for (fp = path; fp && *fp; fp++) if (IS_DIR_SEP(*fp)) @@ -97,6 +130,7 @@ static char *ex_selfdir(char *argv0) #endif } +@ @c static void prepare_cmdline(lua_State * L, char **argv, int argc, int zero_offset) { @@ -117,22 +151,25 @@ prepare_cmdline(lua_State * L, char **argv, int argc, int zero_offset) return; } -const_string input_name = NULL; +@ @c +string input_name = NULL; -static const_string user_progname = NULL; +static string user_progname = NULL; -const char *startup_filename = NULL; +char *startup_filename = NULL; int lua_only = 0; int lua_offset = 0; int safer_option = 0; int nosocket_option = 0; -/* Reading the options. */ +@ Reading the options. + +@ Test whether getopt found an option ``A''. +Assumes the option index is in the variable |option_index|, and the +option table in a variable |long_options|. -/* Test whether getopt found an option ``A''. - Assumes the option index is in the variable `option_index', and the - option table in a variable `long_options'. */ +@c #define ARGUMENT_IS(a) STREQ (long_options[option_index].name, a) /* SunOS cc can't initialize automatic structs, so make this static. */ @@ -158,8 +195,6 @@ static struct option long_options[] {"output-format", 1, 0, 0}, {"shell-escape", 0, &shellenabledp, 1}, {"no-shell-escape", 0, &shellenabledp, -1}, -{"shell-escape", 0, &shellenabledp, 1}, -{"no-shell-escape", 0, &shellenabledp, -1}, {"enable-write18", 0, &shellenabledp, 1}, {"disable-write18", 0, &shellenabledp, -1}, {"shell-restricted", 0, 0, 0}, @@ -182,6 +217,7 @@ static struct option long_options[] {0, 0, 0, 0} }; +@ @c static void parse_options(int argc, char **argv) { int g; /* `getopt' return code. */ @@ -223,12 +259,12 @@ static void parse_options(int argc, char **argv) output_directory = optarg; } else if (ARGUMENT_IS("output-comment")) { - unsigned len = strlen(optarg); + size_t len = strlen(optarg); if (len < 256) { output_comment = optarg; } else { WARNING2("Comment truncated to 255 characters from %d. (%s)", - len, optarg); + (int) len, optarg); output_comment = (string) xmalloc(256); strncpy(output_comment, optarg, 255); output_comment[255] = 0; @@ -261,7 +297,7 @@ static void parse_options(int argc, char **argv) kpse_maketex_option(optarg, false); } else if (ARGUMENT_IS("interaction")) { - /* These numbers match @d's in *.ch */ + /* These numbers match CPP defines */ if (STREQ(optarg, "batchmode")) { interactionoption = 0; } else if (STREQ(optarg, "nonstopmode")) { @@ -320,7 +356,7 @@ static void parse_options(int argc, char **argv) uexit(0); } } - /* attempt to find dump_name */ + /* attempt to find |dump_name| */ if (argv[optind] && argv[optind][0] == '&') { dump_name = strdup(argv[optind] + 1); } else if (argv[optind] && argv[optind][0] != '\\') { @@ -366,11 +402,13 @@ static void parse_options(int argc, char **argv) } } -/* test for readability */ +@ test for readability +@c #define is_readable(a) (stat(a,&finfo)==0) && S_ISREG(finfo.st_mode) && \ (f=fopen(a,"r")) != NULL && !fclose(f) -static const char *find_filename(const char *name, const char *envkey) +@ @c +static char *find_filename(char *name, const char *envkey) { struct stat finfo; char *dirname = NULL; @@ -385,7 +423,7 @@ static const char *find_filename(const char *name, const char *envkey) if (*(dirname + strlen(dirname) - 1) == '/') { *(dirname + strlen(dirname) - 1) = 0; } - filename = xmalloc(strlen(dirname) + strlen(name) + 2); + filename = xmalloc((unsigned) (strlen(dirname) + strlen(name) + 2)); filename = concat3(dirname, "/", name); if (is_readable(filename)) { xfree(dirname); @@ -398,7 +436,8 @@ static const char *find_filename(const char *name, const char *envkey) } -static char *cleaned_invocation_name(char *arg) +@ @c +char *cleaned_invocation_name(char *arg) { char *ret, *dot; const char *start = xbasename(arg); @@ -410,7 +449,8 @@ static char *cleaned_invocation_name(char *arg) return ret; } -static void init_kpse(void) +@ @c +void init_kpse(void) { if (!user_progname) { @@ -439,34 +479,249 @@ static void init_kpse(void) program_name_set = 1; } -static void fix_dumpname(void) +@ @c +void fix_dumpname(void) { int dist; if (dump_name) { /* adjust array for Pascal and provide extension, if needed */ - dist = strlen(dump_name) - strlen(DUMP_EXT); + dist = (int) (strlen(dump_name) - strlen(DUMP_EXT)); if (strstr(dump_name, DUMP_EXT) == dump_name + dist) - DUMP_VAR = concat(" ", dump_name); + TEX_format_default = dump_name; else - DUMP_VAR = concat3(" ", dump_name, DUMP_EXT); - DUMP_LENGTH_VAR = strlen(DUMP_VAR + 1); + TEX_format_default = concat(dump_name, DUMP_EXT); } else { - /* For dump_name to be NULL is a bug. */ + /* For |dump_name| to be NULL is a bug. */ if (!ini_version) abort(); } } +@ lua require patch + +@ Auxiliary function for kpse search + +@c +static const char *luatex_kpse_find_aux(lua_State *L, const char *name, + kpse_file_format_type format, const char *errname) +{ + const char *filename; + const char *altname; + altname = luaL_gsub(L, name, ".", "/"); /* Lua convention */ + filename = kpse_find_file(altname, format, false); + if (filename == NULL) { + filename = kpse_find_file(name, format, false); + } + if (filename == NULL) { + lua_pushfstring(L, "\n\t[kpse %s searcher] file not found: " LUA_QS, + errname, name); + } + return filename; +} + +@ The lua search function. + +When kpathsea is not initialized, then it runs the +normal lua function that is saved in the registry, otherwise +it uses kpathsea. + +two registry ref variables are needed: one for the actual lua +function, the other for its environment . + +@c +static int lua_loader_function = 0; +static int lua_loader_env = 0; + +static int luatex_kpse_lua_find(lua_State * L) +{ + const char *filename; + const char *name; + name = luaL_checkstring(L, 1); + if (program_name_set == 0) { + lua_CFunction orig_func; + lua_rawgeti(L, LUA_REGISTRYINDEX, lua_loader_function); + lua_rawgeti(L, LUA_REGISTRYINDEX, lua_loader_env); + lua_replace(L, LUA_ENVIRONINDEX); + orig_func = lua_tocfunction(L, -1); + lua_pop(L, 1); + return (orig_func) (L); + } + filename = luatex_kpse_find_aux(L, name, kpse_lua_format, "lua"); + if (filename == NULL) + return 1; /* library not found in this path */ + if (luaL_loadfile(L, filename) != 0) { + luaL_error(L, "error loading module %s from file %s:\n\t%s", + lua_tostring(L, 1), filename, lua_tostring(L, -1)); + } + return 1; /* library loaded successfully */ +} + +@ @c +static int clua_loader_function = 0; +static int clua_loader_env = 0; + +static int luatex_kpse_clua_find(lua_State * L) +{ + const char *filename; + const char *name; + if (safer_option) { + lua_pushliteral(L, "\n\t[C searcher disabled in safer mode]"); + return 1; /* library not found in this path */ + } + name = luaL_checkstring(L, 1); + if (program_name_set == 0) { + lua_CFunction orig_func; + lua_rawgeti(L, LUA_REGISTRYINDEX, clua_loader_function); + lua_rawgeti(L, LUA_REGISTRYINDEX, clua_loader_env); + lua_replace(L, LUA_ENVIRONINDEX); + orig_func = lua_tocfunction(L, -1); + lua_pop(L, 1); + return (orig_func) (L); + } + filename = luatex_kpse_find_aux(L, name, kpse_clua_format, "C"); + if (filename == NULL) + return 1; /* library not found in this path */ + return loader_C_luatex(L, name, filename); +} + +@ @c +static int clua_loadall_function = 0; +static int clua_loadall_env = 0; + +static int luatex_kpse_cluaall_find(lua_State * L) +{ + const char *filename; + const char *name; + char *fixedname; + const char *p = NULL; + if (safer_option) { + lua_pushliteral(L, "\n\t[All-in-one searcher disabled in safer mode]"); + return 1; /* library not found in this path */ + } + name = luaL_checkstring(L, 1); + p = strchr(name, '.'); + if (program_name_set == 0) { + lua_CFunction orig_func; + lua_rawgeti(L, LUA_REGISTRYINDEX, clua_loadall_function); + lua_rawgeti(L, LUA_REGISTRYINDEX, clua_loadall_env); + lua_replace(L, LUA_ENVIRONINDEX); + orig_func = lua_tocfunction(L, -1); + lua_pop(L, 1); + return (orig_func) (L); + } + if (p == NULL) return 0; /* is root */ + fixedname = xmalloc((size_t)(p - name)+1); + memcpy(fixedname,name,(size_t)(p - name)); + fixedname[(p - name)] = '\0'; + filename = luatex_kpse_find_aux(L, fixedname, kpse_clua_format, "All-in-one"); + free(fixedname); + if (filename == NULL) + return 1; /* library not found in this path */ + return loader_Call_luatex(L, name, filename); +} + +@ Setting up the new search functions. + + This replaces package.loaders[2] with the function defined above. + +@c +static void setup_lua_path(lua_State * L) +{ + lua_getglobal(L, "package"); + lua_getfield(L, -1, "loaders"); + lua_rawgeti(L, -1, 2); /* package.loaders[2] */ + lua_getfenv(L, -1); + lua_loader_env = luaL_ref(L, LUA_REGISTRYINDEX); + lua_loader_function = luaL_ref(L, LUA_REGISTRYINDEX); + lua_pushcfunction(L, luatex_kpse_lua_find); + lua_rawseti(L, -2, 2); /* replace the normal lua loader */ + + lua_rawgeti(L, -1, 3); /* package.loaders[3] */ + lua_getfenv(L, -1); + clua_loader_env = luaL_ref(L, LUA_REGISTRYINDEX); + clua_loader_function = luaL_ref(L, LUA_REGISTRYINDEX); + lua_pushcfunction(L, luatex_kpse_clua_find); + lua_rawseti(L, -2, 3); /* replace the normal lua lib loader */ + + lua_rawgeti(L, -1, 4); /* package.loaders[4] */ + lua_getfenv(L, -1); + clua_loadall_env = luaL_ref(L, LUA_REGISTRYINDEX); + clua_loadall_function = luaL_ref(L, LUA_REGISTRYINDEX); + lua_pushcfunction(L, luatex_kpse_cluaall_find); + lua_rawseti(L, -2, 4); /* replace the normal lua lib loader */ + + lua_pop(L, 2); /* pop the array and table */ +} + +@ helper variables for the safe keeping of table ids + +@c +int tex_table_id; +int pdf_table_id; +int token_table_id; +int node_table_id; + + +#if defined(WIN32) || defined(__MINGW32__) || defined(__CYGWIN__) +char **suffixlist; + +# define EXE_SUFFIXES ".com;.exe;.bat;.cmd;.vbs;.vbe;.js;.jse;.wsf;.wsh;.ws;.tcl;.py;.pyw" + +@ @c +static void mk_suffixlist(void) +{ + char **p; + char *q, *r, *v; + int n; + +# if defined(__CYGWIN__) + v = xstrdup(EXE_SUFFIXES); +# else + v = (char *) getenv("PATHEXT"); + if (v) /* strlwr() exists also in MingW */ + v = (char *) strlwr(xstrdup(v)); + else + v = xstrdup(EXE_SUFFIXES); +# endif + + q = v; + n = 0; + + while ((r = strchr(q, ';')) != NULL) { + n++; + r++; + q = r; + } + if (*q) + n++; + suffixlist = (char **) xmalloc((n + 2) * sizeof(char *)); + p = suffixlist; + *p = xstrdup(".dll"); + p++; + q = v; + while ((r = strchr(q, ';')) != NULL) { + *r = '\0'; + *p = xstrdup(q); + p++; + r++; + q = r; + } + if (*q) { + *p = xstrdup(q); + p++; + } + *p = NULL; + free(v); +} +#endif + +@ @c void lua_initialize(int ac, char **av) { char *given_file = NULL; + char *banner; int kpse_init; - int tex_table_id; - int pdf_table_id; - int token_table_id; - int node_table_id; - /* Non-const initialized variables for putenv(). */ static char LC_CTYPE_C[] = "LC_CTYPE=C"; static char LC_COLLATE_C[] = "LC_COLLATE=C"; static char LC_NUMERIC_C[] = "LC_NUMERIC=C"; @@ -475,7 +730,18 @@ void lua_initialize(int ac, char **av) argc = ac; argv = av; - ptexbanner = BANNER; + if (luatex_svn < 0) { + if (asprintf(&banner, "This is LuaTeX, Version %s-%d", + luatex_version_string, luatex_date_info) < 0) { + exit(EXIT_FAILURE); + } + } else { + if (asprintf(&banner, "This is LuaTeX, Version %s-%d (rev %d)", + luatex_version_string, luatex_date_info, luatex_svn) < 0) { + exit(EXIT_FAILURE); + } + } + ptexbanner = banner; program_invocation_name = cleaned_invocation_name(argv[0]); @@ -485,16 +751,19 @@ void lua_initialize(int ac, char **av) STREQ(argv[1], "--luaconly") || STREQ(argv[1], "--luac"))) { exit(luac_main(ac, av)); } +#if defined(WIN32) || defined(__MINGW32__) || defined(__CYGWIN__) + mk_suffixlist(); +#endif /* Must be initialized before options are parsed. */ interactionoption = 4; dump_name = NULL; /* 0 means "disable Synchronize TeXnology". - * synctexoption is a *.web variable. - * We initialize it to a weird value to catch the -synctex command line flag - * At runtime, if synctexoption is not INT_MAX, then it contains the command line option provided, - * otherwise no such option was given by the user. */ + synctexoption is a *.web variable. + We initialize it to a weird value to catch the -synctex command line flag + At runtime, if synctexoption is not |INT_MAX|, then it contains the command line option provided, + otherwise no such option was given by the user. */ #define SYNCTEX_NO_OPTION INT_MAX synctexoption = SYNCTEX_NO_OPTION; @@ -504,6 +773,7 @@ void lua_initialize(int ac, char **av) shellenabledp = true; /* make sure that the locale is 'sane' (for lua) */ + putenv(LC_CTYPE_C); putenv(LC_COLLATE_C); putenv(LC_NUMERIC_C); @@ -514,6 +784,7 @@ void lua_initialize(int ac, char **av) luainterpreter(); prepare_cmdline(Luas, argv, argc, lua_offset); /* collect arguments */ + setup_lua_path(Luas); if (startup_filename != NULL) { given_file = xstrdup(startup_filename); @@ -521,7 +792,7 @@ void lua_initialize(int ac, char **av) } /* now run the file */ if (startup_filename != NULL) { - const char *v1; + char *v1; /* hide the 'tex' and 'pdf' table */ tex_table_id = hide_lua_table(Luas, "tex"); token_table_id = hide_lua_table(Luas, "token"); @@ -532,6 +803,8 @@ void lua_initialize(int ac, char **av) fprintf(stdout, "%s\n", lua_tostring(Luas, -1)); exit(1); } + /* */ + init_tex_table(Luas); if (lua_pcall(Luas, 0, 0, 0)) { fprintf(stdout, "%s\n", lua_tostring(Luas, -1)); exit(1); @@ -556,7 +829,7 @@ void lua_initialize(int ac, char **av) unhide_lua_table(Luas, "token", token_table_id); unhide_lua_table(Luas, "node", node_table_id); - /* kpse_init */ + /* |kpse_init| */ kpse_init = -1; get_lua_boolean("texconfig", "kpse_init", &kpse_init); @@ -564,19 +837,19 @@ void lua_initialize(int ac, char **av) luainit = 0; /* re-enable loading of texmf.cnf values, see luatex.ch */ init_kpse(); } - /* prohibit_file_trace (boolean) */ + /* |prohibit_file_trace| (boolean) */ tracefilenames = 1; get_lua_boolean("texconfig", "trace_file_names", &tracefilenames); - /* file_line_error */ + /* |file_line_error| */ filelineerrorstylep = false; get_lua_boolean("texconfig", "file_line_error", &filelineerrorstylep); - /* halt_on_error */ + /* |halt_on_error| */ haltonerrorp = false; get_lua_boolean("texconfig", "halt_on_error", &haltonerrorp); - /* restrictedshell */ + /* |restrictedshell| */ v1 = NULL; get_lua_string("texconfig", "shell_escape", &v1); if (v1) { @@ -617,6 +890,7 @@ void lua_initialize(int ac, char **av) } } +@ @c void check_texconfig_init(void) { if (Luas != NULL) { @@ -636,7 +910,8 @@ void check_texconfig_init(void) } } -void write_svnversion(const char *v) +@ @c +void write_svnversion(char *v) { char *a_head, *n; char *a = strdup(v); diff --git a/Build/source/texk/web2c/luatexdir/lua/luanode.c b/Build/source/texk/web2c/luatexdir/lua/luanode.w index a9daa106920..81e6b4fa74e 100644 --- a/Build/source/texk/web2c/luatexdir/lua/luanode.c +++ b/Build/source/texk/web2c/luatexdir/lua/luanode.w @@ -1,33 +1,32 @@ -/* luanode.c - - Copyright 2006-2008 Taco Hoekwater <taco@luatex.org> +% luanode.w +% +% Copyright 2006-2008 Taco Hoekwater <taco@@luatex.org> - This file is part of LuaTeX. +% This file is part of LuaTeX. - LuaTeX is free software; you can redistribute it and/or modify it under - the terms of the GNU General Public License as published by the Free - Software Foundation; either version 2 of the License, or (at your - option) any later version. +% LuaTeX is free software; you can redistribute it and/or modify it under +% the terms of the GNU General Public License as published by the Free +% Software Foundation; either version 2 of the License, or (at your +% option) any later version. - LuaTeX is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. +% LuaTeX is distributed in the hope that it will be useful, but WITHOUT +% ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +% FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +% License for more details. - You should have received a copy of the GNU General Public License along - with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */ +% You should have received a copy of the GNU General Public License along +% with LuaTeX; if not, see <http://www.gnu.org/licenses/>. -#include "luatex-api.h" -#include <ptexlib.h> -#include "nodes.h" +@ @c +#include "lua/luatex-api.h" +#include "ptexlib.h" -static const char _svn_version[] = - "$Id: luanode.c 2448 2009-06-08 07:43:50Z taco $ $URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.40.6/source/texk/web2c/luatexdir/lua/luanode.c $"; -#undef link /* defined by cpascal.h */ -#define info(a) fixmem[(a)].hhlh -#define link(a) fixmem[(a)].hhrh +static const char _svn_version[] = + "$Id: luanode.w 3583 2010-04-02 17:40:44Z hhenkel $ " +"$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/lua/luanode.w $"; +@ @c static const char *group_code_names[] = { "", "simple", @@ -54,9 +53,10 @@ static const char *group_code_names[] = { "fin_row" }; -static const char *pack_type_name[] = { "exactly", "additional" }; +const char *pack_type_name[] = { "exactly", "additional" }; +@ @c void lua_node_filter_s(int filterid, const char *extrainfo) { lua_State *L = Luas; @@ -79,6 +79,7 @@ void lua_node_filter_s(int filterid, const char *extrainfo) return; } +@ @c void lua_node_filter(int filterid, int xextrainfo, halfword head_node, halfword * tail_node) @@ -126,6 +127,7 @@ lua_node_filter(int filterid, int xextrainfo, halfword head_node, } +@ @c int lua_linebreak_callback(int is_broken, halfword head_node, halfword * new_head) { @@ -161,8 +163,10 @@ lua_linebreak_callback(int is_broken, halfword head_node, halfword * new_head) +@ @c halfword -lua_hpack_filter(halfword head_node, scaled size, int pack_type, int extrainfo) +lua_hpack_filter(halfword head_node, scaled size, int pack_type, int extrainfo, + int pack_direction) { halfword ret; lua_State *L = Luas; @@ -177,7 +181,11 @@ lua_hpack_filter(halfword head_node, scaled size, int pack_type, int extrainfo) lua_pushstring(L, group_code_names[extrainfo]); lua_pushnumber(L, size); lua_pushstring(L, pack_type_name[pack_type]); - if (lua_pcall(L, 4, 1, 0) != 0) { /* no arg, 1 result */ + if (pack_direction >= 0) + lua_pushstring(L, string_dir(pack_direction)); + else + lua_pushnil(L); + if (lua_pcall(L, 5, 1, 0) != 0) { /* no arg, 1 result */ fprintf(stdout, "error: %s\n", lua_tostring(L, -1)); lua_pop(L, 2); error(); @@ -193,18 +201,21 @@ lua_hpack_filter(halfword head_node, scaled size, int pack_type, int extrainfo) ret = nodelist_from_lua(L); } lua_pop(L, 2); /* result and callback container table */ - /* lua_gc(L,LUA_GCSTEP, LUA_GC_STEP_SIZE); */ +#if 0 + lua_gc(L,LUA_GCSTEP, LUA_GC_STEP_SIZE); +#endif if (fix_node_lists) fix_node_list(ret); return ret; } +@ @c halfword lua_vpack_filter(halfword head_node, scaled size, int pack_type, scaled maxd, - int extrainfo) + int extrainfo, int pack_direction) { halfword ret; - integer callback_id; + int callback_id; lua_State *L = Luas; if (head_node == null) return head_node; @@ -225,7 +236,11 @@ lua_vpack_filter(halfword head_node, scaled size, int pack_type, scaled maxd, lua_pushnumber(L, size); lua_pushstring(L, pack_type_name[pack_type]); lua_pushnumber(L, maxd); - if (lua_pcall(L, 5, 1, 0) != 0) { /* no arg, 1 result */ + if (pack_direction >= 0) + lua_pushstring(L, string_dir(pack_direction)); + else + lua_pushnil(L); + if (lua_pcall(L, 6, 1, 0) != 0) { /* no arg, 1 result */ fprintf(stdout, "error: %s\n", lua_tostring(L, -1)); lua_pop(L, 2); error(); @@ -241,46 +256,59 @@ lua_vpack_filter(halfword head_node, scaled size, int pack_type, scaled maxd, ret = nodelist_from_lua(L); } lua_pop(L, 2); /* result and callback container table */ - /* lua_gc(L,LUA_GCSTEP, LUA_GC_STEP_SIZE); */ +#if 0 + lua_gc(L,LUA_GCSTEP, LUA_GC_STEP_SIZE); +#endif if (fix_node_lists) fix_node_list(ret); return ret; } -/* This is a quick hack to fix etex's \lastnodetype now that - * there are many more visible node types. TODO: check the - * eTeX manual for the expected return values. - */ - +@ This is a quick hack to fix etex's \.{\\lastnodetype} now that + there are many more visible node types. TODO: check the + eTeX manual for the expected return values. + +@c int visible_last_node_type(int n) { int i = type(n); - if ((i != math_node) && (i <= unset_node)) - return i + 1; - if (i == glyph_node) - return -1; if (i == whatsit_node && subtype(n) == local_par_node) return -1; - if (i == 255) - return -1; /* this is not right, probably dir nodes! */ - return last_known_node + 1; + if (i == glyph_node) { + if (is_ligature(n)) + return 7; /* old ligature value */ + else + return 0; /* old character value */ + } + if (i <= unset_node) { + return i + 1; + } else if (i <= delim_node) { + return 15; /* so-called math nodes */ + } else { + return -1; + } } -void lua_pdf_literal(int i) +@ @c +void lua_pdf_literal(PDF pdf, int i) { - const char *s; + const char *s = NULL; size_t l = 0; lua_rawgeti(Luas, LUA_REGISTRYINDEX, i); s = lua_tolstring(Luas, -1, &l); - while (l--) { - pdf_room(1); - pdf_buf[pdf_ptr++] = *s++; + if (l < max_single_pdf_print) { + pdf_out_block(pdf, s, l); + } else { + while (l--) { + pdf_out(pdf, *s++); + } } - pdf_buf[pdf_ptr++] = 10; /* pdf_print_nl */ + pdf_out(pdf, 10); /* |pdf_print_nl| */ lua_pop(Luas, 1); } +@ @c void copy_pdf_literal(pointer r, pointer p) { pdf_literal_type(r) = pdf_literal_type(p); @@ -295,6 +323,7 @@ void copy_pdf_literal(pointer r, pointer p) } +@ @c void free_pdf_literal(pointer p) { if (pdf_literal_type(p) == normal) { @@ -304,6 +333,7 @@ void free_pdf_literal(pointer p) } } +@ @c void show_pdf_literal(pointer p) { tprint_esc("pdfliteral"); @@ -317,7 +347,7 @@ void show_pdf_literal(pointer p) tprint(" direct"); break; default: - tconfusion("literal2"); + confusion("literal2"); break; } if (pdf_literal_type(p) == normal) { diff --git a/Build/source/texk/web2c/luatexdir/lua/luastuff.c b/Build/source/texk/web2c/luatexdir/lua/luastuff.w index 75bdaf367ef..06547bc4de9 100644 --- a/Build/source/texk/web2c/luatexdir/lua/luastuff.c +++ b/Build/source/texk/web2c/luatexdir/lua/luastuff.w @@ -1,57 +1,63 @@ -/* luastuff.c - - Copyright 2006-2008 Taco Hoekwater <taco@luatex.org> +% luastuff.w - This file is part of LuaTeX. +% Copyright 2006-2010 Taco Hoekwater <taco@@luatex.org> - LuaTeX is free software; you can redistribute it and/or modify it under - the terms of the GNU General Public License as published by the Free - Software Foundation; either version 2 of the License, or (at your - option) any later version. +% This file is part of LuaTeX. - LuaTeX is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. +% LuaTeX is free software; you can redistribute it and/or modify it under +% the terms of the GNU General Public License as published by the Free +% Software Foundation; either version 2 of the License, or (at your +% option) any later version. - You should have received a copy of the GNU General Public License along - with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */ +% LuaTeX is distributed in the hope that it will be useful, but WITHOUT +% ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +% FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +% License for more details. -#include "luatex-api.h" -#include <ptexlib.h> +% You should have received a copy of the GNU General Public License along +% with LuaTeX; if not, see <http://www.gnu.org/licenses/>. +@ @c static const char _svn_version[] = - "$Id: luastuff.c 2321 2009-04-18 09:17:13Z hhenkel $ $URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.40.6/source/texk/web2c/luatexdir/lua/luastuff.c $"; + "$Id: luastuff.w 3583 2010-04-02 17:40:44Z hhenkel $ " + "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/lua/luastuff.w $"; +#include "lua/luatex-api.h" +#include "ptexlib.h" + +@ @c lua_State *Luas = NULL; int luastate_bytes = 0; int lua_active = 0; -void make_table(lua_State * L, const char *tab, const char *getfunc, const char *setfunc) +@ @c +void make_table(lua_State * L, const char *tab, const char *getfunc, + const char *setfunc) { - /* make the table *//* [{<tex>}] */ - lua_pushstring(L, tab); /* [{<tex>},"dimen"] */ - lua_newtable(L); /* [{<tex>},"dimen",{}] */ - lua_settable(L, -3); /* [{<tex>}] */ + /* make the table *//* |[{<tex>}]| */ + lua_pushstring(L, tab); /* |[{<tex>},"dimen"]| */ + lua_newtable(L); /* |[{<tex>},"dimen",{}]| */ + lua_settable(L, -3); /* |[{<tex>}]| */ /* fetch it back */ - lua_pushstring(L, tab); /* [{<tex>},"dimen"] */ - lua_gettable(L, -2); /* [{<tex>},{<dimen>}] */ + lua_pushstring(L, tab); /* |[{<tex>},"dimen"]| */ + lua_gettable(L, -2); /* |[{<tex>},{<dimen>}]| */ /* make the meta entries */ - luaL_newmetatable(L, tab); /* [{<tex>},{<dimen>},{<dimen_m>}] */ - lua_pushstring(L, "__index"); /* [{<tex>},{<dimen>},{<dimen_m>},"__index"] */ - lua_pushstring(L, getfunc); /* [{<tex>},{<dimen>},{<dimen_m>},"__index","getdimen"] */ - lua_gettable(L, -5); /* [{<tex>},{<dimen>},{<dimen_m>},"__index",<tex.getdimen>] */ - lua_settable(L, -3); /* [{<tex>},{<dimen>},{<dimen_m>}] */ - lua_pushstring(L, "__newindex"); /* [{<tex>},{<dimen>},{<dimen_m>},"__newindex"] */ - lua_pushstring(L, setfunc); /* [{<tex>},{<dimen>},{<dimen_m>},"__newindex","setdimen"] */ - lua_gettable(L, -5); /* [{<tex>},{<dimen>},{<dimen_m>},"__newindex",<tex.setdimen>] */ - lua_settable(L, -3); /* [{<tex>},{<dimen>},{<dimen_m>}] */ - lua_setmetatable(L, -2); /* [{<tex>},{<dimen>}] : assign the metatable */ - lua_pop(L, 1); /* [{<tex>}] : clean the stack */ + luaL_newmetatable(L, tab); /* |[{<tex>},{<dimen>},{<dimen_m>}]| */ + lua_pushstring(L, "__index"); /* |[{<tex>},{<dimen>},{<dimen_m>},"__index"]| */ + lua_pushstring(L, getfunc); /* |[{<tex>},{<dimen>},{<dimen_m>},"__index","getdimen"]| */ + lua_gettable(L, -5); /* |[{<tex>},{<dimen>},{<dimen_m>},"__index",<tex.getdimen>]| */ + lua_settable(L, -3); /* |[{<tex>},{<dimen>},{<dimen_m>}]| */ + lua_pushstring(L, "__newindex"); /* |[{<tex>},{<dimen>},{<dimen_m>},"__newindex"]| */ + lua_pushstring(L, setfunc); /* |[{<tex>},{<dimen>},{<dimen_m>},"__newindex","setdimen"]| */ + lua_gettable(L, -5); /* |[{<tex>},{<dimen>},{<dimen_m>},"__newindex",<tex.setdimen>]| */ + lua_settable(L, -3); /* |[{<tex>},{<dimen>},{<dimen_m>}]| */ + lua_setmetatable(L, -2); /* |[{<tex>},{<dimen>}]| : assign the metatable */ + lua_pop(L, 1); /* |[{<tex>}]| : clean the stack */ } +@ @c static const char *getS(lua_State * L, void *ud, size_t * size) { @@ -64,7 +70,8 @@ const char *getS(lua_State * L, void *ud, size_t * size) return ls->s; } -static void *my_luaalloc(void *ud, void *ptr, size_t osize, size_t nsize) +@ @c +void *my_luaalloc(void *ud, void *ptr, size_t osize, size_t nsize) { void *ret = NULL; (void) ud; /* for -Wunused */ @@ -72,10 +79,11 @@ static void *my_luaalloc(void *ud, void *ptr, size_t osize, size_t nsize) free(ptr); else ret = realloc(ptr, nsize); - luastate_bytes += (nsize - osize); + luastate_bytes += (int) (nsize - osize); return ret; } +@ @c static int my_luapanic(lua_State * L) { (void) L; /* to avoid warnings */ @@ -84,6 +92,7 @@ static int my_luapanic(lua_State * L) return 0; } +@ @c static const luaL_Reg lualibs[] = { {"", luaopen_base}, {"package", luaopen_package}, @@ -103,6 +112,7 @@ static const luaL_Reg lualibs[] = { }; +@ @c static void do_openlibs(lua_State * L) { const luaL_Reg *lib = lualibs; @@ -113,6 +123,52 @@ static void do_openlibs(lua_State * L) } } +@ @c +static int load_aux (lua_State *L, int status) { + if (status == 0) /* OK? */ + return 1; + else { + lua_pushnil(L); + lua_insert(L, -2); /* put before error message */ + return 2; /* return nil plus error message */ + } +} + +@ @c +static int luatex_loadfile (lua_State *L) { + const char *fname = luaL_optstring(L, 1, NULL); + if (!lua_only && !fname) { + if (interaction == batch_mode) { + lua_pushnil(L); + lua_pushstring(L, "reading from stdin is disabled in batch mode"); + return 2; /* return nil plus error message */ + } else { + tprint_nl("lua> "); + } + } + return load_aux(L, luaL_loadfile(L, fname)); +} + +@ @c +static int luatex_dofile (lua_State *L) { + const char *fname = luaL_optstring(L, 1, NULL); + int n = lua_gettop(L); + if (!lua_only && !fname) { + if (interaction == batch_mode) { + lua_pushnil(L); + lua_pushstring(L, "reading from stdin is disabled in batch mode"); + return 2; /* return nil plus error message */ + } else { + tprint_nl("lua> "); + } + } + if (luaL_loadfile(L, fname) != 0) lua_error(L); + lua_call(L, 0, LUA_MULTRET); + return lua_gettop(L) - n; +} + + +@ @c void luainterpreter(void) { lua_State *L; @@ -124,19 +180,21 @@ void luainterpreter(void) lua_atpanic(L, &my_luapanic); do_openlibs(L); /* does all the 'simple' libraries */ + + lua_pushcfunction(L,luatex_dofile); + lua_setglobal(L, "dofile"); + lua_pushcfunction(L,luatex_loadfile); + lua_setglobal(L, "loadfile"); - open_oslibext(L, safer_option); + luatex_md5_lua_open(L); - lua_getglobal(L, "package"); - lua_pushstring(L, ""); - lua_setfield(L, -2, "cpath"); - lua_pop(L, 1); /* pop the table */ + open_oslibext(L, safer_option); /* luasockets */ /* socket and mime are a bit tricky to open because - * they use a load-time dependency that has to be - * worked around for luatex, where the C module is - * loaded way before the lua module. + they use a load-time dependency that has to be + worked around for luatex, where the C module is + loaded way before the lua module. */ if (!nosocket_option) { lua_getglobal(L, "package"); @@ -166,7 +224,6 @@ void luainterpreter(void) /* our own libraries */ luaopen_ff(L); - luaopen_pdf(L); luaopen_tex(L); luaopen_token(L); luaopen_node(L); @@ -179,11 +236,22 @@ void luainterpreter(void) luaopen_lang(L); luaopen_mplib(L); - /* luaopen_img(L); */ + /* |luaopen_pdf(L);| */ + /* environment table at |LUA_ENVIRONINDEX| needs to load this way: */ + lua_pushcfunction(L, luaopen_pdf); + lua_pushstring(L, "pdf"); + lua_call(L, 1, 0); + + /* |luaopen_img(L);| */ lua_pushcfunction(L, luaopen_img); lua_pushstring(L, "img"); lua_call(L, 1, 0); + /* |luaopen_epdf(L);| */ + lua_pushcfunction(L, luaopen_epdf); + lua_pushstring(L, "epdf"); + lua_call(L, 1, 0); + lua_createtable(L, 0, 0); lua_setglobal(L, "texconfig"); @@ -209,6 +277,7 @@ void luainterpreter(void) Luas = L; } +@ @c int hide_lua_table(lua_State * L, const char *name) { int r = 0; @@ -221,6 +290,7 @@ int hide_lua_table(lua_State * L, const char *name) return r; } +@ @c void unhide_lua_table(lua_State * L, const char *name, int r) { lua_rawgeti(L, LUA_REGISTRYINDEX, r); @@ -228,6 +298,7 @@ void unhide_lua_table(lua_State * L, const char *name, int r) luaL_unref(L, LUA_REGISTRYINDEX, r); } +@ @c int hide_lua_value(lua_State * L, const char *name, const char *item) { int r = 0; @@ -241,6 +312,7 @@ int hide_lua_value(lua_State * L, const char *name, const char *item) return r; } +@ @c void unhide_lua_value(lua_State * L, const char *name, const char *item, int r) { lua_getglobal(L, name); @@ -252,7 +324,8 @@ void unhide_lua_value(lua_State * L, const char *name, const char *item, int r) } -static int lua_traceback(lua_State * L) +@ @c +int lua_traceback(lua_State * L) { lua_getfield(L, LUA_GLOBALSINDEX, "debug"); if (!lua_istable(L, -1)) { @@ -270,7 +343,8 @@ static int lua_traceback(lua_State * L) return 1; } -void luacall(int p, int nameptr) +@ @c +static void luacall(int p, int nameptr) { LoadS ls; int i, l; @@ -284,7 +358,7 @@ void luacall(int p, int nameptr) lua_active++; s = tokenlist_to_cstring(p, 1, &l); ls.s = s; - ls.size = l; + ls.size = (size_t) l; if (ls.size > 0) { if (nameptr > 0) { @@ -320,6 +394,16 @@ void luacall(int p, int nameptr) lua_active--; } +@ @c +void late_lua(PDF pdf, halfword p) +{ + (void) pdf; + expand_macros_in_tokenlist(p); /* sets |def_ref| */ + luacall(def_ref, late_lua_name(p)); + flush_list(def_ref); +} + +@ @c void luatokencall(int p, int nameptr) { LoadS ls; @@ -331,7 +415,7 @@ void luatokencall(int p, int nameptr) lua_active++; s = tokenlist_to_cstring(p, 1, &l); ls.s = s; - ls.size = l; + ls.size = (size_t) l; if (ls.size > 0) { if (nameptr > 0) { lua_id = tokenlist_to_cstring(nameptr, 1, &l); @@ -365,42 +449,45 @@ void luatokencall(int p, int nameptr) lua_active--; } - - -void luatex_load_init(int s, LoadS * ls) -{ - ls->s = (const char *) &(str_pool[str_start[s]]); - ls->size = str_start[s + 1] - str_start[s]; -} - - +@ @c lua_State *luatex_error(lua_State * L, int is_fatal) { - str_number s; const char *luaerr; size_t len = 0; char *err = NULL; if (lua_isstring(L, -1)) { luaerr = lua_tolstring(L, -1, &len); - err = (char *) xmalloc(len + 1); - len = snprintf(err, (len + 1), "%s", luaerr); + err = (char *) xmalloc((unsigned) (len + 1)); + len = (size_t) snprintf(err, (len + 1), "%s", luaerr); } if (is_fatal > 0) { - /* Normally a memory error from lua. - The pool may overflow during the maketexlstring(), but we + /* Normally a memory error from lua. + The pool may overflow during the |maketexlstring()|, but we are crashing anyway so we may as well abort on the pool size */ - s = maketexlstring(err, len); - lua_fatal_error(s); + lua_fatal_error(err); /* never reached */ xfree(err); lua_close(L); return (lua_State *) NULL; } else { - s = maketexlstring(err, len); - lua_norm_error(s); - flush_str(s); + lua_norm_error(err); xfree(err); return L; } } + +@ @c +void preset_environment(lua_State * L, const parm_struct * p) +{ + int i; + assert(L != NULL); + lua_newtable(L); /* t */ + for (i = 1, ++p; p->name != NULL; i++, p++) { + assert(i == p->idx); + lua_pushstring(L, p->name); /* k t */ + lua_pushinteger(L, p->idx); /* v k t */ + lua_settable(L, -3); /* t */ + } + lua_replace(L, LUA_ENVIRONINDEX); /* - */ +} diff --git a/Build/source/texk/web2c/luatexdir/lua/luatex-api.h b/Build/source/texk/web2c/luatexdir/lua/luatex-api.h new file mode 100644 index 00000000000..155fb6a3cb6 --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/lua/luatex-api.h @@ -0,0 +1,202 @@ +/* luatex-api.h + + Copyright 2006-2010 Taco Hoekwater <taco@luatex.org> + + This file is part of LuaTeX. + + LuaTeX is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your + option) any later version. + + LuaTeX is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. + + You should have received a copy of the GNU General Public License along + with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */ + +/* $Id: luatex-api.h 3558 2010-03-29 07:21:45Z taco $ */ + +#ifndef LUATEX_API_H +# define LUATEX_API_H 1 + +# include <stdlib.h> +# include <stdio.h> +# include <stdarg.h> +# include "lua51/lua.h" +# include "lua51/lauxlib.h" +# include "lua51/lualib.h" + +typedef struct LoadS { + const char *s; + size_t size; +} LoadS; + +extern lua_State *Luas; + +extern void make_table(lua_State * L, const char *tab, const char *getfunc, + const char *setfunc); + +extern int luac_main(int argc, char *argv[]); + +extern int luaopen_tex(lua_State * L); + +extern int luaopen_pdf(lua_State * L); + +# define LUA_TEXFILEHANDLE "TEXFILE*" + +extern int luaopen_texio(lua_State * L); + +extern int luaopen_lang(lua_State * L); + +extern lua_State *luatex_error(lua_State * L, int fatal); + +extern int luaopen_unicode(lua_State * L); +extern int luaopen_zip(lua_State * L); +extern int luaopen_lfs(lua_State * L); +extern int luaopen_lpeg(lua_State * L); +extern int luaopen_md5(lua_State * L); +extern int luatex_md5_lua_open(lua_State * L); + +extern int luaopen_zlib(lua_State * L); +extern int luaopen_gzip(lua_State * L); +extern int luaopen_ff(lua_State * L); +extern int luaopen_profiler(lua_State * L); + +extern int luaopen_socket_core(lua_State * L); +extern int luaopen_mime_core(lua_State * L); +extern void luatex_socketlua_open(lua_State * L); + +extern int luaopen_img(lua_State * L); +extern int l_new_image(lua_State * L); +extern int luaopen_epdf(lua_State * L); +extern int luaopen_mplib(lua_State * L); + +extern void open_oslibext(lua_State * L, int safer_option); + +extern void initfilecallbackids(int max); +extern void setinputfilecallbackid(int n, int i); +extern void setreadfilecallbackid(int n, int i); +extern int getinputfilecallbackid(int n); +extern int getreadfilecallbackid(int n); + +extern void lua_initialize(int ac, char **av); + +extern int luaopen_kpse(lua_State * L); + +extern int luaopen_callback(lua_State * L); + +extern int luaopen_lua(lua_State * L, char *fname); + +extern int luaopen_stats(lua_State * L); + +extern int luaopen_font(lua_State * L); +extern int font_to_lua(lua_State * L, int f); +extern int font_from_lua(lua_State * L, int f); /* return is boolean */ + +extern int luaopen_token(lua_State * L); +extern void tokenlist_to_lua(lua_State * L, int p); +extern void tokenlist_to_luastring(lua_State * L, int p); +extern int tokenlist_from_lua(lua_State * L); + +extern void lua_nodelib_push(lua_State * L); +extern int nodelib_getdir(lua_State * L, int n); + +extern int luaopen_node(lua_State * L); +extern void nodelist_to_lua(lua_State * L, int n); +extern int nodelist_from_lua(lua_State * L); + +extern int dimen_to_number(lua_State * L, const char *s); + +extern int get_command_id(const char *s); + +extern void dump_luac_registers(void); + +extern void undump_luac_registers(void); + +extern int lua_only; + +extern void unhide_lua_table(lua_State * lua, const char *name, int r); +extern int hide_lua_table(lua_State * lua, const char *name); + +extern void unhide_lua_value(lua_State * lua, const char *name, + const char *item, int r); +extern int hide_lua_value(lua_State * lua, const char *name, const char *item); + +typedef struct command_item_ { + const char *cmd_name; + int command_offset; + const char **commands; +} command_item; + +extern command_item command_names[]; +extern int callback_callbacks_id; + +extern void luainterpreter(void); + +extern int luabytecode_max; +extern unsigned int luabytecode_bytes; +extern int luastate_bytes; + +extern int callback_count; +extern int saved_callback_count; + +extern const char *ptexbanner; + +/* luastuff.h */ + +typedef struct { + const char *name; /* parameter name */ + int idx; /* index within img_parms array */ +} parm_struct; + +extern void preset_environment(lua_State * L, const parm_struct * p); + +extern char *startup_filename; +extern int safer_option; +extern int nosocket_option; + +extern char *last_source_name; +extern int last_lineno; + +extern int program_name_set; /* in lkpselib.c */ + +/* for topenin() */ +extern char **argv; +extern int argc; + + +extern int loader_C_luatex(lua_State * L, const char *name, + const char *filename); +extern int loader_Call_luatex (lua_State *L, const char *name, + const char *filename); + + +extern void init_tex_table(lua_State * L); + +extern int tex_table_id; +extern int pdf_table_id; +extern int token_table_id; +extern int node_table_id; +extern int main_initialize(void); + +extern int do_run_callback(int special, const char *values, va_list vl); +extern int lua_traceback(lua_State * L); + +extern int luainit; + +extern char *luanames[]; + +extern int ff_get_ttc_index(char *ffname, char *psname); /* luafontloader/src/luafflib.c */ +extern int ff_createcff(char *, unsigned char **, int *); /* luafontloader/src/luafflib.c */ + +extern char *FindResourceTtfFont(char *filename, char *fontname); /* luafontloader/fontforge/fontforge/macbinary.c */ + +extern char charsetstr[]; /* from mpdir/psout.w */ + +extern char **environ; + + +#endif diff --git a/Build/source/texk/web2c/luatexdir/lua/luatex.c b/Build/source/texk/web2c/luatexdir/lua/luatex.c deleted file mode 100644 index 88903fe338b..00000000000 --- a/Build/source/texk/web2c/luatexdir/lua/luatex.c +++ /dev/null @@ -1,364 +0,0 @@ -/* luatex.c - - Copyright 2006-2008 Taco Hoekwater <taco@luatex.org> - - This file is part of LuaTeX. - - LuaTeX is free software; you can redistribute it and/or modify it under - the terms of the GNU General Public License as published by the Free - Software Foundation; either version 2 of the License, or (at your - option) any later version. - - LuaTeX is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU General Public License along - with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */ - -#include "luatex-api.h" -#include <ptexlib.h> -#include <zlib.h> - -static const char _svn_version[] = - "$Id: luatex.c 2599 2009-06-25 10:35:26Z taco $ $URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.40.6/source/texk/web2c/luatexdir/lua/luatex.c $"; - -/* do this aleph stuff here, for now */ - -void b_test_in(void) -{ - if (program_name_set) { - string fname = kpse_find_file((char *) (nameoffile + 1), - kpse_program_binary_format, true); - if (fname) { - libcfree(nameoffile); - nameoffile = xmalloc(2 + strlen(fname)); - namelength = strlen(fname); - strcpy((char *) nameoffile + 1, fname); - } else { - libcfree(nameoffile); - nameoffile = xmalloc(2); - namelength = 0; - nameoffile[0] = 0; - nameoffile[1] = 0; - } - } -} - - -int **ocp_tables; -static int ocp_entries = 0; - -void -allocate_ocp_table (int ocp_number, int ocp_size) -{ - int i; - if (ocp_entries == 0) { - ocp_tables = (int **) xmalloc(256 * sizeof(int **)); - ocp_entries = 256; - } else if ((ocp_number == 256) && (ocp_entries == 256)) { - ocp_tables = xrealloc(ocp_tables, 65536); - ocp_entries = 65536; - } - ocp_tables[ocp_number] = (int *) xmalloc((1 + ocp_size) * sizeof(int)); - ocp_tables[ocp_number][0] = ocp_size; - for (i = 1; i <= ocp_size; i++) { - ocp_tables[ocp_number][i] = 0; - } -} - -void -dump_ocp_table (int ocp_number) -{ - dump_things(ocp_tables[ocp_number][0], ocp_tables[ocp_number][0] + 1); -} - -void -undump_ocp_table (int ocp_number) -{ - int sizeword; - if (ocp_entries == 0) { - ocp_tables = (int **) xmalloc(256 * sizeof(int **)); - ocp_entries = 256; - } else if ((ocp_number == 256) && (ocp_entries == 256)) { - ocp_tables = xrealloc(ocp_tables, 65536); - ocp_entries = 65536; - } - undump_things(sizeword, 1); - ocp_tables[ocp_number] = (int *) xmalloc((1 + sizeword) * sizeof(int)); - ocp_tables[ocp_number][0] = sizeword; - undump_things(ocp_tables[ocp_number][1], sizeword); -} - - -void -run_external_ocp (string external_ocp_name) -{ - char *in_file_name; - char *out_file_name; - FILE *in_file; - FILE *out_file; - int in_file_fd; - int out_file_fd; - char command_line[400]; - int i; - unsigned c; - int c_in; -#ifdef WIN32 - char *tempenv; - -# define null_string(s) ((s == NULL) || (*s == '\0')) - - tempenv = getenv("TMPDIR"); - if (null_string(tempenv)) - tempenv = getenv("TEMP"); - if (null_string(tempenv)) - tempenv = getenv("TMP"); - if (null_string(tempenv)) - tempenv = "c:/tmp"; /* "/tmp" is not good if we are on a CD-ROM */ - in_file_name = concat(tempenv, "/__aleph__in__XXXXXX"); - mktemp(in_file_name); - in_file = fopen(in_file_name, FOPEN_WBIN_MODE); -#else - in_file_name = strdup("/tmp/__aleph__in__XXXXXX"); - in_file_fd = mkstemp(in_file_name); - in_file = fdopen(in_file_fd, FOPEN_WBIN_MODE); -#endif /* WIN32 */ - - - for (i = 1; i <= otp_input_end; i++) { - c = otp_input_buf[i]; - if (c > 0xffff) { - fprintf(stderr, "Aleph does not currently support 31-bit chars\n"); - exit(1); - } - if (c > 0x4000000) { - fputc(0xfc | ((c >> 30) & 0x1), in_file); - fputc(0x80 | ((c >> 24) & 0x3f), in_file); - fputc(0x80 | ((c >> 18) & 0x3f), in_file); - fputc(0x80 | ((c >> 12) & 0x3f), in_file); - fputc(0x80 | ((c >> 6) & 0x3f), in_file); - fputc(0x80 | (c & 0x3f), in_file); - } else if (c > 0x200000) { - fputc(0xf8 | ((c >> 24) & 0x3), in_file); - fputc(0x80 | ((c >> 18) & 0x3f), in_file); - fputc(0x80 | ((c >> 12) & 0x3f), in_file); - fputc(0x80 | ((c >> 6) & 0x3f), in_file); - fputc(0x80 | (c & 0x3f), in_file); - } else if (c > 0x10000) { - fputc(0xf0 | ((c >> 18) & 0x7), in_file); - fputc(0x80 | ((c >> 12) & 0x3f), in_file); - fputc(0x80 | ((c >> 6) & 0x3f), in_file); - fputc(0x80 | (c & 0x3f), in_file); - } else if (c > 0x800) { - fputc(0xe0 | ((c >> 12) & 0xf), in_file); - fputc(0x80 | ((c >> 6) & 0x3f), in_file); - fputc(0x80 | (c & 0x3f), in_file); - } else if (c > 0x80) { - fputc(0xc0 | ((c >> 6) & 0x1f), in_file); - fputc(0x80 | (c & 0x3f), in_file); - } else { - fputc(c & 0x7f, in_file); - } - } - fclose(in_file); - -#define advance_cin if ((c_in = fgetc(out_file)) == -1) { \ - fprintf(stderr, "File contains bad char\n"); \ - goto end_of_while; \ - } - -#ifdef WIN32 - out_file_name = concat(tempenv, "/__aleph__out__XXXXXX"); - mktemp(out_file_name); - out_file = fopen(out_file_name, FOPEN_RBIN_MODE); -#else - out_file_name = strdup("/tmp/__aleph__out__XXXXXX"); - out_file_fd = mkstemp(out_file_name); - out_file = fdopen(out_file_fd, FOPEN_RBIN_MODE); -#endif - - sprintf(command_line, "%s <%s >%s\n", - external_ocp_name + 1, in_file_name, out_file_name); - system(command_line); - otp_output_end = 0; - otp_output_buf[otp_output_end] = 0; - while ((c_in = fgetc(out_file)) != -1) { - if (c_in >= 0xfc) { - c = (c_in & 0x1) << 30; - advance_cin; - c |= (c_in & 0x3f) << 24; - advance_cin; - c |= (c_in & 0x3f) << 18; - advance_cin; - c |= (c_in & 0x3f) << 12; - advance_cin; - c |= (c_in & 0x3f) << 6; - advance_cin; - c |= c_in & 0x3f; - } else if (c_in >= 0xf8) { - c = (c_in & 0x3) << 24; - advance_cin; - c |= (c_in & 0x3f) << 18; - advance_cin; - c |= (c_in & 0x3f) << 12; - advance_cin; - c |= (c_in & 0x3f) << 6; - advance_cin; - c |= c_in & 0x3f; - } else if (c_in >= 0xf0) { - c = (c_in & 0x7) << 18; - advance_cin; - c |= (c_in & 0x3f) << 12; - advance_cin; - c |= (c_in & 0x3f) << 6; - advance_cin; - c |= c_in & 0x3f; - } else if (c_in >= 0xe0) { - c = (c_in & 0xf) << 12; - advance_cin; - c |= (c_in & 0x3f) << 6; - advance_cin; - c |= c_in & 0x3f; - } else if (c_in >= 0x80) { - c = (c_in & 0x1f) << 6; - advance_cin; - c |= c_in & 0x3f; - } else { - c = c_in & 0x7f; - } - otp_output_buf[++otp_output_end] = c; - } - fclose(out_file); - - end_of_while: - remove(in_file_name); - remove(out_file_name); -} - -/* Read and write dump files through zlib */ - -/* Earlier versions recast *f from FILE * to gzFile, but there is - * no guarantee that these have the same size, so a static variable - * is needed. - */ - -static gzFile gz_fmtfile = NULL; - -void do_zdump(char *p, int item_size, int nitems, FILE * out_file) -{ - int err; - (void) out_file; - if (nitems == 0) - return; - if (gzwrite(gz_fmtfile, (void *) p, item_size * nitems) != - item_size * nitems) { - fprintf(stderr, "! Could not write %d %d-byte item(s): %s.\n", nitems, - item_size, gzerror(gz_fmtfile, &err)); - uexit(1); - } -} - -void do_zundump(char *p, int item_size, int nitems, FILE * in_file) -{ - int err; - (void) in_file; - if (nitems == 0) - return; - if (gzread(gz_fmtfile, (void *) p, item_size * nitems) <= 0) { - fprintf(stderr, "Could not undump %d %d-byte item(s): %s.\n", - nitems, item_size, gzerror(gz_fmtfile, &err)); - uexit(1); - } -} - -#define COMPRESSION "R3" - -boolean zopen_w_input(FILE ** f, int format, const_string fopen_mode) -{ - int callbackid; - int res; - char *fnam; - callbackid = callback_defined(find_format_file_callback); - if (callbackid > 0) { - res = run_callback(callbackid, "S->S", (nameoffile + 1), &fnam); - if (res && fnam && strlen(fnam) > 0) { - xfree(nameoffile); - nameoffile = xmalloc(strlen(fnam) + 2); - memcpy((nameoffile + 1), fnam, strlen(fnam)); - *(nameoffile + strlen(fnam) + 1) = 0; - *f = xfopen(fnam, fopen_mode); - if (*f == NULL) { - return 0; - } - } else { - return 0; - } - } else { - res = open_input(f, format, fopen_mode); - } - if (res) { - gz_fmtfile = gzdopen(fileno(*f), "rb" COMPRESSION); - } - return res; -} - -boolean zopen_w_output(FILE ** f, const_string fopen_mode) -{ - int res = 1; - if (luainit) { - *f = fopen((const_string) (nameoffile + 1), fopen_mode); - if (*f == NULL) { - return 0; - } - } else { - res = open_output(f, fopen_mode); - } - if (res) { - gz_fmtfile = gzdopen(fileno(*f), "wb" COMPRESSION); - } - return res; -} - -void zwclose(FILE * f) -{ - (void) f; - gzclose(gz_fmtfile); -} - -/* create the dvi or pdf file */ - -int open_outfile(FILE ** f, const char *name, const char *mode) -{ - FILE *res; - res = fopen(name, mode); - if (res != NULL) { - *f = res; - return 1; - } - return 0; -} - - -/* the caller sets tfm_buffer=NULL and tfm_size=0 */ - -int readbinfile(FILE * f, unsigned char **tfm_buffer, integer * tfm_size) -{ - void *buf; - int size; - if (fseek(f, 0, SEEK_END) == 0) { - size = ftell(f); - if (size > 0) { - buf = xmalloc(size); - if (fseek(f, 0, SEEK_SET) == 0) { - if (fread((void *) buf, size, 1, f) == 1) { - *tfm_buffer = (unsigned char *) buf; - *tfm_size = (integer) size; - return 1; - } - } - } - } /* seek failed, or zero-sized file */ - return 0; -} diff --git a/Build/source/texk/web2c/luatexdir/lua/luatoken.c b/Build/source/texk/web2c/luatexdir/lua/luatoken.w index 628dbf21478..7a96fcd1a11 100644 --- a/Build/source/texk/web2c/luatexdir/lua/luatoken.c +++ b/Build/source/texk/web2c/luatexdir/lua/luatoken.w @@ -1,31 +1,31 @@ -/* luatoken.c - - Copyright 2006-2008 Taco Hoekwater <taco@luatex.org> +% luatoken.w +% +% Copyright 2006-2010 Taco Hoekwater <taco@@luatex.org> - This file is part of LuaTeX. +% This file is part of LuaTeX. - LuaTeX is free software; you can redistribute it and/or modify it under - the terms of the GNU General Public License as published by the Free - Software Foundation; either version 2 of the License, or (at your - option) any later version. +% LuaTeX is free software; you can redistribute it and/or modify it under +% the terms of the GNU General Public License as published by the Free +% Software Foundation; either version 2 of the License, or (at your +% option) any later version. - LuaTeX is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. +% LuaTeX is distributed in the hope that it will be useful, but WITHOUT +% ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +% FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +% License for more details. - You should have received a copy of the GNU General Public License along - with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */ +% You should have received a copy of the GNU General Public License along +% with LuaTeX; if not, see <http://www.gnu.org/licenses/>. -#include "luatex-api.h" -#include <ptexlib.h> - -#include "tokens.h" -#include "commands.h" +@ @c +#include "lua/luatex-api.h" +#include "ptexlib.h" static const char _svn_version[] = - "$Id: luatoken.c 2271 2009-04-12 23:42:21Z oneiros $ $URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.40.6/source/texk/web2c/luatexdir/lua/luatoken.c $"; + "$Id: luatoken.w 3583 2010-04-02 17:40:44Z hhenkel $ " +"$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/lua/luatoken.w $"; +@ @c command_item command_names[] = { {"relax", relax_cmd, NULL}, {"left_brace", left_brace_cmd, NULL}, @@ -177,6 +177,7 @@ command_item command_names[] = { }; +@ @c int get_command_id(const char *s) { int i; @@ -191,24 +192,25 @@ int get_command_id(const char *s) return cmd; } +@ @c static int get_cur_cmd(lua_State * L) { int r = 0; - int len = lua_objlen(L, -1); + size_t len = lua_objlen(L, -1); cur_cs = 0; if (len == 3 || len == 2) { r = 1; lua_rawgeti(L, -1, 1); - cur_cmd = lua_tointeger(L, -1); + cur_cmd = (int) lua_tointeger(L, -1); lua_rawgeti(L, -2, 2); - cur_chr = lua_tointeger(L, -1); + cur_chr = (halfword) lua_tointeger(L, -1); if (len == 3) { lua_rawgeti(L, -3, 3); - cur_cs = lua_tointeger(L, -1); + cur_cs = (halfword) lua_tointeger(L, -1); } - lua_pop(L, len); + lua_pop(L, (int) len); if (cur_cs == 0) - cur_tok = (cur_cmd * string_offset) + cur_chr; + cur_tok = token_val(cur_cmd, cur_chr); else cur_tok = cs_token_flag + cur_cs; } @@ -216,23 +218,24 @@ static int get_cur_cmd(lua_State * L) } +@ @c static int token_from_lua(lua_State * L) { int cmd, chr; int cs = 0; - int len = lua_objlen(L, -1); + size_t len = lua_objlen(L, -1); if (len == 3 || len == 2) { lua_rawgeti(L, -1, 1); - cmd = lua_tointeger(L, -1); + cmd = (int) lua_tointeger(L, -1); lua_rawgeti(L, -2, 2); - chr = lua_tointeger(L, -1); + chr = (int) lua_tointeger(L, -1); if (len == 3) { lua_rawgeti(L, -3, 3); - cs = lua_tointeger(L, -1); + cs = (int) lua_tointeger(L, -1); } - lua_pop(L, len); + lua_pop(L, (int) len); if (cs == 0) { - return (cmd * string_offset) + chr; + return token_val(cmd, chr); } else { return cs_token_flag + cs; } @@ -240,12 +243,13 @@ static int token_from_lua(lua_State * L) return -1; } +@ @c static int get_cur_cs(lua_State * L) { const char *s; unsigned j; size_t l; - integer cs; + int cs; int save_nncs; int ret; ret = 0; @@ -254,17 +258,17 @@ static int get_cur_cs(lua_State * L) if (lua_isstring(L, -1)) { s = lua_tolstring(L, -1, &l); if (l > 0) { - if ((int) (last + l) > buf_size) - check_buffer_overflow(last + l); + if ((last + (int) l) > buf_size) + check_buffer_overflow((last + (int) l)); for (j = 0; j < l; j++) { - buffer[last + 1 + j] = *s++; + buffer[(unsigned) last + 1 + j] = (packed_ASCII_code) * s++; } save_nncs = no_new_control_sequence; no_new_control_sequence = false; - cs = id_lookup((last + 1), l); + cs = id_lookup((last + 1), (int) l); cur_tok = cs_token_flag + cs; - cur_cmd = zget_eq_type(cs); - cur_chr = zget_equiv(cs); + cur_cmd = eq_type(cs); + cur_chr = equiv(cs); no_new_control_sequence = save_nncs; ret = 1; } @@ -273,232 +277,46 @@ static int get_cur_cs(lua_State * L) return ret; } - -#define make_room(a) \ - if ((i+a+1)>alloci) { \ - ret = xrealloc(ret,alloci+64); \ - alloci = alloci + 64; \ - } - - -#define append_i_byte(a) ret[i++] = a - -#define Print_char(a) make_room(1); append_i_byte(a) - -#define Print_uchar(s) { \ - make_room(4); \ - if (s<=0x7F) { \ - append_i_byte(s); \ - } else if (s<=0x7FF) { \ - append_i_byte(0xC0 + (s / 0x40)); \ - append_i_byte(0x80 + (s % 0x40)); \ - } else if (s<=0xFFFF) { \ - append_i_byte(0xE0 + (s / 0x1000)); \ - append_i_byte(0x80 + ((s % 0x1000) / 0x40)); \ - append_i_byte(0x80 + ((s % 0x1000) % 0x40)); \ - } else if (s>=0x110000) { \ - append_i_byte(s-0x11000); \ - } else { \ - append_i_byte(0xF0 + (s / 0x40000)); \ - append_i_byte(0x80 + ((s % 0x40000) / 0x1000)); \ - append_i_byte(0x80 + (((s % 0x40000) % 0x1000) / 0x40)); \ - append_i_byte(0x80 + (((s % 0x40000) % 0x1000) % 0x40)); \ - } } - - -#define Print_esc(b) { \ - const char *v = b; \ - if (e>0 && e<string_offset) { \ - Print_uchar (e); Print_uchar (e); \ - } \ - while (*v) { Print_char(*v); v++; } \ - } - -#define single_letter(a) (length(a)==1)|| \ - ((length(a)==4)&&(str_pool[str_start_macro(a)]>=0xF0))|| \ - ((length(a)==3)&&(str_pool[str_start_macro(a)]>=0xE0))|| \ - ((length(a)==2)&&(str_pool[str_start_macro(a)]>=0xC0)) - -#define is_active_cs(a) (length(a)>3 && \ - (str_pool[str_start_macro(a)] == 0xEF) && \ - (str_pool[str_start_macro(a)+1] == 0xBF) && \ - (str_pool[str_start_macro(a)+2] == 0xBF)) - -#define is_cat_letter(a) \ - (get_char_cat_code(pool_to_unichar(str_start_macro(a))) == 11) - -static int null_cs = 0; -static int eqtb_size = 0; - -/* 2,720,652 */ -char *tokenlist_to_cstring(int pp, int inhibit_par, int *siz) -{ - register integer p, c, m; - integer q; - integer infop; - char *s; - int e; - char *ret; - int match_chr = '#'; - int n = '0'; - int alloci = 1024; - int i = 0; - p = pp; - if (p == null || link(p) == null) { - if (siz != NULL) - *siz = 0; - return NULL; - } - ret = xmalloc(alloci); - p = link(p); /* skip refcount */ - if (null_cs == 0) { - null_cs = get_nullcs(); - eqtb_size = get_eqtb_size(); - } - e = get_escape_char(); - while (p != null) { - if (p < fix_mem_min || p > fix_mem_end) { - Print_esc("CLOBBERED."); - break; - } - infop = info(p); - if (infop >= cs_token_flag) { - if (!(inhibit_par && infop == par_token)) { - q = infop - cs_token_flag; - if (q < hash_base) { - if (q == null_cs) { - /* Print_esc("csname"); Print_esc("endcsname"); */ - } - } else if ((q >= static_undefined_control_sequence) - && ((q <= eqtb_size) - || (q > eqtb_size + hash_extra))) { - Print_esc("IMPOSSIBLE."); - } else if ((zget_cs_text(q) < 0) - || (zget_cs_text(q) >= str_ptr)) { - Print_esc("NONEXISTENT."); - } else { - str_number txt = zget_cs_text(q); - s = makecstring(txt); - if (is_active_cs(txt)) { - s = s + 3; - while (*s) { - Print_char(*s); - s++; - } - } else { - Print_uchar(e); - while (*s) { - Print_char(*s); - s++; - } - if ((!single_letter(zget_cs_text(q))) - || is_cat_letter(zget_cs_text(q))) { - Print_char(' '); - } - } - } - } - } else { - if (infop < 0) { - Print_esc("BAD."); - } else { - m = infop >> string_offset_bits; - c = infop & (string_offset - 1); - switch (m) { - case 10: - case 11: - case 12: - case 1: - case 2: - case 3: - case 4: - case 7: - case 8: - Print_uchar(c); - break; - case 6: - /* Print_uchar(c); */ - Print_uchar(c); - break; - case 5: - Print_uchar(match_chr); - if (c <= 9) { - Print_char(c + '0'); - } else { - Print_char('!'); - xfree(ret); - return NULL; - } - break; - case 13: - match_chr = c; - Print_uchar(c); - n++; - Print_char(n); - if (n > '9') { - xfree(ret); - return NULL; - } - break; - case 14: - if (c == 0) { - Print_char('-'); - Print_char('>'); - } - break; - default: - Print_esc("BAD."); - break; - } - } - } - p = link(p); - } - ret[i] = 0; - if (siz != NULL) - *siz = i; - return ret; -} - - +@ @c void tokenlist_to_lua(lua_State * L, int p) { int cmd, chr, cs; int v; int i = 1; v = p; - while (v != null && v < fix_mem_end) { + while (v != null && v < (int) fix_mem_end) { i++; - v = link(v); + v = token_link(v); } i = 1; lua_createtable(L, i, 0); - while (p != null && p < fix_mem_end) { - if (info(p) >= cs_token_flag) { - cs = info(p) - cs_token_flag; - cmd = zget_eq_type(cs); - chr = zget_equiv(cs); + while (p != null && p < (int) fix_mem_end) { + if (token_info(p) >= cs_token_flag) { + cs = token_info(p) - cs_token_flag; + cmd = eq_type(cs); + chr = equiv(cs); make_token_table(L, cmd, chr, cs); } else { - cmd = info(p) / string_offset; - chr = info(p) % string_offset; + cmd = token_cmd(token_info(p)); + chr = token_chr(token_info(p)); make_token_table(L, cmd, chr, 0); } lua_rawseti(L, -2, i++); - p = link(p); + p = token_link(p); } } - +@ @c void tokenlist_to_luastring(lua_State * L, int p) { int l; char *s; s = tokenlist_to_cstring(p, 1, &l); - lua_pushlstring(L, s, l); + lua_pushlstring(L, s, (size_t) l); } +@ @c int tokenlist_from_lua(lua_State * L) { const char *s; @@ -506,14 +324,14 @@ int tokenlist_from_lua(lua_State * L) size_t i, j; halfword p, q, r; r = get_avail(); - info(r) = 0; /* ref count */ - link(r) = null; + token_info(r) = 0; /* ref count */ + token_link(r) = null; p = r; if (lua_istable(L, -1)) { j = lua_objlen(L, -1); if (j > 0) { for (i = 1; i <= j; i++) { - lua_rawgeti(L, -1, i); + lua_rawgeti(L, -1, (int) i); tok = token_from_lua(L); if (tok >= 0) { store_new_token(tok); @@ -526,9 +344,11 @@ int tokenlist_from_lua(lua_State * L) s = lua_tolstring(L, -1, &j); for (i = 0; i < j; i++) { if (s[i] == 32) { - tok = (10 * string_offset) + s[i]; + tok = token_val(10, s[i]); } else { - tok = (12 * string_offset) + s[i]; + int j = (int) str2uni((const unsigned char *) (s + i)); + i = i + (size_t) (utf8_size(j) - 1); + tok = token_val(12, j); } store_new_token(tok); } @@ -539,7 +359,8 @@ int tokenlist_from_lua(lua_State * L) } } -void do_get_token_lua(integer callback_id) +@ @c +void do_get_token_lua(int callback_id) { lua_State *L = Luas; while (1) { @@ -556,8 +377,8 @@ void do_get_token_lua(integer callback_id) if (lua_istable(L, -1)) { lua_rawgeti(L, -1, 1); if (lua_istable(L, -1)) { /* container, result, result[1] */ - integer p, q, r; - int i, j; + int p, q, r; + size_t i, j; lua_pop(L, 1); /* container, result */ /* build a token list */ r = get_avail(); @@ -565,7 +386,7 @@ void do_get_token_lua(integer callback_id) j = lua_objlen(L, -1); if (j > 0) { for (i = 1; i <= j; i++) { - lua_rawgeti(L, -1, i); + lua_rawgeti(L, -1, (int) i); if (get_cur_cmd(L) || get_cur_cs(L)) { store_new_token(cur_tok); } @@ -573,7 +394,7 @@ void do_get_token_lua(integer callback_id) } } if (p != r) { - p = link(r); + p = token_link(r); free_avail(r); begin_token_list(p, inserted); cur_input.nofilter_field = true; diff --git a/Build/source/texk/web2c/luatexdir/lua/texluac.c b/Build/source/texk/web2c/luatexdir/lua/texluac.w index c994785bd08..108e27864dc 100644 --- a/Build/source/texk/web2c/luatexdir/lua/texluac.c +++ b/Build/source/texk/web2c/luatexdir/lua/texluac.w @@ -1,31 +1,30 @@ -/* texlua.c - -* Copyright (C) 1994-2007 Lua.org, PUC-Rio. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining -* a copy of this software and associated documentation files (the -* "Software"), to deal in the Software without restriction, including -* without limitation the rights to use, copy, modify, merge, publish, -* distribute, sublicense, and/or sell copies of the Software, and to -* permit persons to whom the Software is furnished to do so, subject to -* the following conditions: +% texlua.w +% +% Copyright (C) 1994-2007 Lua.org, PUC-Rio. All rights reserved. +% Copyright 2006-2010 Taco Hoekwater <taco@@luatex.org> +% +% Permission is hereby granted, free of charge, to any person obtaining +% a copy of this software and associated documentation files (the +% "Software"), to deal in the Software without restriction, including +% without limitation the rights to use, copy, modify, merge, publish, +% distribute, sublicense, and/or sell copies of the Software, and to +% permit persons to whom the Software is furnished to do so, subject to +% the following conditions: * -* The above copyright notice and this permission notice shall be -* included in all copies or substantial portions of the Software. +% The above copyright notice and this permission notice shall be +% included in all copies or substantial portions of the Software. * -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - Copyright 2006-2008 Taco Hoekwater <taco@luatex.org> +% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +% EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +% MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +% IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +% CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +% TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +% SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - This file is part of LuaTeX. -*/ +% This file is part of LuaTeX. +@ @c #include <errno.h> #include <stdio.h> #include <stdlib.h> @@ -34,37 +33,42 @@ #define luac_c #define LUA_CORE -#include <../lua51/lua.h> -#include <../lua51/lauxlib.h> +#include "lua51/lua.h" +#include "lua51/lauxlib.h" -#include <../lua51/ldo.h> -#include <../lua51/lfunc.h> -#include <../lua51/lmem.h> -#include <../lua51/lobject.h> -#include <../lua51/lopcodes.h> -#include <../lua51/lstring.h> -#include <../lua51/lundump.h> - -#include "luatex-api.h" +#include "lua51/ldo.h" +#include "lua51/lfunc.h" +#include "lua51/lmem.h" +#include "lua51/lobject.h" +#include "lua51/lopcodes.h" +#include "lua51/lstring.h" +#include "lua51/lundump.h" +@ @c static const char _svn_version[] = - "$Id: texluac.c 2271 2009-04-12 23:42:21Z oneiros $ $URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.40.6/source/texk/web2c/luatexdir/lua/texluac.c $"; + "$Id: texluac.w 3583 2010-04-02 17:40:44Z hhenkel $ $URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/lua/texluac.w $"; +@ @c #define PROGNAME "texluac" /* default program name */ #define OUTPUT PROGNAME ".out" /* default output file */ static int dumping = 1; /* dump bytecodes? */ static int stripping = 0; /* strip debug information? */ static char Output[] = { OUTPUT }; /* default output file name */ + static const char *output = Output; /* actual output file name */ static const char *progname = PROGNAME; /* actual program name */ +@ @c +__attribute__ ((noreturn)) static void fatal(const char *message) { fprintf(stderr, "%s: %s\n", progname, message); exit(EXIT_FAILURE); } +@ @c +__attribute__ ((noreturn)) static void cannot(const char *what) { fprintf(stderr, "%s: cannot %s %s: %s\n", progname, what, output, @@ -72,6 +76,8 @@ static void cannot(const char *what) exit(EXIT_FAILURE); } +@ @c +__attribute__ ((noreturn)) static void usage(const char *message) { if (*message == '-') @@ -91,6 +97,7 @@ static void usage(const char *message) exit(EXIT_FAILURE); } +@ @c #define IS(s) (strcmp(argv[i],s)==0) static int doargs(int argc, char *argv[]) @@ -140,6 +147,7 @@ static int doargs(int argc, char *argv[]) return i; } +@ @c #define toproto(L,i) (clvalue(L->top+(i))->l.p) static const Proto *combine(lua_State * L, int n) @@ -154,9 +162,9 @@ static const Proto *combine(lua_State * L, int n) f->source = luaS_newliteral(L, "=(" PROGNAME ")"); f->maxstacksize = 1; pc = 2 * n + 1; - f->code = luaM_newvector(L, pc, Instruction); + f->code = luaM_newvector(L, (unsigned long) pc, Instruction); f->sizecode = pc; - f->p = luaM_newvector(L, n, Proto *); + f->p = luaM_newvector(L, (unsigned long) n, Proto *); f->sizep = n; pc = 0; for (i = 0; i < n; i++) { @@ -169,17 +177,20 @@ static const Proto *combine(lua_State * L, int n) } } +@ @c static int writer(lua_State * L, const void *p, size_t size, void *u) { UNUSED(L); return (fwrite(p, size, 1, (FILE *) u) != 1) && (size != 0); } +@ @c struct Smain { int argc; char **argv; }; +@ @c static int pmain(lua_State * L) { struct Smain *s = (struct Smain *) lua_touserdata(L, 1); @@ -210,6 +221,7 @@ static int pmain(lua_State * L) return 0; } +@ @c int luac_main(int argc, char *argv[]) { lua_State *L; |