diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2000-08-28 14:57:04 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2000-08-28 14:57:04 -0300 |
commit | 9fdf73bc9a6b4c6afbfff1d8181fface6b1c6761 (patch) | |
tree | da8d97d954e5ffabf9ff275df725f1e0a3a5b3e6 /lstrlib.c | |
parent | f1fd9b5c2c21f24d25d7813f431a3495702ebea6 (diff) | |
download | lua-9fdf73bc9a6b4c6afbfff1d8181fface6b1c6761.tar.gz lua-9fdf73bc9a6b4c6afbfff1d8181fface6b1c6761.tar.bz2 lua-9fdf73bc9a6b4c6afbfff1d8181fface6b1c6761.zip |
first version for new API
Diffstat (limited to 'lstrlib.c')
-rw-r--r-- | lstrlib.c | 104 |
1 files changed, 57 insertions, 47 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lstrlib.c,v 1.45 2000/06/12 14:37:18 roberto Exp roberto $ | 2 | ** $Id: lstrlib.c,v 1.46 2000/08/09 19:16:57 roberto Exp roberto $ |
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 | */ |
@@ -25,10 +25,11 @@ static void addnchar (lua_State *L, const char *s, size_t n) { | |||
25 | } | 25 | } |
26 | 26 | ||
27 | 27 | ||
28 | static void str_len (lua_State *L) { | 28 | static int str_len (lua_State *L) { |
29 | size_t l; | 29 | size_t l; |
30 | luaL_check_lstr(L, 1, &l); | 30 | luaL_check_lstr(L, 1, &l); |
31 | lua_pushnumber(L, l); | 31 | lua_pushnumber(L, l); |
32 | return 1; | ||
32 | } | 33 | } |
33 | 34 | ||
34 | 35 | ||
@@ -43,7 +44,7 @@ static long posrelat (long pos, size_t len) { | |||
43 | } | 44 | } |
44 | 45 | ||
45 | 46 | ||
46 | static void str_sub (lua_State *L) { | 47 | static int str_sub (lua_State *L) { |
47 | size_t l; | 48 | size_t l; |
48 | const char *s = luaL_check_lstr(L, 1, &l); | 49 | const char *s = luaL_check_lstr(L, 1, &l); |
49 | long start = posrelat(luaL_check_long(L, 2), l); | 50 | long start = posrelat(luaL_check_long(L, 2), l); |
@@ -53,10 +54,11 @@ static void str_sub (lua_State *L) { | |||
53 | if (start <= end) | 54 | if (start <= end) |
54 | lua_pushlstring(L, s+start-1, end-start+1); | 55 | lua_pushlstring(L, s+start-1, end-start+1); |
55 | else lua_pushstring(L, ""); | 56 | else lua_pushstring(L, ""); |
57 | return 1; | ||
56 | } | 58 | } |
57 | 59 | ||
58 | 60 | ||
59 | static void str_lower (lua_State *L) { | 61 | static int str_lower (lua_State *L) { |
60 | size_t l; | 62 | size_t l; |
61 | size_t i; | 63 | size_t i; |
62 | const char *s = luaL_check_lstr(L, 1, &l); | 64 | const char *s = luaL_check_lstr(L, 1, &l); |
@@ -64,10 +66,11 @@ static void str_lower (lua_State *L) { | |||
64 | for (i=0; i<l; i++) | 66 | for (i=0; i<l; i++) |
65 | luaL_addchar(L, tolower((unsigned char)(s[i]))); | 67 | luaL_addchar(L, tolower((unsigned char)(s[i]))); |
66 | closeandpush(L); | 68 | closeandpush(L); |
69 | return 1; | ||
67 | } | 70 | } |
68 | 71 | ||
69 | 72 | ||
70 | static void str_upper (lua_State *L) { | 73 | static int str_upper (lua_State *L) { |
71 | size_t l; | 74 | size_t l; |
72 | size_t i; | 75 | size_t i; |
73 | const char *s = luaL_check_lstr(L, 1, &l); | 76 | const char *s = luaL_check_lstr(L, 1, &l); |
@@ -75,9 +78,10 @@ static void str_upper (lua_State *L) { | |||
75 | for (i=0; i<l; i++) | 78 | for (i=0; i<l; i++) |
76 | luaL_addchar(L, toupper((unsigned char)(s[i]))); | 79 | luaL_addchar(L, toupper((unsigned char)(s[i]))); |
77 | closeandpush(L); | 80 | closeandpush(L); |
81 | return 1; | ||
78 | } | 82 | } |
79 | 83 | ||
80 | static void str_rep (lua_State *L) { | 84 | static int str_rep (lua_State *L) { |
81 | size_t l; | 85 | size_t l; |
82 | const char *s = luaL_check_lstr(L, 1, &l); | 86 | const char *s = luaL_check_lstr(L, 1, &l); |
83 | int n = luaL_check_int(L, 2); | 87 | int n = luaL_check_int(L, 2); |
@@ -85,27 +89,31 @@ static void str_rep (lua_State *L) { | |||
85 | while (n-- > 0) | 89 | while (n-- > 0) |
86 | addnchar(L, s, l); | 90 | addnchar(L, s, l); |
87 | closeandpush(L); | 91 | closeandpush(L); |
92 | return 1; | ||
88 | } | 93 | } |
89 | 94 | ||
90 | 95 | ||
91 | static void str_byte (lua_State *L) { | 96 | static int str_byte (lua_State *L) { |
92 | size_t l; | 97 | size_t l; |
93 | const char *s = luaL_check_lstr(L, 1, &l); | 98 | const char *s = luaL_check_lstr(L, 1, &l); |
94 | long pos = posrelat(luaL_opt_long(L, 2, 1), l); | 99 | long pos = posrelat(luaL_opt_long(L, 2, 1), l); |
95 | luaL_arg_check(L, 0<pos && (size_t)pos<=l, 2, "out of range"); | 100 | luaL_arg_check(L, 0<pos && (size_t)pos<=l, 2, "out of range"); |
96 | lua_pushnumber(L, (unsigned char)s[pos-1]); | 101 | lua_pushnumber(L, (unsigned char)s[pos-1]); |
102 | return 1; | ||
97 | } | 103 | } |
98 | 104 | ||
99 | 105 | ||
100 | static void str_char (lua_State *L) { | 106 | static int str_char (lua_State *L) { |
101 | int i = 0; | 107 | int n = lua_gettop(L); /* number of arguments */ |
108 | int i; | ||
102 | luaL_resetbuffer(L); | 109 | luaL_resetbuffer(L); |
103 | while (lua_getparam(L, ++i) != LUA_NOOBJECT) { | 110 | for (i=1; i<=n; i++) { |
104 | int c = luaL_check_int(L, i); | 111 | int c = luaL_check_int(L, i); |
105 | luaL_arg_check(L, (unsigned char)c == c, i, "invalid value"); | 112 | luaL_arg_check(L, (unsigned char)c == c, i, "invalid value"); |
106 | luaL_addchar(L, (unsigned char)c); | 113 | luaL_addchar(L, (unsigned char)c); |
107 | } | 114 | } |
108 | closeandpush(L); | 115 | closeandpush(L); |
116 | return 1; | ||
109 | } | 117 | } |
110 | 118 | ||
111 | 119 | ||
@@ -135,16 +143,6 @@ struct Capture { | |||
135 | #define SPECIALS "^$*+?.([%-" | 143 | #define SPECIALS "^$*+?.([%-" |
136 | 144 | ||
137 | 145 | ||
138 | static void push_captures (lua_State *L, struct Capture *cap) { | ||
139 | int i; | ||
140 | for (i=0; i<cap->level; i++) { | ||
141 | int l = cap->capture[i].len; | ||
142 | if (l == -1) lua_error(L, "unfinished capture"); | ||
143 | lua_pushlstring(L, cap->capture[i].init, l); | ||
144 | } | ||
145 | } | ||
146 | |||
147 | |||
148 | static int check_capture (lua_State *L, int l, struct Capture *cap) { | 146 | static int check_capture (lua_State *L, int l, struct Capture *cap) { |
149 | l -= '1'; | 147 | l -= '1'; |
150 | if (!(0 <= l && l < cap->level && cap->capture[l].len != -1)) | 148 | if (!(0 <= l && l < cap->level && cap->capture[l].len != -1)) |
@@ -400,20 +398,31 @@ static const char *lmemfind (const char *s1, size_t l1, | |||
400 | } | 398 | } |
401 | 399 | ||
402 | 400 | ||
403 | static void str_find (lua_State *L) { | 401 | static int push_captures (lua_State *L, struct Capture *cap) { |
402 | int i; | ||
403 | for (i=0; i<cap->level; i++) { | ||
404 | int l = cap->capture[i].len; | ||
405 | if (l == -1) lua_error(L, "unfinished capture"); | ||
406 | lua_pushlstring(L, cap->capture[i].init, l); | ||
407 | } | ||
408 | return cap->level; /* number of strings pushed */ | ||
409 | } | ||
410 | |||
411 | |||
412 | static int str_find (lua_State *L) { | ||
404 | size_t l1, l2; | 413 | size_t l1, l2; |
405 | const char *s = luaL_check_lstr(L, 1, &l1); | 414 | const char *s = luaL_check_lstr(L, 1, &l1); |
406 | const char *p = luaL_check_lstr(L, 2, &l2); | 415 | const char *p = luaL_check_lstr(L, 2, &l2); |
407 | long init = posrelat(luaL_opt_long(L, 3, 1), l1) - 1; | 416 | long init = posrelat(luaL_opt_long(L, 3, 1), l1) - 1; |
408 | struct Capture cap; | 417 | struct Capture cap; |
409 | luaL_arg_check(L, 0 <= init && (size_t)init <= l1, 3, "out of range"); | 418 | luaL_arg_check(L, 0 <= init && (size_t)init <= l1, 3, "out of range"); |
410 | if (lua_getparam(L, 4) != LUA_NOOBJECT || | 419 | if (lua_gettop(L) > 3 || /* extra argument? */ |
411 | strpbrk(p, SPECIALS) == NULL) { /* no special characters? */ | 420 | strpbrk(p, SPECIALS) == NULL) { /* or no special characters? */ |
412 | const char *s2 = lmemfind(s+init, l1-init, p, l2); | 421 | const char *s2 = lmemfind(s+init, l1-init, p, l2); |
413 | if (s2) { | 422 | if (s2) { |
414 | lua_pushnumber(L, s2-s+1); | 423 | lua_pushnumber(L, s2-s+1); |
415 | lua_pushnumber(L, s2-s+l2); | 424 | lua_pushnumber(L, s2-s+l2); |
416 | return; | 425 | return 2; |
417 | } | 426 | } |
418 | } | 427 | } |
419 | else { | 428 | else { |
@@ -426,19 +435,19 @@ static void str_find (lua_State *L) { | |||
426 | if ((res=match(L, s1, p, &cap)) != NULL) { | 435 | if ((res=match(L, s1, p, &cap)) != NULL) { |
427 | lua_pushnumber(L, s1-s+1); /* start */ | 436 | lua_pushnumber(L, s1-s+1); /* start */ |
428 | lua_pushnumber(L, res-s); /* end */ | 437 | lua_pushnumber(L, res-s); /* end */ |
429 | push_captures(L, &cap); | 438 | return push_captures(L, &cap) + 2; |
430 | return; | ||
431 | } | 439 | } |
432 | } while (s1++<cap.src_end && !anchor); | 440 | } while (s1++<cap.src_end && !anchor); |
433 | } | 441 | } |
434 | lua_pushnil(L); /* not found */ | 442 | lua_pushnil(L); /* not found */ |
443 | return 1; | ||
435 | } | 444 | } |
436 | 445 | ||
437 | 446 | ||
438 | static void add_s (lua_State *L, lua_Object newp, struct Capture *cap) { | 447 | static void add_s (lua_State *L, struct Capture *cap) { |
439 | if (lua_isstring(L, newp)) { | 448 | if (lua_isstring(L, 3)) { |
440 | const char *news = lua_getstring(L, newp); | 449 | const char *news = lua_tostring(L, 3); |
441 | size_t l = lua_strlen(L, newp); | 450 | size_t l = lua_strlen(L, 3); |
442 | size_t i; | 451 | size_t i; |
443 | for (i=0; i<l; i++) { | 452 | for (i=0; i<l; i++) { |
444 | if (news[i] != ESC) | 453 | if (news[i] != ESC) |
@@ -455,39 +464,38 @@ static void add_s (lua_State *L, lua_Object newp, struct Capture *cap) { | |||
455 | } | 464 | } |
456 | } | 465 | } |
457 | else { /* is a function */ | 466 | else { /* is a function */ |
458 | lua_Object res; | ||
459 | int status; | 467 | int status; |
460 | size_t oldbuff; | 468 | size_t oldbuff; |
461 | lua_beginblock(L); | 469 | int n; |
462 | push_captures(L, cap); | 470 | const char *s; |
471 | lua_pushobject(L, 3); | ||
472 | n = push_captures(L, cap); | ||
463 | /* function may use buffer, so save it and create a new one */ | 473 | /* function may use buffer, so save it and create a new one */ |
464 | oldbuff = luaL_newbuffer(L, 0); | 474 | oldbuff = luaL_newbuffer(L, 0); |
465 | status = lua_callfunction(L, newp); | 475 | status = lua_call(L, n, 1); |
466 | /* restore old buffer */ | 476 | /* restore old buffer */ |
467 | luaL_oldbuffer(L, oldbuff); | 477 | luaL_oldbuffer(L, oldbuff); |
468 | if (status != 0) { | 478 | if (status != 0) |
469 | lua_endblock(L); | ||
470 | lua_error(L, NULL); | 479 | lua_error(L, NULL); |
471 | } | 480 | s = lua_tostring(L, -1); |
472 | res = lua_getresult(L, 1); | 481 | if (s) |
473 | if (lua_isstring(L, res)) | 482 | addnchar(L, lua_tostring(L, -1), lua_strlen(L, -1)); |
474 | addnchar(L, lua_getstring(L, res), lua_strlen(L, res)); | 483 | lua_settop(L, -1); /* pop function result */ |
475 | lua_endblock(L); | ||
476 | } | 484 | } |
477 | } | 485 | } |
478 | 486 | ||
479 | 487 | ||
480 | static void str_gsub (lua_State *L) { | 488 | static int str_gsub (lua_State *L) { |
481 | size_t srcl; | 489 | size_t srcl; |
482 | const char *src = luaL_check_lstr(L, 1, &srcl); | 490 | const char *src = luaL_check_lstr(L, 1, &srcl); |
483 | const char *p = luaL_check_string(L, 2); | 491 | const char *p = luaL_check_string(L, 2); |
484 | lua_Object newp = lua_getparam(L, 3); | ||
485 | int max_s = luaL_opt_int(L, 4, srcl+1); | 492 | int max_s = luaL_opt_int(L, 4, srcl+1); |
486 | int anchor = (*p == '^') ? (p++, 1) : 0; | 493 | int anchor = (*p == '^') ? (p++, 1) : 0; |
487 | int n = 0; | 494 | int n = 0; |
488 | struct Capture cap; | 495 | struct Capture cap; |
489 | luaL_arg_check(L, lua_isstring(L, newp) || lua_isfunction(L, newp), 3, | 496 | luaL_arg_check(L, |
490 | "string or function expected"); | 497 | lua_gettop(L) >= 3 && (lua_isstring(L, 3) || lua_isfunction(L, 3)), |
498 | 3, "string or function expected"); | ||
491 | luaL_resetbuffer(L); | 499 | luaL_resetbuffer(L); |
492 | cap.src_end = src+srcl; | 500 | cap.src_end = src+srcl; |
493 | while (n < max_s) { | 501 | while (n < max_s) { |
@@ -496,7 +504,7 @@ static void str_gsub (lua_State *L) { | |||
496 | e = match(L, src, p, &cap); | 504 | e = match(L, src, p, &cap); |
497 | if (e) { | 505 | if (e) { |
498 | n++; | 506 | n++; |
499 | add_s(L, newp, &cap); | 507 | add_s(L, &cap); |
500 | } | 508 | } |
501 | if (e && e>src) /* non empty match? */ | 509 | if (e && e>src) /* non empty match? */ |
502 | src = e; /* skip it */ | 510 | src = e; /* skip it */ |
@@ -508,6 +516,7 @@ static void str_gsub (lua_State *L) { | |||
508 | addnchar(L, src, cap.src_end-src); | 516 | addnchar(L, src, cap.src_end-src); |
509 | closeandpush(L); | 517 | closeandpush(L); |
510 | lua_pushnumber(L, n); /* number of substitutions */ | 518 | lua_pushnumber(L, n); /* number of substitutions */ |
519 | return 2; | ||
511 | } | 520 | } |
512 | 521 | ||
513 | /* }====================================================== */ | 522 | /* }====================================================== */ |
@@ -534,7 +543,7 @@ static void luaI_addquoted (lua_State *L, int arg) { | |||
534 | /* maximum size of each format specification (such as '%-099.99d') */ | 543 | /* maximum size of each format specification (such as '%-099.99d') */ |
535 | #define MAX_FORMAT 20 /* arbitrary limit */ | 544 | #define MAX_FORMAT 20 /* arbitrary limit */ |
536 | 545 | ||
537 | static void str_format (lua_State *L) { | 546 | static int str_format (lua_State *L) { |
538 | int arg = 1; | 547 | int arg = 1; |
539 | const char *strfrmt = luaL_check_string(L, arg); | 548 | const char *strfrmt = luaL_check_string(L, arg); |
540 | luaL_resetbuffer(L); | 549 | luaL_resetbuffer(L); |
@@ -597,6 +606,7 @@ static void str_format (lua_State *L) { | |||
597 | } | 606 | } |
598 | } | 607 | } |
599 | closeandpush(L); /* push the result */ | 608 | closeandpush(L); /* push the result */ |
609 | return 1; | ||
600 | } | 610 | } |
601 | 611 | ||
602 | 612 | ||