/*++

Copyright (c) 2004, Intel Corporation                                                         
All rights reserved. This program and the accompanying materials                          
are licensed and made available under the terms and conditions of the BSD License         
which accompanies this distribution.  The full text of the license may be found at        
http://opensource.org/licenses/bsd-license.php                                            
                                                                                          
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             

Module Name:

  StringDB.c

Abstract:

  String database implementation
  
--*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>  // for tolower()

#include <Common/UefiBaseTypes.h>
#include <Common/MultiPhase.h>
#include <Common/InternalFormRepresentation.h>
#include <Protocol/UgaDraw.h>  // for EFI_UGA_PIXEL definition
#include <Protocol/Hii.h>

#include "EfiUtilityMsgs.h"
#include "StrGather.h"
#include "StringDB.h"


#define STRING_OFFSET RELOFST

#define STRING_DB_KEY (('S' << 24) | ('D' << 16) | ('B' << 8) | 'K')
//
// Version supported by this tool
//
#define STRING_DB_VERSION             0x00010000

#define STRING_DB_MAJOR_VERSION_MASK  0xFFFF0000
#define STRING_DB_MINOR_VERSION_MASK  0x0000FFFF

#define DEFINE_STR                    L"// #define"

#define LANGUAGE_CODE_WIDTH           4
//
// This is the header that gets written to the top of the
// output binary database file.
//
typedef struct {
  UINT32  Key;
  UINT32  HeaderSize;
  UINT32  Version;
  UINT32  NumStringIdenfiers;
  UINT32  StringIdentifiersSize;
  UINT32  NumLanguages;
} STRING_DB_HEADER;

//
// When we write out data to the database, we have a UINT16 identifier, which
// indicates what follows, followed by the data. Here's the structure.
//
typedef struct {
  UINT16  DataType;
  UINT16  Reserved;
} DB_DATA_ITEM_HEADER;

#define DB_DATA_TYPE_INVALID              0x0000
#define DB_DATA_TYPE_STRING_IDENTIFIER    0x0001
#define DB_DATA_TYPE_LANGUAGE_DEFINITION  0x0002
#define DB_DATA_TYPE_STRING_DEFINITION    0x0003
#define DB_DATA_TYPE_LAST                 DB_DATA_TYPE_STRING_DEFINITION

//
// We have to keep track of a list of languages, each of which has its own
// list of strings. Define a structure to keep track of all languages and
// their list of strings.
//
typedef struct _STRING_LIST {
  struct _STRING_LIST *Next;
  UINT32              Size;         // number of bytes in string, including null terminator
  WCHAR               *LanguageName;
  WCHAR               *StringName;  // for example STR_ID_TEXT1
  WCHAR               *Scope;       //
  WCHAR               *Str;         // the actual string
  UINT16              Flags;        // properties of this string (used, undefined)
} STRING_LIST;

typedef struct _LANGUAGE_LIST {
  struct _LANGUAGE_LIST *Next;
  WCHAR                 LanguageName[4];
  WCHAR                 *PrintableLanguageName;
  STRING_LIST           *String;
  STRING_LIST           *LastString;
} LANGUAGE_LIST;

//
// We also keep track of all the string identifier names, which we assign unique
// values to. Create a structure to keep track of them all.
//
typedef struct _STRING_IDENTIFIER {
  struct _STRING_IDENTIFIER *Next;
  UINT32                    Index;  // only need 16 bits, but makes it easier with UINT32
  WCHAR                     *StringName;
  UINT16                    Flags;  // if someone referenced it via STRING_TOKEN()
} STRING_IDENTIFIER;
//
// Keep our globals in this structure to be as modular as possible.
//
typedef struct {
  FILE              *StringDBFptr;
  LANGUAGE_LIST     *LanguageList;
  LANGUAGE_LIST     *LastLanguageList;
  LANGUAGE_LIST     *CurrentLanguage;         // keep track of the last language they used
  STRING_IDENTIFIER *StringIdentifier;
  STRING_IDENTIFIER *LastStringIdentifier;
  UINT8             *StringDBFileName;
  UINT32            NumStringIdentifiers;
  UINT32            NumStringIdentifiersReferenced;
  STRING_IDENTIFIER *CurrentStringIdentifier; // keep track of the last string identifier they added
  WCHAR             *CurrentScope;
} STRING_DB_DATA;

static STRING_DB_DATA mDBData;

static const char     *mSourceFileHeader[] = {
  "//",
  "//  DO NOT EDIT -- auto-generated file",
  "//",
  "//  This file is generated by the string gather utility",
  "//",
  NULL
};

static
STRING_LIST           *
StringDBFindString (
  WCHAR                       *LanguageName,
  WCHAR                       *StringName,
  WCHAR                       *Scope,
  WCHAR_STRING_LIST           *LanguagesOfInterest,
  WCHAR_MATCHING_STRING_LIST  *IndirectionList
  );

static
STRING_IDENTIFIER     *
StringDBFindStringIdentifierByName (
  WCHAR *Name
  );

static
STRING_IDENTIFIER     *
StringDBFindStringIdentifierByIndex (
  UINT32    Index
  );

static
LANGUAGE_LIST         *
StringDBFindLanguageList (
  WCHAR *LanguageName
  );

static
void
StringDBWriteStandardFileHeader (
  FILE *OutFptr
  );

static
WCHAR                 *
AsciiToWchar (
  CHAR8 *Str
  );

static
WCHAR                 *
DuplicateString (
  WCHAR   *Str
  );

static
STATUS
StringDBWriteStringIdentifier (
  FILE                *DBFptr,
  UINT16              StringId,
  UINT16              Flags,
  WCHAR               *IdentifierName
  );

static
STATUS
StringDBReadStringIdentifier (
  FILE                *DBFptr
  );

static
STATUS
StringDBWriteLanguageDefinition (
  FILE            *DBFptr,
  WCHAR           *LanguageName,
  WCHAR           *PrintableLanguageName
  );

static
STATUS
StringDBReadLanguageDefinition (
  FILE            *DBFptr
  );

static
STATUS
StringDBWriteString (
  FILE            *DBFptr,
  UINT16          Flags,
  WCHAR           *Language,
  WCHAR           *StringName,
  WCHAR           *Scope,
  WCHAR           *Str
  );

static
STATUS
StringDBReadString (
  FILE            *DBFptr
  );

static
STATUS
StringDBReadGenericString (
  FILE      *DBFptr,
  UINT16    *Size,
  WCHAR     **Str
  );

static
STATUS
StringDBWriteGenericString (
  FILE      *DBFptr,
  WCHAR     *Str
  );

static
void
StringDBAssignStringIndexes (
  VOID
  );

/*****************************************************************************/

/*++

Routine Description:
  Constructor function for the string database handler.

Arguments:
  None.

Returns:
  None.

--*/
void
StringDBConstructor (
  VOID
  )
{
  memset ((char *) &mDBData, 0, sizeof (STRING_DB_DATA));
  mDBData.CurrentScope = DuplicateString (L"NULL");
}

/*****************************************************************************/

/*++

Routine Description:
  Destructor function for the string database handler.

Arguments:
  None.

Returns:
  None.

--*/
void
StringDBDestructor (
  VOID
  )
{
  LANGUAGE_LIST     *NextLang;
  STRING_LIST       *NextStr;
  STRING_IDENTIFIER *NextIdentifier;
  //
  // Close the database file if it's open
  //
  if (mDBData.StringDBFptr != NULL) {
    fclose (mDBData.StringDBFptr);
    mDBData.StringDBFptr = NULL;
  }
  //
  // If we've allocated any strings/languages, free them up
  //
  while (mDBData.LanguageList != NULL) {
    NextLang = mDBData.LanguageList->Next;
    //
    // Free up all strings for this language
    //
    while (mDBData.LanguageList->String != NULL) {
      NextStr = mDBData.LanguageList->String->Next;
      FREE (mDBData.LanguageList->String->Str);
      FREE (mDBData.LanguageList->String);
      mDBData.LanguageList->String = NextStr;
    }

    FREE (mDBData.LanguageList->PrintableLanguageName);
    FREE (mDBData.LanguageList);
    mDBData.LanguageList = NextLang;
  }
  //
  // Free up string identifiers
  //
  while (mDBData.StringIdentifier != NULL) {
    NextIdentifier = mDBData.StringIdentifier->Next;
    FREE (mDBData.StringIdentifier->StringName);
    FREE (mDBData.StringIdentifier);
    mDBData.StringIdentifier = NextIdentifier;
  }
  //
  // Free the filename
  //
  if (mDBData.StringDBFileName != NULL) {
    FREE (mDBData.StringDBFileName);
    mDBData.StringDBFileName = NULL;
  }
  //
  // We save a copy of the scope, so free it up if we
  // have one.
  //
  if (mDBData.CurrentScope != NULL) {
    FREE (mDBData.CurrentScope);
    mDBData.CurrentScope = NULL;
  }
}

/*****************************************************************************/

