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 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 MAX_LINE_LEN 400
44 #define T_CHAR_SPACE ' '
46 #define T_CHAR_CR '\r'
47 #define T_CHAR_TAB '\t'
48 #define T_CHAR_LF '\n'
49 #define T_CHAR_SLASH '/'
50 #define T_CHAR_BACKSLASH '\\'
51 #define T_CHAR_DOUBLE_QUOTE '"'
52 #define T_CHAR_LC_X 'x'
54 #define T_CHAR_STAR '*'
57 // We keep a linked list of these for the source files we process
59 typedef struct _SOURCE_FILE
{
62 T_CHAR
*FileBufferPtr
;
63 unsigned int FileSize
;
64 char FileName
[MAX_PATH
];
68 struct _SOURCE_FILE
*Previous
;
69 struct _SOURCE_FILE
*Next
;
70 T_CHAR ControlCharacter
;
74 T_CHAR
*FileBufferPtr
;
78 // Keep all our module globals in this structure
81 SOURCE_FILE SourceFile
;
110 SOURCE_FILE
*SourceFile
116 SOURCE_FILE
*SourceFile
122 SOURCE_FILE
*SourceFile
128 SOURCE_FILE
*SourceFile
134 SOURCE_FILE
*SourceFile
147 SOURCE_FILE
*SourceFile
,
148 SOURCE_FILE
*ParentSourceFile
154 SOURCE_FILE
*SourceFile
162 unsigned int FoundFileNameLen
168 SOURCE_FILE
*SourceFile
195 STATUS_SUCCESS always
199 memset ((void *) &mGlobals
, 0, sizeof (mGlobals
));
200 return STATUS_SUCCESS
;
211 Return the line number of the file we're parsing. Used
212 for error reporting purposes.
218 The line number, or 0 if no file is being processed
222 return mGlobals
.SourceFile
.LineNum
;
232 Return the name of the file we're parsing. Used
233 for error reporting purposes.
239 A pointer to the file name. Null if no file is being
244 if (mGlobals
.SourceFile
.FileName
[0]) {
245 return mGlobals
.SourceFile
.FileName
;
258 Open a file for parsing.
261 FileName - name of the file to parse
269 t_strcpy (mGlobals
.SourceFile
.FileName
, FileName
);
270 Status
= ProcessIncludeFile (&mGlobals
.SourceFile
, NULL
);
281 Check to see if the specified token is found at
282 the current position in the input file.
285 Str - the token to look for
288 TRUE - the token is next
289 FALSE - the token is not next
292 We do a simple string comparison on this function. It is
293 the responsibility of the caller to ensure that the token
294 is not a subset of some other token.
296 The file pointer is advanced past the token in the input file.
301 SkipWhiteSpace (&mGlobals
.SourceFile
);
302 if (EndOfFile (&mGlobals
.SourceFile
)) {
306 if ((Len
= t_strcmp (mGlobals
.SourceFile
.FileBufferPtr
, Str
)) > 0) {
307 mGlobals
.SourceFile
.FileBufferPtr
+= Len
;
308 if (mGlobals
.VerboseToken
) {
309 printf ("Token: '%s'\n", Str
);
325 Check to see if the specified keyword is found at
326 the current position in the input file.
329 Str - keyword to look for
332 TRUE - the keyword is next
333 FALSE - the keyword is not next
336 A keyword is defined as a "special" string that has a non-alphanumeric
337 character following it.
342 SkipWhiteSpace (&mGlobals
.SourceFile
);
343 if (EndOfFile (&mGlobals
.SourceFile
)) {
347 if ((Len
= t_strcmp (mGlobals
.SourceFile
.FileBufferPtr
, Str
)) > 0) {
348 if (isalnum (mGlobals
.SourceFile
.FileBufferPtr
[Len
])) {
352 mGlobals
.SourceFile
.FileBufferPtr
+= Len
;
353 if (mGlobals
.VerboseToken
) {
354 printf ("Token: '%s'\n", Str
);
371 Get the next token from the input stream.
374 Str - pointer to a copy of the next token
375 Len - size of buffer pointed to by Str
378 TRUE - next token successfully returned
382 Preceeding white space is ignored.
383 The parser's buffer pointer is advanced past the end of the
391 SkipWhiteSpace (&mGlobals
.SourceFile
);
392 if (EndOfFile (&mGlobals
.SourceFile
)) {
396 // Have to have enough string for at least one char and a null-terminator
402 // Look at the first character. If it's an identifier, then treat it
405 TempChar
= mGlobals
.SourceFile
.FileBufferPtr
[0];
406 if (((TempChar
>= 'a') && (TempChar
<= 'z')) || ((TempChar
>= 'A') && (TempChar
<= 'Z')) || (TempChar
== '_')) {
408 mGlobals
.SourceFile
.FileBufferPtr
++;
410 while (!EndOfFile (&mGlobals
.SourceFile
) && (Index
< Len
)) {
411 TempChar
= mGlobals
.SourceFile
.FileBufferPtr
[0];
412 if (((TempChar
>= 'a') && (TempChar
<= 'z')) ||
413 ((TempChar
>= 'A') && (TempChar
<= 'Z')) ||
414 ((TempChar
>= '0') && (TempChar
<= '9')) ||
417 Str
[Index
] = mGlobals
.SourceFile
.FileBufferPtr
[0];
418 mGlobals
.SourceFile
.FileBufferPtr
++;
422 // Invalid character for symbol name, so break out
428 // Null terminate and return success
432 } else if ((TempChar
== ')') || (TempChar
== '(') || (TempChar
== '*')) {
433 Str
[0] = mGlobals
.SourceFile
.FileBufferPtr
[0];
434 mGlobals
.SourceFile
.FileBufferPtr
++;
439 // Everything else is white-space (or EOF) separated
442 while (!EndOfFile (&mGlobals
.SourceFile
) && (Index
< Len
)) {
443 if (IsWhiteSpace (&mGlobals
.SourceFile
)) {
451 Str
[Index
] = mGlobals
.SourceFile
.FileBufferPtr
[0];
452 mGlobals
.SourceFile
.FileBufferPtr
++;
457 // See if we just ran out of file contents, but did find a token
459 if ((Index
> 0) && EndOfFile (&mGlobals
.SourceFile
)) {
476 Parse a GUID from the input stream. Stop when you discover white space.
479 Str - pointer to a copy of the next token
480 Len - size of buffer pointed to by Str
483 TRUE - GUID string returned successfully
489 SkipWhiteSpace (&mGlobals
.SourceFile
);
490 if (EndOfFile (&mGlobals
.SourceFile
)) {
495 while (!EndOfFile (&mGlobals
.SourceFile
) && (Index
< Len
)) {
496 if (IsWhiteSpace (&mGlobals
.SourceFile
)) {
504 Str
[Index
] = mGlobals
.SourceFile
.FileBufferPtr
[0];
505 mGlobals
.SourceFile
.FileBufferPtr
++;
520 Len
= t_strlen (Str
);
521 SavePos
= mGlobals
.SourceFile
.FileBufferPtr
;
522 SkipWhiteSpace (&mGlobals
.SourceFile
);
523 while (!EndOfFile (&mGlobals
.SourceFile
)) {
524 if (t_strncmp (Str
, mGlobals
.SourceFile
.FileBufferPtr
, Len
) == 0) {
525 mGlobals
.SourceFile
.FileBufferPtr
+= Len
;
529 mGlobals
.SourceFile
.FileBufferPtr
++;
530 SkipWhiteSpace (&mGlobals
.SourceFile
);
533 mGlobals
.SourceFile
.FileBufferPtr
= SavePos
;
544 Check the token at the current file position for a numeric value.
545 May be either decimal or hex.
548 Value - pointer where to store the value
551 FALSE - current token is not a number
552 TRUE - current token is a number
556 SkipWhiteSpace (&mGlobals
.SourceFile
);
557 if (EndOfFile (&mGlobals
.SourceFile
)) {
561 if (isdigit (mGlobals
.SourceFile
.FileBufferPtr
[0])) {
563 // Check for hex value
565 if ((mGlobals
.SourceFile
.FileBufferPtr
[0] == T_CHAR_0
) && (mGlobals
.SourceFile
.FileBufferPtr
[1] == T_CHAR_LC_X
)) {
566 if (!isxdigit (mGlobals
.SourceFile
.FileBufferPtr
[2])) {
570 mGlobals
.SourceFile
.FileBufferPtr
+= 2;
571 sscanf (mGlobals
.SourceFile
.FileBufferPtr
, "%x", Value
);
572 while (isxdigit (mGlobals
.SourceFile
.FileBufferPtr
[0])) {
573 mGlobals
.SourceFile
.FileBufferPtr
++;
578 *Value
= atoi (mGlobals
.SourceFile
.FileBufferPtr
);
579 while (isdigit (mGlobals
.SourceFile
.FileBufferPtr
[0])) {
580 mGlobals
.SourceFile
.FileBufferPtr
++;
597 Close the file being parsed.
603 STATUS_SUCCESS - the file was closed
604 STATUS_ERROR - no file is currently open
608 if (mGlobals
.SourceFile
.FileBuffer
!= NULL
) {
609 free (mGlobals
.SourceFile
.FileBuffer
);
610 memset (&mGlobals
.SourceFile
, 0, sizeof (mGlobals
.SourceFile
));
611 return STATUS_SUCCESS
;
620 SOURCE_FILE
*SourceFile
,
621 SOURCE_FILE
*ParentSourceFile
627 Given a source file, open the file and parse it
631 SourceFile - name of file to parse
632 ParentSourceFile - for error reporting purposes, the file that #included SourceFile.
640 static unsigned int NestDepth
= 0;
641 char FoundFileName
[MAX_PATH
];
644 Status
= STATUS_SUCCESS
;
647 // Print the file being processed. Indent so you can tell the include nesting
650 if (mGlobals
.VerboseFile
) {
651 fprintf (stdout
, "%*cProcessing file '%s'\n", NestDepth
* 2, ' ', SourceFile
->FileName
);
652 fprintf (stdout
, "Parent source file = '%s'\n", ParentSourceFile
);
656 // Make sure we didn't exceed our maximum nesting depth
658 if (NestDepth
> MAX_NEST_DEPTH
) {
659 Error (NULL
, 0, 0, SourceFile
->FileName
, "max nesting depth (%d) exceeded", NestDepth
);
660 Status
= STATUS_ERROR
;
664 // Try to open the file locally, and if that fails try along our include paths.
666 strcpy (FoundFileName
, SourceFile
->FileName
);
667 if ((SourceFile
->Fptr
= fopen (FoundFileName
, "rb")) == NULL
) {
671 // Process the file found
673 ProcessFile (SourceFile
);
676 // Close open files and return status
678 if (SourceFile
->Fptr
!= NULL
) {
679 fclose (SourceFile
->Fptr
);
680 SourceFile
->Fptr
= NULL
;
689 SOURCE_FILE
*SourceFile
695 Given a source file that's been opened, read the contents into an internal
696 buffer and pre-process it to remove comments.
700 SourceFile - structure containing info on the file to process
709 // Get the file size, and then read the entire thing into memory.
710 // Allocate extra space for a terminator character.
712 fseek (SourceFile
->Fptr
, 0, SEEK_END
);
713 SourceFile
->FileSize
= ftell (SourceFile
->Fptr
);
714 if (mGlobals
.VerboseFile
) {
715 printf ("FileSize = %d (0x%X)\n", SourceFile
->FileSize
, SourceFile
->FileSize
);
718 fseek (SourceFile
->Fptr
, 0, SEEK_SET
);
719 SourceFile
->FileBuffer
= (T_CHAR
*) malloc (SourceFile
->FileSize
+ sizeof (T_CHAR
));
720 if (SourceFile
->FileBuffer
== NULL
) {
721 Error (NULL
, 0, 0, "memory allocation failure", NULL
);
725 fread ((void *) SourceFile
->FileBuffer
, SourceFile
->FileSize
, 1, SourceFile
->Fptr
);
726 SourceFile
->FileBuffer
[(SourceFile
->FileSize
/ sizeof (T_CHAR
))] = T_CHAR_NULL
;
728 // Pre-process the file to replace comments with spaces
730 PreprocessFile (SourceFile
);
731 SourceFile
->LineNum
= 1;
732 return STATUS_SUCCESS
;
738 SOURCE_FILE
*SourceFile
743 Preprocess a file to replace all carriage returns with NULLs so
744 we can print lines (as part of error messages) from the file to the screen.
747 SourceFile - structure that we use to keep track of an input file.
755 BOOLEAN SlashSlashComment
;
758 RewindFile (SourceFile
);
760 SlashSlashComment
= FALSE
;
761 while (!EndOfFile (SourceFile
)) {
763 // If a line-feed, then no longer in a comment if we're in a // comment
765 if (SourceFile
->FileBufferPtr
[0] == T_CHAR_LF
) {
766 SourceFile
->FileBufferPtr
++;
767 SourceFile
->LineNum
++;
768 if (InComment
&& SlashSlashComment
) {
770 SlashSlashComment
= FALSE
;
772 } else if (SourceFile
->FileBufferPtr
[0] == T_CHAR_CR
) {
774 // Replace all carriage returns with a NULL so we can print stuff
776 SourceFile
->FileBufferPtr
[0] = 0;
777 SourceFile
->FileBufferPtr
++;
779 // Check for */ comment end
781 } else if (InComment
&&
782 !SlashSlashComment
&&
783 (SourceFile
->FileBufferPtr
[0] == T_CHAR_STAR
) &&
784 (SourceFile
->FileBufferPtr
[1] == T_CHAR_SLASH
)
786 SourceFile
->FileBufferPtr
[0] = T_CHAR_SPACE
;
787 SourceFile
->FileBufferPtr
++;
788 SourceFile
->FileBufferPtr
[0] = T_CHAR_SPACE
;
789 SourceFile
->FileBufferPtr
++;
791 } else if (InComment
) {
792 SourceFile
->FileBufferPtr
[0] = T_CHAR_SPACE
;
793 SourceFile
->FileBufferPtr
++;
795 // Check for // comments
797 } else if ((SourceFile
->FileBufferPtr
[0] == T_CHAR_SLASH
) && (SourceFile
->FileBufferPtr
[1] == T_CHAR_SLASH
)) {
799 SlashSlashComment
= TRUE
;
801 // Check for /* comment start
803 } else if ((SourceFile
->FileBufferPtr
[0] == T_CHAR_SLASH
) && (SourceFile
->FileBufferPtr
[1] == T_CHAR_STAR
)) {
804 SourceFile
->FileBufferPtr
[0] = T_CHAR_SPACE
;
805 SourceFile
->FileBufferPtr
++;
806 SourceFile
->FileBufferPtr
[0] = T_CHAR_SPACE
;
807 SourceFile
->FileBufferPtr
++;
808 SlashSlashComment
= FALSE
;
811 SourceFile
->FileBufferPtr
++;
815 // Could check for end-of-file and still in a comment, but
816 // should not be necessary. So just restore the file pointers.
818 RewindFile (SourceFile
);
820 // Dump the reformatted file if verbose mode
822 if (mGlobals
.VerboseFile
) {
824 printf ("%04d: ", LineNum
);
825 while (!EndOfFile (SourceFile
)) {
826 if (SourceFile
->FileBufferPtr
[0] == T_CHAR_LF
) {
827 printf ("'\n%04d: '", ++LineNum
);
829 printf ("%c", SourceFile
->FileBufferPtr
[0]);
832 SourceFile
->FileBufferPtr
++;
836 printf ("FileSize = %d (0x%X)\n", SourceFile
->FileSize
, SourceFile
->FileSize
);
837 RewindFile (SourceFile
);
849 Retrieve a quoted-string from the input file.
852 Str - pointer to a copy of the quoted string parsed
853 Length - size of buffer pointed to by Str
856 TRUE - next token in input stream was a quoted string, and
857 the string value was returned in Str
862 SkipWhiteSpace (&mGlobals
.SourceFile
);
863 if (EndOfFile (&mGlobals
.SourceFile
)) {
867 if (mGlobals
.SourceFile
.FileBufferPtr
[0] == T_CHAR_DOUBLE_QUOTE
) {
868 mGlobals
.SourceFile
.FileBufferPtr
++;
870 if (EndOfFile (&mGlobals
.SourceFile
)) {
874 // Check for closing quote
876 if (mGlobals
.SourceFile
.FileBufferPtr
[0] == T_CHAR_DOUBLE_QUOTE
) {
877 mGlobals
.SourceFile
.FileBufferPtr
++;
882 *Str
= mGlobals
.SourceFile
.FileBufferPtr
[0];
885 mGlobals
.SourceFile
.FileBufferPtr
++;
889 // First character was not a quote, or the input string length was
890 // insufficient to contain the quoted string, so return failure code.
902 Return TRUE of FALSE to indicate whether or not we've reached the end of the
914 SkipWhiteSpace (&mGlobals
.SourceFile
);
915 return EndOfFile (&mGlobals
.SourceFile
);
922 SOURCE_FILE
*SourceFile
,
930 BOOLEAN PreviousBackslash
;
932 if (SourceFile
->FileBufferPtr
[0] != T_CHAR_DOUBLE_QUOTE
) {
933 if (Optional
== FALSE
) {
934 Error (SourceFile
->FileName
, SourceFile
->LineNum
, 0, "expected quoted string", "%S", SourceFile
->FileBufferPtr
);
941 SourceFile
->FileBufferPtr
++;
942 Start
= Ptr
= SourceFile
->FileBufferPtr
;
943 PreviousBackslash
= FALSE
;
944 while (!EndOfFile (SourceFile
)) {
945 if ((SourceFile
->FileBufferPtr
[0] == T_CHAR_DOUBLE_QUOTE
) && (PreviousBackslash
== FALSE
)) {
947 } else if (SourceFile
->FileBufferPtr
[0] == T_CHAR_CR
) {
948 Warning (SourceFile
->FileName
, SourceFile
->LineNum
, 0, "carriage return found in quoted string", "%S", Start
);
949 PreviousBackslash
= FALSE
;
950 } else if (SourceFile
->FileBufferPtr
[0] == T_CHAR_BACKSLASH
) {
951 PreviousBackslash
= TRUE
;
953 PreviousBackslash
= FALSE
;
956 SourceFile
->FileBufferPtr
++;
960 if (SourceFile
->FileBufferPtr
[0] != T_CHAR_DOUBLE_QUOTE
) {
961 Warning (SourceFile
->FileName
, SourceFile
->LineNum
, 0, "missing closing quote on string", "%S", Start
);
963 SourceFile
->FileBufferPtr
++;
966 // Now allocate memory for the string and save it off
968 String
= (T_CHAR
*) malloc ((Len
+ 1) * sizeof (T_CHAR
));
969 if (String
== NULL
) {
970 Error (NULL
, 0, 0, "memory allocation failed", NULL
);
974 // Copy the string from the file buffer to the local copy.
975 // We do no reformatting of it whatsoever at this point.
992 SOURCE_FILE
*SourceFile
996 // The file buffer pointer will typically get updated before the End-of-file flag in the
997 // source file structure, so check it first.
999 if (SourceFile
->FileBufferPtr
>= SourceFile
->FileBuffer
+ SourceFile
->FileSize
/ sizeof (T_CHAR
)) {
1000 SourceFile
->EndOfFile
= TRUE
;
1004 if (SourceFile
->EndOfFile
) {
1014 ProcessTokenInclude (
1015 SOURCE_FILE
*SourceFile
1018 char IncludeFileName
[MAX_PATH
];
1021 BOOLEAN ReportedError
;
1022 SOURCE_FILE IncludedSourceFile
;
1024 ReportedError
= FALSE
;
1025 if (SkipWhiteSpace (SourceFile
) == 0) {
1026 Warning (SourceFile
->FileName
, SourceFile
->LineNum
, 0, "expected whitespace following #include keyword", NULL
);
1029 // Should be quoted file name
1031 if (SourceFile
->FileBufferPtr
[0] != T_CHAR_DOUBLE_QUOTE
) {
1032 Error (SourceFile
->FileName
, SourceFile
->LineNum
, 0, "expected quoted include file name", NULL
);
1036 SourceFile
->FileBufferPtr
++;
1038 // Copy the filename as ascii to our local string
1040 To
= IncludeFileName
;
1042 while (!EndOfFile (SourceFile
)) {
1043 if ((SourceFile
->FileBufferPtr
[0] == T_CHAR_CR
) || (SourceFile
->FileBufferPtr
[0] == T_CHAR_LF
)) {
1044 Error (SourceFile
->FileName
, SourceFile
->LineNum
, 0, "end-of-line found in quoted include file name", NULL
);
1048 if (SourceFile
->FileBufferPtr
[0] == T_CHAR_DOUBLE_QUOTE
) {
1049 SourceFile
->FileBufferPtr
++;
1053 // If too long, then report the error once and process until the closing quote
1056 if (!ReportedError
&& (Len
>= sizeof (IncludeFileName
))) {
1057 Error (SourceFile
->FileName
, SourceFile
->LineNum
, 0, "length of include file name exceeds limit", NULL
);
1058 ReportedError
= TRUE
;
1061 if (!ReportedError
) {
1062 *To
= (T_CHAR
) SourceFile
->FileBufferPtr
[0];
1066 SourceFile
->FileBufferPtr
++;
1069 if (!ReportedError
) {
1071 memset ((char *) &IncludedSourceFile
, 0, sizeof (SOURCE_FILE
));
1072 strcpy (IncludedSourceFile
.FileName
, IncludeFileName
);
1073 ProcessIncludeFile (&IncludedSourceFile
, SourceFile
);
1079 // Error recovery -- skip to next #
1081 SourceFile
->SkipToHash
= TRUE
;
1087 SOURCE_FILE
*SourceFile
1090 switch (*SourceFile
->FileBufferPtr
) {
1105 SOURCE_FILE
*SourceFile
1111 while (!EndOfFile (SourceFile
)) {
1113 switch (*SourceFile
->FileBufferPtr
) {
1118 SourceFile
->FileBufferPtr
++;
1122 SourceFile
->FileBufferPtr
++;
1123 SourceFile
->LineNum
++;
1131 // Some tokens require trailing whitespace. If we're at the end of the
1132 // file, then we count that as well.
1134 if ((Count
== 0) && (EndOfFile (SourceFile
))) {
1149 Routine Description:
1150 Compare two strings for equality. The string pointed to by 'Buffer' may or may not be null-terminated,
1151 so only compare up to the length of Str.
1154 Buffer - pointer to first (possibly not null-terminated) string
1155 Str - pointer to null-terminated string to compare to Buffer
1158 Number of bytes matched if exact match
1159 0 if Buffer does not start with Str
1166 while (*Str
&& (*Str
== *Buffer
)) {
1204 if (*Str1
!= *Str2
) {
1238 SOURCE_FILE
*SourceFile
1241 SourceFile
->LineNum
= 1;
1242 SourceFile
->FileBufferPtr
= SourceFile
->FileBuffer
;
1243 SourceFile
->EndOfFile
= 0;
1255 while (!EndOfFile (&mGlobals
.SourceFile
) && (BufferLen
> 0)) {
1256 if (isxdigit (mGlobals
.SourceFile
.FileBufferPtr
[0])) {
1257 *Buffer
= mGlobals
.SourceFile
.FileBufferPtr
[0];
1261 mGlobals
.SourceFile
.FileBufferPtr
++;
1267 // Null terminate if we can
1269 if ((Len
> 0) && (BufferLen
> 0)) {
1283 Routine Description:
1284 Parse a GUID from the input stream. Stop when you discover white space.
1287 GuidStyle - Style of the following GUID token
1288 Value - pointer to EFI_GUID struct for output
1291 TRUE - GUID string parsed successfully
1295 Style[0] 12345678-1234-5678-AAAA-BBBBCCCCDDDD
1302 T_CHAR TempString
[20];
1303 T_CHAR TempString2
[3];
1311 // Skip white space, then start parsing
1313 SkipWhiteSpace (&mGlobals
.SourceFile
);
1314 GetFilePosition (&FPos
);
1315 if (EndOfFile (&mGlobals
.SourceFile
)) {
1319 if (GuidStyle
== PARSE_GUID_STYLE_5_FIELDS
) {
1321 // Style[0] 12345678-1234-5678-AAAA-BBBBCCCCDDDD
1323 Len
= GetHexChars (TempString
, sizeof (TempString
));
1324 if ((Len
== 0) || (Len
> 8)) {
1328 sscanf (TempString
, "%x", &Value32
);
1329 Value
->Data1
= Value32
;
1331 // Next two UINT16 fields
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
->Data2
= (UINT16
) Value32
;
1346 if (mGlobals
.SourceFile
.FileBufferPtr
[0] != '-') {
1350 mGlobals
.SourceFile
.FileBufferPtr
++;
1351 Len
= GetHexChars (TempString
, sizeof (TempString
));
1352 if ((Len
== 0) || (Len
> 4)) {
1356 sscanf (TempString
, "%x", &Value32
);
1357 Value
->Data3
= (UINT16
) Value32
;
1359 // Parse the "AAAA" as two bytes
1361 if (mGlobals
.SourceFile
.FileBufferPtr
[0] != '-') {
1365 mGlobals
.SourceFile
.FileBufferPtr
++;
1366 Len
= GetHexChars (TempString
, sizeof (TempString
));
1367 if ((Len
== 0) || (Len
> 4)) {
1371 sscanf (TempString
, "%x", &Value32
);
1372 Value
->Data4
[0] = (UINT8
) (Value32
>> 8);
1373 Value
->Data4
[1] = (UINT8
) Value32
;
1374 if (mGlobals
.SourceFile
.FileBufferPtr
[0] != '-') {
1378 mGlobals
.SourceFile
.FileBufferPtr
++;
1380 // Read the last 6 bytes of the GUID
1383 Len
= GetHexChars (TempString
, sizeof (TempString
));
1384 if ((Len
== 0) || (Len
> 12)) {
1388 // Insert leading 0's to make life easier
1391 From
= TempString
+ Len
- 1;
1392 To
= TempString
+ 11;
1394 while (From
>= TempString
) {
1400 while (To
>= TempString
) {
1406 // Now parse each byte
1409 for (Index
= 0; Index
< 6; Index
++) {
1411 // Copy the two characters from the input string to something
1414 TempString2
[0] = TempString
[Index
* 2];
1415 TempString2
[1] = TempString
[Index
* 2 + 1];
1416 sscanf (TempString2
, "%x", &Value32
);
1417 Value
->Data4
[Index
+ 2] = (UINT8
) Value32
;
1423 // Unsupported GUID style
1429 if (Status
== FALSE
) {
1430 SetFilePosition (&FPos
);
1442 Fpos
->FileBufferPtr
= mGlobals
.SourceFile
.FileBufferPtr
;
1443 return STATUS_SUCCESS
;
1453 // Should check range of pointer
1455 mGlobals
.SourceFile
.FileBufferPtr
= Fpos
->FileBufferPtr
;
1456 return STATUS_SUCCESS
;