Add autocomplete function and cmd arg type for global variables (#1577)
* Add autocomplete function and cmd arg type for global variables * Add unit tests for global var auto completion Co-authored-by: Riccardo Schirone <ret2libc@users.noreply.github.com>
This commit is contained in:
parent
cba3f0b763
commit
aed6854bdf
5 changed files with 65 additions and 10 deletions
|
|
@ -276,6 +276,19 @@ static void autocmplt_cmd_arg_any_type(RzCore *core, RzLineNSCompletionResult *r
|
|||
rz_list_free(list);
|
||||
}
|
||||
|
||||
static void autocmplt_cmd_arg_global_var(RzCore *core, RzLineNSCompletionResult *res, const char *s, size_t len) {
|
||||
RzAnalysisVarGlobal *glob;
|
||||
RzListIter *iter;
|
||||
RzList *list = rz_analysis_var_global_get_all(core->analysis);
|
||||
rz_list_foreach (list, iter, glob) {
|
||||
char *name = glob->name;
|
||||
if (!strncmp(name, s, len)) {
|
||||
rz_line_ns_completion_result_add(res, name);
|
||||
}
|
||||
}
|
||||
rz_list_free(list);
|
||||
}
|
||||
|
||||
static void autocmplt_cmd_arg_help_var(RzCore *core, RzLineNSCompletionResult *res, const char *s, size_t len) {
|
||||
const char **vars = rz_core_help_vars_get(core);
|
||||
while (*vars) {
|
||||
|
|
@ -521,6 +534,9 @@ static void autocmplt_cmd_arg(RzCore *core, RzLineNSCompletionResult *res, const
|
|||
case RZ_CMD_ARG_TYPE_ANY_TYPE:
|
||||
autocmplt_cmd_arg_any_type(core, res, s, len);
|
||||
break;
|
||||
case RZ_CMD_ARG_TYPE_GLOBAL_VAR:
|
||||
autocmplt_cmd_arg_global_var(core, res, s, len);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -406,7 +406,7 @@ commands:
|
|||
- RZ_OUTPUT_MODE_JSON
|
||||
args:
|
||||
- name: var_name
|
||||
type: RZ_CMD_ARG_TYPE_STRING
|
||||
type: RZ_CMD_ARG_TYPE_GLOBAL_VAR
|
||||
optional: true
|
||||
- name: avga
|
||||
summary: add global variable manually
|
||||
|
|
@ -432,14 +432,14 @@ commands:
|
|||
cname: analysis_global_variable_delete_byname
|
||||
args:
|
||||
- name: name
|
||||
type: RZ_CMD_ARG_TYPE_STRING
|
||||
type: RZ_CMD_ARG_TYPE_GLOBAL_VAR
|
||||
- name: avgn
|
||||
summary: rename the global variable
|
||||
type: RZ_CMD_DESC_TYPE_ARGV
|
||||
cname: analysis_global_variable_rename
|
||||
args:
|
||||
- name: old_var_name
|
||||
type: RZ_CMD_ARG_TYPE_STRING
|
||||
type: RZ_CMD_ARG_TYPE_GLOBAL_VAR
|
||||
- name: new_var_name
|
||||
type: RZ_CMD_ARG_TYPE_STRING
|
||||
- name: avgt
|
||||
|
|
@ -448,7 +448,7 @@ commands:
|
|||
cname: analysis_global_variable_retype
|
||||
args:
|
||||
- name: var_name
|
||||
type: RZ_CMD_ARG_TYPE_STRING
|
||||
type: RZ_CMD_ARG_TYPE_GLOBAL_VAR
|
||||
- name: type
|
||||
type: RZ_CMD_ARG_TYPE_ANY_TYPE
|
||||
- name: avr
|
||||
|
|
|
|||
|
|
@ -1510,8 +1510,7 @@ static const RzCmdDescHelp avg_help = {
|
|||
static const RzCmdDescArg analysis_print_global_variable_args[] = {
|
||||
{
|
||||
.name = "var_name",
|
||||
.type = RZ_CMD_ARG_TYPE_STRING,
|
||||
.flags = RZ_CMD_ARG_FLAG_LAST,
|
||||
.type = RZ_CMD_ARG_TYPE_GLOBAL_VAR,
|
||||
.optional = true,
|
||||
|
||||
},
|
||||
|
|
@ -1562,8 +1561,7 @@ static const RzCmdDescHelp analysis_global_variable_delete_byaddr_help = {
|
|||
static const RzCmdDescArg analysis_global_variable_delete_byname_args[] = {
|
||||
{
|
||||
.name = "name",
|
||||
.type = RZ_CMD_ARG_TYPE_STRING,
|
||||
.flags = RZ_CMD_ARG_FLAG_LAST,
|
||||
.type = RZ_CMD_ARG_TYPE_GLOBAL_VAR,
|
||||
|
||||
},
|
||||
{ 0 },
|
||||
|
|
@ -1576,7 +1574,7 @@ static const RzCmdDescHelp analysis_global_variable_delete_byname_help = {
|
|||
static const RzCmdDescArg analysis_global_variable_rename_args[] = {
|
||||
{
|
||||
.name = "old_var_name",
|
||||
.type = RZ_CMD_ARG_TYPE_STRING,
|
||||
.type = RZ_CMD_ARG_TYPE_GLOBAL_VAR,
|
||||
|
||||
},
|
||||
{
|
||||
|
|
@ -1595,7 +1593,7 @@ static const RzCmdDescHelp analysis_global_variable_rename_help = {
|
|||
static const RzCmdDescArg analysis_global_variable_retype_args[] = {
|
||||
{
|
||||
.name = "var_name",
|
||||
.type = RZ_CMD_ARG_TYPE_STRING,
|
||||
.type = RZ_CMD_ARG_TYPE_GLOBAL_VAR,
|
||||
|
||||
},
|
||||
{
|
||||
|
|
|
|||
|
|
@ -57,6 +57,7 @@ typedef enum rz_cmd_arg_type_t {
|
|||
RZ_CMD_ARG_TYPE_ALIAS_TYPE, ///< Argument is a C typedef (alias) name
|
||||
RZ_CMD_ARG_TYPE_CLASS_TYPE, ///< Argument is a C++/etc class name
|
||||
RZ_CMD_ARG_TYPE_ANY_TYPE, ///< Argument is the any of the C or C++ type name
|
||||
RZ_CMD_ARG_TYPE_GLOBAL_VAR, ///< Argument is a user defined global variable
|
||||
} RzCmdArgType;
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -400,6 +400,45 @@ static bool test_autocmplt_seek(void) {
|
|||
mu_end;
|
||||
}
|
||||
|
||||
static bool test_autocmplt_global(void) {
|
||||
RzCore *core = rz_core_new();
|
||||
mu_assert_notnull(core, "core should not be null");
|
||||
|
||||
RzAnalysisVarGlobal *glob1 = rz_analysis_var_global_new("GINT", 0x1337); // untyped global
|
||||
mu_assert_notnull(glob1, "glob1 null");
|
||||
bool added = rz_analysis_var_global_add(core->analysis, glob1);
|
||||
mu_assert_true(added, "unable to add glob1");
|
||||
|
||||
RzAnalysisVarGlobal *glob2 = rz_analysis_var_global_new("GCHR", 0xd3ad); // typed global
|
||||
mu_assert_notnull(glob2, "glob2 null");
|
||||
added = rz_analysis_var_global_add(core->analysis, glob2);
|
||||
mu_assert_true(added, "unable to add glob2");
|
||||
RzTypeParser *parser = rz_type_parser_new();
|
||||
mu_assert_notnull(parser, "create type parser");
|
||||
char *errmsg = NULL;
|
||||
RzType *typ = rz_type_parse_string_single(parser, "int", &errmsg);
|
||||
mu_assert_notnull(typ, "parsed type");
|
||||
rz_analysis_var_global_set_type(glob2, typ);
|
||||
|
||||
RzLineBuffer *buf = &core->cons->line->buffer;
|
||||
const char *s = "avg ";
|
||||
strcpy(buf->data, s);
|
||||
buf->length = strlen(s);
|
||||
buf->index = buf->length;
|
||||
RzLineNSCompletionResult *r = rz_core_autocomplete_rzshell(core, buf, RZ_LINE_PROMPT_DEFAULT);
|
||||
|
||||
mu_assert_notnull(r, "r should not be null");
|
||||
mu_assert_eq(r->start, strlen("avg "), "should autocomplete the last arg");
|
||||
mu_assert_eq(r->end, buf->length, "should autocomplete ending at end of buffer");
|
||||
mu_assert_eq(rz_pvector_len(&r->options), 2, "there are 2 global vars");
|
||||
mu_assert_streq(rz_pvector_at(&r->options, 0), "GINT", "GINT found");
|
||||
mu_assert_streq(rz_pvector_at(&r->options, 1), "GCHR", "GCHR found");
|
||||
rz_line_ns_completion_result_free(r);
|
||||
|
||||
rz_core_free(core);
|
||||
mu_end;
|
||||
}
|
||||
|
||||
bool all_tests() {
|
||||
mu_run_test(test_autocmplt_cmdid);
|
||||
mu_run_test(test_autocmplt_newcommand);
|
||||
|
|
@ -409,6 +448,7 @@ bool all_tests() {
|
|||
mu_run_test(test_autocmplt_fcn);
|
||||
mu_run_test(test_autocmplt_eval);
|
||||
mu_run_test(test_autocmplt_seek);
|
||||
mu_run_test(test_autocmplt_global);
|
||||
return tests_passed != tests_run;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue