]>
git.proxmox.com Git - mirror_edk2.git/blob - Tools/Source/TianoTools/FlashMap/Symbols.c
3 Copyright (c) 2004 Intel Corporation. All rights reserved
4 This software and associated documentation (if any) is furnished
5 under a license and may only be used or copied in accordance
6 with the terms of the license. Except as permitted by such
7 license, no part of this software or documentation may be
8 reproduced, stored in a retrieval system, or transmitted in any
9 form or by any means without the express written consent of
19 Class-like implementation for a symbol table.
23 // GC_TODO: fix comment to set correct module name: Symbols.c
32 #include <UefiBaseTypes.h>
34 #include <CommonLib.h>
36 #include "EfiUtilityMsgs.h"
39 #define MAX_LINE_LEN 512
42 // Linked list to keep track of all symbols
44 typedef struct _SYMBOL
{
65 static SYMBOL
*mSymbolTable
= NULL
;
75 GC_TODO: Add function description
83 GC_TODO: add return values
98 GC_TODO: Add function description
106 GC_TODO: add return values
110 mSymbolTable
= FreeSymbols (mSymbolTable
);
121 Look up a symbol in our symbol table.
129 Pointer to the value of the symbol if found
130 NULL if the symbol is not found
133 // GC_TODO: SymbolName - add argument and description to function comment
137 // Walk the symbol table
139 Symbol
= mSymbolTable
;
141 if (stricmp (SymbolName
, Symbol
->Name
) == 0) {
142 return Symbol
->Value
;
145 Symbol
= Symbol
->Next
;
161 Add a symbol name/value to the symbol table
165 Name - name of symbol to add
166 Value - value of symbol to add
167 Mode - currrently unused
171 Length of symbol added.
174 If Value == NULL, then this routine will assume that the Name field
175 looks something like "MySymName = MySymValue", and will try to parse
176 it that way and add the symbol name/pair from the string.
193 // If value pointer is null, then they passed us a line something like:
194 // varname = value, or simply var =
198 while (*Name
&& isspace (*Name
)) {
206 // Find the end of the name. Either space or a '='.
208 for (Value
= Name
; *Value
&& !isspace (*Value
) && (*Value
!= '='); Value
++)
217 while (*Value
&& (*Value
!= '=')) {
225 // Now truncate the name
229 // Skip over the = and then any spaces
232 while (*Value
&& isspace (*Value
)) {
237 // Find end of string, checking for quoted string
239 if (*Value
== '\"') {
241 for (Cptr
= Value
; *Cptr
&& *Cptr
!= '\"'; Cptr
++)
244 for (Cptr
= Value
; *Cptr
&& !isspace (*Cptr
); Cptr
++)
248 // Null terminate the value string
253 Len
= (int) (Cptr
- Start
);
256 // We now have a symbol name and a value. Look for an existing variable
259 Symbol
= mSymbolTable
;
262 // Check for symbol name match
264 if (stricmp (Name
, Symbol
->Name
) == 0) {
265 _free (Symbol
->Value
);
266 Symbol
->Value
= (char *) _malloc (strlen (Value
) + 1);
267 if (Symbol
->Value
== NULL
) {
268 Error (NULL
, 0, 0, NULL
, "failed to allocate memory");
272 strcpy (Symbol
->Value
, Value
);
274 // If value == "NULL", then make it a 0-length string
276 if (stricmp (Symbol
->Value
, "NULL") == 0) {
277 Symbol
->Value
[0] = 0;
283 Symbol
= Symbol
->Next
;
286 // Does not exist, create a new one
288 NewSymbol
= (SYMBOL
*) _malloc (sizeof (SYMBOL
));
289 if (NewSymbol
== NULL
) {
290 Error (NULL
, 0, 0, NULL
, "memory allocation failure");
294 memset ((char *) NewSymbol
, 0, sizeof (SYMBOL
));
295 NewSymbol
->Name
= (char *) _malloc (strlen (Name
) + 1);
296 if (NewSymbol
->Name
== NULL
) {
297 Error (NULL
, 0, 0, NULL
, "memory allocation failure");
302 NewSymbol
->Value
= (char *) _malloc (strlen (Value
) + 1);
303 if (NewSymbol
->Value
== NULL
) {
304 Error (NULL
, 0, 0, NULL
, "memory allocation failure");
305 _free (NewSymbol
->Name
);
310 strcpy (NewSymbol
->Name
, Name
);
311 strcpy (NewSymbol
->Value
, Value
);
313 // Remove trailing spaces
315 Cptr
= NewSymbol
->Value
+ strlen (NewSymbol
->Value
) - 1;
316 while (Cptr
> NewSymbol
->Value
) {
317 if (isspace (*Cptr
)) {
325 // Add it to the head of the list.
327 NewSymbol
->Next
= mSymbolTable
;
328 mSymbolTable
= NewSymbol
;
330 // If value == "NULL", then make it a 0-length string
332 if (stricmp (NewSymbol
->Value
, "NULL") == 0) {
333 NewSymbol
->Value
[0] = 0;
336 // Restore the terminator we inserted if they passed in var=value
338 if (SaveCptr
!= NULL
) {
341 _free (NewSymbol
->Value
);
342 _free (NewSymbol
->Name
);
357 Remove a symbol name/value from the symbol table
361 Name - name of symbol to remove
362 SymbolType - type of symbol to remove
366 STATUS_SUCCESS - matching symbol found and removed
367 STATUS_ERROR - matching symbol not found in symbol table
376 Symbol
= mSymbolTable
;
378 // Walk the linked list of symbols in the symbol table looking
379 // for a match of both symbol name and type.
382 if ((stricmp (Name
, Symbol
->Name
) == 0) && (Symbol
->Type
& SymbolType
)) {
384 // If the symbol has a value associated with it, free the memory
385 // allocated for the value.
386 // Then free the memory allocated for the symbols string name.
389 _free (Symbol
->Value
);
392 _free (Symbol
->Name
);
394 // Link the previous symbol to the next symbol to effectively
395 // remove this symbol from the linked list.
398 PrevSymbol
->Next
= Symbol
->Next
;
400 mSymbolTable
= Symbol
->Next
;
404 return STATUS_SUCCESS
;
408 Symbol
= Symbol
->Next
;
411 return STATUS_WARNING
;
423 GC_TODO: Add function description
427 Syms - GC_TODO: add argument description
431 GC_TODO: add return values
437 if (Syms
->Name
!= NULL
) {
441 if (Syms
->Value
!= NULL
) {
464 Given a line of text, replace all variables of format $(NAME) with values
465 from our symbol table.
469 SourceLine - input line of text to do symbol replacements on
470 DestLine - on output, SourceLine with symbols replaced
471 LineLen - length of DestLine, so we don't exceed its allocated length
475 STATUS_SUCCESS - no problems encountered
476 STATUS_WARNING - missing closing parenthesis on a symbol reference in SourceLine
477 STATUS_ERROR - memory allocation failure
481 static int NestDepth
= 0;
494 Status
= STATUS_SUCCESS
;
495 LocalDestLine
= (char *) _malloc (LineLen
);
496 if (LocalDestLine
== NULL
) {
497 Error (__FILE__
, __LINE__
, 0, "memory allocation failed", NULL
);
501 FromPtr
= SourceLine
;
502 ToPtr
= LocalDestLine
;
504 // Walk the entire line, replacing $(MACRO_NAME).
506 LocalLineLen
= LineLen
;
508 while (*FromPtr
&& (LocalLineLen
> 0)) {
509 if ((*FromPtr
== '$') && (*(FromPtr
+ 1) == '(')) {
511 // Save the start in case it's undefined, in which case we copy it as-is.
516 // Macro expansion time. Find the end (no spaces allowed)
519 for (Cptr
= FromPtr
; *Cptr
&& (*Cptr
!= ')'); Cptr
++)
523 // Truncate the string at the closing parenthesis for ease-of-use.
524 // Then copy the string directly to the destination line in case we don't find
525 // a definition for it.
528 strcpy (ToPtr
, SaveStart
);
529 if ((value
= GetSymbolValue (FromPtr
)) != NULL
) {
530 strcpy (ToPtr
, value
);
531 LocalLineLen
-= strlen (value
);
532 ToPtr
+= strlen (value
);
539 // Restore closing parenthesis, and advance to next character
542 FromPtr
= SaveStart
+ 1;
548 Error (NULL
, 0, 0, SourceLine
, "missing closing parenthesis on macro");
549 strcpy (ToPtr
, FromPtr
);
550 Status
= STATUS_WARNING
;
566 // If we expanded at least one string successfully, then make a recursive call to try again.
568 if ((ExpandedCount
!= 0) && (Status
== STATUS_SUCCESS
) && (NestDepth
< 10)) {
569 Status
= ExpandMacros (LocalDestLine
, DestLine
, LineLen
);
570 _free (LocalDestLine
);
576 if (Status
!= STATUS_ERROR
) {
577 strcpy (DestLine
, LocalDestLine
);
581 _free (LocalDestLine
);
586 SymbolsFileStringsReplace (
594 Given input and output file names, read in the input file, replace variable
595 references of format $(NAME) with appropriate values from our symbol table,
596 and write the result out to the output file.
600 InFileName - name of input text file to replace variable references
601 OutFileName - name of output text file to write results to
605 STATUS_SUCCESS - no problems encountered
606 STATUS_ERROR - failed to open input or output file
613 char Line
[MAX_LINE_LEN
];
614 char OutLine
[MAX_LINE_LEN
];
616 Status
= STATUS_ERROR
;
618 // Open input and output files
622 if ((InFptr
= fopen (InFileName
, "r")) == NULL
) {
623 Error (NULL
, 0, 0, InFileName
, "failed to open input file for reading");
627 if ((OutFptr
= fopen (OutFileName
, "w")) == NULL
) {
628 Error (NULL
, 0, 0, OutFileName
, "failed to open output file for writing");
632 // Read lines from input file until done
634 while (fgets (Line
, sizeof (Line
), InFptr
) != NULL
) {
635 ExpandMacros (Line
, OutLine
, sizeof (OutLine
));
636 fprintf (OutFptr
, OutLine
);
639 Status
= STATUS_SUCCESS
;
641 if (InFptr
!= NULL
) {
645 if (OutFptr
!= NULL
) {