/* * symbol2list: convert a symbol into a list (with given delimiters) * * (c) 1999-2011 IOhannes m zmölnig, forum::für::umläute, institute of electronic music and acoustics (iem) * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . */ #include "zexy.h" #include #include /* ------------------------- symbol2list ------------------------------- */ static t_class *symbol2list_class; typedef struct _symbol2list { t_object x_obj; t_symbol *s, *delimiter; t_atom *argv; int argc, argnum; /* "argnum" is the number of reserved atoms (might be >argc) */ } t_symbol2list; static void symbol2list_delimiter(t_symbol2list *x, t_symbol *s){ x->delimiter = s; } STATIC_INLINE void string2atom(t_atom *ap, char* cp, int clen){ char *buffer=getbytes(sizeof(char)*(clen+1)); char *endptr[1]; t_float ftest; strncpy(buffer, cp, clen); buffer[clen]=0; ftest=strtod(buffer, endptr); /* what should we do with the special cases of hexadecimal values, "INF" and "NAN" ??? * strtod() parses them to numeric values: * symbol "hallo 0x12" will become "list hallo 18" * do we want this ?? */ if (buffer+clen!=*endptr){ /* strtof() failed, we have a symbol */ SETSYMBOL(ap, gensym(buffer)); } else { /* it is a number. */ SETFLOAT(ap,ftest); } freebytes(buffer, sizeof(char)*(clen+1)); } static void symbol2list_process(t_symbol2list *x) { char *cc; char *deli; int dell; char *cp, *d; int i=1; if (x->s==NULL){ x->argc=0; return; } cc=x->s->s_name; cp=cc; if (x->delimiter==NULL || x->delimiter==gensym("")){ i=strlen(cc); if(x->argnumargv, x->argnum*sizeof(t_atom)); x->argnum=i+10; x->argv=getbytes(x->argnum*sizeof(t_atom)); } x->argc=i; while(i--)string2atom(x->argv+i, cc+i, 1); return; } deli=x->delimiter->s_name; dell=strlen(deli); /* get the number of tokens */ while((d=strstr(cp, deli))){ if (d!=NULL && d!=cp){ i++; } cp=d+dell; } /* resize the list-buffer if necessary */ if(x->argnumargv, x->argnum*sizeof(t_atom)); x->argnum=i+10; x->argv=getbytes(x->argnum*sizeof(t_atom)); } x->argc=i; /* parse the tokens into the list-buffer */ i=0; /* find the first token */ cp=cc; while(cp==(d=strstr(cp,deli))){cp+=dell;} while((d=strstr(cp, deli))){ if(d!=cp){ string2atom(x->argv+i, cp, d-cp); i++; } cp=d+dell; } if(cp)string2atom(x->argv+i, cp, strlen(cp)); } static void symbol2list_bang(t_symbol2list *x){ if(!(x->s) || x->s==gensym("")){ outlet_bang(x->x_obj.ob_outlet); return; } symbol2list_process(x); if(x->argc)outlet_list(x->x_obj.ob_outlet, 0, x->argc, x->argv); } static void symbol2list_symbol(t_symbol2list *x, t_symbol *s){ x->s = s; symbol2list_bang(x); } static void *symbol2list_new(t_symbol* UNUSED(s), int argc, t_atom *argv) { t_symbol2list *x = (t_symbol2list *)pd_new(symbol2list_class); outlet_new(&x->x_obj, 0); inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("symbol"), gensym("")); x->argc=0; x->argnum=16; x->argv=getbytes(x->argnum*sizeof(t_atom)); symbol2list_delimiter(x, (argc)?atom_getsymbol(argv):gensym(" ")); return (x); } static void symbol2list_free(t_symbol2list *x) {} static void symbol2list_help(t_symbol2list*x) { post("\n"HEARTSYMBOL" symbol2list\t:: split a symbol into a list of atoms"); } void symbol2list_setup(void) { symbol2list_class = class_new(gensym("symbol2list"), (t_newmethod)symbol2list_new, (t_method)symbol2list_free, sizeof(t_symbol2list), 0, A_GIMME, 0); class_addcreator((t_newmethod)symbol2list_new, gensym("s2l"), A_GIMME, 0); class_addsymbol (symbol2list_class, symbol2list_symbol); class_addbang (symbol2list_class, symbol2list_bang); class_addmethod (symbol2list_class, (t_method)symbol2list_delimiter, gensym(""), A_SYMBOL, 0); class_addmethod(symbol2list_class, (t_method)symbol2list_help, gensym("help"), A_NULL); zexy_register("symbol2list"); } void s2l_setup(void) { symbol2list_setup(); }