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 - 2018, 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 MERCHANTIBILITY 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 preprocesser, 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 Gbl_HasIncludeFiles = TRUE; 108 109 /* Eat the entire line that contains the #line directive */ 110 111 Gbl_LineBufPtr = Gbl_CurrentLineBuffer; 112 113 while ((c = input()) != '\n' && c != EOF) 114 { 115 *Gbl_LineBufPtr = c; 116 Gbl_LineBufPtr++; 117 } 118 *Gbl_LineBufPtr = 0; 119 120 /* First argument is the actual line number */ 121 122 Token = strtok (Gbl_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 Gbl_CurrentColumn = 0; 135 if (LineNumber > Gbl_CurrentLineNumber) 136 { 137 for (i = 0; i < (LineNumber - Gbl_CurrentLineNumber); i++) 138 { 139 FlWriteFile (ASL_FILE_SOURCE_OUTPUT, "\n", 1); 140 Gbl_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 = ACPI_ALLOCATE_ZEROED (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 Gbl_CurrentLineOffset += Gbl_CurrentColumn; 163 Gbl_CurrentColumn = 0; 164 Gbl_LineBufPtr = Gbl_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 Gbl_PreviousIncludeFilename = Gbl_Files[ASL_FILE_INPUT].Filename; 191 Fnode = Gbl_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", Gbl_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 Gbl_IncludeFileStack = Fnode->Next; 210 211 /* Reset global line counter and filename */ 212 213 Gbl_Files[ASL_FILE_INPUT].Filename = Fnode->Filename; 214 Gbl_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 = Gbl_IncludeFileStack; 258 Fnode->State = YY_CURRENT_BUFFER; 259 Fnode->Filename = Gbl_Files[ASL_FILE_INPUT].Filename; 260 Fnode->CurrentLineNumber = Gbl_CurrentLineNumber; 261 262 /* Push it on the stack */ 263 264 Gbl_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 Gbl_Files[ASL_FILE_INPUT].Filename = 277 UtLocalCacheCalloc (strlen (Filename) + 1); 278 279 strcpy (Gbl_Files[ASL_FILE_INPUT].Filename, Filename); 280 281 Gbl_CurrentLineNumber = 1; 282 yyin = InputFile; 283 284 /* converter: reset the comment state to STANDARD_COMMENT */ 285 286 Gbl_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 (Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Handle) 308 { 309 FlWriteFile (ASL_FILE_SOURCE_OUTPUT, Gbl_CurrentLineBuffer, 310 Gbl_LineBufPtr - Gbl_CurrentLineBuffer); 311 } 312 313 Gbl_CurrentLineOffset += Gbl_CurrentColumn; 314 Gbl_CurrentColumn = 0; 315 316 Gbl_CurrentLineNumber++; 317 Gbl_LogicalLineNumber++; 318 Gbl_LineBufPtr = Gbl_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 Gbl_InputByteCount++; 348 349 /* Handle tabs. Convert to spaces */ 350 351 if (SourceChar == '\t') 352 { 353 SourceChar = ' '; 354 Count = ASL_SPACES_PER_TAB - 355 (Gbl_CurrentColumn & (ASL_SPACES_PER_TAB-1)); 356 } 357 358 for (i = 0; i < Count; i++) 359 { 360 Gbl_CurrentColumn++; 361 362 /* Insert the character into the line buffer */ 363 364 *Gbl_LineBufPtr = (UINT8) SourceChar; 365 Gbl_LineBufPtr++; 366 367 if (Gbl_LineBufPtr > 368 (Gbl_CurrentLineBuffer + (Gbl_LineBufferSize - 1))) 369 { 370 #if 0 371 /* 372 * Warning if we have split a long source line. 373 * <Probably overkill> 374 */ 375 snprintf (MsgBuffer, sizeof(MsgBuffer), "Max %u", Gbl_LineBufferSize); 376 AslCommonError (ASL_WARNING, ASL_MSG_LONG_LINE, 377 Gbl_CurrentLineNumber, Gbl_LogicalLineNumber, 378 Gbl_CurrentLineOffset, Gbl_CurrentColumn, 379 Gbl_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 (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 TotalKeywords++; 428 TotalNamedObjects++; 429 break; 430 431 case 3: 432 433 TotalKeywords++; 434 TotalExecutableOpcodes++; 435 break; 436 437 default: 438 439 break; 440 } 441 442 for (p = yytext; *p != '\0'; p++) 443 { 444 AslInsertLineBuffer (*p); 445 *Gbl_LineBufPtr = 0; 446 } 447 } 448 449 450 /******************************************************************************* 451 * 452 * FUNCTION: AslDoComment 453 * 454 * PARAMETERS: none 455 * 456 * RETURN: none 457 * 458 * DESCRIPTION: Process a standard comment. 459 * 460 ******************************************************************************/ 461 462 static BOOLEAN 463 AslDoComment ( 464 void) 465 { 466 int c; 467 int c1 = 0; 468 char *StringBuffer = MsgBuffer; 469 char *EndBuffer = MsgBuffer + ASL_MSG_BUFFER_SIZE; 470 ASL_COMMENT_STATE CurrentState = Gbl_CommentState; /* to reference later on */ 471 472 473 AslInsertLineBuffer ('/'); 474 AslInsertLineBuffer ('*'); 475 if (AcpiGbl_CaptureComments && CurrentState.CaptureComments) 476 { 477 *StringBuffer = '/'; 478 ++StringBuffer; 479 *StringBuffer = '*'; 480 ++StringBuffer; 481 } 482 483 loop: 484 485 /* Eat chars until end-of-comment */ 486 487 while (((c = input ()) != '*') && (c != EOF)) 488 { 489 AslInsertLineBuffer (c); 490 if (AcpiGbl_CaptureComments && CurrentState.CaptureComments) 491 { 492 *StringBuffer = c; 493 ++StringBuffer; 494 } 495 c1 = c; 496 } 497 498 if (c == EOF) 499 { 500 goto EarlyEOF; 501 } 502 503 /* 504 * Check for nested comment -- can help catch cases where a previous 505 * comment was accidently left unterminated 506 */ 507 if ((c1 == '/') && (c == '*')) 508 { 509 AslCommonError (ASL_WARNING, ASL_MSG_NESTED_COMMENT, 510 Gbl_CurrentLineNumber, Gbl_LogicalLineNumber, 511 Gbl_InputByteCount, Gbl_CurrentColumn, 512 Gbl_Files[ASL_FILE_INPUT].Filename, NULL); 513 } 514 515 /* Comment is closed only if the NEXT character is a slash */ 516 517 AslInsertLineBuffer (c); 518 if (AcpiGbl_CaptureComments && CurrentState.CaptureComments) 519 { 520 *StringBuffer = c; 521 ++StringBuffer; 522 } 523 524 if (((c1 = input ()) != '/') && (c1 != EOF)) 525 { 526 unput (c1); 527 goto loop; 528 } 529 530 if (c1 == EOF) 531 { 532 goto EarlyEOF; 533 } 534 if (StringBuffer > EndBuffer) 535 { 536 goto BufferOverflow; 537 } 538 539 AslInsertLineBuffer (c1); 540 CvProcessComment (CurrentState, StringBuffer, c1); 541 return (TRUE); 542 543 544 EarlyEOF: 545 /* 546 * Premature End-Of-File 547 */ 548 AslCommonError (ASL_ERROR, ASL_MSG_EARLY_EOF, 549 Gbl_CurrentLineNumber, Gbl_LogicalLineNumber, 550 Gbl_CurrentLineOffset, Gbl_CurrentColumn, 551 Gbl_Files[ASL_FILE_INPUT].Filename, NULL); 552 return (FALSE); 553 554 555 BufferOverflow: 556 557 /* Comment was too long */ 558 559 AslCommonError (ASL_ERROR, ASL_MSG_STRING_LENGTH, 560 Gbl_CurrentLineNumber, Gbl_LogicalLineNumber, 561 Gbl_CurrentLineOffset, Gbl_CurrentColumn, 562 Gbl_Files[ASL_FILE_INPUT].Filename, "Max length 4096"); 563 return (FALSE); 564 565 } 566 567 568 /******************************************************************************* 569 * 570 * FUNCTION: AslDoCommentType2 571 * 572 * PARAMETERS: none 573 * 574 * RETURN: none 575 * 576 * DESCRIPTION: Process a new "//" comment. Inline comments will be converted 577 * to "/ *" standard comments. 578 * 579 ******************************************************************************/ 580 581 static BOOLEAN 582 AslDoCommentType2 ( 583 void) 584 { 585 int c; 586 char *StringBuffer = MsgBuffer; 587 char *EndBuffer = MsgBuffer + ASL_MSG_BUFFER_SIZE; 588 ASL_COMMENT_STATE CurrentState = Gbl_CommentState; 589 590 591 AslInsertLineBuffer ('/'); 592 593 if (AcpiGbl_CaptureComments && CurrentState.CaptureComments) 594 { 595 AslInsertLineBuffer ('*'); 596 *StringBuffer = '/'; 597 ++StringBuffer; 598 *StringBuffer = '*'; 599 ++StringBuffer; 600 } 601 else 602 { 603 AslInsertLineBuffer ('/'); 604 } 605 606 while (((c = input ()) != '\n') && (c != EOF)) 607 { 608 AslInsertLineBuffer (c); 609 if (AcpiGbl_CaptureComments && CurrentState.CaptureComments) 610 { 611 *StringBuffer = c; 612 ++StringBuffer; 613 } 614 } 615 616 if (c == EOF) 617 { 618 /* End of file is OK, change to newline. Let parser detect EOF later */ 619 620 c = '\n'; 621 } 622 623 if (StringBuffer > EndBuffer) 624 { 625 goto BufferOverflow; 626 } 627 AslInsertLineBuffer (c); 628 629 CvProcessCommentType2 (CurrentState, StringBuffer); 630 return (TRUE); 631 632 633 BufferOverflow: 634 635 /* Comment was too long */ 636 637 AslCommonError (ASL_ERROR, ASL_MSG_STRING_LENGTH, 638 Gbl_CurrentLineNumber, Gbl_LogicalLineNumber, 639 Gbl_CurrentLineOffset, Gbl_CurrentColumn, 640 Gbl_Files[ASL_FILE_INPUT].Filename, "Max length 4096"); 641 return (FALSE); 642 643 } 644 645 646 /******************************************************************************* 647 * 648 * FUNCTION: AslDoStringLiteral 649 * 650 * PARAMETERS: none 651 * 652 * RETURN: none 653 * 654 * DESCRIPTION: Process a string literal (surrounded by quotes) 655 * 656 ******************************************************************************/ 657 658 static char 659 AslDoStringLiteral ( 660 void) 661 { 662 char *StringBuffer = MsgBuffer; 663 char *EndBuffer = MsgBuffer + ASL_MSG_BUFFER_SIZE; 664 char *CleanString; 665 int StringChar; 666 UINT32 State = ASL_NORMAL_CHAR; 667 UINT32 i = 0; 668 UINT8 Digit; 669 char ConvertBuffer[4]; 670 671 672 /* 673 * Eat chars until end-of-literal. 674 * NOTE: Put back the original surrounding quotes into the 675 * source line buffer. 676 */ 677 AslInsertLineBuffer ('\"'); 678 while ((StringChar = input()) != EOF) 679 { 680 AslInsertLineBuffer (StringChar); 681 682 DoCharacter: 683 switch (State) 684 { 685 case ASL_NORMAL_CHAR: 686 687 switch (StringChar) 688 { 689 case '\\': 690 /* 691 * Special handling for backslash-escape sequence. We will 692 * toss the backslash and translate the escape char(s). 693 */ 694 State = ASL_ESCAPE_SEQUENCE; 695 continue; 696 697 case '\"': 698 699 /* String terminator */ 700 701 goto CompletedString; 702 703 default: 704 705 break; 706 } 707 break; 708 709 710 case ASL_ESCAPE_SEQUENCE: 711 712 State = ASL_NORMAL_CHAR; 713 switch (StringChar) 714 { 715 case 'a': 716 717 StringChar = 0x07; /* BELL */ 718 break; 719 720 case 'b': 721 722 StringChar = 0x08; /* BACKSPACE */ 723 break; 724 725 case 'f': 726 727 StringChar = 0x0C; /* FORMFEED */ 728 break; 729 730 case 'n': 731 732 StringChar = 0x0A; /* LINEFEED */ 733 break; 734 735 case 'r': 736 737 StringChar = 0x0D; /* CARRIAGE RETURN*/ 738 break; 739 740 case 't': 741 742 StringChar = 0x09; /* HORIZONTAL TAB */ 743 break; 744 745 case 'v': 746 747 StringChar = 0x0B; /* VERTICAL TAB */ 748 break; 749 750 case 'x': 751 752 State = ASL_HEX_CONSTANT; 753 i = 0; 754 continue; 755 756 case '\'': /* Single Quote */ 757 case '\"': /* Double Quote */ 758 case '\\': /* Backslash */ 759 760 break; 761 762 default: 763 764 /* Check for an octal digit (0-7) */ 765 766 if (ACPI_IS_OCTAL_DIGIT (StringChar)) 767 { 768 State = ASL_OCTAL_CONSTANT; 769 ConvertBuffer[0] = StringChar; 770 i = 1; 771 continue; 772 } 773 774 /* Unknown escape sequence issue warning, but use the character */ 775 776 AslCommonError (ASL_WARNING, ASL_MSG_INVALID_ESCAPE, 777 Gbl_CurrentLineNumber, Gbl_LogicalLineNumber, 778 Gbl_CurrentLineOffset, Gbl_CurrentColumn, 779 Gbl_Files[ASL_FILE_INPUT].Filename, NULL); 780 break; 781 } 782 break; 783 784 785 case ASL_OCTAL_CONSTANT: 786 787 /* Up to three octal digits allowed */ 788 789 if (!ACPI_IS_OCTAL_DIGIT (StringChar) || 790 (i > 2)) 791 { 792 /* 793 * Reached end of the constant. Convert the assembled ASCII 794 * string and resume processing of the next character 795 */ 796 ConvertBuffer[i] = 0; 797 Digit = (UINT8) strtoul (ConvertBuffer, NULL, 8); 798 799 /* Check for NULL or non-ascii character (ignore if so) */ 800 801 if ((Digit == 0) || (Digit > ACPI_ASCII_MAX)) 802 { 803 AslCommonError (ASL_WARNING, ASL_MSG_INVALID_STRING, 804 Gbl_CurrentLineNumber, Gbl_LogicalLineNumber, 805 Gbl_CurrentLineOffset, Gbl_CurrentColumn, 806 Gbl_Files[ASL_FILE_INPUT].Filename, NULL); 807 } 808 else 809 { 810 *StringBuffer = (char) Digit; 811 StringBuffer++; 812 if (StringBuffer >= EndBuffer) 813 { 814 goto BufferOverflow; 815 } 816 } 817 818 State = ASL_NORMAL_CHAR; 819 goto DoCharacter; 820 break; 821 } 822 823 /* Append another digit of the constant */ 824 825 ConvertBuffer[i] = StringChar; 826 i++; 827 continue; 828 829 case ASL_HEX_CONSTANT: 830 831 /* Up to two hex digits allowed */ 832 833 if (!isxdigit (StringChar) || 834 (i > 1)) 835 { 836 /* 837 * Reached end of the constant. Convert the assembled ASCII 838 * string and resume processing of the next character 839 */ 840 ConvertBuffer[i] = 0; 841 Digit = (UINT8) strtoul (ConvertBuffer, NULL, 16); 842 843 /* Check for NULL or non-ascii character (ignore if so) */ 844 845 if ((Digit == 0) || (Digit > ACPI_ASCII_MAX)) 846 { 847 AslCommonError (ASL_WARNING, ASL_MSG_INVALID_STRING, 848 Gbl_CurrentLineNumber, Gbl_LogicalLineNumber, 849 Gbl_CurrentLineOffset, Gbl_CurrentColumn, 850 Gbl_Files[ASL_FILE_INPUT].Filename, NULL); 851 } 852 else 853 { 854 *StringBuffer = (char) Digit; 855 StringBuffer++; 856 if (StringBuffer >= EndBuffer) 857 { 858 goto BufferOverflow; 859 } 860 } 861 862 State = ASL_NORMAL_CHAR; 863 goto DoCharacter; 864 break; 865 } 866 867 /* Append another digit of the constant */ 868 869 ConvertBuffer[i] = StringChar; 870 i++; 871 continue; 872 873 default: 874 875 break; 876 } 877 878 /* Save the finished character */ 879 880 *StringBuffer = StringChar; 881 StringBuffer++; 882 if (StringBuffer >= EndBuffer) 883 { 884 goto BufferOverflow; 885 } 886 } 887 888 /* 889 * Premature End-Of-File 890 */ 891 AslCommonError (ASL_ERROR, ASL_MSG_EARLY_EOF, 892 Gbl_CurrentLineNumber, Gbl_LogicalLineNumber, 893 Gbl_CurrentLineOffset, Gbl_CurrentColumn, 894 Gbl_Files[ASL_FILE_INPUT].Filename, NULL); 895 return (FALSE); 896 897 898 CompletedString: 899 /* 900 * Null terminate the input string and copy string to a new buffer 901 */ 902 *StringBuffer = 0; 903 904 CleanString = UtLocalCacheCalloc (strlen (MsgBuffer) + 1); 905 strcpy (CleanString, MsgBuffer); 906 AslCompilerlval.s = CleanString; 907 return (TRUE); 908 909 910 BufferOverflow: 911 912 /* Literal was too long */ 913 914 AslCommonError (ASL_ERROR, ASL_MSG_STRING_LENGTH, 915 Gbl_CurrentLineNumber, Gbl_LogicalLineNumber, 916 Gbl_CurrentLineOffset, Gbl_CurrentColumn, 917 Gbl_Files[ASL_FILE_INPUT].Filename, "Max length 4096"); 918 return (FALSE); 919 } 920