Do more R2_600 pending changes

This commit is contained in:
pancake 2024-11-22 16:44:44 +01:00
parent 89ba6ec0bc
commit dd22e8b01f
12 changed files with 302 additions and 310 deletions

View File

@ -4446,8 +4446,7 @@ static void nextword(RCore *core, RAGraph *g, const char *word) {
} }
} }
// R2_600 return bool R_API bool r_core_visual_graph(RCore *core, RAGraph *g, RAnalFunction *_fcn, int mode) {
R_API int r_core_visual_graph(RCore *core, RAGraph *g, RAnalFunction *_fcn, int mode) {
bool is_interactive = (mode != 0); bool is_interactive = (mode != 0);
if (is_interactive && !r_cons_is_interactive ()) { if (is_interactive && !r_cons_is_interactive ()) {
R_LOG_ERROR ("Interactive graph mode requires 'e scr.interactive=true'"); R_LOG_ERROR ("Interactive graph mode requires 'e scr.interactive=true'");
@ -5339,7 +5338,7 @@ R_API int r_core_visual_graph(RCore *core, RAGraph *g, RAnalFunction *_fcn, int
r_config_hold_restore (hc); r_config_hold_restore (hc);
r_config_hold_free (hc); r_config_hold_free (hc);
if (must_update_seek) { if (must_update_seek) {
return -1; return true; // -1
} }
return !is_error; return !is_error;
} }

View File

@ -2306,84 +2306,6 @@ R_API int r_core_print_bb_custom(RCore *core, RAnalFunction *fcn) {
return true; return true;
} }
// R2_600 - return bool
R_API int r_core_print_bb_gml(RCore *core, RAnalFunction *fcn) {
RAnalBlock *bb;
RListIter *iter;
if (!fcn) {
return false;
}
int id = 0;
HtUU *ht = ht_uu_new0 ();
r_cons_printf ("graph\n[\n" "hierarchic 1\n" "label \"\"\n" "directed 1\n");
r_list_foreach (fcn->bbs, iter, bb) {
RFlagItem *flag = r_flag_get_i (core->flags, bb->addr);
char *msg = flag? strdup (flag->name): r_str_newf ("0x%08"PFMT64x, bb->addr);
// TODO char *str = r_str_escape_dot (msg);
ht_uu_insert (ht, bb->addr, id);
r_cons_printf (" node [\n"
" id %d\n"
" label \"%s\"\n"
" ]\n", id, msg);
id++;
free (msg);
}
r_list_foreach (fcn->bbs, iter, bb) {
if (bb->addr == UT64_MAX) {
continue;
}
if (bb->jump != UT64_MAX) {
bool found;
int i = ht_uu_find (ht, bb->addr, &found);
if (found) {
int i2 = ht_uu_find (ht, bb->jump, &found);
if (found) {
r_cons_printf (" edge [\n"
" source %d\n"
" target %d\n"
" ]\n", i, i2);
}
}
}
if (bb->fail != UT64_MAX) {
bool found;
int i = ht_uu_find (ht, bb->addr, &found);
if (found) {
int i2 = ht_uu_find (ht, bb->fail, &found);
if (found) {
r_cons_printf (" edge [\n"
" source %d\n"
" target %d\n"
" ]\n", i, i2);
}
}
}
if (bb->switch_op) {
RListIter *it;
RAnalCaseOp *cop;
r_list_foreach (bb->switch_op->cases, it, cop) {
bool found;
int i = ht_uu_find (ht, bb->addr, &found);
if (found) {
int i2 = ht_uu_find (ht, cop->addr, &found);
if (found) {
r_cons_printf (" edge [\n"
" source %d\n"
" target %d\n"
" ]\n", i, i2);
}
}
}
}
}
r_cons_printf ("]\n");
ht_uu_free (ht);
return true;
}
R_API void r_core_anal_datarefs(RCore *core, ut64 addr) { R_API void r_core_anal_datarefs(RCore *core, ut64 addr) {
RAnalFunction *fcn = r_anal_get_fcn_in (core->anal, addr, -1); RAnalFunction *fcn = r_anal_get_fcn_in (core->anal, addr, -1);
if (fcn) { if (fcn) {

View File

@ -12204,6 +12204,83 @@ static void r_core_graph_print(RCore *core, RGraph /*<RGraphNodeInfo>*/ *graph,
} }
} }
static bool r_core_print_bb_gml(RCore *core, RAnalFunction *fcn) {
RAnalBlock *bb;
RListIter *iter;
if (!fcn) {
return false;
}
int id = 0;
HtUU *ht = ht_uu_new0 ();
r_cons_printf ("graph\n[\n" "hierarchic 1\n" "label \"\"\n" "directed 1\n");
r_list_foreach (fcn->bbs, iter, bb) {
RFlagItem *flag = r_flag_get_i (core->flags, bb->addr);
char *msg = flag? strdup (flag->name): r_str_newf ("0x%08"PFMT64x, bb->addr);
// TODO char *str = r_str_escape_dot (msg);
ht_uu_insert (ht, bb->addr, id);
r_cons_printf (" node [\n"
" id %d\n"
" label \"%s\"\n"
" ]\n", id, msg);
id++;
free (msg);
}
r_list_foreach (fcn->bbs, iter, bb) {
if (bb->addr == UT64_MAX) {
continue;
}
if (bb->jump != UT64_MAX) {
bool found;
int i = ht_uu_find (ht, bb->addr, &found);
if (found) {
int i2 = ht_uu_find (ht, bb->jump, &found);
if (found) {
r_cons_printf (" edge [\n"
" source %d\n"
" target %d\n"
" ]\n", i, i2);
}
}
}
if (bb->fail != UT64_MAX) {
bool found;
int i = ht_uu_find (ht, bb->addr, &found);
if (found) {
int i2 = ht_uu_find (ht, bb->fail, &found);
if (found) {
r_cons_printf (" edge [\n"
" source %d\n"
" target %d\n"
" ]\n", i, i2);
}
}
}
if (bb->switch_op) {
RListIter *it;
RAnalCaseOp *cop;
r_list_foreach (bb->switch_op->cases, it, cop) {
bool found;
int i = ht_uu_find (ht, bb->addr, &found);
if (found) {
int i2 = ht_uu_find (ht, cop->addr, &found);
if (found) {
r_cons_printf (" edge [\n"
" source %d\n"
" target %d\n"
" ]\n", i, i2);
}
}
}
}
}
r_cons_printf ("]\n");
ht_uu_free (ht);
return true;
}
static inline bool mermaid_add_node_asm(RAnal *a, RAnalBlock *bb, RStrBuf *nodes) { static inline bool mermaid_add_node_asm(RAnal *a, RAnalBlock *bb, RStrBuf *nodes) {
ut8 *bb_buf = calloc (1, bb->size); ut8 *bb_buf = calloc (1, bb->size);
if (!bb_buf) { if (!bb_buf) {

View File

@ -225,34 +225,35 @@ static bool get_keys(void *keylist_in, const void *k, const void *v) {
} }
R_API const char **r_cmd_alias_keys(RCmd *cmd) { R_API const char **r_cmd_alias_keys(RCmd *cmd) {
AliasKeylist keylist; AliasKeylist keylist = {
.current_key = 0,
keylist.keys = R_NEWS (const char *, cmd->aliases->count); .keys = R_NEWS (const char *, cmd->aliases->count)
};
if (!keylist.keys) { if (!keylist.keys) {
return NULL; return NULL;
} }
keylist.current_key = 0;
ht_pp_foreach (cmd->aliases, get_keys, &keylist); ht_pp_foreach (cmd->aliases, get_keys, &keylist);
// We don't need to return a count - it's already in cmd->aliases. // We don't need to return a count - it's already in cmd->aliases.
return keylist.keys; return keylist.keys;
} }
R_API void r_cmd_alias_free(RCmd *cmd) { R_API void r_cmd_alias_free(RCmd *cmd) {
R_RETURN_IF_FAIL (cmd);
ht_pp_free (cmd->aliases); ht_pp_free (cmd->aliases);
cmd->aliases = NULL; cmd->aliases = NULL;
} }
R_API bool r_cmd_alias_del(RCmd *cmd, const char *k) { R_API bool r_cmd_alias_del(RCmd *cmd, const char *k) {
R_RETURN_VAL_IF_FAIL (cmd && k, false);
return ht_pp_delete (cmd->aliases, k); return ht_pp_delete (cmd->aliases, k);
} }
R_API int r_cmd_alias_set_cmd(RCmd *cmd, const char *k, const char *v) { R_API bool r_cmd_alias_set_cmd(RCmd *cmd, const char *k, const char *v) {
R_RETURN_VAL_IF_FAIL (cmd && k && v, false);
RCmdAliasVal val; RCmdAliasVal val;
val.data = (ut8 *)v; val.data = (ut8 *)v;
if (!val.data) { if (!val.data) {
return 1; return true;
} }
val.sz = strlen (v) + 1; val.sz = strlen (v) + 1;
val.is_str = true; val.is_str = true;
@ -388,32 +389,31 @@ static ut8 *alias_append_internal(int *out_szp, const RCmdAliasVal *first, const
return out; return out;
} }
R_API int r_cmd_alias_append_str(RCmd *cmd, const char *k, const char *a) { R_API bool r_cmd_alias_append_str(RCmd *cmd, const char *k, const char *a) {
R_RETURN_VAL_IF_FAIL (cmd && k && a, 1); R_RETURN_VAL_IF_FAIL (cmd && k && a, 1);
RCmdAliasVal *v_old = r_cmd_alias_get (cmd, k); RCmdAliasVal *v_old = r_cmd_alias_get (cmd, k);
if (v_old) { if (v_old) {
if (!v_old->is_data) { if (!v_old->is_data) {
return 1; return true;
} }
int new_len = 0; int new_len = 0;
ut8* new = alias_append_internal (&new_len, v_old, (ut8 *)a, strlen (a) + 1); ut8* new = alias_append_internal (&new_len, v_old, (ut8 *)a, strlen (a) + 1);
if (!new) { if (!new) {
return 1; return true;
} }
r_cmd_alias_set_raw (cmd, k, new, new_len); r_cmd_alias_set_raw (cmd, k, new, new_len);
free (new); free (new);
} else { } else {
r_cmd_alias_set_str (cmd, k, a); r_cmd_alias_set_str (cmd, k, a);
} }
return 0; return false;
} }
// R2_600 - return bool instead R_API bool r_cmd_alias_append_raw(RCmd *cmd, const char *k, const ut8 *a, int sz) {
R_API int r_cmd_alias_append_raw(RCmd *cmd, const char *k, const ut8 *a, int sz) {
RCmdAliasVal *v_old = r_cmd_alias_get (cmd, k); RCmdAliasVal *v_old = r_cmd_alias_get (cmd, k);
if (v_old) { if (v_old) {
if (!v_old->is_data) { if (!v_old->is_data) {
return 0; return false;
} }
int new_len = 0; int new_len = 0;
ut8 *new = alias_append_internal (&new_len, v_old, a, sz); ut8 *new = alias_append_internal (&new_len, v_old, a, sz);

View File

@ -42,200 +42,6 @@ static bool is_document(const char *name) {
return r_str_endswith (name, ".r2s") || r_str_endswith (name, ".md") || r_str_endswith (name, ".txt"); return r_str_endswith (name, ".r2s") || r_str_endswith (name, ".md") || r_str_endswith (name, ".txt");
} }
static void fill_line(RStrBuf *sb, int maxcol) {
int i;
if (maxcol < 1) {
return;
}
for (i = 0; i < maxcol; i++) {
r_strbuf_append (sb, " ");
}
r_strbuf_append (sb, Color_RESET_BG);
r_strbuf_append (sb, Color_RESET);
r_strbuf_append (sb, "\n");
}
// R2_600 - Rename to RStr.md2txt ?
static char *unmarkdown(const char *page, bool usecolor) {
char *b = r_file_slurp (page, NULL);
RStrBuf *sb = r_strbuf_new ("");
int col = 0;
const int maxcol = 75;
bool codeblock = false;
bool contline = false;
bool title = false;
bool codeblockline = false;
while (*b) {
int ch = *b;
repeat:
switch (ch) {
case 10:
if (codeblock || title) {
const int j = title? maxcol + 2: maxcol - 4;
if (usecolor) {
if (!contline) {
fill_line (sb, j - col);
}
if (title) {
r_strbuf_append (sb, Color_BLACK);
r_strbuf_append (sb, Color_BGBLUE);
fill_line (sb, maxcol + 4);
}
}
title = false;
}
if (contline) {
contline = false;
} else {
col = 0;
}
if (usecolor) {
r_strbuf_append (sb, Color_RESET);
}
if (!codeblock) {
r_strbuf_append (sb, "\n");
}
if (codeblockline) {
codeblock = false;
codeblockline = false;
}
break;
case '\t':
if (col == 0) {
codeblock = true;
codeblockline = true;
} else {
r_strbuf_append (sb, " ");
}
break;
case 13:
// ignore
break;
default:
if (col > maxcol) {
ch = 10;
if (*b == ' ') {
b++;
} else {
if (codeblock) {
col = 1;
// nothing
} else {
r_strbuf_append (sb, "-");
}
#if 0
contline = true;
if (codeblock) {
r_strbuf_append (sb, "\n");
col = 0;
}
#endif
}
b--;
goto repeat;
}
if (col == 0) {
if (r_str_startswith (b, "```")) {
while (*b && *b != '\n') {
b++;
}
codeblock = !codeblock;
if (!codeblock) {
r_strbuf_append (sb, Color_RESET_BG);
}
continue;
} else if (!codeblock && r_str_startswith (b, "###")) {
if (usecolor) {
r_strbuf_append (sb, Color_BLACK);
r_strbuf_append (sb, Color_BGBLUE);
fill_line (sb, maxcol + 4);
r_strbuf_append (sb, Color_BLUE);
r_strbuf_append (sb, Color_BGCYAN);
}
r_strbuf_append (sb, " ");
b += 3;
title = true;
} else if (!codeblock && r_str_startswith (b, "##")) {
if (usecolor) {
r_strbuf_append (sb, Color_BLACK);
r_strbuf_append (sb, Color_BGBLUE);
fill_line (sb, maxcol + 4);
r_strbuf_append (sb, Color_BLACK);
r_strbuf_append (sb, Color_BGBLUE);
}
r_strbuf_append (sb, " ");
ch = ' ';
b += 2;
title = true;
} else if (!codeblock && r_str_startswith (b, "#")) {
RStrBuf *sb2 = r_strbuf_new ("");
while (*b) {
if (*b == '\n') {
b++;
break;
}
r_strbuf_appendf (sb2, "%c", *b);
b++;
}
char *sb2s = r_strbuf_drain (sb2);
char *sb2ss = r_str_ss (sb2s, 0, 0);
char *p = sb2ss;
char *nextlist = strstr (p, "\n");
if (usecolor) {
r_strbuf_append (sb, Color_BLACK);
r_strbuf_append (sb, Color_BGGREEN);
}
while (nextlist) {
char *line = r_str_ndup (p, nextlist - p);
r_strbuf_appendf (sb, "%s", line);
int col = strlen (line);
int i;
for (i = col; i < maxcol + 1; i++) {
r_strbuf_append (sb, " ");
}
if (usecolor) {
r_strbuf_append (sb, " ");
r_strbuf_append (sb, " "Color_RESET_BG""Color_RESET"\n"Color_BGGREEN""Color_BLACK);
} else {
r_strbuf_append (sb, " \n");
}
p = nextlist + 1;
nextlist = strstr (p, "\n");
}
//r_strbuf_append (sb, sb2ss);
free (sb2ss);
free (sb2s);
if (usecolor) {
r_strbuf_append (sb, Color_RESET_BG""Color_RESET"\n");
} else {
r_strbuf_append (sb, "\n");
}
title = false;
break;
} else {
if (codeblock) {
if (usecolor) {
r_strbuf_append (sb, " "Color_BGYELLOW" "Color_BLACK);
} else {
r_strbuf_append (sb, " ");
}
} else {
r_strbuf_append (sb, " ");
}
}
}
col ++;
r_strbuf_appendf (sb, "%c", ch);
break;
}
b++;
}
char *s = r_strbuf_drain (sb);
r_cons_printf ("%s", s);
free (s);
return NULL;
}
static char *readman(RCore *core, const char *page) { static char *readman(RCore *core, const char *page) {
const char *docdir = R2_DATDIR"/doc/radare2/"; const char *docdir = R2_DATDIR"/doc/radare2/";
if (!strcmp (page, "?")) { if (!strcmp (page, "?")) {
@ -268,7 +74,8 @@ static char *readman(RCore *core, const char *page) {
return NULL; return NULL;
} }
if (r_str_endswith (page, ".md")) { if (r_str_endswith (page, ".md")) {
char *data = unmarkdown (n, r_config_get_i (core->config, "scr.color") > 0); const bool use_color = r_config_get_i (core->config, "scr.color") > 0;
char *data = r_str_md2txt (n, use_color);
free (n); free (n);
return data; return data;
} }

View File

@ -330,9 +330,8 @@ R_API char *r_core_cmd_call_str_at(RCore *core, ut64 addr, const char *cmd) {
return retstr; return retstr;
} }
// R2_600 - return void R_API void r_core_bind(RCore *core, RCoreBind *bnd) {
R_API int r_core_bind(RCore *core, RCoreBind *bnd) { R_RETURN_IF_FAIL (core && bnd);
R_RETURN_VAL_IF_FAIL (core && bnd, false);
bnd->core = core; bnd->core = core;
bnd->bphit = (RCoreDebugBpHit)r_core_debug_breakpoint_hit; bnd->bphit = (RCoreDebugBpHit)r_core_debug_breakpoint_hit;
bnd->syshit = (RCoreDebugSyscallHit)r_core_debug_syscall_hit; bnd->syshit = (RCoreDebugSyscallHit)r_core_debug_syscall_hit;
@ -353,7 +352,6 @@ R_API int r_core_bind(RCore *core, RCoreBind *bnd) {
bnd->isMapped = (RCoreIsMapped)__isMapped; bnd->isMapped = (RCoreIsMapped)__isMapped;
bnd->syncDebugMaps = (RCoreDebugMapsSync)__syncDebugMaps; bnd->syncDebugMaps = (RCoreDebugMapsSync)__syncDebugMaps;
bnd->pjWithEncoding = (RCorePJWithEncoding)r_core_pj_new; bnd->pjWithEncoding = (RCorePJWithEncoding)r_core_pj_new;
return true;
} }
R_API RCore *r_core_ncast(ut64 p) { R_API RCore *r_core_ncast(ut64 p) {

View File

@ -318,8 +318,8 @@ R_API bool r_core_hack(RCore *core, const char *op) {
if (core->blocksize < 4) { if (core->blocksize < 4) {
return false; return false;
} }
#if R2_600 #if 0
// R2_590 TODO: call RArch.patch() if available, otherwise just do this hack until all anal plugs are moved to arch // R2_600 TODO: call RArch.patch() if available, otherwise just do this hack until all anal plugs are moved to arch
// r_arch_patch (aop, 0); // r_arch_patch (aop, 0);
RArchSession *acur = R_UNWRAP3 (core, rasm, acur); RArchSession *acur = R_UNWRAP3 (core, rasm, acur);
if (acur && acur->plugin->patch) { if (acur && acur->plugin->patch) {

View File

@ -101,14 +101,13 @@ static bool __core_patch_bracket(RCore *core, const char *str, ut64 *noff) {
return true; return true;
} }
// R2_600 - return boolean R_API bool r_core_patch(RCore *core, const char *patch) {
R_API int r_core_patch(RCore *core, const char *patch) {
char *p, *p0, *str; char *p, *p0, *str;
ut64 noff = 0LL; ut64 noff = 0LL;
p = p0 = str = strdup (patch); p = p0 = str = strdup (patch);
if (!p) { if (!p) {
return 0; return false;
} }
for (; *p; p++) { for (; *p; p++) {
/* read until newline */ /* read until newline */
@ -144,5 +143,6 @@ R_API int r_core_patch(RCore *core, const char *patch) {
str = p; str = p;
} }
free (p0); free (p0);
return 0; // TODO do some minimum error checking
return true;
} }

View File

@ -278,12 +278,12 @@ R_API int r_cmd_macro_break(RCmdMacro *mac, const char *value);
R_API bool r_cmd_alias_del(RCmd *cmd, const char *k); R_API bool r_cmd_alias_del(RCmd *cmd, const char *k);
R_API const char **r_cmd_alias_keys(RCmd *cmd); R_API const char **r_cmd_alias_keys(RCmd *cmd);
R_API int r_cmd_alias_set_cmd(RCmd *cmd, const char *k, const char *v); R_API bool r_cmd_alias_set_cmd(RCmd *cmd, const char *k, const char *v);
R_API int r_cmd_alias_set_str(RCmd *cmd, const char *k, const char *v); R_API int r_cmd_alias_set_str(RCmd *cmd, const char *k, const char *v);
R_API int r_cmd_alias_set_raw(RCmd *cmd, const char *k, const ut8 *v, int sz); R_API int r_cmd_alias_set_raw(RCmd *cmd, const char *k, const ut8 *v, int sz);
R_API RCmdAliasVal *r_cmd_alias_get(RCmd *cmd, const char *k); R_API RCmdAliasVal *r_cmd_alias_get(RCmd *cmd, const char *k);
R_API int r_cmd_alias_append_str(RCmd *cmd, const char *k, const char *a); R_API bool r_cmd_alias_append_str(RCmd *cmd, const char *k, const char *a);
R_API int r_cmd_alias_append_raw(RCmd *cmd, const char *k, const ut8 *a, int sz); R_API bool r_cmd_alias_append_raw(RCmd *cmd, const char *k, const ut8 *a, int sz);
R_API char *r_cmd_alias_val_strdup(RCmdAliasVal *v); R_API char *r_cmd_alias_val_strdup(RCmdAliasVal *v);
R_API char *r_cmd_alias_val_strdup_b64(RCmdAliasVal *v); R_API char *r_cmd_alias_val_strdup_b64(RCmdAliasVal *v);
R_API void r_cmd_alias_free(RCmd *cmd); R_API void r_cmd_alias_free(RCmd *cmd);

View File

@ -437,8 +437,7 @@ typedef struct r_core_item_t {
R_API RCoreItem *r_core_item_at(RCore *core, ut64 addr); R_API RCoreItem *r_core_item_at(RCore *core, ut64 addr);
R_API void r_core_item_free(RCoreItem *ci); R_API void r_core_item_free(RCoreItem *ci);
R_API void r_core_bind(RCore *core, RCoreBind *bnd);
R_API int r_core_bind(RCore *core, RCoreBind *bnd);
typedef struct r_core_cmpwatch_t { typedef struct r_core_cmpwatch_t {
ut64 addr; ut64 addr;
@ -549,7 +548,7 @@ R_API int r_core_visual_anal_classes(RCore *core);
R_API int r_core_visual_types(RCore *core); R_API int r_core_visual_types(RCore *core);
R_API int r_core_visual(RCore *core, const char *input); R_API int r_core_visual(RCore *core, const char *input);
R_API void r_core_visual_find(RCore *core, RAGraph *g); R_API void r_core_visual_find(RCore *core, RAGraph *g);
R_API int r_core_visual_graph(RCore *core, RAGraph *g, RAnalFunction *_fcn, int mode); R_API bool r_core_visual_graph(RCore *core, RAGraph *g, RAnalFunction *_fcn, int mode);
R_API void r_core_visual_browse(RCore *core, const char *arg); R_API void r_core_visual_browse(RCore *core, const char *arg);
R_API int r_core_visual_cmd(RCore *core, const char *arg); R_API int r_core_visual_cmd(RCore *core, const char *arg);
R_API void r_core_visual_seek_animation(RCore *core, ut64 addr); R_API void r_core_visual_seek_animation(RCore *core, ut64 addr);
@ -697,7 +696,6 @@ R_API ut64 r_core_anal_fcn_list_size(RCore *core);
R_API void r_core_anal_fcn_labels(RCore *core, RAnalFunction *fcn, int rad); R_API void r_core_anal_fcn_labels(RCore *core, RAnalFunction *fcn, int rad);
R_API int r_core_anal_fcn_clean(RCore *core, ut64 addr); R_API int r_core_anal_fcn_clean(RCore *core, ut64 addr);
R_API int r_core_print_bb_custom(RCore *core, RAnalFunction *fcn); R_API int r_core_print_bb_custom(RCore *core, RAnalFunction *fcn);
R_API int r_core_print_bb_gml(RCore *core, RAnalFunction *fcn);
R_API int r_core_anal_graph(RCore *core, ut64 addr, int opts); R_API int r_core_anal_graph(RCore *core, ut64 addr, int opts);
R_API int r_core_anal_graph_fcn(RCore *core, char *input, int opts); R_API int r_core_anal_graph_fcn(RCore *core, char *input, int opts);
R_API RList* r_core_anal_graph_to(RCore *core, ut64 addr, int n); R_API RList* r_core_anal_graph_to(RCore *core, ut64 addr, int n);
@ -884,7 +882,7 @@ R_API int r_core_search_preludes(RCore *core, bool log);
R_API int r_core_search_prelude(RCore *core, ut64 from, ut64 to, const ut8 *buf, int blen, const ut8 *mask, int mlen); R_API int r_core_search_prelude(RCore *core, ut64 from, ut64 to, const ut8 *buf, int blen, const ut8 *mask, int mlen);
R_API RList* /*<RIOMap*>*/ r_core_get_boundaries_prot(RCore *core, int protection, const char *mode, const char *prefix); R_API RList* /*<RIOMap*>*/ r_core_get_boundaries_prot(RCore *core, int protection, const char *mode, const char *prefix);
R_API int r_core_patch(RCore *core, const char *patch); R_API bool r_core_patch(RCore *core, const char *patch);
R_API bool r_core_hack(RCore *core, const char *op); R_API bool r_core_hack(RCore *core, const char *op);
R_API bool r_core_dump(RCore *core, const char *file, ut64 addr, ut64 size, int append); R_API bool r_core_dump(RCore *core, const char *file, ut64 addr, ut64 size, int append);

View File

@ -183,6 +183,7 @@ R_API char *r_str_word_get_first(const char *string);
R_API void r_str_trim(char *str); R_API void r_str_trim(char *str);
R_API void r_str_trim_emptylines(char *str); R_API void r_str_trim_emptylines(char *str);
R_API int r_str_ntrim(char *str, int n); R_API int r_str_ntrim(char *str, int n);
R_API char *r_str_md2txt(const char *page, bool usecolor);
R_API char *r_str_wrap(const char *str, int w); R_API char *r_str_wrap(const char *str, int w);
R_API char *r_str_trim_dup(const char *str); R_API char *r_str_trim_dup(const char *str);
R_API char *r_str_trim_ndup(const char *str, size_t n); R_API char *r_str_trim_ndup(const char *str, size_t n);

View File

@ -4181,3 +4181,193 @@ R_API R_MUSTUSE char *r_str_after(char *s, char c) {
} }
return NULL; return NULL;
} }
static void fill_line(RStrBuf *sb, int maxcol) {
int i;
if (maxcol < 1) {
return;
}
for (i = 0; i < maxcol; i++) {
r_strbuf_append (sb, " ");
}
r_strbuf_append (sb, Color_RESET_BG);
r_strbuf_append (sb, Color_RESET);
r_strbuf_append (sb, "\n");
}
R_API char *r_str_md2txt(const char *page, bool usecolor) {
char *b = r_file_slurp (page, NULL);
RStrBuf *sb = r_strbuf_new ("");
int col = 0;
const int maxcol = 75;
bool codeblock = false;
bool contline = false;
bool title = false;
bool codeblockline = false;
while (*b) {
int ch = *b;
repeat:
switch (ch) {
case 10:
if (codeblock || title) {
const int j = title? maxcol + 2: maxcol - 4;
if (usecolor) {
if (!contline) {
fill_line (sb, j - col);
}
if (title) {
r_strbuf_append (sb, Color_BLACK);
r_strbuf_append (sb, Color_BGBLUE);
fill_line (sb, maxcol + 4);
}
}
title = false;
}
if (contline) {
contline = false;
} else {
col = 0;
}
if (usecolor) {
r_strbuf_append (sb, Color_RESET);
}
if (!codeblock) {
r_strbuf_append (sb, "\n");
}
if (codeblockline) {
codeblock = false;
codeblockline = false;
}
break;
case '\t':
if (col == 0) {
codeblock = true;
codeblockline = true;
} else {
r_strbuf_append (sb, " ");
}
break;
case 13:
// ignore
break;
default:
if (col > maxcol) {
ch = 10;
if (*b == ' ') {
b++;
} else {
if (codeblock) {
col = 1;
// nothing
} else {
r_strbuf_append (sb, "-");
}
#if 0
contline = true;
if (codeblock) {
r_strbuf_append (sb, "\n");
col = 0;
}
#endif
}
b--;
goto repeat;
}
if (col == 0) {
if (r_str_startswith (b, "```")) {
while (*b && *b != '\n') {
b++;
}
codeblock = !codeblock;
if (!codeblock) {
r_strbuf_append (sb, Color_RESET_BG);
}
continue;
} else if (!codeblock && r_str_startswith (b, "###")) {
if (usecolor) {
r_strbuf_append (sb, Color_BLACK);
r_strbuf_append (sb, Color_BGBLUE);
fill_line (sb, maxcol + 4);
r_strbuf_append (sb, Color_BLUE);
r_strbuf_append (sb, Color_BGCYAN);
}
r_strbuf_append (sb, " ");
b += 3;
title = true;
} else if (!codeblock && r_str_startswith (b, "##")) {
if (usecolor) {
r_strbuf_append (sb, Color_BLACK);
r_strbuf_append (sb, Color_BGBLUE);
fill_line (sb, maxcol + 4);
r_strbuf_append (sb, Color_BLACK);
r_strbuf_append (sb, Color_BGBLUE);
}
r_strbuf_append (sb, " ");
ch = ' ';
b += 2;
title = true;
} else if (!codeblock && r_str_startswith (b, "#")) {
RStrBuf *sb2 = r_strbuf_new ("");
while (*b) {
if (*b == '\n') {
b++;
break;
}
r_strbuf_appendf (sb2, "%c", *b);
b++;
}
char *sb2s = r_strbuf_drain (sb2);
char *sb2ss = r_str_ss (sb2s, 0, 0);
char *p = sb2ss;
char *nextlist = strstr (p, "\n");
if (usecolor) {
r_strbuf_append (sb, Color_BLACK);
r_strbuf_append (sb, Color_BGGREEN);
}
while (nextlist) {
char *line = r_str_ndup (p, nextlist - p);
r_strbuf_appendf (sb, "%s", line);
int col = strlen (line);
int i;
for (i = col; i < maxcol + 1; i++) {
r_strbuf_append (sb, " ");
}
if (usecolor) {
r_strbuf_append (sb, " ");
r_strbuf_append (sb, " "Color_RESET_BG""Color_RESET"\n"Color_BGGREEN""Color_BLACK);
} else {
r_strbuf_append (sb, " \n");
}
p = nextlist + 1;
nextlist = strstr (p, "\n");
}
//r_strbuf_append (sb, sb2ss);
free (sb2ss);
free (sb2s);
if (usecolor) {
r_strbuf_append (sb, Color_RESET_BG""Color_RESET"\n");
} else {
r_strbuf_append (sb, "\n");
}
title = false;
break;
} else {
if (codeblock) {
if (usecolor) {
r_strbuf_append (sb, " "Color_BGYELLOW" "Color_BLACK);
} else {
r_strbuf_append (sb, " ");
}
} else {
r_strbuf_append (sb, " ");
}
}
}
col ++;
r_strbuf_appendf (sb, "%c", ch);
break;
}
b++;
}
return r_strbuf_drain (sb);
}