diff options
Diffstat (limited to 'lpcap.c')
-rw-r--r-- | lpcap.c | 24 |
1 files changed, 23 insertions, 1 deletions
@@ -231,6 +231,22 @@ static int functioncap (CapState *cs) { | |||
231 | 231 | ||
232 | 232 | ||
233 | /* | 233 | /* |
234 | ** Accumulator capture | ||
235 | */ | ||
236 | static 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 | */ |
236 | static int numcap (CapState *cs) { | 252 | static 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 */ |