aslsupport.l revision 250838
1234518Sjkim/****************************************************************************** 2234518Sjkim * 3234518Sjkim * Module Name: aslsupport.l - Flex/lex scanner C support routines. 4234518Sjkim * NOTE: Included into aslcompile.l, not compiled by itself. 5234518Sjkim * 6234518Sjkim *****************************************************************************/ 7234518Sjkim 8234518Sjkim/* 9245582Sjkim * Copyright (C) 2000 - 2013, Intel Corp. 10234518Sjkim * All rights reserved. 11234518Sjkim * 12234518Sjkim * Redistribution and use in source and binary forms, with or without 13234518Sjkim * modification, are permitted provided that the following conditions 14234518Sjkim * are met: 15234518Sjkim * 1. Redistributions of source code must retain the above copyright 16234518Sjkim * notice, this list of conditions, and the following disclaimer, 17234518Sjkim * without modification. 18234518Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer 19234518Sjkim * substantially similar to the "NO WARRANTY" disclaimer below 20234518Sjkim * ("Disclaimer") and any redistribution must be conditioned upon 21234518Sjkim * including a substantially similar Disclaimer requirement for further 22234518Sjkim * binary redistribution. 23234518Sjkim * 3. Neither the names of the above-listed copyright holders nor the names 24234518Sjkim * of any contributors may be used to endorse or promote products derived 25234518Sjkim * from this software without specific prior written permission. 26234518Sjkim * 27234518Sjkim * Alternatively, this software may be distributed under the terms of the 28234518Sjkim * GNU General Public License ("GPL") version 2 as published by the Free 29234518Sjkim * Software Foundation. 30234518Sjkim * 31234518Sjkim * NO WARRANTY 32234518Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 33234518Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 34234518Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 35234518Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 36234518Sjkim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 37234518Sjkim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 38234518Sjkim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 39234518Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 40234518Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 41234518Sjkim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 42234518Sjkim * POSSIBILITY OF SUCH DAMAGES. 43234518Sjkim */ 44234518Sjkim 45234518Sjkim 46234518Sjkim/* Configuration */ 47234518Sjkim 48234518Sjkim#define ASL_SPACES_PER_TAB 4 49234518Sjkim 50234518Sjkim#define ASL_NORMAL_CHAR 0 51234518Sjkim#define ASL_ESCAPE_SEQUENCE 1 52234518Sjkim#define ASL_OCTAL_CONSTANT 2 53234518Sjkim#define ASL_HEX_CONSTANT 3 54234518Sjkim 55234518Sjkim 56234518Sjkim/* File node - used for "Include" operator file stack */ 57234518Sjkim 58234518Sjkimtypedef struct asl_file_node 59234518Sjkim{ 60234518Sjkim FILE *File; 61234518Sjkim UINT32 CurrentLineNumber; 62234518Sjkim YY_BUFFER_STATE State; 63234518Sjkim char *Filename; 64234518Sjkim struct asl_file_node *Next; 65234518Sjkim 66234518Sjkim} ASL_FILE_NODE; 67234518Sjkim 68234518Sjkim/* File stack for the "Include" operator (NOT #include operator) */ 69234518Sjkim 70234518SjkimASL_FILE_NODE *Gbl_IncludeFileStack = NULL; 71234518Sjkim 72234518Sjkim 73234518Sjkim/******************************************************************************* 74234518Sjkim * 75234518Sjkim * FUNCTION: AslDoLineDirective 76234518Sjkim * 77234518Sjkim * PARAMETERS: None. Uses input() to access current source code line 78234518Sjkim * 79234518Sjkim * RETURN: Updates global line number and filename 80234518Sjkim * 81234518Sjkim * DESCRIPTION: Handle #line directives emitted by the preprocessor. 82234518Sjkim * 83234518Sjkim * The #line directive is emitted by the preprocesser, and is used to 84234518Sjkim * pass through line numbers from the original source code file to the 85234518Sjkim * preprocessor output file (.i). This allows any compiler-generated 86234518Sjkim * error messages to be displayed with the correct line number. 87234518Sjkim * 88234518Sjkim ******************************************************************************/ 89234518Sjkim 90234518Sjkimstatic void 91234518SjkimAslDoLineDirective ( 92234518Sjkim void) 93234518Sjkim{ 94237412Sjkim int c; 95234518Sjkim char *Token; 96234518Sjkim UINT32 LineNumber; 97234518Sjkim char *Filename; 98237412Sjkim UINT32 i; 99234518Sjkim 100234518Sjkim 101234518Sjkim /* Eat the entire line that contains the #line directive */ 102234518Sjkim 103237412Sjkim Gbl_LineBufPtr = Gbl_CurrentLineBuffer; 104237412Sjkim 105237412Sjkim while ((c = input()) != '\n' && c != EOF) 106234518Sjkim { 107237412Sjkim *Gbl_LineBufPtr = c; 108237412Sjkim Gbl_LineBufPtr++; 109234518Sjkim } 110237412Sjkim *Gbl_LineBufPtr = 0; 111234518Sjkim 112234518Sjkim /* First argument is the actual line number */ 113234518Sjkim 114234518Sjkim Token = strtok (Gbl_CurrentLineBuffer, " "); 115234518Sjkim if (!Token) 116234518Sjkim { 117234518Sjkim goto ResetAndExit; 118234518Sjkim } 119234518Sjkim 120237412Sjkim /* First argument is the line number */ 121234518Sjkim 122234518Sjkim LineNumber = (UINT32) UtDoConstant (Token); 123234518Sjkim 124237412Sjkim /* Emit the appropriate number of newlines */ 125237412Sjkim 126237412Sjkim Gbl_CurrentColumn = 0; 127237412Sjkim if (LineNumber > Gbl_CurrentLineNumber) 128237412Sjkim { 129237412Sjkim for (i = 0; i < (LineNumber - Gbl_CurrentLineNumber); i++) 130237412Sjkim { 131237412Sjkim FlWriteFile (ASL_FILE_SOURCE_OUTPUT, "\n", 1); 132237412Sjkim Gbl_CurrentColumn++; 133237412Sjkim } 134237412Sjkim } 135237412Sjkim 136237412Sjkim FlSetLineNumber (LineNumber); 137237412Sjkim 138234518Sjkim /* Second argument is the optional filename (in double quotes) */ 139234518Sjkim 140234518Sjkim Token = strtok (NULL, " \""); 141234518Sjkim if (Token) 142234518Sjkim { 143234518Sjkim Filename = ACPI_ALLOCATE_ZEROED (strlen (Token) + 1); 144234518Sjkim strcpy (Filename, Token); 145234518Sjkim FlSetFilename (Filename); 146234518Sjkim } 147234518Sjkim 148234518Sjkim /* Third argument is not supported at this time */ 149234518Sjkim 150234518SjkimResetAndExit: 151237412Sjkim 152237412Sjkim /* Reset globals for a new line */ 153237412Sjkim 154237412Sjkim Gbl_CurrentLineOffset += Gbl_CurrentColumn; 155237412Sjkim Gbl_CurrentColumn = 0; 156237412Sjkim Gbl_LineBufPtr = Gbl_CurrentLineBuffer; 157234518Sjkim} 158234518Sjkim 159234518Sjkim 160234518Sjkim/******************************************************************************* 161234518Sjkim * 162234518Sjkim * FUNCTION: AslPopInputFileStack 163234518Sjkim * 164234518Sjkim * PARAMETERS: None 165234518Sjkim * 166234518Sjkim * RETURN: 0 if a node was popped, -1 otherwise 167234518Sjkim * 168234518Sjkim * DESCRIPTION: Pop the top of the input file stack and point the parser to 169241973Sjkim * the saved parse buffer contained in the fnode. Also, set the 170241973Sjkim * global line counters to the saved values. This function is 171234518Sjkim * called when an include file reaches EOF. 172234518Sjkim * 173234518Sjkim ******************************************************************************/ 174234518Sjkim 175234518Sjkimint 176234518SjkimAslPopInputFileStack ( 177234518Sjkim void) 178234518Sjkim{ 179234518Sjkim ASL_FILE_NODE *Fnode; 180234518Sjkim 181234518Sjkim 182234518Sjkim Fnode = Gbl_IncludeFileStack; 183234518Sjkim DbgPrint (ASL_PARSE_OUTPUT, "\nPop InputFile Stack, Fnode %p\n\n", Fnode); 184234518Sjkim 185234518Sjkim if (!Fnode) 186234518Sjkim { 187234518Sjkim return (-1); 188234518Sjkim } 189234518Sjkim 190234518Sjkim /* Close the current include file */ 191234518Sjkim 192234518Sjkim fclose (yyin); 193234518Sjkim 194234518Sjkim /* Update the top-of-stack */ 195234518Sjkim 196234518Sjkim Gbl_IncludeFileStack = Fnode->Next; 197234518Sjkim 198234518Sjkim /* Reset global line counter and filename */ 199234518Sjkim 200234518Sjkim Gbl_Files[ASL_FILE_INPUT].Filename = Fnode->Filename; 201234518Sjkim Gbl_CurrentLineNumber = Fnode->CurrentLineNumber; 202234518Sjkim 203234518Sjkim /* Point the parser to the popped file */ 204234518Sjkim 205234518Sjkim yy_delete_buffer (YY_CURRENT_BUFFER); 206234518Sjkim yy_switch_to_buffer (Fnode->State); 207234518Sjkim 208234518Sjkim /* All done with this node */ 209234518Sjkim 210234518Sjkim ACPI_FREE (Fnode); 211234518Sjkim return (0); 212234518Sjkim} 213234518Sjkim 214234518Sjkim 215234518Sjkim/******************************************************************************* 216234518Sjkim * 217234518Sjkim * FUNCTION: AslPushInputFileStack 218234518Sjkim * 219234518Sjkim * PARAMETERS: InputFile - Open file pointer 220234518Sjkim * Filename - Name of the file 221234518Sjkim * 222234518Sjkim * RETURN: None 223234518Sjkim * 224234518Sjkim * DESCRIPTION: Push the InputFile onto the file stack, and point the parser 225241973Sjkim * to this file. Called when an include file is successfully 226234518Sjkim * opened. 227234518Sjkim * 228234518Sjkim ******************************************************************************/ 229234518Sjkim 230234518Sjkimvoid 231234518SjkimAslPushInputFileStack ( 232234518Sjkim FILE *InputFile, 233234518Sjkim char *Filename) 234234518Sjkim{ 235234518Sjkim ASL_FILE_NODE *Fnode; 236234518Sjkim YY_BUFFER_STATE State; 237234518Sjkim 238234518Sjkim 239234518Sjkim /* Save the current state in an Fnode */ 240234518Sjkim 241234518Sjkim Fnode = UtLocalCalloc (sizeof (ASL_FILE_NODE)); 242234518Sjkim 243234518Sjkim Fnode->File = yyin; 244234518Sjkim Fnode->Next = Gbl_IncludeFileStack; 245234518Sjkim Fnode->State = YY_CURRENT_BUFFER; 246234518Sjkim Fnode->CurrentLineNumber = Gbl_CurrentLineNumber; 247234518Sjkim Fnode->Filename = Gbl_Files[ASL_FILE_INPUT].Filename; 248234518Sjkim 249234518Sjkim /* Push it on the stack */ 250234518Sjkim 251234518Sjkim Gbl_IncludeFileStack = Fnode; 252234518Sjkim 253234518Sjkim /* Point the parser to this file */ 254234518Sjkim 255234518Sjkim State = yy_create_buffer (InputFile, YY_BUF_SIZE); 256234518Sjkim yy_switch_to_buffer (State); 257234518Sjkim 258234518Sjkim DbgPrint (ASL_PARSE_OUTPUT, "\nPush InputFile Stack, returning %p\n\n", InputFile); 259234518Sjkim 260234518Sjkim /* Reset the global line count and filename */ 261234518Sjkim 262234518Sjkim Gbl_Files[ASL_FILE_INPUT].Filename = Filename; 263234518Sjkim Gbl_CurrentLineNumber = 1; 264234518Sjkim yyin = InputFile; 265234518Sjkim} 266234518Sjkim 267234518Sjkim 268234518Sjkim/******************************************************************************* 269234518Sjkim * 270234518Sjkim * FUNCTION: AslResetCurrentLineBuffer 271234518Sjkim * 272234518Sjkim * PARAMETERS: None 273234518Sjkim * 274234518Sjkim * RETURN: None 275234518Sjkim * 276234518Sjkim * DESCRIPTION: Reset the Line Buffer to zero, increment global line numbers. 277234518Sjkim * 278234518Sjkim ******************************************************************************/ 279234518Sjkim 280234518Sjkimvoid 281234518SjkimAslResetCurrentLineBuffer ( 282234518Sjkim void) 283234518Sjkim{ 284234518Sjkim 285234518Sjkim if (Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Handle) 286234518Sjkim { 287234518Sjkim FlWriteFile (ASL_FILE_SOURCE_OUTPUT, Gbl_CurrentLineBuffer, 288234518Sjkim Gbl_LineBufPtr - Gbl_CurrentLineBuffer); 289234518Sjkim } 290234518Sjkim 291234518Sjkim Gbl_CurrentLineOffset += Gbl_CurrentColumn; 292234518Sjkim Gbl_CurrentColumn = 0; 293234518Sjkim 294234518Sjkim Gbl_CurrentLineNumber++; 295234518Sjkim Gbl_LogicalLineNumber++; 296234518Sjkim Gbl_LineBufPtr = Gbl_CurrentLineBuffer; 297234518Sjkim} 298234518Sjkim 299234518Sjkim 300234518Sjkim/******************************************************************************* 301234518Sjkim * 302234518Sjkim * FUNCTION: AslInsertLineBuffer 303234518Sjkim * 304234518Sjkim * PARAMETERS: SourceChar - One char from the input ASL source file 305234518Sjkim * 306234518Sjkim * RETURN: None 307234518Sjkim * 308234518Sjkim * DESCRIPTION: Put one character of the source file into the temp line buffer 309234518Sjkim * 310234518Sjkim ******************************************************************************/ 311234518Sjkim 312234518Sjkimvoid 313234518SjkimAslInsertLineBuffer ( 314234518Sjkim int SourceChar) 315234518Sjkim{ 316234518Sjkim UINT32 i; 317234518Sjkim UINT32 Count = 1; 318234518Sjkim 319234518Sjkim 320234518Sjkim if (SourceChar == EOF) 321234518Sjkim { 322234518Sjkim return; 323234518Sjkim } 324234518Sjkim 325234518Sjkim Gbl_InputByteCount++; 326234518Sjkim 327241973Sjkim /* Handle tabs. Convert to spaces */ 328234518Sjkim 329234518Sjkim if (SourceChar == '\t') 330234518Sjkim { 331234518Sjkim SourceChar = ' '; 332234518Sjkim Count = ASL_SPACES_PER_TAB - 333234518Sjkim (Gbl_CurrentColumn & (ASL_SPACES_PER_TAB-1)); 334234518Sjkim } 335234518Sjkim 336234518Sjkim for (i = 0; i < Count; i++) 337234518Sjkim { 338234518Sjkim Gbl_CurrentColumn++; 339234518Sjkim 340234518Sjkim /* Insert the character into the line buffer */ 341234518Sjkim 342234518Sjkim *Gbl_LineBufPtr = (UINT8) SourceChar; 343234518Sjkim Gbl_LineBufPtr++; 344234518Sjkim 345240716Sjkim if (Gbl_LineBufPtr > (Gbl_CurrentLineBuffer + (Gbl_LineBufferSize - 1))) 346234518Sjkim { 347234518Sjkim#if 0 348234518Sjkim /* 349234518Sjkim * Warning if we have split a long source line. 350234518Sjkim * <Probably overkill> 351234518Sjkim */ 352240716Sjkim sprintf (MsgBuffer, "Max %u", Gbl_LineBufferSize); 353234518Sjkim AslCommonError (ASL_WARNING, ASL_MSG_LONG_LINE, 354234518Sjkim Gbl_CurrentLineNumber, Gbl_LogicalLineNumber, 355234518Sjkim Gbl_CurrentLineOffset, Gbl_CurrentColumn, 356234518Sjkim Gbl_Files[ASL_FILE_INPUT].Filename, MsgBuffer); 357234518Sjkim#endif 358234518Sjkim 359234518Sjkim AslResetCurrentLineBuffer (); 360234518Sjkim } 361234518Sjkim else if (SourceChar == '\n') 362234518Sjkim { 363234518Sjkim /* End of line */ 364234518Sjkim 365234518Sjkim AslResetCurrentLineBuffer (); 366234518Sjkim } 367234518Sjkim } 368234518Sjkim} 369234518Sjkim 370234518Sjkim 371234518Sjkim/******************************************************************************* 372234518Sjkim * 373234518Sjkim * FUNCTION: count 374234518Sjkim * 375234518Sjkim * PARAMETERS: yytext - Contains the matched keyword. 376234518Sjkim * Type - Keyword/Character type: 377234518Sjkim * 0 = anything except a keyword 378234518Sjkim * 1 = pseudo-keywords 379234518Sjkim * 2 = non-executable ASL keywords 380234518Sjkim * 3 = executable ASL keywords 381234518Sjkim * 382234518Sjkim * RETURN: None 383234518Sjkim * 384234518Sjkim * DESCRIPTION: Count keywords and put them into the line buffer 385234518Sjkim * 386234518Sjkim ******************************************************************************/ 387234518Sjkim 388234518Sjkimstatic void 389234518Sjkimcount ( 390234518Sjkim int Type) 391234518Sjkim{ 392234518Sjkim int i; 393234518Sjkim 394234518Sjkim 395234518Sjkim switch (Type) 396234518Sjkim { 397234518Sjkim case 2: 398250838Sjkim 399234518Sjkim TotalKeywords++; 400234518Sjkim TotalNamedObjects++; 401234518Sjkim break; 402234518Sjkim 403234518Sjkim case 3: 404250838Sjkim 405234518Sjkim TotalKeywords++; 406234518Sjkim TotalExecutableOpcodes++; 407234518Sjkim break; 408246849Sjkim 409246849Sjkim default: 410250838Sjkim 411246849Sjkim break; 412234518Sjkim } 413234518Sjkim 414234518Sjkim for (i = 0; (yytext[i] != 0) && (yytext[i] != EOF); i++) 415234518Sjkim { 416234518Sjkim AslInsertLineBuffer (yytext[i]); 417234518Sjkim *Gbl_LineBufPtr = 0; 418234518Sjkim } 419234518Sjkim} 420234518Sjkim 421234518Sjkim 422234518Sjkim/******************************************************************************* 423234518Sjkim * 424234518Sjkim * FUNCTION: AslDoComment 425234518Sjkim * 426234518Sjkim * PARAMETERS: none 427234518Sjkim * 428234518Sjkim * RETURN: none 429234518Sjkim * 430234518Sjkim * DESCRIPTION: Process a standard comment. 431234518Sjkim * 432234518Sjkim ******************************************************************************/ 433234518Sjkim 434234518Sjkimstatic char 435234518SjkimAslDoComment ( 436234518Sjkim void) 437234518Sjkim{ 438237412Sjkim int c; 439237412Sjkim int c1 = 0; 440234518Sjkim 441234518Sjkim 442234518Sjkim AslInsertLineBuffer ('/'); 443234518Sjkim AslInsertLineBuffer ('*'); 444234518Sjkim 445234518Sjkimloop: 446234518Sjkim 447234518Sjkim /* Eat chars until end-of-comment */ 448234518Sjkim 449237412Sjkim while ((c = input()) != '*' && c != EOF) 450234518Sjkim { 451234518Sjkim AslInsertLineBuffer (c); 452234518Sjkim c1 = c; 453234518Sjkim } 454234518Sjkim 455234518Sjkim if (c == EOF) 456234518Sjkim { 457234518Sjkim goto EarlyEOF; 458234518Sjkim } 459234518Sjkim 460234518Sjkim /* 461234518Sjkim * Check for nested comment -- can help catch cases where a previous 462234518Sjkim * comment was accidently left unterminated 463234518Sjkim */ 464234518Sjkim if ((c1 == '/') && (c == '*')) 465234518Sjkim { 466234518Sjkim AslCommonError (ASL_WARNING, ASL_MSG_NESTED_COMMENT, 467234518Sjkim Gbl_CurrentLineNumber, Gbl_LogicalLineNumber, 468234518Sjkim Gbl_InputByteCount, Gbl_CurrentColumn, 469234518Sjkim Gbl_Files[ASL_FILE_INPUT].Filename, NULL); 470234518Sjkim } 471234518Sjkim 472234518Sjkim /* Comment is closed only if the NEXT character is a slash */ 473234518Sjkim 474234518Sjkim AslInsertLineBuffer (c); 475234518Sjkim 476237412Sjkim if ((c1 = input()) != '/' && c1 != EOF) 477234518Sjkim { 478234518Sjkim unput(c1); 479234518Sjkim goto loop; 480234518Sjkim } 481234518Sjkim 482234518Sjkim if (c1 == EOF) 483234518Sjkim { 484234518Sjkim goto EarlyEOF; 485234518Sjkim } 486234518Sjkim 487234518Sjkim AslInsertLineBuffer (c1); 488234518Sjkim return (TRUE); 489234518Sjkim 490234518Sjkim 491234518SjkimEarlyEOF: 492234518Sjkim /* 493234518Sjkim * Premature End-Of-File 494234518Sjkim */ 495234518Sjkim AslCommonError (ASL_ERROR, ASL_MSG_EARLY_EOF, 496234518Sjkim Gbl_CurrentLineNumber, Gbl_LogicalLineNumber, 497234518Sjkim Gbl_CurrentLineOffset, Gbl_CurrentColumn, 498234518Sjkim Gbl_Files[ASL_FILE_INPUT].Filename, NULL); 499234518Sjkim return (FALSE); 500234518Sjkim} 501234518Sjkim 502234518Sjkim 503234518Sjkim/******************************************************************************* 504234518Sjkim * 505234518Sjkim * FUNCTION: AslDoCommentType2 506234518Sjkim * 507234518Sjkim * PARAMETERS: none 508234518Sjkim * 509234518Sjkim * RETURN: none 510234518Sjkim * 511234518Sjkim * DESCRIPTION: Process a new "//" comment. 512234518Sjkim * 513234518Sjkim ******************************************************************************/ 514234518Sjkim 515234518Sjkimstatic char 516234518SjkimAslDoCommentType2 ( 517234518Sjkim void) 518234518Sjkim{ 519237412Sjkim int c; 520234518Sjkim 521234518Sjkim 522234518Sjkim AslInsertLineBuffer ('/'); 523234518Sjkim AslInsertLineBuffer ('/'); 524234518Sjkim 525237412Sjkim while ((c = input()) != '\n' && c != EOF) 526234518Sjkim { 527234518Sjkim AslInsertLineBuffer (c); 528234518Sjkim } 529234518Sjkim 530234518Sjkim if (c == EOF) 531234518Sjkim { 532234518Sjkim /* End of file is OK, change to newline. Let parser detect EOF later */ 533234518Sjkim 534234518Sjkim c = '\n'; 535234518Sjkim } 536234518Sjkim 537234518Sjkim AslInsertLineBuffer (c); 538234518Sjkim return (TRUE); 539234518Sjkim} 540234518Sjkim 541234518Sjkim 542234518Sjkim/******************************************************************************* 543234518Sjkim * 544234518Sjkim * FUNCTION: AslDoStringLiteral 545234518Sjkim * 546234518Sjkim * PARAMETERS: none 547234518Sjkim * 548234518Sjkim * RETURN: none 549234518Sjkim * 550234518Sjkim * DESCRIPTION: Process a string literal (surrounded by quotes) 551234518Sjkim * 552234518Sjkim ******************************************************************************/ 553234518Sjkim 554234518Sjkimstatic char 555234518SjkimAslDoStringLiteral ( 556234518Sjkim void) 557234518Sjkim{ 558234518Sjkim char *StringBuffer = MsgBuffer; 559234518Sjkim char *EndBuffer = MsgBuffer + ASL_MSG_BUFFER_SIZE; 560234518Sjkim char *CleanString; 561237412Sjkim int StringChar; 562234518Sjkim UINT32 State = ASL_NORMAL_CHAR; 563234518Sjkim UINT32 i = 0; 564234518Sjkim UINT8 Digit; 565234518Sjkim char ConvertBuffer[4]; 566234518Sjkim 567234518Sjkim 568234518Sjkim /* 569234518Sjkim * Eat chars until end-of-literal. 570234518Sjkim * NOTE: Put back the original surrounding quotes into the 571234518Sjkim * source line buffer. 572234518Sjkim */ 573234518Sjkim AslInsertLineBuffer ('\"'); 574237412Sjkim while ((StringChar = input()) != EOF) 575234518Sjkim { 576234518Sjkim AslInsertLineBuffer (StringChar); 577234518Sjkim 578234518SjkimDoCharacter: 579234518Sjkim switch (State) 580234518Sjkim { 581234518Sjkim case ASL_NORMAL_CHAR: 582234518Sjkim 583234518Sjkim switch (StringChar) 584234518Sjkim { 585234518Sjkim case '\\': 586234518Sjkim /* 587241973Sjkim * Special handling for backslash-escape sequence. We will 588234518Sjkim * toss the backslash and translate the escape char(s). 589234518Sjkim */ 590234518Sjkim State = ASL_ESCAPE_SEQUENCE; 591234518Sjkim continue; 592234518Sjkim 593234518Sjkim case '\"': 594234518Sjkim 595234518Sjkim /* String terminator */ 596234518Sjkim 597234518Sjkim goto CompletedString; 598246849Sjkim 599246849Sjkim default: 600250838Sjkim 601246849Sjkim break; 602234518Sjkim } 603234518Sjkim break; 604234518Sjkim 605234518Sjkim 606234518Sjkim case ASL_ESCAPE_SEQUENCE: 607234518Sjkim 608234518Sjkim State = ASL_NORMAL_CHAR; 609234518Sjkim switch (StringChar) 610234518Sjkim { 611234518Sjkim case 'a': 612250838Sjkim 613234518Sjkim StringChar = 0x07; /* BELL */ 614234518Sjkim break; 615234518Sjkim 616234518Sjkim case 'b': 617250838Sjkim 618234518Sjkim StringChar = 0x08; /* BACKSPACE */ 619234518Sjkim break; 620234518Sjkim 621234518Sjkim case 'f': 622250838Sjkim 623234518Sjkim StringChar = 0x0C; /* FORMFEED */ 624234518Sjkim break; 625234518Sjkim 626234518Sjkim case 'n': 627250838Sjkim 628234518Sjkim StringChar = 0x0A; /* LINEFEED */ 629234518Sjkim break; 630234518Sjkim 631234518Sjkim case 'r': 632250838Sjkim 633234518Sjkim StringChar = 0x0D; /* CARRIAGE RETURN*/ 634234518Sjkim break; 635234518Sjkim 636234518Sjkim case 't': 637250838Sjkim 638234518Sjkim StringChar = 0x09; /* HORIZONTAL TAB */ 639234518Sjkim break; 640234518Sjkim 641234518Sjkim case 'v': 642250838Sjkim 643234518Sjkim StringChar = 0x0B; /* VERTICAL TAB */ 644234518Sjkim break; 645234518Sjkim 646234518Sjkim case 'x': 647250838Sjkim 648234518Sjkim State = ASL_HEX_CONSTANT; 649234518Sjkim i = 0; 650234518Sjkim continue; 651234518Sjkim 652234518Sjkim case '\'': /* Single Quote */ 653234518Sjkim case '\"': /* Double Quote */ 654234518Sjkim case '\\': /* Backslash */ 655250838Sjkim 656234518Sjkim break; 657234518Sjkim 658234518Sjkim default: 659234518Sjkim 660234518Sjkim /* Check for an octal digit (0-7) */ 661234518Sjkim 662234518Sjkim if (ACPI_IS_OCTAL_DIGIT (StringChar)) 663234518Sjkim { 664234518Sjkim State = ASL_OCTAL_CONSTANT; 665234518Sjkim ConvertBuffer[0] = StringChar; 666234518Sjkim i = 1; 667234518Sjkim continue; 668234518Sjkim } 669234518Sjkim 670234518Sjkim /* Unknown escape sequence issue warning, but use the character */ 671234518Sjkim 672234518Sjkim AslCommonError (ASL_WARNING, ASL_MSG_INVALID_ESCAPE, 673234518Sjkim Gbl_CurrentLineNumber, Gbl_LogicalLineNumber, 674234518Sjkim Gbl_CurrentLineOffset, Gbl_CurrentColumn, 675234518Sjkim Gbl_Files[ASL_FILE_INPUT].Filename, NULL); 676234518Sjkim break; 677234518Sjkim } 678234518Sjkim break; 679234518Sjkim 680234518Sjkim 681234518Sjkim case ASL_OCTAL_CONSTANT: 682234518Sjkim 683234518Sjkim /* Up to three octal digits allowed */ 684234518Sjkim 685234518Sjkim if (!ACPI_IS_OCTAL_DIGIT (StringChar) || 686234518Sjkim (i > 2)) 687234518Sjkim { 688234518Sjkim /* 689241973Sjkim * Reached end of the constant. Convert the assembled ASCII 690234518Sjkim * string and resume processing of the next character 691234518Sjkim */ 692234518Sjkim ConvertBuffer[i] = 0; 693234518Sjkim Digit = (UINT8) ACPI_STRTOUL (ConvertBuffer, NULL, 8); 694234518Sjkim 695234518Sjkim /* Check for NULL or non-ascii character (ignore if so) */ 696234518Sjkim 697234518Sjkim if ((Digit == 0) || (Digit > ACPI_ASCII_MAX)) 698234518Sjkim { 699234518Sjkim AslCommonError (ASL_WARNING, ASL_MSG_INVALID_STRING, 700234518Sjkim Gbl_CurrentLineNumber, Gbl_LogicalLineNumber, 701234518Sjkim Gbl_CurrentLineOffset, Gbl_CurrentColumn, 702234518Sjkim Gbl_Files[ASL_FILE_INPUT].Filename, NULL); 703234518Sjkim } 704234518Sjkim else 705234518Sjkim { 706234518Sjkim *StringBuffer = (char) Digit; 707234518Sjkim StringBuffer++; 708234518Sjkim if (StringBuffer >= EndBuffer) 709234518Sjkim { 710234518Sjkim goto BufferOverflow; 711234518Sjkim } 712234518Sjkim } 713234518Sjkim 714234518Sjkim State = ASL_NORMAL_CHAR; 715234518Sjkim goto DoCharacter; 716234518Sjkim break; 717234518Sjkim } 718234518Sjkim 719234518Sjkim /* Append another digit of the constant */ 720234518Sjkim 721234518Sjkim ConvertBuffer[i] = StringChar; 722234518Sjkim i++; 723234518Sjkim continue; 724234518Sjkim 725234518Sjkim case ASL_HEX_CONSTANT: 726234518Sjkim 727234518Sjkim /* Up to two hex digits allowed */ 728234518Sjkim 729234518Sjkim if (!ACPI_IS_XDIGIT (StringChar) || 730234518Sjkim (i > 1)) 731234518Sjkim { 732234518Sjkim /* 733241973Sjkim * Reached end of the constant. Convert the assembled ASCII 734234518Sjkim * string and resume processing of the next character 735234518Sjkim */ 736234518Sjkim ConvertBuffer[i] = 0; 737234518Sjkim Digit = (UINT8) ACPI_STRTOUL (ConvertBuffer, NULL, 16); 738234518Sjkim 739234518Sjkim /* Check for NULL or non-ascii character (ignore if so) */ 740234518Sjkim 741234518Sjkim if ((Digit == 0) || (Digit > ACPI_ASCII_MAX)) 742234518Sjkim { 743234518Sjkim AslCommonError (ASL_WARNING, ASL_MSG_INVALID_STRING, 744234518Sjkim Gbl_CurrentLineNumber, Gbl_LogicalLineNumber, 745234518Sjkim Gbl_CurrentLineOffset, Gbl_CurrentColumn, 746234518Sjkim Gbl_Files[ASL_FILE_INPUT].Filename, NULL); 747234518Sjkim } 748234518Sjkim else 749234518Sjkim { 750234518Sjkim *StringBuffer = (char) Digit; 751234518Sjkim StringBuffer++; 752234518Sjkim if (StringBuffer >= EndBuffer) 753234518Sjkim { 754234518Sjkim goto BufferOverflow; 755234518Sjkim } 756234518Sjkim } 757234518Sjkim 758234518Sjkim State = ASL_NORMAL_CHAR; 759234518Sjkim goto DoCharacter; 760234518Sjkim break; 761234518Sjkim } 762234518Sjkim 763234518Sjkim /* Append another digit of the constant */ 764234518Sjkim 765234518Sjkim ConvertBuffer[i] = StringChar; 766234518Sjkim i++; 767234518Sjkim continue; 768246849Sjkim 769246849Sjkim default: 770250838Sjkim 771246849Sjkim break; 772234518Sjkim } 773234518Sjkim 774234518Sjkim /* Save the finished character */ 775234518Sjkim 776234518Sjkim *StringBuffer = StringChar; 777234518Sjkim StringBuffer++; 778234518Sjkim if (StringBuffer >= EndBuffer) 779234518Sjkim { 780234518Sjkim goto BufferOverflow; 781234518Sjkim } 782234518Sjkim } 783234518Sjkim 784234518Sjkim /* 785234518Sjkim * Premature End-Of-File 786234518Sjkim */ 787234518Sjkim AslCommonError (ASL_ERROR, ASL_MSG_EARLY_EOF, 788234518Sjkim Gbl_CurrentLineNumber, Gbl_LogicalLineNumber, 789234518Sjkim Gbl_CurrentLineOffset, Gbl_CurrentColumn, 790234518Sjkim Gbl_Files[ASL_FILE_INPUT].Filename, NULL); 791234518Sjkim return (FALSE); 792234518Sjkim 793234518Sjkim 794234518SjkimCompletedString: 795234518Sjkim /* 796234518Sjkim * Null terminate the input string and copy string to a new buffer 797234518Sjkim */ 798234518Sjkim *StringBuffer = 0; 799234518Sjkim 800234518Sjkim CleanString = UtGetStringBuffer (strlen (MsgBuffer) + 1); 801234518Sjkim if (!CleanString) 802234518Sjkim { 803234518Sjkim AslCommonError (ASL_ERROR, ASL_MSG_MEMORY_ALLOCATION, 804234518Sjkim Gbl_CurrentLineNumber, Gbl_LogicalLineNumber, 805234518Sjkim Gbl_CurrentLineOffset, Gbl_CurrentColumn, 806234518Sjkim Gbl_Files[ASL_FILE_INPUT].Filename, NULL); 807234518Sjkim return (FALSE); 808234518Sjkim } 809234518Sjkim 810234518Sjkim ACPI_STRCPY (CleanString, MsgBuffer); 811234518Sjkim AslCompilerlval.s = CleanString; 812234518Sjkim return (TRUE); 813234518Sjkim 814234518Sjkim 815234518SjkimBufferOverflow: 816234518Sjkim 817234518Sjkim /* Literal was too long */ 818234518Sjkim 819234518Sjkim AslCommonError (ASL_ERROR, ASL_MSG_STRING_LENGTH, 820234518Sjkim Gbl_CurrentLineNumber, Gbl_LogicalLineNumber, 821234518Sjkim Gbl_CurrentLineOffset, Gbl_CurrentColumn, 822234518Sjkim Gbl_Files[ASL_FILE_INPUT].Filename, "Max length 4096"); 823234518Sjkim return (FALSE); 824234518Sjkim} 825