aboutsummaryrefslogtreecommitdiff
path: root/match.c
diff options
context:
space:
mode:
authorHans-Christoph Steiner <eighthave@users.sourceforge.net>2013-01-17 22:54:00 +0000
committerIOhannes m zmölnig <zmoelnig@iem.at>2015-10-14 13:53:22 +0200
commit71b83fc040b848c98c5065d95ecbc72b0b4f8943 (patch)
treeb64020d616887a488f8304fc13f57ff4d6c4e313 /match.c
parent2b487890477a2ad969a1694270cee19b1265f3f6 (diff)
merging maxlib v1.5.5 from branches/pd-extended/0.43HEADsvn2git-headmaster
svn path=/trunk/externals/maxlib/; revision=16897
Diffstat (limited to 'match.c')
-rw-r--r--match.c548
1 files changed, 274 insertions, 274 deletions
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 <olaf.matthes@gmx.de>. */
-/* 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 <string.h>
-#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 <olaf.matthes@gmx.de>. */
+/* 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 <string.h>
+#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
+}