From 71b83fc040b848c98c5065d95ecbc72b0b4f8943 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Thu, 17 Jan 2013 22:54:00 +0000 Subject: merging maxlib v1.5.5 from branches/pd-extended/0.43 svn path=/trunk/externals/maxlib/; revision=16897 --- match.c | 548 ++++++++++++++++++++++++++++++++-------------------------------- 1 file changed, 274 insertions(+), 274 deletions(-) (limited to 'match.c') diff --git a/match.c b/match.c index 48eca45..53ad633 100644 --- a/match.c +++ b/match.c @@ -1,274 +1,274 @@ -/* ------------------------- match ------------------------------------------ */ -/* */ -/* Outputs a list when a list of input values matches the creation args. */ -/* Written by Krzysztof Czaja for his cyclone library. */ -/* Modified to fit into maxlib by Olaf Matthes . */ -/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */ -/* */ -/* 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, write to the Free Software */ -/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* */ -/* Based on PureData by Miller Puckette and others. */ -/* */ -/* ---------------------------------------------------------------------------- */ - -/* this is the original copyright notice: */ - -/* Copyright (c) 1997-2002 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 -#include "m_pd.h" - -#define MATCH_INISIZE 16 /* LATER rethink */ - -typedef struct _match -{ - t_object x_ob; - int x_size; /* as allocated */ - int x_patlen; /* as used */ - t_atom *x_pattern; - t_atom x_patini[MATCH_INISIZE]; - int x_quelen; - t_atom *x_queue; - t_atom x_queini[MATCH_INISIZE]; - t_atom *x_queend; - t_atom *x_queptr; /* writing head, post-incremented (oldest-pointing) */ - int x_; -} t_match; - -static t_class *match_class; - -/* a caller must check for nrequested > *sizep */ -/* returns actual number of atoms: requested (success) - or a default value of initial size (failure) */ -/* the result is guaranteed to be >= min(nrequested, inisize) */ -static int match_grow(int nrequested, int *sizep, t_atom **bufp, - int inisize, t_atom *bufini) -{ - int newsize = *sizep * 2; - while (newsize < nrequested) newsize *= 2; - if (*bufp == bufini) - *bufp = (t_atom *)getbytes(newsize * sizeof(**bufp)); - else - *bufp = (t_atom *)resizebytes(*bufp, *sizep * sizeof(**bufp), - newsize * sizeof(**bufp)); - if (*bufp) - *sizep = newsize; - else - { - *bufp = bufini; - nrequested = *sizep = inisize; - } - return (nrequested); -} - -static void match_clear(t_match *x) -{ - x->x_quelen = 0; - x->x_queptr = x->x_queue; -} - -/* x->x_patlen > 0 is assumed */ -/* LATER use a lock to disable reentrant calls. I do not see any - purpose of reentering match, but lets CHECKME first... */ -static void match_checkin(t_match *x) -{ - int i, patlen = x->x_patlen; - t_atom *queptr, *pp, *qp; - if (x->x_queptr >= x->x_queend) - x->x_queptr = x->x_queue; - else x->x_queptr++; - if (x->x_quelen < patlen && ++(x->x_quelen) < patlen) - return; - - qp = queptr = x->x_queptr; - for (i = 0, pp = x->x_pattern; i < patlen; i++, pp++) - { - if (pp->a_type == A_FLOAT) - { - if (qp->a_type != A_FLOAT || qp->a_w.w_float != pp->a_w.w_float) - break; - } - else if (pp->a_type == A_SYMBOL) - { - if (qp->a_type != A_SYMBOL || qp->a_w.w_symbol != pp->a_w.w_symbol) - break; - } - else if (pp->a_type == A_NULL) - { - if (qp->a_type == A_FLOAT || qp->a_type == A_SYMBOL) - { - /* instantiating a pattern */ - *pp = *qp; - qp->a_type = A_NULL; - } - else break; /* LATER rethink */ - } - else break; /* LATER rethink */ - if (qp >= x->x_queend) - qp = x->x_queue; - else qp++; - } - if (i == patlen) - { - pp = x->x_pattern; - if (pp->a_type == A_FLOAT) - { - if (patlen == 1) - outlet_float(((t_object *)x)->ob_outlet, pp->a_w.w_float); - else - outlet_list(((t_object *)x)->ob_outlet, &s_list, patlen, pp); - } - else /* assuming A_SYMBOL (see above) */ - { - if (pp->a_w.w_symbol == &s_symbol /* bypassing typedmess() */ - && patlen == 2 && pp[1].a_type == A_SYMBOL) - outlet_symbol(((t_object *)x)->ob_outlet, pp[1].a_w.w_symbol); - else - outlet_anything(((t_object *)x)->ob_outlet, pp->a_w.w_symbol, - patlen - 1, pp + 1); - } - /* CHECKED: no implicit clear (resolving overlapping patterns) */ - } - /* restoring a pattern */ - for (i = 0, pp = x->x_pattern; i < patlen; i++, pp++) - { - if (queptr->a_type == A_NULL) - { - queptr->a_type = pp->a_type; - pp->a_type = A_NULL; - } - if (queptr >= x->x_queend) - queptr = x->x_queue; - else queptr++; - } -} - -static void match_float(t_match *x, t_float f) -{ - if (x->x_patlen) - { - SETFLOAT(x->x_queptr, f); - match_checkin(x); - } -} - -static void match_symbol(t_match *x, t_symbol *s) -{ - if (s && s != &s_ && x->x_patlen) - { - SETSYMBOL(x->x_queptr, s); - match_checkin(x); - } -} - -/* LATER gpointer */ - -static void match_list(t_match *x, t_symbol *s, int ac, t_atom *av) -{ - while (ac--) - { - if (av->a_type == A_FLOAT) match_float(x, av->a_w.w_float); - else if (av->a_type == A_SYMBOL) match_symbol(x, av->a_w.w_symbol); - av++; - } -} - -static void match_anything(t_match *x, t_symbol *s, int ac, t_atom *av) -{ - match_symbol(x, s); - match_list(x, 0, ac, av); -} - -static void match_set(t_match *x, t_symbol *s, int ac, t_atom *av) -{ - if (ac) /* CHECKED */ - { - t_atom *pp; - t_symbol *ps_nn; - int newlen = ac * 2; - if (newlen > x->x_size) - { - newlen = match_grow(newlen, &x->x_size, &x->x_pattern, - MATCH_INISIZE * 2, x->x_patini); - if (newlen == MATCH_INISIZE * 2) - { - x->x_queue = x->x_queini; - ac = MATCH_INISIZE; - } - else x->x_queue = x->x_pattern + x->x_size / 2; - } - x->x_patlen = ac; - x->x_queend = x->x_queue + ac - 1; - match_clear(x); /* CHECKED */ - memcpy(x->x_pattern, av, ac * sizeof(*x->x_pattern)); - pp = x->x_pattern; - ps_nn = gensym("nn"); - while (ac--) - { - if (pp->a_type == A_SYMBOL && pp->a_w.w_symbol == ps_nn) - pp->a_type = A_NULL; - pp++; - } - } -} - -static void match_free(t_match *x) -{ - if (x->x_pattern != x->x_patini) - freebytes(x->x_pattern, 2 * x->x_size * sizeof(*x->x_pattern)); -} - -static void *match_new(t_symbol *s, int ac, t_atom *av) -{ - t_match *x = (t_match *)pd_new(match_class); - x->x_size = MATCH_INISIZE * 2; - x->x_patlen = 0; - x->x_pattern = x->x_patini; - x->x_queue = x->x_queini; - /* x->x_queend is not used unless x->x_patlen > 0, - LATER consider chosing a more defensive way... */ - outlet_new((t_object *)x, &s_anything); - match_clear(x); - match_set(x, 0, ac, av); - return (x); -} - -#ifndef MAXLIB -void match_setup(void) -{ - match_class = class_new(gensym("match"), (t_newmethod)match_new, - (t_method)match_free, sizeof(t_match), 0, A_GIMME, 0); -#else -void maxlib_match_setup(void) -{ - match_class = class_new(gensym("maxlib_match"), (t_newmethod)match_new, - (t_method)match_free, sizeof(t_match), 0, A_GIMME, 0); - class_addcreator((t_newmethod)match_new, gensym("match"), A_GIMME, 0); -#endif - class_addfloat(match_class, match_float); - class_addsymbol(match_class, match_symbol); - class_addlist(match_class, match_list); - class_addanything(match_class, match_anything); - class_addmethod(match_class, (t_method)match_set, gensym("set"), A_GIMME, 0); - class_addmethod(match_class, (t_method)match_clear, gensym("clear"), 0); -#ifndef MAXLIB - -#else - class_sethelpsymbol(match_class, gensym("maxlib/match-help.pd")); -#endif -} +/* ------------------------- match ------------------------------------------ */ +/* */ +/* Outputs a list when a list of input values matches the creation args. */ +/* Written by Krzysztof Czaja for his cyclone library. */ +/* Modified to fit into maxlib by Olaf Matthes . */ +/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */ +/* */ +/* 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, write to the Free Software */ +/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* */ +/* Based on PureData by Miller Puckette and others. */ +/* */ +/* ---------------------------------------------------------------------------- */ + +/* this is the original copyright notice: */ + +/* Copyright (c) 1997-2002 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 +#include "m_pd.h" + +#define MATCH_INISIZE 16 /* LATER rethink */ + +typedef struct _match +{ + t_object x_ob; + int x_size; /* as allocated */ + int x_patlen; /* as used */ + t_atom *x_pattern; + t_atom x_patini[MATCH_INISIZE]; + int x_quelen; + t_atom *x_queue; + t_atom x_queini[MATCH_INISIZE]; + t_atom *x_queend; + t_atom *x_queptr; /* writing head, post-incremented (oldest-pointing) */ + int x_; +} t_match; + +static t_class *match_class; + +/* a caller must check for nrequested > *sizep */ +/* returns actual number of atoms: requested (success) + or a default value of initial size (failure) */ +/* the result is guaranteed to be >= min(nrequested, inisize) */ +static int match_grow(int nrequested, int *sizep, t_atom **bufp, + int inisize, t_atom *bufini) +{ + int newsize = *sizep * 2; + while (newsize < nrequested) newsize *= 2; + if (*bufp == bufini) + *bufp = (t_atom *)getbytes(newsize * sizeof(**bufp)); + else + *bufp = (t_atom *)resizebytes(*bufp, *sizep * sizeof(**bufp), + newsize * sizeof(**bufp)); + if (*bufp) + *sizep = newsize; + else + { + *bufp = bufini; + nrequested = *sizep = inisize; + } + return (nrequested); +} + +static void match_clear(t_match *x) +{ + x->x_quelen = 0; + x->x_queptr = x->x_queue; +} + +/* x->x_patlen > 0 is assumed */ +/* LATER use a lock to disable reentrant calls. I do not see any + purpose of reentering match, but lets CHECKME first... */ +static void match_checkin(t_match *x) +{ + int i, patlen = x->x_patlen; + t_atom *queptr, *pp, *qp; + if (x->x_queptr >= x->x_queend) + x->x_queptr = x->x_queue; + else x->x_queptr++; + if (x->x_quelen < patlen && ++(x->x_quelen) < patlen) + return; + + qp = queptr = x->x_queptr; + for (i = 0, pp = x->x_pattern; i < patlen; i++, pp++) + { + if (pp->a_type == A_FLOAT) + { + if (qp->a_type != A_FLOAT || qp->a_w.w_float != pp->a_w.w_float) + break; + } + else if (pp->a_type == A_SYMBOL) + { + if (qp->a_type != A_SYMBOL || qp->a_w.w_symbol != pp->a_w.w_symbol) + break; + } + else if (pp->a_type == A_NULL) + { + if (qp->a_type == A_FLOAT || qp->a_type == A_SYMBOL) + { + /* instantiating a pattern */ + *pp = *qp; + qp->a_type = A_NULL; + } + else break; /* LATER rethink */ + } + else break; /* LATER rethink */ + if (qp >= x->x_queend) + qp = x->x_queue; + else qp++; + } + if (i == patlen) + { + pp = x->x_pattern; + if (pp->a_type == A_FLOAT) + { + if (patlen == 1) + outlet_float(((t_object *)x)->ob_outlet, pp->a_w.w_float); + else + outlet_list(((t_object *)x)->ob_outlet, &s_list, patlen, pp); + } + else /* assuming A_SYMBOL (see above) */ + { + if (pp->a_w.w_symbol == &s_symbol /* bypassing typedmess() */ + && patlen == 2 && pp[1].a_type == A_SYMBOL) + outlet_symbol(((t_object *)x)->ob_outlet, pp[1].a_w.w_symbol); + else + outlet_anything(((t_object *)x)->ob_outlet, pp->a_w.w_symbol, + patlen - 1, pp + 1); + } + /* CHECKED: no implicit clear (resolving overlapping patterns) */ + } + /* restoring a pattern */ + for (i = 0, pp = x->x_pattern; i < patlen; i++, pp++) + { + if (queptr->a_type == A_NULL) + { + queptr->a_type = pp->a_type; + pp->a_type = A_NULL; + } + if (queptr >= x->x_queend) + queptr = x->x_queue; + else queptr++; + } +} + +static void match_float(t_match *x, t_float f) +{ + if (x->x_patlen) + { + SETFLOAT(x->x_queptr, f); + match_checkin(x); + } +} + +static void match_symbol(t_match *x, t_symbol *s) +{ + if (s && s != &s_ && x->x_patlen) + { + SETSYMBOL(x->x_queptr, s); + match_checkin(x); + } +} + +/* LATER gpointer */ + +static void match_list(t_match *x, t_symbol *s, int ac, t_atom *av) +{ + while (ac--) + { + if (av->a_type == A_FLOAT) match_float(x, av->a_w.w_float); + else if (av->a_type == A_SYMBOL) match_symbol(x, av->a_w.w_symbol); + av++; + } +} + +static void match_anything(t_match *x, t_symbol *s, int ac, t_atom *av) +{ + match_symbol(x, s); + match_list(x, 0, ac, av); +} + +static void match_set(t_match *x, t_symbol *s, int ac, t_atom *av) +{ + if (ac) /* CHECKED */ + { + t_atom *pp; + t_symbol *ps_nn; + int newlen = ac * 2; + if (newlen > x->x_size) + { + newlen = match_grow(newlen, &x->x_size, &x->x_pattern, + MATCH_INISIZE * 2, x->x_patini); + if (newlen == MATCH_INISIZE * 2) + { + x->x_queue = x->x_queini; + ac = MATCH_INISIZE; + } + else x->x_queue = x->x_pattern + x->x_size / 2; + } + x->x_patlen = ac; + x->x_queend = x->x_queue + ac - 1; + match_clear(x); /* CHECKED */ + memcpy(x->x_pattern, av, ac * sizeof(*x->x_pattern)); + pp = x->x_pattern; + ps_nn = gensym("nn"); + while (ac--) + { + if (pp->a_type == A_SYMBOL && pp->a_w.w_symbol == ps_nn) + pp->a_type = A_NULL; + pp++; + } + } +} + +static void match_free(t_match *x) +{ + if (x->x_pattern != x->x_patini) + freebytes(x->x_pattern, 2 * x->x_size * sizeof(*x->x_pattern)); +} + +static void *match_new(t_symbol *s, int ac, t_atom *av) +{ + t_match *x = (t_match *)pd_new(match_class); + x->x_size = MATCH_INISIZE * 2; + x->x_patlen = 0; + x->x_pattern = x->x_patini; + x->x_queue = x->x_queini; + /* x->x_queend is not used unless x->x_patlen > 0, + LATER consider chosing a more defensive way... */ + outlet_new((t_object *)x, &s_anything); + match_clear(x); + match_set(x, 0, ac, av); + return (x); +} + +#ifndef MAXLIB +void match_setup(void) +{ + match_class = class_new(gensym("match"), (t_newmethod)match_new, + (t_method)match_free, sizeof(t_match), 0, A_GIMME, 0); +#else +void maxlib_match_setup(void) +{ + match_class = class_new(gensym("maxlib_match"), (t_newmethod)match_new, + (t_method)match_free, sizeof(t_match), 0, A_GIMME, 0); + class_addcreator((t_newmethod)match_new, gensym("match"), A_GIMME, 0); +#endif + class_addfloat(match_class, match_float); + class_addsymbol(match_class, match_symbol); + class_addlist(match_class, match_list); + class_addanything(match_class, match_anything); + class_addmethod(match_class, (t_method)match_set, gensym("set"), A_GIMME, 0); + class_addmethod(match_class, (t_method)match_clear, gensym("clear"), 0); +#ifndef MAXLIB + +#else + class_sethelpsymbol(match_class, gensym("maxlib/match-help.pd")); +#endif +} -- cgit v1.2.1