Home | History | Annotate | Line # | Download | only in compiler
aslerror.c revision 1.8
      1 /******************************************************************************
      2  *
      3  * Module Name: aslerror - Error handling and statistics
      4  *
      5  *****************************************************************************/
      6 
      7 /*
      8  * Copyright (C) 2000 - 2017, Intel Corp.
      9  * All rights reserved.
     10  *
     11  * Redistribution and use in source and binary forms, with or without
     12  * modification, are permitted provided that the following conditions
     13  * are met:
     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.
     25  *
     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.
     29  *
     30  * NO WARRANTY
     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.
     42  */
     43 
     44 #include "aslcompiler.h"
     45 
     46 #define _COMPONENT          ACPI_COMPILER
     47         ACPI_MODULE_NAME    ("aslerror")
     48 
     49 /* Local prototypes */
     50 
     51 static void
     52 AeAddToErrorLog (
     53     ASL_ERROR_MSG           *Enode);
     54 
     55 static BOOLEAN
     56 AslIsExceptionExpected (
     57     UINT8                   Level,
     58     UINT16                  MessageId);
     59 
     60 static BOOLEAN
     61 AslIsExceptionDisabled (
     62     UINT8                   Level,
     63     UINT16                  MessageId);
     64 
     65 
     66 /*******************************************************************************
     67  *
     68  * FUNCTION:    AslAbort
     69  *
     70  * PARAMETERS:  None
     71  *
     72  * RETURN:      None
     73  *
     74  * DESCRIPTION: Dump the error log and abort the compiler. Used for serious
     75  *              I/O errors.
     76  *
     77  ******************************************************************************/
     78 
     79 void
     80 AslAbort (
     81     void)
     82 {
     83 
     84     AePrintErrorLog (ASL_FILE_STDERR);
     85     if (Gbl_DebugFlag)
     86     {
     87         /* Print error summary to stdout also */
     88 
     89         AePrintErrorLog (ASL_FILE_STDOUT);
     90     }
     91 
     92     exit (1);
     93 }
     94 
     95 
     96 /*******************************************************************************
     97  *
     98  * FUNCTION:    AeClearErrorLog
     99  *
    100  * PARAMETERS:  None
    101  *
    102  * RETURN:      None
    103  *
    104  * DESCRIPTION: Empty the error list
    105  *
    106  ******************************************************************************/
    107 
    108 void
    109 AeClearErrorLog (
    110     void)
    111 {
    112     ASL_ERROR_MSG           *Enode = Gbl_ErrorLog;
    113     ASL_ERROR_MSG           *Next;
    114 
    115     /* Walk the error node list */
    116 
    117     while (Enode)
    118     {
    119         Next = Enode->Next;
    120         ACPI_FREE (Enode);
    121         Enode = Next;
    122     }
    123 
    124     Gbl_ErrorLog = NULL;
    125 }
    126 
    127 
    128 /*******************************************************************************
    129  *
    130  * FUNCTION:    AeAddToErrorLog
    131  *
    132  * PARAMETERS:  Enode       - An error node to add to the log
    133  *
    134  * RETURN:      None
    135  *
    136  * DESCRIPTION: Add a new error node to the error log. The error log is
    137  *              ordered by the "logical" line number (cumulative line number
    138  *              including all include files.)
    139  *
    140  ******************************************************************************/
    141 
    142 static void
    143 AeAddToErrorLog (
    144     ASL_ERROR_MSG           *Enode)
    145 {
    146     ASL_ERROR_MSG           *Next;
    147     ASL_ERROR_MSG           *Prev;
    148 
    149 
    150     /* If Gbl_ErrorLog is null, this is the first error node */
    151 
    152     if (!Gbl_ErrorLog)
    153     {
    154         Gbl_ErrorLog = Enode;
    155         return;
    156     }
    157 
    158     /*
    159      * Walk error list until we find a line number greater than ours.
    160      * List is sorted according to line number.
    161      */
    162     Prev = NULL;
    163     Next = Gbl_ErrorLog;
    164 
    165     while ((Next) &&
    166            (Next->LogicalLineNumber <= Enode->LogicalLineNumber))
    167     {
    168         Prev = Next;
    169         Next = Next->Next;
    170     }
    171 
    172     /* Found our place in the list */
    173 
    174     Enode->Next = Next;
    175 
    176     if (Prev)
    177     {
    178         Prev->Next = Enode;
    179     }
    180     else
    181     {
    182         Gbl_ErrorLog = Enode;
    183     }
    184 }
    185 
    186 
    187 /*******************************************************************************
    188  *
    189  * FUNCTION:    AePrintException
    190  *
    191  * PARAMETERS:  FileId          - ID of output file
    192  *              Enode           - Error node to print
    193  *              Header          - Additional text before each message
    194  *
    195  * RETURN:      None
    196  *
    197  * DESCRIPTION: Print the contents of an error node.
    198  *
    199  * NOTE:        We don't use the FlxxxFile I/O functions here because on error
    200  *              they abort the compiler and call this function!  Since we
    201  *              are reporting errors here, we ignore most output errors and
    202  *              just try to get out as much as we can.
    203  *
    204  ******************************************************************************/
    205 
    206 void
    207 AePrintException (
    208     UINT32                  FileId,
    209     ASL_ERROR_MSG           *Enode,
    210     char                    *Header)
    211 {
    212     UINT8                   SourceByte;
    213     int                     Actual;
    214     size_t                  RActual;
    215     UINT32                  MsgLength;
    216     const char              *MainMessage;
    217     char                    *ExtraMessage;
    218     UINT32                  SourceColumn;
    219     UINT32                  ErrorColumn;
    220     FILE                    *OutputFile;
    221     FILE                    *SourceFile = NULL;
    222     long                    FileSize;
    223     BOOLEAN                 PrematureEOF = FALSE;
    224     UINT32                  Total = 0;
    225 
    226 
    227     if (Gbl_NoErrors)
    228     {
    229         return;
    230     }
    231 
    232     /*
    233      * Only listing files have a header, and remarks/optimizations
    234      * are always output
    235      */
    236     if (!Header)
    237     {
    238         /* Ignore remarks if requested */
    239 
    240         switch (Enode->Level)
    241         {
    242         case ASL_WARNING:
    243         case ASL_WARNING2:
    244         case ASL_WARNING3:
    245 
    246             if (!Gbl_DisplayWarnings)
    247             {
    248                 return;
    249             }
    250             break;
    251 
    252         case ASL_REMARK:
    253 
    254             if (!Gbl_DisplayRemarks)
    255             {
    256                 return;
    257             }
    258             break;
    259 
    260         case ASL_OPTIMIZATION:
    261 
    262             if (!Gbl_DisplayOptimizations)
    263             {
    264                 return;
    265             }
    266             break;
    267 
    268         default:
    269 
    270             break;
    271         }
    272     }
    273 
    274     /* Get the various required file handles */
    275 
    276     OutputFile = Gbl_Files[FileId].Handle;
    277 
    278     if (!Enode->SourceLine)
    279     {
    280         /*
    281          * Use the merged header/source file if present, otherwise
    282          * use input file
    283          */
    284         SourceFile = Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Handle;
    285         if (!SourceFile)
    286         {
    287             SourceFile = Gbl_Files[ASL_FILE_INPUT].Handle;
    288         }
    289 
    290         if (SourceFile)
    291         {
    292             /* Determine if the error occurred at source file EOF */
    293 
    294             fseek (SourceFile, 0, SEEK_END);
    295             FileSize = ftell (SourceFile);
    296 
    297             if ((long) Enode->LogicalByteOffset >= FileSize)
    298             {
    299                 PrematureEOF = TRUE;
    300             }
    301         }
    302     }
    303 
    304     if (Header)
    305     {
    306         fprintf (OutputFile, "%s", Header);
    307     }
    308 
    309     /* Print filename and line number if present and valid */
    310 
    311     if (Enode->Filename)
    312     {
    313         if (Gbl_VerboseErrors)
    314         {
    315             fprintf (OutputFile, "%-8s", Enode->Filename);
    316 
    317             if (Enode->LineNumber)
    318             {
    319                 if (Enode->SourceLine)
    320                 {
    321                     fprintf (OutputFile, " %6u: %s",
    322                         Enode->LineNumber, Enode->SourceLine);
    323                 }
    324                 else
    325                 {
    326                     fprintf (OutputFile, " %6u: ", Enode->LineNumber);
    327 
    328                     /*
    329                      * If not at EOF, get the corresponding source code line
    330                      * and display it. Don't attempt this if we have a
    331                      * premature EOF condition.
    332                      */
    333                     if (!PrematureEOF)
    334                     {
    335                         /*
    336                          * Seek to the offset in the combined source file,
    337                          * read the source line, and write it to the output.
    338                          */
    339                         Actual = fseek (SourceFile,
    340                             (long) Enode->LogicalByteOffset, (int) SEEK_SET);
    341                         if (Actual)
    342                         {
    343                             fprintf (OutputFile,
    344                                 "[*** iASL: Seek error on source code temp file %s ***]",
    345                                 Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Filename);
    346                         }
    347                         else
    348                         {
    349                             RActual = fread (&SourceByte, 1, 1, SourceFile);
    350                             if (RActual != 1)
    351                             {
    352                                 fprintf (OutputFile,
    353                                     "[*** iASL: Read error on source code temp file %s ***]",
    354                                     Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Filename);
    355                             }
    356                             else
    357                             {
    358                                 /* Read/write the source line, up to the maximum line length */
    359 
    360                                 while (RActual && SourceByte && (SourceByte != '\n'))
    361                                 {
    362                                     if (Total < 256)
    363                                     {
    364                                         /* After the max line length, we will just read the line, no write */
    365 
    366                                         if (fwrite (&SourceByte, 1, 1, OutputFile) != 1)
    367                                         {
    368                                             printf ("[*** iASL: Write error on output file ***]\n");
    369                                             return;
    370                                         }
    371                                     }
    372                                     else if (Total == 256)
    373                                     {
    374                                         fprintf (OutputFile,
    375                                             "\n[*** iASL: Very long input line, message below refers to column %u ***]",
    376                                             Enode->Column);
    377                                     }
    378 
    379                                     RActual = fread (&SourceByte, 1, 1, SourceFile);
    380                                     if (RActual != 1)
    381                                     {
    382                                         fprintf (OutputFile,
    383                                             "[*** iASL: Read error on source code temp file %s ***]",
    384                                             Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Filename);
    385                                         return;
    386                                     }
    387                                     Total++;
    388                                 }
    389                             }
    390                         }
    391                     }
    392 
    393                     fprintf (OutputFile, "\n");
    394                 }
    395             }
    396         }
    397         else
    398         {
    399             /*
    400              * Less verbose version of the error message, enabled via the
    401              * -vi switch. The format is compatible with MS Visual Studio.
    402              */
    403             fprintf (OutputFile, "%s", Enode->Filename);
    404 
    405             if (Enode->LineNumber)
    406             {
    407                 fprintf (OutputFile, "(%u) : ",
    408                     Enode->LineNumber);
    409             }
    410         }
    411     }
    412 
    413     /* If a NULL message ID, just print the raw message */
    414 
    415     if (Enode->MessageId == 0)
    416     {
    417         fprintf (OutputFile, "%s\n", Enode->Message);
    418         return;
    419     }
    420 
    421     /* Decode the message ID */
    422 
    423     fprintf (OutputFile, "%s %4.4d -",
    424         AeDecodeExceptionLevel (Enode->Level),
    425         AeBuildFullExceptionCode (Enode->Level, Enode->MessageId));
    426 
    427     MainMessage = AeDecodeMessageId (Enode->MessageId);
    428     ExtraMessage = Enode->Message;
    429 
    430     /* If a NULL line number, just print the decoded message */
    431 
    432     if (!Enode->LineNumber)
    433     {
    434         fprintf (OutputFile, " %s %s\n\n", MainMessage, ExtraMessage);
    435         return;
    436     }
    437 
    438     MsgLength = strlen (MainMessage);
    439     if (MsgLength == 0)
    440     {
    441         /* Use the secondary/extra message as main message */
    442 
    443         MainMessage = Enode->Message;
    444         if (!MainMessage)
    445         {
    446             MainMessage = "";
    447         }
    448 
    449         MsgLength = strlen (MainMessage);
    450         ExtraMessage = NULL;
    451     }
    452 
    453     if (Gbl_VerboseErrors && !PrematureEOF)
    454     {
    455         if (Total >= 256)
    456         {
    457             fprintf (OutputFile, "    %s",
    458                 MainMessage);
    459         }
    460         else
    461         {
    462             SourceColumn = Enode->Column + Enode->FilenameLength + 6 + 2;
    463             ErrorColumn = ASL_ERROR_LEVEL_LENGTH + 5 + 2 + 1;
    464 
    465             if ((MsgLength + ErrorColumn) < (SourceColumn - 1))
    466             {
    467                 fprintf (OutputFile, "%*s%s",
    468                     (int) ((SourceColumn - 1) - ErrorColumn),
    469                     MainMessage, " ^ ");
    470             }
    471             else
    472             {
    473                 fprintf (OutputFile, "%*s %s",
    474                     (int) ((SourceColumn - ErrorColumn) + 1), "^",
    475                     MainMessage);
    476             }
    477         }
    478     }
    479     else
    480     {
    481         fprintf (OutputFile, " %s", MainMessage);
    482     }
    483 
    484     /* Print the extra info message if present */
    485 
    486     if (ExtraMessage)
    487     {
    488         fprintf (OutputFile, " (%s)", ExtraMessage);
    489     }
    490 
    491     if (PrematureEOF)
    492     {
    493         fprintf (OutputFile, " and premature End-Of-File");
    494     }
    495 
    496     fprintf (OutputFile, "\n");
    497     if (Gbl_VerboseErrors)
    498     {
    499         fprintf (OutputFile, "\n");
    500     }
    501 }
    502 
    503 
    504 /*******************************************************************************
    505  *
    506  * FUNCTION:    AePrintErrorLog
    507  *
    508  * PARAMETERS:  FileId           - Where to output the error log
    509  *
    510  * RETURN:      None
    511  *
    512  * DESCRIPTION: Print the entire contents of the error log
    513  *
    514  ******************************************************************************/
    515 
    516 void
    517 AePrintErrorLog (
    518     UINT32                  FileId)
    519 {
    520     ASL_ERROR_MSG           *Enode = Gbl_ErrorLog;
    521 
    522 
    523     /* Walk the error node list */
    524 
    525     while (Enode)
    526     {
    527         AePrintException (FileId, Enode, NULL);
    528         Enode = Enode->Next;
    529     }
    530 }
    531 
    532 
    533 /*******************************************************************************
    534  *
    535  * FUNCTION:    AslCommonError2
    536  *
    537  * PARAMETERS:  Level               - Seriousness (Warning/error, etc.)
    538  *              MessageId           - Index into global message buffer
    539  *              LineNumber          - Actual file line number
    540  *              Column              - Column in current line
    541  *              SourceLine          - Actual source code line
    542  *              Filename            - source filename
    543  *              ExtraMessage        - additional error message
    544  *
    545  * RETURN:      None
    546  *
    547  * DESCRIPTION: Create a new error node and add it to the error log
    548  *
    549  ******************************************************************************/
    550 
    551 void
    552 AslCommonError2 (
    553     UINT8                   Level,
    554     UINT16                  MessageId,
    555     UINT32                  LineNumber,
    556     UINT32                  Column,
    557     char                    *SourceLine,
    558     char                    *Filename,
    559     char                    *ExtraMessage)
    560 {
    561     char                    *MessageBuffer = NULL;
    562     char                    *LineBuffer;
    563     ASL_ERROR_MSG           *Enode;
    564 
    565 
    566     Enode = UtLocalCalloc (sizeof (ASL_ERROR_MSG));
    567 
    568     if (ExtraMessage)
    569     {
    570         /* Allocate a buffer for the message and a new error node */
    571 
    572         MessageBuffer = UtStringCacheCalloc (strlen (ExtraMessage) + 1);
    573 
    574         /* Keep a copy of the extra message */
    575 
    576         strcpy (MessageBuffer, ExtraMessage);
    577     }
    578 
    579     LineBuffer = UtLocalCalloc (strlen (SourceLine) + 1);
    580     strcpy (LineBuffer, SourceLine);
    581 
    582     /* Initialize the error node */
    583 
    584     if (Filename)
    585     {
    586         Enode->Filename = Filename;
    587         Enode->FilenameLength = strlen (Filename);
    588         if (Enode->FilenameLength < 6)
    589         {
    590             Enode->FilenameLength = 6;
    591         }
    592     }
    593 
    594     Enode->MessageId            = MessageId;
    595     Enode->Level                = Level;
    596     Enode->LineNumber           = LineNumber;
    597     Enode->LogicalLineNumber    = LineNumber;
    598     Enode->LogicalByteOffset    = 0;
    599     Enode->Column               = Column;
    600     Enode->Message              = MessageBuffer;
    601     Enode->SourceLine           = LineBuffer;
    602 
    603     /* Add the new node to the error node list */
    604 
    605     AeAddToErrorLog (Enode);
    606 
    607     if (Gbl_DebugFlag)
    608     {
    609         /* stderr is a file, send error to it immediately */
    610 
    611         AePrintException (ASL_FILE_STDERR, Enode, NULL);
    612     }
    613 
    614     Gbl_ExceptionCount[Level]++;
    615 }
    616 
    617 
    618 /*******************************************************************************
    619  *
    620  * FUNCTION:    AslCommonError
    621  *
    622  * PARAMETERS:  Level               - Seriousness (Warning/error, etc.)
    623  *              MessageId           - Index into global message buffer
    624  *              CurrentLineNumber   - Actual file line number
    625  *              LogicalLineNumber   - Cumulative line number
    626  *              LogicalByteOffset   - Byte offset in source file
    627  *              Column              - Column in current line
    628  *              Filename            - source filename
    629  *              ExtraMessage        - additional error message
    630  *
    631  * RETURN:      None
    632  *
    633  * DESCRIPTION: Create a new error node and add it to the error log
    634  *
    635  ******************************************************************************/
    636 
    637 void
    638 AslCommonError (
    639     UINT8                   Level,
    640     UINT16                  MessageId,
    641     UINT32                  CurrentLineNumber,
    642     UINT32                  LogicalLineNumber,
    643     UINT32                  LogicalByteOffset,
    644     UINT32                  Column,
    645     char                    *Filename,
    646     char                    *ExtraMessage)
    647 {
    648     char                    *MessageBuffer = NULL;
    649     ASL_ERROR_MSG           *Enode;
    650 
    651 
    652     if (AslIsExceptionIgnored (Level, MessageId))
    653     {
    654         return;
    655     }
    656 
    657     Enode = UtLocalCalloc (sizeof (ASL_ERROR_MSG));
    658 
    659     if (ExtraMessage)
    660     {
    661         /* Allocate a buffer for the message and a new error node */
    662 
    663         MessageBuffer = UtStringCacheCalloc (strlen (ExtraMessage) + 1);
    664 
    665         /* Keep a copy of the extra message */
    666 
    667         strcpy (MessageBuffer, ExtraMessage);
    668     }
    669 
    670     /* Initialize the error node */
    671 
    672     if (Filename)
    673     {
    674         Enode->Filename = Filename;
    675         Enode->FilenameLength = strlen (Filename);
    676         if (Enode->FilenameLength < 6)
    677         {
    678             Enode->FilenameLength = 6;
    679         }
    680     }
    681 
    682     Enode->MessageId            = MessageId;
    683     Enode->Level                = Level;
    684     Enode->LineNumber           = CurrentLineNumber;
    685     Enode->LogicalLineNumber    = LogicalLineNumber;
    686     Enode->LogicalByteOffset    = LogicalByteOffset;
    687     Enode->Column               = Column;
    688     Enode->Message              = MessageBuffer;
    689     Enode->SourceLine           = NULL;
    690 
    691     /* Add the new node to the error node list */
    692 
    693     AeAddToErrorLog (Enode);
    694 
    695     if (Gbl_DebugFlag)
    696     {
    697         /* stderr is a file, send error to it immediately */
    698 
    699         AePrintException (ASL_FILE_STDERR, Enode, NULL);
    700     }
    701 
    702     Gbl_ExceptionCount[Level]++;
    703     if (Gbl_ExceptionCount[ASL_ERROR] > ASL_MAX_ERROR_COUNT)
    704     {
    705         printf ("\nMaximum error count (%u) exceeded\n", ASL_MAX_ERROR_COUNT);
    706 
    707         Gbl_SourceLine = 0;
    708         Gbl_NextError = Gbl_ErrorLog;
    709         CmCleanupAndExit ();
    710         exit(1);
    711     }
    712 
    713     return;
    714 }
    715 
    716 /*******************************************************************************
    717  *
    718  * FUNCTION:    AslIsExceptionIgnored
    719  *
    720  * PARAMETERS:  Level               - Seriousness (Warning/error, etc.)
    721  *              MessageId           - Index into global message buffer
    722  *
    723  * RETURN:      BOOLEAN
    724  *
    725  * DESCRIPTION: Check if a particular exception is ignored. In this case it
    726  *              means that the exception is (expected or disabled.
    727  *
    728  ******************************************************************************/
    729 
    730 BOOLEAN
    731 AslIsExceptionIgnored (
    732     UINT8                   Level,
    733     UINT16                  MessageId)
    734 {
    735     BOOLEAN ExceptionIgnored;
    736 
    737 
    738     /* Note: this allows exception to be disabled and expected */
    739 
    740     ExceptionIgnored = AslIsExceptionDisabled (Level, MessageId);
    741     ExceptionIgnored |= AslIsExceptionExpected (Level, MessageId);
    742 
    743     return (Gbl_AllExceptionsDisabled || ExceptionIgnored);
    744 }
    745 
    746 
    747 /*******************************************************************************
    748  *
    749  * FUNCTION:    AslCheckExpectException
    750  *
    751  * PARAMETERS:  none
    752  *
    753  * RETURN:      none
    754  *
    755  * DESCRIPTION: Check the global expected messages table and raise an error
    756  *              for each message that has not been received.
    757  *
    758  ******************************************************************************/
    759 
    760 void
    761 AslCheckExpectedExceptions (
    762     void)
    763 {
    764     UINT8 i;
    765 
    766     for (i = 0; i < Gbl_ExpectedMessagesIndex; ++i)
    767     {
    768         if (!Gbl_ExpectedMessages[i].MessageReceived)
    769         {
    770             AslError (ASL_ERROR, ASL_MSG_EXCEPTION_NOT_RECEIVED, NULL,
    771                 Gbl_ExpectedMessages[i].MessageIdStr);
    772         }
    773     }
    774 }
    775 
    776 
    777 /*******************************************************************************
    778  *
    779  * FUNCTION:    AslExpectException
    780  *
    781  * PARAMETERS:  MessageIdString     - ID of excepted exception during compile
    782  *
    783  * RETURN:      Status
    784  *
    785  * DESCRIPTION: Enter a message ID into the global expected messages table
    786  *              If these messages are not raised during the compilation, throw
    787  *              an error.
    788  *
    789  ******************************************************************************/
    790 
    791 ACPI_STATUS
    792 AslExpectException (
    793     char                    *MessageIdString)
    794 {
    795     UINT32                  MessageId;
    796 
    797 
    798     /* Convert argument to an integer and validate it */
    799 
    800     MessageId = (UINT32) strtoul (MessageIdString, NULL, 0);
    801 
    802     if (MessageId > 6999)
    803     {
    804         printf ("\"%s\" is not a valid warning/remark/erro ID\n",
    805             MessageIdString);
    806         return (AE_BAD_PARAMETER);
    807     }
    808 
    809     /* Insert value into the global expected message array */
    810 
    811     if (Gbl_ExpectedMessagesIndex >= ASL_MAX_EXPECTED_MESSAGES)
    812     {
    813         printf ("Too many messages have been registered as expected (max %u)\n",
    814             ASL_MAX_DISABLED_MESSAGES);
    815         return (AE_LIMIT);
    816     }
    817 
    818     Gbl_ExpectedMessages[Gbl_ExpectedMessagesIndex].MessageId = MessageId;
    819     Gbl_ExpectedMessages[Gbl_ExpectedMessagesIndex].MessageIdStr = MessageIdString;
    820     Gbl_ExpectedMessages[Gbl_ExpectedMessagesIndex].MessageReceived = FALSE;
    821     Gbl_ExpectedMessagesIndex++;
    822     return (AE_OK);
    823 }
    824 
    825 
    826 /*******************************************************************************
    827  *
    828  * FUNCTION:    AslDisableException
    829  *
    830  * PARAMETERS:  MessageIdString     - ID to be disabled
    831  *
    832  * RETURN:      Status
    833  *
    834  * DESCRIPTION: Enter a message ID into the global disabled messages table
    835  *
    836  ******************************************************************************/
    837 
    838 ACPI_STATUS
    839 AslDisableException (
    840     char                    *MessageIdString)
    841 {
    842     UINT32                  MessageId;
    843 
    844 
    845     /* Convert argument to an integer and validate it */
    846 
    847     MessageId = (UINT32) strtoul (MessageIdString, NULL, 0);
    848 
    849     if ((MessageId < 2000) || (MessageId > 6999))
    850     {
    851         printf ("\"%s\" is not a valid warning/remark/error ID\n",
    852             MessageIdString);
    853         return (AE_BAD_PARAMETER);
    854     }
    855 
    856     /* Insert value into the global disabled message array */
    857 
    858     if (Gbl_DisabledMessagesIndex >= ASL_MAX_DISABLED_MESSAGES)
    859     {
    860         printf ("Too many messages have been disabled (max %u)\n",
    861             ASL_MAX_DISABLED_MESSAGES);
    862         return (AE_LIMIT);
    863     }
    864 
    865     Gbl_DisabledMessages[Gbl_DisabledMessagesIndex] = MessageId;
    866     Gbl_DisabledMessagesIndex++;
    867     return (AE_OK);
    868 }
    869 
    870 
    871 /*******************************************************************************
    872  *
    873  * FUNCTION:    AslIsExceptionDisabled
    874  *
    875  * PARAMETERS:  Level               - Seriousness (Warning/error, etc.)
    876  *              MessageId           - Index into global message buffer
    877  *
    878  * RETURN:      TRUE if exception/message should be ignored
    879  *
    880  * DESCRIPTION: Check if the user has specified options such that this
    881  *              exception should be ignored
    882  *
    883  ******************************************************************************/
    884 
    885 static BOOLEAN
    886 AslIsExceptionExpected (
    887     UINT8                   Level,
    888     UINT16                  MessageId)
    889 {
    890     UINT32                  EncodedMessageId;
    891     UINT32                  i;
    892 
    893 
    894     /*
    895      * Mark this exception as received
    896      */
    897     EncodedMessageId = AeBuildFullExceptionCode (Level, MessageId);
    898     for (i = 0; i < Gbl_ExpectedMessagesIndex; i++)
    899     {
    900         /* Simple implementation via fixed array */
    901 
    902         if (EncodedMessageId == Gbl_ExpectedMessages[i].MessageId)
    903         {
    904             return (Gbl_ExpectedMessages[i].MessageReceived = TRUE);
    905         }
    906     }
    907 
    908     return (FALSE);
    909 }
    910 
    911 
    912 /*******************************************************************************
    913  *
    914  * FUNCTION:    AslIsExceptionDisabled
    915  *
    916  * PARAMETERS:  Level               - Seriousness (Warning/error, etc.)
    917  *              MessageId           - Index into global message buffer
    918  *
    919  * RETURN:      TRUE if exception/message should be ignored
    920  *
    921  * DESCRIPTION: Check if the user has specified options such that this
    922  *              exception should be ignored
    923  *
    924  ******************************************************************************/
    925 
    926 static BOOLEAN
    927 AslIsExceptionDisabled (
    928     UINT8                   Level,
    929     UINT16                  MessageId)
    930 {
    931     UINT32                  EncodedMessageId;
    932     UINT32                  i;
    933 
    934 
    935     switch (Level)
    936     {
    937     case ASL_WARNING2:
    938     case ASL_WARNING3:
    939 
    940         /* Check for global disable via -w1/-w2/-w3 options */
    941 
    942         if (Level > Gbl_WarningLevel)
    943         {
    944             return (TRUE);
    945         }
    946         /* Fall through */
    947 
    948     case ASL_WARNING:
    949     case ASL_REMARK:
    950     case ASL_ERROR:
    951         /*
    952          * Ignore this error/warning/remark if it has been disabled by
    953          * the user (-vw option)
    954          */
    955         EncodedMessageId = AeBuildFullExceptionCode (Level, MessageId);
    956         for (i = 0; i < Gbl_DisabledMessagesIndex; i++)
    957         {
    958             /* Simple implementation via fixed array */
    959 
    960             if (EncodedMessageId == Gbl_DisabledMessages[i])
    961             {
    962                 return (TRUE);
    963             }
    964         }
    965         break;
    966 
    967     default:
    968         break;
    969     }
    970 
    971     return (FALSE);
    972 }
    973 
    974 
    975 /*******************************************************************************
    976  *
    977  * FUNCTION:    AslError
    978  *
    979  * PARAMETERS:  Level               - Seriousness (Warning/error, etc.)
    980  *              MessageId           - Index into global message buffer
    981  *              Op                  - Parse node where error happened
    982  *              ExtraMessage        - additional error message
    983  *
    984  * RETURN:      None
    985  *
    986  * DESCRIPTION: Main error reporting routine for the ASL compiler (all code
    987  *              except the parser.)
    988  *
    989  ******************************************************************************/
    990 
    991 void
    992 AslError (
    993     UINT8                   Level,
    994     UINT16                  MessageId,
    995     ACPI_PARSE_OBJECT       *Op,
    996     char                    *ExtraMessage)
    997 {
    998     if (Op)
    999     {
   1000         AslCommonError (Level, MessageId, Op->Asl.LineNumber,
   1001             Op->Asl.LogicalLineNumber,
   1002             Op->Asl.LogicalByteOffset,
   1003             Op->Asl.Column,
   1004             Op->Asl.Filename, ExtraMessage);
   1005     }
   1006     else
   1007     {
   1008         AslCommonError (Level, MessageId, 0,
   1009             0, 0, 0, NULL, ExtraMessage);
   1010     }
   1011 }
   1012 
   1013 
   1014 /*******************************************************************************
   1015  *
   1016  * FUNCTION:    AslCoreSubsystemError
   1017  *
   1018  * PARAMETERS:  Op                  - Parse node where error happened
   1019  *              Status              - The ACPICA Exception
   1020  *              ExtraMessage        - additional error message
   1021  *              Abort               - TRUE -> Abort compilation
   1022  *
   1023  * RETURN:      None
   1024  *
   1025  * DESCRIPTION: Error reporting routine for exceptions returned by the ACPICA
   1026  *              core subsystem.
   1027  *
   1028  ******************************************************************************/
   1029 
   1030 void
   1031 AslCoreSubsystemError (
   1032     ACPI_PARSE_OBJECT       *Op,
   1033     ACPI_STATUS             Status,
   1034     char                    *ExtraMessage,
   1035     BOOLEAN                 Abort)
   1036 {
   1037 
   1038     snprintf (MsgBuffer, sizeof(MsgBuffer), "%s %s", AcpiFormatException (Status), ExtraMessage);
   1039 
   1040     if (Op)
   1041     {
   1042         AslCommonError (ASL_ERROR, ASL_MSG_CORE_EXCEPTION,
   1043             Op->Asl.LineNumber,
   1044             Op->Asl.LogicalLineNumber,
   1045             Op->Asl.LogicalByteOffset,
   1046             Op->Asl.Column,
   1047             Op->Asl.Filename, MsgBuffer);
   1048     }
   1049     else
   1050     {
   1051         AslCommonError (ASL_ERROR, ASL_MSG_CORE_EXCEPTION,
   1052             0, 0, 0, 0, NULL, MsgBuffer);
   1053     }
   1054 
   1055     if (Abort)
   1056     {
   1057         AslAbort ();
   1058     }
   1059 }
   1060 
   1061 
   1062 /*******************************************************************************
   1063  *
   1064  * FUNCTION:    AslCompilererror
   1065  *
   1066  * PARAMETERS:  CompilerMessage         - Error message from the parser
   1067  *
   1068  * RETURN:      Status (0 for now)
   1069  *
   1070  * DESCRIPTION: Report an error situation discovered in a production
   1071  *              NOTE: don't change the name of this function, it is called
   1072  *              from the auto-generated parser.
   1073  *
   1074  ******************************************************************************/
   1075 
   1076 int
   1077 AslCompilererror (
   1078     const char              *CompilerMessage)
   1079 {
   1080 
   1081     Gbl_SyntaxError++;
   1082 
   1083     AslCommonError (ASL_ERROR, ASL_MSG_SYNTAX, Gbl_CurrentLineNumber,
   1084         Gbl_LogicalLineNumber, Gbl_CurrentLineOffset,
   1085         Gbl_CurrentColumn, Gbl_Files[ASL_FILE_INPUT].Filename,
   1086         ACPI_CAST_PTR (char, CompilerMessage));
   1087 
   1088     return (0);
   1089 }
   1090