summaryrefslogtreecommitdiff
path: root/Build/source/texk/web2c/luatexdir/lua
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/texk/web2c/luatexdir/lua')
-rw-r--r--Build/source/texk/web2c/luatexdir/lua/helpers.c29
-rw-r--r--Build/source/texk/web2c/luatexdir/lua/helpers.w26
-rw-r--r--Build/source/texk/web2c/luatexdir/lua/llfslibext.c171
-rw-r--r--Build/source/texk/web2c/luatexdir/lua/lpdfelib.c1666
-rw-r--r--Build/source/texk/web2c/luatexdir/lua/lpdfscannerlib.c1110
-rw-r--r--Build/source/texk/web2c/luatexdir/lua/luainit.c (renamed from Build/source/texk/web2c/luatexdir/lua/luainit.w)538
-rw-r--r--Build/source/texk/web2c/luatexdir/lua/luanode.c (renamed from Build/source/texk/web2c/luatexdir/lua/luanode.w)252
-rw-r--r--Build/source/texk/web2c/luatexdir/lua/luastuff.c (renamed from Build/source/texk/web2c/luatexdir/lua/luastuff.w)451
-rw-r--r--Build/source/texk/web2c/luatexdir/lua/luatoken.c585
-rw-r--r--Build/source/texk/web2c/luatexdir/lua/luatoken.w424
-rw-r--r--Build/source/texk/web2c/luatexdir/lua/mplibstuff.c115
-rw-r--r--Build/source/texk/web2c/luatexdir/lua/mplibstuff.w93
-rw-r--r--Build/source/texk/web2c/luatexdir/lua/texluac.c532
-rw-r--r--Build/source/texk/web2c/luatexdir/lua/texluac.w495
-rw-r--r--Build/source/texk/web2c/luatexdir/lua/texluajitc.c650
-rw-r--r--Build/source/texk/web2c/luatexdir/lua/texluajitc.w575
16 files changed, 5368 insertions, 2344 deletions
diff --git a/Build/source/texk/web2c/luatexdir/lua/helpers.c b/Build/source/texk/web2c/luatexdir/lua/helpers.c
new file mode 100644
index 00000000000..e7be7a2c2fe
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/lua/helpers.c
@@ -0,0 +1,29 @@
+/*
+
+helpers.w
+
+Copyright 2017 LuaTeX team <bugs@@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/>.
+
+*/
+
+/*tex
+
+We might move here some helpers common to code that are now in weird places,
+probably organized in texhelpers, luahelpers, pdfhelpers.
+
+*/
diff --git a/Build/source/texk/web2c/luatexdir/lua/helpers.w b/Build/source/texk/web2c/luatexdir/lua/helpers.w
deleted file mode 100644
index d12e476909d..00000000000
--- a/Build/source/texk/web2c/luatexdir/lua/helpers.w
+++ /dev/null
@@ -1,26 +0,0 @@
-% helpers.w
-%
-% Copyright 2017 LuaTeX team <bugs@@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/>.
-
-@ We will move here some helpers common to code that are now in weird places,
-probably organized in texhelpers, luahelpers, pdfhelpers.
-
-
-
-@c
-/* to fill... */
diff --git a/Build/source/texk/web2c/luatexdir/lua/llfslibext.c b/Build/source/texk/web2c/luatexdir/lua/llfslibext.c
deleted file mode 100644
index eba5778dfc7..00000000000
--- a/Build/source/texk/web2c/luatexdir/lua/llfslibext.c
+++ /dev/null
@@ -1,171 +0,0 @@
-/* llfslibext.c
-
- Copyright 2010-2011 Taco Hoekwater <taco@luatex.org>
-
- This file is part of LuaTeX.
-
- LuaTeX is free software; you can redistribute it and/or modify it under
- the terms of the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at your
- option) any later version.
-
- LuaTeX is distributed in the hope that it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
- License for more details.
-
- You should have received a copy of the GNU General Public License along
- with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */
-
-#include "ptexlib.h"
-#include "lua/luatex-api.h"
-
-#include <kpathsea/c-stat.h>
-#include <kpathsea/c-dir.h>
-#include <time.h>
-
-
-#ifdef _WIN32
-# include <windows.h>
-#else
-#endif
-
-#ifdef _WIN32
-
-static int get_short_name(lua_State * L)
-{
- long length = 0;
- TCHAR *buffer = NULL;
- const char *lpszPath = luaL_checkstring(L, 1);
- length = GetShortPathName(lpszPath, NULL, 0);
- if (length == 0) {
- lua_pushnil(L);
- lua_pushfstring(L, "operating system error: %d", (int) GetLastError());
- return 2;
- }
- buffer = (TCHAR *) xmalloc(length * sizeof(TCHAR));
- length = GetShortPathName(lpszPath, buffer, length);
- if (length == 0) {
- lua_pushnil(L);
- lua_pushfstring(L, "operating system error: %d", (int) GetLastError());
- return 2;
- }
- lua_pushlstring(L, (const char *) buffer, (size_t) length);
- return 1;
-}
-
-static int read_link(lua_State * L)
-{
- lua_pushboolean(L, 0);
- lua_pushliteral(L, "readlink not supported on this platform");
- return 2;
-}
-
-#else
-
-static int pusherror(lua_State * L, const char *info)
-{
- lua_pushnil(L);
- if (info == NULL)
- lua_pushstring(L, strerror(errno));
- else
- lua_pushfstring(L, "%s: %s", info, strerror(errno));
- lua_pushinteger(L, errno);
- return 3;
-}
-
-static int Preadlink(lua_State * L)
-{
-/** readlink(path) */
- const char *path = luaL_checkstring(L, 1);
- char *b = NULL;
- int allocated = 128;
- int n;
- while (1) {
- b = malloc(allocated);
- if (!b)
- return pusherror(L, path);
- n = readlink(path, b, allocated);
- if (n == -1) {
- free(b);
- return pusherror(L, path);
- }
- if (n < allocated)
- break;
- /* Not enough room, try bigger */
- allocated *= 2;
- free(b);
- }
- lua_pushlstring(L, b, n);
- free(b);
- return 1;
-}
-
-
-static int read_link(lua_State * L)
-{
- return Preadlink(L);
-}
-
-static int get_short_name(lua_State * L __attribute__ ((unused)))
-{
- /* simply do nothing */
- return 1;
-}
-#endif
-
-
-/*
-** Get file information
-*/
-static int file_is_directory(lua_State * L)
-{
- struct stat info;
- const char *file = luaL_checkstring(L, 1);
-
- if (stat(file, &info)) {
- lua_pushnil(L);
- lua_pushfstring(L, "cannot obtain information from file `%s'", file);
- return 2;
- }
- if (S_ISDIR(info.st_mode))
- lua_pushboolean(L, 1);
- else
- lua_pushboolean(L, 0);
-
- return 1;
-}
-
-static int file_is_file(lua_State * L)
-{
- struct stat info;
- const char *file = luaL_checkstring(L, 1);
-
- if (stat(file, &info)) {
- lua_pushnil(L);
- lua_pushfstring(L, "cannot obtain information from file `%s'", file);
- return 2;
- }
- if (S_ISREG(info.st_mode))
- lua_pushboolean(L, 1);
- else
- lua_pushboolean(L, 0);
-
- return 1;
-}
-
-
-void open_lfslibext(lua_State * L)
-{
-
- lua_getglobal(L, "lfs");
- lua_pushcfunction(L, file_is_directory);
- lua_setfield(L, -2, "isdir");
- lua_pushcfunction(L, file_is_file);
- lua_setfield(L, -2, "isfile");
- lua_pushcfunction(L, read_link);
- lua_setfield(L, -2, "readlink");
- lua_pushcfunction(L, get_short_name);
- lua_setfield(L, -2, "shortname");
- lua_pop(L, 1); /* pop the table */
-}
diff --git a/Build/source/texk/web2c/luatexdir/lua/lpdfelib.c b/Build/source/texk/web2c/luatexdir/lua/lpdfelib.c
new file mode 100644
index 00000000000..31fad9f632d
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/lua/lpdfelib.c
@@ -0,0 +1,1666 @@
+/*tex
+
+ This file will host the encapsulated \PDF\ support code used for inclusion
+ and access from \LUA.
+
+*/
+
+#include "ptexlib.h"
+
+/*tex
+
+ We need to avoid collision with some defines in |cpascal.h|.
+
+*/
+
+#undef lpdfelib_orig_input
+#undef lpdfelib_orig_output
+
+#ifdef input
+#define lpdfelib_orig_input input
+#undef input
+#endif
+
+#ifdef output
+#define lpdfelib_orig_output output
+#undef output
+#endif
+
+#include "luapplib/pplib.h"
+
+#include "image/epdf.h"
+
+#ifdef lpdfelib_orig_input
+#define input lpdfelib_orig_input
+#undef lpdfelib_orig_input
+#endif
+
+#ifdef lpdfelib_orig_output
+#define output lpdfelib_orig_output
+#undef lpdfelib_orig_output
+#endif
+
+#include "lua/luatex-api.h"
+
+/*tex
+
+ We start with some housekeeping. Dictionaries, arrays, streams and references
+ get userdata, while strings, names, integers, floats and booleans become regular
+ \LUA\ objects. We need to define a few metatable identifiers too.
+
+*/
+
+#define PDFE_METATABLE "luatex.pdfe"
+#define PDFE_METATABLE_DICTIONARY "luatex.pdfe.dictionary"
+#define PDFE_METATABLE_ARRAY "luatex.pdfe.array"
+#define PDFE_METATABLE_STREAM "luatex.pdfe.stream"
+#define PDFE_METATABLE_REFERENCE "luatex.pdfe.reference"
+
+typedef struct {
+ ppdoc *document;
+ boolean open;
+ boolean isfile;
+ char *memstream;
+ int pages;
+ int index;
+} pdfe_document ;
+
+typedef struct {
+ ppdict *dictionary;
+ ppref *ref;
+} pdfe_dictionary;
+
+typedef struct {
+ pparray *array;
+ ppref *ref;
+} pdfe_array;
+
+typedef struct {
+ ppstream *stream;
+ ppref *ref;
+ int decode;
+ int open;
+} pdfe_stream;
+
+typedef struct {
+ ppref *reference;
+} pdfe_reference;
+
+/*tex
+
+ We need to check if we have the right userdata. A similar warning is issued
+ when encounter a problem. We don't exit.
+
+*/
+
+static void pdfe_invalid_object_warning(const char * detail)
+{
+ formatted_warning("pdfe lib","lua <pdfe %s> expected",detail);
+}
+
+static pdfe_document *check_isdocument(lua_State * L, int n)
+{
+ pdfe_document *p = (pdfe_document *)lua_touserdata(L, n);
+ if (p != NULL && lua_getmetatable(L, n)) {
+ lua_get_metatablelua(luatex_pdfe);
+ if (!lua_rawequal(L, -1, -2)) {
+ p = NULL;
+ }
+ lua_pop(L, 2);
+ if (p != NULL) {
+ return p;
+ }
+ }
+ pdfe_invalid_object_warning("document");
+ return NULL;
+}
+
+static pdfe_dictionary *check_isdictionary(lua_State * L, int n)
+{
+ pdfe_dictionary *p = (pdfe_dictionary *)lua_touserdata(L, n);
+ if (p != NULL && lua_getmetatable(L, n)) {
+ lua_get_metatablelua(luatex_pdfe_dictionary);
+ if (!lua_rawequal(L, -1, -2)) {
+ p = NULL;
+ }
+ lua_pop(L, 2);
+ if (p != NULL) {
+ return p;
+ }
+ }
+ pdfe_invalid_object_warning("dictionary");
+ return NULL;
+}
+
+static pdfe_array *check_isarray(lua_State * L, int n)
+{
+ pdfe_array *p = (pdfe_array *)lua_touserdata(L, n);
+ if (p != NULL && lua_getmetatable(L, n)) {
+ lua_get_metatablelua(luatex_pdfe_array);
+ if (!lua_rawequal(L, -1, -2)) {
+ p = NULL;
+ }
+ lua_pop(L, 2);
+ if (p != NULL) {
+ return p;
+ }
+ }
+ pdfe_invalid_object_warning("array");
+ return NULL;
+}
+
+static pdfe_stream *check_isstream(lua_State * L, int n)
+{
+ pdfe_stream *p = (pdfe_stream *)lua_touserdata(L, n);
+ if (p != NULL && lua_getmetatable(L, n)) {
+ lua_get_metatablelua(luatex_pdfe_stream);
+ if (!lua_rawequal(L, -1, -2)) {
+ p = NULL;
+ }
+ lua_pop(L, 2);
+ if (p != NULL) {
+ return p;
+ }
+ }
+ pdfe_invalid_object_warning("stream");
+ return NULL;
+}
+
+static pdfe_reference *check_isreference(lua_State * L, int n)
+{
+ pdfe_reference *p = (pdfe_reference *)lua_touserdata(L, n);
+ if (p != NULL && lua_getmetatable(L, n)) {
+ lua_get_metatablelua(luatex_pdfe_reference);
+ if (!lua_rawequal(L, -1, -2)) {
+ p = NULL;
+ }
+ lua_pop(L, 2);
+ if (p != NULL) {
+ return p;
+ }
+ }
+ pdfe_invalid_object_warning("reference");
+ return NULL;
+}
+
+/*tex
+
+ Reporting the type of a userdata is just a sequence of tests till we find the
+ right one. We return nothing is it is no pdfe type.
+
+ \starttyping
+ t = pdfe.type(<pdfe document|dictionary|array|reference|stream>)
+ \stoptyping
+
+*/
+
+#define check_type(field,meta,name) do { \
+ lua_get_metatablelua(luatex_##meta); \
+ if (lua_rawequal(L, -1, -2)) { \
+ lua_pushstring(L,name); \
+ return 1; \
+ } \
+ lua_pop(L, 1); \
+} while (0)
+
+static int pdfelib_type(lua_State * L)
+{
+ void *p = lua_touserdata(L, 1);
+ if (p != NULL && lua_getmetatable(L, 1)) {
+ check_type(document, pdfe, "pdfe");
+ check_type(dictionary,pdfe_dictionary,"pdfe.dictionary");
+ check_type(array, pdfe_array, "pdfe.array");
+ check_type(reference, pdfe_reference, "pdfe.reference");
+ check_type(stream, pdfe_stream, "pdfe.stream");
+ }
+ return 0;
+}
+
+/*tex
+
+ The \type {tostring} metamethods are similar and report a pdfe type plus a
+ pointer value, as is rather usual in \LUA.
+
+*/
+
+#define define_to_string(field,what) \
+static int pdfelib_tostring_##field(lua_State * L) { \
+ pdfe_##field *p = check_is##field(L, 1); \
+ if (p != NULL) { \
+ lua_pushfstring(L, "<" what " %p>", (ppdoc *) p->field); \
+ return 1; \
+ } \
+ return 0; \
+}
+
+define_to_string(document, "pdfe")
+define_to_string(dictionary,"pdfe.dictionary")
+define_to_string(array, "pdfe.array")
+define_to_string(reference, "pdfe.reference")
+define_to_string(stream, "pdfe.stream")
+
+/*tex
+
+ The pushers look rather similar. We have two variants, one that just pushes
+ the object, and another that also pushes some extra information.
+
+*/
+
+#define pdfe_push_dictionary do { \
+ pdfe_dictionary *d = (pdfe_dictionary *)lua_newuserdata(L, sizeof(pdfe_dictionary)); \
+ luaL_getmetatable(L, PDFE_METATABLE_DICTIONARY); \
+ lua_setmetatable(L, -2); \
+ d->dictionary = dictionary; \
+} while(0)
+
+static int pushdictionary(lua_State * L, ppdict *dictionary)
+{
+ if (dictionary != NULL) {
+ pdfe_push_dictionary;
+ lua_pushinteger(L,dictionary->size);
+ return 2;
+ }
+ return 0;
+}
+
+static int pushdictionaryonly(lua_State * L, ppdict *dictionary)
+{
+ if (dictionary != NULL) {
+ pdfe_push_dictionary;
+ return 1;
+ }
+ return 0;
+}
+
+#define pdfe_push_array do { \
+ pdfe_array *a = (pdfe_array *)lua_newuserdata(L, sizeof(pdfe_array)); \
+ luaL_getmetatable(L, PDFE_METATABLE_ARRAY); \
+ lua_setmetatable(L, -2); \
+ a->array = array; \
+ } while (0)
+
+static int pusharray(lua_State * L, pparray * array)
+{
+ if (array != NULL) {
+ pdfe_push_array;
+ lua_pushinteger(L,array->size);
+ return 2;
+ }
+ return 0;
+}
+
+static int pusharrayonly(lua_State * L, pparray * array)
+{
+ if (array != NULL) {
+ pdfe_push_array;
+ return 1;
+ }
+ return 0;
+}
+
+#define pdfe_push_stream do { \
+ pdfe_stream *s = (pdfe_stream *)lua_newuserdata(L, sizeof(pdfe_stream)); \
+ luaL_getmetatable(L, PDFE_METATABLE_STREAM); \
+ lua_setmetatable(L, -2); \
+ s->stream = stream; \
+ s->open = 0; \
+ s->decode = 0; \
+} while(0)
+
+static int pushstream(lua_State * L, ppstream * stream)
+{
+ if (stream != NULL) {
+ pdfe_push_stream;
+ if (pushdictionary(L, stream->dict) > 0)
+ return 3;
+ else
+ return 1;
+ }
+ return 0;
+}
+
+static int pushstreamonly(lua_State * L, ppstream * stream)
+{
+ if (stream != NULL) {
+ pdfe_push_stream;
+ if (pushdictionaryonly(L, stream->dict) > 0)
+ return 2;
+ else
+ return 1;
+ }
+ return 0;
+}
+
+#define pdfe_push_reference do { \
+ pdfe_reference *r = (pdfe_reference *)lua_newuserdata(L, sizeof(pdfe_reference)); \
+ luaL_getmetatable(L, PDFE_METATABLE_REFERENCE); \
+ lua_setmetatable(L, -2); \
+ r->reference = reference; \
+ } while (0)
+
+static int pushreference(lua_State * L, ppref * reference)
+{
+ if (reference != NULL) {
+ pdfe_push_reference;
+ lua_pushinteger(L,reference->number);
+ return 2;
+ }
+ return 0;
+}
+
+/*tex
+
+ The next function checks for the type and then pushes the matching data on
+ the stack.
+
+ \starttabulate[|c|l|l|l|]
+ \BC type \BC meaning \BC value \BC detail \NC \NR
+ \NC \type {0} \NC none \NC nil \NC \NC \NR
+ \NC \type {1} \NC null \NC nil \NC \NC \NR
+ \NC \type {2} \NC boolean \NC boolean \NC \NC \NR
+ \NC \type {3} \NC boolean \NC integer \NC \NC \NR
+ \NC \type {4} \NC number \NC float \NC \NC \NR
+ \NC \type {5} \NC name \NC string \NC \NC \NR
+ \NC \type {6} \NC string \NC string \NC type \NC \NR
+ \NC \type {7} \NC array \NC arrayobject \NC size \NC \NR
+ \NC \type {8} \NC dictionary \NC dictionaryobject \NC size \NC \NR
+ \NC \type {9} \NC stream \NC streamobject \NC dictionary size \NC \NR
+ \NC \type {10} \NC reference \NC integer \NC \NC \NR
+ \LL
+ \stoptabulate
+
+ A name and string can be distinguished by the extra type value that a string
+ has.
+
+*/
+
+static int pushvalue(lua_State * L, ppobj *object)
+{
+ switch (object->type) {
+ case PPNONE:
+ case PPNULL:
+ lua_pushnil(L);
+ return 1;
+ break;
+ case PPBOOL:
+ lua_pushboolean(L,object->integer);
+ return 1;
+ break;
+ case PPINT:
+ lua_pushinteger(L, object-> integer);
+ return 1;
+ break;
+ case PPNUM:
+ lua_pushnumber(L, object->number);
+ return 1;
+ break;
+ case PPNAME:
+ lua_pushstring(L, (const char *) ppname_decoded(object->name));
+ return 1;
+ break;
+ case PPSTRING:
+ lua_pushlstring(L,(const char *) object->string, ppstring_size((void *)object->string));
+ lua_pushboolean(L, ppstring_hex((void *)object->string));
+ return 2;
+ break;
+ case PPARRAY:
+ return pusharray(L, object->array);
+ break;
+ case PPDICT:
+ return pushdictionary(L, object->dict);
+ break;
+ case PPSTREAM:
+ return pushstream(L, object->stream);
+ break;
+ case PPREF:
+ return pushreference(L, object->ref);
+ break;
+ }
+ return 0;
+}
+
+/*tex
+
+ We need to start someplace when we traverse a document's tree. There are
+ three places:
+
+ \starttyping
+ catalogdictionary = getcatalog(documentobject)
+ trailerdictionary = gettrailer(documentobject)
+ infodictionary = getinfo (documentobject)
+ \stoptyping
+
+*/
+
+static int pdfelib_getcatalog(lua_State * L)
+{
+ pdfe_document *p = check_isdocument(L, 1);
+ if (p == NULL)
+ return 0;
+ return pushdictionaryonly(L,ppdoc_catalog(p->document));
+}
+
+static int pdfelib_gettrailer(lua_State * L)
+{
+ pdfe_document *p = check_isdocument(L, 1);
+ if (p == NULL)
+ return 0;
+ return pushdictionaryonly(L,ppdoc_trailer(p->document));
+}
+
+static int pdfelib_getinfo(lua_State * L)
+{
+ pdfe_document *p = check_isdocument(L, 1);
+ if (p == NULL)
+ return 0;
+ return pushdictionaryonly(L,ppdoc_info(p->document));
+}
+
+/*tex
+
+ We have three more helpers.
+
+ \starttyping
+ [key,] type, value, detail = getfromdictionary(dictionaryobject,name|index)
+ type, value, detail = getfromarray (arrayobject,index)
+ [key,] type, value, detail = getfromstream (streamobject,name|index)
+ \stoptyping
+
+*/
+
+static int pdfelib_getfromarray(lua_State * L)
+{
+ pdfe_array *a = check_isarray(L, 1);
+ if (a != NULL) {
+ int index = luaL_checkint(L, 2) - 1;
+ if (index < a->array->size) {
+ ppobj *object = pparray_at(a->array,index);
+ lua_pushinteger(L,(int) object->type);
+ return 1 + pushvalue(L,object);
+ }
+ }
+ return 0;
+}
+
+static int pdfelib_getfromdictionary(lua_State * L)
+{
+ pdfe_dictionary *d = check_isdictionary(L, 1);
+ if (d != NULL) {
+ if (lua_type(L,2) == LUA_TSTRING) {
+ const char *name = luaL_checkstring(L, 2);
+ ppobj *object = ppdict_get_obj(d->dictionary,name);
+ if (object != NULL) {
+ lua_pushinteger(L,(int) object->type);
+ return 1 + pushvalue(L,object);
+ }
+ } else {
+ int index = luaL_checkint(L, 2) - 1;
+ if (index < d->dictionary->size) {
+ ppobj *object = ppdict_at(d->dictionary,index);
+ ppname key = ppdict_key(d->dictionary,index);
+ lua_pushstring(L,(const char *) key);
+ lua_pushinteger(L,(int) object->type);
+ return 2 + pushvalue(L,object);
+ }
+ }
+ }
+ return 0;
+}
+
+static int pdfelib_getfromstream(lua_State * L)
+{
+ pdfe_stream *s = (pdfe_stream *)lua_touserdata(L, 1);
+ if (s != NULL) {
+ ppdict *d = s->stream->dict;
+ if (lua_type(L,2) == LUA_TSTRING) {
+ const char *name = luaL_checkstring(L, 2);
+ ppobj *object = ppdict_get_obj(d,name);
+ if (object != NULL) {
+ lua_pushinteger(L,(int) object->type);
+ return 1 + pushvalue(L,object);
+ }
+ } else {
+ int index = luaL_checkint(L, 2) - 1;
+ if (index < d->size) {
+ ppobj *object = ppdict_at(d,index);
+ ppname key = ppdict_key(d,index);
+ lua_pushstring(L,(const char *) key);
+ lua_pushinteger(L,(int) object->type);
+ return 2 + pushvalue(L,object);
+ }
+ }
+ }
+ return 0;
+}
+
+/*tex
+
+ An indexed table with all entries in an array can be fetched with::
+
+ \starttyping
+ t = arraytotable(arrayobject)
+ \stoptyping
+
+ An hashed table with all entries in an dictionary can be fetched with::
+
+ \starttyping
+ t = dictionarytotable(arrayobject)
+ \stoptyping
+
+*/
+
+static void pdfelib_totable(lua_State * L, ppobj * object, int flat)
+{
+ int n = pushvalue(L,object);
+ if (flat && n < 2) {
+ return;
+ }
+ /* [value] [extra] [more] */
+ lua_createtable(L,n+1,0);
+ if (n == 1) {
+ /* value { nil, nil } */
+ lua_insert(L,-2);
+ /* { nil, nil } value */
+ lua_rawseti(L,-2,2);
+ /* { nil , value } */
+ } else if (n == 2) {
+ /* value extra { nil, nil, nil } */
+ lua_insert(L,-3);
+ /* { nil, nil, nil } value extra */
+ lua_rawseti(L,-3,3);
+ /* { nil, nil, extra } value */
+ lua_rawseti(L,-2,2);
+ /* { nil, value, extra } */
+ } else if (n == 3) {
+ /* value extra more { nil, nil, nil, nil } */
+ lua_insert(L,-4);
+ /* { nil, nil, nil, nil, nil } value extra more */
+ lua_rawseti(L,-4,4);
+ /* { nil, nil, nil, more } value extra */
+ lua_rawseti(L,-3,3);
+ /* { nil, nil, extra, more } value */
+ lua_rawseti(L,-2,2);
+ /* { nil, value, extra, more } */
+ }
+ lua_pushinteger(L,(int) object->type);
+ /* { nil, [value], [extra], [more] } type */
+ lua_rawseti(L,-2,1);
+ /* { type, [value], [extra], [more] } */
+ return;
+}
+
+static int pdfelib_arraytotable(lua_State * L)
+{
+ pdfe_array *a = check_isarray(L, 1);
+ if (a != NULL) {
+ int flat = lua_isboolean(L,2);
+ int i = 0;
+ lua_createtable(L,i,0);
+ /* table */
+ for (i=0;i<a->array->size;i++) {
+ ppobj *object = pparray_at(a->array,i);
+ pdfelib_totable(L,object,flat);
+ /* table { type, [value], [extra], [more] } */
+ lua_rawseti(L,-2,i+1);
+ /* table[i] = { type, [value], [extra], [more] } */
+ }
+ return 1;
+ }
+ return 0;
+}
+
+static int pdfelib_dictionarytotable(lua_State * L)
+{
+ pdfe_dictionary *d = check_isdictionary(L, 1);
+ if (d != NULL) {
+ int flat = lua_isboolean(L,2);
+ int i = 0;
+ lua_createtable(L,0,i);
+ /* table */
+ for (i=0;i<d->dictionary->size;i++) {
+ ppobj *object = ppdict_at(d->dictionary,i);
+ ppname key = ppdict_key(d->dictionary,i);
+ lua_pushstring(L,(const char *) key);
+ /* table key */
+ pdfelib_totable(L,object,flat);
+ /* table key { type, [value], [extra], [more] } */
+ lua_rawset(L,-3);
+ /* table[key] = { type, [value], [extra] } */
+ }
+ return 1;
+ }
+ return 0;
+}
+
+/*tex
+
+ All pages are collected with:
+
+ \starttyping
+ { { dict, size, objnum }, ... } = pagestotable(document)
+ \stoptyping
+
+*/
+
+static int pdfelib_pagestotable(lua_State * L)
+{
+ pdfe_document *p = check_isdocument(L, 1);
+ if (p != NULL) {
+ ppdoc *d = p->document;
+ ppref *r = NULL;
+ int i = 0;
+ lua_createtable(L,ppdoc_page_count(d),0);
+ /* pages[1..n] */
+ for (r = ppdoc_first_page(d), i = 1; r != NULL; r = ppdoc_next_page(d), ++i) {
+ lua_createtable(L,3,0);
+ pushdictionary(L,ppref_obj(r)->dict);
+ /* table dictionary n */
+ lua_rawseti(L,-3,2);
+ /* table dictionary */
+ lua_rawseti(L,-2,1);
+ /* table */
+ lua_pushinteger(L,r->number);
+ /* table reference */
+ lua_rawseti(L,-2,3);
+ /* table */
+ lua_rawseti(L,-2,i);
+ /* pages[i] = { dictionary, size, objnum } */
+ }
+ return 1;
+ }
+ return 0;
+}
+
+/*tex
+
+ Streams can be fetched on one go:
+
+ \starttyping
+ string, n = readwholestream(streamobject,decode)
+ \stoptyping
+
+*/
+
+static int pdfelib_readwholestream(lua_State * L)
+{
+ pdfe_stream *s = check_isstream(L, 1);
+ if (s != NULL) {
+ uint8_t *b = NULL;
+ int decode = 0;
+ size_t n = 0;
+ if (s->open > 0) {
+ ppstream_done(s->stream);
+ s->open = 0;
+ s->decode = 0;
+ }
+ if (lua_gettop(L) > 1 && lua_isboolean(L, 2)) {
+ decode = lua_toboolean(L, 2);
+ }
+ b = ppstream_all(s->stream,&n,decode);
+ lua_pushlstring(L, (const char *) b, n);
+ lua_pushinteger(L, (int) n);
+ ppstream_done(s->stream);
+ return 2;
+ }
+ return 0;
+}
+
+/*tex
+
+ Alternatively streams can be fetched stepwise:
+
+ okay = openstream(streamobject,[decode])
+ string, n = readfromstream(streamobject)
+ closestream(streamobject)
+
+*/
+
+static int pdfelib_openstream(lua_State * L)
+{
+ pdfe_stream *s = check_isstream(L, 1);
+ if (s != NULL) {
+ if (s->open == 0) {
+ if (lua_gettop(L) > 1) {
+ s->decode = lua_isboolean(L, 2);
+ }
+ s->open = 1;
+ }
+ lua_pushboolean(L,1);
+ return 1;
+ }
+ return 0;
+}
+
+static int pdfelib_closestream(lua_State * L)
+{
+ pdfe_stream *s = check_isstream(L, 1);
+ if (s != NULL) {
+ if (s->open >0) {
+ ppstream_done(s->stream);
+ s->open = 0;
+ s->decode = 0;
+ }
+ }
+ return 0;
+}
+
+static int pdfelib_readfromstream(lua_State * L)
+{
+ pdfe_stream *s = check_isstream(L, 1);
+ if (s != NULL) {
+ size_t n = 0;
+ uint8_t *d = NULL;
+ if (s->open == 1) {
+ d = ppstream_first(s->stream,&n,s->decode);
+ s->open = 2;
+ } else if (s->open == 2) {
+ d = ppstream_next(s->stream,&n);
+ } else {
+ return 0;
+ }
+ lua_pushlstring(L, (const char *) d, n);
+ lua_pushinteger(L, (int) n);
+ return 2;
+ }
+ return 0;
+}
+
+/*tex
+
+ There are two methods for opening a document: files and strings.
+
+ \starttyping
+ documentobject = open(filename)
+ documentobject = new(string,length)
+ \stoptyping
+
+ Closing happens with:
+
+ \starttyping
+ close(documentobject)
+ \stoptyping
+
+ When the \type {new} function gets a peudo filename as third argument,
+ no user data will be created but the stream is accessible as image.
+
+*/
+
+static int pdfelib_open(lua_State * L)
+{
+ const char *filename = luaL_checkstring(L, 1);
+ ppdoc *d = ppdoc_load(filename);
+ if (d == NULL) {
+ formatted_warning("pdfe lib","no valid pdf file '%s'",filename);
+ } else {
+ pdfe_document *p = (pdfe_document *) lua_newuserdata(L, sizeof(pdfe_document));
+ luaL_getmetatable(L, PDFE_METATABLE);
+ lua_setmetatable(L, -2);
+ p->document = d;
+ p->open = true;
+ p->isfile = true;
+ p->memstream = NULL;
+ return 1;
+ }
+ return 0;
+}
+
+static int pdfelib_new(lua_State * L)
+{
+ const char *docstream = NULL;
+ char *memstream = NULL ;
+ unsigned long long streamsize;
+ switch (lua_type(L, 1)) {
+ case LUA_TSTRING:
+ /* stream as Lua string */
+ docstream = luaL_checkstring(L, 1);
+ break;
+ case LUA_TLIGHTUSERDATA:
+ /* stream as sequence of bytes */
+ docstream = (const char *) lua_touserdata(L, 1);
+ break;
+ default:
+ luaL_error(L, "bad <pdfe> argument: string or lightuserdata expected");
+ break;
+ }
+ if (docstream == NULL) {
+ luaL_error(L, "bad <pdfe> document");
+ }
+ /* size of the stream */
+ streamsize = (unsigned long long) luaL_checkint(L, 2);
+ memstream = xmalloc((unsigned) (streamsize + 1));
+ if (! memstream) {
+ luaL_error(L, "no room for <pdfe> stream");
+ }
+ memcpy(memstream, docstream, (streamsize + 1));
+ memstream[streamsize]='\0';
+ if (lua_gettop(L) == 2) {
+ /* we stay at the lua end */
+ ppdoc *d = ppdoc_mem(memstream, streamsize);
+ if (d == NULL) {
+ normal_warning("pdfe lib","no valid pdf mem stream");
+ } else {
+ pdfe_document *p = (pdfe_document *) lua_newuserdata(L, sizeof(pdfe_document));
+ luaL_getmetatable(L, PDFE_METATABLE);
+ lua_setmetatable(L, -2);
+ p->document = d;
+ p->open = true;
+ p->isfile = false;
+ p->memstream = memstream;
+ return 1;
+ }
+ } else {
+ /* pseudo file name */
+ PdfDocument *pdf_doc;
+ const char *file_id = luaL_checkstring(L, 3);
+ if (file_id == NULL) {
+ luaL_error(L, "<pdfe> stream has an invalid id");
+ }
+ if (strlen(file_id) > STREAM_FILE_ID_LEN ) {
+ /* a limit to the length of the string */
+ luaL_error(L, "<pdfe> stream has a too long id");
+ }
+ pdf_doc = refMemStreamPdfDocument(memstream, streamsize, file_id);
+ if (pdf_doc != NULL) {
+ lua_pushstring(L,pdf_doc->file_path);
+ return 1;
+ } else {
+ /* pplib does this: xfree(memstream); */
+ }
+ }
+ return 0;
+}
+
+/*
+
+ There is no garbage collection needed as the library itself manages the
+ objects. Normally objects don't take much space. Streams use buffers so (I
+ assume) that they are not persistent. The only collector is in the parent
+ object (the document).
+
+*/
+
+static int pdfelib_free(lua_State * L)
+{
+ pdfe_document *p = check_isdocument(L, 1);
+ if (p != NULL && p->open) {
+ if (p->document != NULL) {
+ ppdoc_free(p->document);
+ p->document = NULL;
+ }
+ if (p->memstream != NULL) {
+ /* pplib does this: xfree(p->memstream); */
+ p->memstream = NULL;
+ }
+ p->open = false;
+ }
+ return 0;
+}
+
+static int pdfelib_close(lua_State * L)
+{
+ return pdfelib_free(L);
+}
+
+/*tex
+
+ A document is can be uncrypted with:
+
+ \starttyping
+ status = unencrypt(documentobject,user,owner)
+ \stoptyping
+
+ Instead of a password \type {nil} can be passed, so there are three possible
+ useful combinations.
+
+*/
+
+static int pdfelib_unencrypt(lua_State * L)
+{
+ pdfe_document *p = check_isdocument(L, 1);
+ if (p != NULL) {
+ size_t u = 0;
+ size_t o = 0;
+ const char* user = NULL;
+ const char* owner = NULL;
+ int top = lua_gettop(L);
+ if (top > 1) {
+ if (lua_type(L,2) == LUA_TSTRING) {
+ user = lua_tolstring(L, 2, &u);
+ } else {
+ /*tex we're not too picky but normally it will be nil or false */
+ }
+ if (top > 2) {
+ if (lua_type(L,3) == LUA_TSTRING) {
+ owner = lua_tolstring(L, 3, &o);
+ } else {
+ /*tex we're not too picky but normally it will be nil or false */
+ }
+ }
+ lua_pushinteger(L, (int) ppdoc_crypt_pass(p->document,user,u,owner,o));
+ return 1;
+ }
+ }
+ lua_pushinteger(L, (int) PPCRYPT_FAIL);
+ return 1;
+}
+
+/*tex
+
+ There are a couple of ways to get information about the document:
+
+ \starttyping
+ n = getsize (documentobject)
+ major, minor = getversion (documentobject)
+ status = getstatus (documentobject)
+ n = getnofobjects (documentobject)
+ n = getnofpages (documentobject)
+ bytes, waste = getmemoryusage(documentobject)
+ \stoptyping
+
+*/
+
+static int pdfelib_getsize(lua_State * L)
+{
+ pdfe_document *p = check_isdocument(L, 1);
+ if (p == NULL)
+ return 0;
+ lua_pushinteger(L,(int) ppdoc_file_size(p->document));
+ return 1;
+}
+
+
+static int pdfelib_getversion(lua_State * L)
+{
+ pdfe_document *p = check_isdocument(L, 1);
+ if (p == NULL) {
+ return 0;
+ } else {
+ int minor;
+ int major = ppdoc_version_number(p->document, &minor);
+ lua_pushinteger(L,(int) major);
+ lua_pushinteger(L,(int) minor);
+ return 2;
+ }
+}
+
+static int pdfelib_getstatus(lua_State * L)
+{
+ pdfe_document *p = check_isdocument(L, 1);
+ if (p == NULL)
+ return 0;
+ lua_pushinteger(L,(int) ppdoc_crypt_status(p->document));
+ return 1;
+}
+
+static int pdfelib_getnofobjects(lua_State * L)
+{
+ pdfe_document *p = check_isdocument(L, 1);
+ if (p == NULL)
+ return 0;
+ lua_pushinteger(L,(int) ppdoc_objects(p->document));
+ return 1;
+}
+
+static int pdfelib_getnofpages(lua_State * L)
+{
+ pdfe_document *p = check_isdocument(L, 1);
+ if (p == NULL)
+ return 0;
+ lua_pushinteger(L,(int) ppdoc_page_count(p->document));
+ return 1;
+}
+
+static int pdfelib_getmemoryusage(lua_State * L)
+{
+ pdfe_document *p = check_isdocument(L, 1);
+ if (p != NULL) {
+ size_t w = 0;
+ size_t m = ppdoc_memory(p->document,&w);
+ lua_pushinteger(L,(int) m);
+ lua_pushinteger(L,(int) w);
+ return 2;
+ }
+ return 0;
+}
+
+/*
+ A specific page dictionary can be filtered with the next command. So, there
+ is no need to parse the document page tree (with these \type {kids} arrays).
+
+ \starttyping
+ dictionaryobject = getpage(documentobject,pagenumber)
+ \stoptyping
+
+*/
+
+static int pushpage(lua_State * L, ppdoc * d, int page)
+{
+ if (page <= 0 || page > ppdoc_page_count(d)) {
+ return 0;
+ } else {
+ ppref *pp = ppdoc_page(d,page);
+ return pushdictionaryonly(L, ppref_obj(pp)->dict);
+ }
+}
+
+static int pdfelib_getpage(lua_State * L)
+{
+ pdfe_document *p = check_isdocument(L, 1);
+ if (p == NULL) {
+ return 0;
+ } else {
+ return pushpage(L, p->document, luaL_checkint(L, 2));
+ }
+}
+
+static int pushpages(lua_State * L, ppdoc * d)
+{
+ int i = 0;
+ ppref *r;
+ lua_createtable(L,ppdoc_page_count(d),0);
+ /* pages[1..n] */
+ for (r = ppdoc_first_page(d), i = 1; r != NULL; r = ppdoc_next_page(d), ++i) {
+ pushdictionaryonly(L,ppref_obj(r)->dict);
+ lua_rawseti(L,-2,i);
+ }
+ return 1 ;
+}
+
+static int pdfelib_getpages(lua_State * L)
+{
+ pdfe_document *p = check_isdocument(L, 1);
+ if (p == NULL) {
+ return 0;
+ } else {
+ return pushpages(L, p->document);
+ }
+}
+
+/*tex
+
+ The boundingbox (\type {MediaBox) and similar boxes can be available in a
+ (page) doctionary but also in a parent object. Therefore a helper is
+ available that does the (backtracked) lookup.
+
+ \starttyping
+ { lx, ly, rx, ry } = getbox(dictionaryobject)
+ \stoptyping
+
+*/
+
+static int pdfelib_getbox(lua_State * L)
+{
+ if (lua_gettop(L) > 1 && lua_type(L,2) == LUA_TSTRING) {
+ pdfe_dictionary *p = check_isdictionary(L, 1);
+ if (p != NULL) {
+ const char *key = lua_tostring(L,2);
+ pprect box;
+ pprect *r;
+ box.lx = box.rx = box.ly = box.ry = 0;
+ r = ppdict_get_box(p->dictionary,key,&box);
+ if (r != NULL) {
+ lua_createtable(L,4,0);
+ lua_pushnumber(L,r->lx);
+ lua_rawseti(L,-2,1);
+ lua_pushnumber(L,r->ly);
+ lua_rawseti(L,-2,2);
+ lua_pushnumber(L,r->rx);
+ lua_rawseti(L,-2,3);
+ lua_pushnumber(L,r->ry);
+ lua_rawseti(L,-2,4);
+ return 1;
+ }
+ }
+ }
+ return 0;
+}
+
+/*tex
+
+ This one is needed when you use the detailed getters and run into an
+ object reference. The regular getters resolve this automatically.
+
+ \starttyping
+ [dictionary|array|stream]object = getfromreference(referenceobject)
+ \stoptyping
+
+*/
+
+static int pdfelib_getfromreference(lua_State * L)
+{
+ pdfe_reference *r = check_isreference(L, 1);
+ if (r != NULL) {
+ ppobj *o = ppref_obj(r->reference);
+ lua_pushinteger(L,o->type);
+ return 1 + pushvalue(L,o);
+ }
+ return 0;
+}
+
+/*tex
+
+ Here are some convenient getters:
+
+ \starttyping
+ <string> = getstring (array|dict|ref,index|key)
+ <integer> = getinteger (array|dict|ref,index|key)
+ <number> = getnumber (array|dict|ref,index|key)
+ <boolan> = getboolean (array|dict|ref,index|key)
+ <string> = getname (array|dict|ref,index|key)
+ <dictionary> = getdictionary(array|dict|ref,index|key)
+ <array> = getarray (array|dict|ref,index|key)
+ <stream>, <dict> = getstream (array|dict|ref,index|key)
+ \stoptyping
+
+ We report issues when reasonable but are silent when it makes sense. We don't
+ error on this because we expect the user code to act reasonable on a return
+ value.
+
+*/
+
+#define pdfelib_get_value_check_1 do { \
+ if (p == NULL) { \
+ if (t == LUA_TSTRING) { \
+ normal_warning("pdfe lib","lua <pdfe dictionary> expected"); \
+ } else if (t == LUA_TNUMBER) { \
+ normal_warning("pdfe lib","lua <pdfe array> expected"); \
+ } else { \
+ normal_warning("pdfe lib","invalid arguments"); \
+ } \
+ return 0; \
+ } else if (! lua_getmetatable(L, 1)) { \
+ normal_warning("pdfe lib","first argument should be a <pde array> or <pde dictionary>"); \
+ } \
+} while (0)
+
+#define pdfelib_get_value_check_2 \
+ normal_warning("pdfe lib","second argument should be integer or string");
+
+/*tex
+
+ The direct fetcher returns the result or |NULL| when there is nothing
+ found.
+
+*/
+
+#define pdfelib_get_value_direct(get_d,get_a) do { \
+ int t = lua_type(L,2); \
+ void *p = lua_touserdata(L, 1); \
+ pdfelib_get_value_check_1; \
+ if (t == LUA_TSTRING) { \
+ const char *key = lua_tostring(L,-2); \
+ lua_get_metatablelua(luatex_pdfe_dictionary); \
+ if (lua_rawequal(L, -1, -2)) { \
+ value = get_d(((pdfe_dictionary *) p)->dictionary, key); \
+ } else { \
+ lua_pop(L,1); \
+ lua_get_metatablelua(luatex_pdfe_reference); \
+ if (lua_rawequal(L, -1, -2)) { \
+ ppobj * o = ppref_obj((ppref *) (((pdfe_reference *) p)->reference)); \
+ if (o != NULL && o->type == PPDICT) { \
+ value = get_d((ppdict *)o->dict, key); \
+ } \
+ } \
+ } \
+ } else if (t == LUA_TNUMBER) { \
+ size_t index = lua_tointeger(L,-2); \
+ lua_get_metatablelua(luatex_pdfe_array); \
+ if (lua_rawequal(L, -1, -2)) { \
+ value = get_a(((pdfe_array *) p)->array, index); \
+ } else { \
+ lua_pop(L,1); \
+ lua_get_metatablelua(luatex_pdfe_reference); \
+ if (lua_rawequal(L, -1, -2)) { \
+ ppobj * o = ppref_obj((ppref *) (((pdfe_reference *) p)->reference)); \
+ if (o != NULL && o->type == PPARRAY) { \
+ value = get_a((pparray *) o->array, index); \
+ } \
+ } \
+ } \
+ } else { \
+ pdfelib_get_value_check_2; \
+ } \
+} while (0)
+
+/*tex
+
+ The indirect fetcher passes a pointer to the target variable and returns
+ success state.
+
+*/
+
+#define pdfelib_get_value_indirect(get_d,get_a) do { \
+ int t = lua_type(L,2); \
+ void *p = lua_touserdata(L, 1); \
+ pdfelib_get_value_check_1; \
+ if (t == LUA_TSTRING) { \
+ const char *key = lua_tostring(L,-2); \
+ lua_get_metatablelua(luatex_pdfe_dictionary); \
+ if (lua_rawequal(L, -1, -2)) { \
+ okay = get_d(((pdfe_dictionary *) p)->dictionary, key, &value); \
+ } else { \
+ lua_pop(L,1); \
+ lua_get_metatablelua(luatex_pdfe_reference); \
+ if (lua_rawequal(L, -1, -2)) { \
+ ppobj * o = ppref_obj((ppref *) (((pdfe_reference *) p)->reference)); \
+ if (o != NULL && o->type == PPDICT) \
+ okay = get_d(o->dict, key, &value); \
+ } \
+ } \
+ } else if (t == LUA_TNUMBER) { \
+ size_t index = lua_tointeger(L,-2); \
+ lua_get_metatablelua(luatex_pdfe_array); \
+ if (lua_rawequal(L, -1, -2)) { \
+ okay = get_a(((pdfe_array *) p)->array, index, &value); \
+ } else { \
+ lua_pop(L,1); \
+ lua_get_metatablelua(luatex_pdfe_reference); \
+ if (lua_rawequal(L, -1, -2)) { \
+ ppobj * o = ppref_obj((ppref *) (((pdfe_reference *) p)->reference)); \
+ if (o != NULL && o->type == PPARRAY) \
+ okay = get_a(o->array, index, &value); \
+ } \
+ } \
+ } else { \
+ pdfelib_get_value_check_2; \
+ } \
+} while (0)
+
+static int pdfelib_getstring(lua_State * L)
+{
+ if (lua_gettop(L) > 1) {
+ ppstring value = NULL;
+ pdfelib_get_value_direct(ppdict_rget_string,pparray_rget_string);
+ if (value != NULL) {
+ lua_pushstring(L,(const char *) value);
+ return 1;
+ }
+ }
+ return 0;
+}
+
+static int pdfelib_getinteger(lua_State * L)
+{
+ if (lua_gettop(L) > 1) {
+ ppint value = 0;
+ int okay = 0;
+ pdfelib_get_value_indirect(ppdict_rget_int,pparray_rget_int);
+ if (okay) {
+ lua_pushinteger(L,(int) value);
+ return 1;
+ }
+ }
+ return 0;
+}
+
+static int pdfelib_getnumber(lua_State * L)
+{
+ if (lua_gettop(L) > 1) {
+ ppnum value = 0;
+ int okay = 0;
+ pdfelib_get_value_indirect(ppdict_rget_num,pparray_rget_num);
+ if (okay) {
+ lua_pushnumber(L,value);
+ return 1;
+ }
+ }
+ return 0;
+}
+
+static int pdfelib_getboolean(lua_State * L)
+{
+ if (lua_gettop(L) > 1) {
+ int value = 0;
+ int okay = 0;
+ pdfelib_get_value_indirect(ppdict_rget_bool,pparray_rget_bool);
+ if (okay) {
+ lua_pushboolean(L,value);
+ return 1;
+ }
+ }
+ return 0;
+}
+
+static int pdfelib_getname(lua_State * L)
+{
+ if (lua_gettop(L) > 1) {
+ ppname value = NULL;
+ pdfelib_get_value_direct(ppdict_rget_name,pparray_rget_name);
+ if (value != NULL) {
+ lua_pushstring(L,(const char *) ppname_decoded(value));
+ return 1;
+ }
+ }
+ return 0;
+}
+
+static int pdfelib_getdictionary(lua_State * L)
+{
+ if (lua_gettop(L) > 1) {
+ ppdict * value = NULL;
+ pdfelib_get_value_direct(ppdict_rget_dict,pparray_rget_dict);
+ if (value != NULL) {
+ return pushdictionaryonly(L,value);
+ }
+ }
+ return 0;
+}
+
+static int pdfelib_getarray(lua_State * L)
+{
+ if (lua_gettop(L) > 1) {
+ pparray * value = NULL;
+ pdfelib_get_value_direct(ppdict_rget_array,pparray_rget_array);
+ if (value != NULL) {
+ return pusharrayonly(L,value);
+ }
+ }
+ return 0;
+}
+
+static int pdfelib_getstream(lua_State * L)
+{
+ if (lua_gettop(L) > 1) {
+ ppobj * value = NULL;
+ pdfelib_get_value_direct(ppdict_rget_obj,pparray_rget_obj);
+ if (value != NULL && value->type == PPSTREAM) {
+ return pushstreamonly(L,(ppstream *) value->stream);
+ }
+ }
+ return 0;
+}
+
+/*tex
+
+ The generic pushed that does a similar job as the previous getters acts upon
+ the type.
+
+*/
+
+static int pdfelib_pushvalue(lua_State * L, ppobj *object)
+{
+ switch (object->type) {
+ case PPNONE:
+ case PPNULL:
+ lua_pushnil(L);
+ break;
+ case PPBOOL:
+ lua_pushboolean(L, object->integer);
+ break;
+ case PPINT:
+ lua_pushinteger(L, object->integer);
+ break;
+ case PPNUM:
+ lua_pushnumber(L, object->number);
+ break;
+ case PPNAME:
+ lua_pushstring(L, (const char *) ppname_decoded(object->name));
+ break;
+ case PPSTRING:
+ lua_pushlstring(L,(const char *) object->string, ppstring_size((void *)object->string));
+ break;
+ case PPARRAY:
+ return pusharrayonly(L, object->array);
+ break;
+ case PPDICT:
+ return pushdictionary(L, object->dict);
+ break;
+ case PPSTREAM:
+ return pushstream(L, object->stream);
+ break;
+ case PPREF:
+ pushreference(L, object->ref);
+ break;
+ default:
+ lua_pushnil(L);
+ break;
+ }
+ return 1;
+}
+
+/*tex
+
+ Finally we arrived at the acessors for the userdata objects. The use
+ previously defined helpers.
+
+*/
+
+static int pdfelib_access(lua_State * L)
+{
+ if (lua_type(L,2) == LUA_TSTRING) {
+ pdfe_document *p = (pdfe_document *)lua_touserdata(L, 1);
+ const char *s = lua_tostring(L,2);
+ if (lua_key_eq(s,catalog) || lua_key_eq(s,Catalog)) {
+ return pushdictionaryonly(L,ppdoc_catalog(p->document));
+ } else if (lua_key_eq(s,info) || lua_key_eq(s,Info)) {
+ return pushdictionaryonly(L,ppdoc_info(p->document));
+ } else if (lua_key_eq(s,trailer) || lua_key_eq(s,Trailer)) {
+ return pushdictionaryonly(L,ppdoc_trailer(p->document));
+ } else if (lua_key_eq(s,pages) || lua_key_eq(s,Pages)) {
+ return pushpages(L,p->document);
+ }
+ }
+ return 0;
+}
+
+static int pdfelib_array_access(lua_State * L)
+{
+ if (lua_type(L,2) == LUA_TNUMBER) {
+ pdfe_array *p = (pdfe_array *)lua_touserdata(L, 1);
+ ppint index = lua_tointeger(L,2) - 1;
+ ppobj *o = pparray_rget_obj(p->array,index);
+ if (o != NULL) {
+ return pdfelib_pushvalue(L,o);
+ }
+ }
+ return 0;
+}
+
+static int pdfelib_dictionary_access(lua_State * L)
+{
+ pdfe_dictionary *p = (pdfe_dictionary *)lua_touserdata(L, 1);
+ if (lua_type(L,2) == LUA_TSTRING) {
+ const char *key = lua_tostring(L,2);
+ ppobj *o = ppdict_rget_obj(p->dictionary,key);
+ if (o != NULL) {
+ return pdfelib_pushvalue(L,o);
+ }
+ } else if (lua_type(L,2) == LUA_TNUMBER) {
+ ppint index = lua_tointeger(L,2) - 1;
+ ppobj *o = ppdict_at(p->dictionary,index);
+ if (o != NULL) {
+ return pdfelib_pushvalue(L,o);
+ }
+ }
+ return 0;
+}
+
+static int pdfelib_stream_access(lua_State * L)
+{
+ pdfe_stream *p = (pdfe_stream *)lua_touserdata(L, 1);
+ if (lua_type(L,2) == LUA_TSTRING) {
+ const char *key = lua_tostring(L,2);
+ ppobj *o = ppdict_rget_obj(p->stream->dict,key);
+ if (o != NULL) {
+ return pdfelib_pushvalue(L,o);
+ }
+ } else if (lua_type(L,2) == LUA_TNUMBER) {
+ ppint index = lua_tointeger(L,2) - 1;
+ ppobj *o = ppdict_at(p->stream->dict,index);
+ if (o != NULL) {
+ return pdfelib_pushvalue(L,o);
+ }
+ }
+ return 0;
+}
+
+/*tex
+
+ The length metamethods are defined last.
+
+*/
+
+static int pdfelib_array_size(lua_State * L)
+{
+ pdfe_array *p = (pdfe_array *)lua_touserdata(L, 1);
+ lua_pushinteger(L,p->array->size);
+ return 1;
+}
+
+static int pdfelib_dictionary_size(lua_State * L)
+{
+ pdfe_dictionary *p = (pdfe_dictionary *)lua_touserdata(L, 1);
+ lua_pushinteger(L,p->dictionary->size);
+ return 1;
+}
+
+static int pdfelib_stream_size(lua_State * L)
+{
+ pdfe_stream *p = (pdfe_stream *)lua_touserdata(L, 1);
+ lua_pushinteger(L,p->stream->dict->size);
+ return 1;
+}
+
+/*tex
+
+ We now initialize the main interface. We might aa few more
+ informational helpers but this is it.
+
+*/
+
+static const struct luaL_Reg pdfelib[] = {
+ /* management */
+ { "type", pdfelib_type },
+ { "open", pdfelib_open },
+ { "new", pdfelib_new },
+ { "close", pdfelib_close },
+ { "unencrypt", pdfelib_unencrypt },
+ /* statistics */
+ { "getversion", pdfelib_getversion },
+ { "getstatus", pdfelib_getstatus },
+ { "getsize", pdfelib_getsize },
+ { "getnofobjects", pdfelib_getnofobjects },
+ { "getnofpages", pdfelib_getnofpages },
+ { "getmemoryusage", pdfelib_getmemoryusage },
+ /* getters */
+ { "getcatalog", pdfelib_getcatalog },
+ { "gettrailer", pdfelib_gettrailer },
+ { "getinfo", pdfelib_getinfo },
+ { "getpage", pdfelib_getpage },
+ { "getpages", pdfelib_getpages },
+ { "getbox", pdfelib_getbox },
+ { "getfromreference", pdfelib_getfromreference },
+ { "getfromdictionary", pdfelib_getfromdictionary },
+ { "getfromarray", pdfelib_getfromarray },
+ { "getfromstream", pdfelib_getfromstream },
+ /* collectors */
+ { "dictionarytotable", pdfelib_dictionarytotable },
+ { "arraytotable", pdfelib_arraytotable },
+ { "pagestotable", pdfelib_pagestotable },
+ /* more getters */
+ { "getstring", pdfelib_getstring },
+ { "getinteger", pdfelib_getinteger },
+ { "getnumber", pdfelib_getnumber },
+ { "getboolean", pdfelib_getboolean },
+ { "getname", pdfelib_getname },
+ { "getdictionary", pdfelib_getdictionary },
+ { "getarray", pdfelib_getarray },
+ { "getstream", pdfelib_getstream },
+ /* streams */
+ { "readwholestream", pdfelib_readwholestream },
+ /* not really needed */
+ { "openstream", pdfelib_openstream },
+ { "readfromstream", pdfelib_readfromstream },
+ { "closestream", pdfelib_closestream },
+ /* done */
+ { NULL, NULL}
+};
+
+/*tex
+
+ The user data metatables are defined as follows. Watch how only the
+ document needs a garbage collector.
+
+*/
+
+static const struct luaL_Reg pdfelib_m[] = {
+ { "__tostring", pdfelib_tostring_document },
+ { "__gc", pdfelib_free },
+ { "__index", pdfelib_access },
+ { NULL, NULL}
+};
+
+static const struct luaL_Reg pdfelib_m_dictionary[] = {
+ { "__tostring", pdfelib_tostring_dictionary },
+ { "__index", pdfelib_dictionary_access },
+ { "__len", pdfelib_dictionary_size },
+ { NULL, NULL}
+};
+
+static const struct luaL_Reg pdfelib_m_array[] = {
+ { "__tostring", pdfelib_tostring_array },
+ { "__index", pdfelib_array_access },
+ { "__len", pdfelib_array_size },
+ { NULL, NULL}
+};
+
+static const struct luaL_Reg pdfelib_m_stream[] = {
+ { "__tostring", pdfelib_tostring_stream },
+ { "__index", pdfelib_stream_access },
+ { "__len", pdfelib_stream_size },
+ { "__call", pdfelib_readwholestream },
+ { NULL, NULL}
+};
+
+static const struct luaL_Reg pdfelib_m_reference[] = {
+ { "__tostring", pdfelib_tostring_reference },
+ { NULL, NULL}
+};
+
+/*tex
+
+ Finally we hav earrived at the main initialiser that will be called as part
+ of \LUATEX's initializer.
+
+*/
+
+/*tex
+
+ Here we hook in the error handler.
+
+*/
+
+static void pdfelib_message(const char *message, void *alien)
+{
+ normal_warning("pdfe",message);
+}
+
+int luaopen_pdfe(lua_State * L)
+{
+ /*tex First the four userdata object get their metatables defined. */
+
+ luaL_newmetatable(L, PDFE_METATABLE_DICTIONARY);
+ luaL_openlib(L, NULL, pdfelib_m_dictionary, 0);
+
+ luaL_newmetatable(L, PDFE_METATABLE_ARRAY);
+ luaL_openlib(L, NULL, pdfelib_m_array, 0);
+
+ luaL_newmetatable(L, PDFE_METATABLE_STREAM);
+ luaL_openlib(L, NULL, pdfelib_m_stream, 0);
+
+ luaL_newmetatable(L, PDFE_METATABLE_REFERENCE);
+ luaL_openlib(L, NULL, pdfelib_m_reference, 0);
+
+ /*tex Then comes the main (document) metatable: */
+
+ luaL_newmetatable(L, PDFE_METATABLE);
+ luaL_openlib(L, NULL, pdfelib_m, 0);
+
+ /*tex Last the library opens up itself to the world. */
+
+ luaL_openlib(L, "pdfe", pdfelib, 0);
+
+ pplog_callback(pdfelib_message, stderr);
+
+ return 1;
+}
diff --git a/Build/source/texk/web2c/luatexdir/lua/lpdfscannerlib.c b/Build/source/texk/web2c/luatexdir/lua/lpdfscannerlib.c
new file mode 100644
index 00000000000..6c3bc8876ee
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/lua/lpdfscannerlib.c
@@ -0,0 +1,1110 @@
+/* lpdfscannerlib.c
+
+ Copyright 2013 Taco Hoekwater <taco@luatex.org>
+
+ This file is part of LuaTeX.
+
+ LuaTeX is free software; you can redistribute it and/or modify it under
+ the terms of the GNU General Public License as published by the Free
+ Software Foundation; either version 2 of the License, or (at your
+ option) any later version.
+
+ LuaTeX is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with LuaTeX; if not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+/*tex
+
+ The scanner can read from a string or stream. Streams can be given directly as
+ |ppstream| object or as a |pparray| of streams. Here is an example of usage:
+
+ \starttyping
+ local operatortable = { }
+
+ operatortable.Do = function(scanner,info)
+ local resources = info.resources
+ if resources then
+ local val = scanner:pop()
+ local name = val[2]
+ local xobject = resources.XObject
+ print(info.space .. "Uses XObject " .. name)
+ local resources = xobject.Resources
+ if resources then
+ local newinfo = {
+ space = info.space .. " ",
+ resources = resources,
+ }
+ pdfscanner.scan(entry, operatortable, newinfo)
+ end
+ end
+ end
+
+ local function Analyze(filename)
+ local doc = pdfe.open(filename)
+ if doc then
+ local pages = doc.Pages
+ for i=1,#pages do
+ local page = pages[i]
+ local info = {
+ space = " " ,
+ resources = page.Resources,
+ }
+ print("Page " .. i)
+ pdfscanner.scan(page.Contents,operatortable,info)
+ pdfscanner.scan(page.Contents(),operatortable,info)
+ end
+ end
+ end
+
+ Analyze("foo.pdf")
+ \stoptyping
+
+*/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+#include <assert.h>
+#include <math.h>
+
+#include <lua.h>
+#include <lauxlib.h>
+#include <lualib.h>
+
+#include "luapplib/pplib.h"
+
+#include <lua/luatex-api.h>
+
+#define SCANNER "pdfscanner"
+
+#define MAXOPERANDS 1000
+
+typedef enum {
+ pdf_integer = 1,
+ pdf_real,
+ pdf_boolean,
+ pdf_name,
+ pdf_operator,
+ pdf_string,
+ pdf_startarray,
+ pdf_stoparray,
+ pdf_startdict,
+ pdf_stopdict,
+} pdf_token_type;
+
+typedef struct Token {
+ pdf_token_type type;
+ double value;
+ char *string;
+} Token;
+
+typedef struct ObjectList {
+ struct ObjectList *next;
+ ppstream *stream;
+} ObjectList;
+
+typedef struct scannerdata {
+ int _ininlineimage;
+ int _nextoperand;
+ Token **_operandstack;
+ ppstream *_stream;
+ ObjectList *_streams;
+ const char *buffer;
+ size_t position;
+ size_t size;
+ int uses_stream;
+} scannerdata;
+
+#define PDFE_METATABLE_ARRAY "luatex.pdfe.array"
+#define PDFE_METATABLE_STREAM "luatex.pdfe.stream"
+
+typedef struct {
+ void *d;
+ /*tex reference to |PdfDocument|, or |NULL| */
+ void *pd;
+ /*tex counter to detect |PDFDoc| change */
+ unsigned long pc;
+} udstruct;
+
+static void clear_operand_stack(scannerdata * self, int from);
+static Token *_parseToken(scannerdata * self, int c);
+static void push_token(lua_State * L, scannerdata * self);
+
+static void *priv_xmalloc(size_t size)
+{
+ void *new_mem = (void *) malloc(size);
+ if (new_mem == NULL) {
+ luaL_error(Luas, "no room for <pdfscanned> stream");
+ }
+ return new_mem;
+}
+
+static void *priv_xrealloc(void *old_ptr, size_t size)
+{
+ void *new_mem = (void *) realloc(old_ptr, size);
+ if (new_mem == NULL) {
+ luaL_error(Luas, "no room for <pdfscanned> stream");
+ }
+ return new_mem;
+}
+
+#define xreallocarray(ptr,type,size) ((type*)priv_xrealloc(ptr,(size+1)*sizeof(type)))
+
+#define INITBUFSIZE 64
+
+#define define_buffer(a) \
+ char *a = (char *)priv_xmalloc (INITBUFSIZE); \
+ int a##_size = INITBUFSIZE; \
+ int a##index = 0; \
+ memset (a,0,INITBUFSIZE)
+
+#define check_overflow(a, wsize) do { \
+ if (wsize >= a##_size) { \
+ int nsize = a##_size + a##_size / 4; \
+ a = (char *) xreallocarray(a, char, (unsigned) nsize); \
+ memset (a+a##_size, 0, a##_size / 4); \
+ a##_size = nsize; \
+ } \
+} while (0)
+
+
+static scannerdata *scanner_push(lua_State * L)
+{
+ scannerdata *a = (scannerdata *) lua_newuserdata(L, sizeof(scannerdata));
+ luaL_getmetatable(L, SCANNER);
+ lua_setmetatable(L, -2);
+ return a;
+}
+
+static scannerdata *scanner_check(lua_State * L, int index)
+{
+ scannerdata *bar;
+ luaL_checktype(L, index, LUA_TUSERDATA);
+ bar = (scannerdata *) luaL_checkudata(L, index, SCANNER);
+ if (bar == NULL)
+ luaL_argerror(L, index, SCANNER " expected");
+ return bar;
+}
+
+static void free_token(Token * token)
+{
+ if (token->string) {
+ free(token->string);
+ }
+ free(token);
+}
+
+static void clear_operand_stack(scannerdata * self, int from)
+{
+ int i = self->_nextoperand - 1;
+ while (i >= from) {
+ if (self->_operandstack[i]) {
+ free_token(self->_operandstack[i]);
+ self->_operandstack[i] = NULL;
+ }
+ i--;
+ }
+ self->_nextoperand = from;
+}
+
+static void push_operand(scannerdata * self, Token * token)
+{
+ if (self->_nextoperand + 1 > MAXOPERANDS) {
+ fprintf(stderr, "out of operand stack space");
+ exit(1);
+ }
+ self->_operandstack[self->_nextoperand++] = token;
+}
+
+static Token *new_operand(pdf_token_type c)
+{
+ Token *token = (Token *) priv_xmalloc(sizeof(Token));
+ memset(token, 0, sizeof(Token));
+ token->type = c;
+ return token;
+}
+
+static void _nextStream(scannerdata * self)
+{
+ ObjectList *rover = NULL;
+ if (self->uses_stream && self->buffer != NULL) {
+ if (self->uses_stream) {
+ ppstream_done(self->_stream);
+ } else {
+ free(self->_stream);
+ }
+ }
+ rover = self->_streams;
+ self->_stream = rover->stream;
+ if (self->uses_stream) {
+ self->buffer = (const char *) ppstream_all(self->_stream, &self->size, 1);
+ }
+ self->position = 0;
+ self->_streams = rover->next;
+ free(rover);
+}
+
+static int streamGetChar(scannerdata * self)
+{
+ int i = EOF;
+ if (self->position < self->size) {
+ const char c = self->buffer[self->position];
+ ++self->position;
+ i = (int) c;
+ }
+ if (i < 0 && self->_streams) {
+ _nextStream(self);
+ i = streamGetChar(self);
+ }
+ return i;
+}
+
+static int streamLookChar(scannerdata * self)
+{
+ int i = EOF;
+ if (self->position < self->size) {
+ const char c = self->buffer[self->position];
+ /*not |++self->position;| */
+ i = (int) c;
+ }
+ if (i < 0 && self->_streams) {
+ _nextStream(self);
+ i = streamGetChar(self);
+ }
+ return i;
+}
+
+static void streamReset(scannerdata * self)
+{
+ if (self->uses_stream) {
+ self->buffer = (const char *) ppstream_all(self->_stream, &self->size, 1);
+ }
+ self->position = 0;
+}
+
+static void streamClose(scannerdata * self)
+{
+ if (self->uses_stream) {
+ ppstream_done(self->_stream);
+ } else {
+ free(self->_stream);
+ }
+ self->buffer = NULL;
+ self->_stream = NULL;
+}
+
+/*tex end of stream interface */
+
+static Token *_parseSpace(scannerdata * self)
+{
+ return _parseToken(self, streamGetChar(self));
+}
+
+static Token *_parseString(scannerdata * self, int c)
+{
+ int level;
+ Token *token = NULL;
+ define_buffer(found);
+ level = 1;
+ while (1) {
+ c = streamGetChar(self);
+ if (c == '(') {
+ level = level + 1;
+ } else if (c == ')') {
+ level = level - 1;
+ if (level < 1)
+ break;
+ } else if (c == '\\') {
+ int next = streamGetChar(self);
+ if (next == '(' || next == ')' || next == '\\') {
+ c = next;
+ } else if (next == '\n' || next == '\r') {
+ c = '\0';
+ } else if (next == 'n') {
+ c = '\n';
+ } else if (next == 'r') {
+ c = '\r';
+ } else if (next == 't') {
+ c = '\t';
+ } else if (next == 'b') {
+ c = '\b';
+ } else if (next == 'f') {
+ c = '\f';
+ } else if (next >= '0' && next <= '7') {
+ int next2;
+ next = next - '0';
+ next2 = streamLookChar(self);
+ if (next2 >= '0' && next2 <= '7') {
+ int next3;
+ next2 = streamGetChar(self);
+ next2 = next2 - '0';
+ next3 = streamLookChar(self);
+ if (next3 >= '0' && next3 <= '7') {
+ next3 = streamGetChar(self);
+ next3 = next3 - '0';
+ c = (next * 64 + next2 * 8 + next3);
+ } else {
+ c = (next * 8 + next2);
+ }
+ } else {
+ c = next;
+ }
+ } else {
+ c = next;
+ }
+ }
+ check_overflow(found, foundindex);
+ if (c >= 0) {
+ found[foundindex++] = c;
+ }
+ }
+ token = new_operand(pdf_string);
+ token->value = foundindex;
+ token->string = found;
+ return token;
+}
+
+static Token *_parseNumber(scannerdata * self, int c)
+{
+ double value = 0;
+ pdf_token_type type = pdf_integer;
+ int isfraction = 0;
+ int isnegative = 0;
+ int i = 0;
+ Token *token = NULL;
+ if (c == '-') {
+ isnegative = 1;
+ c = streamGetChar(self);
+ }
+ if (c == '.') {
+ type = pdf_real;
+ isfraction = 1;
+ } else {
+ value = c - '0';
+ }
+ c = streamLookChar(self);
+ if ((c >= '0' && c <= '9') || c == '.') {
+ c = streamGetChar(self);
+ while (1) {
+ if (c == '.') {
+ type = pdf_real;
+ isfraction = 1;
+ } else {
+ i = c - '0';
+ if (isfraction > 0) {
+ value = value + (i / (pow(10.0, isfraction)));
+ isfraction = isfraction + 1;
+ } else {
+ value = (value * 10) + i;
+ }
+ }
+ c = streamLookChar(self);
+ if (!((c >= '0' && c <= '9') || c == '.'))
+ break;
+ c = streamGetChar(self);
+ }
+ }
+ if (isnegative) {
+ value = -value;
+ }
+ token = new_operand(type);
+ token->value = value;
+ return token;
+}
+
+static Token *_parseName(scannerdata * self, int c)
+{
+ Token *token = NULL;
+ define_buffer(found);
+ c = streamGetChar(self);
+ while (1) {
+ check_overflow(found, foundindex);
+ found[foundindex++] = c;
+ c = streamLookChar(self);
+ if (c == ' ' || c == '\n' || c == '\r' || c == '\t' ||
+ c == '/' || c == '[' || c == '(' || c == '<')
+ break;
+ c = streamGetChar(self);
+ }
+ token = new_operand(pdf_name);
+ token->string = found;
+ token->value = strlen(found);
+ return token;
+}
+
+#define hexdigit(c) \
+ (c>= '0' && c<= '9') ? (c - '0') : ((c>= 'A' && c<= 'F') ? (c - 'A' + 10) : (c - 'a' + 10))
+
+static Token *_parseHexstring(scannerdata * self, int c)
+{
+ int isodd = 1;
+ int hexval = 0;
+ Token *token = NULL;
+ define_buffer(found);
+ while (c != '>') {
+ if ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f')) {
+ if (isodd == 1) {
+ int v = hexdigit(c);
+ hexval = 16 * v;
+ } else {
+ hexval += hexdigit(c);
+ check_overflow(found, foundindex);
+ found[foundindex++] = hexval;
+ }
+ isodd = (isodd == 1 ? 0 : 1);
+ }
+ c = streamGetChar(self);
+ }
+ token = new_operand(pdf_string);
+ token->value = foundindex;
+ token->string = found;
+ return token;
+}
+
+#define pdf_isspace(a) (a == '\0' || a == ' ' || a == '\n' || a == '\r' || a == '\t' || a == '\v')
+
+/*tex this is rather horrible */
+
+static Token *_parseInlineImage(scannerdata * self, int c)
+{
+ Token *token = NULL;
+ define_buffer(found);
+ if (c == ' ') {
+ /*tex first space can be ignored */
+ c = streamGetChar(self);
+ }
+ check_overflow(found, foundindex);
+ found[foundindex++] = c;
+ while (1) {
+ c = streamLookChar(self);
+ if (c == 'E'
+ && (found[foundindex - 1] == '\n'
+ || found[foundindex - 1] == '\r')) {
+ c = streamGetChar(self);
+ check_overflow(found, foundindex);
+ found[foundindex++] = c;
+ c = streamLookChar(self);
+ if (c == 'I') {
+ c = streamGetChar(self);
+ check_overflow(found, foundindex);
+ found[foundindex++] = c;
+ c = streamLookChar(self);
+ if (pdf_isspace(c)) {
+ /*tex |I| */
+ found[--foundindex] = '\0';
+ /*tex |E| */
+ found[--foundindex] = '\0';
+ /*tex remove end-of-line before |EI| */
+ if (found[foundindex - 1] == '\n') {
+ found[--foundindex] = '\0';
+ }
+ if (found[foundindex - 1] == '\r') {
+ found[--foundindex] = '\0';
+ }
+ break;
+ } else {
+ c = streamGetChar(self);
+ check_overflow(found, foundindex);
+ found[foundindex++] = c;
+ }
+ } else {
+ c = streamGetChar(self);
+ check_overflow(found, foundindex);
+ found[foundindex++] = c;
+ }
+ } else {
+ c = streamGetChar(self);
+ check_overflow(found, foundindex);
+ found[foundindex++] = c;
+ }
+ }
+ token = new_operand(pdf_string);
+ token->value = foundindex;
+ token->string = found;
+ return token;
+}
+
+static Token *_parseOperator(scannerdata * self, int c)
+{
+ define_buffer(found);
+ while (1) {
+ check_overflow(found, foundindex);
+ found[foundindex++] = c;
+ c = streamLookChar(self);
+ if ((c < 0) || (c == ' ' || c == '\n' || c == '\r' || c == '\t' ||
+ c == '/' || c == '[' || c == '(' || c == '<'))
+ break;
+ c = streamGetChar(self);
+ }
+ /*tex |print| (found) */
+ if (strcmp(found, "ID") == 0) {
+ self->_ininlineimage = 1;
+ }
+ if (strcmp(found, "false") == 0) {
+ Token *token = new_operand(pdf_boolean);
+ token->value = 0;
+ free(found);
+ return token;
+ } else if (strcmp(found, "true") == 0) {
+ Token *token = new_operand(pdf_boolean);
+ token->value = 1.0;
+ free(found);
+ return token;
+ } else {
+ Token *token = new_operand(pdf_operator);
+ token->string = found;
+ return token;
+ }
+}
+
+static Token *_parseComment(scannerdata * self, int c)
+{
+ do {
+ c = streamGetChar(self);
+ } while (c != '\n' && c != '\r' && c != -1);
+ return _parseToken(self, streamGetChar(self));
+}
+
+static Token *_parseLt(scannerdata * self, int c)
+{
+ c = streamGetChar(self);
+ if (c == '<') {
+ return new_operand(pdf_startdict);
+ } else {
+ return _parseHexstring(self, c);
+ }
+}
+
+static Token *_parseGt(scannerdata * self, int c)
+{
+ c = streamGetChar(self);
+ if (c == '>') {
+ return new_operand(pdf_stopdict);
+ } else {
+ fprintf(stderr, "stray > in stream");
+ return NULL;
+ }
+}
+
+static Token *_parseError(int c)
+{
+ fprintf(stderr, "stray %c [%d] in stream", c, c);
+ return NULL;
+}
+
+static Token *_parseStartarray(void)
+{
+ return new_operand(pdf_startarray);
+}
+
+static Token *_parseStoparray(void)
+{
+ return new_operand(pdf_stoparray);
+}
+
+static Token *_parseToken(scannerdata * self, int c)
+{
+ if (self->_ininlineimage == 1) {
+ self->_ininlineimage = 2;
+ return _parseInlineImage(self, c);
+ } else if (self->_ininlineimage == 2) {
+ Token *token = NULL;
+ self->_ininlineimage = 0;
+ token = new_operand(pdf_operator);
+ token->string = strdup("EI");
+ return token;
+ }
+ if (c < 0)
+ return NULL;
+ switch (c) {
+ case '(':
+ return _parseString(self, c);
+ break;
+ case ')':
+ return _parseError(c);
+ break;
+ case '[':
+ return _parseStartarray();
+ break;
+ case ']':
+ return _parseStoparray();
+ break;
+ case '/':
+ return _parseName(self, c);
+ break;
+ case '<':
+ return _parseLt(self, c);
+ break;
+ case '>':
+ return _parseGt(self, c);
+ break;
+ case '%':
+ return _parseComment(self, c);
+ break;
+ case ' ':
+ case '\r':
+ case '\n':
+ case '\t':
+ return _parseSpace(self);
+ break;
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ case '-':
+ case '.':
+ return _parseNumber(self, c);
+ break;
+ default:
+ if (c <= 127) {
+ return _parseOperator(self, c);
+ } else {
+ return _parseError(c);
+ }
+ }
+}
+
+static int scanner_scan(lua_State * L)
+{
+ Token *token;
+ scannerdata *self;
+ if (lua_gettop(L) != 3) {
+ return 0;
+ }
+ luaL_checktype(L, 2, LUA_TTABLE);
+ luaL_checktype(L, 3, LUA_TTABLE);
+ self = scanner_push(L);
+ memset(self, 0, sizeof(scannerdata));
+ self->_operandstack = (Token **) priv_xmalloc(MAXOPERANDS * sizeof(Token));
+ memset(self->_operandstack, 0, (MAXOPERANDS * sizeof(Token)));
+ /*tex stack slot 4 = self */
+ self->uses_stream = 1;
+ if (lua_type(L, 1) == LUA_TSTRING) {
+ /*tex
+ We could make a temporary copy on the stack (or in the registry)
+ which saves memory.
+ */
+ char *buf = NULL;
+ const char *s = lua_tolstring(L, 1, &self->size);
+ if (s==NULL){
+ fprintf(stderr,"fatal: cannot convert the token to string.");
+ exit(1);
+ }
+ buf = priv_xmalloc(self->size+1);
+ buf[self->size]='\0';
+ self->uses_stream = 0;
+ memcpy(buf,s,self->size);
+ self->buffer = buf;
+ } else if (lua_type(L, 1) == LUA_TTABLE) {
+ udstruct *uin;
+ void *ud;
+ int i = 1;
+ while (1) {
+ lua_rawgeti(L, 1, i);
+ if (lua_type(L, -1) == LUA_TUSERDATA) {
+ ud = luaL_checkudata(L, -1, PDFE_METATABLE_STREAM);
+ if (ud != NULL) {
+ ObjectList *rover = NULL;
+ ObjectList *item = NULL;
+ uin = (udstruct *) ud;
+ rover = self->_streams;
+ item = (ObjectList *) priv_xmalloc(sizeof(ObjectList));
+ item->stream = ((ppstream *) uin->d);
+ item->next = NULL;
+ if (!rover) {
+ rover = item;
+ self->_streams = rover;
+ } else {
+ while (rover->next)
+ rover = rover->next;
+ rover->next = item;
+ }
+ }
+ } else {
+ ObjectList *rover = self->_streams;
+ self->_stream = rover->stream;
+ self->_streams = rover->next;
+ free(rover);
+ lua_pop(L, 1);
+ break;
+ }
+ lua_pop(L, 1);
+ i++;
+ }
+ } else {
+ udstruct *uin;
+ void *ud;
+ luaL_checktype(L, 1, LUA_TUSERDATA);
+ ud = luaL_checkudata(L, 1, PDFE_METATABLE_STREAM);
+ if (ud != NULL) {
+ uin = (udstruct *) ud;
+ self->_stream = ((ppstream *) uin->d);
+ } else {
+ ud = luaL_checkudata(L, 1, PDFE_METATABLE_ARRAY);
+ if (ud != NULL) {
+ ObjectList *rover = NULL;
+ pparray *array = NULL;
+ int count;
+ int i;
+ uin = (udstruct *) ud;
+ array = (pparray *) uin->d;
+ count = array->size;
+ for (i = 0; i < count; i++) {
+ ppobj *obj = pparray_at(array, i);
+ if (obj->type == PPSTREAM) {
+ ObjectList *rover = self->_streams;
+ ObjectList *item =
+ (ObjectList *)
+ priv_xmalloc(sizeof(ObjectList));
+ item->stream = obj->stream;
+ item->next = NULL;
+ if (!rover) {
+ rover = item;
+ self->_streams = rover;
+ } else {
+ while (rover->next)
+ rover = rover->next;
+ rover->next = item;
+ }
+ }
+ }
+ rover = self->_streams;
+ self->_stream = rover->stream;
+ self->_streams = rover->next;
+ }
+ }
+ }
+ streamReset(self);
+ token = _parseToken(self, streamGetChar(self));
+ while (token) {
+ if (token->type == pdf_operator) {
+ lua_pushstring(L, token->string);
+ free_token(token);
+ /*tex fetch operator table */
+ lua_rawget(L, 2);
+ if (lua_isfunction(L, -1)) {
+ lua_pushvalue(L, 4);
+ lua_pushvalue(L, 3);
+ (void) lua_call(L, 2, 0);
+ } else {
+ /*tex nil */
+ lua_pop(L, 1);
+ }
+ clear_operand_stack(self, 0);
+ } else {
+ push_operand(self, token);
+ }
+ if (self->uses_stream) {
+ if (!self->_stream) {
+ break;
+ }
+ } else {
+ if (self->buffer == NULL) {
+ break;
+ }
+ }
+ token = _parseToken(self, streamGetChar(self));
+ }
+ /*tex wrap up */
+ if (self->_stream) {
+ streamClose(self);
+ }
+ clear_operand_stack(self, 0);
+ free(self->_operandstack);
+ return 0;
+}
+
+static int scanner_done(lua_State * L)
+{
+ int c;
+ scannerdata *self = scanner_check(L, 1);
+ while ((c = streamGetChar(self)) >= 0);
+ return 0;
+}
+
+/*tex here are the stack popping functions, and their helpers */
+
+static void operandstack_backup(scannerdata * self)
+{
+ int i = self->_nextoperand - 1;
+ int balance = 0;
+ int backupstart = 0;
+ int backupstop = self->_operandstack[i]->type;
+ if (backupstop == pdf_stopdict) {
+ backupstart = pdf_startdict;
+ } else if (backupstop == pdf_stoparray) {
+ backupstart = pdf_startarray;
+ } else {
+ return;
+ }
+ for (; i >= 0; i--) {
+ if (self->_operandstack[i]->type == backupstop) {
+ balance++;
+ } else if (self->_operandstack[i]->type == backupstart) {
+ balance--;
+ }
+ if (balance == 0) {
+ break;
+ }
+ }
+ self->_nextoperand = i + 1;
+}
+
+static void push_array(lua_State * L, scannerdata * self)
+{
+ /*tex nesting tracking */
+ int balance = 1;
+ /*tex \LUA\ array index */
+ int index = 1;
+ Token *token = self->_operandstack[self->_nextoperand++];
+ lua_newtable(L);
+ while (token) {
+ if (token->type == pdf_stoparray)
+ balance--;
+ if (token->type == pdf_startarray)
+ balance++;
+ if (!balance) {
+ break;
+ } else {
+ push_token(L, self);
+ lua_rawseti(L, -2, index++);
+ }
+ token = self->_operandstack[self->_nextoperand++];
+ }
+}
+
+
+static void push_dict(lua_State * L, scannerdata * self)
+{
+ /*tex nesting tracking */
+ int balance = 1;
+ /*tex toggle between \LUA\ value and \LUA\ key */
+ int needskey = 1;
+ Token *token = self->_operandstack[self->_nextoperand++];
+ lua_newtable(L);
+ while (token) {
+ if (token->type == pdf_stopdict)
+ balance--;
+ if (token->type == pdf_startdict)
+ balance++;
+ if (!balance) {
+ break;
+ } else if (needskey) {
+ lua_pushlstring(L, token->string, token->value);
+ needskey = 0;
+ } else {
+ push_token(L, self);
+ needskey = 1;
+ lua_rawset(L, -3);
+ }
+ token = self->_operandstack[self->_nextoperand++];
+ }
+}
+
+const char *typenames[pdf_stopdict + 1] = {
+ "unknown", "integer", "real", "boolean", "name", "operator",
+ "string", "array", "array", "dict", "dict"
+};
+
+static void push_token(lua_State * L, scannerdata * self)
+{
+ Token *token = self->_operandstack[self->_nextoperand - 1];
+ lua_createtable(L, 2, 0);
+ lua_pushstring(L, typenames[token->type]);
+ lua_rawseti(L, -2, 1);
+ if (token->type == pdf_string || token->type == pdf_name) {
+ lua_pushlstring(L, token->string, token->value);
+ } else if (token->type == pdf_real || token->type == pdf_integer) {
+ /*tex This is an integer or float. */
+ lua_pushnumber(L, token->value);
+ } else if (token->type == pdf_boolean) {
+ lua_pushboolean(L, (int) token->value);
+ } else if (token->type == pdf_startarray) {
+ push_array(L, self);
+ } else if (token->type == pdf_startdict) {
+ push_dict(L, self);
+ } else {
+ lua_pushnil(L);
+ }
+ lua_rawseti(L, -2, 2);
+}
+
+static int scanner_popsingular(lua_State * L, int token_type)
+{
+ Token *token = NULL;
+ /*tex this keeps track of how much of the operand stack needs deleting: */
+ int clear = 0;
+ scannerdata *self = scanner_check(L, 1);
+ if (self->_nextoperand == 0) {
+ return 0;
+ }
+ clear = self->_nextoperand - 1;
+ token = self->_operandstack[self->_nextoperand - 1];
+ if (token == NULL || (token->type != token_type)) {
+ return 0;
+ }
+ /*tex
+ The simple cases can be written out directly, but dicts and
+ arrays are better done via the recursive function.
+ */
+ if (token_type == pdf_stoparray || token_type == pdf_stopdict) {
+ operandstack_backup(self);
+ clear = self->_nextoperand - 1;
+ push_token(L, self);
+ lua_rawgeti(L, -1, 2);
+ } else if (token_type == pdf_real || token_type == pdf_integer) {
+ /*tex the number can be an integer or float */
+ lua_pushnumber(L, token->value);
+ } else if (token_type == pdf_boolean) {
+ lua_pushboolean(L, (int) token->value);
+ } else if (token_type == pdf_name || token_type == pdf_string) {
+ lua_pushlstring(L, token->string, token->value);
+ } else {
+ return 0;
+ }
+ clear_operand_stack(self, clear);
+ return 1;
+}
+
+static int scanner_popanything(lua_State * L)
+{
+ Token *token = NULL;
+ /*tex how much of the operand stack needs deleting: */
+ int clear = 0;
+ int token_type;
+ scannerdata *self = scanner_check(L, 1);
+ if (self->_nextoperand == 0) {
+ return 0;
+ }
+ clear = self->_nextoperand - 1;
+ token = self->_operandstack[self->_nextoperand - 1];
+ if (token == NULL) {
+ return 0;
+ }
+ token_type = token->type;
+ /*tex
+ The simple cases can be written out directly, but dicts and
+ arrays are better done via the recursive function.
+ */
+ if (token_type == pdf_stoparray || token_type == pdf_stopdict) {
+ operandstack_backup(self);
+ clear = self->_nextoperand - 1;
+ push_token(L, self);
+ } else {
+ push_token(L, self);
+ }
+ clear_operand_stack(self, clear);
+ return 1;
+}
+
+static int scanner_popnumber(lua_State * L)
+{
+ if (scanner_popsingular(L, pdf_real))
+ return 1;
+ if (scanner_popsingular(L, pdf_integer))
+ return 1;
+ lua_pushnil(L);
+ return 1;
+}
+
+static int scanner_popboolean(lua_State * L)
+{
+ if (scanner_popsingular(L, pdf_boolean))
+ return 1;
+ lua_pushnil(L);
+ return 1;
+}
+
+static int scanner_popstring(lua_State * L)
+{
+ if (scanner_popsingular(L, pdf_string))
+ return 1;
+ lua_pushnil(L);
+ return 1;
+}
+
+static int scanner_popname(lua_State * L)
+{
+ if (scanner_popsingular(L, pdf_name))
+ return 1;
+ lua_pushnil(L);
+ return 1;
+}
+
+static int scanner_poparray(lua_State * L)
+{
+ if (scanner_popsingular(L, pdf_stoparray))
+ return 1;
+ lua_pushnil(L);
+ return 1;
+}
+
+static int scanner_popdictionary(lua_State * L)
+{
+ if (scanner_popsingular(L, pdf_stopdict))
+ return 1;
+ lua_pushnil(L);
+ return 1;
+}
+
+static int scanner_popany(lua_State * L)
+{
+ if (scanner_popanything(L))
+ return 1;
+ lua_pushnil(L);
+ return 1;
+}
+
+static const luaL_Reg scannerlib_meta[] = {
+ {0, 0}
+};
+
+static const struct luaL_Reg scannerlib_m[] = {
+ { "done", scanner_done },
+ { "pop", scanner_popany },
+ { "popnumber", scanner_popnumber },
+ { "popname", scanner_popname },
+ { "popstring", scanner_popstring },
+ { "poparray", scanner_poparray },
+ { "popdictionary", scanner_popdictionary },
+ { "popboolean", scanner_popboolean },
+ /*tex For old times sake: */
+ { "popNumber", scanner_popnumber },
+ { "popName", scanner_popname },
+ { "popString", scanner_popstring },
+ { "popArray", scanner_poparray },
+ { "popDict", scanner_popdictionary },
+ { "popBool", scanner_popboolean },
+ /*tex Sentinel: */
+ { NULL, NULL }
+};
+
+static const luaL_Reg scannerlib[] = {
+ { "scan", scanner_scan },
+ /*tex Sentinel: */
+ { NULL, NULL }
+};
+
+LUALIB_API int luaopen_pdfscanner(lua_State * L)
+{
+ luaL_newmetatable(L, SCANNER);
+ luaL_openlib(L, 0, scannerlib_meta, 0);
+ lua_pushvalue(L, -1);
+ lua_setfield(L, -2, "__index");
+ luaL_openlib(L, NULL, scannerlib_m, 0);
+ luaL_openlib(L, "pdfscanner", scannerlib, 0);
+ return 1;
+}
diff --git a/Build/source/texk/web2c/luatexdir/lua/luainit.w b/Build/source/texk/web2c/luatexdir/lua/luainit.c
index dec76b0216b..60c654aa0a0 100644
--- a/Build/source/texk/web2c/luatexdir/lua/luainit.w
+++ b/Build/source/texk/web2c/luatexdir/lua/luainit.c
@@ -1,23 +1,25 @@
-% luainit.w
-%
-% Copyright 2006-2018 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
+/*
+
+luainit.w
+
+Copyright 2006-2018 Taco Hoekwater <taco@@luatex.org>
+
+This file is part of LuaTeX.
+
+LuaTeX is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version.
+
+LuaTeX is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU General Public License along
+with LuaTeX; if not, see <http://www.gnu.org/licenses/>.
+
+*/
#include "ptexlib.h"
@@ -29,27 +31,23 @@
extern int load_luatex_core_lua (lua_State * L);
-/* internalized strings: see luatex-api.h */
-set_make_keys;
+/*tex internalized strings: see luatex-api.h */
-@
-This file is getting a bit messy, but it is not simple to fix unilaterally.
+set_make_keys;
-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.
+/*tex
-In fact, it sets three C variables:
+This file is getting a bit messy, but it is not simple to fix unilaterally. In
+fact, it sets three C variables:
- |kpse_invocation_name| |kpse_invocation_short_name| |kpse->program_name|
+ |kpse_invocation_name| |kpse_invocation_short_name| |kpse->program_name|
and five environment variables:
- SELFAUTOLOC SELFAUTODIR SELFAUTOPARENT SELFAUTOGRANDPARENT progname
+ |SELFAUTOLOC| |SELFAUTODIR| |SELFAUTOPARENT| |SELFAUTOGRANDPARENT| |progname|
+
+*/
-@c
const_string LUATEX_IHELP[] = {
"Usage: " my_name " --lua=FILE [OPTION]... [TEXNAME[.tex]] [COMMANDS]",
" or: " my_name " --lua=FILE [OPTION]... \\FIRST-LINE",
@@ -109,9 +107,13 @@ const_string LUATEX_IHELP[] = {
NULL
};
-@ Later we will put on environment |LC_CTYPE|, |LC_COLLATE| and
-|LC_NUMERIC| set to |C|, so we need a place where to store the old values.
-@c
+/*tex
+
+Later we will put on environment |LC_CTYPE|, |LC_COLLATE| and |LC_NUMERIC| set to
+|C|, so we need a place where to store the old values.
+
+*/
+
const char *lc_ctype;
const char *lc_collate;
const char *lc_numeric;
@@ -126,26 +128,28 @@ const char *lc_numeric;
" --translate-file=FILE ignored, input is assumed to be in UTF-8 encoding",
*/
-@ The return value will be the directory of the executable, e.g.: \.{c:/TeX/bin}
-@c
+/*tex
+
+The return value will be the directory of the executable, e.g.: \.{c:/TeX/bin}
+
+*/
+
static char *ex_selfdir(char *argv0)
{
#if defined(WIN32)
#if defined(__MINGW32__)
char path[PATH_MAX], *fp;
-
- /* SearchPath() always gives back an absolute directory */
+ /*tex SearchPath() always gives back an absolute directory */
if (SearchPath(NULL, argv0, ".exe", PATH_MAX, path, NULL) == 0)
FATAL1("Can't determine where the executable %s is.\n", argv0);
- /* slashify the dirname */
+ /*tex slashify the dirname */
for (fp = path; fp && *fp; fp++)
if (IS_DIR_SEP(*fp))
*fp = DIR_SEP;
#else /* __MINGW32__ */
#define PATH_MAX 512
char short_path[PATH_MAX], path[PATH_MAX], *fp;
-
- /* SearchPath() always gives back an absolute directory */
+ /*tex 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 (getlongpath(path, short_path, sizeof(path)) == 0) {
@@ -158,7 +162,6 @@ static char *ex_selfdir(char *argv0)
#endif
}
-@ @c
static void prepare_cmdline(lua_State * L, char **av, int ac, int zero_offset)
{
int i;
@@ -178,11 +181,8 @@ static void prepare_cmdline(lua_State * L, char **av, int ac, int zero_offset)
return;
}
-
-@ @c
int kpse_init = -1;
-@ @c
string input_name = NULL;
static string user_progname = NULL;
@@ -201,22 +201,20 @@ int safer_option = 0;
int nosocket_option = 0;
int utc_option = 0;
-@ Reading the options.
+/*tex
-@ 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.
*/
-/*
+#define ARGUMENT_IS(a) STREQ (long_options[option_index].name, a)
+
+/*tex
Nota Bene: we still intercept some options that other engines handle
so that existing scripted usage will not fail.
+
+ SunOS cc can't initialize automatic structs, so make this static.
*/
static struct option long_options[] = {
@@ -253,9 +251,7 @@ static struct option long_options[] = {
{"debug-format", 0, &debug_format_file, 1},
{"file-line-error-style", 0, &filelineerrorstylep, 1},
{"no-file-line-error-style", 0, &filelineerrorstylep, -1},
-
- /* Shorter option names for the above. */
-
+ /*tex Shorter option names for the above. */
{"file-line-error", 0, &filelineerrorstylep, 1},
{"no-file-line-error", 0, &filelineerrorstylep, -1},
{"jobname", 1, 0, 0},
@@ -266,18 +262,16 @@ static struct option long_options[] = {
{"8bit", 0, 0, 0},
{"mktex", 1, 0, 0},
{"no-mktex", 1, 0, 0},
-
- /* Synchronization: just like "interaction" above */
-
+ /*tex Synchronization: just like ``interaction'' above */
{"synctex", 1, 0, 0},
{0, 0, 0, 0}
};
-@ @c
int lua_numeric_field_by_index(lua_State * L, int name_index, int dflt)
{
register int i = dflt;
- lua_rawgeti(L, LUA_REGISTRYINDEX, name_index); /* fetch the stringptr */
+ /*tex fetch the stringptr */
+ lua_rawgeti(L, LUA_REGISTRYINDEX, name_index);
lua_rawget(L, -2);
if (lua_type(L, -1) == LUA_TNUMBER) {
i = lua_roundnumber(L, -1);
@@ -286,11 +280,11 @@ int lua_numeric_field_by_index(lua_State * L, int name_index, int dflt)
return i;
}
-@ @c
unsigned int lua_unsigned_numeric_field_by_index(lua_State * L, int name_index, int dflt)
{
register unsigned int i = dflt;
- lua_rawgeti(L, LUA_REGISTRYINDEX, name_index); /* fetch the stringptr */
+ /*tex fetch the stringptr */
+ lua_rawgeti(L, LUA_REGISTRYINDEX, name_index);
lua_rawget(L, -2);
if (lua_type(L, -1) == LUA_TNUMBER) {
i = lua_uroundnumber(L, -1);
@@ -299,20 +293,21 @@ unsigned int lua_unsigned_numeric_field_by_index(lua_State * L, int name_index,
return i;
}
-@ @c
static int recorderoption = 0;
static void parse_options(int ac, char **av)
{
#ifdef WIN32
-/* save argc and argv */
+ /*tex We save |argc| and |argv|. */
int sargc = argc;
char **sargv = argv;
#endif
- int g; /* `getopt' return code. */
+ /*tex The `getopt' return code. */
+ int g;
int option_index;
char *firstfile = NULL;
- opterr = 0; /* dont whine */
+ /*tex Dont whine. */
+ opterr = 0;
#ifdef LuajitTeX
if ((strstr(argv[0], "luajittexlua") != NULL) ||
(strstr(argv[0], "texluajit") != NULL)) {
@@ -326,37 +321,39 @@ static void parse_options(int ac, char **av)
for (;;) {
g = getopt_long_only(ac, av, "+", long_options, &option_index);
- if (g == -1) /* End of arguments, exit the loop. */
+ if (g == -1) {
+ /*tex End of arguments, exit the loop. */
break;
- if (g == '?') { /* Unknown option. */
- if (!luainit)
- fprintf(stderr,"%s: unrecognized option '%s'\n", argv[0], argv[optind-1]);
- continue;
}
-
- assert(g == 0); /* We have no short option names. */
-
+ if (g == '?') {
+ /*tex Unknown option. */
+ if (!luainit)
+ fprintf(stderr,"%s: unrecognized option '%s'\n", argv[0], argv[optind-1]);
+ continue;
+ }
+ /* We have no short option names. */
+ assert(g == 0);
if (ARGUMENT_IS("luaonly")) {
lua_only = 1;
lua_offset = optind;
luainit = 1;
} else if (ARGUMENT_IS("lua")) {
- startup_filename = xstrdup(optarg);
+ startup_filename = optarg;
lua_offset = (optind - 1);
luainit = 1;
#ifdef LuajitTeX
} else if (ARGUMENT_IS("jiton")) {
luajiton = 1;
} else if (ARGUMENT_IS("jithash")) {
- size_t len = strlen(optarg);
- if (len<16) {
- jithash_hashname = optarg;
- } else {
- WARNING2("hash name truncated to 15 characters from %d. (%s)", (int) len, optarg);
- jithash_hashname = (string) xmalloc(16);
- strncpy(jithash_hashname, optarg, 15);
- jithash_hashname[15] = 0;
- }
+ size_t len = strlen(optarg);
+ if (len<16) {
+ jithash_hashname = optarg;
+ } else {
+ WARNING2("hash name truncated to 15 characters from %d. (%s)", (int) len, optarg);
+ jithash_hashname = (string) xmalloc(16);
+ strncpy(jithash_hashname, optarg, 15);
+ jithash_hashname[15] = 0;
+ }
#endif
} else if (ARGUMENT_IS("luahashchars")) {
show_luahashchars = 1;
@@ -414,7 +411,7 @@ static void parse_options(int ac, char **av)
WARNING1("Ignoring unknown argument `%s' to --interaction", optarg);
}
} else if (ARGUMENT_IS("synctex")) {
- /* Synchronize TeXnology: catching the command line option as a long */
+ /*tex Synchronize TeXnology: catching the command line option as a long */
synctexoption = (int) strtol(optarg, NULL, 0);
} else if (ARGUMENT_IS("recorder")) {
recorderoption = 1 ;
@@ -445,8 +442,8 @@ static void parse_options(int ac, char **av)
"pdftex : Han The Thanh and friends\n"
"kpathsea : Karl Berry, Olaf Weber and others\n"
"lua : Roberto Ierusalimschy, Waldemar Celes and Luiz Henrique de Figueiredo\n"
- "metapost : John Hobby, Taco Hoekwater and friends\n"
- "poppler : Derek Noonburg, Kristian Hogsberg (partial)\n"
+ "metapost : John Hobby, Taco Hoekwater, Luigi Scarso, Hans Hagen and friends\n"
+ "pplib : Paweł Jackowski\n"
"fontforge : George Williams (partial)\n"
"luajit : Mike Pall (used in LuajitTeX)\n");
/* *INDENT-ON* */
@@ -454,7 +451,7 @@ static void parse_options(int ac, char **av)
uexit(0);
}
}
- /* attempt to find |input_name| / |dump_name| */
+ /*tex attempt to find |input_name| and |dump_name| */
if (lua_only) {
if (argv[optind]) {
startup_filename = xstrdup(argv[optind]);
@@ -502,20 +499,23 @@ static void parse_options(int ac, char **av)
return;
#endif
}
- if (safer_option) /* --safer implies --nosocket */
+ /*tex |--safer| implies |--nosocket| */
+ if (safer_option)
nosocket_option = 1;
- /* Finalize the input filename. */
+ /*tex Finalize the input filename. */
if (input_name != NULL) {
argv[optind] = normalize_quotes(input_name, "argument");
}
}
-@ test for readability
-@c
-#define is_readable(a) (stat(a,&finfo)==0) && S_ISREG(finfo.st_mode) && \
- (f=fopen(a,"r")) != NULL && !fclose(f)
+/*tex
+ Test for readability.
+*/
+
+#define is_readable(a) (stat(a,&finfo)==0) \
+ && S_ISREG(finfo.st_mode) \
+ && (f=fopen(a,"r")) != NULL && !fclose(f)
-@ @c
static char *find_filename(char *name, const char *envkey)
{
struct stat finfo;
@@ -543,8 +543,6 @@ static char *find_filename(char *name, const char *envkey)
return NULL;
}
-@ @c
-
static void init_kpse(void)
{
if (!user_progname) {
@@ -576,11 +574,10 @@ static void init_kpse(void)
user_progname = dump_name;
}
}
- kpse_set_program_enabled(kpse_fmt_format, MAKE_TEX_FMT_BY_DEFAULT,
- kpse_src_compile);
-
+ kpse_set_program_enabled(kpse_fmt_format, MAKE_TEX_FMT_BY_DEFAULT, kpse_src_compile);
kpse_set_program_name(argv[0], user_progname);
- init_shell_escape(); /* set up 'restrictedshell' */
+ /*tex set up 'restrictedshell' */
+ init_shell_escape();
init_start_time();
program_name_set = 1 ;
if (recorderoption) {
@@ -588,19 +585,18 @@ static void init_kpse(void)
}
}
-@ @c
static void fix_dumpname(void)
{
int dist;
if (dump_name) {
- /* adjust array for Pascal and provide extension, if needed */
+ /*tex Adjust array for Pascal and provide extension, if needed. */
dist = (int) (strlen(dump_name) - strlen(DUMP_EXT));
if (strstr(dump_name, DUMP_EXT) == dump_name + dist)
TEX_format_default = dump_name;
else
TEX_format_default = concat(dump_name, DUMP_EXT);
} else {
- /* For |dump_name| to be NULL is a bug. */
+ /*tex For |dump_name| to be NULL is a bug. */
if (!ini_version) {
fprintf(stdout, "no format given, quitting\n");
exit(1);
@@ -608,17 +604,17 @@ static void fix_dumpname(void)
}
}
-@ lua require patch
-
-@ Auxiliary function for kpse search
+/*tex
+ 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)
+ kpse_file_format_type format, const char *errname)
{
const char *filename;
const char *altname;
- altname = luaL_gsub(L, name, ".", "/"); /* Lua convention */
+ /*tex Lua convention */
+ altname = luaL_gsub(L, name, ".", "/");
filename = kpse_find_file(altname, format, false);
if (filename == NULL) {
filename = kpse_find_file(name, format, false);
@@ -629,16 +625,17 @@ static const char *luatex_kpse_find_aux(lua_State *L, const char *name,
return filename;
}
-@ The lua search function.
+/*tex
+
+ Here comes 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.
-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 .
-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 luatex_kpse_lua_find(lua_State * L)
@@ -653,16 +650,18 @@ static int luatex_kpse_lua_find(lua_State * L)
return 1;
}
filename = luatex_kpse_find_aux(L, name, kpse_lua_format, "lua");
- if (filename == NULL)
- return 1; /* library not found in this path */
+ if (filename == NULL) {
+ /*tex library not found in this path */
+ return 1;
+ }
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));
+ lua_tostring(L, 1), filename, lua_tostring(L, -1));
}
- return 1; /* library loaded successfully */
+ /*tex library loaded successfully */
+ return 1;
}
-@ @c
static int clua_loader_function = 0;
extern int searcher_C_luatex (lua_State *L, const char *name, const char *filename);
@@ -671,8 +670,9 @@ static int luatex_kpse_clua_find(lua_State * L)
const char *filename;
const char *name;
if (safer_option) {
+ /*tex library not found in this path */
lua_pushliteral(L, "\n\t[C searcher disabled in safer mode]");
- return 1; /* library not found in this path */
+ return 1;
}
name = luaL_checkstring(L, 1);
if (program_name_set == 0) {
@@ -687,12 +687,16 @@ static int luatex_kpse_clua_find(lua_State * L)
char *temp_name;
int j;
filename = luatex_kpse_find_aux(L, name, kpse_clua_format, "C");
- if (filename == NULL)
- return 1; /* library not found in this path */
+ if (filename == NULL) {
+ /*tex library not found in this path */
+ return 1;
+ }
extensionless = strdup(filename);
- if (!extensionless)
- return 1; /* allocation failure */
- /* Fix Issue 850: replace '.' with LUA_DIRSEP */
+ if (!extensionless) {
+ /*tex allocation failure */
+ return 1;
+ }
+ /*tex Replace '.' with |LUA_DIRSEP| */
temp_name = strdup(name);
for(j=0; ; j++){
if ((unsigned char)temp_name[j]=='\0') {
@@ -703,33 +707,44 @@ static int luatex_kpse_clua_find(lua_State * L)
}
}
p = strstr(extensionless, temp_name);
- if (!p) return 1; /* this would be exceedingly weird */
+ if (!p) {
+ /*tex this would be exceedingly weird */
+ return 1;
+ }
*p = '\0';
prefix = strdup(extensionless);
- if (!prefix) return 1; /* allocation failure */
+ if (!prefix) {
+ /*tex allocation failure */
+ return 1;
+ }
postfix = strdup(p+strlen(name));
- if (!postfix) return 1; /* allocation failure */
+ if (!postfix) {
+ /*tex allocation failure */
+ return 1;
+ }
total = malloc(strlen(prefix)+strlen(postfix)+2);
if (!total) return 1; /* allocation failure */
snprintf(total,strlen(prefix)+strlen(postfix)+2, "%s?%s", prefix, postfix);
- /* save package.path */
+ /*tex save package.path */
lua_getglobal(L,"package");
lua_getfield(L,-1,"cpath");
path_saved = lua_tostring(L,-1);
lua_pop(L,1);
- /* set package.path = "?" */
+ /*tex set package.path = "?" */
lua_pushstring(L,total);
lua_setfield(L,-2,"cpath");
- lua_pop(L,1); /* pop "package" */
- /* run function */
+ /*tex pop ``package'' */
+ lua_pop(L,1);
+ /*tex run function */
lua_rawgeti(L, LUA_REGISTRYINDEX, clua_loader_function);
lua_pushstring(L, name);
lua_call(L, 1, 1);
- /* restore package.path */
+ /*tex restore package.path */
lua_getglobal(L,"package");
lua_pushstring(L,path_saved);
lua_setfield(L,-2,"cpath");
- lua_pop(L,1); /* pop "package" */
+ /*tex pop ``package'' */
+ lua_pop(L,1);
free(extensionless);
free(total);
free(temp_name);
@@ -737,12 +752,13 @@ static int luatex_kpse_clua_find(lua_State * L)
}
}
-@ Setting up the new search functions.
+/*tex
+
+ Setting up the new search functions. This replaces package.searchers[2] and
+ package.searchers[3] with the functions defined above.
-This replaces package.searchers[2] and package.searchers[3] with the
-functions defined above.
+*/
-@c
static void setup_lua_path(lua_State * L)
{
lua_getglobal(L, "package");
@@ -751,46 +767,45 @@ static void setup_lua_path(lua_State * L)
#else
lua_getfield(L, -1, "searchers");
#endif
- lua_rawgeti(L, -1, 2); /* package.searchers[2] */
+ /*tex package.searchers[2] */
+ lua_rawgeti(L, -1, 2);
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.searchers[3] */
+ /*tex replace the normal lua loader */
+ lua_rawseti(L, -2, 2);
+ /*tex package.searchers[3] */
+ lua_rawgeti(L, -1, 3);
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_pop(L, 2); /* pop the array and table */
+ /*tex replace the normal lua lib loader */
+ lua_rawseti(L, -2, 3);
+ /*tex pop the array and table */
+ lua_pop(L, 2);
}
-@ helper variables for the safe keeping of table ids
+/*tex
+
+ 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;
*/
-@ @c
int l_pack_type_index [PACK_TYPE_SIZE] ;
int l_group_code_index [GROUP_CODE_SIZE];
int l_local_par_index [LOCAL_PAR_SIZE];
int l_math_style_name_index [MATH_STYLE_NAME_SIZE];
int l_dir_par_index [DIR_PAR_SIZE];
-int l_dir_text_index [DIR_TEXT_SIZE];
+int l_dir_text_index_normal [DIR_TEXT_SIZE];
+int l_dir_text_index_cancel [DIR_TEXT_SIZE];
int img_parms [img_parms_max];
int img_pageboxes [img_pageboxes_max];
-int lua_show_valid_list(lua_State *L, const char **list, int max)
+int lua_show_valid_list(lua_State *L, const char **list, int offset, int max)
{
int i;
lua_newtable(L);
for (i = 0; i < max; i++) {
- lua_pushinteger(L,i+1);
+ lua_pushinteger(L,i+offset);
lua_pushstring(L, list[i]);
lua_settable(L, -3);
}
@@ -812,28 +827,31 @@ int lua_show_valid_keys(lua_State *L, int *list, int max)
#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"
+/* Why do we add script stuff to this weird incomplete. Let's go more minimal. */
+
+/*
+ #define EXE_SUFFIXES ".com;.exe;.bat;.cmd;.vbs;.vbe;.js;.jse;.wsf;.wsh;.ws;.tcl;.py;.pyw"
+*/
+
+#define EXE_SUFFIXES ".com;.exe;.bat;.cmd"
-@ @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 */
+ /*tex strlwr() exists also in MingW */
+ if (v)
v = (char *) strlwr(xstrdup(v));
else
v = xstrdup(EXE_SUFFIXES);
# endif
-
q = v;
n = 0;
-
while ((r = strchr(q, ';')) != NULL) {
n++;
r++;
@@ -862,12 +880,10 @@ static void mk_suffixlist(void)
}
#endif
-@ @c
void lua_initialize(int ac, char **av)
{
char *given_file = NULL;
char *banner;
- /*int kpse_init;*/
size_t len;
int starttime;
int utc;
@@ -878,7 +894,7 @@ void lua_initialize(int ac, char **av)
char *old_locale = NULL;
char *env_locale = NULL;
char *tmp = NULL;
- /* Save to pass along to topenin. */
+ /*tex Save to pass along to topenin. */
const char *fmt = "This is " MyName ", Version %s" WEB2CVERSION;
argc = ac;
argv = av;
@@ -887,8 +903,7 @@ void lua_initialize(int ac, char **av)
sprintf(banner, fmt, luatex_version_string);
luatex_banner = banner;
kpse_invocation_name = kpse_program_basename(argv[0]);
-
- /* be 'luac' */
+ /*tex be `luac' */
if (argc >1) {
#ifdef LuajitTeX
if (FILESTRCASEEQ(kpse_invocation_name, "texluajitc"))
@@ -911,106 +926,104 @@ void lua_initialize(int ac, char **av)
#if defined(WIN32) || defined(__MINGW32__) || defined(__CYGWIN__)
mk_suffixlist();
#endif
-
- /* Must be initialized before options are parsed. */
+ /*tex 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. */
+ /*tex
+ In the next option 0 means ``disable Synchronize TeXnology''. The
+ |synctexoption| is a *.web variable. We initialize it to a weird value to
+ catch the -synctex command line flag At runtime, if synctexoption is not
+ |INT_MAX|, then it contains the command line option provided, otherwise
+ no such option was given by the user.
+ */
#define SYNCTEX_NO_OPTION INT_MAX
synctexoption = SYNCTEX_NO_OPTION;
-
- /* parse commandline */
+ /*tex parse commandline */
parse_options(ac, av);
if (lua_only) {
- /* Shell has no restrictions. */
+ /*tex Shell has no restrictions. */
shellenabledp = true;
restrictedshell = false;
safer_option = 0;
}
- /* Get the current locale (it should be C ) */
- /* and save LC_CTYPE, LC_COLLATE and LC_NUMERIC. */
- /* Later luainterpreter() will consciously use them. */
+ /*tex
+ Get the current locale (it should be |C|) and save |LC_CTYPE|, |LC_COLLATE|
+ and |LC_NUMERIC|. Later |luainterpreter()| will consciously use them.
+ */
old_locale = xstrdup(setlocale (LC_ALL, NULL));
lc_ctype = NULL;
lc_collate = NULL;
lc_numeric = NULL;
if (old_locale) {
- /* If setlocale fails here, then the state */
- /* could be compromised, and we exit. */
+ /*tex
+ If |setlocale| fails here, then the state could be compromised, and
+ we exit.
+ */
env_locale = setlocale (LC_ALL, "");
- if (!env_locale && !lua_only) {
- fprintf(stderr,"Unable to read environment locale: exit now.\n");
- exit(1);
- }
+ if (!env_locale && !lua_only) {
+ fprintf(stderr,"Unable to read environment locale: exit now.\n");
+ exit(1);
+ }
tmp = setlocale (LC_CTYPE, NULL);
- if (tmp) {
- lc_ctype = xstrdup(tmp);
+ if (tmp) {
+ lc_ctype = xstrdup(tmp);
}
- tmp = setlocale (LC_COLLATE, NULL);
- if (tmp){
- lc_collate = xstrdup(tmp);
+ tmp = setlocale (LC_COLLATE, NULL);
+ if (tmp) {
+ lc_collate = xstrdup(tmp);
}
- tmp = setlocale (LC_NUMERIC, NULL);
- if (tmp){
- lc_numeric = xstrdup(tmp);
+ tmp = setlocale (LC_NUMERIC, NULL);
+ if (tmp) {
+ lc_numeric = xstrdup(tmp);
+ }
+ /*tex
+ Return to the previous locale if possible, otherwise it's a serious
+ error and we exit: we can't ensure a 'sane' locale for lua.
+ */
+ env_locale = setlocale (LC_ALL, old_locale);
+ if (!env_locale) {
+ fprintf(stderr,"Unable to restore original locale %s: exit now.\n",old_locale);
+ exit(1);
}
- /* Back to the previous locale if possible, */
- /* otherwise it's a serious error and we exit:*/
- /* we can't ensure a 'sane' locale for lua. */
- env_locale = setlocale (LC_ALL, old_locale);
- if (!env_locale) {
- fprintf(stderr,"Unable to restore original locale %s: exit now.\n",old_locale);
- exit(1);
- }
xfree(old_locale);
} else {
fprintf(stderr,"Unable to store environment locale.\n");
}
-
- /* make sure that the locale is 'sane' (for lua) */
+ /*tex make sure that the locale is 'sane' (for lua) */
putenv(LC_CTYPE_C);
putenv(LC_COLLATE_C);
putenv(LC_NUMERIC_C);
-
- /* this is sometimes needed */
+ /*tex this is sometimes needed */
putenv(engine_luatex);
-
luainterpreter();
-
- /* init internalized strings */
+ /*tex init internalized strings */
set_init_keys;
-
lua_pushstring(Luas,"lua.functions");
lua_newtable(Luas);
lua_settable(Luas,LUA_REGISTRYINDEX);
-
- /* here start the key definitions */
+ /*tex here start the key definitions */
set_l_pack_type_index;
set_l_group_code_index;
set_l_local_par_index;
set_l_math_style_name_index;
set_l_dir_par_index;
set_l_dir_text_index;
-
+ l_set_node_data();
+ l_set_whatsit_data();
+ l_set_token_data();
set_l_img_keys_index;
set_l_img_pageboxes_index;
-
- prepare_cmdline(Luas, argv, argc, lua_offset); /* collect arguments */
+ /*tex collect arguments */
+ prepare_cmdline(Luas, argv, argc, lua_offset);
setup_lua_path(Luas);
-
if (startup_filename != NULL) {
given_file = xstrdup(startup_filename);
if (lua_only) {
- xfree(startup_filename);
+ xfree(startup_filename);
}
startup_filename = find_filename(given_file, "LUATEXDIR");
}
- /* now run the file */
+ /*tex now run the file */
if (startup_filename != NULL) {
char *v1;
int tex_table_id = hide_lua_table(Luas, "tex");
@@ -1018,7 +1031,7 @@ void lua_initialize(int ac, char **av)
int node_table_id = hide_lua_table(Luas, "node");
int pdf_table_id = hide_lua_table(Luas, "pdf");
if (lua_only) {
- /* hide the 'tex' and 'pdf' table */
+ /*tex hide the 'tex' and 'pdf' table */
if (load_luatex_core_lua(Luas)) {
fprintf(stderr, "Error in execution of luatex-core.lua .\n");
}
@@ -1026,20 +1039,20 @@ void lua_initialize(int ac, char **av)
fprintf(stdout, "%s\n", lua_tostring(Luas, -1));
exit(1);
}
- init_tex_table(Luas); /* needed ? */
+ init_tex_table(Luas);
if (lua_pcall(Luas, 0, 0, 0)) {
fprintf(stdout, "%s\n", lua_tostring(Luas, -1));
lua_traceback(Luas);
- /* lua_close(Luas); */
+ /*tex lua_close(Luas); */
exit(1);
} else {
if (given_file)
free(given_file);
- /* lua_close(Luas); */
+ /*tex lua_close(Luas); */
exit(0);
}
}
- /* a normal tex run */
+ /*tex a normal tex run */
init_tex_table(Luas);
unhide_lua_table(Luas, "tex", tex_table_id);
unhide_lua_table(Luas, "pdf", pdf_table_id);
@@ -1060,28 +1073,25 @@ void lua_initialize(int ac, char **av)
if (!dump_name) {
get_lua_string("texconfig", "formatname", &dump_name);
}
- /* |kpse_init| */
kpse_init = -1;
get_lua_boolean("texconfig", "kpse_init", &kpse_init);
if (kpse_init != 0) {
- luainit = 0; /* re-enable loading of texmf.cnf values, see luatex.ch */
+ /*tex re-enable loading of texmf.cnf values, see luatex.ch */
+ luainit = 0;
init_kpse();
kpse_init = 1;
}
- /* |prohibit_file_trace| (boolean) */
+ /*tex |prohibit_file_trace| (boolean) */
tracefilenames = 1;
get_lua_boolean("texconfig", "trace_file_names", &tracefilenames);
-
- /* |file_line_error| */
+ /*tex |file_line_error| */
filelineerrorstylep = false;
get_lua_boolean("texconfig", "file_line_error", &filelineerrorstylep);
-
- /* |halt_on_error| */
+ /*tex |halt_on_error| */
haltonerrorp = false;
get_lua_boolean("texconfig", "halt_on_error", &haltonerrorp);
-
- /* |restrictedshell| */
+ /*tex |restrictedshell| */
v1 = NULL;
get_lua_string("texconfig", "shell_escape", &v1);
if (v1) {
@@ -1093,7 +1103,7 @@ void lua_initialize(int ac, char **av)
}
free(v1);
}
- /* If shell escapes are restricted, get allowed cmds from cnf. */
+ /*tex If shell escapes are restricted, get allowed cmds from cnf. */
if (shellenabledp && restrictedshell == 1) {
v1 = NULL;
get_lua_string("texconfig", "shell_escape_commands", &v1);
@@ -1102,11 +1112,10 @@ void lua_initialize(int ac, char **av)
free(v1);
}
}
-
starttime = -1 ;
get_lua_number("texconfig", "start_time", &starttime);
if (starttime < 0) {
- /*
+ /*tex
We provide this one for compatibility reasons and therefore also in
uppercase.
*/
@@ -1115,38 +1124,32 @@ void lua_initialize(int ac, char **av)
if (starttime >= 0) {
set_start_time(starttime);
}
-
utc = -1 ;
get_lua_boolean("texconfig", "use_utc_time", &utc);
if (utc >= 0 && utc <= 1) {
utc_option = utc;
}
-
fix_dumpname();
- } else {
- if (luainit) {
- if (given_file) {
- fprintf(stdout, "%s file %s not found\n", (lua_only ? "Script" : "Configuration"), given_file);
- free(given_file);
- } else {
- fprintf(stdout, "No %s file given\n", (lua_only ? "script" : "configuration"));
- }
- exit(1);
+ } else if (luainit) {
+ if (given_file) {
+ fprintf(stdout, "%s file %s not found\n", (lua_only ? "Script" : "Configuration"), given_file);
+ free(given_file);
} else {
- /* init */
- init_kpse();
- kpse_init = 1;
- fix_dumpname();
+ fprintf(stdout, "No %s file given\n", (lua_only ? "script" : "configuration"));
}
+ exit(1);
+ } else {
+ /* init */
+ init_kpse();
+ kpse_init = 1;
+ fix_dumpname();
+ }
+ /*tex Here we load luatex-core.lua which takes care of some protection on demand. */
+ if (load_luatex_core_lua(Luas)) {
+ fprintf(stderr, "Error in execution of luatex-core.lua .\n");
}
-
- /* Here we load luatex-core.lua which takes care of some protection on demand. */
- if (load_luatex_core_lua(Luas))
- fprintf(stderr, "Error in execution of luatex-core.lua .\n");
- /* Done. */
}
-@ @c
void check_texconfig_init(void)
{
if (Luas != NULL) {
@@ -1156,7 +1159,10 @@ void check_texconfig_init(void)
if (lua_isfunction(Luas, -1)) {
int i = lua_pcall(Luas, 0, 0, 0);
if (i != 0) {
- /* Can't be more precise here, called before TeX initialization */
+ /*tex
+ We can't be more precise hereas it's called before \TEX\
+ initialization happens.
+ */
fprintf(stderr, "This went wrong: %s\n", lua_tostring(Luas, -1));
error();
}
diff --git a/Build/source/texk/web2c/luatexdir/lua/luanode.w b/Build/source/texk/web2c/luatexdir/lua/luanode.c
index ef2f0b92655..3182b609773 100644
--- a/Build/source/texk/web2c/luatexdir/lua/luanode.w
+++ b/Build/source/texk/web2c/luatexdir/lua/luanode.c
@@ -1,33 +1,32 @@
-% luanode.w
-%
-% Copyright 2006-2008 Taco Hoekwater <taco@@luatex.org>
-%
-% This file is part of LuaTeX.
-%
-% LuaTeX is free software; you can redistribute it and/or modify it under
-% the terms of the GNU General Public License as published by the Free
-% Software Foundation; either version 2 of the License, or (at your
-% option) any later version.
-%
-% LuaTeX is distributed in the hope that it will be useful, but WITHOUT
-% ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-% FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
-% License for more details.
-%
-% You should have received a copy of the GNU General Public License along
-% with LuaTeX; if not, see <http://www.gnu.org/licenses/>.
+/*
-/* hh-ls: we make sure that lua never sees prev of head but also that when
-nodes are removed or inserted, temp nodes don't interfere */
+luanode.w
-@ @c
+Copyright 2006-2008 Taco Hoekwater <taco@@luatex.org>
+
+This file is part of LuaTeX.
+
+LuaTeX is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version.
+
+LuaTeX is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU General Public License along
+with LuaTeX; if not, see <http://www.gnu.org/licenses/>.
+
+*/
#include "ptexlib.h"
#include "lua/luatex-api.h"
-@ @c
void lua_node_filter_s(int filterid, int extrainfo)
{
+ int i;
int callback_id = callback_defined(filterid);
int s_top = lua_gettop(Luas);
if (callback_id <= 0) {
@@ -38,20 +37,20 @@ void lua_node_filter_s(int filterid, int extrainfo)
lua_settop(Luas, s_top);
return;
}
- lua_push_string_by_index(Luas,extrainfo); /* arg 1 */
- if (lua_pcall(Luas, 1, 0, 0) != 0) {
- fprintf(stdout, "error: %s\n", lua_tostring(Luas, -1));
+ lua_push_string_by_index(Luas,extrainfo);
+ if ((i=lua_pcall(Luas, 1, 0, 0)) != 0) {
+ formatted_warning("node filter","error: %s", lua_tostring(Luas, -1));
lua_settop(Luas, s_top);
- error();
+ luatex_error(Luas, (i == LUA_ERRRUN ? 0 : 1));
return;
}
lua_settop(Luas, s_top);
return;
}
-@ @c
void lua_node_filter(int filterid, int extrainfo, halfword head_node, halfword * tail_node)
{
+ int i;
halfword start_node, start_done, last_node;
int s_top = lua_gettop(Luas);
int callback_id = callback_defined(filterid);
@@ -59,45 +58,45 @@ void lua_node_filter(int filterid, int extrainfo, halfword head_node, halfword *
lua_settop(Luas, s_top);
return;
}
- /* we start after head */
+ /*tex We start after head. */
start_node = vlink(head_node);
if (start_node == null || !get_callback(Luas, callback_id)) {
lua_settop(Luas, s_top);
return;
}
- /* we make sure we have no prev */
+ /*tex We make sure we have no prev */
alink(start_node) = null ;
- /* the action */
+ /*tex the action */
nodelist_to_lua(Luas, start_node);
lua_push_group_code(Luas,extrainfo);
- if (lua_pcall(Luas, 2, 1, 0) != 0) {
- fprintf(stdout, "error: %s\n", lua_tostring(Luas, -1));
+ if ((i=lua_pcall(Luas, 2, 1, 0)) != 0) {
+ formatted_warning("node filter", "error: %s\n", lua_tostring(Luas, -1));
lua_settop(Luas, s_top);
- error();
+ luatex_error(Luas, (i == LUA_ERRRUN ? 0 : 1));
return;
}
- /* the result */
+ /*tex the result */
if (lua_isboolean(Luas, -1)) {
if (lua_toboolean(Luas, -1) != 1) {
- /* discard */
+ /*tex discard */
flush_node_list(start_node);
vlink(head_node) = null;
} else {
- /* keep */
+ /*tex keep */
}
} else {
- /* append to old head */
- start_done = nodelist_from_lua(Luas);
+ /*tex append to old head */
+ start_done = nodelist_from_lua(Luas,-1);
try_couple_nodes(head_node,start_done);
}
- /* redundant as we set top anyway */
+ /*tex redundant as we set top anyway */
lua_pop(Luas, 2);
- /* find tail in order to update tail */
+ /*tex find tail in order to update tail */
start_node = vlink(head_node);
if (start_node != null) {
- /* maybe just always slide (harmless and fast) */
+ /*tex maybe just always slide (harmless and fast) */
if (fix_node_lists) {
- /* slides and returns last node */
+ /*tex slides and returns last node */
*tail_node = fix_node_list(start_node);
} else {
last_node = vlink(start_node);
@@ -105,24 +104,23 @@ void lua_node_filter(int filterid, int extrainfo, halfword head_node, halfword *
start_node = last_node;
last_node = vlink(start_node);
}
- /* we're at the end now */
+ /*tex we're at the end now */
*tail_node = start_node;
}
} else {
- /* we're already at the end */
+ /*tex we're already at the end */
*tail_node = head_node;
}
- /* clean up */
+ /*tex clean up */
lua_settop(Luas, s_top);
return;
}
-@ @c
int lua_linebreak_callback(int is_broken, halfword head_node, halfword * new_head)
{
- int a;
+ int a, i;
register halfword *p;
- int ret = 0; /* failure */
+ int ret = 0;
int s_top = lua_gettop(Luas);
int callback_id = callback_defined(linebreak_filter_callback);
if (head_node == null || vlink(head_node) == null || callback_id <= 0) {
@@ -130,32 +128,33 @@ int lua_linebreak_callback(int is_broken, halfword head_node, halfword * new_hea
return ret;
}
if (!get_callback(Luas, callback_id)) {
- lua_settop(Luas, s_top);
+ lua_settop(Luas, s_top);
return ret;
}
- alink(vlink(head_node)) = null ; /* hh-ls */
- nodelist_to_lua(Luas, vlink(head_node)); /* arg 1 */
- lua_pushboolean(Luas, is_broken); /* arg 2 */
- if (lua_pcall(Luas, 2, 1, 0) != 0) { /* no arg, 1 result */
- fprintf(stdout, "error: %s\n", lua_tostring(Luas, -1));
+ alink(vlink(head_node)) = null ;
+ nodelist_to_lua(Luas, vlink(head_node));
+ lua_pushboolean(Luas, is_broken);
+ if ((i=lua_pcall(Luas, 2, 1, 0)) != 0) {
+ formatted_warning("linebreak", "error: %s", lua_tostring(Luas, -1));
lua_settop(Luas, s_top);
- error();
+ luatex_error(Luas, (i == LUA_ERRRUN ? 0 : 1));
return ret;
}
+ lua_settop(Luas, s_top);
p = lua_touserdata(Luas, -1);
if (p != NULL) {
- a = nodelist_from_lua(Luas);
+ a = nodelist_from_lua(Luas,-1);
try_couple_nodes(*new_head,a);
ret = 1;
}
- lua_settop(Luas, s_top);
return ret;
}
-@ @c
-int lua_appendtovlist_callback(halfword box, int location, halfword prev_depth, boolean is_mirrored, halfword * result, int * next_depth, boolean * prev_set)
+int lua_appendtovlist_callback(halfword box, int location, halfword prev_depth,
+ boolean is_mirrored, halfword * result, int * next_depth, boolean * prev_set)
{
register halfword *p;
+ int i;
int s_top = lua_gettop(Luas);
int callback_id = callback_defined(append_to_vlist_filter_callback);
if (box == null || callback_id <= 0) {
@@ -170,10 +169,10 @@ int lua_appendtovlist_callback(halfword box, int location, halfword prev_depth,
lua_push_string_by_index(Luas,location);
lua_pushinteger(Luas, (int) prev_depth);
lua_pushboolean(Luas, is_mirrored);
- if (lua_pcall(Luas, 4, 2, 0) != 0) {
- fprintf(stdout, "error: %s\n", lua_tostring(Luas, -1));
+ if ((i=lua_pcall(Luas, 4, 2, 0)) != 0) {
+ formatted_warning("append to vlist","error: %s", lua_tostring(Luas, -1));
lua_settop(Luas, s_top);
- error();
+ luatex_error(Luas, (i == LUA_ERRRUN ? 0 : 1));
return 0;
}
if (lua_type(Luas,-1) == LUA_TNUMBER) {
@@ -187,13 +186,13 @@ int lua_appendtovlist_callback(halfword box, int location, halfword prev_depth,
p = check_isnode(Luas, -1);
*result = *p;
}
- lua_settop(Luas, s_top);
return 1;
}
-@ @c
-halfword lua_hpack_filter(halfword head_node, scaled size, int pack_type, int extrainfo, int pack_direction, halfword attr)
+halfword lua_hpack_filter(halfword head_node, scaled size, int pack_type, int extrainfo,
+ int pack_direction, halfword attr)
{
+ int i;
halfword ret;
int s_top = lua_gettop(Luas);
int callback_id = callback_defined(hpack_filter_callback);
@@ -205,7 +204,7 @@ halfword lua_hpack_filter(halfword head_node, scaled size, int pack_type, int ex
lua_settop(Luas, s_top);
return head_node;
}
- alink(head_node) = null ; /* hh-ls */
+ alink(head_node) = null ;
nodelist_to_lua(Luas, head_node);
lua_push_group_code(Luas,extrainfo);
lua_pushinteger(Luas, size);
@@ -220,10 +219,10 @@ halfword lua_hpack_filter(halfword head_node, scaled size, int pack_type, int ex
} else {
lua_pushnil(Luas);
}
- if (lua_pcall(Luas, 6, 1, 0) != 0) {
- fprintf(stdout, "error: %s\n", lua_tostring(Luas, -1));
+ if ((i=lua_pcall(Luas, 6, 1, 0)) != 0) {
+ formatted_warning("hpack filter", "error: %s\n", lua_tostring(Luas, -1));
lua_settop(Luas, s_top);
- error();
+ luatex_error(Luas, (i == LUA_ERRRUN ? 0 : 1));
return head_node;
}
ret = head_node;
@@ -233,29 +232,26 @@ halfword lua_hpack_filter(halfword head_node, scaled size, int pack_type, int ex
ret = null;
}
} else {
- ret = nodelist_from_lua(Luas);
+ ret = nodelist_from_lua(Luas,-1);
}
lua_settop(Luas, s_top);
-#if 0
- lua_gc(Luas,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 pack_direction, halfword attr)
+ int extrainfo, int pack_direction, halfword attr)
{
halfword ret;
+ int i;
int callback_id;
int s_top = lua_gettop(Luas);
if (head_node == null) {
lua_settop(Luas, s_top);
return head_node;
}
- if (extrainfo == 8) { /* output */
+ if (extrainfo == 8) {
callback_id = callback_defined(pre_output_filter_callback);
} else {
callback_id = callback_defined(vpack_filter_callback);
@@ -268,7 +264,7 @@ halfword lua_vpack_filter(halfword head_node, scaled size, int pack_type, scaled
lua_settop(Luas, s_top);
return head_node;
}
- alink(head_node) = null ; /* hh-ls */
+ alink(head_node) = null ;
nodelist_to_lua(Luas, head_node);
lua_push_group_code(Luas, extrainfo);
lua_pushinteger(Luas, size);
@@ -284,10 +280,10 @@ halfword lua_vpack_filter(halfword head_node, scaled size, int pack_type, scaled
} else {
lua_pushnil(Luas);
}
- if (lua_pcall(Luas, 7, 1, 0) != 0) {
- fprintf(stdout, "error: %s\n", lua_tostring(Luas, -1));
+ if ((i=lua_pcall(Luas, 7, 1, 0)) != 0) {
+ formatted_warning("vpack filter", "error: %s", lua_tostring(Luas, -1));
lua_settop(Luas, s_top);
- error();
+ luatex_error(Luas, (i == LUA_ERRRUN ? 0 : 1));
return head_node;
}
ret = head_node;
@@ -297,76 +293,84 @@ halfword lua_vpack_filter(halfword head_node, scaled size, int pack_type, scaled
ret = null;
}
} else {
- ret = nodelist_from_lua(Luas);
+ ret = nodelist_from_lua(Luas,-1);
}
lua_settop(Luas, s_top);
-#if 0
- lua_gc(Luas,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.
+/*tex
+
+ This is a quick hack to fix \ETEX's \.{\\lastnodetype} now that there are many
+ more visible node types.
+
+*/
-@c
int visible_last_node_type(int n)
{
int i = type(n);
if (i != glyph_node) {
return get_etex_code(i);
} else if (is_ligature(n)) {
- return 7; /* old ligature value */
+ /*tex old ligature value */
+ return 7;
} else {
- return 0; /* old character value */
+ /*tex old character value */
+ return 0;
}
}
-@ @c
-void lua_pdf_literal(PDF pdf, int i)
+void lua_pdf_literal(PDF pdf, int i, int noline)
{
const char *s = NULL;
size_t l = 0;
lua_rawgeti(Luas, LUA_REGISTRYINDEX, i);
s = lua_tolstring(Luas, -1, &l);
- pdf_out_block(pdf, s, l);
- pdf_out(pdf, 10); /* |pdf_print_nl| */
+ if (noline) {
+ pdf_check_space(pdf);
+ pdf_out_block(pdf, s, l);
+ pdf_set_space(pdf);
+ } else {
+ pdf_out_block(pdf, s, l);
+ pdf_out(pdf, 10);
+ }
lua_pop(Luas, 1);
}
-@ @c
void copy_pdf_literal(pointer r, pointer p)
{
- pdf_literal_type(r) = pdf_literal_type(p);
+ int t = pdf_literal_type(p);
+ pdf_literal_type(r) = t;
pdf_literal_mode(r) = pdf_literal_mode(p);
- if (pdf_literal_type(p) == normal) {
+ if (t == normal) {
pdf_literal_data(r) = pdf_literal_data(p);
add_token_ref(pdf_literal_data(p));
- } else {
+ } else if (t == lua_refid_literal) {
lua_rawgeti(Luas, LUA_REGISTRYINDEX, pdf_literal_data(p));
pdf_literal_data(r) = luaL_ref(Luas, LUA_REGISTRYINDEX);
+ } else {
+ /* maybe something user, we don't support a call here but best keep it sane anyway. */
+ pdf_literal_data(r) = pdf_literal_data(p);
}
}
-@ @c
void copy_late_lua(pointer r, pointer p)
{
- late_lua_type(r) = late_lua_type(p);
+ int t = late_lua_type(p);
+ late_lua_type(r) = t;
if (late_lua_name(p) > 0)
add_token_ref(late_lua_name(p));
- if (late_lua_type(p) == normal) {
+ if (t == normal) {
late_lua_data(r) = late_lua_data(p);
add_token_ref(late_lua_data(p));
- } else {
+ } else if (t == lua_refid_literal) {
lua_rawgeti(Luas, LUA_REGISTRYINDEX, late_lua_data(p));
late_lua_data(r) = luaL_ref(Luas, LUA_REGISTRYINDEX);
}
}
-@ @c
void copy_user_lua(pointer r, pointer p)
{
if (user_node_value(p) != 0) {
@@ -375,28 +379,28 @@ void copy_user_lua(pointer r, pointer p)
}
}
-@ @c
void free_pdf_literal(pointer p)
{
- if (pdf_literal_type(p) == normal) {
+ int t = pdf_literal_type(p);
+ if (t == normal) {
delete_token_ref(pdf_literal_data(p));
- } else {
+ } else if (t == lua_refid_literal) {
luaL_unref(Luas, LUA_REGISTRYINDEX, pdf_literal_data(p));
}
}
void free_late_lua(pointer p)
{
+ int t = late_lua_type(p);
if (late_lua_name(p) > 0)
delete_token_ref(late_lua_name(p));
- if (late_lua_type(p) == normal) {
+ if (t == normal) {
delete_token_ref(late_lua_data(p));
- } else {
+ } else if (t == lua_refid_literal) {
luaL_unref(Luas, LUA_REGISTRYINDEX, late_lua_data(p));
}
}
-@ @c
void free_user_lua(pointer p)
{
if (user_node_value(p) != 0) {
@@ -404,9 +408,9 @@ void free_user_lua(pointer p)
}
}
-@ @c
void show_pdf_literal(pointer p)
{
+ int t = pdf_literal_type(p);
tprint_esc("pdfliteral");
switch (pdf_literal_mode(p)) {
case set_origin:
@@ -422,30 +426,36 @@ void show_pdf_literal(pointer p)
tprint(" raw");
break;
default:
- confusion("literal2");
+ tprint(" <invalid mode>");
break;
}
- if (pdf_literal_type(p) == normal) {
+ if (t == normal) {
print_mark(pdf_literal_data(p));
+ } else if (t == lua_refid_literal) {
+ tprint(" <lua data reference ");
+ print_int(pdf_literal_data(p));
+ tprint(">");
} else {
- lua_rawgeti(Luas, LUA_REGISTRYINDEX, pdf_literal_data(p));
- tprint("\"");
- tprint(lua_tostring(Luas, -1));
- tprint("\"");
- lua_pop(Luas, 1);
+ tprint(" <invalid data>");
}
}
-@ @c
void show_late_lua(pointer p)
{
+ int t = late_lua_type(p);
tprint_esc("latelua");
print_int(late_lua_reg(p));
- if (late_lua_type(p) == normal) {
+ if (t == normal) {
print_mark(late_lua_data(p));
- } else {
- tprint(" <function ");
+ } else if (t == lua_refid_literal) {
+ tprint(" <function reference ");
print_int(late_lua_data(p));
tprint(">");
+ } else if (t == lua_refid_call) {
+ tprint(" <functioncall reference ");
+ print_int(late_lua_data(p));
+ tprint(">");
+ } else {
+ tprint(" <invalid data>");
}
}
diff --git a/Build/source/texk/web2c/luatexdir/lua/luastuff.w b/Build/source/texk/web2c/luatexdir/lua/luastuff.c
index a2b1dd14327..0d9342223df 100644
--- a/Build/source/texk/web2c/luatexdir/lua/luastuff.w
+++ b/Build/source/texk/web2c/luatexdir/lua/luastuff.c
@@ -1,30 +1,32 @@
-% luastuff.w
-%
-% Copyright 2006-2013 Taco Hoekwater <taco@@luatex.org>
-%
-% This file is part of LuaTeX.
-%
-% LuaTeX is free software; you can redistribute it and/or modify it under
-% the terms of the GNU General Public License as published by the Free
-% Software Foundation; either version 2 of the License, or (at your
-% option) any later version.
-%
-% LuaTeX is distributed in the hope that it will be useful, but WITHOUT
-% ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-% FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
-% License for more details.
-%
-% You should have received a copy of the GNU General Public License along
-% with LuaTeX; if not, see <http://www.gnu.org/licenses/>.
-
-@ @c
+/*
+
+luastuff.w
+
+Copyright 2006-2013 Taco Hoekwater <taco@@luatex.org>
+
+This file is part of LuaTeX.
+
+LuaTeX is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version.
+
+LuaTeX is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU General Public License along
+with LuaTeX; if not, see <http://www.gnu.org/licenses/>.
+
+*/
+
#include "ptexlib.h"
#include "lua/luatex-api.h"
#ifdef LuajitTeX
#include "lua/lauxlib_bridge.h"
#endif
-@ @c
lua_State *Luas = NULL;
int luastate_bytes = 0;
@@ -45,31 +47,44 @@ int lua_active = 0;
lua_pop(L, 1);
#endif
-@ @c
void make_table(lua_State * L, const char *tab, const char *mttab, 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>}]| */
- /* fetch it back */
- lua_pushstring(L, tab); /* |[{<tex>},"dimen"]| */
- lua_gettable(L, -2); /* |[{<tex>},{<dimen>}]| */
- /* make the meta entries */
- luaL_newmetatable(L, mttab); /* |[{<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 */
+ /*tex make the table *//* |[{<tex>}]| */
+ /*tex |[{<tex>},"dimen"]| */
+ lua_pushstring(L, tab);
+ /*tex |[{<tex>},"dimen",{}]| */
+ lua_newtable(L);
+ /*tex |[{<tex>}]| */
+ lua_settable(L, -3);
+ /*tex fetch it back */
+ /*tex |[{<tex>},"dimen"]| */
+ lua_pushstring(L, tab);
+ /*tex |[{<tex>},{<dimen>}]| */
+ lua_gettable(L, -2);
+ /*tex make the meta entries */
+ /*tex |[{<tex>},{<dimen>},{<dimen_m>}]| */
+ luaL_newmetatable(L, mttab);
+ /*tex |[{<tex>},{<dimen>},{<dimen_m>},"__index"]| */
+ lua_pushstring(L, "__index");
+ /*tex |[{<tex>},{<dimen>},{<dimen_m>},"__index","getdimen"]| */
+ lua_pushstring(L, getfunc);
+ /*tex |[{<tex>},{<dimen>},{<dimen_m>},"__index",<tex.getdimen>]| */
+ lua_gettable(L, -5);
+ /*tex |[{<tex>},{<dimen>},{<dimen_m>}]| */
+ lua_settable(L, -3);
+ lua_pushstring(L, "__newindex"); /*tex |[{<tex>},{<dimen>},{<dimen_m>},"__newindex"]| */
+ /*tex |[{<tex>},{<dimen>},{<dimen_m>},"__newindex","setdimen"]| */
+ lua_pushstring(L, setfunc);
+ /*tex |[{<tex>},{<dimen>},{<dimen_m>},"__newindex",<tex.setdimen>]| */
+ lua_gettable(L, -5);
+ /*tex |[{<tex>},{<dimen>},{<dimen_m>}]| */
+ lua_settable(L, -3);
+ /*tex |[{<tex>},{<dimen>}]| : assign the metatable */
+ lua_setmetatable(L, -2);
+ /*tex |[{<tex>}]| : clean the stack */
+ lua_pop(L, 1);
}
-@ @c
static const char *getS(lua_State * L, void *ud, size_t * size)
{
LoadS *ls = (LoadS *) ud;
@@ -81,18 +96,19 @@ static const char *getS(lua_State * L, void *ud, size_t * size)
return ls->s;
}
-@ @c
#ifdef LuajitTeX
- /* Luatex has its own memory allocator, LuajitTeX uses the */
- /* standard one from the stock. We left this space as */
- /* reference, but be careful: memory allocator is a key */
- /* component in luajit, it's easy to get sub-optimal */
- /* performances. */
+ /*
+ \LUATEX\ has its own memory allocator, \LUAJIITEX\ uses the standard one
+ from the stock. We left this space as reference, but be careful: memory
+ allocator is a key component in \LUAJIT, it's easy to get sub-optimal
+ performances.
+ */
#else
static void *my_luaalloc(void *ud, void *ptr, size_t osize, size_t nsize)
{
void *ret = NULL;
- (void) ud; /* for -Wunused */
+ /*tex define |ud| for -Wunused */
+ (void) ud;
if (nsize == 0)
free(ptr);
else
@@ -102,15 +118,14 @@ static void *my_luaalloc(void *ud, void *ptr, size_t osize, size_t nsize)
}
#endif
-@ @c
static int my_luapanic(lua_State * L)
{
- (void) L; /* to avoid warnings */
+ /*tex define |L| to avoid warnings */
+ (void) L;
fprintf(stderr, "PANIC: unprotected error in call to Lua API (%s)\n", lua_tostring(L, -1));
return 0;
}
-@ @c
void luafunctioncall(int slot)
{
int i ;
@@ -120,12 +135,17 @@ void luafunctioncall(int slot)
lua_gettable(Luas, LUA_REGISTRYINDEX);
lua_rawgeti(Luas, -1,slot);
if (lua_isfunction(Luas,-1)) {
- int base = lua_gettop(Luas); /* function index */
+ /*tex function index */
+ int base = lua_gettop(Luas);
lua_pushinteger(Luas, slot);
- lua_pushcfunction(Luas, lua_traceback); /* push traceback function */
- lua_insert(Luas, base); /* put it under chunk */
+ /* push traceback function */
+ lua_pushcfunction(Luas, lua_traceback);
+ /*tex put it under chunk */
+ lua_insert(Luas, base);
+ ++function_callback_count;
i = lua_pcall(Luas, 1, 0, base);
- lua_remove(Luas, base); /* remove traceback function */
+ /*tex remove traceback function */
+ lua_remove(Luas, base);
if (i != 0) {
lua_gc(Luas, LUA_GCCOLLECT, 0);
Luas = luatex_error(Luas, (i == LUA_ERRRUN ? 0 : 1));
@@ -135,9 +155,8 @@ void luafunctioncall(int slot)
lua_active--;
}
-@ @c
static const luaL_Reg lualibs[] = {
- /* standard lua libraries */
+ /*tex standard \LUA\ libraries */
{ "_G", luaopen_base },
{ "package", luaopen_package },
{ "table", luaopen_table },
@@ -149,32 +168,30 @@ static const luaL_Reg lualibs[] = {
{ "lpeg", luaopen_lpeg },
{ "bit32", luaopen_bit32 },
#ifdef LuajitTeX
- /* bit is only in luajit, */
- /* coroutine is loaded in a special way */
- { "bit", luaopen_bit },
+ /*tex |bit| is only in \LUAJIT */
+ /*tex |coroutine| is loaded in a special way */
+ { "bit", luaopen_bit },
#else
#if LUA_VERSION_NUM == 503
{ "utf8", luaopen_utf8 },
#endif
{ "coroutine", luaopen_coroutine },
#endif
- /* additional (public) libraries */
+ /*tex additional (public) libraries */
{ "unicode", luaopen_unicode },
{ "zip", luaopen_zip },
{ "md5", luaopen_md5 },
+ { "sha2", luaopen_sha2 },
{ "lfs", luaopen_lfs },
- /* extra standard lua libraries */
+ /*tex extra standard lua libraries */
#ifdef LuajitTeX
{ "jit", luaopen_jit },
#endif
{ "ffi", luaopen_ffi },
- /* obsolete, undocumented and for oru own testing only */
- /*{ "profiler", luaopen_profiler }, */
- /* more libraries will be loaded later */
+ /*tex more libraries will be loaded later */
{ NULL, NULL }
};
-@ @c
static void do_openlibs(lua_State * L)
{
const luaL_Reg *lib = lualibs;
@@ -183,22 +200,23 @@ static void do_openlibs(lua_State * L)
}
}
-@ @c
#ifdef LuajitTeX
- /* in luajit load_aux is not used.*/
+ /*tex in \LUAJIT\ |load_aux| is not used.*/
#else
static int load_aux (lua_State *L, int status) {
- if (status == 0) /* OK? */
+ if (status == 0)
+ /*tex okay */
return 1;
else {
+ /*tex return nil plus error message */
lua_pushnil(L);
- lua_insert(L, -2); /* put before error message */
- return 2; /* return nil plus error message */
+ /*tex put before error message */
+ lua_insert(L, -2);
+ return 2;
}
}
#endif
-@ @c
static int luatex_loadfile (lua_State *L) {
int status = 0;
const char *fname = luaL_optstring(L, 1, NULL);
@@ -206,12 +224,14 @@ static int luatex_loadfile (lua_State *L) {
#ifdef LuajitTeX
/* 5.1 */
#else
- int env = !lua_isnone(L, 3); /* 'env' parameter? */
+ /*tex the |env| parameter */
+ int env = !lua_isnone(L, 3);
#endif
if (!lua_only && !fname && interaction == batch_mode) {
+ /*tex return |nil| plus error message */
lua_pushnil(L);
lua_pushstring(L, "reading from stdin is disabled in batch mode");
- return 2; /* return nil plus error message */
+ return 2;
}
status = luaL_loadfilex(L, fname, mode);
if (status == LUA_OK) {
@@ -219,9 +239,11 @@ static int luatex_loadfile (lua_State *L) {
#ifdef LuajitTeX
/* 5.1 */
#else
- if (env) { /* 'env' parameter? */
+ if (env) {
+ /*tex the |env| parameter */
lua_pushvalue(L, 3);
- lua_setupvalue(L, -2, 1); /* set it as 1st upvalue of loaded chunk */
+ /*tex set it as first upvalue of loaded chunk */
+ lua_setupvalue(L, -2, 1);
}
#endif
}
@@ -232,15 +254,15 @@ static int luatex_loadfile (lua_State *L) {
#endif
}
-@ @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) {
+ /*tex return |nil| plus error message */
lua_pushnil(L);
lua_pushstring(L, "reading from stdin is disabled in batch mode");
- return 2; /* return nil plus error message */
+ return 2;
} else {
tprint_nl("lua> ");
}
@@ -252,13 +274,12 @@ static int luatex_dofile (lua_State *L) {
return lua_gettop(L) - n;
}
-@ @c
void luainterpreter(void)
{
lua_State *L;
#ifdef LuajitTeX
if (jithash_hashname == NULL) {
- /* default lua51 */
+ /*tex default lua51 */
luajittex_choose_hash_function = 0;
jithash_hashname = (char *) xmalloc(strlen("lua51") + 1);
jithash_hashname = strcpy ( jithash_hashname, "lua51");
@@ -267,7 +288,7 @@ void luainterpreter(void)
} else if (strcmp((const char*)jithash_hashname,"luajit20") == 0) {
luajittex_choose_hash_function = 1;
} else {
- /* default lua51 */
+ /*tex default lua51 */
luajittex_choose_hash_function = 0;
jithash_hashname = strcpy ( jithash_hashname, "lua51");
}
@@ -280,8 +301,8 @@ void luainterpreter(void)
return;
}
lua_atpanic(L, &my_luapanic);
-
- do_openlibs(L); /* does all the 'simple' libraries */
+ /*tex This initializes all the `simple' libraries: */
+ do_openlibs(L);
#ifdef LuajitTeX
if (luajiton){
luaJIT_setmode(L, 0, LUAJIT_MODE_ENGINE|LUAJIT_MODE_ON);
@@ -290,22 +311,17 @@ void luainterpreter(void)
luaJIT_setmode(L, 0, LUAJIT_MODE_ENGINE|LUAJIT_MODE_OFF);
}
#endif
-
lua_pushcfunction(L,luatex_dofile);
lua_setglobal(L, "dofile");
lua_pushcfunction(L,luatex_loadfile);
lua_setglobal(L, "loadfile");
-
open_oslibext(L);
open_strlibext(L);
- open_lfslibext(L);
-
- /*
- The socket and mime libraries 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.
+ /*tex
+ The socket and mime libraries are a bit tricky to open because they use a
+ load-time dependency that has to be worked around for luatex, where the C
+ module is loaded way before the lua module.
*/
-
if (!nosocket_option) {
/* todo: move this to common */
lua_getglobal(L, "package");
@@ -315,28 +331,26 @@ void luainterpreter(void)
lua_setfield(L, -2, "loaded");
lua_getfield(L, -1, "loaded");
}
+ /*tex |package.loaded.socket = nil| */
luaopen_socket_core(L);
lua_setfield(L, -2, "socket.core");
lua_pushnil(L);
- lua_setfield(L, -2, "socket"); /* package.loaded.socket = nil */
-
+ lua_setfield(L, -2, "socket");
+ /*tex |package.loaded.mime = nil| */
luaopen_mime_core(L);
lua_setfield(L, -2, "mime.core");
lua_pushnil(L);
- lua_setfield(L, -2, "mime"); /* package.loaded.mime = nil */
- lua_pop(L, 2); /* pop the tables */
-
- luatex_socketlua_open(L); /* preload the pure lua modules */
+ lua_setfield(L, -2, "mime");
+ /*tex pop the tables */
+ lua_pop(L, 2);
+ /*tex preload the pure \LUA\ modules */
+ luatex_socketlua_open(L);
}
-
- /* zlib. slightly odd calling convention */
+ /*tex |zlib|'s slightly odd calling convention */
luaopen_zlib(L);
lua_setglobal(L, "zlib");
-
luaopen_gzip(L);
-
- /* our own libraries register themselves */
-
+ /*tex our own libraries register themselves */
luaopen_fio(L);
luaopen_ff(L);
luaopen_tex(L);
@@ -345,29 +359,25 @@ void luainterpreter(void)
luaopen_texio(L);
luaopen_kpse(L);
luaopen_callback(L);
-
+ /*tex now we plug in extra \LUA\ startup code */
luaopen_lua(L, startup_filename);
-
+ /*tex and open some \TEX\ ones */
luaopen_stats(L);
luaopen_font(L);
luaopen_lang(L);
luaopen_mplib(L);
luaopen_vf(L);
luaopen_pdf(L);
- luaopen_epdf(L);
+ luaopen_pdfe(L);
luaopen_pdfscanner(L);
-
if (!lua_only) {
luaopen_img(L);
}
-
lua_createtable(L, 0, 0);
lua_setglobal(L, "texconfig");
-
Luas = L;
}
-@ @c
int hide_lua_table(lua_State * L, const char *name)
{
int r = 0;
@@ -380,7 +390,6 @@ 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);
@@ -388,7 +397,6 @@ 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;
@@ -402,7 +410,6 @@ 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);
@@ -413,7 +420,6 @@ void unhide_lua_value(lua_State * L, const char *name, const char *item, int r)
}
}
-@ @c
int lua_traceback(lua_State * L)
{
lua_getglobal(L, "debug");
@@ -426,21 +432,23 @@ int lua_traceback(lua_State * L)
lua_pop(L, 2);
return 1;
}
- lua_pushvalue(L, 1); /* pass error message */
- lua_pushinteger(L, 2); /* skip this function and traceback */
- lua_call(L, 2, 1); /* call debug.traceback */
+ /*tex pass error message */
+ lua_pushvalue(L, 1);
+ /*tex skip this function and traceback */
+ lua_pushinteger(L, 2);
+ /*tex call |debug.traceback| */
+ lua_call(L, 2, 1);
return 1;
}
-@ @c
-static void luacall(int p, int nameptr, boolean is_string) /* hh-ls: optimized lua_id resolving */
+static void luacall(int p, int nameptr, boolean is_string)
{
LoadS ls;
int i;
size_t ll = 0;
char *lua_id;
char *s = NULL;
-
+ int stacktop = lua_gettop(Luas);
if (Luas == NULL) {
luainterpreter();
}
@@ -449,16 +457,22 @@ static void luacall(int p, int nameptr, boolean is_string) /* hh-ls: optimized l
const char *ss = NULL;
lua_rawgeti(Luas, LUA_REGISTRYINDEX, p);
if (lua_isfunction(Luas,-1)) {
- int base = lua_gettop(Luas); /* function index */
+ /*tex function index */
+ int base = lua_gettop(Luas);
lua_checkstack(Luas, 1);
- lua_pushcfunction(Luas, lua_traceback); /* push traceback function */
- lua_insert(Luas, base); /* put it under chunk */
+ /*tex push traceback function */
+ lua_pushcfunction(Luas, lua_traceback);
+ /*tex put it under chunk */
+ lua_insert(Luas, base);
+ ++late_callback_count;
i = lua_pcall(Luas, 0, 0, base);
- lua_remove(Luas, base); /* remove traceback function */
+ /*tex remove traceback function */
+ lua_remove(Luas, base);
if (i != 0) {
lua_gc(Luas, LUA_GCCOLLECT, 0);
Luas = luatex_error(Luas, (i == LUA_ERRRUN ? 0 : 1));
}
+ lua_settop(Luas,stacktop);
lua_active--;
return ;
}
@@ -475,7 +489,8 @@ static void luacall(int p, int nameptr, boolean is_string) /* hh-ls: optimized l
ls.size = ll;
if (ls.size > 0) {
if (nameptr > 0) {
- int l = 0; /* not used */
+ /*tex |l| is not used */
+ int l = 0;
lua_id = tokenlist_to_cstring(nameptr, 1, &l);
i = Luas_load(Luas, getS, &ls, lua_id);
xfree(lua_id);
@@ -492,12 +507,17 @@ static void luacall(int p, int nameptr, boolean is_string) /* hh-ls: optimized l
if (i != 0) {
Luas = luatex_error(Luas, (i == LUA_ERRSYNTAX ? 0 : 1));
} else {
- int base = lua_gettop(Luas); /* function index */
+ /*tex function index */
+ int base = lua_gettop(Luas);
lua_checkstack(Luas, 1);
- lua_pushcfunction(Luas, lua_traceback); /* push traceback function */
- lua_insert(Luas, base); /* put it under chunk */
+ /*tex push traceback function */
+ lua_pushcfunction(Luas, lua_traceback);
+ /*tex put it under chunk */
+ lua_insert(Luas, base);
+ ++late_callback_count;
i = lua_pcall(Luas, 0, 0, base);
- lua_remove(Luas, base); /* remove traceback function */
+ /*tex remove traceback function */
+ lua_remove(Luas, base);
if (i != 0) {
lua_gc(Luas, LUA_GCCOLLECT, 0);
Luas = luatex_error(Luas, (i == LUA_ERRRUN ? 0 : 1));
@@ -505,31 +525,99 @@ static void luacall(int p, int nameptr, boolean is_string) /* hh-ls: optimized l
}
xfree(ls.s);
}
+ lua_settop(Luas,stacktop);
+ lua_active--;
+}
+
+void luacall_vf(int p, int f, int c)
+{
+ int i;
+ int stacktop = lua_gettop(Luas);
+ if (Luas == NULL) {
+ luainterpreter();
+ }
+ lua_active++;
+ lua_rawgeti(Luas, LUA_REGISTRYINDEX, p);
+ if (lua_isfunction(Luas,-1)) {
+ /*tex function index */
+ int base = lua_gettop(Luas);
+ lua_checkstack(Luas, 1);
+ /*tex push traceback function */
+ lua_pushcfunction(Luas, lua_traceback);
+ /*tex put it under chunk */
+ lua_insert(Luas, base);
+ lua_pushinteger(Luas, f);
+ lua_pushinteger(Luas, c);
+ ++late_callback_count;
+ i = lua_pcall(Luas, 2, 0, base);
+ /*tex remove traceback function */
+ lua_remove(Luas, base);
+ if (i != 0) {
+ lua_gc(Luas, LUA_GCCOLLECT, 0);
+ Luas = luatex_error(Luas, (i == LUA_ERRRUN ? 0 : 1));
+ }
+ } else {
+ LoadS ls;
+ size_t ll = 0;
+ char *s = NULL;
+ const char *ss = NULL;
+ ss = lua_tolstring(Luas, -1, &ll);
+ s = xmalloc(ll+1);
+ memcpy(s,ss,ll+1);
+ lua_pop(Luas,1);
+ ls.s = s;
+ ls.size = ll;
+ if (ls.size > 0) {
+ i = Luas_load(Luas, getS, &ls, "=[vf command]");
+ if (i != 0) {
+ Luas = luatex_error(Luas, (i == LUA_ERRSYNTAX ? 0 : 1));
+ } else {
+ int base = lua_gettop(Luas); /* function index */
+ lua_checkstack(Luas, 1);
+ lua_pushcfunction(Luas, lua_traceback); /* push traceback function */
+ lua_insert(Luas, base); /* put it under chunk */
+ ++late_callback_count;
+ i = lua_pcall(Luas, 0, 0, base);
+ lua_remove(Luas, base); /* remove traceback function */
+ if (i != 0) {
+ lua_gc(Luas, LUA_GCCOLLECT, 0);
+ Luas = luatex_error(Luas, (i == LUA_ERRRUN ? 0 : 1));
+ }
+ }
+ xfree(ls.s);
+ }
+ }
+ lua_settop(Luas,stacktop);
lua_active--;
}
-@ @c
void late_lua(PDF pdf, halfword p)
{
+ halfword t;
(void) pdf;
- if (late_lua_type(p)==normal) {
- expand_macros_in_tokenlist(p); /* sets |def_ref| */
+ t = late_lua_type(p);
+ if (t == normal) {
+ /*tex sets |def_ref| */
+ expand_macros_in_tokenlist(p);
luacall(def_ref, late_lua_name(p), false);
flush_list(def_ref);
- } else {
+ } else if (t == lua_refid_call) {
+ luafunctioncall(late_lua_data(p));
+ } else if (t == lua_refid_literal) {
luacall(late_lua_data(p), late_lua_name(p), true);
+ } else {
+ /*tex Let's just ignore it, could be some user specific thing. */
}
}
-@ @c
-void luatokencall(int p, int nameptr) /* hh-ls: optimized lua_id resolving */
+void luatokencall(int p, int nameptr)
{
LoadS ls;
- int i, l;
+ int i;
+ int l = 0;
char *s = NULL;
char *lua_id;
- assert(Luas);
- l = 0;
+ int stacktop = lua_gettop(Luas);
lua_active++;
s = tokenlist_to_cstring(p, 1, &l);
ls.s = s;
@@ -538,7 +626,7 @@ void luatokencall(int p, int nameptr) /* hh-ls: optimized lua_id resolving */
if (nameptr > 0) {
lua_id = tokenlist_to_cstring(nameptr, 1, &l);
i = Luas_load(Luas, getS, &ls, lua_id);
- xfree(lua_id);
+ xfree(lua_id);
} else if (nameptr < 0) {
lua_id = get_lua_name((nameptr + 65536));
if (lua_id != NULL) {
@@ -553,40 +641,53 @@ void luatokencall(int p, int nameptr) /* hh-ls: optimized lua_id resolving */
if (i != 0) {
Luas = luatex_error(Luas, (i == LUA_ERRSYNTAX ? 0 : 1));
} else {
- int base = lua_gettop(Luas); /* function index */
+ /*tex function index */
+ int base = lua_gettop(Luas);
lua_checkstack(Luas, 1);
- lua_pushcfunction(Luas, lua_traceback); /* push traceback function */
- lua_insert(Luas, base); /* put it under chunk */
+ /*tex push traceback function */
+ lua_pushcfunction(Luas, lua_traceback);
+ /*tex put it under chunk */
+ lua_insert(Luas, base);
+ ++direct_callback_count;
i = lua_pcall(Luas, 0, 0, base);
- lua_remove(Luas, base); /* remove traceback function */
+ /*tex remove traceback function */
+ lua_remove(Luas, base);
if (i != 0) {
lua_gc(Luas, LUA_GCCOLLECT, 0);
Luas = luatex_error(Luas, (i == LUA_ERRRUN ? 0 : 1));
}
}
}
+ lua_settop(Luas,stacktop);
lua_active--;
}
-@ @c
lua_State *luatex_error(lua_State * L, int is_fatal)
{
-
const_lstring luaerr;
char *err = NULL;
if (lua_type(L, -1) == LUA_TSTRING) {
luaerr.s = lua_tolstring(L, -1, &luaerr.l);
- /* free last one ? */
+ /*tex
+ Free the last one.
+ */
err = (char *) xmalloc((unsigned) (luaerr.l + 1));
snprintf(err, (luaerr.l + 1), "%s", luaerr.s);
- last_lua_error = err; /* hm, what if we have several .. not freed */
+ /*tex
+ What if we have several .. not freed?
+ */
+ last_lua_error = err;
}
if (is_fatal > 0) {
- /* Normally a memory error from lua.
- The pool may overflow during the |maketexlstring()|, but we
- are crashing anyway so we may as well abort on the pool size */
+ /*
+ 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
+ */
normal_error("lua",err);
- /* never reached */
+ /*tex
+ This is never reached.
+ */
lua_close(L);
return (lua_State *) NULL;
} else {
@@ -595,35 +696,41 @@ lua_State *luatex_error(lua_State * L, int is_fatal)
}
}
-@ @c
void preset_environment(lua_State * L, const parm_struct * p, const char *s)
{
int i;
assert(L != NULL);
- /* double call with same s gives assert(0) */
- lua_pushstring(L, s); /* s */
- lua_gettable(L, LUA_REGISTRYINDEX); /* t */
+ /*tex double call with same s gives assert(0) */
+ lua_pushstring(L, s);
+ /*tex state: s */
+ lua_gettable(L, LUA_REGISTRYINDEX);
+ /*tex state: t */
assert(lua_isnil(L, -1));
- lua_pop(L, 1); /* - */
- lua_pushstring(L, s); /* s */
- lua_newtable(L); /* t s */
+ lua_pop(L, 1);
+ /*tex state: - */
+ lua_pushstring(L, s);
+ /*tex state: s */
+ lua_newtable(L);
+ /*tex state: t s */
for (i = 1, ++p; p->name != NULL; i++, p++) {
assert(i == p->idx);
- lua_pushstring(L, p->name); /* k t s */
- lua_pushinteger(L, p->idx); /* v k t s */
- lua_settable(L, -3); /* t s */
+ lua_pushstring(L, p->name);
+ /*tex state: k t s */
+ lua_pushinteger(L, p->idx);
+ /*tex state: v k t s */
+ lua_settable(L, -3);
+ /*tex state: t s */
}
- lua_settable(L, LUA_REGISTRYINDEX); /* - */
+ lua_settable(L, LUA_REGISTRYINDEX);
+ /* tex state: - */
}
-
-@ @c
-/*
- luajit compatibility layer for luatex lua5.2
+/*tex
+ Here comes a \LUAJIT\ compatibility layer for \LUATEX\ \LUA5.2:
*/
+
#ifdef LuajitTeX
-@ @c
LUALIB_API char *luaL_prepbuffsize (luaL_Buffer *B, size_t sz) {
lua_State *L = B->L;
if (sz > LUAL_BUFFERSIZE )
@@ -631,24 +738,22 @@ LUALIB_API char *luaL_prepbuffsize (luaL_Buffer *B, size_t sz) {
return luaL_prepbuffer(B) ;
}
-@ @c
LUA_API int lua_compare (lua_State *L, int o1, int o2, int op) {
/*StkId o1, o2;*/
int i = 0;
lua_lock(L); /* may call tag method */
/* o1 = index2addr(L, index1); */
/* o2 = index2addr(L, index2); */
- /*if (isvalid(o1) && isvalid(o2)) {*/
+ /* if (isvalid(o1) && isvalid(o2)) {*/
switch (op) {
case LUA_OPEQ: i = lua_equal(L, o1, o2); break;
case LUA_OPLT: i = lua_lessthan(L, o1, o2); break;
case LUA_OPLE: i = (lua_lessthan(L, o1, o2) || lua_equal(L, o1, o2)) ; break;
default: luaL_error(L, "invalid option");
}
- /*}*/
+ /* } */
lua_unlock(L);
return i;
}
-@ @c
#endif
diff --git a/Build/source/texk/web2c/luatexdir/lua/luatoken.c b/Build/source/texk/web2c/luatexdir/lua/luatoken.c
new file mode 100644
index 00000000000..fb197b68f7b
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/lua/luatoken.c
@@ -0,0 +1,585 @@
+/*
+
+luatoken.w
+
+Copyright 2006-2012 Taco Hoekwater <taco@@luatex.org>
+
+This file is part of LuaTeX.
+
+LuaTeX is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version.
+
+LuaTeX is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU General Public License along
+with LuaTeX; if not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#include "ptexlib.h"
+#include "lua/luatex-api.h"
+
+command_item command_names[] = {
+ { relax_cmd, NULL, 0},
+ { left_brace_cmd, NULL, 0},
+ { right_brace_cmd, NULL, 0},
+ { math_shift_cmd, NULL, 0},
+ { tab_mark_cmd, NULL, 0},
+ { car_ret_cmd, NULL, 0},
+ { mac_param_cmd, NULL, 0},
+ { sup_mark_cmd, NULL, 0},
+ { sub_mark_cmd, NULL, 0},
+ { endv_cmd, NULL, 0},
+ { spacer_cmd, NULL, 0},
+ { letter_cmd, NULL, 0},
+ { other_char_cmd, NULL, 0},
+ { par_end_cmd, NULL, 0},
+ { stop_cmd, NULL, 0},
+ { delim_num_cmd, NULL, 0},
+ { char_num_cmd, NULL, 0},
+ { math_char_num_cmd, NULL, 0},
+ { mark_cmd, NULL, 0},
+ { node_cmd, NULL, 0},
+ { xray_cmd, NULL, 0},
+ { make_box_cmd, NULL, 0},
+ { hmove_cmd, NULL, 0},
+ { vmove_cmd, NULL, 0},
+ { un_hbox_cmd, NULL, 0},
+ { un_vbox_cmd, NULL, 0},
+ { remove_item_cmd, NULL, 0},
+ { hskip_cmd, NULL, 0},
+ { vskip_cmd, NULL, 0},
+ { mskip_cmd, NULL, 0},
+ { kern_cmd, NULL, 0},
+ { mkern_cmd, NULL, 0},
+ { leader_ship_cmd, NULL, 0},
+ { halign_cmd, NULL, 0},
+ { valign_cmd, NULL, 0},
+ { no_align_cmd, NULL, 0},
+ { no_vrule_cmd, NULL, 0},
+ { no_hrule_cmd, NULL, 0},
+ { vrule_cmd, NULL, 0},
+ { hrule_cmd, NULL, 0},
+ { insert_cmd, NULL, 0},
+ { vadjust_cmd, NULL, 0},
+ { ignore_spaces_cmd, NULL, 0},
+ { after_assignment_cmd, NULL, 0},
+ { after_group_cmd, NULL, 0},
+ { break_penalty_cmd, NULL, 0},
+ { start_par_cmd, NULL, 0},
+ { ital_corr_cmd, NULL, 0},
+ { accent_cmd, NULL, 0},
+ { math_accent_cmd, NULL, 0},
+ { discretionary_cmd, NULL, 0},
+ { eq_no_cmd, NULL, 0},
+ { left_right_cmd, NULL, 0},
+ { math_comp_cmd, NULL, 0},
+ { limit_switch_cmd, NULL, 0},
+ { above_cmd, NULL, 0},
+ { math_style_cmd, NULL, 0},
+ { math_choice_cmd, NULL, 0},
+ { non_script_cmd, NULL, 0},
+ { vcenter_cmd, NULL, 0},
+ { case_shift_cmd, NULL, 0},
+ { message_cmd, NULL, 0},
+ { normal_cmd, NULL, 0},
+ { extension_cmd, NULL, 0},
+ { option_cmd, NULL, 0},
+ { lua_function_call_cmd, NULL, 0},
+ { lua_bytecode_call_cmd, NULL, 0},
+ { lua_call_cmd, NULL, 0},
+ { in_stream_cmd, NULL, 0},
+ { begin_group_cmd, NULL, 0},
+ { end_group_cmd, NULL, 0},
+ { omit_cmd, NULL, 0},
+ { ex_space_cmd, NULL, 0},
+ { boundary_cmd, NULL, 0},
+ { radical_cmd, NULL, 0},
+ { super_sub_script_cmd, NULL, 0},
+ { no_super_sub_script_cmd, NULL, 0},
+ { math_shift_cs_cmd, NULL, 0},
+ { end_cs_name_cmd, NULL, 0},
+ { char_ghost_cmd, NULL, 0},
+ { assign_local_box_cmd, NULL, 0},
+ { char_given_cmd, NULL, 0},
+ { math_given_cmd, NULL, 0},
+ { xmath_given_cmd, NULL, 0},
+ { last_item_cmd, NULL, 0},
+ { toks_register_cmd, NULL, 0},
+ { assign_toks_cmd, NULL, 0},
+ { assign_int_cmd, NULL, 0},
+ { assign_attr_cmd, NULL, 0},
+ { assign_dimen_cmd, NULL, 0},
+ { assign_glue_cmd, NULL, 0},
+ { assign_mu_glue_cmd, NULL, 0},
+ { assign_font_dimen_cmd, NULL, 0},
+ { assign_font_int_cmd, NULL, 0},
+ { assign_hang_indent_cmd, NULL, 0},
+ { set_aux_cmd, NULL, 0},
+ { set_prev_graf_cmd, NULL, 0},
+ { set_page_dimen_cmd, NULL, 0},
+ { set_page_int_cmd, NULL, 0},
+ { set_box_dimen_cmd, NULL, 0},
+ { set_tex_shape_cmd, NULL, 0},
+ { set_etex_shape_cmd, NULL, 0},
+ { def_char_code_cmd, NULL, 0},
+ { def_del_code_cmd, NULL, 0},
+ { extdef_math_code_cmd, NULL, 0},
+ { extdef_del_code_cmd, NULL, 0},
+ { def_family_cmd, NULL, 0},
+ { set_math_param_cmd, NULL, 0},
+ { set_font_cmd, NULL, 0},
+ { def_font_cmd, NULL, 0},
+ { register_cmd, NULL, 0},
+ { assign_box_direction_cmd, NULL, 0},
+ { assign_box_dir_cmd, NULL, 0},
+ { assign_direction_cmd, NULL, 0},
+ { assign_dir_cmd, NULL, 0},
+ { advance_cmd, NULL, 0},
+ { multiply_cmd, NULL, 0},
+ { divide_cmd, NULL, 0},
+ { prefix_cmd, NULL, 0},
+ { let_cmd, NULL, 0},
+ { shorthand_def_cmd, NULL, 0},
+ { def_lua_call_cmd, NULL, 0},
+ { read_to_cs_cmd, NULL, 0},
+ { def_cmd, NULL, 0},
+ { set_box_cmd, NULL, 0},
+ { hyph_data_cmd, NULL, 0},
+ { set_interaction_cmd, NULL, 0},
+ { letterspace_font_cmd, NULL, 0},
+ { expand_font_cmd, NULL, 0},
+ { copy_font_cmd, NULL, 0},
+ { set_font_id_cmd, NULL, 0},
+ { undefined_cs_cmd, NULL, 0},
+ { expand_after_cmd, NULL, 0},
+ { no_expand_cmd, NULL, 0},
+ { input_cmd, NULL, 0},
+ { lua_expandable_call_cmd, NULL, 0},
+ { lua_local_call_cmd, NULL, 0},
+ { if_test_cmd, NULL, 0},
+ { fi_or_else_cmd, NULL, 0},
+ { cs_name_cmd, NULL, 0},
+ { convert_cmd, NULL, 0},
+ { variable_cmd, NULL, 0},
+ { feedback_cmd, NULL, 0},
+ { the_cmd, NULL, 0},
+ { combine_toks_cmd, NULL, 0},
+ { top_bot_mark_cmd, NULL, 0},
+ { call_cmd, NULL, 0},
+ { long_call_cmd, NULL, 0},
+ { outer_call_cmd, NULL, 0},
+ { long_outer_call_cmd, NULL, 0},
+ { end_template_cmd, NULL, 0},
+ { dont_expand_cmd, NULL, 0},
+ { glue_ref_cmd, NULL, 0},
+ { shape_ref_cmd, NULL, 0},
+ { box_ref_cmd, NULL, 0},
+ { data_cmd, NULL, 0},
+ { -1, NULL, 0}
+};
+
+# define init_token_key(target,n,key) \
+ target[n].lua = luaS_##key##_index; \
+ target[n].name = luaS_##key##_ptr;
+
+void l_set_token_data(void)
+{
+ init_token_key(command_names, relax_cmd, relax);
+ init_token_key(command_names, left_brace_cmd, left_brace);
+ init_token_key(command_names, right_brace_cmd, right_brace);
+ init_token_key(command_names, math_shift_cmd, math_shift);
+ init_token_key(command_names, tab_mark_cmd, tab_mark);
+ init_token_key(command_names, car_ret_cmd, car_ret);
+ init_token_key(command_names, mac_param_cmd, mac_param);
+ init_token_key(command_names, sup_mark_cmd, sup_mark);
+ init_token_key(command_names, sub_mark_cmd, sub_mark);
+ init_token_key(command_names, endv_cmd, endv);
+ init_token_key(command_names, spacer_cmd, spacer);
+ init_token_key(command_names, letter_cmd, letter);
+ init_token_key(command_names, other_char_cmd, other_char);
+ init_token_key(command_names, par_end_cmd, par_end);
+ init_token_key(command_names, stop_cmd, stop);
+ init_token_key(command_names, delim_num_cmd, delim_num);
+ init_token_key(command_names, char_num_cmd, char_num);
+ init_token_key(command_names, math_char_num_cmd, math_char_num);
+ init_token_key(command_names, mark_cmd, mark);
+ init_token_key(command_names, node_cmd, node);
+ init_token_key(command_names, xray_cmd, xray);
+ init_token_key(command_names, make_box_cmd, make_box);
+ init_token_key(command_names, hmove_cmd, hmove);
+ init_token_key(command_names, vmove_cmd, vmove);
+ init_token_key(command_names, un_hbox_cmd, un_hbox);
+ init_token_key(command_names, un_vbox_cmd, un_vbox);
+ init_token_key(command_names, remove_item_cmd, remove_item);
+ init_token_key(command_names, hskip_cmd, hskip);
+ init_token_key(command_names, vskip_cmd, vskip);
+ init_token_key(command_names, mskip_cmd, mskip);
+ init_token_key(command_names, kern_cmd, kern);
+ init_token_key(command_names, mkern_cmd, mkern);
+ init_token_key(command_names, leader_ship_cmd, leader_ship);
+ init_token_key(command_names, halign_cmd, halign);
+ init_token_key(command_names, valign_cmd, valign);
+ init_token_key(command_names, no_align_cmd, no_align);
+ init_token_key(command_names, vrule_cmd, vrule);
+ init_token_key(command_names, hrule_cmd, hrule);
+ init_token_key(command_names, no_vrule_cmd, novrule);
+ init_token_key(command_names, no_hrule_cmd, nohrule);
+ init_token_key(command_names, insert_cmd, insert);
+ init_token_key(command_names, vadjust_cmd, vadjust);
+ init_token_key(command_names, ignore_spaces_cmd, ignore_spaces);
+ init_token_key(command_names, after_assignment_cmd, after_assignment);
+ init_token_key(command_names, after_group_cmd, after_group);
+ init_token_key(command_names, break_penalty_cmd, break_penalty);
+ init_token_key(command_names, start_par_cmd, start_par);
+ init_token_key(command_names, ital_corr_cmd, ital_corr);
+ init_token_key(command_names, accent_cmd, accent);
+ init_token_key(command_names, math_accent_cmd, math_accent);
+ init_token_key(command_names, discretionary_cmd, discretionary);
+ init_token_key(command_names, eq_no_cmd, eq_no);
+ init_token_key(command_names, left_right_cmd, left_right);
+ init_token_key(command_names, math_comp_cmd, math_comp);
+ init_token_key(command_names, limit_switch_cmd, limit_switch);
+ init_token_key(command_names, above_cmd, above);
+ init_token_key(command_names, math_style_cmd, math_style);
+ init_token_key(command_names, math_choice_cmd, math_choice);
+ init_token_key(command_names, non_script_cmd, non_script);
+ init_token_key(command_names, vcenter_cmd, vcenter);
+ init_token_key(command_names, case_shift_cmd, case_shift);
+ init_token_key(command_names, message_cmd, message);
+ init_token_key(command_names, normal_cmd, normal);
+ init_token_key(command_names, extension_cmd, extension);
+ init_token_key(command_names, option_cmd, option);
+ init_token_key(command_names, lua_function_call_cmd, lua_function_call);
+ init_token_key(command_names, lua_bytecode_call_cmd, lua_bytecode_call);
+ init_token_key(command_names, lua_call_cmd, lua_call);
+ init_token_key(command_names, in_stream_cmd, in_stream);
+ init_token_key(command_names, begin_group_cmd, begin_group);
+ init_token_key(command_names, end_group_cmd, end_group);
+ init_token_key(command_names, omit_cmd, omit);
+ init_token_key(command_names, ex_space_cmd, ex_space);
+ init_token_key(command_names, boundary_cmd, boundary);
+ init_token_key(command_names, radical_cmd, radical);
+ init_token_key(command_names, super_sub_script_cmd, super_sub_script);
+ init_token_key(command_names, no_super_sub_script_cmd, no_super_sub_script);
+ init_token_key(command_names, math_shift_cs_cmd, math_shift_cs);
+ init_token_key(command_names, end_cs_name_cmd, end_cs_name);
+ init_token_key(command_names, char_ghost_cmd, char_ghost);
+ init_token_key(command_names, assign_local_box_cmd, assign_local_box);
+ init_token_key(command_names, char_given_cmd, char_given);
+ init_token_key(command_names, math_given_cmd, math_given);
+ init_token_key(command_names, xmath_given_cmd, xmath_given);
+ init_token_key(command_names, last_item_cmd, last_item);
+ init_token_key(command_names, toks_register_cmd, toks_register);
+ init_token_key(command_names, assign_toks_cmd, assign_toks);
+ init_token_key(command_names, assign_int_cmd, assign_int);
+ init_token_key(command_names, assign_attr_cmd, assign_attr);
+ init_token_key(command_names, assign_dimen_cmd, assign_dimen);
+ init_token_key(command_names, assign_glue_cmd, assign_glue);
+ init_token_key(command_names, assign_mu_glue_cmd, assign_mu_glue);
+ init_token_key(command_names, assign_font_dimen_cmd, assign_font_dimen);
+ init_token_key(command_names, assign_font_int_cmd, assign_font_int);
+ init_token_key(command_names, assign_hang_indent_cmd, assign_hang_indent);
+ init_token_key(command_names, set_aux_cmd, set_aux);
+ init_token_key(command_names, set_prev_graf_cmd, set_prev_graf);
+ init_token_key(command_names, set_page_dimen_cmd, set_page_dimen);
+ init_token_key(command_names, set_page_int_cmd, set_page_int);
+ init_token_key(command_names, set_box_dimen_cmd, set_box_dimen);
+ init_token_key(command_names, set_tex_shape_cmd, set_tex_shape);
+ init_token_key(command_names, set_etex_shape_cmd, set_etex_shape);
+ init_token_key(command_names, def_char_code_cmd, def_char_code);
+ init_token_key(command_names, def_del_code_cmd, def_del_code);
+ init_token_key(command_names, extdef_math_code_cmd, extdef_math_code);
+ init_token_key(command_names, extdef_del_code_cmd, extdef_del_code);
+ init_token_key(command_names, def_family_cmd, def_family);
+ init_token_key(command_names, set_math_param_cmd, set_math_param);
+ init_token_key(command_names, set_font_cmd, set_font);
+ init_token_key(command_names, def_font_cmd, def_font);
+ init_token_key(command_names, def_lua_call_cmd, def_lua_call);
+ init_token_key(command_names, register_cmd, register);
+ init_token_key(command_names, assign_box_direction_cmd, assign_box_direction);
+ init_token_key(command_names, assign_box_dir_cmd, assign_box_dir);
+ init_token_key(command_names, assign_direction_cmd, assign_direction);
+ init_token_key(command_names, assign_dir_cmd, assign_dir);
+ init_token_key(command_names, advance_cmd, advance);
+ init_token_key(command_names, multiply_cmd, multiply);
+ init_token_key(command_names, divide_cmd, divide);
+ init_token_key(command_names, prefix_cmd, prefix);
+ init_token_key(command_names, let_cmd, let);
+ init_token_key(command_names, shorthand_def_cmd, shorthand_def);
+ init_token_key(command_names, read_to_cs_cmd, read_to_cs);
+ init_token_key(command_names, def_cmd, def);
+ init_token_key(command_names, set_box_cmd, set_box);
+ init_token_key(command_names, hyph_data_cmd, hyph_data);
+ init_token_key(command_names, set_interaction_cmd, set_interaction);
+ init_token_key(command_names, letterspace_font_cmd, letterspace_font);
+ init_token_key(command_names, expand_font_cmd, expand_font);
+ init_token_key(command_names, copy_font_cmd, copy_font);
+ init_token_key(command_names, set_font_id_cmd, set_font_id);
+ init_token_key(command_names, undefined_cs_cmd, undefined_cs);
+ init_token_key(command_names, expand_after_cmd, expand_after);
+ init_token_key(command_names, no_expand_cmd, no_expand);
+ init_token_key(command_names, input_cmd, input);
+ init_token_key(command_names, lua_expandable_call_cmd, lua_expandable_call);
+ init_token_key(command_names, lua_local_call_cmd, lua_local_call);
+ init_token_key(command_names, if_test_cmd, if_test);
+ init_token_key(command_names, fi_or_else_cmd, fi_or_else);
+ init_token_key(command_names, cs_name_cmd, cs_name);
+ init_token_key(command_names, convert_cmd, convert);
+ init_token_key(command_names, variable_cmd, variable);
+ init_token_key(command_names, feedback_cmd, feedback);
+ init_token_key(command_names, the_cmd, the);
+ init_token_key(command_names, combine_toks_cmd, combinetoks);
+ init_token_key(command_names, top_bot_mark_cmd, top_bot_mark);
+ init_token_key(command_names, call_cmd, call);
+ init_token_key(command_names, long_call_cmd, long_call);
+ init_token_key(command_names, outer_call_cmd, outer_call);
+ init_token_key(command_names, long_outer_call_cmd, long_outer_call);
+ init_token_key(command_names, end_template_cmd, end_template);
+ init_token_key(command_names, dont_expand_cmd, dont_expand);
+ init_token_key(command_names, glue_ref_cmd, glue_ref);
+ init_token_key(command_names, shape_ref_cmd, shape_ref);
+ init_token_key(command_names, box_ref_cmd, box_ref);
+ init_token_key(command_names, data_cmd, data);
+}
+
+int get_command_id(const char *s)
+{
+ int i;
+ for (i = 0; command_names[i].id != -1; i++) {
+ if (s == command_names[i].name)
+ return i;
+ }
+ return -1;
+}
+
+/*
+static int get_cur_cmd(lua_State * L)
+{
+ int r = 0;
+ size_t len = lua_rawlen(L, -1);
+ cur_cs = 0;
+ if (len == 3 || len == 2) {
+ r = 1;
+ lua_rawgeti(L, -1, 1);
+ cur_cmd = (int) lua_tointeger(L, -1);
+ lua_rawgeti(L, -2, 2);
+ cur_chr = (halfword) lua_tointeger(L, -1);
+ if (len == 3) {
+ lua_rawgeti(L, -3, 3);
+ cur_cs = (halfword) lua_tointeger(L, -1);
+ }
+ lua_pop(L, (int) len);
+ if (cur_cs == 0)
+ cur_tok = token_val(cur_cmd, cur_chr);
+ else
+ cur_tok = cs_token_flag + cur_cs;
+ }
+ return r;
+}
+*/
+
+static int token_from_lua(lua_State * L)
+{
+ int cmd, chr;
+ int cs = 0;
+ size_t len = lua_rawlen(L, -1);
+ if (len == 3 || len == 2) {
+ lua_rawgeti(L, -1, 1);
+ cmd = (int) lua_tointeger(L, -1);
+ lua_rawgeti(L, -2, 2);
+ chr = (int) lua_tointeger(L, -1);
+ if (len == 3) {
+ lua_rawgeti(L, -3, 3);
+ cs = (int) lua_tointeger(L, -1);
+ }
+ lua_pop(L, (int) len);
+ if (cs == 0) {
+ return token_val(cmd, chr);
+ } else {
+ return cs_token_flag + cs;
+ }
+ }
+ return -1;
+}
+
+/*
+static int get_cur_cs(lua_State * L)
+{
+ const char *s;
+ unsigned j;
+ size_t l;
+ int cs;
+ int save_nncs;
+ int ret;
+ ret = 0;
+ cur_cs = 0;
+ lua_getfield(L, -1, "name");
+ if (lua_type(L, -1) == LUA_TSTRING) {
+ s = lua_tolstring(L, -1, &l);
+ if (l > 0) {
+ if ((last + (int) l) > buf_size)
+ check_buffer_overflow((last + (int) l));
+ for (j = 0; j < l; j++) {
+ 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), (int) l);
+ cur_tok = cs_token_flag + cs;
+ cur_cmd = eq_type(cs);
+ cur_chr = equiv(cs);
+ no_new_control_sequence = save_nncs;
+ ret = 1;
+ }
+ }
+ lua_pop(L, 1);
+ return ret;
+}
+*/
+
+void tokenlist_to_lua(lua_State * L, int p)
+{
+ int cmd, chr, cs;
+ int v;
+ int i = 1;
+ v = p;
+ while (v != null && v < (int) fix_mem_end) {
+ i++;
+ v = token_link(v);
+ }
+ i = 1;
+ lua_createtable(L, i, 0);
+ 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 = token_cmd(token_info(p));
+ chr = token_chr(token_info(p));
+ make_token_table(L, cmd, chr, 0);
+ }
+ lua_rawseti(L, -2, i++);
+ p = token_link(p);
+ }
+}
+
+void tokenlist_to_luastring(lua_State * L, int p)
+{
+ int l;
+ char *s;
+ s = tokenlist_to_cstring(p, 1, &l);
+ lua_pushlstring(L, s, (size_t) l);
+ free(s);
+}
+
+int tokenlist_from_lua(lua_State * L)
+{
+ const char *s;
+ int tok, t;
+ size_t i, j;
+ halfword p, q, r;
+ r = get_avail();
+ token_info(r) = 0;
+ token_link(r) = null;
+ p = r;
+ t = lua_type(L, -1);
+ if (t == LUA_TTABLE) {
+ j = lua_rawlen(L, -1);
+ if (j > 0) {
+ for (i = 1; i <= j; i++) {
+ lua_rawgeti(L, -1, (int) i);
+ tok = token_from_lua(L);
+ if (tok >= 0) {
+ store_new_token(tok);
+ }
+ lua_pop(L, 1);
+ };
+ }
+ return r;
+ } else if (t == LUA_TSTRING) {
+ s = lua_tolstring(L, -1, &j);
+ for (i = 0; i < j; i++) {
+ if (s[i] == 32) {
+ tok = token_val(10, s[i]);
+ } else {
+ int j1 = (int) str2uni((const unsigned char *) (s + i));
+ i = i + (size_t) (utf8_size(j1) - 1);
+ tok = token_val(12, j1);
+ }
+ store_new_token(tok);
+ }
+ return r;
+ } else {
+ free_avail(r);
+ return null;
+ }
+}
+
+/*
+static void do_get_token_lua(int callback_id)
+{
+ while (1) {
+ if (!get_callback(Luas, callback_id)) {
+ get_next();
+ lua_pop(Luas, 2);
+ break;
+ }
+ if (lua_pcall(Luas, 0, 1, 0) != 0) {
+ tex_error(lua_tostring(Luas, -1), NULL);
+ lua_pop(Luas, 2);
+ break;
+ }
+ if (lua_istable(Luas, -1)) {
+ lua_rawgeti(Luas, -1, 1);
+ if (lua_istable(Luas, -1)) {
+ int p, q, r;
+ size_t i, j;
+ lua_pop(Luas, 1);
+ r = get_avail();
+ p = r;
+ j = lua_rawlen(Luas, -1);
+ if (j > 0) {
+ for (i = 1; i <= j; i++) {
+ lua_rawgeti(Luas, -1, (int) i);
+ if (get_cur_cmd(Luas) || get_cur_cs(Luas)) {
+ store_new_token(cur_tok);
+ }
+ lua_pop(Luas, 1);
+ }
+ }
+ if (p != r) {
+ p = token_link(r);
+ free_avail(r);
+ begin_token_list(p, inserted);
+ cur_input.nofilter_field = true;
+ get_next();
+ } else {
+ tex_error("error: illegal or empty token list returned", NULL);
+ }
+ lua_pop(Luas, 2);
+ break;
+ } else {
+ lua_pop(Luas, 1);
+ if (get_cur_cmd(Luas) || get_cur_cs(Luas)) {
+ lua_pop(Luas, 2);
+ break;
+ } else {
+ lua_pop(Luas, 2);
+ continue;
+ }
+ }
+ } else {
+ lua_pop(Luas, 2);
+ }
+ }
+ return;
+}
+*/
diff --git a/Build/source/texk/web2c/luatexdir/lua/luatoken.w b/Build/source/texk/web2c/luatexdir/lua/luatoken.w
deleted file mode 100644
index e9740ffc676..00000000000
--- a/Build/source/texk/web2c/luatexdir/lua/luatoken.w
+++ /dev/null
@@ -1,424 +0,0 @@
-% luatoken.w
-%
-% Copyright 2006-2012 Taco Hoekwater <taco@@luatex.org>
-%
-% This file is part of LuaTeX.
-%
-% LuaTeX is free software; you can redistribute it and/or modify it under
-% the terms of the GNU General Public License as published by the Free
-% Software Foundation; either version 2 of the License, or (at your
-% option) any later version.
-%
-% LuaTeX is distributed in the hope that it will be useful, but WITHOUT
-% ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-% FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
-% License for more details.
-%
-% You should have received a copy of the GNU General Public License along
-% with LuaTeX; if not, see <http://www.gnu.org/licenses/>.
-
-@ @c
-
-#include "ptexlib.h"
-#include "lua/luatex-api.h"
-
-@ @c
-command_item command_names[] = {
- {"relax", relax_cmd, NULL},
- {"left_brace", left_brace_cmd, NULL},
- {"right_brace", right_brace_cmd, NULL},
- {"math_shift", math_shift_cmd, NULL},
- {"tab_mark", tab_mark_cmd, NULL},
- {"car_ret", car_ret_cmd, NULL},
- {"mac_param", mac_param_cmd, NULL},
- {"sup_mark", sup_mark_cmd, NULL},
- {"sub_mark", sub_mark_cmd, NULL},
- {"endv", endv_cmd, NULL},
- {"spacer", spacer_cmd, NULL},
- {"letter", letter_cmd, NULL},
- {"other_char", other_char_cmd, NULL},
- {"par_end", par_end_cmd, NULL},
- {"stop", stop_cmd, NULL},
- {"delim_num", delim_num_cmd, NULL},
- {"char_num", char_num_cmd, NULL},
- {"math_char_num", math_char_num_cmd, NULL},
- {"mark", mark_cmd, NULL},
- {"xray", xray_cmd, NULL},
- {"make_box", make_box_cmd, NULL},
- {"hmove", hmove_cmd, NULL},
- {"vmove", vmove_cmd, NULL},
- {"un_hbox", un_hbox_cmd, NULL},
- {"un_vbox", un_vbox_cmd, NULL},
- {"remove_item", remove_item_cmd, NULL},
- {"hskip", hskip_cmd, NULL},
- {"vskip", vskip_cmd, NULL},
- {"mskip", mskip_cmd, NULL},
- {"kern", kern_cmd, NULL},
- {"mkern", mkern_cmd, NULL},
- {"leader_ship", leader_ship_cmd, NULL},
- {"halign", halign_cmd, NULL},
- {"valign", valign_cmd, NULL},
- {"no_align", no_align_cmd, NULL},
- {"novrule", no_vrule_cmd, NULL},
- {"nohrule", no_hrule_cmd, NULL},
- {"vrule", vrule_cmd, NULL},
- {"hrule", hrule_cmd, NULL},
- {"insert", insert_cmd, NULL},
- {"vadjust", vadjust_cmd, NULL},
- {"ignore_spaces", ignore_spaces_cmd, NULL},
- {"after_assignment", after_assignment_cmd, NULL},
- {"after_group", after_group_cmd, NULL},
- {"break_penalty", break_penalty_cmd, NULL},
- {"start_par", start_par_cmd, NULL},
- {"ital_corr", ital_corr_cmd, NULL},
- {"accent", accent_cmd, NULL},
- {"math_accent", math_accent_cmd, NULL},
- {"discretionary", discretionary_cmd, NULL},
- {"eq_no", eq_no_cmd, NULL},
- {"left_right", left_right_cmd, NULL},
- {"math_comp", math_comp_cmd, NULL},
- {"limit_switch", limit_switch_cmd, NULL},
- {"above", above_cmd, NULL},
- {"math_style", math_style_cmd, NULL},
- {"math_choice", math_choice_cmd, NULL},
- {"non_script", non_script_cmd, NULL},
- {"vcenter", vcenter_cmd, NULL},
- {"case_shift", case_shift_cmd, NULL},
- {"message", message_cmd, NULL},
- {"normal", normal_cmd, NULL},
- {"extension", extension_cmd, NULL},
- {"option", option_cmd, NULL},
- {"in_stream", in_stream_cmd, NULL},
- {"begin_group", begin_group_cmd, NULL},
- {"end_group", end_group_cmd, NULL},
- {"omit", omit_cmd, NULL},
- {"ex_space", ex_space_cmd, NULL},
- {"boundary", boundary_cmd, NULL},
- {"radical", radical_cmd, NULL},
- {"super_sub_script", super_sub_script_cmd, NULL},
- {"no_super_sub_script", no_super_sub_script_cmd, NULL},
- {"math_shift_cs", math_shift_cs_cmd, NULL},
- {"end_cs_name", end_cs_name_cmd, NULL},
- {"char_ghost", char_ghost_cmd, NULL},
- {"assign_local_box", assign_local_box_cmd, NULL},
- {"char_given", char_given_cmd, NULL},
- {"math_given", math_given_cmd, NULL},
- {"xmath_given", xmath_given_cmd, NULL},
- {"last_item", last_item_cmd, NULL},
- {"toks_register", toks_register_cmd, NULL},
- {"assign_toks", assign_toks_cmd, NULL},
- {"assign_int", assign_int_cmd, NULL},
- {"assign_attr", assign_attr_cmd, NULL},
- {"assign_dimen", assign_dimen_cmd, NULL},
- {"assign_glue", assign_glue_cmd, NULL},
- {"assign_mu_glue", assign_mu_glue_cmd, NULL},
- {"assign_font_dimen", assign_font_dimen_cmd, NULL},
- {"assign_font_int", assign_font_int_cmd, NULL},
- {"assign_hang_indent", assign_hang_indent_cmd, NULL},
- {"set_aux", set_aux_cmd, NULL},
- {"set_prev_graf", set_prev_graf_cmd, NULL},
- {"set_page_dimen", set_page_dimen_cmd, NULL},
- {"set_page_int", set_page_int_cmd, NULL},
- {"set_box_dimen", set_box_dimen_cmd, NULL},
- {"set_tex_shape", set_tex_shape_cmd, NULL},
- {"set_etex_shape", set_etex_shape_cmd, NULL},
- {"def_char_code", def_char_code_cmd, NULL},
- {"def_del_code", def_del_code_cmd, NULL},
- {"extdef_math_code", extdef_math_code_cmd, NULL},
- {"extdef_del_code", extdef_del_code_cmd, NULL},
- {"def_family", def_family_cmd, NULL},
- {"set_math_param", set_math_param_cmd, NULL},
- {"set_font", set_font_cmd, NULL},
- {"def_font", def_font_cmd, NULL},
- {"register", register_cmd, NULL},
- {"assign_box_dir", assign_box_dir_cmd, NULL},
- {"assign_dir", assign_dir_cmd, NULL},
- {"advance", advance_cmd, NULL},
- {"multiply", multiply_cmd, NULL},
- {"divide", divide_cmd, NULL},
- {"prefix", prefix_cmd, NULL},
- {"let", let_cmd, NULL},
- {"shorthand_def", shorthand_def_cmd, NULL},
- {"read_to_cs", read_to_cs_cmd, NULL},
- {"def", def_cmd, NULL},
- {"set_box", set_box_cmd, NULL},
- {"hyph_data", hyph_data_cmd, NULL},
- {"set_interaction", set_interaction_cmd, NULL},
- {"letterspace_font", letterspace_font_cmd, NULL},
- {"expand_font",expand_font_cmd, NULL},
- {"copy_font", copy_font_cmd, NULL},
- {"set_font_id", set_font_id_cmd, NULL},
- {"undefined_cs", undefined_cs_cmd, NULL},
- {"expand_after", expand_after_cmd, NULL},
- {"no_expand", no_expand_cmd, NULL},
- {"input", input_cmd, NULL},
- {"if_test", if_test_cmd, NULL},
- {"fi_or_else", fi_or_else_cmd, NULL},
- {"cs_name", cs_name_cmd, NULL},
- {"convert", convert_cmd, NULL},
- {"variable", variable_cmd, NULL},
- {"feedback", feedback_cmd, NULL},
- {"the", the_cmd, NULL},
- {"combinetoks", combine_toks_cmd, NULL},
- {"top_bot_mark", top_bot_mark_cmd, NULL},
- {"call", call_cmd, NULL},
- {"long_call", long_call_cmd, NULL},
- {"outer_call", outer_call_cmd, NULL},
- {"long_outer_call", long_outer_call_cmd, NULL},
- {"end_template", end_template_cmd, NULL},
- {"dont_expand", dont_expand_cmd, NULL},
- {"glue_ref", glue_ref_cmd, NULL},
- {"shape_ref", shape_ref_cmd, NULL},
- {"box_ref", box_ref_cmd, NULL},
- {"data", data_cmd, NULL},
- {NULL, 0, NULL}
-};
-
-
-@ @c
-int get_command_id(const char *s)
-{
- int i;
- int cmd = -1;
- for (i = 0; command_names[i].cmd_name != NULL; i++) {
- if (strcmp(s, command_names[i].cmd_name) == 0)
- break;
- }
- if (command_names[i].cmd_name != NULL) {
- cmd = i;
- }
- return cmd;
-}
-
-/*
-static int get_cur_cmd(lua_State * L)
-{
- int r = 0;
- size_t len = lua_rawlen(L, -1);
- cur_cs = 0;
- if (len == 3 || len == 2) {
- r = 1;
- lua_rawgeti(L, -1, 1);
- cur_cmd = (int) lua_tointeger(L, -1);
- lua_rawgeti(L, -2, 2);
- cur_chr = (halfword) lua_tointeger(L, -1);
- if (len == 3) {
- lua_rawgeti(L, -3, 3);
- cur_cs = (halfword) lua_tointeger(L, -1);
- }
- lua_pop(L, (int) len);
- if (cur_cs == 0)
- cur_tok = token_val(cur_cmd, cur_chr);
- else
- cur_tok = cs_token_flag + cur_cs;
- }
- return r;
-}
-*/
-
-@ @c
-static int token_from_lua(lua_State * L)
-{
- int cmd, chr;
- int cs = 0;
- size_t len = lua_rawlen(L, -1);
- if (len == 3 || len == 2) {
- lua_rawgeti(L, -1, 1);
- cmd = (int) lua_tointeger(L, -1);
- lua_rawgeti(L, -2, 2);
- chr = (int) lua_tointeger(L, -1);
- if (len == 3) {
- lua_rawgeti(L, -3, 3);
- cs = (int) lua_tointeger(L, -1);
- }
- lua_pop(L, (int) len);
- if (cs == 0) {
- return token_val(cmd, chr);
- } else {
- return cs_token_flag + cs;
- }
- }
- return -1;
-}
-
-/*
-static int get_cur_cs(lua_State * L)
-{
- const char *s;
- unsigned j;
- size_t l;
- int cs;
- int save_nncs;
- int ret;
- ret = 0;
- cur_cs = 0;
- lua_getfield(L, -1, "name");
- if (lua_type(L, -1) == LUA_TSTRING) {
- s = lua_tolstring(L, -1, &l);
- if (l > 0) {
- if ((last + (int) l) > buf_size)
- check_buffer_overflow((last + (int) l));
- for (j = 0; j < l; j++) {
- 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), (int) l);
- cur_tok = cs_token_flag + cs;
- cur_cmd = eq_type(cs);
- cur_chr = equiv(cs);
- no_new_control_sequence = save_nncs;
- ret = 1;
- }
- }
- lua_pop(L, 1);
- 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 < (int) fix_mem_end) {
- i++;
- v = token_link(v);
- }
- i = 1;
- lua_createtable(L, i, 0);
- 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 = token_cmd(token_info(p));
- chr = token_chr(token_info(p));
- make_token_table(L, cmd, chr, 0);
- }
- lua_rawseti(L, -2, i++);
- 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, (size_t) l);
- free(s);
-}
-
-
-@ @c
-int tokenlist_from_lua(lua_State * L)
-{
- const char *s;
- int tok, t;
- size_t i, j;
- halfword p, q, r;
- r = get_avail();
- token_info(r) = 0; /* ref count */
- token_link(r) = null;
- p = r;
- t = lua_type(L, -1);
- if (t == LUA_TTABLE) {
- j = lua_rawlen(L, -1);
- if (j > 0) {
- for (i = 1; i <= j; i++) {
- lua_rawgeti(L, -1, (int) i);
- tok = token_from_lua(L);
- if (tok >= 0) {
- store_new_token(tok);
- }
- lua_pop(L, 1);
- };
- }
- return r;
- } else if (t == LUA_TSTRING) {
- s = lua_tolstring(L, -1, &j);
- for (i = 0; i < j; i++) {
- if (s[i] == 32) {
- tok = token_val(10, s[i]);
- } else {
- int j1 = (int) str2uni((const unsigned char *) (s + i));
- i = i + (size_t) (utf8_size(j1) - 1);
- tok = token_val(12, j1);
- }
- store_new_token(tok);
- }
- return r;
- } else {
- free_avail(r);
- return null;
- }
-}
-
-/*
-
-static void do_get_token_lua(int callback_id)
-{
- while (1) {
- if (!get_callback(Luas, callback_id)) {
- get_next();
- lua_pop(Luas, 2);
- break;
- }
- if (lua_pcall(Luas, 0, 1, 0) != 0) {
- tex_error(lua_tostring(Luas, -1), NULL);
- lua_pop(Luas, 2);
- break;
- }
- if (lua_istable(Luas, -1)) {
- lua_rawgeti(Luas, -1, 1);
- if (lua_istable(Luas, -1)) {
- int p, q, r;
- size_t i, j;
- lua_pop(Luas, 1);
- r = get_avail();
- p = r;
- j = lua_rawlen(Luas, -1);
- if (j > 0) {
- for (i = 1; i <= j; i++) {
- lua_rawgeti(Luas, -1, (int) i);
- if (get_cur_cmd(Luas) || get_cur_cs(Luas)) {
- store_new_token(cur_tok);
- }
- lua_pop(Luas, 1);
- }
- }
- if (p != r) {
- p = token_link(r);
- free_avail(r);
- begin_token_list(p, inserted);
- cur_input.nofilter_field = true;
- get_next();
- } else {
- tex_error("error: illegal or empty token list returned", NULL);
- }
- lua_pop(Luas, 2);
- break;
- } else {
- lua_pop(Luas, 1);
- if (get_cur_cmd(Luas) || get_cur_cs(Luas)) {
- lua_pop(Luas, 2);
- break;
- } else {
- lua_pop(Luas, 2);
- continue;
- }
- }
- } else {
- lua_pop(Luas, 2);
- }
- }
- return;
-}
-
-*/
diff --git a/Build/source/texk/web2c/luatexdir/lua/mplibstuff.c b/Build/source/texk/web2c/luatexdir/lua/mplibstuff.c
new file mode 100644
index 00000000000..f1713ae0e6e
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/lua/mplibstuff.c
@@ -0,0 +1,115 @@
+/*
+
+mplibstuff.w
+
+Copyright 2017 LuaTeX team <bugs@@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/>.
+
+*/
+
+/*tex
+
+The \PNG\ and \SVG\ backends are not available in \LUATEX, because it's complex
+to manage the math formulas at run time. In this respect \POSTSCRIPT\ and the
+highlevel |objects| are better, and they are the standard way. Another problem is
+how to emit the warning: the |normal_warning| function is not available when
+\LUATEX\ is called as \LUA\ only.
+
+*/
+
+#include <stdio.h>
+
+extern void normal_warning(const char *t, const char *p);
+
+extern int lua_only;
+
+#define mplibstuff_message(MSG) do { \
+ if (lua_only) { \
+ fprintf(stdout,"mplib: " #MSG " not available.\n"); \
+ } else { \
+ normal_warning("mplib", #MSG " not available."); \
+ } \
+} while (0)
+
+void mp_png_backend_initialize (void *mp);
+void mp_png_backend_free (void *mp);
+int mp_png_gr_ship_out (void *hh, void *options, int standalone);
+int mp_png_ship_out (void *hh, const char *options);
+
+void mp_svg_backend_initialize (void *mp);
+void mp_svg_backend_free (void *mp);
+int mp_svg_ship_out (void *hh, int prologues);
+int mp_svg_gr_ship_out (void *hh, int qprologues, int standalone);
+
+void *mp_initialize_binary_math(void *mp);
+
+
+void mp_png_backend_initialize (void *mp) { return; }
+void mp_png_backend_free (void *mp) { return; }
+int mp_png_gr_ship_out (void *hh, void *options, int standalone) { mplibstuff_message(png backend); return 1; }
+int mp_png_ship_out (void *hh, const char *options) { mplibstuff_message(png backend); return 1; }
+
+void mp_svg_backend_initialize (void *mp) { return; }
+void mp_svg_backend_free (void *mp) { return; }
+int mp_svg_ship_out (void *hh, int prologues) { mplibstuff_message(svg bakend); return 1; }
+int mp_svg_gr_ship_out (void *hh, int qprologues, int standalone) { mplibstuff_message(svg backend); return 1; }
+
+
+void *mp_initialize_binary_math(void *mp) {mplibstuff_message(math binary);return NULL; }
+
+const char* cairo_version_string (void);
+const char* mpfr_get_version(void);
+const char* pixman_version_string (void);
+
+
+#define CAIRO_VERSION_STRING "CAIRO NOT AVAILABLE"
+const char *COMPILED_CAIRO_VERSION_STRING = CAIRO_VERSION_STRING;
+
+#define MPFR_VERSION_STRING "MPFR NOT AVAILABLE"
+const char *COMPILED_MPFR_VERSION_STRING = MPFR_VERSION_STRING;
+
+
+#define __GNU_MP_VERSION -1
+#define __GNU_MP_VERSION_MINOR -1
+#define __GNU_MP_VERSION_PATCHLEVEL -1
+int COMPILED__GNU_MP_VERSION = __GNU_MP_VERSION ;
+int COMPILED__GNU_MP_VERSION_MINOR = __GNU_MP_VERSION_MINOR ;
+int COMPILED__GNU_MP_VERSION_PATCHLEVEL = __GNU_MP_VERSION_PATCHLEVEL ;
+const char * const COMPILED_gmp_version="GMP NOT AVAILABLE";
+
+#define PIXMAN_VERSION_STRING "PIXMAN NOT AVAILABLE"
+const char *COMPILED_PIXMAN_VERSION_STRING = PIXMAN_VERSION_STRING;
+
+const char* cairo_version_string (void)
+{
+ return CAIRO_VERSION_STRING;
+}
+
+const char* mpfr_get_version(void)
+{
+ return MPFR_VERSION_STRING;
+}
+
+const char* pixman_version_string (void)
+{
+ return PIXMAN_VERSION_STRING;
+}
+
+char png_libpng_ver[] = "PNG NOT AVAILABLE";
+
+
+
diff --git a/Build/source/texk/web2c/luatexdir/lua/mplibstuff.w b/Build/source/texk/web2c/luatexdir/lua/mplibstuff.w
deleted file mode 100644
index 3104a287007..00000000000
--- a/Build/source/texk/web2c/luatexdir/lua/mplibstuff.w
+++ /dev/null
@@ -1,93 +0,0 @@
-% mplibstuff.w
-%
-% Copyright 2017 LuaTeX team <bugs@@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/>.
-
-@ PNG and SVG backends are not available in \LuaTeX, because it's complex
-to manage the math formulas at run time. In this respect |PostScript| and the highlevel |objects|
-are better, and they are the standard way. Another problem is how to emit the warning:
-the |normal\_warning| function is not available when \LuaTeX\ is called as LUA only.
-
-
-
-@c
-#include <stdio.h>
-
-extern void normal_warning(const char *t, const char *p);
-extern int lua_only;
-#define mplibstuff_message(BACKEND) do { \
- if (lua_only) { \
- fprintf(stdout,"mplib: " #BACKEND " backend not available.\n"); \
- } else { \
- normal_warning("mplib", #BACKEND " backend not available."); \
- } \
-} while (0)
-
-
-@ @c
-void mp_png_backend_initialize (void *mp);
-void mp_png_backend_free (void *mp);
-int mp_png_gr_ship_out (void *hh, void *options, int standalone);
-int mp_png_ship_out (void *hh, const char *options);
-
-@ @c
-void mp_svg_backend_initialize (void *mp);
-void mp_svg_backend_free (void *mp);
-int mp_svg_ship_out (void *hh, int prologues);
-int mp_svg_gr_ship_out (void *hh, int qprologues, int standalone);
-
-@ @c
-void mp_png_backend_initialize (void *mp) {return; } /*{mplibstuff_message(1png);return;}*/
-void mp_png_backend_free (void *mp) {return; } /*{mplibstuff_message(png);return;}*/
-int mp_png_gr_ship_out (void *hh, void *options, int standalone) {mplibstuff_message(png);return 1;}
-int mp_png_ship_out (void *hh, const char *options) {mplibstuff_message(png);return 1;}
-
-@ @c
-void mp_svg_backend_initialize (void *mp) {return;} /*{mplibstuff_message(svg);return;}*/
-void mp_svg_backend_free (void *mp) {return;} /*{mplibstuff_message(svg);return;}*/
-int mp_svg_ship_out (void *hh, int prologues) {mplibstuff_message(svg);return 1;}
-int mp_svg_gr_ship_out (void *hh, int qprologues, int standalone) {mplibstuff_message(svg);return 1;}
-
-@ @c
-const char*
-cairo_version_string (void);
-const char*
-pixman_version_string (void);
-#define CAIRO_VERSION_STRING "CAIRO NOT AVAILABLE"
-const char *COMPILED_CAIRO_VERSION_STRING = CAIRO_VERSION_STRING;
-#define PIXMAN_VERSION_STRING "PIXMAN NOT AVAILABLE"
-const char *COMPILED_PIXMAN_VERSION_STRING = PIXMAN_VERSION_STRING;
-
-const char*
-cairo_version_string (void)
-{
- return CAIRO_VERSION_STRING;
-}
-
-const char*
-pixman_version_string (void)
-{
- return PIXMAN_VERSION_STRING;
-}
-
-
-
-
-
-@ @c
-char png_libpng_ver[] = "PNG NOT AVAILABLE";
-
diff --git a/Build/source/texk/web2c/luatexdir/lua/texluac.c b/Build/source/texk/web2c/luatexdir/lua/texluac.c
new file mode 100644
index 00000000000..61016cfdb5b
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/lua/texluac.c
@@ -0,0 +1,532 @@
+/*
+
+texluac.w
+
+Copyright (C) 1994-2007 Lua.org, PUC-Rio. All rights reserved.
+Copyright 2006-2013 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 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.
+
+*/
+
+#include <ctype.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define luac_c
+#define LUA_CORE
+
+#include "lua.h"
+#include "lauxlib.h"
+
+#include "ldebug.h"
+#include "ldo.h"
+#include "lfunc.h"
+#include "lmem.h"
+#include "lobject.h"
+#include "lopcodes.h"
+#include "lstring.h"
+#include "lundump.h"
+
+#include "lua/luatex-api.h"
+
+static void PrintFunction(const Proto* f, int full);
+
+#define luaU_print PrintFunction
+
+/*tex A fix for non-gcc compilation: */
+
+#if !defined(__GNUC__) || (__GNUC__ < 2)
+# define __attribute__(x)
+#endif
+
+/*tex default program name */
+
+#define PROGNAME "texluac"
+
+/*tex default output file */
+
+#define OUTPUT PROGNAME ".out"
+
+/*tex list bytecodes? */
+
+static int listing = 0;
+
+/*tex dump bytecodes? */
+
+static int dumping = 1;
+
+/*tex strip debug information? */
+
+static int stripping = 0;
+
+/*tex default output file name */
+
+static char Output[] = { OUTPUT };
+
+/*tex actual output file name */
+
+static const char *output = Output;
+
+/*tex actual program name */
+
+static const char *progname = PROGNAME;
+
+__attribute__ ((noreturn))
+static void fatal(const char *message) {
+ fprintf(stderr,"%s: %s\n",progname,message);
+ exit(EXIT_FAILURE);
+}
+
+__attribute__ ((noreturn))
+static void cannot(const char *what) {
+ fprintf(stderr,"%s: cannot %s %s: %s\n",progname,what,output,strerror(errno));
+ exit(EXIT_FAILURE);
+}
+
+__attribute__ ((noreturn))
+static void usage(const char* message)
+{
+ if (*message=='-')
+ fprintf(stderr,"%s: unrecognized option " LUA_QS "\n",progname,message);
+ else
+ fprintf(stderr,"%s: %s\n",progname,message);
+ fprintf(stderr,
+ "usage: %s [options] [filenames]\n"
+ "Available options are:\n"
+ " -l list (use -l -l for full listing)\n"
+ " -o name output to file " LUA_QL("name") " (default is \"%s\")\n"
+ " -p parse only\n"
+ " -s strip debug information\n"
+ " -v show version information\n"
+ " -- stop handling options\n"
+ " - stop handling options and process stdin\n"
+ ,progname,Output);
+ exit(EXIT_FAILURE);
+}
+
+#define IS(s) (strcmp(argv[i],s)==0)
+
+static int doargs(int argc, char* argv[])
+{
+ int i;
+ int version=0;
+ if (argv[0]!=NULL && *argv[0]!=0)
+ progname=argv[0];
+ for (i=1; i<argc; i++) {
+ if (*argv[i]!='-') {
+ /* end of options; keep it */
+ break;
+ } else if (IS("--")) {
+ /* end of options; skip it */
+ ++i;
+ if (version) ++version;
+ break;
+ } else if (IS("-")) {
+ /* end of options; use stdin */
+ break;
+ } else if (IS("-l")) {
+ /* list */
+ ++listing;
+ } else if (IS("-o")) {
+ /* output file */
+ output=argv[++i];
+ if (output==NULL || *output==0 || (*output=='-' && output[1]!=0))
+ usage(LUA_QL("-o") " needs argument");
+ if (IS("-"))
+ output=NULL;
+ } else if (IS("-p")) {
+ /* parse only */
+ dumping=0;
+ } else if (IS("-s")) {
+ /* strip debug information */
+ stripping=1;
+ } else if (IS("-v")) {
+ /* show version */
+ ++version;
+ } else {
+ /* unknown option */
+ usage(argv[i]);
+ }
+ }
+ if (i==argc && (listing || !dumping)) {
+ dumping=0;
+ argv[--i]=Output;
+ }
+ if (version) {
+ printf("%s\n",LUA_COPYRIGHT);
+ if (version==argc-1)
+ exit(EXIT_SUCCESS);
+ }
+ return i;
+}
+
+#define FUNCTION "(function()end)();"
+
+static const char* reader(lua_State *L, void *ud, size_t *size)
+{
+ UNUSED(L);
+ if ((*(int*)ud)--) {
+ *size=sizeof(FUNCTION)-1;
+ return FUNCTION;
+ } else {
+ *size=0;
+ return NULL;
+ }
+}
+
+#define toproto(L,i) getproto(L->top+(i))
+
+static const Proto* combine(lua_State* L, int n)
+{
+ if (n==1) {
+ return toproto(L,-1);
+ } else {
+ Proto* f;
+ int i=n;
+ if (lua_load(L,reader,&i,"=(" PROGNAME ")",NULL)!=LUA_OK)
+ fatal(lua_tostring(L,-1));
+ f=toproto(L,-1);
+ for (i=0; i<n; i++) {
+ f->p[i]=toproto(L,i-n-1);
+ if (f->p[i]->sizeupvalues>0)
+ f->p[i]->upvalues[0].instack=0;
+ }
+ f->sizelineinfo=0;
+ return f;
+ }
+}
+
+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);
+}
+
+static int pmain(lua_State* L)
+{
+ int argc=(int)lua_tointeger(L,1);
+ char** argv=(char**)lua_touserdata(L,2);
+ const Proto* f;
+ int i;
+ if (!lua_checkstack(L,argc))
+ fatal("too many input files");
+ /*tex
+ Open standard libraries: we need to to this to keep the symbol
+ |luaL_openlibs|.
+ */
+ luaL_checkversion(L);
+ /*tex stop collector during initialization */
+ lua_gc(L, LUA_GCSTOP, 0);
+ /*tex open libraries */
+ luaL_openlibs(L);
+ lua_gc(L, LUA_GCRESTART, 0);
+ for (i=0; i<argc; i++) {
+ const char* filename=IS("-") ? NULL : argv[i];
+ if (luaL_loadfile(L,filename)!=LUA_OK)
+ fatal(lua_tostring(L,-1));
+ }
+ f=combine(L,argc);
+ if (listing)
+ luaU_print(f,listing>1);
+ if (dumping) {
+ FILE* D= (output==NULL) ? stdout : fopen(output,"wb");
+ if (D==NULL)
+ cannot("open");
+ lua_lock(L);
+ luaU_dump(L,f,writer,D,stripping);
+ lua_unlock(L);
+ if (ferror(D))
+ cannot("write");
+ if (fclose(D))
+ cannot("close");
+ }
+ return 0;
+}
+
+int luac_main(int ac, char *av[])
+{
+ lua_State *L;
+ int i = doargs(ac, av);
+ ac -= i;
+ av += i;
+ if (ac <= 0)
+ usage("no input files given");
+ L=luaL_newstate();
+ if (L == NULL)
+ fatal("not enough memory for state");
+ lua_pushcfunction(L,&pmain);
+ lua_pushinteger(L,ac);
+ lua_pushlightuserdata(L,av);
+ if (lua_pcall(L,2,0,0)!=LUA_OK)
+ fatal(lua_tostring(L,-1));
+ lua_close(L);
+ return EXIT_SUCCESS;
+}
+
+/*
+ See Copyright Notice in |lua.h|.
+*/
+
+#define VOID(p) ((const void*)(p))
+
+#if (defined(LuajitTeX)) || (LUA_VERSION_NUM == 502)
+#define TSVALUE(o) rawtsvalue(o)
+#endif
+#if (LUA_VERSION_NUM == 503)
+#define TSVALUE(o) tsvalue(o)
+#endif
+
+static void PrintString(const TString* ts)
+{
+ const char* s=getstr(ts);
+ size_t i,n;
+#if (defined(LuajitTeX)) || (LUA_VERSION_NUM == 502)
+ n=ts->tsv.len;
+#endif
+#if (LUA_VERSION_NUM == 503)
+ n=(ts->tt == LUA_TSHRSTR ? ts->shrlen : ts->u.lnglen);
+#endif
+ printf("%c",'"');
+ for (i=0; i<n; i++) {
+ int c=(int)(unsigned char)s[i];
+ switch (c) {
+ case '"':
+ printf("\\\"");
+ break;
+ case '\\':
+ printf("\\\\");
+ break;
+ case '\a':
+ printf("\\a");
+ break;
+ case '\b':
+ printf("\\b");
+ break;
+ case '\f':
+ printf("\\f");
+ break;
+ case '\n':
+ printf("\\n");
+ break;
+ case '\r':
+ printf("\\r");
+ break;
+ case '\t':
+ printf("\\t");
+ break;
+ case '\v':
+ printf("\\v");
+ break;
+ default :
+ if (isprint(c))
+ printf("%c",c);
+ else
+ printf("\\%03d",c);
+ break;
+ }
+ }
+ printf("%c",'"');
+}
+
+static void PrintConstant(const Proto* f, int i)
+{
+ const TValue* o=&f->k[i];
+ switch (ttype(o)) {
+ case LUA_TNIL:
+ printf("nil");
+ break;
+ case LUA_TBOOLEAN:
+ printf(bvalue(o) ? "true" : "false");
+ break;
+ case LUA_TNUMBER:
+ printf(LUA_NUMBER_FMT,nvalue(o));
+ break;
+ case LUA_TSTRING:
+ PrintString(TSVALUE(o));
+ break;
+ default:
+ /*tex This cannot happen. */
+ printf("? type=%d",ttype(o));
+ break;
+ }
+}
+
+#define UPVALNAME(x) ((f->upvalues[x].name) ? getstr(f->upvalues[x].name) : "-")
+#define MYK(x) (-1-(x))
+
+static void PrintCode(const Proto* f)
+{
+ const Instruction* code=f->code;
+ int pc,n=f->sizecode;
+ for (pc=0; pc<n; pc++) {
+ Instruction i=code[pc];
+ OpCode o=GET_OPCODE(i);
+ int a=GETARG_A(i);
+ int b=GETARG_B(i);
+ int c=GETARG_C(i);
+ int ax=GETARG_Ax(i);
+ int bx=GETARG_Bx(i);
+ int sbx=GETARG_sBx(i);
+ int line=getfuncline(f,pc);
+ printf("\t%d\t",pc+1);
+ if (line>0)
+ printf("[%d]\t",line);
+ else
+ printf("[-]\t");
+ printf("%-9s\t",luaP_opnames[o]);
+ switch (getOpMode(o)) {
+ case iABC:
+ printf("%d",a);
+ if (getBMode(o)!=OpArgN) printf(" %d",ISK(b) ? (MYK(INDEXK(b))) : b);
+ if (getCMode(o)!=OpArgN) printf(" %d",ISK(c) ? (MYK(INDEXK(c))) : c);
+ break;
+ case iABx:
+ printf("%d",a);
+ if (getBMode(o)==OpArgK) printf(" %d",MYK(bx));
+ if (getBMode(o)==OpArgU) printf(" %d",bx);
+ break;
+ case iAsBx:
+ printf("%d %d",a,sbx);
+ break;
+ case iAx:
+ printf("%d",MYK(ax));
+ break;
+ }
+ switch (o) {
+ case OP_LOADK:
+ printf("\t; "); PrintConstant(f,bx);
+ break;
+ case OP_GETUPVAL:
+ case OP_SETUPVAL:
+ printf("\t; %s",UPVALNAME(b));
+ break;
+ case OP_GETTABUP:
+ printf("\t; %s",UPVALNAME(b));
+ if (ISK(c)) { printf(" "); PrintConstant(f,INDEXK(c)); }
+ break;
+ case OP_SETTABUP:
+ printf("\t; %s",UPVALNAME(a));
+ if (ISK(b)) { printf(" "); PrintConstant(f,INDEXK(b)); }
+ if (ISK(c)) { printf(" "); PrintConstant(f,INDEXK(c)); }
+ break;
+ case OP_GETTABLE:
+ case OP_SELF:
+ if (ISK(c)) { printf("\t; "); PrintConstant(f,INDEXK(c)); }
+ break;
+ case OP_SETTABLE:
+ case OP_ADD:
+ case OP_SUB:
+ case OP_MUL:
+ case OP_DIV:
+ case OP_POW:
+ case OP_EQ:
+ case OP_LT:
+ case OP_LE:
+ if (ISK(b) || ISK(c)) {
+ printf("\t; ");
+ if (ISK(b)) PrintConstant(f,INDEXK(b)); else printf("-");
+ printf(" ");
+ if (ISK(c)) PrintConstant(f,INDEXK(c)); else printf("-");
+ }
+ break;
+ case OP_JMP:
+ case OP_FORLOOP:
+ case OP_FORPREP:
+ case OP_TFORLOOP:
+ printf("\t; to %d",sbx+pc+2);
+ break;
+ case OP_CLOSURE:
+ printf("\t; %p",VOID(f->p[bx]));
+ break;
+ case OP_SETLIST:
+ if (c==0) printf("\t; %d",(int)code[++pc]); else printf("\t; %d",c);
+ break;
+ case OP_EXTRAARG:
+ printf("\t; "); PrintConstant(f,ax);
+ break;
+ default:
+ break;
+ }
+ printf("\n");
+ }
+}
+
+#define SS(x) ((x==1)?"":"s")
+#define S(x) (int)(x),SS(x)
+
+static void PrintHeader(const Proto* f)
+{
+ const char* s=f->source ? getstr(f->source) : "=?";
+ if (*s=='@' || *s=='=')
+ s++;
+ else if (*s==LUA_SIGNATURE[0])
+ s="(bstring)";
+ else
+ s="(string)";
+ printf("\n%s <%s:%d,%d> (%d instruction%s at %p)\n",
+ (f->linedefined==0)?"main":"function",s,
+ f->linedefined,f->lastlinedefined,
+ S(f->sizecode),VOID(f));
+ printf("%d%s param%s, %d slot%s, %d upvalue%s, ",
+ (int)(f->numparams),f->is_vararg?"+":"",SS(f->numparams),
+ S(f->maxstacksize),S(f->sizeupvalues));
+ printf("%d local%s, %d constant%s, %d function%s\n",
+ S(f->sizelocvars),S(f->sizek),S(f->sizep));
+}
+
+static void PrintDebug(const Proto* f)
+{
+ int i,n;
+ n=f->sizek;
+ printf("constants (%d) for %p:\n",n,VOID(f));
+ for (i=0; i<n; i++) {
+ printf("\t%d\t",i+1);
+ PrintConstant(f,i);
+ printf("\n");
+ }
+ n=f->sizelocvars;
+ printf("locals (%d) for %p:\n",n,VOID(f));
+ for (i=0; i<n; i++) {
+ printf("\t%d\t%s\t%d\t%d\n",
+ i,getstr(f->locvars[i].varname),f->locvars[i].startpc+1,f->locvars[i].endpc+1);
+ }
+ n=f->sizeupvalues;
+ printf("upvalues (%d) for %p:\n",n,VOID(f));
+ for (i=0; i<n; i++) {
+ printf("\t%d\t%s\t%d\t%d\n",
+ i,UPVALNAME(i),f->upvalues[i].instack,f->upvalues[i].idx);
+ }
+}
+
+static void PrintFunction(const Proto* f, int full)
+{
+ int i,n=f->sizep;
+ PrintHeader(f);
+ PrintCode(f);
+ if (full)
+ PrintDebug(f);
+ for (i=0; i<n; i++)
+ PrintFunction(f->p[i],full);
+}
diff --git a/Build/source/texk/web2c/luatexdir/lua/texluac.w b/Build/source/texk/web2c/luatexdir/lua/texluac.w
deleted file mode 100644
index 424c74c77fd..00000000000
--- a/Build/source/texk/web2c/luatexdir/lua/texluac.w
+++ /dev/null
@@ -1,495 +0,0 @@
-% texluac.w
-%
-% Copyright (C) 1994-2007 Lua.org, PUC-Rio. All rights reserved.
-% Copyright 2006-2013 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 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.
-
-@ @c
-
-
-#include <ctype.h>
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#define luac_c
-#define LUA_CORE
-
-#include "lua.h"
-#include "lauxlib.h"
-
-#include "ldebug.h"
-#include "ldo.h"
-#include "lfunc.h"
-#include "lmem.h"
-#include "lobject.h"
-#include "lopcodes.h"
-#include "lstring.h"
-#include "lundump.h"
-
-#include "lua/luatex-api.h"
-
-static void PrintFunction(const Proto* f, int full);
-#define luaU_print PrintFunction
-
-@ @c
-/* fix for non-gcc compilation: */
-#if !defined(__GNUC__) || (__GNUC__ < 2)
-# define __attribute__(x)
-#endif /* !defined(__GNUC__) || (__GNUC__ < 2) */
-
-@ @c
-#define PROGNAME "texluac" /* default program name */
-#define OUTPUT PROGNAME ".out" /* default output file */
-
-static int listing=0; /* list bytecodes? */
-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,strerror(errno));
- exit(EXIT_FAILURE);
-}
-
-@ @c
-__attribute__ ((noreturn))
-static void usage(const char* message)
-{
- if (*message=='-')
- fprintf(stderr,"%s: unrecognized option " LUA_QS "\n",progname,message);
- else
- fprintf(stderr,"%s: %s\n",progname,message);
- fprintf(stderr,
- "usage: %s [options] [filenames]\n"
- "Available options are:\n"
- " -l list (use -l -l for full listing)\n"
- " -o name output to file " LUA_QL("name") " (default is \"%s\")\n"
- " -p parse only\n"
- " -s strip debug information\n"
- " -v show version information\n"
- " -- stop handling options\n"
- " - stop handling options and process stdin\n"
- ,progname,Output);
- exit(EXIT_FAILURE);
-}
-
-@ @c
-#define IS(s) (strcmp(argv[i],s)==0)
-
-static int doargs(int argc, char* argv[])
-{
- int i;
- int version=0;
- if (argv[0]!=NULL && *argv[0]!=0) progname=argv[0];
- for (i=1; i<argc; i++)
- {
- if (*argv[i]!='-') /* end of options; keep it */
- break;
- else if (IS("--")) /* end of options; skip it */
- {
- ++i;
- if (version) ++version;
- break;
- }
- else if (IS("-")) /* end of options; use stdin */
- break;
- else if (IS("-l")) /* list */
- ++listing;
- else if (IS("-o")) /* output file */
- {
- output=argv[++i];
- if (output==NULL || *output==0 || (*output=='-' && output[1]!=0))
- usage(LUA_QL("-o") " needs argument");
- if (IS("-")) output=NULL;
- }
- else if (IS("-p")) /* parse only */
- dumping=0;
- else if (IS("-s")) /* strip debug information */
- stripping=1;
- else if (IS("-v")) /* show version */
- ++version;
- else /* unknown option */
- usage(argv[i]);
- }
- if (i==argc && (listing || !dumping))
- {
- dumping=0;
- argv[--i]=Output;
- }
- if (version)
- {
- printf("%s\n",LUA_COPYRIGHT);
- if (version==argc-1) exit(EXIT_SUCCESS);
- }
- return i;
-}
-
-@ @c
-#define FUNCTION "(function()end)();"
-
-static const char* reader(lua_State *L, void *ud, size_t *size)
-{
- UNUSED(L);
- if ((*(int*)ud)--)
- {
- *size=sizeof(FUNCTION)-1;
- return FUNCTION;
- }
- else
- {
- *size=0;
- return NULL;
- }
-}
-
-#define toproto(L,i) getproto(L->top+(i))
-
-static const Proto* combine(lua_State* L, int n)
-{
- if (n==1)
- return toproto(L,-1);
- else
- {
- Proto* f;
- int i=n;
- if (lua_load(L,reader,&i,"=(" PROGNAME ")",NULL)!=LUA_OK) fatal(lua_tostring(L,-1));
- f=toproto(L,-1);
- for (i=0; i<n; i++)
- {
- f->p[i]=toproto(L,i-n-1);
- if (f->p[i]->sizeupvalues>0) f->p[i]->upvalues[0].instack=0;
- }
- f->sizelineinfo=0;
- return f;
- }
-}
-
-@ @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);
-}
-
-static int pmain(lua_State* L)
-{
- int argc=(int)lua_tointeger(L,1);
- char** argv=(char**)lua_touserdata(L,2);
- const Proto* f;
- int i;
- if (!lua_checkstack(L,argc)) fatal("too many input files");
- /* open standard libraries: */
- /* we need to to this to keep */
- /* the symbol luaL_openlibs */
- luaL_checkversion(L);
- lua_gc(L, LUA_GCSTOP, 0); /* stop collector during initialization */
- luaL_openlibs(L); /* open libraries */
- lua_gc(L, LUA_GCRESTART, 0);
- for (i=0; i<argc; i++)
- {
- const char* filename=IS("-") ? NULL : argv[i];
- if (luaL_loadfile(L,filename)!=LUA_OK) fatal(lua_tostring(L,-1));
- }
- f=combine(L,argc);
- if (listing) luaU_print(f,listing>1);
- if (dumping)
- {
- FILE* D= (output==NULL) ? stdout : fopen(output,"wb");
- if (D==NULL) cannot("open");
- lua_lock(L);
- luaU_dump(L,f,writer,D,stripping);
- lua_unlock(L);
- if (ferror(D)) cannot("write");
- if (fclose(D)) cannot("close");
- }
- return 0;
-}
-
-@ @c
-int luac_main(int ac, char *av[])
-{
- lua_State *L;
- int i = doargs(ac, av);
- ac -= i;
- av += i;
- if (ac <= 0)
- usage("no input files given");
- L=luaL_newstate();
- if (L == NULL)
- fatal("not enough memory for state");
- lua_pushcfunction(L,&pmain);
- lua_pushinteger(L,ac);
- lua_pushlightuserdata(L,av);
- if (lua_pcall(L,2,0,0)!=LUA_OK)
- fatal(lua_tostring(L,-1));
- lua_close(L);
- return EXIT_SUCCESS;
-}
-
-/*
-** print bytecodes
-** See Copyright Notice in lua.h
-*/
-
-#define VOID(p) ((const void*)(p))
-
-#if (defined(LuajitTeX)) || (LUA_VERSION_NUM == 502)
-#define TSVALUE(o) rawtsvalue(o)
-#endif
-#if (LUA_VERSION_NUM == 503)
-#define TSVALUE(o) tsvalue(o)
-#endif
-
-
-static void PrintString(const TString* ts)
-{
- const char* s=getstr(ts);
- size_t i,n;
-#if (defined(LuajitTeX)) || (LUA_VERSION_NUM == 502)
- n=ts->tsv.len;
-#endif
-#if (LUA_VERSION_NUM == 503)
- n=(ts->tt == LUA_TSHRSTR ? ts->shrlen : ts->u.lnglen);
-#endif
- printf("%c",'"');
- for (i=0; i<n; i++)
- {
- int c=(int)(unsigned char)s[i];
- switch (c)
- {
- case '"': printf("\\\""); break;
- case '\\': printf("\\\\"); break;
- case '\a': printf("\\a"); break;
- case '\b': printf("\\b"); break;
- case '\f': printf("\\f"); break;
- case '\n': printf("\\n"); break;
- case '\r': printf("\\r"); break;
- case '\t': printf("\\t"); break;
- case '\v': printf("\\v"); break;
- default: if (isprint(c))
- printf("%c",c);
- else
- printf("\\%03d",c);
- }
- }
- printf("%c",'"');
-}
-
-static void PrintConstant(const Proto* f, int i)
-{
- const TValue* o=&f->k[i];
- switch (ttype(o))
- {
- case LUA_TNIL:
- printf("nil");
- break;
- case LUA_TBOOLEAN:
- printf(bvalue(o) ? "true" : "false");
- break;
- case LUA_TNUMBER:
- printf(LUA_NUMBER_FMT,nvalue(o));
- break;
- case LUA_TSTRING:
- PrintString(TSVALUE(o));
- break;
- default: /* cannot happen */
- printf("? type=%d",ttype(o));
- break;
- }
-}
-
-#define UPVALNAME(x) ((f->upvalues[x].name) ? getstr(f->upvalues[x].name) : "-")
-#define MYK(x) (-1-(x))
-
-static void PrintCode(const Proto* f)
-{
- const Instruction* code=f->code;
- int pc,n=f->sizecode;
- for (pc=0; pc<n; pc++)
- {
- Instruction i=code[pc];
- OpCode o=GET_OPCODE(i);
- int a=GETARG_A(i);
- int b=GETARG_B(i);
- int c=GETARG_C(i);
- int ax=GETARG_Ax(i);
- int bx=GETARG_Bx(i);
- int sbx=GETARG_sBx(i);
- int line=getfuncline(f,pc);
- printf("\t%d\t",pc+1);
- if (line>0) printf("[%d]\t",line); else printf("[-]\t");
- printf("%-9s\t",luaP_opnames[o]);
- switch (getOpMode(o))
- {
- case iABC:
- printf("%d",a);
- if (getBMode(o)!=OpArgN) printf(" %d",ISK(b) ? (MYK(INDEXK(b))) : b);
- if (getCMode(o)!=OpArgN) printf(" %d",ISK(c) ? (MYK(INDEXK(c))) : c);
- break;
- case iABx:
- printf("%d",a);
- if (getBMode(o)==OpArgK) printf(" %d",MYK(bx));
- if (getBMode(o)==OpArgU) printf(" %d",bx);
- break;
- case iAsBx:
- printf("%d %d",a,sbx);
- break;
- case iAx:
- printf("%d",MYK(ax));
- break;
- }
- switch (o)
- {
- case OP_LOADK:
- printf("\t; "); PrintConstant(f,bx);
- break;
- case OP_GETUPVAL:
- case OP_SETUPVAL:
- printf("\t; %s",UPVALNAME(b));
- break;
- case OP_GETTABUP:
- printf("\t; %s",UPVALNAME(b));
- if (ISK(c)) { printf(" "); PrintConstant(f,INDEXK(c)); }
- break;
- case OP_SETTABUP:
- printf("\t; %s",UPVALNAME(a));
- if (ISK(b)) { printf(" "); PrintConstant(f,INDEXK(b)); }
- if (ISK(c)) { printf(" "); PrintConstant(f,INDEXK(c)); }
- break;
- case OP_GETTABLE:
- case OP_SELF:
- if (ISK(c)) { printf("\t; "); PrintConstant(f,INDEXK(c)); }
- break;
- case OP_SETTABLE:
- case OP_ADD:
- case OP_SUB:
- case OP_MUL:
- case OP_DIV:
- case OP_POW:
- case OP_EQ:
- case OP_LT:
- case OP_LE:
- if (ISK(b) || ISK(c))
- {
- printf("\t; ");
- if (ISK(b)) PrintConstant(f,INDEXK(b)); else printf("-");
- printf(" ");
- if (ISK(c)) PrintConstant(f,INDEXK(c)); else printf("-");
- }
- break;
- case OP_JMP:
- case OP_FORLOOP:
- case OP_FORPREP:
- case OP_TFORLOOP:
- printf("\t; to %d",sbx+pc+2);
- break;
- case OP_CLOSURE:
- printf("\t; %p",VOID(f->p[bx]));
- break;
- case OP_SETLIST:
- if (c==0) printf("\t; %d",(int)code[++pc]); else printf("\t; %d",c);
- break;
- case OP_EXTRAARG:
- printf("\t; "); PrintConstant(f,ax);
- break;
- default:
- break;
- }
- printf("\n");
- }
-}
-
-#define SS(x) ((x==1)?"":"s")
-#define S(x) (int)(x),SS(x)
-
-static void PrintHeader(const Proto* f)
-{
- const char* s=f->source ? getstr(f->source) : "=?";
- if (*s=='@@' || *s=='=')
- s++;
- else if (*s==LUA_SIGNATURE[0])
- s="(bstring)";
- else
- s="(string)";
- printf("\n%s <%s:%d,%d> (%d instruction%s at %p)\n",
- (f->linedefined==0)?"main":"function",s,
- f->linedefined,f->lastlinedefined,
- S(f->sizecode),VOID(f));
- printf("%d%s param%s, %d slot%s, %d upvalue%s, ",
- (int)(f->numparams),f->is_vararg?"+":"",SS(f->numparams),
- S(f->maxstacksize),S(f->sizeupvalues));
- printf("%d local%s, %d constant%s, %d function%s\n",
- S(f->sizelocvars),S(f->sizek),S(f->sizep));
-}
-
-static void PrintDebug(const Proto* f)
-{
- int i,n;
- n=f->sizek;
- printf("constants (%d) for %p:\n",n,VOID(f));
- for (i=0; i<n; i++)
- {
- printf("\t%d\t",i+1);
- PrintConstant(f,i);
- printf("\n");
- }
- n=f->sizelocvars;
- printf("locals (%d) for %p:\n",n,VOID(f));
- for (i=0; i<n; i++)
- {
- printf("\t%d\t%s\t%d\t%d\n",
- i,getstr(f->locvars[i].varname),f->locvars[i].startpc+1,f->locvars[i].endpc+1);
- }
- n=f->sizeupvalues;
- printf("upvalues (%d) for %p:\n",n,VOID(f));
- for (i=0; i<n; i++)
- {
- printf("\t%d\t%s\t%d\t%d\n",
- i,UPVALNAME(i),f->upvalues[i].instack,f->upvalues[i].idx);
- }
-}
-
-static void PrintFunction(const Proto* f, int full)
-{
- int i,n=f->sizep;
- PrintHeader(f);
- PrintCode(f);
- if (full) PrintDebug(f);
- for (i=0; i<n; i++) PrintFunction(f->p[i],full);
-}
diff --git a/Build/source/texk/web2c/luatexdir/lua/texluajitc.c b/Build/source/texk/web2c/luatexdir/lua/texluajitc.c
new file mode 100644
index 00000000000..5cac5d65ab1
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/lua/texluajitc.c
@@ -0,0 +1,650 @@
+/*
+
+ LuaJIT frontend. Runs commands, scripts, read-eval-print (REPL) etc.
+ Copyright (C) 2005-2012 Mike Pall. See Copyright Notice in luajit.h
+
+ Major portions taken verbatim or adapted from the Lua interpreter.
+ Copyright (C) 1994-2008 Lua.org, PUC-Rio. See Copyright Notice in lua.h
+
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define luajit_c
+
+#include "lua.h"
+#include "lauxlib.h"
+#include "lualib.h"
+#include "luajit.h"
+
+#include "lj_arch.h"
+
+#if LJ_TARGET_POSIX
+#include <unistd.h>
+#define lua_stdin_is_tty() isatty(0)
+#elif LJ_TARGET_WINDOWS
+#include <io.h>
+#ifdef __BORLANDC__
+#define lua_stdin_is_tty() isatty(_fileno(stdin))
+#else
+#define lua_stdin_is_tty() _isatty(_fileno(stdin))
+#endif
+#else
+#define lua_stdin_is_tty() 1
+#endif
+
+#if !LJ_TARGET_CONSOLE
+#include <signal.h>
+#endif
+
+#include "lua/luatex-api.h"
+
+static lua_State *globalL = NULL;
+static const char *progname = LUA_PROGNAME;
+
+#if !LJ_TARGET_CONSOLE
+
+static void lstop(lua_State *L, lua_Debug *ar)
+{
+ /*tex Unused arg. */
+ (void)ar;
+ lua_sethook(L, NULL, 0, 0);
+ /*tex Avoid luaL_error -- a C hook doesn't add an extra frame. */
+ luaL_where(L, 0);
+ lua_pushfstring(L, "%sinterrupted!", lua_tostring(L, -1));
+ lua_error(L);
+}
+
+/*tex if another SIGINT happens before lstop, terminate process (default action) */
+
+static void laction(int i)
+{
+ signal(i, SIG_DFL);
+ lua_sethook(globalL, lstop, LUA_MASKCALL | LUA_MASKRET | LUA_MASKCOUNT, 1);
+}
+
+#endif
+
+static void print_usage(void)
+{
+ fprintf(stderr,
+ "usage: %s [options]... [script [args]...].\n"
+ "Available options are:\n"
+ " -e chunk Execute string " LUA_QL("chunk") ".\n"
+ " -l name Require library " LUA_QL("name") ".\n"
+ " -b ... Save or list bytecode.\n"
+ " -j cmd Perform LuaJIT control command.\n"
+ " -O[opt] Control LuaJIT optimizations.\n"
+ " -i Enter interactive mode after executing " LUA_QL("script") ".\n"
+ " -v Show version information.\n"
+ " -E Ignore environment variables.\n"
+ " -- Stop handling options.\n"
+ " - Execute stdin and stop handling options.\n"
+ ,
+ progname);
+ fflush(stderr);
+}
+
+static void l_message(const char *pname, const char *msg)
+{
+ if (pname) fprintf(stderr, "%s: ", pname);
+ fprintf(stderr, "%s\n", msg);
+ fflush(stderr);
+}
+
+static int report(lua_State *L, int status)
+{
+ if (status && !lua_isnil(L, -1)) {
+ const char *msg = lua_tostring(L, -1);
+ if (msg == NULL)
+ msg = "(error object is not a string)";
+ l_message(progname, msg);
+ lua_pop(L, 1);
+ }
+ return status;
+}
+
+static int traceback(lua_State *L)
+{
+ if (!lua_isstring(L, 1)) {
+ /*tex Non-string error object? Try metamethod. */
+ if (lua_isnoneornil(L, 1) || !luaL_callmeta(L, 1, "__tostring") || !lua_isstring(L, -1)) {
+ /*tex Return non-string error object. */
+ return 1;
+ }
+ /*tex Replace object by result of __tostring metamethod. */
+ lua_remove(L, 1);
+ }
+ luaL_traceback(L, L, lua_tostring(L, 1), 1);
+ return 1;
+}
+
+static int docall(lua_State *L, int narg, int clear)
+{
+ int status;
+ /*tex function index */
+ int base = lua_gettop(L) - narg;
+ /*tex push traceback function */
+ lua_pushcfunction(L, traceback);
+ /*tex put it under chunk and args */
+ lua_insert(L, base);
+#if !LJ_TARGET_CONSOLE
+ signal(SIGINT, laction);
+#endif
+ status = lua_pcall(L, narg, (clear ? 0 : LUA_MULTRET), base);
+#if !LJ_TARGET_CONSOLE
+ signal(SIGINT, SIG_DFL);
+#endif
+ /*tex remove traceback function */
+ lua_remove(L, base);
+ /*tex force a complete garbage collection in case of errors */
+ if (status != 0)
+ lua_gc(L, LUA_GCCOLLECT, 0);
+ return status;
+}
+
+static void print_version(void)
+{
+ fputs(LUAJIT_VERSION " -- " LUAJIT_COPYRIGHT ". " LUAJIT_URL "\n", stdout);
+}
+
+static void print_jit_status(lua_State *L)
+{
+ int n;
+ const char *s;
+ lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED");
+ /*tex Get jit.* module table. */
+ lua_getfield(L, -1, "jit");
+ lua_remove(L, -2);
+ lua_getfield(L, -1, "status");
+ lua_remove(L, -2);
+ n = lua_gettop(L);
+ lua_call(L, 0, LUA_MULTRET);
+ fputs(lua_toboolean(L, n) ? "JIT: ON" : "JIT: OFF", stdout);
+ for (n++; (s = lua_tostring(L, n)); n++) {
+ putc(' ', stdout);
+ fputs(s, stdout);
+ }
+ putc('\n', stdout);
+}
+
+static int getargs(lua_State *L, char **argv, int n)
+{
+ int narg = 0;
+ int i;
+ /*tex count total number of arguments */
+ while (argv[argc]) argc++;
+ /*tex number of arguments to the script */
+ narg = argc - (n + 1);
+ luaL_checkstack(L, narg + 3, "too many arguments to script");
+ for (i = n+1; i < argc; i++) {
+ lua_pushstring(L, argv[i]);
+ }
+ lua_createtable(L, narg, n + 1);
+ for (i = 0; i < argc; i++) {
+ lua_pushstring(L, argv[i]);
+ lua_rawseti(L, -2, i - n);
+ }
+ return narg;
+}
+
+static int dofile(lua_State *L, const char *name)
+{
+ int status = luaL_loadfile(L, name) || docall(L, 0, 1);
+ return report(L, status);
+}
+
+static int dostring(lua_State *L, const char *s, const char *name)
+{
+ int status = luaL_loadbuffer(L, s, strlen(s), name) || docall(L, 0, 1);
+ return report(L, status);
+}
+
+static int dolibrary(lua_State *L, const char *name)
+{
+ lua_getglobal(L, "require");
+ lua_pushstring(L, name);
+ return report(L, docall(L, 1, 1));
+}
+
+static void write_prompt(lua_State *L, int firstline)
+{
+ const char *p;
+ lua_getfield(L, LUA_GLOBALSINDEX, firstline ? "_PROMPT" : "_PROMPT2");
+ p = lua_tostring(L, -1);
+ if (p == NULL) p = firstline ? LUA_PROMPT : LUA_PROMPT2;
+ fputs(p, stdout);
+ fflush(stdout);
+ /*tex remove global */
+ lua_pop(L, 1);
+}
+
+static int incomplete(lua_State *L, int status)
+{
+ if (status == LUA_ERRSYNTAX) {
+ size_t lmsg;
+ const char *msg = lua_tolstring(L, -1, &lmsg);
+ const char *tp = msg + lmsg - (sizeof(LUA_QL("<eof>")) - 1);
+ if (strstr(msg, LUA_QL("<eof>")) == tp) {
+ lua_pop(L, 1);
+ return 1;
+ }
+ }
+ return 0;
+}
+
+static int pushline(lua_State *L, int firstline)
+{
+ char buf[LUA_MAXINPUT];
+ write_prompt(L, firstline);
+ if (fgets(buf, LUA_MAXINPUT, stdin)) {
+ size_t len = strlen(buf);
+ if (len > 0 && buf[len-1] == '\n')
+ buf[len-1] = '\0';
+ if (firstline && buf[0] == '=')
+ lua_pushfstring(L, "return %s", buf+1);
+ else
+ lua_pushstring(L, buf);
+ return 1;
+ }
+ return 0;
+}
+
+static int loadline(lua_State *L)
+{
+ int status;
+ lua_settop(L, 0);
+ if (!pushline(L, 1)) {
+ /*tex no input */
+ return -1;
+ }
+ for (;;) {
+ /*tex repeat until gets a complete line */
+ status = luaL_loadbuffer(L, lua_tostring(L, 1), lua_strlen(L, 1), "=stdin");
+ /*tex cannot try to add lines? */
+ if (!incomplete(L, status))
+ break;
+ /*tex no more input? */
+ if (!pushline(L, 0))
+ return -1;
+ /*tex add a new line... */
+ lua_pushliteral(L, "\n");
+ /*tex ...between the two lines */
+ lua_insert(L, -2);
+ /*tex join them */
+ lua_concat(L, 3);
+ }
+ /*tex remove line */
+ lua_remove(L, 1);
+ return status;
+}
+
+static void dotty(lua_State *L)
+{
+ int status;
+ const char *oldprogname = progname;
+ progname = NULL;
+ while ((status = loadline(L)) != -1) {
+ if (status == 0)
+ status = docall(L, 0, 0);
+ report(L, status);
+ if (status == 0 && lua_gettop(L) > 0) {
+ /*tex any result to print? */
+ lua_getglobal(L, "print");
+ lua_insert(L, 1);
+ if (lua_pcall(L, lua_gettop(L)-1, 0, 0) != 0)
+ l_message(progname,
+ lua_pushfstring(L, "error calling " LUA_QL("print") " (%s)",
+ lua_tostring(L, -1)));
+ }
+ }
+ /*tex clear stack */
+ lua_settop(L, 0);
+ fputs("\n", stdout);
+ fflush(stdout);
+ progname = oldprogname;
+}
+
+static int handle_script(lua_State *L, char **argv, int n)
+{
+ int status;
+ const char *fname;
+ /*tex collect arguments */
+ int narg = getargs(L, argv, n);
+ lua_setglobal(L, "arg");
+ fname = argv[n];
+ if (strcmp(fname, "-") == 0 && strcmp(argv[n-1], "--") != 0) {
+ /*tex use stdin */
+ fname = NULL;
+ }
+ status = luaL_loadfile(L, fname);
+ lua_insert(L, -(narg+1));
+ if (status == 0)
+ status = docall(L, narg, 0);
+ else
+ lua_pop(L, narg);
+ return report(L, status);
+}
+
+/*tex Load add-on module. */
+
+static int loadjitmodule(lua_State *L)
+{
+ lua_getglobal(L, "require");
+ lua_pushliteral(L, "jit.");
+ lua_pushvalue(L, -3);
+ lua_concat(L, 2);
+ if (lua_pcall(L, 1, 1, 0)) {
+ const char *msg = lua_tostring(L, -1);
+ if (msg && !strncmp(msg, "module ", 7)) {
+ err:
+ l_message(progname,
+ "unknown luaJIT command or jit.* modules not installed");
+ return 1;
+ } else {
+ return report(L, 1);
+ }
+ }
+ lua_getfield(L, -1, "start");
+ if (lua_isnil(L, -1))
+ goto err;
+ /*tex Drop module table. */
+ lua_remove(L, -2);
+ return 0;
+}
+
+/*tex Run command with options. */
+
+static int runcmdopt(lua_State *L, const char *opt)
+{
+ int narg = 0;
+ if (opt && *opt) {
+ /*tex Split arguments. */
+ for (;;) {
+ const char *p = strchr(opt, ',');
+ narg++;
+ if (!p)
+ break;
+ if (p == opt)
+ lua_pushnil(L);
+ else
+ lua_pushlstring(L, opt, (size_t)(p - opt));
+ opt = p + 1;
+ }
+ if (*opt)
+ lua_pushstring(L, opt);
+ else
+ lua_pushnil(L);
+ }
+ return report(L, lua_pcall(L, narg, 0, 0));
+}
+
+/*tex JIT engine control command: try jit library first or load add-on module. */
+
+static int dojitcmd(lua_State *L, const char *cmd)
+{
+ const char *opt = strchr(cmd, '=');
+ lua_pushlstring(L, cmd, opt ? (size_t)(opt - cmd) : strlen(cmd));
+ lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED");
+ /*tex Get jit.* module table. */
+ lua_getfield(L, -1, "jit");
+ lua_remove(L, -2);
+ /*tex Lookup library function. */
+ lua_pushvalue(L, -2);
+ lua_gettable(L, -2);
+ if (!lua_isfunction(L, -1)) {
+ /*tex Drop non-function and jit.* table, keep module name. */
+ lua_pop(L, 2);
+ if (loadjitmodule(L))
+ return 1;
+ } else {
+ /*tex Drop jit.* table. */
+ lua_remove(L, -2);
+ }
+ /*tex Drop module name. */
+ lua_remove(L, -2);
+ return runcmdopt(L, opt ? opt+1 : opt);
+}
+
+/*tex Optimization flags. */
+
+static int dojitopt(lua_State *L, const char *opt)
+{
+ lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED");
+ lua_getfield(L, -1, "jit.opt");
+ lua_remove(L, -2);
+ lua_getfield(L, -1, "start");
+ lua_remove(L, -2);
+ return runcmdopt(L, opt);
+}
+
+/*tex Save or list bytecode. */
+
+static int dobytecode(lua_State *L, char **argv)
+{
+ int narg = 0;
+ lua_pushliteral(L, "bcsave");
+ if (loadjitmodule(L))
+ return 1;
+ if (argv[0][2]) {
+ narg++;
+ argv[0][1] = '-';
+ lua_pushstring(L, argv[0]+1);
+ }
+ for (argv++; *argv != NULL; narg++, argv++)
+ lua_pushstring(L, *argv);
+ return report(L, lua_pcall(L, narg, 0, 0));
+}
+
+/*tex Check that argument has no extra characters at the end */
+
+#define notail(x) {if ((x)[2] != '\0') return -1;}
+
+#define FLAGS_INTERACTIVE 1
+#define FLAGS_VERSION 2
+#define FLAGS_EXEC 4
+#define FLAGS_OPTION 8
+#define FLAGS_NOENV 16
+
+static int collectargs(char **argv, int *flags)
+{
+ int i;
+ for (i = 1; argv[i] != NULL; i++) {
+ /*tex Not an option? */
+ if (argv[i][0] != '-')
+ return i;
+ /*tex Check option. */
+ switch (argv[i][1]) {
+ case '-':
+ notail(argv[i]);
+ return (argv[i+1] != NULL ? i+1 : 0);
+ case '\0':
+ return i;
+ case 'i':
+ notail(argv[i]);
+ *flags |= FLAGS_INTERACTIVE;
+ /*tex fallthrough */
+ case 'v':
+ notail(argv[i]);
+ *flags |= FLAGS_VERSION;
+ break;
+ case 'e':
+ *flags |= FLAGS_EXEC;
+ case 'j':
+ /*tex LuaJIT extension */
+ case 'l':
+ *flags |= FLAGS_OPTION;
+ if (argv[i][2] == '\0') {
+ i++;
+ if (argv[i] == NULL)
+ return -1;
+ }
+ break;
+ case 'O':
+ /*tex LuaJIT extension */
+ break;
+ case 'b':
+ /*tex LuaJIT extension */
+ if (*flags) return -1;
+ *flags |= FLAGS_EXEC;
+ return 0;
+ case 'E':
+ *flags |= FLAGS_NOENV;
+ break;
+ default:
+ /*tex invalid option */
+ return -1;
+ }
+ }
+ return 0;
+}
+
+static int runargs(lua_State *L, char **argv, int n)
+{
+ int i;
+ for (i = 1; i < n; i++) {
+ if (argv[i] == NULL)
+ continue;
+ lua_assert(argv[i][0] == '-');
+ switch (argv[i][1]) {
+ /*tex Options */
+ case 'e': {
+ const char *chunk = argv[i] + 2;
+ if (*chunk == '\0')
+ chunk = argv[++i];
+ lua_assert(chunk != NULL);
+ if (dostring(L, chunk, "=(command line)") != 0)
+ return 1;
+ break;
+ }
+ case 'l': {
+ const char *filename = argv[i] + 2;
+ if (*filename == '\0')
+ filename = argv[++i];
+ lua_assert(filename != NULL);
+ if (dolibrary(L, filename)) {
+ /*tex stop if file fails */
+ return 1;
+ }
+ break;
+ }
+ case 'j': {
+ /*tex LuaJIT extension */
+ const char *cmd = argv[i] + 2;
+ if (*cmd == '\0')
+ cmd = argv[++i];
+ lua_assert(cmd != NULL);
+ if (dojitcmd(L, cmd))
+ return 1;
+ break;
+ }
+ case 'O':
+ /*tex LuaJIT extension */
+ if (dojitopt(L, argv[i] + 2))
+ return 1;
+ break;
+ case 'b':
+ /*tex LuaJIT extension */
+ return dobytecode(L, argv+i);
+ default: break;
+ }
+ }
+ return 0;
+}
+
+static int handle_luainit(lua_State *L)
+{
+#if LJ_TARGET_CONSOLE
+ const char *init = NULL;
+#else
+ const char *init = getenv(LUA_INIT);
+#endif
+ if (init == NULL) {
+ /*tex status OK */
+ return 0;
+ } else if (init[0] == 64) {
+ return dofile(L, init+1);
+ } else {
+ return dostring(L, init, "=" LUA_INIT);
+ }
+}
+
+struct Smain {
+ char **argv;
+ int argc;
+ int status;
+};
+
+static int pmain(lua_State *L)
+{
+ struct Smain *s = (struct Smain *)lua_touserdata(L, 1);
+ char **argv = s->argv;
+ int script;
+ int flags = 0;
+ globalL = L;
+ if (argv[0] && argv[0][0])
+ progname = argv[0];
+ /*tex linker-enforced version check */
+ LUAJIT_VERSION_SYM();
+ script = collectargs(argv, &flags);
+ if (script < 0) {
+ /*tex invalid args? */
+ print_usage();
+ s->status = 1;
+ return 0;
+ }
+ if ((flags & FLAGS_NOENV)) {
+ lua_pushboolean(L, 1);
+ lua_setfield(L, LUA_REGISTRYINDEX, "LUA_NOENV");
+ }
+ /*tex stop collector during initialization */
+ lua_gc(L, LUA_GCSTOP, 0);
+ /*tex open libraries */
+ luaL_openlibs(L);
+ lua_gc(L, LUA_GCRESTART, -1);
+ if (!(flags & FLAGS_NOENV)) {
+ s->status = handle_luainit(L);
+ if (s->status != 0) return 0;
+ }
+ if ((flags & FLAGS_VERSION)) print_version();
+ s->status = runargs(L, argv, (script > 0) ? script : s->argc);
+ if (s->status != 0) return 0;
+ if (script) {
+ s->status = handle_script(L, argv, script);
+ if (s->status != 0) return 0;
+ }
+ if ((flags & FLAGS_INTERACTIVE)) {
+ print_jit_status(L);
+ dotty(L);
+ } else if (script == 0 && !(flags & (FLAGS_EXEC|FLAGS_VERSION))) {
+ if (lua_stdin_is_tty()) {
+ print_version();
+ print_jit_status(L);
+ dotty(L);
+ } else {
+ /*tex executes stdin as a file */
+ dofile(L, NULL);
+ }
+ }
+ return 0;
+}
+
+int luac_main(int argc, char **argv)
+{
+ int status;
+ struct Smain s;
+ lua_State *L = lua_open(); /* create state */
+ if (L == NULL) {
+ l_message(argv[0], "cannot create state: not enough memory");
+ return EXIT_FAILURE;
+ }
+ s.argc = argc;
+ s.argv = argv;
+ status = lua_cpcall(L, pmain, &s);
+ report(L, status);
+ lua_close(L);
+ return (status || s.status) ? EXIT_FAILURE : EXIT_SUCCESS;
+}
+
diff --git a/Build/source/texk/web2c/luatexdir/lua/texluajitc.w b/Build/source/texk/web2c/luatexdir/lua/texluajitc.w
deleted file mode 100644
index f54f9c8d4a4..00000000000
--- a/Build/source/texk/web2c/luatexdir/lua/texluajitc.w
+++ /dev/null
@@ -1,575 +0,0 @@
-/*
-** LuaJIT frontend. Runs commands, scripts, read-eval-print (REPL) etc.
-** Copyright (C) 2005-2012 Mike Pall. See Copyright Notice in luajit.h
-**
-** Major portions taken verbatim or adapted from the Lua interpreter.
-** Copyright (C) 1994-2008 Lua.org, PUC-Rio. See Copyright Notice in lua.h
-*/
-
-@ @c
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#define luajit_c
-
-#include "lua.h"
-#include "lauxlib.h"
-#include "lualib.h"
-#include "luajit.h"
-
-#include "lj_arch.h"
-
-#if LJ_TARGET_POSIX
-#include <unistd.h>
-#define lua_stdin_is_tty() isatty(0)
-#elif LJ_TARGET_WINDOWS
-#include <io.h>
-#ifdef __BORLANDC__
-#define lua_stdin_is_tty() isatty(_fileno(stdin))
-#else
-#define lua_stdin_is_tty() _isatty(_fileno(stdin))
-#endif
-#else
-#define lua_stdin_is_tty() 1
-#endif
-
-#if !LJ_TARGET_CONSOLE
-#include <signal.h>
-#endif
-
-#include "lua/luatex-api.h"
-
-static lua_State *globalL = NULL;
-static const char *progname = LUA_PROGNAME;
-
-#if !LJ_TARGET_CONSOLE
-static void lstop(lua_State *L, lua_Debug *ar)
-{
- (void)ar; /* unused arg. */
- lua_sethook(L, NULL, 0, 0);
- /* Avoid luaL_error -- a C hook doesn't add an extra frame. */
- luaL_where(L, 0);
- lua_pushfstring(L, "%sinterrupted!", lua_tostring(L, -1));
- lua_error(L);
-}
-
-static void laction(int i)
-{
- signal(i, SIG_DFL); /* if another SIGINT happens before lstop,
- terminate process (default action) */
- lua_sethook(globalL, lstop, LUA_MASKCALL | LUA_MASKRET | LUA_MASKCOUNT, 1);
-}
-#endif
-
-static void print_usage(void)
-{
- fprintf(stderr,
- "usage: %s [options]... [script [args]...].\n"
- "Available options are:\n"
- " -e chunk Execute string " LUA_QL("chunk") ".\n"
- " -l name Require library " LUA_QL("name") ".\n"
- " -b ... Save or list bytecode.\n"
- " -j cmd Perform LuaJIT control command.\n"
- " -O[opt] Control LuaJIT optimizations.\n"
- " -i Enter interactive mode after executing " LUA_QL("script") ".\n"
- " -v Show version information.\n"
- " -E Ignore environment variables.\n"
- " -- Stop handling options.\n"
- " - Execute stdin and stop handling options.\n"
- ,
- progname);
- fflush(stderr);
-}
-
-static void l_message(const char *pname, const char *msg)
-{
- if (pname) fprintf(stderr, "%s: ", pname);
- fprintf(stderr, "%s\n", msg);
- fflush(stderr);
-}
-
-static int report(lua_State *L, int status)
-{
- if (status && !lua_isnil(L, -1)) {
- const char *msg = lua_tostring(L, -1);
- if (msg == NULL) msg = "(error object is not a string)";
- l_message(progname, msg);
- lua_pop(L, 1);
- }
- return status;
-}
-
-static int traceback(lua_State *L)
-{
- if (!lua_isstring(L, 1)) { /* Non-string error object? Try metamethod. */
- if (lua_isnoneornil(L, 1) ||
- !luaL_callmeta(L, 1, "__tostring") ||
- !lua_isstring(L, -1))
- return 1; /* Return non-string error object. */
- lua_remove(L, 1); /* Replace object by result of __tostring metamethod. */
- }
- luaL_traceback(L, L, lua_tostring(L, 1), 1);
- return 1;
-}
-
-static int docall(lua_State *L, int narg, int clear)
-{
- int status;
- int base = lua_gettop(L) - narg; /* function index */
- lua_pushcfunction(L, traceback); /* push traceback function */
- lua_insert(L, base); /* put it under chunk and args */
-#if !LJ_TARGET_CONSOLE
- signal(SIGINT, laction);
-#endif
- status = lua_pcall(L, narg, (clear ? 0 : LUA_MULTRET), base);
-#if !LJ_TARGET_CONSOLE
- signal(SIGINT, SIG_DFL);
-#endif
- lua_remove(L, base); /* remove traceback function */
- /* force a complete garbage collection in case of errors */
- if (status != 0) lua_gc(L, LUA_GCCOLLECT, 0);
- return status;
-}
-
-static void print_version(void)
-{
- fputs(LUAJIT_VERSION " -- " LUAJIT_COPYRIGHT ". " LUAJIT_URL "\n", stdout);
-}
-
-static void print_jit_status(lua_State *L)
-{
- int n;
- const char *s;
- lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED");
- lua_getfield(L, -1, "jit"); /* Get jit.* module table. */
- lua_remove(L, -2);
- lua_getfield(L, -1, "status");
- lua_remove(L, -2);
- n = lua_gettop(L);
- lua_call(L, 0, LUA_MULTRET);
- fputs(lua_toboolean(L, n) ? "JIT: ON" : "JIT: OFF", stdout);
- for (n++; (s = lua_tostring(L, n)); n++) {
- putc(' ', stdout);
- fputs(s, stdout);
- }
- putc('\n', stdout);
-}
-
-static int getargs(lua_State *L, char **argv, int n)
-{
- int narg;
- int i;
- int argc = 0;
- while (argv[argc]) argc++; /* count total number of arguments */
- narg = argc - (n + 1); /* number of arguments to the script */
- luaL_checkstack(L, narg + 3, "too many arguments to script");
- for (i = n+1; i < argc; i++)
- lua_pushstring(L, argv[i]);
- lua_createtable(L, narg, n + 1);
- for (i = 0; i < argc; i++) {
- lua_pushstring(L, argv[i]);
- lua_rawseti(L, -2, i - n);
- }
- return narg;
-}
-
-static int dofile(lua_State *L, const char *name)
-{
- int status = luaL_loadfile(L, name) || docall(L, 0, 1);
- return report(L, status);
-}
-
-static int dostring(lua_State *L, const char *s, const char *name)
-{
- int status = luaL_loadbuffer(L, s, strlen(s), name) || docall(L, 0, 1);
- return report(L, status);
-}
-
-static int dolibrary(lua_State *L, const char *name)
-{
- lua_getglobal(L, "require");
- lua_pushstring(L, name);
- return report(L, docall(L, 1, 1));
-}
-
-static void write_prompt(lua_State *L, int firstline)
-{
- const char *p;
- lua_getfield(L, LUA_GLOBALSINDEX, firstline ? "_PROMPT" : "_PROMPT2");
- p = lua_tostring(L, -1);
- if (p == NULL) p = firstline ? LUA_PROMPT : LUA_PROMPT2;
- fputs(p, stdout);
- fflush(stdout);
- lua_pop(L, 1); /* remove global */
-}
-
-static int incomplete(lua_State *L, int status)
-{
- if (status == LUA_ERRSYNTAX) {
- size_t lmsg;
- const char *msg = lua_tolstring(L, -1, &lmsg);
- const char *tp = msg + lmsg - (sizeof(LUA_QL("<eof>")) - 1);
- if (strstr(msg, LUA_QL("<eof>")) == tp) {
- lua_pop(L, 1);
- return 1;
- }
- }
- return 0; /* else... */
-}
-
-static int pushline(lua_State *L, int firstline)
-{
- char buf[LUA_MAXINPUT];
- write_prompt(L, firstline);
- if (fgets(buf, LUA_MAXINPUT, stdin)) {
- size_t len = strlen(buf);
- if (len > 0 && buf[len-1] == '\n')
- buf[len-1] = '\0';
- if (firstline && buf[0] == '=')
- lua_pushfstring(L, "return %s", buf+1);
- else
- lua_pushstring(L, buf);
- return 1;
- }
- return 0;
-}
-
-static int loadline(lua_State *L)
-{
- int status;
- lua_settop(L, 0);
- if (!pushline(L, 1))
- return -1; /* no input */
- for (;;) { /* repeat until gets a complete line */
- status = luaL_loadbuffer(L, lua_tostring(L, 1), lua_strlen(L, 1), "=stdin");
- if (!incomplete(L, status)) break; /* cannot try to add lines? */
- if (!pushline(L, 0)) /* no more input? */
- return -1;
- lua_pushliteral(L, "\n"); /* add a new line... */
- lua_insert(L, -2); /* ...between the two lines */
- lua_concat(L, 3); /* join them */
- }
- lua_remove(L, 1); /* remove line */
- return status;
-}
-
-static void dotty(lua_State *L)
-{
- int status;
- const char *oldprogname = progname;
- progname = NULL;
- while ((status = loadline(L)) != -1) {
- if (status == 0) status = docall(L, 0, 0);
- report(L, status);
- if (status == 0 && lua_gettop(L) > 0) { /* any result to print? */
- lua_getglobal(L, "print");
- lua_insert(L, 1);
- if (lua_pcall(L, lua_gettop(L)-1, 0, 0) != 0)
- l_message(progname,
- lua_pushfstring(L, "error calling " LUA_QL("print") " (%s)",
- lua_tostring(L, -1)));
- }
- }
- lua_settop(L, 0); /* clear stack */
- fputs("\n", stdout);
- fflush(stdout);
- progname = oldprogname;
-}
-
-static int handle_script(lua_State *L, char **argv, int n)
-{
- int status;
- const char *fname;
- int narg = getargs(L, argv, n); /* collect arguments */
- lua_setglobal(L, "arg");
- fname = argv[n];
- if (strcmp(fname, "-") == 0 && strcmp(argv[n-1], "--") != 0)
- fname = NULL; /* stdin */
- status = luaL_loadfile(L, fname);
- lua_insert(L, -(narg+1));
- if (status == 0)
- status = docall(L, narg, 0);
- else
- lua_pop(L, narg);
- return report(L, status);
-}
-
-/* Load add-on module. */
-static int loadjitmodule(lua_State *L)
-{
- lua_getglobal(L, "require");
- lua_pushliteral(L, "jit.");
- lua_pushvalue(L, -3);
- lua_concat(L, 2);
- if (lua_pcall(L, 1, 1, 0)) {
- const char *msg = lua_tostring(L, -1);
- if (msg && !strncmp(msg, "module ", 7)) {
- err:
- l_message(progname,
- "unknown luaJIT command or jit.* modules not installed");
- return 1;
- } else {
- return report(L, 1);
- }
- }
- lua_getfield(L, -1, "start");
- if (lua_isnil(L, -1)) goto err;
- lua_remove(L, -2); /* Drop module table. */
- return 0;
-}
-
-/* Run command with options. */
-static int runcmdopt(lua_State *L, const char *opt)
-{
- int narg = 0;
- if (opt && *opt) {
- for (;;) { /* Split arguments. */
- const char *p = strchr(opt, ',');
- narg++;
- if (!p) break;
- if (p == opt)
- lua_pushnil(L);
- else
- lua_pushlstring(L, opt, (size_t)(p - opt));
- opt = p + 1;
- }
- if (*opt)
- lua_pushstring(L, opt);
- else
- lua_pushnil(L);
- }
- return report(L, lua_pcall(L, narg, 0, 0));
-}
-
-/* JIT engine control command: try jit library first or load add-on module. */
-static int dojitcmd(lua_State *L, const char *cmd)
-{
- const char *opt = strchr(cmd, '=');
- lua_pushlstring(L, cmd, opt ? (size_t)(opt - cmd) : strlen(cmd));
- lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED");
- lua_getfield(L, -1, "jit"); /* Get jit.* module table. */
- lua_remove(L, -2);
- lua_pushvalue(L, -2);
- lua_gettable(L, -2); /* Lookup library function. */
- if (!lua_isfunction(L, -1)) {
- lua_pop(L, 2); /* Drop non-function and jit.* table, keep module name. */
- if (loadjitmodule(L))
- return 1;
- } else {
- lua_remove(L, -2); /* Drop jit.* table. */
- }
- lua_remove(L, -2); /* Drop module name. */
- return runcmdopt(L, opt ? opt+1 : opt);
-}
-
-/* Optimization flags. */
-static int dojitopt(lua_State *L, const char *opt)
-{
- lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED");
- lua_getfield(L, -1, "jit.opt"); /* Get jit.opt.* module table. */
- lua_remove(L, -2);
- lua_getfield(L, -1, "start");
- lua_remove(L, -2);
- return runcmdopt(L, opt);
-}
-
-/* Save or list bytecode. */
-static int dobytecode(lua_State *L, char **argv)
-{
- int narg = 0;
- lua_pushliteral(L, "bcsave");
- if (loadjitmodule(L))
- return 1;
- if (argv[0][2]) {
- narg++;
- argv[0][1] = '-';
- lua_pushstring(L, argv[0]+1);
- }
- for (argv++; *argv != NULL; narg++, argv++)
- lua_pushstring(L, *argv);
- return report(L, lua_pcall(L, narg, 0, 0));
-}
-
-/* check that argument has no extra characters at the end */
-#define notail(x) {if ((x)[2] != '\0') return -1;}
-
-#define FLAGS_INTERACTIVE 1
-#define FLAGS_VERSION 2
-#define FLAGS_EXEC 4
-#define FLAGS_OPTION 8
-#define FLAGS_NOENV 16
-
-static int collectargs(char **argv, int *flags)
-{
- int i;
- for (i = 1; argv[i] != NULL; i++) {
- if (argv[i][0] != '-') /* Not an option? */
- return i;
- switch (argv[i][1]) { /* Check option. */
- case '-':
- notail(argv[i]);
- return (argv[i+1] != NULL ? i+1 : 0);
- case '\0':
- return i;
- case 'i':
- notail(argv[i]);
- *flags |= FLAGS_INTERACTIVE;
- /* fallthrough */
- case 'v':
- notail(argv[i]);
- *flags |= FLAGS_VERSION;
- break;
- case 'e':
- *flags |= FLAGS_EXEC;
- case 'j': /* LuaJIT extension */
- case 'l':
- *flags |= FLAGS_OPTION;
- if (argv[i][2] == '\0') {
- i++;
- if (argv[i] == NULL) return -1;
- }
- break;
- case 'O': break; /* LuaJIT extension */
- case 'b': /* LuaJIT extension */
- if (*flags) return -1;
- *flags |= FLAGS_EXEC;
- return 0;
- case 'E':
- *flags |= FLAGS_NOENV;
- break;
- default: return -1; /* invalid option */
- }
- }
- return 0;
-}
-
-static int runargs(lua_State *L, char **argv, int n)
-{
- int i;
- for (i = 1; i < n; i++) {
- if (argv[i] == NULL) continue;
- lua_assert(argv[i][0] == '-');
- switch (argv[i][1]) { /* option */
- case 'e': {
- const char *chunk = argv[i] + 2;
- if (*chunk == '\0') chunk = argv[++i];
- lua_assert(chunk != NULL);
- if (dostring(L, chunk, "=(command line)") != 0)
- return 1;
- break;
- }
- case 'l': {
- const char *filename = argv[i] + 2;
- if (*filename == '\0') filename = argv[++i];
- lua_assert(filename != NULL);
- if (dolibrary(L, filename))
- return 1; /* stop if file fails */
- break;
- }
- case 'j': { /* LuaJIT extension */
- const char *cmd = argv[i] + 2;
- if (*cmd == '\0') cmd = argv[++i];
- lua_assert(cmd != NULL);
- if (dojitcmd(L, cmd))
- return 1;
- break;
- }
- case 'O': /* LuaJIT extension */
- if (dojitopt(L, argv[i] + 2))
- return 1;
- break;
- case 'b': /* LuaJIT extension */
- return dobytecode(L, argv+i);
- default: break;
- }
- }
- return 0;
-}
-
-static int handle_luainit(lua_State *L)
-{
-#if LJ_TARGET_CONSOLE
- const char *init = NULL;
-#else
- const char *init = getenv(LUA_INIT);
-#endif
- if (init == NULL)
- return 0; /* status OK */
- else if (init[0] == 64)
- return dofile(L, init+1);
- else
- return dostring(L, init, "=" LUA_INIT);
-}
-
-struct Smain {
- char **argv;
- int argc;
- int status;
-};
-
-static int pmain(lua_State *L)
-{
- struct Smain *s = (struct Smain *)lua_touserdata(L, 1);
- char **argv = s->argv;
- int script;
- int flags = 0;
- globalL = L;
- if (argv[0] && argv[0][0]) progname = argv[0];
- LUAJIT_VERSION_SYM(); /* linker-enforced version check */
- script = collectargs(argv, &flags);
- if (script < 0) { /* invalid args? */
- print_usage();
- s->status = 1;
- return 0;
- }
- if ((flags & FLAGS_NOENV)) {
- lua_pushboolean(L, 1);
- lua_setfield(L, LUA_REGISTRYINDEX, "LUA_NOENV");
- }
- lua_gc(L, LUA_GCSTOP, 0); /* stop collector during initialization */
- luaL_openlibs(L); /* open libraries */
- lua_gc(L, LUA_GCRESTART, -1);
- if (!(flags & FLAGS_NOENV)) {
- s->status = handle_luainit(L);
- if (s->status != 0) return 0;
- }
- if ((flags & FLAGS_VERSION)) print_version();
- s->status = runargs(L, argv, (script > 0) ? script : s->argc);
- if (s->status != 0) return 0;
- if (script) {
- s->status = handle_script(L, argv, script);
- if (s->status != 0) return 0;
- }
- if ((flags & FLAGS_INTERACTIVE)) {
- print_jit_status(L);
- dotty(L);
- } else if (script == 0 && !(flags & (FLAGS_EXEC|FLAGS_VERSION))) {
- if (lua_stdin_is_tty()) {
- print_version();
- print_jit_status(L);
- dotty(L);
- } else {
- dofile(L, NULL); /* executes stdin as a file */
- }
- }
- return 0;
-}
-
-int luac_main(int argc, char **argv)
-{
- int status;
- struct Smain s;
- lua_State *L = lua_open(); /* create state */
- if (L == NULL) {
- l_message(argv[0], "cannot create state: not enough memory");
- return EXIT_FAILURE;
- }
- s.argc = argc;
- s.argv = argv;
- status = lua_cpcall(L, pmain, &s);
- report(L, status);
- lua_close(L);
- return (status || s.status) ? EXIT_FAILURE : EXIT_SUCCESS;
-}
-