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