stringdb.c
来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 2,280 行 · 第 1/5 页
C
2,280 行
// 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;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?