summaryrefslogtreecommitdiffstats
path: root/usr.sbin/config/lang.l
diff options
context:
space:
mode:
authordd <dd@FreeBSD.org>2001-07-12 02:08:51 +0000
committerdd <dd@FreeBSD.org>2001-07-12 02:08:51 +0000
commitb5164c6585fabc3c848ff92ada3f6ffb64a9e8f2 (patch)
tree6e5c6a1c595fde5e5c90b1af74b8c2880c887a37 /usr.sbin/config/lang.l
parent93faa5d597dce09f52a652cb24242bd11e6b6682 (diff)
downloadFreeBSD-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.l85
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);
+}
OpenPOWER on IntegriCloud