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 | } |
