aslcompile.c revision 217365
1
2/******************************************************************************
3 *
4 * Module Name: aslcompile - top level compile module
5 *
6 *****************************************************************************/
7
8/*
9 * Copyright (C) 2000 - 2011, Intel Corp.
10 * All rights reserved.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 *    notice, this list of conditions, and the following disclaimer,
17 *    without modification.
18 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
19 *    substantially similar to the "NO WARRANTY" disclaimer below
20 *    ("Disclaimer") and any redistribution must be conditioned upon
21 *    including a substantially similar Disclaimer requirement for further
22 *    binary redistribution.
23 * 3. Neither the names of the above-listed copyright holders nor the names
24 *    of any contributors may be used to endorse or promote products derived
25 *    from this software without specific prior written permission.
26 *
27 * Alternatively, this software may be distributed under the terms of the
28 * GNU General Public License ("GPL") version 2 as published by the Free
29 * Software Foundation.
30 *
31 * NO WARRANTY
32 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
35 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
36 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
41 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42 * POSSIBILITY OF SUCH DAMAGES.
43 */
44
45#include <contrib/dev/acpica/compiler/aslcompiler.h>
46
47#include <stdio.h>
48#include <time.h>
49#include <contrib/dev/acpica/include/acapps.h>
50
51#define _COMPONENT          ACPI_COMPILER
52        ACPI_MODULE_NAME    ("aslcompile")
53
54/* Local prototypes */
55
56static void
57CmFlushSourceCode (
58    void);
59
60static void
61FlConsumeAnsiComment (
62    ASL_FILE_INFO           *FileInfo,
63    ASL_FILE_STATUS         *Status);
64
65static void
66FlConsumeNewComment (
67    ASL_FILE_INFO           *FileInfo,
68    ASL_FILE_STATUS         *Status);
69
70
71/*******************************************************************************
72 *
73 * FUNCTION:    AslCompilerSignon
74 *
75 * PARAMETERS:  FileId      - ID of the output file
76 *
77 * RETURN:      None
78 *
79 * DESCRIPTION: Display compiler signon
80 *
81 ******************************************************************************/
82
83void
84AslCompilerSignon (
85    UINT32                  FileId)
86{
87    char                    *Prefix = "";
88    char                    *UtilityName;
89
90
91    /* Set line prefix depending on the destination file type */
92
93    switch (FileId)
94    {
95    case ASL_FILE_ASM_SOURCE_OUTPUT:
96    case ASL_FILE_ASM_INCLUDE_OUTPUT:
97
98        Prefix = "; ";
99        break;
100
101    case ASL_FILE_HEX_OUTPUT:
102
103        if (Gbl_HexOutputFlag == HEX_OUTPUT_ASM)
104        {
105            Prefix = "; ";
106        }
107        else if ((Gbl_HexOutputFlag == HEX_OUTPUT_C) ||
108                 (Gbl_HexOutputFlag == HEX_OUTPUT_ASL))
109        {
110            FlPrintFile (ASL_FILE_HEX_OUTPUT, "/*\n");
111            Prefix = " * ";
112        }
113        break;
114
115    case ASL_FILE_C_SOURCE_OUTPUT:
116    case ASL_FILE_C_INCLUDE_OUTPUT:
117
118        Prefix = " * ";
119        break;
120
121    default:
122        /* No other output types supported */
123        break;
124    }
125
126    /* Running compiler or disassembler? */
127
128    if (Gbl_DisasmFlag)
129    {
130        UtilityName = AML_DISASSEMBLER_NAME;
131    }
132    else
133    {
134        UtilityName = ASL_COMPILER_NAME;
135    }
136
137    /* Compiler signon with copyright */
138
139    FlPrintFile (FileId, "%s\n", Prefix);
140    FlPrintFile (FileId, ACPI_COMMON_HEADER (UtilityName, Prefix));
141}
142
143
144/*******************************************************************************
145 *
146 * FUNCTION:    AslCompilerFileHeader
147 *
148 * PARAMETERS:  FileId      - ID of the output file
149 *
150 * RETURN:      None
151 *
152 * DESCRIPTION: Header used at the beginning of output files
153 *
154 ******************************************************************************/
155
156void
157AslCompilerFileHeader (
158    UINT32                  FileId)
159{
160    struct tm               *NewTime;
161    time_t                  Aclock;
162    char                    *Prefix = "";
163
164
165    /* Set line prefix depending on the destination file type */
166
167    switch (FileId)
168    {
169    case ASL_FILE_ASM_SOURCE_OUTPUT:
170    case ASL_FILE_ASM_INCLUDE_OUTPUT:
171
172        Prefix = "; ";
173        break;
174
175    case ASL_FILE_HEX_OUTPUT:
176
177        if (Gbl_HexOutputFlag == HEX_OUTPUT_ASM)
178        {
179            Prefix = "; ";
180        }
181        else if ((Gbl_HexOutputFlag == HEX_OUTPUT_C) ||
182                 (Gbl_HexOutputFlag == HEX_OUTPUT_ASL))
183        {
184            Prefix = " * ";
185        }
186        break;
187
188    case ASL_FILE_C_SOURCE_OUTPUT:
189    case ASL_FILE_C_INCLUDE_OUTPUT:
190
191        Prefix = " * ";
192        break;
193
194    default:
195        /* No other output types supported */
196        break;
197    }
198
199    /* Compilation header with timestamp */
200
201    (void) time (&Aclock);
202    NewTime = localtime (&Aclock);
203
204    FlPrintFile (FileId,
205        "%sCompilation of \"%s\" - %s%s\n",
206        Prefix, Gbl_Files[ASL_FILE_INPUT].Filename, asctime (NewTime),
207        Prefix);
208
209    switch (FileId)
210    {
211    case ASL_FILE_C_SOURCE_OUTPUT:
212    case ASL_FILE_C_INCLUDE_OUTPUT:
213        FlPrintFile (FileId, " */\n");
214        break;
215
216    default:
217        /* Nothing to do for other output types */
218        break;
219    }
220}
221
222
223/*******************************************************************************
224 *
225 * FUNCTION:    CmFlushSourceCode
226 *
227 * PARAMETERS:  None
228 *
229 * RETURN:      None
230 *
231 * DESCRIPTION: Read in any remaining source code after the parse tree
232 *              has been constructed.
233 *
234 ******************************************************************************/
235
236static void
237CmFlushSourceCode (
238    void)
239{
240    char                    Buffer;
241
242
243    while (FlReadFile (ASL_FILE_INPUT, &Buffer, 1) != AE_ERROR)
244    {
245        InsertLineBuffer ((int) Buffer);
246    }
247
248    ResetCurrentLineBuffer ();
249}
250
251
252/*******************************************************************************
253 *
254 * FUNCTION:    FlConsume*
255 *
256 * PARAMETERS:  FileInfo        - Points to an open input file
257 *
258 * RETURN:      Number of lines consumed
259 *
260 * DESCRIPTION: Step over both types of comment during check for ascii chars
261 *
262 ******************************************************************************/
263
264static void
265FlConsumeAnsiComment (
266    ASL_FILE_INFO           *FileInfo,
267    ASL_FILE_STATUS         *Status)
268{
269    UINT8                   Byte;
270    BOOLEAN                 ClosingComment = FALSE;
271
272
273    while (fread (&Byte, 1, 1, FileInfo->Handle))
274    {
275        /* Scan until comment close is found */
276
277        if (ClosingComment)
278        {
279            if (Byte == '/')
280            {
281                return;
282            }
283
284            if (Byte != '*')
285            {
286                /* Reset */
287
288                ClosingComment = FALSE;
289            }
290        }
291        else if (Byte == '*')
292        {
293            ClosingComment = TRUE;
294        }
295
296        /* Maintain line count */
297
298        if (Byte == 0x0A)
299        {
300            Status->Line++;
301        }
302
303        Status->Offset++;
304    }
305}
306
307
308static void
309FlConsumeNewComment (
310    ASL_FILE_INFO           *FileInfo,
311    ASL_FILE_STATUS         *Status)
312{
313    UINT8                   Byte;
314
315
316    while (fread (&Byte, 1, 1, FileInfo->Handle))
317    {
318        Status->Offset++;
319
320        /* Comment ends at newline */
321
322        if (Byte == 0x0A)
323        {
324            Status->Line++;
325            return;
326        }
327    }
328}
329
330
331/*******************************************************************************
332 *
333 * FUNCTION:    FlCheckForAscii
334 *
335 * PARAMETERS:  FileInfo        - Points to an open input file
336 *
337 * RETURN:      Status
338 *
339 * DESCRIPTION: Verify that the input file is entirely ASCII. Ignores characters
340 *              within comments. Note: does not handle nested comments and does
341 *              not handle comment delimiters within string literals. However,
342 *              on the rare chance this happens and an invalid character is
343 *              missed, the parser will catch the error by failing in some
344 *              spectactular manner.
345 *
346 ******************************************************************************/
347
348ACPI_STATUS
349FlCheckForAscii (
350    ASL_FILE_INFO           *FileInfo)
351{
352    UINT8                   Byte;
353    ACPI_SIZE               BadBytes = 0;
354    BOOLEAN                 OpeningComment = FALSE;
355    ASL_FILE_STATUS         Status;
356
357
358    Status.Line = 1;
359    Status.Offset = 0;
360
361    /* Read the entire file */
362
363    while (fread (&Byte, 1, 1, FileInfo->Handle))
364    {
365        /* Ignore comment fields (allow non-ascii within) */
366
367        if (OpeningComment)
368        {
369            /* Check for second comment open delimiter */
370
371            if (Byte == '*')
372            {
373                FlConsumeAnsiComment (FileInfo, &Status);
374            }
375
376            if (Byte == '/')
377            {
378                FlConsumeNewComment (FileInfo, &Status);
379            }
380
381            /* Reset */
382
383            OpeningComment = FALSE;
384        }
385        else if (Byte == '/')
386        {
387            OpeningComment = TRUE;
388        }
389
390        /* Check for an ASCII character */
391
392        if (!ACPI_IS_ASCII (Byte))
393        {
394            if (BadBytes < 10)
395            {
396                AcpiOsPrintf (
397                    "Non-ASCII character [0x%2.2X] found in line %u, file offset 0x%.2X\n",
398                    Byte, Status.Line, Status.Offset);
399            }
400
401            BadBytes++;
402        }
403
404        /* Update line counter */
405
406        else if (Byte == 0x0A)
407        {
408            Status.Line++;
409        }
410
411        Status.Offset++;
412    }
413
414    /* Seek back to the beginning of the source file */
415
416    fseek (FileInfo->Handle, 0, SEEK_SET);
417
418    /* Were there any non-ASCII characters in the file? */
419
420    if (BadBytes)
421    {
422        AcpiOsPrintf (
423            "%u non-ASCII characters found in input source text, could be a binary file\n",
424            BadBytes);
425        AslError (ASL_ERROR, ASL_MSG_NON_ASCII, NULL, FileInfo->Filename);
426        return (AE_BAD_CHARACTER);
427    }
428
429    /* File is OK */
430
431    return (AE_OK);
432}
433
434
435/*******************************************************************************
436 *
437 * FUNCTION:    CmDoCompile
438 *
439 * PARAMETERS:  None
440 *
441 * RETURN:      Status (0 = OK)
442 *
443 * DESCRIPTION: This procedure performs the entire compile
444 *
445 ******************************************************************************/
446
447int
448CmDoCompile (
449    void)
450{
451    ACPI_STATUS             Status;
452    UINT8                   FullCompile;
453    UINT8                   Event;
454
455
456    FullCompile = UtBeginEvent ("*** Total Compile time ***");
457    Event = UtBeginEvent ("Open input and output files");
458    UtEndEvent (Event);
459
460    /* Build the parse tree */
461
462    Event = UtBeginEvent ("Parse source code and build parse tree");
463    AslCompilerparse();
464    UtEndEvent (Event);
465
466    /* Flush out any remaining source after parse tree is complete */
467
468    Event = UtBeginEvent ("Flush source input");
469    CmFlushSourceCode ();
470
471    /* Did the parse tree get successfully constructed? */
472
473    if (!RootNode)
474    {
475        CmCleanupAndExit ();
476        return -1;
477    }
478
479    /* Optional parse tree dump, compiler debug output only */
480
481    LsDumpParseTree ();
482
483    OpcGetIntegerWidth (RootNode);
484    UtEndEvent (Event);
485
486    /* Pre-process parse tree for any operator transforms */
487
488    Event = UtBeginEvent ("Parse tree transforms");
489    DbgPrint (ASL_DEBUG_OUTPUT, "\nParse tree transforms\n\n");
490    TrWalkParseTree (RootNode, ASL_WALK_VISIT_DOWNWARD,
491        TrAmlTransformWalk, NULL, NULL);
492    UtEndEvent (Event);
493
494    /* Generate AML opcodes corresponding to the parse tokens */
495
496    Event = UtBeginEvent ("Generate AML opcodes");
497    DbgPrint (ASL_DEBUG_OUTPUT, "\nGenerating AML opcodes\n\n");
498    TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD, NULL,
499        OpcAmlOpcodeWalk, NULL);
500    UtEndEvent (Event);
501
502    /*
503     * Now that the input is parsed, we can open the AML output file.
504     * Note: by default, the name of this file comes from the table descriptor
505     * within the input file.
506     */
507    Event = UtBeginEvent ("Open AML output file");
508    Status = FlOpenAmlOutputFile (Gbl_OutputFilenamePrefix);
509    if (ACPI_FAILURE (Status))
510    {
511        AePrintErrorLog (ASL_FILE_STDERR);
512        return -1;
513    }
514    UtEndEvent (Event);
515
516    /* Interpret and generate all compile-time constants */
517
518    Event = UtBeginEvent ("Constant folding via AML interpreter");
519    DbgPrint (ASL_DEBUG_OUTPUT,
520        "\nInterpreting compile-time constant expressions\n\n");
521    TrWalkParseTree (RootNode, ASL_WALK_VISIT_DOWNWARD,
522        OpcAmlConstantWalk, NULL, NULL);
523    UtEndEvent (Event);
524
525    /* Update AML opcodes if necessary, after constant folding */
526
527    Event = UtBeginEvent ("Updating AML opcodes after constant folding");
528    DbgPrint (ASL_DEBUG_OUTPUT,
529        "\nUpdating AML opcodes after constant folding\n\n");
530    TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD,
531        NULL, OpcAmlOpcodeUpdateWalk, NULL);
532    UtEndEvent (Event);
533
534    /* Calculate all AML package lengths */
535
536    Event = UtBeginEvent ("Generate AML package lengths");
537    DbgPrint (ASL_DEBUG_OUTPUT, "\nGenerating Package lengths\n\n");
538    TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD, NULL,
539        LnPackageLengthWalk, NULL);
540    UtEndEvent (Event);
541
542    if (Gbl_ParseOnlyFlag)
543    {
544        AePrintErrorLog (ASL_FILE_STDOUT);
545        UtDisplaySummary (ASL_FILE_STDOUT);
546        if (Gbl_DebugFlag)
547        {
548            /* Print error summary to the debug file */
549
550            AePrintErrorLog (ASL_FILE_STDERR);
551            UtDisplaySummary (ASL_FILE_STDERR);
552        }
553        return 0;
554    }
555
556    /*
557     * Create an internal namespace and use it as a symbol table
558     */
559
560    /* Namespace loading */
561
562    Event = UtBeginEvent ("Create ACPI Namespace");
563    Status = LdLoadNamespace (RootNode);
564    UtEndEvent (Event);
565    if (ACPI_FAILURE (Status))
566    {
567        return -1;
568    }
569
570    /* Namespace cross-reference */
571
572    AslGbl_NamespaceEvent = UtBeginEvent ("Cross reference parse tree and Namespace");
573    Status = LkCrossReferenceNamespace ();
574    if (ACPI_FAILURE (Status))
575    {
576        return -1;
577    }
578
579    /* Namespace - Check for non-referenced objects */
580
581    LkFindUnreferencedObjects ();
582    UtEndEvent (AslGbl_NamespaceEvent);
583
584    /*
585     * Semantic analysis.  This can happen only after the
586     * namespace has been loaded and cross-referenced.
587     *
588     * part one - check control methods
589     */
590    Event = UtBeginEvent ("Analyze control method return types");
591    AnalysisWalkInfo.MethodStack = NULL;
592
593    DbgPrint (ASL_DEBUG_OUTPUT, "\nSemantic analysis - Method analysis\n\n");
594    TrWalkParseTree (RootNode, ASL_WALK_VISIT_TWICE,
595        AnMethodAnalysisWalkBegin,
596        AnMethodAnalysisWalkEnd, &AnalysisWalkInfo);
597    UtEndEvent (Event);
598
599    /* Semantic error checking part two - typing of method returns */
600
601    Event = UtBeginEvent ("Determine object types returned by methods");
602    DbgPrint (ASL_DEBUG_OUTPUT, "\nSemantic analysis - Method typing\n\n");
603    TrWalkParseTree (RootNode, ASL_WALK_VISIT_TWICE,
604        AnMethodTypingWalkBegin,
605        AnMethodTypingWalkEnd, NULL);
606    UtEndEvent (Event);
607
608    /* Semantic error checking part three - operand type checking */
609
610    Event = UtBeginEvent ("Analyze AML operand types");
611    DbgPrint (ASL_DEBUG_OUTPUT, "\nSemantic analysis - Operand type checking\n\n");
612    TrWalkParseTree (RootNode, ASL_WALK_VISIT_TWICE,
613        AnOperandTypecheckWalkBegin,
614        AnOperandTypecheckWalkEnd, &AnalysisWalkInfo);
615    UtEndEvent (Event);
616
617    /* Semantic error checking part four - other miscellaneous checks */
618
619    Event = UtBeginEvent ("Miscellaneous analysis");
620    DbgPrint (ASL_DEBUG_OUTPUT, "\nSemantic analysis - miscellaneous\n\n");
621    TrWalkParseTree (RootNode, ASL_WALK_VISIT_TWICE,
622        AnOtherSemanticAnalysisWalkBegin,
623        AnOtherSemanticAnalysisWalkEnd, &AnalysisWalkInfo);
624    UtEndEvent (Event);
625
626    /* Calculate all AML package lengths */
627
628    Event = UtBeginEvent ("Finish AML package length generation");
629    DbgPrint (ASL_DEBUG_OUTPUT, "\nGenerating Package lengths\n\n");
630    TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD, NULL,
631        LnInitLengthsWalk, NULL);
632    TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD, NULL,
633        LnPackageLengthWalk, NULL);
634    UtEndEvent (Event);
635
636    /* Code generation - emit the AML */
637
638    Event = UtBeginEvent ("Generate AML code and write output files");
639    CgGenerateAmlOutput ();
640    UtEndEvent (Event);
641
642    Event = UtBeginEvent ("Write optional output files");
643    CmDoOutputFiles ();
644    UtEndEvent (Event);
645
646    UtEndEvent (FullCompile);
647    CmCleanupAndExit ();
648    return 0;
649}
650
651
652/*******************************************************************************
653 *
654 * FUNCTION:    CmDoOutputFiles
655 *
656 * PARAMETERS:  None
657 *
658 * RETURN:      None.
659 *
660 * DESCRIPTION: Create all "listing" type files
661 *
662 ******************************************************************************/
663
664void
665CmDoOutputFiles (
666    void)
667{
668
669    /* Create listings and hex files */
670
671    LsDoListings ();
672    LsDoHexOutput ();
673
674    /* Dump the namespace to the .nsp file if requested */
675
676    (void) LsDisplayNamespace ();
677}
678
679
680/*******************************************************************************
681 *
682 * FUNCTION:    CmDumpEvent
683 *
684 * PARAMETERS:  Event           - A compiler event struct
685 *
686 * RETURN:      None.
687 *
688 * DESCRIPTION: Dump a compiler event struct
689 *
690 ******************************************************************************/
691
692static void
693CmDumpEvent (
694    ASL_EVENT_INFO          *Event)
695{
696    UINT32                  Delta;
697    UINT32                  USec;
698    UINT32                  MSec;
699
700    if (!Event->Valid)
701    {
702        return;
703    }
704
705    /* Delta will be in 100-nanosecond units */
706
707    Delta = (UINT32) (Event->EndTime - Event->StartTime);
708
709    USec = Delta / 10;
710    MSec = Delta / 10000;
711
712    /* Round milliseconds up */
713
714    if ((USec - (MSec * 1000)) >= 500)
715    {
716        MSec++;
717    }
718
719    DbgPrint (ASL_DEBUG_OUTPUT, "%8u usec %8u msec - %s\n",
720        USec, MSec, Event->EventName);
721}
722
723
724/*******************************************************************************
725 *
726 * FUNCTION:    CmCleanupAndExit
727 *
728 * PARAMETERS:  None
729 *
730 * RETURN:      None.
731 *
732 * DESCRIPTION: Close all open files and exit the compiler
733 *
734 ******************************************************************************/
735
736void
737CmCleanupAndExit (
738    void)
739{
740    UINT32                  i;
741
742
743    AePrintErrorLog (ASL_FILE_STDOUT);
744    if (Gbl_DebugFlag)
745    {
746        /* Print error summary to the debug file */
747
748        AePrintErrorLog (ASL_FILE_STDERR);
749    }
750
751    DbgPrint (ASL_DEBUG_OUTPUT, "\n\nElapsed time for major events\n\n");
752    for (i = 0; i < AslGbl_NextEvent; i++)
753    {
754        CmDumpEvent (&AslGbl_Events[i]);
755    }
756
757    if (Gbl_CompileTimesFlag)
758    {
759        printf ("\nElapsed time for major events\n\n");
760        for (i = 0; i < AslGbl_NextEvent; i++)
761        {
762            CmDumpEvent (&AslGbl_Events[i]);
763        }
764
765        printf ("\nMiscellaneous compile statistics\n\n");
766        printf ("%11u : %s\n", TotalParseNodes, "Parse nodes");
767        printf ("%11u : %s\n", Gbl_NsLookupCount, "Namespace searches");
768        printf ("%11u : %s\n", TotalNamedObjects, "Named objects");
769        printf ("%11u : %s\n", TotalMethods, "Control methods");
770        printf ("%11u : %s\n", TotalAllocations, "Memory Allocations");
771        printf ("%11u : %s\n", TotalAllocated, "Total allocated memory");
772        printf ("%11u : %s\n", TotalFolds, "Constant subtrees folded");
773        printf ("\n");
774    }
775
776    if (Gbl_NsLookupCount)
777    {
778        DbgPrint (ASL_DEBUG_OUTPUT,
779            "\n\nMiscellaneous compile statistics\n\n");
780
781        DbgPrint (ASL_DEBUG_OUTPUT,
782            "%32s : %u\n", "Total Namespace searches",
783            Gbl_NsLookupCount);
784
785        DbgPrint (ASL_DEBUG_OUTPUT,
786            "%32s : %u usec\n", "Time per search", ((UINT32)
787            (AslGbl_Events[AslGbl_NamespaceEvent].EndTime -
788                AslGbl_Events[AslGbl_NamespaceEvent].StartTime) / 10) /
789                Gbl_NsLookupCount);
790    }
791
792    if (Gbl_ExceptionCount[ASL_ERROR] > ASL_MAX_ERROR_COUNT)
793    {
794        printf ("\nMaximum error count (%u) exceeded\n",
795            ASL_MAX_ERROR_COUNT);
796    }
797
798    UtDisplaySummary (ASL_FILE_STDOUT);
799
800    /* Close all open files */
801
802    for (i = 2; i < ASL_MAX_FILE_TYPE; i++)
803    {
804        FlCloseFile (i);
805    }
806
807    /* Delete AML file if there are errors */
808
809    if ((Gbl_ExceptionCount[ASL_ERROR] > 0) && (!Gbl_IgnoreErrors) &&
810        Gbl_Files[ASL_FILE_AML_OUTPUT].Handle)
811    {
812        if (remove (Gbl_Files[ASL_FILE_AML_OUTPUT].Filename))
813        {
814            printf ("%s: ",
815                Gbl_Files[ASL_FILE_AML_OUTPUT].Filename);
816            perror ("Could not delete AML file");
817        }
818    }
819
820    /*
821     * Delete intermediate ("combined") source file (if -ls flag not set)
822     * This file is created during normal ASL/AML compiles. It is not
823     * created by the data table compiler.
824     *
825     * If the -ls flag is set, then the .SRC file should not be deleted.
826     * In this case, Gbl_SourceOutputFlag is set to TRUE.
827     *
828     * Note: Handles are cleared by FlCloseFile above, so we look at the
829     * filename instead, to determine if the .SRC file was actually
830     * created.
831     *
832     * TBD: SourceOutput should be .TMP, then rename if we want to keep it?
833     */
834    if (!Gbl_SourceOutputFlag && Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Filename)
835    {
836        if (remove (Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Filename))
837        {
838            printf ("%s: ",
839                Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Filename);
840            perror ("Could not delete SRC file");
841        }
842    }
843}
844
845
846