X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;ds=sidebyside;f=src%2FMain%2Foptions.cxx;h=ad17068e682f48494c07c76a0aa5a11ab0b83697;hb=0c8c8380b1037ca52725e4703cf87ffb6aee77eb;hp=f6de4c80d36598e5d3ff244a5af3c6a0eb5abda7;hpb=8e5eed90d5e469b13494802acee9c340714843ba;p=flightgear.git diff --git a/src/Main/options.cxx b/src/Main/options.cxx index f6de4c80d..ad17068e6 100644 --- a/src/Main/options.cxx +++ b/src/Main/options.cxx @@ -16,7 +16,7 @@ // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software -// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // // $Id$ @@ -35,19 +35,21 @@ #include // strcmp() #include -#include STL_STRING +#include +#include #include #include +#include #include #include +#include // #include // #include // #include // #include -// #include #include #include @@ -58,12 +60,17 @@ #include "options.hxx" #include "util.hxx" #include "viewmgr.hxx" +#include
+using std::string; +using std::sort; +using std::cout; +using std::cerr; +using std::endl; -SG_USING_STD(string); -SG_USING_STD(sort); -SG_USING_NAMESPACE(std); - +#ifndef VERSION +#define VERSION "CVS "__DATE__ +#endif #define NEW_DEFAULT_MODEL_HZ 120 @@ -72,34 +79,23 @@ enum FG_OPTIONS_OK = 0, FG_OPTIONS_HELP = 1, FG_OPTIONS_ERROR = 2, - FG_OPTIONS_VERBOSE_HELP = 3, - FG_OPTIONS_SHOW_AIRCRAFT = 4 + FG_OPTIONS_EXIT = 3, + FG_OPTIONS_VERBOSE_HELP = 4, + FG_OPTIONS_SHOW_AIRCRAFT = 5 }; static double atof( const string& str ) { - -#ifdef __MWERKS__ - // -dw- if ::atof is called, then we get an infinite loop - return std::atof( str.c_str() ); -#else return ::atof( str.c_str() ); -#endif } static int atoi( const string& str ) { -#ifdef __MWERKS__ - // -dw- if ::atoi is called, then we get an infinite loop - return std::atoi( str.c_str() ); -#else return ::atoi( str.c_str() ); -#endif } - /** * Set a few fail-safe default property values. * @@ -111,7 +107,7 @@ void fgSetDefaults () { // set a possibly independent location for scenery data - char *envp = ::getenv( "FG_SCENERY" ); + const char *envp = ::getenv( "FG_SCENERY" ); if ( envp != NULL ) { // fg_root could be anywhere, so default to environmental @@ -127,8 +123,8 @@ fgSetDefaults () fgSetDouble("/position/altitude-ft", -9999.0); // Orientation - fgSetDouble("/orientation/heading-deg", 270); - fgSetDouble("/orientation/roll-deg", 0); + fgSetDouble("/orientation/heading-deg", 9999.0); + fgSetDouble("/orientation/roll-deg", 0.0); fgSetDouble("/orientation/pitch-deg", 0.424); // Velocities @@ -146,8 +142,8 @@ fgSetDefaults () fgSetDouble("/sim/presets/latitude-deg", 9999.0); fgSetDouble("/sim/presets/altitude-ft", -9999.0); - fgSetDouble("/sim/presets/heading-deg", 270); - fgSetDouble("/sim/presets/roll-deg", 0); + fgSetDouble("/sim/presets/heading-deg", 9999.0); + fgSetDouble("/sim/presets/roll-deg", 0.0); fgSetDouble("/sim/presets/pitch-deg", 0.424); fgSetString("/sim/presets/speed-set", "knots"); @@ -172,15 +168,21 @@ fgSetDefaults () // fgSetString("/sim/startup/mouse-pointer", "disabled"); fgSetString("/sim/control-mode", "joystick"); fgSetBool("/sim/auto-coordination", false); -#if !defined(WIN32) - fgSetString("/sim/startup/browser-app", "netscape"); -#else +#if defined(WIN32) fgSetString("/sim/startup/browser-app", "webrun.bat"); +#elif defined(__APPLE__) + fgSetString("/sim/startup/browser-app", "open"); +#elif defined(sgi) + fgSetString("/sim/startup/browser-app", "launchWebJumper"); +#else + envp = ::getenv( "WEBBROWSER" ); + if (!envp) envp = "netscape"; + fgSetString("/sim/startup/browser-app", envp); #endif fgSetString("/sim/logging/priority", "alert"); // Features - fgSetBool("/sim/hud/antialiased", false); + fgSetBool("/sim/hud/color/antialiased", false); fgSetBool("/sim/hud/enable3d", true); fgSetBool("/sim/hud/visibility", false); fgSetBool("/sim/panel/visibility", true); @@ -199,6 +201,8 @@ fgSetDefaults () fgSetBool("/sim/rendering/shading", true); fgSetBool("/sim/rendering/skyblend", true); fgSetBool("/sim/rendering/textures", true); + fgTie( "/sim/rendering/filtering", SGGetTextureFilter, SGSetTextureFilter, false); + fgSetInt("/sim/rendering/filtering", 1); fgSetBool("/sim/rendering/wireframe", false); fgSetBool("/sim/rendering/horizon-effect", false); fgSetBool("/sim/rendering/enhanced-lighting", false); @@ -225,14 +229,11 @@ fgSetDefaults () fgSetBool("/sim/freeze/clock", false); fgSetBool("/sim/freeze/fuel", false); -#ifdef FG_MPLAYER_AS fgSetString("/sim/multiplay/callsign", "callsign"); fgSetString("/sim/multiplay/rxhost", "0"); fgSetString("/sim/multiplay/txhost", "0"); fgSetInt("/sim/multiplay/rxport", 0); fgSetInt("/sim/multiplay/txport", 0); -#endif - } static bool @@ -490,7 +491,7 @@ parse_fov( const string& arg ) { if ( fov < FG_FOV_MIN ) { fov = FG_FOV_MIN; } if ( fov > FG_FOV_MAX ) { fov = FG_FOV_MAX; } - fgSetDouble("/sim/current-view/field-of-view", fov); + fgSetDouble("/sim/view[0]/config/default-field-of-view-deg", fov); // printf("parse_fov(): result = %.4f\n", fov); @@ -502,7 +503,7 @@ parse_fov( const string& arg ) { // // Format is "--protocol=medium,direction,hz,medium_options,..." // -// protocol = { native, nmea, garmin, fgfs, rul, pve, etc. } +// protocol = { native, nmea, garmin, AV400, AV400Sim, fgfs, rul, pve, etc. } // medium = { serial, socket, file, etc. } // direction = { in, out, bi } // hz = number of times to process channel per second (floating @@ -526,64 +527,58 @@ parse_fov( const string& arg ) { static bool add_channel( const string& type, const string& channel_str ) { SG_LOG(SG_GENERAL, SG_INFO, "Channel string = " << channel_str ); - globals->get_channel_options_list()->push_back( type + "," + channel_str ); - - // cout << "here" << endl; - return true; } -// The parse wp and parse flight-plan options don't work anymore, because + +// The parse wp and parse flight-plan options don't work anymore, because // the route manager and the airport subsystems have not yet been initialized -// at this stage. +// at this stage. // Parse --wp=ID[@alt] -static void +static void parse_wp( const string& arg ) { string_list *waypoints = globals->get_initial_waypoints(); if (!waypoints) { waypoints = new string_list; + globals->set_initial_waypoints(waypoints); } waypoints->push_back(arg); - globals->set_initial_waypoints(waypoints); } // Parse --flight-plan=[file] -static bool +static bool parse_flightplan(const string& arg) { - string_list *waypoints = globals->get_initial_waypoints(); - if (!waypoints) - waypoints = new string_list; - sg_gzifstream in(arg.c_str()); - if ( !in.is_open() ) { - return false; - } - while ( true ) { - string line; - -#if defined( macintosh ) - getline( in, line, '\r' ); -#else - getline( in, line, '\n' ); -#endif - - // catch extraneous (DOS) line ending character - if ( line[line.length() - 1] < 32 ) { - line = line.substr( 0, line.length()-1 ); + string_list *waypoints = globals->get_initial_waypoints(); + if (!waypoints) { + waypoints = new string_list; + globals->set_initial_waypoints(waypoints); } - - if ( in.eof() ) { - break; + + sg_gzifstream in(arg.c_str()); + if ( !in.is_open() ) + return false; + + while ( true ) { + string line; + getline( in, line, '\n' ); + + // catch extraneous (DOS) line ending character + if ( line[line.length() - 1] < 32 ) + line = line.substr( 0, line.length()-1 ); + + if ( in.eof() ) + break; + + waypoints->push_back(line); } - waypoints->push_back(line); - } - globals->set_initial_waypoints(waypoints); - return true; + return true; } + static int fgOptLanguage( const char *arg ) { @@ -597,6 +592,8 @@ clearLocation () fgSetString("/sim/presets/airport-id", ""); fgSetString("/sim/presets/vor-id", ""); fgSetString("/sim/presets/ndb-id", ""); + fgSetString("/sim/presets/carrier", ""); + fgSetString("/sim/presets/parkpos", ""); fgSetString("/sim/presets/fix", ""); } @@ -616,6 +613,21 @@ fgOptNDB( const char * arg ) return FG_OPTIONS_OK; } +static int +fgOptCarrier( const char * arg ) +{ + clearLocation(); + fgSetString("/sim/presets/carrier", arg); + return FG_OPTIONS_OK; +} + +static int +fgOptParkpos( const char * arg ) +{ + fgSetString("/sim/presets/parkpos", arg); + return FG_OPTIONS_OK; +} + static int fgOptFIX( const char * arg ) { @@ -860,7 +872,7 @@ fgSetupProxy( const char *arg ) { string options = arg; string host, port, auth; - unsigned int pos; + string::size_type pos; host = port = auth = ""; if ((pos = options.find("@")) != string::npos) @@ -984,7 +996,7 @@ fgOptRandomWind( const char *arg ) static int fgOptWind( const char *arg ) { - double min_hdg, max_hdg, speed, gust; + double min_hdg = 0.0, max_hdg = 0.0, speed = 0.0, gust = 0.0; if (!parse_wind( arg, &min_hdg, &max_hdg, &speed, &gust)) { SG_LOG( SG_GENERAL, SG_ALERT, "bad wind value " << arg ); return FG_OPTIONS_ERROR; @@ -1041,7 +1053,7 @@ fgOptConfig( const char *arg ) readProperties(file, globals->get_props()); } catch (const sg_exception &e) { string message = "Error loading config file: "; - message += e.getFormattedMessage(); + message += e.getFormattedMessage() + e.getOrigin(); SG_LOG(SG_INPUT, SG_ALERT, message); exit(2); } @@ -1135,6 +1147,75 @@ fgOptDME( const char *arg ) return FG_OPTIONS_OK; } +static int +fgOptLivery( const char *arg ) +{ + string opt = arg; + string livery_path = "livery/" + opt; + fgSetString("/sim/model/texture-path", livery_path.c_str() ); + return FG_OPTIONS_OK; +} + +static int +fgOptScenario( const char *arg ) +{ + SGPropertyNode_ptr ai_node = fgGetNode( "/sim/ai", true ); + vector scenarii = ai_node->getChildren( "scenario" ); + int index = -1; + for ( size_t i = 0; i < scenarii.size(); ++i ) { + int ind = scenarii[i]->getIndex(); + if ( index < ind ) { + index = ind; + } + } + SGPropertyNode_ptr scenario = ai_node->getNode( "scenario", index + 1, true ); + scenario->setStringValue( arg ); + ai_node->setBoolValue( "enabled", true ); + return FG_OPTIONS_OK; +} + +static int +fgOptRunway( const char *arg ) +{ + fgSetString("/sim/presets/runway", arg ); + fgSetBool("/sim/presets/runway-requested", true ); + return FG_OPTIONS_OK; +} + +static int +fgOptParking( const char *arg ) +{ + cerr << "Processing argument " << arg << endl; + fgSetString("/sim/presets/parking", arg ); + fgSetBool ("/sim/presets/parking-requested", true ); + return FG_OPTIONS_OK; +} + +static int +fgOptVersion( const char *arg ) +{ + cerr << VERSION << endl; + cerr << "FG_ROOT=" << globals->get_fg_root() << endl; + cerr << "FG_HOME=" << fgGetString("/sim/fg-home") << endl; + return FG_OPTIONS_EXIT; +} + +static int +fgOptFpe(const char* arg) +{ + // Actually handled in bootstrap.cxx + return FG_OPTIONS_OK; +} + +static int +fgOptFgviewer(const char* arg) +{ + // Actually handled in bootstrap.cxx + return FG_OPTIONS_OK; +} + + + static map fgOptionMap; /* @@ -1155,7 +1236,7 @@ where: value set to the property if has_param is false func : function called if type==OPTION_FUNC. if has_param is true, the value is passed to the function as a string, otherwise, - 0 is passed. + s_param is passed. For OPTION_DOUBLE and OPTION_INT, the parameter value is converted into a double or an integer and set to the property. @@ -1166,12 +1247,12 @@ where: enum OptionType { OPTION_BOOL, OPTION_STRING, OPTION_DOUBLE, OPTION_INT, OPTION_CHANNEL, OPTION_FUNC }; struct OptionDesc { - char *option; + const char *option; bool has_param; enum OptionType type; - char *property; + const char *property; bool b_param; - char *s_param; + const char *s_param; int (*func)( const char * ); } fgOptionArray[] = { @@ -1187,7 +1268,8 @@ struct OptionDesc { {"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-real-weather-fetch", false, OPTION_BOOL, "/environment/params/real-world-weather-fetch", false, "", 0 }, - {"enable-real-weather-fetch", false, OPTION_BOOL, "/environment/params/real-world-weather-fetch", true, "", 0 }, + {"enable-real-weather-fetch", false, OPTION_BOOL, "/environment/params/real-world-weather-fetch", true, "", 0 }, + {"metar", true, OPTION_STRING, "/environment/metar/data", false, "", 0 }, {"disable-ai-models", false, OPTION_BOOL, "/sim/ai/enabled", false, "", 0 }, {"enable-ai-models", false, OPTION_BOOL, "/sim/ai/enabled", true, "", 0 }, {"disable-freeze", false, OPTION_BOOL, "/sim/freeze/master", false, "", 0 }, @@ -1198,8 +1280,8 @@ struct OptionDesc { {"enable-clock-freeze", false, OPTION_BOOL, "/sim/freeze/clock", true, "", 0 }, {"disable-hud-3d", false, OPTION_BOOL, "/sim/hud/enable3d", false, "", 0 }, {"enable-hud-3d", false, OPTION_BOOL, "/sim/hud/enable3d", true, "", 0 }, - {"disable-anti-alias-hud", false, OPTION_BOOL, "/sim/hud/antialiased", false, "", 0 }, - {"enable-anti-alias-hud", false, OPTION_BOOL, "/sim/hud/antialiased", true, "", 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 }, @@ -1211,13 +1293,14 @@ struct OptionDesc { {"disable-sound", false, OPTION_BOOL, "/sim/sound/pause", true, "", 0 }, {"enable-sound", false, OPTION_BOOL, "/sim/sound/pause", false, "", 0 }, {"airport", true, OPTION_STRING, "/sim/presets/airport-id", false, "", 0 }, - {"airport-id", true, OPTION_STRING, "/sim/presets/airport-id", false, "", 0 }, - {"runway", true, OPTION_STRING, "/sim/presets/runway", false, "", 0 }, + {"runway", true, OPTION_FUNC, "", false, "", fgOptRunway }, {"vor", true, OPTION_FUNC, "", false, "", fgOptVOR }, {"ndb", true, OPTION_FUNC, "", false, "", fgOptNDB }, + {"carrier", true, OPTION_FUNC, "", false, "", fgOptCarrier }, + {"parkpos", true, OPTION_FUNC, "", false, "", fgOptParkpos }, {"fix", true, OPTION_FUNC, "", false, "", fgOptFIX }, - {"offset-distance", true, OPTION_DOUBLE, "/sim/presets/offset-distance", false, "", 0 }, - {"offset-azimuth", true, OPTION_DOUBLE, "/sim/presets/offset-azimuth", false, "", 0 }, + {"offset-distance", true, OPTION_DOUBLE, "/sim/presets/offset-distance-nm", false, "", 0 }, + {"offset-azimuth", true, OPTION_DOUBLE, "/sim/presets/offset-azimuth-deg", false, "", 0 }, {"lon", true, OPTION_FUNC, "", false, "", fgOptLon }, {"lat", true, OPTION_FUNC, "", false, "", fgOptLat }, {"altitude", true, OPTION_FUNC, "", false, "", fgOptAltitude }, @@ -1264,12 +1347,15 @@ struct OptionDesc { {"aspect-ratio-multiplier", true, OPTION_DOUBLE, "/sim/current-view/aspect-ratio-multiplier", false, "", 0 }, {"disable-fullscreen", false, OPTION_BOOL, "/sim/startup/fullscreen", 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 }, {"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 }, {"enable-skyblend", false, OPTION_BOOL, "/sim/rendering/skyblend", true, "", 0 }, {"disable-textures", false, OPTION_BOOL, "/sim/rendering/textures", false, "", 0 }, {"enable-textures", false, OPTION_BOOL, "/sim/rendering/textures", true, "", 0 }, + {"texture-filtering", false, OPTION_INT, "/sim/rendering/filtering", 1, "", 0 }, {"disable-wireframe", false, OPTION_BOOL, "/sim/rendering/wireframe", false, "", 0 }, {"enable-wireframe", false, OPTION_BOOL, "/sim/rendering/wireframe", true, "", 0 }, {"geometry", true, OPTION_FUNC, "", false, "", fgOptGeometry }, @@ -1277,6 +1363,7 @@ struct OptionDesc { {"units-feet", false, OPTION_STRING, "/sim/startup/units", false, "feet", 0 }, {"units-meters", false, OPTION_STRING, "/sim/startup/units", false, "meters", 0 }, {"timeofday", true, OPTION_STRING, "/sim/startup/time-offset-type", false, "noon", 0 }, + {"season", true, OPTION_STRING, "/sim/startup/season", false, "summer", 0 }, {"time-offset", true, OPTION_FUNC, "", false, "", fgOptTimeOffset }, {"time-match-real", false, OPTION_STRING, "/sim/startup/time-offset-type", false, "system-offset", 0 }, {"time-match-local", false, OPTION_STRING, "/sim/startup/time-offset-type", false, "latitude-offset", 0 }, @@ -1296,6 +1383,8 @@ struct OptionDesc { {"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 }, {"garmin", true, OPTION_CHANNEL, "", false, "", 0 }, {"nmea", true, OPTION_CHANNEL, "", false, "", 0 }, {"generic", true, OPTION_CHANNEL, "", false, "", 0 }, @@ -1307,10 +1396,8 @@ struct OptionDesc { {"joyclient", true, OPTION_CHANNEL, "", false, "", 0 }, {"jsclient", true, OPTION_CHANNEL, "", false, "", 0 }, {"proxy", true, OPTION_FUNC, "", false, "", fgSetupProxy }, -#ifdef FG_MPLAYER_AS {"callsign", true, OPTION_STRING, "sim/multiplay/callsign", false, "", 0 }, {"multiplay", true, OPTION_CHANNEL, "", false, "", 0 }, -#endif {"trace-read", true, OPTION_FUNC, "", false, "", fgOptTraceRead }, {"trace-write", true, OPTION_FUNC, "", false, "", fgOptTraceWrite }, {"log-level", true, OPTION_FUNC, "", false, "", fgOptLogLevel }, @@ -1325,6 +1412,7 @@ struct OptionDesc { {"flight-plan", true, OPTION_FUNC, "", false, "", fgOptFlightPlan }, {"config", true, OPTION_FUNC, "", false, "", fgOptConfig }, {"aircraft", true, OPTION_STRING, "/sim/aircraft", false, "", 0 }, + {"vehicle", true, OPTION_STRING, "/sim/aircraft", false, "", 0 }, {"failure", true, OPTION_FUNC, "", false, "", fgOptFailure }, {"com1", true, OPTION_DOUBLE, "/instrumentation/comm[0]/frequencies/selected-mhz", false, "", 0 }, {"com2", true, OPTION_DOUBLE, "/instrumentation/comm[1]/frequencies/selected-mhz", false, "", 0 }, @@ -1333,10 +1421,63 @@ struct OptionDesc { {"adf", true, OPTION_FUNC, "", false, "", fgOptADF }, {"dme", true, OPTION_FUNC, "", false, "", fgOptDME }, {"min-status", true, OPTION_STRING, "/sim/aircraft-min-status", false, "all", 0 }, + {"livery", true, OPTION_FUNC, "", false, "", fgOptLivery }, + {"ai-scenario", true, OPTION_FUNC, "", false, "", fgOptScenario }, + {"parking-id", true, OPTION_FUNC, "", false, "", fgOptParking }, + {"version", false, OPTION_FUNC, "", false, "", fgOptVersion }, + {"enable-fpe", false, OPTION_FUNC, "", false, "", fgOptFpe}, + {"fgviewer", false, OPTION_FUNC, "", false, "", fgOptFgviewer}, {0} }; +// Set a property for the --prop: option. Syntax: --prop:[:]= +// can be "double" etc. but also only the first letter "d". +// Examples: --prop:alpha=1 --prop:bool:beta=true --prop:d:gamma=0.123 +static bool +set_property(const string& arg) +{ + string::size_type pos = arg.find('='); + if (pos == arg.npos || pos == 0 || pos + 1 == arg.size()) + return false; + + string name = arg.substr(0, pos); + string value = arg.substr(pos + 1); + string type; + pos = name.find(':'); + + if (pos != name.npos && pos != 0 && pos + 1 != name.size()) { + type = name.substr(0, pos); + name = name.substr(pos + 1); + } + SGPropertyNode *n = fgGetNode(name.c_str(), true); + + bool writable = n->getAttribute(SGPropertyNode::WRITE); + if (!writable) + n->setAttribute(SGPropertyNode::WRITE, true); + + bool ret = false; + if (type.empty()) + ret = n->setUnspecifiedValue(value.c_str()); + else if (type == "s" || type == "string") + ret = n->setStringValue(value.c_str()); + else if (type == "d" || type == "double") + ret = n->setDoubleValue(strtod(value.c_str(), 0)); + else if (type == "f" || type == "float") + ret = n->setFloatValue(atof(value.c_str())); + else if (type == "l" || type == "long") + ret = n->setLongValue(strtol(value.c_str(), 0, 0)); + else if (type == "i" || type == "int") + ret = n->setIntValue(atoi(value.c_str())); + else if (type == "b" || type == "bool") + ret = n->setBoolValue(value == "true" || atoi(value.c_str()) != 0); + + if (!writable) + n->setAttribute(SGPropertyNode::WRITE, false); + return ret; +} + + // Parse a single option static int parse_option (const string& arg) @@ -1361,24 +1502,18 @@ parse_option (const string& arg) } else if ( arg.find( "--show-aircraft") == 0) { return(FG_OPTIONS_SHOW_AIRCRAFT); } else if ( arg.find( "--prop:" ) == 0 ) { - string assign = arg.substr(7); - string::size_type pos = assign.find('='); - if ( pos == arg.npos || pos == 0 ) { - SG_LOG( SG_GENERAL, SG_ALERT, "Bad property assignment: " << arg ); - return FG_OPTIONS_ERROR; - } - string name = assign.substr(0, pos); - string value = assign.substr(pos + 1); - fgSetString(name.c_str(), value.c_str()); - // SG_LOG(SG_GENERAL, SG_INFO, "Setting default value of property " - // << name << " to \"" << value << '"'); + if (!set_property(arg.substr(7))) { + SG_LOG( SG_GENERAL, SG_ALERT, "Bad property assignment: " << arg ); + return FG_OPTIONS_ERROR; + } } else if ( arg.find( "--" ) == 0 ) { size_t pos = arg.find( '=' ); - string arg_name; + string arg_name, arg_value; if ( pos == string::npos ) { arg_name = arg.substr( 2 ); } else { arg_name = arg.substr( 2, pos - 2 ); + arg_value = arg.substr( pos + 1); } map::iterator it = fgOptionMap.find( arg_name ); if ( it != fgOptionMap.end() ) { @@ -1388,9 +1523,9 @@ parse_option (const string& arg) fgSetBool( pt->property, pt->b_param ); break; case OPTION_STRING: - if ( pt->has_param && pos != string::npos ) { - fgSetString( pt->property, arg.substr( pos + 1 ).c_str() ); - } else if ( !pt->has_param && pos == string::npos ) { + if ( pt->has_param && !arg_value.empty() ) { + fgSetString( pt->property, arg_value.c_str() ); + } else if ( !pt->has_param && arg_value.empty() ) { fgSetString( pt->property, pt->s_param ); } else if ( pt->has_param ) { SG_LOG( SG_GENERAL, SG_ALERT, "Option '" << arg << "' needs a parameter" ); @@ -1401,25 +1536,25 @@ parse_option (const string& arg) } break; case OPTION_DOUBLE: - if ( pos != string::npos ) { - fgSetDouble( pt->property, atof( arg.substr( pos + 1 ) ) ); + if ( !arg_value.empty() ) { + fgSetDouble( pt->property, atof( arg_value ) ); } else { SG_LOG( SG_GENERAL, SG_ALERT, "Option '" << arg << "' needs a parameter" ); return FG_OPTIONS_ERROR; } break; case OPTION_INT: - if ( pos != string::npos ) { - fgSetInt( pt->property, atoi( arg.substr( pos + 1 ) ) ); + if ( !arg_value.empty() ) { + fgSetInt( pt->property, atoi( arg_value ) ); } else { SG_LOG( SG_GENERAL, SG_ALERT, "Option '" << arg << "' needs a parameter" ); return FG_OPTIONS_ERROR; } break; case OPTION_CHANNEL: - if ( pt->has_param && pos != string::npos ) { - add_channel( pt->option, arg.substr( pos + 1 ) ); - } else if ( !pt->has_param && pos == string::npos ) { + if ( pt->has_param && !arg_value.empty() ) { + add_channel( pt->option, arg_value ); + } else if ( !pt->has_param && arg_value.empty() ) { add_channel( pt->option, pt->s_param ); } else if ( pt->has_param ) { SG_LOG( SG_GENERAL, SG_ALERT, "Option '" << arg << "' needs a parameter" ); @@ -1430,10 +1565,10 @@ parse_option (const string& arg) } break; case OPTION_FUNC: - if ( pt->has_param && pos != string::npos ) { - return pt->func( arg.substr( pos + 1 ).c_str() ); - } else if ( !pt->has_param && pos == string::npos ) { - return pt->func( 0 ); + if ( pt->has_param && !arg_value.empty() ) { + return pt->func( arg_value.c_str() ); + } else if ( !pt->has_param && arg_value.empty() ) { + return pt->func( pt->s_param ); } else if ( pt->has_param ) { SG_LOG( SG_GENERAL, SG_ALERT, "Option '" << arg << "' needs a parameter" ); return FG_OPTIONS_ERROR; @@ -1487,6 +1622,9 @@ fgParseArgs (int argc, char **argv) fgShowAircraft(path, true); exit(0); } + + else if (result == FG_OPTIONS_EXIT) + exit(0); } } else { in_options = false; @@ -1517,20 +1655,9 @@ fgParseOptions (const string& path) { SG_LOG( SG_GENERAL, SG_INFO, "Processing config file: " << path ); in >> skipcomment; -#ifndef __MWERKS__ while ( ! in.eof() ) { -#else - char c = '\0'; - while ( in.get(c) && c != '\0' ) { - in.putback(c); -#endif string line; - -#if defined( macintosh ) - getline( in, line, '\r' ); -#else getline( in, line, '\n' ); -#endif // catch extraneous (DOS) line ending character int i; @@ -1563,7 +1690,7 @@ fgUsage (bool verbose) try { fgLoadProps("options.xml", &options_root); - } catch (const sg_exception &ex) { + } catch (const sg_exception &) { cout << "Unable to read the help file." << endl; cout << "Make sure the file options.xml is located in the FlightGear base directory," << endl; cout << "and the location of the base directory is specified by setting $FG_ROOT or" << endl; @@ -1595,7 +1722,7 @@ fgUsage (bool verbose) SGPropertyNode *short_name = option[k]->getNode("short"); SGPropertyNode *key = option[k]->getNode("key"); SGPropertyNode *arg = option[k]->getNode("arg"); - bool brief = option[k]->getNode("brief"); + bool brief = option[k]->getNode("brief") != 0; if ((brief || verbose) && name) { string tmp = name->getStringValue(); @@ -1612,21 +1739,21 @@ fgUsage (bool verbose) tmp.append(", -"); tmp.append(short_name->getStringValue()); } - - char cstr[96]; + if (tmp.size() <= 25) { - snprintf(cstr, 96, " --%-27s", tmp.c_str()); + msg+= " --"; + msg += tmp; + msg.append( 27-tmp.size(), ' '); } else { - snprintf(cstr, 96, "\n --%s\n%32c", tmp.c_str(), ' '); + msg += "\n --"; + msg += tmp + '\n'; + msg.append(32, ' '); } - // There may be more than one tag assosiated // with one option - msg += cstr; - vectordesc = - option[k]->getChildren("description"); - + vector desc; + desc = option[k]->getChildren("description"); if (desc.size() > 0) { for ( unsigned int l = 0; l < desc.size(); l++) { @@ -1641,9 +1768,7 @@ fgUsage (bool verbose) string t_str = trans_desc[m]->getStringValue(); if ((m > 0) || ((l > 0) && m == 0)) { - snprintf(cstr, 96, "%32c", ' '); - msg += cstr; - + msg.append( 32, ' '); } // If the string is too large to fit on the screen, @@ -1652,9 +1777,8 @@ fgUsage (bool verbose) while ( t_str.size() > 47 ) { unsigned int m = t_str.rfind(' ', 47); - msg += t_str.substr(0, m); - snprintf(cstr, 96, "\n%32c", ' '); - msg += cstr; + msg += t_str.substr(0, m) + '\n'; + msg.append( 32, ' '); t_str.erase(t_str.begin(), t_str.begin() + m + 1); } @@ -1665,8 +1789,8 @@ fgUsage (bool verbose) } } - SGPropertyNode *name = - locale->getNode(section[j]->getStringValue("name")); + SGPropertyNode *name; + name = locale->getNode(section[j]->getStringValue("name")); if (!msg.empty() && name) { cout << endl << name->getStringValue() << ":" << endl; @@ -1691,9 +1815,9 @@ unsigned int getNumMaturity(const char * str) { // changes should also be reflected in $FG_ROOT/data/options.xml & // $FG_ROOT/data/Translations/string-default.xml - const char levels[][20]= {"alpha","beta","early-production","production",0}; + const char* levels[] = {"alpha","beta","early-production","production"}; - for (unsigned int i=0; i<(sizeof(levels)/sizeof(levels[0])-1);i++) + for (size_t i=0; i<(sizeof(levels)/sizeof(levels[0]));i++) if (strcmp(str,levels[i])==0) return i; @@ -1708,7 +1832,7 @@ static void fgSearchAircraft(const SGPath &path, string_list &aircraft, ulDirEnt* dire; ulDir *dirp = ulOpenDir(path.str().c_str()); if (dirp == NULL) { - cerr << "Unable to open aircraft directory." << endl; + cerr << "Unable to open aircraft directory '" << path.str() << '\'' << endl; exit(-1); } @@ -1749,25 +1873,27 @@ static void fgSearchAircraft(const SGPath &path, string_list &aircraft, status = node->getNode("status"); } - char cstr[96]; - //additionally display status information where it is available - - if (strlen(dire->d_name) <= 27) { - snprintf(cstr, 96, " %-27s %s", dire->d_name, - (desc) ? desc->getStringValue() : ""); - - } else { - snprintf(cstr, 96, " %-27s\n%32c%s", dire->d_name, ' ', - (desc) ? desc->getStringValue() : ""); + //additionally display status information where it is available + + string descStr(" "); + descStr += dire->d_name; + if (desc) { + if (descStr.size() <= 27+3) { + descStr.append(29+3-descStr.size(), ' '); + } else { + descStr += '\n'; + descStr.append( 32, ' '); + } + descStr += desc->getStringValue(); } - - SGPropertyNode * required_status + + SGPropertyNode * required_status = fgGetNode ("/sim/aircraft-min-status", true); // If the node holds the value "all", then there wasn't any status // level specified, so we simply go ahead and output ALL aircraft if (strcmp(required_status->getStringValue(),"all")==0) { - aircraft.push_back(cstr); + aircraft.push_back(descStr); } else { @@ -1779,7 +1905,7 @@ static void fgSearchAircraft(const SGPath &path, string_list &aircraft, //Compare (minimally) required status level with actual aircraft status: if ( getNumMaturity(status->getStringValue() ) >= getNumMaturity(required_status->getStringValue() ) ) - aircraft.push_back(cstr); } + aircraft.push_back(descStr); } }