Home | History | Annotate | Line # | Download | only in compiler
aslutils.c revision 1.1
      1 
      2 /******************************************************************************
      3  *
      4  * Module Name: aslutils -- compiler utilities
      5  *
      6  *****************************************************************************/
      7 
      8 /******************************************************************************
      9  *
     10  * 1. Copyright Notice
     11  *
     12  * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp.
     13  * All rights reserved.
     14  *
     15  * 2. License
     16  *
     17  * 2.1. This is your license from Intel Corp. under its intellectual property
     18  * rights.  You may have additional license terms from the party that provided
     19  * you this software, covering your right to use that party's intellectual
     20  * property rights.
     21  *
     22  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
     23  * copy of the source code appearing in this file ("Covered Code") an
     24  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
     25  * base code distributed originally by Intel ("Original Intel Code") to copy,
     26  * make derivatives, distribute, use and display any portion of the Covered
     27  * Code in any form, with the right to sublicense such rights; and
     28  *
     29  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
     30  * license (with the right to sublicense), under only those claims of Intel
     31  * patents that are infringed by the Original Intel Code, to make, use, sell,
     32  * offer to sell, and import the Covered Code and derivative works thereof
     33  * solely to the minimum extent necessary to exercise the above copyright
     34  * license, and in no event shall the patent license extend to any additions
     35  * to or modifications of the Original Intel Code.  No other license or right
     36  * is granted directly or by implication, estoppel or otherwise;
     37  *
     38  * The above copyright and patent license is granted only if the following
     39  * conditions are met:
     40  *
     41  * 3. Conditions
     42  *
     43  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
     44  * Redistribution of source code of any substantial portion of the Covered
     45  * Code or modification with rights to further distribute source must include
     46  * the above Copyright Notice, the above License, this list of Conditions,
     47  * and the following Disclaimer and Export Compliance provision.  In addition,
     48  * Licensee must cause all Covered Code to which Licensee contributes to
     49  * contain a file documenting the changes Licensee made to create that Covered
     50  * Code and the date of any change.  Licensee must include in that file the
     51  * documentation of any changes made by any predecessor Licensee.  Licensee
     52  * must include a prominent statement that the modification is derived,
     53  * directly or indirectly, from Original Intel Code.
     54  *
     55  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
     56  * Redistribution of source code of any substantial portion of the Covered
     57  * Code or modification without rights to further distribute source must
     58  * include the following Disclaimer and Export Compliance provision in the
     59  * documentation and/or other materials provided with distribution.  In
     60  * addition, Licensee may not authorize further sublicense of source of any
     61  * portion of the Covered Code, and must include terms to the effect that the
     62  * license from Licensee to its licensee is limited to the intellectual
     63  * property embodied in the software Licensee provides to its licensee, and
     64  * not to intellectual property embodied in modifications its licensee may
     65  * make.
     66  *
     67  * 3.3. Redistribution of Executable. Redistribution in executable form of any
     68  * substantial portion of the Covered Code or modification must reproduce the
     69  * above Copyright Notice, and the following Disclaimer and Export Compliance
     70  * provision in the documentation and/or other materials provided with the
     71  * distribution.
     72  *
     73  * 3.4. Intel retains all right, title, and interest in and to the Original
     74  * Intel Code.
     75  *
     76  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
     77  * Intel shall be used in advertising or otherwise to promote the sale, use or
     78  * other dealings in products derived from or relating to the Covered Code
     79  * without prior written authorization from Intel.
     80  *
     81  * 4. Disclaimer and Export Compliance
     82  *
     83  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
     84  * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
     85  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
     86  * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
     87  * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
     88  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
     89  * PARTICULAR PURPOSE.
     90  *
     91  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
     92  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
     93  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
     94  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
     95  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
     96  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
     97  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
     98  * LIMITED REMEDY.
     99  *
    100  * 4.3. Licensee shall not export, either directly or indirectly, any of this
    101  * software or system incorporating such software without first obtaining any
    102  * required license or other approval from the U. S. Department of Commerce or
    103  * any other agency or department of the United States Government.  In the
    104  * event Licensee exports any such software from the United States or
    105  * re-exports any such software from a foreign destination, Licensee shall
    106  * ensure that the distribution and export/re-export of the software is in
    107  * compliance with all laws, regulations, orders, or other restrictions of the
    108  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
    109  * any of its subsidiaries will export/re-export any technical data, process,
    110  * software, or service, directly or indirectly, to any country for which the
    111  * United States government or any agency thereof requires an export license,
    112  * other governmental approval, or letter of assurance, without first obtaining
    113  * such license, approval or letter.
    114  *
    115  *****************************************************************************/
    116 
    117 
    118 #include "aslcompiler.h"
    119 #include "aslcompiler.y.h"
    120 #include "acnamesp.h"
    121 #include "amlcode.h"
    122 
    123 #define _COMPONENT          ACPI_COMPILER
    124         ACPI_MODULE_NAME    ("aslutils")
    125 
    126 #ifdef _USE_BERKELEY_YACC
    127 extern const char * const       AslCompilername[];
    128 static const char * const       *yytname = &AslCompilername[254];
    129 #else
    130 extern const char * const       yytname[];
    131 #endif
    132 
    133 char                    HexLookup[] =
    134 {
    135     '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'
    136 };
    137 
    138 
    139 /* Local prototypes */
    140 
    141 static ACPI_STATUS
    142 UtStrtoul64 (
    143     char                    *String,
    144     UINT32                  Base,
    145     UINT64                  *RetInteger);
    146 
    147 static void
    148 UtPadNameWithUnderscores (
    149     char                    *NameSeg,
    150     char                    *PaddedNameSeg);
    151 
    152 static void
    153 UtAttachNameseg (
    154     ACPI_PARSE_OBJECT       *Op,
    155     char                    *Name);
    156 
    157 
    158 /*******************************************************************************
    159  *
    160  * FUNCTION:    AcpiPsDisplayConstantOpcodes
    161  *
    162  * PARAMETERS:  None
    163  *
    164  * RETURN:      None
    165  *
    166  * DESCRIPTION: Print AML opcodes that can be used in constant expressions.
    167  *
    168  ******************************************************************************/
    169 
    170 void
    171 UtDisplayConstantOpcodes (
    172     void)
    173 {
    174     UINT32                  i;
    175 
    176 
    177     printf ("Constant expression opcode information\n\n");
    178 
    179     for (i = 0; i < sizeof (AcpiGbl_AmlOpInfo) / sizeof (ACPI_OPCODE_INFO); i++)
    180     {
    181         if (AcpiGbl_AmlOpInfo[i].Flags & AML_CONSTANT)
    182         {
    183             printf ("%s\n", AcpiGbl_AmlOpInfo[i].Name);
    184         }
    185     }
    186 }
    187 
    188 
    189 /*******************************************************************************
    190  *
    191  * FUNCTION:    UtLocalCalloc
    192  *
    193  * PARAMETERS:  Size        - Bytes to be allocated
    194  *
    195  * RETURN:      Pointer to the allocated memory.  Guaranteed to be valid.
    196  *
    197  * DESCRIPTION: Allocate zero-initialized memory.  Aborts the compile on an
    198  *              allocation failure, on the assumption that nothing more can be
    199  *              accomplished.
    200  *
    201  ******************************************************************************/
    202 
    203 void *
    204 UtLocalCalloc (
    205     UINT32                  Size)
    206 {
    207     void                    *Allocated;
    208 
    209 
    210     Allocated = ACPI_ALLOCATE_ZEROED (Size);
    211     if (!Allocated)
    212     {
    213         AslCommonError (ASL_ERROR, ASL_MSG_MEMORY_ALLOCATION,
    214             Gbl_CurrentLineNumber, Gbl_LogicalLineNumber,
    215             Gbl_InputByteCount, Gbl_CurrentColumn,
    216             Gbl_Files[ASL_FILE_INPUT].Filename, NULL);
    217 
    218         CmCleanupAndExit ();
    219         exit (1);
    220     }
    221 
    222     TotalAllocations++;
    223     TotalAllocated += Size;
    224     return (Allocated);
    225 }
    226 
    227 
    228 /*******************************************************************************
    229  *
    230  * FUNCTION:    UtBeginEvent
    231  *
    232  * PARAMETERS:  Name        - Ascii name of this event
    233  *
    234  * RETURN:      Event       - Event number (integer index)
    235  *
    236  * DESCRIPTION: Saves the current time with this event
    237  *
    238  ******************************************************************************/
    239 
    240 UINT8
    241 UtBeginEvent (
    242     char                    *Name)
    243 {
    244 
    245     if (AslGbl_NextEvent >= ASL_NUM_EVENTS)
    246     {
    247         AcpiOsPrintf ("Ran out of compiler event structs!\n");
    248         return (AslGbl_NextEvent);
    249     }
    250 
    251     /* Init event with current (start) time */
    252 
    253     AslGbl_Events[AslGbl_NextEvent].StartTime = AcpiOsGetTimer ();
    254     AslGbl_Events[AslGbl_NextEvent].EventName = Name;
    255     AslGbl_Events[AslGbl_NextEvent].Valid = TRUE;
    256 
    257     return (AslGbl_NextEvent++);
    258 }
    259 
    260 
    261 /*******************************************************************************
    262  *
    263  * FUNCTION:    UtEndEvent
    264  *
    265  * PARAMETERS:  Event       - Event number (integer index)
    266  *
    267  * RETURN:      None
    268  *
    269  * DESCRIPTION: Saves the current time (end time) with this event
    270  *
    271  ******************************************************************************/
    272 
    273 void
    274 UtEndEvent (
    275     UINT8                  Event)
    276 {
    277 
    278     if (Event >= ASL_NUM_EVENTS)
    279     {
    280         return;
    281     }
    282 
    283     /* Insert end time for event */
    284 
    285     AslGbl_Events[Event].EndTime = AcpiOsGetTimer ();
    286 }
    287 
    288 
    289 /*******************************************************************************
    290  *
    291  * FUNCTION:    UtHexCharToValue
    292  *
    293  * PARAMETERS:  HexChar         - Hex character in Ascii
    294  *
    295  * RETURN:      The binary value of the hex character
    296  *
    297  * DESCRIPTION: Perform ascii-to-hex translation
    298  *
    299  ******************************************************************************/
    300 
    301 UINT8
    302 UtHexCharToValue (
    303     int                     HexChar)
    304 {
    305 
    306     if (HexChar <= 0x39)
    307     {
    308         return ((UINT8) (HexChar - 0x30));
    309     }
    310 
    311     if (HexChar <= 0x46)
    312     {
    313         return ((UINT8) (HexChar - 0x37));
    314     }
    315 
    316     return ((UINT8) (HexChar - 0x57));
    317 }
    318 
    319 
    320 /*******************************************************************************
    321  *
    322  * FUNCTION:    UtConvertByteToHex
    323  *
    324  * PARAMETERS:  RawByte         - Binary data
    325  *              Buffer          - Pointer to where the hex bytes will be stored
    326  *
    327  * RETURN:      Ascii hex byte is stored in Buffer.
    328  *
    329  * DESCRIPTION: Perform hex-to-ascii translation.  The return data is prefixed
    330  *              with "0x"
    331  *
    332  ******************************************************************************/
    333 
    334 void
    335 UtConvertByteToHex (
    336     UINT8                   RawByte,
    337     UINT8                   *Buffer)
    338 {
    339 
    340     Buffer[0] = '0';
    341     Buffer[1] = 'x';
    342 
    343     Buffer[2] = (UINT8) HexLookup[(RawByte >> 4) & 0xF];
    344     Buffer[3] = (UINT8) HexLookup[RawByte & 0xF];
    345 }
    346 
    347 
    348 /*******************************************************************************
    349  *
    350  * FUNCTION:    UtConvertByteToAsmHex
    351  *
    352  * PARAMETERS:  RawByte         - Binary data
    353  *              Buffer          - Pointer to where the hex bytes will be stored
    354  *
    355  * RETURN:      Ascii hex byte is stored in Buffer.
    356  *
    357  * DESCRIPTION: Perform hex-to-ascii translation.  The return data is prefixed
    358  *              with "0x"
    359  *
    360  ******************************************************************************/
    361 
    362 void
    363 UtConvertByteToAsmHex (
    364     UINT8                   RawByte,
    365     UINT8                   *Buffer)
    366 {
    367 
    368     Buffer[0] = '0';
    369     Buffer[1] = (UINT8) HexLookup[(RawByte >> 4) & 0xF];
    370     Buffer[2] = (UINT8) HexLookup[RawByte & 0xF];
    371     Buffer[3] = 'h';
    372 }
    373 
    374 
    375 /*******************************************************************************
    376  *
    377  * FUNCTION:    DbgPrint
    378  *
    379  * PARAMETERS:  Type            - Type of output
    380  *              Fmt             - Printf format string
    381  *              ...             - variable printf list
    382  *
    383  * RETURN:      None
    384  *
    385  * DESCRIPTION: Conditional print statement.  Prints to stderr only if the
    386  *              debug flag is set.
    387  *
    388  ******************************************************************************/
    389 
    390 void
    391 DbgPrint (
    392     UINT32                  Type,
    393     char                    *Fmt,
    394     ...)
    395 {
    396     va_list                 Args;
    397 
    398 
    399     va_start (Args, Fmt);
    400 
    401     if (!Gbl_DebugFlag)
    402     {
    403         return;
    404     }
    405 
    406     if ((Type == ASL_PARSE_OUTPUT) &&
    407         (!(AslCompilerdebug)))
    408     {
    409         return;
    410     }
    411 
    412     (void) vfprintf (stderr, Fmt, Args);
    413     va_end (Args);
    414     return;
    415 }
    416 
    417 
    418 /*******************************************************************************
    419  *
    420  * FUNCTION:    UtPrintFormattedName
    421  *
    422  * PARAMETERS:  ParseOpcode         - Parser keyword ID
    423  *              Level               - Indentation level
    424  *
    425  * RETURN:      None
    426  *
    427  * DESCRIPTION: Print the ascii name of the parse opcode.
    428  *
    429  ******************************************************************************/
    430 
    431 #define TEXT_OFFSET 10
    432 
    433 void
    434 UtPrintFormattedName (
    435     UINT16                  ParseOpcode,
    436     UINT32                  Level)
    437 {
    438 
    439     if (Level)
    440     {
    441         DbgPrint (ASL_TREE_OUTPUT,
    442             "%*s", (3 * Level), " ");
    443     }
    444     DbgPrint (ASL_TREE_OUTPUT,
    445         " %-20.20s", UtGetOpName (ParseOpcode));
    446 
    447     if (Level < TEXT_OFFSET)
    448     {
    449         DbgPrint (ASL_TREE_OUTPUT,
    450             "%*s", (TEXT_OFFSET - Level) * 3, " ");
    451     }
    452 }
    453 
    454 
    455 /*******************************************************************************
    456  *
    457  * FUNCTION:    UtSetParseOpName
    458  *
    459  * PARAMETERS:  Op
    460  *
    461  * RETURN:      None
    462  *
    463  * DESCRIPTION: Insert the ascii name of the parse opcode
    464  *
    465  ******************************************************************************/
    466 
    467 void
    468 UtSetParseOpName (
    469     ACPI_PARSE_OBJECT       *Op)
    470 {
    471 
    472     strncpy (Op->Asl.ParseOpName, UtGetOpName (Op->Asl.ParseOpcode),
    473         ACPI_MAX_PARSEOP_NAME);
    474 }
    475 
    476 
    477 /*******************************************************************************
    478  *
    479  * FUNCTION:    UtGetOpName
    480  *
    481  * PARAMETERS:  ParseOpcode         - Parser keyword ID
    482  *
    483  * RETURN:      Pointer to the opcode name
    484  *
    485  * DESCRIPTION: Get the ascii name of the parse opcode
    486  *
    487  ******************************************************************************/
    488 
    489 char *
    490 UtGetOpName (
    491     UINT32                  ParseOpcode)
    492 {
    493 
    494     /*
    495      * First entries (ASL_YYTNAME_START) in yytname are special reserved names.
    496      * Ignore first 8 characters of the name
    497      */
    498     return ((char *) yytname
    499         [(ParseOpcode - ASL_FIRST_PARSE_OPCODE) + ASL_YYTNAME_START] + 8);
    500 }
    501 
    502 
    503 /*******************************************************************************
    504  *
    505  * FUNCTION:    UtDisplaySummary
    506  *
    507  * PARAMETERS:  FileID          - ID of outpout file
    508  *
    509  * RETURN:      None
    510  *
    511  * DESCRIPTION: Display compilation statistics
    512  *
    513  ******************************************************************************/
    514 
    515 void
    516 UtDisplaySummary (
    517     UINT32                  FileId)
    518 {
    519 
    520     if (FileId != ASL_FILE_STDOUT)
    521     {
    522         /* Compiler name and version number */
    523 
    524         FlPrintFile (FileId, "%s version %X [%s]\n",
    525             CompilerId, (UINT32) ACPI_CA_VERSION, __DATE__);
    526     }
    527 
    528     if (Gbl_FileType == ASL_INPUT_TYPE_ASCII_DATA)
    529     {
    530         FlPrintFile (FileId,
    531             "Table Input:   %s - %u lines, %u bytes, %u fields\n",
    532             Gbl_Files[ASL_FILE_INPUT].Filename, Gbl_CurrentLineNumber,
    533             Gbl_InputByteCount, Gbl_InputFieldCount);
    534 
    535         if ((Gbl_ExceptionCount[ASL_ERROR] == 0) || (Gbl_IgnoreErrors))
    536         {
    537             FlPrintFile (FileId,
    538                 "Binary Output: %s - %u bytes\n\n",
    539                 Gbl_Files[ASL_FILE_AML_OUTPUT].Filename, Gbl_TableLength);
    540         }
    541     }
    542     else
    543     {
    544         /* Input/Output summary */
    545 
    546         FlPrintFile (FileId,
    547             "ASL Input:  %s - %u lines, %u bytes, %u keywords\n",
    548             Gbl_Files[ASL_FILE_INPUT].Filename, Gbl_CurrentLineNumber,
    549             Gbl_InputByteCount, TotalKeywords);
    550 
    551         /* AML summary */
    552 
    553         if ((Gbl_ExceptionCount[ASL_ERROR] == 0) || (Gbl_IgnoreErrors))
    554         {
    555             FlPrintFile (FileId,
    556                 "AML Output: %s - %u bytes, %u named objects, %u executable opcodes\n\n",
    557                 Gbl_Files[ASL_FILE_AML_OUTPUT].Filename, Gbl_TableLength,
    558                 TotalNamedObjects, TotalExecutableOpcodes);
    559         }
    560     }
    561 
    562     /* Error summary */
    563 
    564     FlPrintFile (FileId,
    565         "Compilation complete. %u Errors, %u Warnings, %u Remarks",
    566         Gbl_ExceptionCount[ASL_ERROR],
    567         Gbl_ExceptionCount[ASL_WARNING] +
    568             Gbl_ExceptionCount[ASL_WARNING2] +
    569             Gbl_ExceptionCount[ASL_WARNING3],
    570         Gbl_ExceptionCount[ASL_REMARK]);
    571 
    572     if (Gbl_FileType != ASL_INPUT_TYPE_ASCII_DATA)
    573     {
    574         FlPrintFile (FileId,
    575             ", %u Optimizations", Gbl_ExceptionCount[ASL_OPTIMIZATION]);
    576     }
    577 
    578     FlPrintFile (FileId, "\n");
    579 }
    580 
    581 
    582 /*******************************************************************************
    583  *
    584  * FUNCTION:    UtDisplaySummary
    585  *
    586  * PARAMETERS:  Op              - Integer parse node
    587  *              LowValue        - Smallest allowed value
    588  *              HighValue       - Largest allowed value
    589  *
    590  * RETURN:      Op if OK, otherwise NULL
    591  *
    592  * DESCRIPTION: Check integer for an allowable range
    593  *
    594  ******************************************************************************/
    595 
    596 ACPI_PARSE_OBJECT *
    597 UtCheckIntegerRange (
    598     ACPI_PARSE_OBJECT       *Op,
    599     UINT32                  LowValue,
    600     UINT32                  HighValue)
    601 {
    602     char                    *ParseError = NULL;
    603     char                    Buffer[64];
    604 
    605 
    606     if (!Op)
    607     {
    608         return NULL;
    609     }
    610 
    611     if (Op->Asl.Value.Integer < LowValue)
    612     {
    613         ParseError = "Value below valid range";
    614         Op->Asl.Value.Integer = LowValue;
    615     }
    616 
    617     if (Op->Asl.Value.Integer > HighValue)
    618     {
    619         ParseError = "Value above valid range";
    620         Op->Asl.Value.Integer = HighValue;
    621     }
    622 
    623     if (ParseError)
    624     {
    625         sprintf (Buffer, "%s 0x%X-0x%X", ParseError, LowValue, HighValue);
    626         AslCompilererror (Buffer);
    627 
    628         return NULL;
    629     }
    630 
    631     return Op;
    632 }
    633 
    634 
    635 /*******************************************************************************
    636  *
    637  * FUNCTION:    UtGetStringBuffer
    638  *
    639  * PARAMETERS:  Length          - Size of buffer requested
    640  *
    641  * RETURN:      Pointer to the buffer.  Aborts on allocation failure
    642  *
    643  * DESCRIPTION: Allocate a string buffer.  Bypass the local
    644  *              dynamic memory manager for performance reasons (This has a
    645  *              major impact on the speed of the compiler.)
    646  *
    647  ******************************************************************************/
    648 
    649 char *
    650 UtGetStringBuffer (
    651     UINT32                  Length)
    652 {
    653     char                    *Buffer;
    654 
    655 
    656     if ((Gbl_StringCacheNext + Length) >= Gbl_StringCacheLast)
    657     {
    658         Gbl_StringCacheNext = UtLocalCalloc (ASL_STRING_CACHE_SIZE + Length);
    659         Gbl_StringCacheLast = Gbl_StringCacheNext + ASL_STRING_CACHE_SIZE +
    660                                 Length;
    661     }
    662 
    663     Buffer = Gbl_StringCacheNext;
    664     Gbl_StringCacheNext += Length;
    665 
    666     return (Buffer);
    667 }
    668 
    669 
    670 /*******************************************************************************
    671  *
    672  * FUNCTION:    UtInternalizeName
    673  *
    674  * PARAMETERS:  ExternalName            - Name to convert
    675  *              ConvertedName           - Where the converted name is returned
    676  *
    677  * RETURN:      Status
    678  *
    679  * DESCRIPTION: Convert an external (ASL) name to an internal (AML) name
    680  *
    681  ******************************************************************************/
    682 
    683 ACPI_STATUS
    684 UtInternalizeName (
    685     char                    *ExternalName,
    686     char                    **ConvertedName)
    687 {
    688     ACPI_NAMESTRING_INFO    Info;
    689     ACPI_STATUS             Status;
    690 
    691 
    692     if (!ExternalName)
    693     {
    694         return (AE_OK);
    695     }
    696 
    697     /* Get the length of the new internal name */
    698 
    699     Info.ExternalName = ExternalName;
    700     AcpiNsGetInternalNameLength (&Info);
    701 
    702     /* We need a segment to store the internal  name */
    703 
    704     Info.InternalName = UtGetStringBuffer (Info.Length);
    705     if (!Info.InternalName)
    706     {
    707         return (AE_NO_MEMORY);
    708     }
    709 
    710     /* Build the name */
    711 
    712     Status = AcpiNsBuildInternalName (&Info);
    713     if (ACPI_FAILURE (Status))
    714     {
    715         return (Status);
    716     }
    717 
    718     *ConvertedName = Info.InternalName;
    719     return (AE_OK);
    720 }
    721 
    722 
    723 /*******************************************************************************
    724  *
    725  * FUNCTION:    UtPadNameWithUnderscores
    726  *
    727  * PARAMETERS:  NameSeg         - Input nameseg
    728  *              PaddedNameSeg   - Output padded nameseg
    729  *
    730  * RETURN:      Padded nameseg.
    731  *
    732  * DESCRIPTION: Pads a NameSeg with underscores if necessary to form a full
    733  *              ACPI_NAME.
    734  *
    735  ******************************************************************************/
    736 
    737 static void
    738 UtPadNameWithUnderscores (
    739     char                    *NameSeg,
    740     char                    *PaddedNameSeg)
    741 {
    742     UINT32                  i;
    743 
    744 
    745     for (i = 0; (i < ACPI_NAME_SIZE); i++)
    746     {
    747         if (*NameSeg)
    748         {
    749             *PaddedNameSeg = *NameSeg;
    750             NameSeg++;
    751         }
    752         else
    753         {
    754             *PaddedNameSeg = '_';
    755         }
    756         PaddedNameSeg++;
    757     }
    758 }
    759 
    760 
    761 /*******************************************************************************
    762  *
    763  * FUNCTION:    UtAttachNameseg
    764  *
    765  * PARAMETERS:  Op              - Parent parse node
    766  *              Name            - Full ExternalName
    767  *
    768  * RETURN:      None; Sets the NameSeg field in parent node
    769  *
    770  * DESCRIPTION: Extract the last nameseg of the ExternalName and store it
    771  *              in the NameSeg field of the Op.
    772  *
    773  ******************************************************************************/
    774 
    775 static void
    776 UtAttachNameseg (
    777     ACPI_PARSE_OBJECT       *Op,
    778     char                    *Name)
    779 {
    780     char                    *NameSeg;
    781     char                    PaddedNameSeg[4];
    782 
    783 
    784     if (!Name)
    785     {
    786         return;
    787     }
    788 
    789     /* Look for the last dot in the namepath */
    790 
    791     NameSeg = strrchr (Name, '.');
    792     if (NameSeg)
    793     {
    794         /* Found last dot, we have also found the final nameseg */
    795 
    796         NameSeg++;
    797         UtPadNameWithUnderscores (NameSeg, PaddedNameSeg);
    798     }
    799     else
    800     {
    801         /* No dots in the namepath, there is only a single nameseg. */
    802         /* Handle prefixes */
    803 
    804         while ((*Name == '\\') || (*Name == '^'))
    805         {
    806             Name++;
    807         }
    808 
    809         /* Remaing string should be one single nameseg */
    810 
    811         UtPadNameWithUnderscores (Name, PaddedNameSeg);
    812     }
    813 
    814     strncpy (Op->Asl.NameSeg, PaddedNameSeg, 4);
    815 }
    816 
    817 
    818 /*******************************************************************************
    819  *
    820  * FUNCTION:    UtAttachNamepathToOwner
    821  *
    822  * PARAMETERS:  Op            - Parent parse node
    823  *              NameOp        - Node that contains the name
    824  *
    825  * RETURN:      Sets the ExternalName and Namepath in the parent node
    826  *
    827  * DESCRIPTION: Store the name in two forms in the parent node:  The original
    828  *              (external) name, and the internalized name that is used within
    829  *              the ACPI namespace manager.
    830  *
    831  ******************************************************************************/
    832 
    833 void
    834 UtAttachNamepathToOwner (
    835     ACPI_PARSE_OBJECT       *Op,
    836     ACPI_PARSE_OBJECT       *NameOp)
    837 {
    838     ACPI_STATUS             Status;
    839 
    840 
    841     /* Full external path */
    842 
    843     Op->Asl.ExternalName = NameOp->Asl.Value.String;
    844 
    845     /* Save the NameOp for possible error reporting later */
    846 
    847     Op->Asl.ParentMethod = (void *) NameOp;
    848 
    849     /* Last nameseg of the path */
    850 
    851     UtAttachNameseg (Op, Op->Asl.ExternalName);
    852 
    853     /* Create internalized path */
    854 
    855     Status = UtInternalizeName (NameOp->Asl.Value.String, &Op->Asl.Namepath);
    856     if (ACPI_FAILURE (Status))
    857     {
    858         /* TBD: abort on no memory */
    859     }
    860 }
    861 
    862 
    863 /*******************************************************************************
    864  *
    865  * FUNCTION:    UtDoConstant
    866  *
    867  * PARAMETERS:  String      - Hex, Octal, or Decimal string
    868  *
    869  * RETURN:      Converted Integer
    870  *
    871  * DESCRIPTION: Convert a string to an integer.  With error checking.
    872  *
    873  ******************************************************************************/
    874 
    875 UINT64
    876 UtDoConstant (
    877     char                    *String)
    878 {
    879     ACPI_STATUS             Status;
    880     UINT64                  Converted;
    881     char                    ErrBuf[64];
    882 
    883 
    884     Status = UtStrtoul64 (String, 0, &Converted);
    885     if (ACPI_FAILURE (Status))
    886     {
    887         sprintf (ErrBuf, "%s %s\n", "Conversion error:",
    888             AcpiFormatException (Status));
    889         AslCompilererror (ErrBuf);
    890     }
    891 
    892     return (Converted);
    893 }
    894 
    895 
    896 /* TBD: use version in ACPI CA main code base? */
    897 
    898 /*******************************************************************************
    899  *
    900  * FUNCTION:    UtStrtoul64
    901  *
    902  * PARAMETERS:  String          - Null terminated string
    903  *              Terminater      - Where a pointer to the terminating byte is
    904  *                                returned
    905  *              Base            - Radix of the string
    906  *
    907  * RETURN:      Converted value
    908  *
    909  * DESCRIPTION: Convert a string into an unsigned value.
    910  *
    911  ******************************************************************************/
    912 
    913 static ACPI_STATUS
    914 UtStrtoul64 (
    915     char                    *String,
    916     UINT32                  Base,
    917     UINT64                  *RetInteger)
    918 {
    919     UINT32                  Index;
    920     UINT32                  Sign;
    921     UINT64                  ReturnValue = 0;
    922     ACPI_STATUS             Status = AE_OK;
    923 
    924 
    925     *RetInteger = 0;
    926 
    927     switch (Base)
    928     {
    929     case 0:
    930     case 8:
    931     case 10:
    932     case 16:
    933         break;
    934 
    935     default:
    936         /*
    937          * The specified Base parameter is not in the domain of
    938          * this function:
    939          */
    940         return (AE_BAD_PARAMETER);
    941     }
    942 
    943     /* Skip over any white space in the buffer: */
    944 
    945     while (isspace ((int) *String) || *String == '\t')
    946     {
    947         ++String;
    948     }
    949 
    950     /*
    951      * The buffer may contain an optional plus or minus sign.
    952      * If it does, then skip over it but remember what is was:
    953      */
    954     if (*String == '-')
    955     {
    956         Sign = NEGATIVE;
    957         ++String;
    958     }
    959     else if (*String == '+')
    960     {
    961         ++String;
    962         Sign = POSITIVE;
    963     }
    964     else
    965     {
    966         Sign = POSITIVE;
    967     }
    968 
    969     /*
    970      * If the input parameter Base is zero, then we need to
    971      * determine if it is octal, decimal, or hexadecimal:
    972      */
    973     if (Base == 0)
    974     {
    975         if (*String == '0')
    976         {
    977             if (tolower ((int) *(++String)) == 'x')
    978             {
    979                 Base = 16;
    980                 ++String;
    981             }
    982             else
    983             {
    984                 Base = 8;
    985             }
    986         }
    987         else
    988         {
    989             Base = 10;
    990         }
    991     }
    992 
    993     /*
    994      * For octal and hexadecimal bases, skip over the leading
    995      * 0 or 0x, if they are present.
    996      */
    997     if (Base == 8 && *String == '0')
    998     {
    999         String++;
   1000     }
   1001 
   1002     if (Base == 16 &&
   1003         *String == '0' &&
   1004         tolower ((int) *(++String)) == 'x')
   1005     {
   1006         String++;
   1007     }
   1008 
   1009     /* Main loop: convert the string to an unsigned long */
   1010 
   1011     while (*String)
   1012     {
   1013         if (isdigit ((int) *String))
   1014         {
   1015             Index = ((UINT8) *String) - '0';
   1016         }
   1017         else
   1018         {
   1019             Index = (UINT8) toupper ((int) *String);
   1020             if (isupper ((int) Index))
   1021             {
   1022                 Index = Index - 'A' + 10;
   1023             }
   1024             else
   1025             {
   1026                 goto ErrorExit;
   1027             }
   1028         }
   1029 
   1030         if (Index >= Base)
   1031         {
   1032             goto ErrorExit;
   1033         }
   1034 
   1035         /* Check to see if value is out of range: */
   1036 
   1037         if (ReturnValue > ((ACPI_UINT64_MAX - (UINT64) Index) /
   1038                             (UINT64) Base))
   1039         {
   1040             goto ErrorExit;
   1041         }
   1042         else
   1043         {
   1044             ReturnValue *= Base;
   1045             ReturnValue += Index;
   1046         }
   1047 
   1048         ++String;
   1049     }
   1050 
   1051 
   1052     /* If a minus sign was present, then "the conversion is negated": */
   1053 
   1054     if (Sign == NEGATIVE)
   1055     {
   1056         ReturnValue = (ACPI_UINT32_MAX - ReturnValue) + 1;
   1057     }
   1058 
   1059     *RetInteger = ReturnValue;
   1060     return (Status);
   1061 
   1062 
   1063 ErrorExit:
   1064     switch (Base)
   1065     {
   1066     case 8:
   1067         Status = AE_BAD_OCTAL_CONSTANT;
   1068         break;
   1069 
   1070     case 10:
   1071         Status = AE_BAD_DECIMAL_CONSTANT;
   1072         break;
   1073 
   1074     case 16:
   1075         Status = AE_BAD_HEX_CONSTANT;
   1076         break;
   1077 
   1078     default:
   1079         /* Base validated above */
   1080         break;
   1081     }
   1082 
   1083     return (Status);
   1084 }
   1085 
   1086 
   1087