extern int ex(unsigned char* str, unsigned char* pattern, OnigSyntaxType* syntax) { int r; unsigned char *start, *range, *end; regex_t* reg; OnigErrorInfo einfo; OnigRegion *region; r = onig_new(®, pattern, pattern + strlen((char* )pattern), ONIG_OPTION_DEFAULT, ONIG_ENCODING_ASCII, syntax, &einfo); if (r != ONIG_NORMAL) { char s[ONIG_MAX_ERROR_MESSAGE_LEN]; onig_error_code_to_str(s, r, &einfo); fprintf(stderr, "ERROR: %s\n", s); return -1; } fprintf(stderr, "number of captures: %d\n", onig_number_of_captures(reg)); fprintf(stderr, "number of capture histories: %d\n", onig_number_of_capture_histories(reg)); region = onig_region_new(); end = str + strlen((char* )str); start = str; range = end; r = onig_search(reg, str, end, start, range, region, ONIG_OPTION_NONE); if (r >= 0) { int i; fprintf(stderr, "match at %d\n", r); for (i = 0; i < region->num_regs; i++) { fprintf(stderr, "%d: (%ld-%ld)\n", i, region->beg[i], region->end[i]); } fprintf(stderr, "\n"); r = onig_capture_tree_traverse(region, ONIG_TRAVERSE_CALLBACK_AT_FIRST, node_callback, (void* )0); } else if (r == ONIG_MISMATCH) { fprintf(stderr, "search fail\n"); } else { /* error */ char s[ONIG_MAX_ERROR_MESSAGE_LEN]; onig_error_code_to_str(s, r); return -1; } onig_region_free(region, 1 /* 1:free self, 0:free contents only */); onig_free(reg); return 0; }
regexp_splitter::regexp_splitter(const std::string& regexp, int group) : reg_(NULL), group_(group) { if (group < 0) { throw JUBATUS_EXCEPTION(converter_exception("'group' must be positive")); } const UChar* pattern = reinterpret_cast<const UChar*>(regexp.data()); if (ONIG_NORMAL != onig_new(®_, pattern, pattern + regexp.size(), ONIG_OPTION_DEFAULT, ONIG_ENCODING_UTF8, ONIG_SYNTAX_PERL, NULL)) { throw JUBATUS_EXCEPTION(converter_exception("invalid regular expression")); } const int num_capture = onig_number_of_captures(reg_); if (group > num_capture) { std::string msg = "regexp '" + regexp + "' only contains " + lexical_cast<std::string>(num_capture) + " groups, but 'group' is " + lexical_cast<std::string>(group); throw JUBATUS_EXCEPTION(converter_exception(msg)); } }
bregonig *recompile_onig_ex(bregonig *rxold, pattern_type type, const TCHAR *ptn, const TCHAR *patternp, const TCHAR *patternendp, const TCHAR *prerepp, const TCHAR *prerependp, const TCHAR *optionp, const TCHAR *optionendp, TCHAR *msg) { int flag, compare; bregonig *rx; OnigOptionType option; OnigEncoding enc; TRACE0(_T("recompile_onig_ex()\n")); TRACE2(_T("patternp: %s, len: %d\n"), patternp, patternendp-patternp); TRACE2(_T("prerepp: %s, len: %d\n"), prerepp, prerependp-prerepp); TRACE2(_T("optionp: %s, len: %d\n"), optionp, optionendp-optionp); compare = compare_pattern(rxold, type, patternp, patternendp, prerepp, prerependp, optionp, optionendp); TRACE1(_T("compare: %d\n"), compare); if (compare < 0) { // need to compile delete rxold; rxold = NULL; if (patternp == NULL || ((type == PTN_SUBST || type == PTN_TRANS) && prerepp == NULL)) { asc2tcs(msg, "invalid reg parameter", BREGEXP_MAX_ERROR_MESSAGE_LEN); return NULL; } } else { // no need to compile if (rxold->outp) { delete [] rxold->outp; rxold->outp = NULL; } if (rxold->splitp) { delete [] rxold->splitp; rxold->splitp = NULL; } } parse_option(optionp, optionendp, &option, &enc, &flag); if (type == PTN_TRANS) { if (compare == 0) { // no need to compile TRACE1(_T("rxold(1):0x%08x\n"), rxold); return rxold; } rx = trcomp(patternp, patternendp, prerepp, prerependp, flag, msg); if (rx == NULL) { return NULL; } } else { if (compare == 0) { // no need to compile TRACE1(_T("rxold(2):0x%08x\n"), rxold); return rxold; } else if (compare < 0) { // pattern string needs to compile. rx = new (std::nothrow) bregonig(); if (rx == NULL) { asc2tcs(msg, "out of space regexp", BREGEXP_MAX_ERROR_MESSAGE_LEN); return NULL; } OnigErrorInfo err_info; int err_code = onig_new(&rx->reg, (UChar*) patternp, (UChar*) patternendp, option, enc, &OnigSyntaxPerl_NG_EX, &err_info); if (err_code != ONIG_NORMAL) { onig_err_to_bregexp_msg(err_code, &err_info, msg); delete rx; return NULL; } rx->nparens = onig_number_of_captures(rx->reg); // rx->pmflags = flag; } else { // only replace string needs to compile. rx = rxold; } if (rxold != NULL && rxold->repstr != NULL) { delete rxold->repstr; rxold->repstr = NULL; } if (type == PTN_SUBST) { // substitute try { rx->pmflags |= PMf_SUBSTITUTE; rx->repstr = compile_rep(rx, prerepp, prerependp); // compile replace string } catch (std::exception& ex) { asc2tcs(msg, ex.what(), BREGEXP_MAX_ERROR_MESSAGE_LEN); delete rx; return NULL; } } } if (ptn != NULL) { size_t plen = _tcslen(ptn); delete [] rx->parap; rx->parap = new (std::nothrow) TCHAR[plen+1]; // parameter copy if (rx->parap == NULL) { asc2tcs(msg, "precompile out of space", BREGEXP_MAX_ERROR_MESSAGE_LEN); delete rx; return NULL; } memcpy(rx->parap, ptn, (plen+1)*sizeof(TCHAR)); // copy include null rx->paraendp = rx->parap + plen; } TCHAR *oldpatternp = rx->patternp; if (patternp == NULL) { patternp = rx->patternp; patternendp = rx->patternendp; optionp = rx->optionp; optionendp = rx->optionendp; } /* save pattern, replace and option string */ ptrdiff_t len1 = patternendp - patternp; ptrdiff_t len2 = prerependp - prerepp; ptrdiff_t len3 = optionendp - optionp; rx->patternp = new (std::nothrow) TCHAR[len1+1 + len2+1 + len3+1]; if (rx->patternp == NULL) { delete rx; delete [] oldpatternp; return NULL; } memcpy(rx->patternp, patternp, len1*sizeof(TCHAR)); rx->patternp[len1] = 0; rx->patternendp = rx->patternp + len1; rx->prerepp = rx->patternp + len1 + 1; memcpy(rx->prerepp, prerepp, len2*sizeof(TCHAR)); rx->prerepp[len2] = 0; rx->prerependp = rx->prerepp + len2; rx->optionp = rx->prerepp + len2 + 1; memcpy(rx->optionp, optionp, len3*sizeof(TCHAR)); rx->optionp[len3] = 0; rx->optionendp = rx->optionp + len3; delete [] oldpatternp; TRACE1(_T("rx:0x%08x\n"), rx); return rx; }
static int LOnig_capturecount (lua_State *L) { TOnig *ud = check_ud(L); lua_pushinteger(L, onig_number_of_captures(ud->reg)); return 1; }