/*++

Routine Description:

  Dump the contents of a database to an output C file.

Arguments:

  FileName        - name of the output file to write 
  BaseName        - used for the name of the C array defined
  Languages       - list of languages of interest

Returns:

  STATUS

Notes:

  Languages is a pointer to a linked list of languages specified on
  the command line. Format is "eng" and "spa+cat". For this, print
  the strings for eng. Print the strings for spa too, but if one is
  missing look for a cat string and print if it it exists.

--*/
STATUS
StringDBDumpCStrings (
  CHAR8                       *FileName,
  CHAR8                       *BaseName,
  WCHAR_STRING_LIST           *LanguagesOfInterest,
  WCHAR_MATCHING_STRING_LIST  *IndirectionList
  )
{
  FILE                        *Fptr;
  LANGUAGE_LIST               *Lang;
  STRING_LIST                 *CurrString;
  STRING_LIST                 EmptyString;
  UINT32                      Offset;
  UINT32                      StringIndex;
  UINT32                      TempIndex;
  UINT32                      BytesThisLine;
  EFI_HII_STRING_PACK         StringPack;
  UINT8                       *Ptr;
  UINT32                      Len;
  WCHAR                       ZeroString[1];
  WCHAR_STRING_LIST           *LOIPtr;
  BOOLEAN                     LanguageOk;
  WCHAR                       *TempStringPtr;
  WCHAR                       *LangName;
  STRING_IDENTIFIER           *StringIdentifier;
  WCHAR                       Line[200];

  if ((Fptr = fopen (FileName, "w")) == NULL) {
    Error (NULL, 0, 0, FileName, "failed to open output C string file");
    return STATUS_ERROR;
  }
  //
  // Assign index values to the string identifiers
  //
  StringDBAssignStringIndexes ();
  //
  // Write the standard header to the output file, then the structure
  // definition header.
  //
  StringDBWriteStandardFileHeader (Fptr);
  fprintf (Fptr, "\nunsigned char %s[] = {\n", BaseName);
  //
  // If a given string is not defined, then we'll use this one.
  //
  memset (&EmptyString, 0, sizeof (EmptyString));
  EmptyString.Size  = sizeof (ZeroString);
  EmptyString.Str   = ZeroString;
  //
  // Process each language, then each string for each langage
  //
  ZeroString[0] = 0;
  for (Lang = mDBData.LanguageList; Lang != NULL; Lang = Lang->Next) {
    //
    // If we have a language list, then make sure this language is in that
    // list.
    //
    LanguageOk  = TRUE;
    LangName    = Lang->LanguageName;
    if (LanguagesOfInterest != NULL) {
      LanguageOk = FALSE;
      for (LOIPtr = LanguagesOfInterest; LOIPtr != NULL; LOIPtr = LOIPtr->Next) {
        if (StrnCmp (LOIPtr->Str, Lang->LanguageName, LANGUAGE_IDENTIFIER_NAME_LEN) == 0) {
          LangName    = LOIPtr->Str;
          LanguageOk  = TRUE;
          break;
        }
      }
    }

    if (!LanguageOk) {
      continue;
    }
    //
    // Process each string for this language. We have to make 3 passes on the strings:
    //   Pass1: computes sizes and fill in the string pack header
    //   Pass2: write the array of offsets
    //   Pass3: write the strings
    //
    //
    // PASS 1: Fill in and print the HII string pack header
    //
    // Compute the size for this language package and write
    // the header out. Each string package contains:
    //   Header
    //   Offset[]  -- an array of offsets to strings, of type RELOFST each
    //   String[]  -- the actual strings themselves
    //
    AsciiSPrint ( Line, sizeof(Line),
      "\n//******************************************************************************"
      "\n// Start of string definitions for %s/%s",
      Lang->LanguageName,
      Lang->PrintableLanguageName
      );
    fprintf (Fptr, "%s", Line);
    memset ((char *) &StringPack, 0, sizeof (EFI_HII_STRING_PACK));
    StringPack.Header.Type        = EFI_HII_STRING;
    StringPack.NumStringPointers  = (UINT16) mDBData.NumStringIdentifiersReferenced;
    //
    // First string is the language name. If we're printing all languages, then
    // it's just the "spa". If we were given a list of languages to print, then it's
    // the "spacat" string. Compute its offset and fill in
    // the info in the header. Since we know the language name string's length,
    // and the printable language name follows it, use that info to fill in the
    // entry for the printable language name as well.
    //
    StringPack.LanguageNameString = (STRING_OFFSET) (sizeof (EFI_HII_STRING_PACK) + (mDBData.NumStringIdentifiersReferenced * sizeof (STRING_OFFSET)));
    StringPack.PrintableLanguageName = (STRING_OFFSET) (StringPack.LanguageNameString + (StrLen (LangName) + 1) * sizeof (WCHAR));
    //
    // Add up the size of all strings so we can fill in our header.
    //
    Len = 0;
    for (StringIndex = 0; StringIndex < mDBData.NumStringIdentifiersReferenced; StringIndex++) {
      //
      // For the first string (language name), we print out the "spacat" if they
      // requested it. We set LangName to point to the proper language name string above.
      //
      if (StringIndex == STRING_ID_LANGUAGE_NAME) {
        Len += (StrLen (LangName) + 1) * sizeof (WCHAR);
      } else {
        //
        // Find a string with this language.stringname
        //
        StringIdentifier = StringDBFindStringIdentifierByIndex (StringIndex);
        if (StringIdentifier == NULL) {
          Error (NULL, 0, 0, "internal error", "invalid string index 0x%X", StringIndex);
          return STATUS_ERROR;
        }
        //
        // Find a matching string if this string identifier was referenced
        //
        EmptyString.Flags = STRING_FLAGS_UNDEFINED;
        CurrString        = NULL;
        if (StringIdentifier->Flags & STRING_FLAGS_REFERENCED) {
          CurrString = StringDBFindString (
                        Lang->LanguageName,
                        StringIdentifier->StringName,
                        NULL,
                        LanguagesOfInterest,
                        IndirectionList
                        );
          if (NULL == CurrString) {
            //
            // If string for Lang->LanguageName is not found, try to get an English version
            //
            CurrString = StringDBFindString (
                          L"eng",
                          StringIdentifier->StringName,
                          NULL,
                          LanguagesOfInterest,
                          IndirectionList
                          );
          }
        }

        if (CurrString == NULL) {
          CurrString = &EmptyString;
          EmptyString.Flags |= StringIdentifier->Flags;
        }

        Len += CurrString->Size;
      }
    }
    StringPack.Header.Length =    sizeof (EFI_HII_STRING_PACK) 
                                + mDBData.NumStringIdentifiersReferenced * sizeof (STRING_OFFSET) 
                                + Len;
    //
    // Write out the header one byte at a time
    //
    Ptr = (UINT8 *) &StringPack;
    for (TempIndex = 0; TempIndex < sizeof (EFI_HII_STRING_PACK); TempIndex++, Ptr++) {
      if ((TempIndex & 0x07) == 0) {
        fprintf (Fptr, "\n  ");
      }

      fprintf (Fptr, "0x%02X, ", (UINT32) *Ptr);
    }

    fprintf (Fptr, "\n  // offset 0x%X\n", sizeof (StringPack));
    //
    // PASS2 : write the offsets
    //
    // Traverse the list of strings again and write the array of offsets. The
    // offset to the first string is the size of the string pack header
    // plus the size of the offsets array. The other strings follow it.
    //
    StringIndex = 0;
    Offset      = sizeof (StringPack) + mDBData.NumStringIdentifiersReferenced * sizeof (STRING_OFFSET);
    for (StringIndex = 0; StringIndex < mDBData.NumStringIdentifiersReferenced; StringIndex++) {
      //
      // Write the offset, followed by a useful comment
      //
      fprintf (Fptr, "  ");
      Ptr = (UINT8 *) &Offset;
      for (TempIndex = 0; TempIndex < sizeof (STRING_OFFSET); TempIndex++) {
        fprintf (Fptr, "0x%02X, ", (UINT32) Ptr[TempIndex]);
      }
      //
      // Find the string name
      //
      StringIdentifier = StringDBFindStringIdentifierByIndex (StringIndex);
      if (StringIdentifier == NULL) {
        Error (NULL, 0, 0, "internal error", "invalid string index 0x%X", StringIndex);
        return STATUS_ERROR;
      }

      AsciiSPrint (Line, sizeof(Line) , " // offset to string %s (0x%04X)", StringIdentifier->StringName, StringIndex);
      fprintf (Fptr, "%s", Line);
      //
      // For the first string (language name), we print out the "spacat" if they
      // requested it. We set LangName to point to the proper language name string above.
      //
      if (StringIndex == STRING_ID_LANGUAGE_NAME) {
        Offset += (StrLen (LangName) + 1) * sizeof (WCHAR);
        CurrString = StringDBFindString (
                      Lang->LanguageName,
                      StringIdentifier->StringName,
                      NULL, // scope
                      NULL,
                      NULL
                      );
      } else {
        //
        // Find a matching string
        //
        CurrString = StringDBFindString (
                      Lang->LanguageName,
                      StringIdentifier->StringName,
                      NULL,   // scope
                      LanguagesOfInterest,
                      IndirectionList
                      );

        if (NULL == CurrString) {
          CurrString = StringDBFindString (
                        L"eng",
                        StringIdentifier->StringName,
                        NULL, // scope
                        LanguagesOfInterest,
                        IndirectionList
                        );
        }

        EmptyString.LanguageName = Lang->LanguageName;
        if (CurrString == NULL) {
          CurrString        = &EmptyString;
          EmptyString.Flags = STRING_FLAGS_UNDEFINED;
        } else if ((StringIdentifier->Flags & STRING_FLAGS_REFERENCED) == 0) {
          CurrString        = &EmptyString;
          EmptyString.Flags = 0;
        }

        Offset += CurrString->Size;
      }
      //
      // Print useful info about this string
      //
      if ((StringIdentifier->Flags & STRING_FLAGS_REFERENCED) == 0) {
        fprintf (Fptr, " - not referenced");
      }

      if (CurrString->Flags & STRING_FLAGS_UNDEFINED) {
        fprintf (Fptr, " - not defined for this language");
      } else if (StrCmp (CurrString->LanguageName, Lang->LanguageName) != 0) {
        AsciiSPrint (
          Line, sizeof(Line),
          " - not defined for this language -- using secondary language %s definition",
          CurrString->LanguageName
          );
        fprintf ( Fptr, "%s", Line);
      }

      fprintf (Fptr, "\n");
    }
    //
    // For unreferenced string identifiers, print a message that they are not referenced anywhere
    //
    while (StringIndex < mDBData.NumStringIdentifiers) {
      StringIdentifier = StringDBFindStringIdentifierByIndex (StringIndex);
      if (StringIdentifier != NULL) {
        AsciiSPrint (Line, sizeof(Line), "  // %s not referenced\n", StringIdentifier->StringName);
        fprintf (Fptr, "%s", Line);
      }

      StringIndex++;
    }

    //
    // PASS 3: write the strings themselves.
    // Keep track of how many bytes we write per line because some editors
    // (Visual Studio for instance) can't handle too long of lines.
    //
    Offset = sizeof (StringPack) + mDBData.NumStringIdentifiersReferenced * sizeof (STRING_OFFSET);
    for (StringIndex = 0; StringIndex < mDBData.NumStringIdentifiersReferenced; StringIndex++) {
      StringIdentifier = StringDBFindStringIdentifierByIndex (StringIndex);
      if (StringIdentifier == NULL) {
        Error (NULL, 0, 0, "internal error", "invalid string index 0x%X", StringIndex);
        return STATUS_ERROR;
      }

      AsciiSPrint (Line, sizeof(Line), "  // string %s offset 0x%08X\n  ", StringIdentifier->StringName, Offset);
      fprintf (Fptr, "%s", Line);
      //
      // For the first string (language name), we print out the "spacat" if they
      // requested it. We set LangName to point to the proper language name string above.
      //
      if (StringIndex == STRING_ID_LANGUAGE_NAME) {
        TempStringPtr = LangName;
      } else {
        //
        // Find a matching string if this string identifier was referenced
        //
        CurrString = NULL;
        if (StringIdentifier->Flags & STRING_FLAGS_REFERENCED) {
          CurrString = StringDBFindString (
                        Lang->LanguageName,
                        StringIdentifier->StringName,
                        NULL,   // scope
                        LanguagesOfInterest,
                        IndirectionList
                        );
          if (NULL == CurrString) {
            CurrString = StringDBFindString (
                          L"eng",
                          StringIdentifier->StringName,
                          NULL, // scope
                          LanguagesOfInterest,
                          IndirectionList
                          );
          }
        }

        if (CurrString == NULL) {
          CurrString = &EmptyString;
        }

        TempStringPtr = CurrString->Str;
      }

      BytesThisLine = 0;
      for (TempIndex = 0; TempStringPtr[TempIndex] != 0; TempIndex++) {
        fprintf (
          Fptr,
          "0x%02X, 0x%02X, ",
          (UINT32) TempStringPtr[TempIndex] & 0xFF,
          (UINT32) ((TempStringPtr[TempIndex] >> 8) & 0xFF)
          );
        BytesThisLine += 2;
        Offset += 2;
        //
        // Let's say we only allow 14 per line
        //
        if (BytesThisLine > 14) {
          fprintf (Fptr, "\n  ");
          BytesThisLine = 0;
        }
      }
      //
      // Print NULL WCHAR at the end of this string.
      //
      fprintf (Fptr, "0x00, 0x00,\n");
      Offset += 2;
    }
    //
    // Sanity check the offset. Make sure our running offset is what we put in the
    // string pack header.
    //
    if (StringPack.Header.Length != Offset) {
      Error (
        __FILE__,
        __LINE__,
        0,
        "application error",
        "stringpack size 0x%X does not match final size 0x%X",
        StringPack.Header.Length,
        Offset
        );
    }
  }
  //
  // Print terminator string pack, closing brace and close the file.
  // The size of 0 triggers to the consumer that this is the end.
  //
  memset ((char *) &StringPack, 0, sizeof (EFI_HII_STRING_PACK));
  StringPack.Header.Type  = EFI_HII_STRING;
  Ptr                     = (UINT8 *) &StringPack;
  fprintf (Fptr, "\n  // strings terminator pack");
  for (TempIndex = 0; TempIndex < sizeof (StringPack); TempIndex++, Ptr++) {
    if ((TempIndex & 0x0F) == 0) {
      fprintf (Fptr, "\n  ");
    }

    fprintf (Fptr, "0x%02X, ", (UINT32) *Ptr);
  }

  fprintf (Fptr, "\n};\n");
  fclose (Fptr);
  return STATUS_SUCCESS;
}

