Home | History | Annotate | Line # | Download | only in compiler
aslutils.c revision 1.9
      1 /******************************************************************************
      2  *
      3  * Module Name: aslutils -- compiler utilities
      4  *
      5  *****************************************************************************/
      6 
      7 /*
      8  * Copyright (C) 2000 - 2014, 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 #include "aslcompiler.h"
     45 #include "aslcompiler.y.h"
     46 #include "acdisasm.h"
     47 #include "acnamesp.h"
     48 #include "amlcode.h"
     49 #include <acapps.h>
     50 
     51 #define _COMPONENT          ACPI_COMPILER
     52         ACPI_MODULE_NAME    ("aslutils")
     53 
     54 
     55 /* Local prototypes */
     56 
     57 static void
     58 UtPadNameWithUnderscores (
     59     char                    *NameSeg,
     60     char                    *PaddedNameSeg);
     61 
     62 static void
     63 UtAttachNameseg (
     64     ACPI_PARSE_OBJECT       *Op,
     65     char                    *Name);
     66 
     67 
     68 /*******************************************************************************
     69  *
     70  * FUNCTION:    UtDisplaySupportedTables
     71  *
     72  * PARAMETERS:  None
     73  *
     74  * RETURN:      None
     75  *
     76  * DESCRIPTION: Print all supported ACPI table names.
     77  *
     78  ******************************************************************************/
     79 
     80 #define ACPI_TABLE_HELP_FORMAT  "%8u) %s    %s\n"
     81 
     82 void
     83 UtDisplaySupportedTables (
     84     void)
     85 {
     86     ACPI_DMTABLE_DATA       *TableData;
     87     UINT32                  i;
     88 
     89 
     90     printf ("\nACPI tables supported by iASL version %8.8X:\n"
     91         "  (Compiler, Disassembler, Template Generator)\n\n",
     92         ACPI_CA_VERSION);
     93 
     94     /* Special tables */
     95 
     96     printf ("  Special tables and AML tables:\n");
     97     printf (ACPI_TABLE_HELP_FORMAT, 1, ACPI_RSDP_NAME, "Root System Description Pointer");
     98     printf (ACPI_TABLE_HELP_FORMAT, 2, ACPI_SIG_FACS, "Firmware ACPI Control Structure");
     99     printf (ACPI_TABLE_HELP_FORMAT, 3, ACPI_SIG_DSDT, "Differentiated System Description Table");
    100     printf (ACPI_TABLE_HELP_FORMAT, 4, ACPI_SIG_SSDT, "Secondary System Description Table");
    101 
    102     /* All data tables with common table header */
    103 
    104     printf ("\n  Standard ACPI data tables:\n");
    105     for (TableData = AcpiDmTableData, i = 5; TableData->Signature; TableData++, i++)
    106     {
    107         printf (ACPI_TABLE_HELP_FORMAT, i, TableData->Signature, TableData->Name);
    108     }
    109 }
    110 
    111 
    112 /*******************************************************************************
    113  *
    114  * FUNCTION:    UtDisplayConstantOpcodes
    115  *
    116  * PARAMETERS:  None
    117  *
    118  * RETURN:      None
    119  *
    120  * DESCRIPTION: Print AML opcodes that can be used in constant expressions.
    121  *
    122  ******************************************************************************/
    123 
    124 void
    125 UtDisplayConstantOpcodes (
    126     void)
    127 {
    128     UINT32                  i;
    129 
    130 
    131     printf ("Constant expression opcode information\n\n");
    132 
    133     for (i = 0; i < sizeof (AcpiGbl_AmlOpInfo) / sizeof (ACPI_OPCODE_INFO); i++)
    134     {
    135         if (AcpiGbl_AmlOpInfo[i].Flags & AML_CONSTANT)
    136         {
    137             printf ("%s\n", AcpiGbl_AmlOpInfo[i].Name);
    138         }
    139     }
    140 }
    141 
    142 
    143 /*******************************************************************************
    144  *
    145  * FUNCTION:    UtLocalCalloc
    146  *
    147  * PARAMETERS:  Size                - Bytes to be allocated
    148  *
    149  * RETURN:      Pointer to the allocated memory. Guaranteed to be valid.
    150  *
    151  * DESCRIPTION: Allocate zero-initialized memory. Aborts the compile on an
    152  *              allocation failure, on the assumption that nothing more can be
    153  *              accomplished.
    154  *
    155  ******************************************************************************/
    156 
    157 void *
    158 UtLocalCalloc (
    159     UINT32                  Size)
    160 {
    161     void                    *Allocated;
    162 
    163 
    164     Allocated = ACPI_ALLOCATE_ZEROED (Size);
    165     if (!Allocated)
    166     {
    167         AslCommonError (ASL_ERROR, ASL_MSG_MEMORY_ALLOCATION,
    168             Gbl_CurrentLineNumber, Gbl_LogicalLineNumber,
    169             Gbl_InputByteCount, Gbl_CurrentColumn,
    170             Gbl_Files[ASL_FILE_INPUT].Filename, NULL);
    171 
    172         CmCleanupAndExit ();
    173         exit (1);
    174     }
    175 
    176     TotalAllocations++;
    177     TotalAllocated += Size;
    178     return (Allocated);
    179 }
    180 
    181 
    182 /*******************************************************************************
    183  *
    184  * FUNCTION:    UtBeginEvent
    185  *
    186  * PARAMETERS:  Name                - Ascii name of this event
    187  *
    188  * RETURN:      Event number (integer index)
    189  *
    190  * DESCRIPTION: Saves the current time with this event
    191  *
    192  ******************************************************************************/
    193 
    194 UINT8
    195 UtBeginEvent (
    196     char                    *Name)
    197 {
    198 
    199     if (AslGbl_NextEvent >= ASL_NUM_EVENTS)
    200     {
    201         AcpiOsPrintf ("Ran out of compiler event structs!\n");
    202         return (AslGbl_NextEvent);
    203     }
    204 
    205     /* Init event with current (start) time */
    206 
    207     AslGbl_Events[AslGbl_NextEvent].StartTime = AcpiOsGetTimer ();
    208     AslGbl_Events[AslGbl_NextEvent].EventName = Name;
    209     AslGbl_Events[AslGbl_NextEvent].Valid = TRUE;
    210 
    211     return (AslGbl_NextEvent++);
    212 }
    213 
    214 
    215 /*******************************************************************************
    216  *
    217  * FUNCTION:    UtEndEvent
    218  *
    219  * PARAMETERS:  Event               - Event number (integer index)
    220  *
    221  * RETURN:      None
    222  *
    223  * DESCRIPTION: Saves the current time (end time) with this event
    224  *
    225  ******************************************************************************/
    226 
    227 void
    228 UtEndEvent (
    229     UINT8                   Event)
    230 {
    231 
    232     if (Event >= ASL_NUM_EVENTS)
    233     {
    234         return;
    235     }
    236 
    237     /* Insert end time for event */
    238 
    239     AslGbl_Events[Event].EndTime = AcpiOsGetTimer ();
    240 }
    241 
    242 
    243 /*******************************************************************************
    244  *
    245  * FUNCTION:    UtConvertByteToHex
    246  *
    247  * PARAMETERS:  RawByte             - Binary data
    248  *              Buffer              - Pointer to where the hex bytes will be
    249  *                                    stored
    250  *
    251  * RETURN:      Ascii hex byte is stored in Buffer.
    252  *
    253  * DESCRIPTION: Perform hex-to-ascii translation. The return data is prefixed
    254  *              with "0x"
    255  *
    256  ******************************************************************************/
    257 
    258 void
    259 UtConvertByteToHex (
    260     UINT8                   RawByte,
    261     UINT8                   *Buffer)
    262 {
    263 
    264     Buffer[0] = '0';
    265     Buffer[1] = 'x';
    266 
    267     Buffer[2] = (UINT8) AcpiUtHexToAsciiChar (RawByte, 4);
    268     Buffer[3] = (UINT8) AcpiUtHexToAsciiChar (RawByte, 0);
    269 }
    270 
    271 
    272 /*******************************************************************************
    273  *
    274  * FUNCTION:    UtConvertByteToAsmHex
    275  *
    276  * PARAMETERS:  RawByte             - Binary data
    277  *              Buffer              - Pointer to where the hex bytes will be
    278  *                                    stored
    279  *
    280  * RETURN:      Ascii hex byte is stored in Buffer.
    281  *
    282  * DESCRIPTION: Perform hex-to-ascii translation. The return data is prefixed
    283  *              with '0', and a trailing 'h' is added.
    284  *
    285  ******************************************************************************/
    286 
    287 void
    288 UtConvertByteToAsmHex (
    289     UINT8                   RawByte,
    290     UINT8                   *Buffer)
    291 {
    292 
    293     Buffer[0] = '0';
    294     Buffer[1] = (UINT8) AcpiUtHexToAsciiChar (RawByte, 4);
    295     Buffer[2] = (UINT8) AcpiUtHexToAsciiChar (RawByte, 0);
    296     Buffer[3] = 'h';
    297 }
    298 
    299 
    300 /*******************************************************************************
    301  *
    302  * FUNCTION:    DbgPrint
    303  *
    304  * PARAMETERS:  Type                - Type of output
    305  *              Fmt                 - Printf format string
    306  *              ...                 - variable printf list
    307  *
    308  * RETURN:      None
    309  *
    310  * DESCRIPTION: Conditional print statement. Prints to stderr only if the
    311  *              debug flag is set.
    312  *
    313  ******************************************************************************/
    314 
    315 void
    316 DbgPrint (
    317     UINT32                  Type,
    318     char                    *Fmt,
    319     ...)
    320 {
    321     va_list                 Args;
    322 
    323 
    324     if (!Gbl_DebugFlag)
    325     {
    326         return;
    327     }
    328 
    329     if ((Type == ASL_PARSE_OUTPUT) &&
    330         (!(AslCompilerdebug)))
    331     {
    332         return;
    333     }
    334 
    335     va_start (Args, Fmt);
    336     (void) vfprintf (stderr, Fmt, Args);
    337     va_end (Args);
    338     return;
    339 }
    340 
    341 
    342 /*******************************************************************************
    343  *
    344  * FUNCTION:    UtPrintFormattedName
    345  *
    346  * PARAMETERS:  ParseOpcode         - Parser keyword ID
    347  *              Level               - Indentation level
    348  *
    349  * RETURN:      None
    350  *
    351  * DESCRIPTION: Print the ascii name of the parse opcode.
    352  *
    353  ******************************************************************************/
    354 
    355 #define TEXT_OFFSET 10
    356 
    357 void
    358 UtPrintFormattedName (
    359     UINT16                  ParseOpcode,
    360     UINT32                  Level)
    361 {
    362 
    363     if (Level)
    364     {
    365         DbgPrint (ASL_TREE_OUTPUT,
    366             "%*s", (3 * Level), " ");
    367     }
    368     DbgPrint (ASL_TREE_OUTPUT,
    369         " %-20.20s", UtGetOpName (ParseOpcode));
    370 
    371     if (Level < TEXT_OFFSET)
    372     {
    373         DbgPrint (ASL_TREE_OUTPUT,
    374             "%*s", (TEXT_OFFSET - Level) * 3, " ");
    375     }
    376 }
    377 
    378 
    379 /*******************************************************************************
    380  *
    381  * FUNCTION:    UtSetParseOpName
    382  *
    383  * PARAMETERS:  Op                  - Parse op to be named.
    384  *
    385  * RETURN:      None
    386  *
    387  * DESCRIPTION: Insert the ascii name of the parse opcode
    388  *
    389  ******************************************************************************/
    390 
    391 void
    392 UtSetParseOpName (
    393     ACPI_PARSE_OBJECT       *Op)
    394 {
    395 
    396     strncpy (Op->Asl.ParseOpName, UtGetOpName (Op->Asl.ParseOpcode),
    397         ACPI_MAX_PARSEOP_NAME);
    398 }
    399 
    400 
    401 /*******************************************************************************
    402  *
    403  * FUNCTION:    UtDisplaySummary
    404  *
    405  * PARAMETERS:  FileID              - ID of outpout file
    406  *
    407  * RETURN:      None
    408  *
    409  * DESCRIPTION: Display compilation statistics
    410  *
    411  ******************************************************************************/
    412 
    413 void
    414 UtDisplaySummary (
    415     UINT32                  FileId)
    416 {
    417     UINT32                  i;
    418 
    419 
    420     if (FileId != ASL_FILE_STDOUT)
    421     {
    422         /* Compiler name and version number */
    423 
    424         FlPrintFile (FileId, "%s version %X%s [%s]\n\n",
    425             ASL_COMPILER_NAME, (UINT32) ACPI_CA_VERSION, ACPI_WIDTH, ACPI_DATE);
    426     }
    427 
    428     /* Summary of main input and output files */
    429 
    430     if (Gbl_FileType == ASL_INPUT_TYPE_ASCII_DATA)
    431     {
    432         FlPrintFile (FileId,
    433             "%-14s %s - %u lines, %u bytes, %u fields\n",
    434             "Table Input:",
    435             Gbl_Files[ASL_FILE_INPUT].Filename, Gbl_CurrentLineNumber,
    436             Gbl_InputByteCount, Gbl_InputFieldCount);
    437 
    438         if ((Gbl_ExceptionCount[ASL_ERROR] == 0) || (Gbl_IgnoreErrors))
    439         {
    440             FlPrintFile (FileId,
    441                 "%-14s %s - %u bytes\n",
    442                 "Binary Output:",
    443                 Gbl_Files[ASL_FILE_AML_OUTPUT].Filename, Gbl_TableLength);
    444         }
    445     }
    446     else
    447     {
    448         FlPrintFile (FileId,
    449             "%-14s %s - %u lines, %u bytes, %u keywords\n",
    450             "ASL Input:",
    451             Gbl_Files[ASL_FILE_INPUT].Filename, Gbl_CurrentLineNumber,
    452             Gbl_InputByteCount, TotalKeywords);
    453 
    454         /* AML summary */
    455 
    456         if ((Gbl_ExceptionCount[ASL_ERROR] == 0) || (Gbl_IgnoreErrors))
    457         {
    458             FlPrintFile (FileId,
    459                 "%-14s %s - %u bytes, %u named objects, %u executable opcodes\n",
    460                 "AML Output:",
    461                 Gbl_Files[ASL_FILE_AML_OUTPUT].Filename, Gbl_TableLength,
    462                 TotalNamedObjects, TotalExecutableOpcodes);
    463         }
    464     }
    465 
    466     /* Display summary of any optional files */
    467 
    468     for (i = ASL_FILE_SOURCE_OUTPUT; i <= ASL_MAX_FILE_TYPE; i++)
    469     {
    470         if (!Gbl_Files[i].Filename || !Gbl_Files[i].Handle)
    471         {
    472             continue;
    473         }
    474 
    475         /* .SRC is a temp file unless specifically requested */
    476 
    477         if ((i == ASL_FILE_SOURCE_OUTPUT) && (!Gbl_SourceOutputFlag))
    478         {
    479             continue;
    480         }
    481 
    482         /* .I is a temp file unless specifically requested */
    483 
    484         if ((i == ASL_FILE_PREPROCESSOR) && (!Gbl_PreprocessorOutputFlag))
    485         {
    486             continue;
    487         }
    488 
    489         FlPrintFile (FileId, "%14s %s - %u bytes\n",
    490             Gbl_Files[i].ShortDescription,
    491             Gbl_Files[i].Filename, FlGetFileSize (i));
    492     }
    493 
    494     /* Error summary */
    495 
    496     FlPrintFile (FileId,
    497         "\nCompilation complete. %u Errors, %u Warnings, %u Remarks",
    498         Gbl_ExceptionCount[ASL_ERROR],
    499         Gbl_ExceptionCount[ASL_WARNING] +
    500             Gbl_ExceptionCount[ASL_WARNING2] +
    501             Gbl_ExceptionCount[ASL_WARNING3],
    502         Gbl_ExceptionCount[ASL_REMARK]);
    503 
    504     if (Gbl_FileType != ASL_INPUT_TYPE_ASCII_DATA)
    505     {
    506         FlPrintFile (FileId,
    507             ", %u Optimizations", Gbl_ExceptionCount[ASL_OPTIMIZATION]);
    508     }
    509 
    510     FlPrintFile (FileId, "\n");
    511 }
    512 
    513 
    514 /*******************************************************************************
    515  *
    516  * FUNCTION:    UtCheckIntegerRange
    517  *
    518  * PARAMETERS:  Op                  - Integer parse node
    519  *              LowValue            - Smallest allowed value
    520  *              HighValue           - Largest allowed value
    521  *
    522  * RETURN:      Op if OK, otherwise NULL
    523  *
    524  * DESCRIPTION: Check integer for an allowable range
    525  *
    526  ******************************************************************************/
    527 
    528 ACPI_PARSE_OBJECT *
    529 UtCheckIntegerRange (
    530     ACPI_PARSE_OBJECT       *Op,
    531     UINT32                  LowValue,
    532     UINT32                  HighValue)
    533 {
    534 
    535     if (!Op)
    536     {
    537         return (NULL);
    538     }
    539 
    540     if ((Op->Asl.Value.Integer < LowValue) ||
    541         (Op->Asl.Value.Integer > HighValue))
    542     {
    543         snprintf (MsgBuffer, sizeof(MsgBuffer), "0x%X, allowable: 0x%X-0x%X",
    544             (UINT32) Op->Asl.Value.Integer, LowValue, HighValue);
    545 
    546         AslError (ASL_ERROR, ASL_MSG_RANGE, Op, MsgBuffer);
    547         return (NULL);
    548     }
    549 
    550     return (Op);
    551 }
    552 
    553 
    554 /*******************************************************************************
    555  *
    556  * FUNCTION:    UtStringCacheCalloc
    557  *
    558  * PARAMETERS:  Length              - Size of buffer requested
    559  *
    560  * RETURN:      Pointer to the buffer. Aborts on allocation failure
    561  *
    562  * DESCRIPTION: Allocate a string buffer. Bypass the local
    563  *              dynamic memory manager for performance reasons (This has a
    564  *              major impact on the speed of the compiler.)
    565  *
    566  ******************************************************************************/
    567 
    568 char *
    569 UtStringCacheCalloc (
    570     UINT32                  Length)
    571 {
    572     char                    *Buffer;
    573     ASL_CACHE_INFO          *Cache;
    574 
    575 
    576     if (Length > ASL_STRING_CACHE_SIZE)
    577     {
    578         Buffer = UtLocalCalloc (Length);
    579         return (Buffer);
    580     }
    581 
    582     if ((Gbl_StringCacheNext + Length) >= Gbl_StringCacheLast)
    583     {
    584         /* Allocate a new buffer */
    585 
    586         Cache = UtLocalCalloc (sizeof (Cache->Next) +
    587             ASL_STRING_CACHE_SIZE);
    588 
    589         /* Link new cache buffer to head of list */
    590 
    591         Cache->Next = Gbl_StringCacheList;
    592         Gbl_StringCacheList = Cache;
    593 
    594         /* Setup cache management pointers */
    595 
    596         Gbl_StringCacheNext = Cache->Buffer;
    597         Gbl_StringCacheLast = Gbl_StringCacheNext + ASL_STRING_CACHE_SIZE;
    598     }
    599 
    600     Gbl_StringCount++;
    601     Gbl_StringSize += Length;
    602 
    603     Buffer = Gbl_StringCacheNext;
    604     Gbl_StringCacheNext += Length;
    605     return (Buffer);
    606 }
    607 
    608 
    609 /******************************************************************************
    610  *
    611  * FUNCTION:    UtExpandLineBuffers
    612  *
    613  * PARAMETERS:  None. Updates global line buffer pointers.
    614  *
    615  * RETURN:      None. Reallocates the global line buffers
    616  *
    617  * DESCRIPTION: Called if the current line buffer becomes filled. Reallocates
    618  *              all global line buffers and updates Gbl_LineBufferSize. NOTE:
    619  *              Also used for the initial allocation of the buffers, when
    620  *              all of the buffer pointers are NULL. Initial allocations are
    621  *              of size ASL_DEFAULT_LINE_BUFFER_SIZE
    622  *
    623  *****************************************************************************/
    624 
    625 void
    626 UtExpandLineBuffers (
    627     void)
    628 {
    629     UINT32                  NewSize;
    630 
    631 
    632     /* Attempt to double the size of all line buffers */
    633 
    634     NewSize = Gbl_LineBufferSize * 2;
    635     if (Gbl_CurrentLineBuffer)
    636     {
    637         DbgPrint (ASL_DEBUG_OUTPUT,
    638             "Increasing line buffer size from %u to %u\n",
    639             Gbl_LineBufferSize, NewSize);
    640     }
    641 
    642     Gbl_CurrentLineBuffer = realloc (Gbl_CurrentLineBuffer, NewSize);
    643     Gbl_LineBufPtr = Gbl_CurrentLineBuffer;
    644     if (!Gbl_CurrentLineBuffer)
    645     {
    646         goto ErrorExit;
    647     }
    648 
    649     Gbl_MainTokenBuffer = realloc (Gbl_MainTokenBuffer, NewSize);
    650     if (!Gbl_MainTokenBuffer)
    651     {
    652         goto ErrorExit;
    653     }
    654 
    655     Gbl_MacroTokenBuffer = realloc (Gbl_MacroTokenBuffer, NewSize);
    656     if (!Gbl_MacroTokenBuffer)
    657     {
    658         goto ErrorExit;
    659     }
    660 
    661     Gbl_ExpressionTokenBuffer = realloc (Gbl_ExpressionTokenBuffer, NewSize);
    662     if (!Gbl_ExpressionTokenBuffer)
    663     {
    664         goto ErrorExit;
    665     }
    666 
    667     Gbl_LineBufferSize = NewSize;
    668     return;
    669 
    670 
    671     /* On error above, simply issue error messages and abort, cannot continue */
    672 
    673 ErrorExit:
    674     printf ("Could not increase line buffer size from %u to %u\n",
    675         Gbl_LineBufferSize, Gbl_LineBufferSize * 2);
    676 
    677     AslError (ASL_ERROR, ASL_MSG_BUFFER_ALLOCATION,
    678         NULL, NULL);
    679     AslAbort ();
    680 }
    681 
    682 
    683 /******************************************************************************
    684  *
    685  * FUNCTION:    UtFreeLineBuffers
    686  *
    687  * PARAMETERS:  None
    688  *
    689  * RETURN:      None
    690  *
    691  * DESCRIPTION: Free all line buffers
    692  *
    693  *****************************************************************************/
    694 
    695 void
    696 UtFreeLineBuffers (
    697     void)
    698 {
    699 
    700     free (Gbl_CurrentLineBuffer);
    701     free (Gbl_MainTokenBuffer);
    702     free (Gbl_MacroTokenBuffer);
    703     free (Gbl_ExpressionTokenBuffer);
    704 }
    705 
    706 
    707 /*******************************************************************************
    708  *
    709  * FUNCTION:    UtInternalizeName
    710  *
    711  * PARAMETERS:  ExternalName        - Name to convert
    712  *              ConvertedName       - Where the converted name is returned
    713  *
    714  * RETURN:      Status
    715  *
    716  * DESCRIPTION: Convert an external (ASL) name to an internal (AML) name
    717  *
    718  ******************************************************************************/
    719 
    720 ACPI_STATUS
    721 UtInternalizeName (
    722     char                    *ExternalName,
    723     char                    **ConvertedName)
    724 {
    725     ACPI_NAMESTRING_INFO    Info;
    726     ACPI_STATUS             Status;
    727 
    728 
    729     if (!ExternalName)
    730     {
    731         return (AE_OK);
    732     }
    733 
    734     /* Get the length of the new internal name */
    735 
    736     Info.ExternalName = ExternalName;
    737     AcpiNsGetInternalNameLength (&Info);
    738 
    739     /* We need a segment to store the internal name */
    740 
    741     Info.InternalName = UtStringCacheCalloc (Info.Length);
    742     if (!Info.InternalName)
    743     {
    744         return (AE_NO_MEMORY);
    745     }
    746 
    747     /* Build the name */
    748 
    749     Status = AcpiNsBuildInternalName (&Info);
    750     if (ACPI_FAILURE (Status))
    751     {
    752         return (Status);
    753     }
    754 
    755     *ConvertedName = Info.InternalName;
    756     return (AE_OK);
    757 }
    758 
    759 
    760 /*******************************************************************************
    761  *
    762  * FUNCTION:    UtPadNameWithUnderscores
    763  *
    764  * PARAMETERS:  NameSeg             - Input nameseg
    765  *              PaddedNameSeg       - Output padded nameseg
    766  *
    767  * RETURN:      Padded nameseg.
    768  *
    769  * DESCRIPTION: Pads a NameSeg with underscores if necessary to form a full
    770  *              ACPI_NAME.
    771  *
    772  ******************************************************************************/
    773 
    774 static void
    775 UtPadNameWithUnderscores (
    776     char                    *NameSeg,
    777     char                    *PaddedNameSeg)
    778 {
    779     UINT32                  i;
    780 
    781 
    782     for (i = 0; (i < ACPI_NAME_SIZE); i++)
    783     {
    784         if (*NameSeg)
    785         {
    786             *PaddedNameSeg = *NameSeg;
    787             NameSeg++;
    788         }
    789         else
    790         {
    791             *PaddedNameSeg = '_';
    792         }
    793         PaddedNameSeg++;
    794     }
    795 }
    796 
    797 
    798 /*******************************************************************************
    799  *
    800  * FUNCTION:    UtAttachNameseg
    801  *
    802  * PARAMETERS:  Op                  - Parent parse node
    803  *              Name                - Full ExternalName
    804  *
    805  * RETURN:      None; Sets the NameSeg field in parent node
    806  *
    807  * DESCRIPTION: Extract the last nameseg of the ExternalName and store it
    808  *              in the NameSeg field of the Op.
    809  *
    810  ******************************************************************************/
    811 
    812 static void
    813 UtAttachNameseg (
    814     ACPI_PARSE_OBJECT       *Op,
    815     char                    *Name)
    816 {
    817     char                    *NameSeg;
    818     char                    PaddedNameSeg[4];
    819 
    820 
    821     if (!Name)
    822     {
    823         return;
    824     }
    825 
    826     /* Look for the last dot in the namepath */
    827 
    828     NameSeg = strrchr (Name, '.');
    829     if (NameSeg)
    830     {
    831         /* Found last dot, we have also found the final nameseg */
    832 
    833         NameSeg++;
    834         UtPadNameWithUnderscores (NameSeg, PaddedNameSeg);
    835     }
    836     else
    837     {
    838         /* No dots in the namepath, there is only a single nameseg. */
    839         /* Handle prefixes */
    840 
    841         while (ACPI_IS_ROOT_PREFIX (*Name) ||
    842                ACPI_IS_PARENT_PREFIX (*Name))
    843         {
    844             Name++;
    845         }
    846 
    847         /* Remaining string should be one single nameseg */
    848 
    849         UtPadNameWithUnderscores (Name, PaddedNameSeg);
    850     }
    851 
    852     ACPI_MOVE_NAME (Op->Asl.NameSeg, PaddedNameSeg);
    853 }
    854 
    855 
    856 /*******************************************************************************
    857  *
    858  * FUNCTION:    UtAttachNamepathToOwner
    859  *
    860  * PARAMETERS:  Op                  - Parent parse node
    861  *              NameOp              - Node that contains the name
    862  *
    863  * RETURN:      Sets the ExternalName and Namepath in the parent node
    864  *
    865  * DESCRIPTION: Store the name in two forms in the parent node: The original
    866  *              (external) name, and the internalized name that is used within
    867  *              the ACPI namespace manager.
    868  *
    869  ******************************************************************************/
    870 
    871 void
    872 UtAttachNamepathToOwner (
    873     ACPI_PARSE_OBJECT       *Op,
    874     ACPI_PARSE_OBJECT       *NameOp)
    875 {
    876     ACPI_STATUS             Status;
    877 
    878 
    879     /* Full external path */
    880 
    881     Op->Asl.ExternalName = NameOp->Asl.Value.String;
    882 
    883     /* Save the NameOp for possible error reporting later */
    884 
    885     Op->Asl.ParentMethod = (void *) NameOp;
    886 
    887     /* Last nameseg of the path */
    888 
    889     UtAttachNameseg (Op, Op->Asl.ExternalName);
    890 
    891     /* Create internalized path */
    892 
    893     Status = UtInternalizeName (NameOp->Asl.Value.String, &Op->Asl.Namepath);
    894     if (ACPI_FAILURE (Status))
    895     {
    896         /* TBD: abort on no memory */
    897     }
    898 }
    899 
    900 
    901 /*******************************************************************************
    902  *
    903  * FUNCTION:    UtDoConstant
    904  *
    905  * PARAMETERS:  String              - Hex, Octal, or Decimal string
    906  *
    907  * RETURN:      Converted Integer
    908  *
    909  * DESCRIPTION: Convert a string to an integer, with error checking.
    910  *
    911  ******************************************************************************/
    912 
    913 UINT64
    914 UtDoConstant (
    915     char                    *String)
    916 {
    917     ACPI_STATUS             Status;
    918     UINT64                  Converted;
    919     char                    ErrBuf[64];
    920 
    921 
    922     Status = UtStrtoul64 (String, 0, &Converted);
    923     if (ACPI_FAILURE (Status))
    924     {
    925         snprintf (ErrBuf, sizeof(ErrBuf), "%s %s\n", "Conversion error:",
    926             AcpiFormatException (Status));
    927         AslCompilererror (ErrBuf);
    928     }
    929 
    930     return (Converted);
    931 }
    932 
    933 
    934 /* TBD: use version in ACPICA main code base? */
    935 
    936 /*******************************************************************************
    937  *
    938  * FUNCTION:    UtStrtoul64
    939  *
    940  * PARAMETERS:  String              - Null terminated string
    941  *              Terminater          - Where a pointer to the terminating byte
    942  *                                    is returned
    943  *              Base                - Radix of the string
    944  *
    945  * RETURN:      Converted value
    946  *
    947  * DESCRIPTION: Convert a string into an unsigned value.
    948  *
    949  ******************************************************************************/
    950 
    951 ACPI_STATUS
    952 UtStrtoul64 (
    953     char                    *String,
    954     UINT32                  Base,
    955     UINT64                  *RetInteger)
    956 {
    957     UINT32                  Index;
    958     UINT32                  Sign;
    959     UINT64                  ReturnValue = 0;
    960     ACPI_STATUS             Status = AE_OK;
    961 
    962 
    963     *RetInteger = 0;
    964 
    965     switch (Base)
    966     {
    967     case 0:
    968     case 8:
    969     case 10:
    970     case 16:
    971 
    972         break;
    973 
    974     default:
    975         /*
    976          * The specified Base parameter is not in the domain of
    977          * this function:
    978          */
    979         return (AE_BAD_PARAMETER);
    980     }
    981 
    982     /* Skip over any white space in the buffer: */
    983 
    984     while (isspace ((int) *String) || *String == '\t')
    985     {
    986         ++String;
    987     }
    988 
    989     /*
    990      * The buffer may contain an optional plus or minus sign.
    991      * If it does, then skip over it but remember what is was:
    992      */
    993     if (*String == '-')
    994     {
    995         Sign = NEGATIVE;
    996         ++String;
    997     }
    998     else if (*String == '+')
    999     {
   1000         ++String;
   1001         Sign = POSITIVE;
   1002     }
   1003     else
   1004     {
   1005         Sign = POSITIVE;
   1006     }
   1007 
   1008     /*
   1009      * If the input parameter Base is zero, then we need to
   1010      * determine if it is octal, decimal, or hexadecimal:
   1011      */
   1012     if (Base == 0)
   1013     {
   1014         if (*String == '0')
   1015         {
   1016             if (tolower ((int) *(++String)) == 'x')
   1017             {
   1018                 Base = 16;
   1019                 ++String;
   1020             }
   1021             else
   1022             {
   1023                 Base = 8;
   1024             }
   1025         }
   1026         else
   1027         {
   1028             Base = 10;
   1029         }
   1030     }
   1031 
   1032     /*
   1033      * For octal and hexadecimal bases, skip over the leading
   1034      * 0 or 0x, if they are present.
   1035      */
   1036     if (Base == 8 && *String == '0')
   1037     {
   1038         String++;
   1039     }
   1040 
   1041     if (Base == 16 &&
   1042         *String == '0' &&
   1043         tolower ((int) *(++String)) == 'x')
   1044     {
   1045         String++;
   1046     }
   1047 
   1048     /* Main loop: convert the string to an unsigned long */
   1049 
   1050     while (*String)
   1051     {
   1052         if (isdigit ((int) *String))
   1053         {
   1054             Index = ((UINT8) *String) - '0';
   1055         }
   1056         else
   1057         {
   1058             Index = (UINT8) toupper ((int) *String);
   1059             if (isupper ((int) Index))
   1060             {
   1061                 Index = Index - 'A' + 10;
   1062             }
   1063             else
   1064             {
   1065                 goto ErrorExit;
   1066             }
   1067         }
   1068 
   1069         if (Index >= Base)
   1070         {
   1071             goto ErrorExit;
   1072         }
   1073 
   1074         /* Check to see if value is out of range: */
   1075 
   1076         if (ReturnValue > ((ACPI_UINT64_MAX - (UINT64) Index) /
   1077                             (UINT64) Base))
   1078         {
   1079             goto ErrorExit;
   1080         }
   1081         else
   1082         {
   1083             ReturnValue *= Base;
   1084             ReturnValue += Index;
   1085         }
   1086 
   1087         ++String;
   1088     }
   1089 
   1090 
   1091     /* If a minus sign was present, then "the conversion is negated": */
   1092 
   1093     if (Sign == NEGATIVE)
   1094     {
   1095         ReturnValue = (ACPI_UINT32_MAX - ReturnValue) + 1;
   1096     }
   1097 
   1098     *RetInteger = ReturnValue;
   1099     return (Status);
   1100 
   1101 
   1102 ErrorExit:
   1103     switch (Base)
   1104     {
   1105     case 8:
   1106 
   1107         Status = AE_BAD_OCTAL_CONSTANT;
   1108         break;
   1109 
   1110     case 10:
   1111 
   1112         Status = AE_BAD_DECIMAL_CONSTANT;
   1113         break;
   1114 
   1115     case 16:
   1116 
   1117         Status = AE_BAD_HEX_CONSTANT;
   1118         break;
   1119 
   1120     default:
   1121 
   1122         /* Base validated above */
   1123 
   1124         break;
   1125     }
   1126 
   1127     return (Status);
   1128 }
   1129