Files
smmapdfw/smmapdfw/libsmmapdfw/cfg.c
2004-10-15 11:18:48 +00:00

296 lines
5.8 KiB
C

/*
Copyright (C) 2004, Wolfgang Hottgenroth
This file is part of smmapdfw.
smmapdfw 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.
smmapdfw 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 smmapdfw. If not, write to the Free Software Foundation, 59
Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#if HAVE_CONFIG_H
# include "config.h"
#endif
#include <stdio.h>
#if STDC_HEADERS
#include <stdlib.h>
#endif
#if HAVE_SYSLOG_H
#include <syslog.h>
#endif
#include "cfg.h"
#include "htmalloc.h"
#include "sunos_comp.h"
#define LF 10
#define STATE_START 0
#define STATE_COMMENT 1
#define STATE_SECTION 2
#define STATE_NAME 3
#define STATE_EQUAL 4
#define STATE_VALUESTART 5
#define STATE_VALUE 6
#define BUFSIZE 1024
config_section_t *readcfg(char *cfgfile) {
FILE *f;
char buffer[BUFSIZE+1];
char c;
int state = STATE_START;
int i = 0;
char tmp;
config_section_t *cfg = NULL;
config_section_t *cs_head;
config_section_t *cs;
config_item_t *ci_head;
config_item_t *ci;
f = fopen(cfgfile, "r");
if (NULL == f) {
syslog(LOG_ERR, "readcfg: unable to open config file %s", cfgfile);
return NULL;
}
while (EOF != (c = fgetc(f))) {
/* printf("read: (%d) (%d) (%c)\n", state, c, c); */
switch (state) {
case STATE_START:
if ((';' == c) || ('#' == c)) {
state = STATE_COMMENT;
break;
} else if ('[' == c) {
state = STATE_SECTION;
i = 0;
break;
} else if (LF == c) {
break;
} else {
buffer[i++] = c;
state = STATE_NAME;
}
case STATE_COMMENT:
if (LF == c)
state = STATE_START;
break;
case STATE_SECTION:
if (']' == c) {
buffer[i] = '\0';
/* printf("section: (%s)\n", buffer); */
state = STATE_START;
i = 0;
cs = (config_section_t*) htmalloc(sizeof(config_section_t));
cs->next = NULL;
cs->name = (char*) htmalloc(strlen(buffer)+1);
strcpy(cs->name, buffer);
cs->item = NULL;
if (NULL == cfg) {
cfg = cs;
cs_head = cfg;
} else {
cs_head->next = cs;
cs_head = cs;
}
break;
} else if (LF == c) {
syslog(LOG_ERR, "readcfg: unexpected EOL in section");
freecfg(cfg);
fclose(f);
return NULL;
} else {
buffer[i++] = c;
break;
}
case STATE_NAME:
if (isblank(c)) {
buffer[i] = '\0';
/* printf("name: (%s)\n", buffer); */
state = STATE_EQUAL;
i = 0;
ci = (config_item_t*) htmalloc(sizeof(config_item_t));
ci->next = NULL;
ci->name = (char*) htmalloc(strlen(buffer)+1);
strcpy(ci->name, buffer);
ci->value = NULL;
if (NULL == cs->item) {
cs->item = ci;
ci_head = ci;
} else {
ci_head->next = ci;
ci_head = ci;
}
break;
} else if (LF == c) {
syslog(LOG_ERR, "readcfg: unexpected EOL in name");
freecfg(cfg);
fclose(f);
return NULL;
} else {
buffer[i++] = c;
break;
}
case STATE_EQUAL:
if ('=' == c) {
state = STATE_VALUESTART;
break;
} else if (isblank(c)) {
break;
} else {
syslog(LOG_ERR, "readcfg: unexpected character in equal");
freecfg(cfg);
fclose(f);
return NULL;
}
case STATE_VALUESTART:
if (isblank(c)) {
break;
} else if (LF == c) {
syslog(LOG_ERR, "readcfg: unexpected EOL in valuestart");
freecfg(cfg);
fclose(f);
return NULL;
} else {
buffer[i++] = c;
state = STATE_VALUE;
break;
}
case STATE_VALUE:
if (LF == c) {
buffer[i] = '\0';
/* printf("value: (%s)\n", buffer); */
state = STATE_START;
i = 0;
ci->value = (char*) htmalloc(strlen(buffer)+1);
strcpy(ci->value, buffer);
break;
} else {
buffer[i++] = c;
break;
}
}
}
fclose(f);
if (STATE_START != state) {
syslog(LOG_ERR, "readcfg: unexpected EOF");
freecfg(cfg);
fclose(f);
return NULL;
}
return cfg;
}
void printcfg(config_section_t *cfg) {
config_section_t *cs;
config_item_t *ci;
for (cs = cfg; cs != NULL; cs = cs->next) {
printf("section: %s\n", cs->name);
for (ci = cs->item; ci != NULL; ci = ci->next) {
printf(" item: %s -> %s\n", ci->name, ci->value);
}
}
}
void freecfg(config_section_t *cfg) {
config_section_t *cs, *csf;
config_item_t *ci, *cif;
cs = cfg;
while (NULL != cs) {
ci = cs->item;
while (NULL != ci) {
cif = ci;
ci = ci->next;
free(cif->name);
free(cif->value);
free(cif);
}
csf = cs;
cs = cs->next;
free(csf->name);
free(csf);
}
}
config_item_t *findcfgsection(config_section_t *cfg, char *section) {
config_section_t *cs;
for (cs = cfg; cs != NULL; cs = cs->next)
if (0 == strcmp(section, cs->name))
return cs->item;
return NULL;
}
char *findcfg(config_section_t *cfg, char *section, char *name) {
config_item_t *ci;
for (ci = findcfgsection(cfg, section); ci != NULL; ci = ci->next)
if (0 == strcmp(name, ci->name))
return ci->value;
return NULL;
}
char *findcfgx(config_section_t *cfg, char *section, char *name, char *default_value) {
char *r = findcfg(cfg, section, name);
return (NULL != r) ? r : default_value;
}
#ifdef _TEST_MODE_
int main() {
config_section_t *cfg = readcfg("smmapd.ini");
printcfg(cfg);
printf("test1: %s\n", findcfg(cfg, "test_worker1", "obj"));
printf("test2: %s\n", findcfg(cfg, "global", "port"));
printf("test3: %s\n", findcfg(cfg, "nix", "obj"));
printf("test4: %s\n", findcfg(cfg, "global", "nix"));
printf("test5: %s\n", findcfgx(cfg, "global", "test", "test default"));
freecfg(cfg);
}
#endif /* _TEST_MODE_ */