Author: imp
Date: Thu Jul 15 23:07:02 2010
New Revision: 210148
URL: http://svn.freebsd.org/changeset/base/210148

Log:
  MFC: r188277, r188280, r201227, r205880, r206664, r206915, r207260, r207263,
  r207265, r209135, r209969
  
  (I'm not repeating all that here, see the logs for all the details):
  
  Config version is now 600010
  option alias support
  makefile parsing fixes
  calloc failure coping
  WARNS=6
  comment placement correction
  alpha vestige removal
  
  This should allow building of -current kernels and modules on 7-stable
  machines (although not officially supported, enough people do it to
  make some efforts to make it work a big win).
  
  imp, ed, wkoszek, ru, gcooper, and nwhitehorn authored the original revs

Modified:
  stable/7/usr.sbin/config/config.8
  stable/7/usr.sbin/config/config.h
  stable/7/usr.sbin/config/config.y
  stable/7/usr.sbin/config/configvers.h
  stable/7/usr.sbin/config/lang.l
  stable/7/usr.sbin/config/main.c
  stable/7/usr.sbin/config/mkmakefile.c
  stable/7/usr.sbin/config/mkoptions.c
Directory Properties:
  stable/7/usr.sbin/config/   (props changed)

Modified: stable/7/usr.sbin/config/config.8
==============================================================================
--- stable/7/usr.sbin/config/config.8   Thu Jul 15 22:52:36 2010        
(r210147)
+++ stable/7/usr.sbin/config/config.8   Thu Jul 15 23:07:02 2010        
(r210148)
@@ -92,6 +92,9 @@ Note that
 does not append
 .Ar SYSTEM_NAME
 to the directory given.
+.It Fl m
+Print the MACHINE and MACHINE_ARCH values for this
+kernel and exit.
 .It Fl g
 Configure a system for debugging.
 .It Fl x Ar kernel

Modified: stable/7/usr.sbin/config/config.h
==============================================================================
--- stable/7/usr.sbin/config/config.h   Thu Jul 15 22:52:36 2010        
(r210147)
+++ stable/7/usr.sbin/config/config.h   Thu Jul 15 23:07:02 2010        
(r210148)
@@ -129,6 +129,8 @@ SLIST_HEAD(opt_head, opt) opt, mkopt, rm
 struct opt_list {
        char *o_name;
        char *o_file;
+       int o_flags;
+#define OL_ALIAS       1
        SLIST_ENTRY(opt_list) o_next;
 };
 
@@ -177,6 +179,7 @@ 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;
 

Modified: stable/7/usr.sbin/config/config.y
==============================================================================
--- stable/7/usr.sbin/config/config.y   Thu Jul 15 22:52:36 2010        
(r210147)
+++ stable/7/usr.sbin/config/config.y   Thu Jul 15 23:07:02 2010        
(r210148)
@@ -166,6 +166,8 @@ Config_spec:
              = {
                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);
              } |
@@ -205,6 +207,8 @@ Config_spec:
                struct hint *hint;
 
                hint = (struct hint *)calloc(1, sizeof (struct hint));
+               if (hint == NULL)
+                       err(EXIT_FAILURE, "calloc");    
                hint->hint_name = $2;
                STAILQ_INSERT_TAIL(&hints, hint, hint_next);
                hintmode = 1;
@@ -350,6 +354,8 @@ 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);
 }
@@ -383,6 +389,8 @@ newdev(char *name)
        }
 
        np = (struct device *) calloc(1, sizeof *np);
+       if (np == NULL)
+               err(EXIT_FAILURE, "calloc");
        np->d_name = name;
        STAILQ_INSERT_TAIL(&dtab, np, d_next);
 }
@@ -441,6 +449,8 @@ newopt(struct opt_head *list, char *name
        }
 
        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;

Modified: stable/7/usr.sbin/config/configvers.h
==============================================================================
--- stable/7/usr.sbin/config/configvers.h       Thu Jul 15 22:52:36 2010        
(r210147)
+++ stable/7/usr.sbin/config/configvers.h       Thu Jul 15 23:07:02 2010        
(r210148)
@@ -49,5 +49,5 @@
  *
  * $FreeBSD$
  */
