Module Name: src
Committed By: uebayasi
Date: Sat Oct 11 06:07:20 UTC 2014
Modified Files:
src/usr.bin/config: sem.c
Log Message:
Resolve "device" definition dependency lazily.
To generate a diff of this commit:
cvs rdiff -u -r1.55 -r1.56 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/sem.c
diff -u src/usr.bin/config/sem.c:1.55 src/usr.bin/config/sem.c:1.56
--- src/usr.bin/config/sem.c:1.55 Fri Oct 10 11:09:50 2014
+++ src/usr.bin/config/sem.c Sat Oct 11 06:07:20 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: sem.c,v 1.55 2014/10/10 11:09:50 uebayasi Exp $ */
+/* $NetBSD: sem.c,v 1.56 2014/10/11 06:07:20 uebayasi Exp $ */
/*
* Copyright (c) 1992, 1993
@@ -128,6 +128,75 @@ initsem(void)
/* Name of include file just ended (set in scan.l) */
extern const char *lastfile;
+struct attr *
+finddep(struct attr *a, const char *name)
+{
+ struct attrlist *al;
+
+ for (al = a->a_deps; al != NULL; al = al->al_next) {
+ struct attr *this = al->al_this;
+ if (strcmp(this->a_name, name) == 0)
+ return this;
+ }
+ return NULL;
+}
+
+static void
+mergedeps(struct devbase *dev, const char *name)
+{
+ struct attr *a, *newa;
+ struct attrlist *newal;
+
+ a = refattr(dev->d_name);
+
+ CFGDBG(3, "merging attr `%s' in attr `%s'", name, a->a_name);
+ if (finddep(a, name) == NULL) {
+ newa = refattr(name);
+ a->a_deps = attrlist_cons(a->a_deps, newa);
+ CFGDBG(3, "attr `%s' merged to attr `%s'", newa->a_name,
+ a->a_name);
+ }
+}
+
+static void
+fixdev(struct devbase *dev)
+{
+ struct attrlist *al;
+ struct attr *devattr, *a;
+
+ devattr = refattr(dev->d_name);
+ if (devattr->a_devclass)
+ panic("%s: dev %s is devclass!", devattr->a_name);
+
+ /*
+ * For each interface attribute this device refers to, add this
+ * device to its reference list. This makes, e.g., finding all
+ * "scsi"s easier.
+ *
+ * While looking through the attributes, set up the device
+ * class if any are devclass attributes (and error out if the
+ * device has two classes).
+ */
+ for (al = dev->d_attrs; al != NULL; al = al->al_next) {
+ a = al->al_this;
+ if (a->a_iattr) {
+ a->a_refs = addtoattr(a->a_refs, dev);
+ } else if (a->a_devclass != NULL) {
+ if (dev->d_classattr != NULL) {
+ cfgwarn("device `%s' has multiple classes "
+ "(`%s' and `%s')",
+ dev->d_name, dev->d_classattr->a_name,
+ a->a_name);
+ }
+ dev->d_classattr = a;
+ } else {
+ if (strcmp(dev->d_name, a->a_name) != 0) {
+ mergedeps(dev, a->a_name);
+ }
+ }
+ }
+}
+
void
enddefs(void)
{
@@ -141,6 +210,7 @@ enddefs(void)
errors++;
continue;
}
+ fixdev(dev);
}
if (errors) {
(void)fprintf(stderr, "*** Stop.\n");
@@ -440,6 +510,7 @@ defdev(struct devbase *dev, struct locli
dev->d_ispseudo = ispseudo;
dev->d_attrs = attrs;
dev->d_classattr = NULL; /* for now */
+ CFGDBG(3, "dev `%s' defined", dev->d_name);
/*
* Implicit attribute definition for device.
@@ -457,17 +528,11 @@ defdev(struct devbase *dev, struct locli
*/
for (al = attrs; al != NULL; al = al->al_next) {
a = al->al_this;
- if (a->a_iattr)
- a->a_refs = addtoattr(a->a_refs, dev);
- if (a->a_devclass != NULL) {
- if (dev->d_classattr != NULL) {
- cfgerror("device `%s' has multiple classes "
- "(`%s' and `%s')",
- dev->d_name, dev->d_classattr->a_name,
- a->a_name);
- }
- dev->d_classattr = a;
- }
+
+ /*
+ * Implicit attribute definition for device dependencies.
+ */
+ refattr(dev->d_name);
}
return;
bad:
@@ -512,6 +577,7 @@ getdevbase(const char *name)
TAILQ_INSERT_TAIL(&allbases, dev, d_next);
if (ht_insert(devbasetab, name, dev))
panic("getdevbase(%s)", name);
+ CFGDBG(3, "devbase defined `%s'", dev->d_name);
}
return (dev);
}
@@ -1890,6 +1956,11 @@ selectbase(struct devbase *d, struct dev
a = al->al_this;
expandattr(a, selectattr);
}
+
+ struct attr *devattr;
+ devattr = refattr(d->d_name);
+ expandattr(devattr, selectattr);
+
if (da != NULL) {
(void)ht_insert(selecttab, da->d_name, __UNCONST(da->d_name));
CFGDBG(3, "devattr selected `%s'", da->d_name);