=================================================================== RCS file: /cvs/cvs/blind/parse.y,v retrieving revision 1.18 retrieving revision 1.19 diff -u -p -r1.18 -r1.19 --- blind/parse.y 2022/04/10 21:20:24 1.18 +++ blind/parse.y 2022/04/17 21:23:34 1.19 @@ -40,6 +40,7 @@ int yyerror(const char *, ...) __attribute__((__format__ (printf, 1, 2))) __attribute__((__nonnull__ (1))); +int symset(const char *, const char *, int); char *symget(const char *); int config_load(struct blind *); @@ -77,10 +78,28 @@ typedef struct { grammar : | grammar '\n' + | grammar varset '\n' | 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 { env->bl_ttl = $3; } @@ -141,6 +160,46 @@ lookup(char *s) return (p->k_val); else return (STRING); +} + +int +symset(const char *nam, const char *val, int persist) +{ + struct sym *sym; + + 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 *