Bring back test_regexp changes that were made when porting to Fossil. Also
fix some bugs that were introduced by the Fossil port. FossilOrigin-Name: 45c158b1a015e0295244982e7a61ecc55cca8436
This commit is contained in:
parent
953bf725b4
commit
26de1e9956
12
manifest
12
manifest
@ -1,5 +1,5 @@
|
||||
C Improvements\sto\scolumn\sname\sresolution\sin\squeries\swith\sparenthesized\sFROM\nclauses.\s\sAlso\sincludes\sa\sfix\sfor\sticket\s[beba9cae6345a3].
|
||||
D 2013-01-03T18:07:37.816
|
||||
C Bring\sback\stest_regexp\schanges\sthat\swere\smade\swhen\sporting\sto\sFossil.\s\sAlso\nfix\ssome\sbugs\sthat\swere\sintroduced\sby\sthe\sFossil\sport.
|
||||
D 2013-01-03T19:34:46.935
|
||||
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
||||
F Makefile.in a48faa9e7dd7d556d84f5456eabe5825dd8a6282
|
||||
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
||||
@ -217,7 +217,7 @@ F src/test_osinst.c 90a845c8183013d80eccb1f29e8805608516edba
|
||||
F src/test_pcache.c a5cd24730cb43c5b18629043314548c9169abb00
|
||||
F src/test_quota.c 0e0e2e3bf6766b101ecccd8c042b66e44e9be8f5
|
||||
F src/test_quota.h 8761e463b25e75ebc078bd67d70e39b9c817a0cb
|
||||
F src/test_regexp.c d8cb342e08a346a6daeda29e434e2d9a49f557ec
|
||||
F src/test_regexp.c 8d91d00e45e899eb13575bec4870ce415900bec6
|
||||
F src/test_rtree.c aba603c949766c4193f1068b91c787f57274e0d9
|
||||
F src/test_schema.c 8c06ef9ddb240c7a0fcd31bc221a6a2aade58bf0
|
||||
F src/test_server.c 2f99eb2837dfa06a4aacf24af24c6affdf66a84f
|
||||
@ -1031,7 +1031,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381
|
||||
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
|
||||
F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381
|
||||
F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac
|
||||
P 5a2ac944839ec0c5b9147a035c6cbf0935f3d202 20730bad7082b559a65e8cfedb31b6afca50df58
|
||||
R f686e430b5e8ddbc351355c5b12308be
|
||||
P 99127a669c49f82918853091c9c5b7db5ad73cba
|
||||
R c3dfd34890a9fadadecfeeae8889e37f
|
||||
U drh
|
||||
Z 393fc5c6f8c30a4998c90107d978b3f0
|
||||
Z 1e14e89eb51110980c945c9622f22c94
|
||||
|
@ -1 +1 @@
|
||||
99127a669c49f82918853091c9c5b7db5ad73cba
|
||||
45c158b1a015e0295244982e7a61ecc55cca8436
|
@ -88,19 +88,30 @@ typedef struct ReStateSet {
|
||||
ReStateNumber *aState; /* Current states */
|
||||
} ReStateSet;
|
||||
|
||||
/* An input string read one character at a time.
|
||||
*/
|
||||
typedef struct ReInput ReInput;
|
||||
struct ReInput {
|
||||
const unsigned char *z; /* All text */
|
||||
int i; /* Next byte to read */
|
||||
int mx; /* EOF when i>=mx */
|
||||
};
|
||||
|
||||
/* A compiled NFA (or an NFA that is in the process of being compiled) is
|
||||
** an instance of the following object.
|
||||
*/
|
||||
typedef struct ReCompiled {
|
||||
const unsigned char *zIn; /* Regular expression text */
|
||||
typedef struct ReCompiled ReCompiled;
|
||||
struct ReCompiled {
|
||||
ReInput sIn; /* Regular expression text */
|
||||
const char *zErr; /* Error message to return */
|
||||
char *aOp; /* Operators for the virtual machine */
|
||||
int *aArg; /* Arguments to each operator */
|
||||
unsigned (*xNextChar)(ReInput*); /* Next character function */
|
||||
char zInit[12]; /* Initial text to match */
|
||||
int nInit; /* Number of characters in zInit */
|
||||
unsigned nState; /* Number of entries in aOp[] and aArg[] */
|
||||
unsigned nAlloc; /* Slots allocated for aOp[] and aArg[] */
|
||||
} ReCompiled;
|
||||
};
|
||||
|
||||
/* Add a state to the given state set if it is not already there */
|
||||
static void re_add_state(ReStateSet *pSet, int newState){
|
||||
@ -114,24 +125,24 @@ static void re_add_state(ReStateSet *pSet, int newState){
|
||||
** be clear: this routine converts utf8 to unicode. This routine is
|
||||
** optimized for the common case where the next character is a single byte.
|
||||
*/
|
||||
static unsigned re_next_char(const unsigned char **pzIn){
|
||||
unsigned c = **pzIn;
|
||||
if( c>0 ) (*pzIn)++;
|
||||
static unsigned re_next_char(ReInput *p){
|
||||
unsigned c;
|
||||
if( p->i>=p->mx ) return 0;
|
||||
c = p->z[p->i++];
|
||||
if( c>0x80 ){
|
||||
if( (c&0xe0)==0xc0 && ((*pzIn)[0]&0xc0)==0x80 ){
|
||||
c = (c&0x1f)<<6 | ((*pzIn)[0]&0x3f);
|
||||
(*pzIn)++;
|
||||
if( (c&0xe0)==0xc0 && p->i<p->mx && (p->z[p->i]&0xc0)==0x80 ){
|
||||
c = (c&0x1f)<<6 | (p->z[p->i++]&0x3f);
|
||||
if( c<0x80 ) c = 0xfffd;
|
||||
}else if( (c&0xf0)==0xe0 && ((*pzIn)[0]&0xc0)==0x80
|
||||
&& ((*pzIn)[1]&0xc0)==0x80 ){
|
||||
c = (c&0x0f)<<12 | (((*pzIn)[0]&0x3f)<<6) | ((*pzIn)[1]&0x3f);
|
||||
*pzIn += 2;
|
||||
}else if( (c&0xf0)==0xe0 && p->i+1<p->mx && (p->z[p->i]&0xc0)==0x80
|
||||
&& (p->z[p->i+1]&0xc0)==0x80 ){
|
||||
c = (c&0x0f)<<12 | ((p->z[p->i]&0x3f)<<6) | (p->z[p->i+1]&0x3f);
|
||||
p->i += 2;
|
||||
if( c<0x3ff || (c>=0xd800 && c<=0xdfff) ) c = 0xfffd;
|
||||
}else if( (c&0xf8)==0xf0 && ((*pzIn)[0]&0xc0)==0x80
|
||||
&& ((*pzIn)[1]&0xc0)==0x80 && ((*pzIn)[2]&0xc0)==0x80 ){
|
||||
c = (c&0x07)<<18 | (((*pzIn)[0]&0x3f)<<12) | (((*pzIn)[1]&0x3f)<<6)
|
||||
| ((*pzIn)[2]&0x3f);
|
||||
*pzIn += 3;
|
||||
}else if( (c&0xf8)==0xf0 && p->i+3<p->mx && (p->z[p->i]&0xc0)==0x80
|
||||
&& (p->z[p->i+1]&0xc0)==0x80 && (p->z[p->i+2]&0xc0)==0x80 ){
|
||||
c = (c&0x07)<<18 | ((p->z[p->i]&0x3f)<<12) | ((p->z[p->i+1]&0x3f)<<6)
|
||||
| (p->z[p->i+2]&0x3f);
|
||||
p->i += 3;
|
||||
if( c<0xffff ) c = 0xfffd;
|
||||
}else{
|
||||
c = 0xfffd;
|
||||
@ -139,6 +150,11 @@ static unsigned re_next_char(const unsigned char **pzIn){
|
||||
}
|
||||
return c;
|
||||
}
|
||||
static unsigned re_next_char_nocase(ReInput *p){
|
||||
unsigned c = re_next_char(p);
|
||||
if( c>='A' && c<='Z' ) c += 'a' - 'A';
|
||||
return c;
|
||||
}
|
||||
|
||||
/* Return true if c is a perl "word" character: [A-Za-z0-9_] */
|
||||
static int re_word_char(int c){
|
||||
@ -159,7 +175,7 @@ static int re_space_char(int c){
|
||||
/* Run a compiled regular expression on the zero-terminated input
|
||||
** string zIn[]. Return true on a match and false if there is no match.
|
||||
*/
|
||||
static int re_exec(ReCompiled *pRe, const unsigned char *zIn){
|
||||
int re_match(ReCompiled *pRe, const unsigned char *zIn, int nIn){
|
||||
ReStateSet aStateSet[2], *pThis, *pNext;
|
||||
ReStateNumber aSpace[100];
|
||||
ReStateNumber *pToFree;
|
||||
@ -168,19 +184,25 @@ static int re_exec(ReCompiled *pRe, const unsigned char *zIn){
|
||||
int c = RE_EOF+1;
|
||||
int cPrev = 0;
|
||||
int rc = 0;
|
||||
|
||||
ReInput in;
|
||||
|
||||
in.z = zIn;
|
||||
in.i = 0;
|
||||
in.mx = nIn>=0 ? nIn : strlen((char*)zIn);
|
||||
if( pRe->nInit ){
|
||||
unsigned char x = pRe->zInit[0];
|
||||
while( zIn[0] && (zIn[0]!=x || memcmp(zIn, pRe->zInit, pRe->nInit)!=0) ){
|
||||
zIn++;
|
||||
while( in.i+pRe->nInit<=in.mx
|
||||
&& (zIn[in.i]!=x || memcmp(zIn+in.i, pRe->zInit, pRe->nInit)!=0)
|
||||
){
|
||||
in.i++;
|
||||
}
|
||||
if( zIn[0]==0 ) return 0;
|
||||
if( in.i+pRe->nInit>in.mx ) return 0;
|
||||
}
|
||||
if( pRe->nState<=(sizeof(aSpace)/(sizeof(aSpace[0])*2)) ){
|
||||
pToFree = 0;
|
||||
aStateSet[0].aState = aSpace;
|
||||
}else{
|
||||
pToFree = malloc( sizeof(ReStateNumber)*2*pRe->nState );
|
||||
pToFree = sqlite3_malloc( sizeof(ReStateNumber)*2*pRe->nState );
|
||||
if( pToFree==0 ) return -1;
|
||||
aStateSet[0].aState = pToFree;
|
||||
}
|
||||
@ -190,7 +212,7 @@ static int re_exec(ReCompiled *pRe, const unsigned char *zIn){
|
||||
re_add_state(pNext, 0);
|
||||
while( c!=RE_EOF && pNext->nState>0 ){
|
||||
cPrev = c;
|
||||
c = re_next_char(&zIn);
|
||||
c = pRe->xNextChar(&in);
|
||||
pThis = pNext;
|
||||
pNext = &aStateSet[iSwap];
|
||||
iSwap = 1 - iSwap;
|
||||
@ -250,7 +272,7 @@ static int re_exec(ReCompiled *pRe, const unsigned char *zIn){
|
||||
}
|
||||
case RE_OP_ACCEPT: {
|
||||
rc = 1;
|
||||
goto re_exec_end;
|
||||
goto re_match_end;
|
||||
}
|
||||
case RE_OP_CC_INC:
|
||||
case RE_OP_CC_EXC: {
|
||||
@ -282,8 +304,8 @@ static int re_exec(ReCompiled *pRe, const unsigned char *zIn){
|
||||
for(i=0; i<pNext->nState; i++){
|
||||
if( pRe->aOp[pNext->aState[i]]==RE_OP_ACCEPT ){ rc = 1; break; }
|
||||
}
|
||||
re_exec_end:
|
||||
free(pToFree);
|
||||
re_match_end:
|
||||
sqlite3_free(pToFree);
|
||||
return rc;
|
||||
}
|
||||
|
||||
@ -292,10 +314,10 @@ re_exec_end:
|
||||
static int re_resize(ReCompiled *p, int N){
|
||||
char *aOp;
|
||||
int *aArg;
|
||||
aOp = realloc(p->aOp, N*sizeof(p->aOp[0]));
|
||||
aOp = sqlite3_realloc(p->aOp, N*sizeof(p->aOp[0]));
|
||||
if( aOp==0 ) return 1;
|
||||
p->aOp = aOp;
|
||||
aArg = realloc(p->aArg, N*sizeof(p->aArg[0]));
|
||||
aArg = sqlite3_realloc(p->aArg, N*sizeof(p->aArg[0]));
|
||||
if( aArg==0 ) return 1;
|
||||
p->aArg = aArg;
|
||||
p->nAlloc = N;
|
||||
@ -359,30 +381,33 @@ static unsigned re_esc_char(ReCompiled *p){
|
||||
static const char zEsc[] = "afnrtv\\()*.+?[$^{|}]";
|
||||
static const char zTrans[] = "\a\f\n\r\t\v";
|
||||
int i, v = 0;
|
||||
char c = p->zIn[0];
|
||||
if( c=='u' ){
|
||||
char c;
|
||||
if( p->sIn.i>=p->sIn.mx ) return 0;
|
||||
c = p->sIn.z[p->sIn.i];
|
||||
if( c=='u' && p->sIn.i+5<p->sIn.mx ){
|
||||
v = 0;
|
||||
if( re_hex(p->zIn[1],&v)
|
||||
&& re_hex(p->zIn[2],&v)
|
||||
&& re_hex(p->zIn[3],&v)
|
||||
&& re_hex(p->zIn[4],&v)
|
||||
const unsigned char *zIn = p->sIn.z + p->sIn.i;
|
||||
if( re_hex(zIn[1],&v)
|
||||
&& re_hex(zIn[2],&v)
|
||||
&& re_hex(zIn[3],&v)
|
||||
&& re_hex(zIn[4],&v)
|
||||
){
|
||||
p->zIn += 5;
|
||||
p->sIn.i += 5;
|
||||
return v;
|
||||
}
|
||||
}
|
||||
if( c=='x' ){
|
||||
v = 0;
|
||||
for(i=1; re_hex(p->zIn[i], &v); i++){}
|
||||
for(i=1; p->sIn.i<p->sIn.mx && re_hex(p->sIn.z[p->sIn.i+i], &v); i++){}
|
||||
if( i>1 ){
|
||||
p->zIn += i;
|
||||
p->sIn.i += i;
|
||||
return v;
|
||||
}
|
||||
}
|
||||
for(i=0; zEsc[i] && zEsc[i]!=c; i++){}
|
||||
if( zEsc[i] ){
|
||||
if( i<6 ) c = zTrans[i];
|
||||
p->zIn++;
|
||||
p->sIn.i++;
|
||||
}else{
|
||||
p->zErr = "unknown \\ escape";
|
||||
}
|
||||
@ -392,6 +417,11 @@ static unsigned re_esc_char(ReCompiled *p){
|
||||
/* Forward declaration */
|
||||
static const char *re_subcompile_string(ReCompiled*);
|
||||
|
||||
/* Peek at the next byte of input */
|
||||
static unsigned char rePeek(ReCompiled *p){
|
||||
return p->sIn.i<p->sIn.mx ? p->sIn.z[p->sIn.i] : 0;
|
||||
}
|
||||
|
||||
/* Compile RE text into a sequence of opcodes. Continue up to the
|
||||
** first unmatched ")" character, then return. If an error is found,
|
||||
** return a pointer to the error message string.
|
||||
@ -402,11 +432,11 @@ static const char *re_subcompile_re(ReCompiled *p){
|
||||
iStart = p->nState;
|
||||
zErr = re_subcompile_string(p);
|
||||
if( zErr ) return zErr;
|
||||
while( p->zIn[0]=='|' ){
|
||||
while( rePeek(p)=='|' ){
|
||||
iEnd = p->nState;
|
||||
re_insert(p, iStart, RE_OP_FORK, iEnd + 2 - iStart);
|
||||
iGoto = re_append(p, RE_OP_GOTO, 0);
|
||||
p->zIn++;
|
||||
p->sIn.i++;
|
||||
zErr = re_subcompile_string(p);
|
||||
if( zErr ) return zErr;
|
||||
p->aArg[iGoto] = p->nState - iGoto;
|
||||
@ -423,26 +453,26 @@ static const char *re_subcompile_string(ReCompiled *p){
|
||||
int iStart;
|
||||
unsigned c;
|
||||
const char *zErr;
|
||||
while( (c = re_next_char(&p->zIn))!=0 ){
|
||||
while( (c = p->xNextChar(&p->sIn))!=0 ){
|
||||
iStart = p->nState;
|
||||
switch( c ){
|
||||
case '|':
|
||||
case '$':
|
||||
case ')': {
|
||||
p->zIn--;
|
||||
p->sIn.i--;
|
||||
return 0;
|
||||
}
|
||||
case '(': {
|
||||
zErr = re_subcompile_re(p);
|
||||
if( zErr ) return zErr;
|
||||
if( p->zIn[0]!=')' ) return "unmatched '('";
|
||||
p->zIn++;
|
||||
if( rePeek(p)!=')' ) return "unmatched '('";
|
||||
p->sIn.i++;
|
||||
break;
|
||||
}
|
||||
case '.': {
|
||||
if( p->zIn[0]=='*' ){
|
||||
if( rePeek(p)=='*' ){
|
||||
re_append(p, RE_OP_ANYSTAR, 0);
|
||||
p->zIn++;
|
||||
p->sIn.i++;
|
||||
}else{
|
||||
re_append(p, RE_OP_ANY, 0);
|
||||
}
|
||||
@ -468,16 +498,16 @@ static const char *re_subcompile_string(ReCompiled *p){
|
||||
int m = 0, n = 0;
|
||||
int sz, j;
|
||||
if( iPrev<0 ) return "'{m,n}' without operand";
|
||||
while( (c=p->zIn[0])>='0' && c<='9' ){ m = m*10 + c - '0'; p->zIn++; }
|
||||
while( (c=rePeek(p))>='0' && c<='9' ){ m = m*10 + c - '0'; p->sIn.i++; }
|
||||
n = m;
|
||||
if( c==',' ){
|
||||
p->zIn++;
|
||||
p->sIn.i++;
|
||||
n = 0;
|
||||
while( (c=p->zIn[0])>='0' && c<='9' ){ n = n*10 + c - '0'; p->zIn++; }
|
||||
while( (c=rePeek(p))>='0' && c<='9' ){ n = n*10 + c-'0'; p->sIn.i++; }
|
||||
}
|
||||
if( c!='}' ) return "unmatched '{'";
|
||||
if( n>0 && n<m ) return "n less than m in '{m,n}'";
|
||||
p->zIn++;
|
||||
p->sIn.i++;
|
||||
sz = p->nState - iPrev;
|
||||
if( m==0 ){
|
||||
if( n==0 ) return "both m and n are zero in '{m,n}'";
|
||||
@ -497,27 +527,27 @@ static const char *re_subcompile_string(ReCompiled *p){
|
||||
}
|
||||
case '[': {
|
||||
int iFirst = p->nState;
|
||||
if( p->zIn[0]=='^' ){
|
||||
if( rePeek(p)=='^' ){
|
||||
re_append(p, RE_OP_CC_EXC, 0);
|
||||
p->zIn++;
|
||||
p->sIn.i++;
|
||||
}else{
|
||||
re_append(p, RE_OP_CC_INC, 0);
|
||||
}
|
||||
while( (c = re_next_char(&p->zIn))!=0 ){
|
||||
if( c=='[' && p->zIn[0]==':' ){
|
||||
while( (c = p->xNextChar(&p->sIn))!=0 ){
|
||||
if( c=='[' && rePeek(p)==':' ){
|
||||
return "POSIX character classes not supported";
|
||||
}
|
||||
if( c=='\\' ) c = re_esc_char(p);
|
||||
if( p->zIn[0]=='-' && p->zIn[1] ){
|
||||
if( rePeek(p)=='-' ){
|
||||
re_append(p, RE_OP_CC_RANGE, c);
|
||||
p->zIn++;
|
||||
c = re_next_char(&p->zIn);
|
||||
p->sIn.i++;
|
||||
c = p->xNextChar(&p->sIn);
|
||||
if( c=='\\' ) c = re_esc_char(p);
|
||||
re_append(p, RE_OP_CC_RANGE, c);
|
||||
}else{
|
||||
re_append(p, RE_OP_CC_VALUE, c);
|
||||
}
|
||||
if( p->zIn[0]==']' ){ p->zIn++; break; }
|
||||
if( rePeek(p)==']' ){ p->sIn.i++; break; }
|
||||
}
|
||||
if( c==0 ) return "unclosed '['";
|
||||
p->aArg[iFirst] = p->nState - iFirst;
|
||||
@ -525,7 +555,7 @@ static const char *re_subcompile_string(ReCompiled *p){
|
||||
}
|
||||
case '\\': {
|
||||
int specialOp = 0;
|
||||
switch( p->zIn[0] ){
|
||||
switch( rePeek(p) ){
|
||||
case 'b': specialOp = RE_OP_BOUNDARY; break;
|
||||
case 'd': specialOp = RE_OP_DIGIT; break;
|
||||
case 'D': specialOp = RE_OP_NOTDIGIT; break;
|
||||
@ -535,7 +565,7 @@ static const char *re_subcompile_string(ReCompiled *p){
|
||||
case 'W': specialOp = RE_OP_NOTWORD; break;
|
||||
}
|
||||
if( specialOp ){
|
||||
p->zIn++;
|
||||
p->sIn.i++;
|
||||
re_append(p, specialOp, 0);
|
||||
}else{
|
||||
c = re_esc_char(p);
|
||||
@ -557,30 +587,32 @@ static const char *re_subcompile_string(ReCompiled *p){
|
||||
** regular expression. Applications should invoke this routine once
|
||||
** for every call to re_compile() to avoid memory leaks.
|
||||
*/
|
||||
static void re_free(ReCompiled *pRe){
|
||||
void re_free(ReCompiled *pRe){
|
||||
if( pRe ){
|
||||
free(pRe->aOp);
|
||||
free(pRe->aArg);
|
||||
sqlite3_free(pRe->aOp);
|
||||
sqlite3_free(pRe->aArg);
|
||||
sqlite3_free(pRe);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Compile a textual regular expression in zIn[] into a compiled regular
|
||||
** expression suitable for us by re_exec() and return a pointer to the
|
||||
** expression suitable for us by re_match() and return a pointer to the
|
||||
** compiled regular expression in *ppRe. Return NULL on success or an
|
||||
** error message if something goes wrong.
|
||||
*/
|
||||
static const char *re_compile(ReCompiled **ppRe, const char *zIn){
|
||||
const char *re_compile(ReCompiled **ppRe, const char *zIn, int noCase){
|
||||
ReCompiled *pRe;
|
||||
const char *zErr;
|
||||
int i, j;
|
||||
|
||||
*ppRe = 0;
|
||||
pRe = malloc( sizeof(*pRe) );
|
||||
pRe = sqlite3_malloc( sizeof(*pRe) );
|
||||
if( pRe==0 ){
|
||||
return "out of memory";
|
||||
}
|
||||
memset(pRe, 0, sizeof(*pRe));
|
||||
pRe->xNextChar = noCase ? re_next_char_nocase : re_next_char;
|
||||
if( re_resize(pRe, 30) ){
|
||||
re_free(pRe);
|
||||
return "out of memory";
|
||||
@ -590,17 +622,19 @@ static const char *re_compile(ReCompiled **ppRe, const char *zIn){
|
||||
}else{
|
||||
re_append(pRe, RE_OP_ANYSTAR, 0);
|
||||
}
|
||||
pRe->zIn = (unsigned char*)zIn;
|
||||
pRe->sIn.z = (unsigned char*)zIn;
|
||||
pRe->sIn.i = 0;
|
||||
pRe->sIn.mx = strlen((char*)pRe->sIn.z);
|
||||
zErr = re_subcompile_re(pRe);
|
||||
if( zErr ){
|
||||
re_free(pRe);
|
||||
return zErr;
|
||||
}
|
||||
if( pRe->zIn[0]=='$' && pRe->zIn[1]==0 ){
|
||||
if( rePeek(pRe)=='$' && pRe->sIn.i+1>=pRe->sIn.mx ){
|
||||
re_append(pRe, RE_OP_MATCH, RE_EOF);
|
||||
re_append(pRe, RE_OP_ACCEPT, 0);
|
||||
*ppRe = pRe;
|
||||
}else if( pRe->zIn[0]==0 ){
|
||||
}else if( pRe->sIn.i>=pRe->sIn.mx ){
|
||||
re_append(pRe, RE_OP_ACCEPT, 0);
|
||||
*ppRe = pRe;
|
||||
}else{
|
||||
@ -623,6 +657,7 @@ static const char *re_compile(ReCompiled **ppRe, const char *zIn){
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( j>0 && pRe->zInit[j-1]==0 ) j--;
|
||||
pRe->nInit = j;
|
||||
}
|
||||
return pRe->zErr;
|
||||
@ -651,8 +686,9 @@ static void re_sql_func(
|
||||
if( pRe==0 ){
|
||||
zPattern = (const char*)sqlite3_value_text(argv[0]);
|
||||
if( zPattern==0 ) return;
|
||||
zErr = re_compile(&pRe, zPattern);
|
||||
zErr = re_compile(&pRe, zPattern, 0);
|
||||
if( zErr ){
|
||||
re_free(pRe);
|
||||
sqlite3_result_error(context, zErr, -1);
|
||||
return;
|
||||
}
|
||||
@ -664,7 +700,7 @@ static void re_sql_func(
|
||||
}
|
||||
zStr = (const unsigned char*)sqlite3_value_text(argv[1]);
|
||||
if( zStr!=0 ){
|
||||
sqlite3_result_int(context, re_exec(pRe, zStr));
|
||||
sqlite3_result_int(context, re_match(pRe, zStr, -1));
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user