mirror of
https://github.com/radareorg/radare2.git
synced 2024-12-14 08:49:50 +00:00
e8b70a1a0b
- Added initial cursor support - Q also for quit - Added visual prompt * Added date.c * Move cursor responsability to r_print * Make r_cons_invert work also for noncolor terminals * Added r_num_minmax_swap_i in r_util
211 lines
4.0 KiB
C
211 lines
4.0 KiB
C
/* radare - LGPL - Copyright 2007-2009 pancake<nopcode.org> */
|
|
|
|
#include "r_types.h"
|
|
#include "r_util.h"
|
|
|
|
#define D if(0)
|
|
|
|
#define __htonq(x) (\
|
|
(((x) & 0xff00000000000000LL) >> 56) | \
|
|
(((x) & 0x00ff000000000000LL) >> 40) | \
|
|
(((x) & 0x0000ff0000000000LL) >> 24) | \
|
|
(((x) & 0x000000ff00000000LL) >> 8) | \
|
|
(((x) & 0x00000000ff000000LL) << 8) | \
|
|
(((x) & 0x0000000000ff0000LL) << 24) | \
|
|
(((x) & 0x000000000000ff00LL) << 40) | \
|
|
(((x) & 0x00000000000000ffLL) << 56))
|
|
|
|
u64 r_num_htonq(u64 value) {
|
|
u64 ret = value;
|
|
#if LIL_ENDIAN
|
|
endian_memcpy_e((u8*)&ret, (u8*)&value, 8, 0);
|
|
#endif
|
|
return ret;
|
|
}
|
|
|
|
void r_num_minmax_swap(u64 *a, u64 *b)
|
|
{
|
|
if (*a>*b) {
|
|
u64 tmp = *a;
|
|
*a = *b;
|
|
*b = tmp;
|
|
}
|
|
}
|
|
|
|
void r_num_minmax_swap_i(int *a, int *b)
|
|
{
|
|
if (*a>*b) {
|
|
u64 tmp = *a;
|
|
*a = *b;
|
|
*b = tmp;
|
|
}
|
|
}
|
|
|
|
void r_num_init(struct r_num_t *num)
|
|
{
|
|
num->callback = NULL;
|
|
num->userptr = NULL;
|
|
num->value = 0LL;
|
|
}
|
|
|
|
struct r_num_t *r_num_new(u64 (*cb)(void*,const char *,int*), void *ptr)
|
|
{
|
|
struct r_num_t *num;
|
|
num = (struct r_num_t*) malloc(sizeof(struct r_num_t));
|
|
r_num_init(num);
|
|
return num;
|
|
}
|
|
|
|
/* old get_offset */
|
|
u64 r_num_get(struct r_num_t *num, const char *str)
|
|
{
|
|
int i, j;
|
|
char lch;
|
|
u64 ret = 0LL;
|
|
|
|
for(;str[0]==' ';) str = str+1;
|
|
|
|
/* resolve string with an external callback */
|
|
if (num && num->callback) {
|
|
int ok;
|
|
ret = num->callback(num->userptr, str, &ok);
|
|
if (ok) return ret;
|
|
}
|
|
|
|
if (str[0]=='0' && str[1]=='x') {
|
|
sscanf(str, "0x%llx", &ret);
|
|
} else {
|
|
lch = str[strlen(str)-1];
|
|
switch(lch) {
|
|
case 'h': // hexa
|
|
sscanf(str, "%llx", &ret);
|
|
break;
|
|
case 'o': // octal
|
|
sscanf(str, "%llo", &ret);
|
|
break;
|
|
case 'b': // binary
|
|
ret = 0;
|
|
for(j=0,i=strlen(str)-2;i>=0;i--,j++) {
|
|
if (str[i]=='1') ret|=1<<j;
|
|
else if (str[i]!='0') break;
|
|
}
|
|
break;
|
|
default:
|
|
sscanf(str, "%lld", &ret);
|
|
break;
|
|
case 'K': case 'k':
|
|
sscanf(str, "%lld", &ret);
|
|
ret *= 1024;
|
|
break;
|
|
case 'M': case 'm':
|
|
sscanf(str, "%lld", &ret);
|
|
ret *= 1024*1024;
|
|
break;
|
|
case 'G': case 'g':
|
|
sscanf(str, "%lld", &ret);
|
|
ret *= 1024*1024*1024;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (num != NULL)
|
|
num->value = ret;
|
|
|
|
return ret;
|
|
}
|
|
|
|
u64 r_num_op(char op, u64 a, u64 b)
|
|
{
|
|
D printf("r_num_op: %lld %c %lld\n", a,op,b);
|
|
switch(op) {
|
|
case '+': return a+b;
|
|
case '-': return a-b;
|
|
case '*': return a*b;
|
|
case '/': return a/b;
|
|
case '&': return a&b;
|
|
case '|': return a|b;
|
|
case '^': return a^b;
|
|
}
|
|
return b;
|
|
}
|
|
|
|
static u64 r_num_math_internal(struct r_num_t *num, char *s)
|
|
{
|
|
u64 ret = 0LL;
|
|
char *p = s;
|
|
int i, nop, op='\0';
|
|
|
|
D printf("r_num_math_internal: %s\n", s);
|
|
|
|
for(i=0;s[i];i++) {
|
|
switch(s[i]) {
|
|
case '+':
|
|
case '-':
|
|
case '*':
|
|
case '/':
|
|
case '&':
|
|
case '^':
|
|
case '|':
|
|
nop = s[i]; s[i] = '\0';
|
|
ret = r_num_op(op, ret, r_num_get(num, p));
|
|
op = s[i] = nop; p = s + i + 1;
|
|
break;
|
|
}
|
|
}
|
|
|
|
return r_num_op(op, ret, r_num_get(num, p));
|
|
}
|
|
|
|
u64 r_num_math(struct r_num_t *num, const char *str)
|
|
{
|
|
u64 ret = 0LL;
|
|
char op='+';
|
|
int len = strlen(str)+1;
|
|
char *p, *s = alloca(len);
|
|
char *group;
|
|
|
|
D printf("r_num_math: %s\n", str);
|
|
|
|
memcpy(s, str, len);
|
|
for(;*s==' ';s+=1);
|
|
p = s;
|
|
|
|
do {
|
|
group = strchr(p, '(');
|
|
if (group) {
|
|
group[0]='\0';
|
|
ret = r_num_op(op, ret, r_num_math_internal(num, p));
|
|
for(;p<group;p+=1) {
|
|
switch(*p) {
|
|
case '+':
|
|
case '-':
|
|
case '*':
|
|
case '/':
|
|
case '&':
|
|
case '|':
|
|
case '^':
|
|
op = *p;
|
|
break;
|
|
}
|
|
}
|
|
group[0]='(';
|
|
p = group+1;
|
|
if (r_str_delta(p, '(', ')')<0) {
|
|
char *p2 = strchr(p, '(');
|
|
if (p2 != NULL) {
|
|
p2[0]='\0';
|
|
ret = r_num_op(op, ret, r_num_math_internal(num, p));
|
|
ret = r_num_op(op, ret, r_num_math(num, p2+1));
|
|
p =p2+1;
|
|
continue;
|
|
} else fprintf(stderr, "WTF!\n");
|
|
} else ret = r_num_op(op, ret, r_num_math_internal(num, p));
|
|
} else ret = r_num_op(op, ret, r_num_math_internal(num, p));
|
|
} while(0);
|
|
|
|
if (num != NULL)
|
|
num->value = ret;
|
|
|
|
return ret;
|
|
}
|