added 3dengfx into the repo, probably not the correct version for this
[summerhack] / src / 3dengfx / src / common / config_parser.c
1 /*
2 Copyright 2004 John Tsiombikas <nuclear@siggraph.org>
3
4 This file is part of the eternal demo.
5
6 The eternal library is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 The eternal demo is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with the eternal demo; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19 */
20 #include <stdio.h>
21 #include <string.h>
22 #include <stdlib.h>
23 #include <ctype.h>
24 #include "config_parser.h"
25
26 /* state variables */
27 static char sym_assign = '=';
28 static char sym_comment = ';';
29 static char max_line_len = 100;
30 static char seperators[257] = " \t";
31 static struct ConfigOption cfg_opt;
32
33 static char *config_file, *cfgptr;
34
35 void set_parser_state(enum ParserState state, long value) {
36         switch(state) {
37         case PS_AssignmentSymbol:
38                 sym_assign = (char)value;
39                 break;
40                 
41         case PS_CommentSymbol:
42                 sym_comment = (char)value;
43                 break;
44                 
45         case PS_MaxLineLen:
46                 max_line_len = value;
47                 break;
48                 
49         case PS_Seperators:
50                 strncpy(seperators, (char*)value, 257);
51                 break;
52         }
53 }
54
55 int load_config_file(const char *fname) {
56         FILE *fp;
57         int fsize;
58         char *temp, *line;
59         
60         if(!fname) return -1;   
61         if(!(fp = fopen(fname, "r"))) return -1;
62         
63         fseek(fp, 0, SEEK_END);
64         fsize = ftell(fp);
65         fseek(fp, 0, SEEK_SET);
66         
67         if(!(temp = realloc(config_file, fsize))) return -1;
68         config_file = temp;
69         
70         cfgptr = config_file;
71         if(!(line = malloc(max_line_len + 1))) return -1;
72         while(fgets(line, max_line_len, fp)) {
73                 char *ptr = line;
74                 
75                 if(*ptr == '\n') continue;      /* kill empty lines, they irritate the parser */
76                 
77                 while(ptr && *ptr && *ptr != sym_comment) {
78                         if(!strchr(seperators, *ptr)) { /* not a seperator */
79                                 *cfgptr++ = *ptr;
80                         }
81                         ptr++;
82                 }
83                 
84                 if(*ptr == sym_comment && ptr != line) {
85                         *cfgptr++ = '\n';
86                 }
87         }
88         
89         *cfgptr = 0;
90         
91         memset(&cfg_opt, 0, sizeof(struct ConfigOption));
92         cfgptr = config_file;
93         free(line);
94         return 0;
95 }
96
97 const struct ConfigOption *get_next_option() {
98         char *tmpbuf = malloc(max_line_len + 1);
99         char *ptr = tmpbuf;
100         
101         if(!(*cfgptr)) {
102                 free(tmpbuf);
103                 return 0;
104         }
105         
106         while(*cfgptr != '\n') {
107                 *ptr++ = *cfgptr++;
108         }
109         *ptr = 0;
110         cfgptr++;
111         
112         if(!(ptr = strchr(tmpbuf, sym_assign))) {
113                 free(tmpbuf);
114                 return 0;
115         }       
116         *ptr++ = 0;
117         
118         cfg_opt.flags = 0;
119         
120         cfg_opt.option = realloc(cfg_opt.option, strlen(tmpbuf) + 1);
121         strcpy(cfg_opt.option, tmpbuf);
122         
123         cfg_opt.str_value = realloc(cfg_opt.str_value, strlen(ptr) + 1);
124         strcpy(cfg_opt.str_value, ptr);
125         
126         if(isdigit(cfg_opt.str_value[0])) {
127                 cfg_opt.flags |= CFGOPT_INT;
128                 cfg_opt.int_value = atoi(cfg_opt.str_value);
129                 cfg_opt.flt_value = atof(cfg_opt.str_value);
130         }
131
132         free(tmpbuf);   
133         return &cfg_opt;
134 }
135
136 void destroy_config_parser() {
137         if(cfg_opt.str_value) free(cfg_opt.str_value);
138         if(cfg_opt.option) free(cfg_opt.option);
139         if(config_file) free(config_file);
140         config_file = 0;
141 }