Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 23 Jun 2001 23:20:02 -0700
From:      Dima Dorfman <dima@unixfreak.org>
To:        John Baldwin <jhb@FreeBSD.org>
Cc:        hackers@FreeBSD.org, peter@FreeBSD.org
Subject:   "include" directive in config(8) (was: Two Junior Kernel Hacker tasks..)
Message-ID:  <20010624062002.1DC013E28@bazooka.unixfreak.org>
In-Reply-To: <XFMail.010622145213.jhb@FreeBSD.org>; from jhb@FreeBSD.org on "Fri, 22 Jun 2001 14:52:13 -0700 (PDT)"

next in thread | previous in thread | raw e-mail | index | archive | help
[ peter@ cc'd because he's done a lot of work with config(8) ]

John Baldwin <jhb@FreeBSD.org> writes:
> On 22-Jun-01 Dima Dorfman wrote:
> > John Baldwin <jhb@FreeBSD.org> writes:
> >> 1) Split sys/i386/conf/NOTES up into MI and MD parts.  The MI portion would
> >>    become sys/conf/NOTES and would contain all the machine independent
> >>    options and devices.  The MD options and devices would live in
> >>    sys/${MACHINE_ARCH}/conf/NOTES.  This would include altering the
> >>    sys/${MACHINE_ARCH}/conf/Makefile's (based on the LINT: target in the
> >>    i386 Makefile) to concatenate the MI and MD NOTES files together to
> >>    feed to makelint.pl to build LINT.  This addresses problems with not
> >>    having
> >>    a place for non-i386 kernel options/devices that aren't in GENERIC for
> >>    example.
> > 
> > OpenBSD (and I think NetBSD) solve this problem by having an 'include'
> > directive in the kernel config file.  E.g., in
> > sys/arch/i386/conf/GENRIC (the MD config file):
> > 
> >       machine i386
> >       ...
> >       include "../../../conf/GENREIC"         # <-- MI config file
> >       ...
> > 
> > I think this is much more general than just splitting NOTES.  Is there
> > any reason we shouldn't do this?  I'd be willing to implement
> > 'include' in config(8).
> 
> That's fine.  LINT is still special, because we do extra processing to convert
> NOTES to LINT, but that would make updating GENERIC easier.

Okay, attached is a patch to config(8) that implements an 'include'
directive.  The include()/endinclude() routines are mostly from
OpenBSD.  I can't say I've done excessive testing on this, but it
works pretty well from what I can tell.

Comments?  Suggestions?  Reviews?

Thanks,

					Dima Dorfman
					dima@unixfreak.org

Index: config.h
===================================================================
RCS file: /stl/src/FreeBSD/src/usr.sbin/config/config.h,v
retrieving revision 1.48
diff -u -r1.48 config.h
--- config.h	2001/02/28 02:55:15	1.48
+++ config.h	2001/06/24 06:11:11
@@ -142,6 +142,7 @@
 
 extern char	errbuf[80];
 extern int	yyline;
+extern const	char *yyfile;
 
 extern struct	file_list *ftab;
 
Index: config.y
===================================================================
RCS file: /stl/src/FreeBSD/src/usr.sbin/config/config.y,v
retrieving revision 1.54
diff -u -r1.54 config.y
--- config.y	2001/02/22 04:00:29	1.54
+++ config.y	2001/06/24 06:11:11
@@ -17,6 +17,7 @@
 %token	OPTIONS
 %token	MAKEOPTIONS
 %token	SEMICOLON
+%token	INCLUDE
 
 %token	<str>	ID
 %token	<val>	NUMBER
@@ -77,14 +78,15 @@
 char	*hints;
 int	hintmode;
 int	yyline;
+const	char *yyfile;
 struct  file_list *ftab;
 char	errbuf[80];
 int	maxusers;
 
 #define ns(s)	strdup(s)
+int include(const char *, int);
+void yyerror(const char *s);
 
-static void yyerror(const char *s);
-
 static char *
 devopt(char *dev)
 {
@@ -147,11 +149,14 @@
 	      = {
 		      hints = $2;
 		      hintmode = 1;
-		};
+	        } |
+	INCLUDE ID
+	      = { include($2, 0); };
 
 System_spec:
 	CONFIG System_id System_parameter_list
-	  = { errx(1, "line %d: root/dump/swap specifications obsolete", yyline);}
+	  = { errx(1, "%s:%d: root/dump/swap specifications obsolete",
+	      yyfile, yyline);}
 	  |
 	CONFIG System_id
 	  ;
@@ -178,7 +183,8 @@
 
 		newopt(&opt, $1, NULL);
 		if ((s = strchr($1, '=')))
