[ 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

Reply via email to