Module Name:    src
Committed By:   christos
Date:           Fri Sep  9 21:09:11 UTC 2016

Modified Files:
        src/usr.bin/config: defs.h files.c sem.c

Log Message:
Make attribute deselection work:
- when deselecting attributes, remove files that depend on them
- when deselecting attributes, remove devices that depend on them


To generate a diff of this commit:
cvs rdiff -u -r1.97 -r1.98 src/usr.bin/config/defs.h
cvs rdiff -u -r1.35 -r1.36 src/usr.bin/config/files.c
cvs rdiff -u -r1.75 -r1.76 src/usr.bin/config/sem.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/usr.bin/config/defs.h
diff -u src/usr.bin/config/defs.h:1.97 src/usr.bin/config/defs.h:1.98
--- src/usr.bin/config/defs.h:1.97	Sun Aug  7 17:11:55 2016
+++ src/usr.bin/config/defs.h	Fri Sep  9 17:09:11 2016
@@ -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 */

Index: src/usr.bin/config/files.c
diff -u src/usr.bin/config/files.c:1.35 src/usr.bin/config/files.c:1.36
--- src/usr.bin/config/files.c:1.35	Fri Sep  4 17:32:54 2015
+++ src/usr.bin/config/files.c	Fri Sep  9 17:09:11 2016
@@ -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)) {

Index: src/usr.bin/config/sem.c
diff -u src/usr.bin/config/sem.c:1.75 src/usr.bin/config/sem.c:1.76
--- src/usr.bin/config/sem.c:1.75	Sun Aug  7 06:37:24 2016
+++ src/usr.bin/config/sem.c	Fri Sep  9 17:09:11 2016
@@ -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 devba
 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
 			    "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 locli
 		 * 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);

Reply via email to