diff options
Diffstat (limited to 'source/luametatex/source/luarest/lmtstrlibext.c')
-rw-r--r-- | source/luametatex/source/luarest/lmtstrlibext.c | 69 |
1 files changed, 69 insertions, 0 deletions
diff --git a/source/luametatex/source/luarest/lmtstrlibext.c b/source/luametatex/source/luarest/lmtstrlibext.c index ffc687ff4..31dc53c86 100644 --- a/source/luametatex/source/luarest/lmtstrlibext.c +++ b/source/luametatex/source/luarest/lmtstrlibext.c @@ -777,6 +777,74 @@ static int strlib_pack_rows_columns(lua_State* L) return 1; } +/*tex + This converts a hex string to characters. Spacing is ignored and invalid characters result in + a false result. EMpty strings are okay. +*/ + +static int strlib_hextocharacters(lua_State *L) +{ + size_t ls = 0; + const char *s = lua_tolstring(L, 1, &ls); + if (ls > 0) { + luaL_Buffer b; + luaL_buffinitsize(L, &b, ls/2); + while (1) { + unsigned char first = *s++; + switch (first) { + case ' ': case '\n': case '\r': case '\t': + continue; + case '\0': + goto DONE; + default: + { + unsigned char second = *s++; + switch (second) { + case ' ': case '\n': case '\r': case '\t': + continue; + case '\0': + goto BAD; + default: + { + unsigned char chr; + if (first >= '0' && first <= '9') { + chr = 16 * (first - '0'); + } else if (first>= 'A' && first <= 'F') { + chr = 16 * (first - 'A' + 10); + } else if (first >= 'a' && first <= 'f') { + chr = 16 * (first - 'a' + 10); + } else { + goto BAD; + } + if (second >= '0' && second <= '9') { + chr += second - '0'; + } else if (second >= 'A' && second <= 'F') { + chr += second - 'A' + 10; + } else if (first >= 'a' && second <= 'f') { + chr += second - 'a' + 10; + } else { + goto BAD; + } + luaL_addchar(&b, chr); + break; + } + } + break; + } + } + } + DONE: + luaL_pushresult(&b); + return 1; + BAD: + lua_pushboolean(L, 0); + return 1; + } else { + lua_pushliteral(L, ""); + return 1; + } +} + static const luaL_Reg strlib_function_list[] = { { "characters", strlib_characters }, { "characterpairs", strlib_characterpairs }, @@ -797,6 +865,7 @@ static const luaL_Reg strlib_function_list[] = { /* { "toutf16", strlib_format_toutf16 }, */ /* untested */ { "toutf32", strlib_format_toutf32 }, { "packrowscolumns", strlib_pack_rows_columns }, + { "hextocharacters", strlib_hextocharacters }, { NULL, NULL }, }; |