Home | History | Annotate | Line # | Download | only in compiler
aslutils.c revision 1.1.1.17
      1 /******************************************************************************
      2  *
      3  * Module Name: aslutils -- compiler utilities
      4  *
      5  *****************************************************************************/
      6 
      7 /*
      8  * Copyright (C) 2000 - 2019, 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 #include <sys/stat.h>
     51 
     52 
     53 #define _COMPONENT          ACPI_COMPILER
     54         ACPI_MODULE_NAME    ("aslutils")
     55 
     56 
     57 /* Local prototypes */
     58 
     59 static void
     60 UtPadNameWithUnderscores (
     61     char                    *NameSeg,
     62     char                    *PaddedNameSeg);
     63 
     64 static void
     65 UtAttachNameseg (
     66     ACPI_PARSE_OBJECT       *Op,
     67     char                    *Name);
     68 
     69 static void
     70 UtDisplayErrorSummary (
     71     UINT32                  FileId);
     72 
     73 
     74 /*******************************************************************************
     75  *
     76  * FUNCTION:    UtIsBigEndianMachine
     77  *
     78  * PARAMETERS:  None
     79  *
     80  * RETURN:      TRUE if machine is big endian
     81  *              FALSE if machine is little endian
     82  *
     83  * DESCRIPTION: Detect whether machine is little endian or big endian.
     84  *
     85  ******************************************************************************/
     86 
     87 UINT8
     88 UtIsBigEndianMachine (
     89     void)
     90 {
     91     union {
     92         UINT32              Integer;
     93         UINT8               Bytes[4];
     94     } Overlay =                 {0xFF000000};
     95 
     96 
     97     return (Overlay.Bytes[0]); /* Returns 0xFF (TRUE) for big endian */
     98 }
     99 
    100 
    101 /******************************************************************************
    102  *
    103  * FUNCTION:    UtQueryForOverwrite
    104  *
    105  * PARAMETERS:  Pathname            - Output filename
    106  *
    107  * RETURN:      TRUE if file does not exist or overwrite is authorized
    108  *
    109  * DESCRIPTION: Query for file overwrite if it already exists.
    110  *
    111  ******************************************************************************/
    112 
    113 BOOLEAN
    114 UtQueryForOverwrite (
    115     char                    *Pathname)
    116 {
    117     struct stat             StatInfo;
    118 
    119 
    120     if (!stat (Pathname, &StatInfo))
    121     {
    122         fprintf (stderr, "Target file \"%s\" already exists, overwrite? [y|n] ",
    123             Pathname);
    124 
    125         if (getchar () != 'y')
    126         {
    127             return (FALSE);
    128         }
    129     }
    130 
    131     return (TRUE);
    132 }
    133 
    134 
    135 /*******************************************************************************
    136  *
    137  * FUNCTION:    UtNodeIsDescendantOf
    138  *
    139  * PARAMETERS:  Node1                   - Child node
    140  *              Node2                   - Possible parent node
    141  *
    142  * RETURN:      Boolean
    143  *
    144  * DESCRIPTION: Returns TRUE if Node1 is a descendant of Node2. Otherwise,
    145  *              return FALSE. Note, we assume a NULL Node2 element to be the
    146  *              topmost (root) scope. All nodes are descendants of the root.
    147  *              Note: Nodes at the same level (siblings) are not considered
    148  *              descendants.
    149  *
    150  ******************************************************************************/
    151 
    152 BOOLEAN
    153 UtNodeIsDescendantOf (
    154     ACPI_NAMESPACE_NODE     *Node1,
    155     ACPI_NAMESPACE_NODE     *Node2)
    156 {
    157 
    158     if (Node1 == Node2)
    159     {
    160         return (FALSE);
    161     }
    162 
    163     if (!Node2)
    164     {
    165         return (TRUE); /* All nodes descend from the root */
    166     }
    167 
    168     /* Walk upward until the root is reached or parent is found */
    169 
    170     while (Node1)
    171     {
    172         if (Node1 == Node2)
    173         {
    174             return (TRUE);
    175         }
    176 
    177         Node1 = Node1->Parent;
    178     }
    179 
    180     return (FALSE);
    181 }
    182 
    183 
    184 /*******************************************************************************
    185  *
    186  * FUNCTION:    UtGetParentMethod
    187  *
    188  * PARAMETERS:  Node                    - Namespace node for any object
    189  *
    190  * RETURN:      Namespace node for the parent method
    191  *              NULL - object is not within a method
    192  *
    193  * DESCRIPTION: Find the parent (owning) method node for a namespace object
    194  *
    195  ******************************************************************************/
    196 
    197 void *
    198 UtGetParentMethod (
    199     ACPI_NAMESPACE_NODE     *Node)
    200 {
    201     ACPI_NAMESPACE_NODE     *ParentNode;
    202 
    203 
    204     if (!Node)
    205     {
    206         return (NULL);
    207     }
    208 
    209     /* Walk upward until a method is found, or the root is reached */
    210 
    211     ParentNode = Node->Parent;
    212     while (ParentNode)
    213     {
    214         if (ParentNode->Type == ACPI_TYPE_METHOD)
    215         {
    216             return (ParentNode);
    217         }
    218 
    219         ParentNode = ParentNode->Parent;
    220     }
    221 
    222     return (NULL); /* Object is not within a control method */
    223 }
    224 
    225 
    226 /*******************************************************************************
    227  *
    228  * FUNCTION:    UtDisplaySupportedTables
    229  *
    230  * PARAMETERS:  None
    231  *
    232  * RETURN:      None
    233  *
    234  * DESCRIPTION: Print all supported ACPI table names.
    235  *
    236  ******************************************************************************/
    237 
    238 void
    239 UtDisplaySupportedTables (
    240     void)
    241 {
    242     const AH_TABLE          *TableData;
    243     UINT32                  i;
    244 
    245 
    246     printf ("\nACPI tables supported by iASL version %8.8X:\n"
    247         "  (Compiler, Disassembler, Template Generator)\n\n",
    248         ACPI_CA_VERSION);
    249 
    250     /* All ACPI tables with the common table header */
    251 
    252     printf ("\n  Supported ACPI tables:\n");
    253     for (TableData = AcpiGbl_SupportedTables, i = 1;
    254          TableData->Signature; TableData++, i++)
    255     {
    256         printf ("%8u) %s    %s\n", i,
    257             TableData->Signature, TableData->Description);
    258     }
    259 }
    260 
    261 
    262 /*******************************************************************************
    263  *
    264  * FUNCTION:    UtDisplayConstantOpcodes
    265  *
    266  * PARAMETERS:  None
    267  *
    268  * RETURN:      None
    269  *
    270  * DESCRIPTION: Print AML opcodes that can be used in constant expressions.
    271  *
    272  ******************************************************************************/
    273 
    274 void
    275 UtDisplayConstantOpcodes (
    276     void)
    277 {
    278     UINT32                  i;
    279 
    280 
    281     printf ("Constant expression opcode information\n\n");
    282 
    283     for (i = 0; i < sizeof (AcpiGbl_AmlOpInfo) / sizeof (ACPI_OPCODE_INFO); i++)
    284     {
    285         if (AcpiGbl_AmlOpInfo[i].Flags & AML_CONSTANT)
    286         {
    287             printf ("%s\n", AcpiGbl_AmlOpInfo[i].Name);
    288         }
    289     }
    290 }
    291 
    292 
    293 /*******************************************************************************
    294  *
    295  * FUNCTION:    UtBeginEvent
    296  *
    297  * PARAMETERS:  Name                - Ascii name of this event
    298  *
    299  * RETURN:      Event number (integer index)
    300  *
    301  * DESCRIPTION: Saves the current time with this event
    302  *
    303  ******************************************************************************/
    304 
    305 UINT8
    306 UtBeginEvent (
    307     char                    *Name)
    308 {
    309 
    310     if (AslGbl_NextEvent >= ASL_NUM_EVENTS)
    311     {
    312         AcpiOsPrintf ("Ran out of compiler event structs!\n");
    313         return (AslGbl_NextEvent);
    314     }
    315 
    316     /* Init event with current (start) time */
    317 
    318     AslGbl_Events[AslGbl_NextEvent].StartTime = AcpiOsGetTimer ();
    319     AslGbl_Events[AslGbl_NextEvent].EventName = Name;
    320     AslGbl_Events[AslGbl_NextEvent].Valid = TRUE;
    321     return (AslGbl_NextEvent++);
    322 }
    323 
    324 
    325 /*******************************************************************************
    326  *
    327  * FUNCTION:    UtEndEvent
    328  *
    329  * PARAMETERS:  Event               - Event number (integer index)
    330  *
    331  * RETURN:      None
    332  *
    333  * DESCRIPTION: Saves the current time (end time) with this event
    334  *
    335  ******************************************************************************/
    336 
    337 void
    338 UtEndEvent (
    339     UINT8                   Event)
    340 {
    341 
    342     if (Event >= ASL_NUM_EVENTS)
    343     {
    344         return;
    345     }
    346 
    347     /* Insert end time for event */
    348 
    349     AslGbl_Events[Event].EndTime = AcpiOsGetTimer ();
    350 }
    351 
    352 
    353 /*******************************************************************************
    354  *
    355  * FUNCTION:    DbgPrint
    356  *
    357  * PARAMETERS:  Type                - Type of output
    358  *              Fmt                 - Printf format string
    359  *              ...                 - variable printf list
    360  *
    361  * RETURN:      None
    362  *
    363  * DESCRIPTION: Conditional print statement. Prints to stderr only if the
    364  *              debug flag is set.
    365  *
    366  ******************************************************************************/
    367 
    368 void
    369 DbgPrint (
    370     UINT32                  Type,
    371     char                    *Fmt,
    372     ...)
    373 {
    374     va_list                 Args;
    375 
    376 
    377     if (!AslGbl_DebugFlag)
    378     {
    379         return;
    380     }
    381 
    382     if ((Type == ASL_PARSE_OUTPUT) &&
    383         (!(AslCompilerdebug)))
    384     {
    385         return;
    386     }
    387 
    388     va_start (Args, Fmt);
    389     (void) vfprintf (stderr, Fmt, Args);
    390     va_end (Args);
    391     return;
    392 }
    393 
    394 
    395 /*******************************************************************************
    396  *
    397  * FUNCTION:    UtSetParseOpName
    398  *
    399  * PARAMETERS:  Op                  - Parse op to be named.
    400  *
    401  * RETURN:      None
    402  *
    403  * DESCRIPTION: Insert the ascii name of the parse opcode
    404  *
    405  ******************************************************************************/
    406 
    407 void
    408 UtSetParseOpName (
    409     ACPI_PARSE_OBJECT       *Op)
    410 {
    411 
    412     AcpiUtSafeStrncpy (Op->Asl.ParseOpName, UtGetOpName (Op->Asl.ParseOpcode),
    413         ACPI_MAX_PARSEOP_NAME);
    414 }
    415 
    416 
    417 /*******************************************************************************
    418  *
    419  * FUNCTION:    UtDisplayOneSummary
    420  *
    421  * PARAMETERS:  FileID              - ID of outpout file
    422  *
    423  * RETURN:      None
    424  *
    425  * DESCRIPTION: Display compilation statistics for one input file
    426  *
    427  ******************************************************************************/
    428 
    429 void
    430 UtDisplayOneSummary (
    431     UINT32                  FileId,
    432     BOOLEAN                 DisplayErrorSummary)
    433 {
    434     UINT32                  i;
    435     ASL_GLOBAL_FILE_NODE    *FileNode;
    436 
    437 
    438     if (FileId != ASL_FILE_STDOUT)
    439     {
    440         /* Compiler name and version number */
    441 
    442         FlPrintFile (FileId, "%s version %X [%s]\n\n",
    443             ASL_COMPILER_NAME, (UINT32) ACPI_CA_VERSION, __DATE__);
    444     }
    445 
    446     /* Summary of main input and output files */
    447 
    448     if (AslGbl_FileType == ASL_INPUT_TYPE_ASCII_DATA)
    449     {
    450         FlPrintFile (FileId,
    451             "%-14s %s - %u lines, %u bytes, %u fields\n",
    452             "Table Input:",
    453             AslGbl_Files[ASL_FILE_INPUT].Filename, AslGbl_CurrentLineNumber,
    454             AslGbl_InputByteCount, AslGbl_InputFieldCount);
    455 
    456         if ((AslGbl_ExceptionCount[ASL_ERROR] == 0) || (AslGbl_IgnoreErrors))
    457         {
    458             FlPrintFile (FileId,
    459                 "%-14s %s - %u bytes\n",
    460                 "Binary Output:",
    461                 AslGbl_Files[ASL_FILE_AML_OUTPUT].Filename, AslGbl_TableLength);
    462         }
    463     }
    464     else
    465     {
    466         FileNode = FlGetCurrentFileNode ();
    467         if (!FileNode)
    468         {
    469             fprintf (stderr, "Summary could not be generated");
    470             return;
    471         }
    472         if (FileNode->ParserErrorDetected)
    473         {
    474             FlPrintFile (FileId,
    475                 "%-14s %s - Compilation aborted due to parser-detected syntax error(s)\n",
    476                 "ASL Input:", AslGbl_Files[ASL_FILE_INPUT].Filename);
    477         }
    478         else
    479         {
    480             FlPrintFile (FileId,
    481                 "%-14s %s - %7u bytes %6u keywords %6u source lines\n",
    482                 "ASL Input:",
    483                 AslGbl_Files[ASL_FILE_INPUT].Filename,
    484                 FileNode->OriginalInputFileSize,
    485                 FileNode->TotalKeywords,
    486                 FileNode->TotalLineCount);
    487 
    488             /* AML summary */
    489 
    490             if (!AslGbl_ParserErrorDetected &&
    491                 ((AslGbl_ExceptionCount[ASL_ERROR] == 0) || AslGbl_IgnoreErrors) &&
    492                 AslGbl_Files[ASL_FILE_AML_OUTPUT].Handle)
    493             {
    494                 FlPrintFile (FileId,
    495                     "%-14s %s - %7u bytes %6u opcodes  %6u named objects\n",
    496                     "AML Output:",
    497                     AslGbl_Files[ASL_FILE_AML_OUTPUT].Filename,
    498                     FlGetFileSize (ASL_FILE_AML_OUTPUT),
    499                     FileNode->TotalExecutableOpcodes,
    500                     FileNode->TotalNamedObjects);
    501             }
    502         }
    503     }
    504 
    505     /* Display summary of any optional files */
    506 
    507     for (i = ASL_FILE_SOURCE_OUTPUT; i <= ASL_MAX_FILE_TYPE; i++)
    508     {
    509         if (!AslGbl_Files[i].Filename || !AslGbl_Files[i].Handle)
    510         {
    511             continue;
    512         }
    513 
    514         /* .SRC is a temp file unless specifically requested */
    515 
    516         if ((i == ASL_FILE_SOURCE_OUTPUT) && (!AslGbl_SourceOutputFlag))
    517         {
    518             continue;
    519         }
    520 
    521         /* .PRE is the preprocessor intermediate file */
    522 
    523         if ((i == ASL_FILE_PREPROCESSOR)  && (!AslGbl_KeepPreprocessorTempFile))
    524         {
    525             continue;
    526         }
    527 
    528         FlPrintFile (FileId, "%14s %s - %u bytes\n",
    529             AslGbl_FileDescs[i].ShortDescription,
    530             AslGbl_Files[i].Filename, FlGetFileSize (i));
    531     }
    532 
    533 
    534     /*
    535      * Optionally emit an error summary for a file. This is used to enhance the
    536      * appearance of listing files.
    537      */
    538     if (DisplayErrorSummary)
    539     {
    540         UtDisplayErrorSummary (FileId);
    541     }
    542 }
    543 
    544 
    545 /*******************************************************************************
    546  *
    547  * FUNCTION:    UtDisplayErrorSummary
    548  *
    549  * PARAMETERS:  FileID              - ID of outpout file
    550  *
    551  * RETURN:      None
    552  *
    553  * DESCRIPTION: Display compilation statistics for all input files
    554  *
    555  ******************************************************************************/
    556 
    557 static void
    558 UtDisplayErrorSummary (
    559     UINT32                  FileId)
    560 {
    561     BOOLEAN                 ErrorDetected;
    562 
    563 
    564     ErrorDetected = AslGbl_ParserErrorDetected ||
    565         ((AslGbl_ExceptionCount[ASL_ERROR] > 0) && !AslGbl_IgnoreErrors);
    566 
    567     if (ErrorDetected)
    568     {
    569         FlPrintFile (FileId, "\nCompilation failed. ");
    570     }
    571     else
    572     {
    573         FlPrintFile (FileId, "\nCompilation successful. ");
    574     }
    575 
    576     FlPrintFile (FileId,
    577         "%u Errors, %u Warnings, %u Remarks",
    578         AslGbl_ExceptionCount[ASL_ERROR],
    579         AslGbl_ExceptionCount[ASL_WARNING] +
    580             AslGbl_ExceptionCount[ASL_WARNING2] +
    581             AslGbl_ExceptionCount[ASL_WARNING3],
    582         AslGbl_ExceptionCount[ASL_REMARK]);
    583 
    584     if (AslGbl_FileType != ASL_INPUT_TYPE_ASCII_DATA)
    585     {
    586         if (AslGbl_ParserErrorDetected)
    587         {
    588             FlPrintFile (FileId,
    589                 "\nNo AML files were generated due to syntax error(s)\n");
    590             return;
    591         }
    592         else if (ErrorDetected)
    593         {
    594             FlPrintFile (FileId,
    595                 "\nNo AML files were generated due to compiler error(s)\n");
    596             return;
    597         }
    598 
    599         FlPrintFile (FileId, ", %u Optimizations",
    600             AslGbl_ExceptionCount[ASL_OPTIMIZATION]);
    601 
    602         if (AslGbl_TotalFolds)
    603         {
    604             FlPrintFile (FileId, ", %u Constants Folded", AslGbl_TotalFolds);
    605         }
    606     }
    607 
    608     FlPrintFile (FileId, "\n");
    609 }
    610 
    611 
    612 /*******************************************************************************
    613  *
    614  * FUNCTION:    UtDisplaySummary
    615  *
    616  * PARAMETERS:  FileID              - ID of outpout file
    617  *
    618  * RETURN:      None
    619  *
    620  * DESCRIPTION: Display compilation statistics for all input files
    621  *
    622  ******************************************************************************/
    623 
    624 void
    625 UtDisplaySummary (
    626     UINT32                  FileId)
    627 {
    628     ASL_GLOBAL_FILE_NODE    *Current = AslGbl_FilesList;
    629 
    630 
    631     while (Current)
    632     {
    633         switch  (FlSwitchFileSet(Current->Files[ASL_FILE_INPUT].Filename))
    634         {
    635             case SWITCH_TO_SAME_FILE:
    636             case SWITCH_TO_DIFFERENT_FILE:
    637 
    638                 UtDisplayOneSummary (FileId, FALSE);
    639                 Current = Current->Next;
    640                 break;
    641 
    642             case FILE_NOT_FOUND:
    643             default:
    644 
    645                 Current = NULL;
    646                 break;
    647         }
    648     }
    649     UtDisplayErrorSummary (FileId);
    650 }
    651 
    652 /*******************************************************************************
    653  *
    654  * FUNCTION:    UtCheckIntegerRange
    655  *
    656  * PARAMETERS:  Op                  - Integer parse node
    657  *              LowValue            - Smallest allowed value
    658  *              HighValue           - Largest allowed value
    659  *
    660  * RETURN:      Op if OK, otherwise NULL
    661  *
    662  * DESCRIPTION: Check integer for an allowable range
    663  *
    664  ******************************************************************************/
    665 
    666 ACPI_PARSE_OBJECT *
    667 UtCheckIntegerRange (
    668     ACPI_PARSE_OBJECT       *Op,
    669     UINT32                  LowValue,
    670     UINT32                  HighValue)
    671 {
    672 
    673     if (!Op)
    674     {
    675         return (NULL);
    676     }
    677 
    678     if ((Op->Asl.Value.Integer < LowValue) ||
    679         (Op->Asl.Value.Integer > HighValue))
    680     {
    681         sprintf (AslGbl_MsgBuffer, "0x%X, allowable: 0x%X-0x%X",
    682             (UINT32) Op->Asl.Value.Integer, LowValue, HighValue);
    683 
    684         AslError (ASL_ERROR, ASL_MSG_RANGE, Op, AslGbl_MsgBuffer);
    685         return (NULL);
    686     }
    687 
    688     return (Op);
    689 }
    690 
    691 
    692 /*******************************************************************************
    693  *
    694  * FUNCTION:    UtInternalizeName
    695  *
    696  * PARAMETERS:  ExternalName        - Name to convert
    697  *              ConvertedName       - Where the converted name is returned
    698  *
    699  * RETURN:      Status
    700  *
    701  * DESCRIPTION: Convert an external (ASL) name to an internal (AML) name
    702  *
    703  ******************************************************************************/
    704 
    705 ACPI_STATUS
    706 UtInternalizeName (
    707     char                    *ExternalName,
    708     char                    **ConvertedName)
    709 {
    710     ACPI_NAMESTRING_INFO    Info;
    711     ACPI_STATUS             Status;
    712 
    713 
    714     if (!ExternalName)
    715     {
    716         return (AE_OK);
    717     }
    718 
    719     /* Get the length of the new internal name */
    720 
    721     Info.ExternalName = ExternalName;
    722     AcpiNsGetInternalNameLength (&Info);
    723 
    724     /* We need a segment to store the internal name */
    725 
    726     Info.InternalName = UtLocalCacheCalloc (Info.Length);
    727 
    728     /* Build the name */
    729 
    730     Status = AcpiNsBuildInternalName (&Info);
    731     if (ACPI_FAILURE (Status))
    732     {
    733         return (Status);
    734     }
    735 
    736     *ConvertedName = Info.InternalName;
    737     return (AE_OK);
    738 }
    739 
    740 
    741 /*******************************************************************************
    742  *
    743  * FUNCTION:    UtPadNameWithUnderscores
    744  *
    745  * PARAMETERS:  NameSeg             - Input nameseg
    746  *              PaddedNameSeg       - Output padded nameseg
    747  *
    748  * RETURN:      Padded nameseg.
    749  *
    750  * DESCRIPTION: Pads a NameSeg with underscores if necessary to form a full
    751  *              ACPI_NAME.
    752  *
    753  ******************************************************************************/
    754 
    755 static void
    756 UtPadNameWithUnderscores (
    757     char                    *NameSeg,
    758     char                    *PaddedNameSeg)
    759 {
    760     UINT32                  i;
    761 
    762 
    763     for (i = 0; (i < ACPI_NAMESEG_SIZE); i++)
    764     {
    765         if (*NameSeg)
    766         {
    767             *PaddedNameSeg = *NameSeg;
    768             NameSeg++;
    769         }
    770         else
    771         {
    772             *PaddedNameSeg = '_';
    773         }
    774 
    775         PaddedNameSeg++;
    776     }
    777 }
    778 
    779 
    780 /*******************************************************************************
    781  *
    782  * FUNCTION:    UtAttachNameseg
    783  *
    784  * PARAMETERS:  Op                  - Parent parse node
    785  *              Name                - Full ExternalName
    786  *
    787  * RETURN:      None; Sets the NameSeg field in parent node
    788  *
    789  * DESCRIPTION: Extract the last nameseg of the ExternalName and store it
    790  *              in the NameSeg field of the Op.
    791  *
    792  ******************************************************************************/
    793 
    794 static void
    795 UtAttachNameseg (
    796     ACPI_PARSE_OBJECT       *Op,
    797     char                    *Name)
    798 {
    799     char                    *NameSeg;
    800     char                    PaddedNameSeg[4];
    801 
    802 
    803     if (!Name)
    804     {
    805         return;
    806     }
    807 
    808     /* Look for the last dot in the namepath */
    809 
    810     NameSeg = strrchr (Name, '.');
    811     if (NameSeg)
    812     {
    813         /* Found last dot, we have also found the final nameseg */
    814 
    815         NameSeg++;
    816         UtPadNameWithUnderscores (NameSeg, PaddedNameSeg);
    817     }
    818     else
    819     {
    820         /* No dots in the namepath, there is only a single nameseg. */
    821         /* Handle prefixes */
    822 
    823         while (ACPI_IS_ROOT_PREFIX (*Name) ||
    824                ACPI_IS_PARENT_PREFIX (*Name))
    825         {
    826             Name++;
    827         }
    828 
    829         /* Remaining string should be one single nameseg */
    830 
    831         UtPadNameWithUnderscores (Name, PaddedNameSeg);
    832     }
    833 
    834     ACPI_COPY_NAMESEG (Op->Asl.NameSeg, PaddedNameSeg);
    835 }
    836 
    837 
    838 /*******************************************************************************
    839  *
    840  * FUNCTION:    UtAttachNamepathToOwner
    841  *
    842  * PARAMETERS:  Op                  - Parent parse node
    843  *              NameOp              - Node that contains the name
    844  *
    845  * RETURN:      Sets the ExternalName and Namepath in the parent node
    846  *
    847  * DESCRIPTION: Store the name in two forms in the parent node: The original
    848  *              (external) name, and the internalized name that is used within
    849  *              the ACPI namespace manager.
    850  *
    851  ******************************************************************************/
    852 
    853 void
    854 UtAttachNamepathToOwner (
    855     ACPI_PARSE_OBJECT       *Op,
    856     ACPI_PARSE_OBJECT       *NameOp)
    857 {
    858     ACPI_STATUS             Status;
    859 
    860 
    861     /* Full external path */
    862 
    863     Op->Asl.ExternalName = NameOp->Asl.Value.String;
    864 
    865     /* Save the NameOp for possible error reporting later */
    866 
    867     Op->Asl.ParentMethod = (void *) NameOp;
    868 
    869     /* Last nameseg of the path */
    870 
    871     UtAttachNameseg (Op, Op->Asl.ExternalName);
    872 
    873     /* Create internalized path */
    874 
    875     Status = UtInternalizeName (NameOp->Asl.Value.String, &Op->Asl.Namepath);
    876     if (ACPI_FAILURE (Status))
    877     {
    878         /* TBD: abort on no memory */
    879     }
    880 }
    881 
    882 
    883 /*******************************************************************************
    884  *
    885  * FUNCTION:    UtDoConstant
    886  *
    887  * PARAMETERS:  String              - Hex/Decimal/Octal
    888  *
    889  * RETURN:      Converted Integer
    890  *
    891  * DESCRIPTION: Convert a string to an integer, with overflow/error checking.
    892  *
    893  ******************************************************************************/
    894 
    895 UINT64
    896 UtDoConstant (
    897     char                    *String)
    898 {
    899     ACPI_STATUS             Status;
    900     UINT64                  ConvertedInteger;
    901     char                    ErrBuf[64];
    902 
    903 
    904     Status = AcpiUtStrtoul64 (String, &ConvertedInteger);
    905     if (ACPI_FAILURE (Status))
    906     {
    907         sprintf (ErrBuf, "While creating 64-bit constant: %s\n",
    908             AcpiFormatException (Status));
    909 
    910         AslCommonError (ASL_ERROR, ASL_MSG_SYNTAX, AslGbl_CurrentLineNumber,
    911             AslGbl_LogicalLineNumber, AslGbl_CurrentLineOffset,
    912             AslGbl_CurrentColumn, AslGbl_Files[ASL_FILE_INPUT].Filename, ErrBuf);
    913     }
    914 
    915     return (ConvertedInteger);
    916 }
    917