Stronger checking of options:

* machinery for nonfatal warnings.
* new backend config-file keywords:
     defparam -- like defopt, but each defparam option is required
		 to have a value when configured via "options".
     defflag -- like defopt, but defflag options may not have a value.
		 Also, on "option FOO",  a needs-count style flag
		 (NFOO, either 0 or 1)  is emitted to the .h file.

* Warn about old-style options that aren't defined via def{opt,param,flag}
  and which are  added to IDENT. (These behave subtly differently
  to defopt options when  no explicit value is given.)
This commit is contained in:
jonathan 1998-06-24 11:20:54 +00:00
parent dbe5213b11
commit 0925cf4fda
6 changed files with 198 additions and 32 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: config.h,v 1.38 1998/06/10 04:33:31 scottr Exp $ */
/* $NetBSD: config.h,v 1.39 1998/06/24 11:20:54 jonathan Exp $ */
/*
* Copyright (c) 1992, 1993
@ -309,6 +309,8 @@ struct hashtab *needcnttab; /* retains names marked "needs-count" */
struct hashtab *opttab; /* table of configured options */
struct hashtab *fsopttab; /* table of configured file systems */
struct hashtab *defopttab; /* options that have been "defopt"'d */
struct hashtab *defflagtab; /* options that have been "defflag"'d */
struct hashtab *defparamtab; /* options that have been "defparam"'d */
struct hashtab *deffstab; /* defined file systems */
struct hashtab *optfiletab; /* "defopt"'d option .h files */
struct hashtab *attrtab; /* attributes (locators, etc.) */
@ -362,6 +364,10 @@ 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,
struct nvlist *deps));
void defflag __P((const char *fname, struct nvlist *opts,
struct nvlist *deps));
void defparam __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));
@ -393,6 +399,7 @@ void initsem __P((void));
void *emalloc __P((size_t));
void *erealloc __P((void *, size_t));
char *sourcepath __P((const char *));
void warn __P((const char *, ...)); /* immediate warns */
void error __P((const char *, ...)); /* immediate errs */
void xerror __P((const char *, int, const char *, ...)); /* delayed errs */
__dead void panic __P((const char *, ...));

View File

