diff --git a/src/Base/CMakeLists.txt b/src/Base/CMakeLists.txt index 7c93f02f42..f3bab0cff3 100644 --- a/src/Base/CMakeLists.txt +++ b/src/Base/CMakeLists.txt @@ -30,6 +30,16 @@ if(MSVC) Rpcrt4.lib version.lib ) + + #Universal C runtime introduced in VS 2015 (cl version 19) + if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER "18") + list(APPEND FreeCADBase_LIBS + debug vcruntimed.lib + debug ucrtd.lib + optimized vcruntime.lib + optimized ucrt.lib + ) + endif() elseif(MINGW) set(FreeCADBase_LIBS ${PYTHON_LIBRARIES} @@ -185,6 +195,21 @@ SET(FreeCADBase_UNITAPI_SRCS ) SOURCE_GROUP("Units" FILES ${FreeCADBase_UNITAPI_SRCS}) +if(PYTHON_VERSION_MAJOR LESS 3) +SET(SWIG_SRCS + swigpyrun_1.3.25.cpp + swigpyrun_1.3.33.cpp + swigpyrun_1.3.36.cpp + swigpyrun_1.3.38.cpp + swigpyrun_1.3.40.cpp + swigpyrun.cpp +) +else(PYTHON_VERSION_MAJOR LESS 3) +SET(SWIG_SRCS + swigpyrun.cpp +) +endif(PYTHON_VERSION_MAJOR LESS 3) + SET(FreeCADBase_CPP_SRCS Axis.cpp AxisPyImp.cpp @@ -225,12 +250,7 @@ SET(FreeCADBase_CPP_SRCS Sequencer.cpp Stream.cpp Swap.cpp - swigpyrun_1.3.25.cpp - swigpyrun_1.3.33.cpp - swigpyrun_1.3.36.cpp - swigpyrun_1.3.38.cpp - swigpyrun_1.3.40.cpp - swigpyrun.cpp + ${SWIG_SRCS} TimeInfo.cpp Tools.cpp Tools2D.cpp @@ -242,6 +262,21 @@ SET(FreeCADBase_CPP_SRCS XMLTools.cpp ) +if(PYTHON_VERSION_MAJOR LESS 3) +SET(SWIG_HEADERS + swigpyrun_1.3.25.h + swigpyrun_1.3.33.h + swigpyrun_1.3.36.h + swigpyrun_1.3.38.h + swigpyrun_1.3.40.h + swigpyrun.inl +) +else(PYTHON_VERSION_MAJOR LESS 3) +SET(SWIG_HEADERS + swigpyrun.inl +) +endif(PYTHON_VERSION_MAJOR LESS 3) + SET(FreeCADBase_HPP_SRCS Axis.h Base64.h @@ -276,12 +311,7 @@ SET(FreeCADBase_HPP_SRCS Sequencer.h Stream.h Swap.h - swigpyrun_1.3.25.h - swigpyrun_1.3.33.h - swigpyrun_1.3.36.h - swigpyrun_1.3.38.h - swigpyrun_1.3.40.h - swigpyrun.inl + ${SWIG_HEADERS} TimeInfo.h Tools.h Tools2D.h diff --git a/src/Base/Console.cpp b/src/Base/Console.cpp index 5b75a5807a..ea5a099e99 100644 --- a/src/Base/Console.cpp +++ b/src/Base/Console.cpp @@ -429,6 +429,18 @@ PyObject *ConsoleSingleton::sPyMessage(PyObject * /*self*/, PyObject *args, PyOb if (!PyArg_ParseTuple(args, "O", &output)) return NULL; +#if PY_MAJOR_VERSION >= 3 + const char* string=0; + PyObject* unicode=0; + if (PyUnicode_Check(output)) { + string = PyUnicode_AsUTF8(output); + } + else { + unicode = PyObject_Str(output); + if (unicode) + string = PyUnicode_AsUTF8(unicode); + } +#else const char* string=0; PyObject* unicode=0; if (PyUnicode_Check(output)) { @@ -444,6 +456,7 @@ PyObject *ConsoleSingleton::sPyMessage(PyObject * /*self*/, PyObject *args, PyOb if (unicode) string = PyString_AsString(unicode); } +#endif PY_TRY { if (string) @@ -462,6 +475,18 @@ PyObject *ConsoleSingleton::sPyWarning(PyObject * /*self*/, PyObject *args, PyOb if (!PyArg_ParseTuple(args, "O", &output)) return NULL; +#if PY_MAJOR_VERSION >= 3 + const char* string=0; + PyObject* unicode=0; + if (PyUnicode_Check(output)) { + string = PyUnicode_AsUTF8(output); + } + else { + unicode = PyObject_Str(output); + if (unicode) + string = PyUnicode_AsUTF8(unicode); + } +#else const char* string=0; PyObject* unicode=0; if (PyUnicode_Check(output)) { @@ -477,6 +502,7 @@ PyObject *ConsoleSingleton::sPyWarning(PyObject * /*self*/, PyObject *args, PyOb if (unicode) string = PyString_AsString(unicode); } +#endif PY_TRY { if (string) @@ -495,6 +521,18 @@ PyObject *ConsoleSingleton::sPyError(PyObject * /*self*/, PyObject *args, PyObje if (!PyArg_ParseTuple(args, "O", &output)) return NULL; +#if PY_MAJOR_VERSION >= 3 + const char* string=0; + PyObject* unicode=0; + if (PyUnicode_Check(output)) { + string = PyUnicode_AsUTF8(output); + } + else { + unicode = PyObject_Str(output); + if (unicode) + string = PyUnicode_AsUTF8(unicode); + } +#else const char* string=0; PyObject* unicode=0; if (PyUnicode_Check(output)) { @@ -510,6 +548,7 @@ PyObject *ConsoleSingleton::sPyError(PyObject * /*self*/, PyObject *args, PyObje if (unicode) string = PyString_AsString(unicode); } +#endif PY_TRY { if (string) @@ -528,6 +567,18 @@ PyObject *ConsoleSingleton::sPyLog(PyObject * /*self*/, PyObject *args, PyObject if (!PyArg_ParseTuple(args, "O", &output)) return NULL; +#if PY_MAJOR_VERSION >= 3 + const char* string=0; + PyObject* unicode=0; + if (PyUnicode_Check(output)) { + string = PyUnicode_AsUTF8(output); + } + else { + unicode = PyObject_Str(output); + if (unicode) + string = PyUnicode_AsUTF8(unicode); + } +#else const char* string=0; PyObject* unicode=0; if (PyUnicode_Check(output)) { @@ -543,6 +594,7 @@ PyObject *ConsoleSingleton::sPyLog(PyObject * /*self*/, PyObject *args, PyObject if (unicode) string = PyString_AsString(unicode); } +#endif PY_TRY { if (string) diff --git a/src/Base/Interpreter.cpp b/src/Base/Interpreter.cpp index b23cb715db..9b60303fa1 100644 --- a/src/Base/Interpreter.cpp +++ b/src/Base/Interpreter.cpp @@ -141,6 +141,16 @@ SystemExitException::SystemExitException() value = code; } +#if PY_MAJOR_VERSION >= 3 + if (PyLong_Check(value)) { + errCode = PyLong_AsLong(value); + } + else { + const char *str = PyUnicode_AsUTF8(value); + if (str) + errMsg = errMsg + ": " + str; + } +#else if (PyInt_Check(value)) { errCode = PyInt_AsLong(value); } @@ -149,6 +159,7 @@ SystemExitException::SystemExitException() if (str) errMsg = errMsg + ": " + str; } +#endif } _sErrMsg = errMsg; @@ -231,7 +242,11 @@ std::string InterpreterSingleton::runString(const char *sCmd) PyObject* repr = PyObject_Repr(presult); Py_DECREF(presult); if (repr) { +#if PY_MAJOR_VERSION >= 3 + std::string ret(PyUnicode_AsUTF8(repr)); +#else std::string ret(PyString_AsString(repr)); +#endif Py_DECREF(repr); return ret; } @@ -272,12 +287,14 @@ void InterpreterSingleton::systemExit(void) int exitcode = 0; PyErr_Fetch(&exception, &value, &tb); +#if PY_MAJOR_VERSION < 3 if (Py_FlushLine()) PyErr_Clear(); +#endif fflush(stdout); if (value == NULL || value == Py_None) goto done; - if (PyInstance_Check(value)) { + if (PyExceptionInstance_Check(value)) { /* The error code should be in the `code' attribute. */ PyObject *code = PyObject_GetAttrString(value, "code"); if (code) { @@ -289,8 +306,13 @@ void InterpreterSingleton::systemExit(void) /* If we failed to dig out the 'code' attribute, just let the else clause below print the error. */ } +#if PY_MAJOR_VERSION < 3 if (PyInt_Check(value)) exitcode = (int)PyInt_AsLong(value); +#else + if (PyLong_Check(value)) + exitcode = (int)PyLong_AsLong(value); +#endif else { PyObject_Print(value, stderr, Py_PRINT_RAW); PySys_WriteStderr("\n"); @@ -331,8 +353,13 @@ void InterpreterSingleton::runInteractiveString(const char *sCmd) PyErr_Fetch(&errobj, &errdata, &errtraceback); RuntimeError exc(""); // do not use PyException since this clears the error indicator +#if PY_MAJOR_VERSION >= 3 + if (PyUnicode_Check(errdata)) + exc.setMessage(PyUnicode_AsUTF8(errdata)); +#else if (PyString_Check(errdata)) exc.setMessage(PyString_AsString(errdata)); +#endif PyErr_Restore(errobj, errdata, errtraceback); if (PyErr_Occurred()) PyErr_Print(); @@ -366,7 +393,11 @@ void InterpreterSingleton::runFile(const char*pxFileName, bool local) } if (PyDict_GetItemString(dict, "__file__") == NULL) { +#if PY_MAJOR_VERSION >= 3 + PyObject *f = PyUnicode_FromString(pxFileName); +#else PyObject *f = PyString_FromString(pxFileName); +#endif if (f == NULL) { fclose(fp); Py_DECREF(dict); @@ -431,7 +462,11 @@ void InterpreterSingleton::addPythonPath(const char* Path) { PyGILStateLocker locker; PyObject *list = PySys_GetObject("path"); +#if PY_MAJOR_VERSION >= 3 + PyObject *path = PyUnicode_FromString(Path); +#else PyObject *path = PyString_FromString(Path); +#endif PyList_Append(list, path); Py_DECREF(path); PySys_SetObject("path", list); @@ -440,15 +475,31 @@ void InterpreterSingleton::addPythonPath(const char* Path) const char* InterpreterSingleton::init(int argc,char *argv[]) { if (!Py_IsInitialized()) { +#if PY_MAJOR_VERSION >= 3 + Py_SetProgramName(Py_DecodeLocale(argv[0],NULL)); +#else Py_SetProgramName(argv[0]); - PyEval_InitThreads(); +#endif Py_Initialize(); + PyEval_InitThreads(); +#if PY_MAJOR_VERSION >= 3 + size_t size = argc; + wchar_t **_argv = new wchar_t*[size]; + for (int i = 0; i < argc; i++) { + _argv[i] = Py_DecodeLocale(argv[i],NULL); + } + PySys_SetArgv(argc, _argv); +#else PySys_SetArgv(argc, argv); +#endif PythonStdOutput::init_type(); this->_global = PyEval_SaveThread(); } - +#if PY_MAJOR_VERSION >= 3 + return Py_EncodeLocale(Py_GetPath(),NULL); +#else return Py_GetPath(); +#endif } void InterpreterSingleton::replaceStdOutput() @@ -706,17 +757,20 @@ int getSWIGVersionFromModule(const std::string& module) #if (defined(HAVE_SWIG) && (HAVE_SWIG == 1)) namespace Swig_python { extern int createSWIGPointerObj_T(const char* TypeName, void* obj, PyObject** ptr, int own); } #endif +#if PY_MAJOR_VERSION < 3 namespace Swig_1_3_25 { extern int createSWIGPointerObj_T(const char* TypeName, void* obj, PyObject** ptr, int own); } namespace Swig_1_3_33 { extern int createSWIGPointerObj_T(const char* TypeName, void* obj, PyObject** ptr, int own); } namespace Swig_1_3_36 { extern int createSWIGPointerObj_T(const char* TypeName, void* obj, PyObject** ptr, int own); } namespace Swig_1_3_38 { extern int createSWIGPointerObj_T(const char* TypeName, void* obj, PyObject** ptr, int own); } namespace Swig_1_3_40 { extern int createSWIGPointerObj_T(const char* TypeName, void* obj, PyObject** ptr, int own); } +#endif PyObject* InterpreterSingleton::createSWIGPointerObj(const char* Module, const char* TypeName, void* Pointer, int own) { int result = 0; PyObject* proxy=0; PyGILStateLocker locker; +#if PY_MAJOR_VERSION < 3 int version = getSWIGVersionFromModule(Module); switch (version) { @@ -736,12 +790,15 @@ PyObject* InterpreterSingleton::createSWIGPointerObj(const char* Module, const c result = Swig_1_3_40::createSWIGPointerObj_T(TypeName, Pointer, &proxy, own); break; default: +#endif #if (defined(HAVE_SWIG) && (HAVE_SWIG == 1)) result = Swig_python::createSWIGPointerObj_T(TypeName, Pointer, &proxy, own); #else result = -1; // indicates error #endif +#if PY_MAJOR_VERSION < 3 } +#endif if (result == 0) return proxy; @@ -753,16 +810,19 @@ PyObject* InterpreterSingleton::createSWIGPointerObj(const char* Module, const c #if (defined(HAVE_SWIG) && (HAVE_SWIG == 1)) namespace Swig_python { extern int convertSWIGPointerObj_T(const char* TypeName, PyObject* obj, void** ptr, int flags); } #endif +#if PY_MAJOR_VERSION < 3 namespace Swig_1_3_25 { extern int convertSWIGPointerObj_T(const char* TypeName, PyObject* obj, void** ptr, int flags); } namespace Swig_1_3_33 { extern int convertSWIGPointerObj_T(const char* TypeName, PyObject* obj, void** ptr, int flags); } namespace Swig_1_3_36 { extern int convertSWIGPointerObj_T(const char* TypeName, PyObject* obj, void** ptr, int flags); } namespace Swig_1_3_38 { extern int convertSWIGPointerObj_T(const char* TypeName, PyObject* obj, void** ptr, int flags); } namespace Swig_1_3_40 { extern int convertSWIGPointerObj_T(const char* TypeName, PyObject* obj, void** ptr, int flags); } +#endif bool InterpreterSingleton::convertSWIGPointerObj(const char* Module, const char* TypeName, PyObject* obj, void** ptr, int flags) { int result = 0; PyGILStateLocker locker; +#if PY_MAJOR_VERSION < 3 int version = getSWIGVersionFromModule(Module); switch (version) { @@ -782,12 +842,15 @@ bool InterpreterSingleton::convertSWIGPointerObj(const char* Module, const char* result = Swig_1_3_40::convertSWIGPointerObj_T(TypeName, obj, ptr, flags); break; default: +#endif #if (defined(HAVE_SWIG) && (HAVE_SWIG == 1)) result = Swig_python::convertSWIGPointerObj_T(TypeName, obj, ptr, flags); #else result = -1; // indicates error #endif +#if PY_MAJOR_VERSION < 3 } +#endif if (result == 0) return true; @@ -799,11 +862,13 @@ bool InterpreterSingleton::convertSWIGPointerObj(const char* Module, const char* #if (defined(HAVE_SWIG) && (HAVE_SWIG == 1)) namespace Swig_python { extern void cleanupSWIG_T(const char* TypeName); } #endif +#if PY_MAJOR_VERSION < 3 namespace Swig_1_3_25 { extern void cleanupSWIG_T(const char* TypeName); } namespace Swig_1_3_33 { extern void cleanupSWIG_T(const char* TypeName); } namespace Swig_1_3_36 { extern void cleanupSWIG_T(const char* TypeName); } namespace Swig_1_3_38 { extern void cleanupSWIG_T(const char* TypeName); } namespace Swig_1_3_40 { extern void cleanupSWIG_T(const char* TypeName); } +#endif void InterpreterSingleton::cleanupSWIG(const char* TypeName) { @@ -811,9 +876,11 @@ void InterpreterSingleton::cleanupSWIG(const char* TypeName) #if (defined(HAVE_SWIG) && (HAVE_SWIG == 1)) Swig_python::cleanupSWIG_T(TypeName); #endif +#if PY_MAJOR_VERSION < 3 Swig_1_3_25::cleanupSWIG_T(TypeName); Swig_1_3_33::cleanupSWIG_T(TypeName); Swig_1_3_36::cleanupSWIG_T(TypeName); Swig_1_3_38::cleanupSWIG_T(TypeName); Swig_1_3_40::cleanupSWIG_T(TypeName); +#endif }