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