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