strgather.c
来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 2,364 行 · 第 1/5 页
C
2,364 行
}
//
// Make sure we didn't exceed our maximum nesting depth
//
if (NestDepth > MAX_NEST_DEPTH) {
Error (NULL, 0, 0, SourceFile->FileName, "max nesting depth (%d) exceeded", NestDepth);
Status = STATUS_ERROR;
goto Finish;
}
//
// Try to open the file locally, and if that fails try along our include paths.
//
strcpy (FoundFileName, SourceFile->FileName);
if ((SourceFile->Fptr = fopen (FoundFileName, "rb")) == NULL) {
//
// Try to find it among the paths if it has a parent (that is, it is included
// by someone else).
//
if (ParentSourceFile == NULL) {
Error (NULL, 0, 0, SourceFile->FileName, "file not found");
return STATUS_ERROR;
}
SourceFile->Fptr = FindFile (SourceFile->FileName, FoundFileName, sizeof (FoundFileName));
if (SourceFile->Fptr == NULL) {
Error (ParentSourceFile->FileName, ParentSourceFile->LineNum, 0, SourceFile->FileName, "include file not found");
return STATUS_ERROR;
}
}
//
// Process the file found
//
AddDependency (FoundFileName);
ProcessFile (SourceFile);
Finish:
//
// Close open files and return status
//
if (SourceFile->Fptr != NULL) {
fclose (SourceFile->Fptr);
}
return Status;
}
static
STATUS
ProcessFile (
SOURCE_FILE *SourceFile
)
{
//
// Get the file size, and then read the entire thing into memory.
// Allocate space for a terminator character.
//
fseek (SourceFile->Fptr, 0, SEEK_END);
SourceFile->FileSize = ftell (SourceFile->Fptr);
fseek (SourceFile->Fptr, 0, SEEK_SET);
SourceFile->FileBuffer = (WCHAR *) malloc (SourceFile->FileSize + sizeof (WCHAR));
if (SourceFile->FileBuffer == NULL) {
Error (NULL, 0, 0, "memory allocation failure", NULL);
return STATUS_ERROR;
}
fread ((VOID *) SourceFile->FileBuffer, SourceFile->FileSize, 1, SourceFile->Fptr);
SourceFile->FileBuffer[(SourceFile->FileSize / sizeof (WCHAR))] = UNICODE_NULL;
//
// Pre-process the file to replace comments with spaces
//
PreprocessFile (SourceFile);
//
// Parse the file
//
ParseFile (SourceFile);
free (SourceFile->FileBuffer);
return STATUS_SUCCESS;
}
static
STATUS
ParseFile (
SOURCE_FILE *SourceFile
)
{
BOOLEAN InComment;
UINT32 Len;
//
// First character of a unicode file is special. Make sure
//
if (SourceFile->FileBufferPtr[0] != UNICODE_FILE_START) {
Error (SourceFile->FileName, 1, 0, SourceFile->FileName, "file does not appear to be a unicode file");
return STATUS_ERROR;
}
SourceFile->FileBufferPtr++;
InComment = FALSE;
//
// Print the first line if in verbose mode
//
if (mGlobals.Verbose) {
printf ("%d: %S\n", SourceFile->LineNum, SourceFile->FileBufferPtr);
}
//
// Since the syntax is relatively straightforward, just switch on the next char
//
while (!EndOfFile (SourceFile)) {
//
// Check for whitespace
//
if (SourceFile->FileBufferPtr[0] == UNICODE_SPACE) {
SourceFile->FileBufferPtr++;
} else if (SourceFile->FileBufferPtr[0] == UNICODE_TAB) {
SourceFile->FileBufferPtr++;
} else if (SourceFile->FileBufferPtr[0] == UNICODE_CR) {
SourceFile->FileBufferPtr++;
} else if (SourceFile->FileBufferPtr[0] == UNICODE_LF) {
SourceFile->FileBufferPtr++;
SourceFile->LineNum++;
if (mGlobals.Verbose) {
printf ("%d: %S\n", SourceFile->LineNum, SourceFile->FileBufferPtr);
}
InComment = FALSE;
} else if (SourceFile->FileBufferPtr[0] == 0) {
SourceFile->FileBufferPtr++;
} else if (InComment) {
SourceFile->FileBufferPtr++;
} else if ((SourceFile->FileBufferPtr[0] == UNICODE_SLASH) && (SourceFile->FileBufferPtr[1] == UNICODE_SLASH)) {
SourceFile->FileBufferPtr += 2;
InComment = TRUE;
} else if (SourceFile->SkipToHash && (SourceFile->FileBufferPtr[0] != SourceFile->ControlCharacter)) {
SourceFile->FileBufferPtr++;
} else {
SourceFile->SkipToHash = FALSE;
if ((SourceFile->FileBufferPtr[0] == SourceFile->ControlCharacter) &&
((Len = wstrcmp (SourceFile->FileBufferPtr + 1, L"include")) > 0)
) {
SourceFile->FileBufferPtr += Len + 1;
ProcessTokenInclude (SourceFile);
} else if ((SourceFile->FileBufferPtr[0] == SourceFile->ControlCharacter) &&
(Len = wstrcmp (SourceFile->FileBufferPtr + 1, L"scope")) > 0
) {
SourceFile->FileBufferPtr += Len + 1;
ProcessTokenScope (SourceFile);
} else if ((SourceFile->FileBufferPtr[0] == SourceFile->ControlCharacter) &&
(Len = wstrcmp (SourceFile->FileBufferPtr + 1, L"language")) > 0
) {
SourceFile->FileBufferPtr += Len + 1;
ProcessTokenLanguage (SourceFile);
} else if ((SourceFile->FileBufferPtr[0] == SourceFile->ControlCharacter) &&
(Len = wstrcmp (SourceFile->FileBufferPtr + 1, L"langdef")) > 0
) {
SourceFile->FileBufferPtr += Len + 1;
ProcessTokenLangDef (SourceFile);
} else if ((SourceFile->FileBufferPtr[0] == SourceFile->ControlCharacter) &&
(Len = wstrcmp (SourceFile->FileBufferPtr + 1, L"string")) > 0
) {
SourceFile->FileBufferPtr += Len + 1;
ProcessTokenString (SourceFile);
} else if ((SourceFile->FileBufferPtr[0] == SourceFile->ControlCharacter) &&
(Len = wstrcmp (SourceFile->FileBufferPtr + 1, L"EFI_BREAKPOINT()")) > 0
) {
SourceFile->FileBufferPtr += Len;
EFI_BREAKPOINT ();
} else if ((SourceFile->FileBufferPtr[0] == SourceFile->ControlCharacter) &&
(SourceFile->FileBufferPtr[1] == UNICODE_EQUAL_SIGN)
) {
SourceFile->ControlCharacter = SourceFile->FileBufferPtr[2];
SourceFile->FileBufferPtr += 3;
} else {
Error (SourceFile->FileName, SourceFile->LineNum, 0, "unrecognized token", "%S", SourceFile->FileBufferPtr);
//
// Treat rest of line as a comment.
//
InComment = TRUE;
}
}
}
return STATUS_SUCCESS;
}
static
void
PreprocessFile (
SOURCE_FILE *SourceFile
)
/*++
Routine Description:
Preprocess a file to replace all carriage returns with NULLs so
we can print lines from the file to the screen.
Arguments:
SourceFile - structure that we use to keep track of an input file.
Returns:
Nothing.
--*/
{
BOOLEAN InComment;
RewindFile (SourceFile);
InComment = FALSE;
while (!EndOfFile (SourceFile)) {
//
// If a line-feed, then no longer in a comment
//
if (SourceFile->FileBufferPtr[0] == UNICODE_LF) {
SourceFile->FileBufferPtr++;
SourceFile->LineNum++;
InComment = 0;
} else if (SourceFile->FileBufferPtr[0] == UNICODE_CR) {
//
// Replace all carriage returns with a NULL so we can print stuff
//
SourceFile->FileBufferPtr[0] = 0;
SourceFile->FileBufferPtr++;
} else if (InComment) {
SourceFile->FileBufferPtr[0] = UNICODE_SPACE;
SourceFile->FileBufferPtr++;
} else if ((SourceFile->FileBufferPtr[0] == UNICODE_SLASH) && (SourceFile->FileBufferPtr[1] == UNICODE_SLASH)) {
SourceFile->FileBufferPtr += 2;
InComment = TRUE;
} else {
SourceFile->FileBufferPtr++;
}
}
//
// Could check for end-of-file and still in a comment, but
// should not be necessary. So just restore the file pointers.
//
RewindFile (SourceFile);
}
static
WCHAR *
GetPrintableLanguageName (
IN SOURCE_FILE *SourceFile
)
{
WCHAR *String;
WCHAR *Start;
WCHAR *Ptr;
UINT32 Len;
SkipWhiteSpace (SourceFile);
if (SourceFile->FileBufferPtr[0] != UNICODE_DOUBLE_QUOTE) {
Error (
SourceFile->FileName,
SourceFile->LineNum,
0,
"expected quoted printable language name",
"%S",
SourceFile->FileBufferPtr
);
SourceFile->SkipToHash = TRUE;
return NULL;
}
Len = 0;
SourceFile->FileBufferPtr++;
Start = Ptr = SourceFile->FileBufferPtr;
while (!EndOfFile (SourceFile)) {
if (SourceFile->FileBufferPtr[0] == UNICODE_CR) {
Warning (SourceFile->FileName, SourceFile->LineNum, 0, "carriage return found in quoted string", "%S", Start);
break;
} else if (SourceFile->FileBufferPtr[0] == UNICODE_DOUBLE_QUOTE) {
break;
}
SourceFile->FileBufferPtr++;
Len++;
}
if (SourceFile->FileBufferPtr[0] != UNICODE_DOUBLE_QUOTE) {
Warning (
SourceFile->FileName,
SourceFile->LineNum,
0,
"missing closing quote on printable language name string",
"%S",
Start
);
} else {
SourceFile->FileBufferPtr++;
}
//
// Now allocate memory for the string and save it off
//
String = (WCHAR *) malloc ((Len + 1) * sizeof (WCHAR));
if (String == NULL) {
Error (NULL, 0, 0, "memory allocation failed", NULL);
return NULL;
}
//
// Copy the string from the file buffer to the local copy.
// We do no reformatting of it whatsoever at this point.
//
Ptr = String;
while (Len > 0) {
*Ptr = *Start;
Start++;
Ptr++;
Len--;
}
*Ptr = 0;
//
// Now format the string to convert \wide and \narrow controls
//
StringDBFormatString (String);
return String;
}
static
WCHAR *
GetQuotedString (
SOURCE_FILE *SourceFile,
BOOLEAN Optional
)
{
WCHAR *String;
WCHAR *Start;
WCHAR *Ptr;
UINT32 Len;
BOOLEAN PreviousBackslash;
if (SourceFile->FileBufferPtr[0] != UNICODE_DOUBLE_QUOTE) {
if (!Optional) {
Error (SourceFile->FileName, SourceFile->LineNum, 0, "expected quoted string", "%S", SourceFile->FileBufferPtr);
}
return NULL;
}
Len = 0;
SourceFile->FileBufferPtr++;
Start = Ptr = SourceFile->FileBufferPtr;
PreviousBackslash = FALSE;
while (!EndOfFile (SourceFile)) {
if ((SourceFile->FileBufferPtr[0] == UNICODE_DOUBLE_QUOTE) && (!PreviousBackslash)) {
break;
} else if (SourceFile->FileBufferPtr[0] == UNICODE_CR) {
Warning (SourceFile->FileName, SourceFile->LineNum, 0, "carriage return found in quoted string", "%S", Start);
PreviousBackslash = FALSE;
} else if (SourceFile->FileBufferPtr[0] == UNICODE_BACKSLASH) {
PreviousBackslash = TRUE;
} else {
PreviousBackslash = FALSE;
}
SourceFile->FileBufferPtr++;
Len++;
}
if (SourceFile->FileBufferPtr[0] != UNICODE_DOUBLE_QUOTE) {
Warning (SourceFile->FileName, SourceFile->LineNum, 0, "missing closing quote on string", "%S", Start);
} else {
SourceFile->FileBufferPtr++;
}
//
// Now allocate memory for the string and save it off
//
String = (WCHAR *) malloc ((Len + 1) * sizeof (WCHAR));
if (String == NULL) {
Error (NULL, 0, 0, "memory allocation failed", NULL);
return NULL;
}
//
// Copy the string from the file buffer to the local copy.
// We do no reformatting of it whatsoever at this point.
//
Ptr = String;
while (Len > 0) {
*Ptr = *Start;
Start++;
Ptr++;
Len--;
}
*Ptr = 0;
return String;
}
//
// Parse:
// #string STR_ID_NAME
//
// All we can do is call the string database to add the string identifier. Unfortunately
// he'll have to keep track of the last identifier we added.
//
static
void
ProcessTokenString (
SOURCE_FILE *SourceFile
)
{
WCHAR StringIdentifier[MAX_STRING_IDENTIFIER_NAME];
UINT16 StringId;
//
// Extract the string identifier name and add it to the database.
//
if (GetStringIdentifierName (SourceFile, StringIdentifier, sizeof (StringIdentifier)) > 0) {
StringId = STRING_ID_INVALID;
StringDBAddStringIdentifier (StringIdentifier, &StringId, 0);
} else {
//
// Error recovery -- skip to the next #
//
SourceFile->SkipToHash = TRUE;
}
}
static
BOOLEAN
EndOfFile (
SOURCE_FILE *SourceFile
)
{
//
// The file buffer pointer will typically get updated before the End-of-file flag in the
// source file structure, so check it first.
//
if (SourceFile->FileBufferPtr >= SourceFile->FileBuffer + SourceFile->FileSize / sizeof (WCHAR)) {
SourceFile->EndOfFile = TRUE;
return TRUE;
}
if (SourceFile->EndOfFile) {
return TRUE;
}
return FALSE;
}
static
UINT32
GetStringIdentifierName (
IN SOURCE_FILE *SourceFile,
IN OUT WCHAR *StringIdentifierName,
IN UINT32 StringIdentifierNameLen
)
{
UINT32 Len;
WCHAR *From;
WCHAR *Start;
//
// Skip whitespace
//
SkipWhiteSpace (SourceFile);
if (SourceFile->EndOfFile) {
Error (SourceFile->FileName, SourceFile->LineNum, 0, "end-of-file encountered", "expected string identifier");
return 0;
}
//
// Verify first character of name is [A-Za-z]
//
Len = 0;
StringIdentifierNameLen /= 2;
From = SourceFile->FileBufferPtr;
Start = SourceFile->FileBufferPtr;
if (((SourceFile->FileBufferPtr[0] >= UNICODE_A) && (SourceFile->FileBufferPtr[0] <= UNICODE_Z)) ||
((SourceFile->FileBufferPtr[0] >= UNICODE_z) && (SourceFile->FileBufferPtr[0] <= UNICODE_z))
) {
//
// Do nothing
//
} else {
Error (SourceFile->FileName, SourceFile->LineNum, 0, "invalid character in string identifier name", "%S", Start);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?