]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/C/VfrCompile/VfrCompiler.cpp
Sync BaseTool trunk (version r2640) into EDKII BaseTools.
[mirror_edk2.git] / BaseTools / Source / C / VfrCompile / VfrCompiler.cpp
CommitLineData
30fdf114
LG
1/** @file\r
2 \r
3 VfrCompiler main class and main function.\r
4\r
2bc3256c 5Copyright (c) 2004 - 2013, Intel Corporation. All rights reserved.<BR>\r
40d841f6 6This program and the accompanying materials \r
30fdf114
LG
7are licensed and made available under the terms and conditions of the BSD License \r
8which accompanies this distribution. The full text of the license may be found at \r
9http://opensource.org/licenses/bsd-license.php \r
10 \r
11THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
12WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
13\r
14**/\r
15\r
16#include "stdio.h"\r
17#include "stdlib.h"\r
18#include "string.h"\r
19#include "VfrCompiler.h"\r
20#include "CommonLib.h"\r
21#include "EfiUtilityMsgs.h"\r
22\r
23PACKAGE_DATA gCBuffer;\r
24PACKAGE_DATA gRBuffer;\r
4234283c 25CVfrStringDB gCVfrStringDB;\r
30fdf114
LG
26\r
27VOID \r
52302d4d
LG
28CVfrCompiler::DebugError (\r
29 IN CHAR8 *FileName,\r
30 IN UINT32 LineNumber,\r
31 IN UINT32 MessageCode,\r
32 IN CONST CHAR8 *Text,\r
33 IN CONST CHAR8 *MsgFmt,\r
34 ...\r
35 ) \r
36{\r
37 va_list List;\r
38 va_start (List, MsgFmt);\r
39 PrintMessage ((CHAR8 *) "ERROR", FileName, LineNumber, MessageCode, (CHAR8 *) Text, (CHAR8 *) MsgFmt, List);\r
40 va_end (List);\r
30fdf114
LG
41}\r
42\r
43VOID\r
44CVfrCompiler::SET_RUN_STATUS (\r
45 IN COMPILER_RUN_STATUS Status\r
46 )\r
47{\r
48 mRunStatus = Status;\r
49}\r
50\r
51BOOLEAN\r
52CVfrCompiler::IS_RUN_STATUS (\r
53 IN COMPILER_RUN_STATUS Status\r
54 )\r
55{\r
56 return mRunStatus == Status;\r
57}\r
58\r
59VOID\r
60CVfrCompiler::OptionInitialization (\r
61 IN INT32 Argc, \r
62 IN CHAR8 **Argv\r
63 )\r
64{\r
65 INT32 Index;\r
4234283c
LG
66 EFI_STATUS Status;\r
67\r
68 Status = EFI_SUCCESS;\r
52302d4d 69 SetUtilityName ((CHAR8*) PROGRAM_NAME);\r
30fdf114
LG
70\r
71 mOptions.VfrFileName[0] = '\0';\r
72 mOptions.RecordListFile[0] = '\0';\r
73 mOptions.CreateRecordListFile = FALSE;\r
74 mOptions.CreateIfrPkgFile = FALSE;\r
75 mOptions.PkgOutputFileName[0] = '\0';\r
76 mOptions.COutputFileName[0] = '\0';\r
77 mOptions.OutputDirectory[0] = '\0';\r
78 mOptions.PreprocessorOutputFileName[0] = '\0';\r
79 mOptions.VfrBaseFileName[0] = '\0';\r
80 mOptions.IncludePaths = NULL;\r
81 mOptions.SkipCPreprocessor = TRUE;\r
82 mOptions.CPreprocessorOptions = NULL;\r
83 mOptions.CompatibleMode = FALSE;\r
4234283c 84 mOptions.HasOverrideClassGuid = FALSE;\r
4afd3d04 85 mOptions.WarningAsError = FALSE;\r
4234283c 86 memset (&mOptions.OverrideClassGuid, 0, sizeof (EFI_GUID));\r
30fdf114
LG
87 \r
88 if (Argc == 1) {\r
89 Usage ();\r
90 SET_RUN_STATUS (STATUS_DEAD);\r
91 return;\r
92 }\r
93\r
94 for (Index = 1; (Index < Argc) && (Argv[Index][0] == '-'); Index++) {\r
95 if ((stricmp(Argv[Index], "-h") == 0) || (stricmp(Argv[Index], "--help") == 0)) {\r
96 Usage ();\r
97 SET_RUN_STATUS (STATUS_DEAD);\r
98 return;\r
99 } else if (stricmp(Argv[Index], "-l") == 0) {\r
100 mOptions.CreateRecordListFile = TRUE;\r
101 gCIfrRecordInfoDB.TurnOn ();\r
102 } else if (stricmp(Argv[Index], "-i") == 0) {\r
30fdf114
LG
103 Index++;\r
104 if ((Index >= Argc) || (Argv[Index][0] == '-')) {\r
52302d4d 105 DebugError (NULL, 0, 1001, "Missing option", "-i missing path argument"); \r
30fdf114
LG
106 goto Fail;\r
107 }\r
108\r
109 AppendIncludePath(Argv[Index]);\r
110 } else if (stricmp(Argv[Index], "-o") == 0 || stricmp(Argv[Index], "--output-directory") == 0 || stricmp(Argv[Index], "-od") == 0) {\r
111 Index++;\r
112 if ((Index >= Argc) || (Argv[Index][0] == '-')) {\r
52302d4d 113 DebugError (NULL, 0, 1001, "Missing option", "-o missing output directory name");\r
30fdf114
LG
114 goto Fail;\r
115 }\r
116 strcpy (mOptions.OutputDirectory, Argv[Index]);\r
117 \r
118 CHAR8 lastChar = mOptions.OutputDirectory[strlen(mOptions.OutputDirectory) - 1];\r
119 if ((lastChar != '/') && (lastChar != '\\')) {\r
120 if (strchr(mOptions.OutputDirectory, '/') != NULL) {\r
121 strcat (mOptions.OutputDirectory, "/");\r
122 } else {\r
123 strcat (mOptions.OutputDirectory, "\\");\r
124 }\r
125 }\r
52302d4d 126 DebugMsg (NULL, 0, 9, (CHAR8 *) "Output Directory", mOptions.OutputDirectory);\r
30fdf114
LG
127 } else if (stricmp(Argv[Index], "-b") == 0 || stricmp(Argv[Index], "--create-ifr-package") == 0 || stricmp(Argv[Index], "-ibin") == 0) {\r
128 mOptions.CreateIfrPkgFile = TRUE;\r
129 } else if (stricmp(Argv[Index], "-n") == 0 || stricmp(Argv[Index], "--no-pre-processing") == 0 || stricmp(Argv[Index], "-nopp") == 0) {\r
130 mOptions.SkipCPreprocessor = TRUE;\r
131 } else if (stricmp(Argv[Index], "-f") == 0 || stricmp(Argv[Index], "--pre-processing-flag") == 0 || stricmp(Argv[Index], "-ppflag") == 0) {\r
30fdf114
LG
132 Index++;\r
133 if ((Index >= Argc) || (Argv[Index][0] == '-')) {\r
52302d4d 134 DebugError (NULL, 0, 1001, "Missing option", "-od - missing C-preprocessor argument");\r
30fdf114
LG
135 goto Fail;\r
136 }\r
137\r
138 AppendCPreprocessorOptions (Argv[Index]);\r
139 } else if (stricmp(Argv[Index], "-c") == 0 || stricmp(Argv[Index], "--compatible-framework") == 0) {\r
140 mOptions.CompatibleMode = TRUE;\r
4234283c
LG
141 } else if (stricmp(Argv[Index], "-s") == 0|| stricmp(Argv[Index], "--string-db") == 0) {\r
142 Index++;\r
143 if ((Index >= Argc) || (Argv[Index][0] == '-')) {\r
144 DebugError (NULL, 0, 1001, "Missing option", "-s missing input string file name");\r
145 goto Fail;\r
146 }\r
147 gCVfrStringDB.SetStringFileName(Argv[Index]);\r
148 DebugMsg (NULL, 0, 9, (CHAR8 *) "Input string file path", Argv[Index]);\r
149 } else if ((stricmp (Argv[Index], "-g") == 0) || (stricmp (Argv[Index], "--guid") == 0)) {\r
150 Index++;\r
151 Status = StringToGuid (Argv[Index], &mOptions.OverrideClassGuid);\r
152 if (EFI_ERROR (Status)) {\r
153 DebugError (NULL, 0, 1000, "Invalid format:", "%s", Argv[Index]);\r
154 goto Fail;\r
155 }\r
156 mOptions.HasOverrideClassGuid = TRUE;\r
4afd3d04
LG
157 } else if (stricmp(Argv[Index], "-w") == 0 || stricmp(Argv[Index], "--warning-as-error") == 0) {\r
158 mOptions.WarningAsError = TRUE;\r
30fdf114 159 } else {\r
52302d4d 160 DebugError (NULL, 0, 1000, "Unknown option", "unrecognized option %s", Argv[Index]);\r
30fdf114
LG
161 goto Fail;\r
162 }\r
163 }\r
164\r
165 if (Index != Argc - 1) {\r
52302d4d 166 DebugError (NULL, 0, 1001, "Missing option", "VFR file name is not specified.");\r
30fdf114
LG
167 goto Fail;\r
168 } else {\r
169 strcpy (mOptions.VfrFileName, Argv[Index]);\r
170 }\r
171\r
172 if (SetBaseFileName() != 0) {\r
173 goto Fail;\r
174 }\r
175 if (SetPkgOutputFileName () != 0) {\r
176 goto Fail;\r
177 }\r
178 if (SetCOutputFileName() != 0) {\r
179 goto Fail;\r
180 }\r
181 if (SetPreprocessorOutputFileName () != 0) {\r
182 goto Fail;\r
183 }\r
184 if (SetRecordListFileName () != 0) {\r
185 goto Fail;\r
186 }\r
187 return;\r
188\r
189Fail:\r
190 SET_RUN_STATUS (STATUS_DEAD);\r
191\r
192 mOptions.VfrFileName[0] = '\0';\r
193 mOptions.RecordListFile[0] = '\0';\r
194 mOptions.CreateRecordListFile = FALSE;\r
195 mOptions.CreateIfrPkgFile = FALSE;\r
196 mOptions.PkgOutputFileName[0] = '\0';\r
197 mOptions.COutputFileName[0] = '\0';\r
198 mOptions.OutputDirectory[0] = '\0';\r
199 mOptions.PreprocessorOutputFileName[0] = '\0';\r
200 mOptions.VfrBaseFileName[0] = '\0';\r
201 if (mOptions.IncludePaths != NULL) {\r
202 delete mOptions.IncludePaths;\r
203 mOptions.IncludePaths = NULL;\r
204 } \r
205 if (mOptions.CPreprocessorOptions != NULL) {\r
206 delete mOptions.CPreprocessorOptions;\r
207 mOptions.CPreprocessorOptions = NULL;\r
208 }\r
209}\r
210\r
211VOID\r
212CVfrCompiler::AppendIncludePath (\r
213 IN CHAR8 *PathStr\r
214 )\r
215{\r
216 UINT32 Len = 0;\r
217 CHAR8 *IncludePaths = NULL;\r
218\r
219 Len = strlen (" -I ") + strlen (PathStr) + 1;\r
220 if (mOptions.IncludePaths != NULL) {\r
221 Len += strlen (mOptions.IncludePaths);\r
222 }\r
223 IncludePaths = new CHAR8[Len];\r
224 if (IncludePaths == NULL) {\r
52302d4d 225 DebugError (NULL, 0, 4001, "Resource: memory can't be allocated", NULL);\r
30fdf114
LG
226 return;\r
227 }\r
228 IncludePaths[0] = '\0';\r
229 if (mOptions.IncludePaths != NULL) {\r
230 strcat (IncludePaths, mOptions.IncludePaths);\r
231 }\r
232 strcat (IncludePaths, " -I ");\r
233 strcat (IncludePaths, PathStr);\r
234 if (mOptions.IncludePaths != NULL) {\r
235 delete mOptions.IncludePaths;\r
236 }\r
237 mOptions.IncludePaths = IncludePaths;\r
238}\r
239\r
240VOID\r
241CVfrCompiler::AppendCPreprocessorOptions (\r
242 IN CHAR8 *Options\r
243 )\r
244{\r
245 UINT32 Len = 0;\r
246 CHAR8 *Opt = NULL;\r
247\r
248 Len = strlen (Options) + strlen (" ") + 1;\r
249 if (mOptions.CPreprocessorOptions != NULL) {\r
250 Len += strlen (mOptions.CPreprocessorOptions);\r
251 }\r
252 Opt = new CHAR8[Len];\r
253 if (Opt == NULL) {\r
52302d4d 254 DebugError (NULL, 0, 4001, "Resource: memory can't be allocated", NULL);\r
30fdf114
LG
255 return;\r
256 }\r
257 Opt[0] = 0;\r
258 if (mOptions.CPreprocessorOptions != NULL) {\r
259 strcat (Opt, mOptions.CPreprocessorOptions);\r
260 }\r
261 strcat (Opt, " ");\r
262 strcat (Opt, Options);\r
263 if (mOptions.CPreprocessorOptions != NULL) {\r
264 delete mOptions.CPreprocessorOptions;\r
265 }\r
266 mOptions.CPreprocessorOptions = Opt;\r
267}\r
268\r
269INT8\r
270CVfrCompiler::SetBaseFileName (\r
271 VOID\r
272 )\r
273{\r
274 CHAR8 *pFileName, *pPath, *pExt;\r
275\r
276 if (mOptions.VfrFileName[0] == '\0') {\r
277 return -1;\r
278 }\r
279\r
280 pFileName = mOptions.VfrFileName;\r
281 while (\r
282 ((pPath = strchr (pFileName, '\\')) != NULL) ||\r
283 ((pPath = strchr (pFileName, '/')) != NULL)\r
284 )\r
285 {\r
286 pFileName = pPath + 1;\r
287 }\r
288\r
289 if (pFileName == NULL) {\r
290 return -1;\r
291 }\r
292\r
293 if ((pExt = strchr (pFileName, '.')) == NULL) {\r
294 return -1;\r
295 }\r
296\r
297 strncpy (mOptions.VfrBaseFileName, pFileName, pExt - pFileName);\r
298 mOptions.VfrBaseFileName[pExt - pFileName] = '\0';\r
299\r
300 return 0;\r
301}\r
302\r
303INT8\r
304CVfrCompiler::SetPkgOutputFileName (\r
305 VOID\r
306 )\r
307{\r
308 if (mOptions.VfrBaseFileName[0] == '\0') {\r
309 return -1;\r
310 }\r
311\r
312 strcpy (mOptions.PkgOutputFileName, mOptions.OutputDirectory);\r
313 strcat (mOptions.PkgOutputFileName, mOptions.VfrBaseFileName);\r
314 strcat (mOptions.PkgOutputFileName, VFR_PACKAGE_FILENAME_EXTENSION);\r
315\r
316 return 0;\r
317}\r
318\r
319INT8\r
320CVfrCompiler::SetCOutputFileName (\r
321 VOID\r
322 )\r
323{\r
324 if (mOptions.VfrBaseFileName[0] == '\0') {\r
325 return -1;\r
326 }\r
327\r
328 strcpy (mOptions.COutputFileName, mOptions.OutputDirectory);\r
329 strcat (mOptions.COutputFileName, mOptions.VfrBaseFileName);\r
330 strcat (mOptions.COutputFileName, ".c");\r
331\r
332 return 0;\r
333}\r
334\r
335INT8\r
336CVfrCompiler::SetPreprocessorOutputFileName (\r
337 VOID\r
338 )\r
339{\r
340 if (mOptions.VfrBaseFileName[0] == '\0') {\r
341 return -1;\r
342 }\r
343\r
344 strcpy (mOptions.PreprocessorOutputFileName, mOptions.OutputDirectory);\r
345 strcat (mOptions.PreprocessorOutputFileName, mOptions.VfrBaseFileName);\r
346 strcat (mOptions.PreprocessorOutputFileName, VFR_PREPROCESS_FILENAME_EXTENSION);\r
347\r
348 return 0;\r
349}\r
350\r
351INT8\r
352CVfrCompiler::SetRecordListFileName (\r
353 VOID\r
354 )\r
355{\r
356 if (mOptions.VfrBaseFileName[0] == '\0') {\r
357 return -1;\r
358 }\r
359\r
360 strcpy (mOptions.RecordListFile, mOptions.OutputDirectory);\r
361 strcat (mOptions.RecordListFile, mOptions.VfrBaseFileName);\r
362 strcat (mOptions.RecordListFile, VFR_RECORDLIST_FILENAME_EXTENSION);\r
363\r
364 return 0;\r
365}\r
366\r
367CVfrCompiler::CVfrCompiler (\r
368 IN INT32 Argc, \r
369 IN CHAR8 **Argv\r
370 )\r
371{\r
52302d4d
LG
372 mPreProcessCmd = (CHAR8 *) PREPROCESSOR_COMMAND;\r
373 mPreProcessOpt = (CHAR8 *) PREPROCESSOR_OPTIONS;\r
30fdf114
LG
374\r
375 OptionInitialization(Argc, Argv);\r
376\r
377 if ((IS_RUN_STATUS(STATUS_FAILED)) || (IS_RUN_STATUS(STATUS_DEAD))) {\r
378 return;\r
379 }\r
380\r
381 SET_RUN_STATUS(STATUS_INITIALIZED);\r
382}\r
383\r
384CVfrCompiler::~CVfrCompiler (\r
385 VOID\r
386 )\r
387{\r
388 if (mOptions.IncludePaths != NULL) {\r
389 delete mOptions.IncludePaths;\r
390 mOptions.IncludePaths = NULL;\r
391 }\r
392\r
393 if (mOptions.CPreprocessorOptions != NULL) {\r
394 delete mOptions.CPreprocessorOptions;\r
395 mOptions.CPreprocessorOptions = NULL;\r
396 }\r
397\r
398 SET_RUN_STATUS(STATUS_DEAD);\r
399}\r
400\r
401VOID \r
402CVfrCompiler::Usage (\r
403 VOID\r
404 )\r
405{\r
406 UINT32 Index;\r
407 CONST CHAR8 *Help[] = {\r
408 " ", \r
2bc3256c
LG
409 "VfrCompile version " VFR_COMPILER_VERSION __BUILD_VERSION,\r
410 "Copyright (c) 2004-2013 Intel Corporation. All rights reserved.",\r
30fdf114
LG
411 " ",\r
412 "Usage: VfrCompile [options] VfrFile",\r
413 " ",\r
414 "Options:",\r
415 " -h, --help prints this help",\r
416 " -l create an output IFR listing file",\r
417 " -o DIR, --output-directory DIR",\r
418 " deposit all output files to directory OutputDir",\r
419 " default is current directory",\r
420 " -b, --create-ifr-package",\r
421 " create an IFR HII pack file",\r
422 " -n, --no-pre-processing",\r
423 " do not preprocessing input file",\r
424 " -c, --compatible-framework",\r
425 " compatible framework vfr file",\r
4234283c
LG
426 " -s, --string-db",\r
427 " input uni string package file",\r
428 " -g, --guid",\r
429 " override class guid input",\r
430 " format is xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",\r
4afd3d04
LG
431 " -w --warning-as-error",\r
432 " treat warning as an error",\r
30fdf114
LG
433 NULL\r
434 };\r
435 for (Index = 0; Help[Index] != NULL; Index++) {\r
436 fprintf (stdout, "%s\n", Help[Index]);\r
437 }\r
438}\r
439\r
440VOID\r
441CVfrCompiler::PreProcess (\r
442 VOID\r
443 )\r
444{\r
445 FILE *pVfrFile = NULL;\r
446 UINT32 CmdLen = 0;\r
447 CHAR8 *PreProcessCmd = NULL;\r
448\r
449 if (!IS_RUN_STATUS(STATUS_INITIALIZED)) {\r
450 goto Fail;\r
451 }\r
452\r
453 if (mOptions.SkipCPreprocessor == TRUE) {\r
454 goto Out;\r
455 }\r
456\r
457 if ((pVfrFile = fopen (mOptions.VfrFileName, "r")) == NULL) {\r
52302d4d 458 DebugError (NULL, 0, 0001, "Error opening the input VFR file", mOptions.VfrFileName);\r
30fdf114
LG
459 goto Fail;\r
460 }\r
461 fclose (pVfrFile);\r
462\r
463 CmdLen = strlen (mPreProcessCmd) + strlen (mPreProcessOpt) + \r
464 strlen (mOptions.VfrFileName) + strlen (mOptions.PreprocessorOutputFileName);\r
465 if (mOptions.CPreprocessorOptions != NULL) {\r
466 CmdLen += strlen (mOptions.CPreprocessorOptions);\r
467 }\r
468 if (mOptions.IncludePaths != NULL) {\r
469 CmdLen += strlen (mOptions.IncludePaths);\r
470 }\r
471\r
472 PreProcessCmd = new CHAR8[CmdLen + 10];\r
473 if (PreProcessCmd == NULL) {\r
52302d4d 474 DebugError (NULL, 0, 4001, "Resource: memory can't be allocated", NULL);\r
30fdf114
LG
475 goto Fail;\r
476 }\r
477 strcpy (PreProcessCmd, mPreProcessCmd), strcat (PreProcessCmd, " ");\r
478 strcat (PreProcessCmd, mPreProcessOpt), strcat (PreProcessCmd, " ");\r
479 if (mOptions.IncludePaths != NULL) {\r
480 strcat (PreProcessCmd, mOptions.IncludePaths), strcat (PreProcessCmd, " ");\r
481 }\r
482 if (mOptions.CPreprocessorOptions != NULL) {\r
483 strcat (PreProcessCmd, mOptions.CPreprocessorOptions), strcat (PreProcessCmd, " ");\r
484 }\r
485 strcat (PreProcessCmd, mOptions.VfrFileName), strcat (PreProcessCmd, " > ");\r
486 strcat (PreProcessCmd, mOptions.PreprocessorOutputFileName);\r
487\r
488 if (system (PreProcessCmd) != 0) {\r
52302d4d 489 DebugError (NULL, 0, 0003, "Error parsing file", "failed to spawn C preprocessor on VFR file %s\n", PreProcessCmd);\r
30fdf114
LG
490 goto Fail;\r
491 }\r
492\r
493 delete PreProcessCmd;\r
494\r
495Out:\r
496 SET_RUN_STATUS (STATUS_PREPROCESSED);\r
497 return;\r
498\r
499Fail:\r
500 if (!IS_RUN_STATUS(STATUS_DEAD)) {\r
501 SET_RUN_STATUS (STATUS_FAILED);\r
502 }\r
503 delete PreProcessCmd;\r
504}\r
505\r
4234283c 506extern UINT8 VfrParserStart (IN FILE *, IN INPUT_INFO_TO_SYNTAX *);\r
30fdf114
LG
507\r
508VOID\r
509CVfrCompiler::Compile (\r
510 VOID\r
511 )\r
512{\r
513 FILE *pInFile = NULL;\r
514 CHAR8 *InFileName = NULL;\r
4234283c 515 INPUT_INFO_TO_SYNTAX InputInfo;\r
30fdf114
LG
516\r
517 if (!IS_RUN_STATUS(STATUS_PREPROCESSED)) {\r
518 goto Fail;\r
519 }\r
520\r
521 InFileName = (mOptions.SkipCPreprocessor == TRUE) ? mOptions.VfrFileName : mOptions.PreprocessorOutputFileName;\r
522\r
523 gCVfrErrorHandle.SetInputFile (InFileName);\r
4afd3d04 524 gCVfrErrorHandle.SetWarningAsError(mOptions.WarningAsError);\r
30fdf114
LG
525\r
526 if ((pInFile = fopen (InFileName, "r")) == NULL) {\r
52302d4d 527 DebugError (NULL, 0, 0001, "Error opening the input file", InFileName);\r
30fdf114
LG
528 goto Fail;\r
529 }\r
530\r
4234283c
LG
531 InputInfo.CompatibleMode = mOptions.CompatibleMode;\r
532 if (mOptions.HasOverrideClassGuid) {\r
533 InputInfo.OverrideClassGuid = &mOptions.OverrideClassGuid;\r
534 } else {\r
535 InputInfo.OverrideClassGuid = NULL;\r
536 }\r
537\r
538 if (VfrParserStart (pInFile, &InputInfo) != 0) {\r
30fdf114
LG
539 goto Fail;\r
540 }\r
541\r
542 fclose (pInFile);\r
543\r
544 if (gCFormPkg.HavePendingUnassigned () == TRUE) {\r
545 gCFormPkg.PendingAssignPrintAll ();\r
546 goto Fail;\r
547 }\r
548\r
549 SET_RUN_STATUS (STATUS_COMPILEED);\r
550 return;\r
551\r
552Fail:\r
553 if (!IS_RUN_STATUS(STATUS_DEAD)) {\r
52302d4d 554 DebugError (NULL, 0, 0003, "Error parsing", "compile error in file %s", InFileName);\r
30fdf114
LG
555 SET_RUN_STATUS (STATUS_FAILED);\r
556 }\r
557 if (pInFile != NULL) {\r
558 fclose (pInFile);\r
559 }\r
560}\r
561\r
4afd3d04
LG
562VOID\r
563CVfrCompiler::UpdateInfoForDynamicOpcode (\r
564 VOID\r
565 )\r
566{\r
567 SIfrRecord *pRecord;\r
568\r
569 if (!gNeedAdjustOpcode) {\r
570 return;\r
571 }\r
572 \r
573 //\r
574 // Base on the original offset info to update the record list.\r
575 //\r
576 if (!gCIfrRecordInfoDB.IfrAdjustDynamicOpcodeInRecords()) {\r
577 DebugError (NULL, 0, 1001, "Error parsing vfr file", "Can find the offset in the record.");\r
578 }\r
579\r
580 //\r
581 // Base on the opcode binary length to recalculate the offset for each opcode.\r
582 //\r
583 gCIfrRecordInfoDB.IfrAdjustOffsetForRecord();\r
584\r
585 //\r
586 // Base on the offset to find the binary address.\r
587 //\r
588 pRecord = gCIfrRecordInfoDB.GetRecordInfoFromOffset(gAdjustOpcodeOffset);\r
589 while (pRecord != NULL) {\r
590 pRecord->mIfrBinBuf = gCFormPkg.GetBufAddrBaseOnOffset(pRecord->mOffset);\r
591 if (pRecord->mIfrBinBuf == NULL) {\r
592 DebugError (NULL, 0, 0001, "Error parsing vfr file", " 0x%X. offset not allocated.", pRecord->mOffset);\r
593 }\r
594 pRecord = pRecord->mNext;\r
595 }\r
596}\r
597\r
30fdf114
LG
598VOID\r
599CVfrCompiler::AdjustBin (\r
600 VOID\r
601 )\r
602{\r
603 EFI_VFR_RETURN_CODE Status;\r
4afd3d04
LG
604\r
605 if (!IS_RUN_STATUS(STATUS_COMPILEED)) {\r
606 return;\r
607 }\r
608\r
609 UpdateInfoForDynamicOpcode ();\r
610\r
30fdf114
LG
611 //\r
612 // Check Binary Code consistent between Form and IfrRecord\r
613 //\r
614\r
615 //\r
616 // Get Package Data and IfrRecord Data\r
617 //\r
618 gCFormPkg.BuildPkg (gCBuffer);\r
619 gCIfrRecordInfoDB.IfrRecordOutput (gRBuffer); \r
620\r
621 //\r
622 // Compare Form and Record data\r
623 //\r
624 if (gCBuffer.Buffer != NULL && gRBuffer.Buffer != NULL) {\r
625 UINT32 Index;\r
626 if (gCBuffer.Size != gRBuffer.Size) {\r
52302d4d 627 DebugError (NULL, 0, 0001, "Error parsing vfr file", " %s. FormBinary Size 0x%X is not same to RecordBuffer Size 0x%X", mOptions.VfrFileName, gCBuffer.Size, gRBuffer.Size);\r
30fdf114
LG
628 }\r
629 for (Index = 0; Index < gCBuffer.Size; Index ++) {\r
630 if (gCBuffer.Buffer[Index] != gRBuffer.Buffer[Index]) {\r
631 break;\r
632 }\r
633 }\r
634 if (Index != gCBuffer.Size) {\r
52302d4d 635 DebugError (NULL, 0, 0001, "Error parsing vfr file", " %s. the 0x%X byte is different between Form and Record", mOptions.VfrFileName, Index);\r
30fdf114 636 }\r
52302d4d 637 DebugMsg (NULL, 0, 9, (CHAR8 *) "IFR Buffer", (CHAR8 *) "Form Buffer same to Record Buffer and Size is 0x%X", Index);\r
30fdf114
LG
638 } else if (gCBuffer.Buffer == NULL && gRBuffer.Buffer == NULL) {\r
639 //ok\r
640 } else {\r
52302d4d 641 DebugError (NULL, 0, 0001, "Error parsing vfr file", " %s.Buffer not allocated.", mOptions.VfrFileName);\r
30fdf114
LG
642 }\r
643\r
644 //\r
645 // For UEFI mode, not do OpCode Adjust\r
646 //\r
647 if (mOptions.CompatibleMode) {\r
648 //\r
649 // Adjust Opcode to be compatible with framework vfr\r
650 //\r
651 Status = gCIfrRecordInfoDB.IfrRecordAdjust ();\r
652 if (Status != VFR_RETURN_SUCCESS) {\r
653 //\r
654 // Record List Adjust Failed\r
655 //\r
656 SET_RUN_STATUS (STATUS_FAILED);\r
657 return;\r
658 }\r
659 //\r
660 // Re get the IfrRecord Buffer.\r
661 //\r
662 gCIfrRecordInfoDB.IfrRecordOutput (gRBuffer); \r
663 }\r
664\r
665 return;\r
666}\r
667\r
668VOID\r
669CVfrCompiler::GenBinary (\r
670 VOID\r
671 )\r
672{\r
673 FILE *pFile = NULL;\r
674\r
675 if (!IS_RUN_STATUS(STATUS_COMPILEED)) {\r
676 goto Fail;\r
677 }\r
678\r
679 if (mOptions.CreateIfrPkgFile == TRUE) {\r
680 if ((pFile = fopen (mOptions.PkgOutputFileName, "wb")) == NULL) {\r
52302d4d 681 DebugError (NULL, 0, 0001, "Error opening file", mOptions.PkgOutputFileName);\r
30fdf114
LG
682 goto Fail;\r
683 }\r
684 if (gCFormPkg.BuildPkg (pFile, &gRBuffer) != VFR_RETURN_SUCCESS) {\r
685 fclose (pFile);\r
686 goto Fail;\r
687 }\r
688 fclose (pFile);\r
689 }\r
690\r
691 SET_RUN_STATUS (STATUS_GENBINARY);\r
692\r
693 return;\r
694\r
695Fail:\r
696 if (!IS_RUN_STATUS(STATUS_DEAD)) {\r
697 SET_RUN_STATUS (STATUS_FAILED);\r
698 }\r
699}\r
700\r
701static const char *gSourceFileHeader[] = {\r
702 "//",\r
703 "// DO NOT EDIT -- auto-generated file",\r
704 "//",\r
705 "// This file is generated by the vfrcompiler utility",\r
706 "//",\r
707 NULL\r
708};\r
709\r
710VOID\r
711CVfrCompiler::GenCFile (\r
712 VOID\r
713 )\r
714{\r
715 FILE *pFile;\r
716 UINT32 Index;\r
717\r
718 if (!IS_RUN_STATUS(STATUS_GENBINARY)) {\r
719 goto Fail;\r
720 }\r
b303ea72
LG
721 \r
722 if (!mOptions.CreateIfrPkgFile || mOptions.CompatibleMode) {\r
723 if ((pFile = fopen (mOptions.COutputFileName, "w")) == NULL) {\r
52302d4d 724 DebugError (NULL, 0, 0001, "Error opening output C file", mOptions.COutputFileName);\r
b303ea72
LG
725 goto Fail;\r
726 }\r
30fdf114 727\r
b303ea72
LG
728 for (Index = 0; gSourceFileHeader[Index] != NULL; Index++) {\r
729 fprintf (pFile, "%s\n", gSourceFileHeader[Index]);\r
730 }\r
30fdf114 731\r
b303ea72
LG
732 if (mOptions.CompatibleMode) { \r
733 gCVfrBufferConfig.OutputCFile (pFile, mOptions.VfrBaseFileName);\r
734 }\r
30fdf114 735\r
b303ea72
LG
736 if (gCFormPkg.GenCFile (mOptions.VfrBaseFileName, pFile, &gRBuffer) != VFR_RETURN_SUCCESS) {\r
737 fclose (pFile);\r
738 goto Fail;\r
739 }\r
30fdf114 740 fclose (pFile);\r
30fdf114 741 }\r
30fdf114
LG
742\r
743 SET_RUN_STATUS (STATUS_FINISHED);\r
744 return;\r
745\r
746Fail:\r
747 if (!IS_RUN_STATUS(STATUS_DEAD)) {\r
748 SET_RUN_STATUS (STATUS_FAILED);\r
749 }\r
750}\r
751\r
752VOID\r
753CVfrCompiler::GenRecordListFile (\r
754 VOID\r
755 )\r
756{\r
757 CHAR8 *InFileName = NULL;\r
758 FILE *pInFile = NULL;\r
759 FILE *pOutFile = NULL;\r
760 CHAR8 LineBuf[MAX_VFR_LINE_LEN];\r
761 UINT32 LineNo;\r
762\r
763 InFileName = (mOptions.SkipCPreprocessor == TRUE) ? mOptions.VfrFileName : mOptions.PreprocessorOutputFileName;\r
764\r
765 if (mOptions.CreateRecordListFile == TRUE) {\r
766 if ((InFileName[0] == '\0') || (mOptions.RecordListFile[0] == '\0')) {\r
767 return;\r
768 }\r
769\r
770 if ((pInFile = fopen (InFileName, "r")) == NULL) {\r
52302d4d 771 DebugError (NULL, 0, 0001, "Error opening the input VFR preprocessor output file", InFileName);\r
30fdf114
LG
772 return;\r
773 }\r
774\r
775 if ((pOutFile = fopen (mOptions.RecordListFile, "w")) == NULL) {\r
52302d4d 776 DebugError (NULL, 0, 0001, "Error opening the record list file", mOptions.RecordListFile);\r
30fdf114
LG
777 goto Err1;\r
778 }\r
779\r
b36d134f 780 fprintf (pOutFile, "//\n// VFR compiler version " VFR_COMPILER_VERSION __BUILD_VERSION "\n//\n");\r
30fdf114
LG
781 LineNo = 0;\r
782 while (!feof (pInFile)) {\r
783 if (fgets (LineBuf, MAX_VFR_LINE_LEN, pInFile) != NULL) {\r
784 fprintf (pOutFile, "%s", LineBuf);\r
785 LineNo++;\r
786 gCIfrRecordInfoDB.IfrRecordOutput (pOutFile, LineNo);\r
787 }\r
788 }\r
789 \r
790 fprintf (pOutFile, "\n//\n// All Opcode Record List \n//\n");\r
791 gCIfrRecordInfoDB.IfrRecordOutput (pOutFile, 0);\r
792 gCVfrVarDataTypeDB.Dump(pOutFile);\r
793\r
794 fclose (pOutFile);\r
795 fclose (pInFile);\r
796 }\r
797\r
798 return;\r
799\r
800Err1:\r
801 fclose (pInFile);\r
802}\r
803\r
804int\r
805main (\r
52302d4d
LG
806 IN int Argc, \r
807 IN char **Argv\r
30fdf114
LG
808 )\r
809{\r
810 COMPILER_RUN_STATUS Status;\r
4afd3d04
LG
811\r
812 SetPrintLevel(WARNING_LOG_LEVEL);\r
30fdf114
LG
813 CVfrCompiler Compiler(Argc, Argv);\r
814 \r
815 Compiler.PreProcess();\r
816 Compiler.Compile();\r
817 Compiler.AdjustBin();\r
818 Compiler.GenBinary();\r
819 Compiler.GenCFile();\r
820 Compiler.GenRecordListFile ();\r
821\r
822 Status = Compiler.RunStatus ();\r
823 if ((Status == STATUS_DEAD) || (Status == STATUS_FAILED)) {\r
824 return 2;\r
825 }\r
826\r
827 if (gCBuffer.Buffer != NULL) {\r
828 delete gCBuffer.Buffer;\r
829 }\r
830 \r
831 if (gRBuffer.Buffer != NULL) {\r
832 delete gRBuffer.Buffer;\r
833 }\r
834\r
835 return GetUtilityStatus ();\r
836}\r
837\r
52302d4d 838\r