/*****************************************************************************/

/*++

Routine Description:

  Dump the #define string names

Arguments:

  FileName        - name of the output file to write 
  BaseName        - used for the protection #ifndef/#endif 

Returns:

  STATUS

--*/
STATUS
StringDBDumpStringDefines (
  CHAR8 *FileName,
  CHAR8 *BaseName
  )
{
  FILE              *Fptr;
  STRING_IDENTIFIER *Identifier;
  CHAR8             CopyBaseName[100];
  WCHAR             Line[200];
  UINT32            Index;
  const CHAR8       *StrDefHeader[] = {
    "#ifndef _%s_STRINGS_DEFINE_H_\n",
    "#define _%s_STRINGS_DEFINE_H_\n\n",
    NULL
  };

  if ((Fptr = fopen (FileName, "w")) == NULL) {
    Error (NULL, 0, 0, FileName, "failed to open output string defines file");
    return STATUS_ERROR;
  }
  //
  // Get the base source filename and convert to uppercase.
  //
  if (sizeof (CopyBaseName) <= strlen (BaseName) + 1) {
    Error (NULL, 0, 0, "application error", "StringDBDumpStringDefines() string length insufficient");
    return STATUS_ERROR;
  }

  strcpy (CopyBaseName, BaseName);
  for (Index = 0; CopyBaseName[Index] != 0; Index++) {
    if (islower (CopyBaseName[Index])) {
      CopyBaseName[Index] = (INT8) toupper (CopyBaseName[Index]);
    }
  }
  //
  // Assign index values to the string identifiers
  //
  StringDBAssignStringIndexes ();
  //
  // Write the standard header to the output file, and then the
  // protective #ifndef.
  //
  StringDBWriteStandardFileHeader (Fptr);
  for (Index = 0; StrDefHeader[Index] != NULL; Index++) {
    fprintf (Fptr, StrDefHeader[Index], CopyBaseName);
  }
  //
  // Print all the #defines for the string identifiers. Print identifiers
  // whose names start with '$' as comments. Add comments for string
  // identifiers not used as well.
  //
  Identifier = mDBData.StringIdentifier;
  while (Identifier != NULL) {
    if (Identifier->StringName[0] == L'$') {
      fprintf (Fptr, "// ");
    }

    if (Identifier->Flags & STRING_FLAGS_REFERENCED) {
      AsciiSPrint (Line, sizeof(Line), "#define %-40s 0x%04X\n", Identifier->StringName, Identifier->Index);
      fprintf (Fptr, "%s", Line);
    } else {
      AsciiSPrint (Line, sizeof(Line), "//#define %-40s 0x%04X // not referenced\n", Identifier->StringName, Identifier->Index);
      fprintf (Fptr, "%s", Line);
    }

    Identifier = Identifier->Next;
  }

  fprintf (Fptr, "\n#endif\n");
  fclose (Fptr);
  return STATUS_SUCCESS;
}

/*****************************************************************************/

/*++

Routine Description:

  Add a string identifier to the database.

Arguments:

  StringName      - name of the string identifier. For example "STR_MY_STRING"
  NewId           - if an ID has been assigned
  Flags           - characteristics for the identifier

Returns:

  STATUS

--*/
STATUS
StringDBAddStringIdentifier (
  WCHAR     *StringName,
  UINT16    *NewId,
  UINT16    Flags
  )
{
  STRING_IDENTIFIER *StringIdentifier;
  STATUS            Status;
  //
  // If it was already used for some other language, then we don't
  // need to add it. But set it to the current string identifier.
  // The referenced bit is sticky.
  //
  Status            = STATUS_SUCCESS;
  StringIdentifier  = StringDBFindStringIdentifierByName (StringName);
  if (StringIdentifier != NULL) {
    if (Flags & STRING_FLAGS_REFERENCED) {
      StringIdentifier->Flags |= STRING_FLAGS_REFERENCED;
    }

    mDBData.CurrentStringIdentifier = StringIdentifier;
    *NewId                          = (UINT16) StringIdentifier->Index;
    return Status;
  }

  StringIdentifier = (STRING_IDENTIFIER *) MALLOC (sizeof (STRING_IDENTIFIER));
  if (StringIdentifier == NULL) {
    Error (NULL, 0, 0, NULL, "memory allocation error");
    return STATUS_ERROR;
  }

  memset ((char *) StringIdentifier, 0, sizeof (STRING_IDENTIFIER));
  StringIdentifier->StringName = (WCHAR *) malloc ((StrLen (StringName) + 1) * sizeof (WCHAR));
  if (StringIdentifier->StringName == NULL) {
    Error (NULL, 0, 0, NULL, "memory allocation error");
    return STATUS_ERROR;
  }

  StrCpy (StringIdentifier->StringName, StringName);
  if (*NewId != STRING_ID_INVALID) {
    StringIdentifier->Index = *NewId;
    StringIdentifier->Flags |= STRING_FLAGS_INDEX_ASSIGNED;
    if (mDBData.NumStringIdentifiers <= StringIdentifier->Index) {
      mDBData.NumStringIdentifiers = StringIdentifier->Index + 1;
    }
  } else {
    StringIdentifier->Index = mDBData.NumStringIdentifiers++;
  }

  StringIdentifier->Flags |= Flags;
  //
  // Add it to our list of string identifiers
  //
  if (mDBData.StringIdentifier == NULL) {
    mDBData.StringIdentifier = StringIdentifier;
  } else {
    mDBData.LastStringIdentifier->Next = StringIdentifier;
  }

  mDBData.LastStringIdentifier    = StringIdentifier;
  mDBData.CurrentStringIdentifier = StringIdentifier;
  *NewId                          = (UINT16) StringIdentifier->Index;
  return Status;
}

/*****************************************************************************/

