mirror of
https://github.com/radareorg/radare2.git
synced 2025-03-05 21:13:27 +00:00
anon pf struct and add n/N
add anon nested struct help and fix tests fix tests minor changes add support for unsigned and signed char, short, int and long long add help cleanup minor fix
This commit is contained in:
parent
29bf4e2fe2
commit
18cd2f5ec5
@ -324,6 +324,8 @@ static void print_format_help_help(RCore *core) {
|
||||
" ", "E", "resolve enum name (see t?)",
|
||||
" ", "f", "float value (4 bytes)",
|
||||
" ", "i", "%%i integer value (4 bytes)",
|
||||
" ", "n", "next char specifies size of signed value (1, 2, 4 or 8 byte(s))",
|
||||
" ", "N", "next char specifies size of unsigned value (1, 2, 4 or 8 byte(s))",
|
||||
" ", "o", "0x%%08o octal value (4 byte)",
|
||||
" ", "p", "pointer reference (2, 4 or 8 bytes)",
|
||||
" ", "q", "quadword (8 bytes)",
|
||||
@ -361,6 +363,8 @@ static void print_format_help_help_help(RCore *core) {
|
||||
"pf", " 10xiz pointer length string", "Print a size 10 array of the xiz struct with its field names",
|
||||
"pf", " {integer}bifc", "Print integer times the following format (bifc)",
|
||||
"pf", " [4]w[7]i", "Print an array of 4 words and then an array of 7 integers",
|
||||
"pf", " ic...?i foo bar \"(pf xw yo foo)troll\" yo", "Print nested anonymous structres",
|
||||
"pf", "n2", "print signed short (2 bytes) value. Use N insted of n for printing unsigned values",
|
||||
NULL};
|
||||
r_core_cmd_help (core, help_msg);
|
||||
}
|
||||
@ -549,10 +553,11 @@ static void cmd_print_format(RCore *core, const char *_input, int len) {
|
||||
char *fields = NULL;
|
||||
*space++ = 0;
|
||||
fields = strchr (space, ' ');
|
||||
if (strchr (name, '.') != NULL || (fields != NULL && strchr(fields, '.') != NULL))
|
||||
if (strchr (name, '.') != NULL) {// || (fields != NULL && strchr(fields, '.') != NULL)) // if anon struct, then field can have '.'
|
||||
eprintf ("Struct or fields name can not contain dot symbol (.)\n");
|
||||
else
|
||||
} else {
|
||||
r_strht_set (core->print->formats, name, space);
|
||||
}
|
||||
free (name);
|
||||
free (input);
|
||||
return;
|
||||
|
@ -246,7 +246,7 @@ static void r_print_format_char(const RPrint* p, int endian, int mode,
|
||||
if (MUSTSET) {
|
||||
p->cb_printf ("\"w %s\" @ 0x%08"PFMT64x"\n", setval, seeki+((elem>=0)?elem:0));
|
||||
} else if (MUSTSEE) {
|
||||
if (!SEEVALUE) p->cb_printf ("0x%08"PFMT64x" = ", seeki+((elem>=0)?elem*2:0));
|
||||
if (!SEEVALUE) p->cb_printf ("0x%08"PFMT64x" = ", seeki+((elem>=0)?elem*2:0)); //XXX:: shouldn't it be elem*1??
|
||||
if (size==-1)
|
||||
p->cb_printf ("'%c'", IS_PRINTABLE (buf[i])?buf[i]:'.');
|
||||
else {
|
||||
@ -434,22 +434,31 @@ static void r_print_format_hex(const RPrint* p, int endian, int mode,
|
||||
p->cb_printf ("%"PFMT64d, addr);
|
||||
} else if (MUSTSEE) {
|
||||
if (!SEEVALUE) p->cb_printf ("0x%08"PFMT64x" = ", seeki+((elem>=0)?elem*4:0));
|
||||
if (size==-1)
|
||||
if (size==-1) {
|
||||
p->cb_printf ("%"PFMT64d, addr);
|
||||
else {
|
||||
if (!SEEVALUE) p->cb_printf ("[ ");
|
||||
} else {
|
||||
if (!SEEVALUE) {
|
||||
p->cb_printf ("[ ");
|
||||
}
|
||||
while (size--) {
|
||||
updateAddr (buf, i, endian, &addr, NULL);
|
||||
if (elem == -1 || elem == 0) {
|
||||
p->cb_printf ("%"PFMT64d, addr);
|
||||
if (elem == 0) elem = -2;
|
||||
if (elem == 0) {
|
||||
elem = -2;
|
||||
}
|
||||
}
|
||||
if (size != 0 && elem == -1)
|
||||
if (size != 0 && elem == -1) {
|
||||
p->cb_printf (", ");
|
||||
if (elem > -1) elem--;
|
||||
i+=4;
|
||||
}
|
||||
if (elem > -1) {
|
||||
elem--;
|
||||
}
|
||||
i += 4;
|
||||
}
|
||||
if (!SEEVALUE) {
|
||||
p->cb_printf (" ]");
|
||||
}
|
||||
if (!SEEVALUE) p->cb_printf (" ]");
|
||||
}
|
||||
} else if (MUSTSEEJSON) {
|
||||
if (size==-1)
|
||||
@ -460,11 +469,16 @@ static void r_print_format_hex(const RPrint* p, int endian, int mode,
|
||||
updateAddr (buf, i, endian, &addr, NULL);
|
||||
if (elem == -1 || elem == 0) {
|
||||
p->cb_printf ("%d", addr);
|
||||
if (elem == 0) elem = -2;
|
||||
if (elem == 0) {
|
||||
elem = -2;
|
||||
}
|
||||
}
|
||||
if (size != 0 && elem == -1)
|
||||
if (size != 0 && elem == -1) {
|
||||
p->cb_printf (", ");
|
||||
if (elem > -1) elem--;
|
||||
}
|
||||
if (elem > -1) {
|
||||
elem--;
|
||||
}
|
||||
i+=4;
|
||||
}
|
||||
p->cb_printf (" ]");
|
||||
@ -989,10 +1003,105 @@ static void r_print_format_register (const RPrint* p, int mode,
|
||||
}
|
||||
}
|
||||
|
||||
// XXX: this is very incomplete. must be updated to handle all format chars
|
||||
static void r_print_format_num_specifier (const RPrint *p, ut64 addr, int bytes, int sign) {
|
||||
#define EXT(T) (sign ? (signed T)(addr) : (unsigned T)(addr) )
|
||||
const char *fs64 = sign ? "%"PFMT64d : "%"PFMT64u;
|
||||
const char *fs = sign ? "%d" : "%u";
|
||||
if (bytes == 1) {
|
||||
p->cb_printf (fs, EXT(char));
|
||||
} else if (bytes == 2) {
|
||||
p->cb_printf (fs, EXT(short));
|
||||
} else if (bytes == 4) {
|
||||
p->cb_printf (fs, EXT(int)); //XXX: int is not necessarily 4 bytes I guess.
|
||||
} else if (bytes == 8) {
|
||||
p->cb_printf (fs64, addr);
|
||||
}
|
||||
#undef EXT
|
||||
}
|
||||
|
||||
static void r_print_format_num (const RPrint *p, int endian, int mode, const char *setval, ut64 seeki, ut8 *buf, int i, int bytes, int sign, int size) {
|
||||
ut64 addr;
|
||||
int elem = -1;
|
||||
if (size >= ARRAYINDEX_COEF) {
|
||||
elem = size/ARRAYINDEX_COEF-1;
|
||||
size %= ARRAYINDEX_COEF;
|
||||
}
|
||||
if (bytes == 8) {
|
||||
updateAddr (buf, i, endian, NULL, &addr);
|
||||
} else {
|
||||
updateAddr (buf, i, endian, &addr, NULL);
|
||||
}
|
||||
if (MUSTSET) {
|
||||
p->cb_printf ("wv%d %s @ 0x%08"PFMT64x"\n", bytes, setval, seeki+((elem>=0)?elem*(bytes):0));
|
||||
} else if (mode & R_PRINT_DOT) {
|
||||
p->cb_printf ("%"PFMT64u, addr);
|
||||
} else if (MUSTSEE) {
|
||||
if (!SEEVALUE) p->cb_printf ("0x%08"PFMT64x" = ", seeki+((elem>=0)?elem*(bytes):0));
|
||||
if (size == -1) {
|
||||
r_print_format_num_specifier (p, addr, bytes, sign);
|
||||
} else {
|
||||
if (!SEEVALUE) {
|
||||
p->cb_printf ("[ ");
|
||||
}
|
||||
while (size--) {
|
||||
if (bytes == 8) {
|
||||
updateAddr (buf, i, endian, NULL, &addr);
|
||||
} else {
|
||||
updateAddr (buf, i, endian, &addr, NULL);
|
||||
}
|
||||
if (elem == -1 || elem == 0) {
|
||||
r_print_format_num_specifier (p, addr, bytes, sign);
|
||||
if (elem == 0) {
|
||||
elem = -2;
|
||||
}
|
||||
}
|
||||
if (size != 0 && elem == -1) {
|
||||
p->cb_printf (", ");
|
||||
}
|
||||
if (elem > -1) {
|
||||
elem--;
|
||||
}
|
||||
i += bytes;
|
||||
}
|
||||
if (!SEEVALUE) {
|
||||
p->cb_printf (" ]");
|
||||
}
|
||||
}
|
||||
} else if (MUSTSEEJSON) {
|
||||
if (size == -1) {
|
||||
r_print_format_num_specifier (p, addr, bytes, sign);
|
||||
} else {
|
||||
p->cb_printf ("[ ");
|
||||
while (size--) {
|
||||
if (bytes == 8) {
|
||||
updateAddr (buf, i, endian, NULL, &addr);
|
||||
} else {
|
||||
updateAddr (buf, i, endian, &addr, NULL);
|
||||
}
|
||||
if (elem == -1 || elem == 0) {
|
||||
r_print_format_num_specifier (p, addr, bytes, sign);
|
||||
if (elem == 0) {
|
||||
elem = -2;
|
||||
}
|
||||
}
|
||||
if (size != 0 && elem == -1) {
|
||||
p->cb_printf (", ");
|
||||
}
|
||||
if (elem > -1) {
|
||||
elem--;
|
||||
}
|
||||
i += bytes;
|
||||
}
|
||||
p->cb_printf (" ]");
|
||||
}
|
||||
p->cb_printf ("}");
|
||||
}
|
||||
}
|
||||
|
||||
// XXX: this is somewhat incomplete. must be updated to handle all format chars
|
||||
int r_print_format_struct_size(const char *f, RPrint *p, int mode) {
|
||||
char *o, *end, *args, *fmt;
|
||||
int size = 0, tabsize = 0, i, idx = 0, biggest = 0;
|
||||
int size = 0, tabsize = 0, i, idx = 0, biggest = 0, fmt_len = 0;
|
||||
if (!f) return -1;
|
||||
o = strdup (f);
|
||||
if (!o) return -1;
|
||||
@ -1015,8 +1124,16 @@ int r_print_format_struct_size(const char *f, RPrint *p, int mode) {
|
||||
mode &= ~R_PRINT_UNIONMODE;
|
||||
}
|
||||
|
||||
i = 0;
|
||||
if (fmt[i] >= '0' && fmt[i] <= '9') {
|
||||
while (fmt[i] >= '0' && fmt[i] <= '9') {
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
r_str_word_set0 (args);
|
||||
for (i=0; i < strlen (fmt); i++) {
|
||||
fmt_len = strlen (fmt);
|
||||
for (; i < fmt_len; i++) {
|
||||
if (fmt[i] == '[') {
|
||||
char *end = strchr (fmt+i,']');
|
||||
if (!end) {
|
||||
@ -1032,15 +1149,18 @@ int r_print_format_struct_size(const char *f, RPrint *p, int mode) {
|
||||
}
|
||||
|
||||
switch (fmt[i]) {
|
||||
case '.':
|
||||
idx--;
|
||||
case 'c':
|
||||
case 'b':
|
||||
case '.':
|
||||
case 'X':
|
||||
size += tabsize*1;
|
||||
size += tabsize * 1;
|
||||
break;
|
||||
case 'w':
|
||||
size += tabsize*2;
|
||||
size += tabsize * 2;
|
||||
break;
|
||||
case ':':
|
||||
idx--;
|
||||
case 'd':
|
||||
case 'o':
|
||||
case 'i':
|
||||
@ -1048,7 +1168,6 @@ int r_print_format_struct_size(const char *f, RPrint *p, int mode) {
|
||||
case 'f':
|
||||
case 's':
|
||||
case 't':
|
||||
case ':':
|
||||
size += tabsize * 4;
|
||||
break;
|
||||
case 'S':
|
||||
@ -1060,8 +1179,9 @@ int r_print_format_struct_size(const char *f, RPrint *p, int mode) {
|
||||
size += tabsize;
|
||||
break;
|
||||
case '*':
|
||||
size += tabsize * 4;
|
||||
size += tabsize * (p->bits / 8);
|
||||
i++;
|
||||
idx--; //no need to go ahead for args
|
||||
break;
|
||||
case 'B':
|
||||
case 'E':
|
||||
@ -1079,22 +1199,85 @@ int r_print_format_struct_size(const char *f, RPrint *p, int mode) {
|
||||
{
|
||||
const char *format = NULL;
|
||||
char *endname = NULL, *structname = NULL;
|
||||
char tmp = 0;
|
||||
structname = strdup (r_str_word_get0 (args, idx));
|
||||
if (*structname == '(') {
|
||||
endname = strchr (structname, ')');
|
||||
endname = r_str_rchr (structname, NULL, ')');
|
||||
} else {
|
||||
eprintf ("Struct name missing (%s)\n", structname);
|
||||
free (structname);
|
||||
break;
|
||||
}
|
||||
if (endname) *endname = '\0';
|
||||
format = r_strht_get (p->formats, structname + 1);
|
||||
free (structname);
|
||||
format = strchr (structname, ' ');
|
||||
if (format) {
|
||||
tmp = *format;
|
||||
while (tmp == ' ') {
|
||||
format++;
|
||||
tmp = *format;
|
||||
}
|
||||
} else {
|
||||
format = r_strht_get (p->formats, structname + 1);
|
||||
}
|
||||
size += tabsize * r_print_format_struct_size (format, p, mode);
|
||||
free (structname);
|
||||
}
|
||||
break;
|
||||
// TODO continue list
|
||||
case '{':
|
||||
while (fmt[i] != '}') {
|
||||
if (!fmt[i]) {
|
||||
return -1;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
i++;
|
||||
idx--;
|
||||
break;
|
||||
case '}':
|
||||
free (o);
|
||||
free (args);
|
||||
return -1;
|
||||
case '+':
|
||||
case 'e':
|
||||
idx--;
|
||||
break;
|
||||
case 'p':
|
||||
if (fmt[i+1] == '2') {
|
||||
size += tabsize * 2;
|
||||
} else if (fmt[i+1] == '4') {
|
||||
size += tabsize * 4;
|
||||
} else if (fmt[i+1] == '8') {
|
||||
size += tabsize * 8;
|
||||
} else {
|
||||
size += tabsize * (p->bits / 8);
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
break;
|
||||
case 'r':
|
||||
break;
|
||||
case 'n':
|
||||
case 'N':
|
||||
if (fmt[i+1] == '1') {
|
||||
size += tabsize * 1;
|
||||
} else if (fmt[i+1] == '2') {
|
||||
size += tabsize * 2;
|
||||
} else if (fmt[i+1] == '4') {
|
||||
size += tabsize * 4;
|
||||
} else if (fmt[i+1] == '8') {
|
||||
size += tabsize * 8;
|
||||
} else {
|
||||
eprintf ("Invalid n format.\n");
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
break;
|
||||
case 'D':
|
||||
case 'T':
|
||||
case 'u':
|
||||
//TODO complete this.
|
||||
default:
|
||||
//idx--; //Does this makes sense?
|
||||
break;
|
||||
}
|
||||
idx++;
|
||||
@ -1105,27 +1288,34 @@ int r_print_format_struct_size(const char *f, RPrint *p, int mode) {
|
||||
}
|
||||
free (o);
|
||||
free (args);
|
||||
//TODO: what if struct is `pf.abc {2}ii a b` should the size be 8 or 16? same goes for `pf 2ii a b`
|
||||
return (mode & R_PRINT_UNIONMODE)? biggest : size;
|
||||
}
|
||||
|
||||
static int r_print_format_struct(RPrint* p, ut64 seek, const ut8* b, int len,
|
||||
char *name, int slide, int mode, const char *setval, char *field) {
|
||||
static int r_print_format_struct(RPrint* p, ut64 seek, const ut8* b, int len, const char *name,
|
||||
int slide, int mode, const char *setval, char *field, int anon) {
|
||||
const char *fmt;
|
||||
char namefmt[128];
|
||||
if ((slide % STRUCTPTR) > NESTDEPTH || (slide%STRUCTFLAG)/STRUCTPTR > NESTDEPTH) {
|
||||
if ((slide % STRUCTPTR) > NESTDEPTH || (slide % STRUCTFLAG)/STRUCTPTR > NESTDEPTH) {
|
||||
eprintf ("Too much nested struct, recursion too deep...\n");
|
||||
return 0;
|
||||
}
|
||||
fmt = r_strht_get (p->formats, name);
|
||||
if (anon) {
|
||||
fmt = name;
|
||||
} else {
|
||||
fmt = r_strht_get (p->formats, name);
|
||||
}
|
||||
if (!fmt || !*fmt) {
|
||||
eprintf ("Undefined struct '%s'.\n", name);
|
||||
return 0;
|
||||
}
|
||||
if (MUSTSEE && !SEEVALUE) {
|
||||
snprintf (namefmt, sizeof (namefmt), "%%%ds", 10+6*slide%STRUCTPTR);
|
||||
if (fmt[0] == '0')
|
||||
if (fmt[0] == '0') {
|
||||
p->cb_printf (namefmt, "union");
|
||||
else p->cb_printf (namefmt, "struct");
|
||||
} else {
|
||||
p->cb_printf (namefmt, "struct");
|
||||
}
|
||||
p->cb_printf ("<%s>\n", name);
|
||||
}
|
||||
r_print_format (p, seek, b, len, fmt, mode, setval, field);
|
||||
@ -1191,7 +1381,7 @@ R_API int r_print_format(RPrint *p, ut64 seek, const ut8* b, const int len,
|
||||
if (bracket) {
|
||||
char *end = strchr (arg, '}');
|
||||
if (end == NULL) {
|
||||
eprintf ("No end bracket. Try pm {ecx}b @ esi\n");
|
||||
eprintf ("No end bracket. Try pf {ecx}b @ esi\n");
|
||||
goto beach;
|
||||
}
|
||||
*end = '\0';
|
||||
@ -1208,13 +1398,26 @@ R_API int r_print_format(RPrint *p, ut64 seek, const ut8* b, const int len,
|
||||
if (args) {
|
||||
int l = 0, maxl = 0;
|
||||
argend = args;
|
||||
args = strdup (args + 1);
|
||||
tmp = *args;
|
||||
while (tmp == ' ') {
|
||||
args++;
|
||||
tmp = *args;
|
||||
}
|
||||
args = strdup (args);
|
||||
nargs = r_str_word_set0 (args);
|
||||
if (nargs == 0) {
|
||||
R_FREE (args);
|
||||
}
|
||||
for (i = 0; i < nargs; i++) {
|
||||
const int len = strlen (r_str_word_get0 (args, i));
|
||||
char *tmp = r_str_word_get0 (args, i);
|
||||
char *nm = NULL;
|
||||
int len;
|
||||
nm = r_str_rchr (tmp, NULL, ')');
|
||||
if (nm) {
|
||||
len = strlen (nm+1);
|
||||
} else {
|
||||
len = strlen (tmp);
|
||||
}
|
||||
if (len > maxl) {
|
||||
maxl = len;
|
||||
}
|
||||
@ -1267,7 +1470,6 @@ R_API int r_print_format(RPrint *p, ut64 seek, const ut8* b, const int len,
|
||||
}
|
||||
}
|
||||
arg = orig;
|
||||
int flag = 0;
|
||||
for (idx = 0; i < len && arg < argend && *arg; arg++) {
|
||||
int size = 0, elem = 0; /* size of the array, element of the array */
|
||||
char *fieldname = NULL, *fmtname = NULL;
|
||||
@ -1306,6 +1508,7 @@ R_API int r_print_format(RPrint *p, ut64 seek, const ut8* b, const int len,
|
||||
if (mode & R_PRINT_MUSTSEE && otimes > 1) {
|
||||
p->cb_printf (" ");
|
||||
}
|
||||
|
||||
if (idx < nargs && tmp != 'e' && isptr == 0) {
|
||||
char *dot = NULL, *bracket = NULL;
|
||||
if (field)
|
||||
@ -1317,9 +1520,10 @@ R_API int r_print_format(RPrint *p, ut64 seek, const ut8* b, const int len,
|
||||
if (ISSTRUCT || tmp=='E' || tmp=='B' || tmp=='r') {
|
||||
if (*fieldname == '(') {
|
||||
fmtname = fieldname+1;
|
||||
fieldname = strchr (fieldname, ')');
|
||||
if (fieldname) *fieldname++ = '\0';
|
||||
else {
|
||||
fieldname = r_str_rchr (fieldname, NULL, ')');
|
||||
if (fieldname) {
|
||||
*fieldname++ = '\0';
|
||||
} else {
|
||||
eprintf ("Missing closing parenthesis in format ')'\n");
|
||||
goto beach;
|
||||
}
|
||||
@ -1347,16 +1551,18 @@ R_API int r_print_format(RPrint *p, ut64 seek, const ut8* b, const int len,
|
||||
}
|
||||
*end = '\0';
|
||||
elem = r_num_math (NULL, bracket+1)+1; // +1 to handle 0 index easily
|
||||
for ( ; bracket < end; bracket++)
|
||||
for ( ; bracket < end; bracket++) {
|
||||
*bracket = '\0';
|
||||
}
|
||||
size += elem*ARRAYINDEX_COEF;
|
||||
} else {
|
||||
elem = -1;
|
||||
}
|
||||
idx++;
|
||||
if (MUSTSEE && !SEEVALUE && !flag) {
|
||||
p->cb_printf (namefmt, fieldname);
|
||||
flag = 1;
|
||||
if (tmp != '.' && tmp != ':') {
|
||||
idx++;
|
||||
if (MUSTSEE && !SEEVALUE) {
|
||||
p->cb_printf (namefmt, fieldname);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1366,7 +1572,9 @@ R_API int r_print_format(RPrint *p, ut64 seek, const ut8* b, const int len,
|
||||
{
|
||||
nexti = i + (p->bits/8);
|
||||
i = 0;
|
||||
if (tmp == '?' ) seeki = addr;
|
||||
if (tmp == '?' ) {
|
||||
seeki = addr;
|
||||
}
|
||||
memset (buf, '\0', len);
|
||||
if (MUSTSEE) {
|
||||
p->cb_printf ("(*0x%"PFMT64x")", addr);
|
||||
@ -1415,33 +1623,36 @@ R_API int r_print_format(RPrint *p, ut64 seek, const ut8* b, const int len,
|
||||
endian ^= 1;
|
||||
continue;
|
||||
case ':': // skip 4 bytes
|
||||
if (size == -1) i+=4;
|
||||
else while (size--) i+=4;
|
||||
idx--;
|
||||
if (size == -1) {
|
||||
i += 4;
|
||||
} else {
|
||||
while (size--) {
|
||||
i+=4;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
case '.': // skip 1 byte
|
||||
i += (size == -1)? 1: size;
|
||||
idx--;
|
||||
continue;
|
||||
case 'p': // pointer reference
|
||||
if (*(arg+1) == '2') {
|
||||
p->bits = 16;
|
||||
tmp = 'w';
|
||||
arg++;
|
||||
} else if (*(arg+1) == '4') {
|
||||
p->bits = 32;
|
||||
tmp = 'x';
|
||||
arg++;
|
||||
} else if (*(arg+1) == '8') {
|
||||
p->bits = 64;
|
||||
tmp = 'q';
|
||||
arg++;
|
||||
}
|
||||
switch (p->bits) {
|
||||
} else { //If pointer reference is not mentioned explicitly
|
||||
switch (p->bits) {
|
||||
case 16: tmp = 'w'; break;
|
||||
case 32: tmp = 'x'; break;
|
||||
default: tmp = 'q'; break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
flag = 0;
|
||||
|
||||
/* flags */
|
||||
if (mode & R_PRINT_SEEFLAGS && isptr != NULLPTR) {
|
||||
@ -1488,7 +1699,11 @@ R_API int r_print_format(RPrint *p, ut64 seek, const ut8* b, const int len,
|
||||
if (ISSTRUCT) {
|
||||
p->cb_printf ("%s", fmtname);
|
||||
} else {
|
||||
p->cb_printf ("%c", tmp);
|
||||
if (tmp == 'n' || tmp == 'N') {
|
||||
p->cb_printf ("%c%c", tmp, *(arg+1));
|
||||
} else {
|
||||
p->cb_printf ("%c", tmp);
|
||||
}
|
||||
}
|
||||
if (isptr) p->cb_printf ("*");
|
||||
p->cb_printf ("\",\"offset\":%d,\"value\":",(isptr)?(seek+nexti-(p->bits/8)):seek+i);
|
||||
@ -1544,7 +1759,7 @@ R_API int r_print_format(RPrint *p, ut64 seek, const ut8* b, const int len,
|
||||
i += (size==-1) ? 4 : 4*size;
|
||||
break;
|
||||
case 'i':
|
||||
case 'd':
|
||||
case 'd': //WHY?? help says: 0x%%08x hexadecimal value (4 bytes)
|
||||
r_print_format_hex (p, endian, mode, setval, seeki, buf, i, size);
|
||||
i+= (size==-1) ? 4 : 4*size;
|
||||
break;
|
||||
@ -1602,53 +1817,85 @@ R_API int r_print_format(RPrint *p, ut64 seek, const ut8* b, const int len,
|
||||
{
|
||||
int s = 0;
|
||||
char *nxtfield = NULL;
|
||||
char *format = NULL;
|
||||
int anon = 0;
|
||||
if (size >= ARRAYINDEX_COEF) {
|
||||
elem = size / ARRAYINDEX_COEF - 1;
|
||||
size %= ARRAYINDEX_COEF;
|
||||
}
|
||||
if (!(mode & R_PRINT_ISFIELD)) nxtfield = MINUSONE;
|
||||
else if (field) nxtfield = strchr (ofield, '.');
|
||||
if (nxtfield != MINUSONE && nxtfield) nxtfield++;
|
||||
if (!(mode & R_PRINT_ISFIELD)) {
|
||||
nxtfield = MINUSONE;
|
||||
} else if (field) {
|
||||
nxtfield = strchr (ofield, '.');
|
||||
}
|
||||
if (nxtfield != MINUSONE && nxtfield) {
|
||||
nxtfield++;
|
||||
}
|
||||
|
||||
if (MUSTSEE) {
|
||||
if (!SEEVALUE) p->cb_printf ("\n");
|
||||
}
|
||||
if (MUSTSEEJSON) {
|
||||
if (isptr)
|
||||
if (isptr) {
|
||||
p->cb_printf ("%d},", seeki);
|
||||
else
|
||||
} else {
|
||||
p->cb_printf ("[");
|
||||
}
|
||||
}
|
||||
if (mode & R_PRINT_SEEFLAGS) {
|
||||
slide += STRUCTFLAG;
|
||||
}
|
||||
format = strchr (fmtname, ' ');
|
||||
if (format) {
|
||||
anon = 1;
|
||||
fmtname = format;
|
||||
while (*fmtname == ' ') {
|
||||
fmtname++;
|
||||
}
|
||||
}
|
||||
if (mode & R_PRINT_SEEFLAGS) slide += STRUCTFLAG;
|
||||
oldslide = slide;
|
||||
slide += (isptr) ? STRUCTPTR : NESTEDSTRUCT;
|
||||
if (size == -1) {
|
||||
s = r_print_format_struct (p, seeki,
|
||||
buf+i, len-i, fmtname, slide,
|
||||
mode, setval, nxtfield);
|
||||
i+= (isptr) ? 4 : s;
|
||||
s = r_print_format_struct (p, seeki,
|
||||
buf+i, len-i, fmtname, slide,
|
||||
mode, setval, nxtfield, anon);
|
||||
i += (isptr) ? (p->bits / 8) : s;
|
||||
} else {
|
||||
if (mode & R_PRINT_ISFIELD)
|
||||
if (!SEEVALUE) p->cb_printf ("[\n");
|
||||
if (mode & R_PRINT_ISFIELD) {
|
||||
if (!SEEVALUE) {
|
||||
p->cb_printf ("[\n");
|
||||
}
|
||||
}
|
||||
while (size--) {
|
||||
if (elem == -1 || elem == 0) {
|
||||
mode |= R_PRINT_MUSTSEE;
|
||||
if (elem == 0) elem = -2;
|
||||
if (elem == 0) {
|
||||
elem = -2;
|
||||
}
|
||||
} else {
|
||||
mode &= ~R_PRINT_MUSTSEE;
|
||||
}
|
||||
s = r_print_format_struct (p, seek+i,
|
||||
buf+i, len-i, fmtname, slide, mode, setval, nxtfield);
|
||||
buf+i, len-i, fmtname, slide, mode, setval, nxtfield, anon);
|
||||
if ((MUSTSEE || MUSTSEEJSON) && size != 0 && elem == -1) {
|
||||
p->cb_printf (",");
|
||||
if (MUSTSEE) p->cb_printf ("\n");
|
||||
if (MUSTSEE) {
|
||||
p->cb_printf ("\n");
|
||||
}
|
||||
}
|
||||
if (elem > -1) elem--;
|
||||
i+= (isptr) ? 4 : s;
|
||||
if (elem > -1) {
|
||||
elem--;
|
||||
}
|
||||
i += (isptr) ? (p->bits / 8) : s;
|
||||
}
|
||||
if (mode & R_PRINT_ISFIELD) {
|
||||
if (!SEEVALUE) {
|
||||
p->cb_printf ("]");
|
||||
}
|
||||
}
|
||||
if (MUSTSEEJSON) {
|
||||
p->cb_printf ("]}]}");
|
||||
}
|
||||
if (mode & R_PRINT_ISFIELD)
|
||||
if (!SEEVALUE) p->cb_printf ("]");
|
||||
if (MUSTSEEJSON) p->cb_printf ("]}]}");
|
||||
}
|
||||
oldslide = slide;
|
||||
slide -= (isptr) ? STRUCTPTR : NESTEDSTRUCT;
|
||||
@ -1658,6 +1905,29 @@ R_API int r_print_format(RPrint *p, ut64 seek, const ut8* b, const int len,
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'n':
|
||||
case 'N':
|
||||
{
|
||||
int bytes = 0;
|
||||
int sign = (tmp == 'n') ? 1 : 0;
|
||||
if (arg[1] == '1') {
|
||||
bytes = 1;
|
||||
} else if (arg[1] == '2') {
|
||||
bytes = 2;
|
||||
} else if (arg[1] == '4') {
|
||||
bytes = 4;
|
||||
} else if (arg[1] == '8') {
|
||||
bytes = 8;
|
||||
} else {
|
||||
invalid = 1;
|
||||
break;
|
||||
//or goto beach;???
|
||||
}
|
||||
r_print_format_num (p, endian, mode, setval, seeki, buf, i, bytes, sign, size);
|
||||
i += (size == -1) ? bytes : size * bytes;
|
||||
arg++;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
/* ignore unknown chars */
|
||||
invalid = 1;
|
||||
|
@ -333,13 +333,15 @@ R_API int r_str_word_set0(char *str) {
|
||||
if (!str || !*str)
|
||||
return 0;
|
||||
for (i=0; str[i] && str[i+1]; i++) {
|
||||
if (str[i]==' ' && str[i+1]==' ') {
|
||||
int len = strlen (str+i+1)+1;
|
||||
if (i > 0 && str[i-1] == ' ' && str[i] == ' ') {
|
||||
int len = strlen (str+i)+1;
|
||||
memmove (str+i, str+i+1, len);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
if (str[i]==' ')
|
||||
if (str[i]==' ') {
|
||||
str[i] = 0;
|
||||
}
|
||||
for (i=1, p=str; *p; p++) {
|
||||
if (*p=='\"') {
|
||||
if (quote) {
|
||||
@ -355,9 +357,13 @@ R_API int r_str_word_set0(char *str) {
|
||||
if (quote) continue;
|
||||
if (*p==' ') {
|
||||
char *q = p-1;
|
||||
if (p>str && *q=='\\') {
|
||||
memmove (q, p, strlen (p)+1);
|
||||
continue;
|
||||
if (p > str && (*q == '\\' || !*q)) {
|
||||
memmove (p, p+1, strlen (p+1)+1);
|
||||
if (*q == '\\') {
|
||||
*q = ' ';
|
||||
continue;
|
||||
}
|
||||
p--;
|
||||
}
|
||||
i++;
|
||||
*p='\0';
|
||||
|
Loading…
x
Reference in New Issue
Block a user