diff --git a/libr/core/cmd_help.c b/libr/core/cmd_help.c index c429668d59..b26787a710 100644 --- a/libr/core/cmd_help.c +++ b/libr/core/cmd_help.c @@ -77,7 +77,7 @@ static const char *help_msg_question[] = { "?_", " hudfile", "load hud menu with given file", "?b", " [num]", "show binary value of number", "?b64[-]", " [str]", "encode/decode in base64", - "?btw", " num|(expr) num|(expr) num|(expr)", "returns boolean value of a <= b <= c", + "?btw", " num|expr num|expr num|expr", "returns boolean value of a <= b <= c", "?B", " [elem]", "show range boundaries like 'e?search.in", "?d[.]", " opcode", "describe opcode for asm.arch", "?e[nbgc]", " string", "echo string (nonl, gotoxy, column, bars)", @@ -440,13 +440,14 @@ static int cmd_help(void *data, const char *input) { double d; float f; char * const inputs = strdup (input + 1); - int inputs_len = r_str_split (inputs, ' '); - const char *iter = inputs; - for (i = 0; i < inputs_len; i++, iter += strlen (iter) + 1) { - if (*iter == '\0') { + RList *list = r_num_str_split_list (inputs); + const int list_len = r_list_length (list); + for (i = 0; i < list_len; i++) { + const char *str = r_list_pop_head (list); + if (*str == '\0') { continue; } - n = r_num_math (core->num, iter); + n = r_num_math (core->num, str); if (core->num->dbz) { eprintf ("RNum ERROR: Division by Zero\n"); } @@ -479,6 +480,7 @@ static int cmd_help(void *data, const char *input) { r_cons_printf ("\n"); } free (inputs); + r_list_free (list); } break; case 'v': // "?v" diff --git a/libr/include/r_util/r_num.h b/libr/include/r_util/r_num.h index e32399a76c..27060450fc 100644 --- a/libr/include/r_util/r_num.h +++ b/libr/include/r_util/r_num.h @@ -72,7 +72,11 @@ R_API void r_num_irand(void); R_API ut16 r_num_ntohs(ut16 foo); R_API ut64 r_get_input_num_value(RNum *num, const char *input_value); R_API int r_is_valid_input_num_value(RNum *num, const char *input_value); -R_API int r_num_between (RNum *num, const char *input_value); +R_API int r_num_between(RNum *num, const char *input_value); +R_API bool r_num_is_op(const char c); +R_API int r_num_str_len(const char *str); +R_API int r_num_str_split(char *str); +R_API RList *r_num_str_split_list(char *str); #ifdef __cplusplus } diff --git a/libr/util/unum.c b/libr/util/unum.c index c9cbd4b127..28e9f2a2ce 100644 --- a/libr/util/unum.c +++ b/libr/util/unum.c @@ -271,14 +271,7 @@ R_API static ut64 r_num_math_internal(RNum *num, char *s) { char *p = s; int i, nop, op = 0; for (i=0; s[i]; i++) { - switch (s[i]) { - case '/': - case '+': - case '-': - case '*': - case '&': - case '^': - case '|': + if (r_num_is_op (s[i])) { nop = s[i]; s[i] = '\0'; ret = r_num_op (num, op, ret, r_num_get (num, p)); op = s[i] = nop; p = s + i + 1; @@ -330,14 +323,7 @@ R_API ut64 r_num_math(RNum *num, const char *str) { group[0] = '\0'; ret = r_num_op (op, ret, r_num_math_internal (num, p)); for (; p 3) { + len = 3; } + for (i = 0; i < len; i++) { + ns[i] = r_num_math (num, r_list_pop_head (nums)); + } + free (str); return num->value = R_BETWEEN (ns[0], ns[1], ns[2]); } + +R_API bool r_num_is_op(const char c) { + return c == '/' || c == '+' || c == '-' || c == '*' + || c == '&' || c == '^' || c == '|'; +} + +//Assumed *str is parsed as an expression correctly +R_API int r_num_str_len (const char *str) { + int i = 0, len = 0, st; + st = 0;//0: number, 1: op + if (str[0] == '(') { + i++; + } + while (str[i] != '\0') { + switch (st) { + case 0: //number + while (!r_num_is_op (str[i]) && str[i] != ' ' + && str[i] != '\0') { + i++; + if (str[i] == '(') { + i += r_num_str_len (str+i); + } + } + len = i; + st = 1; + break; + case 1: //op + while (str[i] != '\0' && str[i] == ' ') { + i++; + } + if (!r_num_is_op (str[i])) { + return len; + } + if (str[i] == ')') { + return i + 1; + } + i++; + while (str[i] != '\0' && str[i] == ' ') { + i++; + } + st = 0; + break; + } + } + return len; +} + +R_API int r_num_str_split(char *str) { + int i = 0, count = 0; + const int len = strlen (str); + while (i < len) { + i += r_num_str_len (str + i); + str[i] = '\0'; + i++; + count++; + } + return count; +} + +R_API RList *r_num_str_split_list(char *str) { + int i, count = r_num_str_split (str); + RList *list = r_list_newf (free); + for (i = 0; i < count; i++) { + r_list_append (list, str); + str += strlen (str) + 1; + } + return list; +}