diff options
| -rw-r--r-- | README.md | 1 | ||||
| -rw-r--r-- | regc_lex.c | 1 | ||||
| -rw-r--r-- | regex.h | 3 | ||||
| -rw-r--r-- | regexec.c | 6 | ||||
| -rwxr-xr-x | regtest_terex.sh | 117 |
5 files changed, 80 insertions, 48 deletions
@@ -20,6 +20,7 @@ Compared to hsrex, this library has the following changes: You no longer need to compile a special version of the library. It expects Unicode strings by default unless specifying the `REG_RAW` `tere_comp()` compilation flag. +* Support the `REG_ANCHORED` flag for `tere_exec()`. ## TODO @@ -322,6 +322,7 @@ next( /* * REG_BOSONLY + * FIXME: Let this be handled by REG_ANCHORED during execution as well? */ if (v->nexttype == EMPTY && (v->cflags®_BOSONLY)) { @@ -230,7 +230,7 @@ typedef struct { #define REG_DUMP 004000 /* none of your business :-) */ #define REG_FAKE 010000 /* none of your business :-) */ #define REG_PROGRESS 020000 /* none of your business :-) */ -#define REG_RAW 040000 /* pattern and subject are raw ASCII */ +#define REG_RAW 040000 /* pattern and subject are raw bytes */ /* * execution @@ -252,6 +252,7 @@ typedef struct { #define REG_FTRACE 0010 /* none of your business */ #define REG_MTRACE 0020 /* none of your business */ #define REG_SMALL 0040 /* none of your business */ +#define REG_ANCHORED 0100 /* match anchored (see also REG_BOSONLY) */ /* * misc generics (may be more functions here eventually) @@ -415,6 +415,9 @@ find( if (end != NULL) { break; /* NOTE BREAK OUT */ } + if (v->eflags & REG_ANCHORED) { + break; /* NOTE BREAK OUT */ + } } assert(end != NULL); /* search RE succeeded so loop should */ freedfa(d); @@ -578,6 +581,9 @@ cfindloop( estop = prevchr(v, end); } } + if (v->eflags & REG_ANCHORED) { + break; /* NOTE BREAK OUT */ + } } } while (close < v->stop); diff --git a/regtest_terex.sh b/regtest_terex.sh index 75e051b..930867d 100755 --- a/regtest_terex.sh +++ b/regtest_terex.sh @@ -72,6 +72,7 @@ cat<<-EOF>$rgsrc #include <stdio.h> #include <stdlib.h> #include <string.h> + #include <unistd.h> #include "regalone.h" #include "regex.h" size_t hexescapes2bin(unsigned char *t, char *src, size_t mxlen) @@ -100,16 +101,27 @@ cat<<-EOF>$rgsrc size_t relen, datlen; regex_t cre; regmatch_t pmatch[100]; - int cflags, nmatch, rc; + int nmatch, rc, ch; + int cflags = REG_ADVANCED, eflags = 0; char buf[1024*2]; //memset(&cre, '\0', sizeof(cre)); - nmatch = atoi(argv[2]); - relen = hexescapes2bin(re, argv[3], sizeof(re)/sizeof(char)); - datlen = hexescapes2bin(dat, argv[4], sizeof(dat)/sizeof(char)); - cflags = REG_ADVANCED | (nmatch ? 0 : REG_NOSUB); - if ( atoi(argv[1]) != 0 ) cflags |= REG_RAW; - rc = re_comp(&cre, re, relen, cflags); + + while ((ch = getopt(argc, argv, "raA")) != -1) { + switch (ch) { + case 'r': cflags |= REG_RAW; break; + case 'a': cflags |= REG_BOSONLY; break; + case 'A': eflags |= REG_ANCHORED; break; + } + } + argc -= optind; + argv += optind; + + nmatch = atoi(argv[0]); + if (!nmatch) cflags |= REG_NOSUB; + relen = hexescapes2bin(re, argv[1], sizeof(re)/sizeof(char)); + datlen = hexescapes2bin(dat, argv[2], sizeof(dat)/sizeof(char)); + rc = tere_comp(&cre, re, relen, cflags); if ( rc != REG_OKAY ) { regerror(rc, &cre, buf, sizeof(buf)); @@ -124,7 +136,7 @@ cat<<-EOF>$rgsrc nmatch, cre.re_nsub); return 1; } - rc = re_exec(&cre, dat, datlen, NULL, 100, pmatch, 0); + rc = tere_exec(&cre, dat, datlen, NULL, 100, pmatch, eflags); if ( rc != REG_OKAY ) { regerror(rc, &cre, buf, sizeof(buf)); @@ -140,7 +152,7 @@ cat<<-EOF>$rgsrc sprintf(&buf[strlen(buf)], "%s%.*s", i>1 ? ":" : "", (int)(pmatch[i].rm_eo-pmatch[i].rm_so), - argv[4]+pmatch[i].rm_so); + argv[2]+pmatch[i].rm_so); printf("%s\n", buf); } regfree(&cre); @@ -153,69 +165,73 @@ export PATH LD_LIBRARY_PATH $CC -Wall -g -O0 -I. -I$H/inc -L. -lterex -o $rgbin $rgsrc #----------------------------------- msg="Simple match" -resp=`$rgbin 0 0 "clavo" "Pablito clavo un clavito" 2>&1` +resp=`$rgbin 0 "clavo" "Pablito clavo un clavito" 2>&1` test -z "$resp" && f_ok "$msg" || f_no "$msg" "$resp" -resp=`$rgbin 1 0 "clavo" "Pablito clavo un clavito" 2>&1` +resp=`$rgbin -r 0 "clavo" "Pablito clavo un clavito" 2>&1` test -z "$resp" && f_ok "$msg (raw)" || f_no "$msg (raw)" "$resp" #----------------------------------- msg="yyyy-mm-dd between 1900-01-01 and 2099-12-31" -resp=`$rgbin 0 0 \ +resp=`$rgbin 0 \ "(19|20)\d\d[- /.](0[1-9]|1[012])[- /.](0[1-9]|[12][0-9]|3[01])" \ "1960-10-12" 2>&1` test -z "$resp" && f_ok "$msg" || f_no "$msg" "$resp" -resp=`$rgbin 1 0 \ +resp=`$rgbin -r 0 \ "(19|20)\d\d[- /.](0[1-9]|1[012])[- /.](0[1-9]|[12][0-9]|3[01])" \ "1960-10-12" 2>&1` test -z "$resp" && f_ok "$msg (raw)" || f_no "$msg (raw)" "$resp" #----------------------------------- msg="yyyy-mm-dd out of 1900-01-01 and 2099-12-31" -resp=`$rgbin 0 0 \ +resp=`$rgbin 0 \ "(19|20)\d\d[- /.](0[1-9]|1[012])[- /.](0[1-9]|[12][0-9]|3[01])" \ "El arzobispo 1960-14-12 de Constantinopla" 2>&1` if echo "$resp"|grep "failed to match">/dev/null; then f_ok "$msg"; else f_no "$msg" "$resp"; fi -resp=`$rgbin 1 0 \ +resp=`$rgbin -r 0 \ "(19|20)\d\d[- /.](0[1-9]|1[012])[- /.](0[1-9]|[12][0-9]|3[01])" \ "El arzobispo 1960-14-12 de Constantinopla" 2>&1` if echo "$resp"|grep "failed to match">/dev/null; then f_ok "$msg (raw)"; else f_no "$msg (raw)" "$resp"; fi #----------------------------------- msg="1..999" -resp=`$rgbin 0 0 "^([1-9]|[1-9][0-9]|[1-9][0-9][0-9])$" "432" 2>&1` +resp=`$rgbin 0 "^([1-9]|[1-9][0-9]|[1-9][0-9][0-9])$" "432" 2>&1` test -z "$resp" && f_ok "$msg" || f_no "$msg" "$resp" -resp=`$rgbin 1 0 "^([1-9]|[1-9][0-9]|[1-9][0-9][0-9])$" "432" 2>&1` +resp=`$rgbin -r 0 "^([1-9]|[1-9][0-9]|[1-9][0-9][0-9])$" "432" 2>&1` test -z "$resp" && f_ok "$msg (raw)" || f_no "$msg (raw)" "$resp" #----------------------------------- msg="Bad 1..999" -resp=`$rgbin 0 0 "^([1-9]|[1-9][0-9]|[1-9][0-9][0-9])$" " 4321" 2>&1` +resp=`$rgbin 0 "^([1-9]|[1-9][0-9]|[1-9][0-9][0-9])$" " 4321" 2>&1` if echo "$resp"|grep "failed to match">/dev/null; then f_ok "$msg"; else f_no "$msg" "$resp"; fi -resp=`$rgbin 1 0 "^([1-9]|[1-9][0-9]|[1-9][0-9][0-9])$" " 4321" 2>&1` +resp=`$rgbin -r 0 "^([1-9]|[1-9][0-9]|[1-9][0-9][0-9])$" " 4321" 2>&1` if echo "$resp"|grep "failed to match">/dev/null; then f_ok "$msg (raw)"; else f_no "$msg (raw)" "$resp"; fi #----------------------------------- msg="Quantifier: One to three words between 'word1' and 'word2'" -resp=`$rgbin 0 0 "word1\W+(?:\w+\W+){1,3}?word2" \ - "word1 clavo un clavito word2" 2>&1` +resp=`$rgbin 0 \ + "word1\W+(?:\w+\W+){1,3}?word2" \ + "word1 clavo un clavito word2" 2>&1` test -z "$resp" && f_ok "$msg" || f_no "$msg" "$resp" -resp=`$rgbin 1 0 "word1\W+(?:\w+\W+){1,3}?word2" \ - "word1 clavo un clavito word2" 2>&1` +resp=`$rgbin -r 0 \ + "word1\W+(?:\w+\W+){1,3}?word2" \ + "word1 clavo un clavito word2" 2>&1` test -z "$resp" && f_ok "$msg (raw)" || f_no "$msg (raw)" "$resp" #----------------------------------- msg="Pathological: a?^6a^15 against aaaaaaaaaaaaaaaaaa..." -resp=`$rgbin 0 0 "a?a?a?a?a?aaaaaaaaaaaaaaa" \ - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" 2>&1` +resp=`$rgbin 0 \ + "a?a?a?a?a?aaaaaaaaaaaaaaa" \ + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" 2>&1` test -z "$resp" && f_ok "$msg" || f_no "$msg" "$resp" -resp=`$rgbin 1 0 "a?a?a?a?a?aaaaaaaaaaaaaaa" \ - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" 2>&1` +resp=`$rgbin -r 0 \ + "a?a?a?a?a?aaaaaaaaaaaaaaa" \ + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" 2>&1` test -z "$resp" && f_ok "$msg (raw)" || f_no "$msg (raw)" "$resp" #----------------------------------- msg="Pathological: (a|aa)*b against aaaaaaaaaaaaaaaaaa...b" -resp=`$rgbin 0 0 "(a|aa)*b" \ - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaab" 2>&1` +resp=`$rgbin 0 \ + "(a|aa)*b" "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaab" 2>&1` test -z "$resp" && f_ok "$msg" || f_no "$msg" "$resp" -resp=`$rgbin 1 0 "(a|aa)*b" \ - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaab" 2>&1` +resp=`$rgbin -r 0 \ + "(a|aa)*b" "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaab" 2>&1` test -z "$resp" && f_ok "$msg (raw)" || f_no "$msg (raw)" "$resp" #----------------------------------- cat<<-EOF>$datsrc @@ -263,9 +279,9 @@ while test $i -lt 5; do i=`expr $i + 1` done msg="5 group patterns taken with bracket ranges" -resp=`$rgbin 0 5 "$totre" "$totdat" 2>&1` +resp=`$rgbin 5 "$totre" "$totdat" 2>&1` test "$resp" = "$expectedresp" && f_ok "$msg" || f_no "$msg" "$resp" -resp=`$rgbin 1 5 "$totre" "$totdat" 2>&1` +resp=`$rgbin -r 5 "$totre" "$totdat" 2>&1` test "$resp" = "$expectedresp" && f_ok "$msg (raw)" || f_no "$msg (raw)" "$resp" #----------------------------------- i=0 @@ -280,9 +296,9 @@ while test $i -lt 10; do i=`expr $i + 1` done msg="10 group patterns taken with bracket ranges" -resp=`$rgbin 0 10 "$totre" "$totdat" 2>&1` +resp=`$rgbin 10 "$totre" "$totdat" 2>&1` test "$resp" = "$expectedresp" && f_ok "$msg" || f_no "$msg" "$resp" -resp=`$rgbin 1 10 "$totre" "$totdat" 2>&1` +resp=`$rgbin -r 10 "$totre" "$totdat" 2>&1` test "$resp" = "$expectedresp" && f_ok "$msg (raw)" || f_no "$msg (raw)" "$resp" #----------------------------------- i=0 @@ -297,9 +313,9 @@ while test $i -lt 99; do i=`expr $i + 1` done msg="99 group patterns taken with bracket ranges" -resp=`$rgbin 0 99 "$totre" "$totdat" 2>&1` +resp=`$rgbin 99 "$totre" "$totdat" 2>&1` test "$resp" = "$expectedresp" && f_ok "$msg" || f_no "$msg" "$resp" -resp=`$rgbin 1 99 "$totre" "$totdat" 2>&1` +resp=`$rgbin -r 99 "$totre" "$totdat" 2>&1` test "$resp" = "$expectedresp" && f_ok "$msg (raw)" || f_no "$msg (raw)" "$resp" #----------------------------------- i=0 @@ -314,34 +330,41 @@ while test $i -lt 99; do i=`expr $i + 1` done msg="99 group patterns taken with character classes" -resp=`$rgbin 0 99 "$totre" "$totdat" 2>&1` +resp=`$rgbin 99 "$totre" "$totdat" 2>&1` test "$resp" = "$expectedresp" && f_ok "$msg" || f_no "$msg" "$resp" -resp=`$rgbin 1 99 "$totre" "$totdat" 2>&1` +resp=`$rgbin -r 99 "$totre" "$totdat" 2>&1` test "$resp" = "$expectedresp" && f_ok "$msg (raw)" || f_no "$msg (raw)" "$resp" #----------------------------------- msg="Binary data" -resp=`$rgbin 0 0 "clavo" $'Pablito\01clavo un clavito' 2>&1` +resp=`$rgbin 0 "clavo" $'Pablito\01clavo un clavito' 2>&1` test -z "$resp" && f_ok "$msg" || f_no "$msg" "$resp" -resp=`$rgbin 1 0 "clavo" $'Pablito\01clavo un clavito' 2>&1` +resp=`$rgbin -r 0 "clavo" $'Pablito\01clavo un clavito' 2>&1` test -z "$resp" && f_ok "$msg (raw)" || f_no "$msg (raw)" "$resp" #----------------------------------- msg="Binary RE and data" -resp=`$rgbin 0 0 $'cl\xFFavo' $'Pablito\x01cl\xFFavo un clavito' 2>&1` +resp=`$rgbin 0 $'cl\xFFavo' $'Pablito\x01cl\xFFavo un clavito' 2>&1` test -z "$resp" && f_ok "$msg" || f_no "$msg" "$resp" -resp=`$rgbin 1 0 $'cl\xFFavo' $'Pablito\x01cl\xFFavo un clavito' 2>&1` +resp=`$rgbin -r 0 $'cl\xFFavo' $'Pablito\x01cl\xFFavo un clavito' 2>&1` test -z "$resp" && f_ok "$msg (raw)" || f_no "$msg (raw)" "$resp" #----------------------------------- msg="One group pattern with case-insensitive matching" -resp=`$rgbin 0 1 "(?i)(clavo)" "Pablito ClAvO un clavito" 2>&1` +resp=`$rgbin 1 "(?i)(clavo)" "Pablito ClAvO un clavito" 2>&1` test "$resp" = "ClAvO" && f_ok "$msg" || f_no "$msg" "$resp" -resp=`$rgbin 1 1 "(?i)(clavo)" "Pablito ClAvO un clavito" 2>&1` +resp=`$rgbin -r 1 "(?i)(clavo)" "Pablito ClAvO un clavito" 2>&1` test "$resp" = "ClAvO" && f_ok "$msg (raw)" || f_no "$msg" "$resp (raw)" #----------------------------------- -resp=`$rgbin 1 1 $'([\x01\x5F\xFF]+)' $'ABC\x5F' 2>&1` +resp=`$rgbin -r 1 $'([\x01\x5F\xFF]+)' $'ABC\x5F' 2>&1` msg="Raw character class" test "$resp" = $'\x5F' && f_ok "$msg" || f_no "$msg" "$resp" #----------------------------------- -resp=`$rgbin 0 1 '([[:alpha:]]+)' 'абвгд' 2>&1` +resp=`$rgbin 1 '([[:alpha:]]+)' 'абвгд' 2>&1` msg="Unicode character class" test "$resp" = "абвгд" && f_ok "$msg" || f_no "$msg" "$resp" #----------------------------------- +resp=`$rgbin -A 0 'ABC' 'blablaABC' 2>&1` +msg="Anchored search (failure)" +test -z "$resp" && f_ok "$msg" || f_no "$msg" "$resp" +resp=`$rgbin -A 1 '(ABC)' 'ABCblablaABC' 2>&1` +msg="Anchored search (success)" +test "$resp" = "ABC" && f_ok "$msg" || f_no "$msg" "$resp" +#----------------------------------- |
