xref: /netbsd-src/sys/external/bsd/acpica/dist/compiler/cvcompiler.c (revision 7c192b2a5e1093666e67801684f930ef49b3b363)
1 /******************************************************************************
2  *
3  * Module Name: cvcompiler - ASL-/ASL+ converter functions
4  *
5  *****************************************************************************/
6 
7 /*
8  * Copyright (C) 2000 - 2017, 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 "amlcode.h"
47 #include "acapps.h"
48 #include "acconvert.h"
49 
50 
51 /*******************************************************************************
52  *
53  * FUNCTION:    CvProcessComment
54  *
55  * PARAMETERS:  CurrentState      Current comment parse state
56  *              StringBuffer      Buffer containing the comment being processed
57  *              c1                Current input
58  *
59  * RETURN:      none
60  *
61  * DESCRIPTION: Process a single line comment of a c Style comment. This
62  *              function captures a line of a c style comment in a char* and
63  *              places the comment in the approperiate global buffer.
64  *
65  ******************************************************************************/
66 
67 void
68 CvProcessComment (
69     ASL_COMMENT_STATE       CurrentState,
70     char                    *StringBuffer,
71     int                     c1)
72 {
73     UINT64                  i;
74     char                    *LineToken;
75     char                    *FinalLineToken;
76     BOOLEAN                 CharStart;
77     char                    *CommentString;
78     char                    *FinalCommentString;
79 
80 
81     if (Gbl_CaptureComments && CurrentState.CaptureComments)
82     {
83         *StringBuffer = (char) c1;
84         ++StringBuffer;
85         *StringBuffer = 0;
86         CvDbgPrint ("Multi-line comment\n");
87         CommentString = UtStringCacheCalloc (strlen (MsgBuffer) + 1);
88         strcpy (CommentString, MsgBuffer);
89 
90         CvDbgPrint ("CommentString: %s\n", CommentString);
91 
92         /*
93          * Determine whether if this comment spans multiple lines.
94          * If so, break apart the comment by line so that it can be
95          * properly indented.
96          */
97         if (strchr (CommentString, '\n') != NULL)
98         {
99             /*
100              * Get the first token. The for loop pads subsequent lines
101              * for comments similar to the style of this comment.
102              */
103             LineToken = strtok (CommentString, "\n");
104             FinalLineToken = UtStringCacheCalloc (strlen (LineToken) + 1);
105             strcpy (FinalLineToken, LineToken);
106 
107             /* Get rid of any carriage returns */
108 
109             if (FinalLineToken[strlen (FinalLineToken) - 1] == 0x0D)
110             {
111                 FinalLineToken[strlen(FinalLineToken)-1] = 0;
112             }
113             CvAddToCommentList (FinalLineToken);
114             LineToken = strtok (NULL, "\n");
115             while (LineToken != NULL)
116             {
117                 /*
118                  * It is assumed that each line has some sort of indentation.
119                  * This means that we need to find the first character that is not
120                  * a white space within each line.
121                  */
122                 CharStart = FALSE;
123                 for (i = 0; (i < (strlen (LineToken) + 1)) && !CharStart; i++)
124                 {
125                     if (LineToken[i] != ' ' && LineToken[i] != '\t')
126                     {
127                         CharStart = TRUE;
128                         LineToken += i-1;
129                         LineToken [0] = ' '; /* Pad for Formatting */
130                     }
131                 }
132                 FinalLineToken = UtStringCacheCalloc (strlen (LineToken) + 1);
133                 strcat (FinalLineToken, LineToken);
134 
135                 /* Get rid of any carriage returns */
136 
137                 if (FinalLineToken[strlen (FinalLineToken) - 1] == 0x0D)
138                 {
139                     FinalLineToken[strlen(FinalLineToken) - 1] = 0;
140                 }
141                 CvAddToCommentList (FinalLineToken);
142                 LineToken = strtok (NULL,"\n");
143             }
144         }
145 
146         /*
147          * If this only spans a single line, check to see whether if this comment
148          * appears on the same line as a line of code. If does, retain it's
149          * position for stylistic reasons. If it doesn't, add it to the comment
150          * List so that it can be associated with the next node that's created.
151          */
152         else
153         {
154            /*
155             * if this is not a regular comment, pad with extra spaces that appeared
156             * in the original source input to retain the original spacing.
157             */
158             FinalCommentString = UtStringCacheCalloc (strlen (CommentString) + CurrentState.SpacesBefore + 1);
159             for (i=0; (CurrentState.CommentType != ASL_COMMENT_STANDARD) &&
160                 (i < CurrentState.SpacesBefore); ++i)
161             {
162                  FinalCommentString[i] = ' ';
163             }
164             strcat (FinalCommentString, CommentString);
165             CvPlaceComment (CurrentState.CommentType, FinalCommentString);
166         }
167     }
168 }
169 
170 
171 /*******************************************************************************
172  *
173  * FUNCTION:    CvProcessCommentType2
174  *
175  * PARAMETERS:  CurrentState      Current comment parse state
176  *              StringBuffer      Buffer containing the comment being processed
177  *
178  * RETURN:      none
179  *
180  * DESCRIPTION: Process a single line comment. This function captures a comment
181  *              in a char* and places the comment in the approperiate global
182  *              buffer through CvPlaceComment
183  *
184  ******************************************************************************/
185 
186 void
187 CvProcessCommentType2 (
188     ASL_COMMENT_STATE       CurrentState,
189     char                    *StringBuffer)
190 {
191     UINT32                  i;
192     char                    *CommentString;
193     char                    *FinalCommentString;
194 
195 
196     if (Gbl_CaptureComments && CurrentState.CaptureComments)
197     {
198         *StringBuffer = 0; /* null terminate */
199         CvDbgPrint ("Single-line comment\n");
200         CommentString = UtStringCacheCalloc (strlen (MsgBuffer) + 1);
201         strcpy (CommentString, MsgBuffer);
202 
203         /* If this comment lies on the same line as the latest parse node,
204          * assign it to that node's CommentAfter field. Saving in this field
205          * will allow us to support comments that come after code on the same
206          * line as the code itself. For example,
207          * Name(A,"") //comment
208          *
209          * will be retained rather than transformed into
210          *
211          * Name(A,"")
212          * //comment
213          *
214          * For this case, we only need to add one comment since
215          *
216          * Name(A,"") //comment1 //comment2 ... more comments here.
217          *
218          * would be lexically analyzed as a single comment.
219          *
220          * Create a new string with the approperiate spaces. Since we need
221          * to account for the proper spacing, the actual comment,
222          * extra 2 spaces so that this comment can be converted to the "/ *"
223          * style and the null terminator, the string would look something like
224          *
225          * [ (spaces) (comment)  ( * /) ('\0') ]
226          *
227          */
228         FinalCommentString = UtStringCacheCalloc (CurrentState.SpacesBefore + strlen (CommentString) + 3 + 1);
229         for (i=0; (CurrentState.CommentType!=1) && (i<CurrentState.SpacesBefore); ++i)
230         {
231             FinalCommentString[i] = ' ';
232         }
233         strcat (FinalCommentString, CommentString);
234 
235         /* convert to a "/ *" style comment  */
236 
237         strcat (FinalCommentString, " */");
238         FinalCommentString [CurrentState.SpacesBefore + strlen (CommentString) + 3] = 0;
239 
240         /* get rid of the carriage return */
241 
242         if (FinalCommentString[strlen (FinalCommentString) - 1] == 0x0D)
243         {
244             FinalCommentString[strlen(FinalCommentString)-1] = 0;
245         }
246         CvPlaceComment (CurrentState.CommentType, FinalCommentString);
247     }
248 }
249 
250 
251 /*******************************************************************************
252  *
253  * FUNCTION:    CgCalculateCommentLengths
254  *
255  * PARAMETERS:  Op                 - Calculate all comments of this Op
256  *
257  * RETURN:      TotalCommentLength - Length of all comments within this node.
258  *
259  * DESCRIPTION: calculate the length that the each comment takes up within Op.
260  *              Comments look like the follwoing: [0xA9 OptionBtye comment 0x00]
261  *              therefore, we add 1 + 1 + strlen (comment) + 1 to get the actual
262  *              length of this comment.
263  *
264  ******************************************************************************/
265 
266 UINT32
267 CvCalculateCommentLengths(
268    ACPI_PARSE_OBJECT        *Op)
269 {
270     UINT32                  CommentLength = 0;
271     UINT32                  TotalCommentLength = 0;
272     ACPI_COMMENT_NODE       *Current = NULL;
273 
274 
275     if (!Gbl_CaptureComments)
276     {
277         return (0);
278     }
279 
280     CvDbgPrint ("==Calculating comment lengths for %s\n",  Op->Asl.ParseOpName);
281     if (Op->Asl.FileChanged)
282     {
283         TotalCommentLength += strlen (Op->Asl.Filename) + 3;
284 
285         if (Op->Asl.ParentFilename &&
286             AcpiUtStricmp (Op->Asl.Filename, Op->Asl.ParentFilename))
287         {
288             TotalCommentLength += strlen (Op->Asl.ParentFilename) + 3;
289         }
290     }
291     if (Op->Asl.CommentList)
292     {
293         Current = Op->Asl.CommentList;
294         while (Current)
295         {
296             CommentLength = strlen (Current->Comment)+3;
297             CvDbgPrint ("Length of standard comment: %d\n", CommentLength);
298             CvDbgPrint ("    Comment string: %s\n\n", Current->Comment);
299             TotalCommentLength += CommentLength;
300             Current = Current->Next;
301         }
302     }
303     if (Op->Asl.EndBlkComment)
304     {
305         Current = Op->Asl.EndBlkComment;
306         while (Current)
307         {
308             CommentLength = strlen (Current->Comment)+3;
309             CvDbgPrint ("Length of endblkcomment: %d\n", CommentLength);
310             CvDbgPrint ("    Comment string: %s\n\n", Current->Comment);
311             TotalCommentLength += CommentLength;
312             Current = Current->Next;
313         }
314     }
315     if (Op->Asl.InlineComment)
316     {
317         CommentLength = strlen (Op->Asl.InlineComment)+3;
318         CvDbgPrint ("Length of inline comment: %d\n", CommentLength);
319         CvDbgPrint ("    Comment string: %s\n\n", Op->Asl.InlineComment);
320         TotalCommentLength += CommentLength;
321     }
322     if (Op->Asl.EndNodeComment)
323     {
324         CommentLength = strlen(Op->Asl.EndNodeComment)+3;
325         CvDbgPrint ("Length of end node comment +3: %d\n", CommentLength);
326         CvDbgPrint ("    Comment string: %s\n\n", Op->Asl.EndNodeComment);
327         TotalCommentLength += CommentLength;
328     }
329 
330     if (Op->Asl.CloseBraceComment)
331     {
332         CommentLength = strlen (Op->Asl.CloseBraceComment)+3;
333         CvDbgPrint ("Length of close brace comment: %d\n", CommentLength);
334         CvDbgPrint ("    Comment string: %s\n\n", Op->Asl.CloseBraceComment);
335         TotalCommentLength += CommentLength;
336     }
337 
338     CvDbgPrint("\n\n");
339 
340     return TotalCommentLength;
341 
342 }
343 
344 
345 /*******************************************************************************
346  *
347  * FUNCTION:    CgWriteAmlDefBlockComment
348  *
349  * PARAMETERS:  Op              - Current parse op
350  *
351  * RETURN:      None
352  *
353  * DESCRIPTION: Write all comments for a particular definition block.
354  *              For definition blocks, the comments need to come after the
355  *              definition block header. The regular comments above the
356  *              definition block would be categorized as
357  *              STD_DEFBLK_COMMENT and comments after the closing brace
358  *              is categorized as END_DEFBLK_COMMENT.
359  *
360  ******************************************************************************/
361 
362 void
363 CgWriteAmlDefBlockComment(
364     ACPI_PARSE_OBJECT       *Op)
365 {
366     UINT8                   CommentOption;
367     ACPI_COMMENT_NODE       *Current;
368     char                    *NewFilename;
369     char                    *Position;
370     char                    *DirectoryPosition;
371 
372 
373     if (!Gbl_CaptureComments ||
374         (Op->Asl.ParseOpcode != PARSEOP_DEFINITION_BLOCK))
375     {
376         return;
377     }
378 
379     CvDbgPrint ("Printing comments for a definition block..\n");
380 
381     /* first, print the file name comment after changing .asl to .dsl */
382 
383     NewFilename = UtStringCacheCalloc (strlen (Op->Asl.Filename));
384     strcpy (NewFilename, Op->Asl.Filename);
385     DirectoryPosition = strrchr (NewFilename, '/');
386     Position = strrchr (NewFilename, '.');
387 
388     if (Position && (Position > DirectoryPosition))
389     {
390         /* Tack on the new suffix */
391 
392         Position++;
393         *Position = 0;
394         strcat (Position, FILE_SUFFIX_DISASSEMBLY);
395     }
396     else
397     {
398         /* No dot, add one and then the suffix */
399 
400         strcat (NewFilename, ".");
401         strcat (NewFilename, FILE_SUFFIX_DISASSEMBLY);
402     }
403 
404     CommentOption = FILENAME_COMMENT;
405     CgWriteOneAmlComment(Op, NewFilename, CommentOption);
406 
407     Current = Op->Asl.CommentList;
408     CommentOption = STD_DEFBLK_COMMENT;
409     while (Current)
410     {
411         CgWriteOneAmlComment(Op, Current->Comment, CommentOption);
412         CvDbgPrint ("Printing comment: %s\n", Current->Comment);
413         Current = Current->Next;
414     }
415     Op->Asl.CommentList = NULL;
416 
417     /* print any Inline comments associated with this node */
418 
419     if (Op->Asl.CloseBraceComment)
420     {
421         CommentOption = END_DEFBLK_COMMENT;
422         CgWriteOneAmlComment(Op, Op->Asl.CloseBraceComment, CommentOption);
423         Op->Asl.CloseBraceComment = NULL;
424     }
425 }
426 
427 
428 /*******************************************************************************
429  *
430  * FUNCTION:    CgWriteOneAmlComment
431  *
432  * PARAMETERS:  Op              - Current parse op
433  *              CommentToPrint  - Comment that's printed
434  *              InputOption     - Denotes the comment option.
435  *
436  * RETURN:      None
437  *
438  * DESCRIPTION: write a single comment.
439  *
440  ******************************************************************************/
441 
442 void
443 CgWriteOneAmlComment(
444     ACPI_PARSE_OBJECT       *Op,
445     char*                   CommentToPrint,
446     UINT8                   InputOption)
447 {
448     UINT8 CommentOption = InputOption;
449     UINT8 CommentOpcode = (UINT8)AML_COMMENT_OP;
450 
451     CgLocalWriteAmlData (Op, &CommentOpcode, 1);
452     CgLocalWriteAmlData (Op, &CommentOption, 1);
453 
454     /* The strlen (..) + 1 is to include the null terminator */
455 
456     CgLocalWriteAmlData (Op, CommentToPrint, strlen (CommentToPrint) + 1);
457 }
458 
459 
460 /*******************************************************************************
461  *
462  * FUNCTION:    CgWriteAmlComment
463  *
464  * PARAMETERS:  Op              - Current parse op
465  *
466  * RETURN:      None
467  *
468  * DESCRIPTION: write all comments pertaining to the
469  *              current parse op
470  *
471  ******************************************************************************/
472 
473 void
474 CgWriteAmlComment(
475     ACPI_PARSE_OBJECT       *Op)
476 {
477     ACPI_COMMENT_NODE       *Current;
478     UINT8                   CommentOption;
479     char                    *NewFilename;
480     char                    *ParentFilename;
481 
482 
483     if ((Op->Asl.ParseOpcode == PARSEOP_DEFINITION_BLOCK) ||
484          !Gbl_CaptureComments)
485     {
486         return;
487     }
488 
489     /* Print out the filename comment if needed */
490 
491     if (Op->Asl.FileChanged)
492     {
493 
494         /* first, print the file name comment after changing .asl to .dsl */
495 
496         NewFilename =
497             FlGenerateFilename (Op->Asl.Filename, FILE_SUFFIX_DISASSEMBLY);
498         CvDbgPrint ("Writing file comment, \"%s\" for %s\n",
499             NewFilename, Op->Asl.ParseOpName);
500         CgWriteOneAmlComment(Op, NewFilename, FILENAME_COMMENT);
501 
502         if (Op->Asl.ParentFilename &&
503             AcpiUtStricmp (Op->Asl.ParentFilename, Op->Asl.Filename))
504         {
505             ParentFilename = FlGenerateFilename (Op->Asl.ParentFilename,
506                 FILE_SUFFIX_DISASSEMBLY);
507             CgWriteOneAmlComment(Op, ParentFilename, PARENTFILENAME_COMMENT);
508         }
509 
510         /* prevent multiple writes of the same comment */
511 
512         Op->Asl.FileChanged = FALSE;
513     }
514 
515     /*
516      * Regular comments are stored in a list of comments within an Op.
517      * If there is a such list in this node, print out the comment
518      * as byte code.
519      */
520     Current = Op->Asl.CommentList;
521     if (Op->Asl.ParseOpcode == PARSEOP_INCLUDE)
522     {
523         CommentOption = INCLUDE_COMMENT;
524     }
525     else
526     {
527         CommentOption = STANDARD_COMMENT;
528     }
529 
530     while (Current)
531     {
532         CgWriteOneAmlComment(Op, Current->Comment, CommentOption);
533         Current = Current->Next;
534     }
535     Op->Asl.CommentList = NULL;
536 
537     Current = Op->Asl.EndBlkComment;
538     CommentOption = ENDBLK_COMMENT;
539     while (Current)
540     {
541         CgWriteOneAmlComment(Op, Current->Comment, CommentOption);
542         Current = Current->Next;
543     }
544     Op->Asl.EndBlkComment = NULL;
545 
546     /* print any Inline comments associated with this node */
547 
548     if (Op->Asl.InlineComment)
549     {
550         CommentOption = INLINE_COMMENT;
551         CgWriteOneAmlComment(Op, Op->Asl.InlineComment, CommentOption);
552         Op->Asl.InlineComment = NULL;
553     }
554 
555     if (Op->Asl.EndNodeComment)
556     {
557         CommentOption = ENDNODE_COMMENT;
558         CgWriteOneAmlComment(Op, Op->Asl.EndNodeComment, CommentOption);
559         Op->Asl.EndNodeComment = NULL;
560     }
561 
562     if (Op->Asl.CloseBraceComment)
563     {
564         CommentOption = CLOSE_BRACE_COMMENT;
565         CgWriteOneAmlComment(Op, Op->Asl.CloseBraceComment, CommentOption);
566         Op->Asl.CloseBraceComment = NULL;
567     }
568 }
569 
570 
571 /*******************************************************************************
572  *
573  * FUNCTION:    CvCommentNodeCalloc
574  *
575  * PARAMETERS:  none
576  *
577  * RETURN:      Pointer to the comment node. Aborts on allocation failure
578  *
579  * DESCRIPTION: Allocate a string node buffer.
580  *
581  ******************************************************************************/
582 
583 ACPI_COMMENT_NODE*
584 CvCommentNodeCalloc (
585     void)
586 {
587    ACPI_COMMENT_NODE        *NewCommentNode;
588 
589 
590    NewCommentNode =
591        (ACPI_COMMENT_NODE*) UtLocalCalloc (sizeof(ACPI_COMMENT_NODE));
592    NewCommentNode->Next = NULL;
593    return NewCommentNode;
594 }
595 
596 
597 /*******************************************************************************
598  *
599  * FUNCTION:    CvParseOpBlockType
600  *
601  * PARAMETERS:  Op              - Object to be examined
602  *
603  * RETURN:      BlockType - not a block, parens, braces, or even both.
604  *
605  * DESCRIPTION: Type of block for this ASL parseop (parens or braces)
606  *              keep this in sync with aslprimaries.y, aslresources.y and
607  *              aslrules.y
608  *
609  ******************************************************************************/
610 
611 UINT32
612 CvParseOpBlockType (
613     ACPI_PARSE_OBJECT       *Op)
614 {
615     if (!Op)
616     {
617         return (BLOCK_NONE);
618     }
619 
620     switch (Op->Asl.ParseOpcode)
621     {
622 
623     /* from aslprimaries.y */
624 
625     case PARSEOP_VAR_PACKAGE:
626     case PARSEOP_BANKFIELD:
627     case PARSEOP_BUFFER:
628     case PARSEOP_CASE:
629     case PARSEOP_DEVICE:
630     case PARSEOP_FIELD:
631     case PARSEOP_FOR:
632     case PARSEOP_FUNCTION:
633     case PARSEOP_IF:
634     case PARSEOP_ELSEIF:
635     case PARSEOP_INDEXFIELD:
636     case PARSEOP_METHOD:
637     case PARSEOP_POWERRESOURCE:
638     case PARSEOP_PROCESSOR:
639     case PARSEOP_DATABUFFER:
640     case PARSEOP_SCOPE:
641     case PARSEOP_SWITCH:
642     case PARSEOP_THERMALZONE:
643     case PARSEOP_WHILE:
644 
645     /* from aslresources.y */
646 
647     case PARSEOP_RESOURCETEMPLATE: /* optional parens */
648     case PARSEOP_VENDORLONG:
649     case PARSEOP_VENDORSHORT:
650     case PARSEOP_INTERRUPT:
651     case PARSEOP_IRQNOFLAGS:
652     case PARSEOP_IRQ:
653     case PARSEOP_GPIO_INT:
654     case PARSEOP_GPIO_IO:
655     case PARSEOP_DMA:
656 
657     /*from aslrules.y */
658 
659     case PARSEOP_DEFINITION_BLOCK:
660         return (BLOCK_PAREN | BLOCK_BRACE);
661 
662     default:
663 
664         return (BLOCK_NONE);
665     }
666 }
667 
668 
669 /*******************************************************************************
670  *
671  * FUNCTION:    CvProcessCommentState
672  *
673  * PARAMETERS:  char
674  *
675  * RETURN:      None
676  *
677  * DESCRIPTION: Take the given input. If this character is
678  *              defined as a comment table entry, then update the state
679  *              accordingly.
680  *
681  ******************************************************************************/
682 
683 void
684 CvProcessCommentState (
685     char                    input)
686 {
687 
688     if (input != ' ')
689     {
690         Gbl_CommentState.SpacesBefore = 0;
691     }
692 
693     switch (input)
694     {
695     case '\n':
696 
697         Gbl_CommentState.CommentType = ASL_COMMENT_STANDARD;
698         break;
699 
700     case ' ':
701 
702         /* Keep the CommentType the same */
703 
704         Gbl_CommentState.SpacesBefore++;
705         break;
706 
707     case '(':
708 
709         Gbl_CommentState.CommentType = ASL_COMMENT_OPEN_PAREN;
710         break;
711 
712     case ')':
713 
714         Gbl_CommentState.CommentType = ASL_COMMENT_CLOSE_PAREN;
715         break;
716 
717     case '{':
718 
719         Gbl_CommentState.CommentType = ASL_COMMENT_STANDARD;
720         Gbl_CommentState.ParsingParenBraceNode = NULL;
721         CvDbgPrint ("End Parsing paren/Brace node!\n");
722         break;
723 
724     case '}':
725 
726         Gbl_CommentState.CommentType = ASL_COMMENT_CLOSE_BRACE;
727         break;
728 
729     case ',':
730 
731         Gbl_CommentState.CommentType = ASLCOMMENT_INLINE;
732         break;
733 
734     default:
735 
736         Gbl_CommentState.CommentType = ASLCOMMENT_INLINE;
737         break;
738 
739     }
740 }
741 
742 
743 /*******************************************************************************
744  *
745  * FUNCTION:    CvAddToCommentList
746  *
747  * PARAMETERS:  toAdd              - Contains the comment to be inserted
748  *
749  * RETURN:      None
750  *
751  * DESCRIPTION: Add the given char* to a list of comments in the global list
752  *              of comments.
753  *
754  ******************************************************************************/
755 
756 void
757 CvAddToCommentList (
758     char*                   ToAdd)
759 {
760    if (Gbl_Comment_List_Head)
761    {
762        Gbl_Comment_List_Tail->Next = CvCommentNodeCalloc ();
763        Gbl_Comment_List_Tail = Gbl_Comment_List_Tail->Next;
764    }
765    else
766    {
767        Gbl_Comment_List_Head = CvCommentNodeCalloc ();
768        Gbl_Comment_List_Tail = Gbl_Comment_List_Head;
769    }
770 
771    Gbl_Comment_List_Tail->Comment = ToAdd;
772 
773    return;
774 }
775 
776 /*******************************************************************************
777  *
778  * FUNCTION:    CvAppendInlineComment
779  *
780  * PARAMETERS:  InlineComment      - Append to the end of this string.
781  *              toAdd              - Contains the comment to be inserted
782  *
783  * RETURN:      Str                - toAdd appended to InlineComment
784  *
785  * DESCRIPTION: Concatenate ToAdd to InlineComment
786  *
787  ******************************************************************************/
788 
789 char*
790 CvAppendInlineComment (
791     char                    *InlineComment,
792     char                    *ToAdd)
793 {
794     char*                   Str;
795     UINT32                  Size = 0;
796 
797 
798     if (!InlineComment)
799     {
800         return ToAdd;
801     }
802     if (ToAdd)
803     {
804         Size = strlen (ToAdd);
805     }
806     Size += strlen (InlineComment);
807     Str = UtStringCacheCalloc (Size+1);
808     strcpy (Str, InlineComment);
809     strcat (Str, ToAdd);
810     Str[Size+1] = 0;
811 
812     return Str;
813 }
814 
815 
816 /*******************************************************************************
817  *
818  * FUNCTION:    CvPlaceComment
819  *
820  * PARAMETERS:  Int           - Type
821  *              char*         - CommentString
822  *
823  * RETURN:      None
824  *
825  * DESCRIPTION: Given type and CommentString, this function places the
826  *              CommentString in the approperiate global comment list or char*
827  *
828  ******************************************************************************/
829 
830 void
831 CvPlaceComment(
832     UINT8                   Type,
833     char                    *CommentString)
834 {
835     ACPI_PARSE_OBJECT       *LatestParseNode;
836     ACPI_PARSE_OBJECT       *ParenBraceNode;
837 
838 
839     LatestParseNode = Gbl_CommentState.Latest_Parse_Node;
840     ParenBraceNode  = Gbl_CommentState.ParsingParenBraceNode;
841     CvDbgPrint ("Placing comment %s for type %d\n", CommentString, Type);
842 
843     switch (Type)
844     {
845     case ASL_COMMENT_STANDARD:
846 
847         CvAddToCommentList (CommentString);
848         break;
849 
850     case ASLCOMMENT_INLINE:
851 
852         LatestParseNode->Asl.InlineComment =
853             CvAppendInlineComment (LatestParseNode->Asl.InlineComment,
854             CommentString);
855         break;
856 
857     case ASL_COMMENT_OPEN_PAREN:
858 
859         Gbl_Inline_Comment_Buffer =
860             CvAppendInlineComment(Gbl_Inline_Comment_Buffer,
861             CommentString);
862         break;
863 
864     case ASL_COMMENT_CLOSE_PAREN:
865 
866         if (ParenBraceNode)
867         {
868             ParenBraceNode->Asl.EndNodeComment =
869                 CvAppendInlineComment (ParenBraceNode->Asl.EndNodeComment,
870                 CommentString);
871         }
872         else
873         {
874             LatestParseNode->Asl.EndNodeComment =
875                 CvAppendInlineComment (LatestParseNode->Asl.EndNodeComment,
876                 CommentString);
877         }
878         break;
879 
880     case ASL_COMMENT_CLOSE_BRACE:
881 
882         LatestParseNode->Asl.CloseBraceComment = CommentString;
883         break;
884 
885     default:
886 
887         break;
888 
889     }
890 }
891