aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2002-03-11 10:29:40 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2002-03-11 10:29:40 -0300
commitc97dc294a9db1645a96958dc8f2ab61783ad7a83 (patch)
tree576ce78b11b848f2edba5facc73f2521ac5a6a67
parent71c716e5a88a6993369505c79cd1383ef27366c4 (diff)
downloadlua-c97dc294a9db1645a96958dc8f2ab61783ad7a83.tar.gz
lua-c97dc294a9db1645a96958dc8f2ab61783ad7a83.tar.bz2
lua-c97dc294a9db1645a96958dc8f2ab61783ad7a83.zip
first implementation of `gfind'
-rw-r--r--lstrlib.c62
1 files changed, 53 insertions, 9 deletions
diff --git a/lstrlib.c b/lstrlib.c
index d1f5dcfb..7ad674bd 100644
--- a/lstrlib.c
+++ b/lstrlib.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lstrlib.c,v 1.1 2001/11/29 22:14:34 rieru Exp rieru $ 2** $Id: lstrlib.c,v 1.77 2002/02/08 22:39:36 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*/
@@ -434,12 +434,18 @@ static void push_onecapture (MatchState *ms, int i) {
434} 434}
435 435
436 436
437static int push_captures (MatchState *ms) { 437static int push_captures (MatchState *ms, const char *s, const char *e) {
438 int i; 438 int i;
439 luaL_check_stack(ms->L, ms->level, "too many captures"); 439 luaL_check_stack(ms->L, ms->level, "too many captures");
440 for (i=0; i<ms->level; i++) 440 if (ms->level == 0 && s) { /* no explicit captures? */
441 push_onecapture(ms, i); 441 lua_pushlstring(ms->L, s, e-s); /* return whole match */
442 return ms->level; /* number of strings pushed */ 442 return 1;
443 }
444 else { /* return all captures */
445 for (i=0; i<ms->level; i++)
446 push_onecapture(ms, i);
447 return ms->level; /* number of strings pushed */
448 }
443} 449}
444 450
445 451
@@ -472,7 +478,7 @@ static int str_find (lua_State *L) {
472 if ((res=match(&ms, s1, p)) != NULL) { 478 if ((res=match(&ms, s1, p)) != NULL) {
473 lua_pushnumber(L, s1-s+1); /* start */ 479 lua_pushnumber(L, s1-s+1); /* start */
474 lua_pushnumber(L, res-s); /* end */ 480 lua_pushnumber(L, res-s); /* end */
475 return push_captures(&ms) + 2; 481 return push_captures(&ms, NULL, 0) + 2;
476 } 482 }
477 } while (s1++<ms.src_end && !anchor); 483 } while (s1++<ms.src_end && !anchor);
478 } 484 }
@@ -481,7 +487,44 @@ static int str_find (lua_State *L) {
481} 487}
482 488
483 489
484static void add_s (MatchState *ms, luaL_Buffer *b) { 490static int gfind_aux (lua_State *L) {
491 MatchState ms;
492 const char *s = lua_tostring(L, lua_upvalueindex(1));
493 size_t ls = lua_strlen(L, lua_upvalueindex(1));
494 const char *p = lua_tostring(L, lua_upvalueindex(2));
495 const char *src;
496 ms.L = L;
497 ms.src_init = s;
498 ms.src_end = s+ls;
499 for (src = s + (size_t)lua_tonumber(L, lua_upvalueindex(3));
500 src <= ms.src_end;
501 src++) {
502 const char *e;
503 ms.level = 0;
504 if ((e = match(&ms, src, p)) != NULL) {
505 int newstart = e-s;
506 if (e == src) newstart++; /* empty match? go at least one position */
507 lua_pushnumber(L, newstart);
508 lua_replace(L, lua_upvalueindex(3));
509 return push_captures(&ms, src, e);
510 }
511 }
512 return 0; /* not found */
513}
514
515
516static int gfind (lua_State *L) {
517 luaL_check_string(L, 1);
518 luaL_check_string(L, 2);
519 lua_settop(L, 2);
520 lua_pushnumber(L, 0);
521 lua_pushcclosure(L, gfind_aux, 3);
522 return 1;
523}
524
525
526static void add_s (MatchState *ms, luaL_Buffer *b,
527 const char *s, const char *e) {
485 lua_State *L = ms->L; 528 lua_State *L = ms->L;
486 if (lua_isstring(L, 3)) { 529 if (lua_isstring(L, 3)) {
487 const char *news = lua_tostring(L, 3); 530 const char *news = lua_tostring(L, 3);
@@ -505,7 +548,7 @@ static void add_s (MatchState *ms, luaL_Buffer *b) {
505 else { /* is a function */ 548 else { /* is a function */
506 int n; 549 int n;
507 lua_pushvalue(L, 3); 550 lua_pushvalue(L, 3);
508 n = push_captures(ms); 551 n = push_captures(ms, s, e);
509 lua_rawcall(L, n, 1); 552 lua_rawcall(L, n, 1);
510 if (lua_isstring(L, -1)) 553 if (lua_isstring(L, -1))
511 luaL_addvalue(b); /* add return to accumulated result */ 554 luaL_addvalue(b); /* add return to accumulated result */
@@ -537,7 +580,7 @@ static int str_gsub (lua_State *L) {
537 e = match(&ms, src, p); 580 e = match(&ms, src, p);
538 if (e) { 581 if (e) {
539 n++; 582 n++;
540 add_s(&ms, &b); 583 add_s(&ms, &b, src, e);
541 } 584 }
542 if (e && e>src) /* non empty match? */ 585 if (e && e>src) /* non empty match? */
543 src = e; /* skip it */ 586 src = e; /* skip it */
@@ -674,6 +717,7 @@ static const luaL_reg strlib[] = {
674{"concat", str_concat}, 717{"concat", str_concat},
675{"format", str_format}, 718{"format", str_format},
676{"strfind", str_find}, 719{"strfind", str_find},
720{"gfind", gfind},
677{"gsub", str_gsub} 721{"gsub", str_gsub}
678}; 722};
679 723