radare2/libr/core/vslides.c
2022-08-22 23:25:40 +02:00

163 lines
3.1 KiB
C

/* radare - LGPL - Copyright 2021 - pancake */
#include <r_core.h>
static char *keys[256] = {0};
static void clearkeys(void) {
int i;
for (i = 0; i < 256; i++) {
free (keys[i]);
keys[i] = NULL;
}
}
static int findpage(RList *list, const char *pagename) {
int count = 0;
RListIter *iter;
char *s;
r_list_foreach (list, iter, s) {
if (!strncmp (s, "# ", 2)) {
count++;
} else if (r_str_startswith (s, "--label:")) {
const char *label = s + strlen ("--label:");
if (!strcmp (pagename, label)) {
return count;
}
}
}
return -1;
}
static int gotokey(RList *list, int ch, int page) {
if (keys[ch]) {
int npage = findpage (list, keys[ch]);
if (npage != -1) {
return npage;
}
}
return page;
}
static void render(RCore *core, RList *list, int page) {
char *s;
if (page < 0) {
page = 0;
}
int count = 0;
RListIter *iter;
r_list_foreach (list, iter, s) {
if (!strncmp (s, "# ", 2)) {
count++;
}
if (count == page) {
if (*s == '`') {
char *cmd = r_str_ndup (s + 1, strlen (s) -2);
char *res = r_core_cmd_str (core, cmd);
r_cons_printf ("%s", res);
free (res);
free (cmd);
} else if (r_str_startswith (s, "--gotokey:")) {
char *kv = strdup (s + strlen ("--gotokey:"));
if (kv[0] && kv[1]) {
kv[1] = 0;
int k = kv[0];
R_FREE (keys[k]);
if (kv[2]) {
keys[k] = strdup (kv + 2);
}
}
free (kv);
} else if (!strncmp (s, "--", 2)) {
// directive, do not print
} else if (*s == '#') {
char *ss = r_str_ss (s, 0, 0);
r_cons_printf ("%s\n", ss);
free (ss);
} else {
r_cons_printf (" %s\n", s);
}
}
}
}
R_API void r_core_visual_slides(RCore *core, const char *file) {
bool having_fun = true;
r_return_if_fail (core && file);
if (!*file) {
return;
}
char *data = r_file_slurp (file, NULL);
if (!data) {
R_LOG_ERROR ("Cannot open file");
return;
}
RList *list = r_str_split_list (data, "\n", 0);
int ch;
int page = 1;
while (having_fun) {
clearkeys ();
r_cons_clear00 ();
render (core, list, page);
r_cons_flush ();
r_cons_enable_mouse (false);
ch = r_cons_readchar ();
ch = r_cons_arrow_to_hjkl (ch);
switch (ch) {
case 'q':
having_fun = false;
break;
case ' ':
case 'n':
page++;
break;
case 'p':
page--;
if (page < 1) {
page = 1;
}
break;
case '!':
//
{
r_core_cmdf (core, "vim %s", file);
char *ndata = r_file_slurp (file, NULL);
if (ndata) {
r_list_free (list);
free (data);
data = ndata;
list = r_str_split_list (data, "\n", 0);
}
}
break;
case ':':
r_cons_show_cursor (true);
r_cons_set_raw (0);
while (1) {
char cmd[1024];
*cmd = 0;
r_line_set_prompt (":> ");
if (r_cons_fgets (cmd, sizeof (cmd), 0, NULL) < 0) {
cmd[0] = '\0';
}
r_core_cmd0 (core, cmd);
if (!cmd[0]) {
break;
}
r_cons_flush ();
}
r_cons_show_cursor (false);
r_cons_set_raw (1);
r_cons_clear ();
break;
default:
page = gotokey (list, ch, page);
break;
}
}
r_list_free (list);
free (data);
}