]>
git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Source/C/Common/ParseInf.c
2 This contains some useful functions for parsing INF files.
4 Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
19 #include "EfiUtilityMsgs.h"
21 #include "CommonLib.h"
25 IN MEMORY_FILE
*InputFile
,
26 IN OUT CHAR8
*InputBuffer
,
33 This function reads a line, stripping any comments.
34 The function reads a string from the input stream argument and stores it in
35 the input string. ReadLine reads characters from the current file position
36 to and including the first newline character, to the end of the stream, or
37 until the number of characters read is equal to MaxLength - 1, whichever
38 comes first. The newline character, if read, is replaced with a \0.
42 InputFile Memory file image.
43 InputBuffer Buffer to read into, must be MaxLength size.
44 MaxLength The maximum size of the input buffer.
58 // Verify input parameters are not null
61 assert (InputFile
->FileImage
);
62 assert (InputFile
->Eof
);
63 assert (InputFile
->CurrentFilePointer
);
66 // Check for end of file condition
68 if (InputFile
->CurrentFilePointer
>= InputFile
->Eof
) {
72 // Find the next newline char
74 EndOfLine
= strchr (InputFile
->CurrentFilePointer
, '\n');
77 // Determine the number of characters to copy.
81 // If no newline found, copy to the end of the file.
83 CharsToCopy
= InputFile
->Eof
- InputFile
->CurrentFilePointer
;
84 } else if (EndOfLine
>= InputFile
->Eof
) {
86 // If the newline found was beyond the end of file, copy to the eof.
88 CharsToCopy
= InputFile
->Eof
- InputFile
->CurrentFilePointer
;
91 // Newline found in the file.
93 CharsToCopy
= EndOfLine
- InputFile
->CurrentFilePointer
;
96 // If the end of line is too big for the current buffer, set it to the max
97 // size of the buffer (leaving room for the \0.
99 if (CharsToCopy
> MaxLength
- 1) {
100 CharsToCopy
= MaxLength
- 1;
105 memcpy (InputBuffer
, InputFile
->CurrentFilePointer
, CharsToCopy
);
108 // Add the null termination over the 0x0D
110 if (InputBuffer
[CharsToCopy
- 1] == '\r') {
112 InputBuffer
[CharsToCopy
- 1] = '\0';
116 InputBuffer
[CharsToCopy
] = '\0';
121 // Increment the current file pointer (include the 0x0A)
123 InputFile
->CurrentFilePointer
+= CharsToCopy
+ 1;
126 // Strip any comments
128 CharPtr
= strstr (InputBuffer
, "//");
140 IN MEMORY_FILE
*InputFile
,
147 This function parses a file from the beginning to find a section.
148 The section string may be anywhere within a line.
152 InputFile Memory file image.
153 Section Section to search for
157 FALSE if error or EOF
158 TRUE if section found
162 CHAR8 InputBuffer
[MAX_LONG_FILE_PATH
];
166 // Verify input is not NULL
168 assert (InputFile
->FileImage
);
169 assert (InputFile
->Eof
);
170 assert (InputFile
->CurrentFilePointer
);
174 // Rewind to beginning of file
176 InputFile
->CurrentFilePointer
= InputFile
->FileImage
;
179 // Read lines until the section is found
181 while (InputFile
->CurrentFilePointer
< InputFile
->Eof
) {
185 ReadLine (InputFile
, InputBuffer
, MAX_LONG_FILE_PATH
);
188 // Check if the section is found
190 CurrentToken
= strstr (InputBuffer
, Section
);
191 if (CurrentToken
!= NULL
) {
201 IN MEMORY_FILE
*InputFile
,
211 Finds a token value given the section and token to search for.
215 InputFile Memory file image.
216 Section The section to search for, a string within [].
217 Token The token to search for, e.g. EFI_PEIM_RECOVERY, followed by an = in the INF file.
218 Instance The instance of the token to search for. Zero is the first instance.
219 Value The string that holds the value following the =. Must be MAX_LONG_FILE_PATH in size.
223 EFI_SUCCESS Value found.
224 EFI_ABORTED Format error detected in INF file.
225 EFI_INVALID_PARAMETER Input argument was null.
226 EFI_LOAD_ERROR Error reading from the file.
227 EFI_NOT_FOUND Section/Token/Value not found.
231 CHAR8 InputBuffer
[MAX_LONG_FILE_PATH
];
239 // Check input parameters
241 if (InputFile
->FileImage
== NULL
||
242 InputFile
->Eof
== NULL
||
243 InputFile
->CurrentFilePointer
== NULL
||
245 strlen (Section
) == 0 ||
247 strlen (Token
) == 0 ||
250 return EFI_INVALID_PARAMETER
;
253 // Initialize error codes
259 // Initialize our instance counter for the search token
263 if (FindSection (InputFile
, Section
)) {
265 // Found the desired section, find and read the desired token
269 // Read a line from the file
271 if (ReadLine (InputFile
, InputBuffer
, MAX_LONG_FILE_PATH
) == NULL
) {
273 // Error reading from input file
279 // Get the first non-whitespace string
281 Delimiter
= strchr (InputBuffer
, '=');
282 if (Delimiter
!= NULL
) {
286 CurrentToken
= strtok (InputBuffer
, " \t\n");
287 if (CurrentToken
== NULL
|| Delimiter
== NULL
) {
289 // Whitespace line found (or comment) so continue
291 CurrentToken
= InputBuffer
;
295 // Make sure we have not reached the end of the current section
297 if (CurrentToken
[0] == '[') {
301 // Compare the current token with the desired token
303 if (strcmp (CurrentToken
, Token
) == 0) {
308 // Check if it is the correct instance
310 if (Instance
== Occurrance
) {
312 // Copy the contents following the =
314 CurrentToken
= Delimiter
+ 1;
315 if (*CurrentToken
== 0) {
317 // Nothing found, parsing error
322 // Strip leading white space
324 while (*CurrentToken
== ' ' || *CurrentToken
== '\t') {
328 // Copy the current token to the output value
330 strcpy (Value
, CurrentToken
);
332 // Strip trailing white space
334 while (strlen(Value
) > 0 && (*(Value
+ strlen(Value
) - 1) == ' ' || *(Value
+ strlen(Value
) - 1) == '\t')) {
335 *(Value
+ strlen(Value
) - 1) = 0;
341 // Increment the occurrance found
349 InputFile
->CurrentFilePointer
< InputFile
->Eof
&&
350 CurrentToken
[0] != '[' &&
351 Occurrance
<= Instance
355 // Distinguish between read errors and INF file format errors.
358 return EFI_LOAD_ERROR
;
365 return EFI_NOT_FOUND
;
370 IN CHAR8
*AsciiGuidBuffer
,
371 OUT EFI_GUID
*GuidBuffer
377 Converts a string to an EFI_GUID. The string must be in the
378 xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx format.
382 AsciiGuidBuffer - pointer to ascii string
383 GuidBuffer - pointer to destination Guid
387 EFI_ABORTED Could not convert the string
388 EFI_SUCCESS The string was successfully converted
389 EFI_INVALID_PARAMETER Input parameter is invalid.
399 if (AsciiGuidBuffer
== NULL
|| GuidBuffer
== NULL
) {
400 return EFI_INVALID_PARAMETER
;
403 // Check Guid Format strictly xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
405 for (Index
= 0; AsciiGuidBuffer
[Index
] != '\0' && Index
< 37; Index
++) {
406 if (Index
== 8 || Index
== 13 || Index
== 18 || Index
== 23) {
407 if (AsciiGuidBuffer
[Index
] != '-') {
411 if (((AsciiGuidBuffer
[Index
] >= '0') && (AsciiGuidBuffer
[Index
] <= '9')) ||
412 ((AsciiGuidBuffer
[Index
] >= 'a') && (AsciiGuidBuffer
[Index
] <= 'f')) ||
413 ((AsciiGuidBuffer
[Index
] >= 'A') && (AsciiGuidBuffer
[Index
] <= 'F'))) {
421 if (Index
< 36 || AsciiGuidBuffer
[36] != '\0') {
422 Error (NULL
, 0, 1003, "Invalid option value", "Incorrect GUID \"%s\"\n Correct Format \"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\"", AsciiGuidBuffer
);
427 // Scan the guid string into the buffer
431 "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
446 // Verify the correct number of items were scanned.
449 Error (NULL
, 0, 1003, "Invalid option value", "Incorrect GUID \"%s\"\n Correct Format \"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\"", AsciiGuidBuffer
);
453 // Copy the data into our GUID.
455 GuidBuffer
->Data1
= (UINT32
) Data1
;
456 GuidBuffer
->Data2
= (UINT16
) Data2
;
457 GuidBuffer
->Data3
= (UINT16
) Data3
;
458 GuidBuffer
->Data4
[0] = (UINT8
) Data4
[0];
459 GuidBuffer
->Data4
[1] = (UINT8
) Data4
[1];
460 GuidBuffer
->Data4
[2] = (UINT8
) Data4
[2];
461 GuidBuffer
->Data4
[3] = (UINT8
) Data4
[3];
462 GuidBuffer
->Data4
[4] = (UINT8
) Data4
[4];
463 GuidBuffer
->Data4
[5] = (UINT8
) Data4
[5];
464 GuidBuffer
->Data4
[6] = (UINT8
) Data4
[6];
465 GuidBuffer
->Data4
[7] = (UINT8
) Data4
[7];
471 AsciiStringToUint64 (
472 IN CONST CHAR8
*AsciiString
,
474 OUT UINT64
*ReturnValue
480 Converts a null terminated ascii string that represents a number into a
481 UINT64 value. A hex number may be preceeded by a 0x, but may not be
482 succeeded by an h. A number without 0x or 0X is considered to be base 10
483 unless the IsHex input is true.
487 AsciiString The string to convert.
488 IsHex Force the string to be treated as a hex number.
489 ReturnValue The return value.
493 EFI_SUCCESS Number successfully converted.
494 EFI_ABORTED Invalid character encountered.
503 // Initialize the result
509 // Check input paramter
511 if (AsciiString
== NULL
|| ReturnValue
== NULL
) {
512 return EFI_INVALID_PARAMETER
;
514 while (AsciiString
[Index
] == ' ') {
519 // Add each character to the result
523 // Skip first two chars only if the string starts with '0x' or '0X'
525 if (AsciiString
[Index
] == '0' && (AsciiString
[Index
+ 1] == 'x' || AsciiString
[Index
+ 1] == 'X')) {
531 // Convert the hex string.
533 for (; AsciiString
[Index
] != '\0'; Index
++) {
534 CurrentChar
= AsciiString
[Index
];
535 if (CurrentChar
== ' ') {
541 if (isxdigit ((int)CurrentChar
) == 0) {
548 if (CurrentChar
>= '0' && CurrentChar
<= '9') {
549 Value
+= CurrentChar
- '0';
550 } else if (CurrentChar
>= 'a' && CurrentChar
<= 'f') {
551 Value
+= CurrentChar
- 'a' + 10;
552 } else if (CurrentChar
>= 'A' && CurrentChar
<= 'F') {
553 Value
+= CurrentChar
- 'A' + 10;
557 *ReturnValue
= Value
;
560 // Convert dec string is a number
562 for (; Index
< strlen (AsciiString
); Index
++) {
563 CurrentChar
= AsciiString
[Index
];
564 if (CurrentChar
== ' ') {
570 if (isdigit ((int)CurrentChar
) == 0) {
577 Value
+= CurrentChar
- '0';
580 *ReturnValue
= Value
;
589 IN OUT CHAR8
*InputBuffer
595 This function reads a line, stripping any comments.
596 // BUGBUG: This is obsolete once genmake goes away...
600 InputFile Stream pointer.
601 InputBuffer Buffer to read into, must be MAX_LONG_FILE_PATH size.
606 InputBuffer otherwise
613 // Verify input parameters are not null
616 assert (InputBuffer
);
621 if (fgets (InputBuffer
, MAX_LONG_FILE_PATH
, InputFile
) == NULL
) {
625 // Strip any comments
627 CharPtr
= strstr (InputBuffer
, "//");
632 CharPtr
= strstr (InputBuffer
, "#");
643 FindSectionInStream (
651 This function parses a stream file from the beginning to find a section.
652 The section string may be anywhere within a line.
653 // BUGBUG: This is obsolete once genmake goes away...
657 InputFile Stream pointer.
658 Section Section to search for
662 FALSE if error or EOF
663 TRUE if section found
667 CHAR8 InputBuffer
[MAX_LONG_FILE_PATH
];
671 // Verify input is not NULL
677 // Rewind to beginning of file
679 if (fseek (InputFile
, 0, SEEK_SET
) != 0) {
683 // Read lines until the section is found
685 while (feof (InputFile
) == 0) {
689 ReadLineInStream (InputFile
, InputBuffer
);
692 // Check if the section is found
694 CurrentToken
= strstr (InputBuffer
, Section
);
695 if (CurrentToken
!= NULL
) {