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