static void substitute_anything(t_substitute *x, t_symbol *s, int ac, t_atom *av) { int matchndx = substitute_check(x, s, ac, av); if (matchndx < -1) //if replace type is null or no match found substitute_dooutput(x, s, ac, av, 1); else { int replaceonce = x->x_replaceonce; int replaced = 0; //if we've replaced something, useful for replaceonce int reentered = x->x_entered; int prealloc = !reentered; int ntotal = ac; t_atom *buf; t_substitute_proxy *proxy = (t_substitute_proxy *)x->x_proxy; x->x_entered = 1; //while method is working, point to aux versions so if they change, won't effect //currently undergoing replacement scheme proxy->p_match = &x->x_auxmatch; proxy->p_repl = &x->x_auxrepl; if (s == &s_) s = 0; if (matchndx == -1) { //if match type is a symbol AND is the selector if (x->x_repl.a_type == A_FLOAT) { //since we're replacing the selector and it can't be a float, //need to add it to the list ntotal++; //if there's a rest to it, the selector needs to be a list selector if (ac) s = &s_list; //else there's no "rest of it", can be a float selector else s = &s_float; replaced = 1; } else if (x->x_repl.a_type == A_SYMBOL) { //just replace the selector if the replace type is the symbol //set matchndx to 0 to avoid the if in the message contructor clause below s = x->x_repl.a_w.w_symbol; matchndx = 0; replaced = 1; } } else if (matchndx == 0 && (!s || s == &s_list || s == &s_float) && av->a_type == A_FLOAT && x->x_repl.a_type == A_SYMBOL) { //match index is at the beginning of a list (or singleton) //incoming list[0] is a float, being replaced by a symbol //just make the selector the replacement s = x->x_repl.a_w.w_symbol; ac--; av++; ntotal = ac; } if (prealloc && ac > x->x_size) { //if bigger that maximum size, don't bother allocating to x_message if (ntotal > SUBSTITUTE_MAXSIZE) prealloc = 0; else x->x_message = grow_nodata(&ntotal, &x->x_size, x->x_message, SUBSTITUTE_INISIZE, x->x_messini, sizeof(*x->x_message)); } //if allocated, just point stack pointer to struct's x_message //else just point stack pointer to new allocated memory if (prealloc) buf = x->x_message; else /* LATER consider using the stack if ntotal <= MAXSTACK */ buf = getbytes(ntotal * sizeof(*buf)); if (buf) { int ncopy = ntotal; t_atom *bp = buf; if (matchndx == -1) { //only hit if x_repl is a float because of the earlier clause SETFLOAT(bp++, x->x_repl.a_w.w_float); ncopy--; } //copy over incoming list to allocated buf (or x message), do the substitution if (ncopy) memcpy(bp, av, ncopy * sizeof(*buf)); substitute_doit(x, s, ntotal, buf, matchndx, replaceonce, replaced); //free newly allocated memory if using it if (buf != x->x_message) freebytes(buf, ntotal * sizeof(*buf)); } if (!reentered) { x->x_entered = 0; if (x->x_auxmatch.a_type != A_NULL) { x->x_match = x->x_auxmatch; x->x_auxmatch.a_type = A_NULL; } if (x->x_auxrepl.a_type != A_NULL) { x->x_repl = x->x_auxrepl; x->x_auxrepl.a_type = A_NULL; } proxy->p_match = &x->x_match; proxy->p_repl = &x->x_repl; } } }
static void substitute_anything(t_substitute *x, t_symbol *s, int ac, t_atom *av) { int matchndx = substitute_check(x, s, ac, av); if (matchndx < -1) substitute_dooutput(x, s, ac, av, 1); else { int reentered = x->x_entered; int prealloc = !reentered; int ntotal = ac; t_atom *buf; t_substitute_proxy *proxy = (t_substitute_proxy *)x->x_proxy; x->x_entered = 1; proxy->p_match = &x->x_auxmatch; proxy->p_repl = &x->x_auxrepl; if (s == &s_) s = 0; if (matchndx == -1) { if (x->x_repl.a_type == A_FLOAT) { ntotal++; if (ac) s = &s_list; else s = &s_float; } else if (x->x_repl.a_type == A_SYMBOL) { s = x->x_repl.a_w.w_symbol; matchndx = 0; } } else if (matchndx == 0 && (!s || s == &s_list || s == &s_float) && av->a_type == A_FLOAT && x->x_repl.a_type == A_SYMBOL) { s = x->x_repl.a_w.w_symbol; ac--; av++; ntotal = ac; } if (prealloc && ac > x->x_size) { if (ntotal > SUBSTITUTE_MAXSIZE) prealloc = 0; else x->x_message = grow_nodata(&ntotal, &x->x_size, x->x_message, SUBSTITUTE_INISIZE, x->x_messini, sizeof(*x->x_message)); } if (prealloc) buf = x->x_message; else /* LATER consider using the stack if ntotal <= MAXSTACK */ buf = getbytes(ntotal * sizeof(*buf)); if (buf) { int ncopy = ntotal; t_atom *bp = buf; if (matchndx == -1) { SETFLOAT(bp++, x->x_repl.a_w.w_float); ncopy--; } if (ncopy) memcpy(bp, av, ncopy * sizeof(*buf)); substitute_doit(x, s, ntotal, buf, matchndx); if (buf != x->x_message) freebytes(buf, ntotal * sizeof(*buf)); } if (!reentered) { x->x_entered = 0; if (x->x_auxmatch.a_type != A_NULL) { x->x_match = x->x_auxmatch; x->x_auxmatch.a_type = A_NULL; } if (x->x_auxrepl.a_type != A_NULL) { x->x_repl = x->x_auxrepl; x->x_auxrepl.a_type = A_NULL; } proxy->p_match = &x->x_match; proxy->p_repl = &x->x_repl; } } }