diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2023-06-07 15:41:01 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2023-06-07 15:41:01 -0300 |
commit | cf1705c1d96b549ef5887a2bc3038dbc31912e50 (patch) | |
tree | 98d37b61c4f095b089fa40e55032e0479932be6c /lpcap.c | |
parent | e31e13f59ef1a4df1698b15ff1fe0198553cc3c2 (diff) | |
download | lpeg-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.c | 26 |
1 files changed, 15 insertions, 11 deletions
@@ -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) { | |||
82 | static int pushnestedvalues (CapState *cs, int addextra) { | 82 | static 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 { | |||
342 | static int getstrcaps (CapState *cs, StrAux *cps, int n) { | 344 | static 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 | */ |
409 | static void substcap (luaL_Buffer *b, CapState *cs) { | 411 | static 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) { | |||
553 | int getcaptures (lua_State *L, const char *s, const char *r, int ptop) { | 556 | int 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; |