aboutsummaryrefslogtreecommitdiff
path: root/lstrlib.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>1997-12-17 18:48:58 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>1997-12-17 18:48:58 -0200
commit502343b40230dfb00efc37bdbaa5c5576f3a5aa5 (patch)
treeb75f9e296ad3229a607fb2b7152dd9efc3706ef6 /lstrlib.c
parent82d09fbf0dbd5aee890f033b25b09dc48ce58a48 (diff)
downloadlua-502343b40230dfb00efc37bdbaa5c5576f3a5aa5.tar.gz
lua-502343b40230dfb00efc37bdbaa5c5576f3a5aa5.tar.bz2
lua-502343b40230dfb00efc37bdbaa5c5576f3a5aa5.zip
new scheme for buffers, centralized in auxlib.
Diffstat (limited to 'lstrlib.c')
-rw-r--r--lstrlib.c125
1 files changed, 44 insertions, 81 deletions
diff --git a/lstrlib.c b/lstrlib.c
index 9f1ae82d..cca70bc5 100644
--- a/lstrlib.c
+++ b/lstrlib.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lstrlib.c,v 1.3 1997/12/09 13:35:19 roberto Exp roberto $ 2** $Id: lstrlib.c,v 1.4 1997/12/15 17:58:49 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*/
@@ -15,56 +15,12 @@
15#include "lualib.h" 15#include "lualib.h"
16 16
17 17
18struct lbuff {
19 char *b;
20 size_t max;
21 size_t size;
22};
23
24static struct lbuff lbuffer = {NULL, 0, 0};
25
26
27static char *strbuffer (unsigned long size)
28{
29 if (size > lbuffer.max) {
30 /* ANSI "realloc" doesn't need this test, but some machines (Sun!)
31 don't follow ANSI */
32 lbuffer.b = (lbuffer.b) ? realloc(lbuffer.b, lbuffer.max=size) :
33 malloc(lbuffer.max=size);
34 if (lbuffer.b == NULL)
35 lua_error("memory overflow");
36 }
37 return lbuffer.b;
38}
39
40
41static char *openspace (unsigned long size)
42{
43 char *buff = strbuffer(lbuffer.size+size);
44 return buff+lbuffer.size;
45}
46
47
48char *luaI_addchar (int c)
49{
50 if (lbuffer.size >= lbuffer.max)
51 strbuffer(lbuffer.max == 0 ? 100 : lbuffer.max*2);
52 lbuffer.b[lbuffer.size++] = c;
53 return lbuffer.b;
54}
55
56
57void luaI_emptybuff (void)
58{
59 lbuffer.size = 0; /* prepare for next string */
60}
61
62 18
63static void addnchar (char *s, int n) 19static void addnchar (char *s, int n)
64{ 20{
65 char *b = openspace(n); 21 char *b = luaL_openspace(n);
66 strncpy(b, s, n); 22 strncpy(b, s, n);
67 lbuffer.size += n; 23 luaL_addsize(n);
68} 24}
69 25
70 26
@@ -80,6 +36,13 @@ static void str_len (void)
80} 36}
81 37
82 38
39static void closeandpush (void)
40{
41 luaL_addchar(0);
42 lua_pushstring(luaL_buffer());
43}
44
45
83static void str_sub (void) 46static void str_sub (void)
84{ 47{
85 char *s = luaL_check_string(1); 48 char *s = luaL_check_string(1);
@@ -89,9 +52,9 @@ static void str_sub (void)
89 if (start < 0) start = l+start+1; 52 if (start < 0) start = l+start+1;
90 if (end < 0) end = l+end+1; 53 if (end < 0) end = l+end+1;
91 if (1 <= start && start <= end && end <= l) { 54 if (1 <= start && start <= end && end <= l) {
92 luaI_emptybuff(); 55 luaL_resetbuffer();
93 addnchar(s+start-1, end-start+1); 56 addnchar(s+start-1, end-start+1);
94 lua_pushstring(luaI_addchar(0)); 57 closeandpush();
95 } 58 }
96 else lua_pushstring(""); 59 else lua_pushstring("");
97} 60}
@@ -100,30 +63,30 @@ static void str_sub (void)
100static void str_lower (void) 63static void str_lower (void)
101{ 64{
102 char *s; 65 char *s;
103 luaI_emptybuff(); 66 luaL_resetbuffer();
104 for (s = luaL_check_string(1); *s; s++) 67 for (s = luaL_check_string(1); *s; s++)
105 luaI_addchar(tolower((unsigned char)*s)); 68 luaL_addchar(tolower((unsigned char)*s));
106 lua_pushstring(luaI_addchar(0)); 69 closeandpush();
107} 70}
108 71
109 72
110static void str_upper (void) 73static void str_upper (void)
111{ 74{
112 char *s; 75 char *s;
113 luaI_emptybuff(); 76 luaL_resetbuffer();
114 for (s = luaL_check_string(1); *s; s++) 77 for (s = luaL_check_string(1); *s; s++)
115 luaI_addchar(toupper((unsigned char)*s)); 78 luaL_addchar(toupper((unsigned char)*s));
116 lua_pushstring(luaI_addchar(0)); 79 closeandpush();
117} 80}
118 81
119static void str_rep (void) 82static void str_rep (void)
120{ 83{
121 char *s = luaL_check_string(1); 84 char *s = luaL_check_string(1);
122 int n = (int)luaL_check_number(2); 85 int n = (int)luaL_check_number(2);
123 luaI_emptybuff(); 86 luaL_resetbuffer();
124 while (n-- > 0) 87 while (n-- > 0)
125 addstr(s); 88 addstr(s);
126 lua_pushstring(luaI_addchar(0)); 89 closeandpush();
127} 90}
128 91
129 92
@@ -163,7 +126,7 @@ static void push_captures (struct Capture *cap)
163 int i; 126 int i;
164 for (i=0; i<cap->level; i++) { 127 for (i=0; i<cap->level; i++) {
165 int l = cap->capture[i].len; 128 int l = cap->capture[i].len;
166 char *buff = openspace(l+1); 129 char *buff = luaL_openspace(l+1);
167 if (l == -1) lua_error("unfinished capture"); 130 if (l == -1) lua_error("unfinished capture");
168 strncpy(buff, cap->capture[i].init, l); 131 strncpy(buff, cap->capture[i].init, l);
169 buff[l] = 0; 132 buff[l] = 0;
@@ -395,7 +358,7 @@ static void add_s (lua_Object newp, struct Capture *cap)
395 char *news = lua_getstring(newp); 358 char *news = lua_getstring(newp);
396 while (*news) { 359 while (*news) {
397 if (*news != ESC || !isdigit((unsigned char)*++news)) 360 if (*news != ESC || !isdigit((unsigned char)*++news))
398 luaI_addchar(*news++); 361 luaL_addchar(*news++);
399 else { 362 else {
400 int l = check_cap(*news++, cap); 363 int l = check_cap(*news++, cap);
401 addnchar(cap->capture[l].init, cap->capture[l].len); 364 addnchar(cap->capture[l].init, cap->capture[l].len);
@@ -404,24 +367,24 @@ static void add_s (lua_Object newp, struct Capture *cap)
404 } 367 }
405 else if (lua_isfunction(newp)) { 368 else if (lua_isfunction(newp)) {
406 lua_Object res; 369 lua_Object res;
407 struct lbuff oldbuff;
408 int status; 370 int status;
371 int oldbuff;
409 lua_beginblock(); 372 lua_beginblock();
410 push_captures(cap); 373 push_captures(cap);
411 /* function may use lbuffer, so save it and create a luaM_new one */ 374 /* function may use buffer, so save it and create a new one */
412 oldbuff = lbuffer; 375 oldbuff = luaL_newbuffer(0);
413 lbuffer.b = NULL; lbuffer.max = lbuffer.size = 0;
414 status = lua_callfunction(newp); 376 status = lua_callfunction(newp);
415 /* restore old buffer */ 377 /* restore old buffer */
416 free(lbuffer.b); 378 luaL_oldbuffer(oldbuff);
417 lbuffer = oldbuff; 379 if (status != 0) {
418 if (status != 0) 380 lua_endblock();
419 lua_error(NULL); 381 lua_error(NULL);
382 }
420 res = lua_getresult(1); 383 res = lua_getresult(1);
421 addstr(lua_isstring(res) ? lua_getstring(res) : ""); 384 addstr(lua_isstring(res) ? lua_getstring(res) : "");
422 lua_endblock(); 385 lua_endblock();
423 } 386 }
424 else luaL_arg_check(0, 3, NULL); 387 else luaL_arg_check(0, 3, "string or function expected");
425} 388}
426 389
427 390
@@ -433,7 +396,7 @@ static void str_gsub (void)
433 int max_s = (int)luaL_opt_number(4, strlen(src)+1); 396 int max_s = (int)luaL_opt_number(4, strlen(src)+1);
434 int anchor = (*p == '^') ? (p++, 1) : 0; 397 int anchor = (*p == '^') ? (p++, 1) : 0;
435 int n = 0; 398 int n = 0;
436 luaI_emptybuff(); 399 luaL_resetbuffer();
437 while (n < max_s) { 400 while (n < max_s) {
438 struct Capture cap; 401 struct Capture cap;
439 char *e; 402 char *e;
@@ -446,25 +409,25 @@ static void str_gsub (void)
446 if (e && e>src) /* non empty match? */ 409 if (e && e>src) /* non empty match? */
447 src = e; /* skip it */ 410 src = e; /* skip it */
448 else if (*src) 411 else if (*src)
449 luaI_addchar(*src++); 412 luaL_addchar(*src++);
450 else break; 413 else break;
451 if (anchor) break; 414 if (anchor) break;
452 } 415 }
453 addstr(src); 416 addstr(src);
454 lua_pushstring(luaI_addchar(0)); 417 closeandpush();
455 lua_pushnumber(n); /* number of substitutions */ 418 lua_pushnumber(n); /* number of substitutions */
456} 419}
457 420
458 421
459static void luaI_addquoted (char *s) 422static void luaI_addquoted (char *s)
460{ 423{
461 luaI_addchar('"'); 424 luaL_addchar('"');
462 for (; *s; s++) { 425 for (; *s; s++) {
463 if (strchr("\"\\\n", *s)) 426 if (strchr("\"\\\n", *s))
464 luaI_addchar('\\'); 427 luaL_addchar('\\');
465 luaI_addchar(*s); 428 luaL_addchar(*s);
466 } 429 }
467 luaI_addchar('"'); 430 luaL_addchar('"');
468} 431}
469 432
470#define MAX_FORMAT 200 433#define MAX_FORMAT 200
@@ -473,12 +436,12 @@ static void str_format (void)
473{ 436{
474 int arg = 1; 437 int arg = 1;
475 char *strfrmt = luaL_check_string(arg); 438 char *strfrmt = luaL_check_string(arg);
476 luaI_emptybuff(); /* initialize */ 439 luaL_resetbuffer();
477 while (*strfrmt) { 440 while (*strfrmt) {
478 if (*strfrmt != '%') 441 if (*strfrmt != '%')
479 luaI_addchar(*strfrmt++); 442 luaL_addchar(*strfrmt++);
480 else if (*++strfrmt == '%') 443 else if (*++strfrmt == '%')
481 luaI_addchar(*strfrmt++); /* %% */ 444 luaL_addchar(*strfrmt++); /* %% */
482 else { /* format item */ 445 else { /* format item */
483 char form[MAX_FORMAT]; /* store the format ('%...') */ 446 char form[MAX_FORMAT]; /* store the format ('%...') */
484 struct Capture cap; 447 struct Capture cap;
@@ -496,14 +459,14 @@ static void str_format (void)
496 arg++; 459 arg++;
497 strncpy(form+1, initf, strfrmt-initf+1); /* +1 to include convertion */ 460 strncpy(form+1, initf, strfrmt-initf+1); /* +1 to include convertion */
498 form[strfrmt-initf+2] = 0; 461 form[strfrmt-initf+2] = 0;
499 buff = openspace(1000); /* to store the formatted value */ 462 buff = luaL_openspace(1000); /* to store the formatted value */
500 switch (*strfrmt++) { 463 switch (*strfrmt++) {
501 case 'q': 464 case 'q':
502 luaI_addquoted(luaL_check_string(arg)); 465 luaI_addquoted(luaL_check_string(arg));
503 continue; 466 continue;
504 case 's': { 467 case 's': {
505 char *s = luaL_check_string(arg); 468 char *s = luaL_check_string(arg);
506 buff = openspace(strlen(s)); 469 buff = luaL_openspace(strlen(s));
507 sprintf(buff, form, s); 470 sprintf(buff, form, s);
508 break; 471 break;
509 } 472 }
@@ -517,10 +480,10 @@ static void str_format (void)
517 default: /* also treat cases 'pnLlh' */ 480 default: /* also treat cases 'pnLlh' */
518 lua_error("invalid option in `format'"); 481 lua_error("invalid option in `format'");
519 } 482 }
520 lbuffer.size += strlen(buff); 483 luaL_addsize(strlen(buff));
521 } 484 }
522 } 485 }
523 lua_pushstring(luaI_addchar(0)); /* push the result */ 486 closeandpush(); /* push the result */
524} 487}
525 488
526 489