1%{
2/*
3 * Copyright (c) 2010 Apple Inc. All rights reserved.
4 *
5 * @APPLE_LICENSE_HEADER_START@
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * 1.  Redistributions of source code must retain the above copyright
12 *     notice, this list of conditions and the following disclaimer.
13 * 2.  Redistributions in binary form must reproduce the above copyright
14 *     notice, this list of conditions and the following disclaimer in the
15 *     documentation and/or other materials provided with the distribution.
16 * 3.  Neither the name of Apple Inc. ("Apple") nor the names of its
17 *     contributors may be used to endorse or promote products derived from
18 *     this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
21 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
24 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
27 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 *
31 * Portions of this software have been released under the following terms:
32 *
33 * (c) Copyright 1989-1993 OPEN SOFTWARE FOUNDATION, INC.
34 * (c) Copyright 1989-1993 HEWLETT-PACKARD COMPANY
35 * (c) Copyright 1989-1993 DIGITAL EQUIPMENT CORPORATION
36 *
37 * To anyone who acknowledges that this file is provided "AS IS"
38 * without any express or implied warranty:
39 * permission to use, copy, modify, and distribute this file for any
40 * purpose is hereby granted without fee, provided that the above
41 * copyright notices and this notice appears in all source code copies,
42 * and that none of the names of Open Software Foundation, Inc., Hewlett-
43 * Packard Company or Digital Equipment Corporation be used
44 * in advertising or publicity pertaining to distribution of the software
45 * without specific, written prior permission.  Neither Open Software
46 * Foundation, Inc., Hewlett-Packard Company nor Digital
47 * Equipment Corporation makes any representations about the suitability
48 * of this software for any purpose.
49 *
50 * Copyright (c) 2007, Novell, Inc. All rights reserved.
51 * Redistribution and use in source and binary forms, with or without
52 * modification, are permitted provided that the following conditions
53 * are met:
54 *
55 * 1.  Redistributions of source code must retain the above copyright
56 *     notice, this list of conditions and the following disclaimer.
57 * 2.  Redistributions in binary form must reproduce the above copyright
58 *     notice, this list of conditions and the following disclaimer in the
59 *     documentation and/or other materials provided with the distribution.
60 * 3.  Neither the name of Novell Inc. nor the names of its contributors
61 *     may be used to endorse or promote products derived from this
62 *     this software without specific prior written permission.
63 *
64 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
65 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
66 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
67 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY
68 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
69 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
70 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
71 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
72 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
73 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
74 *
75 * @APPLE_LICENSE_HEADER_END@
76 */
77
78/*
79**  NAME:
80**
81**      IDL.L
82**
83**  FACILITY:
84**
85**      Interface Definition Language (IDL) Compiler
86**
87**  ABSTRACT:
88**
89**      This file defines the tokenizing rules for lexical analysis.
90**
91**  VERSION: DCE 1.0
92**
93*/
94
95/*  Get definitions for token values    */
96#define PROCESSING_LEX          /* Define before including nidl.h */
97#define PROCESSING_NIDL_LEX     /* Define before including nidl.h */
98#include <nidl.h>
99#include <ctype.h>
100#include <errors.h>
101#include <nametbl.h>
102#include <ast.h>
103#include <astp.h>
104#include <nidl_y.h>
105#include <driver.h>
106#include <command.h>
107
108/* Tank Trap to stop non-flex lexxers */
109/* The macro FLEX_SCANNER is defined and generated by FLEX */
110
111#ifndef FLEX_SCANNER
112This grammar file needs to be built with GNU Flex V2.4.6 or later.
113  GNU Flex can be be obtained from ftp://prep.ai.mit.edu:/pub/gnu
114#endif
115
116boolean search_attributes_table = false ;
117
118void commenteof (yyscan_t scanner);
119void read_c_comment (yyscan_t scanner);
120
121/* From acf_l.l */
122void acf_yymark (yyscan_t scanner);
123static int yyuuid (yyscan_t, const char *, nidl_uuid_t *);
124static int yyolduuid (yyscan_t, const char *, nidl_uuid_t *);
125
126%}
127
128/* regular definitions  */
129
130delim           [ \t\n\f]
131opt_ws          {delim}*
132ws              {delim}
133letter          [A-Za-z_$]
134digit           [0-9]
135hex_digit       [0-9A-Fa-f]
136id              {letter}({letter}|{digit})*
137l_suffix        (l|L)
138u_suffix        (u|U)
139f_suffix        (u|U)
140integer         -?{digit}+(({u_suffix}{l_suffix})|({l_suffix}{u_suffix})|{l_suffix}|{u_suffix})?
141c_hex_integer   (0(x|X){hex_digit}*)(({l_suffix}{u_suffix}?)|({u_suffix}{l_suffix}?))?
142float           {digit}+\.{digit}+({f_suffix}|{l_suffix})?
143octet           {hex_digit}{hex_digit}
144octet2          {octet}{octet}
145octet_dot       {octet}\.
146octet2_dash     {octet2}\-
147olduuid         \({opt_ws}{octet2}{octet2}{octet}{octet_dot}{octet_dot}{octet_dot}{octet_dot}{octet_dot}{octet_dot}{octet_dot}{octet_dot}{octet}{opt_ws}\)
148uuid            \({opt_ws}{octet2}{octet2_dash}{octet2_dash}{octet2_dash}{octet2_dash}{octet2}{octet2}{octet2}{opt_ws}\)
149other           .
150
151%option reentrant
152%option prefix="nidl_yy"
153%option yylineno
154%option header-file="nidl_l.h"
155%option bison-bridge
156%option bison-locations
157%option noyywrap
158
159%%
160{ws}            { /* No action, and no return */ }
161'\n'            { /* GNU FLEX doesnt automatically track line #'s */
162		    int lineno = yyget_lineno(yyscanner);
163		    yyset_lineno(lineno + 1, yyscanner);
164		    /* XXX %option lineno, tracks lines automatically. We
165		     * ought to be able to remove this -- jpeach
166		     */
167                }
168":"             {return(COLON);}
169","             {return(COMMA);}
170".."            {return(DOTDOT);}
171"="             {return(EQUAL);}
172\[              {return(LBRACKET);}
173"("             {return(LPAREN);}
174\]              {return(RBRACKET);}
175")"             {return(RPAREN);}
176";"             {return(SEMI);}
177"*"             {return(STAR);}
178"{"             {return(LBRACE);}
179"??<"           {return(LBRACE);}
180"}"             {return(RBRACE);}
181"??>"           {return(RBRACE);}
182"?"             {return(QUESTION);}
183"|"             {return(BAR);}
184"||"            {return(BARBAR);}
185"<"             {return(LANGLE);}
186"<<"            {return(LANGLEANGLE);}
187">"             {return(RANGLE);}
188">>"            {return(RANGLEANGLE);}
189"&"             {return(AMP);}
190"&&"            {return(AMPAMP);}
191"<="            {return(LESSEQUAL);}
192">="            {return(GREATEREQUAL);}
193"=="            {return(EQUALEQUAL);}
194"^"             {return(CARET);}
195"+"             {return(PLUS);}
196"-"             {return(MINUS);}
197"!"             {return(NOT);}
198"!="            {return(NOTEQUAL);}
199"/"             {return(SLASH);}
200"%"             {return(PERCENT);}
201"~"             {return(TILDE);}
202
203^"#".*\n            { acf_yymark(yyscanner) ;}
204^"%"(c|C){ws}\n     {
205    log_error(yyget_lineno(yyscanner) - 1, NIDL_USETRANS, NULL);
206}
207
208^"%pascal"{ws}\n    {
209    log_error(yyget_lineno(yyscanner) - 1, NIDL_USETRANS, NULL);
210}
211
212^"%PASCAL"{ws}\n    {
213    log_error(yyget_lineno(yyscanner) - 1, NIDL_USETRANS, NULL);
214}
215
216'\\''   {
217    /* Simple escaped single quote character literal */
218    yylval->y_char = '\'';
219    return(CHAR);
220}
221
222'[^'\n\\]'  {
223    /* Simple character constants */
224    yylval->y_char = yytext [1];
225    return(CHAR);
226}
227
228'\\[^'\n]*' {
229    /* Character constants with an escape */
230    if ((yyleng > 6) || (yyleng < 4)) {
231          log_error(yyget_lineno(yyscanner), NIDL_INVCHARLIT, NULL);
232          return(UNKNOWN);
233    }
234    switch (yytext[2]) {
235        case 'n':   yylval->y_char = '\n'; break;
236        case 't':   yylval->y_char = '\t'; break;
237        case 'v':   yylval->y_char = '\v'; break;
238        case 'b':   yylval->y_char = '\b'; break;
239        case 'r':   yylval->y_char = '\r'; break;
240        case 'f':   yylval->y_char = '\f'; break;
241        case 'a':   yylval->y_char = AUDIBLE_BELL; break;
242        case '\\':  yylval->y_char = '\\'; break;
243        case '?':   yylval->y_char = '\?'; break;
244        case '\'':  yylval->y_char = '\''; break;
245        case '\"':  yylval->y_char = '\"'; break;
246        case 'x' :  {
247            /* Hex literal value */
248            int char_value;
249            if (sscanf((char *)&yytext[3],"%x",&char_value) != 1)
250                log_error(yyget_lineno(yyscanner), NIDL_INVCHARLIT, NULL);
251            else
252            {
253                yylval->y_char = (char )char_value;
254                log_warning(yyget_lineno(yyscanner), NIDL_NONPORTCHAR, NULL);
255            }
256            break;
257        }
258        case '0':
259        case '1':
260        case '2':
261        case '3':
262        case '4':
263        case '5':
264        case '7':   {
265            /* Octal literal value */
266            int char_value;
267            if (sscanf((char *)&yytext[2],"%o",&char_value) != 1)
268                log_error(yyget_lineno(yyscanner), NIDL_INVCHARLIT, NULL);
269            else
270            {
271                yylval->y_char = (char )char_value;
272                log_warning(yyget_lineno(yyscanner), NIDL_NONPORTCHAR, NULL);
273            }
274            break;
275        }
276        default:
277            /* all others are illegal */
278            log_error(yyget_lineno(yyscanner), NIDL_INVCHARLIT, NULL);
279            return(UNKNOWN);
280    }
281
282    return (CHAR);
283}
284
285\"[^\"\n]*  {
286    char stripped_string[max_string_len] ATTRIBUTE_UNUSED;
287    if (yytext[yyleng-1] == '\\')
288    {
289	/* Allow backslashed " within strings, look for next " */
290        yymore();
291    }
292    else
293    {
294	yylval->y_string = STRTAB_add_string((char *)&yytext[1]);
295        if (input(yyscanner) == '\n')
296            log_error(yyget_lineno(yyscanner), NIDL_STRUNTERM, NULL);
297        return(STRING);
298    }
299}
300
301"/*"    { read_c_comment(yyscanner); }
302"//".*\n	{ /* read_cpp_comment */ }
303
304{id}    {
305    int token;
306    NAMETABLE_id_t id;
307    /* If id is too long, truncate it and issue a warning */
308    if (yyleng > MAX_ID) {
309        char const *identifier;
310        id = NAMETABLE_add_id((char *)yytext);
311        NAMETABLE_id_to_string(id, &identifier);
312        log_warning(yyget_lineno(yyscanner), NIDL_IDTOOLONG, identifier, MAX_ID, NULL);
313        /* Truncate the string */
314        yytext[MAX_ID] = '\0';
315        id = NAMETABLE_add_id((char *)yytext);
316    }
317    if ((token = KEYWORDS_screen((char *)yytext, &id))==IDENTIFIER) {
318        yylval->y_id = id;
319    }
320    else {
321        yylval->y_id = NAMETABLE_NIL_ID;
322    }
323    return token;
324}
325
326{integer}   {
327    int unsigned_int = false;
328#if defined(vax) && defined(ultrix)
329    float fval;
330#define FLOAT_FORMAT "%f"
331#define FLOAT float
332#else
333    double fval;
334#define FLOAT_FORMAT "%lf"
335#define FLOAT double
336#endif
337
338    /*
339    ** Remove suffix for long and/or unsigned, if present
340    */
341    if ((yytext[yyleng-1] == 'L') ||
342        (yytext[yyleng-1] == 'l') ||
343        (yytext[yyleng-1] == 'U') ||
344        (yytext[yyleng-1] == 'u'))
345    {
346        if ((yytext[yyleng-1] == 'U') ||
347            (yytext[yyleng-1] == 'u'))
348                unsigned_int = true;
349        yytext[yyleng-1] = '\0';
350        if ((yytext[yyleng-2] == 'L') ||
351            (yytext[yyleng-2] == 'l') ||
352            (yytext[yyleng-2] == 'U') ||
353            (yytext[yyleng-2] == 'u'))
354        {
355            if ((yytext[yyleng-2] == 'U') ||
356                (yytext[yyleng-2] == 'u'))
357                    unsigned_int = true;
358            yytext[yyleng-2] = '\0';
359        }
360    }
361
362    /*
363    ** Convert to a float to get overflow detection.
364    */
365    sscanf((char *)yytext, FLOAT_FORMAT, &fval);
366    yylval->y_int_info.int_val = 0;
367
368    /*
369    ** Throw out integers that are out of range.
370    */
371    if (unsigned_int &&
372        ((strlen((char *)yytext) > 10)
373        || (fval > (FLOAT)ASTP_C_ULONG_MAX)
374        || (fval < (FLOAT)ASTP_C_ULONG_MIN)
375        ))
376        log_error(yyget_lineno(yyscanner), NIDL_INTOVERFLOW,
377		  KEYWORDS_lookup_text(LONG_KW), NULL);
378    else if ((strlen((char *)yytext) > 11) ||
379        (fval > (FLOAT)ASTP_C_LONG_MAX) ||
380        (fval < (FLOAT)ASTP_C_LONG_MIN)
381        )
382        log_error(yyget_lineno(yyscanner), NIDL_INTOVERFLOW,
383		  KEYWORDS_lookup_text(LONG_KW), NULL);
384    else {
385        sscanf((char *)yytext, "%ld", &yylval->y_int_info.int_val);
386    }
387
388    if ((yytext[0] == '0') && (strlen((char *)yytext) != strspn((char *)yytext,"01234567"))) {
389        char const *int_text;           /* Text of integer */
390        STRTAB_str_t string_id;         /* Entry in string table of integer */
391        string_id = STRTAB_add_string(yytext);
392        STRTAB_str_to_string(string_id, &int_text);
393        log_error(yyget_lineno(yyscanner), NIDL_INVOCTDIGIT, int_text, NULL);
394    }
395
396	/* remember the signed-ness */
397	yylval->y_int_info.int_signed = !unsigned_int;
398
399    return(INTEGER_NUMERIC);
400}
401
402{c_hex_integer} {
403	 int unsigned_int = true;
404    /*
405    ** Remove suffix for long and/or unsigned, if present
406    */
407    if ((yytext[yyleng-1] == 'L') ||
408        (yytext[yyleng-1] == 'l') ||
409        (yytext[yyleng-1] == 'U') ||
410        (yytext[yyleng-1] == 'u'))
411	 {
412		  if (yytext[yyleng-1] == 'U' || yytext[yyleng-1] == 'u')
413				unsigned_int = true;
414		  yytext[yyleng-1] = '\0';
415		  if ((yytext[yyleng-2] == 'L') ||
416					 (yytext[yyleng-2] == 'l') ||
417					 (yytext[yyleng-2] == 'U') ||
418					 (yytext[yyleng-2] == 'u'))
419		  {
420				if (yytext[yyleng-2] == 'U' || yytext[yyleng-2] == 'u')
421					 unsigned_int = true;
422
423				yytext[yyleng-2] = '\0';
424		  }
425	 }
426
427    /*
428    ** Scan the hex integer and return the value as an integer
429    */
430    sscanf((char *)&yytext[2],"%lx", &yylval->y_int_info.int_val);
431	 yylval->y_int_info.int_signed = !unsigned_int;
432    return(INTEGER_NUMERIC);
433}
434
435{float} {
436    yylval->y_float = STRTAB_add_string((char *)yytext);
437    return(FLOAT_NUMERIC);
438}
439
440{uuid}      {   return (yyuuid(yyscanner, &yytext[1], &yylval->y_uuid)); }
441{olduuid}   {   return (yyolduuid(yyscanner, &yytext[1], &yylval->y_uuid)); }
442{other}     {   return (UNKNOWN); }
443
444%%
445
446void commenteof
447(
448    yyscan_t scanner
449)
450{
451    log_error (yyget_lineno(scanner), NIDL_COMMENTEOF, NULL);
452    nidl_terminate();
453}
454
455void read_c_comment
456(
457    yyscan_t scanner
458)
459{
460    register int c;
461
462    /* While not EOF look for end of comment */
463    while ((c = input(scanner)))
464    {
465        if (c == '*')
466        {
467            if ((c = input(scanner)) == '/')
468                break ;
469            else
470		yyunput(c, yyget_text(scanner), scanner);
471        }
472    }
473
474    /* Didn't find end comment before EOF, issue error */
475    if (c == 0) commenteof(scanner);
476}
477
478static int yyolduuid
479(
480    yyscan_t	scanner,
481    const char *str,
482    nidl_uuid_t *uuid
483)
484{
485    unsigned32 v1_time_high;
486    unsigned32 v1_time_low;
487    unsigned32 v1_reserved = 0;  /* v1 UUID always zero here */
488    unsigned32 v1_family;
489    unsigned32 v1_host[7];
490    int        i;
491    char *uuid_str;
492
493    if (sscanf(str, "%8lX%4lX.%2lX.%2lX.%2lX.%2lX.%2lX.%2lX.%2lX.%2lX",
494              &v1_time_high, &v1_time_low, &v1_family,
495              &v1_host[0], &v1_host[1], &v1_host[2], &v1_host[3],
496              &v1_host[4], &v1_host[5], &v1_host[6]) != 10)
497    {
498        log_error(yyget_lineno(scanner), NIDL_SYNTAXUUID, NULL);
499    }
500
501    /* scanf only returns ints, so scan into ints and copy into smaller types */
502    uuid->time_low                  = v1_time_high;
503    uuid->time_mid                  = v1_time_low;
504    uuid->time_hi_and_version       = v1_reserved;
505    uuid->clock_seq_hi_and_reserved = v1_family;
506    uuid->clock_seq_low             = v1_host[0];
507
508    for (i=0; i < 6; i++)
509        uuid->node[i] = v1_host[i+1];
510
511    uuid_str = (char *)malloc(sizeof("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"));
512
513    sprintf(uuid_str, "%08lX-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X",
514              uuid->time_low, uuid->time_mid, uuid->time_hi_and_version,
515              uuid->clock_seq_hi_and_reserved, uuid->clock_seq_low,
516              uuid->node[0], uuid->node[1], uuid->node[2],
517              uuid->node[3], uuid->node[4], uuid->node[5]);
518
519    log_warning(yyget_lineno(scanner), NIDL_OLDUUID, NULL);
520    log_warning(yyget_lineno(scanner), NIDL_NEWUUID, uuid_str, NULL);
521    return (UUID_REP) ;
522}
523
524static int yyuuid
525(
526    yyscan_t	scanner,
527    const char	*str,
528    nidl_uuid_t *uuid
529)
530{
531    int i;
532    unsigned32 time_low, time_mid, time_hi_and_version,
533              clock_seq_hi_and_reserved, clock_seq_low,
534              node[6];
535
536    if (sscanf(str,
537	      "%08lX-%04lX-%04lX-%02lX%02lX-%02lX%02lX%02lX%02lX%02lX%02lX",
538              &time_low, &time_mid, &time_hi_and_version,
539              &clock_seq_hi_and_reserved, &clock_seq_low,
540              &node[0], &node[1], &node[2],
541              &node[3], &node[4], &node[5]) != 11)
542    {
543        log_error(yyget_lineno(scanner), NIDL_SYNTAXUUID, NULL);
544    }
545
546    /* scanf only returns ints, so scan into ints and copy into smaller types */
547    uuid->time_low = time_low;
548    uuid->time_mid = time_mid;
549    uuid->time_hi_and_version = time_hi_and_version;
550    uuid->clock_seq_hi_and_reserved = clock_seq_hi_and_reserved;
551    uuid->clock_seq_low = clock_seq_low;
552    for (i=0; i < 6; i++)
553        uuid->node[i] = node[i];
554    return (UUID_REP);
555}
556
557/* preserve coding style vim: set tw=78 sw=4 : */
558