mirror of
https://github.com/radareorg/radare2.git
synced 2025-02-25 00:31:08 +00:00
Use g->x and g->y to rebase x/y got with r_str_str_xy
* Use RVector instead of RPVector * Use RAGraph instead of the fixed core->agraph which may be wrong * Fix infinite loop and remove unused functions
This commit is contained in:
parent
4b0e25caeb
commit
79bee09fc3
@ -218,49 +218,6 @@ R_API bool r_cons_canvas_gotoxy(RConsCanvas *c, int x, int y) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
static char *canvas_string(RConsCanvas *c, size_t pos) {
|
||||
int x, y;
|
||||
char *s = calloc (c->w, c->h);
|
||||
if (!s) {
|
||||
return NULL;
|
||||
}
|
||||
char *p = s;
|
||||
int ox = c->x;
|
||||
int oy = c->y;
|
||||
for (y = oy; y < c->h; y ++) {
|
||||
for (x = (y == oy)? ox: 0; x < c->w; x ++) {
|
||||
char ch = c->b[y][x];
|
||||
const char *rune = r_cons_get_rune ((const ut8)ch);
|
||||
if (rune) {
|
||||
size_t rune_len = strlen (rune);
|
||||
memcpy (p, rune, rune_len + 1);
|
||||
p += rune_len;
|
||||
} else {
|
||||
*p = c->b[y][x];
|
||||
}
|
||||
}
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
static int count_newlines(char *s, size_t len, size_t *col) {
|
||||
size_t nl = 0;
|
||||
size_t nc = 0;
|
||||
size_t i;
|
||||
for (i = 0; i < len; i++) {
|
||||
if (s[i] == '\n') {
|
||||
nl++;
|
||||
nc = 0;
|
||||
} else {
|
||||
nc ++;
|
||||
}
|
||||
}
|
||||
if (col) {
|
||||
*col = nc;
|
||||
}
|
||||
return nl;
|
||||
}
|
||||
|
||||
R_API RConsCanvas *r_cons_canvas_new(int w, int h) {
|
||||
if (w < 1 || h < 1) {
|
||||
return NULL;
|
||||
|
@ -100,6 +100,11 @@ struct agraph_refresh_data {
|
||||
int fs;
|
||||
};
|
||||
|
||||
struct r_agraph_location {
|
||||
int x;
|
||||
int y;
|
||||
};
|
||||
|
||||
#define G(x, y) r_cons_canvas_gotoxy (g->can, x, y)
|
||||
#define W(x) r_cons_canvas_write (g->can, x)
|
||||
#define F(x, y, x2, y2, c) r_cons_canvas_fill (g->can, x, y, x2, y2, c)
|
||||
@ -3570,6 +3575,7 @@ static void agraph_init(RAGraph *g) {
|
||||
g->hints = 1;
|
||||
g->movspeed = DEFAULT_SPEED;
|
||||
g->db = sdb_new0 ();
|
||||
r_vector_init (&g->ghits.word_list, sizeof (struct r_agraph_location), NULL, NULL);
|
||||
}
|
||||
|
||||
static void free_anode(RANode *n) {
|
||||
@ -4038,39 +4044,12 @@ static bool toggle_bb(RCore *core, ut64 addr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
typedef struct r_canvas_location {
|
||||
int x;
|
||||
int y;
|
||||
} RPosition;
|
||||
|
||||
static const char *strstr_xy(const char *p, const char *s, int *x, int *y) {
|
||||
const char *d = strstr (p, s);
|
||||
if (!d) {
|
||||
return NULL;
|
||||
}
|
||||
const char *q;
|
||||
int nl = 0;
|
||||
int nc = *x;
|
||||
for (q = p; q < d; q++) {
|
||||
if (*q == '\n') {
|
||||
nl++;
|
||||
*x = 0;
|
||||
nc = 0;
|
||||
} else {
|
||||
nc++;
|
||||
}
|
||||
}
|
||||
*x += nc;
|
||||
*y += nl;
|
||||
return d;
|
||||
}
|
||||
|
||||
static char *get_graph_string(RCore *core) {
|
||||
static char *get_graph_string(RCore *core, RAGraph *g) {
|
||||
int c = r_config_get_i (core->config, "scr.color");
|
||||
int u = r_config_get_i (core->config, "scr.utf8");
|
||||
r_config_set_i (core->config, "scr.color", 0);
|
||||
r_config_set_i (core->config, "scr.utf8", 0);
|
||||
r_core_visual_graph (core, NULL, NULL, false);
|
||||
r_core_visual_graph (core, g, NULL, false);
|
||||
char *s = strdup (r_cons_get_buffer ());
|
||||
r_cons_reset ();
|
||||
r_config_set_i (core->config, "scr.color", c);
|
||||
@ -4078,72 +4057,53 @@ static char *get_graph_string(RCore *core) {
|
||||
return s;
|
||||
}
|
||||
|
||||
static void nextword(RCore *core, RConsCanvas *can, const char *word) {
|
||||
r_return_if_fail (core && core->graph && can && word);
|
||||
static void nextword(RCore *core, RAGraph *g, const char *word) {
|
||||
r_return_if_fail (core && core->graph && g && g->can && word);
|
||||
if (R_STR_ISEMPTY (word)) {
|
||||
return;
|
||||
}
|
||||
RAGraphHits *gh = &core->graph->ghits;
|
||||
if (gh->word_list.v.len && gh->old_word && !strcmp (word, gh->old_word)) {
|
||||
RPosition *pos = r_pvector_at (&gh->word_list, gh->word_nth);
|
||||
if (pos) {
|
||||
gh->word_nth++;
|
||||
} else {
|
||||
RAGraphHits *gh = &g->ghits;
|
||||
RConsCanvas *can = g->can;
|
||||
if (gh->word_list.len && gh->old_word && !strcmp (word, gh->old_word)) {
|
||||
if (gh->word_nth >= gh->word_list.len) {
|
||||
gh->word_nth = 0;
|
||||
pos = r_pvector_at (&gh->word_list, gh->word_nth);
|
||||
}
|
||||
|
||||
struct r_agraph_location *pos = r_vector_index_ptr (&gh->word_list, gh->word_nth);
|
||||
gh->word_nth++;
|
||||
if (pos) {
|
||||
can->sx = pos->x;
|
||||
can->sy = pos->y;
|
||||
can->sx = -pos->x + can->w / 2;
|
||||
can->sy = -pos->y + can->h / 2;
|
||||
}
|
||||
return;
|
||||
} else {
|
||||
r_pvector_fini (&gh->word_list);
|
||||
r_pvector_init (&gh->word_list, free);
|
||||
r_vector_clear (&gh->word_list);
|
||||
}
|
||||
char *s = get_graph_string (core);
|
||||
const char *p = s;
|
||||
char *s = get_graph_string (core, g);
|
||||
r_cons_clear00 ();
|
||||
r_cons_flush ();
|
||||
int ox = 0;
|
||||
int oy = 0;
|
||||
size_t count = 0;
|
||||
const size_t MAX_COUNT = 4096;
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
bool first_x = true;
|
||||
const char *a = NULL;
|
||||
size_t count = 0;
|
||||
int x = 0, y = 0;
|
||||
for (count = 0; count < MAX_COUNT; count++) {
|
||||
x = 0;
|
||||
const char *a = strstr_xy (p, word, &x, &y);
|
||||
a = r_str_str_xy (s, word, a, &x, &y);
|
||||
if (!a) {
|
||||
break;
|
||||
}
|
||||
RPosition *pos = R_NEW0 (RPosition);
|
||||
if (!pos) {
|
||||
break;
|
||||
struct r_agraph_location *pos = r_vector_push (&gh->word_list, NULL);
|
||||
if (pos) {
|
||||
pos->x = x + g->x;
|
||||
pos->y = y + g->y;
|
||||
}
|
||||
if (first_x) {
|
||||
gh->x_origin = x;
|
||||
first_x = false;
|
||||
}
|
||||
const size_t yhalf = can->h / 6;
|
||||
pos->y = -y + yhalf;
|
||||
if (oy == pos->y) {
|
||||
const size_t xhalf = can->w / 2;
|
||||
pos->x = - (x - (ox * 2) - xhalf);
|
||||
} else {
|
||||
const size_t nhalf = can->w / 3;
|
||||
pos->x = gh->x_origin - x + nhalf;
|
||||
}
|
||||
oy = pos->y;
|
||||
ox = pos->x;
|
||||
r_pvector_push (&gh->word_list, pos);
|
||||
p = a + 1;
|
||||
}
|
||||
free (gh->old_word);
|
||||
gh->old_word = strdup (word);
|
||||
free (s);
|
||||
return nextword (core, can, word);
|
||||
if (!a && count == 0) {
|
||||
return;
|
||||
}
|
||||
nextword (core, g, word);
|
||||
}
|
||||
|
||||
R_API int r_core_visual_graph(RCore *core, RAGraph *g, RAnalFunction *_fcn, int is_interactive) {
|
||||
@ -4343,7 +4303,7 @@ R_API int r_core_visual_graph(RCore *core, RAGraph *g, RAnalFunction *_fcn, int
|
||||
}
|
||||
break;
|
||||
case '\\':
|
||||
nextword (core, can, r_config_get (core->config, "scr.highlight"));
|
||||
nextword (core, g, r_config_get (core->config, "scr.highlight"));
|
||||
break;
|
||||
case 'b':
|
||||
r_core_visual_browse (core, "");
|
||||
@ -4942,8 +4902,7 @@ R_API int r_core_visual_graph(RCore *core, RAGraph *g, RAnalFunction *_fcn, int
|
||||
break;
|
||||
}
|
||||
}
|
||||
RAGraphHits *gh = &core->graph->ghits;
|
||||
r_pvector_fini (&gh->word_list);
|
||||
r_vector_fini (&g->ghits.word_list);
|
||||
r_cons_break_pop ();
|
||||
r_config_set (core->config, "asm.comments", r_str_bool (asm_comments));
|
||||
core->cons->event_resize = NULL;
|
||||
|
@ -28,9 +28,8 @@ typedef struct r_ascii_node_t {
|
||||
|
||||
typedef struct r_core_graph_hits_t {
|
||||
char *old_word ;
|
||||
RPVector word_list;
|
||||
RVector word_list;
|
||||
int word_nth;
|
||||
int x_origin;
|
||||
} RAGraphHits;
|
||||
|
||||
|
||||
|
@ -135,6 +135,7 @@ R_API wchar_t *r_str_mb_to_wc(const char *buf);
|
||||
R_API char *r_str_wc_to_mb(const wchar_t *buf);
|
||||
R_API wchar_t *r_str_mb_to_wc_l(const char *buf, int len);
|
||||
R_API char *r_str_wc_to_mb_l(const wchar_t *buf, int len);
|
||||
R_API const char *r_str_str_xy(const char *s, const char *word, const char *prev, int *x, int *y);
|
||||
|
||||
typedef void(*str_operation)(char *c);
|
||||
|
||||
|
@ -3646,6 +3646,27 @@ R_API char *r_str_scale(const char *s, int w, int h) {
|
||||
return r_str_list_join (out, "\n");
|
||||
}
|
||||
|
||||
R_API const char *r_str_str_xy(const char *s, const char *word, const char *prev, int *x, int *y) {
|
||||
r_return_val_if_fail (s && word && x && y, NULL);
|
||||
r_return_val_if_fail (word[0] != '\0' && word[0] != '\n', NULL);
|
||||
const char *src = prev ? prev + 1 : s;
|
||||
const char *d = strstr (src, word);
|
||||
if (!d) {
|
||||
return NULL;
|
||||
}
|
||||
const char *q;
|
||||
for (q = prev ? prev : s; q < d; q++) {
|
||||
if (*q == '\n') {
|
||||
(*y)++;
|
||||
*x = 0;
|
||||
|
||||
} else {
|
||||
(*x)++;
|
||||
}
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
||||
// version.c
|
||||
#include <r_userconf.h>
|
||||
#include <r_util.h>
|
||||
|
@ -430,7 +430,29 @@ bool test_r_str_format_msvc_argv() {
|
||||
mu_end;
|
||||
}
|
||||
|
||||
bool all_tests() {
|
||||
bool test_r_str_str_xy(void) {
|
||||
char *canvas = "Hello World\n"
|
||||
"This World is World\n"
|
||||
"World is Hello\n";
|
||||
int x = 0, y = 0;
|
||||
const char *next = r_str_str_xy (canvas, "World", NULL, &x, &y);
|
||||
mu_assert_eq (x, 6, "x of first occurrence");
|
||||
mu_assert_eq (y, 0, "y of first occurrence");
|
||||
next = r_str_str_xy (canvas, "World", next, &x, &y);
|
||||
mu_assert_eq (x, 5, "x of second occurrence");
|
||||
mu_assert_eq (y, 1, "y of second occurrence");
|
||||
next = r_str_str_xy (canvas, "World", next, &x, &y);
|
||||
mu_assert_eq (x, 14, "x of third occurrence");
|
||||
mu_assert_eq (y, 1, "y of third occurrence");
|
||||
next = r_str_str_xy (canvas, "World", next, &x, &y);
|
||||
mu_assert_eq (x, 0, "x of fourth occurrence");
|
||||
mu_assert_eq (y, 2, "y of fourth occurrence");
|
||||
next = r_str_str_xy (canvas, "World", next, &x, &y);
|
||||
mu_assert_null (next, "no more occurences");
|
||||
mu_end;
|
||||
}
|
||||
|
||||
bool all_tests () {
|
||||
mu_run_test (test_r_str_newf);
|
||||
mu_run_test (test_r_str_replace_char_once);
|
||||
mu_run_test (test_r_str_replace_char);
|
||||
@ -458,6 +480,7 @@ bool all_tests() {
|
||||
mu_run_test (test_r_str_unescape);
|
||||
mu_run_test (test_r_str_constpool);
|
||||
mu_run_test (test_r_str_format_msvc_argv);
|
||||
mu_run_test (test_r_str_str_xy);
|
||||
return tests_passed != tests_run;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user