radare2/libr/cons/grep.c

280 lines
6.2 KiB
C
Raw Normal View History

/* radare - LGPL - Copyright 2009-2011 pancake<nopcode.org> nibble<develsec.org> */
#include <r_cons.h>
#include <r_util.h>
R_API void r_cons_grep(const char *str) {
RCons *cons;
char buf[1024];
2010-07-16 12:53:06 +00:00
char *ptr, *optr, *ptr2, *ptr3;
cons = r_cons_singleton ();
2010-07-16 12:53:06 +00:00
cons->grep.str = NULL;
cons->grep.nstrings = 0;
cons->grep.tokenfrom = 0;
cons->grep.tokento = ST32_MAX;
cons->grep.line = -1;
2010-07-16 12:53:06 +00:00
cons->grep.counter = cons->grep.neg = 0;
2010-07-16 12:53:06 +00:00
if (str == NULL || !*str)
return;
2010-07-16 12:53:06 +00:00
if (*str == '!') { // neg
cons->grep.neg = 1;
str++;
2010-07-16 12:53:06 +00:00
}
if (*str == '?') { // counter
cons->grep.counter = 1;
str++;
2010-07-16 12:53:06 +00:00
}
strncpy (buf, str, sizeof (buf));
ptr = buf;
ptr3 = strchr (ptr, '['); // column number
if (ptr3) {
ptr3[0]='\0';
cons->grep.tokenfrom = r_num_get (cons->num, ptr3+1);
ptr3 = strchr (ptr3+1, '-');
if (ptr3) {
cons->grep.tokento = r_num_get (cons->num, ptr3+1);
if (cons->grep.tokento == 0)
cons->grep.tokento = ST32_MAX;
} else cons->grep.tokento = cons->grep.tokenfrom;
if (cons->grep.tokenfrom<0)
cons->grep.tokenfrom = 0;
if (cons->grep.tokento<0)
cons->grep.tokento = ST32_MAX;
2010-07-16 12:53:06 +00:00
}
ptr2 = strchr (ptr, ':'); // line number
if (ptr2) {
*ptr2 = '\0';
cons->grep.line = r_num_get (cons->num, ptr2+1);
2010-07-16 12:53:06 +00:00
if (cons->grep.line<0)
cons->grep.line = -1;
}
free (cons->grep.str);
2010-07-16 12:53:06 +00:00
if (*ptr) {
cons->grep.str = (char *)strdup (ptr);
do {
optr = ptr;
ptr = strchr (ptr, ','); // grep keywords
if (ptr) {
ptr[0] = '\0';
ptr = ptr+1;
}
2010-07-16 12:53:06 +00:00
// TODO: check if keyword > 64
strncpy (cons->grep.strings[cons->grep.nstrings], optr, 63);
cons->grep.nstrings++;
2010-07-16 12:53:06 +00:00
} while (ptr);
} else {
cons->grep.str = strdup (ptr);
cons->grep.nstrings++;
cons->grep.strings[0][0] = 0;
}
}
R_API int r_cons_grepbuf(char *buf, int len) {
2010-07-16 12:53:06 +00:00
RCons *cons = r_cons_singleton ();
2010-08-03 11:30:58 +00:00
char *tline, *tbuf, *p, *out, *in = buf;
int ret, buffer_len = 0, l = 0, tl = 0;
2010-07-16 12:53:06 +00:00
out = tbuf = calloc (1, len);
2010-08-03 11:30:58 +00:00
tline = malloc (len);
2010-07-16 12:53:06 +00:00
cons->lines = 0;
while (in-buf<len) {
p = strchr (in, '\n');
if (!p) {
free (tbuf);
2010-08-03 11:30:58 +00:00
free (tline);
return 0;
}
2010-07-18 10:33:47 +00:00
l = p-in;
2010-08-03 11:30:58 +00:00
if (l > 0) {
2010-07-16 12:53:06 +00:00
memcpy (tline, in, l);
tl = r_str_ansi_filter (tline, l);
if (tl < 0)
ret = -1;
else ret = r_cons_grep_line (tline, tl);
2010-07-16 12:53:06 +00:00
if (ret > 0) {
if (cons->grep.line == -1 ||
(cons->grep.line != -1 && cons->grep.line == cons->lines)) {
2010-07-16 12:53:06 +00:00
memcpy (out, tline, ret);
2010-08-03 11:30:58 +00:00
memcpy (out+ret, "\n", 1);
out += ret+1;
buffer_len += ret+1;
2010-07-16 12:53:06 +00:00
}
cons->lines++;
} else if (ret < 0) {
2010-07-16 12:53:06 +00:00
free (tbuf);
2010-08-03 11:30:58 +00:00
free (tline);
2010-07-16 12:53:06 +00:00
return 0;
}
in += l+1;
} else in++;
}
2010-07-16 12:53:06 +00:00
memcpy (buf, tbuf, len);
cons->buffer_len = buffer_len;
free (tbuf);
2010-08-03 11:30:58 +00:00
free (tline);
if (cons->grep.counter) {
snprintf (cons->buffer, cons->buffer_len, "%d\n", cons->lines);
cons->buffer_len = strlen (cons->buffer);;
}
2010-07-16 12:53:06 +00:00
return cons->lines;
}
2010-07-16 12:53:06 +00:00
R_API int r_cons_grep_line(char *buf, int len) {
RCons *cons = r_cons_singleton ();
const char delims[6][2] = { "|", "/", "\\", ",", ";", "\t" };
2010-08-03 11:30:58 +00:00
char *in, *out, *tok = NULL;
2010-07-16 12:53:06 +00:00
int hit = cons->grep.neg;
int i, j, outlen = 0;
2010-08-03 11:30:58 +00:00
in = calloc (1, len+1);
out = calloc (1, len+2);
memcpy (in, buf, len);
2010-07-18 10:33:47 +00:00
if (cons->grep.nstrings>0) {
2010-07-16 12:53:06 +00:00
for (i=0; i<cons->grep.nstrings; i++)
2010-08-03 11:30:58 +00:00
if (strstr (in, cons->grep.strings[i])) {
2010-07-16 12:53:06 +00:00
hit = !cons->grep.neg;
break;
}
2010-07-18 10:33:47 +00:00
} else hit = 1;
2010-07-16 12:53:06 +00:00
if (hit) {
if ((cons->grep.tokenfrom != 0 || cons->grep.tokento != ST32_MAX) &&
(cons->grep.line == -1 || cons->grep.line == cons->lines)) {
for (i=0; i<len; i++) for (j=0; j<6; j++)
if (in[i] == delims[j][0])
in[i] = ' ';
2010-08-03 11:30:58 +00:00
for (i=0; i <= cons->grep.tokento; i++) {
tok = (char *) strtok (i?NULL:in, " ");
if (tok) {
if (i >= cons->grep.tokenfrom) {
int toklen = strlen (tok);
memcpy (out+outlen, tok, toklen);
memcpy (out+outlen+toklen, " ", 2);
outlen += toklen+1;
}
} else {
2010-08-03 11:30:58 +00:00
if (strlen (out) == 0) {
free (in);
free (out);
return -1;
} else break;
}
}
outlen = outlen>0? outlen - 1: 0;
if (outlen>len) { // should never happen
eprintf ("r_cons_grep_line: wtf, how you reach this?\n");
return -1;
}
memcpy (buf, out, len);
len = outlen;
}
2010-07-16 12:53:06 +00:00
} else len = 0;
2010-08-03 11:30:58 +00:00
free (in);
free (out);
2010-07-16 12:53:06 +00:00
return len;
}
2011-04-29 08:38:01 +00:00
static const char *gethtmlcolor(const char ptrch, const char *def) {
switch (ptrch) {
case '0': return "#000"; // BLACK
case '1': return "#f00"; // RED
case '2': return "#0f0"; // GREEN
case '3': return "#ff0"; // YELLOW
case '4': return "#00f"; // BLUE
case '5': return "#f0f"; // MAGENTA
case '6': return "#aaf"; // TURQOISE
case '7': return "#fff"; // WHITE
case '8': return "#777"; // GREY
case '9': break; // ???
}
return def;
}
// XXX: rename char *r_cons_filter_html(const char *ptr)
R_API int r_cons_html_print(const char *ptr) {
const char *str = ptr;
int esc = 0;
int len = 0;
int inv = 0;
int tmp;
for (;ptr[0]; ptr = ptr + 1) {
if (ptr[0] == '\n') {
printf ("<br />");
fflush (stdout);
}
if (ptr[0] == 0x1b) {
esc = 1;
tmp = (int) (size_t) (ptr-str);
if (write (1, str, tmp) != tmp)
eprintf ("r_cons_html_print: write: error\n");
str = ptr + 1;
continue;
}
if (esc == 1) {
// \x1b[2J
if (ptr[0] != '[') {
eprintf ("Oops invalid escape char\n");
esc = 0;
str = ptr + 1;
continue;
}
esc = 2;
continue;
} else
if (esc == 2) {
if (ptr[0]=='2'&&ptr[1]=='J') {
printf ("<hr />\n"); fflush(stdout);
2011-04-29 08:38:01 +00:00
ptr++;
esc = 0;
str = ptr;
continue;
} else
if (ptr[0]=='0'&&ptr[1]==';'&&ptr[2]=='0') {
r_cons_gotoxy (0,0);
2011-04-29 08:38:01 +00:00
ptr += 4;
esc = 0;
str = ptr;
continue;
} else
if (ptr[0]=='0'&&ptr[1]=='m') {
2011-04-29 08:38:01 +00:00
str = (++ptr) +1;
esc = inv = 0;
continue;
// reset color
} else
if (ptr[0]=='7'&&ptr[1]=='m') {
2011-04-29 08:38:01 +00:00
str = (++ptr) +1;
inv = 128;
esc = 0;
continue;
// reset color
} else
if (ptr[0]=='3' && ptr[2]=='m') {
2011-04-29 08:38:01 +00:00
// TODO: honor inv here
printf ("<font color='%s'>", gethtmlcolor (ptr[1], "#000"));
fflush(stdout);
ptr = ptr + 1;
str = ptr + 2;
esc = 0;
continue;
} else
if (ptr[0]=='4' && ptr[2]=='m') {
2011-04-29 08:38:01 +00:00
// TODO: USE INV HERE
printf ("<font style='background-color:%s'>", gethtmlcolor (ptr[1], "#fff"));
fflush(stdout);
}
}
len++;
}
write (1, str, ptr-str);
return len;
}