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.
This commit is contained in:
scottr 1998-06-10 04:33:31 +00:00
parent dbeb2648a6
commit e6eb7d0530
3 changed files with 93 additions and 42 deletions

View File

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

View File

@ -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 <str> fsoptfile_opt
%type <str> defopt
%type <list> defopts
%type <list> defoptdeps
%type <str> 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); };

View File

@ -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 <machine/foo.h>" 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;
}
}
}