Merge branch 'vendor/FILE'
[dragonfly.git] / sys / contrib / dev / acpica / source / compiler / dtio.c
1 /******************************************************************************
2  *
3  * Module Name: dtio.c - File I/O support for data table compiler
4  *
5  *****************************************************************************/
6
7 /******************************************************************************
8  *
9  * 1. Copyright Notice
10  *
11  * Some or all of this work - Copyright (c) 1999 - 2017, Intel Corp.
12  * All rights reserved.
13  *
14  * 2. License
15  *
16  * 2.1. This is your license from Intel Corp. under its intellectual property
17  * rights. You may have additional license terms from the party that provided
18  * you this software, covering your right to use that party's intellectual
19  * property rights.
20  *
21  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
22  * copy of the source code appearing in this file ("Covered Code") an
23  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
24  * base code distributed originally by Intel ("Original Intel Code") to copy,
25  * make derivatives, distribute, use and display any portion of the Covered
26  * Code in any form, with the right to sublicense such rights; and
27  *
28  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
29  * license (with the right to sublicense), under only those claims of Intel
30  * patents that are infringed by the Original Intel Code, to make, use, sell,
31  * offer to sell, and import the Covered Code and derivative works thereof
32  * solely to the minimum extent necessary to exercise the above copyright
33  * license, and in no event shall the patent license extend to any additions
34  * to or modifications of the Original Intel Code. No other license or right
35  * is granted directly or by implication, estoppel or otherwise;
36  *
37  * The above copyright and patent license is granted only if the following
38  * conditions are met:
39  *
40  * 3. Conditions
41  *
42  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
43  * Redistribution of source code of any substantial portion of the Covered
44  * Code or modification with rights to further distribute source must include
45  * the above Copyright Notice, the above License, this list of Conditions,
46  * and the following Disclaimer and Export Compliance provision. In addition,
47  * Licensee must cause all Covered Code to which Licensee contributes to
48  * contain a file documenting the changes Licensee made to create that Covered
49  * Code and the date of any change. Licensee must include in that file the
50  * documentation of any changes made by any predecessor Licensee. Licensee
51  * must include a prominent statement that the modification is derived,
52  * directly or indirectly, from Original Intel Code.
53  *
54  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
55  * Redistribution of source code of any substantial portion of the Covered
56  * Code or modification without rights to further distribute source must
57  * include the following Disclaimer and Export Compliance provision in the
58  * documentation and/or other materials provided with distribution. In
59  * addition, Licensee may not authorize further sublicense of source of any
60  * portion of the Covered Code, and must include terms to the effect that the
61  * license from Licensee to its licensee is limited to the intellectual
62  * property embodied in the software Licensee provides to its licensee, and
63  * not to intellectual property embodied in modifications its licensee may
64  * make.
65  *
66  * 3.3. Redistribution of Executable. Redistribution in executable form of any
67  * substantial portion of the Covered Code or modification must reproduce the
68  * above Copyright Notice, and the following Disclaimer and Export Compliance
69  * provision in the documentation and/or other materials provided with the
70  * distribution.
71  *
72  * 3.4. Intel retains all right, title, and interest in and to the Original
73  * Intel Code.
74  *
75  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
76  * Intel shall be used in advertising or otherwise to promote the sale, use or
77  * other dealings in products derived from or relating to the Covered Code
78  * without prior written authorization from Intel.
79  *
80  * 4. Disclaimer and Export Compliance
81  *
82  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
83  * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
84  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
85  * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
86  * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
87  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
88  * PARTICULAR PURPOSE.
89  *
90  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
91  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
92  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
93  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
94  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
95  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
96  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
97  * LIMITED REMEDY.
98  *
99  * 4.3. Licensee shall not export, either directly or indirectly, any of this
100  * software or system incorporating such software without first obtaining any
101  * required license or other approval from the U. S. Department of Commerce or
102  * any other agency or department of the United States Government. In the
103  * event Licensee exports any such software from the United States or
104  * re-exports any such software from a foreign destination, Licensee shall
105  * ensure that the distribution and export/re-export of the software is in
106  * compliance with all laws, regulations, orders, or other restrictions of the
107  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
108  * any of its subsidiaries will export/re-export any technical data, process,
109  * software, or service, directly or indirectly, to any country for which the
110  * United States government or any agency thereof requires an export license,
111  * other governmental approval, or letter of assurance, without first obtaining
112  * such license, approval or letter.
113  *
114  *****************************************************************************
115  *
116  * Alternatively, you may choose to be licensed under the terms of the
117  * following license:
118  *
119  * Redistribution and use in source and binary forms, with or without
120  * modification, are permitted provided that the following conditions
121  * are met:
122  * 1. Redistributions of source code must retain the above copyright
123  *    notice, this list of conditions, and the following disclaimer,
124  *    without modification.
125  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
126  *    substantially similar to the "NO WARRANTY" disclaimer below
127  *    ("Disclaimer") and any redistribution must be conditioned upon
128  *    including a substantially similar Disclaimer requirement for further
129  *    binary redistribution.
130  * 3. Neither the names of the above-listed copyright holders nor the names
131  *    of any contributors may be used to endorse or promote products derived
132  *    from this software without specific prior written permission.
133  *
134  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
135  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
136  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
137  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
138  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
139  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
140  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
141  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
142  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
143  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
144  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
145  *
146  * Alternatively, you may choose to be licensed under the terms of the
147  * GNU General Public License ("GPL") version 2 as published by the Free
148  * Software Foundation.
149  *
150  *****************************************************************************/
151
152 #include "aslcompiler.h"
153 #include "dtcompiler.h"
154 #include "acapps.h"
155
156 #define _COMPONENT          DT_COMPILER
157         ACPI_MODULE_NAME    ("dtio")
158
159
160 /* Local prototypes */
161
162 static char *
163 DtTrim (
164     char                    *String);
165
166 static void
167 DtLinkField (
168     DT_FIELD                *Field);
169
170 static ACPI_STATUS
171 DtParseLine (
172     char                    *LineBuffer,
173     UINT32                  Line,
174     UINT32                  Offset);
175
176 static void
177 DtWriteBinary (
178     DT_SUBTABLE             *Subtable,
179     void                    *Context,
180     void                    *ReturnValue);
181
182 static void
183 DtDumpBuffer (
184     UINT32                  FileId,
185     UINT8                   *Buffer,
186     UINT32                  Offset,
187     UINT32                  Length);
188
189 static void
190 DtDumpSubtableInfo (
191     DT_SUBTABLE             *Subtable,
192     void                    *Context,
193     void                    *ReturnValue);
194
195 static void
196 DtDumpSubtableTree (
197     DT_SUBTABLE             *Subtable,
198     void                    *Context,
199     void                    *ReturnValue);
200
201
202 /* States for DtGetNextLine */
203
204 #define DT_NORMAL_TEXT              0
205 #define DT_START_QUOTED_STRING      1
206 #define DT_START_COMMENT            2
207 #define DT_SLASH_ASTERISK_COMMENT   3
208 #define DT_SLASH_SLASH_COMMENT      4
209 #define DT_END_COMMENT              5
210 #define DT_MERGE_LINES              6
211 #define DT_ESCAPE_SEQUENCE          7
212
213 static UINT32               Gbl_NextLineOffset;
214
215
216 /******************************************************************************
217  *
218  * FUNCTION:    DtTrim
219  *
220  * PARAMETERS:  String              - Current source code line to trim
221  *
222  * RETURN:      Trimmed line. Must be freed by caller.
223  *
224  * DESCRIPTION: Trim left and right spaces
225  *
226  *****************************************************************************/
227
228 static char *
229 DtTrim (
230     char                    *String)
231 {
232     char                    *Start;
233     char                    *End;
234     char                    *ReturnString;
235     ACPI_SIZE               Length;
236
237
238     /* Skip lines that start with a space */
239
240     if (!strcmp (String, " "))
241     {
242         ReturnString = UtStringCacheCalloc (1);
243         return (ReturnString);
244     }
245
246     /* Setup pointers to start and end of input string */
247
248     Start = String;
249     End = String + strlen (String) - 1;
250
251     /* Find first non-whitespace character */
252
253     while ((Start <= End) && ((*Start == ' ') || (*Start == '\t')))
254     {
255         Start++;
256     }
257
258     /* Find last non-space character */
259
260     while (End >= Start)
261     {
262         if (*End == '\r' || *End == '\n')
263         {
264             End--;
265             continue;
266         }
267
268         if (*End != ' ')
269         {
270             break;
271         }
272
273         End--;
274     }
275
276     /* Remove any quotes around the string */
277
278     if (*Start == '\"')
279     {
280         Start++;
281     }
282     if (*End == '\"')
283     {
284         End--;
285     }
286
287     /* Create the trimmed return string */
288
289     Length = ACPI_PTR_DIFF (End, Start) + 1;
290     ReturnString = UtStringCacheCalloc (Length + 1);
291     if (strlen (Start))
292     {
293         strncpy (ReturnString, Start, Length);
294     }
295
296     ReturnString[Length] = 0;
297     return (ReturnString);
298 }
299
300
301 /******************************************************************************
302  *
303  * FUNCTION:    DtLinkField
304  *
305  * PARAMETERS:  Field               - New field object to link
306  *
307  * RETURN:      None
308  *
309  * DESCRIPTION: Link one field name and value to the list
310  *
311  *****************************************************************************/
312
313 static void
314 DtLinkField (
315     DT_FIELD                *Field)
316 {
317     DT_FIELD                *Prev;
318     DT_FIELD                *Next;
319
320
321     Prev = Next = Gbl_FieldList;
322
323     while (Next)
324     {
325         Prev = Next;
326         Next = Next->Next;
327     }
328
329     if (Prev)
330     {
331         Prev->Next = Field;
332     }
333     else
334     {
335         Gbl_FieldList = Field;
336     }
337 }
338
339
340 /******************************************************************************
341  *
342  * FUNCTION:    DtParseLine
343  *
344  * PARAMETERS:  LineBuffer          - Current source code line
345  *              Line                - Current line number in the source
346  *              Offset              - Current byte offset of the line
347  *
348  * RETURN:      Status
349  *
350  * DESCRIPTION: Parse one source line
351  *
352  *****************************************************************************/
353
354 static ACPI_STATUS
355 DtParseLine (
356     char                    *LineBuffer,
357     UINT32                  Line,
358     UINT32                  Offset)
359 {
360     char                    *Start;
361     char                    *End;
362     char                    *TmpName;
363     char                    *TmpValue;
364     char                    *Name;
365     char                    *Value;
366     char                    *Colon;
367     UINT32                  Length;
368     DT_FIELD                *Field;
369     UINT32                  Column;
370     UINT32                  NameColumn;
371     BOOLEAN                 IsNullString = FALSE;
372
373
374     if (!LineBuffer)
375     {
376         return (AE_OK);
377     }
378
379     /* All lines after "Raw Table Data" are ingored */
380
381     if (strstr (LineBuffer, ACPI_RAW_TABLE_DATA_HEADER))
382     {
383         return (AE_NOT_FOUND);
384     }
385
386     Colon = strchr (LineBuffer, ':');
387     if (!Colon)
388     {
389         return (AE_OK);
390     }
391
392     Start = LineBuffer;
393     End = Colon;
394
395     while (Start < Colon)
396     {
397         if (*Start == '[')
398         {
399             /* Found left bracket, go to the right bracket */
400
401             while (Start < Colon && *Start != ']')
402             {
403                 Start++;
404             }
405         }
406         else if (*Start != ' ')
407         {
408             break;
409         }
410
411         Start++;
412     }
413
414     /*
415      * There are two column values. One for the field name,
416      * and one for the field value.
417      */
418     Column = ACPI_PTR_DIFF (Colon, LineBuffer) + 3;
419     NameColumn = ACPI_PTR_DIFF (Start, LineBuffer) + 1;
420
421     Length = ACPI_PTR_DIFF (End, Start);
422
423     TmpName = UtLocalCalloc (Length + 1);
424     strncpy (TmpName, Start, Length);
425     Name = DtTrim (TmpName);
426     ACPI_FREE (TmpName);
427
428     Start = End = (Colon + 1);
429     while (*End)
430     {
431         /* Found left quotation, go to the right quotation and break */
432
433         if (*End == '"')
434         {
435             End++;
436
437             /* Check for an explicit null string */
438
439             if (*End == '"')
440             {
441                 IsNullString = TRUE;
442             }
443             while (*End && (*End != '"'))
444             {
445                 End++;
446             }
447
448             End++;
449             break;
450         }
451
452         /*
453          * Special "comment" fields at line end, ignore them.
454          * Note: normal slash-slash and slash-asterisk comments are
455          * stripped already by the DtGetNextLine parser.
456          *
457          * TBD: Perhaps DtGetNextLine should parse the following type
458          * of comments also.
459          */
460         if (*End == '[')
461         {
462             End--;
463             break;
464         }
465
466         End++;
467     }
468
469     Length = ACPI_PTR_DIFF (End, Start);
470     TmpValue = UtLocalCalloc (Length + 1);
471
472     strncpy (TmpValue, Start, Length);
473     Value = DtTrim (TmpValue);
474     ACPI_FREE (TmpValue);
475
476     /* Create a new field object only if we have a valid value field */
477
478     if ((Value && *Value) || IsNullString)
479     {
480         Field = UtFieldCacheCalloc ();
481         Field->Name = Name;
482         Field->Value = Value;
483         Field->Line = Line;
484         Field->ByteOffset = Offset;
485         Field->NameColumn = NameColumn;
486         Field->Column = Column;
487         Field->StringLength = Length;
488
489         DtLinkField (Field);
490     }
491     /* Else -- Ignore this field, it has no valid data */
492
493     return (AE_OK);
494 }
495
496
497 /******************************************************************************
498  *
499  * FUNCTION:    DtGetNextLine
500  *
501  * PARAMETERS:  Handle              - Open file handle for the source file
502  *
503  * RETURN:      Filled line buffer and offset of start-of-line (ASL_EOF on EOF)
504  *
505  * DESCRIPTION: Get the next valid source line. Removes all comments.
506  *              Ignores empty lines.
507  *
508  * Handles both slash-asterisk and slash-slash comments.
509  * Also, quoted strings, but no escapes within.
510  *
511  * Line is returned in Gbl_CurrentLineBuffer.
512  * Line number in original file is returned in Gbl_CurrentLineNumber.
513  *
514  *****************************************************************************/
515
516 UINT32
517 DtGetNextLine (
518     FILE                    *Handle,
519     UINT32                  Flags)
520 {
521     BOOLEAN                 LineNotAllBlanks = FALSE;
522     UINT32                  State = DT_NORMAL_TEXT;
523     UINT32                  CurrentLineOffset;
524     UINT32                  i;
525     int                     c;
526
527
528     memset (Gbl_CurrentLineBuffer, 0, Gbl_LineBufferSize);
529     for (i = 0; ;)
530     {
531         /*
532          * If line is too long, expand the line buffers. Also increases
533          * Gbl_LineBufferSize.
534          */
535         if (i >= Gbl_LineBufferSize)
536         {
537             UtExpandLineBuffers ();
538         }
539
540         c = getc (Handle);
541         if (c == EOF)
542         {
543             switch (State)
544             {
545             case DT_START_QUOTED_STRING:
546             case DT_SLASH_ASTERISK_COMMENT:
547
548                 AcpiOsPrintf ("**** EOF within comment/string %u\n", State);
549                 break;
550
551             default:
552
553                 break;
554             }
555
556             /* Standalone EOF is OK */
557
558             if (i == 0)
559             {
560                 return (ASL_EOF);
561             }
562
563             /*
564              * Received an EOF in the middle of a line. Terminate the
565              * line with a newline. The next call to this function will
566              * return a standalone EOF. Thus, the upper parsing software
567              * never has to deal with an EOF within a valid line (or
568              * the last line does not get tossed on the floor.)
569              */
570             c = '\n';
571             State = DT_NORMAL_TEXT;
572         }
573
574         switch (State)
575         {
576         case DT_NORMAL_TEXT:
577
578             /* Normal text, insert char into line buffer */
579
580             Gbl_CurrentLineBuffer[i] = (char) c;
581             switch (c)
582             {
583             case '/':
584
585                 State = DT_START_COMMENT;
586                 break;
587
588             case '"':
589
590                 State = DT_START_QUOTED_STRING;
591                 LineNotAllBlanks = TRUE;
592                 i++;
593                 break;
594
595             case '\\':
596                 /*
597                  * The continuation char MUST be last char on this line.
598                  * Otherwise, it will be assumed to be a valid ASL char.
599                  */
600                 State = DT_MERGE_LINES;
601                 break;
602
603             case '\n':
604
605                 CurrentLineOffset = Gbl_NextLineOffset;
606                 Gbl_NextLineOffset = (UINT32) ftell (Handle);
607                 Gbl_CurrentLineNumber++;
608
609                 /*
610                  * Exit if line is complete. Ignore empty lines (only \n)
611                  * or lines that contain nothing but blanks.
612                  */
613                 if ((i != 0) && LineNotAllBlanks)
614                 {
615                     if ((i + 1) >= Gbl_LineBufferSize)
616                     {
617                         UtExpandLineBuffers ();
618                     }
619
620                     Gbl_CurrentLineBuffer[i+1] = 0; /* Terminate string */
621                     return (CurrentLineOffset);
622                 }
623
624                 /* Toss this line and start a new one */
625
626                 i = 0;
627                 LineNotAllBlanks = FALSE;
628                 break;
629
630             default:
631
632                 if (c != ' ')
633                 {
634                     LineNotAllBlanks = TRUE;
635                 }
636
637                 i++;
638                 break;
639             }
640             break;
641
642         case DT_START_QUOTED_STRING:
643
644             /* Insert raw chars until end of quoted string */
645
646             Gbl_CurrentLineBuffer[i] = (char) c;
647             i++;
648
649             switch (c)
650             {
651             case '"':
652
653                 State = DT_NORMAL_TEXT;
654                 break;
655
656             case '\\':
657
658                 State = DT_ESCAPE_SEQUENCE;
659                 break;
660
661             case '\n':
662
663                 if (!(Flags & DT_ALLOW_MULTILINE_QUOTES))
664                 {
665                     AcpiOsPrintf (
666                         "ERROR at line %u: Unterminated quoted string\n",
667                         Gbl_CurrentLineNumber++);
668                     State = DT_NORMAL_TEXT;
669                 }
670                 break;
671
672             default:    /* Get next character */
673
674                 break;
675             }
676             break;
677
678         case DT_ESCAPE_SEQUENCE:
679
680             /* Just copy the escaped character. TBD: sufficient for table compiler? */
681
682             Gbl_CurrentLineBuffer[i] = (char) c;
683             i++;
684             State = DT_START_QUOTED_STRING;
685             break;
686
687         case DT_START_COMMENT:
688
689             /* Open comment if this character is an asterisk or slash */
690
691             switch (c)
692             {
693             case '*':
694
695                 State = DT_SLASH_ASTERISK_COMMENT;
696                 break;
697
698             case '/':
699
700                 State = DT_SLASH_SLASH_COMMENT;
701                 break;
702
703             default:    /* Not a comment */
704
705                 i++;    /* Save the preceding slash */
706                 if (i >= Gbl_LineBufferSize)
707                 {
708                     UtExpandLineBuffers ();
709                 }
710
711                 Gbl_CurrentLineBuffer[i] = (char) c;
712                 i++;
713                 State = DT_NORMAL_TEXT;
714                 break;
715             }
716             break;
717
718         case DT_SLASH_ASTERISK_COMMENT:
719
720             /* Ignore chars until an asterisk-slash is found */
721
722             switch (c)
723             {
724             case '\n':
725
726                 Gbl_NextLineOffset = (UINT32) ftell (Handle);
727                 Gbl_CurrentLineNumber++;
728                 break;
729
730             case '*':
731
732                 State = DT_END_COMMENT;
733                 break;
734
735             default:
736
737                 break;
738             }
739             break;
740
741         case DT_SLASH_SLASH_COMMENT:
742
743             /* Ignore chars until end-of-line */
744
745             if (c == '\n')
746             {
747                 /* We will exit via the NORMAL_TEXT path */
748
749                 ungetc (c, Handle);
750                 State = DT_NORMAL_TEXT;
751             }
752             break;
753
754         case DT_END_COMMENT:
755
756             /* End comment if this char is a slash */
757
758             switch (c)
759             {
760             case '/':
761
762                 State = DT_NORMAL_TEXT;
763                 break;
764
765             case '\n':
766
767                 CurrentLineOffset = Gbl_NextLineOffset;
768                 Gbl_NextLineOffset = (UINT32) ftell (Handle);
769                 Gbl_CurrentLineNumber++;
770                 break;
771
772             case '*':
773
774                 /* Consume all adjacent asterisks */
775                 break;
776
777             default:
778
779                 State = DT_SLASH_ASTERISK_COMMENT;
780                 break;
781             }
782             break;
783
784         case DT_MERGE_LINES:
785
786             if (c != '\n')
787             {
788                 /*
789                  * This is not a continuation backslash, it is a normal
790                  * normal ASL backslash - for example: Scope(\_SB_)
791                  */
792                 i++; /* Keep the backslash that is already in the buffer */
793
794                 ungetc (c, Handle);
795                 State = DT_NORMAL_TEXT;
796             }
797             else
798             {
799                 /*
800                  * This is a continuation line -- a backlash followed
801                  * immediately by a newline. Insert a space between the
802                  * lines (overwrite the backslash)
803                  */
804                 Gbl_CurrentLineBuffer[i] = ' ';
805                 i++;
806
807                 /* Ignore newline, this will merge the lines */
808
809                 CurrentLineOffset = Gbl_NextLineOffset;
810                 Gbl_NextLineOffset = (UINT32) ftell (Handle);
811                 Gbl_CurrentLineNumber++;
812                 State = DT_NORMAL_TEXT;
813             }
814             break;
815
816         default:
817
818             DtFatal (ASL_MSG_COMPILER_INTERNAL, NULL, "Unknown input state");
819             return (ASL_EOF);
820         }
821     }
822 }
823
824
825 /******************************************************************************
826  *
827  * FUNCTION:    DtScanFile
828  *
829  * PARAMETERS:  Handle              - Open file handle for the source file
830  *
831  * RETURN:      Pointer to start of the constructed parse tree.
832  *
833  * DESCRIPTION: Scan source file, link all field names and values
834  *              to the global parse tree: Gbl_FieldList
835  *
836  *****************************************************************************/
837
838 DT_FIELD *
839 DtScanFile (
840     FILE                    *Handle)
841 {
842     ACPI_STATUS             Status;
843     UINT32                  Offset;
844
845
846     ACPI_FUNCTION_NAME (DtScanFile);
847
848
849     /* Get the file size */
850
851     Gbl_InputByteCount = CmGetFileSize (Handle);
852     if (Gbl_InputByteCount == ACPI_UINT32_MAX)
853     {
854         AslAbort ();
855     }
856
857     Gbl_CurrentLineNumber = 0;
858     Gbl_CurrentLineOffset = 0;
859     Gbl_NextLineOffset = 0;
860
861     /* Scan line-by-line */
862
863     while ((Offset = DtGetNextLine (Handle, 0)) != ASL_EOF)
864     {
865         ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Line %2.2u/%4.4X - %s",
866             Gbl_CurrentLineNumber, Offset, Gbl_CurrentLineBuffer));
867
868         Status = DtParseLine (Gbl_CurrentLineBuffer,
869             Gbl_CurrentLineNumber, Offset);
870         if (Status == AE_NOT_FOUND)
871         {
872             break;
873         }
874     }
875
876     /* Dump the parse tree if debug enabled */
877
878     DtDumpFieldList (Gbl_FieldList);
879     return (Gbl_FieldList);
880 }
881
882
883 /*
884  * Output functions
885  */
886
887 /******************************************************************************
888  *
889  * FUNCTION:    DtWriteBinary
890  *
891  * PARAMETERS:  DT_WALK_CALLBACK
892  *
893  * RETURN:      Status
894  *
895  * DESCRIPTION: Write one subtable of a binary ACPI table
896  *
897  *****************************************************************************/
898
899 static void
900 DtWriteBinary (
901     DT_SUBTABLE             *Subtable,
902     void                    *Context,
903     void                    *ReturnValue)
904 {
905
906     FlWriteFile (ASL_FILE_AML_OUTPUT, Subtable->Buffer, Subtable->Length);
907 }
908
909
910 /******************************************************************************
911  *
912  * FUNCTION:    DtOutputBinary
913  *
914  * PARAMETERS:
915  *
916  * RETURN:      Status
917  *
918  * DESCRIPTION: Write entire binary ACPI table (result of compilation)
919  *
920  *****************************************************************************/
921
922 void
923 DtOutputBinary (
924     DT_SUBTABLE             *RootTable)
925 {
926
927     if (!RootTable)
928     {
929         return;
930     }
931
932     /* Walk the entire parse tree, emitting the binary data */
933
934     DtWalkTableTree (RootTable, DtWriteBinary, NULL, NULL);
935
936     Gbl_TableLength = CmGetFileSize (Gbl_Files[ASL_FILE_AML_OUTPUT].Handle);
937     if (Gbl_TableLength == ACPI_UINT32_MAX)
938     {
939         AslAbort ();
940     }
941 }
942
943
944 /*
945  * Listing support
946  */
947
948 /******************************************************************************
949  *
950  * FUNCTION:    DtDumpBuffer
951  *
952  * PARAMETERS:  FileID              - Where to write buffer data
953  *              Buffer              - Buffer to dump
954  *              Offset              - Offset in current table
955  *              Length              - Buffer Length
956  *
957  * RETURN:      None
958  *
959  * DESCRIPTION: Another copy of DumpBuffer routine (unfortunately).
960  *
961  * TBD: merge dump buffer routines
962  *
963  *****************************************************************************/
964
965 static void
966 DtDumpBuffer (
967     UINT32                  FileId,
968     UINT8                   *Buffer,
969     UINT32                  Offset,
970     UINT32                  Length)
971 {
972     UINT32                  i;
973     UINT32                  j;
974     UINT8                   BufChar;
975
976
977     FlPrintFile (FileId, "Output: [%3.3Xh %4.4d %3d] ",
978         Offset, Offset, Length);
979
980     i = 0;
981     while (i < Length)
982     {
983         if (i >= 16)
984         {
985             FlPrintFile (FileId, "%24s", "");
986         }
987
988         /* Print 16 hex chars */
989
990         for (j = 0; j < 16;)
991         {
992             if (i + j >= Length)
993             {
994                 /* Dump fill spaces */
995
996                 FlPrintFile (FileId, "   ");
997                 j++;
998                 continue;
999             }
1000
1001             FlPrintFile (FileId, "%02X ", Buffer[i+j]);
1002             j++;
1003         }
1004
1005         FlPrintFile (FileId, " ");
1006         for (j = 0; j < 16; j++)
1007         {
1008             if (i + j >= Length)
1009             {
1010                 FlPrintFile (FileId, "\n\n");
1011                 return;
1012             }
1013
1014             BufChar = Buffer[(ACPI_SIZE) i + j];
1015             if (isprint (BufChar))
1016             {
1017                 FlPrintFile (FileId, "%c", BufChar);
1018             }
1019             else
1020             {
1021                 FlPrintFile (FileId, ".");
1022             }
1023         }
1024
1025         /* Done with that line. */
1026
1027         FlPrintFile (FileId, "\n");
1028         i += 16;
1029     }
1030
1031     FlPrintFile (FileId, "\n\n");
1032 }
1033
1034
1035 /******************************************************************************
1036  *
1037  * FUNCTION:    DtDumpFieldList
1038  *
1039  * PARAMETERS:  Field               - Root field
1040  *
1041  * RETURN:      None
1042  *
1043  * DESCRIPTION: Dump the entire field list
1044  *
1045  *****************************************************************************/
1046
1047 void
1048 DtDumpFieldList (
1049     DT_FIELD                *Field)
1050 {
1051
1052     if (!Gbl_DebugFlag || !Field)
1053     {
1054         return;
1055     }
1056
1057     DbgPrint (ASL_DEBUG_OUTPUT,  "\nField List:\n"
1058         "LineNo   ByteOff  NameCol  Column   TableOff "
1059         "Flags %32s : %s\n\n", "Name", "Value");
1060
1061     while (Field)
1062     {
1063         DbgPrint (ASL_DEBUG_OUTPUT,
1064             "%.08X %.08X %.08X %.08X %.08X %2.2X    %32s : %s\n",
1065             Field->Line, Field->ByteOffset, Field->NameColumn,
1066             Field->Column, Field->TableOffset, Field->Flags,
1067             Field->Name, Field->Value);
1068
1069         Field = Field->Next;
1070     }
1071
1072     DbgPrint (ASL_DEBUG_OUTPUT,  "\n\n");
1073 }
1074
1075
1076 /******************************************************************************
1077  *
1078  * FUNCTION:    DtDumpSubtableInfo, DtDumpSubtableTree
1079  *
1080  * PARAMETERS:  DT_WALK_CALLBACK
1081  *
1082  * RETURN:      None
1083  *
1084  * DESCRIPTION: Info - dump a subtable tree entry with extra information.
1085  *              Tree - dump a subtable tree formatted by depth indentation.
1086  *
1087  *****************************************************************************/
1088
1089 static void
1090 DtDumpSubtableInfo (
1091     DT_SUBTABLE             *Subtable,
1092     void                    *Context,
1093     void                    *ReturnValue)
1094 {
1095
1096     DbgPrint (ASL_DEBUG_OUTPUT,
1097         "[%.04X] %24s %.08X %.08X %.08X %.08X %.08X %p %p %p\n",
1098         Subtable->Depth, Subtable->Name, Subtable->Length, Subtable->TotalLength,
1099         Subtable->SizeOfLengthField, Subtable->Flags, Subtable,
1100         Subtable->Parent, Subtable->Child, Subtable->Peer);
1101 }
1102
1103 static void
1104 DtDumpSubtableTree (
1105     DT_SUBTABLE             *Subtable,
1106     void                    *Context,
1107     void                    *ReturnValue)
1108 {
1109
1110     DbgPrint (ASL_DEBUG_OUTPUT,
1111         "[%.04X] %24s %*s%08X (%.02X) - (%.02X)\n",
1112         Subtable->Depth, Subtable->Name, (4 * Subtable->Depth), " ",
1113         Subtable, Subtable->Length, Subtable->TotalLength);
1114 }
1115
1116
1117 /******************************************************************************
1118  *
1119  * FUNCTION:    DtDumpSubtableList
1120  *
1121  * PARAMETERS:  None
1122  *
1123  * RETURN:      None
1124  *
1125  * DESCRIPTION: Dump the raw list of subtables with information, and also
1126  *              dump the subtable list in formatted tree format. Assists with
1127  *              the development of new table code.
1128  *
1129  *****************************************************************************/
1130
1131 void
1132 DtDumpSubtableList (
1133     void)
1134 {
1135
1136     if (!Gbl_DebugFlag || !Gbl_RootTable)
1137     {
1138         return;
1139     }
1140
1141     DbgPrint (ASL_DEBUG_OUTPUT,
1142         "Subtable Info:\n"
1143         "Depth                      Name Length   TotalLen LenSize  Flags    "
1144         "This     Parent   Child    Peer\n\n");
1145     DtWalkTableTree (Gbl_RootTable, DtDumpSubtableInfo, NULL, NULL);
1146
1147     DbgPrint (ASL_DEBUG_OUTPUT,
1148         "\nSubtable Tree: (Depth, Name, Subtable, Length, TotalLength)\n\n");
1149     DtWalkTableTree (Gbl_RootTable, DtDumpSubtableTree, NULL, NULL);
1150
1151     DbgPrint (ASL_DEBUG_OUTPUT, "\n");
1152 }
1153
1154
1155 /******************************************************************************
1156  *
1157  * FUNCTION:    DtWriteFieldToListing
1158  *
1159  * PARAMETERS:  Buffer              - Contains the compiled data
1160  *              Field               - Field node for the input line
1161  *              Length              - Length of the output data
1162  *
1163  * RETURN:      None
1164  *
1165  * DESCRIPTION: Write one field to the listing file (if listing is enabled).
1166  *
1167  *****************************************************************************/
1168
1169 void
1170 DtWriteFieldToListing (
1171     UINT8                   *Buffer,
1172     DT_FIELD                *Field,
1173     UINT32                  Length)
1174 {
1175     UINT8                   FileByte;
1176
1177
1178     if (!Gbl_ListingFlag || !Field)
1179     {
1180         return;
1181     }
1182
1183     /* Dump the original source line */
1184
1185     FlPrintFile (ASL_FILE_LISTING_OUTPUT, "Input:  ");
1186     FlSeekFile (ASL_FILE_INPUT, Field->ByteOffset);
1187
1188     while (FlReadFile (ASL_FILE_INPUT, &FileByte, 1) == AE_OK)
1189     {
1190         FlWriteFile (ASL_FILE_LISTING_OUTPUT, &FileByte, 1);
1191         if (FileByte == '\n')
1192         {
1193             break;
1194         }
1195     }
1196
1197     /* Dump the line as parsed and represented internally */
1198
1199     FlPrintFile (ASL_FILE_LISTING_OUTPUT, "Parsed: %*s : %.64s",
1200         Field->Column-4, Field->Name, Field->Value);
1201
1202     if (strlen (Field->Value) > 64)
1203     {
1204         FlPrintFile (ASL_FILE_LISTING_OUTPUT, "...Additional data, length 0x%X\n",
1205             strlen (Field->Value));
1206     }
1207
1208     FlPrintFile (ASL_FILE_LISTING_OUTPUT, "\n");
1209
1210     /* Dump the hex data that will be output for this field */
1211
1212     DtDumpBuffer (ASL_FILE_LISTING_OUTPUT, Buffer, Field->TableOffset, Length);
1213 }
1214
1215
1216 /******************************************************************************
1217  *
1218  * FUNCTION:    DtWriteTableToListing
1219  *
1220  * PARAMETERS:  None
1221  *
1222  * RETURN:      None
1223  *
1224  * DESCRIPTION: Write the entire compiled table to the listing file
1225  *              in hex format
1226  *
1227  *****************************************************************************/
1228
1229 void
1230 DtWriteTableToListing (
1231     void)
1232 {
1233     UINT8                   *Buffer;
1234
1235
1236     if (!Gbl_ListingFlag)
1237     {
1238         return;
1239     }
1240
1241     /* Read the entire table from the output file */
1242
1243     Buffer = UtLocalCalloc (Gbl_TableLength);
1244     FlSeekFile (ASL_FILE_AML_OUTPUT, 0);
1245     FlReadFile (ASL_FILE_AML_OUTPUT, Buffer, Gbl_TableLength);
1246
1247     /* Dump the raw table data */
1248
1249     AcpiOsRedirectOutput (Gbl_Files[ASL_FILE_LISTING_OUTPUT].Handle);
1250
1251     AcpiOsPrintf ("\n%s: Length %d (0x%X)\n\n",
1252         ACPI_RAW_TABLE_DATA_HEADER, Gbl_TableLength, Gbl_TableLength);
1253     AcpiUtDumpBuffer (Buffer, Gbl_TableLength, DB_BYTE_DISPLAY, 0);
1254
1255     AcpiOsRedirectOutput (stdout);
1256     ACPI_FREE (Buffer);
1257 }