mirror of
https://github.com/radareorg/radare2.git
synced 2024-11-24 13:49:50 +00:00
* Fix lot of bugs with cons+grep for @@=`` or stuff like that
* The grepping algorithm in r_cons has been rewritten from scratch - Grepped at memcat() which is the root entrypoint for console IO - Faster than before (200 less LOC) - Not yet working at all, but it is quite better than before * Fix history bug when using @@ * Use return value of filtercmd function to not invoke children core_cmd * Fix some random segfaults
This commit is contained in:
parent
692cefa68b
commit
448d76a5e7
4
TODO
4
TODO
@ -1,7 +1,3 @@
|
||||
* BUG: r_core_cmd_str doesnt works with grep strings because
|
||||
uses the get_buffer method. we have to refactor r_cons to
|
||||
filter strings at runtime instead of doing it at flush()
|
||||
|
||||
* Add maxrows option for r_print (fix visual problem)
|
||||
* Drop #if conditionals to use #ifdef ones
|
||||
- fits better with plan9 compiler
|
||||
|
280
libr/cons/cons.c
280
libr/cons/cons.c
@ -34,6 +34,7 @@ FILE *r_cons_stdin_fd = NULL; // TODO use int fd here too!
|
||||
static int r_cons_buffer_sz = 0;
|
||||
static int r_cons_buffer_len = 0;
|
||||
static char *r_cons_buffer = NULL;
|
||||
static char *r_cons_lastline = NULL;
|
||||
char *r_cons_filterline = NULL;
|
||||
char *r_cons_teefile = NULL;
|
||||
int r_cons_is_html = 0;
|
||||
@ -171,6 +172,11 @@ void r_cons_reset()
|
||||
r_cons_buffer[0] = '\0';
|
||||
r_cons_buffer_len = 0;
|
||||
r_cons_lines = 0;
|
||||
r_cons_lastline = r_cons_buffer;
|
||||
grepstrings_n = 0; // XXX
|
||||
grepline = -1;
|
||||
grepstr = NULL;
|
||||
greptoken = -1;
|
||||
}
|
||||
|
||||
const char *r_cons_get_buffer()
|
||||
@ -180,6 +186,7 @@ const char *r_cons_get_buffer()
|
||||
|
||||
void r_cons_grep(const char *str)
|
||||
{
|
||||
char *optr, *tptr;
|
||||
char *ptr, *ptr2, *ptr3;
|
||||
grepcounter=0;
|
||||
/* set grep string */
|
||||
@ -214,10 +221,10 @@ void r_cons_grep(const char *str)
|
||||
free(grepstr);
|
||||
grepstr = (char *)strdup(ptr);
|
||||
/* set the rest of words to grep */
|
||||
grepstrings_n = 0;
|
||||
{ // TODO: refactor this ugly loop
|
||||
char *optr = grepstr;
|
||||
char *tptr = strchr(optr, '!');
|
||||
grepstrings_n = 0;
|
||||
// TODO: refactor this ugly loop
|
||||
optr = grepstr;
|
||||
tptr = strchr(optr, '!');
|
||||
while(tptr) {
|
||||
tptr[0] = '\0';
|
||||
// TODO: check if keyword > 64
|
||||
@ -230,13 +237,11 @@ void r_cons_grep(const char *str)
|
||||
grepstrings_n++;
|
||||
ptr = optr;
|
||||
}
|
||||
|
||||
}
|
||||
} else {
|
||||
greptoken = -1;
|
||||
grepline = -1;
|
||||
//free(grepstr);
|
||||
grepstr = NULL;
|
||||
grepstrings_n = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -247,6 +252,7 @@ void r_cons_flush()
|
||||
char buf[1024];
|
||||
int i,j;
|
||||
int lines_counter = 0;
|
||||
char *tee = r_cons_teefile;
|
||||
|
||||
if (r_cons_noflush)
|
||||
return;
|
||||
@ -260,9 +266,19 @@ void r_cons_flush()
|
||||
}
|
||||
}
|
||||
|
||||
if (!STR_IS_NULL(r_cons_buffer)) {
|
||||
if (tee&&tee[0]) {
|
||||
FILE *d = fopen(tee, "a+");
|
||||
if (d != NULL) {
|
||||
fwrite(r_cons_buffer, strlen(r_cons_buffer), 1, d);
|
||||
fclose(d);
|
||||
}
|
||||
} else write(1, r_cons_buffer, r_cons_buffer_len);
|
||||
// TODO: make 'write' portable
|
||||
r_cons_reset();
|
||||
return;
|
||||
|
||||
#if 0
|
||||
char *file = r_cons_filterline;
|
||||
char *tee = r_cons_teefile;
|
||||
if (!STR_IS_NULL(file)) {
|
||||
fd = fopen(file, "r");
|
||||
if (fd) {
|
||||
@ -282,166 +298,12 @@ void r_cons_flush()
|
||||
fclose(fd);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (tee&&tee[0]) {
|
||||
FILE *d = fopen(tee, "a+");
|
||||
if (d != NULL) {
|
||||
fwrite(r_cons_buffer, strlen(r_cons_buffer),1, d);
|
||||
fclose(d);
|
||||
}
|
||||
}
|
||||
|
||||
// XXX merge grepstr with r_cons_lines loop //
|
||||
r_cons_lines += r_str_nchr(buf, '\n');
|
||||
|
||||
// XXX buggy! this needs a major cleanup here!
|
||||
if (grepstr != NULL) {
|
||||
int line, len;
|
||||
char *one = r_cons_buffer;
|
||||
char *two;
|
||||
char *ptr, *tok;
|
||||
char delims[6][2] = {"|", "/", "\\", ",", ";", "\t"};
|
||||
|
||||
for(line=0;;) {
|
||||
two = strchr(one, '\n');
|
||||
if (two) {
|
||||
int grepstr_match = 0;
|
||||
two[0] = '\0';
|
||||
len = two-one;
|
||||
// len = strlen(one);
|
||||
// if (strstr(one, grepstr)) {
|
||||
for(i=0;i<grepstrings_n;i++) {
|
||||
grepstr=grepstrings[i];
|
||||
if ( (!grepneg && strstr(one, grepstr))
|
||||
|| (grepneg && !strstr(one, grepstr))) {
|
||||
grepstr_match=1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (grepstr_match) {
|
||||
if (grepline ==-1 || grepline==line) {
|
||||
if (greptoken != -1) {
|
||||
ptr = alloca(len+1);
|
||||
strcpy(ptr, one);
|
||||
for (i=0; i<len; i++)
|
||||
for (j=0;j<6;j++)
|
||||
if (ptr[i] == delims[j][0])
|
||||
ptr[i] = ' ';
|
||||
tok = ptr;
|
||||
if (greptoken<0) {
|
||||
int i, idx = greptoken+1;
|
||||
for(i = 0;ptr[i]; i++) {
|
||||
if (ptr[i]==' ')
|
||||
idx++;
|
||||
if (idx == 0) {
|
||||
ptr = ptr +i;
|
||||
r_cons_buffer_len = strlen(ptr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (i=0;tok != NULL && i<=greptoken;i++) {
|
||||
if (i==0)
|
||||
tok = (char *)strtok(ptr, " ");
|
||||
else tok = (char *)strtok(NULL, " ");
|
||||
}
|
||||
}
|
||||
|
||||
if (tok) {
|
||||
ptr = tok;
|
||||
r_cons_buffer_len=strlen(tok);
|
||||
}
|
||||
} else {
|
||||
ptr = one;
|
||||
r_cons_buffer_len=len;
|
||||
}
|
||||
if (grepcounter==0) {
|
||||
r_cons_print_real(ptr);
|
||||
r_cons_buffer_len=1;
|
||||
r_cons_print_real("\n");
|
||||
} else lines_counter++;
|
||||
}
|
||||
line++;
|
||||
}
|
||||
two[0] = '\n';
|
||||
one = two + 1;
|
||||
} else break;
|
||||
}
|
||||
} else {
|
||||
if (grepline != -1 || grepcounter || greptoken != -1) {
|
||||
int len, line;
|
||||
char *one = r_cons_buffer;
|
||||
char *two;
|
||||
char *ptr, *tok;
|
||||
char delims[6][2] = {"|", "/", "\\", ",", ";", "\t"};
|
||||
for(line=0;;line++) {
|
||||
two = strchr(one, '\n');
|
||||
if (two) {
|
||||
two[0] = '\0';
|
||||
len=two-one;
|
||||
if (grepline ==-1 || grepline==line) {
|
||||
if (greptoken != -1) {
|
||||
ptr = alloca(len+1);
|
||||
strcpy(ptr, one);
|
||||
|
||||
for (i=0; i<len; i++)
|
||||
for (j=0;j<6;j++)
|
||||
if (ptr[i] == delims[j][0])
|
||||
ptr[i] = ' ';
|
||||
|
||||
tok = ptr;
|
||||
if (greptoken<0) {
|
||||
int i, idx = greptoken+1;
|
||||
for(i = 0;ptr[i]; i++) {
|
||||
if (ptr[i]==' ')
|
||||
idx++;
|
||||
if (idx == 0) {
|
||||
ptr = ptr +i;
|
||||
r_cons_buffer_len = strlen(ptr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (i=0;tok != NULL && i<=greptoken;i++) {
|
||||
if (i==0)
|
||||
tok = (char *)strtok(ptr, " ");
|
||||
else tok = (char *)strtok(NULL," ");
|
||||
}
|
||||
}
|
||||
|
||||
if (tok) {
|
||||
ptr = tok;
|
||||
r_cons_buffer_len=strlen(tok);
|
||||
}
|
||||
} else {
|
||||
ptr = one;
|
||||
r_cons_buffer_len=len;
|
||||
}
|
||||
if (grepcounter==0) {
|
||||
r_cons_print_real(ptr);
|
||||
r_cons_buffer_len=1;
|
||||
r_cons_print_real("\n");
|
||||
} else lines_counter++;
|
||||
}
|
||||
two[0] = '\n';
|
||||
one = two + 1;
|
||||
} else break;
|
||||
}
|
||||
} else r_cons_print_real(r_cons_buffer);
|
||||
}
|
||||
|
||||
r_cons_buffer[0] = '\0';
|
||||
}
|
||||
|
||||
if (grepcounter) {
|
||||
char buf[32];
|
||||
sprintf(buf, "%d\n", lines_counter);
|
||||
r_cons_buffer_len = strlen(buf);
|
||||
r_cons_print_real(buf);
|
||||
}
|
||||
r_cons_buffer_len = 0;
|
||||
}
|
||||
|
||||
#if 0
|
||||
// UNUSED
|
||||
/* stream is ignored */
|
||||
void r_cons_fprintf(FILE *stream, const char *format, ...)
|
||||
{
|
||||
@ -462,6 +324,7 @@ void r_cons_fprintf(FILE *stream, const char *format, ...)
|
||||
|
||||
va_end(ap);
|
||||
}
|
||||
#endif
|
||||
|
||||
void r_cons_printf(const char *format, ...)
|
||||
{
|
||||
@ -477,21 +340,90 @@ void r_cons_printf(const char *format, ...)
|
||||
va_start(ap, format);
|
||||
|
||||
len = vsnprintf(buf, CONS_BUFSZ-1, format, ap);
|
||||
if (len>0) {
|
||||
palloc(len);
|
||||
// r_cons_lines += r_cons_lines_count(buf);
|
||||
memcpy(r_cons_buffer+r_cons_buffer_len, buf, len+1);
|
||||
r_cons_buffer_len += len;
|
||||
}
|
||||
if (len>0)
|
||||
r_cons_memcat(buf, len);
|
||||
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
int r_cons_grepbuf(const char *buf, int len)
|
||||
{
|
||||
int donotline = 0;
|
||||
int i, j, hit = 0;
|
||||
char delims[6][2] = {"|", "/", "\\", ",", ";", "\t"};
|
||||
char *n = memchr(buf, '\n', len);
|
||||
|
||||
if (grepstrings_n==0) {
|
||||
if (n) r_cons_lines++;
|
||||
return len;
|
||||
}
|
||||
|
||||
if (r_cons_lastline==NULL)
|
||||
r_cons_lastline = r_cons_buffer;
|
||||
|
||||
if (!n) return len;
|
||||
|
||||
for(i=0;i<grepstrings_n;i++) {
|
||||
grepstr = grepstrings[i];
|
||||
if ( (!grepneg && strstr(buf, grepstr))
|
||||
|| (grepneg && !strstr(buf, grepstr))) {
|
||||
hit = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (hit) {
|
||||
if (grepline != -1) {
|
||||
if (grepline==r_cons_lines) {
|
||||
r_cons_lastline = buf+len;
|
||||
//r_cons_lines++;
|
||||
} else {
|
||||
donotline = 1;
|
||||
r_cons_lines++;
|
||||
}
|
||||
}
|
||||
} else donotline = 1;
|
||||
|
||||
if (donotline) {
|
||||
r_cons_buffer_len -= strlen(r_cons_lastline)-len;
|
||||
r_cons_lastline[0]='\0';
|
||||
len = 0;
|
||||
} else {
|
||||
if (greptoken != -1) {
|
||||
//ptr = alloca(strlen(r_cons_lastline));
|
||||
char *tok = NULL;
|
||||
char *ptr = alloca(1024); // XXX
|
||||
strcpy(ptr, r_cons_lastline);
|
||||
for (i=0; i<len; i++) for (j=0;j<6;j++)
|
||||
if (ptr[i] == delims[j][0])
|
||||
ptr[i] = ' ';
|
||||
tok = ptr;
|
||||
for (i=0;tok != NULL && i<=greptoken;i++) {
|
||||
if (i==0) tok = (char *)strtok(ptr, " ");
|
||||
else tok = (char *)strtok(NULL, " ");
|
||||
}
|
||||
if (tok) {
|
||||
// XXX remove strlen here!
|
||||
r_cons_buffer_len -= strlen(r_cons_lastline)-len;
|
||||
len = strlen(tok);
|
||||
memcpy(r_cons_lastline, tok, len);
|
||||
if (r_cons_lastline[len-1]!='\n')
|
||||
memcpy(r_cons_lastline+len, "\n", 2);
|
||||
len++;
|
||||
r_cons_lastline +=len;
|
||||
}
|
||||
} else r_cons_lastline = buf+len;
|
||||
r_cons_lines++;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
/* final entrypoint for adding stuff in the buffer screen */
|
||||
void r_cons_memcat(const char *str, int len)
|
||||
{
|
||||
palloc(len);
|
||||
memcpy(r_cons_buffer+r_cons_buffer_len, str, len+1);
|
||||
r_cons_buffer_len += len;
|
||||
memcpy(r_cons_buffer+r_cons_buffer_len, str, len+1); // XXX +1??
|
||||
r_cons_buffer_len += r_cons_grepbuf(r_cons_buffer+r_cons_buffer_len, len);
|
||||
}
|
||||
|
||||
void r_cons_strcat(const char *str)
|
||||
|
@ -788,7 +788,8 @@ static int cmd_eval(void *data, const char *input)
|
||||
r_config_list(&core->config, NULL, 0);
|
||||
break;
|
||||
case '-':
|
||||
r_config_init(&core->config, core);
|
||||
r_core_config_init(core);
|
||||
eprintf("BUG: 'e-' command locks the eval hashtable. patches are welcome :)\n");
|
||||
break;
|
||||
case '*':
|
||||
r_config_list(&core->config, NULL, 1);
|
||||
@ -1027,23 +1028,6 @@ static int r_core_cmd_subst(struct r_core_t *core, char *cmd, int *rs, int *rfd,
|
||||
for(str=ptr+1; str[0]== ' '; str=str+1);
|
||||
*rfd = r_cons_pipe_open(str, ptr[1]=='>');
|
||||
}
|
||||
ptr = strchr(cmd, '@');
|
||||
if (ptr) {
|
||||
char *pt = ptr;
|
||||
ptr[0]='\0';
|
||||
while(pt[0]==' '||pt[0]=='\t') {
|
||||
pt[0]='\0';
|
||||
pt = pt-1;
|
||||
}
|
||||
*rs = 1;
|
||||
if (ptr[1]=='@') {
|
||||
// TODO: remove temporally seek (should be done by cmd_foreach)
|
||||
u64 tmpoff = core->seek;
|
||||
r_core_cmd_foreach(core, cmd, ptr+2);
|
||||
r_core_seek(core, tmpoff);
|
||||
return 0;
|
||||
} else r_core_seek(core, r_num_math(&core->num, ptr+1));
|
||||
}
|
||||
|
||||
while(((ptr = strchr(cmd, '`')))) {
|
||||
ptr2 = strchr(ptr+1, '`');
|
||||
@ -1058,6 +1042,30 @@ static int r_core_cmd_subst(struct r_core_t *core, char *cmd, int *rs, int *rfd,
|
||||
free(str);
|
||||
}
|
||||
|
||||
ptr = strchr(cmd, '~');
|
||||
if (ptr) {
|
||||
ptr[0]='\0';
|
||||
r_cons_grep(ptr+1);
|
||||
} else r_cons_grep(NULL);
|
||||
|
||||
ptr = strchr(cmd, '@');
|
||||
if (ptr) {
|
||||
char *pt = ptr;
|
||||
ptr[0]='\0';
|
||||
while(pt[0]==' '||pt[0]=='\t') {
|
||||
pt[0]='\0';
|
||||
pt = pt-1;
|
||||
}
|
||||
*rs = 1;
|
||||
if (ptr[1]=='@') {
|
||||
// TODO: remove temporally seek (should be done by cmd_foreach)
|
||||
u64 tmpoff = core->seek;
|
||||
r_core_cmd_foreach(core, cmd, ptr+2);
|
||||
r_core_seek(core, tmpoff);
|
||||
return -1; /* do not run out-of-foreach cmd */
|
||||
} else r_core_seek(core, r_num_math(&core->num, ptr+1));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1067,7 +1075,7 @@ int r_core_cmd_foreach(struct r_core_t *core, const char *cmd, char *each)
|
||||
int i=0,j;
|
||||
char ch;
|
||||
char *word = NULL;
|
||||
char *str;
|
||||
char *str, *ostr;
|
||||
struct list_head *pos;
|
||||
u64 oseek, addr;
|
||||
|
||||
@ -1075,7 +1083,7 @@ int r_core_cmd_foreach(struct r_core_t *core, const char *cmd, char *each)
|
||||
for(;*cmd==' ';cmd=cmd+1);
|
||||
|
||||
oseek = core->seek;
|
||||
str = strdup(each);
|
||||
ostr = str = strdup(each);
|
||||
//radare_controlc();
|
||||
|
||||
switch(each[0]) {
|
||||
@ -1089,19 +1097,21 @@ int r_core_cmd_foreach(struct r_core_t *core, const char *cmd, char *each)
|
||||
break;
|
||||
case '=':
|
||||
/* foreach list of items */
|
||||
each = each+1;
|
||||
each = str+1;
|
||||
do {
|
||||
while(each[0]==' ') each=each+1;
|
||||
if (!*each) break;
|
||||
str = strchr(each, ' ');
|
||||
if (str) {
|
||||
str[0]='\0';
|
||||
addr = r_num_math(&core->num, each);
|
||||
str[0]=' ';
|
||||
} else addr = r_num_math(&core->num, each);
|
||||
eprintf("; 0x%08llx:\n", addr);
|
||||
each = str+1;
|
||||
r_core_seek(core, addr);
|
||||
eprintf("\n"); //eprintf("===(%s)at(0x%08llx)\n", cmd, addr);
|
||||
r_core_cmd(core, cmd, 0);
|
||||
r_cons_flush();
|
||||
} while(str != NULL);
|
||||
break;
|
||||
case '.':
|
||||
@ -1218,7 +1228,7 @@ printf("No flags foreach implemented\n");
|
||||
|
||||
free(word);
|
||||
word = NULL;
|
||||
free(str);
|
||||
free(ostr);
|
||||
}
|
||||
|
||||
int r_core_cmd(struct r_core_t *core, const char *command, int log)
|
||||
@ -1255,10 +1265,7 @@ int r_core_cmd(struct r_core_t *core, const char *command, int log)
|
||||
}
|
||||
|
||||
ret = r_core_cmd_subst(core, cmd, &restoreseek, &newfd, ×);
|
||||
if (ret == -1) {
|
||||
fprintf(stderr, "Invalid conversion: '%s'\n", command);
|
||||
ret = -1;
|
||||
} else {
|
||||
if (ret != -1) {
|
||||
for(i=0;i<times;i++) {
|
||||
if (quoted) {
|
||||
ret = r_cmd_call(&core->cmd, cmd);
|
||||
@ -1286,9 +1293,10 @@ int r_core_cmd(struct r_core_t *core, const char *command, int log)
|
||||
ret = 1;
|
||||
} else
|
||||
if (log) r_line_hist_add(command);
|
||||
if (restoreseek)
|
||||
r_core_seek(core, tmpseek);
|
||||
}
|
||||
if (log) r_line_hist_add(command);
|
||||
if (restoreseek)
|
||||
r_core_seek(core, tmpseek);
|
||||
|
||||
if (newfd != 1) {
|
||||
r_cons_flush();
|
||||
@ -1299,7 +1307,7 @@ int r_core_cmd(struct r_core_t *core, const char *command, int log)
|
||||
core->oobi = NULL;
|
||||
core->oobi_len = 0;
|
||||
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int r_core_cmd_file(struct r_core_t *core, const char *file)
|
||||
|
Loading…
Reference in New Issue
Block a user