2 * Much of the design is taken from doas (parse.y rev 1.29)
4 * Copyright (c) 2021 Omar Polo <op@omarpolo.com>
5 * Copyright (c) 2015 Ted Unangst <tedu@openbsd.org>
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
23 #include "telescope.h"
40 #define YYSTYPE yystype
42 static char *current_style;
43 static const char *path;
49 static void yyerror(const char *, ...);
50 static int yylex(void);
51 static void setprfx(int, const char *);
52 static void setvari(char *, int);
53 static void setvars(char *, char *);
58 %token TSTYLE TPRFX TCONT TBG TFG TATTR TBOLD TUNDERLINE
73 | style { free(current_style); current_style = NULL; }
78 set : TSET TSTRING '=' TSTRING { setvars($2, $4); }
79 | TSET TSTRING '=' TNUMBER { setvari($2, $4); }
82 style : TSTYLE TSTRING { current_style = $2; } styleopt
83 | TSTYLE TSTRING { current_style = $2; } '{' styleopts '}'
86 styleopts : /* empty */
88 | styleopts styleopt '\n'
91 styleopt : TPRFX TSTRING { setprfx(0, $2); }
92 | TCONT TSTRING { setprfx(1, $2); }
93 | TBG TSTRING { printf("style background setted to \"%s\"\n", $2); }
94 | TFG TSTRING { printf("style foreground setted to \"%s\"\n", $2); }
95 | TATTR TBOLD { printf("style attr setted to bold\n"); }
96 | TATTR TUNDERLINE { printf("style attr setted to underline\n"); }
99 bind : TBIND TSTRING TSTRING TSTRING { printf("TODO: bind %s %s %s\n", $2, $3, $4); }
102 unbind : TUNBIND TSTRING TSTRING { printf("TODO: unbind %s %s\n", $2, $3); }
108 yyerror(const char *fmt, ...)
112 fprintf(stderr, "%s:%d ", path, yylval.lineno+1);
114 vfprintf(stderr, fmt, va);
116 fprintf(stderr, "\n");
120 static struct keyword {
128 { "background", TBG },
129 { "foreground", TFG },
132 { "underline", TUNDERLINE },
134 { "unbind", TUNBIND },
140 char buf[1024], *ebuf, *p, *str;
142 int c, quotes = 0, escape = 0, qpos = -1, nonkw = 0;
146 ebuf = buf + sizeof(buf);
149 /* skip whitespace first */
150 for (c = getc(yyfp); c == ' ' || c == '\t' || c == '\f'; c = getc(yyfp))
153 /* check for special one-character constructions */
164 /* skip comments; NUL is allowed; no continuation */
165 while ((c = getc(yyfp)) != '\n')
175 /* parsing next word */
176 for (;; c = getc(yyfp), yylval.colno++) {
179 yyerror("unallowed character NULL in column %d",
190 yyerror("unterminated quotes in column %d",
201 yyerror("unterminated escape in column %d",
204 yyerror("unterminated quotes in column %d",
213 if (!escape && !quotes)
228 yyerror("line too long");
240 * There could be a number of reason for empty buffer,
241 * and we handle all of them here, to avoid cluttering
246 else if (qpos == -1) /* accept, e.g., empty args: cmd foo args "" */
250 for (i = 0; i < sizeof(keywords) / sizeof(keywords[0]); i++) {
251 if (strcmp(buf, keywords[i].word) == 0)
252 return keywords[i].token;
256 if (!nonkw && (c == '-' || isdigit(c))) {
257 yylval.num = strtonum(buf, INT_MIN, INT_MAX, &errstr);
259 yyerror("number is %s: %s", errstr, buf);
262 if ((str = strdup(buf)) == NULL)
263 err(1, "%s", __func__);
269 yyerror("input error reading config");
274 setprfx(int cont, const char *name)
276 if (current_style == NULL) {
277 warnx("current_style = NULL!");
281 if (!config_setprfx(current_style, cont, name))
282 yyerror("invalid style %s", name);
286 setvari(char *var, int val)
288 if (!config_setvari(var, val))
289 yyerror("invalid variable or value: %s = %d",
296 setvars(char *var, char *val)
298 if (!config_setvars(var, val))
299 yyerror("invalid variable or value: %s = \"%s\"",
306 parseconfig(const char *filename, int fonf)
308 if ((yyfp = fopen(filename, "r")) == NULL) {
310 err(1, "%s", filename);