diff --git a/usr.sbin/config/config.h b/usr.sbin/config/config.h index 1887c2238c65..6974b86a6faf 100644 --- a/usr.sbin/config/config.h +++ b/usr.sbin/config/config.h @@ -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 *, ...)); diff --git a/usr.sbin/config/gram.y b/usr.sbin/config/gram.y index f3e1a2fa0204..de476a9b2c31 100644 --- a/usr.sbin/config/gram.y +++ b/usr.sbin/config/gram.y @@ -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 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 diff --git a/usr.sbin/config/main.c b/usr.sbin/config/main.c index fc13570afc95..28eadd771b84 100644 --- a/usr.sbin/config/main.c +++ b/usr.sbin/config/main.c @@ -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; diff --git a/usr.sbin/config/mkheaders.c b/usr.sbin/config/mkheaders.c index 885610bd370d..dc708001bcee 100644 --- a/usr.sbin/config/mkheaders.c +++ b/usr.sbin/config/mkheaders.c @@ -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) diff --git a/usr.sbin/config/scan.l b/usr.sbin/config/scan.l index a8b4177442a3..2520fc8d0135 100644 --- a/usr.sbin/config/scan.l +++ b/usr.sbin/config/scan.l @@ -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; diff --git a/usr.sbin/config/util.c b/usr.sbin/config/util.c index 434895562401..62f49f0a0a07 100644 --- a/usr.sbin/config/util.c +++ b/usr.sbin/config/util.c @@ -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); +}