Rizin
unix-like reverse engineering framework and cli tools
lang.c File Reference
#include "config.h"
#include <rz_lang.h>
#include <rz_util.h>
#include <rz_cons.h>

Go to the source code of this file.

Functions

 RZ_LIB_VERSION (rz_lang)
 
RZ_API void rz_lang_plugin_free (RzLangPlugin *p)
 
RZ_API RzLangrz_lang_new (void)
 
RZ_API void rz_lang_free (RzLang *lang)
 
RZ_API void rz_lang_set_user_ptr (RzLang *lang, void *user)
 
RZ_API bool rz_lang_define (RzLang *lang, const char *type, const char *name, void *value)
 
RZ_API void rz_lang_def_free (RzLangDef *def)
 
RZ_API void rz_lang_undef (RzLang *lang, const char *name)
 
RZ_API bool rz_lang_setup (RzLang *lang)
 
RZ_API bool rz_lang_add (RzLang *lang, RzLangPlugin *foo)
 
RZ_API RzLangPluginrz_lang_get_by_extension (RzLang *lang, const char *ext)
 
RZ_API RzLangPluginrz_lang_get_by_name (RzLang *lang, const char *name)
 
RZ_API bool rz_lang_use (RzLang *lang, const char *name)
 
RZ_API bool rz_lang_set_argv (RzLang *lang, int argc, char **argv)
 
RZ_API int rz_lang_run (RzLang *lang, const char *code, int len)
 
RZ_API int rz_lang_run_string (RzLang *lang, const char *code)
 
RZ_API int rz_lang_run_file (RzLang *lang, const char *file)
 
RZ_API int rz_lang_prompt (RzLang *lang)
 

Variables

static RzLangPluginlang_static_plugins [] = { RZ_LANG_STATIC_PLUGINS }
 
static RzLang__lang = NULL
 

Function Documentation

◆ rz_lang_add()

RZ_API bool rz_lang_add ( RzLang lang,
RzLangPlugin foo 
)

Definition at line 115 of file lang.c.

115  {
116  if (foo && (!rz_lang_get_by_name(lang, foo->name))) {
117  if (foo->init) {
118  foo->init(lang);
119  }
120  rz_list_append(lang->langs, foo);
121  return true;
122  }
123  return false;
124 }
RZ_API RzLangPlugin * rz_lang_get_by_name(RzLang *lang, const char *name)
Definition: lang.c:141
static RzMain foo[]
Definition: main.c:11
RZ_API RZ_BORROW RzListIter * rz_list_append(RZ_NONNULL RzList *list, void *data)
Appends at the end of the list a new element.
Definition: list.c:288
RzList * langs
Definition: rz_lang.h:21
const char * name
Definition: rz_main.h:17

References foo, rz_lang_t::langs, rz_main_t::name, rz_lang_get_by_name(), and rz_list_append().

Referenced by rz_lang_new().

◆ rz_lang_def_free()

RZ_API void rz_lang_def_free ( RzLangDef def)

Definition at line 85 of file lang.c.

85  {
86  free(def->name);
87  free(def->type);
88  free(def);
89 }
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
int def(FILE *source, FILE *dest, int level)
Definition: zpipe.c:36

References def(), and free().

Referenced by rz_lang_new().

◆ rz_lang_define()

RZ_API bool rz_lang_define ( RzLang lang,
const char *  type,
const char *  name,
void *  value 
)

Definition at line 65 of file lang.c.

