%{ /* * * (c) Copyright 1989 OPEN SOFTWARE FOUNDATION, INC. * (c) Copyright 1989 HEWLETT-PACKARD COMPANY * (c) Copyright 1989 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. * */ /* ** 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 #include #include #include #include #include #include #include #include #include /* 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 extern YYSTYPE nidl_yylval; extern int nidl_yylineno; boolean search_attributes_table = false ; static int yywrap(void) { /* Free the Flex buffer, yy_curent_buffer and yy_delete_buffer() * are FLEX interfaces to the internal buffering system. */ #ifdef YY_CURRENT_BUFFER_LVALUE nidl_yy_delete_buffer(YY_CURRENT_BUFFER_LVALUE); #else nidl_yy_delete_buffer(yy_current_buffer); #endif nidl_yylineno = 1; return 1; } void commenteof ( #ifdef PROTO void #endif ); int yylex ( #ifdef PROTO void #endif ); int yylook ( #ifdef PROTO void #endif ); static void read_c_comment ( #ifdef PROTO void #endif ); static void yymark ( #ifdef PROTO void #endif ); static int yyuuid ( #ifdef PROTO char *s, nidl_uuid_t *uuid #endif ); static int yyolduuid ( #ifdef PROTO char *s, nidl_uuid_t *uuid #endif ); int KEYWORDS_screen ( #ifdef PROTO char *token, NAMETABLE_id_t *id #endif ); char *KEYWORDS_lookup_text ( #ifdef PROTO long token #endif ); int yyinput ( #ifdef PROTO void #endif ); int yyback ( #ifdef PROTO int *p, int m #endif ); %} /* 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 yylineno %% {ws} { /* No action, and no return */ } '\n' { /* GNU FLEX doesnt automatically track line #'s */ nidl_yylineno++; } ":" {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 { yymark() ;} ^"%"(c|C){ws}\n { log_error(nidl_yylineno-1, NIDL_USETRANS, NULL); } ^"%pascal"{ws}\n { log_error(nidl_yylineno-1, NIDL_USETRANS, NULL); } ^"%PASCAL"{ws}\n { log_error(nidl_yylineno-1, NIDL_USETRANS, NULL); } '\\'' { /* Simple escaped single quote character literal */ nidl_yylval.y_char = '\''; return(CHAR); } '[^'\n\\]' { /* Simple character constants */ nidl_yylval.y_char = yytext [1]; return(CHAR); } '\\[^'\n]*' { /* Character constants with an escape */ if ((yyleng > 6) || (yyleng < 4)) { log_error(nidl_yylineno, NIDL_INVCHARLIT, NULL); return(UNKNOWN); } switch (yytext[2]) { case 'n': nidl_yylval.y_char = '\n'; break; case 't': nidl_yylval.y_char = '\t'; break; case 'v': nidl_yylval.y_char = '\v'; break; case 'b': nidl_yylval.y_char = '\b'; break; case 'r': nidl_yylval.y_char = '\r'; break; case 'f': nidl_yylval.y_char = '\f'; break; case 'a': nidl_yylval.y_char = AUDIBLE_BELL; break; case '\\': nidl_yylval.y_char = '\\'; break; case '?': nidl_yylval.y_char = '\?'; break; case '\'': nidl_yylval.y_char = '\''; break; case '\"': nidl_yylval.y_char = '\"'; break; case 'x' : { /* Hex literal value */ int char_value; if (sscanf((char *)&yytext[3],"%x",&char_value) != 1) log_error(nidl_yylineno, NIDL_INVCHARLIT, NULL); else { nidl_yylval.y_char = (char )char_value; log_warning(nidl_yylineno, 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(nidl_yylineno, NIDL_INVCHARLIT, NULL); else { nidl_yylval.y_char = (char )char_value; log_warning(nidl_yylineno, NIDL_NONPORTCHAR, NULL); } break; } default: /* all others are illegal */ log_error(nidl_yylineno, NIDL_INVCHARLIT, NULL); return(UNKNOWN); } return (CHAR); } \"[^\"\n]* { char stripped_string[max_string_len] ATTRIBUTE_UNUSED; if (yytext[yyleng-1] == '\\') yymore(); /* Allow backslashed " within strings, look for next " */ else { nidl_yylval.y_string = STRTAB_add_string((char *)&yytext[1]); if (input() == '\n') log_error(nidl_yylineno, NIDL_STRUNTERM, NULL); return(STRING); } } "/*" { read_c_comment(); } "//".*\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) { NAMETABLE_id_t id; char const *identifier; id = NAMETABLE_add_id((char *)yytext); NAMETABLE_id_to_string(id, &identifier); log_warning(nidl_yylineno, 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) { nidl_yylval.y_id = id; } else { nidl_yylval.y_id = NAMETABLE_NIL_ID; } return token; } {integer} { int unsigned_int = false; #if defined(vax) && defined(ultrix) float fval; char *fval_fmt = "%f"; #define FLOAT float #else double fval; char *fval_fmt = "%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, fval_fmt, &fval); nidl_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(nidl_yylineno, 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(nidl_yylineno, NIDL_INTOVERFLOW, KEYWORDS_lookup_text(LONG_KW), NULL); else { sscanf((char *)yytext, "%ld", &nidl_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(nidl_yylineno, NIDL_INVOCTDIGIT, int_text, NULL); } /* remember the signed-ness */ nidl_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", &nidl_yylval.y_int_info.int_val); nidl_yylval.y_int_info.int_signed = !unsigned_int; return(INTEGER_NUMERIC); } {float} { nidl_yylval.y_float = STRTAB_add_string((char *)yytext); return(FLOAT_NUMERIC); } {uuid} { return (yyuuid((char *)&yytext[1], &nidl_yylval.y_uuid)); } {olduuid} { return (yyolduuid((char *)&yytext[1], &nidl_yylval.y_uuid)); } {other} { return (UNKNOWN); } %% void commenteof() { log_error (nidl_yylineno, NIDL_COMMENTEOF, NULL); nidl_terminate(); } static void yymark() { char *source ; /* Source file name in #line directive */ int prev_lineno = nidl_yylineno - 1; source = NEW_VEC (char, yyleng); source[0] ='\0'; /* If the format wasn't # line {int} {string}, then reparse without "line" identifier */ if (sscanf((char *)yytext, "# line %d %s", &nidl_yylineno, source) < 1) { if (sscanf((char *)yytext, "# %d %s", &nidl_yylineno, source) < 1) { log_warning(prev_lineno, NIDL_CPPCMDOPT, #ifdef VMS (CMD_DCL_interface) ? "/PREPROCESS" : #endif "-cpp_cmd", NULL); } } /* If text included a source file name, set name for error reporting. */ if (source[0] != '\0' && !(source[0] == '"' && source[1] == '"')) { char file_name[max_string_len]; /* Strip the quotes. */ strcpy(file_name, &source[1]); file_name[strlen(file_name)-1] = '\0'; set_name_for_errors(file_name); } FREE(source); } static void read_c_comment() { register int c; /* While not EOF look for end of comment */ while ((c = input())) { if (c == '*') { if ((c = input()) == '/') break ; else unput(c) ; } } /* Didn't find end comment before EOF, issue error */ if (c == 0) commenteof(); } static int yyolduuid(s, uuid) char *s; 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(s, "%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(nidl_yylineno, 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(nidl_yylineno, NIDL_OLDUUID, NULL); log_warning(nidl_yylineno, NIDL_NEWUUID, uuid_str, NULL); return (UUID_REP) ; } static int yyuuid(s, uuid) char *s; 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(s, "%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(nidl_yylineno, 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); } #ifdef FLEX_SCANNER /***************************************************************** * * Helper functions for managing multiple FLEX contexts * * GNU FLEX support for DCE 1.2.2 idl_compiler * added 07-11-97 Jim Doyle, Boston University, * * Maintainance note: * * The set of flex-specific static and global variables * managed by the following code may need to be changed * for versions of FLEX newer or later than v2.5.4. This * code was tested with Flex 2.4.6 and 2.5.4. V2.4 of FLEX * defined three static variables (yy_start_stack, * yy_start_stack_depth,yy_start_stack_ptr). In V2.5 of FLEX, * these three statics disappeared. Fortunately FLEX defined * macros YY_FLEX_MANOR_VERSION and YY_FLEX_MINOR_VERSION. * These are helpful for conditionally compiling in support for * several vintages of FLEX. * * *****************************************************************/ /***************************************************************** * * Data structure to store the state of a FLEX lexxer context * *****************************************************************/ struct nidl_flexxer_state_data { /* * flex statics - hidden from the outside world. These are * generated by flex. * * MAINTAINANCE NOTE: In versions later or earlier than 2.5.4, * the exact set of static variables that FLEX generates may be * different than is what is defined here. In that case, generate * the lexxer (i.e. flex nidl.l), grep the resulting generated C * flexxer for the word 'static'. You can then determine what * variables are new, dont exist, or have been renamed. Another * alternative for learning the names of all the static and global * variables used by the flexxer - is to compile the stub and * examine the object table dump (i.e using nm(1) on the .o file). * */ YY_BUFFER_STATE yy_current_buffer; char yy_hold_char; int yy_n_chars; char * yy_c_buf_p; int yy_init; int yy_start; int yy_did_buffer_switch_on_eof; #ifdef YY_USES_REJECT yy_state_type *yy_state_ptr; char *yy_full_match; int yy_lp; #else yy_state_type yy_last_accepting_state; char * yy_last_accepting_cpos; #endif int yy_more_flag; int yy_more_len; #if (YY_FLEX_MAJOR_VERSION == 2) && (YY_FLEX_MINOR_VERSION == 4) int yy_start_stack_ptr; int yy_start_stack_depth; int * yy_start_stack; #endif /* * flex globals - visible to the outside world * */ FILE * yyin; FILE * yyout; int yylineno; YYSTYPE yylval; int yyleng; char * yytext; }; typedef struct nidl_flexxer_state_data nidl_flexxer_activation_record; /***************************************************************** * * Basic constructors/destructors for FLEX activation states * *****************************************************************/ void * new_nidl_flexxer_activation_record() { return (malloc(sizeof(nidl_flexxer_activation_record))); } void delete_nidl_flexxer_activation_record(void * p) { if (p) { /* Note: Never call nidl_yy_free_buffer(yy_current_buffer) * from here to delete the Flex internal buffer context. * you will get a hard to diagnose bug. Instead, nidl_yywrap() * should call the delete function for the buffer. I know, * it is tempting to put all the 'destructors' in one place, * however, this is NOT a good place to do it. * jrd@bu.edu 07-12-97 04:30 */ free((void *)p); } } /***************************************************************** * * Get/Set/Initialize methods * *****************************************************************/ void * get_current_nidl_flexxer_activation() { nidl_flexxer_activation_record * p; p = (nidl_flexxer_activation_record * ) new_nidl_flexxer_activation_record(); /* * save the statics internal to the flexxer * */ #ifdef YY_CURRENT_BUFFER_LVALUE yyensure_buffer_stack(); p->yy_current_buffer = YY_CURRENT_BUFFER_LVALUE; #else p->yy_current_buffer = yy_current_buffer; #endif /* YY_CURRENT_BUFFER_LVALUE */ p->yy_hold_char = yy_hold_char; p->yy_n_chars = yy_n_chars; p->yy_c_buf_p = yy_c_buf_p; p->yy_init = yy_init; p->yy_start = yy_start; p->yy_did_buffer_switch_on_eof = yy_did_buffer_switch_on_eof; #ifdef YY_USES_REJECT p->yy_state_ptr = yy_state_ptr; p->yy_full_match = yy_full_match; p->yy_lp = yy_lp; #else p->yy_last_accepting_state = yy_last_accepting_state; p->yy_last_accepting_cpos = yy_last_accepting_cpos; #endif p->yy_more_flag = yy_more_flag; p->yy_more_len = yy_more_len; /* FLEX 2.5 does not have these variables. * FLEX 2.4 does have them though... */ #if (YY_FLEX_MAJOR_VERSION == 2) && (YY_FLEX_MINOR_VERSION == 4) p->yy_start_stack_ptr = yy_start_stack_ptr; p->yy_start_stack_depth = yy_start_stack_depth; p->yy_start_stack = yy_start_stack; #endif /* * save the globals, these are visible outside the scope * of the lexxer * */ p->yyin = nidl_yyin; p->yyout = nidl_yyout; p->yylineno = nidl_yylineno; p->yylval = nidl_yylval; p->yyleng = nidl_yyleng; p->yytext = nidl_yytext; return (void *)p; } void set_current_nidl_flexxer_activation(void * ptr) { nidl_flexxer_activation_record * p = (nidl_flexxer_activation_record *)ptr; /* restore the statics */ #ifdef YY_CURRENT_BUFFER_LVALUE YY_CURRENT_BUFFER_LVALUE = p->yy_current_buffer; #else yy_current_buffer = p->yy_current_buffer; #endif /* YY_CURRENT_BUFFER_LVALUE */ yy_hold_char = p->yy_hold_char; yy_n_chars = p->yy_n_chars; yy_c_buf_p = p->yy_c_buf_p; yy_init = p->yy_init; yy_start = p->yy_start; yy_did_buffer_switch_on_eof = p->yy_did_buffer_switch_on_eof; #ifdef YY_USES_REJECT yy_state_ptr = p->yy_state_ptr; yy_full_match = p->yy_full_match; yy_lp = p->yy_lp; #else yy_last_accepting_state = p->yy_last_accepting_state; yy_last_accepting_cpos = p->yy_last_accepting_cpos; #endif yy_more_flag = p->yy_more_flag; yy_more_len = p->yy_more_len; /* FLEX 2.5 does not have these variables. * FLEX 2.4 does have them though... */ #if (YY_FLEX_MAJOR_VERSION == 2) && (YY_FLEX_MINOR_VERSION == 4) yy_start_stack_ptr = p->yy_start_stack_ptr; yy_start_stack_depth = p->yy_start_stack_depth; yy_start_stack = p->yy_start_stack; #endif /* * save the globals, these are visible outside the scope * of the lexxer * */ nidl_yyin = p->yyin; nidl_yyout = p->yyout; nidl_yylineno = p->yylineno; nidl_yylval = p->yylval; nidl_yyleng = p->yyleng; nidl_yytext = p->yytext; } void init_new_nidl_flexxer_activation(void) { /* * set some initial conditions for a new FLEXER state * These were gleaned by looking at the compile-time * initializations in the generated nidl_lex_yy.c file. * */ #ifdef YY_CURRENT_BUFFER_LVALUE yyensure_buffer_stack(); YY_CURRENT_BUFFER_LVALUE = 0; #else yy_current_buffer = 0; #endif /* YY_CURRENT_BUFFER_LVALUE */ yy_c_buf_p = (char *) 0; yy_init = 1; yy_start = 0; yy_more_flag = 0; yy_more_len = 0; /* FLEX 2.5 does not have these variables. * FLEX 2.4 does have them though... */ #if (YY_FLEX_MAJOR_VERSION == 2) && (YY_FLEX_MINOR_VERSION == 4) yy_start_stack_ptr = 0; yy_start_stack_depth = 0; yy_start_stack = 0; #endif /* * Set the globals to reasonable states */ nidl_yyin = NULL; nidl_yyout = NULL; nidl_yylineno = 1; nidl_yyleng = 0; } #endif /* FLEX_SCANNER */ /* preserve coding style vim: set tw=78 sw=4 : */