version 1.29, 2021/01/27 17:02:50 |
version 1.30, 2021/11/30 20:08:15 |
|
|
%{ |
%{ |
#include <sys/types.h> |
#include <sys/types.h> |
#include <ctype.h> |
#include <ctype.h> |
|
#include <limits.h> |
#include <unistd.h> |
#include <unistd.h> |
#include <stdint.h> |
#include <stdint.h> |
#include <stdarg.h> |
#include <stdarg.h> |
|
|
const char **strlist; |
const char **strlist; |
const char *str; |
const char *str; |
}; |
}; |
int lineno; |
unsigned long lineno; |
int colno; |
unsigned long colno; |
} yystype; |
} yystype; |
#define YYSTYPE yystype |
#define YYSTYPE yystype |
|
|
|
|
size_t nrules; |
size_t nrules; |
static size_t maxrules; |
static size_t maxrules; |
|
|
int parse_errors = 0; |
int parse_error = 0; |
|
|
static void yyerror(const char *, ...); |
static void yyerror(const char *, ...); |
static int yylex(void); |
static int yylex(void); |
|
|
va_start(va, fmt); |
va_start(va, fmt); |
vfprintf(stderr, fmt, va); |
vfprintf(stderr, fmt, va); |
va_end(va); |
va_end(va); |
fprintf(stderr, " at line %d\n", yylval.lineno + 1); |
fprintf(stderr, " at line %lu\n", yylval.lineno + 1); |
parse_errors++; |
parse_error = 1; |
} |
} |
|
|
static struct keyword { |
static struct keyword { |
|
|
yylex(void) |
yylex(void) |
{ |
{ |
char buf[1024], *ebuf, *p, *str; |
char buf[1024], *ebuf, *p, *str; |
int c, quotes = 0, escape = 0, qpos = -1, nonkw = 0; |
int c, quoted = 0, quotes = 0, qerr = 0, escape = 0, nonkw = 0; |
|
unsigned long qpos = 0; |
size_t i; |
size_t i; |
|
|
p = buf; |
p = buf; |
|
|
for (;; c = getc(yyfp), yylval.colno++) { |
for (;; c = getc(yyfp), yylval.colno++) { |
switch (c) { |
switch (c) { |
case '\0': |
case '\0': |
yyerror("unallowed character NUL in column %d", |
yyerror("unallowed character NUL in column %lu", |
yylval.colno + 1); |
yylval.colno + 1); |
escape = 0; |
escape = 0; |
continue; |
continue; |
|
|
continue; |
continue; |
break; |
break; |
case '\n': |
case '\n': |
if (quotes) |
if (quotes && !qerr) { |
yyerror("unterminated quotes in column %d", |
yyerror("unterminated quotes in column %lu", |
qpos + 1); |
qpos + 1); |
|
qerr = 1; |
|
} |
if (escape) { |
if (escape) { |
nonkw = 1; |
nonkw = 1; |
escape = 0; |
escape = 0; |
yylval.colno = 0; |
yylval.colno = ULONG_MAX; |
yylval.lineno++; |
yylval.lineno++; |
continue; |
continue; |
} |
} |
goto eow; |
goto eow; |
case EOF: |
case EOF: |
if (escape) |
if (escape) |
yyerror("unterminated escape in column %d", |
yyerror("unterminated escape in column %lu", |
yylval.colno); |
yylval.colno); |
if (quotes) |
if (quotes && !qerr) |
yyerror("unterminated quotes in column %d", |
yyerror("unterminated quotes in column %lu", |
qpos + 1); |
qpos + 1); |
goto eow; |
goto eow; |
/* FALLTHROUGH */ |
|
case '{': |
case '{': |
case '}': |
case '}': |
case '#': |
case '#': |
|
|
break; |
break; |
case '"': |
case '"': |
if (!escape) { |
if (!escape) { |
|
quoted = 1; |
quotes = !quotes; |
quotes = !quotes; |
if (quotes) { |
if (quotes) { |
nonkw = 1; |
nonkw = 1; |
|
qerr = 0; |
qpos = yylval.colno; |
qpos = yylval.colno; |
} |
} |
continue; |
continue; |
|
|
*/ |
*/ |
if (c == EOF) |
if (c == EOF) |
goto eof; |
goto eof; |
else if (qpos == -1) /* accept, e.g., empty args: cmd foo args "" */ |
else if (!quoted) /* accept, e.g., empty args: cmd foo args "" */ |
goto repeat; |
goto repeat; |
} |
} |
if (!nonkw) { |
if (!nonkw) { |