diff options
Diffstat (limited to 'contrib/tsearch2/ispell/regis.c')
-rw-r--r-- | contrib/tsearch2/ispell/regis.c | 136 |
1 files changed, 80 insertions, 56 deletions
diff --git a/contrib/tsearch2/ispell/regis.c b/contrib/tsearch2/ispell/regis.c index 996417b18a9..db6f1873f33 100644 --- a/contrib/tsearch2/ispell/regis.c +++ b/contrib/tsearch2/ispell/regis.c @@ -1,22 +1,23 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> -#include <ctype.h> #include "regis.h" +#include "ts_locale.h" #include "common.h" -int +bool RS_isRegis(const char *str) { unsigned char *ptr = (unsigned char *) str; while (ptr && *ptr) - if (isalpha(*ptr) || *ptr == '[' || *ptr == ']' || *ptr == '^') - ptr++; + if (t_isalpha(ptr) || t_iseq(ptr,'[') || t_iseq(ptr,']') || t_iseq(ptr, '^')) + ptr+=pg_mblen(ptr); else - return 0; - return 1; + return false; + + return true; } #define RS_IN_ONEOF 1 @@ -38,34 +39,32 @@ newRegisNode(RegisNode * prev, int len) return ptr; } -int -RS_compile(Regis * r, int issuffix, const char *str) +void +RS_compile(Regis * r, bool issuffix, char *str) { - int i, - len = strlen(str); + int len = strlen(str); int state = RS_IN_WAIT; + char *c = (char*)str; RegisNode *ptr = NULL; memset(r, 0, sizeof(Regis)); r->issuffix = (issuffix) ? 1 : 0; - for (i = 0; i < len; i++) + while(*c) { - unsigned char c = *(((unsigned char *) str) + i); - if (state == RS_IN_WAIT) { - if (isalpha(c)) + if (t_isalpha(c)) { if (ptr) ptr = newRegisNode(ptr, len); else ptr = r->node = newRegisNode(NULL, len); - ptr->data[0] = c; + COPYCHAR(ptr->data, c); ptr->type = RSF_ONEOF; - ptr->len = 1; + ptr->len = pg_mblen(c); } - else if (c == '[') + else if (t_iseq(c,'[')) { if (ptr) ptr = newRegisNode(ptr, len); @@ -75,38 +74,39 @@ RS_compile(Regis * r, int issuffix, const char *str) state = RS_IN_ONEOF; } else - ts_error(ERROR, "Error in regis: %s at pos %d\n", str, i + 1); + ts_error(ERROR, "Error in regis: %s", str ); } else if (state == RS_IN_ONEOF) { - if (c == '^') + if (t_iseq(c,'^')) { ptr->type = RSF_NONEOF; state = RS_IN_NONEOF; } - else if (isalpha(c)) + else if (t_isalpha(c)) { - ptr->data[0] = c; - ptr->len = 1; + COPYCHAR(ptr->data, c); + ptr->len = pg_mblen(c); state = RS_IN_ONEOF_IN; } else - ts_error(ERROR, "Error in regis: %s at pos %d\n", str, i + 1); + ts_error(ERROR, "Error in regis: %s", str); } else if (state == RS_IN_ONEOF_IN || state == RS_IN_NONEOF) { - if (isalpha(c)) + if (t_isalpha(c)) { - ptr->data[ptr->len] = c; - ptr->len++; + COPYCHAR(ptr->data+ptr->len, c); + ptr->len+=pg_mblen(c); } - else if (c == ']') + else if (t_iseq(c,']')) state = RS_IN_WAIT; else - ts_error(ERROR, "Error in regis: %s at pos %d\n", str, i + 1); + ts_error(ERROR, "Error in regis: %s", str); } else - ts_error(ERROR, "Internal error in RS_compile: %d\n", state); + ts_error(ERROR, "Internal error in RS_compile: %d", state); + c += pg_mblen(c); } ptr = r->node; @@ -115,8 +115,6 @@ RS_compile(Regis * r, int issuffix, const char *str) r->nchar++; ptr = ptr->next; } - - return 0; } void @@ -135,51 +133,77 @@ RS_free(Regis * r) r->node = NULL; } -int -RS_execute(Regis * r, const char *str, int len) +#ifdef TS_USE_WIDE +static bool +mb_strchr(char *str, char *c) { + int clen = pg_mblen(c), plen,i; + char *ptr =str; + bool res=false; + + clen = pg_mblen(c); + while( *ptr && !res) { + plen = pg_mblen(ptr); + if ( plen == clen ) { + i=plen; + res = true; + while(i--) + if ( *(ptr+i) != *(c+i) ) { + res = false; + break; + } + } + + ptr += plen; + } + + return res; +} +#else +#define mb_strchr(s,c) ( (strchr((s),*(c)) == NULL) ? false : true ) +#endif + + +bool +RS_execute(Regis * r, char *str) { RegisNode *ptr = r->node; - unsigned char *c; + char *c = str; + int len=0; - if (len < 0) - len = strlen(str); + while(*c) { + len++; + c += pg_mblen(c); + } if (len < r->nchar) return 0; - if (r->issuffix) - c = ((unsigned char *) str) + len - r->nchar; - else - c = (unsigned char *) str; + c = str; + if (r->issuffix) { + len -= r->nchar; + while(len-- > 0) + c += pg_mblen(c); + } + while (ptr) { switch (ptr->type) { case RSF_ONEOF: - if (ptr->len == 0) - { - if (*c != *(ptr->data)) - return 0; - } - else if (strchr((char *) ptr->data, *c) == NULL) - return 0; + if ( mb_strchr((char *) ptr->data, c) != true ) + return false; break; case RSF_NONEOF: - if (ptr->len == 0) - { - if (*c == *(ptr->data)) - return 0; - } - else if (strchr((char *) ptr->data, *c) != NULL) - return 0; + if ( mb_strchr((char *) ptr->data, c) == true ) + return false; break; default: ts_error(ERROR, "RS_execute: Unknown type node: %d\n", ptr->type); } ptr = ptr->next; - c++; + c+=pg_mblen(c); } - return 1; + return true; } |