]>
git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Source/C/Common/ParseInf.c
00ae0e65a10b8aee9fa193689e79dc3c4c746558
3 Copyright (c) 2004 - 2014, 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
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.
26 #include "EfiUtilityMsgs.h"
28 #include "CommonLib.h"
32 IN MEMORY_FILE
*InputFile
,
33 IN OUT CHAR8
*InputBuffer
,
40 This function reads a line, stripping any comments.
41 The function reads a string from the input stream argument and stores it in
42 the input string. ReadLine reads characters from the current file position
43 to and including the first newline character, to the end of the stream, or
44 until the number of characters read is equal to MaxLength - 1, whichever
45 comes first. The newline character, if read, is replaced with a \0.
49 InputFile Memory file image.
50 InputBuffer Buffer to read into, must be MaxLength size.
51 MaxLength The maximum size of the input buffer.
65 // Verify input parameters are not null
68 assert (InputFile
->FileImage
);
69 assert (InputFile
->Eof
);
70 assert (InputFile
->CurrentFilePointer
);
73 // Check for end of file condition
75 if (InputFile
->CurrentFilePointer
>= InputFile
->Eof
) {
79 // Find the next newline char
81 EndOfLine
= strchr (InputFile
->CurrentFilePointer
, '\n');
84 // Determine the number of characters to copy.
88 // If no newline found, copy to the end of the file.
90 CharsToCopy
= InputFile
->Eof
- InputFile
->CurrentFilePointer
;
91 } else if (EndOfLine
>= InputFile
->Eof
) {
93 // If the newline found was beyond the end of file, copy to the eof.
95 CharsToCopy
= InputFile
->Eof
- InputFile
->CurrentFilePointer
;
98 // Newline found in the file.
100 CharsToCopy
= EndOfLine
- InputFile
->CurrentFilePointer
;
103 // If the end of line is too big for the current buffer, set it to the max
104 // size of the buffer (leaving room for the \0.
106 if (CharsToCopy
> MaxLength
- 1) {
107 CharsToCopy
= MaxLength
- 1;
112 memcpy (InputBuffer
, InputFile
->CurrentFilePointer
, CharsToCopy
);
115 // Add the null termination over the 0x0D
117 if (InputBuffer
[CharsToCopy
- 1] == '\r') {
119 InputBuffer
[CharsToCopy
- 1] = '\0';
123 InputBuffer
[CharsToCopy
] = '\0';
128 // Increment the current file pointer (include the 0x0A)
130 InputFile
->CurrentFilePointer
+= CharsToCopy
+ 1;
133 // Strip any comments
135 CharPtr
= strstr (InputBuffer
, "//");
147 IN MEMORY_FILE
*InputFile
,
154 This function parses a file from the beginning to find a section.
155 The section string may be anywhere within a line.
159 InputFile Memory file image.
160 Section Section to search for
164 FALSE if error or EOF
165 TRUE if section found
169 CHAR8 InputBuffer
[MAX_LONG_FILE_PATH
];
173 // Verify input is not NULL
175 assert (InputFile
->FileImage
);
176 assert (InputFile
->Eof
);
177 assert (InputFile
->CurrentFilePointer
);
181 // Rewind to beginning of file
183 InputFile
->CurrentFilePointer
= InputFile
->FileImage
;
186 // Read lines until the section is found
188 while (InputFile
->CurrentFilePointer
< InputFile
->Eof
) {
192 ReadLine (InputFile
, InputBuffer
, MAX_LONG_FILE_PATH
);
195 // Check if the section is found
197 CurrentToken
= strstr (InputBuffer
, Section
);
198 if (CurrentToken
!= NULL
) {
208 IN MEMORY_FILE
*InputFile
,
218 Finds a token value given the section and token to search for.
222 InputFile Memory file image.
223 Section The section to search for, a string within [].
224 Token The token to search for, e.g. EFI_PEIM_RECOVERY, followed by an = in the INF file.
225 Instance The instance of the token to search for. Zero is the first instance.
226 Value The string that holds the value following the =. Must be MAX_LONG_FILE_PATH in size.
230 EFI_SUCCESS Value found.
231 EFI_ABORTED Format error detected in INF file.
232 EFI_INVALID_PARAMETER Input argument was null.
233 EFI_LOAD_ERROR Error reading from the file.
234 EFI_NOT_FOUND Section/Token/Value not found.
238 CHAR8 InputBuffer
[MAX_LONG_FILE_PATH
];
246 // Check input parameters
248 if (InputFile
->FileImage
== NULL
||
249 InputFile
->Eof
== NULL
||
250 InputFile
->CurrentFilePointer
== NULL
||
252 strlen (Section
) == 0 ||
254 strlen (Token
) == 0 ||
257 return EFI_INVALID_PARAMETER
;
260 // Initialize error codes
266 // Initialize our instance counter for the search token
270 if (FindSection (InputFile
, Section
)) {
272 // Found the desired section, find and read the desired token
276 // Read a line from the file
278 if (ReadLine (InputFile
, InputBuffer
, MAX_LONG_FILE_PATH
) == NULL
) {
280 // Error reading from input file
286 // Get the first non-whitespace string
288 Delimiter
= strchr (InputBuffer
, '=');
289 if (Delimiter
!= NULL
) {
293 CurrentToken
= strtok (InputBuffer
, " \t\n");
294 if (CurrentToken
== NULL
|| Delimiter
== NULL
) {
296 // Whitespace line found (or comment) so continue
298 CurrentToken
= InputBuffer
;
302 // Make sure we have not reached the end of the current section
304 if (CurrentToken
[0] == '[') {
308 // Compare the current token with the desired token
310 if (strcmp (CurrentToken
, Token
) == 0) {
315 // Check if it is the correct instance
317 if (Instance
== Occurrance
) {
319 // Copy the contents following the =
321 CurrentToken
= Delimiter
+ 1;
322 if (*CurrentToken
== 0) {
324 // Nothing found, parsing error
329 // Strip leading white space
331 while (*CurrentToken
== ' ' || *CurrentToken
== '\t') {
335 // Copy the current token to the output value
337 strcpy (Value
, CurrentToken
);
339 // Strip trailing white space
341 while (strlen(Value
) > 0 && (*(Value
+ strlen(Value
) - 1) == ' ' || *(Value
+ strlen(Value
) - 1) == '\t')) {
342 *(Value
+ strlen(Value
) - 1) = 0;
348 // Increment the occurrance found
356 InputFile
->CurrentFilePointer
< InputFile
->Eof
&&
357 CurrentToken
[0] != '[' &&
358 Occurrance
<= Instance
362 // Distinguish between read errors and INF file format errors.
365 return EFI_LOAD_ERROR
;
372 return EFI_NOT_FOUND
;
377 IN CHAR8
*AsciiGuidBuffer
,
378 OUT EFI_GUID
*GuidBuffer
384 Converts a string to an EFI_GUID. The string must be in the
385 xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx format.
389 AsciiGuidBuffer - pointer to ascii string
390 GuidBuffer - pointer to destination Guid
394 EFI_ABORTED Could not convert the string
395 EFI_SUCCESS The string was successfully converted
396 EFI_INVALID_PARAMETER Input parameter is invalid.
406 if (AsciiGuidBuffer
== NULL
|| GuidBuffer
== NULL
) {
407 return EFI_INVALID_PARAMETER
;
410 // Check Guid Format strictly xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
412 for (Index
= 0; AsciiGuidBuffer
[Index
] != '\0' && Index
< 37; Index
++) {
413 if (Index
== 8 || Index
== 13 || Index
== 18 || Index
== 23) {
414 if (AsciiGuidBuffer
[Index
] != '-') {
418 if (((AsciiGuidBuffer
[Index
] >= '0') && (AsciiGuidBuffer
[Index
] <= '9')) ||
419 ((AsciiGuidBuffer
[Index
] >= 'a') && (AsciiGuidBuffer
[Index
] <= 'f')) ||
420 ((AsciiGuidBuffer
[Index
] >= 'A') && (AsciiGuidBuffer
[Index
] <= 'F'))) {
428 if (Index
< 36 || AsciiGuidBuffer
[36] != '\0') {
429 Error (NULL
, 0, 1003, "Invalid option value", "Incorrect GUID \"%s\"\n Correct Format \"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\"", AsciiGuidBuffer
);
434 // Scan the guid string into the buffer
438 "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
453 // Verify the correct number of items were scanned.
456 Error (NULL
, 0, 1003, "Invalid option value", "Incorrect GUID \"%s\"\n Correct Format \"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\"", AsciiGuidBuffer
);
460 // Copy the data into our GUID.
462 GuidBuffer
->Data1
= (UINT32
) Data1
;
463 GuidBuffer
->Data2
= (UINT16
) Data2
;
464 GuidBuffer
->Data3
= (UINT16
) Data3
;
465 GuidBuffer
->Data4
[0] = (UINT8
) Data4
[0];
466 GuidBuffer
->Data4
[1] = (UINT8
) Data4
[1];
467 GuidBuffer
->Data4
[2] = (UINT8
) Data4
[2];
468 GuidBuffer
->Data4
[3] = (UINT8
) Data4
[3];
469 GuidBuffer
->Data4
[4] = (UINT8
) Data4
[4];
470 GuidBuffer
->Data4
[5] = (UINT8
) Data4
[5];
471 GuidBuffer
->Data4
[6] = (UINT8
) Data4
[6];
472 GuidBuffer
->Data4
[7] = (UINT8
) Data4
[7];
478 AsciiStringToUint64 (
479 IN CONST CHAR8
*AsciiString
,
481 OUT UINT64
*ReturnValue
487 Converts a null terminated ascii string that represents a number into a
488 UINT64 value. A hex number may be preceeded by a 0x, but may not be
489 succeeded by an h. A number without 0x or 0X is considered to be base 10
490 unless the IsHex input is true.
494 AsciiString The string to convert.
495 IsHex Force the string to be treated as a hex number.
496 ReturnValue The return value.
500 EFI_SUCCESS Number successfully converted.
501 EFI_ABORTED Invalid character encountered.
510 // Initialize the result
516 // Check input paramter
518 if (AsciiString
== NULL
|| ReturnValue
== NULL
) {
519 return EFI_INVALID_PARAMETER
;
521 while (AsciiString
[Index
] == ' ') {
526 // Add each character to the result
530 // Skip first two chars only if the string starts with '0x' or '0X'
532 if (AsciiString
[Index
] == '0' && (AsciiString
[Index
+ 1] == 'x' || AsciiString
[Index
+ 1] == 'X')) {
538 // Convert the hex string.
540 for (; AsciiString
[Index
] != '\0'; Index
++) {
541 CurrentChar
= AsciiString
[Index
];
542 if (CurrentChar
== ' ') {
548 if (isxdigit ((int)CurrentChar
) == 0) {
555 if (CurrentChar
>= '0' && CurrentChar
<= '9') {
556 Value
+= CurrentChar
- '0';
557 } else if (CurrentChar
>= 'a' && CurrentChar
<= 'f') {
558 Value
+= CurrentChar
- 'a' + 10;
559 } else if (CurrentChar
>= 'A' && CurrentChar
<= 'F') {
560 Value
+= CurrentChar
- 'A' + 10;
564 *ReturnValue
= Value
;
567 // Convert dec string is a number
569 for (; Index
< strlen (AsciiString
); Index
++) {
570 CurrentChar
= AsciiString
[Index
];
571 if (CurrentChar
== ' ') {
577 if (isdigit ((int)CurrentChar
) == 0) {
584 Value
+= CurrentChar
- '0';
587 *ReturnValue
= Value
;
596 IN OUT CHAR8
*InputBuffer
602 This function reads a line, stripping any comments.
603 // BUGBUG: This is obsolete once genmake goes away...
607 InputFile Stream pointer.
608 InputBuffer Buffer to read into, must be MAX_LONG_FILE_PATH size.
613 InputBuffer otherwise
620 // Verify input parameters are not null
623 assert (InputBuffer
);
628 if (fgets (InputBuffer
, MAX_LONG_FILE_PATH
, InputFile
) == NULL
) {
632 // Strip any comments
634 CharPtr
= strstr (InputBuffer
, "//");
639 CharPtr
= strstr (InputBuffer
, "#");
650 FindSectionInStream (
658 This function parses a stream file from the beginning to find a section.
659 The section string may be anywhere within a line.
660 // BUGBUG: This is obsolete once genmake goes away...
664 InputFile Stream pointer.
665 Section Section to search for
669 FALSE if error or EOF
670 TRUE if section found
674 CHAR8 InputBuffer
[MAX_LONG_FILE_PATH
];
678 // Verify input is not NULL
684 // Rewind to beginning of file
686 if (fseek (InputFile
, 0, SEEK_SET
) != 0) {
690 // Read lines until the section is found
692 while (feof (InputFile
) == 0) {
696 ReadLineInStream (InputFile
, InputBuffer
);
699 // Check if the section is found
701 CurrentToken
= strstr (InputBuffer
, Section
);
702 if (CurrentToken
!= NULL
) {