summaryrefslogtreecommitdiff
path: root/backends/markup-tree.c
diff options
context:
space:
mode:
authorMark McLoughlin <mark@skynet.ie>2004-06-22 11:43:47 +0000
committerMark McLoughlin <markmc@src.gnome.org>2004-06-22 11:43:47 +0000
commit2bb792de417e79185dcbd3d8f3255d64c2aeee18 (patch)
tree98184f7e556fe3a68e3ef28bf288a0870f49f5fd /backends/markup-tree.c
parent28d07e279a98eb0e2bae93fe3fe732344e539347 (diff)
downloadgconf-2bb792de417e79185dcbd3d8f3255d64c2aeee18.tar.gz
Fix for bug #138498 - turn on "subtree-in-a-file" for the subdirectories
2004-06-21 Mark McLoughlin <mark@skynet.ie> Fix for bug #138498 - turn on "subtree-in-a-file" for the subdirectories of the following directories: /apps/evolution", /apps/panel/profiles", /apps /desktop/gnome /system /schemas/apps /schemas/desktop/gnome /schemas/system /schemas / You can turn this of by passing the "nomerge" flag to the backend - e.g. xml:readwrite,nomerge:$(HOME)/.gconf * backends/markup-tree.[ch]: (markup_tree_get): pass in the nomerge path. (markup_dir_build_file_path), (markup_dir_build_dir_path): simple wrappers for build_path(). (load_subtree), (load_entries), (load_subdirs), (delete_useless_subdirs): upd. for above change. (recursively_load_subtree): impl. recursively loading the tree below a given dir. (should_save_as_subtree): logic to figure out which dirs should be saved as merged files. (markup_dir_sync): save the dir in a merged file if neccessary. (markup_dir_build_path): allow building a non-filesystem path. (parse_tree), (save_tree): upd. (write_dir): set the "not_in_filesystem" flag. * backends/markup-backend.c: (resolve_address), (ms_new): parse and use the "nomerge" flag. * backends/gconf-merge-tree.c: (merge_tree): upd.
Diffstat (limited to 'backends/markup-tree.c')
-rw-r--r--backends/markup-tree.c153
1 files changed, 139 insertions, 14 deletions
diff --git a/backends/markup-tree.c b/backends/markup-tree.c
index 7527f00c..3f1b3aeb 100644
--- a/backends/markup-tree.c
+++ b/backends/markup-tree.c
@@ -63,8 +63,9 @@ static void markup_dir_free (MarkupDir *dir);
static gboolean markup_dir_needs_sync (MarkupDir *dir);
static gboolean markup_dir_sync (MarkupDir *dir);
static char* markup_dir_build_path (MarkupDir *dir,
- gboolean with_data_file,
- gboolean subtree_data_file);
+ gboolean filesystem_path,
+ gboolean with_data_file,
+ gboolean subtree_data_file);
static void markup_dir_set_entries_need_save (MarkupDir *dir);
static MarkupEntry* markup_entry_new (MarkupDir *dir,
@@ -89,14 +90,34 @@ struct _MarkupTree
MarkupDir *root;
guint refcount;
+
+ guint try_merge : 1;
};
static GHashTable *trees_by_root_dir = NULL;
+/* List of dirs whose subdirs should be saved as a
+ * subtree-in-a-file. The order is important.
+ */
+static const char *save_as_subtree_dirs[] =
+{
+ "/apps/evolution",
+ "/apps/panel/profiles",
+ "/apps",
+ "/desktop/gnome",
+ "/system"
+ "/schemas/apps",
+ "/schemas/desktop/gnome",
+ "/schemas/system",
+ "/schemas",
+ "/"
+};
+
MarkupTree*
markup_tree_get (const char *root_dir,
guint dir_mode,
- guint file_mode)
+ guint file_mode,
+ gboolean try_merge)
{
MarkupTree *tree = NULL;
@@ -116,6 +137,7 @@ markup_tree_get (const char *root_dir,
tree->dirname = g_strdup (root_dir);
tree->dir_mode = dir_mode;
tree->file_mode = file_mode;
+ tree->try_merge = try_merge != FALSE;
tree->root = markup_dir_new (tree, NULL, "/");
@@ -258,6 +280,20 @@ markup_dir_queue_sync (MarkupDir *dir)
}
}
+static inline char *
+markup_dir_build_file_path (MarkupDir *dir,
+ gboolean subtree_data_file)
+{
+ return markup_dir_build_path (dir, TRUE, TRUE, subtree_data_file);
+}
+
+static inline char *
+markup_dir_build_dir_path (MarkupDir *dir,
+ gboolean filesystem_path)
+{
+ return markup_dir_build_path (dir, filesystem_path, FALSE, FALSE);
+}
+
static MarkupDir*
markup_tree_get_dir_internal (MarkupTree *tree,
const char *full_key,
@@ -361,7 +397,7 @@ load_subtree (MarkupDir *dir)
GError *tmp_err = NULL;
char *markup_file;
- markup_file = markup_dir_build_path (dir, TRUE, TRUE);
+ markup_file = markup_dir_build_file_path (dir, TRUE);
if (!gconf_file_exists (markup_file))
{
g_free (markup_file);
@@ -427,7 +463,7 @@ load_entries (MarkupDir *dir)
/* this message is debug-only because it usually happens
* when creating a new directory
*/
- markup_file = markup_dir_build_path (dir, TRUE, FALSE);
+ markup_file = markup_dir_build_file_path (dir, FALSE);
gconf_log (GCL_DEBUG,
"Failed to load file \"%s\": %s",
markup_file, tmp_err->message);
@@ -467,7 +503,7 @@ load_subdirs (MarkupDir *dir)
if (load_subtree (dir))
return TRUE;
- markup_dir = markup_dir_build_path (dir, FALSE, FALSE);
+ markup_dir = markup_dir_build_dir_path (dir, TRUE);
dp = opendir (markup_dir);
@@ -786,8 +822,8 @@ delete_useless_subdirs (MarkupDir *dir)
char *fs_dirname;
char *fs_filename;
- fs_dirname = markup_dir_build_path (subdir, FALSE, FALSE);
- fs_filename = markup_dir_build_path (subdir, TRUE, dir->save_as_subtree);
+ fs_dirname = markup_dir_build_dir_path (subdir, TRUE);
+ fs_filename = markup_dir_build_file_path (subdir, dir->save_as_subtree);
if (unlink (fs_filename) < 0)
{
@@ -887,6 +923,80 @@ delete_useless_entries (MarkupDir *dir)
return some_deleted;
}
+static void
+recursively_load_subtree (MarkupDir *dir)
+{
+ GSList *tmp;
+
+ load_entries (dir);
+ load_subdirs (dir);
+
+ tmp = dir->subdirs;
+ while (tmp != NULL)
+ {
+ MarkupDir *subdir = tmp->data;
+
+ recursively_load_subtree (subdir);
+
+ tmp = tmp->next;
+ }
+}
+
+static gboolean
+should_save_as_subtree (MarkupDir *dir)
+{
+ gboolean save_as_subtree = FALSE;
+ char *dir_path;
+ char *parent_path;
+ int pathlen;
+ int i;
+
+ if (!dir->tree->try_merge)
+ return FALSE;
+
+ /* never merge root */
+ if (!dir->parent)
+ return FALSE;
+
+ dir_path = markup_dir_build_dir_path (dir, FALSE);
+ pathlen = strlen (dir_path);
+
+ parent_path = markup_dir_build_dir_path (dir->parent, FALSE);
+
+ i = 0;
+ while (i < G_N_ELEMENTS (save_as_subtree_dirs))
+ {
+ const char *match = save_as_subtree_dirs [i];
+
+ /* 2 rules:
+ * 1) If @match is an ancestor of this dir, don't
+ * consider merging this dir
+ * 2) If @match is this dir's parent, then merge
+ * this dir
+ *
+ * (1) is so that we don't e.g., with "/apps" and
+ * "/apps/panel/profiles", merge /apps/panel when
+ * we really want to merge /apps/panel/profiles/default
+ */
+
+ if (strncmp (match, dir_path, pathlen) == 0)
+ break;
+
+ if (strcmp (match, parent_path) == 0)
+ {
+ save_as_subtree = TRUE;
+ break;
+ }
+
+ ++i;
+ }
+
+ g_free (dir_path);
+ g_free (parent_path);
+
+ return save_as_subtree;
+}
+
static gboolean
markup_dir_sync (MarkupDir *dir)
{
@@ -918,10 +1028,16 @@ markup_dir_sync (MarkupDir *dir)
tmp = tmp->next;
}
+
+ if (!dir->save_as_subtree && should_save_as_subtree (dir))
+ {
+ dir->save_as_subtree = TRUE;
+ recursively_load_subtree (dir);
+ }
- fs_dirname = markup_dir_build_path (dir, FALSE, FALSE);
- fs_filename = markup_dir_build_path (dir, TRUE, FALSE);
- fs_subtree = markup_dir_build_path (dir, TRUE, TRUE);
+ fs_dirname = markup_dir_build_dir_path (dir, TRUE);
+ fs_filename = markup_dir_build_file_path (dir, FALSE);
+ fs_subtree = markup_dir_build_file_path (dir, TRUE);
/* For a dir to be loaded as a subdir, it must have a
* %gconf.xml file, even if it has no entries in that
@@ -1051,6 +1167,7 @@ markup_dir_sync (MarkupDir *dir)
static char*
markup_dir_build_path (MarkupDir *dir,
+ gboolean filesystem_path,
gboolean with_data_file,
gboolean subtree_data_file)
{
@@ -1059,6 +1176,8 @@ markup_dir_build_path (MarkupDir *dir,
GSList *tmp;
MarkupDir *iter;
+ g_assert (filesystem_path || !with_data_file);
+
components = NULL;
iter = dir;
while (iter->parent != NULL) /* exclude root dir */
@@ -1067,7 +1186,11 @@ markup_dir_build_path (MarkupDir *dir,
iter = iter->parent;
}
- name = g_string_new (dir->tree->dirname);
+ if (filesystem_path)
+ name = g_string_new (dir->tree->dirname);
+ else
+ name = g_string_new (components ? NULL : "/");
+
tmp = components;
while (tmp != NULL)
{
@@ -3072,7 +3195,7 @@ parse_tree (MarkupDir *root,
char *text;
gsize length;
- filename = markup_dir_build_path (root, TRUE, parse_subtree);
+ filename = markup_dir_build_file_path (root, parse_subtree);
parse_info_init (&info, root, parse_subtree);
@@ -3570,6 +3693,8 @@ write_dir (MarkupDir *dir,
gboolean retval = FALSE;
char *whitespace;
+ dir->not_in_filesystem = TRUE;
+
/* This dir will be deleted from the
* MarkupTree after syncing anyway ...
*/
@@ -3639,7 +3764,7 @@ save_tree (MarkupDir *dir,
new_fd = -1;
f = NULL;
- filename = markup_dir_build_path (dir, TRUE, save_as_subtree);
+ filename = markup_dir_build_file_path (dir, save_as_subtree);
new_filename = g_strconcat (filename, ".new", NULL);
new_fd = open (new_filename, O_WRONLY | O_CREAT, file_mode);