[BACK]Return to parse.y CVS log [TXT][DIR] Up to [local] / blind

Diff for /blind/parse.y between version 1.10 and 1.20

version 1.10, 2022/03/25 22:43:43 version 1.20, 2022/04/19 02:16:17
Line 17 
Line 17 
 %{  %{
 #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);  #define EXPAND_ON       1
 static struct file {  #define EXPAND_OFF      2
         //      TAILQ_ENTRY(file)        entry;  
         FILE                    *stream;  
         char                    *name;  
         size_t                   ungetpos;  
         size_t                   ungetsize;  
         u_char                  *ungetbuf;  
         int                      eof_reached;  
         int                      lineno;  
         int                      errors;  
 } *file;  
 //, *top;  
   
 int             lookup(char *);  int     lookup(char *);
 int             igetc(void);  int     igetc(void);
 int             lgetc(int);  int     lgetc(int);
 int             findeol(void);  int     findeol(void);
 void            lungetc(int);  void    lungetc(int);
 int             kw_cmp(const void *, const void *);  int     kw_cmp(const void *, const void *);
 int             yyparse(void);  int     yyparse(void);
 int             yylex(void);  int     yylex(void);
 int             yyerror(const char *, ...)  int     yyerror(const char *, ...)
                 __attribute__((__format__ (printf, 1, 2)))          __attribute__((__format__ (printf, 1, 2)))
                 __attribute__((__nonnull__ (1)));          __attribute__((__nonnull__ (1)));
   
 int             config_load(struct blind *);  int     symset(const char *, const char *, int);
 struct file    *config_push(const char *);  char   *symget(const char *);
 int             config_pop(void);  
   
 TAILQ_HEAD(symhead, sym)         symhead = TAILQ_HEAD_INITIALIZER(symhead);  int     config_load(struct blind *);
   int     config_close(void);
   
   TAILQ_HEAD(symhead, sym)        symhead = TAILQ_HEAD_INITIALIZER(symhead);
 struct sym {  struct sym {
         TAILQ_ENTRY(sym)         entry;          TAILQ_ENTRY(sym)        entry;
         int                      used;          int                     used;
         int                      persist;          int                     persist;
         char                    *nam;          char                   *nam;
         char                    *val;          char                   *val;
 };  };
 char           *symget(const char *);  
   
 struct blind   *env = NULL;  
 static int      errors = 0;  
   
 typedef struct {  typedef struct {
         union {          union {
                 int64_t  number;                  int64_t         number;
                 char    *string;                  char           *string;
         } v;          } v;
         int lineno;          int lineno;
 } YYSTYPE;  } YYSTYPE;
   
   static int              expanding;
   static int              errors = 0;
   struct blind           *env = NULL;
   static struct file     *f = NULL;
   
 %}  %}
   
 %token ACTION ARROW DISABLE ENABLE EXPIRE ERROR SET  %token ACTION ARROW DISABLE ENABLE EXPIRE ERROR SET
Line 86  typedef struct {
Line 78  typedef struct {
   
 grammar :  grammar :
         | grammar '\n'          | grammar '\n'
         | grammar set '\n'          | grammar varset '\n'
         | grammar error '\n'    { file->errors++; }          | grammar set '\n'
         ;          | grammar error '\n'    { errors++; }
           ;
   
   varset  : STRING '=' STRING {
                   char *s = $1;
                   while (*s++) {
                           if (isspace((unsigned char)*s)) {
                                   yyerror("macro contain whitespace");
                                   free($1);
                                   free($3);
                                   YYERROR;
                           }
                   }
                   if (symset($1, $3, 0) == -1)
                           log_fatal("cannot store variable");
                   free($1);
                   free($3);
   }
   ;
   
 set     : SET EXPIRE NUMBER {  set     : SET EXPIRE NUMBER {
         env->bl_ttl = $3;          env->bl_ttl = $3;
 }  }
 | SET ACTION ENABLE {  | SET ACTION ENABLE {
         env->bl_opt |= BL_OPT_ACTION;          env->bl_opt |= BL_OPT_ACTION;
  }   }
 | SET ACTION DISABLE {  | SET ACTION DISABLE {
         env->bl_opt |= !BL_OPT_ACTION;          env->bl_opt |= !BL_OPT_ACTION;
  }   }
 ;  ;
   
 %%  %%
   
 struct keywords {  struct keywords {
         const char      *k_name;          const char     *k_name;
         int              k_val;          int             k_val;
 };  };
   
 int  int
 yyerror(const char *fmt, ...)  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);
 }  }
