From 1a23e8233e6c1cbc30b9ddee4df153c21f4b282b Mon Sep 17 00:00:00 2001 From: Thomas Grill Date: Tue, 31 Aug 2004 04:07:35 +0000 Subject: "" svn path=/trunk/; revision=1982 --- externals/grill/flext/changes.txt | 1 + externals/grill/flext/source/flout.cpp | 335 +++++++++++++++-------------- externals/grill/py/readme.txt | 4 + externals/grill/py/source/bound.cpp | 2 + externals/grill/py/source/clmeth.cpp | 141 ++++++------ externals/grill/py/source/main.cpp | 60 +++--- externals/grill/py/source/modmeth.cpp | 66 +++--- externals/grill/py/source/pyargs.cpp | 12 +- externals/grill/py/source/pyext.cpp | 15 +- externals/grill/py/source/register.cpp | 4 +- externals/grill/vasp/changes.txt | 2 + externals/grill/vasp/source/main.cpp | 2 +- externals/grill/vasp/source/obj_imm.cpp | 2 + externals/grill/vasp/source/obj_peaks.cpp | 2 + externals/grill/vasp/source/obj_q.cpp | 4 + externals/grill/vasp/source/ops_search.cpp | 9 +- 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(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) { -- cgit v1.2.1