-			errx(1, "line %d: The `=' in options should not be quoted", yyline);
+			errx(1, "%s:%d: The `=' in options should not be "
+			    "quoted", yyfile, yyline);
 	      } |
 	Save_id EQUALS Opt_value
 	      = {
@@ -229,16 +235,17 @@
 		/* and the device part */
 		newdev($2, $3);
 		if ($3 == 0)
-			errx(1, "line %d: devices with zero units are not likely to be correct", yyline);
+			errx(1, "%s:%d: devices with zero units are not "
+			    "likely to be correct", yyfile, yyline);
 		} ;
 
 %%
 
-static void
+void
 yyerror(const char *s)
 {
 
-	errx(1, "line %d: %s", yyline + 1, s);
+	errx(1, "%s:%d: %s", yyfile, yyline + 1, s);
 }
 
 /*
Index: lang.l
===================================================================
RCS file: /stl/src/FreeBSD/src/usr.sbin/config/lang.l,v
retrieving revision 1.30
diff -u -r1.30 lang.l
--- lang.l	2001/02/19 04:43:21	1.30
+++ lang.l	2001/06/24 06:11:11
@@ -35,6 +35,7 @@
  * $FreeBSD: src/usr.sbin/config/lang.l,v 1.30 2001/02/19 04:43:21 peter Exp $
  */
 
+#include <assert.h>
 #include <ctype.h>
 #include <string.h>
 #include "y.tab.h"
@@ -43,6 +44,19 @@
 #define YY_NO_UNPUT
 
 /*
+ * 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 */
+	int	in_ateof;	/* token to insert at EOF */
+};
+static struct	incl *inclp;
+static const	char *lastfile;
+
+/*
  * Key word table
  */
 
@@ -61,13 +75,17 @@
 	{ "profile",	PROFILE },
 	{ "option",	OPTIONS },
 	{ "options",	OPTIONS },
+	{ "include",	INCLUDE },
 	{ 0, 0 },
 };
 
 
+static int endinclude(void);
+int include(const char *, int);
 int kw_lookup(char *);
 int octal(char *);
 int hex(char *);
+int yyerror(const char *);
 
 %}
 WORD	[A-Za-z_][-A-Za-z_]*
@@ -145,6 +163,16 @@
 ";"		{	return SEMICOLON;		}
 ","		{	return COMMA;			}
 "="		{	BEGIN TOEOL; return EQUALS;	}
+<<EOF>>		{
+			int tok;
+
+			if (inclp == NULL)
+				return YY_NULL;
+			tok = endinclude();
+			if (tok != 0)
+				return tok;
+			/* otherwise continue scanning */
+		}
 .		{	return yytext[0];		}
 
 %%
@@ -185,4 +213,61 @@
 
 	(void) sscanf(str+2, "%x", &num);
 	return num;
+}
+
+
+/*
+ * Open the named file for inclusion at the current point.  Returns 0 on
+ * success (file opened and previous state pushed), nonzero on failure
+ * (fopen failed, complaint made).  The `ateof' parameter controls the
+ * token to be inserted at the end of the include file. If ateof == 0,
+ * then nothing is inserted.
+ */
+int
+include(const char *fname, int ateof)
+{
+	FILE *fp;
+	struct incl *in;
+
+	fp = fopen(fname, "r");
+	if (fp == NULL) {
+		yyerror("cannot open file");
+		return (-1);
+	}
+	in = malloc(sizeof(*in));
+	assert(in != NULL);
+	in->in_prev = inclp;
+	in->in_buf = YY_CURRENT_BUFFER;
+	in->in_fname = yyfile;
+	in->in_lineno = yyline;
+	in->in_ateof = ateof;
+	inclp = in;
+	yy_switch_to_buffer(yy_create_buffer(fp, YY_BUF_SIZE));
+	yyfile = fname;
+	yyline = 0;
+	return (0);
+}
+
+/*
+ * Terminate the most recent inclusion.
+ */
+static int
+endinclude()
+{
+	struct incl *in;
+	int ateof;
+
+	in = inclp;
+	assert(in != NULL);
+	inclp = in->in_prev;
+	lastfile = yyfile;
+	yy_delete_buffer(YY_CURRENT_BUFFER);
+	(void)fclose(yyin);
+	yy_switch_to_buffer(in->in_buf);
+	yyfile = in->in_fname;
+	yyline = in->in_lineno;
+	ateof  = in->in_ateof;
+	free(in);
+
+	return (ateof);
 }
Index: main.c
===================================================================
RCS file: /stl/src/FreeBSD/src/usr.sbin/config/main.c,v
retrieving revision 1.50
diff -u -r1.50 main.c
--- main.c	2001/02/23 00:22:04	1.50
+++ main.c	2001/06/24 06:11:11
@@ -144,6 +144,7 @@
 		errx(2, "%s isn't a directory", p);
 
 	dtab = NULL;
+	yyfile = *argv;
 	if (yyparse())
 		exit(3);
 	if (machinename == NULL) {

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-hackers" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20010624062002.1DC013E28>