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