rizin/libr/include/r_cmd.h
Riccardo Schirone f322c1b1bc
Add support for @* commands in new r2-shell-parser (#16038)
* Use TSSymbol instead of comparing type strings

This patch uses ts_node_symbol instead of ts_node_type to check whether
a node is of a given type. Since TSSymbol is just an integer, the check
will be much faster. Also, it allows to store commands handler in an
hashtable, instead of having if-cascade.

* Make sure r_config_hold works even when keys do not exist or are freed

* Add support for all _tmp_commands

* Make sure to always reuse the same TSLanguage

* Update both tree-sitter and radare2-shell-parser

This way we use TSLanguage version 11, which fixes some problems with
TSSymbols.

* Compute is_last_cmd on each single command and fix logging

is_last_cmd should be set on a per-command basis, so if you analyze
things like `pd 3; .; .; .;` the `.` refers to `pd 3`.

This also fixes logging, so when an invalid command is parsed, it is
still available in the history.

* Add comment about directly using r2-shell-parser in r_core_cmd_lines

r_core_cmd_lines tries to parse the input and split it in lines, but at
least in theory, we don't need it as the new parser can already handle
full scripts.

* Allow other tasks to run between commands even in the new parser

* Update radare2-shell-parser
2020-02-24 09:46:15 +01:00

146 lines
3.5 KiB
C

#ifndef R2_CMD_H
#define R2_CMD_H
#include <r_types.h>
#include <r_util.h>
#include <r_bind.h>
#ifdef __cplusplus
extern "C" {
#endif
//R_LIB_VERSION_HEADER (r_cmd);
#define MACRO_LIMIT 1024
#define MACRO_LABELS 20
#define R_CMD_MAXLEN 4096
#define r_cmd_callback(x) int (*x)(void *data, const char *input)
#define r_cmd_nullcallback(x) int (*x)(void *data)
typedef struct r_cmd_macro_label_t {
char name[80];
char *ptr;
} RCmdMacroLabel;
typedef struct r_cmd_macro_item_t {
char *name;
char *args;
char *code;
int codelen;
int nargs;
} RCmdMacroItem;
typedef struct r_cmd_macro_t {
int counter;
ut64 *brk_value;
ut64 _brk_value;
int brk;
// int (*cmd)(void *user, const char *cmd);
RCoreCmd cmd;
PrintfCallback cb_printf;
void *user;
RNum *num;
int labels_n;
RCmdMacroLabel labels[MACRO_LABELS];
RList *macros;
} RCmdMacro;
typedef int (*RCmdCallback)(void *user, const char *cmd);
typedef struct r_cmd_item_t {
char cmd[64];
char desc[128];
r_cmd_callback (callback);
} RCmdItem;
typedef struct r_cmd_long_item_t {
char cmd[64]; /* long command */
int cmd_len;
char cmd_short[32]; /* short command */
char desc[128];
} RCmdLongItem;
typedef struct r_cmd_alias_t {
int count;
char **keys;
char **values;
int *remote;
} RCmdAlias;
typedef struct r_cmd_t {
void *data;
r_cmd_nullcallback (nullcallback);
RCmdItem *cmds[UT8_MAX];
RCmdMacro macro;
RList *lcmds;
RList *plist;
RCmdAlias aliases;
#if USE_TREESITTER
void *language; // used to store TSLanguage *
HtUP *ts_symbols_ht;
#endif
} RCmd;
// TODO WIP
typedef struct r_cmd_descriptor_t {
const char *cmd;
const char **help_msg;
const char **help_detail;
const char **help_detail2;
struct r_cmd_descriptor_t *sub[127];
} RCmdDescriptor;
// TODO: move into r_core.h
typedef struct r_core_plugin_t {
const char *name;
const char *desc;
const char *license;
const char *author;
const char *version;
RCmdCallback call;
RCmdCallback init;
RCmdCallback fini;
} RCorePlugin;
#ifdef R_API
R_API int r_core_plugin_init(RCmd *cmd);
R_API int r_core_plugin_add(RCmd *cmd, RCorePlugin *plugin);
R_API int r_core_plugin_check(RCmd *cmd, const char *a0);
R_API int r_core_plugin_fini(RCmd *cmd);
/* review api */
R_API RCmd *r_cmd_new(void);
R_API RCmd *r_cmd_free(RCmd *cmd);
R_API int r_cmd_set_data(RCmd *cmd, void *data);
R_API int r_cmd_add(RCmd *cmd, const char *command, const char *desc, r_cmd_callback(callback));
R_API int r_cmd_add_long(RCmd *cmd, const char *longcmd, const char *shortcmd, const char *desc);
R_API int r_core_del(RCmd *cmd, const char *command);
R_API int r_cmd_call(RCmd *cmd, const char *command);
R_API int r_cmd_call_long(RCmd *cmd, const char *input);
R_API char **r_cmd_args(RCmd *cmd, int *argc);
/* r_cmd_macro */
R_API RCmdMacroItem *r_cmd_macro_item_new(void);
R_API void r_cmd_macro_item_free(RCmdMacroItem *item);
R_API void r_cmd_macro_init(RCmdMacro *mac);
R_API int r_cmd_macro_add(RCmdMacro *mac, const char *name);
R_API int r_cmd_macro_rm(RCmdMacro *mac, const char *_name);
R_API void r_cmd_macro_list(RCmdMacro *mac);
R_API void r_cmd_macro_meta(RCmdMacro *mac);
R_API int r_cmd_macro_call(RCmdMacro *mac, const char *name);
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 char **r_cmd_alias_keys(RCmd *cmd, int *sz);
R_API int r_cmd_alias_set (RCmd *cmd, const char *k, const char *v, int remote);
R_API char *r_cmd_alias_get (RCmd *cmd, const char *k, int remote);
R_API void r_cmd_alias_free (RCmd *cmd);
R_API void r_cmd_macro_fini(RCmdMacro *mac);
#ifdef __cplusplus
}
#endif
#endif
#endif