Line 133  kw_cmp(const void *k, const void *e)
Line 143  kw_cmp(const void *k, const void *e)
 int  int
 lookup(char *s)  lookup(char *s)
 {  {
         /* this has to be sorted always */  
         static const struct keywords keywords[] = {          static const struct keywords keywords[] = {
                 { "action",             ACTION  },                  { "action",             ACTION  },
                 { "disable",            DISABLE },                  { "disable",            DISABLE },
                 { "enable",             ENABLE  },                  { "enable",             ENABLE  },
                 { "expire",             EXPIRE  },                  { "expire",             EXPIRE  },
                 { "set",                SET     },                  { "set",                SET     },
         };          };
         const struct keywords   *p;          const struct keywords *p;
   
         p = bsearch(s, keywords, sizeof(keywords)/sizeof(keywords[0]),          p = bsearch(s, keywords, sizeof(keywords)/sizeof(keywords[0]),
             sizeof(keywords[0]), kw_cmp);              sizeof(keywords[0]), kw_cmp);
Line 152  lookup(char *s)
Line 161  lookup(char *s)
                 return (STRING);                  return (STRING);
 }  }
   
 #define START_EXPAND    1  int
 #define DONE_EXPAND     2  symset(const char *nam, const char *val, int persist)
   {
           struct sym      *sym;
   
 static int      expanding;          TAILQ_FOREACH(sym, &symhead, entry) {
                   if (strcmp(nam, sym->nam) == 0)
                           break;
           }
   
           if (sym != NULL) {
                   if (sym->persist == 1)
                           return (0);
                   else {
                           free(sym->nam);
                           free(sym->val);
                           TAILQ_REMOVE(&symhead, sym, entry);
                           free(sym);
                   }
           }
           if ((sym = calloc(1, sizeof(*sym))) == NULL)
                   return (-1);
   
           sym->nam = strdup(nam);
           if (sym->nam == NULL) {
                   free(sym);
                   return (-1);
           }
           sym->val = strdup(val);
           if (sym->val == NULL) {
                   free(sym->nam);
                   free(sym);
                   return (-1);
           }
           sym->used = 0;
           sym->persist = persist;
           TAILQ_INSERT_TAIL(&symhead, sym, entry);
           return (0);
   }
   
 char *  char *
 symget(const char *nam)  symget(const char *nam)
 {  {
Line 177  igetc(void)
Line 221  igetc(void)
         int     c;          int     c;
   
         while (1) {          while (1) {
                 if (file->ungetpos > 0)                  if (f->unpos > 0)
                         c = file->ungetbuf[--file->ungetpos];                          c = f->unbuf[--f->unpos];
                 else                  else
                         c = getc(file->stream);                          c = getc(f->stream);
   
                 if (c == START_EXPAND)                  if (c == EXPAND_ON)
                         expanding = 1;                          expanding = 1;
                 else if (c == DONE_EXPAND)                  else if (c == EXPAND_OFF)
                         expanding = 0;                          expanding = 0;
                 else                  else
                         break;                          break;
Line 195  igetc(void)
Line 239  igetc(void)
 int  int
 lgetc(int quotec)  lgetc(int quotec)
 {  {
         int             c, next;          int     c, next;
   
         if (quotec) {          if (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_close() == EOF)
                         if (config_pop() == EOF)  
                                 return (EOF);                                  return (EOF);
                         return (quotec);                          return (quotec);
                 }                  }
Line 215  lgetc(int quotec)
Line 258  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) {
                 /*                  if (config_close() == EOF)
                  * Fake EOL when hit EOF for the first time. This gets line                          return (EOF);
                  * count right if last line in included file is syntactically                  c = igetc();
                  * invalid and has no newline.  
                  */  
                 if (file->eof_reached == 0) {  
                         file->eof_reached = 1;  
                         return ('\n');  
                 }  
                 while (c == EOF) {  
                         //if (file == top || config_pop() == EOF)  
                         if (config_pop() == EOF)  
                                 return (EOF);  
                         c = igetc();  
                 }  
         }          }
         return (c);          return (c);
 }  }
Line 245  lungetc(int c)
Line 276  lungetc(int c)
         if (c == EOF)          if (c == EOF)
                 return;                  return;
   
         if (file->ungetpos >= file->ungetsize) {          if (f->unpos >= f->unsize) {
                 void *p = reallocarray(file->ungetbuf, file->ungetsize, 2);                  void *p = reallocarray(f->unbuf, f->unsize, 2);
                 if (p == NULL)                  if (p == NULL)
                         log_fatal("cannot reallocate memory");                          log_fatal("cannot reallocate memory");
                 file->ungetbuf = p;                  f->unbuf = p;
                 file->ungetsize *= 2;                  f->unsize *= 2;
         }          }
         file->ungetbuf[file->ungetpos++] = c;          f->unbuf[f->unpos++] = c;
 }  }
   
 int  int
