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