m_option: move code around

Move the helper functions for parsing -vf, and rename some.
This commit is contained in:
wm4 2013-05-22 23:25:59 +02:00
parent 3d87ca6b5e
commit f9f40a417f
1 changed files with 146 additions and 139 deletions

View File

@ -1786,6 +1786,141 @@ static int find_obj_desc(struct bstr name, const m_obj_list_t *l,
return 0;
}
static void obj_setting_free(m_obj_settings_t *item)
{
talloc_free(item->name);
talloc_free(item->label);
free_str_list(&(item->attribs));
}
// If at least one item has a label, compare labels only - otherwise ignore them.
static bool obj_setting_equals(m_obj_settings_t *a, m_obj_settings_t *b)
{
bstr la = bstr0(a->label), lb = bstr0(b->label);
if (la.len || lb.len)
return bstr_equals(la, lb);
if (strcmp(a->name, b->name) != 0)
return false;
int a_attr_count = 0;
while (a->attribs && a->attribs[a_attr_count])
a_attr_count++;
int b_attr_count = 0;
while (b->attribs && b->attribs[b_attr_count])
b_attr_count++;
if (a_attr_count != b_attr_count)
return false;
for (int n = 0; n < a_attr_count; n++) {
if (strcmp(a->attribs[n], b->attribs[n]) != 0)
return false;
}
return true;
}
static int obj_settings_list_num_items(m_obj_settings_t *obj_list)
{
int num = 0;
while (obj_list && obj_list[num].name)
num++;
return num;
}
static void obj_settings_list_del_at(m_obj_settings_t **p_obj_list, int idx)
{
m_obj_settings_t *obj_list = *p_obj_list;
int num = obj_settings_list_num_items(obj_list);
assert(idx >= 0 && idx < num);
obj_setting_free(&obj_list[idx]);
// Note: the NULL-terminating element is moved down as part of this
memmove(&obj_list[idx], &obj_list[idx + 1],
sizeof(m_obj_settings_t) * (num - idx));
*p_obj_list = talloc_realloc(NULL, obj_list, struct m_obj_settings, num);
}
// Insert such that *p_obj_list[idx] is set to item.
// If idx < 0, set idx = count + idx + 1 (i.e. -1 inserts it as last element).
// Memory referenced by *item is not copied.
static void obj_settings_list_insert_at(m_obj_settings_t **p_obj_list, int idx,
m_obj_settings_t *item)
{
int num = obj_settings_list_num_items(*p_obj_list);
if (idx < 0)
idx = num + idx + 1;
assert(idx >= 0 && idx <= num);
*p_obj_list = talloc_realloc(NULL, *p_obj_list, struct m_obj_settings,
num + 2);
memmove(*p_obj_list + idx + 1, *p_obj_list + idx,
(num - idx) * sizeof(m_obj_settings_t));
(*p_obj_list)[idx] = *item;
(*p_obj_list)[num + 1] = (m_obj_settings_t){0};
}
static int obj_settings_list_find_by_label(m_obj_settings_t *obj_list,
bstr label)
{
for (int n = 0; obj_list && obj_list[n].name; n++) {
if (label.len && bstr_equals0(label, obj_list[n].label))
return n;
}
return -1;
}
static int obj_settings_list_find_by_label0(m_obj_settings_t *obj_list,
const char *label)
{
return obj_settings_list_find_by_label(obj_list, bstr0(label));
}
static void free_obj_settings_list(void *dst)
{
int n;
m_obj_settings_t *d;
if (!dst || !VAL(dst))
return;
d = VAL(dst);
for (n = 0; d[n].name; n++)
obj_setting_free(&d[n]);
talloc_free(d);
VAL(dst) = NULL;
}
static void copy_obj_settings_list(const m_option_t *opt, void *dst,
const void *src)
{
m_obj_settings_t *d, *s;
int n;
if (!(dst && src))
return;
s = VAL(src);
if (VAL(dst))
free_obj_settings_list(dst);
if (!s)
return;
for (n = 0; s[n].name; n++)
/* NOP */;
d = talloc_array(NULL, struct m_obj_settings, n + 1);
for (n = 0; s[n].name; n++) {
d[n].name = talloc_strdup(NULL, s[n].name);
d[n].label = talloc_strdup(NULL, s[n].label);
d[n].attribs = NULL;
copy_str_list(NULL, &(d[n].attribs), &(s[n].attribs));
}
d[n].name = NULL;
d[n].label = NULL;
d[n].attribs = NULL;
VAL(dst) = d;
}
// Consider -vf a=b=c:d=e. This verifies "b"="c" and "d"="e" and that the
// option names/values are correct. Try to determine whether an option
// without '=' sets a flag, or whether it's a positional argument.
@ -1998,88 +2133,6 @@ static int parse_obj_settings(struct bstr opt, struct bstr *pstr,
return 1;
}
static int obj_settings_list_num_items(m_obj_settings_t *obj_list)
{
int num = 0;
while (obj_list && obj_list[num].name)
num++;
return num;
}
static void obj_settings_free_item(m_obj_settings_t *item)
{
talloc_free(item->name);
talloc_free(item->label);
free_str_list(&(item->attribs));
}
static void del_obj_settings_list_at(m_obj_settings_t **p_obj_list, int idx)
{
m_obj_settings_t *obj_list = *p_obj_list;
int num = obj_settings_list_num_items(obj_list);
assert(idx >= 0 && idx < num);
obj_settings_free_item(&obj_list[idx]);
// Note: the NULL-terminating element is moved down as part of this
memmove(&obj_list[idx], &obj_list[idx + 1],
sizeof(m_obj_settings_t) * (num - idx));
*p_obj_list = talloc_realloc(NULL, obj_list, struct m_obj_settings, num);
}
// Insert such that *p_obj_list[idx] is set to item.
// If idx < 0, set idx = count + idx + 1 (i.e. -1 inserts it as last element).
// Memory referenced by *item is not copied.
static void insert_obj_settings_list_at(m_obj_settings_t **p_obj_list, int idx,
m_obj_settings_t *item)
{
int num = obj_settings_list_num_items(*p_obj_list);
if (idx < 0)
idx = num + idx + 1;
assert(idx >= 0 && idx <= num);
*p_obj_list = talloc_realloc(NULL, *p_obj_list, struct m_obj_settings,
num + 2);
memmove(*p_obj_list + idx + 1, *p_obj_list + idx,
(num - idx) * sizeof(m_obj_settings_t));
(*p_obj_list)[idx] = *item;
(*p_obj_list)[num + 1] = (m_obj_settings_t){0};
}
// If at least one item has a label, compare labels only - otherwise ignore them.
static bool obj_setting_equals(m_obj_settings_t *a, m_obj_settings_t *b)
{
bstr la = bstr0(a->label), lb = bstr0(b->label);
if (la.len || lb.len)
return bstr_equals(la, lb);
if (strcmp(a->name, b->name) != 0)
return false;
int a_attr_count = 0;
while (a->attribs && a->attribs[a_attr_count])
a_attr_count++;
int b_attr_count = 0;
while (b->attribs && b->attribs[b_attr_count])
b_attr_count++;
if (a_attr_count != b_attr_count)
return false;
for (int n = 0; n < a_attr_count; n++) {
if (strcmp(a->attribs[n], b->attribs[n]) != 0)
return false;
}
return true;
}
static int obj_settings_find_by_label(m_obj_settings_t *obj_list, bstr label)
{
for (int n = 0; obj_list && obj_list[n].name; n++) {
if (label.len && bstr_equals0(label, obj_list[n].label))
return n;
}
return -1;
}
static int obj_settings_list_del(struct bstr opt_name, struct bstr param,
void *dst)
{
@ -2101,7 +2154,7 @@ static int obj_settings_list_del(struct bstr opt_name, struct bstr param,
bstr_split_tok(param, ",", &item, &param);
if (bstr_eatstart0(&item, "@")) {
int label_index = obj_settings_find_by_label(obj_list, item);
int label_index = obj_settings_list_find_by_label(obj_list, item);
if (label_index >= 0) {
mark_del[label_index] = true;
goto found;
@ -2147,7 +2200,7 @@ static int obj_settings_list_del(struct bstr opt_name, struct bstr param,
if (dst) {
for (int n = idx_max - 1; n >= 0; n--) {
if (mark_del[n])
del_obj_settings_list_at(&obj_list, n);
obj_settings_list_del_at(&obj_list, n);
}
VAL(dst) = obj_list;
}
@ -2156,21 +2209,6 @@ static int obj_settings_list_del(struct bstr opt_name, struct bstr param,
return 1;
}
static void free_obj_settings_list(void *dst)
{
int n;
m_obj_settings_t *d;
if (!dst || !VAL(dst))
return;
d = VAL(dst);
for (n = 0; d[n].name; n++)
obj_settings_free_item(&d[n]);
talloc_free(d);
VAL(dst) = NULL;
}
static int parse_obj_settings_list(const m_option_t *opt, struct bstr name,
struct bstr param, void *dst)
{
@ -2258,27 +2296,27 @@ static int parse_obj_settings_list(const m_option_t *opt, struct bstr name,
if (op == OP_PRE) {
int prepend_counter = 0;
for (int n = 0; res && res[n].name; n++) {
int label = obj_settings_find_by_label(list, bstr0(res[n].label));
int label = obj_settings_list_find_by_label0(list, res[n].label);
if (label < 0) {
insert_obj_settings_list_at(&list, prepend_counter, &res[n]);
obj_settings_list_insert_at(&list, prepend_counter, &res[n]);
prepend_counter++;
} else {
// Prefer replacement semantics, instead of actually
// prepending.
obj_settings_free_item(&list[label]);
obj_setting_free(&list[label]);
list[label] = res[n];
}
}
talloc_free(res);
} else if (op == OP_ADD) {
for (int n = 0; res && res[n].name; n++) {
int label = obj_settings_find_by_label(list, bstr0(res[n].label));
int label = obj_settings_list_find_by_label0(list, res[n].label);
if (label < 0) {
insert_obj_settings_list_at(&list, -1, &res[n]);
obj_settings_list_insert_at(&list, -1, &res[n]);
} else {
// Prefer replacement semantics, instead of actually
// appending.
obj_settings_free_item(&list[label]);
obj_setting_free(&list[label]);
list[label] = res[n];
}
}
@ -2293,10 +2331,10 @@ static int parse_obj_settings_list(const m_option_t *opt, struct bstr name,
}
}
if (found < 0) {
insert_obj_settings_list_at(&list, -1, &res[n]);
obj_settings_list_insert_at(&list, -1, &res[n]);
} else {
del_obj_settings_list_at(&list, found);
obj_settings_free_item(&res[n]);
obj_settings_list_del_at(&list, found);
obj_setting_free(&res[n]);
}
}
talloc_free(res);
@ -2310,37 +2348,6 @@ static int parse_obj_settings_list(const m_option_t *opt, struct bstr name,
return 1;
}
static void copy_obj_settings_list(const m_option_t *opt, void *dst,
const void *src)
{
m_obj_settings_t *d, *s;
int n;
if (!(dst && src))
return;
s = VAL(src);
if (VAL(dst))
free_obj_settings_list(dst);
if (!s)
return;
for (n = 0; s[n].name; n++)
/* NOP */;
d = talloc_array(NULL, struct m_obj_settings, n + 1);
for (n = 0; s[n].name; n++) {
d[n].name = talloc_strdup(NULL, s[n].name);
d[n].label = talloc_strdup(NULL, s[n].label);
d[n].attribs = NULL;
copy_str_list(NULL, &(d[n].attribs), &(s[n].attribs));
}
d[n].name = NULL;
d[n].label = NULL;
d[n].attribs = NULL;
VAL(dst) = d;
}
const m_option_type_t m_option_type_obj_settings_list = {
.name = "Object settings list",
.size = sizeof(m_obj_settings_t *),