/*++

Routine Description:

  Add a new string to the database.

Arguments:

  LanguageName    - "eng" or "spa" language name
  StringName      - "STR_MY_TEXT" string name
  Scope           - from the #scope statements in the string file
  Format          - if we should format the string
  Flags           - characteristic flags for the string

Returns:

  STATUS

Notes:

  Several of the fields can be "inherited" from the previous calls to
  our database functions. For example, if scope is NULL here, then
  we'll use the previous setting.

--*/
STATUS
StringDBAddString (
  WCHAR   *LanguageName,
  WCHAR   *StringName,
  WCHAR   *Scope,
  WCHAR   *String,
  BOOLEAN Format,
  UINT16  Flags
  )
{
  LANGUAGE_LIST     *Lang;
  UINT32            Size;
  STRING_LIST       *Str;
  UINT16            StringIndex;
  WCHAR             TempLangName[4];
  STRING_IDENTIFIER *StringIdentifier;

  //
  // Check that language name is exactly 3 characters, or emit an error.
  // Truncate at 3 if it's longer, or make it 3 if it's shorter.
  //
  if (LanguageName != NULL) {
    Size = StrLen (LanguageName);
    if (Size != 3) {
      ParserError (0, "invalid length for language name", "%S", LanguageName);
      if (Size > 3) {
        LanguageName[3] = 0;
      } else {
        //
        // Make a local copy of the language name string, and extend to
        // 3 characters since we make assumptions elsewhere in this program
        // on the length.
        //
        StrCpy (TempLangName, LanguageName);
        for (; Size < 3; Size++) {
          TempLangName[Size] = L'?';
        }

        TempLangName[4] = 0;
        LanguageName    = TempLangName;
      }
    }
  }
  //
  // If they specified a language, make sure they've defined it already
  // via a #langdef statement. Otherwise use the current default language.
  //
  if (LanguageName != NULL) {
    Lang = StringDBFindLanguageList (LanguageName);
    if (Lang == NULL) {
      ParserError (0, "language not defined", "%S", LanguageName);
      return STATUS_ERROR;
    } else {
      StringDBSetCurrentLanguage (LanguageName);
    }
  } else {
    Lang = mDBData.CurrentLanguage;
    if (Lang == NULL) {
      //
      // Have to call SetLanguage() first
      //
      ParserError (0, "no language defined", "%S", StringName);
      return STATUS_ERROR;
    }
  }
  //
  // If they didn't define a string identifier, use the last string identifier
  // added.
  //
  if (StringName == NULL) {
    StringName = mDBData.CurrentStringIdentifier->StringName;
    if (StringName == NULL) {
      ParserError (0, "no string identifier previously specified", NULL);
      return STATUS_ERROR;
    }
  }
  //
  // If scope was not specified, use the default setting
  //
  if (Scope != NULL) {
    Scope = DuplicateString (Scope);
  } else {
    Scope = DuplicateString (mDBData.CurrentScope);
  }
  //
  // printf ("Adding string: %S.%S.%S\n", Lang->LanguageName, StringName, Scope);
  //
  // Check for duplicates for this Language.StringName.Scope. Allow multiple
  // definitions of the language name and printable language name, since the
  // user does not specifically define them.
  //
  if (StringDBFindString (Lang->LanguageName, StringName, Scope, NULL, NULL) != NULL) {
    if ((StrCmp (StringName, LANGUAGE_NAME_STRING_NAME) == 0) &&
        (StrCmp (StringName, PRINTABLE_LANGUAGE_NAME_STRING_NAME) == 0)
        ) {
      ParserError (
        0,
        "string multiply defined",
        "Language.Name.Scope = %S.%S.%S",
        Lang->LanguageName,
        StringName,
        Scope
        );
      return STATUS_ERROR;
    }
  }

  StringIndex = STRING_ID_INVALID;
  if (StringDBAddStringIdentifier (StringName, &StringIndex, Flags) != STATUS_SUCCESS) {
    return STATUS_ERROR;
  }

  StringIdentifier = StringDBFindStringIdentifierByName (StringName);
  //
  // Add this string to the end of the strings for this language.
  //
  Str = (STRING_LIST *) malloc (sizeof (STRING_LIST));
  if (Str == NULL) {
    Error (NULL, 0, 0, NULL, "memory allocation error");
    return STATUS_ERROR;
  }

  memset ((char *) Str, 0, sizeof (STRING_LIST));
  Size              = (StrLen (String) + 1) * sizeof (WCHAR);
  Str->Flags        = Flags;
  Str->Scope        = Scope;
  Str->StringName   = StringIdentifier->StringName;
  Str->LanguageName = DuplicateString (LanguageName);
  Str->Str          = (WCHAR *) MALLOC (Size);
  if (Str->Str == NULL) {
    Error (NULL, 0, 0, NULL, "memory allocation error");
    return STATUS_ERROR;
  }
  //
  // If not formatting, just copy the string.
  //
  StrCpy (Str->Str, String);
  if (Format) {
    StringDBFormatString (Str->Str);
  }
  //
  // Size may change after formatting. We set the size to
  // the actual size of the string, including the null for
  // easier processing later.
  //
  Str->Size = (StrLen (Str->Str) + 1) * sizeof (WCHAR);
  if (Lang->String == NULL) {
    Lang->String = Str;
  } else {
    Lang->LastString->Next = Str;
  }

  Lang->LastString = Str;
  return STATUS_SUCCESS;
}

/*****************************************************************************/

/*++

Routine Description:

  Given a language name, see if a language list for it has been defined

Arguments:

  LanguageName    - like "eng"

Returns:

  A pointer to the language list

--*/
static
LANGUAGE_LIST *
StringDBFindLanguageList (
  WCHAR *LanguageName
  )
{
  LANGUAGE_LIST *Lang;

  Lang = mDBData.LanguageList;
  while (Lang != NULL) {
    if (StrCmp (LanguageName, Lang->LanguageName) == 0) {
      break;
    }

    Lang = Lang->Next;
  }

  return Lang;
}

/*****************************************************************************/
STATUS
StringDBSetCurrentLanguage (
  WCHAR *LanguageName
  )
{
  LANGUAGE_LIST *Lang;

  Lang = StringDBFindLanguageList (LanguageName);
  if (Lang == NULL) {
    ParserError (0, "language not previously defined", "%S", LanguageName);
    return STATUS_ERROR;
  }

  mDBData.CurrentLanguage = Lang;
  return STATUS_SUCCESS;
}

/*****************************************************************************/
STATUS
StringDBAddLanguage (
  WCHAR *LanguageName,
  WCHAR *PrintableLanguageName
  )
{
  LANGUAGE_LIST *Lang;
  //
  // Check for redefinitions
  //
  Lang = StringDBFindLanguageList (LanguageName);
  if (Lang != NULL) {
    //
    // Better be the same printable name
    //
    if (StrCmp (PrintableLanguageName, Lang->PrintableLanguageName) != 0) {
      ParserError (
        0,
        "language redefinition",
        "%S:%S != %S:%S",
        Lang->LanguageName,
        Lang->PrintableLanguageName,
        LanguageName,
        PrintableLanguageName
        );
      return STATUS_ERROR;
      //
      //    } else {
      //      ParserWarning (0, "benign language redefinition", "%S", PrintableLanguageName);
      //      return STATUS_WARNING;
      //
    }
  } else {
    //
    // Allocate memory to keep track of this new language
    //
    Lang = (LANGUAGE_LIST *) malloc (sizeof (LANGUAGE_LIST));
    if (Lang == NULL) {
      Error (NULL, 0, 0, NULL, "memory allocation error");
      return STATUS_ERROR;
    }

    memset ((char *) Lang, 0, sizeof (LANGUAGE_LIST));
    //
    // Save the language name, then allocate memory to save the
    // printable language name
    //
    StrCpy (Lang->LanguageName, LanguageName);
    Lang->PrintableLanguageName = (WCHAR *) malloc ((StrLen (PrintableLanguageName) + 1) * sizeof (WCHAR));
    if (Lang->PrintableLanguageName == NULL) {
      Error (NULL, 0, 0, NULL, "memory allocation error");
      return STATUS_ERROR;
    }

    StrCpy (Lang->PrintableLanguageName, PrintableLanguageName);

    if (mDBData.LanguageList == NULL) {
      mDBData.LanguageList = Lang;
    } else {
      mDBData.LastLanguageList->Next = Lang;
    }

    mDBData.LastLanguageList = Lang;
  }
  //
  // Default is to make our active language this new one
  //
  StringDBSetCurrentLanguage (LanguageName);
  //
  // The first two strings for any language are the language name,
  // followed by the printable language name. Add them and set them
  // to referenced so they never get stripped out.
  //
  StringDBAddString (
    LanguageName,
    LANGUAGE_NAME_STRING_NAME,
    NULL,
    LanguageName,
    FALSE,
    STRING_FLAGS_REFERENCED
    );
  StringDBAddString (
    LanguageName,
    PRINTABLE_LANGUAGE_NAME_STRING_NAME,
    NULL,
    PrintableLanguageName,
    FALSE,
    STRING_FLAGS_REFERENCED
    );
  return STATUS_SUCCESS;
}

/*****************************************************************************/
static
STRING_IDENTIFIER *
StringDBFindStringIdentifierByName (
  WCHAR *StringName
  )
{
  STRING_IDENTIFIER *Identifier;

  Identifier = mDBData.StringIdentifier;
  while (Identifier != NULL) {
    if (StrCmp (StringName, Identifier->StringName) == 0) {
      return Identifier;
    }

    Identifier = Identifier->Next;
  }

  return NULL;
}

static
STRING_IDENTIFIER *
StringDBFindStringIdentifierByIndex (
  UINT32    StringIndex
  )
{
  STRING_IDENTIFIER *Identifier;

  Identifier = mDBData.StringIdentifier;
  while (Identifier != NULL) {
    if (Identifier->Index == StringIndex) {
      return Identifier;
    }

    Identifier = Identifier->Next;
  }

  return NULL;
}

/*****************************************************************************/
static
void
StringDBWriteStandardFileHeader (
  FILE *OutFptr
  )
{
  UINT32  TempIndex;
  for (TempIndex = 0; mSourceFileHeader[TempIndex] != NULL; TempIndex++) {
    fprintf (OutFptr, "%s\n", mSourceFileHeader[TempIndex]);
  }
}

/*****************************************************************************/

/*++

Routine Description:
  
  Given a Unicode string from an input file, reformat the string to replace
  backslash control sequences with the appropriate encoding.

Arguments:

  String        - pointer to string to reformat

Returns:

  Nothing

--*/
void
StringDBFormatString (
  WCHAR   *String
  )
{
  WCHAR *From;
  WCHAR *To;
  int   HexNibbles;
  WCHAR HexValue;
  //
  // Go through the string and process any formatting characters
  //
  From  = String;
  To    = String;
  while (*From) {
    if (*From == UNICODE_BACKSLASH) {
      //
      // First look for \wide and replace with the appropriate control character. Note that
      // when you have "define STR L"ABC"", then sizeof(ABC) is 8 because the null char is
      // counted. Make adjustments for this. We advance From below, so subtract 2 each time.
      //
      if (StrnCmp (From, UNICODE_WIDE_STRING, sizeof (UNICODE_WIDE_STRING) / sizeof (WCHAR) - 1) == 0) {
        *To = WIDE_CHAR;
        From += sizeof (UNICODE_WIDE_STRING) / sizeof (WCHAR) - 2;
      } else if (StrnCmp (From, UNICODE_NARROW_STRING, sizeof (UNICODE_NARROW_STRING) / sizeof (WCHAR) - 1) == 0) {
        //
        // Found: \narrow
        //
        *To = NARROW_CHAR;
        From += sizeof (UNICODE_NARROW_STRING) / sizeof (WCHAR) - 2;
      } else if (StrnCmp (From, UNICODE_NBR_STRING, sizeof (UNICODE_NBR_STRING) / sizeof (WCHAR) - 1) == 0) {
        //
        // Found: \nbr
        //
        *To = NON_BREAKING_CHAR;
        From += sizeof (UNICODE_NBR_STRING) / sizeof (WCHAR) - 2;
      } else if (StrnCmp (From, UNICODE_BR_STRING, sizeof (UNICODE_BR_STRING) / sizeof (WCHAR) - 1) == 0) {
        //
        // Found: \br -- pass through untouched
        //
        *To = *From;
      } else {
        //
        // Standard one-character control sequences such as \n, \r, \\, or \x
        //
        From++;
        switch (*From) {
        case ASCII_TO_UNICODE ('n'):
          *To = UNICODE_CR;
          To++;
          *To = UNICODE_LF;
          break;

        //
        // carriage return
        //
        case ASCII_TO_UNICODE ('r'):
          *To = UNICODE_CR;
          break;

        //
        // backslash
        //
        case UNICODE_BACKSLASH:
          *To = UNICODE_BACKSLASH;
          break;

        //
        // Tab
        //
        case ASCII_TO_UNICODE ('t'):
          *To = UNICODE_TAB;
          break;

        //
        // embedded double-quote
        //
        case UNICODE_DOUBLE_QUOTE:
          *To = UNICODE_DOUBLE_QUOTE;
          break;

        //
        // Hex Unicode character \x1234. We'll process up to 4 hex characters
        //
        case ASCII_TO_UNICODE ('x'):
          HexValue = 0;
          for (HexNibbles = 0; HexNibbles < 4; HexNibbles++) {
            if ((From[1] >= UNICODE_0) && (From[1] <= UNICODE_9)) {
              HexValue = (HexValue << 4) | (From[1] - UNICODE_0);
            } else if ((From[1] >= UNICODE_a) && (From[1] <= UNICODE_f)) {
              HexValue = (HexValue << 4) | (10 + From[1] - UNICODE_a);
            } else if ((From[1] >= UNICODE_A) && (From[1] <= UNICODE_F)) {
              HexValue = (HexValue << 4) | (10 + From[1] - UNICODE_A);
            } else {
              break;
            }

            From++;
          }

          if (HexNibbles == 0) {
            ParserWarning (
              0,
              "expected at least one valid hex digit with \\x escaped character in string",
              "\\%C",
              *From
              );
          } else {
            *To = HexValue;
          }
          break;

        default:
          *To = UNICODE_SPACE;
          ParserWarning (0, "invalid escaped character in string", "\\%C", *From);
          break;
        }
      }
    } else {
      *To = *From;
    }

    From++;
    To++;
  }

  *To = 0;
}

