/** * erwin - really simple html editor * Copyright (C) 1999-2002 Adrian Reber * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: configuration.c,v 1.13 2004/06/21 21:45:19 erwin Exp $ * * $Author: erwin $ * * Descripiton: configuration parser and writer * * $Log: configuration.c,v $ * Revision 1.13 2004/06/21 21:45:19 erwin * big commit * it has been a long time without a checkout * we are close to version 0.7 * * Revision 1.12 2003/11/08 22:17:42 erwin * fix compiler warnings -Wall * * Revision 1.11 2003/10/30 20:54:06 erwin * syntax highlighting implementation * * Revision 1.10 2003/10/22 15:20:41 erwin * include file mess cleaned up * changed format to indent -kr -i8 -l100 * */ #ifndef lint static const char vcid[] = "$Id: configuration.c,v 1.13 2004/06/21 21:45:19 erwin Exp $"; #endif /* lint */ #include extern int _debug_; #ifdef ENABLE_DEBUG_OUTPUT #define _DEBUG_ if(_debug_) #else #define _DEBUG_ if(0) #endif #include #include xmlDocPtr doc = NULL; char *application = NULL; void free_if_empty(void *freeme) { if (freeme) free(freeme); freeme = NULL; } xmlNodePtr get_root_element(xmlNodePtr cur) { if (!doc) fprintf(stderr, "%s:%s:%d:giving up. I don't understand this anymore.\n", PACKAGE, __FILE__, __LINE__); cur = xmlDocGetRootElement(doc); if (cur == NULL) { _DEBUG_ fprintf(stderr, "%s:empty document\n", PACKAGE); xmlFreeDoc(doc); return NULL; } return cur; } char *construct_file_name() { char *home_dir = NULL; char *config_file = NULL; home_dir = getenv("HOME"); if (home_dir) { if (home_dir[strlen(home_dir) - 1] != '/') { config_file = (char *) malloc(strlen(home_dir) + strlen(application) + 5); strcpy(config_file, home_dir); strcat(config_file, "/."); strcat(config_file, application); } else { config_file = (char *) malloc(strlen(home_dir) + strlen(application) + 5); strcpy(config_file, home_dir); strcat(config_file, "."); strcat(config_file, application); } } else return NULL; return config_file; } void config_sync() { char *file; file = construct_file_name(); xmlSaveFormatFile(file, doc, 1); free(file); } void create_configuration() { doc = xmlNewDoc("1.0"); xmlDocSetRootElement(doc, xmlNewNode(NULL, application)); config_sync(); } void config_init(const char *app) { xmlNodePtr cur = NULL; char *file; free_if_empty(application); application = (char *) strdup(app); file = construct_file_name(); doc = xmlParseFile(file); free(file); if (!doc) { create_configuration(); } cur = get_root_element(cur); if (!cur) return; _DEBUG_ fprintf(stderr, "%s:top level node: %s\n", PACKAGE, cur->name); if (xmlStrcmp(cur->name, (const xmlChar *) "erwin")) { _DEBUG_ fprintf(stderr, "%s:not a valid configuration for %s\n", PACKAGE, app); } else { _DEBUG_ fprintf(stderr, "%s:found valid configuration\n", PACKAGE); } cur = cur->xmlChildrenNode; while (cur != NULL) { _DEBUG_ fprintf(stderr, "%s:name:%s\n", PACKAGE, cur->name); _DEBUG_ fprintf(stderr, "%s:get_string:%s\n", PACKAGE, xmlNodeListGetString(doc, cur->xmlChildrenNode, 1)); cur = cur->next; } } int config_get_int(const char *key, char **error) { int val; xmlNodePtr cur = NULL; *error = NULL; if (!doc) { *error = (char *) strdup("xmlDocPtr not initialized. did you call config_init()?"); fprintf(stderr, "%s\n", *error); return -1; } cur = get_root_element(cur); if (!cur) { *error = (char *) strdup("empty document"); return -1; } /* Let's go to the second level */ cur = cur->xmlChildrenNode; val = -1; while (cur != NULL) { if (!xmlStrcmp(cur->name, (const xmlChar *) key)) { val = atoi(xmlNodeListGetString(doc, cur->xmlChildrenNode, 1)); *error = NULL; break; } cur = cur->next; } if (val == -1) *error = (char *) strdup("key not found"); return val; } int config_set_int(const char *key, int value, char **error) { int val; char xml_value[8]; xmlNodePtr cur = NULL; *error = NULL; if (!doc) { *error = (char *) strdup("xmlDocPtr not initialized. did you call config_init()?"); _DEBUG_ fprintf(stderr, "%s:%s\n", PACKAGE, *error); return -1; } cur = get_root_element(cur); if (!cur) { *error = (char *) strdup("empty document"); return -1; } snprintf(xml_value, 6, "%d", value); // cur is always top level // if we want to change something we need the second level // for new insertion we need the top level /* Let's go to the second level */ cur = cur->xmlChildrenNode; val = -1; while (cur != NULL) { if (!xmlStrcmp(cur->name, (const xmlChar *) key)) { xmlNodeSetContent(cur, xml_value); *error = NULL; val = value; break; } else val = -1; cur = cur->next; } //Back to the top level cur = get_root_element(cur); if (val == -1) { xmlNewTextChild(get_root_element(cur), NULL, key, xml_value); val = value; } return val; } char *config_get_string(const char *key, char **error) { char *val; xmlNodePtr cur = NULL; *error = NULL; if (!doc) { *error = (char *) strdup("xmlDocPtr not initialized. did you call config_init()?"); fprintf(stderr, "%s\n", *error); return NULL; } cur = get_root_element(cur); if (!cur) { *error = (char *) strdup("empty document"); return NULL; } /* Let's go to the second level */ cur = cur->xmlChildrenNode; val = NULL; while (cur != NULL) { if (!xmlStrcmp(cur->name, (const xmlChar *) key)) { if (cur->xmlChildrenNode) { val = (char *) strdup(xmlNodeListGetString(doc, cur->xmlChildrenNode, 1)); *error = NULL; break; } } cur = cur->next; } if (!val) *error = (char *) strdup("key not found"); return val; } int config_set_string(const char *key, const char *value, char **error) { int val; xmlNodePtr cur = NULL; *error = NULL; if (!doc) { *error = (char *) strdup("xmlDocPtr not initialized. did you call config_init()?"); _DEBUG_ fprintf(stderr, "%s:%s\n", PACKAGE, *error); return -1; } cur = get_root_element(cur); if (!cur) { *error = (char *) strdup("empty document"); return -1; } // cur is always top level // if we want to change something we need the second level // for new insertion we need the top level /* Let's go to the second level */ cur = cur->xmlChildrenNode; val = -1; while (cur != NULL) { if (!xmlStrcmp(cur->name, (const xmlChar *) key)) { xmlNodeSetContent(cur, value); *error = NULL; val = 1; break; } else val = -1; cur = cur->next; } //Back to the top level cur = get_root_element(cur); if (val == -1) { xmlNewTextChild(get_root_element(cur), NULL, key, value); val = 1; } return val; }