Hi Miller, just in case you haven't noticed, here's the promised bugfix for [list store]: https://sourceforge.net/p/pure-data/patches/583/
With this fix I don't get any error messages and crashes anymore. I've just added a cleaner version. Christof > Gesendet: Samstag, 22. Juli 2017 um 14:21 Uhr > Von: "Christof Ressi" <christof.re...@gmx.at> > An: "Miller Puckette" <m...@ucsd.edu> > Cc: pd-...@iem.at > Betreff: Re: [PD-dev] 0.48.0 release status > > Yeah, let's save this for later. In the meantime I'll try to hunt down the > pointer bugs... > > > Gesendet: Freitag, 21. Juli 2017 um 19:58 Uhr > > Von: "Miller Puckette" <m...@ucsd.edu> > > An: "Christof Ressi" <christof.re...@gmx.at> > > Cc: "Dan Wilcox" <danomat...@gmail.com>, pd-...@iem.at > > Betreff: Re: [PD-dev] 0.48.0 release status > > > > OK... for now, I renamed "range" to "get" (did it right away to avoid the > > necessity of keeping the other name for compatibility). We can mess with > > the > > other stuff later. > > > > Not sure about the pointer issues, will just hope that doesn't bite us > > before > > I can look closer at it. > > > > Meanwhile, yeah, I can think of losts of cool things to try (e.g., "sort") > > > > cheers > > Miller > > > > On Fri, Jul 21, 2017 at 06:20:49PM +0200, Christof Ressi wrote: > > > Thanks for your answer! I guess it doesn't have high priority but anyway, > > > the thing is this: > > > > > > I'm really happy about [list store] but I think it can be way more > > > expressive. My idea was to take the interface of [text] and [array] to > > > add more methods. > > > > > > First, I renamed [range( to [get( (but kept the old method around as an > > > alias) because it's structurally very similar to [text get] and [array > > > get]. > > > > > > Then I added a method [set <f> ...( which lets you overwrite atoms, just > > > like [text set] and [array set]. the first float is the index, followed > > > by the atoms you want to copy. > > > > > > Then I added a general [insert <f> ...( method which lets you insert > > > atoms, where the first float is the index, followed by the atoms you want > > > to insert *before* that index. A large index lets you append atoms. I > > > kept [prepend ...( and [append ...( as shortcuts for those two special > > > cases. > > > > > > Finally I added a [delete <f> <f>( method where the first float is the > > > index to start deleting and the second float is the number of floats to > > > delete. > > > > > > --- > > > > > > These methods would turn [list store] into a powerful dynamically sized > > > type-agnostic array - which we don't have in Pd yet! [text] comes > > > closest, but it doesn't handle pointers and it bashes everything to > > > binbufs which sometimes leads to unexpected or undesired behaviour. > > > > > > Please find my version of x_list.c(which also includes the bug fix that > > > you've already applied) and a messy test patch attached. I didn't have > > > much time... > > > > > > The methods works well with floats and symbols but there are mysterious > > > bugs with pointers. Not only with my new method but also with your > > > [range( method (which I didn't change). For example, sequencing a list of > > > pointers creates 'consistency check failed' errors with [print] and > > > sometimes there are crashes with segmentation faults. > > > > > > Also, I'm wondering if memmove() and realloc() is really safe with arrays > > > of t_listelem because a gpointer atom l_a inside t_listelem points to > > > l_a. when the array changes location in memory, won't the pointer point > > > to the wrong location? > > > > > > I know there are more important things to do right now. Just have look > > > when you have time. > > > > > > Thanks! > > > > > > Christof > > > > > > > > > > > > > > > > > > > > > > Gesendet: Freitag, 21. Juli 2017 um 17:26 Uhr > > > > Von: "Miller Puckette" <m...@ucsd.edu> > > > > An: "Christof Ressi" <christof.re...@gmx.at> > > > > Cc: "Dan Wilcox" <danomat...@gmail.com>, pd-...@iem.at > > > > Betreff: Re: [PD-dev] 0.48.0 release status > > > > > > > > Always open to bug reports (although swamped right now I'm afraid, will > > > > only > > > > get to things that are either urgent or easy :) > > > > > > > > I've already fixed "list_store_range" following your earlier report, > > > > thanks. > > > > > > > > Miller > > > > > > > > On Fri, Jul 21, 2017 at 01:05:15PM +0200, Christof Ressi wrote: > > > > > I got some more feedback/code for [list store], apart from the > > > > > list_store_range bug I've already reported on the list. Is there some > > > > > time left for you guys to review it? I can send it in a couple of > > > > > hours. I'm travelling right now. > > > > > > > > > > Christof > > > > > > > > > > > Gesendet: Freitag, 21. Juli 2017 um 11:54 Uhr > > > > > > Von: "Dan Wilcox" <danomat...@gmail.com> > > > > > > An: pd-...@iem.at > > > > > > Cc: "Miller Puckette" <m...@ucsd.edu> > > > > > > Betreff: [PD-dev] 0.48.0 release status > > > > > > > > > > > > Ok all, at this point we've nailed most of the bugs and feedback so > > > > > > far. The latest PR is > > > > > > https://github.com/pure-data/pure-data/pull/123 > > > > > > <https://github.com/pure-data/pure-data/pull/123> > > > > > > > > > > > > As far as I can tell, the only remaining things which could be > > > > > > done/included for the release are: > > > > > > > > > > > > Small Stuff > > > > > > > > > > > > * Remove midiin & sysexin Windows warnings in x_midi.c (& update > > > > > > help file) > > > > > > > > > > > > (Optional) Big Stuff > > > > > > > > > > > > * Adopt DejaVu Sans Mono a the default font -> this is in the > > > > > > dejavu branch https://github.com/pure-data/pure-data/pull/42 > > > > > > <https://github.com/pure-data/pure-data/pull/42> > > > > > > This is mainly for mac & Linux, Windows support will need to be > > > > > > added later as mentioned in the discussion. It also fixes the bad > > > > > > Monaco rendering on > > > > > > retina screens at small font sizes. > > > > > > * Update the icon -> see my pd-icon repo > > > > > > https://github.com/pure-data/pd-icon > > > > > > <https://github.com/pure-data/pd-icon> & the recent thread on the > > > > > > pd-list > > > > > > > > > > > > There may be more things, but I think I'm done on my end for now. > > > > > > We could do one final test release after this, but hopefully the > > > > > > feedback bugs will all have been fixed. > > > > > > > > > > > > -------- > > > > > > Dan Wilcox > > > > > > @danomatika <http://twitter.com/danomatika> > > > > > > danomatika.com <http://danomatika.com/> > > > > > > robotcowboy.com <http://robotcowboy.com/> > > > > > > > > > > > > > > > > > > > > > > > > _______________________________________________ > > > > > > Pd-dev mailing list > > > > > > Pd-dev@lists.iem.at > > > > > > https://lists.puredata.info/listinfo/pd-dev > > > > > > > > > > > > > > > > _______________________________________________ > > > > > Pd-dev mailing list > > > > > Pd-dev@lists.iem.at > > > > > https://lists.puredata.info/listinfo/pd-dev > > > > > > > > > > > /* Copyright (c) 1997- Miller Puckette and others. > > > * For information on usage and redistribution, and for a DISCLAIMER OF ALL > > > * WARRANTIES, see the file, "LICENSE.txt," in this distribution. */ > > > > > > #include "m_pd.h" > > > #include <string.h> > > > > > > #ifdef _WIN32 > > > # include <malloc.h> /* MSVC or mingw on windows */ > > > #elif defined(__linux__) || defined(__APPLE__) > > > # include <alloca.h> /* linux, mac, mingw, cygwin */ > > > #else > > > # include <stdlib.h> /* BSDs for example */ > > > #endif > > > > > > #ifndef HAVE_ALLOCA /* can work without alloca() but we never need it > > > */ > > > #define HAVE_ALLOCA 1 > > > #endif > > > > > > #define LIST_NGETBYTE 100 /* bigger that this we use alloc, not alloca */ > > > > > > /* the "list" object family. > > > > > > list append - append a list to another > > > list prepend - prepend a list to another > > > list split - first n elements to first outlet, rest to second outlet > > > list trim - trim off "list" selector > > > list length - output number of items in list > > > list fromsymbol - "explode" a symbol into a list of character codes > > > > > > Need to think more about: > > > list foreach - spit out elements of a list one by one (also in > > > reverse?) > > > list reverse - permute elements of a list back to front > > > list cat - build a list by accumulating elements > > > > > > Probably don't need: > > > list first - output first n elements. > > > list last - output last n elements > > > list nth - nth item in list, counting from zero > > > list array - get items from a named array as a list > > > list pack - synonym for 'pack' > > > list unpack - synonym for 'unpack' > > > */ > > > > > > /* -------------- utility functions: storage, copying -------------- */ > > > /* List element for storage. Keep an atom and, in case it's a > > > pointer, > > > an associated 'gpointer' to protect against stale pointers. */ > > > typedef struct _listelem > > > { > > > t_atom l_a; > > > t_gpointer l_p; > > > } t_listelem; > > > > > > typedef struct _alist > > > { > > > t_pd l_pd; /* object to point inlets to */ > > > int l_n; /* number of items */ > > > int l_npointer; /* number of pointers */ > > > t_listelem *l_vec; /* pointer to items */ > > > } t_alist; > > > > > > #if HAVE_ALLOCA > > > #define ATOMS_ALLOCA(x, n) ((x) = (t_atom *)((n) < LIST_NGETBYTE ? \ > > > alloca((n) * sizeof(t_atom)) : getbytes((n) * sizeof(t_atom)))) > > > #define ATOMS_FREEA(x, n) ( \ > > > ((n) < LIST_NGETBYTE || (freebytes((x), (n) * sizeof(t_atom)), 0))) > > > #else > > > #define ATOMS_ALLOCA(x, n) ((x) = (t_atom *)getbytes((n) * > > > sizeof(t_atom))) > > > #define ATOMS_FREEA(x, n) (freebytes((x), (n) * sizeof(t_atom))) > > > #endif > > > > > > static void atoms_copy(int argc, t_atom *from, t_atom *to) > > > { > > > int i; > > > for (i = 0; i < argc; i++) > > > to[i] = from[i]; > > > } > > > > > > /* ------------- fake class to divert inlets to ----------------- */ > > > > > > t_class *alist_class; > > > > > > static void alist_init(t_alist *x) > > > { > > > x->l_pd = alist_class; > > > x->l_n = x->l_npointer = 0; > > > x->l_vec = 0; > > > } > > > > > > static void alist_clear(t_alist *x) > > > { > > > int i; > > > for (i = 0; i < x->l_n; i++) > > > { > > > if (x->l_vec[i].l_a.a_type == A_POINTER) > > > gpointer_unset(x->l_vec[i].l_a.a_w.w_gpointer); > > > } > > > if (x->l_vec) > > > freebytes(x->l_vec, x->l_n * sizeof(*x->l_vec)); > > > } > > > > > > static void alist_copyin(t_alist *x, t_symbol *s, int argc, t_atom *argv, > > > int where) > > > { > > > int i, j; > > > for (i = 0, j = where; i < argc; i++, j++) > > > { > > > x->l_vec[j].l_a = argv[i]; > > > if (x->l_vec[j].l_a.a_type == A_POINTER) > > > { > > > x->l_npointer++; > > > gpointer_copy(x->l_vec[j].l_a.a_w.w_gpointer, > > > &x->l_vec[j].l_p); > > > x->l_vec[j].l_a.a_w.w_gpointer = &x->l_vec[j].l_p; > > > } > > > } > > > } > > > > > > /* set contents to a list */ > > > static void alist_list(t_alist *x, t_symbol *s, int argc, t_atom *argv) > > > { > > > alist_clear(x); > > > if (!(x->l_vec = (t_listelem *)getbytes(argc * sizeof(*x->l_vec)))) > > > { > > > x->l_n = 0; > > > error("list: out of memory"); > > > return; > > > } > > > x->l_n = argc; > > > x->l_npointer = 0; > > > alist_copyin(x, s, argc, argv, 0); > > > } > > > > > > /* set contents to an arbitrary non-list message */ > > > static void alist_anything(t_alist *x, t_symbol *s, int argc, t_atom > > > *argv) > > > { > > > int i; > > > alist_clear(x); > > > if (!(x->l_vec = (t_listelem *)getbytes((argc+1) * > > > sizeof(*x->l_vec)))) > > > { > > > x->l_n = 0; > > > error("list_alloc: out of memory"); > > > return; > > > } > > > x->l_n = argc+1; > > > x->l_npointer = 0; > > > SETSYMBOL(&x->l_vec[0].l_a, s); > > > for (i = 0; i < argc; i++) > > > { > > > x->l_vec[i+1].l_a = argv[i]; > > > if (x->l_vec[i+1].l_a.a_type == A_POINTER) > > > { > > > x->l_npointer++; > > > gpointer_copy(x->l_vec[i+1].l_a.a_w.w_gpointer, > > > &x->l_vec[i+1].l_p); > > > x->l_vec[i+1].l_a.a_w.w_gpointer = &x->l_vec[i+1].l_p; > > > } > > > } > > > } > > > > > > static void alist_toatoms(t_alist *x, t_atom *to, int onset, int count) > > > { > > > int i; > > > for (i = 0; i < count; i++) > > > to[i] = x->l_vec[onset + i].l_a; > > > } > > > > > > > > > static void alist_clone(t_alist *x, t_alist *y, int onset, int count) > > > { > > > int i; > > > y->l_pd = alist_class; > > > y->l_n = count; > > > y->l_npointer = 0; > > > if (!(y->l_vec = (t_listelem *)getbytes(y->l_n * sizeof(*y->l_vec)))) > > > { > > > y->l_n = 0; > > > error("list_alloc: out of memory"); > > > } > > > else for (i = 0; i < count; i++) > > > { > > > y->l_vec[i].l_a = x->l_vec[onset + i].l_a; > > > if (y->l_vec[i].l_a.a_type == A_POINTER) > > > { > > > gpointer_copy(y->l_vec[i].l_a.a_w.w_gpointer, > > > &y->l_vec[i].l_p); > > > y->l_vec[i].l_a.a_w.w_gpointer = &y->l_vec[i].l_p; > > > y->l_npointer++; > > > } > > > } > > > } > > > > > > static void alist_setup(void) > > > { > > > alist_class = class_new(gensym("list inlet"), > > > 0, 0, sizeof(t_alist), 0, 0); > > > class_addlist(alist_class, alist_list); > > > class_addanything(alist_class, alist_anything); > > > } > > > > > > /* ------------- list append --------------------- */ > > > > > > t_class *list_append_class; > > > > > > typedef struct _list_append > > > { > > > t_object x_obj; > > > t_alist x_alist; > > > } t_list_append; > > > > > > static void *list_append_new(t_symbol *s, int argc, t_atom *argv) > > > { > > > t_list_append *x = (t_list_append *)pd_new(list_append_class); > > > alist_init(&x->x_alist); > > > alist_list(&x->x_alist, 0, argc, argv); > > > outlet_new(&x->x_obj, &s_list); > > > inlet_new(&x->x_obj, &x->x_alist.l_pd, 0, 0); > > > return (x); > > > } > > > > > > static void list_append_list(t_list_append *x, t_symbol *s, > > > int argc, t_atom *argv) > > > { > > > t_atom *outv; > > > int n, outc = x->x_alist.l_n + argc; > > > ATOMS_ALLOCA(outv, outc); > > > atoms_copy(argc, argv, outv); > > > if (x->x_alist.l_npointer) > > > { > > > t_alist y; > > > alist_clone(&x->x_alist, &y, 0, x->x_alist.l_n); > > > alist_toatoms(&y, outv+argc, 0, x->x_alist.l_n); > > > outlet_list(x->x_obj.ob_outlet, &s_list, outc, outv); > > > alist_clear(&y); > > > } > > > else > > > { > > > alist_toatoms(&x->x_alist, outv+argc, 0, x->x_alist.l_n); > > > outlet_list(x->x_obj.ob_outlet, &s_list, outc, outv); > > > } > > > ATOMS_FREEA(outv, outc); > > > } > > > > > > static void list_append_anything(t_list_append *x, t_symbol *s, > > > int argc, t_atom *argv) > > > { > > > t_atom *outv; > > > int n, outc = x->x_alist.l_n + argc + 1; > > > ATOMS_ALLOCA(outv, outc); > > > SETSYMBOL(outv, s); > > > atoms_copy(argc, argv, outv + 1); > > > if (x->x_alist.l_npointer) > > > { > > > t_alist y; > > > alist_clone(&x->x_alist, &y, 0, x->x_alist.l_n); > > > alist_toatoms(&y, outv + 1 + argc, 0, x->x_alist.l_n); > > > outlet_list(x->x_obj.ob_outlet, &s_list, outc, outv); > > > alist_clear(&y); > > > } > > > else > > > { > > > alist_toatoms(&x->x_alist, outv + 1 + argc, 0, x->x_alist.l_n); > > > outlet_list(x->x_obj.ob_outlet, &s_list, outc, outv); > > > } > > > ATOMS_FREEA(outv, outc); > > > } > > > > > > static void list_append_append(t_list_append *x, t_symbol *s, > > > int argc, t_atom *argv) > > > { > > > if (!(x->x_alist.l_vec = (t_listelem *)resizebytes(x->x_alist.l_vec, > > > (x->x_alist.l_n) * sizeof(*x->x_alist.l_vec), > > > (x->x_alist.l_n + argc) * sizeof(*x->x_alist.l_vec)))) > > > { > > > x->x_alist.l_n = 0; > > > error("list: out of memory"); > > > return; > > > } > > > alist_copyin(&x->x_alist, s, argc, argv, x->x_alist.l_n); > > > x->x_alist.l_n += argc; > > > } > > > > > > static void list_append_prepend(t_list_append *x, t_symbol *s, > > > int argc, t_atom *argv) > > > { > > > if (!(x->x_alist.l_vec = (t_listelem *)resizebytes(x->x_alist.l_vec, > > > (x->x_alist.l_n) * sizeof(*x->x_alist.l_vec), > > > (x->x_alist.l_n + argc) * sizeof(*x->x_alist.l_vec)))) > > > { > > > x->x_alist.l_n = 0; > > > error("list: out of memory"); > > > return; > > > } > > > memmove(x->x_alist.l_vec + argc, x->x_alist.l_vec, > > > x->x_alist.l_n * sizeof(*x->x_alist.l_vec)); > > > alist_copyin(&x->x_alist, s, argc, argv, 0); > > > x->x_alist.l_n += argc; > > > } > > > > > > static void list_append_free(t_list_append *x) > > > { > > > alist_clear(&x->x_alist); > > > } > > > > > > static void list_append_setup(void) > > > { > > > list_append_class = class_new(gensym("list append"), > > > (t_newmethod)list_append_new, (t_method)list_append_free, > > > sizeof(t_list_append), 0, A_GIMME, 0); > > > class_addlist(list_append_class, list_append_list); > > > class_addanything(list_append_class, list_append_anything); > > > class_sethelpsymbol(list_append_class, &s_list); > > > } > > > > > > /* ------------- list prepend --------------------- */ > > > > > > t_class *list_prepend_class; > > > > > > typedef t_list_append t_list_prepend; > > > > > > static void *list_prepend_new(t_symbol *s, int argc, t_atom *argv) > > > { > > > t_list_prepend *x = (t_list_prepend *)pd_new(list_prepend_class); > > > alist_init(&x->x_alist); > > > alist_list(&x->x_alist, 0, argc, argv); > > > outlet_new(&x->x_obj, &s_list); > > > inlet_new(&x->x_obj, &x->x_alist.l_pd, 0, 0); > > > return (x); > > > } > > > > > > static void list_prepend_list(t_list_prepend *x, t_symbol *s, > > > int argc, t_atom *argv) > > > { > > > t_atom *outv; > > > int n, outc = x->x_alist.l_n + argc; > > > ATOMS_ALLOCA(outv, outc); > > > atoms_copy(argc, argv, outv + x->x_alist.l_n); > > > if (x->x_alist.l_npointer) > > > { > > > t_alist y; > > > alist_clone(&x->x_alist, &y, 0, x->x_alist.l_n); > > > alist_toatoms(&y, outv, 0, x->x_alist.l_n); > > > outlet_list(x->x_obj.ob_outlet, &s_list, outc, outv); > > > alist_clear(&y); > > > } > > > else > > > { > > > alist_toatoms(&x->x_alist, outv, 0, x->x_alist.l_n); > > > outlet_list(x->x_obj.ob_outlet, &s_list, outc, outv); > > > } > > > ATOMS_FREEA(outv, outc); > > > } > > > > > > static void list_prepend_anything(t_list_prepend *x, t_symbol *s, > > > int argc, t_atom *argv) > > > { > > > t_atom *outv; > > > int n, outc = x->x_alist.l_n + argc + 1; > > > ATOMS_ALLOCA(outv, outc); > > > SETSYMBOL(outv + x->x_alist.l_n, s); > > > atoms_copy(argc, argv, outv + x->x_alist.l_n + 1); > > > if (x->x_alist.l_npointer) > > > { > > > t_alist y; > > > alist_clone(&x->x_alist, &y, 0, x->x_alist.l_n); > > > alist_toatoms(&y, outv, 0, x->x_alist.l_n); > > > outlet_list(x->x_obj.ob_outlet, &s_list, outc, outv); > > > alist_clear(&y); > > > } > > > else > > > { > > > alist_toatoms(&x->x_alist, outv, 0, x->x_alist.l_n); > > > outlet_list(x->x_obj.ob_outlet, &s_list, outc, outv); > > > } > > > ATOMS_FREEA(outv, outc); > > > } > > > > > > static void list_prepend_free(t_list_prepend *x) > > > { > > > alist_clear(&x->x_alist); > > > } > > > > > > static void list_prepend_setup(void) > > > { > > > list_prepend_class = class_new(gensym("list prepend"), > > > (t_newmethod)list_prepend_new, (t_method)list_prepend_free, > > > sizeof(t_list_prepend), 0, A_GIMME, 0); > > > class_addlist(list_prepend_class, list_prepend_list); > > > class_addanything(list_prepend_class, list_prepend_anything); > > > class_sethelpsymbol(list_prepend_class, &s_list); > > > } > > > > > > /* ------------- list store --------------------- */ > > > > > > t_class *list_store_class; > > > > > > typedef struct _list_store > > > { > > > t_object x_obj; > > > t_alist x_alist; > > > t_outlet *x_out1; > > > t_outlet *x_out2; > > > } t_list_store; > > > > > > static void *list_store_new(t_symbol *s, int argc, t_atom *argv) > > > { > > > t_list_store *x = (t_list_store *)pd_new(list_store_class); > > > alist_init(&x->x_alist); > > > alist_list(&x->x_alist, 0, argc, argv); > > > x->x_out1 = outlet_new(&x->x_obj, &s_list); > > > x->x_out2 = outlet_new(&x->x_obj, &s_bang); > > > inlet_new(&x->x_obj, &x->x_alist.l_pd, 0, 0); > > > return (x); > > > } > > > > > > static void list_store_list(t_list_store *x, t_symbol *s, > > > int argc, t_atom *argv) > > > { > > > t_atom *outv; > > > int n, outc = x->x_alist.l_n + argc; > > > ATOMS_ALLOCA(outv, outc); > > > atoms_copy(argc, argv, outv); > > > if (x->x_alist.l_npointer) > > > { > > > t_alist y; > > > alist_clone(&x->x_alist, &y, 0, x->x_alist.l_n); > > > alist_toatoms(&y, outv+argc, 0, x->x_alist.l_n); > > > outlet_list(x->x_out1, &s_list, outc, outv); > > > alist_clear(&y); > > > } > > > else > > > { > > > alist_toatoms(&x->x_alist, outv+argc, 0, x->x_alist.l_n); > > > outlet_list(x->x_out1, &s_list, outc, outv); > > > } > > > ATOMS_FREEA(outv, outc); > > > } > > > > > > /* insert atoms before a given index */ > > > static void list_store_doinsert(t_list_store *x, int index, t_symbol *s, > > > int argc, t_atom *argv) > > > { > > > if (index < 0) index = 0; /* index = 0 -> prepend */ > > > if (index > x->x_alist.l_n) index = x->x_alist.l_n; /* index >= length > > > -> append */ > > > > > > if (!(x->x_alist.l_vec = (t_listelem *)resizebytes(x->x_alist.l_vec, > > > (x->x_alist.l_n) * sizeof(*x->x_alist.l_vec), > > > (x->x_alist.l_n + argc) * sizeof(*x->x_alist.l_vec)))) > > > { > > > x->x_alist.l_n = 0; > > > error("list: out of memory"); > > > return; > > > } > > > /* we don't need memmove for appending */ > > > if (index < x->x_alist.l_n){ > > > memmove(x->x_alist.l_vec + index + argc, x->x_alist.l_vec + > > > index, (x->x_alist.l_n - index) * sizeof(*x->x_alist.l_vec)); > > > } > > > alist_copyin(&x->x_alist, s, argc, argv, index); > > > x->x_alist.l_n += argc; > > > } > > > > > > static void list_store_insert(t_list_store *x, t_symbol *s, > > > int argc, t_atom *argv) > > > { > > > if (argc < 2) return; > > > > > > /* first atom is the index where to start inserting atoms. */ > > > int index = atom_getfloat(argv); > > > argc--; argv++; > > > /* insert remaining atoms */ > > > list_store_doinsert(x, index, s, argc, argv); > > > } > > > > > > static void list_store_append(t_list_store *x, t_symbol *s, > > > int argc, t_atom *argv) > > > { > > > list_store_doinsert(x, 1e+009, s, argc, argv); > > > } > > > > > > static void list_store_prepend(t_list_store *x, t_symbol *s, > > > int argc, t_atom *argv) > > > { > > > list_store_doinsert(x, 0, s, argc, argv); > > > } > > > > > > static void list_store_delete(t_list_store *x, float f1, float f2) > > > { > > > int index = f1; > > > int ndelete = f2; > > > > > > if (index < 0) index = 0; > > > if (index >= x->x_alist.l_n) return; /* out of range: nothing to delete > > > */ > > > > > > int maxlength = x->x_alist.l_n - index; > > > if (ndelete > maxlength) ndelete = maxlength; > > > > > > /* first unset pointers */ > > > if (x->x_alist.l_npointer) > > > { > > > t_listelem *vec = x->x_alist.l_vec; > > > for (int i = 0; i < ndelete; i++) > > > { > > > if (vec[index + i].l_a.a_type == A_POINTER) > > > { > > > gpointer_unset(vec[i].l_a.a_w.w_gpointer); > > > x->x_alist.l_npointer--; > > > post("remaining number of pointers: %d", > > > x->x_alist.l_npointer); > > > } > > > } > > > } > > > > > > /* then move atoms */ > > > memmove(x->x_alist.l_vec + index, x->x_alist.l_vec + index + ndelete, > > > (x->x_alist.l_n - index - ndelete) * sizeof(*x->x_alist.l_vec)); > > > > > > x->x_alist.l_vec = (t_listelem *)resizebytes(x->x_alist.l_vec, > > > (x->x_alist.l_n) * sizeof(*x->x_alist.l_vec), > > > (x->x_alist.l_n - ndelete) * sizeof(*x->x_alist.l_vec)); > > > > > > x->x_alist.l_n -= ndelete; > > > } > > > > > > static void list_store_set(t_list_store *x, t_symbol *s, > > > int argc, t_atom *argv) > > > { > > > if (argc < 2) return; > > > > > > /* first atom is the index where to start copying the atoms */ > > > int index = atom_getfloat(argv); > > > if (index < 0) index = 0; > > > if (index > x->x_alist.l_n - 1) index = x->x_alist.l_n - 1; > > > argc--; argv++; > > > > > > /* copy remaining atoms */ > > > int maxlength = x->x_alist.l_n - index; > > > /* for now we truncate. we could also append remaining atoms... */ > > > if (argc > maxlength) argc = maxlength; > > > > > > /* first unset pointers */ > > > if (x->x_alist.l_npointer) > > > { > > > t_listelem *vec = x->x_alist.l_vec; > > > for (int i = 0; i < argc; i++) > > > { > > > if (vec[index + i].l_a.a_type == A_POINTER) > > > { > > > gpointer_unset(vec[i+index].l_a.a_w.w_gpointer); > > > x->x_alist.l_npointer--; > > > } > > > } > > > } > > > /* then copy */ > > > alist_copyin(&x->x_alist, s, argc, argv, index); > > > } > > > > > > static void list_store_get(t_list_store *x, float f1, float f2) > > > { > > > t_atom *outv; > > > int onset = f1, outc = f2; > > > if (onset < 0 || outc < 0) > > > { > > > pd_error(x, "list_store_range: negative range (%d %d)", onset, > > > outc); > > > return; > > > } > > > if (onset + outc > x->x_alist.l_n) > > > { > > > outlet_bang(x->x_out2); > > > return; > > > } > > > ATOMS_ALLOCA(outv, outc); > > > if (x->x_alist.l_npointer) > > > { > > > t_alist y; > > > alist_clone(&x->x_alist, &y, onset, outc); > > > alist_toatoms(&y, outv, onset, outc); > > > outlet_list(x->x_out1, &s_list, outc, outv); > > > alist_clear(&y); > > > } > > > else > > > { > > > alist_toatoms(&x->x_alist, outv, onset, outc); > > > outlet_list(x->x_out1, &s_list, outc, outv); > > > } > > > ATOMS_FREEA(outv, outc); > > > } > > > > > > static void list_store_range(t_list_store *x, float f1, float f2) > > > { > > > list_store_get(x, f1, f2); > > > } > > > > > > static void list_store_free(t_list_store *x) > > > { > > > alist_clear(&x->x_alist); > > > } > > > > > > static void list_store_setup(void) > > > { > > > list_store_class = class_new(gensym("list store"), > > > (t_newmethod)list_store_new, (t_method)list_store_free, > > > sizeof(t_list_store), 0, A_GIMME, 0); > > > class_addlist(list_store_class, list_store_list); > > > class_addmethod(list_store_class, (t_method)list_store_set, > > > gensym("set"), A_GIMME, 0); > > > class_addmethod(list_store_class, (t_method)list_store_get, > > > gensym("get"), A_FLOAT, A_FLOAT, 0); > > > class_addmethod(list_store_class, (t_method)list_store_range, > > > gensym("range"), A_FLOAT, A_FLOAT, 0); /* alias for "get" */ > > > class_addmethod(list_store_class, (t_method)list_store_insert, > > > gensym("insert"), A_GIMME, 0); > > > class_addmethod(list_store_class, (t_method)list_store_append, > > > gensym("append"), A_GIMME, 0); > > > class_addmethod(list_store_class, (t_method)list_store_prepend, > > > gensym("prepend"), A_GIMME, 0); > > > class_addmethod(list_store_class, (t_method)list_store_delete, > > > gensym("delete"), A_FLOAT, A_FLOAT, 0); > > > > > > class_sethelpsymbol(list_store_class, &s_list); > > > } > > > > > > /* ------------- list split --------------------- */ > > > > > > t_class *list_split_class; > > > > > > typedef struct _list_split > > > { > > > t_object x_obj; > > > t_float x_f; > > > t_outlet *x_out1; > > > t_outlet *x_out2; > > > t_outlet *x_out3; > > > } t_list_split; > > > > > > static void *list_split_new(t_floatarg f) > > > { > > > t_list_split *x = (t_list_split *)pd_new(list_split_class); > > > x->x_out1 = outlet_new(&x->x_obj, &s_list); > > > x->x_out2 = outlet_new(&x->x_obj, &s_list); > > > x->x_out3 = outlet_new(&x->x_obj, &s_list); > > > floatinlet_new(&x->x_obj, &x->x_f); > > > x->x_f = f; > > > return (x); > > > } > > > > > > static void list_split_list(t_list_split *x, t_symbol *s, > > > int argc, t_atom *argv) > > > { > > > int n = x->x_f; > > > if (n < 0) > > > n = 0; > > > if (argc >= n) > > > { > > > outlet_list(x->x_out2, &s_list, argc-n, argv+n); > > > outlet_list(x->x_out1, &s_list, n, argv); > > > } > > > else outlet_list(x->x_out3, &s_list, argc, argv); > > > } > > > > > > static void list_split_anything(t_list_split *x, t_symbol *s, > > > int argc, t_atom *argv) > > > { > > > t_atom *outv; > > > ATOMS_ALLOCA(outv, argc+1); > > > SETSYMBOL(outv, s); > > > atoms_copy(argc, argv, outv + 1); > > > list_split_list(x, &s_list, argc+1, outv); > > > ATOMS_FREEA(outv, argc+1); > > > } > > > > > > static void list_split_setup(void) > > > { > > > list_split_class = class_new(gensym("list split"), > > > (t_newmethod)list_split_new, 0, > > > sizeof(t_list_split), 0, A_DEFFLOAT, 0); > > > class_addlist(list_split_class, list_split_list); > > > class_addanything(list_split_class, list_split_anything); > > > class_sethelpsymbol(list_split_class, &s_list); > > > } > > > > > > /* ------------- list trim --------------------- */ > > > > > > t_class *list_trim_class; > > > > > > typedef struct _list_trim > > > { > > > t_object x_obj; > > > } t_list_trim; > > > > > > static void *list_trim_new( void) > > > { > > > t_list_trim *x = (t_list_trim *)pd_new(list_trim_class); > > > outlet_new(&x->x_obj, &s_list); > > > return (x); > > > } > > > > > > static void list_trim_list(t_list_trim *x, t_symbol *s, > > > int argc, t_atom *argv) > > > { > > > if (argc < 1 || argv[0].a_type != A_SYMBOL) > > > outlet_list(x->x_obj.ob_outlet, &s_list, argc, argv); > > > else outlet_anything(x->x_obj.ob_outlet, argv[0].a_w.w_symbol, > > > argc-1, argv+1); > > > } > > > > > > static void list_trim_anything(t_list_trim *x, t_symbol *s, > > > int argc, t_atom *argv) > > > { > > > outlet_anything(x->x_obj.ob_outlet, s, argc, argv); > > > } > > > > > > static void list_trim_setup(void) > > > { > > > list_trim_class = class_new(gensym("list trim"), > > > (t_newmethod)list_trim_new, 0, > > > sizeof(t_list_trim), 0, 0); > > > class_addlist(list_trim_class, list_trim_list); > > > class_addanything(list_trim_class, list_trim_anything); > > > class_sethelpsymbol(list_trim_class, &s_list); > > > } > > > > > > /* ------------- list length --------------------- */ > > > > > > t_class *list_length_class; > > > > > > typedef struct _list_length > > > { > > > t_object x_obj; > > > } t_list_length; > > > > > > static void *list_length_new( void) > > > { > > > t_list_length *x = (t_list_length *)pd_new(list_length_class); > > > outlet_new(&x->x_obj, &s_float); > > > return (x); > > > } > > > > > > static void list_length_list(t_list_length *x, t_symbol *s, > > > int argc, t_atom *argv) > > > { > > > outlet_float(x->x_obj.ob_outlet, (t_float)argc); > > > } > > > > > > static void list_length_anything(t_list_length *x, t_symbol *s, > > > int argc, t_atom *argv) > > > { > > > outlet_float(x->x_obj.ob_outlet, (t_float)argc+1); > > > } > > > > > > static void list_length_setup(void) > > > { > > > list_length_class = class_new(gensym("list length"), > > > (t_newmethod)list_length_new, 0, > > > sizeof(t_list_length), 0, 0); > > > class_addlist(list_length_class, list_length_list); > > > class_addanything(list_length_class, list_length_anything); > > > class_sethelpsymbol(list_length_class, &s_list); > > > } > > > > > > /* ------------- list fromsymbol --------------------- */ > > > > > > t_class *list_fromsymbol_class; > > > > > > typedef struct _list_fromsymbol > > > { > > > t_object x_obj; > > > } t_list_fromsymbol; > > > > > > static void *list_fromsymbol_new( void) > > > { > > > t_list_fromsymbol *x = (t_list_fromsymbol > > > *)pd_new(list_fromsymbol_class); > > > outlet_new(&x->x_obj, &s_list); > > > return (x); > > > } > > > > > > static void list_fromsymbol_symbol(t_list_fromsymbol *x, t_symbol *s) > > > { > > > t_atom *outv; > > > int n, outc = strlen(s->s_name); > > > ATOMS_ALLOCA(outv, outc); > > > for (n = 0; n < outc; n++) > > > SETFLOAT(outv + n, (unsigned char)s->s_name[n]); > > > outlet_list(x->x_obj.ob_outlet, &s_list, outc, outv); > > > ATOMS_FREEA(outv, outc); > > > } > > > > > > static void list_fromsymbol_setup(void) > > > { > > > list_fromsymbol_class = class_new(gensym("list fromsymbol"), > > > (t_newmethod)list_fromsymbol_new, 0, sizeof(t_list_fromsymbol), > > > 0, 0); > > > class_addsymbol(list_fromsymbol_class, list_fromsymbol_symbol); > > > class_sethelpsymbol(list_fromsymbol_class, &s_list); > > > } > > > > > > /* ------------- list tosymbol --------------------- */ > > > > > > t_class *list_tosymbol_class; > > > > > > typedef struct _list_tosymbol > > > { > > > t_object x_obj; > > > } t_list_tosymbol; > > > > > > static void *list_tosymbol_new( void) > > > { > > > t_list_tosymbol *x = (t_list_tosymbol *)pd_new(list_tosymbol_class); > > > outlet_new(&x->x_obj, &s_symbol); > > > return (x); > > > } > > > > > > static void list_tosymbol_list(t_list_tosymbol *x, t_symbol *s, > > > int argc, t_atom *argv) > > > { > > > int i; > > > #if HAVE_ALLOCA > > > char *str = alloca(argc + 1); > > > #else > > > char *str = getbytes(argc + 1); > > > #endif > > > for (i = 0; i < argc; i++) > > > str[i] = (char)atom_getfloatarg(i, argc, argv); > > > str[argc] = 0; > > > outlet_symbol(x->x_obj.ob_outlet, gensym(str)); > > > #if HAVE_ALLOCA > > > #else > > > freebytes(str, argc+1); > > > #endif > > > } > > > > > > static void list_tosymbol_setup(void) > > > { > > > list_tosymbol_class = class_new(gensym("list tosymbol"), > > > (t_newmethod)list_tosymbol_new, 0, sizeof(t_list_tosymbol), 0, 0); > > > class_addlist(list_tosymbol_class, list_tosymbol_list); > > > class_sethelpsymbol(list_tosymbol_class, &s_list); > > > } > > > > > > /* ------------- list ------------------- */ > > > > > > static void *list_new(t_pd *dummy, t_symbol *s, int argc, t_atom *argv) > > > { > > > if (!argc || argv[0].a_type != A_SYMBOL) > > > pd_this->pd_newest = list_append_new(s, argc, argv); > > > else > > > { > > > t_symbol *s2 = argv[0].a_w.w_symbol; > > > if (s2 == gensym("append")) > > > pd_this->pd_newest = list_append_new(s, argc-1, argv+1); > > > else if (s2 == gensym("prepend")) > > > pd_this->pd_newest = list_prepend_new(s, argc-1, argv+1); > > > else if (s2 == gensym("split")) > > > pd_this->pd_newest = > > > list_split_new(atom_getfloatarg(1, argc, argv)); > > > else if (s2 == gensym("trim")) > > > pd_this->pd_newest = list_trim_new(); > > > else if (s2 == gensym("length")) > > > pd_this->pd_newest = list_length_new(); > > > else if (s2 == gensym("fromsymbol")) > > > pd_this->pd_newest = list_fromsymbol_new(); > > > else if (s2 == gensym("tosymbol")) > > > pd_this->pd_newest = list_tosymbol_new(); > > > else if (s2 == gensym("store")) > > > pd_this->pd_newest = list_store_new(s, argc-1, argv+1); > > > else > > > { > > > error("list %s: unknown function", s2->s_name); > > > pd_this->pd_newest = 0; > > > } > > > } > > > return (pd_this->pd_newest); > > > } > > > > > > void x_list_setup(void) > > > { > > > alist_setup(); > > > list_append_setup(); > > > list_prepend_setup(); > > > list_store_setup(); > > > list_split_setup(); > > > list_trim_setup(); > > > list_length_setup(); > > > list_fromsymbol_setup(); > > > list_tosymbol_setup(); > > > class_addcreator((t_newmethod)list_new, &s_list, A_GIMME, 0); > > > } > > > > > _______________________________________________ > > > Pd-dev mailing list > > > Pd-dev@lists.iem.at > > > https://lists.puredata.info/listinfo/pd-dev > > > > > > _______________________________________________ > Pd-dev mailing list > Pd-dev@lists.iem.at > https://lists.puredata.info/listinfo/pd-dev > _______________________________________________ Pd-dev mailing list Pd-dev@lists.iem.at https://lists.puredata.info/listinfo/pd-dev