From 29f62b1d35c91fd24360161e7a9e06ae04973f48 Mon Sep 17 00:00:00 2001 From: Robert Fairley Date: Wed, 20 Feb 2019 00:56:54 -0500 Subject: [PATCH] libotutil: Add ot_keyfile_get_value_with_default_group_optional() Add ot_keyfile_get_value_with_default_group_optional() which allows getting values from keys where the group is optional in the config file. This is preparatory to add the sysroot.bootloader repo config key, where the sysroot group is optional. Closes: #1814 Approved by: jlebon --- src/libotutil/ot-keyfile-utils.c | 36 +++++++++++++++ src/libotutil/ot-keyfile-utils.h | 8 ++++ tests/test-keyfile-utils.c | 76 +++++++++++++++++++++++++++++--- 3 files changed, 114 insertions(+), 6 deletions(-) diff --git a/src/libotutil/ot-keyfile-utils.c b/src/libotutil/ot-keyfile-utils.c index 2af48a6e90..9d5903cefb 100644 --- a/src/libotutil/ot-keyfile-utils.c +++ b/src/libotutil/ot-keyfile-utils.c @@ -101,6 +101,42 @@ ot_keyfile_get_value_with_default (GKeyFile *keyfile, return ret; } +gboolean +ot_keyfile_get_value_with_default_group_optional (GKeyFile *keyfile, + const char *section, + const char *value, + const char *default_value, + char **out_value, + GError **error) +{ + gboolean ret = FALSE; + GError *local_error = NULL; + g_autofree char *ret_value = NULL; + + g_return_val_if_fail (keyfile != NULL, ret); + g_return_val_if_fail (section != NULL, ret); + g_return_val_if_fail (value != NULL, ret); + + if (!ot_keyfile_get_value_with_default (keyfile, section, value, default_value, &ret_value, &local_error)) + { + if (g_error_matches (local_error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_GROUP_NOT_FOUND)) + { + g_clear_error (&local_error); + ret_value = g_strdup (default_value); + } + else + { + g_propagate_error (error, local_error); + goto out; + } + } + + ret = TRUE; + ot_transfer_out_value(out_value, &ret_value); + out: + return ret; +} + /* Read the value of key as a string. If the value string contains * zero or one of the separators and none of the others, read the * string as a NULL-terminated array out_value. If the value string diff --git a/src/libotutil/ot-keyfile-utils.h b/src/libotutil/ot-keyfile-utils.h index 1a03cc261b..b16571df46 100644 --- a/src/libotutil/ot-keyfile-utils.h +++ b/src/libotutil/ot-keyfile-utils.h @@ -44,6 +44,14 @@ ot_keyfile_get_value_with_default (GKeyFile *keyfile, char **out_value, GError **error); +gboolean +ot_keyfile_get_value_with_default_group_optional (GKeyFile *keyfile, + const char *section, + const char *value, + const char *default_value, + char **out_value, + GError **error); + gboolean ot_keyfile_get_string_list_with_separator_choice (GKeyFile *keyfile, const char *section, diff --git a/tests/test-keyfile-utils.c b/tests/test-keyfile-utils.c index 8acd0a1cd3..258e7dd8ff 100644 --- a/tests/test-keyfile-utils.c +++ b/tests/test-keyfile-utils.c @@ -79,7 +79,6 @@ test_get_value_with_default (void) /* Avoid that g_return_val_if_fail causes the test to fail. */ always_fatal_mask = g_log_set_always_fatal (0); - g_assert_false (ot_keyfile_get_value_with_default (g_keyfile, NULL, "value_foo", @@ -124,11 +123,75 @@ test_get_value_with_default (void) g_clear_pointer (&out, g_free); g_assert_false (ot_keyfile_get_value_with_default (g_keyfile, - "a_fake_section", - "a_value_true", - "no value", - &out, - &error)); + "a_fake_section", + "a_value_true", + "no value", + &out, + &error)); + g_clear_error (&error); + g_clear_pointer (&out, g_free); +} + +static void +test_get_value_with_default_group_optional (void) +{ + g_autoptr(GError) error = NULL; + g_autofree char *out = NULL; + GLogLevelFlags always_fatal_mask; + const char *section = "section"; + +/* Avoid that g_return_val_if_fail causes the test to fail. */ + always_fatal_mask = g_log_set_always_fatal (0); + + g_assert_false (ot_keyfile_get_value_with_default_group_optional (g_keyfile, + NULL, + "value_foo", + "none", + &out, + &error)); + g_clear_pointer (&out, g_free); + g_assert_false (ot_keyfile_get_value_with_default_group_optional (g_keyfile, + section, + NULL, + "none", + &out, + &error)); + g_clear_pointer (&out, g_free); + g_assert_false (ot_keyfile_get_value_with_default_group_optional (g_keyfile, + section, + NULL, + "something", + &out, + &error)); + g_clear_pointer (&out, g_free); + + /* Restore the old mask. */ + g_log_set_always_fatal (always_fatal_mask); + + g_assert (ot_keyfile_get_value_with_default_group_optional (g_keyfile, + section, + "value_foo", + "none", + &out, + &error)); + g_assert_cmpstr (out, ==, "foo"); + g_clear_pointer (&out, g_free); + + g_assert (ot_keyfile_get_value_with_default_group_optional (g_keyfile, + section, + "a_not_existing_value", + "correct", + &out, + &error)); + g_assert_cmpstr (out, ==, "correct"); + g_clear_pointer (&out, g_free); + + g_assert (ot_keyfile_get_value_with_default_group_optional (g_keyfile, + "an_optional_section", + "a_value_true", + "no value", + &out, + &error)); g_clear_error (&error); g_clear_pointer (&out, g_free); } @@ -191,6 +254,7 @@ int main (int argc, char **argv) g_test_add_func ("/keyfile-utils/get-boolean-with-default", test_get_boolean_with_default); g_test_add_func ("/keyfile-utils/get-value-with-default", test_get_value_with_default); + g_test_add_func ("/keyfile-utils/get-value-with-default-group-optional", test_get_value_with_default_group_optional); g_test_add_func ("/keyfile-utils/copy-group", test_copy_group); ret = g_test_run();