stringdb.c

来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 2,280 行 · 第 1/5 页

C
2,280
字号
/*++

Copyright (c) 2004 - 2006, 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

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?