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