diff options
Diffstat (limited to 'lib/libcurses/director/testlang_conf.l')
-rw-r--r-- | lib/libcurses/director/testlang_conf.l | 437 |
1 files changed, 437 insertions, 0 deletions
diff --git a/lib/libcurses/director/testlang_conf.l b/lib/libcurses/director/testlang_conf.l new file mode 100644 index 0000000000000..a732afce3a890 --- /dev/null +++ b/lib/libcurses/director/testlang_conf.l @@ -0,0 +1,437 @@ +%{ +/* $NetBSD: testlang_conf.l,v 1.7 2013/11/21 11:06:04 blymn Exp $ */ + +/*- + * Copyright 2009 Brett Lymn <blymn@NetBSD.org> + * + * All rights reserved. + * + * This code has been donated to The NetBSD Foundation by the Author. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. The name of the author may not be used to endorse or promote products + * derived from this software withough specific prior written permission + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + */ + +#include <curses.h> +#include <ctype.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/param.h> +#include <err.h> +#include "returns.h" +#include "testlang_parse.h" + +#define MAX_INCLUDES 32 /* limit for the number of nested includes */ + +int yylex(void); + +extern size_t line; +extern char *include_path; /* from director.c */ +extern char *cur_file; /* from director.c */ + +static int include_stack[MAX_INCLUDES]; +static char *include_files[MAX_INCLUDES]; +static int include_ptr = 0; + +static char * +dequote(const char *s, size_t *len) +{ + const unsigned char *p; + char *buf, *q; + + *len = 0; + p = (const unsigned char *)s; + while (*p) { + if (*p == '\\' && *(p+1)) { + if (isdigit(*(p+1)) && *(p+2) && isdigit(*(p+2)) && + *(p+3) && isdigit(*(p+3))) + p += 3; + else + ++p; + } + ++(*len); + ++p; + } + + buf = malloc(*len + 1); + if (buf == NULL) + return NULL; + + p = (const unsigned char *)s; + q = buf; + while (*p) { + if (*p == '\\' && *(p+1)) { + ++p; + if (isdigit(*p)) { + if (*(p+1) && isdigit(*(p+1)) && *(p+2) && + isdigit(*(p+2))) { + *q++ = ((*p - '0') * 8 + (*(p+1) - '0')) * 8 + (*(p+2) - '0'); + p += 3; + } else { + *q++ = *p++; + } + } else { + switch (*p) { + case 'e': + /* escape */ + *q++ = '\e'; + p++; + break; + + case 'n': + /* newline */ + *q++ = '\n'; + p++; + break; + + case 'r': + /* carriage return */ + *q++ = '\r'; + p++; + break; + + case 't': + /* tab */ + *q++ = '\t'; + p++; + break; + + case '\\': + /* backslash */ + *q++ = '\\'; + p++; + break; + + default: + *q++ = *p++; + } + } + } else + *q++ = *p++; + } + *q++ = '\0'; + + return buf; +} +%} + +HEX 0[xX][0-9a-zA-Z]+ +STRING [0-9a-z!#-&(-^ \t%._\\]+ +numeric [-0-9]+ +PCHAR (\\.|[^ \t\n]) +ASSIGN [aA][sS][sS][iI][gG][nN] +CALL2 [cC][aA][lL][lL]2 +CALL3 [cC][aA][lL][lL]3 +CALL4 [cC][aA][lL][lL]4 +CALL [cC][aA][lL][lL] +CHECK [cC][hH][eE][cC][kK] +DELAY [dD][eE][lL][aA][yY] +INPUT [iI][nN][pP][uU][tT] +NOINPUT [nN][oO][iI][nN][pP][uU][tT] +OK_RET [oO][kK] +ERR_RET [eE][rR][rR] +COMPARE [cC][oO][mM][pP][aA][rR][eE] +COMPAREND [cC][oO][mM][pP][aA][rR][eE][Nn][Dd] +FILENAME [A-Za-z0-9.][A-Za-z0-9./_-]+ +VARNAME [A-Za-z][A-Za-z0-9_-]+ +NULL_RET NULL +NON_NULL NON_NULL +BYTE BYTE +OR \| +LHB \( +RHB \) + +%x incl +%option noinput nounput + +%% + +include BEGIN(incl); + +<incl>[ \t]* /* eat the whitespace */ +<incl>[^ \t\n]+ { /* got the include file name */ + char inc_file[MAXPATHLEN]; + + if (include_ptr > MAX_INCLUDES) { + fprintf(stderr, + "Maximum number of nested includes exceeded " + "at line %zu of file %s\n", line, cur_file); + exit(2); + } + + if (yytext[0] != '/') { + if (strlcpy(inc_file, include_path, sizeof(inc_file)) + >= sizeof(inc_file)) + err(2, "CHECK_PATH too long"); + if ((include_path[strlen(include_path) - 1] != '/') && + ((strlcat(inc_file, "/", sizeof(inc_file)) + >= sizeof(inc_file)))) + err(2, "Could not append / to include file path"); + } else { + inc_file[0] = '\0'; + } + + if (strlcat(inc_file, yytext, sizeof(inc_file)) + >= sizeof(inc_file)) + err(2, "Path to include file path overflowed"); + + yyin = fopen(inc_file, "r" ); + + if (!yyin) + err(1, "Error opening %s", inc_file); + + yypush_buffer_state(yy_create_buffer(yyin, YY_BUF_SIZE)); + + include_stack[include_ptr] = line; + include_files[include_ptr++] = cur_file; + cur_file = strdup(inc_file); + if (cur_file == NULL) + err(2, "Cannot allocate new include file string"); + line = 0; + BEGIN(INITIAL); + } + +<<EOF>> { + yypop_buffer_state(); + + if ( !YY_CURRENT_BUFFER ) + { + yyterminate(); + } + + if (--include_ptr < 0) + err(2, "Include stack underflow"); + + free(cur_file); + cur_file = include_files[include_ptr]; + line = include_stack[include_ptr]; + } + +{ASSIGN} { + return ASSIGN; + } + +{CALL2} { + return CALL2; + } + +{CALL3} { + return CALL3; + } + +{CALL4} { + return CALL4; + } + +{CALL} { + return CALL; + } + +{CHECK} { + return CHECK; + } + +{DELAY} { + return DELAY; + } + +{INPUT} { + return INPUT; + } + +{NOINPUT} { + return NOINPUT; + } + +{COMPARE} { + return COMPARE; + } + +{COMPAREND} { + return COMPAREND; + } + +{NON_NULL} { + return NON_NULL; + } + +{NULL_RET} { + return NULL_RET; + } + +{OK_RET} { + return OK_RET; + } + +{ERR_RET} { + return ERR_RET; + } + +{OR} { + return OR; + } + +{LHB} { + return LHB; + } + +{RHB} { + return RHB; + } + +{HEX} { + /* Hex value, convert to decimal and return numeric */ + unsigned long val; + + if (sscanf(yytext, "%lx", &val) != 1) + err(1, "Bad hex conversion"); + + asprintf(&yylval.string, "%ld", val); + return numeric; + } + + +{numeric} { + if ((yylval.string = strdup(yytext)) == NULL) + err(1, "Cannot allocate numeric string"); + return numeric; +} + +{VARNAME} { + if ((yylval.string = strdup(yytext)) == NULL) + err(1, "Cannot allocate string for varname"); + return VARNAME; + } + +{FILENAME} { + size_t len; + + if ((yylval.string = dequote(yytext, &len)) == NULL) + err(1, "Cannot allocate filename string"); + return FILENAME; + } + + /* path */ +\/{PCHAR}+ { + size_t len; + if ((yylval.string = dequote(yytext, &len)) == NULL) + err(1, "Cannot allocate string"); + return PATH; + } + +\'{STRING}\' { + char *p; + size_t len; + + if ((yylval.retval = malloc(sizeof(returns_t))) == NULL) + err(1, "Cannot allocate return struct"); + p = yytext; + p++; /* skip the leading ' */ + if ((yylval.retval->return_value = dequote(p, &len)) + == NULL) + err(1, "Cannot allocate string"); + + yylval.retval->return_type = ret_byte; + /* trim trailing ' */ + yylval.retval->return_len = len - 1; + return BYTE; + } + +\`{STRING}\` { + char *p, *str; + size_t len, chlen; + size_t i; + chtype *rv; + + if ((yylval.retval = malloc(sizeof(returns_t))) == NULL) + err(1, "Cannot allocate return struct"); + p = yytext; + p++; /* skip the leading ' */ + if ((str = dequote(p, &len)) == NULL) + err(1, "Cannot allocate string"); + len--; /* trim trailing ` */ + if ((len % 2) != 0) + len--; + + chlen = ((len / 2) + 1) * sizeof(chtype); + if ((yylval.retval->return_value = malloc(chlen)) + == NULL) + err(1, "Cannot allocate chtype array"); + + rv = yylval.retval->return_value; + for (i = 0; i < len; i += 2) + *rv++ = (str[i] << 8) | str[i+1]; + *rv = __NORMAL | '\0'; /* terminates chtype array */ + yylval.retval->return_type = ret_byte; + yylval.retval->return_len = chlen; + return BYTE; + } + +\"{STRING}\" { + char *p; + size_t len; + + p = yytext; + p++; /* skip the leading " */ + if ((yylval.string = dequote(p, &len)) == NULL) + err(1, "Cannot allocate string"); + + /* remove trailing " */ + yylval.string[len - 1] = '\0'; + return STRING; + } + +\${VARNAME} { + char *p; + + p = yytext; + p++; /* skip $ before var name */ + if ((yylval.string = strdup(p)) == NULL) + err(1, "Cannot allocate string for varname"); + return VARIABLE; + } + + /* comments, white-outs */ +[ \t\r] | +#.* ; +^#.*\n | +#.*\n | +\\\n | +^\n { +line++; } + + /* eol on a line with data. need to process, return eol */ +\n { + line++; + return EOL; + } + +. { + } + +%% + +int +yywrap(void) +{ + return 1; +} |