aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>1996-09-16 15:02:40 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>1996-09-16 15:02:40 -0300
commitc96ad1c9455b59ea3ff25660549b0e2ad222791e (patch)
tree8d15f6055e16302bba23e066b89f2fbf5cc22709
parent5b9fbfa0066e86a8397c7f07a9596cb94d14e51b (diff)
downloadlua-c96ad1c9455b59ea3ff25660549b0e2ad222791e.tar.gz
lua-c96ad1c9455b59ea3ff25660549b0e2ad222791e.tar.bz2
lua-c96ad1c9455b59ea3ff25660549b0e2ad222791e.zip
"strmap" replaced by "strupper" and "strlower" (that's what people will
use, anyway). "gsub" aceppts a function to give the replacement string.
-rw-r--r--strlib.c167
1 files changed, 100 insertions, 67 deletions
diff --git a/strlib.c b/strlib.c
index 2063c9c6..be9e7734 100644
--- a/strlib.c
+++ b/strlib.c
@@ -3,7 +3,7 @@
3** String library to LUA 3** String library to LUA
4*/ 4*/
5 5
6char *rcs_strlib="$Id: strlib.c,v 1.26 1996/08/05 20:55:24 roberto Exp roberto $"; 6char *rcs_strlib="$Id: strlib.c,v 1.27 1996/08/09 13:14:11 roberto Exp roberto $";
7 7
8#include <string.h> 8#include <string.h>
9#include <stdio.h> 9#include <stdio.h>
@@ -14,25 +14,32 @@ char *rcs_strlib="$Id: strlib.c,v 1.26 1996/08/05 20:55:24 roberto Exp roberto $
14#include "lualib.h" 14#include "lualib.h"
15 15
16 16
17static char *buffer = NULL; 17struct lbuff {
18static size_t maxbuff = 0; 18 char *b;
19static size_t buff_size = 0; 19 size_t max;
20 size_t size;
21};
22
23static struct lbuff lbuffer = {NULL, 0, 0};
20 24
21 25
22static char *lua_strbuffer (unsigned long size) 26static char *lua_strbuffer (unsigned long size)
23{ 27{
24 if (size > maxbuff) { 28 if (size > lbuffer.max) {
25 buffer = (buffer) ? realloc(buffer, maxbuff=size) : malloc(maxbuff=size); 29 /* ANSI "realloc" doesn't need this test, but some machines (Sun!)
26 if (buffer == NULL) 30 don't follow ANSI */
31 lbuffer.b = (lbuffer.b) ? realloc(lbuffer.b, lbuffer.max=size) :
32 malloc(lbuffer.max=size);
33 if (lbuffer.b == NULL)
27 lua_error("memory overflow"); 34 lua_error("memory overflow");
28 } 35 }
29 return buffer; 36 return lbuffer.b;
30} 37}
31 38
32static char *openspace (unsigned long size) 39static char *openspace (unsigned long size)
33{ 40{
34 char *buff = lua_strbuffer(buff_size+size); 41 char *buff = lua_strbuffer(lbuffer.size+size);
35 return buff+buff_size; 42 return buff+lbuffer.size;
36} 43}
37 44
38void lua_arg_check(int cond, char *funcname) 45void lua_arg_check(int cond, char *funcname)
@@ -72,21 +79,25 @@ long lua_opt_number (int numArg, long def, char *funcname)
72 79
73char *luaI_addchar (int c) 80char *luaI_addchar (int c)
74{ 81{
75 if (buff_size >= maxbuff) 82 if (lbuffer.size >= lbuffer.max)
76 lua_strbuffer(maxbuff == 0 ? 100 : maxbuff*2); 83 lua_strbuffer(lbuffer.max == 0 ? 100 : lbuffer.max*2);
77 buffer[buff_size++] = c; 84 lbuffer.b[lbuffer.size++] = c;
78 if (c == 0) 85 if (c == 0)
79 buff_size = 0; /* prepare for next string */ 86 lbuffer.size = 0; /* prepare for next string */
80 return buffer; 87 return lbuffer.b;
81} 88}
82 89
83static void addnchar (char *s, int n) 90static void addnchar (char *s, int n)
84{ 91{
85 char *b = openspace(n); 92 char *b = openspace(n);
86 strncpy(b, s, n); 93 strncpy(b, s, n);
87 buff_size += n; 94 lbuffer.size += n;
88} 95}
89 96
97static void addstr (char *s)
98{
99 addnchar(s, strlen(s));
100}
90 101
91/* 102/*
92** Interface to strtok 103** Interface to strtok
@@ -113,8 +124,6 @@ static void str_tok (void)
113 124
114/* 125/*
115** Return the string length 126** Return the string length
116** LUA interface:
117** n = strlen (string)
118*/ 127*/
119static void str_len (void) 128static void str_len (void)
120{ 129{
@@ -122,9 +131,7 @@ static void str_len (void)
122} 131}
123 132
124/* 133/*
125** Return the substring of a string, from start to end 134** Return the substring of a string
126** LUA interface:
127** substring = strsub (string, start, end)
128*/ 135*/
129static void str_sub (void) 136static void str_sub (void)
130{ 137{
@@ -140,24 +147,26 @@ static void str_sub (void)
140} 147}
141 148
142/* 149/*
143** Transliterate a string 150** Convert a string to lower case.
144*/ 151*/
145static void str_map (void) 152static void str_lower (void)
146{ 153{
147 char *s = lua_check_string(1, "strmap"); 154 char *s = lua_check_string(1, "strlower");
148 char *from = lua_check_string(2, "strmap"); 155 luaI_addchar(0);
149 char *to = lua_opt_string(3, "", "strmap"); 156 while (*s)
150 long len = strlen(to); 157 luaI_addchar(tolower(*s++));
151 for (luaI_addchar(0); *s; s++) { 158 lua_pushstring(luaI_addchar(0));
152 char *f = strrchr(from, *s); 159}
153 if (f == NULL) 160
154 luaI_addchar(*s); 161/*
155 else { 162** Convert a string to upper case.
156 long pos = f-from; 163*/
157 if (pos < len) 164static void str_upper (void)
158 luaI_addchar(to[pos]); 165{
159 } 166 char *s = lua_check_string(1, "strupper");
160 } 167 luaI_addchar(0);
168 while (*s)
169 luaI_addchar(toupper(*s++));
161 lua_pushstring(luaI_addchar(0)); 170 lua_pushstring(luaI_addchar(0));
162} 171}
163 172
@@ -255,11 +264,13 @@ static int num_captures; /* only valid after a sucessful call to match */
255static void push_captures (void) 264static void push_captures (void)
256{ 265{
257 int i; 266 int i;
258 luaI_addchar(0);
259 for (i=0; i<num_captures; i++) { 267 for (i=0; i<num_captures; i++) {
260 if (capture[i].len == -1) lua_error("unfinished capture"); 268 int l = capture[i].len;
261 addnchar(capture[i].init, capture[i].len); 269 char *buff = openspace(l+1);
262 lua_pushstring(luaI_addchar(0)); 270 if (l == -1) lua_error("unfinished capture");
271 strncpy(buff, capture[i].init, l);
272 buff[l] = 0;
273 lua_pushstring(buff);
263 } 274 }
264} 275}
265 276
@@ -271,18 +282,6 @@ static int check_cap (int l, int level)
271 return l; 282 return l;
272} 283}
273 284
274static void add_s (char *newp)
275{
276 while (*newp) {
277 if (*newp != ESC || !isdigit(*++newp))
278 luaI_addchar(*newp++);
279 else {
280 int l = check_cap(*newp++, num_captures);
281 addnchar(capture[l].init, capture[l].len);
282 }
283 }
284}
285
286static int capture_to_close (int level) 285static int capture_to_close (int level)
287{ 286{
288 for (level--; level>=0; level--) 287 for (level--; level>=0; level--)
@@ -376,12 +375,44 @@ static void str_find (void)
376 } 375 }
377} 376}
378 377
379static void str_s (void) 378static void add_s (lua_Object newp)
379{
380 if (lua_isstring(newp)) {
381 char *news = lua_getstring(newp);
382 while (*news) {
383 if (*news != ESC || !isdigit(*++news))
384 luaI_addchar(*news++);
385 else {
386 int l = check_cap(*news++, num_captures);
387 addnchar(capture[l].init, capture[l].len);
388 }
389 }
390 }
391 else if (lua_isfunction(newp)) {
392 lua_Object res;
393 struct lbuff oldbuff;
394 lua_beginblock();
395 push_captures();
396 /* function may use lbuffer, so save it and create a new one */
397 oldbuff = lbuffer;
398 lbuffer.b = NULL; lbuffer.max = lbuffer.size = 0;
399 lua_callfunction(newp);
400 /* restore old buffer */
401 free(lbuffer.b);
402 lbuffer = oldbuff;
403 res = lua_getresult(1);
404 addstr(lua_isstring(res) ? lua_getstring(res) : "");
405 lua_endblock();
406 }
407 else lua_error("incorrect argument to `gsub'");
408}
409
410static void str_gsub (void)
380{ 411{
381 char *src = lua_check_string(1, "s"); 412 char *src = lua_check_string(1, "gsub");
382 char *p = lua_check_string(2, "s"); 413 char *p = lua_check_string(2, "gsub");
383 char *newp = lua_check_string(3, "s"); 414 lua_Object newp = lua_getparam(3);
384 int max_s = lua_opt_number(4, strlen(src), "s"); 415 int max_s = lua_opt_number(4, strlen(src), "gsub");
385 int anchor = (*p == '^') ? (p++, 1) : 0; 416 int anchor = (*p == '^') ? (p++, 1) : 0;
386 int n = 0; 417 int n = 0;
387 luaI_addchar(0); 418 luaI_addchar(0);
@@ -390,14 +421,14 @@ static void str_s (void)
390 if ((e=match(src, p, 0)) == NULL) 421 if ((e=match(src, p, 0)) == NULL)
391 luaI_addchar(*src++); 422 luaI_addchar(*src++);
392 else { 423 else {
393 if (e == src) lua_error("empty pattern in substitution"); /* ??? */ 424 if (e == src) lua_error("empty pattern in substitution");
394 add_s(newp); 425 add_s(newp);
395 src = e; 426 src = e;
396 n++; 427 n++;
397 } 428 }
398 if (anchor) break; 429 if (anchor) break;
399 } 430 }
400 addnchar(src, strlen(src)); 431 addstr(src);
401 lua_pushstring(luaI_addchar(0)); 432 lua_pushstring(luaI_addchar(0));
402 lua_pushnumber(n); /* number of substitutions */ 433 lua_pushnumber(n); /* number of substitutions */
403} 434}
@@ -455,16 +486,17 @@ static void str_format (void)
455 case 's': { 486 case 's': {
456 char *s = lua_check_string(arg++, "format"); 487 char *s = lua_check_string(arg++, "format");
457 buff = openspace(strlen(s)); 488 buff = openspace(strlen(s));
458 buff_size += sprintf(buff, form, s); 489 lbuffer.size += sprintf(buff, form, s);
459 break; 490 break;
460 } 491 }
461 case 'c': case 'd': case 'i': case 'o': 492 case 'c': case 'd': case 'i': case 'o':
462 case 'u': case 'x': case 'X': 493 case 'u': case 'x': case 'X':
463 buff_size += sprintf(buff, form, 494 lbuffer.size += sprintf(buff, form,
464 (int)lua_check_number(arg++, "format")); 495 (int)lua_check_number(arg++, "format"));
465 break; 496 break;
466 case 'e': case 'E': case 'f': case 'g': 497 case 'e': case 'E': case 'f': case 'g':
467 buff_size += sprintf(buff, form, lua_check_number(arg++, "format")); 498 lbuffer.size += sprintf(buff, form,
499 lua_check_number(arg++, "format"));
468 break; 500 break;
469 default: /* also treat cases 'pnLlh' */ 501 default: /* also treat cases 'pnLlh' */
470 lua_error("invalid format option in function `format'"); 502 lua_error("invalid format option in function `format'");
@@ -488,11 +520,12 @@ static struct lua_reg strlib[] = {
488{"strlen", str_len}, 520{"strlen", str_len},
489{"strsub", str_sub}, 521{"strsub", str_sub},
490{"strset", str_set}, 522{"strset", str_set},
491{"strmap", str_map}, 523{"strlower", str_lower},
524{"strupper", str_upper},
492{"ascii", str_ascii}, 525{"ascii", str_ascii},
493{"format", str_format}, 526{"format", str_format},
494{"strfind", str_find}, 527{"strfind", str_find},
495{"gsub", str_s} 528{"gsub", str_gsub}
496}; 529};
497 530
498 531