nuclear@0: /* nuclear@0: This file is part of dynwatch, a win32 system tray applet which nuclear@0: updates automatically the dyndns entry of quake.gr. nuclear@0: nuclear@0: Copyright (c) 2005 John Tsiombikas nuclear@0: nuclear@0: This program is free software; you can redistribute it and/or modify nuclear@0: it under the terms of the GNU General Public License as published by nuclear@0: the Free Software Foundation; either version 2 of the License, or nuclear@0: (at your option) any later version. nuclear@0: nuclear@0: This program is distributed in the hope that it will be useful, nuclear@0: but WITHOUT ANY WARRANTY; without even the implied warranty of nuclear@0: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the nuclear@0: GNU General Public License for more details. nuclear@0: nuclear@0: You should have received a copy of the GNU General Public License nuclear@0: along with this program; if not, write to the Free Software nuclear@0: Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA nuclear@0: */ nuclear@0: #include nuclear@0: #include nuclear@0: #include nuclear@0: #include nuclear@0: #include "config_parser.h" nuclear@0: nuclear@0: /* state variables */ nuclear@0: static char sym_assign = '='; nuclear@0: static char sym_comment = ';'; nuclear@0: static char max_line_len = 100; nuclear@0: static char seperators[257] = " \t"; nuclear@0: static struct ConfigOption cfg_opt; nuclear@0: nuclear@0: static char *config_file, *cfgptr; nuclear@0: nuclear@0: void SetParserState(enum ParserState state, int value) { nuclear@0: switch(state) { nuclear@0: case PS_AssignmentSymbol: nuclear@0: sym_assign = (char)value; nuclear@0: break; nuclear@0: nuclear@0: case PS_CommentSymbol: nuclear@0: sym_comment = (char)value; nuclear@0: break; nuclear@0: nuclear@0: case PS_MaxLineLen: nuclear@0: max_line_len = value; nuclear@0: break; nuclear@0: nuclear@0: case PS_Seperators: nuclear@0: strncpy(seperators, (char*)value, 257); nuclear@0: break; nuclear@0: } nuclear@0: } nuclear@0: nuclear@0: int LoadConfigFile(const char *fname) { nuclear@0: FILE *fp; nuclear@0: int fsize; nuclear@0: char *temp; nuclear@0: nuclear@0: if(!fname) return -1; nuclear@0: if(!(fp = fopen(fname, "r"))) return -1; nuclear@0: nuclear@0: fseek(fp, 0, SEEK_END); nuclear@0: fsize = ftell(fp); nuclear@0: fseek(fp, 0, SEEK_SET); nuclear@0: nuclear@0: if(!(temp = realloc(config_file, fsize))) return -1; nuclear@0: config_file = temp; nuclear@0: nuclear@0: cfgptr = config_file; nuclear@0: temp = malloc(max_line_len + 1); nuclear@0: while(fgets(temp, max_line_len, fp)) { nuclear@0: char *ptr = temp; nuclear@0: nuclear@0: if(*ptr == '\n') continue; /* kill empty lines, they irritate the parser */ nuclear@0: nuclear@0: while(ptr && *ptr && *ptr != sym_comment) { nuclear@0: if(!strchr(seperators, *ptr)) { /* not a seperator */ nuclear@0: *cfgptr++ = *ptr; nuclear@0: } nuclear@0: ptr++; nuclear@0: } nuclear@0: nuclear@0: if(*ptr == sym_comment && ptr != temp) { nuclear@0: *cfgptr++ = '\n'; nuclear@0: } nuclear@0: } nuclear@0: nuclear@0: *cfgptr = 0; nuclear@0: nuclear@0: memset(&cfg_opt, 0, sizeof(struct ConfigOption)); nuclear@0: cfgptr = config_file; nuclear@0: free(temp); nuclear@0: return 0; nuclear@0: } nuclear@0: nuclear@0: const struct ConfigOption *GetNextOption() { nuclear@0: char *tmpbuf = malloc(max_line_len + 1); nuclear@0: char *ptr = tmpbuf; nuclear@0: nuclear@0: if(!(*cfgptr)) { nuclear@0: free(tmpbuf); nuclear@0: return 0; nuclear@0: } nuclear@0: nuclear@0: while(*cfgptr != '\n') { nuclear@0: *ptr++ = *cfgptr++; nuclear@0: } nuclear@0: *ptr = 0; nuclear@0: cfgptr++; nuclear@0: nuclear@0: if(!(ptr = strchr(tmpbuf, sym_assign))) { nuclear@0: free(tmpbuf); nuclear@0: return 0; nuclear@0: } nuclear@0: *ptr++ = 0; nuclear@0: nuclear@0: cfg_opt.flags = 0; nuclear@0: nuclear@0: cfg_opt.option = realloc(cfg_opt.option, strlen(tmpbuf) + 1); nuclear@0: strcpy(cfg_opt.option, tmpbuf); nuclear@0: nuclear@0: cfg_opt.str_value = realloc(cfg_opt.str_value, strlen(ptr) + 1); nuclear@0: strcpy(cfg_opt.str_value, ptr); nuclear@0: nuclear@0: if(isdigit(cfg_opt.str_value[0])) { nuclear@0: cfg_opt.flags |= CFGOPT_INT; nuclear@0: cfg_opt.int_value = atoi(cfg_opt.str_value); nuclear@0: cfg_opt.flt_value = atof(cfg_opt.str_value); nuclear@0: } nuclear@0: nuclear@0: free(tmpbuf); nuclear@0: return &cfg_opt; nuclear@0: } nuclear@0: nuclear@0: void DestroyConfigParser() { nuclear@0: if(cfg_opt.str_value) free(cfg_opt.str_value); nuclear@0: if(cfg_opt.option) free(cfg_opt.option); nuclear@0: if(config_file) free(config_file); nuclear@0: }