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.
28 #include "EfiUtilityMsgs.h"
29 #include "SimpleFileParsing.h"
33 // just in case we get in an endless loop.
35 #define MAX_NEST_DEPTH 20
39 #define MAX_STRING_IDENTIFIER_NAME 100
41 #define MAX_LINE_LEN 400
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
{
61 T_CHAR
*FileBufferPtr
;
62 unsigned int FileSize
;
63 char FileName
[MAX_PATH
];
67 struct _SOURCE_FILE
*Previous
;
68 struct _SOURCE_FILE
*Next
;
69 T_CHAR ControlCharacter
;
73 T_CHAR
*FileBufferPtr
;
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
161 unsigned int FoundFileNameLen
167 SOURCE_FILE
*SourceFile
194 STATUS_SUCCESS always
198 memset ((void *) &mGlobals
, 0, sizeof (mGlobals
));
199 return STATUS_SUCCESS
;
210 Return the line number of the file we're parsing. Used
211 for error reporting purposes.
217 The line number, or 0 if no file is being processed
221 return mGlobals
.SourceFile
.LineNum
;
231 Return the name of the file we're parsing. Used
232 for error reporting purposes.
238 A pointer to the file name. Null if no file is being
243 if (mGlobals
.SourceFile
.FileName
[0]) {
244 return mGlobals
.SourceFile
.FileName
;
257 Open a file for parsing.
260 FileName - name of the file to parse
268 t_strcpy (mGlobals
.SourceFile
.FileName
, FileName
);
269 Status
= ProcessIncludeFile (&mGlobals
.SourceFile
, NULL
);
280 Check to see if the specified token is found at
281 the current position in the input file.
284 Str - the token to look for
287 TRUE - the token is next
288 FALSE - the token is not next
291 We do a simple string comparison on this function. It is
292 the responsibility of the caller to ensure that the token
293 is not a subset of some other token.
295 The file pointer is advanced past the token in the input file.
300 SkipWhiteSpace (&mGlobals
.SourceFile
);
301 if (EndOfFile (&mGlobals
.SourceFile
)) {
305 if ((Len
= t_strcmp (mGlobals
.SourceFile
.FileBufferPtr
, Str
)) > 0) {
306 mGlobals
.SourceFile
.FileBufferPtr
+= Len
;
307 if (mGlobals
.VerboseToken
) {
308 printf ("Token: '%s'\n", Str
);
324 Check to see if the specified keyword is found at
325 the current position in the input file.
328 Str - keyword to look for
331 TRUE - the keyword is next
332 FALSE - the keyword is not next
335 A keyword is defined as a "special" string that has a non-alphanumeric
336 character following it.
341 SkipWhiteSpace (&mGlobals
.SourceFile
);
342 if (EndOfFile (&mGlobals
.SourceFile
)) {
346 if ((Len
= t_strcmp (mGlobals
.SourceFile
.FileBufferPtr
, Str
)) > 0) {
347 if (isalnum (mGlobals
.SourceFile
.FileBufferPtr
[Len
])) {
351 mGlobals
.SourceFile
.FileBufferPtr
+= Len
;
352 if (mGlobals
.VerboseToken
) {
353 printf ("Token: '%s'\n", Str
);
370 Get the next token from the input stream.
373 Str - pointer to a copy of the next token
374 Len - size of buffer pointed to by Str
377 TRUE - next token successfully returned
381 Preceeding white space is ignored.
382 The parser's buffer pointer is advanced past the end of the
390 SkipWhiteSpace (&mGlobals
.SourceFile
);
391 if (EndOfFile (&mGlobals
.SourceFile
)) {
395 // Have to have enough string for at least one char and a null-terminator
401 // Look at the first character. If it's an identifier, then treat it
404 TempChar
= mGlobals
.SourceFile
.FileBufferPtr
[0];
405 if (((TempChar
>= 'a') && (TempChar
<= 'z')) || ((TempChar
>= 'A') && (TempChar
<= 'Z')) || (TempChar
== '_')) {
407 mGlobals
.SourceFile
.FileBufferPtr
++;
409 while (!EndOfFile (&mGlobals
.SourceFile
) && (Index
< Len
)) {
410 TempChar
= mGlobals
.SourceFile
.FileBufferPtr
[0];
411 if (((TempChar
>= 'a') && (TempChar
<= 'z')) ||
412 ((TempChar
>= 'A') && (TempChar
<= 'Z')) ||
413 ((TempChar
>= '0') && (TempChar
<= '9')) ||
416 Str
[Index
] = mGlobals
.SourceFile
.FileBufferPtr
[0];
417 mGlobals
.SourceFile
.FileBufferPtr
++;
421 // Invalid character for symbol name, so break out
427 // Null terminate and return success
431 } else if ((TempChar
== ')') || (TempChar
== '(') || (TempChar
== '*')) {
432 Str
[0] = mGlobals
.SourceFile
.FileBufferPtr
[0];
433 mGlobals
.SourceFile
.FileBufferPtr
++;
438 // Everything else is white-space (or EOF) separated
441 while (!EndOfFile (&mGlobals
.SourceFile
) && (Index
< Len
)) {
442 if (IsWhiteSpace (&mGlobals
.SourceFile
)) {
450 Str
[Index
] = mGlobals
.SourceFile
.FileBufferPtr
[0];
451 mGlobals
.SourceFile
.FileBufferPtr
++;
456 // See if we just ran out of file contents, but did find a token
458 if ((Index
> 0) && EndOfFile (&mGlobals
.SourceFile
)) {
475 Parse a GUID from the input stream. Stop when you discover white space.
478 Str - pointer to a copy of the next token
479 Len - size of buffer pointed to by Str
482 TRUE - GUID string returned successfully
488 SkipWhiteSpace (&mGlobals
.SourceFile
);
489 if (EndOfFile (&mGlobals
.SourceFile
)) {
494 while (!EndOfFile (&mGlobals
.SourceFile
) && (Index
< Len
)) {
495 if (IsWhiteSpace (&mGlobals
.SourceFile
)) {
503 Str
[Index
] = mGlobals
.SourceFile
.FileBufferPtr
[0];
504 mGlobals
.SourceFile
.FileBufferPtr
++;
519 Len
= t_strlen (Str
);
520 SavePos
= mGlobals
.SourceFile
.FileBufferPtr
;
521 SkipWhiteSpace (&mGlobals
.SourceFile
);
522 while (!EndOfFile (&mGlobals
.SourceFile
)) {
523 if (t_strncmp (Str
, mGlobals
.SourceFile
.FileBufferPtr
, Len
) == 0) {
524 mGlobals
.SourceFile
.FileBufferPtr
+= Len
;
528 mGlobals
.SourceFile
.FileBufferPtr
++;
529 SkipWhiteSpace (&mGlobals
.SourceFile
);
532 mGlobals
.SourceFile
.FileBufferPtr
= SavePos
;
543 Check the token at the current file position for a numeric value.
544 May be either decimal or hex.
547 Value - pointer where to store the value
550 FALSE - current token is not a number
551 TRUE - current token is a number
555 SkipWhiteSpace (&mGlobals
.SourceFile
);
556 if (EndOfFile (&mGlobals
.SourceFile
)) {
560 if (isdigit (mGlobals
.SourceFile
.FileBufferPtr
[0])) {
562 // Check for hex value
564 if ((mGlobals
.SourceFile
.FileBufferPtr
[0] == T_CHAR_0
) && (mGlobals
.SourceFile
.FileBufferPtr
[1] == T_CHAR_LC_X
)) {
565 if (!isxdigit (mGlobals
.SourceFile
.FileBufferPtr
[2])) {
569 mGlobals
.SourceFile
.FileBufferPtr
+= 2;
570 sscanf (mGlobals
.SourceFile
.FileBufferPtr
, "%x", Value
);
571 while (isxdigit (mGlobals
.SourceFile
.FileBufferPtr
[0])) {
572 mGlobals
.SourceFile
.FileBufferPtr
++;
577 *Value
= atoi (mGlobals
.SourceFile
.FileBufferPtr
);
578 while (isdigit (mGlobals
.SourceFile
.FileBufferPtr
[0])) {
579 mGlobals
.SourceFile
.FileBufferPtr
++;
596 Close the file being parsed.
602 STATUS_SUCCESS - the file was closed
603 STATUS_ERROR - no file is currently open
607 if (mGlobals
.SourceFile
.FileBuffer
!= NULL
) {
608 free (mGlobals
.SourceFile
.FileBuffer
);
609 memset (&mGlobals
.SourceFile
, 0, sizeof (mGlobals
.SourceFile
));
610 return STATUS_SUCCESS
;
619 SOURCE_FILE
*SourceFile
,
620 SOURCE_FILE
*ParentSourceFile
626 Given a source file, open the file and parse it
630 SourceFile - name of file to parse
631 ParentSourceFile - for error reporting purposes, the file that #included SourceFile.
639 static unsigned int NestDepth
= 0;
640 char FoundFileName
[MAX_PATH
];
643 Status
= STATUS_SUCCESS
;
646 // Print the file being processed. Indent so you can tell the include nesting
649 if (mGlobals
.VerboseFile
) {
650 fprintf (stdout
, "%*cProcessing file '%s'\n", NestDepth
* 2, ' ', SourceFile
->FileName
);
651 fprintf (stdout
, "Parent source file = '%s'\n", ParentSourceFile
);
655 // Make sure we didn't exceed our maximum nesting depth
657 if (NestDepth
> MAX_NEST_DEPTH
) {
658 Error (NULL
, 0, 0, SourceFile
->FileName
, "max nesting depth (%d) exceeded", NestDepth
);
659 Status
= STATUS_ERROR
;
663 // Try to open the file locally, and if that fails try along our include paths.
665 strcpy (FoundFileName
, SourceFile
->FileName
);
666 if ((SourceFile
->Fptr
= fopen (FoundFileName
, "rb")) == NULL
) {
670 // Process the file found
672 ProcessFile (SourceFile
);
675 // Close open files and return status
677 if (SourceFile
->Fptr
!= NULL
) {
678 fclose (SourceFile
->Fptr
);
679 SourceFile
->Fptr
= NULL
;
688 SOURCE_FILE
*SourceFile
694 Given a source file that's been opened, read the contents into an internal
695 buffer and pre-process it to remove comments.
699 SourceFile - structure containing info on the file to process
708 // Get the file size, and then read the entire thing into memory.
709 // Allocate extra space for a terminator character.
711 fseek (SourceFile
->Fptr
, 0, SEEK_END
);
712 SourceFile
->FileSize
= ftell (SourceFile
->Fptr
);
713 if (mGlobals
.VerboseFile
) {
714 printf ("FileSize = %d (0x%X)\n", SourceFile
->FileSize
, SourceFile
->FileSize
);
717 fseek (SourceFile
->Fptr
, 0, SEEK_SET
);
718 SourceFile
->FileBuffer
= (T_CHAR
*) malloc (SourceFile
->FileSize
+ sizeof (T_CHAR
));
719 if (SourceFile
->FileBuffer
== NULL
) {
720 Error (NULL
, 0, 0, "memory allocation failure", NULL
);
724 fread ((void *) SourceFile
->FileBuffer
, SourceFile
->FileSize
, 1, SourceFile
->Fptr
);
725 SourceFile
->FileBuffer
[(SourceFile
->FileSize
/ sizeof (T_CHAR
))] = T_CHAR_NULL
;
727 // Pre-process the file to replace comments with spaces
729 PreprocessFile (SourceFile
);
730 SourceFile
->LineNum
= 1;
731 return STATUS_SUCCESS
;
737 SOURCE_FILE
*SourceFile
742 Preprocess a file to replace all carriage returns with NULLs so
743 we can print lines (as part of error messages) from the file to the screen.
746 SourceFile - structure that we use to keep track of an input file.
754 BOOLEAN SlashSlashComment
;
757 RewindFile (SourceFile
);
759 SlashSlashComment
= FALSE
;
760 while (!EndOfFile (SourceFile
)) {
762 // If a line-feed, then no longer in a comment if we're in a // comment
764 if (SourceFile
->FileBufferPtr
[0] == T_CHAR_LF
) {
765 SourceFile
->FileBufferPtr
++;
766 SourceFile
->LineNum
++;
767 if (InComment
&& SlashSlashComment
) {
769 SlashSlashComment
= FALSE
;
771 } else if (SourceFile
->FileBufferPtr
[0] == T_CHAR_CR
) {
773 // Replace all carriage returns with a NULL so we can print stuff
775 SourceFile
->FileBufferPtr
[0] = 0;
776 SourceFile
->FileBufferPtr
++;
778 // Check for */ comment end
780 } else if (InComment
&&
781 !SlashSlashComment
&&
782 (SourceFile
->FileBufferPtr
[0] == T_CHAR_STAR
) &&
783 (SourceFile
->FileBufferPtr
[1] == T_CHAR_SLASH
)
785 SourceFile
->FileBufferPtr
[0] = T_CHAR_SPACE
;
786 SourceFile
->FileBufferPtr
++;
787 SourceFile
->FileBufferPtr
[0] = T_CHAR_SPACE
;
788 SourceFile
->FileBufferPtr
++;
790 } else if (InComment
) {
791 SourceFile
->FileBufferPtr
[0] = T_CHAR_SPACE
;
792 SourceFile
->FileBufferPtr
++;
794 // Check for // comments
796 } else if ((SourceFile
->FileBufferPtr
[0] == T_CHAR_SLASH
) && (SourceFile
->FileBufferPtr
[1] == T_CHAR_SLASH
)) {
798 SlashSlashComment
= TRUE
;
800 // Check for /* comment start
802 } else if ((SourceFile
->FileBufferPtr
[0] == T_CHAR_SLASH
) && (SourceFile
->FileBufferPtr
[1] == T_CHAR_STAR
)) {
803 SourceFile
->FileBufferPtr
[0] = T_CHAR_SPACE
;
804 SourceFile
->FileBufferPtr
++;
805 SourceFile
->FileBufferPtr
[0] = T_CHAR_SPACE
;
806 SourceFile
->FileBufferPtr
++;
807 SlashSlashComment
= FALSE
;
810 SourceFile
->FileBufferPtr
++;
814 // Could check for end-of-file and still in a comment, but
815 // should not be necessary. So just restore the file pointers.
817 RewindFile (SourceFile
);
819 // Dump the reformatted file if verbose mode
821 if (mGlobals
.VerboseFile
) {
823 printf ("%04d: ", LineNum
);
824 while (!EndOfFile (SourceFile
)) {
825 if (SourceFile
->FileBufferPtr
[0] == T_CHAR_LF
) {
826 printf ("'\n%04d: '", ++LineNum
);
828 printf ("%c", SourceFile
->FileBufferPtr
[0]);
831 SourceFile
->FileBufferPtr
++;
835 printf ("FileSize = %d (0x%X)\n", SourceFile
->FileSize
, SourceFile
->FileSize
);
836 RewindFile (SourceFile
);
848 Retrieve a quoted-string from the input file.
851 Str - pointer to a copy of the quoted string parsed
852 Length - size of buffer pointed to by Str
855 TRUE - next token in input stream was a quoted string, and
856 the string value was returned in Str
861 SkipWhiteSpace (&mGlobals
.SourceFile
);
862 if (EndOfFile (&mGlobals
.SourceFile
)) {
866 if (mGlobals
.SourceFile
.FileBufferPtr
[0] == T_CHAR_DOUBLE_QUOTE
) {
867 mGlobals
.SourceFile
.FileBufferPtr
++;
869 if (EndOfFile (&mGlobals
.SourceFile
)) {
873 // Check for closing quote
875 if (mGlobals
.SourceFile
.FileBufferPtr
[0] == T_CHAR_DOUBLE_QUOTE
) {
876 mGlobals
.SourceFile
.FileBufferPtr
++;
881 *Str
= mGlobals
.SourceFile
.FileBufferPtr
[0];
884 mGlobals
.SourceFile
.FileBufferPtr
++;
888 // First character was not a quote, or the input string length was
889 // insufficient to contain the quoted string, so return failure code.
901 Return TRUE of FALSE to indicate whether or not we've reached the end of the
913 SkipWhiteSpace (&mGlobals
.SourceFile
);
914 return EndOfFile (&mGlobals
.SourceFile
);
921 SOURCE_FILE
*SourceFile
,
929 BOOLEAN PreviousBackslash
;
931 if (SourceFile
->FileBufferPtr
[0] != T_CHAR_DOUBLE_QUOTE
) {
932 if (Optional
== FALSE
) {
933 Error (SourceFile
->FileName
, SourceFile
->LineNum
, 0, "expected quoted string", "%S", SourceFile
->FileBufferPtr
);
940 SourceFile
->FileBufferPtr
++;
941 Start
= Ptr
= SourceFile
->FileBufferPtr
;
942 PreviousBackslash
= FALSE
;
943 while (!EndOfFile (SourceFile
)) {
944 if ((SourceFile
->FileBufferPtr
[0] == T_CHAR_DOUBLE_QUOTE
) && (PreviousBackslash
== FALSE
)) {
946 } else if (SourceFile
->FileBufferPtr
[0] == T_CHAR_CR
) {
947 Warning (SourceFile
->FileName
, SourceFile
->LineNum
, 0, "carriage return found in quoted string", "%S", Start
);
948 PreviousBackslash
= FALSE
;
949 } else if (SourceFile
->FileBufferPtr
[0] == T_CHAR_BACKSLASH
) {
950 PreviousBackslash
= TRUE
;
952 PreviousBackslash
= FALSE
;
955 SourceFile
->FileBufferPtr
++;
959 if (SourceFile
->FileBufferPtr
[0] != T_CHAR_DOUBLE_QUOTE
) {
960 Warning (SourceFile
->FileName
, SourceFile
->LineNum
, 0, "missing closing quote on string", "%S", Start
);
962 SourceFile
->FileBufferPtr
++;
965 // Now allocate memory for the string and save it off
967 String
= (T_CHAR
*) malloc ((Len
+ 1) * sizeof (T_CHAR
));
968 if (String
== NULL
) {
969 Error (NULL
, 0, 0, "memory allocation failed", NULL
);
973 // Copy the string from the file buffer to the local copy.
974 // We do no reformatting of it whatsoever at this point.
991 SOURCE_FILE
*SourceFile
995 // The file buffer pointer will typically get updated before the End-of-file flag in the
996 // source file structure, so check it first.
998 if (SourceFile
->FileBufferPtr
>= SourceFile
->FileBuffer
+ SourceFile
->FileSize
/ sizeof (T_CHAR
)) {
999 SourceFile
->EndOfFile
= TRUE
;
1003 if (SourceFile
->EndOfFile
) {
1013 ProcessTokenInclude (
1014 SOURCE_FILE
*SourceFile
1017 char IncludeFileName
[MAX_PATH
];
1020 BOOLEAN ReportedError
;
1021 SOURCE_FILE IncludedSourceFile
;
1023 ReportedError
= FALSE
;
1024 if (SkipWhiteSpace (SourceFile
) == 0) {
1025 Warning (SourceFile
->FileName
, SourceFile
->LineNum
, 0, "expected whitespace following #include keyword", NULL
);
1028 // Should be quoted file name
1030 if (SourceFile
->FileBufferPtr
[0] != T_CHAR_DOUBLE_QUOTE
) {
1031 Error (SourceFile
->FileName
, SourceFile
->LineNum
, 0, "expected quoted include file name", NULL
);
1035 SourceFile
->FileBufferPtr
++;
1037 // Copy the filename as ascii to our local string
1039 To
= IncludeFileName
;
1041 while (!EndOfFile (SourceFile
)) {
1042 if ((SourceFile
->FileBufferPtr
[0] == T_CHAR_CR
) || (SourceFile
->FileBufferPtr
[0] == T_CHAR_LF
)) {
1043 Error (SourceFile
->FileName
, SourceFile
->LineNum
, 0, "end-of-line found in quoted include file name", NULL
);
1047 if (SourceFile
->FileBufferPtr
[0] == T_CHAR_DOUBLE_QUOTE
) {
1048 SourceFile
->FileBufferPtr
++;
1052 // If too long, then report the error once and process until the closing quote
1055 if (!ReportedError
&& (Len
>= sizeof (IncludeFileName
))) {
1056 Error (SourceFile
->FileName
, SourceFile
->LineNum
, 0, "length of include file name exceeds limit", NULL
);
1057 ReportedError
= TRUE
;
1060 if (!ReportedError
) {
1061 *To
= (T_CHAR
) SourceFile
->FileBufferPtr
[0];
1065 SourceFile
->FileBufferPtr
++;
1068 if (!ReportedError
) {
1070 memset ((char *) &IncludedSourceFile
, 0, sizeof (SOURCE_FILE
));
1071 strcpy (IncludedSourceFile
.FileName
, IncludeFileName
);
1072 ProcessIncludeFile (&IncludedSourceFile
, SourceFile
);
1078 // Error recovery -- skip to next #
1080 SourceFile
->SkipToHash
= TRUE
;
1086 SOURCE_FILE
*SourceFile
1089 switch (*SourceFile
->FileBufferPtr
) {
1104 SOURCE_FILE
*SourceFile
1110 while (!EndOfFile (SourceFile
)) {
1112 switch (*SourceFile
->FileBufferPtr
) {
1117 SourceFile
->FileBufferPtr
++;
1121 SourceFile
->FileBufferPtr
++;
1122 SourceFile
->LineNum
++;
1130 // Some tokens require trailing whitespace. If we're at the end of the
1131 // file, then we count that as well.
1133 if ((Count
== 0) && (EndOfFile (SourceFile
))) {
1148 Routine Description:
1149 Compare two strings for equality. The string pointed to by 'Buffer' may or may not be null-terminated,
1150 so only compare up to the length of Str.
1153 Buffer - pointer to first (possibly not null-terminated) string
1154 Str - pointer to null-terminated string to compare to Buffer
1157 Number of bytes matched if exact match
1158 0 if Buffer does not start with Str
1165 while (*Str
&& (*Str
== *Buffer
)) {
1203 if (*Str1
!= *Str2
) {
1237 SOURCE_FILE
*SourceFile
1240 SourceFile
->LineNum
= 1;
1241 SourceFile
->FileBufferPtr
= SourceFile
->FileBuffer
;
1242 SourceFile
->EndOfFile
= 0;
1254 while (!EndOfFile (&mGlobals
.SourceFile
) && (BufferLen
> 0)) {
1255 if (isxdigit (mGlobals
.SourceFile
.FileBufferPtr
[0])) {
1256 *Buffer
= mGlobals
.SourceFile
.FileBufferPtr
[0];
1260 mGlobals
.SourceFile
.FileBufferPtr
++;
1266 // Null terminate if we can
1268 if ((Len
> 0) && (BufferLen
> 0)) {
1282 Routine Description:
1283 Parse a GUID from the input stream. Stop when you discover white space.
1286 GuidStyle - Style of the following GUID token
1287 Value - pointer to EFI_GUID struct for output
1290 TRUE - GUID string parsed successfully
1294 Style[0] 12345678-1234-5678-AAAA-BBBBCCCCDDDD
1301 T_CHAR TempString
[20];
1302 T_CHAR TempString2
[3];
1310 // Skip white space, then start parsing
1312 SkipWhiteSpace (&mGlobals
.SourceFile
);
1313 GetFilePosition (&FPos
);
1314 if (EndOfFile (&mGlobals
.SourceFile
)) {
1318 if (GuidStyle
== PARSE_GUID_STYLE_5_FIELDS
) {
1320 // Style[0] 12345678-1234-5678-AAAA-BBBBCCCCDDDD
1322 Len
= GetHexChars (TempString
, sizeof (TempString
));
1323 if ((Len
== 0) || (Len
> 8)) {
1327 sscanf (TempString
, "%x", &Value32
);
1328 Value
->Data1
= Value32
;
1330 // Next two UINT16 fields
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
->Data2
= (UINT16
) Value32
;
1345 if (mGlobals
.SourceFile
.FileBufferPtr
[0] != '-') {
1349 mGlobals
.SourceFile
.FileBufferPtr
++;
1350 Len
= GetHexChars (TempString
, sizeof (TempString
));
1351 if ((Len
== 0) || (Len
> 4)) {
1355 sscanf (TempString
, "%x", &Value32
);
1356 Value
->Data3
= (UINT16
) Value32
;
1358 // Parse the "AAAA" as two bytes
1360 if (mGlobals
.SourceFile
.FileBufferPtr
[0] != '-') {
1364 mGlobals
.SourceFile
.FileBufferPtr
++;
1365 Len
= GetHexChars (TempString
, sizeof (TempString
));
1366 if ((Len
== 0) || (Len
> 4)) {
1370 sscanf (TempString
, "%x", &Value32
);
1371 Value
->Data4
[0] = (UINT8
) (Value32
>> 8);
1372 Value
->Data4
[1] = (UINT8
) Value32
;
1373 if (mGlobals
.SourceFile
.FileBufferPtr
[0] != '-') {
1377 mGlobals
.SourceFile
.FileBufferPtr
++;
1379 // Read the last 6 bytes of the GUID
1382 Len
= GetHexChars (TempString
, sizeof (TempString
));
1383 if ((Len
== 0) || (Len
> 12)) {
1387 // Insert leading 0's to make life easier
1390 From
= TempString
+ Len
- 1;
1391 To
= TempString
+ 11;
1393 while (From
>= TempString
) {
1399 while (To
>= TempString
) {
1405 // Now parse each byte
1408 for (Index
= 0; Index
< 6; Index
++) {
1410 // Copy the two characters from the input string to something
1413 TempString2
[0] = TempString
[Index
* 2];
1414 TempString2
[1] = TempString
[Index
* 2 + 1];
1415 sscanf (TempString2
, "%x", &Value32
);
1416 Value
->Data4
[Index
+ 2] = (UINT8
) Value32
;
1422 // Unsupported GUID style
1428 if (Status
== FALSE
) {
1429 SetFilePosition (&FPos
);
1441 Fpos
->FileBufferPtr
= mGlobals
.SourceFile
.FileBufferPtr
;
1442 return STATUS_SUCCESS
;
1452 // Should check range of pointer
1454 mGlobals
.SourceFile
.FileBufferPtr
= Fpos
->FileBufferPtr
;
1455 return STATUS_SUCCESS
;