aboutsummaryrefslogtreecommitdiff
path: root/lpcap.c
diff options
context:
space:
mode:
Diffstat (limited to 'lpcap.c')
-rw-r--r--lpcap.c24
1 files changed, 23 insertions, 1 deletions
diff --git a/lpcap.c b/lpcap.c
index ec17d23..4750f01 100644
--- a/lpcap.c
+++ b/lpcap.c
@@ -231,6 +231,22 @@ static int functioncap (CapState *cs) {
231 231
232 232
233/* 233/*
234** Accumulator capture
235*/
236static int accumulatorcap (CapState *cs) {
237 lua_State *L = cs->L;
238 int n;
239 if (lua_gettop(L) < cs->firstcap)
240 luaL_error(L, "no previous value for accumulator capture");
241 pushluaval(cs); /* push function */
242 lua_insert(L, -2); /* previous value becomes first argument */
243 n = pushnestedvalues(cs, 0); /* push nested captures */
244 lua_call(L, n + 1, 1); /* call function */
245 return 0; /* did not add any extra value */
246}
247
248
249/*
234** Select capture 250** Select capture
235*/ 251*/
236static int numcap (CapState *cs) { 252static int numcap (CapState *cs) {
@@ -422,13 +438,16 @@ static int addonestring (luaL_Buffer *b, CapState *cs, const char *what) {
422 case Csubst: 438 case Csubst:
423 substcap(b, cs); /* add capture directly to buffer */ 439 substcap(b, cs); /* add capture directly to buffer */
424 return 1; 440 return 1;
441 case Cacc: /* accumulator capture? */
442 return luaL_error(cs->L, "accumulator capture inside substitution capture");
425 default: { 443 default: {
426 lua_State *L = cs->L; 444 lua_State *L = cs->L;
427 int n = pushcapture(cs); 445 int n = pushcapture(cs);
428 if (n > 0) { 446 if (n > 0) {
429 if (n > 1) lua_pop(L, n - 1); /* only one result */ 447 if (n > 1) lua_pop(L, n - 1); /* only one result */
430 if (!lua_isstring(L, -1)) 448 if (!lua_isstring(L, -1))
431 luaL_error(L, "invalid %s value (a %s)", what, luaL_typename(L, -1)); 449 return luaL_error(L, "invalid %s value (a %s)",
450 what, luaL_typename(L, -1));
432 luaL_addvalue(b); 451 luaL_addvalue(b);
433 } 452 }
434 return n; 453 return n;
@@ -512,6 +531,7 @@ static int pushcapture (CapState *cs) {
512 case Cbackref: res = backrefcap(cs); break; 531 case Cbackref: res = backrefcap(cs); break;
513 case Ctable: res = tablecap(cs); break; 532 case Ctable: res = tablecap(cs); break;
514 case Cfunction: res = functioncap(cs); break; 533 case Cfunction: res = functioncap(cs); break;
534 case Cacc: res = accumulatorcap(cs); break;
515 case Cnum: res = numcap(cs); break; 535 case Cnum: res = numcap(cs); break;
516 case Cquery: res = querycap(cs); break; 536 case Cquery: res = querycap(cs); break;
517 case Cfold: res = foldcap(cs); break; 537 case Cfold: res = foldcap(cs); break;
@@ -537,9 +557,11 @@ int getcaptures (lua_State *L, const char *s, const char *r, int ptop) {
537 CapState cs; 557 CapState cs;
538 cs.ocap = cs.cap = capture; cs.L = L; cs.reclevel = 0; 558 cs.ocap = cs.cap = capture; cs.L = L; cs.reclevel = 0;
539 cs.s = s; cs.valuecached = 0; cs.ptop = ptop; 559 cs.s = s; cs.valuecached = 0; cs.ptop = ptop;
560 cs.firstcap = lua_gettop(L) + 1; /* where first value (if any) will go */
540 do { /* collect their values */ 561 do { /* collect their values */
541 n += pushcapture(&cs); 562 n += pushcapture(&cs);
542 } while (!isclosecap(cs.cap)); 563 } while (!isclosecap(cs.cap));
564 assert(lua_gettop(L) - cs.firstcap == n - 1);
543 } 565 }
544 if (n == 0) { /* no capture values? */ 566 if (n == 0) { /* no capture values? */
545 lua_pushinteger(L, r - s + 1); /* return only end position */ 567 lua_pushinteger(L, r - s + 1); /* return only end position */