static int wmatch(char *wlist, char **s2) /* char *wlist; word list */ /* char **s2; buffer to match from */ { char *matchstr, /* which word to find */ *strend, /* end of current word from wlist */ *matchbuf, /* where to find from */ *bufend; /* end of match buffer */ int result = 1; /* intermediate result */ if (!wlist || !*s2) return 1; matchbuf = *s2; matchstr = wlist; bufend = strchr(matchbuf, ' '); if (bufend == NULL) *s2 += strlen(*s2); else { *s2 = bufend; *bufend = '\0'; } do { if ((strend = estrchr(matchstr, '|', '\\')) != NULL) *strend = '\0'; result = smatch(matchstr, matchbuf); if (strend != NULL) *strend++ = '|'; if (!result) break; } while ((matchstr = strend) != NULL); if (bufend != NULL) *bufend = ' '; return result; }
static RegInfo *tf_reg_compile_fl(const char *pattern, int optimize, const char *file, int line) { RegInfo *ri; const char *emsg, *s; int eoffset, n; /* PCRE_DOTALL optimizes patterns starting with ".*" */ int options = PCRE_DOLLAR_ENDONLY | PCRE_DOTALL | PCRE_CASELESS; ri = dmalloc(NULL, sizeof(RegInfo), file, line); if (!ri) return NULL; ri->extra = NULL; ri->ovector = NULL; ri->Str = NULL; ri->links = 1; if (warn_curly_re && (s = estrchr(pattern, '{', '\\')) && (is_digit(s[1]) || s[1] == ',')) { wprintf("regexp contains '{', which has a new meaning in version 5.0. " "(This warning can be disabled with '/set warn_curly_re=off'.)"); } for (s = pattern; *s; s++) { if (*s == '\\') { if (s[1]) s++; } else if (is_upper(*s)) { options &= ~PCRE_CASELESS; break; } } ri->re = pcre_compile((char*)pattern, options, &emsg, &eoffset, re_tables); if (!ri->re) { /* don't trust emsg to be non-NULL or NUL-terminated */ eprintf("regexp error: character %d: %.128s", eoffset, emsg ? emsg : "unknown error"); goto tf_reg_compile_error; } n = pcre_info(ri->re, NULL, NULL); if (n < 0) goto tf_reg_compile_error; ri->ovecsize = 3 * (n + 1); ri->ovector = dmalloc(NULL, sizeof(int) * ri->ovecsize, file, line); if (!ri->ovector) goto tf_reg_compile_error; if (optimize) { ri->extra = pcre_study(ri->re, 0, &emsg); if (emsg) { eprintf("regexp study error: %.128s", emsg); goto tf_reg_compile_error; } } return ri; tf_reg_compile_error: tf_reg_free(ri); return NULL; }
char* estrtok(const char** str, const char* delim, char* token) { char* mem = NULL; const char *end; const char* start = estrchrn(str[0], delim); if(start) { end = estrchr(start+1, delim); if(token) { mem = (char *)realloc(token, (size_t)(end - start + 1) * sizeof(char)); if(mem) { memset(mem, 0, (size_t)(end - start + 1) * sizeof(char)); strncpy(mem, start, (size_t)(end - start)); str[0] = end; return mem; } else { free(token); str[0] = NULL; return NULL; } } else { mem = (char *)malloc((size_t)(end - start + 1) * sizeof(char)); if(mem) { memset(mem, 0, (size_t)(end - start + 1) * sizeof(char)); strncpy(mem, start, (size_t)(end - start)); str[0] = end; return mem; } else { str[0] = NULL; return NULL; } } } else { if(token) { free(token); } str[0] = NULL; return NULL; } }
int smatch(char *s1, char *s2) { char ch, *start = s2; while (*s1) { switch (*s1) { case '\\': if (!*(s1+1)) { return 1; } else { s1++; if (DOWNCASE(*s1++) != DOWNCASE(*s2++)) return 1; } break; case '?': if (!*s2++) return 1; s1++; break; case '*': while (*s1 == '*' || (*s1 == '?' && *s2++)) s1++; if (*s1 == '?') return 1; if (*s1 == '{') { if (s2 == start) if (!smatch(s1, s2)) return 0; while ((s2 = strchr(s2, ' ')) != NULL) if (!smatch(s1, ++s2)) return 0; return 1; } else if (*s1 == '[') { while (*s2) if (!smatch(s1, s2++)) return 0; return 1; } if (*s1 == '\\' && *(s1+1)) ch = *(s1 + 1); else ch = *s1; while ((s2 = cstrchr(s2, ch)) != NULL) { if (!smatch(s1, s2)) return 0; s2++; } return 1; case '[': { char *end; int tmpflg; if (!(end = estrchr(s1, ']', '\\'))) { return 1; } *end = '\0'; tmpflg = cmatch(&s1[1], *s2++); *end = ']'; if (tmpflg) { return 1; } s1 = end + 1; } break; case '{': if (s2 != start && *(s2 - 1) != ' ') return 1; { char *end; int tmpflg = 0; if (s1[1] == '^') tmpflg = 1; if (!(end = estrchr(s1, '}', '\\'))) { return 1; } *end = '\0'; tmpflg -= (wmatch(&s1[tmpflg + 1], &s2)) ? 1 : 0; *end = '}'; if (tmpflg) { return 1; } s1 = end + 1; } break; default: if (DOWNCASE(*s1++) != DOWNCASE(*s2++)) return 1; break; } } return DOWNCASE(*s1) - DOWNCASE(*s2); }