From 682acdb411514688872c8126d726a6a45ff8ef6e Mon Sep 17 00:00:00 2001 From: Thomas O Fredericks Date: Tue, 27 Oct 2009 14:45:38 +0000 Subject: Added an argument parser svn path=/trunk/externals/tof/; revision=12686 --- help/argument-help.pd | 16 +++-- help/arguments-help.pd | 38 +++++++++++ help/test-arguments-all.pd | 9 +++ help/test-arguments-comma.pd | 23 +++++++ help/test-arguments-token.pd | 15 +++++ src/arguments.c | 152 +++++++++++++++++++++++++++++++++++++++++++ src/param.c | 59 ++++++++++++----- src/paramGui.h | 99 ++++++++++------------------ 8 files changed, 326 insertions(+), 85 deletions(-) create mode 100644 help/arguments-help.pd create mode 100644 help/test-arguments-all.pd create mode 100644 help/test-arguments-comma.pd create mode 100644 help/test-arguments-token.pd create mode 100644 src/arguments.c diff --git a/help/argument-help.pd b/help/argument-help.pd index 7c8ac56..a6fbd47 100644 --- a/help/argument-help.pd +++ b/help/argument-help.pd @@ -1,4 +1,4 @@ -#N canvas 53 62 922 529 10; +#N canvas 59 319 922 529 10; #X obj 496 461 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1 -1; #X obj -11 19 cnv 15 400 100 empty empty empty 20 12 0 14 -249661 -66577 @@ -19,7 +19,7 @@ #X obj 419 244 tof/argument 1 32; #X obj 422 325 tof/argument; #X obj 496 485 ./argument-abs a b; -#X text 9 132 [argument n default]; +#X text 5 176 [argument n default]; #X text -4 17 description: Outputs the patch's creation arguments individually. ; #X text 516 147 This help patch is a file and therefore has no creation @@ -34,17 +34,19 @@ of the printed output.; #X text 534 237 As stated before \, this help patch is a file and has no creation arguments. But the [argument] to the left has a default value and will output it.; -#X text 10 155 argument 1: patch's creation argument to output.; -#X text 9 172 argument 2: default value to output if the patch's creation +#X text 6 199 argument 1: patch's creation argument to output.; +#X text 5 216 argument 2: default value to output if the patch's creation argument is not set or if the wrong type.; -#X text 8 209 inlet 1 bang: outputs the n-th patch creation argument +#X text 4 253 inlet 1 bang: outputs the n-th patch creation argument or the default value if there is no n-th creation argument.; -#X text 9 245 outlet 1 anything: outputs the n-th patch creation argument +#X text 5 289 outlet 1 anything: outputs the n-th patch creation argument or the default value if there is no n-th creation argument.; -#X text 5 287 If the patch's n-th creation argument is not of the same +#X text 1 331 If the patch's n-th creation argument is not of the same type as the default value \, the default value will be outputed instead. ; #X text -4 46 tags: initialization patch; +#X text 1 126 see also:; +#X obj 73 129 tof/arguments; #X connect 0 0 14 0; #X connect 4 0 11 0; #X connect 5 0 12 0; diff --git a/help/arguments-help.pd b/help/arguments-help.pd new file mode 100644 index 0000000..26d4a28 --- /dev/null +++ b/help/arguments-help.pd @@ -0,0 +1,38 @@ +#N canvas 56 497 880 406 10; +#X obj 506 84 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1 +-1; +#X obj 506 333 ./test-arguments-all a bear 3 34; +#X obj 507 307 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 +-1 -1; +#X obj 508 181 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 +-1 -1; +#X obj 508 206 ./test-arguments-token @a 54 @c 764; +#X obj 506 104 ./test-arguments-comma ready \, 1 2 3 \, go speedracer +; +#X obj -1 29 cnv 15 400 100 empty empty empty 20 12 0 14 -249661 -66577 +0; +#X text 7 78 author: mrtoftrash@gmail.com; +#X text 6 56 tags: initialization patch; +#X text 6 27 description: Outputs and parses the patch's creation arguments. +; +#X text 5 98 version: 2009-10-27 (initial release); +#X text 5 139 see also:; +#X obj 77 142 tof/argument; +#X text 15 180 [arguments mode]; +#X text 15 209 argument 1 symbol: the parsing mode. If it is "comma" +or " \, " the mode is set to COMMA. If it is another symbol \, the +first character of the symbol is used as a TOKEN. If no argument is +set \, the default mode is ALL.; +#X text 17 284 inlet 1 bang: outputs parsed patch creation arguments. +; +#X text 18 308 outlet 1 variable: the parsed patch arguments.; +#X text 611 32 COMMA MODE; +#X obj 546 57 tof/arguments comma; +#X obj 681 57 tof/arguments \,; +#X text 613 265 ALL MODE; +#X text 608 132 TOKEN MODE; +#X obj 593 158 tof/arguments @; +#X obj 596 290 tof/arguments; +#X connect 0 0 5 0; +#X connect 2 0 1 0; +#X connect 3 0 4 0; diff --git a/help/test-arguments-all.pd b/help/test-arguments-all.pd new file mode 100644 index 0000000..6f4c874 --- /dev/null +++ b/help/test-arguments-all.pd @@ -0,0 +1,9 @@ +#N canvas 402 618 450 300 10; +#X obj 141 46 inlet; +#X obj 141 163 print; +#X obj 143 110 tof/arguments; +#X obj 143 76 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1 +-1; +#X connect 0 0 3 0; +#X connect 2 0 1 0; +#X connect 3 0 2 0; diff --git a/help/test-arguments-comma.pd b/help/test-arguments-comma.pd new file mode 100644 index 0000000..71afc78 --- /dev/null +++ b/help/test-arguments-comma.pd @@ -0,0 +1,23 @@ +#N canvas 402 618 450 300 10; +#X obj 140 54 inlet; +#X obj 143 110 tof/arguments comma; +#X obj 140 83 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1 +-1; +#X symbolatom 41 232 10 0 0 0 - - -; +#X obj 260 257 print; +#X obj 41 210 symbol; +#X obj 33 165 route go list; +#X obj 118 199 unpack f f f; +#X floatatom 118 231 5 0 0 0 - - -; +#X floatatom 159 231 5 0 0 0 - - -; +#X floatatom 203 232 5 0 0 0 - - -; +#X connect 0 0 2 0; +#X connect 1 0 4 0; +#X connect 1 0 6 0; +#X connect 2 0 1 0; +#X connect 5 0 3 0; +#X connect 6 0 5 0; +#X connect 6 1 7 0; +#X connect 7 0 8 0; +#X connect 7 1 9 0; +#X connect 7 2 10 0; diff --git a/help/test-arguments-token.pd b/help/test-arguments-token.pd new file mode 100644 index 0000000..89795b1 --- /dev/null +++ b/help/test-arguments-token.pd @@ -0,0 +1,15 @@ +#N canvas 402 618 450 300 10; +#X obj 141 46 inlet; +#X obj 144 108 tof/arguments @; +#X obj 144 157 route @a @c; +#X floatatom 139 194 5 0 0 0 - - -; +#X floatatom 186 193 5 0 0 0 - - -; +#X obj 142 72 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1 +-1; +#X obj 268 175 print; +#X connect 0 0 5 0; +#X connect 1 0 2 0; +#X connect 1 0 6 0; +#X connect 2 0 3 0; +#X connect 2 1 4 0; +#X connect 5 0 1 0; diff --git a/src/arguments.c b/src/arguments.c new file mode 100644 index 0000000..c5ba961 --- /dev/null +++ b/src/arguments.c @@ -0,0 +1,152 @@ + + + #include "m_pd.h" + +#define IS_A_SYMBOL(atom,index) ((atom+index)->a_type == A_SYMBOL) +#define IS_A_FLOAT(atom,index) ((atom+index)->a_type == A_FLOAT) + +#define TOKEN 0 +#define COMMA 1 +#define ALL 2 + +static t_class *arguments_class; + + +typedef struct _arguments +{ + t_object x_obj; + t_outlet* outlet; + t_canvas* canvas; + t_symbol* s_comma; + int mode; + char token; + int size; + int ac; + t_atom* av; +} t_arguments; + + +// Prepends the proper selector +static void arguments_output(t_outlet* o, int argc, t_atom* argv) { + + if (!argc) outlet_bang(o); + else if (IS_A_SYMBOL(argv,0)) outlet_anything(o,atom_getsymbol(argv),argc-1,argv+1); + else if (IS_A_FLOAT(argv,0) && argc==1) outlet_float(o,atom_getfloat(argv)); + else outlet_anything(o,&s_list,argc,argv); +} + + +static int next_token(char tag, int ac, t_atom *av, int* ac_a, t_atom ** av_a, int* iter) { + int i; + + if ( ac == 0 || *iter >= ac) { + *ac_a = 0; + *av_a = NULL; + return 0; + } + + for ( i= *iter + 1; i < ac; i++ ) { + if ( (av+i)->a_type == A_SYMBOL + && (atom_getsymbol(av+i))->s_name[0] == tag) break; + } + *ac_a = i - *iter; + *av_a = av + *iter; + *iter = i; + + return (*ac_a); +} + +// Dump arguments +static void arguments_bang(t_arguments *x) { + + + + + if ( x->mode == TOKEN ) { + int ac_a; + t_atom* av_a; + t_symbol* selector_a; + int iter = 0 ; + while ( next_token(x->token, x->ac, x->av, &ac_a, &av_a,&iter)) { + arguments_output(x->outlet,ac_a,av_a); + } + } else if (x->mode == COMMA) { + // we are trusting the system that the commas are split from the + // neighboring floats and symbols + int ac = x->ac; + t_atom* av = x->av; + t_symbol* selector; + + int i =0; + int j; + for (j=0; js_comma ) ) { + if ( (j != i) ) arguments_output(x->outlet, j - i, av+i); + + i = j+1; + } + } + // Output any leftovers + if ( j != i) arguments_output(x->outlet, ac-i, av+i); + } else { //x->mode = ALL + arguments_output(x->outlet, x->ac, x->av); + } +} + + +static void arguments_free(t_arguments *x) +{ + freebytes(x->av,x->ac*sizeof(*(x->av))); +} + +static void copy_atoms(t_atom *src, t_atom *dst, int n) +{ + while(n--) + *dst++ = *src++; +} + + + +static void *arguments_new(t_symbol *selector, int argc, t_atom* argv) { + t_arguments *x = (t_arguments *)pd_new(arguments_class); + + x->s_comma = gensym(","); + + if ( argc && IS_A_SYMBOL(argv,0) ) { + t_symbol* s = atom_getsymbol(argv); + if ( s == gensym("comma") || s == x->s_comma ) { + x->mode = COMMA; + post("COMMA"); + } else { + x->mode = TOKEN; + x->token = s->s_name[0]; + post("TOKEN: %c",x->token); + } + } else { + post("ALL"); + x->mode = ALL; + } + + + int ac; + t_atom* av; + canvas_getargs(&ac, &av); + + x->ac = ac; + x->av = getbytes(x->ac * sizeof(*(x->av))); + copy_atoms(av,x->av,x->ac); + + x->outlet = outlet_new(&x->x_obj, &s_anything); + + return (x); +} + +void arguments_setup(void) { + arguments_class = class_new(gensym("arguments"), + (t_newmethod)arguments_new, (t_method)arguments_free, + sizeof(t_arguments), 0, A_GIMME, 0); + + class_addbang(arguments_class, arguments_bang); + + +} diff --git a/src/param.c b/src/param.c index 9464a40..a0779f2 100644 --- a/src/param.c +++ b/src/param.c @@ -19,17 +19,37 @@ * MA 02110-1301, USA. */ -// Post a lot of debug messages +// Post a lot of debug messages. //#define PARAMDEBUG -// Adds the root's $0 to the start of the paths +// Adds the root's $0 to the start of the paths. //#define LOCAL // Uses the symbol's s_thing to target the proper param -// This is faster but can potentially target two params +// Instead of searching through paramroots for a match. +// This is faster but can potentially target two params. #define USEBINDINGS #include "param.h" + +// Global symbols +static t_symbol* s_vis; +static t_symbol* s_empty; +static t_symbol* s_clear; +static t_symbol* s_set; +static t_symbol* s_obj; +static t_symbol* s_nbx; +static t_symbol* s_bng; +static t_symbol* s_slider; +static t_symbol* s_hsl; +static t_symbol* s_knob; +static t_symbol* s_tgl; +static t_symbol* s_symbolatom; +static t_symbol* s_sym; +static t_symbol* s_text; +static t_symbol* s_cnv; + + #include "paramCustom.h" #include "paramDump.h" #include "paramFile.h" @@ -37,6 +57,7 @@ #include "paramRoute.h" #include "paramGui.h" +// For loadbang extern int sys_noloadbang; static t_class *param_class; @@ -349,18 +370,7 @@ static void* param_new(t_symbol *s, int argc, t_atom *argv) { else post("Param is missing an argument. Possible values: custom, dump, file, path, route, gui or a /name."); } - /* - if ( x == NULL) { - //post(" custom"); - //dump file id route gui or a /\"name\" - //post("- dump"); - //post("- file"); - //post("- id"); - //post("- route"); - //post("- gui"); - //post("- or a /name."); - } - */ + return (x); } @@ -402,5 +412,24 @@ void param_setup(void) class_addcreator((t_newmethod)param_new, gensym("param"), A_GIMME, 0); class_addcreator((t_newmethod)param_new, gensym("tof/param"), A_GIMME, 0); + // GENERATE THE SYMBOLS + + s_vis = gensym("vis"); + s_empty = gensym("empty"); + s_clear = gensym("clear"); + s_set = gensym("set"); + s_obj = gensym("obj"); + s_nbx = gensym("nbx"); + s_bng = gensym("bng"); + s_slider = gensym("slider"); + s_hsl=gensym("hsl"); + s_knob = gensym("knob"); + s_tgl = gensym("tgl"); + s_symbolatom = gensym("symbolatom"); + s_sym = gensym("sym"); + s_text = gensym("text"); + s_cnv = gensym("cnv"); + + } diff --git a/src/paramGui.h b/src/paramGui.h index 8071377..c8d947a 100644 --- a/src/paramGui.h +++ b/src/paramGui.h @@ -16,22 +16,7 @@ typedef struct _paramGui t_symbol* path; int path_l; int build; - t_symbol* s_vis; - t_symbol* s_empty; - t_symbol* s_clear; - t_symbol* s_set; - t_symbol* root; - t_symbol* s_obj; - t_symbol* s_nbx; - t_symbol* s_bng; - t_symbol* s_slider; - t_symbol* s_hsl; - t_symbol* s_knob; - t_symbol* s_tgl; - t_symbol* s_symbolatom; - t_symbol* s_sym; - t_symbol* s_text; - t_symbol* s_cnv; + t_symbol* root; t_symbol* receive; int waiting; @@ -45,7 +30,7 @@ typedef struct _paramGui static void paramGui_buildCanvas(t_paramGui* x,int x_position,int y_position) { // Clear the canvas - pd_typedmess((t_pd*)x->childcanvas,x->s_clear,0,NULL); + pd_typedmess((t_pd*)x->childcanvas,s_clear,0,NULL); int pos_x = 0; int pos_y = 0; @@ -53,15 +38,15 @@ static void paramGui_buildCanvas(t_paramGui* x,int x_position,int y_position) { t_atom atoms[22]; // This should be the maximum number of atoms // PINK HEADER - SETSYMBOL(&atoms[0],x->s_obj); + SETSYMBOL(&atoms[0],s_obj); SETFLOAT(&atoms[1],pos_x); SETFLOAT(&atoms[2],pos_y); - SETSYMBOL(&atoms[3],x->s_cnv); + SETSYMBOL(&atoms[3],s_cnv); SETFLOAT(&atoms[4],15); SETFLOAT(&atoms[5],200); SETFLOAT(&atoms[6],20); - SETSYMBOL(&atoms[7],x->s_empty); - SETSYMBOL(&atoms[8],x->s_empty); + SETSYMBOL(&atoms[7],s_empty); + SETSYMBOL(&atoms[8],s_empty); SETSYMBOL(&atoms[9],x->path); SETFLOAT(&atoms[10],2); SETFLOAT(&atoms[11],12); @@ -73,7 +58,7 @@ static void paramGui_buildCanvas(t_paramGui* x,int x_position,int y_position) { pd_forwardmess((t_pd*)x->childcanvas, 17, atoms); pos_y = pos_y + 23; - t_param* p = get_param_list(x->root); + int ac; t_atom* av; t_symbol* type; @@ -91,14 +76,16 @@ static void paramGui_buildCanvas(t_paramGui* x,int x_position,int y_position) { t_atom* av_got; t_symbol* s_got; + + t_param* p = get_param_list(x->root); - - while (p) { + while (p) { + gui_built = 1; if (p->GUI && (strncmp(p->path->s_name,x->path->s_name,x->path_l)==0)) { p->GUI(p->x,&ac,&av,&send,&receive); - if ( send == NULL ) send = x->s_empty; - if ( receive == NULL ) receive = x->s_empty; + if ( send == NULL ) send = s_empty; + if ( receive == NULL ) receive = s_empty; /* // This code alows the positioning of the guis, but creates @@ -129,11 +116,11 @@ static void paramGui_buildCanvas(t_paramGui* x,int x_position,int y_position) { type = atom_getsymbol(av); - if ( type == x->s_nbx ) { - SETSYMBOL(&atoms[0],x->s_obj); + if ( type == s_nbx ) { + SETSYMBOL(&atoms[0],s_obj); SETFLOAT(&atoms[1],pos_x); SETFLOAT(&atoms[2],pos_y); - SETSYMBOL(&atoms[3],x->s_nbx); + SETSYMBOL(&atoms[3],s_nbx); SETFLOAT(&atoms[4],5); SETFLOAT(&atoms[5],14); SETFLOAT(&atoms[6],-1.0e+37); @@ -155,11 +142,11 @@ static void paramGui_buildCanvas(t_paramGui* x,int x_position,int y_position) { pd_forwardmess((t_pd*)x->childcanvas, 22, atoms); pos_y = pos_y + GUI_Y_STEP; - } else if (type == x->s_bng) { - SETSYMBOL(&atoms[0],x->s_obj); + } else if (type == s_bng) { + SETSYMBOL(&atoms[0],s_obj); SETFLOAT(&atoms[1],pos_x); SETFLOAT(&atoms[2],pos_y); - SETSYMBOL(&atoms[3],x->s_bng); + SETSYMBOL(&atoms[3],s_bng); SETFLOAT(&atoms[4],15); SETFLOAT(&atoms[5],250); SETFLOAT(&atoms[6],50); @@ -176,11 +163,11 @@ static void paramGui_buildCanvas(t_paramGui* x,int x_position,int y_position) { SETFLOAT(&atoms[17],-1); pd_forwardmess((t_pd*)x->childcanvas, 18, atoms); pos_y = pos_y + GUI_Y_STEP; - } else if ( (type == x->s_slider) || (type == x->s_knob) || (type == x->s_hsl) ) { - SETSYMBOL(&atoms[0],x->s_obj); + } else if ( (type == s_slider) || (type == s_knob) || (type == s_hsl) ) { + SETSYMBOL(&atoms[0],s_obj); SETFLOAT(&atoms[1],pos_x); SETFLOAT(&atoms[2],pos_y); - SETSYMBOL(&atoms[3],x->s_hsl); + SETSYMBOL(&atoms[3],s_hsl); SETFLOAT(&atoms[4],100); SETFLOAT(&atoms[5],15); if (ac > 1 && IS_A_FLOAT(av,1) ) { @@ -210,11 +197,11 @@ static void paramGui_buildCanvas(t_paramGui* x,int x_position,int y_position) { pd_forwardmess((t_pd*)x->childcanvas, 22, atoms); pos_y = pos_y + GUI_Y_STEP; - } else if (type == x->s_tgl) { - SETSYMBOL(&atoms[0],x->s_obj); + } else if (type == s_tgl) { + SETSYMBOL(&atoms[0],s_obj); SETFLOAT(&atoms[1],pos_x); SETFLOAT(&atoms[2],pos_y); - SETSYMBOL(&atoms[3],x->s_tgl); + SETSYMBOL(&atoms[3],s_tgl); SETFLOAT(&atoms[4],15); SETFLOAT(&atoms[5],0); SETSYMBOL(&atoms[6],send); @@ -233,8 +220,8 @@ static void paramGui_buildCanvas(t_paramGui* x,int x_position,int y_position) { pos_y = pos_y + GUI_Y_STEP; - } else if ( type == x->s_symbolatom || type == x->s_sym) { - SETSYMBOL(&atoms[0],x->s_symbolatom); + } else if ( type == s_symbolatom || type == s_sym) { + SETSYMBOL(&atoms[0],s_symbolatom); SETFLOAT(&atoms[1],pos_x); SETFLOAT(&atoms[2],pos_y); SETFLOAT(&atoms[3],17); @@ -247,7 +234,7 @@ static void paramGui_buildCanvas(t_paramGui* x,int x_position,int y_position) { pd_forwardmess((t_pd*)x->childcanvas, 10,atoms); pos_y = pos_y + GUI_Y_STEP; } else { - SETSYMBOL(&atoms[0],x->s_text); + SETSYMBOL(&atoms[0],s_text); SETFLOAT(&atoms[1],pos_x); SETFLOAT(&atoms[2],pos_y); SETSYMBOL(&atoms[3],shortpath); @@ -256,16 +243,16 @@ static void paramGui_buildCanvas(t_paramGui* x,int x_position,int y_position) { gui_built = 0; } - if ((gui_built) && (receive != x->s_empty) && (p->get)) { + if ((gui_built) && (receive != s_empty) && (p->get)) { p->get(p->x,&s_got,&ac_got,&av_got); - tof_send_anything_prepend(receive,s_got,ac_got,av_got,x->s_set); + tof_send_anything_prepend(receive,s_got,ac_got,av_got,s_set); } } } p = p->next; - + } - + // Try to resize the canvas x->childcanvas->gl_screenx1 = x_position; x->childcanvas->gl_screeny1 = y_position; @@ -281,7 +268,7 @@ static void paramGui_buildCanvas(t_paramGui* x,int x_position,int y_position) { // Show canvas t_atom a; SETFLOAT(&a,1); - pd_typedmess((t_pd*)x->childcanvas,x->s_vis,1,&a); + pd_typedmess((t_pd*)x->childcanvas,s_vis,1,&a); } @@ -312,7 +299,7 @@ static void paramGui_bang(t_paramGui *x) { // Show canvas t_atom a; SETFLOAT(&a,1); - pd_typedmess((t_pd*)x->childcanvas,x->s_vis,1,&a); + pd_typedmess((t_pd*)x->childcanvas,s_vis,1,&a); } } else { @@ -358,24 +345,10 @@ static void *paramGui_new(t_symbol *s, int ac, t_atom *av) { x->build = 1; - x->s_vis = gensym("vis"); - x->s_empty = gensym("empty"); - x->s_clear = gensym("clear"); - x->s_set = gensym("set"); - x->s_obj = gensym("obj"); - x->s_nbx = gensym("nbx"); - x->s_bng = gensym("bng"); - x->s_slider = gensym("slider"); - x->s_hsl=gensym("hsl"); - x->s_knob = gensym("knob"); - x->s_tgl = gensym("tgl"); - x->s_symbolatom = gensym("symbolatom"); - x->s_sym = gensym("sym"); - x->s_text = gensym("text"); - x->s_cnv = gensym("cnv"); + char buf[MAXPDSTRING]; - sprintf(buf, "#%lx", (t_int)x); + sprintf(buf, "#%lx", (long)x); x->receive = gensym(buf); pd_bind(&x->x_obj.ob_pd, x->receive ); -- cgit v1.2.1