From 6cac8cca18c75986df3b85aa150173eb7e8e6223 Mon Sep 17 00:00:00 2001 From: Jesse van den Kieboom Date: Wed, 29 Mar 2006 15:42:41 +0000 Subject: [PATCH] Convert option files to xml format --- gnoemoe/gm-app.c | 7 +- gnoemoe/gm-color-table.c | 1 + gnoemoe/gm-options.c | 176 +++++++++++++++++++++++++++++++-------- gnoemoe/gm-options.h | 2 + gnoemoe/gm-triggers.c | 2 +- gnoemoe/gm-world.c | 19 ++++- 6 files changed, 166 insertions(+), 41 deletions(-) diff --git a/gnoemoe/gm-app.c b/gnoemoe/gm-app.c index 4ca3e36..fbfb77b 100644 --- a/gnoemoe/gm-app.c +++ b/gnoemoe/gm-app.c @@ -393,7 +393,7 @@ gm_app_initialize(GmApp *app) { app->priv->worlds_path = g_strconcat(app->priv->path, G_DIR_SEPARATOR_S, "worlds", NULL); app->priv->options_path = g_strconcat(app->priv->path, G_DIR_SEPARATOR_S, - "settings", NULL); + "settings.xml", NULL); if (!g_file_test(app->priv->path, G_FILE_TEST_EXISTS)) { mkdir(app->priv->path, 0755); @@ -405,6 +405,7 @@ gm_app_initialize(GmApp *app) { #endif gm_app_create_settings(app); + _gm_options_check_old_options(app->priv->options_path); gm_options_load(app->priv->options, app->priv->options_path); // Load color table @@ -416,6 +417,10 @@ gm_app_initialize(GmApp *app) { gm_app_convert_old_color_configuration(app, colors_path); } + g_free(colors_path); + + colors_path = g_strconcat(app->priv->path, G_DIR_SEPARATOR_S, "colors.xml", + NULL); app->priv->color_table = gm_color_table_new_from_options(colors_path); g_free(colors_path); } diff --git a/gnoemoe/gm-color-table.c b/gnoemoe/gm-color-table.c index dbb8b80..dc67a30 100644 --- a/gnoemoe/gm-color-table.c +++ b/gnoemoe/gm-color-table.c @@ -369,6 +369,7 @@ gm_color_table_new_from_options(gchar *filename) { table->priv->options = gm_options_new(); gm_options_set(table->priv->options, "color_scheme", "default"); + _gm_options_check_old_options(filename); gm_options_load(table->priv->options, filename); gm_color_table_fill_from_options(table); diff --git a/gnoemoe/gm-options.c b/gnoemoe/gm-options.c index 5f50ab3..f642c44 100644 --- a/gnoemoe/gm-options.c +++ b/gnoemoe/gm-options.c @@ -3,6 +3,8 @@ #include #include #include +#include +#include #include "gm-options.h" #include "gm-string.h" @@ -25,6 +27,9 @@ enum { NUM_SIGNALS }; +#define XML_ROOT_NAME "options" +#define XML_OPTION_NAME "option" + static guint options_signals[NUM_SIGNALS] = {0}; G_DEFINE_TYPE(GmOptions, gm_options, G_TYPE_OBJECT) @@ -67,6 +72,48 @@ gm_options_init(GmOptions *options) { options->priv->filepath = NULL; } +static void +gm_options_load_option(GmOptions *options, xmlDocPtr doc, xmlNodePtr ptr) { + xmlChar *key, *value; + + key = xmlGetProp(ptr, (const xmlChar *)"key"); + value = xmlGetProp(ptr, (const xmlChar *)"value"); + + if (key == NULL) { + gm_debug_msg(DEBUG_DEFAULT, + "GmOptions.load_option: key not present in option"); + } else if (value == NULL) { + gm_debug_msg(DEBUG_DEFAULT, + "GmOptions.load_option: value not present in option"); + } else { + gm_debug_msg(DEBUG_DEFAULT, + "GmOptions.load_option: adding option %s: %s", key, value); + gm_options_set(options, (gchar const *)key, (gchar const *)value); + } + + xmlFree(key); + xmlFree(value); +} + +static void +gm_options_save_option(gchar *key, gchar *value, xmlNodePtr root) { + xmlNodePtr option; + + gm_debug_msg(DEBUG_DEFAULT, "GmOptions.SaveValue: saving %s, %s", key, + value); + + option = xmlNewChild(root, NULL, (const xmlChar *)(XML_OPTION_NAME), NULL); + xmlNewProp(option, (const xmlChar *)("key"), (const xmlChar *)(key)); + xmlNewProp(option, (const xmlChar *)("value"), (const xmlChar *)(value)); +} + +static void +gm_options_dup_option(gchar *key, gchar *value, GmOptions *copy) { + gm_options_set(copy, key, value); +} + +/* Public functions */ + GmOptions * gm_options_new(void) { GmOptions *options = GM_OPTIONS(g_object_new(GM_TYPE_OPTIONS, NULL)); @@ -74,11 +121,6 @@ gm_options_new(void) { return options; } -void -gm_options_dup_option(gchar *key, gchar *value, GmOptions *copy) { - gm_options_set(copy, key, value); -} - GmOptions * gm_options_dup(GmOptions *source) { GmOptions *copy = gm_options_new(); @@ -138,36 +180,30 @@ gm_options_remove(GmOptions *options, gchar const *key) { g_hash_table_remove(options->priv->options, key); } -void -gm_options_save_value(gchar *key, gchar *value, FILE *f) { - gm_debug_msg(DEBUG_DEFAULT, "GmOptions.SaveValue: saving %s, %s", key, - value); - fprintf(f, "%s=%s\n", key, value); -} - void gm_options_save(GmOptions *options) { - FILE *f; + xmlDocPtr doc; + xmlNodePtr root; if (options->priv->filepath == NULL) { return; } - f = fopen(options->priv->filepath, "w"); - gm_debug_msg(DEBUG_DEFAULT, "GmOptions.save: saving options (%s)!", options->priv->filepath); - if (f) { - g_hash_table_foreach(options->priv->options, - (GHFunc)gm_options_save_value, f); + doc = xmlNewDoc((const xmlChar *)("1.0")); + root = xmlNewNode(NULL, (const xmlChar *)(XML_ROOT_NAME)); + xmlDocSetRootElement(doc, root); - fclose(f); - chmod(options->priv->filepath, 0660); - } else { - gm_debug_msg(DEBUG_DEFAULT, "GmOptions.save: couldn't open option " - "file for saving: %s", strerror(errno)); - } + g_hash_table_foreach(options->priv->options, + (GHFunc)gm_options_save_option, root); + + xmlSaveFormatFileEnc(options->priv->filepath, doc, "UTF-8", 1); + xmlFreeDoc(doc); + + // Make sure to make this only readable for the user and the group + chmod(options->priv->filepath, 0660); } void @@ -179,14 +215,73 @@ gm_options_save_as(GmOptions *options, gchar const *filename) { } void -gm_options_load(GmOptions *options, const char *filename) { - FILE *f; - gchar **keyvalue, line[1024]; - int i; - +gm_options_load(GmOptions *options, gchar const *filename) { + xmlDocPtr doc; + xmlNodePtr root; + gm_debug_msg(DEBUG_DEFAULT, "GmOptions.load: loading options (%s)!", filename); + if (!g_file_test(filename, G_FILE_TEST_EXISTS)) { + gm_debug_msg(DEBUG_DEFAULT, "GmOptions.load: file does not exist"); + return; + } + + doc = xmlParseFile(filename); + + if (doc == NULL) { + gm_debug_msg(DEBUG_DEFAULT, + "GmOptions.load: error on parsing options file"); + return; + } + + root = xmlDocGetRootElement(doc); + + if (root == NULL) { + xmlFreeDoc(doc); + return; + } + + if (xmlStrcmp(root->name, (const xmlChar *)(XML_ROOT_NAME))) { + gm_debug_msg(DEBUG_DEFAULT, "GmOptions.load: invalid root node"); + xmlFreeDoc(doc); + return; + } + + for (root = root->xmlChildrenNode; root; root = root->next) { + if (!xmlStrcmp(root->name, (const xmlChar *)(XML_OPTION_NAME))) { + gm_options_load_option(options, doc, root); + } + } + + xmlFreeDoc(doc); + + g_free(options->priv->filepath); + options->priv->filepath = g_strdup(filename); +} + +void +_gm_options_check_old_options(gchar const *xmlname) { + gchar *filename; + xmlDocPtr doc; + xmlNodePtr root; + FILE *f; + gchar **keyvalue, line[1024]; + gint i; + + filename = g_strdup(xmlname); + filename[strlen(xmlname) - 4] = '\0'; + + if (g_file_test(xmlname, G_FILE_TEST_EXISTS) || + !g_file_test(filename, G_FILE_TEST_EXISTS)) { + g_free(filename); + return; + } + + doc = xmlNewDoc((const xmlChar *)("1.0")); + root = xmlNewNode(NULL, (const xmlChar *)(XML_ROOT_NAME)); + xmlDocSetRootElement(doc, root); + if ((f = fopen(filename, "r")) != NULL) { i = 0; while (fgets((char *) &line, 1024 - 1, f) != NULL) { @@ -200,9 +295,10 @@ gm_options_load(GmOptions *options, const char *filename) { if (strncmp(keyvalue[0], "#", 1) != 0) { // Commented lines, well ignore them too if (keyvalue[1] != NULL) { - gm_debug_msg(DEBUG_DEFAULT, "GmOptions.load: " - "adding %s, %s", keyvalue[0], keyvalue[1]); - gm_options_set(options, keyvalue[0], keyvalue[1]); + gm_debug_msg(DEBUG_DEFAULT, + "GmOptions.check_old_options: converting %s, %s", + keyvalue[0], keyvalue[1]); + gm_options_save_option(keyvalue[0], keyvalue[1], root); } else { gm_debug_msg(DEBUG_DEFAULT, "GmOptions.load: wrong " "syntax of options line in %s line %d", @@ -216,10 +312,18 @@ gm_options_load(GmOptions *options, const char *filename) { fclose(f); } else { - gm_debug_msg(DEBUG_DEFAULT, "GmOptions.load: could not retrieve " - "contents of file %s (%s)", filename, strerror(errno)); + gm_debug_msg(DEBUG_DEFAULT, "GmOptions.check_old_options: could not " + "retrieve contents of file %s (%s)", filename, strerror(errno)); } - g_free(options->priv->filepath); - options->priv->filepath = g_strdup(filename); + xmlSaveFormatFileEnc(xmlname, doc, "UTF-8", 1); + xmlFreeDoc(doc); + + if (g_file_test(xmlname, G_FILE_TEST_EXISTS)) { + // Make sure to make this only readable for the user and the group + chmod(xmlname, 0660); + unlink(filename); + } + + g_free(filename); } diff --git a/gnoemoe/gm-options.h b/gnoemoe/gm-options.h index 349d25d..cf36fb6 100644 --- a/gnoemoe/gm-options.h +++ b/gnoemoe/gm-options.h @@ -64,6 +64,8 @@ void gm_options_save(GmOptions *options); void gm_options_save_as(GmOptions *options, gchar const *filename); void gm_options_load(GmOptions *options, gchar const *filename); +void _gm_options_check_old_options(gchar const *filename); + G_END_DECLS #endif /* __GM_OPTIONS_H__ */ diff --git a/gnoemoe/gm-triggers.c b/gnoemoe/gm-triggers.c index 119c6dd..edf451f 100644 --- a/gnoemoe/gm-triggers.c +++ b/gnoemoe/gm-triggers.c @@ -475,8 +475,8 @@ gm_triggers_new_from_file(gchar *filename) { if (!g_file_test(filename, G_FILE_TEST_EXISTS)) { gm_debug_msg(DEBUG_DEFAULT, "GmTriggers.NewFromFile: Trigger file does not exist"); - return trg; + return trg; } doc = xmlParseFile(filename); diff --git a/gnoemoe/gm-world.c b/gnoemoe/gm-world.c index 5bd0953..d3482d4 100644 --- a/gnoemoe/gm-world.c +++ b/gnoemoe/gm-world.c @@ -441,12 +441,23 @@ gm_world_save_input_history(GmWorld *world) { void gm_world_load_triggers(GmWorld *world) { gchar *path; - + gchar *oldpath; + if (world->priv->triggers) { g_object_unref(world->priv->triggers); } - path = g_strconcat(world->priv->path, G_DIR_SEPARATOR_S, "triggers", NULL); + oldpath = g_strconcat(world->priv->path, G_DIR_SEPARATOR_S, "triggers", + NULL); + path = g_strconcat(world->priv->path, G_DIR_SEPARATOR_S, "triggers.xml", + NULL); + + if (g_file_test(oldpath, G_FILE_TEST_EXISTS) && + !g_file_test(path, G_FILE_TEST_EXISTS)) { + rename(oldpath, path); + } + + g_free(oldpath); world->priv->triggers = gm_triggers_new_from_file(path); g_free(path); } @@ -493,7 +504,7 @@ gm_world_new(gchar *path) { gchar *options_path; if (path != NULL) { - options_path = g_strconcat(path, "/settings", NULL); + options_path = g_strconcat(path, G_DIR_SEPARATOR_S, "settings.xml", NULL); gm_debug_msg(DEBUG_DEFAULT, "GmWorld.new: creating new world for %s", path); @@ -501,6 +512,8 @@ gm_world_new(gchar *path) { gm_debug_msg(DEBUG_DEFAULT, "GmWorld.new: creating default world " "settings for %s", path); + + _gm_options_check_old_options(options_path); gm_options_load(world->priv->options, options_path); if (strlen(gm_options_get(world->priv->options, "charset")) == 0) {