From feccee87a78e68d575dbdf44b34ca0cb5a21ea8d Mon Sep 17 00:00:00 2001 From: lhauch Date: Thu, 5 Oct 2006 23:12:07 +0000 Subject: Restructuring for better separation of Tool packages. git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@1674 6f19259b-4bc3-4df7-8a09-765794883524 --- Tools/CodeTools/TianoTools/FlashMap/Symbols.c | 648 ++++++++++++++++++++++++++ 1 file changed, 648 insertions(+) create mode 100644 Tools/CodeTools/TianoTools/FlashMap/Symbols.c (limited to 'Tools/CodeTools/TianoTools/FlashMap/Symbols.c') diff --git a/Tools/CodeTools/TianoTools/FlashMap/Symbols.c b/Tools/CodeTools/TianoTools/FlashMap/Symbols.c new file mode 100644 index 0000000000..8e408144db --- /dev/null +++ b/Tools/CodeTools/TianoTools/FlashMap/Symbols.c @@ -0,0 +1,648 @@ +/*++ + +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: + + Symbol.c + +Abstract: + + Class-like implementation for a symbol table. + +--*/ + +// GC_TODO: fix comment to set correct module name: Symbols.c +#include +#include +#include +// +// for isspace() +// +#include + +#include + +#include "CommonLib.h" +#include "EfiUtilityMsgs.h" +#include "Symbols.h" + +#define MAX_LINE_LEN 512 + +// +// Linked list to keep track of all symbols +// +typedef struct _SYMBOL { + struct _SYMBOL *Next; + int Type; + char *Name; + char *Value; +} SYMBOL; + +static +SYMBOL * +FreeSymbols ( + SYMBOL *Syms + ); + +static +int +ExpandMacros ( + char *SourceLine, + char *DestLine, + int LineLen + ); + +static SYMBOL *mSymbolTable = NULL; + +void +SymbolsConstructor ( + VOID + ) +/*++ + +Routine Description: + + GC_TODO: Add function description + +Arguments: + + None + +Returns: + + GC_TODO: add return values + +--*/ +{ + SymbolsDestructor (); +} + +void +SymbolsDestructor ( + VOID + ) +/*++ + +Routine Description: + + GC_TODO: Add function description + +Arguments: + + None + +Returns: + + GC_TODO: add return values + +--*/ +{ + mSymbolTable = FreeSymbols (mSymbolTable); +} + +char * +GetSymbolValue ( + char *SymbolName + ) +/*++ + +Routine Description: + + Look up a symbol in our symbol table. + +Arguments: + + SymbolName + +Returns: + + Pointer to the value of the symbol if found + NULL if the symbol is not found + +--*/ +// GC_TODO: SymbolName - add argument and description to function comment +{ + SYMBOL *Symbol; + // + // Walk the symbol table + // + Symbol = mSymbolTable; + while (Symbol) { + if (stricmp (SymbolName, Symbol->Name) == 0) { + return Symbol->Value; + } + + Symbol = Symbol->Next; + } + + return NULL; +} + +int +SymbolAdd ( + char *Name, + char *Value, + int Mode + ) +/*++ + +Routine Description: + + Add a symbol name/value to the symbol table + +Arguments: + + Name - name of symbol to add + Value - value of symbol to add + Mode - currrently unused + +Returns: + + Length of symbol added. + +Notes: + If Value == NULL, then this routine will assume that the Name field + looks something like "MySymName = MySymValue", and will try to parse + it that way and add the symbol name/pair from the string. + +--*/ +{ + SYMBOL *Symbol; + + SYMBOL *NewSymbol; + int Len; + char *Start; + char *Cptr; + char CSave; + char *SaveCptr; + + Len = 0; + SaveCptr = NULL; + CSave = 0; + // + // If value pointer is null, then they passed us a line something like: + // varname = value, or simply var = + // + if (Value == NULL) { + Start = Name; + while (*Name && isspace (*Name)) { + Name++; + } + + if (Name == NULL) { + return -1; + } + // + // Find the end of the name. Either space or a '='. + // + for (Value = Name; *Value && !isspace (*Value) && (*Value != '='); Value++) + ; + if (Value == NULL) { + return -1; + } + // + // Look for the '=' + // + Cptr = Value; + while (*Value && (*Value != '=')) { + Value++; + } + + if (Value == NULL) { + return -1; + } + // + // Now truncate the name + // + *Cptr = 0; + // + // Skip over the = and then any spaces + // + Value++; + while (*Value && isspace (*Value)) { + Value++; + + } + // + // Find end of string, checking for quoted string + // + if (*Value == '\"') { + Value++; + for (Cptr = Value; *Cptr && *Cptr != '\"'; Cptr++) + ; + } else { + for (Cptr = Value; *Cptr && !isspace (*Cptr); Cptr++) + ; + } + // + // Null terminate the value string + // + CSave = *Cptr; + SaveCptr = Cptr; + *Cptr = 0; + Len = (int) (Cptr - Start); + } + // + // We now have a symbol name and a value. Look for an existing variable + // and overwrite it. + // + Symbol = mSymbolTable; + while (Symbol) { + // + // Check for symbol name match + // + if (stricmp (Name, Symbol->Name) == 0) { + _free (Symbol->Value); + Symbol->Value = (char *) _malloc (strlen (Value) + 1); + if (Symbol->Value == NULL) { + Error (NULL, 0, 0, NULL, "failed to allocate memory"); + return -1; + } + + strcpy (Symbol->Value, Value); + // + // If value == "NULL", then make it a 0-length string + // + if (stricmp (Symbol->Value, "NULL") == 0) { + Symbol->Value[0] = 0; + } + + return Len; + } + + Symbol = Symbol->Next; + } + // + // Does not exist, create a new one + // + NewSymbol = (SYMBOL *) _malloc (sizeof (SYMBOL)); + if (NewSymbol == NULL) { + Error (NULL, 0, 0, NULL, "memory allocation failure"); + return -1; + } + + memset ((char *) NewSymbol, 0, sizeof (SYMBOL)); + NewSymbol->Name = (char *) _malloc (strlen (Name) + 1); + if (NewSymbol->Name == NULL) { + Error (NULL, 0, 0, NULL, "memory allocation failure"); + _free (NewSymbol); + return -1; + } + + NewSymbol->Value = (char *) _malloc (strlen (Value) + 1); + if (NewSymbol->Value == NULL) { + Error (NULL, 0, 0, NULL, "memory allocation failure"); + _free (NewSymbol->Name); + _free (NewSymbol); + return -1; + } + + strcpy (NewSymbol->Name, Name); + strcpy (NewSymbol->Value, Value); + // + // Remove trailing spaces + // + Cptr = NewSymbol->Value + strlen (NewSymbol->Value) - 1; + while (Cptr > NewSymbol->Value) { + if (isspace (*Cptr)) { + *Cptr = 0; + Cptr--; + } else { + break; + } + } + // + // Add it to the head of the list. + // + NewSymbol->Next = mSymbolTable; + mSymbolTable = NewSymbol; + // + // If value == "NULL", then make it a 0-length string + // + if (stricmp (NewSymbol->Value, "NULL") == 0) { + NewSymbol->Value[0] = 0; + } + // + // Restore the terminator we inserted if they passed in var=value + // + if (SaveCptr != NULL) { + *SaveCptr = CSave; + } + _free (NewSymbol->Value); + _free (NewSymbol->Name); + _free (NewSymbol); + return Len; +} + +static +STATUS +RemoveSymbol ( + char *Name, + char SymbolType + ) +/*++ + +Routine Description: + + Remove a symbol name/value from the symbol table + +Arguments: + + Name - name of symbol to remove + SymbolType - type of symbol to remove + +Returns: + + STATUS_SUCCESS - matching symbol found and removed + STATUS_ERROR - matching symbol not found in symbol table + +--*/ +{ + SYMBOL *Symbol; + + SYMBOL *PrevSymbol; + + PrevSymbol = NULL; + Symbol = mSymbolTable; + // + // Walk the linked list of symbols in the symbol table looking + // for a match of both symbol name and type. + // + while (Symbol) { + if ((stricmp (Name, Symbol->Name) == 0) && (Symbol->Type & SymbolType)) { + // + // If the symbol has a value associated with it, free the memory + // allocated for the value. + // Then free the memory allocated for the symbols string name. + // + if (Symbol->Value) { + _free (Symbol->Value); + } + + _free (Symbol->Name); + // + // Link the previous symbol to the next symbol to effectively + // remove this symbol from the linked list. + // + if (PrevSymbol) { + PrevSymbol->Next = Symbol->Next; + } else { + mSymbolTable = Symbol->Next; + } + + _free (Symbol); + return STATUS_SUCCESS; + } + + PrevSymbol = Symbol; + Symbol = Symbol->Next; + } + + return STATUS_WARNING; +} + +static +SYMBOL * +FreeSymbols ( + SYMBOL *Syms + ) +/*++ + +Routine Description: + + GC_TODO: Add function description + +Arguments: + + Syms - GC_TODO: add argument description + +Returns: + + GC_TODO: add return values + +--*/ +{ + SYMBOL *Next; + while (Syms) { + if (Syms->Name != NULL) { + _free (Syms->Name); + } + + if (Syms->Value != NULL) { + _free (Syms->Value); + } + + Next = Syms->Next; + _free (Syms); + Syms = Next; + } + + return Syms; +} + +static +int +ExpandMacros ( + char *SourceLine, + char *DestLine, + int LineLen + ) +/*++ + +Routine Description: + + Given a line of text, replace all variables of format $(NAME) with values + from our symbol table. + +Arguments: + + SourceLine - input line of text to do symbol replacements on + DestLine - on output, SourceLine with symbols replaced + LineLen - length of DestLine, so we don't exceed its allocated length + +Returns: + + STATUS_SUCCESS - no problems encountered + STATUS_WARNING - missing closing parenthesis on a symbol reference in SourceLine + STATUS_ERROR - memory allocation failure + +--*/ +{ + static int NestDepth = 0; + char *FromPtr; + char *ToPtr; + char *SaveStart; + char *Cptr; + char *value; + int Expanded; + int ExpandedCount; + INT8 *LocalDestLine; + STATUS Status; + int LocalLineLen; + + NestDepth++; + Status = STATUS_SUCCESS; + LocalDestLine = (char *) _malloc (LineLen); + if (LocalDestLine == NULL) { + Error (__FILE__, __LINE__, 0, "memory allocation failed", NULL); + return STATUS_ERROR; + } + + FromPtr = SourceLine; + ToPtr = LocalDestLine; + // + // Walk the entire line, replacing $(MACRO_NAME). + // + LocalLineLen = LineLen; + ExpandedCount = 0; + while (*FromPtr && (LocalLineLen > 0)) { + if ((*FromPtr == '$') && (*(FromPtr + 1) == '(')) { + // + // Save the start in case it's undefined, in which case we copy it as-is. + // + SaveStart = FromPtr; + Expanded = 0; + // + // Macro expansion time. Find the end (no spaces allowed) + // + FromPtr += 2; + for (Cptr = FromPtr; *Cptr && (*Cptr != ')'); Cptr++) + ; + if (*Cptr) { + // + // Truncate the string at the closing parenthesis for ease-of-use. + // Then copy the string directly to the destination line in case we don't find + // a definition for it. + // + *Cptr = 0; + strcpy (ToPtr, SaveStart); + if ((value = GetSymbolValue (FromPtr)) != NULL) { + strcpy (ToPtr, value); + LocalLineLen -= strlen (value); + ToPtr += strlen (value); + Expanded = 1; + ExpandedCount++; + } + + if (!Expanded) { + // + // Restore closing parenthesis, and advance to next character + // + *Cptr = ')'; + FromPtr = SaveStart + 1; + ToPtr++; + } else { + FromPtr = Cptr + 1; + } + } else { + Error (NULL, 0, 0, SourceLine, "missing closing parenthesis on macro"); + strcpy (ToPtr, FromPtr); + Status = STATUS_WARNING; + goto Done; + } + } else { + *ToPtr = *FromPtr; + FromPtr++; + ToPtr++; + LocalLineLen--; + } + } + + if (*FromPtr == 0) { + *ToPtr = 0; + } + + // + // If we expanded at least one string successfully, then make a recursive call to try again. + // + if ((ExpandedCount != 0) && (Status == STATUS_SUCCESS) && (NestDepth < 10)) { + Status = ExpandMacros (LocalDestLine, DestLine, LineLen); + _free (LocalDestLine); + NestDepth = 0; + return Status; + } + +Done: + if (Status != STATUS_ERROR) { + strcpy (DestLine, LocalDestLine); + } + + NestDepth = 0; + _free (LocalDestLine); + return Status; +} + +STATUS +SymbolsFileStringsReplace ( + char *InFileName, + char *OutFileName + ) +/*++ + +Routine Description: + + Given input and output file names, read in the input file, replace variable + references of format $(NAME) with appropriate values from our symbol table, + and write the result out to the output file. + +Arguments: + + InFileName - name of input text file to replace variable references + OutFileName - name of output text file to write results to + +Returns: + + STATUS_SUCCESS - no problems encountered + STATUS_ERROR - failed to open input or output file + +--*/ +{ + STATUS Status; + FILE *InFptr; + FILE *OutFptr; + char Line[MAX_LINE_LEN]; + char OutLine[MAX_LINE_LEN]; + + Status = STATUS_ERROR; + // + // Open input and output files + // + InFptr = NULL; + OutFptr = NULL; + if ((InFptr = fopen (InFileName, "r")) == NULL) { + Error (NULL, 0, 0, InFileName, "failed to open input file for reading"); + goto Done; + } + + if ((OutFptr = fopen (OutFileName, "w")) == NULL) { + Error (NULL, 0, 0, OutFileName, "failed to open output file for writing"); + goto Done; + } + // + // Read lines from input file until done + // + while (fgets (Line, sizeof (Line), InFptr) != NULL) { + ExpandMacros (Line, OutLine, sizeof (OutLine)); + fprintf (OutFptr, OutLine); + } + + Status = STATUS_SUCCESS; +Done: + if (InFptr != NULL) { + fclose (InFptr); + } + + if (OutFptr != NULL) { + fclose (OutFptr); + } + + return Status; +} -- cgit v1.2.3