00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifndef BASE_PYOBJECTBASE_H
00024 #define BASE_PYOBJECTBASE_H
00025
00026
00027
00028
00029 #if defined (_POSIX_C_SOURCE)
00030 # undef _POSIX_C_SOURCE
00031 #endif
00032 #if defined (_XOPEN_SOURCE)
00033 # undef _XOPEN_SOURCE
00034 #endif
00035
00036
00037 #undef slots
00038 # include <Python.h>
00039 #define slots
00040 #include <iostream>
00041 #include <bitset>
00042
00043 #include <typeinfo>
00044 #include "Exception.h"
00045 #include <CXX/Objects.hxx>
00046
00047
00048
00060 #define PYFUNCDEF_S(SFUNC) static PyObject* SFUNC (PyObject *self,PyObject *args,PyObject *kwd);
00061
00062
00076 #define PYFUNCIMP_S(CLASS,SFUNC) PyObject* CLASS::SFUNC (PyObject *self,PyObject *args,PyObject *kwd)
00077
00081 union PyType_Object {
00082 PyTypeObject *t;
00083 PyObject *o;
00084 };
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094 namespace Base
00095 {
00096
00097 inline int streq(const char *A, const char *B)
00098 { return strcmp(A,B) == 0;};
00099
00100
00101 inline void Assert(int expr, char *msg)
00102 {
00103 if (!expr)
00104 {
00105 fprintf(stderr, "%s\n", msg);
00106 exit(-1);
00107 };
00108 }
00109
00110 }
00111
00112
00113
00114
00115
00117 #define Py_NEWARGS 1
00119 #define Py_Return Py_INCREF(Py_None); return Py_None;
00121 #define Py_Error(E, M) {PyErr_SetString(E, M); return NULL;}
00123 #define Py_Try(F) {if (!(F)) return NULL;}
00125 #define Py_Assert(A,E,M) {if (!(A)) {PyErr_SetString(E, M); return NULL;}}
00126
00127
00129 typedef PyTypeObject * PyParentObject;
00130
00131
00133 #define Py_Header \
00134 public: \
00135 static PyTypeObject Type; \
00136 static PyMethodDef Methods[]; \
00137 static PyParentObject Parents[]; \
00138 virtual PyTypeObject *GetType(void) {return &Type;}; \
00139 virtual PyParentObject *GetParents(void) {return Parents;}
00140
00145 #define _getattr_up(Parent) \
00146 { \
00147 PyObject *rvalue = Py_FindMethod(Methods, this, attr); \
00148 if (rvalue == NULL) \
00149 { \
00150 PyErr_Clear(); \
00151 return Parent::_getattr(attr); \
00152 } \
00153 else \
00154 return rvalue; \
00155 }
00156
00157
00158
00159
00160
00161 namespace Base
00162 {
00163
00164
00186 class BaseExport PyObjectBase : public PyObject
00187 {
00192 Py_Header;
00193
00194 protected:
00196 virtual ~PyObjectBase();
00197
00198 public:
00203 PyObjectBase(void*, PyTypeObject *T);
00205 static void PyDestructor(PyObject *P)
00206 { delete ((PyObjectBase *) P); }
00208 PyObjectBase* IncRef(void) {Py_INCREF(this);return this;}
00210 PyObjectBase* DecRef(void) {Py_DECREF(this);return this;}
00211
00221 virtual PyObject *_getattr(char *attr);
00223 static PyObject *__getattr(PyObject * PyObj, char *attr);
00224
00231 virtual int _setattr(char *attr, PyObject *value);
00233 static int __setattr(PyObject *PyObj, char *attr, PyObject *value);
00234
00249 virtual PyObject *_repr(void);
00251 static PyObject *__repr(PyObject *PyObj) {
00252 if (!((PyObjectBase*) PyObj)->isValid()){
00253 PyErr_Format(PyExc_ReferenceError, "Cannot print representation of deleted object");
00254 return NULL;
00255 }
00256 return ((PyObjectBase*) PyObj)->_repr();
00257 }
00258
00263 virtual int PyInit(PyObject* , PyObject* )
00264 {
00265 return 0;
00266 }
00268 static int __PyInit(PyObject* self, PyObject* args, PyObject* kwd)
00269 {
00270 return ((PyObjectBase*) self)->PyInit(args, kwd);
00271 }
00272
00273 void setInvalid() {
00274
00275 StatusBits.reset(0);
00276 _pcTwinPointer = 0;
00277 }
00278
00279 bool isValid() {
00280 return StatusBits.test(0);
00281 }
00282
00283 void setConst() {
00284
00285 StatusBits.set(1);
00286 }
00287
00288 bool isConst() {
00289 return StatusBits.test(1);
00290 }
00291
00292 void setAttributeOf(const char* attr, const PyObjectBase* par);
00293 void startNotify();
00294
00295 typedef void* PointerType ;
00296
00297 protected:
00298 std::bitset<32> StatusBits;
00300 void * _pcTwinPointer;
00301 PyObjectBase* parent;
00302 char* attribute;
00303 };
00304
00305
00306
00307
00326 #define PYFUNCDEF_D(CLASS,DFUNC) PyObject * DFUNC (PyObject *args); \
00327 static PyObject * s##DFUNC (PyObject *self, PyObject *args, PyObject * ){return (( CLASS *)self)-> DFUNC (args);};
00328
00341 #define PYFUNCIMP_D(CLASS,DFUNC) PyObject* CLASS::DFUNC (PyObject *args)
00342
00343
00344
00369 #define PYMETHODEDEF(FUNC) {"" #FUNC "",(PyCFunction) s##FUNC,Py_NEWARGS},
00370
00371
00372
00410 #define PY_TRY try
00411
00412 #ifndef DONT_CATCH_CXX_EXCEPTIONS
00414 # define PY_CATCH catch(Base::Exception &e) \
00415 { \
00416 std::string str; \
00417 str += "FreeCAD exception thrown ("; \
00418 str += e.what(); \
00419 str += ")"; \
00420 e.ReportException(); \
00421 Py_Error(PyExc_Exception,str.c_str()); \
00422 } \
00423 catch(std::exception &e) \
00424 { \
00425 std::string str; \
00426 str += "STL exception thrown ("; \
00427 str += e.what(); \
00428 str += ")"; \
00429 Base::Console().Error(str.c_str()); \
00430 Py_Error(PyExc_Exception,str.c_str()); \
00431 } \
00432 catch(const Py::Exception&) \
00433 { \
00434 return NULL; \
00435 } \
00436 catch(const char *e) \
00437 { \
00438 Py_Error(PyExc_Exception,e); \
00439 } \
00440 catch(...) \
00441 { \
00442 Py_Error(PyExc_Exception,"Unknown C++ exception"); \
00443 }
00444
00445 #else
00447 # define PY_CATCH catch(Base::Exception &e) \
00448 { \
00449 std::string str; \
00450 str += "FreeCAD exception thrown ("; \
00451 str += e.what(); \
00452 str += ")"; \
00453 e.ReportException(); \
00454 Py_Error(PyExc_Exception,str.c_str()); \
00455 } \
00456 catch(std::exception &e) \
00457 { \
00458 std::string str; \
00459 str += "STL exception thrown ("; \
00460 str += e.what(); \
00461 str += ")"; \
00462 Base::Console().Error(str.c_str()); \
00463 Py_Error(PyExc_Exception,str.c_str()); \
00464 } \
00465 catch(const Py::Exception&) \
00466 { \
00467 return NULL; \
00468 } \
00469 catch(const char *e) \
00470 { \
00471 Py_Error(PyExc_Exception,e); \
00472 }
00473
00474 #endif // DONT_CATCH_CXX_EXCEPTIONS
00475
00477 #define PARENTSBasePyObjectBase &Base::PyObjectBase::Type,NULL
00478
00483 inline PyObject * PyAsUnicodeObject(const char *str)
00484 {
00485
00486 PyObject *p = PyUnicode_DecodeUTF8(str,strlen(str),0);
00487 if(!p)
00488 throw Base::Exception("UTF8 conversion failure at PyAsUnicodeString()");
00489 return p;
00490 }
00491
00492 inline PyObject * PyAsUnicodeObject(const std::string &str)
00493 {
00494 return PyAsUnicodeObject(str.c_str());
00495 }
00496
00497
00498 }
00499
00500
00501 #endif // BASE_PYOBJECTBASE_H