Module Name:    src
Committed By:   dholland
Date:           Mon Mar 12 02:58:55 UTC 2012

Modified Files:
        src/usr.bin/config: defs.h gram.y hash.c lint.c main.c mkheaders.c
            util.c

Log Message:
Give option definitions their own data structure instead of using nvlists.
(and using messy hacks to make up for nvlists not holding quite the right
things)


To generate a diff of this commit:
cvs rdiff -u -r1.41 -r1.42 src/usr.bin/config/defs.h
cvs rdiff -u -r1.36 -r1.37 src/usr.bin/config/gram.y
cvs rdiff -u -r1.7 -r1.8 src/usr.bin/config/hash.c
cvs rdiff -u -r1.11 -r1.12 src/usr.bin/config/lint.c
cvs rdiff -u -r1.46 -r1.47 src/usr.bin/config/main.c
cvs rdiff -u -r1.20 -r1.21 src/usr.bin/config/mkheaders.c
cvs rdiff -u -r1.13 -r1.14 src/usr.bin/config/util.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.41 src/usr.bin/config/defs.h:1.42
--- src/usr.bin/config/defs.h:1.41	Mon Mar 12 00:20:30 2012
+++ src/usr.bin/config/defs.h	Mon Mar 12 02:58:55 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: defs.h,v 1.41 2012/03/12 00:20:30 dholland Exp $	*/
+/*	$NetBSD: defs.h,v 1.42 2012/03/12 02:58:55 dholland Exp $	*/
 
 /*
  * Copyright (c) 1992, 1993
@@ -139,6 +139,18 @@ struct config {
 };
 
 /*
+ * Option definition list
+ */
+struct defoptlist {
+	struct defoptlist *dl_next;
+	const char *dl_name;
+	const char *dl_value;
+	const char *dl_lintvalue;
+	int dl_obsolete;
+	struct nvlist *dl_depends;
+};
+
+/*
  * Attributes.  These come in three flavors: "plain", "device class,"
  * and "interface".  Plain attributes (e.g., "ether") simply serve
  * to pull in files.  Device class attributes are like plain
@@ -460,12 +472,12 @@ struct	hashtab *selecttab;	/* selects th
 struct	hashtab *needcnttab;	/* retains names marked "needs-count" */
 struct	hashtab *opttab;	/* table of configured options */
 struct	hashtab *fsopttab;	/* table of configured file systems */
-struct	nvhash *defopttab;	/* options that have been "defopt"'d */
-struct	nvhash *defflagtab;	/* options that have been "defflag"'d */
-struct	nvhash *defparamtab;	/* options that have been "defparam"'d */
-struct	nvhash *defoptlint;	/* lint values for options */
+struct	dlhash *defopttab;	/* options that have been "defopt"'d */
+struct	dlhash *defflagtab;	/* options that have been "defflag"'d */
+struct	dlhash *defparamtab;	/* options that have been "defparam"'d */
+struct	dlhash *defoptlint;	/* lint values for options */
 struct	nvhash *deffstab;	/* defined file systems */
-struct	nvhash *optfiletab;	/* "defopt"'d option .h files */
+struct	dlhash *optfiletab;	/* "defopt"'d option .h files */
 struct	hashtab *attrtab;	/* attributes (locators, etc.) */
 struct	hashtab *bdevmtab;	/* block devm lookup */
 struct	hashtab *cdevmtab;	/* character devm lookup */
@@ -541,6 +553,7 @@ int	ht_enumerate(struct hashtab *, ht_ca
 			int (*)(const char *, struct VT *, void *),	\
 			void *)
 DECLHASH(nvhash, nvlist);
+DECLHASH(dlhash, defoptlist);
 
 /* lint.c */
 void	emit_instances(void);
