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);