3 Copyright (c) 2004, Intel Corporation
4 All rights reserved. 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
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.
18 This contains some useful functions for parsing INF files.
29 IN MEMORY_FILE
*InputFile
,
30 IN OUT CHAR8
*InputBuffer
,
37 This function reads a line, stripping any comments.
38 The function reads a string from the input stream argument and stores it in
39 the input string. ReadLine reads characters from the current file position
40 to and including the first newline character, to the end of the stream, or
41 until the number of characters read is equal to MaxLength - 1, whichever
42 comes first. The newline character, if read, is replaced with a \0.
46 InputFile Memory file image.
47 InputBuffer Buffer to read into, must be _MAX_PATH size.
48 MaxLength The maximum size of the input buffer.
62 // Verify input parameters are not null
65 assert (InputFile
->FileImage
);
66 assert (InputFile
->Eof
);
67 assert (InputFile
->CurrentFilePointer
);
70 // Check for end of file condition
72 if (InputFile
->CurrentFilePointer
>= InputFile
->Eof
) {
76 // Find the next newline char
78 EndOfLine
= strchr (InputFile
->CurrentFilePointer
, '\n');
81 // Determine the number of characters to copy.
85 // If no newline found, copy to the end of the file.
87 CharsToCopy
= InputFile
->Eof
- InputFile
->CurrentFilePointer
;
88 } else if (EndOfLine
>= InputFile
->Eof
) {
90 // If the newline found was beyond the end of file, copy to the eof.
92 CharsToCopy
= InputFile
->Eof
- InputFile
->CurrentFilePointer
;
95 // Newline found in the file.
97 CharsToCopy
= EndOfLine
- InputFile
->CurrentFilePointer
;
100 // If the end of line is too big for the current buffer, set it to the max
101 // size of the buffer (leaving room for the \0.
103 if (CharsToCopy
> MaxLength
- 1) {
104 CharsToCopy
= MaxLength
- 1;
109 memcpy (InputBuffer
, InputFile
->CurrentFilePointer
, CharsToCopy
);
112 // Add the null termination over the 0x0D
114 InputBuffer
[CharsToCopy
- 1] = '\0';
117 // Increment the current file pointer (include the 0x0A)
119 InputFile
->CurrentFilePointer
+= CharsToCopy
+ 1;
122 // Strip any comments
124 CharPtr
= strstr (InputBuffer
, "//");
136 IN MEMORY_FILE
*InputFile
,
143 This function parses a file from the beginning to find a section.
144 The section string may be anywhere within a line.
148 InputFile Memory file image.
149 Section Section to search for
153 FALSE if error or EOF
154 TRUE if section found
158 CHAR8 InputBuffer
[_MAX_PATH
];
162 // Verify input is not NULL
164 assert (InputFile
->FileImage
);
165 assert (InputFile
->Eof
);
166 assert (InputFile
->CurrentFilePointer
);
170 // Rewind to beginning of file
172 InputFile
->CurrentFilePointer
= InputFile
->FileImage
;
175 // Read lines until the section is found
177 while (InputFile
->CurrentFilePointer
< InputFile
->Eof
) {
181 ReadLine (InputFile
, InputBuffer
, _MAX_PATH
);
184 // Check if the section is found
186 CurrentToken
= strstr (InputBuffer
, Section
);
187 if (CurrentToken
!= NULL
) {
197 IN MEMORY_FILE
*InputFile
,
207 Finds a token value given the section and token to search for.
211 InputFile Memory file image.
212 Section The section to search for, a string within [].
213 Token The token to search for, e.g. EFI_PEIM_RECOVERY, followed by an = in the INF file.
214 Instance The instance of the token to search for. Zero is the first instance.
215 Value The string that holds the value following the =. Must be _MAX_PATH in size.
219 EFI_SUCCESS Value found.
220 EFI_ABORTED Format error detected in INF file.
221 EFI_INVALID_PARAMETER Input argument was null.
222 EFI_LOAD_ERROR Error reading from the file.
223 EFI_NOT_FOUND Section/Token/Value not found.
227 CHAR8 InputBuffer
[_MAX_PATH
];
234 // Check input parameters
236 if (InputFile
->FileImage
== NULL
||
237 InputFile
->Eof
== NULL
||
238 InputFile
->CurrentFilePointer
== NULL
||
240 strlen (Section
) == 0 ||
242 strlen (Token
) == 0 ||
245 return EFI_INVALID_PARAMETER
;
248 // Initialize error codes
254 // Initialize our instance counter for the search token
258 if (FindSection (InputFile
, Section
)) {
260 // Found the desired section, find and read the desired token
264 // Read a line from the file
266 if (ReadLine (InputFile
, InputBuffer
, _MAX_PATH
) == NULL
) {
268 // Error reading from input file
274 // Get the first non-whitespace string
276 CurrentToken
= strtok (InputBuffer
, " \t\n");
277 if (CurrentToken
== NULL
) {
279 // Whitespace line found (or comment) so continue
281 CurrentToken
= InputBuffer
;
285 // Make sure we have not reached the end of the current section
287 if (CurrentToken
[0] == '[') {
291 // Compare the current token with the desired token
293 if (strcmp (CurrentToken
, Token
) == 0) {
298 // Check if it is the correct instance
300 if (Instance
== Occurrance
) {
302 // Copy the contents following the =
304 CurrentToken
= strtok (NULL
, "= \t\n");
305 if (CurrentToken
== NULL
) {
307 // Nothing found, parsing error
312 // Copy the current token to the output value
314 strcpy (Value
, CurrentToken
);
319 // Increment the occurrance found
327 InputFile
->CurrentFilePointer
< InputFile
->Eof
&&
328 CurrentToken
[0] != '[' &&
329 Occurrance
<= Instance
333 // Distinguish between read errors and INF file format errors.
336 return EFI_LOAD_ERROR
;
343 return EFI_NOT_FOUND
;
348 IN CHAR8
*AsciiGuidBuffer
,
349 OUT EFI_GUID
*GuidBuffer
355 Converts a string to an EFI_GUID. The string must be in the
356 xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx format.
360 AsciiGuidBuffer - pointer to ascii string
361 GuidBuffer - pointer to destination Guid
365 EFI_ABORTED Could not convert the string
366 EFI_SUCCESS The string was successfully converted
367 EFI_INVALID_PARAMETER Input parameter is invalid.
377 if (AsciiGuidBuffer
== NULL
|| GuidBuffer
== NULL
) {
378 return EFI_INVALID_PARAMETER
;
381 // Scan the guid string into the buffer
385 "%08x-%04x-%04x-%02x%02x-%02hx%02hx%02hx%02hx%02hx%02hx",
400 // Verify the correct number of items were scanned.
403 printf ("ERROR: Malformed GUID \"%s\".\n\n", AsciiGuidBuffer
);
407 // Copy the data into our GUID.
409 GuidBuffer
->Data1
= (UINT32
) Data1
;
410 GuidBuffer
->Data2
= (UINT16
) Data2
;
411 GuidBuffer
->Data3
= (UINT16
) Data3
;
412 GuidBuffer
->Data4
[0] = (UINT8
) Data4
[0];
413 GuidBuffer
->Data4
[1] = (UINT8
) Data4
[1];
414 GuidBuffer
->Data4
[2] = (UINT8
) Data4
[2];
415 GuidBuffer
->Data4
[3] = (UINT8
) Data4
[3];
416 GuidBuffer
->Data4
[4] = (UINT8
) Data4
[4];
417 GuidBuffer
->Data4
[5] = (UINT8
) Data4
[5];
418 GuidBuffer
->Data4
[6] = (UINT8
) Data4
[6];
419 GuidBuffer
->Data4
[7] = (UINT8
) Data4
[7];
425 AsciiStringToUint64 (
426 IN CONST CHAR8
*AsciiString
,
428 OUT UINT64
*ReturnValue
434 Converts a null terminated ascii string that represents a number into a
435 UINT64 value. A hex number may be preceeded by a 0x, but may not be
436 succeeded by an h. A number without 0x or 0X is considered to be base 10
437 unless the IsHex input is true.
441 AsciiString The string to convert.
442 IsHex Force the string to be treated as a hex number.
443 ReturnValue The return value.
447 EFI_SUCCESS Number successfully converted.
448 EFI_ABORTED Invalid character encountered.
457 // Initialize the result
462 // Add each character to the result
464 if (IsHex
|| (AsciiString
[0] == '0' && (AsciiString
[1] == 'x' || AsciiString
[1] == 'X'))) {
466 // Verify string is a hex number
468 for (Index
= 2; Index
< strlen (AsciiString
); Index
++) {
469 if (isxdigit (AsciiString
[Index
]) == 0) {
474 // Convert the hex string.
476 for (Index
= 2; AsciiString
[Index
] != '\0'; Index
++) {
477 CurrentChar
= AsciiString
[Index
];
479 if (CurrentChar
>= '0' && CurrentChar
<= '9') {
480 HexNumber
+= CurrentChar
- '0';
481 } else if (CurrentChar
>= 'a' && CurrentChar
<= 'f') {
482 HexNumber
+= CurrentChar
- 'a' + 10;
483 } else if (CurrentChar
>= 'A' && CurrentChar
<= 'F') {
484 HexNumber
+= CurrentChar
- 'A' + 10;
487 // Unrecognized character
493 *ReturnValue
= HexNumber
;
496 // Verify string is a number
498 for (Index
= 0; Index
< strlen (AsciiString
); Index
++) {
499 if (isdigit (AsciiString
[Index
]) == 0) {
504 *ReturnValue
= atol (AsciiString
);
513 IN OUT CHAR8
*InputBuffer
519 This function reads a line, stripping any comments.
520 // BUGBUG: This is obsolete once genmake goes away...
524 InputFile Stream pointer.
525 InputBuffer Buffer to read into, must be _MAX_PATH size.
530 InputBuffer otherwise
537 // Verify input parameters are not null
540 assert (InputBuffer
);
545 if (fgets (InputBuffer
, _MAX_PATH
, InputFile
) == NULL
) {
549 // Strip any comments
551 CharPtr
= strstr (InputBuffer
, "//");
556 CharPtr
= strstr (InputBuffer
, "#");
567 FindSectionInStream (
575 This function parses a stream file from the beginning to find a section.
576 The section string may be anywhere within a line.
577 // BUGBUG: This is obsolete once genmake goes away...
581 InputFile Stream pointer.
582 Section Section to search for
586 FALSE if error or EOF
587 TRUE if section found
591 CHAR8 InputBuffer
[_MAX_PATH
];
595 // Verify input is not NULL
601 // Rewind to beginning of file
603 if (fseek (InputFile
, 0, SEEK_SET
) != 0) {
607 // Read lines until the section is found
609 while (feof (InputFile
) == 0) {
613 ReadLineInStream (InputFile
, InputBuffer
);
616 // Check if the section is found
618 CurrentToken
= strstr (InputBuffer
, Section
);
619 if (CurrentToken
!= NULL
) {