65  {
66  RzLangDef *def;
68  rz_list_foreach (lang->defs, iter, def) {
69  if (!rz_str_casecmp(name, def->name)) {
70  def->value = value;
71  return true;
72  }
73  }
75  if (!def) {
76  return false;
77  }
78  def->type = strdup(type);
79  def->name = strdup(name);
80  def->value = value;
81  rz_list_append(lang->defs, def);
82  return true;
83 }
static int value
Definition: cmd_api.c:93
return strdup("=SP r13\n" "=LR r14\n" "=PC r15\n" "=A0 r0\n" "=A1 r1\n" "=A2 r2\n" "=A3 r3\n" "=ZF zf\n" "=SF nf\n" "=OF vf\n" "=CF cf\n" "=SN or0\n" "gpr lr .32 56 0\n" "gpr pc .32 60 0\n" "gpr cpsr .32 64 0 ____tfiae_________________qvczn\n" "gpr or0 .32 68 0\n" "gpr tf .1 64.5 0 thumb\n" "gpr ef .1 64.9 0 endian\n" "gpr jf .1 64.24 0 java\n" "gpr qf .1 64.27 0 sticky_overflow\n" "gpr vf .1 64.28 0 overflow\n" "gpr cf .1 64.29 0 carry\n" "gpr zf .1 64.30 0 zero\n" "gpr nf .1 64.31 0 negative\n" "gpr itc .4 64.10 0 if_then_count\n" "gpr gef .4 64.16 0 great_or_equal\n" "gpr r0 .32 0 0\n" "gpr r1 .32 4 0\n" "gpr r2 .32 8 0\n" "gpr r3 .32 12 0\n" "gpr r4 .32 16 0\n" "gpr r5 .32 20 0\n" "gpr r6 .32 24 0\n" "gpr r7 .32 28 0\n" "gpr r8 .32 32 0\n" "gpr r9 .32 36 0\n" "gpr r10 .32 40 0\n" "gpr r11 .32 44 0\n" "gpr r12 .32 48 0\n" "gpr r13 .32 52 0\n" "gpr r14 .32 56 0\n" "gpr r15 .32 60 0\n" "gpr r16 .32 64 0\n" "gpr r17 .32 68 0\n")
int type
Definition: mipsasm.c:17
RZ_API int rz_str_casecmp(const char *dst, const char *orig)
Definition: str.c:121
#define RZ_NEW0(x)
Definition: rz_types.h:284
Definition: z80asm.h:102
RzList * defs
Definition: rz_lang.h:20

References def(), rz_lang_t::defs, rz_list_append(), RZ_NEW0, rz_str_casecmp(), strdup(), type, and value.

Referenced by rz_core_init().

◆ rz_lang_free()

RZ_API void rz_lang_free ( RzLang lang)

Definition at line 46 of file lang.c.

46  {
47  if (lang) {
48  __lang = NULL;
49  rz_lang_undef(lang, NULL);
50  rz_list_free(lang->langs);
51  rz_list_free(lang->defs);
52  // TODO: remove langs plugins
53  free(lang);
54  }
55 }
#define NULL
Definition: cris-opc.c:27
RZ_API void rz_lang_undef(RzLang *lang, const char *name)
Definition: lang.c:91
static RzLang * __lang
Definition: lang.c:12
RZ_API void rz_list_free(RZ_NONNULL RzList *list)
Empties the list and frees the list pointer.
Definition: list.c:137

References __lang, rz_lang_t::defs, free(), rz_lang_t::langs, NULL, rz_lang_undef(), and rz_list_free().

Referenced by rz_core_fini(), and rz_lang_new().

◆ rz_lang_get_by_extension()

RZ_API RzLangPlugin* rz_lang_get_by_extension ( RzLang lang,
const char *  ext 
)

Definition at line 126 of file lang.c.

126  {
127  RzListIter *iter;
128  RzLangPlugin *h;
129  const char *p = rz_str_lchr(ext, '.');
130  if (p) {
131  ext = p + 1;
132  }
133  rz_list_foreach (lang->langs, iter, h) {
134  if (!rz_str_casecmp(h->ext, ext)) {
135  return h;
136  }
137  }
138  return NULL;
139 }
static const char ext[]
Definition: apprentice.c:1981
void * p
Definition: libc.cpp:67
RZ_API const char * rz_str_lchr(const char *str, char chr)
Definition: str.c:669
#define h(i)
Definition: sha256.c:48

References ext, h, rz_lang_t::langs, NULL, p, rz_str_casecmp(), and rz_str_lchr().

Referenced by rz_core_run_script().

◆ rz_lang_get_by_name()

RZ_API RzLangPlugin* rz_lang_get_by_name ( RzLang lang,
const char *  name 
)

Definition at line 141 of file lang.c.

141  {
142  RzListIter *iter;
143  RzLangPlugin *h;
144  rz_list_foreach (lang->langs, iter, h) {
145  if (!rz_str_casecmp(h->name, name)) {
146  return h;
147  }
148  if (h->alias && !rz_str_casecmp(h->alias, name)) {
149  return h;
150  }
151  }
152  return NULL;
153 }

