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
This commit is contained in:
Dima Dorfman 2001-07-12 02:08:51 +00:00
parent dc3c85941a
commit 5e06480c9f
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=79607
4 changed files with 102 additions and 8 deletions

View File

@ -142,6 +142,7 @@ extern struct device *dtab;
extern char errbuf[80];
extern int yyline;
extern const char *yyfile;
extern struct file_list *ftab;

View File

@ -17,6 +17,7 @@
%token OPTIONS
%token MAKEOPTIONS
%token SEMICOLON
%token INCLUDE
%token <str> ID
%token <val> NUMBER
@ -77,13 +78,14 @@ char *ident;
char *hints;
int hintmode;
int yyline;
const char *yyfile;
struct file_list *ftab;
char errbuf[80];
int maxusers;
#define ns(s) strdup(s)
static void yyerror(const char *s);
int include(const char *, int);
void yyerror(const char *s);
static char *
devopt(char *dev)
@ -147,11 +149,14 @@ Config_spec:
= {
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 @@ Option:
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 @@ Device_spec:
/* 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);
}
/*

View File

@ -35,6 +35,7 @@
* $FreeBSD$
*/
#include <assert.h>
#include <ctype.h>
#include <string.h>
#include "y.tab.h"
@ -42,6 +43,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);
}

View File

@ -144,6 +144,7 @@ main(int argc, char **argv)
errx(2, "%s isn't a directory", p);
dtab = NULL;
yyfile = *argv;
if (yyparse())
exit(3);
if (machinename == NULL) {