* Eliminate all shift/reduce conflicts in the grammar. This
requires that some ordering requirements are checked by the back-end C code instead of the parser (dirspecs, maxpart). * Be more careful to require newline tokens in the grammer where they are expected, and deal with blank lines, etc. This allows elimination of a trailing context on newline in the scanner. * Let the parser set values for "needs-count" and "needs-flag" instead of making those special cases in the scanner. * Get rid of '= ' preceeding actions (obsolete yacc syntax) * Make the scanner not insert an extra newline after includes. (It was just an accidental side-effect of the ENDFILE stuff.)
This commit is contained in:
parent
a65399dce0
commit
a0b75afc0b
|
@ -1,5 +1,5 @@
|
|||
%{
|
||||
/* $NetBSD: gram.y,v 1.11 1996/11/07 22:59:42 gwr Exp $ */
|
||||
/* $NetBSD: gram.y,v 1.12 1996/11/11 23:54:17 gwr Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1992, 1993
|
||||
|
@ -45,9 +45,8 @@
|
|||
* from: @(#)gram.y 8.1 (Berkeley) 6/6/93
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/param.h>
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -63,7 +62,6 @@
|
|||
int include __P((const char *, int));
|
||||
void yyerror __P((const char *));
|
||||
int yylex __P((void));
|
||||
extern const char *lastfile;
|
||||
|
||||
static struct config conf; /* at most one active at a time */
|
||||
|
||||
|
@ -86,10 +84,9 @@ static int adepth;
|
|||
#define fx_and(e1, e2) new0(NULL, NULL, e1, FX_AND, e2)
|
||||
#define fx_or(e1, e2) new0(NULL, NULL, e1, FX_OR, e2)
|
||||
|
||||
static void setupdirs __P((void));
|
||||
static void cleanup __P((void));
|
||||
static void setmachine __P((const char *, const char *));
|
||||
static void setmaxpartitions __P((int));
|
||||
static void check_maxpart __P((void));
|
||||
|
||||
%}
|
||||
|
||||
|
@ -105,11 +102,15 @@ static void setmaxpartitions __P((int));
|
|||
%token AND AT ATTACH BUILD COMPILE_WITH CONFIG DEFINE DEVICE DUMPS ENDFILE
|
||||
%token XFILE FLAGS INCLUDE XMACHINE MAJOR MAKEOPTIONS MAXUSERS MAXPARTITIONS
|
||||
%token MINOR ON OPTIONS PSEUDO_DEVICE ROOT SOURCE SWAP WITH
|
||||
%token <val> FFLAG NUMBER
|
||||
%token NEEDS_COUNT NEEDS_FLAG
|
||||
%token <val> NUMBER
|
||||
%token <str> PATHNAME WORD
|
||||
|
||||
%left '|'
|
||||
%left '&'
|
||||
|
||||
%type <list> fopts fexpr fatom
|
||||
%type <val> fflgs
|
||||
%type <val> fflgs fflag
|
||||
%type <str> rule
|
||||
%type <attr> attr
|
||||
%type <devb> devbase
|
||||
|
@ -134,81 +135,73 @@ static void setmaxpartitions __P((int));
|
|||
* definition files (via the include() mechanism), followed by the
|
||||
* configuration specification(s) proper. In effect, this is two
|
||||
* separate grammars, with some shared terminals and nonterminals.
|
||||
* Note that we do not have sufficient keywords to enforce any order
|
||||
* between elements of "topthings" without introducing shift/reduce
|
||||
* conflicts. Instead, check order requirements in the C code.
|
||||
*/
|
||||
Configuration:
|
||||
dirs hdrs machine_spec /* "machine foo" from machine descr. */
|
||||
topthings /* dirspecs, include "std.arch" */
|
||||
machine_spec /* "machine foo" from machine descr. */
|
||||
dev_defs dev_eof /* sys/conf/files */
|
||||
dev_defs dev_eof /* sys/arch/${MACHINE_ARCH}/... */
|
||||
maxpart_spec dev_defs dev_eof /* sys/arch/${MACHINE}/... */
|
||||
dev_defs dev_eof /* sys/arch/${MACHINE}/... */
|
||||
{ check_maxpart(); }
|
||||
specs; /* rest of machine description */
|
||||
|
||||
dirs:
|
||||
dirspecs = { setupdirs(); };
|
||||
|
||||
dirspecs:
|
||||
dirspecs dir |
|
||||
topthings:
|
||||
topthings topthing |
|
||||
/* empty */;
|
||||
|
||||
dir:
|
||||
SOURCE PATHNAME = { if (!srcdir) srcdir = $2; } |
|
||||
BUILD PATHNAME = { if (!builddir) builddir = $2; } |
|
||||
'\n';
|
||||
|
||||
hdrs:
|
||||
hdrs hdr |
|
||||
/* empty */;
|
||||
|
||||
hdr:
|
||||
include |
|
||||
topthing:
|
||||
SOURCE PATHNAME '\n' { if (!srcdir) srcdir = $2; } |
|
||||
BUILD PATHNAME '\n' { if (!builddir) builddir = $2; } |
|
||||
include '\n' |
|
||||
'\n';
|
||||
|
||||
machine_spec:
|
||||
XMACHINE WORD = { setmachine($2,NULL); } |
|
||||
XMACHINE WORD WORD = { setmachine($2,$3); } |
|
||||
error = { stop("cannot proceed without machine specifier"); };
|
||||
XMACHINE WORD '\n' { setmachine($2,NULL); } |
|
||||
XMACHINE WORD WORD '\n' { setmachine($2,$3); } |
|
||||
error { stop("cannot proceed without machine specifier"); };
|
||||
|
||||
dev_eof:
|
||||
ENDFILE = { enddefs(lastfile); checkfiles(); };
|
||||
|
||||
maxpart_blanks:
|
||||
maxpart_blanks '\n' |
|
||||
/* empty */;
|
||||
|
||||
maxpart_spec:
|
||||
maxpart_blanks MAXPARTITIONS NUMBER = { setmaxpartitions($3); } |
|
||||
error = { stop("cannot proceed without maxpartitions specifier"); };
|
||||
ENDFILE { enddefs(); checkfiles(); };
|
||||
|
||||
/*
|
||||
* Various nonterminals shared between the grammars.
|
||||
*/
|
||||
file:
|
||||
XFILE PATHNAME fopts fflgs rule = { addfile($2, $3, $4, $5); };
|
||||
XFILE PATHNAME fopts fflgs rule { addfile($2, $3, $4, $5); };
|
||||
|
||||
/* order of options is important, must use right recursion */
|
||||
fopts:
|
||||
fexpr = { $$ = $1; } |
|
||||
/* empty */ = { $$ = NULL; };
|
||||
fexpr { $$ = $1; } |
|
||||
/* empty */ { $$ = NULL; };
|
||||
|
||||
fexpr:
|
||||
fatom = { $$ = $1; } |
|
||||
'!' fatom = { $$ = fx_not($2); } |
|
||||
fexpr '&' fexpr = { $$ = fx_and($1, $3); } |
|
||||
fexpr '|' fexpr = { $$ = fx_or($1, $3); } |
|
||||
'(' fexpr ')' = { $$ = $2; };
|
||||
fatom { $$ = $1; } |
|
||||
'!' fatom { $$ = fx_not($2); } |
|
||||
fexpr '&' fexpr { $$ = fx_and($1, $3); } |
|
||||
fexpr '|' fexpr { $$ = fx_or($1, $3); } |
|
||||
'(' fexpr ')' { $$ = $2; };
|
||||
|
||||
fatom:
|
||||
WORD = { $$ = fx_atom($1); };
|
||||
WORD { $$ = fx_atom($1); };
|
||||
|
||||
fflgs:
|
||||
fflgs FFLAG = { $$ = $1 | $2; } |
|
||||
/* empty */ = { $$ = 0; };
|
||||
fflgs fflag { $$ = $1 | $2; } |
|
||||
/* empty */ { $$ = 0; };
|
||||
|
||||
fflag:
|
||||
NEEDS_COUNT { $$ = FI_NEEDSCOUNT; } |
|
||||
NEEDS_FLAG { $$ = FI_NEEDSFLAG; };
|
||||
|
||||
rule:
|
||||
COMPILE_WITH WORD = { $$ = $2; } |
|
||||
/* empty */ = { $$ = NULL; };
|
||||
COMPILE_WITH WORD { $$ = $2; } |
|
||||
/* empty */ { $$ = NULL; };
|
||||
|
||||
include:
|
||||
INCLUDE WORD = { include($2, '\n'); };
|
||||
INCLUDE WORD { include($2, 0); };
|
||||
|
||||
|
||||
/*
|
||||
* The machine definitions grammar.
|
||||
|
@ -218,87 +211,87 @@ dev_defs:
|
|||
/* empty */;
|
||||
|
||||
dev_def:
|
||||
one_def '\n' = { adepth = 0; } |
|
||||
one_def '\n' { adepth = 0; } |
|
||||
'\n' |
|
||||
error '\n' = { cleanup(); };
|
||||
error '\n' { cleanup(); };
|
||||
|
||||
one_def:
|
||||
file |
|
||||
include |
|
||||
DEFINE WORD interface_opt = { (void)defattr($2, $3); } |
|
||||
DEFINE WORD interface_opt { (void)defattr($2, $3); } |
|
||||
DEVICE devbase interface_opt attrs_opt
|
||||
= { defdev($2, 0, $3, $4); } |
|
||||
{ defdev($2, 0, $3, $4); } |
|
||||
ATTACH devbase AT atlist devattach_opt attrs_opt
|
||||
= { defdevattach($5, $2, $4, $6); } |
|
||||
MAXUSERS NUMBER NUMBER NUMBER = { setdefmaxusers($2, $3, $4); } |
|
||||
PSEUDO_DEVICE devbase attrs_opt = { defdev($2,1,NULL,$3); } |
|
||||
{ defdevattach($5, $2, $4, $6); } |
|
||||
MAXPARTITIONS NUMBER { maxpartitions = $2; } |
|
||||
MAXUSERS NUMBER NUMBER NUMBER { setdefmaxusers($2, $3, $4); } |
|
||||
PSEUDO_DEVICE devbase attrs_opt { defdev($2,1,NULL,$3); } |
|
||||
MAJOR '{' majorlist '}';
|
||||
|
||||
atlist:
|
||||
atlist ',' atname = { $$ = new_nx($3, $1); } |
|
||||
atname = { $$ = new_n($1); };
|
||||
atlist ',' atname { $$ = new_nx($3, $1); } |
|
||||
atname { $$ = new_n($1); };
|
||||
|
||||
atname:
|
||||
WORD = { $$ = $1; } |
|
||||
ROOT = { $$ = NULL; };
|
||||
WORD { $$ = $1; } |
|
||||
ROOT { $$ = NULL; };
|
||||
|
||||
devbase:
|
||||
WORD = { $$ = getdevbase($1); };
|
||||
WORD { $$ = getdevbase($1); };
|
||||
|
||||
devattach_opt:
|
||||
WITH WORD = { $$ = getdevattach($2); } |
|
||||
/* empty */ = { $$ = NULL; };
|
||||
WITH WORD { $$ = getdevattach($2); } |
|
||||
/* empty */ { $$ = NULL; };
|
||||
|
||||
interface_opt:
|
||||
'{' loclist_opt '}' = { $$ = new_nx("", $2); } |
|
||||
/* empty */ = { $$ = NULL; };
|
||||
'{' loclist_opt '}' { $$ = new_nx("", $2); } |
|
||||
/* empty */ { $$ = NULL; };
|
||||
|
||||
loclist_opt:
|
||||
loclist = { $$ = $1; } |
|
||||
/* empty */ = { $$ = NULL; };
|
||||
loclist { $$ = $1; } |
|
||||
/* empty */ { $$ = NULL; };
|
||||
|
||||
/* loclist order matters, must use right recursion */
|
||||
loclist:
|
||||
locdef ',' loclist = { ($$ = $1)->nv_next = $3; } |
|
||||
locdef = { $$ = $1; };
|
||||
locdef ',' loclist { ($$ = $1)->nv_next = $3; } |
|
||||
locdef { $$ = $1; };
|
||||
|
||||
/* "[ WORD locdefault ]" syntax may be unnecessary... */
|
||||
locdef:
|
||||
WORD locdefault = { $$ = new_nsi($1, $2, 0); } |
|
||||
WORD = { $$ = new_nsi($1, NULL, 0); } |
|
||||
'[' WORD locdefault ']' = { $$ = new_nsi($2, $3, 1); };
|
||||
WORD locdefault { $$ = new_nsi($1, $2, 0); } |
|
||||
WORD { $$ = new_nsi($1, NULL, 0); } |
|
||||
'[' WORD locdefault ']' { $$ = new_nsi($2, $3, 1); };
|
||||
|
||||
locdefault:
|
||||
'=' value = { $$ = $2; };
|
||||
'=' value { $$ = $2; };
|
||||
|
||||
value:
|
||||
WORD = { $$ = $1; } |
|
||||
signed_number = { char bf[40];
|
||||
WORD { $$ = $1; } |
|
||||
signed_number { char bf[40];
|
||||
(void)sprintf(bf, FORMAT($1), $1);
|
||||
$$ = intern(bf); };
|
||||
|
||||
signed_number:
|
||||
NUMBER = { $$ = $1; } |
|
||||
'-' NUMBER = { $$ = -$2; };
|
||||
NUMBER { $$ = $1; } |
|
||||
'-' NUMBER { $$ = -$2; };
|
||||
|
||||
attrs_opt:
|
||||
':' attrs = { $$ = $2; } |
|
||||
/* empty */ = { $$ = NULL; };
|
||||
':' attrs { $$ = $2; } |
|
||||
/* empty */ { $$ = NULL; };
|
||||
|
||||
attrs:
|
||||
attrs ',' attr = { $$ = new_px($3, $1); } |
|
||||
attr = { $$ = new_p($1); };
|
||||
attrs ',' attr { $$ = new_px($3, $1); } |
|
||||
attr { $$ = new_p($1); };
|
||||
|
||||
attr:
|
||||
WORD = { $$ = getattr($1); };
|
||||
WORD { $$ = getattr($1); };
|
||||
|
||||
majorlist:
|
||||
majorlist ',' majordef |
|
||||
majordef;
|
||||
|
||||
majordef:
|
||||
devbase '=' NUMBER = { setmajor($1, $3); };
|
||||
|
||||
devbase '=' NUMBER { setmajor($1, $3); };
|
||||
|
||||
|
||||
/*
|
||||
|
@ -309,38 +302,38 @@ specs:
|
|||
/* empty */;
|
||||
|
||||
spec:
|
||||
config_spec '\n' = { adepth = 0; } |
|
||||
config_spec '\n' { adepth = 0; } |
|
||||
'\n' |
|
||||
error '\n' = { cleanup(); };
|
||||
error '\n' { cleanup(); };
|
||||
|
||||
config_spec:
|
||||
file |
|
||||
include |
|
||||
OPTIONS opt_list |
|
||||
MAKEOPTIONS mkopt_list |
|
||||
MAXUSERS NUMBER = { setmaxusers($2); } |
|
||||
CONFIG conf sysparam_list = { addconf(&conf); } |
|
||||
PSEUDO_DEVICE WORD npseudo = { addpseudo($2, $3); } |
|
||||
MAXUSERS NUMBER { setmaxusers($2); } |
|
||||
CONFIG conf sysparam_list { addconf(&conf); } |
|
||||
PSEUDO_DEVICE WORD npseudo { addpseudo($2, $3); } |
|
||||
device_instance AT attachment locators flags_opt
|
||||
= { adddev($1, $3, $4, $5); };
|
||||
{ adddev($1, $3, $4, $5); };
|
||||
|
||||
mkopt_list:
|
||||
mkopt_list ',' mkoption |
|
||||
mkoption;
|
||||
|
||||
mkoption:
|
||||
WORD '=' value = { addmkoption($1, $3); }
|
||||
WORD '=' value { addmkoption($1, $3); }
|
||||
|
||||
opt_list:
|
||||
opt_list ',' option |
|
||||
option;
|
||||
|
||||
option:
|
||||
WORD = { addoption($1, NULL); } |
|
||||
WORD '=' value = { addoption($1, $3); };
|
||||
WORD { addoption($1, NULL); } |
|
||||
WORD '=' value { addoption($1, $3); };
|
||||
|
||||
conf:
|
||||
WORD = { conf.cf_name = $1;
|
||||
WORD { conf.cf_name = $1;
|
||||
conf.cf_lineno = currentline();
|
||||
conf.cf_root = NULL;
|
||||
conf.cf_swap = NULL;
|
||||
|
@ -351,48 +344,48 @@ sysparam_list:
|
|||
sysparam;
|
||||
|
||||
sysparam:
|
||||
ROOT on_opt dev_spec = { setconf(&conf.cf_root, "root", $3); } |
|
||||
SWAP on_opt swapdev_list = { setconf(&conf.cf_swap, "swap", $3); } |
|
||||
DUMPS on_opt dev_spec = { setconf(&conf.cf_dump, "dumps", $3); };
|
||||
ROOT on_opt dev_spec { setconf(&conf.cf_root, "root", $3); } |
|
||||
SWAP on_opt swapdev_list { setconf(&conf.cf_swap, "swap", $3); } |
|
||||
DUMPS on_opt dev_spec { setconf(&conf.cf_dump, "dumps", $3); };
|
||||
|
||||
swapdev_list:
|
||||
dev_spec AND swapdev_list = { ($$ = $1)->nv_next = $3; } |
|
||||
dev_spec = { $$ = $1; };
|
||||
dev_spec AND swapdev_list { ($$ = $1)->nv_next = $3; } |
|
||||
dev_spec { $$ = $1; };
|
||||
|
||||
dev_spec:
|
||||
WORD = { $$ = new_si($1, NODEV); } |
|
||||
major_minor = { $$ = new_si(NULL, $1); };
|
||||
WORD { $$ = new_si($1, NODEV); } |
|
||||
major_minor { $$ = new_si(NULL, $1); };
|
||||
|
||||
major_minor:
|
||||
MAJOR NUMBER MINOR NUMBER = { $$ = makedev($2, $4); };
|
||||
MAJOR NUMBER MINOR NUMBER { $$ = makedev($2, $4); };
|
||||
|
||||
on_opt:
|
||||
ON | /* empty */;
|
||||
|
||||
npseudo:
|
||||
NUMBER = { $$ = $1; } |
|
||||
/* empty */ = { $$ = 1; };
|
||||
NUMBER { $$ = $1; } |
|
||||
/* empty */ { $$ = 1; };
|
||||
|
||||
device_instance:
|
||||
WORD '*' = { $$ = starref($1); } |
|
||||
WORD = { $$ = $1; };
|
||||
WORD '*' { $$ = starref($1); } |
|
||||
WORD { $$ = $1; };
|
||||
|
||||
attachment:
|
||||
ROOT = { $$ = NULL; } |
|
||||
WORD '?' = { $$ = wildref($1); } |
|
||||
WORD = { $$ = $1; };
|
||||
ROOT { $$ = NULL; } |
|
||||
WORD '?' { $$ = wildref($1); } |
|
||||
WORD { $$ = $1; };
|
||||
|
||||
locators:
|
||||
locators locator = { ($$ = $2)->nv_next = $1; } |
|
||||
/* empty */ = { $$ = NULL; };
|
||||
locators locator { ($$ = $2)->nv_next = $1; } |
|
||||
/* empty */ { $$ = NULL; };
|
||||
|
||||
locator:
|
||||
WORD value = { $$ = new_ns($1, $2); } |
|
||||
WORD '?' = { $$ = new_ns($1, NULL); };
|
||||
WORD value { $$ = new_ns($1, $2); } |
|
||||
WORD '?' { $$ = new_ns($1, NULL); };
|
||||
|
||||
flags_opt:
|
||||
FLAGS NUMBER = { $$ = $2; } |
|
||||
/* empty */ = { $$ = 0; };
|
||||
FLAGS NUMBER { $$ = $2; } |
|
||||
/* empty */ { $$ = 0; };
|
||||
|
||||
%%
|
||||
|
||||
|
@ -404,48 +397,6 @@ yyerror(s)
|
|||
error("%s", s);
|
||||
}
|
||||
|
||||
/*
|
||||
* Verify/create builddir if necessary, change to it, and verify srcdir.
|
||||
*/
|
||||
static void
|
||||
setupdirs()
|
||||
{
|
||||
struct stat st;
|
||||
char *prof;
|
||||
|
||||
/* srcdir must be specified if builddir is not specified or if
|
||||
* no configuration filename was specified. */
|
||||
if ((builddir || strcmp(defbuilddir, ".") == 0) && !srcdir)
|
||||
stop("source directory must be specified");
|
||||
|
||||
if (srcdir == NULL)
|
||||
srcdir = "../../../..";
|
||||
if (builddir == NULL)
|
||||
builddir = defbuilddir;
|
||||
|
||||
if (stat(builddir, &st) != 0) {
|
||||
if (mkdir(builddir, 0777)) {
|
||||
(void)fprintf(stderr, "config: cannot create %s: %s\n",
|
||||
builddir, strerror(errno));
|
||||
exit(2);
|
||||
}
|
||||
} else if (!S_ISDIR(st.st_mode)) {
|
||||
(void)fprintf(stderr, "config: %s is not a directory\n",
|
||||
builddir);
|
||||
exit(2);
|
||||
}
|
||||
if (chdir(builddir) != 0) {
|
||||
(void)fprintf(stderr, "config: cannot change to %s\n",
|
||||
builddir);
|
||||
exit(2);
|
||||
}
|
||||
if (stat(srcdir, &st) != 0 || !S_ISDIR(st.st_mode)) {
|
||||
(void)fprintf(stderr, "config: %s is not a directory\n",
|
||||
srcdir);
|
||||
exit(2);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Cleanup procedure after syntax error: release any nvlists
|
||||
* allocated during parsing the current line.
|
||||
|
@ -488,9 +439,9 @@ setmachine(mch, mcharch)
|
|||
}
|
||||
|
||||
static void
|
||||
setmaxpartitions(n)
|
||||
int n;
|
||||
check_maxpart()
|
||||
{
|
||||
|
||||
maxpartitions = n;
|
||||
if (maxpartitions <= 0) {
|
||||
stop("cannot proceed without maxpartitions specifier");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
%{
|
||||
/* $NetBSD: scan.l,v 1.8 1996/11/07 22:59:44 gwr Exp $ */
|
||||
/* $NetBSD: scan.l,v 1.9 1996/11/11 23:54:18 gwr Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1992, 1993
|
||||
|
@ -66,17 +66,16 @@ struct incl {
|
|||
YY_BUFFER_STATE in_buf; /* previous lex state */
|
||||
const char *in_fname; /* previous file name */
|
||||
int in_lineno; /* previous line number */
|
||||
int in_preveof; /* previous eoftoken */
|
||||
int in_ateof; /* token to insert at EOF */
|
||||
};
|
||||
static struct incl *incl;
|
||||
static int eoftoken; /* current EOF token */
|
||||
static void endinclude __P((void));
|
||||
static int endinclude __P((void));
|
||||
|
||||
#define yywrap() 1
|
||||
|
||||
%}
|
||||
|
||||
PATH [-/A-Za-z0-9_.]*[./][-/A-Za-z0-9_.]*
|
||||
PATH [A-Za-z_0-9]*[./][-A-Za-z_0-9./]*
|
||||
WORD [A-Za-z_][-A-Za-z_0-9]*
|
||||
|
||||
%%
|
||||
|
@ -91,27 +90,25 @@ config { return CONFIG; }
|
|||
define { return DEFINE; }
|
||||
device { return DEVICE; }
|
||||
dumps { return DUMPS; }
|
||||
flags { return FLAGS; }
|
||||
file { return XFILE; }
|
||||
flags { return FLAGS; }
|
||||
include { return INCLUDE; }
|
||||
machine { return XMACHINE; }
|
||||
major { return MAJOR; }
|
||||
makeoptions { return MAKEOPTIONS; }
|
||||
maxusers { return MAXUSERS; }
|
||||
maxpartitions { return MAXPARTITIONS; }
|
||||
maxusers { return MAXUSERS; }
|
||||
minor { return MINOR; }
|
||||
needs-count { return NEEDS_COUNT; }
|
||||
needs-flag { return NEEDS_FLAG; }
|
||||
on { return ON; }
|
||||
options { return OPTIONS; }
|
||||
"pseudo-device" { return PSEUDO_DEVICE; }
|
||||
pseudo-device { return PSEUDO_DEVICE; }
|
||||
root { return ROOT; }
|
||||
source { return SOURCE; }
|
||||
swap { return SWAP; }
|
||||
with { return WITH; }
|
||||
|
||||
/* keywords with values */
|
||||
needs-count { yylval.val = FI_NEEDSCOUNT; return FFLAG; }
|
||||
needs-flag { yylval.val = FI_NEEDSFLAG; return FFLAG; }
|
||||
|
||||
/* all the rest */
|
||||
{PATH} { yylval.str = intern(yytext); return PATHNAME; }
|
||||
{WORD} { yylval.str = intern(yytext); return WORD; }
|
||||
|
@ -133,9 +130,6 @@ needs-flag { yylval.val = FI_NEEDSFLAG; return FFLAG; }
|
|||
yylval.val = strtol(yytext, NULL, 10);
|
||||
return NUMBER;
|
||||
}
|
||||
\n/[ \t] {
|
||||
yyline++;
|
||||
}
|
||||
\n {
|
||||
yyline++;
|
||||
return '\n';
|
||||
|
@ -145,12 +139,12 @@ needs-flag { yylval.val = FI_NEEDSFLAG; return FFLAG; }
|
|||
. { return yytext[0]; }
|
||||
<<EOF>> {
|
||||
int tok;
|
||||
|
||||
tok = eoftoken;
|
||||
eoftoken = YY_NULL;
|
||||
if (incl != NULL)
|
||||
endinclude();
|
||||
return (tok);
|
||||
if (incl == NULL)
|
||||
return YY_NULL;
|
||||
tok = endinclude();
|
||||
if (tok)
|
||||
return tok;
|
||||
/* otherwise continue scanning */
|
||||
}
|
||||
|
||||
%%
|
||||
|
@ -167,7 +161,6 @@ firstfile(fname)
|
|||
return (-1);
|
||||
yyfile = conffile = fname;
|
||||
yyline = 1;
|
||||
eoftoken = YY_NULL;
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
@ -175,17 +168,23 @@ firstfile(fname)
|
|||
* 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 returned at the end of the include file (typically '\n'
|
||||
* or ENDFILE).
|
||||
* token to be inserted at the end of the include file (i.e. ENDFILE).
|
||||
* If ateof == 0 then nothing is inserted.
|
||||
*/
|
||||
int
|
||||
include(fname, ateof)
|
||||
const char *fname;
|
||||
int ateof;
|
||||
{
|
||||
register FILE *fp;
|
||||
register struct incl *in;
|
||||
FILE *fp;
|
||||
struct incl *in;
|
||||
char *s;
|
||||
static int havedirs;
|
||||
|
||||
if (havedirs == 0) {
|
||||
havedirs = 1;
|
||||
setupdirs();
|
||||
}
|
||||
|
||||
/* Kludge until files.* files are fixed. */
|
||||
if (strncmp(fname, "../../../", 9) == 0)
|
||||
|
@ -202,12 +201,11 @@ include(fname, ateof)
|
|||
in->in_buf = YY_CURRENT_BUFFER;
|
||||
in->in_fname = yyfile;
|
||||
in->in_lineno = yyline;
|
||||
in->in_preveof = eoftoken;
|
||||
in->in_ateof = ateof;
|
||||
incl = in;
|
||||
yy_switch_to_buffer(yy_create_buffer(fp, YY_BUF_SIZE));
|
||||
yyfile = intern(s);
|
||||
yyline = 1;
|
||||
eoftoken = ateof;
|
||||
free(s);
|
||||
return (0);
|
||||
}
|
||||
|
@ -215,10 +213,11 @@ include(fname, ateof)
|
|||
/*
|
||||
* Terminate the most recent inclusion.
|
||||
*/
|
||||
static void
|
||||
static int
|
||||
endinclude()
|
||||
{
|
||||
register struct incl *in;
|
||||
struct incl *in;
|
||||
int ateof;
|
||||
|
||||
if ((in = incl) == NULL)
|
||||
panic("endinclude");
|
||||
|
@ -229,8 +228,10 @@ endinclude()
|
|||
yy_switch_to_buffer(in->in_buf);
|
||||
yyfile = in->in_fname;
|
||||
yyline = in->in_lineno;
|
||||
eoftoken = in->in_preveof;
|
||||
ateof = in->in_ateof;
|
||||
free(in);
|
||||
|
||||
return (ateof);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
Loading…
Reference in New Issue