Home | History | Annotate | Download | only in VfrCompile
      1 /** @file
      2 
      3   VfrCompiler error handler.
      4 
      5 Copyright (c) 2004 - 2016, Intel Corporation. All rights reserved.<BR>
      6 This program and the accompanying materials
      7 are licensed and made available under the terms and conditions of the BSD License
      8 which accompanies this distribution.  The full text of the license may be found at
      9 http://opensource.org/licenses/bsd-license.php
     10 
     11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     13 
     14 **/
     15 
     16 #include "stdio.h"
     17 #include "string.h"
     18 #include "stdlib.h"
     19 #include "VfrError.h"
     20 #include "EfiUtilityMsgs.h"
     21 
     22 static SVFR_ERROR_HANDLE VFR_ERROR_HANDLE_TABLE [] = {
     23   { VFR_RETURN_SUCCESS, NULL },
     24   { VFR_RETURN_ERROR_SKIPED, NULL },
     25   { VFR_RETURN_FATAL_ERROR, ": fatal error!!" },
     26 
     27   { VFR_RETURN_MISMATCHED, ": unexpected token" },
     28   { VFR_RETURN_INVALID_PARAMETER, ": invalid parameter" },
     29   { VFR_RETURN_OUT_FOR_RESOURCES, ": system out of memory" },
     30   { VFR_RETURN_UNSUPPORTED, ": unsupported" },
     31   { VFR_RETURN_REDEFINED, ": already defined" },
     32   { VFR_RETURN_FORMID_REDEFINED, ": form id already defined" },
     33   { VFR_RETURN_QUESTIONID_REDEFINED, ": question id already defined" },
     34   { VFR_RETURN_VARSTOREID_REDEFINED, ": varstore id already defined" },
     35   { VFR_RETURN_UNDEFINED, ": undefined" },
     36   { VFR_RETURN_VAR_NOTDEFINED_BY_QUESTION, ": some variable has not defined by a question"},
     37   { VFR_RETURN_VARSTORE_DATATYPE_REDEFINED_ERROR, ": Data Structure is defined by more than one varstores, it can't be referred as varstore, only varstore name could be used."},
     38   { VFR_RETURN_GET_EFIVARSTORE_ERROR, ": get efi varstore error"},
     39   { VFR_RETURN_EFIVARSTORE_USE_ERROR, ": can not use the efi varstore like this" },
     40   { VFR_RETURN_EFIVARSTORE_SIZE_ERROR, ": unsupport efi varstore size should be <= 8 bytes" },
     41   { VFR_RETURN_GET_NVVARSTORE_ERROR, ": get name value varstore error" },
     42   { VFR_RETURN_QVAR_REUSE, ": variable reused by more than one question" },
     43   { VFR_RETURN_FLAGS_UNSUPPORTED, ": flags unsupported" },
     44   { VFR_RETURN_ERROR_ARRARY_NUM, ": array number error, the valid value is in (0 ~ MAX_INDEX-1) for UEFI vfr and in (1 ~ MAX_INDEX) for Framework Vfr" },
     45   { VFR_RETURN_DATA_STRING_ERROR, ": data field string error or not support"},
     46   { VFR_RETURN_DEFAULT_VALUE_REDEFINED, ": default value re-defined with different value"},
     47   { VFR_RETURN_CONSTANT_ONLY, ": only constant is allowed in the expression"},
     48   { VFR_RETURN_VARSTORE_NAME_REDEFINED_ERROR, ": Varstore name is defined by more than one varstores, it can't be referred as varstore, only varstore strucure name could be used."},
     49   { VFR_RETURN_CODEUNDEFINED, ": undefined Error Code" }
     50 };
     51 
     52 static SVFR_WARNING_HANDLE VFR_WARNING_HANDLE_TABLE [] = {
     53   { VFR_WARNING_DEFAULT_VALUE_REDEFINED, ": default value re-defined with different value"},
     54   { VFR_WARNING_STRING_TO_UINT_OVERFLOW, ": String to UINT* Overflow"},
     55   { VFR_WARNING_ACTION_WITH_TEXT_TWO, ": Action opcode should not have TextTwo part"},
     56   { VFR_WARNING_OBSOLETED_FRAMEWORK_OPCODE, ": Not recommend to use obsoleted framework opcode"},
     57   { VFR_WARNING_CODEUNDEFINED, ": undefined Warning Code" }
     58 };
     59 
     60 CVfrErrorHandle::CVfrErrorHandle (
     61   VOID
     62   )
     63 {
     64   mInputFileName         = NULL;
     65   mScopeRecordListHead   = NULL;
     66   mScopeRecordListTail   = NULL;
     67   mVfrErrorHandleTable   = VFR_ERROR_HANDLE_TABLE;
     68   mVfrWarningHandleTable = VFR_WARNING_HANDLE_TABLE;
     69 }
     70 
     71 CVfrErrorHandle::~CVfrErrorHandle (
     72   VOID
     73   )
     74 {
     75   SVfrFileScopeRecord *pNode = NULL;
     76 
     77   if (mInputFileName != NULL) {
     78     delete mInputFileName;
     79   }
     80 
     81   while (mScopeRecordListHead != NULL) {
     82     pNode = mScopeRecordListHead;
     83     mScopeRecordListHead = mScopeRecordListHead->mNext;
     84     delete pNode;
     85   }
     86 
     87   mScopeRecordListHead   = NULL;
     88   mScopeRecordListTail   = NULL;
     89   mVfrErrorHandleTable   = NULL;
     90   mVfrWarningHandleTable = NULL;
     91 }
     92 
     93 VOID
     94 CVfrErrorHandle::SetWarningAsError (
     95   IN BOOLEAN  WarningAsError
     96   )
     97 {
     98   mWarningAsError = WarningAsError;
     99 }
    100 
    101 VOID
    102 CVfrErrorHandle::SetInputFile (
    103   IN CHAR8    *InputFile
    104   )
    105 {
    106   if (InputFile != NULL) {
    107     mInputFileName = new CHAR8[strlen(InputFile) + 1];
    108     strcpy (mInputFileName, InputFile);
    109   }
    110 }
    111 
    112 SVfrFileScopeRecord::SVfrFileScopeRecord (
    113   IN CHAR8    *Record,
    114   IN UINT32   LineNum
    115   )
    116 {
    117   UINT32      Index;
    118   CHAR8       *FileName = NULL;
    119   CHAR8       *Str      = NULL;
    120 
    121   mWholeScopeLine      = LineNum;
    122   mNext                = NULL;
    123 
    124   Str = strchr (Record, ' ');
    125   mScopeLineStart = atoi (++Str);
    126 
    127   Str = strchr (Str, '\"');
    128   FileName = ++Str;
    129 
    130   while((Str = strstr (FileName, "\\\\")) != NULL) {
    131     FileName = Str + 2;
    132   }
    133   if ((mFileName = new CHAR8[strlen(FileName)]) != NULL) {
    134     for (Index = 0; FileName[Index] != '\"'; Index++) {
    135       mFileName[Index] = FileName[Index];
    136     }
    137     mFileName[Index] = '\0';
    138   }
    139 
    140   return;
    141 }
    142 
    143 SVfrFileScopeRecord::~SVfrFileScopeRecord (
    144   VOID
    145   )
    146 {
    147   if (mFileName != NULL) {
    148     delete[] mFileName;
    149   }
    150 }
    151 
    152 VOID
    153 CVfrErrorHandle::ParseFileScopeRecord (
    154   IN CHAR8     *Record,
    155   IN UINT32    WholeScopeLine
    156   )
    157 {
    158   SVfrFileScopeRecord *pNode        = NULL;
    159 
    160   if (Record == NULL) {
    161     return;
    162   }
    163 
    164   if ((pNode = new SVfrFileScopeRecord(Record, WholeScopeLine)) == NULL) {
    165     return;
    166   }
    167 
    168   if (mScopeRecordListHead == NULL) {
    169     mScopeRecordListTail = mScopeRecordListHead = pNode;
    170   } else {
    171     mScopeRecordListTail->mNext = pNode;
    172     mScopeRecordListTail        = pNode;
    173   }
    174 }
    175 
    176 VOID
    177 CVfrErrorHandle::GetFileNameLineNum (
    178   IN  UINT32 LineNum,
    179   OUT CHAR8  **FileName,
    180   OUT UINT32 *FileLine
    181   )
    182 {
    183   SVfrFileScopeRecord *pNode    = NULL;
    184 
    185   if ((FileName == NULL) || (FileLine == NULL)) {
    186     return;
    187   }
    188 
    189   *FileName = NULL;
    190   *FileLine = 0xFFFFFFFF;
    191 
    192   //
    193   // Some errors occur before scope record list been built.
    194   //
    195   if (mScopeRecordListHead == NULL) {
    196     *FileLine = LineNum;
    197     *FileName = mInputFileName;
    198     return ;
    199   }
    200 
    201   for (pNode = mScopeRecordListHead; pNode->mNext != NULL; pNode = pNode->mNext) {
    202     if ((LineNum > pNode->mWholeScopeLine) && (pNode->mNext->mWholeScopeLine > LineNum)) {
    203       *FileName = pNode->mFileName;
    204       *FileLine = LineNum - pNode->mWholeScopeLine + pNode->mScopeLineStart - 1;
    205       return ;
    206     }
    207   }
    208 
    209   *FileName = pNode->mFileName;
    210   *FileLine = LineNum - pNode->mWholeScopeLine + pNode->mScopeLineStart - 1;
    211 }
    212 
    213 VOID
    214 CVfrErrorHandle::PrintMsg (
    215   IN UINT32               LineNum,
    216   IN CHAR8                *TokName,
    217   IN CONST CHAR8          *MsgType,
    218   IN CONST CHAR8          *ErrorMsg
    219   )
    220 {
    221   CHAR8                  *FileName = NULL;
    222   UINT32                 FileLine;
    223 
    224   if (strncmp ("Warning", MsgType, strlen ("Warning")) == 0) {
    225     VerboseMsg ((CHAR8 *) ErrorMsg);
    226     return;
    227   }
    228   GetFileNameLineNum (LineNum, &FileName, &FileLine);
    229   Error (FileName, FileLine, 0x3000, TokName, (CHAR8 *) "\t%s\n", (CHAR8 *) ErrorMsg);
    230 }
    231 
    232 UINT8
    233 CVfrErrorHandle::HandleError (
    234   IN EFI_VFR_RETURN_CODE  ErrorCode,
    235   IN UINT32               LineNum,
    236   IN CHAR8                *TokName
    237   )
    238 {
    239   UINT32                 Index;
    240   CHAR8                  *FileName = NULL;
    241   UINT32                 FileLine;
    242   CONST CHAR8            *ErrorMsg = NULL;
    243 
    244   if (mVfrErrorHandleTable == NULL) {
    245     return 1;
    246   }
    247 
    248   for (Index = 0; mVfrErrorHandleTable[Index].mErrorCode != VFR_RETURN_CODEUNDEFINED; Index++) {
    249     if (ErrorCode == mVfrErrorHandleTable[Index].mErrorCode) {
    250       ErrorMsg = mVfrErrorHandleTable[Index].mErrorMsg;
    251       break;
    252     }
    253   }
    254 
    255   if (ErrorMsg != NULL) {
    256     GetFileNameLineNum (LineNum, &FileName, &FileLine);
    257     Error (FileName, FileLine, 0x3000, TokName, (CHAR8 *) "\t%s\n", (CHAR8 *) ErrorMsg);
    258     return 1;
    259   } else {
    260     return 0;
    261   }
    262 }
    263 
    264 UINT8
    265 CVfrErrorHandle::HandleWarning (
    266   IN EFI_VFR_WARNING_CODE WarningCode,
    267   IN UINT32               LineNum,
    268   IN CHAR8                *TokName
    269   )
    270 {
    271   UINT32                 Index;
    272   CHAR8                  *FileName = NULL;
    273   UINT32                 FileLine;
    274   CONST CHAR8            *WarningMsg = NULL;
    275 
    276   if (mVfrWarningHandleTable == NULL) {
    277     return 1;
    278   }
    279 
    280   GetFileNameLineNum (LineNum, &FileName, &FileLine);
    281 
    282   if (mWarningAsError) {
    283     Error (FileName, FileLine, 0x2220, (CHAR8 *) "warning treated as error", NULL);
    284   }
    285 
    286   for (Index = 0; mVfrWarningHandleTable[Index].mWarningCode != VFR_WARNING_CODEUNDEFINED; Index++) {
    287     if (WarningCode == mVfrWarningHandleTable[Index].mWarningCode) {
    288       WarningMsg = mVfrWarningHandleTable[Index].mWarningMsg;
    289       break;
    290     }
    291   }
    292 
    293   if (WarningMsg != NULL) {
    294     Warning (FileName, FileLine, 0, TokName, (CHAR8 *) "\t%s\n", (CHAR8 *) WarningMsg);
    295     return 1;
    296   } else {
    297     return 0;
    298   }
    299 }
    300 
    301 CVfrErrorHandle gCVfrErrorHandle;
    302