xref: /freebsd/sys/contrib/dev/acpica/compiler/cvcompiler.c (revision 69ef36e315772f884582ffc5ef888400fad61f52)
1 /******************************************************************************
2  *
3  * Module Name: cvcompiler - ASL-/ASL+ converter functions
4  *
5  *****************************************************************************/
6 
7 /******************************************************************************
8  *
9  * 1. Copyright Notice
10  *
11  * Some or all of this work - Copyright (c) 1999 - 2017, Intel Corp.
12  * All rights reserved.
13  *
14  * 2. License
15  *
16  * 2.1. This is your license from Intel Corp. under its intellectual property
17  * rights. You may have additional license terms from the party that provided
18  * you this software, covering your right to use that party's intellectual
19  * property rights.
20  *
21  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
22  * copy of the source code appearing in this file ("Covered Code") an
23  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
24  * base code distributed originally by Intel ("Original Intel Code") to copy,
25  * make derivatives, distribute, use and display any portion of the Covered
26  * Code in any form, with the right to sublicense such rights; and
27  *
28  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
29  * license (with the right to sublicense), under only those claims of Intel
30  * patents that are infringed by the Original Intel Code, to make, use, sell,
31  * offer to sell, and import the Covered Code and derivative works thereof
32  * solely to the minimum extent necessary to exercise the above copyright
33  * license, and in no event shall the patent license extend to any additions
34  * to or modifications of the Original Intel Code. No other license or right
35  * is granted directly or by implication, estoppel or otherwise;
36  *
37  * The above copyright and patent license is granted only if the following
38  * conditions are met:
39  *
40  * 3. Conditions
41  *
42  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
43  * Redistribution of source code of any substantial portion of the Covered
44  * Code or modification with rights to further distribute source must include
45  * the above Copyright Notice, the above License, this list of Conditions,
46  * and the following Disclaimer and Export Compliance provision. In addition,
47  * Licensee must cause all Covered Code to which Licensee contributes to
48  * contain a file documenting the changes Licensee made to create that Covered
49  * Code and the date of any change. Licensee must include in that file the
50  * documentation of any changes made by any predecessor Licensee. Licensee
51  * must include a prominent statement that the modification is derived,
52  * directly or indirectly, from Original Intel Code.
53  *
54  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
55  * Redistribution of source code of any substantial portion of the Covered
56  * Code or modification without rights to further distribute source must
57  * include the following Disclaimer and Export Compliance provision in the
58  * documentation and/or other materials provided with distribution. In
59  * addition, Licensee may not authorize further sublicense of source of any
60  * portion of the Covered Code, and must include terms to the effect that the
61  * license from Licensee to its licensee is limited to the intellectual
62  * property embodied in the software Licensee provides to its licensee, and
63  * not to intellectual property embodied in modifications its licensee may
64  * make.
65  *
66  * 3.3. Redistribution of Executable. Redistribution in executable form of any
67  * substantial portion of the Covered Code or modification must reproduce the
68  * above Copyright Notice, and the following Disclaimer and Export Compliance
69  * provision in the documentation and/or other materials provided with the
70  * distribution.
71  *
72  * 3.4. Intel retains all right, title, and interest in and to the Original
73  * Intel Code.
74  *
75  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
76  * Intel shall be used in advertising or otherwise to promote the sale, use or
77  * other dealings in products derived from or relating to the Covered Code
78  * without prior written authorization from Intel.
79  *
80  * 4. Disclaimer and Export Compliance
81  *
82  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
83  * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
84  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
85  * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
86  * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
87  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
88  * PARTICULAR PURPOSE.
89  *
90  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
91  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
92  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
93  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
94  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
95  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
96  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
97  * LIMITED REMEDY.
98  *
99  * 4.3. Licensee shall not export, either directly or indirectly, any of this
100  * software or system incorporating such software without first obtaining any
101  * required license or other approval from the U. S. Department of Commerce or
102  * any other agency or department of the United States Government. In the
103  * event Licensee exports any such software from the United States or
104  * re-exports any such software from a foreign destination, Licensee shall
105  * ensure that the distribution and export/re-export of the software is in
106  * compliance with all laws, regulations, orders, or other restrictions of the
107  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
108  * any of its subsidiaries will export/re-export any technical data, process,
109  * software, or service, directly or indirectly, to any country for which the
110  * United States government or any agency thereof requires an export license,
111  * other governmental approval, or letter of assurance, without first obtaining
112  * such license, approval or letter.
113  *
114  *****************************************************************************
115  *
116  * Alternatively, you may choose to be licensed under the terms of the
117  * following license:
118  *
119  * Redistribution and use in source and binary forms, with or without
120  * modification, are permitted provided that the following conditions
121  * are met:
122  * 1. Redistributions of source code must retain the above copyright
123  *    notice, this list of conditions, and the following disclaimer,
124  *    without modification.
125  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
126  *    substantially similar to the "NO WARRANTY" disclaimer below
127  *    ("Disclaimer") and any redistribution must be conditioned upon
128  *    including a substantially similar Disclaimer requirement for further
129  *    binary redistribution.
130  * 3. Neither the names of the above-listed copyright holders nor the names
131  *    of any contributors may be used to endorse or promote products derived
132  *    from this software without specific prior written permission.
133  *
134  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
135  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
136  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
137  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
138  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
139  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
140  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
141  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
142  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
143  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
144  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
145  *
146  * Alternatively, you may choose to be licensed under the terms of the
147  * GNU General Public License ("GPL") version 2 as published by the Free
148  * Software Foundation.
149  *
150  *****************************************************************************/
151 
152 #include <contrib/dev/acpica/compiler/aslcompiler.h>
153 #include "aslcompiler.y.h"
154 #include <contrib/dev/acpica/include/amlcode.h>
155 #include <contrib/dev/acpica/include/acapps.h>
156 #include <contrib/dev/acpica/include/acconvert.h>
157 
158 
159 /*******************************************************************************
160  *
161  * FUNCTION:    CvProcessComment
162  *
163  * PARAMETERS:  CurrentState      Current comment parse state
164  *              StringBuffer      Buffer containing the comment being processed
165  *              c1                Current input
166  *
167  * RETURN:      None
168  *
169  * DESCRIPTION: Process a single line comment of a c Style comment. This
170  *              function captures a line of a c style comment in a char* and
171  *              places the comment in the approperiate global buffer.
172  *
173  ******************************************************************************/
174 
175 void
176 CvProcessComment (
177     ASL_COMMENT_STATE       CurrentState,
178     char                    *StringBuffer,
179     int                     c1)
180 {
181     UINT64                  i;
182     char                    *LineToken;
183     char                    *FinalLineToken;
184     BOOLEAN                 CharStart;
185     char                    *CommentString;
186     char                    *FinalCommentString;
187 
188 
189     if (Gbl_CaptureComments && CurrentState.CaptureComments)
190     {
191         *StringBuffer = (char) c1;
192         ++StringBuffer;
193         *StringBuffer = 0;
194 
195         CvDbgPrint ("Multi-line comment\n");
196         CommentString = UtStringCacheCalloc (strlen (MsgBuffer) + 1);
197         strcpy (CommentString, MsgBuffer);
198 
199         CvDbgPrint ("CommentString: %s\n", CommentString);
200 
201         /*
202          * Determine whether if this comment spans multiple lines. If so,
203          * break apart the comment by storing each line in a different node
204          * within the comment list. This allows the disassembler to
205          * properly indent a multi-line comment.
206          */
207         LineToken = strtok (CommentString, "\n");
208 
209         if (LineToken)
210         {
211             FinalLineToken = UtStringCacheCalloc (strlen (LineToken) + 1);
212             strcpy (FinalLineToken, LineToken);
213 
214             /* Get rid of any carriage returns */
215 
216             if (FinalLineToken[strlen (FinalLineToken) - 1] == 0x0D)
217             {
218                 FinalLineToken[strlen(FinalLineToken)-1] = 0;
219             }
220 
221             CvAddToCommentList (FinalLineToken);
222             LineToken = strtok (NULL, "\n");
223             while (LineToken != NULL)
224             {
225                 /*
226                  * It is assumed that each line has some sort of indentation.
227                  * This means that we need to find the first character that
228                  * is not a white space within each line.
229                  */
230                 CharStart = FALSE;
231                 for (i = 0; (i < (strlen (LineToken) + 1)) && !CharStart; i++)
232                 {
233                     if (LineToken[i] != ' ' && LineToken[i] != '\t')
234                     {
235                         CharStart = TRUE;
236                         LineToken += i-1;
237                         LineToken [0] = ' '; /* Pad for Formatting */
238                     }
239                 }
240 
241                 FinalLineToken = UtStringCacheCalloc (strlen (LineToken) + 1);
242                 strcat (FinalLineToken, LineToken);
243 
244                 /* Get rid of any carriage returns */
245 
246                 if (FinalLineToken[strlen (FinalLineToken) - 1] == 0x0D)
247                 {
248                     FinalLineToken[strlen(FinalLineToken) - 1] = 0;
249                 }
250 
251                 CvAddToCommentList (FinalLineToken);
252                 LineToken = strtok (NULL,"\n");
253             }
254         }
255 
256         /*
257          * If this only spans a single line, check to see whether if this
258          * comment appears on the same line as a line of code. If does,
259          * retain it's position for stylistic reasons. If it doesn't,
260          * add it to the comment list so that it can be associated with
261          * the next node that's created.
262          */
263         else
264         {
265            /*
266             * If this is not a regular comment, pad with extra spaces that
267             * appeared in the original source input to retain the original
268             * spacing.
269             */
270             FinalCommentString =
271                 UtStringCacheCalloc (strlen (CommentString) +
272                 CurrentState.SpacesBefore + 1);
273 
274             for (i = 0; (CurrentState.CommentType != ASL_COMMENT_STANDARD) &&
275                 (i < CurrentState.SpacesBefore); i++)
276             {
277                  FinalCommentString[i] = ' ';
278             }
279 
280             strcat (FinalCommentString, CommentString);
281             CvPlaceComment (CurrentState.CommentType, FinalCommentString);
282         }
283     }
284 }
285 
286 
287 /*******************************************************************************
288  *
289  * FUNCTION:    CvProcessCommentType2
290  *
291  * PARAMETERS:  CurrentState      Current comment parse state
292  *              StringBuffer      Buffer containing the comment being processed
293  *
294  * RETURN:      none
295  *
296  * DESCRIPTION: Process a single line comment. This function captures a comment
297  *              in a char* and places the comment in the approperiate global
298  *              buffer through CvPlaceComment
299  *
300  ******************************************************************************/
301 
302 void
303 CvProcessCommentType2 (
304     ASL_COMMENT_STATE       CurrentState,
305     char                    *StringBuffer)
306 {
307     UINT32                  i;
308     char                    *CommentString;
309     char                    *FinalCommentString;
310 
311 
312     if (Gbl_CaptureComments && CurrentState.CaptureComments)
313     {
314         *StringBuffer = 0; /* null terminate */
315         CvDbgPrint ("Single-line comment\n");
316         CommentString = UtStringCacheCalloc (strlen (MsgBuffer) + 1);
317         strcpy (CommentString, MsgBuffer);
318 
319         /* If this comment lies on the same line as the latest parse op,
320          * assign it to that op's CommentAfter field. Saving in this field
321          * will allow us to support comments that come after code on the
322          * same line as the code itself. For example,
323          * Name(A,"") //comment
324          *
325          * will be retained rather than transformed into
326          *
327          * Name(A,"")
328          * //comment
329          *
330          * For this case, we only need to add one comment since
331          *
332          * Name(A,"") //comment1 //comment2 ... more comments here.
333          *
334          * would be lexically analyzed as a single comment.
335          *
336          * Create a new string with the approperiate spaces. Since we need
337          * to account for the proper spacing, the actual comment,
338          * extra 2 spaces so that this comment can be converted to the "/ *"
339          * style and the null terminator, the string would look something
340          * like:
341          *
342          * [ (spaces) (comment)  ( * /) ('\0') ]
343          *
344          */
345         FinalCommentString = UtStringCacheCalloc (CurrentState.SpacesBefore +
346             strlen (CommentString) + 3 + 1);
347 
348         for (i = 0; (CurrentState.CommentType != 1) &&
349             (i < CurrentState.SpacesBefore); i++)
350         {
351             FinalCommentString[i] = ' ';
352         }
353 
354         strcat (FinalCommentString, CommentString);
355 
356         /* convert to a "/ *" style comment  */
357 
358         strcat (FinalCommentString, " */");
359         FinalCommentString [CurrentState.SpacesBefore +
360             strlen (CommentString) + 3] = 0;
361 
362         /* get rid of the carriage return */
363 
364         if (FinalCommentString[strlen (FinalCommentString) - 1] == 0x0D)
365         {
366             FinalCommentString[strlen(FinalCommentString) - 1] = 0;
367         }
368 
369         CvPlaceComment (CurrentState.CommentType, FinalCommentString);
370     }
371 }
372 
373 
374 /*******************************************************************************
375  *
376  * FUNCTION:    CgCalculateCommentLengths
377  *
378  * PARAMETERS:  Op                 - Calculate all comments of this Op
379  *
380  * RETURN:      TotalCommentLength - Length of all comments within this op.
381  *
382  * DESCRIPTION: Calculate the length that the each comment takes up within Op.
383  *              Comments look like the follwoing: [0xA9 OptionBtye comment 0x00]
384  *              therefore, we add 1 + 1 + strlen (comment) + 1 to get the actual
385  *              length of this comment.
386  *
387  ******************************************************************************/
388 
389 UINT32
390 CvCalculateCommentLengths(
391    ACPI_PARSE_OBJECT        *Op)
392 {
393     UINT32                  CommentLength = 0;
394     UINT32                  TotalCommentLength = 0;
395     ACPI_COMMENT_NODE       *Current = NULL;
396 
397 
398     if (!Gbl_CaptureComments)
399     {
400         return (0);
401     }
402 
403     CvDbgPrint ("==Calculating comment lengths for %s\n",
404         Op->Asl.ParseOpName);
405 
406     if (Op->Asl.FileChanged)
407     {
408         TotalCommentLength += strlen (Op->Asl.Filename) + 3;
409 
410         if (Op->Asl.ParentFilename &&
411             AcpiUtStricmp (Op->Asl.Filename, Op->Asl.ParentFilename))
412         {
413             TotalCommentLength += strlen (Op->Asl.ParentFilename) + 3;
414         }
415     }
416 
417     if (Op->Asl.CommentList)
418     {
419         Current = Op->Asl.CommentList;
420         while (Current)
421         {
422             CommentLength = strlen (Current->Comment)+3;
423             CvDbgPrint ("Length of standard comment: %d\n", CommentLength);
424             CvDbgPrint ("    Comment string: %s\n\n", Current->Comment);
425             TotalCommentLength += CommentLength;
426             Current = Current->Next;
427         }
428     }
429 
430     if (Op->Asl.EndBlkComment)
431     {
432         Current = Op->Asl.EndBlkComment;
433         while (Current)
434         {
435             CommentLength = strlen (Current->Comment)+3;
436             CvDbgPrint ("Length of endblkcomment: %d\n", CommentLength);
437             CvDbgPrint ("    Comment string: %s\n\n", Current->Comment);
438             TotalCommentLength += CommentLength;
439             Current = Current->Next;
440         }
441     }
442 
443     if (Op->Asl.InlineComment)
444     {
445         CommentLength = strlen (Op->Asl.InlineComment)+3;
446         CvDbgPrint ("Length of inline comment: %d\n", CommentLength);
447         CvDbgPrint ("    Comment string: %s\n\n", Op->Asl.InlineComment);
448         TotalCommentLength += CommentLength;
449     }
450 
451     if (Op->Asl.EndNodeComment)
452     {
453         CommentLength = strlen(Op->Asl.EndNodeComment)+3;
454         CvDbgPrint ("Length of end node comment +3: %d\n", CommentLength);
455         CvDbgPrint ("    Comment string: %s\n\n", Op->Asl.EndNodeComment);
456         TotalCommentLength += CommentLength;
457     }
458 
459     if (Op->Asl.CloseBraceComment)
460     {
461         CommentLength = strlen (Op->Asl.CloseBraceComment)+3;
462         CvDbgPrint ("Length of close brace comment: %d\n", CommentLength);
463         CvDbgPrint ("    Comment string: %s\n\n", Op->Asl.CloseBraceComment);
464         TotalCommentLength += CommentLength;
465     }
466 
467     CvDbgPrint("\n\n");
468     return (TotalCommentLength);
469 }
470 
471 
472 /*******************************************************************************
473  *
474  * FUNCTION:    CgWriteAmlDefBlockComment
475  *
476  * PARAMETERS:  Op              - Current parse op
477  *
478  * RETURN:      None
479  *
480  * DESCRIPTION: Write all comments for a particular definition block.
481  *              For definition blocks, the comments need to come after the
482  *              definition block header. The regular comments above the
483  *              definition block would be categorized as
484  *              STD_DEFBLK_COMMENT and comments after the closing brace
485  *              is categorized as END_DEFBLK_COMMENT.
486  *
487  ******************************************************************************/
488 
489 void
490 CgWriteAmlDefBlockComment(
491     ACPI_PARSE_OBJECT       *Op)
492 {
493     UINT8                   CommentOption;
494     ACPI_COMMENT_NODE       *Current;
495     char                    *NewFilename;
496     char                    *Position;
497     char                    *DirectoryPosition;
498 
499 
500     if (!Gbl_CaptureComments ||
501         (Op->Asl.ParseOpcode != PARSEOP_DEFINITION_BLOCK))
502     {
503         return;
504     }
505 
506     CvDbgPrint ("Printing comments for a definition block..\n");
507 
508     /* First, print the file name comment after changing .asl to .dsl */
509 
510     NewFilename = UtStringCacheCalloc (strlen (Op->Asl.Filename));
511     strcpy (NewFilename, Op->Asl.Filename);
512     DirectoryPosition = strrchr (NewFilename, '/');
513     Position = strrchr (NewFilename, '.');
514 
515     if (Position && (Position > DirectoryPosition))
516     {
517         /* Tack on the new suffix */
518 
519         Position++;
520         *Position = 0;
521         strcat (Position, FILE_SUFFIX_DISASSEMBLY);
522     }
523     else
524     {
525         /* No dot, add one and then the suffix */
526 
527         strcat (NewFilename, ".");
528         strcat (NewFilename, FILE_SUFFIX_DISASSEMBLY);
529     }
530 
531     CommentOption = FILENAME_COMMENT;
532     CgWriteOneAmlComment(Op, NewFilename, CommentOption);
533 
534     Current = Op->Asl.CommentList;
535     CommentOption = STD_DEFBLK_COMMENT;
536 
537     while (Current)
538     {
539         CgWriteOneAmlComment(Op, Current->Comment, CommentOption);
540         CvDbgPrint ("Printing comment: %s\n", Current->Comment);
541         Current = Current->Next;
542     }
543 
544     Op->Asl.CommentList = NULL;
545 
546     /* Print any Inline comments associated with this node */
547 
548     if (Op->Asl.CloseBraceComment)
549     {
550         CommentOption = END_DEFBLK_COMMENT;
551         CgWriteOneAmlComment(Op, Op->Asl.CloseBraceComment, CommentOption);
552         Op->Asl.CloseBraceComment = NULL;
553     }
554 }
555 
556 
557 /*******************************************************************************
558  *
559  * FUNCTION:    CgWriteOneAmlComment
560  *
561  * PARAMETERS:  Op              - Current parse op
562  *              CommentToPrint  - Comment that's printed
563  *              InputOption     - Denotes the comment option.
564  *
565  * RETURN:      None
566  *
567  * DESCRIPTION: write a single comment.
568  *
569  ******************************************************************************/
570 
571 void
572 CgWriteOneAmlComment(
573     ACPI_PARSE_OBJECT       *Op,
574     char*                   CommentToPrint,
575     UINT8                   InputOption)
576 {
577     UINT8                   CommentOption = InputOption;
578     UINT8                   CommentOpcode = (UINT8) AML_COMMENT_OP;
579 
580 
581     if (!CommentToPrint)
582     {
583         return;
584     }
585 
586     CgLocalWriteAmlData (Op, &CommentOpcode, 1);
587     CgLocalWriteAmlData (Op, &CommentOption, 1);
588 
589     /* The strlen (..) + 1 is to include the null terminator */
590 
591     CgLocalWriteAmlData (Op, CommentToPrint, strlen (CommentToPrint) + 1);
592 }
593 
594 
595 /*******************************************************************************
596  *
597  * FUNCTION:    CgWriteAmlComment
598  *
599  * PARAMETERS:  Op              - Current parse op
600  *
601  * RETURN:      None
602  *
603  * DESCRIPTION: Write all comments pertaining to the current parse op
604  *
605  ******************************************************************************/
606 
607 void
608 CgWriteAmlComment(
609     ACPI_PARSE_OBJECT       *Op)
610 {
611     ACPI_COMMENT_NODE       *Current;
612     UINT8                   CommentOption;
613     char                    *NewFilename;
614     char                    *ParentFilename;
615 
616 
617     if ((Op->Asl.ParseOpcode == PARSEOP_DEFINITION_BLOCK) ||
618          !Gbl_CaptureComments)
619     {
620         return;
621     }
622 
623     /* Print out the filename comment if needed */
624 
625     if (Op->Asl.FileChanged)
626     {
627 
628         /* First, print the file name comment after changing .asl to .dsl */
629 
630         NewFilename =
631             FlGenerateFilename (Op->Asl.Filename, FILE_SUFFIX_DISASSEMBLY);
632         if (NewFilename)
633         {
634             CvDbgPrint ("Writing file comment, \"%s\" for %s\n",
635                 NewFilename, Op->Asl.ParseOpName);
636         }
637 
638         CgWriteOneAmlComment(Op, NewFilename, FILENAME_COMMENT);
639 
640         if (Op->Asl.ParentFilename &&
641             AcpiUtStricmp (Op->Asl.ParentFilename, Op->Asl.Filename))
642         {
643             ParentFilename = FlGenerateFilename (Op->Asl.ParentFilename,
644                 FILE_SUFFIX_DISASSEMBLY);
645             CgWriteOneAmlComment(Op, ParentFilename, PARENTFILENAME_COMMENT);
646         }
647 
648         /* Prevent multiple writes of the same comment */
649 
650         Op->Asl.FileChanged = FALSE;
651     }
652 
653     /*
654      * Regular comments are stored in a list of comments within an Op.
655      * If there is a such list in this node, print out the comment
656      * as byte code.
657      */
658     Current = Op->Asl.CommentList;
659     if (Op->Asl.ParseOpcode == PARSEOP_INCLUDE)
660     {
661         CommentOption = INCLUDE_COMMENT;
662     }
663     else
664     {
665         CommentOption = STANDARD_COMMENT;
666     }
667 
668     while (Current)
669     {
670         CgWriteOneAmlComment(Op, Current->Comment, CommentOption);
671         Current = Current->Next;
672     }
673 
674     Op->Asl.CommentList = NULL;
675 
676     Current = Op->Asl.EndBlkComment;
677     CommentOption = ENDBLK_COMMENT;
678     while (Current)
679     {
680         CgWriteOneAmlComment(Op, Current->Comment, CommentOption);
681         Current = Current->Next;
682     }
683 
684     Op->Asl.EndBlkComment = NULL;
685 
686     /* Print any Inline comments associated with this node */
687 
688     if (Op->Asl.InlineComment)
689     {
690         CommentOption = INLINE_COMMENT;
691         CgWriteOneAmlComment(Op, Op->Asl.InlineComment, CommentOption);
692         Op->Asl.InlineComment = NULL;
693     }
694 
695     if (Op->Asl.EndNodeComment)
696     {
697         CommentOption = ENDNODE_COMMENT;
698         CgWriteOneAmlComment(Op, Op->Asl.EndNodeComment, CommentOption);
699         Op->Asl.EndNodeComment = NULL;
700     }
701 
702     if (Op->Asl.CloseBraceComment)
703     {
704         CommentOption = CLOSE_BRACE_COMMENT;
705         CgWriteOneAmlComment(Op, Op->Asl.CloseBraceComment, CommentOption);
706         Op->Asl.CloseBraceComment = NULL;
707     }
708 }
709 
710 
711 /*******************************************************************************
712  *
713  * FUNCTION:    CvCommentNodeCalloc
714  *
715  * PARAMETERS:  None
716  *
717  * RETURN:      Pointer to the comment node. Aborts on allocation failure
718  *
719  * DESCRIPTION: Allocate a string node buffer.
720  *
721  ******************************************************************************/
722 
723 ACPI_COMMENT_NODE *
724 CvCommentNodeCalloc (
725     void)
726 {
727    ACPI_COMMENT_NODE        *NewCommentNode;
728 
729 
730    NewCommentNode = UtLocalCalloc (sizeof (ACPI_COMMENT_NODE));
731    NewCommentNode->Next = NULL;
732    return (NewCommentNode);
733 }
734 
735 
736 /*******************************************************************************
737  *
738  * FUNCTION:    CvParseOpBlockType
739  *
740  * PARAMETERS:  Op              - Object to be examined
741  *
742  * RETURN:      BlockType - not a block, parens, braces, or even both.
743  *
744  * DESCRIPTION: Type of block for this ASL parseop (parens or braces)
745  *              keep this in sync with aslprimaries.y, aslresources.y and
746  *              aslrules.y
747  *
748  ******************************************************************************/
749 
750 UINT32
751 CvParseOpBlockType (
752     ACPI_PARSE_OBJECT       *Op)
753 {
754 
755     if (!Op)
756     {
757         return (BLOCK_NONE);
758     }
759 
760     switch (Op->Asl.ParseOpcode)
761     {
762     /* From aslprimaries.y */
763 
764     case PARSEOP_VAR_PACKAGE:
765     case PARSEOP_BANKFIELD:
766     case PARSEOP_BUFFER:
767     case PARSEOP_CASE:
768     case PARSEOP_DEVICE:
769     case PARSEOP_FIELD:
770     case PARSEOP_FOR:
771     case PARSEOP_FUNCTION:
772     case PARSEOP_IF:
773     case PARSEOP_ELSEIF:
774     case PARSEOP_INDEXFIELD:
775     case PARSEOP_METHOD:
776     case PARSEOP_POWERRESOURCE:
777     case PARSEOP_PROCESSOR:
778     case PARSEOP_DATABUFFER:
779     case PARSEOP_SCOPE:
780     case PARSEOP_SWITCH:
781     case PARSEOP_THERMALZONE:
782     case PARSEOP_WHILE:
783 
784     /* From aslresources.y */
785 
786     case PARSEOP_RESOURCETEMPLATE: /* optional parens */
787     case PARSEOP_VENDORLONG:
788     case PARSEOP_VENDORSHORT:
789     case PARSEOP_INTERRUPT:
790     case PARSEOP_IRQNOFLAGS:
791     case PARSEOP_IRQ:
792     case PARSEOP_GPIO_INT:
793     case PARSEOP_GPIO_IO:
794     case PARSEOP_DMA:
795 
796     /* From aslrules.y */
797 
798     case PARSEOP_DEFINITION_BLOCK:
799         return (BLOCK_PAREN | BLOCK_BRACE);
800 
801     default:
802         return (BLOCK_NONE);
803     }
804 }
805 
806 
807 /*******************************************************************************
808  *
809  * FUNCTION:    CvProcessCommentState
810  *
811  * PARAMETERS:  Input           - Input character
812  *
813  * RETURN:      None
814  *
815  * DESCRIPTION: Take the given input. If this character is
816  *              defined as a comment table entry, then update the state
817  *              accordingly.
818  *
819  ******************************************************************************/
820 
821 void
822 CvProcessCommentState (
823     char                    Input)
824 {
825 
826     if (Input != ' ')
827     {
828         Gbl_CommentState.SpacesBefore = 0;
829     }
830 
831     switch (Input)
832     {
833     case '\n':
834 
835         Gbl_CommentState.CommentType = ASL_COMMENT_STANDARD;
836         break;
837 
838     case ' ':
839 
840         /* Keep the CommentType the same */
841 
842         Gbl_CommentState.SpacesBefore++;
843         break;
844 
845     case '(':
846 
847         Gbl_CommentState.CommentType = ASL_COMMENT_OPEN_PAREN;
848         break;
849 
850     case ')':
851 
852         Gbl_CommentState.CommentType = ASL_COMMENT_CLOSE_PAREN;
853         break;
854 
855     case '{':
856 
857         Gbl_CommentState.CommentType = ASL_COMMENT_STANDARD;
858         Gbl_CommentState.ParsingParenBraceNode = NULL;
859         CvDbgPrint ("End Parsing paren/Brace node!\n");
860         break;
861 
862     case '}':
863 
864         Gbl_CommentState.CommentType = ASL_COMMENT_CLOSE_BRACE;
865         break;
866 
867     case ',':
868 
869         Gbl_CommentState.CommentType = ASLCOMMENT_INLINE;
870         break;
871 
872     default:
873 
874         Gbl_CommentState.CommentType = ASLCOMMENT_INLINE;
875         break;
876     }
877 }
878 
879 
880 /*******************************************************************************
881  *
882  * FUNCTION:    CvAddToCommentList
883  *
884  * PARAMETERS:  ToAdd              - Contains the comment to be inserted
885  *
886  * RETURN:      None
887  *
888  * DESCRIPTION: Add the given char* to a list of comments in the global list
889  *              of comments.
890  *
891  ******************************************************************************/
892 
893 void
894 CvAddToCommentList (
895     char                    *ToAdd)
896 {
897 
898    if (Gbl_CommentListHead)
899    {
900        Gbl_CommentListTail->Next = CvCommentNodeCalloc ();
901        Gbl_CommentListTail = Gbl_CommentListTail->Next;
902    }
903    else
904    {
905        Gbl_CommentListHead = CvCommentNodeCalloc ();
906        Gbl_CommentListTail = Gbl_CommentListHead;
907    }
908 
909    Gbl_CommentListTail->Comment = ToAdd;
910 }
911 
912 
913 /*******************************************************************************
914  *
915  * FUNCTION:    CvAppendInlineComment
916  *
917  * PARAMETERS:  InlineComment      - Append to the end of this string.
918  *              toAdd              - Contains the comment to be inserted
919  *
920  * RETURN:      Str                - toAdd appended to InlineComment
921  *
922  * DESCRIPTION: Concatenate ToAdd to InlineComment
923  *
924  ******************************************************************************/
925 
926 char *
927 CvAppendInlineComment (
928     char                    *InlineComment,
929     char                    *ToAdd)
930 {
931     char*                   Str;
932     UINT32                  Size = 0;
933 
934 
935     if (!InlineComment)
936     {
937         return (ToAdd);
938     }
939 
940     if (!ToAdd)
941     {
942         return (InlineComment);
943     }
944 
945     Size = strlen (ToAdd);
946     Size += strlen (InlineComment);
947     Str = UtStringCacheCalloc (Size + 1);
948 
949     strcpy (Str, InlineComment);
950     strcat (Str, ToAdd);
951     Str[Size +1] = 0;
952     return (Str);
953 }
954 
955 
956 /*******************************************************************************
957  *
958  * FUNCTION:    CvPlaceComment
959  *
960  * PARAMETERS:  UINT8               - Type
961  *              char *              - CommentString
962  *
963  * RETURN:      None
964  *
965  * DESCRIPTION: Given type and CommentString, this function places the
966  *              CommentString in the approperiate global comment list or char*
967  *
968  ******************************************************************************/
969 
970 void
971 CvPlaceComment(
972     UINT8                   Type,
973     char                    *CommentString)
974 {
975     ACPI_PARSE_OBJECT       *LatestParseNode;
976     ACPI_PARSE_OBJECT       *ParenBraceNode;
977 
978 
979     LatestParseNode = Gbl_CommentState.LatestParseOp;
980     ParenBraceNode  = Gbl_CommentState.ParsingParenBraceNode;
981     CvDbgPrint ("Placing comment %s for type %d\n", CommentString, Type);
982 
983     switch (Type)
984     {
985     case ASL_COMMENT_STANDARD:
986 
987         CvAddToCommentList (CommentString);
988         break;
989 
990     case ASLCOMMENT_INLINE:
991 
992         LatestParseNode->Asl.InlineComment =
993             CvAppendInlineComment (LatestParseNode->Asl.InlineComment,
994             CommentString);
995         break;
996 
997     case ASL_COMMENT_OPEN_PAREN:
998 
999         Gbl_InlineCommentBuffer =
1000             CvAppendInlineComment(Gbl_InlineCommentBuffer,
1001             CommentString);
1002         break;
1003 
1004     case ASL_COMMENT_CLOSE_PAREN:
1005 
1006         if (ParenBraceNode)
1007         {
1008             ParenBraceNode->Asl.EndNodeComment =
1009                 CvAppendInlineComment (ParenBraceNode->Asl.EndNodeComment,
1010                 CommentString);
1011         }
1012         else
1013         {
1014             LatestParseNode->Asl.EndNodeComment =
1015                 CvAppendInlineComment (LatestParseNode->Asl.EndNodeComment,
1016                 CommentString);
1017         }
1018         break;
1019 
1020     case ASL_COMMENT_CLOSE_BRACE:
1021 
1022         LatestParseNode->Asl.CloseBraceComment = CommentString;
1023         break;
1024 
1025     default:
1026 
1027         break;
1028     }
1029 }
1030