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 /lutf8lib.c | |
parent | 007f66408db5b8c54f97909e5d5027f1454544e0 (diff) | |
download | lua-144afa4d476c8a510ea93f02dd19dc20ce5e6c16.tar.gz lua-144afa4d476c8a510ea93f02dd19dc20ce5e6c16.tar.bz2 lua-144afa4d476c8a510ea93f02dd19dc20ce5e6c16.zip |
several changes in 'utf8.offset'
Diffstat (limited to 'lutf8lib.c')
-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 | ||