#include "fg_props.hxx"
#include "options.hxx"
#include "util.hxx"
-#include "viewmgr.hxx"
-#include <Main/viewer.hxx>
+#include "main.hxx"
+#include "locale.hxx"
+#include <Viewer/viewer.hxx>
+#include <Viewer/viewmgr.hxx>
#include <Environment/presets.hxx>
#include <osg/Version>
using std::cerr;
using std::endl;
using std::vector;
+using std::cin;
#define NEW_DEFAULT_MODEL_HZ 120
-// defined in bootstrap.cxx
-extern char *homedir;
-extern char *hostname;
-
enum
{
FG_OPTIONS_OK = 0,
// specified so we can do the right thing for voodoo-1/2 cards.
// fgSetString("/sim/startup/mouse-pointer", "disabled");
fgSetString("/sim/control-mode", "joystick");
- fgSetBool("/sim/auto-coordination", false);
+ fgSetBool("/controls/flight/auto-coordination", false);
#if defined(WIN32)
fgSetString("/sim/startup/browser-app", "webrun.bat");
#elif defined(__APPLE__)
return true;
}
+static bool
+parseIntValue(char** ppParserPos, int* pValue,int min, int max, const char* field, const char* argument)
+{
+ if ( !strlen(*ppParserPos) )
+ return true;
+
+ char num[256];
+ int i = 0;
+
+ while ( isdigit((*ppParserPos)[0]) && (i<255) )
+ {
+ num[i] = (*ppParserPos)[0];
+ (*ppParserPos)++;
+ i++;
+ }
+ num[i] = '\0';
+
+ switch ((*ppParserPos)[0])
+ {
+ case 0:
+ break;
+ case ':':
+ (*ppParserPos)++;
+ break;
+ default:
+ SG_LOG(SG_GENERAL, SG_ALERT, "Illegal character in time string for " << field << ": '" <<
+ (*ppParserPos)[0] << "'.");
+ // invalid field - skip rest of string to avoid further errors
+ while ((*ppParserPos)[0])
+ (*ppParserPos)++;
+ return false;
+ }
+
+ if (i<=0)
+ return true;
+
+ int value = atoi(num);
+ if ((value < min)||(value > max))
+ {
+ SG_LOG(SG_GENERAL, SG_ALERT, "Invalid " << field << " in '" << argument <<
+ "'. Valid range is " << min << "-" << max << ".");
+ return false;
+ }
+ else
+ {
+ *pValue = value;
+ return true;
+ }
+}
+
// parse a time string ([+/-]%f[:%f[:%f]]) into hours
static double
parse_time(const string& time_in) {
return(sign * result);
}
-
// parse a date string (yyyy:mm:dd:hh:mm:ss) into a time_t (seconds)
static long int
-parse_date( const string& date)
+parse_date( const string& date, const char* timeType)
{
- struct tm gmt;
- char * date_str, num[256];
- int i;
- // initialize to zero
- gmt.tm_sec = 0;
- gmt.tm_min = 0;
- gmt.tm_hour = 0;
- gmt.tm_mday = 0;
- gmt.tm_mon = 0;
- gmt.tm_year = 0;
- gmt.tm_isdst = 0; // ignore daylight savings time for the moment
- date_str = (char *)date.c_str();
- // get year
- if ( strlen(date_str) ) {
- i = 0;
- while ( (date_str[0] != ':') && (date_str[0] != '\0') ) {
- num[i] = date_str[0];
- date_str++;
- i++;
- }
- if ( date_str[0] == ':' ) {
- date_str++;
- }
- num[i] = '\0';
- gmt.tm_year = atoi(num) - 1900;
- }
- // get month
- if ( strlen(date_str) ) {
- i = 0;
- while ( (date_str[0] != ':') && (date_str[0] != '\0') ) {
- num[i] = date_str[0];
- date_str++;
- i++;
- }
- if ( date_str[0] == ':' ) {
- date_str++;
- }
- num[i] = '\0';
- gmt.tm_mon = atoi(num) -1;
- }
- // get day
- if ( strlen(date_str) ) {
- i = 0;
- while ( (date_str[0] != ':') && (date_str[0] != '\0') ) {
- num[i] = date_str[0];
- date_str++;
- i++;
- }
- if ( date_str[0] == ':' ) {
- date_str++;
- }
- num[i] = '\0';
- gmt.tm_mday = atoi(num);
- }
- // get hour
- if ( strlen(date_str) ) {
- i = 0;
- while ( (date_str[0] != ':') && (date_str[0] != '\0') ) {
- num[i] = date_str[0];
- date_str++;
- i++;
- }
- if ( date_str[0] == ':' ) {
- date_str++;
- }
- num[i] = '\0';
- gmt.tm_hour = atoi(num);
- }
- // get minute
- if ( strlen(date_str) ) {
- i = 0;
- while ( (date_str[0] != ':') && (date_str[0] != '\0') ) {
- num[i] = date_str[0];
- date_str++;
- i++;
- }
- if ( date_str[0] == ':' ) {
- date_str++;
- }
- num[i] = '\0';
- gmt.tm_min = atoi(num);
+ struct tm gmt,*pCurrentTime;
+ int year,month,day,hour,minute,second;
+ char *argument, *date_str;
+
+ SGTime CurrentTime = SGTime();
+ CurrentTime.update(0,0,0,0);
+
+ // FIXME This should obtain system/aircraft/GMT time depending on timeType
+ pCurrentTime = CurrentTime.getGmt();
+
+ // initialize all fields with current time
+ year = pCurrentTime->tm_year + 1900;
+ month = pCurrentTime->tm_mon + 1;
+ day = pCurrentTime->tm_mday;
+ hour = pCurrentTime->tm_hour;
+ minute = pCurrentTime->tm_min;
+ second = pCurrentTime->tm_sec;
+
+ argument = (char *)date.c_str();
+ date_str = argument;
+
+ // start with parsing year
+ if (!strlen(date_str) ||
+ !parseIntValue(&date_str,&year,0,9999,"year",argument))
+ {
+ return -1;
}
- // get second
- if ( strlen(date_str) ) {
- i = 0;
- while ( (date_str[0] != ':') && (date_str[0] != '\0') ) {
- num[i] = date_str[0];
- date_str++;
- i++;
- }
- if ( date_str[0] == ':' ) {
- date_str++;
- }
- num[i] = '\0';
- gmt.tm_sec = atoi(num);
+
+ if (year < 1970)
+ {
+ SG_LOG(SG_GENERAL, SG_ALERT, "Invalid year '" << year << "'. Use 1970 or later.");
+ return -1;
}
+
+ parseIntValue(&date_str, &month, 1, 12, "month", argument);
+ parseIntValue(&date_str, &day, 1, 31, "day", argument);
+ parseIntValue(&date_str, &hour, 0, 23, "hour", argument);
+ parseIntValue(&date_str, &minute, 0, 59, "minute", argument);
+ parseIntValue(&date_str, &second, 0, 59, "second", argument);
+
+ gmt.tm_sec = second;
+ gmt.tm_min = minute;
+ gmt.tm_hour = hour;
+ gmt.tm_mday = day;
+ gmt.tm_mon = month - 1;
+ gmt.tm_year = year -1900;
+ gmt.tm_isdst = 0; // ignore daylight savings time for the moment
+
time_t theTime = sgTimeGetGMT( gmt.tm_year, gmt.tm_mon, gmt.tm_mday,
- gmt.tm_hour, gmt.tm_min, gmt.tm_sec );
- //printf ("Date is %s\n", ctime(&theTime));
- //printf ("in seconds that is %d\n", theTime);
- //exit(1);
+ gmt.tm_hour, gmt.tm_min, gmt.tm_sec );
+
+ SG_LOG(SG_GENERAL, SG_INFO, "Configuring startup time to " << ctime(&theTime));
+
return (theTime);
}
// parse time offset string into seconds
-static int
+static long int
parse_time_offset( const string& time_str) {
- int result;
+ long int result;
// printf("time offset = %s\n", time_str);
return true;
}
-static int
-fgOptLanguage( const char *arg )
-{
- globals->set_locale( fgInitLocale( arg ) );
- return FG_OPTIONS_OK;
-}
-
static void
clearLocation ()
{
static int
fgOptRoc( const char *arg )
{
- fgSetDouble("/velocities/vertical-speed-fps", atof(arg)/60);
+ fgSetDouble("/sim/presets/vertical-speed-fps", atof(arg)/60);
return FG_OPTIONS_OK;
}
static int
fgOptTimeOffset( const char *arg )
{
- fgSetInt("/sim/startup/time-offset",
+ fgSetLong("/sim/startup/time-offset",
parse_time_offset( arg ));
fgSetString("/sim/startup/time-offset-type", "system-offset");
return FG_OPTIONS_OK;
static int
fgOptStartDateSys( const char *arg )
{
- fgSetInt("/sim/startup/time-offset", parse_date( arg ) );
- fgSetString("/sim/startup/time-offset-type", "system");
+ long int theTime = parse_date( arg, "system" );
+ if (theTime>=0)
+ {
+ fgSetLong("/sim/startup/time-offset", theTime);
+ fgSetString("/sim/startup/time-offset-type", "system");
+ }
return FG_OPTIONS_OK;
}
static int
fgOptStartDateLat( const char *arg )
{
- fgSetInt("/sim/startup/time-offset", parse_date( arg ) );
- fgSetString("/sim/startup/time-offset-type", "latitude");
+ long int theTime = parse_date( arg, "latitude" );
+ if (theTime>=0)
+ {
+ fgSetLong("/sim/startup/time-offset", theTime);
+ fgSetString("/sim/startup/time-offset-type", "latitude");
+ }
return FG_OPTIONS_OK;
}
static int
fgOptStartDateGmt( const char *arg )
{
- fgSetInt("/sim/startup/time-offset", parse_date( arg ) );
- fgSetString("/sim/startup/time-offset-type", "gmt");
+ long int theTime = parse_date( arg, "gmt" );
+ if (theTime>=0)
+ {
+ fgSetLong("/sim/startup/time-offset", theTime);
+ fgSetString("/sim/startup/time-offset-type", "gmt");
+ }
return FG_OPTIONS_OK;
}
static int
fgOptLogLevel( const char *arg )
{
- fgSetString("/sim/logging/classes", "all");
fgSetString("/sim/logging/priority", arg);
-
- string priority = arg;
- logbuf::set_log_classes(SG_ALL);
- if (priority == "bulk") {
- logbuf::set_log_priority(SG_BULK);
- } else if (priority == "debug") {
- logbuf::set_log_priority(SG_DEBUG);
- } else if (priority == "info") {
- logbuf::set_log_priority(SG_INFO);
- } else if (priority == "warn") {
- logbuf::set_log_priority(SG_WARN);
- } else if (priority == "alert") {
- logbuf::set_log_priority(SG_ALERT);
- } else {
- SG_LOG(SG_GENERAL, SG_WARN, "Unknown logging priority " << priority);
- }
- SG_LOG(SG_GENERAL, SG_DEBUG, "Logging priority is " << priority);
+ setLoggingPriority(arg);
return FG_OPTIONS_OK;
}
+static int
+fgOptLogClasses( const char *arg )
+{
+ fgSetString("/sim/logging/classes", arg);
+ setLoggingClasses (arg);
+
+ return FG_OPTIONS_OK;
+}
static int
fgOptTraceWrite( const char *arg )
}
SGPropertyNode_ptr scenario = ai_node->getNode( "scenario", index + 1, true );
scenario->setStringValue( arg );
- ai_node->setBoolValue( "enabled", true );
+ ai_node->setBoolValue( "scenarios-enabled", true );
return FG_OPTIONS_OK;
}
{
SGPropertyNode_ptr ai_node = fgGetNode( "/sim/ai", true );
ai_node->removeChildren("scenario",false);
- ai_node->setBoolValue( "enabled", false );
+ ai_node->setBoolValue( "scenarios-enabled", false );
return FG_OPTIONS_OK;
}
int (*func)( const char * );
} fgOptionArray[] = {
- {"language", true, OPTION_FUNC, "", false, "", fgOptLanguage },
+ {"language", true, OPTION_IGNORE, "", false, "", 0 },
+ {"disable-rembrandt", false, OPTION_BOOL, "/sim/rendering/rembrandt/enabled", false, "", 0 },
+ {"enable-rembrandt", false, OPTION_BOOL, "/sim/rendering/rembrandt/enabled", true, "", 0 },
+ {"renderer", true, OPTION_STRING, "/sim/rendering/rembrandt/renderer", false, "", 0 },
{"disable-game-mode", false, OPTION_BOOL, "/sim/startup/game-mode", false, "", 0 },
{"enable-game-mode", false, OPTION_BOOL, "/sim/startup/game-mode", true, "", 0 },
{"disable-splash-screen", false, OPTION_BOOL, "/sim/startup/splash-screen", false, "", 0 },
{"enable-mouse-pointer", false, OPTION_STRING, "/sim/startup/mouse-pointer", false, "enabled", 0 },
{"disable-random-objects", false, OPTION_BOOL, "/sim/rendering/random-objects", false, "", 0 },
{"enable-random-objects", false, OPTION_BOOL, "/sim/rendering/random-objects", true, "", 0 },
+ {"disable-random-vegetation", false, OPTION_BOOL, "/sim/rendering/random-vegetation", false, "", 0 },
+ {"enable-random-vegetation", false, OPTION_BOOL, "/sim/rendering/random-vegetation", true, "", 0 },
+ {"disable-random-buildings", false, OPTION_BOOL, "/sim/rendering/random-buildings", false, "", 0 },
+ {"enable-random-buildings", false, OPTION_BOOL, "/sim/rendering/random-buildings", true, "", 0 },
{"disable-real-weather-fetch", false, OPTION_BOOL, "/environment/realwx/enabled", false, "", 0 },
{"enable-real-weather-fetch", false, OPTION_BOOL, "/environment/realwx/enabled", true, "", 0 },
{"metar", true, OPTION_STRING, "/environment/metar/data", false, "", 0 },
{"disable-anti-alias-hud", false, OPTION_BOOL, "/sim/hud/color/antialiased", false, "", 0 },
{"enable-anti-alias-hud", false, OPTION_BOOL, "/sim/hud/color/antialiased", true, "", 0 },
{"control", true, OPTION_STRING, "/sim/control-mode", false, "", 0 },
- {"disable-auto-coordination", false, OPTION_BOOL, "/sim/auto-coordination", false, "", 0 },
- {"enable-auto-coordination", false, OPTION_BOOL, "/sim/auto-coordination", true, "", 0 },
+ {"disable-auto-coordination", false, OPTION_BOOL, "/controls/flight/auto-coordination", false, "", 0 },
+ {"enable-auto-coordination", false, OPTION_BOOL, "/controls/flight/auto-coordination", true, "", 0 },
{"browser-app", true, OPTION_STRING, "/sim/startup/browser-app", false, "", 0 },
{"disable-hud", false, OPTION_BOOL, "/sim/hud/visibility[1]", false, "", 0 },
{"enable-hud", false, OPTION_BOOL, "/sim/hud/visibility[1]", true, "", 0 },
{"aero", true, OPTION_STRING, "/sim/aero", false, "", 0 },
{"aircraft-dir", true, OPTION_IGNORE, "", false, "", 0 },
{"model-hz", true, OPTION_INT, "/sim/model-hz", false, "", 0 },
+ {"max-fps", true, OPTION_DOUBLE, "/sim/frame-rate-throttle-hz", false, "", 0 },
{"speed", true, OPTION_INT, "/sim/speed-up", false, "", 0 },
{"trim", false, OPTION_BOOL, "/sim/presets/trim", true, "", 0 },
{"notrim", false, OPTION_BOOL, "/sim/presets/trim", false, "", 0 },
{"enable-fullscreen", false, OPTION_BOOL, "/sim/startup/fullscreen", true, "", 0 },
{"disable-save-on-exit", false, OPTION_BOOL, "/sim/startup/save-on-exit", false, "", 0 },
{"enable-save-on-exit", false, OPTION_BOOL, "/sim/startup/save-on-exit", true, "", 0 },
+ {"restore-defaults", false, OPTION_BOOL, "/sim/startup/restore-defaults", true, "", 0 },
{"shading-flat", false, OPTION_BOOL, "/sim/rendering/shading", false, "", 0 },
{"shading-smooth", false, OPTION_BOOL, "/sim/rendering/shading", true, "", 0 },
{"disable-skyblend", false, OPTION_BOOL, "/sim/rendering/skyblend", false, "", 0 },
{"hud-tris", false, OPTION_STRING, "/sim/hud/frame-stat-type", false, "tris", 0 },
{"hud-culled", false, OPTION_STRING, "/sim/hud/frame-stat-type", false, "culled", 0 },
{"atcsim", true, OPTION_CHANNEL, "", false, "dummy", 0 },
- {"atlas", true, OPTION_CHANNEL, "", false, "", 0 },
+ {"atlas", true, OPTION_CHANNEL | OPTION_MULTI, "", false, "", 0 },
{"httpd", true, OPTION_CHANNEL, "", false, "", 0 },
#ifdef FG_JPEG_SERVER
{"jpg-httpd", true, OPTION_CHANNEL, "", false, "", 0 },
#endif
- {"native", true, OPTION_CHANNEL, "", false, "", 0 },
- {"native-ctrls", true, OPTION_CHANNEL, "", false, "", 0 },
- {"native-fdm", true, OPTION_CHANNEL, "", false, "", 0 },
- {"native-gui", true, OPTION_CHANNEL, "", false, "", 0 },
- {"opengc", true, OPTION_CHANNEL, "", false, "", 0 },
- {"AV400", true, OPTION_CHANNEL, "", false, "", 0 },
- {"AV400Sim", true, OPTION_CHANNEL, "", false, "", 0 },
- {"AV400WSimA", true, OPTION_CHANNEL, "", false, "", 0 },
- {"AV400WSimB", true, OPTION_CHANNEL, "", false, "", 0 },
- {"garmin", true, OPTION_CHANNEL, "", false, "", 0 },
+ {"native", true, OPTION_CHANNEL | OPTION_MULTI, "", false, "", 0 },
+ {"native-ctrls", true, OPTION_CHANNEL | OPTION_MULTI, "", false, "", 0 },
+ {"native-fdm", true, OPTION_CHANNEL | OPTION_MULTI, "", false, "", 0 },
+ {"native-gui", true, OPTION_CHANNEL | OPTION_MULTI, "", false, "", 0 },
+ {"opengc", true, OPTION_CHANNEL | OPTION_MULTI, "", false, "", 0 },
+ {"AV400", true, OPTION_CHANNEL | OPTION_MULTI, "", false, "", 0 },
+ {"AV400Sim", true, OPTION_CHANNEL | OPTION_MULTI, "", false, "", 0 },
+ {"AV400WSimA", true, OPTION_CHANNEL | OPTION_MULTI, "", false, "", 0 },
+ {"AV400WSimB", true, OPTION_CHANNEL | OPTION_MULTI, "", false, "", 0 },
+ {"garmin", true, OPTION_CHANNEL | OPTION_MULTI, "", false, "", 0 },
{"nmea", true, OPTION_CHANNEL | OPTION_MULTI, "", false, "", 0 },
{"generic", true, OPTION_CHANNEL | OPTION_MULTI, "", false, "", 0 },
{"props", true, OPTION_CHANNEL | OPTION_MULTI, "", false, "", 0 },
{"jsclient", true, OPTION_CHANNEL, "", false, "", 0 },
{"proxy", true, OPTION_FUNC, "", false, "", fgSetupProxy },
{"callsign", true, OPTION_FUNC, "", false, "", fgOptCallSign},
- {"multiplay", true, OPTION_CHANNEL, "", false, "", 0 },
+ {"multiplay", true, OPTION_CHANNEL | OPTION_MULTI, "", false, "", 0 },
#ifdef FG_HAVE_HLA
{"hla", true, OPTION_CHANNEL, "", false, "", 0 },
#endif
- {"trace-read", true, OPTION_FUNC, "", false, "", fgOptTraceRead },
- {"trace-write", true, OPTION_FUNC, "", false, "", fgOptTraceWrite },
+ {"trace-read", true, OPTION_FUNC | OPTION_MULTI, "", false, "", fgOptTraceRead },
+ {"trace-write", true, OPTION_FUNC | OPTION_MULTI, "", false, "", fgOptTraceWrite },
{"log-level", true, OPTION_FUNC, "", false, "", fgOptLogLevel },
+ {"log-class", true, OPTION_FUNC, "", false, "", fgOptLogClasses },
{"view-offset", true, OPTION_FUNC | OPTION_MULTI, "", false, "", fgOptViewOffset },
{"visibility", true, OPTION_FUNC, "", false, "", fgOptVisibilityMeters },
{"visibility-miles", true, OPTION_FUNC, "", false, "", fgOptVisibilityMiles },
{
OptionValueVec::const_iterator it = values.begin();
for (; it != values.end(); ++it) {
+ if (!it->desc) {
+ continue; // ignore markers
+ }
+
if (it->desc->option == key) {
return it;
}
int processOption(OptionDesc* desc, const string& arg_value)
{
+ if (!desc) {
+ return FG_OPTIONS_OK; // tolerate marker options
+ }
+
switch ( desc->type & 0xffff ) {
case OPTION_BOOL:
fgSetBool( desc->property, desc->b_param );
return FG_OPTIONS_OK;
}
+
+ /**
+ * insert a marker value into the values vector. This is necessary
+ * when processing options, to ensure the correct ordering, where we scan
+ * for marker values in reverse, and then forwards within each group.
+ */
+ void insertGroupMarker()
+ {
+ values.push_back(OptionValue(NULL, "-"));
+ }
+
+ /**
+ * given a current iterator into the values, find the preceeding group marker,
+ * or return the beginning of the value vector.
+ */
+ OptionValueVec::const_iterator rfindGroup(OptionValueVec::const_iterator pos) const
+ {
+ while (--pos != values.begin()) {
+ if (pos->desc == NULL) {
+ return pos; // found a marker, we're done
+ }
+ }
+
+ return pos;
+ }
bool showHelp,
verbose,
showAircraft;
+
OptionDescDict options;
OptionValueVec values;
simgear::PathList propertyFiles;
p->propertyFiles.push_back(f);
}
} // of arguments iteration
+ p->insertGroupMarker(); // command line is one group
+ // establish log-level before anything else - otherwise it is not possible
+ // to show extra (debug/info/warning) messages for the start-up phase.
+ fgOptLogLevel(valueForOption("log-level", "alert").c_str());
+
// then config files
SGPath config;
- if( homedir && hostname && strlen(hostname) > 0 ) {
+ if( homedir.size() && hostname.size() ) {
// Check for ~/.fgfsrc.hostname
config.set(homedir);
config.append(".fgfsrc");
}
// Check for ~/.fgfsrc
- if( homedir ) {
+ if( homedir.size() ) {
config.set(homedir);
config.append(".fgfsrc");
readConfig(config);
setupRoot();
// system.fgfsrc handling
- if( hostname && strlen(hostname) > 0 ) {
+ if( hostname.size() > 0 ) {
config.set(globals->get_fg_root());
config.append( "system.fgfsrc" );
config.concat( "." );
in >> skipcomment;
}
+ p->insertGroupMarker(); // each config file is a group
}
int Options::parseOption(const string& s)
{
OptionDesc* desc = p->findOption(key);
if (!desc) {
+ SG_LOG(SG_GENERAL, SG_ALERT, "unknown option:" << key);
return FG_OPTIONS_ERROR;
}
string_list result;
OptionValueVec::const_iterator it = p->values.begin();
for (; it != p->values.end(); ++it) {
+ if (!it->desc) {
+ continue; // ignore marker values
+ }
+
if (it->desc->option == key) {
result.push_back(it->value);
}
return result;
}
-
+
void Options::processOptions()
{
+ // establish locale before showing help (this selects the default locale,
+ // when no explicit option was set)
+ globals->get_locale()->selectLanguage(valueForOption("language").c_str());
+
// now FG_ROOT is setup, process various command line options that bail us
// out quickly, but rely on aircraft / root settings
if (p->showHelp) {
exit(0);
}
- BOOST_FOREACH(const OptionValue& v, p->values) {
- int result = p->processOption(v.desc, v.value);
- if (result == FG_OPTIONS_ERROR) {
- showUsage();
- exit(-1);
+ // processing order is complicated. We must process groups LIFO, but the
+ // values *within* each group in FIFO order, to retain consistency with
+ // older versions of FG, and existing user configs.
+ // in practice this means system.fgfsrc must be *processed* before
+ // .fgfsrc, which must be processed before the command line args, and so on.
+ OptionValueVec::const_iterator groupEnd = p->values.end();
+
+ while (groupEnd != p->values.begin()) {
+ OptionValueVec::const_iterator groupBegin = p->rfindGroup(groupEnd);
+ // run over the group in FIFO order
+ OptionValueVec::const_iterator it;
+ for (it = groupBegin; it != groupEnd; ++it) {
+ int result = p->processOption(it->desc, it->value);
+ switch(result)
+ {
+ case FG_OPTIONS_ERROR:
+ showUsage();
+ exit(-1); // exit and return an error
+ case FG_OPTIONS_EXIT:
+ exit(0); // clean exit
+ default:
+ break;
+ }
}
+
+ groupEnd = groupBegin;
}
-
+
BOOST_FOREACH(const SGPath& file, p->propertyFiles) {
if (!file.exists()) {
SG_LOG(SG_GENERAL, SG_ALERT, "config file not found:" << file.str());
{
fgOptLogLevel( "alert" );
- SGPropertyNode *locale = globals->get_locale();
+ FGLocale *locale = globals->get_locale();
SGPropertyNode options_root;
SG_LOG( SG_GENERAL, SG_ALERT, "" ); // To popup the console on Windows
cout << endl;
-
+
try {
fgLoadProps("options.xml", &options_root);
} catch (const sg_exception &) {
exit(-1);
}
-
+
SGPropertyNode *options = options_root.getNode("options");
if (!options) {
SG_LOG( SG_GENERAL, SG_ALERT,
"Error reading options.xml: <options> directive not found." );
exit(-1);
}
-
- SGPropertyNode *usage = locale->getNode(options->getStringValue("usage"));
+
+ if (!locale->loadResource("options"))
+ {
+ cout << "Unable to read the language resource." << endl;
+ exit(-1);
+ }
+
+ const char* usage = locale->getLocalizedString(options->getStringValue("usage"), "options");
if (usage) {
- cout << "Usage: " << usage->getStringValue() << endl;
+ cout << usage << endl;
}
vector<SGPropertyNode_ptr>section = options->getChildren("section");
msg += tmp + '\n';
msg.append(32, ' ');
}
- // There may be more than one <description> tag assosiated
+ // There may be more than one <description> tag associated
// with one option
vector<SGPropertyNode_ptr> desc;
desc = option[k]->getChildren("description");
if (desc.size() > 0) {
for ( unsigned int l = 0; l < desc.size(); l++) {
-
- // There may be more than one translation line.
-
string t = desc[l]->getStringValue();
- SGPropertyNode *n = locale->getNode("strings");
- vector<SGPropertyNode_ptr>trans_desc =
- n->getChildren(t.substr(8).c_str());
-
+
+ // There may be more than one translation line.
+ vector<SGPropertyNode_ptr>trans_desc = locale->getLocalizedStrings(t.c_str(),"options");
for ( unsigned int m = 0; m < trans_desc.size(); m++ ) {
string t_str = trans_desc[m]->getStringValue();
}
}
- SGPropertyNode *name;
- name = locale->getNode(section[j]->getStringValue("name"));
-
+ const char* name = locale->getLocalizedString(section[j]->getStringValue("name"),"options");
if (!msg.empty() && name) {
- cout << endl << name->getStringValue() << ":" << endl;
+ cout << endl << name << ":" << endl;
cout << msg;
msg.erase();
}
}
if ( !p->verbose ) {
- cout << endl;
- cout << "For a complete list of options use --help --verbose" << endl;
+ const char* verbose_help = locale->getLocalizedString(options->getStringValue("verbose-help"),"options");
+ if (verbose_help)
+ cout << endl << verbose_help << endl;
}
#ifdef _MSC_VER
- cout << "Hit a key to continue..." << endl;
- cin.get();
+ std::cout << "Hit a key to continue..." << std::endl;
+ std::cin.get();
#endif
}
globals->set_fg_root(root);
// validate it
- static char required_version[] = "2.5.0";
+ static char required_version[] = FLIGHTGEAR_VERSION;
string base_version = fgBasePackageVersion();
if ( !(base_version == required_version) ) {
// tell the operator how to use this application