svn commit: r210148 - stable/7/usr.sbin/config

Warner Losh imp at FreeBSD.org
Thu Jul 15 23:07:03 UTC 2010


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 *


More information about the svn-src-stable-7 mailing list