1/******************************************************************************
2 *
3 * Module Name: aslerror - Error handling and statistics
4 *
5 *****************************************************************************/
6
7/******************************************************************************
8 *
9 * 1. Copyright Notice
10 *
11 * Some or all of this work - Copyright (c) 1999 - 2023, Intel Corp.
12 * All rights reserved.
13 *
14 * 2. License
15 *
16 * 2.1. This is your license from Intel Corp. under its intellectual property
17 * rights. You may have additional license terms from the party that provided
18 * you this software, covering your right to use that party's intellectual
19 * property rights.
20 *
21 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
22 * copy of the source code appearing in this file ("Covered Code") an
23 * irrevocable, perpetual, worldwide license under Intel's copyrights in the
24 * base code distributed originally by Intel ("Original Intel Code") to copy,
25 * make derivatives, distribute, use and display any portion of the Covered
26 * Code in any form, with the right to sublicense such rights; and
27 *
28 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
29 * license (with the right to sublicense), under only those claims of Intel
30 * patents that are infringed by the Original Intel Code, to make, use, sell,
31 * offer to sell, and import the Covered Code and derivative works thereof
32 * solely to the minimum extent necessary to exercise the above copyright
33 * license, and in no event shall the patent license extend to any additions
34 * to or modifications of the Original Intel Code. No other license or right
35 * is granted directly or by implication, estoppel or otherwise;
36 *
37 * The above copyright and patent license is granted only if the following
38 * conditions are met:
39 *
40 * 3. Conditions
41 *
42 * 3.1. Redistribution of Source with Rights to Further Distribute Source.
43 * Redistribution of source code of any substantial portion of the Covered
44 * Code or modification with rights to further distribute source must include
45 * the above Copyright Notice, the above License, this list of Conditions,
46 * and the following Disclaimer and Export Compliance provision. In addition,
47 * Licensee must cause all Covered Code to which Licensee contributes to
48 * contain a file documenting the changes Licensee made to create that Covered
49 * Code and the date of any change. Licensee must include in that file the
50 * documentation of any changes made by any predecessor Licensee. Licensee
51 * must include a prominent statement that the modification is derived,
52 * directly or indirectly, from Original Intel Code.
53 *
54 * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
55 * Redistribution of source code of any substantial portion of the Covered
56 * Code or modification without rights to further distribute source must
57 * include the following Disclaimer and Export Compliance provision in the
58 * documentation and/or other materials provided with distribution. In
59 * addition, Licensee may not authorize further sublicense of source of any
60 * portion of the Covered Code, and must include terms to the effect that the
61 * license from Licensee to its licensee is limited to the intellectual
62 * property embodied in the software Licensee provides to its licensee, and
63 * not to intellectual property embodied in modifications its licensee may
64 * make.
65 *
66 * 3.3. Redistribution of Executable. Redistribution in executable form of any
67 * substantial portion of the Covered Code or modification must reproduce the
68 * above Copyright Notice, and the following Disclaimer and Export Compliance
69 * provision in the documentation and/or other materials provided with the
70 * distribution.
71 *
72 * 3.4. Intel retains all right, title, and interest in and to the Original
73 * Intel Code.
74 *
75 * 3.5. Neither the name Intel nor any other trademark owned or controlled by
76 * Intel shall be used in advertising or otherwise to promote the sale, use or
77 * other dealings in products derived from or relating to the Covered Code
78 * without prior written authorization from Intel.
79 *
80 * 4. Disclaimer and Export Compliance
81 *
82 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
83 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
84 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
85 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
86 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
87 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
88 * PARTICULAR PURPOSE.
89 *
90 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
91 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
92 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
93 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
94 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
95 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
96 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
97 * LIMITED REMEDY.
98 *
99 * 4.3. Licensee shall not export, either directly or indirectly, any of this
100 * software or system incorporating such software without first obtaining any
101 * required license or other approval from the U. S. Department of Commerce or
102 * any other agency or department of the United States Government. In the
103 * event Licensee exports any such software from the United States or
104 * re-exports any such software from a foreign destination, Licensee shall
105 * ensure that the distribution and export/re-export of the software is in
106 * compliance with all laws, regulations, orders, or other restrictions of the
107 * U.S. Export Administration Regulations. Licensee agrees that neither it nor
108 * any of its subsidiaries will export/re-export any technical data, process,
109 * software, or service, directly or indirectly, to any country for which the
110 * United States government or any agency thereof requires an export license,
111 * other governmental approval, or letter of assurance, without first obtaining
112 * such license, approval or letter.
113 *
114 *****************************************************************************
115 *
116 * Alternatively, you may choose to be licensed under the terms of the
117 * following license:
118 *
119 * Redistribution and use in source and binary forms, with or without
120 * modification, are permitted provided that the following conditions
121 * are met:
122 * 1. Redistributions of source code must retain the above copyright
123 *    notice, this list of conditions, and the following disclaimer,
124 *    without modification.
125 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
126 *    substantially similar to the "NO WARRANTY" disclaimer below
127 *    ("Disclaimer") and any redistribution must be conditioned upon
128 *    including a substantially similar Disclaimer requirement for further
129 *    binary redistribution.
130 * 3. Neither the names of the above-listed copyright holders nor the names
131 *    of any contributors may be used to endorse or promote products derived
132 *    from this software without specific prior written permission.
133 *
134 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
135 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
136 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
137 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
138 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
139 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
140 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
141 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
142 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
143 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
144 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
145 *
146 * Alternatively, you may choose to be licensed under the terms of the
147 * GNU General Public License ("GPL") version 2 as published by the Free
148 * Software Foundation.
149 *
150 *****************************************************************************/
151
152#include <contrib/dev/acpica/compiler/aslcompiler.h>
153
154#define _COMPONENT          ACPI_COMPILER
155        ACPI_MODULE_NAME    ("aslerror")
156
157/* Local prototypes */
158
159static void
160AeAddToErrorLog (
161    ASL_ERROR_MSG           *Enode);
162
163static BOOLEAN
164AslIsExceptionExpected (
165    char                    *Filename,
166    UINT32                  LineNumber,
167    UINT8                   Level,
168    UINT16                  MessageId);
169
170static BOOLEAN
171AslIsExceptionDisabled (
172    UINT8                   Level,
173    UINT16                  MessageId);
174
175static void
176AslInitEnode (
177    ASL_ERROR_MSG           **Enode,
178    UINT8                   Level,
179    UINT16                  MessageId,
180    UINT32                  LineNumber,
181    UINT32                  LogicalLineNumber,
182    UINT32                  LogicalByteOffset,
183    UINT32                  Column,
184    char                    *Filename,
185    char                    *Message,
186    char                    *SourceLine,
187    ASL_ERROR_MSG           *SubError);
188
189static void
190AslLogNewError (
191    UINT8                   Level,
192    UINT16                  MessageId,
193    UINT32                  LineNumber,
194    UINT32                  LogicalLineNumber,
195    UINT32                  LogicalByteOffset,
196    UINT32                  Column,
197    char                    *Filename,
198    char                    *Message,
199    char                    *SourceLine,
200    ASL_ERROR_MSG           *SubError);
201
202static void
203AePrintSubError (
204    FILE                    *OutputFile,
205    ASL_ERROR_MSG           *Enode);
206
207static UINT8
208GetModifiedLevel (
209    UINT8                   Level,
210    UINT16                  MessageId);
211
212
213/*******************************************************************************
214 *
215 * FUNCTION:    AslAbort
216 *
217 * PARAMETERS:  None
218 *
219 * RETURN:      None
220 *
221 * DESCRIPTION: Dump the error log and abort the compiler. Used for serious
222 *              I/O errors.
223 *
224 ******************************************************************************/
225
226void
227AslAbort (
228    void)
229{
230
231    AePrintErrorLog (ASL_FILE_STDERR);
232    if (AslGbl_DebugFlag)
233    {
234        /* Print error summary to stdout also */
235
236        AePrintErrorLog (ASL_FILE_STDOUT);
237    }
238
239    exit (1);
240}
241
242
243/*******************************************************************************
244 *
245 * FUNCTION:    AeClearErrorLog
246 *
247 * PARAMETERS:  None
248 *
249 * RETURN:      None
250 *
251 * DESCRIPTION: Empty the error list
252 *
253 ******************************************************************************/
254
255void
256AeClearErrorLog (
257    void)
258{
259    ASL_ERROR_MSG           *Enode = AslGbl_ErrorLog;
260    ASL_ERROR_MSG           *Next;
261
262
263    /* Walk the error node list */
264
265    while (Enode)
266    {
267        Next = Enode->Next;
268        ACPI_FREE (Enode);
269        Enode = Next;
270    }
271
272   AslGbl_ErrorLog = NULL;
273}
274
275
276/*******************************************************************************
277 *
278 * FUNCTION:    AeAddToErrorLog
279 *
280 * PARAMETERS:  Enode       - An error node to add to the log
281 *
282 * RETURN:      None
283 *
284 * DESCRIPTION: Add a new error node to the error log. The error log is
285 *              ordered by the "logical" line number (cumulative line number
286 *              including all include files.)
287 *
288 ******************************************************************************/
289
290static void
291AeAddToErrorLog (
292    ASL_ERROR_MSG           *Enode)
293{
294    ASL_ERROR_MSG           *Next;
295    ASL_ERROR_MSG           *Prev;
296
297
298    /* If Gbl_ErrorLog is null, this is the first error node */
299
300    if (!AslGbl_ErrorLog)
301    {
302        AslGbl_ErrorLog = Enode;
303        return;
304    }
305
306    /*
307     * Walk error list until we find a line number greater than ours.
308     * List is sorted according to line number.
309     */
310    Prev = NULL;
311    Next = AslGbl_ErrorLog;
312
313    while ((Next) && (Next->LogicalLineNumber <= Enode->LogicalLineNumber))
314    {
315        Prev = Next;
316        Next = Next->Next;
317    }
318
319    /* Found our place in the list */
320
321    Enode->Next = Next;
322
323    if (Prev)
324    {
325        Prev->Next = Enode;
326    }
327    else
328    {
329        AslGbl_ErrorLog = Enode;
330    }
331}
332
333
334/*******************************************************************************
335 *
336 * FUNCTION:    AeDecodeErrorMessageId
337 *
338 * PARAMETERS:  OutputFile      - Output file
339 *              Enode           - Error node to print
340 *              PrematureEOF    - True = PrematureEOF has been reached
341 *              Total           - Total length of line
342 *
343 * RETURN:      None
344 *
345 * DESCRIPTION: Print the source line of an error.
346 *
347 ******************************************************************************/
348
349static void
350AeDecodeErrorMessageId (
351    FILE                    *OutputFile,
352    ASL_ERROR_MSG           *Enode,
353    BOOLEAN                 PrematureEOF,
354    UINT32                  Total)
355{
356    UINT32                  MsgLength;
357    const char              *MainMessage;
358    char                    *ExtraMessage;
359    UINT32                  SourceColumn;
360    UINT32                  ErrorColumn;
361
362
363    fprintf (OutputFile, "%s %4.4d -",
364        AeDecodeExceptionLevel (Enode->Level),
365        AeBuildFullExceptionCode (Enode->Level, Enode->MessageId));
366
367    MainMessage = AeDecodeMessageId (Enode->MessageId);
368    ExtraMessage = Enode->Message;
369
370    /* If a NULL line number, just print the decoded message */
371
372    if (!Enode->LineNumber)
373    {
374        fprintf (OutputFile, " %s %s\n\n", MainMessage, ExtraMessage);
375        return;
376    }
377
378    MsgLength = strlen (MainMessage);
379    if (MsgLength == 0)
380    {
381        /* Use the secondary/extra message as main message */
382
383        MainMessage = Enode->Message;
384        if (!MainMessage)
385        {
386            MainMessage = "";
387        }
388
389        MsgLength = strlen (MainMessage);
390        ExtraMessage = NULL;
391    }
392
393    if (AslGbl_VerboseErrors && !PrematureEOF)
394    {
395        if (Total >= 256)
396        {
397            fprintf (OutputFile, "    %s",
398                MainMessage);
399        }
400        else
401        {
402            SourceColumn = Enode->Column + Enode->FilenameLength + 6 + 2;
403            ErrorColumn = ASL_ERROR_LEVEL_LENGTH + 5 + 2 + 1;
404
405            if ((MsgLength + ErrorColumn) < (SourceColumn - 1))
406            {
407                fprintf (OutputFile, "%*s%s",
408                    (int) ((SourceColumn - 1) - ErrorColumn),
409                    MainMessage, " ^ ");
410            }
411            else
412            {
413                fprintf (OutputFile, "%*s %s",
414                    (int) ((SourceColumn - ErrorColumn) + 1), "^",
415                    MainMessage);
416            }
417        }
418    }
419    else
420    {
421        fprintf (OutputFile, " %s", MainMessage);
422    }
423
424    /* Print the extra info message if present */
425
426    if (ExtraMessage)
427    {
428        fprintf (OutputFile, " (%s)", ExtraMessage);
429    }
430
431    if (PrematureEOF)
432    {
433        fprintf (OutputFile, " and premature End-Of-File");
434    }
435
436    fprintf (OutputFile, "\n");
437    if (AslGbl_VerboseErrors && !Enode->SubError)
438    {
439        fprintf (OutputFile, "\n");
440    }
441}
442
443
444/*******************************************************************************
445 *
446 * FUNCTION:    AePrintErrorSourceLine
447 *
448 * PARAMETERS:  OutputFile      - Output file
449 *              Enode           - Error node to print
450 *              PrematureEOF    - True = PrematureEOF has been reached
451 *              Total           - Number of characters printed so far
452 *
453 *
454 * RETURN:      Status
455 *
456 * DESCRIPTION: Print the source line of an error.
457 *
458 ******************************************************************************/
459
460static ACPI_STATUS
461AePrintErrorSourceLine (
462    FILE                    *OutputFile,
463    ASL_ERROR_MSG           *Enode,
464    BOOLEAN                 *PrematureEOF,
465    UINT32                  *Total)
466{
467    UINT8                   SourceByte;
468    int                     Actual;
469    size_t                  RActual;
470    FILE                    *SourceFile = NULL;
471    long                    FileSize;
472
473
474    if (!Enode->SourceLine)
475    {
476        /*
477         * Use the merged header/source file if present, otherwise
478         * use input file
479         */
480        SourceFile = FlGetFileHandle (ASL_FILE_SOURCE_OUTPUT,
481            ASL_FILE_SOURCE_OUTPUT, Enode->SourceFilename);
482        if (!SourceFile)
483        {
484            SourceFile = FlGetFileHandle (ASL_FILE_INPUT,
485                ASL_FILE_INPUT, Enode->Filename);
486        }
487
488        if (SourceFile)
489        {
490            /* Determine if the error occurred at source file EOF */
491
492            fseek (SourceFile, 0, SEEK_END);
493            FileSize = ftell (SourceFile);
494
495            if ((long) Enode->LogicalByteOffset >= FileSize)
496            {
497                *PrematureEOF = TRUE;
498            }
499        }
500        else
501        {
502            fprintf (OutputFile,
503                "[*** iASL: Source File Does not exist ***]\n");
504            return AE_IO_ERROR;
505        }
506    }
507
508    /* Print filename and line number if present and valid */
509
510    if (AslGbl_VerboseErrors)
511    {
512        fprintf (OutputFile, "%-8s", Enode->Filename);
513
514        if (Enode->SourceLine && Enode->LineNumber)
515        {
516            fprintf (OutputFile, " %6u: %s",
517                Enode->LineNumber, Enode->SourceLine);
518        }
519        else if (Enode->LineNumber)
520        {
521            fprintf (OutputFile, " %6u: ", Enode->LineNumber);
522
523            /*
524             * If not at EOF, get the corresponding source code line
525             * and display it. Don't attempt this if we have a
526             * premature EOF condition.
527             */
528            if (*PrematureEOF)
529            {
530                fprintf (OutputFile, "\n");
531                return AE_OK;
532            }
533
534            /*
535             * Seek to the offset in the combined source file,
536             * read the source line, and write it to the output.
537             */
538            Actual = fseek (SourceFile,
539                (long) Enode->LogicalByteOffset, (int) SEEK_SET);
540            if (Actual)
541            {
542                fprintf (OutputFile,
543                    "[*** iASL: Seek error on source code temp file %s ***]",
544                    AslGbl_Files[ASL_FILE_SOURCE_OUTPUT].Filename);
545
546                fprintf (OutputFile, "\n");
547                return AE_OK;
548            }
549            RActual = fread (&SourceByte, 1, 1, SourceFile);
550            if (RActual != 1)
551            {
552                fprintf (OutputFile,
553                    "[*** iASL: Read error on source code temp file %s ***]",
554                    AslGbl_Files[ASL_FILE_SOURCE_OUTPUT].Filename);
555                return AE_IO_ERROR;
556            }
557
558            /* Read/write the source line, up to the maximum line length */
559
560            while (RActual && SourceByte && (SourceByte != '\n'))
561            {
562                if (*Total < 256)
563                {
564                    /* After the max line length, we will just read the line, no write */
565
566                    if (fwrite (&SourceByte, 1, 1, OutputFile) != 1)
567                    {
568                        printf ("[*** iASL: Write error on output file ***]\n");
569                        return AE_IO_ERROR;
570                    }
571                }
572                else if (*Total == 256)
573                {
574                    fprintf (OutputFile,
575                        "\n[*** iASL: Very long input line, message below refers to column %u ***]",
576                        Enode->Column);
577                }
578
579                RActual = fread (&SourceByte, 1, 1, SourceFile);
580                if (RActual != 1)
581                {
582                    fprintf (OutputFile,
583                        "[*** iASL: Read error on source code temp file %s ***]",
584                        AslGbl_Files[ASL_FILE_SOURCE_OUTPUT].Filename);
585
586                    return AE_IO_ERROR;
587                }
588                *Total += 1;
589            }
590
591            fprintf (OutputFile, "\n");
592        }
593    }
594    else
595    {
596        /*
597         * Less verbose version of the error message, enabled via the
598         * -vi switch. The format is compatible with MS Visual Studio.
599         */
600        fprintf (OutputFile, "%s", Enode->Filename);
601
602        if (Enode->LineNumber)
603        {
604            fprintf (OutputFile, "(%u) : ",
605                Enode->LineNumber);
606        }
607    }
608
609    return AE_OK;
610}
611
612/*******************************************************************************
613 *
614 * FUNCTION:    AePrintException
615 *
616 * PARAMETERS:  FileId          - ID of output file
617 *              Enode           - Error node to print
618 *              Header          - Additional text before each message
619 *
620 * RETURN:      None
621 *
622 * DESCRIPTION: Print the contents of an error node.
623 *
624 * NOTE:        We don't use the FlxxxFile I/O functions here because on error
625 *              they abort the compiler and call this function!  Since we
626 *              are reporting errors here, we ignore most output errors and
627 *              just try to get out as much as we can.
628 *
629 ******************************************************************************/
630
631void
632AePrintException (
633    UINT32                  FileId,
634    ASL_ERROR_MSG           *Enode,
635    char                    *Header)
636{
637    FILE                    *OutputFile;
638    BOOLEAN                 PrematureEOF = FALSE;
639    UINT32                  Total = 0;
640    ACPI_STATUS             Status;
641    ASL_ERROR_MSG           *Child = Enode->SubError;
642
643
644    if (AslGbl_NoErrors)
645    {
646        return;
647    }
648
649    /*
650     * Only listing files have a header, and remarks/optimizations
651     * are always output
652     */
653    if (!Header)
654    {
655        /* Ignore remarks if requested */
656
657        switch (Enode->Level)
658        {
659        case ASL_WARNING:
660        case ASL_WARNING2:
661        case ASL_WARNING3:
662
663            if (!AslGbl_DisplayWarnings)
664            {
665                return;
666            }
667            break;
668
669        case ASL_REMARK:
670
671            if (!AslGbl_DisplayRemarks)
672            {
673                return;
674            }
675            break;
676
677        case ASL_OPTIMIZATION:
678
679            if (!AslGbl_DisplayOptimizations)
680            {
681                return;
682            }
683            break;
684
685        default:
686
687            break;
688        }
689    }
690
691    /* Get the various required file handles */
692
693    OutputFile = AslGbl_Files[FileId].Handle;
694
695    if (Header)
696    {
697        fprintf (OutputFile, "%s", Header);
698    }
699
700    if (!Enode->Filename)
701    {
702        AeDecodeErrorMessageId (OutputFile, Enode, PrematureEOF, Total);
703        return;
704    }
705
706    Status = AePrintErrorSourceLine (OutputFile, Enode, &PrematureEOF, &Total);
707    if (ACPI_FAILURE (Status))
708    {
709        return;
710    }
711
712    /* If a NULL message ID, just print the raw message */
713
714    if (Enode->MessageId == 0)
715    {
716        fprintf (OutputFile, "%s\n", Enode->Message);
717        return;
718    }
719
720    AeDecodeErrorMessageId (OutputFile, Enode, PrematureEOF, Total);
721
722    while (Child)
723    {
724        fprintf (OutputFile, "\n");
725        AePrintSubError (OutputFile, Child);
726        Child = Child->SubError;
727    }
728}
729
730
731/*******************************************************************************
732 *
733 * FUNCTION:    AePrintSubError
734 *
735 * PARAMETERS:  OutputFile      - Output file
736 *              Enode           - Error node to print
737 *
738 * RETURN:      None
739 *
740 * DESCRIPTION: Print the contents of an error node. This function is tailored
741 *              to print error nodes that are SubErrors within ASL_ERROR_MSG
742 *
743 ******************************************************************************/
744
745static void
746AePrintSubError (
747    FILE                    *OutputFile,
748    ASL_ERROR_MSG           *Enode)
749{
750    UINT32                  Total = 0;
751    BOOLEAN                 PrematureEOF = FALSE;
752    const char              *MainMessage;
753
754
755    MainMessage = AeDecodeMessageId (Enode->MessageId);
756
757    fprintf (OutputFile, "    %s", MainMessage);
758
759    if (Enode->Message)
760    {
761        fprintf (OutputFile, "(%s)", Enode->Message);
762    }
763
764    fprintf (OutputFile, "\n    ");
765    (void) AePrintErrorSourceLine (OutputFile, Enode, &PrematureEOF, &Total);
766    fprintf (OutputFile, "\n");
767}
768
769
770/*******************************************************************************
771 *
772 * FUNCTION:    AePrintErrorLog
773 *
774 * PARAMETERS:  FileId           - Where to output the error log
775 *
776 * RETURN:      None
777 *
778 * DESCRIPTION: Print the entire contents of the error log
779 *
780 ******************************************************************************/
781
782void
783AePrintErrorLog (
784    UINT32                  FileId)
785{
786    ASL_ERROR_MSG           *Enode = AslGbl_ErrorLog;
787
788
789    /* Walk the error node list */
790
791    while (Enode)
792    {
793        AePrintException (FileId, Enode, NULL);
794        Enode = Enode->Next;
795    }
796}
797
798
799/*******************************************************************************
800 *
801 * FUNCTION:    AslInitEnode
802 *
803 * PARAMETERS:  InputEnode          - Input Error node to initialize
804 *              Level               - Seriousness (Warning/error, etc.)
805 *              MessageId           - Index into global message buffer
806 *              CurrentLineNumber   - Actual file line number
807 *              LogicalLineNumber   - Cumulative line number
808 *              LogicalByteOffset   - Byte offset in source file
809 *              Column              - Column in current line
810 *              Filename            - Source filename
811 *              ExtraMessage        - Additional error message
812 *              SourceLine          - Line of error source code
813 *              SubError            - SubError of this InputEnode
814 *
815 * RETURN:      None
816 *
817 * DESCRIPTION: Initialize an Error node
818 *
819 ******************************************************************************/
820
821static void AslInitEnode (
822    ASL_ERROR_MSG           **InputEnode,
823    UINT8                   Level,
824    UINT16                  MessageId,
825    UINT32                  LineNumber,
826    UINT32                  LogicalLineNumber,
827    UINT32                  LogicalByteOffset,
828    UINT32                  Column,
829    char                    *Filename,
830    char                    *ExtraMessage,
831    char                    *SourceLine,
832    ASL_ERROR_MSG           *SubError)
833{
834    ASL_ERROR_MSG           *Enode;
835    ASL_GLOBAL_FILE_NODE    *FileNode;
836
837
838    *InputEnode = UtLocalCalloc (sizeof (ASL_ERROR_MSG));
839    Enode = *InputEnode;
840    Enode->Level                = Level;
841    Enode->MessageId            = MessageId;
842    Enode->LineNumber           = LineNumber;
843    Enode->LogicalLineNumber    = LogicalLineNumber;
844    Enode->LogicalByteOffset    = LogicalByteOffset;
845    Enode->Column               = Column;
846    Enode->SubError             = SubError;
847    Enode->Message              = NULL;
848    Enode->SourceLine           = NULL;
849    Enode->Filename             = NULL;
850
851    if (ExtraMessage)
852    {
853        /* Allocate a buffer for the message and a new error node */
854
855        Enode->Message = UtLocalCacheCalloc (strlen (ExtraMessage) + 1);
856
857        /* Keep a copy of the extra message */
858
859        strcpy (Enode->Message, ExtraMessage);
860    }
861
862    if (SourceLine)
863    {
864        Enode->SourceLine = UtLocalCalloc (strlen (SourceLine) + 1);
865        strcpy (Enode->SourceLine, SourceLine);
866    }
867
868
869    if (Filename)
870    {
871        Enode->Filename = Filename;
872        Enode->FilenameLength = strlen (Filename);
873        if (Enode->FilenameLength < 6)
874        {
875            Enode->FilenameLength = 6;
876        }
877
878        /*
879         * Attempt to get the file node of the filename listed in the parse
880         * node. If the name doesn't exist in the global file node, it is
881         * because the file is included by #include or ASL include. In this
882         * case, get the current file node. The source output of the current
883         * file will contain the contents of the file listed in the parse node.
884         */
885        FileNode = FlGetFileNode (ASL_FILE_INPUT, Filename);
886        if (!FileNode)
887        {
888            FileNode = FlGetCurrentFileNode ();
889        }
890
891        Enode->SourceFilename =
892            FileNode->Files[ASL_FILE_SOURCE_OUTPUT].Filename;
893    }
894}
895
896
897/*******************************************************************************
898 *
899 * FUNCTION:    AslCommonError2
900 *
901 * PARAMETERS:  Level               - Seriousness (Warning/error, etc.)
902 *              MessageId           - Index into global message buffer
903 *              LineNumber          - Actual file line number
904 *              Column              - Column in current line
905 *              SourceLine          - Actual source code line
906 *              Filename            - Source filename
907 *              ExtraMessage        - Additional error message
908 *
909 * RETURN:      None
910 *
911 * DESCRIPTION: Create a new error node and add it to the error log
912 *
913 ******************************************************************************/
914
915void
916AslCommonError2 (
917    UINT8                   Level,
918    UINT16                  MessageId,
919    UINT32                  LineNumber,
920    UINT32                  Column,
921    char                    *SourceLine,
922    char                    *Filename,
923    char                    *ExtraMessage)
924{
925    AslLogNewError (Level, MessageId, LineNumber, LineNumber, 0, Column,
926        Filename, ExtraMessage, SourceLine, NULL);
927}
928
929
930/*******************************************************************************
931 *
932 * FUNCTION:    AslCommonError
933 *
934 * PARAMETERS:  Level               - Seriousness (Warning/error, etc.)
935 *              MessageId           - Index into global message buffer
936 *              CurrentLineNumber   - Actual file line number
937 *              LogicalLineNumber   - Cumulative line number
938 *              LogicalByteOffset   - Byte offset in source file
939 *              Column              - Column in current line
940 *              Filename            - Source filename
941 *              ExtraMessage        - Additional error message
942 *
943 * RETURN:      None
944 *
945 * DESCRIPTION: Create a new error node and add it to the error log
946 *
947 ******************************************************************************/
948
949void
950AslCommonError (
951    UINT8                   Level,
952    UINT16                  MessageId,
953    UINT32                  CurrentLineNumber,
954    UINT32                  LogicalLineNumber,
955    UINT32                  LogicalByteOffset,
956    UINT32                  Column,
957    char                    *Filename,
958    char                    *ExtraMessage)
959{
960    /* Check if user wants to ignore this exception */
961
962    if (AslIsExceptionIgnored (Filename, LogicalLineNumber, Level, MessageId))
963    {
964        return;
965    }
966
967    AslLogNewError (Level, MessageId, CurrentLineNumber, LogicalLineNumber,
968        LogicalByteOffset, Column, Filename, ExtraMessage,
969        NULL, NULL);
970}
971
972
973/*******************************************************************************
974 *
975 * FUNCTION:    AslLogNewError
976 *
977 * PARAMETERS:  Level               - Seriousness (Warning/error, etc.)
978 *              MessageId           - Index into global message buffer
979 *              CurrentLineNumber   - Actual file line number
980 *              LogicalLineNumber   - Cumulative line number
981 *              LogicalByteOffset   - Byte offset in source file
982 *              Column              - Column in current line
983 *              Filename            - Source filename
984 *              Message             - Additional error message
985 *              SourceLine          - Actual line of source code
986 *              SubError            - Sub-error associated with this error
987 *
988 * RETURN:      None
989 *
990 * DESCRIPTION: Create a new error node and add it to the error log
991 *
992 ******************************************************************************/
993static void
994AslLogNewError (
995    UINT8                   Level,
996    UINT16                  MessageId,
997    UINT32                  LineNumber,
998    UINT32                  LogicalLineNumber,
999    UINT32                  LogicalByteOffset,
1000    UINT32                  Column,
1001    char                    *Filename,
1002    char                    *Message,
1003    char                    *SourceLine,
1004    ASL_ERROR_MSG           *SubError)
1005{
1006    ASL_ERROR_MSG           *Enode = NULL;
1007    UINT8                   ModifiedLevel = GetModifiedLevel (Level, MessageId);
1008
1009
1010    AslInitEnode (&Enode, ModifiedLevel, MessageId, LineNumber,
1011        LogicalLineNumber, LogicalByteOffset, Column, Filename, Message,
1012        SourceLine, SubError);
1013
1014    /* Add the new node to the error node list */
1015
1016    AeAddToErrorLog (Enode);
1017
1018    if (AslGbl_DebugFlag)
1019    {
1020        /* stderr is a file, send error to it immediately */
1021
1022        AePrintException (ASL_FILE_STDERR, Enode, NULL);
1023    }
1024
1025    AslGbl_ExceptionCount[ModifiedLevel]++;
1026    if (!AslGbl_IgnoreErrors && AslGbl_ExceptionCount[ASL_ERROR] > ASL_MAX_ERROR_COUNT)
1027    {
1028        printf ("\nMaximum error count (%u) exceeded (aslerror.c)\n", ASL_MAX_ERROR_COUNT);
1029
1030        AslGbl_SourceLine = 0;
1031        AslGbl_NextError = AslGbl_ErrorLog;
1032        CmCleanupAndExit ();
1033        exit(1);
1034    }
1035
1036    return;
1037}
1038
1039
1040/*******************************************************************************
1041 *
1042 * FUNCTION:    GetModifiedLevel
1043 *
1044 * PARAMETERS:  Level           - Seriousness (Warning/error, etc.)
1045 *              MessageId       - Index into global message buffer
1046 *
1047 * RETURN:      UINT8           - Modified level
1048 *
1049 * DESCRIPTION: Get the modified level of exception codes that are reported as
1050 *              errors from the -ww option.
1051 *
1052 ******************************************************************************/
1053
1054static UINT8
1055GetModifiedLevel (
1056    UINT8                   Level,
1057    UINT16                  MessageId)
1058{
1059    UINT32                  i;
1060    UINT16                  ExceptionCode;
1061
1062
1063    ExceptionCode = AeBuildFullExceptionCode (Level, MessageId);
1064
1065    for (i = 0; i < AslGbl_ElevatedMessagesIndex; i++)
1066    {
1067        if (ExceptionCode == AslGbl_ElevatedMessages[i])
1068        {
1069            return (ASL_ERROR);
1070        }
1071    }
1072
1073    return (Level);
1074}
1075
1076
1077/*******************************************************************************
1078 *
1079 * FUNCTION:    AslIsExceptionIgnored
1080 *
1081 * PARAMETERS:  Level           - Seriousness (Warning/error, etc.)
1082 *              MessageId       - Index into global message buffer
1083 *
1084 * RETURN:      BOOLEAN
1085 *
1086 * DESCRIPTION: Check if a particular exception is ignored. In this case it
1087 *              means that the exception is (expected or disabled.
1088 *
1089 ******************************************************************************/
1090
1091BOOLEAN
1092AslIsExceptionIgnored (
1093    char                    *Filename,
1094    UINT32                  LineNumber,
1095    UINT8                   Level,
1096    UINT16                  MessageId)
1097{
1098    BOOLEAN                 ExceptionIgnored;
1099
1100
1101    /* Note: this allows exception to be disabled and expected */
1102
1103    ExceptionIgnored = AslIsExceptionDisabled (Level, MessageId);
1104    ExceptionIgnored |=
1105        AslIsExceptionExpected (Filename, LineNumber, Level, MessageId);
1106
1107    return (AslGbl_AllExceptionsDisabled || ExceptionIgnored);
1108}
1109
1110
1111/*******************************************************************************
1112 *
1113 * FUNCTION:    AslCheckExpectedException
1114 *
1115 * PARAMETERS:  none
1116 *
1117 * RETURN:      none
1118 *
1119 * DESCRIPTION: Check the global expected messages table and raise an error
1120 *              for each message that has not been received.
1121 *
1122 ******************************************************************************/
1123
1124void
1125AslCheckExpectedExceptions (
1126    void)
1127{
1128    UINT32                  i;
1129    ASL_EXPECTED_MSG_NODE   *Current = AslGbl_ExpectedErrorCodeList;
1130    ASL_LOCATION_NODE       *LocationNode;
1131
1132
1133    for (i = 0; i < AslGbl_ExpectedMessagesIndex; ++i)
1134    {
1135        if (!AslGbl_ExpectedMessages[i].MessageReceived)
1136        {
1137            AslError (ASL_ERROR, ASL_MSG_EXCEPTION_NOT_RECEIVED, NULL,
1138                AslGbl_ExpectedMessages[i].MessageIdStr);
1139        }
1140    }
1141
1142    while (Current)
1143    {
1144        LocationNode = Current->LocationList;
1145
1146        while (LocationNode)
1147        {
1148            if (!LocationNode->MessageReceived)
1149            {
1150                AslCommonError (ASL_ERROR, ASL_MSG_EXCEPTION_NOT_RECEIVED,
1151                    LocationNode->LineNumber, LocationNode->LineNumber,
1152                    LocationNode->LogicalByteOffset, LocationNode->Column,
1153                    LocationNode->Filename, Current->MessageIdStr);
1154            }
1155
1156            LocationNode = LocationNode->Next;
1157        }
1158
1159        Current = Current->Next;
1160    }
1161}
1162
1163
1164/*******************************************************************************
1165 *
1166 * FUNCTION:    AslLogExpectedException
1167 *
1168 * PARAMETERS:  MessageIdString     - ID of excepted exception during compile
1169 *
1170 * RETURN:      Status
1171 *
1172 * DESCRIPTION: Enter a message ID into the global expected messages table
1173 *              If these messages are not raised during the compilation, throw
1174 *              an error.
1175 *
1176 ******************************************************************************/
1177
1178ACPI_STATUS
1179AslLogExpectedException (
1180    char                    *MessageIdString)
1181{
1182    UINT32                  MessageId;
1183
1184
1185    /* Convert argument to an integer and validate it */
1186
1187    MessageId = (UINT32) strtoul (MessageIdString, NULL, 0);
1188
1189    if (MessageId > 6999)
1190    {
1191        printf ("\"%s\" is not a valid warning/remark/error ID\n",
1192            MessageIdString);
1193        return (AE_BAD_PARAMETER);
1194    }
1195
1196    /* Insert value into the global expected message array */
1197
1198    if (AslGbl_ExpectedMessagesIndex >= ASL_MAX_EXPECTED_MESSAGES)
1199    {
1200        printf ("Too many messages have been registered as expected (max %d)\n",
1201            ASL_MAX_DISABLED_MESSAGES);
1202        return (AE_LIMIT);
1203    }
1204
1205    AslGbl_ExpectedMessages[AslGbl_ExpectedMessagesIndex].MessageId = MessageId;
1206    AslGbl_ExpectedMessages[AslGbl_ExpectedMessagesIndex].MessageIdStr = MessageIdString;
1207    AslGbl_ExpectedMessages[AslGbl_ExpectedMessagesIndex].MessageReceived = FALSE;
1208    AslGbl_ExpectedMessagesIndex++;
1209    return (AE_OK);
1210}
1211
1212
1213/*******************************************************************************
1214 *
1215 * FUNCTION:    AslLogExpectedExceptionByLine
1216 *
1217 * PARAMETERS:  MessageIdString     - ID of excepted exception during compile
1218 *
1219 * RETURN:      Status
1220 *
1221 * DESCRIPTION: Enter a message ID into the global expected messages table
1222 *              based on file and line number. If these messages are not raised
1223 *              during the compilation, throw an error.
1224 *
1225 ******************************************************************************/
1226
1227void
1228AslLogExpectedExceptionByLine (
1229    char                    *MessageIdString)
1230{
1231    ASL_LOCATION_NODE       *NewErrorLocationNode;
1232    ASL_EXPECTED_MSG_NODE   *Current = AslGbl_ExpectedErrorCodeList;
1233    UINT32                  MessageId;
1234
1235
1236    NewErrorLocationNode = UtLocalCalloc (sizeof (ASL_LOCATION_NODE));
1237
1238    NewErrorLocationNode->LineNumber = AslGbl_CurrentLineNumber;
1239    NewErrorLocationNode->Filename = AslGbl_Files[ASL_FILE_INPUT].Filename;
1240    NewErrorLocationNode->LogicalByteOffset = AslGbl_CurrentLineOffset;
1241    NewErrorLocationNode->Column = AslGbl_CurrentColumn;
1242
1243    MessageId = (UINT32) strtoul (MessageIdString, NULL, 0);
1244
1245    /* search the existing list for a matching message ID */
1246
1247    while (Current && Current->MessageId != MessageId )
1248    {
1249        Current = Current->Next;
1250    }
1251    if (!Current)
1252    {
1253        /* ID was not found, create a new node for this message ID */
1254
1255        Current = UtLocalCalloc (sizeof (ASL_EXPECTED_MSG_NODE));
1256
1257        Current->Next = AslGbl_ExpectedErrorCodeList;
1258        Current->MessageIdStr = MessageIdString;
1259        Current->MessageId = MessageId;
1260        AslGbl_ExpectedErrorCodeList = Current;
1261    }
1262
1263    NewErrorLocationNode->Next = Current->LocationList;
1264    Current->LocationList = NewErrorLocationNode;
1265}
1266
1267
1268/*******************************************************************************
1269 *
1270 * FUNCTION:    AslDisableException
1271 *
1272 * PARAMETERS:  MessageIdString     - ID to be disabled
1273 *
1274 * RETURN:      Status
1275 *
1276 * DESCRIPTION: Enter a message ID into the global disabled messages table
1277 *
1278 ******************************************************************************/
1279
1280ACPI_STATUS
1281AslDisableException (
1282    char                    *MessageIdString)
1283{
1284    UINT32                  MessageId;
1285
1286
1287    /* Convert argument to an integer and validate it */
1288
1289    MessageId = (UINT32) strtoul (MessageIdString, NULL, 0);
1290
1291    if ((MessageId < 2000) || (MessageId > 6999))
1292    {
1293        printf ("\"%s\" is not a valid warning/remark/error ID\n",
1294            MessageIdString);
1295        return (AE_BAD_PARAMETER);
1296    }
1297
1298    /* Insert value into the global disabled message array */
1299
1300    if (AslGbl_DisabledMessagesIndex >= ASL_MAX_DISABLED_MESSAGES)
1301    {
1302        printf ("Too many messages have been disabled (max %d)\n",
1303            ASL_MAX_DISABLED_MESSAGES);
1304        return (AE_LIMIT);
1305    }
1306
1307    AslGbl_DisabledMessages[AslGbl_DisabledMessagesIndex] = MessageId;
1308    AslGbl_DisabledMessagesIndex++;
1309    return (AE_OK);
1310}
1311
1312
1313/*******************************************************************************
1314 *
1315 * FUNCTION:    AslElevateException
1316 *
1317 * PARAMETERS:  MessageIdString     - ID of excepted exception during compile
1318 *
1319 * RETURN:      Status
1320 *
1321 * DESCRIPTION: Enter a message ID into the global elevated exceptions table.
1322 *              These messages will be considered as compilation errors.
1323 *
1324 ******************************************************************************/
1325
1326ACPI_STATUS
1327AslElevateException (
1328    char                    *MessageIdString)
1329{
1330    UINT32                  MessageId;
1331
1332
1333    /* Convert argument to an integer and validate it */
1334
1335    MessageId = (UINT32) strtoul (MessageIdString, NULL, 0);
1336
1337    if (MessageId > 6999)
1338    {
1339        printf ("\"%s\" is not a valid warning/remark/error ID\n",
1340            MessageIdString);
1341        return (AE_BAD_PARAMETER);
1342    }
1343
1344    /* Insert value into the global expected message array */
1345
1346    if (AslGbl_ElevatedMessagesIndex >= ASL_MAX_ELEVATED_MESSAGES)
1347    {
1348        printf ("Too many messages have been registered as elevated (max %d)\n",
1349            ASL_MAX_DISABLED_MESSAGES);
1350        return (AE_LIMIT);
1351    }
1352
1353    AslGbl_ElevatedMessages[AslGbl_ElevatedMessagesIndex] = MessageId;
1354    AslGbl_ElevatedMessagesIndex++;
1355    return (AE_OK);
1356}
1357
1358
1359/*******************************************************************************
1360 *
1361 * FUNCTION:    AslIsExceptionDisabled
1362 *
1363 * PARAMETERS:  Level           - Seriousness (Warning/error, etc.)
1364 *              MessageId       - Index into global message buffer
1365 *
1366 * RETURN:      TRUE if exception/message should be ignored
1367 *
1368 * DESCRIPTION: Check if the user has specified options such that this
1369 *              exception should be ignored
1370 *
1371 ******************************************************************************/
1372
1373static BOOLEAN
1374AslIsExceptionExpected (
1375    char                    *Filename,
1376    UINT32                  LineNumber,
1377    UINT8                   Level,
1378    UINT16                  MessageId)
1379{
1380    ASL_EXPECTED_MSG_NODE   *Current = AslGbl_ExpectedErrorCodeList;
1381    ASL_LOCATION_NODE       *CurrentErrorLocation;
1382    UINT32                  EncodedMessageId;
1383    UINT32                  i;
1384
1385
1386    /* Mark this exception as received */
1387
1388    EncodedMessageId = AeBuildFullExceptionCode (Level, MessageId);
1389    for (i = 0; i < AslGbl_ExpectedMessagesIndex; i++)
1390    {
1391        /* Simple implementation via fixed array */
1392
1393        if (EncodedMessageId == AslGbl_ExpectedMessages[i].MessageId)
1394        {
1395            return (AslGbl_ExpectedMessages[i].MessageReceived = TRUE);
1396        }
1397    }
1398
1399    while (Current && Current->MessageId != EncodedMessageId)
1400    {
1401        Current = Current->Next;
1402    }
1403    if (!Current)
1404    {
1405        return (FALSE);
1406    }
1407
1408    CurrentErrorLocation = Current->LocationList;
1409
1410    while (CurrentErrorLocation)
1411    {
1412        if (!strcmp (CurrentErrorLocation->Filename, Filename) &&
1413            CurrentErrorLocation->LineNumber == LineNumber)
1414        {
1415            return (CurrentErrorLocation->MessageReceived = TRUE);
1416        }
1417
1418        CurrentErrorLocation = CurrentErrorLocation->Next;
1419    }
1420
1421    return (FALSE);
1422}
1423
1424
1425/*******************************************************************************
1426 *
1427 * FUNCTION:    AslIsExceptionDisabled
1428 *
1429 * PARAMETERS:  Level               - Seriousness (Warning/error, etc.)
1430 *              MessageId           - Index into global message buffer
1431 *
1432 * RETURN:      TRUE if exception/message should be ignored
1433 *
1434 * DESCRIPTION: Check if the user has specified options such that this
1435 *              exception should be ignored
1436 *
1437 ******************************************************************************/
1438
1439static BOOLEAN
1440AslIsExceptionDisabled (
1441    UINT8                   Level,
1442    UINT16                  MessageId)
1443{
1444    UINT32                  EncodedMessageId;
1445    UINT32                  i;
1446
1447
1448    switch (Level)
1449    {
1450    case ASL_WARNING2:
1451    case ASL_WARNING3:
1452
1453        /* Check for global disable via -w1/-w2/-w3 options */
1454
1455        if (Level > AslGbl_WarningLevel)
1456        {
1457            return (TRUE);
1458        }
1459        ACPI_FALLTHROUGH;
1460
1461    case ASL_WARNING:
1462    case ASL_REMARK:
1463    case ASL_ERROR:
1464        /*
1465         * Ignore this error/warning/remark if it has been disabled by
1466         * the user (-vw option)
1467         */
1468        EncodedMessageId = AeBuildFullExceptionCode (Level, MessageId);
1469        for (i = 0; i < AslGbl_DisabledMessagesIndex; i++)
1470        {
1471            /* Simple implementation via fixed array */
1472
1473            if (EncodedMessageId == AslGbl_DisabledMessages[i])
1474            {
1475                return (TRUE);
1476            }
1477        }
1478        break;
1479
1480    default:
1481        break;
1482    }
1483
1484    return (FALSE);
1485}
1486
1487
1488/*******************************************************************************
1489 *
1490 * FUNCTION:    AslDualParseOpError
1491 *
1492 * PARAMETERS:  Level           - Seriousness (Warning/error, etc.)
1493 *              MainMsgId       - Index into global message buffer
1494 *              MainOp          - Parse node where error happened
1495 *              MainMsg         - Message pertaining to the MainOp
1496 *              SubMsgId        - Index into global message buffer
1497 *              SubOp           - Additional parse node for better message
1498 *              SubMsg          - Message pertaining to SubOp
1499 *
1500 *
1501 * RETURN:      None
1502 *
1503 * DESCRIPTION: Main error reporting routine for the ASL compiler for error
1504 *              messages that point to multiple parse objects.
1505 *
1506 ******************************************************************************/
1507
1508void
1509AslDualParseOpError (
1510    UINT8                   Level,
1511    UINT16                  MainMsgId,
1512    ACPI_PARSE_OBJECT       *MainOp,
1513    char                    *MainMsg,
1514    UINT16                  SubMsgId,
1515    ACPI_PARSE_OBJECT       *SubOp,
1516    char                    *SubMsg)
1517{
1518    ASL_ERROR_MSG           *SubEnode = NULL;
1519
1520
1521    /* Check if user wants to ignore this exception */
1522
1523    if (!MainOp || AslIsExceptionIgnored (MainOp->Asl.Filename,
1524        MainOp->Asl.LogicalLineNumber, Level, MainMsgId))
1525    {
1526        return;
1527    }
1528
1529    if (SubOp)
1530    {
1531        AslInitEnode (&SubEnode, Level, SubMsgId, SubOp->Asl.LineNumber,
1532            SubOp->Asl.LogicalLineNumber, SubOp->Asl.LogicalByteOffset,
1533            SubOp->Asl.Column, SubOp->Asl.Filename, SubMsg,
1534            NULL, NULL);
1535    }
1536
1537    AslLogNewError (Level, MainMsgId, MainOp->Asl.LineNumber,
1538        MainOp->Asl.LogicalLineNumber, MainOp->Asl.LogicalByteOffset,
1539        MainOp->Asl.Column, MainOp->Asl.Filename, MainMsg,
1540        NULL, SubEnode);
1541}
1542
1543
1544/*******************************************************************************
1545 *
1546 * FUNCTION:    AslError
1547 *
1548 * PARAMETERS:  Level               - Seriousness (Warning/error, etc.)
1549 *              MessageId           - Index into global message buffer
1550 *              Op                  - Parse node where error happened
1551 *              ExtraMessage        - Additional error message
1552 *
1553 * RETURN:      None
1554 *
1555 * DESCRIPTION: Main error reporting routine for the ASL compiler (all code
1556 *              except the parser.)
1557 *
1558 ******************************************************************************/
1559
1560void
1561AslError (
1562    UINT8                   Level,
1563    UINT16                  MessageId,
1564    ACPI_PARSE_OBJECT       *Op,
1565    char                    *ExtraMessage)
1566{
1567    if (Op)
1568    {
1569        AslCommonError (Level, MessageId, Op->Asl.LineNumber,
1570            Op->Asl.LogicalLineNumber,
1571            Op->Asl.LogicalByteOffset,
1572            Op->Asl.Column,
1573            Op->Asl.Filename, ExtraMessage);
1574    }
1575    else
1576    {
1577        AslCommonError (Level, MessageId, 0,
1578            0, 0, 0, NULL, ExtraMessage);
1579    }
1580}
1581
1582
1583/*******************************************************************************
1584 *
1585 * FUNCTION:    AslCoreSubsystemError
1586 *
1587 * PARAMETERS:  Op                  - Parse node where error happened
1588 *              Status              - The ACPICA Exception
1589 *              ExtraMessage        - Additional error message
1590 *              Abort               - TRUE -> Abort compilation
1591 *
1592 * RETURN:      None
1593 *
1594 * DESCRIPTION: Error reporting routine for exceptions returned by the ACPICA
1595 *              core subsystem.
1596 *
1597 ******************************************************************************/
1598
1599void
1600AslCoreSubsystemError (
1601    ACPI_PARSE_OBJECT       *Op,
1602    ACPI_STATUS             Status,
1603    char                    *ExtraMessage,
1604    BOOLEAN                 Abort)
1605{
1606
1607    sprintf (AslGbl_MsgBuffer, "%s %s", AcpiFormatException (Status), ExtraMessage);
1608
1609    if (Op)
1610    {
1611        AslCommonError (ASL_ERROR, ASL_MSG_CORE_EXCEPTION,
1612            Op->Asl.LineNumber,
1613            Op->Asl.LogicalLineNumber,
1614            Op->Asl.LogicalByteOffset,
1615            Op->Asl.Column,
1616            Op->Asl.Filename, AslGbl_MsgBuffer);
1617    }
1618    else
1619    {
1620        AslCommonError (ASL_ERROR, ASL_MSG_CORE_EXCEPTION,
1621            0, 0, 0, 0, NULL, AslGbl_MsgBuffer);
1622    }
1623
1624    if (Abort)
1625    {
1626        AslAbort ();
1627    }
1628}
1629
1630
1631/*******************************************************************************
1632 *
1633 * FUNCTION:    AslCompilererror
1634 *
1635 * PARAMETERS:  CompilerMessage         - Error message from the parser
1636 *
1637 * RETURN:      Status (0 for now)
1638 *
1639 * DESCRIPTION: Report an error situation discovered in a production
1640 *              NOTE: don't change the name of this function, it is called
1641 *              from the auto-generated parser.
1642 *
1643 ******************************************************************************/
1644
1645int
1646AslCompilererror (
1647    const char              *CompilerMessage)
1648{
1649
1650    AslGbl_SyntaxError++;
1651
1652    AslCommonError (ASL_ERROR, ASL_MSG_SYNTAX, AslGbl_CurrentLineNumber,
1653        AslGbl_LogicalLineNumber, AslGbl_CurrentLineOffset,
1654        AslGbl_CurrentColumn, AslGbl_Files[ASL_FILE_INPUT].Filename,
1655        ACPI_CAST_PTR (char, CompilerMessage));
1656
1657    return (0);
1658}
1659