]> git.proxmox.com Git - mirror_edk2.git/blob - EdkCompatibilityPkg/Sample/Tools/Source/GenAprioriFile/GenAprioriFile.c
Sync all bug fixes between EDK1.04 and EDK1.06 into EdkCompatibilityPkg.
[mirror_edk2.git] / EdkCompatibilityPkg / Sample / Tools / Source / GenAprioriFile / GenAprioriFile.c
1 /*++
2
3 Copyright (c) 2006 - 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
13 Module Name:
14
15 GenAprioriFile.c
16
17 Abstract:
18
19 Given an input file containing a list of GUIDs (or Guided file names),
20 convert the file to an Apriori file consumable by the dispatcher.
21
22 --*/
23
24 #include <stdio.h>
25 #include <string.h>
26 #include <ctype.h>
27
28 #include "EfiCommon.h"
29 #include "ParseInf.h"
30 #include "CommonLib.h" // for compare guid
31 #include "EfiUtilityMsgs.h"
32
33 #define MAX_LINE_LEN 200
34 #define MAX_PATH 200
35
36 //
37 // typedef unsigned int STATUS;
38 // #define STATUS_SUCCESS 0
39 // #define STATUS_WARNING 1
40 // #define STATUS_ERROR 2
41 //
42 #define UTILITY_NAME "GenAprioriFile"
43 #define UTILITY_VERSION "v1.0"
44 //
45 // Here's all our globals.
46 //
47 static struct {
48 FILE *BinFptr; // output dependencies to this file
49 INT8 *AprioriFileName;
50 INT8 *OutputFileName;
51 BOOLEAN Intelligent;
52 BOOLEAN Verbose;
53 BOOLEAN NullTerminate;
54 } mGlobals;
55
56 static
57 STATUS
58 ProcessArgs (
59 int Argc,
60 char *Argv[]
61 );
62
63 static
64 BOOLEAN
65 IsCommentLine (
66 INT8 *Line
67 );
68
69 static
70 void
71 Usage (
72 VOID
73 );
74
75 int
76 main (
77 int Argc,
78 char *Argv[]
79 )
80 /*++
81
82 Routine Description:
83
84 Call the routine to parse the command-line options, then process the
85 Apriori list file and generate the GUID file.
86
87 Arguments:
88
89 Standard C main() argc and argv.
90
91 Returns:
92
93 0 if successful
94 nonzero otherwise
95
96 --*/
97 // GC_TODO: Argc - add argument and description to function comment
98 // GC_TODO: ] - add argument and description to function comment
99 {
100 STATUS Status;
101 FILE *AprioriFptr;
102 FILE *BinFptr;
103 INT8 Line[MAX_LINE_LEN];
104 EFI_GUID Guid;
105 EFI_GUID GuidIn;
106 EFI_GUID ZeroGuid;
107 UINT32 LineCounter;
108 //
109 // Initialize the error printing routines
110 //
111 SetUtilityName (UTILITY_NAME);
112 //
113 // Clear our globals
114 //
115 memset ((char *) &mGlobals, 0, sizeof (mGlobals));
116 memset ((char *) &ZeroGuid, 0, sizeof (ZeroGuid));
117 AprioriFptr = NULL;
118 BinFptr = NULL;
119
120 //
121 // Process the command-line arguments
122 //
123 Status = ProcessArgs (Argc, Argv);
124 if (Status != STATUS_SUCCESS) {
125 return Status;
126 }
127 //
128 // If arguments were ok, then open the Apriori file and process it.
129 //
130 if ((AprioriFptr = fopen (mGlobals.AprioriFileName, "r")) == NULL) {
131 Error (NULL, 0, 0, mGlobals.AprioriFileName, "failed to open file for reading");
132 goto FinishUp;
133 }
134 //
135 // If -i intelligent option specified, then attempt to read and
136 // existing output file and see if we'd be creating an identical file.
137 //
138 if (mGlobals.Intelligent) {
139 if ((BinFptr = fopen (mGlobals.OutputFileName, "rb")) == NULL) {
140 if (mGlobals.Verbose) {
141 DebugMsg (NULL, 0, 0, "Creating new apriori file -- no existing file", NULL);
142 }
143
144 goto CreateFile;
145 }
146 //
147 // Read lines from the input file until done. Convert each to a guid, then
148 // read a guid from the input file and compare them.
149 //
150 while (fgets (Line, sizeof (Line), AprioriFptr) != NULL) {
151
152 if (IsCommentLine (Line)) {
153 continue;
154 }
155 //
156 // Convert to a guid
157 //
158 if (StringToGuid (Line, &Guid) != EFI_SUCCESS) {
159 if (mGlobals.Verbose) {
160 DebugMsg (NULL, 0, 0, "failed to read GUID from input text file -- creating new file", NULL);
161 }
162
163 goto CreateFile;
164 }
165 //
166 // Read guid from input file, then compare
167 //
168 if (fread (&GuidIn, sizeof (GuidIn), 1, BinFptr) != 1) {
169 if (mGlobals.Verbose) {
170 DebugMsg (NULL, 0, 0, "failed to read GUID from input binary file -- creating new file", NULL);
171 }
172
173 goto CreateFile;
174 }
175
176 if (CompareGuid (&Guid, &GuidIn) != 0) {
177 if (mGlobals.Verbose) {
178 DebugMsg (NULL, 0, 0, "GUID comparison failed -- creating new file", NULL);
179 }
180
181 goto CreateFile;
182 }
183 }
184 //
185 // May be one more NULL guid in the binary file
186 //
187 if (mGlobals.NullTerminate) {
188 if (fread (&GuidIn, sizeof (GuidIn), 1, BinFptr) != 1) {
189 if (mGlobals.Verbose) {
190 DebugMsg (NULL, 0, 0, "failed to read NULL GUID from input binary file -- creating new file", NULL);
191 }
192
193 goto CreateFile;
194 }
195
196 if (CompareGuid (&GuidIn, &ZeroGuid) != 0) {
197 if (mGlobals.Verbose) {
198 DebugMsg (NULL, 0, 0, "NULL GUID comparison failed -- creating new file", NULL);
199 }
200
201 goto CreateFile;
202 }
203 }
204 //
205 // Make sure we're at the end of both files.
206 //
207 if ((fgets (Line, sizeof (Line), AprioriFptr) != NULL) || (fread (&GuidIn, 1, 1, BinFptr) != 0)) {
208 if (mGlobals.Verbose) {
209 DebugMsg (NULL, 0, 0, "file sizes different, -i test failed -- creating new file", NULL);
210 }
211
212 goto CreateFile;
213 }
214
215 if (mGlobals.Verbose) {
216 DebugMsg (NULL, 0, 0, "existing file would be unchanged -- keeping existing apriori file", NULL);
217 }
218
219 goto FinishUp;
220 }
221
222 CreateFile:
223 //
224 // Rewind the Apriori file in case -i was specified. Also
225 // try to close the output file for the case where we prescanned
226 // it (again, because of -i).
227 //
228 rewind (AprioriFptr);
229 if (BinFptr != NULL) {
230 fclose (BinFptr);
231 }
232 //
233 // Open the output file
234 //
235 if ((BinFptr = fopen (mGlobals.OutputFileName, "wb")) == NULL) {
236 Error (NULL, 0, 0, mGlobals.OutputFileName, "could not open input file");
237 goto FinishUp;
238 }
239 //
240 // Read lines until we're done
241 //
242 LineCounter = 0;
243 while (fgets (Line, sizeof (Line), AprioriFptr) != NULL) {
244 LineCounter++;
245 if (IsCommentLine (Line)) {
246 continue;
247 }
248 //
249 // Convert to a GUID
250 //
251 if (StringToGuid (Line, &Guid) != EFI_SUCCESS) {
252 Error (mGlobals.AprioriFileName, LineCounter, 0, "failed to convert GUID", NULL);
253 goto FinishUp;
254 }
255 //
256 // Write the guid to the output file
257 //
258 if (fwrite (&Guid, sizeof (Guid), 1, BinFptr) != 1) {
259 Error (NULL, 0, 0, mGlobals.OutputFileName, "failed to write GUID to output file");
260 goto FinishUp;
261 }
262 }
263 //
264 // Write a null guid out to terminate the list
265 //
266 if (mGlobals.NullTerminate) {
267 memset ((void *) &Guid, 0, sizeof (Guid));
268 if (fwrite (&Guid, sizeof (Guid), 1, BinFptr) != 1) {
269 Error (NULL, 0, 0, mGlobals.OutputFileName, "failed to write NULL termination GUID to output file");
270 }
271 }
272
273 FinishUp:
274
275 if (AprioriFptr != NULL) {
276 fclose (AprioriFptr);
277 }
278
279 if (BinFptr != NULL) {
280 fclose (BinFptr);
281 }
282
283 return GetUtilityStatus ();
284 }
285
286 static
287 BOOLEAN
288 IsCommentLine (
289 INT8 *Line
290 )
291 /*++
292
293 Routine Description:
294
295 GC_TODO: Add function description
296
297 Arguments:
298
299 Line - GC_TODO: add argument description
300
301 Returns:
302
303 GC_TODO: add return values
304
305 --*/
306 {
307 for (; isspace (*Line) && *Line; Line++)
308 ;
309
310 //
311 // Allow # or // comments
312 //
313 if ((*Line == '#') || ((*Line == '/') && (*(Line + 1) == '/')) || (*Line == '\n') || (*Line == 0)) {
314 return TRUE;
315 }
316
317 return FALSE;
318 }
319 //
320 // Process the command-line arguments
321 //
322 static
323 STATUS
324 ProcessArgs (
325 int Argc,
326 char *Argv[]
327 )
328 /*++
329
330 Routine Description:
331
332 GC_TODO: Add function description
333
334 Arguments:
335
336 Argc - GC_TODO: add argument description
337 ] - GC_TODO: add argument description
338
339 Returns:
340
341 GC_TODO: add return values
342
343 --*/
344 {
345 //
346 // Skip program name
347 //
348 Argc--;
349 Argv++;
350
351 //
352 // Process until no more args
353 //
354 while (Argc) {
355 //
356 // -f AprioriFile
357 //
358 if (_stricmp (Argv[0], "-f") == 0) {
359 //
360 // check for one more arg
361 //
362 if (Argc > 1) {
363 mGlobals.AprioriFileName = Argv[1];
364 } else {
365 Error (NULL, 0, 0, NULL, "missing filename with %s", Argv[0]);
366 Usage ();
367 return STATUS_ERROR;
368 }
369
370 Argc--;
371 Argv++;
372 } else if (_stricmp (Argv[0], "-i") == 0) {
373 //
374 // intelligent creation of output file. That is to say, if
375 // there's already a file there, and it's the same as what
376 // we'd create, then don't re-create. This is to support
377 // incremental builds (that is to say, running nmake a second time
378 // does nothing).
379 //
380 mGlobals.Intelligent = TRUE;
381 } else if (_stricmp (Argv[0], "-v") == 0) {
382 mGlobals.Verbose = TRUE;
383 } else if (_stricmp (Argv[0], "-null") == 0) {
384 mGlobals.NullTerminate = TRUE;
385 } else if (_stricmp (Argv[0], "-o") == 0) {
386 //
387 // -o OutputFileName
388 // check for one more arg
389 //
390 if (Argc > 1) {
391 mGlobals.OutputFileName = Argv[1];
392 } else {
393 Error (NULL, 0, 0, NULL, "missing filename argument with %s", Argv[0]);
394 Usage ();
395 return STATUS_ERROR;
396 }
397
398 Argc--;
399 Argv++;
400 } else if ((_stricmp (Argv[0], "-h") == 0) || (strcmp (Argv[0], "-?") == 0)) {
401 Usage ();
402 return STATUS_ERROR;
403 } else {
404 Error (NULL, 0, 0, Argv[0], "unrecognized option");
405 Usage ();
406 return STATUS_ERROR;
407 }
408
409 Argc--;
410 Argv++;
411 }
412 //
413 // Had to specify the apriori input file and output file names
414 //
415 if (mGlobals.AprioriFileName == NULL) {
416 Error (NULL, 0, 0, "must specify -f AprioriFile", NULL);
417 Usage ();
418 return STATUS_ERROR;
419 }
420
421 if (mGlobals.OutputFileName == NULL) {
422 Error (NULL, 0, 0, "must specify -o OutputFile", NULL);
423 Usage ();
424 return STATUS_ERROR;
425 }
426
427 return STATUS_SUCCESS;
428 }
429
430 static
431 void
432 Usage (
433 VOID
434 )
435 /*++
436
437 Routine Description:
438
439 Print usage information for this utility.
440
441 Arguments:
442
443 None.
444
445 Returns:
446
447 Nothing.
448
449 --*/
450 {
451 int Index;
452 const char *Str[] = {
453 UTILITY_NAME" "UTILITY_VERSION" - Intel Generate Apriori File Utility",
454 " Copyright (C), 2006 - 2008 Intel Corporation",
455
456 #if ( defined(UTILITY_BUILD) && defined(UTILITY_VENDOR) )
457 " Built from "UTILITY_BUILD", project of "UTILITY_VENDOR,
458 #endif
459 "",
460 "Usage:",
461 " "UTILITY_NAME" [OPTION]...",
462 "Description:",
463 " Generate an Apriori file consumable by the DXE or PEI dispatcher.",
464 "Options:",
465 " -h or -? for this help information",
466 " -f AprioriFile parse the GUID'ed files in AprioriFile (required)",
467 " -o OutputFile write output to OutputFile (required)",
468 " -i for intelligent re-creation of OutputFile",
469 " -null to terminate the output file with a NULL GUID",
470 " -v verbose option",
471 NULL
472 };
473 for (Index = 0; Str[Index] != NULL; Index++) {
474 fprintf (stdout, "%s\n", Str[Index]);
475 }
476 }