2004-01-31 20:56:22 +00:00
|
|
|
/* Strings manipulation
|
2004-03-05 19:30:29 +00:00
|
|
|
*
|
|
|
|
* by the AMX Mod X Development Team
|
|
|
|
* originally developed by OLO
|
|
|
|
*
|
|
|
|
* This file is provided as is (no warranties).
|
|
|
|
*/
|
2004-01-31 20:56:22 +00:00
|
|
|
|
2004-02-21 20:30:04 +00:00
|
|
|
#if defined _string_included
|
|
|
|
#endinput
|
|
|
|
#endif
|
|
|
|
#define _string_included
|
|
|
|
|
2004-01-31 20:56:22 +00:00
|
|
|
/* Checks if source contains string. On success function
|
2004-02-21 20:30:04 +00:00
|
|
|
* returns position in source, on failure returns -1. */
|
2004-01-31 20:56:22 +00:00
|
|
|
native contain(const source[],const string[]);
|
|
|
|
|
|
|
|
/* Checks if source contains string with case ignoring. On success function
|
2004-02-21 20:30:04 +00:00
|
|
|
* returns position in source, on failure returns -1. */
|
2004-01-31 20:56:22 +00:00
|
|
|
native containi(const source[],const string[]);
|
|
|
|
|
|
|
|
/* Replaces given string to another in given text. */
|
2006-09-10 08:15:00 +00:00
|
|
|
native replace(text[], len, const what[], const with[]);
|
2004-01-31 20:56:22 +00:00
|
|
|
|
|
|
|
/* Adds one string to another. Last parameter different from 0, specifies
|
2004-02-21 20:30:04 +00:00
|
|
|
* how many chars we want to add. Function returns number of all merged chars. */
|
2004-01-31 20:56:22 +00:00
|
|
|
native add(dest[],len,const src[],max=0);
|
|
|
|
|
|
|
|
/* Fills string with given format and parameters.
|
2006-02-24 07:49:08 +00:00
|
|
|
* Function returns number of copied chars.
|
|
|
|
* Example: format(dest,"Hello %s. You are %d years old","Tom",17).
|
|
|
|
* If any of your input buffers overlap with the destination buffer,
|
|
|
|
* format() falls back to a "copy-back" version as of 1.65. This is
|
|
|
|
* slower, so you should using a source string that is the same as
|
|
|
|
* the destination.
|
|
|
|
*/
|
2004-09-07 09:26:20 +00:00
|
|
|
native format(output[] ,len ,const format[] , {Float,Sql,Result,_}:...);
|
2004-01-31 20:56:22 +00:00
|
|
|
|
2006-02-24 07:49:08 +00:00
|
|
|
/* Same as format(), except does not perform a "copy back" check.
|
2006-02-24 10:12:55 +00:00
|
|
|
* This means formatex() is faster, but DOES NOT ALLOW this type
|
2006-02-24 07:49:08 +00:00
|
|
|
* of call:
|
2006-02-24 10:12:55 +00:00
|
|
|
* formatex(buffer, len, "%s", buffer)
|
|
|
|
* formatex(buffer, len, buffer, buffer)
|
|
|
|
* formatex(buffer, len, "%s", buffer[5])
|
2006-02-24 07:49:08 +00:00
|
|
|
* This is because the output is directly stored into "buffer",
|
|
|
|
* rather than copied back at the end.
|
|
|
|
*/
|
|
|
|
native formatex(output[] ,len ,const format[] , {Float,Sql,Result,_}:...);
|
|
|
|
|
2006-05-07 00:25:30 +00:00
|
|
|
/* Replacement for format_args. Much faster and %L compatible.
|
|
|
|
* This works exactly like vsnprintf() from C.
|
|
|
|
* You must pass in the output buffer and its size,
|
|
|
|
* the string to format, and the number of the FIRST variable
|
|
|
|
* argument parameter. For example, for:
|
|
|
|
* function (a, b, c, ...)
|
|
|
|
* You would pass 4 (a is 1, b is 2, c is 3, et cetera).
|
|
|
|
* There is no vformatex().
|
|
|
|
*/
|
|
|
|
native vformat(buffer[], len, const fmt[], vararg);
|
|
|
|
|
2006-08-28 11:08:18 +00:00
|
|
|
/*
|
|
|
|
* Same as vformat(), except works in normal style dynamic natives.
|
|
|
|
* Instead of passing the format arg string, you can only pass the
|
|
|
|
* actual format argument number itself.
|
|
|
|
* If you pass 0, it will read the format string from an optional
|
|
|
|
* fifth parameter.
|
|
|
|
*/
|
|
|
|
native vdformat(buffer[], len, fmt_arg, vararg, ...);
|
|
|
|
|
2004-01-31 20:56:22 +00:00
|
|
|
/* Gets parameters from function as formated string. */
|
|
|
|
native format_args(output[] ,len ,pos = 0);
|
|
|
|
|
|
|
|
/* Converts number to string. */
|
2004-03-08 06:07:47 +00:00
|
|
|
native num_to_str(num,string[],len);
|
2004-03-08 05:29:51 +00:00
|
|
|
|
2004-01-31 20:56:22 +00:00
|
|
|
/* Returns converted string to number. */
|
2004-03-08 06:07:47 +00:00
|
|
|
native str_to_num(const string[]);
|
|
|
|
|
2005-09-06 16:34:17 +00:00
|
|
|
/* Converts float to string. */
|
|
|
|
native float_to_str(Float:fl, string[], len);
|
|
|
|
|
|
|
|
/* Parses a float. */
|
|
|
|
native Float:str_to_float(const string[]);
|
|
|
|
|
2004-01-31 20:56:22 +00:00
|
|
|
/* Checks if two strings equal. If len var is set
|
2004-02-21 20:30:04 +00:00
|
|
|
* then there are only c chars comapred. */
|
2004-01-31 20:56:22 +00:00
|
|
|
native equal(const a[],const b[],c=0);
|
|
|
|
|
|
|
|
/* Checks if two strings equal with case ignoring.
|
2004-02-21 20:30:04 +00:00
|
|
|
* If len var is set then there are only c chars comapred. */
|
2004-01-31 20:56:22 +00:00
|
|
|
native equali(const a[],const b[],c=0);
|
|
|
|
|
|
|
|
/* Copies one string to another. By len var
|
2004-02-21 20:30:04 +00:00
|
|
|
* you may specify max. number of chars to copy. */
|
2004-01-31 20:56:22 +00:00
|
|
|
native copy(dest[],len,const src[]);
|
|
|
|
|
|
|
|
/* Copies one string to another until char ch is found.
|
2004-02-21 20:30:04 +00:00
|
|
|
* By len var you may specify max. number of chars to copy. */
|
2004-01-31 20:56:22 +00:00
|
|
|
native copyc(dest[],len,const src[],ch);
|
|
|
|
|
|
|
|
/* Sets string with given character. */
|
|
|
|
native setc(src[],len,ch);
|
|
|
|
|
|
|
|
/* Gets parameters from text.
|
2004-02-21 20:30:04 +00:00
|
|
|
* Example: to split text: "^"This is^" the best year",
|
|
|
|
* call function like this: parse(text,arg1,len1,arg2,len2,arg3,len3,arg4,len4)
|
|
|
|
* and you will get: "This is", "the", "best", "year"
|
|
|
|
* Function returns number of parsed parameters. */
|
2004-01-31 20:56:22 +00:00
|
|
|
native parse(const text[], ... );
|
|
|
|
|
2004-09-19 17:25:51 +00:00
|
|
|
/* Breaks a string into two halves, by token.
|
|
|
|
See strbreak() for doing this with parameters.
|
|
|
|
Example:
|
|
|
|
str1[] = This *is*some text
|
|
|
|
strtok(str1, left, 24, right, 24, '*')
|
|
|
|
left will be "This "
|
|
|
|
Right will be "is*some text"
|
|
|
|
If you use trimSpaces, all spaces are trimmed from Left.
|
|
|
|
*/
|
|
|
|
native strtok(const text[], Left[], leftLen, Right[], rightLen, token=' ', trimSpaces=0);
|
|
|
|
|
|
|
|
|
2004-04-03 03:00:57 +00:00
|
|
|
/* Gets parameters from text one at a time
|
|
|
|
It breaks a string into the first parameter and the rest of the parameters
|
|
|
|
(A left side and right side of the string)
|
|
|
|
Example: to split text: "^"This is^" the best year",
|
2004-09-19 17:25:51 +00:00
|
|
|
strbreak(text, arg1, len1, arg2, len2)
|
2004-04-03 20:05:27 +00:00
|
|
|
arg1="This is", arg2=the best year
|
|
|
|
This is more useful than parse() because you can keep breaking
|
2004-04-03 03:00:57 +00:00
|
|
|
any number of arguments */
|
|
|
|
native strbreak(const text[], Left[], leftLen, Right[], rightLen);
|
|
|
|
|
2004-07-24 01:52:45 +00:00
|
|
|
/* Strips spaces from the beginning and end of a string. */
|
|
|
|
native trim(text[]);
|
|
|
|
|
2004-01-31 20:56:22 +00:00
|
|
|
/* Converts all chars in string to lower case. */
|
|
|
|
native strtolower(string[]);
|
|
|
|
|
|
|
|
/* Converts all chars in string to upper case. */
|
|
|
|
native strtoupper(string[]);
|
|
|
|
|
2004-08-01 16:49:24 +00:00
|
|
|
/* Make a string's first character uppercase */
|
|
|
|
native ucfirst(string[]);
|
|
|
|
|
2004-01-31 20:56:22 +00:00
|
|
|
/* Returns true when value is digit. */
|
|
|
|
native isdigit(ch);
|
|
|
|
|
|
|
|
/* Returns true when value is letter. */
|
|
|
|
native isalpha(ch);
|
|
|
|
|
|
|
|
/* Returns true when value is space. */
|
|
|
|
native isspace(ch);
|
|
|
|
|
|
|
|
/* Returns true when value is letter or digit. */
|
2005-07-30 16:41:34 +00:00
|
|
|
native isalnum(ch);
|
|
|
|
|
|
|
|
/* Concatenates a string. Maxlength is the total buffer of the destination. */
|
|
|
|
native strcat(dest[], const source[], maxlength);
|
|
|
|
|
|
|
|
/* Finds a string in another string. Returns -1 if not found. */
|
2005-07-30 16:46:40 +00:00
|
|
|
native strfind(const string[], const sub[], ignorecase=0, pos=0);
|
|
|
|
|
|
|
|
/* Compares two strings with the C function strcmp(). Returns 0 on equal. */
|
2005-09-15 17:53:02 +00:00
|
|
|
native strcmp(const string1[], const string2[], ignorecase=0);
|
|
|
|
|
2006-01-04 23:23:52 +00:00
|
|
|
/* Tests if given string contains only digits. Also, returns false for zero-length strings. */
|
2005-09-15 17:53:02 +00:00
|
|
|
stock bool:is_str_num(sString[])
|
|
|
|
{
|
2005-11-17 21:12:50 +00:00
|
|
|
new i = 0;
|
|
|
|
|
2006-01-04 23:23:52 +00:00
|
|
|
while (sString[i] && isdigit(sString[i]))
|
2005-11-17 21:12:50 +00:00
|
|
|
++i;
|
|
|
|
|
|
|
|
return sString[i] == 0 && i != 0;
|
2005-11-12 22:43:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* It is basically strbreak but you have a delimiter that is more than one character in length.
|
|
|
|
You pass the Input string, the Left output, the max length of the left output,
|
|
|
|
the right output , the max right length, and then the delimiter string.
|
|
|
|
By Suicid3
|
|
|
|
*/
|
2005-11-20 23:45:53 +00:00
|
|
|
stock split(szInput[], szLeft[], pL_Max, szRight[], pR_Max, szDelim[])
|
2005-11-12 22:43:55 +00:00
|
|
|
{
|
2005-11-20 23:45:53 +00:00
|
|
|
new iEnd = contain(szInput, szDelim);
|
|
|
|
new iStart = iEnd + strlen(szDelim);
|
|
|
|
|
|
|
|
//If delimiter isnt in Input just split the string at max lengths
|
2005-11-21 21:47:54 +00:00
|
|
|
if (iEnd == -1)
|
2005-11-20 23:45:53 +00:00
|
|
|
{
|
|
|
|
iStart = copy(szLeft, pL_Max, szInput);
|
|
|
|
copy(szRight, pR_Max, szInput[iStart]);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
//If delimter is in Input then split at input for max lengths
|
2005-11-21 21:47:54 +00:00
|
|
|
if (pL_Max >= iEnd)
|
2005-11-20 23:45:53 +00:00
|
|
|
copy(szLeft, iEnd, szInput);
|
|
|
|
else
|
|
|
|
copy(szLeft, pL_Max, szInput);
|
|
|
|
|
2006-03-06 14:54:12 +00:00
|
|
|
copy(szRight, pR_Max, szInput[iStart]);
|
2005-11-20 23:45:53 +00:00
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Removes a path from szFilePath leaving the name of the file in szFile for a pMax length. */
|
|
|
|
stock remove_filepath(szFilePath[], szFile[], pMax)
|
|
|
|
{
|
|
|
|
new len = strlen(szFilePath);
|
|
|
|
|
2005-11-21 21:47:54 +00:00
|
|
|
while ((--len >= 0) && (szFilePath[len] != '/') && (szFilePath[len] != '\')) { }
|
2005-11-20 23:45:53 +00:00
|
|
|
|
2005-11-21 21:47:54 +00:00
|
|
|
copy(szFile, pMax, szFilePath[len + 1]);
|
2005-11-20 23:45:53 +00:00
|
|
|
|
|
|
|
return;
|
2005-11-12 22:43:55 +00:00
|
|
|
}
|
2005-11-21 21:47:54 +00:00
|
|
|
|
2006-09-10 08:15:00 +00:00
|
|
|
/* Replaces a contained string iteratively.
|
|
|
|
* This ensures that no infinite replacements will take place by
|
|
|
|
* intelligently moving to the next string position each iteration.
|
|
|
|
*/
|
2005-11-21 21:47:54 +00:00
|
|
|
stock replace_all(string[], len, what[], with[])
|
|
|
|
{
|
2006-09-10 08:15:00 +00:00
|
|
|
new pos = 0;
|
2005-11-21 21:47:54 +00:00
|
|
|
|
2006-09-10 08:15:00 +00:00
|
|
|
if ((pos = contain(string, what)) == -1)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
new total = 0;
|
|
|
|
new with_len = strlen(with);
|
|
|
|
new diff = strlen(what) - with_len;
|
|
|
|
new total_len = strlen(string);
|
|
|
|
new temp_pos = 0
|
2005-11-21 21:47:54 +00:00
|
|
|
|
2006-09-12 13:26:40 +00:00
|
|
|
while (replace(string[pos], len - pos, what, with) != 0)
|
2005-11-21 21:47:54 +00:00
|
|
|
{
|
2006-09-10 08:15:00 +00:00
|
|
|
/* jump to position after replacement */
|
|
|
|
pos += with_len;
|
|
|
|
|
|
|
|
/* update cached length of string */
|
|
|
|
total_len -= diff;
|
|
|
|
|
|
|
|
/* will the next call be operating on the last character? */
|
|
|
|
if (pos >= total_len)
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* find the next position from our offset */
|
|
|
|
temp_pos = contain(string[pos], what);
|
|
|
|
|
|
|
|
/* if it's invalid, we're done */
|
|
|
|
if (temp_pos == -1)
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* otherwise, reposition and update counters */
|
|
|
|
pos += temp_pos;
|
2006-09-10 05:16:26 +00:00
|
|
|
total++;
|
2005-11-21 21:47:54 +00:00
|
|
|
}
|
2006-09-10 05:16:26 +00:00
|
|
|
|
|
|
|
return total;
|
2005-11-21 21:47:54 +00:00
|
|
|
}
|