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