diff options
author | Luigi Scarso <luigi.scarso@gmail.com> | 2018-01-09 23:43:20 +0000 |
---|---|---|
committer | Luigi Scarso <luigi.scarso@gmail.com> | 2018-01-09 23:43:20 +0000 |
commit | aa5d0e8bf3515c424ba0594a2d4e06ae31da7796 (patch) | |
tree | e56fd10d89732547ddb207c1998a1ded4360382e /Build/source/texk/web2c/luatexdir/lua/lstrlibext.c | |
parent | d33684eeca435784c95c62c7981dd02f7818b263 (diff) |
Imported Luatex 1.06.3 (Lua 5.2.4)
git-svn-id: svn://tug.org/texlive/trunk@46269 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/texk/web2c/luatexdir/lua/lstrlibext.c')
-rw-r--r-- | Build/source/texk/web2c/luatexdir/lua/lstrlibext.c | 130 |
1 files changed, 130 insertions, 0 deletions
diff --git a/Build/source/texk/web2c/luatexdir/lua/lstrlibext.c b/Build/source/texk/web2c/luatexdir/lua/lstrlibext.c index 5d5c0d723ac..f7f8cbf10ea 100644 --- a/Build/source/texk/web2c/luatexdir/lua/lstrlibext.c +++ b/Build/source/texk/web2c/luatexdir/lua/lstrlibext.c @@ -359,6 +359,133 @@ static int str_bytetable (lua_State *L) { return 1; } +/* + We provide a few helpers that we derived from the lua utf8 module + and slunicode. That way we're sort of covering a decent mix. + +*/ + +#define MAXUNICODE 0x10FFFF + +/* + This is a combination of slunicode and utf8 converters but without mode + and a bit faster on the average than the utf8 one. +*/ + +static void utf8_enco (luaL_Buffer *b, unsigned c) +{ + if (c > MAXUNICODE) { + /* we silently ignore the bad character */ + return; + } + if (0x80 > c) { + luaL_addchar(b, c); + return; + } + if (0x800 > c) + luaL_addchar(b, 0xC0|(c>>6)); + else { + if (0x10000 > c) + luaL_addchar(b, 0xE0|(c>>12)); + else { + luaL_addchar(b, 0xF0|(c>>18)); + luaL_addchar(b, 0x80|(0x3F&(c>>12))); + } + luaL_addchar(b, 0x80|(0x3F&(c>>6))); + } + luaL_addchar(b, 0x80|(0x3F&c)); +} + +static int str_character (lua_State *L) { + int n = lua_gettop(L); /* number of arguments */ + int i; + luaL_Buffer b; + luaL_buffinit(L,&b); + for (i = 1; i <= n; i++) { + utf8_enco (&b, (unsigned) lua_tointeger(L, i)); + } + luaL_pushresult(&b); + return 1; +} + +/* + The utf8 codepoint function takes two arguments, being positions in the + string, while slunicode byte takes two arguments representing the number of + utf characters. The variant below always returns all codepoints. + +*/ + +static int str_utfvalue (lua_State *L) { + size_t ls; + int ind = 0; + int num = 0; + const char *s = lua_tolstring(L, 1, &ls); + while (ind<(int)ls) { + unsigned char i = (unsigned)*(s+ind); + if (i<0x80) { + lua_pushinteger(L, i); + num += 1; + ind += 1; + } else if (i>=0xF0) { + if ((ind+3)<(int)ls && ((unsigned)*(s+ind+1))>=0x80 && ((unsigned)*(s+ind+2))>=0x80 && ((unsigned)*(s+ind+3))>=0x80) { + unsigned char j = ((unsigned)*(s+ind+1))-128; + unsigned char k = ((unsigned)*(s+ind+2))-128; + unsigned char l = ((unsigned)*(s+ind+3))-128; + lua_pushinteger(L, (((((i-0xF0)*64) + j)*64) + k)*64 + l); + num += 1; + } + ind += 4; + } else if (i>=0xE0) { + if ((ind+2)<(int)ls && ((unsigned)*(s+ind+1))>=0x80 && ((unsigned)*(s+ind+2))>=0x80) { + unsigned char j = ((unsigned)*(s+ind+1))-128; + unsigned char k = ((unsigned)*(s+ind+2))-128; + lua_pushinteger(L, (((i-0xE0)*64) + j)*64 + k); + num += 1; + } + ind += 3; + } else if (i>=0xC0) { + if ((ind+1)<(int)ls && ((unsigned)*(s+ind+1))>=0x80) { + unsigned char j = ((unsigned)*(s+ind+1))-128; + lua_pushinteger(L, ((i-0xC0)*64) + j); + num += 1; + } + ind += 2; + } else { + ind += 1; + } + } + return num; +} + +/* This is a simplified version of utf8.len but without range. */ + +static int str_utflength (lua_State *L) { + size_t ls; + int ind = 0; + int num = 0; + const char *s = lua_tolstring(L, 1, &ls); + while (ind<(int)ls) { + unsigned char i = (unsigned)*(s+ind); + if (i<0x80) { + ind += 1; + } else if (i>=0xF0) { + ind += 4; + } else if (i>=0xE0) { + ind += 3; + } else if (i>=0xC0) { + ind += 2; + } else { + /* bad news, stupid recovery */ + ind += 1; + } + num += 1; + } + lua_pushinteger(L, num); + return 1; +} + +/* end of convenience inclusion */ + static const luaL_Reg strlibext[] = { {"utfvalues", str_utfvalues}, {"utfcharacters", str_utfcharacters}, @@ -368,6 +495,9 @@ static const luaL_Reg strlibext[] = { {"bytepairs", str_bytepairs}, {"bytetable", str_bytetable}, {"explode", str_split}, + {"utfcharacter", str_character}, + {"utfvalue", str_utfvalue}, + {"utflength", str_utflength}, #ifdef LuajitTeX /* luajit has dump built in */ #else |