Fossil SCM
Update the regexp implementation with the latest fixes from the SQLite trunk. Add the regexpi() SQL function.
Commit
1f3a053b1613f2c69b158928536851b0dea9942f8155bc63e837d86a5015078b
Parent
dc47bf4b6af2bc6…
1 file changed
+13
-5
+13
-5
| --- src/regexp.c | ||
| +++ src/regexp.c | ||
| @@ -197,11 +197,11 @@ | ||
| 197 | 197 | case RE_OP_MATCH: { |
| 198 | 198 | if( pRe->aArg[x]==c ) re_add_state(pNext, x+1); |
| 199 | 199 | break; |
| 200 | 200 | } |
| 201 | 201 | case RE_OP_ANY: { |
| 202 | - re_add_state(pNext, x+1); | |
| 202 | + if( c!=0 ) re_add_state(pNext, x+1); | |
| 203 | 203 | break; |
| 204 | 204 | } |
| 205 | 205 | case RE_OP_WORD: { |
| 206 | 206 | if( re_word_char(c) ) re_add_state(pNext, x+1); |
| 207 | 207 | break; |
| @@ -622,11 +622,11 @@ | ||
| 622 | 622 | ** zInit[]. The re_match() routine can then search ahead in the input |
| 623 | 623 | ** string looking for the initial match without having to run the whole |
| 624 | 624 | ** regex engine over the string. Do not worry able trying to match |
| 625 | 625 | ** unicode characters beyond plane 0 - those are very rare and this is |
| 626 | 626 | ** just an optimization. */ |
| 627 | - if( pRe->aOp[0]==RE_OP_ANYSTAR ){ | |
| 627 | + if( pRe->aOp[0]==RE_OP_ANYSTAR && !noCase ){ | |
| 628 | 628 | for(j=0, i=1; j<sizeof(pRe->zInit)-2 && pRe->aOp[i]==RE_OP_MATCH; i++){ |
| 629 | 629 | unsigned x = pRe->aArg[i]; |
| 630 | 630 | if( x<=127 ){ |
| 631 | 631 | pRe->zInit[j++] = (unsigned char)x; |
| 632 | 632 | }else if( x<=0xfff ){ |
| @@ -668,11 +668,11 @@ | ||
| 668 | 668 | |
| 669 | 669 | pRe = sqlite3_get_auxdata(context, 0); |
| 670 | 670 | if( pRe==0 ){ |
| 671 | 671 | zPattern = (const char*)sqlite3_value_text(argv[0]); |
| 672 | 672 | if( zPattern==0 ) return; |
| 673 | - zErr = re_compile(&pRe, zPattern, 0); | |
| 673 | + zErr = re_compile(&pRe, zPattern, sqlite3_user_data(context)!=0); | |
| 674 | 674 | if( zErr ){ |
| 675 | 675 | re_free(pRe); |
| 676 | 676 | sqlite3_result_error(context, zErr, -1); |
| 677 | 677 | return; |
| 678 | 678 | } |
| @@ -694,12 +694,20 @@ | ||
| 694 | 694 | /* |
| 695 | 695 | ** Invoke this routine to register the regexp() function with the |
| 696 | 696 | ** SQLite database connection. |
| 697 | 697 | */ |
| 698 | 698 | int re_add_sql_func(sqlite3 *db){ |
| 699 | - return sqlite3_create_function(db, "regexp", 2, SQLITE_UTF8, 0, | |
| 700 | - re_sql_func, 0, 0); | |
| 699 | + int rc; | |
| 700 | + rc = sqlite3_create_function(db, "regexp", 2, SQLITE_UTF8|SQLITE_INNOCUOUS, | |
| 701 | + 0, re_sql_func, 0, 0); | |
| 702 | + if( rc==SQLITE_OK ){ | |
| 703 | + /* The regexpi(PATTERN,STRING) function is a case-insensitive version | |
| 704 | + ** of regexp(PATTERN,STRING). */ | |
| 705 | + rc = sqlite3_create_function(db, "regexpi", 2, SQLITE_UTF8|SQLITE_INNOCUOUS, | |
| 706 | + (void*)db, re_sql_func, 0, 0); | |
| 707 | + } | |
| 708 | + return rc; | |
| 701 | 709 | } |
| 702 | 710 | |
| 703 | 711 | /* |
| 704 | 712 | ** Run a "grep" over a single file read from disk. |
| 705 | 713 | */ |
| 706 | 714 |
| --- src/regexp.c | |
| +++ src/regexp.c | |
| @@ -197,11 +197,11 @@ | |
| 197 | case RE_OP_MATCH: { |
| 198 | if( pRe->aArg[x]==c ) re_add_state(pNext, x+1); |
| 199 | break; |
| 200 | } |
| 201 | case RE_OP_ANY: { |
| 202 | re_add_state(pNext, x+1); |
| 203 | break; |
| 204 | } |
| 205 | case RE_OP_WORD: { |
| 206 | if( re_word_char(c) ) re_add_state(pNext, x+1); |
| 207 | break; |
| @@ -622,11 +622,11 @@ | |
| 622 | ** zInit[]. The re_match() routine can then search ahead in the input |
| 623 | ** string looking for the initial match without having to run the whole |
| 624 | ** regex engine over the string. Do not worry able trying to match |
| 625 | ** unicode characters beyond plane 0 - those are very rare and this is |
| 626 | ** just an optimization. */ |
| 627 | if( pRe->aOp[0]==RE_OP_ANYSTAR ){ |
| 628 | for(j=0, i=1; j<sizeof(pRe->zInit)-2 && pRe->aOp[i]==RE_OP_MATCH; i++){ |
| 629 | unsigned x = pRe->aArg[i]; |
| 630 | if( x<=127 ){ |
| 631 | pRe->zInit[j++] = (unsigned char)x; |
| 632 | }else if( x<=0xfff ){ |
| @@ -668,11 +668,11 @@ | |
| 668 | |
| 669 | pRe = sqlite3_get_auxdata(context, 0); |
| 670 | if( pRe==0 ){ |
| 671 | zPattern = (const char*)sqlite3_value_text(argv[0]); |
| 672 | if( zPattern==0 ) return; |
| 673 | zErr = re_compile(&pRe, zPattern, 0); |
| 674 | if( zErr ){ |
| 675 | re_free(pRe); |
| 676 | sqlite3_result_error(context, zErr, -1); |
| 677 | return; |
| 678 | } |
| @@ -694,12 +694,20 @@ | |
| 694 | /* |
| 695 | ** Invoke this routine to register the regexp() function with the |
| 696 | ** SQLite database connection. |
| 697 | */ |
| 698 | int re_add_sql_func(sqlite3 *db){ |
| 699 | return sqlite3_create_function(db, "regexp", 2, SQLITE_UTF8, 0, |
| 700 | re_sql_func, 0, 0); |
| 701 | } |
| 702 | |
| 703 | /* |
| 704 | ** Run a "grep" over a single file read from disk. |
| 705 | */ |
| 706 |
| --- src/regexp.c | |
| +++ src/regexp.c | |
| @@ -197,11 +197,11 @@ | |
| 197 | case RE_OP_MATCH: { |
| 198 | if( pRe->aArg[x]==c ) re_add_state(pNext, x+1); |
| 199 | break; |
| 200 | } |
| 201 | case RE_OP_ANY: { |
| 202 | if( c!=0 ) re_add_state(pNext, x+1); |
| 203 | break; |
| 204 | } |
| 205 | case RE_OP_WORD: { |
| 206 | if( re_word_char(c) ) re_add_state(pNext, x+1); |
| 207 | break; |
| @@ -622,11 +622,11 @@ | |
| 622 | ** zInit[]. The re_match() routine can then search ahead in the input |
| 623 | ** string looking for the initial match without having to run the whole |
| 624 | ** regex engine over the string. Do not worry able trying to match |
| 625 | ** unicode characters beyond plane 0 - those are very rare and this is |
| 626 | ** just an optimization. */ |
| 627 | if( pRe->aOp[0]==RE_OP_ANYSTAR && !noCase ){ |
| 628 | for(j=0, i=1; j<sizeof(pRe->zInit)-2 && pRe->aOp[i]==RE_OP_MATCH; i++){ |
| 629 | unsigned x = pRe->aArg[i]; |
| 630 | if( x<=127 ){ |
| 631 | pRe->zInit[j++] = (unsigned char)x; |
| 632 | }else if( x<=0xfff ){ |
| @@ -668,11 +668,11 @@ | |
| 668 | |
| 669 | pRe = sqlite3_get_auxdata(context, 0); |
| 670 | if( pRe==0 ){ |
| 671 | zPattern = (const char*)sqlite3_value_text(argv[0]); |
| 672 | if( zPattern==0 ) return; |
| 673 | zErr = re_compile(&pRe, zPattern, sqlite3_user_data(context)!=0); |
| 674 | if( zErr ){ |
| 675 | re_free(pRe); |
| 676 | sqlite3_result_error(context, zErr, -1); |
| 677 | return; |
| 678 | } |
| @@ -694,12 +694,20 @@ | |
| 694 | /* |
| 695 | ** Invoke this routine to register the regexp() function with the |
| 696 | ** SQLite database connection. |
| 697 | */ |
| 698 | int re_add_sql_func(sqlite3 *db){ |
| 699 | int rc; |
| 700 | rc = sqlite3_create_function(db, "regexp", 2, SQLITE_UTF8|SQLITE_INNOCUOUS, |
| 701 | 0, re_sql_func, 0, 0); |
| 702 | if( rc==SQLITE_OK ){ |
| 703 | /* The regexpi(PATTERN,STRING) function is a case-insensitive version |
| 704 | ** of regexp(PATTERN,STRING). */ |
| 705 | rc = sqlite3_create_function(db, "regexpi", 2, SQLITE_UTF8|SQLITE_INNOCUOUS, |
| 706 | (void*)db, re_sql_func, 0, 0); |
| 707 | } |
| 708 | return rc; |
| 709 | } |
| 710 | |
| 711 | /* |
| 712 | ** Run a "grep" over a single file read from disk. |
| 713 | */ |
| 714 |