** offset(s, n, [i]) -> indices where n-th character counting from ** position 'i' starts and ends; 0 means character at 'i'. */
| 176 | ** position 'i' starts and ends; 0 means character at 'i'. |
| 177 | */ |
| 178 | static int byteoffset (lua_State *L) { |
| 179 | size_t len; |
| 180 | const char *s = luaL_checklstring(L, 1, &len); |
| 181 | lua_Integer n = luaL_checkinteger(L, 2); |
| 182 | lua_Integer posi = (n >= 0) ? 1 : cast_st2S(len) + 1; |
| 183 | posi = u_posrelat(luaL_optinteger(L, 3, posi), len); |
| 184 | luaL_argcheck(L, 1 <= posi && --posi <= (lua_Integer)len, 3, |
| 185 | "position out of bounds"); |
| 186 | if (n == 0) { |
| 187 | /* find beginning of current byte sequence */ |
| 188 | while (posi > 0 && iscontp(s + posi)) posi--; |
| 189 | } |
| 190 | else { |
| 191 | if (iscontp(s + posi)) |
| 192 | return luaL_error(L, "initial position is a continuation byte"); |
| 193 | if (n < 0) { |
| 194 | while (n < 0 && posi > 0) { /* move back */ |
| 195 | do { /* find beginning of previous character */ |
| 196 | posi--; |
| 197 | } while (posi > 0 && iscontp(s + posi)); |
| 198 | n++; |
| 199 | } |
| 200 | } |
| 201 | else { |
| 202 | n--; /* do not move for 1st character */ |
| 203 | while (n > 0 && posi < (lua_Integer)len) { |
| 204 | do { /* find beginning of next character */ |
| 205 | posi++; |
| 206 | } while (iscontp(s + posi)); /* (cannot pass final '\0') */ |
| 207 | n--; |
| 208 | } |
| 209 | } |
| 210 | } |
| 211 | if (n != 0) { /* did not find given character? */ |
| 212 | luaL_pushfail(L); |
| 213 | return 1; |
| 214 | } |
| 215 | lua_pushinteger(L, posi + 1); /* initial position */ |
| 216 | if ((s[posi] & 0x80) != 0) { /* multi-byte character? */ |
| 217 | if (iscont(s[posi])) |
| 218 | return luaL_error(L, "initial position is a continuation byte"); |
| 219 | while (iscontp(s + posi + 1)) |
| 220 | posi++; /* skip to last continuation byte */ |
| 221 | } |
| 222 | /* else one-byte character: final position is the initial one */ |
| 223 | lua_pushinteger(L, posi + 1); /* 'posi' now is the final position */ |
| 224 | return 2; |
| 225 | } |
| 226 | |
| 227 | |
| 228 | static int iter_aux (lua_State *L, int strict) { |
nothing calls this directly
no test coverage detected