1 /******************************************************************************
3 * Module Name: aslerror - Error handling and statistics
5 *****************************************************************************/
8 * Copyright (C) 2000 - 2012, Intel Corp.
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions, and the following disclaimer,
16 * without modification.
17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18 * substantially similar to the "NO WARRANTY" disclaimer below
19 * ("Disclaimer") and any redistribution must be conditioned upon
20 * including a substantially similar Disclaimer requirement for further
21 * binary redistribution.
22 * 3. Neither the names of the above-listed copyright holders nor the names
23 * of any contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
26 * Alternatively, this software may be distributed under the terms of the
27 * GNU General Public License ("GPL") version 2 as published by the Free
28 * Software Foundation.
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGES.
44 #define ASL_EXCEPTIONS
45 #include "aslcompiler.h"
47 #define _COMPONENT ACPI_COMPILER
48 ACPI_MODULE_NAME ("aslerror")
50 /* Local prototypes */
54 ASL_ERROR_MSG *Enode);
57 /*******************************************************************************
59 * FUNCTION: AeClearErrorLog
65 * DESCRIPTION: Empty the error list
67 ******************************************************************************/
73 ASL_ERROR_MSG *Enode = Gbl_ErrorLog;
76 /* Walk the error node list */
89 /*******************************************************************************
91 * FUNCTION: AeAddToErrorLog
93 * PARAMETERS: Enode - An error node to add to the log
97 * DESCRIPTION: Add a new error node to the error log. The error log is
98 * ordered by the "logical" line number (cumulative line number
99 * including all include files.)
101 ******************************************************************************/
105 ASL_ERROR_MSG *Enode)
111 /* If Gbl_ErrorLog is null, this is the first error node */
115 Gbl_ErrorLog = Enode;
120 * Walk error list until we find a line number greater than ours.
121 * List is sorted according to line number.
127 (Next->LogicalLineNumber <= Enode->LogicalLineNumber))
133 /* Found our place in the list */
143 Gbl_ErrorLog = Enode;
148 /*******************************************************************************
150 * FUNCTION: AePrintException
152 * PARAMETERS: FileId - ID of output file
153 * Enode - Error node to print
154 * Header - Additional text before each message
158 * DESCRIPTION: Print the contents of an error node.
160 * NOTE: We don't use the FlxxxFile I/O functions here because on error
161 * they abort the compiler and call this function! Since we
162 * are reporting errors here, we ignore most output errors and
163 * just try to get out as much as we can.
165 ******************************************************************************/
170 ASL_ERROR_MSG *Enode,
182 FILE *SourceFile = NULL;
184 BOOLEAN PrematureEOF = FALSE;
194 * Only listing files have a header, and remarks/optimizations
199 /* Ignore remarks if requested */
201 switch (Enode->Level)
204 if (!Gbl_DisplayRemarks)
210 case ASL_OPTIMIZATION:
211 if (!Gbl_DisplayOptimizations)
222 /* Get the file handles */
224 OutputFile = Gbl_Files[FileId].Handle;
227 if (!Enode->SourceLine)
229 /* Use the merged header/source file if present, otherwise use input file */
231 SourceFile = Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Handle;
234 SourceFile = Gbl_Files[ASL_FILE_INPUT].Handle;
239 /* Determine if the error occurred at source file EOF */
241 fseek (SourceFile, 0, SEEK_END);
242 FileSize = ftell (SourceFile);
244 if ((long) Enode->LogicalByteOffset >= FileSize)
253 fprintf (OutputFile, "%s", Header);
256 /* Print filename and line number if present and valid */
260 if (Gbl_VerboseErrors)
262 fprintf (OutputFile, "%-8s", Enode->Filename);
264 if (Enode->LineNumber)
266 if (Enode->SourceLine)
268 fprintf (OutputFile, " %6u: %s",
269 Enode->LineNumber, Enode->SourceLine);
273 fprintf (OutputFile, " %6u: ", Enode->LineNumber);
276 * If not at EOF, get the corresponding source code line and
277 * display it. Don't attempt this if we have a premature EOF
283 * Seek to the offset in the combined source file, read
284 * the source line, and write it to the output.
286 Actual = fseek (SourceFile, (long) Enode->LogicalByteOffset,
291 "[*** iASL: Seek error on source code temp file %s ***]",
292 Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Filename);
296 RActual = fread (&SourceByte, 1, 1, SourceFile);
300 "[*** iASL: Read error on source code temp file %s ***]",
301 Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Filename);
305 while (RActual && SourceByte && (SourceByte != '\n') && (Total < 256))
307 if (fwrite (&SourceByte, 1, 1, OutputFile) != 1)
309 printf ("[*** iASL: Write error on output file ***]\n");
313 RActual = fread (&SourceByte, 1, 1, SourceFile);
317 "[*** iASL: Read error on source code temp file %s ***]",
318 Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Filename);
327 "\n[*** iASL: Long input line, an error occurred at column %u ***]",
334 fprintf (OutputFile, "\n");
341 * Less verbose version of the error message, enabled via the
342 * -vi switch. The format is compatible with MS Visual Studio.
344 fprintf (OutputFile, "%s", Enode->Filename);
346 if (Enode->LineNumber)
348 fprintf (OutputFile, "(%u) : ",
354 /* NULL message ID, just print the raw message */
356 if (Enode->MessageId == 0)
358 fprintf (OutputFile, "%s\n", Enode->Message);
362 /* Decode the message ID */
364 if (Gbl_VerboseErrors)
366 fprintf (OutputFile, "%s %4.4d -",
367 AslErrorLevel[Enode->Level],
368 Enode->MessageId + ((Enode->Level+1) * 1000));
372 fprintf (OutputFile, "%s %4.4d:",
373 AslErrorLevelIde[Enode->Level],
374 Enode->MessageId + ((Enode->Level+1) * 1000));
377 MainMessage = AslMessages[Enode->MessageId];
378 ExtraMessage = Enode->Message;
380 if (Enode->LineNumber)
382 /* Main message: try to use string from AslMessages first */
389 MsgLength = strlen (MainMessage);
392 /* Use the secondary/extra message as main message */
394 MainMessage = Enode->Message;
400 MsgLength = strlen (MainMessage);
404 if (Gbl_VerboseErrors && !PrematureEOF)
408 fprintf (OutputFile, " %s",
413 SourceColumn = Enode->Column + Enode->FilenameLength + 6 + 2;
414 ErrorColumn = ASL_ERROR_LEVEL_LENGTH + 5 + 2 + 1;
416 if ((MsgLength + ErrorColumn) < (SourceColumn - 1))
418 fprintf (OutputFile, "%*s%s",
419 (int) ((SourceColumn - 1) - ErrorColumn),
424 fprintf (OutputFile, "%*s %s",
425 (int) ((SourceColumn - ErrorColumn) + 1), "^",
432 fprintf (OutputFile, " %s", MainMessage);
435 /* Print the extra info message if present */
439 fprintf (OutputFile, " (%s)", ExtraMessage);
444 fprintf (OutputFile, " and premature End-Of-File");
447 fprintf (OutputFile, "\n");
448 if (Gbl_VerboseErrors)
450 fprintf (OutputFile, "\n");
455 fprintf (OutputFile, " %s %s\n\n", MainMessage, ExtraMessage);
461 /*******************************************************************************
463 * FUNCTION: AePrintErrorLog
465 * PARAMETERS: FileId - Where to output the error log
469 * DESCRIPTION: Print the entire contents of the error log
471 ******************************************************************************/
477 ASL_ERROR_MSG *Enode = Gbl_ErrorLog;
480 /* Walk the error node list */
484 AePrintException (FileId, Enode, NULL);
490 /*******************************************************************************
492 * FUNCTION: AslCommonError2
494 * PARAMETERS: Level - Seriousness (Warning/error, etc.)
495 * MessageId - Index into global message buffer
496 * LineNumber - Actual file line number
497 * Column - Column in current line
498 * SourceLine - Actual source code line
499 * Filename - source filename
500 * ExtraMessage - additional error message
504 * DESCRIPTION: Create a new error node and add it to the error log
506 ******************************************************************************/
518 char *MessageBuffer = NULL;
520 ASL_ERROR_MSG *Enode;
523 Enode = UtLocalCalloc (sizeof (ASL_ERROR_MSG));
527 /* Allocate a buffer for the message and a new error node */
529 MessageBuffer = UtLocalCalloc (strlen (ExtraMessage) + 1);
531 /* Keep a copy of the extra message */
533 ACPI_STRCPY (MessageBuffer, ExtraMessage);
536 LineBuffer = UtLocalCalloc (strlen (SourceLine) + 1);
537 ACPI_STRCPY (LineBuffer, SourceLine);
539 /* Initialize the error node */
543 Enode->Filename = Filename;
544 Enode->FilenameLength = strlen (Filename);
545 if (Enode->FilenameLength < 6)
547 Enode->FilenameLength = 6;
551 Enode->MessageId = MessageId;
552 Enode->Level = Level;
553 Enode->LineNumber = LineNumber;
554 Enode->LogicalLineNumber = LineNumber;
555 Enode->LogicalByteOffset = 0;
556 Enode->Column = Column;
557 Enode->Message = MessageBuffer;
558 Enode->SourceLine = LineBuffer;
560 /* Add the new node to the error node list */
562 AeAddToErrorLog (Enode);
566 /* stderr is a file, send error to it immediately */
568 AePrintException (ASL_FILE_STDERR, Enode, NULL);
571 Gbl_ExceptionCount[Level]++;
575 /*******************************************************************************
577 * FUNCTION: AslCommonError
579 * PARAMETERS: Level - Seriousness (Warning/error, etc.)
580 * MessageId - Index into global message buffer
581 * CurrentLineNumber - Actual file line number
582 * LogicalLineNumber - Cumulative line number
583 * LogicalByteOffset - Byte offset in source file
584 * Column - Column in current line
585 * Filename - source filename
586 * ExtraMessage - additional error message
590 * DESCRIPTION: Create a new error node and add it to the error log
592 ******************************************************************************/
598 UINT32 CurrentLineNumber,
599 UINT32 LogicalLineNumber,
600 UINT32 LogicalByteOffset,
606 char *MessageBuffer = NULL;
607 ASL_ERROR_MSG *Enode;
610 Enode = UtLocalCalloc (sizeof (ASL_ERROR_MSG));
614 /* Allocate a buffer for the message and a new error node */
616 MessageSize = strlen (ExtraMessage) + 1;
617 MessageBuffer = UtLocalCalloc (MessageSize);
619 /* Keep a copy of the extra message */
621 ACPI_STRCPY (MessageBuffer, ExtraMessage);
624 /* Initialize the error node */
628 Enode->Filename = Filename;
629 Enode->FilenameLength = strlen (Filename);
630 if (Enode->FilenameLength < 6)
632 Enode->FilenameLength = 6;
636 Enode->MessageId = MessageId;
637 Enode->Level = Level;
638 Enode->LineNumber = CurrentLineNumber;
639 Enode->LogicalLineNumber = LogicalLineNumber;
640 Enode->LogicalByteOffset = LogicalByteOffset;
641 Enode->Column = Column;
642 Enode->Message = MessageBuffer;
643 Enode->SourceLine = NULL;
645 /* Add the new node to the error node list */
647 AeAddToErrorLog (Enode);
651 /* stderr is a file, send error to it immediately */
653 AePrintException (ASL_FILE_STDERR, Enode, NULL);
656 Gbl_ExceptionCount[Level]++;
657 if (Gbl_ExceptionCount[ASL_ERROR] > ASL_MAX_ERROR_COUNT)
659 printf ("\nMaximum error count (%u) exceeded\n", ASL_MAX_ERROR_COUNT);
662 Gbl_NextError = Gbl_ErrorLog;
672 /*******************************************************************************
676 * PARAMETERS: Level - Seriousness (Warning/error, etc.)
677 * MessageId - Index into global message buffer
678 * Op - Parse node where error happened
679 * ExtraMessage - additional error message
683 * DESCRIPTION: Main error reporting routine for the ASL compiler (all code
684 * except the parser.)
686 ******************************************************************************/
692 ACPI_PARSE_OBJECT *Op,
700 if (Gbl_WarningLevel < Level)
712 AslCommonError (Level, MessageId, Op->Asl.LineNumber,
713 Op->Asl.LogicalLineNumber,
714 Op->Asl.LogicalByteOffset,
716 Op->Asl.Filename, ExtraMessage);
720 AslCommonError (Level, MessageId, 0,
721 0, 0, 0, NULL, ExtraMessage);
726 /*******************************************************************************
728 * FUNCTION: AslCoreSubsystemError
730 * PARAMETERS: Op - Parse node where error happened
731 * Status - The ACPI CA Exception
732 * ExtraMessage - additional error message
733 * Abort - TRUE -> Abort compilation
737 * DESCRIPTION: Error reporting routine for exceptions returned by the ACPI
740 ******************************************************************************/
743 AslCoreSubsystemError (
744 ACPI_PARSE_OBJECT *Op,
750 sprintf (MsgBuffer, "%s %s", AcpiFormatException (Status), ExtraMessage);
754 AslCommonError (ASL_ERROR, ASL_MSG_CORE_EXCEPTION, Op->Asl.LineNumber,
755 Op->Asl.LogicalLineNumber,
756 Op->Asl.LogicalByteOffset,
758 Op->Asl.Filename, MsgBuffer);
762 AslCommonError (ASL_ERROR, ASL_MSG_CORE_EXCEPTION, 0,
763 0, 0, 0, NULL, MsgBuffer);
773 /*******************************************************************************
775 * FUNCTION: AslCompilererror
777 * PARAMETERS: CompilerMessage - Error message from the parser
779 * RETURN: Status (0 for now)
781 * DESCRIPTION: Report an error situation discovered in a production
782 * NOTE: don't change the name of this function, it is called
783 * from the auto-generated parser.
785 ******************************************************************************/
789 const char *CompilerMessage)
792 AslCommonError (ASL_ERROR, ASL_MSG_SYNTAX, Gbl_CurrentLineNumber,
793 Gbl_LogicalLineNumber, Gbl_CurrentLineOffset,
794 Gbl_CurrentColumn, Gbl_Files[ASL_FILE_INPUT].Filename,
795 ACPI_CAST_PTR (char, CompilerMessage));