Line 260  findeol(void)
Line 291  findeol(void)
 {  {
         int     c;          int     c;
   
         /* skip to either EOF or the first real EOL */  
         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)
Line 276  findeol(void)
Line 306  findeol(void)
 int  int
 yylex(void)  yylex(void)
 {  {
         char     buf[8096];          char    buf[8096];
         char    *p, *val;          char   *p, *val;
         int      quotec, next, c;          int     quotec, next, c;
         int      token;          int     token;
   
 top:  top:
         p = buf;          p = buf;
         while ((c = lgetc(0)) == ' ' || c == '\t')          while ((c = lgetc(0)) == ' ' || c == '\t')
                 ; /* 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 */                          ;
   
         if (c == '$' && !expanding) {          if (c == '$' && !expanding) {
                 while (1) {                  while (1) {
                         if ((c = lgetc(0)) == EOF)                          if ((c = lgetc(0)) == EOF)
Line 313  top:
Line 344  top:
                         return (findeol());                          return (findeol());
                 }                  }
                 p = val + strlen(val) - 1;                  p = val + strlen(val) - 1;
                 lungetc(DONE_EXPAND);                  lungetc(EXPAND_OFF);
                 while (p >= val) {                  while (p >= val) {
                         lungetc((unsigned char)*p);                          lungetc((unsigned char)*p);
                         p--;                          p--;
                 }                  }
                 lungetc(START_EXPAND);                  lungetc(EXPAND_ON);
                 goto top;                  goto top;
         }          }
   
Line 330  top:
Line 361  top:
                         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)
Line 339  top:
Line 370  top:
                                     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);
Line 368  top:
Line 399  top:
         if (c == '-' || isdigit(c)) {          if (c == '-' || isdigit(c)) {
                 do {                  do {
                         *p++ = c;                          *p++ = c;
                         if ((size_t)(p-buf) >= sizeof(buf)) {                                  if ((size_t)(p-buf) >= sizeof(buf)) {
                                 yyerror("string too long");                                  yyerror("string too long");
                                 return (findeol());                                  return (findeol());
                         }                          }
Line 427  nodigits:
Line 458  nodigits:
                 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 438  nodigits:
Line 469  nodigits:
 int  int
 config_load(struct blind *temp)  config_load(struct blind *temp)
 {  {
         env = temp;          env = temp;
         errors = 0;          errors = 0;
   
         if ((file = config_push(env->bl_conf)) == NULL) {          if ((f = calloc(1, sizeof(struct file))) == NULL) {
                 //       config_purge(PURGE_ALL);                  log_debug("cannot allocate memory");
                 return (-1);                  return (-1);
         }          }
         //        top = file;          if ((f->name = strdup(env->bl_conf)) == NULL) {
                   log_debug("cannot duplicate name");
                   free(f);
                   return (-1);
           }
           if ((f->stream = fopen(f->name, "r")) == NULL) {
                   log_debug("cannot open config file");
                   free(f->name);
                   free(f);
                   return (-1);
           }
           if (config_perm(fileno(f->stream), f->name)) {
                   fclose(f->stream);
                   free(f->name);
                   free(f);
                   return (-1);
           }
           f->lineno = 1;
           f->unsize = 16;
           if ((f->unbuf = malloc(f->unsize)) == NULL) {
                   log_debug("cannot allocate buffer");
                   fclose(f->stream);
                   free(f->name);
                   free(f);
                   return (-1);
           }
   
         yyparse();          yyparse();
           // setup
   
         errors = file->errors;          if (errors)
         config_pop();                  return (-1);
   
         // setup          return (0);
   
         if (errors) {  
                 //      config_purge(PURGE_ALL);  
                 return (-1);  
         }  
   
         return (0);  
 }  }
   
 struct file *  
 config_push(const char *name)  
 {  
         struct file *nfile;  
   
         if ((nfile = calloc(1, sizeof(struct file))) == NULL) {  
                 log_debug("cannot allocate memory");  
                 return (NULL);  
         }  
         if ((nfile->name = strdup(name)) == NULL) {  
                 log_debug("cannot duplicate name");  
                 free(nfile);  
                 return (NULL);  
         }  
         if ((nfile->stream = fopen(nfile->name, "r")) == NULL) {  
                 log_debug("cannot open config file");  
                 free(nfile->name);  
                 free(nfile);  
                 return (NULL);  
         }  
         if (config_perm(fileno(nfile->stream), nfile->name)) {  
                 fclose(nfile->stream);  
                 free(nfile->name);  
                 free(nfile);  
                 return (NULL);  
         }  
         nfile->lineno = 1; // TAILQ_EMPTY(&files) ? 1 : 0;  
         nfile->ungetsize = 16;  
         nfile->ungetbuf = malloc(nfile->ungetsize);  
         if (nfile->ungetbuf == NULL) {  
                 log_debug("cannot allocate buffer");  
                 fclose(nfile->stream);  
                 free(nfile->name);  
                 free(nfile);  
                 return (NULL);  
         }  
         //TAILQ_INSERT_TAIL(&files, nfile, entry);  
         return (nfile);  
 }  
   
 int  int
 config_pop(void)  config_close(void)
 {  {
         //        struct file *prv;          fclose(f->stream);
           free(f->name);
           free(f->unbuf);
           free(f);
   
         //if ((prv = TAILQ_PREV(file, files, entry)) != NULL)          return (EOF);
         //        prv->errors += file->errors;  
   
         // TAILQ_REMOVE(&files, file, entry);  
         fclose(file->stream);  
         free(file->name);  
         free(file->ungetbuf);  
         // free(file);  
         // file = prv;  
   
         // return (file ? 0 : EOF);  
         return (EOF);  
 }  }

Legend:
Removed from v.1.10  
changed lines
  Added in v.1.20

https://cvs.kroczynski.net