[PD-cvs] externals/grill/py/source pyprefix.h,NONE,1.1 pysymbol.cpp,NONE,1.1 pysymbol.h,NONE,1.1 bound.cpp,1.13,1.14 clmeth.cpp,1.12,1.13 main.cpp,1.20,1.21 main.h,1.27,1.28 modmeth.cpp,1.13,1.14 py.cpp,1.17,1.18 pyargs.cpp,1.10,1.11 pyext.cpp,1.24,1.25 pyext.h,1.18,1.19

Thomas Grill xovo at users.sourceforge.net
Tue Jan 11 05:59:29 CET 2005


Update of /cvsroot/pure-data/externals/grill/py/source
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv24330/source

Modified Files:
	bound.cpp clmeth.cpp main.cpp main.h modmeth.cpp py.cpp 
	pyargs.cpp pyext.cpp pyext.h 
Added Files:
	pyprefix.h pysymbol.cpp pysymbol.h 
Log Message:
added symbol type
fixed incorrect unbinding of instance methods
fixes for symbol type
little restructuring


Index: clmeth.cpp
===================================================================
RCS file: /cvsroot/pure-data/externals/grill/py/source/clmeth.cpp,v
retrieving revision 1.12
retrieving revision 1.13
diff -C2 -d -r1.12 -r1.13
*** clmeth.cpp	9 Jan 2005 04:59:30 -0000	1.12
--- clmeth.cpp	11 Jan 2005 04:59:27 -0000	1.13
***************
*** 14,20 ****
  PyMethodDef pyext::meth_tbl[] = 
  {
      {"__init__", pyext::pyext__init__, METH_VARARGS, "Constructor"},
      {"__del__", pyext::pyext__del__, METH_VARARGS, "Destructor"},
! 
      {"_outlet", pyext::pyext_outlet, METH_VARARGS,"Send message to outlet"},
  #if FLEXT_SYS == FLEXT_SYS_PD
--- 14,21 ----
  PyMethodDef pyext::meth_tbl[] = 
  {
+ /*
      {"__init__", pyext::pyext__init__, METH_VARARGS, "Constructor"},
      {"__del__", pyext::pyext__del__, METH_VARARGS, "Destructor"},
! */
      {"_outlet", pyext::pyext_outlet, METH_VARARGS,"Send message to outlet"},
  #if FLEXT_SYS == FLEXT_SYS_PD
***************
*** 57,60 ****
--- 58,62 ----
  ;
  
+ /*
  PyObject* pyext::pyext__init__(PyObject *,PyObject *args)
  {
***************
*** 72,75 ****
--- 74,78 ----
      return Py_None;
  }
+ */
  
  PyObject* pyext::pyext_setattr(PyObject *,PyObject *args)
***************
*** 83,86 ****
--- 86,91 ----
  
  	bool handled = false;
+ 
+ /*
      if(PyString_Check(name)) {
  	    char* sname = PyString_AsString(name);
***************
*** 89,93 ****
  		}
  	}
! 
  	if(!handled) {
  		if(PyInstance_Check(self)) 
--- 94,98 ----
  		}
  	}
! */
  	if(!handled) {
  		if(PyInstance_Check(self)) 
***************
*** 110,115 ****
  
      if(PyString_Check(name)) {
! 	    char* sname = PyString_AsString(name);
! 		if (sname) {
  			if(!strcmp(sname,"_shouldexit")) {
  				pyext *ext = GetThis(self); 
--- 115,120 ----
  
      if(PyString_Check(name)) {
! 	    char* sname = PyString_AS_STRING(name);
! 		if(sname) {
  			if(!strcmp(sname,"_shouldexit")) {
  				pyext *ext = GetThis(self); 
***************
*** 123,128 ****
  	if(!ret) { 
  #if PY_VERSION_HEX >= 0x02020000
!         // \todo borrowed or new???
! 		ret = PyObject_GenericGetAttr(self,name);
  #else
  		if(PyInstance_Check(self))
--- 128,132 ----
  	if(!ret) { 
  #if PY_VERSION_HEX >= 0x02020000
! 		ret = PyObject_GenericGetAttr(self,name); // new reference (?)
  #else
  		if(PyInstance_Check(self))
***************
*** 142,155 ****
      FLEXT_ASSERT(PyTuple_Check(args));
  
      // borrowed references!
! 	PyObject *self = PyTuple_GetItem(args,0);
! 	PyObject *outl = PyTuple_GetItem(args,1);
  	if(
! 		self && PyInstance_Check(self) && 
! 		outl && PyInt_Check(outl)
  	) {
  		pyext *ext = GetThis(self);
  
- 		int sz = PyTuple_Size(args);
  		PyObject *val;
          
--- 146,161 ----
      FLEXT_ASSERT(PyTuple_Check(args));
  
+     int sz = PyTuple_GET_SIZE(args);
+ 
      // borrowed references!
!     PyObject *self,*outl;
! 
  	if(
!         sz >= 2 &&
! 		(self = PyTuple_GET_ITEM(args,0)) != NULL && PyInstance_Check(self) && 
! 		(outl = PyTuple_GET_ITEM(args,1)) != NULL && PyInt_Check(outl)
  	) {
  		pyext *ext = GetThis(self);
  
  		PyObject *val;
          
***************
*** 157,161 ****
              sz == 3 && 
              PySequence_Check(
!                 val = PyTuple_GetItem(args,2) // borrow reference
              );
  
--- 163,167 ----
              sz == 3 && 
              PySequence_Check(
!                 val = PyTuple_GET_ITEM(args,2) // borrow reference
              );
  
***************
*** 256,265 ****
      FLEXT_ASSERT(PyTuple_Check(args));
  
  	bool ok = false;
! 	PyObject *self = PyTuple_GetItem(args,0); // borrowed ref
! 	if(self && PyInstance_Check(self)) {
  		pyext *ext = GetThis(self);
  
- 		int sz = PySequence_Size(args);
  		PyObject *val;
  
--- 262,275 ----
      FLEXT_ASSERT(PyTuple_Check(args));
  
+     int sz = PyTuple_GET_SIZE(args);
+ 
  	bool ok = false;
! 	PyObject *self; // borrowed ref
! 	if(
!         sz >= 1 &&
!         (self = PyTuple_GET_ITEM(args,0)) != NULL && PyInstance_Check(self)
!     ) {
  		pyext *ext = GetThis(self);
  
  		PyObject *val;
  
***************
*** 267,271 ****
              sz == 2 && 
              PySequence_Check(
!                 val = PyTuple_GetItem(args,1) // borrowed ref
              );
  
--- 277,281 ----
              sz == 2 && 
              PySequence_Check(
!                 val = PyTuple_GET_ITEM(args,1) // borrowed ref
              );
  

--- NEW FILE: pyprefix.h ---
/* 

py/pyext - python script object for PD and MaxMSP

Copyright (c)2002-2005 Thomas Grill (gr at grrrr.org)
For information on usage and redistribution, and for a DISCLAIMER OF ALL
WARRANTIES, see the file, "license.txt," in this distribution.  

*/

#ifndef __PREFIX_H
#define __PREFIX_H

#define FLEXT_ATTRIBUTES 1
#include <flext.h>

#if FLEXT_OS == FLEXT_OS_MAC
#include <Python/Python.h>
#else
#include <Python.h>
#endif

#if !defined(FLEXT_VERSION) || (FLEXT_VERSION < 500)
#error You need at least flext version 0.5.0
#endif

#endif

Index: main.cpp
===================================================================
RCS file: /cvsroot/pure-data/externals/grill/py/source/main.cpp,v
retrieving revision 1.20
retrieving revision 1.21
diff -C2 -d -r1.20 -r1.21
*** main.cpp	10 Jan 2005 05:00:56 -0000	1.20
--- main.cpp	11 Jan 2005 04:59:27 -0000	1.21
***************
*** 57,60 ****
--- 57,62 ----
  
  
+ void initsymbol();
+ 
  void py::lib_setup()
  {
***************
*** 77,82 ****
  
  #ifdef FLEXT_DEBUG
! //	Py_DebugFlag = 1;
! 	Py_VerboseFlag = 1;
  #endif
  
--- 79,83 ----
  
  #ifdef FLEXT_DEBUG
! //	Py_VerboseFlag = 1;
  #endif
  
***************
*** 100,103 ****
--- 101,116 ----
  	PyModule_AddStringConstant(module_obj,"__doc__",(char *)py_doc);
  
+     // add symbol type
+     initsymbol();
+     PyModule_AddObject(module_obj,"Symbol",(PyObject *)&pySymbol_Type);
+ 
+     // pre-defined symbols
+     PyModule_AddObject(module_obj,"_s_",(PyObject *)pySymbol__);
+     PyModule_AddObject(module_obj,"_s_bang",(PyObject *)pySymbol_bang);
+     PyModule_AddObject(module_obj,"_s_list",(PyObject *)pySymbol_list);
+     PyModule_AddObject(module_obj,"_s_symbol",(PyObject *)pySymbol_symbol);
+     PyModule_AddObject(module_obj,"_s_float",(PyObject *)pySymbol_float);
+     PyModule_AddObject(module_obj,"_s_int",(PyObject *)pySymbol_int);
+ 
  	// redirect stdout
  	PyObject* py_out;
***************
*** 125,128 ****
--- 138,151 ----
  
  
+ void py::Setup(t_classid c)
+ {
+ 	FLEXT_CADDMETHOD_(c,0,"doc",m_doc);
+ 	FLEXT_CADDMETHOD_(c,0,"dir",m_dir);
+ #ifdef FLEXT_THREADS
+ 	FLEXT_CADDATTR_VAR1(c,"detach",detach);
+ 	FLEXT_CADDMETHOD_(c,0,"stop",m_stop);
+ #endif
+ }
+ 
  py::py(): 
  	module(NULL),
***************
*** 151,155 ****
  		// Wait forever
  		post("%s - Waiting for thread termination!",thisName());
! 		while(thrcount) Sleep(0.2f);
  		post("%s - Okay, all threads have terminated",thisName());
  	}
--- 174,178 ----
  		// Wait forever
  		post("%s - Waiting for thread termination!",thisName());
! 		while(thrcount) Sleep(0.01f);
  		post("%s - Okay, all threads have terminated",thisName());
  	}
***************
*** 199,203 ****
  		if(docf && PyString_Check(docf)) {
  			post("");
! 			const char *s = PyString_AsString(docf);
  
  			// FIX: Python doc strings can easily be larger than 1k characters
--- 222,226 ----
  		if(docf && PyString_Check(docf)) {
  			post("");
! 			const char *s = PyString_AS_STRING(docf);
  
  			// FIX: Python doc strings can easily be larger than 1k characters
***************
*** 227,230 ****
--- 250,257 ----
  }
  
+ void py::m_click()
+ {
+     // this should once open the editor....
+ }
  
  void py::SetArgs(int argc,const t_atom *argv)
***************
*** 252,257 ****
  
  	module = PyImport_ImportModule((char *)name);  // increases module_obj ref count by one
! 	if (!module) {
! 
  		PyErr_Print();
  		dict = NULL;
--- 279,283 ----
  
  	module = PyImport_ImportModule((char *)name);  // increases module_obj ref count by one
! 	if(!module) {
  		PyErr_Print();
  		dict = NULL;
***************
*** 265,269 ****
  	if(!module) return;
  
! 	assert(dict && module_obj && module_dict);
  
  	Py_DECREF(module);
--- 291,295 ----
  	if(!module) return;
  
! 	FLEXT_ASSERT(dict && module_obj && module_dict);
  
  	Py_DECREF(module);
***************
*** 344,358 ****
  		PyObject *pobj = PySys_GetObject("path");
  		if(pobj && PyList_Check(pobj)) {
! 			int i,n = PyList_Size(pobj);
! 			for(i = 0; i < n; ++i) {
! 				PyObject *pt = PyList_GetItem(pobj,i); // borrowed reference
! 				if(PyString_Check(pt) && !strcmp(dir,PyString_AS_STRING(pt))) break;
! 			}
! 			if(i == n) { // string is not yet existent in path
! 				PyObject *ps = PyString_FromString(dir);
! 				PyList_Append(pobj,ps);
! 			}
  		}
! 		PySys_SetObject("path",pobj);
  	}
  }
--- 370,379 ----
  		PyObject *pobj = PySys_GetObject("path");
  		if(pobj && PyList_Check(pobj)) {
!     		PyObject *ps = PyString_FromString(dir);
!             if(!PySequence_Contains(pobj,ps))
! 				PyList_Append(pobj,ps); // makes new reference
!             Py_DECREF(ps);
  		}
! 		PySys_SetObject("path",pobj); // steals reference to pobj
  	}
  }
***************
*** 379,385 ****
      FLEXT_ASSERT(PyTuple_Check(args));
  
! 	int sz = PyTuple_Size(args);
  	for(int i = 0; i < sz; ++i) {
! 		PyObject *val = PyTuple_GetItem(args,i); // borrowed reference
  		PyObject *str = PyObject_Str(val); // new reference
  		char *cstr = PyString_AS_STRING(str);
--- 400,407 ----
      FLEXT_ASSERT(PyTuple_Check(args));
  
! 	const int sz = PyTuple_GET_SIZE(args);
! 
  	for(int i = 0; i < sz; ++i) {
! 		PyObject *val = PyTuple_GET_ITEM(args,i); // borrowed reference
  		PyObject *str = PyObject_Str(val); // new reference
  		char *cstr = PyString_AS_STRING(str);

Index: pyargs.cpp
===================================================================
RCS file: /cvsroot/pure-data/externals/grill/py/source/pyargs.cpp,v
retrieving revision 1.10
retrieving revision 1.11
diff -C2 -d -r1.10 -r1.11
*** pyargs.cpp	9 Jan 2005 04:59:30 -0000	1.10
--- pyargs.cpp	11 Jan 2005 04:59:27 -0000	1.11
***************
*** 13,17 ****
  static PyObject *MakePyAtom(const t_atom &at)
  {
! 	if(flext::IsSymbol(at)) return PyString_FromString(flext::GetString(at));
  //	else if(flext::IsPointer(at)) return NULL; // not handled
      else if(flext::CanbeInt(at) && flext::CanbeFloat(at)) {
--- 13,18 ----
  static PyObject *MakePyAtom(const t_atom &at)
  {
! 	if(flext::IsSymbol(at)) 
!         return pySymbol_FromSymbol(flext::GetSymbol(at));
  //	else if(flext::IsPointer(at)) return NULL; // not handled
      else if(flext::CanbeInt(at) && flext::CanbeFloat(at)) {
***************
*** 46,55 ****
  	    int pix = 0;
  
! 	    if(inlet >= 0) {
! 		    PyObject *pValue = PyInt_FromLong(inlet); 
!     		
! 		    // reference stolen:
! 		    PyTuple_SetItem(pArgs, pix++, pValue); 
! 	    }
  
  	    int ix;
--- 47,52 ----
  	    int pix = 0;
  
! 	    if(inlet >= 0)
! 		    PyTuple_SetItem(pArgs, pix++, PyInt_FromLong(inlet)); 
  
  	    int ix;
***************
*** 58,67 ****
  	    else tmp = PyTuple_New(argc+(any?1:0)),ix = 0;
  
! 	    if(any) {
! 		    PyObject *pValue = PyString_FromString(GetString(s));
! 
! 		    // reference stolen here: 
! 		    PyTuple_SetItem(tmp, ix++, pValue); 
! 	    }
  
  	    for(int i = 0; i < argc; ++i) {
--- 55,60 ----
  	    else tmp = PyTuple_New(argc+(any?1:0)),ix = 0;
  
! 	    if(any)
! 		    PyTuple_SET_ITEM(tmp, ix++, pySymbol_FromSymbol(s)); 
  
  	    for(int i = 0; i < argc; ++i) {
***************
*** 73,81 ****
  
  		    /* pValue reference stolen here: */
! 		    PyTuple_SetItem(tmp, ix++, pValue); 
  	    }
  
  	    if(tmp != pArgs) {
! 		    PyTuple_SetItem(pArgs, pix++, tmp); 
      #if PY_VERSION_HEX >= 0x02020000
  		    _PyTuple_Resize(&pArgs,pix);
--- 66,74 ----
  
  		    /* pValue reference stolen here: */
! 		    PyTuple_SET_ITEM(tmp, ix++, pValue); 
  	    }
  
  	    if(tmp != pArgs) {
! 		    PyTuple_SET_ITEM(pArgs, pix++, tmp); 
      #if PY_VERSION_HEX >= 0x02020000
  		    _PyTuple_Resize(&pArgs,pix);
***************
*** 127,131 ****
  		else if(PyLong_Check(arg)) SetInt((*ret)[ix],PyLong_AsLong(arg));
  		else if(PyFloat_Check(arg)) SetFloat((*ret)[ix],(float)PyFloat_AsDouble(arg));
! 		else if(PyString_Check(arg)) SetString((*ret)[ix],PyString_AsString(arg));
  		else if(ix == 0 && self && PyInstance_Check(arg)) {
  			// assumed to be self ... that should be checked _somehow_ !!!
--- 120,125 ----
  		else if(PyLong_Check(arg)) SetInt((*ret)[ix],PyLong_AsLong(arg));
  		else if(PyFloat_Check(arg)) SetFloat((*ret)[ix],(float)PyFloat_AsDouble(arg));
! 		else if(pySymbol_Check(arg)) SetSymbol((*ret)[ix],pySymbol_AS_SYMBOL(arg));
! 		else if(PyString_Check(arg)) SetString((*ret)[ix],PyString_AS_STRING(arg));
  		else if(ix == 0 && self && PyInstance_Check(arg)) {
  			// assumed to be self ... that should be checked _somehow_ !!!
***************
*** 137,141 ****
  			PyObject *stp = tp?PyObject_Str(tp):NULL;
  			char *tmp = "";
! 			if(stp) tmp = PyString_AsString(stp);
  			post("py/pyext: Could not convert argument %s",tmp);
  			Py_XDECREF(stp);
--- 131,135 ----
  			PyObject *stp = tp?PyObject_Str(tp):NULL;
  			char *tmp = "";
! 			if(stp) tmp = PyString_AS_STRING(stp);
  			post("py/pyext: Could not convert argument %s",tmp);
  			Py_XDECREF(stp);

Index: modmeth.cpp
===================================================================
RCS file: /cvsroot/pure-data/externals/grill/py/source/modmeth.cpp,v
retrieving revision 1.13
retrieving revision 1.14
diff -C2 -d -r1.13 -r1.14
*** modmeth.cpp	9 Jan 2005 04:59:30 -0000	1.13
--- modmeth.cpp	11 Jan 2005 04:59:27 -0000	1.14
***************
*** 108,115 ****
      FLEXT_ASSERT(PyTuple_Check(args));
  
! 	PyObject *name = PyTuple_GetItem(args,0); // borrowed reference
!     if(name && PyString_Check(name)) {
! 		const t_symbol *recv = MakeSymbol(PyString_AsString(name));
! 		int sz = PySequence_Size(args);
  		PyObject *val;
  
--- 108,118 ----
      FLEXT_ASSERT(PyTuple_Check(args));
  
! 	const int sz = PyTuple_GET_SIZE(args);
! 
!     const t_symbol *recv;
!     if(
!         sz >= 1 && 
!         (recv = pyObject_AsSymbol(PyTuple_GET_ITEM(args,0))) != NULL
!     ) {
  		PyObject *val;
  
***************
*** 117,121 ****
              sz == 2 && 
              PySequence_Check(
!                 val = PyTuple_GetItem(args,1) // borrowed ref
              );
  
--- 120,124 ----
              sz == 2 && 
              PySequence_Check(
!                 val = PyTuple_GET_ITEM(args,1) // borrowed ref
              );
  
***************
*** 169,178 ****
      FLEXT_ASSERT(PyTuple_Check(args));
  
      PyObject *ret;
- 	PyObject *name = PyTuple_GetItem(args,0); // borrowed reference
- 
-     if(name && PyString_Check(name)) {
- 		const t_symbol *sym = MakeSymbol(PyString_AsString(name));
  
          float f;
          if(value_getfloat(const_cast<t_symbol *>(sym),&f)) {
--- 172,183 ----
      FLEXT_ASSERT(PyTuple_Check(args));
  
+ 	const int sz = PyTuple_GET_SIZE(args);
+     const t_symbol *sym;
      PyObject *ret;
  
+     if(
+         sz == 1 && 
+         (sym = pyObject_AsSymbol(PyTuple_GET_ITEM(args,0))) != NULL
+     ) {
          float f;
          if(value_getfloat(const_cast<t_symbol *>(sym),&f)) {
***************
*** 194,201 ****
      FLEXT_ASSERT(PyTuple_Check(args));
  
! 	PyObject *name = PyTuple_GetItem(args,0); // borrowed reference
! 	PyObject *val = PyTuple_GetItem(args,1); // borrowed reference
!     if(name && val && PyString_Check(name) && PyNumber_Check(val)) {
! 		const t_symbol *sym = MakeSymbol(PyString_AsString(name));
          float f = (float)PyFloat_AsDouble(val);
  
--- 199,211 ----
      FLEXT_ASSERT(PyTuple_Check(args));
  
! 	const int sz = PyTuple_GET_SIZE(args);
! 	const t_symbol *sym;
! 	PyObject *val; // borrowed reference
! 
!     if(
!         sz == 2 &&
!         (sym = pyObject_AsSymbol(PyTuple_GET_ITEM(args,0))) != NULL &&
!         PyNumber_Check(val = PyTuple_GET_ITEM(args,1))
!     ) {
          float f = (float)PyFloat_AsDouble(val);
  

Index: bound.cpp
===================================================================
RCS file: /cvsroot/pure-data/externals/grill/py/source/bound.cpp,v
retrieving revision 1.13
retrieving revision 1.14
diff -C2 -d -r1.13 -r1.14
*** bound.cpp	9 Jan 2005 04:59:30 -0000	1.13
--- bound.cpp	11 Jan 2005 04:59:27 -0000	1.14
***************
*** 14,18 ****
  #include <set>
  
! typedef std::set<PyObject *> FuncSet;
  
  struct bounddata 
--- 14,56 ----
  #include <set>
  
! class MethodCompare:
!     public std::less<PyObject *>
! {
! public:
!     bool operator()(PyObject *a,PyObject *b) const
!     {
!         if(PyMethod_Check(a))
!             if(PyMethod_Check(b)) {
!                 // both are methods
!                 PyObject *sa = PyMethod_GET_SELF(a);
!                 PyObject *sb = PyMethod_GET_SELF(b);
!                 if(sa)
!                     if(sb) {
!                         // both have self
!                         if(sa == sb)
!                             return PyMethod_GET_FUNCTION(a) < PyMethod_GET_FUNCTION(b);
!                         else
!                             return sa < sb;
!                     }
!                     else 
!                         return false;
!                 else
!                     if(sb)
!                         return true;
!                     else 
!                         return PyMethod_GET_FUNCTION(a) < PyMethod_GET_FUNCTION(b);
!             }
!             else
!                 return false;
!         else
!             if(PyMethod_Check(b))
!                 return true;
!             else
!                 // both are functions
!                 return a < b;
!     }
! };
! 
! typedef std::set<PyObject *,MethodCompare> FuncSet;
  
  struct bounddata 
***************
*** 34,41 ****
      for(FuncSet::iterator it = obj->funcs.begin(); it != obj->funcs.end(); ++it) {
  	    PyObject *ret = PyObject_CallObject(*it,args);
! 	    if(!ret) {
  		    PyErr_Print();
! 	    }
!     	Py_XDECREF(ret);
      }
  
--- 72,79 ----
      for(FuncSet::iterator it = obj->funcs.begin(); it != obj->funcs.end(); ++it) {
  	    PyObject *ret = PyObject_CallObject(*it,args);
! 	    if(!ret)
  		    PyErr_Print();
!         else
!     	    Py_DECREF(ret);
      }
  
***************
*** 48,54 ****
  PyObject *pyext::pyext_bind(PyObject *,PyObject *args)
  {
!     PyObject *self,*meth;
! 	char *name;
!     if(!PyArg_ParseTuple(args, "OsO:pyext_bind", &self,&name,&meth))
  		post("py/pyext - Wrong arguments!");
  	else if(!PyInstance_Check(self) || !(PyMethod_Check(meth) || PyFunction_Check(meth))) {
--- 86,91 ----
  PyObject *pyext::pyext_bind(PyObject *,PyObject *args)
  {
!     PyObject *self,*meth,*name;
!     if(!PyArg_ParseTuple(args, "OOO:pyext_bind", &self,&name,&meth)) // borrowed references
  		post("py/pyext - Wrong arguments!");
  	else if(!PyInstance_Check(self) || !(PyMethod_Check(meth) || PyFunction_Check(meth))) {
***************
*** 56,86 ****
      }
  	else {
! 		const t_symbol *recv = MakeSymbol(name);
! /*
! 		if(GetBound(recv))
! 			post("py/pyext - Symbol \"%s\" is already hooked",GetString(recv));
! */		
! 		// make a proxy object
  
! 		if(PyMethod_Check(meth)) {
! 			PyObject *no = PyObject_GetAttrString(meth,"__name__");
! 			meth  = PyObject_GetAttr(self,no); 
! 			Py_DECREF(no);
! 		}
  
          void *data = NULL;
!         if(GetThis(self)->GetBoundMethod(recv,boundmeth,data)) {
              // already bound to that symbol and function
              bounddata *bdt = (bounddata *)data;
              FLEXT_ASSERT(bdt != NULL && bdt->self == self);
!             bdt->funcs.insert(meth);
          }
          else {
              bounddata *data = new bounddata;
              data->self = self;
              data->funcs.insert(meth);
-             GetThis(self)->BindMethod(recv,boundmeth,data);
  
!     		Py_INCREF(self); // self is borrowed reference
          }
  	}
--- 93,122 ----
      }
  	else {
!         py *th = GetThis(self);
!         FLEXT_ASSERT(th);
  
! 		const t_symbol *recv = pyObject_AsSymbol(name);
  
          void *data = NULL;
!         if(recv && th->GetBoundMethod(recv,boundmeth,data)) {
              // already bound to that symbol and function
              bounddata *bdt = (bounddata *)data;
              FLEXT_ASSERT(bdt != NULL && bdt->self == self);
! 
!             FuncSet::iterator it = bdt->funcs.find(meth);
!             if(it == bdt->funcs.end()) {
!                 bdt->funcs.insert(meth);
!                 Py_INCREF(meth);
!             }
          }
          else {
+     		Py_INCREF(self); // self is borrowed reference
+             Py_INCREF(meth);
+ 
              bounddata *data = new bounddata;
              data->self = self;
              data->funcs.insert(meth);
  
!             th->BindMethod(recv,boundmeth,data);
          }
  	}
***************
*** 92,98 ****
  PyObject *pyext::pyext_unbind(PyObject *,PyObject *args)
  {
!     PyObject *self,*meth;
! 	char *name;
!     if(!PyArg_ParseTuple(args, "OsO:pyext_bind", &self,&name,&meth))
  		post("py/pyext - Wrong arguments!");
  	else if(!PyInstance_Check(self) || !(PyMethod_Check(meth) || PyFunction_Check(meth))) {
--- 128,133 ----
  PyObject *pyext::pyext_unbind(PyObject *,PyObject *args)
  {
!     PyObject *self,*meth,*name;
!     if(!PyArg_ParseTuple(args, "OOO:pyext_bind", &self,&name,&meth))  // borrowed references
  		post("py/pyext - Wrong arguments!");
  	else if(!PyInstance_Check(self) || !(PyMethod_Check(meth) || PyFunction_Check(meth))) {
***************
*** 100,123 ****
      }
  	else {
! 		const t_symbol *recv = MakeSymbol(name);
! 		if(PyMethod_Check(meth)) {
! 			PyObject *no = PyObject_GetAttrString(meth,"__name__");
! 			meth  = PyObject_GetAttr(self,no); // meth is given a new reference!
! 			Py_DECREF(no);
! 		}
  
          void *data = NULL;
!         if(GetThis(self)->UnbindMethod(recv,boundmeth,&data)) {
              bounddata *bdt = (bounddata *)data;
              FLEXT_ASSERT(bdt != NULL);
  
-     	    if(PyMethod_Check(meth)) Py_DECREF(meth);
- 
              // erase from map
!             bdt->funcs.erase(meth);
  
              if(bdt->funcs.empty()) {
      		    Py_DECREF(bdt->self);
                  delete bdt; 
              }
          }
--- 135,164 ----
      }
  	else {
!         py *th = GetThis(self);
!         FLEXT_ASSERT(th);
! 
! 		const t_symbol *recv = pyObject_AsSymbol(name);
  
          void *data = NULL;
!         if(recv && th->GetBoundMethod(recv,boundmeth,data)) {
              bounddata *bdt = (bounddata *)data;
              FLEXT_ASSERT(bdt != NULL);
  
              // erase from map
!             // ATTENTION: meth is different from the element found in the map
!             // it just points to the same instance method
!             FuncSet::iterator it = bdt->funcs.find(meth);
!             if(it != bdt->funcs.end()) {
!     	        Py_DECREF(*it);
!                 bdt->funcs.erase(it);               
!             }
!             else
!                 post("py/pyext - Function to unbind couldn't be found");
  
              if(bdt->funcs.empty()) {
      		    Py_DECREF(bdt->self);
                  delete bdt; 
+ 
+                 th->UnbindMethod(recv,boundmeth,NULL);
              }
          }
***************
*** 143,153 ****
          bounddata *bdt = (bounddata *)data; 
          if(bdt) {
!             for(FuncSet::iterator it = bdt->funcs.begin(); it != bdt->funcs.end(); ++it) {
!                 PyObject *func = *it;
! 		        if(PyMethod_Check(func)) Py_DECREF(func);
!             }
  
  		    Py_DECREF(bdt->self);
!             if(data) delete bdt; 
          }
      }
--- 184,192 ----
          bounddata *bdt = (bounddata *)data; 
          if(bdt) {
!             for(FuncSet::iterator it = bdt->funcs.begin(); it != bdt->funcs.end(); ++it) 
!                 Py_DECREF(*it);
  
  		    Py_DECREF(bdt->self);
!             delete bdt; 
          }
      }

Index: pyext.cpp
===================================================================
RCS file: /cvsroot/pure-data/externals/grill/py/source/pyext.cpp,v
retrieving revision 1.24
retrieving revision 1.25
diff -C2 -d -r1.24 -r1.25
*** pyext.cpp	10 Jan 2005 05:00:56 -0000	1.24
--- pyext.cpp	11 Jan 2005 04:59:27 -0000	1.25
***************
*** 21,38 ****
      sym_get = flext::MakeSymbol("get");
      
-     FLEXT_CADDMETHOD_(c,0,"reload.",m_reload);
  	FLEXT_CADDMETHOD_(c,0,"reload",m_reload_);
! 	FLEXT_CADDMETHOD_(c,0,"dir",m_dir);
! 	FLEXT_CADDMETHOD_(c,0,"dir+",m_dir_);
! 	FLEXT_CADDMETHOD_(c,0,"doc",m_doc);
  	FLEXT_CADDMETHOD_(c,0,"doc+",m_doc_);
! 
!   	FLEXT_CADDATTR_VAR(c,"args",args,ms_args);
  	FLEXT_CADDATTR_GET(c,"dir+",mg_dir_);
  
! #ifdef FLEXT_THREADS
! 	FLEXT_CADDATTR_VAR1(c,"detach",detach);
! 	FLEXT_CADDMETHOD_(c,0,"stop",m_stop);
! #endif
  
  	FLEXT_CADDMETHOD_(c,0,"get",m_get);
--- 21,31 ----
      sym_get = flext::MakeSymbol("get");
      
  	FLEXT_CADDMETHOD_(c,0,"reload",m_reload_);
!     FLEXT_CADDMETHOD_(c,0,"reload.",m_reload);
  	FLEXT_CADDMETHOD_(c,0,"doc+",m_doc_);
! 	FLEXT_CADDMETHOD_(c,0,"dir+",m_dir_);
  	FLEXT_CADDATTR_GET(c,"dir+",mg_dir_);
  
!     FLEXT_CADDATTR_VAR(c,"args",args,ms_args);
  
  	FLEXT_CADDMETHOD_(c,0,"get",m_get);
***************
*** 173,228 ****
  		MakeInstance();
  
!         if(pyobj) {
!             if(inlets >= 0) {
!                 // set number of inlets
! 			    PyObject *res = PyInt_FromLong(inlets);
!                 int ret = PyObject_SetAttrString(pyobj,"_inlets",res);
!                 FLEXT_ASSERT(!ret);
!             }
!             if(outlets >= 0) {
!                 // set number of outlets
! 			    PyObject *res = PyInt_FromLong(outlets);
! 			    int ret = PyObject_SetAttrString(pyobj,"_outlets",res);
!                 FLEXT_ASSERT(!ret);
!             }
! 
!             DoInit(); // call __init__ constructor
!             // __init__ can override the number of inlets and outlets
! 
!             if(inlets < 0) {
! 		        // get number of inlets
! 		        inlets = 1;
! 			    PyObject *res = PyObject_GetAttrString(pyobj,"_inlets"); // get ref
! 			    if(res) {
! 				    if(PyCallable_Check(res)) {
! 					    PyObject *fres = PyEval_CallObject(res,NULL);
! 					    Py_DECREF(res);
! 					    res = fres;
! 				    }
! 				    if(PyInt_Check(res)) 
! 					    inlets = PyInt_AsLong(res);
! 				    Py_DECREF(res);
! 			    }
! 			    else 
! 				    PyErr_Clear();
!             }
!             if(outlets < 0) {
!                 // get number of outlets
!                 outlets = 1;
! 			    PyObject *res = PyObject_GetAttrString(pyobj,"_outlets"); // get ref
! 			    if(res) {
! 				    if(PyCallable_Check(res)) {
! 					    PyObject *fres = PyEval_CallObject(res,NULL);
! 					    Py_DECREF(res);
! 					    res = fres;
! 				    }
! 				    if(PyInt_Check(res))
! 					    outlets = PyInt_AsLong(res);
! 				    Py_DECREF(res);
! 			    }
! 			    else
! 				    PyErr_Clear();
!             }
!         }
  	}
      else 
--- 166,171 ----
  		MakeInstance();
  
!         if(pyobj) 
!             InitInOut(inlets,outlets);
  	}
      else 
***************
*** 246,255 ****
  	PyThreadState *state = PyLock();
  
! 	ClearBinding();
!     
!     if(pyobj) {
!         if(pyobj->ob_refcnt > 1) post("%s - Python object is still referenced",thisName());
!     	Py_DECREF(pyobj);  // opposite of SetClssMeth
!     }
  
      Unregister("_pyext");
--- 189,193 ----
  	PyThreadState *state = PyLock();
  
!     DoExit();
  
      Unregister("_pyext");
***************
*** 270,275 ****
  	PyObject *init = PyObject_GetAttrString(pyobj,"__init__"); // get ref
      if(init) {
!         if(PyCallable_Check(init)) {
! 			PyObject *res = PyEval_CallObject(init,pargs);
  			if(!res)
  				PyErr_Print();
--- 208,213 ----
  	PyObject *init = PyObject_GetAttrString(pyobj,"__init__"); // get ref
      if(init) {
!         if(PyMethod_Check(init)) {
! 			PyObject *res = PyObject_CallObject(init,pargs);
  			if(!res)
  				PyErr_Print();
***************
*** 284,287 ****
--- 222,305 ----
  }
  
+ void pyext::DoExit()
+ {
+ 	ClearBinding();
+ 
+     if(pyobj) {
+         if(pyobj->ob_refcnt > 1) {
+             post("%s - Python object is still referenced",thisName());
+ 
+             // Force-quit object:
+             // call __del__ manually
+             // this is dangerous, because it could get called a second time
+             // if object really has no more references then
+ 	        PyObject *meth = PyObject_GetAttrString(pyobj,"__del__"); // get ref
+             if(meth) {
+                 if(PyMethod_Check(meth)) {
+ 			        PyObject *res = PyObject_CallObject(meth,NULL);
+ 			        if(!res)
+ 				        PyErr_Print();
+ 			        else
+ 				        Py_DECREF(res);
+                 }
+                 Py_DECREF(meth);
+ 	        }
+         }
+     	Py_DECREF(pyobj);  // opposite of SetClssMeth
+     }
+ }
+ 
+ void pyext::InitInOut(int &inl,int &outl)
+ {
+     if(inl >= 0) {
+         // set number of inlets
+         int ret = PyObject_SetAttrString(pyobj,"_inlets",PyInt_FromLong(inl));
+         FLEXT_ASSERT(!ret);
+     }
+     if(outl >= 0) {
+         // set number of outlets
+ 		int ret = PyObject_SetAttrString(pyobj,"_outlets",PyInt_FromLong(outl));
+         FLEXT_ASSERT(!ret);
+     }
+ 
+     DoInit(); // call __init__ constructor
+     // __init__ can override the number of inlets and outlets
+ 
+     if(inl < 0) {
+ 		// get number of inlets
+ 		inl = 1;
+ 		PyObject *res = PyObject_GetAttrString(pyobj,"_inlets"); // get ref
+ 		if(res) {
+ 			if(PyCallable_Check(res)) {
+ 				PyObject *fres = PyEval_CallObject(res,NULL);
+ 				Py_DECREF(res);
+ 				res = fres;
+ 			}
+ 			if(PyInt_Check(res)) 
+ 				inl = PyInt_AS_LONG(res);
+ 			Py_DECREF(res);
+ 		}
+ 		else 
+ 			PyErr_Clear();
+     }
+     if(outl < 0) {
+         // get number of outlets
+         outl = 1;
+ 		PyObject *res = PyObject_GetAttrString(pyobj,"_outlets"); // get ref
+ 		if(res) {
+ 			if(PyCallable_Check(res)) {
+ 				PyObject *fres = PyEval_CallObject(res,NULL);
+ 				Py_DECREF(res);
+ 				res = fres;
+ 			}
+ 			if(PyInt_Check(res))
+ 				outl = PyInt_AS_LONG(res);
+ 			Py_DECREF(res);
+ 		}
+ 		else
+ 			PyErr_Clear();
+     }
+ }
+ 
  bool pyext::MakeInstance()
  {
***************
*** 312,317 ****
  void pyext::Reload()
  {
! 	ClearBinding();
! 	Py_XDECREF(pyobj);
  
  	// by here, the Python class destructor should have been called!
--- 330,334 ----
  void pyext::Reload()
  {
! 	DoExit();
  
  	// by here, the Python class destructor should have been called!
***************
*** 321,324 ****
--- 338,347 ----
  	
  	MakeInstance();
+ 
+     int inl = -1,outl = -1;
+     InitInOut(inl,outl);
+ 
+     if(inl != inlets || outl != outlets)
+         post("%s - Inlet and outlet count can't be changed by reload",thisName());
  }
  

Index: pyext.h
===================================================================
RCS file: /cvsroot/pure-data/externals/grill/py/source/pyext.h,v
retrieving revision 1.18
retrieving revision 1.19
diff -C2 -d -r1.18 -r1.19
*** pyext.h	9 Jan 2005 04:59:30 -0000	1.18
--- pyext.h	11 Jan 2005 04:59:27 -0000	1.19
***************
*** 71,74 ****
--- 71,76 ----
  	bool MakeInstance();
  	bool DoInit();
+ 	void DoExit();
+     void InitInOut(int &inlets,int &outlets);
  
  	AtomList args;

--- NEW FILE: pysymbol.cpp ---
/* 

py/pyext - python script object for PD and Max/MSP

Copyright (c)2002-2005 Thomas Grill (gr at grrrr.org)
For information on usage and redistribution, and for a DISCLAIMER OF ALL
WARRANTIES, see the file, "license.txt," in this distribution.  

*/

#include "pysymbol.h"

inline pySymbol *symbol_newsym(const t_symbol *sym)
{
    pySymbol *self = (pySymbol *)pySymbol_Type.tp_alloc(&pySymbol_Type, 0);
    if(self) self->sym = sym;
    return self;
}

static PyObject *symbol_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
    return (PyObject *)symbol_newsym(flext::sym__);
}

static int symbol_init(PyObject *self, PyObject *args, PyObject *kwds)
{
    FLEXT_ASSERT(pySymbol_Check(self));

    PyObject *arg = PySequence_GetItem(args,0); // new reference
    if(!arg) return -1;

    int ret = 0;

    if(pySymbol_Check(arg))
        ((pySymbol *)self)->sym = pySymbol_AS_SYMBOL(arg);
    else if(PyString_Check(arg))
        ((pySymbol *)self)->sym = flext::MakeSymbol(PyString_AS_STRING(arg));
    else
        ret = -1;
    Py_DECREF(arg);

    return ret;
}

static PyObject *symbol_str(PyObject *self)
{
    FLEXT_ASSERT(pySymbol_Check(self));
    return (PyObject *)PyString_FromString(pySymbol_AS_STRING(self));
}

static PyObject *symbol_repr(PyObject *self)
{
    FLEXT_ASSERT(pySymbol_Check(self));
    return (PyObject *)PyString_FromFormat("<Symbol %s>",pySymbol_AS_STRING(self));
}

static PyObject *symbol_richcompare(PyObject *a,PyObject *b,int cmp)
{
    if(pySymbol_Check(a) && pySymbol_Check(b)) {
        const t_symbol *asym = pySymbol_AS_SYMBOL(a);
        const t_symbol *bsym = pySymbol_AS_SYMBOL(a);
        bool ret;
        switch(cmp) {
            case Py_LT: ret = asym < bsym;
            case Py_LE: ret = asym <= bsym;
            case Py_EQ: ret = asym == bsym;
            case Py_NE: ret = asym != bsym;
            case Py_GT: ret = asym > bsym;
            case Py_GE: ret = asym >= bsym;
        }
        return PyBool_FromLong(ret);
    }
	Py_INCREF(Py_NotImplemented);
	return Py_NotImplemented;
}

static long symbol_hash(PyObject *self)
{
    FLEXT_ASSERT(pySymbol_Check(self));
    return (long)pySymbol_AS_SYMBOL(self);
}

PyTypeObject pySymbol_Type = {
    PyObject_HEAD_INIT(NULL)
    0,                         /*ob_size*/
    "Symbol",              /*tp_name*/
    sizeof(pySymbol),          /*tp_basicsize*/
    0,                         /*tp_itemsize*/
    0,                         /*tp_dealloc*/
    0,                         /*tp_print*/
    0,                         /*tp_getattr*/
    0,                         /*tp_setattr*/
    0,            /*tp_compare*/
    symbol_repr,               /*tp_repr*/
    0,                         /*tp_as_number*/
    0,                         /*tp_as_sequence*/
    0,                         /*tp_as_mapping*/
    symbol_hash,               /*tp_hash */
    0,                         /*tp_call*/
    symbol_str,                /*tp_str*/
    0,                         /*tp_getattro*/
    0,                         /*tp_setattro*/
    0,                         /*tp_as_buffer*/
    Py_TPFLAGS_DEFAULT /*| Py_TPFLAGS_BASETYPE*/,   /*tp_flags*/
    "Symbol objects",           /* tp_doc */
    0,		               /* tp_traverse */
    0,		               /* tp_clear */
    symbol_richcompare,	       /* tp_richcompare */
    0,		               /* tp_weaklistoffset */
    0,		               /* tp_iter */
    0,		               /* tp_iternext */
    0,                          /* tp_methods */
    0,                          /* tp_members */
    0,                         /* tp_getset */
    0,                         /* tp_base */
    0,                         /* tp_dict */
    0,                         /* tp_descr_get */
    0,                         /* tp_descr_set */
    0,                         /* tp_dictoffset */
    symbol_init,            /* tp_init */
    0,                         /* tp_alloc */
    symbol_new,                 /* tp_new */
};

pySymbol *pySymbol__;
pySymbol *pySymbol_bang;
pySymbol *pySymbol_list;
pySymbol *pySymbol_symbol;
pySymbol *pySymbol_float;
pySymbol *pySymbol_int;


void initsymbol()
{
    if(PyType_Ready(&pySymbol_Type) < 0)
        FLEXT_ASSERT(false);
    else
        Py_INCREF(&pySymbol_Type);

    // initialize predefined objects
    pySymbol__ = symbol_newsym(flext::sym__);
    pySymbol_bang = symbol_newsym(flext::sym_bang);
    pySymbol_list = symbol_newsym(flext::sym_list);
    pySymbol_symbol = symbol_newsym(flext::sym_symbol);
    pySymbol_float = symbol_newsym(flext::sym_float);
    pySymbol_int = symbol_newsym(flext::sym_int);
}


PyObject *pySymbol_FromSymbol(const t_symbol *sym)
{
    pySymbol *op;
    if(sym == flext::sym__)
        Py_INCREF(op = pySymbol__);
    else if(sym == flext::sym_bang)
        Py_INCREF(op = pySymbol_bang);
    else if(sym == flext::sym_list)
        Py_INCREF(op = pySymbol_list);
    else if(sym == flext::sym_symbol)
        Py_INCREF(op = pySymbol_symbol);
    else if(sym == flext::sym_float)
        Py_INCREF(op = pySymbol_float);
    else if(sym == flext::sym_int)
        Py_INCREF(op = pySymbol_int);
    else
        op = symbol_newsym(sym);
    return (PyObject *)op;
}

Index: main.h
===================================================================
RCS file: /cvsroot/pure-data/externals/grill/py/source/main.h,v
retrieving revision 1.27
retrieving revision 1.28
diff -C2 -d -r1.27 -r1.28
*** main.h	10 Jan 2005 05:00:56 -0000	1.27
--- main.h	11 Jan 2005 04:59:27 -0000	1.28
***************
*** 12,23 ****
  #define __MAIN_H
  
! #define FLEXT_ATTRIBUTES 1
! 
! #include <flext.h>
! #if FLEXT_OS == FLEXT_OS_MAC
! #include <Python/Python.h>
! #else
! #include <Python.h>
! #endif
  
  #if FLEXT_OS == FLEXT_LINUX || FLEXT_OS == FLEXT_IRIX
--- 12,17 ----
  #define __MAIN_H
  
! #include "pyprefix.h"
! #include "pysymbol.h"
  
  #if FLEXT_OS == FLEXT_LINUX || FLEXT_OS == FLEXT_IRIX
***************
*** 25,32 ****
  #endif
  
- #if !defined(FLEXT_VERSION) || (FLEXT_VERSION < 500)
- #error You need at least flext version 0.5.0
- #endif
- 
  #define PY__VERSION "0.2.0pre"
  
--- 19,22 ----
***************
*** 62,66 ****
  	public flext_base
  {
! 	FLEXT_HEADER(py,flext_base)
  
  public:
--- 52,56 ----
  	public flext_base
  {
! 	FLEXT_HEADER_S(py,flext_base,Setup)
  
  public:
***************
*** 191,196 ****
  
  protected:
- 	// callbacks
  
  	FLEXT_ATTRVAR_I(detach)
  	FLEXT_ATTRVAR_B(respond)
--- 181,190 ----
  
  protected:
  
+     virtual void m_click();
+ 
+ 	static void Setup(t_classid c);
+ 
+ 	// callbacks
  	FLEXT_ATTRVAR_I(detach)
  	FLEXT_ATTRVAR_B(respond)

Index: py.cpp
===================================================================
RCS file: /cvsroot/pure-data/externals/grill/py/source/py.cpp,v
retrieving revision 1.17
retrieving revision 1.18
diff -C2 -d -r1.17 -r1.18
*** py.cpp	10 Jan 2005 05:00:56 -0000	1.17
--- py.cpp	11 Jan 2005 04:59:27 -0000	1.18
***************
*** 82,98 ****
  void pyobj::Setup(t_classid c)
  {
- 	FLEXT_CADDBANG(c,0,m_bang);
  	FLEXT_CADDMETHOD_(c,0,"reload",m_reload_);
! 	FLEXT_CADDMETHOD_(c,0,"reload.",m_reload);
! 	FLEXT_CADDMETHOD_(c,0,"set",m_set);
! 	FLEXT_CADDMETHOD_(c,0,"doc",m_doc);
  	FLEXT_CADDMETHOD_(c,0,"doc+",m_doc_);
- #ifdef FLEXT_THREADS
- 	FLEXT_CADDATTR_VAR1(c,"detach",detach);
- 	FLEXT_CADDMETHOD_(c,0,"stop",m_stop);
- #endif
- 	FLEXT_CADDMETHOD_(c,0,"dir",m_dir);
  	FLEXT_CADDMETHOD_(c,0,"dir+",m_dir_);
  
  	FLEXT_CADDMETHOD_(c,1,"float",m_py_float);
  	FLEXT_CADDMETHOD_(c,1,"int",m_py_int);
--- 82,93 ----
  void pyobj::Setup(t_classid c)
  {
  	FLEXT_CADDMETHOD_(c,0,"reload",m_reload_);
!     FLEXT_CADDMETHOD_(c,0,"reload.",m_reload);
  	FLEXT_CADDMETHOD_(c,0,"doc+",m_doc_);
  	FLEXT_CADDMETHOD_(c,0,"dir+",m_dir_);
  
+ 	FLEXT_CADDBANG(c,0,m_bang);
+ 	FLEXT_CADDMETHOD_(c,0,"set",m_set);
+ 
  	FLEXT_CADDMETHOD_(c,1,"float",m_py_float);
  	FLEXT_CADDMETHOD_(c,1,"int",m_py_int);

--- NEW FILE: pysymbol.h ---
/* 

py/pyext - python script object for PD and Max/MSP

Copyright (c)2002-2005 Thomas Grill (gr at grrrr.org)
For information on usage and redistribution, and for a DISCLAIMER OF ALL
WARRANTIES, see the file, "license.txt," in this distribution.  

*/

#include "pyprefix.h"

typedef struct {
    PyObject_HEAD
    /* Type-specific fields go here. */
    const t_symbol *sym;
} pySymbol;

extern PyTypeObject pySymbol_Type;

extern pySymbol *pySymbol__;
extern pySymbol *pySymbol_bang;
extern pySymbol *pySymbol_list;
extern pySymbol *pySymbol_symbol;
extern pySymbol *pySymbol_float;
extern pySymbol *pySymbol_int;


#define pySymbol_Check(op) PyObject_TypeCheck(op, &pySymbol_Type)
#define pySymbol_CheckExact(op) ((op)->ob_type == &PySymbol_Type)


PyObject *pySymbol_FromSymbol(const t_symbol *sym);

inline const t_symbol *pySymbol_AS_SYMBOL(PyObject *op) 
{
    return ((pySymbol *)op)->sym;
}

inline const t_symbol *pySymbol_AsSymbol(PyObject *op) 
{
    return pySymbol_Check(op)?pySymbol_AS_SYMBOL(op):NULL;
}

inline const char *pySymbol_AS_STRING(PyObject *op) 
{
    return flext::GetString(pySymbol_AS_SYMBOL(op));
}

inline const t_symbol *pyObject_AsSymbol(PyObject *op)
{
    if(PyString_Check(op))
        return flext::MakeSymbol(PyString_AS_STRING(op));
    else
        return pySymbol_AsSymbol(op);
}






More information about the Pd-cvs mailing list