diff options
author | Peter Breitenlohner <peb@mppmu.mpg.de> | 2014-02-06 11:04:14 +0000 |
---|---|---|
committer | Peter Breitenlohner <peb@mppmu.mpg.de> | 2014-02-06 11:04:14 +0000 |
commit | ad714058c45d0dd9e1f1417d3af804229b93b6f9 (patch) | |
tree | 6bb4f268b2b3537df995f58374551da92463fe68 /Build/source/texk/web2c/luatexdir/lua/lstrlibextjit.c | |
parent | 4169934ceb43a6b413b4280552bcd309333b469a (diff) |
LuaJITTeX
git-svn-id: svn://tug.org/texlive/trunk@32878 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/texk/web2c/luatexdir/lua/lstrlibextjit.c')
-rw-r--r-- | Build/source/texk/web2c/luatexdir/lua/lstrlibextjit.c | 395 |
1 files changed, 395 insertions, 0 deletions
diff --git a/Build/source/texk/web2c/luatexdir/lua/lstrlibextjit.c b/Build/source/texk/web2c/luatexdir/lua/lstrlibextjit.c new file mode 100644 index 00000000000..511bd821df9 --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/lua/lstrlibextjit.c @@ -0,0 +1,395 @@ +/* lstrlibext.c for luajitex + + Copyright 2013 Luigi Scarso + + Code from lstrlibext.c for LuaTeX + Original version copyright 2012 Taco Hoekwater <taco@luatex.org> + + This file is part of LuajitTeX. + + LuajitTeX 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. + + LuajitTeX 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 <stdio.h> + +#define LUA_CORE + +#include "lua.h" +#include "lauxlib.h" +#include "lualib.h" + + + + +/*#include "lua51/lj_obj.h"*/ +/*#include "lua51/lj_gc.h"*/ +/*#include "lua51/lj_err.h"*/ +/*#include "lua51/lj_str.h"*/ +/*#include "lua51/lj_tab.h"*/ +/*#include "lua51/lj_meta.h"*/ +/*#include "lua51/lj_state.h"*/ +/*#include "lua51/lj_ff.h" */ +/*#include "lua51/lj_bcdump.h"*/ +/*#include "lua51/lj_char.h"*/ +/*#include "lua51/lj_lib.h"*/ + + + +static int bytepairs_aux (lua_State *L) { + size_t ls; + unsigned char i; + const char *s = lua_tolstring(L, lua_upvalueindex(1), &ls); + int ind = lua_tointeger(L, lua_upvalueindex(2)); + if (ind<(int)ls) { + if (ind+1<(int)ls) { + lua_pushinteger(L, (ind+2)); /* iterator */ + } else { + lua_pushinteger(L, (ind+1)); /* iterator */ + } + lua_replace(L, lua_upvalueindex(2)); + i = (unsigned char)*(s+ind); + lua_pushinteger(L, i); /* byte one */ + if (ind+1<(int)ls) { + i = (unsigned char)*(s+ind+1); + lua_pushinteger(L, i); /* byte two */ + } else { + lua_pushnil(L); /* odd string length */ + } + return 2; + } + return 0; /* string ended */ +} + + +static int str_bytepairs (lua_State *L) { + luaL_checkstring(L, 1); + lua_settop(L, 1); + lua_pushinteger(L, 0); + lua_pushcclosure(L, bytepairs_aux, 2); + return 1; +} + + +static int bytes_aux (lua_State *L) { + size_t ls; + unsigned char i; + const char *s = lua_tolstring(L, lua_upvalueindex(1), &ls); + int ind = lua_tointeger(L, lua_upvalueindex(2)); + if (ind<(int)ls) { + lua_pushinteger(L, (ind+1)); /* iterator */ + lua_replace(L, lua_upvalueindex(2)); + i = (unsigned char)*(s+ind); + lua_pushinteger(L, i); /* byte */ + return 1; + } + return 0; /* string ended */ +} + + +static int str_bytes (lua_State *L) { + luaL_checkstring(L, 1); + lua_settop(L, 1); + lua_pushinteger(L, 0); + lua_pushcclosure(L, bytes_aux, 2); + return 1; +} + + +static int utf_failed(lua_State *L, int new_ind) { + static char fffd [3] = {0xEF,0xBF,0xBD}; + lua_pushinteger(L, new_ind); /* iterator */ + lua_replace(L, lua_upvalueindex(2)); + lua_pushlstring(L, fffd, 3); + return 1; +} + + +static int utfcharacters_aux (lua_State *L) { + static const unsigned char mask[4] = {0x80,0xE0,0xF0,0xF8}; + static const unsigned char mequ[4] = {0x00,0xC0,0xE0,0xF0}; + size_t ls; + unsigned char c; + int j; + const char *s = lua_tolstring(L, lua_upvalueindex(1), &ls); + int ind = lua_tointeger(L, lua_upvalueindex(2)); + if (ind>=(int)ls) return 0; /* end of string */ + c = (unsigned) s[ind]; + for (j=0;j<4;j++) { + if ((c&mask[j])==mequ[j]) { + int k; + if (ind+1+j>(int)ls) return utf_failed(L,ls); /* will not fit */ + for (k=1; k<=j; k++) { + c = (unsigned) s[ind+k]; + if ((c&0xC0)!=0x80) return utf_failed(L,ind+k); /* bad follow */ + } + lua_pushinteger(L, ind+1+j); /* iterator */ + lua_replace(L, lua_upvalueindex(2)); + lua_pushlstring(L, s+ind, 1+j); + return 1; + } + } + return utf_failed(L,ind+1); /* we found a follow byte! */ +} + + +static int str_utfcharacters (lua_State *L) { + luaL_checkstring(L, 1); + lua_settop(L, 1); + lua_pushinteger(L, 0); + lua_pushcclosure(L, utfcharacters_aux, 2); + return 1; +} + + + +static int utfvalues_aux (lua_State *L) { + size_t ls; + unsigned char i = 0; + unsigned char j = 0; + unsigned char k = 0; + unsigned char l = 0; + unsigned int v = 0xFFFD; + int numbytes = 1; + const char *s = lua_tolstring(L, lua_upvalueindex(1), &ls); + int ind = lua_tointeger(L, lua_upvalueindex(2)); + + if (ind<(int)ls) { + i = *(s+ind); + if (i<0x80) { + v = i; + } else if (i>=0xF0) { + if ((ind+3)<(int)ls && ((unsigned)*(s+ind+1))>=0x80 + && ((unsigned)*(s+ind+2))>=0x80 && ((unsigned)*(s+ind+3))>=0x80) { + numbytes = 4; + j = ((unsigned)*(s+ind+1))-128; + k = ((unsigned)*(s+ind+2))-128; + l = ((unsigned)*(s+ind+3))-128; + v = (((((i-0xF0)*64) + j)*64) + k)*64 + l; + } + } else if (i>=0xE0) { + if ((ind+2)<(int)ls && ((unsigned)*(s+ind+1))>=0x80 && ((unsigned)*(s+ind+2))>=0x80) { + numbytes = 3; + j = ((unsigned)*(s+ind+1))-128; + k = ((unsigned)*(s+ind+2))-128; + v = (((i-0xE0)*64) + j)*64 + k; + } + + } else if (i>=0xC0) { + if ((ind+1)<(int)ls && ((unsigned)*(s+ind+1))>=0x80) { + numbytes = 2; + j = ((unsigned)*(s+ind+1))-128; + v = ((i-0xC0)*64) + j; + } + } + lua_pushinteger(L, (ind+numbytes)); /* iterator */ + lua_replace(L, lua_upvalueindex(2)); + lua_pushinteger(L, v); + return 1; + } + return 0; /* string ended */ +} + + +static int str_utfvalues (lua_State *L) { + luaL_checkstring(L, 1); + lua_settop(L, 1); + lua_pushinteger(L, 0); + lua_pushcclosure(L, utfvalues_aux, 2); + return 1; +} + + +static int characterpairs_aux (lua_State *L) { + size_t ls; + char b[2]; + const char *s = lua_tolstring(L, lua_upvalueindex(1), &ls); + int ind = lua_tointeger(L, lua_upvalueindex(2)); + if (ind<(int)ls) { + if (ind+1<(int)ls) { + lua_pushinteger(L, (ind+2)); /* iterator */ + } else { + lua_pushinteger(L, (ind+1)); /* iterator */ + } + lua_replace(L, lua_upvalueindex(2)); + b[0] = *(s+ind); b[1] = 0; + lua_pushlstring(L, b, 1); + if (ind+1<(int)ls) { + b[0] = *(s+ind+1); + lua_pushlstring(L, b, 1); + } else { + lua_pushlstring(L, b+1, 0); + } + return 2; + } + return 0; /* string ended */ +} + + +static int str_characterpairs (lua_State *L) { + luaL_checkstring(L, 1); + lua_settop(L, 1); + lua_pushinteger(L, 0); + lua_pushcclosure(L, characterpairs_aux, 2); + return 1; +} + + +static int characters_aux (lua_State *L) { + size_t ls; + char b[2]; + const char *s = lua_tolstring(L, lua_upvalueindex(1), &ls); + int ind = lua_tointeger(L, lua_upvalueindex(2)); + if (ind<(int)ls) { + lua_pushinteger(L, (ind+1)); /* iterator */ + lua_replace(L, lua_upvalueindex(2)); + b[0] = *(s+ind); b[1] = 0; + lua_pushlstring(L, b, 1); + return 1; + } + return 0; /* string ended */ +} + + +static int str_characters (lua_State *L) { + luaL_checkstring(L, 1); + lua_settop(L, 1); + lua_pushinteger(L, 0); + lua_pushcclosure(L, characters_aux, 2); + return 1; +} + +static int str_split (lua_State *L) { + size_t l; + size_t i; + int n; + char *q, *p, *orig; + int mult = 0; + const char *s = luaL_checklstring(L, 1, &l); + const char *joiner = luaL_optstring(L, 2, " +"); + lua_newtable(L); + if (l == 0) { + lua_pushvalue(L,1); + lua_rawseti(L,-2,1); + return 1; + } + orig = p = malloc(l+1); + if (p==NULL) { + fprintf(stderr, "fatal: memory exhausted (malloc of %u bytes).\n",(int)(l+1)); + exit(EXIT_FAILURE); + } + strcpy(p,s); + n = 1; + q = p; + + if (*joiner == 0) { + for (i=0;i<l;i++) { + lua_pushlstring(L,q,1); q++; + lua_rawseti(L,-2,n); n++; + } + free(orig); + return 1; + } + if (*(joiner+1) == '+') { + mult = 1; + while(*p==*joiner) { + p++; + l--; + } + q = p; + } + for (i=0;i<l;i++) { + if (*(p+i)==*joiner) { + *(p+i) = 0; + lua_pushlstring(L,q,((p+i)-q)); + lua_rawseti(L,-2,n); n++; + if (mult) { + while(*(p+i+1)==*joiner) { + i++; + } + } + q = p+i+1; + } + } + if (mult && q==(p+l)) { + free(orig); + return 1; + } + if(q<=(p+l)) { + lua_pushlstring(L,q,strlen(q)); + lua_rawseti(L,-2,n); + } + free(orig); + return 1; +} + + +static const luaL_Reg strlibext[] = { + {"utfvalues", str_utfvalues}, + {"utfcharacters", str_utfcharacters}, + {"characters", str_characters}, + {"characterpairs", str_characterpairs}, + {"bytes", str_bytes}, + {"bytepairs", str_bytepairs}, + {"explode", str_split}, + /* {"dump", str_dump} already in luajit */ + {NULL, NULL} +}; + + + + +/* ------------------------------------------------------------------------ */ + +/* lj_libdef.h is generated by buildvm, it's not available on source */ +/* #include "lua51/lj_libdef.h" */ + +/* LUALIB_API int luaopen_string(lua_State *L) */ +/* { */ +/* GCtab *mt; */ +/* global_State *g; */ +/* LJ_LIB_REG(L, LUA_STRLIBNAME, string); */ +/* luaL_register(L, LUA_STRLIBNAME, strlib); */ +/* //LJ_LIB_REG(L, LUA_STRLIBNAME, strlib); */ +/* #if defined(LUA_COMPAT_GFIND) && !LJ_52 */ +/* lua_getfield(L, -1, "gmatch"); */ +/* lua_setfield(L, -2, "gfind"); */ +/* #endif */ +/* mt = lj_tab_new(L, 0, 1); */ +/* /\* NOBARRIER: basemt is a GC root. *\/ */ +/* g = G(L); */ +/* setgcref(basemt_it(g, LJ_TSTR), obj2gco(mt)); */ +/* settabV(L, lj_tab_setstr(L, mt, mmname_str(g, MM_index)), tabV(L->top-1)); */ +/* mt->nomm = (uint8_t)(~(1u<<MM_index)); */ +/* return 1; */ +/* } */ + +/* void open_strlibext(lua_State *L) */ +/* { */ +/* int v; */ +/* v = luaopen_string(L); */ +/* } */ + + +void open_strlibext(lua_State * L) +{ + const luaL_Reg *lib; + lua_getglobal(L, "string"); + for (lib=strlibext;lib->name;lib++) { + lua_pushcfunction(L, lib->func); + lua_setfield(L, -2, lib->name); + } + lua_pop(L,1); +} + |