2010-04-09 21:57:22 +08:00
|
|
|
/* radare - LGPL - Copyright 2009-2010 pancake<nopcode.org> */
|
2009-02-06 05:08:46 +08:00
|
|
|
|
|
|
|
#include <r_lang.h>
|
2009-02-11 07:56:20 +08:00
|
|
|
#include <r_util.h>
|
2009-02-06 05:08:46 +08:00
|
|
|
|
2010-05-20 23:40:58 +08:00
|
|
|
R_API RLang *r_lang_new() {
|
|
|
|
RLang *lang;
|
|
|
|
|
|
|
|
lang = R_NEW (RLang);
|
2009-09-20 07:03:57 +08:00
|
|
|
if (lang) {
|
|
|
|
lang->user = NULL;
|
2010-04-07 00:21:41 +08:00
|
|
|
INIT_LIST_HEAD (&lang->langs);
|
|
|
|
INIT_LIST_HEAD (&lang->defs);
|
2009-09-20 07:03:57 +08:00
|
|
|
}
|
|
|
|
return lang;
|
|
|
|
}
|
|
|
|
|
2010-04-09 21:57:22 +08:00
|
|
|
R_API void *r_lang_free(RLang *lang) {
|
2010-04-07 00:21:41 +08:00
|
|
|
r_lang_undef (lang);
|
2009-09-20 07:03:57 +08:00
|
|
|
// TODO: remove langs plugins
|
2010-04-07 00:21:41 +08:00
|
|
|
free (lang);
|
2009-09-20 07:03:57 +08:00
|
|
|
return NULL;
|
2009-02-06 05:08:46 +08:00
|
|
|
}
|
|
|
|
|
2009-09-17 17:48:36 +08:00
|
|
|
// XXX: This is only used actually to pass 'core' structure
|
|
|
|
// TODO: when language bindings are done we will need an api to
|
|
|
|
// define symbols from C to the language namespace
|
2009-09-20 07:03:57 +08:00
|
|
|
// XXX: Depcreate!!
|
2010-04-09 21:57:22 +08:00
|
|
|
R_API void r_lang_set_user_ptr(RLang *lang, void *user) {
|
2009-02-12 07:04:30 +08:00
|
|
|
lang->user = user;
|
|
|
|
}
|
|
|
|
|
2010-04-09 21:57:22 +08:00
|
|
|
R_API int r_lang_define(RLang *lang, const char *type, const char *name, void *value) {
|
2009-09-20 07:03:57 +08:00
|
|
|
int ret = R_FALSE;
|
2010-04-09 21:57:22 +08:00
|
|
|
RLangDef *def = NULL;
|
2009-09-20 07:03:57 +08:00
|
|
|
struct list_head *pos;
|
2010-04-09 21:57:22 +08:00
|
|
|
list_for_each_prev (pos, &lang->defs) {
|
|
|
|
def = list_entry (pos, RLangDef, list);
|
2010-04-07 00:21:41 +08:00
|
|
|
if (!strcmp (name, def->name)) {
|
2009-09-20 07:03:57 +08:00
|
|
|
def->value = value;
|
|
|
|
ret = R_TRUE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!ret) {
|
2010-04-09 21:57:22 +08:00
|
|
|
def = R_NEW (RLangDef);
|
2009-09-20 07:03:57 +08:00
|
|
|
if (def != NULL) {
|
2010-04-09 21:57:22 +08:00
|
|
|
def->type = strdup (type);
|
|
|
|
def->name = strdup (name);
|
2009-09-20 07:03:57 +08:00
|
|
|
def->value = value;
|
2010-04-09 21:57:22 +08:00
|
|
|
list_add_tail (&(def->list), &lang->defs);
|
2009-09-20 07:03:57 +08:00
|
|
|
ret = R_TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2010-04-09 21:57:22 +08:00
|
|
|
R_API void r_lang_undef(RLang *lang) {
|
2009-09-20 07:03:57 +08:00
|
|
|
struct list_head *pos, *n;
|
2010-04-09 21:57:22 +08:00
|
|
|
list_for_each_safe (pos, n, &lang->defs) {
|
|
|
|
RLangDef *def = list_entry (pos, RLangDef, list);
|
2010-04-07 00:21:41 +08:00
|
|
|
list_del (&def->list);
|
|
|
|
free (def->name);
|
|
|
|
free (def->type);
|
|
|
|
free (def);
|
2009-09-20 07:03:57 +08:00
|
|
|
}
|
2009-09-17 17:48:36 +08:00
|
|
|
}
|
|
|
|
|
2010-04-09 21:57:22 +08:00
|
|
|
R_API int r_lang_setup(RLang *lang) {
|
|
|
|
int ret = R_FALSE;
|
|
|
|
if (lang->cur && lang->cur->setup)
|
|
|
|
ret = lang->cur->setup (lang);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2010-05-26 07:42:22 +08:00
|
|
|
R_API int r_lang_add(RLang *lang, struct r_lang_plugin_t *foo) {
|
2009-02-12 07:04:30 +08:00
|
|
|
if (foo->init)
|
2010-04-07 00:21:41 +08:00
|
|
|
foo->init (lang->user);
|
|
|
|
list_add_tail (&(foo->list), &(lang->langs));
|
2009-02-06 05:08:46 +08:00
|
|
|
return R_TRUE;
|
|
|
|
}
|
|
|
|
|
2009-09-20 07:03:57 +08:00
|
|
|
/* TODO: deprecate all list methods */
|
2010-04-09 21:57:22 +08:00
|
|
|
R_API int r_lang_list(RLang *lang) {
|
2009-02-06 05:08:46 +08:00
|
|
|
struct list_head *pos;
|
2010-04-07 00:21:41 +08:00
|
|
|
list_for_each_prev (pos, &lang->langs) {
|
2010-05-26 07:42:22 +08:00
|
|
|
RLangPlugin *h = list_entry (pos, RLangPlugin, list);
|
2010-04-07 00:21:41 +08:00
|
|
|
printf (" %s: %s\n", h->name, h->desc);
|
2009-02-06 05:08:46 +08:00
|
|
|
}
|
|
|
|
return R_FALSE;
|
|
|
|
}
|
|
|
|
|
2010-04-09 21:57:22 +08:00
|
|
|
R_API int r_lang_use(RLang *lang, const char *name) {
|
2009-02-06 05:08:46 +08:00
|
|
|
struct list_head *pos;
|
|
|
|
list_for_each_prev(pos, &lang->langs) {
|
2010-05-26 07:42:22 +08:00
|
|
|
struct r_lang_plugin_t *h = list_entry (pos, struct r_lang_plugin_t, list);
|
2010-04-07 00:21:41 +08:00
|
|
|
if (!strcmp (h->name, name)) {
|
2009-02-06 05:08:46 +08:00
|
|
|
lang->cur = h;
|
|
|
|
return R_TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return R_FALSE;
|
|
|
|
}
|
|
|
|
|
2009-09-20 07:03:57 +08:00
|
|
|
// TODO: store in r_lang and use it from the plugin?
|
2010-04-09 21:57:22 +08:00
|
|
|
R_API int r_lang_set_argv(RLang *lang, int argc, char **argv) {
|
2009-02-11 07:56:20 +08:00
|
|
|
if (lang->cur && lang->cur->set_argv)
|
2010-04-07 00:21:41 +08:00
|
|
|
return lang->cur->set_argv (lang, argc, argv);
|
2009-02-11 07:56:20 +08:00
|
|
|
return R_FALSE;
|
|
|
|
}
|
|
|
|
|
2010-04-09 21:57:22 +08:00
|
|
|
|
|
|
|
R_API int r_lang_run(RLang *lang, const char *code, int len) {
|
2009-02-11 07:56:20 +08:00
|
|
|
if (lang->cur && lang->cur->run)
|
2010-04-07 00:21:41 +08:00
|
|
|
return lang->cur->run (lang, code, len);
|
2009-02-11 07:56:20 +08:00
|
|
|
return R_FALSE;
|
|
|
|
}
|
|
|
|
|
2010-04-09 21:57:22 +08:00
|
|
|
R_API int r_lang_run_string(RLang *lang, const char *code) {
|
|
|
|
return r_lang_run (lang, code, strlen (code));
|
|
|
|
}
|
|
|
|
|
|
|
|
R_API int r_lang_run_file(RLang *lang, const char *file) {
|
2009-02-11 07:56:20 +08:00
|
|
|
int len, ret = R_FALSE;
|
2009-02-06 05:08:46 +08:00
|
|
|
if (lang->cur) {
|
2009-02-11 07:56:20 +08:00
|
|
|
if (lang->cur->run_file == NULL) {
|
|
|
|
if (lang->cur->run != NULL) {
|
|
|
|
char *code = r_file_slurp(file, &len);
|
2009-09-20 07:03:57 +08:00
|
|
|
ret = lang->cur->run(lang, code, len);
|
2009-02-11 07:56:20 +08:00
|
|
|
free(code);
|
|
|
|
}
|
2009-09-20 07:03:57 +08:00
|
|
|
} else ret = lang->cur->run_file(lang, file);
|
2009-02-06 05:08:46 +08:00
|
|
|
}
|
2009-02-11 07:56:20 +08:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2009-09-20 07:03:57 +08:00
|
|
|
/* TODO: deprecate or make it more modular .. reading from stdin in a lib?!? wtf */
|
2010-04-09 21:57:22 +08:00
|
|
|
R_API int r_lang_prompt(RLang *lang) {
|
2009-02-11 07:56:20 +08:00
|
|
|
char buf[1024];
|
2009-02-11 20:31:26 +08:00
|
|
|
|
2009-02-11 07:56:20 +08:00
|
|
|
if (lang->cur == NULL)
|
|
|
|
return R_FALSE;
|
2009-02-11 20:31:26 +08:00
|
|
|
|
|
|
|
if (lang->cur->prompt)
|
2009-09-20 07:03:57 +08:00
|
|
|
if (lang->cur->prompt(lang) == R_TRUE)
|
2009-02-11 20:31:26 +08:00
|
|
|
return R_TRUE;
|
|
|
|
|
2010-04-07 00:21:41 +08:00
|
|
|
for (;;) {
|
|
|
|
printf ("%s> ", lang->cur->name);
|
|
|
|
fflush (stdout);
|
|
|
|
fgets (buf, 1023, stdin);
|
|
|
|
if (feof (stdin)) break;
|
|
|
|
buf[strlen (buf)-1]='\0';
|
|
|
|
if (!strcmp (buf, "q"))
|
2009-02-11 07:56:20 +08:00
|
|
|
return R_TRUE;
|
2010-04-07 00:21:41 +08:00
|
|
|
if (!strcmp (buf, "?")) {
|
2009-02-20 01:13:34 +08:00
|
|
|
if (lang->cur->help)
|
2010-04-07 00:21:41 +08:00
|
|
|
printf (*lang->cur->help);
|
|
|
|
} else r_lang_run (lang, buf, strlen(buf));
|
2009-02-11 07:56:20 +08:00
|
|
|
}
|
2010-04-09 21:57:22 +08:00
|
|
|
clearerr (stdin);
|
|
|
|
printf ("\n");
|
2009-02-11 07:56:20 +08:00
|
|
|
return R_TRUE;
|
2009-02-06 05:08:46 +08:00
|
|
|
}
|