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