]> git.proxmox.com Git - mirror_edk2.git/blob - EdkCompatibilityPkg/Sample/Tools/Source/UefiVfrCompile/VfrCompiler.cpp
Update the copyright notice format
[mirror_edk2.git] / EdkCompatibilityPkg / Sample / Tools / Source / UefiVfrCompile / VfrCompiler.cpp
1 /*++
2
3 Copyright (c) 2004 - 2010, Intel Corporation. All rights reserved.<BR>
4 This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
8
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
11
12 Module Name:
13
14 VfrCompiler.cpp
15
16 Abstract:
17
18 --*/
19
20 #include "stdio.h"
21 #include "string.h"
22 #include "process.h"
23 #include "VfrCompiler.h"
24
25
26 VOID
27 CVfrCompiler::SET_RUN_STATUS (
28 IN COMPILER_RUN_STATUS Status
29 )
30 {
31 mRunStatus = Status;
32 }
33
34 BOOLEAN
35 CVfrCompiler::IS_RUN_STATUS (
36 IN COMPILER_RUN_STATUS Status
37 )
38 {
39 return mRunStatus == Status;
40 }
41
42 VOID
43 CVfrCompiler::OptionInitialization (
44 IN INT32 Argc,
45 IN INT8 **Argv
46 )
47 {
48 INT32 Index;
49
50 mOptions.VfrFileName[0] = '\0';
51 mOptions.RecordListFile[0] = '\0';
52 mOptions.CreateRecordListFile = FALSE;
53 mOptions.CreateIfrPkgFile = FALSE;
54 mOptions.PkgOutputFileName[0] = '\0';
55 mOptions.COutputFileName[0] = '\0';
56 mOptions.OutputDirectory[0] = '\0';
57 mOptions.PreprocessorOutputFileName[0] = '\0';
58 mOptions.VfrBaseFileName[0] = '\0';
59 mOptions.IncludePaths = NULL;
60 mOptions.CPreprocessorOptions = NULL;
61
62 for (Index = 1; (Index < Argc) && (Argv[Index][0] == '-'); Index++) {
63 if ((_stricmp(Argv[Index], "-?") == 0) || (_stricmp(Argv[Index], "-h") == 0)) {
64 Usage ();
65 SET_RUN_STATUS (STATUS_DEAD);
66 return;
67 } else if (_stricmp(Argv[Index], "-l") == 0) {
68 mOptions.CreateRecordListFile = TRUE;
69 gCIfrRecordInfoDB.TurnOn ();
70 } else if (_stricmp(Argv[Index], "-i") == 0) {
71 Index++;
72 if ((Index >= Argc) || (Argv[Index][0] == '-')) {
73 printf ("%s -i - missing path argument\n", PROGRAM_NAME);
74 goto Fail;
75 }
76
77 AppendIncludePath(Argv[Index]);
78 } else if (_stricmp(Argv[Index], "-od") == 0) {
79 Index++;
80 if ((Index >= Argc) || (Argv[Index][0] == '-')) {
81 printf ("%s -od - missing output directory name\n", PROGRAM_NAME);
82 goto Fail;
83 }
84 strcpy (mOptions.OutputDirectory, Argv[Index]);
85 } else if (_stricmp(Argv[Index], "-ibin") == 0) {
86 mOptions.CreateIfrPkgFile = TRUE;
87 } else if (_stricmp(Argv[Index], "-nostrings") == 0) {
88 } else if (_stricmp(Argv[Index], "-ppflag") == 0) {
89 Index++;
90 if ((Index >= Argc) || (Argv[Index][0] == '-')) {
91 printf ("%s -od - missing C-preprocessor argument\n", PROGRAM_NAME);
92 goto Fail;
93 }
94
95 AppendCPreprocessorOptions (Argv[Index]);
96 } else {
97 printf ("%s unrecognized option %s\n", PROGRAM_NAME, Argv[Index]);
98 Usage ();
99 goto Fail;
100 }
101 }
102
103 if (Index != Argc - 1) {
104 printf ("%s must specify VFR file name", PROGRAM_NAME);
105 Usage ();
106 goto Fail;
107 } else {
108 strcpy (mOptions.VfrFileName, Argv[Index]);
109 }
110
111 if (SetBaseFileName() != 0) {
112 goto Fail;
113 }
114 if (SetPkgOutputFileName () != 0) {
115 goto Fail;
116 }
117 if (SetCOutputFileName() != 0) {
118 goto Fail;
119 }
120 if (SetPreprocessorOutputFileName () != 0) {
121 goto Fail;
122 }
123 if (SetRecordListFileName () != 0) {
124 goto Fail;
125 }
126 return;
127
128 Fail:
129 SET_RUN_STATUS (STATUS_FAILED);
130
131 mOptions.VfrFileName[0] = '\0';
132 mOptions.RecordListFile[0] = '\0';
133 mOptions.CreateRecordListFile = FALSE;
134 mOptions.CreateIfrPkgFile = FALSE;
135 mOptions.PkgOutputFileName[0] = '\0';
136 mOptions.COutputFileName[0] = '\0';
137 mOptions.OutputDirectory[0] = '\0';
138 mOptions.PreprocessorOutputFileName[0] = '\0';
139 mOptions.VfrBaseFileName[0] = '\0';
140 if (mOptions.IncludePaths != NULL) {
141 delete mOptions.IncludePaths;
142 mOptions.IncludePaths = NULL;
143 }
144 if (mOptions.CPreprocessorOptions != NULL) {
145 delete mOptions.CPreprocessorOptions;
146 mOptions.CPreprocessorOptions = NULL;
147 }
148 }
149
150 VOID
151 CVfrCompiler::AppendIncludePath (
152 IN INT8 *PathStr
153 )
154 {
155 UINT32 Len = 0;
156 INT8 *IncludePaths = NULL;
157
158 Len = strlen (" -I ") + strlen (PathStr) + 1;
159 if (mOptions.IncludePaths != NULL) {
160 Len += strlen (mOptions.IncludePaths);
161 }
162 IncludePaths = new INT8[Len];
163 if (IncludePaths == NULL) {
164 printf ("%s memory allocation failure\n", PROGRAM_NAME);
165 return;
166 }
167 IncludePaths[0] = '\0';
168 if (mOptions.IncludePaths != NULL) {
169 strcat (IncludePaths, mOptions.IncludePaths);
170 }
171 strcat (IncludePaths, " -I ");
172 strcat (IncludePaths, PathStr);
173 if (mOptions.IncludePaths != NULL) {
174 delete mOptions.IncludePaths;
175 }
176 mOptions.IncludePaths = IncludePaths;
177 }
178
179 VOID
180 CVfrCompiler::AppendCPreprocessorOptions (
181 IN INT8 *Options
182 )
183 {
184 UINT32 Len = 0;
185 INT8 *Opt = NULL;
186
187 Len = strlen (Options) + strlen (" ") + 1;
188 if (mOptions.CPreprocessorOptions != NULL) {
189 Len += strlen (mOptions.CPreprocessorOptions);
190 }
191 Opt = new INT8[Len];
192 if (Opt == NULL) {
193 printf ("%s memory allocation failure\n", PROGRAM_NAME);
194 return;
195 }
196 Opt[0] = 0;
197 if (mOptions.CPreprocessorOptions != NULL) {
198 strcat (Opt, mOptions.CPreprocessorOptions);
199 }
200 strcat (Opt, " ");
201 strcat (Opt, Options);
202 if (mOptions.CPreprocessorOptions != NULL) {
203 delete mOptions.CPreprocessorOptions;
204 }
205 mOptions.CPreprocessorOptions = Opt;
206 }
207
208 INT8
209 CVfrCompiler::SetBaseFileName (
210 VOID
211 )
212 {
213 INT8 *pFileName, *pPath, *pExt;
214
215 if (mOptions.VfrFileName[0] == '\0') {
216 return -1;
217 }
218
219 pFileName = mOptions.VfrFileName;
220 while ((pPath = strchr (pFileName, '\\')) != NULL) {
221 pFileName = pPath + 1;
222 }
223
224 if (pFileName == NULL) {
225 return -1;
226 }
227
228 if ((pExt = strchr (pFileName, '.')) == NULL) {
229 return -1;
230 }
231
232 strncpy (mOptions.VfrBaseFileName, pFileName, pExt - pFileName);
233 mOptions.VfrBaseFileName[pExt - pFileName] = '\0';
234
235 return 0;
236 }
237
238 INT8
239 CVfrCompiler::SetPkgOutputFileName (
240 VOID
241 )
242 {
243 if (mOptions.VfrBaseFileName[0] == '\0') {
244 return -1;
245 }
246
247 strcpy (mOptions.PkgOutputFileName, mOptions.OutputDirectory);
248 strcat (mOptions.PkgOutputFileName, mOptions.VfrBaseFileName);
249 strcat (mOptions.PkgOutputFileName, VFR_PACKAGE_FILENAME_EXTENSION);
250
251 return 0;
252 }
253
254 INT8
255 CVfrCompiler::SetCOutputFileName (
256 VOID
257 )
258 {
259 if (mOptions.VfrBaseFileName[0] == '\0') {
260 return -1;
261 }
262
263 strcpy (mOptions.COutputFileName, mOptions.OutputDirectory);
264 strcat (mOptions.COutputFileName, mOptions.VfrBaseFileName);
265 strcat (mOptions.COutputFileName, ".c");
266
267 return 0;
268 }
269
270 INT8
271 CVfrCompiler::SetPreprocessorOutputFileName (
272 VOID
273 )
274 {
275 if (mOptions.VfrBaseFileName[0] == '\0') {
276 return -1;
277 }
278
279 strcpy (mOptions.PreprocessorOutputFileName, mOptions.OutputDirectory);
280 strcat (mOptions.PreprocessorOutputFileName, mOptions.VfrBaseFileName);
281 strcat (mOptions.PreprocessorOutputFileName, VFR_PREPROCESS_FILENAME_EXTENSION);
282
283 return 0;
284 }
285
286 INT8
287 CVfrCompiler::SetRecordListFileName (
288 VOID
289 )
290 {
291 if (mOptions.VfrBaseFileName[0] == '\0') {
292 return -1;
293 }
294
295 strcpy (mOptions.RecordListFile, mOptions.OutputDirectory);
296 strcat (mOptions.RecordListFile, mOptions.VfrBaseFileName);
297 strcat (mOptions.RecordListFile, VFR_RECORDLIST_FILENAME_EXTENSION);
298
299 return 0;
300 }
301
302 CVfrCompiler::CVfrCompiler (
303 IN INT32 Argc,
304 IN INT8 **Argv
305 )
306 {
307 mPreProcessCmd = PREPROCESSOR_COMMAND;
308 mPreProcessOpt = PREPROCESSOR_OPTIONS;
309
310 OptionInitialization(Argc, Argv);
311
312 if ((IS_RUN_STATUS(STATUS_FAILED)) || (IS_RUN_STATUS(STATUS_DEAD))) {
313 return;
314 }
315
316 SET_RUN_STATUS(STATUS_INITIALIZED);
317 }
318
319 CVfrCompiler::~CVfrCompiler (
320 VOID
321 )
322 {
323 if (mOptions.IncludePaths != NULL) {
324 delete mOptions.IncludePaths;
325 mOptions.IncludePaths = NULL;
326 }
327
328 if (mOptions.CPreprocessorOptions != NULL) {
329 delete mOptions.CPreprocessorOptions;
330 mOptions.CPreprocessorOptions = NULL;
331 }
332
333 SET_RUN_STATUS(STATUS_DEAD);
334 }
335
336 VOID
337 CVfrCompiler::Usage (
338 VOID
339 )
340 {
341 UINT32 Index;
342 CONST INT8 *Help[] = {
343 " ",
344 "VfrCompile version " VFR_COMPILER_VERSION,
345 " ",
346 " Usage: VfrCompile {options} [VfrFile]",
347 " ",
348 " where options include:",
349 " -? or -h prints this help",
350 " -l create an output IFR listing file",
351 " -i IncPath add IncPath to the search path for VFR included files",
352 " -od OutputDir deposit all output files to directory OutputDir (default=cwd)",
353 " -ibin create an IFR HII pack file"
354 " -ppflag C-preprocessor argument",
355 " where parameters include:",
356 " VfrFile name of the input VFR script file",
357 " ",
358 NULL
359 };
360 for (Index = 0; Help[Index] != NULL; Index++) {
361 fprintf (stdout, "%s\n", Help[Index]);
362 }
363 }
364
365 VOID
366 CVfrCompiler::PreProcess (
367 VOID
368 )
369 {
370 FILE *pVfrFile = NULL;
371 UINT32 CmdLen = 0;
372 INT8 *PreProcessCmd = NULL;
373
374 if (!IS_RUN_STATUS(STATUS_INITIALIZED)) {
375 goto Fail;
376 }
377
378 if ((pVfrFile = fopen (mOptions.VfrFileName, "r")) == NULL) {
379 printf ("%s could not open input VFR file - %s\n", PROGRAM_NAME, mOptions.VfrFileName);
380 goto Fail;
381 }
382 fclose (pVfrFile);
383
384 CmdLen = strlen (mPreProcessCmd) + strlen (mPreProcessOpt) +
385 strlen (mOptions.VfrFileName) + strlen (mOptions.PreprocessorOutputFileName);
386 if (mOptions.CPreprocessorOptions != NULL) {
387 CmdLen += strlen (mOptions.CPreprocessorOptions);
388 }
389 if (mOptions.IncludePaths != NULL) {
390 CmdLen += strlen (mOptions.IncludePaths);
391 }
392
393 PreProcessCmd = new INT8[CmdLen + 10];
394 if (PreProcessCmd == NULL) {
395 printf ("%s could not allocate memory\n", PROGRAM_NAME);
396 goto Fail;
397 }
398 strcpy (PreProcessCmd, mPreProcessCmd), strcat (PreProcessCmd, " ");
399 strcat (PreProcessCmd, mPreProcessOpt), strcat (PreProcessCmd, " ");
400 if (mOptions.IncludePaths != NULL) {
401 strcat (PreProcessCmd, mOptions.IncludePaths), strcat (PreProcessCmd, " ");
402 }
403 if (mOptions.CPreprocessorOptions != NULL) {
404 strcat (PreProcessCmd, mOptions.CPreprocessorOptions), strcat (PreProcessCmd, " ");
405 }
406 strcat (PreProcessCmd, mOptions.VfrFileName), strcat (PreProcessCmd, " > ");
407 strcat (PreProcessCmd, mOptions.PreprocessorOutputFileName);
408
409 if (system (PreProcessCmd) != 0) {
410 printf ("%s failed to spawn C preprocessor on VFR file \n\t - %s\n", PROGRAM_NAME, PreProcessCmd);
411 goto Fail;
412 }
413
414 delete PreProcessCmd;
415 SET_RUN_STATUS (STATUS_PREPROCESSED);
416 return;
417
418 Fail:
419 if (!IS_RUN_STATUS(STATUS_DEAD)) {
420 SET_RUN_STATUS (STATUS_FAILED);
421 }
422 delete PreProcessCmd;
423 }
424
425 extern UINT8 VfrParserStart (IN FILE *);
426
427 VOID
428 CVfrCompiler::Compile (
429 VOID
430 )
431 {
432 FILE *VfrFile = NULL;
433
434 if (!IS_RUN_STATUS(STATUS_PREPROCESSED)) {
435 goto Fail;
436 }
437
438 if ((VfrFile = fopen (mOptions.PreprocessorOutputFileName, "r")) == NULL) {
439 printf ("%s failed to open input VFR preprocessor output file - %s\n", PROGRAM_NAME, mOptions.PreprocessorOutputFileName);
440 goto Fail;
441 }
442
443 if (VfrParserStart (VfrFile) != 0) {
444 goto Fail;
445 }
446
447 fclose (VfrFile);
448
449 if (gCFormPkg.HavePendingUnassigned () == TRUE) {
450 gCFormPkg.PendingAssignPrintAll ();
451 goto Fail;
452 }
453
454 SET_RUN_STATUS (STATUS_COMPILEED);
455 return;
456
457 Fail:
458 if (!IS_RUN_STATUS(STATUS_DEAD)) {
459 printf ("%s compile error!\n", PROGRAM_NAME);
460 SET_RUN_STATUS (STATUS_FAILED);
461 }
462 if (VfrFile != NULL) {
463 fclose (VfrFile);
464 }
465 }
466
467 VOID
468 CVfrCompiler::GenBinary (
469 VOID
470 )
471 {
472 FILE *pFile = NULL;
473
474 if (!IS_RUN_STATUS(STATUS_COMPILEED)) {
475 goto Fail;
476 }
477
478 if (mOptions.CreateIfrPkgFile == TRUE) {
479 if ((pFile = fopen (mOptions.PkgOutputFileName, "wb")) == NULL) {
480 printf ("can not open PkgFileName\n", mOptions.PkgOutputFileName);
481 goto Fail;
482 }
483 if (gCFormPkg.BuildPkg (pFile) != VFR_RETURN_SUCCESS) {
484 fclose (pFile);
485 goto Fail;
486 }
487 fclose (pFile);
488 }
489
490 SET_RUN_STATUS (STATUS_GENBINARY);
491 return;
492
493 Fail:
494 if (!IS_RUN_STATUS(STATUS_DEAD)) {
495 SET_RUN_STATUS (STATUS_FAILED);
496 }
497 }
498
499 static const char *gSourceFileHeader[] = {
500 "//",
501 "// DO NOT EDIT -- auto-generated file",
502 "//",
503 "// This file is generated by the vfrcompiler utility",
504 "//",
505 NULL
506 };
507
508 VOID
509 CVfrCompiler::GenCFile (
510 VOID
511 )
512 {
513 FILE *pFile;
514 UINT32 Index;
515
516 if (!IS_RUN_STATUS(STATUS_GENBINARY)) {
517 goto Fail;
518 }
519
520 if ((pFile = fopen (mOptions.COutputFileName, "w")) == NULL) {
521 printf ("failed to open output C file - %s\n", mOptions.COutputFileName);
522 goto Fail;
523 }
524
525 for (Index = 0; gSourceFileHeader[Index] != NULL; Index++) {
526 fprintf (pFile, "%s\n", gSourceFileHeader[Index]);
527 }
528
529 gCVfrBufferConfig.OutputCFile (pFile, mOptions.VfrBaseFileName);
530
531 if (gCFormPkg.GenCFile (mOptions.VfrBaseFileName, pFile) != VFR_RETURN_SUCCESS) {
532 fclose (pFile);
533 goto Fail;
534 }
535 fclose (pFile);
536
537 SET_RUN_STATUS (STATUS_FINISHED);
538 return;
539
540 Fail:
541 if (!IS_RUN_STATUS(STATUS_DEAD)) {
542 SET_RUN_STATUS (STATUS_FAILED);
543 }
544 }
545
546 VOID
547 CVfrCompiler::GenRecordListFile (
548 VOID
549 )
550 {
551 FILE *pInFile = NULL;
552 FILE *pOutFile = NULL;
553 INT8 LineBuf[MAX_LINE_LEN];
554 UINT32 LineNo;
555
556 if (mOptions.CreateRecordListFile == TRUE) {
557 if ((mOptions.PreprocessorOutputFileName[0] == '\0') || (mOptions.RecordListFile[0] == '\0')) {
558 return;
559 }
560
561 if ((pInFile = fopen (mOptions.PreprocessorOutputFileName, "r")) == NULL) {
562 printf ("%s failed to open input VFR preprocessor output file - %s\n", PROGRAM_NAME, mOptions.PreprocessorOutputFileName);
563 return;
564 }
565
566 if ((pOutFile = fopen (mOptions.RecordListFile, "w")) == NULL) {
567 printf ("%s failed to open record list file for writing - %s\n", PROGRAM_NAME, mOptions.RecordListFile);
568 goto Err1;
569 }
570
571 fprintf (pOutFile, "//\n// VFR compiler version " VFR_COMPILER_VERSION "\n//\n");
572 LineNo = 0;
573 while (!feof (pInFile)) {
574 if (fgets (LineBuf, MAX_LINE_LEN, pInFile) != NULL) {
575 fprintf (pOutFile, "%s", LineBuf);
576 LineNo++;
577 gCIfrRecordInfoDB.IfrRecordOutput (pOutFile, LineNo);
578 }
579 }
580
581 fclose (pOutFile);
582 fclose (pInFile);
583 }
584
585 return;
586
587 Err1:
588 fclose (pInFile);
589 }
590
591 INT32
592 main (
593 IN INT32 Argc,
594 IN INT8 **Argv
595 )
596 {
597 COMPILER_RUN_STATUS Status;
598 CVfrCompiler Compiler(Argc, Argv);
599
600 Compiler.PreProcess();
601 Compiler.Compile();
602 Compiler.GenBinary();
603 Compiler.GenCFile();
604 Compiler.GenRecordListFile ();
605
606 Status = Compiler.RunStatus ();
607 if ((Status == STATUS_DEAD) || (Status == STATUS_FAILED)) {
608 return 2;
609 }
610
611 return 0;
612 }
613