From 386d87e098f37a2785b854c0c8b523737e5cab43 Mon Sep 17 00:00:00 2001 From: James Turner Date: Tue, 15 Oct 2013 22:16:50 +0100 Subject: [PATCH] Cleanup exit handling. Replace many lingering calls to exit() from the code, replacing most with exception throws, which can be caught by the existing mechanisms. Update the option-parsing code to return an explicit value indicating what to do (e.g., exit status to return to the shell). --- src/Airports/apt_loader.cxx | 4 ++-- src/Airports/runwayprefs.cxx | 3 ++- src/Airports/sidstar.cxx | 1 - src/Main/fg_init.cxx | 14 +++++--------- src/Main/fg_init.hxx | 2 +- src/Main/main.cxx | 15 ++++++++------- src/Main/options.cxx | 36 +++++++++++++++--------------------- src/Main/options.hxx | 21 ++++++++++++++++++--- src/Navaids/fixlist.cxx | 4 ++-- src/Sound/voiceplayer.cxx | 12 ++---------- src/Systems/electrical.cxx | 8 +------- src/Traffic/TrafficMgr.cxx | 7 +++++-- src/Viewer/fgviewer.cxx | 13 +++++++------ 13 files changed, 68 insertions(+), 72 deletions(-) diff --git a/src/Airports/apt_loader.cxx b/src/Airports/apt_loader.cxx index 5833c02c3..f2f3b7120 100644 --- a/src/Airports/apt_loader.cxx +++ b/src/Airports/apt_loader.cxx @@ -90,7 +90,7 @@ public: if ( !in.is_open() ) { SG_LOG( SG_GENERAL, SG_ALERT, "Cannot open file: " << aptdb_file ); - exit(-1); + throw sg_io_exception("cannot open APT file", aptdb_file); } string line; @@ -186,7 +186,7 @@ public: } else { SG_LOG( SG_GENERAL, SG_ALERT, "Unknown line(#" << line_num << ") in apt.dat file: " << line ); - exit( -1 ); + throw sg_format_exception("malformed line in apt.dat:", line); } } diff --git a/src/Airports/runwayprefs.cxx b/src/Airports/runwayprefs.cxx index 46c9bcb58..e6f1eb68a 100644 --- a/src/Airports/runwayprefs.cxx +++ b/src/Airports/runwayprefs.cxx @@ -34,6 +34,7 @@ #include #include #include +#include #include
#include @@ -100,7 +101,7 @@ std::string ScheduleTime::getName(time_t dayStart) if ((start.size() != end.size()) || (start.size() != scheduleNames.size())) { SG_LOG(SG_GENERAL, SG_INFO, "Unable to parse schedule times"); - exit(1); + throw sg_exception("Unable to parse schedule times"); } else { int nrItems = start.size(); //cerr << "Nr of items to process: " << nrItems << endl; diff --git a/src/Airports/sidstar.cxx b/src/Airports/sidstar.cxx index a95119482..ad8d61344 100644 --- a/src/Airports/sidstar.cxx +++ b/src/Airports/sidstar.cxx @@ -44,7 +44,6 @@ FGSidStar::FGSidStar(FGAirport *ap) { FGSidStar::FGSidStar(const FGSidStar &other) { cerr << "TODO" << endl; - exit(1); } void FGSidStar::load(SGPath filename) { diff --git a/src/Main/fg_init.cxx b/src/Main/fg_init.cxx index 82bf86f95..07488ac64 100644 --- a/src/Main/fg_init.cxx +++ b/src/Main/fg_init.cxx @@ -409,7 +409,7 @@ void fgInitHome() } // Read in configuration (file and command line) -bool fgInitConfig ( int argc, char **argv ) +int fgInitConfig ( int argc, char **argv ) { SGPath dataPath = globals->get_fg_home(); @@ -453,14 +453,12 @@ bool fgInitConfig ( int argc, char **argv ) FindAndCacheAircraft f(globals->get_props()); if (!f.loadAircraft()) { - return false; + return flightgear::FG_OPTIONS_ERROR; } // parse options after loading aircraft to ensure any user // overrides of defaults are honored. - options->processOptions(); - - return true; + return options->processOptions(); } @@ -510,7 +508,7 @@ bool fgInitGeneral() { SG_LOG( SG_GENERAL, SG_ALERT, "Cannot continue without a path to the base package " << "being defined." ); - exit(-1); + return false; } SG_LOG( SG_GENERAL, SG_INFO, "FG_ROOT = " << '"' << root << '"' << endl ); @@ -599,9 +597,7 @@ void fgCreateSubsystems() { mpath.append( fgGetString("/sim/rendering/materials-file") ); if ( ! globals->get_matlib()->load(globals->get_fg_root(), mpath.str(), globals->get_props()) ) { - SG_LOG( SG_GENERAL, SG_ALERT, - "Error loading materials file " << mpath.str() ); - exit(-1); + throw sg_io_exception("Error loading materials file", mpath); } globals->add_subsystem( "http", new FGHTTPClient ); diff --git a/src/Main/fg_init.hxx b/src/Main/fg_init.hxx index 2d81cc82b..5329b0381 100644 --- a/src/Main/fg_init.hxx +++ b/src/Main/fg_init.hxx @@ -37,7 +37,7 @@ std::string fgBasePackageVersion(); void fgInitHome(); // Read in configuration (file and command line) -bool fgInitConfig ( int argc, char **argv ); +int fgInitConfig ( int argc, char **argv ); // log various settings / configuration state diff --git a/src/Main/main.cxx b/src/Main/main.cxx index 4ca387e21..792362632 100644 --- a/src/Main/main.cxx +++ b/src/Main/main.cxx @@ -65,6 +65,7 @@ #include "fg_props.hxx" #include "positioninit.hxx" #include "subsystemFactory.hxx" +#include "options.hxx" using namespace flightgear; @@ -164,9 +165,7 @@ static void fgIdleFunction ( void ) { // Do some quick general initializations if( !fgInitGeneral()) { - SG_LOG( SG_GENERAL, SG_ALERT, - "General initialization failed ..." ); - exit(-1); + throw sg_exception("General initialization failed"); } //////////////////////////////////////////////////////////////////// @@ -344,11 +343,13 @@ int fgMainInit( int argc, char **argv ) { // Load the configuration parameters. (Command line options // override config file options. Config file options override // defaults.) - if ( !fgInitConfig(argc, argv) ) { - SG_LOG( SG_GENERAL, SG_ALERT, "Config option parsing failed ..." ); - exit(-1); + int configResult = fgInitConfig(argc, argv); + if (configResult == flightgear::FG_OPTIONS_ERROR) { + return EXIT_FAILURE; + } else if (configResult == flightgear::FG_OPTIONS_EXIT) { + return EXIT_SUCCESS; } - + // Initialize the Window/Graphics environment. fgOSInit(&argc, argv); _bootstrap_OSInit++; diff --git a/src/Main/options.cxx b/src/Main/options.cxx index 5ec12cdec..261343b13 100644 --- a/src/Main/options.cxx +++ b/src/Main/options.cxx @@ -84,19 +84,9 @@ using std::endl; using std::vector; using std::cin; -#define NEW_DEFAULT_MODEL_HZ 120 +using namespace flightgear; -enum -{ - FG_OPTIONS_OK = 0, - FG_OPTIONS_HELP = 1, - FG_OPTIONS_ERROR = 2, - FG_OPTIONS_EXIT = 3, - FG_OPTIONS_VERBOSE_HELP = 4, - FG_OPTIONS_SHOW_AIRCRAFT = 5, - FG_OPTIONS_SHOW_SOUND_DEVICES = 6, - FG_OPTIONS_NO_DEFAULT_CONFIG = 7 -}; +#define NEW_DEFAULT_MODEL_HZ 120 static flightgear::Options* shared_instance = NULL; @@ -1016,12 +1006,12 @@ fgOptConfig( const char *arg ) { string file = arg; try { - readProperties(file, globals->get_props()); + readProperties(file, globals->get_props()); } catch (const sg_exception &e) { - string message = "Error loading config file: "; - message += e.getFormattedMessage() + e.getOrigin(); - SG_LOG(SG_INPUT, SG_ALERT, message); - exit(2); + string message = "Error loading config file: "; + message += e.getFormattedMessage() + e.getOrigin(); + SG_LOG(SG_INPUT, SG_ALERT, message); + return FG_OPTIONS_ERROR; } return FG_OPTIONS_OK; } @@ -1988,7 +1978,7 @@ string_list Options::valuesForOption(const std::string& key) const return result; } -void Options::processOptions() +OptionResult Options::processOptions() { // establish locale before showing help (this selects the default locale, // when no explicit option was set) @@ -1998,7 +1988,7 @@ void Options::processOptions() // out quickly, but rely on aircraft / root settings if (p->showHelp) { showUsage(); - exit(0); + return FG_OPTIONS_EXIT; } // processing order is complicated. We must process groups LIFO, but the @@ -2018,9 +2008,11 @@ void Options::processOptions() { case FG_OPTIONS_ERROR: showUsage(); - exit(-1); // exit and return an error + return FG_OPTIONS_ERROR; + case FG_OPTIONS_EXIT: - exit(0); // clean exit + return FG_OPTIONS_EXIT; + default: break; } @@ -2085,6 +2077,8 @@ void Options::processOptions() root.append("Scenery"); globals->append_fg_scenery(root.str()); } + + return FG_OPTIONS_OK; } void Options::showUsage() const diff --git a/src/Main/options.hxx b/src/Main/options.hxx index 082d4a430..7765ecffe 100644 --- a/src/Main/options.hxx +++ b/src/Main/options.hxx @@ -34,7 +34,22 @@ class SGPath; namespace flightgear { - + +/// option processing can have various result values +/// depending on what the user requested. Note processOptions only +/// returns a subset of these. +enum OptionResult +{ + FG_OPTIONS_OK = 0, + FG_OPTIONS_HELP = 1, + FG_OPTIONS_ERROR = 2, + FG_OPTIONS_EXIT = 3, + FG_OPTIONS_VERBOSE_HELP = 4, + FG_OPTIONS_SHOW_AIRCRAFT = 5, + FG_OPTIONS_SHOW_SOUND_DEVICES = 6, + FG_OPTIONS_NO_DEFAULT_CONFIG = 7 +}; + class Options { private: @@ -80,9 +95,9 @@ public: /** * apply option values to the simulation state - * (set properties, etc) + * (set properties, etc). */ - void processOptions(); + OptionResult processOptions(); /** * init the aircraft options diff --git a/src/Navaids/fixlist.cxx b/src/Navaids/fixlist.cxx index 2dc8806ea..27ece5744 100644 --- a/src/Navaids/fixlist.cxx +++ b/src/Navaids/fixlist.cxx @@ -31,6 +31,7 @@ #include #include #include +#include #include "fixlist.hxx" #include @@ -49,8 +50,7 @@ void loadFixes(const SGPath& path) { sg_gzifstream in( path.str() ); if ( !in.is_open() ) { - SG_LOG( SG_NAVAID, SG_ALERT, "Cannot open file: " << path.str() ); - exit(-1); + throw sg_io_exception("Cannot open file:", path); } // toss the first two lines of the file diff --git a/src/Sound/voiceplayer.cxx b/src/Sound/voiceplayer.cxx index 6e12b083d..583443ded 100644 --- a/src/Sound/voiceplayer.cxx +++ b/src/Sound/voiceplayer.cxx @@ -249,16 +249,8 @@ FGVoicePlayer::get_sample (const char *name) if (! sample) { string filename = dir_prefix + string(name) + ".wav"; - try - { - sample = new SGSoundSample(filename.c_str(), SGPath()); - } - catch (const sg_exception &e) - { - SG_LOG(SG_SOUND, SG_ALERT, "Error loading sound sample \"" + filename + "\": " + e.getFormattedMessage()); - exit(1); - } - + sample = new SGSoundSample(filename.c_str(), SGPath()); + _sgr->add(sample, refname); samples[refname] = sample; } diff --git a/src/Systems/electrical.cxx b/src/Systems/electrical.cxx index 947df0aae..ebe684cc9 100644 --- a/src/Systems/electrical.cxx +++ b/src/Systems/electrical.cxx @@ -386,13 +386,7 @@ void FGElectricalSystem::init () { if ( build(config_props) ) { enabled = true; } else { - SG_LOG( SG_SYSTEMS, SG_ALERT, - "Detected a logic error in the electrical system "); - SG_LOG( SG_SYSTEMS, SG_ALERT, - "specification file. See earlier errors for " ); - SG_LOG( SG_SYSTEMS, SG_ALERT, - "details."); - exit(-1); + throw sg_exception("Logic error in electrical system file."); } } catch (const sg_exception&) { SG_LOG( SG_SYSTEMS, SG_ALERT, diff --git a/src/Traffic/TrafficMgr.cxx b/src/Traffic/TrafficMgr.cxx index 51d7154d7..d36645b46 100644 --- a/src/Traffic/TrafficMgr.cxx +++ b/src/Traffic/TrafficMgr.cxx @@ -57,6 +57,8 @@ #include #include #include +#include + #include #include #include @@ -709,9 +711,10 @@ void FGTrafficManager::readTimeTableFromFile(SGPath infileName) if (!tokens.empty()) { if (tokens[0] == string("AC")) { if (tokens.size() != 13) { - SG_LOG(SG_AI, SG_ALERT, "Error parsing traffic file " << infileName.str() << " at " << buffString); - exit(1); + throw sg_io_exception("Error parsing traffic file @ " + buffString, sg_location(infileName.str())); } + + model = tokens[12]; livery = tokens[6]; homePort = tokens[1]; diff --git a/src/Viewer/fgviewer.cxx b/src/Viewer/fgviewer.cxx index 757266926..0e98613dd 100644 --- a/src/Viewer/fgviewer.cxx +++ b/src/Viewer/fgviewer.cxx @@ -29,6 +29,7 @@ #include #include #include +#include #include @@ -170,9 +171,11 @@ fgviewerMain(int argc, char** argv) globals = new FGGlobals; - if ( !fgInitConfig(arguments.argc(), arguments.argv()) ) { - SG_LOG( SG_GENERAL, SG_ALERT, "Config option parsing failed ..." ); - exit(-1); + int configResult = fgInitConfig(arguments.argc(), arguments.argv()); + if (configResult == flightgear::FG_OPTIONS_ERROR) { + return EXIT_FAILURE; + } else if (configResult == flightgear::FG_OPTIONS_EXIT) { + return EXIT_SUCCESS; } osgDB::FilePathList filePathList @@ -193,9 +196,7 @@ fgviewerMain(int argc, char** argv) mpath.append( fgGetString("/sim/rendering/materials-file") ); if ( ! globals->get_matlib()->load(globals->get_fg_root(), mpath.str(), globals->get_props()) ) { - SG_LOG( SG_GENERAL, SG_ALERT, - "Error loading materials file " << mpath.str() ); - exit(-1); + throw sg_io_exception("Error loading materials file", mpath); } globals->set_scenery( new FGScenery ); -- 2.39.5