** codepoint(s, [i, [j [, lax]]]) -> returns codepoints for all ** characters that start in the range [i,j] */
| 120 | ** characters that start in the range [i,j] |
| 121 | */ |
| 122 | static int codepoint (lua_State *L) { |
| 123 | size_t len; |
| 124 | const char *s = luaL_checklstring(L, 1, &len); |
| 125 | lua_Integer posi = u_posrelat(luaL_optinteger(L, 2, 1), len); |
| 126 | lua_Integer pose = u_posrelat(luaL_optinteger(L, 3, posi), len); |
| 127 | int lax = lua_toboolean(L, 4); |
| 128 | int n; |
| 129 | const char *se; |
| 130 | luaL_argcheck(L, posi >= 1, 2, "out of range"); |
| 131 | luaL_argcheck(L, pose <= (lua_Integer)len, 3, "out of range"); |
| 132 | if (posi > pose) return 0; /* empty interval; return no values */ |
| 133 | if (pose - posi >= INT_MAX) /* (lua_Integer -> int) overflow? */ |
| 134 | return luaL_error(L, "string slice too long"); |
| 135 | n = (int)(pose - posi) + 1; /* upper bound for number of returns */ |
| 136 | luaL_checkstack(L, n, "string slice too long"); |
| 137 | n = 0; /* count the number of returns */ |
| 138 | se = s + pose; /* string end */ |
| 139 | for (s += posi - 1; s < se;) { |
| 140 | utfint code; |
| 141 | s = utf8_decode(s, &code, !lax); |
| 142 | if (s == NULL) |
| 143 | return luaL_error(L, "invalid UTF-8 code"); |
| 144 | lua_pushinteger(L, code); |
| 145 | n++; |
| 146 | } |
| 147 | return n; |
| 148 | } |
| 149 | |
| 150 | |
| 151 | static void pushutfchar (lua_State *L, int arg) { |
nothing calls this directly
no test coverage detected