Rizin
unix-like reverse engineering framework and cli tools
cautocmpl.c
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2020 ret2libc <sirmy15@gmail.com>
2 // SPDX-License-Identifier: LGPL-3.0-only
3 
4 #include <tree_sitter/api.h>
5 #include <rz_core.h>
6 #include <rz_cons.h>
7 #include <rz_cmd.h>
8 
9 #include "core_private.h"
10 
28 };
29 
35  enum autocmplt_type_t type;
37  const RzCmdDesc *cd;
38  size_t i_arg;
39 };
40 
46  const char *s;
47  size_t len;
48 };
49 
54 struct guess_data_t {
55  char *input;
59 };
60 
61 static void guess_data_free(struct guess_data_t *g) {
62  ts_tree_delete(g->tree);
63  ts_parser_delete(g->parser);
64  free(g->input);
65  free(g);
66 }
67 
74 static struct guess_data_t *guess_next_autocmplt_token(RzCore *core, RzLineBuffer *buf, const char *fake_text, size_t offset) {
75  size_t fake_len = strlen(fake_text);
76  char *tmp = malloc(strlen(buf->data) + 1 + fake_len);
77  memcpy(tmp, buf->data, buf->index);
78  memcpy(tmp + buf->index, fake_text, fake_len);
79  memcpy(tmp + buf->index + fake_len, buf->data + buf->index, buf->length - buf->index);
80  tmp[buf->length + fake_len] = '\0';
81  RZ_LOG_DEBUG("guess_next_autocmplt_token = '%s'\n", tmp);
82 
85  TSTree *tree = ts_parser_parse_string(parser, NULL, tmp, buf->length + fake_len);
88  if (ts_node_is_null(node)) {
89  goto err;
90  }
91 
92  struct guess_data_t *g = RZ_NEW0(struct guess_data_t);
93  g->node = node;
94  g->tree = tree;
95  g->parser = parser;
96  g->input = tmp;
97  return g;
98 
99 err:
102  free(tmp);
103  return NULL;
104 }
105 
106 static bool do_autocmplt_cmdidentifier(RzCmd *cmd, const RzCmdDesc *desc, void *user) {
107  struct autocmplt_cmdidentifier_t *u = (struct autocmplt_cmdidentifier_t *)user;
108  if (!strncmp(desc->name, u->s, u->len)) {
110  }
111  return true;
112 }
113 
114 static void autocmplt_cmdidentifier(RzCore *core, RzLineNSCompletionResult *res, const char *s, size_t len) {
115  struct autocmplt_cmdidentifier_t u = {
116  .res = res,
117  .s = s,
118  .len = len,
119  };
121 }
122 
123 static void autocmplt_at_stmt(RzCore *core, RzLineNSCompletionResult *res, const char *s, size_t len) {
124  const char *stmts[] = {
125  "@ ",
126  "@!",
127  "@(",
128  "@a:",
129  "@b:",
130  "@B:",
131  "@e:",
132  "@f:",
133  "@F:",
134  "@i:",
135  "@k:",
136  "@o:",
137  "@r:",
138  "@s:",
139  "@v:",
140  "@x:",
141  "@@.",
142  "@@=",
143  "@@@=",
144  "@@",
145  "@@c:",
146  "@@@c:",
147  "@@C",
148  "@@C:",
149  "@@dbt",
150  "@@dbtb",
151  "@@dbts",
152  "@@t",
153  "@@b",
154  "@@i",
155  "@@ii",
156  "@@iS",
157  "@@iSS",
158  "@@is",
159  "@@iz",
160  "@@f",
161  "@@f:",
162  "@@F",
163  "@@F:",
164  "@@om",
165  "@@dm",
166  "@@r",
167  "@@s:",
168  NULL,
169  };
170  const char **stmt;
171  for (stmt = stmts; *stmt; stmt++) {
172  if (!strncmp(*stmt, s, len)) {
174  }
175  }
176  res->end_string = "";
177 }
178 
179 static void autocmplt_bits_plugin(RzAsmPlugin *plugin, RzLineNSCompletionResult *res, const char *s, size_t len) {
180  int bits = plugin->bits;
181  int i;
182  char sbits[5];
183  for (i = 1; i <= bits; i <<= 1) {
184  if (i & bits && !strncmp(rz_strf(sbits, "%d", i), s, len)) {
186  }
187  }
188 }
189 
190 static void autocmplt_arch(RzCore *core, RzLineNSCompletionResult *res, const char *s, size_t len) {
191  rz_return_if_fail(core->rasm);
192 
193  RzList *asm_plugins = rz_asm_get_plugins(core->rasm);
194  RzListIter *it;
195  RzAsmPlugin *plugin;
196 
197  // @a: can either be used with @a:arch or @a:arch:bits
198  // Check for `:` to determine where we are
199  const char *delim = rz_sub_str_rchr(s, 0, len, ':');
200  if (!delim) {
201  // We autocomplete just the architecture part
202  rz_list_foreach (asm_plugins, it, plugin) {
203  if (!strncmp(plugin->name, s, len)) {
205  }
206  }
207  res->end_string = "";
208  } else {
209  // We autocomplete the bits part
210  res->start += delim + 1 - s;
211  rz_list_foreach (asm_plugins, it, plugin) {
212  if (!strncmp(plugin->name, s, delim - s)) {
213  autocmplt_bits_plugin(plugin, res, delim + 1, len - (delim + 1 - s));
214  break;
215  }
216  }
217  }
218 }
219 
220 static void autocmplt_bits(RzCore *core, RzLineNSCompletionResult *res, const char *s, size_t len) {
221  rz_return_if_fail(core->rasm && core->rasm->cur);
222 
223  autocmplt_bits_plugin(core->rasm->cur, res, s, len);
224 }
225 
226 static void autocmplt_flag_space(RzCore *core, RzLineNSCompletionResult *res, const char *s, size_t len) {
227  RzSpace *space;
228  RBIter it;
229 
230  rz_flag_space_foreach(core->flags, it, space) {
231  if (!strncmp(space->name, s, len)) {
233  }
234  }
235  if (len == 0) {
237  }
238 }
239 
240 static void autocmplt_reg(RzCore *core, RzLineNSCompletionResult *res, const char *s, size_t len) {
241  RzReg *reg = rz_core_reg_default(core);
243  RzListIter *it;
244  RzRegItem *regitem;
245 
246  rz_list_foreach (regs, it, regitem) {
247  if (!strncmp(regitem->name, s, len)) {
249  }
250  }
251 }
252 
253 static void autocmplt_cmd_arg_file(RzLineNSCompletionResult *res, const char *s, size_t len) {
254  char *input = rz_str_ndup(s, len);
255  if (!input) {
256  return;
257  }
258 
259  if (RZ_STR_ISEMPTY(input)) {
260  free(input);
261  input = strdup(".");
262  } else if (!rz_file_is_abspath(input) && !rz_str_startswith(input, ".")) {
263  const char *fmt = ".%s%s";
264 #if __WINDOWS__
265  if (strchr(input, ':')) {
266  fmt = "%.0s%s";
267  }
268 #endif
269  char *tmp = rz_str_newf(fmt, RZ_SYS_DIR, input);
270  if (!tmp) {
271  return;
272  }
273  free(input);
274  input = tmp;
275  }
276  char *einput = rz_path_home_expand(input);
277  free(input);
278 
279  char *basedir = rz_file_dirname(einput);
280  const char *basename = rz_file_basename(einput + 1);
281 #if __WINDOWS__
282  rz_str_replace_ch(basedir, '/', '\\', true);
283 #endif
284 
285  RzList *l = rz_sys_dir(basedir);
286  RzListIter *iter;
287  char *filename;
288  rz_list_foreach (l, iter, filename) {
289  if (!strcmp(filename, ".") || !strcmp(filename, "..")) {
290  continue;
291  }
292  if (!strncmp(filename, basename, strlen(basename))) {
293  // TODO: only show/autocomplete the last part of the path, not the whole path
294  char *tmpfilename = rz_file_path_join(basedir, filename);
295  if (rz_file_is_directory(tmpfilename)) {
297  }
299  free(tmpfilename);
300  }
301  }
302  rz_list_free(l);
303  free(basedir);
304  free(einput);
305 }
306 
307 static void autocmplt_cmd_arg_env(RzLineNSCompletionResult *res, const char *s, size_t len) {
308  char **env;
309  res->end_string = "";
310  for (env = rz_sys_get_environ(); *env; env++) {
311  const char *eq = strchr(*env, '=');
312  char *envkey = eq ? rz_str_ndup(*env, eq - *env) : strdup(*env);
313  if (!strncmp(envkey, s, len)) {
315  }
316  free(envkey);
317  }
318 }
319 
320 static void autocmplt_cmd_arg_macro(RzCore *core, RzLineNSCompletionResult *res, const char *s, size_t len) {
321  RzCmdMacroItem *item;
322  RzListIter *iter;
323  rz_list_foreach (core->rcmd->macro.macros, iter, item) {
324  char *p = item->name;
325  if (!strncmp(p, s, len)) {
327  }
328  }
329 }
330 
331 static void autocmplt_cmd_arg_flag(RzCore *core, RzLineNSCompletionResult *res, const char *s, size_t len) {
332  RzFlagItem *item;
333  RzListIter *iter;
334  RzList *list = rz_flag_all_list(core->flags, false);
335  rz_list_foreach (list, iter, item) {
336  char *flag = item->name;
337  if (!strncmp(flag, s, len)) {
339  }
340  }
342 }
343 
344 static bool offset_prompt_add_flag(RzFlagItem *fi, void *user) {
347  return true;
348 }
349 
350 static void autocmplt_cmd_arg_fcn(RzCore *core, RzLineNSCompletionResult *res, const char *s, size_t len) {
351  RzListIter *iter;
352  RzAnalysisFunction *fcn;
353  rz_list_foreach (core->analysis->fcns, iter, fcn) {
354  char *name = rz_core_analysis_fcn_name(core, fcn);
355  if (!strncmp(name, s, len)) {
357  }
358  free(name);
359  }
360 }
361 
362 static void autocmplt_cmd_arg_enum_type(RzCore *core, RzLineNSCompletionResult *res, const char *s, size_t len) {
363  char *item;
364  RzListIter *iter;
366  rz_list_foreach (list, iter, item) {
367  if (!strncmp(item, s, len)) {
369  }
370  }
372 }
373 
374 static void autocmplt_cmd_arg_struct_type(RzCore *core, RzLineNSCompletionResult *res, const char *s, size_t len) {
375  char *item;
376  RzListIter *iter;
378  rz_list_foreach (list, iter, item) {
379  if (!strncmp(item, s, len)) {
381  }
382  }
384 }
385 
386 static void autocmplt_cmd_arg_union_type(RzCore *core, RzLineNSCompletionResult *res, const char *s, size_t len) {
387  char *item;
388  RzListIter *iter;
390  rz_list_foreach (list, iter, item) {
391  if (!strncmp(item, s, len)) {
393  }
394  }
396 }
397 
398 static void autocmplt_cmd_arg_alias_type(RzCore *core, RzLineNSCompletionResult *res, const char *s, size_t len) {
399  char *item;
400  RzListIter *iter;
402  rz_list_foreach (list, iter, item) {
403  if (!strncmp(item, s, len)) {
405  }
406  }
408 }
409 
410 static void autocmplt_cmd_arg_any_type(RzCore *core, RzLineNSCompletionResult *res, const char *s, size_t len) {
411  char *item;
412  RzListIter *iter;
414  rz_list_foreach (list, iter, item) {
415  if (!strncmp(item, s, len)) {
417  }
418  }
420 }
421 
422 static void autocmplt_cmd_arg_global_var(RzCore *core, RzLineNSCompletionResult *res, const char *s, size_t len) {
423  RzAnalysisVarGlobal *glob;
424  RzListIter *iter;
426  rz_list_foreach (list, iter, glob) {
427  char *name = glob->name;
428  if (!strncmp(name, s, len)) {
430  }
431  }
433 }
434 
435 static void autocmplt_cmd_arg_reg_filter(RzCore *core, const RzCmdDesc *cd, RzLineNSCompletionResult *res, const char *s, size_t len) {
436  bool is_analysis = cd->name && cd->name[0] == 'a';
437  RzReg *reg = is_analysis ? core->analysis->reg : core->dbg->reg;
438  if (!reg) {
439  return;
440  }
441 
448 
449  for (int type = 0; type < RZ_REG_TYPE_LAST; type++) {
450  const char *name = rz_reg_get_type(type);
451  if (!name) {
452  continue;
453  }
455  }
457 
458  for (int role = 0; role < RZ_REG_NAME_LAST; role++) {
459  if (!reg->name[role]) {
460  // don't autocomplete if there isn't a register with this role anyway
461  continue;
462  }
463  const char *name = rz_reg_get_role(role);
464  if (!name) {
465  continue;
466  }
468  }
469 
470  RzListIter *iter;
471  RzRegItem *ri;
472  rz_list_foreach (reg->allregs, iter, ri) {
473  if (!ri->name) {
474  continue;
475  }
477  }
478 }
479 
480 static void autocmplt_cmd_arg_reg_type(RzCore *core, const RzCmdDesc *cd, RzLineNSCompletionResult *res, const char *s, size_t len) {
481  for (int t = 0; t < RZ_REG_TYPE_LAST; t++) {
483  }
484 }
485 
486 static void autocmplt_cmd_arg_help_var(RzCore *core, RzLineNSCompletionResult *res, const char *s, size_t len) {
487  const char **vars = rz_core_help_vars_get(core);
488  while (*vars) {
489  if (!strncmp(*vars, s, len)) {
491  }
492  vars++;
493  }
494 }
495 
496 static bool is_op_ch(char ch) {
497  return ch == '+' || ch == '-' || ch == '*' || ch == '/' || ch == '%' ||
498  ch == '>' || ch == '<';
499 }
500 
501 static void autocmplt_cmd_arg_rznum(RzCore *core, RzLineNSCompletionResult *res, const char *s, size_t len) {
502  if (len > 0) {
503  // If the argument is composed of a complex expression with some
504  // operator, autocomplete only the last part
505  const char *p;
506  size_t plen;
507  for (p = s, plen = len; *p && plen > 0; p++, plen--) {
508  if (is_op_ch(*p)) {
509  res->start += p + 1 - s;
510  s = p + 1;
511  len = plen - 1;
512  }
513  }
514  }
515  autocmplt_cmd_arg_fcn(core, res, s, len);
518 }
519 
520 static void autocmplt_cmd_arg_choices(RzCore *core, RzLineNSCompletionResult *res, const char *s, size_t len, const RzCmdDescArg *arg) {
521  char **oc, **c;
522  oc = c = arg->choices_cb ? arg->choices_cb(core) : (char **)arg->choices;
523  for (c = oc; c && *c; c++) {
524  if (!strncmp(*c, s, len)) {
526  }
527  }
528  if (arg->choices_cb) {
529  for (c = oc; c && *c; c++) {
530  free(*c);
531  }
532  free(oc);
533  }
534 }
535 
536 static void autocmplt_cmd_arg_eval_key(RzCore *core, RzLineNSCompletionResult *res, const char *s, size_t len) {
537  RzListIter *iter;
538  RzConfigNode *bt;
539  rz_list_foreach (core->config->nodes, iter, bt) {
540  if (!strncmp(bt->name, s, len)) {
542  }
543  }
544 }
545 
546 static void autocmplt_cmd_arg_eval_full(RzCore *core, RzLineNSCompletionResult *res, const char *s, size_t len) {
547  char *eq = (char *)rz_sub_str_rchr(s, 0, len, '=');
548  if (!eq) {
549  // autocomplete only the key
550  res->end_string = "";
552  return;
553  }
554 
555  char *k = rz_str_ndup(s, eq - s);
556  char *v = NULL;
557  RzConfigNode *node = rz_config_node_get(core->config, k);
558  if (!node) {
559  goto err;
560  }
561 
562  v = rz_str_ndup(eq + 1, len - (eq - s) - 1);
563  len = strlen(v);
564 
565  res->start += strlen(k) + 1;
566 
567  if (node->options && rz_list_length(node->options)) {
568  RzListIter *iter;
569  char *opt;
570  rz_list_foreach (node->options, iter, opt) {
571  if (!strncmp(opt, v, len)) {
573  }
574  }
575  } else if (rz_config_node_is_bool(node)) {
576  if (!strncmp("true", v, len)) {
578  }
579  if (!strncmp("false", v, len)) {
581  }
582  }
583 
584 err:
585  free(v);
586  free(k);
587 }
588 
589 static void autocmplt_cmd_arg_fcn_var(RzCore *core, RzLineNSCompletionResult *res, const char *s, size_t len) {
591  if (!fcn) {
592  return;
593  }
594  RzList *vars = rz_analysis_var_all_list(core->analysis, fcn);
595  RzListIter *iter;
596  RzAnalysisVar *var;
597  rz_list_foreach (vars, iter, var) {
598  if (!strncmp(var->name, s, len)) {
600  }
601  }
602  rz_list_free(vars);
603 }
604 
605 static bool is_arg_type(const char *type) {
606  return !strcmp(type, "concatenation") || !strcmp(type, "arg") ||
607  !strcmp(type, "args") || !strcmp(type, "arg_identifier") ||
608  !strcmp(type, "double_quoted_arg") || !strcmp(type, "single_quoted_arg");
609 }
610 
611 static RzCmdDesc *get_cd_from_cmdid(RzCore *core, const char *data, TSNode cmd_id) {
612  ut32 command_start = ts_node_start_byte(cmd_id);
613  ut32 command_end = ts_node_end_byte(cmd_id);
614  char *cmdid = rz_str_ndup(data + command_start, command_end - command_start);
616  free(cmdid);
617  return cd;
618 }
619 
620 static RzCmdDesc *get_cd_from_arg(RzCore *core, const char *data, TSNode arg) {
621  if (ts_node_is_null(arg)) {
622  return NULL;
623  }
624  const char *parent_type;
625  TSNode parent = arg;
626  do {
627  parent = ts_node_parent(parent);
628  if (ts_node_is_null(parent)) {
629  return NULL;
630  }
631  parent_type = ts_node_type(parent);
632  } while (is_arg_type(parent_type));
633 
634  if (strcmp(parent_type, "arged_stmt")) {
635  return NULL;
636  }
637 
638  TSNode cmdid = ts_node_named_child(parent, 0);
639  const char *node_type = ts_node_is_null(cmdid) ? "" : ts_node_type(cmdid);
640  if (strcmp(node_type, "cmd_identifier")) {
641  return false;
642  }
643 
644  return get_cd_from_cmdid(core, data, cmdid);
645 }
646 
647 static size_t get_arg_number(TSNode arg) {
648  const char *arg_type = ts_node_type(arg);
649  while (strcmp(arg_type, "arg")) {
651  arg_type = ts_node_type(arg);
652  }
653 
654  size_t i_arg = 0;
656  while (!ts_node_is_null(arg)) {
657  i_arg++;
659  }
660  return i_arg;
661 }
662 
667 static void autocmplt_cmd_arg(RzCore *core, RzLineNSCompletionResult *res, const RzCmdDesc *cd, size_t i_arg, const char *s, size_t len) {
668  const RzCmdDescArg *arg = rz_cmd_desc_get_arg(core->rcmd, cd, i_arg);
669  if (!arg) {
670  return;
671  }
672 
673  RzCmdArgType arg_type = arg->type;
674  switch (arg_type) {
677  break;
678  case RZ_CMD_ARG_TYPE_ENV:
680  break;
683  break;
684  case RZ_CMD_ARG_TYPE_FCN:
685  autocmplt_cmd_arg_fcn(core, res, s, len);
686  break;
688  autocmplt_cmd_arg_macro(core, res, s, len);
689  break;
691  autocmplt_cmd_arg_rznum(core, res, s, len);
692  break;
695  break;
698  break;
701  break;
703  autocmplt_cmd_arg_flag(core, res, s, len);
704  break;
707  break;
710  break;
713  break;
716  break;
719  break;
722  break;
725  break;
728  break;
729  default:
730  break;
731  }
732 }
733 
735  ad->type = type;
737  return true;
738 }
739 
746 }
747 
753 static bool fill_autocmplt_data_cmdarg(struct autocmplt_data_t *ad, ut32 start, ut32 end, const char *s, TSNode node, RzCore *core) {
754  ad->type = AUTOCMPLT_CMD_ARG;
755  ad->cd = get_cd_from_arg(core, s, node);
756  if (!ad->cd) {
757  return false;
758  }
759 
760  ad->i_arg = get_arg_number(node);
761 
762  const RzCmdDescArg *arg = rz_cmd_desc_get_arg(core->rcmd, ad->cd, ad->i_arg);
763  if (!arg) {
764  return false;
765  }
766 
768  return true;
769 }
770 
777 }
778 
780  bool res = false;
781  struct guess_data_t *g = guess_next_autocmplt_token(core, buf, "a", 0);
782  if (g) {
783  const char *node_type = ts_node_type(g->node);
784  ut32 node_start = ts_node_start_byte(g->node);
785  if (!strcmp(node_type, "cmd_identifier")) {
786  res = fill_autocmplt_data_cmdid(ad, node_start, node_start);
787  } else if (is_arg_type(node_type)) {
788  res = fill_autocmplt_data_cmdarg(ad, node_start, node_start, g->input, g->node, core);
789  }
791  }
792  return res;
793 }
794 
798  }
799  return node;
800 }
801 
803  if (!is_arg_type(ts_node_type(node))) {
804  return false;
805  }
807  if (ts_node_is_null(node)) {
808  return false;
809  }
810  const char *node_type = ts_node_type(node);
811  bool is_iter_or_tmp = rz_str_startswith(node_type, "tmp_") || rz_str_startswith(node_type, "iter_");
812  return is_iter_or_tmp && rz_str_endswith(node_type, "_stmt");
813 }
814 
816  bool res = false;
817  if (buf->index > 1 && buf->data[buf->index - 1] == '@' && buf->data[buf->index - 2] == '@') {
818  struct guess_data_t *g = guess_next_autocmplt_token(core, buf, "=a", 1);
819  if (g) {
820  ut32 node_start = ts_node_start_byte(g->node);
821  ut32 node_end = ts_node_end_byte(g->node);
822  ut32 start = node_start - 3;
823  if (buf->index > 2 && buf->data[buf->index - 3] == '@') {
824  start--;
825  node_start--;
826  }
827  if (is_arg_identifier_in_tmp_stmt(g->node) && node_start > 3) {
828  res = fill_autocmplt_data_at_stmt(ad, start, node_end - 2);
829  }
831  }
832  } else if (buf->index > 0 && buf->data[buf->index - 1] == '@') {
833  struct guess_data_t *g = guess_next_autocmplt_token(core, buf, " a", 1);
834  if (g) {
835  ut32 node_start = ts_node_start_byte(g->node);
836  ut32 node_end = ts_node_end_byte(g->node);
837  if (is_arg_identifier_in_tmp_stmt(g->node) && node_start > 2) {
838  res = fill_autocmplt_data_at_stmt(ad, node_start - 2, node_end - 2);
839  }
841  }
842  }
843  if (res) {
844  return res;
845  }
846 
847  char *start_iter = buf->data + buf->index;
848  char *p = start_iter;
849  // 4 is the longest @@ iter command (see @@dbta)
850  // We don't care to look for the @@ pattern before that point, because it
851  // wouldn't be a valid command anyway
852  char *maximum_search = buf->index > 4 ? start_iter - 4 : start_iter;
853  while (p > buf->data + 2 && p > maximum_search && !(*(p - 1) == '@' && *(p - 2) == '@') && *p != ' ') {
854  p--;
855  }
856  if (p > buf->data + 2 && p > maximum_search && p + 4 - buf->data < RZ_LINE_BUFSIZE && *(p - 3) == '@' && *p != ' ') {
857  // This handles the case <cmd> @@@c<TAB>
858  int idx = buf->index;
859  buf->index = p - buf->data + 1;
860  char last_char = buf->data[buf->index - 1];
861  buf->data[buf->index - 1] = '=';
862  struct guess_data_t *g = guess_next_autocmplt_token(core, buf, "a", 0);
863  buf->data[buf->index - 1] = last_char;
864  buf->index = idx;
865  if (g) {
866  if (is_arg_identifier_in_tmp_stmt(g->node)) {
867  res = fill_autocmplt_data_at_stmt(ad, p - buf->data - 3, buf->index);
868  }
870  }
871  } else if (p > buf->data + 2 && p > maximum_search && p + 4 - buf->data < RZ_LINE_BUFSIZE && *p != ' ') {
872  // This handles the cases <cmd> @@d<TAB> and similar
873  int idx = buf->index;
874  buf->index = p - buf->data + 1;
875  char last_char = buf->data[buf->index - 1];
876  buf->data[buf->index - 1] = 'd';
877  struct guess_data_t *g = guess_next_autocmplt_token(core, buf, "bta", 2);
878  buf->data[buf->index - 1] = last_char;
879  buf->index = idx;
880  if (g) {
881  const char *node_type = ts_node_type(g->node);
882  if (!strcmp(node_type, "iter_dbta_stmt")) {
883  res = fill_autocmplt_data_at_stmt(ad, p - buf->data - 2, buf->index);
884  }
886  }
887  } else if (buf->index > 1 && buf->data[buf->index - 2] == '@') {
888  // This handles the cases <cmd> @v<TAB> and similar
889  struct guess_data_t *g = guess_next_autocmplt_token(core, buf, ":a", 1);
890  if (g) {
891  ut32 node_start = ts_node_start_byte(g->node);
892  ut32 node_end = ts_node_end_byte(g->node);
893  if (is_arg_identifier_in_tmp_stmt(g->node) && node_start > 3 && node_end > 2) {
894  res = fill_autocmplt_data_at_stmt(ad, node_start - 3, node_end - 2);
895  }
897  }
898  }
899  return res;
900 }
901 
903  const char *tmp_op, const char *newtext, enum autocmplt_type_t ad_type) {
904  bool res = false;
905  struct guess_data_t *g = guess_next_autocmplt_token(core, buf, newtext, 0);
906  if (g) {
907  ut32 node_start = ts_node_start_byte(g->node);
908  ut32 node_end = ts_node_end_byte(g->node);
909  const char *node_type = ts_node_type(g->node);
910  TSNode parent = get_arg_parent(g->node);
911  if (!ts_node_is_null(parent)) {
912  const char *parent_type = ts_node_type(parent);
913  if (!strcmp(node_type, "arg_identifier") && !strcmp(parent_type, tmp_op)) {
914  res = fill_autocmplt_data(ad, ad_type, node_start, node_end - 1);
915  }
916  }
918  }
919  return res;
920 }
921 
922 static bool find_autocmplt_type_quoted_arg(struct autocmplt_data_t *ad, RzCore *core, RzLineBuffer *buf, const char *quote, const char *quote_node_type) {
923  bool res = false;
924  struct guess_data_t *g = guess_next_autocmplt_token(core, buf, quote, 0);
925  if (g) {
926  const char *node_type = ts_node_type(g->node);
927  ut32 node_start = ts_node_start_byte(g->node);
928  ut32 node_end = ts_node_end_byte(g->node);
929  if (!strcmp(node_type, quote_node_type) && !ts_node_has_error(g->node)) {
930  res = fill_autocmplt_data_cmdarg(ad, node_start + 1, node_end - 1, g->input, g->node, core);
931  }
933  }
934  return res;
935 }
936 
938  TSNode parent = get_arg_parent(root);
939  if (!ts_node_is_null(parent) && !strcmp(ts_node_type(parent), "tmp_seek_stmt")) {
940  return fill_autocmplt_data(ad, AUTOCMPLT_RZNUM, lstart, lend);
941  } else if (!ts_node_is_null(parent) && !strcmp(ts_node_type(parent), "tmp_fromto_stmt")) {
942  return fill_autocmplt_data(ad, AUTOCMPLT_RZNUM, lstart, lend);
943  } else if (!ts_node_is_null(parent) && !strcmp(ts_node_type(parent), "tmp_arch_stmt")) {
944  return fill_autocmplt_data(ad, AUTOCMPLT_ARCH, lstart, lend);
945  } else if (!ts_node_is_null(parent) && !strcmp(ts_node_type(parent), "tmp_bits_stmt")) {
946  return fill_autocmplt_data(ad, AUTOCMPLT_BITS, lstart, lend);
947  } else if (!ts_node_is_null(parent) && !strcmp(ts_node_type(parent), "tmp_file_stmt")) {
948  return fill_autocmplt_data(ad, AUTOCMPLT_FILE, lstart, lend);
949  } else if (!ts_node_is_null(parent) && !strcmp(ts_node_type(parent), "tmp_fs_stmt")) {
950  return fill_autocmplt_data(ad, AUTOCMPLT_FLAG_SPACE, lstart, lend);
951  } else if (!ts_node_is_null(parent) && !strcmp(ts_node_type(parent), "tmp_reg_stmt")) {
952  return fill_autocmplt_data(ad, AUTOCMPLT_REG, lstart, lend);
953  } else if (!ts_node_is_null(parent) && !strcmp(ts_node_type(parent), "tmp_eval_stmt")) {
954  return fill_autocmplt_data(ad, AUTOCMPLT_EVAL_FULL, lstart, lend);
955  } else {
956  return fill_autocmplt_data_cmdarg(ad, lstart, lend, buf->data, root, core);
957  }
958 }
959 
970  ut32 lstart = ts_node_start_byte(root);
971  ut32 lend = ts_node_end_byte(root);
972  if (lend > buf->index) {
973  lend = buf->index;
974  }
975 
976  const char *root_type = ts_node_type(root);
977  bool res = false;
978  RZ_LOG_DEBUG("lstart = %d, lend = %d, type = %s\n", lstart, lend, root_type);
979  if (!strcmp(root_type, "cmd_identifier") && buf->data[lend - 1] != ' ') {
980  res = fill_autocmplt_data_cmdid(ad, lstart, lend);
981  } else if (!strcmp(root_type, "statements") && ts_node_named_child_count(root) == 0) {
982  res = fill_autocmplt_data_cmdid(ad, lend, lend);
983  } else if (!strcmp(root_type, "arg_identifier")) {
984  res = find_autocmplt_type_arg_identifier(ad, core, root, buf, lstart, lend);
985  } else if (!strcmp(root_type, "double_quoted_arg")) {
986  res = fill_autocmplt_data_cmdarg(ad, lstart + 1, lend, buf->data, root, core);
987  if (res) {
988  ad->res->end_string = "\" ";
989  }
990  } else if (!strcmp(root_type, "single_quoted_arg")) {
991  res = fill_autocmplt_data_cmdarg(ad, lstart + 1, lend, buf->data, root, core);
992  if (res) {
993  ad->res->end_string = "' ";
994  }
995  }
996  if (res) {
997  return true;
998  }
999 
1000  // while writing a command and asking for autocompletion, the command
1001  // could still be invalid (e.g. missing ending `"`, missing ending `)`,
1002  // etc.). In this case we try to guess what is the correct type to
1003  // autocomplete.
1004  if (find_autocmplt_type_newcmd_or_arg(ad, core, buf)) {
1005  return true;
1006  } else if (find_autocmplt_type_quoted_arg(ad, core, buf, "\"", "double_quoted_arg")) {
1007  ad->res->end_string = "\" ";
1008  return true;
1009  } else if (find_autocmplt_type_quoted_arg(ad, core, buf, "'", "single_quoted_arg")) {
1010  ad->res->end_string = "' ";
1011  return true;
1012  } else if (find_autocmplt_type_at_stmt_op(ad, core, buf, "tmp_seek_stmt", "a", AUTOCMPLT_RZNUM)) {
1013  return true;
1014  } else if (find_autocmplt_type_at_stmt_op(ad, core, buf, "tmp_fromto_stmt", "a b)", AUTOCMPLT_RZNUM)) {
1015  return true;
1016  } else if (find_autocmplt_type_at_stmt_op(ad, core, buf, "tmp_arch_stmt", "a", AUTOCMPLT_ARCH)) {
1017  return true;
1018  } else if (find_autocmplt_type_at_stmt_op(ad, core, buf, "tmp_bits_stmt", "1", AUTOCMPLT_BITS)) {
1019  return true;
1020  } else if (find_autocmplt_type_at_stmt_op(ad, core, buf, "tmp_file_stmt", "a", AUTOCMPLT_FILE)) {
1021  return true;
1022  } else if (find_autocmplt_type_at_stmt_op(ad, core, buf, "tmp_fs_stmt", "a", AUTOCMPLT_FLAG_SPACE)) {
1023  return true;
1024  } else if (find_autocmplt_type_at_stmt_op(ad, core, buf, "tmp_reg_stmt", "a", AUTOCMPLT_REG)) {
1025  return true;
1026  } else if (find_autocmplt_type_at_stmt_op(ad, core, buf, "tmp_eval_stmt", "a", AUTOCMPLT_EVAL_FULL)) {
1027  return true;
1028  } else if (find_autocmplt_type_at_stmt_op(ad, core, buf, "iter_offsets_stmt", "a", AUTOCMPLT_RZNUM)) {
1029  return true;
1030  } else if (find_autocmplt_type_at_stmt_op(ad, core, buf, "iter_offsetssizes_stmt", "a", AUTOCMPLT_RZNUM)) {
1031  return true;
1032  } else if (find_autocmplt_type_at_stmt_op(ad, core, buf, "iter_file_lines_stmt", "a", AUTOCMPLT_FILE)) {
1033  return true;
1034  } else if (find_autocmplt_type_at_stmt_op(ad, core, buf, "iter_flags_stmt", "a", AUTOCMPLT_FLAG)) {
1035  return true;
1036  } else if (find_autocmplt_type_at_stmt_op(ad, core, buf, "iter_function_stmt", "a", AUTOCMPLT_FUNCTION)) {
1037  return true;
1038  } else if (find_autocmplt_type_at_stmt(ad, core, buf)) {
1039  return true;
1040  }
1041  return false;
1042 }
1043 
1050  if (prompt_type == RZ_LINE_PROMPT_OFFSET) {
1051  res = rz_line_ns_completion_result_new(0, buf->length, NULL);
1052  int n = strlen(buf->data);
1053  autocmplt_cmd_arg_rznum(core, res, buf->data, n);
1054  return res;
1055  } else if (prompt_type == RZ_LINE_PROMPT_FILE) {
1056  res = rz_line_ns_completion_result_new(0, buf->length, NULL);
1057  size_t len = strlen(buf->data);
1058  autocmplt_cmd_arg_file(res, buf->data, len);
1059  return res;
1060  }
1061 
1062  struct autocmplt_data_t ad = { 0 };
1065 
1066  TSTree *tree = ts_parser_parse_string(parser, NULL, buf->data, buf->length);
1067  TSNode root = ts_tree_root_node(tree);
1068  TSNode node = ts_node_named_descendant_for_byte_range(root, buf->index - 1, buf->index);
1069  if (ts_node_is_null(node)) {
1070  goto err;
1071  }
1072  char *root_string = ts_node_string(root);
1073  char *node_string = ts_node_string(node);
1074  RZ_LOG_DEBUG("autocomplete_rzshell root = '%s'\n", root_string);
1075  RZ_LOG_DEBUG("autocomplete_rzshell node = '%s'\n", node_string);
1076  free(node_string);
1077  free(root_string);
1078 
1079  // the autocompletion works in 2 steps:
1080  // 1) it finds the proper type to autocomplete (sometimes it guesses)
1081  // 2) it traverses the proper RzCore structures to provide opportune
1082  // autocompletion options for the discovered type
1083  bool type_found = find_autocmplt_type(&ad, core, node, buf);
1084  if (type_found) {
1085  switch (ad.type) {
1086  case AUTOCMPLT_CMD_ID:
1087  autocmplt_cmdidentifier(core, ad.res, buf->data + ad.res->start, ad.res->end - ad.res->start);
1088  break;
1089  case AUTOCMPLT_CMD_ARG:
1090  autocmplt_cmd_arg(core, ad.res, ad.cd, ad.i_arg, buf->data + ad.res->start, ad.res->end - ad.res->start);
1091  break;
1092  case AUTOCMPLT_AT_STMT:
1093  autocmplt_at_stmt(core, ad.res, buf->data + ad.res->start, ad.res->end - ad.res->start);
1094  break;
1095  case AUTOCMPLT_RZNUM:
1096  autocmplt_cmd_arg_rznum(core, ad.res, buf->data + ad.res->start, ad.res->end - ad.res->start);
1097  break;
1098  case AUTOCMPLT_ARCH:
1099  autocmplt_arch(core, ad.res, buf->data + ad.res->start, ad.res->end - ad.res->start);
1100  break;
1101  case AUTOCMPLT_BITS:
1102  autocmplt_bits(core, ad.res, buf->data + ad.res->start, ad.res->end - ad.res->start);
1103  break;
1104  case AUTOCMPLT_FILE:
1105  autocmplt_cmd_arg_file(ad.res, buf->data + ad.res->start, ad.res->end - ad.res->start);
1106  break;
1107  case AUTOCMPLT_FLAG_SPACE:
1108  autocmplt_flag_space(core, ad.res, buf->data + ad.res->start, ad.res->end - ad.res->start);
1109  break;
1110  case AUTOCMPLT_REG:
1111  autocmplt_reg(core, ad.res, buf->data + ad.res->start, ad.res->end - ad.res->start);
1112  break;
1113  case AUTOCMPLT_EVAL_FULL:
1114  autocmplt_cmd_arg_eval_full(core, ad.res, buf->data + ad.res->start, ad.res->end - ad.res->start);
1115  break;
1116  case AUTOCMPLT_FLAG:
1117  autocmplt_cmd_arg_flag(core, ad.res, buf->data + ad.res->start, ad.res->end - ad.res->start);
1118  break;
1119  case AUTOCMPLT_FUNCTION:
1120  autocmplt_cmd_arg_fcn(core, ad.res, buf->data + ad.res->start, ad.res->end - ad.res->start);
1121  break;
1122  default:
1123  break;
1124  }
1125  }
1126 
1127 err:
1128  ts_tree_delete(tree);
1130  return ad.res;
1131 }
size_t len
Definition: 6502dis.c:15
static char * regs[]
Definition: analysis_sh.c:203
lzma_index ** i
Definition: index.h:629
const char * ts_node_type(TSNode)
Definition: node.c:420
void ts_parser_delete(TSParser *parser)
Definition: parser.c:1725
TSNode ts_node_named_child(TSNode, uint32_t)
Definition: node.c:496
uint32_t ts_node_start_byte(TSNode)
Definition: node.c:36
char * ts_node_string(TSNode)
Definition: node.c:426
uint32_t ts_node_named_child_count(TSNode)
Definition: node.c:611
bool ts_node_is_null(TSNode)
Definition: node.c:434
TSNode ts_node_prev_sibling(TSNode)
Definition: node.c:628
void ts_tree_delete(TSTree *self)
Definition: tree.c:26
TSNode ts_tree_root_node(const TSTree *self)
Definition: tree.c:36
bool ts_parser_set_language(TSParser *self, const TSLanguage *language)
Definition: parser.c:1754
bool ts_node_has_error(TSNode)
Definition: node.c:457
uint32_t ts_node_end_byte(TSNode)
Definition: node.c:406
TSParser * ts_parser_new(void)
Definition: parser.c:1704
TSNode ts_node_parent(TSNode)
Definition: node.c:461
TSTree * ts_parser_parse_string(TSParser *self, const TSTree *old_tree, const char *string, uint32_t length)
Definition: parser.c:1945
TSNode ts_node_named_descendant_for_byte_range(TSNode, uint32_t, uint32_t)
Definition: node.c:652
static const char * arg(RzAnalysis *a, csh *handle, cs_insn *insn, char *buf, int n)
Definition: arm_esil32.c:136
static bool err
Definition: armass.c:435
RZ_API RzList * rz_asm_get_plugins(RzAsm *a)
Definition: asm.c:1191
static csh cd
Definition: asm_mips_cs.c:10
const char * desc
Definition: bin_vsf.c:19
int bits(struct state *s, int need)
Definition: blast.c:72
RZ_API char * rz_core_analysis_fcn_name(RzCore *core, RzAnalysisFunction *fcn)
Definition: canalysis.c:2647
static bool find_autocmplt_type_arg_identifier(struct autocmplt_data_t *ad, RzCore *core, TSNode root, RzLineBuffer *buf, ut32 lstart, ut32 lend)
Definition: cautocmpl.c:937
static void autocmplt_cmd_arg(RzCore *core, RzLineNSCompletionResult *res, const RzCmdDesc *cd, size_t i_arg, const char *s, size_t len)
Definition: cautocmpl.c:667
static bool fill_autocmplt_data(struct autocmplt_data_t *ad, enum autocmplt_type_t type, ut32 start, ut32 end)
Definition: cautocmpl.c:734
static void autocmplt_flag_space(RzCore *core, RzLineNSCompletionResult *res, const char *s, size_t len)
Definition: cautocmpl.c:226
static RzCmdDesc * get_cd_from_arg(RzCore *core, const char *data, TSNode arg)
Definition: cautocmpl.c:620
static void autocmplt_bits(RzCore *core, RzLineNSCompletionResult *res, const char *s, size_t len)
Definition: cautocmpl.c:220
RZ_API RzLineNSCompletionResult * rz_core_autocomplete_rzshell(RzCore *core, RzLineBuffer *buf, RzLinePromptType prompt_type)
Definition: cautocmpl.c:1048
static void autocmplt_cmd_arg_eval_key(RzCore *core, RzLineNSCompletionResult *res, const char *s, size_t len)
Definition: cautocmpl.c:536
static void autocmplt_reg(RzCore *core, RzLineNSCompletionResult *res, const char *s, size_t len)
Definition: cautocmpl.c:240
static bool find_autocmplt_type_at_stmt_op(struct autocmplt_data_t *ad, RzCore *core, RzLineBuffer *buf, const char *tmp_op, const char *newtext, enum autocmplt_type_t ad_type)
Definition: cautocmpl.c:902
static struct guess_data_t * guess_next_autocmplt_token(RzCore *core, RzLineBuffer *buf, const char *fake_text, size_t offset)
Definition: cautocmpl.c:74
static void autocmplt_cmd_arg_rznum(RzCore *core, RzLineNSCompletionResult *res, const char *s, size_t len)
Definition: cautocmpl.c:501
static void autocmplt_cmd_arg_any_type(RzCore *core, RzLineNSCompletionResult *res, const char *s, size_t len)
Definition: cautocmpl.c:410
autocmplt_type_t
Definition: cautocmpl.c:14
@ AUTOCMPLT_AT_STMT
A temporary modifier operator like @, @a:, @v: or a iter operator like @@., @@, @@i,...
Definition: cautocmpl.c:18
@ AUTOCMPLT_FILE
A file needs to be autocompleted.
Definition: cautocmpl.c:22
@ AUTOCMPLT_RZNUM
A expression that can be parsed by RzNum (e.g. "flag+3")
Definition: cautocmpl.c:19
@ AUTOCMPLT_REG
A cpu register needs to be autocompleted.
Definition: cautocmpl.c:24
@ AUTOCMPLT_BITS
A bits value supported by the currently selected architecture (e asm.bits=?)
Definition: cautocmpl.c:21
@ AUTOCMPLT_FLAG
A flag item needs to be autocompleted.
Definition: cautocmpl.c:26
@ AUTOCMPLT_FLAG_SPACE
A flag space needs to be autocompleted.
Definition: cautocmpl.c:23
@ AUTOCMPLT_CMD_ARG
The argument of an arged_stmt (see grammar.js) needs to be autocompleted.
Definition: cautocmpl.c:17
@ AUTOCMPLT_ARCH
An architecture supported by Rizin (e.g. x86, arm, etc.)
Definition: cautocmpl.c:20
@ AUTOCMPLT_FUNCTION
A function name needs to be autocompleted.
Definition: cautocmpl.c:27
@ AUTOCMPLT_UNKNOWN
Unknown, nothing will be autocompleted.
Definition: cautocmpl.c:15
@ AUTOCMPLT_CMD_ID
A command identifier (aka command name) needs to be autocompleted.
Definition: cautocmpl.c:16
@ AUTOCMPLT_EVAL_FULL
A name=value of a evaluable variable (e.g. e command)
Definition: cautocmpl.c:25
static void autocmplt_cmd_arg_choices(RzCore *core, RzLineNSCompletionResult *res, const char *s, size_t len, const RzCmdDescArg *arg)
Definition: cautocmpl.c:520
static bool find_autocmplt_type(struct autocmplt_data_t *ad, RzCore *core, TSNode root, RzLineBuffer *buf)
Returns true and a properly filled ad when something to autocomplete was discovered.
Definition: cautocmpl.c:969
static bool fill_autocmplt_data_cmdarg(struct autocmplt_data_t *ad, ut32 start, ut32 end, const char *s, TSNode node, RzCore *core)
Definition: cautocmpl.c:753
static bool find_autocmplt_type_at_stmt(struct autocmplt_data_t *ad, RzCore *core, RzLineBuffer *buf)
Definition: cautocmpl.c:815
static bool is_arg_identifier_in_tmp_stmt(TSNode node)
Definition: cautocmpl.c:802
static void autocmplt_cmd_arg_enum_type(RzCore *core, RzLineNSCompletionResult *res, const char *s, size_t len)
Definition: cautocmpl.c:362
static bool fill_autocmplt_data_at_stmt(struct autocmplt_data_t *ad, ut32 start, ut32 end)
Definition: cautocmpl.c:775
static RzCmdDesc * get_cd_from_cmdid(RzCore *core, const char *data, TSNode cmd_id)
Definition: cautocmpl.c:611
static bool fill_autocmplt_data_cmdid(struct autocmplt_data_t *ad, ut32 start, ut32 end)
Definition: cautocmpl.c:744
static void autocmplt_cmd_arg_macro(RzCore *core, RzLineNSCompletionResult *res, const char *s, size_t len)
Definition: cautocmpl.c:320
static bool find_autocmplt_type_quoted_arg(struct autocmplt_data_t *ad, RzCore *core, RzLineBuffer *buf, const char *quote, const char *quote_node_type)
Definition: cautocmpl.c:922
static void autocmplt_arch(RzCore *core, RzLineNSCompletionResult *res, const char *s, size_t len)
Definition: cautocmpl.c:190
static bool is_op_ch(char ch)
Definition: cautocmpl.c:496
static void autocmplt_at_stmt(RzCore *core, RzLineNSCompletionResult *res, const char *s, size_t len)
Definition: cautocmpl.c:123
static TSNode get_arg_parent(TSNode node)
Definition: cautocmpl.c:795
static void autocmplt_cmd_arg_help_var(RzCore *core, RzLineNSCompletionResult *res, const char *s, size_t len)
Definition: cautocmpl.c:486
static bool is_arg_type(const char *type)
Definition: cautocmpl.c:605
static void autocmplt_cmd_arg_env(RzLineNSCompletionResult *res, const char *s, size_t len)
Definition: cautocmpl.c:307
static void autocmplt_cmd_arg_reg_type(RzCore *core, const RzCmdDesc *cd, RzLineNSCompletionResult *res, const char *s, size_t len)
Definition: cautocmpl.c:480
static void autocmplt_cmd_arg_fcn(RzCore *core, RzLineNSCompletionResult *res, const char *s, size_t len)
Definition: cautocmpl.c:350
static void autocmplt_cmd_arg_fcn_var(RzCore *core, RzLineNSCompletionResult *res, const char *s, size_t len)
Definition: cautocmpl.c:589
static void autocmplt_cmdidentifier(RzCore *core, RzLineNSCompletionResult *res, const char *s, size_t len)
Definition: cautocmpl.c:114
static void autocmplt_cmd_arg_global_var(RzCore *core, RzLineNSCompletionResult *res, const char *s, size_t len)
Definition: cautocmpl.c:422
static size_t get_arg_number(TSNode arg)
Definition: cautocmpl.c:647
static void autocmplt_cmd_arg_reg_filter(RzCore *core, const RzCmdDesc *cd, RzLineNSCompletionResult *res, const char *s, size_t len)
Definition: cautocmpl.c:435
static bool find_autocmplt_type_newcmd_or_arg(struct autocmplt_data_t *ad, RzCore *core, RzLineBuffer *buf)
Definition: cautocmpl.c:779
static void autocmplt_cmd_arg_union_type(RzCore *core, RzLineNSCompletionResult *res, const char *s, size_t len)
Definition: cautocmpl.c:386
static bool offset_prompt_add_flag(RzFlagItem *fi, void *user)
Definition: cautocmpl.c:344
static void autocmplt_bits_plugin(RzAsmPlugin *plugin, RzLineNSCompletionResult *res, const char *s, size_t len)
Definition: cautocmpl.c:179
static void autocmplt_cmd_arg_struct_type(RzCore *core, RzLineNSCompletionResult *res, const char *s, size_t len)
Definition: cautocmpl.c:374
static bool do_autocmplt_cmdidentifier(RzCmd *cmd, const RzCmdDesc *desc, void *user)
Definition: cautocmpl.c:106
static void guess_data_free(struct guess_data_t *g)
Definition: cautocmpl.c:61
static void autocmplt_cmd_arg_flag(RzCore *core, RzLineNSCompletionResult *res, const char *s, size_t len)
Definition: cautocmpl.c:331
static void autocmplt_cmd_arg_alias_type(RzCore *core, RzLineNSCompletionResult *res, const char *s, size_t len)
Definition: cautocmpl.c:398
static void autocmplt_cmd_arg_file(RzLineNSCompletionResult *res, const char *s, size_t len)
Definition: cautocmpl.c:253
static void autocmplt_cmd_arg_eval_full(RzCore *core, RzLineNSCompletionResult *res, const char *s, size_t len)
Definition: cautocmpl.c:546
RZ_API RzCmdDesc * rz_cmd_get_desc(RzCmd *cmd, const char *cmd_identifier)
Retrieve the command descriptor for the command named cmd_identifier.
Definition: cmd_api.c:372
RZ_API void rz_cmd_foreach_cmdname(RzCmd *cmd, RzCmdDesc *begin, RzCmdForeachNameCb cb, void *user)
Execute a callback function on each possible command the user can execute.
Definition: cmd_api.c:2474
RZ_API const RzCmdDescArg * rz_cmd_desc_get_arg(RzCmd *cmd, const RzCmdDesc *cd, size_t i)
Get a reference to the i-th argument of a command descriptor.
Definition: cmd_api.c:2375
RZ_API RzCmdDesc * rz_cmd_desc_get_exec(RzCmdDesc *cd)
Definition: cmd_api.c:291
RZ_API const char ** rz_core_help_vars_get(RzCore *core)
Returns all the $ variable names in a NULL-terminated array.
Definition: cmd_help.c:360
RZ_API RZ_BORROW RzConfigNode * rz_config_node_get(RzConfig *cfg, RZ_NONNULL const char *name)
Definition: config.c:48
#define RZ_API
RZ_API RzReg * rz_core_reg_default(RzCore *core)
Get the currently relevant RzReg.
Definition: creg.c:17
#define NULL
Definition: cris-opc.c:27
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void static offset struct stat static buf void long static basep static whence static length const void static len static semflg const void static shmflg const struct timespec struct timespec static rem const char static group const void start
Definition: sflib.h:133
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags cmd
Definition: sflib.h:79
uint32_t ut32
const char * k
Definition: dsignal.c:11
const char * v
Definition: dsignal.c:12
int root
Definition: enough.c:226
struct @667 g
RZ_DEPRECATE RZ_API RzAnalysisFunction * rz_analysis_get_fcn_in(RzAnalysis *analysis, ut64 addr, int type)
Definition: fcn.c:1687
RZ_API void rz_flag_foreach_prefix(RzFlag *f, const char *pfx, int pfx_len, RzFlagItemCb cb, void *user)
Definition: flag.c:804
RZ_API RzList * rz_flag_all_list(RzFlag *f, bool by_space)
Definition: flag.c:463
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
const char * filename
Definition: ioapi.h:137
voidpf uLong offset
Definition: ioapi.h:144
voidpf void * buf
Definition: ioapi.h:138
#define reg(n)
void * p
Definition: libc.cpp:67
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
#define basename
Definition: libiberty.h:109
static void list(RzEgg *egg)
Definition: rz-gg.c:52
RZ_API ut32 rz_list_length(RZ_NONNULL const RzList *list)
Returns the length of the list.
Definition: list.c:109
RZ_API void rz_list_free(RZ_NONNULL RzList *list)
Empties the list and frees the list pointer.
Definition: list.c:137
void * malloc(size_t size)
Definition: malloc.c:123
RZ_API RzLineNSCompletionResult * rz_line_ns_completion_result_new(size_t start, size_t end, const char *end_string)
Definition: line.c:122
RZ_API void rz_line_ns_completion_result_add(RzLineNSCompletionResult *res, const char *option)
Definition: line.c:156
RZ_API void rz_line_ns_completion_result_propose(RzLineNSCompletionResult *res, const char *option, const char *cur, size_t cur_len)
Add a new option to the list of possible autocomplete-able value if it matches the given string.
Definition: line.c:170
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 n
Definition: mipsasm.c:19
int type
Definition: mipsasm.c:17
int idx
Definition: setup.py:197
RZ_API const char * rz_reg_get_type(int idx)
Definition: reg.c:68
RZ_API const RzList * rz_reg_get_list(RzReg *reg, int type)
Definition: reg.c:389
RZ_API const char * rz_reg_get_role(int role)
Definition: reg.c:172
static RzSocket * s
Definition: rtr.c:28
#define rz_return_if_fail(expr)
Definition: rz_assert.h:100
enum rz_cmd_arg_type_t RzCmdArgType
@ RZ_CMD_ARG_TYPE_FCN
Argument can be the name of an existing function.
Definition: rz_cmd.h:43
@ RZ_CMD_ARG_TYPE_MACRO
Argument is the name of a pre-defined macro.
Definition: rz_cmd.h:47
@ RZ_CMD_ARG_TYPE_EVAL_KEY
Argument is the name of a evaluable variable (e.g. et command)
Definition: rz_cmd.h:48
@ RZ_CMD_ARG_TYPE_EVAL_FULL
Argument is the name+(optional)value of a evaluable variable (e.g. e command)
Definition: rz_cmd.h:49
@ RZ_CMD_ARG_TYPE_FCN_VAR
Argument is the name of a function variable/argument.
Definition: rz_cmd.h:50
@ RZ_CMD_ARG_TYPE_STRUCT_TYPE
Argument is a C struct type name.
Definition: rz_cmd.h:53
@ RZ_CMD_ARG_TYPE_ENUM_TYPE
Argument is a C enum type name.
Definition: rz_cmd.h:52
@ RZ_CMD_ARG_TYPE_CHOICES
Argument can be one of the provided choices.
Definition: rz_cmd.h:42
@ RZ_CMD_ARG_TYPE_RZNUM
Argument that can be interpreted by RzNum (numbers, flags, operations, etc.)
Definition: rz_cmd.h:39
@ RZ_CMD_ARG_TYPE_REG_TYPE
Argument is a register type/arena like "gpr".
Definition: rz_cmd.h:60
@ RZ_CMD_ARG_TYPE_ANY_TYPE
Argument is the any of the C or C++ type name.
Definition: rz_cmd.h:57
@ RZ_CMD_ARG_TYPE_FLAG
Argument is a rizin flag.
Definition: rz_cmd.h:51
@ RZ_CMD_ARG_TYPE_UNION_TYPE
Argument is a C union type name.
Definition: rz_cmd.h:54
@ RZ_CMD_ARG_TYPE_ALIAS_TYPE
Argument is a C typedef (alias) name.
Definition: rz_cmd.h:55
@ RZ_CMD_ARG_TYPE_REG_FILTER
Argument is a register name, size, type or "all".
Definition: rz_cmd.h:59
@ RZ_CMD_ARG_TYPE_FILE
Argument is a filename.
Definition: rz_cmd.h:44
@ RZ_CMD_ARG_TYPE_GLOBAL_VAR
Argument is a user defined global variable.
Definition: rz_cmd.h:58
@ RZ_CMD_ARG_TYPE_ENV
Argument can be the name of an existing rizin variable.
Definition: rz_cmd.h:41
static bool rz_config_node_is_bool(RzConfigNode *node)
Definition: rz_config.h:117
RzLinePromptType
Definition: rz_cons.h:1037
@ RZ_LINE_PROMPT_OFFSET
Definition: rz_cons.h:1038
@ RZ_LINE_PROMPT_FILE
Definition: rz_cons.h:1039
#define RZ_LINE_BUFSIZE
Definition: rz_cons.h:991
RZ_API const char * rz_file_basename(const char *path)
Definition: file.c:83
RZ_API bool rz_file_is_directory(const char *str)
Definition: file.c:167
RZ_API bool rz_file_is_abspath(const char *file)
Definition: file.c:214
RZ_API char * rz_file_dirname(const char *path)
Definition: file.c:120
RZ_API RZ_OWN char * rz_file_path_join(RZ_NONNULL const char *s1, RZ_NULLABLE const char *s2)
Concatenate two paths to create a new one with s1+s2 with the correct path separator.
Definition: file.c:1312
#define RZ_LOG_DEBUG(fmtstr,...)
Definition: rz_log.h:49
RZ_API RZ_OWN char * rz_path_home_expand(RZ_NULLABLE const char *path)
Return a new path with the ~ char expanded to the home directory.
Definition: path.c:268
@ RZ_REG_TYPE_LAST
Definition: rz_reg.h:34
@ RZ_REG_TYPE_ANY
Definition: rz_reg.h:35
@ RZ_REG_NAME_LAST
Definition: rz_reg.h:71
RZ_API char * rz_str_newf(const char *fmt,...) RZ_PRINTF_CHECK(1
RZ_API char * rz_str_ndup(RZ_NULLABLE const char *ptr, int len)
Create new copy of string ptr limited to size len.
Definition: str.c:1006
#define RZ_STR_ISEMPTY(x)
Definition: rz_str.h:67
RZ_API int rz_str_replace_ch(char *s, char a, char b, bool g)
Definition: str.c:139
RZ_API const char * rz_sub_str_rchr(const char *str, int start, int end, char chr)
Definition: str.c:690
RZ_API bool rz_str_startswith(RZ_NONNULL const char *str, RZ_NONNULL const char *needle)
Checks if a string starts with a specifc sequence of characters (case sensitive)
Definition: str.c:3286
RZ_API bool rz_str_endswith(RZ_NONNULL const char *str, RZ_NONNULL const char *needle)
Checks if a string ends with a specifc sequence of characters (case sensitive)
Definition: str.c:3329
#define rz_strf(buf,...)
Convenience macro for local temporary strings.
Definition: rz_str.h:59
RZ_API RzList * rz_sys_dir(const char *path)
Definition: sys.c:216
RZ_API char ** rz_sys_get_environ(void)
Definition: sys.c:1115
#define RZ_SYS_DIR
Definition: rz_types.h:218
#define RZ_NEW0(x)
Definition: rz_types.h:284
#define c(i)
Definition: sha256.c:43
Definition: api.h:92
Definition: tree.h:15
RzLineNSCompletionResult * res
Definition: cautocmpl.c:45
const RzCmdDesc * cd
Used if type is AUTOCMPLT_CMD_ARG to describe the related command.
Definition: cautocmpl.c:37
size_t i_arg
Used if type is AUTOCMPLT_CMD_ARG to describe the argument that will be autocompleted.
Definition: cautocmpl.c:38
RzLineNSCompletionResult * res
Result returned to RzCons API to provide possible suggestions.
Definition: cautocmpl.c:36
enum autocmplt_type_t type
Type of token that will be autocompleted.
Definition: cautocmpl.c:35
TSNode node
Node identified under the user position cursor when using the modified input.
Definition: cautocmpl.c:58
char * input
Modified input.
Definition: cautocmpl.c:55
TSTree * tree
Pointer to the syntax tree of the modified input.
Definition: cautocmpl.c:57
TSParser * parser
Parser used to parser the modified input.
Definition: cautocmpl.c:56
Definition: z80asm.h:102
RzList * fcns
Definition: rz_analysis.h:565
RzTypeDB * typedb
Definition: rz_analysis.h:602
Global variables.
Definition: rz_analysis.h:744
char * name
name of the variable
Definition: rz_analysis.h:746
const char * name
Definition: rz_asm.h:130
_RzAsmPlugin * cur
Definition: rz_asm.h:106
RzList * macros
Definition: rz_cmd.h:148
RzCmdMacro macro
Definition: rz_cmd.h:482
void * language
Definition: rz_cmd.h:484
RzList * options
Definition: rz_config.h:47
RzList * nodes
Definition: rz_config.h:56
RzCmd * rcmd
Definition: rz_core.h:319
ut64 offset
Definition: rz_core.h:301
RzAsm * rasm
Definition: rz_core.h:323
RzAnalysis * analysis
Definition: rz_core.h:322
RzDebug * dbg
Definition: rz_core.h:329
RzFlag * flags
Definition: rz_core.h:330
RzConfig * config
Definition: rz_core.h:300
RzReg * reg
Definition: rz_debug.h:286
char * name
Definition: rz_flag.h:35
size_t start
First byte that was considered for autocompletion. Everything before this will be left intact.
Definition: rz_cons.h:1062
const char * end_string
String to place after the only option available is autocompleted. By default a space is used.
Definition: rz_cons.h:1064
size_t end
Last byte that was considered for autocompletion. Everything after this will be left intact.
Definition: rz_cons.h:1063
char * name
Definition: rz_reg.h:118
char * name
Definition: rz_spaces.h:29
static char ** env
Definition: sys.c:32
RZ_API RZ_OWN RzList * rz_type_db_enum_names(RzTypeDB *typedb)
Returns the list of all enum names.
Definition: type.c:369
RZ_API RZ_OWN RzList * rz_type_db_union_names(RzTypeDB *typedb)
Returns the list of all union names.
Definition: type.c:387
RZ_API RZ_OWN RzList * rz_type_db_struct_names(RzTypeDB *typedb)
Returns the list of all struct names.
Definition: type.c:405
RZ_API RZ_OWN RzList * rz_type_db_all(RzTypeDB *typedb)
Returns the list of all type names.
Definition: type.c:441
RZ_API RZ_OWN RzList * rz_type_db_typedef_names(RzTypeDB *typedb)
Returns the list of all typedef (type aliases) names.
Definition: type.c:423
RZ_DEPRECATE RZ_API RzList * rz_analysis_var_all_list(RzAnalysis *analysis, RzAnalysisFunction *fcn)
Definition: var.c:1135
RZ_API RZ_OWN RzList * rz_analysis_var_global_get_all(RzAnalysis *analysis)
Get all of the added global variables.
Definition: var_global.c:259
static bool input(void *ud, zip_uint8_t *data, zip_uint64_t length)