3 Copyright (c) 2004 - 2008, 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 Generic but simple file parsing routines.
27 #include "EfiUtilityMsgs.h"
28 #include "SimpleFileParsing.h"
34 // just in case we get in an endless loop.
36 #define MAX_NEST_DEPTH 20
40 #define MAX_STRING_IDENTIFIER_NAME 100
42 #define T_CHAR_SPACE ' '
44 #define T_CHAR_CR '\r'
45 #define T_CHAR_TAB '\t'
46 #define T_CHAR_LF '\n'
47 #define T_CHAR_SLASH '/'
48 #define T_CHAR_BACKSLASH '\\'
49 #define T_CHAR_DOUBLE_QUOTE '"'
50 #define T_CHAR_LC_X 'x'
52 #define T_CHAR_STAR '*'
55 // We keep a linked list of these for the source files we process
57 typedef struct _SOURCE_FILE
{
62 CHAR8 FileName
[MAX_PATH
];
66 struct _SOURCE_FILE
*Previous
;
67 struct _SOURCE_FILE
*Next
;
68 CHAR8 ControlCharacter
;
76 // Keep all our module globals in this structure
79 SOURCE_FILE SourceFile
;
108 SOURCE_FILE
*SourceFile
114 SOURCE_FILE
*SourceFile
120 SOURCE_FILE
*SourceFile
126 SOURCE_FILE
*SourceFile
132 SOURCE_FILE
*SourceFile
145 SOURCE_FILE
*SourceFile
,
146 SOURCE_FILE
*ParentSourceFile
152 SOURCE_FILE
*SourceFile
179 STATUS_SUCCESS always
183 memset ((VOID
*) &mGlobals
, 0, sizeof (mGlobals
));
184 return STATUS_SUCCESS
;
194 Return the line number of the file we're parsing. Used
195 for error reporting purposes.
201 The line number, or 0 if no file is being processed
205 return mGlobals
.SourceFile
.LineNum
;
215 Return the name of the file we're parsing. Used
216 for error reporting purposes.
222 A pointer to the file name. Null if no file is being
227 if (mGlobals
.SourceFile
.FileName
[0]) {
228 return mGlobals
.SourceFile
.FileName
;
241 Open a file for parsing.
244 FileName - name of the file to parse
252 t_strcpy (mGlobals
.SourceFile
.FileName
, FileName
);
253 Status
= ProcessIncludeFile (&mGlobals
.SourceFile
, NULL
);
264 Check to see if the specified token is found at
265 the current position in the input file.
268 Str - the token to look for
271 TRUE - the token is next
272 FALSE - the token is not next
275 We do a simple string comparison on this function. It is
276 the responsibility of the caller to ensure that the token
277 is not a subset of some other token.
279 The file pointer is advanced past the token in the input file.
284 SkipWhiteSpace (&mGlobals
.SourceFile
);
285 if (EndOfFile (&mGlobals
.SourceFile
)) {
289 if ((Len
= t_strcmp (mGlobals
.SourceFile
.FileBufferPtr
, Str
)) > 0) {
290 mGlobals
.SourceFile
.FileBufferPtr
+= Len
;
291 if (mGlobals
.VerboseToken
) {
292 printf ("Token: '%s'\n", Str
);
308 Check to see if the specified keyword is found at
309 the current position in the input file.
312 Str - keyword to look for
315 TRUE - the keyword is next
316 FALSE - the keyword is not next
319 A keyword is defined as a "special" string that has a non-alphanumeric
320 character following it.
325 SkipWhiteSpace (&mGlobals
.SourceFile
);
326 if (EndOfFile (&mGlobals
.SourceFile
)) {
330 if ((Len
= t_strcmp (mGlobals
.SourceFile
.FileBufferPtr
, Str
)) > 0) {
331 if (isalnum ((int)mGlobals
.SourceFile
.FileBufferPtr
[Len
])) {
335 mGlobals
.SourceFile
.FileBufferPtr
+= Len
;
336 if (mGlobals
.VerboseToken
) {
337 printf ("Token: '%s'\n", Str
);
354 Get the next token from the input stream.
357 Str - pointer to a copy of the next token
358 Len - size of buffer pointed to by Str
361 TRUE - next token successfully returned
365 Preceeding white space is ignored.
366 The parser's buffer pointer is advanced past the end of the
374 SkipWhiteSpace (&mGlobals
.SourceFile
);
375 if (EndOfFile (&mGlobals
.SourceFile
)) {
379 // Have to have enough string for at least one char and a null-terminator
385 // Look at the first character. If it's an identifier, then treat it
388 TempChar
= mGlobals
.SourceFile
.FileBufferPtr
[0];
389 if (((TempChar
>= 'a') && (TempChar
<= 'z')) || ((TempChar
>= 'A') && (TempChar
<= 'Z')) || (TempChar
== '_')) {
391 mGlobals
.SourceFile
.FileBufferPtr
++;
393 while (!EndOfFile (&mGlobals
.SourceFile
) && (Index
< Len
)) {
394 TempChar
= mGlobals
.SourceFile
.FileBufferPtr
[0];
395 if (((TempChar
>= 'a') && (TempChar
<= 'z')) ||
396 ((TempChar
>= 'A') && (TempChar
<= 'Z')) ||
397 ((TempChar
>= '0') && (TempChar
<= '9')) ||
400 Str
[Index
] = mGlobals
.SourceFile
.FileBufferPtr
[0];
401 mGlobals
.SourceFile
.FileBufferPtr
++;
405 // Invalid character for symbol name, so break out
411 // Null terminate and return success
415 } else if ((TempChar
== ')') || (TempChar
== '(') || (TempChar
== '*')) {
416 Str
[0] = mGlobals
.SourceFile
.FileBufferPtr
[0];
417 mGlobals
.SourceFile
.FileBufferPtr
++;
422 // Everything else is white-space (or EOF) separated
425 while (!EndOfFile (&mGlobals
.SourceFile
) && (Index
< Len
)) {
426 if (IsWhiteSpace (&mGlobals
.SourceFile
)) {
434 Str
[Index
] = mGlobals
.SourceFile
.FileBufferPtr
[0];
435 mGlobals
.SourceFile
.FileBufferPtr
++;
440 // See if we just ran out of file contents, but did find a token
442 if ((Index
> 0) && EndOfFile (&mGlobals
.SourceFile
)) {
459 Parse a GUID from the input stream. Stop when you discover white space.
462 Str - pointer to a copy of the next token
463 Len - size of buffer pointed to by Str
466 TRUE - GUID string returned successfully
472 SkipWhiteSpace (&mGlobals
.SourceFile
);
473 if (EndOfFile (&mGlobals
.SourceFile
)) {
478 while (!EndOfFile (&mGlobals
.SourceFile
) && (Index
< Len
)) {
479 if (IsWhiteSpace (&mGlobals
.SourceFile
)) {
487 Str
[Index
] = mGlobals
.SourceFile
.FileBufferPtr
[0];
488 mGlobals
.SourceFile
.FileBufferPtr
++;
503 Len
= t_strlen (Str
);
504 SavePos
= mGlobals
.SourceFile
.FileBufferPtr
;
505 SkipWhiteSpace (&mGlobals
.SourceFile
);
506 while (!EndOfFile (&mGlobals
.SourceFile
)) {
507 if (t_strncmp (Str
, mGlobals
.SourceFile
.FileBufferPtr
, Len
) == 0) {
508 mGlobals
.SourceFile
.FileBufferPtr
+= Len
;
512 mGlobals
.SourceFile
.FileBufferPtr
++;
513 SkipWhiteSpace (&mGlobals
.SourceFile
);
516 mGlobals
.SourceFile
.FileBufferPtr
= SavePos
;
527 Check the token at the current file position for a numeric value.
528 May be either decimal or hex.
531 Value - pointer where to store the value
534 FALSE - current token is not a number
535 TRUE - current token is a number
541 SkipWhiteSpace (&mGlobals
.SourceFile
);
542 if (EndOfFile (&mGlobals
.SourceFile
)) {
546 if (isdigit ((int)mGlobals
.SourceFile
.FileBufferPtr
[0])) {
548 // Check for hex value
550 if ((mGlobals
.SourceFile
.FileBufferPtr
[0] == T_CHAR_0
) && (mGlobals
.SourceFile
.FileBufferPtr
[1] == T_CHAR_LC_X
)) {
551 if (!isxdigit ((int)mGlobals
.SourceFile
.FileBufferPtr
[2])) {
555 mGlobals
.SourceFile
.FileBufferPtr
+= 2;
556 sscanf (mGlobals
.SourceFile
.FileBufferPtr
, "%x", &Val
);
557 *Value
= (UINT32
) Val
;
558 while (isxdigit ((int)mGlobals
.SourceFile
.FileBufferPtr
[0])) {
559 mGlobals
.SourceFile
.FileBufferPtr
++;
564 *Value
= atoi (mGlobals
.SourceFile
.FileBufferPtr
);
565 while (isdigit ((int)mGlobals
.SourceFile
.FileBufferPtr
[0])) {
566 mGlobals
.SourceFile
.FileBufferPtr
++;
583 Close the file being parsed.
589 STATUS_SUCCESS - the file was closed
590 STATUS_ERROR - no file is currently open
594 if (mGlobals
.SourceFile
.FileBuffer
!= NULL
) {
595 free (mGlobals
.SourceFile
.FileBuffer
);
596 memset (&mGlobals
.SourceFile
, 0, sizeof (mGlobals
.SourceFile
));
597 return STATUS_SUCCESS
;
606 SOURCE_FILE
*SourceFile
,
607 SOURCE_FILE
*ParentSourceFile
613 Given a source file, open the file and parse it
617 SourceFile - name of file to parse
618 ParentSourceFile - for error reporting purposes, the file that #included SourceFile.
626 STATIC UINTN NestDepth
= 0;
627 CHAR8 FoundFileName
[MAX_PATH
];
630 Status
= STATUS_SUCCESS
;
633 // Print the file being processed. Indent so you can tell the include nesting
636 if (mGlobals
.VerboseFile
) {
637 fprintf (stdout
, "%*cProcessing file '%s'\n", (int)NestDepth
* 2, ' ', SourceFile
->FileName
);
638 fprintf (stdout
, "Parent source file = '%s'\n", ParentSourceFile
->FileName
);
642 // Make sure we didn't exceed our maximum nesting depth
644 if (NestDepth
> MAX_NEST_DEPTH
) {
645 Error (NULL
, 0, 3001, "Not Supported", "%s exceeeds max nesting depth (%u)", SourceFile
->FileName
, (unsigned) NestDepth
);
646 Status
= STATUS_ERROR
;
650 // Try to open the file locally, and if that fails try along our include paths.
652 strcpy (FoundFileName
, SourceFile
->FileName
);
653 if ((SourceFile
->Fptr
= fopen (FoundFileName
, "rb")) == NULL
) {
657 // Process the file found
659 ProcessFile (SourceFile
);
662 // Close open files and return status
664 if (SourceFile
->Fptr
!= NULL
) {
665 fclose (SourceFile
->Fptr
);
666 SourceFile
->Fptr
= NULL
;
675 SOURCE_FILE
*SourceFile
681 Given a source file that's been opened, read the contents into an internal
682 buffer and pre-process it to remove comments.
686 SourceFile - structure containing info on the file to process
695 // Get the file size, and then read the entire thing into memory.
696 // Allocate extra space for a terminator character.
698 fseek (SourceFile
->Fptr
, 0, SEEK_END
);
699 SourceFile
->FileSize
= ftell (SourceFile
->Fptr
);
700 if (mGlobals
.VerboseFile
) {
701 printf ("FileSize = %u (0x%X)\n", (unsigned) SourceFile
->FileSize
, (unsigned) SourceFile
->FileSize
);
704 fseek (SourceFile
->Fptr
, 0, SEEK_SET
);
705 SourceFile
->FileBuffer
= (CHAR8
*) malloc (SourceFile
->FileSize
+ sizeof (CHAR8
));
706 if (SourceFile
->FileBuffer
== NULL
) {
707 Error (NULL
, 0, 4001, "Resource: memory cannot be allocated", NULL
);
711 fread ((VOID
*) SourceFile
->FileBuffer
, SourceFile
->FileSize
, 1, SourceFile
->Fptr
);
712 SourceFile
->FileBuffer
[(SourceFile
->FileSize
/ sizeof (CHAR8
))] = T_CHAR_NULL
;
714 // Pre-process the file to replace comments with spaces
716 PreprocessFile (SourceFile
);
717 SourceFile
->LineNum
= 1;
718 return STATUS_SUCCESS
;
724 SOURCE_FILE
*SourceFile
729 Preprocess a file to replace all carriage returns with NULLs so
730 we can print lines (as part of error messages) from the file to the screen.
733 SourceFile - structure that we use to keep track of an input file.
741 BOOLEAN SlashSlashComment
;
744 RewindFile (SourceFile
);
746 SlashSlashComment
= FALSE
;
747 while (!EndOfFile (SourceFile
)) {
749 // If a line-feed, then no longer in a comment if we're in a // comment
751 if (SourceFile
->FileBufferPtr
[0] == T_CHAR_LF
) {
752 SourceFile
->FileBufferPtr
++;
753 SourceFile
->LineNum
++;
754 if (InComment
&& SlashSlashComment
) {
756 SlashSlashComment
= FALSE
;
758 } else if (SourceFile
->FileBufferPtr
[0] == T_CHAR_CR
) {
760 // Replace all carriage returns with a NULL so we can print stuff
762 SourceFile
->FileBufferPtr
[0] = 0;
763 SourceFile
->FileBufferPtr
++;
765 // Check for */ comment end
767 } else if (InComment
&&
768 !SlashSlashComment
&&
769 (SourceFile
->FileBufferPtr
[0] == T_CHAR_STAR
) &&
770 (SourceFile
->FileBufferPtr
[1] == T_CHAR_SLASH
)
772 SourceFile
->FileBufferPtr
[0] = T_CHAR_SPACE
;
773 SourceFile
->FileBufferPtr
++;
774 SourceFile
->FileBufferPtr
[0] = T_CHAR_SPACE
;
775 SourceFile
->FileBufferPtr
++;
777 } else if (InComment
) {
778 SourceFile
->FileBufferPtr
[0] = T_CHAR_SPACE
;
779 SourceFile
->FileBufferPtr
++;
781 // Check for // comments
783 } else if ((SourceFile
->FileBufferPtr
[0] == T_CHAR_SLASH
) && (SourceFile
->FileBufferPtr
[1] == T_CHAR_SLASH
)) {
785 SlashSlashComment
= TRUE
;
787 // Check for /* comment start
789 } else if ((SourceFile
->FileBufferPtr
[0] == T_CHAR_SLASH
) && (SourceFile
->FileBufferPtr
[1] == T_CHAR_STAR
)) {
790 SourceFile
->FileBufferPtr
[0] = T_CHAR_SPACE
;
791 SourceFile
->FileBufferPtr
++;
792 SourceFile
->FileBufferPtr
[0] = T_CHAR_SPACE
;
793 SourceFile
->FileBufferPtr
++;
794 SlashSlashComment
= FALSE
;
797 SourceFile
->FileBufferPtr
++;
801 // Could check for end-of-file and still in a comment, but
802 // should not be necessary. So just restore the file pointers.
804 RewindFile (SourceFile
);
806 // Dump the reformatted file if verbose mode
808 if (mGlobals
.VerboseFile
) {
810 printf ("%04d: ", LineNum
);
811 while (!EndOfFile (SourceFile
)) {
812 if (SourceFile
->FileBufferPtr
[0] == T_CHAR_LF
) {
813 printf ("'\n%04d: '", ++LineNum
);
815 printf ("%c", SourceFile
->FileBufferPtr
[0]);
818 SourceFile
->FileBufferPtr
++;
822 printf ("FileSize = %u (0x%X)\n", (unsigned)SourceFile
->FileSize
, (unsigned)SourceFile
->FileSize
);
823 RewindFile (SourceFile
);
835 Retrieve a quoted-string from the input file.
838 Str - pointer to a copy of the quoted string parsed
839 Length - size of buffer pointed to by Str
842 TRUE - next token in input stream was a quoted string, and
843 the string value was returned in Str
848 SkipWhiteSpace (&mGlobals
.SourceFile
);
849 if (EndOfFile (&mGlobals
.SourceFile
)) {
853 if (mGlobals
.SourceFile
.FileBufferPtr
[0] == T_CHAR_DOUBLE_QUOTE
) {
854 mGlobals
.SourceFile
.FileBufferPtr
++;
856 if (EndOfFile (&mGlobals
.SourceFile
)) {
860 // Check for closing quote
862 if (mGlobals
.SourceFile
.FileBufferPtr
[0] == T_CHAR_DOUBLE_QUOTE
) {
863 mGlobals
.SourceFile
.FileBufferPtr
++;
868 *Str
= mGlobals
.SourceFile
.FileBufferPtr
[0];
871 mGlobals
.SourceFile
.FileBufferPtr
++;
875 // First character was not a quote, or the input string length was
876 // insufficient to contain the quoted string, so return failure code.
888 Return TRUE of FALSE to indicate whether or not we've reached the end of the
900 SkipWhiteSpace (&mGlobals
.SourceFile
);
901 return EndOfFile (&mGlobals
.SourceFile
);
908 SOURCE_FILE
*SourceFile
,
916 BOOLEAN PreviousBackslash
;
918 if (SourceFile
->FileBufferPtr
[0] != T_CHAR_DOUBLE_QUOTE
) {
919 if (Optional
== FALSE
) {
920 Error (SourceFile
->FileName
, SourceFile
->LineNum
, 0, "expected quoted string", "%S", SourceFile
->FileBufferPtr
);
927 SourceFile
->FileBufferPtr
++;
928 Start
= Ptr
= SourceFile
->FileBufferPtr
;
929 PreviousBackslash
= FALSE
;
930 while (!EndOfFile (SourceFile
)) {
931 if ((SourceFile
->FileBufferPtr
[0] == T_CHAR_DOUBLE_QUOTE
) && (PreviousBackslash
== FALSE
)) {
933 } else if (SourceFile
->FileBufferPtr
[0] == T_CHAR_CR
) {
934 Warning (SourceFile
->FileName
, SourceFile
->LineNum
, 0, "carriage return found in quoted string", "%S", Start
);
935 PreviousBackslash
= FALSE
;
936 } else if (SourceFile
->FileBufferPtr
[0] == T_CHAR_BACKSLASH
) {
937 PreviousBackslash
= TRUE
;
939 PreviousBackslash
= FALSE
;
942 SourceFile
->FileBufferPtr
++;
946 if (SourceFile
->FileBufferPtr
[0] != T_CHAR_DOUBLE_QUOTE
) {
947 Warning (SourceFile
->FileName
, SourceFile
->LineNum
, 0, "missing closing quote on string", "%S", Start
);
949 SourceFile
->FileBufferPtr
++;
952 // Now allocate memory for the string and save it off
954 String
= (CHAR8
*) malloc ((Len
+ 1) * sizeof (CHAR8
));
955 if (String
== NULL
) {
956 Error (NULL
, 0, 4001, "Resource: memory cannot be allocated", NULL
);
960 // Copy the string from the file buffer to the local copy.
961 // We do no reformatting of it whatsoever at this point.
978 SOURCE_FILE
*SourceFile
982 // The file buffer pointer will typically get updated before the End-of-file flag in the
983 // source file structure, so check it first.
985 if (SourceFile
->FileBufferPtr
>= SourceFile
->FileBuffer
+ SourceFile
->FileSize
/ sizeof (CHAR8
)) {
986 SourceFile
->EndOfFile
= TRUE
;
990 if (SourceFile
->EndOfFile
) {
1000 ProcessTokenInclude (
1001 SOURCE_FILE
*SourceFile
1004 CHAR8 IncludeFileName
[MAX_PATH
];
1007 BOOLEAN ReportedError
;
1008 SOURCE_FILE IncludedSourceFile
;
1010 ReportedError
= FALSE
;
1011 if (SkipWhiteSpace (SourceFile
) == 0) {
1012 Warning (SourceFile
->FileName
, SourceFile
->LineNum
, 0, "expected whitespace following #include keyword", NULL
);
1015 // Should be quoted file name
1017 if (SourceFile
->FileBufferPtr
[0] != T_CHAR_DOUBLE_QUOTE
) {
1018 Error (SourceFile
->FileName
, SourceFile
->LineNum
, 0, "expected quoted include file name", NULL
);
1022 SourceFile
->FileBufferPtr
++;
1024 // Copy the filename as ascii to our local string
1026 To
= IncludeFileName
;
1028 while (!EndOfFile (SourceFile
)) {
1029 if ((SourceFile
->FileBufferPtr
[0] == T_CHAR_CR
) || (SourceFile
->FileBufferPtr
[0] == T_CHAR_LF
)) {
1030 Error (SourceFile
->FileName
, SourceFile
->LineNum
, 0, "end-of-line found in quoted include file name", NULL
);
1034 if (SourceFile
->FileBufferPtr
[0] == T_CHAR_DOUBLE_QUOTE
) {
1035 SourceFile
->FileBufferPtr
++;
1039 // If too long, then report the error once and process until the closing quote
1042 if (!ReportedError
&& (Len
>= sizeof (IncludeFileName
))) {
1043 Error (SourceFile
->FileName
, SourceFile
->LineNum
, 0, "length of include file name exceeds limit", NULL
);
1044 ReportedError
= TRUE
;
1047 if (!ReportedError
) {
1048 *To
= (CHAR8
) SourceFile
->FileBufferPtr
[0];
1052 SourceFile
->FileBufferPtr
++;
1055 if (!ReportedError
) {
1057 memset ((CHAR8
*) &IncludedSourceFile
, 0, sizeof (SOURCE_FILE
));
1058 strcpy (IncludedSourceFile
.FileName
, IncludeFileName
);
1059 ProcessIncludeFile (&IncludedSourceFile
, SourceFile
);
1065 // Error recovery -- skip to next #
1067 SourceFile
->SkipToHash
= TRUE
;
1073 SOURCE_FILE
*SourceFile
1076 switch (*SourceFile
->FileBufferPtr
) {
1091 SOURCE_FILE
*SourceFile
1097 while (!EndOfFile (SourceFile
)) {
1099 switch (*SourceFile
->FileBufferPtr
) {
1104 SourceFile
->FileBufferPtr
++;
1108 SourceFile
->FileBufferPtr
++;
1109 SourceFile
->LineNum
++;
1117 // Some tokens require trailing whitespace. If we're at the end of the
1118 // file, then we count that as well.
1120 if ((Count
== 0) && (EndOfFile (SourceFile
))) {
1135 Routine Description:
1136 Compare two strings for equality. The string pointed to by 'Buffer' may or may not be null-terminated,
1137 so only compare up to the length of Str.
1140 Buffer - pointer to first (possibly not null-terminated) string
1141 Str - pointer to null-terminated string to compare to Buffer
1144 Number of bytes matched if exact match
1145 0 if Buffer does not start with Str
1152 while (*Str
&& (*Str
== *Buffer
)) {
1190 if (*Str1
!= *Str2
) {
1224 SOURCE_FILE
*SourceFile
1227 SourceFile
->LineNum
= 1;
1228 SourceFile
->FileBufferPtr
= SourceFile
->FileBuffer
;
1229 SourceFile
->EndOfFile
= 0;
1241 while (!EndOfFile (&mGlobals
.SourceFile
) && (BufferLen
> 0)) {
1242 if (isxdigit ((int)mGlobals
.SourceFile
.FileBufferPtr
[0])) {
1243 *Buffer
= mGlobals
.SourceFile
.FileBufferPtr
[0];
1247 mGlobals
.SourceFile
.FileBufferPtr
++;
1253 // Null terminate if we can
1255 if ((Len
> 0) && (BufferLen
> 0)) {
1269 Routine Description:
1270 Parse a GUID from the input stream. Stop when you discover white space.
1273 GuidStyle - Style of the following GUID token
1274 Value - pointer to EFI_GUID struct for output
1277 TRUE - GUID string parsed successfully
1281 Style[0] 12345678-1234-5678-AAAA-BBBBCCCCDDDD
1288 CHAR8 TempString
[20];
1289 CHAR8 TempString2
[3];
1297 // Skip white space, then start parsing
1299 SkipWhiteSpace (&mGlobals
.SourceFile
);
1300 GetFilePosition (&FPos
);
1301 if (EndOfFile (&mGlobals
.SourceFile
)) {
1305 if (GuidStyle
== PARSE_GUID_STYLE_5_FIELDS
) {
1307 // Style[0] 12345678-1234-5678-AAAA-BBBBCCCCDDDD
1309 Len
= GetHexChars (TempString
, sizeof (TempString
));
1310 if ((Len
== 0) || (Len
> 8)) {
1314 sscanf (TempString
, "%x", &Value32
);
1315 Value
->Data1
= Value32
;
1317 // Next two UINT16 fields
1319 if (mGlobals
.SourceFile
.FileBufferPtr
[0] != '-') {
1323 mGlobals
.SourceFile
.FileBufferPtr
++;
1324 Len
= GetHexChars (TempString
, sizeof (TempString
));
1325 if ((Len
== 0) || (Len
> 4)) {
1329 sscanf (TempString
, "%x", &Value32
);
1330 Value
->Data2
= (UINT16
) Value32
;
1332 if (mGlobals
.SourceFile
.FileBufferPtr
[0] != '-') {
1336 mGlobals
.SourceFile
.FileBufferPtr
++;
1337 Len
= GetHexChars (TempString
, sizeof (TempString
));
1338 if ((Len
== 0) || (Len
> 4)) {
1342 sscanf (TempString
, "%x", &Value32
);
1343 Value
->Data3
= (UINT16
) Value32
;
1345 // Parse the "AAAA" as two bytes
1347 if (mGlobals
.SourceFile
.FileBufferPtr
[0] != '-') {
1351 mGlobals
.SourceFile
.FileBufferPtr
++;
1352 Len
= GetHexChars (TempString
, sizeof (TempString
));
1353 if ((Len
== 0) || (Len
> 4)) {
1357 sscanf (TempString
, "%x", &Value32
);
1358 Value
->Data4
[0] = (UINT8
) (Value32
>> 8);
1359 Value
->Data4
[1] = (UINT8
) Value32
;
1360 if (mGlobals
.SourceFile
.FileBufferPtr
[0] != '-') {
1364 mGlobals
.SourceFile
.FileBufferPtr
++;
1366 // Read the last 6 bytes of the GUID
1369 Len
= GetHexChars (TempString
, sizeof (TempString
));
1370 if ((Len
== 0) || (Len
> 12)) {
1374 // Insert leading 0's to make life easier
1377 From
= TempString
+ Len
- 1;
1378 To
= TempString
+ 11;
1380 while (From
>= TempString
) {
1386 while (To
>= TempString
) {
1392 // Now parse each byte
1395 for (Index
= 0; Index
< 6; Index
++) {
1397 // Copy the two characters from the input string to something
1400 TempString2
[0] = TempString
[Index
* 2];
1401 TempString2
[1] = TempString
[Index
* 2 + 1];
1402 sscanf (TempString2
, "%x", &Value32
);
1403 Value
->Data4
[Index
+ 2] = (UINT8
) Value32
;
1409 // Unsupported GUID style
1415 if (Status
== FALSE
) {
1416 SetFilePosition (&FPos
);
1428 Fpos
->FileBufferPtr
= mGlobals
.SourceFile
.FileBufferPtr
;
1429 return STATUS_SUCCESS
;
1439 // Should check range of pointer
1441 mGlobals
.SourceFile
.FileBufferPtr
= Fpos
->FileBufferPtr
;
1442 return STATUS_SUCCESS
;