-#define        CONFIGVERS      600007
+#define        CONFIGVERS      600010
 #define        MAJOR_VERS(x)   ((x) / 100000)

Modified: stable/7/usr.sbin/config/lang.l
==============================================================================
--- stable/7/usr.sbin/config/lang.l     Thu Jul 15 22:52:36 2010        
(r210147)
+++ stable/7/usr.sbin/config/lang.l     Thu Jul 15 23:07:02 2010        
(r210148)
@@ -33,6 +33,7 @@
 
 #include <assert.h>
 #include <ctype.h>
+#include <err.h>
 #include <string.h>
 #include "y.tab.h"
 #include "config.h"
@@ -220,6 +221,8 @@ cfgfile_add(const char *fname)
        struct cfgfile *cf;
 
        cf = calloc(1, sizeof(*cf));
+       if (cf == NULL)
+               err(EXIT_FAILURE, "calloc");
        assert(cf != NULL);
        asprintf(&cf->cfg_path, "%s", fname);
        STAILQ_INSERT_TAIL(&cfgfiles, cf, cfg_next);
@@ -285,7 +288,7 @@ include(const char *fname, int ateof)
  * Terminate the most recent inclusion.
  */
 static int
-endinclude()
+endinclude(void)
 {
        struct incl *in;
        int ateof;

Modified: stable/7/usr.sbin/config/main.c
==============================================================================
--- stable/7/usr.sbin/config/main.c     Thu Jul 15 22:52:36 2010        
(r210147)
+++ stable/7/usr.sbin/config/main.c     Thu Jul 15 23:07:02 2010        
(r210148)
@@ -90,6 +90,7 @@ static void get_srcdir(void);
 static void usage(void);
 static void cleanheaders(char *);
 static void kernconfdump(const char *);
+static void checkversion(void);
 
 struct hdr_list {
        char *h_name;
@@ -109,18 +110,23 @@ main(int argc, char **argv)
        char *p;
        char xxx[MAXPATHLEN];
        char *kernfile;
+       int printmachine;
 
+       printmachine = 0;
        kernfile = NULL;
-       while ((ch = getopt(argc, argv, "Cd:gpVx:")) != -1)
+       while ((ch = getopt(argc, argv, "Cd:gmpVx:")) != -1)
                switch (ch) {
                case 'C':
                        filebased = 1;
                        break;
+               case 'm':
+                       printmachine = 1;
+                       break;
                case 'd':
                        if (*destdir == '\0')
                                strlcpy(destdir, optarg, sizeof(destdir));
                        else
-                               errx(2, "directory already set");
+                               errx(EXIT_FAILURE, "directory already set");
                        break;
                case 'g':
                        debugging++;
@@ -168,13 +174,6 @@ main(int argc, char **argv)
                strlcat(destdir, PREFIX, sizeof(destdir));
        }
 
-       p = path((char *)NULL);
-       if (stat(p, &buf)) {
-               if (mkdir(p, 0777))
-                       err(2, "%s", p);
-       } else if (!S_ISDIR(buf.st_mode))
-               errx(2, "%s isn't a directory", p);
-
        SLIST_INIT(&cputype);
        SLIST_INIT(&mkopt);
        SLIST_INIT(&opt);
@@ -202,6 +201,20 @@ main(int argc, char **argv)
                printf("cpu type must be specified\n");
                exit(1);
        }
+       checkversion();
+
+       if (printmachine) {
+               printf("%s\t%s\n",machinename,machinearch);
+               exit(0);
+       }
+
+       /* Make compile directory */
+       p = path((char *)NULL);
+       if (stat(p, &buf)) {
+               if (mkdir(p, 0777))
+                       err(2, "%s", p);
+       } else if (!S_ISDIR(buf.st_mode))
+               errx(EXIT_FAILURE, "%s isn't a directory", p);
 
        /*
         * make symbolic links in compilation directory
@@ -254,7 +267,7 @@ get_srcdir(void)
        int i;
 
        if (realpath("../..", srcdir) == NULL)
-               errx(2, "Unable to find root of source tree");
+               err(EXIT_FAILURE, "Unable to find root of source tree");
        if ((pwd = getenv("PWD")) != NULL && *pwd == '/' &&
            (pwd = strdup(pwd)) != NULL) {
                /* Remove the last two path components. */
@@ -276,7 +289,7 @@ static void
 usage(void)
 {
 
-       fprintf(stderr, "usage: config [-CgpV] [-d destdir] sysname\n");
+       fprintf(stderr, "usage: config [-CgmpV] [-d destdir] sysname\n");
        fprintf(stderr, "       config -x kernel\n");
        exit(EX_USAGE);
 }
@@ -464,6 +477,11 @@ configfile_filebased(struct sbuf *sb)
        struct cfgfile *cf;
        int i;
 
+       /*
+        * Try to read all configuration files. Since those will be present as
+        * C string in the macro, we have to slash their ends then the line
+        * wraps.
+        */
        STAILQ_FOREACH(cf, &cfgfiles, cfg_next) {
                cff = fopen(cf->cfg_path, "r");
                if (cff == NULL) {
@@ -498,11 +516,6 @@ configfile(void)
        sb = sbuf_new(NULL, NULL, 2048, SBUF_AUTOEXTEND);
        assert(sb != NULL);
        sbuf_clear(sb);
-       /*
-        * Try to read all configuration files. Since those will be present as
-        * C string in the macro, we have to slash their ends then the line
-        * wraps.
-        */
        if (filebased) {
                /* Is needed, can be used for backward compatibility. */
                configfile_filebased(sb);
@@ -511,7 +524,7 @@ configfile(void)
        }
        sbuf_finish(sb);
        /* 
-        * We print first part of the tamplate, replace our tag with
+        * We print first part of the template, replace our tag with
         * configuration files content and later continue writing our
         * template.
         */
@@ -563,9 +576,6 @@ moveifchanged(const char *from_name, con
 
        if (!changed) {
                p = mmap(NULL, tsize, PROT_READ, MAP_SHARED, from_fd, (off_t)0);
-#ifndef MAP_FAILED
-#define MAP_FAILED ((caddr_t) -1)
-#endif
                if (p == MAP_FAILED)
                        err(EX_OSERR, "mmap %s", from_name);
                q = mmap(NULL, tsize, PROT_READ, MAP_SHARED, to_fd, (off_t)0);
@@ -651,6 +661,8 @@ remember(const char *file)
                }
        }
        hl = calloc(1, sizeof(*hl));
+       if (hl == NULL)
+               err(EXIT_FAILURE, "calloc");
        hl->h_name = s;
        hl->h_next = htab;
        htab = hl;
@@ -672,19 +684,19 @@ kernconfdump(const char *file)
 
        r = open(file, O_RDONLY);
        if (r == -1)
-               errx(EXIT_FAILURE, "Couldn't open file '%s'", file);
+               err(EXIT_FAILURE, "Couldn't open file '%s'", file);
        error = fstat(r, &st);
        if (error == -1)
-               errx(EXIT_FAILURE, "fstat() failed");
+               err(EXIT_FAILURE, "fstat() failed");
        if (S_ISDIR(st.st_mode))
                errx(EXIT_FAILURE, "'%s' is a directory", file);
        fp = fdopen(r, "r");
        if (fp == NULL)
-               errx(EXIT_FAILURE, "fdopen() failed");
+               err(EXIT_FAILURE, "fdopen() failed");
        osz = 1024;
        o = calloc(1, osz);
        if (o == NULL)
-               errx(EXIT_FAILURE, "Couldn't allocate memory");
+               err(EXIT_FAILURE, "Couldn't allocate memory");
        /* ELF note section header. */
        asprintf(&cmd, "/usr/bin/elfdump -c %s | grep -A 8 kern_conf"
            "| tail -5 | cut -d ' ' -f 2 | paste - - - - -", file);
@@ -704,7 +716,7 @@ kernconfdump(const char *file)
                    "INCLUDE_CONFIG_FILE", file);
        r = fseek(fp, off, SEEK_CUR);
        if (r != 0)
-               errx(EXIT_FAILURE, "fseek() failed");
+               err(EXIT_FAILURE, "fseek() failed");
        for (i = 0; i < size; i++) {
                r = fgetc(fp);
                if (r == EOF)
@@ -724,3 +736,41 @@ kernconfdump(const char *file)
        }
        fclose(fp);
 }
+
+static void 
+badversion(int versreq)
+{
+       fprintf(stderr, "ERROR: version of config(8) does not match kernel!\n");
+       fprintf(stderr, "config version = %d, ", CONFIGVERS);
+       fprintf(stderr, "version required = %d\n\n", versreq);
+       fprintf(stderr, "Make sure that /usr/src/usr.sbin/config is in sync\n");
+       fprintf(stderr, "with your /usr/src/sys and install a new config 
binary\n");
+       fprintf(stderr, "before trying this again.\n\n");
+       fprintf(stderr, "If running the new config fails check your config\n");
+       fprintf(stderr, "file against the GENERIC or LINT config files for\n");
+       fprintf(stderr, "changes in config syntax, or option/device naming\n");
+       fprintf(stderr, "conventions\n\n");
+       exit(1);
+}
+
+static void
+checkversion(void)
+{
+       FILE *ifp;
+       char line[BUFSIZ];
+       int versreq;
+
+       ifp = open_makefile_template();
+       while (fgets(line, BUFSIZ, ifp) != 0) {
+               if (*line != '%')
+                       continue;
+               if (strncmp(line, "%VERSREQ=", 9) != 0)
+                       continue;
+               versreq = atoi(line + 9);
+               if (MAJOR_VERS(versreq) == MAJOR_VERS(CONFIGVERS) &&
+                   versreq <= CONFIGVERS)
+                       continue;
+               badversion(versreq);
+       }
+       fclose(ifp);
+}

Modified: stable/7/usr.sbin/config/mkmakefile.c
==============================================================================
--- stable/7/usr.sbin/config/mkmakefile.c       Thu Jul 15 22:52:36 2010        
(r210147)
+++ stable/7/usr.sbin/config/mkmakefile.c       Thu Jul 15 23:07:02 2010        
(r210148)
@@ -98,22 +98,21 @@ new_fent(void)
        struct file_list *fp;
 
        fp = (struct file_list *) calloc(1, sizeof *fp);
+       if (fp == NULL)
+               err(EXIT_FAILURE, "calloc");
        STAILQ_INSERT_TAIL(&ftab, fp, f_next);
        return (fp);
 }
 
 /*
- * Build the makefile from the skeleton
+ * Open the correct Makefile and return it, or error out.
  */
-void
-makefile(void)
+FILE *
+open_makefile_template(void)
 {
-       FILE *ifp, *ofp;
+       FILE *ifp;
        char line[BUFSIZ];
-       struct opt *op, *t;
-       int versreq;
 
-       read_files();
        snprintf(line, sizeof(line), "../../conf/Makefile.%s", machinename);
        ifp = fopen(line, "r");
        if (ifp == 0) {
@@ -122,7 +121,21 @@ makefile(void)
        }
        if (ifp == 0)
                err(1, "%s", line);
+       return (ifp);
+}
+
+/*
+ * Build the makefile from the skeleton
+ */
+void
+makefile(void)
+{
+       FILE *ifp, *ofp;
+       char line[BUFSIZ];
+       struct opt *op, *t;
 
+       read_files();
+       ifp = open_makefile_template();
        ofp = fopen(path("Makefile.new"), "w");
        if (ofp == 0)
                err(1, "%s", path("Makefile.new"));
@@ -154,23 +167,9 @@ makefile(void)
                        do_rules(ofp);
                else if (eq(line, "%CLEAN\n"))
                        do_clean(ofp);
-               else if (strncmp(line, "%VERSREQ=", sizeof("%VERSREQ=") - 1) == 
0) {
-                       versreq = atoi(line + sizeof("%VERSREQ=") - 1);
-                       if (MAJOR_VERS(versreq) != MAJOR_VERS(CONFIGVERS) ||
-                           versreq > CONFIGVERS) {
-                               fprintf(stderr, "ERROR: version of config(8) 
does not match kernel!\n");
-                               fprintf(stderr, "config version = %d, ", 
CONFIGVERS);
-                               fprintf(stderr, "version required = %d\n\n", 
versreq);
-                               fprintf(stderr, "Make sure that 
/usr/src/usr.sbin/config is in sync\n");
-                               fprintf(stderr, "with your /usr/src/sys and 
install a new config binary\n");
-                               fprintf(stderr, "before trying this 
again.\n\n");
-                               fprintf(stderr, "If running the new config 
fails check your config\n");
-                               fprintf(stderr, "file against the GENERIC or 
LINT config files for\n");
-                               fprintf(stderr, "changes in config syntax, or 
option/device naming\n");
-                               fprintf(stderr, "conventions\n\n");
-                               exit(1);
-                       }
-               } else
+               else if (strncmp(line, "%VERSREQ=", 9) == 0)
+                       line[0] = '\0'; /* handled elsewhere */
+               else
                        fprintf(stderr,
                            "Unknown %% construct in generic makefile: %s",
                            line);
@@ -684,6 +683,7 @@ do_rules(FILE *f)
        char *cp, *np, och;
        struct file_list *ftp;
        char *compilewith;
+       char cmd[128];
 
        STAILQ_FOREACH(ftp, &ftab, f_next) {
                if (ftp->f_warn)
@@ -721,26 +721,23 @@ do_rules(FILE *f)
                compilewith = ftp->f_compilewith;
                if (compilewith == 0) {
                        const char *ftype = NULL;
-                       static char cmd[128];
 
                        switch (ftp->f_type) {
-
                        case NORMAL:
                                ftype = "NORMAL";
                                break;
-
                        case PROFILING:
                                if (!profiling)
                                        continue;
                                ftype = "PROFILE";
                                break;
-
                        default:
                                printf("config: don't know rules for %s\n", np);
                                break;
                        }
                        snprintf(cmd, sizeof(cmd), "${%s_%c%s}\n"
-                           ".if defined(NORMAL_CTFCONVERT) && 
!empty(NORMAL_CTFCONVERT)\n"
+                           ".if defined(NORMAL_CTFCONVERT) && "
+                           "!empty(NORMAL_CTFCONVERT)\n"
                            "\t${NORMAL_CTFCONVERT}\n.endif", ftype,
                            toupper(och),
                            ftp->f_flags & NOWERROR ? "_NOWERROR" : "");

Modified: stable/7/usr.sbin/config/mkoptions.c
==============================================================================
--- stable/7/usr.sbin/config/mkoptions.c        Thu Jul 15 22:52:36 2010        
(r210147)
+++ stable/7/usr.sbin/config/mkoptions.c        Thu Jul 15 23:07:02 2010        
(r210148)
@@ -70,6 +70,8 @@ options(void)
        /* Fake the cpu types as options. */
        SLIST_FOREACH(cp, &cputype, cpu_next) {
                op = (struct opt *)calloc(1, sizeof(*op));
+               if (op == NULL)
+                       err(EXIT_FAILURE, "calloc");
                op->op_name = ns(cp->cpu_name);
                SLIST_INSERT_HEAD(&opt, op, op_next);
        }       
@@ -84,12 +86,39 @@ options(void)
 
        /* Fake MAXUSERS as an option. */
        op = (struct opt *)calloc(1, sizeof(*op));
+       if (op == NULL)
+               err(EXIT_FAILURE, "calloc");
        op->op_name = ns("MAXUSERS");
        snprintf(buf, sizeof(buf), "%d", maxusers);
        op->op_value = ns(buf);
        SLIST_INSERT_HEAD(&opt, op, op_next);
 
        read_options();
+
+       /* Fake the value of MACHINE_ARCH as an option if necessary */
+       SLIST_FOREACH(ol, &otab, o_next) {
+               if (strcasecmp(ol->o_name, machinearch) != 0)
+                       continue;
+
+               op = (struct opt *)calloc(1, sizeof(*op));
+               if (op == NULL)
+                       err(EXIT_FAILURE, "calloc");
+               op->op_name = ns(ol->o_name);
+               SLIST_INSERT_HEAD(&opt, op, op_next);
+               break;
+       }
+
+       SLIST_FOREACH(op, &opt, op_next) {
+               SLIST_FOREACH(ol, &otab, o_next) {
+                       if (eq(op->op_name, ol->o_name) &&
+                           (ol->o_flags & OL_ALIAS)) {
+                               printf("Mapping option %s to %s.\n",
+                                   op->op_name, ol->o_file);
+                               op->op_name = ol->o_file;
+                               break;
+                       }
+               }
+       }
        SLIST_FOREACH(ol, &otab, o_next)
                do_option(ol->o_name);
        SLIST_FOREACH(op, &opt, op_next) {
@@ -120,7 +149,6 @@ do_option(char *name)
        int tidy;
 
        file = tooption(name);
-
        /*
         * Check to see if the option was specified..
         */
@@ -152,7 +180,7 @@ do_option(char *name)
                        fprintf(outf, "#define %s %s\n", name, value);
                } /* else empty file */
 
-               (void) fclose(outf);
+               (void)fclose(outf);
                return;
        }
        basefile = "";
@@ -199,6 +227,8 @@ do_option(char *name)
                        tidy++;
                } else {
                        op = (struct opt *) calloc(1, sizeof *op);
+                       if (op == NULL)
+                               err(EXIT_FAILURE, "calloc");
                        op->op_name = inw;
                        op->op_value = invalue;
                        SLIST_INSERT_HEAD(&op_head, op, op_next);
@@ -209,7 +239,7 @@ do_option(char *name)
                if (cp == (char *)EOF)
                        break;
        }
-       (void) fclose(inf);
+       (void)fclose(inf);
        if (!tidy && ((value == NULL && oldvalue == NULL) ||
            (value && oldvalue && eq(value, oldvalue)))) {      
                while (!SLIST_EMPTY(&op_head)) {
@@ -225,6 +255,8 @@ do_option(char *name)
        if (value && !seen) {
                /* New option appears */
                op = (struct opt *) calloc(1, sizeof *op);
+               if (op == NULL)
+                       err(EXIT_FAILURE, "calloc");
                op->op_name = ns(name);
                op->op_value = value ? ns(value) : NULL;
                SLIST_INSERT_HEAD(&op_head, op, op_next);
@@ -245,7 +277,7 @@ do_option(char *name)
                free(op->op_value);
                free(op);
        }
-       (void) fclose(outf);
+       (void)fclose(outf);
 }
 
 /*
@@ -259,7 +291,7 @@ tooption(char *name)
        struct opt_list *po;
 
        /* "cannot happen"?  the otab list should be complete.. */
-       (void) strlcpy(nbuf, "options.h", sizeof(nbuf));
+       (void)strlcpy(nbuf, "options.h", sizeof(nbuf));
 
        SLIST_FOREACH(po, &otab, o_next) {
                if (eq(po->o_name, name)) {
@@ -268,64 +300,15 @@ tooption(char *name)
                }
        }
 
-       (void) strlcpy(hbuf, path(nbuf), sizeof(hbuf));
+       (void)strlcpy(hbuf, path(nbuf), sizeof(hbuf));
        return (hbuf);
 }
 
-/*
- * read the options and options.<machine> files
- */
+       
 static void
-read_options(void)
+check_duplicate(const char *fname, const char *this)
 {
-       FILE *fp;
-       char fname[MAXPATHLEN];
-       char *wd, *this, *val;
        struct opt_list *po;
-       int first = 1;
-       char genopt[MAXPATHLEN];
-
-       SLIST_INIT(&otab);
-       (void) snprintf(fname, sizeof(fname), "../../conf/options");
-openit:
-       fp = fopen(fname, "r");
-       if (fp == 0) {
-               return;
-       }
-next:
-       wd = get_word(fp);
-       if (wd == (char *)EOF) {
-               (void) fclose(fp);
-               if (first == 1) {
-                       first++;
-                       (void) snprintf(fname, sizeof fname, 
"../../conf/options.%s", machinename);
-                       fp = fopen(fname, "r");
-                       if (fp != 0)
-                               goto next;
-                       (void) snprintf(fname, sizeof fname, "options.%s", 
machinename);
-                       goto openit;
-               }
-               return;
-       }
-       if (wd == 0)
-               goto next;
-       if (wd[0] == '#')
-       {
-               while (((wd = get_word(fp)) != (char *)EOF) && wd)
-               ;
-               goto next;
-       }
-       this = ns(wd);
-       val = get_word(fp);
-       if (val == (char *)EOF)
-               return;
-       if (val == 0) {
-               char *s = ns(this);
-               (void) snprintf(genopt, sizeof(genopt), "opt_%s.h", lower(s));
-               val = genopt;
-               free(s);
-       }
-       val = ns(val);
 
        SLIST_FOREACH(po, &otab, o_next) {
                if (eq(po->o_name, this)) {
@@ -334,13 +317,101 @@ next:
                        exit(1);
                }
        }
-       
+}
+
+static void
+insert_option(const char *fname, char *this, char *val)
+{
+       struct opt_list *po;
+
+       check_duplicate(fname, this);
        po = (struct opt_list *) calloc(1, sizeof *po);
+       if (po == NULL)
+               err(EXIT_FAILURE, "calloc");
        po->o_name = this;
        po->o_file = val;
+       po->o_flags = 0;
        SLIST_INSERT_HEAD(&otab, po, o_next);
+}
+
+static void
+update_option(const char *this, char *val, int flags)
+{
+       struct opt_list *po;
+
+       SLIST_FOREACH(po, &otab, o_next) {
+               if (eq(po->o_name, this)) {
+                       free(po->o_file);
+                       po->o_file = val;
+                       po->o_flags = flags;
+                       return;
+               }
+       }
+       printf("Compat option %s not listed in options file.\n", this);
+       exit(1);
+}
+
+static int
+read_option_file(const char *fname, int flags)
+{
+       FILE *fp;
+       char *wd, *this, *val;
+       char genopt[MAXPATHLEN];
 
-       goto next;
+       fp = fopen(fname, "r");
+       if (fp == 0)
+               return (0);
+       while ((wd = get_word(fp)) != (char *)EOF) {
+               if (wd == 0)
+                       continue;
+               if (wd[0] == '#') {
+                       while (((wd = get_word(fp)) != (char *)EOF) && wd)
+                               continue;
+                       continue;
+               }
+               this = ns(wd);
+               val = get_word(fp);
+               if (val == (char *)EOF)
+                       return (1);
+               if (val == 0) {
+                       if (flags) {
+                               printf("%s: compat file requires two words "
+                                   "per line at %s\n", fname, this);
+                               exit(1);
+                       }
+                       char *s = ns(this);
+                       (void)snprintf(genopt, sizeof(genopt), "opt_%s.h",
+                           lower(s));
+                       val = genopt;
+                       free(s);
+               }
+               val = ns(val);
+               if (flags == 0)
+                       insert_option(fname, this, val);
+               else
+                       update_option(this, val, flags);
+       }
+       (void)fclose(fp);
+       return (1);
+}
+
+/*
+ * read the options and options.<machine> files
+ */
+static void
+read_options(void)
+{
+       char fname[MAXPATHLEN];
+
+       SLIST_INIT(&otab);
+       read_option_file("../../conf/options", 0);
+       (void)snprintf(fname, sizeof fname, "../../conf/options.%s",
+           machinename);
+       if (!read_option_file(fname, 0)) {
+               (void)snprintf(fname, sizeof fname, "options.%s", machinename);
+               read_option_file(fname, 0);
+       }
+       read_option_file("../../conf/options-compat", OL_ALIAS);
 }
 
 static char *
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to