diff --git a/libr/cons/grep.c b/libr/cons/grep.c index 30543edd62d8a..d3cd7bd6356ba 100644 --- a/libr/cons/grep.c +++ b/libr/cons/grep.c @@ -3,6 +3,7 @@ #include #include #include +#include #include // R2R db/cmd/cons_grep @@ -44,6 +45,7 @@ static RCoreHelpMessage help_detail_tilde = { " ...", "", "internal 'hud' (like V_)", " ....", "", "internal 'hud' in one line", " :)", "", "parse C-like output from decompiler", + " :))", "", "code syntax highlight", " <50", "", "perform zoom to the given text width on the buffer", " <>", "", "xml indentation", " {:", "", "human friendly indentation (yes, it's a smiley)", @@ -136,6 +138,11 @@ R_API void r_cons_grep_expression(const char *str) { switch (*ptr) { case ':': if (ptr[1] == ')') { // ":)" + if (ptr[2] == ')') { // ":))" + // R2_600 - add grep->colorcode option + grep->sort = -123; + ptr++; + } grep->code = true; ptr++; } @@ -567,6 +574,135 @@ static inline ut64 cmpstrings(const void *a) { return r_str_hash64 (a); } +static char *colorword(char *res, const char *k, const char *color) { + char *tv = r_str_newf ("~~[%s]~~", k); + r_str_case (tv, true); + char *nv = r_str_newf ("%s%s"Color_RESET, color, k); + res = r_str_replace_all (res, k, tv); + res = r_str_replace_all (res, tv, nv); + free (nv); + free (tv); + return res; +} + +static void colorcode(void) { + RCons *cons = r_cons_singleton (); + int i; + char *res = r_str_ndup (cons->context->buffer, cons->context->buffer_len); + if (res) { + bool linecomment = false; + bool comment = false; + bool string = false; + RStrBuf *sb = r_strbuf_new (""); + for (i = 0; res[i]; i++) { + const char ch = res[i]; + const char ch2 = res[i + 1]; + if (linecomment) { + if (ch == '\n') { + r_strbuf_append (sb, Color_RESET); + r_strbuf_append_n (sb, &ch, 1); + linecomment = false; + } else { + r_strbuf_append_n (sb, &ch, 1); + } + } else if (comment) { + if (ch == '*' && res[i + 1] == '/') { + r_strbuf_append_n (sb, &ch, 1); + r_strbuf_append_n (sb, &ch2, 1); + r_strbuf_append (sb, Color_RESET); + comment = false; + i++; + } else { + r_strbuf_append_n (sb, &ch, 1); + } + } else if (string) { + if (ch == '\\') { + if (res[i + 1]) { + r_strbuf_append_n (sb, &ch, 1); + r_strbuf_append_n (sb, &ch2, 1); + i++; + } else { + r_strbuf_append_n (sb, &ch, 1); + } + } else if (ch == '"') { + r_strbuf_append_n (sb, &ch, 1); + r_strbuf_append (sb, Color_RESET); + string = false; + } else { + r_strbuf_append_n (sb, &ch, 1); + } + } else { + if (i == 0 && ch == '#') { + r_strbuf_append (sb, Color_BLUE); + r_strbuf_append_n (sb, &ch, 1); + linecomment = true; + } else if (ch == '\n') { + if (ch2 == '#') { + r_strbuf_append_n (sb, &ch, 1); + r_strbuf_append (sb, Color_BLUE); + r_strbuf_append_n (sb, &ch2, 1); + linecomment = true; + i++; + i++; + } else { + r_strbuf_append_n (sb, &ch, 1); + } + } else if (ch == '/') { + if (ch2 == '*') { + comment = true; + r_strbuf_append (sb, Color_BLUE); + r_strbuf_append_n (sb, &ch, 1); + } else if (ch2 == '/') { + linecomment = true; + r_strbuf_append (sb, Color_BLUE); + r_strbuf_append_n (sb, &ch, 1); + } else { + r_strbuf_append_n (sb, &ch, 1); + } + } else if (ch == '"') { + string = true; + r_strbuf_append (sb, Color_RED); + r_strbuf_append_n (sb, &ch, 1); + } else { + r_strbuf_append_n (sb, &ch, 1); + } + } + } + free (res); + res = r_strbuf_drain (sb); + // ugly temporary hack +#if 0 + res = colorword (res, "if ", Color_RED); + res = colorword (res, " else ", Color_RED); +#endif + res = colorword (res, "for ", Color_RED); + res = colorword (res, "while ", Color_RED); + res = colorword (res, "switch ", Color_RED); + res = colorword (res, "static ", Color_RED); + res = colorword (res, "inline ", Color_RED); + // res = colorword (res, " -> ", Color_RED); + res = colorword (res, "return", Color_RED); + res = colorword (res, "string ", Color_RED); + res = colorword (res, "number ", Color_RED); + + res = colorword (res, "void ", Color_GREEN); + res = colorword (res, "bool ", Color_GREEN); + res = colorword (res, "ut64 ", Color_GREEN); + res = colorword (res, "int ", Color_GREEN); + res = colorword (res, "char ", Color_GREEN); + res = colorword (res, "const ", Color_GREEN); +#if 0 + res = colorword (res, "{", Color_YELLOW); + res = colorword (res, "}", Color_YELLOW); +#endif + // bring back the colorized buffer + cons->context->buffer_len = strlen (res); + cons->context->buffer_sz = cons->context->buffer_len; + free (cons->context->buffer); + cons->context->buffer = res; + } +} + R_API void r_cons_grepbuf(void) { RCons *cons = r_cons_singleton (); const char *buf = cons->context->buffer; @@ -580,6 +716,12 @@ R_API void r_cons_grepbuf(void) { R_FREE (cons->context->buffer); return; } + if (grep->sort == -123) { // R2_600 - colorcode + colorcode (); + grep->sort = 0; + grep->code = false; + return; + } if (grep->code) { char *sbuf = r_str_ndup (cons->context->buffer, cons->context->buffer_len); if (sbuf) {