1 /****************************************************************************** 2 * 3 * Module Name: dtio.c - File I/O support for data table compiler 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2012, Intel Corp. 9 * All rights reserved. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions, and the following disclaimer, 16 * without modification. 17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18 * substantially similar to the "NO WARRANTY" disclaimer below 19 * ("Disclaimer") and any redistribution must be conditioned upon 20 * including a substantially similar Disclaimer requirement for further 21 * binary redistribution. 22 * 3. Neither the names of the above-listed copyright holders nor the names 23 * of any contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * Alternatively, this software may be distributed under the terms of the 27 * GNU General Public License ("GPL") version 2 as published by the Free 28 * Software Foundation. 29 * 30 * NO WARRANTY 31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41 * POSSIBILITY OF SUCH DAMAGES. 42 */ 43 44 #define __DTIO_C__ 45 46 #include <contrib/dev/acpica/compiler/aslcompiler.h> 47 #include <contrib/dev/acpica/compiler/dtcompiler.h> 48 49 #define _COMPONENT DT_COMPILER 50 ACPI_MODULE_NAME ("dtio") 51 52 53 /* Local prototypes */ 54 55 static char * 56 DtTrim ( 57 char *String); 58 59 static void 60 DtLinkField ( 61 DT_FIELD *Field); 62 63 static ACPI_STATUS 64 DtParseLine ( 65 char *LineBuffer, 66 UINT32 Line, 67 UINT32 Offset); 68 69 static void 70 DtWriteBinary ( 71 DT_SUBTABLE *Subtable, 72 void *Context, 73 void *ReturnValue); 74 75 static void 76 DtDumpBuffer ( 77 UINT32 FileId, 78 UINT8 *Buffer, 79 UINT32 Offset, 80 UINT32 Length); 81 82 83 /* States for DtGetNextLine */ 84 85 #define DT_NORMAL_TEXT 0 86 #define DT_START_QUOTED_STRING 1 87 #define DT_START_COMMENT 2 88 #define DT_SLASH_ASTERISK_COMMENT 3 89 #define DT_SLASH_SLASH_COMMENT 4 90 #define DT_END_COMMENT 5 91 #define DT_MERGE_LINES 6 92 #define DT_ESCAPE_SEQUENCE 7 93 94 static UINT32 Gbl_NextLineOffset; 95 96 97 /****************************************************************************** 98 * 99 * FUNCTION: DtTrim 100 * 101 * PARAMETERS: String - Current source code line to trim 102 * 103 * RETURN: Trimmed line. Must be freed by caller. 104 * 105 * DESCRIPTION: Trim left and right spaces 106 * 107 *****************************************************************************/ 108 109 static char * 110 DtTrim ( 111 char *String) 112 { 113 char *Start; 114 char *End; 115 char *ReturnString; 116 ACPI_SIZE Length; 117 118 119 /* Skip lines that start with a space */ 120 121 if (!ACPI_STRCMP (String, " ")) 122 { 123 ReturnString = UtLocalCalloc (1); 124 return (ReturnString); 125 } 126 127 /* Setup pointers to start and end of input string */ 128 129 Start = String; 130 End = String + ACPI_STRLEN (String) - 1; 131 132 /* Find first non-whitespace character */ 133 134 while ((Start <= End) && ((*Start == ' ') || (*Start == '\t'))) 135 { 136 Start++; 137 } 138 139 /* Find last non-space character */ 140 141 while (End >= Start) 142 { 143 if (*End == '\r' || *End == '\n') 144 { 145 End--; 146 continue; 147 } 148 149 if (*End != ' ') 150 { 151 break; 152 } 153 154 End--; 155 } 156 157 /* Remove any quotes around the string */ 158 159 if (*Start == '\"') 160 { 161 Start++; 162 } 163 if (*End == '\"') 164 { 165 End--; 166 } 167 168 /* Create the trimmed return string */ 169 170 Length = ACPI_PTR_DIFF (End, Start) + 1; 171 ReturnString = UtLocalCalloc (Length + 1); 172 if (ACPI_STRLEN (Start)) 173 { 174 ACPI_STRNCPY (ReturnString, Start, Length); 175 } 176 177 ReturnString[Length] = 0; 178 return (ReturnString); 179 } 180 181 182 /****************************************************************************** 183 * 184 * FUNCTION: DtLinkField 185 * 186 * PARAMETERS: Field - New field object to link 187 * 188 * RETURN: None 189 * 190 * DESCRIPTION: Link one field name and value to the list 191 * 192 *****************************************************************************/ 193 194 static void 195 DtLinkField ( 196 DT_FIELD *Field) 197 { 198 DT_FIELD *Prev; 199 DT_FIELD *Next; 200 201 202 Prev = Next = Gbl_FieldList; 203 204 while (Next) 205 { 206 Prev = Next; 207 Next = Next->Next; 208 } 209 210 if (Prev) 211 { 212 Prev->Next = Field; 213 } 214 else 215 { 216 Gbl_FieldList = Field; 217 } 218 } 219 220 221 /****************************************************************************** 222 * 223 * FUNCTION: DtParseLine 224 * 225 * PARAMETERS: LineBuffer - Current source code line 226 * Line - Current line number in the source 227 * Offset - Current byte offset of the line 228 * 229 * RETURN: Status 230 * 231 * DESCRIPTION: Parse one source line 232 * 233 *****************************************************************************/ 234 235 static ACPI_STATUS 236 DtParseLine ( 237 char *LineBuffer, 238 UINT32 Line, 239 UINT32 Offset) 240 { 241 char *Start; 242 char *End; 243 char *TmpName; 244 char *TmpValue; 245 char *Name; 246 char *Value; 247 char *Colon; 248 UINT32 Length; 249 DT_FIELD *Field; 250 UINT32 Column; 251 UINT32 NameColumn; 252 BOOLEAN IsNullString = FALSE; 253 254 255 if (!LineBuffer) 256 { 257 return (AE_OK); 258 } 259 260 /* All lines after "Raw Table Data" are ingored */ 261 262 if (strstr (LineBuffer, ACPI_RAW_TABLE_DATA_HEADER)) 263 { 264 return (AE_NOT_FOUND); 265 } 266 267 Colon = strchr (LineBuffer, ':'); 268 if (!Colon) 269 { 270 return (AE_OK); 271 } 272 273 Start = LineBuffer; 274 End = Colon; 275 276 while (Start < Colon) 277 { 278 if (*Start == ' ') 279 { 280 Start++; 281 continue; 282 } 283 284 /* Found left bracket, go to the right bracket */ 285 286 if (*Start == '[') 287 { 288 while (Start < Colon && *Start != ']') 289 { 290 Start++; 291 } 292 293 if (Start == Colon) 294 { 295 break; 296 } 297 298 Start++; 299 continue; 300 } 301 302 break; 303 } 304 305 /* 306 * There are two column values. One for the field name, 307 * and one for the field value. 308 */ 309 Column = ACPI_PTR_DIFF (Colon, LineBuffer) + 3; 310 NameColumn = ACPI_PTR_DIFF (Start, LineBuffer) + 1; 311 312 Length = ACPI_PTR_DIFF (End, Start); 313 314 TmpName = UtLocalCalloc (Length + 1); 315 ACPI_STRNCPY (TmpName, Start, Length); 316 Name = DtTrim (TmpName); 317 ACPI_FREE (TmpName); 318 319 Start = End = (Colon + 1); 320 while (*End) 321 { 322 /* Found left quotation, go to the right quotation and break */ 323 324 if (*End == '"') 325 { 326 End++; 327 328 /* Check for an explicit null string */ 329 330 if (*End == '"') 331 { 332 IsNullString = TRUE; 333 } 334 while (*End && (*End != '"')) 335 { 336 End++; 337 } 338 339 End++; 340 break; 341 } 342 343 /* 344 * Special "comment" fields at line end, ignore them. 345 * Note: normal slash-slash and slash-asterisk comments are 346 * stripped already by the DtGetNextLine parser. 347 * 348 * TBD: Perhaps DtGetNextLine should parse the following type 349 * of comments also. 350 */ 351 if (*End == '[') 352 { 353 End--; 354 break; 355 } 356 End++; 357 } 358 359 Length = ACPI_PTR_DIFF (End, Start); 360 TmpValue = UtLocalCalloc (Length + 1); 361 362 ACPI_STRNCPY (TmpValue, Start, Length); 363 Value = DtTrim (TmpValue); 364 ACPI_FREE (TmpValue); 365 366 /* Create a new field object only if we have a valid value field */ 367 368 if ((Value && *Value) || IsNullString) 369 { 370 Field = UtLocalCalloc (sizeof (DT_FIELD)); 371 Field->Name = Name; 372 Field->Value = Value; 373 Field->Line = Line; 374 Field->ByteOffset = Offset; 375 Field->NameColumn = NameColumn; 376 Field->Column = Column; 377 378 DtLinkField (Field); 379 } 380 else /* Ignore this field, it has no valid data */ 381 { 382 ACPI_FREE (Name); 383 ACPI_FREE (Value); 384 } 385 386 return (AE_OK); 387 } 388 389 390 /****************************************************************************** 391 * 392 * FUNCTION: DtGetNextLine 393 * 394 * PARAMETERS: Handle - Open file handle for the source file 395 * 396 * RETURN: Filled line buffer and offset of start-of-line (ASL_EOF on EOF) 397 * 398 * DESCRIPTION: Get the next valid source line. Removes all comments. 399 * Ignores empty lines. 400 * 401 * Handles both slash-asterisk and slash-slash comments. 402 * Also, quoted strings, but no escapes within. 403 * 404 * Line is returned in Gbl_CurrentLineBuffer. 405 * Line number in original file is returned in Gbl_CurrentLineNumber. 406 * 407 *****************************************************************************/ 408 409 UINT32 410 DtGetNextLine ( 411 FILE *Handle) 412 { 413 BOOLEAN LineNotAllBlanks = FALSE; 414 UINT32 State = DT_NORMAL_TEXT; 415 UINT32 CurrentLineOffset; 416 UINT32 i; 417 char c; 418 419 420 for (i = 0; ;) 421 { 422 /* 423 * If line is too long, expand the line buffers. Also increases 424 * Gbl_LineBufferSize. 425 */ 426 if (i >= Gbl_LineBufferSize) 427 { 428 UtExpandLineBuffers (); 429 } 430 431 c = (char) getc (Handle); 432 if (c == EOF) 433 { 434 switch (State) 435 { 436 case DT_START_QUOTED_STRING: 437 case DT_SLASH_ASTERISK_COMMENT: 438 439 AcpiOsPrintf ("**** EOF within comment/string %u\n", State); 440 break; 441 442 default: 443 break; 444 } 445 446 /* Standalone EOF is OK */ 447 448 if (i == 0) 449 { 450 return (ASL_EOF); 451 } 452 453 /* 454 * Received an EOF in the middle of a line. Terminate the 455 * line with a newline. The next call to this function will 456 * return a standalone EOF. Thus, the upper parsing software 457 * never has to deal with an EOF within a valid line (or 458 * the last line does not get tossed on the floor.) 459 */ 460 c = '\n'; 461 State = DT_NORMAL_TEXT; 462 } 463 464 switch (State) 465 { 466 case DT_NORMAL_TEXT: 467 468 /* Normal text, insert char into line buffer */ 469 470 Gbl_CurrentLineBuffer[i] = c; 471 switch (c) 472 { 473 case '/': 474 State = DT_START_COMMENT; 475 break; 476 477 case '"': 478 State = DT_START_QUOTED_STRING; 479 LineNotAllBlanks = TRUE; 480 i++; 481 break; 482 483 case '\\': 484 /* 485 * The continuation char MUST be last char on this line. 486 * Otherwise, it will be assumed to be a valid ASL char. 487 */ 488 State = DT_MERGE_LINES; 489 break; 490 491 case '\n': 492 CurrentLineOffset = Gbl_NextLineOffset; 493 Gbl_NextLineOffset = (UINT32) ftell (Handle); 494 Gbl_CurrentLineNumber++; 495 496 /* 497 * Exit if line is complete. Ignore empty lines (only \n) 498 * or lines that contain nothing but blanks. 499 */ 500 if ((i != 0) && LineNotAllBlanks) 501 { 502 if ((i + 1) >= Gbl_LineBufferSize) 503 { 504 UtExpandLineBuffers (); 505 } 506 507 Gbl_CurrentLineBuffer[i+1] = 0; /* Terminate string */ 508 return (CurrentLineOffset); 509 } 510 511 /* Toss this line and start a new one */ 512 513 i = 0; 514 LineNotAllBlanks = FALSE; 515 break; 516 517 default: 518 if (c != ' ') 519 { 520 LineNotAllBlanks = TRUE; 521 } 522 523 i++; 524 break; 525 } 526 break; 527 528 case DT_START_QUOTED_STRING: 529 530 /* Insert raw chars until end of quoted string */ 531 532 Gbl_CurrentLineBuffer[i] = c; 533 i++; 534 535 switch (c) 536 { 537 case '"': 538 State = DT_NORMAL_TEXT; 539 break; 540 541 case '\\': 542 State = DT_ESCAPE_SEQUENCE; 543 break; 544 545 case '\n': 546 AcpiOsPrintf ("ERROR at line %u: Unterminated quoted string\n", 547 Gbl_CurrentLineNumber++); 548 State = DT_NORMAL_TEXT; 549 break; 550 551 default: /* Get next character */ 552 break; 553 } 554 break; 555 556 case DT_ESCAPE_SEQUENCE: 557 558 /* Just copy the escaped character. TBD: sufficient for table compiler? */ 559 560 Gbl_CurrentLineBuffer[i] = c; 561 i++; 562 State = DT_START_QUOTED_STRING; 563 break; 564 565 case DT_START_COMMENT: 566 567 /* Open comment if this character is an asterisk or slash */ 568 569 switch (c) 570 { 571 case '*': 572 State = DT_SLASH_ASTERISK_COMMENT; 573 break; 574 575 case '/': 576 State = DT_SLASH_SLASH_COMMENT; 577 break; 578 579 default: /* Not a comment */ 580 i++; /* Save the preceeding slash */ 581 if (i >= Gbl_LineBufferSize) 582 { 583 UtExpandLineBuffers (); 584 } 585 586 Gbl_CurrentLineBuffer[i] = c; 587 i++; 588 State = DT_NORMAL_TEXT; 589 break; 590 } 591 break; 592 593 case DT_SLASH_ASTERISK_COMMENT: 594 595 /* Ignore chars until an asterisk-slash is found */ 596 597 switch (c) 598 { 599 case '\n': 600 Gbl_NextLineOffset = (UINT32) ftell (Handle); 601 Gbl_CurrentLineNumber++; 602 break; 603 604 case '*': 605 State = DT_END_COMMENT; 606 break; 607 608 default: 609 break; 610 } 611 break; 612 613 case DT_SLASH_SLASH_COMMENT: 614 615 /* Ignore chars until end-of-line */ 616 617 if (c == '\n') 618 { 619 /* We will exit via the NORMAL_TEXT path */ 620 621 ungetc (c, Handle); 622 State = DT_NORMAL_TEXT; 623 } 624 break; 625 626 case DT_END_COMMENT: 627 628 /* End comment if this char is a slash */ 629 630 switch (c) 631 { 632 case '/': 633 State = DT_NORMAL_TEXT; 634 break; 635 636 case '\n': 637 CurrentLineOffset = Gbl_NextLineOffset; 638 Gbl_NextLineOffset = (UINT32) ftell (Handle); 639 Gbl_CurrentLineNumber++; 640 break; 641 642 case '*': 643 /* Consume all adjacent asterisks */ 644 break; 645 646 default: 647 State = DT_SLASH_ASTERISK_COMMENT; 648 break; 649 } 650 break; 651 652 case DT_MERGE_LINES: 653 654 if (c != '\n') 655 { 656 /* 657 * This is not a continuation backslash, it is a normal 658 * normal ASL backslash - for example: Scope(\_SB_) 659 */ 660 i++; /* Keep the backslash that is already in the buffer */ 661 662 ungetc (c, Handle); 663 State = DT_NORMAL_TEXT; 664 } 665 else 666 { 667 /* 668 * This is a continuation line -- a backlash followed 669 * immediately by a newline. Insert a space between the 670 * lines (overwrite the backslash) 671 */ 672 Gbl_CurrentLineBuffer[i] = ' '; 673 i++; 674 675 /* Ignore newline, this will merge the lines */ 676 677 CurrentLineOffset = Gbl_NextLineOffset; 678 Gbl_NextLineOffset = (UINT32) ftell (Handle); 679 Gbl_CurrentLineNumber++; 680 State = DT_NORMAL_TEXT; 681 } 682 break; 683 684 default: 685 DtFatal (ASL_MSG_COMPILER_INTERNAL, NULL, "Unknown input state"); 686 return (ASL_EOF); 687 } 688 } 689 } 690 691 692 /****************************************************************************** 693 * 694 * FUNCTION: DtScanFile 695 * 696 * PARAMETERS: Handle - Open file handle for the source file 697 * 698 * RETURN: Pointer to start of the constructed parse tree. 699 * 700 * DESCRIPTION: Scan source file, link all field names and values 701 * to the global parse tree: Gbl_FieldList 702 * 703 *****************************************************************************/ 704 705 DT_FIELD * 706 DtScanFile ( 707 FILE *Handle) 708 { 709 ACPI_STATUS Status; 710 UINT32 Offset; 711 DT_FIELD *Next; 712 713 714 ACPI_FUNCTION_NAME (DtScanFile); 715 716 717 /* Get the file size */ 718 719 Gbl_InputByteCount = DtGetFileSize (Handle); 720 721 Gbl_CurrentLineNumber = 0; 722 Gbl_CurrentLineOffset = 0; 723 Gbl_NextLineOffset = 0; 724 725 /* Scan line-by-line */ 726 727 while ((Offset = DtGetNextLine (Handle)) != ASL_EOF) 728 { 729 ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Line %2.2u/%4.4X - %s", 730 Gbl_CurrentLineNumber, Offset, Gbl_CurrentLineBuffer)); 731 732 Status = DtParseLine (Gbl_CurrentLineBuffer, Gbl_CurrentLineNumber, Offset); 733 if (Status == AE_NOT_FOUND) 734 { 735 break; 736 } 737 } 738 739 /* Dump the parse tree if debug enabled */ 740 741 if (Gbl_DebugFlag) 742 { 743 Next = Gbl_FieldList; 744 DbgPrint (ASL_DEBUG_OUTPUT, "Tree: %32s %32s %8s %8s %8s %8s %8s %8s\n\n", 745 "Name", "Value", "Line", "ByteOff", "NameCol", "Column", "TableOff", "Flags"); 746 747 while (Next) 748 { 749 DbgPrint (ASL_DEBUG_OUTPUT, "Field: %32.32s %32.32s %.8X %.8X %.8X %.8X %.8X %.8X\n", 750 Next->Name, 751 Next->Value, 752 Next->Line, 753 Next->ByteOffset, 754 Next->NameColumn, 755 Next->Column, 756 Next->TableOffset, 757 Next->Flags); 758 759 Next = Next->Next; 760 } 761 } 762 763 return (Gbl_FieldList); 764 } 765 766 767 /* 768 * Output functions 769 */ 770 771 /****************************************************************************** 772 * 773 * FUNCTION: DtWriteBinary 774 * 775 * PARAMETERS: DT_WALK_CALLBACK 776 * 777 * RETURN: Status 778 * 779 * DESCRIPTION: Write one subtable of a binary ACPI table 780 * 781 *****************************************************************************/ 782 783 static void 784 DtWriteBinary ( 785 DT_SUBTABLE *Subtable, 786 void *Context, 787 void *ReturnValue) 788 { 789 790 FlWriteFile (ASL_FILE_AML_OUTPUT, Subtable->Buffer, Subtable->Length); 791 } 792 793 794 /****************************************************************************** 795 * 796 * FUNCTION: DtOutputBinary 797 * 798 * PARAMETERS: 799 * 800 * RETURN: Status 801 * 802 * DESCRIPTION: Write entire binary ACPI table (result of compilation) 803 * 804 *****************************************************************************/ 805 806 void 807 DtOutputBinary ( 808 DT_SUBTABLE *RootTable) 809 { 810 811 if (!RootTable) 812 { 813 return; 814 } 815 816 /* Walk the entire parse tree, emitting the binary data */ 817 818 DtWalkTableTree (RootTable, DtWriteBinary, NULL, NULL); 819 Gbl_TableLength = DtGetFileSize (Gbl_Files[ASL_FILE_AML_OUTPUT].Handle); 820 } 821 822 823 /* 824 * Listing support 825 */ 826 827 /****************************************************************************** 828 * 829 * FUNCTION: DtDumpBuffer 830 * 831 * PARAMETERS: FileID - Where to write buffer data 832 * Buffer - Buffer to dump 833 * Offset - Offset in current table 834 * Length - Buffer Length 835 * 836 * RETURN: None 837 * 838 * DESCRIPTION: Another copy of DumpBuffer routine (unfortunately). 839 * 840 * TBD: merge dump buffer routines 841 * 842 *****************************************************************************/ 843 844 static void 845 DtDumpBuffer ( 846 UINT32 FileId, 847 UINT8 *Buffer, 848 UINT32 Offset, 849 UINT32 Length) 850 { 851 UINT32 i; 852 UINT32 j; 853 UINT8 BufChar; 854 855 856 FlPrintFile (FileId, "Output: [%3.3Xh %4.4d %3d] ", 857 Offset, Offset, Length); 858 859 i = 0; 860 while (i < Length) 861 { 862 if (i >= 16) 863 { 864 FlPrintFile (FileId, "%24s", ""); 865 } 866 867 /* Print 16 hex chars */ 868 869 for (j = 0; j < 16;) 870 { 871 if (i + j >= Length) 872 { 873 /* Dump fill spaces */ 874 875 FlPrintFile (FileId, " "); 876 j++; 877 continue; 878 } 879 880 FlPrintFile (FileId, "%02X ", Buffer[i+j]); 881 j++; 882 } 883 884 FlPrintFile (FileId, " "); 885 for (j = 0; j < 16; j++) 886 { 887 if (i + j >= Length) 888 { 889 FlPrintFile (FileId, "\n\n"); 890 return; 891 } 892 893 BufChar = Buffer[(ACPI_SIZE) i + j]; 894 if (ACPI_IS_PRINT (BufChar)) 895 { 896 FlPrintFile (FileId, "%c", BufChar); 897 } 898 else 899 { 900 FlPrintFile (FileId, "."); 901 } 902 } 903 904 /* Done with that line. */ 905 906 FlPrintFile (FileId, "\n"); 907 i += 16; 908 } 909 910 FlPrintFile (FileId, "\n\n"); 911 } 912 913 914 /****************************************************************************** 915 * 916 * FUNCTION: DtWriteFieldToListing 917 * 918 * PARAMETERS: Buffer - Contains the compiled data 919 * Field - Field node for the input line 920 * Length - Length of the output data 921 * 922 * RETURN: None 923 * 924 * DESCRIPTION: Write one field to the listing file (if listing is enabled). 925 * 926 *****************************************************************************/ 927 928 void 929 DtWriteFieldToListing ( 930 UINT8 *Buffer, 931 DT_FIELD *Field, 932 UINT32 Length) 933 { 934 UINT8 FileByte; 935 936 937 if (!Gbl_ListingFlag || !Field) 938 { 939 return; 940 } 941 942 /* Dump the original source line */ 943 944 FlPrintFile (ASL_FILE_LISTING_OUTPUT, "Input: "); 945 FlSeekFile (ASL_FILE_INPUT, Field->ByteOffset); 946 947 while (FlReadFile (ASL_FILE_INPUT, &FileByte, 1) == AE_OK) 948 { 949 FlWriteFile (ASL_FILE_LISTING_OUTPUT, &FileByte, 1); 950 if (FileByte == '\n') 951 { 952 break; 953 } 954 } 955 956 /* Dump the line as parsed and represented internally */ 957 958 FlPrintFile (ASL_FILE_LISTING_OUTPUT, "Parsed: %*s : %.64s", 959 Field->Column-4, Field->Name, Field->Value); 960 961 if (strlen (Field->Value) > 64) 962 { 963 FlPrintFile (ASL_FILE_LISTING_OUTPUT, "...Additional data, length 0x%X\n", 964 strlen (Field->Value)); 965 } 966 FlPrintFile (ASL_FILE_LISTING_OUTPUT, "\n"); 967 968 /* Dump the hex data that will be output for this field */ 969 970 DtDumpBuffer (ASL_FILE_LISTING_OUTPUT, Buffer, Field->TableOffset, Length); 971 } 972 973 974 /****************************************************************************** 975 * 976 * FUNCTION: DtWriteTableToListing 977 * 978 * PARAMETERS: None 979 * 980 * RETURN: None 981 * 982 * DESCRIPTION: Write the entire compiled table to the listing file 983 * in hex format 984 * 985 *****************************************************************************/ 986 987 void 988 DtWriteTableToListing ( 989 void) 990 { 991 UINT8 *Buffer; 992 993 994 if (!Gbl_ListingFlag) 995 { 996 return; 997 } 998 999 /* Read the entire table from the output file */ 1000 1001 Buffer = UtLocalCalloc (Gbl_TableLength); 1002 FlSeekFile (ASL_FILE_AML_OUTPUT, 0); 1003 FlReadFile (ASL_FILE_AML_OUTPUT, Buffer, Gbl_TableLength); 1004 1005 /* Dump the raw table data */ 1006 1007 AcpiOsRedirectOutput (Gbl_Files[ASL_FILE_LISTING_OUTPUT].Handle); 1008 1009 AcpiOsPrintf ("\n%s: Length %d (0x%X)\n\n", 1010 ACPI_RAW_TABLE_DATA_HEADER, Gbl_TableLength, Gbl_TableLength); 1011 AcpiUtDumpBuffer2 (Buffer, Gbl_TableLength, DB_BYTE_DISPLAY); 1012 1013 AcpiOsRedirectOutput (stdout); 1014 } 1015