Add strtok2 which fixes a trim issue with strtok (bug 3993, r=arkshine)
Former-commit-id: ad9e3ad972b6f7a2e34c61d615e25de07c9acdfa
This commit is contained in:
parent
da6d417d5d
commit
eb43b69e4d
@ -851,11 +851,87 @@ static cell AMX_NATIVE_CALL amx_strtok(AMX *amx, cell *params)
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Same as amx_strtok but fixes and expands trim, returns token pos if token was found, -1 otherwise
|
||||
static cell AMX_NATIVE_CALL amx_strtok2(AMX *amx, cell *params)
|
||||
{
|
||||
int left_pos = 0, right_pos = 0, len, pos = -1;
|
||||
unsigned int i = 0;
|
||||
|
||||
char *string = get_amxstring(amx, params[1], 0, len);
|
||||
char *left = new char[len + 1], *right = new char[len + 1];
|
||||
int left_max = params[3], right_max = params[5];
|
||||
char token = static_cast<char>(params[6]);
|
||||
|
||||
/* Trim flags:
|
||||
1 - ltrim left
|
||||
2 - rtrim left
|
||||
4 - ltrim right
|
||||
8 - rtrim right
|
||||
*/
|
||||
int trim = params[7];
|
||||
|
||||
// ltrim left
|
||||
if (trim & 1 && isspace(string[i]))
|
||||
{
|
||||
while (isspace(string[++i]));
|
||||
}
|
||||
|
||||
for (; i < (unsigned int) len; ++i)
|
||||
{
|
||||
if (string[i] == token)
|
||||
{
|
||||
pos = i;
|
||||
++i;
|
||||
break;
|
||||
}
|
||||
|
||||
left[left_pos++] = string[i];
|
||||
}
|
||||
|
||||
// rtrim left
|
||||
if (trim & 2 && left_pos && isspace(left[left_pos - 1]))
|
||||
{
|
||||
while (--left_pos >= 0 && isspace(left[left_pos]));
|
||||
|
||||
++left_pos;
|
||||
}
|
||||
|
||||
// ltrim right
|
||||
if (trim & 4 && isspace(string[i]))
|
||||
{
|
||||
while (isspace(string[++i]));
|
||||
}
|
||||
|
||||
for (; i < (unsigned int) len; ++i)
|
||||
{
|
||||
right[right_pos++] = string[i];
|
||||
}
|
||||
|
||||
// rtrim right
|
||||
if (trim & 8 && right_pos && isspace(right[right_pos - 1]))
|
||||
{
|
||||
while (--right_pos >= 0 && isspace(right[right_pos]));
|
||||
|
||||
++right_pos;
|
||||
}
|
||||
|
||||
right[right_pos] = 0;
|
||||
left[left_pos] = 0;
|
||||
set_amxstring(amx, params[2], left, left_max);
|
||||
set_amxstring(amx, params[4], right, right_max);
|
||||
|
||||
delete [] left;
|
||||
delete [] right;
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
//added by BAILOPAN
|
||||
//Takes a string and breaks it into a 1st param and rest params
|
||||
//strbreak(String[], First[], FirstLen, Rest[], RestLen)
|
||||
static cell AMX_NATIVE_CALL strbreak(AMX *amx, cell *params) /* 5 param */
|
||||
{
|
||||
|
||||
int _len;
|
||||
bool in_quote = false;
|
||||
bool had_quotes = false;
|
||||
@ -1156,6 +1232,7 @@ AMX_NATIVE_INFO string_Natives[] =
|
||||
{"trim", amx_trim},
|
||||
{"ucfirst", amx_ucfirst},
|
||||
{"strtok", amx_strtok},
|
||||
{"strtok2", amx_strtok2},
|
||||
{"strlen", amx_strlen},
|
||||
{"strcat", n_strcat},
|
||||
{"strfind", n_strfind},
|
||||
|
@ -162,6 +162,66 @@ native parse(const text[], ... );
|
||||
*/
|
||||
native strtok(const text[], Left[], leftLen, Right[], rightLen, token=' ', trimSpaces=0);
|
||||
|
||||
/**
|
||||
* Below are the trim flags for strtok2
|
||||
*
|
||||
* You can specify how the left and right buffers will
|
||||
* be trimmed by strtok2. LTRIM trims spaces from the
|
||||
* left side. RTRIM trims from the right side.
|
||||
*
|
||||
* The defines TRIM_INNER, TRIM_OUTER and TRIM_FULL are
|
||||
* shorthands for commonly used flag combinations.
|
||||
*
|
||||
* When the initial string is trimmed, using TRIM_INNER
|
||||
* for all subsequent strtok2 calls will ensure that left
|
||||
* and right are always trimmed from both sides.
|
||||
*
|
||||
* Examples:
|
||||
* str1[] = " This is * some text "
|
||||
* strtok2(str1, left, 24, right, 24, '*', TRIM_FULL)
|
||||
* left will be "This is", right will be "some text"
|
||||
*
|
||||
* str2[] = " Here is | an | example "
|
||||
* trim(str2)
|
||||
* strtok2(str2, left, 24, right, 24, '|', TRIM_INNER)
|
||||
* left will be "Here is", right will be "an | example"
|
||||
* strtok2(right, left, 24, right, 24, '|', TRIM_INNER)
|
||||
* left will be "an", right will be "example"
|
||||
*
|
||||
* str3[] = " One - more "
|
||||
* strtok2(str3, left, 24, right, 24, '-', TRIM_OUTER)
|
||||
* left will be "One ", right will be " more"
|
||||
*
|
||||
* str4[] = " Final . example "
|
||||
* strtok2(str4, left, 24, right, 24, '.', LTRIM_LEFT|LTRIM_RIGHT)
|
||||
* left will be "Final ", right will be "example "
|
||||
*/
|
||||
#define LTRIM_LEFT (1<<0)
|
||||
#define RTRIM_LEFT (1<<1)
|
||||
#define LTRIM_RIGHT (1<<2)
|
||||
#define RTRIM_RIGHT (1<<3)
|
||||
|
||||
#define TRIM_INNER RTRIM_LEFT|LTRIM_RIGHT
|
||||
#define TRIM_OUTER LTRIM_LEFT|RTRIM_RIGHT
|
||||
#define TRIM_FULL TRIM_OUTER|TRIM_INNER
|
||||
|
||||
/**
|
||||
* Breaks a string in two by token
|
||||
*
|
||||
* Only available in 1.8.3 and above
|
||||
*
|
||||
* @param text String to tokenize
|
||||
* @param left Buffer to store left half
|
||||
* @param llen Size of left buffer
|
||||
* @param right Buffer to store right half
|
||||
* @param rlen Size of right buffer
|
||||
* @param token Token to split by
|
||||
* @param trim Flags for trimming behavior, see above
|
||||
*
|
||||
* @return Returns position of token in string if found,
|
||||
* -1 if token was not found
|
||||
*/
|
||||
native strtok2(const text[], left[], const llen, right[], const rlen, const token = ' ', const trim = 0);
|
||||
|
||||
/* Gets parameters from text one at a time
|
||||
It breaks a string into the first parameter and the rest of the parameters
|
||||
|
Loading…
Reference in New Issue
Block a user