aslutils.c revision 1.1.1.18 1 /******************************************************************************
2 *
3 * Module Name: aslutils -- compiler utilities
4 *
5 *****************************************************************************/
6
7 /*
8 * Copyright (C) 2000 - 2019, 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 static void
70 UtDisplayErrorSummary (
71 UINT32 FileId);
72
73
74 /*******************************************************************************
75 *
76 * FUNCTION: UtIsBigEndianMachine
77 *
78 * PARAMETERS: None
79 *
80 * RETURN: TRUE if machine is big endian
81 * FALSE if machine is little endian
82 *
83 * DESCRIPTION: Detect whether machine is little endian or big endian.
84 *
85 ******************************************************************************/
86
87 UINT8
88 UtIsBigEndianMachine (
89 void)
90 {
91 union {
92 UINT32 Integer;
93 UINT8 Bytes[4];
94 } Overlay = {0xFF000000};
95
96
97 return (Overlay.Bytes[0]); /* Returns 0xFF (TRUE) for big endian */
98 }
99
100
101 /******************************************************************************
102 *
103 * FUNCTION: UtQueryForOverwrite
104 *
105 * PARAMETERS: Pathname - Output filename
106 *
107 * RETURN: TRUE if file does not exist or overwrite is authorized
108 *
109 * DESCRIPTION: Query for file overwrite if it already exists.
110 *
111 ******************************************************************************/
112
113 BOOLEAN
114 UtQueryForOverwrite (
115 char *Pathname)
116 {
117 struct stat StatInfo;
118 int InChar = 0x34;
119
120
121 if (!stat (Pathname, &StatInfo))
122 {
123 fprintf (stderr, "Target file \"%s\" already exists, overwrite? [y|n] ",
124 Pathname);
125
126 InChar = fgetc (stdin);
127 if (InChar == '\n')
128 {
129 InChar = fgetc (stdin);
130 }
131
132 if ((InChar != 'y') && (InChar != 'Y'))
133 {
134 return (FALSE);
135 }
136 }
137
138 return (TRUE);
139 }
140
141
142 /*******************************************************************************
143 *
144 * FUNCTION: UtNodeIsDescendantOf
145 *
146 * PARAMETERS: Node1 - Child node
147 * Node2 - Possible parent node
148 *
149 * RETURN: Boolean
150 *
151 * DESCRIPTION: Returns TRUE if Node1 is a descendant of Node2. Otherwise,
152 * return FALSE. Note, we assume a NULL Node2 element to be the
153 * topmost (root) scope. All nodes are descendants of the root.
154 * Note: Nodes at the same level (siblings) are not considered
155 * descendants.
156 *
157 ******************************************************************************/
158
159 BOOLEAN
160 UtNodeIsDescendantOf (
161 ACPI_NAMESPACE_NODE *Node1,
162 ACPI_NAMESPACE_NODE *Node2)
163 {
164
165 if (Node1 == Node2)
166 {
167 return (FALSE);
168 }
169
170 if (!Node2)
171 {
172 return (TRUE); /* All nodes descend from the root */
173 }
174
175 /* Walk upward until the root is reached or parent is found */
176
177 while (Node1)
178 {
179 if (Node1 == Node2)
180 {
181 return (TRUE);
182 }
183
184 Node1 = Node1->Parent;
185 }
186
187 return (FALSE);
188 }
189
190
191 /*******************************************************************************
192 *
193 * FUNCTION: UtGetParentMethod
194 *
195 * PARAMETERS: Node - Namespace node for any object
196 *
197 * RETURN: Namespace node for the parent method
198 * NULL - object is not within a method
199 *
200 * DESCRIPTION: Find the parent (owning) method node for a namespace object
201 *
202 ******************************************************************************/
203
204 void *
205 UtGetParentMethod (
206 ACPI_NAMESPACE_NODE *Node)
207 {
208 ACPI_NAMESPACE_NODE *ParentNode;
209
210
211 if (!Node)
212 {
213 return (NULL);
214 }
215
216 /* Walk upward until a method is found, or the root is reached */
217
218 ParentNode = Node->Parent;
219 while (ParentNode)
220 {
221 if (ParentNode->Type == ACPI_TYPE_METHOD)
222 {
223 return (ParentNode);
224 }
225
226 ParentNode = ParentNode->Parent;
227 }
228
229 return (NULL); /* Object is not within a control method */
230 }
231
232
233 /*******************************************************************************
234 *
235 * FUNCTION: UtDisplaySupportedTables
236 *
237 * PARAMETERS: None
238 *
239 * RETURN: None
240 *
241 * DESCRIPTION: Print all supported ACPI table names.
242 *
243 ******************************************************************************/
244
245 void
246 UtDisplaySupportedTables (
247 void)
248 {
249 const AH_TABLE *TableData;
250 UINT32 i;
251
252
253 printf ("\nACPI tables supported by iASL version %8.8X:\n"
254 " (Compiler, Disassembler, Template Generator)\n\n",
255 ACPI_CA_VERSION);
256
257 /* All ACPI tables with the common table header */
258
259 printf ("\n Supported ACPI tables:\n");
260 for (TableData = AcpiGbl_SupportedTables, i = 1;
261 TableData->Signature; TableData++, i++)
262 {
263 printf ("%8u) %s %s\n", i,
264 TableData->Signature, TableData->Description);
265 }
266 }
267
268
269 /*******************************************************************************
270 *
271 * FUNCTION: UtDisplayConstantOpcodes
272 *
273 * PARAMETERS: None
274 *
275 * RETURN: None
276 *
277 * DESCRIPTION: Print AML opcodes that can be used in constant expressions.
278 *
279 ******************************************************************************/
280
281 void
282 UtDisplayConstantOpcodes (
283 void)
284 {
285 UINT32 i;
286
287
288 printf ("Constant expression opcode information\n\n");
289
290 for (i = 0; i < sizeof (AcpiGbl_AmlOpInfo) / sizeof (ACPI_OPCODE_INFO); i++)
291 {
292 if (AcpiGbl_AmlOpInfo[i].Flags & AML_CONSTANT)
293 {
294 printf ("%s\n", AcpiGbl_AmlOpInfo[i].Name);
295 }
296 }
297 }
298
299
300 /*******************************************************************************
301 *
302 * FUNCTION: UtBeginEvent
303 *
304 * PARAMETERS: Name - Ascii name of this event
305 *
306 * RETURN: Event number (integer index)
307 *
308 * DESCRIPTION: Saves the current time with this event
309 *
310 ******************************************************************************/
311
312 UINT8
313 UtBeginEvent (
314 char *Name)
315 {
316
317 if (AslGbl_NextEvent >= ASL_NUM_EVENTS)
318 {
319 AcpiOsPrintf ("Ran out of compiler event structs!\n");
320 return (AslGbl_NextEvent);
321 }
322
323 /* Init event with current (start) time */
324
325 AslGbl_Events[AslGbl_NextEvent].StartTime = AcpiOsGetTimer ();
326 AslGbl_Events[AslGbl_NextEvent].EventName = Name;
327 AslGbl_Events[AslGbl_NextEvent].Valid = TRUE;
328 return (AslGbl_NextEvent++);
329 }
330
331
332 /*******************************************************************************
333 *
334 * FUNCTION: UtEndEvent
335 *
336 * PARAMETERS: Event - Event number (integer index)
337 *
338 * RETURN: None
339 *
340 * DESCRIPTION: Saves the current time (end time) with this event
341 *
342 ******************************************************************************/
343
344 void
345 UtEndEvent (
346 UINT8 Event)
347 {
348
349 if (Event >= ASL_NUM_EVENTS)
350 {
351 return;
352 }
353
354 /* Insert end time for event */
355
356 AslGbl_Events[Event].EndTime = AcpiOsGetTimer ();
357 }
358
359
360 /*******************************************************************************
361 *
362 * FUNCTION: DbgPrint
363 *
364 * PARAMETERS: Type - Type of output
365 * Fmt - Printf format string
366 * ... - variable printf list
367 *
368 * RETURN: None
369 *
370 * DESCRIPTION: Conditional print statement. Prints to stderr only if the
371 * debug flag is set.
372 *
373 ******************************************************************************/
374
375 void
376 DbgPrint (
377 UINT32 Type,
378 char *Fmt,
379 ...)
380 {
381 va_list Args;
382
383
384 if (!AslGbl_DebugFlag)
385 {
386 return;
387 }
388
389 if ((Type == ASL_PARSE_OUTPUT) &&
390 (!(AslCompilerdebug)))
391 {
392 return;
393 }
394
395 va_start (Args, Fmt);
396 (void) vfprintf (stderr, Fmt, Args);
397 va_end (Args);
398 return;
399 }
400
401
402 /*******************************************************************************
403 *
404 * FUNCTION: UtSetParseOpName
405 *
406 * PARAMETERS: Op - Parse op to be named.
407 *
408 * RETURN: None
409 *
410 * DESCRIPTION: Insert the ascii name of the parse opcode
411 *
412 ******************************************************************************/
413
414 void
415 UtSetParseOpName (
416 ACPI_PARSE_OBJECT *Op)
417 {
418
419 AcpiUtSafeStrncpy (Op->Asl.ParseOpName, UtGetOpName (Op->Asl.ParseOpcode),
420 ACPI_MAX_PARSEOP_NAME);
421 }
422
423
424 /*******************************************************************************
425 *
426 * FUNCTION: UtDisplayOneSummary
427 *
428 * PARAMETERS: FileID - ID of outpout file
429 *
430 * RETURN: None
431 *
432 * DESCRIPTION: Display compilation statistics for one input file
433 *
434 ******************************************************************************/
435
436 void
437 UtDisplayOneSummary (
438 UINT32 FileId,
439 BOOLEAN DisplayErrorSummary)
440 {
441 UINT32 i;
442 ASL_GLOBAL_FILE_NODE *FileNode;
443 BOOLEAN DisplayAMLSummary;
444
445
446 DisplayAMLSummary =
447 !AslGbl_PreprocessOnly && !AslGbl_ParserErrorDetected &&
448 ((AslGbl_ExceptionCount[ASL_ERROR] == 0) || AslGbl_IgnoreErrors) &&
449 AslGbl_Files[ASL_FILE_AML_OUTPUT].Handle;
450
451 if (FileId != ASL_FILE_STDOUT)
452 {
453 /* Compiler name and version number */
454
455 FlPrintFile (FileId, "%s version %X [%s]\n\n",
456 ASL_COMPILER_NAME, (UINT32) ACPI_CA_VERSION, __DATE__);
457 }
458
459 /* Summary of main input and output files */
460
461 FileNode = FlGetCurrentFileNode ();
462 if (!FileNode)
463 {
464 fprintf (stderr, "Summary could not be generated");
465 return;
466 }
467
468 if (FileNode->ParserErrorDetected)
469 {
470 FlPrintFile (FileId,
471 "%-14s %s - Compilation aborted due to parser-detected syntax error(s)\n",
472 "Input file:", AslGbl_Files[ASL_FILE_INPUT].Filename);
473 }
474 else if (FileNode->FileType == ASL_INPUT_TYPE_ASCII_DATA)
475 {
476 FlPrintFile (FileId,
477 "%-14s %s - %7u bytes %6u fields %8u source lines\n",
478 "Table Input:",
479 AslGbl_Files[ASL_FILE_INPUT].Filename,
480 FileNode->OriginalInputFileSize, FileNode->TotalFields,
481 FileNode->TotalLineCount);
482
483 FlPrintFile (FileId,
484 "%-14s %s - %7u bytes\n",
485 "Binary Output:",
486 AslGbl_Files[ASL_FILE_AML_OUTPUT].Filename, FileNode->OutputByteLength);
487 }
488 else if (FileNode->FileType == ASL_INPUT_TYPE_ASCII_ASL)
489 {
490 FlPrintFile (FileId,
491 "%-14s %s - %7u bytes %6u keywords %6u source lines\n",
492 "ASL Input:",
493 AslGbl_Files[ASL_FILE_INPUT].Filename,
494 FileNode->OriginalInputFileSize,
495 FileNode->TotalKeywords,
496 FileNode->TotalLineCount);
497
498 /* AML summary */
499
500 if (DisplayAMLSummary)
501 {
502 FlPrintFile (FileId,
503 "%-14s %s - %7u bytes %6u opcodes %6u named objects\n",
504 "AML Output:",
505 AslGbl_Files[ASL_FILE_AML_OUTPUT].Filename,
506 FlGetFileSize (ASL_FILE_AML_OUTPUT),
507 FileNode->TotalExecutableOpcodes,
508 FileNode->TotalNamedObjects);
509 }
510 }
511
512 /* Display summary of any optional files */
513
514 for (i = ASL_FILE_SOURCE_OUTPUT; i <= ASL_MAX_FILE_TYPE; i++)
515 {
516 if (!AslGbl_Files[i].Filename || !AslGbl_Files[i].Handle)
517 {
518 continue;
519 }
520
521 /* .SRC is a temp file unless specifically requested */
522
523 if ((i == ASL_FILE_SOURCE_OUTPUT) && (!AslGbl_SourceOutputFlag))
524 {
525 continue;
526 }
527
528 /* .PRE is the preprocessor intermediate file */
529
530 if ((i == ASL_FILE_PREPROCESSOR) && (!AslGbl_KeepPreprocessorTempFile))
531 {
532 continue;
533 }
534
535 FlPrintFile (FileId, "%-14s %s - %7u bytes\n",
536 AslGbl_FileDescs[i].ShortDescription,
537 AslGbl_Files[i].Filename, FlGetFileSize (i));
538 }
539
540
541 /*
542 * Optionally emit an error summary for a file. This is used to enhance the
543 * appearance of listing files.
544 */
545 if (DisplayErrorSummary)
546 {
547 UtDisplayErrorSummary (FileId);
548 }
549 }
550
551
552 /*******************************************************************************
553 *
554 * FUNCTION: UtDisplayErrorSummary
555 *
556 * PARAMETERS: FileID - ID of outpout file
557 *
558 * RETURN: None
559 *
560 * DESCRIPTION: Display compilation statistics for all input files
561 *
562 ******************************************************************************/
563
564 static void
565 UtDisplayErrorSummary (
566 UINT32 FileId)
567 {
568 BOOLEAN ErrorDetected;
569
570
571 ErrorDetected = AslGbl_ParserErrorDetected ||
572 ((AslGbl_ExceptionCount[ASL_ERROR] > 0) && !AslGbl_IgnoreErrors);
573
574 if (ErrorDetected)
575 {
576 FlPrintFile (FileId, "\nCompilation failed. ");
577 }
578 else
579 {
580 FlPrintFile (FileId, "\nCompilation successful. ");
581 }
582
583 FlPrintFile (FileId,
584 "%u Errors, %u Warnings, %u Remarks",
585 AslGbl_ExceptionCount[ASL_ERROR],
586 AslGbl_ExceptionCount[ASL_WARNING] +
587 AslGbl_ExceptionCount[ASL_WARNING2] +
588 AslGbl_ExceptionCount[ASL_WARNING3],
589 AslGbl_ExceptionCount[ASL_REMARK]);
590
591 if (AslGbl_FileType != ASL_INPUT_TYPE_ASCII_DATA)
592 {
593 if (AslGbl_ParserErrorDetected)
594 {
595 FlPrintFile (FileId,
596 "\nNo AML files were generated due to syntax error(s)\n");
597 return;
598 }
599 else if (ErrorDetected)
600 {
601 FlPrintFile (FileId,
602 "\nNo AML files were generated due to compiler error(s)\n");
603 return;
604 }
605
606 FlPrintFile (FileId, ", %u Optimizations",
607 AslGbl_ExceptionCount[ASL_OPTIMIZATION]);
608
609 if (AslGbl_TotalFolds)
610 {
611 FlPrintFile (FileId, ", %u Constants Folded", AslGbl_TotalFolds);
612 }
613 }
614
615 FlPrintFile (FileId, "\n");
616 }
617
618
619 /*******************************************************************************
620 *
621 * FUNCTION: UtDisplaySummary
622 *
623 * PARAMETERS: FileID - ID of outpout file
624 *
625 * RETURN: None
626 *
627 * DESCRIPTION: Display compilation statistics for all input files
628 *
629 ******************************************************************************/
630
631 void
632 UtDisplaySummary (
633 UINT32 FileId)
634 {
635 ASL_GLOBAL_FILE_NODE *Current = AslGbl_FilesList;
636
637
638 while (Current)
639 {
640 switch (FlSwitchFileSet(Current->Files[ASL_FILE_INPUT].Filename))
641 {
642 case SWITCH_TO_SAME_FILE:
643 case SWITCH_TO_DIFFERENT_FILE:
644
645 UtDisplayOneSummary (FileId, FALSE);
646 Current = Current->Next;
647 break;
648
649 case FILE_NOT_FOUND:
650 default:
651
652 Current = NULL;
653 break;
654 }
655 }
656 UtDisplayErrorSummary (FileId);
657 }
658
659 /*******************************************************************************
660 *
661 * FUNCTION: UtCheckIntegerRange
662 *
663 * PARAMETERS: Op - Integer parse node
664 * LowValue - Smallest allowed value
665 * HighValue - Largest allowed value
666 *
667 * RETURN: Op if OK, otherwise NULL
668 *
669 * DESCRIPTION: Check integer for an allowable range
670 *
671 ******************************************************************************/
672
673 ACPI_PARSE_OBJECT *
674 UtCheckIntegerRange (
675 ACPI_PARSE_OBJECT *Op,
676 UINT32 LowValue,
677 UINT32 HighValue)
678 {
679
680 if (!Op)
681 {
682 return (NULL);
683 }
684
685 if ((Op->Asl.Value.Integer < LowValue) ||
686 (Op->Asl.Value.Integer > HighValue))
687 {
688 sprintf (AslGbl_MsgBuffer, "0x%X, allowable: 0x%X-0x%X",
689 (UINT32) Op->Asl.Value.Integer, LowValue, HighValue);
690
691 AslError (ASL_ERROR, ASL_MSG_RANGE, Op, AslGbl_MsgBuffer);
692 return (NULL);
693 }
694
695 return (Op);
696 }
697
698
699 /*******************************************************************************
700 *
701 * FUNCTION: UtInternalizeName
702 *
703 * PARAMETERS: ExternalName - Name to convert
704 * ConvertedName - Where the converted name is returned
705 *
706 * RETURN: Status
707 *
708 * DESCRIPTION: Convert an external (ASL) name to an internal (AML) name
709 *
710 ******************************************************************************/
711
712 ACPI_STATUS
713 UtInternalizeName (
714 char *ExternalName,
715 char **ConvertedName)
716 {
717 ACPI_NAMESTRING_INFO Info;
718 ACPI_STATUS Status;
719
720
721 if (!ExternalName)
722 {
723 return (AE_OK);
724 }
725
726 /* Get the length of the new internal name */
727
728 Info.ExternalName = ExternalName;
729 AcpiNsGetInternalNameLength (&Info);
730
731 /* We need a segment to store the internal name */
732
733 Info.InternalName = UtLocalCacheCalloc (Info.Length);
734
735 /* Build the name */
736
737 Status = AcpiNsBuildInternalName (&Info);
738 if (ACPI_FAILURE (Status))
739 {
740 return (Status);
741 }
742
743 *ConvertedName = Info.InternalName;
744 return (AE_OK);
745 }
746
747
748 /*******************************************************************************
749 *
750 * FUNCTION: UtPadNameWithUnderscores
751 *
752 * PARAMETERS: NameSeg - Input nameseg
753 * PaddedNameSeg - Output padded nameseg
754 *
755 * RETURN: Padded nameseg.
756 *
757 * DESCRIPTION: Pads a NameSeg with underscores if necessary to form a full
758 * ACPI_NAME.
759 *
760 ******************************************************************************/
761
762 static void
763 UtPadNameWithUnderscores (
764 char *NameSeg,
765 char *PaddedNameSeg)
766 {
767 UINT32 i;
768
769
770 for (i = 0; (i < ACPI_NAMESEG_SIZE); i++)
771 {
772 if (*NameSeg)
773 {
774 *PaddedNameSeg = *NameSeg;
775 NameSeg++;
776 }
777 else
778 {
779 *PaddedNameSeg = '_';
780 }
781
782 PaddedNameSeg++;
783 }
784 }
785
786
787 /*******************************************************************************
788 *
789 * FUNCTION: UtAttachNameseg
790 *
791 * PARAMETERS: Op - Parent parse node
792 * Name - Full ExternalName
793 *
794 * RETURN: None; Sets the NameSeg field in parent node
795 *
796 * DESCRIPTION: Extract the last nameseg of the ExternalName and store it
797 * in the NameSeg field of the Op.
798 *
799 ******************************************************************************/
800
801 static void
802 UtAttachNameseg (
803 ACPI_PARSE_OBJECT *Op,
804 char *Name)
805 {
806 char *NameSeg;
807 char PaddedNameSeg[4];
808
809
810 if (!Name)
811 {
812 return;
813 }
814
815 /* Look for the last dot in the namepath */
816
817 NameSeg = strrchr (Name, '.');
818 if (NameSeg)
819 {
820 /* Found last dot, we have also found the final nameseg */
821
822 NameSeg++;
823 UtPadNameWithUnderscores (NameSeg, PaddedNameSeg);
824 }
825 else
826 {
827 /* No dots in the namepath, there is only a single nameseg. */
828 /* Handle prefixes */
829
830 while (ACPI_IS_ROOT_PREFIX (*Name) ||
831 ACPI_IS_PARENT_PREFIX (*Name))
832 {
833 Name++;
834 }
835
836 /* Remaining string should be one single nameseg */
837
838 UtPadNameWithUnderscores (Name, PaddedNameSeg);
839 }
840
841 ACPI_COPY_NAMESEG (Op->Asl.NameSeg, PaddedNameSeg);
842 }
843
844
845 /*******************************************************************************
846 *
847 * FUNCTION: UtAttachNamepathToOwner
848 *
849 * PARAMETERS: Op - Parent parse node
850 * NameOp - Node that contains the name
851 *
852 * RETURN: Sets the ExternalName and Namepath in the parent node
853 *
854 * DESCRIPTION: Store the name in two forms in the parent node: The original
855 * (external) name, and the internalized name that is used within
856 * the ACPI namespace manager.
857 *
858 ******************************************************************************/
859
860 void
861 UtAttachNamepathToOwner (
862 ACPI_PARSE_OBJECT *Op,
863 ACPI_PARSE_OBJECT *NameOp)
864 {
865 ACPI_STATUS Status;
866
867
868 /* Full external path */
869
870 Op->Asl.ExternalName = NameOp->Asl.Value.String;
871
872 /* Save the NameOp for possible error reporting later */
873
874 Op->Asl.ParentMethod = (void *) NameOp;
875
876 /* Last nameseg of the path */
877
878 UtAttachNameseg (Op, Op->Asl.ExternalName);
879
880 /* Create internalized path */
881
882 Status = UtInternalizeName (NameOp->Asl.Value.String, &Op->Asl.Namepath);
883 if (ACPI_FAILURE (Status))
884 {
885 /* TBD: abort on no memory */
886 }
887 }
888
889
890 /*******************************************************************************
891 *
892 * FUNCTION: UtNameContainsAllPrefix
893 *
894 * PARAMETERS: Op - Op containing NameString
895 *
896 * RETURN: NameString consists of all ^ characters
897 *
898 * DESCRIPTION: Determine if this Op contains a name segment that consists of
899 * all '^' characters.
900 *
901 ******************************************************************************/
902
903 BOOLEAN
904 UtNameContainsAllPrefix (
905 ACPI_PARSE_OBJECT *Op)
906 {
907 UINT32 Length = Op->Asl.AmlLength;
908 UINT32 i;
909
910 for (i = 0; i < Length; i++)
911 {
912 if (Op->Asl.Value.String[i] != '^')
913 {
914 return (FALSE);
915 }
916 }
917
918 return (TRUE);
919 }
920
921 /*******************************************************************************
922 *
923 * FUNCTION: UtDoConstant
924 *
925 * PARAMETERS: String - Hex/Decimal/Octal
926 *
927 * RETURN: Converted Integer
928 *
929 * DESCRIPTION: Convert a string to an integer, with overflow/error checking.
930 *
931 ******************************************************************************/
932
933 UINT64
934 UtDoConstant (
935 char *String)
936 {
937 ACPI_STATUS Status;
938 UINT64 ConvertedInteger;
939 char ErrBuf[64];
940
941
942 Status = AcpiUtStrtoul64 (String, &ConvertedInteger);
943 if (ACPI_FAILURE (Status))
944 {
945 sprintf (ErrBuf, "While creating 64-bit constant: %s\n",
946 AcpiFormatException (Status));
947
948 AslCommonError (ASL_ERROR, ASL_MSG_SYNTAX, AslGbl_CurrentLineNumber,
949 AslGbl_LogicalLineNumber, AslGbl_CurrentLineOffset,
950 AslGbl_CurrentColumn, AslGbl_Files[ASL_FILE_INPUT].Filename, ErrBuf);
951 }
952
953 return (ConvertedInteger);
954 }
955
956
957 /******************************************************************************
958 *
959 * FUNCTION: AcpiUtStrdup
960 *
961 * PARAMETERS: String1 - string to duplicate
962 *
963 * RETURN: int that signifies string relationship. Zero means strings
964 * are equal.
965 *
966 * DESCRIPTION: Duplicate the string using UtCacheAlloc to avoid manual memory
967 * reclamation.
968 *
969 ******************************************************************************/
970
971 char *
972 AcpiUtStrdup (
973 char *String)
974 {
975 char *NewString = (char *) UtLocalCalloc (strlen (String) + 1);
976
977
978 strcpy (NewString, String);
979 return (NewString);
980 }
981
982
983 /******************************************************************************
984 *
985 * FUNCTION: AcpiUtStrcat
986 *
987 * PARAMETERS: String1
988 * String2
989 *
990 * RETURN: New string with String1 concatenated with String2
991 *
992 * DESCRIPTION: Concatenate string1 and string2
993 *
994 ******************************************************************************/
995
996 char *
997 AcpiUtStrcat (
998 char *String1,
999 char *String2)
1000 {
1001 UINT32 String1Length = strlen (String1);
1002 char *NewString = (char *) UtLocalCalloc (strlen (String1) + strlen (String2) + 1);
1003
1004 strcpy (NewString, String1);
1005 strcpy (NewString + String1Length, String2);
1006 return (NewString);
1007 }
1008