aboutsummaryrefslogtreecommitdiff
path: root/lutf8lib.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2014-04-02 14:01:22 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2014-04-02 14:01:22 -0300
commit3a044de5a1df82ed5d76f2c5afdf79677c92800f (patch)
treeae867901bb5aa2be8bb7bc4b81ddf653317c09d6 /lutf8lib.c
parent7d514af0bc95b75d7a162331b0e4c1fd7d20c9c7 (diff)
downloadlua-3a044de5a1df82ed5d76f2c5afdf79677c92800f.tar.gz
lua-3a044de5a1df82ed5d76f2c5afdf79677c92800f.tar.bz2
lua-3a044de5a1df82ed5d76f2c5afdf79677c92800f.zip
new implementation for 'utf8.len'
Diffstat (limited to 'lutf8lib.c')
-rw-r--r--lutf8lib.c31
1 files changed, 18 insertions, 13 deletions
diff --git a/lutf8lib.c b/lutf8lib.c
index 73e86a4a..9c88f00a 100644
--- a/lutf8lib.c
+++ b/lutf8lib.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lutf8lib.c,v 1.4 2014/03/20 19:36:02 roberto Exp roberto $ 2** $Id: lutf8lib.c,v 1.5 2014/04/01 14:39:55 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*/
@@ -61,25 +61,30 @@ static const char *utf8_decode (const char *o, int *val) {
61 61
62 62
63/* 63/*
64** utf8len(s, [i]) --> number of codepoints in 's' after 'i'; 64** utf8len(s [, i [, j]]) --> number of codepoints in 's' between 'i';
65** nil if 's' not well formed 65** nil + current position if 's' not well formed
66*/ 66*/
67static int utflen (lua_State *L) { 67static int utflen (lua_State *L) {
68 int n = 0; 68 int n = 0;
69 const char *ends;
70 size_t len; 69 size_t len;
71 const char *s = luaL_checklstring(L, 1, &len); 70 const char *s = luaL_checklstring(L, 1, &len);
72 lua_Integer posi = u_posrelat(luaL_optinteger(L, 2, 1), 1); 71 lua_Integer posi = u_posrelat(luaL_optinteger(L, 2, 1), len);
73 luaL_argcheck(L, 1 <= posi && posi <= (lua_Integer)len, 1, 72 lua_Integer posj = u_posrelat(luaL_optinteger(L, 3, -1), len);
73 luaL_argcheck(L, 1 <= posi && --posi <= (lua_Integer)len, 2,
74 "initial position out of string"); 74 "initial position out of string");
75 ends = s + len; 75 luaL_argcheck(L, --posj < (lua_Integer)len, 3,
76 s += posi - 1; 76 "final position out of string");
77 while (s < ends && (s = utf8_decode(s, NULL)) != NULL) 77 while (posi <= posj) {
78 const char *s1 = utf8_decode(s + posi, NULL);
79 if (s1 == NULL) { /* conversion error? */
80 lua_pushnil(L); /* return nil ... */
81 lua_pushinteger(L, posi + 1); /* ... and current position */
82 return 2;
83 }
84 posi = s1 - s;
78 n++; 85 n++;
79 if (s == ends) 86 }
80 lua_pushinteger(L, n); 87 lua_pushinteger(L, n);
81 else
82 lua_pushnil(L);
83 return 1; 88 return 1;
84} 89}
85 90