From e6eb7d053021a93928eb545df83fe0f349ef0d50 Mon Sep 17 00:00:00 2001 From: scottr Date: Wed, 10 Jun 1998 04:33:31 +0000 Subject: [PATCH] Implement option dependencies as part of the defopt action. We currently restrict depended-on (or "implied") options to those that have been previously defopt'ed, which inherently eliminates any cycles in the option graph. --- usr.sbin/config/config.h | 5 +- usr.sbin/config/gram.y | 10 +++- usr.sbin/config/main.c | 120 ++++++++++++++++++++++++++------------- 3 files changed, 93 insertions(+), 42 deletions(-) diff --git a/usr.sbin/config/config.h b/usr.sbin/config/config.h index 731712ffaf07..1887c2238c65 100644 --- a/usr.sbin/config/config.h +++ b/usr.sbin/config/config.h @@ -1,4 +1,4 @@ -/* $NetBSD: config.h,v 1.37 1998/02/19 00:27:00 thorpej Exp $ */ +/* $NetBSD: config.h,v 1.38 1998/06/10 04:33:31 scottr Exp $ */ /* * Copyright (c) 1992, 1993 @@ -360,7 +360,8 @@ void addoption __P((const char *name, const char *value)); void addfsoption __P((const char *name)); void addmkoption __P((const char *name, const char *value)); void deffilesystem __P((const char *fname, struct nvlist *fses)); -void defoption __P((const char *fname, struct nvlist *opts)); +void defoption __P((const char *fname, struct nvlist *opts, + struct nvlist *deps)); int devbase_has_instances __P((struct devbase *, int)); int deva_has_instances __P((struct deva *, int)); void setupdirs __P((void)); diff --git a/usr.sbin/config/gram.y b/usr.sbin/config/gram.y index 7b80db851774..f3e1a2fa0204 100644 --- a/usr.sbin/config/gram.y +++ b/usr.sbin/config/gram.y @@ -1,5 +1,5 @@ %{ -/* $NetBSD: gram.y,v 1.22 1998/02/19 00:27:01 thorpej Exp $ */ +/* $NetBSD: gram.y,v 1.23 1998/06/10 04:33:31 scottr Exp $ */ /* * Copyright (c) 1992, 1993 @@ -132,6 +132,7 @@ static void check_maxpart __P((void)); %type fsoptfile_opt %type defopt %type defopts +%type defoptdeps %type optfile_opt %% @@ -238,7 +239,8 @@ one_def: DEVCLASS WORD { (void)defattr($2, NULL, 1); } | DEFFS fsoptfile_opt deffses { deffilesystem($2, $3); } | DEFINE WORD interface_opt { (void)defattr($2, $3, 0); } | - DEFOPT optfile_opt defopts { defoption($2, $3); } | + DEFOPT optfile_opt defopts defoptdeps + { defoption($2, $3, $4); } | DEVICE devbase interface_opt attrs_opt { defdev($2, $3, $4, 0); } | ATTACH devbase AT atlist devattach_opt attrs_opt @@ -263,6 +265,10 @@ deffses: deffs: WORD { $$ = $1; }; +defoptdeps: + ':' defopts { $$ = $2; } | + /* empty */ { $$ = NULL; }; + defopts: defopts defopt { $$ = new_nx($2, $1); } | defopt { $$ = new_n($1); }; diff --git a/usr.sbin/config/main.c b/usr.sbin/config/main.c index c96bc451e049..fc13570afc95 100644 --- a/usr.sbin/config/main.c +++ b/usr.sbin/config/main.c @@ -1,4 +1,4 @@ -/* $NetBSD: main.c,v 1.32 1998/05/22 19:29:00 tv Exp $ */ +/* $NetBSD: main.c,v 1.33 1998/06/10 04:33:31 scottr Exp $ */ /* * Copyright (c) 1992, 1993 @@ -76,6 +76,8 @@ static struct nvlist **nextopt; static struct nvlist **nextmkopt; static struct nvlist **nextfsopt; +static void dependopts __P((void)); +static void do_depend __P((struct nvlist *)); static void stop __P((void)); static int do_option __P((struct hashtab *, struct nvlist ***, const char *, const char *, const char *)); @@ -203,6 +205,11 @@ usage: if (yyparse()) stop(); + /* + * Deal with option dependencies. + */ + dependopts(); + /* * Fix (as in `set firmly in place') files. */ @@ -255,6 +262,39 @@ usage: exit(0); } +/* + * Set any options that are implied by other options. + */ +static void +dependopts() +{ + struct nvlist *nv, *opt; + + for (nv = options; nv != NULL; nv = nv->nv_next) { + if ((opt = ht_lookup(defopttab, nv->nv_name)) != NULL) { + for (opt = opt->nv_ptr; opt != NULL; + opt = opt->nv_next) { + do_depend(opt); + } + } + } +} + +static void +do_depend(nv) + struct nvlist *nv; +{ + struct nvlist *nextnv; + + if (nv != NULL) { + if (ht_lookup(opttab, nv->nv_name) == NULL) + addoption(nv->nv_name, NULL); + if ((nextnv = ht_lookup(defopttab, nv->nv_name)) != NULL) + do_depend(nextnv->nv_ptr); + } + +} + /* * Make a symlink for "machine" so that "#include " works, * and for the machine's CPU architecture, so that works as well. @@ -356,15 +396,30 @@ deffilesystem(fname, fses) * an option file for each option. */ void -defoption(fname, opts) +defoption(fname, opts, deps) const char *fname; - struct nvlist *opts; + struct nvlist *opts, *deps; { - struct nvlist *nv, *nextnv; - const char *n; + struct nvlist *nv, *nextnv, *oldnv; + const char *name, *n; char *p, c; char low[500]; + if (fname != NULL) { + /* + * We're putting multiple options into one file. Sanity + * check the file name. + */ + if (strchr(fname, '/') != NULL) { + error("option file name contains a `/'"); + return; + } + if ((n = strrchr(fname, '.')) == NULL || strcmp(n, ".h") != 0) { + error("option file name does not end in `.h'"); + return; + } + } + /* * Mark these options as ones to skip when creating the Makefile. */ @@ -390,43 +445,32 @@ defoption(fname, opts) *p = '\0'; strcat(low, ".h"); - n = intern(low); - - /* - * This is the only option in the file, so remove - * it from the list. - */ - nv->nv_next = NULL; - - if (ht_insert(optfiletab, n, nv)) { - error("option file `%s' already exists", n); - return; - } + name = intern(low); + } else { + name = fname; } - } - /* - * No more to do if no option file name was specified. - */ - if (fname == NULL) - return; + /* Use nv_ptr to link any other options that are implied. */ + nv->nv_ptr = deps; - /* - * We're putting multiple options into one file. Sanity - * check the file name. - */ - if (strchr(fname, '/') != NULL) { - error("option file name contains a `/'"); - return; - } - if ((n = strrchr(fname, '.')) == NULL || strcmp(n, ".h") != 0) { - error("option file name does not end in `.h'"); - return; - } + /* + * Remove this option from the parameter list before adding + * it to the list associated with this option file. + */ + nv->nv_next = NULL; - if (ht_insert(optfiletab, fname, opts)) { - error("option file `%s' already exists", fname); - return; + /* + * Add this option file if we haven't seen it yet. + * Otherwise, append to the list of options already + * associated with this file. + */ + if ((oldnv = ht_lookup(optfiletab, name)) == NULL) { + (void)ht_insert(optfiletab, name, nv); + } else { + while (oldnv->nv_next != NULL) + oldnv = oldnv->nv_next; + oldnv->nv_next = nv; + } } }