mirror of
https://github.com/radareorg/radare2.git
synced 2024-11-28 07:30:33 +00:00
* add support for floating point arithmetics in r_num_calc
* show r_num_math parsing errors to stderr * add rax2 -f to show result in floating point
This commit is contained in:
parent
44b42708d6
commit
621d78cff4
@ -2,16 +2,18 @@
|
||||
|
||||
#include <r_util.h>
|
||||
|
||||
static int flags = 0;
|
||||
static ut64 flags = 0;
|
||||
|
||||
static int format_output (char mode, ut64 n);
|
||||
static RNum *num;
|
||||
static int help ();
|
||||
static int rax (char *str, int len, int last);
|
||||
static int use_stdin ();
|
||||
|
||||
static int format_output (char mode, ut64 n) {
|
||||
static int format_output (char mode, const char *s) {
|
||||
ut64 n;
|
||||
char *str = (char*) &n;
|
||||
char strbits[65];
|
||||
n = r_num_math (num, s);
|
||||
|
||||
if (flags & 2)
|
||||
r_mem_copyendian ((ut8*) str, (ut8*) str, 4, 0);
|
||||
@ -25,6 +27,9 @@ static int format_output (char mode, ut64 n) {
|
||||
case 'F':
|
||||
printf ("%ff\n", (float)(ut32)n);
|
||||
break;
|
||||
case 'f':
|
||||
printf ("%.01lf\n", num->fvalue);
|
||||
break;
|
||||
case 'B':
|
||||
if (n) {
|
||||
r_num_to_bits (strbits, n);
|
||||
@ -53,6 +58,7 @@ static int help () {
|
||||
" bin -> hex ; rax2 1100011b\n"
|
||||
" hex -> bin ; rax2 Bx63\n"
|
||||
" -e swap endianness ; rax2 -e 0x33\n"
|
||||
" -f floating point ; rax2 -f 6.3+2.1\n"
|
||||
" -b binstr -> bin ; rax2 -b 01000101 01110110\n"
|
||||
" -s hexstr -> bin ; rax2 -s 43 4a 50\n"
|
||||
" -S bin -> hexstr ; rax2 -S C J P\n"
|
||||
@ -90,6 +96,9 @@ static int rax (char *str, int len, int last) {
|
||||
case 'k':
|
||||
flags ^= 32;
|
||||
break;
|
||||
case 'f':
|
||||
flags ^= 64;
|
||||
break;
|
||||
case 'v':
|
||||
printf ("rax2 v"R2_VERSION"\n");
|
||||
break;
|
||||
@ -140,6 +149,9 @@ static int rax (char *str, int len, int last) {
|
||||
}
|
||||
|
||||
#define KB (flags&32)
|
||||
if (flags & 64) {
|
||||
out_mode = 'f';
|
||||
} else
|
||||
if (KB)
|
||||
out_mode = 'I';
|
||||
if (str[0]=='0' && str[1]=='x') {
|
||||
@ -168,11 +180,11 @@ static int rax (char *str, int len, int last) {
|
||||
}
|
||||
while ((p = strchr (str, ' '))) {
|
||||
*p = 0;
|
||||
format_output (out_mode, r_num_math (NULL, str));
|
||||
format_output (out_mode, str); //r_num_math (NULL, str));
|
||||
str = p+1;
|
||||
}
|
||||
if (*str)
|
||||
format_output (out_mode, r_num_math (NULL, str));
|
||||
format_output (out_mode, str); //r_num_math (NULL, str));
|
||||
return R_TRUE;
|
||||
}
|
||||
|
||||
@ -195,6 +207,7 @@ static int use_stdin () {
|
||||
|
||||
int main (int argc, char **argv) {
|
||||
int i;
|
||||
num = r_num_new (NULL, NULL);
|
||||
if (argc == 1)
|
||||
return use_stdin ();
|
||||
for (i=1; i<argc; i++)
|
||||
|
@ -1259,7 +1259,6 @@ static int cmd_help(void *data, const char *input) {
|
||||
ut32 n32, s, a;
|
||||
float f;
|
||||
n = r_num_math (core->num, input+1);
|
||||
core->num->value = n;
|
||||
n32 = (ut32)n;
|
||||
memcpy (&f, &n32, sizeof (f));
|
||||
/* decimal, hexa, octal */
|
||||
@ -1269,7 +1268,7 @@ static int cmd_help(void *data, const char *input) {
|
||||
n, n, n, s, a);
|
||||
/* binary and floating point */
|
||||
r_str_bits (out, (const ut8*)&n, sizeof (n), NULL);
|
||||
r_cons_printf ("%s %f\n", out, f);
|
||||
r_cons_printf ("%s %.01lf %f\n", out, core->num->fvalue, f);
|
||||
}
|
||||
break;
|
||||
case 'v':
|
||||
|
@ -103,6 +103,7 @@ typedef struct r_num_t {
|
||||
ut64 (*callback)(struct r_num_t *userptr, const char *str, int *ok);
|
||||
// RNumCallback callback;
|
||||
ut64 value;
|
||||
double fvalue;
|
||||
void *userptr;
|
||||
} RNum;
|
||||
typedef ut64 (*RNumCallback)(RNum *self, const char *str, int *ok);
|
||||
|
@ -1,5 +1,6 @@
|
||||
/* ported to C by pancake for r2 in 2012 */
|
||||
// TODO: support buffer instead of io
|
||||
// TODO: integrate floating point support
|
||||
// TODO: do not use global variables
|
||||
/*
|
||||
Reference Chapter 6:
|
||||
"The C++ Programming Language", Special Edition.
|
||||
@ -53,9 +54,11 @@ static NumValue number_value = { 0 };
|
||||
static char string_value[STRSZ];
|
||||
static int errors = 0;
|
||||
static char oc = 0;
|
||||
static const char *calc_err = NULL;
|
||||
|
||||
static void error(const char *s) {
|
||||
errors++;
|
||||
calc_err = s;
|
||||
//fprintf (stderr, "error: %s\n", s);
|
||||
}
|
||||
|
||||
@ -157,6 +160,11 @@ static int cin_get_num(NumValue *n) {
|
||||
}
|
||||
str[i] = 0;
|
||||
*n = Nset (r_num_get (calc_num, str));
|
||||
if (*str>='0' && *str<='9' && strchr (str, '.')) {
|
||||
if (sscanf (str, "%lf", &d)<1)
|
||||
return 0;
|
||||
*n = Nsetf (d);
|
||||
}
|
||||
#if 0
|
||||
// XXX: use r_num_get here
|
||||
if (str[0]=='0' && str[1]=='x') {
|
||||
@ -186,10 +194,9 @@ static Token get_token() {
|
||||
} while (ch!='\n' && isspace (ch));
|
||||
|
||||
switch (ch) {
|
||||
case 0: return curr_tok = END;
|
||||
case ';':
|
||||
case '\n':
|
||||
return curr_tok = PRINT;
|
||||
case 0: return curr_tok = END;
|
||||
case '+': // added for ++name and name++
|
||||
if (cin_get (&c) && c == '+')
|
||||
return curr_tok = INC;
|
||||
@ -211,7 +218,7 @@ static Token get_token() {
|
||||
case '.':
|
||||
cin_putback (ch);
|
||||
if (!cin_get_num (&number_value)) {
|
||||
error ("invalid number conversion\n");
|
||||
error ("invalid number conversion");
|
||||
return 1;
|
||||
}
|
||||
return curr_tok = NUMBER;
|
||||
@ -240,6 +247,7 @@ static Token get_token() {
|
||||
void load_token(const char *s) {
|
||||
calc_i = 0;
|
||||
calc_buf = s;
|
||||
calc_err = NULL;
|
||||
}
|
||||
|
||||
#ifdef TEST
|
||||
@ -258,19 +266,20 @@ int main(int argc, char* argv[]) {
|
||||
}
|
||||
#endif
|
||||
|
||||
R_API ut64 r_num_calc (RNum *num, const char *str) {
|
||||
R_API ut64 r_num_calc (RNum *num, const char *str, const char **err) {
|
||||
NumValue n;
|
||||
if (!*str)
|
||||
return 0LL;
|
||||
calc_num = num;
|
||||
load_token (str);
|
||||
get_token ();
|
||||
n = expr (0);
|
||||
if (err) *err = calc_err;
|
||||
//if (curr_tok == END) return 0LL; // XXX: Error
|
||||
//if (curr_tok == PRINT) //return 0LL; // XXX: the fuck
|
||||
// n = expr (0);
|
||||
#if 0
|
||||
// TODO: add support for floating point valuez
|
||||
if (n.d != ((double)(ut64)n.d))
|
||||
eprintf ("floating value: %lf\n", n.d);
|
||||
#endif
|
||||
if (n.d != ((double)(ut64)n.d)) {
|
||||
if (num) num->fvalue = n.d;
|
||||
} else if (num) num->fvalue = (double)n.n;
|
||||
return n.n;
|
||||
}
|
||||
|
@ -160,18 +160,22 @@ R_API static ut64 r_num_math_internal(RNum *num, char *s) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return r_num_op (op, ret, r_num_get (num, p));
|
||||
}
|
||||
#endif
|
||||
|
||||
#if R_NUM_USE_CALC
|
||||
R_API ut64 r_num_calc (RNum *num, const char *str);
|
||||
R_API ut64 r_num_calc (RNum *num, const char *str, const char **err);
|
||||
#endif
|
||||
|
||||
R_API ut64 r_num_math(RNum *num, const char *str) {
|
||||
#if R_NUM_USE_CALC
|
||||
return r_num_calc (num, str);
|
||||
ut64 ret;
|
||||
const char *err = NULL;
|
||||
ret = r_num_calc (num, str, &err);
|
||||
if (err) eprintf ("r_num_calc error: %s\n", err);
|
||||
else if (num) num->value = ret;
|
||||
return ret;
|
||||
#else
|
||||
ut64 ret = 0LL;
|
||||
char op = '+';
|
||||
|
Loading…
Reference in New Issue
Block a user