dtio.c revision 234623
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
55static char *
56DtTrim (
57    char                    *String);
58
59static void
60DtLinkField (
61    DT_FIELD                *Field);
62
63static ACPI_STATUS
64DtParseLine (
65    char                    *LineBuffer,
66    UINT32                  Line,
67    UINT32                  Offset);
68
69static void
70DtWriteBinary (
71    DT_SUBTABLE             *Subtable,
72    void                    *Context,
73    void                    *ReturnValue);
74
75static void
76DtDumpBuffer (
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
94static 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
109static char *
110DtTrim (
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
194static void
195DtLinkField (
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
235static ACPI_STATUS
236DtParseLine (
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
409UINT32
410DtGetNextLine (
411    FILE                    *Handle)
412{
413    BOOLEAN                 LineNotAllBlanks = FALSE;
414    UINT32                  State = DT_NORMAL_TEXT;
415    UINT32                  CurrentLineOffset;
416    UINT32                  BeyondBufferCount;
417    UINT32                  i;
418    char                    c;
419
420
421    for (i = 0; i < ASL_LINE_BUFFER_SIZE;)
422    {
423        c = (char) getc (Handle);
424        if (c == EOF)
425        {
426            switch (State)
427            {
428            case DT_START_QUOTED_STRING:
429            case DT_SLASH_ASTERISK_COMMENT:
430            case DT_SLASH_SLASH_COMMENT:
431
432                AcpiOsPrintf ("**** EOF within comment/string %u\n", State);
433                break;
434
435            default:
436                break;
437            }
438
439            return (ASL_EOF);
440        }
441
442        switch (State)
443        {
444        case DT_NORMAL_TEXT:
445
446            /* Normal text, insert char into line buffer */
447
448            Gbl_CurrentLineBuffer[i] = c;
449            switch (c)
450            {
451            case '/':
452                State = DT_START_COMMENT;
453                break;
454
455            case '"':
456                State = DT_START_QUOTED_STRING;
457                LineNotAllBlanks = TRUE;
458                i++;
459                break;
460
461            case '\\':
462                /*
463                 * The continuation char MUST be last char on this line.
464                 * Otherwise, it will be assumed to be a valid ASL char.
465                 */
466                State = DT_MERGE_LINES;
467                break;
468
469            case '\n':
470                CurrentLineOffset = Gbl_NextLineOffset;
471                Gbl_NextLineOffset = (UINT32) ftell (Handle);
472                Gbl_CurrentLineNumber++;
473
474                /*
475                 * Exit if line is complete. Ignore empty lines (only \n)
476                 * or lines that contain nothing but blanks.
477                 */
478                if ((i != 0) && LineNotAllBlanks)
479                {
480                    Gbl_CurrentLineBuffer[i+1] = 0; /* Terminate string */
481                    return (CurrentLineOffset);
482                }
483
484                /* Toss this line and start a new one */
485
486                i = 0;
487                LineNotAllBlanks = FALSE;
488                break;
489
490            default:
491                if (c != ' ')
492                {
493                    LineNotAllBlanks = TRUE;
494                }
495
496                i++;
497                break;
498            }
499            break;
500
501        case DT_START_QUOTED_STRING:
502
503            /* Insert raw chars until end of quoted string */
504
505            Gbl_CurrentLineBuffer[i] = c;
506            i++;
507
508            switch (c)
509            {
510            case '"':
511                State = DT_NORMAL_TEXT;
512                break;
513
514            case '\\':
515                State = DT_ESCAPE_SEQUENCE;
516                break;
517
518            case '\n':
519                AcpiOsPrintf ("ERROR at line %u: Unterminated quoted string\n",
520                    Gbl_CurrentLineNumber++);
521                State = DT_NORMAL_TEXT;
522                break;
523
524            default:    /* Get next character */
525                break;
526            }
527            break;
528
529        case DT_ESCAPE_SEQUENCE:
530
531            /* Just copy the escaped character. TBD: sufficient for table compiler? */
532
533            Gbl_CurrentLineBuffer[i] = c;
534            i++;
535            State = DT_START_QUOTED_STRING;
536            break;
537
538        case DT_START_COMMENT:
539
540            /* Open comment if this character is an asterisk or slash */
541
542            switch (c)
543            {
544            case '*':
545                State = DT_SLASH_ASTERISK_COMMENT;
546                break;
547
548            case '/':
549                State = DT_SLASH_SLASH_COMMENT;
550                break;
551
552            default:    /* Not a comment */
553                i++;    /* Save the preceeding slash */
554                Gbl_CurrentLineBuffer[i] = c;
555                i++;
556                State = DT_NORMAL_TEXT;
557                break;
558            }
559            break;
560
561        case DT_SLASH_ASTERISK_COMMENT:
562
563            /* Ignore chars until an asterisk-slash is found */
564
565            switch (c)
566            {
567            case '\n':
568                Gbl_NextLineOffset = (UINT32) ftell (Handle);
569                Gbl_CurrentLineNumber++;
570                break;
571
572            case '*':
573                State = DT_END_COMMENT;
574                break;
575
576            default:
577                break;
578            }
579            break;
580
581        case DT_SLASH_SLASH_COMMENT:
582
583            /* Ignore chars until end-of-line */
584
585            if (c == '\n')
586            {
587                /* We will exit via the NORMAL_TEXT path */
588
589                ungetc (c, Handle);
590                State = DT_NORMAL_TEXT;
591            }
592            break;
593
594        case DT_END_COMMENT:
595
596            /* End comment if this char is a slash */
597
598            switch (c)
599            {
600            case '/':
601                State = DT_NORMAL_TEXT;
602                break;
603
604            case '\n':
605                CurrentLineOffset = Gbl_NextLineOffset;
606                Gbl_NextLineOffset = (UINT32) ftell (Handle);
607                Gbl_CurrentLineNumber++;
608                break;
609
610            case '*':
611                /* Consume all adjacent asterisks */
612                break;
613
614            default:
615                State = DT_SLASH_ASTERISK_COMMENT;
616                break;
617            }
618            break;
619
620        case DT_MERGE_LINES:
621
622            if (c != '\n')
623            {
624                /*
625                 * This is not a continuation backslash, it is a normal
626                 * normal ASL backslash - for example: Scope(\_SB_)
627                 */
628                i++; /* Keep the backslash that is already in the buffer */
629
630                ungetc (c, Handle);
631                State = DT_NORMAL_TEXT;
632            }
633            else
634            {
635                /*
636                 * This is a continuation line -- a backlash followed
637                 * immediately by a newline. Insert a space between the
638                 * lines (overwrite the backslash)
639                 */
640                Gbl_CurrentLineBuffer[i] = ' ';
641                i++;
642
643                /* Ignore newline, this will merge the lines */
644
645                CurrentLineOffset = Gbl_NextLineOffset;
646                Gbl_NextLineOffset = (UINT32) ftell (Handle);
647                Gbl_CurrentLineNumber++;
648                State = DT_NORMAL_TEXT;
649            }
650            break;
651
652        default:
653            DtFatal (ASL_MSG_COMPILER_INTERNAL, NULL, "Unknown input state");
654            return (ASL_EOF);
655        }
656    }
657
658    /* Line is too long for internal buffer. Determine actual length */
659
660    BeyondBufferCount = 1;
661    c = (char) getc (Handle);
662    while (c != '\n')
663    {
664        c = (char) getc (Handle);
665        BeyondBufferCount++;
666    }
667
668    printf ("ERROR - At %u: Input line (%u bytes) is too long (max %u)\n",
669        Gbl_CurrentLineNumber++, ASL_LINE_BUFFER_SIZE + BeyondBufferCount,
670        ASL_LINE_BUFFER_SIZE);
671    return (ASL_EOF);
672}
673
674
675/******************************************************************************
676 *
677 * FUNCTION:    DtScanFile
678 *
679 * PARAMETERS:  Handle              - Open file handle for the source file
680 *
681 * RETURN:      Pointer to start of the constructed parse tree.
682 *
683 * DESCRIPTION: Scan source file, link all field names and values
684 *              to the global parse tree: Gbl_FieldList
685 *
686 *****************************************************************************/
687
688DT_FIELD *
689DtScanFile (
690    FILE                    *Handle)
691{
692    ACPI_STATUS             Status;
693    UINT32                  Offset;
694    DT_FIELD                *Next;
695
696
697    ACPI_FUNCTION_NAME (DtScanFile);
698
699
700    /* Get the file size */
701
702    Gbl_InputByteCount = DtGetFileSize (Handle);
703
704    Gbl_CurrentLineNumber = 0;
705    Gbl_CurrentLineOffset = 0;
706    Gbl_NextLineOffset = 0;
707
708    /* Scan line-by-line */
709
710    while ((Offset = DtGetNextLine (Handle)) != ASL_EOF)
711    {
712        ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Line %2.2u/%4.4X - %s",
713            Gbl_CurrentLineNumber, Offset, Gbl_CurrentLineBuffer));
714
715        Status = DtParseLine (Gbl_CurrentLineBuffer, Gbl_CurrentLineNumber, Offset);
716        if (Status == AE_NOT_FOUND)
717        {
718            break;
719        }
720    }
721
722    /* Dump the parse tree if debug enabled */
723
724    if (Gbl_DebugFlag)
725    {
726        Next = Gbl_FieldList;
727        DbgPrint (ASL_DEBUG_OUTPUT, "Tree:  %32s %32s %8s %8s %8s %8s %8s %8s\n\n",
728            "Name", "Value", "Line", "ByteOff", "NameCol", "Column", "TableOff", "Flags");
729
730        while (Next)
731        {
732            DbgPrint (ASL_DEBUG_OUTPUT, "Field: %32.32s %32.32s %.8X %.8X %.8X %.8X %.8X %.8X\n",
733                Next->Name,
734                Next->Value,
735                Next->Line,
736                Next->ByteOffset,
737                Next->NameColumn,
738                Next->Column,
739                Next->TableOffset,
740                Next->Flags);
741
742            Next = Next->Next;
743        }
744    }
745
746    return (Gbl_FieldList);
747}
748
749
750/*
751 * Output functions
752 */
753
754/******************************************************************************
755 *
756 * FUNCTION:    DtWriteBinary
757 *
758 * PARAMETERS:  DT_WALK_CALLBACK
759 *
760 * RETURN:      Status
761 *
762 * DESCRIPTION: Write one subtable of a binary ACPI table
763 *
764 *****************************************************************************/
765
766static void
767DtWriteBinary (
768    DT_SUBTABLE             *Subtable,
769    void                    *Context,
770    void                    *ReturnValue)
771{
772
773    FlWriteFile (ASL_FILE_AML_OUTPUT, Subtable->Buffer, Subtable->Length);
774}
775
776
777/******************************************************************************
778 *
779 * FUNCTION:    DtOutputBinary
780 *
781 * PARAMETERS:
782 *
783 * RETURN:      Status
784 *
785 * DESCRIPTION: Write entire binary ACPI table (result of compilation)
786 *
787 *****************************************************************************/
788
789void
790DtOutputBinary (
791    DT_SUBTABLE             *RootTable)
792{
793
794    if (!RootTable)
795    {
796        return;
797    }
798
799    /* Walk the entire parse tree, emitting the binary data */
800
801    DtWalkTableTree (RootTable, DtWriteBinary, NULL, NULL);
802    Gbl_TableLength = DtGetFileSize (Gbl_Files[ASL_FILE_AML_OUTPUT].Handle);
803}
804
805
806/*
807 * Listing support
808 */
809
810/******************************************************************************
811 *
812 * FUNCTION:    DtDumpBuffer
813 *
814 * PARAMETERS:  FileID              - Where to write buffer data
815 *              Buffer              - Buffer to dump
816 *              Offset              - Offset in current table
817 *              Length              - Buffer Length
818 *
819 * RETURN:      None
820 *
821 * DESCRIPTION: Another copy of DumpBuffer routine (unfortunately).
822 *
823 * TBD: merge dump buffer routines
824 *
825 *****************************************************************************/
826
827static void
828DtDumpBuffer (
829    UINT32                  FileId,
830    UINT8                   *Buffer,
831    UINT32                  Offset,
832    UINT32                  Length)
833{
834    UINT32                  i;
835    UINT32                  j;
836    UINT8                   BufChar;
837
838
839    FlPrintFile (FileId, "Output: [%3.3Xh %4.4d %3d] ",
840        Offset, Offset, Length);
841
842    i = 0;
843    while (i < Length)
844    {
845        if (i >= 16)
846        {
847            FlPrintFile (FileId, "%24s", "");
848        }
849
850        /* Print 16 hex chars */
851
852        for (j = 0; j < 16;)
853        {
854            if (i + j >= Length)
855            {
856                /* Dump fill spaces */
857
858                FlPrintFile (FileId, "   ");
859                j++;
860                continue;
861            }
862
863            FlPrintFile (FileId, "%02X ", Buffer[i+j]);
864            j++;
865        }
866
867        FlPrintFile (FileId, " ");
868        for (j = 0; j < 16; j++)
869        {
870            if (i + j >= Length)
871            {
872                FlPrintFile (FileId, "\n\n");
873                return;
874            }
875
876            BufChar = Buffer[(ACPI_SIZE) i + j];
877            if (ACPI_IS_PRINT (BufChar))
878            {
879                FlPrintFile (FileId, "%c", BufChar);
880            }
881            else
882            {
883                FlPrintFile (FileId, ".");
884            }
885        }
886
887        /* Done with that line. */
888
889        FlPrintFile (FileId, "\n");
890        i += 16;
891    }
892
893    FlPrintFile (FileId, "\n\n");
894}
895
896
897/******************************************************************************
898 *
899 * FUNCTION:    DtWriteFieldToListing
900 *
901 * PARAMETERS:  Buffer              - Contains the compiled data
902 *              Field               - Field node for the input line
903 *              Length              - Length of the output data
904 *
905 * RETURN:      None
906 *
907 * DESCRIPTION: Write one field to the listing file (if listing is enabled).
908 *
909 *****************************************************************************/
910
911void
912DtWriteFieldToListing (
913    UINT8                   *Buffer,
914    DT_FIELD                *Field,
915    UINT32                  Length)
916{
917    UINT8                   FileByte;
918
919
920    if (!Gbl_ListingFlag || !Field)
921    {
922        return;
923    }
924
925    /* Dump the original source line */
926
927    FlPrintFile (ASL_FILE_LISTING_OUTPUT, "Input:  ");
928    FlSeekFile (ASL_FILE_INPUT, Field->ByteOffset);
929
930    while (FlReadFile (ASL_FILE_INPUT, &FileByte, 1) == AE_OK)
931    {
932        FlWriteFile (ASL_FILE_LISTING_OUTPUT, &FileByte, 1);
933        if (FileByte == '\n')
934        {
935            break;
936        }
937    }
938
939    /* Dump the line as parsed and represented internally */
940
941    FlPrintFile (ASL_FILE_LISTING_OUTPUT, "Parsed: %*s : %.64s",
942        Field->Column-4, Field->Name, Field->Value);
943
944    if (strlen (Field->Value) > 64)
945    {
946        FlPrintFile (ASL_FILE_LISTING_OUTPUT, "...Additional data, length 0x%X\n",
947            strlen (Field->Value));
948    }
949    FlPrintFile (ASL_FILE_LISTING_OUTPUT, "\n");
950
951    /* Dump the hex data that will be output for this field */
952
953    DtDumpBuffer (ASL_FILE_LISTING_OUTPUT, Buffer, Field->TableOffset, Length);
954}
955
956
957/******************************************************************************
958 *
959 * FUNCTION:    DtWriteTableToListing
960 *
961 * PARAMETERS:  None
962 *
963 * RETURN:      None
964 *
965 * DESCRIPTION: Write the entire compiled table to the listing file
966 *              in hex format
967 *
968 *****************************************************************************/
969
970void
971DtWriteTableToListing (
972    void)
973{
974    UINT8                   *Buffer;
975
976
977    if (!Gbl_ListingFlag)
978    {
979        return;
980    }
981
982    /* Read the entire table from the output file */
983
984    Buffer = UtLocalCalloc (Gbl_TableLength);
985    FlSeekFile (ASL_FILE_AML_OUTPUT, 0);
986    FlReadFile (ASL_FILE_AML_OUTPUT, Buffer, Gbl_TableLength);
987
988    /* Dump the raw table data */
989
990    AcpiOsRedirectOutput (Gbl_Files[ASL_FILE_LISTING_OUTPUT].Handle);
991
992    AcpiOsPrintf ("\n%s: Length %d (0x%X)\n\n",
993        ACPI_RAW_TABLE_DATA_HEADER, Gbl_TableLength, Gbl_TableLength);
994    AcpiUtDumpBuffer2 (Buffer, Gbl_TableLength, DB_BYTE_DISPLAY);
995
996    AcpiOsRedirectOutput (stdout);
997}
998