aslerror.c revision 235945
1118611Snjl
2118611Snjl/******************************************************************************
3118611Snjl *
4118611Snjl * Module Name: aslerror - Error handling and statistics
5118611Snjl *
6118611Snjl *****************************************************************************/
7118611Snjl
8217365Sjkim/*
9229989Sjkim * Copyright (C) 2000 - 2012, Intel Corp.
10118611Snjl * All rights reserved.
11118611Snjl *
12217365Sjkim * Redistribution and use in source and binary forms, with or without
13217365Sjkim * modification, are permitted provided that the following conditions
14217365Sjkim * are met:
15217365Sjkim * 1. Redistributions of source code must retain the above copyright
16217365Sjkim *    notice, this list of conditions, and the following disclaimer,
17217365Sjkim *    without modification.
18217365Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer
19217365Sjkim *    substantially similar to the "NO WARRANTY" disclaimer below
20217365Sjkim *    ("Disclaimer") and any redistribution must be conditioned upon
21217365Sjkim *    including a substantially similar Disclaimer requirement for further
22217365Sjkim *    binary redistribution.
23217365Sjkim * 3. Neither the names of the above-listed copyright holders nor the names
24217365Sjkim *    of any contributors may be used to endorse or promote products derived
25217365Sjkim *    from this software without specific prior written permission.
26118611Snjl *
27217365Sjkim * Alternatively, this software may be distributed under the terms of the
28217365Sjkim * GNU General Public License ("GPL") version 2 as published by the Free
29217365Sjkim * Software Foundation.
30118611Snjl *
31217365Sjkim * NO WARRANTY
32217365Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33217365Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34217365Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
35217365Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
36217365Sjkim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37217365Sjkim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38217365Sjkim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39217365Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40217365Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
41217365Sjkim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42217365Sjkim * POSSIBILITY OF SUCH DAMAGES.
43217365Sjkim */
44118611Snjl
45118611Snjl#define ASL_EXCEPTIONS
46151937Sjkim#include <contrib/dev/acpica/compiler/aslcompiler.h>
47118611Snjl
48118611Snjl#define _COMPONENT          ACPI_COMPILER
49118611Snjl        ACPI_MODULE_NAME    ("aslerror")
50118611Snjl
51151937Sjkim/* Local prototypes */
52118611Snjl
53151937Sjkimstatic void
54151937SjkimAeAddToErrorLog (
55151937Sjkim    ASL_ERROR_MSG           *Enode);
56151937Sjkim
57151937Sjkim
58233250Sjkim/*******************************************************************************
59233250Sjkim *
60233250Sjkim * FUNCTION:    AeClearErrorLog
61233250Sjkim *
62233250Sjkim * PARAMETERS:  None
63233250Sjkim *
64233250Sjkim * RETURN:      None
65233250Sjkim *
66233250Sjkim * DESCRIPTION: Empty the error list
67233250Sjkim *
68233250Sjkim ******************************************************************************/
69233250Sjkim
70193529Sjkimvoid
71193529SjkimAeClearErrorLog (
72193529Sjkim    void)
73193529Sjkim{
74193529Sjkim    ASL_ERROR_MSG           *Enode = Gbl_ErrorLog;
75193529Sjkim    ASL_ERROR_MSG           *Next;
76193529Sjkim
77193529Sjkim    /* Walk the error node list */
78193529Sjkim
79193529Sjkim    while (Enode)
80193529Sjkim    {
81193529Sjkim        Next = Enode->Next;
82193529Sjkim        ACPI_FREE (Enode);
83193529Sjkim        Enode = Next;
84193529Sjkim    }
85193529Sjkim
86193529Sjkim    Gbl_ErrorLog = NULL;
87193529Sjkim}
88193529Sjkim
89193529Sjkim
90118611Snjl/*******************************************************************************
91118611Snjl *
92118611Snjl * FUNCTION:    AeAddToErrorLog
93118611Snjl *
94118611Snjl * PARAMETERS:  Enode       - An error node to add to the log
95118611Snjl *
96118611Snjl * RETURN:      None
97118611Snjl *
98118611Snjl * DESCRIPTION: Add a new error node to the error log.  The error log is
99118611Snjl *              ordered by the "logical" line number (cumulative line number
100118611Snjl *              including all include files.)
101118611Snjl *
102118611Snjl ******************************************************************************/
103118611Snjl
104151937Sjkimstatic void
105118611SnjlAeAddToErrorLog (
106118611Snjl    ASL_ERROR_MSG           *Enode)
107118611Snjl{
108118611Snjl    ASL_ERROR_MSG           *Next;
109118611Snjl    ASL_ERROR_MSG           *Prev;
110118611Snjl
111118611Snjl
112202771Sjkim    /* If Gbl_ErrorLog is null, this is the first error node */
113118611Snjl
114118611Snjl    if (!Gbl_ErrorLog)
115118611Snjl    {
116118611Snjl        Gbl_ErrorLog = Enode;
117118611Snjl        return;
118118611Snjl    }
119118611Snjl
120202771Sjkim    /*
121202771Sjkim     * Walk error list until we find a line number greater than ours.
122202771Sjkim     * List is sorted according to line number.
123202771Sjkim     */
124118611Snjl    Prev = NULL;
125118611Snjl    Next = Gbl_ErrorLog;
126118611Snjl
127118611Snjl    while ((Next) &&
128118611Snjl           (Next->LogicalLineNumber <= Enode->LogicalLineNumber))
129118611Snjl    {
130118611Snjl        Prev = Next;
131118611Snjl        Next = Next->Next;
132118611Snjl    }
133118611Snjl
134118611Snjl    /* Found our place in the list */
135118611Snjl
136118611Snjl    Enode->Next = Next;
137118611Snjl
138118611Snjl    if (Prev)
139118611Snjl    {
140118611Snjl        Prev->Next = Enode;
141118611Snjl    }
142118611Snjl    else
143118611Snjl    {
144118611Snjl        Gbl_ErrorLog = Enode;
145118611Snjl    }
146118611Snjl}
147118611Snjl
148118611Snjl
149118611Snjl/*******************************************************************************
150118611Snjl *
151118611Snjl * FUNCTION:    AePrintException
152118611Snjl *
153151937Sjkim * PARAMETERS:  FileId          - ID of output file
154118611Snjl *              Enode           - Error node to print
155118611Snjl *              Header          - Additional text before each message
156118611Snjl *
157118611Snjl * RETURN:      None
158118611Snjl *
159118611Snjl * DESCRIPTION: Print the contents of an error node.
160118611Snjl *
161118611Snjl * NOTE:        We don't use the FlxxxFile I/O functions here because on error
162118611Snjl *              they abort the compiler and call this function!  Since we
163118611Snjl *              are reporting errors here, we ignore most output errors and
164118611Snjl *              just try to get out as much as we can.
165118611Snjl *
166118611Snjl ******************************************************************************/
167118611Snjl
168118611Snjlvoid
169118611SnjlAePrintException (
170118611Snjl    UINT32                  FileId,
171118611Snjl    ASL_ERROR_MSG           *Enode,
172118611Snjl    char                    *Header)
173118611Snjl{
174118611Snjl    UINT8                   SourceByte;
175151937Sjkim    int                     Actual;
176151937Sjkim    size_t                  RActual;
177118611Snjl    UINT32                  MsgLength;
178118611Snjl    char                    *MainMessage;
179118611Snjl    char                    *ExtraMessage;
180118611Snjl    UINT32                  SourceColumn;
181118611Snjl    UINT32                  ErrorColumn;
182118611Snjl    FILE                    *OutputFile;
183233250Sjkim    FILE                    *SourceFile = NULL;
184216471Sjkim    long                    FileSize;
185216471Sjkim    BOOLEAN                 PrematureEOF = FALSE;
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:
204118611Snjl            if (!Gbl_DisplayRemarks)
205118611Snjl            {
206118611Snjl                return;
207118611Snjl            }
208118611Snjl            break;
209118611Snjl
210118611Snjl        case ASL_OPTIMIZATION:
211118611Snjl            if (!Gbl_DisplayOptimizations)
212118611Snjl            {
213118611Snjl                return;
214118611Snjl            }
215118611Snjl            break;
216118611Snjl
217118611Snjl        default:
218118611Snjl            break;
219118611Snjl        }
220118611Snjl    }
221118611Snjl
222118611Snjl    /* Get the file handles */
223118611Snjl
224118611Snjl    OutputFile = Gbl_Files[FileId].Handle;
225209746Sjkim
226209746Sjkim
227233250Sjkim    if (!Enode->SourceLine)
228209746Sjkim    {
229233250Sjkim        /* Use the merged header/source file if present, otherwise use input file */
230118611Snjl
231233250Sjkim        SourceFile = Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Handle;
232233250Sjkim        if (!SourceFile)
233233250Sjkim        {
234233250Sjkim            SourceFile = Gbl_Files[ASL_FILE_INPUT].Handle;
235233250Sjkim        }
236216471Sjkim
237233250Sjkim        if (SourceFile)
238233250Sjkim        {
239233250Sjkim            /* Determine if the error occurred at source file EOF */
240216471Sjkim
241233250Sjkim            fseek (SourceFile, 0, SEEK_END);
242233250Sjkim            FileSize = ftell (SourceFile);
243233250Sjkim
244233250Sjkim            if ((long) Enode->LogicalByteOffset >= FileSize)
245233250Sjkim            {
246233250Sjkim                PrematureEOF = TRUE;
247233250Sjkim            }
248216471Sjkim        }
249216471Sjkim    }
250216471Sjkim
251118611Snjl    if (Header)
252118611Snjl    {
253118611Snjl        fprintf (OutputFile, "%s", Header);
254118611Snjl    }
255118611Snjl
256118611Snjl    /* Print filename and line number if present and valid */
257118611Snjl
258118611Snjl    if (Enode->Filename)
259118611Snjl    {
260118611Snjl        if (Gbl_VerboseErrors)
261118611Snjl        {
262234623Sjkim            fprintf (OutputFile, "%-8s", Enode->Filename);
263118611Snjl
264118611Snjl            if (Enode->LineNumber)
265118611Snjl            {
266233250Sjkim                if (Enode->SourceLine)
267233250Sjkim                {
268233250Sjkim                    fprintf (OutputFile, " %6u: %s",
269233250Sjkim                        Enode->LineNumber, Enode->SourceLine);
270233250Sjkim                }
271233250Sjkim                else
272233250Sjkim                {
273234623Sjkim                    fprintf (OutputFile, " %6u: ", Enode->LineNumber);
274118611Snjl
275216471Sjkim                    /*
276233250Sjkim                     * If not at EOF, get the corresponding source code line and
277233250Sjkim                     * display it. Don't attempt this if we have a premature EOF
278233250Sjkim                     * condition.
279216471Sjkim                     */
280233250Sjkim                    if (!PrematureEOF)
281118611Snjl                    {
282233250Sjkim                        /*
283233250Sjkim                         * Seek to the offset in the combined source file, read
284233250Sjkim                         * the source line, and write it to the output.
285233250Sjkim                         */
286233250Sjkim                        Actual = fseek (SourceFile, (long) Enode->LogicalByteOffset,
287233250Sjkim                                    (int) SEEK_SET);
288233250Sjkim                        if (Actual)
289216471Sjkim                        {
290216471Sjkim                            fprintf (OutputFile,
291233250Sjkim                                "[*** iASL: Seek error on source code temp file %s ***]",
292216471Sjkim                                Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Filename);
293216471Sjkim                        }
294233250Sjkim                        else
295216471Sjkim                        {
296216471Sjkim                            RActual = fread (&SourceByte, 1, 1, SourceFile);
297233250Sjkim                            if (!RActual)
298233250Sjkim                            {
299233250Sjkim                                fprintf (OutputFile,
300233250Sjkim                                    "[*** iASL: Read error on source code temp file %s ***]",
301233250Sjkim                                    Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Filename);
302233250Sjkim                            }
303233250Sjkim
304233250Sjkim                            else while (RActual && SourceByte && (SourceByte != '\n'))
305233250Sjkim                            {
306233250Sjkim                                fwrite (&SourceByte, 1, 1, OutputFile);
307233250Sjkim                                RActual = fread (&SourceByte, 1, 1, SourceFile);
308233250Sjkim                            }
309216471Sjkim                        }
310118611Snjl                    }
311233250Sjkim
312233250Sjkim                    fprintf (OutputFile, "\n");
313118611Snjl                }
314118611Snjl            }
315118611Snjl        }
316118611Snjl        else
317118611Snjl        {
318235945Sjkim            /*
319235945Sjkim             * Less verbose version of the error message, enabled via the
320235945Sjkim             * -vi switch. The format is compatible with MS Visual Studio.
321235945Sjkim             */
322118611Snjl            fprintf (OutputFile, "%s", Enode->Filename);
323118611Snjl
324118611Snjl            if (Enode->LineNumber)
325118611Snjl            {
326235945Sjkim                fprintf (OutputFile, "(%u) : ",
327235945Sjkim                    Enode->LineNumber);
328118611Snjl            }
329118611Snjl        }
330118611Snjl    }
331118611Snjl
332118611Snjl    /* NULL message ID, just print the raw message */
333118611Snjl
334118611Snjl    if (Enode->MessageId == 0)
335118611Snjl    {
336118611Snjl        fprintf (OutputFile, "%s\n", Enode->Message);
337118611Snjl    }
338118611Snjl    else
339118611Snjl    {
340118611Snjl        /* Decode the message ID */
341118611Snjl
342235945Sjkim        if (Gbl_VerboseErrors)
343235945Sjkim        {
344235945Sjkim            fprintf (OutputFile, "%s %4.4d - ",
345235945Sjkim                        AslErrorLevel[Enode->Level],
346235945Sjkim                        Enode->MessageId + ((Enode->Level+1) * 1000));
347235945Sjkim        }
348235945Sjkim        else /* IDE case */
349235945Sjkim        {
350235945Sjkim            fprintf (OutputFile, "%s %4.4d:",
351235945Sjkim                        AslErrorLevelIde[Enode->Level],
352235945Sjkim                        Enode->MessageId + ((Enode->Level+1) * 1000));
353235945Sjkim        }
354118611Snjl
355118611Snjl        MainMessage = AslMessages[Enode->MessageId];
356118611Snjl        ExtraMessage = Enode->Message;
357118611Snjl
358118611Snjl        if (Enode->LineNumber)
359118611Snjl        {
360228110Sjkim            /* Main message: try to use string from AslMessages first */
361228110Sjkim
362228110Sjkim            if (!MainMessage)
363228110Sjkim            {
364228110Sjkim                MainMessage = "";
365228110Sjkim            }
366228110Sjkim
367118611Snjl            MsgLength = strlen (MainMessage);
368118611Snjl            if (MsgLength == 0)
369118611Snjl            {
370228110Sjkim                /* Use the secondary/extra message as main message */
371228110Sjkim
372118611Snjl                MainMessage = Enode->Message;
373228110Sjkim                if (!MainMessage)
374228110Sjkim                {
375228110Sjkim                    MainMessage = "";
376228110Sjkim                }
377118611Snjl
378118611Snjl                MsgLength = strlen (MainMessage);
379118611Snjl                ExtraMessage = NULL;
380118611Snjl            }
381118611Snjl
382216471Sjkim            if (Gbl_VerboseErrors && !PrematureEOF)
383118611Snjl            {
384118611Snjl                SourceColumn = Enode->Column + Enode->FilenameLength + 6 + 2;
385118611Snjl                ErrorColumn = ASL_ERROR_LEVEL_LENGTH + 5 + 2 + 1;
386118611Snjl
387118611Snjl                if ((MsgLength + ErrorColumn) < (SourceColumn - 1))
388118611Snjl                {
389118611Snjl                    fprintf (OutputFile, "%*s%s",
390118611Snjl                        (int) ((SourceColumn - 1) - ErrorColumn),
391118611Snjl                        MainMessage, " ^ ");
392118611Snjl                }
393118611Snjl                else
394118611Snjl                {
395118611Snjl                    fprintf (OutputFile, "%*s %s",
396118611Snjl                        (int) ((SourceColumn - ErrorColumn) + 1), "^",
397118611Snjl                        MainMessage);
398118611Snjl                }
399118611Snjl            }
400118611Snjl            else
401118611Snjl            {
402118611Snjl                fprintf (OutputFile, " %s", MainMessage);
403118611Snjl            }
404118611Snjl
405118611Snjl            /* Print the extra info message if present */
406118611Snjl
407118611Snjl            if (ExtraMessage)
408118611Snjl            {
409118611Snjl                fprintf (OutputFile, " (%s)", ExtraMessage);
410118611Snjl            }
411118611Snjl
412216471Sjkim            if (PrematureEOF)
413216471Sjkim            {
414216471Sjkim                fprintf (OutputFile, " and premature End-Of-File");
415216471Sjkim            }
416216471Sjkim
417118611Snjl            fprintf (OutputFile, "\n");
418118611Snjl            if (Gbl_VerboseErrors)
419118611Snjl            {
420118611Snjl                fprintf (OutputFile, "\n");
421118611Snjl            }
422118611Snjl        }
423118611Snjl        else
424118611Snjl        {
425151937Sjkim            fprintf (OutputFile, " %s %s\n\n", MainMessage, ExtraMessage);
426118611Snjl        }
427118611Snjl    }
428118611Snjl}
429118611Snjl
430118611Snjl
431118611Snjl/*******************************************************************************
432118611Snjl *
433118611Snjl * FUNCTION:    AePrintErrorLog
434118611Snjl *
435118611Snjl * PARAMETERS:  FileId           - Where to output the error log
436118611Snjl *
437118611Snjl * RETURN:      None
438118611Snjl *
439118611Snjl * DESCRIPTION: Print the entire contents of the error log
440118611Snjl *
441118611Snjl ******************************************************************************/
442118611Snjl
443118611Snjlvoid
444118611SnjlAePrintErrorLog (
445118611Snjl    UINT32                  FileId)
446118611Snjl{
447118611Snjl    ASL_ERROR_MSG           *Enode = Gbl_ErrorLog;
448118611Snjl
449118611Snjl
450118611Snjl    /* Walk the error node list */
451118611Snjl
452118611Snjl    while (Enode)
453118611Snjl    {
454118611Snjl        AePrintException (FileId, Enode, NULL);
455118611Snjl        Enode = Enode->Next;
456118611Snjl    }
457118611Snjl}
458118611Snjl
459118611Snjl
460118611Snjl/*******************************************************************************
461118611Snjl *
462233250Sjkim * FUNCTION:    AslCommonError2
463233250Sjkim *
464233250Sjkim * PARAMETERS:  Level               - Seriousness (Warning/error, etc.)
465233250Sjkim *              MessageId           - Index into global message buffer
466233250Sjkim *              LineNumber          - Actual file line number
467233250Sjkim *              Column              - Column in current line
468233250Sjkim *              SourceLine          - Actual source code line
469233250Sjkim *              Filename            - source filename
470233250Sjkim *              ExtraMessage        - additional error message
471233250Sjkim *
472233250Sjkim * RETURN:      None
473233250Sjkim *
474233250Sjkim * DESCRIPTION: Create a new error node and add it to the error log
475233250Sjkim *
476233250Sjkim ******************************************************************************/
477233250Sjkim
478233250Sjkimvoid
479233250SjkimAslCommonError2 (
480233250Sjkim    UINT8                   Level,
481233250Sjkim    UINT8                   MessageId,
482233250Sjkim    UINT32                  LineNumber,
483233250Sjkim    UINT32                  Column,
484233250Sjkim    char                    *SourceLine,
485233250Sjkim    char                    *Filename,
486233250Sjkim    char                    *ExtraMessage)
487233250Sjkim{
488233250Sjkim    char                    *MessageBuffer = NULL;
489233250Sjkim    char                    *LineBuffer;
490233250Sjkim    ASL_ERROR_MSG           *Enode;
491233250Sjkim
492233250Sjkim
493233250Sjkim    Enode = UtLocalCalloc (sizeof (ASL_ERROR_MSG));
494233250Sjkim
495233250Sjkim    if (ExtraMessage)
496233250Sjkim    {
497233250Sjkim        /* Allocate a buffer for the message and a new error node */
498233250Sjkim
499233250Sjkim        MessageBuffer = UtLocalCalloc (strlen (ExtraMessage) + 1);
500233250Sjkim
501233250Sjkim        /* Keep a copy of the extra message */
502233250Sjkim
503233250Sjkim        ACPI_STRCPY (MessageBuffer, ExtraMessage);
504233250Sjkim    }
505233250Sjkim
506233250Sjkim    LineBuffer = UtLocalCalloc (strlen (SourceLine) + 1);
507233250Sjkim    ACPI_STRCPY (LineBuffer, SourceLine);
508233250Sjkim
509233250Sjkim    /* Initialize the error node */
510233250Sjkim
511233250Sjkim    if (Filename)
512233250Sjkim    {
513233250Sjkim        Enode->Filename       = Filename;
514233250Sjkim        Enode->FilenameLength = strlen (Filename);
515233250Sjkim        if (Enode->FilenameLength < 6)
516233250Sjkim        {
517233250Sjkim            Enode->FilenameLength = 6;
518233250Sjkim        }
519233250Sjkim    }
520233250Sjkim
521233250Sjkim    Enode->MessageId            = MessageId;
522233250Sjkim    Enode->Level                = Level;
523233250Sjkim    Enode->LineNumber           = LineNumber;
524233250Sjkim    Enode->LogicalLineNumber    = LineNumber;
525233250Sjkim    Enode->LogicalByteOffset    = 0;
526233250Sjkim    Enode->Column               = Column;
527233250Sjkim    Enode->Message              = MessageBuffer;
528233250Sjkim    Enode->SourceLine           = LineBuffer;
529233250Sjkim
530233250Sjkim    /* Add the new node to the error node list */
531233250Sjkim
532233250Sjkim    AeAddToErrorLog (Enode);
533233250Sjkim
534233250Sjkim    if (Gbl_DebugFlag)
535233250Sjkim    {
536233250Sjkim        /* stderr is a file, send error to it immediately */
537233250Sjkim
538233250Sjkim        AePrintException (ASL_FILE_STDERR, Enode, NULL);
539233250Sjkim    }
540233250Sjkim
541233250Sjkim    Gbl_ExceptionCount[Level]++;
542233250Sjkim}
543233250Sjkim
544233250Sjkim
545233250Sjkim/*******************************************************************************
546233250Sjkim *
547118611Snjl * FUNCTION:    AslCommonError
548118611Snjl *
549118611Snjl * PARAMETERS:  Level               - Seriousness (Warning/error, etc.)
550118611Snjl *              MessageId           - Index into global message buffer
551118611Snjl *              CurrentLineNumber   - Actual file line number
552118611Snjl *              LogicalLineNumber   - Cumulative line number
553118611Snjl *              LogicalByteOffset   - Byte offset in source file
554118611Snjl *              Column              - Column in current line
555118611Snjl *              Filename            - source filename
556118611Snjl *              ExtraMessage        - additional error message
557118611Snjl *
558151937Sjkim * RETURN:      None
559118611Snjl *
560118611Snjl * DESCRIPTION: Create a new error node and add it to the error log
561118611Snjl *
562118611Snjl ******************************************************************************/
563118611Snjl
564118611Snjlvoid
565118611SnjlAslCommonError (
566118611Snjl    UINT8                   Level,
567118611Snjl    UINT8                   MessageId,
568118611Snjl    UINT32                  CurrentLineNumber,
569118611Snjl    UINT32                  LogicalLineNumber,
570118611Snjl    UINT32                  LogicalByteOffset,
571118611Snjl    UINT32                  Column,
572118611Snjl    char                    *Filename,
573118611Snjl    char                    *ExtraMessage)
574118611Snjl{
575118611Snjl    UINT32                  MessageSize;
576118611Snjl    char                    *MessageBuffer = NULL;
577118611Snjl    ASL_ERROR_MSG           *Enode;
578118611Snjl
579118611Snjl
580118611Snjl    Enode = UtLocalCalloc (sizeof (ASL_ERROR_MSG));
581118611Snjl
582118611Snjl    if (ExtraMessage)
583118611Snjl    {
584118611Snjl        /* Allocate a buffer for the message and a new error node */
585118611Snjl
586118611Snjl        MessageSize   = strlen (ExtraMessage) + 1;
587118611Snjl        MessageBuffer = UtLocalCalloc (MessageSize);
588118611Snjl
589118611Snjl        /* Keep a copy of the extra message */
590118611Snjl
591118611Snjl        ACPI_STRCPY (MessageBuffer, ExtraMessage);
592118611Snjl    }
593118611Snjl
594118611Snjl    /* Initialize the error node */
595118611Snjl
596118611Snjl    if (Filename)
597118611Snjl    {
598118611Snjl        Enode->Filename       = Filename;
599118611Snjl        Enode->FilenameLength = strlen (Filename);
600118611Snjl        if (Enode->FilenameLength < 6)
601118611Snjl        {
602118611Snjl            Enode->FilenameLength = 6;
603118611Snjl        }
604118611Snjl    }
605118611Snjl
606118611Snjl    Enode->MessageId            = MessageId;
607118611Snjl    Enode->Level                = Level;
608118611Snjl    Enode->LineNumber           = CurrentLineNumber;
609118611Snjl    Enode->LogicalLineNumber    = LogicalLineNumber;
610118611Snjl    Enode->LogicalByteOffset    = LogicalByteOffset;
611118611Snjl    Enode->Column               = Column;
612118611Snjl    Enode->Message              = MessageBuffer;
613233250Sjkim    Enode->SourceLine           = NULL;
614118611Snjl
615118611Snjl    /* Add the new node to the error node list */
616118611Snjl
617118611Snjl    AeAddToErrorLog (Enode);
618118611Snjl
619118611Snjl    if (Gbl_DebugFlag)
620118611Snjl    {
621118611Snjl        /* stderr is a file, send error to it immediately */
622118611Snjl
623118611Snjl        AePrintException (ASL_FILE_STDERR, Enode, NULL);
624118611Snjl    }
625118611Snjl
626118611Snjl    Gbl_ExceptionCount[Level]++;
627118611Snjl    if (Gbl_ExceptionCount[ASL_ERROR] > ASL_MAX_ERROR_COUNT)
628118611Snjl    {
629209746Sjkim        printf ("\nMaximum error count (%u) exceeded\n", ASL_MAX_ERROR_COUNT);
630118611Snjl
631118611Snjl        Gbl_SourceLine = 0;
632118611Snjl        Gbl_NextError = Gbl_ErrorLog;
633118611Snjl        CmDoOutputFiles ();
634118611Snjl        CmCleanupAndExit ();
635199337Sjkim        exit(1);
636118611Snjl    }
637118611Snjl
638118611Snjl    return;
639118611Snjl}
640118611Snjl
641118611Snjl
642118611Snjl/*******************************************************************************
643118611Snjl *
644118611Snjl * FUNCTION:    AslError
645118611Snjl *
646118611Snjl * PARAMETERS:  Level               - Seriousness (Warning/error, etc.)
647118611Snjl *              MessageId           - Index into global message buffer
648118611Snjl *              Op                  - Parse node where error happened
649118611Snjl *              ExtraMessage        - additional error message
650118611Snjl *
651118611Snjl * RETURN:      None
652118611Snjl *
653118611Snjl * DESCRIPTION: Main error reporting routine for the ASL compiler (all code
654118611Snjl *              except the parser.)
655118611Snjl *
656118611Snjl ******************************************************************************/
657118611Snjl
658118611Snjlvoid
659118611SnjlAslError (
660118611Snjl    UINT8                   Level,
661118611Snjl    UINT8                   MessageId,
662118611Snjl    ACPI_PARSE_OBJECT       *Op,
663118611Snjl    char                    *ExtraMessage)
664118611Snjl{
665118611Snjl
666167802Sjkim    switch (Level)
667167802Sjkim    {
668167802Sjkim    case ASL_WARNING2:
669167802Sjkim    case ASL_WARNING3:
670167802Sjkim        if (Gbl_WarningLevel < Level)
671167802Sjkim        {
672167802Sjkim            return;
673167802Sjkim        }
674167802Sjkim        break;
675167802Sjkim
676167802Sjkim    default:
677167802Sjkim        break;
678167802Sjkim    }
679167802Sjkim
680118611Snjl    if (Op)
681118611Snjl    {
682118611Snjl        AslCommonError (Level, MessageId, Op->Asl.LineNumber,
683118611Snjl                        Op->Asl.LogicalLineNumber,
684118611Snjl                        Op->Asl.LogicalByteOffset,
685118611Snjl                        Op->Asl.Column,
686118611Snjl                        Op->Asl.Filename, ExtraMessage);
687118611Snjl    }
688118611Snjl    else
689118611Snjl    {
690118611Snjl        AslCommonError (Level, MessageId, 0,
691118611Snjl                        0, 0, 0, NULL, ExtraMessage);
692118611Snjl    }
693118611Snjl}
694118611Snjl
695118611Snjl
696118611Snjl/*******************************************************************************
697118611Snjl *
698118611Snjl * FUNCTION:    AslCoreSubsystemError
699118611Snjl *
700118611Snjl * PARAMETERS:  Op                  - Parse node where error happened
701118611Snjl *              Status              - The ACPI CA Exception
702118611Snjl *              ExtraMessage        - additional error message
703118611Snjl *              Abort               - TRUE -> Abort compilation
704118611Snjl *
705118611Snjl * RETURN:      None
706118611Snjl *
707118611Snjl * DESCRIPTION: Error reporting routine for exceptions returned by the ACPI
708118611Snjl *              CA core subsystem.
709118611Snjl *
710118611Snjl ******************************************************************************/
711118611Snjl
712118611Snjlvoid
713118611SnjlAslCoreSubsystemError (
714118611Snjl    ACPI_PARSE_OBJECT       *Op,
715118611Snjl    ACPI_STATUS             Status,
716118611Snjl    char                    *ExtraMessage,
717118611Snjl    BOOLEAN                 Abort)
718118611Snjl{
719118611Snjl
720118611Snjl    sprintf (MsgBuffer, "%s %s", AcpiFormatException (Status), ExtraMessage);
721118611Snjl
722118611Snjl    if (Op)
723118611Snjl    {
724118611Snjl        AslCommonError (ASL_ERROR, ASL_MSG_CORE_EXCEPTION, Op->Asl.LineNumber,
725118611Snjl                        Op->Asl.LogicalLineNumber,
726118611Snjl                        Op->Asl.LogicalByteOffset,
727118611Snjl                        Op->Asl.Column,
728118611Snjl                        Op->Asl.Filename, MsgBuffer);
729118611Snjl    }
730118611Snjl    else
731118611Snjl    {
732118611Snjl        AslCommonError (ASL_ERROR, ASL_MSG_CORE_EXCEPTION, 0,
733118611Snjl                        0, 0, 0, NULL, MsgBuffer);
734118611Snjl    }
735118611Snjl
736118611Snjl    if (Abort)
737118611Snjl    {
738118611Snjl        AslAbort ();
739118611Snjl    }
740118611Snjl}
741118611Snjl
742118611Snjl
743118611Snjl/*******************************************************************************
744118611Snjl *
745118611Snjl * FUNCTION:    AslCompilererror
746118611Snjl *
747118611Snjl * PARAMETERS:  CompilerMessage         - Error message from the parser
748118611Snjl *
749151937Sjkim * RETURN:      Status (0 for now)
750118611Snjl *
751118611Snjl * DESCRIPTION: Report an error situation discovered in a production
752151937Sjkim *              NOTE: don't change the name of this function, it is called
753151937Sjkim *              from the auto-generated parser.
754118611Snjl *
755118611Snjl ******************************************************************************/
756118611Snjl
757118611Snjlint
758118611SnjlAslCompilererror (
759228110Sjkim    const char              *CompilerMessage)
760118611Snjl{
761118611Snjl
762118611Snjl    AslCommonError (ASL_ERROR, ASL_MSG_SYNTAX, Gbl_CurrentLineNumber,
763228110Sjkim        Gbl_LogicalLineNumber, Gbl_CurrentLineOffset,
764228110Sjkim        Gbl_CurrentColumn, Gbl_Files[ASL_FILE_INPUT].Filename,
765228110Sjkim        ACPI_CAST_PTR (char, CompilerMessage));
766118611Snjl
767118611Snjl    return 0;
768118611Snjl}
769