Module Name: src Committed By: martin Date: Mon Mar 9 15:22:21 UTC 2020
Modified Files: src/usr.bin/config [netbsd-9]: TODO defs.h files.c gram.y main.c scan.l sem.c util.c Log Message: Pull up the following, requested by christos in ticket #776: usr.bin/config/TODO up to 1.32 usr.bin/config/defs.h up to 1.105 usr.bin/config/files.c up to 1.37 usr.bin/config/gram.y up to 1.55 usr.bin/config/main.c up to 1.99 usr.bin/config/scan.l up to 1.30 usr.bin/config/sem.c up to 1.84 usr.bin/config/util.c up to 1.21 config(1): fix issue with incorrect handling of elifdef statements. To generate a diff of this commit: cvs rdiff -u -r1.31 -r1.31.18.1 src/usr.bin/config/TODO cvs rdiff -u -r1.104 -r1.104.2.1 src/usr.bin/config/defs.h cvs rdiff -u -r1.36 -r1.36.16.1 src/usr.bin/config/files.c cvs rdiff -u -r1.54 -r1.54.16.1 src/usr.bin/config/gram.y cvs rdiff -u -r1.98 -r1.98.2.1 src/usr.bin/config/main.c cvs rdiff -u -r1.26 -r1.26.16.1 src/usr.bin/config/scan.l cvs rdiff -u -r1.83 -r1.83.4.1 src/usr.bin/config/sem.c cvs rdiff -u -r1.20 -r1.20.18.1 src/usr.bin/config/util.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/usr.bin/config/TODO diff -u src/usr.bin/config/TODO:1.31 src/usr.bin/config/TODO:1.31.18.1 --- src/usr.bin/config/TODO:1.31 Sun Nov 22 01:20:36 2015 +++ src/usr.bin/config/TODO Mon Mar 9 15:22:21 2020 @@ -259,7 +259,7 @@ o Control ELF sections using linker scri *.ko ---> *.ro Modular MI linkage *.ro ---> *.kmod Modular MD linkage - Genric MI linkage is for processing MI linkage that can be applied generally. + Generic MI linkage is for processing MI linkage that can be applied generally. Data section alignment (.data.read_mostly and .data.cacheline_aligned) is processed here. Index: src/usr.bin/config/defs.h diff -u src/usr.bin/config/defs.h:1.104 src/usr.bin/config/defs.h:1.104.2.1 --- src/usr.bin/config/defs.h:1.104 Mon Aug 27 16:04:45 2018 +++ src/usr.bin/config/defs.h Mon Mar 9 15:22:21 2020 @@ -1,4 +1,4 @@ -/* $NetBSD: defs.h,v 1.104 2018/08/27 16:04:45 riastradh Exp $ */ +/* $NetBSD: defs.h,v 1.104.2.1 2020/03/09 15:22:21 martin Exp $ */ /* * Copyright (c) 1992, 1993 @@ -110,6 +110,10 @@ extern const char *progname; #define CONFIG_VERSION 20180827 #define CONFIG_MINVERSION 0 +struct where { + const char *w_srcfile; /* file name where we are defined */ + u_short w_srcline; /* line number where we are defined */ +}; /* * Name/value lists. Values can be strings or pointers and/or can carry * integers. The names can be NULL, resulting in simple value lists. @@ -123,6 +127,7 @@ struct nvlist { int nv_ifunit; /* XXX XXX XXX */ int nv_flags; #define NV_DEPENDED 1 + struct where nv_where; }; /* @@ -131,10 +136,10 @@ struct nvlist { struct config { TAILQ_ENTRY(config) cf_next; const char *cf_name; /* "netbsd" */ - int cf_lineno; /* source line */ const char *cf_fstype; /* file system type */ struct nvlist *cf_root; /* "root on ra0a" */ struct nvlist *cf_dump; /* "dumps on ra0b" */ + struct where cf_where; }; /* @@ -147,6 +152,7 @@ struct defoptlist { const char *dl_lintvalue; int dl_obsolete; struct nvlist *dl_depends; + struct where dl_where; }; struct files; @@ -199,6 +205,7 @@ struct attr { /* "device class" */ const char *a_devclass; /* device class described */ + struct where a_where; }; /* @@ -277,8 +284,7 @@ struct devbase { struct deva *d_ahead; /* first attachment, if any */ struct deva **d_app; /* used for tacking on attachments */ struct attr *d_classattr; /* device class attribute (if any) */ - const char *d_srcfile; /* file name where we are defined */ - u_short d_srcline; /* line number where we are defined */ + struct where d_where; }; struct deva { @@ -291,8 +297,7 @@ struct deva { struct attrlist *d_attrs; /* attributes, if any */ struct devi *d_ihead; /* first instance, if any */ struct devi **d_ipp; /* used for tacking on more instances */ - const char *d_srcfile; /* file name where we are defined */ - u_short d_srcline; /* line number where we are defined */ + struct where d_where; }; /* @@ -319,8 +324,6 @@ struct devi { struct deva *i_atdeva; const char **i_locs; /* locators (as given by pspec's iattr) */ int i_cfflags; /* flags from config line */ - int i_lineno; /* line # in config, for later errors */ - const char *i_srcfile; /* file it appears in */ int i_level; /* position between negated instances */ int i_active; #define DEVI_ORPHAN 0 /* instance has no active parent */ @@ -333,7 +336,7 @@ struct devi { short i_collapsed; /* set => this alias no longer needed */ u_short i_cfindex; /* our index in cfdata */ int i_locoff; /* offset in locators.vec */ - + struct where i_where; }; /* special units */ #define STAR (-1) /* unit number for, e.g., "sd*" */ @@ -346,8 +349,7 @@ struct devi { struct files { TAILQ_ENTRY(files) fi_next; TAILQ_ENTRY(files) fi_snext; /* per-suffix list */ - const char *fi_srcfile; /* the name of the "files" file that got us */ - u_short fi_srcline; /* and the line number */ + struct where fi_where; u_char fi_flags; /* as below */ const char *fi_tail; /* name, i.e., strrchr(fi_path, '/') + 1 */ const char *fi_base; /* tail minus ".c" (or whatever) */ @@ -418,13 +420,12 @@ struct prefix { */ struct devm { TAILQ_ENTRY(devm) dm_next; - const char *dm_srcfile; /* the name of the "majors" file */ - u_short dm_srcline; /* the line number */ const char *dm_name; /* [bc]devsw name */ devmajor_t dm_cmajor; /* character major */ devmajor_t dm_bmajor; /* block major */ struct condexpr *dm_opts; /* options */ struct nvlist *dm_devnodes; /* information on /dev nodes */ + struct where dm_where; }; /* @@ -581,7 +582,7 @@ void deloption(const char *, int); void delfsoption(const char *, int); void delmkoption(const char *, int); int devbase_has_instances(struct devbase *, int); -int is_declared_option(const char *); +struct where *find_declared_option(const char *); int deva_has_instances(struct deva *, int); void setupdirs(void); void fixmaxusers(void); @@ -594,7 +595,7 @@ const char *strtolower(const char *); #define OPT_DEFFLAG(n) (dlhash_lookup(defflagtab, (n)) != NULL) #define OPT_DEFPARAM(n) (dlhash_lookup(defparamtab, (n)) != NULL) #define OPT_OBSOLETE(n) (dlhash_lookup(obsopttab, (n)) != NULL) -#define DEFINED_OPTION(n) (is_declared_option((n))) +#define DEFINED_OPTION(n) (find_declared_option((n))) /* main.c */ void logconfig_include(FILE *, const char *); Index: src/usr.bin/config/files.c diff -u src/usr.bin/config/files.c:1.36 src/usr.bin/config/files.c:1.36.16.1 --- src/usr.bin/config/files.c:1.36 Fri Sep 9 21:09:11 2016 +++ src/usr.bin/config/files.c Mon Mar 9 15:22:21 2020 @@ -1,4 +1,4 @@ -/* $NetBSD: files.c,v 1.36 2016/09/09 21:09:11 christos Exp $ */ +/* $NetBSD: files.c,v 1.36.16.1 2020/03/09 15:22:21 martin Exp $ */ /* * Copyright (c) 1992, 1993 @@ -45,7 +45,7 @@ #endif #include <sys/cdefs.h> -__RCSID("$NetBSD: files.c,v 1.36 2016/09/09 21:09:11 christos Exp $"); +__RCSID("$NetBSD: files.c,v 1.36.16.1 2020/03/09 15:22:21 martin Exp $"); #include <sys/param.h> #include <assert.h> @@ -158,19 +158,19 @@ addfile(const char *path, struct condexp * options for specific files. */ if (rule != NULL && optx == NULL && flags == 0 && - yyfile != fi->fi_srcfile) { + yyfile != fi->fi_where.w_srcfile) { fi->fi_mkrule = rule; return; } cfgerror("duplicate file %s", path); - cfgxerror(fi->fi_srcfile, fi->fi_srcline, + cfgxerror(fi->fi_where.w_srcfile, fi->fi_where.w_srcline, "here is the original definition"); goto bad; } memcpy(base, tail, baselen); base[baselen] = '\0'; - fi->fi_srcfile = yyfile; - fi->fi_srcline = currentline(); + fi->fi_where.w_srcfile = yyfile; + fi->fi_where.w_srcline = currentline(); fi->fi_flags = flags; fi->fi_path = path; fi->fi_tail = tail; @@ -204,7 +204,7 @@ addfile(const char *path, struct condexp TAILQ_INSERT_TAIL(&allfiles, fi, fi_next); break; default: - cfgxerror(fi->fi_srcfile, fi->fi_srcline, + cfgxerror(fi->fi_where.w_srcfile, fi->fi_where.w_srcline, "unknown suffix"); break; } @@ -262,7 +262,7 @@ checkaux(const char *name, void *context struct files *fi = context; if (ht_lookup(devbasetab, name) == NULL) { - cfgxerror(fi->fi_srcfile, fi->fi_srcline, + cfgxerror(fi->fi_where.w_srcfile, fi->fi_where.w_srcline, "`%s' is not a countable device", name); /* keep fixfiles() from complaining again */ @@ -356,10 +356,10 @@ fixfiles(void) ofi->fi_flags &= (u_char)~FI_SEL; ofi->fi_flags |= FI_HIDDEN; } else { - cfgxerror(fi->fi_srcfile, fi->fi_srcline, + cfgxerror(fi->fi_where.w_srcfile, fi->fi_where.w_srcline, "object file collision on %s.o, from %s", fi->fi_base, fi->fi_path); - cfgxerror(ofi->fi_srcfile, ofi->fi_srcline, + cfgxerror(ofi->fi_where.w_srcfile, ofi->fi_where.w_srcline, "here is the previous file: %s", ofi->fi_path); err = 1; @@ -412,22 +412,25 @@ fixdevsw(void) if (res != NULL) { if (res->dm_cmajor != dm->dm_cmajor || res->dm_bmajor != dm->dm_bmajor) { - cfgxerror(res->dm_srcfile, res->dm_srcline, - "device-major '%s' " - "block %d, char %d redefined" - " at %s:%d as block %d, char %d", - res->dm_name, - res->dm_bmajor, res->dm_cmajor, - dm->dm_srcfile, dm->dm_srcline, - dm->dm_bmajor, dm->dm_cmajor); + cfgxerror(res->dm_where.w_srcfile, + res->dm_where.w_srcline, + "device-major '%s' " + "block %d, char %d redefined" + " at %s:%d as block %d, char %d", + res->dm_name, + res->dm_bmajor, res->dm_cmajor, + dm->dm_where.w_srcfile, dm->dm_where.w_srcline, + dm->dm_bmajor, dm->dm_cmajor); } else { - cfgxerror(res->dm_srcfile, res->dm_srcline, - "device-major '%s' " - "(block %d, char %d) duplicated" - " at %s:%d", - dm->dm_name, dm->dm_bmajor, - dm->dm_cmajor, - dm->dm_srcfile, dm->dm_srcline); + cfgxerror(res->dm_where.w_srcfile, + res->dm_where.w_srcline, + "device-major '%s' " + "(block %d, char %d) duplicated" + " at %s:%d", + dm->dm_name, dm->dm_bmajor, + dm->dm_cmajor, + dm->dm_where.w_srcfile, + dm->dm_where.w_srcline); } error = 1; goto out; @@ -443,15 +446,16 @@ fixdevsw(void) if (dm->dm_cmajor != NODEVMAJOR) { if (ht_lookup(cdevmtab, intern(dm->dm_name)) != NULL) { - cfgxerror(dm->dm_srcfile, dm->dm_srcline, - "device-major of character device '%s' " - "is already defined", dm->dm_name); + cfgxerror(dm->dm_where.w_srcfile, + dm->dm_where.w_srcline, + "device-major of character device '%s' " + "is already defined", dm->dm_name); error = 1; goto out; } (void)snprintf(mstr, sizeof(mstr), "%d", dm->dm_cmajor); if (ht_lookup(cdevmtab, intern(mstr)) != NULL) { - cfgxerror(dm->dm_srcfile, dm->dm_srcline, + cfgxerror(dm->dm_where.w_srcfile, dm->dm_where.w_srcline, "device-major of character major '%d' " "is already defined", dm->dm_cmajor); error = 1; @@ -465,7 +469,7 @@ fixdevsw(void) } if (dm->dm_bmajor != NODEVMAJOR) { if (ht_lookup(bdevmtab, intern(dm->dm_name)) != NULL) { - cfgxerror(dm->dm_srcfile, dm->dm_srcline, + cfgxerror(dm->dm_where.w_srcfile, dm->dm_where.w_srcline, "device-major of block device '%s' " "is already defined", dm->dm_name); error = 1; @@ -473,7 +477,7 @@ fixdevsw(void) } (void)snprintf(mstr, sizeof(mstr), "%d", dm->dm_bmajor); if (ht_lookup(bdevmtab, intern(mstr)) != NULL) { - cfgxerror(dm->dm_srcfile, dm->dm_srcline, + cfgxerror(dm->dm_where.w_srcfile, dm->dm_where.w_srcline, "device-major of block major '%d' " "is already defined", dm->dm_bmajor); error = 1; Index: src/usr.bin/config/gram.y diff -u src/usr.bin/config/gram.y:1.54 src/usr.bin/config/gram.y:1.54.16.1 --- src/usr.bin/config/gram.y:1.54 Sun Aug 7 10:37:24 2016 +++ src/usr.bin/config/gram.y Mon Mar 9 15:22:21 2020 @@ -1,5 +1,5 @@ %{ -/* $NetBSD: gram.y,v 1.54 2016/08/07 10:37:24 christos Exp $ */ +/* $NetBSD: gram.y,v 1.54.16.1 2020/03/09 15:22:21 martin Exp $ */ /* * Copyright (c) 1992, 1993 @@ -42,7 +42,7 @@ */ #include <sys/cdefs.h> -__RCSID("$NetBSD: gram.y,v 1.54 2016/08/07 10:37:24 christos Exp $"); +__RCSID("$NetBSD: gram.y,v 1.54.16.1 2020/03/09 15:22:21 martin Exp $"); #include <sys/types.h> #include <sys/param.h> @@ -898,7 +898,7 @@ no_option: conf: WORD { conf.cf_name = $1; - conf.cf_lineno = currentline(); + conf.cf_where.w_srcline = currentline(); conf.cf_fstype = NULL; conf.cf_root = NULL; conf.cf_dump = NULL; Index: src/usr.bin/config/main.c diff -u src/usr.bin/config/main.c:1.98 src/usr.bin/config/main.c:1.98.2.1 --- src/usr.bin/config/main.c:1.98 Mon Dec 24 02:07:44 2018 +++ src/usr.bin/config/main.c Mon Mar 9 15:22:21 2020 @@ -1,4 +1,4 @@ -/* $NetBSD: main.c,v 1.98 2018/12/24 02:07:44 christos Exp $ */ +/* $NetBSD: main.c,v 1.98.2.1 2020/03/09 15:22:21 martin Exp $ */ /* * Copyright (c) 1992, 1993 @@ -45,7 +45,7 @@ #endif #include <sys/cdefs.h> -__RCSID("$NetBSD: main.c,v 1.98 2018/12/24 02:07:44 christos Exp $"); +__RCSID("$NetBSD: main.c,v 1.98.2.1 2020/03/09 15:22:21 martin Exp $"); #ifndef MAKE_BOOTSTRAP #include <sys/cdefs.h> @@ -756,7 +756,7 @@ check_dependencies(const char *thing, st } else if (OPT_OBSOLETE(dep->nv_name)) { cfgerror("option `%s' dependency `%s' " "is obsolete", thing, dep->nv_name); - } else if (!is_declared_option(dep->nv_name)) { + } else if (!find_declared_option(dep->nv_name)) { cfgerror("option `%s' dependency `%s' " "is an unknown option", thing, dep->nv_name); @@ -786,14 +786,16 @@ void deffilesystem(struct nvlist *fses, struct nvlist *deps) { struct nvlist *nv; + struct where *w; /* * Mark these options as ones to skip when creating the Makefile. */ for (nv = fses; nv != NULL; nv = nv->nv_next) { - if (DEFINED_OPTION(nv->nv_name)) { - cfgerror("file system or option `%s' already defined", - nv->nv_name); + if ((w = DEFINED_OPTION(nv->nv_name)) != NULL) { + cfgerror("file system or option `%s' already defined" + " at %s:%hu", nv->nv_name, w->w_srcfile, + w->w_srcline); return; } @@ -878,8 +880,8 @@ find_declared_fs_option(const char *name * Like find_declared_option but doesn't return what it finds, so it * can search both the various kinds of options and also filesystems. */ -int -is_declared_option(const char *name) +struct where * +find_declared_option(const char *name) { struct defoptlist *option = NULL; struct nvlist *fs; @@ -887,13 +889,13 @@ is_declared_option(const char *name) if ((option = dlhash_lookup(defopttab, name)) != NULL || (option = dlhash_lookup(defparamtab, name)) != NULL || (option = dlhash_lookup(defflagtab, name)) != NULL) { - return 1; + return &option->dl_where; } if ((fs = nvhash_lookup(deffstab, name)) != NULL) { - return 1; + return &fs->nv_where; } - return 0; + return NULL; } /* @@ -908,6 +910,7 @@ defopt(struct dlhash *ht, const char *fn { struct defoptlist *dl, *nextdl, *olddl; const char *name; + struct where *w; char buf[500]; if (fname != NULL && badfilename(fname)) { @@ -930,15 +933,17 @@ defopt(struct dlhash *ht, const char *fn } /* An option name can be declared at most once. */ - if (DEFINED_OPTION(dl->dl_name)) { - cfgerror("file system or option `%s' already defined", - dl->dl_name); + if ((w = DEFINED_OPTION(dl->dl_name)) != NULL) { + cfgerror("file system or option `%s' already defined" + " at %s:%hu", dl->dl_name, w->w_srcfile, + w->w_srcline); return; } if (dlhash_insert(ht, dl->dl_name, dl)) { - cfgerror("file system or option `%s' already defined", - dl->dl_name); + cfgerror("file system or option `%s' already defined" + " at %s:%hu", dl->dl_name, dl->dl_where.w_srcfile, + dl->dl_where.w_srcline); return; } @@ -1379,8 +1384,8 @@ cfcrosscheck(struct config *cf, const ch goto loop; } (void)fprintf(stderr, - "%s:%d: %s says %s on %s, but there's no %s\n", - conffile, cf->cf_lineno, + "%s:%hu: %s says %s on %s, but there's no %s\n", + conffile, cf->cf_where.w_srcline, cf->cf_name, what, nv->nv_str, nv->nv_str); errs++; loop: Index: src/usr.bin/config/scan.l diff -u src/usr.bin/config/scan.l:1.26 src/usr.bin/config/scan.l:1.26.16.1 --- src/usr.bin/config/scan.l:1.26 Sun Aug 7 10:37:24 2016 +++ src/usr.bin/config/scan.l Mon Mar 9 15:22:21 2020 @@ -1,5 +1,5 @@ %{ -/* $NetBSD: scan.l,v 1.26 2016/08/07 10:37:24 christos Exp $ */ +/* $NetBSD: scan.l,v 1.26.16.1 2020/03/09 15:22:21 martin Exp $ */ /* * Copyright (c) 1992, 1993 @@ -42,7 +42,7 @@ */ #include <sys/cdefs.h> -__RCSID("$NetBSD: scan.l,v 1.26 2016/08/07 10:37:24 christos Exp $"); +__RCSID("$NetBSD: scan.l,v 1.26.16.1 2020/03/09 15:22:21 martin Exp $"); #include <sys/param.h> #include <errno.h> @@ -62,46 +62,53 @@ int yyline; const char *yyfile; const char *lastfile; char curinclpath[PATH_MAX]; -int ifdefstate = -1; -int st; +uint64_t ifdefstate; +int ifdefshift = -1; + +/* + * The state is represented by 3 bits. + */ +#define IDS_MATCH 1ll +#define IDS_ELIF 2ll +#define IDS_ELSE 4ll + +#define IDS_BITS 7 +#define IDS_SHIFT 3 + +#define IDS_ISMATCH(st) (((st) & IDS_MATCH) != 0) #define IDS_PARENT_DISABLED \ - ((ifdefstate > 6) && ((((ifdefstate/6)-1) & 1) == 1)) -#define IDS_MAX_DEPTH 362797056 /* 6^11 */ -/* States for ifdefstate: - - 0 -> matched ifdef - 1 -> unmatched ifdef - 2 -> matched elifdef - 3 -> unmatched elifdef - 4 -> matched else - 5 -> unmatched else - - Upon "ifdef", add one and multiply by 6. - Upon "endif", divide by 6, remove 1. - - ifdef -> MATCH => continue - MISMATCH => set to 1 - elifdef -> if (!1) -> MISMATCH - MATCH => set to 2 - MISMATCH => if (2 || 3) set to 3, else set to 1 - else -> if (1) -> MATCH - MATCH => set to 4 - MISMATCH => set to 5 - - in each case, if parent & 1 == 1, MISMATCH -*/ - + (ifdefshift > 0 && !IDS_ISMATCH(ifdefstate >> IDS_SHIFT)) +#define IDS_MAX_DEPTH 21 /* 64 / 3 */ + +#ifdef IDS_DEBUG +# define IDS_PRINT(s, st, x) \ + do { \ + for (int i = 0; i < ifdefshift + 1; i++) \ + fprintf(stderr, " "); \ + printf("%s%s [%d,%d,%d] %#" PRIx64 "\n", x, # s, \ + IDS_PARENT_DISABLED, IDS_ISMATCH(st), getcurifdef(), \ + ifdefstate); \ + } while (/*CONSTCOND*/0) +#else +# define IDS_PRINT(s, st, x) __nothing +#endif + +#define IDS_ENTER(s, st) \ + IDS_PRINT(s, st, ">") +#define IDS_EXIT(s, st) \ + IDS_PRINT(s, st, "<") + /* * Data for returning to previous files from include files. */ struct incl { struct incl *in_prev; /* previous includes in effect, if any */ YY_BUFFER_STATE in_buf; /* previous lex state */ - const char *in_fname; /* previous file name */ - int in_lineno; /* previous line number */ + struct where in_where; int in_ateof; /* token to insert at EOF */ int in_interesting; /* previous value for "interesting" */ - int in_ifdefstate; /* conditional level */ + uint64_t in_ifdefstate; /* conditional level */ + int in_ifdefshift; /* conditional level */ }; static struct incl *incl; static int endinclude(void); @@ -118,6 +125,7 @@ QCHARS \"(\\.|[^\\"])*\" WORD [A-Za-z_][-A-Za-z_0-9]* FILENAME ({PATH}|{QCHARS}) RESTOFLINE [ \t]*(#[^\n]*)?\n +WS ^[ \t]* %x IGNORED @@ -180,98 +188,101 @@ with return WITH; \+= return PLUSEQ; := return COLONEQ; -<*>ifdef[ \t]+{WORD}{RESTOFLINE} { - ifdefstate = (ifdefstate + 1) * 6; - if (ifdefstate >= IDS_MAX_DEPTH) { +<*>{WS}ifdef[ \t]+{WORD}{RESTOFLINE} { + ifdefstate <<= IDS_SHIFT; + if (++ifdefshift >= IDS_MAX_DEPTH) { yyerror("too many levels of conditional"); } - if (!IDS_PARENT_DISABLED && getcurifdef()) { - BEGIN(INITIAL); - } else { - ifdefstate++; + IDS_ENTER(ifdef, 0); + if (IDS_PARENT_DISABLED || !getcurifdef()) { BEGIN(IGNORED); + } else { + ifdefstate |= IDS_MATCH; + BEGIN(INITIAL); } + IDS_EXIT(ifdef, 0); yyline++; } -<*>ifndef[ \t]+{WORD}{RESTOFLINE} { - ifdefstate = (ifdefstate + 1) * 6; - if (ifdefstate >= IDS_MAX_DEPTH) { +<*>{WS}ifndef[ \t]+{WORD}{RESTOFLINE} { + ifdefstate <<= IDS_SHIFT; + if (++ifdefshift >= IDS_MAX_DEPTH) { yyerror("too many levels of conditional"); } - if (!IDS_PARENT_DISABLED && !getcurifdef()) { - BEGIN(INITIAL); - } else { - ifdefstate++; + IDS_ENTER(ifndef, 0); + if (IDS_PARENT_DISABLED || getcurifdef()) { BEGIN(IGNORED); + } else { + ifdefstate |= IDS_MATCH; + BEGIN(INITIAL); } + IDS_EXIT(ifndef, 0); yyline++; } -<*>elifdef[ \t]+{WORD}{RESTOFLINE} { - st = ifdefstate % 6; - if (ifdefstate < 0 || st > 3) { +<*>{WS}elifdef[ \t]+{WORD}{RESTOFLINE} { + int st = ifdefstate & IDS_BITS; + IDS_ENTER(elifdef, st); + if (ifdefshift == -1 || (st & IDS_ELSE) != 0) { yyerror("mismatched elifdef"); } - if (IDS_PARENT_DISABLED || - st != 1 || !getcurifdef()) { - if (st == 2 || st == 3) { - ifdefstate += 3 - st; - } else { - ifdefstate += 1 - st; - } + if (IDS_PARENT_DISABLED || IDS_ISMATCH(st) || !getcurifdef()) { BEGIN(IGNORED); } else { - ifdefstate++; + ifdefstate |= IDS_MATCH; BEGIN(INITIAL); } + ifdefstate |= IDS_ELIF; + IDS_EXIT(elifdef, st); yyline++; } -<*>elifndef[ \t]+{WORD}{RESTOFLINE} { - st = ifdefstate % 6; - if (ifdefstate < 0 || st > 3) { +<*>{WS}elifndef[ \t]+{WORD}{RESTOFLINE} { + int st = ifdefstate & IDS_BITS; + IDS_ENTER(elifndef, st); + if (ifdefshift == -1 || (st & IDS_ELSE) != 0) { yyerror("mismatched elifndef"); } - if (IDS_PARENT_DISABLED || - st != 1 || getcurifdef()) { - if (st == 2 || st == 3) { - ifdefstate += 3 - st; - } else { - ifdefstate += 1 - st; - } + if (IDS_PARENT_DISABLED || IDS_ISMATCH(st) || getcurifdef()) { BEGIN(IGNORED); } else { - ifdefstate++; + ifdefstate |= IDS_MATCH; BEGIN(INITIAL); } + ifdefstate |= IDS_ELIF; + IDS_EXIT(elifndef, st); yyline++; } -<*>else{RESTOFLINE} { - st = ifdefstate % 6; - if (ifdefstate < 0 || st > 3) { +<*>{WS}else{RESTOFLINE} { + int st = ifdefstate & IDS_BITS; + IDS_ENTER(else, st); + if (ifdefshift == -1 || (st & IDS_ELSE) != 0) { yyerror("mismatched else"); } - if (!IDS_PARENT_DISABLED && (st == 1)) { - ifdefstate += 3; - BEGIN(INITIAL); - } else { - ifdefstate += 5 - st; + if (IDS_PARENT_DISABLED || IDS_ISMATCH(st)) { BEGIN(IGNORED); + } else { + ifdefstate |= IDS_MATCH; + BEGIN(INITIAL); } + ifdefstate |= IDS_ELSE; + IDS_ENTER(else, st); yyline++; } -<*>endif{RESTOFLINE} { - if (ifdefstate < 0) { +<*>{WS}endif{RESTOFLINE} { + IDS_ENTER(endif, 0); + if (ifdefshift == -1) { yyerror("mismatched endif"); } if (!IDS_PARENT_DISABLED) { BEGIN(INITIAL); } - ifdefstate = (ifdefstate/6) - 1; + IDS_EXIT(endif, 0); + ifdefshift--; + ifdefstate >>= IDS_SHIFT; yyline++; } @@ -370,7 +381,7 @@ package[ \t]+{FILENAME}{RESTOFLINE} { [ \t]+ { /* ignored (white space) */; } . { return yytext[0]; } <*><<EOF>> { - if (ifdefstate > (incl == NULL ? -1 : incl->in_ifdefstate)) { + if (ifdefshift > (incl == NULL ? -1 : incl->in_ifdefshift)) { yyerror("reached EOF while looking for endif"); } if (incl == NULL) @@ -526,11 +537,12 @@ include(const char *fname, int ateof, in in = ecalloc(1, sizeof *in); in->in_prev = incl; in->in_buf = YY_CURRENT_BUFFER; - in->in_fname = yyfile; - in->in_lineno = yyline; + in->in_where.w_srcfile = yyfile; + in->in_where.w_srcline = (u_short)yyline; in->in_ateof = ateof; in->in_interesting = interesting; in->in_ifdefstate = ifdefstate; + in->in_ifdefshift = ifdefshift; interesting = direct & interesting; if (interesting) logconfig_include(fp, fname); @@ -597,10 +609,12 @@ endinclude(void) yy_delete_buffer(YY_CURRENT_BUFFER); (void)fclose(yyin); yy_switch_to_buffer(in->in_buf); - yyfile = in->in_fname; - yyline = in->in_lineno; + yyfile = in->in_where.w_srcfile; + yyline = in->in_where.w_srcline; ateof = in->in_ateof; interesting = in->in_interesting; + ifdefstate = in->in_ifdefstate; + ifdefshift = in->in_ifdefshift; free(in); includedepth--; Index: src/usr.bin/config/sem.c diff -u src/usr.bin/config/sem.c:1.83 src/usr.bin/config/sem.c:1.83.4.1 --- src/usr.bin/config/sem.c:1.83 Mon Apr 9 17:46:56 2018 +++ src/usr.bin/config/sem.c Mon Mar 9 15:22:21 2020 @@ -1,4 +1,4 @@ -/* $NetBSD: sem.c,v 1.83 2018/04/09 17:46:56 christos Exp $ */ +/* $NetBSD: sem.c,v 1.83.4.1 2020/03/09 15:22:21 martin Exp $ */ /* * Copyright (c) 1992, 1993 @@ -45,7 +45,7 @@ #endif #include <sys/cdefs.h> -__RCSID("$NetBSD: sem.c,v 1.83 2018/04/09 17:46:56 christos Exp $"); +__RCSID("$NetBSD: sem.c,v 1.83.4.1 2020/03/09 15:22:21 martin Exp $"); #include <sys/param.h> #include <ctype.h> @@ -276,17 +276,24 @@ setdefmaxusers(int min, int def, int max } } +static const char *maxusers_srcfile; +static u_short maxusers_srcline; + void setmaxusers(int n) { if (maxusers == n) { - cfgerror("duplicate maxusers parameter"); + cfgerror("duplicate maxusers parameter at %s:%hu", + maxusers_srcfile, maxusers_srcline); return; } if (vflag && maxusers != 0) - cfgwarn("warning: maxusers already defined"); + cfgwarn("warning: maxusers already defined at %s:%hu", + maxusers_srcfile, maxusers_srcline); maxusers = n; + maxusers_srcfile = yyfile; + maxusers_srcline = currentline(); if (n < minmaxusers) { cfgerror("warning: minimum of %d maxusers assumed", minmaxusers); @@ -338,7 +345,8 @@ defattr(const char *name, struct loclist struct attrlist *al; if (getrefattr(name, &a)) { - cfgerror("attribute `%s' already defined", name); + cfgerror("attribute `%s' already defined at %s:%hu", name, + a->a_where.w_srcfile, a->a_where.w_srcline); loclist_destroy(locs); return (1); } @@ -380,6 +388,8 @@ mkattr(const char *name) return NULL; } a->a_name = name; + a->a_where.w_srcfile = yyfile; + a->a_where.w_srcline = currentline(); TAILQ_INIT(&a->a_files); CFGDBG(3, "attr `%s' allocated", name); @@ -510,7 +520,7 @@ defdev(struct devbase *dev, struct locli goto bad; if (dev->d_isdef) { cfgerror("redefinition of `%s' (previously defined at %s:%d)", - dev->d_name, dev->d_srcfile, dev->d_srcline); + dev->d_name, dev->d_where.w_srcfile, dev->d_where.w_srcline); goto bad; } @@ -625,8 +635,8 @@ getdevbase(const char *name) dev->d_ahead = NULL; dev->d_app = &dev->d_ahead; dev->d_umax = 0; - dev->d_srcfile = yyfile; - dev->d_srcline = currentline(); + dev->d_where.w_srcfile = yyfile; + dev->d_where.w_srcline = currentline(); TAILQ_INSERT_TAIL(&allbases, dev, d_next); if (ht_insert(devbasetab, name, dev)) panic("%s: Can't insert %s", __func__, name); @@ -659,7 +669,7 @@ defdevattach(struct deva *deva, struct d } if (deva->d_isdef) { cfgerror("redefinition of `%s' (previously defined at %s:%d)", - deva->d_name, deva->d_srcfile, deva->d_srcline); + deva->d_name, deva->d_where.w_srcfile, deva->d_where.w_srcline); goto bad; } if (dev->d_ispseudo) { @@ -768,8 +778,8 @@ getdevattach(const char *name) deva->d_attrs = NULL; deva->d_ihead = NULL; deva->d_ipp = &deva->d_ihead; - deva->d_srcfile = yyfile; - deva->d_srcline = currentline(); + deva->d_where.w_srcfile = yyfile; + deva->d_where.w_srcline = currentline(); TAILQ_INSERT_TAIL(&alldevas, deva, d_next); if (ht_insert(devatab, name, deva)) panic("%s: Can't insert %s", __func__, name); @@ -1039,13 +1049,18 @@ addconf(struct config *cf0) const char *name; name = cf0->cf_name; + if ((cf = ht_lookup(cfhashtab, name)) != NULL) { + cfgerror("configuration `%s' already defined %s:%hu", name, + cf->cf_where.w_srcfile, cf->cf_where.w_srcline); + goto bad; + } cf = ecalloc(1, sizeof *cf); if (ht_insert(cfhashtab, name, cf)) { - cfgerror("configuration `%s' already defined", name); free(cf); - goto bad; } *cf = *cf0; + cf->cf_where.w_srcfile = yyfile; + cf->cf_where.w_srcline = currentline(); /* * Resolve the root device. @@ -1157,11 +1172,13 @@ newdevi(const char *name, int unit, stru i->i_atdeva = NULL; i->i_locs = NULL; i->i_cfflags = 0; - i->i_lineno = currentline(); - i->i_srcfile = yyfile; + i->i_where.w_srcline = currentline(); + i->i_where.w_srcfile = yyfile; i->i_active = DEVI_ORPHAN; /* Proper analysis comes later */ i->i_level = devilevel; i->i_pseudoroot = 0; + i->i_where.w_srcfile = yyfile; + i->i_where.w_srcline = currentline(); if (unit >= d->d_umax) d->d_umax = unit + 1; return (i); @@ -1796,8 +1813,9 @@ addpseudo(const char *name, int number) cfgerror("%s is a real device, not a pseudo-device", name); return; } - if (ht_lookup(devitab, name) != NULL) { - cfgerror("`%s' already defined", name); + if ((i = ht_lookup(devitab, name)) != NULL) { + cfgerror("`%s' already defined at %s:%hu", name, + i->i_where.w_srcfile, i->i_where.w_srcline); return; } i = newdevi(name, number - 1, d); /* foo 16 => "foo0..foo15" */ @@ -1855,8 +1873,8 @@ adddevm(const char *name, devmajor_t cma } dm = ecalloc(1, sizeof(*dm)); - dm->dm_srcfile = yyfile; - dm->dm_srcline = currentline(); + dm->dm_where.w_srcfile = yyfile; + dm->dm_where.w_srcline = currentline(); dm->dm_name = name; dm->dm_cmajor = cmajor; dm->dm_bmajor = bmajor; @@ -1890,11 +1908,11 @@ fixdevis(void) p = i->i_pspec; msg = p == NULL ? "no parent" : (p->p_atunit == WILD ? "nothing matching" : "no"); - cfgxerror(i->i_srcfile, i->i_lineno, + cfgxerror(i->i_where.w_srcfile, i->i_where.w_srcline, "`%s at %s' is orphaned (%s `%s' found)", i->i_name, i->i_at, msg, i->i_at); } else if (vflag && i->i_active == DEVI_IGNORED) - cfgxwarn(i->i_srcfile, i->i_lineno, "ignoring " + cfgxwarn(i->i_where.w_srcfile, i->i_where.w_srcline, "ignoring " "explicitly orphaned instance `%s at %s'", i->i_name, i->i_at); } Index: src/usr.bin/config/util.c diff -u src/usr.bin/config/util.c:1.20 src/usr.bin/config/util.c:1.20.18.1 --- src/usr.bin/config/util.c:1.20 Tue Sep 1 13:42:48 2015 +++ src/usr.bin/config/util.c Mon Mar 9 15:22:21 2020 @@ -1,4 +1,4 @@ -/* $NetBSD: util.c,v 1.20 2015/09/01 13:42:48 uebayasi Exp $ */ +/* $NetBSD: util.c,v 1.20.18.1 2020/03/09 15:22:21 martin Exp $ */ /* * Copyright (c) 1992, 1993 @@ -45,7 +45,7 @@ #endif #include <sys/cdefs.h> -__RCSID("$NetBSD: util.c,v 1.20 2015/09/01 13:42:48 uebayasi Exp $"); +__RCSID("$NetBSD: util.c,v 1.20.18.1 2020/03/09 15:22:21 martin Exp $"); #include <sys/types.h> #include <assert.h> @@ -58,6 +58,8 @@ __RCSID("$NetBSD: util.c,v 1.20 2015/09/ #include <err.h> #include "defs.h" +extern const char *yyfile; + static void cfgvxerror(const char *, int, const char *, va_list) __printflike(3, 0); static void cfgvxdbg(const char *, int, const char *, va_list) @@ -198,6 +200,8 @@ newnv(const char *name, const char *str, nv->nv_str = str; nv->nv_ptr = ptr; nv->nv_num = i; + nv->nv_where.w_srcfile = yyfile; + nv->nv_where.w_srcline = currentline(); return nv; } @@ -255,6 +259,8 @@ defoptlist_create(const char *name, cons dl->dl_lintvalue = lintval; dl->dl_obsolete = 0; dl->dl_depends = NULL; + dl->dl_where.w_srcfile = yyfile; + dl->dl_where.w_srcline = currentline(); return dl; }