aboutsummaryrefslogtreecommitdiff
path: root/lutf8lib.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2014-04-03 10:45:09 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2014-04-03 10:45:09 -0300
commit144afa4d476c8a510ea93f02dd19dc20ce5e6c16 (patch)
tree23eabaa6a5d0c141e60834d2a420078092ab68d6 /lutf8lib.c
parent007f66408db5b8c54f97909e5d5027f1454544e0 (diff)
downloadlua-144afa4d476c8a510ea93f02dd19dc20ce5e6c16.tar.gz
lua-144afa4d476c8a510ea93f02dd19dc20ce5e6c16.tar.bz2
lua-144afa4d476c8a510ea93f02dd19dc20ce5e6c16.zip
several changes in 'utf8.offset'
Diffstat (limited to 'lutf8lib.c')
-rw-r--r--lutf8lib.c49
1 files changed, 27 insertions, 22 deletions
diff --git a/lutf8lib.c b/lutf8lib.c
index 9c88f00a..f7eb676f 100644
--- a/lutf8lib.c
+++ b/lutf8lib.c
@@ -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*/
156static int byteoffset (lua_State *L) { 156static 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