diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2014-04-03 10:45:09 -0300 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2014-04-03 10:45:09 -0300 |
| commit | 144afa4d476c8a510ea93f02dd19dc20ce5e6c16 (patch) | |
| tree | 23eabaa6a5d0c141e60834d2a420078092ab68d6 | |
| parent | 007f66408db5b8c54f97909e5d5027f1454544e0 (diff) | |
| download | lua-144afa4d476c8a510ea93f02dd19dc20ce5e6c16.tar.gz lua-144afa4d476c8a510ea93f02dd19dc20ce5e6c16.tar.bz2 lua-144afa4d476c8a510ea93f02dd19dc20ce5e6c16.zip | |
several changes in 'utf8.offset'
| -rw-r--r-- | lutf8lib.c | 49 |
1 files changed, 27 insertions, 22 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lutf8lib.c,v 1.5 2014/04/01 14:39:55 roberto Exp roberto $ | 2 | ** $Id: lutf8lib.c,v 1.6 2014/04/02 17:01:22 roberto Exp roberto $ |
| 3 | ** Standard library for UTF-8 manipulation | 3 | ** Standard library for UTF-8 manipulation |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -150,41 +150,46 @@ static int utfchar (lua_State *L) { | |||
| 150 | 150 | ||
| 151 | 151 | ||
| 152 | /* | 152 | /* |
| 153 | ** offset(s, n, [i]) -> index where n-th character *after* | 153 | ** offset(s, n, [i]) -> index where n-th character counting from |
| 154 | ** position 'i' starts; 0 means character at 'i'. | 154 | ** position 'i' starts; 0 means character at 'i'. |
| 155 | */ | 155 | */ |
| 156 | static int byteoffset (lua_State *L) { | 156 | static int byteoffset (lua_State *L) { |
| 157 | size_t len; | 157 | size_t len; |
| 158 | const char *s = luaL_checklstring(L, 1, &len); | 158 | const char *s = luaL_checklstring(L, 1, &len); |
| 159 | int n = luaL_checkint(L, 2); | 159 | int n = luaL_checkint(L, 2); |
| 160 | lua_Integer posi = u_posrelat(luaL_optinteger(L, 3, 1), len) - 1; | 160 | lua_Integer posi = (n >= 0) ? 1 : len + 1; |
| 161 | luaL_argcheck(L, 0 <= posi && posi <= (lua_Integer)len, 3, | 161 | posi = u_posrelat(luaL_optinteger(L, 3, posi), len); |
| 162 | luaL_argcheck(L, 1 <= posi && --posi <= (lua_Integer)len, 3, | ||
| 162 | "position out of range"); | 163 | "position out of range"); |
| 163 | if (n == 0) { | 164 | if (n == 0) { |
| 164 | /* find beginning of current byte sequence */ | 165 | /* find beginning of current byte sequence */ |
| 165 | while (posi > 0 && iscont(s + posi)) posi--; | 166 | while (posi > 0 && iscont(s + posi)) posi--; |
| 166 | } | 167 | } |
| 167 | else if (n < 0) { | ||
| 168 | while (n < 0 && posi > 0) { /* move back */ | ||
| 169 | do { /* find beginning of previous character */ | ||
| 170 | posi--; | ||
| 171 | } while (posi > 0 && iscont(s + posi)); | ||
| 172 | n++; | ||
| 173 | } | ||
| 174 | } | ||
| 175 | else { | 168 | else { |
| 176 | n--; /* do not move for 1st character */ | 169 | if (iscont(s + posi)) |
| 177 | while (n > 0 && posi < (lua_Integer)len) { | 170 | luaL_error(L, "initial position is a continuation byte"); |
| 178 | do { /* find beginning of next character */ | 171 | if (n < 0) { |
| 179 | posi++; | 172 | while (n < 0 && posi > 0) { /* move back */ |
| 180 | } while (iscont(s + posi)); /* ('\0' is not continuation) */ | 173 | do { /* find beginning of previous character */ |
| 181 | n--; | 174 | posi--; |
| 182 | } | 175 | } while (posi > 0 && iscont(s + posi)); |
| 176 | n++; | ||
| 177 | } | ||
| 178 | } | ||
| 179 | else { | ||
| 180 | n--; /* do not move for 1st character */ | ||
| 181 | while (n > 0 && posi < (lua_Integer)len) { | ||
| 182 | do { /* find beginning of next character */ | ||
| 183 | posi++; | ||
| 184 | } while (iscont(s + posi)); /* (cannot pass final '\0') */ | ||
| 185 | n--; | ||
| 186 | } | ||
| 187 | } | ||
| 183 | } | 188 | } |
| 184 | if (n == 0) | 189 | if (n == 0) /* did it find given character? */ |
| 185 | lua_pushinteger(L, posi + 1); | 190 | lua_pushinteger(L, posi + 1); |
| 186 | else | 191 | else /* no such character */ |
| 187 | lua_pushnil(L); /* no such position */ | 192 | lua_pushnil(L); |
| 188 | return 1; | 193 | return 1; |
| 189 | } | 194 | } |
| 190 | 195 | ||
