Merge branch 'keyfile-parsing-performance' into 'main'

Keyfile parsing performance improvements

See merge request GNOME/glib!1991
This commit is contained in:
Sebastian Dröge 2021-11-02 11:08:15 +00:00
commit 82be9c4f11
3 changed files with 184 additions and 150 deletions

View File

@ -511,8 +511,8 @@ struct _GKeyFile
GKeyFileFlags flags;
gboolean checked_locales;
gchar **locales;
gboolean checked_locales; /* TRUE if @locales has been initialised */
gchar **locales; /* (nullable) */
gint ref_count; /* (atomic) */
};
@ -575,7 +575,8 @@ static void g_key_file_add_key (GKeyFile
static void g_key_file_add_group (GKeyFile *key_file,
const gchar *group_name);
static gboolean g_key_file_is_group_name (const gchar *name);
static gboolean g_key_file_is_key_name (const gchar *name);
static gboolean g_key_file_is_key_name (const gchar *name,
gsize len);
static void g_key_file_key_value_pair_free (GKeyFileKeyValuePair *pair);
static gboolean g_key_file_line_is_comment (const gchar *line);
static gboolean g_key_file_line_is_group (const gchar *line);
@ -598,7 +599,7 @@ static gdouble g_key_file_parse_value_as_double (GKeyFile
static gboolean g_key_file_parse_value_as_boolean (GKeyFile *key_file,
const gchar *value,
GError **error);
static gchar *g_key_file_parse_boolean_as_value (GKeyFile *key_file,
static const gchar *g_key_file_parse_boolean_as_value (GKeyFile *key_file,
gboolean value);
static gchar *g_key_file_parse_value_as_comment (GKeyFile *key_file,
const gchar *value,
@ -617,7 +618,8 @@ static void g_key_file_parse_group (GKeyFile
const gchar *line,
gsize length,
GError **error);
static gchar *key_get_locale (const gchar *key);
static const gchar *key_get_locale (const gchar *key,
gsize *len_out);
static void g_key_file_parse_data (GKeyFile *key_file,
const gchar *data,
gsize length,
@ -745,9 +747,10 @@ find_file_in_data_dirs (const gchar *file,
while (data_dirs && (data_dir = *data_dirs) && fd == -1)
{
gchar *candidate_file, *sub_dir;
const gchar *candidate_file;
gchar *sub_dir;
candidate_file = (gchar *) file;
candidate_file = file;
sub_dir = g_strdup ("");
while (candidate_file != NULL && fd == -1)
{
@ -1227,7 +1230,8 @@ g_key_file_unref (GKeyFile *key_file)
*/
static gboolean
g_key_file_locale_is_interesting (GKeyFile *key_file,
const gchar *locale)
const gchar *locale,
gsize locale_len)
{
gsize i;
@ -1236,13 +1240,15 @@ g_key_file_locale_is_interesting (GKeyFile *key_file,
if (!key_file->checked_locales)
{
g_assert (key_file->locales == NULL);
key_file->locales = g_strdupv ((gchar **)g_get_language_names ());
key_file->checked_locales = TRUE;
}
for (i = 0; key_file->locales[i] != NULL; i++)
{
if (g_ascii_strcasecmp (key_file->locales[i], locale) == 0)
if (g_ascii_strncasecmp (key_file->locales[i], locale, locale_len) == 0 &&
key_file->locales[i][locale_len] == '\0')
return TRUE;
}
@ -1256,12 +1262,12 @@ g_key_file_parse_line (GKeyFile *key_file,
GError **error)
{
GError *parse_error = NULL;
gchar *line_start;
const gchar *line_start;
g_return_if_fail (key_file != NULL);
g_return_if_fail (line != NULL);
line_start = (gchar *) line;
line_start = line;
while (g_ascii_isspace (*line_start))
line_start++;
@ -1352,7 +1358,9 @@ g_key_file_parse_key_value_pair (GKeyFile *key_file,
gsize length,
GError **error)
{
gchar *key, *value, *key_end, *value_start, *locale;
gchar *key, *key_end, *value_start;
const gchar *locale;
gsize locale_len;
gsize key_len, value_len;
if (key_file->current_group == NULL || key_file->current_group->name == NULL)
@ -1379,37 +1387,36 @@ g_key_file_parse_key_value_pair (GKeyFile *key_file,
g_warn_if_fail (key_len <= length);
key = g_strndup (line, key_len - 1);
if (!g_key_file_is_key_name (key))
if (!g_key_file_is_key_name (line, key_len - 1))
{
g_set_error (error, G_KEY_FILE_ERROR,
G_KEY_FILE_ERROR_PARSE,
_("Invalid key name: %s"), key);
g_free (key);
_("Invalid key name: %.*s"), (int) key_len - 1, line);
return;
}
key = g_strndup (line, key_len - 1);
/* Pull the value from the line (chugging leading whitespace)
*/
while (g_ascii_isspace (*value_start))
value_start++;
value_len = line + length - value_start + 1;
value = g_strndup (value_start, value_len);
value_len = line + length - value_start;
g_warn_if_fail (key_file->start_group != NULL);
if (key_file->current_group
&& key_file->current_group->name
&& strcmp (key_file->start_group->name,
key_file->current_group->name) == 0
/* Checked on entry to this function */
g_assert (key_file->current_group != NULL);
g_assert (key_file->current_group->name != NULL);
if (key_file->start_group == key_file->current_group
&& strcmp (key, "Encoding") == 0)
{
if (g_ascii_strcasecmp (value, "UTF-8") != 0)
if (value_len != strlen ("UTF-8") ||
g_ascii_strncasecmp (value_start, "UTF-8", value_len) != 0)
{
gchar *value_utf8 = g_utf8_make_valid (value, value_len);
gchar *value_utf8 = g_utf8_make_valid (value_start, value_len);
g_set_error (error, G_KEY_FILE_ERROR,
G_KEY_FILE_ERROR_UNKNOWN_ENCODING,
_("Key file contains unsupported "
@ -1417,47 +1424,53 @@ g_key_file_parse_key_value_pair (GKeyFile *key_file,
g_free (value_utf8);
g_free (key);
g_free (value);
return;
}
}
/* Is this key a translation? If so, is it one that we care about?
*/
locale = key_get_locale (key);
locale = key_get_locale (key, &locale_len);
if (locale == NULL || g_key_file_locale_is_interesting (key_file, locale))
if (locale == NULL || g_key_file_locale_is_interesting (key_file, locale, locale_len))
{
GKeyFileKeyValuePair *pair;
pair = g_slice_new (GKeyFileKeyValuePair);
pair->key = key;
pair->value = value;
pair->key = g_steal_pointer (&key);
pair->value = g_strndup (value_start, value_len);
g_key_file_add_key_value_pair (key_file, key_file->current_group, pair);
}
else
{
g_free (key);
g_free (value);
}
g_free (locale);
g_free (key);
}
static gchar *
key_get_locale (const gchar *key)
static const gchar *
key_get_locale (const gchar *key,
gsize *len_out)
{
gchar *locale;
const gchar *locale;
gsize locale_len;
locale = g_strrstr (key, "[");
if (locale != NULL)
locale_len = strlen (locale);
else
locale_len = 0;
if (locale && strlen (locale) <= 2)
locale = NULL;
if (locale)
locale = g_strndup (locale + 1, strlen (locale) - 2);
if (locale_len > 2)
{
locale++; /* skip `[` */
locale_len -= 2; /* drop `[` and `]` */
}
else
{
locale = NULL;
locale_len = 0;
}
*len_out = locale_len;
return locale;
}
@ -1875,8 +1888,8 @@ g_key_file_set_value (GKeyFile *key_file,
GKeyFileKeyValuePair *pair;
g_return_if_fail (key_file != NULL);
g_return_if_fail (g_key_file_is_group_name (group_name));
g_return_if_fail (g_key_file_is_key_name (key));
g_return_if_fail (group_name != NULL && g_key_file_is_group_name (group_name));
g_return_if_fail (key != NULL && g_key_file_is_key_name (key, strlen (key)));
g_return_if_fail (value != NULL);
group = g_key_file_lookup_group (key_file, group_name);
@ -2556,13 +2569,12 @@ g_key_file_set_boolean (GKeyFile *key_file,
const gchar *key,
gboolean value)
{
gchar *result;
const gchar *result;
g_return_if_fail (key_file != NULL);
result = g_key_file_parse_boolean_as_value (key_file, value);
g_key_file_set_value (key_file, group_name, key, result);
g_free (result);
}
/**
@ -2673,14 +2685,12 @@ g_key_file_set_boolean_list (GKeyFile *key_file,
value_list = g_string_sized_new (length * 8);
for (i = 0; i < length; i++)
{
gchar *value;
const gchar *value;
value = g_key_file_parse_boolean_as_value (key_file, list[i]);
g_string_append (value_list, value);
g_string_append_c (value_list, key_file->list_separator);
g_free (value);
}
g_key_file_set_value (key_file, group_name, key, value_list->str);
@ -3341,7 +3351,7 @@ g_key_file_set_group_comment (GKeyFile *key_file,
{
GKeyFileGroup *group;
g_return_val_if_fail (g_key_file_is_group_name (group_name), FALSE);
g_return_val_if_fail (group_name != NULL && g_key_file_is_group_name (group_name), FALSE);
group = g_key_file_lookup_group (key_file, group_name);
if (!group)
@ -3471,7 +3481,7 @@ g_key_file_get_key_comment (GKeyFile *key_file,
GString *string;
gchar *comment;
g_return_val_if_fail (g_key_file_is_group_name (group_name), NULL);
g_return_val_if_fail (group_name != NULL && g_key_file_is_group_name (group_name), NULL);
group = g_key_file_lookup_group (key_file, group_name);
if (!group)
@ -3818,7 +3828,7 @@ g_key_file_add_group (GKeyFile *key_file,
GKeyFileGroup *group;
g_return_if_fail (key_file != NULL);
g_return_if_fail (g_key_file_is_group_name (group_name));
g_return_if_fail (group_name != NULL && g_key_file_is_group_name (group_name));
group = g_key_file_lookup_group (key_file, group_name);
if (group != NULL)
@ -4083,17 +4093,12 @@ g_key_file_lookup_group_node (GKeyFile *key_file,
const gchar *group_name)
{
GKeyFileGroup *group;
GList *tmp;
for (tmp = key_file->groups; tmp != NULL; tmp = tmp->next)
{
group = (GKeyFileGroup *) tmp->data;
group = g_key_file_lookup_group (key_file, group_name);
if (group == NULL)
return NULL;
if (group && group->name && strcmp (group->name, group_name) == 0)
break;
}
return tmp;
return g_list_find (key_file->groups, group);
}
static GKeyFileGroup *
@ -4149,12 +4154,11 @@ g_key_file_line_is_comment (const gchar *line)
static gboolean
g_key_file_is_group_name (const gchar *name)
{
gchar *p, *q;
const gchar *p, *q;
if (name == NULL)
return FALSE;
g_assert (name != NULL);
p = q = (gchar *) name;
p = q = name;
while (*q && *q != ']' && *q != '[' && !g_ascii_iscntrl (*q))
q = g_utf8_find_next_char (q, NULL);
@ -4165,19 +4169,25 @@ g_key_file_is_group_name (const gchar *name)
}
static gboolean
g_key_file_is_key_name (const gchar *name)
g_key_file_is_key_name (const gchar *name,
gsize len)
{
gchar *p, *q;
const gchar *p, *q, *end;
if (name == NULL)
return FALSE;
g_assert (name != NULL);
p = q = name;
end = name + len;
p = q = (gchar *) name;
/* We accept a little more than the desktop entry spec says,
* since gnome-vfs uses mime-types as keys in its cache.
*/
while (*q && *q != '=' && *q != '[' && *q != ']')
q = g_utf8_find_next_char (q, NULL);
while (q < end && *q && *q != '=' && *q != '[' && *q != ']')
{
q = g_utf8_find_next_char (q, end);
if (q == NULL)
q = end;
}
/* No empty keys, please */
if (q == p)
@ -4194,8 +4204,17 @@ g_key_file_is_key_name (const gchar *name)
if (*q == '[')
{
q++;
while (*q && (g_unichar_isalnum (g_utf8_get_char_validated (q, -1)) || *q == '-' || *q == '_' || *q == '.' || *q == '@'))
q = g_utf8_find_next_char (q, NULL);
while (q < end &&
*q != '\0' &&
(g_unichar_isalnum (g_utf8_get_char_validated (q, end - q)) || *q == '-' || *q == '_' || *q == '.' || *q == '@'))
{
q = g_utf8_find_next_char (q, end);
if (q == NULL)
{
q = end;
break;
}
}
if (*q != ']')
return FALSE;
@ -4203,7 +4222,7 @@ g_key_file_is_key_name (const gchar *name)
q++;
}
if (*q != '\0')
if (q < end)
return FALSE;
return TRUE;
@ -4215,9 +4234,9 @@ g_key_file_is_key_name (const gchar *name)
static gboolean
g_key_file_line_is_group (const gchar *line)
{
gchar *p;
const gchar *p;
p = (gchar *) line;
p = line;
if (*p != '[')
return FALSE;
@ -4243,9 +4262,9 @@ g_key_file_line_is_group (const gchar *line)
static gboolean
g_key_file_line_is_key_value_pair (const gchar *line)
{
gchar *p;
const gchar *p;
p = (gchar *) g_utf8_strchr (line, -1, '=');
p = g_utf8_strchr (line, -1, '=');
if (!p)
return FALSE;
@ -4264,11 +4283,12 @@ g_key_file_parse_value_as_string (GKeyFile *key_file,
GSList **pieces,
GError **error)
{
gchar *string_value, *p, *q0, *q;
gchar *string_value, *q0, *q;
const gchar *p;
string_value = g_new (gchar, strlen (value) + 1);
p = (gchar *) value;
p = value;
q0 = q = string_value;
while (*p)
{
@ -4363,7 +4383,8 @@ g_key_file_parse_string_as_value (GKeyFile *key_file,
const gchar *string,
gboolean escape_separator)
{
gchar *value, *p, *q;
gchar *value, *q;
const gchar *p;
gsize length;
gboolean parsing_leading_space;
@ -4374,7 +4395,7 @@ g_key_file_parse_string_as_value (GKeyFile *key_file,
*/
value = g_new (gchar, 2 * length);
p = (gchar *) string;
p = string;
q = value;
parsing_leading_space = TRUE;
while (p < (string + length - 1))
@ -4560,14 +4581,14 @@ g_key_file_parse_value_as_boolean (GKeyFile *key_file,
return FALSE;
}
static gchar *
static const gchar *
g_key_file_parse_boolean_as_value (GKeyFile *key_file,
gboolean value)
{
if (value)
return g_strdup ("true");
return "true";
else
return g_strdup ("false");
return "false";
}
static gchar *

View File

@ -1874,7 +1874,9 @@ g_ascii_strcasecmp (const gchar *s1,
* @n: number of characters to compare
*
* Compare @s1 and @s2, ignoring the case of ASCII characters and any
* characters after the first @n in each string.
* characters after the first @n in each string. If either string is
* less than @n bytes long, comparison will stop at the first nul byte
* encountered.
*
* Unlike the BSD strcasecmp() function, this only recognizes standard
* ASCII letters and ignores the locale, treating all non-ASCII

View File

@ -45,7 +45,7 @@ check_string_value (GKeyFile *keyfile,
value = g_key_file_get_string (keyfile, group, key, &error);
check_no_error (&error);
g_assert (value != NULL);
g_assert_nonnull (value);
g_assert_cmpstr (value, ==, expected);
g_free (value);
}
@ -62,7 +62,7 @@ check_locale_string_value (GKeyFile *keyfile,
value = g_key_file_get_locale_string (keyfile, group, key, locale, &error);
check_no_error (&error);
g_assert (value != NULL);
g_assert_nonnull (value);
g_assert_cmpstr (value, ==, expected);
g_free (value);
}
@ -95,14 +95,14 @@ check_string_list_value (GKeyFile *keyfile,
value = g_key_file_get_string_list (keyfile, group, key, &len, &error);
check_no_error (&error);
g_assert (value != NULL);
g_assert_nonnull (value);
va_start (args, key);
i = 0;
v = va_arg (args, gchar*);
while (v)
{
g_assert (value[i] != NULL);
g_assert_nonnull (value[i]);
g_assert_cmpstr (v, ==, value[i]);
i++;
v = va_arg (args, gchar*);
@ -128,14 +128,14 @@ check_locale_string_list_value (GKeyFile *keyfile,
value = g_key_file_get_locale_string_list (keyfile, group, key, locale, &len, &error);
check_no_error (&error);
g_assert (value != NULL);
g_assert_nonnull (value);
va_start (args, locale);
i = 0;
v = va_arg (args, gchar*);
while (v)
{
g_assert (value[i] != NULL);
g_assert_nonnull (value[i]);
g_assert_cmpstr (v, ==, value[i]);
i++;
v = va_arg (args, gchar*);
@ -160,7 +160,7 @@ check_integer_list_value (GKeyFile *keyfile,
value = g_key_file_get_integer_list (keyfile, group, key, &len, &error);
check_no_error (&error);
g_assert (value != NULL);
g_assert_nonnull (value);
va_start (args, key);
i = 0;
@ -192,7 +192,7 @@ check_double_list_value (GKeyFile *keyfile,
value = g_key_file_get_double_list (keyfile, group, key, &len, &error);
check_no_error (&error);
g_assert (value != NULL);
g_assert_nonnull (value);
va_start (args, key);
i = 0;
@ -224,7 +224,7 @@ check_boolean_list_value (GKeyFile *keyfile,
value = g_key_file_get_boolean_list (keyfile, group, key, &len, &error);
check_no_error (&error);
g_assert (value != NULL);
g_assert_nonnull (value);
va_start (args, key);
i = 0;
@ -436,7 +436,7 @@ test_comments (void)
check_no_error (&error);
comment = g_key_file_get_comment (keyfile, "group1", "key2", &error);
check_no_error (&error);
g_assert (comment == NULL);
g_assert_null (comment);
comment = g_key_file_get_comment (keyfile, "group1", "key4", &error);
check_no_error (&error);
@ -452,7 +452,7 @@ test_comments (void)
check_error (&error,
G_KEY_FILE_ERROR,
G_KEY_FILE_ERROR_GROUP_NOT_FOUND);
g_assert (comment == NULL);
g_assert_null (comment);
g_key_file_free (keyfile);
}
@ -479,7 +479,7 @@ test_listing (void)
keyfile = load_data (data, 0);
names = g_key_file_get_groups (keyfile, &len);
g_assert (names != NULL);
g_assert_nonnull (names);
check_length ("groups", g_strv_length (names), len, 2);
check_name ("group name", names[0], "group1", 0);
@ -501,20 +501,20 @@ test_listing (void)
g_strfreev (names);
g_assert (g_key_file_has_group (keyfile, "group1"));
g_assert (g_key_file_has_group (keyfile, "group2"));
g_assert (!g_key_file_has_group (keyfile, "group10"));
g_assert (!g_key_file_has_group (keyfile, "group20"));
g_assert_true (g_key_file_has_group (keyfile, "group1"));
g_assert_true (g_key_file_has_group (keyfile, "group2"));
g_assert_false (g_key_file_has_group (keyfile, "group10"));
g_assert_false (g_key_file_has_group (keyfile, "group20"));
start = g_key_file_get_start_group (keyfile);
g_assert_cmpstr (start, ==, "group1");
g_free (start);
g_assert (g_key_file_has_key (keyfile, "group1", "key1", &error));
g_assert_true (g_key_file_has_key (keyfile, "group1", "key1", &error));
check_no_error (&error);
g_assert (g_key_file_has_key (keyfile, "group2", "key3", &error));
g_assert_true (g_key_file_has_key (keyfile, "group2", "key3", &error));
check_no_error (&error);
g_assert (!g_key_file_has_key (keyfile, "group2", "no-such-key", NULL));
g_assert_false (g_key_file_has_key (keyfile, "group2", "no-such-key", NULL));
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);
@ -902,7 +902,7 @@ test_group_remove (void)
keyfile = load_data (data, 0);
names = g_key_file_get_groups (keyfile, &len);
g_assert (names != NULL);
g_assert_nonnull (names);
check_length ("groups", g_strv_length (names), len, 3);
check_name ("group name", names[0], "group1", 0);
@ -915,7 +915,7 @@ test_group_remove (void)
g_strfreev (names);
names = g_key_file_get_groups (keyfile, &len);
g_assert (names != NULL);
g_assert_nonnull (names);
check_length ("groups", g_strv_length (names), len, 2);
check_name ("group name", names[0], "group2", 0);
@ -927,7 +927,7 @@ test_group_remove (void)
g_strfreev (names);
names = g_key_file_get_groups (keyfile, &len);
g_assert (names != NULL);
g_assert_nonnull (names);
check_length ("groups", g_strv_length (names), len, 1);
check_name ("group name", names[0], "group3", 0);
@ -1058,7 +1058,7 @@ test_group_names (void)
check_error (&error,
G_KEY_FILE_ERROR,
G_KEY_FILE_ERROR_GROUP_NOT_FOUND);
g_assert (value == NULL);
g_assert_null (value);
g_key_file_free (keyfile);
keyfile = g_key_file_new ();
@ -1067,7 +1067,7 @@ test_group_names (void)
check_error (&error,
G_KEY_FILE_ERROR,
G_KEY_FILE_ERROR_GROUP_NOT_FOUND);
g_assert (value == NULL);
g_assert_null (value);
g_key_file_free (keyfile);
keyfile = g_key_file_new ();
@ -1076,7 +1076,7 @@ test_group_names (void)
check_error (&error,
G_KEY_FILE_ERROR,
G_KEY_FILE_ERROR_GROUP_NOT_FOUND);
g_assert (value == NULL);
g_assert_null (value);
g_key_file_free (keyfile);
keyfile = g_key_file_new ();
@ -1335,7 +1335,7 @@ test_reload_idempotency (void)
check_no_error (&error);
data1 = g_key_file_to_data (keyfile, &len1, &error);
g_assert (data1 != NULL);
g_assert_nonnull (data1);
g_key_file_free (keyfile);
keyfile = g_key_file_new ();
@ -1346,7 +1346,7 @@ test_reload_idempotency (void)
check_no_error (&error);
data2 = g_key_file_to_data (keyfile, &len2, &error);
g_assert (data2 != NULL);
g_assert_nonnull (data2);
g_key_file_free (keyfile);
g_assert_cmpstr (data1, ==, data2);
@ -1377,13 +1377,13 @@ test_int64 (void)
ok = g_key_file_load_from_data (file, int64_data, strlen (int64_data),
0, NULL);
g_assert (ok);
g_assert_true (ok);
c = g_key_file_get_uint64 (file, "bees", "c", NULL);
g_assert (c == G_GUINT64_CONSTANT (123456789123456789));
g_assert_cmpuint (c, ==, G_GUINT64_CONSTANT (123456789123456789));
d = g_key_file_get_int64 (file, "bees", "d", NULL);
g_assert (d == G_GINT64_CONSTANT (-123456789123456789));
g_assert_cmpint (d, ==, G_GINT64_CONSTANT (-123456789123456789));
g_key_file_set_uint64 (file, "bees", "c",
G_GUINT64_CONSTANT (987654321987654321));
@ -1417,7 +1417,7 @@ test_load (void)
loaded = g_key_file_load_from_file (file, g_test_get_filename (G_TEST_DIST, "keyfiletest.ini", NULL), 0, &error);
#endif
g_assert_no_error (error);
g_assert (loaded);
g_assert_true (loaded);
g_key_file_set_locale_string (file, "test", "key4", "de", "Vierter Schlüssel");
g_key_file_set_boolean_list (file, "test", "key5", bools, 2);
@ -1431,7 +1431,7 @@ test_load (void)
file = g_key_file_new ();
error = NULL;
g_assert (!g_key_file_load_from_data_dirs (file, "keyfile-test.ini", NULL, 0, &error));
g_assert_false (g_key_file_load_from_data_dirs (file, "keyfile-test.ini", NULL, 0, &error));
g_assert_error (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_NOT_FOUND);
g_error_free (error);
g_key_file_free (file);
@ -1456,25 +1456,25 @@ test_save (void)
kf = g_key_file_new ();
ok = g_key_file_load_from_data (kf, data, strlen (data), 0, NULL);
g_assert (ok);
g_assert_true (ok);
file = g_strdup ("key_file_XXXXXX");
fd = g_mkstemp (file);
g_assert (fd != -1);
g_assert_cmpint (fd, !=, -1);
ok = g_close (fd, &error);
g_assert (ok);
g_assert_true (ok);
g_assert_no_error (error);
ok = g_key_file_save_to_file (kf, file, &error);
g_assert (ok);
g_assert_true (ok);
g_assert_no_error (error);
kf2 = g_key_file_new ();
ok = g_key_file_load_from_file (kf2, file, 0, &error);
g_assert (ok);
g_assert_true (ok);
g_assert_no_error (error);
c = g_key_file_get_uint64 (kf2, "bees", "c", NULL);
g_assert (c == G_GUINT64_CONSTANT (123456789123456789));
g_assert_cmpuint (c, ==, G_GUINT64_CONSTANT (123456789123456789));
remove (file);
g_free (file);
@ -1490,10 +1490,10 @@ test_load_fail (void)
file = g_key_file_new ();
error = NULL;
g_assert (!g_key_file_load_from_file (file, g_test_get_filename (G_TEST_DIST, "keyfile.c", NULL), 0, &error));
g_assert_false (g_key_file_load_from_file (file, g_test_get_filename (G_TEST_DIST, "keyfile.c", NULL), 0, &error));
g_assert_error (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_PARSE);
g_clear_error (&error);
g_assert (!g_key_file_load_from_file (file, "/nosuchfile", 0, &error));
g_assert_false (g_key_file_load_from_file (file, "/nosuchfile", 0, &error));
g_assert_error (error, G_FILE_ERROR, G_FILE_ERROR_NOENT);
g_clear_error (&error);
@ -1517,22 +1517,22 @@ test_non_utf8 (void)
file = g_key_file_new ();
ok = g_key_file_load_from_data (file, data, strlen (data), 0, NULL);
g_assert (ok);
g_assert_true (ok);
error = NULL;
s = g_key_file_get_string (file, "group", "a", &error);
g_assert_error (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_UNKNOWN_ENCODING);
g_assert (s == NULL);
g_assert_null (s);
g_clear_error (&error);
l = g_key_file_get_string_list (file, "group", "b", NULL, &error);
g_assert_error (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_UNKNOWN_ENCODING);
g_assert (l == NULL);
g_assert_null (l);
g_clear_error (&error);
l = g_key_file_get_string_list (file, "group", "c", NULL, &error);
g_assert_error (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_INVALID_VALUE);
g_assert (l == NULL);
g_assert_null (l);
g_clear_error (&error);
@ -1587,8 +1587,8 @@ test_ref (void)
file = g_key_file_new ();
ok = g_key_file_load_from_data (file, data, strlen (data), 0, NULL);
g_assert (ok);
g_assert (g_key_file_has_key (file, "group", "a", NULL));
g_assert_true (ok);
g_assert_true (g_key_file_has_key (file, "group", "a", NULL));
g_key_file_ref (file);
g_key_file_free (file);
g_key_file_unref (file);
@ -1666,7 +1666,7 @@ test_limbo (void)
error = NULL;
ok = g_key_file_load_from_data (file, data, strlen (data), 0, &error);
g_assert (!ok);
g_assert_false (ok);
g_assert_error (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_GROUP_NOT_FOUND);
g_clear_error (&error);
g_key_file_free (file);
@ -1675,21 +1675,32 @@ test_limbo (void)
static void
test_utf8 (void)
{
GKeyFile *file;
static const char data[] =
"[group]\n"
"Encoding=non-UTF-8\n";
gboolean ok;
GError *error;
const gchar *invalid_encoding_names[] =
{
"non-UTF-8",
"UTF",
"UTF-9",
};
gsize i;
file = g_key_file_new ();
for (i = 0; i < G_N_ELEMENTS (invalid_encoding_names); i++)
{
GKeyFile *file = NULL;
gchar *data = NULL;
gboolean ok;
GError *error = NULL;
error = NULL;
ok = g_key_file_load_from_data (file, data, strlen (data), 0, &error);
g_assert (!ok);
g_assert_error (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_UNKNOWN_ENCODING);
g_clear_error (&error);
g_key_file_free (file);
g_test_message ("Testing invalid encoding %s", invalid_encoding_names[i]);
file = g_key_file_new ();
data = g_strdup_printf ("[group]\n"
"Encoding=%s\n", invalid_encoding_names[i]);
ok = g_key_file_load_from_data (file, data, strlen (data), 0, &error);
g_assert_false (ok);
g_assert_error (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_UNKNOWN_ENCODING);
g_clear_error (&error);
g_key_file_free (file);
}
}
static void