Sync ACPICA with Intel's version 20190108.
[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 - 2019, 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 "acapps.h"
154
155 #define _COMPONENT          DT_COMPILER
156         ACPI_MODULE_NAME    ("dtio")
157
158
159 /* Local prototypes */
160
161 static char *
162 DtTrim (
163     char                    *String);
164
165 static void
166 DtLinkField (
167     DT_FIELD                *Field);
168
169 static ACPI_STATUS
170 DtParseLine (
171     char                    *LineBuffer,
172     UINT32                  Line,
173     UINT32                  Offset);
174
175 static void
176 DtWriteBinary (
177     DT_SUBTABLE             *Subtable,
178     void                    *Context,
179     void                    *ReturnValue);
180
181 static void
182 DtDumpBuffer (
183     UINT32                  FileId,
184     UINT8                   *Buffer,
185     UINT32                  Offset,
186     UINT32                  Length);
187
188 static void
189 DtDumpSubtableInfo (
190     DT_SUBTABLE             *Subtable,
191     void                    *Context,
192     void                    *ReturnValue);
193
194 static void
195 DtDumpSubtableTree (
196     DT_SUBTABLE             *Subtable,
197     void                    *Context,
198     void                    *ReturnValue);
199
200
201 /* States for DtGetNextLine */
202
203 #define DT_NORMAL_TEXT              0
204 #define DT_START_QUOTED_STRING      1
205 #define DT_START_COMMENT            2
206 #define DT_SLASH_ASTERISK_COMMENT   3
207 #define DT_SLASH_SLASH_COMMENT      4
208 #define DT_END_COMMENT              5
209 #define DT_MERGE_LINES              6
210 #define DT_ESCAPE_SEQUENCE          7
211
212 static UINT32               AslGbl_NextLineOffset;
213
214
215 /******************************************************************************
216  *
217  * FUNCTION:    DtTrim
218  *
219  * PARAMETERS:  String              - Current source code line to trim
220  *
221  * RETURN:      Trimmed line. Must be freed by caller.
222  *
223  * DESCRIPTION: Trim left and right spaces
224  *
225  *****************************************************************************/
226
227 static char *
228 DtTrim (
229     char                    *String)
230 {
231     char                    *Start;
232     char                    *End;
233     char                    *ReturnString;
234     ACPI_SIZE               Length;
235
236
237     /* Skip lines that start with a space */
238
239     if (*String == 0 || !strcmp (String, " "))
240     {
241         ReturnString = UtLocalCacheCalloc (1);
242         return (ReturnString);
243     }
244
245     /* Setup pointers to start and end of input string */
246
247     Start = String;
248     End = String + strlen (String) - 1;
249
250     /* Find first non-whitespace character */
251
252     while ((Start <= End) && ((*Start == ' ') || (*Start == '\t')))
253     {
254         Start++;
255     }
256
257     /* Find last non-space character */
258
259     while (End >= Start)
260     {
261         if (*End == '\n')
262         {
263             End--;
264             continue;
265         }
266
267         if (*End != ' ')
268         {
269             break;
270         }
271
272         End--;
273     }
274
275     /* Remove any quotes around the string */
276
277     if (*Start == '\"')
278     {
279         Start++;
280     }
281     if (*End == '\"')
282     {
283         End--;
284     }
285
286     /* Create the trimmed return string */
287
288     Length = ACPI_PTR_DIFF (End, Start) + 1;
289     ReturnString = UtLocalCacheCalloc (Length + 1);
290     if (strlen (Start))
291     {
292         strncpy (ReturnString, Start, Length);
293     }
294
295     ReturnString[Length] = 0;
296     return (ReturnString);
297 }
298
299
300 /******************************************************************************
301  *
302  * FUNCTION:    DtLinkField
303  *
304  * PARAMETERS:  Field               - New field object to link
305  *
306  * RETURN:      None
307  *
308  * DESCRIPTION: Link one field name and value to the list
309  *
310  *****************************************************************************/
311
312 static void
313 DtLinkField (
314     DT_FIELD                *Field)
315 {
316     DT_FIELD                *Prev;
317     DT_FIELD                *Next;
318
319
320     Prev = Next = AslGbl_FieldList;
321
322     while (Next)
323     {
324         Prev = Next;
325         Next = Next->Next;
326     }
327
328     if (Prev)
329     {
330         Prev->Next = Field;
331     }
332     else
333     {
334         AslGbl_FieldList = Field;
335     }
336 }
337
338
339 /******************************************************************************
340  *
341  * FUNCTION:    DtParseLine
342  *
343  * PARAMETERS:  LineBuffer          - Current source code line
344  *              Line                - Current line number in the source
345  *              Offset              - Current byte offset of the line
346  *
347  * RETURN:      Status
348  *
349  * DESCRIPTION: Parse one source line
350  *
351  *****************************************************************************/
352
353 static ACPI_STATUS
354 DtParseLine (
355     char                    *LineBuffer,
356     UINT32                  Line,
357     UINT32                  Offset)
358 {
359     char                    *Start;
360     char                    *End;
361     char                    *TmpName;
362     char                    *TmpValue;
363     char                    *Name;
364     char                    *Value;
365     char                    *Colon;
366     UINT32                  Length;
367     DT_FIELD                *Field;
368     UINT32                  Column;
369     UINT32                  NameColumn;
370     BOOLEAN                 IsNullString = FALSE;
371
372
373     if (!LineBuffer)
374     {
375         return (AE_OK);
376     }
377
378     /* All lines after "Raw Table Data" are ingored */
379
380     if (strstr (LineBuffer, ACPI_RAW_TABLE_DATA_HEADER))
381     {
382         return (AE_NOT_FOUND);
383     }
384
385     Colon = strchr (LineBuffer, ':');
386     if (!Colon)
387     {
388         return (AE_OK);
389     }
390
391     Start = LineBuffer;
392     End = Colon;
393
394     while (Start < Colon)
395     {
396         if (*Start == '[')
397         {
398             /* Found left bracket, go to the right bracket */
399
400             while (Start < Colon && *Start != ']')
401             {
402                 Start++;
403             }
404         }
405         else if (*Start != ' ')
406         {
407             break;
408         }
409
410         Start++;
411     }
412
413     /*
414      * There are two column values. One for the field name,
415      * and one for the field value.
416      */
417     Column = ACPI_PTR_DIFF (Colon, LineBuffer) + 3;
418     NameColumn = ACPI_PTR_DIFF (Start, LineBuffer) + 1;
419
420     Length = ACPI_PTR_DIFF (End, Start);
421
422     TmpName = UtLocalCalloc (Length + 1);
423     strncpy (TmpName, Start, Length);
424     Name = DtTrim (TmpName);
425     ACPI_FREE (TmpName);
426
427     Start = End = (Colon + 1);
428     while (*End)
429     {
430         /* Found left quotation, go to the right quotation and break */
431
432         if (*End == '"')
433         {
434             End++;
435
436             /* Check for an explicit null string */
437
438             if (*End == '"')
439             {
440                 IsNullString = TRUE;
441             }
442             while (*End && (*End != '"'))
443             {
444                 End++;
445             }
446
447             End++;
448             break;
449         }
450
451         /*
452          * Special "comment" fields at line end, ignore them.
453          * Note: normal slash-slash and slash-asterisk comments are
454          * stripped already by the DtGetNextLine parser.
455          *
456          * TBD: Perhaps DtGetNextLine should parse the following type
457          * of comments also.
458          */
459         if (*End == '[')
460         {
461             End--;
462             break;
463         }
464
465         End++;
466     }
467
468     Length = ACPI_PTR_DIFF (End, Start);
469     TmpValue = UtLocalCalloc (Length + 1);
470
471     strncpy (TmpValue, Start, Length);
472     Value = DtTrim (TmpValue);
473     ACPI_FREE (TmpValue);
474
475     /* Create a new field object only if we have a valid value field */
476
477     if ((Value && *Value) || IsNullString)
478     {
479         Field = UtFieldCacheCalloc ();
480         Field->Name = Name;
481         Field->Value = Value;
482         Field->Line = Line;
483         Field->ByteOffset = Offset;
484         Field->NameColumn = NameColumn;
485         Field->Column = Column;
486         Field->StringLength = Length;
487
488         DtLinkField (Field);
489     }
490     /* Else -- Ignore this field, it has no valid data */
491
492     return (AE_OK);
493 }
494
495
496 /******************************************************************************
497  *
498  * FUNCTION:    DtGetNextLine
499  *
500  * PARAMETERS:  Handle              - Open file handle for the source file
501  *
502  * RETURN:      Filled line buffer and offset of start-of-line (ASL_EOF on EOF)
503  *
504  * DESCRIPTION: Get the next valid source line. Removes all comments.
505  *              Ignores empty lines.
506  *
507  * Handles both slash-asterisk and slash-slash comments.
508  * Also, quoted strings, but no escapes within.
509  *
510  * Line is returned in AslGbl_CurrentLineBuffer.
511  * Line number in original file is returned in AslGbl_CurrentLineNumber.
512  *
513  *****************************************************************************/
514
515 UINT32
516 DtGetNextLine (
517     FILE                    *Handle,
518     UINT32                  Flags)
519 {
520     BOOLEAN                 LineNotAllBlanks = FALSE;
521     UINT32                  State = DT_NORMAL_TEXT;
522     UINT32                  CurrentLineOffset;
523     UINT32                  i;
524     int                     c;
525     int                     c1;
526
527
528     memset (AslGbl_CurrentLineBuffer, 0, AslGbl_LineBufferSize);
529     for (i = 0; ;)
530     {
531         /*
532          * If line is too long, expand the line buffers. Also increases
533          * AslGbl_LineBufferSize.
534          */
535         if (i >= AslGbl_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         else if (c == '\r')
574         {
575             c1 = getc (Handle);
576             if (c1 == '\n')
577             {
578                 /*
579                  * Skip the carriage return as if it didn't exist. This is
580                  * onlt meant for input files in DOS format in unix. fopen in
581                  * unix may not support "text mode" and leaves CRLF intact.
582                  */
583                 c = '\n';
584             }
585             else
586             {
587                 /* This was not a CRLF. Only a CR */
588
589                 ungetc(c1, Handle);
590
591                 DtFatal (ASL_MSG_COMPILER_INTERNAL, NULL,
592                     "Carriage return without linefeed detected");
593                 return (ASL_EOF);
594             }
595         }
596
597         switch (State)
598         {
599         case DT_NORMAL_TEXT:
600
601             /* Normal text, insert char into line buffer */
602
603             AslGbl_CurrentLineBuffer[i] = (char) c;
604             switch (c)
605             {
606             case '/':
607
608                 State = DT_START_COMMENT;
609                 break;
610
611             case '"':
612
613                 State = DT_START_QUOTED_STRING;
614                 LineNotAllBlanks = TRUE;
615                 i++;
616                 break;
617
618             case '\\':
619                 /*
620                  * The continuation char MUST be last char on this line.
621                  * Otherwise, it will be assumed to be a valid ASL char.
622                  */
623                 State = DT_MERGE_LINES;
624                 break;
625
626             case '\n':
627
628                 CurrentLineOffset = AslGbl_NextLineOffset;
629                 AslGbl_NextLineOffset = (UINT32) ftell (Handle);
630                 AslGbl_CurrentLineNumber++;
631
632                 /*
633                  * Exit if line is complete. Ignore empty lines (only \n)
634                  * or lines that contain nothing but blanks.
635                  */
636                 if ((i != 0) && LineNotAllBlanks)
637                 {
638                     if ((i + 1) >= AslGbl_LineBufferSize)
639                     {
640                         UtExpandLineBuffers ();
641                     }
642
643                     AslGbl_CurrentLineBuffer[i+1] = 0; /* Terminate string */
644                     return (CurrentLineOffset);
645                 }
646
647                 /* Toss this line and start a new one */
648
649                 i = 0;
650                 LineNotAllBlanks = FALSE;
651                 break;
652
653             default:
654
655                 if (c != ' ')
656                 {
657                     LineNotAllBlanks = TRUE;
658                 }
659
660                 i++;
661                 break;
662             }
663             break;
664
665         case DT_START_QUOTED_STRING:
666
667             /* Insert raw chars until end of quoted string */
668
669             AslGbl_CurrentLineBuffer[i] = (char) c;
670             i++;
671
672             switch (c)
673             {
674             case '"':
675
676                 State = DT_NORMAL_TEXT;
677                 break;
678
679             case '\\':
680
681                 State = DT_ESCAPE_SEQUENCE;
682                 break;
683
684             case '\n':
685
686                 if (!(Flags & DT_ALLOW_MULTILINE_QUOTES))
687                 {
688                     AcpiOsPrintf (
689                         "ERROR at line %u: Unterminated quoted string\n",
690                         AslGbl_CurrentLineNumber++);
691                     State = DT_NORMAL_TEXT;
692                 }
693                 break;
694
695             default:    /* Get next character */
696
697                 break;
698             }
699             break;
700
701         case DT_ESCAPE_SEQUENCE:
702
703             /* Just copy the escaped character. TBD: sufficient for table compiler? */
704
705             AslGbl_CurrentLineBuffer[i] = (char) c;
706             i++;
707             State = DT_START_QUOTED_STRING;
708             break;
709
710         case DT_START_COMMENT:
711
712             /* Open comment if this character is an asterisk or slash */
713
714             switch (c)
715             {
716             case '*':
717
718                 State = DT_SLASH_ASTERISK_COMMENT;
719                 break;
720
721             case '/':
722
723                 State = DT_SLASH_SLASH_COMMENT;
724                 break;
725
726             default:    /* Not a comment */
727
728                 i++;    /* Save the preceding slash */
729                 if (i >= AslGbl_LineBufferSize)
730                 {
731                     UtExpandLineBuffers ();
732                 }
733
734                 AslGbl_CurrentLineBuffer[i] = (char) c;
735                 i++;
736                 State = DT_NORMAL_TEXT;
737                 break;
738             }
739             break;
740
741         case DT_SLASH_ASTERISK_COMMENT:
742
743             /* Ignore chars until an asterisk-slash is found */
744
745             switch (c)
746             {
747             case '\n':
748
749                 AslGbl_NextLineOffset = (UINT32) ftell (Handle);
750                 AslGbl_CurrentLineNumber++;
751                 break;
752
753             case '*':
754
755                 State = DT_END_COMMENT;
756                 break;
757
758             default:
759
760                 break;
761             }
762             break;
763
764         case DT_SLASH_SLASH_COMMENT:
765
766             /* Ignore chars until end-of-line */
767
768             if (c == '\n')
769             {
770                 /* We will exit via the NORMAL_TEXT path */
771
772                 ungetc (c, Handle);
773                 State = DT_NORMAL_TEXT;
774             }
775             break;
776
777         case DT_END_COMMENT:
778
779             /* End comment if this char is a slash */
780
781             switch (c)
782             {
783             case '/':
784
785                 State = DT_NORMAL_TEXT;
786                 break;
787
788             case '\n':
789
790                 CurrentLineOffset = AslGbl_NextLineOffset;
791                 AslGbl_NextLineOffset = (UINT32) ftell (Handle);
792                 AslGbl_CurrentLineNumber++;
793                 break;
794
795             case '*':
796
797                 /* Consume all adjacent asterisks */
798                 break;
799
800             default:
801
802                 State = DT_SLASH_ASTERISK_COMMENT;
803                 break;
804             }
805             break;
806
807         case DT_MERGE_LINES:
808
809             if (c != '\n')
810             {
811                 /*
812                  * This is not a continuation backslash, it is a normal
813                  * normal ASL backslash - for example: Scope(\_SB_)
814                  */
815                 i++; /* Keep the backslash that is already in the buffer */
816
817                 ungetc (c, Handle);
818                 State = DT_NORMAL_TEXT;
819             }
820             else
821             {
822                 /*
823                  * This is a continuation line -- a backlash followed
824                  * immediately by a newline. Insert a space between the
825                  * lines (overwrite the backslash)
826                  */
827                 AslGbl_CurrentLineBuffer[i] = ' ';
828                 i++;
829
830                 /* Ignore newline, this will merge the lines */
831
832                 CurrentLineOffset = AslGbl_NextLineOffset;
833                 AslGbl_NextLineOffset = (UINT32) ftell (Handle);
834                 AslGbl_CurrentLineNumber++;
835                 State = DT_NORMAL_TEXT;
836             }
837             break;
838
839         default:
840
841             DtFatal (ASL_MSG_COMPILER_INTERNAL, NULL, "Unknown input state");
842             return (ASL_EOF);
843         }
844     }
845 }
846
847
848 /******************************************************************************
849  *
850  * FUNCTION:    DtScanFile
851  *
852  * PARAMETERS:  Handle              - Open file handle for the source file
853  *
854  * RETURN:      Pointer to start of the constructed parse tree.
855  *
856  * DESCRIPTION: Scan source file, link all field names and values
857  *              to the global parse tree: AslGbl_FieldList
858  *
859  *****************************************************************************/
860
861 DT_FIELD *
862 DtScanFile (
863     FILE                    *Handle)
864 {
865     ACPI_STATUS             Status;
866     UINT32                  Offset;
867
868
869     ACPI_FUNCTION_NAME (DtScanFile);
870
871
872     /* Get the file size */
873
874     AslGbl_InputByteCount = CmGetFileSize (Handle);
875     if (AslGbl_InputByteCount == ACPI_UINT32_MAX)
876     {
877         AslAbort ();
878     }
879
880     AslGbl_CurrentLineNumber = 0;
881     AslGbl_CurrentLineOffset = 0;
882     AslGbl_NextLineOffset = 0;
883
884     /* Scan line-by-line */
885
886     while ((Offset = DtGetNextLine (Handle, 0)) != ASL_EOF)
887     {
888         ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Line %2.2u/%4.4X - %s",
889             AslGbl_CurrentLineNumber, Offset, AslGbl_CurrentLineBuffer));
890
891         Status = DtParseLine (AslGbl_CurrentLineBuffer,
892             AslGbl_CurrentLineNumber, Offset);
893         if (Status == AE_NOT_FOUND)
894         {
895             break;
896         }
897     }
898
899     /* Dump the parse tree if debug enabled */
900
901     DtDumpFieldList (AslGbl_FieldList);
902     return (AslGbl_FieldList);
903 }
904
905
906 /*
907  * Output functions
908  */
909
910 /******************************************************************************
911  *
912  * FUNCTION:    DtWriteBinary
913  *
914  * PARAMETERS:  DT_WALK_CALLBACK
915  *
916  * RETURN:      Status
917  *
918  * DESCRIPTION: Write one subtable of a binary ACPI table
919  *
920  *****************************************************************************/
921
922 static void
923 DtWriteBinary (
924     DT_SUBTABLE             *Subtable,
925     void                    *Context,
926     void                    *ReturnValue)
927 {
928
929     FlWriteFile (ASL_FILE_AML_OUTPUT, Subtable->Buffer, Subtable->Length);
930 }
931
932
933 /******************************************************************************
934  *
935  * FUNCTION:    DtOutputBinary
936  *
937  * PARAMETERS:
938  *
939  * RETURN:      Status
940  *
941  * DESCRIPTION: Write entire binary ACPI table (result of compilation)
942  *
943  *****************************************************************************/
944
945 void
946 DtOutputBinary (
947     DT_SUBTABLE             *RootTable)
948 {
949
950     if (!RootTable)
951     {
952         return;
953     }
954
955     /* Walk the entire parse tree, emitting the binary data */
956
957     DtWalkTableTree (RootTable, DtWriteBinary, NULL, NULL);
958
959     AslGbl_TableLength = CmGetFileSize (AslGbl_Files[ASL_FILE_AML_OUTPUT].Handle);
960     if (AslGbl_TableLength == ACPI_UINT32_MAX)
961     {
962         AslAbort ();
963     }
964 }
965
966
967 /*
968  * Listing support
969  */
970
971 /******************************************************************************
972  *
973  * FUNCTION:    DtDumpBuffer
974  *
975  * PARAMETERS:  FileID              - Where to write buffer data
976  *              Buffer              - Buffer to dump
977  *              Offset              - Offset in current table
978  *              Length              - Buffer Length
979  *
980  * RETURN:      None
981  *
982  * DESCRIPTION: Another copy of DumpBuffer routine (unfortunately).
983  *
984  * TBD: merge dump buffer routines
985  *
986  *****************************************************************************/
987
988 static void
989 DtDumpBuffer (
990     UINT32                  FileId,
991     UINT8                   *Buffer,
992     UINT32                  Offset,
993     UINT32                  Length)
994 {
995     UINT32                  i;
996     UINT32                  j;
997     UINT8                   BufChar;
998
999
1000     FlPrintFile (FileId, "Output: [%3.3Xh %4.4d %3d] ",
1001         Offset, Offset, Length);
1002
1003     i = 0;
1004     while (i < Length)
1005     {
1006         if (i >= 16)
1007         {
1008             FlPrintFile (FileId, "%24s", "");
1009         }
1010
1011         /* Print 16 hex chars */
1012
1013         for (j = 0; j < 16;)
1014         {
1015             if (i + j >= Length)
1016             {
1017                 /* Dump fill spaces */
1018
1019                 FlPrintFile (FileId, "   ");
1020                 j++;
1021                 continue;
1022             }
1023
1024             FlPrintFile (FileId, "%02X ", Buffer[i+j]);
1025             j++;
1026         }
1027
1028         FlPrintFile (FileId, " ");
1029         for (j = 0; j < 16; j++)
1030         {
1031             if (i + j >= Length)
1032             {
1033                 FlPrintFile (FileId, "\n\n");
1034                 return;
1035             }
1036
1037             BufChar = Buffer[(ACPI_SIZE) i + j];
1038             if (isprint (BufChar))
1039             {
1040                 FlPrintFile (FileId, "%c", BufChar);
1041             }
1042             else
1043             {
1044                 FlPrintFile (FileId, ".");
1045             }
1046         }
1047
1048         /* Done with that line. */
1049
1050         FlPrintFile (FileId, "\n");
1051         i += 16;
1052     }
1053
1054     FlPrintFile (FileId, "\n\n");
1055 }
1056
1057
1058 /******************************************************************************
1059  *
1060  * FUNCTION:    DtDumpFieldList
1061  *
1062  * PARAMETERS:  Field               - Root field
1063  *
1064  * RETURN:      None
1065  *
1066  * DESCRIPTION: Dump the entire field list
1067  *
1068  *****************************************************************************/
1069
1070 void
1071 DtDumpFieldList (
1072     DT_FIELD                *Field)
1073 {
1074
1075     if (!AslGbl_DebugFlag || !Field)
1076     {
1077         return;
1078     }
1079
1080     DbgPrint (ASL_DEBUG_OUTPUT,  "\nField List:\n"
1081         "LineNo   ByteOff  NameCol  Column   TableOff "
1082         "Flags %32s : %s\n\n", "Name", "Value");
1083
1084     while (Field)
1085     {
1086         DbgPrint (ASL_DEBUG_OUTPUT,
1087             "%.08X %.08X %.08X %.08X %.08X %2.2X    %32s : %s\n",
1088             Field->Line, Field->ByteOffset, Field->NameColumn,
1089             Field->Column, Field->TableOffset, Field->Flags,
1090             Field->Name, Field->Value);
1091
1092         Field = Field->Next;
1093     }
1094
1095     DbgPrint (ASL_DEBUG_OUTPUT,  "\n\n");
1096 }
1097
1098
1099 /******************************************************************************
1100  *
1101  * FUNCTION:    DtDumpSubtableInfo, DtDumpSubtableTree
1102  *
1103  * PARAMETERS:  DT_WALK_CALLBACK
1104  *
1105  * RETURN:      None
1106  *
1107  * DESCRIPTION: Info - dump a subtable tree entry with extra information.
1108  *              Tree - dump a subtable tree formatted by depth indentation.
1109  *
1110  *****************************************************************************/
1111
1112 static void
1113 DtDumpSubtableInfo (
1114     DT_SUBTABLE             *Subtable,
1115     void                    *Context,
1116     void                    *ReturnValue)
1117 {
1118
1119     DbgPrint (ASL_DEBUG_OUTPUT,
1120         "[%.04X] %24s %.08X %.08X %.08X %.08X %.08X %p %p %p\n",
1121         Subtable->Depth, Subtable->Name, Subtable->Length, Subtable->TotalLength,
1122         Subtable->SizeOfLengthField, Subtable->Flags, Subtable,
1123         Subtable->Parent, Subtable->Child, Subtable->Peer);
1124 }
1125
1126 static void
1127 DtDumpSubtableTree (
1128     DT_SUBTABLE             *Subtable,
1129     void                    *Context,
1130     void                    *ReturnValue)
1131 {
1132
1133     DbgPrint (ASL_DEBUG_OUTPUT,
1134         "[%.04X] %24s %*s%08X (%.02X) - (%.02X)\n",
1135         Subtable->Depth, Subtable->Name, (4 * Subtable->Depth), " ",
1136         Subtable, Subtable->Length, Subtable->TotalLength);
1137 }
1138
1139
1140 /******************************************************************************
1141  *
1142  * FUNCTION:    DtDumpSubtableList
1143  *
1144  * PARAMETERS:  None
1145  *
1146  * RETURN:      None
1147  *
1148  * DESCRIPTION: Dump the raw list of subtables with information, and also
1149  *              dump the subtable list in formatted tree format. Assists with
1150  *              the development of new table code.
1151  *
1152  *****************************************************************************/
1153
1154 void
1155 DtDumpSubtableList (
1156     void)
1157 {
1158
1159     if (!AslGbl_DebugFlag || !AslGbl_RootTable)
1160     {
1161         return;
1162     }
1163
1164     DbgPrint (ASL_DEBUG_OUTPUT,
1165         "Subtable Info:\n"
1166         "Depth                      Name Length   TotalLen LenSize  Flags    "
1167         "This     Parent   Child    Peer\n\n");
1168     DtWalkTableTree (AslGbl_RootTable, DtDumpSubtableInfo, NULL, NULL);
1169
1170     DbgPrint (ASL_DEBUG_OUTPUT,
1171         "\nSubtable Tree: (Depth, Name, Subtable, Length, TotalLength)\n\n");
1172     DtWalkTableTree (AslGbl_RootTable, DtDumpSubtableTree, NULL, NULL);
1173
1174     DbgPrint (ASL_DEBUG_OUTPUT, "\n");
1175 }
1176
1177
1178 /******************************************************************************
1179  *
1180  * FUNCTION:    DtWriteFieldToListing
1181  *
1182  * PARAMETERS:  Buffer              - Contains the compiled data
1183  *              Field               - Field node for the input line
1184  *              Length              - Length of the output data
1185  *
1186  * RETURN:      None
1187  *
1188  * DESCRIPTION: Write one field to the listing file (if listing is enabled).
1189  *
1190  *****************************************************************************/
1191
1192 void
1193 DtWriteFieldToListing (
1194     UINT8                   *Buffer,
1195     DT_FIELD                *Field,
1196     UINT32                  Length)
1197 {
1198     UINT8                   FileByte;
1199
1200
1201     if (!AslGbl_ListingFlag || !Field)
1202     {
1203         return;
1204     }
1205
1206     /* Dump the original source line */
1207
1208     FlPrintFile (ASL_FILE_LISTING_OUTPUT, "Input:  ");
1209     FlSeekFile (ASL_FILE_INPUT, Field->ByteOffset);
1210
1211     while (FlReadFile (ASL_FILE_INPUT, &FileByte, 1) == AE_OK)
1212     {
1213         FlWriteFile (ASL_FILE_LISTING_OUTPUT, &FileByte, 1);
1214         if (FileByte == '\n')
1215         {
1216             break;
1217         }
1218     }
1219
1220     /* Dump the line as parsed and represented internally */
1221
1222     FlPrintFile (ASL_FILE_LISTING_OUTPUT, "Parsed: %*s : %.64s",
1223         Field->Column-4, Field->Name, Field->Value);
1224
1225     if (strlen (Field->Value) > 64)
1226     {
1227         FlPrintFile (ASL_FILE_LISTING_OUTPUT, "...Additional data, length 0x%X\n",
1228             strlen (Field->Value));
1229     }
1230
1231     FlPrintFile (ASL_FILE_LISTING_OUTPUT, "\n");
1232
1233     /* Dump the hex data that will be output for this field */
1234
1235     DtDumpBuffer (ASL_FILE_LISTING_OUTPUT, Buffer, Field->TableOffset, Length);
1236 }
1237
1238
1239 /******************************************************************************
1240  *
1241  * FUNCTION:    DtWriteTableToListing
1242  *
1243  * PARAMETERS:  None
1244  *
1245  * RETURN:      None
1246  *
1247  * DESCRIPTION: Write the entire compiled table to the listing file
1248  *              in hex format
1249  *
1250  *****************************************************************************/
1251
1252 void
1253 DtWriteTableToListing (
1254     void)
1255 {
1256     UINT8                   *Buffer;
1257
1258
1259     if (!AslGbl_ListingFlag)
1260     {
1261         return;
1262     }
1263
1264     /* Read the entire table from the output file */
1265
1266     Buffer = UtLocalCalloc (AslGbl_TableLength);
1267     FlSeekFile (ASL_FILE_AML_OUTPUT, 0);
1268     FlReadFile (ASL_FILE_AML_OUTPUT, Buffer, AslGbl_TableLength);
1269
1270     /* Dump the raw table data */
1271
1272     AcpiOsRedirectOutput (AslGbl_Files[ASL_FILE_LISTING_OUTPUT].Handle);
1273
1274     AcpiOsPrintf ("\n%s: Length %d (0x%X)\n\n",
1275         ACPI_RAW_TABLE_DATA_HEADER, AslGbl_TableLength, AslGbl_TableLength);
1276     AcpiUtDumpBuffer (Buffer, AslGbl_TableLength, DB_BYTE_DISPLAY, 0);
1277
1278     AcpiOsRedirectOutput (stdout);
1279     ACPI_FREE (Buffer);
1280 }