diff --git a/core/smn_string.cpp b/core/smn_string.cpp index a4eba5ed..c85e9666 100644 --- a/core/smn_string.cpp +++ b/core/smn_string.cpp @@ -238,7 +238,7 @@ static cell_t sm_vformat(IPluginContext *pContext, const cell_t *params) } /* :TODO: make this UTF8 safe */ -static cell_t StrBreak(IPluginContext *pContext, const cell_t *params) +static cell_t BreakString(IPluginContext *pContext, const cell_t *params) { const char *input; char *out; @@ -383,7 +383,7 @@ static cell_t IsCharMB(IPluginContext *pContext, const cell_t *params) return bytes; } -static cell_t IsCharUpper(IPluginContext *pContext, const cell_t *params) +static cell_t IsCharUpper(IPluginContext *pContext, const cell_t *params) { char chr = params[1]; @@ -395,7 +395,7 @@ static cell_t IsCharUpper(IPluginContext *pContext, const cell_t *params) return isupper(chr); } -static cell_t IsCharLower(IPluginContext *pContext, const cell_t *params) +static cell_t IsCharLower(IPluginContext *pContext, const cell_t *params) { char chr = params[1]; @@ -407,6 +407,41 @@ static cell_t IsCharLower(IPluginContext *pContext, const cell_t *params) return islower(chr); } +static cell_t TrimString(IPluginContext *pContext, const cell_t *params) +{ + char *str; + pContext->LocalToString(params[1], &str); + + size_t chars = strlen(str); + + if (chars == 0) + { + return 0; + } + + char *end = str + chars - 1; + + /* Iterate backwards through string until we reach first non-whitespace char */ + while (end >= str && IsWhitespace(end)) + { + end--; + } + + /* Replace first whitespace char (at the end) with null terminator */ + *(end + 1) = '\0'; + + /* Iterate forwards through string until first non-whitespace char is reached */ + while (IsWhitespace(str)) + { + str++; + } + + size_t bytes; + pContext->StringToLocalUTF8(params[1], chars + 1, str, &bytes); + + return bytes; +} + REGISTER_NATIVES(basicStrings) { {"GetCharBytes", GetCharBytes}, @@ -418,7 +453,8 @@ REGISTER_NATIVES(basicStrings) {"IsCharSpace", IsCharSpace}, {"IsCharUpper", IsCharUpper}, {"strlen", sm_strlen}, - {"StrBreak", StrBreak}, + {"StrBreak", BreakString}, /* Backwards compat shim */ + {"BreakString", BreakString}, {"StrContains", sm_contain}, {"strcmp", sm_strcmp}, {"StrCompare", sm_strcmp}, /* Backwards compat shim */ @@ -431,5 +467,6 @@ REGISTER_NATIVES(basicStrings) {"Format", sm_format}, {"FormatEx", sm_formatex}, {"VFormat", sm_vformat}, + {"TrimString", TrimString}, {NULL, NULL}, }; diff --git a/plugins/include/string.inc b/plugins/include/string.inc index 6bbe3263..c405e8ce 100644 --- a/plugins/include/string.inc +++ b/plugins/include/string.inc @@ -84,7 +84,6 @@ stock StrCompare(const String:str1[], const String:str2[], bool:caseSensitive=tr /** * Returns whether two strings are equal. * - * * @param str1 First string (left). * @param str2 Second string (right). * @param caseSensitive If true (default), comparison is case sensitive. @@ -206,7 +205,16 @@ native FloatToString(Float:num, String:str[], maxlength); * @param argLen Maximum length of argument buffer. * @return Index to next piece of string, or -1 if none. */ -native StrBreak(const String:source[], String:arg[], argLen); +native BreakString(const String:source[], String:arg[], argLen); + +/** + * Backwards compatibility stock - use BreakString + * @deprecated Renamed to BreakString. + */ +stock StrBreak(const String:source[], String:arg[], argLen) +{ + return BreakString(source, arg, argLen); +} /** * Returns the number of bytes a character is using. This is @@ -327,3 +335,11 @@ stock StrCat(String:buffer[], maxlength, const String:source[]) return Format(buffer[len], maxlength-len, "%s", source); } + +/** + * Removes whitespace characters from the beginning and end of a string. + * + * @param str The string to trim. + * @return Number of bytes written (UTF-8 safe). + */ +native TrimString(String:str[]);