wip: config reader, reading input
[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 #include "../debug.h"
20
21 #include <iostream>
22 #include <fstream>
23 #include <string>
24
25 using std::ifstream;
26 using std::string;
27
28 char* configDir = "../configs/";
29
30 /// ***** Private Method Headers *****
31
32 void processLine(const string& str, keyMap* map);
33 bool extractLine(const string& str, string* name, string* value);
34
35 /// ***** Private Variables *****
36
37 /// ***** Public Methods *****
38
39 void readConfigs(keyMap* map)
40 {
41     char fileName[64];
42
43     strcpy(fileName, configDir);
44     strcat(fileName, "test.cfg");
45
46     ifstream file(fileName);
47
48     if( !file.is_open() )
49     {
50         cerr << "Unable to open file " << fileName << "." << endl;
51         exit(1);
52     }
53
54     while(true)
55     {
56         string line;
57         getline(file, line);
58
59         if(file.eof())
60             break;
61
62         processLine(line, map);
63     }
64
65     file.close();
66 }
67
68 /// ***** Private Methods *****
69
70 void processLine(const string& str, keyMap* map)
71 {
72     string name;
73     string value;
74
75     bool extracted;
76
77     extracted = extractLine(str, &name, &value);
78
79     if(extracted)
80     {
81         cout << name << endl;
82         cout << value << endl;
83     }
84 }
85
86 /*
87  * Return true iff the string str, had a name and value extracted and saved in
88  * name and value. Otherwise return false and leave name and value alone.
89  */
90 bool extractLine(const string& str, string* name, string* value)
91 {
92     /*
93      * state    := 0 if eating leading name whitespace
94      *          := 1 if saving name
95      *          := 2 if eating trailing name whitespace
96      *          := 3 if eating leading value whitespace
97      *          := 4 if saving value
98      *          := 5 if all is done and well
99      */
100     int state = 0;
101
102     int char_pos = 0;
103
104     int name_start;
105     int name_end;
106
107     int value_start;
108     int value_end;
109
110     const char* c_str = str.c_str();
111
112     while(true)
113     {
114         if(c_str[char_pos] == 0 && state != 4)
115             return false;
116
117         switch (state)
118         {
119             case 0:
120                 if(c_str[char_pos] != ' '
121                 && c_str[char_pos] != '\t')
122                 {
123                     state++;
124                     name_start = char_pos;
125                 }
126                 break;
127             case 1:
128                 if(c_str[char_pos] == ' '
129                 || c_str[char_pos] == '\t'
130                 || c_str[char_pos] == '=')
131                 {
132                     state++;
133                     name_end = char_pos;
134                 }
135                 if(c_str[char_pos] == '=')
136                     char_pos--; // decrement to stay on this char
137                 break;
138             case 2:
139                 if(c_str[char_pos] == '=')
140                 {
141                     state++;
142                 }
143                 break;
144             case 3:
145                 if(c_str[char_pos] != ' '
146                 && c_str[char_pos] != '\t')
147                 {
148                     state++;
149                     value_start = char_pos;
150                 }
151                 break;
152             case 4:
153                 if(c_str[char_pos] == ' '
154                 || c_str[char_pos] == '\t'
155                 || c_str[char_pos] == 0)
156                 {
157                     state++;
158                     value_end = char_pos;
159                 }
160                 break;
161         }
162
163         if(state == 5)
164             break;
165
166         char_pos++;
167     }
168
169     name->clear();
170     value->clear();
171
172     name->replace(0, 0, c_str, name_start, name_end-name_start);
173     value->replace(0, 0, c_str, value_start, value_end-value_start);
174
175     return true;
176 }