diff --git a/dlls/regex/module.cpp b/dlls/regex/module.cpp index d3048a1b..9bb08737 100755 --- a/dlls/regex/module.cpp +++ b/dlls/regex/module.cpp @@ -64,9 +64,8 @@ static cell AMX_NATIVE_CALL regex_compile(AMX *amx, cell *params) if (x->Compile(regex, flags) == 0) { - cell *eOff = MF_GetAmxAddr(amx, params[2]); const char *err = x->mError; - *eOff = x->mErrorOffset; + *MF_GetAmxAddr(amx, params[2]) = x->mErrorOffset; MF_SetAmxString(amx, params[3], err?err:"unknown", params[4]); return -1; } @@ -74,7 +73,7 @@ static cell AMX_NATIVE_CALL regex_compile(AMX *amx, cell *params) return id+1; } -// native Regex:regex_compile_ex(const pattern[], flags = 0, error[] = "", maxLen = 0, &RegexError:errcode = REGEX_ERROR_NONE); +// 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; @@ -85,9 +84,8 @@ static cell AMX_NATIVE_CALL regex_compile_ex(AMX *amx, cell *params) if (x->Compile(regex, params[2]) == 0) { - cell *eOff = MF_GetAmxAddr(amx, params[5]); const char *err = x->mError; - *eOff = x->mErrorOffset; + *MF_GetAmxAddr(amx, params[5]) = x->mErrorOffset; MF_SetAmxString(amx, params[3], err ? err : "unknown", params[4]); return -1; } @@ -104,23 +102,36 @@ cell match(AMX *amx, cell *params, bool all) int id = GetPEL(); RegEx *x = PEL[id]; - char* flags = NULL; + char *flags = NULL; + cell *errorCode; + int result = 0; - if ((params[0] / sizeof(cell)) >= 6) // compiled with 1.8's extra parameter + if (!all) { - flags = MF_GetAmxString(amx, params[6], 2, &len); + 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 (x->Compile(regex, flags) == 0) + if (!result) { - cell *eOff = MF_GetAmxAddr(amx, params[3]); const char *err = x->mError; - *eOff = x->mErrorOffset; + *errorCode = x->mErrorOffset; MF_SetAmxString(amx, params[4], err ? err : "unknown", params[5]); return -1; } int e; + if (all) e = x->MatchAll(str); else @@ -129,33 +140,31 @@ cell match(AMX *amx, cell *params, bool all) if (e == -1) { /* there was a match error. destroy this and move on. */ - cell *res = MF_GetAmxAddr(amx, params[3]); - *res = x->mErrorOffset; + *errorCode = x->mErrorOffset; x->Clear(); return -2; } - else if (e == 0) { - cell *res = MF_GetAmxAddr(amx, params[3]); - *res = 0; + else if (e == 0) + { + *errorCode = 0; x->Clear(); return 0; } - else { - cell *res = MF_GetAmxAddr(amx, params[3]); - *res = x->Count(); + else + { + *errorCode = x->Count(); } return id + 1; } -// 1.8 includes the last parameter -// Regex:regex_match(const string[], const pattern[], &ret, error[], maxLen, const flags[] = ""); +// native Regex:regex_match(const string[], const pattern[], &ret, error[], maxLen, const flags[] = ""); static cell AMX_NATIVE_CALL regex_match(AMX *amx, cell *params) { return match(amx, params, false); } -// Regex:regex_match_all(const string[], const pattern[], &ret, error[], maxLen, const flags[] = ""); +// native Regex:regex_match_all(const string[], const pattern[], flags = 0, error[] = "", maxLen = 0, &errcode = 0); static cell AMX_NATIVE_CALL regex_match_all(AMX *amx, cell *params) { return match(amx, params, true); @@ -163,9 +172,7 @@ static cell AMX_NATIVE_CALL regex_match_all(AMX *amx, cell *params) cell match_c(AMX *amx, cell *params, bool all) { - int len; int id = params[2] - 1; - const char *str = MF_GetAmxString(amx, params[1], 0, &len); if (id >= (int)PEL.length() || id < 0 || PEL[id]->isFree()) { @@ -173,6 +180,10 @@ cell match_c(AMX *amx, cell *params, bool all) return 0; } + int len; + const char *str = MF_GetAmxString(amx, params[1], 0, &len); + cell *errorCode = MF_GetAmxAddr(amx, params[3]); + RegEx *x = PEL[id]; int e; @@ -184,24 +195,25 @@ cell match_c(AMX *amx, cell *params, bool all) if (e == -1) { /* there was a match error. move on. */ - cell *res = MF_GetAmxAddr(amx, params[3]); - *res = x->mErrorOffset; + *errorCode = x->mErrorOffset; + /* only clear the match results, since the regex object may still be referenced later */ x->ClearMatch(); return -2; } - else if (e == 0) { - cell *res = MF_GetAmxAddr(amx, params[3]); - *res = 0; + else if (e == 0) + { + *errorCode = 0; + /* only clear the match results, since the regex object may still be referenced later */ x->ClearMatch(); return 0; } - else { - cell *res = MF_GetAmxAddr(amx, params[3]); - *res = x->Count(); + else + { + *errorCode = x->Count(); return x->Count(); } } @@ -218,47 +230,7 @@ static cell AMX_NATIVE_CALL regex_match_all_c(AMX *amx, cell *params) return match_c(amx, params, true); } -// native regex_match_ex(Regex:id, const string[], &RegexError:ret = REGEX_ERROR_NONE); -static cell AMX_NATIVE_CALL regex_match_ex(AMX *amx, cell *params) -{ - int id = params[1] - 1; - - if (id >= (int)PEL.length() || id < 0 || PEL[id]->isFree()) - { - MF_LogError(amx, AMX_ERR_NATIVE, "Invalid regex handle %d", id); - return 0; - } - - int len; - const char *str = MF_GetAmxString(amx, params[2], 0, &len); - - RegEx *x = PEL[id]; - - int e = x->Match(str); - if (e == -1) - { - /* there was a match error. move on. */ - cell *res = MF_GetAmxAddr(amx, params[3]); - *res = x->mErrorOffset; - - /* only clear the match results, since the regex object - may still be referenced later */ - x->ClearMatch(); - return -2; - } - else if (e == 0) - { - /* only clear the match results, since the regex object - may still be referenced later */ - x->ClearMatch(); - return 0; - } - else - { - return x->Count(); - } -} - +// native regex_substr(Regex:id, str_id, buffer[], maxLen); static cell AMX_NATIVE_CALL regex_substr(AMX *amx, cell *params) { int id = params[1]-1; @@ -305,7 +277,6 @@ AMX_NATIVE_INFO regex_Natives[] = { {"regex_compile_ex", regex_compile_ex}, {"regex_match", regex_match}, {"regex_match_c", regex_match_c}, - {"regex_match_ex", regex_match_ex}, {"regex_match_all", regex_match_all}, {"regex_match_all_c", regex_match_all_c}, {"regex_substr", regex_substr}, diff --git a/plugins/include/regex.inc b/plugins/include/regex.inc index 32f9646c..9bff0b08 100755 --- a/plugins/include/regex.inc +++ b/plugins/include/regex.inc @@ -50,121 +50,6 @@ enum Regex REGEX_OK }; -/** - * Precompile a regular expression. - * - * @note Use this if you intend on using the ame expression multiple times. - * Pass the regex handle returned here to regex_match_c to check for matches. - * - * @note This handle is automatically freed on map change. However, - * if you are completely done with it before then, you should - * call regex_free on this handle. - * - * @param pattern The regular expression pattern. - * @param ret Error code encountered, if applicable. - * @param error Error message encountered, if applicable. - * @param maxLen Maximum string length of the error buffer. - * @param flags General flags for the regular expression. - * i = Ignore case - * m = Multilines (affects ^ and $ so that they match - * the start/end of a line rather than matching the - * start/end of the string). - * s = Single line (affects . so that it matches any character, - * even new line characters). - * x = Pattern extension (ignore whitespace and # comments). - * - * @return -1 on error in the pattern, > valid regex handle (> 0) on success. - */ -native Regex:regex_compile(const pattern[], &ret, error[], maxLen, const flags[]=""); - -/** - * Matches a string against a pre-compiled regular expression pattern. - * - * @note You should free the returned handle with regex_free() - * when you are done with this pattern. - * - * @note Use the regex handle passed to this function to extract - * matches with regex_substr(). - * - * @param string The string to check. - * @param pattern The regular expression pattern. - * @param ret Error code, if applicable, or number of results on success. - * - * @return -2 = Matching error (error code is stored in ret) - * 0 = No match. - * >1 = Number of results. - */ -native regex_match_c(const string[], Regex:pattern, &ret); - -/** - * Matches a string against a regular expression pattern. - * - * @note If you intend on using the same regular expression pattern - * multiple times, consider using regex_compile and regex_match_ex - * instead of making this function reparse the expression each time. - * - * @note Flags only exist in amxmodx 1.8 and later. - * - * @note You should free the returned handle with regex_free() - * when you are done extracting all of the substrings. - * - * @param string The string to check. - * @param pattern The regular expression pattern. - * @param ret Error code, or result state of the match. - * @param error Error message, if applicable. - * @param maxLen Maximum length of the error buffer. - * @param flags General flags for the regular expression. - * i = Ignore case - * m = Multilines (affects ^ and $ so that they match - * the start/end of a line rather than matching the - * start/end of the string). - * s = Single line (affects . so that it matches any character, - * even new line characters). - * x = Pattern extension (ignore whitespace and # comments). - * - * @return -2 = Matching error (error code is stored in ret) - * -1 = Error in pattern (error message and offset # in error and ret) - * 0 = No match. - * >1 = Handle for getting more information (via regex_substr) - */ -native Regex:regex_match(const string[], const pattern[], &ret, error[], maxLen, const flags[] = ""); - -/** - * Returns a matched substring from a regex handle. - * - * @note Substring ids start at 0 and end at ret - 1, where ret is from the corresponding - * regex_match, regex_match_c or regex_match_ex function call. - * - * @param id The regex handle to extract data from. - * @param str_id The index of the expression to get - starts at 0, and ends at ret - 1. - * @param buffer The buffer to set to the matching substring. - * @param maxLen The maximum string length of the buffer. - * - * @return 1 on success, otherwise 0 on failure. - */ -native regex_substr(Regex:id, str_id, buffer[], maxLen); - -/** - * Frees the memory associated with a regex result, and sets the handle to 0. - * - * @note This must be called on all results from regex_match() when you are done extracting - * the results with regex_substr(). - * - * @note The results of regex_compile() or regex_compile_ex() (and subsequently, regex_match_c() or regex_match_ex()) - * only need to be freed when you are done using the pattern. - * - * @note Do not use the handle again after freeing it! - * - * @param id The regex handle to free. - * @noreturn - */ -native regex_free(&Regex:id); - - -/** - * The following natives are only available in 1.8.3 and above. - */ - /** * Flags for compiling regex expressions. * These come directly from the pcre library and can be used in regex_compile_ex. @@ -187,7 +72,7 @@ native regex_free(&Regex:id); * Regex expression error codes. * This can be used with regex_compile_ex and regex_match_ex. */ -enum RegexError +enum /*RegexError*/ { REGEX_ERROR_NONE = 0, /* No error */ REGEX_ERROR_NOMATCH = -1, /* No match was found */ @@ -225,6 +110,121 @@ enum RegexError REGEX_ERROR_UNSET = -33 }; +/** + * Precompile a regular expression. + * + * @note Use this if you intend on using the ame expression multiple times. + * Pass the regex handle returned here to regex_match_c to check for matches. + * + * @note This handle is automatically freed on map change. However, + * if you are completely done with it before then, you should + * call regex_free on this handle. + * + * @param pattern The regular expression pattern. + * @param ret Error code encountered, if applicable. + * @param error Error message encountered, if applicable. + * @param maxLen Maximum string length of the error buffer. + * @param flags General flags for the regular expression. + * i = Ignore case + * m = Multilines (affects ^ and $ so that they match + * the start/end of a line rather than matching the + * start/end of the string). + * s = Single line (affects . so that it matches any character, + * even new line characters). + * x = Pattern extension (ignore whitespace and # comments). + * + * @return -1 on error in the pattern, > valid regex handle (> 0) on success. + */ +native Regex:regex_compile(const pattern[], &ret = 0, error[] = "", maxLen = 0, const flags[]=""); + +/** + * Matches a string against a pre-compiled regular expression pattern. + * + * @note You should free the returned handle with regex_free() + * when you are done with this pattern. + * + * @note Use the regex handle passed to this function to extract + * matches with regex_substr(). + * + * @param string The string to check. + * @param pattern The regular expression pattern. + * @param ret Error code, if applicable, or number of results on success. See REGEX_ERROR_* defines. + * + * @return -2 = Matching error (error code is stored in ret) + * 0 = No match. + * >1 = Number of results. + */ +native regex_match_c(const string[], Regex:pattern, &ret = 0); + +/** + * Matches a string against a regular expression pattern. + * + * @note If you intend on using the same regular expression pattern + * multiple times, consider using regex_compile and regex_match_ex + * instead of making this function reparse the expression each time. + * + * @note Flags only exist in amxmodx 1.8 and later. + * + * @note You should free the returned handle with regex_free() + * when you are done extracting all of the substrings. + * + * @param string The string to check. + * @param pattern The regular expression pattern. + * @param ret Error code, or result state of the match. + * @param error Error message, if applicable. + * @param maxLen Maximum length of the error buffer. + * @param flags General flags for the regular expression. + * i = Ignore case + * m = Multilines (affects ^ and $ so that they match + * the start/end of a line rather than matching the + * start/end of the string). + * s = Single line (affects . so that it matches any character, + * even new line characters). + * x = Pattern extension (ignore whitespace and # comments). + * + * @return -2 = Matching error (error code is stored in ret) + * -1 = Error in pattern (error message and offset # in error and ret) + * 0 = No match. + * >1 = Handle for getting more information (via regex_substr) + */ +native Regex:regex_match(const string[], const pattern[], &ret = 0, error[] = "", maxLen = 0, const flags[] = ""); + +/** + * Returns a matched substring from a regex handle. + * + * @note Substring ids start at 0 and end at ret - 1, where ret is from the corresponding + * regex_match, regex_match_c or regex_match_ex function call. + * + * @param id The regex handle to extract data from. + * @param str_id The index of the expression to get - starts at 0, and ends at ret - 1. + * @param buffer The buffer to set to the matching substring. + * @param maxLen The maximum string length of the buffer. + * + * @return 1 on success, otherwise 0 on failure. + */ +native regex_substr(Regex:id, str_id, buffer[], maxLen); + +/** + * Frees the memory associated with a regex result, and sets the handle to 0. + * + * @note This must be called on all results from regex_match() when you are done extracting + * the results with regex_substr(). + * + * @note The results of regex_compile() or regex_compile_ex() (and subsequently, regex_match_c() or regex_match_ex()) + * only need to be freed when you are done using the pattern. + * + * @note Do not use the handle again after freeing it! + * + * @param id The regex handle to free. + * @noreturn + */ +native regex_free(&Regex:id); + + +/** + * The following natives are only available in 1.8.3 and above. + */ + /** * Precompile a regular expression. * @@ -238,33 +238,11 @@ enum RegexError * @param flags General flags for the regular expression, see PCRE_* defines. * @param error Error message encountered, if applicable. * @param maxLen Maximum string length of the error buffer. - * @param errcode Regex type error code encountered, if applicable. + * @param errcode Regex type error code encountered, if applicable. See REGEX_ERROR_* defines. * * @return Valid regex handle (> 0) on success, or -1 on failure. */ -native Regex:regex_compile_ex(const pattern[], flags = 0, error[]= "", maxLen = 0, &RegexError:errcode = REGEX_ERROR_NONE); - -/** - * Matches a string against a pre-compiled regular expression pattern. - * - * @note Use the regex handle passed to this function to extract - * matches with regex_substr(). - * - * @note You should free the returned handle with regex_free() - * when you are done with this pattern. - * - * @note Unlike regex_match_c(), this allows you to get a more complete - * set of regular expression error codes and parameter is optional. - * - * @param str The string to check. - * @param regex Regex Handle from regex_compile_ex() - * @param ret Error code, if applicable. - * - * @return -2 = Matching error (error code is stored in ret) - * 0 = No match. - * >1 = Number of results. - */ -native regex_match_ex(Handle:regex, const str[], &RegexError:ret = REGEX_ERROR_NONE); +native Regex:regex_compile_ex(const pattern[], flags = 0, error[]= "", maxLen = 0, &errcode = 0); /** * Matches a string against a pre-compiled regular expression pattern, matching all @@ -272,54 +250,49 @@ native regex_match_ex(Handle:regex, const str[], &RegexError:ret = REGEX_ERROR_N * in perl regex. * * - * @param pattern The regular expression pattern. - * @param string The string to check. - * @param ret Error code, if applicable, or number of results on success. + * @param pattern The regular expression pattern. + * @param string The string to check. + * @param ret Error code, if applicable, or number of results on success. + * See REGEX_ERROR_* defines. * - * @return -2 = Matching error (error code is stored in ret) - * 0 = No match. - * >1 = Number of results. + * @return -2 = Matching error (error code is stored in ret) + * 0 = No match. + * >1 = Number of results. * - * @note You should free the returned handle (with regex_free()) - * when you are done with this pattern. + * @note You should free the returned handle (with regex_free()) + * when you are done with this pattern. * - * @note Use the regex handle passed to this function to extract - * matches with regex_substr(). + * @note Use the regex handle passed to this function to extract + * matches with regex_substr(). */ -native regex_match_all_c(const string[], Regex:pattern, &ret); +native regex_match_all_c(const string[], Regex:pattern, &ret = 0); /** * Matches a string against a regular expression pattern, matching all occurances of the * pattern inside the string. This is similar to using the "g" flag in perl regex. * - * @note If you intend on using the same regular expression pattern - * multiple times, consider using regex_compile and regex_match_c - * instead of making this function reparse the expression each time. + * @note If you intend on using the same regular expression pattern + * multiple times, consider using regex_compile and regex_match_ex + * instead of making this function reparse the expression each time. * - * @param string The string to check. - * @param pattern The regular expression pattern. - * @param ret Error code, or result state of the match. - * @param error Error message, if applicable. - * @param maxLen Maximum length of the error buffer. - * @param flags General flags for the regular expression. - * i = Ignore case - * m = Multilines (affects ^ and $ so that they match - * the start/end of a line rather than matching the - * start/end of the string). - * s = Single line (affects . so that it matches any character, - * even new line characters). - * x = Pattern extension (ignore whitespace and # comments). + * @note Flags only exist in amxmodx 1.8 and later. * - * @return -2 = Matching error (error code is stored in ret) - * -1 = Error in pattern (error message and offset # in error and ret) - * 0 = No match. - * >1 = Handle for getting more information (via regex_substr) + * @note You should free the returned handle with regex_free() + * when you are done extracting all of the substrings. * - * @note Flags only exist in amxmodx 1.8 and later. - * @note You should free the returned handle (with regex_free()) - * when you are done extracting all of the substrings. + * @param string The string to check. + * @param pattern The regular expression pattern. + * @param flags General flags for the regular expression, see PCRE_* defines. + * @param error Error message encountered, if applicable. + * @param maxLen Maximum string length of the error buffer. + * @param errcode Regex type error code encountered, if applicable. See REGEX_ERROR_* defines. + * + * @return -2 = Matching error (error code is stored in ret) + * -1 = Error in pattern (error message and offset # in error and ret) + * 0 = No match. + * >1 = Handle for getting more information (via regex_substr) */ -native Regex:regex_match_all(const string[], const pattern[], &ret, error[], maxLen, const flags[] = ""); +native Regex:regex_match_all(const string[], const pattern[], flags = 0, error[]= "", maxLen = 0, &errcode = 0); /** * Matches a string against a regular expression pattern. @@ -339,16 +312,16 @@ native Regex:regex_match_all(const string[], const pattern[], &ret, error[], max * 0 = No match. * >1 = Number of results. */ -stock regex_match_simple(const str[], const pattern[], flags = 0, error[]="", maxLen = 0) +stock regex_match_simple(const str[], const pattern[], flags = 0, error[]= "", maxLen = 0, &errcode = 0) { - new Regex:regex = regex_compile_ex(pattern, flags, error, maxLen); + new Regex:regex = regex_compile_ex(pattern, flags, error, maxLen, errcode); if (regex < 0) { return -1; } - new substrings = regex_match_ex(regex, str); + new substrings = regex_match_c(regex, str); regex_free(regex);