]> git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Source/C/Common/PcdValueCommon.c
BaseTools: Fix compile error on VS2010
[mirror_edk2.git] / BaseTools / Source / C / Common / PcdValueCommon.c
1 /** @file
2 This file contains the PcdValue structure definition.
3
4 Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
5
6 This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
10
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
13
14 **/
15
16 #include <stdio.h>
17 #include <string.h>
18 #include <stdlib.h>
19 #include "CommonLib.h"
20 #include "PcdValueCommon.h"
21
22 typedef enum {
23 PcdDataTypeBoolean,
24 PcdDataTypeUint8,
25 PcdDataTypeUint16,
26 PcdDataTypeUint32,
27 PcdDataTypeUint64,
28 PcdDataTypePointer
29 } PCD_DATA_TYPE;
30
31 typedef struct {
32 CHAR8 *SkuName;
33 CHAR8 *DefaultValueName;
34 CHAR8 *TokenSpaceGuidName;
35 CHAR8 *TokenName;
36 CHAR8 *DataType;
37 CHAR8 *Value;
38 PCD_DATA_TYPE PcdDataType;
39 } PCD_ENTRY;
40
41 PCD_ENTRY *PcdList;
42 UINT32 PcdListLength;
43
44 VOID
45 STATIC
46 RecordToken (
47 UINT8 *FileBuffer,
48 UINT32 PcdIndex,
49 UINT32 TokenIndex,
50 UINT32 TokenStart,
51 UINT32 TokenEnd
52 )
53 /*++
54
55 Routine Description:
56
57 Record new token information
58
59 Arguments:
60
61 FileBuffer File Buffer to be record
62 PcdIndex Index of PCD in database
63 TokenIndex Index of Token
64 TokenStart Start of Token
65 TokenEnd End of Token
66
67 Returns:
68
69 None
70 --*/
71 {
72 CHAR8 *Token;
73
74 Token = malloc (TokenEnd - TokenStart + 1);
75 memcpy (Token, &FileBuffer[TokenStart], TokenEnd - TokenStart);
76 Token[TokenEnd - TokenStart] = 0;
77 switch (TokenIndex) {
78 case 0:
79 PcdList[PcdIndex].SkuName = Token;
80 break;
81 case 1:
82 PcdList[PcdIndex].DefaultValueName = Token;
83 break;
84 case 2:
85 PcdList[PcdIndex].TokenSpaceGuidName = Token;
86 break;
87 case 3:
88 PcdList[PcdIndex].TokenName = Token;
89 break;
90 case 4:
91 PcdList[PcdIndex].DataType = Token;
92 if (strcmp (Token, "BOOLEAN") == 0) {
93 PcdList[PcdIndex].PcdDataType = PcdDataTypeBoolean;
94 } else if (strcmp (Token, "UINT8") == 0) {
95 PcdList[PcdIndex].PcdDataType = PcdDataTypeUint8;
96 } else if (strcmp (Token, "UINT16") == 0) {
97 PcdList[PcdIndex].PcdDataType = PcdDataTypeUint16;
98 } else if (strcmp (Token, "UINT32") == 0) {
99 PcdList[PcdIndex].PcdDataType = PcdDataTypeUint32;
100 } else if (strcmp (Token, "UINT64") == 0) {
101 PcdList[PcdIndex].PcdDataType = PcdDataTypeUint64;
102 } else {
103 PcdList[PcdIndex].PcdDataType = PcdDataTypePointer;
104 }
105 break;
106 case 5:
107 PcdList[PcdIndex].Value = Token;
108 break;
109 }
110 }
111
112 int
113 STATIC
114 LookupPcdIndex (
115 CHAR8 *SkuName OPTIONAL,
116 CHAR8 *DefaultValueName OPTIONAL,
117 CHAR8 *TokenSpaceGuidName,
118 CHAR8 *TokenName
119 )
120 /*++
121
122 Routine Description:
123
124 Get PCD index in Pcd database
125
126 Arguments:
127
128 SkuName SkuName String
129 DefaultValueName DefaultValueName String
130 TokenSpaceGuidName TokenSpaceGuidName String
131 TokenName TokenName String
132
133 Returns:
134
135 Index of PCD in Pcd database
136 --*/
137 {
138 UINT32 Index;
139
140 if (SkuName == NULL) {
141 SkuName = "DEFAULT";
142 }
143 if (DefaultValueName == NULL) {
144 DefaultValueName = "DEFAULT";
145 }
146 for (Index = 0; Index < PcdListLength; Index++) {
147 if (strcmp(PcdList[Index].TokenSpaceGuidName, TokenSpaceGuidName) != 0) {
148 continue;
149 }
150 if (strcmp(PcdList[Index].TokenName, TokenName) != 0) {
151 continue;
152 }
153 if (strcmp(PcdList[Index].SkuName, SkuName) != 0) {
154 continue;
155 }
156 if (strcmp(PcdList[Index].DefaultValueName, DefaultValueName) != 0) {
157 continue;
158 }
159 return Index;
160 }
161 return -1;
162 }
163
164 UINT64
165 __PcdGet (
166 CHAR8 *SkuName OPTIONAL,
167 CHAR8 *DefaultValueName OPTIONAL,
168 CHAR8 *TokenSpaceGuidName,
169 CHAR8 *TokenName
170 )
171 /*++
172
173 Routine Description:
174
175 Get PCD value
176
177 Arguments:
178
179 SkuName SkuName String
180 DefaultValueName DefaultValueName String
181 TokenSpaceGuidName TokenSpaceGuidName String
182 TokenName TokenName String
183
184 Returns:
185
186 PCD value
187 --*/
188 {
189 int Index;
190 CHAR8 *End;
191
192 Index = LookupPcdIndex (SkuName, DefaultValueName, TokenSpaceGuidName, TokenName);
193 if (Index < 0) {
194 fprintf (stderr, "PCD %s.%s.%s.%s is not in database\n", SkuName, DefaultValueName, TokenSpaceGuidName, TokenName);
195 exit (EXIT_FAILURE);
196 }
197 switch (PcdList[Index].PcdDataType) {
198 case PcdDataTypeBoolean:
199 case PcdDataTypeUint8:
200 case PcdDataTypeUint16:
201 case PcdDataTypeUint32:
202 return (UINT64)strtoul(PcdList[Index].Value, &End, 16);
203 break;
204 case PcdDataTypeUint64:
205 return (UINT64)strtoul(PcdList[Index].Value, &End, 16);
206 break;
207 case PcdDataTypePointer:
208 fprintf (stderr, "PCD %s.%s.%s.%s is structure. Use PcdGetPtr()\n", SkuName, DefaultValueName, TokenSpaceGuidName, TokenName);
209 exit (EXIT_FAILURE);
210 break;
211 }
212 return 0;
213 }
214
215 VOID
216 __PcdSet (
217 CHAR8 *SkuName OPTIONAL,
218 CHAR8 *DefaultValueName OPTIONAL,
219 CHAR8 *TokenSpaceGuidName,
220 CHAR8 *TokenName,
221 UINT64 Value
222 )
223 /*++
224
225 Routine Description:
226
227 Set PCD value
228
229 Arguments:
230
231 SkuName SkuName String
232 DefaultValueName DefaultValueName String
233 TokenSpaceGuidName TokenSpaceGuidName String
234 TokenName TokenName String
235 Value PCD value to be set
236
237 Returns:
238
239 None
240 --*/
241 {
242 int Index;
243
244 Index = LookupPcdIndex (SkuName, DefaultValueName, TokenSpaceGuidName, TokenName);
245 if (Index < 0) {
246 fprintf (stderr, "PCD %s.%s.%s.%s is not in database\n", SkuName, DefaultValueName, TokenSpaceGuidName, TokenName);
247 exit (EXIT_FAILURE);
248 }
249 free(PcdList[Index].Value);
250 PcdList[Index].Value = malloc(20);
251 switch (PcdList[Index].PcdDataType) {
252 case PcdDataTypeBoolean:
253 if (Value == 0) {
254 strcpy (PcdList[Index].Value, "0x00");
255 } else {
256 strcpy (PcdList[Index].Value, "0x01");
257 }
258 break;
259 case PcdDataTypeUint8:
260 sprintf(PcdList[Index].Value, "0x%02x", (UINT8)(Value & 0xff));
261 break;
262 case PcdDataTypeUint16:
263 sprintf(PcdList[Index].Value, "0x%04x", (UINT16)(Value & 0xffff));
264 break;
265 case PcdDataTypeUint32:
266 sprintf(PcdList[Index].Value, "0x%08x", (UINT32)(Value & 0xffffffff));
267 break;
268 case PcdDataTypeUint64:
269 sprintf(PcdList[Index].Value, "0x%016llx", (unsigned long long)Value);
270 break;
271 case PcdDataTypePointer:
272 fprintf (stderr, "PCD %s.%s.%s.%s is structure. Use PcdSetPtr()\n", SkuName, DefaultValueName, TokenSpaceGuidName, TokenName);
273 exit (EXIT_FAILURE);
274 break;
275 }
276 }
277
278 VOID *
279 __PcdGetPtr (
280 CHAR8 *SkuName OPTIONAL,
281 CHAR8 *DefaultValueName OPTIONAL,
282 CHAR8 *TokenSpaceGuidName,
283 CHAR8 *TokenName,
284 UINT32 *Size
285 )
286 /*++
287
288 Routine Description:
289
290 Get PCD value buffer
291
292 Arguments:
293
294 SkuName SkuName String
295 DefaultValueName DefaultValueName String
296 TokenSpaceGuidName TokenSpaceGuidName String
297 TokenName TokenName String
298 Size Size of PCD value buffer
299
300 Returns:
301
302 PCD value buffer
303 --*/
304 {
305 int Index;
306 CHAR8 *Value;
307 UINT8 *Buffer;
308 CHAR8 *End;
309 UINT8 Byte;
310
311 Index = LookupPcdIndex (SkuName, DefaultValueName, TokenSpaceGuidName, TokenName);
312 if (Index < 0) {
313 fprintf (stderr, "PCD %s.%s.%s.%s is not in database\n", SkuName, DefaultValueName, TokenSpaceGuidName, TokenName);
314 exit (EXIT_FAILURE);
315 }
316 switch (PcdList[Index].PcdDataType) {
317 case PcdDataTypeBoolean:
318 case PcdDataTypeUint8:
319 case PcdDataTypeUint16:
320 case PcdDataTypeUint32:
321 case PcdDataTypeUint64:
322 fprintf (stderr, "PCD %s.%s.%s.%s is a value. Use PcdGet()\n", SkuName, DefaultValueName, TokenSpaceGuidName, TokenName);
323 exit (EXIT_FAILURE);
324 break;
325 case PcdDataTypePointer:
326 Value = &PcdList[Index].Value[1];
327 printf ("Value = %s\n", PcdList[Index].Value);
328 for (*Size = 0, Byte = (UINT8) strtoul(Value, &End, 16); Value != End; Byte = (UINT8) strtoul(Value, &End, 16), *Size = *Size + 1) {
329 printf("%x\n", Byte);
330 Value = End + 1;
331 }
332 Buffer = malloc(*Size);
333 Value = &PcdList[Index].Value[1];
334 for (*Size = 0, Buffer[*Size] = (UINT8) strtoul(Value, &End, 16); Value != End; *Size = *Size + 1, Buffer[*Size] = (UINT8) strtoul(Value, &End, 16)) {
335 Value = End + 1;
336 }
337 return Buffer;
338 }
339 *Size = 0;
340 return 0;
341 }
342
343 VOID
344 __PcdSetPtr (
345 CHAR8 *SkuName OPTIONAL,
346 CHAR8 *DefaultValueName OPTIONAL,
347 CHAR8 *TokenSpaceGuidName,
348 CHAR8 *TokenName,
349 UINT32 Size,
350 UINT8 *Value
351 )
352 /*++
353
354 Routine Description:
355
356 Set PCD value buffer
357
358 Arguments:
359
360 SkuName SkuName String
361 DefaultValueName DefaultValueName String
362 TokenSpaceGuidName TokenSpaceGuidName String
363 TokenName TokenName String
364 Size Size of PCD value
365 Value Pointer to the updated PCD value buffer
366
367 Returns:
368
369 None
370 --*/
371 {
372 int Index;
373 UINT32 ValueIndex;
374
375 Index = LookupPcdIndex (SkuName, DefaultValueName, TokenSpaceGuidName, TokenName);
376 if (Index < 0) {
377 fprintf (stderr, "PCD %s.%s.%s.%s is not in database\n", SkuName, DefaultValueName, TokenSpaceGuidName, TokenName);
378 exit (EXIT_FAILURE);
379 }
380 switch (PcdList[Index].PcdDataType) {
381 case PcdDataTypeBoolean:
382 case PcdDataTypeUint8:
383 case PcdDataTypeUint16:
384 case PcdDataTypeUint32:
385 case PcdDataTypeUint64:
386 fprintf (stderr, "PCD %s.%s.%s.%s is a value. Use PcdGet()\n", SkuName, DefaultValueName, TokenSpaceGuidName, TokenName);
387 exit (EXIT_FAILURE);
388 break;
389 case PcdDataTypePointer:
390 free(PcdList[Index].Value);
391 PcdList[Index].Value = malloc(Size * 5 + 3);
392 PcdList[Index].Value[0] = '{';
393 for (ValueIndex = 0; ValueIndex < Size; ValueIndex++) {
394 printf("Value[%d] = %02x\n", ValueIndex, Value[ValueIndex]);
395 sprintf(&PcdList[Index].Value[1 + ValueIndex * 5], "0x%02x,", Value[ValueIndex]);
396 }
397 PcdList[Index].Value[1 + Size * 5 - 1] = '}';
398 PcdList[Index].Value[1 + Size * 5 ] = 0;
399 break;
400 }
401 }
402
403 VOID
404 STATIC
405 ReadInputFile (
406 CHAR8 *InputFileName,
407 UINT8 **FileBuffer,
408 UINT32 *FileSize
409 )
410 /*++
411
412 Routine Description:
413
414 Read the file buffer from the input file.
415
416 Arguments:
417
418 InputFileName Point to the input file name.
419 FileBuffer Point to the input file buffer.
420 FileSize Size of the file buffer.
421
422 Returns:
423
424 None
425 --*/
426 {
427 FILE *InputFile;
428 UINT32 BytesRead;
429
430 //
431 // Open Input file and read file data.
432 //
433 InputFile = fopen (InputFileName, "rb");
434 if (InputFile == NULL) {
435 fprintf (stderr, "Error opening file %s\n", InputFileName);
436 exit (EXIT_FAILURE);
437 }
438
439 //
440 // Go to the end so that we can determine the file size
441 //
442 if (fseek (InputFile, 0, SEEK_END)) {
443 fprintf (stderr, "Error reading input file %s\n", InputFileName);
444 fclose (InputFile);
445 exit (EXIT_FAILURE);
446 }
447
448 //
449 // Get the file size
450 //
451 *FileSize = ftell (InputFile);
452 if (*FileSize == -1) {
453 fprintf (stderr, "Error parsing the input file %s\n", InputFileName);
454 fclose (InputFile);
455 exit (EXIT_FAILURE);
456 }
457
458 //
459 // Allocate a buffer
460 //
461 *FileBuffer = malloc (*FileSize);
462 if (*FileBuffer == NULL) {
463 fprintf (stderr, "Can not allocate buffer for input input file %s\n", InputFileName);
464 fclose (InputFile);
465 exit (EXIT_FAILURE);
466 }
467
468 //
469 // Reset to the beginning of the file
470 //
471 if (fseek (InputFile, 0, SEEK_SET)) {
472 fprintf (stderr, "Error reading the input file %s\n", InputFileName);
473 fclose (InputFile);
474 free (*FileBuffer);
475 exit (EXIT_FAILURE);
476 }
477
478 //
479 // Read all of the file contents.
480 //
481 BytesRead = fread (*FileBuffer, sizeof (UINT8), *FileSize, InputFile);
482 if (BytesRead != *FileSize * sizeof (UINT8)) {
483 fprintf (stderr, "Error reading the input file %s\n", InputFileName);
484 fclose (InputFile);
485 free (*FileBuffer);
486 exit (EXIT_FAILURE);
487 }
488
489 //
490 // Close the file
491 //
492 fclose (InputFile);
493 }
494
495 VOID
496 STATIC
497 ParseFile (
498 UINT8 *FileBuffer,
499 UINT32 FileSize
500 )
501 /*++
502
503 Routine Description:
504
505 Read the initial PCD value from the input file buffer.
506
507 Arguments:
508
509 FileBuffer Point to the input file buffer.
510 FileSize Size of the file buffer.
511
512 Returns:
513
514 None
515 --*/
516 {
517 UINT32 Index;
518 UINT32 NumLines;
519 UINT32 TokenIndex;
520 UINT32 TokenStart;
521
522 for (Index = 0, NumLines = 0; Index < FileSize; Index++) {
523 if (FileBuffer[Index] == '\n') {
524 NumLines++;
525 }
526 }
527 PcdList = malloc((NumLines + 1) * sizeof(PcdList[0]));
528
529 for (Index = 0, TokenIndex = 0, PcdListLength = 0, TokenStart = 0; Index < FileSize; Index++) {
530 if (FileBuffer[Index] == ' ') {
531 continue;
532 }
533 if (FileBuffer[Index] == '|' || FileBuffer[Index] == '.' || FileBuffer[Index] == '\n' || FileBuffer[Index] == '\r') {
534 RecordToken (FileBuffer, PcdListLength, TokenIndex, TokenStart, Index);
535 if (FileBuffer[Index] == '\n' || FileBuffer[Index] == '\r') {
536 if (TokenIndex != 0) {
537 PcdListLength++;
538 TokenIndex = 0;
539 }
540 } else {
541 TokenIndex++;
542 }
543 TokenStart = Index + 1;
544 continue;
545 }
546 }
547 if (Index > TokenStart) {
548 RecordToken (FileBuffer, PcdListLength, TokenIndex, TokenStart, Index);
549 if (TokenIndex != 0) {
550 PcdListLength++;
551 }
552 }
553 }
554
555 VOID
556 STATIC
557 WriteOutputFile (
558 CHAR8 *OutputFileName
559 )
560 /*++
561
562 Routine Description:
563
564 Write the updated PCD value into the output file name.
565
566 Arguments:
567
568 OutputFileName Point to the output file name.
569
570 Returns:
571
572 None
573 --*/
574 {
575 FILE *OutputFile;
576 UINT32 Index;
577
578 //
579 // Open output file
580 //
581 OutputFile = fopen (OutputFileName, "wb");
582 if (OutputFile == NULL) {
583 fprintf (stderr, "Error opening file %s\n", OutputFileName);
584 exit (EXIT_FAILURE);
585 }
586
587 for (Index = 0; Index < PcdListLength; Index++) {
588 fprintf (
589 OutputFile,
590 "%s.%s.%s.%s|%s|%s\n",
591 PcdList[Index].SkuName,
592 PcdList[Index].DefaultValueName,
593 PcdList[Index].TokenSpaceGuidName,
594 PcdList[Index].TokenName,
595 PcdList[Index].DataType,
596 PcdList[Index].Value
597 );
598 }
599
600 //
601 // Done, write output file.
602 //
603 if (OutputFile != NULL) {
604 fclose (OutputFile);
605 }
606 }
607
608 VOID
609 STATIC
610 Usage (
611 VOID
612 )
613 /*++
614
615 Routine Description:
616
617 Displays the utility usage syntax to STDOUT
618
619 Arguments:
620
621 None
622
623 Returns:
624
625 None
626
627 --*/
628 {
629 fprintf (stdout, "Usage: -i <input_file> -o <output_file>\n\n");
630 fprintf (stdout, "optional arguments:\n");
631 fprintf (stdout, " -h, --help Show this help message and exit\n");
632 fprintf (stdout, " -i INPUT_FILENAME, --input INPUT_FILENAME\n\
633 PCD Database Input file name\n");
634 fprintf (stdout, " -o OUTPUT_FILENAME, --output OUTPUT_FILENAME\n\
635 PCD Database Output file name\n");
636 }
637
638 VOID
639 STATIC
640 ParseArguments (
641 int argc,
642 char *argv[],
643 CHAR8 **InputFileName,
644 CHAR8 **OutputFileName
645 )
646 /*++
647
648 Routine Description:
649
650 Parse the input parameters to get the input/output file name.
651
652 Arguments:
653
654 argc Number of command line parameters.
655 argv Array of pointers to parameter strings.
656 InputFileName Point to the input file name.
657 OutputFileName Point to the output file name.
658
659 Returns:
660
661 None
662 --*/
663 {
664 if (argc == 1) {
665 fprintf (stderr, "Missing options\n");
666 exit (EXIT_FAILURE);
667 }
668
669 //
670 // Parse command line
671 //
672 argc--;
673 argv++;
674
675 if ((stricmp (argv[0], "-h") == 0) || (stricmp (argv[0], "--help") == 0)) {
676 Usage ();
677 exit (EXIT_SUCCESS);
678 }
679
680 while (argc > 0) {
681 if ((stricmp (argv[0], "-i") == 0) || (stricmp (argv[0], "--input") == 0)) {
682 if (argv[1] == NULL || argv[1][0] == '-') {
683 fprintf (stderr, "Invalid option value. Input File name is missing for -i option\n");
684 exit (EXIT_FAILURE);
685 }
686 *InputFileName = argv[1];
687 argc -= 2;
688 argv += 2;
689 continue;
690 }
691
692 if ((stricmp (argv[0], "-o") == 0) || (stricmp (argv[0], "--output") == 0)) {
693 if (argv[1] == NULL || argv[1][0] == '-') {
694 fprintf (stderr, "Invalid option value. Output File name is missing for -i option\n");
695 exit (EXIT_FAILURE);
696 }
697 *OutputFileName = argv[1];
698 argc -= 2;
699 argv += 2;
700 continue;
701 }
702
703 if (argv[0][0] == '-') {
704 fprintf (stderr, "Unknown option %s\n", argv[0]);
705 exit (EXIT_FAILURE);
706 }
707 argc --;
708 argv ++;
709 }
710
711 //
712 // Check Input paramters
713 //
714 if (*InputFileName == NULL) {
715 fprintf (stderr, "Missing option. Input files is not specified\n");
716 exit (EXIT_FAILURE);
717 } else {
718 printf ("Input file name is %s\n", *InputFileName);
719 }
720
721 if (*OutputFileName == NULL) {
722 fprintf (stderr, "Missing option. Output file is not specified\n");
723 exit (EXIT_FAILURE);
724 } else {
725 printf ("Output file name is %s\n", *OutputFileName);
726 }
727 }
728
729 int
730 PcdValueMain (
731 int argc,
732 char *argv[]
733 )
734 /*++
735
736 Routine Description:
737
738 Main function updates PCD values.
739
740 Arguments:
741
742 argc Number of command line parameters.
743 argv Array of pointers to parameter strings.
744
745 Returns:
746 EXIT_SUCCESS
747 --*/
748 {
749 CHAR8 *InputFileName;
750 CHAR8 *OutputFileName;
751 UINT8 *FileBuffer;
752 UINT32 FileSize;
753
754 printf ("PCD tool start.\n");
755 InputFileName = NULL;
756 OutputFileName = NULL;
757
758 //
759 // Parse the input arguments
760 //
761 ParseArguments (argc, argv, &InputFileName, &OutputFileName);
762
763 //
764 // Open Input file and read file data.
765 //
766 ReadInputFile (InputFileName, &FileBuffer, &FileSize);
767
768 //
769 // Read the initial Pcd value
770 //
771 ParseFile (FileBuffer, FileSize);
772
773 //
774 // Customize PCD values in the PCD Database
775 //
776 PcdEntryPoint ();
777
778 //
779 // Save the updated PCD value
780 //
781 WriteOutputFile (OutputFileName);
782
783 printf ("PCD tool done.\n");
784
785 exit (EXIT_SUCCESS);
786 }