6 #include "sqstdstring.h" 10 #define scisprint iswprint 12 #define scisprint isprint 18 static const SQChar *g_nnames[] =
20 _SC(
"NONE"),_SC(
"OP_GREEDY"), _SC(
"OP_OR"),
21 _SC(
"OP_EXPR"),_SC(
"OP_NOCAPEXPR"),_SC(
"OP_DOT"), _SC(
"OP_CLASS"),
22 _SC(
"OP_CCLASS"),_SC(
"OP_NCLASS"),_SC(
"OP_RANGE"),_SC(
"OP_CHAR"),
23 _SC(
"OP_EOL"),_SC(
"OP_BOL"),_SC(
"OP_WB")
28 #define OP_GREEDY (MAX_CHAR+1) // * + ? {n} 29 #define OP_OR (MAX_CHAR+2) 30 #define OP_EXPR (MAX_CHAR+3) //parentesis () 31 #define OP_NOCAPEXPR (MAX_CHAR+4) //parentesis (?:) 32 #define OP_DOT (MAX_CHAR+5) 33 #define OP_CLASS (MAX_CHAR+6) 34 #define OP_CCLASS (MAX_CHAR+7) 35 #define OP_NCLASS (MAX_CHAR+8) //negates class the [^ 36 #define OP_RANGE (MAX_CHAR+9) 37 #define OP_CHAR (MAX_CHAR+10) 38 #define OP_EOL (MAX_CHAR+11) 39 #define OP_BOL (MAX_CHAR+12) 40 #define OP_WB (MAX_CHAR+13) 42 #define SQREX_SYMBOL_ANY_CHAR ('.') 43 #define SQREX_SYMBOL_GREEDY_ONE_OR_MORE ('+') 44 #define SQREX_SYMBOL_GREEDY_ZERO_OR_MORE ('*') 45 #define SQREX_SYMBOL_GREEDY_ZERO_OR_ONE ('?') 46 #define SQREX_SYMBOL_BRANCH ('|') 47 #define SQREX_SYMBOL_END_OF_STRING ('$') 48 #define SQREX_SYMBOL_BEGINNING_OF_STRING ('^') 49 #define SQREX_SYMBOL_ESCAPE_CHAR ('\\') 92 SQInteger newid = exp->
_nsize - 1;
93 return (SQInteger)newid;
99 longjmp(*((jmp_buf*)exp->
_jmpbuf),-1);
113 case 'v': exp->
_p++;
return '\v';
114 case 'n': exp->
_p++;
return '\n';
115 case 't': exp->
_p++;
return '\t';
116 case 'r': exp->
_p++;
return '\r';
117 case 'f': exp->
_p++;
return '\f';
118 default:
return (*exp->
_p++);
142 case 'a':
case 'A':
case 'w':
case 'W':
case 's':
case 'S':
143 case 'd':
case 'D':
case 'x':
case 'X':
case 'c':
case 'C':
144 case 'p':
case 'P':
case 'l':
case 'u':
146 t = *exp->
_p; exp->
_p++;
158 t = *exp->
_p; exp->
_p++;
166 t = *exp->
_p; exp->
_p++;
172 SQInteger first = -1,chain;
180 while(*exp->
_p !=
']' && exp->
_p != exp->
_eol) {
181 if(*exp->
_p ==
'-' && first != -1){
220 SQInteger ret = *exp->
_p-
'0';
221 SQInteger positions = 10;
223 while(isdigit(*exp->
_p)) {
224 ret = ret*10+(*exp->
_p++-
'0');
225 if(positions==1000000000)
sqstd_rex_error(exp,_SC(
"overflow in numeric constant"));
269 SQBool isgreedy = SQFalse;
270 unsigned short p0 = 0, p1 = 0;
287 if(isdigit(*exp->
_p)){
331 SQInteger temp,tright;
345 case 'a':
return isalpha(c)?SQTrue:SQFalse;
346 case 'A':
return !isalpha(c)?SQTrue:SQFalse;
347 case 'w':
return (isalnum(c) || c ==
'_')?SQTrue:SQFalse;
348 case 'W':
return (!isalnum(c) && c !=
'_')?SQTrue:SQFalse;
349 case 's':
return isspace(c)?SQTrue:SQFalse;
350 case 'S':
return !isspace(c)?SQTrue:SQFalse;
351 case 'd':
return isdigit(c)?SQTrue:SQFalse;
352 case 'D':
return !isdigit(c)?SQTrue:SQFalse;
353 case 'x':
return isxdigit(c)?SQTrue:SQFalse;
354 case 'X':
return !isxdigit(c)?SQTrue:SQFalse;
355 case 'c':
return iscntrl(c)?SQTrue:SQFalse;
356 case 'C':
return !iscntrl(c)?SQTrue:SQFalse;
357 case 'p':
return ispunct(c)?SQTrue:SQFalse;
358 case 'P':
return !ispunct(c)?SQTrue:SQFalse;
359 case 'l':
return islower(c)?SQTrue:SQFalse;
360 case 'u':
return isupper(c)?SQTrue:SQFalse;
370 if(c >= node->
left && c <= node->
right)
return SQTrue;
376 if(c == node->
type)
return SQTrue;
390 SQInteger p0 = (node->
right >> 16)&0x0000FFFF, p1 = node->
right&0x0000FFFF, nmaches = 0;
391 const SQChar *s=str, *good = str;
393 if(node->
next != -1) {
400 while((nmaches == 0xFFFF || nmaches < p1)) {
414 if(greedystop->
next != -1) {
416 }
else if(next && next->
next != -1){
422 if(p0 == p1 && p0 == nmaches)
break;
423 else if(nmaches >= p0 && p1 == 0xFFFF)
break;
424 else if(nmaches >= p0 && nmaches <= p1)
break;
432 if(p0 == p1 && p0 == nmaches)
return good;
433 else if(nmaches >= p0 && p1 == 0xFFFF)
return good;
434 else if(nmaches >= p0 && nmaches <= p1)
return good;
490 if( (str == exp->
_bol && !isspace(*str))
491 || ((str == exp->
_eol && !isspace(*(str-1))))
492 || ((!isspace(*str) && isspace(*(str+1))))
493 || ((isspace(*str) && !isspace(*(str+1)))) ) {
494 return (node->
left ==
'b')?str:
NULL;
496 return (node->
left ==
'b')?
NULL:str;
498 if(str == exp->
_bol)
return str;
501 if(str == exp->
_eol)
return str;
546 if(setjmp(*((jmp_buf*)exp->
_jmpbuf)) == 0) {
558 for(i = 0;i < nsize; i++) {
560 scprintf(_SC(
"[%02d] %10s "),i,g_nnames[exp->
_nodes[i].
type-MAX_CHAR]);
562 scprintf(_SC(
"[%02d] %10c "),i,exp->
_nodes[i].
type);
592 exp->
_eol = text + scstrlen(text);
603 SQInteger node = exp->
_first;
604 if(text_begin >= text_end)
return SQFalse;
605 exp->
_bol = text_begin;
606 exp->
_eol = text_end;
618 }
while(cur ==
NULL && text_begin != text_end);
625 if(out_begin) *out_begin = text_begin;
626 if(out_end) *out_end = cur;
642 if( n<0 || n >= exp->
_nsubexpr)
return SQFalse;
SQBool sqstd_rex_searchrange(SQRex *exp, const SQChar *text_begin, const SQChar *text_end, const SQChar **out_begin, const SQChar **out_end)
static SQInteger sqstd_rex_list(SQRex *exp)
void * sq_malloc(SQUnsignedInteger size)
static SQInteger sqstd_rex_charnode(SQRex *exp, SQBool isclass)
#define SQREX_SYMBOL_GREEDY_ZERO_OR_MORE
void sqstd_rex_free(SQRex *exp)
SQBool sqstd_rex_search(SQRex *exp, const SQChar *text, const SQChar **out_begin, const SQChar **out_end)
static SQInteger sqstd_rex_parsenumber(SQRex *exp)
static SQBool sqstd_rex_matchclass(SQRex *exp, SQRexNode *node, SQChar c)
static void sqstd_rex_expect(SQRex *exp, SQInteger n)
#define SQREX_SYMBOL_BEGINNING_OF_STRING
static SQInteger sqstd_rex_charclass(SQRex *exp, SQInteger classid)
static SQInteger sqstd_rex_class(SQRex *exp)
SQBool sqstd_rex_getsubexp(SQRex *exp, SQInteger n, SQRexMatch *subexp)
static SQInteger sqstd_rex_newnode(SQRex *exp, SQRexNodeType type)
#define SQREX_SYMBOL_GREEDY_ZERO_OR_ONE
#define SQREX_SYMBOL_END_OF_STRING
void * sq_realloc(void *p, SQUnsignedInteger oldsize, SQUnsignedInteger newsize)
#define SQREX_SYMBOL_BRANCH
SQRex * sqstd_rex_compile(const SQChar *pattern, const SQChar **error)
struct tagSQRexNode SQRexNode
static SQChar sqstd_rex_escapechar(SQRex *exp)
static void sqstd_rex_error(SQRex *exp, const SQChar *error)
void sq_free(void *p, SQUnsignedInteger size)
SQBool sqstd_rex_match(SQRex *exp, const SQChar *text)
SQInteger sqstd_rex_getsubexpcount(SQRex *exp)
static SQBool sqstd_rex_matchcclass(SQInteger cclass, SQChar c)
static const SQChar * sqstd_rex_matchnode(SQRex *exp, SQRexNode *node, const SQChar *str, SQRexNode *next)
#define SQREX_SYMBOL_ANY_CHAR
#define SQREX_SYMBOL_GREEDY_ONE_OR_MORE
static SQInteger sqstd_rex_element(SQRex *exp)
#define SQREX_SYMBOL_ESCAPE_CHAR