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