From 369cc735e1095557dc05d33c4520203c9c7b79b0 Mon Sep 17 00:00:00 2001 From: wmayer Date: Fri, 2 Jun 2017 10:18:41 +0200 Subject: [PATCH] py3: port external FreeCAD module to Python3 whitespace improvement --- src/Main/FreeCADGuiPy.cpp | 6 +- src/Main/MainPy.cpp | 202 ++++++++++++++++++-------------------- 2 files changed, 97 insertions(+), 111 deletions(-) diff --git a/src/Main/FreeCADGuiPy.cpp b/src/Main/FreeCADGuiPy.cpp index cd4d850a67..d1d9362874 100644 --- a/src/Main/FreeCADGuiPy.cpp +++ b/src/Main/FreeCADGuiPy.cpp @@ -319,11 +319,7 @@ QWidget* setupMainWindow() return Gui::getMainWindow(); } -#if PY_MAJOR_VERSION >= 3 -PyMODINIT_FUNC PyInit_FreeCADGui() -#else -PyMODINIT_FUNC initFreeCADGui() -#endif +PyMOD_INIT_FUNC(FreeCADGui) { try { Base::Interpreter().loadModule("FreeCAD"); diff --git a/src/Main/MainPy.cpp b/src/Main/MainPy.cpp index 1f2070e4cc..33765f7375 100644 --- a/src/Main/MainPy.cpp +++ b/src/Main/MainPy.cpp @@ -80,16 +80,7 @@ BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserv # include #endif -#ifdef FC_OS_WIN32 -# define MainExport __declspec(dllexport) -#else -# define MainExport -#endif -#if PY_MAJOR_VERSION >= 3 -PyMODINIT_FUNC PyInit_FreeCAD() -#else -PyMODINIT_FUNC initFreeCAD() -#endif +PyMOD_INIT_FUNC(FreeCAD) { // Init phase =========================================================== App::Application::Config()["ExeName"] = "FreeCAD"; @@ -105,105 +96,24 @@ PyMODINIT_FUNC initFreeCAD() strncpy(argv[0],App::Application::Config()["AppHomePath"].c_str(),MAX_PATH); argv[0][MAX_PATH-1] = '\0'; // ensure null termination #elif defined(FC_OS_CYGWIN) - HMODULE hModule = GetModuleHandle("FreeCAD.dll"); - char szFileName [MAX_PATH]; - GetModuleFileName(hModule, szFileName, MAX_PATH-1); - argv[0] = (char*)malloc(MAX_PATH); - strncpy(argv[0],szFileName,MAX_PATH); - argv[0][MAX_PATH-1] = '\0'; // ensure null termination + HMODULE hModule = GetModuleHandle("FreeCAD.dll"); + char szFileName [MAX_PATH]; + GetModuleFileName(hModule, szFileName, MAX_PATH-1); + argv[0] = (char*)malloc(MAX_PATH); + strncpy(argv[0],szFileName,MAX_PATH); + argv[0][MAX_PATH-1] = '\0'; // ensure null termination #elif defined(FC_OS_LINUX) || defined(FC_OS_BSD) - putenv("LANG=C"); - putenv("LC_ALL=C"); - // get whole path of the library - Dl_info info; + putenv("LANG=C"); + putenv("LC_ALL=C"); + // get whole path of the library + Dl_info info; #if PY_MAJOR_VERSION >= 3 - int ret = dladdr((void*)PyInit_FreeCAD, &info); + int ret = dladdr((void*)PyInit_FreeCAD, &info); #else - int ret = dladdr((void*)initFreeCAD, &info); + int ret = dladdr((void*)initFreeCAD, &info); #endif - if ((ret == 0) || (!info.dli_fname)) { - free(argv); - PyErr_SetString(PyExc_ImportError, "Cannot get path of the FreeCAD module!"); -#if PY_MAJOR_VERSION >= 3 - return 0; -#else - return; -#endif - } - - argv[0] = (char*)malloc(PATH_MAX); - strncpy(argv[0], info.dli_fname,PATH_MAX); - argv[0][PATH_MAX-1] = '\0'; // ensure null termination - // this is a workaround to avoid a crash in libuuid.so -#elif defined(FC_OS_MACOSX) - - // The MacOS approach uses the Python sys.path list to find the path - // to FreeCAD.so - this should be OS-agnostic, except these two - // strings, and the call to access(). - const static char libName[] = "/FreeCAD.so"; - const static char upDir[] = "/../"; - - char *buf = NULL; - - 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) { - char *basePath; - PyObject *pyPath = PyList_GetItem(pySysPath, i); - long sz = 0; - -#if PY_MAJOR_VERSION >= 3 - if ( PyUnicode_Check(pyPath) ) { - // Python 3 string - basePath = PyUnicode_AsUTF8AndSize(pyPath, &sz); - - } -#else - if ( PyString_Check(pyPath) ) { - // Python 2 string type - PyString_AsStringAndSize(pyPath, &basePath, &sz); - - } else if ( PyUnicode_Check(pyPath) ) { - // Python 2 unicode type - explicitly use UTF-8 codec - PyObject *fromUnicode = PyUnicode_AsUTF8String(pyPath); - PyString_AsStringAndSize(fromUnicode, &basePath, &sz); - Py_XDECREF(fromUnicode); - } -#endif // #if/else PY_MAJOR_VERSION >= 3 - else { - continue; - } - - if (sz + sizeof(libName) > PATH_MAX) { - continue; - } - - // buf gets assigned to argv[0], which is free'd at the end - buf = (char *)malloc(sz + sizeof(libName)); - if (buf == NULL) { - break; - } - - strcpy(buf, basePath); - - // append libName to buf - strcat(buf, libName); - if (access(buf, R_OK | X_OK) == 0) { - - // The FreeCAD "home" path is one level up from - // libName, so replace libName with upDir. - strcpy(buf + sz, upDir); - buf[sz + sizeof(upDir)] = '\0'; - break; - } - } // end for (i = PyList_Size(pySysPath) - 1; i >= 0 ; --i) { - } // end if ( PyList_Check(pySysPath) ) { - - if (buf == NULL) { + if ((ret == 0) || (!info.dli_fname)) { + free(argv); PyErr_SetString(PyExc_ImportError, "Cannot get path of the FreeCAD module!"); #if PY_MAJOR_VERSION >= 3 return 0; @@ -212,7 +122,87 @@ PyMODINIT_FUNC initFreeCAD() #endif } - argv[0] = buf; + argv[0] = (char*)malloc(PATH_MAX); + strncpy(argv[0], info.dli_fname,PATH_MAX); + argv[0][PATH_MAX-1] = '\0'; // ensure null termination + // this is a workaround to avoid a crash in libuuid.so +#elif defined(FC_OS_MACOSX) + + // The MacOS approach uses the Python sys.path list to find the path + // to FreeCAD.so - this should be OS-agnostic, except these two + // strings, and the call to access(). + const static char libName[] = "/FreeCAD.so"; + const static char upDir[] = "/../"; + + char *buf = NULL; + + 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) { + char *basePath; + PyObject *pyPath = PyList_GetItem(pySysPath, i); + long sz = 0; + +#if PY_MAJOR_VERSION >= 3 + if ( PyUnicode_Check(pyPath) ) { + // Python 3 string + basePath = PyUnicode_AsUTF8AndSize(pyPath, &sz); + } +#else + if ( PyString_Check(pyPath) ) { + // Python 2 string type + PyString_AsStringAndSize(pyPath, &basePath, &sz); + } + else if ( PyUnicode_Check(pyPath) ) { + // Python 2 unicode type - explicitly use UTF-8 codec + PyObject *fromUnicode = PyUnicode_AsUTF8String(pyPath); + PyString_AsStringAndSize(fromUnicode, &basePath, &sz); + Py_XDECREF(fromUnicode); + } +#endif // #if/else PY_MAJOR_VERSION >= 3 + else { + continue; + } + + if (sz + sizeof(libName) > PATH_MAX) { + continue; + } + + // buf gets assigned to argv[0], which is free'd at the end + buf = (char *)malloc(sz + sizeof(libName)); + if (buf == NULL) { + break; + } + + strcpy(buf, basePath); + + // append libName to buf + strcat(buf, libName); + if (access(buf, R_OK | X_OK) == 0) { + + // The FreeCAD "home" path is one level up from + // libName, so replace libName with upDir. + strcpy(buf + sz, upDir); + buf[sz + sizeof(upDir)] = '\0'; + break; + } + } // end for (i = PyList_Size(pySysPath) - 1; i >= 0 ; --i) { + } // end if ( PyList_Check(pySysPath) ) { + + if (buf == NULL) { + PyErr_SetString(PyExc_ImportError, "Cannot get path of the FreeCAD module!"); +#if PY_MAJOR_VERSION >= 3 + return 0; +#else + return; +#endif + } + + argv[0] = buf; #else # error "Implement: Retrieve the path of the module for your platform." #endif