From 9966fe4493455dcdfe64483a50676891a878c72b Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Mon, 16 May 2011 15:30:31 -0400 Subject: [PATCH] g_key_file_has_key_full: New function to fix g_key_file_has_key()'s GError semantics See https://bugzilla.gnome.org/show_bug.cgi?id=649657 for discussion of why it's bad for bindings for gerror return values to both signal errors and carry meaning. https://bugzilla.gnome.org/show_bug.cgi?id=650345 --- docs/reference/glib/glib-sections.txt | 1 + glib/gkeyfile.c | 54 +++++++++++++++++++++++++++++++++-- glib/gkeyfile.h | 5 ++++ glib/glib.symbols | 1 + glib/tests/keyfile.c | 16 +++++++++++ 5 files changed, 74 insertions(+), 3 deletions(-) diff --git a/docs/reference/glib/glib-sections.txt b/docs/reference/glib/glib-sections.txt index de8f4ae..f1a8c4f 100644 --- a/docs/reference/glib/glib-sections.txt +++ b/docs/reference/glib/glib-sections.txt @@ -1746,6 +1746,7 @@ g_key_file_get_groups g_key_file_get_keys g_key_file_has_group g_key_file_has_key +g_key_file_has_key_full g_key_file_get_value diff --git a/glib/gkeyfile.c b/glib/gkeyfile.c index 31c2a15..3afd781 100644 --- a/glib/gkeyfile.c +++ b/glib/gkeyfile.c @@ -3130,14 +3130,22 @@ g_key_file_has_group (GKeyFile *key_file, } /** - * g_key_file_has_key: + * g_key_file_has_key: (skip) * @key_file: a #GKeyFile * @group_name: a group name * @key: a key name * @error: return location for a #GError * * Looks whether the key file has the key @key in the group - * @group_name. + * @group_name. + * + * This function does not follow the rules for #GError strictly; + * the return value both carries meaning and signals an error. To use + * this function, you must pass a #GError pointer in @error, and check + * whether it is not %NULL to see if an error occurred. + * + * See g_key_file_has_key_full() for a replacement function which does + * follow the #GError rules. * * Return value: %TRUE if @key is a part of @group_name, %FALSE * otherwise. @@ -3150,6 +3158,44 @@ g_key_file_has_key (GKeyFile *key_file, const gchar *key, GError **error) { + GError *temp_error = NULL; + gboolean has_key; + + if (g_key_file_has_key_full (key_file, group_name, key, &has_key, &temp_error)) + { + return has_key; + } + else + { + g_propagate_error (error, temp_error); + return FALSE; + } +} + +/** + * g_key_file_has_key_full: + * @key_file: a #GKeyFile + * @group_name: a group name + * @key: a key name + * @has_key: (out) (allow-none): Return location for whether or not key exists + * @error: return location for a #GError + * + * Looks whether the key file has the key @key in the group + * @group_name. + * + * Return value: %TRUE if a group with the name @group_name + * exists. Otherwise, @error is set and %FALSE is returned. + * + * Since: 2.30 + * Rename to: g_key_file_has_key + **/ +gboolean +g_key_file_has_key_full (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + gboolean *has_key, + GError **error) +{ GKeyFileKeyValuePair *pair; GKeyFileGroup *group; @@ -3171,7 +3217,9 @@ g_key_file_has_key (GKeyFile *key_file, pair = g_key_file_lookup_key_value_pair (key_file, group, key); - return pair != NULL; + if (has_key) + *has_key = pair != NULL; + return TRUE; } static void diff --git a/glib/gkeyfile.h b/glib/gkeyfile.h index e16dc61..e89edaa 100644 --- a/glib/gkeyfile.h +++ b/glib/gkeyfile.h @@ -94,6 +94,11 @@ gboolean g_key_file_has_key (GKeyFile *key_file, const gchar *group_name, const gchar *key, GError **error); +gboolean g_key_file_has_key_full (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + gboolean *has_key, + GError **error); gchar *g_key_file_get_value (GKeyFile *key_file, const gchar *group_name, const gchar *key, diff --git a/glib/glib.symbols b/glib/glib.symbols index 08b2f17..7c82970 100644 --- a/glib/glib.symbols +++ b/glib/glib.symbols @@ -611,6 +611,7 @@ g_key_file_get_string_list G_GNUC_MALLOC g_key_file_get_value G_GNUC_MALLOC g_key_file_has_group g_key_file_has_key +g_key_file_has_key_full g_key_file_load_from_dirs g_key_file_load_from_data g_key_file_load_from_data_dirs diff --git a/glib/tests/keyfile.c b/glib/tests/keyfile.c index 606efe8..f5b0528 100644 --- a/glib/tests/keyfile.c +++ b/glib/tests/keyfile.c @@ -444,6 +444,7 @@ test_listing (void) gsize len; gchar *start; GError *error = NULL; + gboolean has_key; const gchar *data = "[group1]\n" @@ -496,6 +497,21 @@ test_listing (void) g_key_file_has_key (keyfile, "no-such-group", "key", &error); check_error (&error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_GROUP_NOT_FOUND); + g_assert (g_key_file_has_key_full (keyfile, "group1", "key1", &has_key, &error)); + check_no_error (&error); + g_assert (has_key); + + g_assert (g_key_file_has_key_full (keyfile, "group2", "key3", &has_key, &error)); + check_no_error (&error); + g_assert (has_key); + + g_assert (g_key_file_has_key_full (keyfile, "group2", "no-such-key", &has_key, &error)); + g_assert (!has_key); + check_no_error (&error); + + g_assert (!g_key_file_has_key_full (keyfile, "no-such-group", "key", &has_key, &error)); + check_error (&error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_GROUP_NOT_FOUND); + g_key_file_free (keyfile); } -- 2.7.4