@ -1,5 +1,5 @@
%{
/* $NetBSD: gram.y,v 1.23 1998/06/10 04:33:31 scottr Exp $ */
/* $NetBSD: gram.y,v 1.24 1998/06/24 11:20:54 jonathan Exp $ */
/*
* Copyright (c) 1992, 1993
@ -97,9 +97,9 @@ static void check_maxpart __P((void));
int val;
}
%token AND AT ATTACH BUILD COMPILE_WITH CONFIG DEFFS DEFINE DEFOPT DEVICE
%token DEVCLASS DUMPS ENDFILE XFILE XOBJECT FILE_SYSTEM FLAGS INCLUDE
%token XMACHINE MAJOR MAKEOPTIONS
%token AND AT ATTACH BUILD COMPILE_WITH CONFIG DEFFS DEFINE DEFOPT
%token DEFPARAM DEFFLAG DEVICE DEVCLASS DUMPS ENDFILE XFILE XOBJECT
%token FILE_SYSTEM FLAGS INCLUDE XMACHINE MAJOR MAKEOPTIONS
%token MAXUSERS MAXPARTITIONS MINOR ON OPTIONS PSEUDO_DEVICE ROOT SOURCE
%token TYPE WITH NEEDS_COUNT NEEDS_FLAG
%token <val> NUMBER
@ -241,6 +241,10 @@ one_def:
DEFINE WORD interface_opt { (void)defattr($2, $3, 0); } |
DEFOPT optfile_opt defopts defoptdeps
{ defoption($2, $3, $4); } |
DEFFLAG optfile_opt defopts defoptdeps
{ defflag($2, $3, $4); } |
DEFPARAM optfile_opt defopts defoptdeps
{ defparam($2, $3, $4); } |
DEVICE devbase interface_opt attrs_opt
{ defdev($2, $3, $4, 0); } |
ATTACH devbase AT atlist devattach_opt attrs_opt

View File

@ -1,4 +1,4 @@
/* $NetBSD: main.c,v 1.33 1998/06/10 04:33:31 scottr Exp $ */
/* $NetBSD: main.c,v 1.34 1998/06/24 11:20:54 jonathan Exp $ */
/*
* Copyright (c) 1992, 1993
@ -88,6 +88,10 @@ static int mksymlinks __P((void));
static int hasparent __P((struct devi *));
static int cfcrosscheck __P((struct config *, const char *,
struct nvlist *));
void defopt __P((struct hashtab *ht, const char *fname,
struct nvlist *opts, struct nvlist *deps));
int badfilename __P((const char *fname));
int
main(argc, argv)
@ -177,6 +181,8 @@ usage:
fsopttab = ht_new();
deffstab = ht_new();
defopttab = ht_new();
defparamtab = ht_new();
defflagtab = ht_new();
optfiletab = ht_new();
nextopt = &options;
nextmkopt = &mkoptions;
@ -390,13 +396,40 @@ deffilesystem(fname, fses)
}
}
/*
* Sanity check a file name.
*/
int
badfilename(fname)
const char *fname;
{
const char *n;
/*
* We're putting multiple options into one file. Sanity
* check the file name.
*/
if (strchr(fname, '/') != NULL) {
error("option file name contains a `/'");
return 1;
}
if ((n = strrchr(fname, '.')) == NULL || strcmp(n, ".h") != 0) {
error("option file name does not end in `.h'");
return 1;
}
return 0;
}
/*
* Define one or more standard options. If an option file name is specified,
* place all options in one file with the specified name. Otherwise, create
* an option file for each option.
* record the option information in the specified table.
*/
void
defoption(fname, opts, deps)
defopt(ht, fname, opts, deps)
struct hashtab *ht;
const char *fname;
struct nvlist *opts, *deps;
{
@ -405,19 +438,8 @@ defoption(fname, opts, deps)
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;
}
if (fname != NULL && badfilename(fname)) {
return;
}
/*
@ -425,7 +447,7 @@ defoption(fname, opts, deps)
*/
for (nv = opts; nv != NULL; nv = nextnv) {
nextnv = nv->nv_next;
if (ht_insert(defopttab, nv->nv_name, nv)) {
if (ht_insert(ht, nv->nv_name, nv)) {
error("file system or option `%s' already defined",
nv->nv_name);
return;
@ -474,6 +496,44 @@ defoption(fname, opts, deps)
}
}
/*
* Define one or more standard options. If an option file name is specified,
* place all options in one file with the specified name. Otherwise, create
* an option file for each option.
*/
void
defoption(fname, opts, deps)
const char *fname;
struct nvlist *opts, *deps;
{
defopt(defopttab, fname, opts, deps);
}
/*
* Define an option for which a value is required.
*/
void
defparam(fname, opts, deps)
const char *fname;
struct nvlist *opts, *deps;
{
defopt(defparamtab, fname, opts, deps);
}
/*
* Define an option which must have a value, and which
* emits a "needs-flag" style output.
*/
void
defflag(fname, opts, deps)
const char *fname;
struct nvlist *opts, *deps;
{
defopt(defflagtab, fname, opts, deps);
}
/*
* Add an option from "options FOO". Note that this selects things that
* are "optional foo".
@ -485,12 +545,38 @@ addoption(name, value)
const char *n;
char *p, c;
char low[500];
int is_fs, is_param, is_flag, is_opt, is_undecl;
/*
* Figure out how this option was declared (if at all.)
* XXX should use "params" and "flags" in config.
* XXX crying out for a type field in a unified hashtab.
*/
is_fs = ht_lookup(deffstab, name) != NULL;
is_param = ht_lookup(defparamtab, name) != NULL;
is_opt = ht_lookup(defopttab, name) != NULL;
is_flag = ht_lookup(defflagtab, name) != NULL;
is_undecl = (!is_param && !is_flag && !is_fs && !is_opt);
/* Make sure this is not a defined file system. */
if (ht_lookup(deffstab, name) != NULL) {
if (is_fs) {
error("`%s' is a defined file system", name);
return;
}
/* A defparam must have a value */
if (is_param && value == NULL) {
error("option `%s' must have a value", name);
return;
}
/* A defflag must not have a value */
if (is_flag && value != NULL) {
error("option `%s' must not have a value", name);
return;
}
if (is_undecl) {
warn("undeclared option `%s' added to IDENT", name);
}
if (do_option(opttab, &nextopt, name, value, "options"))
return;

View File

@ -1,4 +1,4 @@
/* $NetBSD: mkheaders.c,v 1.18 1998/02/19 06:13:51 thorpej Exp $ */
/* $NetBSD: mkheaders.c,v 1.19 1998/06/24 11:20:55 jonathan Exp $ */
/*
* Copyright (c) 1992, 1993
@ -61,6 +61,7 @@ static int locators_print __P((const char *, void *, void *));
static int defopts_print __P((const char *, void *, void *));
static char *cntname __P((const char *));
static int cmphdr __P((const char *, const char *));
static int fprintcnt(FILE *fp, struct nvlist *nv);
/*
@ -88,6 +89,16 @@ mkheaders()
return (0);
}
static int
fprintcnt(fp, nv)
FILE *fp;
struct nvlist *nv;
{
return (fprintf(fp, "#define\t%s\t%d\n",
cntname(nv->nv_name), nv->nv_int));
}
static int
emitcnt(head)
struct nvlist *head;
@ -106,8 +117,7 @@ emitcnt(head)
}
for (nv = head; nv != NULL; nv = nv->nv_next)
if (fprintf(fp, "#define\t%s\t%d\n",
cntname(nv->nv_name), nv->nv_int) < 0)
if (fprintcnt(fp, nv) < 0)
return (err("writ", tfname, fp));
if (fclose(fp) == EOF)
@ -128,6 +138,8 @@ defopts_print(name, value, arg)
char tfname[BUFSIZ];
struct nvlist *nv, *option;
int isfsoption;
int isparam;
int isflag;
FILE *fp;
(void)sprintf(tfname, "tmp_%s", name);
@ -139,6 +151,8 @@ defopts_print(name, value, arg)
for (nv = value; nv != NULL; nv = nv->nv_next) {
isfsoption = (ht_lookup(deffstab, nv->nv_name) != NULL);
isparam = (ht_lookup(defparamtab, nv->nv_name) != NULL);
isflag = (ht_lookup(defflagtab, nv->nv_name) != NULL);
if ((option = ht_lookup(opttab, nv->nv_name)) == NULL &&
(option = ht_lookup(fsopttab, nv->nv_name)) == NULL) {
@ -155,6 +169,9 @@ defopts_print(name, value, arg)
if (fputc('\n', fp) < 0)
goto bad;
}
if (isflag)
fprintcnt(fp, nv);
}
if (fclose(fp) == EOF)

View File

@ -1,5 +1,5 @@
%{
/* $NetBSD: scan.l,v 1.21 1998/04/09 00:32:39 tv Exp $ */
/* $NetBSD: scan.l,v 1.22 1998/06/24 11:20:55 jonathan Exp $ */
/*
* Copyright (c) 1992, 1993
@ -90,7 +90,9 @@ compile-with return COMPILE_WITH;
config return CONFIG;
deffs return DEFFS;
define return DEFINE;
defflag return DEFFLAG;
defopt return DEFOPT;
defparam return DEFPARAM;
devclass return DEVCLASS;
device return DEVICE;
dumps return DUMPS;

View File

@ -1,4 +1,4 @@
/* $NetBSD: util.c,v 1.6 1997/10/18 07:59:38 lukem Exp $ */
/* $NetBSD: util.c,v 1.7 1998/06/24 11:20:55 jonathan Exp $ */
/*
* Copyright (c) 1992, 1993
@ -58,6 +58,9 @@
static void nomem __P((void));
static void vxerror __P((const char *, int, const char *, va_list));
static void vxwarn __P((const char *, int, const char *, va_list));
static void vxmsg __P((const char *fname, int line, const char *class,
const char *fmt, va_list));
/*
* Malloc, with abort on error.
@ -165,6 +168,38 @@ nvfreel(nv)
}
}
void
#if __STDC__
warn(const char *fmt, ...)
#else
warn(fmt, va_alist)
const char *fmt;
va_dcl
#endif
{
va_list ap;
extern const char *yyfile;
#if __STDC__
va_start(ap, fmt);
#else
va_start(ap);
#endif
vxwarn(yyfile, currentline(), fmt, ap);
va_end(ap);
}
static void
vxwarn(file, line, fmt, ap)
const char *file;
int line;
const char *fmt;
va_list ap;
{
vxmsg(file, line, "warning: ", fmt, ap);
}
/*
* External (config file) error. Complain, using current file
* and line number.
@ -176,7 +211,7 @@ error(const char *fmt, ...)
error(fmt, va_alist)
const char *fmt;
va_dcl
#endif
#endif /* __STDC__ */
{
va_list ap;
extern const char *yyfile;
@ -226,13 +261,11 @@ vxerror(file, line, fmt, ap)
const char *fmt;
va_list ap;
{
(void)fprintf(stderr, "%s:%d: ", file, line);
(void)vfprintf(stderr, fmt, ap);
(void)putc('\n', stderr);
vxmsg(file, line, "", fmt, ap);
errors++;
}
/*
* Internal error, abort.
*/
@ -258,3 +291,20 @@ panic(fmt, va_alist)
va_end(ap);
exit(2);
}
/*
* Internal form of error() and xerror().
*/
static void
vxmsg(file, line, msgclass, fmt, ap)
const char *file;
int line;
const char *msgclass;
const char *fmt;
va_list ap;
{
(void)fprintf(stderr, "%s:%d: %s", file, line, msgclass);
(void)vfprintf(stderr, fmt, ap);
(void)putc('\n', stderr);
}