/*****************************************************************************/
STATUS
StringDBReadDatabase (
  CHAR8   *DBFileName,
  BOOLEAN IgnoreIfNotExist,
  BOOLEAN Verbose
  )
{
  STRING_DB_HEADER    DbHeader;
  STATUS              Status;
  FILE                *DBFptr;
  DB_DATA_ITEM_HEADER DataItemHeader;

  Status  = STATUS_SUCCESS;
  DBFptr  = NULL;
  //
  //  if (Verbose) {
  //    fprintf (stdout, "Reading database file %s\n", DBFileName);
  //  }
  //
  // Try to open the input file
  //
  if ((DBFptr = fopen (DBFileName, "rb")) == NULL) {
    if (IgnoreIfNotExist) {
      return STATUS_SUCCESS;
    }

    Error (NULL, 0, 0, DBFileName, "failed to open input database file for reading");
    return STATUS_ERROR;
  }
  //
  // Read and verify the database header
  //
  if (fread ((void *) &DbHeader, sizeof (STRING_DB_HEADER), 1, DBFptr) != 1) {
    Error (NULL, 0, 0, DBFileName, "failed to read header from database file");
    Status = STATUS_ERROR;
    goto Finish;
  }

  if (DbHeader.Key != STRING_DB_KEY) {
    Error (NULL, 0, 0, DBFileName, "invalid header in database file");
    Status = STATUS_ERROR;
    goto Finish;
  }

  if ((DbHeader.Version & STRING_DB_MAJOR_VERSION_MASK) != (STRING_DB_VERSION & STRING_DB_MAJOR_VERSION_MASK)) {
    Error (NULL, 0, 0, DBFileName, "incompatible database file version -- rebuild clean");
    Status = STATUS_ERROR;
    goto Finish;
  }
  //
  // Read remaining items
  //
  while (fread (&DataItemHeader, sizeof (DataItemHeader), 1, DBFptr) == 1) {
    switch (DataItemHeader.DataType) {
    case DB_DATA_TYPE_STRING_IDENTIFIER:
      StringDBReadStringIdentifier (DBFptr);
      break;

    case DB_DATA_TYPE_LANGUAGE_DEFINITION:
      StringDBReadLanguageDefinition (DBFptr);
      break;

    case DB_DATA_TYPE_STRING_DEFINITION:
      StringDBReadString (DBFptr);
      break;

    default:
      Error (
        NULL,
        0,
        0,
        "database corrupted",
        "invalid data item type 0x%X at offset 0x%X",
        (UINT32) DataItemHeader.DataType,
        ftell (DBFptr) - sizeof (DataItemHeader)
        );
      Status = STATUS_ERROR;
      goto Finish;
    }
  }

Finish:
  if (DBFptr != NULL) {
    fclose (DBFptr);
  }

  return Status;
}

/*****************************************************************************/

/*++

Routine Description:
  
  Write everything we know to the output database file. Write:

  Database header
  String identifiers[]
  StringPacks[]

Arguments:

  DBFileName    - name of the file to write to
  Verbose       - for debug purposes, print info messages along the way.

Returns:

  STATUS

--*/
STATUS
StringDBWriteDatabase (
  CHAR8   *DBFileName,
  BOOLEAN Verbose
  )
{
  STRING_DB_HEADER  DbHeader;
  UINT32            Counter;
  UINT32            StrLength;
  LANGUAGE_LIST     *Lang;
  STRING_IDENTIFIER *StringIdentifier;
  STRING_LIST       *StrList;
  FILE              *DBFptr;

  if (Verbose) {
    fprintf (stdout, "Writing database %s\n", DBFileName);
  }

  if ((DBFptr = fopen (DBFileName, "wb")) == NULL) {
    Error (NULL, 0, 0, DBFileName, "failed to open output database file for writing");
    return STATUS_ERROR;
  }
  //
  // Fill in and write the database header
  //
  memset (&DbHeader, 0, sizeof (STRING_DB_HEADER));
  DbHeader.HeaderSize = sizeof (STRING_DB_HEADER);
  DbHeader.Key        = STRING_DB_KEY;
  DbHeader.Version    = STRING_DB_VERSION;
  //
  // Count the number of languages we have
  //
  for (Lang = mDBData.LanguageList; Lang != NULL; Lang = Lang->Next) {
    DbHeader.NumLanguages++;
  }
  //
  // Count up how many string identifiers we have, and total up the
  // size of the names plus the size of the flags field we will
  // write out too.
  //
  DbHeader.NumStringIdenfiers = mDBData.NumStringIdentifiers;
  StringIdentifier            = mDBData.StringIdentifier;
  for (Counter = 0; Counter < mDBData.NumStringIdentifiers; Counter++) {
    StrLength = StrLen (StringIdentifier->StringName) + 1;
    DbHeader.StringIdentifiersSize += StrLength * sizeof (WCHAR) + sizeof (StringIdentifier->Flags);
    StringIdentifier = StringIdentifier->Next;
  }

  //
  // Write the header
  //
  fwrite (&DbHeader, sizeof (STRING_DB_HEADER), 1, DBFptr);
  if (Verbose) {
    fprintf (stdout, "  Number of string identifiers  0x%04X\n", DbHeader.NumStringIdenfiers);
    fprintf (stdout, "  Number of languages           %d\n", DbHeader.NumLanguages);
  }
  //
  // Write the string identifiers
  //
  for (StringIdentifier = mDBData.StringIdentifier; StringIdentifier != NULL; StringIdentifier = StringIdentifier->Next) {
    StringDBWriteStringIdentifier (
      DBFptr,
      (UINT16) StringIdentifier->Index,
      StringIdentifier->Flags,
      StringIdentifier->StringName
      );
  }
  //
  // Now write all the strings for each language
  //
  for (Lang = mDBData.LanguageList; Lang != NULL; Lang = Lang->Next) {
    StringDBWriteLanguageDefinition (DBFptr, Lang->LanguageName, Lang->PrintableLanguageName);
    for (StrList = Lang->String; StrList != NULL; StrList = StrList->Next) {
      StringDBWriteString (
        DBFptr,
        StrList->Flags,
        Lang->LanguageName,
        StrList->StringName,
        StrList->Scope,
        StrList->Str
        );
    }
  }

  fclose (DBFptr);
  return STATUS_SUCCESS;
}

STATUS
StringDBSetStringReferenced (
  CHAR8     *StringIdentifierName,
  BOOLEAN   IgnoreNotFound
  )
{
  STRING_IDENTIFIER *Id;
  WCHAR             *WName;
  STATUS            Status;
  //
  // See if it's already been defined.
  //
  Status  = STATUS_SUCCESS;
  WName   = (WCHAR *) malloc ((strlen (StringIdentifierName) + 1) * sizeof (WCHAR));
  UnicodeSPrint (WName, (strlen (StringIdentifierName) + 1) * sizeof (WCHAR), L"%a", StringIdentifierName);
  Id = StringDBFindStringIdentifierByName (WName);
  if (Id != NULL) {
    Id->Flags |= STRING_FLAGS_REFERENCED;
  } else {
    if (IgnoreNotFound == 0) {
      ParserWarning (0, StringIdentifierName, "string identifier not found in database");
      Status = STATUS_WARNING;
    }
  }

  free (WName);
  return Status;
}

/*****************************************************************************/

