[ peter@ cc'd because he's done a lot of work with config(8) ]
John Baldwin <[EMAIL PROTECTED]> writes:
> On 22-Jun-01 Dima Dorfman wrote:
> > John Baldwin <[EMAIL PROTECTED]> 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
[EMAIL PROTECTED]
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 [EMAIL PROTECTED]
with "unsubscribe freebsd-hackers" in the body of the message