renamed libpg to libbear
[physics.git] / src / config / reader.cpp
1 /*
2  *  Copyright (C) 2008 Patrik Gornicz, Gornicz_P (at) hotmail (dot) com.
3  *
4  *  This program is free software: you can redistribute it and/or modify
5  *  it under the terms of the GNU General Public License as published by
6  *  the Free Software Foundation, either version 3 of the License, or
7  *  (at your option) any later version.
8  *
9  *  This program is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *  GNU General Public License for more details.
13  *
14  *  You should have received a copy of the GNU General Public License
15  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
16  */
17
18 #include "reader.h"
19
20 #include <bear/debug.h>
21 using namespace bear;
22
23 #include <iostream>
24 using std::cerr;
25 using std::cout;
26 using std::endl;
27
28 #include <fstream>
29 #include <string>
30
31 #include "keys.h"
32
33 using std::ifstream;
34 using std::string;
35
36 typedef std::map<string, SDLKey> kMap;
37 kMap keyMap;
38
39 /// ***** Private Method Headers *****
40
41 void processLine(const string& str);
42 bool extractLine(const string& str, string* name, string* value);
43 void createKeyMap();
44
45 /// ***** Private Variables *****
46
47 const char* configDir = "configs/";
48 const char* testFile = "keys.cfg";
49
50 /// ***** Public Methods *****
51
52 void readConfigs()
53 {
54     char fileName[64];
55
56     createKeyMap();
57
58     strcpy(fileName, configDir);
59     strcat(fileName, testFile);
60
61     ifstream file(fileName);
62
63     if( !file.is_open() )
64     {
65         cerr << "Unable to open file " << fileName << "." << endl;
66         exit(1);
67     }
68
69     while(true)
70     {
71         string line;
72         getline(file, line);
73
74         if(file.eof())
75             break;
76
77         processLine(line);
78     }
79
80     file.close();
81 }
82
83 /// ***** Private Methods *****
84
85 void processLine(const string& str)
86 {
87     string name;
88     string value;
89
90     bool extracted;
91
92     extracted = extractLine(str, &name, &value);
93
94     if(extracted)
95     {
96         SDLKey key = keyMap[value];
97
98         if(0 != key)
99         {
100             *(key::sdlMap[name]) = key;
101         }
102     }
103 }
104
105 /*
106  * Return true iff the string str, had a name and value extracted and saved in
107  * name and value. Otherwise return false and leave name and value alone.
108  */
109 bool extractLine(const string& str, string* name, string* value)
110 {
111     /*
112      * state    := 0 if eating leading name whitespace
113      *          := 1 if saving name
114      *          := 2 if eating trailing name whitespace
115      *          := 3 if eating leading value whitespace
116      *          := 4 if saving value
117      *          := 5 if all is done and well
118      */
119     int state = 0;
120
121     int char_pos = 0;
122
123     int name_start = 0;
124     int name_end = 0;
125
126     int value_start = 0;
127     int value_end = 0;
128
129     const char* c_str = str.c_str();
130
131     while(true)
132     {
133         if(c_str[char_pos] == 0 && state != 4)
134             return false;
135
136         switch (state)
137         {
138             case 0:
139                 if(c_str[char_pos] != ' '
140                 && c_str[char_pos] != '\t')
141                 {
142                     state++;
143                     name_start = char_pos;
144                 }
145                 break;
146             case 1:
147                 if(c_str[char_pos] == ' '
148                 || c_str[char_pos] == '\t'
149                 || c_str[char_pos] == '=')
150                 {
151                     state++;
152                     name_end = char_pos;
153                 }
154
155                 if(c_str[char_pos] == '=')
156                     char_pos--; // decrement to stay on this char
157                 break;
158             case 2:
159                 if(c_str[char_pos] != ' '
160                 && c_str[char_pos] != '\t'
161                 && c_str[char_pos] != '=')
162                 {
163                     return false;
164                 }
165
166                 if(c_str[char_pos] == '=')
167                 {
168                     state++;
169                 }
170                 break;
171             case 3:
172                 if(c_str[char_pos] != ' '
173                 && c_str[char_pos] != '\t')
174                 {
175                     state++;
176                     value_start = char_pos;
177                 }
178                 break;
179             case 4:
180                 if(c_str[char_pos] == ' '
181                 || c_str[char_pos] == '\t'
182                 || c_str[char_pos] == 0)
183                 {
184                     state++;
185                     value_end = char_pos;
186                 }
187                 break;
188         }
189
190         if(state == 5)
191             break;
192
193         char_pos++;
194     }
195
196     name->clear();
197     value->clear();
198
199     name->replace   (0, 0, c_str, name_start,   name_end  - name_start);
200     value->replace  (0, 0, c_str, value_start,  value_end - value_start);
201
202     return true;
203 }
204
205 void createKeyMap()
206 {
207     char buf[2] = {0,0};
208
209     // add all the letters
210     for (int i = 'A'; i <= 'Z'; i++)   // uppercase
211     {
212         buf[0] = (char)i;
213         keyMap[buf] = (SDLKey)(i + 'a' - 'A');
214     }
215     for (int i = 'a'; i <= 'z'; i++)   // lowercase
216     {
217         buf[0] = (char)i;
218         keyMap[buf] = (SDLKey)i;
219     }
220
221     // add all the numbers
222     for (int i = '0'; i <= '9'; i++)
223     {
224         buf[0] = (char)i;
225         keyMap[buf] = (SDLKey)i;
226     }
227
228     /*
229     // add the function keys
230     int F1 = (int)Key.F1;
231     for (int i = F1; i <= (int)Key.F15; i++)
232     {
233         keyMap.Add("F" + (i - F1 + 1), (Key)i);
234         keyMap.Add("f" + (i - F1 + 1), (Key)i);
235     }
236     */
237
238     keyMap["LCtrl"]         = SDLK_LCTRL;
239     keyMap["LeftControl"]   = SDLK_LCTRL;
240     keyMap["LAlt"]          = SDLK_LALT;
241     keyMap["LeftAlt"]       = SDLK_LALT;
242     keyMap["LShift"]        = SDLK_LSHIFT;
243     keyMap["LeftShift"]     = SDLK_LSHIFT;
244     keyMap["LWin"]          = SDLK_LSUPER;
245     keyMap["LeftWindows"]   = SDLK_LSUPER;
246     keyMap["LeftMeta"]      = SDLK_LMETA;
247     keyMap["LMeta"]         = SDLK_LMETA;
248
249     keyMap["RCtrl"]         = SDLK_RCTRL;
250     keyMap["RightControl"]  = SDLK_RCTRL;
251     keyMap["RAlt"]          = SDLK_RALT;
252     keyMap["RightAlt"]      = SDLK_RALT;
253     keyMap["RShift"]        = SDLK_RSHIFT;
254     keyMap["RightShift"]    = SDLK_RSHIFT;
255     keyMap["RWin"]          = SDLK_RSUPER;
256     keyMap["RightWindows"]  = SDLK_RSUPER;
257     keyMap["RightMeta"]     = SDLK_RMETA;
258     keyMap["RMeta"]         = SDLK_RMETA;
259
260     keyMap["Esc"]           = SDLK_ESCAPE;
261     keyMap["Escape"]        = SDLK_ESCAPE;
262
263     keyMap["Return"]        = SDLK_RETURN;
264     keyMap["Enter"]         = SDLK_RETURN;
265
266     keyMap["Insert"]        = SDLK_INSERT;
267     keyMap["Home"]          = SDLK_HOME;
268     keyMap["Delete"]        = SDLK_DELETE;
269     keyMap["End"]           = SDLK_END;
270     keyMap["PageUp"]        = SDLK_PAGEUP;
271     keyMap["PageDown"]      = SDLK_PAGEDOWN;
272
273     keyMap["Minus"]         = SDLK_MINUS;
274     keyMap["Equal"]         = SDLK_EQUALS;
275     keyMap["Equals"]        = SDLK_EQUALS;
276     keyMap["LeftBracket"]   = SDLK_LEFTBRACKET;
277     keyMap["LBracket"]      = SDLK_LEFTBRACKET;
278     keyMap["RightBracket"]  = SDLK_RIGHTBRACKET;
279     keyMap["RBracket"]      = SDLK_RIGHTBRACKET;
280     keyMap["Backslash"]     = SDLK_BACKSLASH;
281     keyMap["Slash"]         = SDLK_SLASH;
282     keyMap["Semicolon"]     = SDLK_SEMICOLON;
283     keyMap["Semi"]          = SDLK_SEMICOLON;
284     keyMap["Quote"]         = SDLK_QUOTE;
285     keyMap["Comma"]         = SDLK_COMMA;
286     keyMap["Period"]        = SDLK_PERIOD;
287     keyMap["Space"]         = SDLK_SPACE;
288     keyMap["BSpace"]        = SDLK_BACKSPACE;
289     keyMap["Backspace"]     = SDLK_BACKSPACE;
290     keyMap["BackSpace"]     = SDLK_BACKSPACE;
291
292     keyMap["Tab"]           = SDLK_TAB;
293     keyMap["BackQuote"]     = SDLK_BACKQUOTE;
294     keyMap["BQuote"]        = SDLK_BACKQUOTE;
295     keyMap["CapsLock"]      = SDLK_CAPSLOCK;
296     keyMap["Caps"]          = SDLK_CAPSLOCK;
297
298     keyMap["Up"]            = SDLK_UP;
299     keyMap["Down"]          = SDLK_DOWN;
300     keyMap["Left"]          = SDLK_LEFT;
301     keyMap["Right"]         = SDLK_RIGHT;
302 }