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.
30 #include "EfiUtilityMsgs.h"
31 #include "SimpleFileParsing.h"
37 // just in case we get in an endless loop.
39 #define MAX_NEST_DEPTH 20
43 #define MAX_STRING_IDENTIFIER_NAME 100
45 #define MAX_LINE_LEN 400
47 #define T_CHAR_SPACE ' '
49 #define T_CHAR_CR '\r'
50 #define T_CHAR_TAB '\t'
51 #define T_CHAR_LF '\n'
52 #define T_CHAR_SLASH '/'
53 #define T_CHAR_BACKSLASH '\\'
54 #define T_CHAR_DOUBLE_QUOTE '"'
55 #define T_CHAR_LC_X 'x'
57 #define T_CHAR_STAR '*'
60 // We keep a linked list of these for the source files we process
62 typedef struct _SOURCE_FILE
{
65 T_CHAR
*FileBufferPtr
;
66 unsigned int FileSize
;
67 char FileName
[MAX_PATH
];
71 struct _SOURCE_FILE
*Previous
;
72 struct _SOURCE_FILE
*Next
;
73 T_CHAR ControlCharacter
;
77 T_CHAR
*FileBufferPtr
;
81 // Keep all our module globals in this structure
84 SOURCE_FILE SourceFile
;
113 SOURCE_FILE
*SourceFile
119 SOURCE_FILE
*SourceFile
125 SOURCE_FILE
*SourceFile
131 SOURCE_FILE
*SourceFile
137 SOURCE_FILE
*SourceFile
150 SOURCE_FILE
*SourceFile
,
151 SOURCE_FILE
*ParentSourceFile
157 SOURCE_FILE
*SourceFile
165 unsigned int FoundFileNameLen
171 SOURCE_FILE
*SourceFile
198 STATUS_SUCCESS always
202 memset ((void *) &mGlobals
, 0, sizeof (mGlobals
));
203 return STATUS_SUCCESS
;
214 Return the line number of the file we're parsing. Used
215 for error reporting purposes.
221 The line number, or 0 if no file is being processed
225 return mGlobals
.SourceFile
.LineNum
;
235 Return the name of the file we're parsing. Used
236 for error reporting purposes.
242 A pointer to the file name. Null if no file is being
247 if (mGlobals
.SourceFile
.FileName
[0]) {
248 return mGlobals
.SourceFile
.FileName
;
261 Open a file for parsing.
264 FileName - name of the file to parse
272 t_strcpy (mGlobals
.SourceFile
.FileName
, FileName
);
273 Status
= ProcessIncludeFile (&mGlobals
.SourceFile
, NULL
);
284 Check to see if the specified token is found at
285 the current position in the input file.
288 Str - the token to look for
291 TRUE - the token is next
292 FALSE - the token is not next
295 We do a simple string comparison on this function. It is
296 the responsibility of the caller to ensure that the token
297 is not a subset of some other token.
299 The file pointer is advanced past the token in the input file.
304 SkipWhiteSpace (&mGlobals
.SourceFile
);
305 if (EndOfFile (&mGlobals
.SourceFile
)) {
309 if ((Len
= t_strcmp (mGlobals
.SourceFile
.FileBufferPtr
, Str
)) > 0) {
310 mGlobals
.SourceFile
.FileBufferPtr
+= Len
;
311 if (mGlobals
.VerboseToken
) {
312 printf ("Token: '%s'\n", Str
);
328 Check to see if the specified keyword is found at
329 the current position in the input file.
332 Str - keyword to look for
335 TRUE - the keyword is next
336 FALSE - the keyword is not next
339 A keyword is defined as a "special" string that has a non-alphanumeric
340 character following it.
345 SkipWhiteSpace (&mGlobals
.SourceFile
);
346 if (EndOfFile (&mGlobals
.SourceFile
)) {
350 if ((Len
= t_strcmp (mGlobals
.SourceFile
.FileBufferPtr
, Str
)) > 0) {
351 if (isalnum (mGlobals
.SourceFile
.FileBufferPtr
[Len
])) {
355 mGlobals
.SourceFile
.FileBufferPtr
+= Len
;
356 if (mGlobals
.VerboseToken
) {
357 printf ("Token: '%s'\n", Str
);
374 Get the next token from the input stream.
377 Str - pointer to a copy of the next token
378 Len - size of buffer pointed to by Str
381 TRUE - next token successfully returned
385 Preceeding white space is ignored.
386 The parser's buffer pointer is advanced past the end of the
394 SkipWhiteSpace (&mGlobals
.SourceFile
);
395 if (EndOfFile (&mGlobals
.SourceFile
)) {
399 // Have to have enough string for at least one char and a null-terminator
405 // Look at the first character. If it's an identifier, then treat it
408 TempChar
= mGlobals
.SourceFile
.FileBufferPtr
[0];
409 if (((TempChar
>= 'a') && (TempChar
<= 'z')) || ((TempChar
>= 'A') && (TempChar
<= 'Z')) || (TempChar
== '_')) {
411 mGlobals
.SourceFile
.FileBufferPtr
++;
413 while (!EndOfFile (&mGlobals
.SourceFile
) && (Index
< Len
)) {
414 TempChar
= mGlobals
.SourceFile
.FileBufferPtr
[0];
415 if (((TempChar
>= 'a') && (TempChar
<= 'z')) ||
416 ((TempChar
>= 'A') && (TempChar
<= 'Z')) ||
417 ((TempChar
>= '0') && (TempChar
<= '9')) ||
420 Str
[Index
] = mGlobals
.SourceFile
.FileBufferPtr
[0];
421 mGlobals
.SourceFile
.FileBufferPtr
++;
425 // Invalid character for symbol name, so break out
431 // Null terminate and return success
435 } else if ((TempChar
== ')') || (TempChar
== '(') || (TempChar
== '*')) {
436 Str
[0] = mGlobals
.SourceFile
.FileBufferPtr
[0];
437 mGlobals
.SourceFile
.FileBufferPtr
++;
442 // Everything else is white-space (or EOF) separated
445 while (!EndOfFile (&mGlobals
.SourceFile
) && (Index
< Len
)) {
446 if (IsWhiteSpace (&mGlobals
.SourceFile
)) {
454 Str
[Index
] = mGlobals
.SourceFile
.FileBufferPtr
[0];
455 mGlobals
.SourceFile
.FileBufferPtr
++;
460 // See if we just ran out of file contents, but did find a token
462 if ((Index
> 0) && EndOfFile (&mGlobals
.SourceFile
)) {
479 Parse a GUID from the input stream. Stop when you discover white space.
482 Str - pointer to a copy of the next token
483 Len - size of buffer pointed to by Str
486 TRUE - GUID string returned successfully
492 SkipWhiteSpace (&mGlobals
.SourceFile
);
493 if (EndOfFile (&mGlobals
.SourceFile
)) {
498 while (!EndOfFile (&mGlobals
.SourceFile
) && (Index
< Len
)) {
499 if (IsWhiteSpace (&mGlobals
.SourceFile
)) {
507 Str
[Index
] = mGlobals
.SourceFile
.FileBufferPtr
[0];
508 mGlobals
.SourceFile
.FileBufferPtr
++;
523 Len
= t_strlen (Str
);
524 SavePos
= mGlobals
.SourceFile
.FileBufferPtr
;
525 SkipWhiteSpace (&mGlobals
.SourceFile
);
526 while (!EndOfFile (&mGlobals
.SourceFile
)) {
527 if (t_strncmp (Str
, mGlobals
.SourceFile
.FileBufferPtr
, Len
) == 0) {
528 mGlobals
.SourceFile
.FileBufferPtr
+= Len
;
532 mGlobals
.SourceFile
.FileBufferPtr
++;
533 SkipWhiteSpace (&mGlobals
.SourceFile
);
536 mGlobals
.SourceFile
.FileBufferPtr
= SavePos
;
547 Check the token at the current file position for a numeric value.
548 May be either decimal or hex.
551 Value - pointer where to store the value
554 FALSE - current token is not a number
555 TRUE - current token is a number
559 SkipWhiteSpace (&mGlobals
.SourceFile
);
560 if (EndOfFile (&mGlobals
.SourceFile
)) {
564 if (isdigit (mGlobals
.SourceFile
.FileBufferPtr
[0])) {
566 // Check for hex value
568 if ((mGlobals
.SourceFile
.FileBufferPtr
[0] == T_CHAR_0
) && (mGlobals
.SourceFile
.FileBufferPtr
[1] == T_CHAR_LC_X
)) {
569 if (!isxdigit (mGlobals
.SourceFile
.FileBufferPtr
[2])) {
573 mGlobals
.SourceFile
.FileBufferPtr
+= 2;
574 sscanf (mGlobals
.SourceFile
.FileBufferPtr
, "%x", Value
);
575 while (isxdigit (mGlobals
.SourceFile
.FileBufferPtr
[0])) {
576 mGlobals
.SourceFile
.FileBufferPtr
++;
581 *Value
= atoi (mGlobals
.SourceFile
.FileBufferPtr
);
582 while (isdigit (mGlobals
.SourceFile
.FileBufferPtr
[0])) {
583 mGlobals
.SourceFile
.FileBufferPtr
++;
600 Close the file being parsed.
606 STATUS_SUCCESS - the file was closed
607 STATUS_ERROR - no file is currently open
611 if (mGlobals
.SourceFile
.FileBuffer
!= NULL
) {
612 free (mGlobals
.SourceFile
.FileBuffer
);
613 memset (&mGlobals
.SourceFile
, 0, sizeof (mGlobals
.SourceFile
));
614 return STATUS_SUCCESS
;
623 SOURCE_FILE
*SourceFile
,
624 SOURCE_FILE
*ParentSourceFile
630 Given a source file, open the file and parse it
634 SourceFile - name of file to parse
635 ParentSourceFile - for error reporting purposes, the file that #included SourceFile.
643 static unsigned int NestDepth
= 0;
644 char FoundFileName
[MAX_PATH
];
647 Status
= STATUS_SUCCESS
;
650 // Print the file being processed. Indent so you can tell the include nesting
653 if (mGlobals
.VerboseFile
) {
654 fprintf (stdout
, "%*cProcessing file '%s'\n", NestDepth
* 2, ' ', SourceFile
->FileName
);
655 fprintf (stdout
, "Parent source file = '%s'\n", ParentSourceFile
);
659 // Make sure we didn't exceed our maximum nesting depth
661 if (NestDepth
> MAX_NEST_DEPTH
) {
662 Error (NULL
, 0, 0, SourceFile
->FileName
, "max nesting depth (%d) exceeded", NestDepth
);
663 Status
= STATUS_ERROR
;
667 // Try to open the file locally, and if that fails try along our include paths.
669 strcpy (FoundFileName
, SourceFile
->FileName
);
670 if ((SourceFile
->Fptr
= fopen (FoundFileName
, "rb")) == NULL
) {
674 // Process the file found
676 ProcessFile (SourceFile
);
679 // Close open files and return status
681 if (SourceFile
->Fptr
!= NULL
) {
682 fclose (SourceFile
->Fptr
);
683 SourceFile
->Fptr
= NULL
;
692 SOURCE_FILE
*SourceFile
698 Given a source file that's been opened, read the contents into an internal
699 buffer and pre-process it to remove comments.
703 SourceFile - structure containing info on the file to process
712 // Get the file size, and then read the entire thing into memory.
713 // Allocate extra space for a terminator character.
715 fseek (SourceFile
->Fptr
, 0, SEEK_END
);
716 SourceFile
->FileSize
= ftell (SourceFile
->Fptr
);
717 if (mGlobals
.VerboseFile
) {
718 printf ("FileSize = %d (0x%X)\n", SourceFile
->FileSize
, SourceFile
->FileSize
);
721 fseek (SourceFile
->Fptr
, 0, SEEK_SET
);
722 SourceFile
->FileBuffer
= (T_CHAR
*) malloc (SourceFile
->FileSize
+ sizeof (T_CHAR
));
723 if (SourceFile
->FileBuffer
== NULL
) {
724 Error (NULL
, 0, 0, "memory allocation failure", NULL
);
728 fread ((void *) SourceFile
->FileBuffer
, SourceFile
->FileSize
, 1, SourceFile
->Fptr
);
729 SourceFile
->FileBuffer
[(SourceFile
->FileSize
/ sizeof (T_CHAR
))] = T_CHAR_NULL
;
731 // Pre-process the file to replace comments with spaces
733 PreprocessFile (SourceFile
);
734 SourceFile
->LineNum
= 1;
735 return STATUS_SUCCESS
;
741 SOURCE_FILE
*SourceFile
746 Preprocess a file to replace all carriage returns with NULLs so
747 we can print lines (as part of error messages) from the file to the screen.
750 SourceFile - structure that we use to keep track of an input file.
758 BOOLEAN SlashSlashComment
;
761 RewindFile (SourceFile
);
763 SlashSlashComment
= FALSE
;
764 while (!EndOfFile (SourceFile
)) {
766 // If a line-feed, then no longer in a comment if we're in a // comment
768 if (SourceFile
->FileBufferPtr
[0] == T_CHAR_LF
) {
769 SourceFile
->FileBufferPtr
++;
770 SourceFile
->LineNum
++;
771 if (InComment
&& SlashSlashComment
) {
773 SlashSlashComment
= FALSE
;
775 } else if (SourceFile
->FileBufferPtr
[0] == T_CHAR_CR
) {
777 // Replace all carriage returns with a NULL so we can print stuff
779 SourceFile
->FileBufferPtr
[0] = 0;
780 SourceFile
->FileBufferPtr
++;
782 // Check for */ comment end
784 } else if (InComment
&&
785 !SlashSlashComment
&&
786 (SourceFile
->FileBufferPtr
[0] == T_CHAR_STAR
) &&
787 (SourceFile
->FileBufferPtr
[1] == T_CHAR_SLASH
)
789 SourceFile
->FileBufferPtr
[0] = T_CHAR_SPACE
;
790 SourceFile
->FileBufferPtr
++;
791 SourceFile
->FileBufferPtr
[0] = T_CHAR_SPACE
;
792 SourceFile
->FileBufferPtr
++;
794 } else if (InComment
) {
795 SourceFile
->FileBufferPtr
[0] = T_CHAR_SPACE
;
796 SourceFile
->FileBufferPtr
++;
798 // Check for // comments
800 } else if ((SourceFile
->FileBufferPtr
[0] == T_CHAR_SLASH
) && (SourceFile
->FileBufferPtr
[1] == T_CHAR_SLASH
)) {
802 SlashSlashComment
= TRUE
;
804 // Check for /* comment start
806 } else if ((SourceFile
->FileBufferPtr
[0] == T_CHAR_SLASH
) && (SourceFile
->FileBufferPtr
[1] == T_CHAR_STAR
)) {
807 SourceFile
->FileBufferPtr
[0] = T_CHAR_SPACE
;
808 SourceFile
->FileBufferPtr
++;
809 SourceFile
->FileBufferPtr
[0] = T_CHAR_SPACE
;
810 SourceFile
->FileBufferPtr
++;
811 SlashSlashComment
= FALSE
;
814 SourceFile
->FileBufferPtr
++;
818 // Could check for end-of-file and still in a comment, but
819 // should not be necessary. So just restore the file pointers.
821 RewindFile (SourceFile
);
823 // Dump the reformatted file if verbose mode
825 if (mGlobals
.VerboseFile
) {
827 printf ("%04d: ", LineNum
);
828 while (!EndOfFile (SourceFile
)) {
829 if (SourceFile
->FileBufferPtr
[0] == T_CHAR_LF
) {
830 printf ("'\n%04d: '", ++LineNum
);
832 printf ("%c", SourceFile
->FileBufferPtr
[0]);
835 SourceFile
->FileBufferPtr
++;
839 printf ("FileSize = %d (0x%X)\n", SourceFile
->FileSize
, SourceFile
->FileSize
);
840 RewindFile (SourceFile
);
852 Retrieve a quoted-string from the input file.
855 Str - pointer to a copy of the quoted string parsed
856 Length - size of buffer pointed to by Str
859 TRUE - next token in input stream was a quoted string, and
860 the string value was returned in Str
865 SkipWhiteSpace (&mGlobals
.SourceFile
);
866 if (EndOfFile (&mGlobals
.SourceFile
)) {
870 if (mGlobals
.SourceFile
.FileBufferPtr
[0] == T_CHAR_DOUBLE_QUOTE
) {
871 mGlobals
.SourceFile
.FileBufferPtr
++;
873 if (EndOfFile (&mGlobals
.SourceFile
)) {
877 // Check for closing quote
879 if (mGlobals
.SourceFile
.FileBufferPtr
[0] == T_CHAR_DOUBLE_QUOTE
) {
880 mGlobals
.SourceFile
.FileBufferPtr
++;
885 *Str
= mGlobals
.SourceFile
.FileBufferPtr
[0];
888 mGlobals
.SourceFile
.FileBufferPtr
++;
892 // First character was not a quote, or the input string length was
893 // insufficient to contain the quoted string, so return failure code.
905 Return TRUE of FALSE to indicate whether or not we've reached the end of the
917 SkipWhiteSpace (&mGlobals
.SourceFile
);
918 return EndOfFile (&mGlobals
.SourceFile
);
925 SOURCE_FILE
*SourceFile
,
933 BOOLEAN PreviousBackslash
;
935 if (SourceFile
->FileBufferPtr
[0] != T_CHAR_DOUBLE_QUOTE
) {
936 if (Optional
== FALSE
) {
937 Error (SourceFile
->FileName
, SourceFile
->LineNum
, 0, "expected quoted string", "%S", SourceFile
->FileBufferPtr
);
944 SourceFile
->FileBufferPtr
++;
945 Start
= Ptr
= SourceFile
->FileBufferPtr
;
946 PreviousBackslash
= FALSE
;
947 while (!EndOfFile (SourceFile
)) {
948 if ((SourceFile
->FileBufferPtr
[0] == T_CHAR_DOUBLE_QUOTE
) && (PreviousBackslash
== FALSE
)) {
950 } else if (SourceFile
->FileBufferPtr
[0] == T_CHAR_CR
) {
951 Warning (SourceFile
->FileName
, SourceFile
->LineNum
, 0, "carriage return found in quoted string", "%S", Start
);
952 PreviousBackslash
= FALSE
;
953 } else if (SourceFile
->FileBufferPtr
[0] == T_CHAR_BACKSLASH
) {
954 PreviousBackslash
= TRUE
;
956 PreviousBackslash
= FALSE
;
959 SourceFile
->FileBufferPtr
++;
963 if (SourceFile
->FileBufferPtr
[0] != T_CHAR_DOUBLE_QUOTE
) {
964 Warning (SourceFile
->FileName
, SourceFile
->LineNum
, 0, "missing closing quote on string", "%S", Start
);
966 SourceFile
->FileBufferPtr
++;
969 // Now allocate memory for the string and save it off
971 String
= (T_CHAR
*) malloc ((Len
+ 1) * sizeof (T_CHAR
));
972 if (String
== NULL
) {
973 Error (NULL
, 0, 0, "memory allocation failed", NULL
);
977 // Copy the string from the file buffer to the local copy.
978 // We do no reformatting of it whatsoever at this point.
995 SOURCE_FILE
*SourceFile
999 // The file buffer pointer will typically get updated before the End-of-file flag in the
1000 // source file structure, so check it first.
1002 if (SourceFile
->FileBufferPtr
>= SourceFile
->FileBuffer
+ SourceFile
->FileSize
/ sizeof (T_CHAR
)) {
1003 SourceFile
->EndOfFile
= TRUE
;
1007 if (SourceFile
->EndOfFile
) {
1017 ProcessTokenInclude (
1018 SOURCE_FILE
*SourceFile
1021 char IncludeFileName
[MAX_PATH
];
1024 BOOLEAN ReportedError
;
1025 SOURCE_FILE IncludedSourceFile
;
1027 ReportedError
= FALSE
;
1028 if (SkipWhiteSpace (SourceFile
) == 0) {
1029 Warning (SourceFile
->FileName
, SourceFile
->LineNum
, 0, "expected whitespace following #include keyword", NULL
);
1032 // Should be quoted file name
1034 if (SourceFile
->FileBufferPtr
[0] != T_CHAR_DOUBLE_QUOTE
) {
1035 Error (SourceFile
->FileName
, SourceFile
->LineNum
, 0, "expected quoted include file name", NULL
);
1039 SourceFile
->FileBufferPtr
++;
1041 // Copy the filename as ascii to our local string
1043 To
= IncludeFileName
;
1045 while (!EndOfFile (SourceFile
)) {
1046 if ((SourceFile
->FileBufferPtr
[0] == T_CHAR_CR
) || (SourceFile
->FileBufferPtr
[0] == T_CHAR_LF
)) {
1047 Error (SourceFile
->FileName
, SourceFile
->LineNum
, 0, "end-of-line found in quoted include file name", NULL
);
1051 if (SourceFile
->FileBufferPtr
[0] == T_CHAR_DOUBLE_QUOTE
) {
1052 SourceFile
->FileBufferPtr
++;
1056 // If too long, then report the error once and process until the closing quote
1059 if (!ReportedError
&& (Len
>= sizeof (IncludeFileName
))) {
1060 Error (SourceFile
->FileName
, SourceFile
->LineNum
, 0, "length of include file name exceeds limit", NULL
);
1061 ReportedError
= TRUE
;
1064 if (!ReportedError
) {
1065 *To
= (T_CHAR
) SourceFile
->FileBufferPtr
[0];
1069 SourceFile
->FileBufferPtr
++;
1072 if (!ReportedError
) {
1074 memset ((char *) &IncludedSourceFile
, 0, sizeof (SOURCE_FILE
));
1075 strcpy (IncludedSourceFile
.FileName
, IncludeFileName
);
1076 ProcessIncludeFile (&IncludedSourceFile
, SourceFile
);
1082 // Error recovery -- skip to next #
1084 SourceFile
->SkipToHash
= TRUE
;
1090 SOURCE_FILE
*SourceFile
1093 switch (*SourceFile
->FileBufferPtr
) {
1108 SOURCE_FILE
*SourceFile
1114 while (!EndOfFile (SourceFile
)) {
1116 switch (*SourceFile
->FileBufferPtr
) {
1121 SourceFile
->FileBufferPtr
++;
1125 SourceFile
->FileBufferPtr
++;
1126 SourceFile
->LineNum
++;
1134 // Some tokens require trailing whitespace. If we're at the end of the
1135 // file, then we count that as well.
1137 if ((Count
== 0) && (EndOfFile (SourceFile
))) {
1152 Routine Description:
1153 Compare two strings for equality. The string pointed to by 'Buffer' may or may not be null-terminated,
1154 so only compare up to the length of Str.
1157 Buffer - pointer to first (possibly not null-terminated) string
1158 Str - pointer to null-terminated string to compare to Buffer
1161 Number of bytes matched if exact match
1162 0 if Buffer does not start with Str
1169 while (*Str
&& (*Str
== *Buffer
)) {
1207 if (*Str1
!= *Str2
) {
1241 SOURCE_FILE
*SourceFile
1244 SourceFile
->LineNum
= 1;
1245 SourceFile
->FileBufferPtr
= SourceFile
->FileBuffer
;
1246 SourceFile
->EndOfFile
= 0;
1258 while (!EndOfFile (&mGlobals
.SourceFile
) && (BufferLen
> 0)) {
1259 if (isxdigit (mGlobals
.SourceFile
.FileBufferPtr
[0])) {
1260 *Buffer
= mGlobals
.SourceFile
.FileBufferPtr
[0];
1264 mGlobals
.SourceFile
.FileBufferPtr
++;
1270 // Null terminate if we can
1272 if ((Len
> 0) && (BufferLen
> 0)) {
1286 Routine Description:
1287 Parse a GUID from the input stream. Stop when you discover white space.
1290 GuidStyle - Style of the following GUID token
1291 Value - pointer to EFI_GUID struct for output
1294 TRUE - GUID string parsed successfully
1298 Style[0] 12345678-1234-5678-AAAA-BBBBCCCCDDDD
1305 T_CHAR TempString
[20];
1306 T_CHAR TempString2
[3];
1314 // Skip white space, then start parsing
1316 SkipWhiteSpace (&mGlobals
.SourceFile
);
1317 GetFilePosition (&FPos
);
1318 if (EndOfFile (&mGlobals
.SourceFile
)) {
1322 if (GuidStyle
== PARSE_GUID_STYLE_5_FIELDS
) {
1324 // Style[0] 12345678-1234-5678-AAAA-BBBBCCCCDDDD
1326 Len
= GetHexChars (TempString
, sizeof (TempString
));
1327 if ((Len
== 0) || (Len
> 8)) {
1331 sscanf (TempString
, "%x", &Value32
);
1332 Value
->Data1
= Value32
;
1334 // Next two UINT16 fields
1336 if (mGlobals
.SourceFile
.FileBufferPtr
[0] != '-') {
1340 mGlobals
.SourceFile
.FileBufferPtr
++;
1341 Len
= GetHexChars (TempString
, sizeof (TempString
));
1342 if ((Len
== 0) || (Len
> 4)) {
1346 sscanf (TempString
, "%x", &Value32
);
1347 Value
->Data2
= (UINT16
) Value32
;
1349 if (mGlobals
.SourceFile
.FileBufferPtr
[0] != '-') {
1353 mGlobals
.SourceFile
.FileBufferPtr
++;
1354 Len
= GetHexChars (TempString
, sizeof (TempString
));
1355 if ((Len
== 0) || (Len
> 4)) {
1359 sscanf (TempString
, "%x", &Value32
);
1360 Value
->Data3
= (UINT16
) Value32
;
1362 // Parse the "AAAA" as two bytes
1364 if (mGlobals
.SourceFile
.FileBufferPtr
[0] != '-') {
1368 mGlobals
.SourceFile
.FileBufferPtr
++;
1369 Len
= GetHexChars (TempString
, sizeof (TempString
));
1370 if ((Len
== 0) || (Len
> 4)) {
1374 sscanf (TempString
, "%x", &Value32
);
1375 Value
->Data4
[0] = (UINT8
) (Value32
>> 8);
1376 Value
->Data4
[1] = (UINT8
) Value32
;
1377 if (mGlobals
.SourceFile
.FileBufferPtr
[0] != '-') {
1381 mGlobals
.SourceFile
.FileBufferPtr
++;
1383 // Read the last 6 bytes of the GUID
1386 Len
= GetHexChars (TempString
, sizeof (TempString
));
1387 if ((Len
== 0) || (Len
> 12)) {
1391 // Insert leading 0's to make life easier
1394 From
= TempString
+ Len
- 1;
1395 To
= TempString
+ 11;
1397 while (From
>= TempString
) {
1403 while (To
>= TempString
) {
1409 // Now parse each byte
1412 for (Index
= 0; Index
< 6; Index
++) {
1414 // Copy the two characters from the input string to something
1417 TempString2
[0] = TempString
[Index
* 2];
1418 TempString2
[1] = TempString
[Index
* 2 + 1];
1419 sscanf (TempString2
, "%x", &Value32
);
1420 Value
->Data4
[Index
+ 2] = (UINT8
) Value32
;
1426 // Unsupported GUID style
1432 if (Status
== FALSE
) {
1433 SetFilePosition (&FPos
);
1445 Fpos
->FileBufferPtr
= mGlobals
.SourceFile
.FileBufferPtr
;
1446 return STATUS_SUCCESS
;
1456 // Should check range of pointer
1458 mGlobals
.SourceFile
.FileBufferPtr
= Fpos
->FileBufferPtr
;
1459 return STATUS_SUCCESS
;