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