mkdep(1) seems to want the current directory on the include path,
[dragonfly.git] / sys / contrib / dev / acpica-unix-20031203 / compiler / asllisting.c
1
2 /******************************************************************************
3  *
4  * Module Name: asllisting - Listing file generation
5  *              $Revision: 50 $
6  *
7  *****************************************************************************/
8
9 /******************************************************************************
10  *
11  * 1. Copyright Notice
12  *
13  * Some or all of this work - Copyright (c) 1999 - 2003, Intel Corp.
14  * All rights reserved.
15  *
16  * 2. License
17  *
18  * 2.1. This is your license from Intel Corp. under its intellectual property
19  * rights.  You may have additional license terms from the party that provided
20  * you this software, covering your right to use that party's intellectual
21  * property rights.
22  *
23  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
24  * copy of the source code appearing in this file ("Covered Code") an
25  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
26  * base code distributed originally by Intel ("Original Intel Code") to copy,
27  * make derivatives, distribute, use and display any portion of the Covered
28  * Code in any form, with the right to sublicense such rights; and
29  *
30  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
31  * license (with the right to sublicense), under only those claims of Intel
32  * patents that are infringed by the Original Intel Code, to make, use, sell,
33  * offer to sell, and import the Covered Code and derivative works thereof
34  * solely to the minimum extent necessary to exercise the above copyright
35  * license, and in no event shall the patent license extend to any additions
36  * to or modifications of the Original Intel Code.  No other license or right
37  * is granted directly or by implication, estoppel or otherwise;
38  *
39  * The above copyright and patent license is granted only if the following
40  * conditions are met:
41  *
42  * 3. Conditions
43  *
44  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
45  * Redistribution of source code of any substantial portion of the Covered
46  * Code or modification with rights to further distribute source must include
47  * the above Copyright Notice, the above License, this list of Conditions,
48  * and the following Disclaimer and Export Compliance provision.  In addition,
49  * Licensee must cause all Covered Code to which Licensee contributes to
50  * contain a file documenting the changes Licensee made to create that Covered
51  * Code and the date of any change.  Licensee must include in that file the
52  * documentation of any changes made by any predecessor Licensee.  Licensee
53  * must include a prominent statement that the modification is derived,
54  * directly or indirectly, from Original Intel Code.
55  *
56  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
57  * Redistribution of source code of any substantial portion of the Covered
58  * Code or modification without rights to further distribute source must
59  * include the following Disclaimer and Export Compliance provision in the
60  * documentation and/or other materials provided with distribution.  In
61  * addition, Licensee may not authorize further sublicense of source of any
62  * portion of the Covered Code, and must include terms to the effect that the
63  * license from Licensee to its licensee is limited to the intellectual
64  * property embodied in the software Licensee provides to its licensee, and
65  * not to intellectual property embodied in modifications its licensee may
66  * make.
67  *
68  * 3.3. Redistribution of Executable. Redistribution in executable form of any
69  * substantial portion of the Covered Code or modification must reproduce the
70  * above Copyright Notice, and the following Disclaimer and Export Compliance
71  * provision in the documentation and/or other materials provided with the
72  * distribution.
73  *
74  * 3.4. Intel retains all right, title, and interest in and to the Original
75  * Intel Code.
76  *
77  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
78  * Intel shall be used in advertising or otherwise to promote the sale, use or
79  * other dealings in products derived from or relating to the Covered Code
80  * without prior written authorization from Intel.
81  *
82  * 4. Disclaimer and Export Compliance
83  *
84  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
85  * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
86  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
87  * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
88  * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
89  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
90  * PARTICULAR PURPOSE.
91  *
92  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
93  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
94  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
95  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
96  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
97  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
98  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
99  * LIMITED REMEDY.
100  *
101  * 4.3. Licensee shall not export, either directly or indirectly, any of this
102  * software or system incorporating such software without first obtaining any
103  * required license or other approval from the U. S. Department of Commerce or
104  * any other agency or department of the United States Government.  In the
105  * event Licensee exports any such software from the United States or
106  * re-exports any such software from a foreign destination, Licensee shall
107  * ensure that the distribution and export/re-export of the software is in
108  * compliance with all laws, regulations, orders, or other restrictions of the
109  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
110  * any of its subsidiaries will export/re-export any technical data, process,
111  * software, or service, directly or indirectly, to any country for which the
112  * United States government or any agency thereof requires an export license,
113  * other governmental approval, or letter of assurance, without first obtaining
114  * such license, approval or letter.
115  *
116  *****************************************************************************/
117
118
119 #include "aslcompiler.h"
120 #include "aslcompiler.y.h"
121 #include "amlcode.h"
122 #include "acparser.h"
123 #include "acnamesp.h"
124
125 #define _COMPONENT          ACPI_COMPILER
126         ACPI_MODULE_NAME    ("aslisting")
127
128
129 /*******************************************************************************
130  *
131  * FUNCTION:    LsDumpAscii
132  *
133  * PARAMETERS:  FileId          - ID of current listing file
134  *              Count           - Number of bytes to convert
135  *              Buffer          - Buffer of bytes to convert
136  *
137  * RETURN:      None.
138  *
139  * DESCRIPTION: Convert hex bytes to ascii
140  *
141  ******************************************************************************/
142
143 void
144 LsDumpAscii (
145     UINT32                  FileId,
146     UINT32                  Count,
147     UINT8                   *Buffer)
148 {
149     UINT8                   BufChar;
150     UINT32                  i;
151
152
153     FlPrintFile (FileId, "    \"");
154     for (i = 0; i < Count; i++)
155     {
156         BufChar = Buffer[i];
157         if (isprint (BufChar))
158         {
159             FlPrintFile (FileId, "%c", BufChar);
160         }
161         else
162         {
163             /* Not a printable character, just put out a dot */
164
165             FlPrintFile (FileId, ".");
166         }
167     }
168     FlPrintFile (FileId, "\"");
169 }
170
171
172 /*******************************************************************************
173  *
174  * FUNCTION:    LsDumpAsciiInComment
175  *
176  * PARAMETERS:  FileId          - ID of current listing file
177  *              Count           - Number of bytes to convert
178  *              Buffer          - Buffer of bytes to convert
179  *
180  * RETURN:      None.
181  *
182  * DESCRIPTION: Convert hex bytes to ascii
183  *
184  ******************************************************************************/
185
186 void
187 LsDumpAsciiInComment (
188     UINT32                  FileId,
189     UINT32                  Count,
190     UINT8                   *Buffer)
191 {
192     UINT8                   BufChar = 0;
193     UINT8                   LastChar;
194     UINT32                  i;
195
196
197     FlPrintFile (FileId, "    \"");
198     for (i = 0; i < Count; i++)
199     {
200         LastChar = BufChar;
201         BufChar = Buffer[i];
202
203         if (isprint (BufChar))
204         {
205             /* Handle embedded C comment sequences */
206
207             if (((LastChar == '*') && (BufChar == '/')) ||
208                 ((LastChar == '/') && (BufChar == '*')))
209             {
210                 /* Insert a space to break the sequence */
211
212                 FlPrintFile (FileId, ".", BufChar);
213             }
214
215             FlPrintFile (FileId, "%c", BufChar);
216         }
217         else
218         {
219             /* Not a printable character, just put out a dot */
220
221             FlPrintFile (FileId, ".");
222         }
223     }
224     FlPrintFile (FileId, "\"");
225 }
226
227
228 /*******************************************************************************
229  *
230  * FUNCTION:    LsAmlListingWalk
231  *
232  * PARAMETERS:  ASL_WALK_CALLBACK
233  *
234  * RETURN:      Status
235  *
236  * DESCRIPTION: Process one node during a listing file generation.
237  *
238  ******************************************************************************/
239
240 ACPI_STATUS
241 LsAmlListingWalk (
242     ACPI_PARSE_OBJECT       *Op,
243     UINT32                  Level,
244     void                    *Context)
245 {
246     UINT8                   FileByte;
247     UINT32                  i;
248     UINT32                  FileId = (UINT32) Context;
249
250
251     LsWriteNodeToListing (Op, FileId);
252
253     /* Write the hex bytes to the listing file(s) (if requested) */
254
255     for (i = 0; i < Op->Asl.FinalAmlLength; i++)
256     {
257         if (ACPI_FAILURE (FlReadFile (ASL_FILE_AML_OUTPUT, &FileByte, 1)))
258         {
259             FlFileError (ASL_FILE_AML_OUTPUT, ASL_MSG_READ);
260             AslAbort ();
261         }
262         LsWriteListingHexBytes (&FileByte, 1, FileId);
263     }
264
265     return (AE_OK);
266 }
267
268
269 /*******************************************************************************
270  *
271  * FUNCTION:    LsGenerateListing
272  *
273  * PARAMETERS:  FileId      - ID of listing file
274  *
275  * RETURN:      None
276  *
277  * DESCRIPTION: Generate a listing file.  This can be one of the several types
278  *              of "listings" supported.
279  *
280  ******************************************************************************/
281
282 void
283 LsGenerateListing (
284     UINT32                  FileId)
285 {
286
287     /* Start at the beginning of both the source and AML files */
288
289     FlSeekFile (ASL_FILE_SOURCE_OUTPUT, 0);
290     FlSeekFile (ASL_FILE_AML_OUTPUT, 0);
291     Gbl_SourceLine = 0;
292     Gbl_CurrentHexColumn = 0;
293     LsPushNode (Gbl_Files[ASL_FILE_INPUT].Filename);
294
295     /* Process all parse nodes */
296
297     TrWalkParseTree (RootNode, ASL_WALK_VISIT_DOWNWARD, LsAmlListingWalk,
298                         NULL, (void *) ACPI_TO_POINTER (FileId));
299
300     /* Final processing */
301
302     LsFinishSourceListing (FileId);
303 }
304
305
306 /*******************************************************************************
307  *
308  * FUNCTION:    LsDoListings
309  *
310  * PARAMETERS:  None.
311  *
312  * RETURN:      None
313  *
314  * DESCRIPTION: Generate all requested listing files.
315  *
316  ******************************************************************************/
317
318 void
319 LsDoListings (void)
320 {
321
322     if (Gbl_C_OutputFlag)
323     {
324         LsGenerateListing (ASL_FILE_C_SOURCE_OUTPUT);
325     }
326
327     if (Gbl_ListingFlag)
328     {
329         LsGenerateListing (ASL_FILE_LISTING_OUTPUT);
330     }
331
332     if (Gbl_AsmOutputFlag)
333     {
334         LsGenerateListing (ASL_FILE_ASM_SOURCE_OUTPUT);
335     }
336
337     if (Gbl_C_IncludeOutputFlag)
338     {
339         LsGenerateListing (ASL_FILE_C_INCLUDE_OUTPUT);
340     }
341
342     if (Gbl_AsmIncludeOutputFlag)
343     {
344         LsGenerateListing (ASL_FILE_ASM_INCLUDE_OUTPUT);
345     }
346 }
347
348
349 /*******************************************************************************
350  *
351  * FUNCTION:    LsPushNode
352  *
353  * PARAMETERS:  Filename        - Pointer to the include filename
354  *
355  * RETURN:      None
356  *
357  * DESCRIPTION: Push a listing node on the listing/include file stack.  This
358  *              stack enables tracking of include files (infinitely nested)
359  *              and resumption of the listing of the parent file when the
360  *              include file is finished.
361  *
362  ******************************************************************************/
363
364 void
365 LsPushNode (
366     char                    *Filename)
367 {
368     ASL_LISTING_NODE        *Lnode;
369
370
371     /* Create a new node */
372
373     Lnode = UtLocalCalloc (sizeof (ASL_LISTING_NODE));
374
375     /* Initialize */
376
377     Lnode->Filename = Filename;
378     Lnode->LineNumber = 0;
379
380     /* Link (push) */
381
382     Lnode->Next = Gbl_ListingNode;
383     Gbl_ListingNode = Lnode;
384 }
385
386
387 /*******************************************************************************
388  *
389  * FUNCTION:    LsPopNode
390  *
391  * PARAMETERS:  None
392  *
393  * RETURN:      List head after current head is popped off
394  *
395  * DESCRIPTION: Pop the current head of the list, free it, and return the
396  *              next node on the stack (the new current node).
397  *
398  ******************************************************************************/
399
400 ASL_LISTING_NODE *
401 LsPopNode (void)
402 {
403     ASL_LISTING_NODE        *Lnode;
404
405
406     /* Just grab the node at the head of the list */
407
408     Lnode = Gbl_ListingNode;
409     if ((!Lnode) ||
410         (!Lnode->Next))
411     {
412         AslError (ASL_ERROR, ASL_MSG_COMPILER_INTERNAL, NULL, "Could not pop empty listing stack");
413         return Gbl_ListingNode;
414     }
415
416     Gbl_ListingNode = Lnode->Next;
417     ACPI_MEM_FREE (Lnode);
418
419     /* New "Current" node is the new head */
420
421     return (Gbl_ListingNode);
422 }
423
424
425 /*******************************************************************************
426  *
427  * FUNCTION:    LsCheckException
428  *
429  * PARAMETERS:  LineNumber          - Current logical (cumulative) line #
430  *              FileId              - ID of output listing file
431  *
432  * RETURN:      None
433  *
434  * DESCRIPTION: Check if there is an exception for this line, and if there is,
435  *              put it in the listing immediately.  Handles multiple errors
436  *              per line.  Gbl_NextError points to the next error in the
437  *              sorted (by line #) list of compile errors/warnings.
438  *
439  ******************************************************************************/
440
441 void
442 LsCheckException (
443     UINT32                  LineNumber,
444     UINT32                  FileId)
445 {
446
447     if ((!Gbl_NextError) ||
448         (LineNumber < Gbl_NextError->LogicalLineNumber ))
449     {
450         return;
451     }
452
453     /* Handle multiple errors per line */
454
455     if (FileId == ASL_FILE_LISTING_OUTPUT)
456     {
457         while (Gbl_NextError &&
458               (LineNumber >= Gbl_NextError->LogicalLineNumber))
459         {
460             AePrintException (FileId, Gbl_NextError, "\n[****iasl****]\n");
461
462             Gbl_NextError = Gbl_NextError->Next;
463         }
464
465         FlPrintFile (FileId, "\n");
466     }
467 }
468
469
470 /*******************************************************************************
471  *
472  * FUNCTION:    LsFlushListingBuffer
473  *
474  * PARAMETERS:  FileId          - ID of the listing file
475  *
476  * RETURN:      None
477  *
478  * DESCRIPTION: Flush out the current contents of the 16-byte hex AML code
479  *              buffer.  Usually called at the termination of a single line
480  *              of source code or when the buffer is full.
481  *
482  ******************************************************************************/
483
484 void
485 LsFlushListingBuffer (
486     UINT32                  FileId)
487 {
488     UINT32                  i;
489
490
491     if (Gbl_CurrentHexColumn == 0)
492     {
493         return;
494     }
495
496     /* Write the hex bytes */
497
498     switch (FileId)
499     {
500     case ASL_FILE_LISTING_OUTPUT:
501
502         for (i = 0; i < Gbl_CurrentHexColumn; i++)
503         {
504             FlPrintFile (FileId, "%2.2X ", Gbl_AmlBuffer[i]);
505         }
506
507         for (i = 0; i < ((HEX_LISTING_LINE_SIZE - Gbl_CurrentHexColumn) * 3); i++)
508         {
509             FlWriteFile (FileId, ".", 1);
510         }
511
512         /* Write the ASCII character associated with each of the bytes */
513
514         LsDumpAscii (FileId, Gbl_CurrentHexColumn, Gbl_AmlBuffer);
515         break;
516
517
518     case ASL_FILE_ASM_SOURCE_OUTPUT:
519
520         for (i = 0; i < Gbl_CurrentHexColumn; i++)
521         {
522             if (i > 0)
523             {
524                 FlPrintFile (FileId, ",");
525             }
526             FlPrintFile (FileId, "0%2.2Xh", Gbl_AmlBuffer[i]);
527         }
528
529         for (i = 0; i < ((HEX_LISTING_LINE_SIZE - Gbl_CurrentHexColumn) * 5); i++)
530         {
531             FlWriteFile (FileId, " ", 1);
532         }
533
534         FlPrintFile (FileId, "  ;%8.8X", Gbl_CurrentAmlOffset - HEX_LISTING_LINE_SIZE);
535
536         /* Write the ASCII character associated with each of the bytes */
537
538         LsDumpAscii (FileId, Gbl_CurrentHexColumn, Gbl_AmlBuffer);
539         break;
540
541
542     case ASL_FILE_C_SOURCE_OUTPUT:
543
544         for (i = 0; i < Gbl_CurrentHexColumn; i++)
545         {
546             FlPrintFile (FileId, "0x%2.2X,", Gbl_AmlBuffer[i]);
547         }
548
549         for (i = 0; i < ((HEX_LISTING_LINE_SIZE - Gbl_CurrentHexColumn) * 5); i++)
550         {
551             FlWriteFile (FileId, " ", 1);
552         }
553
554         FlPrintFile (FileId, "    /* %8.8X", Gbl_CurrentAmlOffset - HEX_LISTING_LINE_SIZE);
555
556         /* Write the ASCII character associated with each of the bytes */
557
558         LsDumpAsciiInComment (FileId, Gbl_CurrentHexColumn, Gbl_AmlBuffer);
559         FlPrintFile (FileId, " */");
560         break;
561
562     default:
563         /* No other types supported */
564         return;
565     }
566
567     FlPrintFile (FileId, "\n");
568
569     Gbl_CurrentHexColumn = 0;
570     Gbl_HexBytesWereWritten = TRUE;
571 }
572
573
574 /*******************************************************************************
575  *
576  * FUNCTION:    LsWriteListingHexBytes
577  *
578  * PARAMETERS:  Buffer          - AML code buffer
579  *              Length          - Number of AML bytes to write
580  *              FileId          - ID of current listing file.
581  *
582  * RETURN:      None
583  *
584  * DESCRIPTION: Write the contents of the AML buffer to the listing file via
585  *              the listing buffer.  The listing buffer is flushed every 16
586  *              AML bytes.
587  *
588  ******************************************************************************/
589
590 void
591 LsWriteListingHexBytes (
592     UINT8                   *Buffer,
593     UINT32                  Length,
594     UINT32                  FileId)
595 {
596     UINT32                  i;
597
598
599     /* Transfer all requested bytes */
600
601     for (i = 0; i < Length; i++)
602     {
603         /* Print line header when buffer is empty */
604
605         if (Gbl_CurrentHexColumn == 0)
606         {
607             if (Gbl_HasIncludeFiles)
608             {
609                 FlPrintFile (FileId, "%*s", 10, " ");
610             }
611
612             switch (FileId)
613             {
614             case ASL_FILE_LISTING_OUTPUT:
615
616                 FlPrintFile (FileId, "%8.8X....", Gbl_CurrentAmlOffset);
617                 break;
618
619             case ASL_FILE_ASM_SOURCE_OUTPUT:
620
621                 FlPrintFile (FileId, "    db ");
622                 break;
623
624             case ASL_FILE_C_SOURCE_OUTPUT:
625
626                 FlPrintFile (FileId, "        ");
627                 break;
628
629             default:
630                 /* No other types supported */
631                 return;
632             }
633         }
634
635         /* Transfer AML byte and update counts */
636
637         Gbl_AmlBuffer[Gbl_CurrentHexColumn] = Buffer[i];
638
639         Gbl_CurrentHexColumn++;
640         Gbl_CurrentAmlOffset++;
641
642         /* Flush buffer when it is full */
643
644         if (Gbl_CurrentHexColumn >= HEX_LISTING_LINE_SIZE)
645         {
646             LsFlushListingBuffer (FileId);
647         }
648     }
649 }
650
651
652 /*******************************************************************************
653  *
654  * FUNCTION:    LsWriteOneSourceLine
655  *
656  * PARAMETERS:  FileID          - ID of current listing file
657  *
658  * RETURN:      FALSE on EOF (input source file), TRUE otherwise
659  *
660  * DESCRIPTION: Read one line from the input source file and echo it to the
661  *              listing file, prefixed with the line number, and if the source
662  *              file contains include files, prefixed with the current filename
663  *
664  ******************************************************************************/
665
666 UINT32
667 LsWriteOneSourceLine (
668     UINT32                  FileId)
669 {
670     UINT8                   FileByte;
671
672
673     Gbl_SourceLine++;
674     Gbl_ListingNode->LineNumber++;
675
676     if (FileId == ASL_FILE_C_SOURCE_OUTPUT)
677     {
678         FlPrintFile (FileId, "     *");
679     }
680     if (FileId == ASL_FILE_ASM_SOURCE_OUTPUT)
681     {
682         FlPrintFile (FileId, "; ");
683     }
684
685     if (Gbl_HasIncludeFiles)
686     {
687         /*
688          * This file contains "include" statements, print the current
689          * filename and line number within the current file
690          */
691         FlPrintFile (FileId, "%12s %5d....",
692                     Gbl_ListingNode->Filename, Gbl_ListingNode->LineNumber);
693     }
694     else
695     {
696         /* No include files, just print the line number */
697
698         FlPrintFile (FileId, "%8d....", Gbl_SourceLine);
699     }
700
701     /* Read one line (up to a newline or EOF) */
702
703     while (FlReadFile (ASL_FILE_SOURCE_OUTPUT, &FileByte, 1) == AE_OK)
704     {
705         if (FileId == ASL_FILE_C_SOURCE_OUTPUT)
706         {
707             if (FileByte == '/')
708             {
709                 FileByte = '*';
710             }
711         }
712
713         FlWriteFile (FileId, &FileByte, 1);
714         if (FileByte == '\n')
715         {
716             /*
717              * Check if an error occurred on this source line during the compile.
718              * If so, we print the error message after the source line.
719              */
720             LsCheckException (Gbl_SourceLine, FileId);
721             return (1);
722         }
723     }
724
725     /* EOF on the input file was reached */
726
727     return (0);
728 }
729
730
731 /*******************************************************************************
732  *
733  * FUNCTION:    LsFinishSourceListing
734  *
735  * PARAMETERS:  FileId          - ID of current listing file.
736  *
737  * RETURN:      None
738  *
739  * DESCRIPTION: Cleanup routine for the listing file.  Flush the hex AML
740  *              listing buffer, and flush out any remaining lines in the
741  *              source input file.
742  *
743  ******************************************************************************/
744
745 void
746 LsFinishSourceListing (
747     UINT32                  FileId)
748 {
749
750     if ((FileId == ASL_FILE_ASM_INCLUDE_OUTPUT) ||
751         (FileId == ASL_FILE_C_INCLUDE_OUTPUT))
752     {
753         return;
754     }
755
756     LsFlushListingBuffer (FileId);
757     Gbl_CurrentAmlOffset = 0;
758
759     /* Flush any remaining text in the source file */
760
761     if (FileId == ASL_FILE_C_SOURCE_OUTPUT)
762     {
763         FlPrintFile (FileId, "    /*\n");
764     }
765
766     while (LsWriteOneSourceLine (FileId))
767     { ; }
768
769     if (FileId == ASL_FILE_C_SOURCE_OUTPUT)
770     {
771         FlPrintFile (FileId, "\n     */\n    };\n");
772     }
773
774     FlPrintFile (FileId, "\n");
775
776     if (FileId == ASL_FILE_LISTING_OUTPUT)
777     {
778         /* Print a summary of the compile exceptions */
779
780         FlPrintFile (FileId, "\n\nSummary of errors and warnings\n\n");
781         AePrintErrorLog (FileId);
782         FlPrintFile (FileId, "\n\n");
783         UtDisplaySummary (FileId);
784         FlPrintFile (FileId, "\n\n");
785     }
786 }
787
788
789 /*******************************************************************************
790  *
791  * FUNCTION:    LsWriteSourceLines
792  *
793  * PARAMETERS:  ToLineNumber            -
794  *              ToLogicalLineNumber     - Write up to this source line number
795  *              FileId                  - ID of current listing file
796  *
797  * RETURN:      None
798  *
799  * DESCRIPTION: Read then write source lines to the listing file until we have
800  *              reached the specified logical (cumulative) line number.  This
801  *              automatically echos out comment blocks and other non-AML
802  *              generating text until we get to the actual AML-generating line
803  *              of ASL code specified by the logical line number.
804  *
805  ******************************************************************************/
806
807 void
808 LsWriteSourceLines (
809     UINT32                  ToLineNumber,
810     UINT32                  ToLogicalLineNumber,
811     UINT32                  FileId)
812 {
813
814     if ((FileId == ASL_FILE_ASM_INCLUDE_OUTPUT) ||
815         (FileId == ASL_FILE_C_INCLUDE_OUTPUT))
816     {
817         return;
818     }
819
820     Gbl_CurrentLine = ToLogicalLineNumber;
821
822     /* Flush any hex bytes remaining from the last opcode */
823
824     LsFlushListingBuffer (FileId);
825
826     /*
827      * Read lines and write them as long as we are not caught up
828      */
829     if (Gbl_SourceLine < Gbl_CurrentLine)
830     {
831         /*
832          * If we just completed writing some AML hex bytes, output a linefeed
833          * to add some whitespace for readability.
834          */
835         if (Gbl_HexBytesWereWritten)
836         {
837             FlPrintFile (FileId, "\n");
838             Gbl_HexBytesWereWritten = FALSE;
839         }
840
841         if (FileId == ASL_FILE_C_SOURCE_OUTPUT)
842         {
843             FlPrintFile (FileId, "    /*\n");
844         }
845
846         /*
847          * Write one line at a time until we have reached the target line #
848          */
849         while ((Gbl_SourceLine < Gbl_CurrentLine) &&
850                 LsWriteOneSourceLine (FileId))
851         { ; }
852
853         if (FileId == ASL_FILE_C_SOURCE_OUTPUT)
854         {
855             FlPrintFile (FileId, "     */");
856         }
857         FlPrintFile (FileId, "\n");
858     }
859 }
860
861
862 /*******************************************************************************
863  *
864  * FUNCTION:    LsWriteNodeToListing
865  *
866  * PARAMETERS:  Op            - Parse node to write to the listing file.
867  *              FileId          - ID of current listing file
868  *
869  * RETURN:      None.
870  *
871  * DESCRIPTION: Write "a node" to the listing file.  This means to
872  *              1) Write out all of the source text associated with the node
873  *              2) Write out all of the AML bytes associated with the node
874  *              3) Write any compiler exceptions associated with the node
875  *
876  ******************************************************************************/
877
878 void
879 LsWriteNodeToListing (
880     ACPI_PARSE_OBJECT       *Op,
881     UINT32                  FileId)
882 {
883     const ACPI_OPCODE_INFO  *OpInfo;
884     UINT32                  OpClass;
885     char                    *Pathname;
886     UINT32                  Length;
887     UINT32                  i;
888
889
890     OpInfo  = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode);
891     OpClass = OpInfo->Class;
892
893     /* TBD: clean this up with a single flag that says: I start a named output block */
894
895     if (FileId == ASL_FILE_C_SOURCE_OUTPUT)
896     {
897         switch (Op->Asl.ParseOpcode)
898         {
899         case PARSEOP_DEFINITIONBLOCK:
900         case PARSEOP_METHODCALL:
901         case PARSEOP_INCLUDE:
902         case PARSEOP_INCLUDE_END:
903         case PARSEOP_DEFAULT_ARG:
904
905             break;
906
907         default:
908             switch (OpClass)
909             {
910             case AML_CLASS_NAMED_OBJECT:
911                 switch (Op->Asl.AmlOpcode)
912                 {
913                 case AML_SCOPE_OP:
914                 case AML_ALIAS_OP:
915                     break;
916
917                 default:
918                     if (Op->Asl.ExternalName)
919                     {
920                         LsFlushListingBuffer (FileId);
921                         FlPrintFile (FileId, "    };\n");
922                     }
923                     break;
924                 }
925                 break;
926
927             default:
928                 /* Don't care about other objects */
929                 break;
930             }
931             break;
932         }
933     }
934
935
936     /* These cases do not have a corresponding AML opcode */
937
938     switch (Op->Asl.ParseOpcode)
939     {
940     case PARSEOP_DEFINITIONBLOCK:
941
942         LsWriteSourceLines (Op->Asl.EndLine, Op->Asl.EndLogicalLine, FileId);
943
944         /* Use the table Signature and TableId to build a unique name */
945
946         if (FileId == ASL_FILE_ASM_SOURCE_OUTPUT)
947         {
948             FlPrintFile (FileId, "%s_%s_Header \\\n",
949                 Gbl_TableSignature, Gbl_TableId);
950         }
951         if (FileId == ASL_FILE_C_SOURCE_OUTPUT)
952         {
953             FlPrintFile (FileId, "    unsigned char    %s_%s_Header [] = \n    {\n",
954                 Gbl_TableSignature, Gbl_TableId);
955         }
956         if (FileId == ASL_FILE_ASM_INCLUDE_OUTPUT)
957         {
958             FlPrintFile (FileId, "extrn %s_%s_Header : byte\n",
959                 Gbl_TableSignature, Gbl_TableId);
960         }
961         if (FileId == ASL_FILE_C_INCLUDE_OUTPUT)
962         {
963             FlPrintFile (FileId, "extern unsigned char    %s_%s_Header [];\n",
964                 Gbl_TableSignature, Gbl_TableId);
965         }
966         return;
967
968
969     case PARSEOP_METHODCALL:
970
971         LsWriteSourceLines (Op->Asl.LineNumber, Op->Asl.LogicalLineNumber, FileId);
972         return;
973
974
975     case PARSEOP_INCLUDE:
976
977         /*
978          * Flush everything up to and including the include source line
979          */
980         LsWriteSourceLines (Op->Asl.LineNumber, Op->Asl.LogicalLineNumber, FileId);
981
982         /*
983          * Create a new listing node and push it
984          */
985         LsPushNode (Op->Asl.Child->Asl.Value.String);
986         return;
987
988
989     case PARSEOP_INCLUDE_END:
990
991         /*
992          * Flush out the rest of the include file
993          */
994         LsWriteSourceLines (Op->Asl.LineNumber, Op->Asl.LogicalLineNumber, FileId);
995
996         /*
997          * Pop off this listing node and go back to the parent file
998          */
999         LsPopNode ();
1000         return;
1001
1002
1003     case PARSEOP_DEFAULT_ARG:
1004         return;
1005
1006
1007     default:
1008         /* All other opcodes have an AML opcode */
1009         break;
1010     }
1011
1012     /*
1013      * Otherwise, we look at the AML opcode because we can
1014      * switch on the opcode type, getting an entire class
1015      * at once
1016      */
1017     switch (OpClass)
1018     {
1019     case AML_CLASS_ARGUMENT:       /* argument type only */
1020     case AML_CLASS_INTERNAL:
1021
1022         break;
1023
1024
1025     case AML_CLASS_NAMED_OBJECT:
1026
1027         switch (Op->Asl.AmlOpcode)
1028         {
1029         case AML_FIELD_OP:
1030         case AML_INDEX_FIELD_OP:
1031         case AML_BANK_FIELD_OP:
1032         case AML_NAME_OP:
1033
1034             /* For fields, we want to dump all the AML after the entire definition */
1035
1036             LsWriteSourceLines (Op->Asl.EndLine, Op->Asl.EndLogicalLine, FileId);
1037             break;
1038
1039         default:
1040             LsWriteSourceLines (Op->Asl.LineNumber, Op->Asl.LogicalLineNumber, FileId);
1041             break;
1042         }
1043
1044         switch (Op->Asl.AmlOpcode)
1045         {
1046         case AML_SCOPE_OP:
1047         case AML_ALIAS_OP:
1048
1049             /* These opcodes do not declare a new object, ignore them */
1050
1051             break;
1052
1053         default:
1054
1055             /* All other named object opcodes come here */
1056
1057             switch (FileId)
1058             {
1059             case ASL_FILE_ASM_SOURCE_OUTPUT:
1060             case ASL_FILE_C_SOURCE_OUTPUT:
1061             case ASL_FILE_ASM_INCLUDE_OUTPUT:
1062             case ASL_FILE_C_INCLUDE_OUTPUT:
1063
1064                 /*
1065                  * For named objects, we will create a valid symbol so that the
1066                  * AML code can be referenced from C or ASM
1067                  */
1068                 if (Op->Asl.ExternalName)
1069                 {
1070                     /* Get the full pathname associated with this node */
1071
1072                     Pathname = AcpiNsGetExternalPathname (Op->Asl.Node);
1073                     Length = strlen (Pathname);
1074                     if (Length >= 4)
1075                     {
1076                         /* Convert all dots in the path to underscores */
1077
1078                         for (i = 0; i < Length; i++)
1079                         {
1080                             if (Pathname[i] == '.')
1081                             {
1082                                 Pathname[i] = '_';
1083                             }
1084                         }
1085
1086                         /* Create the appropriate symbol in the output file */
1087
1088                         if (FileId == ASL_FILE_ASM_SOURCE_OUTPUT)
1089                         {
1090                             FlPrintFile (FileId, "%s_%s_%s  \\\n",
1091                                 Gbl_TableSignature, Gbl_TableId, &Pathname[1]);
1092                         }
1093                         if (FileId == ASL_FILE_C_SOURCE_OUTPUT)
1094                         {
1095                             FlPrintFile (FileId, "    unsigned char    %s_%s_%s [] = \n    {\n",
1096                                 Gbl_TableSignature, Gbl_TableId, &Pathname[1]);
1097                         }
1098                         if (FileId == ASL_FILE_ASM_INCLUDE_OUTPUT)
1099                         {
1100                             FlPrintFile (FileId, "extrn %s_%s_%s : byte\n",
1101                                 Gbl_TableSignature, Gbl_TableId, &Pathname[1]);
1102                         }
1103                         if (FileId == ASL_FILE_C_INCLUDE_OUTPUT)
1104                         {
1105                             FlPrintFile (FileId, "extern unsigned char    %s_%s_%s [];\n",
1106                                 Gbl_TableSignature, Gbl_TableId, &Pathname[1]);
1107                         }
1108                     }
1109                     ACPI_MEM_FREE (Pathname);
1110                 }
1111                 break;
1112
1113             default:
1114                 /* Nothing to do for listing file */
1115                 break;
1116             }
1117         }
1118         break;
1119
1120     case AML_CLASS_EXECUTE:
1121     case AML_CLASS_CREATE:
1122     default:
1123
1124         LsWriteSourceLines (Op->Asl.LineNumber, Op->Asl.LogicalLineNumber, FileId);
1125         break;
1126
1127     case AML_CLASS_UNKNOWN:
1128         break;
1129     }
1130 }
1131
1132
1133 /*******************************************************************************
1134  *
1135  * FUNCTION:    LsDoHexOutput
1136  *
1137  * PARAMETERS:  None
1138  *
1139  * RETURN:      None.
1140  *
1141  * DESCRIPTION: Create the hex output file.
1142  *
1143  ******************************************************************************/
1144
1145 void
1146 LsDoHexOutput (void)
1147 {
1148
1149     switch (Gbl_HexOutputFlag)
1150     {
1151     case HEX_OUTPUT_C:
1152
1153         LsDoHexOutputC ();
1154         break;
1155
1156     case HEX_OUTPUT_ASM:
1157
1158         LsDoHexOutputAsm ();
1159         break;
1160
1161     default:
1162         /* No other output types supported */
1163         break;
1164     }
1165 }
1166
1167
1168 /*******************************************************************************
1169  *
1170  * FUNCTION:    LsDoHexOutputC
1171  *
1172  * PARAMETERS:  None
1173  *
1174  * RETURN:      None.
1175  *
1176  * DESCRIPTION: Create the hex output file.  This is the same data as the AML
1177  *              output file, but formatted into hex/ascii bytes suitable for
1178  *              inclusion into a C source file.
1179  *
1180  ******************************************************************************/
1181
1182 void
1183 LsDoHexOutputC (void)
1184 {
1185     UINT32                  j;
1186     UINT8                   FileByte[HEX_TABLE_LINE_SIZE];
1187     UINT8                   Buffer[4];
1188     UINT32                  Offset = 0;
1189
1190
1191     FlPrintFile (ASL_FILE_HEX_OUTPUT, " * C source code output\n *\n */\n");
1192     FlPrintFile (ASL_FILE_HEX_OUTPUT, "unsigned char AmlCode[] = \n{\n");
1193
1194     /* Start at the beginning of the AML file */
1195
1196     FlSeekFile (ASL_FILE_AML_OUTPUT, 0);
1197
1198     /* Process all AML bytes in the AML file */
1199
1200     j = 0;
1201     while (FlReadFile (ASL_FILE_AML_OUTPUT, &FileByte[j], 1) == AE_OK)
1202     {
1203         if (j == 0)
1204         {
1205             FlPrintFile (ASL_FILE_HEX_OUTPUT, "    ");
1206         }
1207
1208         /*
1209          * Convert each AML byte to hex
1210          */
1211         UtConvertByteToHex (FileByte[j], Buffer);
1212         FlWriteFile (ASL_FILE_HEX_OUTPUT, Buffer, 4);
1213         FlPrintFile (ASL_FILE_HEX_OUTPUT, ",");
1214
1215         /* An occasional linefeed improves readability */
1216
1217         Offset++;
1218         j++;
1219
1220         if (j >= HEX_TABLE_LINE_SIZE)
1221         {
1222             /* End of line, emit the ascii dump of the entire line */
1223
1224             FlPrintFile (ASL_FILE_HEX_OUTPUT, "  /* %8.8X", Offset - HEX_TABLE_LINE_SIZE);
1225
1226             /* Write the ASCII character associated with each of the bytes */
1227
1228             LsDumpAsciiInComment (ASL_FILE_HEX_OUTPUT, HEX_TABLE_LINE_SIZE, FileByte);
1229             FlPrintFile (ASL_FILE_HEX_OUTPUT, " */\n");
1230
1231             /* Start new line */
1232
1233             j = 0;
1234         }
1235
1236     }
1237
1238     FlPrintFile (ASL_FILE_HEX_OUTPUT, "\n};\n");
1239     FlCloseFile (ASL_FILE_HEX_OUTPUT);
1240 }
1241
1242
1243 /*******************************************************************************
1244  *
1245  * FUNCTION:    LsDoHexOutputAsm
1246  *
1247  * PARAMETERS:  None
1248  *
1249  * RETURN:      None.
1250  *
1251  * DESCRIPTION: Create the hex output file.  This is the same data as the AML
1252  *              output file, but formatted into hex/ascii bytes suitable for
1253  *              inclusion into a ASM source file.
1254  *
1255  ******************************************************************************/
1256
1257 void
1258 LsDoHexOutputAsm (
1259     void)
1260 {
1261     UINT32                  j;
1262     UINT8                   FileByte[HEX_TABLE_LINE_SIZE];
1263     UINT8                   Buffer[4];
1264     UINT32                  Offset = 0;
1265     BOOLEAN                 DoComma = FALSE;
1266
1267
1268     FlPrintFile (ASL_FILE_HEX_OUTPUT, "; Assembly code source output\n;\n");
1269
1270     /* Start at the beginning of the AML file */
1271
1272     FlSeekFile (ASL_FILE_AML_OUTPUT, 0);
1273
1274     /* Process all AML bytes in the AML file */
1275
1276     j = 0;
1277     while (FlReadFile (ASL_FILE_AML_OUTPUT, &FileByte[j], 1) == AE_OK)
1278     {
1279         if (j == 0)
1280         {
1281             FlPrintFile (ASL_FILE_HEX_OUTPUT, "  db  ");
1282         }
1283         else if (DoComma)
1284         {
1285             FlPrintFile (ASL_FILE_HEX_OUTPUT, ",");
1286             DoComma = FALSE;
1287         }
1288
1289         /*
1290          * Convert each AML byte to hex
1291          */
1292         UtConvertByteToAsmHex (FileByte[j], Buffer);
1293         FlWriteFile (ASL_FILE_HEX_OUTPUT, Buffer, 4);
1294
1295         /* An occasional linefeed improves readability */
1296
1297         Offset++;
1298         j++;
1299         if (j >= HEX_TABLE_LINE_SIZE)
1300         {
1301             FlPrintFile (ASL_FILE_HEX_OUTPUT, "  ;%8.8X", Offset - HEX_TABLE_LINE_SIZE);
1302
1303             /* Write the ASCII character associated with each of the bytes */
1304
1305             LsDumpAscii (ASL_FILE_HEX_OUTPUT, HEX_TABLE_LINE_SIZE, FileByte);
1306             FlPrintFile (ASL_FILE_HEX_OUTPUT, "\n");
1307             j = 0;
1308         }
1309         else
1310         {
1311             DoComma = TRUE;
1312         }
1313     }
1314
1315     FlPrintFile (ASL_FILE_HEX_OUTPUT, "\n");
1316     FlCloseFile (ASL_FILE_HEX_OUTPUT);
1317 }
1318
1319