2 /* $NetBSD: testlang_conf.l,v 1.7 2013/11/21 11:06:04 blymn Exp $ */
5 * Copyright 2009 Brett Lymn <blymn@NetBSD.org>
9 * This code has been donated to The NetBSD Foundation by the Author.
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. The name of the author may not be used to endorse or promote products
17 * derived from this software withough specific prior written permission
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38 #include <sys/param.h>
41 #include "testlang_parse.h"
43 #define MAX_INCLUDES 32 /* limit for the number of nested includes */
48 extern char *include_path; /* from director.c */
49 extern char *cur_file; /* from director.c */
51 static int include_stack[MAX_INCLUDES];
52 static char *include_files[MAX_INCLUDES];
53 static int include_ptr = 0;
56 dequote(const char *s, size_t *len)
58 const unsigned char *p;
62 p = (const unsigned char *)s;
64 if (*p == '\\' && *(p+1)) {
65 if (isdigit(*(p+1)) && *(p+2) && isdigit(*(p+2)) &&
66 *(p+3) && isdigit(*(p+3)))
75 buf = malloc(*len + 1);
79 p = (const unsigned char *)s;
82 if (*p == '\\' && *(p+1)) {
85 if (*(p+1) && isdigit(*(p+1)) && *(p+2) &&
87 *q++ = ((*p - '0') * 8 + (*(p+1) - '0')) * 8 + (*(p+2) - '0');
107 /* carriage return */
137 HEX 0[xX][0-9a-zA-Z]+
138 STRING [0-9a-z!#-&(-^ \t%._\\]+
141 ASSIGN [aA][sS][sS][iI][gG][nN]
142 CALL2 [cC][aA][lL][lL]2
143 CALL3 [cC][aA][lL][lL]3
144 CALL4 [cC][aA][lL][lL]4
145 CALL [cC][aA][lL][lL]
146 CHECK [cC][hH][eE][cC][kK]
147 DELAY [dD][eE][lL][aA][yY]
148 INPUT [iI][nN][pP][uU][tT]
149 NOINPUT [nN][oO][iI][nN][pP][uU][tT]
152 COMPARE [cC][oO][mM][pP][aA][rR][eE]
153 COMPAREND [cC][oO][mM][pP][aA][rR][eE][Nn][Dd]
154 FILENAME [A-Za-z0-9.][A-Za-z0-9./_-]+
155 VARNAME [A-Za-z][A-Za-z0-9_-]+
164 %option noinput nounput
170 <incl>[ \t]* /* eat the whitespace */
171 <incl>[^ \t\n]+ { /* got the include file name */
172 char inc_file[MAXPATHLEN];
174 if (include_ptr > MAX_INCLUDES) {
176 "Maximum number of nested includes exceeded "
177 "at line %zu of file %s\n", line, cur_file);
181 if (yytext[0] != '/') {
182 if (strlcpy(inc_file, include_path, sizeof(inc_file))
184 err(2, "CHECK_PATH too long");
185 if ((include_path[strlen(include_path) - 1] != '/') &&
186 ((strlcat(inc_file, "/", sizeof(inc_file))
187 >= sizeof(inc_file))))
188 err(2, "Could not append / to include file path");
193 if (strlcat(inc_file, yytext, sizeof(inc_file))
195 err(2, "Path to include file path overflowed");
197 yyin = fopen(inc_file, "r" );
200 err(1, "Error opening %s", inc_file);
202 yypush_buffer_state(yy_create_buffer(yyin, YY_BUF_SIZE));
204 include_stack[include_ptr] = line;
205 include_files[include_ptr++] = cur_file;
206 cur_file = strdup(inc_file);
207 if (cur_file == NULL)
208 err(2, "Cannot allocate new include file string");
214 yypop_buffer_state();
216 if ( !YY_CURRENT_BUFFER )
221 if (--include_ptr < 0)
222 err(2, "Include stack underflow");
225 cur_file = include_files[include_ptr];
226 line = include_stack[include_ptr];
302 /* Hex value, convert to decimal and return numeric */
305 if (sscanf(yytext, "%lx", &val) != 1)
306 err(1, "Bad hex conversion");
308 asprintf(&yylval.string, "%ld", val);
314 if ((yylval.string = strdup(yytext)) == NULL)
315 err(1, "Cannot allocate numeric string");
320 if ((yylval.string = strdup(yytext)) == NULL)
321 err(1, "Cannot allocate string for varname");
328 if ((yylval.string = dequote(yytext, &len)) == NULL)
329 err(1, "Cannot allocate filename string");
336 if ((yylval.string = dequote(yytext, &len)) == NULL)
337 err(1, "Cannot allocate string");
345 if ((yylval.retval = malloc(sizeof(returns_t))) == NULL)
346 err(1, "Cannot allocate return struct");
348 p++; /* skip the leading ' */
349 if ((yylval.retval->return_value = dequote(p, &len))
351 err(1, "Cannot allocate string");
353 yylval.retval->return_type = ret_byte;
354 /* trim trailing ' */
355 yylval.retval->return_len = len - 1;
365 if ((yylval.retval = malloc(sizeof(returns_t))) == NULL)
366 err(1, "Cannot allocate return struct");
368 p++; /* skip the leading ' */
369 if ((str = dequote(p, &len)) == NULL)
370 err(1, "Cannot allocate string");
371 len--; /* trim trailing ` */
375 chlen = ((len / 2) + 1) * sizeof(chtype);
376 if ((yylval.retval->return_value = malloc(chlen))
378 err(1, "Cannot allocate chtype array");
380 rv = yylval.retval->return_value;
381 for (i = 0; i < len; i += 2)
382 *rv++ = (str[i] << 8) | str[i+1];
383 *rv = __NORMAL | '\0'; /* terminates chtype array */
384 yylval.retval->return_type = ret_byte;
385 yylval.retval->return_len = chlen;
394 p++; /* skip the leading " */
395 if ((yylval.string = dequote(p, &len)) == NULL)
396 err(1, "Cannot allocate string");
398 /* remove trailing " */
399 yylval.string[len - 1] = '\0';
407 p++; /* skip $ before var name */
408 if ((yylval.string = strdup(p)) == NULL)
409 err(1, "Cannot allocate string for varname");
413 /* comments, white-outs */
422 /* eol on a line with data. need to process, return eol */