/*++

Routine Description:

  Dump the contents of a database to an output unicode file.

Arguments:

  DBFileName        - name of the pre-existing database file to read
  OutputFileName    - name of the file to dump the database contents to
  Verbose           - for printing of additional info useful for debugging

Returns:

  STATUS

Notes:

  There's some issue with the unicode printing routines. Therefore to 
  write to the output file properly, open it as binary and use fwrite.
  Ideally we could open it with just L"w" and use fwprintf().

--*/
STATUS
StringDBDumpDatabase (
  CHAR8               *DBFileName,
  CHAR8               *OutputFileName,
  BOOLEAN             Verbose
  )
{
  LANGUAGE_LIST     *Lang;
  STRING_IDENTIFIER *StringIdentifier;
  STRING_LIST       *StrList;
  FILE              *OutFptr;
  WCHAR             WChar;
  WCHAR             CrLf[2];
  WCHAR             Line[200];
  WCHAR             *Scope;
  //
  // This function assumes the database has already been read, and
  // we're just dumping our internal data structures to a unicode file.
  //
  if (Verbose) {
    fprintf (stdout, "Dumping database file %s\n", DBFileName);
  }

  OutFptr         = fopen (OutputFileName, "wb");
  if (OutFptr == NULL) {
    Error (NULL, 0, 0, OutputFileName, "failed to open output file for writing");
    return STATUS_ERROR;
  }

  WChar = UNICODE_FILE_START;
  fwrite (&WChar, sizeof (WCHAR), 1, OutFptr);
  CrLf[1] = UNICODE_LF;
  CrLf[0] = UNICODE_CR;
  //
  // The default control character is '/'. Make it '#' by writing
  // "/=#" to the output file.
  //
  UnicodeSPrint (Line, sizeof(Line), L"/=#");
  fwrite (Line, StrLen (Line) * sizeof (WCHAR), 1, OutFptr);
  fwrite (&CrLf, sizeof (CrLf), 1, OutFptr);
  fwrite (&CrLf, sizeof (CrLf), 1, OutFptr);
  //
  // Dump all the string identifiers and their values
  //
  StringDBAssignStringIndexes ();
  for (StringIdentifier = mDBData.StringIdentifier; StringIdentifier != NULL; StringIdentifier = StringIdentifier->Next) {
    //
    // Write the "#define " string
    //
    if (StringIdentifier->Flags & STRING_FLAGS_REFERENCED) {
      UnicodeSPrint (
        Line,
        sizeof(Line), L"%s %-60.60s 0x%04X",
        DEFINE_STR,
        StringIdentifier->StringName,
        StringIdentifier->Index
        );
    } else {
      UnicodeSPrint (
        Line,
        sizeof(Line), L"%s %-60.60s 0x%04X  // NOT REFERENCED",
        DEFINE_STR,
        StringIdentifier->StringName,
        StringIdentifier->Index
        );
    }

    fwrite (Line, StrLen (Line) * sizeof (WCHAR), 1, OutFptr);
    fwrite (&CrLf, sizeof (CrLf), 1, OutFptr);
  }

  fwrite (&CrLf, sizeof (CrLf), 1, OutFptr);
  //
  // Now write all the strings for each language.
  //
  WChar = UNICODE_DOUBLE_QUOTE;
  Scope = NULL;
  for (Lang = mDBData.LanguageList; Lang != NULL; Lang = Lang->Next) {
    fwrite (&CrLf, sizeof (CrLf), 1, OutFptr);
    UnicodeSPrint (Line, sizeof(Line), L"#langdef %s \"%s\"", Lang->LanguageName, Lang->PrintableLanguageName);
    fwrite (Line, StrLen (Line) * sizeof (WCHAR), 1, OutFptr);
    fwrite (&CrLf, sizeof (CrLf), 1, OutFptr);
    fwrite (&CrLf, sizeof (CrLf), 1, OutFptr);
    //
    // Now the strings (in double-quotes) for this language. Write
    // #string STR_NAME  #language eng "string"
    //
    for (StrList = Lang->String; StrList != NULL; StrList = StrList->Next) {
      //
      // Print the internal flags for debug
      //
      UnicodeSPrint (Line, sizeof(Line), L"// flags=0x%02X", (UINT32) StrList->Flags);
      fwrite (Line, StrLen (Line) * sizeof (WCHAR), 1, OutFptr);
      fwrite (&CrLf, sizeof (CrLf), 1, OutFptr);
      //
      // Print the scope if changed
      //
      if ((Scope == NULL) || (StrCmp (Scope, StrList->Scope) != 0)) {
        UnicodeSPrint (Line, sizeof(Line), L"#scope %s", StrList->Scope);
        fwrite (Line, StrLen (Line) * sizeof (WCHAR), 1, OutFptr);
        fwrite (&CrLf, sizeof (CrLf), 1, OutFptr);
        Scope = StrList->Scope;
      }

      UnicodeSPrint (
        Line,
        sizeof(Line), L"#string %-50.50s #language %s \"",
        StrList->StringName,
        Lang->LanguageName
        );
      fwrite (Line, StrLen (Line) * sizeof (WCHAR), 1, OutFptr);
      fwrite (StrList->Str, StrList->Size - sizeof (WCHAR), 1, OutFptr);
      UnicodeSPrint (Line, sizeof(Line), L"\"");
      fwrite (Line, StrLen (Line) * sizeof (WCHAR), 1, OutFptr);
      fwrite (&CrLf, sizeof (CrLf), 1, OutFptr);
    }
  }

  fclose (OutFptr);
  return STATUS_SUCCESS;
}

/*****************************************************************************/

/*++

Routine Description:

  Given a primary language, a string identifier number, and a list of
  languages, find a secondary string.

Arguments:

  LanguageName      - primary language, like "spa"
  StringId          - string index value
  LanguageList      - linked list of "eng", "spa+cat",...

Returns:

  Pointer to a secondary string if found. NULL otherwise.

Notes:
 
  Given: LanguageName "spa"   and  LanguageList "spa+cat", match the
  "spa" and extract the "cat" and see if there is a string defined
  for "cat".StringId.

--*/
static
STATUS
StringDBWriteStringIdentifier (
  FILE                *DBFptr,
  UINT16              StringId,
  UINT16              Flags,
  WCHAR               *IdentifierName
  )
{
  DB_DATA_ITEM_HEADER Hdr;
  memset (&Hdr, 0, sizeof (DB_DATA_ITEM_HEADER));
  Hdr.DataType = DB_DATA_TYPE_STRING_IDENTIFIER;
  if (fwrite (&Hdr, sizeof (DB_DATA_ITEM_HEADER), 1, DBFptr) != 1) {
    Error (NULL, 0, 0, "failed to write string to output database file", NULL);
    return STATUS_ERROR;
  }

  if (fwrite (&StringId, sizeof (StringId), 1, DBFptr) != 1) {
    Error (NULL, 0, 0, "failed to write StringId to output database", NULL);
    return STATUS_ERROR;
  }

  if (fwrite (&Flags, sizeof (Flags), 1, DBFptr) != 1) {
    Error (NULL, 0, 0, "failed to write StringId flags to output database", NULL);
    return STATUS_ERROR;
  }

  if (StringDBWriteGenericString (DBFptr, IdentifierName) != STATUS_SUCCESS) {
    return STATUS_ERROR;
  }

  return STATUS_SUCCESS;
}

static
STATUS
StringDBReadStringIdentifier (
  FILE                *DBFptr
  )
{
  WCHAR   *IdentifierName;
  UINT16  Flags;
  UINT16  StringId;
  UINT16  Size;

  if (fread (&StringId, sizeof (StringId), 1, DBFptr) != 1) {
    Error (NULL, 0, 0, "failed to read StringId from database", NULL);
    return STATUS_ERROR;
  }

  if (fread (&Flags, sizeof (Flags), 1, DBFptr) != 1) {
    Error (NULL, 0, 0, "failed to read StringId flags from database", NULL);
    return STATUS_ERROR;
  }

  if (StringDBReadGenericString (DBFptr, &Size, &IdentifierName) != STATUS_SUCCESS) {
    return STATUS_ERROR;
  }

  StringDBAddStringIdentifier (IdentifierName, &StringId, Flags);
  //
  // printf ("STRID:  0x%04X %S\n", (UINT32)StringId, IdentifierName);
  //
  FREE (IdentifierName);
  return STATUS_SUCCESS;
}

static
STATUS
StringDBWriteString (
  FILE            *DBFptr,
  UINT16          Flags,
  WCHAR           *Language,
  WCHAR           *StringName,
  WCHAR           *Scope,
  WCHAR           *Str
  )
{
  DB_DATA_ITEM_HEADER Hdr;
  memset (&Hdr, 0, sizeof (DB_DATA_ITEM_HEADER));
  Hdr.DataType = DB_DATA_TYPE_STRING_DEFINITION;
  if (fwrite (&Hdr, sizeof (DB_DATA_ITEM_HEADER), 1, DBFptr) != 1) {
    Error (NULL, 0, 0, "failed to write string header to output database file", NULL);
    return STATUS_ERROR;
  }

  if (fwrite (&Flags, sizeof (Flags), 1, DBFptr) != 1) {
    Error (NULL, 0, 0, "failed to write string flags to output database", NULL);
    return STATUS_ERROR;
  }

  if (StringDBWriteGenericString (DBFptr, Language) != STATUS_SUCCESS) {
    return STATUS_ERROR;
  }

  if (StringDBWriteGenericString (DBFptr, StringName) != STATUS_SUCCESS) {
    return STATUS_ERROR;
  }

  if (StringDBWriteGenericString (DBFptr, Scope) != STATUS_SUCCESS) {
    return STATUS_ERROR;
  }

  if (StringDBWriteGenericString (DBFptr, Str) != STATUS_SUCCESS) {
    return STATUS_ERROR;
  }
  //
  // printf ("DBWriteString: %S.%S.%S\n", Language, StringName, Scope);
  //
  return STATUS_SUCCESS;
}

static
STATUS
StringDBReadString (
  FILE            *DBFptr
  )
{
  UINT16  Flags;
  UINT16  Size;
  WCHAR   *Language;
  WCHAR   *StringName;
  WCHAR   *Scope;
  WCHAR   *Str;

  if (fread (&Flags, sizeof (Flags), 1, DBFptr) != 1) {
    Error (NULL, 0, 0, "failed to read string flags from database", NULL);
    return STATUS_ERROR;
  }

  if (StringDBReadGenericString (DBFptr, &Size, &Language) != STATUS_SUCCESS) {
    return STATUS_ERROR;
  }

  if (StringDBReadGenericString (DBFptr, &Size, &StringName) != STATUS_SUCCESS) {
    return STATUS_ERROR;
  }

  if (StringDBReadGenericString (DBFptr, &Size, &Scope) != STATUS_SUCCESS) {
    return STATUS_ERROR;
  }

  if (StringDBReadGenericString (DBFptr, &Size, &Str) != STATUS_SUCCESS) {
    return STATUS_ERROR;
  }
  //
  // If the first or second string (language name and printable language name),
  // then skip them. They're added via language definitions data items in
  // the database.
  //
  if (StringName[0] != L'$') {
    StringDBAddString (Language, StringName, Scope, Str, FALSE, Flags);
  }
  //
  // printf ("DBReadString: %S.%S.%S\n", Language, StringName, Scope);
  //
  FREE (Language);
  FREE (StringName);
  if (Str != NULL) {
    FREE (Str);
  }

  if (Scope != NULL) {
    FREE (Scope);
  }

  return STATUS_SUCCESS;
}

static
STATUS
StringDBWriteLanguageDefinition (
  FILE            *DBFptr,
  WCHAR           *LanguageName,
  WCHAR           *PrintableLanguageName
  )
{
  DB_DATA_ITEM_HEADER Hdr;
  memset (&Hdr, 0, sizeof (DB_DATA_ITEM_HEADER));
  Hdr.DataType = DB_DATA_TYPE_LANGUAGE_DEFINITION;
  if (fwrite (&Hdr, sizeof (DB_DATA_ITEM_HEADER), 1, DBFptr) != 1) {
    Error (NULL, 0, 0, "failed to write string to output database file", NULL);
    return STATUS_ERROR;
  }

  if (StringDBWriteGenericString (DBFptr, LanguageName) != STATUS_SUCCESS) {
    return STATUS_ERROR;
  }

  if (StringDBWriteGenericString (DBFptr, PrintableLanguageName) != STATUS_SUCCESS) {
    return STATUS_ERROR;
  }

  return STATUS_SUCCESS;
}

