]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/C/VfrCompile/VfrCompiler.cpp
Sync BaseTool trunk (version r2670) 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 374\r
e4ac870f
LG
375 SET_RUN_STATUS (STATUS_STARTED);\r
376\r
30fdf114
LG
377 OptionInitialization(Argc, Argv);\r
378\r
379 if ((IS_RUN_STATUS(STATUS_FAILED)) || (IS_RUN_STATUS(STATUS_DEAD))) {\r
380 return;\r
381 }\r
382\r
383 SET_RUN_STATUS(STATUS_INITIALIZED);\r
384}\r
385\r
386CVfrCompiler::~CVfrCompiler (\r
387 VOID\r
388 )\r
389{\r
390 if (mOptions.IncludePaths != NULL) {\r
391 delete mOptions.IncludePaths;\r
392 mOptions.IncludePaths = NULL;\r
393 }\r
394\r
395 if (mOptions.CPreprocessorOptions != NULL) {\r
396 delete mOptions.CPreprocessorOptions;\r
397 mOptions.CPreprocessorOptions = NULL;\r
398 }\r
399\r
400 SET_RUN_STATUS(STATUS_DEAD);\r
401}\r
402\r
403VOID \r
404CVfrCompiler::Usage (\r
405 VOID\r
406 )\r
407{\r
408 UINT32 Index;\r
409 CONST CHAR8 *Help[] = {\r
410 " ", \r
2bc3256c
LG
411 "VfrCompile version " VFR_COMPILER_VERSION __BUILD_VERSION,\r
412 "Copyright (c) 2004-2013 Intel Corporation. All rights reserved.",\r
30fdf114
LG
413 " ",\r
414 "Usage: VfrCompile [options] VfrFile",\r
415 " ",\r
416 "Options:",\r
417 " -h, --help prints this help",\r
418 " -l create an output IFR listing file",\r
419 " -o DIR, --output-directory DIR",\r
420 " deposit all output files to directory OutputDir",\r
421 " default is current directory",\r
422 " -b, --create-ifr-package",\r
423 " create an IFR HII pack file",\r
424 " -n, --no-pre-processing",\r
425 " do not preprocessing input file",\r
426 " -c, --compatible-framework",\r
427 " compatible framework vfr file",\r
4234283c
LG
428 " -s, --string-db",\r
429 " input uni string package file",\r
430 " -g, --guid",\r
431 " override class guid input",\r
432 " format is xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",\r
4afd3d04
LG
433 " -w --warning-as-error",\r
434 " treat warning as an error",\r
30fdf114
LG
435 NULL\r
436 };\r
437 for (Index = 0; Help[Index] != NULL; Index++) {\r
438 fprintf (stdout, "%s\n", Help[Index]);\r
439 }\r
440}\r
441\r
442VOID\r
443CVfrCompiler::PreProcess (\r
444 VOID\r
445 )\r
446{\r
447 FILE *pVfrFile = NULL;\r
448 UINT32 CmdLen = 0;\r
449 CHAR8 *PreProcessCmd = NULL;\r
450\r
451 if (!IS_RUN_STATUS(STATUS_INITIALIZED)) {\r
452 goto Fail;\r
453 }\r
454\r
455 if (mOptions.SkipCPreprocessor == TRUE) {\r
456 goto Out;\r
457 }\r
458\r
459 if ((pVfrFile = fopen (mOptions.VfrFileName, "r")) == NULL) {\r
52302d4d 460 DebugError (NULL, 0, 0001, "Error opening the input VFR file", mOptions.VfrFileName);\r
30fdf114
LG
461 goto Fail;\r
462 }\r
463 fclose (pVfrFile);\r
464\r
465 CmdLen = strlen (mPreProcessCmd) + strlen (mPreProcessOpt) + \r
466 strlen (mOptions.VfrFileName) + strlen (mOptions.PreprocessorOutputFileName);\r
467 if (mOptions.CPreprocessorOptions != NULL) {\r
468 CmdLen += strlen (mOptions.CPreprocessorOptions);\r
469 }\r
470 if (mOptions.IncludePaths != NULL) {\r
471 CmdLen += strlen (mOptions.IncludePaths);\r
472 }\r
473\r
474 PreProcessCmd = new CHAR8[CmdLen + 10];\r
475 if (PreProcessCmd == NULL) {\r
52302d4d 476 DebugError (NULL, 0, 4001, "Resource: memory can't be allocated", NULL);\r
30fdf114
LG
477 goto Fail;\r
478 }\r
479 strcpy (PreProcessCmd, mPreProcessCmd), strcat (PreProcessCmd, " ");\r
480 strcat (PreProcessCmd, mPreProcessOpt), strcat (PreProcessCmd, " ");\r
481 if (mOptions.IncludePaths != NULL) {\r
482 strcat (PreProcessCmd, mOptions.IncludePaths), strcat (PreProcessCmd, " ");\r
483 }\r
484 if (mOptions.CPreprocessorOptions != NULL) {\r
485 strcat (PreProcessCmd, mOptions.CPreprocessorOptions), strcat (PreProcessCmd, " ");\r
486 }\r
487 strcat (PreProcessCmd, mOptions.VfrFileName), strcat (PreProcessCmd, " > ");\r
488 strcat (PreProcessCmd, mOptions.PreprocessorOutputFileName);\r
489\r
490 if (system (PreProcessCmd) != 0) {\r
52302d4d 491 DebugError (NULL, 0, 0003, "Error parsing file", "failed to spawn C preprocessor on VFR file %s\n", PreProcessCmd);\r
30fdf114
LG
492 goto Fail;\r
493 }\r
494\r
495 delete PreProcessCmd;\r
496\r
497Out:\r
498 SET_RUN_STATUS (STATUS_PREPROCESSED);\r
499 return;\r
500\r
501Fail:\r
502 if (!IS_RUN_STATUS(STATUS_DEAD)) {\r
503 SET_RUN_STATUS (STATUS_FAILED);\r
504 }\r
505 delete PreProcessCmd;\r
506}\r
507\r
4234283c 508extern UINT8 VfrParserStart (IN FILE *, IN INPUT_INFO_TO_SYNTAX *);\r
30fdf114
LG
509\r
510VOID\r
511CVfrCompiler::Compile (\r
512 VOID\r
513 )\r
514{\r
515 FILE *pInFile = NULL;\r
516 CHAR8 *InFileName = NULL;\r
4234283c 517 INPUT_INFO_TO_SYNTAX InputInfo;\r
30fdf114
LG
518\r
519 if (!IS_RUN_STATUS(STATUS_PREPROCESSED)) {\r
520 goto Fail;\r
521 }\r
522\r
523 InFileName = (mOptions.SkipCPreprocessor == TRUE) ? mOptions.VfrFileName : mOptions.PreprocessorOutputFileName;\r
524\r
525 gCVfrErrorHandle.SetInputFile (InFileName);\r
4afd3d04 526 gCVfrErrorHandle.SetWarningAsError(mOptions.WarningAsError);\r
30fdf114
LG
527\r
528 if ((pInFile = fopen (InFileName, "r")) == NULL) {\r
52302d4d 529 DebugError (NULL, 0, 0001, "Error opening the input file", InFileName);\r
30fdf114
LG
530 goto Fail;\r
531 }\r
532\r
4234283c
LG
533 InputInfo.CompatibleMode = mOptions.CompatibleMode;\r
534 if (mOptions.HasOverrideClassGuid) {\r
535 InputInfo.OverrideClassGuid = &mOptions.OverrideClassGuid;\r
536 } else {\r
537 InputInfo.OverrideClassGuid = NULL;\r
538 }\r
539\r
540 if (VfrParserStart (pInFile, &InputInfo) != 0) {\r
30fdf114
LG
541 goto Fail;\r
542 }\r
543\r
544 fclose (pInFile);\r
545\r
546 if (gCFormPkg.HavePendingUnassigned () == TRUE) {\r
547 gCFormPkg.PendingAssignPrintAll ();\r
548 goto Fail;\r
549 }\r
550\r
551 SET_RUN_STATUS (STATUS_COMPILEED);\r
552 return;\r
553\r
554Fail:\r
555 if (!IS_RUN_STATUS(STATUS_DEAD)) {\r
52302d4d 556 DebugError (NULL, 0, 0003, "Error parsing", "compile error in file %s", InFileName);\r
30fdf114
LG
557 SET_RUN_STATUS (STATUS_FAILED);\r
558 }\r
559 if (pInFile != NULL) {\r
560 fclose (pInFile);\r
561 }\r
562}\r
563\r
4afd3d04
LG
564VOID\r
565CVfrCompiler::UpdateInfoForDynamicOpcode (\r
566 VOID\r
567 )\r
568{\r
569 SIfrRecord *pRecord;\r
570\r
571 if (!gNeedAdjustOpcode) {\r
572 return;\r
573 }\r
574 \r
575 //\r
576 // Base on the original offset info to update the record list.\r
577 //\r
578 if (!gCIfrRecordInfoDB.IfrAdjustDynamicOpcodeInRecords()) {\r
579 DebugError (NULL, 0, 1001, "Error parsing vfr file", "Can find the offset in the record.");\r
580 }\r
581\r
582 //\r
583 // Base on the opcode binary length to recalculate the offset for each opcode.\r
584 //\r
585 gCIfrRecordInfoDB.IfrAdjustOffsetForRecord();\r
586\r
587 //\r
588 // Base on the offset to find the binary address.\r
589 //\r
590 pRecord = gCIfrRecordInfoDB.GetRecordInfoFromOffset(gAdjustOpcodeOffset);\r
591 while (pRecord != NULL) {\r
592 pRecord->mIfrBinBuf = gCFormPkg.GetBufAddrBaseOnOffset(pRecord->mOffset);\r
593 if (pRecord->mIfrBinBuf == NULL) {\r
594 DebugError (NULL, 0, 0001, "Error parsing vfr file", " 0x%X. offset not allocated.", pRecord->mOffset);\r
595 }\r
596 pRecord = pRecord->mNext;\r
597 }\r
598}\r
599\r
30fdf114
LG
600VOID\r
601CVfrCompiler::AdjustBin (\r
602 VOID\r
603 )\r
604{\r
605 EFI_VFR_RETURN_CODE Status;\r
4afd3d04
LG
606\r
607 if (!IS_RUN_STATUS(STATUS_COMPILEED)) {\r
608 return;\r
609 }\r
610\r
611 UpdateInfoForDynamicOpcode ();\r
612\r
30fdf114
LG
613 //\r
614 // Check Binary Code consistent between Form and IfrRecord\r
615 //\r
616\r
617 //\r
618 // Get Package Data and IfrRecord Data\r
619 //\r
620 gCFormPkg.BuildPkg (gCBuffer);\r
621 gCIfrRecordInfoDB.IfrRecordOutput (gRBuffer); \r
622\r
623 //\r
624 // Compare Form and Record data\r
625 //\r
626 if (gCBuffer.Buffer != NULL && gRBuffer.Buffer != NULL) {\r
627 UINT32 Index;\r
628 if (gCBuffer.Size != gRBuffer.Size) {\r
52302d4d 629 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
630 }\r
631 for (Index = 0; Index < gCBuffer.Size; Index ++) {\r
632 if (gCBuffer.Buffer[Index] != gRBuffer.Buffer[Index]) {\r
633 break;\r
634 }\r
635 }\r
636 if (Index != gCBuffer.Size) {\r
52302d4d 637 DebugError (NULL, 0, 0001, "Error parsing vfr file", " %s. the 0x%X byte is different between Form and Record", mOptions.VfrFileName, Index);\r
30fdf114 638 }\r
52302d4d 639 DebugMsg (NULL, 0, 9, (CHAR8 *) "IFR Buffer", (CHAR8 *) "Form Buffer same to Record Buffer and Size is 0x%X", Index);\r
30fdf114
LG
640 } else if (gCBuffer.Buffer == NULL && gRBuffer.Buffer == NULL) {\r
641 //ok\r
642 } else {\r
52302d4d 643 DebugError (NULL, 0, 0001, "Error parsing vfr file", " %s.Buffer not allocated.", mOptions.VfrFileName);\r
30fdf114
LG
644 }\r
645\r
646 //\r
647 // For UEFI mode, not do OpCode Adjust\r
648 //\r
649 if (mOptions.CompatibleMode) {\r
650 //\r
651 // Adjust Opcode to be compatible with framework vfr\r
652 //\r
653 Status = gCIfrRecordInfoDB.IfrRecordAdjust ();\r
654 if (Status != VFR_RETURN_SUCCESS) {\r
655 //\r
656 // Record List Adjust Failed\r
657 //\r
658 SET_RUN_STATUS (STATUS_FAILED);\r
659 return;\r
660 }\r
661 //\r
662 // Re get the IfrRecord Buffer.\r
663 //\r
664 gCIfrRecordInfoDB.IfrRecordOutput (gRBuffer); \r
665 }\r
666\r
667 return;\r
668}\r
669\r
670VOID\r
671CVfrCompiler::GenBinary (\r
672 VOID\r
673 )\r
674{\r
675 FILE *pFile = NULL;\r
676\r
677 if (!IS_RUN_STATUS(STATUS_COMPILEED)) {\r
678 goto Fail;\r
679 }\r
680\r
681 if (mOptions.CreateIfrPkgFile == TRUE) {\r
682 if ((pFile = fopen (mOptions.PkgOutputFileName, "wb")) == NULL) {\r
52302d4d 683 DebugError (NULL, 0, 0001, "Error opening file", mOptions.PkgOutputFileName);\r
30fdf114
LG
684 goto Fail;\r
685 }\r
686 if (gCFormPkg.BuildPkg (pFile, &gRBuffer) != VFR_RETURN_SUCCESS) {\r
687 fclose (pFile);\r
688 goto Fail;\r
689 }\r
690 fclose (pFile);\r
691 }\r
692\r
693 SET_RUN_STATUS (STATUS_GENBINARY);\r
694\r
695 return;\r
696\r
697Fail:\r
698 if (!IS_RUN_STATUS(STATUS_DEAD)) {\r
699 SET_RUN_STATUS (STATUS_FAILED);\r
700 }\r
701}\r
702\r
703static const char *gSourceFileHeader[] = {\r
704 "//",\r
705 "// DO NOT EDIT -- auto-generated file",\r
706 "//",\r
707 "// This file is generated by the vfrcompiler utility",\r
708 "//",\r
709 NULL\r
710};\r
711\r
712VOID\r
713CVfrCompiler::GenCFile (\r
714 VOID\r
715 )\r
716{\r
717 FILE *pFile;\r
718 UINT32 Index;\r
719\r
720 if (!IS_RUN_STATUS(STATUS_GENBINARY)) {\r
721 goto Fail;\r
722 }\r
b303ea72
LG
723 \r
724 if (!mOptions.CreateIfrPkgFile || mOptions.CompatibleMode) {\r
725 if ((pFile = fopen (mOptions.COutputFileName, "w")) == NULL) {\r
52302d4d 726 DebugError (NULL, 0, 0001, "Error opening output C file", mOptions.COutputFileName);\r
b303ea72
LG
727 goto Fail;\r
728 }\r
30fdf114 729\r
b303ea72
LG
730 for (Index = 0; gSourceFileHeader[Index] != NULL; Index++) {\r
731 fprintf (pFile, "%s\n", gSourceFileHeader[Index]);\r
732 }\r
30fdf114 733\r
b303ea72
LG
734 if (mOptions.CompatibleMode) { \r
735 gCVfrBufferConfig.OutputCFile (pFile, mOptions.VfrBaseFileName);\r
736 }\r
30fdf114 737\r
b303ea72
LG
738 if (gCFormPkg.GenCFile (mOptions.VfrBaseFileName, pFile, &gRBuffer) != VFR_RETURN_SUCCESS) {\r
739 fclose (pFile);\r
740 goto Fail;\r
741 }\r
30fdf114 742 fclose (pFile);\r
30fdf114 743 }\r
30fdf114
LG
744\r
745 SET_RUN_STATUS (STATUS_FINISHED);\r
746 return;\r
747\r
748Fail:\r
749 if (!IS_RUN_STATUS(STATUS_DEAD)) {\r
750 SET_RUN_STATUS (STATUS_FAILED);\r
751 }\r
752}\r
753\r
754VOID\r
755CVfrCompiler::GenRecordListFile (\r
756 VOID\r
757 )\r
758{\r
759 CHAR8 *InFileName = NULL;\r
760 FILE *pInFile = NULL;\r
761 FILE *pOutFile = NULL;\r
762 CHAR8 LineBuf[MAX_VFR_LINE_LEN];\r
763 UINT32 LineNo;\r
764\r
765 InFileName = (mOptions.SkipCPreprocessor == TRUE) ? mOptions.VfrFileName : mOptions.PreprocessorOutputFileName;\r
766\r
767 if (mOptions.CreateRecordListFile == TRUE) {\r
768 if ((InFileName[0] == '\0') || (mOptions.RecordListFile[0] == '\0')) {\r
769 return;\r
770 }\r
771\r
772 if ((pInFile = fopen (InFileName, "r")) == NULL) {\r
52302d4d 773 DebugError (NULL, 0, 0001, "Error opening the input VFR preprocessor output file", InFileName);\r
30fdf114
LG
774 return;\r
775 }\r
776\r
777 if ((pOutFile = fopen (mOptions.RecordListFile, "w")) == NULL) {\r
52302d4d 778 DebugError (NULL, 0, 0001, "Error opening the record list file", mOptions.RecordListFile);\r
30fdf114
LG
779 goto Err1;\r
780 }\r
781\r
b36d134f 782 fprintf (pOutFile, "//\n// VFR compiler version " VFR_COMPILER_VERSION __BUILD_VERSION "\n//\n");\r
30fdf114
LG
783 LineNo = 0;\r
784 while (!feof (pInFile)) {\r
785 if (fgets (LineBuf, MAX_VFR_LINE_LEN, pInFile) != NULL) {\r
786 fprintf (pOutFile, "%s", LineBuf);\r
787 LineNo++;\r
788 gCIfrRecordInfoDB.IfrRecordOutput (pOutFile, LineNo);\r
789 }\r
790 }\r
791 \r
792 fprintf (pOutFile, "\n//\n// All Opcode Record List \n//\n");\r
793 gCIfrRecordInfoDB.IfrRecordOutput (pOutFile, 0);\r
794 gCVfrVarDataTypeDB.Dump(pOutFile);\r
795\r
796 fclose (pOutFile);\r
797 fclose (pInFile);\r
798 }\r
799\r
800 return;\r
801\r
802Err1:\r
803 fclose (pInFile);\r
804}\r
805\r
806int\r
807main (\r
52302d4d
LG
808 IN int Argc, \r
809 IN char **Argv\r
30fdf114
LG
810 )\r
811{\r
812 COMPILER_RUN_STATUS Status;\r
4afd3d04
LG
813\r
814 SetPrintLevel(WARNING_LOG_LEVEL);\r
30fdf114
LG
815 CVfrCompiler Compiler(Argc, Argv);\r
816 \r
817 Compiler.PreProcess();\r
818 Compiler.Compile();\r
819 Compiler.AdjustBin();\r
820 Compiler.GenBinary();\r
821 Compiler.GenCFile();\r
822 Compiler.GenRecordListFile ();\r
823\r
824 Status = Compiler.RunStatus ();\r
825 if ((Status == STATUS_DEAD) || (Status == STATUS_FAILED)) {\r
826 return 2;\r
827 }\r
828\r
829 if (gCBuffer.Buffer != NULL) {\r
830 delete gCBuffer.Buffer;\r
831 }\r
832 \r
833 if (gRBuffer.Buffer != NULL) {\r
834 delete gRBuffer.Buffer;\r
835 }\r
836\r
837 return GetUtilityStatus ();\r
838}\r
839\r
52302d4d 840\r