+++ /dev/null
-/*++\r
-\r
-Copyright (c) 2004, Intel Corporation \r
-All rights reserved. This program and the accompanying materials \r
-are licensed and made available under the terms and conditions of the BSD License \r
-which accompanies this distribution. The full text of the license may be found at \r
-http://opensource.org/licenses/bsd-license.php \r
- \r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
-\r
-Module Name:\r
-\r
- SimpleFileParsing.c \r
-\r
-Abstract:\r
-\r
- Generic but simple file parsing routines.\r
-\r
---*/\r
-\r
-#include <stdio.h>\r
-#include <string.h>\r
-#include <stdlib.h>\r
-#include <ctype.h>\r
-\r
-#include "EfiUtilityMsgs.h"\r
-#include "SimpleFileParsing.h"\r
-\r
-#ifndef MAX_PATH\r
-#define MAX_PATH 255\r
-#endif\r
-//\r
-// just in case we get in an endless loop.\r
-//\r
-#define MAX_NEST_DEPTH 20\r
-//\r
-// number of wchars\r
-//\r
-#define MAX_STRING_IDENTIFIER_NAME 100\r
-\r
-#define MAX_LINE_LEN 400\r
-\r
-#define T_CHAR_SPACE ' '\r
-#define T_CHAR_NULL 0\r
-#define T_CHAR_CR '\r'\r
-#define T_CHAR_TAB '\t'\r
-#define T_CHAR_LF '\n'\r
-#define T_CHAR_SLASH '/'\r
-#define T_CHAR_BACKSLASH '\\'\r
-#define T_CHAR_DOUBLE_QUOTE '"'\r
-#define T_CHAR_LC_X 'x'\r
-#define T_CHAR_0 '0'\r
-#define T_CHAR_STAR '*'\r
-\r
-//\r
-// We keep a linked list of these for the source files we process\r
-//\r
-typedef struct _SOURCE_FILE {\r
- FILE *Fptr;\r
- T_CHAR *FileBuffer;\r
- T_CHAR *FileBufferPtr;\r
- unsigned int FileSize;\r
- char FileName[MAX_PATH];\r
- unsigned int LineNum;\r
- BOOLEAN EndOfFile;\r
- BOOLEAN SkipToHash;\r
- struct _SOURCE_FILE *Previous;\r
- struct _SOURCE_FILE *Next;\r
- T_CHAR ControlCharacter;\r
-} SOURCE_FILE;\r
-\r
-typedef struct {\r
- T_CHAR *FileBufferPtr;\r
-} FILE_POSITION;\r
-\r
-//\r
-// Keep all our module globals in this structure\r
-//\r
-static struct {\r
- SOURCE_FILE SourceFile;\r
- BOOLEAN VerboseFile;\r
- BOOLEAN VerboseToken;\r
-} mGlobals;\r
-\r
-static\r
-unsigned int\r
-t_strcmp (\r
- T_CHAR *Buffer,\r
- T_CHAR *Str\r
- );\r
-\r
-static\r
-unsigned int\r
-t_strncmp (\r
- T_CHAR *Str1,\r
- T_CHAR *Str2,\r
- int Len\r
- );\r
-\r
-static\r
-unsigned int\r
-t_strlen (\r
- T_CHAR *Str\r
- );\r
-\r
-static\r
-void\r
-RewindFile (\r
- SOURCE_FILE *SourceFile\r
- );\r
-\r
-static\r
-BOOLEAN\r
-IsWhiteSpace (\r
- SOURCE_FILE *SourceFile\r
- );\r
-\r
-static\r
-unsigned int\r
-SkipWhiteSpace (\r
- SOURCE_FILE *SourceFile\r
- );\r
-\r
-static\r
-BOOLEAN\r
-EndOfFile (\r
- SOURCE_FILE *SourceFile\r
- );\r
-\r
-static\r
-void\r
-PreprocessFile (\r
- SOURCE_FILE *SourceFile\r
- );\r
-\r
-static\r
-T_CHAR *\r
-t_strcpy (\r
- T_CHAR *Dest,\r
- T_CHAR *Src\r
- );\r
-\r
-static\r
-STATUS\r
-ProcessIncludeFile (\r
- SOURCE_FILE *SourceFile,\r
- SOURCE_FILE *ParentSourceFile\r
- );\r
-\r
-static\r
-STATUS\r
-ParseFile (\r
- SOURCE_FILE *SourceFile\r
- );\r
-\r
-static\r
-FILE *\r
-FindFile (\r
- char *FileName,\r
- char *FoundFileName,\r
- unsigned int FoundFileNameLen\r
- );\r
-\r
-static\r
-STATUS\r
-ProcessFile (\r
- SOURCE_FILE *SourceFile\r
- );\r
-\r
-static\r
-STATUS\r
-GetFilePosition (\r
- FILE_POSITION *Fpos\r
- );\r
-\r
-static\r
-STATUS\r
-SetFilePosition (\r
- FILE_POSITION *Fpos\r
- );\r
-\r
-STATUS\r
-SFPInit (\r
- VOID\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
- None.\r
-\r
-Returns:\r
- STATUS_SUCCESS always\r
-\r
---*/\r
-{\r
- memset ((void *) &mGlobals, 0, sizeof (mGlobals));\r
- return STATUS_SUCCESS;\r
-}\r
-\r
-unsigned\r
-int\r
-SFPGetLineNumber (\r
- VOID\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Return the line number of the file we're parsing. Used\r
- for error reporting purposes.\r
-\r
-Arguments:\r
- None.\r
-\r
-Returns:\r
- The line number, or 0 if no file is being processed\r
-\r
---*/\r
-{\r
- return mGlobals.SourceFile.LineNum;\r
-}\r
-\r
-T_CHAR *\r
-SFPGetFileName (\r
- VOID\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Return the name of the file we're parsing. Used\r
- for error reporting purposes.\r
-\r
-Arguments:\r
- None.\r
-\r
-Returns:\r
- A pointer to the file name. Null if no file is being\r
- processed.\r
-\r
---*/\r
-{\r
- if (mGlobals.SourceFile.FileName[0]) {\r
- return mGlobals.SourceFile.FileName;\r
- }\r
-\r
- return NULL;\r
-}\r
-\r
-STATUS\r
-SFPOpenFile (\r
- char *FileName\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Open a file for parsing.\r
-\r
-Arguments:\r
- FileName - name of the file to parse\r
-\r
-Returns:\r
- \r
-\r
---*/\r
-{\r
- STATUS Status;\r
- t_strcpy (mGlobals.SourceFile.FileName, FileName);\r
- Status = ProcessIncludeFile (&mGlobals.SourceFile, NULL);\r
- return Status;\r
-}\r
-\r
-BOOLEAN\r
-SFPIsToken (\r
- T_CHAR *Str\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Check to see if the specified token is found at\r
- the current position in the input file.\r
-\r
-Arguments:\r
- Str - the token to look for\r
-\r
-Returns:\r
- TRUE - the token is next\r
- FALSE - the token is not next\r
-\r
-Notes:\r
- We do a simple string comparison on this function. It is\r
- the responsibility of the caller to ensure that the token\r
- is not a subset of some other token.\r
-\r
- The file pointer is advanced past the token in the input file.\r
-\r
---*/\r
-{\r
- unsigned int Len;\r
- SkipWhiteSpace (&mGlobals.SourceFile);\r
- if (EndOfFile (&mGlobals.SourceFile)) {\r
- return FALSE;\r
- }\r
-\r
- if ((Len = t_strcmp (mGlobals.SourceFile.FileBufferPtr, Str)) > 0) {\r
- mGlobals.SourceFile.FileBufferPtr += Len;\r
- if (mGlobals.VerboseToken) {\r
- printf ("Token: '%s'\n", Str);\r
- }\r
-\r
- return TRUE;\r
- }\r
-\r
- return FALSE;\r
-}\r
-\r
-BOOLEAN\r
-SFPIsKeyword (\r
- T_CHAR *Str\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Check to see if the specified keyword is found at\r
- the current position in the input file.\r
-\r
-Arguments:\r
- Str - keyword to look for\r
-\r
-Returns:\r
- TRUE - the keyword is next\r
- FALSE - the keyword is not next\r
-\r
-Notes:\r
- A keyword is defined as a "special" string that has a non-alphanumeric\r
- character following it.\r
-\r
---*/\r
-{\r
- unsigned int Len;\r
- SkipWhiteSpace (&mGlobals.SourceFile);\r
- if (EndOfFile (&mGlobals.SourceFile)) {\r
- return FALSE;\r
- }\r
-\r
- if ((Len = t_strcmp (mGlobals.SourceFile.FileBufferPtr, Str)) > 0) {\r
- if (isalnum (mGlobals.SourceFile.FileBufferPtr[Len])) {\r
- return FALSE;\r
- }\r
-\r
- mGlobals.SourceFile.FileBufferPtr += Len;\r
- if (mGlobals.VerboseToken) {\r
- printf ("Token: '%s'\n", Str);\r
- }\r
-\r
- return TRUE;\r
- }\r
-\r
- return FALSE;\r
-}\r
-\r
-BOOLEAN\r
-SFPGetNextToken (\r
- T_CHAR *Str,\r
- unsigned int Len\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Get the next token from the input stream. \r
-\r
-Arguments:\r
- Str - pointer to a copy of the next token\r
- Len - size of buffer pointed to by Str\r
-\r
-Returns:\r
- TRUE - next token successfully returned\r
- FALSE - otherwise\r
-\r
-Notes:\r
- Preceeding white space is ignored. \r
- The parser's buffer pointer is advanced past the end of the\r
- token.\r
-\r
---*/\r
-{\r
- unsigned int Index;\r
- T_CHAR TempChar;\r
-\r
- SkipWhiteSpace (&mGlobals.SourceFile);\r
- if (EndOfFile (&mGlobals.SourceFile)) {\r
- return FALSE;\r
- }\r
- //\r
- // Have to have enough string for at least one char and a null-terminator\r
- //\r
- if (Len < 2) {\r
- return FALSE;\r
- }\r
- //\r
- // Look at the first character. If it's an identifier, then treat it\r
- // as such\r
- //\r
- TempChar = mGlobals.SourceFile.FileBufferPtr[0];\r
- if (((TempChar >= 'a') && (TempChar <= 'z')) || ((TempChar >= 'A') && (TempChar <= 'Z')) || (TempChar == '_')) {\r
- Str[0] = TempChar;\r
- mGlobals.SourceFile.FileBufferPtr++;\r
- Index = 1;\r
- while (!EndOfFile (&mGlobals.SourceFile) && (Index < Len)) {\r
- TempChar = mGlobals.SourceFile.FileBufferPtr[0];\r
- if (((TempChar >= 'a') && (TempChar <= 'z')) ||\r
- ((TempChar >= 'A') && (TempChar <= 'Z')) ||\r
- ((TempChar >= '0') && (TempChar <= '9')) ||\r
- (TempChar == '_')\r
- ) {\r
- Str[Index] = mGlobals.SourceFile.FileBufferPtr[0];\r
- mGlobals.SourceFile.FileBufferPtr++;\r
- Index++;\r
- } else {\r
- //\r
- // Invalid character for symbol name, so break out\r
- //\r
- break;\r
- }\r
- }\r
- //\r
- // Null terminate and return success\r
- //\r
- Str[Index] = 0;\r
- return TRUE;\r
- } else if ((TempChar == ')') || (TempChar == '(') || (TempChar == '*')) {\r
- Str[0] = mGlobals.SourceFile.FileBufferPtr[0];\r
- mGlobals.SourceFile.FileBufferPtr++;\r
- Str[1] = 0;\r
- return TRUE;\r
- } else {\r
- //\r
- // Everything else is white-space (or EOF) separated\r
- //\r
- Index = 0;\r
- while (!EndOfFile (&mGlobals.SourceFile) && (Index < Len)) {\r
- if (IsWhiteSpace (&mGlobals.SourceFile)) {\r
- if (Index > 0) {\r
- Str[Index] = 0;\r
- return TRUE;\r
- }\r
-\r
- return FALSE;\r
- } else {\r
- Str[Index] = mGlobals.SourceFile.FileBufferPtr[0];\r
- mGlobals.SourceFile.FileBufferPtr++;\r
- Index++;\r
- }\r
- }\r
- //\r
- // See if we just ran out of file contents, but did find a token\r
- //\r
- if ((Index > 0) && EndOfFile (&mGlobals.SourceFile)) {\r
- Str[Index] = 0;\r
- return TRUE;\r
- }\r
- }\r
-\r
- return FALSE;\r
-}\r
-\r
-BOOLEAN\r
-SFPGetGuidToken (\r
- T_CHAR *Str,\r
- UINT32 Len\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Parse a GUID from the input stream. Stop when you discover white space.\r
-\r
-Arguments:\r
- Str - pointer to a copy of the next token\r
- Len - size of buffer pointed to by Str\r
-\r
-Returns:\r
- TRUE - GUID string returned successfully\r
- FALSE - otherwise\r
-\r
---*/\r
-{\r
- UINT32 Index;\r
- SkipWhiteSpace (&mGlobals.SourceFile);\r
- if (EndOfFile (&mGlobals.SourceFile)) {\r
- return FALSE;\r
- }\r
-\r
- Index = 0;\r
- while (!EndOfFile (&mGlobals.SourceFile) && (Index < Len)) {\r
- if (IsWhiteSpace (&mGlobals.SourceFile)) {\r
- if (Index > 0) {\r
- Str[Index] = 0;\r
- return TRUE;\r
- }\r
-\r
- return FALSE;\r
- } else {\r
- Str[Index] = mGlobals.SourceFile.FileBufferPtr[0];\r
- mGlobals.SourceFile.FileBufferPtr++;\r
- Index++;\r
- }\r
- }\r
-\r
- return FALSE;\r
-}\r
-\r
-BOOLEAN\r
-SFPSkipToToken (\r
- T_CHAR *Str\r
- )\r
-{\r
- unsigned int Len;\r
- T_CHAR *SavePos;\r
- Len = t_strlen (Str);\r
- SavePos = mGlobals.SourceFile.FileBufferPtr;\r
- SkipWhiteSpace (&mGlobals.SourceFile);\r
- while (!EndOfFile (&mGlobals.SourceFile)) {\r
- if (t_strncmp (Str, mGlobals.SourceFile.FileBufferPtr, Len) == 0) {\r
- mGlobals.SourceFile.FileBufferPtr += Len;\r
- return TRUE;\r
- }\r
-\r
- mGlobals.SourceFile.FileBufferPtr++;\r
- SkipWhiteSpace (&mGlobals.SourceFile);\r
- }\r
-\r
- mGlobals.SourceFile.FileBufferPtr = SavePos;\r
- return FALSE;\r
-}\r
-\r
-BOOLEAN\r
-SFPGetNumber (\r
- unsigned int *Value\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Check the token at the current file position for a numeric value.\r
- May be either decimal or hex.\r
-\r
-Arguments:\r
- Value - pointer where to store the value\r
-\r
-Returns:\r
- FALSE - current token is not a number\r
- TRUE - current token is a number\r
-\r
---*/\r
-{\r
- SkipWhiteSpace (&mGlobals.SourceFile);\r
- if (EndOfFile (&mGlobals.SourceFile)) {\r
- return FALSE;\r
- }\r
-\r
- if (isdigit (mGlobals.SourceFile.FileBufferPtr[0])) {\r
- //\r
- // Check for hex value\r
- //\r
- if ((mGlobals.SourceFile.FileBufferPtr[0] == T_CHAR_0) && (mGlobals.SourceFile.FileBufferPtr[1] == T_CHAR_LC_X)) {\r
- if (!isxdigit (mGlobals.SourceFile.FileBufferPtr[2])) {\r
- return FALSE;\r
- }\r
-\r
- mGlobals.SourceFile.FileBufferPtr += 2;\r
- sscanf (mGlobals.SourceFile.FileBufferPtr, "%x", Value);\r
- while (isxdigit (mGlobals.SourceFile.FileBufferPtr[0])) {\r
- mGlobals.SourceFile.FileBufferPtr++;\r
- }\r
-\r
- return TRUE;\r
- } else {\r
- *Value = atoi (mGlobals.SourceFile.FileBufferPtr);\r
- while (isdigit (mGlobals.SourceFile.FileBufferPtr[0])) {\r
- mGlobals.SourceFile.FileBufferPtr++;\r
- }\r
-\r
- return TRUE;\r
- }\r
- } else {\r
- return FALSE;\r
- }\r
-}\r
-\r
-STATUS\r
-SFPCloseFile (\r
- VOID\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Close the file being parsed.\r
-\r
-Arguments:\r
- None.\r
-\r
-Returns:\r
- STATUS_SUCCESS - the file was closed \r
- STATUS_ERROR - no file is currently open\r
-\r
---*/\r
-{\r
- if (mGlobals.SourceFile.FileBuffer != NULL) {\r
- free (mGlobals.SourceFile.FileBuffer);\r
- memset (&mGlobals.SourceFile, 0, sizeof (mGlobals.SourceFile));\r
- return STATUS_SUCCESS;\r
- }\r
-\r
- return STATUS_ERROR;\r
-}\r
-\r
-static\r
-STATUS\r
-ProcessIncludeFile (\r
- SOURCE_FILE *SourceFile,\r
- SOURCE_FILE *ParentSourceFile\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Given a source file, open the file and parse it\r
- \r
-Arguments:\r
-\r
- SourceFile - name of file to parse\r
- ParentSourceFile - for error reporting purposes, the file that #included SourceFile.\r
-\r
-Returns:\r
-\r
- Standard status.\r
- \r
---*/\r
-{\r
- static unsigned int NestDepth = 0;\r
- char FoundFileName[MAX_PATH];\r
- STATUS Status;\r
-\r
- Status = STATUS_SUCCESS;\r
- NestDepth++;\r
- //\r
- // Print the file being processed. Indent so you can tell the include nesting\r
- // depth.\r
- //\r
- if (mGlobals.VerboseFile) {\r
- fprintf (stdout, "%*cProcessing file '%s'\n", NestDepth * 2, ' ', SourceFile->FileName);\r
- fprintf (stdout, "Parent source file = '%s'\n", ParentSourceFile);\r
- }\r
-\r
- //\r
- // Make sure we didn't exceed our maximum nesting depth\r
- //\r
- if (NestDepth > MAX_NEST_DEPTH) {\r
- Error (NULL, 0, 0, SourceFile->FileName, "max nesting depth (%d) exceeded", NestDepth);\r
- Status = STATUS_ERROR;\r
- goto Finish;\r
- }\r
- //\r
- // Try to open the file locally, and if that fails try along our include paths.\r
- //\r
- strcpy (FoundFileName, SourceFile->FileName);\r
- if ((SourceFile->Fptr = fopen (FoundFileName, "rb")) == NULL) {\r
- return STATUS_ERROR;\r
- }\r
- //\r
- // Process the file found\r
- //\r
- ProcessFile (SourceFile);\r
-Finish:\r
- //\r
- // Close open files and return status\r
- //\r
- if (SourceFile->Fptr != NULL) {\r
- fclose (SourceFile->Fptr);\r
- SourceFile->Fptr = NULL;\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-static\r
-STATUS\r
-ProcessFile (\r
- SOURCE_FILE *SourceFile\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Given a source file that's been opened, read the contents into an internal\r
- buffer and pre-process it to remove comments.\r
- \r
-Arguments:\r
-\r
- SourceFile - structure containing info on the file to process\r
-\r
-Returns:\r
-\r
- Standard status.\r
- \r
---*/\r
-{\r
- //\r
- // Get the file size, and then read the entire thing into memory.\r
- // Allocate extra space for a terminator character.\r
- //\r
- fseek (SourceFile->Fptr, 0, SEEK_END);\r
- SourceFile->FileSize = ftell (SourceFile->Fptr);\r
- if (mGlobals.VerboseFile) {\r
- printf ("FileSize = %d (0x%X)\n", SourceFile->FileSize, SourceFile->FileSize);\r
- }\r
-\r
- fseek (SourceFile->Fptr, 0, SEEK_SET);\r
- SourceFile->FileBuffer = (T_CHAR *) malloc (SourceFile->FileSize + sizeof (T_CHAR));\r
- if (SourceFile->FileBuffer == NULL) {\r
- Error (NULL, 0, 0, "memory allocation failure", NULL);\r
- return STATUS_ERROR;\r
- }\r
-\r
- fread ((void *) SourceFile->FileBuffer, SourceFile->FileSize, 1, SourceFile->Fptr);\r
- SourceFile->FileBuffer[(SourceFile->FileSize / sizeof (T_CHAR))] = T_CHAR_NULL;\r
- //\r
- // Pre-process the file to replace comments with spaces\r
- //\r
- PreprocessFile (SourceFile);\r
- SourceFile->LineNum = 1;\r
- return STATUS_SUCCESS;\r
-}\r
-\r
-static\r
-void\r
-PreprocessFile (\r
- SOURCE_FILE *SourceFile\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Preprocess a file to replace all carriage returns with NULLs so\r
- we can print lines (as part of error messages) from the file to the screen.\r
- \r
-Arguments:\r
- SourceFile - structure that we use to keep track of an input file.\r
-\r
-Returns:\r
- Nothing.\r
- \r
---*/\r
-{\r
- BOOLEAN InComment;\r
- BOOLEAN SlashSlashComment;\r
- int LineNum;\r
-\r
- RewindFile (SourceFile);\r
- InComment = FALSE;\r
- SlashSlashComment = FALSE;\r
- while (!EndOfFile (SourceFile)) {\r
- //\r
- // If a line-feed, then no longer in a comment if we're in a // comment\r
- //\r
- if (SourceFile->FileBufferPtr[0] == T_CHAR_LF) {\r
- SourceFile->FileBufferPtr++;\r
- SourceFile->LineNum++;\r
- if (InComment && SlashSlashComment) {\r
- InComment = FALSE;\r
- SlashSlashComment = FALSE;\r
- }\r
- } else if (SourceFile->FileBufferPtr[0] == T_CHAR_CR) {\r
- //\r
- // Replace all carriage returns with a NULL so we can print stuff\r
- //\r
- SourceFile->FileBufferPtr[0] = 0;\r
- SourceFile->FileBufferPtr++;\r
- //\r
- // Check for */ comment end\r
- //\r
- } else if (InComment &&\r
- !SlashSlashComment &&\r
- (SourceFile->FileBufferPtr[0] == T_CHAR_STAR) &&\r
- (SourceFile->FileBufferPtr[1] == T_CHAR_SLASH)\r
- ) {\r
- SourceFile->FileBufferPtr[0] = T_CHAR_SPACE;\r
- SourceFile->FileBufferPtr++;\r
- SourceFile->FileBufferPtr[0] = T_CHAR_SPACE;\r
- SourceFile->FileBufferPtr++;\r
- InComment = FALSE;\r
- } else if (InComment) {\r
- SourceFile->FileBufferPtr[0] = T_CHAR_SPACE;\r
- SourceFile->FileBufferPtr++;\r
- //\r
- // Check for // comments\r
- //\r
- } else if ((SourceFile->FileBufferPtr[0] == T_CHAR_SLASH) && (SourceFile->FileBufferPtr[1] == T_CHAR_SLASH)) {\r
- InComment = TRUE;\r
- SlashSlashComment = TRUE;\r
- //\r
- // Check for /* comment start\r
- //\r
- } else if ((SourceFile->FileBufferPtr[0] == T_CHAR_SLASH) && (SourceFile->FileBufferPtr[1] == T_CHAR_STAR)) {\r
- SourceFile->FileBufferPtr[0] = T_CHAR_SPACE;\r
- SourceFile->FileBufferPtr++;\r
- SourceFile->FileBufferPtr[0] = T_CHAR_SPACE;\r
- SourceFile->FileBufferPtr++;\r
- SlashSlashComment = FALSE;\r
- InComment = TRUE;\r
- } else {\r
- SourceFile->FileBufferPtr++;\r
- }\r
- }\r
- //\r
- // Could check for end-of-file and still in a comment, but\r
- // should not be necessary. So just restore the file pointers.\r
- //\r
- RewindFile (SourceFile);\r
- //\r
- // Dump the reformatted file if verbose mode\r
- //\r
- if (mGlobals.VerboseFile) {\r
- LineNum = 1;\r
- printf ("%04d: ", LineNum);\r
- while (!EndOfFile (SourceFile)) {\r
- if (SourceFile->FileBufferPtr[0] == T_CHAR_LF) {\r
- printf ("'\n%04d: '", ++LineNum);\r
- } else {\r
- printf ("%c", SourceFile->FileBufferPtr[0]);\r
- }\r
-\r
- SourceFile->FileBufferPtr++;\r
- }\r
-\r
- printf ("'\n");\r
- printf ("FileSize = %d (0x%X)\n", SourceFile->FileSize, SourceFile->FileSize);\r
- RewindFile (SourceFile);\r
- }\r
-}\r
-\r
-BOOLEAN\r
-SFPGetQuotedString (\r
- T_CHAR *Str,\r
- int Length\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Retrieve a quoted-string from the input file. \r
- \r
-Arguments:\r
- Str - pointer to a copy of the quoted string parsed\r
- Length - size of buffer pointed to by Str\r
-\r
-Returns:\r
- TRUE - next token in input stream was a quoted string, and\r
- the string value was returned in Str\r
- FALSE - otherwise\r
- \r
---*/\r
-{\r
- SkipWhiteSpace (&mGlobals.SourceFile);\r
- if (EndOfFile (&mGlobals.SourceFile)) {\r
- return FALSE;\r
- }\r
-\r
- if (mGlobals.SourceFile.FileBufferPtr[0] == T_CHAR_DOUBLE_QUOTE) {\r
- mGlobals.SourceFile.FileBufferPtr++;\r
- while (Length > 0) {\r
- if (EndOfFile (&mGlobals.SourceFile)) {\r
- return FALSE;\r
- }\r
- //\r
- // Check for closing quote\r
- //\r
- if (mGlobals.SourceFile.FileBufferPtr[0] == T_CHAR_DOUBLE_QUOTE) {\r
- mGlobals.SourceFile.FileBufferPtr++;\r
- *Str = 0;\r
- return TRUE;\r
- }\r
-\r
- *Str = mGlobals.SourceFile.FileBufferPtr[0];\r
- Str++;\r
- Length--;\r
- mGlobals.SourceFile.FileBufferPtr++;\r
- }\r
- }\r
- //\r
- // First character was not a quote, or the input string length was\r
- // insufficient to contain the quoted string, so return failure code.\r
- //\r
- return FALSE;\r
-}\r
-\r
-BOOLEAN\r
-SFPIsEOF (\r
- VOID\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Return TRUE of FALSE to indicate whether or not we've reached the end of the\r
- file we're parsing.\r
- \r
-Arguments:\r
- NA\r
-\r
-Returns:\r
- TRUE - EOF reached\r
- FALSE - otherwise\r
- \r
---*/\r
-{\r
- SkipWhiteSpace (&mGlobals.SourceFile);\r
- return EndOfFile (&mGlobals.SourceFile);\r
-}\r
-\r
-#if 0\r
-static\r
-T_CHAR *\r
-GetQuotedString (\r
- SOURCE_FILE *SourceFile,\r
- BOOLEAN Optional\r
- )\r
-{\r
- T_CHAR *String;\r
- T_CHAR *Start;\r
- T_CHAR *Ptr;\r
- unsigned int Len;\r
- BOOLEAN PreviousBackslash;\r
-\r
- if (SourceFile->FileBufferPtr[0] != T_CHAR_DOUBLE_QUOTE) {\r
- if (Optional == FALSE) {\r
- Error (SourceFile->FileName, SourceFile->LineNum, 0, "expected quoted string", "%S", SourceFile->FileBufferPtr);\r
- }\r
-\r
- return NULL;\r
- }\r
-\r
- Len = 0;\r
- SourceFile->FileBufferPtr++;\r
- Start = Ptr = SourceFile->FileBufferPtr;\r
- PreviousBackslash = FALSE;\r
- while (!EndOfFile (SourceFile)) {\r
- if ((SourceFile->FileBufferPtr[0] == T_CHAR_DOUBLE_QUOTE) && (PreviousBackslash == FALSE)) {\r
- break;\r
- } else if (SourceFile->FileBufferPtr[0] == T_CHAR_CR) {\r
- Warning (SourceFile->FileName, SourceFile->LineNum, 0, "carriage return found in quoted string", "%S", Start);\r
- PreviousBackslash = FALSE;\r
- } else if (SourceFile->FileBufferPtr[0] == T_CHAR_BACKSLASH) {\r
- PreviousBackslash = TRUE;\r
- } else {\r
- PreviousBackslash = FALSE;\r
- }\r
-\r
- SourceFile->FileBufferPtr++;\r
- Len++;\r
- }\r
-\r
- if (SourceFile->FileBufferPtr[0] != T_CHAR_DOUBLE_QUOTE) {\r
- Warning (SourceFile->FileName, SourceFile->LineNum, 0, "missing closing quote on string", "%S", Start);\r
- } else {\r
- SourceFile->FileBufferPtr++;\r
- }\r
- //\r
- // Now allocate memory for the string and save it off\r
- //\r
- String = (T_CHAR *) malloc ((Len + 1) * sizeof (T_CHAR));\r
- if (String == NULL) {\r
- Error (NULL, 0, 0, "memory allocation failed", NULL);\r
- return NULL;\r
- }\r
- //\r
- // Copy the string from the file buffer to the local copy.\r
- // We do no reformatting of it whatsoever at this point.\r
- //\r
- Ptr = String;\r
- while (Len > 0) {\r
- *Ptr = *Start;\r
- Start++;\r
- Ptr++;\r
- Len--;\r
- }\r
-\r
- *Ptr = 0;\r
- return String;\r
-}\r
-#endif\r
-static\r
-BOOLEAN\r
-EndOfFile (\r
- SOURCE_FILE *SourceFile\r
- )\r
-{\r
- //\r
- // The file buffer pointer will typically get updated before the End-of-file flag in the\r
- // source file structure, so check it first.\r
- //\r
- if (SourceFile->FileBufferPtr >= SourceFile->FileBuffer + SourceFile->FileSize / sizeof (T_CHAR)) {\r
- SourceFile->EndOfFile = TRUE;\r
- return TRUE;\r
- }\r
-\r
- if (SourceFile->EndOfFile) {\r
- return TRUE;\r
- }\r
-\r
- return FALSE;\r
-}\r
-\r
-#if 0\r
-static\r
-void\r
-ProcessTokenInclude (\r
- SOURCE_FILE *SourceFile\r
- )\r
-{\r
- char IncludeFileName[MAX_PATH];\r
- char *To;\r
- unsigned int Len;\r
- BOOLEAN ReportedError;\r
- SOURCE_FILE IncludedSourceFile;\r
-\r
- ReportedError = FALSE;\r
- if (SkipWhiteSpace (SourceFile) == 0) {\r
- Warning (SourceFile->FileName, SourceFile->LineNum, 0, "expected whitespace following #include keyword", NULL);\r
- }\r
- //\r
- // Should be quoted file name\r
- //\r
- if (SourceFile->FileBufferPtr[0] != T_CHAR_DOUBLE_QUOTE) {\r
- Error (SourceFile->FileName, SourceFile->LineNum, 0, "expected quoted include file name", NULL);\r
- goto FailDone;\r
- }\r
-\r
- SourceFile->FileBufferPtr++;\r
- //\r
- // Copy the filename as ascii to our local string\r
- //\r
- To = IncludeFileName;\r
- Len = 0;\r
- while (!EndOfFile (SourceFile)) {\r
- if ((SourceFile->FileBufferPtr[0] == T_CHAR_CR) || (SourceFile->FileBufferPtr[0] == T_CHAR_LF)) {\r
- Error (SourceFile->FileName, SourceFile->LineNum, 0, "end-of-line found in quoted include file name", NULL);\r
- goto FailDone;\r
- }\r
-\r
- if (SourceFile->FileBufferPtr[0] == T_CHAR_DOUBLE_QUOTE) {\r
- SourceFile->FileBufferPtr++;\r
- break;\r
- }\r
- //\r
- // If too long, then report the error once and process until the closing quote\r
- //\r
- Len++;\r
- if (!ReportedError && (Len >= sizeof (IncludeFileName))) {\r
- Error (SourceFile->FileName, SourceFile->LineNum, 0, "length of include file name exceeds limit", NULL);\r
- ReportedError = TRUE;\r
- }\r
-\r
- if (!ReportedError) {\r
- *To = (T_CHAR) SourceFile->FileBufferPtr[0];\r
- To++;\r
- }\r
-\r
- SourceFile->FileBufferPtr++;\r
- }\r
-\r
- if (!ReportedError) {\r
- *To = 0;\r
- memset ((char *) &IncludedSourceFile, 0, sizeof (SOURCE_FILE));\r
- strcpy (IncludedSourceFile.FileName, IncludeFileName);\r
- ProcessIncludeFile (&IncludedSourceFile, SourceFile);\r
- }\r
-\r
- return ;\r
-FailDone:\r
- //\r
- // Error recovery -- skip to next #\r
- //\r
- SourceFile->SkipToHash = TRUE;\r
-}\r
-#endif\r
-static\r
-BOOLEAN\r
-IsWhiteSpace (\r
- SOURCE_FILE *SourceFile\r
- )\r
-{\r
- switch (*SourceFile->FileBufferPtr) {\r
- case T_CHAR_NULL:\r
- case T_CHAR_CR:\r
- case T_CHAR_SPACE:\r
- case T_CHAR_TAB:\r
- case T_CHAR_LF:\r
- return TRUE;\r
-\r
- default:\r
- return FALSE;\r
- }\r
-}\r
-\r
-unsigned int\r
-SkipWhiteSpace (\r
- SOURCE_FILE *SourceFile\r
- )\r
-{\r
- unsigned int Count;\r
-\r
- Count = 0;\r
- while (!EndOfFile (SourceFile)) {\r
- Count++;\r
- switch (*SourceFile->FileBufferPtr) {\r
- case T_CHAR_NULL:\r
- case T_CHAR_CR:\r
- case T_CHAR_SPACE:\r
- case T_CHAR_TAB:\r
- SourceFile->FileBufferPtr++;\r
- break;\r
-\r
- case T_CHAR_LF:\r
- SourceFile->FileBufferPtr++;\r
- SourceFile->LineNum++;\r
- break;\r
-\r
- default:\r
- return Count - 1;\r
- }\r
- }\r
- //\r
- // Some tokens require trailing whitespace. If we're at the end of the\r
- // file, then we count that as well.\r
- //\r
- if ((Count == 0) && (EndOfFile (SourceFile))) {\r
- Count++;\r
- }\r
-\r
- return Count;\r
-}\r
-\r
-static\r
-unsigned int\r
-t_strcmp (\r
- T_CHAR *Buffer,\r
- T_CHAR *Str\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Compare two strings for equality. The string pointed to by 'Buffer' may or may not be null-terminated,\r
- so only compare up to the length of Str.\r
-\r
-Arguments:\r
- Buffer - pointer to first (possibly not null-terminated) string\r
- Str - pointer to null-terminated string to compare to Buffer\r
-\r
-Returns:\r
- Number of bytes matched if exact match\r
- 0 if Buffer does not start with Str\r
-\r
---*/\r
-{\r
- unsigned int Len;\r
-\r
- Len = 0;\r
- while (*Str && (*Str == *Buffer)) {\r
- Buffer++;\r
- Str++;\r
- Len++;\r
- }\r
-\r
- if (*Str) {\r
- return 0;\r
- }\r
-\r
- return Len;\r
-}\r
-\r
-static\r
-unsigned int\r
-t_strlen (\r
- T_CHAR *Str\r
- )\r
-{\r
- unsigned int Len;\r
- Len = 0;\r
- while (*Str) {\r
- Len++;\r
- Str++;\r
- }\r
-\r
- return Len;\r
-}\r
-\r
-static\r
-unsigned int\r
-t_strncmp (\r
- T_CHAR *Str1,\r
- T_CHAR *Str2,\r
- int Len\r
- )\r
-{\r
- while (Len > 0) {\r
- if (*Str1 != *Str2) {\r
- return Len;\r
- }\r
-\r
- Len--;\r
- Str1++;\r
- Str2++;\r
- }\r
-\r
- return 0;\r
-}\r
-\r
-static\r
-T_CHAR *\r
-t_strcpy (\r
- T_CHAR *Dest,\r
- T_CHAR *Src\r
- )\r
-{\r
- T_CHAR *SaveDest;\r
- SaveDest = Dest;\r
- while (*Src) {\r
- *Dest = *Src;\r
- Dest++;\r
- Src++;\r
- }\r
-\r
- *Dest = 0;\r
- return SaveDest;\r
-}\r
-\r
-static\r
-void\r
-RewindFile (\r
- SOURCE_FILE *SourceFile\r
- )\r
-{\r
- SourceFile->LineNum = 1;\r
- SourceFile->FileBufferPtr = SourceFile->FileBuffer;\r
- SourceFile->EndOfFile = 0;\r
-}\r
-\r
-static\r
-UINT32\r
-GetHexChars (\r
- T_CHAR *Buffer,\r
- UINT32 BufferLen\r
- )\r
-{\r
- UINT32 Len;\r
- Len = 0;\r
- while (!EndOfFile (&mGlobals.SourceFile) && (BufferLen > 0)) {\r
- if (isxdigit (mGlobals.SourceFile.FileBufferPtr[0])) {\r
- *Buffer = mGlobals.SourceFile.FileBufferPtr[0];\r
- Buffer++;\r
- Len++;\r
- BufferLen--;\r
- mGlobals.SourceFile.FileBufferPtr++;\r
- } else {\r
- break;\r
- }\r
- }\r
- //\r
- // Null terminate if we can\r
- //\r
- if ((Len > 0) && (BufferLen > 0)) {\r
- *Buffer = 0;\r
- }\r
-\r
- return Len;\r
-}\r
-\r
-BOOLEAN\r
-SFPGetGuid (\r
- int GuidStyle,\r
- EFI_GUID *Value\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Parse a GUID from the input stream. Stop when you discover white space.\r
-\r
-Arguments:\r
- GuidStyle - Style of the following GUID token\r
- Value - pointer to EFI_GUID struct for output\r
-\r
-Returns:\r
- TRUE - GUID string parsed successfully\r
- FALSE - otherwise\r
-\r
- GUID styles\r
- Style[0] 12345678-1234-5678-AAAA-BBBBCCCCDDDD\r
-\r
---*/\r
-{\r
- UINT32 Value32;\r
- UINT32 Index;\r
- FILE_POSITION FPos;\r
- T_CHAR TempString[20];\r
- T_CHAR TempString2[3];\r
- T_CHAR *From;\r
- T_CHAR *To;\r
- UINT32 Len;\r
- BOOLEAN Status;\r
-\r
- Status = FALSE;\r
- //\r
- // Skip white space, then start parsing\r
- //\r
- SkipWhiteSpace (&mGlobals.SourceFile);\r
- GetFilePosition (&FPos);\r
- if (EndOfFile (&mGlobals.SourceFile)) {\r
- return FALSE;\r
- }\r
-\r
- if (GuidStyle == PARSE_GUID_STYLE_5_FIELDS) {\r
- //\r
- // Style[0] 12345678-1234-5678-AAAA-BBBBCCCCDDDD\r
- //\r
- Len = GetHexChars (TempString, sizeof (TempString));\r
- if ((Len == 0) || (Len > 8)) {\r
- goto Done;\r
- }\r
-\r
- sscanf (TempString, "%x", &Value32);\r
- Value->Data1 = Value32;\r
- //\r
- // Next two UINT16 fields\r
- //\r
- if (mGlobals.SourceFile.FileBufferPtr[0] != '-') {\r
- goto Done;\r
- }\r
-\r
- mGlobals.SourceFile.FileBufferPtr++;\r
- Len = GetHexChars (TempString, sizeof (TempString));\r
- if ((Len == 0) || (Len > 4)) {\r
- goto Done;\r
- }\r
-\r
- sscanf (TempString, "%x", &Value32);\r
- Value->Data2 = (UINT16) Value32;\r
-\r
- if (mGlobals.SourceFile.FileBufferPtr[0] != '-') {\r
- goto Done;\r
- }\r
-\r
- mGlobals.SourceFile.FileBufferPtr++;\r
- Len = GetHexChars (TempString, sizeof (TempString));\r
- if ((Len == 0) || (Len > 4)) {\r
- goto Done;\r
- }\r
-\r
- sscanf (TempString, "%x", &Value32);\r
- Value->Data3 = (UINT16) Value32;\r
- //\r
- // Parse the "AAAA" as two bytes\r
- //\r
- if (mGlobals.SourceFile.FileBufferPtr[0] != '-') {\r
- goto Done;\r
- }\r
-\r
- mGlobals.SourceFile.FileBufferPtr++;\r
- Len = GetHexChars (TempString, sizeof (TempString));\r
- if ((Len == 0) || (Len > 4)) {\r
- goto Done;\r
- }\r
-\r
- sscanf (TempString, "%x", &Value32);\r
- Value->Data4[0] = (UINT8) (Value32 >> 8);\r
- Value->Data4[1] = (UINT8) Value32;\r
- if (mGlobals.SourceFile.FileBufferPtr[0] != '-') {\r
- goto Done;\r
- }\r
-\r
- mGlobals.SourceFile.FileBufferPtr++;\r
- //\r
- // Read the last 6 bytes of the GUID\r
- //\r
- //\r
- Len = GetHexChars (TempString, sizeof (TempString));\r
- if ((Len == 0) || (Len > 12)) {\r
- goto Done;\r
- }\r
- //\r
- // Insert leading 0's to make life easier\r
- //\r
- if (Len != 12) {\r
- From = TempString + Len - 1;\r
- To = TempString + 11;\r
- TempString[12] = 0;\r
- while (From >= TempString) {\r
- *To = *From;\r
- To--;\r
- From--;\r
- }\r
-\r
- while (To >= TempString) {\r
- *To = '0';\r
- To--;\r
- }\r
- }\r
- //\r
- // Now parse each byte\r
- //\r
- TempString2[2] = 0;\r
- for (Index = 0; Index < 6; Index++) {\r
- //\r
- // Copy the two characters from the input string to something\r
- // we can parse.\r
- //\r
- TempString2[0] = TempString[Index * 2];\r
- TempString2[1] = TempString[Index * 2 + 1];\r
- sscanf (TempString2, "%x", &Value32);\r
- Value->Data4[Index + 2] = (UINT8) Value32;\r
- }\r
-\r
- Status = TRUE;\r
- } else {\r
- //\r
- // Unsupported GUID style\r
- //\r
- return FALSE;\r
- }\r
-\r
-Done:\r
- if (Status == FALSE) {\r
- SetFilePosition (&FPos);\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-static\r
-STATUS\r
-GetFilePosition (\r
- FILE_POSITION *Fpos\r
- )\r
-{\r
- Fpos->FileBufferPtr = mGlobals.SourceFile.FileBufferPtr;\r
- return STATUS_SUCCESS;\r
-}\r
-\r
-static\r
-STATUS\r
-SetFilePosition (\r
- FILE_POSITION *Fpos\r
- )\r
-{\r
- //\r
- // Should check range of pointer\r
- //\r
- mGlobals.SourceFile.FileBufferPtr = Fpos->FileBufferPtr;\r
- return STATUS_SUCCESS;\r
-}\r