use xml for modules.conf ?



Hi,

Over the week end, I was thinking that it would be nice to be able to
provide more info about the methods known to gnome-vfs (for example,
some description of what the method do, or if it's a method to access to
some network location, or things like that), but when I looked at the
configuration file loading, that didn't seem really easy to extend, so I
wrote a quick xml parser (with libxml) which can load files looking like
the attached default-modules.conf.xml. This parser (and the associated
file format) is much easier to extend if necessary.

Does it sound like a useful thing which should be in gnome-vfs ? Or
should it be done differently ?

Christophe




Index: libgnomevfs/gnome-vfs-configuration.c
===================================================================
RCS file: /cvs/gnome/gnome-vfs/libgnomevfs/gnome-vfs-configuration.c,v
retrieving revision 1.21
diff -u -d -b -r1.21 gnome-vfs-configuration.c
--- libgnomevfs/gnome-vfs-configuration.c	19 Dec 2002 17:57:19 -0000	1.21
+++ libgnomevfs/gnome-vfs-configuration.c	2 Feb 2003 21:55:44 -0000
@@ -33,6 +33,8 @@
 #include <glib/gstrfuncs.h>
 #include <glib/gthread.h>
 #include <glib/gutils.h>
+#include <libxml/xmlmemory.h>
+#include <libxml/parser.h>
 #include "gnome-vfs-i18n.h"
 #include "gnome-vfs-private.h"
 #include <sys/stat.h>
@@ -115,9 +117,7 @@
 
 
 static void
-hash_free_module_path (gpointer key,
-		       gpointer value,
-		       gpointer user_data)
+hash_free_module_path (gpointer value)
 {
 	ModulePathElement *module_path;
 
@@ -131,8 +131,6 @@
 {
 	g_return_if_fail (configuration != NULL);
 
-	g_hash_table_foreach (configuration->method_to_module_path,
-			      hash_free_module_path, NULL);
 	g_hash_table_destroy (configuration->method_to_module_path);
 	g_list_foreach (configuration->directories, (GFunc) vfs_dir_source_free, NULL);
 	g_list_free (configuration->directories);
@@ -340,13 +338,99 @@
 		line_number += lines_read;
 	}
 
-	g_free (line_buffer);
+	return TRUE;
+}
 
-	fclose (f);
+static gboolean 
+parse_method (xmlDocPtr doc, xmlNodePtr cur)
+{
+	xmlChar *key;
+	GList *method_list = NULL;
+	GList *it = NULL;
+	gchar *module_name = NULL;
+	ModulePathElement *element;
+	
+	cur = cur->xmlChildrenNode;
+	while (cur != NULL) {
+		if ((!xmlStrcmp (cur->name, (const xmlChar *)"method_name"))) {
+			key = xmlNodeListGetString (doc, cur->xmlChildrenNode, 1);
+			method_list = g_list_append (method_list, key);
+		}
+
+		if ((!xmlStrcmp (cur->name, (const xmlChar *)"module_name"))) {
+			if (module_name != NULL) {
+				g_warning ("Module name already defined");
+				/* Free everything */
+				g_free (module_name);
+			}
+			module_name = xmlNodeListGetString (doc, cur->xmlChildrenNode, 1);
+		}
+
+		cur = cur->next;
+	}
+
+	if (module_name == NULL) {
+		g_list_foreach (method_list, (GFunc)g_free, NULL);
+		g_list_free (method_list);
+		return FALSE;
+	}
+	
+	for (it = method_list; it != NULL; it = it->next) {
+		gchar *method_name = it->data;
+		//element = module_path_element_new (method_name, module_name, args);
+		element = module_path_element_new (method_name, module_name, g_strdup(""));
+		printf ("%s: %s\n", method_name, module_name);
+		g_hash_table_insert (configuration->method_to_module_path,
+				     method_name, element);
+	}
+	g_list_free (method_list);
+	g_free (module_name);
+	return TRUE;
+}
+
+
+static gboolean
+parse_xml_file (Configuration *configuration,
+		const gchar *file_name)
+{
+	xmlDocPtr doc;
+	xmlNodePtr cur;
+	
+	doc = xmlParseFile (file_name);
+	
+	if (doc == NULL ) {
+		fprintf (stderr,"Document not parsed successfully. \n");
+		return FALSE;
+	}
+	
+	cur = xmlDocGetRootElement (doc);
+	 
+	if (cur == NULL) {
+		fprintf (stderr,"empty document\n");
+		xmlFreeDoc (doc);
+		return FALSE;
+	}
+	 
+	if (xmlStrcmp (cur->name, (const xmlChar *) "methods")) {
+		fprintf (stderr,"document of the wrong type, root node != story");
+		xmlFreeDoc (doc);
+		return FALSE;
+	}
+
+	cur = cur->xmlChildrenNode;
+	while (cur != NULL) {
+		if ((!xmlStrcmp (cur->name, (const xmlChar *)"method"))){
+			parse_method (doc, cur);
+		}
+		 
+		cur = cur->next;
+	}
+	xmlFreeDoc (doc);
 
 	return TRUE;
 }
 
