diff options
Diffstat (limited to 'shared/common')
-rw-r--r-- | shared/common/props.c | 98 | ||||
-rw-r--r-- | shared/common/props.h | 2 |
2 files changed, 53 insertions, 47 deletions
diff --git a/shared/common/props.c b/shared/common/props.c index 6b6181a..6079308 100644 --- a/shared/common/props.c +++ b/shared/common/props.c @@ -13,6 +13,7 @@ #define PROPS_MAXOTHERS 32 enum { PROPS_NONE = 0, PROPS_THIS, PROPS_OTHER }; +enum { PROPS_SINGLEMODE = 0, PROPS_MULTIMODE }; typedef struct _propelem { @@ -41,8 +42,8 @@ struct _props }; /* Dictionary of properties, p_dict, meant to be nothing more, but an - optimalization detail, is handled implicitly, through its owning t_props. - This optimalization has to be enabled by passing a nonzero 'resolver' + optimization detail, is handled implicitly, through its owning t_props. + This optimization has to be enabled by passing a nonzero 'resolver' argument to props_new(). Since p_dict stores resolved strings, it is a secondary, `shallow' storage, which has to be synced to its master, p_buffer of atoms. @@ -109,18 +110,6 @@ static void props_dictadd(t_props *pp, t_symbol *s, int ac, t_atom *av) } } -static int props_atstart(t_props *pp, char *buf) -{ - if (*buf == pp->p_thisescape) - { - char c = buf[1]; - if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') - || (pp->p_thisinitial && strchr(pp->p_thisinitial, c))) - return (PROPS_THIS); - } - return (PROPS_NONE); -} - static char *props_otherinitial(t_props *pp, char c) { t_props *pp1 = pp->p_otherprops; @@ -135,7 +124,7 @@ static char *props_otherinitial(t_props *pp, char c) return (0); } -static int props_atnext(t_props *pp, char *buf) +static int props_atstart(t_props *pp, int mode, char *buf) { char *otherinitial; if (*buf == pp->p_thisescape) @@ -145,7 +134,8 @@ static int props_atnext(t_props *pp, char *buf) || (pp->p_thisinitial && strchr(pp->p_thisinitial, c))) return (PROPS_THIS); } - else if (*pp->p_otherescapes && strchr(pp->p_otherescapes, *buf)) + else if (mode == PROPS_MULTIMODE && + *pp->p_otherescapes && strchr(pp->p_otherescapes, *buf)) { char c = buf[1]; if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') @@ -158,13 +148,14 @@ static int props_atnext(t_props *pp, char *buf) /* 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, t_symbol *s, int ac, t_atom *av, int doit) +static int props_update(t_props *pp, int mode, + t_symbol *s, 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_atnext(pp, ap->a_w.w_symbol->s_name)) + && props_atstart(pp, mode, ap->a_w.w_symbol->s_name)) break; if (!nadd) { @@ -179,7 +170,8 @@ static int props_update(t_props *pp, t_symbol *s, int ac, t_atom *av, int doit) { for (iend = ibeg + 1, ap++; iend < pp->p_natoms; iend++, ap++) if (ap->a_type == A_SYMBOL - && props_atnext(pp, ap->a_w.w_symbol->s_name)) + && props_atstart(pp, PROPS_SINGLEMODE, + ap->a_w.w_symbol->s_name)) break; break; } @@ -228,23 +220,43 @@ static int props_update(t_props *pp, t_symbol *s, int ac, t_atom *av, int doit) return (ndiff); } -/* If there is an empty property, do not parse beyond. - Return the offending switch, if any. */ -t_symbol *props_add(t_props *pp, t_symbol *s, int ac, t_atom *av) +/* 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) { 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, s->s_name)) - ngrown += props_update(pp, s, ac, av, 0); + if (!s || !props_atstart(pp, PROPS_SINGLEMODE, s->s_name)) + { + 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)) + break; + s = 0; + } + } + if (!s || !ac) + { + empty = s; + goto done; + } + ngrown += props_update(pp, mode, 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, ap->a_w.w_symbol->s_name)) + && props_atstart(pp, PROPS_SINGLEMODE, + ap->a_w.w_symbol->s_name)) { - ngrown += props_update(pp, ap->a_w.w_symbol, ac - i - 1, ap + 1, 0); + ngrown += props_update(pp, mode, ap->a_w.w_symbol, + ac - i - 1, ap + 1, 0); if (pp->p_badupdate) { empty = ap->a_w.w_symbol; @@ -263,24 +275,17 @@ t_symbol *props_add(t_props *pp, t_symbol *s, int ac, t_atom *av) if (nrequested != ngrown) goto done; } - ac1 = (s ? ac + 1 : ac); - if (!(av1 = getbytes(ac1 * sizeof(*av1)))) - goto done; - ap = av1; - if (s) - { - SETSYMBOL(ap, s); - ap++; - } - while (ac--) *ap++ = *av++; - ac = ac1; - av = av1; - for (i = 0, ap = av; i < ac; i++, ap++) + props_update(pp, mode, 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, ap->a_w.w_symbol->s_name)) + && props_atstart(pp, PROPS_SINGLEMODE, + ap->a_w.w_symbol->s_name)) { - props_update(pp, ap->a_w.w_symbol, ac - i - 1, ap + 1, 1); + props_update(pp, mode, ap->a_w.w_symbol, + ac - i - 1, ap + 1, 1); if (pp->p_badupdate) { empty = ap->a_w.w_symbol; @@ -288,7 +293,6 @@ t_symbol *props_add(t_props *pp, t_symbol *s, int ac, t_atom *av) } } } - freebytes(av1, ac1 * sizeof(*av1)); done: return (empty); } @@ -328,11 +332,12 @@ void props_clone(t_props *to, t_props *from) while (ibeg < from->p_natoms) { if (ap->a_type == A_SYMBOL && - props_atstart(from, ap->a_w.w_symbol->s_name)) + 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_atnext(from, ap->a_w.w_symbol->s_name)) + && 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); @@ -397,7 +402,7 @@ t_atom *props_getone(t_props *pp, t_symbol *s, int *npp) { int ibeg, iend = 0; t_atom *ap; - if (!(s && props_atstart(pp, s->s_name))) + 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++) { @@ -405,7 +410,8 @@ t_atom *props_getone(t_props *pp, t_symbol *s, int *npp) { for (iend = ibeg + 1, ap++; iend < pp->p_natoms; iend++, ap++) if (ap->a_type == A_SYMBOL - && props_atnext(pp, ap->a_w.w_symbol->s_name)) + && props_atstart(pp, PROPS_MULTIMODE, + ap->a_w.w_symbol->s_name)) break; break; } diff --git a/shared/common/props.h b/shared/common/props.h index 0eef345..8e3add6 100644 --- a/shared/common/props.h +++ b/shared/common/props.h @@ -10,7 +10,7 @@ EXTERN_STRUCT _props; typedef char *(*t_propsresolver)(t_pd *, int, t_atom *); -t_symbol *props_add(t_props *pp, t_symbol *s, int ac, t_atom *av); +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); |