xref: /freebsd/sys/contrib/dev/acpica/compiler/dtio.c (revision 6486b015fc84e96725fef22b0e3363351399ae83)
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                  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 
688 DT_FIELD *
689 DtScanFile (
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 
766 static void
767 DtWriteBinary (
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 
789 void
790 DtOutputBinary (
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 
827 static void
828 DtDumpBuffer (
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 
911 void
912 DtWriteFieldToListing (
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 
970 void
971 DtWriteTableToListing (
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