static
STATUS
StringDBReadLanguageDefinition (
  FILE            *DBFptr
  )
{
  WCHAR   *LanguageName;
  WCHAR   *PrintableLanguageName;
  UINT16  Size;
  STATUS  Status;

  if (StringDBReadGenericString (DBFptr, &Size, &LanguageName) != STATUS_SUCCESS) {
    return STATUS_ERROR;
  }

  if (StringDBReadGenericString (DBFptr, &Size, &PrintableLanguageName) != STATUS_SUCCESS) {
    return STATUS_ERROR;
  }
  //
  // printf("LANG: %S %S\n", LanguageName, PrintableLanguageName);
  //
  Status = StringDBAddLanguage (LanguageName, PrintableLanguageName);
  FREE (LanguageName);
  FREE (PrintableLanguageName);
  return Status;
}
//
// All unicode strings in the database consist of a UINT16 length
// field, followed by the string itself. This routine reads one
// of those and returns the info.
//
static
STATUS
StringDBReadGenericString (
  FILE      *DBFptr,
  UINT16    *Size,
  WCHAR     **Str
  )
{
  UINT16  LSize;
  UINT16  Flags;
  WCHAR   *LStr;

  if (fread (&LSize, sizeof (UINT16), 1, DBFptr) != 1) {
    Error (NULL, 0, 0, "failed to read a string length field from the database", NULL);
    return STATUS_ERROR;
  }

  if (fread (&Flags, sizeof (UINT16), 1, DBFptr) != 1) {
    Error (NULL, 0, 0, "failed to read a string flags field from the database", NULL);
    return STATUS_ERROR;
  }

  LStr = MALLOC (LSize);
  if (LStr == NULL) {
    Error (__FILE__, __LINE__, 0, "memory allocation failed reading the database", NULL);
    return STATUS_ERROR;
  }

  if (fread (LStr, sizeof (WCHAR), (UINT32) LSize / sizeof (WCHAR), DBFptr) != (UINT32) LSize / sizeof (WCHAR)) {
    Error (NULL, 0, 0, "failed to read string from database", NULL);
    Error (NULL, 0, 0, "database read failure", "offset 0x%X", ftell (DBFptr));
    free (LStr);
    return STATUS_ERROR;
  }
  //
  // printf ("DBR: %S\n", LStr);
  //
  // If the flags field indicated we were asked to write a NULL string, then
  // return them a NULL pointer.
  //
  if (Flags & STRING_FLAGS_UNDEFINED) {
    *Size = 0;
    *Str  = NULL;
  } else {
    *Size = LSize;
    *Str  = LStr;
  }

  return STATUS_SUCCESS;
}

static
STATUS
StringDBWriteGenericString (
  FILE      *DBFptr,
  WCHAR     *Str
  )
{
  UINT16  Size;
  UINT16  Flags;
  WCHAR   ZeroString[1];
  //
  // Strings in the database consist of a size UINT16 followed
  // by the string itself.
  //
  if (Str == NULL) {
    ZeroString[0] = 0;
    Str           = ZeroString;
    Size          = sizeof (ZeroString);
    Flags         = STRING_FLAGS_UNDEFINED;
  } else {
    Flags = 0;
    Size  = (UINT16) ((StrLen (Str) + 1) * sizeof (WCHAR));
  }

  if (fwrite (&Size, sizeof (UINT16), 1, DBFptr) != 1) {
    Error (NULL, 0, 0, "failed to write string size to database", NULL);
    return STATUS_ERROR;
  }

  if (fwrite (&Flags, sizeof (UINT16), 1, DBFptr) != 1) {
    Error (NULL, 0, 0, "failed to write string flags to database", NULL);
    return STATUS_ERROR;
  }

  if (fwrite (Str, sizeof (WCHAR), Size / sizeof (WCHAR), DBFptr) != Size / sizeof (WCHAR)) {
    Error (NULL, 0, 0, "failed to write string to database", NULL);
    return STATUS_ERROR;
  }

  return STATUS_SUCCESS;
}

static
STRING_LIST *
StringDBFindString (
  WCHAR                       *LanguageName,
  WCHAR                       *StringName,
  WCHAR                       *Scope,
  WCHAR_STRING_LIST           *LanguagesOfInterest,
  WCHAR_MATCHING_STRING_LIST  *IndirectionList
  )
{
  LANGUAGE_LIST               *Lang;
  STRING_LIST                 *CurrString;
  WCHAR_MATCHING_STRING_LIST  *IndListPtr;
  WCHAR                       TempLangName[LANGUAGE_IDENTIFIER_NAME_LEN + 1];
  WCHAR                       *WCharPtr;

  //
  // If we were given an indirection list, then see if one was specified for this
  // string identifier. That is to say, if the indirection says "STR_ID_MY_FAVORITE MyScope",
  // then if this string name matches one in the list, then do a lookup with the
  // specified scope and return that value.
  //
  if (IndirectionList != NULL) {
    for (IndListPtr = IndirectionList; IndListPtr != NULL; IndListPtr = IndListPtr->Next) {
      if (StrCmp (StringName, IndListPtr->Str1) == 0) {
        CurrString = StringDBFindString (LanguageName, StringName, IndListPtr->Str2, LanguagesOfInterest, NULL);
        if (CurrString != NULL) {
          return CurrString;
        }
      }
    }
  }
  //
  // First look for exact match language.stringname
  //
  for (Lang = mDBData.LanguageList; Lang != NULL; Lang = Lang->Next) {
    if (StrCmp (LanguageName, Lang->LanguageName) == 0) {
      //
      // Found language match. Try to find string name match
      //
      for (CurrString = Lang->String; CurrString != NULL; CurrString = CurrString->Next) {
        if (StrCmp (StringName, CurrString->StringName) == 0) {
          //
          // Found a string name match. See if we're supposed to find
          // a scope match.
          //
          if (Scope != NULL) {
            if (StrCmp (CurrString->Scope, Scope) == 0) {
              return CurrString;
            }
          } else {
            return CurrString;
          }
        }
      }
    }
  }
  //
  // If we got here, then we didn't find a match. Look for secondary string
  // matches. That is to say, if we're processing "spa", and they requested
  // "spa+cat", then recursively call with "cat"
  //
  while (LanguagesOfInterest != NULL) {
    //
    // If this is the language we're looking for, then process the
    // languages of interest list for it.
    //
    if (StrnCmp (LanguageName, LanguagesOfInterest->Str, LANGUAGE_IDENTIFIER_NAME_LEN) == 0) {
      WCharPtr = LanguagesOfInterest->Str + LANGUAGE_IDENTIFIER_NAME_LEN;
      while (*WCharPtr) {
        //
        // Double-check the length, though it should have been checked on the
        // command line.
        //
        if (StrLen (WCharPtr) < LANGUAGE_IDENTIFIER_NAME_LEN) {
          Error (NULL, 0, 0, "malformed alternate language list", "%S", LanguagesOfInterest->Str);
          return NULL;
        }

        StrnCpy (TempLangName, WCharPtr, LANGUAGE_IDENTIFIER_NAME_LEN);
        TempLangName[LANGUAGE_IDENTIFIER_NAME_LEN]  = 0;
        CurrString = StringDBFindString (TempLangName, StringName, NULL, NULL, IndirectionList);
        if (CurrString != NULL) {
          return CurrString;
        }

        WCharPtr += LANGUAGE_IDENTIFIER_NAME_LEN;
      }
    }

    LanguagesOfInterest = LanguagesOfInterest->Next;
  }

  return NULL;
}

STATUS
StringDBSetScope (
  WCHAR   *Scope
  )
{
  //
  // Free up existing scope memory.
  //
  if (mDBData.CurrentScope != NULL) {
    FREE (mDBData.CurrentScope);
  }

  mDBData.CurrentScope = DuplicateString (Scope);
  return STATUS_SUCCESS;
}
//
// We typically don't assign index values to string identifiers
// until we're ready to write out files. To reduce the size of
// the output file, re-order the string identifiers to move any
// unreferenced ones to the end. Then we'll walk the list
// again to assign string indexes, keeping track of the last
// one referenced.
//
static
void
StringDBAssignStringIndexes (
  VOID
  )
{
  STRING_IDENTIFIER *StrId;
  STRING_IDENTIFIER *FirstUsed;
  STRING_IDENTIFIER *LastUsed;
  STRING_IDENTIFIER *FirstUnused;
  STRING_IDENTIFIER *LastUnused;
  UINT32            Index;
  UINT32            MaxReferenced;

  //
  // Create two lists -- used and unused. Then put them together with
  // the unused ones on the end.
  //
  FirstUsed   = NULL;
  LastUsed    = NULL;
  FirstUnused = NULL;
  LastUnused  = NULL;
  StrId       = mDBData.StringIdentifier;
  while (StrId != NULL) {
    if ((StrId->Flags & STRING_FLAGS_REFERENCED) == 0) {
      //
      // Put it on the unused list
      //
      if (FirstUnused == NULL) {
        FirstUnused = StrId;
      } else {
        LastUnused->Next = StrId;
      }

      LastUnused        = StrId;
      StrId             = StrId->Next;
      LastUnused->Next  = NULL;
    } else {
      //
      // Put it on the used list
      //
      if (FirstUsed == NULL) {
        FirstUsed = StrId;
      } else {
        LastUsed->Next = StrId;
      }

      LastUsed        = StrId;
      StrId           = StrId->Next;
      LastUsed->Next  = NULL;
    }
  }
  //
  // Join the lists
  //
  if (FirstUsed != NULL) {
    mDBData.StringIdentifier  = FirstUsed;
    LastUsed->Next            = FirstUnused;
  } else {
    mDBData.StringIdentifier = FirstUnused;
  }

  MaxReferenced = 0;
  Index         = 0;
  for (StrId = mDBData.StringIdentifier; StrId != NULL; StrId = StrId->Next) {
    StrId->Index = Index;
    Index++;
    if (StrId->Flags & STRING_FLAGS_REFERENCED) {
      mDBData.NumStringIdentifiersReferenced = Index;
    }
  }

  mDBData.NumStringIdentifiers = Index;
}

static
WCHAR *
DuplicateString (
  WCHAR   *Str
  )
{
  WCHAR *NewStr;
  if (Str == NULL) {
    return NULL;
  }

  NewStr = MALLOC ((StrLen (Str) + 1) * sizeof (WCHAR));
  if (NewStr == NULL) {
    Error (NULL, 0, 0, "memory allocation failure", NULL);
    return NULL;
  }

  StrCpy (NewStr, Str);
  return NewStr;
}

