Index: stable/12/usr.sbin/config/config.h =================================================================== --- stable/12/usr.sbin/config/config.h (revision 350603) +++ stable/12/usr.sbin/config/config.h (revision 350604) @@ -1,221 +1,223 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1980, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * @(#)config.h 8.1 (Berkeley) 6/6/93 * $FreeBSD$ */ /* * Config. */ #include #include #include #include #include struct cfgfile { STAILQ_ENTRY(cfgfile) cfg_next; char *cfg_path; }; STAILQ_HEAD(, cfgfile) cfgfiles; struct file_list { STAILQ_ENTRY(file_list) f_next; char *f_fn; /* the name */ int f_type; /* type */ u_char f_flags; /* see below */ char *f_compilewith; /* special make rule if present */ char *f_depends; /* additional dependencies */ char *f_clean; /* File list to add to clean rule */ char *f_warn; /* warning message */ const char *f_objprefix; /* prefix string for object name */ const char *f_srcprefix; /* source prefix such as $S/ */ }; struct files_name { char *f_name; STAILQ_ENTRY(files_name) f_next; }; /* * Types. */ #define NORMAL 1 #define PROFILING 3 #define NODEPEND 4 #define LOCAL 5 #define DEVDONE 0x80000000 #define TYPEMASK 0x7fffffff /* * Attributes (flags). */ #define NO_IMPLCT_RULE 1 #define NO_OBJ 2 #define BEFORE_DEPEND 4 #define NOWERROR 16 struct device { int d_done; /* processed */ char *d_name; /* name of device (e.g. rk11) */ + char *yyfile; /* name of the file that first include the device */ #define UNKNOWN -2 /* -2 means not set yet */ STAILQ_ENTRY(device) d_next; /* Next one in list */ }; struct config { char *s_sysname; }; /* * Config has a global notion of which machine type is * being used. It uses the name of the machine in choosing * files and directories. Thus if the name of the machine is ``i386'', * it will build from ``Makefile.i386'' and use ``../i386/inline'' * in the makerules, etc. machinearch is the global notion of the * MACHINE_ARCH for this MACHINE. */ char *machinename; char *machinearch; /* * For each machine, a set of CPU's may be specified as supported. * These and the options (below) are put in the C flags in the makefile. */ struct cputype { char *cpu_name; SLIST_ENTRY(cputype) cpu_next; }; SLIST_HEAD(, cputype) cputype; /* * A set of options may also be specified which are like CPU types, * but which may also specify values for the options. * A separate set of options may be defined for make-style options. */ struct opt { char *op_name; char *op_value; int op_ownfile; /* true = own file, false = makefile */ + char *yyfile; /* name of the file that first include the option */ SLIST_ENTRY(opt) op_next; SLIST_ENTRY(opt) op_append; }; SLIST_HEAD(opt_head, opt) opt, mkopt, rmopts; struct opt_list { char *o_name; char *o_file; int o_flags; #define OL_ALIAS 1 SLIST_ENTRY(opt_list) o_next; }; SLIST_HEAD(, opt_list) otab; struct envvar { char *env_str; bool env_is_file; STAILQ_ENTRY(envvar) envvar_next; }; STAILQ_HEAD(envvar_head, envvar) envvars; struct hint { char *hint_name; STAILQ_ENTRY(hint) hint_next; }; STAILQ_HEAD(hint_head, hint) hints; struct includepath { char *path; SLIST_ENTRY(includepath) path_next; }; SLIST_HEAD(, includepath) includepath; /* * Tag present in the kernconf.tmpl template file. It's mandatory for those * two strings to be the same. Otherwise you'll get into trouble. */ #define KERNCONFTAG "%%KERNCONFFILE%%" /* * Faked option to note, that the configuration file has been taken from the * kernel file and inclusion of DEFAULTS etc.. isn't nessesery, because we * already have a list of all required devices. */ #define OPT_AUTOGEN "CONFIG_AUTOGENERATED" extern char *ident; extern char kernconfstr[]; extern int do_trace; extern int incignore; char *get_word(FILE *); char *get_quoted_word(FILE *); char *path(const char *); char *raisestr(char *); void remember(const char *); void moveifchanged(const char *, const char *); int yylex(void); void options(void); void makefile(void); void makeenv(void); void makehints(void); void headers(void); void cfgfile_add(const char *); void cfgfile_removeall(void); FILE *open_makefile_template(void); extern STAILQ_HEAD(device_head, device) dtab; extern char errbuf[80]; extern int yyline; extern const char *yyfile; extern STAILQ_HEAD(file_list_head, file_list) ftab; extern STAILQ_HEAD(files_name_head, files_name) fntab; extern int profiling; extern int debugging; extern int found_defaults; extern int maxusers; extern int versreq; extern char *PREFIX; /* Config file name - for error messages */ extern char srcdir[]; /* root of the kernel source tree */ #define eq(a,b) (!strcmp(a,b)) #define ns(s) strdup(s) Index: stable/12/usr.sbin/config/config.y =================================================================== --- stable/12/usr.sbin/config/config.y (revision 350603) +++ stable/12/usr.sbin/config/config.y (revision 350604) @@ -1,487 +1,494 @@ %union { char *str; int val; struct file_list *file; } %token ARCH %token COMMA %token CONFIG %token CPU %token NOCPU %token DEVICE %token NODEVICE %token ENV %token ENVVAR %token EQUALS %token PLUSEQUALS %token HINTS %token IDENT %token MAXUSERS %token PROFILE %token OPTIONS %token NOOPTION %token MAKEOPTIONS %token NOMAKEOPTION %token SEMICOLON %token INCLUDE %token FILES %token ENVLINE %token ID %token NUMBER %type Save_id %type Opt_value %type Dev %token PATH %{ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1988, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * @(#)config.y 8.1 (Berkeley) 6/6/93 * $FreeBSD$ */ #include #include #include #include #include #include "config.h" struct device_head dtab; char *ident; char *env; int yyline; const char *yyfile; struct file_list_head ftab; struct files_name_head fntab; char errbuf[80]; int maxusers; #define ns(s) strdup(s) int include(const char *, int); void yyerror(const char *s); int yywrap(void); static void newdev(char *name); static void newfile(char *name); static void newenvvar(char *name, bool is_file); static void rmdev_schedule(struct device_head *dh, char *name); static void newopt(struct opt_head *list, char *name, char *value, int append, int dupe); static void rmopt_schedule(struct opt_head *list, char *name); static char * devopt(char *dev) { char *ret = malloc(strlen(dev) + 5); sprintf(ret, "DEV_%s", dev); raisestr(ret); return ret; } %} %% Configuration: Many_specs ; Many_specs: Many_specs Spec | /* lambda */ ; Spec: Device_spec SEMICOLON | Config_spec SEMICOLON | INCLUDE PATH SEMICOLON { if (incignore == 0) include($2, 0); }; | INCLUDE ID SEMICOLON { if (incignore == 0) include($2, 0); }; | FILES ID SEMICOLON { newfile($2); }; | SEMICOLON | error SEMICOLON ; Config_spec: ARCH Save_id { if (machinename != NULL && !eq($2, machinename)) errx(1, "%s:%d: only one machine directive is allowed", yyfile, yyline); machinename = $2; machinearch = $2; } | ARCH Save_id Save_id { if (machinename != NULL && !(eq($2, machinename) && eq($3, machinearch))) errx(1, "%s:%d: only one machine directive is allowed", yyfile, yyline); machinename = $2; machinearch = $3; } | CPU Save_id { struct cputype *cp = (struct cputype *)calloc(1, sizeof (struct cputype)); if (cp == NULL) err(EXIT_FAILURE, "calloc"); cp->cpu_name = $2; SLIST_INSERT_HEAD(&cputype, cp, cpu_next); } | NOCPU Save_id { struct cputype *cp, *cp2; SLIST_FOREACH_SAFE(cp, &cputype, cpu_next, cp2) { if (eq(cp->cpu_name, $2)) { SLIST_REMOVE(&cputype, cp, cputype, cpu_next); free(cp); } } } | OPTIONS Opt_list | NOOPTION NoOpt_list | MAKEOPTIONS Mkopt_list | NOMAKEOPTION Save_id { rmopt_schedule(&mkopt, $2); } | IDENT ID { ident = $2; } | System_spec | MAXUSERS NUMBER { maxusers = $2; } | PROFILE NUMBER { profiling = $2; } | ENV ID { newenvvar($2, true); } | ENVVAR ENVLINE { newenvvar($2, false); } | HINTS ID { struct hint *hint; hint = (struct hint *)calloc(1, sizeof (struct hint)); if (hint == NULL) err(EXIT_FAILURE, "calloc"); hint->hint_name = $2; STAILQ_INSERT_HEAD(&hints, hint, hint_next); } System_spec: CONFIG System_id System_parameter_list { errx(1, "%s:%d: root/dump/swap specifications obsolete", yyfile, yyline); } | CONFIG System_id ; System_id: Save_id { newopt(&mkopt, ns("KERNEL"), $1, 0, 0); }; System_parameter_list: System_parameter_list ID | ID ; Opt_list: Opt_list COMMA Option | Option ; NoOpt_list: NoOpt_list COMMA NoOption | NoOption ; Option: Save_id { newopt(&opt, $1, NULL, 0, 1); if (strchr($1, '=') != NULL) errx(1, "%s:%d: The `=' in options should not be " "quoted", yyfile, yyline); } | Save_id EQUALS Opt_value { newopt(&opt, $1, $3, 0, 1); } ; NoOption: Save_id { rmopt_schedule(&opt, $1); }; Opt_value: ID { $$ = $1; } | NUMBER { char buf[80]; (void) snprintf(buf, sizeof(buf), "%d", $1); $$ = ns(buf); } ; Save_id: ID { $$ = $1; } ; Mkopt_list: Mkopt_list COMMA Mkoption | Mkoption ; Mkoption: Save_id { newopt(&mkopt, $1, ns(""), 0, 0); } | Save_id EQUALS { newopt(&mkopt, $1, ns(""), 0, 0); } | Save_id EQUALS Opt_value { newopt(&mkopt, $1, $3, 0, 0); } | Save_id PLUSEQUALS Opt_value { newopt(&mkopt, $1, $3, 1, 0); } ; Dev: ID { $$ = $1; } ; Device_spec: DEVICE Dev_list | NODEVICE NoDev_list ; Dev_list: Dev_list COMMA Device | Device ; NoDev_list: NoDev_list COMMA NoDevice | NoDevice ; Device: Dev { newopt(&opt, devopt($1), ns("1"), 0, 0); /* and the device part */ newdev($1); } NoDevice: Dev { char *s = devopt($1); rmopt_schedule(&opt, s); free(s); /* and the device part */ rmdev_schedule(&dtab, $1); } ; %% void yyerror(const char *s) { errx(1, "%s:%d: %s", yyfile, yyline + 1, s); } int yywrap(void) { if (found_defaults) { if (freopen(PREFIX, "r", stdin) == NULL) err(2, "%s", PREFIX); yyfile = PREFIX; yyline = 0; found_defaults = 0; return 0; } return 1; } /* * Add a new file to the list of files. */ static void newfile(char *name) { struct files_name *nl; nl = (struct files_name *) calloc(1, sizeof *nl); if (nl == NULL) err(EXIT_FAILURE, "calloc"); nl->f_name = name; STAILQ_INSERT_TAIL(&fntab, nl, f_next); } static void newenvvar(char *name, bool is_file) { struct envvar *envvar; envvar = (struct envvar *)calloc(1, sizeof (struct envvar)); if (envvar == NULL) err(EXIT_FAILURE, "calloc"); envvar->env_str = name; envvar->env_is_file = is_file; STAILQ_INSERT_HEAD(&envvars, envvar, envvar_next); } /* * Find a device in the list of devices. */ static struct device * finddev(struct device_head *dlist, char *name) { struct device *dp; STAILQ_FOREACH(dp, dlist, d_next) if (eq(dp->d_name, name)) return (dp); return (NULL); } /* * Add a device to the list of devices. */ static void newdev(char *name) { - struct device *np; + struct device *np, *dp; - if (finddev(&dtab, name)) { - fprintf(stderr, - "WARNING: duplicate device `%s' encountered.\n", name); + if ((dp = finddev(&dtab, name)) != NULL) { + if (strcmp(dp->yyfile, yyfile) == 0) + fprintf(stderr, + "WARNING: duplicate device `%s' encountered in %s\n", + name, yyfile); return; } np = (struct device *) calloc(1, sizeof *np); if (np == NULL) err(EXIT_FAILURE, "calloc"); np->d_name = name; + np->yyfile = strdup(yyfile); STAILQ_INSERT_TAIL(&dtab, np, d_next); } /* * Schedule a device to removal. */ static void rmdev_schedule(struct device_head *dh, char *name) { struct device *dp; dp = finddev(dh, name); if (dp != NULL) { STAILQ_REMOVE(dh, dp, device, d_next); + free(dp->yyfile); free(dp->d_name); free(dp); } } /* * Find an option in the list of options. */ static struct opt * findopt(struct opt_head *list, char *name) { struct opt *op; SLIST_FOREACH(op, list, op_next) if (eq(op->op_name, name)) return (op); return (NULL); } /* * Add an option to the list of options. */ static void newopt(struct opt_head *list, char *name, char *value, int append, int dupe) { struct opt *op, *op2; /* * Ignore inclusions listed explicitly for configuration files. */ if (eq(name, OPT_AUTOGEN)) { incignore = 1; return; } op2 = findopt(list, name); if (op2 != NULL && !append && !dupe) { - fprintf(stderr, - "WARNING: duplicate option `%s' encountered.\n", name); + if (strcmp(op2->yyfile, yyfile) == 0) + fprintf(stderr, + "WARNING: duplicate option `%s' encountered.\n", name); return; } op = (struct opt *)calloc(1, sizeof (struct opt)); if (op == NULL) err(EXIT_FAILURE, "calloc"); op->op_name = name; op->op_ownfile = 0; op->op_value = value; + op->yyfile = strdup(yyfile); if (op2 != NULL) { if (append) { while (SLIST_NEXT(op2, op_append) != NULL) op2 = SLIST_NEXT(op2, op_append); SLIST_NEXT(op2, op_append) = op; } else { while (SLIST_NEXT(op2, op_next) != NULL) op2 = SLIST_NEXT(op2, op_next); SLIST_NEXT(op2, op_next) = op; } } else SLIST_INSERT_HEAD(list, op, op_next); } /* * Remove an option from the list of options. */ static void rmopt_schedule(struct opt_head *list, char *name) { struct opt *op; while ((op = findopt(list, name)) != NULL) { SLIST_REMOVE(list, op, opt, op_next); + free(op->yyfile); free(op->op_name); free(op); } } Index: stable/12 =================================================================== --- stable/12 (revision 350603) +++ stable/12 (revision 350604) Property changes on: stable/12 ___________________________________________________________________ Modified: svn:mergeinfo ## -0,0 +0,1 ## Merged /head:r346298