aboutsummaryrefslogtreecommitdiff
path: root/lpcap.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2023-06-07 15:41:01 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2023-06-07 15:41:01 -0300
commitcf1705c1d96b549ef5887a2bc3038dbc31912e50 (patch)
tree98d37b61c4f095b089fa40e55032e0479932be6c /lpcap.c
parente31e13f59ef1a4df1698b15ff1fe0198553cc3c2 (diff)
downloadlpeg-cf1705c1d96b549ef5887a2bc3038dbc31912e50.tar.gz
lpeg-cf1705c1d96b549ef5887a2bc3038dbc31912e50.tar.bz2
lpeg-cf1705c1d96b549ef5887a2bc3038dbc31912e50.zip
Captures point to string positions using indices
That uses 4 bytes (uint) instead of 8 (char*); the size of the structure 'Capture' reduces from 16 to 8 bytes in 64-bit machines.
Diffstat (limited to 'lpcap.c')
-rw-r--r--lpcap.c26
1 files changed, 15 insertions, 11 deletions
diff --git a/lpcap.c b/lpcap.c
index 4750f01..d17a47a 100644
--- a/lpcap.c
+++ b/lpcap.c
@@ -10,7 +10,7 @@
10 10
11#define isclosecap(cap) (captype(cap) == Cclose) 11#define isclosecap(cap) (captype(cap) == Cclose)
12 12
13#define closeaddr(c) ((c)->s + (c)->siz - 1) 13#define closeaddr(cs,c) ((cs)->s + (c)->index + (c)->siz - 1)
14 14
15#define isfullcap(cap) ((cap)->siz != 0) 15#define isfullcap(cap) ((cap)->siz != 0)
16 16
@@ -82,7 +82,8 @@ static void nextcap (CapState *cs) {
82static int pushnestedvalues (CapState *cs, int addextra) { 82static int pushnestedvalues (CapState *cs, int addextra) {
83 Capture *co = cs->cap; 83 Capture *co = cs->cap;
84 if (isfullcap(cs->cap++)) { /* no nested captures? */ 84 if (isfullcap(cs->cap++)) { /* no nested captures? */
85 lua_pushlstring(cs->L, co->s, co->siz - 1); /* push whole match */ 85 /* push whole match */
86 lua_pushlstring(cs->L, cs->s + co->index, co->siz - 1);
86 return 1; /* that is it */ 87 return 1; /* that is it */
87 } 88 }
88 else { 89 else {
@@ -90,7 +91,8 @@ static int pushnestedvalues (CapState *cs, int addextra) {
90 while (!isclosecap(cs->cap)) /* repeat for all nested patterns */ 91 while (!isclosecap(cs->cap)) /* repeat for all nested patterns */
91 n += pushcapture(cs); 92 n += pushcapture(cs);
92 if (addextra || n == 0) { /* need extra? */ 93 if (addextra || n == 0) { /* need extra? */
93 lua_pushlstring(cs->L, co->s, cs->cap->s - co->s); /* push whole match */ 94 /* push whole match */
95 lua_pushlstring(cs->L, cs->s + co->index, cs->cap->index - co->index);
94 n++; 96 n++;
95 } 97 }
96 cs->cap++; /* skip close entry */ 98 cs->cap++; /* skip close entry */
@@ -295,7 +297,7 @@ int runtimecap (CapState *cs, Capture *close, const char *s, int *rem) {
295 assert(captype(open) == Cgroup); 297 assert(captype(open) == Cgroup);
296 id = finddyncap(open, close); /* get first dynamic capture argument */ 298 id = finddyncap(open, close); /* get first dynamic capture argument */
297 close->kind = Cclose; /* closes the group */ 299 close->kind = Cclose; /* closes the group */
298 close->s = s; 300 close->index = s - cs->s;
299 cs->cap = open; cs->valuecached = 0; /* prepare capture state */ 301 cs->cap = open; cs->valuecached = 0; /* prepare capture state */
300 luaL_checkstack(L, 4, "too many runtime captures"); 302 luaL_checkstack(L, 4, "too many runtime captures");
301 pushluaval(cs); /* push function to be called */ 303 pushluaval(cs); /* push function to be called */
@@ -342,7 +344,7 @@ typedef struct StrAux {
342static int getstrcaps (CapState *cs, StrAux *cps, int n) { 344static int getstrcaps (CapState *cs, StrAux *cps, int n) {
343 int k = n++; 345 int k = n++;
344 cps[k].isstring = 1; /* get string value */ 346 cps[k].isstring = 1; /* get string value */
345 cps[k].u.s.s = cs->cap->s; /* starts here */ 347 cps[k].u.s.s = cs->s + cs->cap->index; /* starts here */
346 if (!isfullcap(cs->cap++)) { /* nested captures? */ 348 if (!isfullcap(cs->cap++)) { /* nested captures? */
347 while (!isclosecap(cs->cap)) { /* traverse them */ 349 while (!isclosecap(cs->cap)) { /* traverse them */
348 if (n >= MAXSTRCAPS) /* too many captures? */ 350 if (n >= MAXSTRCAPS) /* too many captures? */
@@ -358,7 +360,7 @@ static int getstrcaps (CapState *cs, StrAux *cps, int n) {
358 } 360 }
359 cs->cap++; /* skip close */ 361 cs->cap++; /* skip close */
360 } 362 }
361 cps[k].u.s.e = closeaddr(cs->cap - 1); /* ends here */ 363 cps[k].u.s.e = closeaddr(cs, cs->cap - 1); /* ends here */
362 return n; 364 return n;
363} 365}
364 366
@@ -407,20 +409,21 @@ static void stringcap (luaL_Buffer *b, CapState *cs) {
407** Substitution capture: add result to buffer 'b' 409** Substitution capture: add result to buffer 'b'
408*/ 410*/
409static void substcap (luaL_Buffer *b, CapState *cs) { 411static void substcap (luaL_Buffer *b, CapState *cs) {
410 const char *curr = cs->cap->s; 412 const char *curr = cs->s + cs->cap->index;
411 if (isfullcap(cs->cap)) /* no nested captures? */ 413 if (isfullcap(cs->cap)) /* no nested captures? */
412 luaL_addlstring(b, curr, cs->cap->siz - 1); /* keep original text */ 414 luaL_addlstring(b, curr, cs->cap->siz - 1); /* keep original text */
413 else { 415 else {
414 cs->cap++; /* skip open entry */ 416 cs->cap++; /* skip open entry */
415 while (!isclosecap(cs->cap)) { /* traverse nested captures */ 417 while (!isclosecap(cs->cap)) { /* traverse nested captures */
416 const char *next = cs->cap->s; 418 const char *next = cs->s + cs->cap->index;
417 luaL_addlstring(b, curr, next - curr); /* add text up to capture */ 419 luaL_addlstring(b, curr, next - curr); /* add text up to capture */
418 if (addonestring(b, cs, "replacement")) 420 if (addonestring(b, cs, "replacement"))
419 curr = closeaddr(cs->cap - 1); /* continue after match */ 421 curr = closeaddr(cs, cs->cap - 1); /* continue after match */
420 else /* no capture value */ 422 else /* no capture value */
421 curr = next; /* keep original text in final result */ 423 curr = next; /* keep original text in final result */
422 } 424 }
423 luaL_addlstring(b, curr, cs->cap->s - curr); /* add last piece of text */ 425 /* add last piece of text */
426 luaL_addlstring(b, curr, cs->s + cs->cap->index - curr);
424 } 427 }
425 cs->cap++; /* go to next capture */ 428 cs->cap++; /* go to next capture */
426} 429}
@@ -473,7 +476,7 @@ static int pushcapture (CapState *cs) {
473 return luaL_error(L, "subcapture nesting too deep"); 476 return luaL_error(L, "subcapture nesting too deep");
474 switch (captype(cs->cap)) { 477 switch (captype(cs->cap)) {
475 case Cposition: { 478 case Cposition: {
476 lua_pushinteger(L, cs->cap->s - cs->s + 1); 479 lua_pushinteger(L, cs->cap->index + 1);
477 cs->cap++; 480 cs->cap++;
478 res = 1; 481 res = 1;
479 break; 482 break;
@@ -553,6 +556,7 @@ static int pushcapture (CapState *cs) {
553int getcaptures (lua_State *L, const char *s, const char *r, int ptop) { 556int getcaptures (lua_State *L, const char *s, const char *r, int ptop) {
554 Capture *capture = (Capture *)lua_touserdata(L, caplistidx(ptop)); 557 Capture *capture = (Capture *)lua_touserdata(L, caplistidx(ptop));
555 int n = 0; 558 int n = 0;
559 /* printcaplist(capture); */
556 if (!isclosecap(capture)) { /* is there any capture? */ 560 if (!isclosecap(capture)) { /* is there any capture? */
557 CapState cs; 561 CapState cs;
558 cs.ocap = cs.cap = capture; cs.L = L; cs.reclevel = 0; 562 cs.ocap = cs.cap = capture; cs.L = L; cs.reclevel = 0;