]> CyberLeo.Net >> Repos - FreeBSD/releng/10.2.git/blob - contrib/netbsd-tests/lib/libcurses/director/testlang_conf.l
- Copy stable/10@285827 to releng/10.2 in preparation for 10.2-RC1
[FreeBSD/releng/10.2.git] / contrib / netbsd-tests / lib / libcurses / director / testlang_conf.l
1 %{
2 /*      $NetBSD: testlang_conf.l,v 1.7 2013/11/21 11:06:04 blymn Exp $  */
3
4 /*-
5  * Copyright 2009 Brett Lymn <blymn@NetBSD.org>
6  *
7  * All rights reserved.
8  *
9  * This code has been donated to The NetBSD Foundation by the Author.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
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
18  *
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.
29  *
30  *
31  */
32
33 #include <curses.h>
34 #include <ctype.h>
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <string.h>
38 #include <sys/param.h>
39 #include <err.h>
40 #include "returns.h"
41 #include "testlang_parse.h"
42
43 #define MAX_INCLUDES 32 /* limit for the number of nested includes */
44
45 int yylex(void);
46
47 extern size_t line;
48 extern char *include_path;      /* from director.c */
49 extern char *cur_file;          /* from director.c */
50
51 static int include_stack[MAX_INCLUDES];
52 static char *include_files[MAX_INCLUDES];
53 static int include_ptr = 0;
54
55 static char *
56 dequote(const char *s, size_t *len)
57 {
58         const unsigned char *p;
59         char *buf, *q;
60
61         *len = 0;
62         p = (const unsigned char *)s;
63         while (*p) {
64                 if (*p == '\\' && *(p+1)) {
65                         if (isdigit(*(p+1)) && *(p+2) && isdigit(*(p+2)) &&
66                             *(p+3) && isdigit(*(p+3)))
67                                 p += 3;
68                         else
69                                 ++p;
70                 }
71                 ++(*len);
72                 ++p;
73         }
74
75         buf = malloc(*len + 1);
76         if (buf == NULL)
77                 return NULL;
78
79         p = (const unsigned char *)s;
80         q = buf;
81         while (*p) {
82                 if (*p == '\\' && *(p+1)) {
83                         ++p;
84                         if (isdigit(*p)) {
85                                 if (*(p+1) && isdigit(*(p+1)) && *(p+2) &&
86                                     isdigit(*(p+2))) {
87                                         *q++ = ((*p - '0') * 8 + (*(p+1) - '0')) * 8 + (*(p+2) - '0');
88                                         p += 3;
89                                 } else {
90                                         *q++ = *p++;
91                                 }
92                         } else {
93                                 switch (*p) {
94                                 case 'e':
95                                         /* escape */
96                                         *q++ = '\e';
97                                         p++;
98                                         break;
99
100                                 case 'n':
101                                         /* newline */
102                                         *q++ = '\n';
103                                         p++;
104                                         break;
105
106                                 case 'r':
107                                         /* carriage return */
108                                         *q++ = '\r';
109                                         p++;
110                                         break;
111
112                                 case 't':
113                                         /* tab */
114                                         *q++ = '\t';
115                                         p++;
116                                         break;
117
118                                 case '\\':
119                                         /* backslash */
120                                         *q++ = '\\';
121                                         p++;
122                                         break;
123
124                                 default:
125                                         *q++ = *p++;
126                                 }
127                         }
128                 } else
129                         *q++ = *p++;
130         }
131         *q++ = '\0';
132
133         return buf;
134 }
135 %}
136
137 HEX             0[xX][0-9a-zA-Z]+
138 STRING          [0-9a-z!#-&(-^ \t%._\\]+
139 numeric         [-0-9]+
140 PCHAR           (\\.|[^ \t\n])
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]
150 OK_RET          [oO][kK]
151 ERR_RET         [eE][rR][rR]
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_-]+
156 NULL_RET        NULL
157 NON_NULL        NON_NULL
158 BYTE            BYTE
159 OR              \|
160 LHB             \(
161 RHB             \)
162
163 %x incl
164 %option noinput nounput
165
166 %%
167
168 include         BEGIN(incl);
169
170 <incl>[ \t]*      /* eat the whitespace */
171 <incl>[^ \t\n]+   { /* got the include file name */
172                 char inc_file[MAXPATHLEN];
173
174                 if (include_ptr > MAX_INCLUDES) {
175                         fprintf(stderr,
176                                 "Maximum number of nested includes exceeded "
177                                 "at line %zu of file %s\n", line, cur_file);
178                                 exit(2);
179                 }
180
181                 if (yytext[0] != '/') {
182                         if (strlcpy(inc_file, include_path, sizeof(inc_file))
183                             >= 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");
189                 } else {
190                         inc_file[0] = '\0';
191                 }
192
193                 if (strlcat(inc_file, yytext, sizeof(inc_file))
194                     >= sizeof(inc_file))
195                         err(2, "Path to include file path overflowed");
196
197                 yyin = fopen(inc_file, "r" );
198
199                 if (!yyin)
200                         err(1, "Error opening %s", inc_file);
201
202                 yypush_buffer_state(yy_create_buffer(yyin, YY_BUF_SIZE));
203
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");
209                 line = 0;
210                 BEGIN(INITIAL);
211         }
212
213 <<EOF>> {
214                 yypop_buffer_state();
215
216                 if ( !YY_CURRENT_BUFFER )
217                 {
218                         yyterminate();
219                 }
220
221                 if (--include_ptr < 0)
222                         err(2, "Include stack underflow");
223
224                 free(cur_file);
225                 cur_file = include_files[include_ptr];
226                 line = include_stack[include_ptr];
227         }
228
229 {ASSIGN}        {
230                         return ASSIGN;
231                 }
232
233 {CALL2}         {
234                         return CALL2;
235                 }
236
237 {CALL3}         {
238                         return CALL3;
239                 }
240
241 {CALL4}         {
242                         return CALL4;
243                 }
244
245 {CALL}          {
246                         return CALL;
247                 }
248
249 {CHECK}         {
250                         return CHECK;
251                 }
252
253 {DELAY}         {
254                         return DELAY;
255                 }
256
257 {INPUT}         {
258                         return INPUT;
259                 }
260
261 {NOINPUT}               {
262                         return NOINPUT;
263                 }
264
265 {COMPARE}       {
266                         return COMPARE;
267                 }
268
269 {COMPAREND}     {
270                         return COMPAREND;
271                 }
272
273 {NON_NULL}      {
274                         return NON_NULL;
275                 }
276
277 {NULL_RET}              {
278                         return NULL_RET;
279                 }
280
281 {OK_RET}                {
282                         return OK_RET;
283                 }
284
285 {ERR_RET}               {
286                         return ERR_RET;
287                 }
288
289 {OR}            {
290                         return OR;
291                 }
292
293 {LHB}           {
294                         return LHB;
295                 }
296
297 {RHB}           {
298                         return RHB;
299                 }
300
301 {HEX}           {
302                         /* Hex value, convert to decimal and return numeric */
303                         unsigned long val;
304
305                         if (sscanf(yytext, "%lx", &val) != 1)
306                                 err(1, "Bad hex conversion");
307
308                         asprintf(&yylval.string, "%ld", val);
309                         return numeric;
310                 }
311
312
313 {numeric}               {
314                         if ((yylval.string = strdup(yytext)) == NULL)
315                                 err(1, "Cannot allocate numeric string");
316                         return numeric;
317 }
318
319 {VARNAME}       {
320                         if ((yylval.string = strdup(yytext)) == NULL)
321                                 err(1, "Cannot allocate string for varname");
322                         return VARNAME;
323                 }
324
325 {FILENAME}      {
326                         size_t len;
327
328                         if ((yylval.string = dequote(yytext, &len)) == NULL)
329                                 err(1, "Cannot allocate filename string");
330                         return FILENAME;
331                 }
332
333         /* path */
334 \/{PCHAR}+      {
335                         size_t len;
336                         if ((yylval.string = dequote(yytext, &len)) == NULL)
337                                 err(1, "Cannot allocate string");
338                         return PATH;
339                 }
340
341 \'{STRING}\'    {
342                         char *p;
343                         size_t len;
344
345                         if ((yylval.retval = malloc(sizeof(returns_t))) == NULL)
346                                 err(1, "Cannot allocate return struct");
347                         p = yytext;
348                         p++; /* skip the leading ' */
349                         if ((yylval.retval->return_value = dequote(p, &len))
350                              == NULL)
351                                 err(1, "Cannot allocate string");
352
353                         yylval.retval->return_type = ret_byte;
354                         /* trim trailing ' */
355                         yylval.retval->return_len = len - 1;
356                         return BYTE;
357                 }
358
359 \`{STRING}\`    {
360                         char *p, *str;
361                         size_t len, chlen;
362                         size_t i;
363                         chtype *rv;
364
365                         if ((yylval.retval = malloc(sizeof(returns_t))) == NULL)
366                                 err(1, "Cannot allocate return struct");
367                         p = yytext;
368                         p++; /* skip the leading ' */
369                         if ((str = dequote(p, &len)) == NULL)
370                                 err(1, "Cannot allocate string");
371                         len--; /* trim trailing ` */
372                         if ((len % 2) != 0)
373                                 len--;
374
375                         chlen = ((len / 2) + 1) * sizeof(chtype);
376                         if ((yylval.retval->return_value = malloc(chlen))
377                             == NULL)
378                                 err(1, "Cannot allocate chtype array");
379
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;
386                         return BYTE;
387                 }
388
389 \"{STRING}\"    {
390                         char *p;
391                         size_t len;
392
393                         p = yytext;
394                         p++; /* skip the leading " */
395                         if ((yylval.string = dequote(p, &len)) == NULL)
396                                 err(1, "Cannot allocate string");
397
398                         /* remove trailing " */
399                         yylval.string[len - 1] = '\0';
400                         return STRING;
401                 }
402
403 \${VARNAME}     {
404                         char *p;
405
406                         p = yytext;
407                         p++; /* skip $ before var name */
408                         if ((yylval.string = strdup(p)) == NULL)
409                                 err(1, "Cannot allocate string for varname");
410                         return VARIABLE;
411                 }
412         
413         /* comments, white-outs */
414 [ \t\r]         |
415 #.*             ;
416 ^#.*\n          |
417 #.*\n           |
418 \\\n            |
419 ^\n             { 
420 line++; }
421
422         /* eol on a line with data. need to process, return eol */
423 \n              {
424                         line++;
425                         return EOL;
426                 }
427
428 .               {
429                 }
430
431 %%
432
433 int
434 yywrap(void)
435 {
436         return 1;
437 }