strgather.c
来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 2,364 行 · 第 1/5 页
C
2,364 行
/*++
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:
StrGather.c
Abstract:
Parse a strings file and create or add to a string database file.
--*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include "Tiano.h"
#include "EfiUtilityMsgs.h"
#include "StrGather.h"
#include "StringDB.h"
#define TOOL_VERSION "0.31"
typedef UINT16 WCHAR;
#define MAX_PATH 1024
#define MAX_NEST_DEPTH 20 // just in case we get in an endless loop.
#define MAX_STRING_IDENTIFIER_NAME 100 // number of wchars
#define MAX_LINE_LEN 400
#define STRING_TOKEN "STRING_TOKEN"
#define DEFAULT_BASE_NAME "BaseName"
//
// Operational modes for this utility
//
#define MODE_UNKNOWN 0
#define MODE_PARSE 1
#define MODE_SCAN 2
#define MODE_DUMP 3
//
// We keep a linked list of these for the source files we process
//
typedef struct _SOURCE_FILE {
FILE *Fptr;
WCHAR *FileBuffer;
WCHAR *FileBufferPtr;
UINT32 FileSize;
INT8 FileName[MAX_PATH];
UINT32 LineNum;
BOOLEAN EndOfFile;
BOOLEAN SkipToHash;
struct _SOURCE_FILE *Previous;
struct _SOURCE_FILE *Next;
WCHAR ControlCharacter;
} SOURCE_FILE;
#define DEFAULT_CONTROL_CHARACTER UNICODE_SLASH
//
// Here's all our globals. We need a linked list of include paths, a linked
// list of source files, a linked list of subdirectories (appended to each
// include path when searching), and a couple other fields.
//
static struct {
SOURCE_FILE SourceFiles;
TEXT_STRING_LIST *IncludePaths; // all include paths to search
TEXT_STRING_LIST *LastIncludePath;
TEXT_STRING_LIST *ScanFileName;
TEXT_STRING_LIST *LastScanFileName;
TEXT_STRING_LIST *SkipExt; // if -skipext .uni
TEXT_STRING_LIST *LastSkipExt;
TEXT_STRING_LIST *IndirectionFileName;
TEXT_STRING_LIST *LastIndirectionFileName;
TEXT_STRING_LIST *DatabaseFileName;
TEXT_STRING_LIST *LastDatabaseFileName;
WCHAR_STRING_LIST *Language;
WCHAR_STRING_LIST *LastLanguage;
WCHAR_MATCHING_STRING_LIST *IndirectionList; // from indirection file(s)
WCHAR_MATCHING_STRING_LIST *LastIndirectionList;
BOOLEAN Verbose; // for more detailed output
BOOLEAN VerboseDatabaseWrite; // for more detailed output when writing database
BOOLEAN VerboseDatabaseRead; // for more detailed output when reading database
BOOLEAN NewDatabase; // to start from scratch
BOOLEAN IgnoreNotFound; // when scanning
BOOLEAN VerboseScan;
BOOLEAN UnquotedStrings; // -uqs option
INT8 OutputDatabaseFileName[MAX_PATH];
INT8 OutputDependencyFileName[MAX_PATH];
INT8 StringHFileName[MAX_PATH];
INT8 StringCFileName[MAX_PATH]; // output .C filename
INT8 DumpUFileName[MAX_PATH]; // output unicode dump file name
INT8 HiiExportPackFileName[MAX_PATH]; // HII export pack file name
INT8 BaseName[MAX_PATH]; // base filename of the strings file
UINT32 Mode;
} mGlobals;
static
BOOLEAN
IsValidIdentifierChar (
INT8 Char,
BOOLEAN FirstChar
);
static
void
RewindFile (
SOURCE_FILE *SourceFile
);
static
BOOLEAN
SkipTo (
SOURCE_FILE *SourceFile,
WCHAR WChar,
BOOLEAN StopAfterNewline
);
static
UINT32
SkipWhiteSpace (
SOURCE_FILE *SourceFile
);
static
BOOLEAN
IsWhiteSpace (
SOURCE_FILE *SourceFile
);
static
BOOLEAN
EndOfFile (
SOURCE_FILE *SourceFile
);
static
void
PreprocessFile (
SOURCE_FILE *SourceFile
);
static
UINT32
GetStringIdentifierName (
IN SOURCE_FILE *SourceFile,
IN OUT WCHAR *StringIdentifierName,
IN UINT32 StringIdentifierNameLen
);
static
UINT32
GetLanguageIdentifierName (
IN SOURCE_FILE *SourceFile,
IN OUT WCHAR *LanguageIdentifierName,
IN UINT32 LanguageIdentifierNameLen,
IN BOOLEAN Optional
);
static
WCHAR *
GetPrintableLanguageName (
IN SOURCE_FILE *SourceFile
);
static
STATUS
AddCommandLineLanguage (
IN INT8 *Language
);
static
WCHAR *
GetQuotedString (
SOURCE_FILE *SourceFile,
BOOLEAN Optional
);
static
STATUS
ProcessIncludeFile (
SOURCE_FILE *SourceFile,
SOURCE_FILE *ParentSourceFile
);
static
STATUS
ParseFile (
SOURCE_FILE *SourceFile
);
static
FILE *
FindFile (
IN INT8 *FileName,
OUT INT8 *FoundFileName,
IN UINT32 FoundFileNameLen
);
static
STATUS
ProcessArgs (
int Argc,
char *Argv[]
);
static
STATUS
ProcessFile (
SOURCE_FILE *SourceFile
);
static
UINT32
wstrcmp (
WCHAR *Buffer,
WCHAR *Str
);
static
void
Usage (
VOID
);
static
void
FreeLists (
VOID
);
static
void
ProcessTokenString (
SOURCE_FILE *SourceFile
);
static
void
ProcessTokenInclude (
SOURCE_FILE *SourceFile
);
static
void
ProcessTokenScope (
SOURCE_FILE *SourceFile
);
static
void
ProcessTokenLanguage (
SOURCE_FILE *SourceFile
);
static
void
ProcessTokenLangDef (
SOURCE_FILE *SourceFile
);
static
STATUS
ScanFiles (
TEXT_STRING_LIST *ScanFiles
);
static
STATUS
ParseIndirectionFiles (
TEXT_STRING_LIST *Files
);
STATUS
StringDBCreateHiiExportPack (
INT8 *OutputFileName
);
static
void
EmptyDependency (
void
);
static
void
AddDependency (
INT8 *FileName
);
int
main (
int Argc,
char *Argv[]
)
/*++
Routine Description:
Call the routine to parse the command-line options, then process the file.
Arguments:
Argc - Standard C main() argc and argv.
Argv - Standard C main() argc and argv.
Returns:
0 if successful
nonzero otherwise
--*/
{
STATUS Status;
SetUtilityName (PROGRAM_NAME);
//
// Process the command-line arguments
//
Status = ProcessArgs (Argc, Argv);
if (Status != STATUS_SUCCESS) {
return Status;
}
//
// Initialize the database manager
//
StringDBConstructor ();
//
// We always try to read in an existing database file. It may not
// exist, which is ok usually.
//
if (mGlobals.NewDatabase == 0) {
//
// Read all databases specified.
//
for (mGlobals.LastDatabaseFileName = mGlobals.DatabaseFileName;
mGlobals.LastDatabaseFileName != NULL;
mGlobals.LastDatabaseFileName = mGlobals.LastDatabaseFileName->Next
) {
Status = StringDBReadDatabase (mGlobals.LastDatabaseFileName->Str, TRUE, mGlobals.VerboseDatabaseRead);
if (Status != STATUS_SUCCESS) {
return Status;
}
}
}
//
// Read indirection file(s) if specified
//
if (ParseIndirectionFiles (mGlobals.IndirectionFileName) != STATUS_SUCCESS) {
goto Finish;
}
//
// If scanning source files, do that now
//
if (mGlobals.Mode == MODE_SCAN) {
ScanFiles (mGlobals.ScanFileName);
} else if (mGlobals.Mode == MODE_PARSE) {
//
// Parsing a unicode strings file
//
mGlobals.SourceFiles.ControlCharacter = DEFAULT_CONTROL_CHARACTER;
EmptyDependency ();
Status = ProcessIncludeFile (&mGlobals.SourceFiles, NULL);
if (Status != STATUS_SUCCESS) {
goto Finish;
}
}
//
// Create the string defines header file if there have been no errors.
//
ParserSetPosition (NULL, 0);
if ((mGlobals.StringHFileName[0] != 0) && (GetUtilityStatus () < STATUS_ERROR)) {
Status = StringDBDumpStringDefines (mGlobals.StringHFileName, mGlobals.BaseName);
if (Status != EFI_SUCCESS) {
goto Finish;
}
}
//
// Dump the strings to a .c file if there have still been no errors.
//
if ((mGlobals.StringCFileName[0] != 0) && (GetUtilityStatus () < STATUS_ERROR)) {
Status = StringDBDumpCStrings (
mGlobals.StringCFileName,
mGlobals.BaseName,
mGlobals.Language,
mGlobals.IndirectionList
);
if (Status != EFI_SUCCESS) {
goto Finish;
}
}
//
// Dump the database if requested
//
if ((mGlobals.DumpUFileName[0] != 0) && (GetUtilityStatus () < STATUS_ERROR)) {
StringDBDumpDatabase (NULL, mGlobals.DumpUFileName, FALSE);
}
//
// Dump the string data as HII binary string pack if requested
//
if ((mGlobals.HiiExportPackFileName[0] != 0) && (GetUtilityStatus () < STATUS_ERROR)) {
StringDBCreateHiiExportPack (mGlobals.HiiExportPackFileName);
}
//
// Always update the database if no errors and not in dump mode. If they specified -od
// for an output database file name, then use that name. Otherwise use the name of
// the first database file specified with -db
//
if ((mGlobals.Mode != MODE_DUMP) && (GetUtilityStatus () < STATUS_ERROR)) {
if (mGlobals.OutputDatabaseFileName[0]) {
Status = StringDBWriteDatabase (mGlobals.OutputDatabaseFileName, mGlobals.VerboseDatabaseWrite);
} else {
Status = StringDBWriteDatabase (mGlobals.DatabaseFileName->Str, mGlobals.VerboseDatabaseWrite);
}
if (Status != EFI_SUCCESS) {
goto Finish;
}
}
Finish:
//
// Free up memory
//
FreeLists ();
StringDBDestructor ();
return GetUtilityStatus ();
}
static
STATUS
ProcessIncludeFile (
SOURCE_FILE *SourceFile,
SOURCE_FILE *ParentSourceFile
)
/*++
Routine Description:
Given a source file, open the file and parse it
Arguments:
SourceFile - name of file to parse
ParentSourceFile - for error reporting purposes, the file that #included SourceFile.
Returns:
Standard status.
--*/
{
static UINT32 NestDepth = 0;
INT8 FoundFileName[MAX_PATH];
STATUS Status;
Status = STATUS_SUCCESS;
NestDepth++;
//
// Print the file being processed. Indent so you can tell the include nesting
// depth.
//
if (mGlobals.Verbose) {
fprintf (stdout, "%*cProcessing file '%s'\n", NestDepth * 2, ' ', SourceFile->FileName);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?