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