static
WCHAR *
AsciiToWchar (
  CHAR8 *Str
  )
{
  UINT32  Len;
  WCHAR   *NewStr;
  WCHAR   *Ptr;

  Len     = strlen (Str) + 1;
  NewStr  = (WCHAR *) malloc (Len * sizeof (WCHAR));
  for (Ptr = NewStr; *Str != 0; Str++, Ptr++) {
    *Ptr = (UINT16) (UINT8) *Str;
  }

  *Ptr = 0;
  return NewStr;
}

/*****************************************************************************/

/*++

Routine Description:

  Create an HII export string pack for the strings in our database.

Arguments:

  FileName        - name of the output file to write 

Returns:

  STATUS


--*/
STATUS
StringDBCreateHiiExportPack (
  CHAR8                       *FileName
  )
{
  FILE                        *Fptr;
  LANGUAGE_LIST               *Lang;
  STRING_LIST                 *CurrString;
  STRING_LIST                 EmptyString;
  UINT32                      Offset;
  UINT32                      StringIndex;
  UINT32                      TempIndex;
  EFI_HII_STRING_PACK         StringPack;
  UINT32                      Len;
  WCHAR                       ZeroString[1];
  WCHAR                       *TempStringPtr;
  WCHAR                       *LangName;
  STRING_IDENTIFIER           *StringIdentifier;

  if ((Fptr = fopen (FileName, "wb")) == NULL) {
    Error (NULL, 0, 0, FileName, "failed to open output HII export file");
    return STATUS_ERROR;
  }
  //
  // Assign index values to the string identifiers
  //
  StringDBAssignStringIndexes ();
  //
  // If a given string is not defined, then we'll use this one.
  //
  memset (&EmptyString, 0, sizeof (EmptyString));
  EmptyString.Size  = sizeof (ZeroString);
  EmptyString.Str   = ZeroString;
  //
  // Process each language, then each string for each langage
  //
  ZeroString[0] = 0;
  for (Lang = mDBData.LanguageList; Lang != NULL; Lang = Lang->Next) {
    //
    // Process each string for this language. We have to make 3 passes on the strings:
    //   Pass1: computes sizes and fill in the string pack header
    //   Pass2: write the array of offsets
    //   Pass3: write the strings
    //
    //
    // PASS 1: Fill in and print the HII string pack header
    //
    // Compute the size for this language package and write
    // the header out. Each string package contains:
    //   Header
    //   Offset[]  -- an array of offsets to strings, of type RELOFST each
    //   String[]  -- the actual strings themselves
    //
    memset ((char *) &StringPack, 0, sizeof (EFI_HII_STRING_PACK));
    StringPack.Header.Type        = EFI_HII_STRING;
    StringPack.NumStringPointers  = (UINT16) mDBData.NumStringIdentifiersReferenced;
    LangName                      = Lang->LanguageName;
    //
    // First string is the language name. If we're printing all languages, then
    // it's just the "spa". If we were given a list of languages to print, then it's
    // the "spacat" string. Compute its offset and fill in
    // the info in the header. Since we know the language name string's length,
    // and the printable language name follows it, use that info to fill in the
    // entry for the printable language name as well.
    //
    StringPack.LanguageNameString = (STRING_OFFSET) (sizeof (EFI_HII_STRING_PACK) + (mDBData.NumStringIdentifiersReferenced * sizeof (STRING_OFFSET)));
    StringPack.PrintableLanguageName = (STRING_OFFSET) (StringPack.LanguageNameString + (StrLen (LangName) + 1) * sizeof (WCHAR));
    //
    // Add up the size of all strings so we can fill in our header.
    //
    Len = 0;
    for (StringIndex = 0; StringIndex < mDBData.NumStringIdentifiersReferenced; StringIndex++) {
      //
      // For the first string (language name), we print out the "spacat" if they
      // requested it. We set LangName to point to the proper language name string above.
      //
      if (StringIndex == STRING_ID_LANGUAGE_NAME) {
        Len += (StrLen (LangName) + 1) * sizeof (WCHAR);
      } else {
        //
        // Find a string with this language.stringname
        //
        StringIdentifier = StringDBFindStringIdentifierByIndex (StringIndex);
        if (StringIdentifier == NULL) {
          Error (NULL, 0, 0, "internal error", "invalid string index 0x%X", StringIndex);
          return STATUS_ERROR;
        }
        //
        // Find a matching string if this string identifier was referenced
        //
        EmptyString.Flags = STRING_FLAGS_UNDEFINED;
        CurrString        = NULL;
        if (StringIdentifier->Flags & STRING_FLAGS_REFERENCED) {
          CurrString = StringDBFindString (
                        Lang->LanguageName,
                        StringIdentifier->StringName,
                        NULL,
                        NULL, // LanguagesOfInterest,
                        NULL
                        );
          //
          // IndirectionList);
          //
          if (NULL == CurrString) {
            //
            // If string for Lang->LanguageName is not found, try to get an English version
            //
            CurrString = StringDBFindString (
                          L"eng",
                          StringIdentifier->StringName,
                          NULL,
                          NULL, // LanguagesOfInterest,
                          NULL
                          );
            //
            // IndirectionList);
            //
          }
        }

        if (CurrString == NULL) {
          CurrString = &EmptyString;
          EmptyString.Flags |= StringIdentifier->Flags;
        }

        Len += CurrString->Size;
      }
    }
    StringPack.Header.Length =    sizeof (EFI_HII_STRING_PACK) 
                                + mDBData.NumStringIdentifiersReferenced * sizeof (STRING_OFFSET) 
                                + Len;
    //
    // Write out the string pack header
    //
    fwrite ((void *) &StringPack, sizeof (StringPack), 1, Fptr);
    //
    // PASS2 : write the offsets
    //
    // Traverse the list of strings again and write the array of offsets. The
    // offset to the first string is the size of the string pack header
    // plus the size of the offsets array. The other strings follow it.
    //
    StringIndex = 0;
    Offset      = sizeof (StringPack) + mDBData.NumStringIdentifiersReferenced * sizeof (STRING_OFFSET);
    for (StringIndex = 0; StringIndex < mDBData.NumStringIdentifiersReferenced; StringIndex++) {
      //
      // Write the offset
      //
      fwrite (&Offset, sizeof (STRING_OFFSET), 1, Fptr);
      //
      // Find the string name
      //
      StringIdentifier = StringDBFindStringIdentifierByIndex (StringIndex);
      if (StringIdentifier == NULL) {
        Error (NULL, 0, 0, "internal error", "invalid string index 0x%X", StringIndex);
        return STATUS_ERROR;
      }
      //
      // For the first string (language name), we print out the "spacat" if they
      // requested it. We set LangName to point to the proper language name string above.
      //
      if (StringIndex == STRING_ID_LANGUAGE_NAME) {
        Offset += (StrLen (LangName) + 1) * sizeof (WCHAR);
        CurrString = StringDBFindString (
                      Lang->LanguageName,
                      StringIdentifier->StringName,
                      NULL, // scope
                      NULL,
                      NULL
                      );
      } else {
        //
        // Find a matching string
        //
        CurrString = StringDBFindString (
                      Lang->LanguageName,
                      StringIdentifier->StringName,
                      NULL, // scope
                      NULL, // LanguagesOfInterest,
                      NULL
                      );
        //
        // IndirectionList);
        //
        if (NULL == CurrString) {
          CurrString = StringDBFindString (
                        L"eng",
                        StringIdentifier->StringName,
                        NULL, // scope
                        NULL, // LanguagesOfInterest,
                        NULL
                        );
          //
          // IndirectionList);
          //
        }

        EmptyString.LanguageName = Lang->LanguageName;
        if (CurrString == NULL) {
          CurrString        = &EmptyString;
          EmptyString.Flags = STRING_FLAGS_UNDEFINED;
        } else if ((StringIdentifier->Flags & STRING_FLAGS_REFERENCED) == 0) {
          CurrString        = &EmptyString;
          EmptyString.Flags = 0;
        }

        Offset += CurrString->Size;
      }
    }

    //
    // PASS 3: write the strings themselves.
    //
    Offset = sizeof (StringPack) + mDBData.NumStringIdentifiersReferenced * sizeof (STRING_OFFSET);
    for (StringIndex = 0; StringIndex < mDBData.NumStringIdentifiersReferenced; StringIndex++) {
      StringIdentifier = StringDBFindStringIdentifierByIndex (StringIndex);
      if (StringIdentifier == NULL) {
        Error (NULL, 0, 0, "internal error", "invalid string index 0x%X", StringIndex);
        return STATUS_ERROR;
      }
      //
      // For the first string (language name), we print out the "spacat" if they
      // requested it. We set LangName to point to the proper language name string above.
      //
      if (StringIndex == STRING_ID_LANGUAGE_NAME) {
        TempStringPtr = LangName;
      } else {
        //
        // Find a matching string if this string identifier was referenced
        //
        CurrString = NULL;
        if (StringIdentifier->Flags & STRING_FLAGS_REFERENCED) {
          CurrString = StringDBFindString (
                        Lang->LanguageName,
                        StringIdentifier->StringName,
                        NULL, // scope
                        NULL, // LanguagesOfInterest,
                        NULL
                        );
          //
          // IndirectionList);
          //
          if (NULL == CurrString) {
            CurrString = StringDBFindString (
                          L"eng",
                          StringIdentifier->StringName,
                          NULL, // scope
                          NULL, // LanguagesOfInterest,
                          NULL
                          );
            //
            // IndirectionList);
            //
          }
        }

        if (CurrString == NULL) {
          CurrString = &EmptyString;
        }

        TempStringPtr = CurrString->Str;
      }

      for (TempIndex = 0; TempStringPtr[TempIndex] != 0; TempIndex++) {
        fwrite (&TempStringPtr[TempIndex], sizeof (CHAR16), 1, Fptr);
        Offset += 2;
      }
      //
      // Print NULL WCHAR at the end of this string.
      //
      TempIndex = 0;
      fwrite (&TempIndex, sizeof (CHAR16), 1, Fptr);
      Offset += 2;
    }
    //
    // Sanity check the offset. Make sure our running offset is what we put in the
    // string pack header.
    //
    if (StringPack.Header.Length != Offset) {
      Error (
        __FILE__,
        __LINE__,
        0,
        "application error",
        "stringpack size 0x%X does not match final size 0x%X",
        StringPack.Header.Length,
        Offset
        );
    }
  }
  //
  // Print terminator string pack, closing brace and close the file.
  // The size of 0 triggers to the consumer that this is the end.
  //
  memset ((char *) &StringPack, 0, sizeof (EFI_HII_STRING_PACK));
  StringPack.Header.Type = EFI_HII_STRING;
  fwrite ((void *) &StringPack, sizeof (StringPack), 1, Fptr);
  fclose (Fptr);
  return STATUS_SUCCESS;
}
