Skip to content

Commit

Permalink
Add graph.edges, bringback the linemode=0 and add the graph+dis mode
Browse files Browse the repository at this point in the history
  • Loading branch information
radare committed Dec 29, 2017
1 parent 252ee30 commit b49314a
Show file tree
Hide file tree
Showing 5 changed files with 145 additions and 49 deletions.
3 changes: 1 addition & 2 deletions libr/cons/canvas.c
Expand Up @@ -435,11 +435,10 @@ R_API void r_cons_canvas_box(RConsCanvas *c, int x, int y, int w, int h, const c

R_API void r_cons_canvas_fill(RConsCanvas *c, int x, int y, int w, int h, char ch, int replace) {
int i;
char *row = NULL;
if (w < 0) {
return;
}
row = malloc (w + 1);
char *row = malloc (w + 1);
if (!row) {
return;
}
Expand Down
64 changes: 44 additions & 20 deletions libr/cons/canvas_line.c
Expand Up @@ -76,51 +76,68 @@ static void apply_line_style(RConsCanvas *c, int x, int y, int x2, int y2,
}
}

R_API void r_cons_canvas_line_diagonal (RConsCanvas *c, int x, int y, int x2, int y2,
RCanvasLineStyle *style) {
apply_line_style(c,x,y,x2,y2,style, 1);
if(y2<y){
R_API void r_cons_canvas_line_diagonal (RConsCanvas *c, int x, int y, int x2, int y2, RCanvasLineStyle *style) {
if (x == x2 || y == y2) {
r_cons_canvas_line_square (c, x, y +1, x2, y2, style);
return;
}
apply_line_style (c, x, y, x2, y2, style, 1);
if (y2 < y) {
int tmp = y2;
y2=y;
y2 = y;
y=tmp;
tmp=x2;
x2=x;
x=tmp;
}
char chizzle[2] = {0}; // = '.';//my nizzle
int dx = abs(x2-x);
int dy = abs(y2-y);
int sx = x<x2 ? 1 : -1;
int sy = y<y2 ? 1 : -1;
int err = (dx>dy?dx:-dy)/2;
// destination
int dx = abs (x2-x);
int dy = abs (y2-y);

This comment has been minimized.

Copy link
@radare

radare May 2, 2018

Author Collaborator

use tabs

This comment has been minimized.

Copy link
@radare

radare May 2, 2018

Author Collaborator

spaces around -

// source
int sx = (x < x2) ? 1 : -1;
int sy = (y < y2) ? 1 : -1;

int err = (dx > (dy?dx:-dy)) / 2;
int e2;

// TODO: find if there's any collision in this line
loop:
e2 = err;
if (e2>-dx) {
*chizzle='_';
err-=dy;
if (e2 > -dx) {
*chizzle = '_';
err -= dy;
x+=sx;
}
if (e2<dy) {
*chizzle='|';
err+=dx;
y+=sy;
err += dx;
y += sy;
}
if ((e2<dy) && (e2>-dx)) {
if (sy > 0){
if ((e2 < dy) && (e2 > -dx)) {
if (sy > 0) {
*chizzle = (sx > 0)?'\\':'/';
} else {
*chizzle = (sx > 0)?'/':'\\';
}
}
if (!(x == x2 && y == y2)) {
int i = (*chizzle=='_'&&sy<0) ? 1 : 0;
if(G(x,y-i)) {
int i = (*chizzle == '_' && sy < 0) ? 1 : 0;
if (G(x, y - i)) {
W(chizzle);
}
goto loop;
}
if (dx) {
if ((dx / dy) < 1) {
if (G(x, y)) {
W("|");
}
}
if (G(x, y + 1)) {
W("|");
}
}
c->attr = Color_RESET;
}

Expand Down Expand Up @@ -330,8 +347,11 @@ R_API void r_cons_canvas_line_square (RConsCanvas *c, int x, int y, int x2, int
c->attr = Color_RESET;
}


R_API void r_cons_canvas_line_square_defined (RConsCanvas *c, int x, int y, int x2, int y2, RCanvasLineStyle *style, int bendpoint, int isvert) {
if (!c->linemode) {
r_cons_canvas_line (c, x, y, x2, y2, style);
return;
}
int min_x = R_MIN (x, x2);
int diff_x = R_ABS (x - x2);
int diff_y = R_ABS (y - y2);
Expand Down Expand Up @@ -381,6 +401,10 @@ R_API void r_cons_canvas_line_square_defined (RConsCanvas *c, int x, int y, int
}

R_API void r_cons_canvas_line_back_edge (RConsCanvas *c, int x, int y, int x2, int y2, RCanvasLineStyle *style, int ybendpoint1, int xbendpoint, int ybendpoint2, int isvert) {
if (!c->linemode) {
r_cons_canvas_line (c, x, y, x2, y2, style);
return;
}
int min_x1 = R_MIN (x, xbendpoint);
int min_x2 = R_MIN (x2, xbendpoint);

Expand Down
1 change: 1 addition & 0 deletions libr/core/cconfig.c
Expand Up @@ -2623,6 +2623,7 @@ R_API int r_core_config_init(RCore *core) {
SETPREF ("graph.cmtright", "false", "Show comments at right");
SETPREF ("graph.format", "dot", "Specify output format for graphs (dot, gml, gmlfcn)");
SETPREF ("graph.refs", "false", "Graph references in callgraphs (.agc*;aggi)");
SETI ("graph.edges", 2, "0=no edges, 1=simple edges, 2=avoid collisions");
SETI ("graph.layout", 0, "Graph layout (0=vertical, 1=horizontal)");
SETI ("graph.linemode", 1, "Graph edges (0=diagonal, 1=square)");
SETPREF ("graph.font", "Courier", "Font for dot graphs");
Expand Down
124 changes: 97 additions & 27 deletions libr/core/graph.c
Expand Up @@ -2566,10 +2566,34 @@ int tmplayercmp (const void *a, const void *b) {
return ((struct tmplayer *)a)->layer > ((struct tmplayer *)b)->layer;
}

static void agraph_print_edges_simple(RAGraph *g) {
RCanvasLineStyle style = {0};
RANode *n, *n2;
RGraphNode *gn, *gn2;
RListIter *iter, *iter2;
const RList *nodes = r_graph_get_nodes (g->graph);
graph_foreach_anode (nodes, iter, gn, n) {
const RList *outnodes = n->gnode->out_nodes;
graph_foreach_anode (outnodes, iter2, gn2, n2) {
// TODO: better alignments here
r_cons_canvas_line (g->can,
n->x + (n->w/2), n->y + n->h,
n2->x + (n2->w/2), n2->y, &style);
}
}
}

static void agraph_print_edges(RAGraph *g) {
if (!g->edgemode) {
return;
}
if (g->edgemode == 1) {
agraph_print_edges_simple (g);
return;
}
int nth;
RListIter *itn, *itm, *ito;
RCanvasLineStyle style;
RCanvasLineStyle style = {0};
const RList *nodes = r_graph_get_nodes (g->graph);
RGraphNode *ga;
RANode *a;
Expand Down Expand Up @@ -3006,10 +3030,28 @@ static int agraph_print(RAGraph *g, int is_interactive, RCore *core, RAnalFuncti
g->can->sx = -g->x;
g->can->sy = -g->y - 1;
}

if (!g->is_tiny) {
if (g->is_dis) {
(void) G (-g->can->sx + 1, -g->can->sy + 2);
int scr_utf8 = r_config_get_i (core->config, "scr.utf8");

This comment has been minimized.

Copy link
@radare

radare May 2, 2018

Author Collaborator

maybe better to use the RConfigHold api instead of doing it by hand

int asm_bytes = r_config_get_i (core->config, "asm.bytes");
int asm_cmtright = r_config_get_i (core->config, "asm.cmtright");
r_config_set_i (core->config, "scr.utf8", 0);
r_config_set_i (core->config, "asm.bytes", 0);
r_config_set_i (core->config, "asm.cmtright", 0);
char *str = r_core_cmd_str (core, "pd $r");
//r_cons_canvas_fill (g->can, -g->can->sx + title_len, -g->can->sy,
// w - title_len, 1, ' ', true);
W(str);
free (str);
r_config_set_i (core->config, "scr.utf8", scr_utf8);
r_config_set_i (core->config, "asm.bytes", asm_bytes);
r_config_set_i (core->config, "asm.cmtright", asm_cmtright);
}

// TODO: add an option/key to toggle this
// if (!g->is_tiny) {
agraph_print_edges (g);
}
// }
if (g->title && *g->title) {
g->can->sy ++;
agraph_print_nodes (g);
Expand Down Expand Up @@ -3077,11 +3119,14 @@ static int agraph_refresh(struct agraph_refresh_data *grd) {
if (!f) {
// r_cons_message ("Not in a function. Type 'df' to define it here");
r_cons_flush ();
if (!r_cons_yesno ('y', "\rNo function at 0x%08"PFMT64x". Define it here (Y/n)? ", core->offset)) {
return 0;
if (!g->is_dis) {
if (!r_cons_yesno ('y', "\rNo function at 0x%08"PFMT64x". Define it here (Y/n)? ", core->offset)) {
return 0;
}
r_core_cmd0 (core, "af");
}
r_core_cmd0 (core, "af");
f = r_anal_get_fcn_in (core->anal, core->offset, 0);
g->need_reload_nodes = true;
}
if (f && f != *fcn) {
*fcn = f;
Expand All @@ -3108,6 +3153,7 @@ static void agraph_init(RAGraph *g) {
g->color_box3 = Color_MAGENTA;
g->graph = r_graph_new ();
g->nodes = sdb_new0 (); // XXX leak
g->edgemode = 2;
g->zoom = ZOOM_DEFAULT;
g->movspeed = DEFAULT_SPEED; // r_config_get_i (g->core->config, "graph.scroll");
g->db = sdb_new0 ();
Expand Down Expand Up @@ -3819,6 +3865,7 @@ R_API int r_core_visual_graph(RCore *core, RAGraph *g, RAnalFunction *_fcn, int
} else {
r_core_cmd0 (core, "ecn");
}
g->edgemode = r_config_get_i (core->config, "graph.edges");
g->color_box = core->cons->pal.graph_box;
g->color_box2 = core->cons->pal.graph_box2;
g->color_box3 = core->cons->pal.graph_box3;
Expand Down Expand Up @@ -3872,6 +3919,9 @@ R_API int r_core_visual_graph(RCore *core, RAGraph *g, RAnalFunction *_fcn, int
}
}
break;
case 'D':
g->is_dis = !g->is_dis;
break;
case 'n':
r_core_seek_next (core, r_config_get (core->config, "scr.nkey"));
break;
Expand All @@ -3886,31 +3936,39 @@ R_API int r_core_visual_graph(RCore *core, RAGraph *g, RAnalFunction *_fcn, int
agraph_toggle_mini (g);
break;
case 'J':
if (okey == 27) { // && r_cons_readchar () == 126) {
// handle page down key
can->sy -= PAGEKEY_SPEED * (invscroll? -1: 1);
if (g->is_dis) {
r_core_cmd0 (core, "so 4");
} else {
RANode *n = get_anode (g->curnode);
if (n) {
if (g->is_tiny) {
n->y++;
} else {
n->y += movspeed;
if (okey == 27) { // && r_cons_readchar () == 126) {
// handle page down key
can->sy -= PAGEKEY_SPEED * (invscroll? -1: 1);
} else {
RANode *n = get_anode (g->curnode);
if (n) {
if (g->is_tiny) {
n->y++;
} else {
n->y += movspeed;
}
}
}
}
break;
case 'K':
if (okey == 27) { // && r_cons_readchar () == 126) {
// handle page up key
can->sy += PAGEKEY_SPEED * (invscroll? -1: 1);
if (g->is_dis) {
r_core_cmd0 (core, "so -4");
} else {
RANode *n = get_anode (g->curnode);
if (n) {
if (g->is_tiny) {
n->y --;
} else {
n->y -= movspeed;
if (okey == 27) { // && r_cons_readchar () == 126) {
// handle page up key
can->sy += PAGEKEY_SPEED * (invscroll? -1: 1);
} else {
RANode *n = get_anode (g->curnode);
if (n) {
if (g->is_tiny) {
n->y --;
} else {
n->y -= movspeed;
}
}
}
}
Expand Down Expand Up @@ -3946,8 +4004,20 @@ R_API int r_core_visual_graph(RCore *core, RAGraph *g, RAnalFunction *_fcn, int
}
break;
}
case 'j': can->sy -= movspeed * (invscroll? -1: 1); break;
case 'k': can->sy += movspeed * (invscroll? -1: 1); break;
case 'j':
if (g->is_dis) {
r_core_cmd0 (core, "so 1");
} else {
can->sy -= movspeed * (invscroll? -1: 1);
}
break;
case 'k':
if (g->is_dis) {
r_core_cmd0 (core, "so -1");
} else {
can->sy += movspeed * (invscroll? -1: 1);
}
break;
case 'l': can->sx -= movspeed * (invscroll? -1: 1); break;
case 'h': can->sx += movspeed * (invscroll? -1: 1); break;
case '.':
Expand Down
2 changes: 2 additions & 0 deletions libr/include/r_cons.h
Expand Up @@ -767,6 +767,8 @@ typedef struct r_ascii_graph_t {
int layout;
int is_instep;
bool is_tiny;
bool is_dis;
int edgemode;
int mode;
bool is_callgraph;
int zoom;
Expand Down

0 comments on commit b49314a

Please sign in to comment.