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>