%{
/*
* Copyright (c) 2010 Apple Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* 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. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Apple Inc. ("Apple") nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "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 APPLE OR ITS CONTRIBUTORS 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.
*
* Portions of this software have been released under the following terms:
*
* (c) Copyright 1989-1993 OPEN SOFTWARE FOUNDATION, INC.
* (c) Copyright 1989-1993 HEWLETT-PACKARD COMPANY
* (c) Copyright 1989-1993 DIGITAL EQUIPMENT CORPORATION
*
* To anyone who acknowledges that this file is provided "AS IS"
* without any express or implied warranty:
* permission to use, copy, modify, and distribute this file for any
* purpose is hereby granted without fee, provided that the above
* copyright notices and this notice appears in all source code copies,
* and that none of the names of Open Software Foundation, Inc., Hewlett-
* Packard Company or Digital Equipment Corporation be used
* in advertising or publicity pertaining to distribution of the software
* without specific, written prior permission. Neither Open Software
* Foundation, Inc., Hewlett-Packard Company nor Digital
* Equipment Corporation makes any representations about the suitability
* of this software for any purpose.
*
* Copyright (c) 2007, Novell, Inc. All rights reserved.
* 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. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Novell Inc. nor the names of its contributors
* may be used to endorse or promote products derived from this
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT HOLDERS OR CONTRIBUTORS 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.
*
* @APPLE_LICENSE_HEADER_END@
*/
/*
** NAME:
**
** IDL.L
**
** FACILITY:
**
** Interface Definition Language (IDL) Compiler
**
** ABSTRACT:
**
** This file defines the tokenizing rules for lexical analysis.
**
** VERSION: DCE 1.0
**
*/
/* Get definitions for token values */
#define PROCESSING_LEX /* Define before including nidl.h */
#define PROCESSING_NIDL_LEX /* Define before including nidl.h */
#include <nidl.h>
#include <ctype.h>
#include <errors.h>
#include <nametbl.h>
#include <ast.h>
#include <astp.h>
#include <nidl_y.h>
#include <driver.h>
#include <command.h>
/* Tank Trap to stop non-flex lexxers */
/* The macro FLEX_SCANNER is defined and generated by FLEX */
#ifndef FLEX_SCANNER
This grammar file needs to be built with GNU Flex V2.4.6 or later.
GNU Flex can be be obtained from ftp://prep.ai.mit.edu:/pub/gnu
#endif
boolean search_attributes_table = false ;
void commenteof (yyscan_t scanner);
void read_c_comment (yyscan_t scanner);
/* From acf_l.l */
void acf_yymark (yyscan_t scanner);
static int yyuuid (yyscan_t, const char *, nidl_uuid_t *);
static int yyolduuid (yyscan_t, const char *, nidl_uuid_t *);
%}
/* regular definitions */
delim [ \t\n\f]
opt_ws {delim}*
ws {delim}
letter [A-Za-z_$]
digit [0-9]
hex_digit [0-9A-Fa-f]
id {letter}({letter}|{digit})*
l_suffix (l|L)
u_suffix (u|U)
f_suffix (u|U)
integer -?{digit}+(({u_suffix}{l_suffix})|({l_suffix}{u_suffix})|{l_suffix}|{u_suffix})?
c_hex_integer (0(x|X){hex_digit}*)(({l_suffix}{u_suffix}?)|({u_suffix}{l_suffix}?))?
float {digit}+\.{digit}+({f_suffix}|{l_suffix})?
octet {hex_digit}{hex_digit}
octet2 {octet}{octet}
octet_dot {octet}\.
octet2_dash {octet2}\-
olduuid \({opt_ws}{octet2}{octet2}{octet}{octet_dot}{octet_dot}{octet_dot}{octet_dot}{octet_dot}{octet_dot}{octet_dot}{octet_dot}{octet}{opt_ws}\)
uuid \({opt_ws}{octet2}{octet2_dash}{octet2_dash}{octet2_dash}{octet2_dash}{octet2}{octet2}{octet2}{opt_ws}\)
other .
%option reentrant
%option prefix="nidl_yy"
%option yylineno
%option header-file="nidl_l.h"
%option bison-bridge
%option bison-locations
%option noyywrap
%%
{ws} { /* No action, and no return */ }
'\n' { /* GNU FLEX doesnt automatically track line #'s */
int lineno = yyget_lineno(yyscanner);
yyset_lineno(lineno + 1, yyscanner);
/* XXX %option lineno, tracks lines automatically. We
* ought to be able to remove this -- jpeach
*/
}
":" {return(COLON);}
"," {return(COMMA);}
".." {return(DOTDOT);}
"=" {return(EQUAL);}
\[ {return(LBRACKET);}
"(" {return(LPAREN);}
\] {return(RBRACKET);}
")" {return(RPAREN);}
";" {return(SEMI);}
"*" {return(STAR);}
"{" {return(LBRACE);}
"??<" {return(LBRACE);}
"}" {return(RBRACE);}
"??>" {return(RBRACE);}
"?" {return(QUESTION);}
"|" {return(BAR);}
"||" {return(BARBAR);}
"<" {return(LANGLE);}
"<<" {return(LANGLEANGLE);}
">" {return(RANGLE);}
">>" {return(RANGLEANGLE);}
"&" {return(AMP);}
"&&" {return(AMPAMP);}
"<=" {return(LESSEQUAL);}
">=" {return(GREATEREQUAL);}
"==" {return(EQUALEQUAL);}
"^" {return(CARET);}
"+" {return(PLUS);}
"-" {return(MINUS);}
"!" {return(NOT);}
"!=" {return(NOTEQUAL);}
"/" {return(SLASH);}
"%" {return(PERCENT);}
"~" {return(TILDE);}
^"#".*\n { acf_yymark(yyscanner) ;}
^"%"(c|C){ws}\n {
log_error(yyget_lineno(yyscanner) - 1, NIDL_USETRANS, NULL);
}
^"%pascal"{ws}\n {
log_error(yyget_lineno(yyscanner) - 1, NIDL_USETRANS, NULL);
}
^"%PASCAL"{ws}\n {
log_error(yyget_lineno(yyscanner) - 1, NIDL_USETRANS, NULL);
}
'\\'' {
/* Simple escaped single quote character literal */
yylval->y_char = '\'';
return(CHAR);
}
'[^'\n\\]' {
/* Simple character constants */
yylval->y_char = yytext [1];
return(CHAR);
}
'\\[^'\n]*' {
/* Character constants with an escape */
if ((yyleng > 6) || (yyleng < 4)) {
log_error(yyget_lineno(yyscanner), NIDL_INVCHARLIT, NULL);
return(UNKNOWN);
}
switch (yytext[2]) {
case 'n': yylval->y_char = '\n'; break;
case 't': yylval->y_char = '\t'; break;
case 'v': yylval->y_char = '\v'; break;
case 'b': yylval->y_char = '\b'; break;
case 'r': yylval->y_char = '\r'; break;
case 'f': yylval->y_char = '\f'; break;
case 'a': yylval->y_char = AUDIBLE_BELL; break;
case '\\': yylval->y_char = '\\'; break;
case '?': yylval->y_char = '\?'; break;
case '\'': yylval->y_char = '\''; break;
case '\"': yylval->y_char = '\"'; break;
case 'x' : {
/* Hex literal value */
int char_value;
if (sscanf((char *)&yytext[3],"%x",&char_value) != 1)
log_error(yyget_lineno(yyscanner), NIDL_INVCHARLIT, NULL);
else
{
yylval->y_char = (char )char_value;
log_warning(yyget_lineno(yyscanner), NIDL_NONPORTCHAR, NULL);
}
break;
}
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '7': {
/* Octal literal value */
int char_value;
if (sscanf((char *)&yytext[2],"%o",&char_value) != 1)
log_error(yyget_lineno(yyscanner), NIDL_INVCHARLIT, NULL);
else
{
yylval->y_char = (char )char_value;
log_warning(yyget_lineno(yyscanner), NIDL_NONPORTCHAR, NULL);
}
break;
}
default:
/* all others are illegal */
log_error(yyget_lineno(yyscanner), NIDL_INVCHARLIT, NULL);
return(UNKNOWN);
}
return (CHAR);
}
\"[^\"\n]* {
char stripped_string[max_string_len] ATTRIBUTE_UNUSED;
if (yytext[yyleng-1] == '\\')
{
/* Allow backslashed " within strings, look for next " */
yymore();
}
else
{
yylval->y_string = STRTAB_add_string((char *)&yytext[1]);
if (input(yyscanner) == '\n')
log_error(yyget_lineno(yyscanner), NIDL_STRUNTERM, NULL);
return(STRING);
}
}
"/*" { read_c_comment(yyscanner); }
"//".*\n { /* read_cpp_comment */ }
{id} {
int token;
NAMETABLE_id_t id;
/* If id is too long, truncate it and issue a warning */
if (yyleng > MAX_ID) {
char const *identifier;
id = NAMETABLE_add_id((char *)yytext);
NAMETABLE_id_to_string(id, &identifier);
log_warning(yyget_lineno(yyscanner), NIDL_IDTOOLONG, identifier, MAX_ID, NULL);
/* Truncate the string */
yytext[MAX_ID] = '\0';
id = NAMETABLE_add_id((char *)yytext);
}
if ((token = KEYWORDS_screen((char *)yytext, &id))==IDENTIFIER) {
yylval->y_id = id;
}
else {
yylval->y_id = NAMETABLE_NIL_ID;
}
return token;
}
{integer} {
int unsigned_int = false;
#if defined(vax) && defined(ultrix)
float fval;
#define FLOAT_FORMAT "%f"
#define FLOAT float
#else
double fval;
#define FLOAT_FORMAT "%lf"
#define FLOAT double
#endif
/*
** Remove suffix for long and/or unsigned, if present
*/
if ((yytext[yyleng-1] == 'L') ||
(yytext[yyleng-1] == 'l') ||
(yytext[yyleng-1] == 'U') ||
(yytext[yyleng-1] == 'u'))
{
if ((yytext[yyleng-1] == 'U') ||
(yytext[yyleng-1] == 'u'))
unsigned_int = true;
yytext[yyleng-1] = '\0';
if ((yytext[yyleng-2] == 'L') ||
(yytext[yyleng-2] == 'l') ||
(yytext[yyleng-2] == 'U') ||
(yytext[yyleng-2] == 'u'))
{
if ((yytext[yyleng-2] == 'U') ||
(yytext[yyleng-2] == 'u'))
unsigned_int = true;
yytext[yyleng-2] = '\0';
}
}
/*
** Convert to a float to get overflow detection.
*/
sscanf((char *)yytext, FLOAT_FORMAT, &fval);
yylval->y_int_info.int_val = 0;
/*
** Throw out integers that are out of range.
*/
if (unsigned_int &&
((strlen((char *)yytext) > 10)
|| (fval > (FLOAT)ASTP_C_ULONG_MAX)
|| (fval < (FLOAT)ASTP_C_ULONG_MIN)
))
log_error(yyget_lineno(yyscanner), NIDL_INTOVERFLOW,
KEYWORDS_lookup_text(LONG_KW), NULL);
else if ((strlen((char *)yytext) > 11) ||
(fval > (FLOAT)ASTP_C_LONG_MAX) ||
(fval < (FLOAT)ASTP_C_LONG_MIN)
)
log_error(yyget_lineno(yyscanner), NIDL_INTOVERFLOW,
KEYWORDS_lookup_text(LONG_KW), NULL);
else {
sscanf((char *)yytext, "%ld", &yylval->y_int_info.int_val);
}
if ((yytext[0] == '0') && (strlen((char *)yytext) != strspn((char *)yytext,"01234567"))) {
char const *int_text; /* Text of integer */
STRTAB_str_t string_id; /* Entry in string table of integer */
string_id = STRTAB_add_string(yytext);
STRTAB_str_to_string(string_id, &int_text);
log_error(yyget_lineno(yyscanner), NIDL_INVOCTDIGIT, int_text, NULL);
}
/* remember the signed-ness */
yylval->y_int_info.int_signed = !unsigned_int;
return(INTEGER_NUMERIC);
}
{c_hex_integer} {
int unsigned_int = true;
/*
** Remove suffix for long and/or unsigned, if present
*/
if ((yytext[yyleng-1] == 'L') ||
(yytext[yyleng-1] == 'l') ||
(yytext[yyleng-1] == 'U') ||
(yytext[yyleng-1] == 'u'))
{
if (yytext[yyleng-1] == 'U' || yytext[yyleng-1] == 'u')
unsigned_int = true;
yytext[yyleng-1] = '\0';
if ((yytext[yyleng-2] == 'L') ||
(yytext[yyleng-2] == 'l') ||
(yytext[yyleng-2] == 'U') ||
(yytext[yyleng-2] == 'u'))
{
if (yytext[yyleng-2] == 'U' || yytext[yyleng-2] == 'u')
unsigned_int = true;
yytext[yyleng-2] = '\0';
}
}
/*
** Scan the hex integer and return the value as an integer
*/
sscanf((char *)&yytext[2],"%lx", &yylval->y_int_info.int_val);
yylval->y_int_info.int_signed = !unsigned_int;
return(INTEGER_NUMERIC);
}
{float} {
yylval->y_float = STRTAB_add_string((char *)yytext);
return(FLOAT_NUMERIC);
}
{uuid} { return (yyuuid(yyscanner, &yytext[1], &yylval->y_uuid)); }
{olduuid} { return (yyolduuid(yyscanner, &yytext[1], &yylval->y_uuid)); }
{other} { return (UNKNOWN); }
%%
void commenteof
(
yyscan_t scanner
)
{
log_error (yyget_lineno(scanner), NIDL_COMMENTEOF, NULL);
nidl_terminate();
}
void read_c_comment
(
yyscan_t scanner
)
{
register int c;
/* While not EOF look for end of comment */
while ((c = input(scanner)))
{
if (c == '*')
{
if ((c = input(scanner)) == '/')
break ;
else
yyunput(c, yyget_text(scanner), scanner);
}
}
/* Didn't find end comment before EOF, issue error */
if (c == 0) commenteof(scanner);
}
static int yyolduuid
(
yyscan_t scanner,
const char *str,
nidl_uuid_t *uuid
)
{
unsigned32 v1_time_high;
unsigned32 v1_time_low;
unsigned32 v1_reserved = 0; /* v1 UUID always zero here */
unsigned32 v1_family;
unsigned32 v1_host[7];
int i;
char *uuid_str;
if (sscanf(str, "%8lX%4lX.%2lX.%2lX.%2lX.%2lX.%2lX.%2lX.%2lX.%2lX",
&v1_time_high, &v1_time_low, &v1_family,
&v1_host[0], &v1_host[1], &v1_host[2], &v1_host[3],
&v1_host[4], &v1_host[5], &v1_host[6]) != 10)
{
log_error(yyget_lineno(scanner), NIDL_SYNTAXUUID, NULL);
}
/* scanf only returns ints, so scan into ints and copy into smaller types */
uuid->time_low = v1_time_high;
uuid->time_mid = v1_time_low;
uuid->time_hi_and_version = v1_reserved;
uuid->clock_seq_hi_and_reserved = v1_family;
uuid->clock_seq_low = v1_host[0];
for (i=0; i < 6; i++)
uuid->node[i] = v1_host[i+1];
uuid_str = (char *)malloc(sizeof("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"));
sprintf(uuid_str, "%08lX-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X",
uuid->time_low, uuid->time_mid, uuid->time_hi_and_version,
uuid->clock_seq_hi_and_reserved, uuid->clock_seq_low,
uuid->node[0], uuid->node[1], uuid->node[2],
uuid->node[3], uuid->node[4], uuid->node[5]);
log_warning(yyget_lineno(scanner), NIDL_OLDUUID, NULL);
log_warning(yyget_lineno(scanner), NIDL_NEWUUID, uuid_str, NULL);
return (UUID_REP) ;
}
static int yyuuid
(
yyscan_t scanner,
const char *str,
nidl_uuid_t *uuid
)
{
int i;
unsigned32 time_low, time_mid, time_hi_and_version,
clock_seq_hi_and_reserved, clock_seq_low,
node[6];
if (sscanf(str,
"%08lX-%04lX-%04lX-%02lX%02lX-%02lX%02lX%02lX%02lX%02lX%02lX",
&time_low, &time_mid, &time_hi_and_version,
&clock_seq_hi_and_reserved, &clock_seq_low,
&node[0], &node[1], &node[2],
&node[3], &node[4], &node[5]) != 11)
{
log_error(yyget_lineno(scanner), NIDL_SYNTAXUUID, NULL);
}
/* scanf only returns ints, so scan into ints and copy into smaller types */
uuid->time_low = time_low;
uuid->time_mid = time_mid;
uuid->time_hi_and_version = time_hi_and_version;
uuid->clock_seq_hi_and_reserved = clock_seq_hi_and_reserved;
uuid->clock_seq_low = clock_seq_low;
for (i=0; i < 6; i++)
uuid->node[i] = node[i];
return (UUID_REP);
}
/* preserve coding style vim: set tw=78 sw=4 : */