@@ -554,25 +567,25 @@ void	addmkoption(const char *, const cha
 void	appendmkoption(const char *, const char *);
 void	appendcondmkoption(struct condexpr *, const char *, const char *);
 void	deffilesystem(struct nvlist *, struct nvlist *);
-void	defoption(const char *, struct nvlist *, struct nvlist *);
-void	defflag(const char *, struct nvlist *, struct nvlist *, int);
-void	defparam(const char *, struct nvlist *, struct nvlist *, int);
+void	defoption(const char *, struct defoptlist *, struct nvlist *);
+void	defflag(const char *, struct defoptlist *, struct nvlist *, int);
+void	defparam(const char *, struct defoptlist *, struct nvlist *, int);
 void	deloption(const char *);
 void	delfsoption(const char *);
 void	delmkoption(const char *);
 int	devbase_has_instances(struct devbase *, int);
-struct nvlist * find_declared_option(const char *);
+int	is_declared_option(const char *);
 int	deva_has_instances(struct deva *, int);
 void	setupdirs(void);
 const char *strtolower(const char *);
 
 /* tests on option types */
 #define OPT_FSOPT(n)	(nvhash_lookup(deffstab, (n)) != NULL)
-#define OPT_DEFOPT(n)	(nvhash_lookup(defopttab, (n)) != NULL)
-#define OPT_DEFFLAG(n)	(nvhash_lookup(defflagtab, (n)) != NULL)
-#define OPT_DEFPARAM(n)	(nvhash_lookup(defparamtab, (n)) != NULL)
-#define OPT_OBSOLETE(n)	(nvhash_lookup(obsopttab, (n)) != NULL)
-#define DEFINED_OPTION(n) (find_declared_option((n)) != NULL)
+#define OPT_DEFOPT(n)	(dlhash_lookup(defopttab, (n)) != NULL)
+#define OPT_DEFFLAG(n)	(dlhash_lookup(defflagtab, (n)) != NULL)
+#define OPT_DEFPARAM(n)	(dlhash_lookup(defparamtab, (n)) != NULL)
+#define OPT_OBSOLETE(n)	(dlhash_lookup(obsopttab, (n)) != NULL)
+#define DEFINED_OPTION(n) (is_declared_option((n)))
 
 /* main.c */
 void	logconfig_include(FILE *, const char *);
@@ -627,6 +640,9 @@ void	nvfree(struct nvlist *);
 void	nvfreel(struct nvlist *);
 struct nvlist *nvcat(struct nvlist *, struct nvlist *);
 void	autogen_comment(FILE *, const char *);
+struct defoptlist *defoptlist_create(const char *, const char *, const char *);
+void defoptlist_destroy(struct defoptlist *);
+struct defoptlist *defoptlist_append(struct defoptlist *, struct defoptlist *);
 struct attrlist *attrlist_create(void);
 struct attrlist *attrlist_cons(struct attrlist *, struct attr *);
 void attrlist_destroy(struct attrlist *);

Index: src/usr.bin/config/gram.y
diff -u src/usr.bin/config/gram.y:1.36 src/usr.bin/config/gram.y:1.37
--- src/usr.bin/config/gram.y:1.36	Sun Mar 11 21:16:08 2012
+++ src/usr.bin/config/gram.y	Mon Mar 12 02:58:55 2012
@@ -1,5 +1,5 @@
 %{
-/*	$NetBSD: gram.y,v 1.36 2012/03/11 21:16:08 dholland Exp $	*/
+/*	$NetBSD: gram.y,v 1.37 2012/03/12 02:58:55 dholland Exp $	*/
 
 /*
  * Copyright (c) 1992, 1993
@@ -70,9 +70,10 @@ static void wrap_cleanup(void);
  * Allocation wrapper type codes
  */
 #define WRAP_CODE_nvlist	1
-#define WRAP_CODE_loclist	2
-#define WRAP_CODE_attrlist	3
-#define WRAP_CODE_condexpr	4
+#define WRAP_CODE_defoptlist	2
+#define WRAP_CODE_loclist	3
+#define WRAP_CODE_attrlist	4
+#define WRAP_CODE_condexpr	5
 
 /*
  * The allocation wrappers themselves
@@ -80,6 +81,7 @@ static void wrap_cleanup(void);
 #define DECL_ALLOCWRAP(t)	static struct t *wrap_mk_##t(struct t *arg)
 
 DECL_ALLOCWRAP(nvlist);
+DECL_ALLOCWRAP(defoptlist);
 DECL_ALLOCWRAP(loclist);
 DECL_ALLOCWRAP(attrlist);
 DECL_ALLOCWRAP(condexpr);
@@ -121,6 +123,8 @@ DECL_ALLOCWRAP(condexpr);
  * Data constructors
  */
 
+static struct defoptlist *mk_defoptlist(const char *, const char *,
+					const char *);
 static struct loclist *mk_loc(const char *, const char *, long long);
 static struct loclist *mk_loc_val(const char *, struct loclist *);
 static struct attrlist *mk_attrlist(struct attrlist *, struct attr *);
@@ -148,6 +152,7 @@ static struct loclist *namelocvals(const
 	struct	devbase *devb;
 	struct	deva *deva;
 	struct	nvlist *list;
+	struct defoptlist *defoptlist;
 	struct loclist *loclist;
 	struct attrlist *attrlist;
 	struct condexpr *condexpr;
@@ -204,8 +209,8 @@ static struct loclist *namelocvals(const
 %type	<val>	device_flags
 %type	<str>	deffs
 %type	<list>	deffses
-%type	<list>	defopt
-%type	<list>	defopts
+%type	<defoptlist>	defopt
+%type	<defoptlist>	defopts
 %type	<str>	optdepend
 %type	<list>	optdepends
 %type	<list>	optdepend_list
@@ -547,23 +552,15 @@ atname:
 /* one or more defined options */
 defopts:
 	  defopt			{ $$ = $1; }
-	| defopts defopt		{ $$ = nvcat($2, $1); }
+	| defopts defopt		{ $$ = defoptlist_append($2, $1); }
 ;
 
 /* one defined option */
 defopt:
-	  WORD				{ $$ = new_n($1); }
-	| WORD '=' value		{ $$ = new_ns($1, $3); }
-	| WORD COLONEQ value		{
-		struct nvlist *__nv = new_n($1);
-
-		$$ = new_nsx("", $3, __nv);
-	  }
-	| WORD '=' value COLONEQ value	{
-		struct nvlist *__nv = new_n($1);
-
-		$$ = new_nsx("", $5, __nv);
-	  }
+	  WORD				{ $$ = MK3(defoptlist, $1, NULL, NULL); }
+	| WORD '=' value		{ $$ = MK3(defoptlist, $1, $3, NULL); }
+	| WORD COLONEQ value		{ $$ = MK3(defoptlist, $1, NULL, $3); }
+	| WORD '=' value COLONEQ value	{ $$ = MK3(defoptlist, $1, $3, $5); }
 ;
 
 /* list of conditional makeoptions */
@@ -977,6 +974,14 @@ wrap_cleanup(void)
 		    case WRAP_CODE_nvlist:
 			nvfree(wrapstack[i].ptr);
 			break;
+		    case WRAP_CODE_defoptlist:
+			{
+				struct defoptlist *dl = wrapstack[i].ptr;
+
+				dl->dl_next = NULL;
+				defoptlist_destroy(dl);
+			}
+			break;
 		    case WRAP_CODE_loclist:
 			{
 				struct loclist *ll = wrapstack[i].ptr;
@@ -1028,6 +1033,7 @@ wrap_cleanup(void)
 	}
 
 DEF_ALLOCWRAP(nvlist);
+DEF_ALLOCWRAP(defoptlist);
 DEF_ALLOCWRAP(loclist);
 DEF_ALLOCWRAP(attrlist);
 DEF_ALLOCWRAP(condexpr);
@@ -1040,6 +1046,12 @@ DEF_ALLOCWRAP(condexpr);
  * (These are *beneath* the allocation wrappers.)
  */
 
+static struct defoptlist *
+mk_defoptlist(const char *name, const char *val, const char *lintval)
+{
+	return defoptlist_create(name, val, lintval);
+}
+
 static struct loclist *
 mk_loc(const char *name, const char *str, long long num)
 {

Index: src/usr.bin/config/hash.c
diff -u src/usr.bin/config/hash.c:1.7 src/usr.bin/config/hash.c:1.8
--- src/usr.bin/config/hash.c:1.7	Mon Mar 12 00:20:30 2012
+++ src/usr.bin/config/hash.c	Mon Mar 12 02:58:55 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: hash.c,v 1.7 2012/03/12 00:20:30 dholland Exp $	*/
+/*	$NetBSD: hash.c,v 1.8 2012/03/12 02:58:55 dholland Exp $	*/
 
 /*
  * Copyright (c) 1992, 1993
@@ -387,3 +387,4 @@ ht_enumerate(struct hashtab *ht, ht_call
 	}
 
 DEFHASH(nvhash, nvlist);
+DEFHASH(dlhash, defoptlist);

Index: src/usr.bin/config/lint.c
diff -u src/usr.bin/config/lint.c:1.11 src/usr.bin/config/lint.c:1.12
--- src/usr.bin/config/lint.c:1.11	Mon Mar 12 00:20:30 2012
+++ src/usr.bin/config/lint.c	Mon Mar 12 02:58:55 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: lint.c,v 1.11 2012/03/12 00:20:30 dholland Exp $	*/
+/*	$NetBSD: lint.c,v 1.12 2012/03/12 02:58:55 dholland Exp $	*/
 
 /*
  *  Copyright (c) 2007 The NetBSD Foundation.
@@ -30,6 +30,7 @@
 #include "nbtool_config.h"
 #endif
 
+#include <assert.h>
 #include <stdlib.h>
 
 #include "defs.h"
@@ -62,39 +63,63 @@ static struct opt_type {
 };
 
 static int
-do_emit_option(const char *name, struct nvlist *value, void *v)
+do_emit_option(const char *name, struct defoptlist *dl, void *v)
 {
-	struct nvlist *nv = value;
 	const struct opt_type *ot = v;
+	const char *value;
 
-	if (nv->nv_flags & NV_OBSOLETE)
+	if (dl->dl_obsolete)
 		return 0;
 
 	if (ht_lookup(*(ot->ot_ht), name))
 		return 0;
 
-	printf("%s\t%s", ot->ot_name, nv->nv_name);
+	printf("%s\t%s", ot->ot_name, dl->dl_name);
 	if (ot->ot_type == OT_PARAM) {
-		struct nvlist *nv2  = nvhash_lookup(defoptlint, nv->nv_name);
-		if (nv2 == NULL)
-			nv2 = nv;
-		printf("=\"%s\"", nv2->nv_str ? nv2->nv_str : "1");
+		struct defoptlist *dl2 = dlhash_lookup(defoptlint, dl->dl_name);
+		if (dl2 != NULL)
+			value = dl2->dl_lintvalue;
+		else
+			value = dl->dl_value;
+		assert(dl2 == dl);
+		printf("=\"%s\"", value ? value : "1");
 	}
 	printf("\n");
 
 	return 1;
 }
+
+/*
+ * Same as do_emit_option but for filesystem definitions, which now
+ * have a different data type. XXX these should probably be unified
+ * again.
+ */
+static int
+do_emit_fs(const char *name, struct nvlist *nv, void *v)
+{
+	const struct opt_type *ot = v;
+
+	assert((nv->nv_flags & NV_OBSOLETE) == 0);
+
+	if (ht_lookup(*(ot->ot_ht), name))
+		return 0;
+
+	assert(ot->ot_type != OT_PARAM);
+	printf("%s\t%s\n", ot->ot_name, nv->nv_name);
+
+	return 1;
+}
 	
 
 void
 emit_options(void)
 {
 
-	(void)nvhash_enumerate(defflagtab, do_emit_option, &opt_types[0]);
+	(void)dlhash_enumerate(defflagtab, do_emit_option, &opt_types[0]);
 	printf("\n");
-	(void)nvhash_enumerate(defparamtab, do_emit_option, &opt_types[1]);
+	(void)dlhash_enumerate(defparamtab, do_emit_option, &opt_types[1]);
 	printf("\n");
-	(void)nvhash_enumerate(deffstab, do_emit_option, &opt_types[2]);
+	(void)nvhash_enumerate(deffstab, do_emit_fs, &opt_types[2]);
 	printf("\n");
 }
 

Index: src/usr.bin/config/main.c
diff -u src/usr.bin/config/main.c:1.46 src/usr.bin/config/main.c:1.47
--- src/usr.bin/config/main.c:1.46	Mon Mar 12 00:20:30 2012
+++ src/usr.bin/config/main.c	Mon Mar 12 02:58:55 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: main.c,v 1.46 2012/03/12 00:20:30 dholland Exp $	*/
+/*	$NetBSD: main.c,v 1.47 2012/03/12 02:58:55 dholland Exp $	*/
 
 /*
  * Copyright (c) 1992, 1993
@@ -90,7 +90,7 @@ int	yyparse(void);
 extern int yydebug;
 #endif
 
-static struct nvhash *obsopttab;
+static struct dlhash *obsopttab;
 static struct hashtab *mkopttab;
 static struct nvlist **nextopt;
 static struct nvlist **nextmkopt;
@@ -100,6 +100,8 @@ static struct nvlist **nextfsopt;
 
 static	void	usage(void) __dead;
 static	void	dependopts(void);
+static	void	dependopts_one(const char *);
+static	void	do_depends(struct nvlist *);
 static	void	do_depend(struct nvlist *);
 static	void	stop(void);
 static	int	do_option(struct hashtab *, struct nvlist ***,
@@ -119,8 +121,10 @@ static	void	do_kill_orphans(struct devba
     struct devbase *, int);
 static	int	kill_orphans_cb(const char *, void *, void *);
 static	int	cfcrosscheck(struct config *, const char *, struct nvlist *);
-void	defopt(struct nvhash *ht, const char *fname,
-	     struct nvlist *opts, struct nvlist *deps, int obs);
+static void	defopt(struct dlhash *ht, const char *fname,
+	     struct defoptlist *opts, struct nvlist *deps, int obs);
+static struct defoptlist *find_declared_option_option(const char *name);
+static struct nvlist *find_declared_fs_option(const char *name);
 
 #define LOGCONFIG_LARGE "INCLUDE_CONFIG_FILE"
 #define LOGCONFIG_SMALL "INCLUDE_JUST_CONFIG"
@@ -267,12 +271,12 @@ main(int argc, char **argv)
 	mkopttab = ht_new();
 	fsopttab = ht_new();
 	deffstab = nvhash_create();
-	defopttab = nvhash_create();
-	defparamtab = nvhash_create();
-	defoptlint = nvhash_create();
-	defflagtab = nvhash_create();
-	optfiletab = nvhash_create();
-	obsopttab = nvhash_create();
+	defopttab = dlhash_create();
+	defparamtab = dlhash_create();
+	defoptlint = dlhash_create();
+	defflagtab = dlhash_create();
+	optfiletab = dlhash_create();
+	obsopttab = dlhash_create();
 	bdevmtab = ht_new();
 	maxbdevm = 0;
 	cdevmtab = ht_new();
@@ -466,31 +470,46 @@ usage(void)
 static void
 dependopts(void)
 {
-	struct nvlist *nv, *opt;
+	struct nvlist *nv;
 
 	for (nv = options; nv != NULL; nv = nv->nv_next) {
-		if ((opt = find_declared_option(nv->nv_name)) != NULL) {
-			for (opt = opt->nv_ptr; opt != NULL;
-			    opt = opt->nv_next) {
-				do_depend(opt);
-			}
-		}
+		dependopts_one(nv->nv_name);
 	}
 
 	for (nv = fsoptions; nv != NULL; nv = nv->nv_next) {
-		if ((opt = find_declared_option(nv->nv_name)) != NULL) {
-			for (opt = opt->nv_ptr; opt != NULL;
-			    opt = opt->nv_next) {
-				do_depend(opt);
-			}
-		}
+		dependopts_one(nv->nv_name);
+	}
+}
+
+static void
+dependopts_one(const char *name)
+{
+	struct defoptlist *dl;
+	struct nvlist *fs;
+
+	dl = find_declared_option_option(name);
+	if (dl != NULL) {
+		do_depends(dl->dl_depends);
+	}
+	fs = find_declared_fs_option(name);
+	if (fs != NULL) {
+		do_depends(fs->nv_ptr);
+	}
+}
+
+static void
+do_depends(struct nvlist *nv)
+{
+	struct nvlist *opt;
+
+	for (opt = nv; opt != NULL; opt = opt->nv_next) {
+		do_depend(opt);
 	}
 }
 
 static void
 do_depend(struct nvlist *nv)
 {
-	struct nvlist *nextnv;
 	struct attr *a;
 
 	if (nv != NULL && (nv->nv_flags & NV_DEPENDED) == 0) {
@@ -507,9 +526,7 @@ do_depend(struct nvlist *nv)
 		} else {
 			if (ht_lookup(opttab, nv->nv_name) == NULL)
 				addoption(nv->nv_name, NULL);
-			if ((nextnv =
-			     find_declared_option(nv->nv_name)) != NULL)
-				do_depend(nextnv->nv_ptr);
+			dependopts_one(nv->nv_name);
 		}
 	}
 }
@@ -575,13 +592,11 @@ stop(void)
 }
 
 static void
-add_dependencies(struct nvlist *nv, struct nvlist *deps)
+check_dependencies(const char *thing, struct nvlist *deps)
 {
 	struct nvlist *dep;
 	struct attr *a;
 
-	/* Use nv_ptr to link any other options that are implied. */
-	nv->nv_ptr = deps;
 	for (dep = deps; dep != NULL; dep = dep->nv_next) {
 		/*
 		 * If the dependency is an attribute, it must not
@@ -592,18 +607,33 @@ add_dependencies(struct nvlist *nv, stru
 			if (a->a_iattr)
 				cfgerror("option `%s' dependency `%s' "
 				    "is an interface attribute",
-				    nv->nv_name, a->a_name);
+				    thing, a->a_name);
 		} else if (OPT_OBSOLETE(dep->nv_name)) {
 			cfgerror("option `%s' dependency `%s' "
-			    "is obsolete", nv->nv_name, dep->nv_name);
-		} else if (find_declared_option(dep->nv_name) == NULL) {
+			    "is obsolete", thing, dep->nv_name);
+		} else if (!is_declared_option(dep->nv_name)) {
 			cfgerror("option `%s' dependency `%s' "
 			    "is an unknown option",
-			    nv->nv_name, dep->nv_name);
+			    thing, dep->nv_name);
 		}
 	}
 }
 
+static void
+add_fs_dependencies(struct nvlist *nv, struct nvlist *deps)
+{
+	/* Use nv_ptr to link any other options that are implied. */
+	nv->nv_ptr = deps;
+	check_dependencies(nv->nv_name, deps);
+}
+
+static void
+add_opt_dependencies(struct defoptlist *dl, struct nvlist *deps)
+{
+	dl->dl_depends = deps;
+	check_dependencies(dl->dl_name, deps);
+}
+
 /*
  * Define one or more file systems.
  */
@@ -631,7 +661,7 @@ deffilesystem(struct nvlist *fses, struc
 			panic("file system `%s' already in table?!",
 			    nv->nv_name);
 
-		add_dependencies(nv, deps);
+		add_fs_dependencies(nv, deps);
 	}
 }
 
@@ -662,22 +692,57 @@ badfilename(const char *fname)
 /*
  * Search for a defined option (defopt, filesystem, etc), and if found,
  * return the option's struct nvlist.
+ *
+ * This used to be one function (find_declared_option) before options
+ * and filesystems became different types.
  */
-struct nvlist *
-find_declared_option(const char *name)
+static struct defoptlist *
+find_declared_option_option(const char *name)
 {
-	struct nvlist *option = NULL;
+	struct defoptlist *option;
 
-	if ((option = nvhash_lookup(defopttab, name)) != NULL ||
-	    (option = nvhash_lookup(defparamtab, name)) != NULL ||
-	    (option = nvhash_lookup(defflagtab, name)) != NULL ||
-	    (option = nvhash_lookup(deffstab, name)) != NULL) {
+	if ((option = dlhash_lookup(defopttab, name)) != NULL ||
+	    (option = dlhash_lookup(defparamtab, name)) != NULL ||
+	    (option = dlhash_lookup(defflagtab, name)) != NULL) {
 		return (option);
 	}
 
 	return (NULL);
 }
 
+static struct nvlist *
+find_declared_fs_option(const char *name)
+{
+	struct nvlist *fs;
+
+	if ((fs = nvhash_lookup(deffstab, name)) != NULL) {
+		return fs;
+	}
+
+	return (NULL);
+}
+
+/*
+ * Like find_declared_option but doesn't return what it finds, so it
+ * can search both the various kinds of options and also filesystems.
+ */
+int
+is_declared_option(const char *name)
+{
+	struct defoptlist *option = NULL;
+	struct nvlist *fs;
+
+	if ((option = dlhash_lookup(defopttab, name)) != NULL ||
+	    (option = dlhash_lookup(defparamtab, name)) != NULL ||
+	    (option = dlhash_lookup(defflagtab, name)) != NULL) {
+		return 1;
+	}
+	if ((fs = nvhash_lookup(deffstab, name)) != NULL) {
+		return 1;
+	}
+
+	return 0;
+}
 
 /*
  * Define one or more standard options.  If an option file name is specified,
@@ -686,10 +751,10 @@ find_declared_option(const char *name)
  * record the option information in the specified table.
  */
 void
-defopt(struct nvhash *ht, const char *fname, struct nvlist *opts,
+defopt(struct dlhash *ht, const char *fname, struct defoptlist *opts,
        struct nvlist *deps, int obs)
 {
-	struct nvlist *nv, *nextnv, *oldnv;
+	struct defoptlist *dl, *nextdl, *olddl;
 	const char *name;
 	char buf[500];
 
@@ -700,32 +765,28 @@ defopt(struct nvhash *ht, const char *fn
 	/*
 	 * Mark these options as ones to skip when creating the Makefile.
 	 */
-	for (nv = opts; nv != NULL; nv = nextnv) {
-		nextnv = nv->nv_next;
+	for (dl = opts; dl != NULL; dl = nextdl) {
+		nextdl = dl->dl_next;
 
-		if (*(nv->nv_name) == '\0') {
-			if (nextnv == NULL)
-				panic("invalid option chain");
+		if (dl->dl_lintvalue != NULL) {
 			/*
 			 * If an entry already exists, then we are about to
 			 * complain, so no worry.
 			 */
-			(void) nvhash_insert(defoptlint, nextnv->nv_name,
-			    nv);
-			nv = nextnv;
-			nextnv = nextnv->nv_next;
+			(void) dlhash_insert(defoptlint, dl->dl_name,
+			    dl);
 		}
 
 		/* An option name can be declared at most once. */
-		if (DEFINED_OPTION(nv->nv_name)) {
+		if (DEFINED_OPTION(dl->dl_name)) {
 			cfgerror("file system or option `%s' already defined",
-			    nv->nv_name);
+			    dl->dl_name);
 			return;
 		}
 
-		if (nvhash_insert(ht, nv->nv_name, nv)) {
+		if (dlhash_insert(ht, dl->dl_name, dl)) {
 			cfgerror("file system or option `%s' already defined",
-			    nv->nv_name);
+			    dl->dl_name);
 			return;
 		}
 
@@ -737,26 +798,26 @@ defopt(struct nvhash *ht, const char *fn
 			 * file name.
 			 */
 			(void) snprintf(buf, sizeof(buf), "opt_%s.h",
-			    strtolower(nv->nv_name));
+			    strtolower(dl->dl_name));
 			name = intern(buf);
 		} else {
 			name = fname;
 		}
 
-		add_dependencies(nv, deps);
+		add_opt_dependencies(dl, deps);
 
 		/*
 		 * Remove this option from the parameter list before adding
 		 * it to the list associated with this option file.
 		 */
-		nv->nv_next = NULL;
+		dl->dl_next = NULL;
 
 		/*
 		 * Flag as obsolete, if requested.
 		 */
 		if (obs) {
-			nv->nv_flags |= NV_OBSOLETE;
-			(void)nvhash_insert(obsopttab, nv->nv_name, nv);
+			dl->dl_obsolete = 1;
+			(void)dlhash_insert(obsopttab, dl->dl_name, dl);
 		}
 
 		/*
@@ -764,12 +825,12 @@ defopt(struct nvhash *ht, const char *fn
 		 * Otherwise, append to the list of options already
 		 * associated with this file.
 		 */
-		if ((oldnv = nvhash_lookup(optfiletab, name)) == NULL) {
-			(void)nvhash_insert(optfiletab, name, nv);
+		if ((olddl = dlhash_lookup(optfiletab, name)) == NULL) {
+			(void)dlhash_insert(optfiletab, name, dl);
 		} else {
-			while (oldnv->nv_next != NULL)
-				oldnv = oldnv->nv_next;
-			oldnv->nv_next = nv;
+			while (olddl->dl_next != NULL)
+				olddl = olddl->dl_next;
+			olddl->dl_next = dl;
 		}
 	}
 }
@@ -780,7 +841,7 @@ defopt(struct nvhash *ht, const char *fn
  * an option file for each option.
  */
 void
-defoption(const char *fname, struct nvlist *opts, struct nvlist *deps)
+defoption(const char *fname, struct defoptlist *opts, struct nvlist *deps)
 {
 
 	cfgwarn("The use of `defopt' is deprecated");
@@ -792,7 +853,7 @@ defoption(const char *fname, struct nvli
  * Define an option for which a value is required. 
  */
 void
-defparam(const char *fname, struct nvlist *opts, struct nvlist *deps, int obs)
+defparam(const char *fname, struct defoptlist *opts, struct nvlist *deps, int obs)
 {
 
 	defopt(defparamtab, fname, opts, deps, obs);
@@ -803,7 +864,7 @@ defparam(const char *fname, struct nvlis
  * emits a "needs-flag" style output.
  */
 void
-defflag(const char *fname, struct nvlist *opts, struct nvlist *deps, int obs)
+defflag(const char *fname, struct defoptlist *opts, struct nvlist *deps, int obs)
 {
 
 	defopt(defflagtab, fname, opts, deps, obs);

Index: src/usr.bin/config/mkheaders.c
diff -u src/usr.bin/config/mkheaders.c:1.20 src/usr.bin/config/mkheaders.c:1.21
--- src/usr.bin/config/mkheaders.c:1.20	Mon Mar 12 00:20:30 2012
+++ src/usr.bin/config/mkheaders.c	Mon Mar 12 02:58:55 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: mkheaders.c,v 1.20 2012/03/12 00:20:30 dholland Exp $	*/
+/*	$NetBSD: mkheaders.c,v 1.21 2012/03/12 02:58:55 dholland Exp $	*/
 
 /*
  * Copyright (c) 1992, 1993
@@ -61,7 +61,7 @@ static int emitcnt(struct nvlist *);
 static int emitopts(void);
 static int emittime(void);
 static int herr(const char *, const char *, FILE *);
-static int defopts_print(const char *, struct nvlist *, void *);
+static int defopts_print(const char *, struct defoptlist *, void *);
 static char *cntname(const char *);
 
 /*
@@ -221,10 +221,11 @@ fprintstr(FILE *fp, const char *str)
  */
 static int
 /*ARGSUSED*/
-defopts_print(const char *name, struct nvlist *value, void *arg)
+defopts_print(const char *name, struct defoptlist *value, void *arg)
 {
 	char tfname[BUFSIZ];
-	struct nvlist *nv, *option;
+	struct nvlist *option;
+	struct defoptlist *dl;
 	const char *opt_value;
 	int isfsoption;
 	FILE *fp;
@@ -233,39 +234,39 @@ defopts_print(const char *name, struct n
 	if ((fp = fopen(tfname, "w")) == NULL)
 		return (herr("open", tfname, NULL));
 
-	for (nv = value; nv != NULL; nv = nv->nv_next) {
-		isfsoption = OPT_FSOPT(nv->nv_name);
+	for (dl = value; dl != NULL; dl = dl->dl_next) {
+		isfsoption = OPT_FSOPT(dl->dl_name);
 
-		if (nv->nv_flags & NV_OBSOLETE) {
+		if (dl->dl_obsolete) {
 			fprintf(fp, "/* %s `%s' is obsolete */\n",
 			    isfsoption ? "file system" : "option",
-			    nv->nv_name);
-			fprint_global(fp, nv->nv_name, 0xdeadbeef);
+			    dl->dl_name);
+			fprint_global(fp, dl->dl_name, 0xdeadbeef);
 			continue;
 		}
 
-		if (((option = ht_lookup(opttab, nv->nv_name)) == NULL &&
-		    (option = ht_lookup(fsopttab, nv->nv_name)) == NULL) &&
-		    (nv->nv_str == NULL)) {
+		if (((option = ht_lookup(opttab, dl->dl_name)) == NULL &&
+		    (option = ht_lookup(fsopttab, dl->dl_name)) == NULL) &&
+		    (dl->dl_value == NULL)) {
 			fprintf(fp, "/* %s `%s' not defined */\n",
 			    isfsoption ? "file system" : "option",
-			    nv->nv_name);
-			fprint_global(fp, nv->nv_name, UNDEFINED);
+			    dl->dl_name);
+			fprint_global(fp, dl->dl_name, UNDEFINED);
 			continue;
 		}
 
-		opt_value = option != NULL ? option->nv_str : nv->nv_str;
+		opt_value = option != NULL ? option->nv_str : dl->dl_value;
 		if (isfsoption == 1)
 			/* For filesysteme we'd output the lower case name */
 			opt_value = NULL;
 
-		fprintf(fp, "#define\t%s", nv->nv_name);
+		fprintf(fp, "#define\t%s", dl->dl_name);
 		if (opt_value != NULL)
 			fprintstr(fp, opt_value);
 		else if (!isfsoption)
 			fprintstr(fp, "1");
 		fputc('\n', fp);
-		fprint_global(fp, nv->nv_name,
+		fprint_global(fp, dl->dl_name,
 		    opt_value == NULL ? 1 : global_hash(opt_value));
 	}
 
@@ -286,7 +287,7 @@ static int
 emitopts(void)
 {
 
-	return (nvhash_enumerate(optfiletab, defopts_print, NULL));
+	return (dlhash_enumerate(optfiletab, defopts_print, NULL));
 }
 
 /*

Index: src/usr.bin/config/util.c
diff -u src/usr.bin/config/util.c:1.13 src/usr.bin/config/util.c:1.14
--- src/usr.bin/config/util.c:1.13	Sun Mar 11 21:16:08 2012
+++ src/usr.bin/config/util.c	Mon Mar 12 02:58:55 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: util.c,v 1.13 2012/03/11 21:16:08 dholland Exp $	*/
+/*	$NetBSD: util.c,v 1.14 2012/03/12 02:58:55 dholland Exp $	*/
 
 /*
  * Copyright (c) 1992, 1993
@@ -205,6 +205,57 @@ nvcat(struct nvlist *nv1, struct nvlist 
 }
 
 /*
+ * Option definition lists
+ */
+
+struct defoptlist *
+defoptlist_create(const char *name, const char *val, const char *lintval)
+{
+	struct defoptlist *dl;
+
+	dl = emalloc(sizeof(*dl));
+	dl->dl_next = NULL;
+	dl->dl_name = name;
+	dl->dl_value = val;
+	dl->dl_lintvalue = lintval;
+	dl->dl_obsolete = 0;
+	dl->dl_depends = NULL;
+	return dl;
+}
+
+void
+defoptlist_destroy(struct defoptlist *dl)
+{
+	struct defoptlist *next;
+
+	while (dl != NULL) {
+		next = dl->dl_next;
+		dl->dl_next = NULL;
+
+		// XXX should we assert that dl->dl_deps is null to
+		// be sure the deps have already been destroyed?
+		free(dl);
+
+		dl = next;
+	}
+}
+
+struct defoptlist *
+defoptlist_append(struct defoptlist *dla, struct defoptlist *dlb)
+{
+	struct defoptlist *dl;
+
+	if (dla == NULL)
+		return dlb;
+
+	for (dl = dla; dl->dl_next != NULL; dl = dl->dl_next)
+		;
+
+	dl->dl_next = dlb;
+	return dla;
+}
+
+/*
  * Locator lists
  */
 

Reply via email to