Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:03

0001 /*******************************************************************************
0002  *
0003  * Module Name: nsnames - Name manipulation and search
0004  *
0005  ******************************************************************************/
0006 
0007 /******************************************************************************
0008  *
0009  * 1. Copyright Notice
0010  *
0011  * Some or all of this work - Copyright (c) 1999 - 2024, Intel Corp.
0012  * All rights reserved.
0013  *
0014  * 2. License
0015  *
0016  * 2.1. This is your license from Intel Corp. under its intellectual property
0017  * rights. You may have additional license terms from the party that provided
0018  * you this software, covering your right to use that party's intellectual
0019  * property rights.
0020  *
0021  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
0022  * copy of the source code appearing in this file ("Covered Code") an
0023  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
0024  * base code distributed originally by Intel ("Original Intel Code") to copy,
0025  * make derivatives, distribute, use and display any portion of the Covered
0026  * Code in any form, with the right to sublicense such rights; and
0027  *
0028  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
0029  * license (with the right to sublicense), under only those claims of Intel
0030  * patents that are infringed by the Original Intel Code, to make, use, sell,
0031  * offer to sell, and import the Covered Code and derivative works thereof
0032  * solely to the minimum extent necessary to exercise the above copyright
0033  * license, and in no event shall the patent license extend to any additions
0034  * to or modifications of the Original Intel Code. No other license or right
0035  * is granted directly or by implication, estoppel or otherwise;
0036  *
0037  * The above copyright and patent license is granted only if the following
0038  * conditions are met:
0039  *
0040  * 3. Conditions
0041  *
0042  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
0043  * Redistribution of source code of any substantial portion of the Covered
0044  * Code or modification with rights to further distribute source must include
0045  * the above Copyright Notice, the above License, this list of Conditions,
0046  * and the following Disclaimer and Export Compliance provision. In addition,
0047  * Licensee must cause all Covered Code to which Licensee contributes to
0048  * contain a file documenting the changes Licensee made to create that Covered
0049  * Code and the date of any change. Licensee must include in that file the
0050  * documentation of any changes made by any predecessor Licensee. Licensee
0051  * must include a prominent statement that the modification is derived,
0052  * directly or indirectly, from Original Intel Code.
0053  *
0054  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
0055  * Redistribution of source code of any substantial portion of the Covered
0056  * Code or modification without rights to further distribute source must
0057  * include the following Disclaimer and Export Compliance provision in the
0058  * documentation and/or other materials provided with distribution. In
0059  * addition, Licensee may not authorize further sublicense of source of any
0060  * portion of the Covered Code, and must include terms to the effect that the
0061  * license from Licensee to its licensee is limited to the intellectual
0062  * property embodied in the software Licensee provides to its licensee, and
0063  * not to intellectual property embodied in modifications its licensee may
0064  * make.
0065  *
0066  * 3.3. Redistribution of Executable. Redistribution in executable form of any
0067  * substantial portion of the Covered Code or modification must reproduce the
0068  * above Copyright Notice, and the following Disclaimer and Export Compliance
0069  * provision in the documentation and/or other materials provided with the
0070  * distribution.
0071  *
0072  * 3.4. Intel retains all right, title, and interest in and to the Original
0073  * Intel Code.
0074  *
0075  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
0076  * Intel shall be used in advertising or otherwise to promote the sale, use or
0077  * other dealings in products derived from or relating to the Covered Code
0078  * without prior written authorization from Intel.
0079  *
0080  * 4. Disclaimer and Export Compliance
0081  *
0082  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
0083  * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
0084  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
0085  * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
0086  * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
0087  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
0088  * PARTICULAR PURPOSE.
0089  *
0090  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
0091  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
0092  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
0093  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
0094  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
0095  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
0096  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
0097  * LIMITED REMEDY.
0098  *
0099  * 4.3. Licensee shall not export, either directly or indirectly, any of this
0100  * software or system incorporating such software without first obtaining any
0101  * required license or other approval from the U. S. Department of Commerce or
0102  * any other agency or department of the United States Government. In the
0103  * event Licensee exports any such software from the United States or
0104  * re-exports any such software from a foreign destination, Licensee shall
0105  * ensure that the distribution and export/re-export of the software is in
0106  * compliance with all laws, regulations, orders, or other restrictions of the
0107  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
0108  * any of its subsidiaries will export/re-export any technical data, process,
0109  * software, or service, directly or indirectly, to any country for which the
0110  * United States government or any agency thereof requires an export license,
0111  * other governmental approval, or letter of assurance, without first obtaining
0112  * such license, approval or letter.
0113  *
0114  *****************************************************************************
0115  *
0116  * Alternatively, you may choose to be licensed under the terms of the
0117  * following license:
0118  *
0119  * Redistribution and use in source and binary forms, with or without
0120  * modification, are permitted provided that the following conditions
0121  * are met:
0122  * 1. Redistributions of source code must retain the above copyright
0123  *    notice, this list of conditions, and the following disclaimer,
0124  *    without modification.
0125  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
0126  *    substantially similar to the "NO WARRANTY" disclaimer below
0127  *    ("Disclaimer") and any redistribution must be conditioned upon
0128  *    including a substantially similar Disclaimer requirement for further
0129  *    binary redistribution.
0130  * 3. Neither the names of the above-listed copyright holders nor the names
0131  *    of any contributors may be used to endorse or promote products derived
0132  *    from this software without specific prior written permission.
0133  *
0134  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
0135  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
0136  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
0137  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
0138  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
0139  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
0140  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
0141  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
0142  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
0143  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
0144  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0145  *
0146  * Alternatively, you may choose to be licensed under the terms of the
0147  * GNU General Public License ("GPL") version 2 as published by the Free
0148  * Software Foundation.
0149  *
0150  *****************************************************************************/
0151 
0152 #include "acpi.h"
0153 #include "accommon.h"
0154 #include "amlcode.h"
0155 #include "acnamesp.h"
0156 
0157 
0158 #define _COMPONENT          ACPI_NAMESPACE
0159         ACPI_MODULE_NAME    ("nsnames")
0160 
0161 
0162 /*******************************************************************************
0163  *
0164  * FUNCTION:    AcpiNsGetExternalPathname
0165  *
0166  * PARAMETERS:  Node            - Namespace node whose pathname is needed
0167  *
0168  * RETURN:      Pointer to storage containing the fully qualified name of
0169  *              the node, In external format (name segments separated by path
0170  *              separators.)
0171  *
0172  * DESCRIPTION: Used to obtain the full pathname to a namespace node, usually
0173  *              for error and debug statements.
0174  *
0175  ******************************************************************************/
0176 
0177 char *
0178 AcpiNsGetExternalPathname (
0179     ACPI_NAMESPACE_NODE     *Node)
0180 {
0181     char                    *NameBuffer;
0182 
0183 
0184     ACPI_FUNCTION_TRACE_PTR (NsGetExternalPathname, Node);
0185 
0186 
0187     NameBuffer = AcpiNsGetNormalizedPathname (Node, FALSE);
0188     return_PTR (NameBuffer);
0189 }
0190 
0191 
0192 /*******************************************************************************
0193  *
0194  * FUNCTION:    AcpiNsGetPathnameLength
0195  *
0196  * PARAMETERS:  Node        - Namespace node
0197  *
0198  * RETURN:      Length of path, including prefix
0199  *
0200  * DESCRIPTION: Get the length of the pathname string for this node
0201  *
0202  ******************************************************************************/
0203 
0204 ACPI_SIZE
0205 AcpiNsGetPathnameLength (
0206     ACPI_NAMESPACE_NODE     *Node)
0207 {
0208     ACPI_SIZE               Size;
0209 
0210 
0211     /* Validate the Node */
0212 
0213     if (ACPI_GET_DESCRIPTOR_TYPE (Node) != ACPI_DESC_TYPE_NAMED)
0214     {
0215         ACPI_ERROR ((AE_INFO,
0216             "Invalid/cached reference target node: %p, descriptor type %d",
0217             Node, ACPI_GET_DESCRIPTOR_TYPE (Node)));
0218         return (0);
0219     }
0220 
0221     Size = AcpiNsBuildNormalizedPath (Node, NULL, 0, FALSE);
0222     return (Size);
0223 }
0224 
0225 
0226 /*******************************************************************************
0227  *
0228  * FUNCTION:    AcpiNsHandleToName
0229  *
0230  * PARAMETERS:  TargetHandle            - Handle of named object whose name is
0231  *                                        to be found
0232  *              Buffer                  - Where the name is returned
0233  *
0234  * RETURN:      Status, Buffer is filled with name if status is AE_OK
0235  *
0236  * DESCRIPTION: Build and return a full namespace name
0237  *
0238  ******************************************************************************/
0239 
0240 ACPI_STATUS
0241 AcpiNsHandleToName (
0242     ACPI_HANDLE             TargetHandle,
0243     ACPI_BUFFER             *Buffer)
0244 {
0245     ACPI_STATUS             Status;
0246     ACPI_NAMESPACE_NODE     *Node;
0247     const char              *NodeName;
0248 
0249 
0250     ACPI_FUNCTION_TRACE_PTR (NsHandleToName, TargetHandle);
0251 
0252 
0253     Node = AcpiNsValidateHandle (TargetHandle);
0254     if (!Node)
0255     {
0256         return_ACPI_STATUS (AE_BAD_PARAMETER);
0257     }
0258 
0259     /* Validate/Allocate/Clear caller buffer */
0260 
0261     Status = AcpiUtInitializeBuffer (Buffer, ACPI_PATH_SEGMENT_LENGTH);
0262     if (ACPI_FAILURE (Status))
0263     {
0264         return_ACPI_STATUS (Status);
0265     }
0266 
0267     /* Just copy the ACPI name from the Node and zero terminate it */
0268 
0269     NodeName = AcpiUtGetNodeName (Node);
0270     ACPI_COPY_NAMESEG (Buffer->Pointer, NodeName);
0271     ((char *) Buffer->Pointer) [ACPI_NAMESEG_SIZE] = 0;
0272 
0273     ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%4.4s\n", (char *) Buffer->Pointer));
0274     return_ACPI_STATUS (AE_OK);
0275 }
0276 
0277 
0278 /*******************************************************************************
0279  *
0280  * FUNCTION:    AcpiNsHandleToPathname
0281  *
0282  * PARAMETERS:  TargetHandle            - Handle of named object whose name is
0283  *                                        to be found
0284  *              Buffer                  - Where the pathname is returned
0285  *              NoTrailing              - Remove trailing '_' for each name
0286  *                                        segment
0287  *
0288  * RETURN:      Status, Buffer is filled with pathname if status is AE_OK
0289  *
0290  * DESCRIPTION: Build and return a full namespace pathname
0291  *
0292  ******************************************************************************/
0293 
0294 ACPI_STATUS
0295 AcpiNsHandleToPathname (
0296     ACPI_HANDLE             TargetHandle,
0297     ACPI_BUFFER             *Buffer,
0298     BOOLEAN                 NoTrailing)
0299 {
0300     ACPI_STATUS             Status;
0301     ACPI_NAMESPACE_NODE     *Node;
0302     ACPI_SIZE               RequiredSize;
0303 
0304 
0305     ACPI_FUNCTION_TRACE_PTR (NsHandleToPathname, TargetHandle);
0306 
0307 
0308     Node = AcpiNsValidateHandle (TargetHandle);
0309     if (!Node)
0310     {
0311         return_ACPI_STATUS (AE_BAD_PARAMETER);
0312     }
0313 
0314     /* Determine size required for the caller buffer */
0315 
0316     RequiredSize = AcpiNsBuildNormalizedPath (Node, NULL, 0, NoTrailing);
0317     if (!RequiredSize)
0318     {
0319         return_ACPI_STATUS (AE_BAD_PARAMETER);
0320     }
0321 
0322     /* Validate/Allocate/Clear caller buffer */
0323 
0324     Status = AcpiUtInitializeBuffer (Buffer, RequiredSize);
0325     if (ACPI_FAILURE (Status))
0326     {
0327         return_ACPI_STATUS (Status);
0328     }
0329 
0330     /* Build the path in the caller buffer */
0331 
0332     (void) AcpiNsBuildNormalizedPath (Node, Buffer->Pointer,
0333         (UINT32) RequiredSize, NoTrailing);
0334 
0335     ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%s [%X]\n",
0336         (char *) Buffer->Pointer, (UINT32) RequiredSize));
0337     return_ACPI_STATUS (AE_OK);
0338 }
0339 
0340 
0341 /*******************************************************************************
0342  *
0343  * FUNCTION:    AcpiNsBuildNormalizedPath
0344  *
0345  * PARAMETERS:  Node        - Namespace node
0346  *              FullPath    - Where the path name is returned
0347  *              PathSize    - Size of returned path name buffer
0348  *              NoTrailing  - Remove trailing '_' from each name segment
0349  *
0350  * RETURN:      Return 1 if the AML path is empty, otherwise returning (length
0351  *              of pathname + 1) which means the 'FullPath' contains a trailing
0352  *              null.
0353  *
0354  * DESCRIPTION: Build and return a full namespace pathname.
0355  *              Note that if the size of 'FullPath' isn't large enough to
0356  *              contain the namespace node's path name, the actual required
0357  *              buffer length is returned, and it should be greater than
0358  *              'PathSize'. So callers are able to check the returning value
0359  *              to determine the buffer size of 'FullPath'.
0360  *
0361  ******************************************************************************/
0362 
0363 UINT32
0364 AcpiNsBuildNormalizedPath (
0365     ACPI_NAMESPACE_NODE     *Node,
0366     char                    *FullPath,
0367     UINT32                  PathSize,
0368     BOOLEAN                 NoTrailing)
0369 {
0370     UINT32                  Length = 0, i;
0371     char                    Name[ACPI_NAMESEG_SIZE];
0372     BOOLEAN                 DoNoTrailing;
0373     char                    c, *Left, *Right;
0374     ACPI_NAMESPACE_NODE     *NextNode;
0375 
0376 
0377     ACPI_FUNCTION_TRACE_PTR (NsBuildNormalizedPath, Node);
0378 
0379 
0380 #define ACPI_PATH_PUT8(Path, Size, Byte, Length)    \
0381     do {                                            \
0382         if ((Length) < (Size))                      \
0383         {                                           \
0384             (Path)[(Length)] = (Byte);              \
0385         }                                           \
0386         (Length)++;                                 \
0387     } while (0)
0388 
0389     /*
0390      * Make sure the PathSize is correct, so that we don't need to
0391      * validate both FullPath and PathSize.
0392      */
0393     if (!FullPath)
0394     {
0395         PathSize = 0;
0396     }
0397 
0398     if (!Node)
0399     {
0400         goto BuildTrailingNull;
0401     }
0402 
0403     NextNode = Node;
0404     while (NextNode && NextNode != AcpiGbl_RootNode)
0405     {
0406         if (NextNode != Node)
0407         {
0408             ACPI_PATH_PUT8(FullPath, PathSize, AML_DUAL_NAME_PREFIX, Length);
0409         }
0410 
0411         ACPI_MOVE_32_TO_32 (Name, &NextNode->Name);
0412         DoNoTrailing = NoTrailing;
0413         for (i = 0; i < 4; i++)
0414         {
0415             c = Name[4-i-1];
0416             if (DoNoTrailing && c != '_')
0417             {
0418                 DoNoTrailing = FALSE;
0419             }
0420             if (!DoNoTrailing)
0421             {
0422                 ACPI_PATH_PUT8(FullPath, PathSize, c, Length);
0423             }
0424         }
0425 
0426         NextNode = NextNode->Parent;
0427     }
0428 
0429     ACPI_PATH_PUT8(FullPath, PathSize, AML_ROOT_PREFIX, Length);
0430 
0431     /* Reverse the path string */
0432 
0433     if (Length <= PathSize)
0434     {
0435         Left = FullPath;
0436         Right = FullPath+Length - 1;
0437 
0438         while (Left < Right)
0439         {
0440             c = *Left;
0441             *Left++ = *Right;
0442             *Right-- = c;
0443         }
0444     }
0445 
0446     /* Append the trailing null */
0447 
0448 BuildTrailingNull:
0449     ACPI_PATH_PUT8 (FullPath, PathSize, '\0', Length);
0450 
0451 #undef ACPI_PATH_PUT8
0452 
0453     return_UINT32 (Length);
0454 }
0455 
0456 
0457 /*******************************************************************************
0458  *
0459  * FUNCTION:    AcpiNsGetNormalizedPathname
0460  *
0461  * PARAMETERS:  Node            - Namespace node whose pathname is needed
0462  *              NoTrailing      - Remove trailing '_' from each name segment
0463  *
0464  * RETURN:      Pointer to storage containing the fully qualified name of
0465  *              the node, In external format (name segments separated by path
0466  *              separators.)
0467  *
0468  * DESCRIPTION: Used to obtain the full pathname to a namespace node, usually
0469  *              for error and debug statements. All trailing '_' will be
0470  *              removed from the full pathname if 'NoTrailing' is specified..
0471  *
0472  ******************************************************************************/
0473 
0474 char *
0475 AcpiNsGetNormalizedPathname (
0476     ACPI_NAMESPACE_NODE     *Node,
0477     BOOLEAN                 NoTrailing)
0478 {
0479     char                    *NameBuffer;
0480     ACPI_SIZE               Size;
0481 
0482 
0483     ACPI_FUNCTION_TRACE_PTR (NsGetNormalizedPathname, Node);
0484 
0485 
0486     /* Calculate required buffer size based on depth below root */
0487 
0488     Size = AcpiNsBuildNormalizedPath (Node, NULL, 0, NoTrailing);
0489     if (!Size)
0490     {
0491         return_PTR (NULL);
0492     }
0493 
0494     /* Allocate a buffer to be returned to caller */
0495 
0496     NameBuffer = ACPI_ALLOCATE_ZEROED (Size);
0497     if (!NameBuffer)
0498     {
0499         ACPI_ERROR ((AE_INFO,
0500             "Could not allocate %u bytes", (UINT32) Size));
0501         return_PTR (NULL);
0502     }
0503 
0504     /* Build the path in the allocated buffer */
0505 
0506     (void) AcpiNsBuildNormalizedPath (Node, NameBuffer, (UINT32) Size, NoTrailing);
0507 
0508     ACPI_DEBUG_PRINT_RAW ((ACPI_DB_NAMES, "%s: Path \"%s\"\n",
0509         ACPI_GET_FUNCTION_NAME, NameBuffer));
0510 
0511     return_PTR (NameBuffer);
0512 }
0513 
0514 
0515 /*******************************************************************************
0516  *
0517  * FUNCTION:    AcpiNsBuildPrefixedPathname
0518  *
0519  * PARAMETERS:  PrefixScope         - Scope/Path that prefixes the internal path
0520  *              InternalPath        - Name or path of the namespace node
0521  *
0522  * RETURN:      None
0523  *
0524  * DESCRIPTION: Construct a fully qualified pathname from a concatenation of:
0525  *              1) Path associated with the PrefixScope namespace node
0526  *              2) External path representation of the Internal path
0527  *
0528  ******************************************************************************/
0529 
0530 char *
0531 AcpiNsBuildPrefixedPathname (
0532     ACPI_GENERIC_STATE      *PrefixScope,
0533     const char              *InternalPath)
0534 {
0535     ACPI_STATUS             Status;
0536     char                    *FullPath = NULL;
0537     char                    *ExternalPath = NULL;
0538     char                    *PrefixPath = NULL;
0539     ACPI_SIZE               PrefixPathLength = 0;
0540 
0541 
0542     /* If there is a prefix, get the pathname to it */
0543 
0544     if (PrefixScope && PrefixScope->Scope.Node)
0545     {
0546         PrefixPath = AcpiNsGetNormalizedPathname (PrefixScope->Scope.Node, TRUE);
0547         if (PrefixPath)
0548         {
0549             PrefixPathLength = strlen (PrefixPath);
0550         }
0551     }
0552 
0553     Status = AcpiNsExternalizeName (ACPI_UINT32_MAX, InternalPath,
0554         NULL, &ExternalPath);
0555     if (ACPI_FAILURE (Status))
0556     {
0557         goto Cleanup;
0558     }
0559 
0560     /* Merge the prefix path and the path. 2 is for one dot and trailing null */
0561 
0562     FullPath = ACPI_ALLOCATE_ZEROED (
0563         PrefixPathLength + strlen (ExternalPath) + 2);
0564     if (!FullPath)
0565     {
0566         goto Cleanup;
0567     }
0568 
0569     /* Don't merge if the External path is already fully qualified */
0570 
0571     if (PrefixPath &&
0572         (*ExternalPath != '\\') &&
0573         (*ExternalPath != '^'))
0574     {
0575         strcat (FullPath, PrefixPath);
0576         if (PrefixPath[1])
0577         {
0578             strcat (FullPath, ".");
0579         }
0580     }
0581 
0582     AcpiNsNormalizePathname (ExternalPath);
0583     strcat (FullPath, ExternalPath);
0584 
0585 Cleanup:
0586     if (PrefixPath)
0587     {
0588         ACPI_FREE (PrefixPath);
0589     }
0590     if (ExternalPath)
0591     {
0592         ACPI_FREE (ExternalPath);
0593     }
0594 
0595     return (FullPath);
0596 }
0597 
0598 
0599 /*******************************************************************************
0600  *
0601  * FUNCTION:    AcpiNsNormalizePathname
0602  *
0603  * PARAMETERS:  OriginalPath        - Path to be normalized, in External format
0604  *
0605  * RETURN:      The original path is processed in-place
0606  *
0607  * DESCRIPTION: Remove trailing underscores from each element of a path.
0608  *
0609  *              For example:  \A___.B___.C___ becomes \A.B.C
0610  *
0611  ******************************************************************************/
0612 
0613 void
0614 AcpiNsNormalizePathname (
0615     char                    *OriginalPath)
0616 {
0617     char                    *InputPath = OriginalPath;
0618     char                    *NewPathBuffer;
0619     char                    *NewPath;
0620     UINT32                  i;
0621 
0622 
0623     /* Allocate a temp buffer in which to construct the new path */
0624 
0625     NewPathBuffer = ACPI_ALLOCATE_ZEROED (strlen (InputPath) + 1);
0626     NewPath = NewPathBuffer;
0627     if (!NewPathBuffer)
0628     {
0629         return;
0630     }
0631 
0632     /* Special characters may appear at the beginning of the path */
0633 
0634     if (*InputPath == '\\')
0635     {
0636         *NewPath = *InputPath;
0637         NewPath++;
0638         InputPath++;
0639     }
0640 
0641     while (*InputPath == '^')
0642     {
0643         *NewPath = *InputPath;
0644         NewPath++;
0645         InputPath++;
0646     }
0647 
0648     /* Remainder of the path */
0649 
0650     while (*InputPath)
0651     {
0652         /* Do one nameseg at a time */
0653 
0654         for (i = 0; (i < ACPI_NAMESEG_SIZE) && *InputPath; i++)
0655         {
0656             if ((i == 0) || (*InputPath != '_')) /* First char is allowed to be underscore */
0657             {
0658                 *NewPath = *InputPath;
0659                 NewPath++;
0660             }
0661 
0662             InputPath++;
0663         }
0664 
0665         /* Dot means that there are more namesegs to come */
0666 
0667         if (*InputPath == '.')
0668         {
0669             *NewPath = *InputPath;
0670             NewPath++;
0671             InputPath++;
0672         }
0673     }
0674 
0675     *NewPath = 0;
0676     strcpy (OriginalPath, NewPathBuffer);
0677     ACPI_FREE (NewPathBuffer);
0678 }