963bd2da42698659559d1920352cc4cd402eb39e
[efi/edk2/.git] / edk2 / BaseTools / Source / C / VfrCompile / VfrError.cpp
1 /** @file\r
2   \r
3   VfrCompiler error handler.\r
4 \r
5 Copyright (c) 2004 - 2008, Intel Corporation                                                         \r
6 All rights reserved. This program and the accompanying materials                          \r
7 are licensed and made available under the terms and conditions of the BSD License         \r
8 which accompanies this distribution.  The full text of the license may be found at        \r
9 http://opensource.org/licenses/bsd-license.php                                            \r
10                                                                                           \r
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
13 \r
14 **/\r
15 \r
16 #include "stdio.h"\r
17 #include "string.h"\r
18 #include "stdlib.h"\r
19 #include "VfrError.h"\r
20 #include "EfiUtilityMsgs.h"\r
21 \r
22 static SVFR_ERROR_HANDLE VFR_ERROR_HANDLE_TABLE [] = {\r
23   { VFR_RETURN_SUCCESS, NULL },\r
24   { VFR_RETURN_ERROR_SKIPED, NULL },\r
25   { VFR_RETURN_FATAL_ERROR, ": fatal error!!" },\r
26 \r
27   { VFR_RETURN_MISMATCHED, ": unexpected token" },\r
28   { VFR_RETURN_INVALID_PARAMETER, ": invalid parameter" },\r
29   { VFR_RETURN_OUT_FOR_RESOURCES, ": system out of memory" },\r
30   { VFR_RETURN_UNSUPPORTED, ": unsupported" },\r
31   { VFR_RETURN_REDEFINED, ": already defined" },\r
32   { VFR_RETURN_FORMID_REDEFINED, ": form id already defined" },\r
33   { VFR_RETURN_QUESTIONID_REDEFINED, ": question id already defined" },\r
34   { VFR_RETURN_VARSTOREID_REDEFINED, ": varstore id already defined" },\r
35   { VFR_RETURN_UNDEFINED, ": undefined" },\r
36   { VFR_RETURN_VAR_NOTDEFINED_BY_QUESTION, ": some variable has not defined by a question"},\r
37   { VFR_RETURN_GET_EFIVARSTORE_ERROR, ": get efi varstore error"},\r
38   { VFR_RETURN_EFIVARSTORE_USE_ERROR, ": can not use the efi varstore like this" },\r
39   { VFR_RETURN_EFIVARSTORE_SIZE_ERROR, ": unsupport efi varstore size should be <= 8 bytes" },\r
40   { VFR_RETURN_GET_NVVARSTORE_ERROR, ": get name value varstore error" },\r
41   { VFR_RETURN_QVAR_REUSE, ": variable reused by more than one question" },\r
42   { VFR_RETURN_FLAGS_UNSUPPORTED, ": flags unsupported" },\r
43   { 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" },\r
44   { VFR_RETURN_DATA_STRING_ERROR, ": data field string error or not support"},\r
45   { VFR_RETURN_DEFAULT_VALUE_REDEFINED, ": default value re-defined with different value"},\r
46   { VFR_RETURN_CONSTANT_ONLY, ": only constant is allowed in the expression"},\r
47   { VFR_RETURN_CODEUNDEFINED, ": undefined Error Code" }\r
48 };\r
49 \r
50 CVfrErrorHandle::CVfrErrorHandle (\r
51   VOID\r
52   )\r
53 {\r
54   mInputFileName       = NULL;\r
55   mScopeRecordListHead = NULL;\r
56   mScopeRecordListTail = NULL;\r
57   mVfrErrorHandleTable = VFR_ERROR_HANDLE_TABLE;\r
58 }\r
59 \r
60 CVfrErrorHandle::~CVfrErrorHandle (\r
61   VOID\r
62   )\r
63 {\r
64   SVfrFileScopeRecord *pNode = NULL;\r
65 \r
66   if (mInputFileName != NULL) {\r
67     delete mInputFileName;\r
68   }\r
69 \r
70   while (mScopeRecordListHead != NULL) {\r
71     pNode = mScopeRecordListHead;\r
72     mScopeRecordListHead = mScopeRecordListHead->mNext;\r
73     delete pNode;\r
74   }\r
75 \r
76   mScopeRecordListHead = NULL;\r
77   mScopeRecordListTail = NULL;\r
78   mVfrErrorHandleTable = NULL;\r
79 }\r
80 \r
81 VOID\r
82 CVfrErrorHandle::SetInputFile (\r
83   IN CHAR8    *InputFile\r
84   )\r
85 {\r
86   if (InputFile != NULL) {\r
87     mInputFileName = new CHAR8[strlen(InputFile) + 1];\r
88     strcpy (mInputFileName, InputFile);\r
89   }\r
90 }\r
91 \r
92 SVfrFileScopeRecord::SVfrFileScopeRecord (\r
93   IN CHAR8    *Record, \r
94   IN UINT32   LineNum\r
95   )\r
96 {\r
97   UINT32      Index;\r
98   CHAR8       *FileName = NULL;\r
99   CHAR8       *Str      = NULL;\r
100 \r
101   mWholeScopeLine      = LineNum;\r
102   mNext                = NULL;\r
103 \r
104   Str = strchr (Record, ' ');\r
105   mScopeLineStart = atoi (++Str);\r
106 \r
107   Str = strchr (Str, '\"');\r
108   FileName = ++Str;\r
109 \r
110   while((Str = strstr (FileName, "\\\\")) != NULL) {\r
111     FileName = Str + 2;\r
112   }\r
113   if ((mFileName = new CHAR8[strlen(FileName)]) != NULL) {\r
114     for (Index = 0; FileName[Index] != '\"'; Index++) {\r
115       mFileName[Index] = FileName[Index];\r
116     }\r
117     mFileName[Index] = '\0';\r
118   }\r
119 \r
120   return;\r
121 }\r
122 \r
123 SVfrFileScopeRecord::~SVfrFileScopeRecord (\r
124   VOID\r
125   )\r
126 {\r
127   if (mFileName != NULL) {\r
128     delete mFileName;\r
129   }\r
130 }\r
131 \r
132 VOID\r
133 CVfrErrorHandle::ParseFileScopeRecord (\r
134   IN CHAR8     *Record, \r
135   IN UINT32    WholeScopeLine\r
136   )\r
137 {\r
138   CHAR8               *FullPathName = NULL;\r
139   SVfrFileScopeRecord *pNode        = NULL;\r
140 \r
141   if (Record == NULL) {\r
142     return;\r
143   }\r
144 \r
145   if ((pNode = new SVfrFileScopeRecord(Record, WholeScopeLine)) == NULL) {\r
146     return;\r
147   }\r
148 \r
149   if (mScopeRecordListHead == NULL) {\r
150     mScopeRecordListTail = mScopeRecordListHead = pNode;\r
151   } else {\r
152     mScopeRecordListTail->mNext = pNode;\r
153     mScopeRecordListTail        = pNode;\r
154   }\r
155 }\r
156 \r
157 VOID\r
158 CVfrErrorHandle::GetFileNameLineNum (\r
159   IN  UINT32 LineNum,\r
160   OUT CHAR8  **FileName,\r
161   OUT UINT32 *FileLine\r
162   )\r
163 {\r
164   SVfrFileScopeRecord *pNode    = NULL;\r
165 \r
166   if ((FileName == NULL) || (FileLine == NULL)) {\r
167     return;\r
168   }\r
169 \r
170   *FileName = NULL;\r
171   *FileLine = 0xFFFFFFFF;\r
172 \r
173   //\r
174   // Some errors occur before scope record list been built.\r
175   //\r
176   if (mScopeRecordListHead == NULL) {\r
177     *FileLine = LineNum;\r
178     *FileName = mInputFileName;\r
179     return ;\r
180   }\r
181 \r
182   for (pNode = mScopeRecordListHead; pNode->mNext != NULL; pNode = pNode->mNext) {\r
183     if ((LineNum > pNode->mWholeScopeLine) && (pNode->mNext->mWholeScopeLine > LineNum)) {\r
184       *FileName = pNode->mFileName;\r
185       *FileLine = LineNum - pNode->mWholeScopeLine + pNode->mScopeLineStart - 1;\r
186       return ;\r
187     }\r
188   }\r
189 \r
190   *FileName = pNode->mFileName;\r
191   *FileLine = LineNum - pNode->mWholeScopeLine + pNode->mScopeLineStart - 1;\r
192 }\r
193 \r
194 VOID\r
195 CVfrErrorHandle::PrintMsg (\r
196   IN UINT32               LineNum,\r
197   IN CHAR8                *TokName,\r
198   IN CHAR8                *MsgType,\r
199   IN CHAR8                *ErrorMsg\r
200   )\r
201 {\r
202   CHAR8                  *FileName = NULL;\r
203   UINT32                 FileLine;\r
204   \r
205   if (strncmp ("Warning", MsgType, strlen ("Warning")) == 0) {\r
206     VerboseMsg (ErrorMsg);\r
207     return;\r
208   }\r
209   GetFileNameLineNum (LineNum, &FileName, &FileLine);\r
210   Error (FileName, FileLine, 0x3000, TokName, "\t%s\n", ErrorMsg);\r
211 }\r
212 \r
213 UINT8\r
214 CVfrErrorHandle::HandleError (\r
215   IN EFI_VFR_RETURN_CODE  ErrorCode,\r
216   IN UINT32               LineNum,\r
217   IN CHAR8                *TokName\r
218   )\r
219 {\r
220   UINT32                 Index;\r
221   CHAR8                  *FileName = NULL;\r
222   UINT32                 FileLine;\r
223   CHAR8                  *ErrorMsg = NULL;\r
224 \r
225   if (mVfrErrorHandleTable == NULL) {\r
226     return 1;\r
227   }\r
228 \r
229   for (Index = 0; mVfrErrorHandleTable[Index].mErrorCode != VFR_RETURN_CODEUNDEFINED; Index++) {\r
230     if (ErrorCode == mVfrErrorHandleTable[Index].mErrorCode) {\r
231       ErrorMsg = mVfrErrorHandleTable[Index].mErrorMsg;\r
232       break;\r
233     }\r
234   }\r
235 \r
236   if (ErrorMsg != NULL) {\r
237     GetFileNameLineNum (LineNum, &FileName, &FileLine);\r
238     Error (FileName, FileLine, 0x3000, TokName, "\t%s\n", ErrorMsg);\r
239     return 1;\r
240   } else {\r
241     return 0;\r
242   }\r
243 }\r
244 \r
245 CVfrErrorHandle gCVfrErrorHandle;\r