void RegEx::ClearMatchList(void) { if (matchlist) { pcre_free_substring_list(matchlist); matchlist = NULL; } }
/* Public Methods */ gboolean mud_regex_check(MudRegex *regex, const gchar *data, guint length, const gchar *rx, gint ovector[1020]) { pcre *re = NULL; const gchar *error = NULL; gint errorcode; gint erroroffset; gint rc; if(!MUD_IS_REGEX(regex)) return FALSE; re = pcre_compile2(rx, 0, &errorcode, &error, &erroroffset, NULL); if(!re) { gint i; /* This should never be called since we check the regex validity at entry time. But You Never Know(tm) so its here to catch any runtime errors that cosmic rays, evil magic, errant gconf editing, and Monday mornings might produce. */ g_warning("Error in Regex! - ErrCode: %d - %s", errorcode, error); printf("--> %s\n ", rx); for(i = 0; i < erroroffset - 1; i++) printf(" "); printf("^\n"); return FALSE; } rc = pcre_exec(re, NULL, data, length, 0, 0, ovector, 1020); if(rc < 0) return FALSE; if(regex->priv->substring_list) pcre_free_substring_list(regex->priv->substring_list); pcre_get_substring_list(data, ovector, rc, ®ex->priv->substring_list); regex->priv->substring_count = rc; return TRUE; }
/* The expected input file is the result of anathons analysis */ int get_data(char *inFileName, Dat *dat){ FILE *inFile = 0; /* input file */ char line[80]; /* line */ unsigned int allocated = 64; /* allocation counter */ pcre *re; /* regular expression */ const char *error; /* error message string */ int erroffset; /* error offset */ int ovector[OVECCOUNT]; /* match vector */ int rc; /* match return value */ char **substring_list; /* substring list */ /* initialise/allocate memory for set of (64) frag entries */ dat->nData = 0; dat->data = safe_malloc(allocated * sizeof(Ang)); /* read data */ inFile = safe_open(inFileName, "r"); /* compile regexp */ re = pcre_compile("^.{7}\t.{4}\t.{6}\t(........)\t(........)\t(........)", 0, &error, &erroffset, NULL); /* count the number of models */ while(fgets(line, 80, inFile) != NULL ) { rc = pcre_exec(re, NULL, line, strlen(line), 0, 0, ovector, OVECCOUNT); if (rc == 4){ pcre_get_substring_list(line, ovector, rc, (const char ***)&substring_list); dat->data[dat->nData].phi1 = atof(substring_list[1]); dat->data[dat->nData].phi2 = atof(substring_list[2]); dat->data[dat->nData].theta = atof(substring_list[3]); ++dat->nData; /* free substring_list memory */ pcre_free_substring_list((const char **)substring_list); } /* allocate more memory if needed */ if (dat->nData == allocated) { allocated += 64; dat->data = safe_realloc(dat->data, allocated * sizeof(Ang)); } } /* free regexp */ pcre_free(re); assert(dat->nData > 1); /* close file handle */ fclose(inFile); return 0; }
static void mud_regex_finalize (GObject *object) { MudRegex *regex; GObjectClass *parent_class; regex = MUD_REGEX(object); if(regex->priv->substring_list) pcre_free_substring_list(regex->priv->substring_list); parent_class = g_type_class_peek_parent(G_OBJECT_GET_CLASS(object)); parent_class->finalize(object); }
std::vector<std::string> Pattern::groups (void) { const char ** stringList; pcre_get_substring_list (_subject.c_str(), _ovector, _count, &stringList); std::vector<std::string> matchedSubstrings; for (int i = 1; stringList[i] != NULL; i++) matchedSubstrings.push_back (stringList[i]); pcre_free_substring_list (stringList); return matchedSubstrings; }
static int zpcre_get_substrings(char *arg, int *ovec, int ret, char *receptacle) { char **captures, **matches; if(!pcre_get_substring_list(arg, ovec, ret, (const char ***)&captures)) { matches = zarrdup(&captures[1]); /* first one would be entire string */ if (receptacle == NULL) setaparam("match", matches); else setaparam(receptacle, matches); pcre_free_substring_list((const char **)captures); } return 0; }
static int zpcre_get_substrings(char *arg, int *ovec, int ret, char *matchvar, char *substravar, int want_offset_pair, int matchedinarr, int want_begin_end) { char **captures, *match_all, **matches; char offset_all[50]; int capture_start = 1; if (matchedinarr) capture_start = 0; if (matchvar == NULL) matchvar = "MATCH"; if (substravar == NULL) substravar = "match"; /* captures[0] will be entire matched string, [1] first substring */ if (!pcre_get_substring_list(arg, ovec, ret, (const char ***)&captures)) { int nelem = arrlen(captures)-1; /* Set to the offsets of the complete match */ if (want_offset_pair) { sprintf(offset_all, "%d %d", ovec[0], ovec[1]); setsparam("ZPCRE_OP", ztrdup(offset_all)); } match_all = metafy(captures[0], -1, META_DUP); setsparam(matchvar, match_all); /* * If we're setting match, mbegin, mend we only do * so if there were parenthesised matches, for consistency * (c.f. regex.c). */ if (!want_begin_end || nelem) { char **x, **y; y = &captures[capture_start]; matches = x = (char **) zalloc(sizeof(char *) * (arrlen(y) + 1)); do { if (*y) *x++ = metafy(*y, -1, META_DUP); else *x++ = NULL; } while (*y++); setaparam(substravar, matches); } if (want_begin_end) { char *ptr = arg; zlong offs = 0; /* Count the characters before the match */ MB_METACHARINIT(); while (ptr < arg + ovec[0]) { offs++; ptr += MB_METACHARLEN(ptr); } setiparam("MBEGIN", offs + !isset(KSHARRAYS)); /* Add on the characters in the match */ while (ptr < arg + ovec[1]) { offs++; ptr += MB_METACHARLEN(ptr); } setiparam("MEND", offs + !isset(KSHARRAYS) - 1); if (nelem) { char **mbegin, **mend, **bptr, **eptr; int i, *ipair; bptr = mbegin = zalloc(sizeof(char*)*(nelem+1)); eptr = mend = zalloc(sizeof(char*)*(nelem+1)); for (ipair = ovec + 2, i = 0; i < nelem; ipair += 2, i++, bptr++, eptr++) { char buf[DIGBUFSIZE]; ptr = arg; offs = 0; /* Find the start offset */ MB_METACHARINIT(); while (ptr < arg + ipair[0]) { offs++; ptr += MB_METACHARLEN(ptr); } convbase(buf, offs + !isset(KSHARRAYS), 10); *bptr = ztrdup(buf); /* Continue to the end offset */ while (ptr < arg + ipair[1]) { offs++; ptr += MB_METACHARLEN(ptr); } convbase(buf, offs + !isset(KSHARRAYS) - 1, 10); *eptr = ztrdup(buf); } *bptr = *eptr = NULL; setaparam("mbegin", mbegin); setaparam("mend", mend); } } pcre_free_substring_list((const char **)captures); } return 0; }
int main(int argc, char **argv) { FILE *infile = stdin; int options = 0; int study_options = 0; int op = 1; int timeit = 0; int showinfo = 0; int showstore = 0; int size_offsets = 45; int size_offsets_max; int *offsets; #if !defined NOPOSIX int posix = 0; #endif int debug = 0; int done = 0; unsigned char buffer[30000]; unsigned char dbuffer[1024]; /* Static so that new_malloc can use it. */ outfile = stdout; /* Scan options */ while (argc > 1 && argv[op][0] == '-') { char *endptr; if (strcmp(argv[op], "-s") == 0 || strcmp(argv[op], "-m") == 0) showstore = 1; else if (strcmp(argv[op], "-t") == 0) timeit = 1; else if (strcmp(argv[op], "-i") == 0) showinfo = 1; else if (strcmp(argv[op], "-d") == 0) showinfo = debug = 1; else if (strcmp(argv[op], "-o") == 0 && argc > 2 && ((size_offsets = (int)strtoul(argv[op+1], &endptr, 10)), *endptr == 0)) { op++; argc--; } #if !defined NOPOSIX else if (strcmp(argv[op], "-p") == 0) posix = 1; #endif else { printf("** Unknown or malformed option %s\n", argv[op]); printf("Usage: pcretest [-d] [-i] [-o <n>] [-p] [-s] [-t] [<input> [<output>]]\n"); printf(" -d debug: show compiled code; implies -i\n" " -i show information about compiled pattern\n" " -o <n> set size of offsets vector to <n>\n"); #if !defined NOPOSIX printf(" -p use POSIX interface\n"); #endif printf(" -s output store information\n" " -t time compilation and execution\n"); return 1; } op++; argc--; } /* Get the store for the offsets vector, and remember what it was */ size_offsets_max = size_offsets; offsets = malloc(size_offsets_max * sizeof(int)); if (offsets == NULL) { printf("** Failed to get %d bytes of memory for offsets vector\n", size_offsets_max * sizeof(int)); return 1; } /* Sort out the input and output files */ if (argc > 1) { infile = fopen(argv[op], "r"); if (infile == NULL) { printf("** Failed to open %s\n", argv[op]); return 1; } } if (argc > 2) { outfile = fopen(argv[op+1], "w"); if (outfile == NULL) { printf("** Failed to open %s\n", argv[op+1]); return 1; } } /* Set alternative malloc function */ pcre_malloc = new_malloc; /* Heading line, then prompt for first regex if stdin */ fprintf(outfile, "PCRE version %s\n\n", pcre_version()); /* Main loop */ while (!done) { pcre *re = NULL; pcre_extra *extra = NULL; #if !defined NOPOSIX /* There are still compilers that require no indent */ regex_t preg; int do_posix = 0; #endif const char *error; unsigned char *p, *pp, *ppp; const unsigned char *tables = NULL; int do_study = 0; int do_debug = debug; int do_G = 0; int do_g = 0; int do_showinfo = showinfo; int do_showrest = 0; int utf8 = 0; int erroroffset, len, delimiter; if (infile == stdin) printf(" re> "); if (fgets((char *)buffer, sizeof(buffer), infile) == NULL) break; if (infile != stdin) fprintf(outfile, "%s", (char *)buffer); p = buffer; while (isspace(*p)) p++; if (*p == 0) continue; /* Get the delimiter and seek the end of the pattern; if is isn't complete, read more. */ delimiter = *p++; if (isalnum(delimiter) || delimiter == '\\') { fprintf(outfile, "** Delimiter must not be alphameric or \\\n"); goto SKIP_DATA; } pp = p; for(;;) { while (*pp != 0) { if (*pp == '\\' && pp[1] != 0) pp++; else if (*pp == delimiter) break; pp++; } if (*pp != 0) break; len = sizeof(buffer) - (pp - buffer); if (len < 256) { fprintf(outfile, "** Expression too long - missing delimiter?\n"); goto SKIP_DATA; } if (infile == stdin) printf(" > "); if (fgets((char *)pp, len, infile) == NULL) { fprintf(outfile, "** Unexpected EOF\n"); done = 1; goto CONTINUE; } if (infile != stdin) fprintf(outfile, "%s", (char *)pp); } /* If the first character after the delimiter is backslash, make the pattern end with backslash. This is purely to provide a way of testing for the error message when a pattern ends with backslash. */ if (pp[1] == '\\') *pp++ = '\\'; /* Terminate the pattern at the delimiter */ *pp++ = 0; /* Look for options after final delimiter */ options = 0; study_options = 0; log_store = showstore; /* default from command line */ while (*pp != 0) { switch (*pp++) { case 'g': do_g = 1; break; case 'i': options |= PCRE_CASELESS; break; case 'm': options |= PCRE_MULTILINE; break; case 's': options |= PCRE_DOTALL; break; case 'x': options |= PCRE_EXTENDED; break; case '+': do_showrest = 1; break; case 'A': options |= PCRE_ANCHORED; break; case 'D': do_debug = do_showinfo = 1; break; case 'E': options |= PCRE_DOLLAR_ENDONLY; break; case 'G': do_G = 1; break; case 'I': do_showinfo = 1; break; case 'M': log_store = 1; break; #if !defined NOPOSIX case 'P': do_posix = 1; break; #endif case 'S': do_study = 1; break; case 'U': options |= PCRE_UNGREEDY; break; case 'X': options |= PCRE_EXTRA; break; case '8': options |= PCRE_UTF8; utf8 = 1; break; case 'L': ppp = pp; while (*ppp != '\n' && *ppp != ' ') ppp++; *ppp = 0; if (setlocale(LC_CTYPE, (const char *)pp) == NULL) { fprintf(outfile, "** Failed to set locale \"%s\"\n", pp); goto SKIP_DATA; } tables = pcre_maketables(); pp = ppp; break; case '\n': case ' ': break; default: fprintf(outfile, "** Unknown option '%c'\n", pp[-1]); goto SKIP_DATA; } } /* Handle compiling via the POSIX interface, which doesn't support the timing, showing, or debugging options, nor the ability to pass over local character tables. */ #if !defined NOPOSIX if (posix || do_posix) { int rc; int cflags = 0; if ((options & PCRE_CASELESS) != 0) cflags |= REG_ICASE; if ((options & PCRE_MULTILINE) != 0) cflags |= REG_NEWLINE; rc = regcomp(&preg, (char *)p, cflags); /* Compilation failed; go back for another re, skipping to blank line if non-interactive. */ if (rc != 0) { (void)regerror(rc, &preg, (char *)buffer, sizeof(buffer)); fprintf(outfile, "Failed: POSIX code %d: %s\n", rc, buffer); goto SKIP_DATA; } } /* Handle compiling via the native interface */ else #endif /* !defined NOPOSIX */ { if (timeit) { register int i; clock_t time_taken; clock_t start_time = clock(); for (i = 0; i < LOOPREPEAT; i++) { re = pcre_compile((char *)p, options, &error, &erroroffset, tables); if (re != NULL) free(re); } time_taken = clock() - start_time; fprintf(outfile, "Compile time %.3f milliseconds\n", ((double)time_taken * 1000.0) / ((double)LOOPREPEAT * (double)CLOCKS_PER_SEC)); } re = pcre_compile((char *)p, options, &error, &erroroffset, tables); /* Compilation failed; go back for another re, skipping to blank line if non-interactive. */ if (re == NULL) { fprintf(outfile, "Failed: %s at offset %d\n", error, erroroffset); SKIP_DATA: if (infile != stdin) { for (;;) { if (fgets((char *)buffer, sizeof(buffer), infile) == NULL) { done = 1; goto CONTINUE; } len = (int)strlen((char *)buffer); while (len > 0 && isspace(buffer[len-1])) len--; if (len == 0) break; } fprintf(outfile, "\n"); } goto CONTINUE; } /* Compilation succeeded; print data if required. There are now two info-returning functions. The old one has a limited interface and returns only limited data. Check that it agrees with the newer one. */ if (do_showinfo) { unsigned long int get_options; int old_first_char, old_options, old_count; int count, backrefmax, first_char, need_char; size_t size; if (do_debug) print_internals(re); new_info(re, NULL, PCRE_INFO_OPTIONS, &get_options); new_info(re, NULL, PCRE_INFO_SIZE, &size); new_info(re, NULL, PCRE_INFO_CAPTURECOUNT, &count); new_info(re, NULL, PCRE_INFO_BACKREFMAX, &backrefmax); new_info(re, NULL, PCRE_INFO_FIRSTCHAR, &first_char); new_info(re, NULL, PCRE_INFO_LASTLITERAL, &need_char); old_count = pcre_info(re, &old_options, &old_first_char); if (count < 0) fprintf(outfile, "Error %d from pcre_info()\n", count); else { if (old_count != count) fprintf(outfile, "Count disagreement: pcre_fullinfo=%d pcre_info=%d\n", count, old_count); if (old_first_char != first_char) fprintf(outfile, "First char disagreement: pcre_fullinfo=%d pcre_info=%d\n", first_char, old_first_char); if (old_options != (int)get_options) fprintf(outfile, "Options disagreement: pcre_fullinfo=%ld pcre_info=%d\n", get_options, old_options); } if (size != gotten_store) fprintf(outfile, "Size disagreement: pcre_fullinfo=%d call to malloc for %d\n", size, gotten_store); fprintf(outfile, "Capturing subpattern count = %d\n", count); if (backrefmax > 0) fprintf(outfile, "Max back reference = %d\n", backrefmax); if (get_options == 0) fprintf(outfile, "No options\n"); else fprintf(outfile, "Options:%s%s%s%s%s%s%s%s%s\n", ((get_options & PCRE_ANCHORED) != 0)? " anchored" : "", ((get_options & PCRE_CASELESS) != 0)? " caseless" : "", ((get_options & PCRE_EXTENDED) != 0)? " extended" : "", ((get_options & PCRE_MULTILINE) != 0)? " multiline" : "", ((get_options & PCRE_DOTALL) != 0)? " dotall" : "", ((get_options & PCRE_DOLLAR_ENDONLY) != 0)? " dollar_endonly" : "", ((get_options & PCRE_EXTRA) != 0)? " extra" : "", ((get_options & PCRE_UNGREEDY) != 0)? " ungreedy" : "", ((get_options & PCRE_UTF8) != 0)? " utf8" : ""); if (((((real_pcre *)re)->options) & PCRE_ICHANGED) != 0) fprintf(outfile, "Case state changes\n"); if (first_char == -1) { fprintf(outfile, "First char at start or follows \\n\n"); } else if (first_char < 0) { fprintf(outfile, "No first char\n"); } else { if (isprint(first_char)) fprintf(outfile, "First char = \'%c\'\n", first_char); else fprintf(outfile, "First char = %d\n", first_char); } if (need_char < 0) { fprintf(outfile, "No need char\n"); } else { if (isprint(need_char)) fprintf(outfile, "Need char = \'%c\'\n", need_char); else fprintf(outfile, "Need char = %d\n", need_char); } } /* If /S was present, study the regexp to generate additional info to help with the matching. */ if (do_study) { if (timeit) { register int i; clock_t time_taken; clock_t start_time = clock(); for (i = 0; i < LOOPREPEAT; i++) extra = pcre_study(re, study_options, &error); time_taken = clock() - start_time; if (extra != NULL) free(extra); fprintf(outfile, " Study time %.3f milliseconds\n", ((double)time_taken * 1000.0)/ ((double)LOOPREPEAT * (double)CLOCKS_PER_SEC)); } extra = pcre_study(re, study_options, &error); if (error != NULL) fprintf(outfile, "Failed to study: %s\n", error); else if (extra == NULL) fprintf(outfile, "Study returned NULL\n"); else if (do_showinfo) { uschar *start_bits = NULL; new_info(re, extra, PCRE_INFO_FIRSTTABLE, &start_bits); if (start_bits == NULL) fprintf(outfile, "No starting character set\n"); else { int i; int c = 24; fprintf(outfile, "Starting character set: "); for (i = 0; i < 256; i++) { if ((start_bits[i/8] & (1<<(i%8))) != 0) { if (c > 75) { fprintf(outfile, "\n "); c = 2; } if (isprint(i) && i != ' ') { fprintf(outfile, "%c ", i); c += 2; } else { fprintf(outfile, "\\x%02x ", i); c += 5; } } } fprintf(outfile, "\n"); } } } } /* Read data lines and test them */ for (;;) { unsigned char *q; unsigned char *bptr = dbuffer; int *use_offsets = offsets; int use_size_offsets = size_offsets; int count, c; int copystrings = 0; int getstrings = 0; int getlist = 0; int gmatched = 0; int start_offset = 0; int g_notempty = 0; options = 0; if (infile == stdin) printf("data> "); if (fgets((char *)buffer, sizeof(buffer), infile) == NULL) { done = 1; goto CONTINUE; } if (infile != stdin) fprintf(outfile, "%s", (char *)buffer); len = (int)strlen((char *)buffer); while (len > 0 && isspace(buffer[len-1])) len--; buffer[len] = 0; if (len == 0) break; p = buffer; while (isspace(*p)) p++; q = dbuffer; while ((c = *p++) != 0) { int i = 0; int n = 0; if (c == '\\') switch ((c = *p++)) { case 'a': c = 7; break; case 'b': c = '\b'; break; case 'e': c = 27; break; case 'f': c = '\f'; break; case 'n': c = '\n'; break; case 'r': c = '\r'; break; case 't': c = '\t'; break; case 'v': c = '\v'; break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': c -= '0'; while (i++ < 2 && isdigit(*p) && *p != '8' && *p != '9') c = c * 8 + *p++ - '0'; break; case 'x': /* Handle \x{..} specially - new Perl thing for utf8 */ if (*p == '{') { unsigned char *pt = p; c = 0; while (isxdigit(*(++pt))) c = c * 16 + tolower(*pt) - ((isdigit(*pt))? '0' : 'W'); if (*pt == '}') { unsigned char buffer[8]; int ii, utn; utn = ord2utf8(c, buffer); for (ii = 0; ii < utn - 1; ii++) *q++ = buffer[ii]; c = buffer[ii]; /* Last byte */ p = pt + 1; break; } /* Not correct form; fall through */ } /* Ordinary \x */ c = 0; while (i++ < 2 && isxdigit(*p)) { c = c * 16 + tolower(*p) - ((isdigit(*p))? '0' : 'W'); p++; } break; case 0: /* Allows for an empty line */ p--; continue; case 'A': /* Option setting */ options |= PCRE_ANCHORED; continue; case 'B': options |= PCRE_NOTBOL; continue; case 'C': while(isdigit(*p)) n = n * 10 + *p++ - '0'; copystrings |= 1 << n; continue; case 'G': while(isdigit(*p)) n = n * 10 + *p++ - '0'; getstrings |= 1 << n; continue; case 'L': getlist = 1; continue; case 'N': options |= PCRE_NOTEMPTY; continue; case 'O': while(isdigit(*p)) n = n * 10 + *p++ - '0'; if (n > size_offsets_max) { size_offsets_max = n; free(offsets); use_offsets = offsets = malloc(size_offsets_max * sizeof(int)); if (offsets == NULL) { printf("** Failed to get %d bytes of memory for offsets vector\n", size_offsets_max * sizeof(int)); return 1; } } use_size_offsets = n; if (n == 0) use_offsets = NULL; continue; case 'Z': options |= PCRE_NOTEOL; continue; } *q++ = c; } *q = 0; len = q - dbuffer; /* Handle matching via the POSIX interface, which does not support timing. */ #if !defined NOPOSIX if (posix || do_posix) { int rc; int eflags = 0; regmatch_t *pmatch = malloc(sizeof(regmatch_t) * use_size_offsets); if ((options & PCRE_NOTBOL) != 0) eflags |= REG_NOTBOL; if ((options & PCRE_NOTEOL) != 0) eflags |= REG_NOTEOL; rc = regexec(&preg, (const char *)bptr, use_size_offsets, pmatch, eflags); if (rc != 0) { (void)regerror(rc, &preg, (char *)buffer, sizeof(buffer)); fprintf(outfile, "No match: POSIX code %d: %s\n", rc, buffer); } else { size_t i; for (i = 0; i < use_size_offsets; i++) { if (pmatch[i].rm_so >= 0) { fprintf(outfile, "%2d: ", (int)i); pchars(dbuffer + pmatch[i].rm_so, pmatch[i].rm_eo - pmatch[i].rm_so, utf8); fprintf(outfile, "\n"); if (i == 0 && do_showrest) { fprintf(outfile, " 0+ "); pchars(dbuffer + pmatch[i].rm_eo, len - pmatch[i].rm_eo, utf8); fprintf(outfile, "\n"); } } } } free(pmatch); } /* Handle matching via the native interface - repeats for /g and /G */ else #endif /* !defined NOPOSIX */ for (;; gmatched++) /* Loop for /g or /G */ { if (timeit) { register int i; clock_t time_taken; clock_t start_time = clock(); for (i = 0; i < LOOPREPEAT; i++) count = pcre_exec(re, extra, (char *)bptr, len, start_offset, options | g_notempty, use_offsets, use_size_offsets); time_taken = clock() - start_time; fprintf(outfile, "Execute time %.3f milliseconds\n", ((double)time_taken * 1000.0)/ ((double)LOOPREPEAT * (double)CLOCKS_PER_SEC)); } count = pcre_exec(re, extra, (char *)bptr, len, start_offset, options | g_notempty, use_offsets, use_size_offsets); if (count == 0) { fprintf(outfile, "Matched, but too many substrings\n"); count = use_size_offsets/3; } /* Matched */ if (count >= 0) { int i; for (i = 0; i < count * 2; i += 2) { if (use_offsets[i] < 0) fprintf(outfile, "%2d: <unset>\n", i/2); else { fprintf(outfile, "%2d: ", i/2); pchars(bptr + use_offsets[i], use_offsets[i+1] - use_offsets[i], utf8); fprintf(outfile, "\n"); if (i == 0) { if (do_showrest) { fprintf(outfile, " 0+ "); pchars(bptr + use_offsets[i+1], len - use_offsets[i+1], utf8); fprintf(outfile, "\n"); } } } } for (i = 0; i < 32; i++) { if ((copystrings & (1 << i)) != 0) { char copybuffer[16]; int rc = pcre_copy_substring((char *)bptr, use_offsets, count, i, copybuffer, sizeof(copybuffer)); if (rc < 0) fprintf(outfile, "copy substring %d failed %d\n", i, rc); else fprintf(outfile, "%2dC %s (%d)\n", i, copybuffer, rc); } } for (i = 0; i < 32; i++) { if ((getstrings & (1 << i)) != 0) { const char *substring; int rc = pcre_get_substring((char *)bptr, use_offsets, count, i, &substring); if (rc < 0) fprintf(outfile, "get substring %d failed %d\n", i, rc); else { fprintf(outfile, "%2dG %s (%d)\n", i, substring, rc); /* free((void *)substring); */ pcre_free_substring(substring); } } } if (getlist) { const char **stringlist; int rc = pcre_get_substring_list((char *)bptr, use_offsets, count, &stringlist); if (rc < 0) fprintf(outfile, "get substring list failed %d\n", rc); else { for (i = 0; i < count; i++) fprintf(outfile, "%2dL %s\n", i, stringlist[i]); if (stringlist[i] != NULL) fprintf(outfile, "string list not terminated by NULL\n"); /* free((void *)stringlist); */ pcre_free_substring_list(stringlist); } } } /* Failed to match. If this is a /g or /G loop and we previously set g_notempty after a null match, this is not necessarily the end. We want to advance the start offset, and continue. Fudge the offset values to achieve this. We won't be at the end of the string - that was checked before setting g_notempty. */ else { if (g_notempty != 0) { use_offsets[0] = start_offset; use_offsets[1] = start_offset + 1; } else { if (gmatched == 0) /* Error if no previous matches */ { if (count == -1) fprintf(outfile, "No match\n"); else fprintf(outfile, "Error %d\n", count); } break; /* Out of the /g loop */ } } /* If not /g or /G we are done */ if (!do_g && !do_G) break; /* If we have matched an empty string, first check to see if we are at the end of the subject. If so, the /g loop is over. Otherwise, mimic what Perl's /g options does. This turns out to be rather cunning. First we set PCRE_NOTEMPTY and PCRE_ANCHORED and try the match again at the same point. If this fails (picked up above) we advance to the next character. */ g_notempty = 0; if (use_offsets[0] == use_offsets[1]) { if (use_offsets[0] == len) break; g_notempty = PCRE_NOTEMPTY | PCRE_ANCHORED; } /* For /g, update the start offset, leaving the rest alone */ if (do_g) start_offset = use_offsets[1]; /* For /G, update the pointer and length */ else { bptr += use_offsets[1]; len -= use_offsets[1]; } } /* End of loop for /g and /G */ } /* End of loop for data lines */ CONTINUE: #if !defined NOPOSIX if (posix || do_posix) regfree(&preg); #endif if (re != NULL) free(re); if (extra != NULL) free(extra); if (tables != NULL) { free((void *)tables); setlocale(LC_CTYPE, "C"); } } fprintf(outfile, "\n"); return 0; }
static int mod_ssi_handle_request(server *srv, connection *con, plugin_data *p) { stream s; #ifdef HAVE_PCRE_H int i, n; #define N 10 int ovec[N * 3]; #endif stat_cache_entry *sce = NULL; /* get a stream to the file */ array_reset(p->ssi_vars); array_reset(p->ssi_cgi_env); buffer_copy_string_len(p->timefmt, CONST_STR_LEN("%a, %d %b %Y %H:%M:%S %Z")); p->sizefmt = 0; build_ssi_cgi_vars(srv, con, p); p->if_is_false = 0; /* Reset the modified time of included files */ include_file_last_mtime = 0; if (HANDLER_ERROR == stat_cache_get_entry(srv, con, con->physical.path, &sce)) { log_error_write(srv, __FILE__, __LINE__, "SB", "stat_cache_get_entry failed: ", con->physical.path); return -1; } if (-1 == stream_open(&s, con->physical.path)) { log_error_write(srv, __FILE__, __LINE__, "sb", "stream-open: ", con->physical.path); return -1; } /** * <!--#element attribute=value attribute=value ... --> * * config DONE * errmsg -- missing * sizefmt DONE * timefmt DONE * echo DONE * var DONE * encoding -- missing * exec DONE * cgi -- never * cmd DONE * fsize DONE * file DONE * virtual DONE * flastmod DONE * file DONE * virtual DONE * include DONE * file DONE * virtual DONE * printenv DONE * set DONE * var DONE * value DONE * * if DONE * elif DONE * else DONE * endif DONE * * * expressions * AND, OR DONE * comp DONE * ${...} -- missing * $... DONE * '...' DONE * ( ... ) DONE * * * * ** all DONE ** * DATE_GMT * The current date in Greenwich Mean Time. * DATE_LOCAL * The current date in the local time zone. * DOCUMENT_NAME * The filename (excluding directories) of the document requested by the user. * DOCUMENT_URI * The (%-decoded) URL path of the document requested by the user. Note that in the case of nested include files, this is not then URL for the current document. * LAST_MODIFIED * The last modification date of the document requested by the user. * USER_NAME * Contains the owner of the file which included it. * */ #ifdef HAVE_PCRE_H for (i = 0; (n = pcre_exec(p->ssi_regex, NULL, s.start, s.size, i, 0, ovec, N * 3)) > 0; i = ovec[1]) { const char **l; /* take everything from last offset to current match pos */ if (!p->if_is_false) chunkqueue_append_file(con->write_queue, con->physical.path, i, ovec[0] - i); pcre_get_substring_list(s.start, ovec, n, &l); process_ssi_stmt(srv, con, p, l, n, sce); pcre_free_substring_list(l); } switch(n) { case PCRE_ERROR_NOMATCH: /* copy everything/the rest */ chunkqueue_append_file(con->write_queue, con->physical.path, i, s.size - i); break; default: log_error_write(srv, __FILE__, __LINE__, "sd", "execution error while matching: ", n); break; } #endif stream_close(&s); con->file_started = 1; con->file_finished = 1; con->mode = p->id; if (p->conf.content_type->used <= 1) { response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/html")); } else { response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_BUF_LEN(p->conf.content_type)); } { /* Generate "ETag" & "Last-Modified" headers */ time_t lm_time = 0; buffer *mtime = NULL; etag_mutate(con->physical.etag, sce->etag); response_header_overwrite(srv, con, CONST_STR_LEN("ETag"), CONST_BUF_LEN(con->physical.etag)); if (sce->st.st_mtime > include_file_last_mtime) lm_time = sce->st.st_mtime; else lm_time = include_file_last_mtime; mtime = strftime_cache_get(srv, lm_time); response_header_overwrite(srv, con, CONST_STR_LEN("Last-Modified"), CONST_BUF_LEN(mtime)); } /* Reset the modified time of included files */ include_file_last_mtime = 0; /* reset physical.path */ buffer_reset(con->physical.path); return 0; }
bool eas::Decode(const char *s, Message &message) { const char *errptr; int erroffset; pcre *re = pcre_compile( "^ZCZC-(\\w+)-(\\w+)((?:-[^+-]+){1,31})\\+(\\d{2})(\\d{2})-(\\d{3})(\\d{2})(\\d{2})-([^-]+)-", // 1 2 3 4 5 6 7 8 9 0, &errptr, &erroffset, NULL); if (re == NULL) { return false; } int ovector[3*10]; int r = pcre_exec( re, NULL, s, strlen(s), 0, 0, ovector, sizeof(ovector)/sizeof(ovector[0])); pcre_free(re); if (r < 0) { return false; } const char **matches; pcre_get_substring_list(s, ovector, r, &matches); int yday = atoi(matches[6]); time_t now = time(0); struct tm *tt; for (;;) { tt = gmtime(&now); if (1+tt->tm_yday == yday) { break; } else if (1+tt->tm_yday < yday) { now += 86400; } else if (1+tt->tm_yday > yday) { now -= 86400; } } tt->tm_hour = atoi(matches[7]); tt->tm_min = atoi(matches[8]); tt->tm_sec = 0; message.raw = s; message.originator = matches[1]; message.originator_desc = getOriginatorDesc(message.originator); message.event = matches[2]; message.event_desc = getEventDesc(message.event); message.areas.clear(); string a; for (const char *p = matches[3]; ; p++) { if (*p == '-' || *p == 0) { if (*p == '-') { p++; } if (!a.empty()) { Message::Area area; area.code = a; if (a.length() == 6 && strspn(a.c_str(), "0123456789") == 6) { area.part = a[0] - '0'; area.state = 10*(a[1] - '0') + (a[2] - '0'); area.county = 10*(10*(a[3] - '0') + (a[4] - '0')) + (a[5] - '0'); } area.desc = getAreaDesc(area); message.areas.push_back(area); } a.erase(); if (*p == 0) { break; } } a += *p; } message.issued = mkgmtime(tt); message.received = time(0); message.purge = message.issued + 60*(60*atoi(matches[4]) + atoi(matches[5])); message.sender = matches[9]; message.sender_desc = getSenderDesc(message.sender); pcre_free_substring_list(matches); return true; }
void mud_regex_substring_clear(const gchar **substring_list) { pcre_free_substring_list(substring_list); }