PyObjectBase.h

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (c) Jürgen Riegel          (juergen.riegel@web.de) 2002     *
00003  *                                                                         *
00004  *   This file is part of the FreeCAD CAx development system.              *
00005  *                                                                         *
00006  *   This library is free software; you can redistribute it and/or         *
00007  *   modify it under the terms of the GNU Library General Public           *
00008  *   License as published by the Free Software Foundation; either          *
00009  *   version 2 of the License, or (at your option) any later version.      *
00010  *                                                                         *
00011  *   This library  is distributed in the hope that it will be useful,      *
00012  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00013  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00014  *   GNU Library General Public License for more details.                  *
00015  *                                                                         *
00016  *   You should have received a copy of the GNU Library General Public     *
00017  *   License along with this library; see the file COPYING.LIB. If not,    *
00018  *   write to the Free Software Foundation, Inc., 59 Temple Place,         *
00019  *   Suite 330, Boston, MA  02111-1307, USA                                *
00020  *                                                                         *
00021  ***************************************************************************/
00022 
00023 #ifndef BASE_PYOBJECTBASE_H
00024 #define BASE_PYOBJECTBASE_H
00025 
00026 // Std. configurations
00027 
00028 // (re-)defined in pyconfig.h
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 // needed header
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  * Basic defines
00090 ------------------------------*/
00091 //typedef const char * version;     // define "version"
00092 
00093 
00094 namespace Base
00095 {
00096 
00097 inline int streq(const char *A, const char *B)  // define "streq"
00098 { return strcmp(A,B) == 0;};
00099 
00100 
00101 inline void Assert(int expr, char *msg)         // C++ assert
00102 {
00103     if (!expr) 
00104     {
00105       fprintf(stderr, "%s\n", msg);
00106       exit(-1);
00107     };
00108 }
00109 
00110 }
00111 
00112 /*------------------------------
00113  * Python defines
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  * PyObjectBase
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)   // python wrapper
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);    // _setattr method
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* /*args*/, PyObject* /*kwd*/)
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         // first bit is not set, i.e. invalid
00275         StatusBits.reset(0);
00276         _pcTwinPointer = 0;
00277     }
00278 
00279     bool isValid() {
00280         return StatusBits.test(0);
00281     }
00282 
00283     void setConst() {
00284         // second bit is set, i.e. immutable
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 * /*kwd*/){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     // Returns a new reference, don't increment it!
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 } // namespace Base
00499 
00500 
00501 #endif // BASE_PYOBJECTBASE_H

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