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:
parent
dc3c85941a
commit
5e06480c9f
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=79607
@ -142,6 +142,7 @@ extern struct device *dtab;
|
||||
|
||||
extern char errbuf[80];
|
||||
extern int yyline;
|
||||
extern const char *yyfile;
|
||||
|
||||
extern struct file_list *ftab;
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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) {
|
||||
|
Loading…
Reference in New Issue
Block a user