1 /****************************************************************************** 2 * 3 * Module Name: aslsupport.l - Flex/lex scanner C support routines. 4 * NOTE: Included into aslcompile.l, not compiled by itself. 5 * 6 *****************************************************************************/ 7 8 /* 9 * Copyright (C) 2000 - 2023, Intel Corp. 10 * All rights reserved. 11 * 12 * Redistribution and use in source and binary forms, with or without 13 * modification, are permitted provided that the following conditions 14 * are met: 15 * 1. Redistributions of source code must retain the above copyright 16 * notice, this list of conditions, and the following disclaimer, 17 * without modification. 18 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 19 * substantially similar to the "NO WARRANTY" disclaimer below 20 * ("Disclaimer") and any redistribution must be conditioned upon 21 * including a substantially similar Disclaimer requirement for further 22 * binary redistribution. 23 * 3. Neither the names of the above-listed copyright holders nor the names 24 * of any contributors may be used to endorse or promote products derived 25 * from this software without specific prior written permission. 26 * 27 * Alternatively, this software may be distributed under the terms of the 28 * GNU General Public License ("GPL") version 2 as published by the Free 29 * Software Foundation. 30 * 31 * NO WARRANTY 32 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 33 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 34 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 35 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 36 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 37 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 38 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 40 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 41 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 42 * POSSIBILITY OF SUCH DAMAGES. 43 */ 44 45 /* Configuration */ 46 47 #define ASL_SPACES_PER_TAB 4 48 49 #define ASL_NORMAL_CHAR 0 50 #define ASL_ESCAPE_SEQUENCE 1 51 #define ASL_OCTAL_CONSTANT 2 52 #define ASL_HEX_CONSTANT 3 53 54 55 void 56 yyerror (char const *s) 57 { 58 59 AcpiOsPrintf ("YYERROR: %s\n", s); 60 } 61 62 63 /******************************************************************************* 64 * 65 * FUNCTION: AslParserCleanup 66 * 67 * Used to delete the current buffer 68 * 69 ******************************************************************************/ 70 71 void 72 AslParserCleanup ( 73 void) 74 { 75 76 yy_delete_buffer (YY_CURRENT_BUFFER); 77 } 78 79 80 /******************************************************************************* 81 * 82 * FUNCTION: AslDoLineDirective 83 * 84 * PARAMETERS: None. Uses input() to access current source code line 85 * 86 * RETURN: Updates global line number and filename 87 * 88 * DESCRIPTION: Handle #line directives emitted by the preprocessor. 89 * 90 * The #line directive is emitted by the preprocessor, and is used to 91 * pass through line numbers from the original source code file to the 92 * preprocessor output file (.i). This allows any compiler-generated 93 * error messages to be displayed with the correct line number. 94 * 95 ******************************************************************************/ 96 97 static void 98 AslDoLineDirective ( 99 void) 100 { 101 int c; 102 char *Token; 103 UINT32 LineNumber; 104 char *Filename; 105 UINT32 i; 106 107 AslGbl_HasIncludeFiles = TRUE; 108 109 /* Eat the entire line that contains the #line directive */ 110 111 AslGbl_LineBufPtr = AslGbl_CurrentLineBuffer; 112 113 while ((c = input()) != '\n' && c != EOF) 114 { 115 *AslGbl_LineBufPtr = (char) c; 116 AslGbl_LineBufPtr++; 117 } 118 *AslGbl_LineBufPtr = 0; 119 120 /* First argument is the actual line number */ 121 122 Token = strtok (AslGbl_CurrentLineBuffer, " "); 123 if (!Token) 124 { 125 goto ResetAndExit; 126 } 127 128 /* First argument is the line number */ 129 130 LineNumber = (UINT32) UtDoConstant (Token); 131 132 /* Emit the appropriate number of newlines */ 133 134 AslGbl_CurrentColumn = 0; 135 if (LineNumber > AslGbl_CurrentLineNumber) 136 { 137 for (i = 0; i < (LineNumber - AslGbl_CurrentLineNumber); i++) 138 { 139 FlWriteFile (ASL_FILE_SOURCE_OUTPUT, "\n", 1); 140 AslGbl_CurrentColumn++; 141 } 142 } 143 144 FlSetLineNumber (LineNumber); 145 146 /* Second argument is the optional filename (in double quotes) */ 147 148 Token = strtok (NULL, " \""); 149 if (Token) 150 { 151 Filename = UtLocalCacheCalloc (strlen (Token) + 1); 152 strcpy (Filename, Token); 153 FlSetFilename (Filename); 154 } 155 156 /* Third argument is not supported at this time */ 157 158 ResetAndExit: 159 160 /* Reset globals for a new line */ 161 162 AslGbl_CurrentLineOffset += AslGbl_CurrentColumn; 163 AslGbl_CurrentColumn = 0; 164 AslGbl_LineBufPtr = AslGbl_CurrentLineBuffer; 165 } 166 167 168 /******************************************************************************* 169 * 170 * FUNCTION: AslPopInputFileStack 171 * 172 * PARAMETERS: None 173 * 174 * RETURN: 0 if a node was popped, -1 otherwise 175 * 176 * DESCRIPTION: Pop the top of the input file stack and point the parser to 177 * the saved parse buffer contained in the fnode. Also, set the 178 * global line counters to the saved values. This function is 179 * called when an include file reaches EOF. 180 * 181 ******************************************************************************/ 182 183 int 184 AslPopInputFileStack ( 185 void) 186 { 187 ASL_FILE_NODE *Fnode; 188 189 190 AslGbl_PreviousIncludeFilename = AslGbl_Files[ASL_FILE_INPUT].Filename; 191 Fnode = AslGbl_IncludeFileStack; 192 DbgPrint (ASL_PARSE_OUTPUT, 193 "\nPop InputFile Stack, Fnode %p\n", Fnode); 194 195 DbgPrint (ASL_PARSE_OUTPUT, 196 "Include: Closing \"%s\"\n\n", AslGbl_Files[ASL_FILE_INPUT].Filename); 197 198 if (!Fnode) 199 { 200 return (-1); 201 } 202 203 /* Close the current include file */ 204 205 fclose (yyin); 206 207 /* Update the top-of-stack */ 208 209 AslGbl_IncludeFileStack = Fnode->Next; 210 211 /* Reset global line counter and filename */ 212 213 AslGbl_Files[ASL_FILE_INPUT].Filename = Fnode->Filename; 214 AslGbl_CurrentLineNumber = Fnode->CurrentLineNumber; 215 216 /* Point the parser to the popped file */ 217 218 yy_delete_buffer (YY_CURRENT_BUFFER); 219 yy_switch_to_buffer (Fnode->State); 220 221 /* All done with this node */ 222 223 ACPI_FREE (Fnode); 224 return (0); 225 } 226 227 228 /******************************************************************************* 229 * 230 * FUNCTION: AslPushInputFileStack 231 * 232 * PARAMETERS: InputFile - Open file pointer 233 * Filename - Name of the file 234 * 235 * RETURN: None 236 * 237 * DESCRIPTION: Push the InputFile onto the file stack, and point the parser 238 * to this file. Called when an include file is successfully 239 * opened. 240 * 241 ******************************************************************************/ 242 243 void 244 AslPushInputFileStack ( 245 FILE *InputFile, 246 char *Filename) 247 { 248 ASL_FILE_NODE *Fnode; 249 YY_BUFFER_STATE State; 250 251 252 /* Save the current state in an Fnode */ 253 254 Fnode = UtLocalCalloc (sizeof (ASL_FILE_NODE)); 255 256 Fnode->File = yyin; 257 Fnode->Next = AslGbl_IncludeFileStack; 258 Fnode->State = YY_CURRENT_BUFFER; 259 Fnode->Filename = AslGbl_Files[ASL_FILE_INPUT].Filename; 260 Fnode->CurrentLineNumber = AslGbl_CurrentLineNumber; 261 262 /* Push it on the stack */ 263 264 AslGbl_IncludeFileStack = Fnode; 265 266 /* Point the parser to this file */ 267 268 State = yy_create_buffer (InputFile, YY_BUF_SIZE); 269 yy_switch_to_buffer (State); 270 271 DbgPrint (ASL_PARSE_OUTPUT, 272 "\nPush InputFile Stack, returning %p\n\n", InputFile); 273 274 /* Reset the global line count and filename */ 275 276 AslGbl_Files[ASL_FILE_INPUT].Filename = 277 UtLocalCacheCalloc (strlen (Filename) + 1); 278 279 strcpy (AslGbl_Files[ASL_FILE_INPUT].Filename, Filename); 280 281 AslGbl_CurrentLineNumber = 1; 282 yyin = InputFile; 283 284 /* converter: reset the comment state to STANDARD_COMMENT */ 285 286 AslGbl_CommentState.CommentType = STANDARD_COMMENT; 287 } 288 289 290 /******************************************************************************* 291 * 292 * FUNCTION: AslResetCurrentLineBuffer 293 * 294 * PARAMETERS: None 295 * 296 * RETURN: None 297 * 298 * DESCRIPTION: Reset the Line Buffer to zero, increment global line numbers. 299 * 300 ******************************************************************************/ 301 302 void 303 AslResetCurrentLineBuffer ( 304 void) 305 { 306 307 if (AslGbl_Files[ASL_FILE_SOURCE_OUTPUT].Handle) 308 { 309 FlWriteFile (ASL_FILE_SOURCE_OUTPUT, AslGbl_CurrentLineBuffer, 310 AslGbl_LineBufPtr - AslGbl_CurrentLineBuffer); 311 } 312 313 AslGbl_CurrentLineOffset += AslGbl_CurrentColumn; 314 AslGbl_CurrentColumn = 0; 315 316 AslGbl_CurrentLineNumber++; 317 AslGbl_LogicalLineNumber++; 318 AslGbl_LineBufPtr = AslGbl_CurrentLineBuffer; 319 } 320 321 322 /******************************************************************************* 323 * 324 * FUNCTION: AslInsertLineBuffer 325 * 326 * PARAMETERS: SourceChar - One char from the input ASL source file 327 * 328 * RETURN: None 329 * 330 * DESCRIPTION: Put one character of the source file into the temp line buffer 331 * 332 ******************************************************************************/ 333 334 void 335 AslInsertLineBuffer ( 336 int SourceChar) 337 { 338 UINT32 i; 339 UINT32 Count = 1; 340 341 342 if (SourceChar == EOF) 343 { 344 return; 345 } 346 347 AslGbl_InputByteCount++; 348 349 /* Handle tabs. Convert to spaces */ 350 351 if (SourceChar == '\t') 352 { 353 SourceChar = ' '; 354 Count = ASL_SPACES_PER_TAB - 355 (AslGbl_CurrentColumn & (ASL_SPACES_PER_TAB-1)); 356 } 357 358 for (i = 0; i < Count; i++) 359 { 360 AslGbl_CurrentColumn++; 361 362 /* Insert the character into the line buffer */ 363 364 *AslGbl_LineBufPtr = (UINT8) SourceChar; 365 AslGbl_LineBufPtr++; 366 367 if (AslGbl_LineBufPtr > 368 (AslGbl_CurrentLineBuffer + (AslGbl_LineBufferSize - 1))) 369 { 370 #if 0 371 /* 372 * Warning if we have split a long source line. 373 * <Probably overkill> 374 */ 375 snprintf (AslGbl_MsgBuffer, sizeof(AslGbl_MsgBuffer), "Max %u", Gbl_LineBufferSize); 376 AslCommonError (ASL_WARNING, ASL_MSG_LONG_LINE, 377 AslGbl_CurrentLineNumber, AslGbl_LogicalLineNumber, 378 AslGbl_CurrentLineOffset, AslGbl_CurrentColumn, 379 AslGbl_Files[ASL_FILE_INPUT].Filename, MsgBuffer); 380 #endif 381 382 AslResetCurrentLineBuffer (); 383 } 384 else if (SourceChar == '\n') 385 { 386 /* End of line */ 387 388 AslResetCurrentLineBuffer (); 389 } 390 391 if (AcpiGbl_CaptureComments) 392 { 393 CvProcessCommentState ((char) SourceChar); 394 } 395 } 396 } 397 398 399 /******************************************************************************* 400 * 401 * FUNCTION: count 402 * 403 * PARAMETERS: yytext - Contains the matched keyword. 404 * Type - Keyword/Character type: 405 * 0 = anything except a keyword 406 * 1 = pseudo-keywords 407 * 2 = non-executable ASL keywords 408 * 3 = executable ASL keywords 409 * 410 * RETURN: None 411 * 412 * DESCRIPTION: Count keywords and put them into the line buffer 413 * 414 ******************************************************************************/ 415 416 static void 417 count ( 418 int Type) 419 { 420 char *p; 421 422 423 switch (Type) 424 { 425 case 2: 426 427 ++AslGbl_TotalKeywords; 428 ++AslGbl_TotalNamedObjects; 429 ++AslGbl_FilesList->TotalKeywords; 430 ++AslGbl_FilesList->TotalNamedObjects; 431 break; 432 433 case 3: 434 435 ++AslGbl_TotalKeywords; 436 ++AslGbl_TotalExecutableOpcodes; 437 ++AslGbl_FilesList->TotalKeywords; 438 ++AslGbl_FilesList->TotalExecutableOpcodes; 439 break; 440 441 default: 442 443 break; 444 } 445 446 for (p = yytext; *p != '\0'; p++) 447 { 448 AslInsertLineBuffer (*p); 449 *AslGbl_LineBufPtr = 0; 450 } 451 } 452 453 454 /******************************************************************************* 455 * 456 * FUNCTION: AslDoComment 457 * 458 * PARAMETERS: none 459 * 460 * RETURN: none 461 * 462 * DESCRIPTION: Process a standard comment. 463 * 464 ******************************************************************************/ 465 466 static BOOLEAN 467 AslDoComment ( 468 void) 469 { 470 int c; 471 int c1 = 0; 472 char *StringBuffer = AslGbl_MsgBuffer; 473 char *EndBuffer = AslGbl_MsgBuffer + ASL_MSG_BUFFER_SIZE; 474 ASL_COMMENT_STATE CurrentState = AslGbl_CommentState; /* to reference later on */ 475 476 477 AslInsertLineBuffer ('/'); 478 AslInsertLineBuffer ('*'); 479 if (AcpiGbl_CaptureComments && CurrentState.CaptureComments) 480 { 481 *StringBuffer = '/'; 482 ++StringBuffer; 483 *StringBuffer = '*'; 484 ++StringBuffer; 485 } 486 487 loop: 488 489 /* Eat chars until end-of-comment */ 490 491 while (((c = input ()) != '*') && (c != EOF)) 492 { 493 AslInsertLineBuffer (c); 494 if (AcpiGbl_CaptureComments && CurrentState.CaptureComments) 495 { 496 *StringBuffer = (char) c; 497 ++StringBuffer; 498 } 499 c1 = c; 500 } 501 502 if (c == EOF) 503 { 504 goto EarlyEOF; 505 } 506 507 /* 508 * Check for nested comment -- can help catch cases where a previous 509 * comment was accidentally left unterminated 510 */ 511 if ((c1 == '/') && (c == '*')) 512 { 513 AslCommonError (ASL_WARNING, ASL_MSG_NESTED_COMMENT, 514 AslGbl_CurrentLineNumber, AslGbl_LogicalLineNumber, 515 AslGbl_InputByteCount, AslGbl_CurrentColumn, 516 AslGbl_Files[ASL_FILE_INPUT].Filename, NULL); 517 } 518 519 /* Comment is closed only if the NEXT character is a slash */ 520 521 AslInsertLineBuffer (c); 522 if (AcpiGbl_CaptureComments && CurrentState.CaptureComments) 523 { 524 *StringBuffer = (char) c; 525 ++StringBuffer; 526 } 527 528 if (((c1 = input ()) != '/') && (c1 != EOF)) 529 { 530 unput (c1); 531 goto loop; 532 } 533 534 if (c1 == EOF) 535 { 536 goto EarlyEOF; 537 } 538 if (StringBuffer > EndBuffer) 539 { 540 goto BufferOverflow; 541 } 542 543 AslInsertLineBuffer (c1); 544 CvProcessComment (CurrentState, StringBuffer, c1); 545 return (TRUE); 546 547 548 EarlyEOF: 549 /* 550 * Premature End-Of-File 551 */ 552 AslCommonError (ASL_ERROR, ASL_MSG_EARLY_EOF, 553 AslGbl_CurrentLineNumber, AslGbl_LogicalLineNumber, 554 AslGbl_CurrentLineOffset, AslGbl_CurrentColumn, 555 AslGbl_Files[ASL_FILE_INPUT].Filename, NULL); 556 return (FALSE); 557 558 559 BufferOverflow: 560 561 /* Comment was too long */ 562 563 AslCommonError (ASL_ERROR, ASL_MSG_STRING_LENGTH, 564 AslGbl_CurrentLineNumber, AslGbl_LogicalLineNumber, 565 AslGbl_CurrentLineOffset, AslGbl_CurrentColumn, 566 AslGbl_Files[ASL_FILE_INPUT].Filename, "Max length 4096"); 567 return (FALSE); 568 569 } 570 571 572 /******************************************************************************* 573 * 574 * FUNCTION: AslDoCommentType2 575 * 576 * PARAMETERS: none 577 * 578 * RETURN: none 579 * 580 * DESCRIPTION: Process a new "//" comment. Inline comments will be converted 581 * to "/ *" standard comments. 582 * 583 ******************************************************************************/ 584 585 static BOOLEAN 586 AslDoCommentType2 ( 587 void) 588 { 589 int c; 590 char *StringBuffer = AslGbl_MsgBuffer; 591 char *EndBuffer = AslGbl_MsgBuffer + ASL_MSG_BUFFER_SIZE; 592 ASL_COMMENT_STATE CurrentState = AslGbl_CommentState; 593 594 595 AslInsertLineBuffer ('/'); 596 597 if (AcpiGbl_CaptureComments && CurrentState.CaptureComments) 598 { 599 AslInsertLineBuffer ('*'); 600 *StringBuffer = '/'; 601 ++StringBuffer; 602 *StringBuffer = '*'; 603 ++StringBuffer; 604 } 605 else 606 { 607 AslInsertLineBuffer ('/'); 608 } 609 610 while (((c = input ()) != '\n') && (c != EOF)) 611 { 612 AslInsertLineBuffer (c); 613 if (AcpiGbl_CaptureComments && CurrentState.CaptureComments) 614 { 615 *StringBuffer = (char) c; 616 ++StringBuffer; 617 } 618 } 619 620 if (c == EOF) 621 { 622 /* End of file is OK, change to newline. Let parser detect EOF later */ 623 624 c = '\n'; 625 } 626 627 if (StringBuffer > EndBuffer) 628 { 629 goto BufferOverflow; 630 } 631 AslInsertLineBuffer (c); 632 633 CvProcessCommentType2 (CurrentState, StringBuffer); 634 return (TRUE); 635 636 637 BufferOverflow: 638 639 /* Comment was too long */ 640 641 AslCommonError (ASL_ERROR, ASL_MSG_STRING_LENGTH, 642 AslGbl_CurrentLineNumber, AslGbl_LogicalLineNumber, 643 AslGbl_CurrentLineOffset, AslGbl_CurrentColumn, 644 AslGbl_Files[ASL_FILE_INPUT].Filename, "Max length 4096"); 645 return (FALSE); 646 647 } 648 649 650 /******************************************************************************* 651 * 652 * FUNCTION: AslDoStringLiteral 653 * 654 * PARAMETERS: none 655 * 656 * RETURN: none 657 * 658 * DESCRIPTION: Process a string literal (surrounded by quotes) 659 * 660 ******************************************************************************/ 661 662 static char 663 AslDoStringLiteral ( 664 void) 665 { 666 char *StringBuffer = AslGbl_MsgBuffer; 667 char *EndBuffer = AslGbl_MsgBuffer + ASL_MSG_BUFFER_SIZE; 668 char *CleanString; 669 int StringChar; 670 UINT32 State = ASL_NORMAL_CHAR; 671 UINT32 i = 0; 672 UINT8 Digit; 673 char ConvertBuffer[4]; 674 675 676 /* 677 * Eat chars until end-of-literal. 678 * NOTE: Put back the original surrounding quotes into the 679 * source line buffer. 680 */ 681 AslInsertLineBuffer ('\"'); 682 while ((StringChar = input()) != EOF) 683 { 684 AslInsertLineBuffer (StringChar); 685 686 DoCharacter: 687 switch (State) 688 { 689 case ASL_NORMAL_CHAR: 690 691 switch (StringChar) 692 { 693 case '\\': 694 /* 695 * Special handling for backslash-escape sequence. We will 696 * toss the backslash and translate the escape char(s). 697 */ 698 State = ASL_ESCAPE_SEQUENCE; 699 continue; 700 701 case '\"': 702 703 /* String terminator */ 704 705 goto CompletedString; 706 707 default: 708 709 break; 710 } 711 break; 712 713 714 case ASL_ESCAPE_SEQUENCE: 715 716 State = ASL_NORMAL_CHAR; 717 switch (StringChar) 718 { 719 case 'a': 720 721 StringChar = 0x07; /* BELL */ 722 break; 723 724 case 'b': 725 726 StringChar = 0x08; /* BACKSPACE */ 727 break; 728 729 case 'f': 730 731 StringChar = 0x0C; /* FORMFEED */ 732 break; 733 734 case 'n': 735 736 StringChar = 0x0A; /* LINEFEED */ 737 break; 738 739 case 'r': 740 741 StringChar = 0x0D; /* CARRIAGE RETURN*/ 742 break; 743 744 case 't': 745 746 StringChar = 0x09; /* HORIZONTAL TAB */ 747 break; 748 749 case 'v': 750 751 StringChar = 0x0B; /* VERTICAL TAB */ 752 break; 753 754 case 'x': 755 756 State = ASL_HEX_CONSTANT; 757 i = 0; 758 continue; 759 760 case '\'': /* Single Quote */ 761 case '\"': /* Double Quote */ 762 case '\\': /* Backslash */ 763 764 break; 765 766 default: 767 768 /* Check for an octal digit (0-7) */ 769 770 if (ACPI_IS_OCTAL_DIGIT (StringChar)) 771 { 772 State = ASL_OCTAL_CONSTANT; 773 ConvertBuffer[0] = (char) StringChar; 774 i = 1; 775 continue; 776 } 777 778 /* Unknown escape sequence issue warning, but use the character */ 779 780 AslCommonError (ASL_WARNING, ASL_MSG_INVALID_ESCAPE, 781 AslGbl_CurrentLineNumber, AslGbl_LogicalLineNumber, 782 AslGbl_CurrentLineOffset, AslGbl_CurrentColumn, 783 AslGbl_Files[ASL_FILE_INPUT].Filename, NULL); 784 break; 785 } 786 break; 787 788 789 case ASL_OCTAL_CONSTANT: 790 791 /* Up to three octal digits allowed */ 792 793 if (!ACPI_IS_OCTAL_DIGIT (StringChar) || 794 (i > 2)) 795 { 796 /* 797 * Reached end of the constant. Convert the assembled ASCII 798 * string and resume processing of the next character 799 */ 800 ConvertBuffer[i] = 0; 801 Digit = (UINT8) strtoul (ConvertBuffer, NULL, 8); 802 803 /* Check for NULL or non-ascii character (ignore if so) */ 804 805 if ((Digit == 0) || (Digit > ACPI_ASCII_MAX)) 806 { 807 AslCommonError (ASL_WARNING, ASL_MSG_INVALID_STRING, 808 AslGbl_CurrentLineNumber, AslGbl_LogicalLineNumber, 809 AslGbl_CurrentLineOffset, AslGbl_CurrentColumn, 810 AslGbl_Files[ASL_FILE_INPUT].Filename, NULL); 811 } 812 else 813 { 814 *StringBuffer = (char) Digit; 815 StringBuffer++; 816 if (StringBuffer >= EndBuffer) 817 { 818 goto BufferOverflow; 819 } 820 } 821 822 State = ASL_NORMAL_CHAR; 823 goto DoCharacter; 824 break; 825 } 826 827 /* Append another digit of the constant */ 828 829 ConvertBuffer[i] = (char) StringChar; 830 i++; 831 continue; 832 833 case ASL_HEX_CONSTANT: 834 835 /* Up to two hex digits allowed */ 836 837 if (!isxdigit (StringChar) || 838 (i > 1)) 839 { 840 /* 841 * Reached end of the constant. Convert the assembled ASCII 842 * string and resume processing of the next character 843 */ 844 ConvertBuffer[i] = 0; 845 Digit = (UINT8) strtoul (ConvertBuffer, NULL, 16); 846 847 /* Check for NULL or non-ascii character (ignore if so) */ 848 849 if ((Digit == 0) || (Digit > ACPI_ASCII_MAX)) 850 { 851 AslCommonError (ASL_WARNING, ASL_MSG_INVALID_STRING, 852 AslGbl_CurrentLineNumber, AslGbl_LogicalLineNumber, 853 AslGbl_CurrentLineOffset, AslGbl_CurrentColumn, 854 AslGbl_Files[ASL_FILE_INPUT].Filename, NULL); 855 } 856 else 857 { 858 *StringBuffer = (char) Digit; 859 StringBuffer++; 860 if (StringBuffer >= EndBuffer) 861 { 862 goto BufferOverflow; 863 } 864 } 865 866 State = ASL_NORMAL_CHAR; 867 goto DoCharacter; 868 break; 869 } 870 871 /* Append another digit of the constant */ 872 873 ConvertBuffer[i] = (char) StringChar; 874 i++; 875 continue; 876 877 default: 878 879 break; 880 } 881 882 /* Save the finished character */ 883 884 *StringBuffer = (char) StringChar; 885 StringBuffer++; 886 if (StringBuffer >= EndBuffer) 887 { 888 goto BufferOverflow; 889 } 890 } 891 892 /* 893 * Premature End-Of-File 894 */ 895 AslCommonError (ASL_ERROR, ASL_MSG_EARLY_EOF, 896 AslGbl_CurrentLineNumber, AslGbl_LogicalLineNumber, 897 AslGbl_CurrentLineOffset, AslGbl_CurrentColumn, 898 AslGbl_Files[ASL_FILE_INPUT].Filename, NULL); 899 return (FALSE); 900 901 902 CompletedString: 903 /* 904 * Null terminate the input string and copy string to a new buffer 905 */ 906 *StringBuffer = 0; 907 908 CleanString = UtLocalCacheCalloc (strlen (AslGbl_MsgBuffer) + 1); 909 strcpy (CleanString, AslGbl_MsgBuffer); 910 AslCompilerlval.s = CleanString; 911 return (TRUE); 912 913 914 BufferOverflow: 915 916 /* Literal was too long */ 917 918 AslCommonError (ASL_ERROR, ASL_MSG_STRING_LENGTH, 919 AslGbl_CurrentLineNumber, AslGbl_LogicalLineNumber, 920 AslGbl_CurrentLineOffset, AslGbl_CurrentColumn, 921 AslGbl_Files[ASL_FILE_INPUT].Filename, "Max length 4096"); 922 return (FALSE); 923 } 924