]>
git.proxmox.com Git - mirror_edk2.git/blob - Tools/Source/TianoTools/FlashMap/Symbols.c
3 Copyright (c) 2004-2006 Intel Corporation. All rights reserved
4 This program and the accompanying materials are licensed and made available
5 under the terms and conditions of the BSD License which accompanies this
6 distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 Class-like implementation for a symbol table.
22 // GC_TODO: fix comment to set correct module name: Symbols.c
31 #include <Common/UefiBaseTypes.h>
33 #include "CommonLib.h"
34 #include "EfiUtilityMsgs.h"
37 #define MAX_LINE_LEN 512
40 // Linked list to keep track of all symbols
42 typedef struct _SYMBOL
{
63 static SYMBOL
*mSymbolTable
= NULL
;
73 GC_TODO: Add function description
81 GC_TODO: add return values
96 GC_TODO: Add function description
104 GC_TODO: add return values
108 mSymbolTable
= FreeSymbols (mSymbolTable
);
119 Look up a symbol in our symbol table.
127 Pointer to the value of the symbol if found
128 NULL if the symbol is not found
131 // GC_TODO: SymbolName - add argument and description to function comment
135 // Walk the symbol table
137 Symbol
= mSymbolTable
;
139 if (stricmp (SymbolName
, Symbol
->Name
) == 0) {
140 return Symbol
->Value
;
143 Symbol
= Symbol
->Next
;
159 Add a symbol name/value to the symbol table
163 Name - name of symbol to add
164 Value - value of symbol to add
165 Mode - currrently unused
169 Length of symbol added.
172 If Value == NULL, then this routine will assume that the Name field
173 looks something like "MySymName = MySymValue", and will try to parse
174 it that way and add the symbol name/pair from the string.
191 // If value pointer is null, then they passed us a line something like:
192 // varname = value, or simply var =
196 while (*Name
&& isspace (*Name
)) {
204 // Find the end of the name. Either space or a '='.
206 for (Value
= Name
; *Value
&& !isspace (*Value
) && (*Value
!= '='); Value
++)
215 while (*Value
&& (*Value
!= '=')) {
223 // Now truncate the name
227 // Skip over the = and then any spaces
230 while (*Value
&& isspace (*Value
)) {
235 // Find end of string, checking for quoted string
237 if (*Value
== '\"') {
239 for (Cptr
= Value
; *Cptr
&& *Cptr
!= '\"'; Cptr
++)
242 for (Cptr
= Value
; *Cptr
&& !isspace (*Cptr
); Cptr
++)
246 // Null terminate the value string
251 Len
= (int) (Cptr
- Start
);
254 // We now have a symbol name and a value. Look for an existing variable
257 Symbol
= mSymbolTable
;
260 // Check for symbol name match
262 if (stricmp (Name
, Symbol
->Name
) == 0) {
263 _free (Symbol
->Value
);
264 Symbol
->Value
= (char *) _malloc (strlen (Value
) + 1);
265 if (Symbol
->Value
== NULL
) {
266 Error (NULL
, 0, 0, NULL
, "failed to allocate memory");
270 strcpy (Symbol
->Value
, Value
);
272 // If value == "NULL", then make it a 0-length string
274 if (stricmp (Symbol
->Value
, "NULL") == 0) {
275 Symbol
->Value
[0] = 0;
281 Symbol
= Symbol
->Next
;
284 // Does not exist, create a new one
286 NewSymbol
= (SYMBOL
*) _malloc (sizeof (SYMBOL
));
287 if (NewSymbol
== NULL
) {
288 Error (NULL
, 0, 0, NULL
, "memory allocation failure");
292 memset ((char *) NewSymbol
, 0, sizeof (SYMBOL
));
293 NewSymbol
->Name
= (char *) _malloc (strlen (Name
) + 1);
294 if (NewSymbol
->Name
== NULL
) {
295 Error (NULL
, 0, 0, NULL
, "memory allocation failure");
300 NewSymbol
->Value
= (char *) _malloc (strlen (Value
) + 1);
301 if (NewSymbol
->Value
== NULL
) {
302 Error (NULL
, 0, 0, NULL
, "memory allocation failure");
303 _free (NewSymbol
->Name
);
308 strcpy (NewSymbol
->Name
, Name
);
309 strcpy (NewSymbol
->Value
, Value
);
311 // Remove trailing spaces
313 Cptr
= NewSymbol
->Value
+ strlen (NewSymbol
->Value
) - 1;
314 while (Cptr
> NewSymbol
->Value
) {
315 if (isspace (*Cptr
)) {
323 // Add it to the head of the list.
325 NewSymbol
->Next
= mSymbolTable
;
326 mSymbolTable
= NewSymbol
;
328 // If value == "NULL", then make it a 0-length string
330 if (stricmp (NewSymbol
->Value
, "NULL") == 0) {
331 NewSymbol
->Value
[0] = 0;
334 // Restore the terminator we inserted if they passed in var=value
336 if (SaveCptr
!= NULL
) {
339 _free (NewSymbol
->Value
);
340 _free (NewSymbol
->Name
);
355 Remove a symbol name/value from the symbol table
359 Name - name of symbol to remove
360 SymbolType - type of symbol to remove
364 STATUS_SUCCESS - matching symbol found and removed
365 STATUS_ERROR - matching symbol not found in symbol table
374 Symbol
= mSymbolTable
;
376 // Walk the linked list of symbols in the symbol table looking
377 // for a match of both symbol name and type.
380 if ((stricmp (Name
, Symbol
->Name
) == 0) && (Symbol
->Type
& SymbolType
)) {
382 // If the symbol has a value associated with it, free the memory
383 // allocated for the value.
384 // Then free the memory allocated for the symbols string name.
387 _free (Symbol
->Value
);
390 _free (Symbol
->Name
);
392 // Link the previous symbol to the next symbol to effectively
393 // remove this symbol from the linked list.
396 PrevSymbol
->Next
= Symbol
->Next
;
398 mSymbolTable
= Symbol
->Next
;
402 return STATUS_SUCCESS
;
406 Symbol
= Symbol
->Next
;
409 return STATUS_WARNING
;
421 GC_TODO: Add function description
425 Syms - GC_TODO: add argument description
429 GC_TODO: add return values
435 if (Syms
->Name
!= NULL
) {
439 if (Syms
->Value
!= NULL
) {
462 Given a line of text, replace all variables of format $(NAME) with values
463 from our symbol table.
467 SourceLine - input line of text to do symbol replacements on
468 DestLine - on output, SourceLine with symbols replaced
469 LineLen - length of DestLine, so we don't exceed its allocated length
473 STATUS_SUCCESS - no problems encountered
474 STATUS_WARNING - missing closing parenthesis on a symbol reference in SourceLine
475 STATUS_ERROR - memory allocation failure
479 static int NestDepth
= 0;
492 Status
= STATUS_SUCCESS
;
493 LocalDestLine
= (char *) _malloc (LineLen
);
494 if (LocalDestLine
== NULL
) {
495 Error (__FILE__
, __LINE__
, 0, "memory allocation failed", NULL
);
499 FromPtr
= SourceLine
;
500 ToPtr
= LocalDestLine
;
502 // Walk the entire line, replacing $(MACRO_NAME).
504 LocalLineLen
= LineLen
;
506 while (*FromPtr
&& (LocalLineLen
> 0)) {
507 if ((*FromPtr
== '$') && (*(FromPtr
+ 1) == '(')) {
509 // Save the start in case it's undefined, in which case we copy it as-is.
514 // Macro expansion time. Find the end (no spaces allowed)
517 for (Cptr
= FromPtr
; *Cptr
&& (*Cptr
!= ')'); Cptr
++)
521 // Truncate the string at the closing parenthesis for ease-of-use.
522 // Then copy the string directly to the destination line in case we don't find
523 // a definition for it.
526 strcpy (ToPtr
, SaveStart
);
527 if ((value
= GetSymbolValue (FromPtr
)) != NULL
) {
528 strcpy (ToPtr
, value
);
529 LocalLineLen
-= strlen (value
);
530 ToPtr
+= strlen (value
);
537 // Restore closing parenthesis, and advance to next character
540 FromPtr
= SaveStart
+ 1;
546 Error (NULL
, 0, 0, SourceLine
, "missing closing parenthesis on macro");
547 strcpy (ToPtr
, FromPtr
);
548 Status
= STATUS_WARNING
;
564 // If we expanded at least one string successfully, then make a recursive call to try again.
566 if ((ExpandedCount
!= 0) && (Status
== STATUS_SUCCESS
) && (NestDepth
< 10)) {
567 Status
= ExpandMacros (LocalDestLine
, DestLine
, LineLen
);
568 _free (LocalDestLine
);
574 if (Status
!= STATUS_ERROR
) {
575 strcpy (DestLine
, LocalDestLine
);
579 _free (LocalDestLine
);
584 SymbolsFileStringsReplace (
592 Given input and output file names, read in the input file, replace variable
593 references of format $(NAME) with appropriate values from our symbol table,
594 and write the result out to the output file.
598 InFileName - name of input text file to replace variable references
599 OutFileName - name of output text file to write results to
603 STATUS_SUCCESS - no problems encountered
604 STATUS_ERROR - failed to open input or output file
611 char Line
[MAX_LINE_LEN
];
612 char OutLine
[MAX_LINE_LEN
];
614 Status
= STATUS_ERROR
;
616 // Open input and output files
620 if ((InFptr
= fopen (InFileName
, "r")) == NULL
) {
621 Error (NULL
, 0, 0, InFileName
, "failed to open input file for reading");
625 if ((OutFptr
= fopen (OutFileName
, "w")) == NULL
) {
626 Error (NULL
, 0, 0, OutFileName
, "failed to open output file for writing");
630 // Read lines from input file until done
632 while (fgets (Line
, sizeof (Line
), InFptr
) != NULL
) {
633 ExpandMacros (Line
, OutLine
, sizeof (OutLine
));
634 fprintf (OutFptr
, OutLine
);
637 Status
= STATUS_SUCCESS
;
639 if (InFptr
!= NULL
) {
643 if (OutFptr
!= NULL
) {