--- gnumeric-gconf.c.orig 2005-07-12 08:38:41.000000000 -0400 +++ gnumeric-gconf.c 2005-07-12 17:15:55.000000000 -0400 @@ -1061,88 +1061,465 @@ #else +#include + +typedef enum { + RC_TYPE_BOOLEAN = 1, + RC_TYPE_INT, + RC_TYPE_DOUBLE, + RC_TYPE_STRING, + RC_TYPE_UNKNOWN +} RCType; + +struct _GOConfNode { + gchar *key; + gchar *value; + RCType type; +}; + +static GOConfNode **rc_nodes; +static int n_rc_nodes; + +static int get_rc_filename (char *rcfile) +{ + char *home = getenv("HOME"); + int err = 0; + + if (home == NULL) { + *rcfile = '\0'; + err = 1; + } else { + sprintf(rcfile, "%s/.gnumericrc", home); + } + + return err; +} + +static GOConfNode *add_rc_conf_node (const char *key, const char *value, RCType type) +{ + GOConfNode **nodes = NULL; + GOConfNode *node = NULL; + int slot = -1; + int i, err = 0; + + /* reuse a blank slot? */ + for (i=0; ikey = g_strdup (key); + if (value != NULL) { + node->value = g_strdup (value); + } else { + node->value = NULL; + } + node->type = type; + rc_nodes[slot] = node; + } + + return node; +} + +static GOConfNode *get_node_from_key (const char *key) +{ + GOConfNode *ret = NULL; + int i; + + for (i=0; ikey, key)) { + ret = rc_nodes[i]; + break; + } + } + +#if 0 + fprintf(stderr, "get_node_from_key: key='%s', %s\n", key, + (ret)? "matched" : "no match"); +#endif + + return ret; +} + +static int node_number_in_list (GOConfNode *node) +{ + int i, ret = -1; + + for (i=0; i maxlen) { + maxlen = len; + } + len = 0; + } + } + + return maxlen + 1; +} + +static int make_nodes_from_rcfile (FILE *fp) +{ + char *line, *value; + char key[128], test[8]; + int type, len; + int err = 0; + + len = max_line_length(fp) + 1; + rewind(fp); + + line = g_malloc (len); + if (line == NULL) { + err = 1; + } else { + while (fgets(line, len, fp)) { + line[strlen(line) - 1] = '\0'; + if (sscanf(line, "%d %127s = %7s", &type, key, test) == 3) { + value = strchr(line, '=') + 2; + add_rc_conf_node (key, value, type); + } + } + g_free (line); + } + + return err; +} + +static void maybe_dump_node (GOConfNode *node, FILE *fp) +{ + if (node->value != NULL && node->value[0]) { + fprintf(fp, "%d %s = %s\n", (int) node->type, node->key, node->value); + } +} + +static int dump_rc_nodes_to_file (void) +{ + char rcfile[FILENAME_MAX]; + FILE *fp = NULL; + int i, err = 0; + + err = get_rc_filename (rcfile); + + if (!err) { + fp = fopen (rcfile, "w"); + if (fp == NULL) { + err = 1; + } + } + + if (!err) { + for (i=0; ikey != NULL) { + maybe_dump_node(rc_nodes[i], fp); + } + } + } + + if (fp != NULL) { + fclose(fp); + } + + return 1; +} + +static GOConfNode *get_real_node (GOConfNode *parent, gchar const *key) +{ + GOConfNode *node = NULL; + gchar *path; + + if (parent != NULL && parent->key != NULL) { + path = g_strdup_printf ("%s/%s", parent->key, key); + } else { + path = g_strdup(key); + } + + node = get_node_from_key (path); + g_free (path); + return node; +} + +static GOConfNode *modify_or_add_node (GOConfNode *parent, + gchar const *key, + gchar const *value, + RCType type) +{ + GOConfNode *node = NULL; + gchar *path; + + if (parent != NULL && parent->key != NULL) { + path = g_strdup_printf ("%s/%s", parent->key, key); + } else { + path = g_strdup(key); + } + + node = get_node_from_key (path); + + if (node == NULL) { + add_rc_conf_node(path, value, type); + } else { + g_free (node->value); + node->value = g_strdup (value); + } + + g_free (path); + return node; +} + static void go_conf_init (void) { + char rcfile[FILENAME_MAX]; + FILE *fp; + int err; + + err = get_rc_filename (rcfile); + if (!err) { + fp = fopen (rcfile, "r"); + if (fp != NULL) { + make_nodes_from_rcfile (fp); + fclose (fp); + } + } } static void go_conf_shutdown (void) { + int i; + + dump_rc_nodes_to_file(); + + for (i=0; ikey != NULL) { + path = g_strdup_printf ("%s/%s", parent->key, key); + } else { + path = g_strdup(key); + } + + node = add_rc_conf_node (path, NULL, RC_TYPE_UNKNOWN); + g_free (path); + return node; } void go_conf_free_node (GOConfNode *node) { + if (node != NULL) { + int nn = node_number_in_list (node); + + g_free (node->key); + g_free (node->value); + g_free (node); + if (nn >= 0) { + rc_nodes[nn] = NULL; + } + } } void go_conf_set_bool (GOConfNode *node, gchar const *key, gboolean val) { + gchar *valstr = g_strdup_printf ("%d", (int) val); + + modify_or_add_node (node, key, valstr, RC_TYPE_BOOLEAN); + g_free (valstr); } void go_conf_set_int (GOConfNode *node, gchar const *key, gint val) { + gchar *valstr = g_strdup_printf ("%d", (int) val); + + modify_or_add_node (node, key, valstr, RC_TYPE_INT); + g_free (valstr); } void go_conf_set_double (GOConfNode *node, gchar const *key, gnm_float val) { + gchar *valstr = g_strdup_printf ("%g", (double) val); + + modify_or_add_node (node, key, valstr, RC_TYPE_DOUBLE); + g_free (valstr); } void go_conf_set_string (GOConfNode *node, gchar const *key, char const *str) { + modify_or_add_node (node, key, str, RC_TYPE_STRING); } void go_conf_set_str_list (GOConfNode *node, gchar const *key, GSList *list) { + if (list != NULL) { + GString *str_list = g_string_new (""); + + while (list) { + const gchar *str = list->data; + + if (*str) { + g_string_append (str_list, g_strescape (str, NULL)); + g_string_append_c (str_list, ';'); + } + list = list->next; + } + + modify_or_add_node (node, key, str_list->str, RC_TYPE_STRING); + g_string_free (str_list, TRUE); + } } gboolean go_conf_get_bool (GOConfNode *node, gchar const *key) { - return FALSE; + GOConfNode *rcnode; + gboolean val = FALSE; + + rcnode = get_real_node (node, key); + if (rcnode != NULL && rcnode->value != NULL) { + val = atoi (rcnode->value); + } + + return val; } gint go_conf_get_int (GOConfNode *node, gchar const *key) { - return 0; + GOConfNode *rcnode; + gint val = 0; + + rcnode = get_real_node (node, key); + if (rcnode != NULL && rcnode->value != NULL) { + val = atoi (rcnode->value); + } + + return val; } gdouble go_conf_get_double (GOConfNode *node, gchar const *key) { - return 0.; + GOConfNode *rcnode; + gdouble val = 0.0; + + rcnode = get_real_node (node, key); + if (rcnode != NULL && rcnode->value != NULL) { + val = atof (rcnode->value); + } + + return val; } gchar * go_conf_get_string (GOConfNode *node, gchar const *key) { - return g_strdup (""); + GOConfNode *rcnode; + gchar *val = NULL; + + rcnode = get_real_node (node, key); + if (rcnode != NULL && rcnode->value != NULL) { + val = g_strdup (node->value); + } else { + val = g_strdup (""); + } + + return val; } GSList * go_conf_get_str_list (GOConfNode *node, gchar const *key) { - return NULL; + GOConfNode *rcnode; + GSList *list = NULL; + gchar *ptr; + gchar **str_list; + gint i; + + rcnode = get_real_node (node, key); + if (rcnode != NULL && (ptr = rcnode->value) != NULL) { + str_list = g_strsplit ((const gchar *) ptr, ";", 0); + for (i = 0; str_list[i]; ++i) { + if (str_list[i][0]) { + /* was 'prepend' here: broke recent file list */ + list = g_slist_append (list, g_strcompress (str_list[i])); + } + } + /* g_slist_reverse (list); */ + g_strfreev (str_list); + } + + return list; } gboolean go_conf_load_bool (GOConfNode *node, gchar const *key, gboolean default_val) { - return default_val; + GOConfNode *rcnode; + gboolean val = default_val; + + rcnode = get_real_node (node, key); + if (rcnode != NULL && rcnode->value != NULL) { + val = atoi (rcnode->value); + } + + return val; } + int go_conf_load_int (GOConfNode *node, gchar const *key, gint minima, gint maxima, @@ -1148,7 +1525,18 @@ gint minima, gint maxima, gint default_val) { - return default_val; + GOConfNode *rcnode; + int val = default_val; + + rcnode = get_real_node (node, key); + if (rcnode != NULL && rcnode->value != NULL) { + val = atoi (rcnode->value); + if (val < minima || val > maxima) { + val = default_val; + } + } + + return val; } double @@ -1156,8 +1544,20 @@ gdouble minima, gdouble maxima, gdouble default_val) { - return default_val; + GOConfNode *rcnode; + double val = default_val; + + rcnode = get_real_node (node, key); + if (rcnode != NULL && rcnode->value != NULL) { + val = atof (rcnode->value); + if (val < minima || val > maxima) { + val = default_val; + } + } + + return val; } + char * go_conf_load_string (GOConfNode *node, gchar const *key) { @@ -1161,8 +1561,17 @@ char * go_conf_load_string (GOConfNode *node, gchar const *key) { - return NULL; + GOConfNode *rcnode; + char *val = NULL; + + rcnode = get_real_node (node, key); + if (rcnode != NULL && rcnode->value != NULL) { + val = g_strdup(rcnode->value); + } + + return val; } + GSList * go_conf_load_str_list (GOConfNode *node, gchar const *key) { @@ -1166,8 +1575,9 @@ GSList * go_conf_load_str_list (GOConfNode *node, gchar const *key) { - return NULL; + return go_conf_get_str_list (node, key); } + char * go_conf_get_short_desc (GOConfNode *node, gchar const *key) { @@ -1183,19 +1593,64 @@ GType go_conf_get_type (GOConfNode *node, gchar const *key) { - return G_TYPE_NONE; + GOConfNode *rcnode; + GType type = G_TYPE_NONE; + + rcnode = get_real_node (node, key); + if (rcnode != NULL) { + switch (rcnode->type) { + case RC_TYPE_BOOLEAN: + type = G_TYPE_BOOLEAN; + break; + case RC_TYPE_INT: + type = G_TYPE_INT; + break; + case RC_TYPE_DOUBLE: + type = G_TYPE_DOUBLE; + break; + case RC_TYPE_STRING: + type = G_TYPE_STRING; + break; + default: + break; + } + } + + return type; } gchar * go_conf_get_value_as_str (GOConfNode *node, gchar const *key) { - return g_strdup (""); + GOConfNode *rcnode; + gchar *val = NULL; + + rcnode = get_real_node (node, key); + if (rcnode != NULL && rcnode->value != NULL) { + val = g_strdup (rcnode->value); + } else { + val = g_strdup (""); + } + + return val; } gboolean go_conf_set_value_from_str (GOConfNode *node, gchar const *key, gchar const *val_str) { - return TRUE; + GOConfNode *rcnode; + gboolean ret = FALSE; + + rcnode = get_real_node (node, key); + if (rcnode == NULL) { + add_rc_conf_node (key, val_str, RC_TYPE_UNKNOWN); + } else { + g_free (rcnode->value); + rcnode->value = g_strdup (val_str); + ret = TRUE; + } + + return ret; } void