mirror of
https://github.com/rizinorg/rizin
synced 2026-08-22 20:26:16 -04:00
Change rz_config variables to use Set instead of List (#6623)
* Update rz_config list variables to set variables * Linking error fix * Update rz_config_get_options in cautocmpl.c * Update rz_config_get_options in core/tui/config.c * Test fix * Assertion error fix
This commit is contained in:
parent
78045e8fc6
commit
fa2db74f86
13 changed files with 362 additions and 306 deletions
|
|
@ -18,7 +18,7 @@ static void config_var_fini(RzConfigVar *var) {
|
|||
|
||||
free(var->name);
|
||||
free(var->desc);
|
||||
rz_list_free(var->options);
|
||||
rz_set_s_free(var->options);
|
||||
if (RZ_CONFIG_VAR_HAS_FLAG(var->flags, RZ_CONFIG_VAR_FLAG_BIND)) {
|
||||
// if is bind, we do not own the value.
|
||||
return;
|
||||
|
|
@ -26,8 +26,8 @@ static void config_var_fini(RzConfigVar *var) {
|
|||
|
||||
if (RZ_CONFIG_VAR_IS_TYPE(var->flags, RZ_CONFIG_VAR_TYPE_STR)) {
|
||||
free(var->value.string);
|
||||
} else if (RZ_CONFIG_VAR_IS_TYPE(var->flags, RZ_CONFIG_VAR_TYPE_LIST)) {
|
||||
rz_list_free(var->value.list);
|
||||
} else if (RZ_CONFIG_VAR_IS_TYPE(var->flags, RZ_CONFIG_VAR_TYPE_SET)) {
|
||||
rz_set_s_free(var->value.set);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -61,30 +61,31 @@ static inline bool config_var_set_readonly(RzConfigVar *var, bool read_only) {
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool config_var_args_to_list(va_list argp, RzList /*<char *>*/ *list) {
|
||||
static bool config_var_args_to_set(va_list argp, RzSetS *set) {
|
||||
const char *value = va_arg(argp, const char *);
|
||||
while (value) {
|
||||
char *copy = rz_str_dup(value);
|
||||
if (!copy || !rz_list_append(list, copy)) {
|
||||
free(copy);
|
||||
return false;
|
||||
}
|
||||
rz_set_s_add(set, value);
|
||||
value = va_arg(argp, const char *);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
RZ_IPI RZ_OWN RzList /*<char *>*/ *rz_config_dup_list(RZ_NULLABLE const RzList /*<const char *>*/ *list) {
|
||||
RzListIter *it;
|
||||
const char *elem;
|
||||
RzList *safe_list = rz_list_newf(free);
|
||||
if (!safe_list) {
|
||||
RZ_IPI RZ_OWN RzSetS *rz_config_dup_set(RZ_NULLABLE const RzSetS *set) {
|
||||
RzSetS *safe_set = rz_set_s_new(HT_STR_DUP);
|
||||
if (!safe_set) {
|
||||
return NULL;
|
||||
}
|
||||
rz_list_foreach (list, it, elem) {
|
||||
rz_list_append(safe_list, rz_str_dup(elem));
|
||||
if (!set) {
|
||||
return safe_set;
|
||||
}
|
||||
return safe_list;
|
||||
|
||||
RzIterator *it = rz_set_s_as_iter(set);
|
||||
const char **elem;
|
||||
rz_iterator_foreach(it, elem) {
|
||||
rz_set_s_add(safe_set, *elem);
|
||||
}
|
||||
rz_iterator_free(it);
|
||||
return safe_set;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -221,14 +222,14 @@ static inline bool config_init_var_string(RzConfigVar *var, const char *name, co
|
|||
return true;
|
||||
}
|
||||
|
||||
static inline bool config_init_var_list(RzConfigVar *var, const char *name, const char *desc, RZ_OWN RzList /*<char *>*/ *value) {
|
||||
static inline bool config_init_var_set(RzConfigVar *var, const char *name, const char *desc, RZ_OWN RzSetS *value) {
|
||||
var->name = rz_str_dup(name);
|
||||
var->value.list = value;
|
||||
if (!var->name || !var->value.list) {
|
||||
var->value.set = value;
|
||||
if (!var->name || !var->value.set) {
|
||||
return false;
|
||||
}
|
||||
var->desc = rz_str_dup(desc);
|
||||
var->flags = RZ_CONFIG_VAR_FLAG_WRITABLE | RZ_CONFIG_VAR_TYPE_LIST;
|
||||
var->flags = RZ_CONFIG_VAR_FLAG_WRITABLE | RZ_CONFIG_VAR_TYPE_SET;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -253,11 +254,11 @@ static inline bool config_var_bind_set_options(RzConfigVar *var) {
|
|||
return true;
|
||||
}
|
||||
|
||||
RzList *options = NULL;
|
||||
RzSetS *options = NULL;
|
||||
if (!var->bind.get_options(var->bind.user, &options)) {
|
||||
return false;
|
||||
}
|
||||
rz_list_free(var->options);
|
||||
rz_set_s_free(var->options);
|
||||
var->options = options;
|
||||
return true;
|
||||
}
|
||||
|
|
@ -373,37 +374,39 @@ RZ_API bool rz_config_add_options(RZ_NONNULL RzConfig *cfg, RZ_NONNULL const cha
|
|||
}
|
||||
|
||||
va_list argp;
|
||||
RzList *list = rz_list_newf(free);
|
||||
if (!list) {
|
||||
RZ_LOG_ERROR("config: failed to initialize options list for '%s'.\n", name);
|
||||
RzSetS *set = rz_set_s_new(HT_STR_DUP);
|
||||
if (!set) {
|
||||
RZ_LOG_ERROR("config: failed to initialize options set for '%s'.\n", name);
|
||||
config_var_fini(&new_entry.var);
|
||||
return false;
|
||||
}
|
||||
|
||||
va_start(argp, desc);
|
||||
bool ok = config_var_args_to_list(argp, list);
|
||||
const char *first = va_arg(argp, const char *);
|
||||
if (first) {
|
||||
rz_set_s_add(set, first);
|
||||
}
|
||||
bool ok = config_var_args_to_set(argp, set);
|
||||
va_end(argp);
|
||||
if (!ok) {
|
||||
RZ_LOG_ERROR("config: failed to initialize options list for '%s'.\n", name);
|
||||
rz_list_free(list);
|
||||
RZ_LOG_ERROR("config: failed to initialize options set for '%s'.\n", name);
|
||||
rz_set_s_free(set);
|
||||
config_var_fini(&new_entry.var);
|
||||
return false;
|
||||
}
|
||||
|
||||
const char *first = rz_list_first_val(list);
|
||||
if (!config_init_var_string(&new_entry.var, name, desc, first)) {
|
||||
RZ_LOG_ERROR("config: failed to initialize '%s'.\n", name);
|
||||
config_var_fini(&new_entry.var);
|
||||
return false;
|
||||
}
|
||||
new_entry.var.options = list;
|
||||
new_entry.var.options = set;
|
||||
|
||||
config_add_entry(cfg, name, &new_entry, true);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Adds a list variable if doesn't exists.
|
||||
* \brief Adds a set variable if doesn't exists.
|
||||
*
|
||||
* \param cfg The configuration where to add the variable
|
||||
* \param[in] name The name of the variable to add
|
||||
|
|
@ -412,7 +415,7 @@ RZ_API bool rz_config_add_options(RZ_NONNULL RzConfig *cfg, RZ_NONNULL const cha
|
|||
*
|
||||
* \return On success returns true, otherwise false
|
||||
*/
|
||||
RZ_API bool rz_config_add_list(RZ_NONNULL RzConfig *cfg, RZ_NONNULL const char *name, RZ_NULLABLE const char *desc, ...) {
|
||||
RZ_API bool rz_config_add_set(RZ_NONNULL RzConfig *cfg, RZ_NONNULL const char *name, RZ_NULLABLE const char *desc, ...) {
|
||||
rz_return_val_if_fail(cfg && RZ_STR_ISNOTEMPTY(name), false);
|
||||
RzConfigEntry new_entry = { 0 };
|
||||
if (config_find_entry(cfg, name)) {
|
||||
|
|
@ -421,18 +424,18 @@ RZ_API bool rz_config_add_list(RZ_NONNULL RzConfig *cfg, RZ_NONNULL const char *
|
|||
}
|
||||
|
||||
va_list argp;
|
||||
RzList *list = rz_list_newf(free);
|
||||
if (!list) {
|
||||
RzSetS *set = rz_set_s_new(HT_STR_DUP);
|
||||
if (!set) {
|
||||
return false;
|
||||
}
|
||||
|
||||
va_start(argp, desc);
|
||||
bool ok = config_var_args_to_list(argp, list);
|
||||
bool ok = config_var_args_to_set(argp, set);
|
||||
va_end(argp);
|
||||
if (!ok) {
|
||||
rz_list_free(list);
|
||||
rz_set_s_free(set);
|
||||
return false;
|
||||
} else if (!config_init_var_list(&new_entry.var, name, desc, list)) {
|
||||
} else if (!config_init_var_set(&new_entry.var, name, desc, set)) {
|
||||
RZ_LOG_ERROR("config: failed to initialize '%s'.\n", name);
|
||||
config_var_fini(&new_entry.var);
|
||||
return false;
|
||||
|
|
@ -519,16 +522,17 @@ RZ_API bool rz_config_var_as_json(RZ_NONNULL const RzConfigVar *var, RZ_NONNULL
|
|||
pj_kn(pj, key, rz_config_var_get_integer(var));
|
||||
} else if (rz_config_var_has_type(var, RZ_CONFIG_VAR_TYPE_STR)) {
|
||||
pj_ks(pj, key, rz_config_var_get_string(var));
|
||||
} else if (rz_config_var_has_type(var, RZ_CONFIG_VAR_TYPE_LIST)) {
|
||||
const char *value;
|
||||
RzListIter *it;
|
||||
RzList *list = rz_config_var_get_list(var);
|
||||
} else if (rz_config_var_has_type(var, RZ_CONFIG_VAR_TYPE_SET)) {
|
||||
const char **value;
|
||||
RzSetS *set = rz_config_var_get_set(var);
|
||||
RzIterator *it = rz_set_s_as_iter(set);
|
||||
pj_ka(pj, key);
|
||||
rz_list_foreach (list, it, value) {
|
||||
pj_s(pj, value);
|
||||
rz_iterator_foreach(it, value) {
|
||||
pj_s(pj, *value);
|
||||
}
|
||||
rz_iterator_free(it);
|
||||
pj_end(pj);
|
||||
rz_list_free(list);
|
||||
rz_set_s_free(set);
|
||||
} else if (rz_config_var_has_type(var, RZ_CONFIG_VAR_TYPE_ITV)) {
|
||||
RzInterval itv = rz_config_var_get_interval(var);
|
||||
pj_ko(pj, key);
|
||||
|
|
@ -558,10 +562,20 @@ RZ_API RZ_OWN char *rz_config_var_as_string(RZ_NONNULL const RzConfigVar *var) {
|
|||
} else if (rz_config_var_has_type(var, RZ_CONFIG_VAR_TYPE_STR)) {
|
||||
const char *str = rz_config_var_get_string(var);
|
||||
return rz_str_dup(str);
|
||||
} else if (rz_config_var_has_type(var, RZ_CONFIG_VAR_TYPE_LIST)) {
|
||||
RzList *list = rz_config_var_get_list(var);
|
||||
char *value = rz_list_to_str(list, ',', false);
|
||||
rz_list_free(list);
|
||||
} else if (rz_config_var_has_type(var, RZ_CONFIG_VAR_TYPE_SET)) {
|
||||
RzSetS *set = rz_config_var_get_set(var);
|
||||
RzStrBuf *sb = rz_strbuf_new("");
|
||||
RzIterator *it = rz_set_s_as_iter(set);
|
||||
const char **val;
|
||||
rz_iterator_foreach(it, val) {
|
||||
if (rz_strbuf_length(sb) > 0) {
|
||||
rz_strbuf_append(sb, ",");
|
||||
}
|
||||
rz_strbuf_append(sb, *val);
|
||||
}
|
||||
rz_iterator_free(it);
|
||||
char *value = rz_strbuf_drain(sb);
|
||||
rz_set_s_free(set);
|
||||
return value;
|
||||
} else if (rz_config_var_has_type(var, RZ_CONFIG_VAR_TYPE_ITV)) {
|
||||
RzInterval itv = rz_config_var_get_interval(var);
|
||||
|
|
@ -658,22 +672,22 @@ RZ_API const char *rz_config_var_get_string(RZ_NONNULL const RzConfigVar *var) {
|
|||
}
|
||||
|
||||
/**
|
||||
* \brief Returns the list held by the RzConfigVar (must be a list type)
|
||||
* \brief Returns the set held by the RzConfigVar (must be a set type)
|
||||
*
|
||||
* \param[in] var The RzConfigVar to use
|
||||
*
|
||||
* \return Returns the value held by the RzConfigVar
|
||||
*/
|
||||
RZ_API RZ_OWN RzList /*<const char *>*/ *rz_config_var_get_list(RZ_NONNULL const RzConfigVar *var) {
|
||||
config_var_assert_return(var && RZ_CONFIG_VAR_IS_TYPE(var->flags, RZ_CONFIG_VAR_TYPE_LIST), var ? var->name : "(null)", false);
|
||||
RZ_API RZ_OWN RzSetS *rz_config_var_get_set(RZ_NONNULL const RzConfigVar *var) {
|
||||
config_var_assert_return(var && RZ_CONFIG_VAR_IS_TYPE(var->flags, RZ_CONFIG_VAR_TYPE_SET), var ? var->name : "(null)", false);
|
||||
|
||||
if (!(RZ_CONFIG_VAR_HAS_FLAG(var->flags, RZ_CONFIG_VAR_FLAG_BIND))) {
|
||||
return rz_list_clone(var->value.list);
|
||||
return rz_config_dup_set(var->value.set);
|
||||
}
|
||||
|
||||
RzList /*<char *>*/ *value = NULL;
|
||||
RzSetS *value = NULL;
|
||||
if (!config_var_bind_get_value(var, &value) || !value) {
|
||||
return rz_list_new();
|
||||
return rz_set_s_new(HT_STR_DUP);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
|
@ -769,7 +783,7 @@ RZ_API const char *rz_config_var_get_desc(RZ_NONNULL const RzConfigVar *var) {
|
|||
*
|
||||
* \return The options (can be NULL)
|
||||
*/
|
||||
RZ_API const RzList /*<char *>*/ *rz_config_var_get_options(RZ_NONNULL const RzConfigVar *var) {
|
||||
RZ_API const RzSetS *rz_config_var_get_options(RZ_NONNULL const RzConfigVar *var) {
|
||||
rz_return_val_if_fail(var, NULL);
|
||||
return var->options;
|
||||
}
|
||||
|
|
@ -798,8 +812,8 @@ RZ_API RZ_OWN char *rz_config_var_flags_as_string(ut32 flags) {
|
|||
case RZ_CONFIG_VAR_TYPE_STR:
|
||||
rz_strbuf_append(&sb, "string");
|
||||
break;
|
||||
case RZ_CONFIG_VAR_TYPE_LIST:
|
||||
rz_strbuf_append(&sb, "list");
|
||||
case RZ_CONFIG_VAR_TYPE_SET:
|
||||
rz_strbuf_append(&sb, "set");
|
||||
break;
|
||||
case RZ_CONFIG_VAR_TYPE_ITV:
|
||||
rz_strbuf_append(&sb, "interval");
|
||||
|
|
@ -865,20 +879,22 @@ RZ_IPI bool rz_config_var_set_integer(RzConfigVar *var, ut64 value) {
|
|||
}
|
||||
|
||||
static bool config_var_has_option(RzConfigVar *var, const char *value) {
|
||||
if (rz_list_length(var->options) < 1) {
|
||||
if (!var->options || rz_set_s_size(var->options) < 1) {
|
||||
// there are no options so the value is always valid.
|
||||
return true;
|
||||
}
|
||||
// we consider NULL as "" (empty string)
|
||||
value = rz_str_get(value);
|
||||
|
||||
const char *opt;
|
||||
RzListIter *it;
|
||||
rz_list_foreach (var->options, it, opt) {
|
||||
if (RZ_STR_EQ(opt, value)) {
|
||||
const char **opt;
|
||||
RzIterator *it = rz_set_s_as_iter(var->options);
|
||||
rz_iterator_foreach(it, opt) {
|
||||
if (RZ_STR_EQ(*opt, value)) {
|
||||
rz_iterator_free(it);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
rz_iterator_free(it);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -903,8 +919,8 @@ RZ_IPI bool rz_config_var_set_string(RzConfigVar *var, const char *value) {
|
|||
return true;
|
||||
}
|
||||
|
||||
RZ_IPI bool rz_config_var_set_list(RzConfigVar *var, const RzList /*<const char *>*/ *value) {
|
||||
config_var_assert_return(RZ_CONFIG_VAR_IS_TYPE(var->flags, RZ_CONFIG_VAR_TYPE_LIST), var->name, false);
|
||||
RZ_IPI bool rz_config_var_set_set(RzConfigVar *var, const RzSetS *value) {
|
||||
config_var_assert_return(RZ_CONFIG_VAR_IS_TYPE(var->flags, RZ_CONFIG_VAR_TYPE_SET), var->name, false);
|
||||
if (rz_config_var_is_readonly(var)) {
|
||||
RZ_LOG_ERROR("config: '%s' is a read only variable\n", var->name);
|
||||
return false;
|
||||
|
|
@ -916,13 +932,13 @@ RZ_IPI bool rz_config_var_set_list(RzConfigVar *var, const RzList /*<const char
|
|||
return false;
|
||||
}
|
||||
|
||||
rz_list_free(var->value.list);
|
||||
var->value.list = rz_config_dup_list(value);
|
||||
rz_set_s_free(var->value.set);
|
||||
var->value.set = rz_config_dup_set(value);
|
||||
return true;
|
||||
}
|
||||
|
||||
RZ_IPI bool rz_config_var_set_list2(RzConfigVar *var, RZ_OWN RzList /*<char *>*/ *value) {
|
||||
config_var_assert_return(RZ_CONFIG_VAR_IS_TYPE(var->flags, RZ_CONFIG_VAR_TYPE_LIST), var->name, false);
|
||||
RZ_IPI bool rz_config_var_set_set2(RzConfigVar *var, RZ_OWN RzSetS *value) {
|
||||
config_var_assert_return(RZ_CONFIG_VAR_IS_TYPE(var->flags, RZ_CONFIG_VAR_TYPE_SET), var->name, false);
|
||||
if (rz_config_var_is_readonly(var)) {
|
||||
RZ_LOG_ERROR("config: '%s' is a read only variable\n", var->name);
|
||||
return false;
|
||||
|
|
@ -930,15 +946,15 @@ RZ_IPI bool rz_config_var_set_list2(RzConfigVar *var, RZ_OWN RzList /*<char *>*/
|
|||
|
||||
if (RZ_CONFIG_VAR_HAS_FLAG(var->flags, RZ_CONFIG_VAR_FLAG_BIND)) {
|
||||
bool ret = config_var_bind_set_value(var, value);
|
||||
rz_list_free(value);
|
||||
rz_set_s_free(value);
|
||||
return ret;
|
||||
} else if (!config_var_is_valid_value(var, value)) {
|
||||
rz_list_free(value);
|
||||
rz_set_s_free(value);
|
||||
return false;
|
||||
}
|
||||
|
||||
rz_list_free(var->value.list);
|
||||
var->value.list = value;
|
||||
rz_set_s_free(var->value.set);
|
||||
var->value.set = value;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -959,16 +975,16 @@ RZ_IPI bool rz_config_var_set_interval(RzConfigVar *var, RzInterval value) {
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool config_set_var_list_from_string(RzConfigVar *var, const char *value) {
|
||||
config_var_assert_return(RZ_CONFIG_VAR_IS_TYPE(var->flags, RZ_CONFIG_VAR_TYPE_LIST), var->name, false);
|
||||
RzList *list = NULL;
|
||||
static bool config_set_var_set_from_string(RzConfigVar *var, const char *value) {
|
||||
config_var_assert_return(RZ_CONFIG_VAR_IS_TYPE(var->flags, RZ_CONFIG_VAR_TYPE_SET), var->name, false);
|
||||
RzSetS *set = NULL;
|
||||
if (value) {
|
||||
list = rz_str_split_duplist(value, ",", true);
|
||||
set = rz_str_split_dupset(value, ",", true);
|
||||
} else {
|
||||
list = rz_list_new();
|
||||
set = rz_set_s_new(HT_STR_DUP);
|
||||
}
|
||||
|
||||
return rz_config_var_set_list2(var, list);
|
||||
return rz_config_var_set_set2(var, set);
|
||||
}
|
||||
|
||||
static bool config_set_var_interval_from_string(RzConfigVar *var, const char *value) {
|
||||
|
|
@ -1000,8 +1016,8 @@ RZ_IPI bool rz_config_var_set_any(RzConfigVar *var, const char *value) {
|
|||
return rz_config_var_set_integer(var, ivalue);
|
||||
} else if (RZ_CONFIG_VAR_IS_TYPE(var->flags, RZ_CONFIG_VAR_TYPE_STR)) {
|
||||
return rz_config_var_set_string(var, value);
|
||||
} else if (RZ_CONFIG_VAR_IS_TYPE(var->flags, RZ_CONFIG_VAR_TYPE_LIST)) {
|
||||
return config_set_var_list_from_string(var, value);
|
||||
} else if (RZ_CONFIG_VAR_IS_TYPE(var->flags, RZ_CONFIG_VAR_TYPE_SET)) {
|
||||
return config_set_var_set_from_string(var, value);
|
||||
} else if (RZ_CONFIG_VAR_IS_TYPE(var->flags, RZ_CONFIG_VAR_TYPE_ITV)) {
|
||||
return config_set_var_interval_from_string(var, value);
|
||||
}
|
||||
|
|
@ -1112,7 +1128,7 @@ RZ_API bool rz_config_set_bool(RZ_NONNULL RzConfig *cfg, RZ_NONNULL const char *
|
|||
}
|
||||
|
||||
/**
|
||||
* \brief Sets the value of a given list variable (must be list type)
|
||||
* \brief Sets the value of a given set variable (must be set type)
|
||||
*
|
||||
* \param cfg The configuration to use
|
||||
* \param[in] name The name of the variable to change
|
||||
|
|
@ -1120,7 +1136,7 @@ RZ_API bool rz_config_set_bool(RZ_NONNULL RzConfig *cfg, RZ_NONNULL const char *
|
|||
*
|
||||
* \return On success return true, otherwise false
|
||||
*/
|
||||
RZ_API bool rz_config_set_list(RZ_NONNULL RzConfig *cfg, RZ_NONNULL const char *name, RZ_NULLABLE const RzList /*<const char *>*/ *value) {
|
||||
RZ_API bool rz_config_set_set(RZ_NONNULL RzConfig *cfg, RZ_NONNULL const char *name, RZ_NULLABLE const RzSetS *value) {
|
||||
rz_return_val_if_fail(cfg && RZ_STR_ISNOTEMPTY(name), NULL);
|
||||
|
||||
RzConfigEntry *entry = config_find_entry(cfg, name);
|
||||
|
|
@ -1132,19 +1148,19 @@ RZ_API bool rz_config_set_list(RZ_NONNULL RzConfig *cfg, RZ_NONNULL const char *
|
|||
return false;
|
||||
}
|
||||
|
||||
return rz_config_var_set_list(&entry->var, value);
|
||||
return rz_config_var_set_set(&entry->var, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Sets the value of a given list variable (must be list type)
|
||||
* \brief Sets the value of a given set variable (must be set type)
|
||||
*
|
||||
* \param cfg The configuration to use
|
||||
* \param[in] name The name of the variable to change
|
||||
* \param[in] ... The list of values to set (terminated by a NULL)
|
||||
* \param[in] ... The set of values to set (terminated by a NULL)
|
||||
*
|
||||
* \return On success return true, otherwise false
|
||||
*/
|
||||
RZ_API bool rz_config_set_list2(RZ_NONNULL RzConfig *cfg, RZ_NONNULL const char *name, ...) {
|
||||
RZ_API bool rz_config_set_set2(RZ_NONNULL RzConfig *cfg, RZ_NONNULL const char *name, ...) {
|
||||
rz_return_val_if_fail(cfg && RZ_STR_ISNOTEMPTY(name), NULL);
|
||||
|
||||
RzConfigEntry *entry = config_find_entry(cfg, name);
|
||||
|
|
@ -1157,25 +1173,25 @@ RZ_API bool rz_config_set_list2(RZ_NONNULL RzConfig *cfg, RZ_NONNULL const char
|
|||
}
|
||||
|
||||
va_list argp;
|
||||
RzList *list = rz_list_newf(free);
|
||||
if (!list) {
|
||||
RzSetS *set = rz_set_s_new(HT_STR_DUP);
|
||||
if (!set) {
|
||||
return false;
|
||||
}
|
||||
|
||||
va_start(argp, name);
|
||||
bool ok = config_var_args_to_list(argp, list);
|
||||
bool ok = config_var_args_to_set(argp, set);
|
||||
va_end(argp);
|
||||
if (!ok) {
|
||||
RZ_LOG_ERROR("config: failed to initialize list for '%s'.\n", name);
|
||||
rz_list_free(list);
|
||||
RZ_LOG_ERROR("config: failed to initialize set for '%s'.\n", name);
|
||||
rz_set_s_free(set);
|
||||
return false;
|
||||
}
|
||||
|
||||
return rz_config_var_set_list2(&entry->var, list);
|
||||
return rz_config_var_set_set2(&entry->var, set);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Sets the value of a given list variable (must be list type)
|
||||
* \brief Sets the value of a given set variable (must be set type)
|
||||
*
|
||||
* \param cfg The configuration to use
|
||||
* \param[in] name The name of the variable to change
|
||||
|
|
@ -1183,7 +1199,7 @@ RZ_API bool rz_config_set_list2(RZ_NONNULL RzConfig *cfg, RZ_NONNULL const char
|
|||
*
|
||||
* \return On success return true, otherwise false
|
||||
*/
|
||||
RZ_API bool rz_config_set_list3(RZ_NONNULL RzConfig *cfg, RZ_NONNULL const char *name, RZ_NULLABLE const char *comma_list) {
|
||||
RZ_API bool rz_config_set_set3(RZ_NONNULL RzConfig *cfg, RZ_NONNULL const char *name, RZ_NULLABLE const char *comma_list) {
|
||||
rz_return_val_if_fail(cfg && RZ_STR_ISNOTEMPTY(name), NULL);
|
||||
|
||||
RzConfigEntry *entry = config_find_entry(cfg, name);
|
||||
|
|
@ -1195,7 +1211,7 @@ RZ_API bool rz_config_set_list3(RZ_NONNULL RzConfig *cfg, RZ_NONNULL const char
|
|||
return false;
|
||||
}
|
||||
|
||||
return config_set_var_list_from_string(&entry->var, comma_list);
|
||||
return config_set_var_set_from_string(&entry->var, comma_list);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1283,7 +1299,7 @@ RZ_API bool rz_config_set_interval3(RZ_NONNULL RzConfig *cfg, RZ_NONNULL const c
|
|||
* - bool, the value `true` is set if `rz_str_is_true` returns true, otherwise is false (on NULL is set to false).
|
||||
* - integer, the value is parsed via RzNum (on NULL is set to 0)
|
||||
* - string, the value is kept as is (on NULL is set to "")
|
||||
* - list, the expected value is a comma separated list like `a,b,c` (on NULL is set to empty list)
|
||||
* - set, the expected value is a comma separated set like `a,b,c` (on NULL is set to empty set)
|
||||
* - interval, the expected value is a comma separated range (inclusive) like `from,to` where from <= to (on NULL is set to [0,0])
|
||||
*
|
||||
* \param cfg The configuration to use
|
||||
|
|
@ -1381,14 +1397,14 @@ RZ_API const char *rz_config_get_string(RZ_NONNULL const RzConfig *cfg, RZ_NONNU
|
|||
}
|
||||
|
||||
/**
|
||||
* \brief Returns the list held by the RzConfig (must be a list type)
|
||||
* \brief Returns the set held by the RzConfig (must be a set type)
|
||||
*
|
||||
* \param[in] cfg The RzConfig to use
|
||||
* \param[in] name The name of the list variable
|
||||
* \param[in] name The name of the set variable
|
||||
*
|
||||
* \return Returns the value held by the RzConfig
|
||||
*/
|
||||
RZ_API RZ_OWN RzList /*<const char *>*/ *rz_config_get_list(RZ_NONNULL const RzConfig *cfg, RZ_NONNULL const char *name) {
|
||||
RZ_API RZ_OWN RzSetS *rz_config_get_set(RZ_NONNULL const RzConfig *cfg, RZ_NONNULL const char *name) {
|
||||
rz_return_val_if_fail(cfg && RZ_STR_ISNOTEMPTY(name), NULL);
|
||||
|
||||
const RzConfigEntry *entry = config_find_entry_ro(cfg, name);
|
||||
|
|
@ -1402,7 +1418,7 @@ RZ_API RZ_OWN RzList /*<const char *>*/ *rz_config_get_list(RZ_NONNULL const RzC
|
|||
return NULL;
|
||||
}
|
||||
|
||||
return rz_config_var_get_list(&entry->var);
|
||||
return rz_config_var_get_set(&entry->var);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1467,7 +1483,7 @@ RZ_API RZ_OWN char *rz_config_get_as_string(RZ_NONNULL const RzConfig *cfg, RZ_N
|
|||
*
|
||||
* \return On success returns a pointer, can be NULL.
|
||||
*/
|
||||
RZ_API const RzList /*<char *>*/ *rz_config_get_options(RZ_NONNULL const RzConfig *cfg, RZ_NONNULL const char *name) {
|
||||
RZ_API const RzSetS *rz_config_get_options(RZ_NONNULL const RzConfig *cfg, RZ_NONNULL const char *name) {
|
||||
rz_return_val_if_fail(cfg && RZ_STR_ISNOTEMPTY(name), NULL);
|
||||
const RzConfigEntry *entry = config_find_entry_ro(cfg, name);
|
||||
if (!entry) {
|
||||
|
|
@ -1510,20 +1526,20 @@ RZ_API ut32 rz_config_get_flags(RZ_NONNULL const RzConfig *cfg, RZ_NONNULL const
|
|||
return rz_config_node_get_var_flags(&entry->node);
|
||||
}
|
||||
|
||||
static bool config_entry_set_options(RzConfigEntry *entry, RZ_NULLABLE RZ_OWN RzList /*<char *>*/ *options) {
|
||||
static bool config_entry_set_options(RzConfigEntry *entry, RZ_NULLABLE RZ_OWN RzSetS *options) {
|
||||
ut32 flags = config_entry_get_flags(entry);
|
||||
if (!(RZ_CONFIG_VAR_IS_TYPE(flags, RZ_CONFIG_VAR_TYPE_STR))) {
|
||||
const char *name = rz_config_entry_get_name(entry);
|
||||
RZ_LOG_ERROR("config: variable '%s' is not a string.\n", name);
|
||||
rz_list_free(options);
|
||||
rz_set_s_free(options);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (entry->is_variable) {
|
||||
rz_list_free(entry->var.options);
|
||||
rz_set_s_free(entry->var.options);
|
||||
entry->var.options = options;
|
||||
} else {
|
||||
rz_list_free(entry->node.options);
|
||||
rz_set_s_free(entry->node.options);
|
||||
entry->node.options = options;
|
||||
}
|
||||
|
||||
|
|
@ -1539,12 +1555,12 @@ static bool config_entry_set_options(RzConfigEntry *entry, RZ_NULLABLE RZ_OWN Rz
|
|||
*
|
||||
* \return On success returns a true, otherwise false.
|
||||
*/
|
||||
RZ_API bool rz_config_set_options(RZ_NONNULL RzConfig *cfg, RZ_NONNULL const char *name, RZ_NULLABLE RZ_OWN RzList /*<char *>*/ *options) {
|
||||
RZ_API bool rz_config_set_options(RZ_NONNULL RzConfig *cfg, RZ_NONNULL const char *name, RZ_NULLABLE RZ_OWN RzSetS *options) {
|
||||
rz_return_val_if_fail(cfg && RZ_STR_ISNOTEMPTY(name), false);
|
||||
RzConfigEntry *entry = config_find_entry(cfg, name);
|
||||
if (!entry) {
|
||||
RZ_LOG_ERROR("config: variable '%s' does not exists.\n", name);
|
||||
rz_list_free(options);
|
||||
rz_set_s_free(options);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -1556,7 +1572,7 @@ RZ_API bool rz_config_set_options(RZ_NONNULL RzConfig *cfg, RZ_NONNULL const cha
|
|||
*
|
||||
* \param[in] cfg The RzConfig to use
|
||||
* \param[in] name The name of the string type variable to update
|
||||
* \param[in] ... The list of options to set (NULL terminated)
|
||||
* \param[in] ... The set of options to set (NULL terminated)
|
||||
*
|
||||
* \return On success returns a true, otherwise false.
|
||||
*/
|
||||
|
|
@ -1569,16 +1585,16 @@ RZ_API bool rz_config_set_options2(RZ_NONNULL RzConfig *cfg, RZ_NONNULL const ch
|
|||
}
|
||||
|
||||
va_list argp;
|
||||
RzList *options = rz_list_newf(free);
|
||||
RzSetS *options = rz_set_s_new(HT_STR_DUP);
|
||||
if (!options) {
|
||||
return false;
|
||||
}
|
||||
|
||||
va_start(argp, name);
|
||||
bool ok = config_var_args_to_list(argp, options);
|
||||
bool ok = config_var_args_to_set(argp, options);
|
||||
va_end(argp);
|
||||
if (!ok) {
|
||||
rz_list_free(options);
|
||||
rz_set_s_free(options);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ typedef struct config_value_t {
|
|||
char *string;
|
||||
ut64 integer;
|
||||
bool boolean;
|
||||
RzList /*<char *>*/ *list;
|
||||
RzSetS *set;
|
||||
RzInterval interval;
|
||||
} value; ///< Copy of the variable value
|
||||
} ConfigValue;
|
||||
|
|
@ -54,13 +54,13 @@ static inline void config_add_entry(RzConfig *cfg, const char *name, RzConfigEnt
|
|||
rz_vector_insert_sorted(&cfg->sorted_vars, entry, (RzVectorComparator)sort_variables, NULL);
|
||||
}
|
||||
|
||||
RZ_IPI RZ_OWN RzList /*<char *>*/ *rz_config_dup_list(RZ_NULLABLE const RzList /*<const char *>*/ *list);
|
||||
RZ_IPI RZ_OWN RzSetS *rz_config_dup_set(RZ_NULLABLE const RzSetS *set);
|
||||
|
||||
RZ_IPI bool rz_config_var_set_bool(RzConfigVar *var, bool value);
|
||||
RZ_IPI bool rz_config_var_set_integer(RzConfigVar *var, ut64 value);
|
||||
RZ_IPI bool rz_config_var_set_string(RzConfigVar *var, const char *value);
|
||||
RZ_IPI bool rz_config_var_set_list(RzConfigVar *var, const RzList /*<const char *>*/ *value);
|
||||
RZ_IPI bool rz_config_var_set_list2(RzConfigVar *var, RZ_OWN RzList /*<char *>*/ *value);
|
||||
RZ_IPI bool rz_config_var_set_set(RzConfigVar *var, const RzSetS *set);
|
||||
RZ_IPI bool rz_config_var_set_set2(RzConfigVar *var, RZ_OWN RzSetS *value);
|
||||
RZ_IPI bool rz_config_var_set_interval(RzConfigVar *var, RzInterval value);
|
||||
RZ_IPI bool rz_config_var_set_any(RzConfigVar *var, const char *value);
|
||||
RZ_IPI bool rz_config_toggle_var_bool(RzConfigVar *var);
|
||||
|
|
|
|||
|
|
@ -3,15 +3,6 @@
|
|||
|
||||
#include "config_internal.h"
|
||||
|
||||
static RzList /*<char *>*/ *config_hold_dup_safe_list(RzConfigVar *var) {
|
||||
// we do not know if the strings returned are
|
||||
// safe or not to be owned, so we just dup them
|
||||
RzList /*<const char *>*/ *list = rz_config_var_get_list(var);
|
||||
RzList *safe_list = rz_config_dup_list(list);
|
||||
rz_list_free(list);
|
||||
return safe_list;
|
||||
}
|
||||
|
||||
static void config_hold_value_init_from_node(ConfigValue *cv, RzConfigNode *node) {
|
||||
cv->name = node->name;
|
||||
if (rz_config_node_is_bool(node)) {
|
||||
|
|
@ -35,8 +26,8 @@ static void config_hold_value_init_from_var(ConfigValue *cv, RzConfigVar *var) {
|
|||
} else if (RZ_CONFIG_VAR_IS_TYPE(var->flags, RZ_CONFIG_VAR_TYPE_STR)) {
|
||||
const char *str = rz_config_var_get_string(var);
|
||||
cv->value.string = rz_str_dup(str);
|
||||
} else if (RZ_CONFIG_VAR_IS_TYPE(var->flags, RZ_CONFIG_VAR_TYPE_LIST)) {
|
||||
cv->value.list = config_hold_dup_safe_list(var);
|
||||
} else if (RZ_CONFIG_VAR_IS_TYPE(var->flags, RZ_CONFIG_VAR_TYPE_SET)) {
|
||||
cv->value.set = rz_config_var_get_set(var);
|
||||
} else if (RZ_CONFIG_VAR_IS_TYPE(var->flags, RZ_CONFIG_VAR_TYPE_INT)) {
|
||||
cv->value.integer = rz_config_var_get_integer(var);
|
||||
} else {
|
||||
|
|
@ -104,8 +95,8 @@ static void config_hold_value_fini(void *e, void *user) {
|
|||
ConfigValue *cv = (ConfigValue *)e;
|
||||
if (RZ_CONFIG_VAR_IS_TYPE(cv->flags, RZ_CONFIG_VAR_TYPE_STR)) {
|
||||
free(cv->value.string);
|
||||
} else if (RZ_CONFIG_VAR_IS_TYPE(cv->flags, RZ_CONFIG_VAR_TYPE_LIST)) {
|
||||
rz_list_free(cv->value.list);
|
||||
} else if (RZ_CONFIG_VAR_IS_TYPE(cv->flags, RZ_CONFIG_VAR_TYPE_SET)) {
|
||||
rz_set_s_free(cv->value.set);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -211,10 +202,10 @@ RZ_API void rz_config_hold_restore(RZ_NULLABLE RzConfigHold *hold) {
|
|||
config_hold_set_integer(entry, cv->value.integer, cfg_user);
|
||||
} else if (RZ_CONFIG_VAR_IS_TYPE(cv->flags, RZ_CONFIG_VAR_TYPE_STR)) {
|
||||
config_hold_set_string(entry, cv->value.string, cfg_user);
|
||||
} else if (RZ_CONFIG_VAR_IS_TYPE(cv->flags, RZ_CONFIG_VAR_TYPE_LIST)) {
|
||||
// ownership of list moved to var.
|
||||
rz_config_var_set_list(&entry->var, cv->value.list);
|
||||
cv->value.list = NULL;
|
||||
} else if (RZ_CONFIG_VAR_IS_TYPE(cv->flags, RZ_CONFIG_VAR_TYPE_SET)) {
|
||||
// ownership of set moved to var.
|
||||
rz_config_var_set_set2(&entry->var, cv->value.set);
|
||||
cv->value.set = NULL;
|
||||
} else { /// RZ_CONFIG_VAR_TYPE_ITV
|
||||
rz_config_var_set_interval(&entry->var, cv->value.interval);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ static bool config_node_init(RzConfigNode *node, RZ_NONNULL const char *name, RZ
|
|||
node->value = rz_str_dup(value);
|
||||
node->flags = CN_STR;
|
||||
node->i_value = rz_num_get(NULL, value);
|
||||
node->options = rz_list_new();
|
||||
node->options = rz_set_s_new(HT_STR_DUP);
|
||||
|
||||
return node->name && node->value && node->options;
|
||||
}
|
||||
|
|
@ -24,7 +24,7 @@ RZ_IPI void rz_config_node_fini(RZ_NULLABLE RzConfigNode *node) {
|
|||
free(node->name);
|
||||
free(node->desc);
|
||||
free(node->value);
|
||||
rz_list_free(node->options);
|
||||
rz_set_s_free(node->options);
|
||||
}
|
||||
|
||||
RZ_API RZ_BORROW RzConfigNode *rz_config_node_get(RZ_BORROW RzConfig *cfg, RZ_NONNULL const char *name) {
|
||||
|
|
|
|||
|
|
@ -89,8 +89,7 @@ RZ_DEPRECATE static void core_update_config_bits_options(RzCore *core, const cha
|
|||
return;
|
||||
}
|
||||
|
||||
node->options->free = free;
|
||||
rz_list_purge(node->options);
|
||||
rz_set_s_clear(node->options);
|
||||
if (!core->rasm) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -98,20 +97,21 @@ RZ_DEPRECATE static void core_update_config_bits_options(RzCore *core, const cha
|
|||
ut32 bits = rz_asm_get_plugin_bits(core->rasm);
|
||||
for (ut32 i = 1; i <= bits; i <<= 1) {
|
||||
if (i & bits) {
|
||||
rz_list_append(node->options, rz_str_newf("%u", i));
|
||||
char *s = rz_str_newf("%u", i);
|
||||
rz_set_s_add(node->options, s);
|
||||
free(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RZ_DEPRECATE static void core_update_config_options(RzConfigNode *node, const char *list_comma_sep) {
|
||||
if (RZ_STR_ISEMPTY(list_comma_sep)) {
|
||||
node->options->free = free;
|
||||
rz_list_purge(node->options);
|
||||
rz_set_s_clear(node->options);
|
||||
return;
|
||||
}
|
||||
|
||||
rz_list_free(node->options);
|
||||
node->options = rz_str_split_duplist(list_comma_sep, ",", true);
|
||||
rz_set_s_free(node->options);
|
||||
node->options = rz_str_split_dupset(list_comma_sep, ",", true);
|
||||
}
|
||||
|
||||
// copied from cconfig.c & cleaned
|
||||
|
|
@ -120,8 +120,7 @@ RZ_DEPRECATE static void core_update_config_cpu_options(RzCore *core, const char
|
|||
if (!node) {
|
||||
return;
|
||||
} else if (!core->rasm) {
|
||||
node->options->free = free;
|
||||
rz_list_purge(node->options);
|
||||
rz_set_s_clear(node->options);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -135,8 +134,7 @@ static void core_update_config_platform_options(RzCore *core, const char *name)
|
|||
if (!node) {
|
||||
return;
|
||||
} else if (!core->rasm) {
|
||||
node->options->free = free;
|
||||
rz_list_purge(node->options);
|
||||
rz_set_s_clear(node->options);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -150,8 +148,7 @@ static void core_update_config_features_options(RzCore *core, const char *name)
|
|||
if (!node) {
|
||||
return;
|
||||
} else if (!core->rasm) {
|
||||
node->options->free = free;
|
||||
rz_list_purge(node->options);
|
||||
rz_set_s_clear(node->options);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -878,7 +878,7 @@ static void autocmplt_cmd_arg_eval_full(RzCore *core, RzLineNSCompletionResult *
|
|||
|
||||
char *k = rz_str_ndup(s, eq - s);
|
||||
char *v = NULL;
|
||||
const RzList *options = rz_config_get_options(core->config, k);
|
||||
const RzSetS *options = rz_config_get_options(core->config, k);
|
||||
if (!options) {
|
||||
goto err;
|
||||
}
|
||||
|
|
@ -889,14 +889,15 @@ static void autocmplt_cmd_arg_eval_full(RzCore *core, RzLineNSCompletionResult *
|
|||
|
||||
res->start += strlen(k) + 1;
|
||||
|
||||
if (rz_list_length(options) > 0) {
|
||||
const RzListIter *iter;
|
||||
const char *opt;
|
||||
rz_list_foreach (options, iter, opt) {
|
||||
if (!strncmp(opt, v, len)) {
|
||||
rz_line_ns_completion_result_add(res, opt);
|
||||
if (rz_set_s_size(options) > 0) {
|
||||
RzIterator *iter = rz_set_s_as_iter(options);
|
||||
const char **opt;
|
||||
rz_iterator_foreach(iter, opt) {
|
||||
if (!strncmp(*opt, v, len)) {
|
||||
rz_line_ns_completion_result_add(res, *opt);
|
||||
}
|
||||
}
|
||||
rz_iterator_free(iter);
|
||||
} else if (RZ_CONFIG_VAR_IS_TYPE(flags, RZ_CONFIG_VAR_TYPE_BOOL)) {
|
||||
if (!strncmp("true", v, len)) {
|
||||
rz_line_ns_completion_result_add(res, "true");
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ static void set_options(RzConfigNode *node, ...) {
|
|||
va_start(argp, node);
|
||||
option = va_arg(argp, char *);
|
||||
while (option) {
|
||||
rz_list_append(node->options, option);
|
||||
rz_set_s_add(node->options, option);
|
||||
option = va_arg(argp, char *);
|
||||
}
|
||||
va_end(argp);
|
||||
|
|
@ -55,11 +55,12 @@ static bool isGdbPlugin(RzCore *core) {
|
|||
}
|
||||
|
||||
static void print_node_options(RzConfigNode *node) {
|
||||
RzListIter *iter;
|
||||
char *option;
|
||||
rz_list_foreach (node->options, iter, option) {
|
||||
rz_cons_printf("%s\n", option);
|
||||
RzIterator *iter = rz_set_s_as_iter(node->options);
|
||||
const char **option;
|
||||
rz_iterator_foreach(iter, option) {
|
||||
rz_cons_printf("%s\n", *option);
|
||||
}
|
||||
rz_iterator_free(iter);
|
||||
}
|
||||
|
||||
static int compareName(const RzAnalysisFunction *a, const RzAnalysisFunction *b, void *user) {
|
||||
|
|
@ -98,7 +99,7 @@ static void update_asmarch_options(RzCore *core, RzConfigNode *node) {
|
|||
|
||||
RzAsmPlugin **val;
|
||||
RzIterator *it = rz_asm_plugin_iterator(core->rasm);
|
||||
rz_list_purge(node->options);
|
||||
rz_set_s_clear(node->options);
|
||||
rz_iterator_foreach(it, val) {
|
||||
RzAsmPlugin *h = *val;
|
||||
SETOPTIONS(node, h->name, NULL);
|
||||
|
|
@ -112,8 +113,7 @@ static void update_asmbits_options(RzCore *core, RzConfigNode *node) {
|
|||
}
|
||||
|
||||
int bits = rz_asm_get_plugin_bits(core->rasm);
|
||||
node->options->free = free;
|
||||
rz_list_purge(node->options);
|
||||
rz_set_s_clear(node->options);
|
||||
for (int i = 1; i <= bits; i <<= 1) {
|
||||
if (i & bits) {
|
||||
SETOPTIONS(node, rz_str_newf("%d", i), NULL);
|
||||
|
|
@ -128,12 +128,12 @@ static void update_asmfeatures_options(RzCore *core, RzConfigNode *node) {
|
|||
|
||||
const char *features = rz_asm_get_plugin_features(core->rasm);
|
||||
if (RZ_STR_ISEMPTY(features)) {
|
||||
rz_list_purge(node->options);
|
||||
rz_set_s_clear(node->options);
|
||||
return;
|
||||
}
|
||||
|
||||
rz_list_free(node->options);
|
||||
node->options = rz_str_split_duplist(features, ",", true);
|
||||
rz_set_s_free(node->options);
|
||||
node->options = rz_str_split_dupset(features, ",", true);
|
||||
}
|
||||
|
||||
static void update_asmplatforms_options(RzCore *core, RzConfigNode *node) {
|
||||
|
|
@ -143,19 +143,19 @@ static void update_asmplatforms_options(RzCore *core, RzConfigNode *node) {
|
|||
|
||||
const char *platforms = rz_asm_get_plugin_platforms(core->rasm);
|
||||
if (RZ_STR_ISEMPTY(platforms)) {
|
||||
rz_list_purge(node->options);
|
||||
rz_set_s_clear(node->options);
|
||||
return;
|
||||
}
|
||||
|
||||
rz_list_free(node->options);
|
||||
node->options = rz_str_split_duplist(platforms, ",", true);
|
||||
rz_set_s_free(node->options);
|
||||
node->options = rz_str_split_dupset(platforms, ",", true);
|
||||
}
|
||||
|
||||
static void update_asmparser_options(RzCore *core, RzConfigNode *node) {
|
||||
RzListIter *iter;
|
||||
RzParsePlugin *parser;
|
||||
if (core && node && core->parser && core->parser->parsers) {
|
||||
rz_list_purge(node->options);
|
||||
rz_set_s_clear(node->options);
|
||||
rz_list_foreach (core->parser->parsers, iter, parser) {
|
||||
SETOPTIONS(node, parser->name, NULL);
|
||||
}
|
||||
|
|
@ -167,12 +167,12 @@ static void update_asmcpu_options(RzCore *core, RzConfigNode *node) {
|
|||
|
||||
const char *cpus = rz_asm_get_plugin_cpus(core->rasm);
|
||||
if (RZ_STR_ISEMPTY(cpus)) {
|
||||
rz_list_purge(node->options);
|
||||
rz_set_s_clear(node->options);
|
||||
return;
|
||||
}
|
||||
|
||||
rz_list_free(node->options);
|
||||
node->options = rz_str_split_duplist(cpus, ",", true);
|
||||
rz_set_s_free(node->options);
|
||||
node->options = rz_str_split_dupset(cpus, ",", true);
|
||||
}
|
||||
|
||||
static bool cb_search_case_sensitive(void *_core, void *_node) {
|
||||
|
|
@ -459,7 +459,7 @@ static void update_analysis_arch_options(RzCore *core, RzConfigNode *node) {
|
|||
RzIterator *it = rz_analysis_plugin_iterator(core->analysis);
|
||||
RzAnalysisPlugin **val;
|
||||
if (core && core->analysis && node) {
|
||||
rz_list_purge(node->options);
|
||||
rz_set_s_clear(node->options);
|
||||
rz_iterator_foreach(it, val) {
|
||||
RzAnalysisPlugin *h = *val;
|
||||
SETOPTIONS(node, h->name, NULL);
|
||||
|
|
@ -946,18 +946,20 @@ static bool cb_search_str_check_ascii_freq(void *user, void *data) {
|
|||
}
|
||||
|
||||
static bool find_encoding(RzConfigNode *node, RzStrEnc *encoding) {
|
||||
RzListIter *iter;
|
||||
const char *option;
|
||||
rz_list_foreach (node->options, iter, option) {
|
||||
if (rz_str_casecmp(option, node->value)) {
|
||||
RzIterator *iter = rz_set_s_as_iter(node->options);
|
||||
const char **option;
|
||||
rz_iterator_foreach(iter, option) {
|
||||
if (rz_str_casecmp(*option, node->value)) {
|
||||
continue;
|
||||
}
|
||||
free(node->value);
|
||||
node->value = rz_str_dup(option);
|
||||
*encoding = rz_str_enc_string_as_type(option);
|
||||
node->value = rz_str_dup(*option);
|
||||
*encoding = rz_str_enc_string_as_type(*option);
|
||||
rz_iterator_free(iter);
|
||||
return true;
|
||||
}
|
||||
if (rz_list_empty(node->options)) {
|
||||
rz_iterator_free(iter);
|
||||
if (rz_set_s_size(node->options) == 0) {
|
||||
// Edge case when the node was just initialized but the options
|
||||
// were not added yet.
|
||||
*encoding = rz_str_enc_string_as_type(node->value);
|
||||
|
|
@ -1594,12 +1596,15 @@ static bool cb_iopcachewrite(void *user, void *data) {
|
|||
return true;
|
||||
}
|
||||
|
||||
static void config_print_options_as_json(PJ *pj, const RzList /*<char *>*/ *options) {
|
||||
RzListIter *iter;
|
||||
const char *option;
|
||||
static void config_print_options_as_json(PJ *pj, const RzSetS *options) {
|
||||
pj_ka(pj, "options");
|
||||
rz_list_foreach (options, iter, option) {
|
||||
pj_s(pj, option);
|
||||
if (options) {
|
||||
RzIterator *iter = rz_set_s_as_iter(options);
|
||||
const char **option;
|
||||
rz_iterator_foreach(iter, option) {
|
||||
pj_s(pj, *option);
|
||||
}
|
||||
rz_iterator_free(iter);
|
||||
}
|
||||
pj_end(pj);
|
||||
}
|
||||
|
|
@ -1636,7 +1641,7 @@ static void config_print_node_as_long_json(const RzConfigNode *node, PJ *pj) {
|
|||
static void config_print_var_as_long_json(const RzConfigVar *var, PJ *pj) {
|
||||
const char *name = rz_config_var_get_name(var);
|
||||
const char *desc = rz_config_var_get_desc(var);
|
||||
const RzList *options = rz_config_var_get_options(var);
|
||||
const RzSetS *options = rz_config_var_get_options(var);
|
||||
ut32 flags = rz_config_var_get_flags(var);
|
||||
pj_o(pj);
|
||||
config_print_long_json(pj, name, desc, flags);
|
||||
|
|
@ -1654,20 +1659,23 @@ typedef struct core_config_print_s {
|
|||
char reset_str[32];
|
||||
} CoreConfigPrint;
|
||||
|
||||
static void core_config_print_array_as_string(const RzList /*<char *>*/ *list, bool allow_empty) {
|
||||
const char *entry;
|
||||
const RzListIter *it;
|
||||
if (rz_list_empty(list) && !allow_empty) {
|
||||
static void core_config_print_set_as_string(const RzSetS *set, bool allow_empty) {
|
||||
if (rz_set_s_size(set) < 1 && !allow_empty) {
|
||||
return;
|
||||
}
|
||||
rz_cons_print("[");
|
||||
rz_list_foreach (list, it, entry) {
|
||||
if (rz_list_head(list) != it) {
|
||||
rz_cons_printf(", %s", entry);
|
||||
RzIterator *iter = rz_set_s_as_iter(set);
|
||||
const char **entry;
|
||||
bool first = true;
|
||||
rz_iterator_foreach(iter, entry) {
|
||||
if (!first) {
|
||||
rz_cons_printf(", %s", *entry);
|
||||
} else {
|
||||
rz_cons_print(entry);
|
||||
rz_cons_print(*entry);
|
||||
first = false;
|
||||
}
|
||||
}
|
||||
rz_iterator_free(iter);
|
||||
rz_cons_print("]");
|
||||
}
|
||||
|
||||
|
|
@ -1685,10 +1693,10 @@ static void core_config_print_var_as_string(const RzConfigEntry *entry, ut32 fla
|
|||
} else if (RZ_CONFIG_VAR_IS_TYPE(flags, RZ_CONFIG_VAR_TYPE_STR)) {
|
||||
const char *value = rz_config_entry_get_string(entry);
|
||||
rz_cons_print(value);
|
||||
} else if (RZ_CONFIG_VAR_IS_TYPE(flags, RZ_CONFIG_VAR_TYPE_LIST)) {
|
||||
RzList *list = rz_config_var_get_list(&entry->var);
|
||||
core_config_print_array_as_string(list, true);
|
||||
rz_list_free(list);
|
||||
} else if (RZ_CONFIG_VAR_IS_TYPE(flags, RZ_CONFIG_VAR_TYPE_SET)) {
|
||||
RzSetS *set = rz_config_var_get_set(&entry->var);
|
||||
core_config_print_set_as_string(set, true);
|
||||
rz_set_s_free(set);
|
||||
} else if (RZ_CONFIG_VAR_IS_TYPE(flags, RZ_CONFIG_VAR_TYPE_ITV)) {
|
||||
RzInterval itv = rz_config_var_get_interval(&entry->var);
|
||||
rz_cons_printf("[0x%08" PFMT64x ",0x%08" PFMT64x "]", rz_itv_begin(itv), rz_itv_end(itv));
|
||||
|
|
@ -1704,7 +1712,7 @@ static bool core_config_print_iterator(const RzConfigEntry *entry, void *user) {
|
|||
|
||||
const char *name = NULL;
|
||||
const char *desc = "";
|
||||
const RzList *options = NULL;
|
||||
const RzSetS *options = NULL;
|
||||
ut32 e_flags = 0;
|
||||
RzOutputMode mode = ccp->state->mode;
|
||||
PJ *pj = ccp->state->d.pj;
|
||||
|
|
@ -1742,7 +1750,7 @@ static bool core_config_print_iterator(const RzConfigEntry *entry, void *user) {
|
|||
rz_cons_printf("%s%20s = %s", ccp->color_name, name, ccp->color_value);
|
||||
core_config_print_var_as_string(entry, e_flags);
|
||||
rz_cons_printf(" %s(%s); %s%s ", ccp->color_meta, s_flags, ccp->reset_str, desc);
|
||||
core_config_print_array_as_string(options, false);
|
||||
core_config_print_set_as_string(options, false);
|
||||
rz_cons_println("");
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -75,17 +75,17 @@ static void config_visual_hit(RzCore *core, const char *name, int editor) {
|
|||
}
|
||||
|
||||
static void show_config_options(RzCore *core, const char *name) {
|
||||
const RzList *options = rz_config_get_options(core->config, name);
|
||||
if (rz_list_empty(options)) {
|
||||
const RzSetS *options = rz_config_get_options(core->config, name);
|
||||
if (rz_set_s_size(options) == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
int w = rz_cons_get_size(NULL);
|
||||
const char *item;
|
||||
const RzListIter *iter;
|
||||
const char **item;
|
||||
RzIterator *iter = rz_set_s_as_iter(options);
|
||||
RzStrBuf *sb = rz_strbuf_new(" Options: ");
|
||||
rz_list_foreach (options, iter, item) {
|
||||
rz_strbuf_appendf(sb, "%s%s", rz_list_val(iter) ? ", " : "", item);
|
||||
rz_iterator_foreach(iter, item) {
|
||||
rz_strbuf_appendf(sb, "%s%s", *item ? ", " : "", *item);
|
||||
if (rz_strbuf_length(sb) + 5 >= w) {
|
||||
char *s = rz_strbuf_drain(sb);
|
||||
rz_cons_println(s);
|
||||
|
|
@ -93,6 +93,7 @@ static void show_config_options(RzCore *core, const char *name) {
|
|||
sb = rz_strbuf_new("");
|
||||
}
|
||||
}
|
||||
rz_iterator_free(iter);
|
||||
char *s = rz_strbuf_drain(sb);
|
||||
rz_cons_println(s);
|
||||
free(s);
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ typedef struct rz_config_node_t {
|
|||
char **cb_ptr_s;
|
||||
RzConfigCallback setter;
|
||||
char *desc;
|
||||
RzList /*<char *>*/ *options;
|
||||
RzSetS *options;
|
||||
} RzConfigNode;
|
||||
|
||||
typedef enum {
|
||||
|
|
@ -52,7 +52,7 @@ typedef enum {
|
|||
RZ_CONFIG_VAR_TYPE_BOOL = 1,
|
||||
RZ_CONFIG_VAR_TYPE_INT = 2,
|
||||
RZ_CONFIG_VAR_TYPE_STR = 3,
|
||||
RZ_CONFIG_VAR_TYPE_LIST = 4,
|
||||
RZ_CONFIG_VAR_TYPE_SET = 4,
|
||||
RZ_CONFIG_VAR_TYPE_ITV = 5,
|
||||
// these are flags
|
||||
RZ_CONFIG_VAR_FLAG_BIND = 0x40000000,
|
||||
|
|
@ -67,14 +67,14 @@ typedef enum {
|
|||
|
||||
typedef bool (*RzConfigBindGet)(void *user, void *value);
|
||||
typedef bool (*RzConfigBindSet)(void *user, const void *value);
|
||||
typedef bool (*RzConfigBindOpts)(void *user, RzList /*<char *>*/ **options);
|
||||
typedef bool (*RzConfigBindOpts)(void *user, RzSetS **options);
|
||||
|
||||
typedef struct rz_config_owned_t {
|
||||
union {
|
||||
bool boolean; ///< Owned boolean
|
||||
ut64 integer; ///< Owned unsigned integer
|
||||
char *string; ///< Owned zero-terminated string (can be NULL)
|
||||
RzList /*<char *>*/ *list; ///< Owned list of zero-terminated string (can be NULL)
|
||||
RzSetS *set; ///< Owned set of zero-terminated string (can be NULL)
|
||||
RzInterval interval; ///< Owned interval
|
||||
};
|
||||
RzConfigBindSet validator; ///< Validator callback
|
||||
|
|
@ -91,7 +91,7 @@ typedef struct rz_config_bind_t {
|
|||
typedef struct rz_config_var_t {
|
||||
char *name; ///< Variable name
|
||||
char *desc; ///< Description of the variable
|
||||
RzList /*<char *>*/ *options; ///< Variable possible values
|
||||
RzSetS *options; ///< Variable possible values
|
||||
ut32 flags; ///< Define the type of the data via RzConfigVar (see RzConfigVarFlags)
|
||||
union {
|
||||
RzConfigOwned value; ///< owned value
|
||||
|
|
@ -135,39 +135,39 @@ RZ_API bool rz_config_add_bool(RZ_NONNULL RzConfig *cfg, RZ_NONNULL const char *
|
|||
RZ_API bool rz_config_add_integer(RZ_NONNULL RzConfig *cfg, RZ_NONNULL const char *name, RZ_NULLABLE const char *desc, ut64 value);
|
||||
RZ_API bool rz_config_add_string(RZ_NONNULL RzConfig *cfg, RZ_NONNULL const char *name, RZ_NULLABLE const char *desc, RZ_NULLABLE const char *value);
|
||||
RZ_API bool rz_config_add_options(RZ_NONNULL RzConfig *cfg, RZ_NONNULL const char *name, RZ_NULLABLE const char *desc, ...);
|
||||
RZ_API bool rz_config_add_list(RZ_NONNULL RzConfig *cfg, RZ_NONNULL const char *name, RZ_NULLABLE const char *desc, ...);
|
||||
RZ_API bool rz_config_add_set(RZ_NONNULL RzConfig *cfg, RZ_NONNULL const char *name, RZ_NULLABLE const char *desc, ...);
|
||||
RZ_API bool rz_config_add_interval(RZ_NONNULL RzConfig *cfg, RZ_NONNULL const char *name, RZ_NULLABLE const char *desc, ut64 from, ut64 to);
|
||||
|
||||
RZ_API bool rz_config_add_bind(RZ_NONNULL RzConfig *cfg, RZ_NONNULL const char *name, RZ_NULLABLE const char *desc, ut32 type, RZ_NONNULL RzConfigBindGet get, RZ_NULLABLE RzConfigBindSet set, RZ_NULLABLE RzConfigBindOpts opts, RZ_NULLABLE void *user);
|
||||
#define rz_config_add_bool_bind(cfg, name, desc, get, set, opts, user) rz_config_add_bind(cfg, name, desc, RZ_CONFIG_VAR_TYPE_BOOL, get, set, opts, user)
|
||||
#define rz_config_add_integer_bind(cfg, name, desc, get, set, opts, user) rz_config_add_bind(cfg, name, desc, RZ_CONFIG_VAR_TYPE_INT, get, set, opts, user)
|
||||
#define rz_config_add_string_bind(cfg, name, desc, get, set, opts, user) rz_config_add_bind(cfg, name, desc, RZ_CONFIG_VAR_TYPE_STR, get, set, opts, user)
|
||||
#define rz_config_add_list_bind(cfg, name, desc, get, set, opts, user) rz_config_add_bind(cfg, name, desc, RZ_CONFIG_VAR_TYPE_LIST, get, set, opts, user)
|
||||
#define rz_config_add_set_bind(cfg, name, desc, get, set, opts, user) rz_config_add_bind(cfg, name, desc, RZ_CONFIG_VAR_TYPE_SET, get, set, opts, user)
|
||||
#define rz_config_add_interval_bind(cfg, name, desc, get, set, opts, user) rz_config_add_bind(cfg, name, desc, RZ_CONFIG_VAR_TYPE_ITV, get, set, opts, user)
|
||||
|
||||
RZ_API bool rz_config_set_string(RZ_NONNULL RzConfig *cfg, RZ_NONNULL const char *name, RZ_NULLABLE const char *value);
|
||||
RZ_API bool rz_config_set_integer(RZ_NONNULL RzConfig *cfg, RZ_NONNULL const char *name, ut64 value);
|
||||
RZ_API bool rz_config_set_bool(RZ_NONNULL RzConfig *cfg, RZ_NONNULL const char *name, bool value);
|
||||
RZ_API bool rz_config_toggle_bool(RZ_NONNULL RzConfig *cfg, RZ_NONNULL const char *name);
|
||||
RZ_API bool rz_config_set_list(RZ_NONNULL RzConfig *cfg, RZ_NONNULL const char *name, RZ_NULLABLE const RzList /*<const char *>*/ *value);
|
||||
RZ_API bool rz_config_set_list2(RZ_NONNULL RzConfig *cfg, RZ_NONNULL const char *name, ...);
|
||||
RZ_API bool rz_config_set_list3(RZ_NONNULL RzConfig *cfg, RZ_NONNULL const char *name, RZ_NULLABLE const char *comma_list);
|
||||
RZ_API bool rz_config_set_set(RZ_NONNULL RzConfig *cfg, RZ_NONNULL const char *name, RZ_NULLABLE const RzSetS *value);
|
||||
RZ_API bool rz_config_set_set2(RZ_NONNULL RzConfig *cfg, RZ_NONNULL const char *name, ...);
|
||||
RZ_API bool rz_config_set_set3(RZ_NONNULL RzConfig *cfg, RZ_NONNULL const char *name, RZ_NULLABLE const char *comma_list);
|
||||
RZ_API bool rz_config_set_interval(RZ_NONNULL RzConfig *cfg, RZ_NONNULL const char *name, RzInterval value);
|
||||
RZ_API bool rz_config_set_interval2(RZ_NONNULL RzConfig *cfg, RZ_NONNULL const char *name, ut64 from, ut64 to);
|
||||
RZ_API bool rz_config_set_interval3(RZ_NONNULL RzConfig *cfg, RZ_NONNULL const char *name, RZ_NULLABLE const char *comma_itv);
|
||||
RZ_API bool rz_config_set_any(RZ_NONNULL RzConfig *cfg, RZ_NONNULL const char *name, RZ_NULLABLE const char *value);
|
||||
RZ_API bool rz_config_set_options(RZ_NONNULL RzConfig *cfg, RZ_NONNULL const char *name, RZ_NULLABLE RZ_OWN RzList /*<char *>*/ *options);
|
||||
RZ_API bool rz_config_set_options(RZ_NONNULL RzConfig *cfg, RZ_NONNULL const char *name, RZ_NULLABLE RZ_OWN RzSetS *options);
|
||||
RZ_API bool rz_config_set_options2(RZ_NONNULL RzConfig *cfg, RZ_NONNULL const char *name, ...);
|
||||
RZ_API bool rz_config_set_validator(RZ_NONNULL RzConfig *cfg, RZ_NONNULL const char *name, RZ_NULLABLE RzConfigBindSet validator, RZ_NULLABLE void *user);
|
||||
|
||||
RZ_API bool rz_config_get_bool(RZ_NONNULL const RzConfig *cfg, RZ_NONNULL const char *name);
|
||||
RZ_API ut64 rz_config_get_integer(RZ_NONNULL const RzConfig *cfg, RZ_NONNULL const char *name);
|
||||
RZ_API const char *rz_config_get_string(RZ_NONNULL const RzConfig *cfg, RZ_NONNULL const char *name);
|
||||
RZ_API RZ_OWN RzList /*<const char *>*/ *rz_config_get_list(RZ_NONNULL const RzConfig *cfg, RZ_NONNULL const char *name);
|
||||
RZ_API RZ_OWN RzSetS *rz_config_get_set(RZ_NONNULL const RzConfig *cfg, RZ_NONNULL const char *name);
|
||||
RZ_API RzInterval rz_config_get_interval(RZ_NONNULL const RzConfig *cfg, RZ_NONNULL const char *name);
|
||||
|
||||
RZ_API RZ_OWN char *rz_config_get_as_string(RZ_NONNULL const RzConfig *cfg, RZ_NONNULL const char *name);
|
||||
RZ_API const RzList /*<char *>*/ *rz_config_get_options(RZ_NONNULL const RzConfig *cfg, RZ_NONNULL const char *name);
|
||||
RZ_API const RzSetS *rz_config_get_options(RZ_NONNULL const RzConfig *cfg, RZ_NONNULL const char *name);
|
||||
RZ_API ut32 rz_config_get_flags(RZ_NONNULL const RzConfig *cfg, RZ_NONNULL const char *name);
|
||||
|
||||
RZ_API bool rz_config_var_as_json(RZ_NONNULL const RzConfigVar *var, RZ_NONNULL PJ *pj, RZ_NONNULL const char *key);
|
||||
|
|
@ -176,7 +176,7 @@ RZ_API bool rz_config_var_is_readonly(RZ_NONNULL const RzConfigVar *var);
|
|||
RZ_API bool rz_config_var_get_bool(RZ_NONNULL const RzConfigVar *var);
|
||||
RZ_API ut64 rz_config_var_get_integer(RZ_NONNULL const RzConfigVar *var);
|
||||
RZ_API const char *rz_config_var_get_string(RZ_NONNULL const RzConfigVar *var);
|
||||
RZ_API RZ_OWN RzList /*<const char *>*/ *rz_config_var_get_list(RZ_NONNULL const RzConfigVar *var);
|
||||
RZ_API RZ_OWN RzSetS *rz_config_var_get_set(RZ_NONNULL const RzConfigVar *var);
|
||||
RZ_API RzInterval rz_config_var_get_interval(RZ_NONNULL const RzConfigVar *var);
|
||||
RZ_API bool rz_config_var_has_type(RZ_NONNULL const RzConfigVar *var, ut32 etype);
|
||||
RZ_API bool rz_config_var_has_flags(RZ_NONNULL const RzConfigVar *var, ut32 eflags);
|
||||
|
|
@ -184,7 +184,7 @@ RZ_API RZ_OWN char *rz_config_var_flags_as_string(ut32 flags);
|
|||
RZ_API ut32 rz_config_var_get_flags(RZ_NONNULL const RzConfigVar *var);
|
||||
RZ_API const char *rz_config_var_get_name(RZ_NONNULL const RzConfigVar *var);
|
||||
RZ_API const char *rz_config_var_get_desc(RZ_NONNULL const RzConfigVar *var);
|
||||
RZ_API const RzList /*<char *>*/ *rz_config_var_get_options(RZ_NONNULL const RzConfigVar *var);
|
||||
RZ_API const RzSetS *rz_config_var_get_options(RZ_NONNULL const RzConfigVar *var);
|
||||
|
||||
/* to deprecate */
|
||||
RZ_API const char *rz_config_entry_get_name(RZ_NONNULL const RzConfigEntry *entry);
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ extern "C" {
|
|||
typedef HtSP RzSetS;
|
||||
|
||||
RZ_API RZ_OWN RzSetS *rz_set_s_new(HtStrOption opt);
|
||||
RZ_API RZ_OWN RzSetS *rz_str_split_dupset(RZ_NONNULL const char *_str, RZ_NONNULL const char *c, bool trim);
|
||||
RZ_API void rz_set_s_free(RZ_NULLABLE RzSetS *set);
|
||||
RZ_API void rz_set_s_add(RZ_NONNULL RzSetS *set, const char *str);
|
||||
RZ_API bool rz_set_s_contains(const RZ_NONNULL RzSetS *set, const char *str);
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@
|
|||
|
||||
#include <rz_util/rz_set.h>
|
||||
#include <rz_util/rz_assert.h>
|
||||
#include <rz_util/rz_str.h>
|
||||
#include <rz_list.h>
|
||||
|
||||
/**
|
||||
* \brief Create a new hash set with C-string as elements.
|
||||
|
|
@ -13,6 +15,37 @@ RZ_API RZ_OWN RzSetS *rz_set_s_new(HtStrOption opt) {
|
|||
return ht_sp_new(opt, NULL, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Split the string \p str according to the substring \p c and returns a \p RzSetS with the result.
|
||||
*
|
||||
* Split a string \p str according to the delimiter specified in \p c. It can
|
||||
* optionally trim (aka remove spaces) the tokens. The result is a \p RzSetS with newly allocated strings for each
|
||||
* token.
|
||||
*
|
||||
* \param _str Input string to split
|
||||
* \param c Delimiter string used to split \p str
|
||||
* \param trim If true each token is considered without trailing/leading whitespaces.
|
||||
*/
|
||||
RZ_API RZ_OWN RzSetS *rz_str_split_dupset(RZ_NONNULL const char *_str, RZ_NONNULL const char *c, bool trim) {
|
||||
rz_return_val_if_fail(_str && c, NULL);
|
||||
RzList *list = rz_str_split_duplist(_str, c, trim);
|
||||
if (!list) {
|
||||
return NULL;
|
||||
}
|
||||
RzSetS *set = rz_set_s_new(HT_STR_DUP);
|
||||
if (!set) {
|
||||
rz_list_free(list);
|
||||
return NULL;
|
||||
}
|
||||
RzListIter *it;
|
||||
const char *val;
|
||||
rz_list_foreach (list, it, val) {
|
||||
rz_set_s_add(set, val);
|
||||
}
|
||||
rz_list_free(list);
|
||||
return set;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Add element \p str to hash set \p set.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -53,15 +53,15 @@ FILE==
|
|||
CMDS=e asm.os=?
|
||||
EXPECT=<<EOF
|
||||
ios
|
||||
dos
|
||||
darwin
|
||||
linux
|
||||
freebsd
|
||||
openbsd
|
||||
netbsd
|
||||
windows
|
||||
s110
|
||||
none
|
||||
darwin
|
||||
freebsd
|
||||
windows
|
||||
dos
|
||||
openbsd
|
||||
netbsd
|
||||
EOF
|
||||
RUN
|
||||
|
||||
|
|
@ -174,7 +174,7 @@ elq zoom
|
|||
EOF
|
||||
EXPECT=<<EOF
|
||||
{"zoom.byte":"h","zoom.from":0,"zoom.in":"io.map","zoom.maxsz":512,"zoom.to":0}
|
||||
[{"name":"zoom.byte","desc":"Zoom callback to calculate each byte (See pz? for help)","flags":"string,bind","options":[],"value":"h"},{"name":"zoom.from","desc":"Zoom start address","flags":"integer","options":[],"value":0},{"name":"zoom.in","desc":"Specify boundaries for zoom","flags":"string,bind","options":["raw","block","bin.section","bin.sections","bin.sections.rwx","bin.sections.r","bin.sections.rw","bin.sections.rx","bin.sections.wx","bin.sections.x","io.map","io.maps","io.maps.rwx","io.maps.r","io.maps.rw","io.maps.rx","io.maps.wx","io.maps.x","dbg.stack","dbg.heap","dbg.map","dbg.maps","dbg.maps.rwx","dbg.maps.r","dbg.maps.rw","dbg.maps.rx","dbg.maps.wx","dbg.maps.x","analysis.fcn","analysis.bb"],"value":"io.map"},{"name":"zoom.maxsz","desc":"Zoom max size of block","flags":"integer","options":[],"value":512},{"name":"zoom.to","desc":"Zoom end address","flags":"integer","options":[],"value":0}]
|
||||
[{"name":"zoom.byte","desc":"Zoom callback to calculate each byte (See pz? for help)","flags":"string,bind","options":[],"value":"h"},{"name":"zoom.from","desc":"Zoom start address","flags":"integer","options":[],"value":0},{"name":"zoom.in","desc":"Specify boundaries for zoom","flags":"string,bind","options":["io.maps.rw","block","bin.sections.rx","io.maps.rwx","dbg.heap","io.map","dbg.maps.rwx","io.maps.r","bin.sections.r","dbg.maps.r","io.maps.x","analysis.fcn","bin.sections.x","analysis.bb","dbg.maps.rw","dbg.maps.x","dbg.map","io.maps.wx","bin.sections.wx","raw","bin.section","bin.sections.rw","bin.sections.rwx","io.maps","dbg.maps.rx","dbg.maps.wx","bin.sections","dbg.stack","io.maps.rx","dbg.maps"],"value":"io.map"},{"name":"zoom.maxsz","desc":"Zoom max size of block","flags":"integer","options":[],"value":512},{"name":"zoom.to","desc":"Zoom end address","flags":"integer","options":[],"value":0}]
|
||||
zoom.byte: Zoom callback to calculate each byte (See pz? for help)
|
||||
zoom.from: Zoom start address
|
||||
zoom.in: Specify boundaries for zoom
|
||||
|
|
@ -182,7 +182,7 @@ EXPECT=<<EOF
|
|||
zoom.to: Zoom end address
|
||||
zoom.byte = h (string,bind); Zoom callback to calculate each byte (See pz? for help)
|
||||
zoom.from = 0 (integer); Zoom start address
|
||||
zoom.in = io.map (string,bind); Specify boundaries for zoom [raw, block, bin.section, bin.sections, bin.sections.rwx, bin.sections.r, bin.sections.rw, bin.sections.rx, bin.sections.wx, bin.sections.x, io.map, io.maps, io.maps.rwx, io.maps.r, io.maps.rw, io.maps.rx, io.maps.wx, io.maps.x, dbg.stack, dbg.heap, dbg.map, dbg.maps, dbg.maps.rwx, dbg.maps.r, dbg.maps.rw, dbg.maps.rx, dbg.maps.wx, dbg.maps.x, analysis.fcn, analysis.bb]
|
||||
zoom.in = io.map (string,bind); Specify boundaries for zoom [io.maps.rw, block, bin.sections.rx, io.maps.rwx, dbg.heap, io.map, dbg.maps.rwx, io.maps.r, bin.sections.r, dbg.maps.r, io.maps.x, analysis.fcn, bin.sections.x, analysis.bb, dbg.maps.rw, dbg.maps.x, dbg.map, io.maps.wx, bin.sections.wx, raw, bin.section, bin.sections.rw, bin.sections.rwx, io.maps, dbg.maps.rx, dbg.maps.wx, bin.sections, dbg.stack, io.maps.rx, dbg.maps]
|
||||
zoom.maxsz = 512 (integer); Zoom max size of block
|
||||
zoom.to = 0 (integer); Zoom end address
|
||||
zoom.byte=h
|
||||
|
|
|
|||
|
|
@ -203,70 +203,58 @@ bool test_config_booleans() {
|
|||
mu_end;
|
||||
}
|
||||
|
||||
bool test_config_lists() {
|
||||
bool test_config_sets() {
|
||||
RzConfig *cfg = rz_config_new(NULL);
|
||||
bool ret = false;
|
||||
const char *elem = NULL;
|
||||
RzList *list = NULL;
|
||||
RzListIter *it;
|
||||
RzSetS *set = NULL;
|
||||
|
||||
// list variables
|
||||
ret = rz_config_add_list(cfg, "thy.list", "is thy.list desc", "r1", "r2", "r3", NULL);
|
||||
mu_assert_true(ret, "added thy.list");
|
||||
// set variables
|
||||
ret = rz_config_add_set(cfg, "thy.set", "is thy.set desc", "r1", "r2", "r3", NULL);
|
||||
mu_assert_true(ret, "added thy.set");
|
||||
|
||||
ret = rz_config_set_validator(cfg, "thy.list", test_config_validator, &ret);
|
||||
mu_assert_true(ret, "can set validator for list");
|
||||
ret = rz_config_set_validator(cfg, "thy.set", test_config_validator, &ret);
|
||||
mu_assert_true(ret, "can set validator for set");
|
||||
|
||||
list = rz_config_get_list(cfg, "thy.list");
|
||||
mu_assert_notnull(list, "List is not null variable");
|
||||
mu_assert_eq(rz_list_length(list), 3, "List size is 3");
|
||||
set = rz_config_get_set(cfg, "thy.set");
|
||||
mu_assert_notnull(set, "Set is not null variable");
|
||||
mu_assert_eq(rz_set_s_size(set), 3, "Set size is 3");
|
||||
|
||||
it = rz_list_head(list);
|
||||
elem = rz_list_val(it);
|
||||
mu_assert_streq(elem, "r1", "list[0] is r1");
|
||||
mu_assert_true(rz_set_s_contains(set, "r1"), "set contains r1");
|
||||
mu_assert_true(rz_set_s_contains(set, "r2"), "set contains r2");
|
||||
mu_assert_true(rz_set_s_contains(set, "r3"), "set contains r3");
|
||||
rz_set_s_free(set);
|
||||
|
||||
it = rz_list_next(it);
|
||||
elem = rz_list_val(it);
|
||||
mu_assert_streq(elem, "r2", "list[1] is r2");
|
||||
ret = rz_config_set_set2(cfg, "thy.set", "x0", "x1", "x2", "x3", "x4", NULL);
|
||||
mu_assert_true(ret, "set thy.set");
|
||||
|
||||
it = rz_list_next(it);
|
||||
elem = rz_list_val(it);
|
||||
mu_assert_streq(elem, "r3", "list[2] is r3");
|
||||
rz_list_free(list);
|
||||
set = rz_config_get_set(cfg, "thy.set");
|
||||
mu_assert_notnull(set, "Set is not null variable");
|
||||
mu_assert_eq(rz_set_s_size(set), 5, "Set size is 5");
|
||||
|
||||
ret = rz_config_set_list2(cfg, "thy.list", "x0", "x1", "x2", "x3", "x4", NULL);
|
||||
mu_assert_true(ret, "set thy.list");
|
||||
mu_assert_true(rz_set_s_contains(set, "x0"), "set contains x0");
|
||||
mu_assert_true(rz_set_s_contains(set, "x1"), "set contains x1");
|
||||
mu_assert_true(rz_set_s_contains(set, "x2"), "set contains x2");
|
||||
mu_assert_true(rz_set_s_contains(set, "x3"), "set contains x3");
|
||||
mu_assert_true(rz_set_s_contains(set, "x4"), "set contains x4");
|
||||
rz_set_s_free(set);
|
||||
|
||||
list = rz_config_get_list(cfg, "thy.list");
|
||||
mu_assert_notnull(list, "List is not null variable");
|
||||
mu_assert_eq(rz_list_length(list), 5, "List size is 5");
|
||||
ret = rz_config_set_set3(cfg, "thy.set", "rax,rbx");
|
||||
mu_assert_true(ret, "set thy.set as string");
|
||||
|
||||
char *s = rz_config_get_as_string(cfg, "thy.list");
|
||||
mu_assert_streq(s, "x0,x1,x2,x3,x4", "get as string thy.list");
|
||||
free(s);
|
||||
set = rz_config_get_set(cfg, "thy.set");
|
||||
mu_assert_notnull(set, "Set is not null variable");
|
||||
mu_assert_eq(rz_set_s_size(set), 2, "Set size is 2");
|
||||
mu_assert_true(rz_set_s_contains(set, "rax"), "set contains rax");
|
||||
mu_assert_true(rz_set_s_contains(set, "rbx"), "set contains rbx");
|
||||
rz_set_s_free(set);
|
||||
|
||||
elem = rz_list_first_val(list);
|
||||
mu_assert_streq(elem, "x0", "list[first] is x0");
|
||||
ret = rz_config_set_set(cfg, "thy.set", NULL);
|
||||
mu_assert_true(ret, "set thy.set as string");
|
||||
|
||||
elem = rz_list_last_val(list);
|
||||
mu_assert_streq(elem, "x4", "list[last] is x4");
|
||||
rz_list_free(list);
|
||||
|
||||
ret = rz_config_set_list3(cfg, "thy.list", "rax,rbx");
|
||||
mu_assert_true(ret, "set thy.list as string");
|
||||
|
||||
list = rz_config_get_list(cfg, "thy.list");
|
||||
mu_assert_notnull(list, "List is not null variable");
|
||||
mu_assert_eq(rz_list_length(list), 2, "List size is 2");
|
||||
rz_list_free(list);
|
||||
|
||||
ret = rz_config_set_list(cfg, "thy.list", NULL);
|
||||
mu_assert_true(ret, "set thy.list as string");
|
||||
|
||||
list = rz_config_get_list(cfg, "thy.list");
|
||||
mu_assert_notnull(list, "List is not null variable");
|
||||
mu_assert_eq(rz_list_length(list), 0, "List is empty");
|
||||
rz_list_free(list);
|
||||
set = rz_config_get_set(cfg, "thy.set");
|
||||
mu_assert_notnull(set, "Set is not null variable");
|
||||
mu_assert_eq(rz_set_s_size(set), 0, "Set is empty");
|
||||
rz_set_s_free(set);
|
||||
|
||||
rz_config_free(cfg);
|
||||
mu_end;
|
||||
|
|
@ -360,7 +348,7 @@ bool test_config_invalid() {
|
|||
RzConfig *cfg = rz_config_new(NULL);
|
||||
|
||||
mu_assert_null(rz_config_get_string(cfg, "string.here"), "string.here does not exist");
|
||||
mu_assert_null(rz_config_get_list(cfg, "list.here"), "list.here does not exist");
|
||||
mu_assert_null(rz_config_get_set(cfg, "set.here"), "set.here does not exist");
|
||||
mu_assert_eq(rz_config_get_integer(cfg, "int.here"), 0, "int.here does not exist");
|
||||
mu_assert_false(rz_config_get_bool(cfg, "bool.here"), "bool.here does not exist");
|
||||
mu_assert_false(rz_config_set_validator(cfg, "self.validator", test_config_validator, &itv), "self.validator does not exist");
|
||||
|
|
@ -378,7 +366,7 @@ typedef struct bind_test_s {
|
|||
ut32 opts;
|
||||
ut32 bind;
|
||||
const void *set_val;
|
||||
RzList *list;
|
||||
RzSetS *set_val_set;
|
||||
} bind_test_t;
|
||||
|
||||
static bool any_get(void *user, void *p) {
|
||||
|
|
@ -402,9 +390,16 @@ static bool any_get(void *user, void *p) {
|
|||
bt->get++;
|
||||
return true;
|
||||
}
|
||||
case RZ_CONFIG_VAR_TYPE_LIST: {
|
||||
const RzList **value = p;
|
||||
*value = bt->list;
|
||||
case RZ_CONFIG_VAR_TYPE_SET: {
|
||||
RzSetS **value = p;
|
||||
RzSetS *dup = rz_set_s_new(HT_STR_DUP);
|
||||
RzIterator *iter = rz_set_s_as_iter(bt->set_val_set);
|
||||
const char **elem;
|
||||
rz_iterator_foreach(iter, elem) {
|
||||
rz_set_s_add(dup, *elem);
|
||||
}
|
||||
rz_iterator_free(iter);
|
||||
*value = dup;
|
||||
bt->get++;
|
||||
return true;
|
||||
}
|
||||
|
|
@ -433,7 +428,7 @@ static bool any_set(void *user, const void *p) {
|
|||
return true;
|
||||
case RZ_CONFIG_VAR_TYPE_STR:
|
||||
/* fall-thru */
|
||||
case RZ_CONFIG_VAR_TYPE_LIST:
|
||||
case RZ_CONFIG_VAR_TYPE_SET:
|
||||
bt->set_val = p;
|
||||
bt->set++;
|
||||
return true;
|
||||
|
|
@ -449,18 +444,22 @@ static bool any_set(void *user, const void *p) {
|
|||
}
|
||||
}
|
||||
|
||||
static bool any_opts(void *user, RzList /*<char *>*/ **options) {
|
||||
static bool any_opts(void *user, RzSetS **options) {
|
||||
bind_test_t *bt = user;
|
||||
switch (bt->bind) {
|
||||
case RZ_CONFIG_VAR_TYPE_STR:
|
||||
*options = rz_str_split_duplist("foo,bar", ",", true);
|
||||
case RZ_CONFIG_VAR_TYPE_STR: {
|
||||
RzSetS *opts_set = rz_set_s_new(HT_STR_DUP);
|
||||
rz_set_s_add(opts_set, "foo");
|
||||
rz_set_s_add(opts_set, "bar");
|
||||
*options = opts_set;
|
||||
bt->opts++;
|
||||
return true;
|
||||
}
|
||||
case RZ_CONFIG_VAR_TYPE_BOOL:
|
||||
/* fall-thru */
|
||||
case RZ_CONFIG_VAR_TYPE_INT:
|
||||
/* fall-thru */
|
||||
case RZ_CONFIG_VAR_TYPE_LIST:
|
||||
case RZ_CONFIG_VAR_TYPE_SET:
|
||||
/* fall-thru */
|
||||
case RZ_CONFIG_VAR_TYPE_ITV:
|
||||
bt->opts++;
|
||||
|
|
@ -478,8 +477,10 @@ bool test_config_binds() {
|
|||
RzConfig *cfg = rz_config_new(NULL);
|
||||
mu_assert_notnull(cfg, "alloc RzConfig");
|
||||
|
||||
bt.list = rz_str_split_duplist("init,fini", ",", true);
|
||||
mu_assert_notnull(bt.list, "alloc list");
|
||||
bt.set_val_set = rz_set_s_new(HT_STR_DUP);
|
||||
rz_set_s_add(bt.set_val_set, "init");
|
||||
rz_set_s_add(bt.set_val_set, "fini");
|
||||
mu_assert_notnull(bt.set_val_set, "alloc set");
|
||||
|
||||
// add binds
|
||||
bt.bind = RZ_CONFIG_VAR_TYPE_BOOL;
|
||||
|
|
@ -503,11 +504,11 @@ bool test_config_binds() {
|
|||
ret = rz_config_set_validator(cfg, "bind.string", test_config_validator, &ret);
|
||||
mu_assert_false(ret, "cannot set validator when bind");
|
||||
|
||||
bt.bind = RZ_CONFIG_VAR_TYPE_LIST;
|
||||
ret = rz_config_add_list_bind(cfg, "bind.list", "is bind.list desc", any_get, any_set, any_opts, &bt);
|
||||
mu_assert_true(ret, "added bind.list");
|
||||
bt.bind = RZ_CONFIG_VAR_TYPE_SET;
|
||||
ret = rz_config_add_set_bind(cfg, "bind.set", "is bind.set desc", any_get, any_set, any_opts, &bt);
|
||||
mu_assert_true(ret, "added bind.set");
|
||||
|
||||
ret = rz_config_set_validator(cfg, "bind.list", test_config_validator, &ret);
|
||||
ret = rz_config_set_validator(cfg, "bind.set", test_config_validator, &ret);
|
||||
mu_assert_false(ret, "cannot set validator when bind");
|
||||
|
||||
bt.bind = RZ_CONFIG_VAR_TYPE_ITV;
|
||||
|
|
@ -526,8 +527,15 @@ bool test_config_binds() {
|
|||
bt.bind = RZ_CONFIG_VAR_TYPE_STR;
|
||||
mu_assert_streq(rz_config_get_string(cfg, "bind.string"), "what", "get bind.string");
|
||||
|
||||
bt.bind = RZ_CONFIG_VAR_TYPE_LIST;
|
||||
mu_assert_ptreq(rz_config_get_list(cfg, "bind.list"), bt.list, "get bind.list");
|
||||
bt.bind = RZ_CONFIG_VAR_TYPE_SET;
|
||||
{
|
||||
RzSetS *bind_set = rz_config_get_set(cfg, "bind.set");
|
||||
mu_assert_notnull(bind_set, "get bind.set");
|
||||
mu_assert_eq(rz_set_s_size(bind_set), 2, "bind.set size is 2");
|
||||
mu_assert_true(rz_set_s_contains(bind_set, "init"), "bind.set contains init");
|
||||
mu_assert_true(rz_set_s_contains(bind_set, "fini"), "bind.set contains fini");
|
||||
rz_set_s_free(bind_set);
|
||||
}
|
||||
|
||||
bt.bind = RZ_CONFIG_VAR_TYPE_ITV;
|
||||
itv = rz_config_get_interval(cfg, "bind.interval");
|
||||
|
|
@ -549,10 +557,10 @@ bool test_config_binds() {
|
|||
mu_assert_true(ret, "set bind.string");
|
||||
mu_assert_streq(bt.set_val, "foo", "has actually set bind.string");
|
||||
|
||||
bt.bind = RZ_CONFIG_VAR_TYPE_LIST;
|
||||
ret = rz_config_set_list(cfg, "bind.list", bt.list);
|
||||
mu_assert_true(ret, "set bind.list");
|
||||
mu_assert_ptreq(bt.set_val, bt.list, "has actually set bind.list");
|
||||
bt.bind = RZ_CONFIG_VAR_TYPE_SET;
|
||||
ret = rz_config_set_set(cfg, "bind.set", bt.set_val_set);
|
||||
mu_assert_true(ret, "set bind.set");
|
||||
mu_assert_notnull(bt.set_val, "has actually set bind.set");
|
||||
|
||||
bt.bind = RZ_CONFIG_VAR_TYPE_ITV;
|
||||
bt.set_val = &itv;
|
||||
|
|
@ -566,7 +574,7 @@ bool test_config_binds() {
|
|||
mu_assert_eq(bt.set, 5, "called bind.set_value");
|
||||
|
||||
rz_config_free(cfg);
|
||||
rz_list_free(bt.list);
|
||||
rz_set_s_free(bt.set_val_set);
|
||||
mu_end;
|
||||
}
|
||||
|
||||
|
|
@ -574,7 +582,7 @@ bool all_tests() {
|
|||
mu_run_test(test_config_strings);
|
||||
mu_run_test(test_config_intergers);
|
||||
mu_run_test(test_config_booleans);
|
||||
mu_run_test(test_config_lists);
|
||||
mu_run_test(test_config_sets);
|
||||
mu_run_test(test_config_itv);
|
||||
mu_run_test(test_config_invalid);
|
||||
mu_run_test(test_config_binds);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue