#include <stdlib.h>
#include <math.h>
+namespace JSBSim {
+
static const char *IdSrc = "$Id$";
static const char *IdHdr = ID_CONFIGFILE;
-extern short debug_lvl;
-
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS IMPLEMENTATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#endif
else Opened = false;
- if (debug_lvl & 2) cout << "Instantiated: FGConfigFile" << endl;
+ Debug(0);
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FGConfigFile::~FGConfigFile()
{
cfgfile.close();
- if (debug_lvl & 2) cout << "Destroyed: FGConfigFile" << endl;
+ Debug(1);
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
string FGConfigFile::GetNextConfigLine(void)
{
+ int comment_starts_at;
+ int comment_ends_at;
+ int comment_length;
+ int line_length;
+ bool start_comment, end_comment;
+ string CommentStringTemp;
+
do {
CurrentLine = GetLine();
- if ((CurrentLine.find("<COMMENT>") != CurrentLine.npos) ||
- (CurrentLine.find("<!--") != CurrentLine.npos)) CommentsOn = true;
- if ((CurrentLine.find("</COMMENT>") != CurrentLine.npos) ||
- (CurrentLine.find("-->") != CurrentLine.npos)) {
+ line_length = CurrentLine.length();
+ comment_starts_at = CurrentLine.find("<!--");
+
+ if (comment_starts_at >= 0) start_comment = true;
+ else start_comment = false;
+
+ comment_ends_at = CurrentLine.find("-->");
+
+ if (comment_ends_at >= 0) end_comment = true;
+ else end_comment = false;
+
+ if (!start_comment && !end_comment) { // command comment
+ if (CommentsOn) CommentStringTemp = CurrentLine;
+ CommentString += CommentStringTemp + "\r\n";
+ } else if (start_comment && comment_ends_at > comment_starts_at) { // <!-- ... -->
+ CommentsOn = false;
+ comment_length = comment_ends_at + 2 - comment_starts_at + 1;
+ LineComment = CurrentLine.substr(comment_starts_at+4, comment_length-4-3);
+ CurrentLine.erase(comment_starts_at, comment_length);
+ if (CurrentLine.find_first_not_of(" ") == string::npos) {
+ CurrentLine.erase();
+ }
+ } else if ( start_comment && !end_comment) { // <!-- ...
+ CommentsOn = true;
+ comment_length = line_length - comment_starts_at;
+ CommentStringTemp = CurrentLine.substr(comment_starts_at+4, comment_length-4);
+ CommentString = CommentStringTemp + "\r\n";
+ CurrentLine.erase(comment_starts_at, comment_length);
+ } else if (!start_comment && end_comment) { // ... -->
+ CommentsOn = false;
+ comment_length = comment_ends_at + 2 + 1;
+ CommentStringTemp = CurrentLine.substr(0, comment_length-4);
+ CommentString += CommentStringTemp + "\r\n";
+ CurrentLine.erase(0, comment_length);
+ } else if (start_comment && comment_ends_at < comment_starts_at) { // --> command <!--
+ cerr << "Old comment ends and new one starts - bad JSBSim config file form." << endl;
CommentsOn = false;
- GetNextConfigLine();
+ comment_length = comment_ends_at + 2 + 1;
+ CommentStringTemp = CurrentLine.substr(0, comment_length-4);
+ CommentString += CommentStringTemp + "\r\n";
+ CurrentLine.erase(0, comment_length);
}
- } while (IsCommentLine());
- if (CurrentLine.length() == 0) GetNextConfigLine();
+ } while (CommentsOn);
+
CurrentIndex = 0;
+ if (CurrentLine.length() == 0) {
+ GetNextConfigLine();
+ }
return CurrentLine;
}
string FGConfigFile::GetValue(string val)
{
- unsigned int pos, p1, p2, ptest;
+ string::size_type pos, p1, p2, ptest;
if (val == "") { // this call is to return the tag value
pos = CurrentLine.find("<");
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-bool FGConfigFile::IsCommentLine(void)
-{
- if (CurrentLine[0] == '/' && CurrentLine[1] == '/') return true;
- if (CommentsOn) return true;
-
- return false;
-}
-
-//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
string FGConfigFile::GetLine(void)
{
string scratch = "";
int test;
while ((test = cfgfile.get()) != EOF) {
- if (test >= 0x20) {
- scratch += (char)test;
+ if (test >= 0x20 || test == 0x09) {
+ if (test == 0x09) {
+ scratch += (char)0x20;
+ } else {
+ scratch += (char)test;
+ }
} else {
- if ((test = cfgfile.get()) != EOF) {
+ if ((test = cfgfile.get()) != EOF) { // get *next* character
#if defined ( sgi ) && !defined( __GNUC__ )
- if (test >= 0x20) cfgfile.putback(test);
+ if (test >= 0x20 || test == 0x09) cfgfile.putback(test);
#else
- if (test >= 0x20) cfgfile.unget();
+ if (test >= 0x20 || test == 0x09) cfgfile.unget();
#endif
break;
}
}
}
- if (cfgfile.eof()) return string("EOF");
- return scratch;
-}
-
-//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-FGConfigFile& FGConfigFile::operator>>(double& val)
-{
- unsigned int pos, end;
+ int index = scratch.find_last_not_of(" ");
+ if (index != string::npos && index < (scratch.size()-1)) {
+ scratch = scratch.substr(0,index+1);
+ }
- pos = CurrentLine.find_first_not_of(", ",CurrentIndex);
- if (pos == CurrentLine.npos) pos = CurrentLine.length();
- end = CurrentLine.find_first_of(", ",pos+1);
- if (end == CurrentLine.npos) end = CurrentLine.length();
- string str = CurrentLine.substr(pos, end - pos);
- val = strtod(str.c_str(),NULL);
- CurrentIndex = end+1;
- if (CurrentIndex >= CurrentLine.length()) GetNextConfigLine();
- return *this;
+ if (cfgfile.eof() && scratch.empty()) return string("EOF");
+ return scratch;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-FGConfigFile& FGConfigFile::operator>>(float& val)
+FGConfigFile& FGConfigFile::operator>>(double& val)
{
- unsigned int pos, end;
+ string::size_type pos, end;
pos = CurrentLine.find_first_not_of(", ",CurrentIndex);
if (pos == CurrentLine.npos) pos = CurrentLine.length();
string str = CurrentLine.substr(pos, end - pos);
val = strtod(str.c_str(),NULL);
CurrentIndex = end+1;
- if (CurrentIndex >= CurrentLine.length()) GetNextConfigLine();
+ if (end == pos) {
+ GetNextConfigLine();
+ *this >> val;
+ } else {
+ if (CurrentIndex >= CurrentLine.length()) GetNextConfigLine();
+ }
return *this;
}
FGConfigFile& FGConfigFile::operator>>(int& val)
{
- unsigned int pos, end;
+ string::size_type pos, end;
pos = CurrentLine.find_first_not_of(", ",CurrentIndex);
if (pos == CurrentLine.npos) pos = CurrentLine.length();
string str = CurrentLine.substr(pos, end - pos);
val = atoi(str.c_str());
CurrentIndex = end+1;
- if (CurrentIndex >= CurrentLine.length()) GetNextConfigLine();
- return *this;
-}
-
-//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-FGConfigFile& FGConfigFile::operator>>(eParam& val)
-{
- unsigned int pos, end;
-
- pos = CurrentLine.find_first_not_of(", ",CurrentIndex);
- if (pos == CurrentLine.npos) pos = CurrentLine.length();
- end = CurrentLine.find_first_of(", ",pos+1);
- if (end == CurrentLine.npos) end = CurrentLine.length();
- string str = CurrentLine.substr(pos, end - pos);
- val = (eParam)atoi(str.c_str());
- CurrentIndex = end+1;
- if (CurrentIndex >= CurrentLine.length()) GetNextConfigLine();
+ if (end == pos) {
+ GetNextConfigLine();
+ *this >> val;
+ } else {
+ if (CurrentIndex >= CurrentLine.length()) GetNextConfigLine();
+ }
return *this;
}
FGConfigFile& FGConfigFile::operator>>(string& str)
{
- unsigned int pos, end;
+ string::size_type pos, end;
pos = CurrentLine.find_first_not_of(", ",CurrentIndex);
if (pos == CurrentLine.npos) pos = CurrentLine.length();
if (end == CurrentLine.npos) end = CurrentLine.length();
str = CurrentLine.substr(pos, end - pos);
CurrentIndex = end+1;
- if (CurrentIndex >= CurrentLine.length()) GetNextConfigLine();
+ if (end == pos) {
+ GetNextConfigLine();
+ *this >> str;
+ } else {
+ if (CurrentIndex >= CurrentLine.length()) GetNextConfigLine();
+ }
return *this;
}
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-void FGConfigFile::Debug(void)
+// The bitmasked value choices are as follows:
+// unset: In this case (the default) JSBSim would only print
+// out the normally expected messages, essentially echoing
+// the config files as they are read. If the environment
+// variable is not set, debug_lvl is set to 1 internally
+// 0: This requests JSBSim not to output any messages
+// whatsoever.
+// 1: This value explicity requests the normal JSBSim
+// startup messages
+// 2: This value asks for a message to be printed out when
+// a class is instantiated
+// 4: When this value is set, a message is displayed when a
+// FGModel object executes its Run() method
+// 8: When this value is set, various runtime state variables
+// are printed out periodically
+// 16: When set various parameters are sanity checked and
+// a message is printed out when they go out of bounds
+
+void FGConfigFile::Debug(int from)
{
- //TODO: Add your source code here
-}
+ if (debug_lvl <= 0) return;
+ if (debug_lvl & 1) { // Standard console startup message output
+ }
+ if (debug_lvl & 2 ) { // Instantiation/Destruction notification
+ if (from == 0) cout << "Instantiated: FGConfigFile" << endl;
+ if (from == 1) cout << "Destroyed: FGConfigFile" << endl;
+ }
+ if (debug_lvl & 4 ) { // Run() method entry print for FGModel-derived objects
+ }
+ if (debug_lvl & 8 ) { // Runtime state variables
+ }
+ if (debug_lvl & 16) { // Sanity checking
+ }
+ if (debug_lvl & 64) {
+ if (from == 0) { // Constructor
+ cout << IdSrc << endl;
+ cout << IdHdr << endl;
+ }
+ }
+}
+}