aboutsummaryrefslogtreecommitdiff
path: root/shared/common
diff options
context:
space:
mode:
Diffstat (limited to 'shared/common')
-rw-r--r--shared/common/loud.c8
-rw-r--r--shared/common/loud.h1
-rw-r--r--shared/common/props.c487
-rw-r--r--shared/common/props.h20
4 files changed, 334 insertions, 182 deletions
diff --git a/shared/common/loud.c b/shared/common/loud.c
index d87d3c0..e1e921d 100644
--- a/shared/common/loud.c
+++ b/shared/common/loud.c
@@ -366,6 +366,14 @@ void loudbug_startpost(char *fmt, ...)
#endif
}
+void loudbug_stringpost(char *s)
+{
+ fputs(s, stderr);
+#ifdef MSW
+ fflush(stderr);
+#endif
+}
+
void loudbug_endpost(void)
{
fputs("\n", stderr);
diff --git a/shared/common/loud.h b/shared/common/loud.h
index 64388c1..297b9c1 100644
--- a/shared/common/loud.h
+++ b/shared/common/loud.h
@@ -45,6 +45,7 @@ t_loudcontext *loudx_newcontext(t_pd *caller, char *callername,
void loudbug_post(char *fmt, ...);
void loudbug_startpost(char *fmt, ...);
+void loudbug_stringpost(char *s);
void loudbug_endpost(void);
void loudbug_postatom(int ac, t_atom *av);
void loudbug_postbinbuf(t_binbuf *bb);
diff --git a/shared/common/props.c b/shared/common/props.c
index 4dfe113..4445bf2 100644
--- a/shared/common/props.c
+++ b/shared/common/props.c
@@ -1,9 +1,10 @@
-/* Copyright (c) 2003 krzYszcz and others.
+/* Copyright (c) 2003-2005 krzYszcz 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"
+#include "common/loud.h"
#include "common/grow.h"
#include "props.h"
@@ -12,9 +13,12 @@
#endif
#define PROPS_INISIZE 32 /* LATER rethink */
-#define PROPS_MAXOTHERS 32
+#define PROPS_MAXMIXUPS 32
-enum { PROPS_NONE = 0, PROPS_THIS, PROPS_OTHER };
+/* return values of props_iskey() */
+enum { PROPS_NONE = 0, PROPS_THIS, PROPS_MIXUP };
+
+/* 'mode' argument values of props_iskey() and props_update() */
enum { PROPS_SINGLEMODE = 0, PROPS_MULTIMODE };
typedef struct _propelem
@@ -29,17 +33,18 @@ struct _props
char p_thisescape;
char *p_thisinitial;
char *p_name;
- int p_size; /* as allocated */
- int p_natoms; /* as used */
+ int p_size; /* as allocated */
+ int p_natoms; /* as used */
t_atom *p_buffer;
t_atom p_bufini[PROPS_INISIZE];
+ int p_nextindex;
t_pd *p_owner;
t_propsresolver p_resolver;
t_propelem *p_dict;
t_propelem *p_nextelem;
int p_badupdate;
- char p_otherescapes[PROPS_MAXOTHERS];
- t_props *p_otherprops; /* props list's head */
+ char p_mixupescapes[PROPS_MAXMIXUPS];
+ t_props *p_firstmixup; /* points to the props list's head */
t_props *p_next;
};
@@ -112,23 +117,124 @@ static void props_dictadd(t_props *pp, t_symbol *s, int ac, t_atom *av)
}
}
-static char *props_otherinitial(t_props *pp, char c)
+/* API calls for lookup (getvalue) and traversal (firstvalue, nextvalue), and
+ non-api calls (removevalue) of resolved properties. Only dictionary-enabled
+ properties handle these calls. Plain 'key', without escape, is expected.
+ Traversal is not thread-safe (will we need threaded props, LATER?) */
+
+char *props_getvalue(t_props *pp, char *key)
+{
+ if (pp->p_resolver)
+ {
+ t_propelem *ep = pp->p_dict;
+ while (ep)
+ {
+ if (strcmp(ep->e_key, key))
+ ep = ep->e_next;
+ else
+ return (ep->e_value);
+ }
+ }
+ return (0);
+}
+
+char *props_nextvalue(t_props *pp, char **keyp)
+{
+ if (pp->p_nextelem)
+ {
+ char *value = pp->p_nextelem->e_value;
+ *keyp = pp->p_nextelem->e_key;
+ pp->p_nextelem = pp->p_nextelem->e_next;
+ return (value);
+ }
+ return (0);
+}
+
+char *props_firstvalue(t_props *pp, char **keyp)
+{
+ if (pp->p_nextelem)
+ loudbug_bug("props_firstvalue");
+ if (pp->p_resolver)
+ pp->p_nextelem = pp->p_dict;
+ return (props_nextvalue(pp, keyp));
+}
+
+static void props_removevalue(t_props *pp, char *key)
+{
+ if (pp->p_resolver && *key)
+ {
+ t_propelem *ep = pp->p_dict, *epp = 0;
+ while (ep)
+ {
+ if (strcmp(ep->e_key, key))
+ {
+ epp = ep;
+ ep = ep->e_next;
+ }
+ else
+ {
+ if (epp)
+ epp->e_next = ep->e_next;
+ else
+ pp->p_dict = ep->e_next;
+ propelem_free(ep);
+ break;
+ }
+ }
+ }
+}
+
+void props_clearvalues(t_props *pp)
{
- t_props *pp1 = pp->p_otherprops;
+ while (pp->p_dict)
+ {
+ t_propelem *ep = pp->p_dict->e_next;
+ propelem_free(pp->p_dict);
+ pp->p_dict = ep;
+ }
+}
+
+/* LATER think about 'deep' cloning, i.e. propagating source atoms into
+ the destination buffer. Since cloning, unless requested by the user,
+ should never be persistent (source atoms should not stick to the
+ destination object in a .pd file), deep cloning requires introducing
+ a two-buffer scheme. There is no reason for deep cloning of arguments,
+ or handlers, but options could benefit. */
+
+void props_clonevalues(t_props *to, t_props *from)
+{
+ if (to->p_resolver)
+ {
+ int ac;
+ t_atom *ap = props_getfirst(from, &ac);
+ while (ap)
+ {
+ props_dictadd(to, ap->a_w.w_symbol, ac - 1, ap + 1);
+ ap = props_getnext(from, &ac);
+ }
+ }
+}
+
+static char *props_mixupinitial(t_props *pp, char c)
+{
+ t_props *pp1 = pp->p_firstmixup;
while (pp1)
{
if (pp1 != pp && pp1->p_thisescape == c)
return (pp1->p_thisinitial);
pp1 = pp1->p_next;
}
- bug("props_otherinitial");
- post("(%c \"%s\")", c, pp->p_otherescapes);
+ loudbug_bug("props_mixupinitial");
+ loudbug_post("(%c \"%s\")", c, pp->p_mixupescapes);
return (0);
}
-static int props_atstart(t_props *pp, int mode, char *buf)
+/* If buf is pp's key, returns PROPS_THIS; otherwise, if PROPS_MULTIMODE
+ was passed and buf is a key of one of pp's mixups, returns PROPS_MIXUP;
+ otherwise, returns PROPS_NONE. */
+static int props_iskey(t_props *pp, int mode, char *buf)
{
- char *otherinitial;
+ char *mixupinitial;
if (*buf == pp->p_thisescape)
{
char c = buf[1];
@@ -137,27 +243,113 @@ static int props_atstart(t_props *pp, int mode, char *buf)
return (PROPS_THIS);
}
else if (mode == PROPS_MULTIMODE &&
- *pp->p_otherescapes && strchr(pp->p_otherescapes, *buf))
+ *pp->p_mixupescapes && strchr(pp->p_mixupescapes, *buf))
{
char c = buf[1];
if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')
- || ((otherinitial = props_otherinitial(pp, *buf))
- && *otherinitial && strchr(otherinitial, c)))
- return (PROPS_OTHER);
+ || ((mixupinitial = props_mixupinitial(pp, *buf))
+ && *mixupinitial && strchr(mixupinitial, c)))
+ return (PROPS_MIXUP);
}
return (PROPS_NONE);
}
+/* Lookup (getone) and traversal (getfirst, getnext) of unresolved properties.
+ These calls return a pointer to the key atom (the contents follows it),
+ unlike the get/first/nextvalue calls, which return the (resolved) value.
+ Traversal is not thread-safe (will we need threaded props, LATER?) */
+
+t_atom *props_getone(t_props *pp, t_symbol *keysym, int *npp)
+{
+ if (keysym &&
+ props_iskey(pp, PROPS_SINGLEMODE, keysym->s_name) != PROPS_NONE)
+ {
+ int ibeg, iend = 0;
+ t_atom *ap;
+ for (ibeg = 0, ap = pp->p_buffer; ibeg < pp->p_natoms; ibeg++, ap++)
+ {
+ if (ap->a_type == A_SYMBOL && ap->a_w.w_symbol == keysym)
+ {
+ for (iend = ibeg + 1, ap++; iend < pp->p_natoms; iend++, ap++)
+ if (ap->a_type == A_SYMBOL &&
+ props_iskey(pp, PROPS_SINGLEMODE,
+ ap->a_w.w_symbol->s_name) != PROPS_NONE)
+ break;
+ break;
+ }
+ }
+ if (iend > ibeg)
+ {
+ *npp = iend - ibeg;
+ return (pp->p_buffer + ibeg);
+ }
+ }
+ *npp = 0;
+ return (0);
+}
+
+t_atom *props_getnext(t_props *pp, int *npp)
+{
+ if (pp->p_nextindex >= 0)
+ {
+ int ibeg = pp->p_nextindex;
+ t_atom *ap;
+ for (ap = pp->p_buffer + ibeg; ibeg < pp->p_natoms; ibeg++, ap++)
+ if (ap->a_type == A_SYMBOL &&
+ props_iskey(pp, PROPS_SINGLEMODE,
+ ap->a_w.w_symbol->s_name) != PROPS_NONE)
+ break;
+ if (ibeg < pp->p_natoms)
+ {
+ int iend;
+ for (iend = ibeg + 1, ap++; iend < pp->p_natoms; iend++, ap++)
+ if (ap->a_type == A_SYMBOL &&
+ props_iskey(pp, PROPS_SINGLEMODE,
+ ap->a_w.w_symbol->s_name) != PROPS_NONE)
+ break;
+ if (iend < pp->p_natoms)
+ pp->p_nextindex = iend;
+ else
+ pp->p_nextindex = -1;
+ *npp = iend - ibeg;
+ return (pp->p_buffer + ibeg);
+ }
+ else pp->p_nextindex = -1;
+ }
+ *npp = 0;
+ return (0);
+}
+
+t_atom *props_getfirst(t_props *pp, int *npp)
+{
+ if (pp->p_nextindex >= 0)
+ loudbug_bug("props_getfirst");
+ pp->p_nextindex = 0;
+ return (props_getnext(pp, npp));
+}
+
+t_atom *props_getall(t_props *pp, int *npp)
+{
+ *npp = pp->p_natoms;
+ return (pp->p_buffer);
+}
+
+char *props_getname(t_props *pp)
+{
+ return (pp ? pp->p_name : "property");
+}
+
/* Search for a property, replace its value if found, otherwise add.
- Assuming s is valid. Returning nafter - nbefore. */
-static int props_update(t_props *pp, int mode,
- t_symbol *s, int ac, t_atom *av, int doit)
+ If 'filter' contains an exact copy, do nothing. Assuming 'keysym'
+ is valid. Returning nafter - nbefore. */
+static int props_update(t_props *pp, int mode, t_props *filter,
+ t_symbol *keysym, int ac, t_atom *av, int doit)
{
int nadd, ndiff, ibeg, iend = 0;
t_atom *ap;
for (nadd = 0, ap = av; nadd < ac; nadd++, ap++)
- if (ap->a_type == A_SYMBOL
- && props_atstart(pp, mode, ap->a_w.w_symbol->s_name))
+ if (ap->a_type == A_SYMBOL &&
+ props_iskey(pp, mode, ap->a_w.w_symbol->s_name) != PROPS_NONE)
break;
if (!nadd)
{
@@ -166,14 +358,43 @@ static int props_update(t_props *pp, int mode,
}
pp->p_badupdate = 0;
nadd++;
+
+ if (filter)
+ {
+ int acf;
+ t_atom *apf = props_getone(filter, keysym, &acf);
+ if (acf == nadd)
+ {
+ int i;
+#ifdef PROPS_DEBUG
+ loudbug_startpost("checking %s", keysym->s_name);
+ loudbug_postatom(nadd - 1, av);
+#endif
+ for (i = 1, ap = av, apf++; i < nadd; i++, ap++, apf++)
+ if (ap->a_type != apf->a_type ||
+ ap->a_w.w_symbol != apf->a_w.w_symbol)
+ break;
+ if (i == nadd)
+#ifndef PROPS_DEBUG
+ return (0);
+#else
+ {
+ loudbug_post(" ... filtered");
+ return (0);
+ }
+ else loudbug_post(" ... updated");
+#endif
+ }
+ }
+
for (ibeg = 0, ap = pp->p_buffer; ibeg < pp->p_natoms; ibeg++, ap++)
{
- if (ap->a_type == A_SYMBOL && ap->a_w.w_symbol == s)
+ if (ap->a_type == A_SYMBOL && ap->a_w.w_symbol == keysym)
{
for (iend = ibeg + 1, ap++; iend < pp->p_natoms; iend++, ap++)
- if (ap->a_type == A_SYMBOL
- && props_atstart(pp, PROPS_SINGLEMODE,
- ap->a_w.w_symbol->s_name))
+ if (ap->a_type == A_SYMBOL &&
+ props_iskey(pp, PROPS_SINGLEMODE,
+ ap->a_w.w_symbol->s_name) != PROPS_NONE)
break;
break;
}
@@ -184,13 +405,13 @@ static int props_update(t_props *pp, int mode,
int i, newnatoms = pp->p_natoms + ndiff;
if (newnatoms > pp->p_size)
{
- bug("props_update");
+ loudbug_bug("props_update");
return (0);
}
#ifdef PROPS_DEBUG
- post("%s %s, [%d..%d), ndiff %d",
- (iend > ibeg ? "replacing" : "adding"), s->s_name,
- ibeg, iend, ndiff);
+ loudbug_post("%s %s, [%d..%d), ndiff %d",
+ (iend > ibeg ? "replacing" : "adding"), keysym->s_name,
+ ibeg, iend, ndiff);
#endif
if (iend > ibeg)
{
@@ -211,34 +432,38 @@ static int props_update(t_props *pp, int mode,
else
{
ap = pp->p_buffer + pp->p_natoms;
- SETSYMBOL(ap, s);
+ SETSYMBOL(ap, keysym);
}
ap++;
nadd--;
- if (pp->p_resolver) props_dictadd(pp, s, nadd, av);
+ if (pp->p_resolver)
+ props_dictadd(pp, keysym, nadd, av);
for (i = 0; i < nadd; i++) *ap++ = *av++;
pp->p_natoms = newnatoms;
}
return (ndiff);
}
-/* If in a single mode, ignore `other' properties (their switches are parsed
- through as values). If there is an empty property, which is not to be
- ignored, do not parse beyond. Return an offending switch, if any. */
-t_symbol *props_add(t_props *pp, int single, t_symbol *s, int ac, t_atom *av)
+/* Carve out all properties of a given kind from a message. If in a single
+ mode, ignore `mixup' properties -- their keys are parsed through as values.
+ If there is an empty property, which is not to be ignored, do not parse
+ beyond. Return an offending key symbol, if any. */
+t_symbol *props_add(t_props *pp, int single, t_props *filter,
+ t_symbol *s, int ac, t_atom *av)
{
t_symbol *empty = 0;
t_atom *av1, *ap;
int mode = (single ? PROPS_SINGLEMODE : PROPS_MULTIMODE);
int ac1, i, ngrown = 0;
- if (!s || !props_atstart(pp, PROPS_SINGLEMODE, s->s_name))
+ if (!s || props_iskey(pp, PROPS_SINGLEMODE, s->s_name) == PROPS_NONE)
{
s = 0;
while (ac)
{
s = (av->a_type == A_SYMBOL ? av->a_w.w_symbol : 0);
ac--; av++;
- if (s && props_atstart(pp, PROPS_SINGLEMODE, s->s_name))
+ if (s &&
+ props_iskey(pp, PROPS_SINGLEMODE, s->s_name) != PROPS_NONE)
break;
s = 0;
}
@@ -248,16 +473,16 @@ t_symbol *props_add(t_props *pp, int single, t_symbol *s, int ac, t_atom *av)
empty = s;
goto done;
}
- ngrown += props_update(pp, mode, s, ac, av, 0);
+ ngrown += props_update(pp, mode, filter, s, ac, av, 0);
if (pp->p_badupdate)
empty = s;
else for (i = 0, ap = av; i < ac; i++, ap++)
{
- if (ap->a_type == A_SYMBOL
- && props_atstart(pp, PROPS_SINGLEMODE,
- ap->a_w.w_symbol->s_name))
+ if (ap->a_type == A_SYMBOL &&
+ props_iskey(pp, PROPS_SINGLEMODE,
+ ap->a_w.w_symbol->s_name) != PROPS_NONE)
{
- ngrown += props_update(pp, mode, ap->a_w.w_symbol,
+ ngrown += props_update(pp, mode, filter, ap->a_w.w_symbol,
ac - i - 1, ap + 1, 0);
if (pp->p_badupdate)
{
@@ -277,16 +502,16 @@ t_symbol *props_add(t_props *pp, int single, t_symbol *s, int ac, t_atom *av)
if (nrequested != ngrown)
goto done;
}
- props_update(pp, mode, s, ac, av, 1);
+ props_update(pp, mode, filter, s, ac, av, 1);
if (pp->p_badupdate)
empty = s;
else for (i = 0, ap = av; i < ac; i++, ap++)
{
- if (ap->a_type == A_SYMBOL
- && props_atstart(pp, PROPS_SINGLEMODE,
- ap->a_w.w_symbol->s_name))
+ if (ap->a_type == A_SYMBOL &&
+ props_iskey(pp, PROPS_SINGLEMODE,
+ ap->a_w.w_symbol->s_name) != PROPS_NONE)
{
- props_update(pp, mode, ap->a_w.w_symbol,
+ props_update(pp, mode, filter, ap->a_w.w_symbol,
ac - i - 1, ap + 1, 1);
if (pp->p_badupdate)
{
@@ -299,11 +524,12 @@ done:
return (empty);
}
-/* FIXME remove from p_dict */
-int props_remove(t_props *pp, t_symbol *s)
+int props_remove(t_props *pp, t_symbol *keysym)
{
int ac;
- t_atom *av = props_getone(pp, s, &ac);
+ t_atom *av = props_getone(pp, keysym, &ac);
+ if (keysym && *keysym->s_name)
+ props_removevalue(pp, keysym->s_name + 1);
if (av)
{
int i;
@@ -316,143 +542,51 @@ int props_remove(t_props *pp, t_symbol *s)
else return (0);
}
-/* LATER think about 'deep' cloning, i.e. propagating source atoms into
- the destination buffer. Since cloning, unless requested by the user,
- should never be persistent (source atoms should not stick to the
- destination object in a .pd file), deep cloning requires introducing
- a two-buffer scheme. There is no reason for deep cloning of arguments,
- or handlers, but options could benefit. */
-
-void props_clone(t_props *to, t_props *from)
+static void props_clearone(t_props *pp)
{
- if (to->p_resolver)
- {
- /* LATER make this into a generic traversing method */
- int ibeg = 0, iend = 0;
- t_atom *abeg = from->p_buffer;
- t_atom *ap = abeg;
- while (ibeg < from->p_natoms)
- {
- if (ap->a_type == A_SYMBOL &&
- props_atstart(from, PROPS_SINGLEMODE, ap->a_w.w_symbol->s_name))
- {
- for (iend = ibeg + 1, ap++; iend < from->p_natoms; iend++, ap++)
- if (ap->a_type == A_SYMBOL
- && props_atstart(from, PROPS_MULTIMODE,
- ap->a_w.w_symbol->s_name))
- break;
- props_dictadd(to, abeg->a_w.w_symbol,
- iend - ibeg - 1, abeg + 1);
- if (iend < from->p_natoms)
- {
- ibeg = iend;
- abeg = ap;
- }
- else break;
- }
- else
- {
- ibeg++;
- ap++;
- }
- }
- }
- else
- {
- /* LATER */
- }
+ pp->p_natoms = 0;
+ props_clearvalues(pp);
}
-/* only dictionary-enabled properties handle props_...value() calls */
-
-char *props_getvalue(t_props *pp, char *key)
+void props_clearall(t_props *pp)
{
- if (pp->p_resolver)
+ if (pp && (pp = pp->p_firstmixup))
{
- t_propelem *ep = pp->p_dict;
- while (ep)
+ while (pp)
{
- if (strcmp(ep->e_key, key))
- ep = ep->e_next;
- else
- return (ep->e_value);
+ props_clearone(pp);
+ pp = pp->p_next;
}
}
- return (0);
+ else loudbug_bug("props_clearall");
}
-char *props_nextvalue(t_props *pp, char **keyp)
+/* Compute pp0 = pp1 - pp2, using key-only equivalence. */
+void props_diff(t_props *pp0, t_props *pp1, t_props *pp2)
{
- if (pp->p_nextelem)
+ int ac1;
+ t_atom *ap1 = props_getfirst(pp1, &ac1);
+ props_clearone(pp0);
+ while (ap1)
{
- char *value = pp->p_nextelem->e_value;
- *keyp = pp->p_nextelem->e_key;
- pp->p_nextelem = pp->p_nextelem->e_next;
- return (value);
+ int ac2;
+ if (!props_getone(pp2, ap1->a_w.w_symbol, &ac2))
+ props_add(pp0, 0, 0, 0, ac1, ap1);
+ ap1 = props_getnext(pp1, &ac1);
}
- return (0);
-}
-
-char *props_firstvalue(t_props *pp, char **keyp)
-{
- if (pp->p_resolver)
- pp->p_nextelem = pp->p_dict;
- return (props_nextvalue(pp, keyp));
-}
-
-t_atom *props_getone(t_props *pp, t_symbol *s, int *npp)
-{
- int ibeg, iend = 0;
- t_atom *ap;
- if (!(s && props_atstart(pp, PROPS_SINGLEMODE, s->s_name)))
- return (0);
- for (ibeg = 0, ap = pp->p_buffer; ibeg < pp->p_natoms; ibeg++, ap++)
- {
- if (ap->a_type == A_SYMBOL && ap->a_w.w_symbol == s)
- {
- for (iend = ibeg + 1, ap++; iend < pp->p_natoms; iend++, ap++)
- if (ap->a_type == A_SYMBOL
- && props_atstart(pp, PROPS_MULTIMODE,
- ap->a_w.w_symbol->s_name))
- break;
- break;
- }
- }
- if (iend > ibeg)
- {
- *npp = iend - ibeg;
- return (pp->p_buffer + ibeg);
- }
- else return (0);
-}
-
-t_atom *props_getall(t_props *pp, int *npp)
-{
- *npp = pp->p_natoms;
- return (pp->p_buffer);
-}
-
-char *props_getname(t_props *pp)
-{
- return (pp ? pp->p_name : "property");
}
static void props_freeone(t_props *pp)
{
if (pp->p_buffer != pp->p_bufini)
freebytes(pp->p_buffer, pp->p_size * sizeof(*pp->p_buffer));
- while (pp->p_dict)
- {
- t_propelem *ep = pp->p_dict->e_next;
- propelem_free(pp->p_dict);
- pp->p_dict = ep;
- }
+ props_clearvalues(pp);
freebytes(pp, sizeof(*pp));
}
void props_freeall(t_props *pp)
{
- if (pp && (pp = pp->p_otherprops))
+ if (pp && (pp = pp->p_firstmixup))
{
while (pp)
{
@@ -461,36 +595,36 @@ void props_freeall(t_props *pp)
pp = pp1;
}
}
- else bug("props_freeall");
+ else loudbug_bug("props_freeall");
}
-void props_setupothers(t_props *pp, t_props *otherprops)
+static void props_setupmixups(t_props *pp, t_props *mixup)
{
t_props *pp1;
- pp->p_next = (otherprops ? otherprops->p_otherprops : 0);
+ pp->p_next = (mixup ? mixup->p_firstmixup : 0);
for (pp1 = pp; pp1; pp1 = pp1->p_next)
{
t_props *pp2;
- char *bp = pp1->p_otherescapes;
+ char *bp = pp1->p_mixupescapes;
int i;
- pp1->p_otherprops = pp;
- for (pp2 = pp, i = 1; pp2 && i < PROPS_MAXOTHERS;
+ pp1->p_firstmixup = pp;
+ for (pp2 = pp, i = 1; pp2 && i < PROPS_MAXMIXUPS;
pp2 = pp2->p_next, i++)
if (pp2 != pp1)
*bp++ = pp2->p_thisescape;
*bp = 0;
#ifdef PROPS_DEBUG
- startpost("%c \"%s\" ", pp1->p_thisescape, pp1->p_otherescapes);
+ loudbug_startpost("%c \"%s\" ", pp1->p_thisescape, pp1->p_mixupescapes);
#endif
}
#ifdef PROPS_DEBUG
- endpost();
+ loudbug_endpost();
#endif
}
/* nonzero resolver requires the owner to be nonzero */
t_props *props_new(t_pd *owner, char *name, char *thisdelim,
- t_props *otherprops, t_propsresolver resolver)
+ t_props *mixup, t_propsresolver resolver)
{
t_props *pp = getbytes(sizeof(*pp));
if (pp)
@@ -503,20 +637,21 @@ t_props *props_new(t_pd *owner, char *name, char *thisdelim,
}
else
{
- bug("props_new (no escape)");
+ loudbug_bug("props_new (no escape)");
pp->p_thisescape = '-';
pp->p_thisinitial = 0;
}
- props_setupothers(pp, otherprops);
+ props_setupmixups(pp, mixup);
pp->p_size = PROPS_INISIZE;
pp->p_natoms = 0;
pp->p_buffer = pp->p_bufini;
+ pp->p_nextindex = -1;
if (pp->p_owner = owner)
pp->p_resolver = resolver;
else
{
if (resolver)
- bug("props_new (no owner)");
+ loudbug_bug("props_new (no owner)");
pp->p_resolver = 0;
}
pp->p_dict = 0;
diff --git a/shared/common/props.h b/shared/common/props.h
index 8e3add6..c9d81a6 100644
--- a/shared/common/props.h
+++ b/shared/common/props.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2003 krzYszcz and others.
+/* Copyright (c) 2003-2005 krzYszcz and others.
* For information on usage and redistribution, and for a DISCLAIMER OF ALL
* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
@@ -10,17 +10,25 @@ EXTERN_STRUCT _props;
typedef char *(*t_propsresolver)(t_pd *, int, t_atom *);
-t_symbol *props_add(t_props *pp, int single, t_symbol *s, int ac, t_atom *av);
-int props_remove(t_props *pp, t_symbol *s);
-void props_clone(t_props *to, t_props *from);
char *props_getvalue(t_props *pp, char *key);
char *props_firstvalue(t_props *pp, char **keyp);
char *props_nextvalue(t_props *pp, char **keyp);
-t_atom *props_getone(t_props *pp, t_symbol *s, int *npp);
+void props_clearvalues(t_props *pp);
+void props_clonevalues(t_props *to, t_props *from);
+
+t_atom *props_getone(t_props *pp, t_symbol *keysym, int *npp);
+t_atom *props_getfirst(t_props *pp, int *npp);
+t_atom *props_getnext(t_props *pp, int *npp);
t_atom *props_getall(t_props *pp, int *npp);
char *props_getname(t_props *pp);
+
+t_symbol *props_add(t_props *pp, int single, t_props *filter,
+ t_symbol *s, int ac, t_atom *av);
+int props_remove(t_props *pp, t_symbol *keysym);
+void props_diff(t_props *pp0, t_props *pp1, t_props *pp2);
+void props_clearall(t_props *pp);
void props_freeall(t_props *pp);
t_props *props_new(t_pd *owner, char *name, char *thisdelim,
- t_props *otherprops, t_propsresolver resolver);
+ t_props *mixup, t_propsresolver resolver);
#endif