aboutsummaryrefslogtreecommitdiff
path: root/lstrlib.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2000-09-11 14:38:42 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2000-09-11 14:38:42 -0300
commit787a78f83e0484c9e9698189982e2f309808fae8 (patch)
tree0682eddf4ea5a49bf5078bac937a36f90057df57 /lstrlib.c
parent70c8a310925d6c41c3ef4f7feeae604a4c9a3a95 (diff)
downloadlua-787a78f83e0484c9e9698189982e2f309808fae8.tar.gz
lua-787a78f83e0484c9e9698189982e2f309808fae8.tar.bz2
lua-787a78f83e0484c9e9698189982e2f309808fae8.zip
new scheme for buffers
Diffstat (limited to 'lstrlib.c')
-rw-r--r--lstrlib.c114
1 files changed, 52 insertions, 62 deletions
diff --git a/lstrlib.c b/lstrlib.c
index 6cdd87da..89114666 100644
--- a/lstrlib.c
+++ b/lstrlib.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lstrlib.c,v 1.50 2000/08/31 20:23:40 roberto Exp roberto $ 2** $Id: lstrlib.c,v 1.51 2000/09/05 19:33:32 roberto Exp $
3** Standard library for string operations and pattern-matching 3** Standard library for string operations and pattern-matching
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -18,13 +18,6 @@
18 18
19 19
20 20
21static void addnchar (lua_State *L, const char *s, size_t n) {
22 char *b = luaL_openspace(L, n);
23 memcpy(b, s, n);
24 luaL_addsize(L, n);
25}
26
27
28static int str_len (lua_State *L) { 21static int str_len (lua_State *L) {
29 size_t l; 22 size_t l;
30 luaL_check_lstr(L, 1, &l); 23 luaL_check_lstr(L, 1, &l);
@@ -33,11 +26,6 @@ static int str_len (lua_State *L) {
33} 26}
34 27
35 28
36static void closeandpush (lua_State *L) {
37 lua_pushlstring(L, luaL_buffer(L), luaL_getsize(L));
38}
39
40
41static long posrelat (long pos, size_t len) { 29static long posrelat (long pos, size_t len) {
42 /* relative string position: negative means back from end */ 30 /* relative string position: negative means back from end */
43 return (pos>=0) ? pos : (long)len+pos+1; 31 return (pos>=0) ? pos : (long)len+pos+1;
@@ -61,11 +49,12 @@ static int str_sub (lua_State *L) {
61static int str_lower (lua_State *L) { 49static int str_lower (lua_State *L) {
62 size_t l; 50 size_t l;
63 size_t i; 51 size_t i;
52 luaL_Buffer b;
64 const char *s = luaL_check_lstr(L, 1, &l); 53 const char *s = luaL_check_lstr(L, 1, &l);
65 luaL_resetbuffer(L); 54 luaL_buffinit(L, &b);
66 for (i=0; i<l; i++) 55 for (i=0; i<l; i++)
67 luaL_addchar(L, tolower((unsigned char)(s[i]))); 56 luaL_putchar(&b, tolower((unsigned char)(s[i])));
68 closeandpush(L); 57 luaL_pushresult(&b);
69 return 1; 58 return 1;
70} 59}
71 60
@@ -73,22 +62,24 @@ static int str_lower (lua_State *L) {
73static int str_upper (lua_State *L) { 62static int str_upper (lua_State *L) {
74 size_t l; 63 size_t l;
75 size_t i; 64 size_t i;
65 luaL_Buffer b;
76 const char *s = luaL_check_lstr(L, 1, &l); 66 const char *s = luaL_check_lstr(L, 1, &l);
77 luaL_resetbuffer(L); 67 luaL_buffinit(L, &b);
78 for (i=0; i<l; i++) 68 for (i=0; i<l; i++)
79 luaL_addchar(L, toupper((unsigned char)(s[i]))); 69 luaL_putchar(&b, toupper((unsigned char)(s[i])));
80 closeandpush(L); 70 luaL_pushresult(&b);
81 return 1; 71 return 1;
82} 72}
83 73
84static int str_rep (lua_State *L) { 74static int str_rep (lua_State *L) {
85 size_t l; 75 size_t l;
76 luaL_Buffer b;
86 const char *s = luaL_check_lstr(L, 1, &l); 77 const char *s = luaL_check_lstr(L, 1, &l);
87 int n = luaL_check_int(L, 2); 78 int n = luaL_check_int(L, 2);
88 luaL_resetbuffer(L); 79 luaL_buffinit(L, &b);
89 while (n-- > 0) 80 while (n-- > 0)
90 addnchar(L, s, l); 81 luaL_addlstring(&b, s, l);
91 closeandpush(L); 82 luaL_pushresult(&b);
92 return 1; 83 return 1;
93} 84}
94 85
@@ -106,13 +97,14 @@ static int str_byte (lua_State *L) {
106static int str_char (lua_State *L) { 97static int str_char (lua_State *L) {
107 int n = lua_gettop(L); /* number of arguments */ 98 int n = lua_gettop(L); /* number of arguments */
108 int i; 99 int i;
109 luaL_resetbuffer(L); 100 luaL_Buffer b;
101 luaL_buffinit(L, &b);
110 for (i=1; i<=n; i++) { 102 for (i=1; i<=n; i++) {
111 int c = luaL_check_int(L, i); 103 int c = luaL_check_int(L, i);
112 luaL_arg_check(L, (unsigned char)c == c, i, "invalid value"); 104 luaL_arg_check(L, (unsigned char)c == c, i, "invalid value");
113 luaL_addchar(L, (unsigned char)c); 105 luaL_putchar(&b, (unsigned char)c);
114 } 106 }
115 closeandpush(L); 107 luaL_pushresult(&b);
116 return 1; 108 return 1;
117} 109}
118 110
@@ -445,43 +437,37 @@ static int str_find (lua_State *L) {
445} 437}
446 438
447 439
448static void add_s (lua_State *L, struct Capture *cap) { 440static void add_s (lua_State *L, luaL_Buffer *b, struct Capture *cap) {
449 if (lua_isstring(L, 3)) { 441 if (lua_isstring(L, 3)) {
450 const char *news = lua_tostring(L, 3); 442 const char *news = lua_tostring(L, 3);
451 size_t l = lua_strlen(L, 3); 443 size_t l = lua_strlen(L, 3);
452 size_t i; 444 size_t i;
453 for (i=0; i<l; i++) { 445 for (i=0; i<l; i++) {
454 if (news[i] != ESC) 446 if (news[i] != ESC)
455 luaL_addchar(L, news[i]); 447 luaL_putchar(b, news[i]);
456 else { 448 else {
457 i++; /* skip ESC */ 449 i++; /* skip ESC */
458 if (!isdigit((unsigned char)news[i])) 450 if (!isdigit((unsigned char)news[i]))
459 luaL_addchar(L, news[i]); 451 luaL_putchar(b, news[i]);
460 else { 452 else {
461 int level = check_capture(L, news[i], cap); 453 int level = check_capture(L, news[i], cap);
462 addnchar(L, cap->capture[level].init, cap->capture[level].len); 454 luaL_addlstring(b, cap->capture[level].init, cap->capture[level].len);
463 } 455 }
464 } 456 }
465 } 457 }
466 } 458 }
467 else { /* is a function */ 459 else { /* is a function */
468 int status; 460 int status;
469 size_t oldbuff;
470 int n; 461 int n;
471 const char *s;
472 lua_pushvalue(L, 3); 462 lua_pushvalue(L, 3);
473 n = push_captures(L, cap); 463 n = push_captures(L, cap);
474 /* function may use buffer, so save it and create a new one */
475 oldbuff = luaL_newbuffer(L, 0);
476 status = lua_call(L, n, 1); 464 status = lua_call(L, n, 1);
477 /* restore old buffer */
478 luaL_oldbuffer(L, oldbuff);
479 if (status != 0) 465 if (status != 0)
480 lua_error(L, NULL); 466 lua_error(L, NULL); /* propagate error */
481 s = lua_tostring(L, -1); 467 if (lua_isstring(L, -1))
482 if (s) 468 luaL_addvalue(b); /* add return to accumulated result */
483 addnchar(L, lua_tostring(L, -1), lua_strlen(L, -1)); 469 else
484 lua_pop(L, 1); /* pop function result */ 470 lua_pop(L, 1); /* function result is not a string: pop it */
485 } 471 }
486} 472}
487 473
@@ -494,10 +480,11 @@ static int str_gsub (lua_State *L) {
494 int anchor = (*p == '^') ? (p++, 1) : 0; 480 int anchor = (*p == '^') ? (p++, 1) : 0;
495 int n = 0; 481 int n = 0;
496 struct Capture cap; 482 struct Capture cap;
483 luaL_Buffer b;
497 luaL_arg_check(L, 484 luaL_arg_check(L,
498 lua_gettop(L) >= 3 && (lua_isstring(L, 3) || lua_isfunction(L, 3)), 485 lua_gettop(L) >= 3 && (lua_isstring(L, 3) || lua_isfunction(L, 3)),
499 3, "string or function expected"); 486 3, "string or function expected");
500 luaL_resetbuffer(L); 487 luaL_buffinit(L, &b);
501 cap.src_end = src+srcl; 488 cap.src_end = src+srcl;
502 while (n < max_s) { 489 while (n < max_s) {
503 const char *e; 490 const char *e;
@@ -505,17 +492,17 @@ static int str_gsub (lua_State *L) {
505 e = match(L, src, p, &cap); 492 e = match(L, src, p, &cap);
506 if (e) { 493 if (e) {
507 n++; 494 n++;
508 add_s(L, &cap); 495 add_s(L, &b, &cap);
509 } 496 }
510 if (e && e>src) /* non empty match? */ 497 if (e && e>src) /* non empty match? */
511 src = e; /* skip it */ 498 src = e; /* skip it */
512 else if (src < cap.src_end) 499 else if (src < cap.src_end)
513 luaL_addchar(L, *src++); 500 luaL_putchar(&b, *src++);
514 else break; 501 else break;
515 if (anchor) break; 502 if (anchor) break;
516 } 503 }
517 addnchar(L, src, cap.src_end-src); 504 luaL_addlstring(&b, src, cap.src_end-src);
518 closeandpush(L); 505 luaL_pushresult(&b);
519 lua_pushnumber(L, n); /* number of substitutions */ 506 lua_pushnumber(L, n); /* number of substitutions */
520 return 2; 507 return 2;
521} 508}
@@ -523,40 +510,43 @@ static int str_gsub (lua_State *L) {
523/* }====================================================== */ 510/* }====================================================== */
524 511
525 512
526static void luaI_addquoted (lua_State *L, int arg) { 513static void luaI_addquoted (lua_State *L, luaL_Buffer *b, int arg) {
527 size_t l; 514 size_t l;
528 const char *s = luaL_check_lstr(L, arg, &l); 515 const char *s = luaL_check_lstr(L, arg, &l);
529 luaL_addchar(L, '"'); 516 luaL_putchar(b, '"');
530 while (l--) { 517 while (l--) {
531 switch (*s) { 518 switch (*s) {
532 case '"': case '\\': case '\n': 519 case '"': case '\\': case '\n':
533 luaL_addchar(L, '\\'); 520 luaL_putchar(b, '\\');
534 luaL_addchar(L, *s); 521 luaL_putchar(b, *s);
535 break; 522 break;
536 case '\0': addnchar(L, "\\000", 4); break; 523 case '\0': luaL_addlstring(b, "\\000", 4); break;
537 default: luaL_addchar(L, *s); 524 default: luaL_putchar(b, *s);
538 } 525 }
539 s++; 526 s++;
540 } 527 }
541 luaL_addchar(L, '"'); 528 luaL_putchar(b, '"');
542} 529}
543 530
531/* maximum size of each formated item (> len(format('%99.99f', -1e308))) */
532#define MAX_ITEM 512
544/* maximum size of each format specification (such as '%-099.99d') */ 533/* maximum size of each format specification (such as '%-099.99d') */
545#define MAX_FORMAT 20 /* arbitrary limit */ 534#define MAX_FORMAT 20
546 535
547static int str_format (lua_State *L) { 536static int str_format (lua_State *L) {
548 int arg = 1; 537 int arg = 1;
549 const char *strfrmt = luaL_check_string(L, arg); 538 const char *strfrmt = luaL_check_string(L, arg);
550 luaL_resetbuffer(L); 539 luaL_Buffer b;
540 luaL_buffinit(L, &b);
551 while (*strfrmt) { 541 while (*strfrmt) {
552 if (*strfrmt != '%') 542 if (*strfrmt != '%')
553 luaL_addchar(L, *strfrmt++); 543 luaL_putchar(&b, *strfrmt++);
554 else if (*++strfrmt == '%') 544 else if (*++strfrmt == '%')
555 luaL_addchar(L, *strfrmt++); /* %% */ 545 luaL_putchar(&b, *strfrmt++); /* %% */
556 else { /* format item */ 546 else { /* format item */
557 struct Capture cap; 547 struct Capture cap;
558 char form[MAX_FORMAT]; /* to store the format ('%...') */ 548 char form[MAX_FORMAT]; /* to store the format ('%...') */
559 char *buff; /* to store the formatted item */ 549 char buff[MAX_ITEM]; /* to store the formatted item */
560 const char *initf = strfrmt; 550 const char *initf = strfrmt;
561 form[0] = '%'; 551 form[0] = '%';
562 if (isdigit((unsigned char)*initf) && *(initf+1) == '$') { 552 if (isdigit((unsigned char)*initf) && *(initf+1) == '$') {
@@ -572,7 +562,6 @@ static int str_format (lua_State *L) {
572 lua_error(L, "invalid format (width or precision too long)"); 562 lua_error(L, "invalid format (width or precision too long)");
573 strncpy(form+1, initf, strfrmt-initf+1); /* +1 to include conversion */ 563 strncpy(form+1, initf, strfrmt-initf+1); /* +1 to include conversion */
574 form[strfrmt-initf+2] = 0; 564 form[strfrmt-initf+2] = 0;
575 buff = luaL_openspace(L, 512); /* 512 > len(format('%99.99f', -1e308)) */
576 switch (*strfrmt++) { 565 switch (*strfrmt++) {
577 case 'c': case 'd': case 'i': 566 case 'c': case 'd': case 'i':
578 sprintf(buff, form, luaL_check_int(L, arg)); 567 sprintf(buff, form, luaL_check_int(L, arg));
@@ -584,7 +573,7 @@ static int str_format (lua_State *L) {
584 sprintf(buff, form, luaL_check_number(L, arg)); 573 sprintf(buff, form, luaL_check_number(L, arg));
585 break; 574 break;
586 case 'q': 575 case 'q':
587 luaI_addquoted(L, arg); 576 luaI_addquoted(L, &b, arg);
588 continue; /* skip the "addsize" at the end */ 577 continue; /* skip the "addsize" at the end */
589 case 's': { 578 case 's': {
590 size_t l; 579 size_t l;
@@ -592,7 +581,8 @@ static int str_format (lua_State *L) {
592 if (cap.capture[1].len == 0 && l >= 100) { 581 if (cap.capture[1].len == 0 && l >= 100) {
593 /* no precision and string is too long to be formatted; 582 /* no precision and string is too long to be formatted;
594 keep original string */ 583 keep original string */
595 addnchar(L, s, l); 584 lua_pushvalue(L, arg);
585 luaL_addvalue(&b);
596 continue; /* skip the "addsize" at the end */ 586 continue; /* skip the "addsize" at the end */
597 } 587 }
598 else { 588 else {
@@ -603,10 +593,10 @@ static int str_format (lua_State *L) {
603 default: /* also treat cases 'pnLlh' */ 593 default: /* also treat cases 'pnLlh' */
604 lua_error(L, "invalid option in `format'"); 594 lua_error(L, "invalid option in `format'");
605 } 595 }
606 luaL_addsize(L, strlen(buff)); 596 luaL_addlstring(&b, buff, strlen(buff));
607 } 597 }
608 } 598 }
609 closeandpush(L); /* push the result */ 599 luaL_pushresult(&b);
610 return 1; 600 return 1;
611} 601}
612 602