testlang_conf.l revision 1.9 1 1.1 blymn %{
2 1.9 blymn /* $NetBSD: testlang_conf.l,v 1.9 2020/10/24 04:46:17 blymn Exp $ */
3 1.1 blymn
4 1.1 blymn /*-
5 1.1 blymn * Copyright 2009 Brett Lymn <blymn (at) NetBSD.org>
6 1.1 blymn *
7 1.1 blymn * All rights reserved.
8 1.1 blymn *
9 1.1 blymn * This code has been donated to The NetBSD Foundation by the Author.
10 1.1 blymn *
11 1.1 blymn * Redistribution and use in source and binary forms, with or without
12 1.1 blymn * modification, are permitted provided that the following conditions
13 1.1 blymn * are met:
14 1.1 blymn * 1. Redistributions of source code must retain the above copyright
15 1.1 blymn * notice, this list of conditions and the following disclaimer.
16 1.1 blymn * 2. The name of the author may not be used to endorse or promote products
17 1.1 blymn * derived from this software withough specific prior written permission
18 1.1 blymn *
19 1.1 blymn * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20 1.1 blymn * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21 1.1 blymn * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22 1.1 blymn * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23 1.1 blymn * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24 1.1 blymn * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 1.1 blymn * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 1.1 blymn * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 1.1 blymn * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 1.1 blymn * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 1.1 blymn *
30 1.1 blymn *
31 1.1 blymn */
32 1.1 blymn
33 1.1 blymn #include <curses.h>
34 1.3 christos #include <ctype.h>
35 1.1 blymn #include <stdio.h>
36 1.1 blymn #include <stdlib.h>
37 1.1 blymn #include <string.h>
38 1.1 blymn #include <sys/param.h>
39 1.1 blymn #include <err.h>
40 1.1 blymn #include "returns.h"
41 1.1 blymn #include "testlang_parse.h"
42 1.1 blymn
43 1.1 blymn #define MAX_INCLUDES 32 /* limit for the number of nested includes */
44 1.1 blymn
45 1.1 blymn int yylex(void);
46 1.1 blymn
47 1.1 blymn extern size_t line;
48 1.1 blymn extern char *include_path; /* from director.c */
49 1.1 blymn extern char *cur_file; /* from director.c */
50 1.1 blymn
51 1.1 blymn static int include_stack[MAX_INCLUDES];
52 1.1 blymn static char *include_files[MAX_INCLUDES];
53 1.1 blymn static int include_ptr = 0;
54 1.1 blymn
55 1.1 blymn static char *
56 1.1 blymn dequote(const char *s, size_t *len)
57 1.1 blymn {
58 1.4 christos const unsigned char *p;
59 1.4 christos char *buf, *q;
60 1.1 blymn
61 1.1 blymn *len = 0;
62 1.4 christos p = (const unsigned char *)s;
63 1.1 blymn while (*p) {
64 1.1 blymn if (*p == '\\' && *(p+1)) {
65 1.1 blymn if (isdigit(*(p+1)) && *(p+2) && isdigit(*(p+2)) &&
66 1.1 blymn *(p+3) && isdigit(*(p+3)))
67 1.1 blymn p += 3;
68 1.1 blymn else
69 1.1 blymn ++p;
70 1.1 blymn }
71 1.1 blymn ++(*len);
72 1.1 blymn ++p;
73 1.1 blymn }
74 1.1 blymn
75 1.1 blymn buf = malloc(*len + 1);
76 1.1 blymn if (buf == NULL)
77 1.1 blymn return NULL;
78 1.1 blymn
79 1.4 christos p = (const unsigned char *)s;
80 1.1 blymn q = buf;
81 1.1 blymn while (*p) {
82 1.1 blymn if (*p == '\\' && *(p+1)) {
83 1.1 blymn ++p;
84 1.1 blymn if (isdigit(*p)) {
85 1.1 blymn if (*(p+1) && isdigit(*(p+1)) && *(p+2) &&
86 1.1 blymn isdigit(*(p+2))) {
87 1.1 blymn *q++ = ((*p - '0') * 8 + (*(p+1) - '0')) * 8 + (*(p+2) - '0');
88 1.1 blymn p += 3;
89 1.1 blymn } else {
90 1.1 blymn *q++ = *p++;
91 1.1 blymn }
92 1.1 blymn } else {
93 1.1 blymn switch (*p) {
94 1.1 blymn case 'e':
95 1.1 blymn /* escape */
96 1.1 blymn *q++ = '\e';
97 1.1 blymn p++;
98 1.1 blymn break;
99 1.1 blymn
100 1.1 blymn case 'n':
101 1.1 blymn /* newline */
102 1.1 blymn *q++ = '\n';
103 1.1 blymn p++;
104 1.1 blymn break;
105 1.1 blymn
106 1.7 blymn case 'r':
107 1.7 blymn /* carriage return */
108 1.7 blymn *q++ = '\r';
109 1.7 blymn p++;
110 1.7 blymn break;
111 1.7 blymn
112 1.1 blymn case 't':
113 1.1 blymn /* tab */
114 1.1 blymn *q++ = '\t';
115 1.1 blymn p++;
116 1.1 blymn break;
117 1.1 blymn
118 1.1 blymn case '\\':
119 1.1 blymn /* backslash */
120 1.1 blymn *q++ = '\\';
121 1.1 blymn p++;
122 1.1 blymn break;
123 1.1 blymn
124 1.1 blymn default:
125 1.1 blymn *q++ = *p++;
126 1.1 blymn }
127 1.1 blymn }
128 1.1 blymn } else
129 1.1 blymn *q++ = *p++;
130 1.1 blymn }
131 1.1 blymn *q++ = '\0';
132 1.1 blymn
133 1.1 blymn return buf;
134 1.1 blymn }
135 1.1 blymn %}
136 1.1 blymn
137 1.1 blymn HEX 0[xX][0-9a-zA-Z]+
138 1.1 blymn STRING [0-9a-z!#-&(-^ \t%._\\]+
139 1.1 blymn numeric [-0-9]+
140 1.1 blymn PCHAR (\\.|[^ \t\n])
141 1.1 blymn ASSIGN [aA][sS][sS][iI][gG][nN]
142 1.1 blymn CALL2 [cC][aA][lL][lL]2
143 1.1 blymn CALL3 [cC][aA][lL][lL]3
144 1.1 blymn CALL4 [cC][aA][lL][lL]4
145 1.1 blymn CALL [cC][aA][lL][lL]
146 1.1 blymn CHECK [cC][hH][eE][cC][kK]
147 1.1 blymn DELAY [dD][eE][lL][aA][yY]
148 1.1 blymn INPUT [iI][nN][pP][uU][tT]
149 1.1 blymn NOINPUT [nN][oO][iI][nN][pP][uU][tT]
150 1.1 blymn OK_RET [oO][kK]
151 1.1 blymn ERR_RET [eE][rR][rR]
152 1.1 blymn COMPARE [cC][oO][mM][pP][aA][rR][eE]
153 1.1 blymn COMPAREND [cC][oO][mM][pP][aA][rR][eE][Nn][Dd]
154 1.1 blymn FILENAME [A-Za-z0-9.][A-Za-z0-9./_-]+
155 1.1 blymn VARNAME [A-Za-z][A-Za-z0-9_-]+
156 1.1 blymn NULL_RET NULL
157 1.1 blymn NON_NULL NON_NULL
158 1.8 blymn CCHAR [cC][cC][hH][aA][rR]
159 1.9 blymn WCHAR [wW][cC][hH][aA][rR]
160 1.1 blymn BYTE BYTE
161 1.1 blymn OR \|
162 1.1 blymn LHB \(
163 1.1 blymn RHB \)
164 1.8 blymn LHSB \[
165 1.8 blymn RHSB \]
166 1.8 blymn MULTIPLIER \*
167 1.1 blymn
168 1.1 blymn %x incl
169 1.5 joerg %option noinput nounput
170 1.1 blymn
171 1.1 blymn %%
172 1.1 blymn
173 1.1 blymn include BEGIN(incl);
174 1.1 blymn
175 1.1 blymn <incl>[ \t]* /* eat the whitespace */
176 1.1 blymn <incl>[^ \t\n]+ { /* got the include file name */
177 1.1 blymn char inc_file[MAXPATHLEN];
178 1.1 blymn
179 1.1 blymn if (include_ptr > MAX_INCLUDES) {
180 1.1 blymn fprintf(stderr,
181 1.1 blymn "Maximum number of nested includes exceeded "
182 1.4 christos "at line %zu of file %s\n", line, cur_file);
183 1.1 blymn exit(2);
184 1.1 blymn }
185 1.1 blymn
186 1.1 blymn if (yytext[0] != '/') {
187 1.1 blymn if (strlcpy(inc_file, include_path, sizeof(inc_file))
188 1.1 blymn >= sizeof(inc_file))
189 1.1 blymn err(2, "CHECK_PATH too long");
190 1.1 blymn if ((include_path[strlen(include_path) - 1] != '/') &&
191 1.1 blymn ((strlcat(inc_file, "/", sizeof(inc_file))
192 1.1 blymn >= sizeof(inc_file))))
193 1.1 blymn err(2, "Could not append / to include file path");
194 1.1 blymn } else {
195 1.1 blymn inc_file[0] = '\0';
196 1.1 blymn }
197 1.1 blymn
198 1.1 blymn if (strlcat(inc_file, yytext, sizeof(inc_file))
199 1.1 blymn >= sizeof(inc_file))
200 1.1 blymn err(2, "Path to include file path overflowed");
201 1.1 blymn
202 1.1 blymn yyin = fopen(inc_file, "r" );
203 1.1 blymn
204 1.4 christos if (!yyin)
205 1.4 christos err(1, "Error opening %s", inc_file);
206 1.1 blymn
207 1.1 blymn yypush_buffer_state(yy_create_buffer(yyin, YY_BUF_SIZE));
208 1.1 blymn
209 1.1 blymn include_stack[include_ptr] = line;
210 1.1 blymn include_files[include_ptr++] = cur_file;
211 1.6 joerg cur_file = strdup(inc_file);
212 1.1 blymn if (cur_file == NULL)
213 1.1 blymn err(2, "Cannot allocate new include file string");
214 1.1 blymn line = 0;
215 1.1 blymn BEGIN(INITIAL);
216 1.1 blymn }
217 1.1 blymn
218 1.1 blymn <<EOF>> {
219 1.1 blymn yypop_buffer_state();
220 1.1 blymn
221 1.1 blymn if ( !YY_CURRENT_BUFFER )
222 1.1 blymn {
223 1.1 blymn yyterminate();
224 1.1 blymn }
225 1.1 blymn
226 1.1 blymn if (--include_ptr < 0)
227 1.1 blymn err(2, "Include stack underflow");
228 1.1 blymn
229 1.1 blymn free(cur_file);
230 1.1 blymn cur_file = include_files[include_ptr];
231 1.1 blymn line = include_stack[include_ptr];
232 1.1 blymn }
233 1.1 blymn
234 1.1 blymn {ASSIGN} {
235 1.1 blymn return ASSIGN;
236 1.1 blymn }
237 1.1 blymn
238 1.1 blymn {CALL2} {
239 1.1 blymn return CALL2;
240 1.1 blymn }
241 1.1 blymn
242 1.1 blymn {CALL3} {
243 1.1 blymn return CALL3;
244 1.1 blymn }
245 1.1 blymn
246 1.1 blymn {CALL4} {
247 1.1 blymn return CALL4;
248 1.1 blymn }
249 1.1 blymn
250 1.1 blymn {CALL} {
251 1.1 blymn return CALL;
252 1.1 blymn }
253 1.1 blymn
254 1.1 blymn {CHECK} {
255 1.1 blymn return CHECK;
256 1.1 blymn }
257 1.1 blymn
258 1.1 blymn {DELAY} {
259 1.1 blymn return DELAY;
260 1.1 blymn }
261 1.1 blymn
262 1.1 blymn {INPUT} {
263 1.1 blymn return INPUT;
264 1.1 blymn }
265 1.1 blymn
266 1.1 blymn {NOINPUT} {
267 1.1 blymn return NOINPUT;
268 1.1 blymn }
269 1.1 blymn
270 1.1 blymn {COMPARE} {
271 1.1 blymn return COMPARE;
272 1.1 blymn }
273 1.1 blymn
274 1.1 blymn {COMPAREND} {
275 1.1 blymn return COMPAREND;
276 1.1 blymn }
277 1.1 blymn
278 1.1 blymn {NON_NULL} {
279 1.1 blymn return NON_NULL;
280 1.1 blymn }
281 1.1 blymn
282 1.1 blymn {NULL_RET} {
283 1.1 blymn return NULL_RET;
284 1.1 blymn }
285 1.1 blymn
286 1.1 blymn {OK_RET} {
287 1.1 blymn return OK_RET;
288 1.1 blymn }
289 1.1 blymn
290 1.1 blymn {ERR_RET} {
291 1.1 blymn return ERR_RET;
292 1.1 blymn }
293 1.1 blymn
294 1.8 blymn {MULTIPLIER} {
295 1.8 blymn return MULTIPLIER;
296 1.8 blymn }
297 1.8 blymn
298 1.9 blymn {CCHAR} {
299 1.8 blymn return CCHAR;
300 1.8 blymn }
301 1.8 blymn
302 1.9 blymn {WCHAR} {
303 1.9 blymn return WCHAR;
304 1.9 blymn }
305 1.9 blymn
306 1.1 blymn {OR} {
307 1.1 blymn return OR;
308 1.1 blymn }
309 1.1 blymn
310 1.1 blymn {LHB} {
311 1.1 blymn return LHB;
312 1.1 blymn }
313 1.1 blymn
314 1.1 blymn {RHB} {
315 1.1 blymn return RHB;
316 1.1 blymn }
317 1.1 blymn
318 1.8 blymn {LHSB} {
319 1.8 blymn return LHSB;
320 1.8 blymn }
321 1.8 blymn
322 1.8 blymn {RHSB} {
323 1.8 blymn return RHSB;
324 1.8 blymn }
325 1.8 blymn
326 1.1 blymn {HEX} {
327 1.1 blymn /* Hex value, convert to decimal and return numeric */
328 1.1 blymn unsigned long val;
329 1.1 blymn
330 1.1 blymn if (sscanf(yytext, "%lx", &val) != 1)
331 1.1 blymn err(1, "Bad hex conversion");
332 1.1 blymn
333 1.1 blymn asprintf(&yylval.string, "%ld", val);
334 1.1 blymn return numeric;
335 1.1 blymn }
336 1.1 blymn
337 1.1 blymn
338 1.1 blymn {numeric} {
339 1.1 blymn if ((yylval.string = strdup(yytext)) == NULL)
340 1.1 blymn err(1, "Cannot allocate numeric string");
341 1.1 blymn return numeric;
342 1.1 blymn }
343 1.1 blymn
344 1.1 blymn {VARNAME} {
345 1.1 blymn if ((yylval.string = strdup(yytext)) == NULL)
346 1.1 blymn err(1, "Cannot allocate string for varname");
347 1.1 blymn return VARNAME;
348 1.1 blymn }
349 1.1 blymn
350 1.1 blymn {FILENAME} {
351 1.1 blymn size_t len;
352 1.1 blymn
353 1.1 blymn if ((yylval.string = dequote(yytext, &len)) == NULL)
354 1.1 blymn err(1, "Cannot allocate filename string");
355 1.1 blymn return FILENAME;
356 1.1 blymn }
357 1.1 blymn
358 1.1 blymn /* path */
359 1.1 blymn \/{PCHAR}+ {
360 1.1 blymn size_t len;
361 1.1 blymn if ((yylval.string = dequote(yytext, &len)) == NULL)
362 1.1 blymn err(1, "Cannot allocate string");
363 1.1 blymn return PATH;
364 1.1 blymn }
365 1.1 blymn
366 1.1 blymn \'{STRING}\' {
367 1.1 blymn char *p;
368 1.1 blymn size_t len;
369 1.1 blymn
370 1.8 blymn if ((yylval.retval = malloc(sizeof(ct_data_t))) == NULL)
371 1.1 blymn err(1, "Cannot allocate return struct");
372 1.1 blymn p = yytext;
373 1.1 blymn p++; /* skip the leading ' */
374 1.8 blymn if ((yylval.retval->data_value = dequote(p, &len))
375 1.1 blymn == NULL)
376 1.1 blymn err(1, "Cannot allocate string");
377 1.1 blymn
378 1.8 blymn yylval.retval->data_type = data_byte;
379 1.1 blymn /* trim trailing ' */
380 1.8 blymn yylval.retval->data_len = len - 1;
381 1.1 blymn return BYTE;
382 1.1 blymn }
383 1.1 blymn
384 1.1 blymn \`{STRING}\` {
385 1.1 blymn char *p, *str;
386 1.1 blymn size_t len, chlen;
387 1.4 christos size_t i;
388 1.1 blymn chtype *rv;
389 1.1 blymn
390 1.8 blymn if ((yylval.retval = malloc(sizeof(ct_data_t))) == NULL)
391 1.1 blymn err(1, "Cannot allocate return struct");
392 1.1 blymn p = yytext;
393 1.9 blymn p++; /* skip the leading ` */
394 1.1 blymn if ((str = dequote(p, &len)) == NULL)
395 1.1 blymn err(1, "Cannot allocate string");
396 1.1 blymn len--; /* trim trailing ` */
397 1.1 blymn if ((len % 2) != 0)
398 1.1 blymn len--;
399 1.1 blymn
400 1.1 blymn chlen = ((len / 2) + 1) * sizeof(chtype);
401 1.8 blymn if ((yylval.retval->data_value = malloc(chlen))
402 1.1 blymn == NULL)
403 1.1 blymn err(1, "Cannot allocate chtype array");
404 1.1 blymn
405 1.8 blymn rv = yylval.retval->data_value;
406 1.1 blymn for (i = 0; i < len; i += 2)
407 1.1 blymn *rv++ = (str[i] << 8) | str[i+1];
408 1.1 blymn *rv = __NORMAL | '\0'; /* terminates chtype array */
409 1.8 blymn yylval.retval->data_type = data_byte;
410 1.8 blymn yylval.retval->data_len = chlen;
411 1.1 blymn return BYTE;
412 1.1 blymn }
413 1.1 blymn
414 1.1 blymn \"{STRING}\" {
415 1.1 blymn char *p;
416 1.1 blymn size_t len;
417 1.1 blymn
418 1.1 blymn p = yytext;
419 1.1 blymn p++; /* skip the leading " */
420 1.1 blymn if ((yylval.string = dequote(p, &len)) == NULL)
421 1.1 blymn err(1, "Cannot allocate string");
422 1.1 blymn
423 1.1 blymn /* remove trailing " */
424 1.1 blymn yylval.string[len - 1] = '\0';
425 1.1 blymn return STRING;
426 1.1 blymn }
427 1.1 blymn
428 1.1 blymn \${VARNAME} {
429 1.1 blymn char *p;
430 1.1 blymn
431 1.1 blymn p = yytext;
432 1.1 blymn p++; /* skip $ before var name */
433 1.1 blymn if ((yylval.string = strdup(p)) == NULL)
434 1.1 blymn err(1, "Cannot allocate string for varname");
435 1.1 blymn return VARIABLE;
436 1.1 blymn }
437 1.1 blymn
438 1.1 blymn /* comments, white-outs */
439 1.1 blymn [ \t\r] |
440 1.1 blymn #.* ;
441 1.1 blymn ^#.*\n |
442 1.1 blymn #.*\n |
443 1.1 blymn \\\n |
444 1.1 blymn ^\n {
445 1.1 blymn line++; }
446 1.1 blymn
447 1.1 blymn /* eol on a line with data. need to process, return eol */
448 1.1 blymn \n {
449 1.1 blymn line++;
450 1.1 blymn return EOL;
451 1.1 blymn }
452 1.1 blymn
453 1.1 blymn . {
454 1.1 blymn }
455 1.1 blymn
456 1.1 blymn %%
457 1.1 blymn
458 1.1 blymn int
459 1.1 blymn yywrap(void)
460 1.1 blymn {
461 1.1 blymn return 1;
462 1.1 blymn }
463