diff options
author | dd <dd@FreeBSD.org> | 2001-07-12 02:08:51 +0000 |
---|---|---|
committer | dd <dd@FreeBSD.org> | 2001-07-12 02:08:51 +0000 |
commit | b5164c6585fabc3c848ff92ada3f6ffb64a9e8f2 (patch) | |
tree | 6e5c6a1c595fde5e5c90b1af74b8c2880c887a37 /usr.sbin/config/lang.l | |
parent | 93faa5d597dce09f52a652cb24242bd11e6b6682 (diff) | |
download | FreeBSD-src-b5164c6585fabc3c848ff92ada3f6ffb64a9e8f2.zip FreeBSD-src-b5164c6585fabc3c848ff92ada3f6ffb64a9e8f2.tar.gz |
Introduce an "include" directive. It takes one argument, a filename
to be included into this one. This works the same way as #include
does in C; as far as the user is concerned, the included file is
inlined into the current one.
Since config(8) is no longer limited to working on one user-supplied
file, printing just a line number in an error message is not
sufficient. The new global variable yyfile represents the file
currently being parsed, and must be printed as well.
Reviewed by: imp
Obtained from: OpenBSD
Diffstat (limited to 'usr.sbin/config/lang.l')
-rw-r--r-- | usr.sbin/config/lang.l | 85 |
1 files changed, 85 insertions, 0 deletions
diff --git a/usr.sbin/config/lang.l b/usr.sbin/config/lang.l index b968772..63e46e4 100644 --- a/usr.sbin/config/lang.l +++ b/usr.sbin/config/lang.l @@ -35,6 +35,7 @@ * $FreeBSD$ */ +#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 @@ struct kt { { "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 @@ ID [A-Za-z_][-A-Za-z_0-9]* ";" { 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]; } %% @@ -186,3 +214,60 @@ hex(char *str) (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); +} |