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 Generic but simple file parsing routines.
27 #include "CommonLib.h"
28 #include "EfiUtilityMsgs.h"
29 #include "SimpleFileParsing.h"
35 // just in case we get in an endless loop.
37 #define MAX_NEST_DEPTH 20
41 #define MAX_STRING_IDENTIFIER_NAME 100
43 #define T_CHAR_SPACE ' '
45 #define T_CHAR_CR '\r'
46 #define T_CHAR_TAB '\t'
47 #define T_CHAR_LF '\n'
48 #define T_CHAR_SLASH '/'
49 #define T_CHAR_BACKSLASH '\\'
50 #define T_CHAR_DOUBLE_QUOTE '"'
51 #define T_CHAR_LC_X 'x'
53 #define T_CHAR_STAR '*'
56 // We keep a linked list of these for the source files we process
58 typedef struct _SOURCE_FILE
{
63 CHAR8 FileName
[MAX_PATH
];
67 struct _SOURCE_FILE
*Previous
;
68 struct _SOURCE_FILE
*Next
;
69 CHAR8 ControlCharacter
;
77 // Keep all our module globals in this structure
80 SOURCE_FILE SourceFile
;
109 SOURCE_FILE
*SourceFile
115 SOURCE_FILE
*SourceFile
121 SOURCE_FILE
*SourceFile
127 SOURCE_FILE
*SourceFile
133 SOURCE_FILE
*SourceFile
146 SOURCE_FILE
*SourceFile
,
147 SOURCE_FILE
*ParentSourceFile
153 SOURCE_FILE
*SourceFile
180 STATUS_SUCCESS always
184 memset ((VOID
*) &mGlobals
, 0, sizeof (mGlobals
));
185 return STATUS_SUCCESS
;
195 Return the line number of the file we're parsing. Used
196 for error reporting purposes.
202 The line number, or 0 if no file is being processed
206 return mGlobals
.SourceFile
.LineNum
;
216 Return the name of the file we're parsing. Used
217 for error reporting purposes.
223 A pointer to the file name. Null if no file is being
228 if (mGlobals
.SourceFile
.FileName
[0]) {
229 return mGlobals
.SourceFile
.FileName
;
242 Open a file for parsing.
245 FileName - name of the file to parse
253 t_strcpy (mGlobals
.SourceFile
.FileName
, FileName
);
254 Status
= ProcessIncludeFile (&mGlobals
.SourceFile
, NULL
);
265 Check to see if the specified token is found at
266 the current position in the input file.
269 Str - the token to look for
272 TRUE - the token is next
273 FALSE - the token is not next
276 We do a simple string comparison on this function. It is
277 the responsibility of the caller to ensure that the token
278 is not a subset of some other token.
280 The file pointer is advanced past the token in the input file.
285 SkipWhiteSpace (&mGlobals
.SourceFile
);
286 if (EndOfFile (&mGlobals
.SourceFile
)) {
290 if ((Len
= t_strcmp (mGlobals
.SourceFile
.FileBufferPtr
, Str
)) > 0) {
291 mGlobals
.SourceFile
.FileBufferPtr
+= Len
;
292 if (mGlobals
.VerboseToken
) {
293 printf ("Token: '%s'\n", Str
);
309 Check to see if the specified keyword is found at
310 the current position in the input file.
313 Str - keyword to look for
316 TRUE - the keyword is next
317 FALSE - the keyword is not next
320 A keyword is defined as a "special" string that has a non-alphanumeric
321 character following it.
326 SkipWhiteSpace (&mGlobals
.SourceFile
);
327 if (EndOfFile (&mGlobals
.SourceFile
)) {
331 if ((Len
= t_strcmp (mGlobals
.SourceFile
.FileBufferPtr
, Str
)) > 0) {
332 if (isalnum ((int)mGlobals
.SourceFile
.FileBufferPtr
[Len
])) {
336 mGlobals
.SourceFile
.FileBufferPtr
+= Len
;
337 if (mGlobals
.VerboseToken
) {
338 printf ("Token: '%s'\n", Str
);
355 Get the next token from the input stream.
358 Str - pointer to a copy of the next token
359 Len - size of buffer pointed to by Str
362 TRUE - next token successfully returned
366 Preceeding white space is ignored.
367 The parser's buffer pointer is advanced past the end of the
375 SkipWhiteSpace (&mGlobals
.SourceFile
);
376 if (EndOfFile (&mGlobals
.SourceFile
)) {
380 // Have to have enough string for at least one char and a null-terminator
386 // Look at the first character. If it's an identifier, then treat it
389 TempChar
= mGlobals
.SourceFile
.FileBufferPtr
[0];
390 if (((TempChar
>= 'a') && (TempChar
<= 'z')) || ((TempChar
>= 'A') && (TempChar
<= 'Z')) || (TempChar
== '_')) {
392 mGlobals
.SourceFile
.FileBufferPtr
++;
394 while (!EndOfFile (&mGlobals
.SourceFile
) && (Index
< Len
)) {
395 TempChar
= mGlobals
.SourceFile
.FileBufferPtr
[0];
396 if (((TempChar
>= 'a') && (TempChar
<= 'z')) ||
397 ((TempChar
>= 'A') && (TempChar
<= 'Z')) ||
398 ((TempChar
>= '0') && (TempChar
<= '9')) ||
401 Str
[Index
] = mGlobals
.SourceFile
.FileBufferPtr
[0];
402 mGlobals
.SourceFile
.FileBufferPtr
++;
406 // Invalid character for symbol name, so break out
412 // Null terminate and return success
416 } else if ((TempChar
== ')') || (TempChar
== '(') || (TempChar
== '*')) {
417 Str
[0] = mGlobals
.SourceFile
.FileBufferPtr
[0];
418 mGlobals
.SourceFile
.FileBufferPtr
++;
423 // Everything else is white-space (or EOF) separated
426 while (!EndOfFile (&mGlobals
.SourceFile
) && (Index
< Len
)) {
427 if (IsWhiteSpace (&mGlobals
.SourceFile
)) {
435 Str
[Index
] = mGlobals
.SourceFile
.FileBufferPtr
[0];
436 mGlobals
.SourceFile
.FileBufferPtr
++;
441 // See if we just ran out of file contents, but did find a token
443 if ((Index
> 0) && EndOfFile (&mGlobals
.SourceFile
)) {
460 Parse a GUID from the input stream. Stop when you discover white space.
463 Str - pointer to a copy of the next token
464 Len - size of buffer pointed to by Str
467 TRUE - GUID string returned successfully
473 SkipWhiteSpace (&mGlobals
.SourceFile
);
474 if (EndOfFile (&mGlobals
.SourceFile
)) {
479 while (!EndOfFile (&mGlobals
.SourceFile
) && (Index
< Len
)) {
480 if (IsWhiteSpace (&mGlobals
.SourceFile
)) {
488 Str
[Index
] = mGlobals
.SourceFile
.FileBufferPtr
[0];
489 mGlobals
.SourceFile
.FileBufferPtr
++;
504 Len
= t_strlen (Str
);
505 SavePos
= mGlobals
.SourceFile
.FileBufferPtr
;
506 SkipWhiteSpace (&mGlobals
.SourceFile
);
507 while (!EndOfFile (&mGlobals
.SourceFile
)) {
508 if (t_strncmp (Str
, mGlobals
.SourceFile
.FileBufferPtr
, Len
) == 0) {
509 mGlobals
.SourceFile
.FileBufferPtr
+= Len
;
513 mGlobals
.SourceFile
.FileBufferPtr
++;
514 SkipWhiteSpace (&mGlobals
.SourceFile
);
517 mGlobals
.SourceFile
.FileBufferPtr
= SavePos
;
528 Check the token at the current file position for a numeric value.
529 May be either decimal or hex.
532 Value - pointer where to store the value
535 FALSE - current token is not a number
536 TRUE - current token is a number
542 SkipWhiteSpace (&mGlobals
.SourceFile
);
543 if (EndOfFile (&mGlobals
.SourceFile
)) {
547 if (isdigit ((int)mGlobals
.SourceFile
.FileBufferPtr
[0])) {
549 // Check for hex value
551 if ((mGlobals
.SourceFile
.FileBufferPtr
[0] == T_CHAR_0
) && (mGlobals
.SourceFile
.FileBufferPtr
[1] == T_CHAR_LC_X
)) {
552 if (!isxdigit ((int)mGlobals
.SourceFile
.FileBufferPtr
[2])) {
556 mGlobals
.SourceFile
.FileBufferPtr
+= 2;
557 sscanf (mGlobals
.SourceFile
.FileBufferPtr
, "%x", &Val
);
558 *Value
= (UINT32
) Val
;
559 while (isxdigit ((int)mGlobals
.SourceFile
.FileBufferPtr
[0])) {
560 mGlobals
.SourceFile
.FileBufferPtr
++;
565 *Value
= atoi (mGlobals
.SourceFile
.FileBufferPtr
);
566 while (isdigit ((int)mGlobals
.SourceFile
.FileBufferPtr
[0])) {
567 mGlobals
.SourceFile
.FileBufferPtr
++;
584 Close the file being parsed.
590 STATUS_SUCCESS - the file was closed
591 STATUS_ERROR - no file is currently open
595 if (mGlobals
.SourceFile
.FileBuffer
!= NULL
) {
596 free (mGlobals
.SourceFile
.FileBuffer
);
597 memset (&mGlobals
.SourceFile
, 0, sizeof (mGlobals
.SourceFile
));
598 return STATUS_SUCCESS
;
607 SOURCE_FILE
*SourceFile
,
608 SOURCE_FILE
*ParentSourceFile
614 Given a source file, open the file and parse it
618 SourceFile - name of file to parse
619 ParentSourceFile - for error reporting purposes, the file that #included SourceFile.
627 STATIC UINTN NestDepth
= 0;
628 CHAR8 FoundFileName
[MAX_PATH
];
631 Status
= STATUS_SUCCESS
;
634 // Print the file being processed. Indent so you can tell the include nesting
637 if (mGlobals
.VerboseFile
) {
638 fprintf (stdout
, "%*cProcessing file '%s'\n", (int)NestDepth
* 2, ' ', SourceFile
->FileName
);
639 fprintf (stdout
, "Parent source file = '%s'\n", ParentSourceFile
->FileName
);
643 // Make sure we didn't exceed our maximum nesting depth
645 if (NestDepth
> MAX_NEST_DEPTH
) {
646 Error (NULL
, 0, 3001, "Not Supported", "%s exceeeds max nesting depth (%u)", SourceFile
->FileName
, (unsigned) NestDepth
);
647 Status
= STATUS_ERROR
;
651 // Try to open the file locally, and if that fails try along our include paths.
653 strcpy (FoundFileName
, SourceFile
->FileName
);
654 if ((SourceFile
->Fptr
= fopen (LongFilePath (FoundFileName
), "rb")) == NULL
) {
658 // Process the file found
660 ProcessFile (SourceFile
);
663 // Close open files and return status
665 if (SourceFile
->Fptr
!= NULL
) {
666 fclose (SourceFile
->Fptr
);
667 SourceFile
->Fptr
= NULL
;
676 SOURCE_FILE
*SourceFile
682 Given a source file that's been opened, read the contents into an internal
683 buffer and pre-process it to remove comments.
687 SourceFile - structure containing info on the file to process
696 // Get the file size, and then read the entire thing into memory.
697 // Allocate extra space for a terminator character.
699 fseek (SourceFile
->Fptr
, 0, SEEK_END
);
700 SourceFile
->FileSize
= ftell (SourceFile
->Fptr
);
701 if (mGlobals
.VerboseFile
) {
702 printf ("FileSize = %u (0x%X)\n", (unsigned) SourceFile
->FileSize
, (unsigned) SourceFile
->FileSize
);
705 fseek (SourceFile
->Fptr
, 0, SEEK_SET
);
706 SourceFile
->FileBuffer
= (CHAR8
*) malloc (SourceFile
->FileSize
+ sizeof (CHAR8
));
707 if (SourceFile
->FileBuffer
== NULL
) {
708 Error (NULL
, 0, 4001, "Resource: memory cannot be allocated", NULL
);
712 fread ((VOID
*) SourceFile
->FileBuffer
, SourceFile
->FileSize
, 1, SourceFile
->Fptr
);
713 SourceFile
->FileBuffer
[(SourceFile
->FileSize
/ sizeof (CHAR8
))] = T_CHAR_NULL
;
715 // Pre-process the file to replace comments with spaces
717 PreprocessFile (SourceFile
);
718 SourceFile
->LineNum
= 1;
719 return STATUS_SUCCESS
;
725 SOURCE_FILE
*SourceFile
730 Preprocess a file to replace all carriage returns with NULLs so
731 we can print lines (as part of error messages) from the file to the screen.
734 SourceFile - structure that we use to keep track of an input file.
742 BOOLEAN SlashSlashComment
;
745 RewindFile (SourceFile
);
747 SlashSlashComment
= FALSE
;
748 while (!EndOfFile (SourceFile
)) {
750 // If a line-feed, then no longer in a comment if we're in a // comment
752 if (SourceFile
->FileBufferPtr
[0] == T_CHAR_LF
) {
753 SourceFile
->FileBufferPtr
++;
754 SourceFile
->LineNum
++;
755 if (InComment
&& SlashSlashComment
) {
757 SlashSlashComment
= FALSE
;
759 } else if (SourceFile
->FileBufferPtr
[0] == T_CHAR_CR
) {
761 // Replace all carriage returns with a NULL so we can print stuff
763 SourceFile
->FileBufferPtr
[0] = 0;
764 SourceFile
->FileBufferPtr
++;
766 // Check for */ comment end
768 } else if (InComment
&&
769 !SlashSlashComment
&&
770 (SourceFile
->FileBufferPtr
[0] == T_CHAR_STAR
) &&
771 (SourceFile
->FileBufferPtr
[1] == T_CHAR_SLASH
)
773 SourceFile
->FileBufferPtr
[0] = T_CHAR_SPACE
;
774 SourceFile
->FileBufferPtr
++;
775 SourceFile
->FileBufferPtr
[0] = T_CHAR_SPACE
;
776 SourceFile
->FileBufferPtr
++;
778 } else if (InComment
) {
779 SourceFile
->FileBufferPtr
[0] = T_CHAR_SPACE
;
780 SourceFile
->FileBufferPtr
++;
782 // Check for // comments
784 } else if ((SourceFile
->FileBufferPtr
[0] == T_CHAR_SLASH
) && (SourceFile
->FileBufferPtr
[1] == T_CHAR_SLASH
)) {
786 SlashSlashComment
= TRUE
;
788 // Check for /* comment start
790 } else if ((SourceFile
->FileBufferPtr
[0] == T_CHAR_SLASH
) && (SourceFile
->FileBufferPtr
[1] == T_CHAR_STAR
)) {
791 SourceFile
->FileBufferPtr
[0] = T_CHAR_SPACE
;
792 SourceFile
->FileBufferPtr
++;
793 SourceFile
->FileBufferPtr
[0] = T_CHAR_SPACE
;
794 SourceFile
->FileBufferPtr
++;
795 SlashSlashComment
= FALSE
;
798 SourceFile
->FileBufferPtr
++;
802 // Could check for end-of-file and still in a comment, but
803 // should not be necessary. So just restore the file pointers.
805 RewindFile (SourceFile
);
807 // Dump the reformatted file if verbose mode
809 if (mGlobals
.VerboseFile
) {
811 printf ("%04d: ", LineNum
);
812 while (!EndOfFile (SourceFile
)) {
813 if (SourceFile
->FileBufferPtr
[0] == T_CHAR_LF
) {
814 printf ("'\n%04d: '", ++LineNum
);
816 printf ("%c", SourceFile
->FileBufferPtr
[0]);
819 SourceFile
->FileBufferPtr
++;
823 printf ("FileSize = %u (0x%X)\n", (unsigned)SourceFile
->FileSize
, (unsigned)SourceFile
->FileSize
);
824 RewindFile (SourceFile
);
836 Retrieve a quoted-string from the input file.
839 Str - pointer to a copy of the quoted string parsed
840 Length - size of buffer pointed to by Str
843 TRUE - next token in input stream was a quoted string, and
844 the string value was returned in Str
849 SkipWhiteSpace (&mGlobals
.SourceFile
);
850 if (EndOfFile (&mGlobals
.SourceFile
)) {
854 if (mGlobals
.SourceFile
.FileBufferPtr
[0] == T_CHAR_DOUBLE_QUOTE
) {
855 mGlobals
.SourceFile
.FileBufferPtr
++;
857 if (EndOfFile (&mGlobals
.SourceFile
)) {
861 // Check for closing quote
863 if (mGlobals
.SourceFile
.FileBufferPtr
[0] == T_CHAR_DOUBLE_QUOTE
) {
864 mGlobals
.SourceFile
.FileBufferPtr
++;
869 *Str
= mGlobals
.SourceFile
.FileBufferPtr
[0];
872 mGlobals
.SourceFile
.FileBufferPtr
++;
876 // First character was not a quote, or the input string length was
877 // insufficient to contain the quoted string, so return failure code.
889 Return TRUE of FALSE to indicate whether or not we've reached the end of the
901 SkipWhiteSpace (&mGlobals
.SourceFile
);
902 return EndOfFile (&mGlobals
.SourceFile
);
909 SOURCE_FILE
*SourceFile
,
917 BOOLEAN PreviousBackslash
;
919 if (SourceFile
->FileBufferPtr
[0] != T_CHAR_DOUBLE_QUOTE
) {
920 if (Optional
== FALSE
) {
921 Error (SourceFile
->FileName
, SourceFile
->LineNum
, 0, "expected quoted string", "%S", SourceFile
->FileBufferPtr
);
928 SourceFile
->FileBufferPtr
++;
929 Start
= Ptr
= SourceFile
->FileBufferPtr
;
930 PreviousBackslash
= FALSE
;
931 while (!EndOfFile (SourceFile
)) {
932 if ((SourceFile
->FileBufferPtr
[0] == T_CHAR_DOUBLE_QUOTE
) && (PreviousBackslash
== FALSE
)) {
934 } else if (SourceFile
->FileBufferPtr
[0] == T_CHAR_CR
) {
935 Warning (SourceFile
->FileName
, SourceFile
->LineNum
, 0, "carriage return found in quoted string", "%S", Start
);
936 PreviousBackslash
= FALSE
;
937 } else if (SourceFile
->FileBufferPtr
[0] == T_CHAR_BACKSLASH
) {
938 PreviousBackslash
= TRUE
;
940 PreviousBackslash
= FALSE
;
943 SourceFile
->FileBufferPtr
++;
947 if (SourceFile
->FileBufferPtr
[0] != T_CHAR_DOUBLE_QUOTE
) {
948 Warning (SourceFile
->FileName
, SourceFile
->LineNum
, 0, "missing closing quote on string", "%S", Start
);
950 SourceFile
->FileBufferPtr
++;
953 // Now allocate memory for the string and save it off
955 String
= (CHAR8
*) malloc ((Len
+ 1) * sizeof (CHAR8
));
956 if (String
== NULL
) {
957 Error (NULL
, 0, 4001, "Resource: memory cannot be allocated", NULL
);
961 // Copy the string from the file buffer to the local copy.
962 // We do no reformatting of it whatsoever at this point.
979 SOURCE_FILE
*SourceFile
983 // The file buffer pointer will typically get updated before the End-of-file flag in the
984 // source file structure, so check it first.
986 if (SourceFile
->FileBufferPtr
>= SourceFile
->FileBuffer
+ SourceFile
->FileSize
/ sizeof (CHAR8
)) {
987 SourceFile
->EndOfFile
= TRUE
;
991 if (SourceFile
->EndOfFile
) {
1001 ProcessTokenInclude (
1002 SOURCE_FILE
*SourceFile
1005 CHAR8 IncludeFileName
[MAX_PATH
];
1008 BOOLEAN ReportedError
;
1009 SOURCE_FILE IncludedSourceFile
;
1011 ReportedError
= FALSE
;
1012 if (SkipWhiteSpace (SourceFile
) == 0) {
1013 Warning (SourceFile
->FileName
, SourceFile
->LineNum
, 0, "expected whitespace following #include keyword", NULL
);
1016 // Should be quoted file name
1018 if (SourceFile
->FileBufferPtr
[0] != T_CHAR_DOUBLE_QUOTE
) {
1019 Error (SourceFile
->FileName
, SourceFile
->LineNum
, 0, "expected quoted include file name", NULL
);
1023 SourceFile
->FileBufferPtr
++;
1025 // Copy the filename as ascii to our local string
1027 To
= IncludeFileName
;
1029 while (!EndOfFile (SourceFile
)) {
1030 if ((SourceFile
->FileBufferPtr
[0] == T_CHAR_CR
) || (SourceFile
->FileBufferPtr
[0] == T_CHAR_LF
)) {
1031 Error (SourceFile
->FileName
, SourceFile
->LineNum
, 0, "end-of-line found in quoted include file name", NULL
);
1035 if (SourceFile
->FileBufferPtr
[0] == T_CHAR_DOUBLE_QUOTE
) {
1036 SourceFile
->FileBufferPtr
++;
1040 // If too long, then report the error once and process until the closing quote
1043 if (!ReportedError
&& (Len
>= sizeof (IncludeFileName
))) {
1044 Error (SourceFile
->FileName
, SourceFile
->LineNum
, 0, "length of include file name exceeds limit", NULL
);
1045 ReportedError
= TRUE
;
1048 if (!ReportedError
) {
1049 *To
= (CHAR8
) SourceFile
->FileBufferPtr
[0];
1053 SourceFile
->FileBufferPtr
++;
1056 if (!ReportedError
) {
1058 memset ((CHAR8
*) &IncludedSourceFile
, 0, sizeof (SOURCE_FILE
));
1059 strcpy (IncludedSourceFile
.FileName
, IncludeFileName
);
1060 ProcessIncludeFile (&IncludedSourceFile
, SourceFile
);
1066 // Error recovery -- skip to next #
1068 SourceFile
->SkipToHash
= TRUE
;
1074 SOURCE_FILE
*SourceFile
1077 switch (*SourceFile
->FileBufferPtr
) {
1092 SOURCE_FILE
*SourceFile
1098 while (!EndOfFile (SourceFile
)) {
1100 switch (*SourceFile
->FileBufferPtr
) {
1105 SourceFile
->FileBufferPtr
++;
1109 SourceFile
->FileBufferPtr
++;
1110 SourceFile
->LineNum
++;
1118 // Some tokens require trailing whitespace. If we're at the end of the
1119 // file, then we count that as well.
1121 if ((Count
== 0) && (EndOfFile (SourceFile
))) {
1136 Routine Description:
1137 Compare two strings for equality. The string pointed to by 'Buffer' may or may not be null-terminated,
1138 so only compare up to the length of Str.
1141 Buffer - pointer to first (possibly not null-terminated) string
1142 Str - pointer to null-terminated string to compare to Buffer
1145 Number of bytes matched if exact match
1146 0 if Buffer does not start with Str
1153 while (*Str
&& (*Str
== *Buffer
)) {
1191 if (*Str1
!= *Str2
) {
1225 SOURCE_FILE
*SourceFile
1228 SourceFile
->LineNum
= 1;
1229 SourceFile
->FileBufferPtr
= SourceFile
->FileBuffer
;
1230 SourceFile
->EndOfFile
= 0;
1242 while (!EndOfFile (&mGlobals
.SourceFile
) && (BufferLen
> 0)) {
1243 if (isxdigit ((int)mGlobals
.SourceFile
.FileBufferPtr
[0])) {
1244 *Buffer
= mGlobals
.SourceFile
.FileBufferPtr
[0];
1248 mGlobals
.SourceFile
.FileBufferPtr
++;
1254 // Null terminate if we can
1256 if ((Len
> 0) && (BufferLen
> 0)) {
1270 Routine Description:
1271 Parse a GUID from the input stream. Stop when you discover white space.
1274 GuidStyle - Style of the following GUID token
1275 Value - pointer to EFI_GUID struct for output
1278 TRUE - GUID string parsed successfully
1282 Style[0] 12345678-1234-5678-AAAA-BBBBCCCCDDDD
1289 CHAR8 TempString
[20];
1290 CHAR8 TempString2
[3];
1298 // Skip white space, then start parsing
1300 SkipWhiteSpace (&mGlobals
.SourceFile
);
1301 GetFilePosition (&FPos
);
1302 if (EndOfFile (&mGlobals
.SourceFile
)) {
1306 if (GuidStyle
== PARSE_GUID_STYLE_5_FIELDS
) {
1308 // Style[0] 12345678-1234-5678-AAAA-BBBBCCCCDDDD
1310 Len
= GetHexChars (TempString
, sizeof (TempString
));
1311 if ((Len
== 0) || (Len
> 8)) {
1315 sscanf (TempString
, "%x", &Value32
);
1316 Value
->Data1
= Value32
;
1318 // Next two UINT16 fields
1320 if (mGlobals
.SourceFile
.FileBufferPtr
[0] != '-') {
1324 mGlobals
.SourceFile
.FileBufferPtr
++;
1325 Len
= GetHexChars (TempString
, sizeof (TempString
));
1326 if ((Len
== 0) || (Len
> 4)) {
1330 sscanf (TempString
, "%x", &Value32
);
1331 Value
->Data2
= (UINT16
) Value32
;
1333 if (mGlobals
.SourceFile
.FileBufferPtr
[0] != '-') {
1337 mGlobals
.SourceFile
.FileBufferPtr
++;
1338 Len
= GetHexChars (TempString
, sizeof (TempString
));
1339 if ((Len
== 0) || (Len
> 4)) {
1343 sscanf (TempString
, "%x", &Value32
);
1344 Value
->Data3
= (UINT16
) Value32
;
1346 // Parse the "AAAA" as two bytes
1348 if (mGlobals
.SourceFile
.FileBufferPtr
[0] != '-') {
1352 mGlobals
.SourceFile
.FileBufferPtr
++;
1353 Len
= GetHexChars (TempString
, sizeof (TempString
));
1354 if ((Len
== 0) || (Len
> 4)) {
1358 sscanf (TempString
, "%x", &Value32
);
1359 Value
->Data4
[0] = (UINT8
) (Value32
>> 8);
1360 Value
->Data4
[1] = (UINT8
) Value32
;
1361 if (mGlobals
.SourceFile
.FileBufferPtr
[0] != '-') {
1365 mGlobals
.SourceFile
.FileBufferPtr
++;
1367 // Read the last 6 bytes of the GUID
1370 Len
= GetHexChars (TempString
, sizeof (TempString
));
1371 if ((Len
== 0) || (Len
> 12)) {
1375 // Insert leading 0's to make life easier
1378 From
= TempString
+ Len
- 1;
1379 To
= TempString
+ 11;
1381 while (From
>= TempString
) {
1387 while (To
>= TempString
) {
1393 // Now parse each byte
1396 for (Index
= 0; Index
< 6; Index
++) {
1398 // Copy the two characters from the input string to something
1401 TempString2
[0] = TempString
[Index
* 2];
1402 TempString2
[1] = TempString
[Index
* 2 + 1];
1403 sscanf (TempString2
, "%x", &Value32
);
1404 Value
->Data4
[Index
+ 2] = (UINT8
) Value32
;
1410 // Unsupported GUID style
1416 if (Status
== FALSE
) {
1417 SetFilePosition (&FPos
);
1429 Fpos
->FileBufferPtr
= mGlobals
.SourceFile
.FileBufferPtr
;
1430 return STATUS_SUCCESS
;
1440 // Should check range of pointer
1442 mGlobals
.SourceFile
.FileBufferPtr
= Fpos
->FileBufferPtr
;
1443 return STATUS_SUCCESS
;