mirror of
https://github.com/radareorg/radare2.git
synced 2025-02-08 23:07:17 +00:00
195 lines
4.7 KiB
C
195 lines
4.7 KiB
C
/* radare - LGPL - Copyright 2009-2012 - pancake */
|
|
|
|
#include <r_cmd.h>
|
|
#include <r_util.h>
|
|
|
|
R_LIB_VERSION (r_cmd);
|
|
|
|
R_API void r_cmd_alias_init(RCmd *cmd) {
|
|
cmd->aliases.count = 0;
|
|
cmd->aliases.keys = NULL;
|
|
cmd->aliases.values = NULL;
|
|
}
|
|
|
|
R_API RCmd *r_cmd_new () {
|
|
int i;
|
|
RCmd *cmd = R_NEW (RCmd);
|
|
if (cmd) {
|
|
cmd->lcmds = r_list_new ();
|
|
for (i=0;i<255;i++)
|
|
cmd->cmds[i] = NULL;
|
|
cmd->nullcallback = cmd->data = NULL;
|
|
}
|
|
r_cmd_plugin_init (cmd);
|
|
r_cmd_macro_init (&cmd->macro);
|
|
r_cmd_alias_init (cmd);
|
|
return cmd;
|
|
}
|
|
|
|
R_API RCmd *r_cmd_free(RCmd *cmd) {
|
|
if (!cmd) return NULL;
|
|
r_cmd_alias_free (cmd);
|
|
r_list_free (cmd->plist);
|
|
free (cmd);
|
|
return NULL;
|
|
}
|
|
|
|
R_API char **r_cmd_alias_keys(RCmd *cmd, int *sz) {
|
|
if (sz) *sz = cmd->aliases.count;
|
|
return cmd->aliases.keys;
|
|
}
|
|
|
|
R_API void r_cmd_alias_free (RCmd *cmd) {
|
|
int i; // find
|
|
for (i=0; i<cmd->aliases.count; i++) {
|
|
free (cmd->aliases.keys[i]);
|
|
free (cmd->aliases.values[i]);
|
|
}
|
|
cmd->aliases.count = 0;
|
|
free (cmd->aliases.keys);
|
|
free (cmd->aliases.values);
|
|
cmd->aliases.keys = NULL;
|
|
cmd->aliases.values = NULL;
|
|
}
|
|
|
|
R_API int r_cmd_alias_del (RCmd *cmd, const char *k) {
|
|
int i; // find
|
|
for (i=0; i<cmd->aliases.count; i++) {
|
|
if (!strcmp (k, cmd->aliases.keys[i])) {
|
|
free (cmd->aliases.values[i]);
|
|
cmd->aliases.values[i] = NULL;
|
|
cmd->aliases.count--;
|
|
if (cmd->aliases.count>0) {
|
|
if (i>0) {
|
|
free (cmd->aliases.keys[i]);
|
|
cmd->aliases.keys[i] = cmd->aliases.keys[0];
|
|
free (cmd->aliases.values[i]);
|
|
cmd->aliases.values[i] = cmd->aliases.values[0];
|
|
}
|
|
memcpy (cmd->aliases.values,
|
|
cmd->aliases.values+1,
|
|
cmd->aliases.count*sizeof (void*));
|
|
memcpy (cmd->aliases.keys,
|
|
cmd->aliases.keys+1,
|
|
cmd->aliases.count*sizeof (void*));
|
|
}
|
|
return 1;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
R_API int r_cmd_alias_set (RCmd *cmd, const char *k, const char *v) {
|
|
int i; // find
|
|
for (i=0; i<cmd->aliases.count; i++) {
|
|
if (!strcmp (k, cmd->aliases.keys[i])) {
|
|
free (cmd->aliases.values[i]);
|
|
cmd->aliases.values[i] = strdup (v);
|
|
return 1;
|
|
}
|
|
}
|
|
// new
|
|
i = cmd->aliases.count++;
|
|
cmd->aliases.keys = (char **)realloc (cmd->aliases.keys,
|
|
sizeof (char**)*cmd->aliases.count);
|
|
cmd->aliases.values = (char **)realloc (cmd->aliases.values,
|
|
sizeof (char**)*cmd->aliases.count);
|
|
cmd->aliases.keys[i] = strdup (k);
|
|
cmd->aliases.values[i] = strdup (v);
|
|
return 0;
|
|
}
|
|
|
|
R_API char *r_cmd_alias_get (RCmd *cmd, const char *k) {
|
|
int i; // find
|
|
for (i=0; i<cmd->aliases.count; i++) {
|
|
if (!strcmp (k, cmd->aliases.keys[i]))
|
|
return cmd->aliases.values[i];
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
R_API int r_cmd_set_data(RCmd *cmd, void *data) {
|
|
cmd->data = data;
|
|
return 1;
|
|
}
|
|
|
|
R_API int r_cmd_add_long(RCmd *cmd, const char *lcmd, const char *scmd, const char *desc) {
|
|
RCmdLongItem *item = R_NEW (RCmdLongItem);
|
|
if (item == NULL)
|
|
return R_FALSE;
|
|
strncpy (item->cmd, lcmd, sizeof (item->cmd)-1);
|
|
strncpy (item->cmd_short, scmd, sizeof (item->cmd_short)-1);
|
|
item->cmd_len = strlen (lcmd);
|
|
strncpy (item->desc, desc, sizeof (item->desc)-1);
|
|
r_list_append (cmd->lcmds, item);
|
|
return R_TRUE;
|
|
}
|
|
|
|
R_API int r_cmd_add(RCmd *c, const char *cmd, const char *desc, r_cmd_callback(cb)) {
|
|
struct r_cmd_item_t *item;
|
|
int idx = (ut8)cmd[0];
|
|
|
|
item = c->cmds[idx];
|
|
if (item == NULL) {
|
|
item = R_NEW (RCmdItem);
|
|
c->cmds[idx] = item;
|
|
}
|
|
strncpy (item->cmd, cmd, sizeof (item->cmd)-1);
|
|
strncpy (item->desc, desc, sizeof (item->desc)-1);
|
|
item->callback = cb;
|
|
return R_TRUE;
|
|
}
|
|
|
|
R_API int r_cmd_del(RCmd *cmd, const char *command) {
|
|
int idx = (ut8)command[0];
|
|
free(cmd->cmds[idx]);
|
|
cmd->cmds[idx] = NULL;
|
|
return 0;
|
|
}
|
|
|
|
R_API int r_cmd_call(RCmd *cmd, const char *input) {
|
|
struct r_cmd_item_t *c;
|
|
int ret = -1;
|
|
RListIter *iter;
|
|
RCmdPlugin *cp;
|
|
|
|
if (!input || !*input) {
|
|
if (cmd->nullcallback != NULL)
|
|
ret = cmd->nullcallback (cmd->data);
|
|
} else {
|
|
r_list_foreach (cmd->plist, iter, cp) {
|
|
if (cp->call (cmd->data, input))
|
|
return R_TRUE;
|
|
}
|
|
c = cmd->cmds[(ut8)input[0]];
|
|
if (c && c->callback)
|
|
ret = c->callback (cmd->data, input+1);
|
|
else ret = -1;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
R_API int r_cmd_call_long(RCmd *cmd, const char *input) {
|
|
char *inp;
|
|
RListIter *iter;
|
|
RCmdLongItem *c;
|
|
int ret, inplen = strlen (input)+1;
|
|
|
|
r_list_foreach (cmd->lcmds, iter, c) {
|
|
if (inplen>=c->cmd_len && !r_str_cmp (input, c->cmd, c->cmd_len)) {
|
|
int lcmd = strlen (c->cmd_short);
|
|
int linp = strlen (input+c->cmd_len);
|
|
/// SLOW malloc on most situations. use stack
|
|
inp = malloc (lcmd+linp+2); // TODO: use static buffer with R_CMD_MAXLEN
|
|
if (inp == NULL)
|
|
return -1;
|
|
memcpy (inp, c->cmd_short, lcmd);
|
|
memcpy (inp+lcmd, input+c->cmd_len, linp+1);
|
|
ret = r_cmd_call (cmd, inp);
|
|
free (inp);
|
|
return ret;
|
|
}
|
|
}
|
|
return -1;
|
|
}
|