summaryrefslogtreecommitdiff
path: root/Tools/CCode/Source/StrGather/StringDB.c
diff options
context:
space:
mode:
Diffstat (limited to 'Tools/CCode/Source/StrGather/StringDB.c')
-rw-r--r--Tools/CCode/Source/StrGather/StringDB.c2759
1 files changed, 0 insertions, 2759 deletions
diff --git a/Tools/CCode/Source/StrGather/StringDB.c b/Tools/CCode/Source/StrGather/StringDB.c
deleted file mode 100644
index 16ef0526d7..0000000000
--- a/Tools/CCode/Source/StrGather/StringDB.c
+++ /dev/null
@@ -1,2759 +0,0 @@
-/*++
-
-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;
-}