diff options
Diffstat (limited to 'Build/source/texk/web2c/luatexdir/lua/ltexlib.c')
-rw-r--r-- | Build/source/texk/web2c/luatexdir/lua/ltexlib.c | 820 |
1 files changed, 820 insertions, 0 deletions
diff --git a/Build/source/texk/web2c/luatexdir/lua/ltexlib.c b/Build/source/texk/web2c/luatexdir/lua/ltexlib.c new file mode 100644 index 00000000000..f2258010136 --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/lua/ltexlib.c @@ -0,0 +1,820 @@ +/* $Id: ltexlib.c 1087 2008-03-07 23:52:35Z hhenkel $ */ + +#include "luatex-api.h" +#include <ptexlib.h> +#include "nodes.h" + +typedef struct { + char *text; + unsigned int tsize; + void *next; + unsigned char partial; + int cattable; +} rope; + +typedef struct { + rope *head; + rope *tail; + char complete; /* currently still writing ? */ +} spindle; + +#define PARTIAL_LINE 1 +#define FULL_LINE 0 + +#define NO_CAT_TABLE -2 +#define DEFAULT_CAT_TABLE -1 + +#define write_spindle spindles[spindle_index] +#define read_spindle spindles[(spindle_index-1)] + +static int spindle_size = 0; +static spindle *spindles = NULL; +static int spindle_index = 0; + + +static int +do_luacprint (lua_State * L, int partial, int deftable) { + int i, n; + size_t tsize; + char *st, *sttemp; + rope *rn; + int cattable = deftable; + int startstrings = 1; + n = lua_gettop(L); + if (cattable != NO_CAT_TABLE) { + if (lua_type(L,1)==LUA_TNUMBER && n>1) { + cattable = lua_tonumber(L, 1); + startstrings = 2; + } + } + for (i = startstrings; i <= n; i++) { + if (!lua_isstring(L, i)) { + lua_pushstring(L, "no string to print"); + lua_error(L); + } + sttemp = (char *)lua_tolstring(L, i,&tsize); + st = xmalloc((tsize+1)); + memcpy(st,sttemp,(tsize+1)); + if (st) { + /* fprintf(stderr,"W[%d]:=%s\n",spindle_index,st);*/ + luacstrings++; + rn = (rope *)xmalloc(sizeof(rope)); /* valgrind says we leak here */ + rn->text = st; + rn->tsize = tsize; + rn->partial = partial; + rn->cattable = cattable; + rn->next = NULL; + if (write_spindle.head == NULL) { + assert(write_spindle.tail == NULL); + write_spindle.head = rn; + } else { + write_spindle.tail->next = rn; + } + write_spindle.tail = rn; + write_spindle.complete = 0; + } + } + return 0; +} + +int luacwrite(lua_State * L) { + return do_luacprint(L,FULL_LINE,NO_CAT_TABLE); +} + +int luacprint(lua_State * L) { + return do_luacprint(L,FULL_LINE,DEFAULT_CAT_TABLE); +} + +int luacsprint(lua_State * L) { + return do_luacprint(L,PARTIAL_LINE,DEFAULT_CAT_TABLE); +} + +int +luacstring_detokenized (void) { + return (read_spindle.tail->cattable == NO_CAT_TABLE); +} + +int +luacstring_defaultcattable (void) { + return (read_spindle.tail->cattable == DEFAULT_CAT_TABLE); +} + +integer +luacstring_cattable (void) { + return (integer)read_spindle.tail->cattable; +} + +int +luacstring_simple (void) { + return (read_spindle.tail->partial == PARTIAL_LINE); +} + +int +luacstring_penultimate (void) { + return (read_spindle.tail->next == NULL); +} + +int +luacstring_input (void) { + char *st; + int ret; + rope *t = read_spindle.head; + if (!read_spindle.complete) { + read_spindle.complete =1; + read_spindle.tail = NULL; + } + if (t == NULL) { + if(read_spindle.tail != NULL) + free(read_spindle.tail); + read_spindle.tail = NULL; + return 0; + } + if (t->text != NULL) { + st = t->text; + /* put that thing in the buffer */ + last = first; + ret = last; + check_buffer_overflow (last + t->tsize); + while (t->tsize-->0) + buffer[last++] = *st++; + if (!t->partial) { + while (last-1>ret && buffer[last-1] == ' ') + last--; + } + free (t->text); + t->text = NULL; + } + if (read_spindle.tail != NULL) { /* not a one-liner */ + free(read_spindle.tail); + } + read_spindle.tail = t; + read_spindle.head = t->next; + return 1; +} + +/* open for reading, and make a new one for writing */ +void +luacstring_start (int n) { + spindle_index++; + if(spindle_size == spindle_index) { /* add a new one */ + spindles = xrealloc(spindles,sizeof(spindle)*(spindle_size+1)); + spindles[spindle_index].head = NULL; + spindles[spindle_index].tail = NULL; + spindles[spindle_index].complete = 0; + spindle_size++; + } +} + +/* close for reading */ + +void +luacstring_close (int n) { + rope *next, *t; + next = read_spindle.head; + while (next != NULL) { + if (next->text != NULL) + free(next->text); + t = next; + next = next->next; + free(t); + } + read_spindle.head = NULL; + if(read_spindle.tail != NULL) + free(read_spindle.tail); + read_spindle.tail = NULL; + read_spindle.complete = 0; + spindle_index--; +} + +/* local (static) versions */ + +#define width_offset 1 +#define depth_offset 2 +#define height_offset 3 + +#define check_index_range(j) \ + if (j<0 || j > 65535) { \ + lua_pushstring(L, "incorrect index value"); \ + lua_error(L); } + + +int dimen_to_number (lua_State *L,char *s){ + double v; + char *d; + int j; + v = strtod(s,&d); + if (strcmp (d,"in") == 0) { j = (int)(((v*7227)/100) *65536); } + else if (strcmp (d,"pc") == 0) { j = (int)((v*12) *65536); } + else if (strcmp (d,"cm") == 0) { j = (int)(((v*7227)/254) *65536); } + else if (strcmp (d,"mm") == 0) { j = (int)(((v*7227)/2540) *65536); } + else if (strcmp (d,"bp") == 0) { j = (int)(((v*7227)/7200) *65536); } + else if (strcmp (d,"dd") == 0) { j = (int)(((v*1238)/1157) *65536); } + else if (strcmp (d,"cc") == 0) { j = (int)(((v*14856)/1157) *65536); } + else if (strcmp (d,"nd") == 0) { j = (int)(((v*21681)/20320)*65536); } + else if (strcmp (d,"nc") == 0) { j = (int)(((v*65043)/5080) *65536); } + else if (strcmp (d,"pt") == 0) { j = (int)(v *65536); } + else if (strcmp (d,"sp") == 0) { j = (int)(v); } + else { + lua_pushstring(L, "unknown dimension specifier"); + lua_error(L); + j = 0; + } + return j; +} + +int setdimen (lua_State *L) { + int i,j; + size_t k; + int cur_cs; + int texstr; + char *s; + i = lua_gettop(L); + j = 0; + /* find the value*/ + if (!lua_isnumber(L,i)) + if (lua_isstring(L,i)) { + j = dimen_to_number(L,(char *)lua_tostring(L,i)); + } else { + lua_pushstring(L, "unsupported value type"); + lua_error(L); + } + else + j = (int)lua_tonumber(L,i); + /* find the index*/ + if (lua_type(L,i-1)==LUA_TSTRING) { + s = (char *)lua_tolstring(L,i-1, &k); + texstr = maketexlstring(s,k); + cur_cs = string_lookup(texstr); + flush_str(texstr); + k = zget_equiv(cur_cs)-get_scaled_base(); + } else { + k = (int)luaL_checkinteger(L,i-1); + } + check_index_range(k); + if(set_tex_dimen_register(k,j)) { + lua_pushstring(L, "incorrect value"); + lua_error(L); + } + return 0; +} + +int getdimen (lua_State *L) { + int i,j; + size_t k; + int cur_cs; + int texstr; + char *s; + i = lua_gettop(L); + if (lua_type(L,i)==LUA_TSTRING) { + s = (char *)lua_tolstring(L,i, &k); + texstr = maketexlstring(s,k); + cur_cs = string_lookup(texstr); + flush_str(texstr); + if (is_undefined_cs(cur_cs)) { + lua_pushnil(L); + return 1; + } + k = zget_equiv(cur_cs)-get_scaled_base(); + } else { + k = (int)luaL_checkinteger(L,i); + } + check_index_range(k); + j = get_tex_dimen_register(k); + lua_pushnumber(L, j); + return 1; +} + +int setcount (lua_State *L) { + int i,j; + size_t k; + int cur_cs; + int texstr; + char *s; + i = lua_gettop(L); + j = (int)luaL_checkinteger(L,i); + if (lua_type(L,i-1)==LUA_TSTRING) { + s = (char *)lua_tolstring(L,i-1,&k); + texstr = maketexlstring(s,k); + cur_cs = string_lookup(texstr); + flush_str(texstr); + k = zget_equiv(cur_cs)-get_count_base(); + } else { + k = (int)luaL_checkinteger(L,i-1); + } + check_index_range(k); + if (set_tex_count_register(k,j)) { + lua_pushstring(L, "incorrect value"); + lua_error(L); + } + return 0; +} + +int getcount (lua_State *L) { + int i, j; + size_t k; + int cur_cs; + int texstr; + char *s; + i = lua_gettop(L); + if (lua_type(L,i)==LUA_TSTRING) { + s = (char *)lua_tolstring(L,i, &k); + texstr = maketexlstring(s,k); + cur_cs = string_lookup(texstr); + flush_str(texstr); + if (is_undefined_cs(cur_cs)) { + lua_pushnil(L); + return 1; + } + k = zget_equiv(cur_cs)-get_count_base(); + } else { + k = (int)luaL_checkinteger(L,i); + } + check_index_range(k); + j = get_tex_count_register(k); + lua_pushnumber(L, j); + return 1; +} + + +int setattribute (lua_State *L) { + int i,j; + size_t k; + int cur_cs; + int texstr; + char *s; + i = lua_gettop(L); + j = (int)luaL_checkinteger(L,i); + if (lua_type(L,i-1)==LUA_TSTRING) { + s = (char *)lua_tolstring(L,i-1, &k); + texstr = maketexlstring(s,k); + cur_cs = string_lookup(texstr); + flush_str(texstr); + k = zget_equiv(cur_cs)-get_attribute_base(); + } else { + k = (int)luaL_checkinteger(L,i-1); + } + check_index_range(k); + if (set_tex_attribute_register(k,j)) { + lua_pushstring(L, "incorrect value"); + lua_error(L); + } + return 0; +} + +int getattribute (lua_State *L) { + int i, j; + size_t k; + int cur_cs; + int texstr; + char *s; + i = lua_gettop(L); + if (lua_type(L,i)==LUA_TSTRING) { + s = (char *)lua_tolstring(L,i, &k); + texstr = maketexlstring(s,k); + cur_cs = string_lookup(texstr); + flush_str(texstr); + if (is_undefined_cs(cur_cs)) { + lua_pushnil(L); + return 1; + } + k = zget_equiv(cur_cs)-get_attribute_base(); + } else { + k = (int)luaL_checkinteger(L,i); + } + check_index_range(k); + j = get_tex_attribute_register(k); + lua_pushnumber(L, j); + return 1; +} + +int settoks (lua_State *L) { + int i,j; + size_t k,len; + int cur_cs; + int texstr; + char *s, *st; + i = lua_gettop(L); + if (!lua_isstring(L,i)) { + lua_pushstring(L, "unsupported value type"); + lua_error(L); + } + st = (char *)lua_tolstring(L,i,&len); + + if (lua_type(L,i-1)==LUA_TSTRING) { + s = (char *)lua_tolstring(L,i-1, &k); + texstr = maketexlstring(s,k); + cur_cs = string_lookup(texstr); + flush_str(texstr); + k = zget_equiv(cur_cs)-get_toks_base(); + } else { + k = (int)luaL_checkinteger(L,i-1); + } + check_index_range(k); + j = maketexlstring(st,len); + + if(zset_tex_toks_register(k,j)) { + flush_str(j); + lua_pushstring(L, "incorrect value"); + lua_error(L); + } + return 0; +} + +int gettoks (lua_State *L) { + int i; + size_t k; + strnumber t; + int cur_cs; + int texstr; + char *s; + i = lua_gettop(L); + if (lua_type(L,i)==LUA_TSTRING) { + s = (char *)lua_tolstring(L,i, &k); + texstr = maketexlstring(s,k); + cur_cs = string_lookup(texstr); + flush_str(texstr); + if (is_undefined_cs(cur_cs)) { + lua_pushnil(L); + return 1; + } + k = zget_equiv(cur_cs)-get_toks_base(); + } else { + k = (int)luaL_checkinteger(L,i); + } + + check_index_range(k); + t = get_tex_toks_register(k); + lua_pushstring(L, makecstring(t)); + flush_str(t); + return 1; +} + +int getbox (lua_State *L) { + int k, t; + k = (int)luaL_checkinteger(L,-1); + check_index_range(k); + t = get_tex_box_register(k); + nodelist_to_lua(L,t); + return 1; +} + +int setbox (lua_State *L) { + int i,j,k; + + + + k = (int)luaL_checkinteger(L,-2); + check_index_range(k); + i = get_tex_box_register(k); + if (lua_isboolean(L,-1)) { + j = lua_toboolean(L,-1); + if (j==0) + j = null; + else + return 0; + } else { + j = nodelist_from_lua(L); + } + if(set_tex_box_register(k,j)) { + lua_pushstring(L, "incorrect value"); + lua_error(L); + } + return 0; +} + + +static int getboxdim (lua_State *L, int whichdim) { + int i, j; + i = lua_gettop(L); + j = (int)lua_tonumber(L,(i)); + lua_settop(L,(i-2)); /* table at -1 */ + if (j<0 || j > 65535) { + lua_pushstring(L, "incorrect index"); + lua_error(L); + } + switch (whichdim) { + case width_offset: + lua_pushnumber(L, get_tex_box_width(j)); + break; + case height_offset: + lua_pushnumber(L, get_tex_box_height(j)); + break; + case depth_offset: + lua_pushnumber(L, get_tex_box_depth(j)); + } + return 1; +} + +int getboxwd (lua_State *L) { + return getboxdim (L, width_offset); +} + +int getboxht (lua_State *L) { + return getboxdim (L, height_offset); +} + +int getboxdp (lua_State *L) { + return getboxdim (L, depth_offset); +} + +static int setboxdim (lua_State *L, int whichdim) { + int i,j,k,err; + i = lua_gettop(L); + if (!lua_isnumber(L,i)) { + j = dimen_to_number(L,(char *)lua_tostring(L,i)); + } else { + j = (int)lua_tonumber(L,i); + } + k = (int)lua_tonumber(L,(i-1)); + lua_settop(L,(i-3)); /* table at -2 */ + if (k<0 || k > 65535) { + lua_pushstring(L, "incorrect index"); + lua_error(L); + } + err = 0; + switch (whichdim) { + case width_offset: + err = set_tex_box_width(k,j); + break; + case height_offset: + err = set_tex_box_height(k,j); + break; + case depth_offset: + err = set_tex_box_depth(k,j); + } + if (err) { + lua_pushstring(L, "not a box"); + lua_error(L); + } + return 0; +} + +int setboxwd (lua_State *L) { + return setboxdim(L,width_offset); +} + +int setboxht (lua_State *L) { + return setboxdim(L,height_offset); +} + +int setboxdp (lua_State *L) { + return setboxdim(L,depth_offset); +} + +int settex (lua_State *L) { + char *st; + int i,j,texstr; + size_t k; + int cur_cs, cur_cmd; + j = 0; + i = lua_gettop(L); + if (lua_isstring(L,(i-1))) { + st = (char *)lua_tolstring(L,(i-1), &k); + texstr = maketexlstring(st,k); + if (zis_primitive(texstr)) { + cur_cs = string_lookup(texstr); + flush_str(texstr); + cur_cmd = zget_eq_type(cur_cs); + if (is_int_assign(cur_cmd)) { + if (lua_isnumber(L,i)) { + assign_internal_int(zget_equiv(cur_cs),lua_tonumber(L,i)); + } else { + lua_pushstring(L, "unsupported value type"); + lua_error(L); + } + } else if (is_dim_assign(cur_cmd)) { + if (!lua_isnumber(L,i)) + if (lua_isstring(L,i)) { + j = dimen_to_number(L,(char *)lua_tostring(L,i)); + } else { + lua_pushstring(L, "unsupported value type"); + lua_error(L); + } + else + j = (int)lua_tonumber(L,i); + assign_internal_dim(zget_equiv(cur_cs),j); + } else { + lua_pushstring(L, "unsupported tex internal assignment"); + lua_error(L); + } + } else { + lua_rawset(L,(i-2)); + } + } else { + lua_rawset(L,(i-2)); + } + return 0; +} + +char * +get_something_internal (int cur_cmd, int cur_code) { + int texstr; + char *str; + int save_cur_val,save_cur_val_level; + save_cur_val = cur_val; + save_cur_val_level = cur_val_level; + zscan_something_simple(cur_cmd,cur_code); + texstr = the_scanned_result(); + cur_val = save_cur_val; + cur_val_level = save_cur_val_level; + str = makecstring(texstr); + flush_str(texstr); + return str; +} + +char * +get_convert (int cur_code) { + int texstr; + char *str = NULL; + texstr = the_convert_string(cur_code); + if (texstr) { + str = makecstring(texstr); + flush_str(texstr); + } + return str; +} + + +int +gettex (lua_State *L) { + char *st; + int i,texstr; + size_t k; + char *str; + int cur_cs, cur_cmd, cur_code; + i = lua_gettop(L); + if (lua_isstring(L,i)) { + st = (char *)lua_tolstring(L,i, &k); + texstr = maketexlstring(st,k); + cur_cs = zprim_lookup(texstr); + flush_str(texstr); + if (cur_cs) { + cur_cmd = zget_prim_eq_type(cur_cs); + cur_code = zget_prim_equiv(cur_cs); + if (is_convert(cur_cmd)) + str = get_convert(cur_code); + else + str = get_something_internal(cur_cmd,cur_code); + if (str) + lua_pushstring(L,str); + else + lua_pushnil(L); + return 1; + } else { + lua_rawget(L,(i-1)); + return 1; + } + } else { + lua_rawget(L,(i-1)); + return 1; + } + return 0; /* not reached */ +} + + +int +getlist (lua_State *L) { + char *str; + if (lua_isstring(L,2)) { + str = (char *)lua_tostring(L,2); + if (strcmp(str,"page_ins_head")==0) { + lua_pushnumber(L,page_ins_head); lua_nodelib_push(L); + } else if (strcmp(str,"contrib_head")==0) { + lua_pushnumber(L,contrib_head); lua_nodelib_push(L); + } else if (strcmp(str,"page_head")==0) { + lua_pushnumber(L,page_head); lua_nodelib_push(L); + } else if (strcmp(str,"temp_head")==0) { + lua_pushnumber(L,temp_head); lua_nodelib_push(L); + } else if (strcmp(str,"hold_head")==0) { + lua_pushnumber(L,hold_head); lua_nodelib_push(L); + } else if (strcmp(str,"adjust_head")==0) { + lua_pushnumber(L,adjust_head); lua_nodelib_push(L); + } else if (strcmp(str,"pre_adjust_head")==0) { + lua_pushnumber(L,pre_adjust_head); lua_nodelib_push(L); + } else if (strcmp(str,"align_head")==0) { + lua_pushnumber(L,align_head); lua_nodelib_push(L); + } else { + lua_pushnil(L); + } + } else { + lua_pushnil(L); + } + return 1; +} + +int +setlist (lua_State *L) { + return 0; +} + +#define infinity 2147483647 + +static int +do_integer_error(double m) { + char *help[] = {"I can only go up to 2147483647='17777777777=""7FFFFFFF,", + "so I'm using that number instead of yours.", + NULL } ; + tex_error("Number too big",help); + return (m>0.0 ? infinity : -infinity); +} + + +static int +tex_roundnumber (lua_State *L) { + double m = lua_tonumber(L, 1)+0.5; + if (abs(m)>(double)infinity) + lua_pushnumber(L,do_integer_error(m)); + else + lua_pushnumber(L,floor(m)); + return 1; +} + +static int +tex_scaletable (lua_State *L) { + double delta = luaL_checknumber(L, 2); + if (lua_istable(L,1)) { + lua_newtable(L); /* the new table is at index 3 */ + lua_pushnil(L); + while (lua_next(L,1)!= 0 ) { /* numeric value */ + lua_pushvalue(L,-2); + lua_insert(L,-2); + if (lua_isnumber(L,-1)) { + double m = lua_tonumber(L,-1)*delta + 0.5; + lua_pop(L,1); + if (abs(m)>(double)infinity) + lua_pushnumber(L,do_integer_error(m)); + else + lua_pushnumber(L,floor(m)); + } + lua_rawset(L,3); + } + } else if (lua_isnumber(L,1)) { + double m = lua_tonumber(L,1)*delta + 0.5; + if (abs(m)>(double)infinity) + lua_pushnumber(L,do_integer_error(m)); + else + lua_pushnumber(L,floor(m)); + } else { + lua_pushnil(L); + } + return 1; +} + +static const struct luaL_reg texlib [] = { + {"write", luacwrite}, + {"print", luacprint}, + {"sprint", luacsprint}, + {"setdimen", setdimen}, + {"getdimen", getdimen}, + {"setattribute", setattribute}, + {"getattribute", getattribute}, + {"setcount", setcount}, + {"getcount", getcount}, + {"settoks", settoks}, + {"gettoks", gettoks}, + {"setbox", setbox}, + {"getbox", getbox}, + {"setlist", setlist}, + {"getlist", getlist}, + {"setboxwd", setboxwd}, + {"getboxwd", getboxwd}, + {"setboxht", setboxht}, + {"getboxht", getboxht}, + {"setboxdp", setboxdp}, + {"getboxdp", getboxdp}, + {"round", tex_roundnumber}, + {"scale", tex_scaletable}, + {NULL, NULL} /* sentinel */ +}; + +int luaopen_tex (lua_State *L) +{ + luaL_register(L, "tex", texlib); + make_table(L,"attribute","getattribute","setattribute"); + make_table(L,"dimen","getdimen","setdimen"); + make_table(L,"count","getcount","setcount"); + make_table(L,"toks","gettoks","settoks"); + make_table(L,"box","getbox","setbox"); + make_table(L,"lists","getlist","setlist"); + make_table(L,"wd","getboxwd","setboxwd"); + make_table(L,"ht","getboxht","setboxht"); + make_table(L,"dp","getboxdp","setboxdp"); + /* make the meta entries */ + /* fetch it back */ + luaL_newmetatable(L,"tex_meta"); + lua_pushstring(L, "__index"); + lua_pushcfunction(L, gettex); + lua_settable(L, -3); + lua_pushstring(L, "__newindex"); + lua_pushcfunction(L, settex); + lua_settable(L, -3); + lua_setmetatable(L,-2); /* meta to itself */ + /* initialize the I/O stack: */ + spindles = xmalloc(sizeof(spindle)); + spindle_index = 0; + spindles[0].head = NULL; + spindles[0].tail = NULL; + spindle_size = 1; + return 1; +} + |