/[pearpc]/src/configparser.cc
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Annotation of /src/configparser.cc

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1 - (hide annotations)
Wed Sep 5 17:11:21 2007 UTC (16 years, 6 months ago) by dpavlin
File size: 8943 byte(s)
import upstream CVS
1 dpavlin 1 /*
2     * PearPC
3     * configparser.cc
4     *
5     * Copyright (C) 2003 Sebastian Biallas (sb@biallas.net)
6     *
7     * This program is free software; you can redistribute it and/or modify
8     * it under the terms of the GNU General Public License version 2 as
9     * published by the Free Software Foundation.
10     *
11     * This program 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 this program; if not, write to the Free Software
18     * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19     */
20    
21     #include <ctype.h>
22     #include "configparser.h"
23     #include "tools/except.h"
24     #include "tools/snprintf.h"
25    
26     ConfigParser *gConfig;
27    
28     ConfigEntry::ConfigEntry(const String &aName, bool mandatory)
29     {
30     mName = new String(aName);
31     mMandatory = mandatory;
32     mInitialized = false;
33     mSet = false;
34     }
35    
36     ConfigEntry::~ConfigEntry()
37     {
38     delete mName;
39     }
40    
41     ConfigType ConfigEntry::getType() const
42     {
43     throw Exception();
44     }
45    
46     int ConfigEntry::asInt() const
47     {
48     throw MsgfException("cannot interprete config entry %y as integer", mName);
49     }
50    
51     String &ConfigEntry::asString(String &result) const
52     {
53     throw MsgfException("cannot interprete config entry %y as string", mName);
54     }
55    
56     int ConfigEntry::compareTo(const Object *obj) const
57     {
58     return mName->compareTo(((ConfigEntry *)obj)->mName);
59     }
60    
61     bool ConfigEntry::isSet() const
62     {
63     return mSet;
64     }
65    
66     bool ConfigEntry::isInitialized() const
67     {
68     return mInitialized;
69     }
70    
71    
72     class ConfigEntryInt: public ConfigEntry {
73     int value;
74     public:
75    
76     ConfigEntryInt(const String &aName, bool mandatory)
77     :ConfigEntry(aName, mandatory)
78     {
79     }
80    
81     ConfigEntryInt(const String &aName, int defaultvalue, int scheiss_c_plus_plus)
82     :ConfigEntry(aName, false)
83     {
84     value = defaultvalue;
85     mInitialized = true;
86     }
87    
88     virtual ConfigType getType() const
89     {
90     return configTypeInt;
91     }
92    
93     void set(int v)
94     {
95     value = v;
96     mInitialized = true;
97     mSet = true;
98     }
99    
100     virtual int asInt() const
101     {
102     return value;
103     }
104     };
105    
106     class ConfigEntryString: public ConfigEntry {
107     String *value;
108     public:
109    
110     ConfigEntryString(const String &aName, bool mandatory)
111     :ConfigEntry(aName, mandatory)
112     {
113     value = new String;
114     }
115    
116     ConfigEntryString(const String &aName, const String &defaultvalue)
117     :ConfigEntry(aName, false)
118     {
119     value = new String(defaultvalue);
120     mInitialized = true;
121     }
122    
123     virtual ConfigType getType() const
124     {
125     return configTypeString;
126     }
127    
128     void set(const String &s)
129     {
130     *value = s;
131     mInitialized = true;
132     mSet = true;
133     }
134    
135     virtual String &asString(String &result) const
136     {
137     result = *value;
138     return result;
139     }
140     };
141    
142     ConfigParser::ConfigParser()
143     {
144     entries = new AVLTree(true);
145     }
146    
147     ConfigParser::~ConfigParser()
148     {
149     delete entries;
150     }
151    
152     void ConfigParser::acceptConfigEntryInt(const String &mName, bool mandatory)
153     {
154     ConfigEntry *entry = new ConfigEntryInt(mName, mandatory);
155     if (!entries->insert(entry)) throw MsgfException("duplicate config entry '%y'", &mName);
156     }
157    
158     void ConfigParser::acceptConfigEntryString(const String &mName, bool mandatory)
159     {
160     ConfigEntry *entry = new ConfigEntryString(mName, mandatory);
161     if (!entries->insert(entry)) throw MsgfException("duplicate config entry '%y'", &mName);
162     }
163    
164     void ConfigParser::acceptConfigEntryIntDef(const String &mName, int d)
165     {
166     ConfigEntry *entry = new ConfigEntryInt(mName, d, 0);
167     if (!entries->insert(entry)) throw MsgfException("duplicate config entry '%y'", &mName);
168     }
169    
170     void ConfigParser::acceptConfigEntryStringDef(const String &mName, const String &d)
171     {
172     ConfigEntry *entry = new ConfigEntryString(mName, d);
173     if (!entries->insert(entry)) throw MsgfException("duplicate config entry '%y'", &mName);
174     }
175    
176     bool ConfigParser::skipWhite(Stream &in)
177     {
178     while (cur == ' ' || cur == '\t' || cur == '\r') {
179     if (!in.read(&cur, 1)) return false;
180     }
181     return true;
182     }
183    
184     #define INV 0xff
185     byte mapchar[]={
186     ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ', 10,' ',' ',' ',' ',' ', // 0-15
187     ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ', // 16-31
188     ' ','!','"','#','$','%','&', 39,'(',')','*','+',',','-','.','/', // 32-47
189     '0','0','0','0','0','0','0','0','0','0',':',';','<','=','>','?', // 48-63
190     '@','A','A','A','A','A','A','A','A','A','A','A','A','A','A','A', // 64-79
191     'A','A','A','A','A','A','A','A','A','A','A','[', 92,']','^','_', // 80-95
192     INV,'A','A','A','A','A','A','A','A','A','A','A','A','A','A','A', // 96-111
193     'A','A','A','A','A','A','A','A','A','A','A','{','|','}','~',INV, // 112-127
194     INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,
195     INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,
196     INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,
197     INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,
198     INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,
199     INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,
200     INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,
201     INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,INV
202     };
203    
204     void ConfigParser::loadConfig(Stream &in)
205     {
206     read(in);
207     foreach(ConfigEntry, e, *entries, {
208     if (e->mMandatory && !e->isInitialized()) {
209     throw MsgfException("config entry '%y' is not set.", e->mName);
210     }
211     });
212     }
213    
214     void ConfigParser::read(Stream &in)
215     {
216     if (!in.read(&cur, 1)) return;
217     line = 1;
218     while (true) {
219     if (!skipWhite(in)) return;
220     if (cur == '#') {
221     // skip comment
222     do {
223     if (!in.read(&cur, 1)) return;
224     } while (cur != '\n');
225     if (!in.read(&cur, 1)) return;
226     line++;
227     continue;
228     }
229     if (cur == '\r') {
230     if (!in.read(&cur, 1)) return;
231     continue;
232     }
233     if (cur == '\n') {
234     if (!in.read(&cur, 1)) return;
235     line++;
236     continue;
237     }
238     byte m = mapchar[cur];
239     String ident;
240     if (m != 'A' && m != '_') throw MsgfException("invalid character '%c' (%02x) in line %d.", cur, cur, line);
241     do {
242     ident += cur;
243     if (!in.read(&cur, 1)) throw MsgfException("syntax error in line %d.", line);
244     m = mapchar[cur];
245     } while (m == 'A' || m == '0' || m == '_');
246    
247     ConfigEntry *e = getEntry(ident);
248     if (!e) throw MsgfException("unknown identifier '%y' in line %d.", &ident, line);
249     if (e->isSet()) throw MsgfException("config entry '%y' is already set in line %d.", e->mName, line);
250    
251     if (!skipWhite(in)) throw MsgfException("%s expected in line %d.", "'='", line);
252     if (cur != '=') throw MsgfException("%s expected in line %d.", "'='", line);
253     if (!in.read(&cur, 1) || !skipWhite(in)) throw MsgfException("syntax error in line %d.", line);
254     m = mapchar[cur];
255    
256     if (e->getType() == configTypeInt) {
257     if (m != '0') throw MsgfException("%s expected in line %d.", "integer", line);
258     String n;
259     do {
260     n += cur;
261     if (!in.read(&cur, 1)) cur = ' ';
262     m = mapchar[cur];
263     } while (m == '0' || m == 'A');
264     if (cur == '\n' || cur == '\r' || cur == ' ' || cur == '\t' || cur == '#') {
265     // nothing to do
266     } else {
267     cur = tolower(cur);
268     if (cur == 'h' || cur == 'o' || cur == 'b' || cur == 'd') {
269     n += cur;
270     if (!in.read(&cur, 1)) cur = ' ';
271     } else {
272     throw MsgfException("%s expected in line %d.", "integer", line);
273     }
274     }
275     uint64 u;
276     if (!n.toInt64(u)) throw MsgfException("%s expected in line %d.", "integer", line);
277     ((ConfigEntryInt *)e)->set(u);
278     } else {
279     if (m != '"') throw MsgfException("%s expected in line %d.", "'\"'", line);
280     String s;
281     int oldline = line;
282     do {
283     s += cur;
284     if (!in.read(&cur, 1)) throw MsgfException("unterminated string in line %d (starts in line %d).", line, oldline);
285     m = mapchar[cur];
286     if (m == '\n') line++;
287     } while (m != '"');
288     s.del(0, 1);
289     ((ConfigEntryString *)e)->set(s);
290     if (!in.read(&cur, 1)) cur = ' ';
291     }
292     if (!skipWhite(in)) return;
293     if (cur == '#') continue;
294     if (cur != '\n') throw MsgfException("syntax error in line %d.", line);
295     }
296     }
297    
298     ConfigEntry *ConfigParser::getEntry(const String &name)
299     {
300     ConfigEntry empty(name, false);
301     return (ConfigEntry *)entries->get(entries->find(&empty));
302     }
303    
304     int ConfigParser::getConfigInt(const String &name)
305     {
306     ConfigEntry empty(name, false);
307     ConfigEntry *entry = (ConfigEntry *)entries->get(entries->find(&empty));
308     if (!entry) throw MsgfException("unknown entry '%y'", &name);
309     if (!entry->isInitialized()) throw MsgfException("%y is not set!", &name);
310     return entry->asInt();
311     }
312    
313     String &ConfigParser::getConfigString(const String &name, String &result)
314     {
315     ConfigEntry empty(name, false);
316     ConfigEntry *entry = (ConfigEntry *)entries->get(entries->find(&empty));
317     if (!entry) throw MsgfException("unknown entry '%y'", &name);
318     if (!entry->isInitialized()) throw MsgfException("%y is not set!", &name);
319     return entry->asString(result);
320     }
321    
322     bool ConfigParser::haveKey(const String &name)
323     {
324     ConfigEntry empty(name, false);
325     ConfigEntry *entry = (ConfigEntry *)entries->get(entries->find(&empty));
326     return entry && entry->isSet();
327     }
328    

  ViewVC Help
Powered by ViewVC 1.1.26