+2007-03-22 Chris Wilson <chris@chris-wilson.co.uk>
+
+ * glib/gkeyfile.c: Track whether the last key=value pair in a group
+ is a blank line and during to_data() only insert a new blank line
+ betweens group in its absence. This allows the beautification of the
+ GKeyFile and prevents newlines being inserted indefinitely. (#420686)
+
+ * tests/keyfile-test.c (test_reload_idempotency): Test that after a
+ single beautification pass, g_key_file_to_data() does not alter its
+ input data.
+
2007-03-21 Matthias Clasen <mclasen@redhat.com>
* glib/pcre/Makefile.am: Make builddir != srcdir work. (#419900)
const gchar *name; /* NULL for above first group (which will be comments) */
GKeyFileKeyValuePair *comment; /* Special comment that is stuck to the top of a group */
+ gboolean has_trailing_blank_line;
GList *key_value_pairs;
key_file->current_group->key_value_pairs =
g_list_prepend (key_file->current_group->key_value_pairs, pair);
+
+ if (length == 0 || line[0] != '#')
+ key_file->current_group->has_trailing_blank_line = TRUE;
}
static void
{
GString *data_string;
GList *group_node, *key_file_node;
+ gboolean has_blank_line = TRUE;
g_return_val_if_fail (key_file != NULL, NULL);
group = (GKeyFileGroup *) group_node->data;
+ /* separate groups by at least an empty line */
+ if (!has_blank_line)
+ g_string_append_c (data_string, '\n');
+ has_blank_line = group->has_trailing_blank_line;
+
if (group->comment != NULL)
g_string_append_printf (data_string, "%s\n", group->comment->value);
- else if (group_node->next) /* separate groups by at least an empty line */
- g_string_append_c (data_string, '\n');
if (group->name != NULL)
g_string_append_printf (data_string, "[%s]\n", group->name);
g_hash_table_replace (group->lookup_map, pair->key, pair);
group->key_value_pairs = g_list_prepend (group->key_value_pairs, pair);
+ group->has_trailing_blank_line = FALSE;
key_file->approximate_size += strlen (key) + strlen (value) + 2;
}
g_key_file_free (keyfile);
}
+
+/* http://bugzilla.gnome.org/show_bug.cgi?id=420686 */
+static void
+test_reload_idempotency (void)
+{
+ static const gchar *original_data=""
+ "# Top comment\n"
+ "\n"
+ "# First comment\n"
+ "[first]\n"
+ "key=value\n"
+ "# A random comment in the first group\n"
+ "anotherkey=anothervalue\n"
+ "# Second comment - one line\n"
+ "[second]\n"
+ "# Third comment - two lines\n"
+ "# Third comment - two lines\n"
+ "[third]\n"
+ "blank_line=1\n"
+ "\n"
+ "blank_lines=2\n"
+ "\n\n"
+ "[fourth]\n"
+ "[fifth]\n";
+ GKeyFile *keyfile;
+ GError *error = NULL;
+ gchar *data1, *data2;
+ gsize len1, len2;
+
+ /* check that we only insert a single new line between groups */
+ keyfile = g_key_file_new ();
+ if (!g_key_file_load_from_data (keyfile,
+ original_data, strlen(original_data),
+ G_KEY_FILE_KEEP_COMMENTS,
+ &error)) {
+ g_print ("Failed to parse keyfile[1]: %s", error->message);
+ g_error_free (error);
+ exit (1);
+ }
+
+ data1 = g_key_file_to_data (keyfile, &len1, &error);
+ if (data1 == NULL) {
+ g_print ("Failed to extract keyfile[1]: %s", error->message);
+ g_error_free (error);
+ exit (1);
+ }
+ g_key_file_free (keyfile);
+
+ keyfile = g_key_file_new ();
+ if (!g_key_file_load_from_data (keyfile,
+ data1, len1,
+ G_KEY_FILE_KEEP_COMMENTS,
+ &error)) {
+ g_print ("Failed to parse keyfile[2]: %s", error->message);
+ g_error_free (error);
+ exit (1);
+ }
+
+ data2 = g_key_file_to_data (keyfile, &len2, &error);
+ if (data2 == NULL) {
+ g_print ("Failed to extract keyfile[2]: %s", error->message);
+ g_error_free (error);
+ exit (1);
+ }
+ g_key_file_free (keyfile);
+
+
+ if (strcmp(data1, data2) != 0) {
+ g_print ("Reloading GKeyFile is not idempotent.");
+ g_print ("original:\n%s\n---\n", original_data);
+ g_print ("pass1:\n%s\n---\n", data1);
+ g_print ("pass2:\n%s\n---\n", data2);
+ exit (1);
+ }
+
+ g_free (data2);
+ g_free (data1);
+}
+
+
static void
log_func (const gchar *log_domain,
GLogLevelFlags log_level,
test_duplicate_groups2 ();
test_group_names ();
test_key_names ();
+ test_reload_idempotency ();
return 0;
}