static cell_t CompileRegex(IPluginContext *pCtx, const cell_t *params) { char *regex; pCtx->LocalToString(params[1], ®ex); RegEx *x = new RegEx(); if (x->Compile(regex, params[2]) == 0) { cell_t *eError; pCtx->LocalToPhysAddr(params[5], &eError); const char *err = x->mError; // Convert error code to posix error code but use pcre's error string since it is more detailed. *eError = pcre_posix_compile_error_map[x->mErrorCode]; pCtx->StringToLocal(params[3], params[4], err ? err:"unknown"); delete x; return 0; } HandleError error = HandleError_None; Handle_t regexHandle = g_pHandleSys->CreateHandle(g_RegexHandle, (void*)x, pCtx->GetIdentity(), myself->GetIdentity(), &error); if (!regexHandle || error != HandleError_None) { delete x; pCtx->ReportError("Allocation of regex handle failed, error code #%d", error); return 0; } return regexHandle; }
// native Regex:regex_compile_ex(const pattern[], flags = 0, error[] = "", maxLen = 0, &errcode = 0); static cell AMX_NATIVE_CALL regex_compile_ex(AMX *amx, cell *params) { int len; const char *regex = MF_GetAmxString(amx, params[1], 0, &len); int id = GetPEL(); RegEx *x = PEL[id]; if (x->Compile(regex, params[2]) == 0) { const char *err = x->mError; *MF_GetAmxAddr(amx, params[5]) = x->mErrorOffset; MF_SetAmxString(amx, params[3], err ? err : "unknown", params[4]); return -1; } return id + 1; }
cell match(AMX *amx, cell *params, bool all) { int len; const char *str = MF_GetAmxString(amx, params[1], 0, &len); const char *regex = MF_GetAmxString(amx, params[2], 1, &len); int id = GetPEL(); RegEx *x = PEL[id]; char *flags = NULL; cell *errorCode; int result = 0; if (!all) { if (*params / sizeof(cell) >= 6) // compiled with 1.8's extra parameter { flags = MF_GetAmxString(amx, params[6], 2, &len); } result = x->Compile(regex, flags); errorCode = MF_GetAmxAddr(amx, params[3]); } else { result = x->Compile(regex, params[3]); errorCode = MF_GetAmxAddr(amx, params[6]); } if (!result) { const char *err = x->mError; *errorCode = x->mErrorOffset; MF_SetAmxString(amx, params[4], err ? err : "unknown", params[5]); return -1; } int e; if (all) e = x->MatchAll(str); else e = x->Match(str); if (e == -1) { /* there was a match error. destroy this and move on. */ *errorCode = x->mErrorOffset; x->Clear(); return -2; } else if (e == 0) { *errorCode = 0; x->Clear(); return 0; } else { *errorCode = x->Count(); if (all) return x->Count(); } return id + 1; }
int main( int argc, char **argv ) { RegEx re; re.Compile("abcd"); assert ( true == re.Match("abcd")); assert ( true == re.Match("abcde")); assert ( true == re.Match("acde")); re.Compile("ab*"); assert ( true == re.Match("ac")); assert ( true == re.Match("abc")); assert ( true == re.Match("abbc")); assert ( true == re.Match("acbb")); assert ( false == re.Match("xcbb")); re.Compile("ab+"); assert ( true == re.Match("abc")); assert ( true == re.Match("abbc")); assert ( false == re.Match ("ac")); re.Compile("ab?"); assert ( true == re.Match("ac")); assert ( true == re.Match("abc")); assert ( true == re.Match ("abbc")); re.Compile("a|b*"); assert ( true == re.Match("a")); assert ( true == re.Match("b")); assert ( true == re.Match ("bbb")); assert ( true == re.Match ("bb")); re.Compile("(a|b)*"); assert ( true == re.Match("a")); assert ( true == re.Match("b")); assert ( true == re.Match ("aa")); assert ( true == re.Match ("ab")); assert ( true == re.Match ("ba")); assert ( true == re.Match ("bb")); assert ( true == re.Match ("aaa")); re.Compile("a*b"); assert ( false == re.Match("a")); assert ( true == re.Match("ab")); assert ( true == re.Match("aaaabbbcccb")); assert ( false == re.Match("a12344b")); assert ( false == re.Match("a@#$@#$b")); assert ( true == re.Match("b")); re.Compile("(a|b)*abb"); assert ( true == re.Match("abb")); assert ( true == re.Match("aabb")); assert ( true == re.Match("babb")); assert ( true == re.Match("aaabb")); assert ( true == re.Match("bbabb")); assert ( true == re.Match("ababb")); assert ( true == re.Match("aababb")); re.Compile("ab[0-9]"); assert ( true == re.Match("ab0")); assert ( true == re.Match("ab1")); assert ( true == re.Match("ab2")); assert ( true == re.Match("ab3")); assert ( true == re.Match("ab4")); assert ( true == re.Match("ab5")); assert ( true == re.Match("ab6")); assert ( true == re.Match("ab7")); assert ( true == re.Match("ab8")); assert ( true == re.Match("ab9")); assert ( true == re.Match("ab199")); re.Compile("XYZ[aeiou]"); assert ( true == re.Match("XYZa")); assert ( true == re.Match("XYZe")); assert ( true == re.Match("XYZi")); assert ( true == re.Match("XYZo")); assert ( true == re.Match("XYZu")); assert ( false == re.Match("XYZb")); return 0; }