diff options
author | Haru <haru@dotalux.com> | 2014-02-08 02:19:41 +0100 |
---|---|---|
committer | Haru <haru@dotalux.com> | 2014-02-08 02:33:49 +0100 |
commit | 1cf7c1ec251d6899707b0eced3bc75da2e212557 (patch) | |
tree | 54008176b1b0fca8affc1e01b1fac7b98e67df95 | |
parent | e7853fa6ed991fdd7bcb4b2c842761742ae3c912 (diff) | |
download | hercules-1cf7c1ec251d6899707b0eced3bc75da2e212557.tar.gz hercules-1cf7c1ec251d6899707b0eced3bc75da2e212557.tar.bz2 hercules-1cf7c1ec251d6899707b0eced3bc75da2e212557.tar.xz hercules-1cf7c1ec251d6899707b0eced3bc75da2e212557.zip |
Improvements on the script commands sscanf, axtoi. Added strtol.
- Added script command strtol (conforming to the ISO C90 function)
- Modified script command axtoi to internally use strtol instead of an
unnecessary own implementation.
- Fixed sscanf behavior to conform to the C specifications in case the
input string is empty. It now correctly returns -1, or 0 if the format
string is also empty. Fixes bugreport:8009, thanks to AnnieRuru -
http://hercules.ws/board/tracker/issue-8009-sscanf-should-return-1-if-the-string-field-is-an-empty-string/
Signed-off-by: Haru <haru@dotalux.com>
-rw-r--r-- | doc/script_commands.txt | 25 | ||||
-rw-r--r-- | src/map/script.c | 76 | ||||
-rw-r--r-- | src/map/script.h | 1 |
3 files changed, 50 insertions, 52 deletions
diff --git a/doc/script_commands.txt b/doc/script_commands.txt index c0b848663..aa8698418 100644 --- a/doc/script_commands.txt +++ b/doc/script_commands.txt @@ -7359,20 +7359,31 @@ setitemscript 2637,""; --------------------------------------- -*atoi ("<string>") -*axtoi ("<string>") +*atoi("<string>") +*axtoi("<string>") +*strtol("string", base) These commands are used to convert strings to numbers. 'atoi' will interpret given string as a decimal number (base 10), while 'axtoi' -interprets strings as hexadecimal numbers (base 16). +interprets strings as hexadecimal numbers (base 16). 'strtol' lets +the user specify a base (valid range is between 2 and 36 inclusive, +or the special value0, which means auto-detection). -Hexadecimal number set: {0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F} +The atoi and strtol functions conform to the C functions with the same +names, and axtoi is the same as strtol, with a base of 16. Results are +clamped to signed 32 bit int range (INT_MIN ~ INT_MAX) Example: -set @var, atoi("11"); // Sets @var to 11 -set @var, axtoi("FF"); // Sets @var to 255 -mes axtoi("11"); // Displays 17 (1 = 1, 10 = 16) +.@var = atoi("11"); // Sets .@var to 11 +.@var = axtoi("FF"); // Sets .@var to 255 +mes axtoi("11"); // Displays 17 (1 = 1, 10 = 16) +.@var = strtol("11", 10); // Sets .@var to 11 (11 base 10) +.@var = strtol("11", 16); // Sets .@var to 17 (11 base 16) +.@var = strtol("11", 0); // Sets .@var to 11 (11 base 10, auto-detected) +.@var = strtol("0x11", 0); // Sets .@var to 17 (11 base 16, auto-detected because of the "0x" prefix) +.@var = strtol("011", 0); // Sets .@var to 9 (11 base 8, auto-detected because of the "0" prefix) +.@var = strtol("11", 2); // Sets .@var to 3 (binary 11) --------------------------------------- diff --git a/src/map/script.c b/src/map/script.c index 21d55ca77..aa3713427 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -14064,6 +14064,15 @@ BUILDIN(sscanf) { argc = script_lastdata(st)-3; len = strlen(format); + + if (len != 0 && strlen(str) == 0) { + // If the source string is empty but the format string is not, we return -1 + // according to the C specs. (if the format string is also empty, we shall + // continue and return 0: 0 conversions took place out of the 0 attempted.) + script_pushint(st, -1); + return true; + } + CREATE(buf, char, len*2+1); // Issue sscanf for each parameter @@ -14379,14 +14388,34 @@ BUILDIN(setnpcdisplay) { return true; } -BUILDIN(atoi) -{ +BUILDIN(atoi) { const char *value; value = script_getstr(st,2); script_pushint(st,atoi(value)); return true; } +BUILDIN(axtoi) { + const char *hex = script_getstr(st,2); + long value = strtol(hex, NULL, 16); +#if LONG_MAX > INT_MAX || LONG_MIN < INT_MIN + value = cap_value(value, INT_MIN, INT_MAX); +#endif + script_pushint(st, (int)value); + return true; +} + +BUILDIN(strtol) { + const char *string = script_getstr(st, 2); + int base = script_getnum(st, 3); + long value = strtol(string, NULL, base); +#if LONG_MAX > INT_MAX || LONG_MIN < INT_MIN + value = cap_value(value, INT_MIN, INT_MAX); +#endif + script_pushint(st, (int)value); + return true; +} + // case-insensitive substring search [lordalfa] BUILDIN(compare) { @@ -15112,47 +15141,6 @@ BUILDIN(searchitem) return true; } -int axtoi(const char *hexStg) -{ - int n = 0; // position in string - int16 m = 0; // position in digit[] to shift - int count; // loop index - int intValue = 0; // integer value of hex string - int digit[11]; // hold values to convert - while (n < 10) { - if (hexStg[n]=='\0') - break; - if (hexStg[n] > 0x29 && hexStg[n] < 0x40 ) //if 0 to 9 - digit[n] = hexStg[n] & 0x0f; //convert to int - else if (hexStg[n] >='a' && hexStg[n] <= 'f') //if a to f - digit[n] = (hexStg[n] & 0x0f) + 9; //convert to int - else if (hexStg[n] >='A' && hexStg[n] <= 'F') //if A to F - digit[n] = (hexStg[n] & 0x0f) + 9; //convert to int - else break; - n++; - } - count = n; - m = n - 1; - n = 0; - while(n < count) { - // digit[n] is value of hex digit at position n - // (m << 2) is the number of positions to shift - // OR the bits into return value - intValue = intValue | (digit[n] << (m << 2)); - m--; // adjust the position to set - n++; // next digit to process - } - return (intValue); -} - -// [Lance] Hex string to integer converter -BUILDIN(axtoi) -{ - const char *hex = script_getstr(st,2); - script_pushint(st,script->axtoi(hex)); - return true; -} - // [zBuffer] List of player cont commands ---> BUILDIN(rid2name) { struct block_list *bl = NULL; @@ -18837,6 +18825,7 @@ void script_parse_builtin(void) { BUILDIN_DEF(query_logsql,"s*"), BUILDIN_DEF(escape_sql,"v"), BUILDIN_DEF(atoi,"s"), + BUILDIN_DEF(strtol,"si"), // [zBuffer] List of player cont commands ---> BUILDIN_DEF(rid2name,"i"), BUILDIN_DEF(pcfollow,"ii"), @@ -19220,7 +19209,6 @@ void script_defaults(void) { script->playbgm_foreachpc_sub = playbgm_foreachpc_sub; script->soundeffect_sub = soundeffect_sub; script->buildin_query_sql_sub = buildin_query_sql_sub; - script->axtoi = axtoi; script->buildin_instance_warpall_sub = buildin_instance_warpall_sub; script->buildin_mobuseskill_sub = buildin_mobuseskill_sub; script->cleanfloor_sub = script_cleanfloor_sub; diff --git a/src/map/script.h b/src/map/script.h index b7e9e5741..4906d4fa8 100644 --- a/src/map/script.h +++ b/src/map/script.h @@ -665,7 +665,6 @@ struct script_interface { int (*playbgm_foreachpc_sub) (struct map_session_data *sd, va_list args); int (*soundeffect_sub) (struct block_list *bl, va_list ap); int (*buildin_query_sql_sub) (struct script_state *st, Sql *handle); - int (*axtoi) (const char *hexStg); int (*buildin_instance_warpall_sub) (struct block_list *bl, va_list ap); int (*buildin_mobuseskill_sub) (struct block_list *bl, va_list ap); int (*cleanfloor_sub) (struct block_list *bl, va_list ap); |