]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - source/compiler/asllisting.c
Import ACPICA 20121220.
[FreeBSD/FreeBSD.git] / source / compiler / asllisting.c
1 /******************************************************************************
2  *
3  * Module Name: asllisting - Listing file generation
4  *
5  *****************************************************************************/
6
7 /*
8  * Copyright (C) 2000 - 2012, 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
45 #include "aslcompiler.h"
46 #include "aslcompiler.y.h"
47 #include "amlcode.h"
48 #include "acparser.h"
49 #include "acnamesp.h"
50
51 #define _COMPONENT          ACPI_COMPILER
52         ACPI_MODULE_NAME    ("aslisting")
53
54 /* Local prototypes */
55
56 static void
57 LsDumpAscii (
58     UINT32                  FileId,
59     UINT32                  Count,
60     UINT8                   *Buffer);
61
62 static ACPI_STATUS
63 LsAmlListingWalk (
64     ACPI_PARSE_OBJECT       *Op,
65     UINT32                  Level,
66     void                    *Context);
67
68 static void
69 LsGenerateListing (
70     UINT32                  FileId);
71
72 static void
73 LsPushNode (
74     char                    *Filename);
75
76 static ASL_LISTING_NODE *
77 LsPopNode (
78     void);
79
80 static void
81 LsCheckException (
82     UINT32                  LineNumber,
83     UINT32                  FileId);
84
85 static void
86 LsFlushListingBuffer (
87     UINT32                  FileId);
88
89 static void
90 LsWriteListingHexBytes (
91     UINT8                   *Buffer,
92     UINT32                  Length,
93     UINT32                  FileId);
94
95 static UINT32
96 LsWriteOneSourceLine (
97     UINT32                  FileId);
98
99 static void
100 LsFinishSourceListing (
101     UINT32                  FileId);
102
103 static void
104 LsWriteSourceLines (
105     UINT32                  ToLineNumber,
106     UINT32                  ToLogicalLineNumber,
107     UINT32                  FileId);
108
109 static void
110 LsWriteNodeToListing (
111     ACPI_PARSE_OBJECT       *Op,
112     UINT32                  FileId);
113
114 static ACPI_STATUS
115 LsTreeWriteWalk (
116     ACPI_PARSE_OBJECT       *Op,
117     UINT32                  Level,
118     void                    *Context);
119
120
121 /*******************************************************************************
122  *
123  * FUNCTION:    LsDoListings
124  *
125  * PARAMETERS:  None
126  *
127  * RETURN:      None
128  *
129  * DESCRIPTION: Generate all requested listing files.
130  *
131  ******************************************************************************/
132
133 void
134 LsDoListings (
135     void)
136 {
137
138     if (Gbl_C_OutputFlag)
139     {
140         LsGenerateListing (ASL_FILE_C_SOURCE_OUTPUT);
141     }
142
143     if (Gbl_ListingFlag)
144     {
145         LsGenerateListing (ASL_FILE_LISTING_OUTPUT);
146     }
147
148     if (Gbl_AsmOutputFlag)
149     {
150         LsGenerateListing (ASL_FILE_ASM_SOURCE_OUTPUT);
151     }
152
153     if (Gbl_C_IncludeOutputFlag)
154     {
155         LsGenerateListing (ASL_FILE_C_INCLUDE_OUTPUT);
156     }
157
158     if (Gbl_AsmIncludeOutputFlag)
159     {
160         LsGenerateListing (ASL_FILE_ASM_INCLUDE_OUTPUT);
161     }
162 }
163
164
165 /*******************************************************************************
166  *
167  * FUNCTION:    LsTreeWriteWalk
168  *
169  * PARAMETERS:  ASL_WALK_CALLBACK
170  *
171  *
172  * RETURN:      None
173  *
174  * DESCRIPTION: Dump entire parse tree, for compiler debug only
175  *
176  ******************************************************************************/
177
178 static ACPI_STATUS
179 LsTreeWriteWalk (
180     ACPI_PARSE_OBJECT       *Op,
181     UINT32                  Level,
182     void                    *Context)
183 {
184
185     /* Debug output */
186
187     DbgPrint (ASL_TREE_OUTPUT,
188         "%5.5d [%2d]", Op->Asl.LogicalLineNumber, Level);
189     UtPrintFormattedName (Op->Asl.ParseOpcode, Level);
190
191
192     DbgPrint (ASL_TREE_OUTPUT, "\n");
193     return (AE_OK);
194 }
195
196
197 void
198 LsDumpParseTree (
199     void)
200 {
201
202     if (!Gbl_DebugFlag)
203     {
204         return;
205     }
206
207     DbgPrint (ASL_TREE_OUTPUT, "\nOriginal parse tree from parser:\n\n");
208     TrWalkParseTree (RootNode, ASL_WALK_VISIT_DOWNWARD,
209         LsTreeWriteWalk, NULL, NULL);
210 }
211
212
213 /*******************************************************************************
214  *
215  * FUNCTION:    LsDumpAscii
216  *
217  * PARAMETERS:  FileId          - ID of current listing file
218  *              Count           - Number of bytes to convert
219  *              Buffer          - Buffer of bytes to convert
220  *
221  * RETURN:      None
222  *
223  * DESCRIPTION: Convert hex bytes to ascii
224  *
225  ******************************************************************************/
226
227 static void
228 LsDumpAscii (
229     UINT32                  FileId,
230     UINT32                  Count,
231     UINT8                   *Buffer)
232 {
233     UINT8                   BufChar;
234     UINT32                  i;
235
236
237     FlPrintFile (FileId, "    \"");
238     for (i = 0; i < Count; i++)
239     {
240         BufChar = Buffer[i];
241         if (isprint (BufChar))
242         {
243             FlPrintFile (FileId, "%c", BufChar);
244         }
245         else
246         {
247             /* Not a printable character, just put out a dot */
248
249             FlPrintFile (FileId, ".");
250         }
251     }
252     FlPrintFile (FileId, "\"");
253 }
254
255
256 /*******************************************************************************
257  *
258  * FUNCTION:    LsDumpAsciiInComment
259  *
260  * PARAMETERS:  FileId          - ID of current listing file
261  *              Count           - Number of bytes to convert
262  *              Buffer          - Buffer of bytes to convert
263  *
264  * RETURN:      None
265  *
266  * DESCRIPTION: Convert hex bytes to ascii
267  *
268  ******************************************************************************/
269
270 void
271 LsDumpAsciiInComment (
272     UINT32                  FileId,
273     UINT32                  Count,
274     UINT8                   *Buffer)
275 {
276     UINT8                   BufChar = 0;
277     UINT8                   LastChar;
278     UINT32                  i;
279
280
281     FlPrintFile (FileId, "    \"");
282     for (i = 0; i < Count; i++)
283     {
284         LastChar = BufChar;
285         BufChar = Buffer[i];
286
287         if (isprint (BufChar))
288         {
289             /* Handle embedded C comment sequences */
290
291             if (((LastChar == '*') && (BufChar == '/')) ||
292                 ((LastChar == '/') && (BufChar == '*')))
293             {
294                 /* Insert a space to break the sequence */
295
296                 FlPrintFile (FileId, ".", BufChar);
297             }
298
299             FlPrintFile (FileId, "%c", BufChar);
300         }
301         else
302         {
303             /* Not a printable character, just put out a dot */
304
305             FlPrintFile (FileId, ".");
306         }
307     }
308     FlPrintFile (FileId, "\"");
309 }
310
311
312 /*******************************************************************************
313  *
314  * FUNCTION:    LsAmlListingWalk
315  *
316  * PARAMETERS:  ASL_WALK_CALLBACK
317  *
318  * RETURN:      Status
319  *
320  * DESCRIPTION: Process one node during a listing file generation.
321  *
322  ******************************************************************************/
323
324 static ACPI_STATUS
325 LsAmlListingWalk (
326     ACPI_PARSE_OBJECT       *Op,
327     UINT32                  Level,
328     void                    *Context)
329 {
330     UINT8                   FileByte;
331     UINT32                  i;
332     UINT32                  FileId = (UINT32) ACPI_TO_INTEGER (Context);
333
334
335     LsWriteNodeToListing (Op, FileId);
336
337     if (Op->Asl.CompileFlags & NODE_IS_RESOURCE_DATA)
338     {
339         /* Buffer is a resource template, don't dump the data all at once */
340
341         return (AE_OK);
342     }
343
344     /* Write the hex bytes to the listing file(s) (if requested) */
345
346     for (i = 0; i < Op->Asl.FinalAmlLength; i++)
347     {
348         if (ACPI_FAILURE (FlReadFile (ASL_FILE_AML_OUTPUT, &FileByte, 1)))
349         {
350             FlFileError (ASL_FILE_AML_OUTPUT, ASL_MSG_READ);
351             AslAbort ();
352         }
353         LsWriteListingHexBytes (&FileByte, 1, FileId);
354     }
355
356     return (AE_OK);
357 }
358
359
360 /*******************************************************************************
361  *
362  * FUNCTION:    LsGenerateListing
363  *
364  * PARAMETERS:  FileId      - ID of listing file
365  *
366  * RETURN:      None
367  *
368  * DESCRIPTION: Generate a listing file. This can be one of the several types
369  *              of "listings" supported.
370  *
371  ******************************************************************************/
372
373 static void
374 LsGenerateListing (
375     UINT32                  FileId)
376 {
377
378     /* Start at the beginning of both the source and AML files */
379
380     FlSeekFile (ASL_FILE_SOURCE_OUTPUT, 0);
381     FlSeekFile (ASL_FILE_AML_OUTPUT, 0);
382     Gbl_SourceLine = 0;
383     Gbl_CurrentHexColumn = 0;
384     LsPushNode (Gbl_Files[ASL_FILE_INPUT].Filename);
385
386     /* Process all parse nodes */
387
388     TrWalkParseTree (RootNode, ASL_WALK_VISIT_DOWNWARD, LsAmlListingWalk,
389                         NULL, (void *) ACPI_TO_POINTER (FileId));
390
391     /* Final processing */
392
393     LsFinishSourceListing (FileId);
394 }
395
396
397 /*******************************************************************************
398  *
399  * FUNCTION:    LsPushNode
400  *
401  * PARAMETERS:  Filename        - Pointer to the include filename
402  *
403  * RETURN:      None
404  *
405  * DESCRIPTION: Push a listing node on the listing/include file stack. This
406  *              stack enables tracking of include files (infinitely nested)
407  *              and resumption of the listing of the parent file when the
408  *              include file is finished.
409  *
410  ******************************************************************************/
411
412 static void
413 LsPushNode (
414     char                    *Filename)
415 {
416     ASL_LISTING_NODE        *Lnode;
417
418
419     /* Create a new node */
420
421     Lnode = UtLocalCalloc (sizeof (ASL_LISTING_NODE));
422
423     /* Initialize */
424
425     Lnode->Filename = Filename;
426     Lnode->LineNumber = 0;
427
428     /* Link (push) */
429
430     Lnode->Next = Gbl_ListingNode;
431     Gbl_ListingNode = Lnode;
432 }
433
434
435 /*******************************************************************************
436  *
437  * FUNCTION:    LsPopNode
438  *
439  * PARAMETERS:  None
440  *
441  * RETURN:      List head after current head is popped off
442  *
443  * DESCRIPTION: Pop the current head of the list, free it, and return the
444  *              next node on the stack (the new current node).
445  *
446  ******************************************************************************/
447
448 static ASL_LISTING_NODE *
449 LsPopNode (
450     void)
451 {
452     ASL_LISTING_NODE        *Lnode;
453
454
455     /* Just grab the node at the head of the list */
456
457     Lnode = Gbl_ListingNode;
458     if ((!Lnode) ||
459         (!Lnode->Next))
460     {
461         AslError (ASL_ERROR, ASL_MSG_COMPILER_INTERNAL, NULL,
462             "Could not pop empty listing stack");
463         return (Gbl_ListingNode);
464     }
465
466     Gbl_ListingNode = Lnode->Next;
467     ACPI_FREE (Lnode);
468
469     /* New "Current" node is the new head */
470
471     return (Gbl_ListingNode);
472 }
473
474
475 /*******************************************************************************
476  *
477  * FUNCTION:    LsCheckException
478  *
479  * PARAMETERS:  LineNumber          - Current logical (cumulative) line #
480  *              FileId              - ID of output listing file
481  *
482  * RETURN:      None
483  *
484  * DESCRIPTION: Check if there is an exception for this line, and if there is,
485  *              put it in the listing immediately. Handles multiple errors
486  *              per line. Gbl_NextError points to the next error in the
487  *              sorted (by line #) list of compile errors/warnings.
488  *
489  ******************************************************************************/
490
491 static void
492 LsCheckException (
493     UINT32                  LineNumber,
494     UINT32                  FileId)
495 {
496
497     if ((!Gbl_NextError) ||
498         (LineNumber < Gbl_NextError->LogicalLineNumber ))
499     {
500         return;
501     }
502
503     /* Handle multiple errors per line */
504
505     if (FileId == ASL_FILE_LISTING_OUTPUT)
506     {
507         while (Gbl_NextError &&
508               (LineNumber >= Gbl_NextError->LogicalLineNumber))
509         {
510             AePrintException (FileId, Gbl_NextError, "\n[****iasl****]\n");
511
512             Gbl_NextError = Gbl_NextError->Next;
513         }
514
515         FlPrintFile (FileId, "\n");
516     }
517 }
518
519
520 /*******************************************************************************
521  *
522  * FUNCTION:    LsFlushListingBuffer
523  *
524  * PARAMETERS:  FileId          - ID of the listing file
525  *
526  * RETURN:      None
527  *
528  * DESCRIPTION: Flush out the current contents of the 16-byte hex AML code
529  *              buffer. Usually called at the termination of a single line
530  *              of source code or when the buffer is full.
531  *
532  ******************************************************************************/
533
534 static void
535 LsFlushListingBuffer (
536     UINT32                  FileId)
537 {
538     UINT32                  i;
539
540
541     if (Gbl_CurrentHexColumn == 0)
542     {
543         return;
544     }
545
546     /* Write the hex bytes */
547
548     switch (FileId)
549     {
550     case ASL_FILE_LISTING_OUTPUT:
551
552         for (i = 0; i < Gbl_CurrentHexColumn; i++)
553         {
554             FlPrintFile (FileId, "%2.2X ", Gbl_AmlBuffer[i]);
555         }
556
557         for (i = 0; i < ((HEX_LISTING_LINE_SIZE - Gbl_CurrentHexColumn) * 3); i++)
558         {
559             FlWriteFile (FileId, ".", 1);
560         }
561
562         /* Write the ASCII character associated with each of the bytes */
563
564         LsDumpAscii (FileId, Gbl_CurrentHexColumn, Gbl_AmlBuffer);
565         break;
566
567
568     case ASL_FILE_ASM_SOURCE_OUTPUT:
569
570         for (i = 0; i < Gbl_CurrentHexColumn; i++)
571         {
572             if (i > 0)
573             {
574                 FlPrintFile (FileId, ",");
575             }
576             FlPrintFile (FileId, "0%2.2Xh", Gbl_AmlBuffer[i]);
577         }
578
579         for (i = 0; i < ((HEX_LISTING_LINE_SIZE - Gbl_CurrentHexColumn) * 5); i++)
580         {
581             FlWriteFile (FileId, " ", 1);
582         }
583
584         FlPrintFile (FileId, "  ;%8.8X",
585             Gbl_CurrentAmlOffset - HEX_LISTING_LINE_SIZE);
586
587         /* Write the ASCII character associated with each of the bytes */
588
589         LsDumpAscii (FileId, Gbl_CurrentHexColumn, Gbl_AmlBuffer);
590         break;
591
592
593     case ASL_FILE_C_SOURCE_OUTPUT:
594
595         for (i = 0; i < Gbl_CurrentHexColumn; i++)
596         {
597             FlPrintFile (FileId, "0x%2.2X,", Gbl_AmlBuffer[i]);
598         }
599
600         for (i = 0; i < ((HEX_LISTING_LINE_SIZE - Gbl_CurrentHexColumn) * 5); i++)
601         {
602             FlWriteFile (FileId, " ", 1);
603         }
604
605         FlPrintFile (FileId, "    /* %8.8X",
606             Gbl_CurrentAmlOffset - HEX_LISTING_LINE_SIZE);
607
608         /* Write the ASCII character associated with each of the bytes */
609
610         LsDumpAsciiInComment (FileId, Gbl_CurrentHexColumn, Gbl_AmlBuffer);
611         FlPrintFile (FileId, " */");
612         break;
613
614     default:
615         /* No other types supported */
616         return;
617     }
618
619     FlPrintFile (FileId, "\n");
620
621     Gbl_CurrentHexColumn = 0;
622     Gbl_HexBytesWereWritten = TRUE;
623 }
624
625
626 /*******************************************************************************
627  *
628  * FUNCTION:    LsWriteListingHexBytes
629  *
630  * PARAMETERS:  Buffer          - AML code buffer
631  *              Length          - Number of AML bytes to write
632  *              FileId          - ID of current listing file.
633  *
634  * RETURN:      None
635  *
636  * DESCRIPTION: Write the contents of the AML buffer to the listing file via
637  *              the listing buffer. The listing buffer is flushed every 16
638  *              AML bytes.
639  *
640  ******************************************************************************/
641
642 static void
643 LsWriteListingHexBytes (
644     UINT8                   *Buffer,
645     UINT32                  Length,
646     UINT32                  FileId)
647 {
648     UINT32                  i;
649
650
651     /* Transfer all requested bytes */
652
653     for (i = 0; i < Length; i++)
654     {
655         /* Print line header when buffer is empty */
656
657         if (Gbl_CurrentHexColumn == 0)
658         {
659             if (Gbl_HasIncludeFiles)
660             {
661                 FlPrintFile (FileId, "%*s", 10, " ");
662             }
663
664             switch (FileId)
665             {
666             case ASL_FILE_LISTING_OUTPUT:
667
668                 FlPrintFile (FileId, "%8.8X....", Gbl_CurrentAmlOffset);
669                 break;
670
671             case ASL_FILE_ASM_SOURCE_OUTPUT:
672
673                 FlPrintFile (FileId, "    db ");
674                 break;
675
676             case ASL_FILE_C_SOURCE_OUTPUT:
677
678                 FlPrintFile (FileId, "        ");
679                 break;
680
681             default:
682                 /* No other types supported */
683                 return;
684             }
685         }
686
687         /* Transfer AML byte and update counts */
688
689         Gbl_AmlBuffer[Gbl_CurrentHexColumn] = Buffer[i];
690
691         Gbl_CurrentHexColumn++;
692         Gbl_CurrentAmlOffset++;
693
694         /* Flush buffer when it is full */
695
696         if (Gbl_CurrentHexColumn >= HEX_LISTING_LINE_SIZE)
697         {
698             LsFlushListingBuffer (FileId);
699         }
700     }
701 }
702
703
704 /*******************************************************************************
705  *
706  * FUNCTION:    LsWriteOneSourceLine
707  *
708  * PARAMETERS:  FileID          - ID of current listing file
709  *
710  * RETURN:      FALSE on EOF (input source file), TRUE otherwise
711  *
712  * DESCRIPTION: Read one line from the input source file and echo it to the
713  *              listing file, prefixed with the line number, and if the source
714  *              file contains include files, prefixed with the current filename
715  *
716  ******************************************************************************/
717
718 static UINT32
719 LsWriteOneSourceLine (
720     UINT32                  FileId)
721 {
722     UINT8                   FileByte;
723
724
725     Gbl_SourceLine++;
726     Gbl_ListingNode->LineNumber++;
727
728     if (FileId == ASL_FILE_C_SOURCE_OUTPUT)
729     {
730         FlPrintFile (FileId, "     *");
731     }
732     if (FileId == ASL_FILE_ASM_SOURCE_OUTPUT)
733     {
734         FlPrintFile (FileId, "; ");
735     }
736
737     if (Gbl_HasIncludeFiles)
738     {
739         /*
740          * This file contains "include" statements, print the current
741          * filename and line number within the current file
742          */
743         FlPrintFile (FileId, "%12s %5d....",
744                     Gbl_ListingNode->Filename, Gbl_ListingNode->LineNumber);
745     }
746     else
747     {
748         /* No include files, just print the line number */
749
750         FlPrintFile (FileId, "%8d....", Gbl_SourceLine);
751     }
752
753     /* Read one line (up to a newline or EOF) */
754
755     while (FlReadFile (ASL_FILE_SOURCE_OUTPUT, &FileByte, 1) == AE_OK)
756     {
757         if (FileId == ASL_FILE_C_SOURCE_OUTPUT)
758         {
759             if (FileByte == '/')
760             {
761                 FileByte = '*';
762             }
763         }
764
765         FlWriteFile (FileId, &FileByte, 1);
766         if (FileByte == '\n')
767         {
768             /*
769              * Check if an error occurred on this source line during the compile.
770              * If so, we print the error message after the source line.
771              */
772             LsCheckException (Gbl_SourceLine, FileId);
773             return (1);
774         }
775     }
776
777     /* EOF on the input file was reached */
778
779     return (0);
780 }
781
782
783 /*******************************************************************************
784  *
785  * FUNCTION:    LsFinishSourceListing
786  *
787  * PARAMETERS:  FileId          - ID of current listing file.
788  *
789  * RETURN:      None
790  *
791  * DESCRIPTION: Cleanup routine for the listing file. Flush the hex AML
792  *              listing buffer, and flush out any remaining lines in the
793  *              source input file.
794  *
795  ******************************************************************************/
796
797 static void
798 LsFinishSourceListing (
799     UINT32                  FileId)
800 {
801
802     if ((FileId == ASL_FILE_ASM_INCLUDE_OUTPUT) ||
803         (FileId == ASL_FILE_C_INCLUDE_OUTPUT))
804     {
805         return;
806     }
807
808     LsFlushListingBuffer (FileId);
809     Gbl_CurrentAmlOffset = 0;
810
811     /* Flush any remaining text in the source file */
812
813     if (FileId == ASL_FILE_C_SOURCE_OUTPUT)
814     {
815         FlPrintFile (FileId, "    /*\n");
816     }
817
818     while (LsWriteOneSourceLine (FileId))
819     { ; }
820
821     if (FileId == ASL_FILE_C_SOURCE_OUTPUT)
822     {
823         FlPrintFile (FileId, "\n     */\n    };\n");
824     }
825
826     FlPrintFile (FileId, "\n");
827
828     if (FileId == ASL_FILE_LISTING_OUTPUT)
829     {
830         /* Print a summary of the compile exceptions */
831
832         FlPrintFile (FileId, "\n\nSummary of errors and warnings\n\n");
833         AePrintErrorLog (FileId);
834         FlPrintFile (FileId, "\n");
835         UtDisplaySummary (FileId);
836         FlPrintFile (FileId, "\n");
837     }
838 }
839
840
841 /*******************************************************************************
842  *
843  * FUNCTION:    LsWriteSourceLines
844  *
845  * PARAMETERS:  ToLineNumber            -
846  *              ToLogicalLineNumber     - Write up to this source line number
847  *              FileId                  - ID of current listing file
848  *
849  * RETURN:      None
850  *
851  * DESCRIPTION: Read then write source lines to the listing file until we have
852  *              reached the specified logical (cumulative) line number. This
853  *              automatically echos out comment blocks and other non-AML
854  *              generating text until we get to the actual AML-generating line
855  *              of ASL code specified by the logical line number.
856  *
857  ******************************************************************************/
858
859 static void
860 LsWriteSourceLines (
861     UINT32                  ToLineNumber,
862     UINT32                  ToLogicalLineNumber,
863     UINT32                  FileId)
864 {
865
866     if ((FileId == ASL_FILE_ASM_INCLUDE_OUTPUT) ||
867         (FileId == ASL_FILE_C_INCLUDE_OUTPUT))
868     {
869         return;
870     }
871
872     Gbl_CurrentLine = ToLogicalLineNumber;
873
874     /* Flush any hex bytes remaining from the last opcode */
875
876     LsFlushListingBuffer (FileId);
877
878     /* Read lines and write them as long as we are not caught up */
879
880     if (Gbl_SourceLine < Gbl_CurrentLine)
881     {
882         /*
883          * If we just completed writing some AML hex bytes, output a linefeed
884          * to add some whitespace for readability.
885          */
886         if (Gbl_HexBytesWereWritten)
887         {
888             FlPrintFile (FileId, "\n");
889             Gbl_HexBytesWereWritten = FALSE;
890         }
891
892         if (FileId == ASL_FILE_C_SOURCE_OUTPUT)
893         {
894             FlPrintFile (FileId, "    /*\n");
895         }
896
897         /* Write one line at a time until we have reached the target line # */
898
899         while ((Gbl_SourceLine < Gbl_CurrentLine) &&
900                 LsWriteOneSourceLine (FileId))
901         { ; }
902
903         if (FileId == ASL_FILE_C_SOURCE_OUTPUT)
904         {
905             FlPrintFile (FileId, "     */");
906         }
907         FlPrintFile (FileId, "\n");
908     }
909 }
910
911
912 /*******************************************************************************
913  *
914  * FUNCTION:    LsWriteNodeToListing
915  *
916  * PARAMETERS:  Op            - Parse node to write to the listing file.
917  *              FileId          - ID of current listing file
918  *
919  * RETURN:      None.
920  *
921  * DESCRIPTION: Write "a node" to the listing file. This means to
922  *              1) Write out all of the source text associated with the node
923  *              2) Write out all of the AML bytes associated with the node
924  *              3) Write any compiler exceptions associated with the node
925  *
926  ******************************************************************************/
927
928 static void
929 LsWriteNodeToListing (
930     ACPI_PARSE_OBJECT       *Op,
931     UINT32                  FileId)
932 {
933     const ACPI_OPCODE_INFO  *OpInfo;
934     UINT32                  OpClass;
935     char                    *Pathname;
936     UINT32                  Length;
937     UINT32                  i;
938
939
940     OpInfo  = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode);
941     OpClass = OpInfo->Class;
942
943     /* TBD: clean this up with a single flag that says:
944      * I start a named output block
945      */
946     if (FileId == ASL_FILE_C_SOURCE_OUTPUT)
947     {
948         switch (Op->Asl.ParseOpcode)
949         {
950         case PARSEOP_DEFINITIONBLOCK:
951         case PARSEOP_METHODCALL:
952         case PARSEOP_INCLUDE:
953         case PARSEOP_INCLUDE_END:
954         case PARSEOP_DEFAULT_ARG:
955
956             break;
957
958         default:
959             switch (OpClass)
960             {
961             case AML_CLASS_NAMED_OBJECT:
962                 switch (Op->Asl.AmlOpcode)
963                 {
964                 case AML_SCOPE_OP:
965                 case AML_ALIAS_OP:
966                     break;
967
968                 default:
969                     if (Op->Asl.ExternalName)
970                     {
971                         LsFlushListingBuffer (FileId);
972                         FlPrintFile (FileId, "    };\n");
973                     }
974                     break;
975                 }
976                 break;
977
978             default:
979                 /* Don't care about other objects */
980                 break;
981             }
982             break;
983         }
984     }
985
986     /* These cases do not have a corresponding AML opcode */
987
988     switch (Op->Asl.ParseOpcode)
989     {
990     case PARSEOP_DEFINITIONBLOCK:
991
992         LsWriteSourceLines (Op->Asl.EndLine, Op->Asl.EndLogicalLine, FileId);
993
994         /* Use the table Signature and TableId to build a unique name */
995
996         if (FileId == ASL_FILE_ASM_SOURCE_OUTPUT)
997         {
998             FlPrintFile (FileId,
999                 "%s_%s_Header \\\n",
1000                 Gbl_TableSignature, Gbl_TableId);
1001         }
1002         if (FileId == ASL_FILE_C_SOURCE_OUTPUT)
1003         {
1004             FlPrintFile (FileId,
1005                 "    unsigned char    %s_%s_Header [] =\n    {\n",
1006                 Gbl_TableSignature, Gbl_TableId);
1007         }
1008         if (FileId == ASL_FILE_ASM_INCLUDE_OUTPUT)
1009         {
1010             FlPrintFile (FileId,
1011                 "extrn %s_%s_Header : byte\n",
1012                 Gbl_TableSignature, Gbl_TableId);
1013         }
1014         if (FileId == ASL_FILE_C_INCLUDE_OUTPUT)
1015         {
1016             FlPrintFile (FileId,
1017                 "extern unsigned char    %s_%s_Header [];\n",
1018                 Gbl_TableSignature, Gbl_TableId);
1019         }
1020         return;
1021
1022
1023     case PARSEOP_METHODCALL:
1024
1025         LsWriteSourceLines (Op->Asl.LineNumber, Op->Asl.LogicalLineNumber,
1026             FileId);
1027         return;
1028
1029
1030     case PARSEOP_INCLUDE:
1031
1032         /* Flush everything up to and including the include source line */
1033
1034         LsWriteSourceLines (Op->Asl.LineNumber, Op->Asl.LogicalLineNumber,
1035             FileId);
1036
1037         /* Create a new listing node and push it */
1038
1039         LsPushNode (Op->Asl.Child->Asl.Value.String);
1040         return;
1041
1042
1043     case PARSEOP_INCLUDE_END:
1044
1045         /* Flush out the rest of the include file */
1046
1047         LsWriteSourceLines (Op->Asl.LineNumber, Op->Asl.LogicalLineNumber,
1048             FileId);
1049
1050         /* Pop off this listing node and go back to the parent file */
1051
1052         (void) LsPopNode ();
1053         return;
1054
1055
1056     case PARSEOP_DEFAULT_ARG:
1057
1058         if (Op->Asl.CompileFlags & NODE_IS_RESOURCE_DESC)
1059         {
1060             LsWriteSourceLines (Op->Asl.LineNumber, Op->Asl.EndLogicalLine,
1061                 FileId);
1062         }
1063         return;
1064
1065
1066     default:
1067         /* All other opcodes have an AML opcode */
1068         break;
1069     }
1070
1071     /*
1072      * Otherwise, we look at the AML opcode because we can
1073      * switch on the opcode type, getting an entire class
1074      * at once
1075      */
1076     switch (OpClass)
1077     {
1078     case AML_CLASS_ARGUMENT:       /* argument type only */
1079     case AML_CLASS_INTERNAL:
1080
1081         break;
1082
1083
1084     case AML_CLASS_NAMED_OBJECT:
1085
1086         switch (Op->Asl.AmlOpcode)
1087         {
1088         case AML_FIELD_OP:
1089         case AML_INDEX_FIELD_OP:
1090         case AML_BANK_FIELD_OP:
1091
1092             /*
1093              * For fields, we want to dump all the AML after the
1094              * entire definition
1095              */
1096             LsWriteSourceLines (Op->Asl.EndLine, Op->Asl.EndLogicalLine,
1097                 FileId);
1098             break;
1099
1100         case AML_NAME_OP:
1101
1102             if (Op->Asl.CompileFlags & NODE_IS_RESOURCE_DESC)
1103             {
1104                 LsWriteSourceLines (Op->Asl.LineNumber, Op->Asl.LogicalLineNumber,
1105                     FileId);
1106             }
1107             else
1108             {
1109                 /*
1110                  * For fields, we want to dump all the AML after the
1111                  * entire definition
1112                  */
1113                 LsWriteSourceLines (Op->Asl.EndLine, Op->Asl.EndLogicalLine,
1114                     FileId);
1115             }
1116             break;
1117
1118         default:
1119             LsWriteSourceLines (Op->Asl.LineNumber, Op->Asl.LogicalLineNumber,
1120                 FileId);
1121             break;
1122         }
1123
1124         switch (Op->Asl.AmlOpcode)
1125         {
1126         case AML_SCOPE_OP:
1127         case AML_ALIAS_OP:
1128
1129             /* These opcodes do not declare a new object, ignore them */
1130
1131             break;
1132
1133         default:
1134
1135             /* All other named object opcodes come here */
1136
1137             switch (FileId)
1138             {
1139             case ASL_FILE_ASM_SOURCE_OUTPUT:
1140             case ASL_FILE_C_SOURCE_OUTPUT:
1141             case ASL_FILE_ASM_INCLUDE_OUTPUT:
1142             case ASL_FILE_C_INCLUDE_OUTPUT:
1143
1144                 /*
1145                  * For named objects, we will create a valid symbol so that the
1146                  * AML code can be referenced from C or ASM
1147                  */
1148                 if (Op->Asl.ExternalName)
1149                 {
1150                     /* Get the full pathname associated with this node */
1151
1152                     Pathname = AcpiNsGetExternalPathname (Op->Asl.Node);
1153                     Length = strlen (Pathname);
1154                     if (Length >= 4)
1155                     {
1156                         /* Convert all dots in the path to underscores */
1157
1158                         for (i = 0; i < Length; i++)
1159                         {
1160                             if (Pathname[i] == '.')
1161                             {
1162                                 Pathname[i] = '_';
1163                             }
1164                         }
1165
1166                         /* Create the appropriate symbol in the output file */
1167
1168                         if (FileId == ASL_FILE_ASM_SOURCE_OUTPUT)
1169                         {
1170                             FlPrintFile (FileId,
1171                                 "%s_%s_%s  \\\n",
1172                                 Gbl_TableSignature, Gbl_TableId, &Pathname[1]);
1173                         }
1174                         if (FileId == ASL_FILE_C_SOURCE_OUTPUT)
1175                         {
1176                             FlPrintFile (FileId,
1177                                 "    unsigned char    %s_%s_%s [] =\n    {\n",
1178                                 Gbl_TableSignature, Gbl_TableId, &Pathname[1]);
1179                         }
1180                         if (FileId == ASL_FILE_ASM_INCLUDE_OUTPUT)
1181                         {
1182                             FlPrintFile (FileId,
1183                                 "extrn %s_%s_%s : byte\n",
1184                                 Gbl_TableSignature, Gbl_TableId, &Pathname[1]);
1185                         }
1186                         if (FileId == ASL_FILE_C_INCLUDE_OUTPUT)
1187                         {
1188                             FlPrintFile (FileId,
1189                                 "extern unsigned char    %s_%s_%s [];\n",
1190                                 Gbl_TableSignature, Gbl_TableId, &Pathname[1]);
1191                         }
1192                     }
1193                     ACPI_FREE (Pathname);
1194                 }
1195                 break;
1196
1197             default:
1198                 /* Nothing to do for listing file */
1199                 break;
1200             }
1201         }
1202         break;
1203
1204     case AML_CLASS_EXECUTE:
1205     case AML_CLASS_CREATE:
1206     default:
1207
1208         if ((Op->Asl.ParseOpcode == PARSEOP_BUFFER) &&
1209             (Op->Asl.CompileFlags & NODE_IS_RESOURCE_DESC))
1210         {
1211             return;
1212         }
1213
1214         LsWriteSourceLines (Op->Asl.LineNumber, Op->Asl.LogicalLineNumber,
1215             FileId);
1216         break;
1217
1218     case AML_CLASS_UNKNOWN:
1219         break;
1220     }
1221 }