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