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