1118611Snjl/******************************************************************************
2118611Snjl *
3118611Snjl * Module Name: aslerror - Error handling and statistics
4118611Snjl *
5118611Snjl *****************************************************************************/
6118611Snjl
7217365Sjkim/*
8245582Sjkim * Copyright (C) 2000 - 2013, Intel Corp.
9118611Snjl * All rights reserved.
10118611Snjl *
11217365Sjkim * Redistribution and use in source and binary forms, with or without
12217365Sjkim * modification, are permitted provided that the following conditions
13217365Sjkim * are met:
14217365Sjkim * 1. Redistributions of source code must retain the above copyright
15217365Sjkim *    notice, this list of conditions, and the following disclaimer,
16217365Sjkim *    without modification.
17217365Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18217365Sjkim *    substantially similar to the "NO WARRANTY" disclaimer below
19217365Sjkim *    ("Disclaimer") and any redistribution must be conditioned upon
20217365Sjkim *    including a substantially similar Disclaimer requirement for further
21217365Sjkim *    binary redistribution.
22217365Sjkim * 3. Neither the names of the above-listed copyright holders nor the names
23217365Sjkim *    of any contributors may be used to endorse or promote products derived
24217365Sjkim *    from this software without specific prior written permission.
25118611Snjl *
26217365Sjkim * Alternatively, this software may be distributed under the terms of the
27217365Sjkim * GNU General Public License ("GPL") version 2 as published by the Free
28217365Sjkim * Software Foundation.
29118611Snjl *
30217365Sjkim * NO WARRANTY
31217365Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32217365Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33217365Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34217365Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35217365Sjkim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36217365Sjkim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37217365Sjkim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38217365Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39217365Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40217365Sjkim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41217365Sjkim * POSSIBILITY OF SUCH DAMAGES.
42217365Sjkim */
43118611Snjl
44118611Snjl#define ASL_EXCEPTIONS
45151937Sjkim#include <contrib/dev/acpica/compiler/aslcompiler.h>
46118611Snjl
47118611Snjl#define _COMPONENT          ACPI_COMPILER
48118611Snjl        ACPI_MODULE_NAME    ("aslerror")
49118611Snjl
50151937Sjkim/* Local prototypes */
51118611Snjl
52151937Sjkimstatic void
53151937SjkimAeAddToErrorLog (
54151937Sjkim    ASL_ERROR_MSG           *Enode);
55151937Sjkim
56151937Sjkim
57233250Sjkim/*******************************************************************************
58233250Sjkim *
59233250Sjkim * FUNCTION:    AeClearErrorLog
60233250Sjkim *
61233250Sjkim * PARAMETERS:  None
62233250Sjkim *
63233250Sjkim * RETURN:      None
64233250Sjkim *
65233250Sjkim * DESCRIPTION: Empty the error list
66233250Sjkim *
67233250Sjkim ******************************************************************************/
68233250Sjkim
69193529Sjkimvoid
70193529SjkimAeClearErrorLog (
71193529Sjkim    void)
72193529Sjkim{
73193529Sjkim    ASL_ERROR_MSG           *Enode = Gbl_ErrorLog;
74193529Sjkim    ASL_ERROR_MSG           *Next;
75193529Sjkim
76193529Sjkim    /* Walk the error node list */
77193529Sjkim
78193529Sjkim    while (Enode)
79193529Sjkim    {
80193529Sjkim        Next = Enode->Next;
81193529Sjkim        ACPI_FREE (Enode);
82193529Sjkim        Enode = Next;
83193529Sjkim    }
84193529Sjkim
85193529Sjkim    Gbl_ErrorLog = NULL;
86193529Sjkim}
87193529Sjkim
88193529Sjkim
89118611Snjl/*******************************************************************************
90118611Snjl *
91118611Snjl * FUNCTION:    AeAddToErrorLog
92118611Snjl *
93118611Snjl * PARAMETERS:  Enode       - An error node to add to the log
94118611Snjl *
95118611Snjl * RETURN:      None
96118611Snjl *
97241973Sjkim * DESCRIPTION: Add a new error node to the error log. The error log is
98118611Snjl *              ordered by the "logical" line number (cumulative line number
99118611Snjl *              including all include files.)
100118611Snjl *
101118611Snjl ******************************************************************************/
102118611Snjl
103151937Sjkimstatic void
104118611SnjlAeAddToErrorLog (
105118611Snjl    ASL_ERROR_MSG           *Enode)
106118611Snjl{
107118611Snjl    ASL_ERROR_MSG           *Next;
108118611Snjl    ASL_ERROR_MSG           *Prev;
109118611Snjl
110118611Snjl
111202771Sjkim    /* If Gbl_ErrorLog is null, this is the first error node */
112118611Snjl
113118611Snjl    if (!Gbl_ErrorLog)
114118611Snjl    {
115118611Snjl        Gbl_ErrorLog = Enode;
116118611Snjl        return;
117118611Snjl    }
118118611Snjl
119202771Sjkim    /*
120202771Sjkim     * Walk error list until we find a line number greater than ours.
121202771Sjkim     * List is sorted according to line number.
122202771Sjkim     */
123118611Snjl    Prev = NULL;
124118611Snjl    Next = Gbl_ErrorLog;
125118611Snjl
126118611Snjl    while ((Next) &&
127118611Snjl           (Next->LogicalLineNumber <= Enode->LogicalLineNumber))
128118611Snjl    {
129118611Snjl        Prev = Next;
130118611Snjl        Next = Next->Next;
131118611Snjl    }
132118611Snjl
133118611Snjl    /* Found our place in the list */
134118611Snjl
135118611Snjl    Enode->Next = Next;
136118611Snjl
137118611Snjl    if (Prev)
138118611Snjl    {
139118611Snjl        Prev->Next = Enode;
140118611Snjl    }
141118611Snjl    else
142118611Snjl    {
143118611Snjl        Gbl_ErrorLog = Enode;
144118611Snjl    }
145118611Snjl}
146118611Snjl
147118611Snjl
148118611Snjl/*******************************************************************************
149118611Snjl *
150118611Snjl * FUNCTION:    AePrintException
151118611Snjl *
152151937Sjkim * PARAMETERS:  FileId          - ID of output file
153118611Snjl *              Enode           - Error node to print
154118611Snjl *              Header          - Additional text before each message
155118611Snjl *
156118611Snjl * RETURN:      None
157118611Snjl *
158118611Snjl * DESCRIPTION: Print the contents of an error node.
159118611Snjl *
160118611Snjl * NOTE:        We don't use the FlxxxFile I/O functions here because on error
161118611Snjl *              they abort the compiler and call this function!  Since we
162118611Snjl *              are reporting errors here, we ignore most output errors and
163118611Snjl *              just try to get out as much as we can.
164118611Snjl *
165118611Snjl ******************************************************************************/
166118611Snjl
167118611Snjlvoid
168118611SnjlAePrintException (
169118611Snjl    UINT32                  FileId,
170118611Snjl    ASL_ERROR_MSG           *Enode,
171118611Snjl    char                    *Header)
172118611Snjl{
173118611Snjl    UINT8                   SourceByte;
174151937Sjkim    int                     Actual;
175151937Sjkim    size_t                  RActual;
176118611Snjl    UINT32                  MsgLength;
177118611Snjl    char                    *MainMessage;
178118611Snjl    char                    *ExtraMessage;
179118611Snjl    UINT32                  SourceColumn;
180118611Snjl    UINT32                  ErrorColumn;
181118611Snjl    FILE                    *OutputFile;
182233250Sjkim    FILE                    *SourceFile = NULL;
183216471Sjkim    long                    FileSize;
184216471Sjkim    BOOLEAN                 PrematureEOF = FALSE;
185240716Sjkim    UINT32                  Total = 0;
186118611Snjl
187118611Snjl
188193529Sjkim    if (Gbl_NoErrors)
189193529Sjkim    {
190193529Sjkim        return;
191193529Sjkim    }
192193529Sjkim
193151937Sjkim    /*
194151937Sjkim     * Only listing files have a header, and remarks/optimizations
195151937Sjkim     * are always output
196151937Sjkim     */
197118611Snjl    if (!Header)
198118611Snjl    {
199118611Snjl        /* Ignore remarks if requested */
200118611Snjl
201118611Snjl        switch (Enode->Level)
202118611Snjl        {
203118611Snjl        case ASL_REMARK:
204250838Sjkim
205118611Snjl            if (!Gbl_DisplayRemarks)
206118611Snjl            {
207118611Snjl                return;
208118611Snjl            }
209118611Snjl            break;
210118611Snjl
211118611Snjl        case ASL_OPTIMIZATION:
212250838Sjkim
213118611Snjl            if (!Gbl_DisplayOptimizations)
214118611Snjl            {
215118611Snjl                return;
216118611Snjl            }
217118611Snjl            break;
218118611Snjl
219118611Snjl        default:
220250838Sjkim
221118611Snjl            break;
222118611Snjl        }
223118611Snjl    }
224118611Snjl
225118611Snjl    /* Get the file handles */
226118611Snjl
227118611Snjl    OutputFile = Gbl_Files[FileId].Handle;
228209746Sjkim
229209746Sjkim
230233250Sjkim    if (!Enode->SourceLine)
231209746Sjkim    {
232233250Sjkim        /* Use the merged header/source file if present, otherwise use input file */
233118611Snjl
234233250Sjkim        SourceFile = Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Handle;
235233250Sjkim        if (!SourceFile)
236233250Sjkim        {
237233250Sjkim            SourceFile = Gbl_Files[ASL_FILE_INPUT].Handle;
238233250Sjkim        }
239216471Sjkim
240233250Sjkim        if (SourceFile)
241233250Sjkim        {
242233250Sjkim            /* Determine if the error occurred at source file EOF */
243216471Sjkim
244233250Sjkim            fseek (SourceFile, 0, SEEK_END);
245233250Sjkim            FileSize = ftell (SourceFile);
246233250Sjkim
247233250Sjkim            if ((long) Enode->LogicalByteOffset >= FileSize)
248233250Sjkim            {
249233250Sjkim                PrematureEOF = TRUE;
250233250Sjkim            }
251216471Sjkim        }
252216471Sjkim    }
253216471Sjkim
254118611Snjl    if (Header)
255118611Snjl    {
256118611Snjl        fprintf (OutputFile, "%s", Header);
257118611Snjl    }
258118611Snjl
259118611Snjl    /* Print filename and line number if present and valid */
260118611Snjl
261118611Snjl    if (Enode->Filename)
262118611Snjl    {
263118611Snjl        if (Gbl_VerboseErrors)
264118611Snjl        {
265234623Sjkim            fprintf (OutputFile, "%-8s", Enode->Filename);
266118611Snjl
267118611Snjl            if (Enode->LineNumber)
268118611Snjl            {
269233250Sjkim                if (Enode->SourceLine)
270233250Sjkim                {
271233250Sjkim                    fprintf (OutputFile, " %6u: %s",
272233250Sjkim                        Enode->LineNumber, Enode->SourceLine);
273233250Sjkim                }
274233250Sjkim                else
275233250Sjkim                {
276234623Sjkim                    fprintf (OutputFile, " %6u: ", Enode->LineNumber);
277118611Snjl
278216471Sjkim                    /*
279233250Sjkim                     * If not at EOF, get the corresponding source code line and
280233250Sjkim                     * display it. Don't attempt this if we have a premature EOF
281233250Sjkim                     * condition.
282216471Sjkim                     */
283233250Sjkim                    if (!PrematureEOF)
284118611Snjl                    {
285233250Sjkim                        /*
286233250Sjkim                         * Seek to the offset in the combined source file, read
287233250Sjkim                         * the source line, and write it to the output.
288233250Sjkim                         */
289233250Sjkim                        Actual = fseek (SourceFile, (long) Enode->LogicalByteOffset,
290233250Sjkim                                    (int) SEEK_SET);
291233250Sjkim                        if (Actual)
292216471Sjkim                        {
293216471Sjkim                            fprintf (OutputFile,
294233250Sjkim                                "[*** iASL: Seek error on source code temp file %s ***]",
295216471Sjkim                                Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Filename);
296216471Sjkim                        }
297233250Sjkim                        else
298216471Sjkim                        {
299216471Sjkim                            RActual = fread (&SourceByte, 1, 1, SourceFile);
300243347Sjkim                            if (RActual != 1)
301233250Sjkim                            {
302233250Sjkim                                fprintf (OutputFile,
303233250Sjkim                                    "[*** iASL: Read error on source code temp file %s ***]",
304233250Sjkim                                    Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Filename);
305233250Sjkim                            }
306240716Sjkim                            else
307240716Sjkim                            {
308249112Sjkim                                /* Read/write the source line, up to the maximum line length */
309249112Sjkim
310249112Sjkim                                while (RActual && SourceByte && (SourceByte != '\n'))
311240716Sjkim                                {
312249112Sjkim                                    if (Total < 256)
313243347Sjkim                                    {
314249112Sjkim                                        /* After the max line length, we will just read the line, no write */
315249112Sjkim
316249112Sjkim                                        if (fwrite (&SourceByte, 1, 1, OutputFile) != 1)
317249112Sjkim                                        {
318249112Sjkim                                            printf ("[*** iASL: Write error on output file ***]\n");
319249112Sjkim                                            return;
320249112Sjkim                                        }
321243347Sjkim                                    }
322249112Sjkim                                    else if (Total == 256)
323249112Sjkim                                    {
324249112Sjkim                                        fprintf (OutputFile,
325249112Sjkim                                            "\n[*** iASL: Very long input line, message below refers to column %u ***]",
326249112Sjkim                                            Enode->Column);
327249112Sjkim                                    }
328243347Sjkim
329240716Sjkim                                    RActual = fread (&SourceByte, 1, 1, SourceFile);
330243347Sjkim                                    if (RActual != 1)
331243347Sjkim                                    {
332243347Sjkim                                        fprintf (OutputFile,
333243347Sjkim                                            "[*** iASL: Read error on source code temp file %s ***]",
334243347Sjkim                                            Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Filename);
335243347Sjkim                                        return;
336243347Sjkim                                    }
337240716Sjkim                                    Total++;
338240716Sjkim                                }
339233250Sjkim                            }
340216471Sjkim                        }
341118611Snjl                    }
342233250Sjkim
343233250Sjkim                    fprintf (OutputFile, "\n");
344118611Snjl                }
345118611Snjl            }
346118611Snjl        }
347118611Snjl        else
348118611Snjl        {
349235945Sjkim            /*
350235945Sjkim             * Less verbose version of the error message, enabled via the
351235945Sjkim             * -vi switch. The format is compatible with MS Visual Studio.
352235945Sjkim             */
353118611Snjl            fprintf (OutputFile, "%s", Enode->Filename);
354118611Snjl
355118611Snjl            if (Enode->LineNumber)
356118611Snjl            {
357235945Sjkim                fprintf (OutputFile, "(%u) : ",
358235945Sjkim                    Enode->LineNumber);
359118611Snjl            }
360118611Snjl        }
361118611Snjl    }
362118611Snjl
363118611Snjl    /* NULL message ID, just print the raw message */
364118611Snjl
365118611Snjl    if (Enode->MessageId == 0)
366118611Snjl    {
367118611Snjl        fprintf (OutputFile, "%s\n", Enode->Message);
368118611Snjl    }
369118611Snjl    else
370118611Snjl    {
371118611Snjl        /* Decode the message ID */
372118611Snjl
373235945Sjkim        if (Gbl_VerboseErrors)
374235945Sjkim        {
375237412Sjkim            fprintf (OutputFile, "%s %4.4d -",
376235945Sjkim                        AslErrorLevel[Enode->Level],
377235945Sjkim                        Enode->MessageId + ((Enode->Level+1) * 1000));
378235945Sjkim        }
379235945Sjkim        else /* IDE case */
380235945Sjkim        {
381235945Sjkim            fprintf (OutputFile, "%s %4.4d:",
382235945Sjkim                        AslErrorLevelIde[Enode->Level],
383235945Sjkim                        Enode->MessageId + ((Enode->Level+1) * 1000));
384235945Sjkim        }
385118611Snjl
386118611Snjl        MainMessage = AslMessages[Enode->MessageId];
387118611Snjl        ExtraMessage = Enode->Message;
388118611Snjl
389118611Snjl        if (Enode->LineNumber)
390118611Snjl        {
391228110Sjkim            /* Main message: try to use string from AslMessages first */
392228110Sjkim
393228110Sjkim            if (!MainMessage)
394228110Sjkim            {
395228110Sjkim                MainMessage = "";
396228110Sjkim            }
397228110Sjkim
398118611Snjl            MsgLength = strlen (MainMessage);
399118611Snjl            if (MsgLength == 0)
400118611Snjl            {
401228110Sjkim                /* Use the secondary/extra message as main message */
402228110Sjkim
403118611Snjl                MainMessage = Enode->Message;
404228110Sjkim                if (!MainMessage)
405228110Sjkim                {
406228110Sjkim                    MainMessage = "";
407228110Sjkim                }
408118611Snjl
409118611Snjl                MsgLength = strlen (MainMessage);
410118611Snjl                ExtraMessage = NULL;
411118611Snjl            }
412118611Snjl
413216471Sjkim            if (Gbl_VerboseErrors && !PrematureEOF)
414118611Snjl            {
415240716Sjkim                if (Total >= 256)
416118611Snjl                {
417240716Sjkim                    fprintf (OutputFile, "    %s",
418240716Sjkim                        MainMessage);
419118611Snjl                }
420118611Snjl                else
421118611Snjl                {
422240716Sjkim                    SourceColumn = Enode->Column + Enode->FilenameLength + 6 + 2;
423240716Sjkim                    ErrorColumn = ASL_ERROR_LEVEL_LENGTH + 5 + 2 + 1;
424240716Sjkim
425240716Sjkim                    if ((MsgLength + ErrorColumn) < (SourceColumn - 1))
426240716Sjkim                    {
427240716Sjkim                        fprintf (OutputFile, "%*s%s",
428240716Sjkim                            (int) ((SourceColumn - 1) - ErrorColumn),
429240716Sjkim                            MainMessage, " ^ ");
430240716Sjkim                    }
431240716Sjkim                    else
432240716Sjkim                    {
433240716Sjkim                        fprintf (OutputFile, "%*s %s",
434240716Sjkim                            (int) ((SourceColumn - ErrorColumn) + 1), "^",
435240716Sjkim                            MainMessage);
436240716Sjkim                    }
437118611Snjl                }
438118611Snjl            }
439118611Snjl            else
440118611Snjl            {
441118611Snjl                fprintf (OutputFile, " %s", MainMessage);
442118611Snjl            }
443118611Snjl
444118611Snjl            /* Print the extra info message if present */
445118611Snjl
446118611Snjl            if (ExtraMessage)
447118611Snjl            {
448118611Snjl                fprintf (OutputFile, " (%s)", ExtraMessage);
449118611Snjl            }
450118611Snjl
451216471Sjkim            if (PrematureEOF)
452216471Sjkim            {
453216471Sjkim                fprintf (OutputFile, " and premature End-Of-File");
454216471Sjkim            }
455216471Sjkim
456118611Snjl            fprintf (OutputFile, "\n");
457118611Snjl            if (Gbl_VerboseErrors)
458118611Snjl            {
459118611Snjl                fprintf (OutputFile, "\n");
460118611Snjl            }
461118611Snjl        }
462118611Snjl        else
463118611Snjl        {
464151937Sjkim            fprintf (OutputFile, " %s %s\n\n", MainMessage, ExtraMessage);
465118611Snjl        }
466118611Snjl    }
467118611Snjl}
468118611Snjl
469118611Snjl
470118611Snjl/*******************************************************************************
471118611Snjl *
472118611Snjl * FUNCTION:    AePrintErrorLog
473118611Snjl *
474118611Snjl * PARAMETERS:  FileId           - Where to output the error log
475118611Snjl *
476118611Snjl * RETURN:      None
477118611Snjl *
478118611Snjl * DESCRIPTION: Print the entire contents of the error log
479118611Snjl *
480118611Snjl ******************************************************************************/
481118611Snjl
482118611Snjlvoid
483118611SnjlAePrintErrorLog (
484118611Snjl    UINT32                  FileId)
485118611Snjl{
486118611Snjl    ASL_ERROR_MSG           *Enode = Gbl_ErrorLog;
487118611Snjl
488118611Snjl
489118611Snjl    /* Walk the error node list */
490118611Snjl
491118611Snjl    while (Enode)
492118611Snjl    {
493118611Snjl        AePrintException (FileId, Enode, NULL);
494118611Snjl        Enode = Enode->Next;
495118611Snjl    }
496118611Snjl}
497118611Snjl
498118611Snjl
499118611Snjl/*******************************************************************************
500118611Snjl *
501233250Sjkim * FUNCTION:    AslCommonError2
502233250Sjkim *
503233250Sjkim * PARAMETERS:  Level               - Seriousness (Warning/error, etc.)
504233250Sjkim *              MessageId           - Index into global message buffer
505233250Sjkim *              LineNumber          - Actual file line number
506233250Sjkim *              Column              - Column in current line
507233250Sjkim *              SourceLine          - Actual source code line
508233250Sjkim *              Filename            - source filename
509233250Sjkim *              ExtraMessage        - additional error message
510233250Sjkim *
511233250Sjkim * RETURN:      None
512233250Sjkim *
513233250Sjkim * DESCRIPTION: Create a new error node and add it to the error log
514233250Sjkim *
515233250Sjkim ******************************************************************************/
516233250Sjkim
517233250Sjkimvoid
518233250SjkimAslCommonError2 (
519233250Sjkim    UINT8                   Level,
520233250Sjkim    UINT8                   MessageId,
521233250Sjkim    UINT32                  LineNumber,
522233250Sjkim    UINT32                  Column,
523233250Sjkim    char                    *SourceLine,
524233250Sjkim    char                    *Filename,
525233250Sjkim    char                    *ExtraMessage)
526233250Sjkim{
527233250Sjkim    char                    *MessageBuffer = NULL;
528233250Sjkim    char                    *LineBuffer;
529233250Sjkim    ASL_ERROR_MSG           *Enode;
530233250Sjkim
531233250Sjkim
532233250Sjkim    Enode = UtLocalCalloc (sizeof (ASL_ERROR_MSG));
533233250Sjkim
534233250Sjkim    if (ExtraMessage)
535233250Sjkim    {
536233250Sjkim        /* Allocate a buffer for the message and a new error node */
537233250Sjkim
538233250Sjkim        MessageBuffer = UtLocalCalloc (strlen (ExtraMessage) + 1);
539233250Sjkim
540233250Sjkim        /* Keep a copy of the extra message */
541233250Sjkim
542233250Sjkim        ACPI_STRCPY (MessageBuffer, ExtraMessage);
543233250Sjkim    }
544233250Sjkim
545233250Sjkim    LineBuffer = UtLocalCalloc (strlen (SourceLine) + 1);
546233250Sjkim    ACPI_STRCPY (LineBuffer, SourceLine);
547233250Sjkim
548233250Sjkim    /* Initialize the error node */
549233250Sjkim
550233250Sjkim    if (Filename)
551233250Sjkim    {
552233250Sjkim        Enode->Filename       = Filename;
553233250Sjkim        Enode->FilenameLength = strlen (Filename);
554233250Sjkim        if (Enode->FilenameLength < 6)
555233250Sjkim        {
556233250Sjkim            Enode->FilenameLength = 6;
557233250Sjkim        }
558233250Sjkim    }
559233250Sjkim
560233250Sjkim    Enode->MessageId            = MessageId;
561233250Sjkim    Enode->Level                = Level;
562233250Sjkim    Enode->LineNumber           = LineNumber;
563233250Sjkim    Enode->LogicalLineNumber    = LineNumber;
564233250Sjkim    Enode->LogicalByteOffset    = 0;
565233250Sjkim    Enode->Column               = Column;
566233250Sjkim    Enode->Message              = MessageBuffer;
567233250Sjkim    Enode->SourceLine           = LineBuffer;
568233250Sjkim
569233250Sjkim    /* Add the new node to the error node list */
570233250Sjkim
571233250Sjkim    AeAddToErrorLog (Enode);
572233250Sjkim
573233250Sjkim    if (Gbl_DebugFlag)
574233250Sjkim    {
575233250Sjkim        /* stderr is a file, send error to it immediately */
576233250Sjkim
577233250Sjkim        AePrintException (ASL_FILE_STDERR, Enode, NULL);
578233250Sjkim    }
579233250Sjkim
580233250Sjkim    Gbl_ExceptionCount[Level]++;
581233250Sjkim}
582233250Sjkim
583233250Sjkim
584233250Sjkim/*******************************************************************************
585233250Sjkim *
586118611Snjl * FUNCTION:    AslCommonError
587118611Snjl *
588118611Snjl * PARAMETERS:  Level               - Seriousness (Warning/error, etc.)
589118611Snjl *              MessageId           - Index into global message buffer
590118611Snjl *              CurrentLineNumber   - Actual file line number
591118611Snjl *              LogicalLineNumber   - Cumulative line number
592118611Snjl *              LogicalByteOffset   - Byte offset in source file
593118611Snjl *              Column              - Column in current line
594118611Snjl *              Filename            - source filename
595118611Snjl *              ExtraMessage        - additional error message
596118611Snjl *
597151937Sjkim * RETURN:      None
598118611Snjl *
599118611Snjl * DESCRIPTION: Create a new error node and add it to the error log
600118611Snjl *
601118611Snjl ******************************************************************************/
602118611Snjl
603118611Snjlvoid
604118611SnjlAslCommonError (
605118611Snjl    UINT8                   Level,
606118611Snjl    UINT8                   MessageId,
607118611Snjl    UINT32                  CurrentLineNumber,
608118611Snjl    UINT32                  LogicalLineNumber,
609118611Snjl    UINT32                  LogicalByteOffset,
610118611Snjl    UINT32                  Column,
611118611Snjl    char                    *Filename,
612118611Snjl    char                    *ExtraMessage)
613118611Snjl{
614118611Snjl    UINT32                  MessageSize;
615118611Snjl    char                    *MessageBuffer = NULL;
616118611Snjl    ASL_ERROR_MSG           *Enode;
617118611Snjl
618118611Snjl
619118611Snjl    Enode = UtLocalCalloc (sizeof (ASL_ERROR_MSG));
620118611Snjl
621118611Snjl    if (ExtraMessage)
622118611Snjl    {
623118611Snjl        /* Allocate a buffer for the message and a new error node */
624118611Snjl
625118611Snjl        MessageSize   = strlen (ExtraMessage) + 1;
626118611Snjl        MessageBuffer = UtLocalCalloc (MessageSize);
627118611Snjl
628118611Snjl        /* Keep a copy of the extra message */
629118611Snjl
630118611Snjl        ACPI_STRCPY (MessageBuffer, ExtraMessage);
631118611Snjl    }
632118611Snjl
633118611Snjl    /* Initialize the error node */
634118611Snjl
635118611Snjl    if (Filename)
636118611Snjl    {
637118611Snjl        Enode->Filename       = Filename;
638118611Snjl        Enode->FilenameLength = strlen (Filename);
639118611Snjl        if (Enode->FilenameLength < 6)
640118611Snjl        {
641118611Snjl            Enode->FilenameLength = 6;
642118611Snjl        }
643118611Snjl    }
644118611Snjl
645118611Snjl    Enode->MessageId            = MessageId;
646118611Snjl    Enode->Level                = Level;
647118611Snjl    Enode->LineNumber           = CurrentLineNumber;
648118611Snjl    Enode->LogicalLineNumber    = LogicalLineNumber;
649118611Snjl    Enode->LogicalByteOffset    = LogicalByteOffset;
650118611Snjl    Enode->Column               = Column;
651118611Snjl    Enode->Message              = MessageBuffer;
652233250Sjkim    Enode->SourceLine           = NULL;
653118611Snjl
654118611Snjl    /* Add the new node to the error node list */
655118611Snjl
656118611Snjl    AeAddToErrorLog (Enode);
657118611Snjl
658118611Snjl    if (Gbl_DebugFlag)
659118611Snjl    {
660118611Snjl        /* stderr is a file, send error to it immediately */
661118611Snjl
662118611Snjl        AePrintException (ASL_FILE_STDERR, Enode, NULL);
663118611Snjl    }
664118611Snjl
665118611Snjl    Gbl_ExceptionCount[Level]++;
666118611Snjl    if (Gbl_ExceptionCount[ASL_ERROR] > ASL_MAX_ERROR_COUNT)
667118611Snjl    {
668209746Sjkim        printf ("\nMaximum error count (%u) exceeded\n", ASL_MAX_ERROR_COUNT);
669118611Snjl
670118611Snjl        Gbl_SourceLine = 0;
671118611Snjl        Gbl_NextError = Gbl_ErrorLog;
672118611Snjl        CmCleanupAndExit ();
673199337Sjkim        exit(1);
674118611Snjl    }
675118611Snjl
676118611Snjl    return;
677118611Snjl}
678118611Snjl
679118611Snjl
680118611Snjl/*******************************************************************************
681118611Snjl *
682250838Sjkim * FUNCTION:    AslDisableException
683250838Sjkim *
684250838Sjkim * PARAMETERS:  MessageIdString     - ID to be disabled
685250838Sjkim *
686250838Sjkim * RETURN:      Status
687250838Sjkim *
688250838Sjkim * DESCRIPTION: Enter a message ID into the global disabled messages table
689250838Sjkim *
690250838Sjkim ******************************************************************************/
691250838Sjkim
692250838SjkimACPI_STATUS
693250838SjkimAslDisableException (
694250838Sjkim    char                    *MessageIdString)
695250838Sjkim{
696250838Sjkim    UINT32                  MessageId;
697250838Sjkim
698250838Sjkim
699250838Sjkim    /* Convert argument to an integer and validate it */
700250838Sjkim
701250838Sjkim    MessageId = (UINT32) strtoul (MessageIdString, NULL, 0);
702250838Sjkim
703250838Sjkim    if ((MessageId < 2000) || (MessageId > 5999))
704250838Sjkim    {
705250838Sjkim        printf ("\"%s\" is not a valid warning/remark ID\n",
706250838Sjkim            MessageIdString);
707250838Sjkim        return (AE_BAD_PARAMETER);
708250838Sjkim    }
709250838Sjkim
710250838Sjkim    /* Insert value into the global disabled message array */
711250838Sjkim
712250838Sjkim    if (Gbl_DisabledMessagesIndex >= ASL_MAX_DISABLED_MESSAGES)
713250838Sjkim    {
714250838Sjkim        printf ("Too many messages have been disabled (max %u)\n",
715250838Sjkim            ASL_MAX_DISABLED_MESSAGES);
716250838Sjkim        return (AE_LIMIT);
717250838Sjkim    }
718250838Sjkim
719250838Sjkim    Gbl_DisabledMessages[Gbl_DisabledMessagesIndex] = MessageId;
720250838Sjkim    Gbl_DisabledMessagesIndex++;
721250838Sjkim    return (AE_OK);
722250838Sjkim}
723250838Sjkim
724250838Sjkim
725250838Sjkim/*******************************************************************************
726250838Sjkim *
727250838Sjkim * FUNCTION:    AslIsExceptionDisabled
728250838Sjkim *
729250838Sjkim * PARAMETERS:  Level               - Seriousness (Warning/error, etc.)
730250838Sjkim *              MessageId           - Index into global message buffer
731250838Sjkim *
732250838Sjkim * RETURN:      TRUE if exception/message should be ignored
733250838Sjkim *
734250838Sjkim * DESCRIPTION: Check if the user has specified options such that this
735250838Sjkim *              exception should be ignored
736250838Sjkim *
737250838Sjkim ******************************************************************************/
738250838Sjkim
739250838SjkimBOOLEAN
740250838SjkimAslIsExceptionDisabled (
741250838Sjkim    UINT8                   Level,
742250838Sjkim    UINT8                   MessageId)
743250838Sjkim{
744250838Sjkim    UINT32                  EncodedMessageId;
745250838Sjkim    UINT32                  i;
746250838Sjkim
747250838Sjkim
748250838Sjkim    switch (Level)
749250838Sjkim    {
750250838Sjkim    case ASL_WARNING2:
751250838Sjkim    case ASL_WARNING3:
752250838Sjkim
753250838Sjkim        /* Check for global disable via -w1/-w2/-w3 options */
754250838Sjkim
755250838Sjkim        if (Level > Gbl_WarningLevel)
756250838Sjkim        {
757250838Sjkim            return (TRUE);
758250838Sjkim        }
759250838Sjkim        /* Fall through */
760250838Sjkim
761250838Sjkim    case ASL_WARNING:
762250838Sjkim    case ASL_REMARK:
763250838Sjkim        /*
764250838Sjkim         * Ignore this warning/remark if it has been disabled by
765250838Sjkim         * the user (-vw option)
766250838Sjkim         */
767250838Sjkim        EncodedMessageId = MessageId + ((Level + 1) * 1000);
768250838Sjkim        for (i = 0; i < Gbl_DisabledMessagesIndex; i++)
769250838Sjkim        {
770250838Sjkim            /* Simple implementation via fixed array */
771250838Sjkim
772250838Sjkim            if (EncodedMessageId == Gbl_DisabledMessages[i])
773250838Sjkim            {
774250838Sjkim                return (TRUE);
775250838Sjkim            }
776250838Sjkim        }
777250838Sjkim        break;
778250838Sjkim
779250838Sjkim    default:
780250838Sjkim        break;
781250838Sjkim    }
782250838Sjkim
783250838Sjkim    return (FALSE);
784250838Sjkim}
785250838Sjkim
786250838Sjkim
787250838Sjkim/*******************************************************************************
788250838Sjkim *
789118611Snjl * FUNCTION:    AslError
790118611Snjl *
791118611Snjl * PARAMETERS:  Level               - Seriousness (Warning/error, etc.)
792118611Snjl *              MessageId           - Index into global message buffer
793118611Snjl *              Op                  - Parse node where error happened
794118611Snjl *              ExtraMessage        - additional error message
795118611Snjl *
796118611Snjl * RETURN:      None
797118611Snjl *
798118611Snjl * DESCRIPTION: Main error reporting routine for the ASL compiler (all code
799118611Snjl *              except the parser.)
800118611Snjl *
801118611Snjl ******************************************************************************/
802118611Snjl
803118611Snjlvoid
804118611SnjlAslError (
805118611Snjl    UINT8                   Level,
806118611Snjl    UINT8                   MessageId,
807118611Snjl    ACPI_PARSE_OBJECT       *Op,
808118611Snjl    char                    *ExtraMessage)
809118611Snjl{
810118611Snjl
811250838Sjkim    /* Check if user wants to ignore this exception */
812250838Sjkim
813250838Sjkim    if (AslIsExceptionDisabled (Level, MessageId))
814167802Sjkim    {
815250838Sjkim        return;
816167802Sjkim    }
817167802Sjkim
818118611Snjl    if (Op)
819118611Snjl    {
820118611Snjl        AslCommonError (Level, MessageId, Op->Asl.LineNumber,
821250838Sjkim            Op->Asl.LogicalLineNumber,
822250838Sjkim            Op->Asl.LogicalByteOffset,
823250838Sjkim            Op->Asl.Column,
824250838Sjkim            Op->Asl.Filename, ExtraMessage);
825118611Snjl    }
826118611Snjl    else
827118611Snjl    {
828118611Snjl        AslCommonError (Level, MessageId, 0,
829250838Sjkim            0, 0, 0, NULL, ExtraMessage);
830118611Snjl    }
831118611Snjl}
832118611Snjl
833118611Snjl
834118611Snjl/*******************************************************************************
835118611Snjl *
836118611Snjl * FUNCTION:    AslCoreSubsystemError
837118611Snjl *
838118611Snjl * PARAMETERS:  Op                  - Parse node where error happened
839118611Snjl *              Status              - The ACPI CA Exception
840118611Snjl *              ExtraMessage        - additional error message
841118611Snjl *              Abort               - TRUE -> Abort compilation
842118611Snjl *
843118611Snjl * RETURN:      None
844118611Snjl *
845118611Snjl * DESCRIPTION: Error reporting routine for exceptions returned by the ACPI
846118611Snjl *              CA core subsystem.
847118611Snjl *
848118611Snjl ******************************************************************************/
849118611Snjl
850118611Snjlvoid
851118611SnjlAslCoreSubsystemError (
852118611Snjl    ACPI_PARSE_OBJECT       *Op,
853118611Snjl    ACPI_STATUS             Status,
854118611Snjl    char                    *ExtraMessage,
855118611Snjl    BOOLEAN                 Abort)
856118611Snjl{
857118611Snjl
858118611Snjl    sprintf (MsgBuffer, "%s %s", AcpiFormatException (Status), ExtraMessage);
859118611Snjl
860118611Snjl    if (Op)
861118611Snjl    {
862118611Snjl        AslCommonError (ASL_ERROR, ASL_MSG_CORE_EXCEPTION, Op->Asl.LineNumber,
863118611Snjl                        Op->Asl.LogicalLineNumber,
864118611Snjl                        Op->Asl.LogicalByteOffset,
865118611Snjl                        Op->Asl.Column,
866118611Snjl                        Op->Asl.Filename, MsgBuffer);
867118611Snjl    }
868118611Snjl    else
869118611Snjl    {
870118611Snjl        AslCommonError (ASL_ERROR, ASL_MSG_CORE_EXCEPTION, 0,
871118611Snjl                        0, 0, 0, NULL, MsgBuffer);
872118611Snjl    }
873118611Snjl
874118611Snjl    if (Abort)
875118611Snjl    {
876118611Snjl        AslAbort ();
877118611Snjl    }
878118611Snjl}
879118611Snjl
880118611Snjl
881118611Snjl/*******************************************************************************
882118611Snjl *
883118611Snjl * FUNCTION:    AslCompilererror
884118611Snjl *
885118611Snjl * PARAMETERS:  CompilerMessage         - Error message from the parser
886118611Snjl *
887151937Sjkim * RETURN:      Status (0 for now)
888118611Snjl *
889118611Snjl * DESCRIPTION: Report an error situation discovered in a production
890151937Sjkim *              NOTE: don't change the name of this function, it is called
891151937Sjkim *              from the auto-generated parser.
892118611Snjl *
893118611Snjl ******************************************************************************/
894118611Snjl
895118611Snjlint
896118611SnjlAslCompilererror (
897228110Sjkim    const char              *CompilerMessage)
898118611Snjl{
899118611Snjl
900118611Snjl    AslCommonError (ASL_ERROR, ASL_MSG_SYNTAX, Gbl_CurrentLineNumber,
901228110Sjkim        Gbl_LogicalLineNumber, Gbl_CurrentLineOffset,
902228110Sjkim        Gbl_CurrentColumn, Gbl_Files[ASL_FILE_INPUT].Filename,
903228110Sjkim        ACPI_CAST_PTR (char, CompilerMessage));
904118611Snjl
905241973Sjkim    return (0);
906118611Snjl}
907