From c2b9f6a27dff2a3a2d697ea47aaac94dea2f92e9 Mon Sep 17 00:00:00 2001 From: Jonathan Wilkes <jon.w.wilkes@gmail.com> Date: Fri, 3 Jun 2016 21:59:34 -0400 Subject: [PATCH] port 9dd405d0a4dd3c3007c75f5bd716eaf0bd28d19b from Pd-l2ork: added list fromsymbol and tosymbol --- pd/src/x_list.c | 109 +++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 104 insertions(+), 5 deletions(-) diff --git a/pd/src/x_list.c b/pd/src/x_list.c index 83ce2dbb8..d43378a21 100644 --- a/pd/src/x_list.c +++ b/pd/src/x_list.c @@ -6,7 +6,7 @@ #include "m_pd.h" #include "s_stuff.h" -/* #include <string.h> */ +#include <string.h> #ifdef HAVE_MALLOC_H #include <malloc.h> @@ -18,15 +18,20 @@ extern t_pd *newest; +#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 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 list cat - build a list by accumulating elements Need to think more about: @@ -44,6 +49,16 @@ Probably don't need: /* -------------- utility functions: storage, copying -------------- */ +#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 + void atoms_copy(int argc, t_atom *from, t_atom *to) { int i; @@ -591,6 +606,84 @@ static void list_length_setup(void) 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) @@ -606,12 +699,16 @@ static void *list_new(t_pd *dummy, t_symbol *s, int argc, t_atom *argv) newest = list_cat_new(); else if (s2 == gensym("prepend")) newest = list_prepend_new(s, argc-1, argv+1); - else if (s2 == gensym("split")) + else if (s2 == gensym("split")) newest = list_split_new(atom_getfloatarg(1, argc, argv)); - else if (s2 == gensym("trim")) + else if (s2 == gensym("trim")) newest = list_trim_new(); - else if (s2 == gensym("length")) + else if (s2 == gensym("length")) newest = list_length_new(); + else if (s2 == gensym("fromsymbol")) + newest = list_fromsymbol_new(); + else if (s2 == gensym("tosymbol")) + newest = list_tosymbol_new(); else { error("list %s: unknown function", s2->s_name); @@ -630,5 +727,7 @@ void x_list_setup(void) 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); } -- GitLab