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