settings: Adopt the new order of sections and settings when replacing configs
This commit is contained in:
@@ -199,10 +199,13 @@ void settings_section_extend(section_t *base, section_t *extension,
|
|||||||
enumerator_t *enumerator;
|
enumerator_t *enumerator;
|
||||||
section_t *section;
|
section_t *section;
|
||||||
kv_t *kv;
|
kv_t *kv;
|
||||||
|
array_t *sections = NULL, *kvs = NULL;
|
||||||
int idx;
|
int idx;
|
||||||
|
|
||||||
if (purge)
|
if (purge)
|
||||||
{ /* remove sections and settings in base not found in extension */
|
{ /* remove sections and settings in base not found in extension, the
|
||||||
|
* others are removed too (from the _order list) so they can be inserted
|
||||||
|
* in the order found in extension */
|
||||||
enumerator = array_create_enumerator(base->sections_order);
|
enumerator = array_create_enumerator(base->sections_order);
|
||||||
while (enumerator->enumerate(enumerator, (void**)§ion))
|
while (enumerator->enumerate(enumerator, (void**)§ion))
|
||||||
{
|
{
|
||||||
@@ -212,32 +215,49 @@ void settings_section_extend(section_t *base, section_t *extension,
|
|||||||
idx = array_bsearch(base->sections, section->name,
|
idx = array_bsearch(base->sections, section->name,
|
||||||
settings_section_find, NULL);
|
settings_section_find, NULL);
|
||||||
if (section_purge(section, contents))
|
if (section_purge(section, contents))
|
||||||
{
|
{ /* only remove them if we can purge them */
|
||||||
array_remove(base->sections, idx, NULL);
|
array_remove(base->sections, idx, NULL);
|
||||||
array_remove_at(base->sections_order, enumerator);
|
array_remove_at(base->sections_order, enumerator);
|
||||||
settings_section_destroy(section, contents);
|
settings_section_destroy(section, contents);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
array_remove_at(base->sections_order, enumerator);
|
||||||
|
array_insert_create(§ions, ARRAY_TAIL, section);
|
||||||
|
array_sort(sections, settings_section_sort, NULL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
enumerator->destroy(enumerator);
|
enumerator->destroy(enumerator);
|
||||||
|
|
||||||
enumerator = array_create_enumerator(base->kv_order);
|
while (array_remove(base->kv_order, 0, &kv))
|
||||||
while (enumerator->enumerate(enumerator, (void**)&kv))
|
|
||||||
{
|
{
|
||||||
if (array_bsearch(extension->kv, kv->key, settings_kv_find,
|
if (array_bsearch(extension->kv, kv->key, settings_kv_find,
|
||||||
NULL) == -1)
|
NULL) == -1)
|
||||||
{
|
{
|
||||||
idx = array_bsearch(base->kv, kv->key, settings_kv_find, NULL);
|
idx = array_bsearch(base->kv, kv->key, settings_kv_find, NULL);
|
||||||
array_remove(base->kv, idx, NULL);
|
array_remove(base->kv, idx, NULL);
|
||||||
array_remove_at(base->kv_order, enumerator);
|
|
||||||
settings_kv_destroy(kv, contents);
|
settings_kv_destroy(kv, contents);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
array_insert_create(&kvs, ARRAY_TAIL, kv);
|
||||||
|
array_sort(kvs, settings_kv_sort, NULL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
enumerator->destroy(enumerator);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
while (array_remove(extension->sections_order, 0, §ion))
|
while (array_remove(extension->sections_order, 0, §ion))
|
||||||
{
|
{
|
||||||
|
idx = array_bsearch(sections, section->name,
|
||||||
|
settings_section_find, NULL);
|
||||||
|
if (idx != -1)
|
||||||
|
{
|
||||||
|
section_t *existing;
|
||||||
|
|
||||||
|
array_remove(sections, idx, &existing);
|
||||||
|
array_insert(base->sections_order, ARRAY_TAIL, existing);
|
||||||
|
}
|
||||||
idx = array_bsearch(extension->sections, section->name,
|
idx = array_bsearch(extension->sections, section->name,
|
||||||
settings_section_find, NULL);
|
settings_section_find, NULL);
|
||||||
array_remove(extension->sections, idx, NULL);
|
array_remove(extension->sections, idx, NULL);
|
||||||
@@ -246,10 +266,20 @@ void settings_section_extend(section_t *base, section_t *extension,
|
|||||||
|
|
||||||
while (array_remove(extension->kv_order, 0, &kv))
|
while (array_remove(extension->kv_order, 0, &kv))
|
||||||
{
|
{
|
||||||
|
idx = array_bsearch(kvs, kv->key, settings_kv_find, NULL);
|
||||||
|
if (idx != -1)
|
||||||
|
{
|
||||||
|
kv_t *existing;
|
||||||
|
|
||||||
|
array_remove(kvs, idx, &existing);
|
||||||
|
array_insert(base->kv_order, ARRAY_TAIL, existing);
|
||||||
|
}
|
||||||
idx = array_bsearch(extension->kv, kv->key, settings_kv_find, NULL);
|
idx = array_bsearch(extension->kv, kv->key, settings_kv_find, NULL);
|
||||||
array_remove(extension->kv, idx, NULL);
|
array_remove(extension->kv, idx, NULL);
|
||||||
settings_kv_add(base, kv, contents);
|
settings_kv_add(base, kv, contents);
|
||||||
}
|
}
|
||||||
|
array_destroy(sections);
|
||||||
|
array_destroy(kvs);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -694,6 +694,87 @@ START_TEST(test_load_files_section)
|
|||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
|
START_TEST(test_order_kv)
|
||||||
|
{
|
||||||
|
chunk_t base = chunk_from_str(
|
||||||
|
"main {\n"
|
||||||
|
" key1 = val1\n"
|
||||||
|
" key2 = val2\n"
|
||||||
|
" key3 = val3\n"
|
||||||
|
"}");
|
||||||
|
chunk_t include = chunk_from_str(
|
||||||
|
"main {\n"
|
||||||
|
" key0 = val0\n"
|
||||||
|
" key3 = val3\n"
|
||||||
|
" key1 = val1\n"
|
||||||
|
"}");
|
||||||
|
linked_list_t *keys, *values;
|
||||||
|
|
||||||
|
create_settings(base);
|
||||||
|
ck_assert(chunk_write(include, include1, 0022, TRUE));
|
||||||
|
|
||||||
|
keys = linked_list_create_with_items("key1", "key2", "key3", NULL);
|
||||||
|
values = linked_list_create_with_items("val1", "val2", "val3", NULL);
|
||||||
|
verify_key_values(keys, values, "main");
|
||||||
|
|
||||||
|
/* the original order is maintained if the settings are merged */
|
||||||
|
ck_assert(settings->load_files(settings, include1, TRUE));
|
||||||
|
keys = linked_list_create_with_items("key1", "key2", "key3", "key0", NULL);
|
||||||
|
values = linked_list_create_with_items("val1", "val2", "val3", "val0", NULL);
|
||||||
|
verify_key_values(keys, values, "main");
|
||||||
|
|
||||||
|
/* but the new order is adopted if the settings are replaced */
|
||||||
|
ck_assert(settings->load_files(settings, include1, FALSE));
|
||||||
|
keys = linked_list_create_with_items("key0", "key3", "key1", NULL);
|
||||||
|
values = linked_list_create_with_items("val0", "val3", "val1", NULL);
|
||||||
|
verify_key_values(keys, values, "main");
|
||||||
|
|
||||||
|
unlink(include1);
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
START_TEST(test_order_section)
|
||||||
|
{
|
||||||
|
chunk_t base = chunk_from_str(
|
||||||
|
"main {\n"
|
||||||
|
" sub1 {\n"
|
||||||
|
" }\n"
|
||||||
|
" sub2 {\n"
|
||||||
|
" }\n"
|
||||||
|
" sub3 {\n"
|
||||||
|
" }\n"
|
||||||
|
"}");
|
||||||
|
chunk_t include = chunk_from_str(
|
||||||
|
"main {\n"
|
||||||
|
" sub0 {\n"
|
||||||
|
" }\n"
|
||||||
|
" sub3 {\n"
|
||||||
|
" }\n"
|
||||||
|
" sub1 {\n"
|
||||||
|
" }\n"
|
||||||
|
"}");
|
||||||
|
linked_list_t *sections;
|
||||||
|
|
||||||
|
create_settings(base);
|
||||||
|
ck_assert(chunk_write(include, include1, 0022, TRUE));
|
||||||
|
|
||||||
|
sections = linked_list_create_with_items("sub1", "sub2", "sub3", NULL);
|
||||||
|
verify_sections(sections, "main");
|
||||||
|
|
||||||
|
/* the original order is maintained if the settings are merged */
|
||||||
|
ck_assert(settings->load_files(settings, include1, TRUE));
|
||||||
|
sections = linked_list_create_with_items("sub1", "sub2", "sub3", "sub0", NULL);
|
||||||
|
verify_sections(sections, "main");
|
||||||
|
|
||||||
|
/* but the new order is adopted if the settings are replaced */
|
||||||
|
ck_assert(settings->load_files(settings, include1, FALSE));
|
||||||
|
sections = linked_list_create_with_items("sub0", "sub3", "sub1", NULL);
|
||||||
|
verify_sections(sections, "main");
|
||||||
|
|
||||||
|
unlink(include1);
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
START_SETUP(setup_fallback_config)
|
START_SETUP(setup_fallback_config)
|
||||||
{
|
{
|
||||||
create_settings(chunk_from_str(
|
create_settings(chunk_from_str(
|
||||||
@@ -811,7 +892,6 @@ START_TEST(test_add_fallback_printf)
|
|||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
|
|
||||||
START_SETUP(setup_string_config)
|
START_SETUP(setup_string_config)
|
||||||
{
|
{
|
||||||
create_settings(chunk_from_str(
|
create_settings(chunk_from_str(
|
||||||
@@ -967,6 +1047,8 @@ Suite *settings_suite_create()
|
|||||||
tcase_add_test(tc, test_include);
|
tcase_add_test(tc, test_include);
|
||||||
tcase_add_test(tc, test_load_files);
|
tcase_add_test(tc, test_load_files);
|
||||||
tcase_add_test(tc, test_load_files_section);
|
tcase_add_test(tc, test_load_files_section);
|
||||||
|
tcase_add_test(tc, test_order_kv);
|
||||||
|
tcase_add_test(tc, test_order_section);
|
||||||
suite_add_tcase(s, tc);
|
suite_add_tcase(s, tc);
|
||||||
|
|
||||||
tc = tcase_create("fallback");
|
tc = tcase_create("fallback");
|
||||||
|
|||||||
Reference in New Issue
Block a user