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