aboutsummaryrefslogtreecommitdiff
path: root/lstrlib.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>1998-03-06 13:54:42 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>1998-03-06 13:54:42 -0300
commit88a2023c3285c4514519158fba90e644fc6ffca3 (patch)
treeda6611257545c486ff856dd48d66d94e056f3d66 /lstrlib.c
parent5ef1989c4b05aff8362a7ea6ba62aad76d4a040d (diff)
downloadlua-88a2023c3285c4514519158fba90e644fc6ffca3.tar.gz
lua-88a2023c3285c4514519158fba90e644fc6ffca3.tar.bz2
lua-88a2023c3285c4514519158fba90e644fc6ffca3.zip
support for strings with '\0'
Diffstat (limited to 'lstrlib.c')
-rw-r--r--lstrlib.c98
1 files changed, 49 insertions, 49 deletions
diff --git a/lstrlib.c b/lstrlib.c
index a1b061ed..8ddf6428 100644
--- a/lstrlib.c
+++ b/lstrlib.c
@@ -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 @@
19static void addnchar (char *s, int n) 19static 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
27static void addstr (char *s) 27static 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
33static void str_len (void) 35static 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
39static void closeandpush (void) 41static 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
46static void str_sub (void) 48static 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
63static void str_lower (void) 60static 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
73static void str_upper (void) 72static 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
82static void str_rep (void) 83static 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
93static void str_ascii (void) 95static 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 {
124static void push_captures (struct Capture *cap) 127static 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)
163static int matchclass (int c, int cl) 160static 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
323static void str_find (void) 319static 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}