]> git.proxmox.com Git - mirror_edk2.git/blame - Tools/Source/TianoTools/FlashMap/Symbols.c
1. Removed the unnecessary #include statements and include files
[mirror_edk2.git] / Tools / Source / TianoTools / FlashMap / Symbols.c
CommitLineData
d25c4bf0 1/*++\r
2\r
3Copyright (c) 2004 Intel Corporation. All rights reserved\r
4This software and associated documentation (if any) is furnished\r
5under a license and may only be used or copied in accordance\r
6with the terms of the license. Except as permitted by such\r
7license, no part of this software or documentation may be\r
8reproduced, stored in a retrieval system, or transmitted in any\r
9form or by any means without the express written consent of\r
10Intel Corporation.\r
11\r
12\r
13Module Name:\r
14\r
15 Symbol.c\r
16\r
17Abstract:\r
18\r
19 Class-like implementation for a symbol table.\r
20\r
21--*/\r
22\r
23// GC_TODO: fix comment to set correct module name: Symbols.c\r
24#include <stdio.h>\r
25#include <string.h>\r
26#include <stdlib.h>\r
27//\r
28// for isspace()\r
29//\r
30#include <ctype.h>\r
31\r
ce53a8c3 32#include <Common/UefiBaseTypes.h>\r
51d48c26 33\r
ce53a8c3 34#include "CommonLib.h"\r
d25c4bf0 35#include "EfiUtilityMsgs.h"\r
36#include "Symbols.h"\r
37\r
38#define MAX_LINE_LEN 512\r
39\r
40//\r
41// Linked list to keep track of all symbols\r
42//\r
43typedef struct _SYMBOL {\r
44 struct _SYMBOL *Next;\r
45 int Type;\r
46 char *Name;\r
47 char *Value;\r
48} SYMBOL;\r
49\r
50static\r
51SYMBOL *\r
52FreeSymbols (\r
53 SYMBOL *Syms\r
54 );\r
55\r
56static\r
57int\r
58ExpandMacros (\r
59 char *SourceLine,\r
60 char *DestLine,\r
61 int LineLen\r
62 );\r
63\r
64static SYMBOL *mSymbolTable = NULL;\r
65\r
66void\r
67SymbolsConstructor (\r
68 VOID\r
69 )\r
70/*++\r
71\r
72Routine Description:\r
73\r
74 GC_TODO: Add function description\r
75\r
76Arguments:\r
77\r
78 None\r
79\r
80Returns:\r
81\r
82 GC_TODO: add return values\r
83\r
84--*/\r
85{\r
86 SymbolsDestructor ();\r
87}\r
88\r
89void\r
90SymbolsDestructor (\r
91 VOID\r
92 )\r
93/*++\r
94\r
95Routine Description:\r
96\r
97 GC_TODO: Add function description\r
98\r
99Arguments:\r
100\r
101 None\r
102\r
103Returns:\r
104\r
105 GC_TODO: add return values\r
106\r
107--*/\r
108{\r
109 mSymbolTable = FreeSymbols (mSymbolTable);\r
110}\r
111\r
112char *\r
113GetSymbolValue (\r
114 char *SymbolName\r
115 )\r
116/*++\r
117\r
118Routine Description:\r
119 \r
120 Look up a symbol in our symbol table.\r
121\r
122Arguments:\r
123\r
124 SymbolName\r
125\r
126Returns:\r
127\r
128 Pointer to the value of the symbol if found\r
129 NULL if the symbol is not found\r
130\r
131--*/\r
132// GC_TODO: SymbolName - add argument and description to function comment\r
133{\r
134 SYMBOL *Symbol;\r
135 //\r
136 // Walk the symbol table\r
137 //\r
138 Symbol = mSymbolTable;\r
139 while (Symbol) {\r
140 if (stricmp (SymbolName, Symbol->Name) == 0) {\r
141 return Symbol->Value;\r
142 }\r
143\r
144 Symbol = Symbol->Next;\r
145 }\r
146\r
147 return NULL;\r
148}\r
149\r
150int\r
151SymbolAdd (\r
152 char *Name,\r
153 char *Value,\r
154 int Mode\r
155 )\r
156/*++\r
157\r
158Routine Description:\r
159 \r
160 Add a symbol name/value to the symbol table\r
161\r
162Arguments:\r
163\r
164 Name - name of symbol to add\r
165 Value - value of symbol to add\r
166 Mode - currrently unused\r
167\r
168Returns:\r
169\r
170 Length of symbol added.\r
171\r
172Notes:\r
173 If Value == NULL, then this routine will assume that the Name field\r
174 looks something like "MySymName = MySymValue", and will try to parse\r
175 it that way and add the symbol name/pair from the string.\r
176\r
177--*/\r
178{\r
179 SYMBOL *Symbol;\r
180\r
181 SYMBOL *NewSymbol;\r
182 int Len;\r
183 char *Start;\r
184 char *Cptr;\r
185 char CSave;\r
186 char *SaveCptr;\r
187\r
188 Len = 0;\r
189 SaveCptr = NULL;\r
190 CSave = 0;\r
191 //\r
192 // If value pointer is null, then they passed us a line something like:\r
193 // varname = value, or simply var =\r
194 //\r
195 if (Value == NULL) {\r
196 Start = Name;\r
197 while (*Name && isspace (*Name)) {\r
198 Name++;\r
199 }\r
200\r
201 if (Name == NULL) {\r
202 return -1;\r
203 }\r
204 //\r
205 // Find the end of the name. Either space or a '='.\r
206 //\r
207 for (Value = Name; *Value && !isspace (*Value) && (*Value != '='); Value++)\r
208 ;\r
209 if (Value == NULL) {\r
210 return -1;\r
211 }\r
212 //\r
213 // Look for the '='\r
214 //\r
215 Cptr = Value;\r
216 while (*Value && (*Value != '=')) {\r
217 Value++;\r
218 }\r
219\r
220 if (Value == NULL) {\r
221 return -1;\r
222 }\r
223 //\r
224 // Now truncate the name\r
225 //\r
226 *Cptr = 0;\r
227 //\r
228 // Skip over the = and then any spaces\r
229 //\r
230 Value++;\r
231 while (*Value && isspace (*Value)) {\r
232 Value++;\r
233\r
234 }\r
235 //\r
236 // Find end of string, checking for quoted string\r
237 //\r
238 if (*Value == '\"') {\r
239 Value++;\r
240 for (Cptr = Value; *Cptr && *Cptr != '\"'; Cptr++)\r
241 ;\r
242 } else {\r
243 for (Cptr = Value; *Cptr && !isspace (*Cptr); Cptr++)\r
244 ;\r
245 }\r
246 //\r
247 // Null terminate the value string\r
248 //\r
249 CSave = *Cptr;\r
250 SaveCptr = Cptr;\r
251 *Cptr = 0;\r
252 Len = (int) (Cptr - Start);\r
253 }\r
254 //\r
255 // We now have a symbol name and a value. Look for an existing variable\r
256 // and overwrite it.\r
257 //\r
258 Symbol = mSymbolTable;\r
259 while (Symbol) {\r
260 //\r
261 // Check for symbol name match\r
262 //\r
263 if (stricmp (Name, Symbol->Name) == 0) {\r
264 _free (Symbol->Value);\r
265 Symbol->Value = (char *) _malloc (strlen (Value) + 1);\r
266 if (Symbol->Value == NULL) {\r
267 Error (NULL, 0, 0, NULL, "failed to allocate memory");\r
268 return -1;\r
269 }\r
270\r
271 strcpy (Symbol->Value, Value);\r
272 //\r
273 // If value == "NULL", then make it a 0-length string\r
274 //\r
275 if (stricmp (Symbol->Value, "NULL") == 0) {\r
276 Symbol->Value[0] = 0;\r
277 }\r
278\r
279 return Len;\r
280 }\r
281\r
282 Symbol = Symbol->Next;\r
283 }\r
284 //\r
285 // Does not exist, create a new one\r
286 //\r
287 NewSymbol = (SYMBOL *) _malloc (sizeof (SYMBOL));\r
288 if (NewSymbol == NULL) {\r
289 Error (NULL, 0, 0, NULL, "memory allocation failure");\r
290 return -1;\r
291 }\r
292\r
293 memset ((char *) NewSymbol, 0, sizeof (SYMBOL));\r
294 NewSymbol->Name = (char *) _malloc (strlen (Name) + 1);\r
295 if (NewSymbol->Name == NULL) {\r
296 Error (NULL, 0, 0, NULL, "memory allocation failure");\r
297 _free (NewSymbol);\r
298 return -1;\r
299 }\r
300\r
301 NewSymbol->Value = (char *) _malloc (strlen (Value) + 1);\r
302 if (NewSymbol->Value == NULL) {\r
303 Error (NULL, 0, 0, NULL, "memory allocation failure");\r
304 _free (NewSymbol->Name);\r
305 _free (NewSymbol);\r
306 return -1;\r
307 }\r
308\r
309 strcpy (NewSymbol->Name, Name);\r
310 strcpy (NewSymbol->Value, Value);\r
311 //\r
312 // Remove trailing spaces\r
313 //\r
314 Cptr = NewSymbol->Value + strlen (NewSymbol->Value) - 1;\r
315 while (Cptr > NewSymbol->Value) {\r
316 if (isspace (*Cptr)) {\r
317 *Cptr = 0;\r
318 Cptr--;\r
319 } else {\r
320 break;\r
321 }\r
322 }\r
323 //\r
324 // Add it to the head of the list.\r
325 //\r
326 NewSymbol->Next = mSymbolTable;\r
327 mSymbolTable = NewSymbol;\r
328 //\r
329 // If value == "NULL", then make it a 0-length string\r
330 //\r
331 if (stricmp (NewSymbol->Value, "NULL") == 0) {\r
332 NewSymbol->Value[0] = 0;\r
333 }\r
334 //\r
335 // Restore the terminator we inserted if they passed in var=value\r
336 //\r
337 if (SaveCptr != NULL) {\r
338 *SaveCptr = CSave;\r
339 }\r
340 _free (NewSymbol->Value);\r
341 _free (NewSymbol->Name);\r
342 _free (NewSymbol);\r
343 return Len;\r
344}\r
345\r
346static\r
347STATUS\r
348RemoveSymbol (\r
349 char *Name,\r
350 char SymbolType\r
351 )\r
352/*++\r
353\r
354Routine Description:\r
355 \r
356 Remove a symbol name/value from the symbol table\r
357\r
358Arguments:\r
359\r
360 Name - name of symbol to remove\r
361 SymbolType - type of symbol to remove\r
362\r
363Returns:\r
364\r
365 STATUS_SUCCESS - matching symbol found and removed\r
366 STATUS_ERROR - matching symbol not found in symbol table\r
367\r
368--*/\r
369{\r
370 SYMBOL *Symbol;\r
371\r
372 SYMBOL *PrevSymbol;\r
373\r
374 PrevSymbol = NULL;\r
375 Symbol = mSymbolTable;\r
376 //\r
377 // Walk the linked list of symbols in the symbol table looking\r
378 // for a match of both symbol name and type.\r
379 //\r
380 while (Symbol) {\r
381 if ((stricmp (Name, Symbol->Name) == 0) && (Symbol->Type & SymbolType)) {\r
382 //\r
383 // If the symbol has a value associated with it, free the memory\r
384 // allocated for the value.\r
385 // Then free the memory allocated for the symbols string name.\r
386 //\r
387 if (Symbol->Value) {\r
388 _free (Symbol->Value);\r
389 }\r
390\r
391 _free (Symbol->Name);\r
392 //\r
393 // Link the previous symbol to the next symbol to effectively\r
394 // remove this symbol from the linked list.\r
395 //\r
396 if (PrevSymbol) {\r
397 PrevSymbol->Next = Symbol->Next;\r
398 } else {\r
399 mSymbolTable = Symbol->Next;\r
400 }\r
401\r
402 _free (Symbol);\r
403 return STATUS_SUCCESS;\r
404 }\r
405\r
406 PrevSymbol = Symbol;\r
407 Symbol = Symbol->Next;\r
408 }\r
409\r
410 return STATUS_WARNING;\r
411}\r
412\r
413static\r
414SYMBOL *\r
415FreeSymbols (\r
416 SYMBOL *Syms\r
417 )\r
418/*++\r
419\r
420Routine Description:\r
421\r
422 GC_TODO: Add function description\r
423\r
424Arguments:\r
425\r
426 Syms - GC_TODO: add argument description\r
427\r
428Returns:\r
429\r
430 GC_TODO: add return values\r
431\r
432--*/\r
433{\r
434 SYMBOL *Next;\r
435 while (Syms) {\r
436 if (Syms->Name != NULL) {\r
437 _free (Syms->Name);\r
438 }\r
439\r
440 if (Syms->Value != NULL) {\r
441 _free (Syms->Value);\r
442 }\r
443\r
444 Next = Syms->Next;\r
445 _free (Syms);\r
446 Syms = Next;\r
447 }\r
448\r
449 return Syms;\r
450}\r
451\r
452static\r
453int\r
454ExpandMacros (\r
455 char *SourceLine,\r
456 char *DestLine,\r
457 int LineLen\r
458 )\r
459/*++\r
460\r
461Routine Description:\r
462 \r
463 Given a line of text, replace all variables of format $(NAME) with values\r
464 from our symbol table.\r
465\r
466Arguments:\r
467\r
468 SourceLine - input line of text to do symbol replacements on\r
469 DestLine - on output, SourceLine with symbols replaced\r
470 LineLen - length of DestLine, so we don't exceed its allocated length\r
471\r
472Returns:\r
473\r
474 STATUS_SUCCESS - no problems encountered\r
475 STATUS_WARNING - missing closing parenthesis on a symbol reference in SourceLine\r
476 STATUS_ERROR - memory allocation failure\r
477\r
478--*/\r
479{\r
480 static int NestDepth = 0;\r
481 char *FromPtr;\r
482 char *ToPtr;\r
483 char *SaveStart;\r
484 char *Cptr;\r
485 char *value;\r
486 int Expanded;\r
487 int ExpandedCount;\r
488 INT8 *LocalDestLine;\r
489 STATUS Status;\r
490 int LocalLineLen;\r
491\r
492 NestDepth++;\r
493 Status = STATUS_SUCCESS;\r
494 LocalDestLine = (char *) _malloc (LineLen);\r
495 if (LocalDestLine == NULL) {\r
496 Error (__FILE__, __LINE__, 0, "memory allocation failed", NULL);\r
497 return STATUS_ERROR;\r
498 }\r
499\r
500 FromPtr = SourceLine;\r
501 ToPtr = LocalDestLine;\r
502 //\r
503 // Walk the entire line, replacing $(MACRO_NAME).\r
504 //\r
505 LocalLineLen = LineLen;\r
506 ExpandedCount = 0;\r
507 while (*FromPtr && (LocalLineLen > 0)) {\r
508 if ((*FromPtr == '$') && (*(FromPtr + 1) == '(')) {\r
509 //\r
510 // Save the start in case it's undefined, in which case we copy it as-is.\r
511 //\r
512 SaveStart = FromPtr;\r
513 Expanded = 0;\r
514 //\r
515 // Macro expansion time. Find the end (no spaces allowed)\r
516 //\r
517 FromPtr += 2;\r
518 for (Cptr = FromPtr; *Cptr && (*Cptr != ')'); Cptr++)\r
519 ;\r
520 if (*Cptr) {\r
521 //\r
522 // Truncate the string at the closing parenthesis for ease-of-use.\r
523 // Then copy the string directly to the destination line in case we don't find\r
524 // a definition for it.\r
525 //\r
526 *Cptr = 0;\r
527 strcpy (ToPtr, SaveStart);\r
528 if ((value = GetSymbolValue (FromPtr)) != NULL) {\r
529 strcpy (ToPtr, value);\r
530 LocalLineLen -= strlen (value);\r
531 ToPtr += strlen (value);\r
532 Expanded = 1;\r
533 ExpandedCount++;\r
534 }\r
535\r
536 if (!Expanded) {\r
537 //\r
538 // Restore closing parenthesis, and advance to next character\r
539 //\r
540 *Cptr = ')';\r
541 FromPtr = SaveStart + 1;\r
542 ToPtr++;\r
543 } else {\r
544 FromPtr = Cptr + 1;\r
545 }\r
546 } else {\r
547 Error (NULL, 0, 0, SourceLine, "missing closing parenthesis on macro");\r
548 strcpy (ToPtr, FromPtr);\r
549 Status = STATUS_WARNING;\r
550 goto Done;\r
551 }\r
552 } else {\r
553 *ToPtr = *FromPtr;\r
554 FromPtr++;\r
555 ToPtr++;\r
556 LocalLineLen--;\r
557 }\r
558 }\r
559\r
560 if (*FromPtr == 0) {\r
561 *ToPtr = 0;\r
562 }\r
563\r
564 //\r
565 // If we expanded at least one string successfully, then make a recursive call to try again.\r
566 //\r
567 if ((ExpandedCount != 0) && (Status == STATUS_SUCCESS) && (NestDepth < 10)) {\r
568 Status = ExpandMacros (LocalDestLine, DestLine, LineLen);\r
569 _free (LocalDestLine);\r
570 NestDepth = 0;\r
571 return Status;\r
572 }\r
573\r
574Done:\r
575 if (Status != STATUS_ERROR) {\r
576 strcpy (DestLine, LocalDestLine);\r
577 }\r
578\r
579 NestDepth = 0;\r
580 _free (LocalDestLine);\r
581 return Status;\r
582}\r
583\r
584STATUS\r
585SymbolsFileStringsReplace (\r
586 char *InFileName,\r
587 char *OutFileName\r
588 )\r
589/*++\r
590\r
591Routine Description:\r
592 \r
593 Given input and output file names, read in the input file, replace variable\r
594 references of format $(NAME) with appropriate values from our symbol table,\r
595 and write the result out to the output file.\r
596\r
597Arguments:\r
598\r
599 InFileName - name of input text file to replace variable references\r
600 OutFileName - name of output text file to write results to\r
601\r
602Returns:\r
603\r
604 STATUS_SUCCESS - no problems encountered\r
605 STATUS_ERROR - failed to open input or output file\r
606\r
607--*/\r
608{\r
609 STATUS Status;\r
610 FILE *InFptr;\r
611 FILE *OutFptr;\r
612 char Line[MAX_LINE_LEN];\r
613 char OutLine[MAX_LINE_LEN];\r
614\r
615 Status = STATUS_ERROR;\r
616 //\r
617 // Open input and output files\r
618 //\r
619 InFptr = NULL;\r
620 OutFptr = NULL;\r
621 if ((InFptr = fopen (InFileName, "r")) == NULL) {\r
622 Error (NULL, 0, 0, InFileName, "failed to open input file for reading");\r
623 goto Done;\r
624 }\r
625\r
626 if ((OutFptr = fopen (OutFileName, "w")) == NULL) {\r
627 Error (NULL, 0, 0, OutFileName, "failed to open output file for writing");\r
628 goto Done;\r
629 }\r
630 //\r
631 // Read lines from input file until done\r
632 //\r
633 while (fgets (Line, sizeof (Line), InFptr) != NULL) {\r
634 ExpandMacros (Line, OutLine, sizeof (OutLine));\r
635 fprintf (OutFptr, OutLine);\r
636 }\r
637\r
638 Status = STATUS_SUCCESS;\r
639Done:\r
640 if (InFptr != NULL) {\r
641 fclose (InFptr);\r
642 }\r
643\r
644 if (OutFptr != NULL) {\r
645 fclose (OutFptr);\r
646 }\r
647\r
648 return Status;\r
649}\r