Implement RCore.visual_slides() ##visual

* Add clearkeys() helper and r2slides example
This commit is contained in:
Sergi Àlvarez i Capilla 2021-10-27 00:39:09 +02:00 committed by pancake
parent a9f422c2a1
commit 5f33adbd83
8 changed files with 211 additions and 5 deletions

40
doc/r2slides.txt Normal file
View File

@ -0,0 +1,40 @@
# Welcome to radare2
--label:title
This is an introductory course to radare2
`?E Welcome to r2land`
`o;pd 4`
--gotokey:i:insert
Press 'n' for next slide (or the spacebar)
Press 'p' to see clippy moving
--pancake
# Contents
We will cover the following topics:
* What is radare2?
* How to install it
* Basic shell usage
* Scripting examples
# Insertion
--label:insert
To insert stuff press : to enter shell and then
use the 'w' command to write a string.
`?ef w hello world`
# Questions
Please send me an email
In this course we will see:
--pancake

View File

@ -9,7 +9,7 @@ R2DEPS+=r_reg r_search r_syscall r_socket r_fs r_magic r_crypto
OBJS=core.o cmd.o cfile.o cconfig.o visual.o cio.o yank.o libs.o agraph.o
OBJS+=fortune.o hack.o vasm.o patch.o cbin.o corelog.o rtr.o cmd_api.o
OBJS+=carg.o canal.o project.o gdiff.o casm.o disasm.o cplugin.o rvc.o
OBJS+=vmenus.o vmenus_graph.o vmenus_zigns.o zdiff.o citem.o
OBJS+=vmenus.o vmenus_graph.o vmenus_zigns.o zdiff.o citem.o vslides.o
OBJS+=task.o panels.o pseudo.o vmarks.o anal_tp.o anal_objc.o blaze.o cundo.o
OBJS+=cproject.o

View File

@ -327,6 +327,7 @@ static const char *help_msg_v[] = {
"Usage:", "v[*i]", "",
"v", "", "open visual panels",
"v", " test", "load saved layout with name test",
"v.", " [file]", "load visual script (also known as slides)",
"v=", " test", "save current layout with name test",
"vi", " test", "open the file test in 'cfg.editor'",
NULL
@ -2424,6 +2425,11 @@ static int cmd_panels(void *data, const char *input) {
if (core->vmode) {
return false;
}
if (*input == '.') {
const char *f = r_str_trim_head_ro (input + 1);
r_core_visual_slides (core, f);
return false;
}
if (*input == '?') {
r_core_cmd_help (core, help_msg_v);
return false;

View File

@ -1091,7 +1091,7 @@ static const char *radare_argv[] = {
"tu?", "tu", "tuj", "tu*", "tuc", "tt?", "tt", "ttj", "ttc",
"T?", "T", "T*", "T-", "Tl", "Tj", "Tm", "Ts", "TT", "T=", "T=.", "T=&",
"u?", "u", "uw", "us", "uc",
"v", "V", "v!", "vv", "vV", "vVV", "VV",
"v", "v.", "V", "v!", "vv", "vV", "vVV", "VV",
"w?", "w", "w1+", "w1-", "w2+", "w2-", "w4+", "w4-", "w8+", "w8-",
"w0", "w", "w6", "w6d", "w6e", "wa", "wa*", "waf", "wao?", "wao",
"wA?", "wA", "wB", "wB-", "wc", "wcj", "wc-", "wc+", "wc*", "wcr", "wci", "wcp", "wcp*", "wcpi",
@ -2574,7 +2574,7 @@ static void __init_autocomplete_default (RCore* core) {
"db-", "dbc", "dbC", "dbd", "dbe", "dbs", "dbi", "dbte", "dbtd", "dbts", NULL
};
const char *files[] = {
".", "..", ".*", ":. ", "/F", "/m", "!", "!!", "#!c", "#!v", "#!cpipe", "#!vala",
".", "..", ".*", ":. ", "/F", "/m", "!", "!!", "#!c", "#!v", "#!cpipe", "#!vala", "v.",
"#!rust", "#!zig", "#!pipe", "#!python", "aeli", "arp", "arpg", "dmd", "drp", "drpg", "o",
"idp", "idpi", "L", "obf", "o+", "oc", "r2", "rabin2", "rasm2", "rahash2", "rax2",
"rafind2", "cd", "ls", "on", "op", "wf", "rm", "wF", "wp", "Sd", "Sl", "to", "pm",

View File

@ -60,6 +60,7 @@ r_core_sources = [
'task.c',
'vasm.c',
'visual.c',
'vslides.c',
'vmarks.c',
'vmenus.c',
'vmenus_graph.c',

158
libr/core/vslides.c Normal file
View File

@ -0,0 +1,158 @@
/* 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);
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;
char *data = r_file_slurp (file, NULL);
if (!data) {
eprintf ("Cannot open file.\n");
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);
}

View File

@ -504,6 +504,7 @@ R_API void r_core_anal_paths(RCore *core, ut64 from, ut64 to, bool followCalls,
R_API void r_core_list_io(RCore *core);
R_API RListInfo *r_listinfo_new (const char *name, RInterval pitv, RInterval vitv, int perm, const char *extra);
R_API void r_listinfo_free (RListInfo *info);
R_API void r_core_visual_slides(RCore *core, const char *file);
/* visual marks */
R_API void r_core_visual_mark_seek(RCore *core, ut8 ch);
R_API void r_core_visual_mark(RCore *core, ut8 ch);

View File

@ -175,8 +175,8 @@ static const SevenSegments ss[] = {
"| |"}
},
{ 'n', {" ",
" __ ",
"| |"}
"|\\ |",
"| \\|"}
},
{ 'o', {" ",
" __ ",