Interpreter.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   (c) Jürgen Riegel (juergen.riegel@web.de) 2002                        *
00003  *                                                                         *
00004  *   This file is part of the FreeCAD CAx development system.              *
00005  *                                                                         *
00006  *   This program is free software; you can redistribute it and/or modify  *
00007  *   it under the terms of the GNU Library General Public License (LGPL)   *
00008  *   as published by the Free Software Foundation; either version 2 of     *
00009  *   the License, or (at your option) any later version.                   *
00010  *   for detail see the LICENCE text file.                                 *
00011  *                                                                         *
00012  *   FreeCAD is distributed in the hope that it will be useful,            *
00013  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00014  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00015  *   GNU Library General Public License for more details.                  *
00016  *                                                                         *
00017  *   You should have received a copy of the GNU Library General Public     *
00018  *   License along with FreeCAD; if not, write to the Free Software        *
00019  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  *
00020  *   USA                                                                   *
00021  *                                                                         *
00022  *   Juergen Riegel 2002                                                   *
00023  ***************************************************************************/
00024 
00025 
00026 #include "PreCompiled.h"
00027 
00028 #ifndef _PreComp_
00029 #   include <Python.h>
00030 #   include <sstream>
00031 #   include <boost/regex.hpp>
00032 #endif
00033 
00034 #include "Console.h"
00035 #include "Interpreter.h"
00036 #include "FileInfo.h"
00037 #include "Stream.h"
00038 #include "PyTools.h"
00039 #include "Exception.h"
00040 #include "PyObjectBase.h"
00041 
00042 
00043 char format2[1024];  //Warning! Can't go over 512 characters!!!
00044 unsigned int format2_len = 1024;
00045 
00046 using namespace Base;
00047 
00048 #if PY_VERSION_HEX <= 0x02050000
00049 #error "Use Python2.5.x or higher"
00050 #endif
00051 
00052 
00053 PyException::PyException(void)
00054 {
00055     PP_Fetch_Error_Text();    /* fetch (and clear) exception */
00056     std::string prefix = PP_last_error_type; /* exception name text */
00057 //  prefix += ": ";
00058     std::string error = PP_last_error_info;            /* exception data text */
00059 #if 0
00060     // The Python exceptions might be thrown from nested functions, so take
00061     // into account not to add the same prefix several times
00062     std::string::size_type pos = error.find(prefix);
00063     if (pos == std::string::npos)
00064         _sErrMsg = prefix + error;
00065     else
00066         _sErrMsg = error;
00067 #endif
00068     _sErrMsg = error;
00069     _errorType = prefix;
00070 
00071 
00072     _stackTrace = PP_last_error_trace;     /* exception traceback text */
00073 
00074     PyErr_Clear(); // must be called to keep Python interpreter in a valid state (Werner)
00075 
00076 }
00077 
00078 // ---------------------------------------------------------
00079 
00080 SystemExitException::SystemExitException()
00081 {
00082     _sErrMsg = "System exit";
00083 }
00084 
00085 SystemExitException::SystemExitException(const SystemExitException &inst)
00086         : Exception(inst)
00087 {
00088 }
00089 
00090 // ---------------------------------------------------------
00091 
00092 
00093 InterpreterSingleton::InterpreterSingleton()
00094 {
00095     //Py_Initialize();
00096 }
00097 
00098 InterpreterSingleton::~InterpreterSingleton()
00099 {
00100 
00101 }
00102 
00103 
00104 std::string InterpreterSingleton::runString(const char *sCmd)
00105 {
00106     PyObject *module, *dict, *presult;          /* "exec code in d, d" */
00107 
00108     PyGILStateLocker locker;
00109     module = PP_Load_Module("__main__");         /* get module, init python */
00110     if (module == NULL)
00111         throw PyException();                         /* not incref'd */
00112     dict = PyModule_GetDict(module);            /* get dict namespace */
00113     if (dict == NULL)
00114         throw PyException();                           /* not incref'd */
00115 
00116 
00117     presult = PyRun_String(sCmd, Py_file_input, dict, dict); /* eval direct */
00118     if (!presult) {
00119         throw PyException();
00120     }
00121 
00122     PyObject* repr = PyObject_Repr(presult);
00123     Py_DECREF(presult);
00124     if (repr) {
00125         std::string ret(PyString_AsString(repr));
00126         Py_DECREF(repr);
00127         return ret;
00128     }
00129     else {
00130         PyErr_Clear();
00131         return std::string();
00132     }
00133 }
00134 
00135 void InterpreterSingleton::systemExit(void)
00136 {
00137     /* This code is taken from the original Python code */
00138     PyObject *exception, *value, *tb;
00139     int exitcode = 0;
00140 
00141     PyErr_Fetch(&exception, &value, &tb);
00142     if (Py_FlushLine())
00143         PyErr_Clear();
00144     fflush(stdout);
00145     if (value == NULL || value == Py_None)
00146         goto done;
00147     if (PyInstance_Check(value)) {
00148         /* The error code should be in the `code' attribute. */
00149         PyObject *code = PyObject_GetAttrString(value, "code");
00150         if (code) {
00151             Py_DECREF(value);
00152             value = code;
00153             if (value == Py_None)
00154                 goto done;
00155         }
00156         /* If we failed to dig out the 'code' attribute,
00157            just let the else clause below print the error. */
00158     }
00159     if (PyInt_Check(value))
00160         exitcode = (int)PyInt_AsLong(value);
00161     else {
00162         PyObject_Print(value, stderr, Py_PRINT_RAW);
00163         PySys_WriteStderr("\n");
00164         exitcode = 1;
00165     }
00166 done:
00167     /* Restore and clear the exception info, in order to properly decref
00168      * the exception, value, and traceback.  If we just exit instead,
00169      * these leak, which confuses PYTHONDUMPREFS output, and may prevent
00170      * some finalizers from running.
00171      */
00172     PyErr_Restore(exception, value, tb);
00173     PyErr_Clear();
00174     Py_Exit(exitcode);
00175     /* NOTREACHED */
00176 }
00177 
00178 void InterpreterSingleton::runInteractiveString(const char *sCmd)
00179 {
00180     PyObject *module, *dict, *presult;          /* "exec code in d, d" */
00181 
00182     PyGILStateLocker locker;
00183     module = PP_Load_Module("__main__");         /* get module, init python */
00184     if (module == NULL)
00185         throw PyException();                         /* not incref'd */
00186     dict = PyModule_GetDict(module);            /* get dict namespace */
00187     if (dict == NULL)
00188         throw PyException();                           /* not incref'd */
00189 
00190     presult = PyRun_String(sCmd, Py_single_input, dict, dict); /* eval direct */
00191     if (!presult) {
00192         if (PyErr_ExceptionMatches(PyExc_SystemExit)) {
00193             //systemExit();
00194             throw SystemExitException();
00195         }
00196         /* get latest python exception information */
00197         /* and print the error to the error output */
00198         PyObject *errobj, *errdata, *errtraceback;
00199         PyErr_Fetch(&errobj, &errdata, &errtraceback);
00200 
00201         Exception exc; // do not use PyException since this clears the error indicator
00202         if (PyString_Check(errdata))
00203             exc.setMessage(PyString_AsString(errdata));
00204         PyErr_Restore(errobj, errdata, errtraceback);
00205         if (PyErr_Occurred())
00206             PyErr_Print();
00207         throw exc;
00208     }
00209     else
00210         Py_DECREF(presult);
00211 }
00212 
00213 void InterpreterSingleton::runFile(const char*pxFileName)
00214 {
00215 #ifdef FC_OS_WIN32
00216     FileInfo fi(pxFileName);
00217     FILE *fp = _wfopen(fi.toStdWString().c_str(),L"r");
00218 #else
00219     FILE *fp = fopen(pxFileName,"r");
00220 #endif
00221     if (fp) {
00222         PyGILStateLocker locker;
00223         //std::string encoding = PyUnicode_GetDefaultEncoding();
00224         //PyUnicode_SetDefaultEncoding("utf-8");
00225         int ret = PyRun_SimpleFile(fp, pxFileName);
00226         //PyUnicode_SetDefaultEncoding(encoding.c_str());
00227         fclose(fp);
00228         if (ret != 0)
00229             throw PyException();
00230     }
00231     else {
00232         std::string err = "Unknown file: ";
00233         err += pxFileName;
00234         err += "\n";
00235         throw Exception(err);
00236     }
00237 }
00238 
00239 bool InterpreterSingleton::loadModule(const char* psModName)
00240 {
00241     // buffer acrobatics
00242     //PyBuf ModName(psModName);
00243     PyObject *module;
00244 
00245     PyGILStateLocker locker;
00246     module = PP_Load_Module(psModName);
00247 
00248     if (!module)
00249         throw PyException();
00250 
00251     return true;
00252 }
00253 
00254 void InterpreterSingleton::addType(PyTypeObject* Type,PyObject* Module, const char * Name)
00255 {
00256     // NOTE: To finish the initialization of our own type objects we must
00257     // call PyType_Ready, otherwise we run into a segmentation fault, later on.
00258     // This function is responsible for adding inherited slots from a type's base class.
00259     if (PyType_Ready(Type) < 0) return;
00260     union PyType_Object pyType = {Type};
00261     PyModule_AddObject(Module, Name, pyType.o);
00262 }
00263 
00264 void InterpreterSingleton::addPythonPath(const char* Path)
00265 {
00266     PyGILStateLocker locker;
00267     PyObject *list = PySys_GetObject("path");
00268     PyObject *path = PyString_FromString(Path);
00269     PyList_Append(list, path);
00270     Py_DECREF(path);
00271     PySys_SetObject("path", list);
00272 }
00273 
00274 const char* InterpreterSingleton::init(int argc,char *argv[])
00275 {
00276     if (!Py_IsInitialized()) {
00277         Py_SetProgramName(argv[0]);
00278         PyEval_InitThreads();
00279         Py_Initialize();
00280         PySys_SetArgv(argc, argv);
00281         this->_global = PyEval_SaveThread();
00282     }
00283 
00284     return Py_GetPath();
00285 }
00286 
00287 int InterpreterSingleton::cleanup(void (*func)(void))
00288 {
00289     return Py_AtExit( func );
00290 }
00291 
00292 void InterpreterSingleton::finalize()
00293 {
00294     try {
00295         PyEval_RestoreThread(this->_global);
00296         Py_Finalize();
00297     }
00298     catch (...) {
00299     }
00300 }
00301 
00302 void InterpreterSingleton::runStringArg(const char * psCom,...)
00303 {
00304     // va stuff
00305     va_list namelessVars;
00306     va_start(namelessVars, psCom);  // Get the "..." vars
00307     int len = vsnprintf(format2, format2_len, psCom, namelessVars);
00308     va_end(namelessVars);
00309     if ( len == -1 ) {
00310         // argument too long
00311         assert(false);
00312     }
00313 
00314     runString(format2);
00315 }
00316 
00317 
00318 // Singelton:
00319 
00320 InterpreterSingleton * InterpreterSingleton::_pcSingelton = 0;
00321 
00322 InterpreterSingleton & InterpreterSingleton::Instance(void)
00323 {
00324     // not initialized!
00325     if (!_pcSingelton)
00326         _pcSingelton = new InterpreterSingleton();
00327     return *_pcSingelton;
00328 }
00329 
00330 void InterpreterSingleton::Destruct(void)
00331 {
00332     // not initialized or double destruct!
00333     assert(_pcSingelton);
00334     delete _pcSingelton;
00335     _pcSingelton = 0;
00336 }
00337 
00338 int InterpreterSingleton::runCommandLine(const char *prompt)
00339 {
00340     PyGILStateLocker locker;
00341     return PP_Run_Command_Line(prompt);
00342 }
00343 
00348 void InterpreterSingleton::runMethodVoid(PyObject *pobject, const char *method)
00349 {
00350     PyGILStateLocker locker;
00351     if (PP_Run_Method(pobject ,    // object
00352                       method,  // run method
00353                       0,                           // no return type
00354                       0,                       // so no return object
00355                       "()")                // no arguments
00356             != 0)
00357         throw PyException(/*"Error running InterpreterSingleton::RunMethodVoid()"*/);
00358 
00359 }
00360 
00361 PyObject* InterpreterSingleton::runMethodObject(PyObject *pobject, const char *method)
00362 {
00363     PyObject *pcO;
00364 
00365     PyGILStateLocker locker;
00366     if (PP_Run_Method(pobject ,    // object
00367                       method,  // run method
00368                       "O",                 // return type
00369                       &pcO,                // return object
00370                       "()")                // no arguments
00371             != 0)
00372         throw PyException();
00373 
00374     return pcO;
00375 }
00376 
00377 void InterpreterSingleton::runMethod(PyObject *pobject, const char *method,
00378                                      const char *resfmt,   void *cresult,        /* convert to c/c++ */
00379                                      const char *argfmt,   ...  )                /* convert to python */
00380 {
00381     PyObject *pmeth, *pargs, *presult;
00382     va_list argslist;                              /* "pobject.method(args)" */
00383     va_start(argslist, argfmt);
00384 
00385     PyGILStateLocker locker;
00386     pmeth = PyObject_GetAttrString(pobject, method);
00387     if (pmeth == NULL)                             /* get callable object */
00388         throw Exception("Error running InterpreterSingleton::RunMethod() method not defined");                                 /* bound method? has self */
00389 
00390     pargs = Py_VaBuildValue(argfmt, argslist);     /* args: c->python */
00391 
00392     if (pargs == NULL) {
00393         Py_DECREF(pmeth);
00394         throw Exception("InterpreterSingleton::RunMethod() wrong arguments");
00395     }
00396 
00397     presult = PyEval_CallObject(pmeth, pargs);   /* run interpreter */
00398 
00399     Py_DECREF(pmeth);
00400     Py_DECREF(pargs);
00401     if (PP_Convert_Result(presult, resfmt, cresult)!= 0) {
00402         if ( PyErr_Occurred() )
00403             PyErr_Print();
00404         throw Exception("Error running InterpreterSingleton::RunMethod() exception in called method");
00405     }
00406 }
00407 
00408 void InterpreterSingleton::dbgObserveFile(const char* sFileName)
00409 {
00410     if (sFileName)
00411         _cDebugFileName = sFileName;
00412     else
00413         _cDebugFileName = "";
00414 }
00415 
00416 void InterpreterSingleton::dbgSetBreakPoint(unsigned int /*uiLineNumber*/)
00417 {
00418 
00419 }
00420 
00421 void InterpreterSingleton::dbgUnsetBreakPoint(unsigned int /*uiLineNumber*/)
00422 {
00423 
00424 }
00425 
00426 void InterpreterSingleton::dbgStep(void)
00427 {
00428 
00429 }
00430 
00431 const std::string InterpreterSingleton::strToPython(const char* Str)
00432 {
00433     std::string result;
00434     const char *It=Str;
00435 
00436     while (*It != '\0') {
00437         switch (*It) {
00438         case '\\':
00439             result += "\\\\";
00440             break;
00441         case '\"':
00442             result += "\\\"";
00443             break;
00444         case '\'':
00445             result += "\\\'";
00446             break;
00447         default:
00448             result += *It;
00449         }
00450         It++;
00451     }
00452 
00453     return result;
00454 }
00455 
00456 // --------------------------------------------------------------------
00457 
00458 int getSWIGVersionFromModule(const std::string& module)
00459 {
00460     static std::map<std::string, int> moduleMap;
00461     std::map<std::string, int>::iterator it = moduleMap.find(module);
00462     if (it != moduleMap.end()) {
00463         return it->second;
00464     }
00465     else {
00466         try {
00467             // Get the module and check its __file__ attribute
00468             Py::Dict dict(PyImport_GetModuleDict());
00469             if (!dict.hasKey(module))
00470                 return 0;
00471             Py::Module mod(module);
00472             Py::String file(mod.getAttr("__file__"));
00473             std::string filename = (std::string)file;
00474             // file can have the extension .py or .pyc
00475             filename = filename.substr(0, filename.rfind("."));
00476             filename += ".py";
00477             boost::regex rx("^# Version ([1-9])\\.([1-9])\\.([1-9][0-9])");
00478             boost::cmatch what;
00479 
00480             std::string line;
00481             Base::FileInfo fi(filename);
00482 
00483             Base::ifstream str(fi, std::ios::in);
00484             while (str && std::getline(str, line)) {
00485                 if (boost::regex_match(line.c_str(), what, rx)) {
00486                     int major = std::atoi(what[1].first);
00487                     int minor = std::atoi(what[2].first);
00488                     int micro = std::atoi(what[3].first);
00489                     int version = (major<<16)+(minor<<8)+micro;
00490                     moduleMap[module] = version;
00491                     return version;
00492                 }
00493             }
00494         }
00495         catch (Py::Exception& e) {
00496             e.clear();
00497         }
00498     }
00499 
00500 #if (defined(HAVE_SWIG) && (HAVE_SWIG == 1))
00501     moduleMap[module] = 0;
00502 #endif
00503     return 0;
00504 }
00505 
00506 #if (defined(HAVE_SWIG) && (HAVE_SWIG == 1))
00507 namespace Swig_python { extern int createSWIGPointerObj_T(const char* TypeName, void* obj, PyObject** ptr, int own); }
00508 #endif
00509 namespace Swig_1_3_25 { extern int createSWIGPointerObj_T(const char* TypeName, void* obj, PyObject** ptr, int own); }
00510 namespace Swig_1_3_33 { extern int createSWIGPointerObj_T(const char* TypeName, void* obj, PyObject** ptr, int own); }
00511 namespace Swig_1_3_36 { extern int createSWIGPointerObj_T(const char* TypeName, void* obj, PyObject** ptr, int own); }
00512 namespace Swig_1_3_38 { extern int createSWIGPointerObj_T(const char* TypeName, void* obj, PyObject** ptr, int own); }
00513 namespace Swig_1_3_40 { extern int createSWIGPointerObj_T(const char* TypeName, void* obj, PyObject** ptr, int own); }
00514 
00515 PyObject* InterpreterSingleton::createSWIGPointerObj(const char* Module, const char* TypeName, void* Pointer, int own)
00516 {
00517     int result = 0;
00518     PyObject* proxy=0;
00519     PyGILStateLocker locker;
00520     int version = getSWIGVersionFromModule(Module);
00521     switch (version&0xff)
00522     {
00523     case 25:
00524         result = Swig_1_3_25::createSWIGPointerObj_T(TypeName, Pointer, &proxy, own);
00525         break;
00526     case 33:
00527         result = Swig_1_3_33::createSWIGPointerObj_T(TypeName, Pointer, &proxy, own);
00528         break;
00529     case 36:
00530         result = Swig_1_3_36::createSWIGPointerObj_T(TypeName, Pointer, &proxy, own);
00531         break;
00532     case 38:
00533         result = Swig_1_3_38::createSWIGPointerObj_T(TypeName, Pointer, &proxy, own);
00534         break;
00535     case 40:
00536         result = Swig_1_3_40::createSWIGPointerObj_T(TypeName, Pointer, &proxy, own);
00537         break;
00538     default:
00539 #if (defined(HAVE_SWIG) && (HAVE_SWIG == 1))
00540     result = Swig_python::createSWIGPointerObj_T(TypeName, Pointer, &proxy, own);
00541 #else
00542     result = -1; // indicates error
00543 #endif
00544     }
00545 
00546     if (result == 0)
00547         return proxy;
00548 
00549     // none of the SWIG's succeeded
00550     throw Base::Exception("No SWIG wrapped library loaded");
00551 }
00552 
00553 #if (defined(HAVE_SWIG) && (HAVE_SWIG == 1))
00554 namespace Swig_python { extern int convertSWIGPointerObj_T(const char* TypeName, PyObject* obj, void** ptr, int flags); }
00555 #endif
00556 namespace Swig_1_3_25 { extern int convertSWIGPointerObj_T(const char* TypeName, PyObject* obj, void** ptr, int flags); }
00557 namespace Swig_1_3_33 { extern int convertSWIGPointerObj_T(const char* TypeName, PyObject* obj, void** ptr, int flags); }
00558 namespace Swig_1_3_36 { extern int convertSWIGPointerObj_T(const char* TypeName, PyObject* obj, void** ptr, int flags); }
00559 namespace Swig_1_3_38 { extern int convertSWIGPointerObj_T(const char* TypeName, PyObject* obj, void** ptr, int flags); }
00560 namespace Swig_1_3_40 { extern int convertSWIGPointerObj_T(const char* TypeName, PyObject* obj, void** ptr, int flags); }
00561 
00562 bool InterpreterSingleton::convertSWIGPointerObj(const char* Module, const char* TypeName, PyObject* obj, void** ptr, int flags)
00563 {
00564     int result = 0;
00565     PyGILStateLocker locker;
00566     int version = getSWIGVersionFromModule(Module);
00567     switch (version&0xff)
00568     {
00569     case 25:
00570         result = Swig_1_3_25::convertSWIGPointerObj_T(TypeName, obj, ptr, flags);
00571         break;
00572     case 33:
00573         result = Swig_1_3_33::convertSWIGPointerObj_T(TypeName, obj, ptr, flags);
00574         break;
00575     case 36:
00576         result = Swig_1_3_36::convertSWIGPointerObj_T(TypeName, obj, ptr, flags);
00577         break;
00578     case 38:
00579         result = Swig_1_3_38::convertSWIGPointerObj_T(TypeName, obj, ptr, flags);
00580         break;
00581     case 40:
00582         result = Swig_1_3_40::convertSWIGPointerObj_T(TypeName, obj, ptr, flags);
00583         break;
00584     default:
00585 #if (defined(HAVE_SWIG) && (HAVE_SWIG == 1))
00586         result = Swig_python::convertSWIGPointerObj_T(TypeName, obj, ptr, flags);
00587 #else
00588         result = -1; // indicates error
00589 #endif
00590     }
00591 
00592     if (result == 0)
00593         return true;
00594 
00595     // none of the SWIG's succeeded
00596     throw Base::Exception("No SWIG wrapped library loaded");
00597 }
00598 
00599 #if (defined(HAVE_SWIG) && (HAVE_SWIG == 1))
00600 namespace Swig_python { extern void cleanupSWIG_T(const char* TypeName); }
00601 #endif
00602 namespace Swig_1_3_25 { extern void cleanupSWIG_T(const char* TypeName); }
00603 namespace Swig_1_3_33 { extern void cleanupSWIG_T(const char* TypeName); }
00604 namespace Swig_1_3_36 { extern void cleanupSWIG_T(const char* TypeName); }
00605 namespace Swig_1_3_38 { extern void cleanupSWIG_T(const char* TypeName); }
00606 namespace Swig_1_3_40 { extern void cleanupSWIG_T(const char* TypeName); }
00607 
00608 void InterpreterSingleton::cleanupSWIG(const char* TypeName)
00609 {
00610     PyGILStateLocker locker;
00611 #if (defined(HAVE_SWIG) && (HAVE_SWIG == 1))
00612     Swig_python::cleanupSWIG_T(TypeName);
00613 #endif
00614     Swig_1_3_25::cleanupSWIG_T(TypeName);
00615     Swig_1_3_33::cleanupSWIG_T(TypeName);
00616     Swig_1_3_36::cleanupSWIG_T(TypeName);
00617     Swig_1_3_38::cleanupSWIG_T(TypeName);
00618     Swig_1_3_40::cleanupSWIG_T(TypeName);
00619 }

Generated on Wed Nov 23 19:00:19 2011 for FreeCAD by  doxygen 1.6.1