1*0Sstevel@tonic-gate %{ 2*0Sstevel@tonic-gate /* 3*0Sstevel@tonic-gate * CDDL HEADER START 4*0Sstevel@tonic-gate * 5*0Sstevel@tonic-gate * The contents of this file are subject to the terms of the 6*0Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 7*0Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 8*0Sstevel@tonic-gate * with the License. 9*0Sstevel@tonic-gate * 10*0Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 11*0Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 12*0Sstevel@tonic-gate * See the License for the specific language governing permissions 13*0Sstevel@tonic-gate * and limitations under the License. 14*0Sstevel@tonic-gate * 15*0Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 16*0Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 17*0Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 18*0Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 19*0Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 20*0Sstevel@tonic-gate * 21*0Sstevel@tonic-gate * CDDL HEADER END 22*0Sstevel@tonic-gate * 23*0Sstevel@tonic-gate * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24*0Sstevel@tonic-gate * Use is subject to license terms. 25*0Sstevel@tonic-gate */ 26*0Sstevel@tonic-gate 27*0Sstevel@tonic-gate /* Copyright (c) 1988 AT&T */ 28*0Sstevel@tonic-gate /* All Rights Reserved */ 29*0Sstevel@tonic-gate 30*0Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 31*0Sstevel@tonic-gate 32*0Sstevel@tonic-gate /* 33*0Sstevel@tonic-gate * cscope - interactive C symbol cross-reference 34*0Sstevel@tonic-gate * 35*0Sstevel@tonic-gate * 36*0Sstevel@tonic-gate * C symbol scanner 37*0Sstevel@tonic-gate */ 38*0Sstevel@tonic-gate #ident "@(#)scanner.l 1.2 93/06/07 SMI" 39*0Sstevel@tonic-gate #include "global.h" 40*0Sstevel@tonic-gate 41*0Sstevel@tonic-gate /* the line counting has been moved from character reading for speed */ 42*0Sstevel@tonic-gate /* comments are discarded */ 43*0Sstevel@tonic-gate #undef input 44*0Sstevel@tonic-gate #define input() \ 45*0Sstevel@tonic-gate ((yytchar = (yytchar = yysptr > yysbuf ? \ 46*0Sstevel@tonic-gate *--yysptr : getc(yyin)) == '/' ? comment() : yytchar) == \ 47*0Sstevel@tonic-gate EOF ? 0 : toascii(yytchar)) 48*0Sstevel@tonic-gate #define noncommentinput() \ 49*0Sstevel@tonic-gate ((yytchar = yysptr > yysbuf ? *--yysptr : getc(yyin)) == \ 50*0Sstevel@tonic-gate EOF ? 0 : yytchar) 51*0Sstevel@tonic-gate #undef unput 52*0Sstevel@tonic-gate #define unput(c) (*yysptr++ = (c)) 53*0Sstevel@tonic-gate 54*0Sstevel@tonic-gate /* not a preprocessor line (allow Ingres(TM) "## char var;" lines) */ 55*0Sstevel@tonic-gate #define notpp() (ppdefine == NO && (*yytext != '#' || yytext[1] == '#')) 56*0Sstevel@tonic-gate 57*0Sstevel@tonic-gate #define IFLEVELINC 5 /* #if nesting level size increment */ 58*0Sstevel@tonic-gate 59*0Sstevel@tonic-gate /* keyword text for fast testing of keywords in the scanner */ 60*0Sstevel@tonic-gate extern char externtext[]; 61*0Sstevel@tonic-gate extern char typedeftext[]; 62*0Sstevel@tonic-gate 63*0Sstevel@tonic-gate int first; /* buffer index for first char of symbol */ 64*0Sstevel@tonic-gate int last; /* buffer index for last char of symbol */ 65*0Sstevel@tonic-gate int lineno; /* symbol line number */ 66*0Sstevel@tonic-gate 67*0Sstevel@tonic-gate static BOOL arraydimension; /* inside array dimension declaration */ 68*0Sstevel@tonic-gate static BOOL bplisting; /* breakpoint listing */ 69*0Sstevel@tonic-gate static int braces; /* unmatched left brace count */ 70*0Sstevel@tonic-gate static int cesudeftoken; /* class/enum/struct/union definition */ 71*0Sstevel@tonic-gate static BOOL classdef; /* c++ class definition */ 72*0Sstevel@tonic-gate static BOOL elseelif; /* #else or #elif found */ 73*0Sstevel@tonic-gate static BOOL esudef; /* enum/struct/union definition */ 74*0Sstevel@tonic-gate static int esubraces; /* outermost enum/struct/union */ 75*0Sstevel@tonic-gate /* brace count */ 76*0Sstevel@tonic-gate static BOOL externdec; /* extern declaration */ 77*0Sstevel@tonic-gate static BOOL fcndef; /* function definition */ 78*0Sstevel@tonic-gate static BOOL globalscope; /* file global scope */ 79*0Sstevel@tonic-gate /* (outside functions) */ 80*0Sstevel@tonic-gate static int iflevel; /* #if nesting level */ 81*0Sstevel@tonic-gate static BOOL initializer; /* data initializer */ 82*0Sstevel@tonic-gate static int initializerbraces; /* data initializer outer brace count */ 83*0Sstevel@tonic-gate static BOOL lex; /* lex file */ 84*0Sstevel@tonic-gate static BOOL localdef; /* function/block local definition */ 85*0Sstevel@tonic-gate static int miflevel = IFLEVELINC; /* maximum #if nesting level */ 86*0Sstevel@tonic-gate static int *maxifbraces; /* maximum brace count within #if */ 87*0Sstevel@tonic-gate static int *preifbraces; /* brace count before #if */ 88*0Sstevel@tonic-gate static int parens; /* unmatched left parenthesis count */ 89*0Sstevel@tonic-gate static BOOL ppdefine; /* preprocessor define statement */ 90*0Sstevel@tonic-gate static BOOL psuedoelif; /* psuedo-#elif */ 91*0Sstevel@tonic-gate static BOOL oldtype; /* next identifier is an old type */ 92*0Sstevel@tonic-gate static BOOL rules; /* lex/yacc rules */ 93*0Sstevel@tonic-gate static BOOL sdl; /* SDL file */ 94*0Sstevel@tonic-gate static BOOL structfield; /* structure field declaration */ 95*0Sstevel@tonic-gate static BOOL template; /* function template */ 96*0Sstevel@tonic-gate static int templateparens; /* function template outer parentheses count */ 97*0Sstevel@tonic-gate static BOOL typedefdef; /* typedef name definition */ 98*0Sstevel@tonic-gate static BOOL typedefname; /* typedef name use */ 99*0Sstevel@tonic-gate static int token; /* token found */ 100*0Sstevel@tonic-gate 101*0Sstevel@tonic-gate static BOOL asy; /* assembly file */ 102*0Sstevel@tonic-gate 103*0Sstevel@tonic-gate void multicharconstant(char terminator); 104*0Sstevel@tonic-gate int do_assembly(int token); 105*0Sstevel@tonic-gate %} 106*0Sstevel@tonic-gate identifier [a-zA-Z_][a-zA-Z_0-9]* 107*0Sstevel@tonic-gate number \.?[0-9][.0-9a-fA-FlLuUxX]* 108*0Sstevel@tonic-gate %start SDL 109*0Sstevel@tonic-gate %a 6000 110*0Sstevel@tonic-gate %o 11000 111*0Sstevel@tonic-gate %p 3000 112*0Sstevel@tonic-gate %% 113*0Sstevel@tonic-gate %\{ { /* lex/yacc C declarations/definitions */ 114*0Sstevel@tonic-gate globalscope = YES; 115*0Sstevel@tonic-gate goto more; 116*0Sstevel@tonic-gate /* NOTREACHED */ 117*0Sstevel@tonic-gate } 118*0Sstevel@tonic-gate %\} { 119*0Sstevel@tonic-gate globalscope = NO; 120*0Sstevel@tonic-gate goto more; 121*0Sstevel@tonic-gate /* NOTREACHED */ 122*0Sstevel@tonic-gate } 123*0Sstevel@tonic-gate ^%% { /* lex/yacc rules delimiter */ 124*0Sstevel@tonic-gate braces = 0; 125*0Sstevel@tonic-gate if (rules == NO) { 126*0Sstevel@tonic-gate rules = YES; 127*0Sstevel@tonic-gate 128*0Sstevel@tonic-gate /* simulate a yylex() or yyparse() definition */ 129*0Sstevel@tonic-gate (void) strcat(yytext, " /* "); 130*0Sstevel@tonic-gate first = strlen(yytext); 131*0Sstevel@tonic-gate if (lex == YES) { 132*0Sstevel@tonic-gate (void) strcat(yytext, "yylex"); 133*0Sstevel@tonic-gate } else { 134*0Sstevel@tonic-gate /* 135*0Sstevel@tonic-gate * yacc: yyparse implicitly calls yylex 136*0Sstevel@tonic-gate */ 137*0Sstevel@tonic-gate char *s = " yylex()"; 138*0Sstevel@tonic-gate char *cp = s + strlen(s); 139*0Sstevel@tonic-gate while (--cp >= s) { 140*0Sstevel@tonic-gate unput(*cp); 141*0Sstevel@tonic-gate } 142*0Sstevel@tonic-gate (void) strcat(yytext, "yyparse"); 143*0Sstevel@tonic-gate } 144*0Sstevel@tonic-gate last = strlen(yytext); 145*0Sstevel@tonic-gate (void) strcat(yytext, " */"); 146*0Sstevel@tonic-gate yyleng = strlen(yytext); 147*0Sstevel@tonic-gate yymore(); 148*0Sstevel@tonic-gate return (FCNDEF); 149*0Sstevel@tonic-gate } else { 150*0Sstevel@tonic-gate rules = NO; 151*0Sstevel@tonic-gate globalscope = YES; 152*0Sstevel@tonic-gate last = first; 153*0Sstevel@tonic-gate yymore(); 154*0Sstevel@tonic-gate return (FCNEND); 155*0Sstevel@tonic-gate } 156*0Sstevel@tonic-gate /* NOTREACHED */ 157*0Sstevel@tonic-gate } 158*0Sstevel@tonic-gate <SDL>(PROCEDURE|STATE)[ \t]+({identifier}|\*) { /* SDL procedure or state */ 159*0Sstevel@tonic-gate braces = 1; 160*0Sstevel@tonic-gate fcndef = YES; /* treat as function definition */ 161*0Sstevel@tonic-gate token = FCNDEF; 162*0Sstevel@tonic-gate globalscope = NO; 163*0Sstevel@tonic-gate goto findident; 164*0Sstevel@tonic-gate /* NOTREACHED */ 165*0Sstevel@tonic-gate } 166*0Sstevel@tonic-gate <SDL>(CALL|NEXTSTATE)[ \t]+({identifier}|\*) { /* SDL call or nextstate */ 167*0Sstevel@tonic-gate token = FCNCALL; 168*0Sstevel@tonic-gate goto findident; /* treat as function call */ 169*0Sstevel@tonic-gate /* NOTREACHED */ 170*0Sstevel@tonic-gate } 171*0Sstevel@tonic-gate <SDL>END(PROCEDURE|STATE)[ \t]+({identifier}|\*) { 172*0Sstevel@tonic-gate /* end of an SDL procedure or state */ 173*0Sstevel@tonic-gate goto endstate; /* treat as the end of a function */ 174*0Sstevel@tonic-gate /* NOTREACHED */ 175*0Sstevel@tonic-gate } 176*0Sstevel@tonic-gate \{ { 177*0Sstevel@tonic-gate /* count unmatched left braces for fcn def detection */ 178*0Sstevel@tonic-gate ++braces; 179*0Sstevel@tonic-gate 180*0Sstevel@tonic-gate /* 181*0Sstevel@tonic-gate * mark an untagged enum/struct/union so its beginning 182*0Sstevel@tonic-gate * can be found 183*0Sstevel@tonic-gate */ 184*0Sstevel@tonic-gate if (cesudeftoken) { 185*0Sstevel@tonic-gate last = first; 186*0Sstevel@tonic-gate savesymbol(cesudeftoken); 187*0Sstevel@tonic-gate cesudeftoken = '\0'; 188*0Sstevel@tonic-gate } 189*0Sstevel@tonic-gate goto more; 190*0Sstevel@tonic-gate /* NOTREACHED */ 191*0Sstevel@tonic-gate } 192*0Sstevel@tonic-gate \#[ \t]*endif/.*[\n\r][ \t\n\r]*#[ \t]*if { 193*0Sstevel@tonic-gate /* 194*0Sstevel@tonic-gate * attempt to correct erroneous brace count caused by: 195*0Sstevel@tonic-gate * 196*0Sstevel@tonic-gate * #if ... 197*0Sstevel@tonic-gate * ... { 198*0Sstevel@tonic-gate * #endif 199*0Sstevel@tonic-gate * #if ... 200*0Sstevel@tonic-gate * ... { 201*0Sstevel@tonic-gate * #endif 202*0Sstevel@tonic-gate */ 203*0Sstevel@tonic-gate /* the current #if must not have an #else or #elif */ 204*0Sstevel@tonic-gate if (elseelif == YES) { 205*0Sstevel@tonic-gate goto endif; 206*0Sstevel@tonic-gate } 207*0Sstevel@tonic-gate psuedoelif = YES; 208*0Sstevel@tonic-gate goto more; 209*0Sstevel@tonic-gate /* NOTREACHED */ 210*0Sstevel@tonic-gate } 211*0Sstevel@tonic-gate \#[ \t]*ifn?(def)? { /* #if, #ifdef or #ifndef */ 212*0Sstevel@tonic-gate elseelif = NO; 213*0Sstevel@tonic-gate if (psuedoelif == YES) { 214*0Sstevel@tonic-gate psuedoelif = NO; 215*0Sstevel@tonic-gate goto elif; 216*0Sstevel@tonic-gate } 217*0Sstevel@tonic-gate /* 218*0Sstevel@tonic-gate * make sure there is room for the current brace count 219*0Sstevel@tonic-gate */ 220*0Sstevel@tonic-gate if (iflevel == miflevel) { 221*0Sstevel@tonic-gate miflevel += IFLEVELINC; 222*0Sstevel@tonic-gate maxifbraces = myrealloc(maxifbraces, 223*0Sstevel@tonic-gate miflevel * sizeof (int)); 224*0Sstevel@tonic-gate preifbraces = myrealloc(preifbraces, 225*0Sstevel@tonic-gate miflevel * sizeof (int)); 226*0Sstevel@tonic-gate } 227*0Sstevel@tonic-gate /* push the current brace count */ 228*0Sstevel@tonic-gate preifbraces[iflevel] = braces; 229*0Sstevel@tonic-gate maxifbraces[iflevel++] = 0; 230*0Sstevel@tonic-gate goto more; 231*0Sstevel@tonic-gate /* NOTREACHED */ 232*0Sstevel@tonic-gate } 233*0Sstevel@tonic-gate \#[ \t]*el(se|if) { /* #elif or #else */ 234*0Sstevel@tonic-gate elseelif = YES; 235*0Sstevel@tonic-gate elif: 236*0Sstevel@tonic-gate if (iflevel > 0) { 237*0Sstevel@tonic-gate 238*0Sstevel@tonic-gate /* save the maximum brace count for this #if */ 239*0Sstevel@tonic-gate if (braces > maxifbraces[iflevel]) { 240*0Sstevel@tonic-gate maxifbraces[iflevel - 1] = braces; 241*0Sstevel@tonic-gate } 242*0Sstevel@tonic-gate /* restore the brace count to before the #if */ 243*0Sstevel@tonic-gate braces = preifbraces[iflevel - 1]; 244*0Sstevel@tonic-gate } 245*0Sstevel@tonic-gate goto more; 246*0Sstevel@tonic-gate /* NOTREACHED */ 247*0Sstevel@tonic-gate } 248*0Sstevel@tonic-gate \#[ \t]*endif { /* #endif */ 249*0Sstevel@tonic-gate endif: 250*0Sstevel@tonic-gate if (iflevel > 0) { 251*0Sstevel@tonic-gate 252*0Sstevel@tonic-gate /* get the maximum brace count for this #if */ 253*0Sstevel@tonic-gate if (braces < maxifbraces[--iflevel]) { 254*0Sstevel@tonic-gate braces = maxifbraces[iflevel]; 255*0Sstevel@tonic-gate } 256*0Sstevel@tonic-gate } 257*0Sstevel@tonic-gate goto more; 258*0Sstevel@tonic-gate /* NOTREACHED */ 259*0Sstevel@tonic-gate } 260*0Sstevel@tonic-gate \} { 261*0Sstevel@tonic-gate /* could be the last enum member initializer */ 262*0Sstevel@tonic-gate if (braces == initializerbraces) { 263*0Sstevel@tonic-gate initializerbraces = -1; 264*0Sstevel@tonic-gate initializer = NO; 265*0Sstevel@tonic-gate } 266*0Sstevel@tonic-gate if (--braces <= 0) { 267*0Sstevel@tonic-gate endstate: 268*0Sstevel@tonic-gate braces = 0; 269*0Sstevel@tonic-gate classdef = NO; 270*0Sstevel@tonic-gate } 271*0Sstevel@tonic-gate /* 272*0Sstevel@tonic-gate * if the end of an outermost enum/struct/union 273*0Sstevel@tonic-gate * definition 274*0Sstevel@tonic-gate */ 275*0Sstevel@tonic-gate if (esudef == YES && braces == esubraces) { 276*0Sstevel@tonic-gate esudef = NO; 277*0Sstevel@tonic-gate esubraces = -1; 278*0Sstevel@tonic-gate last = first; 279*0Sstevel@tonic-gate yymore(); 280*0Sstevel@tonic-gate return (ESUEND); 281*0Sstevel@tonic-gate } 282*0Sstevel@tonic-gate /* if the end of a function */ 283*0Sstevel@tonic-gate if ((braces == 0 || braces == 1 && classdef == YES) && 284*0Sstevel@tonic-gate fcndef == YES) { 285*0Sstevel@tonic-gate fcndef = NO; 286*0Sstevel@tonic-gate globalscope = YES; 287*0Sstevel@tonic-gate last = first; 288*0Sstevel@tonic-gate yymore(); 289*0Sstevel@tonic-gate return (FCNEND); 290*0Sstevel@tonic-gate } 291*0Sstevel@tonic-gate goto more; 292*0Sstevel@tonic-gate /* NOTREACHED */ 293*0Sstevel@tonic-gate } 294*0Sstevel@tonic-gate \( { 295*0Sstevel@tonic-gate /* 296*0Sstevel@tonic-gate * count unmatched left parentheses for function 297*0Sstevel@tonic-gate * templates 298*0Sstevel@tonic-gate */ 299*0Sstevel@tonic-gate ++parens; 300*0Sstevel@tonic-gate goto more; 301*0Sstevel@tonic-gate /* NOTREACHED */ 302*0Sstevel@tonic-gate } 303*0Sstevel@tonic-gate \) { 304*0Sstevel@tonic-gate if (--parens <= 0) { 305*0Sstevel@tonic-gate parens = 0; 306*0Sstevel@tonic-gate } 307*0Sstevel@tonic-gate /* if the end of a function template */ 308*0Sstevel@tonic-gate if (parens == templateparens) { 309*0Sstevel@tonic-gate templateparens = -1; 310*0Sstevel@tonic-gate template = NO; 311*0Sstevel@tonic-gate } 312*0Sstevel@tonic-gate goto more; 313*0Sstevel@tonic-gate /* NOTREACHED */ 314*0Sstevel@tonic-gate } 315*0Sstevel@tonic-gate = { /* if a global definition initializer */ 316*0Sstevel@tonic-gate if ((globalscope == YES || localdef == YES) && 317*0Sstevel@tonic-gate notpp()) { 318*0Sstevel@tonic-gate initializerbraces = braces; 319*0Sstevel@tonic-gate initializer = YES; 320*0Sstevel@tonic-gate } 321*0Sstevel@tonic-gate goto more; 322*0Sstevel@tonic-gate /* NOTREACHED */ 323*0Sstevel@tonic-gate } 324*0Sstevel@tonic-gate : { /* if a structure field */ 325*0Sstevel@tonic-gate /* note: a pr header has a colon in the date */ 326*0Sstevel@tonic-gate if (esudef == YES && notpp()) { 327*0Sstevel@tonic-gate structfield = YES; 328*0Sstevel@tonic-gate } 329*0Sstevel@tonic-gate goto more; 330*0Sstevel@tonic-gate /* NOTREACHED */ 331*0Sstevel@tonic-gate } 332*0Sstevel@tonic-gate \, { 333*0Sstevel@tonic-gate if (braces == initializerbraces) { 334*0Sstevel@tonic-gate initializerbraces = -1; 335*0Sstevel@tonic-gate initializer = NO; 336*0Sstevel@tonic-gate } 337*0Sstevel@tonic-gate structfield = NO; 338*0Sstevel@tonic-gate goto more; 339*0Sstevel@tonic-gate /* NOTREACHED */ 340*0Sstevel@tonic-gate } 341*0Sstevel@tonic-gate "##" | /* start of Ingres(TM) code line */ 342*0Sstevel@tonic-gate ; { 343*0Sstevel@tonic-gate /* if not in an enum/struct/union declaration */ 344*0Sstevel@tonic-gate if (esudef == NO) { 345*0Sstevel@tonic-gate externdec = NO; 346*0Sstevel@tonic-gate typedefdef = NO; 347*0Sstevel@tonic-gate localdef = NO; 348*0Sstevel@tonic-gate } 349*0Sstevel@tonic-gate structfield = NO; 350*0Sstevel@tonic-gate initializer = NO; 351*0Sstevel@tonic-gate oldtype = NO; 352*0Sstevel@tonic-gate goto more; 353*0Sstevel@tonic-gate /* NOTREACHED */ 354*0Sstevel@tonic-gate } 355*0Sstevel@tonic-gate \#[ \t]*define[ \t]+{identifier} { 356*0Sstevel@tonic-gate 357*0Sstevel@tonic-gate /* preprocessor macro or constant definition */ 358*0Sstevel@tonic-gate ppdefine = YES; 359*0Sstevel@tonic-gate token = DEFINE; 360*0Sstevel@tonic-gate if (compress == YES) { 361*0Sstevel@tonic-gate /* compress the keyword */ 362*0Sstevel@tonic-gate yytext[0] = '\7'; 363*0Sstevel@tonic-gate } 364*0Sstevel@tonic-gate findident: 365*0Sstevel@tonic-gate first = yyleng - 1; 366*0Sstevel@tonic-gate while (isalnum(yytext[first]) || yytext[first] == '_') { 367*0Sstevel@tonic-gate --first; 368*0Sstevel@tonic-gate } 369*0Sstevel@tonic-gate ++first; 370*0Sstevel@tonic-gate goto iflongline; 371*0Sstevel@tonic-gate /* NOTREACHED */ 372*0Sstevel@tonic-gate } 373*0Sstevel@tonic-gate class[ \t]+{identifier}[ \t\n\ra-zA-Z0-9_():]*\{ { 374*0Sstevel@tonic-gate /* class definition */ 375*0Sstevel@tonic-gate classdef = YES; 376*0Sstevel@tonic-gate cesudeftoken = 'c'; 377*0Sstevel@tonic-gate REJECT; 378*0Sstevel@tonic-gate /* NOTREACHED */ 379*0Sstevel@tonic-gate } 380*0Sstevel@tonic-gate (enum|struct|union)/([ \t\n\r]+{identifier})?[ \t\n\r]*\{ { 381*0Sstevel@tonic-gate /* enum/struct/union definition */ 382*0Sstevel@tonic-gate esudef = YES; 383*0Sstevel@tonic-gate if (esubraces < 0) { 384*0Sstevel@tonic-gate /* if outermost enum/struct/union */ 385*0Sstevel@tonic-gate esubraces = braces; 386*0Sstevel@tonic-gate } 387*0Sstevel@tonic-gate cesudeftoken = *(yytext + first); 388*0Sstevel@tonic-gate goto iflongline; 389*0Sstevel@tonic-gate /* NOTREACHED */ 390*0Sstevel@tonic-gate } 391*0Sstevel@tonic-gate {identifier}/[ \t]*\(([ \t\n\ra-zA-Z0-9_*&[\]=,.]*|\([ \ta-zA-Z0-9_*[\],]*\))*\)[ \t\n\r()]*[:a-zA-Z_#{] { 392*0Sstevel@tonic-gate 393*0Sstevel@tonic-gate /* 394*0Sstevel@tonic-gate * warning: "if (...)" must not overflow yytext, so 395*0Sstevel@tonic-gate * the content of function argument definitions is 396*0Sstevel@tonic-gate * restricted, in particular parentheses are 397*0Sstevel@tonic-gate * not allowed 398*0Sstevel@tonic-gate */ 399*0Sstevel@tonic-gate 400*0Sstevel@tonic-gate if (asy) { 401*0Sstevel@tonic-gate /* 402*0Sstevel@tonic-gate * In assembly files, if it looks like 403*0Sstevel@tonic-gate * a definition, pass it down as one and we'll 404*0Sstevel@tonic-gate * take care of it later. 405*0Sstevel@tonic-gate */ 406*0Sstevel@tonic-gate token = FCNDEF; 407*0Sstevel@tonic-gate goto iflongline; 408*0Sstevel@tonic-gate } 409*0Sstevel@tonic-gate 410*0Sstevel@tonic-gate /* if a function definition */ 411*0Sstevel@tonic-gate /* 412*0Sstevel@tonic-gate * note: "#define a (b) {" and "#if defined(a)\n#" 413*0Sstevel@tonic-gate * are not 414*0Sstevel@tonic-gate */ 415*0Sstevel@tonic-gate if (braces == 0 && notpp() && rules == NO || 416*0Sstevel@tonic-gate braces == 1 && classdef == YES) { 417*0Sstevel@tonic-gate fcndef = YES; 418*0Sstevel@tonic-gate token = FCNDEF; 419*0Sstevel@tonic-gate globalscope = NO; 420*0Sstevel@tonic-gate goto iflongline; 421*0Sstevel@tonic-gate } 422*0Sstevel@tonic-gate goto iffcncall; 423*0Sstevel@tonic-gate /* NOTREACHED */ 424*0Sstevel@tonic-gate } 425*0Sstevel@tonic-gate {identifier}/[ \t]*\( { 426*0Sstevel@tonic-gate if (asy) { 427*0Sstevel@tonic-gate /* 428*0Sstevel@tonic-gate * Macro calls can get here if they have 429*0Sstevel@tonic-gate * arguments which contain %'s (i.e., 430*0Sstevel@tonic-gate * registers). 431*0Sstevel@tonic-gate */ 432*0Sstevel@tonic-gate token = FCNDEF; 433*0Sstevel@tonic-gate goto iflongline; 434*0Sstevel@tonic-gate } 435*0Sstevel@tonic-gate 436*0Sstevel@tonic-gate /* if a function call */ 437*0Sstevel@tonic-gate iffcncall: 438*0Sstevel@tonic-gate if ((fcndef == YES || ppdefine == YES || 439*0Sstevel@tonic-gate rules == YES) && externdec == NO && 440*0Sstevel@tonic-gate (localdef == NO || initializer == YES)) { 441*0Sstevel@tonic-gate token = FCNCALL; 442*0Sstevel@tonic-gate goto iflongline; 443*0Sstevel@tonic-gate } 444*0Sstevel@tonic-gate if (template == NO && typedefdef == NO) { 445*0Sstevel@tonic-gate templateparens = parens; 446*0Sstevel@tonic-gate template = YES; 447*0Sstevel@tonic-gate } 448*0Sstevel@tonic-gate token = IDENT; 449*0Sstevel@tonic-gate goto iflongline; 450*0Sstevel@tonic-gate /* NOTREACHED */ 451*0Sstevel@tonic-gate } 452*0Sstevel@tonic-gate (\+\+|--)[ \t]*{identifier} { /* prefix increment or decrement */ 453*0Sstevel@tonic-gate token = ASSIGNMENT; 454*0Sstevel@tonic-gate goto findident; 455*0Sstevel@tonic-gate /* NOTREACHED */ 456*0Sstevel@tonic-gate } 457*0Sstevel@tonic-gate {identifier}/[ \t]*(\+\+|--) { /* postfix increment or decrement */ 458*0Sstevel@tonic-gate token = ASSIGNMENT; 459*0Sstevel@tonic-gate goto iflongline; 460*0Sstevel@tonic-gate /* NOTREACHED */ 461*0Sstevel@tonic-gate } 462*0Sstevel@tonic-gate \*[ \t]*{identifier}/[ \t]*[^a-zA-Z0-9_(+-][^+-] { 463*0Sstevel@tonic-gate /* indirect assignment or dcl */ 464*0Sstevel@tonic-gate while (!isalnum(yytext[first]) && 465*0Sstevel@tonic-gate yytext[first] != '_') { 466*0Sstevel@tonic-gate ++first; 467*0Sstevel@tonic-gate } 468*0Sstevel@tonic-gate goto ident; 469*0Sstevel@tonic-gate /* NOTREACHED */ 470*0Sstevel@tonic-gate } 471*0Sstevel@tonic-gate {identifier}/[ \t\n\r]*(=[^=]|[-+*/%&^|]=|<<=|>>=) { /* assignment */ 472*0Sstevel@tonic-gate if ((fcndef == YES || ppdefine == YES || 473*0Sstevel@tonic-gate rules == YES) && localdef == NO) { 474*0Sstevel@tonic-gate token = ASSIGNMENT; 475*0Sstevel@tonic-gate goto iflongline; 476*0Sstevel@tonic-gate } 477*0Sstevel@tonic-gate goto ident; 478*0Sstevel@tonic-gate /* NOTREACHED */ 479*0Sstevel@tonic-gate } 480*0Sstevel@tonic-gate {identifier}/[* \t\n\r]+[a-zA-Z0-9_] { /* possible typedef name use */ 481*0Sstevel@tonic-gate if (notpp() && esudef == NO && fcndef == YES && 482*0Sstevel@tonic-gate typedefdef == NO && parens == 0) { 483*0Sstevel@tonic-gate char c, *s = yytext + first - 1; 484*0Sstevel@tonic-gate 485*0Sstevel@tonic-gate while (--s >= yytext && (c = *s) != ';' && 486*0Sstevel@tonic-gate c != '{') { 487*0Sstevel@tonic-gate if (!isspace(c) && !isalpha(c)) { 488*0Sstevel@tonic-gate goto nottypedefname; 489*0Sstevel@tonic-gate } 490*0Sstevel@tonic-gate } 491*0Sstevel@tonic-gate typedefname = YES; 492*0Sstevel@tonic-gate } 493*0Sstevel@tonic-gate nottypedefname: 494*0Sstevel@tonic-gate /* skip the global/parameter/local tests */ 495*0Sstevel@tonic-gate token = IDENT; 496*0Sstevel@tonic-gate goto iflongline; 497*0Sstevel@tonic-gate /* NOTREACHED */ 498*0Sstevel@tonic-gate } 499*0Sstevel@tonic-gate {identifier} { 500*0Sstevel@tonic-gate struct keystruct *p; 501*0Sstevel@tonic-gate char *s; 502*0Sstevel@tonic-gate 503*0Sstevel@tonic-gate ident: token = IDENT; 504*0Sstevel@tonic-gate if (notpp() && externdec == NO && 505*0Sstevel@tonic-gate arraydimension == NO && initializer == NO) { 506*0Sstevel@tonic-gate 507*0Sstevel@tonic-gate /* if an enum/struct/union member definition */ 508*0Sstevel@tonic-gate if (esudef == YES) { 509*0Sstevel@tonic-gate if (structfield == NO) { 510*0Sstevel@tonic-gate token = MEMBERDEF; 511*0Sstevel@tonic-gate } 512*0Sstevel@tonic-gate } else if (typedefdef == YES && oldtype == NO) { 513*0Sstevel@tonic-gate /* if a typedef name */ 514*0Sstevel@tonic-gate token = TYPEDEF; 515*0Sstevel@tonic-gate } else if (globalscope == YES && 516*0Sstevel@tonic-gate template == NO && oldtype == NO) { 517*0Sstevel@tonic-gate /* if a global definition */ 518*0Sstevel@tonic-gate token = GLOBALDEF; 519*0Sstevel@tonic-gate } else if (fcndef == YES && braces == 0) { 520*0Sstevel@tonic-gate /* if a function parameter definition */ 521*0Sstevel@tonic-gate token = PARAMETER; 522*0Sstevel@tonic-gate } else if (localdef == YES) { 523*0Sstevel@tonic-gate /* if a local definition */ 524*0Sstevel@tonic-gate token = LOCALDEF; 525*0Sstevel@tonic-gate } 526*0Sstevel@tonic-gate } 527*0Sstevel@tonic-gate iflongline: 528*0Sstevel@tonic-gate /* if a long line */ 529*0Sstevel@tonic-gate if (yyleng > STMTMAX) { 530*0Sstevel@tonic-gate int c; 531*0Sstevel@tonic-gate 532*0Sstevel@tonic-gate /* skip to the end of the line */ 533*0Sstevel@tonic-gate warning("line too long"); 534*0Sstevel@tonic-gate while ((c = input()) != LEXEOF) { 535*0Sstevel@tonic-gate if (c == '\n') { 536*0Sstevel@tonic-gate unput(c); 537*0Sstevel@tonic-gate break; 538*0Sstevel@tonic-gate } 539*0Sstevel@tonic-gate } 540*0Sstevel@tonic-gate } 541*0Sstevel@tonic-gate /* truncate a long symbol */ 542*0Sstevel@tonic-gate if (yyleng - first > PATLEN) { 543*0Sstevel@tonic-gate warning("symbol too long"); 544*0Sstevel@tonic-gate yyleng = first + PATLEN; 545*0Sstevel@tonic-gate yytext[yyleng] = '\0'; 546*0Sstevel@tonic-gate } 547*0Sstevel@tonic-gate 548*0Sstevel@tonic-gate yymore(); 549*0Sstevel@tonic-gate 550*0Sstevel@tonic-gate if (asy) { 551*0Sstevel@tonic-gate int t; 552*0Sstevel@tonic-gate 553*0Sstevel@tonic-gate last = yyleng; 554*0Sstevel@tonic-gate t = do_assembly(token); 555*0Sstevel@tonic-gate if (t >= 0) { 556*0Sstevel@tonic-gate token = t; 557*0Sstevel@tonic-gate return (token); 558*0Sstevel@tonic-gate } 559*0Sstevel@tonic-gate 560*0Sstevel@tonic-gate goto end; 561*0Sstevel@tonic-gate } 562*0Sstevel@tonic-gate 563*0Sstevel@tonic-gate /* if a keyword */ 564*0Sstevel@tonic-gate if ((p = lookup(yytext + first)) != NULL) { 565*0Sstevel@tonic-gate first = yyleng; 566*0Sstevel@tonic-gate s = p->text; 567*0Sstevel@tonic-gate 568*0Sstevel@tonic-gate /* if an extern declaration */ 569*0Sstevel@tonic-gate if (s == externtext) { 570*0Sstevel@tonic-gate externdec = YES; 571*0Sstevel@tonic-gate } else if (s == typedeftext) { 572*0Sstevel@tonic-gate /* if a typedef name definition */ 573*0Sstevel@tonic-gate typedefdef = YES; 574*0Sstevel@tonic-gate oldtype = YES; 575*0Sstevel@tonic-gate } else if (p->type == DECL && fcndef == YES && 576*0Sstevel@tonic-gate typedefdef == NO && parens == 0) { 577*0Sstevel@tonic-gate /* if a local definition */ 578*0Sstevel@tonic-gate localdef = YES; 579*0Sstevel@tonic-gate } else if (templateparens == parens && 580*0Sstevel@tonic-gate template == YES) { 581*0Sstevel@tonic-gate /* 582*0Sstevel@tonic-gate * keyword doesn't start a function 583*0Sstevel@tonic-gate * template 584*0Sstevel@tonic-gate */ 585*0Sstevel@tonic-gate templateparens = -1; 586*0Sstevel@tonic-gate template = NO; 587*0Sstevel@tonic-gate } else { 588*0Sstevel@tonic-gate /* 589*0Sstevel@tonic-gate * next identifier after typedef was 590*0Sstevel@tonic-gate * a keyword 591*0Sstevel@tonic-gate */ 592*0Sstevel@tonic-gate oldtype = NO; 593*0Sstevel@tonic-gate } 594*0Sstevel@tonic-gate typedefname = NO; 595*0Sstevel@tonic-gate } else { /* identifier */ 596*0Sstevel@tonic-gate last = yyleng; 597*0Sstevel@tonic-gate 598*0Sstevel@tonic-gate /* 599*0Sstevel@tonic-gate * if an enum/struct/union keyword preceded 600*0Sstevel@tonic-gate * this ident. 601*0Sstevel@tonic-gate */ 602*0Sstevel@tonic-gate if (esudef == YES && cesudeftoken) { 603*0Sstevel@tonic-gate token = cesudeftoken; 604*0Sstevel@tonic-gate cesudeftoken = '\0'; 605*0Sstevel@tonic-gate } else { 606*0Sstevel@tonic-gate oldtype = NO; 607*0Sstevel@tonic-gate } 608*0Sstevel@tonic-gate /* if a local definition using a typedef name */ 609*0Sstevel@tonic-gate if (typedefname == YES) { 610*0Sstevel@tonic-gate localdef = YES; 611*0Sstevel@tonic-gate } 612*0Sstevel@tonic-gate typedefname = NO; 613*0Sstevel@tonic-gate return (token); 614*0Sstevel@tonic-gate } 615*0Sstevel@tonic-gate 616*0Sstevel@tonic-gate end: 617*0Sstevel@tonic-gate ; 618*0Sstevel@tonic-gate } 619*0Sstevel@tonic-gate \[ { /* array dimension (don't worry about subscripts) */ 620*0Sstevel@tonic-gate arraydimension = YES; 621*0Sstevel@tonic-gate goto more; 622*0Sstevel@tonic-gate /* NOTREACHED */ 623*0Sstevel@tonic-gate } 624*0Sstevel@tonic-gate \] { 625*0Sstevel@tonic-gate arraydimension = NO; 626*0Sstevel@tonic-gate goto more; 627*0Sstevel@tonic-gate /* NOTREACHED */ 628*0Sstevel@tonic-gate } 629*0Sstevel@tonic-gate \\\n { /* preprocessor statement is continued on next line */ 630*0Sstevel@tonic-gate goto eol; 631*0Sstevel@tonic-gate /* NOTREACHED */ 632*0Sstevel@tonic-gate } 633*0Sstevel@tonic-gate \n { /* end of the line */ 634*0Sstevel@tonic-gate if (ppdefine == YES) { /* end of a #define */ 635*0Sstevel@tonic-gate ppdefine = NO; 636*0Sstevel@tonic-gate (void) yyless(yyleng - 1); /* rescan \n */ 637*0Sstevel@tonic-gate last = first; 638*0Sstevel@tonic-gate yymore(); 639*0Sstevel@tonic-gate return (DEFINEEND); 640*0Sstevel@tonic-gate } 641*0Sstevel@tonic-gate /* 642*0Sstevel@tonic-gate * skip the first 8 columns of a breakpoint listing 643*0Sstevel@tonic-gate * line and skip the file path in the page header 644*0Sstevel@tonic-gate */ 645*0Sstevel@tonic-gate if (bplisting == YES) { 646*0Sstevel@tonic-gate int c, i; 647*0Sstevel@tonic-gate 648*0Sstevel@tonic-gate switch (input()) { 649*0Sstevel@tonic-gate /* tab and EOF just fall through */ 650*0Sstevel@tonic-gate case ' ': /* breakpoint number line */ 651*0Sstevel@tonic-gate case '[': 652*0Sstevel@tonic-gate for (i = 1; i < 8 && input() != LEXEOF; 653*0Sstevel@tonic-gate ++i) { 654*0Sstevel@tonic-gate /*EMPTY*/ 655*0Sstevel@tonic-gate } 656*0Sstevel@tonic-gate break; 657*0Sstevel@tonic-gate case '.': /* header line */ 658*0Sstevel@tonic-gate case '/': 659*0Sstevel@tonic-gate /* skip to the end of the line */ 660*0Sstevel@tonic-gate while ((c = input()) != LEXEOF) { 661*0Sstevel@tonic-gate if (c == '\n') { 662*0Sstevel@tonic-gate unput(c); 663*0Sstevel@tonic-gate break; 664*0Sstevel@tonic-gate } 665*0Sstevel@tonic-gate } 666*0Sstevel@tonic-gate break; 667*0Sstevel@tonic-gate case '\n': /* empty line */ 668*0Sstevel@tonic-gate unput('\n'); 669*0Sstevel@tonic-gate break; 670*0Sstevel@tonic-gate } 671*0Sstevel@tonic-gate } 672*0Sstevel@tonic-gate eol: 673*0Sstevel@tonic-gate ++yylineno; 674*0Sstevel@tonic-gate first = 0; 675*0Sstevel@tonic-gate last = 0; 676*0Sstevel@tonic-gate if (symbols > 0) { 677*0Sstevel@tonic-gate return (NEWLINE); 678*0Sstevel@tonic-gate } 679*0Sstevel@tonic-gate lineno = yylineno; 680*0Sstevel@tonic-gate } 681*0Sstevel@tonic-gate \' { /* character constant */ 682*0Sstevel@tonic-gate if (sdl == NO) { 683*0Sstevel@tonic-gate multicharconstant('\''); 684*0Sstevel@tonic-gate } 685*0Sstevel@tonic-gate goto more; 686*0Sstevel@tonic-gate /* NOTREACHED */ 687*0Sstevel@tonic-gate } 688*0Sstevel@tonic-gate \" { /* string constant */ 689*0Sstevel@tonic-gate multicharconstant('"'); 690*0Sstevel@tonic-gate goto more; 691*0Sstevel@tonic-gate /* NOTREACHED */ 692*0Sstevel@tonic-gate } 693*0Sstevel@tonic-gate ^[ \t\f\b]+ { /* don't save leading white space */ 694*0Sstevel@tonic-gate } 695*0Sstevel@tonic-gate \#[# \t]*include[ \t]*["<][^"> \t\n\r]+ { /* #include or Ingres ##include */ 696*0Sstevel@tonic-gate char *s; 697*0Sstevel@tonic-gate 698*0Sstevel@tonic-gate s = strpbrk(yytext, "\"<"); 699*0Sstevel@tonic-gate incfile(s + 1, *s); 700*0Sstevel@tonic-gate first = s - yytext; 701*0Sstevel@tonic-gate last = yyleng; 702*0Sstevel@tonic-gate if (compress == YES) { 703*0Sstevel@tonic-gate /* compress the keyword */ 704*0Sstevel@tonic-gate yytext[0] = '\1'; 705*0Sstevel@tonic-gate } 706*0Sstevel@tonic-gate /* 707*0Sstevel@tonic-gate * avoid multicharconstant call triggered by trailing 708*0Sstevel@tonic-gate * ", which puts a trailing comment in the database 709*0Sstevel@tonic-gate */ 710*0Sstevel@tonic-gate if (*s == '"') { 711*0Sstevel@tonic-gate int c; 712*0Sstevel@tonic-gate 713*0Sstevel@tonic-gate while ((c = input()) != LEXEOF) { 714*0Sstevel@tonic-gate if (c == '"') { 715*0Sstevel@tonic-gate yytext[yyleng] = '"'; 716*0Sstevel@tonic-gate yytext[++yyleng] = '\0'; 717*0Sstevel@tonic-gate break; 718*0Sstevel@tonic-gate } 719*0Sstevel@tonic-gate /* the trailing '"' may be missing */ 720*0Sstevel@tonic-gate if (c == '\n') { 721*0Sstevel@tonic-gate unput('\n'); 722*0Sstevel@tonic-gate break; 723*0Sstevel@tonic-gate } 724*0Sstevel@tonic-gate } 725*0Sstevel@tonic-gate } 726*0Sstevel@tonic-gate yymore(); 727*0Sstevel@tonic-gate return (INCLUDE); 728*0Sstevel@tonic-gate /* NOTREACHED */ 729*0Sstevel@tonic-gate } 730*0Sstevel@tonic-gate \#[ \t]*pragma[ \t]+weak[ \t]+{identifier} { 731*0Sstevel@tonic-gate ppdefine = YES; 732*0Sstevel@tonic-gate token = DEFINE; 733*0Sstevel@tonic-gate goto findident; 734*0Sstevel@tonic-gate 735*0Sstevel@tonic-gate /*NOTREACHED*/ 736*0Sstevel@tonic-gate } 737*0Sstevel@tonic-gate \#[ \t]*{identifier} | /* preprocessor keyword */ 738*0Sstevel@tonic-gate {number} | /* number */ 739*0Sstevel@tonic-gate . { /* punctuation and operators */ 740*0Sstevel@tonic-gate more: first = yyleng; 741*0Sstevel@tonic-gate yymore(); 742*0Sstevel@tonic-gate } 743*0Sstevel@tonic-gate %% 744*0Sstevel@tonic-gate 745*0Sstevel@tonic-gate void 746*0Sstevel@tonic-gate initscanner(char *srcfile) 747*0Sstevel@tonic-gate { 748*0Sstevel@tonic-gate char *s; 749*0Sstevel@tonic-gate 750*0Sstevel@tonic-gate if (maxifbraces == NULL) { 751*0Sstevel@tonic-gate maxifbraces = mymalloc(miflevel * sizeof (int)); 752*0Sstevel@tonic-gate preifbraces = mymalloc(miflevel * sizeof (int)); 753*0Sstevel@tonic-gate } 754*0Sstevel@tonic-gate first = 0; /* buffer index for first char of symbol */ 755*0Sstevel@tonic-gate last = 0; /* buffer index for last char of symbol */ 756*0Sstevel@tonic-gate lineno = 1; /* symbol line number */ 757*0Sstevel@tonic-gate yylineno = 1; /* input line number */ 758*0Sstevel@tonic-gate arraydimension = NO; /* inside array dimension declaration */ 759*0Sstevel@tonic-gate bplisting = NO; /* breakpoint listing */ 760*0Sstevel@tonic-gate braces = 0; /* unmatched left brace count */ 761*0Sstevel@tonic-gate cesudeftoken = '\0'; /* class/enum/struct/union definition */ 762*0Sstevel@tonic-gate classdef = NO; /* c++ class definition */ 763*0Sstevel@tonic-gate elseelif = NO; /* #else or #elif found */ 764*0Sstevel@tonic-gate esudef = NO; /* enum/struct/union definition */ 765*0Sstevel@tonic-gate esubraces = -1; /* outermost enum/struct/union brace count */ 766*0Sstevel@tonic-gate externdec = NO; /* extern declaration */ 767*0Sstevel@tonic-gate fcndef = NO; /* function definition */ 768*0Sstevel@tonic-gate globalscope = YES; /* file global scope (outside functions) */ 769*0Sstevel@tonic-gate iflevel = 0; /* #if nesting level */ 770*0Sstevel@tonic-gate initializer = NO; /* data initializer */ 771*0Sstevel@tonic-gate initializerbraces = -1; /* data initializer outer brace count */ 772*0Sstevel@tonic-gate lex = NO; /* lex file */ 773*0Sstevel@tonic-gate localdef = NO; /* function/block local definition */ 774*0Sstevel@tonic-gate parens = 0; /* unmatched left parenthesis count */ 775*0Sstevel@tonic-gate ppdefine = NO; /* preprocessor define statement */ 776*0Sstevel@tonic-gate psuedoelif = NO; /* psuedo-#elif */ 777*0Sstevel@tonic-gate oldtype = NO; /* next identifier is an old type */ 778*0Sstevel@tonic-gate rules = NO; /* lex/yacc rules */ 779*0Sstevel@tonic-gate sdl = NO; /* SDL file */ 780*0Sstevel@tonic-gate structfield = NO; /* structure field declaration */ 781*0Sstevel@tonic-gate template = NO; /* function template */ 782*0Sstevel@tonic-gate templateparens = -1; /* function template outer parentheses count */ 783*0Sstevel@tonic-gate typedefdef = NO; /* typedef name definition */ 784*0Sstevel@tonic-gate typedefname = NO; /* typedef name use */ 785*0Sstevel@tonic-gate asy = NO; /* assembly file */ 786*0Sstevel@tonic-gate BEGIN 0; 787*0Sstevel@tonic-gate 788*0Sstevel@tonic-gate /* if this is not a C file */ 789*0Sstevel@tonic-gate if ((s = strrchr(srcfile, '.')) != NULL) { 790*0Sstevel@tonic-gate switch (*++s) { /* this switch saves time on C files */ 791*0Sstevel@tonic-gate case 'b': 792*0Sstevel@tonic-gate if (strcmp(s, "bp") == 0) { /* breakpoint listing */ 793*0Sstevel@tonic-gate bplisting = YES; 794*0Sstevel@tonic-gate } 795*0Sstevel@tonic-gate break; 796*0Sstevel@tonic-gate case 'l': 797*0Sstevel@tonic-gate if (strcmp(s, "l") == 0) { /* lex */ 798*0Sstevel@tonic-gate lex = YES; 799*0Sstevel@tonic-gate globalscope = NO; 800*0Sstevel@tonic-gate } 801*0Sstevel@tonic-gate break; 802*0Sstevel@tonic-gate case 'p': 803*0Sstevel@tonic-gate case 's': 804*0Sstevel@tonic-gate if (strcmp(s, "pr") == 0 || 805*0Sstevel@tonic-gate strcmp(s, "sd") == 0) { /* SDL */ 806*0Sstevel@tonic-gate sdl = YES; 807*0Sstevel@tonic-gate BEGIN SDL; 808*0Sstevel@tonic-gate } else if (strcmp(s, "s") == 0) { 809*0Sstevel@tonic-gate asy = YES; 810*0Sstevel@tonic-gate } 811*0Sstevel@tonic-gate break; 812*0Sstevel@tonic-gate case 'y': 813*0Sstevel@tonic-gate if (strcmp(s, "y") == 0) { /* yacc */ 814*0Sstevel@tonic-gate globalscope = NO; 815*0Sstevel@tonic-gate } 816*0Sstevel@tonic-gate break; 817*0Sstevel@tonic-gate } 818*0Sstevel@tonic-gate } 819*0Sstevel@tonic-gate } 820*0Sstevel@tonic-gate 821*0Sstevel@tonic-gate int 822*0Sstevel@tonic-gate comment(void) 823*0Sstevel@tonic-gate { 824*0Sstevel@tonic-gate int c, lastc; 825*0Sstevel@tonic-gate 826*0Sstevel@tonic-gate do { 827*0Sstevel@tonic-gate if ((c = getc(yyin)) == '*') { /* C comment */ 828*0Sstevel@tonic-gate lastc = '\0'; 829*0Sstevel@tonic-gate while ((c = getc(yyin)) != EOF && 830*0Sstevel@tonic-gate (c != '/' || lastc != '*')) { /* fewer '/'s */ 831*0Sstevel@tonic-gate if (c == '\n') { 832*0Sstevel@tonic-gate ++yylineno; 833*0Sstevel@tonic-gate } 834*0Sstevel@tonic-gate lastc = c; 835*0Sstevel@tonic-gate } 836*0Sstevel@tonic-gate /* return a blank for Reiser cpp token concatenation */ 837*0Sstevel@tonic-gate if ((c = getc(yyin)) == '_' || isalnum(c)) { 838*0Sstevel@tonic-gate (void) ungetc(c, yyin); 839*0Sstevel@tonic-gate c = ' '; 840*0Sstevel@tonic-gate break; 841*0Sstevel@tonic-gate } 842*0Sstevel@tonic-gate } else if (c == '/') { /* C++ comment */ 843*0Sstevel@tonic-gate while ((c = getc(yyin)) != EOF && c != '\n') { 844*0Sstevel@tonic-gate /*EMPTY*/ 845*0Sstevel@tonic-gate } 846*0Sstevel@tonic-gate break; 847*0Sstevel@tonic-gate } else { /* not a comment */ 848*0Sstevel@tonic-gate (void) ungetc(c, yyin); 849*0Sstevel@tonic-gate c = '/'; 850*0Sstevel@tonic-gate break; 851*0Sstevel@tonic-gate } 852*0Sstevel@tonic-gate 853*0Sstevel@tonic-gate /* there may be an immediately following comment */ 854*0Sstevel@tonic-gate } while (c == '/'); 855*0Sstevel@tonic-gate return (c); 856*0Sstevel@tonic-gate } 857*0Sstevel@tonic-gate 858*0Sstevel@tonic-gate void 859*0Sstevel@tonic-gate multicharconstant(char terminator) 860*0Sstevel@tonic-gate { 861*0Sstevel@tonic-gate char c; 862*0Sstevel@tonic-gate 863*0Sstevel@tonic-gate /* scan until the terminator is found */ 864*0Sstevel@tonic-gate while ((c = yytext[yyleng++] = noncommentinput()) != terminator) { 865*0Sstevel@tonic-gate switch (c) { 866*0Sstevel@tonic-gate case '\\': /* escape character */ 867*0Sstevel@tonic-gate if ((yytext[yyleng++] = noncommentinput()) == '\n') { 868*0Sstevel@tonic-gate ++yylineno; 869*0Sstevel@tonic-gate } 870*0Sstevel@tonic-gate break; 871*0Sstevel@tonic-gate case '\t': /* tab character */ 872*0Sstevel@tonic-gate 873*0Sstevel@tonic-gate /* if not a lex program, continue */ 874*0Sstevel@tonic-gate if (lex == NO) { 875*0Sstevel@tonic-gate break; 876*0Sstevel@tonic-gate } 877*0Sstevel@tonic-gate /* FALLTHROUGH */ 878*0Sstevel@tonic-gate 879*0Sstevel@tonic-gate case '\n': /* illegal character */ 880*0Sstevel@tonic-gate 881*0Sstevel@tonic-gate /* 882*0Sstevel@tonic-gate * assume the terminator is missing, so put 883*0Sstevel@tonic-gate * this character back 884*0Sstevel@tonic-gate */ 885*0Sstevel@tonic-gate unput(c); 886*0Sstevel@tonic-gate yytext[--yyleng] = '\0'; 887*0Sstevel@tonic-gate /* FALLTHROUGH */ 888*0Sstevel@tonic-gate 889*0Sstevel@tonic-gate case LEXEOF: /* end of file */ 890*0Sstevel@tonic-gate return; 891*0Sstevel@tonic-gate 892*0Sstevel@tonic-gate default: 893*0Sstevel@tonic-gate /* change a control character to a blank */ 894*0Sstevel@tonic-gate if (!isprint(c)) { 895*0Sstevel@tonic-gate yytext[yyleng - 1] = ' '; 896*0Sstevel@tonic-gate } 897*0Sstevel@tonic-gate } 898*0Sstevel@tonic-gate /* if this token will overflow the line buffer */ 899*0Sstevel@tonic-gate /* note: '\\' may cause yyleng to be > STMTMAX */ 900*0Sstevel@tonic-gate if (yyleng >= STMTMAX) { 901*0Sstevel@tonic-gate 902*0Sstevel@tonic-gate /* truncate the token */ 903*0Sstevel@tonic-gate while ((c = noncommentinput()) != LEXEOF) { 904*0Sstevel@tonic-gate if (c == terminator) { 905*0Sstevel@tonic-gate unput(c); 906*0Sstevel@tonic-gate break; 907*0Sstevel@tonic-gate } else if (c == '\n') { 908*0Sstevel@tonic-gate ++yylineno; 909*0Sstevel@tonic-gate } 910*0Sstevel@tonic-gate } 911*0Sstevel@tonic-gate } 912*0Sstevel@tonic-gate } 913*0Sstevel@tonic-gate yytext[yyleng] = '\0'; 914*0Sstevel@tonic-gate } 915*0Sstevel@tonic-gate 916*0Sstevel@tonic-gate /* 917*0Sstevel@tonic-gate * Returns true if the beginning of str matches ident, and the next character 918*0Sstevel@tonic-gate * is not alphanumeric and not an underscore. 919*0Sstevel@tonic-gate */ 920*0Sstevel@tonic-gate int 921*0Sstevel@tonic-gate identcmp(const char *str, const char *ident) 922*0Sstevel@tonic-gate { 923*0Sstevel@tonic-gate int n = strlen(ident); 924*0Sstevel@tonic-gate 925*0Sstevel@tonic-gate return (strncmp(str, ident, n) == 0 && !isalnum(str[n]) && 926*0Sstevel@tonic-gate str[n] != '_'); 927*0Sstevel@tonic-gate } 928*0Sstevel@tonic-gate 929*0Sstevel@tonic-gate /* 930*0Sstevel@tonic-gate * Here we want to 931*0Sstevel@tonic-gate * - Make *ENTRY*() macro invocations into function definitions 932*0Sstevel@tonic-gate * - Make SET_SIZE() macro calls into function ends 933*0Sstevel@tonic-gate * - Make "call sym" instructions into function calls 934*0Sstevel@tonic-gate * - Eliminate C function definitions (since they are for lint, and we want 935*0Sstevel@tonic-gate * only one definition for each function) 936*0Sstevel@tonic-gate */ 937*0Sstevel@tonic-gate int 938*0Sstevel@tonic-gate do_assembly(int token) 939*0Sstevel@tonic-gate { 940*0Sstevel@tonic-gate /* Handle C keywords? */ 941*0Sstevel@tonic-gate 942*0Sstevel@tonic-gate switch (token) { 943*0Sstevel@tonic-gate 944*0Sstevel@tonic-gate case FCNDEF: 945*0Sstevel@tonic-gate /* 946*0Sstevel@tonic-gate * We have a symbol that looks like a C function definition or 947*0Sstevel@tonic-gate * call. (Note: That can include assembly instructions with 948*0Sstevel@tonic-gate * the right parentheses.) We want to convert assembly macro 949*0Sstevel@tonic-gate * invocations to function calls, and ignore everything else. 950*0Sstevel@tonic-gate * Since we technically can't tell the difference, we'll use 951*0Sstevel@tonic-gate * an all-caps heuristic. 952*0Sstevel@tonic-gate * 953*0Sstevel@tonic-gate * ... except for SET_SIZE macros, since they will precede 954*0Sstevel@tonic-gate * FUNCEND tokens, which will break code in find.c which 955*0Sstevel@tonic-gate * assumes that FUNCEND tokens occur at the beginning of 956*0Sstevel@tonic-gate * lines. 957*0Sstevel@tonic-gate */ 958*0Sstevel@tonic-gate if (isupper(yytext[first]) && strcmp(yytext, "SET_SIZE") != 0) 959*0Sstevel@tonic-gate return (FCNCALL); 960*0Sstevel@tonic-gate 961*0Sstevel@tonic-gate /* Don't return a token. */ 962*0Sstevel@tonic-gate return (-1); 963*0Sstevel@tonic-gate 964*0Sstevel@tonic-gate case GLOBALDEF: 965*0Sstevel@tonic-gate case IDENT: 966*0Sstevel@tonic-gate /* Macro arguments come down as global variable definitions. */ 967*0Sstevel@tonic-gate 968*0Sstevel@tonic-gate if (identcmp(yytext, "ENTRY") || 969*0Sstevel@tonic-gate identcmp(yytext, "ENTRY2") || 970*0Sstevel@tonic-gate identcmp(yytext, "ENTRY_NP") || 971*0Sstevel@tonic-gate identcmp(yytext, "ENTRY_NP2") || 972*0Sstevel@tonic-gate identcmp(yytext, "RTENTRY") || 973*0Sstevel@tonic-gate identcmp(yytext, "ALTENTRY")) { 974*0Sstevel@tonic-gate /* 975*0Sstevel@tonic-gate * Identifiers on lines beginning with *ENTRY* macros 976*0Sstevel@tonic-gate * are actually function definitions. 977*0Sstevel@tonic-gate */ 978*0Sstevel@tonic-gate return (FCNDEF); 979*0Sstevel@tonic-gate } 980*0Sstevel@tonic-gate 981*0Sstevel@tonic-gate if (identcmp(yytext, "SET_SIZE")) { 982*0Sstevel@tonic-gate /* 983*0Sstevel@tonic-gate * Identifiers on lines beginning with SET_SIZE are 984*0Sstevel@tonic-gate * actually function ends. 985*0Sstevel@tonic-gate */ 986*0Sstevel@tonic-gate return (FCNEND); 987*0Sstevel@tonic-gate } 988*0Sstevel@tonic-gate 989*0Sstevel@tonic-gate if (first != 0 && identcmp(yytext, "call")) { 990*0Sstevel@tonic-gate /* 991*0Sstevel@tonic-gate * Make this a function call. We exclude first == 0, 992*0Sstevel@tonic-gate * because that happens when we're looking at "call" 993*0Sstevel@tonic-gate * itself. (Then we'd get function calls to "call" 994*0Sstevel@tonic-gate * everywhere.) 995*0Sstevel@tonic-gate */ 996*0Sstevel@tonic-gate return (FCNCALL); 997*0Sstevel@tonic-gate } 998*0Sstevel@tonic-gate 999*0Sstevel@tonic-gate default: 1000*0Sstevel@tonic-gate /* Default to normal behavior. */ 1001*0Sstevel@tonic-gate return (token); 1002*0Sstevel@tonic-gate } 1003*0Sstevel@tonic-gate } 1004