+
 static void
 configuration_load (void)
 {
@@ -355,7 +439,7 @@
 	int i = 0;
 	DIR *dirh;
 
-	configuration->method_to_module_path = g_hash_table_new (g_str_hash, g_str_equal);
+	configuration->method_to_module_path = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, hash_free_module_path);
 
 	/* Go through the list of configuration directories and build up a list of config files */
 	for (list = configuration->directories; list && i < MAX_CFG_FILES; list = list->next) {
@@ -371,8 +455,10 @@
 
 		while ((dent = readdir(dirh)) && i < MAX_CFG_FILES) {
 			char *ctmp;
+			char *ctmp2;
 			ctmp = strstr(dent->d_name, ".conf");
-			if(!ctmp || strcmp(ctmp, ".conf"))
+			ctmp2 =  strstr(dent->d_name, ".conf.xml");
+			if( (!ctmp && !ctmp2) || (strcmp(ctmp, ".conf") && strcmp(ctmp2, ".conf.xml")))
 				continue;
 			file_names[i] = g_strdup_printf ("%s/%s", dir_source->dirname, dent->d_name);
 			i++;
@@ -384,7 +470,13 @@
 	/* Now read these cfg files */
 	for(i = 0; file_names[i]; i++) {
 		/* FIXME: should we try to catch errors? */
+		if (strstr (file_names[i], ".xml")) {
+			printf ("Parsing xml file: %s\n", file_names[i]);
+			parse_xml_file (configuration, file_names[i]);
+		} else {
+			printf ("Parsing non xml file: %s\n", file_names[i]);
 		parse_file (configuration, file_names[i]);
+		}
 		g_free (file_names[i]);
 	}
 }
@@ -526,8 +618,6 @@
 
 	configuration->last_checked = time (NULL);
 
-	g_hash_table_foreach (configuration->method_to_module_path,
-			      hash_free_module_path, NULL);
 	g_hash_table_destroy (configuration->method_to_module_path);
 	configuration_load ();
 }
<methods>
  <method>
    <method_name>bzip2</method_name>
    <module_name>bzip2</module_name>
  </method>

  <method>
    <method_name>cdda</method_name>
    <module_name>cdda</module_name>
  </method>

  <method>
    <method_name>file</method_name>
    <module_name>file</module_name>
  </method>

  <method>
    <method_name>test</method_name>
    <module_name>vfs-test</module_name>
  </method>

  <method>
    <method_name>ftp</method_name>
    <module_name>ftp</module_name>
  </method>

  <method>
    <method_name>nntp</method_name>
    <module_name>nntp</module_name>
  </method>

  <method>
    <method_name>gzip</method_name>
    <method_name>guzip</method_name>
    <module_name>gzip</module_name>
  </method>

  <method>
    <method_name>http</method_name>
    <module_name>http</module_name>
  </method>

  <method>
    <method_name>pipe</method_name>
    <module_name>vfs-pipe</module_name>
  </method>

  <method>
    <method_name>ssh</method_name>
    <module_name>ssh</module_name>
  </method>

  <method>
    <method_name>applications</method_name>
    <method_name>applications-all-users</method_name>
    <method_name>all-applications</method_name>
    <method_name>preferences</method_name>
    <method_name>preferences-all-users</method_name>
    <method_name>all-preferences</method_name>
    <method_name>favorites</method_name>
    <method_name>network</method_name>
    <method_name>start-here</method_name>
    <method_name>system-settings</method_name>
    <method_name>server-settings</method_name>
    <module_name>libvfolder-desktop.so</module_name>
  </method>

  <method>
    <method_name>tar</method_name>
    <module_name>tar</module_name>
  </method>

</methods>


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]