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:
parent
dbe5213b11
commit
0925cf4fda
@ -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 *, ...));
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user