aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Grill <xovo@users.sourceforge.net>2004-08-31 04:07:35 +0000
committerThomas Grill <xovo@users.sourceforge.net>2004-08-31 04:07:35 +0000
commit1a23e8233e6c1cbc30b9ddee4df153c21f4b282b (patch)
tree1c79382a41ef857e5beeed6f27ca1c85c81ddac1
parentd28900c480f4ea568acdff80372f12383d463e8c (diff)
""
svn path=/trunk/; revision=1982
-rw-r--r--externals/grill/flext/changes.txt1
-rw-r--r--externals/grill/flext/source/flout.cpp335
-rw-r--r--externals/grill/py/readme.txt4
-rw-r--r--externals/grill/py/source/bound.cpp2
-rw-r--r--externals/grill/py/source/clmeth.cpp141
-rw-r--r--externals/grill/py/source/main.cpp60
-rw-r--r--externals/grill/py/source/modmeth.cpp66
-rw-r--r--externals/grill/py/source/pyargs.cpp12
-rw-r--r--externals/grill/py/source/pyext.cpp15
-rw-r--r--externals/grill/py/source/register.cpp4
-rw-r--r--externals/grill/vasp/changes.txt2
-rw-r--r--externals/grill/vasp/source/main.cpp2
-rw-r--r--externals/grill/vasp/source/obj_imm.cpp2
-rw-r--r--externals/grill/vasp/source/obj_peaks.cpp2
-rw-r--r--externals/grill/vasp/source/obj_q.cpp4
-rw-r--r--externals/grill/vasp/source/ops_search.cpp9
16 files changed, 361 insertions, 300 deletions
diff --git a/externals/grill/flext/changes.txt b/externals/grill/flext/changes.txt
index 8782d4ba..1a910d4b 100644
--- a/externals/grill/flext/changes.txt
+++ b/externals/grill/flext/changes.txt
@@ -22,6 +22,7 @@ Version history:
- fixes for Max 4.5 headers
- removed Mach-O/CFM glue stuff again and added makefiles for Max/MachO
- in flext::StopThread don't wait for thread to have stopped!
+- support PD tooltips (only in devel branch at the moment)
0.4.6:
- added a text edit window for list attributes
diff --git a/externals/grill/flext/source/flout.cpp b/externals/grill/flext/source/flout.cpp
index 245de189..0c7beedc 100644
--- a/externals/grill/flext/source/flout.cpp
+++ b/externals/grill/flext/source/flout.cpp
@@ -67,203 +67,216 @@ bool flext_base::InitInlets()
incnt = insigs = 0;
// digest inlist
- {
- xlet *xi;
- incnt = 0;
- for(xi = inlist; xi; xi = xi->nxt) ++incnt;
- xlet::type *list = new xlet::type[incnt];
- int i;
- for(xi = inlist,i = 0; xi; xi = xi->nxt,++i) list[i] = xi->tp;
-
+
+ xlet *xi;
+ incnt = 0;
+ for(xi = inlist; xi; xi = xi->nxt) ++incnt;
+ xlet::type *list = new xlet::type[incnt];
+ int i;
+ for(xi = inlist,i = 0; xi; xi = xi->nxt,++i) list[i] = xi->tp;
+
#if FLEXT_SYS == FLEXT_SYS_MAX
- // copy inlet descriptions
- indesc = new char *[incnt];
- for(xi = inlist,i = 0; xi; xi = xi->nxt,++i) {
- int l = xi->desc?strlen(xi->desc):0;
- if(l) {
- indesc[i] = new char[l+1];
- memcpy(indesc[i],xi->desc,l);
- indesc[i][l] = 0;
- }
- else
- indesc[i] = NULL;
+ // copy inlet descriptions
+ indesc = new char *[incnt];
+ for(xi = inlist,i = 0; xi; xi = xi->nxt,++i) {
+ int l = xi->desc?strlen(xi->desc):0;
+ if(l) {
+ indesc[i] = new char[l+1];
+ memcpy(indesc[i],xi->desc,l);
+ indesc[i][l] = 0;
}
+ else
+ indesc[i] = NULL;
+ }
#endif
- delete inlist; inlist = NULL;
-
#if FLEXT_SYS == FLEXT_SYS_PD || FLEXT_SYS == FLEXT_SYS_MAX
- inlets = new px_object *[incnt];
- for(i = 0; i < incnt; ++i) inlets[i] = NULL;
+ inlets = new px_object *[incnt];
+ for(i = 0; i < incnt; ++i) inlets[i] = NULL;
#endif
-
- // type info is now in list array
+
+ // type info is now in list array
#if FLEXT_SYS == FLEXT_SYS_PD
- {
- int cnt = 0;
+ {
+ int cnt = 0;
+ xi = inlist; // points to first inlet
- if(incnt >= 1) {
- switch(list[0]) {
- case xlet::tp_sig:
- ++insigs;
- break;
- default:
- // leftmost inlet is already there...
- break;
- }
- ++cnt;
- }
+ if(incnt >= 1) {
+ switch(list[0]) {
+ case xlet::tp_sig:
+ ++insigs;
+ break;
+ default:
+ // leftmost inlet is already there...
+ break;
+ }
+ ++cnt;
- for(int ix = 1; ix < incnt; ++ix,++cnt) {
- switch(list[ix]) {
- case xlet::tp_float:
- case xlet::tp_int: {
- char sym[] = "ft??";
- if(ix >= 10) {
- if(compatibility) {
- // Max allows max. 9 inlets
- post("%s: Only 9 float/int inlets allowed in compatibility mode",thisName());
- ok = false;
- }
- else {
- if(ix > 99)
- post("%s: Inlet index > 99 not allowed for float/int inlets",thisName());
- sym[2] = '0'+ix/10,sym[3] = '0'+ix%10;
- }
- }
- else
- sym[2] = '0'+ix,sym[3] = 0;
- if(ok) inlet_new(&x_obj->obj, &x_obj->obj.ob_pd, (t_symbol *)sym_float, gensym(sym));
- break;
- }
- case xlet::tp_sym:
- (inlets[ix] = (px_object *)pd_new(px_class))->init(this,ix); // proxy for 2nd inlet messages
- inlet_new(&x_obj->obj,&inlets[ix]->obj.ob_pd, (t_symbol *)sym_symbol, (t_symbol *)sym_symbol);
- break;
- case xlet::tp_list:
- (inlets[ix] = (px_object *)pd_new(px_class))->init(this,ix); // proxy for 2nd inlet messages
- inlet_new(&x_obj->obj,&inlets[ix]->obj.ob_pd, (t_symbol *)sym_list, (t_symbol *)sym_list);
- break;
- case xlet::tp_any:
- (inlets[ix] = (px_object *)pd_new(px_class))->init(this,ix); // proxy for 2nd inlet messages
- inlet_new(&x_obj->obj,&inlets[ix]->obj.ob_pd, 0, 0);
- break;
- case xlet::tp_sig:
- if(compatibility && list[ix-1] != xlet::tp_sig) {
- post("%s: All signal inlets must be left-aligned in compatibility mode",thisName());
+#if PD_MINOR_VERSION >= 37 && defined(PD_DEVEL_VERSION)
+ // set tooltip
+ if(xi->desc && *xi->desc) class_settip(thisClass(),gensym(xi->desc));
+#endif
+ }
+
+ for(int ix = 1; ix < incnt; ++ix,++cnt) {
+ xi = xi->nxt; // points to next inlet
+
+ t_inlet *in = NULL;
+ switch(list[ix]) {
+ case xlet::tp_float:
+ case xlet::tp_int: {
+ char sym[] = "ft??";
+ if(ix >= 10) {
+ if(compatibility) {
+ // Max allows max. 9 inlets
+ post("%s: Only 9 float/int inlets allowed in compatibility mode",thisName());
ok = false;
}
else {
- // pd doesn't seem to be able to handle signals and messages into the same inlet...
-
- inlet_new(&x_obj->obj, &x_obj->obj.ob_pd, (t_symbol *)sym_signal, (t_symbol *)sym_signal);
- ++insigs;
+ if(ix > 99)
+ post("%s: Inlet index > 99 not allowed for float/int inlets",thisName());
+ sym[2] = '0'+ix/10,sym[3] = '0'+ix%10;
}
- break;
- default:
- error("%s: Wrong type for inlet #%i: %i",thisName(),ix,(int)list[ix]);
+ }
+ else
+ sym[2] = '0'+ix,sym[3] = 0;
+ if(ok) in = inlet_new(&x_obj->obj, &x_obj->obj.ob_pd, (t_symbol *)sym_float, gensym(sym));
+ break;
+ }
+ case xlet::tp_sym:
+ (inlets[ix] = (px_object *)pd_new(px_class))->init(this,ix); // proxy for 2nd inlet messages
+ in = inlet_new(&x_obj->obj,&inlets[ix]->obj.ob_pd, (t_symbol *)sym_symbol, (t_symbol *)sym_symbol);
+ break;
+ case xlet::tp_list:
+ (inlets[ix] = (px_object *)pd_new(px_class))->init(this,ix); // proxy for 2nd inlet messages
+ in = inlet_new(&x_obj->obj,&inlets[ix]->obj.ob_pd, (t_symbol *)sym_list, (t_symbol *)sym_list);
+ break;
+ case xlet::tp_any:
+ (inlets[ix] = (px_object *)pd_new(px_class))->init(this,ix); // proxy for 2nd inlet messages
+ in = inlet_new(&x_obj->obj,&inlets[ix]->obj.ob_pd, 0, 0);
+ break;
+ case xlet::tp_sig:
+ if(compatibility && list[ix-1] != xlet::tp_sig) {
+ post("%s: All signal inlets must be left-aligned in compatibility mode",thisName());
ok = false;
- }
- }
+ }
+ else {
+ // pd doesn't seem to be able to handle signals and messages into the same inlet...
+
+ in = inlet_new(&x_obj->obj, &x_obj->obj.ob_pd, (t_symbol *)sym_signal, (t_symbol *)sym_signal);
+ ++insigs;
+ }
+ break;
+ default:
+ error("%s: Wrong type for inlet #%i: %i",thisName(),ix,(int)list[ix]);
+ ok = false;
+ }
- incnt = cnt;
+#if PD_MINOR_VERSION >= 37 && defined(PD_DEVEL_VERSION)
+ // set tooltip
+ if(in && xi->desc && *xi->desc) inlet_settip(in,gensym(xi->desc));
+#endif
}
+
+ incnt = cnt;
+ }
#elif FLEXT_SYS == FLEXT_SYS_MAX
- {
- int ix,cnt;
- // count leftmost signal inlets
- while(insigs < incnt && list[insigs] == xlet::tp_sig) ++insigs;
-
- for(cnt = 0,ix = incnt-1; ix >= insigs; --ix,++cnt) {
- if(ix == 0) {
- if(list[ix] != xlet::tp_any) {
- error("%s: Leftmost inlet must be of type signal or anything",thisName());
- ok = false;
- }
- }
- else {
- switch(list[ix]) {
- case xlet::tp_sig:
- error("%s: All signal inlets must be left-aligned",thisName());
- ok = false;
- break;
- case xlet::tp_float:
- if(ix >= 10) {
- post("%s: Only 9 float inlets possible",thisName());
- ok = false;
- }
- else
- floatin(x_obj,ix);
- break;
- case xlet::tp_int:
- if(ix >= 10) {
- post("%s: Only 9 int inlets possible",thisName());
- ok = false;
- }
- else
- intin(x_obj,ix);
- break;
- case xlet::tp_any: // non-leftmost
- case xlet::tp_sym:
- case xlet::tp_list:
- inlets[ix] = (px_object *)proxy_new(x_obj,ix,&((flext_hdr *)x_obj)->curinlet);
- break;
- default:
- error("%s: Wrong type for inlet #%i: %i",thisName(),ix,(int)list[ix]);
- ok = false;
- }
+ {
+ int ix,cnt;
+ // count leftmost signal inlets
+ while(insigs < incnt && list[insigs] == xlet::tp_sig) ++insigs;
+
+ for(cnt = 0,ix = incnt-1; ix >= insigs; --ix,++cnt) {
+ if(ix == 0) {
+ if(list[ix] != xlet::tp_any) {
+ error("%s: Leftmost inlet must be of type signal or anything",thisName());
+ ok = false;
}
}
-
-// incnt = cnt;
-
- if(insigs)
-// dsp_setup(thisHdr(),insigs); // signal inlets
- dsp_setupbox(thisHdr(),insigs); // signal inlets
- }
-#elif FLEXT_SYS == FLEXT_SYS_JMAX
- {
- t_class *cl = thisClass();
- int cnt = 0;
- for(int ix = 0; ix < incnt; ++ix,++cnt) {
+ else {
switch(list[ix]) {
- case xlet::tp_float:
- case xlet::tp_int:
-// fts_class_inlet_number(cl, ix, jmax_proxy);
- break;
- case xlet::tp_sym:
-// fts_class_inlet_symbol(cl, ix, jmax_proxy);
- break;
case xlet::tp_sig:
- if(compatibility && list[ix-1] != xlet::tp_sig) {
- post("%s: All signal inlets must be left-aligned in compatibility mode",thisName());
+ error("%s: All signal inlets must be left-aligned",thisName());
+ ok = false;
+ break;
+ case xlet::tp_float:
+ if(ix >= 10) {
+ post("%s: Only 9 float inlets possible",thisName());
ok = false;
}
- else {
- if(!insigs) fts_dsp_declare_inlet(cl,0);
- ++insigs;
+ else
+ floatin(x_obj,ix);
+ break;
+ case xlet::tp_int:
+ if(ix >= 10) {
+ post("%s: Only 9 int inlets possible",thisName());
+ ok = false;
}
- // no break -> let a signal inlet also accept any messages
+ else
+ intin(x_obj,ix);
+ break;
+ case xlet::tp_any: // non-leftmost
+ case xlet::tp_sym:
case xlet::tp_list:
- case xlet::tp_any:
-// fts_class_inlet_varargs(cl,ix, jmax_proxy);
+ inlets[ix] = (px_object *)proxy_new(x_obj,ix,&((flext_hdr *)x_obj)->curinlet);
break;
default:
error("%s: Wrong type for inlet #%i: %i",thisName(),ix,(int)list[ix]);
ok = false;
}
}
+ }
- incnt = cnt;
+// incnt = cnt;
- fts_object_set_inlets_number((fts_object_t *)thisHdr(), incnt);
+ if(insigs)
+// dsp_setup(thisHdr(),insigs); // signal inlets
+ dsp_setupbox(thisHdr(),insigs); // signal inlets
+ }
+#elif FLEXT_SYS == FLEXT_SYS_JMAX
+ {
+ t_class *cl = thisClass();
+ int cnt = 0;
+ for(int ix = 0; ix < incnt; ++ix,++cnt) {
+ switch(list[ix]) {
+ case xlet::tp_float:
+ case xlet::tp_int:
+// fts_class_inlet_number(cl, ix, jmax_proxy);
+ break;
+ case xlet::tp_sym:
+// fts_class_inlet_symbol(cl, ix, jmax_proxy);
+ break;
+ case xlet::tp_sig:
+ if(compatibility && list[ix-1] != xlet::tp_sig) {
+ post("%s: All signal inlets must be left-aligned in compatibility mode",thisName());
+ ok = false;
+ }
+ else {
+ if(!insigs) fts_dsp_declare_inlet(cl,0);
+ ++insigs;
+ }
+ // no break -> let a signal inlet also accept any messages
+ case xlet::tp_list:
+ case xlet::tp_any:
+// fts_class_inlet_varargs(cl,ix, jmax_proxy);
+ break;
+ default:
+ error("%s: Wrong type for inlet #%i: %i",thisName(),ix,(int)list[ix]);
+ ok = false;
+ }
}
+
+ incnt = cnt;
+
+ fts_object_set_inlets_number((fts_object_t *)thisHdr(), incnt);
+ }
#else
#error
#endif
- delete[] list;
- }
+ delete inlist; inlist = NULL;
+
+ delete[] list;
return ok;
}
@@ -312,8 +325,6 @@ bool flext_base::InitOutlets()
}
#endif
- delete outlist; outlist = NULL;
-
#if FLEXT_SYS == FLEXT_SYS_PD || FLEXT_SYS == FLEXT_SYS_MAX
outlets = new outlet *[outcnt+(procattr?1:0)];
@@ -400,6 +411,8 @@ bool flext_base::InitOutlets()
}
#endif
+ delete outlist; outlist = NULL;
+
return ok;
}
diff --git a/externals/grill/py/readme.txt b/externals/grill/py/readme.txt
index aa9a96a6..57a44661 100644
--- a/externals/grill/py/readme.txt
+++ b/externals/grill/py/readme.txt
@@ -82,6 +82,10 @@ o GCC: edit "config-pd-darwin.txt" & run "sh build-pd-darwin.sh"
Version history:
+0.1.4:
+- ADD: better (and independent) handling of inlet and outlet count (as class variables or dynamically initialized in __init__)
+- FIX: many memory leaks associated to ***GetItem stuff (big thanks to sven!)
+
0.1.3:
- FIX: class variables are now set atomic if parameter list has only 1 element
- ADD: introduced shortcut "pyx" for pyext.
diff --git a/externals/grill/py/source/bound.cpp b/externals/grill/py/source/bound.cpp
index 9578e4c0..75a462e4 100644
--- a/externals/grill/py/source/bound.cpp
+++ b/externals/grill/py/source/bound.cpp
@@ -38,6 +38,8 @@ bool pyext::boundmeth(flext_base *,t_symbol *sym,int argc,t_atom *argv,void *dat
Py_XDECREF(ret);
}
+ Py_XDECREF(args);
+
PY_UNLOCK
return true;
}
diff --git a/externals/grill/py/source/clmeth.cpp b/externals/grill/py/source/clmeth.cpp
index d3b909ff..a9770834 100644
--- a/externals/grill/py/source/clmeth.cpp
+++ b/externals/grill/py/source/clmeth.cpp
@@ -122,9 +122,11 @@ PyObject* pyext::pyext_getattr(PyObject *,PyObject *args)
if(!ret) {
#if PY_VERSION_HEX >= 0x02020000
+ // \todo borrowed or new???
ret = PyObject_GenericGetAttr(self,name);
#else
if(PyInstance_Check(self))
+ // borrowed reference
ret = PyDict_GetItem(((PyInstanceObject *)self)->in_dict,name);
#endif
}
@@ -135,48 +137,54 @@ PyObject* pyext::pyext_getattr(PyObject *,PyObject *args)
PyObject *pyext::pyext_outlet(PyObject *,PyObject *args)
{
BL ok = false;
- if(PySequence_Check(args)) {
- PyObject *self = PySequence_GetItem(args,0);
- PyObject *outl = PySequence_GetItem(args,1);
- if(
- self && PyInstance_Check(self) &&
- outl && PyInt_Check(outl)
- ) {
- pyext *ext = GetThis(self);
-
- I sz = PySequence_Size(args);
- PyObject *val;
- BL tp = sz == 3 && PySequence_Check(PySequence_GetItem(args,2));
-
- if(tp)
- val = PySequence_GetItem(args,2); // borrowed
- else
- val = PySequence_GetSlice(args,2,sz); // new ref
-
- AtomList *lst = GetPyArgs(val);
- if(lst) {
- I o = PyInt_AsLong(outl);
- if(o >= 1 && o <= ext->Outlets()) {
- // by using the queue there is no immediate call of the next object
- // deadlock would occur if this was another py/pyext object!
- if(lst->Count() && IsSymbol((*lst)[0]))
- ext->ToQueueAnything(o-1,GetSymbol((*lst)[0]),lst->Count()-1,lst->Atoms()+1);
+
+ // should always be a tuple!
+ 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);
+
+ I sz = PyTuple_Size(args);
+ PyObject *val;
+
+ BL tp =
+ sz == 3 &&
+ PySequence_Check(
+ val = PyTuple_GetItem(args,2) // borrow reference
+ );
+
+ if(!tp)
+ val = PySequence_GetSlice(args,2,sz); // new ref
+
+ AtomList *lst = GetPyArgs(val);
+ if(lst) {
+ I o = PyInt_AsLong(outl);
+ if(o >= 1 && o <= ext->Outlets()) {
+ // by using the queue there is no immediate call of the next object
+ // deadlock would occur if this was another py/pyext object!
+ if(lst->Count() && IsSymbol((*lst)[0]))
+ ext->ToQueueAnything(o-1,GetSymbol((*lst)[0]),lst->Count()-1,lst->Atoms()+1);
// ext->ToOutAnything(o-1,GetSymbol((*lst)[0]),lst->Count()-1,lst->Atoms()+1);
- else
- ext->ToQueueList(o-1,*lst);
-// ext->ToOutList(o-1,*lst);
- }
else
- post("pyext: outlet index out of range");
-
- ok = true;
+ ext->ToQueueList(o-1,*lst);
+// ext->ToOutList(o-1,*lst);
}
- else
- post("py/pyext - No data to send");
- if(lst) delete lst;
+ else
+ post("pyext: outlet index out of range");
- if(!tp) Py_DECREF(val);
+ ok = true;
}
+ else
+ post("py/pyext - No data to send");
+ if(lst) delete lst;
+
+ if(!tp) Py_DECREF(val);
}
if(!ok) post("pyext - Syntax: _outlet(self,outlet,args...)");
@@ -245,40 +253,43 @@ PyObject *pyext::pyext_isthreaded(PyObject *,PyObject *)
//! Send message to canvas
PyObject *pyext::pyext_tocanvas(PyObject *,PyObject *args)
{
+ FLEXT_ASSERT(PyTuple_Check(args));
+
BL ok = false;
- if(PySequence_Check(args)) {
- PyObject *self = PySequence_GetItem(args,0);
- if(self && PyInstance_Check(self)) {
- pyext *ext = GetThis(self);
+ PyObject *self = PyTuple_GetItem(args,0); // borrowed ref
+ if(self && PyInstance_Check(self)) {
+ pyext *ext = GetThis(self);
- I sz = PySequence_Size(args);
- PyObject *val;
- BL tp = sz == 2 && PySequence_Check(PyTuple_GetItem(args,1));
+ I sz = PySequence_Size(args);
+ PyObject *val;
- if(tp)
- val = PySequence_GetItem(args,1); // borrowed
- else
- val = PySequence_GetSlice(args,1,sz); // new ref
-
- AtomList *lst = GetPyArgs(val);
- if(lst) {
- t_glist *gl = ext->thisCanvas(); //canvas_getcurrent();
- t_class **cl = (t_pd *)gl;
- if(cl) {
- pd_forwardmess(cl,lst->Count(),lst->Atoms());
- }
+ BL tp =
+ sz == 2 &&
+ PySequence_Check(
+ val = PyTuple_GetItem(args,1) // borrowed ref
+ );
+
+ if(!tp)
+ val = PyTuple_GetSlice(args,1,sz); // new ref
+
+ AtomList *lst = GetPyArgs(val);
+ if(lst) {
+ t_glist *gl = ext->thisCanvas(); //canvas_getcurrent();
+ t_class **cl = (t_pd *)gl;
+ if(cl) {
+ pd_forwardmess(cl,lst->Count(),lst->Atoms());
+ }
#ifdef FLEXT_DEBUG
- else
- post("pyext - no parent canvas?!");
+ else
+ post("pyext - no parent canvas?!");
#endif
- ok = true;
- }
- else
- post("py/pyext - No data to send");
- if(lst) delete lst;
-
- if(!tp) Py_DECREF(val);
+ ok = true;
}
+ else
+ post("py/pyext - No data to send");
+ if(lst) delete lst;
+
+ if(!tp) Py_DECREF(val);
}
if(!ok) post("pyext - Syntax: _tocanvas(self,args...)");
diff --git a/externals/grill/py/source/main.cpp b/externals/grill/py/source/main.cpp
index 034fefd2..20e7a865 100644
--- a/externals/grill/py/source/main.cpp
+++ b/externals/grill/py/source/main.cpp
@@ -279,7 +279,7 @@ V py::AddToPath(const C *dir)
if(pobj && PyList_Check(pobj)) {
int i,n = PyList_Size(pobj);
for(i = 0; i < n; ++i) {
- PyObject *pt = PyList_GetItem(pobj,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
@@ -296,33 +296,37 @@ static PyObject *output = NULL;
// post to the console
PyObject* py::StdOut_Write(PyObject* self, PyObject* args)
{
- if(PySequence_Check(args)) {
- int sz = PySequence_Size(args);
- for(int i = 0; i < sz; ++i) {
- PyObject *val = PySequence_GetItem(args,i); // borrowed
- PyObject *str = PyObject_Str(val);
- char *cstr = PyString_AS_STRING(str);
- char *lf = strchr(cstr,'\n');
-
- // line feed in string
- if(!lf) {
- // no -> just append
- if(output)
- PyString_ConcatAndDel(&output,str);
- else
- output = str;
- }
- else {
- // yes -> append up to line feed, reset output buffer to string remainder
- PyObject *part = PyString_FromStringAndSize(cstr,lf-cstr);
- if(output)
- PyString_ConcatAndDel(&output,part);
- else
- output = part;
- post(PyString_AS_STRING(output));
- Py_DECREF(output);
- output = PyString_FromString(lf+1);
- }
+ // should always be a tuple
+ 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);
+ char *lf = strchr(cstr,'\n');
+
+ // line feed in string
+ if(!lf) {
+ // no -> just append
+ if(output)
+ PyString_ConcatAndDel(&output,str); // str is decrefd
+ else
+ output = str; // take str reference
+ }
+ else {
+ // yes -> append up to line feed, reset output buffer to string remainder
+ PyObject *part = PyString_FromStringAndSize(cstr,lf-cstr); // new reference
+ if(output)
+ PyString_ConcatAndDel(&output,part); // str is decrefd
+ else
+ output = part; // take str reference
+
+ // output concatenated string
+ post(PyString_AS_STRING(output));
+
+ Py_DECREF(output);
+ output = PyString_FromString(lf+1); // new reference
}
}
diff --git a/externals/grill/py/source/modmeth.cpp b/externals/grill/py/source/modmeth.cpp
index b3a98c98..0fe0cc6a 100644
--- a/externals/grill/py/source/modmeth.cpp
+++ b/externals/grill/py/source/modmeth.cpp
@@ -104,7 +104,7 @@ PyObject *py::py_inchannels(PyObject *self,PyObject *args)
#if FLEXT_SYS == FLEXT_SYS_PD
I ch = sys_get_inchannels();
#elif FLEXT_SYS == FLEXT_SYS_MAX
- I ch = sys_getch(); // not functioning
+ I ch = sys_getch(); // not working
#else
#pragma message("Not implemented!")
ch = 0;
@@ -117,7 +117,7 @@ PyObject *py::py_outchannels(PyObject *self,PyObject *args)
#if FLEXT_SYS == FLEXT_SYS_PD
I ch = sys_get_outchannels();
#elif FLEXT_SYS == FLEXT_SYS_MAX
- I ch = sys_getch(); // not functioning
+ I ch = sys_getch(); // not working
#else
#pragma message("Not implemented!")
ch = 0;
@@ -127,41 +127,45 @@ PyObject *py::py_outchannels(PyObject *self,PyObject *args)
PyObject *py::py_send(PyObject *,PyObject *args)
{
- if(PySequence_Check(args)) {
- PyObject *name = PySequence_GetItem(args,0); // borrowed
- if(name && PyString_Check(name)) {
- const t_symbol *recv = MakeSymbol(PyString_AsString(name));
- I sz = PySequence_Size(args);
- PyObject *val;
- BL tp = sz == 2 && PySequence_Check(PySequence_GetItem(args,1));
-
- if(tp)
- val = PySequence_GetItem(args,1); // borrowed
+ // should always be a tuple
+ 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;
+
+ bool tp =
+ sz == 2 &&
+ PySequence_Check(
+ val = PyTuple_GetItem(args,1) // borrowed ref
+ );
+
+ if(!tp)
+ val = PySequence_GetSlice(args,1,sz); // new ref
+
+ AtomList *lst = GetPyArgs(val);
+ if(lst) {
+ bool ok;
+ if(lst->Count() && IsSymbol((*lst)[0]))
+ ok = Forward(recv,GetSymbol((*lst)[0]),lst->Count()-1,lst->Atoms()+1);
else
- val = PySequence_GetSlice(args,1,sz); // new ref
-
- AtomList *lst = GetPyArgs(val);
- if(lst) {
- bool ok;
- if(lst->Count() && IsSymbol((*lst)[0]))
- ok = Forward(recv,GetSymbol((*lst)[0]),lst->Count()-1,lst->Atoms()+1);
- else
- ok = Forward(recv,*lst);
+ ok = Forward(recv,*lst);
#ifdef FLEXT_DEBUG
- if(!ok)
- post("py/pyext - Receiver doesn't exist");
+ if(!ok)
+ post("py/pyext - Receiver doesn't exist");
#endif
- }
- else
- post("py/pyext - No data to send");
- if(lst) delete lst;
-
- if(!tp) Py_DECREF(val);
}
- else
- post("py/pyext - Send name is invalid");
+ else
+ post("py/pyext - No data to send");
+ if(lst) delete lst;
+
+ if(!tp) Py_DECREF(val);
}
+ else
+ post("py/pyext - Send name is invalid");
Py_INCREF(Py_None);
return Py_None;
diff --git a/externals/grill/py/source/pyargs.cpp b/externals/grill/py/source/pyargs.cpp
index 1b204273..69e403b0 100644
--- a/externals/grill/py/source/pyargs.cpp
+++ b/externals/grill/py/source/pyargs.cpp
@@ -116,10 +116,10 @@ flext::AtomList *py::GetPyArgs(PyObject *pValue,PyObject **self)
for(I ix = 0; ix < rargc; ++ix) {
PyObject *arg;
- switch(tp) {
- case sequ: arg = PySequence_GetItem(pValue,ix); break;
- default: arg = pValue;
- }
+ if(tp == sequ)
+ arg = PySequence_GetItem(pValue,ix); // new reference
+ else
+ arg = pValue;
if(PyInt_Check(arg)) SetInt((*ret)[ix],PyInt_AsLong(arg));
else if(PyLong_Check(arg)) SetInt((*ret)[ix],PyLong_AsLong(arg));
@@ -127,6 +127,7 @@ flext::AtomList *py::GetPyArgs(PyObject *pValue,PyObject **self)
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_ !!!
+ Py_INCREF(arg);
*self = arg;
}
else {
@@ -139,7 +140,8 @@ flext::AtomList *py::GetPyArgs(PyObject *pValue,PyObject **self)
Py_XDECREF(tp);
ok = false;
}
- // No DECREF for arg -> borrowed from pValue!
+
+ if(tp == sequ) Py_DECREF(arg);
}
if(!ok) {
diff --git a/externals/grill/py/source/pyext.cpp b/externals/grill/py/source/pyext.cpp
index 7ce0995c..adaacc0e 100644
--- a/externals/grill/py/source/pyext.cpp
+++ b/externals/grill/py/source/pyext.cpp
@@ -76,10 +76,15 @@ V pyext::Setup(t_classid c)
pyext *pyext::GetThis(PyObject *self)
{
PyObject *th = PyObject_GetAttrString(self,"_this");
- pyext *ret = th?(pyext *)PyLong_AsVoidPtr(th):NULL;
- PyErr_Clear();
- Py_XDECREF(th);
- return ret;
+ if(th) {
+ pyext *ret = static_cast<pyext *>(PyLong_AsVoidPtr(th));
+ Py_DECREF(th);
+ return ret;
+ }
+ else {
+ PyErr_Clear();
+ return NULL;
+ }
}
@@ -385,7 +390,7 @@ void pyext::m_set(int argc,const t_atom *argv)
if(PySequence_Size(pval) == 1) {
// reduce lists of one element to element itself
- PyObject *val1 = PySequence_GetItem(pval,0);
+ PyObject *val1 = PySequence_GetItem(pval,0); // new reference
Py_DECREF(pval);
pval = val1;
}
diff --git a/externals/grill/py/source/register.cpp b/externals/grill/py/source/register.cpp
index 9fe4dfc7..16e1df65 100644
--- a/externals/grill/py/source/register.cpp
+++ b/externals/grill/py/source/register.cpp
@@ -66,7 +66,7 @@ V py::Reregister(const C *regnm)
else {
I cnt = PySequence_Size(reg);
for(I i = 0; i < cnt; ++i) {
- PyObject *it = PySequence_GetItem(reg,i); // borrowed!!
+ PyObject *it = PySequence_GetItem(reg,i); // new reference
if(!it || !PyInt_Check(it)) {
post("%s - Corrupt registry?!",thisName());
}
@@ -76,6 +76,8 @@ V py::Reregister(const C *regnm)
th->dict = dict;
th->Reload();
}
+
+ Py_XDECREF(it);
}
}
}
diff --git a/externals/grill/vasp/changes.txt b/externals/grill/vasp/changes.txt
index 5d79e4dc..8a2a7dc1 100644
--- a/externals/grill/vasp/changes.txt
+++ b/externals/grill/vasp/changes.txt
@@ -21,6 +21,8 @@ Version history:
- ADD: [vasp.channels?] reports number of channels in the first vasp vector (buffer/array)
- CHANGE: vasp.min?, vasp.max?, vasp.amin?, vasp.amax?, vasp.rmin?, vasp.rmax? no longer return the reference vasp / return a list of vector maxima/minima
- CHANGE: inherited several classes from the flext class, so that new and delete use the RT-system functions
+- FIX: fixed memory leaks associated to VBuffer retrieval
+- FIX: fixed bug on vasp.search for vectors with 0 channels
0.1.2:
- FIX: bug in vasp.frames* ... wrong argument
diff --git a/externals/grill/vasp/source/main.cpp b/externals/grill/vasp/source/main.cpp
index 60352bda..7fb2f0bc 100644
--- a/externals/grill/vasp/source/main.cpp
+++ b/externals/grill/vasp/source/main.cpp
@@ -12,7 +12,7 @@ WARRANTIES, see the file, "license.txt," in this distribution.
#include "classes.h"
-const C *VASP_VERSION = "0.1.3pre11";
+const C *VASP_VERSION = "0.1.3pre12";
#include "opfuns.h"
diff --git a/externals/grill/vasp/source/obj_imm.cpp b/externals/grill/vasp/source/obj_imm.cpp
index ba421ff4..ef75f228 100644
--- a/externals/grill/vasp/source/obj_imm.cpp
+++ b/externals/grill/vasp/source/obj_imm.cpp
@@ -99,6 +99,8 @@ public:
Vasp ret(len,vr);
ToOutVasp(0,ret);
+
+ delete buf;
}
}
diff --git a/externals/grill/vasp/source/obj_peaks.cpp b/externals/grill/vasp/source/obj_peaks.cpp
index e7d7dd80..c9867150 100644
--- a/externals/grill/vasp/source/obj_peaks.cpp
+++ b/externals/grill/vasp/source/obj_peaks.cpp
@@ -98,6 +98,8 @@ public:
ToOutAnything(1,sym_list,pkfnd,lst);
delete[] pos;
delete[] lst;
+
+ delete buf;
}
}
diff --git a/externals/grill/vasp/source/obj_q.cpp b/externals/grill/vasp/source/obj_q.cpp
index c3f86ca5..e3c01f44 100644
--- a/externals/grill/vasp/source/obj_q.cpp
+++ b/externals/grill/vasp/source/obj_q.cpp
@@ -51,6 +51,8 @@ public:
AtomList lst(cnt);
for(I i = 0; i < cnt; ++i,++p) SetFloat(lst[i],*p);
ToOutList(0,lst);
+
+ delete buf;
}
}
@@ -110,6 +112,8 @@ public:
}
ToOutList(0,pos);
ToOutList(1,lst);
+
+ delete buf;
}
}
diff --git a/externals/grill/vasp/source/ops_search.cpp b/externals/grill/vasp/source/ops_search.cpp
index d805437d..bc7c1345 100644
--- a/externals/grill/vasp/source/ops_search.cpp
+++ b/externals/grill/vasp/source/ops_search.cpp
@@ -79,12 +79,15 @@ BL VecOp::d_search(OpParam &p)
Vasp *VaspOp::m_search(OpParam &p,CVasp &src,const Argument &arg,CVasp *dst,BL st)
{
Vasp *ret = NULL;
- if(src.Vectors() > 1)
- post("%s - More than one vector in vasp!",p.opName());
+ if(src.Vectors() != 1)
+ post("%s - Need exactly one vector in vasp!",p.opName());
else if(arg.CanbeFloat() || (arg.IsList() && arg.GetList().Count() >= 1)) {
I fr = src.Frames();
I o = src.Vector(0).Offset();
- I sz = src.Buffer(0)->Frames();
+
+ VBuffer *buf = src.Buffer(0);
+ I sz = buf->Frames();
+ delete buf;
CVasp all(src);
if(st) {