Imported Upstream version 1.1.11
[platform/upstream/cdrkit.git] / librols / default.c
1 /* 
2  * Copyright 2006 Eduard Bloch 
3  *
4  * Uses my config parser code and small wrappers to provide the old interface.
5  *
6  */
7 /*
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License version 2
10  * as published by the Free Software Foundation.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License along with
18  * this program; see the file COPYING.  If not, write to the Free Software
19  * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20  */
21
22 #include <mconfig.h>
23 #include <stdlib.h>
24 #include <stdio.h>
25 #include <ctype.h>
26 #include <string.h>
27
28 enum parstate {
29         KEYBEGINSEARCH,
30         KEYCOMPARE,
31         EQSIGNSEARCH,
32         VALBEGINSEARCH,
33         LASTCHARSEARCH
34 };
35
36 #define GETVAL_BUF_LEN 512
37 #define isUspace(x) isspace( (int) (unsigned char) x)
38
39 static FILE *glob_cfg_ptr = NULL;
40
41 /*
42  * Warning, uses static line buffer, not reentrant. NULL returned if the key isn't found.
43  */
44 static char *get_value(FILE *srcfile, const char *key, int dorewind) {
45         static char linebuf[GETVAL_BUF_LEN];
46
47         if(!srcfile)
48                 return ((char *) NULL);
49
50         if(dorewind)
51                 rewind(srcfile);
52
53         if(!key)
54                 return NULL;
55
56 next_line:
57         while(fgets(linebuf, sizeof(linebuf)-1, srcfile)) {
58                 int i;
59                 int keybeg=0;
60                 int s=KEYBEGINSEARCH;
61                 char *ret=NULL;
62                 int lastchar=0;
63
64                 /* simple state machine, char position moved by the states (or not),
65                  * state change is done by the state (or not) */
66                 for( i=0 ; i<sizeof(linebuf) ; ) {
67                         /* printf("key: %s, %s, s: %d\n", key,  linebuf, s); */
68                         switch(s) {
69                                 case(KEYBEGINSEARCH):
70                                         {
71                                                 if(isUspace(linebuf[i]))
72                                                         i++;
73                                                 else if(linebuf[i] == '#' || linebuf[i]=='\0')
74                                                         goto next_line;
75                                                 else {
76                                                         s=KEYCOMPARE;
77                                                         keybeg=i;
78                                                 }
79                                         }
80                                         break;
81                                 case(KEYCOMPARE): /* compare the key */
82                                         {
83                                                 if(key[i-keybeg]=='\0') 
84                                                         /* end of key, next state decides what to do on this position */
85                                                         s=EQSIGNSEARCH;
86                                                 else {
87                                                         if(linebuf[i-keybeg]!=key[i-keybeg])
88                                                                 goto next_line;
89                                                         else
90                                                                 i++;
91                                                 }
92                                         }
93                                         break;
94                                 case(EQSIGNSEARCH): /* skip whitespace, stop on =, break on anything else */
95                                         {
96                                                 if(isUspace(linebuf[i]))
97                                                         i++;
98                                                 else if(linebuf[i]=='=') {
99                                                         s=VALBEGINSEARCH;
100                                                         i++;
101                                                 }
102                                                 else
103                                                         goto next_line;
104                                         }
105                                         break;
106                                 case(VALBEGINSEARCH):
107                                         {
108                                                 if(isUspace(linebuf[i]))
109                                                         i++;
110                                                 else {
111                                                         /* possible at EOF */
112                                                         if(linebuf[i] == '\0')
113                                                                 return NULL;
114
115                                                         lastchar=i-1; /* lastchar can be a space, see below */
116                                                         ret= & linebuf[i];
117                                                         s=LASTCHARSEARCH;
118                                                 }
119                                         }
120                                         break;
121                                 case(LASTCHARSEARCH):
122                                         {
123                                                 if(linebuf[i]) {
124                                                         if(!isUspace(linebuf[i]))
125                                                                 lastchar=i;
126                                                 }
127                                                 else { /* got string end, terminate after the last seen char */
128                                                         if(linebuf+lastchar < ret) /* no non-space found */
129                                                                 return NULL;
130                                                         linebuf[lastchar+1]='\0';
131                                                         return ret;
132                                                 }
133                                                 i++;
134                                         }
135                                         break;
136                         }
137                 }
138         }
139         return NULL;
140 }
141
142 int cfg_open(const char *name)
143 {
144         if(glob_cfg_ptr) {
145                 fclose(glob_cfg_ptr);
146                 glob_cfg_ptr=NULL;
147         }
148         if(!name) {
149                 glob_cfg_ptr=NULL;
150                 return 0;
151         }
152         glob_cfg_ptr = fopen(name, "r");
153         return (glob_cfg_ptr ? 0 : -1);
154 }
155
156 int cfg_close()
157 {
158         int r;
159         if(!glob_cfg_ptr)
160                 return 0;
161         r=fclose(glob_cfg_ptr);
162         glob_cfg_ptr=NULL;
163         return r;
164 }
165
166 void cfg_restart()
167 {
168         get_value(glob_cfg_ptr, NULL, 1);
169 }
170
171 char *cfg_get(const char *key)
172 {
173         return get_value(glob_cfg_ptr, key, 1);
174 }
175
176 char *cfg_get_next(const char *key)
177 {
178         return get_value(glob_cfg_ptr, key, 0);
179 }