diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 1998-03-06 13:54:42 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 1998-03-06 13:54:42 -0300 |
commit | 88a2023c3285c4514519158fba90e644fc6ffca3 (patch) | |
tree | da6611257545c486ff856dd48d66d94e056f3d66 /lstrlib.c | |
parent | 5ef1989c4b05aff8362a7ea6ba62aad76d4a040d (diff) | |
download | lua-88a2023c3285c4514519158fba90e644fc6ffca3.tar.gz lua-88a2023c3285c4514519158fba90e644fc6ffca3.tar.bz2 lua-88a2023c3285c4514519158fba90e644fc6ffca3.zip |
support for strings with '\0'
Diffstat (limited to 'lstrlib.c')
-rw-r--r-- | lstrlib.c | 98 |
1 files changed, 49 insertions, 49 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lstrlib.c,v 1.7 1998/01/09 14:57:43 roberto Exp roberto $ | 2 | ** $Id: lstrlib.c,v 1.8 1998/01/27 19:11:36 roberto Exp roberto $ |
3 | ** Standard library for strings and pattern-matching | 3 | ** Standard library for strings and pattern-matching |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -19,83 +19,86 @@ | |||
19 | static void addnchar (char *s, int n) | 19 | static void addnchar (char *s, int n) |
20 | { | 20 | { |
21 | char *b = luaL_openspace(n); | 21 | char *b = luaL_openspace(n); |
22 | strncpy(b, s, n); | 22 | memcpy(b, s, n); |
23 | luaL_addsize(n); | 23 | luaL_addsize(n); |
24 | } | 24 | } |
25 | 25 | ||
26 | 26 | ||
27 | static void addstr (char *s) | 27 | static void str_len (void) |
28 | { | 28 | { |
29 | addnchar(s, strlen(s)); | 29 | long l; |
30 | luaL_check_lstr(1, &l); | ||
31 | lua_pushnumber(l); | ||
30 | } | 32 | } |
31 | 33 | ||
32 | 34 | ||
33 | static void str_len (void) | 35 | static void closeandpush (void) |
34 | { | 36 | { |
35 | lua_pushnumber(strlen(luaL_check_string(1))); | 37 | lua_pushlstr(luaL_buffer(), luaL_getsize()); |
36 | } | 38 | } |
37 | 39 | ||
38 | 40 | ||
39 | static void closeandpush (void) | 41 | static long posrelat (long pos, long len) |
40 | { | 42 | { |
41 | luaL_addchar(0); | 43 | /* relative string position: negative means back from end */ |
42 | lua_pushstring(luaL_buffer()); | 44 | return (pos>=0) ? pos : len+pos+1; |
43 | } | 45 | } |
44 | 46 | ||
45 | 47 | ||
46 | static void str_sub (void) | 48 | static void str_sub (void) |
47 | { | 49 | { |
48 | char *s = luaL_check_string(1); | 50 | long l; |
49 | long l = strlen(s); | 51 | char *s = luaL_check_lstr(1, &l); |
50 | long start = (long)luaL_check_number(2); | 52 | long start = posrelat(luaL_check_number(2), l); |
51 | long end = (long)luaL_opt_number(3, -1); | 53 | long end = posrelat(luaL_opt_number(3, -1), l); |
52 | if (start < 0) start = l+start+1; | 54 | if (1 <= start && start <= end && end <= l) |
53 | if (end < 0) end = l+end+1; | 55 | lua_pushlstr(s+start-1, end-start+1); |
54 | if (1 <= start && start <= end && end <= l) { | ||
55 | luaL_resetbuffer(); | ||
56 | addnchar(s+start-1, end-start+1); | ||
57 | closeandpush(); | ||
58 | } | ||
59 | else lua_pushstring(""); | 56 | else lua_pushstring(""); |
60 | } | 57 | } |
61 | 58 | ||
62 | 59 | ||
63 | static void str_lower (void) | 60 | static void str_lower (void) |
64 | { | 61 | { |
65 | char *s; | 62 | long l; |
63 | int i; | ||
64 | char *s = luaL_check_lstr(1, &l); | ||
66 | luaL_resetbuffer(); | 65 | luaL_resetbuffer(); |
67 | for (s = luaL_check_string(1); *s; s++) | 66 | for (i=0; i<l; i++) |
68 | luaL_addchar(tolower((unsigned char)*s)); | 67 | luaL_addchar(tolower((unsigned char)(s[i]))); |
69 | closeandpush(); | 68 | closeandpush(); |
70 | } | 69 | } |
71 | 70 | ||
72 | 71 | ||
73 | static void str_upper (void) | 72 | static void str_upper (void) |
74 | { | 73 | { |
75 | char *s; | 74 | long l; |
75 | int i; | ||
76 | char *s = luaL_check_lstr(1, &l); | ||
76 | luaL_resetbuffer(); | 77 | luaL_resetbuffer(); |
77 | for (s = luaL_check_string(1); *s; s++) | 78 | for (i=0; i<l; i++) |
78 | luaL_addchar(toupper((unsigned char)*s)); | 79 | luaL_addchar(toupper((unsigned char)(s[i]))); |
79 | closeandpush(); | 80 | closeandpush(); |
80 | } | 81 | } |
81 | 82 | ||
82 | static void str_rep (void) | 83 | static void str_rep (void) |
83 | { | 84 | { |
84 | char *s = luaL_check_string(1); | 85 | long l; |
86 | char *s = luaL_check_lstr(1, &l); | ||
85 | int n = (int)luaL_check_number(2); | 87 | int n = (int)luaL_check_number(2); |
86 | luaL_resetbuffer(); | 88 | luaL_resetbuffer(); |
87 | while (n-- > 0) | 89 | while (n-- > 0) |
88 | addstr(s); | 90 | addnchar(s, l); |
89 | closeandpush(); | 91 | closeandpush(); |
90 | } | 92 | } |
91 | 93 | ||
92 | 94 | ||
93 | static void str_ascii (void) | 95 | static void str_ascii (void) |
94 | { | 96 | { |
95 | char *s = luaL_check_string(1); | 97 | long l; |
96 | long pos = (long)luaL_opt_number(2, 1) - 1; | 98 | char *s = luaL_check_lstr(1, &l); |
97 | luaL_arg_check(0<=pos && pos<strlen(s), 2, "out of range"); | 99 | long pos = posrelat(luaL_opt_number(2, 1), l); |
98 | lua_pushnumber((unsigned char)s[pos]); | 100 | luaL_arg_check(0<pos && pos<=l, 2, "out of range"); |
101 | lua_pushnumber((unsigned char)s[pos-1]); | ||
99 | } | 102 | } |
100 | 103 | ||
101 | 104 | ||
@@ -124,14 +127,8 @@ struct Capture { | |||
124 | static void push_captures (struct Capture *cap) | 127 | static void push_captures (struct Capture *cap) |
125 | { | 128 | { |
126 | int i; | 129 | int i; |
127 | for (i=0; i<cap->level; i++) { | 130 | for (i=0; i<cap->level; i++) |
128 | int l = cap->capture[i].len; | 131 | lua_pushlstr(cap->capture[i].init, cap->capture[i].len); |
129 | char *buff = luaL_openspace(l+1); | ||
130 | if (l == -1) lua_error("unfinished capture"); | ||
131 | strncpy(buff, cap->capture[i].init, l); | ||
132 | buff[l] = 0; | ||
133 | lua_pushstring(buff); | ||
134 | } | ||
135 | } | 132 | } |
136 | 133 | ||
137 | 134 | ||
@@ -163,7 +160,6 @@ static char *bracket_end (char *p) | |||
163 | static int matchclass (int c, int cl) | 160 | static int matchclass (int c, int cl) |
164 | { | 161 | { |
165 | int res; | 162 | int res; |
166 | if (c == 0) return 0; | ||
167 | switch (tolower((unsigned char)cl)) { | 163 | switch (tolower((unsigned char)cl)) { |
168 | case 'w' : res = isalnum((unsigned char)c); break; | 164 | case 'w' : res = isalnum((unsigned char)c); break; |
169 | case 'd' : res = isdigit((unsigned char)c); break; | 165 | case 'd' : res = isdigit((unsigned char)c); break; |
@@ -184,7 +180,7 @@ int luaI_singlematch (int c, char *p, char **ep) | |||
184 | switch (*p) { | 180 | switch (*p) { |
185 | case '.': | 181 | case '.': |
186 | *ep = p+1; | 182 | *ep = p+1; |
187 | return (c != 0); | 183 | return 1; |
188 | case '\0': | 184 | case '\0': |
189 | *ep = p; | 185 | *ep = p; |
190 | return 0; | 186 | return 0; |
@@ -198,7 +194,6 @@ int luaI_singlematch (int c, char *p, char **ep) | |||
198 | int sig = *(p+1) == '^' ? (p++, 0) : 1; | 194 | int sig = *(p+1) == '^' ? (p++, 0) : 1; |
199 | if (end == NULL) lua_error("incorrect pattern (missing `]')"); | 195 | if (end == NULL) lua_error("incorrect pattern (missing `]')"); |
200 | *ep = end+1; | 196 | *ep = end+1; |
201 | if (c == 0) return 0; | ||
202 | while (++p < end) { | 197 | while (++p < end) { |
203 | if (*p == ESC) { | 198 | if (*p == ESC) { |
204 | if (((p+1) < end) && matchclass(c, *++p)) return sig; | 199 | if (((p+1) < end) && matchclass(c, *++p)) return sig; |
@@ -254,7 +249,8 @@ static char *matchitem (char *s, char *p, struct Capture *cap, char **ep) | |||
254 | } | 249 | } |
255 | else p--; /* and go through */ | 250 | else p--; /* and go through */ |
256 | } | 251 | } |
257 | return (luaI_singlematch(*s, p, ep) ? s+1 : NULL); | 252 | /* "luaI_singlematch" sets "ep" (so must be called even when *s == 0) */ |
253 | return (luaI_singlematch(*s, p, ep) && *s) ? s+1 : NULL; | ||
258 | } | 254 | } |
259 | 255 | ||
260 | 256 | ||
@@ -322,10 +318,11 @@ static char *match (char *s, char *p, struct Capture *cap) | |||
322 | 318 | ||
323 | static void str_find (void) | 319 | static void str_find (void) |
324 | { | 320 | { |
325 | char *s = luaL_check_string(1); | 321 | long l; |
322 | char *s = luaL_check_lstr(1, &l); | ||
326 | char *p = luaL_check_string(2); | 323 | char *p = luaL_check_string(2); |
327 | long init = (long)luaL_opt_number(3, 1) - 1; | 324 | long init = posrelat(luaL_opt_number(3, 1), l) - 1; |
328 | luaL_arg_check(0 <= init && init <= strlen(s), 3, "out of range"); | 325 | luaL_arg_check(0 <= init && init <= l, 3, "out of range"); |
329 | if (lua_getparam(4) != LUA_NOOBJECT || | 326 | if (lua_getparam(4) != LUA_NOOBJECT || |
330 | strpbrk(p, SPECIALS) == NULL) { /* no special caracters? */ | 327 | strpbrk(p, SPECIALS) == NULL) { /* no special caracters? */ |
331 | char *s2 = strstr(s+init, p); | 328 | char *s2 = strstr(s+init, p); |
@@ -381,7 +378,10 @@ static void add_s (lua_Object newp, struct Capture *cap) | |||
381 | lua_error(NULL); | 378 | lua_error(NULL); |
382 | } | 379 | } |
383 | res = lua_getresult(1); | 380 | res = lua_getresult(1); |
384 | addstr(lua_isstring(res) ? lua_getstring(res) : ""); | 381 | if (lua_isstring(res)) |
382 | addnchar(lua_getstring(res), lua_getstrlen(res)); | ||
383 | else | ||
384 | addnchar(NULL, 0); | ||
385 | lua_endblock(); | 385 | lua_endblock(); |
386 | } | 386 | } |
387 | else luaL_arg_check(0, 3, "string or function expected"); | 387 | else luaL_arg_check(0, 3, "string or function expected"); |
@@ -413,7 +413,7 @@ static void str_gsub (void) | |||
413 | else break; | 413 | else break; |
414 | if (anchor) break; | 414 | if (anchor) break; |
415 | } | 415 | } |
416 | addstr(src); | 416 | addnchar(src, strlen(src)); |
417 | closeandpush(); | 417 | closeandpush(); |
418 | lua_pushnumber(n); /* number of substitutions */ | 418 | lua_pushnumber(n); /* number of substitutions */ |
419 | } | 419 | } |