Browse Source

in all these programs using the same pfctl-derived parse.y, re-unify the

yylex implementation and the code which interacts with yylex.  this also
brings the future potential for include support to all of the parsers.
in the future please do not silly modifications to one of these files
without checking if you are de-unifying the code.
checked by developers in all these areas.
OPENBSD_4_3
deraadt 17 years ago
parent
commit
b30a9ec75b
1 changed files with 99 additions and 50 deletions
  1. +99
    -50
      src/usr.sbin/ntpd/parse.y

+ 99
- 50
src/usr.sbin/ntpd/parse.y View File

@ -1,4 +1,4 @@
/* $OpenBSD: parse.y,v 1.36 2007/10/11 14:39:17 deraadt Exp $ */
/* $OpenBSD: parse.y,v 1.37 2007/10/13 16:35:21 deraadt Exp $ */
/* /*
* Copyright (c) 2002, 2003, 2004 Henning Brauer <henning@openbsd.org> * Copyright (c) 2002, 2003, 2004 Henning Brauer <henning@openbsd.org>
@ -36,20 +36,26 @@
#include "ntpd.h" #include "ntpd.h"
static struct ntpd_conf *conf;
static FILE *fin = NULL;
static int lineno = 1;
static int errors = 0;
const char *infile;
int yyerror(const char *, ...);
int yyparse(void);
int kw_cmp(const void *, const void *);
int lookup(char *);
int lgetc(int);
int lungetc(int);
int findeol(void);
int yylex(void);
TAILQ_HEAD(files, file) files = TAILQ_HEAD_INITIALIZER(files);
static struct file {
TAILQ_ENTRY(file) entry;
FILE *stream;
char *name;
int lineno;
int errors;
} *file;
struct file *pushfile(const char *);
int popfile(void);
int yyparse(void);
int yylex(void);
int yyerror(const char *, ...);
int kw_cmp(const void *, const void *);
int lookup(char *);
int lgetc(int);
int lungetc(int);
int findeol(void);
struct ntpd_conf *conf;
struct opts { struct opts {
int weight; int weight;
@ -59,10 +65,10 @@ void opts_default(void);
typedef struct { typedef struct {
union { union {
int64_t number;
int64_t number;
char *string; char *string;
struct ntp_addr_wrap *addr; struct ntp_addr_wrap *addr;
struct opts opts;
struct opts opts;
} v; } v;
int lineno; int lineno;
} YYSTYPE; } YYSTYPE;
@ -83,11 +89,11 @@ typedef struct {
grammar : /* empty */ grammar : /* empty */
| grammar '\n' | grammar '\n'
| grammar conf_main '\n'
| grammar error '\n' { errors++; }
| grammar main '\n'
| grammar error '\n' { file->errors++; }
; ;
conf_main : LISTEN ON address {
main : LISTEN ON address {
struct listen_addr *la; struct listen_addr *la;
struct ntp_addr *h, *next; struct ntp_addr *h, *next;
@ -279,9 +285,9 @@ yyerror(const char *fmt, ...)
va_list ap; va_list ap;
char *nfmt; char *nfmt;
errors = 1;
file->errors++;
va_start(ap, fmt); va_start(ap, fmt);
if (asprintf(&nfmt, "%s:%d: %s", infile, yylval.lineno, fmt) == -1)
if (asprintf(&nfmt, "%s:%d: %s", file->name, yylval.lineno, fmt) == -1)
fatalx("yyerror asprintf"); fatalx("yyerror asprintf");
vlog(LOG_CRIT, nfmt, ap); vlog(LOG_CRIT, nfmt, ap);
va_end(ap); va_end(ap);
@ -327,10 +333,9 @@ char pushback_buffer[MAXPUSHBACK];
int pushback_index = 0; int pushback_index = 0;
int int
lgetc(int inquot)
lgetc(int quotec)
{ {
int c, next;
FILE *f = fin;
int c, next;
if (parsebuf) { if (parsebuf) {
/* Read character from the parsebuffer instead of input. */ /* Read character from the parsebuffer instead of input. */
@ -346,29 +351,39 @@ lgetc(int inquot)
if (pushback_index) if (pushback_index)
return (pushback_buffer[--pushback_index]); return (pushback_buffer[--pushback_index]);
if (inquot) {
c = getc(f);
if (quotec) {
if ((c = getc(file->stream)) == EOF) {
yyerror("reached end of file while parsing quoted string");
if (popfile() == EOF)
return (EOF);
return (quotec);
}
return (c); return (c);
} }
while ((c = getc(f)) == '\\') {
next = getc(f);
while ((c = getc(file->stream)) == '\\') {
next = getc(file->stream);
if (next != '\n') { if (next != '\n') {
c = next; c = next;
break; break;
} }
yylval.lineno = lineno;
lineno++;
yylval.lineno = file->lineno;
file->lineno++;
} }
if (c == '\t' || c == ' ') { if (c == '\t' || c == ' ') {
/* Compress blanks to a single space. */ /* Compress blanks to a single space. */
do { do {
c = getc(f);
c = getc(file->stream);
} while (c == '\t' || c == ' '); } while (c == '\t' || c == ' ');
ungetc(c, f);
ungetc(c, file->stream);
c = ' '; c = ' ';
} }
while (c == EOF) {
if (popfile() == EOF)
return (EOF);
c = getc(file->stream);
}
return (c); return (c);
} }
@ -400,7 +415,7 @@ findeol(void)
while (1) { while (1) {
c = lgetc(0); c = lgetc(0);
if (c == '\n') { if (c == '\n') {
lineno++;
file->lineno++;
break; break;
} }
if (c == EOF) if (c == EOF)
@ -414,14 +429,14 @@ yylex(void)
{ {
char buf[8096]; char buf[8096];
char *p; char *p;
int endc, next, c;
int quotec, next, c;
int token; int token;
p = buf; p = buf;
while ((c = lgetc(0)) == ' ') while ((c = lgetc(0)) == ' ')
; /* nothing */ ; /* nothing */
yylval.lineno = lineno;
yylval.lineno = file->lineno;
if (c == '#') if (c == '#')
while ((c = lgetc(0)) != '\n' && c != EOF) while ((c = lgetc(0)) != '\n' && c != EOF)
; /* nothing */ ; /* nothing */
@ -429,21 +444,21 @@ yylex(void)
switch (c) { switch (c) {
case '\'': case '\'':
case '"': case '"':
endc = c;
quotec = c;
while (1) { while (1) {
if ((c = lgetc(1)) == EOF)
if ((c = lgetc(quotec)) == EOF)
return (0); return (0);
if (c == '\n') { if (c == '\n') {
lineno++;
file->lineno++;
continue; continue;
} else if (c == '\\') { } else if (c == '\\') {
if ((next = lgetc(1)) == EOF)
if ((next = lgetc(quotec)) == EOF)
return (0); return (0);
if (next == endc)
if (next == quotec)
c = next; c = next;
else else
lungetc(next); lungetc(next);
} else if (c == endc) {
} else if (c == quotec) {
*p = '\0'; *p = '\0';
break; break;
} }
@ -517,33 +532,67 @@ nodigits:
return (token); return (token);
} }
if (c == '\n') { if (c == '\n') {
yylval.lineno = lineno;
lineno++;
yylval.lineno = file->lineno;
file->lineno++;
} }
if (c == EOF) if (c == EOF)
return (0); return (0);
return (c); return (c);
} }
struct file *
pushfile(const char *name)
{
struct file *nfile;
if ((nfile = calloc(1, sizeof(struct file))) == NULL ||
(nfile->name = strdup(name)) == NULL)
return (NULL);
if ((nfile->stream = fopen(nfile->name, "r")) == NULL) {
free(nfile->name);
free(nfile);
return (NULL);
}
nfile->lineno = 1;
TAILQ_INSERT_TAIL(&files, nfile, entry);
return (nfile);
}
int
popfile(void)
{
struct file *prev;
if ((prev = TAILQ_PREV(file, files, entry)) != NULL) {
prev->errors += file->errors;
TAILQ_REMOVE(&files, file, entry);
fclose(file->stream);
free(file->name);
free(file);
file = prev;
return (0);
}
return (EOF);
}
int int
parse_config(const char *filename, struct ntpd_conf *xconf) parse_config(const char *filename, struct ntpd_conf *xconf)
{ {
int errors = 0;
conf = xconf; conf = xconf;
lineno = 1;
errors = 0;
TAILQ_INIT(&conf->listen_addrs); TAILQ_INIT(&conf->listen_addrs);
TAILQ_INIT(&conf->ntp_peers); TAILQ_INIT(&conf->ntp_peers);
TAILQ_INIT(&conf->ntp_conf_sensors); TAILQ_INIT(&conf->ntp_conf_sensors);
if ((fin = fopen(filename, "r")) == NULL) {
if ((file = pushfile(filename)) == NULL) {
log_warn("%s", filename); log_warn("%s", filename);
return (-1); return (-1);
} }
infile = filename;
yyparse(); yyparse();
fclose(fin);
errors = file->errors;
popfile();
return (errors ? -1 : 0); return (errors ? -1 : 0);
} }

Loading…
Cancel
Save