diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index e5e5411e29..145df4de6f 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -5,6 +5,7 @@ files: | (?x)^( src/Base| + src/Main| src/Tools| tests/src| src/Mod/AddonManager| diff --git a/src/Main/FreeCADGuiPy.cpp b/src/Main/FreeCADGuiPy.cpp index 808d88d3f0..f3a3dc70f8 100644 --- a/src/Main/FreeCADGuiPy.cpp +++ b/src/Main/FreeCADGuiPy.cpp @@ -23,11 +23,11 @@ #include #if HAVE_CONFIG_H -# include -#endif // HAVE_CONFIG_H +#include +#endif // HAVE_CONFIG_H #ifdef _MSC_VER -# pragma warning(disable : 4005) +#pragma warning(disable : 4005) #endif #include @@ -58,15 +58,16 @@ static bool _isSetupWithoutGui = false; -static -QWidget* setupMainWindow(); +static QWidget* setupMainWindow(); -class QtApplication : public QApplication { +class QtApplication: public QApplication +{ public: - QtApplication(int &argc, char **argv) - : QApplication(argc, argv) { - } - bool notify (QObject * receiver, QEvent * event) override { + QtApplication(int& argc, char** argv) + : QApplication(argc, argv) + {} + bool notify(QObject* receiver, QEvent* event) override + { try { return QApplication::notify(receiver, event); } @@ -80,25 +81,27 @@ public: #if defined(Q_OS_WIN) HHOOK hhook; -LRESULT CALLBACK -FilterProc(int nCode, WPARAM wParam, LPARAM lParam) { - if (qApp) - qApp->sendPostedEvents(0, -1); // special DeferredDelete +LRESULT CALLBACK FilterProc(int nCode, WPARAM wParam, LPARAM lParam) +{ + if (qApp) { + qApp->sendPostedEvents(0, -1); // special DeferredDelete + } return CallNextHookEx(hhook, nCode, wParam, lParam); } #endif -static PyObject * -FreeCADGui_showMainWindow(PyObject * /*self*/, PyObject *args) +static PyObject* FreeCADGui_showMainWindow(PyObject* /*self*/, PyObject* args) { if (_isSetupWithoutGui) { - PyErr_SetString(PyExc_RuntimeError, "Cannot call showMainWindow() after calling setupWithoutGUI()\n"); + PyErr_SetString(PyExc_RuntimeError, + "Cannot call showMainWindow() after calling setupWithoutGUI()\n"); return nullptr; } PyObject* inThread = Py_False; - if (!PyArg_ParseTuple(args, "|O!", &PyBool_Type, &inThread)) + if (!PyArg_ParseTuple(args, "|O!", &PyBool_Type, &inThread)) { return nullptr; + } static bool thr = false; if (!qApp) { @@ -106,7 +109,7 @@ FreeCADGui_showMainWindow(PyObject * /*self*/, PyObject *args) thr = true; std::thread t([]() { static int argc = 0; - static char **argv = {nullptr}; + static char** argv = {nullptr}; QApplication::setAttribute(Qt::AA_ShareOpenGLContexts); // This only works well if the QApplication is the very first created instance // of a QObject. Otherwise the application lives in a different thread than the @@ -124,18 +127,18 @@ FreeCADGui_showMainWindow(PyObject * /*self*/, PyObject *args) // with a QtCore.QCoreApplication which will raise an exception in ipykernel #if defined(Q_OS_WIN) static int argc = 0; - static char **argv = {0}; + static char** argv = {0}; (void)new QApplication(argc, argv); // When QApplication is constructed - hhook = SetWindowsHookEx(WH_GETMESSAGE, - FilterProc, 0, GetCurrentThreadId()); + hhook = SetWindowsHookEx(WH_GETMESSAGE, FilterProc, 0, GetCurrentThreadId()); #elif !defined(QT_NO_GLIB) static int argc = 0; - static char **argv = {nullptr}; + static char** argv = {nullptr}; (void)new QApplication(argc, argv); #else - PyErr_SetString(PyExc_RuntimeError, "Must construct a QApplication before a QPaintDevice\n"); - return NULL; + PyErr_SetString(PyExc_RuntimeError, + "Must construct a QApplication before a QPaintDevice\n"); + return nullptr; #endif } } @@ -152,7 +155,7 @@ FreeCADGui_showMainWindow(PyObject * /*self*/, PyObject *args) } // if successful then enable Console logger - Base::ILogger *console = Base::Console().Get("Console"); + Base::ILogger* console = Base::Console().Get("Console"); if (console) { console->bMsg = true; console->bWrn = true; @@ -163,14 +166,15 @@ FreeCADGui_showMainWindow(PyObject * /*self*/, PyObject *args) return Py_None; } -static PyObject * -FreeCADGui_exec_loop(PyObject * /*self*/, PyObject *args) +static PyObject* FreeCADGui_exec_loop(PyObject* /*self*/, PyObject* args) { - if (!PyArg_ParseTuple(args, "")) + if (!PyArg_ParseTuple(args, "")) { return nullptr; + } if (!qApp) { - PyErr_SetString(PyExc_RuntimeError, "Must construct a QApplication before a QPaintDevice\n"); + PyErr_SetString(PyExc_RuntimeError, + "Must construct a QApplication before a QPaintDevice\n"); return nullptr; } else if (!qobject_cast(qApp)) { @@ -184,14 +188,14 @@ FreeCADGui_exec_loop(PyObject * /*self*/, PyObject *args) return Py_None; } -static PyObject * -FreeCADGui_setupWithoutGUI(PyObject * /*self*/, PyObject *args) +static PyObject* FreeCADGui_setupWithoutGUI(PyObject* /*self*/, PyObject* args) { - if (!PyArg_ParseTuple(args, "")) + if (!PyArg_ParseTuple(args, "")) { return nullptr; + } if (!Gui::Application::Instance) { - static Gui::Application *app = new Gui::Application(false); + static Gui::Application* app = new Gui::Application(false); _isSetupWithoutGui = true; Q_UNUSED(app); } @@ -209,12 +213,12 @@ FreeCADGui_setupWithoutGUI(PyObject * /*self*/, PyObject *args) return Py_None; } -static PyObject * -FreeCADGui_embedToWindow(PyObject * /*self*/, PyObject *args) +static PyObject* FreeCADGui_embedToWindow(PyObject* /*self*/, PyObject* args) { char* pointer; - if (!PyArg_ParseTuple(args, "s", &pointer)) + if (!PyArg_ParseTuple(args, "s", &pointer)) { return nullptr; + } QWidget* widget = Gui::getMainWindow(); if (!widget) { @@ -231,10 +235,9 @@ FreeCADGui_embedToWindow(PyObject * /*self*/, PyObject *args) HWND winid = (HWND)window; LONG oldLong = GetWindowLong(winid, GWL_STYLE); - SetWindowLong(winid, GWL_STYLE, - oldLong | WS_CLIPCHILDREN | WS_CLIPSIBLINGS); - //SetWindowLong(widget->winId(), GWL_STYLE, - // WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS); + SetWindowLong(winid, GWL_STYLE, oldLong | WS_CLIPCHILDREN | WS_CLIPSIBLINGS); + // SetWindowLong(widget->winId(), GWL_STYLE, + // WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS); SetParent((HWND)widget->winId(), winid); QEvent embeddingEvent(QEvent::EmbeddingControl); @@ -257,25 +260,32 @@ FreeCADGui_embedToWindow(PyObject * /*self*/, PyObject *args) } struct PyMethodDef FreeCADGui_methods[] = { - {"showMainWindow",FreeCADGui_showMainWindow,METH_VARARGS, + {"showMainWindow", + FreeCADGui_showMainWindow, + METH_VARARGS, "showMainWindow() -- Show the main window\n" "If no main window does exist one gets created"}, - {"exec_loop",FreeCADGui_exec_loop,METH_VARARGS, + {"exec_loop", + FreeCADGui_exec_loop, + METH_VARARGS, "exec_loop() -- Starts the event loop\n" "Note: this will block the call until the event loop has terminated"}, - {"setupWithoutGUI",FreeCADGui_setupWithoutGUI,METH_VARARGS, + {"setupWithoutGUI", + FreeCADGui_setupWithoutGUI, + METH_VARARGS, "setupWithoutGUI() -- Uses this module without starting\n" "an event loop or showing up any GUI\n"}, - {"embedToWindow",FreeCADGui_embedToWindow,METH_VARARGS, + {"embedToWindow", + FreeCADGui_embedToWindow, + METH_VARARGS, "embedToWindow() -- Embeds the main window into another window\n"}, - {nullptr, nullptr, 0, nullptr} /* sentinel */ + {nullptr, nullptr, 0, nullptr} /* sentinel */ }; -static -QWidget* setupMainWindow() +static QWidget* setupMainWindow() { if (!Gui::Application::Instance) { - static Gui::Application *app = new Gui::Application(true); + static Gui::Application* app = new Gui::Application(true); Q_UNUSED(app); } @@ -293,12 +303,13 @@ QWidget* setupMainWindow() Base::PyGILStateLocker lock; // It's sufficient to create the config key App::Application::Config()["DontOverrideStdIn"] = ""; - Gui::MainWindow *mw = new Gui::MainWindow(); + Gui::MainWindow* mw = new Gui::MainWindow(); hasMainWindow = true; QIcon icon = qApp->windowIcon(); if (icon.isNull()) { - qApp->setWindowIcon(Gui::BitmapFactory().pixmap(App::Application::Config()["AppIcon"].c_str())); + qApp->setWindowIcon( + Gui::BitmapFactory().pixmap(App::Application::Config()["AppIcon"].c_str())); } mw->setWindowIcon(qApp->windowIcon()); @@ -310,7 +321,6 @@ QWidget* setupMainWindow() catch (const Base::Exception&) { return nullptr; } - } else { Gui::getMainWindow()->show(); @@ -322,22 +332,29 @@ QWidget* setupMainWindow() PyMOD_INIT_FUNC(FreeCADGui) { try { + // clang-format off Base::Interpreter().loadModule("FreeCAD"); App::Application::Config()["AppIcon"] = "freecad"; App::Application::Config()["SplashScreen"] = "freecadsplash"; App::Application::Config()["CopyrightInfo"] = "\xc2\xa9 Juergen Riegel, Werner Mayer, Yorik van Havre and others 2001-2024\n"; App::Application::Config()["LicenseInfo"] = "FreeCAD is free and open-source software licensed under the terms of LGPL2+ license.\n"; App::Application::Config()["CreditsInfo"] = "FreeCAD wouldn't be possible without FreeCAD community.\n"; + // clang-format on + // it's possible that the GUI is already initialized when the Gui version of the executable // is started in command mode - if (Base::Type::fromName("Gui::BaseView").isBad()) + if (Base::Type::fromName("Gui::BaseView").isBad()) { Gui::Application::initApplication(); - static struct PyModuleDef FreeCADGuiModuleDef = { - PyModuleDef_HEAD_INIT, - "FreeCADGui", "FreeCAD GUI module\n", -1, - FreeCADGui_methods, - nullptr, nullptr, nullptr, nullptr - }; + } + static struct PyModuleDef FreeCADGuiModuleDef = {PyModuleDef_HEAD_INIT, + "FreeCADGui", + "FreeCAD GUI module\n", + -1, + FreeCADGui_methods, + nullptr, + nullptr, + nullptr, + nullptr}; PyObject* module = PyModule_Create(&FreeCADGuiModuleDef); return module; } @@ -349,4 +366,3 @@ PyMOD_INIT_FUNC(FreeCADGui) } return nullptr; } - diff --git a/src/Main/MainCmd.cpp b/src/Main/MainCmd.cpp index 77f31cf7c1..0a5aeac0d4 100644 --- a/src/Main/MainCmd.cpp +++ b/src/Main/MainCmd.cpp @@ -24,16 +24,16 @@ #include "../FCConfig.h" #ifdef _PreComp_ -# undef _PreComp_ +#undef _PreComp_ #endif #ifdef FC_OS_LINUX -# include +#include #endif #if HAVE_CONFIG_H -# include -#endif // HAVE_CONFIG_H +#include +#endif // HAVE_CONFIG_H #include #include @@ -47,23 +47,23 @@ #include -using Base::Console; using App::Application; +using Base::Console; -const char sBanner[] = "(c) Juergen Riegel, Werner Mayer, Yorik van Havre and others 2001-2024\n"\ - "FreeCAD is free and open-source software licensed under the terms of LGPL2+ license.\n"\ - "FreeCAD wouldn't be possible without FreeCAD community.\n"\ - " ##### #### ### #### \n" \ - " # # # # # # \n" \ - " # ## #### #### # # # # # \n" \ - " #### # # # # # # # ##### # # \n" \ - " # # #### #### # # # # # \n" \ - " # # # # # # # # # ## ## ##\n" \ - " # # #### #### ### # # #### ## ## ##\n\n" ; +const char sBanner[] = + "(c) Juergen Riegel, Werner Mayer, Yorik van Havre and others 2001-2024\n" + "FreeCAD is free and open-source software licensed under the terms of LGPL2+ license.\n" + "FreeCAD wouldn't be possible without FreeCAD community.\n" + " ##### #### ### #### \n" + " # # # # # # \n" + " # ## #### #### # # # # # \n" + " #### # # # # # # # ##### # # \n" + " # # #### #### # # # # # \n" + " # # # # # # # # # ## ## ##\n" + " # # #### #### ### # # #### ## ## ##\n\n"; - -int main( int argc, char ** argv ) +int main(int argc, char** argv) { // Make sure that we use '.' as decimal point setlocale(LC_ALL, ""); @@ -72,8 +72,9 @@ int main( int argc, char ** argv ) #if defined(__MINGW32__) const char* mingw_prefix = getenv("MINGW_PREFIX"); const char* py_home = getenv("PYTHONHOME"); - if (!py_home && mingw_prefix) + if (!py_home && mingw_prefix) { _putenv_s("PYTHONHOME", mingw_prefix); + } #endif // Name and Version of the Application @@ -86,12 +87,13 @@ int main( int argc, char ** argv ) try { // Init phase =========================================================== - // sets the default run mode for FC, starts with command prompt if not overridden in InitConfig... + // sets the default run mode for FC, starts with command prompt if not overridden in + // InitConfig... App::Application::Config()["RunMode"] = "Exit"; App::Application::Config()["LoggingConsole"] = "1"; // Inits the Application - App::Application::init(argc,argv); + App::Application::init(argc, argv); } catch (const Base::UnknownProgramOption& e) { std::cerr << e.what(); @@ -104,13 +106,16 @@ int main( int argc, char ** argv ) catch (const Base::Exception& e) { std::string appName = App::Application::Config()["ExeName"]; std::stringstream msg; - msg << "While initializing " << appName << " the following exception occurred: '" << e.what() << "'\n\n"; - msg << "Python is searching for its runtime files in the following directories:\n" << Py_EncodeLocale(Py_GetPath(),nullptr) << "\n\n"; + msg << "While initializing " << appName << " the following exception occurred: '" + << e.what() << "'\n\n"; + msg << "Python is searching for its runtime files in the following directories:\n" + << Py_EncodeLocale(Py_GetPath(), nullptr) << "\n\n"; msg << "Python version information:\n" << Py_GetVersion() << "\n"; const char* pythonhome = getenv("PYTHONHOME"); - if ( pythonhome ) { + if (pythonhome) { msg << "\nThe environment variable PYTHONHOME is set to '" << pythonhome << "'."; - msg << "\nSetting this environment variable might cause Python to fail. Please contact your administrator to unset it on your system.\n\n"; + msg << "\nSetting this environment variable might cause Python to fail. Please contact " + "your administrator to unset it on your system.\n\n"; } else { msg << "\nPlease contact the application's support team for more information.\n\n"; @@ -122,7 +127,7 @@ int main( int argc, char ** argv ) catch (...) { std::string appName = App::Application::Config()["ExeName"]; std::stringstream msg; - msg << "Unknown runtime error occurred while initializing " << appName <<".\n\n"; + msg << "Unknown runtime error occurred while initializing " << appName << ".\n\n"; msg << "Please contact the application's support team for more information.\n\n"; printf("Initialization of %s failed:\n%s", appName.c_str(), msg.str().c_str()); exit(101); @@ -132,7 +137,7 @@ int main( int argc, char ** argv ) try { Application::runApplication(); } - catch (const Base::SystemExitException &e) { + catch (const Base::SystemExitException& e) { exit(e.getExitCode()); } catch (const Base::Exception& e) { @@ -151,7 +156,7 @@ int main( int argc, char ** argv ) // close open documents App::GetApplication().closeAllDocuments(); } - catch(...) { + catch (...) { } // cleans up @@ -161,4 +166,3 @@ int main( int argc, char ** argv ) return 0; } - diff --git a/src/Main/MainGui.cpp b/src/Main/MainGui.cpp index 71ed46a2ef..a64227f684 100644 --- a/src/Main/MainGui.cpp +++ b/src/Main/MainGui.cpp @@ -30,16 +30,16 @@ #ifdef _PreComp_ -# undef _PreComp_ +#undef _PreComp_ #endif #ifdef FC_OS_LINUX -# include +#include #endif #if HAVE_CONFIG_H -# include -#endif // HAVE_CONFIG_H +#include +#endif // HAVE_CONFIG_H #include #include @@ -60,16 +60,17 @@ void PrintInitHelp(); -const char sBanner[] = "\xc2\xa9 Juergen Riegel, Werner Mayer, Yorik van Havre and others 2001-2024\n"\ -"FreeCAD is free and open-source software licensed under the terms of LGPL2+ license.\n"\ -"FreeCAD wouldn't be possible without FreeCAD community.\n"\ -" ##### #### ### #### \n" \ -" # # # # # # \n" \ -" # ## #### #### # # # # # \n" \ -" #### # # # # # # # ##### # # \n" \ -" # # #### #### # # # # # \n" \ -" # # # # # # # # # ## ## ##\n" \ -" # # #### #### ### # # #### ## ## ##\n\n" ; +const char sBanner[] = + "\xc2\xa9 Juergen Riegel, Werner Mayer, Yorik van Havre and others 2001-2024\n" + "FreeCAD is free and open-source software licensed under the terms of LGPL2+ license.\n" + "FreeCAD wouldn't be possible without FreeCAD community.\n" + " ##### #### ### #### \n" + " # # # # # # \n" + " # ## #### #### # # # # # \n" + " #### # # # # # # # ##### # # \n" + " # # #### #### # # # # # \n" + " # # # # # # # # # ## ## ##\n" + " # # #### #### ### # # #### ## ## ##\n\n"; #if defined(_MSC_VER) void InitMiniDumpWriter(const std::string&); @@ -79,12 +80,13 @@ class Redirection { public: Redirection(FILE* f) - : fi(Base::FileInfo::getTempFileName()), file(f) + : fi(Base::FileInfo::getTempFileName()) + , file(f) { #ifdef WIN32 - FILE* ptr = _wfreopen(fi.toStdWString().c_str(),L"w",file); + FILE* ptr = _wfreopen(fi.toStdWString().c_str(), L"w", file); #else - FILE* ptr = freopen(fi.filePath().c_str(),"w",file); + FILE* ptr = freopen(fi.filePath().c_str(), "w", file); #endif if (!ptr) { std::cerr << "Failed to reopen file" << std::endl; @@ -101,10 +103,10 @@ private: FILE* file; }; -int main( int argc, char ** argv ) +int main(int argc, char** argv) { -#if defined (FC_OS_LINUX) || defined(FC_OS_BSD) - setlocale(LC_ALL, ""); // use native environment settings +#if defined(FC_OS_LINUX) || defined(FC_OS_BSD) + setlocale(LC_ALL, ""); // use native environment settings // Make sure to setup the Qt locale system before setting LANG and LC_ALL to C. // which is needed to use the system locale settings. @@ -119,27 +121,30 @@ int main( int argc, char ** argv ) #elif defined(__MINGW32__) const char* mingw_prefix = getenv("MINGW_PREFIX"); const char* py_home = getenv("PYTHONHOME"); - if (!py_home && mingw_prefix) + if (!py_home && mingw_prefix) { _putenv_s("PYTHONHOME", mingw_prefix); + } #else _putenv("PYTHONPATH="); // https://forum.freecad.org/viewtopic.php?f=4&t=18288 // https://forum.freecad.org/viewtopic.php?f=3&t=20515 const char* fc_py_home = getenv("FC_PYTHONHOME"); - if (fc_py_home) + if (fc_py_home) { _putenv_s("PYTHONHOME", fc_py_home); - else + } + else { _putenv("PYTHONHOME="); + } #endif -#if defined (FC_OS_WIN32) +#if defined(FC_OS_WIN32) // we need to force Coin not to use Freetype in order to find installed fonts on Windows // see https://forum.freecad.org/viewtopic.php?p=485142#p485016 _putenv("COIN_FORCE_FREETYPE_OFF=1"); int argc_ = argc; QVector data; - QVector argv_; + QVector argv_; // get the command line arguments as unicode string { @@ -149,7 +154,7 @@ int main( int argc, char ** argv ) data.push_back(it->toUtf8()); argv_.push_back(data.back().data()); } - argv_.push_back(0); // 0-terminated string + argv_.push_back(0); // 0-terminated string } #endif @@ -165,11 +170,11 @@ int main( int argc, char ** argv ) App::Application::Config()["SplashScreen"] = "freecadsplash"; App::Application::Config()["AboutImage"] = "freecadabout"; App::Application::Config()["StartWorkbench"] = "PartDesignWorkbench"; - //App::Application::Config()["HiddenDockWindow"] = "Property editor"; - App::Application::Config()["SplashAlignment" ] = "Bottom|Left"; - App::Application::Config()["SplashTextColor" ] = "#8aadf4"; // light blue - App::Application::Config()["SplashInfoColor" ] = "#8aadf4"; // light blue - App::Application::Config()["SplashInfoPosition" ] = "6,75"; + // App::Application::Config()["HiddenDockWindow"] = "Property editor"; + App::Application::Config()["SplashAlignment"] = "Bottom|Left"; + App::Application::Config()["SplashTextColor"] = "#8aadf4"; // light blue + App::Application::Config()["SplashInfoColor"] = "#8aadf4"; // light blue + App::Application::Config()["SplashInfoPosition"] = "6,75"; QGuiApplication::setDesktopFileName(QStringLiteral("org.freecad.FreeCAD")); @@ -181,7 +186,7 @@ int main( int argc, char ** argv ) App::Application::Config()["LoggingConsole"] = "1"; // Inits the Application -#if defined (FC_OS_WIN32) +#if defined(FC_OS_WIN32) App::Application::init(argc_, argv_.data()); #else App::Application::init(argc, argv); @@ -192,9 +197,11 @@ int main( int argc, char ** argv ) dmpfile += "crash.dmp"; InitMiniDumpWriter(dmpfile); #endif - std::map::iterator it = App::Application::Config().find("NavigationStyle"); + std::map::iterator it = + App::Application::Config().find("NavigationStyle"); if (it != App::Application::Config().end()) { - ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/View"); + ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath( + "User parameter:BaseApp/Preferences/View"); // if not already defined do it now (for the very first start) std::string style = hGrp->GetASCII("NavigationStyle", it->second.c_str()); hGrp->SetASCII("NavigationStyle", style.c_str()); @@ -203,11 +210,12 @@ int main( int argc, char ** argv ) Gui::Application::initApplication(); // Only if 'RunMode' is set to 'Gui' do the replacement - if (App::Application::Config()["RunMode"] == "Gui") + if (App::Application::Config()["RunMode"] == "Gui") { Base::Interpreter().replaceStdOutput(); + } } catch (const Base::UnknownProgramOption& e) { - QApplication app(argc,argv); + QApplication app(argc, argv); QString appName = QString::fromLatin1(App::Application::Config()["ExeName"].c_str()); QString msg = QString::fromLatin1(e.what()); QString s = QLatin1String("
") + msg + QLatin1String("
"); @@ -215,7 +223,7 @@ int main( int argc, char ** argv ) exit(1); } catch (const Base::ProgramInformation& e) { - QApplication app(argc,argv); + QApplication app(argc, argv); QString appName = QString::fromLatin1(App::Application::Config()["ExeName"].c_str()); QString msg = QString::fromUtf8(e.what()); QString s = QLatin1String("
") + msg + QLatin1String("
"); @@ -230,54 +238,67 @@ int main( int argc, char ** argv ) } catch (const Base::Exception& e) { // Popup an own dialog box instead of that one of Windows - QApplication app(argc,argv); + QApplication app(argc, argv); QString appName = QString::fromLatin1(App::Application::Config()["ExeName"].c_str()); QString msg; msg = QObject::tr("While initializing %1 the following exception occurred: '%2'\n\n" "Python is searching for its files in the following directories:\n%3\n\n" "Python version information:\n%4\n") - .arg(appName, QString::fromUtf8(e.what()), - QString::fromUtf8(Py_EncodeLocale(Py_GetPath(),nullptr)), QString::fromLatin1(Py_GetVersion())); + .arg(appName, + QString::fromUtf8(e.what()), + QString::fromUtf8(Py_EncodeLocale(Py_GetPath(), nullptr)), + QString::fromLatin1(Py_GetVersion())); const char* pythonhome = getenv("PYTHONHOME"); if (pythonhome) { msg += QObject::tr("\nThe environment variable PYTHONHOME is set to '%1'.") - .arg(QString::fromUtf8(pythonhome)); + .arg(QString::fromUtf8(pythonhome)); msg += QObject::tr("\nSetting this environment variable might cause Python to fail. " - "Please contact your administrator to unset it on your system.\n\n"); - } else { - msg += QObject::tr("\nPlease contact the application's support team for more information.\n\n"); + "Please contact your administrator to unset it on your system.\n\n"); + } + else { + msg += QObject::tr( + "\nPlease contact the application's support team for more information.\n\n"); } - QMessageBox::critical(nullptr, QObject::tr("Initialization of %1 failed").arg(appName), msg); + QMessageBox::critical(nullptr, + QObject::tr("Initialization of %1 failed").arg(appName), + msg); exit(100); } catch (...) { // Popup an own dialog box instead of that one of Windows - QApplication app(argc,argv); + QApplication app(argc, argv); QString appName = QString::fromLatin1(App::Application::Config()["ExeName"].c_str()); - QString msg = QObject::tr("Unknown runtime error occurred while initializing %1.\n\n" - "Please contact the application's support team for more information.\n\n").arg(appName); - QMessageBox::critical(nullptr, QObject::tr("Initialization of %1 failed").arg(appName), msg); + QString msg = + QObject::tr("Unknown runtime error occurred while initializing %1.\n\n" + "Please contact the application's support team for more information.\n\n") + .arg(appName); + QMessageBox::critical(nullptr, + QObject::tr("Initialization of %1 failed").arg(appName), + msg); exit(101); } // Run phase =========================================================== Base::RedirectStdOutput stdcout; - Base::RedirectStdLog stdclog; - Base::RedirectStdError stdcerr; + Base::RedirectStdLog stdclog; + Base::RedirectStdError stdcerr; std::streambuf* oldcout = std::cout.rdbuf(&stdcout); std::streambuf* oldclog = std::clog.rdbuf(&stdclog); std::streambuf* oldcerr = std::cerr.rdbuf(&stdcerr); try { // if console option is set then run in cmd mode - if (App::Application::Config()["Console"] == "1") + if (App::Application::Config()["Console"] == "1") { App::Application::runApplication(); - if (App::Application::Config()["RunMode"] == "Gui" || - App::Application::Config()["RunMode"] == "Internal") { + } + if (App::Application::Config()["RunMode"] == "Gui" + || App::Application::Config()["RunMode"] == "Internal") { Gui::Application::runApplication(); - } else + } + else { App::Application::runApplication(); + } } catch (const Base::SystemExitException& e) { exit(e.getExitCode()); @@ -300,27 +321,27 @@ int main( int argc, char ** argv ) std::cerr.rdbuf(oldcerr); // Destruction phase =========================================================== - Base::Console().Log("%s terminating...\n",App::Application::Config()["ExeName"].c_str()); + Base::Console().Log("%s terminating...\n", App::Application::Config()["ExeName"].c_str()); // cleans up App::Application::destruct(); - Base::Console().Log("%s completely terminated\n",App::Application::Config()["ExeName"].c_str()); + Base::Console().Log("%s completely terminated\n", + App::Application::Config()["ExeName"].c_str()); return 0; } #if defined(_MSC_VER) -typedef BOOL (__stdcall *tMDWD)( - IN HANDLE hProcess, - IN DWORD ProcessId, - IN HANDLE hFile, - IN MINIDUMP_TYPE DumpType, - IN CONST PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam, OPTIONAL - IN CONST PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam, OPTIONAL - IN CONST PMINIDUMP_CALLBACK_INFORMATION CallbackParam OPTIONAL - ); +typedef BOOL(__stdcall* tMDWD)(IN HANDLE hProcess, + IN DWORD ProcessId, + IN HANDLE hFile, + IN MINIDUMP_TYPE DumpType, + IN CONST PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam, + OPTIONAL IN CONST PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam, + OPTIONAL IN CONST PMINIDUMP_CALLBACK_INFORMATION CallbackParam + OPTIONAL); static tMDWD s_pMDWD; static HMODULE s_hDbgHelpMod; @@ -328,104 +349,111 @@ static MINIDUMP_TYPE s_dumpTyp = MiniDumpNormal; static std::wstring s_szMiniDumpFileName; // initialize with whatever appropriate... #include -class MyStackWalker : public StackWalker +class MyStackWalker: public StackWalker { DWORD threadId; + public: - MyStackWalker() : StackWalker(), threadId(GetCurrentThreadId()) + MyStackWalker() + : StackWalker() + , threadId(GetCurrentThreadId()) { std::string name = App::Application::Config()["UserAppData"] + "crash.log"; Base::Console().AttachObserver(new Base::ConsoleObserverFile(name.c_str())); } - MyStackWalker(DWORD dwProcessId, HANDLE hProcess) : StackWalker(dwProcessId, hProcess) {} + MyStackWalker(DWORD dwProcessId, HANDLE hProcess) + : StackWalker(dwProcessId, hProcess) + {} virtual void OnOutput(LPCSTR szText) { Base::Console().Log("Id: %ld: %s", threadId, szText); - //StackWalker::OnOutput(szText); + // StackWalker::OnOutput(szText); } }; -static LONG __stdcall MyCrashHandlerExceptionFilter(EXCEPTION_POINTERS* pEx) +static LONG __stdcall MyCrashHandlerExceptionFilter(EXCEPTION_POINTERS* pEx) { -#ifdef _M_IX86 - if (pEx->ExceptionRecord->ExceptionCode == EXCEPTION_STACK_OVERFLOW) - { - // be sure that we have enough space... - static char MyStack[1024*128]; - // it assumes that DS and SS are the same!!! (this is the case for Win32) - // change the stack only if the selectors are the same (this is the case for Win32) - //__asm push offset MyStack[1024*128]; - //__asm pop esp; - __asm mov eax,offset MyStack[1024*128]; - __asm mov esp,eax; - } -#endif - MyStackWalker sw; - sw.ShowCallstack(GetCurrentThread(), pEx->ContextRecord); - Base::Console().Log("*** Unhandled Exception!\n"); - Base::Console().Log(" ExpCode: 0x%8.8X\n", pEx->ExceptionRecord->ExceptionCode); - Base::Console().Log(" ExpFlags: %d\n", pEx->ExceptionRecord->ExceptionFlags); - Base::Console().Log(" ExpAddress: 0x%8.8X\n", pEx->ExceptionRecord->ExceptionAddress); +#ifdef _M_IX86 + if (pEx->ExceptionRecord->ExceptionCode == EXCEPTION_STACK_OVERFLOW) { + // be sure that we have enough space... + static char MyStack[1024 * 128]; + // it assumes that DS and SS are the same!!! (this is the case for Win32) + // change the stack only if the selectors are the same (this is the case for Win32) + //__asm push offset MyStack[1024*128]; + //__asm pop esp; + __asm mov eax, offset MyStack[1024 * 128]; + __asm mov esp, eax; + } +#endif + MyStackWalker sw; + sw.ShowCallstack(GetCurrentThread(), pEx->ContextRecord); + Base::Console().Log("*** Unhandled Exception!\n"); + Base::Console().Log(" ExpCode: 0x%8.8X\n", pEx->ExceptionRecord->ExceptionCode); + Base::Console().Log(" ExpFlags: %d\n", pEx->ExceptionRecord->ExceptionFlags); + Base::Console().Log(" ExpAddress: 0x%8.8X\n", pEx->ExceptionRecord->ExceptionAddress); - bool bFailed = true; - HANDLE hFile; - hFile = CreateFileW(s_szMiniDumpFileName.c_str(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); - if (hFile != INVALID_HANDLE_VALUE) - { - MINIDUMP_EXCEPTION_INFORMATION stMDEI; - stMDEI.ThreadId = GetCurrentThreadId(); - stMDEI.ExceptionPointers = pEx; - stMDEI.ClientPointers = true; - // try to create a miniDump: - if (s_pMDWD( - GetCurrentProcess(), - GetCurrentProcessId(), - hFile, - s_dumpTyp, - &stMDEI, - NULL, - NULL - )) - { - bFailed = false; // succeeded - } - CloseHandle(hFile); - } + bool bFailed = true; + HANDLE hFile; + hFile = CreateFileW(s_szMiniDumpFileName.c_str(), + GENERIC_WRITE, + 0, + NULL, + CREATE_ALWAYS, + FILE_ATTRIBUTE_NORMAL, + NULL); + if (hFile != INVALID_HANDLE_VALUE) { + MINIDUMP_EXCEPTION_INFORMATION stMDEI; + stMDEI.ThreadId = GetCurrentThreadId(); + stMDEI.ExceptionPointers = pEx; + stMDEI.ClientPointers = true; + // try to create a miniDump: + if (s_pMDWD(GetCurrentProcess(), + GetCurrentProcessId(), + hFile, + s_dumpTyp, + &stMDEI, + NULL, + NULL)) { + bFailed = false; // succeeded + } + CloseHandle(hFile); + } - if (bFailed) - { - return EXCEPTION_CONTINUE_SEARCH; - } + if (bFailed) { + return EXCEPTION_CONTINUE_SEARCH; + } - // Optional display an error message - // FatalAppExit(-1, ("Application failed!")); + // Optional display an error message + // FatalAppExit(-1, ("Application failed!")); - // or return one of the following: - // - EXCEPTION_CONTINUE_SEARCH - // - EXCEPTION_CONTINUE_EXECUTION - // - EXCEPTION_EXECUTE_HANDLER - return EXCEPTION_CONTINUE_SEARCH; // this will trigger the "normal" OS error-dialog -} + // or return one of the following: + // - EXCEPTION_CONTINUE_SEARCH + // - EXCEPTION_CONTINUE_EXECUTION + // - EXCEPTION_EXECUTE_HANDLER + return EXCEPTION_CONTINUE_SEARCH; // this will trigger the "normal" OS error-dialog +} void InitMiniDumpWriter(const std::string& filename) { - if (s_hDbgHelpMod != NULL) - return; - Base::FileInfo fi(filename); - s_szMiniDumpFileName = fi.toStdWString(); + if (s_hDbgHelpMod != NULL) { + return; + } + Base::FileInfo fi(filename); + s_szMiniDumpFileName = fi.toStdWString(); - // Initialize the member, so we do not load the dll after the exception has occurred - // which might be not possible anymore... - s_hDbgHelpMod = LoadLibraryA(("dbghelp.dll")); - if (s_hDbgHelpMod != NULL) - s_pMDWD = (tMDWD) GetProcAddress(s_hDbgHelpMod, "MiniDumpWriteDump"); + // Initialize the member, so we do not load the dll after the exception has occurred + // which might be not possible anymore... + s_hDbgHelpMod = LoadLibraryA(("dbghelp.dll")); + if (s_hDbgHelpMod != NULL) { + s_pMDWD = (tMDWD)GetProcAddress(s_hDbgHelpMod, "MiniDumpWriteDump"); + } - // Register Unhandled Exception-Filter: - SetUnhandledExceptionFilter(MyCrashHandlerExceptionFilter); + // Register Unhandled Exception-Filter: + SetUnhandledExceptionFilter(MyCrashHandlerExceptionFilter); - // Additional call "PreventSetUnhandledExceptionFilter"... - // See also: "SetUnhandledExceptionFilter" and VC8 (and later) - // http://blog.kalmbachnet.de/?postid=75 + // Additional call "PreventSetUnhandledExceptionFilter"... + // See also: "SetUnhandledExceptionFilter" and VC8 (and later) + // http://blog.kalmbachnet.de/?postid=75 } #endif diff --git a/src/Main/MainPy.cpp b/src/Main/MainPy.cpp index 83ccf0fe36..5463ee63b3 100644 --- a/src/Main/MainPy.cpp +++ b/src/Main/MainPy.cpp @@ -24,25 +24,25 @@ #include #ifdef _PreComp_ -# undef _PreComp_ +#undef _PreComp_ #endif #if defined(FC_OS_WIN32) -# include +#include #endif #if defined(FC_OS_LINUX) || defined(FC_OS_BSD) -# include +#include #endif #ifdef FC_OS_MACOSX -# include -# include +#include +#include #endif #if HAVE_CONFIG_H -# include -#endif // HAVE_CONFIG_H +#include +#endif // HAVE_CONFIG_H #include #include @@ -60,30 +60,29 @@ /** DllMain is called when DLL is loaded */ -BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID /*lpReserved*/) +BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID /*lpReserved*/) { switch (ul_reason_for_call) { - case DLL_PROCESS_ATTACH: { - // This name is preliminary, we pass it to Application::init() in initFreeCAD() - // which does the rest. - char szFileName [MAX_PATH]; - GetModuleFileNameA((HMODULE)hModule, szFileName, MAX_PATH-1); - App::Application::Config()["AppHomePath"] = szFileName; - } - break; - default: - break; + case DLL_PROCESS_ATTACH: { + // This name is preliminary, we pass it to Application::init() in initFreeCAD() + // which does the rest. + char szFileName[MAX_PATH]; + GetModuleFileNameA((HMODULE)hModule, szFileName, MAX_PATH - 1); + App::Application::Config()["AppHomePath"] = szFileName; + } break; + default: + break; } return true; } #elif defined(FC_OS_LINUX) || defined(FC_OS_BSD) -# ifndef GNU_SOURCE -# define GNU_SOURCE -# endif -# include +#ifndef GNU_SOURCE +#define GNU_SOURCE +#endif +#include #elif defined(FC_OS_CYGWIN) -# include +#include #endif PyMOD_INIT_FUNC(FreeCAD) @@ -99,8 +98,8 @@ PyMOD_INIT_FUNC(FreeCAD) path = App::Application::Config()["AppHomePath"].c_str(); #elif defined(FC_OS_CYGWIN) HMODULE hModule = GetModuleHandle("FreeCAD.dll"); - char szFileName [MAX_PATH]; - GetModuleFileNameA(hModule, szFileName, MAX_PATH-1); + char szFileName[MAX_PATH]; + GetModuleFileNameA(hModule, szFileName, MAX_PATH - 1); path = szFileName; #elif defined(FC_OS_LINUX) || defined(FC_OS_BSD) putenv("LANG=C"); @@ -123,18 +122,18 @@ PyMOD_INIT_FUNC(FreeCAD) const static char libName[] = "/FreeCAD.so"; const static char upDir[] = "/../"; - PyObject *pySysPath = PySys_GetObject("path"); - if ( PyList_Check(pySysPath) ) { + PyObject* pySysPath = PySys_GetObject("path"); + if (PyList_Check(pySysPath)) { int i; // pySysPath should be a *PyList of strings - iterate through it // backwards since the FreeCAD path was likely appended just before // we were imported. - for (i = PyList_Size(pySysPath) - 1; i >= 0 ; --i) { - const char *basePath; - PyObject *pyPath = PyList_GetItem(pySysPath, i); + for (i = PyList_Size(pySysPath) - 1; i >= 0; --i) { + const char* basePath; + PyObject* pyPath = PyList_GetItem(pySysPath, i); long sz = 0; - if ( PyUnicode_Check(pyPath) ) { + if (PyUnicode_Check(pyPath)) { // Python 3 string basePath = PyUnicode_AsUTF8AndSize(pyPath, &sz); } @@ -156,8 +155,8 @@ PyMOD_INIT_FUNC(FreeCAD) path += upDir; break; } - } // end for (i = PyList_Size(pySysPath) - 1; i >= 0 ; --i) { - } // end if ( PyList_Check(pySysPath) ) { + } // end for (i = PyList_Size(pySysPath) - 1; i >= 0 ; --i) { + } // end if ( PyList_Check(pySysPath) ) { if (path.isEmpty()) { PyErr_SetString(PyExc_ImportError, "Cannot get path of the FreeCAD module!"); @@ -165,7 +164,7 @@ PyMOD_INIT_FUNC(FreeCAD) } #else -# error "Implement: Retrieve the path of the module for your platform." +#error "Implement: Retrieve the path of the module for your platform." #endif int argc = 1; std::vector argv; @@ -187,13 +186,13 @@ PyMOD_INIT_FUNC(FreeCAD) Base::EmptySequencer* seq = new Base::EmptySequencer(); (void)seq; static Base::RedirectStdOutput stdcout; - static Base::RedirectStdLog stdclog; - static Base::RedirectStdError stdcerr; + static Base::RedirectStdLog stdclog; + static Base::RedirectStdError stdcerr; std::cout.rdbuf(&stdcout); std::clog.rdbuf(&stdclog); std::cerr.rdbuf(&stdcerr); - //PyObject* module = _PyImport_FindBuiltin("FreeCAD"); + // PyObject* module = _PyImport_FindBuiltin("FreeCAD"); PyObject* modules = PyImport_GetModuleDict(); PyObject* module = PyDict_GetItemString(modules, "FreeCAD"); if (!module) { @@ -201,4 +200,3 @@ PyMOD_INIT_FUNC(FreeCAD) } return module; } -