version 1.10, 2022/03/25 22:43:43 |
version 1.15, 2022/04/03 13:52:00 |
|
|
%{ |
%{ |
#include <sys/queue.h> |
#include <sys/queue.h> |
|
|
#include <stdio.h> |
|
#include <stdarg.h> |
|
#include <ctype.h> |
#include <ctype.h> |
|
#include <stdarg.h> |
|
#include <stdio.h> |
|
|
#include "blind.h" |
#include "blind.h" |
#include "config.h" |
#include "config.h" |
#include "log.h" |
#include "log.h" |
|
|
//TAILQ_HEAD(files, file) files = TAILQ_HEAD_INITIALIZER(files); |
|
static struct file { |
static struct file { |
// TAILQ_ENTRY(file) entry; |
FILE *stream; |
FILE *stream; |
char *name; |
char *name; |
size_t ungetpos; |
size_t ungetpos; |
size_t ungetsize; |
size_t ungetsize; |
u_char *ungetbuf; |
u_char *ungetbuf; |
int eof_reached; |
int eof_reached; |
int lineno; |
int lineno; |
} *f; |
int errors; |
|
} *file; |
|
//, *top; |
|
|
|
int lookup(char *); |
int lookup(char *); |
int igetc(void); |
int igetc(void); |
|
|
grammar : |
grammar : |
| grammar '\n' |
| grammar '\n' |
| grammar set '\n' |
| grammar set '\n' |
| grammar error '\n' { file->errors++; } |
| grammar error '\n' { errors++; } |
; |
; |
|
|
set : SET EXPIRE NUMBER { |
set : SET EXPIRE NUMBER { |
Line 114 yyerror(const char *fmt, ...) |
|
Line 110 yyerror(const char *fmt, ...) |
|
va_list ap; |
va_list ap; |
char *msg; |
char *msg; |
|
|
file->errors++; |
errors++; |
va_start(ap, fmt); |
va_start(ap, fmt); |
if (vasprintf(&msg, fmt, ap) == -1) |
if (vasprintf(&msg, fmt, ap) == -1) |
log_fatal("yyerror vasprintf"); |
log_fatal("yyerror vasprintf"); |
va_end(ap); |
va_end(ap); |
log_info("%s:%d: %s", file->name, yylval.lineno, msg); |
log_info("%s:%d: %s", f->name, yylval.lineno, msg); |
free(msg); |
free(msg); |
return (0); |
return (0); |
} |
} |
|
|
int c; |
int c; |
|
|
while (1) { |
while (1) { |
if (file->ungetpos > 0) |
if (f->ungetpos > 0) |
c = file->ungetbuf[--file->ungetpos]; |
c = f->ungetbuf[--f->ungetpos]; |
else |
else |
c = getc(file->stream); |
c = getc(f->stream); |
|
|
if (c == START_EXPAND) |
if (c == START_EXPAND) |
expanding = 1; |
expanding = 1; |
Line 201 lgetc(int quotec) |
|
Line 197 lgetc(int quotec) |
|
if ((c = igetc()) == EOF) { |
if ((c = igetc()) == EOF) { |
yyerror("reached end of file while parsing " |
yyerror("reached end of file while parsing " |
"quoted string"); |
"quoted string"); |
// if (file == top || config_pop() == EOF) |
|
if (config_pop() == EOF) |
if (config_pop() == EOF) |
return (EOF); |
return (EOF); |
return (quotec); |
return (quotec); |
Line 215 lgetc(int quotec) |
|
Line 210 lgetc(int quotec) |
|
c = next; |
c = next; |
break; |
break; |
} |
} |
yylval.lineno = file->lineno; |
yylval.lineno = f->lineno; |
file->lineno++; |
f->lineno++; |
} |
} |
|
|
if (c == EOF) { |
if (c == EOF) { |
Line 225 lgetc(int quotec) |
|
Line 220 lgetc(int quotec) |
|
* count right if last line in included file is syntactically |
* count right if last line in included file is syntactically |
* invalid and has no newline. |
* invalid and has no newline. |
*/ |
*/ |
if (file->eof_reached == 0) { |
if (f->eof_reached == 0) { |
file->eof_reached = 1; |
f->eof_reached = 1; |
return ('\n'); |
return ('\n'); |
} |
} |
while (c == EOF) { |
while (c == EOF) { |
//if (file == top || config_pop() == EOF) |
|
if (config_pop() == EOF) |
if (config_pop() == EOF) |
return (EOF); |
return (EOF); |
c = igetc(); |
c = igetc(); |
|
|
if (c == EOF) |
if (c == EOF) |
return; |
return; |
|
|
if (file->ungetpos >= file->ungetsize) { |
if (f->ungetpos >= f->ungetsize) { |
void *p = reallocarray(file->ungetbuf, file->ungetsize, 2); |
void *p = reallocarray(f->ungetbuf, f->ungetsize, 2); |
if (p == NULL) |
if (p == NULL) |
log_fatal("cannot reallocate memory"); |
log_fatal("cannot reallocate memory"); |
file->ungetbuf = p; |
f->ungetbuf = p; |
file->ungetsize *= 2; |
f->ungetsize *= 2; |
} |
} |
file->ungetbuf[file->ungetpos++] = c; |
f->ungetbuf[f->ungetpos++] = c; |
} |
} |
|
|
int |
int |
|
|
while (1) { |
while (1) { |
c = lgetc(0); |
c = lgetc(0); |
if (c == '\n') { |
if (c == '\n') { |
file->lineno++; |
f->lineno++; |
break; |
break; |
} |
} |
if (c == EOF) |
if (c == EOF) |
|
|
while ((c = lgetc(0)) == ' ' || c == '\t') |
while ((c = lgetc(0)) == ' ' || c == '\t') |
; /* nothing */ |
; /* nothing */ |
|
|
yylval.lineno = file->lineno; |
yylval.lineno = f->lineno; |
if (c == '#') |
if (c == '#') |
while ((c = lgetc(0)) != '\n' && c != EOF) |
while ((c = lgetc(0)) != '\n' && c != EOF) |
; /* nothing */ |
; /* nothing */ |
|
|
if ((c = lgetc(quotec)) == EOF) |
if ((c = lgetc(quotec)) == EOF) |
return (0); |
return (0); |
if (c == '\n') { |
if (c == '\n') { |
file->lineno++; |
f->lineno++; |
continue; |
continue; |
} else if (c == '\\') { |
} else if (c == '\\') { |
if ((next = lgetc(quotec)) == EOF) |
if ((next = lgetc(quotec)) == EOF) |
|
|
next == '\t') |
next == '\t') |
c = next; |
c = next; |
else if (next == '\n') { |
else if (next == '\n') { |
file->lineno++; |
f->lineno++; |
continue; |
continue; |
} else |
} else |
lungetc(next); |
lungetc(next); |
|
|
return (token); |
return (token); |
} |
} |
if (c == '\n') { |
if (c == '\n') { |
yylval.lineno = file->lineno; |
yylval.lineno = f->lineno; |
file->lineno++; |
f->lineno++; |
} |
} |
if (c == EOF) |
if (c == EOF) |
return (0); |
return (0); |
Line 441 config_load(struct blind *temp) |
|
Line 435 config_load(struct blind *temp) |
|
env = temp; |
env = temp; |
errors = 0; |
errors = 0; |
|
|
if ((file = config_push(env->bl_conf)) == NULL) { |
if ((f = config_push(env->bl_conf)) == NULL) { |
// config_purge(PURGE_ALL); |
// config_purge(PURGE_ALL); |
return (-1); |
return (-1); |
} |
} |
// top = file; |
|
|
|
yyparse(); |
yyparse(); |
|
|
errors = file->errors; |
|
config_pop(); |
|
|
|
// setup |
// setup |
|
|
if (errors) { |
if (errors) { |
Line 465 config_load(struct blind *temp) |
|
Line 455 config_load(struct blind *temp) |
|
struct file * |
struct file * |
config_push(const char *name) |
config_push(const char *name) |
{ |
{ |
struct file *nfile; |
struct file *nf; |
|
|
if ((nfile = calloc(1, sizeof(struct file))) == NULL) { |
if ((nf = calloc(1, sizeof(struct file))) == NULL) { |
log_debug("cannot allocate memory"); |
log_debug("cannot allocate memory"); |
return (NULL); |
return (NULL); |
} |
} |
if ((nfile->name = strdup(name)) == NULL) { |
if ((nf->name = strdup(name)) == NULL) { |
log_debug("cannot duplicate name"); |
log_debug("cannot duplicate name"); |
free(nfile); |
free(nf); |
return (NULL); |
return (NULL); |
} |
} |
if ((nfile->stream = fopen(nfile->name, "r")) == NULL) { |
if ((nf->stream = fopen(nf->name, "r")) == NULL) { |
log_debug("cannot open config file"); |
log_debug("cannot open config file"); |
free(nfile->name); |
free(nf->name); |
free(nfile); |
free(nf); |
return (NULL); |
return (NULL); |
} |
} |
if (config_perm(fileno(nfile->stream), nfile->name)) { |
if (config_perm(fileno(nf->stream), nf->name)) { |
fclose(nfile->stream); |
fclose(nf->stream); |
free(nfile->name); |
free(nf->name); |
free(nfile); |
free(nf); |
return (NULL); |
return (NULL); |
} |
} |
nfile->lineno = 1; // TAILQ_EMPTY(&files) ? 1 : 0; |
nf->lineno = 1; |
nfile->ungetsize = 16; |
nf->ungetsize = 16; |
nfile->ungetbuf = malloc(nfile->ungetsize); |
nf->ungetbuf = malloc(nf->ungetsize); |
if (nfile->ungetbuf == NULL) { |
if (nf->ungetbuf == NULL) { |
log_debug("cannot allocate buffer"); |
log_debug("cannot allocate buffer"); |
fclose(nfile->stream); |
fclose(nf->stream); |
free(nfile->name); |
free(nf->name); |
free(nfile); |
free(nf); |
return (NULL); |
return (NULL); |
} |
} |
//TAILQ_INSERT_TAIL(&files, nfile, entry); |
|
return (nfile); |
return (nf); |
} |
} |
|
|
int |
int |
config_pop(void) |
config_pop(void) |
{ |
{ |
// struct file *prv; |
fclose(f->stream); |
|
free(f->name); |
//if ((prv = TAILQ_PREV(file, files, entry)) != NULL) |
free(f->ungetbuf); |
// prv->errors += file->errors; |
free(f); |
|
|
// TAILQ_REMOVE(&files, file, entry); |
|
fclose(file->stream); |
|
free(file->name); |
|
free(file->ungetbuf); |
|
// free(file); |
|
// file = prv; |
|
|
|
// return (file ? 0 : EOF); |
|
return (EOF); |
return (EOF); |
} |
} |