** utf8len(s [, i [, j [, lax]]]) --> number of characters that ** start in the range [i,j], or nil + current position if 's' is not ** well formed in that interval */
| 94 | ** well formed in that interval |
| 95 | */ |
| 96 | static int utflen (lua_State *L) { |
| 97 | lua_Integer n = 0; /* counter for the number of characters */ |
| 98 | size_t len; /* string length in bytes */ |
| 99 | const char *s = luaL_checklstring(L, 1, &len); |
| 100 | lua_Integer posi = u_posrelat(luaL_optinteger(L, 2, 1), len); |
| 101 | lua_Integer posj = u_posrelat(luaL_optinteger(L, 3, -1), len); |
| 102 | int lax = lua_toboolean(L, 4); |
| 103 | luaL_argcheck(L, 1 <= posi && --posi <= (lua_Integer)len, 2, |
| 104 | "initial position out of bounds"); |
| 105 | luaL_argcheck(L, --posj < (lua_Integer)len, 3, |
| 106 | "final position out of bounds"); |
| 107 | while (posi <= posj) { |
| 108 | const char *s1 = utf8_decode(s + posi, NULL, !lax); |
| 109 | if (s1 == NULL) { /* conversion error? */ |
| 110 | luaL_pushfail(L); /* return fail ... */ |
| 111 | lua_pushinteger(L, posi + 1); /* ... and current position */ |
| 112 | return 2; |
| 113 | } |
| 114 | posi = s1 - s; |
| 115 | n++; |
| 116 | } |
| 117 | lua_pushinteger(L, n); |
| 118 | return 1; |
| 119 | } |
| 120 | |
| 121 | |
| 122 | /* |
nothing calls this directly
no test coverage detected