aboutsummaryrefslogtreecommitdiff
path: root/src/lua/lutf8lib.c
diff options
context:
space:
mode:
authorLi Jin <dragon-fly@qq.com>2020-06-22 16:50:40 +0800
committerLi Jin <dragon-fly@qq.com>2020-06-22 16:50:40 +0800
commitcd2b60b101a398cb9356d746364e70eaed1860f1 (patch)
treea1fe71b76faabc4883f16905a94164ce5c23e692 /src/lua/lutf8lib.c
parent88c1052e700f38cf3d8ad82d469da4c487760b7e (diff)
downloadyuescript-cd2b60b101a398cb9356d746364e70eaed1860f1.tar.gz
yuescript-cd2b60b101a398cb9356d746364e70eaed1860f1.tar.bz2
yuescript-cd2b60b101a398cb9356d746364e70eaed1860f1.zip
add support for local variable declared with attribute 'close' and 'const' for Lua 5.4.
Diffstat (limited to '')
-rw-r--r--src/lua/lutf8lib.c (renamed from src/lua-5.3/lutf8lib.c)117
1 files changed, 75 insertions, 42 deletions
diff --git a/src/lua-5.3/lutf8lib.c b/src/lua/lutf8lib.c
index 10bd238..901d985 100644
--- a/src/lua-5.3/lutf8lib.c
+++ b/src/lua/lutf8lib.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lutf8lib.c,v 1.16.1.1 2017/04/19 17:29:57 roberto Exp $ 2** $Id: lutf8lib.c $
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*/
@@ -20,7 +20,20 @@
20#include "lauxlib.h" 20#include "lauxlib.h"
21#include "lualib.h" 21#include "lualib.h"
22 22
23#define MAXUNICODE 0x10FFFF 23
24#define MAXUNICODE 0x10FFFFu
25
26#define MAXUTF 0x7FFFFFFFu
27
28/*
29** Integer type for decoded UTF-8 values; MAXUTF needs 31 bits.
30*/
31#if (UINT_MAX >> 30) >= 1
32typedef unsigned int utfint;
33#else
34typedef unsigned long utfint;
35#endif
36
24 37
25#define iscont(p) ((*(p) & 0xC0) == 0x80) 38#define iscont(p) ((*(p) & 0xC0) == 0x80)
26 39
@@ -35,53 +48,62 @@ static lua_Integer u_posrelat (lua_Integer pos, size_t len) {
35 48
36 49
37/* 50/*
38** Decode one UTF-8 sequence, returning NULL if byte sequence is invalid. 51** Decode one UTF-8 sequence, returning NULL if byte sequence is
52** invalid. The array 'limits' stores the minimum value for each
53** sequence length, to check for overlong representations. Its first
54** entry forces an error for non-ascii bytes with no continuation
55** bytes (count == 0).
39*/ 56*/
40static const char *utf8_decode (const char *o, int *val) { 57static const char *utf8_decode (const char *s, utfint *val, int strict) {
41 static const unsigned int limits[] = {0xFF, 0x7F, 0x7FF, 0xFFFF}; 58 static const utfint limits[] =
42 const unsigned char *s = (const unsigned char *)o; 59 {~(utfint)0, 0x80, 0x800, 0x10000u, 0x200000u, 0x4000000u};
43 unsigned int c = s[0]; 60 unsigned int c = (unsigned char)s[0];
44 unsigned int res = 0; /* final result */ 61 utfint res = 0; /* final result */
45 if (c < 0x80) /* ascii? */ 62 if (c < 0x80) /* ascii? */
46 res = c; 63 res = c;
47 else { 64 else {
48 int count = 0; /* to count number of continuation bytes */ 65 int count = 0; /* to count number of continuation bytes */
49 while (c & 0x40) { /* still have continuation bytes? */ 66 for (; c & 0x40; c <<= 1) { /* while it needs continuation bytes... */
50 int cc = s[++count]; /* read next byte */ 67 unsigned int cc = (unsigned char)s[++count]; /* read next byte */
51 if ((cc & 0xC0) != 0x80) /* not a continuation byte? */ 68 if ((cc & 0xC0) != 0x80) /* not a continuation byte? */
52 return NULL; /* invalid byte sequence */ 69 return NULL; /* invalid byte sequence */
53 res = (res << 6) | (cc & 0x3F); /* add lower 6 bits from cont. byte */ 70 res = (res << 6) | (cc & 0x3F); /* add lower 6 bits from cont. byte */
54 c <<= 1; /* to test next bit */
55 } 71 }
56 res |= ((c & 0x7F) << (count * 5)); /* add first byte */ 72 res |= ((utfint)(c & 0x7F) << (count * 5)); /* add first byte */
57 if (count > 3 || res > MAXUNICODE || res <= limits[count]) 73 if (count > 5 || res > MAXUTF || res < limits[count])
58 return NULL; /* invalid byte sequence */ 74 return NULL; /* invalid byte sequence */
59 s += count; /* skip continuation bytes read */ 75 s += count; /* skip continuation bytes read */
60 } 76 }
77 if (strict) {
78 /* check for invalid code points; too large or surrogates */
79 if (res > MAXUNICODE || (0xD800u <= res && res <= 0xDFFFu))
80 return NULL;
81 }
61 if (val) *val = res; 82 if (val) *val = res;
62 return (const char *)s + 1; /* +1 to include first byte */ 83 return s + 1; /* +1 to include first byte */
63} 84}
64 85
65 86
66/* 87/*
67** utf8len(s [, i [, j]]) --> number of characters that start in the 88** utf8len(s [, i [, j [, lax]]]) --> number of characters that
68** range [i,j], or nil + current position if 's' is not well formed in 89** start in the range [i,j], or nil + current position if 's' is not
69** that interval 90** well formed in that interval
70*/ 91*/
71static int utflen (lua_State *L) { 92static int utflen (lua_State *L) {
72 int n = 0; 93 lua_Integer n = 0; /* counter for the number of characters */
73 size_t len; 94 size_t len; /* string length in bytes */
74 const char *s = luaL_checklstring(L, 1, &len); 95 const char *s = luaL_checklstring(L, 1, &len);
75 lua_Integer posi = u_posrelat(luaL_optinteger(L, 2, 1), len); 96 lua_Integer posi = u_posrelat(luaL_optinteger(L, 2, 1), len);
76 lua_Integer posj = u_posrelat(luaL_optinteger(L, 3, -1), len); 97 lua_Integer posj = u_posrelat(luaL_optinteger(L, 3, -1), len);
98 int lax = lua_toboolean(L, 4);
77 luaL_argcheck(L, 1 <= posi && --posi <= (lua_Integer)len, 2, 99 luaL_argcheck(L, 1 <= posi && --posi <= (lua_Integer)len, 2,
78 "initial position out of string"); 100 "initial position out of bounds");
79 luaL_argcheck(L, --posj < (lua_Integer)len, 3, 101 luaL_argcheck(L, --posj < (lua_Integer)len, 3,
80 "final position out of string"); 102 "final position out of bounds");
81 while (posi <= posj) { 103 while (posi <= posj) {
82 const char *s1 = utf8_decode(s + posi, NULL); 104 const char *s1 = utf8_decode(s + posi, NULL, !lax);
83 if (s1 == NULL) { /* conversion error? */ 105 if (s1 == NULL) { /* conversion error? */
84 lua_pushnil(L); /* return nil ... */ 106 luaL_pushfail(L); /* return fail ... */
85 lua_pushinteger(L, posi + 1); /* ... and current position */ 107 lua_pushinteger(L, posi + 1); /* ... and current position */
86 return 2; 108 return 2;
87 } 109 }
@@ -94,28 +116,29 @@ static int utflen (lua_State *L) {
94 116
95 117
96/* 118/*
97** codepoint(s, [i, [j]]) -> returns codepoints for all characters 119** codepoint(s, [i, [j [, lax]]]) -> returns codepoints for all
98** that start in the range [i,j] 120** characters that start in the range [i,j]
99*/ 121*/
100static int codepoint (lua_State *L) { 122static int codepoint (lua_State *L) {
101 size_t len; 123 size_t len;
102 const char *s = luaL_checklstring(L, 1, &len); 124 const char *s = luaL_checklstring(L, 1, &len);
103 lua_Integer posi = u_posrelat(luaL_optinteger(L, 2, 1), len); 125 lua_Integer posi = u_posrelat(luaL_optinteger(L, 2, 1), len);
104 lua_Integer pose = u_posrelat(luaL_optinteger(L, 3, posi), len); 126 lua_Integer pose = u_posrelat(luaL_optinteger(L, 3, posi), len);
127 int lax = lua_toboolean(L, 4);
105 int n; 128 int n;
106 const char *se; 129 const char *se;
107 luaL_argcheck(L, posi >= 1, 2, "out of range"); 130 luaL_argcheck(L, posi >= 1, 2, "out of bounds");
108 luaL_argcheck(L, pose <= (lua_Integer)len, 3, "out of range"); 131 luaL_argcheck(L, pose <= (lua_Integer)len, 3, "out of bounds");
109 if (posi > pose) return 0; /* empty interval; return no values */ 132 if (posi > pose) return 0; /* empty interval; return no values */
110 if (pose - posi >= INT_MAX) /* (lua_Integer -> int) overflow? */ 133 if (pose - posi >= INT_MAX) /* (lua_Integer -> int) overflow? */
111 return luaL_error(L, "string slice too long"); 134 return luaL_error(L, "string slice too long");
112 n = (int)(pose - posi) + 1; 135 n = (int)(pose - posi) + 1; /* upper bound for number of returns */
113 luaL_checkstack(L, n, "string slice too long"); 136 luaL_checkstack(L, n, "string slice too long");
114 n = 0; 137 n = 0; /* count the number of returns */
115 se = s + pose; 138 se = s + pose; /* string end */
116 for (s += posi - 1; s < se;) { 139 for (s += posi - 1; s < se;) {
117 int code; 140 utfint code;
118 s = utf8_decode(s, &code); 141 s = utf8_decode(s, &code, !lax);
119 if (s == NULL) 142 if (s == NULL)
120 return luaL_error(L, "invalid UTF-8 code"); 143 return luaL_error(L, "invalid UTF-8 code");
121 lua_pushinteger(L, code); 144 lua_pushinteger(L, code);
@@ -126,8 +149,8 @@ static int codepoint (lua_State *L) {
126 149
127 150
128static void pushutfchar (lua_State *L, int arg) { 151static void pushutfchar (lua_State *L, int arg) {
129 lua_Integer code = luaL_checkinteger(L, arg); 152 lua_Unsigned code = (lua_Unsigned)luaL_checkinteger(L, arg);
130 luaL_argcheck(L, 0 <= code && code <= MAXUNICODE, arg, "value out of range"); 153 luaL_argcheck(L, code <= MAXUTF, arg, "value out of range");
131 lua_pushfstring(L, "%U", (long)code); 154 lua_pushfstring(L, "%U", (long)code);
132} 155}
133 156
@@ -164,7 +187,7 @@ static int byteoffset (lua_State *L) {
164 lua_Integer posi = (n >= 0) ? 1 : len + 1; 187 lua_Integer posi = (n >= 0) ? 1 : len + 1;
165 posi = u_posrelat(luaL_optinteger(L, 3, posi), len); 188 posi = u_posrelat(luaL_optinteger(L, 3, posi), len);
166 luaL_argcheck(L, 1 <= posi && --posi <= (lua_Integer)len, 3, 189 luaL_argcheck(L, 1 <= posi && --posi <= (lua_Integer)len, 3,
167 "position out of range"); 190 "position out of bounds");
168 if (n == 0) { 191 if (n == 0) {
169 /* find beginning of current byte sequence */ 192 /* find beginning of current byte sequence */
170 while (posi > 0 && iscont(s + posi)) posi--; 193 while (posi > 0 && iscont(s + posi)) posi--;
@@ -193,12 +216,12 @@ static int byteoffset (lua_State *L) {
193 if (n == 0) /* did it find given character? */ 216 if (n == 0) /* did it find given character? */
194 lua_pushinteger(L, posi + 1); 217 lua_pushinteger(L, posi + 1);
195 else /* no such character */ 218 else /* no such character */
196 lua_pushnil(L); 219 luaL_pushfail(L);
197 return 1; 220 return 1;
198} 221}
199 222
200 223
201static int iter_aux (lua_State *L) { 224static int iter_aux (lua_State *L, int strict) {
202 size_t len; 225 size_t len;
203 const char *s = luaL_checklstring(L, 1, &len); 226 const char *s = luaL_checklstring(L, 1, &len);
204 lua_Integer n = lua_tointeger(L, 2) - 1; 227 lua_Integer n = lua_tointeger(L, 2) - 1;
@@ -211,9 +234,9 @@ static int iter_aux (lua_State *L) {
211 if (n >= (lua_Integer)len) 234 if (n >= (lua_Integer)len)
212 return 0; /* no more codepoints */ 235 return 0; /* no more codepoints */
213 else { 236 else {
214 int code; 237 utfint code;
215 const char *next = utf8_decode(s + n, &code); 238 const char *next = utf8_decode(s + n, &code, strict);
216 if (next == NULL || iscont(next)) 239 if (next == NULL)
217 return luaL_error(L, "invalid UTF-8 code"); 240 return luaL_error(L, "invalid UTF-8 code");
218 lua_pushinteger(L, n + 1); 241 lua_pushinteger(L, n + 1);
219 lua_pushinteger(L, code); 242 lua_pushinteger(L, code);
@@ -222,9 +245,19 @@ static int iter_aux (lua_State *L) {
222} 245}
223 246
224 247
248static int iter_auxstrict (lua_State *L) {
249 return iter_aux(L, 1);
250}
251
252static int iter_auxlax (lua_State *L) {
253 return iter_aux(L, 0);
254}
255
256
225static int iter_codes (lua_State *L) { 257static int iter_codes (lua_State *L) {
258 int lax = lua_toboolean(L, 2);
226 luaL_checkstring(L, 1); 259 luaL_checkstring(L, 1);
227 lua_pushcfunction(L, iter_aux); 260 lua_pushcfunction(L, lax ? iter_auxlax : iter_auxstrict);
228 lua_pushvalue(L, 1); 261 lua_pushvalue(L, 1);
229 lua_pushinteger(L, 0); 262 lua_pushinteger(L, 0);
230 return 3; 263 return 3;
@@ -232,7 +265,7 @@ static int iter_codes (lua_State *L) {
232 265
233 266
234/* pattern to match a single UTF-8 character */ 267/* pattern to match a single UTF-8 character */
235#define UTF8PATT "[\0-\x7F\xC2-\xF4][\x80-\xBF]*" 268#define UTF8PATT "[\0-\x7F\xC2-\xFD][\x80-\xBF]*"
236 269
237 270
238static const luaL_Reg funcs[] = { 271static const luaL_Reg funcs[] = {