/**
* 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;
}