diff options
| author | christos <christos@NetBSD.org> | 2016-09-09 21:09:11 +0000 |
|---|---|---|
| committer | christos <christos@NetBSD.org> | 2016-09-09 21:09:11 +0000 |
| commit | 11a68ade93f2e55fb9580da21b733680099345ea (patch) | |
| tree | b2b9ce44bbe68ed06a4be7ed28d205970e5fc85e /usr.bin | |
| parent | 849291640392d2512bafeaf486fb9e45d791ba62 (diff) | |
Make attribute deselection work:
- when deselecting attributes, remove files that depend on them
- when deselecting attributes, remove devices that depend on them
Diffstat (limited to 'usr.bin')
| -rw-r--r-- | usr.bin/config/defs.h | 5 | ||||
| -rw-r--r-- | usr.bin/config/files.c | 9 | ||||
| -rw-r--r-- | usr.bin/config/sem.c | 133 |
3 files changed, 110 insertions, 37 deletions
diff --git a/usr.bin/config/defs.h b/usr.bin/config/defs.h index b7c18c6969b..a08c8746927 100644 --- a/usr.bin/config/defs.h +++ b/usr.bin/config/defs.h @@ -1,4 +1,4 @@ -/* $NetBSD: defs.h,v 1.97 2016/08/07 21:11:55 christos Exp $ */ +/* $NetBSD: defs.h,v 1.98 2016/09/09 21:09:11 christos Exp $ */ /* * Copyright (c) 1992, 1993 @@ -190,7 +190,8 @@ struct attr { #define a_weight a_m.m_weight /* "interface attribute" */ - int a_iattr; /* true => allows children */ + uint8_t a_iattr; /* true => allows children */ + uint8_t a_deselected; /* deselected */ struct loclist *a_locs; /* locators required */ int a_loclen; /* length of above list */ struct nvlist *a_devs; /* children */ diff --git a/usr.bin/config/files.c b/usr.bin/config/files.c index 3b43f69bfd8..3abf29c0f98 100644 --- a/usr.bin/config/files.c +++ b/usr.bin/config/files.c @@ -1,4 +1,4 @@ -/* $NetBSD: files.c,v 1.35 2015/09/04 21:32:54 uebayasi Exp $ */ +/* $NetBSD: files.c,v 1.36 2016/09/09 21:09:11 christos Exp $ */ /* * Copyright (c) 1992, 1993 @@ -45,7 +45,7 @@ #endif #include <sys/cdefs.h> -__RCSID("$NetBSD: files.c,v 1.35 2015/09/04 21:32:54 uebayasi Exp $"); +__RCSID("$NetBSD: files.c,v 1.36 2016/09/09 21:09:11 christos Exp $"); #include <sys/param.h> #include <assert.h> @@ -335,6 +335,11 @@ fixfiles(void) if (!sel) continue; } + if (fi->fi_attr && fi->fi_attr->a_deselected) { + CFGDBG(5, "file `%s' deselected because attr `%s' was", + fi->fi_path, fi->fi_attr->a_name); + continue; + } /* We like this file. Make sure it generates a unique .o. */ if (ht_insert(basetab, fi->fi_base, fi)) { diff --git a/usr.bin/config/sem.c b/usr.bin/config/sem.c index 944503793ba..563a3de9a77 100644 --- a/usr.bin/config/sem.c +++ b/usr.bin/config/sem.c @@ -1,4 +1,4 @@ -/* $NetBSD: sem.c,v 1.75 2016/08/07 10:37:24 christos Exp $ */ +/* $NetBSD: sem.c,v 1.76 2016/09/09 21:09:11 christos Exp $ */ /* * Copyright (c) 1992, 1993 @@ -45,7 +45,7 @@ #endif #include <sys/cdefs.h> -__RCSID("$NetBSD: sem.c,v 1.75 2016/08/07 10:37:24 christos Exp $"); +__RCSID("$NetBSD: sem.c,v 1.76 2016/09/09 21:09:11 christos Exp $"); #include <sys/param.h> #include <ctype.h> @@ -95,6 +95,45 @@ static devmajor_t dev2major(struct devbase *); extern const char *yyfile; extern int vflag; +#define V_ATTRIBUTE 0 +#define V_DEVICE 1 +struct vtype { + int type; + struct attr *attr; + void *value; +}; + +static struct nvlist * +makedevstack(struct devbase *d) +{ + struct devi *firsti, *i; + struct nvlist *stack = NULL; + + for (firsti = d->d_ihead; firsti != NULL; firsti = firsti->i_bsame) + for (i = firsti; i != NULL; i = i->i_alias) + stack = newnv(NULL, NULL, i, 0, stack); + return stack; +} + +static void +devcleanup(struct nvlist *stack) +{ + struct nvlist *nv; + for (nv = stack; nv != NULL; nv = nv->nv_next) + remove_devi(nv->nv_ptr); + nvfreel(stack); +} + +static void * +addvalue(int type, struct attr *a, void *value) +{ + struct vtype *vt = emalloc(sizeof(*vt)); + vt->type = type; + vt->attr = a; + vt->value = value; + return vt; +} + void initsem(void) { @@ -308,7 +347,8 @@ defattr(const char *name, struct loclist *locs, struct attrlist *deps, "attribute", name, dep->a_name); return (1); } - (void)ht_insert2(attrdeptab, name, dep->a_name, NULL); + (void)ht_insert2(attrdeptab, name, dep->a_name, + addvalue(V_ATTRIBUTE, a, dep)); CFGDBG(2, "attr `%s' depends on attr `%s'", name, dep->a_name); } @@ -536,7 +576,8 @@ defdev(struct devbase *dev, struct loclist *loclist, struct attrlist *attrs, * Implicit attribute definition for device dependencies. */ refattr(al->al_this->a_name); - (void)ht_insert2(attrdeptab, dev->d_name, al->al_this->a_name, NULL); + (void)ht_insert2(attrdeptab, dev->d_name, al->al_this->a_name, + addvalue(V_DEVICE, al->al_this, dev)); CFGDBG(2, "device `%s' depends on attr `%s'", dev->d_name, al->al_this->a_name); } @@ -1563,9 +1604,7 @@ out: } } - for (nv = stack; nv != NULL; nv = nv->nv_next) - remove_devi(nv->nv_ptr); - nvfreel(stack); + devcleanup(stack); } void @@ -1573,7 +1612,7 @@ deldev(const char *name, int nowarn) { size_t l; struct devi *firsti, *i; - struct nvlist *nv, *stack = NULL; + struct nvlist *stack = NULL; CFGDBG(5, "deselecting dev `%s'", name); if (name[0] == '\0') @@ -1604,16 +1643,10 @@ out: name); return; } - - for (firsti = d->d_ihead; firsti != NULL; - firsti = firsti->i_bsame) - for (i = firsti; i != NULL; i = i->i_alias) - stack = newnv(NULL, NULL, i, 0, stack); + stack = makedevstack(d); } - for (nv = stack; nv != NULL; nv = nv->nv_next) - remove_devi(nv->nv_ptr); - nvfreel(stack); + devcleanup(stack); } /* @@ -1697,6 +1730,29 @@ addpseudoroot(const char *name) ht_insert(devroottab, ib->d_name, ib); } +static void +deldevbase(struct devbase *d) +{ + struct devi *i; + const char *name = d->d_name; + + if (!d->d_ispseudo) { + devcleanup(makedevstack(d)); + return; + } + + if ((i = ht_lookup(devitab, name)) == NULL) + return; + + d->d_umax = 0; /* clear neads-count entries */ + d->d_ihead = NULL; /* make sure it won't be considered active */ + TAILQ_REMOVE(&allpseudo, i, i_next); + if (ht_remove(devitab, name)) + panic("%s(%s) - can't remove from devitab", __func__, name); + if (ht_insert(deaddevitab, name, i)) + panic("%s(%s) - can't add to deaddevitab", __func__, name); +} + void addpseudo(const char *name, int number) { @@ -1729,7 +1785,6 @@ void delpseudo(const char *name, int nowarn) { struct devbase *d; - struct devi *i; CFGDBG(5, "deselecting pseudo `%s'", name); d = ht_lookup(devbasetab, name); @@ -1742,18 +1797,7 @@ delpseudo(const char *name, int nowarn) cfgerror("%s is a real device, not a pseudo-device", name); return; } - if ((i = ht_lookup(devitab, name)) == NULL) { - if (!nowarn) - cfgerror("`%s' not defined", name); - return; - } - d->d_umax = 0; /* clear neads-count entries */ - d->d_ihead = NULL; /* make sure it won't be considered active */ - TAILQ_REMOVE(&allpseudo, i, i_next); - if (ht_remove(devitab, name)) - panic("delpseudo(%s) - can't remove from devitab", name); - if (ht_insert(deaddevitab, name, i)) - panic("delpseudo(%s) - can't add to deaddevitab", name); + deldevbase(d); } void @@ -2003,19 +2047,42 @@ selectattr(struct attr *a) static int deselectattrcb2(const char *name1, const char *name2, void *v, void *arg) { - const char *name = arg; + struct attr *a = arg; + const char *name = a->a_name; + struct vtype *vt = v; - if (strcmp(name, name2) == 0) + if (strcmp(name, name2) == 0) { delattr(name1, 0); + return 0; + } + + if (!vt->attr->a_deselected) + return 0; + + switch (vt->type) { + case V_ATTRIBUTE: +#ifdef notyet + // XXX: Loops + deselectattr(vt->value); +#endif + break; + case V_DEVICE: + CFGDBG(5, "removing device `%s' with attr `%s' because attr `%s'" + " is deselected", name1, name2, name); + deldevbase(vt->value); + break; + default: + abort(); + } return 0; } void deselectattr(struct attr *a) { - CFGDBG(5, "deselecting attr `%s'", a->a_name); - ht_enumerate2(attrdeptab, deselectattrcb2, __UNCONST(a->a_name)); + a->a_deselected = 1; + ht_enumerate2(attrdeptab, deselectattrcb2, a); if (ht_remove(selecttab, a->a_name) == 0) nattrs--; CFGDBG(3, "attr deselected `%s'", a->a_name); |
