* 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:
pancake 2012-02-14 05:26:41 +01:00
parent 44b42708d6
commit 621d78cff4
5 changed files with 46 additions and 20 deletions

View File

@ -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++)

View File

@ -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':

View File

@ -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);

View File

@ -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;
}

View File

@ -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 = '+';