diff --git a/src/App/Application.cpp b/src/App/Application.cpp index 17b99601f..e6a399926 100644 --- a/src/App/Application.cpp +++ b/src/App/Application.cpp @@ -1188,13 +1188,13 @@ void Application::processCmdLineFiles(void) Application::_pcSingleton->openDocument(File.filePath().c_str()); } else if (File.hasExtension("fcscript")||File.hasExtension("fcmacro")) { - Base::Interpreter().runFile(File.filePath().c_str(), false); + Base::Interpreter().runFile(File.filePath().c_str(), true); } else if (File.hasExtension("py")) { //FIXME: Does this make any sense? I think we should do the ame as for // fcmacro or fcscript. //Base::Interpreter().loadModule(File.fileNamePure().c_str()); - Base::Interpreter().runFile(File.filePath().c_str(), false); + Base::Interpreter().runFile(File.filePath().c_str(), true); } else { std::vector mods = App::GetApplication().getImportModules(Ext.c_str()); @@ -1210,8 +1210,7 @@ void Application::processCmdLineFiles(void) } } catch (const Base::SystemExitException&) { - Base::PyGILStateLocker locker; - Base::Interpreter().systemExit(); + throw; // re-throw to main() function } catch (const Base::Exception& e) { Console().Error("Exception while processing file: %s [%s]\n", File.filePath().c_str(), e.what()); @@ -1523,20 +1522,23 @@ void Application::ParseOptions(int ac, char ** av) notify(vm); } catch (const std::exception& e) { - cerr << e.what() << endl << endl << visible << endl; - exit(1); + std::stringstream str; + str << e.what() << endl << endl << visible << endl; + throw UnknownProgramOption(str.str()); } catch (...) { - cerr << "Wrong or unknown option, bailing out!" << endl << endl << visible << endl; - exit(1); + std::stringstream str; + str << "Wrong or unknown option, bailing out!" << endl << endl << visible << endl; + throw UnknownProgramOption(str.str()); } if (vm.count("help")) { - cout << mConfig["ExeName"] << endl << endl; - cout << "For detailed descripton see http://free-cad.sf.net" << endl<().c_str()); if (!ifs) { Base::Console().Error("Could no open the response file\n"); - cerr << "Could no open the response file: '" - << vm["response-file"].as() << "'" << endl; - exit(1); + std::stringstream str; + str << "Could no open the response file: '" + << vm["response-file"].as() << "'" << endl; + throw Base::UnknownProgramOption(str.str()); } // Read the whole file into a string stringstream ss; @@ -1562,9 +1565,10 @@ void Application::ParseOptions(int ac, char ** av) } if (vm.count("version")) { - std::cout << mConfig["ExeName"] << " " << mConfig["ExeVersion"] - << " Revision: " << mConfig["BuildRevision"] << std::endl; - exit(0); + std::stringstream str; + str << mConfig["ExeName"] << " " << mConfig["ExeVersion"] + << " Revision: " << mConfig["BuildRevision"] << std::endl; + throw Base::ProgramInformation(str.str()); } if (vm.count("console")) { diff --git a/src/Base/Exception.cpp b/src/Base/Exception.cpp index e573c2735..4ca62890c 100644 --- a/src/Base/Exception.cpp +++ b/src/Base/Exception.cpp @@ -202,6 +202,40 @@ AbnormalProgramTermination::AbnormalProgramTermination(const AbnormalProgramTerm // --------------------------------------------------------- +UnknownProgramOption::UnknownProgramOption(const char * sMessage) + : Exception(sMessage) +{ +} + +UnknownProgramOption::UnknownProgramOption(const std::string& sMessage) + : Exception(sMessage) +{ +} + +UnknownProgramOption::UnknownProgramOption(const UnknownProgramOption &inst) + : Exception(inst) +{ +} + +// --------------------------------------------------------- + +ProgramInformation::ProgramInformation(const char * sMessage) + : Exception(sMessage) +{ +} + +ProgramInformation::ProgramInformation(const std::string& sMessage) + : Exception(sMessage) +{ +} + +ProgramInformation::ProgramInformation(const ProgramInformation &inst) + : Exception(inst) +{ +} + +// --------------------------------------------------------- + #if defined(__GNUC__) && defined (FC_OS_LINUX) #include #include diff --git a/src/Base/Exception.h b/src/Base/Exception.h index f50fdb7d3..19bd9155c 100644 --- a/src/Base/Exception.h +++ b/src/Base/Exception.h @@ -174,6 +174,38 @@ public: virtual ~AbnormalProgramTermination() throw() {} }; +/** + * The UnknownProgramOption can be used to indicate an unknown program option. + * @author Werner Mayer + */ +class BaseExport UnknownProgramOption : public Exception +{ +public: + /// Construction + UnknownProgramOption(const char * sMessage); + UnknownProgramOption(const std::string& sMessage); + /// Construction + UnknownProgramOption(const UnknownProgramOption &inst); + /// Destruction + virtual ~UnknownProgramOption() throw() {} +}; + +/** + * The ProgramInformation can be used to show information about the program. + * @author Werner Mayer + */ +class BaseExport ProgramInformation : public Exception +{ +public: + /// Construction + ProgramInformation(const char * sMessage); + ProgramInformation(const std::string& sMessage); + /// Construction + ProgramInformation(const ProgramInformation &inst); + /// Destruction + virtual ~ProgramInformation() throw() {} +}; + inline void Exception::setMessage(const char * sMessage) { diff --git a/src/Base/Interpreter.cpp b/src/Base/Interpreter.cpp index 0a8c4b9e8..a1ddd5a7a 100644 --- a/src/Base/Interpreter.cpp +++ b/src/Base/Interpreter.cpp @@ -190,7 +190,6 @@ void InterpreterSingleton::runInteractiveString(const char *sCmd) presult = PyRun_String(sCmd, Py_single_input, dict, dict); /* eval direct */ if (!presult) { if (PyErr_ExceptionMatches(PyExc_SystemExit)) { - //systemExit(); throw SystemExitException(); } /* get latest python exception information */ diff --git a/src/Gui/Macro.cpp b/src/Gui/Macro.cpp index 89f9fab1a..1ac796478 100644 --- a/src/Gui/Macro.cpp +++ b/src/Gui/Macro.cpp @@ -26,6 +26,7 @@ #ifndef _PreComp_ # include # include +# include # include # include #endif @@ -232,9 +233,7 @@ void MacroManager::run(MacroType eType,const char *sName) Base::Interpreter().runFile(sName, this->localEnv); } catch (const Base::SystemExitException&) { - Base::PyGILStateLocker lock; - PyErr_Clear(); - Base::Interpreter().systemExit(); + qApp->quit(); } catch (const Base::PyException& e) { Base::Console().Error("%s%s: %s\n", diff --git a/src/Gui/MainWindow.cpp b/src/Gui/MainWindow.cpp index 365fc7605..a13a16c2c 100644 --- a/src/Gui/MainWindow.cpp +++ b/src/Gui/MainWindow.cpp @@ -52,6 +52,7 @@ #include #include #include +#include #include #include #include @@ -1152,7 +1153,13 @@ void MainWindow::showMainWindow() void MainWindow::delayedStartup() { // processing all command line files - App::Application::processCmdLineFiles(); + try { + App::Application::processCmdLineFiles(); + } + catch (const Base::SystemExitException&) { + QApplication::quit(); + return; + } const std::map& cfg = App::Application::Config(); std::map::const_iterator it = cfg.find("StartHidden"); diff --git a/src/Gui/PythonConsole.cpp b/src/Gui/PythonConsole.cpp index edccd488a..8364ae4e9 100644 --- a/src/Gui/PythonConsole.cpp +++ b/src/Gui/PythonConsole.cpp @@ -23,6 +23,7 @@ #include "PreCompiled.h" #ifndef _PreComp_ +# include # include # include # include @@ -700,12 +701,13 @@ void PythonConsole::runSource(const QString& line) catch (const Base::SystemExitException&) { ParameterGrp::handle hPrefGrp = getWindowParameter(); bool check = hPrefGrp->GetBool("CheckSystemExit",true); - if (!check) Base::Interpreter().systemExit(); + if (!check) qApp->quit(); int ret = QMessageBox::question(this, tr("System exit"), tr("The application is still running.\nDo you want to exit without saving your data?"), QMessageBox::Yes, QMessageBox::No|QMessageBox::Escape|QMessageBox::Default); if (ret == QMessageBox::Yes) { - Base::Interpreter().systemExit(); - } else { + qApp->quit(); + } + else { PyErr_Clear(); } } diff --git a/src/Gui/View3DInventorExamples.cpp b/src/Gui/View3DInventorExamples.cpp index 99510a005..c7e5a1b4f 100644 --- a/src/Gui/View3DInventorExamples.cpp +++ b/src/Gui/View3DInventorExamples.cpp @@ -311,7 +311,7 @@ void LightManip(SoSeparator * root) in.setBuffer((void *)scenegraph, std::strlen(scenegraph)); SoSeparator * _root = SoDB::readAll( &in ); root->addChild(_root); - if ( root == NULL ) exit( 1 ); // Shouldn't happen. + if ( root == NULL ) return; // Shouldn't happen. root->ref(); const char * pointlightnames[3] = { "RedLight", "GreenLight", "BlueLight" }; @@ -323,7 +323,7 @@ void LightManip(SoSeparator * root) sa.setSearchingAll( FALSE ); sa.apply( root ); SoPath * path = sa.getPath(); - if ( path == NULL) exit( 1 ); // Shouldn't happen. + if ( path == NULL) return; // Shouldn't happen. SoPointLightManip * manip = new SoPointLightManip; manip->replaceNode( path ); @@ -446,7 +446,7 @@ void AnimationTexture(SoSeparator * root) texturetimer->schedule(); // Scene graph - if ( root == NULL ) exit( 1 ); // Shouldn't happen. + if ( root == NULL ) return; // Shouldn't happen. root->ref(); // prevent from being deleted because of the still running timer sensor // SoSeparator * root = new SoSeparator; // root->ref(); diff --git a/src/Main/MainCmd.cpp b/src/Main/MainCmd.cpp index f42d7598b..4fcae2687 100644 --- a/src/Main/MainCmd.cpp +++ b/src/Main/MainCmd.cpp @@ -37,6 +37,7 @@ #include #include +#include // FreeCAD Base header #include @@ -89,6 +90,14 @@ int main( int argc, char ** argv ) // Inits the Application App::Application::init(argc,argv); } + catch (const Base::UnknownProgramOption& e) { + std::cerr << e.what(); + exit(1); + } + catch (const Base::ProgramInformation& e) { + std::cout << e.what(); + exit(0); + } catch (const Base::Exception& e) { std::string appName = App::Application::Config()["ExeName"]; std::stringstream msg; diff --git a/src/Main/MainGui.cpp b/src/Main/MainGui.cpp index 83c4487f4..5552bd6b4 100644 --- a/src/Main/MainGui.cpp +++ b/src/Main/MainGui.cpp @@ -161,83 +161,6 @@ private: QDomDocument domDocument; }; -class ProgramOptions -{ -public: - ProgramOptions() - { - newcout = new ProgramOptionsStream(out); - oldcout = std::cout.rdbuf(newcout); - out.reserve(80); - newcerr = new ProgramOptionsStream(err); - oldcerr = std::cerr.rdbuf(newcerr); - err.reserve(80); - - error = true; - ::atexit(ProgramOptions::failure); - } - ~ProgramOptions() - { - std::cout.rdbuf(oldcout); - delete newcout; - std::cerr.rdbuf(oldcerr); - delete newcerr; - error = false; - } - static void failure() - { - if (error) { - int argc=0; - QApplication app(argc,0); - QString appName = QString::fromAscii(App::Application::Config()["ExeName"].c_str()); - if (!err.empty()) { - QString msg = QString::fromAscii(err.c_str()); - QString s = QLatin1String("
") + msg + QLatin1String("
"); - QMessageBox::critical(0, appName, s); - } - else if (!out.empty()) { - QString msg = QString::fromAscii(out.c_str()); - QString s = QLatin1String("
") + msg + QLatin1String("
"); - QMessageBox::information(0, appName, s); - } - } - } - -private: - class ProgramOptionsStream : public std::streambuf - { - public: - ProgramOptionsStream(std::string& s) : buf(s) - { - } - int overflow(int c = EOF) - { - if (c != EOF) - buf.push_back((char)c); - return c; - } - int sync() - { - return 0; - } - private: - std::string& buf; - }; - -private: - friend class ProgramOptionsStream; - std::streambuf* oldcout; - std::streambuf* newcout; - std::streambuf* oldcerr; - std::streambuf* newcerr; - static std::string out, err; - static bool error; -}; - -bool ProgramOptions::error = false; -std::string ProgramOptions::out; -std::string ProgramOptions::err; - #if defined (FC_OS_LINUX) || defined(FC_OS_BSD) QString myDecoderFunc(const QByteArray &localFileName) { @@ -300,10 +223,25 @@ int main( int argc, char ** argv ) App::Application::Config()["RunMode"] = "Gui"; // Inits the Application - ProgramOptions po; App::Application::init(argc,argv); Gui::Application::initApplication(); } + catch (const Base::UnknownProgramOption& e) { + QApplication app(argc,argv); + QString appName = QString::fromAscii(App::Application::Config()["ExeName"].c_str()); + QString msg = QString::fromAscii(e.what()); + QString s = QLatin1String("
") + msg + QLatin1String("
"); + QMessageBox::critical(0, appName, s); + exit(1); + } + catch (const Base::ProgramInformation& e) { + QApplication app(argc,argv); + QString appName = QString::fromAscii(App::Application::Config()["ExeName"].c_str()); + QString msg = QString::fromAscii(e.what()); + QString s = QLatin1String("
") + msg + QLatin1String("
"); + QMessageBox::information(0, appName, s); + exit(0); + } catch (const Base::Exception& e) { // Popup an own dialog box instead of that one of Windows QApplication app(argc,argv); diff --git a/src/Mod/Raytracing/Gui/Command.cpp b/src/Mod/Raytracing/Gui/Command.cpp index ef2affe17..aeebf3d24 100644 --- a/src/Mod/Raytracing/Gui/Command.cpp +++ b/src/Mod/Raytracing/Gui/Command.cpp @@ -102,8 +102,6 @@ void CmdRaytracingWriteCamera::activated(int iMsg) SoInput in; in.setBuffer((void*)ppReturn,std::strlen(ppReturn)); - //if (!in.openFile(filename)) { exit(1); } - SoNode* rootNode; SoDB::read(&in,rootNode);