References h, rz_lang_t::langs, NULL, and rz_str_casecmp().

Referenced by rz_hash_bang_handler(), rz_lang_add(), and rz_lang_use().

◆ rz_lang_new()

RZ_API RzLang* rz_lang_new ( void  )

Definition at line 20 of file lang.c.

20  {
21  RzLang *lang = RZ_NEW0(RzLang);
22  if (!lang) {
23  return NULL;
24  }
25  lang->user = NULL;
26  lang->langs = rz_list_new();
27  if (!lang->langs) {
28  rz_lang_free(lang);
29  return NULL;
30  }
32  lang->defs = rz_list_new();
33  if (!lang->defs) {
34  rz_lang_free(lang);
35  return NULL;
36  }
39  for (int i = 0; i < RZ_ARRAY_SIZE(lang_static_plugins); i++) {
41  }
42 
43  return lang;
44 }
lzma_index ** i
Definition: index.h:629
_Use_decl_annotations_ int __cdecl printf(const char *const _Format,...)
Definition: cs_driver.c:93
RZ_API void rz_lang_def_free(RzLangDef *def)
Definition: lang.c:85
static RzLangPlugin * lang_static_plugins[]
Definition: lang.c:11
RZ_API void rz_lang_plugin_free(RzLangPlugin *p)
Definition: lang.c:14
RZ_API void rz_lang_free(RzLang *lang)
Definition: lang.c:46
RZ_API bool rz_lang_add(RzLang *lang, RzLangPlugin *foo)
Definition: lang.c:115
RZ_API RZ_OWN RzList * rz_list_new(void)
Returns a new initialized RzList pointer (free method is not initialized)
Definition: list.c:235
void(* RzListFree)(void *ptr)
Definition: rz_list.h:11
int(* PrintfCallback)(const char *str,...) RZ_PRINTF_CHECK(1
Definition: rz_types.h:233
#define RZ_ARRAY_SIZE(x)
Definition: rz_types.h:300
void * user
Definition: rz_lang.h:19
PrintfCallback cb_printf
Definition: rz_lang.h:22
RzListFree free
Definition: rz_list.h:21

References rz_lang_t::cb_printf, rz_lang_t::defs, rz_list_t::free, i, lang_static_plugins, rz_lang_t::langs, NULL, printf(), RZ_ARRAY_SIZE, rz_lang_add(), rz_lang_def_free(), rz_lang_free(), rz_lang_plugin_free(), rz_list_new(), RZ_NEW0, and rz_lang_t::user.

Referenced by rz_core_init().

◆ rz_lang_plugin_free()

RZ_API void rz_lang_plugin_free ( RzLangPlugin p)

Definition at line 14 of file lang.c.

14  {
15  if (p && p->fini) {
16  p->fini(__lang);
17  }
18 }

References __lang, and p.

Referenced by rz_lang_new().

◆ rz_lang_prompt()

RZ_API int rz_lang_prompt ( RzLang lang)

Definition at line 205 of file lang.c.

205  {
206  char buf[1024];
207  const char *p;
208 
209  if (!lang || !lang->cur) {
210  return false;
211  }
212 
213  if (lang->cur->prompt && lang->cur->prompt(lang)) {
214  return true;
215  }
216  /* init line */
218  RzLineHistory hist = line->history;
219  RzLineHistory histnull = { 0 };
220  RzLineCompletion oc = line->completion;
221  RzLineCompletion ocnull = { 0 };
222  char *prompt = strdup(line->prompt);
223  line->completion = ocnull;
224  line->history = histnull;
225 
226  /* foo */
227  for (;;) {
228  rz_cons_flush();
229  snprintf(buf, sizeof(buf) - 1, "%s> ", lang->cur->name);
231  p = rz_line_readline();
232  if (!p) {
233  break;
234  }
236  strncpy(buf, p, sizeof(buf) - 1);
237  if (*buf == '!') {
238  if (buf[1]) {
239  rz_sys_xsystem(buf + 1);
240  }
241  continue;
242  }
243  if (!memcmp(buf, ". ", 2)) {
244  char *file = rz_file_abspath(buf + 2);
245  if (file) {
246  rz_lang_run_file(lang, file);
247  free(file);
248  }
249  continue;
250  }
251  if (!strcmp(buf, "q")) {
252  free(prompt);
253  return true;
254  }
255  if (!strcmp(buf, "?")) {
256  RzLangDef *def;
257  RzListIter *iter;
258  eprintf(" ? - show this help message\n"
259  " !command - run system command\n"
260  " . file - interpret file\n"
261  " q - quit prompt\n");
262  eprintf("%s example:\n", lang->cur->name);
263  if (lang->cur->help) {
264  eprintf("%s", *lang->cur->help);
265  }
266  if (!rz_list_empty(lang->defs)) {
267  eprintf("variables:\n");
268  }
269  rz_list_foreach (lang->defs, iter, def) {
270  eprintf(" %s %s\n", def->type, def->name);
271  }
272  } else {
273  rz_lang_run(lang, buf, strlen(buf));
274  }
275  }
276  // XXX: leaking history
278  line->completion = oc;
279  line->history = hist;
280  clearerr(stdin);
281  printf("\n");
282  free(prompt);
283  return true;
284 }
RZ_API void rz_cons_flush(void)
Definition: cons.c:959
RZ_API const char * rz_line_readline(void)
Definition: dietline.c:913
RZ_API int rz_line_hist_add(const char *line)
Definition: dietline.c:382
voidpf void * buf
Definition: ioapi.h:138
snprintf
Definition: kernel.h:364
RZ_API int rz_lang_run(RzLang *lang, const char *code, int len)
Definition: lang.c:172
RZ_API int rz_lang_run_file(RzLang *lang, const char *file)
Definition: lang.c:183
RZ_API RzLine * rz_line_singleton(void)
Definition: line.c:15
RZ_API void rz_line_set_prompt(const char *prompt)
Definition: line.c:56
line
Definition: setup.py:34
#define eprintf(x, y...)
Definition: rlcc.c:7
RZ_API char * rz_file_abspath(const char *file)
Definition: file.c:267
#define rz_sys_xsystem(cmd)
Definition: rz_sys.h:83
Definition: gzappend.c:170
const char ** help
Definition: rz_lang.h:32
int(* prompt)(RzLang *user)
Definition: rz_lang.h:37
const char * name
Definition: rz_lang.h:28
struct rz_lang_plugin_t * cur
Definition: rz_lang.h:18
static char * prompt(const char *str, const char *txt)
Definition: vmenus.c:30

References rz_lang_t::cur, def(), rz_lang_t::defs, eprintf, free(), rz_lang_plugin_t::help, setup::line, rz_lang_plugin_t::name, p, printf(), prompt(), rz_lang_plugin_t::prompt, rz_cons_flush(), rz_file_abspath(), rz_lang_run(), rz_lang_run_file(), rz_line_hist_add(), rz_line_readline(), rz_line_set_prompt(), rz_line_singleton(), rz_sys_xsystem, snprintf, and strdup().

Referenced by rz_hash_bang_handler().

◆ rz_lang_run()

RZ_API int rz_lang_run ( RzLang lang,
const char *  code,
int  len 
)

Definition at line 172 of file lang.c.

172  {
173  if (lang->cur && lang->cur->run) {
174  return lang->cur->run(lang, code, len);
175  }
176  return false;
177 }
size_t len
Definition: 6502dis.c:15
Definition: inftree9.h:24
int(* run)(RzLang *user, const char *code, int len)
Definition: rz_lang.h:38

References rz_lang_t::cur, len, and rz_lang_plugin_t::run.

Referenced by rz_lang_prompt(), and rz_lang_run_string().

◆ rz_lang_run_file()

RZ_API int rz_lang_run_file ( RzLang lang,
const char *  file 
)

Definition at line 183 of file lang.c.

183  {
184  int ret = false;
185  if (lang->cur) {
186  if (!lang->cur->run_file) {
187  if (lang->cur->run) {
188  size_t len;
189  char *code = rz_file_slurp(file, &len);
190  if (!code) {
191  eprintf("Could not open '%s'.\n", file);
192  return 0;
193  }
194  ret = lang->cur->run(lang, code, (int)len);
195  free(code);
196  }
197  } else {
198  ret = lang->cur->run_file(lang, file);
199  }
200  }
201  return ret;
202 }
RZ_API RZ_OWN char * rz_file_slurp(const char *str, RZ_NULLABLE size_t *usz)
Definition: file.c:454
int(* run_file)(RzLang *user, const char *file)
Definition: rz_lang.h:39

References rz_lang_t::cur, eprintf, free(), len, rz_lang_plugin_t::run, rz_lang_plugin_t::run_file, and rz_file_slurp().

Referenced by lang_run_file(), rz_hash_bang_handler(), and rz_lang_prompt().

◆ rz_lang_run_string()

RZ_API int rz_lang_run_string ( RzLang lang,
const char *  code 
)

Definition at line 179 of file lang.c.

179  {
180  return rz_lang_run(lang, code, strlen(code));
181 }

References rz_lang_run().

◆ rz_lang_set_argv()

RZ_API bool rz_lang_set_argv ( RzLang lang,
int  argc,
char **  argv 
)

Definition at line 165 of file lang.c.

165  {
166  if (lang->cur && lang->cur->set_argv) {
167  return lang->cur->set_argv(lang, argc, argv);
168  }
169  return false;
170 }
static static fork const void static count static fd const char const char static newpath char char argv
Definition: sflib.h:40
int(* set_argv)(RzLang *user, int argc, char **argv)
Definition: rz_lang.h:40

References argv, rz_lang_t::cur, and rz_lang_plugin_t::set_argv.

Referenced by rz_hash_bang_handler().

◆ rz_lang_set_user_ptr()

RZ_API void rz_lang_set_user_ptr ( RzLang lang,
void *  user 
)

Definition at line 61 of file lang.c.

61  {
62  lang->user = user;
63 }

References rz_lang_t::user.

Referenced by rz_core_init().

◆ rz_lang_setup()

RZ_API bool rz_lang_setup ( RzLang lang)

Definition at line 108 of file lang.c.

108  {
109  if (lang && lang->cur && lang->cur->setup) {
110  return lang->cur->setup(lang);
111  }
112  return false;
113 }
bool(* setup)(RzLang *user)
Definition: rz_lang.h:35

References rz_lang_t::cur, and rz_lang_plugin_t::setup.

◆ rz_lang_undef()

RZ_API void rz_lang_undef ( RzLang lang,
const char *  name 
)

Definition at line 91 of file lang.c.

91  {
92  if (name && *name) {
93  RzLangDef *def;
95  /* No _safe loop necessary because we return immediately after the delete. */
96  rz_list_foreach (lang->defs, iter, def) {
97  if (!name || !rz_str_casecmp(name, def->name)) {
98  rz_list_delete(lang->defs, iter);
99  break;
100  }
101  }
102  } else {
103  rz_list_free(lang->defs);
104  lang->defs = NULL;
105  }
106 }
RZ_API void rz_list_delete(RZ_NONNULL RzList *list, RZ_NONNULL RzListIter *iter)
Removes an entry in the list by using the RzListIter pointer.
Definition: list.c:162

References def(), rz_lang_t::defs, NULL, rz_list_delete(), rz_list_free(), and rz_str_casecmp().

Referenced by rz_lang_free().

◆ rz_lang_use()

RZ_API bool rz_lang_use ( RzLang lang,
const char *  name 
)

Definition at line 155 of file lang.c.

155  {
157  if (h) {
158  lang->cur = h;
159  return true;
160  }
161  return false;
162 }

References rz_lang_t::cur, h, and rz_lang_get_by_name().

Referenced by rz_core_run_script().

◆ RZ_LIB_VERSION()

RZ_LIB_VERSION ( rz_lang  )

Variable Documentation

◆ __lang

RzLang* __lang = NULL
static

Definition at line 12 of file lang.c.

Referenced by rz_lang_free(), and rz_lang_plugin_free().

◆ lang_static_plugins

RzLangPlugin* lang_static_plugins[] = { RZ_LANG_STATIC_PLUGINS }
static

Definition at line 11 of file lang.c.

Referenced by rz_lang_new().