/*++

Copyright (c) 2004 - 2007, 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 "Tiano.h"
#include "EfiUtilityMsgs.h"
#include "StrGather.h"
#include "StringDb.h"
#include "EfiInternalFormRepresentation.h"

#include EFI_PROTOCOL_DEFINITION (Hii)

typedef CHAR16  WCHAR;
#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 (
  INT8 *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 (
  INT8                        *FileName,
  INT8                        *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_HEADER  StringPack;
  UINT8                       *Ptr;
  UINT32                      Len;
  WCHAR                       ZeroString[1];
  WCHAR_STRING_LIST           *LOIPtr;
  BOOLEAN                     LanguageOk;
  WCHAR                       *TempStringPtr;
  WCHAR                       *LangName;
  STRING_IDENTIFIER           *StringIdentifier;

  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 (wcsncmp (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
    //
    fprintf (
      Fptr,
      "\n//******************************************************************************"
      "\n// Start of string definitions for %S/%S",
      Lang->LanguageName,
      Lang->PrintableLanguageName
      );
    memset ((char *) &StringPack, 0, sizeof (EFI_HII_STRING_PACK_HEADER));
    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_HEADER) + (mDBData.NumStringIdentifiersReferenced * sizeof (STRING_OFFSET)));
    StringPack.PrintableLanguageName = (STRING_OFFSET) (StringPack.LanguageNameString + (wcslen (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 += (wcslen (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_HEADER) 
                                + 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_HEADER); 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;
      }

      fprintf (Fptr, " // offset to string %S (0x%04X)", StringIdentifier->StringName, 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) {
        Offset += (wcslen (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 (wcscmp (CurrString->LanguageName, Lang->LanguageName) != 0) {
        fprintf (
          Fptr,
          " - not defined for this language -- using secondary language %S definition",
          CurrString->LanguageName
          );
      }

      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) {
        fprintf (Fptr, "  // %S not referenced\n", StringIdentifier->StringName);
      }

      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;
      }

      fprintf (Fptr, "  // string %S offset 0x%08X\n  ", StringIdentifier->StringName, Offset);
      //
      // 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_HEADER));
  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 (
  INT8 *FileName,
  INT8 *BaseName
  )
{
  FILE              *Fptr;
  STRING_IDENTIFIER *Identifier;
  INT8              CopyBaseName[100];
  UINT32            Index;
  const INT8        *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) {
      fprintf (Fptr, "#define %-40S 0x%04X\n", Identifier->StringName, Identifier->Index);
    } else {
      fprintf (Fptr, "//#define %-40S 0x%04X // not referenced\n", Identifier->StringName, Identifier->Index);
    }

    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 ((wcslen (StringName) + 1) * sizeof (WCHAR));
  if (StringIdentifier->StringName == NULL) {
    Error (NULL, 0, 0, NULL, "memory allocation error");
    return STATUS_ERROR;
  }

  wcscpy (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 = wcslen (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.
        //
        wcscpy (TempLangName, LanguageName);
        for (; Size < 3; Size++) {
          TempLangName[Size] = L'?';
        }

        TempLangName[3] = 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 ((wcscmp (StringName, LANGUAGE_NAME_STRING_NAME) == 0) &&
        (wcscmp (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              = (wcslen (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.
  //
  wcscpy (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 = (wcslen (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 (wcscmp (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 (wcscmp (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
    //
    Lang->LanguageName[3] = 0;
    wcsncpy (Lang->LanguageName, LanguageName, 3);
    Lang->PrintableLanguageName = (WCHAR *) malloc ((wcslen (PrintableLanguageName) + 1) * sizeof (WCHAR));
    if (Lang->PrintableLanguageName == NULL) {
      Error (NULL, 0, 0, NULL, "memory allocation error");
      return STATUS_ERROR;
    }

    wcscpy (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 (wcscmp (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 (wcsncmp (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 (wcsncmp (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 (wcsncmp (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 (wcsncmp (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 (
  INT8    *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 (
  INT8    *DBFileName,
  BOOLEAN Verbose
  )
{
  STRING_DB_HEADER  DbHeader;
  UINT32            Counter;
  UINT32            StrLen;
  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++) {
    StrLen = wcslen (StringIdentifier->StringName) + 1;
    DbHeader.StringIdentifiersSize += StrLen * 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 (
  INT8      *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));
#ifdef USE_VC8
  swprintf (WName, (strlen (StringIdentifierName) + 1) * sizeof (WCHAR), L"%S", StringIdentifierName);
#else
  swprintf (WName, L"%S", StringIdentifierName);
#endif
  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 (
  INT8                *DBFileName,
  INT8                *OutputFileName,
  BOOLEAN             Verbose
  )
{
  LANGUAGE_LIST     *Lang;
  STRING_IDENTIFIER *StringIdentifier;
  STRING_LIST       *StrList;
  FILE              *OutFptr;
  WCHAR             WChar;
  WCHAR             *WOutputFileName;
  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);
  }

  WOutputFileName = AsciiToWchar (OutputFileName);
  OutFptr         = _wfopen (WOutputFileName, L"wb");
  free (WOutputFileName);
  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.
  //
#ifdef USE_VC8
  swprintf (Line, wcslen(Line) * sizeof (WCHAR), L"/=#");
#else
  swprintf (Line, L"/=#");
#endif
  fwrite (Line, wcslen (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) {
#ifdef USE_VC8
      swprintf (
        Line,
        wcslen(Line) * sizeof (WCHAR),
        L"%s %-60.60s 0x%04X",
        DEFINE_STR,
        StringIdentifier->StringName,
        StringIdentifier->Index
        );
#else
      swprintf (
        Line,
        L"%s %-60.60s 0x%04X",
        DEFINE_STR,
        StringIdentifier->StringName,
        StringIdentifier->Index
        );
#endif
    } else {
#ifdef USE_VC8
      swprintf (
        Line,
        wcslen(Line) * sizeof (WCHAR), 
        L"%s %-60.60s 0x%04X  // NOT REFERENCED",
        DEFINE_STR,
        StringIdentifier->StringName,
        StringIdentifier->Index
        );
#else
      swprintf (
        Line,
        L"%s %-60.60s 0x%04X  // NOT REFERENCED",
        DEFINE_STR,
        StringIdentifier->StringName,
        StringIdentifier->Index
        );
#endif
    }

    fwrite (Line, wcslen (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);
#ifdef USE_VC8
    swprintf (Line, wcslen(Line) * sizeof (WCHAR), L"#langdef %s \"%s\"", Lang->LanguageName, Lang->PrintableLanguageName);
#else
    swprintf (Line, L"#langdef %s \"%s\"", Lang->LanguageName, Lang->PrintableLanguageName);
#endif
    fwrite (Line, wcslen (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
      //
#ifdef USE_VC8
      swprintf (Line, wcslen(Line) * sizeof (WCHAR), L"// flags=0x%02X", (UINT32) StrList->Flags);
#else
      swprintf (Line, L"// flags=0x%02X", (UINT32) StrList->Flags);
#endif
      fwrite (Line, wcslen (Line) * sizeof (WCHAR), 1, OutFptr);
      fwrite (&CrLf, sizeof (CrLf), 1, OutFptr);
      //
      // Print the scope if changed
      //
      if ((Scope == NULL) || (wcscmp (Scope, StrList->Scope) != 0)) {
#ifdef USE_VC8
        swprintf (Line, wcslen(Line) * sizeof (WCHAR), L"#scope %s", StrList->Scope);
#else
        swprintf (Line, L"#scope %s", StrList->Scope);
#endif
        fwrite (Line, wcslen (Line) * sizeof (WCHAR), 1, OutFptr);
        fwrite (&CrLf, sizeof (CrLf), 1, OutFptr);
        Scope = StrList->Scope;
      }

#ifdef USE_VC8
      swprintf (
        Line,
        wcslen(Line) * sizeof (WCHAR), 
        L"#string %-50.50s #language %s \"",
        StrList->StringName,
        Lang->LanguageName
        );
#else
      swprintf (
        Line,
        L"#string %-50.50s #language %s \"",
        StrList->StringName,
        Lang->LanguageName
        );
#endif
      fwrite (Line, wcslen (Line) * sizeof (WCHAR), 1, OutFptr);
      fwrite (StrList->Str, StrList->Size - sizeof (WCHAR), 1, OutFptr);
#ifdef USE_VC8
      swprintf (Line, wcslen(Line) * sizeof (WCHAR), L"\"");
#else
      swprintf (Line, L"\"");
#endif
      fwrite (Line, wcslen (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) ((wcslen (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 (wcscmp (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 (wcscmp (LanguageName, Lang->LanguageName) == 0) {
      //
      // Found language match. Try to find string name match
      //
      for (CurrString = Lang->String; CurrString != NULL; CurrString = CurrString->Next) {
        if (wcscmp (StringName, CurrString->StringName) == 0) {
          //
          // Found a string name match. See if we're supposed to find
          // a scope match.
          //
          if (Scope != NULL) {
            if (wcscmp (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 (wcsncmp (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 (wcslen (WCharPtr) < LANGUAGE_IDENTIFIER_NAME_LEN) {
          Error (NULL, 0, 0, "malformed alternate language list", "%S", LanguagesOfInterest->Str);
          return NULL;
        }

        wcsncpy (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 ((wcslen (Str) + 1) * sizeof (WCHAR));
  if (NewStr == NULL) {
    Error (NULL, 0, 0, "memory allocation failure", NULL);
    return NULL;
  }

  wcscpy (NewStr, Str);
  return NewStr;
}

static
WCHAR *
AsciiToWchar (
  INT8 *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 (
  INT8                        *FileName
  )
{
  FILE                        *Fptr;
  LANGUAGE_LIST               *Lang;
  STRING_LIST                 *CurrString;
  STRING_LIST                 EmptyString;
  UINT32                      Offset;
  UINT32                      StringIndex;
  UINT32                      TempIndex;
  EFI_HII_STRING_PACK_HEADER  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_HEADER));
    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_HEADER) + (mDBData.NumStringIdentifiersReferenced * sizeof (STRING_OFFSET)));
    StringPack.PrintableLanguageName = (STRING_OFFSET) (StringPack.LanguageNameString + (wcslen (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 += (wcslen (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_HEADER) 
                                + 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 += (wcslen (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_HEADER));
  StringPack.Header.Type = EFI_HII_STRING;
  fwrite ((void *) &StringPack, sizeof (StringPack), 1, Fptr);
  fclose (Fptr);
  return STATUS_SUCCESS;
}
