]> git.mxchange.org Git - flightgear.git/blob - src/FDM/JSBSim/FGConfigFile.cpp
Sync with latest JSBSim CVS.
[flightgear.git] / src / FDM / JSBSim / FGConfigFile.cpp
1 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
2 \r
3  Header:       FGConfigFile.h\r
4  Author:       Jon Berndt\r
5  Date started: 03/29/00\r
6  Purpose:      Config file read-in class\r
7  Called by:    FGAircraft\r
8 \r
9 FUNCTIONAL DESCRIPTION\r
10 --------------------------------------------------------------------------------\r
11 \r
12 HISTORY\r
13 --------------------------------------------------------------------------------\r
14 03/16/2000 JSB  Created\r
15 \r
16 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
17 INCLUDES\r
18 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/\r
19 \r
20 #include "FGConfigFile.h"\r
21 #include <stdlib.h>\r
22 #include <math.h>\r
23 \r
24 static const char *IdSrc = "$Id$";\r
25 static const char *IdHdr = ID_CONFIGFILE;\r
26 \r
27 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
28 CLASS IMPLEMENTATION\r
29 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/\r
30 \r
31 FGConfigFile::FGConfigFile(string cfgFileName)\r
32 {\r
33 #if defined ( sgi ) && !defined( __GNUC__ )\r
34   cfgfile.open(cfgFileName.c_str(), ios::in );\r
35 #else\r
36   cfgfile.open(cfgFileName.c_str(), ios::in | ios::binary );\r
37 #endif\r
38   CommentsOn = false;\r
39   CurrentIndex = 0;\r
40   Opened = true;\r
41 #if defined ( sgi ) && !defined( __GNUC__ )\r
42    if (!cfgfile.fail() && !cfgfile.eof())  GetNextConfigLine();\r
43 #else\r
44   if (cfgfile.is_open()) GetNextConfigLine();\r
45 #endif\r
46   else Opened = false;\r
47 \r
48   if (debug_lvl & 2) cout << "Instantiated: FGConfigFile" << endl;\r
49 }\r
50 \r
51 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
52 \r
53 FGConfigFile::~FGConfigFile()\r
54 {\r
55   cfgfile.close();\r
56   if (debug_lvl & 2) cout << "Destroyed:    FGConfigFile" << endl;\r
57 }\r
58 \r
59 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
60 \r
61 string FGConfigFile::GetNextConfigLine(void)\r
62 {\r
63   int deblank, not_found = string::npos;\r
64   int comment_starts_at;\r
65   int comment_ends_at;\r
66   int comment_length;\r
67   int line_length;\r
68   bool start_comment, end_comment;\r
69   string CommentStringTemp;\r
70 \r
71   do {\r
72     CurrentLine = GetLine();\r
73     line_length = CurrentLine.length();\r
74     comment_starts_at = CurrentLine.find("<!--");\r
75     \r
76     if (comment_starts_at >= 0) start_comment = true;\r
77     else start_comment = false;\r
78     \r
79     comment_ends_at = CurrentLine.find("-->");\r
80     \r
81     if (comment_ends_at >= 0) end_comment = true;\r
82     else end_comment = false;\r
83 \r
84     if (!start_comment && !end_comment) {                              //  command comment\r
85       if (CommentsOn) CommentStringTemp = CurrentLine;\r
86       CommentString += CommentStringTemp + "\r\n";\r
87     } else if (start_comment && comment_ends_at > comment_starts_at) { //  <!-- ... -->\r
88       CommentsOn = false;\r
89       comment_length = comment_ends_at + 2 - comment_starts_at + 1;\r
90       LineComment = CurrentLine.substr(comment_starts_at+4, comment_length-4-3);\r
91       CurrentLine.erase(comment_starts_at, comment_length);\r
92     } else if ( start_comment && !end_comment) {                       //  <!-- ...\r
93       CommentsOn = true;\r
94       comment_length = line_length - comment_starts_at;\r
95       CommentStringTemp = CurrentLine.substr(comment_starts_at+4, comment_length-4);\r
96       CommentString = CommentStringTemp + "\r\n";\r
97       CurrentLine.erase(comment_starts_at, comment_length);\r
98     } else if (!start_comment && end_comment) {                       //  ... -->\r
99       CommentsOn = false;\r
100       comment_length = comment_ends_at + 2 + 1;\r
101       CommentStringTemp = CurrentLine.substr(0, comment_length-4);\r
102       CommentString += CommentStringTemp + "\r\n";\r
103       CurrentLine.erase(0, comment_length);\r
104     } else if (start_comment && comment_ends_at < comment_starts_at) { //  --> command <!--\r
105       cerr << "Old comment ends and new one starts - bad JSBSim config file form." << endl;\r
106       CommentsOn = false;\r
107       comment_length = comment_ends_at + 2 + 1;\r
108       CommentStringTemp = CurrentLine.substr(0, comment_length-4);\r
109       CommentString += CommentStringTemp + "\r\n";\r
110       CurrentLine.erase(0, comment_length);\r
111     }\r
112     \r
113   } while (CommentsOn);\r
114 \r
115   if (CurrentLine.length() == 0) GetNextConfigLine();\r
116   CurrentIndex = 0;\r
117   return CurrentLine;\r
118 }\r
119 \r
120 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
121 \r
122 string FGConfigFile::GetValue(string val)\r
123 {\r
124   unsigned int pos, p1, p2, ptest;\r
125 \r
126   if (val == "") {    // this call is to return the tag value\r
127     pos = CurrentLine.find("<");\r
128     if (pos != CurrentLine.npos) { // beginning brace found "<"\r
129       p1 = CurrentLine.find_first_not_of(" ",pos+1);\r
130       if (p1 != CurrentLine.npos) { // found first character of tag\r
131         p2 = CurrentLine.find_first_of(" >",p1+1);\r
132         if (p2 == CurrentLine.npos) p2 = p1+1;\r
133         return CurrentLine.substr(p1,p2-p1);\r
134       }\r
135     } else {   // beginning brace "<" not found; this is a regular data line\r
136       pos = CurrentLine.find_first_not_of(" ");\r
137       if (pos != CurrentLine.npos) {  // first character in line found\r
138         p2 = CurrentLine.find_first_of(" ",pos+1);\r
139         if (p2 != CurrentLine.npos) {\r
140           return CurrentLine.substr(pos,p2-pos);\r
141         } else {\r
142           return CurrentLine.substr(pos,CurrentLine.length()-pos);\r
143         }\r
144       }\r
145     }\r
146   } else { // return a value for a specific tag\r
147     pos = CurrentLine.find(val);\r
148     if (pos != CurrentLine.npos) {\r
149       pos = CurrentLine.find("=",pos);\r
150       if (pos != CurrentLine.npos) {\r
151         ptest = CurrentLine.find_first_not_of(" ",pos+1);\r
152         if (ptest != CurrentLine.npos) {\r
153           p1 = ptest + 1;\r
154           if (CurrentLine[ptest] == '"') { // quoted\r
155             p2 = CurrentLine.find_first_of("\"",p1);\r
156           } else { // not quoted\r
157             p2 = CurrentLine.find_first_of(" ",p1);\r
158           }\r
159           if (p2 != CurrentLine.npos) {\r
160             return CurrentLine.substr(p1,p2-p1);\r
161           }\r
162         }\r
163       } else {   // "=" not found\r
164         pos = CurrentLine.find(val);\r
165         pos = CurrentLine.find_first_of(" ",pos+1);\r
166         ptest = CurrentLine.find_first_not_of(" ",pos+1);\r
167         if (ptest != CurrentLine.npos) {\r
168           if (CurrentLine[ptest] == '"') { // quoted\r
169             p1 = ptest + 1;\r
170             p2 = CurrentLine.find_first_of("\"",p1);\r
171           } else { // not quoted\r
172             p1 = ptest;\r
173             p2 = CurrentLine.find_first_of(" ",p1);\r
174           }\r
175           if (p2 != CurrentLine.npos) {\r
176             return CurrentLine.substr(p1,p2-p1);\r
177           } else {\r
178             p2 = CurrentLine.length();\r
179             return CurrentLine.substr(p1,p2-p1);\r
180           }\r
181         }\r
182       }\r
183     }\r
184   }\r
185 \r
186   return string("");\r
187 }\r
188 \r
189 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
190 \r
191 string FGConfigFile::GetValue(void)\r
192 {\r
193   return GetValue("");\r
194 }\r
195 \r
196 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
197 \r
198 string FGConfigFile::GetLine(void)\r
199 {\r
200   string scratch = "";\r
201   int test;\r
202 \r
203   while ((test = cfgfile.get()) != EOF) {\r
204     if (test >= 0x20 || test == 0x09) {\r
205       if (test == 0x09) {\r
206         scratch += (char)0x20;\r
207       } else {\r
208         scratch += (char)test;\r
209       }\r
210     } else {\r
211       if ((test = cfgfile.get()) != EOF) { // get *next* character\r
212 #if defined ( sgi ) && !defined( __GNUC__ )\r
213         if (test >= 0x20 || test == 0x09) cfgfile.putback(test);\r
214 #else\r
215         if (test >= 0x20 || test == 0x09) cfgfile.unget();\r
216 #endif\r
217         break;\r
218       }\r
219     }\r
220   }\r
221   if (cfgfile.eof()) return string("EOF");\r
222   return scratch;\r
223 }\r
224 \r
225 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
226 /*\r
227 FGConfigFile& FGConfigFile::operator>>(double& val)\r
228 {\r
229   unsigned int pos, end;\r
230 \r
231   pos = CurrentLine.find_first_not_of(", ",CurrentIndex);\r
232   if (pos == CurrentLine.npos) pos = CurrentLine.length();\r
233   end = CurrentLine.find_first_of(", ",pos+1);\r
234   if (end == CurrentLine.npos) end = CurrentLine.length();\r
235   string str = CurrentLine.substr(pos, end - pos);\r
236   val = strtod(str.c_str(),NULL);\r
237   CurrentIndex = end+1;\r
238   if (CurrentIndex >= CurrentLine.length()) GetNextConfigLine();\r
239   return *this;\r
240 }\r
241 */\r
242 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
243 \r
244 FGConfigFile& FGConfigFile::operator>>(double& val)\r
245 {\r
246   unsigned int pos, end;\r
247 \r
248   pos = CurrentLine.find_first_not_of(", ",CurrentIndex);\r
249   if (pos == CurrentLine.npos) pos = CurrentLine.length();\r
250   end = CurrentLine.find_first_of(", ",pos+1);\r
251   if (end == CurrentLine.npos) end = CurrentLine.length();\r
252   string str = CurrentLine.substr(pos, end - pos);\r
253   val = strtod(str.c_str(),NULL);\r
254   CurrentIndex = end+1;\r
255   if (CurrentIndex >= CurrentLine.length()) GetNextConfigLine();\r
256   return *this;\r
257 }\r
258 \r
259 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
260 \r
261 FGConfigFile& FGConfigFile::operator>>(int& val)\r
262 {\r
263   unsigned int pos, end;\r
264 \r
265   pos = CurrentLine.find_first_not_of(", ",CurrentIndex);\r
266   if (pos == CurrentLine.npos) pos = CurrentLine.length();\r
267   end = CurrentLine.find_first_of(", ",pos+1);\r
268   if (end == CurrentLine.npos) end = CurrentLine.length();\r
269   string str = CurrentLine.substr(pos, end - pos);\r
270   val = atoi(str.c_str());\r
271   CurrentIndex = end+1;\r
272   if (CurrentIndex >= CurrentLine.length()) GetNextConfigLine();\r
273   return *this;\r
274 }\r
275 \r
276 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
277 \r
278 FGConfigFile& FGConfigFile::operator>>(eParam& val)\r
279 {\r
280   unsigned int pos, end;\r
281 \r
282   pos = CurrentLine.find_first_not_of(", ",CurrentIndex);\r
283   if (pos == CurrentLine.npos) pos = CurrentLine.length();\r
284   end = CurrentLine.find_first_of(", ",pos+1);\r
285   if (end == CurrentLine.npos) end = CurrentLine.length();\r
286   string str = CurrentLine.substr(pos, end - pos);\r
287   val = (eParam)atoi(str.c_str());\r
288   CurrentIndex = end+1;\r
289   if (CurrentIndex >= CurrentLine.length()) GetNextConfigLine();\r
290   return *this;\r
291 }\r
292 \r
293 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
294 \r
295 FGConfigFile& FGConfigFile::operator>>(string& str)\r
296 {\r
297   unsigned int pos, end;\r
298 \r
299   pos = CurrentLine.find_first_not_of(", ",CurrentIndex);\r
300   if (pos == CurrentLine.npos) pos = CurrentLine.length();\r
301   end = CurrentLine.find_first_of(", ",pos+1);\r
302   if (end == CurrentLine.npos) end = CurrentLine.length();\r
303   str = CurrentLine.substr(pos, end - pos);\r
304   CurrentIndex = end+1;\r
305   if (CurrentIndex >= CurrentLine.length()) GetNextConfigLine();\r
306   return *this;\r
307 }\r
308 \r
309 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
310 \r
311 void FGConfigFile::ResetLineIndexToZero(void)\r
312 {\r
313   CurrentIndex = 0;\r
314 }\r
315 \r
316 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
317 \r
318 void FGConfigFile::Debug(void)\r
319 {\r
320     //TODO: Add your source code here\r
321 }\r
322 \r