+\r
+static\r
+void\r
+AddMacro (\r
+ UINT8 *MacroString\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Add or override a macro definition.\r
+\r
+Arguments:\r
+\r
+ MacroString - macro definition string: name=value\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/ \r
+{\r
+ MACRO *Macro;\r
+ MACRO *NewMacro;\r
+ UINT8 *Value;\r
+ \r
+ //\r
+ // Seperate macro name and value by '\0'\r
+ //\r
+ for (Value = MacroString; *Value && (*Value != '='); Value++);\r
+ \r
+ if (*Value == '=') {\r
+ *Value = '\0';\r
+ Value ++;\r
+ }\r
+ \r
+ //\r
+ // We now have a macro name and value. \r
+ // Look for an existing macro and overwrite it.\r
+ //\r
+ Macro = mGlobals.MacroList;\r
+ while (Macro) {\r
+ if (_strcmpi (MacroString, Macro->Name) == 0) {\r
+ Macro->Value = Value;\r
+ return;\r
+ }\r
+\r
+ Macro = Macro->Next;\r
+ }\r
+ \r
+ //\r
+ // Does not exist, create a new one\r
+ //\r
+ NewMacro = (MACRO *) malloc (sizeof (MACRO));\r
+ memset ((UINT8 *) NewMacro, 0, sizeof (MACRO));\r
+ NewMacro->Name = MacroString;\r
+ NewMacro->Value = Value;\r
+\r
+ //\r
+ // Add it to the head of the list.\r
+ //\r
+ NewMacro->Next = mGlobals.MacroList;\r
+ mGlobals.MacroList = NewMacro;\r
+ \r
+ return;\r
+}\r
+\r
+static\r
+UINT8 *\r
+GetMacroValue (\r
+ UINT8 *MacroName\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Look up a macro.\r
+\r
+Arguments:\r
+\r
+ MacroName - The name of macro\r
+\r
+Returns:\r
+\r
+ Pointer to the value of the macro if found\r
+ NULL if the macro is not found\r
+\r
+--*/ \r
+{\r
+\r
+ MACRO *Macro;\r
+ UINT8 *Value;\r
+\r
+ //\r
+ // Scan for macro\r
+ //\r
+ Macro = mGlobals.MacroList;\r
+ while (Macro) {\r
+ if (_strcmpi (MacroName, Macro->Name) == 0) {\r
+ return Macro->Value;\r
+ }\r
+ Macro = Macro->Next;\r
+ }\r
+ \r
+ //\r
+ // Try environment variable\r
+ //\r
+ Value = getenv (MacroName);\r
+ if (Value == NULL) {\r
+ printf ("Environment variable %s not found!\n", MacroName);\r
+ } \r
+ return Value;\r
+}\r
+ \r
+static\r
+void\r
+FreeMacros (\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Free the macro list.\r
+\r
+Arguments:\r
+\r
+ None\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/ \r
+{\r
+ MACRO *Macro;\r
+ MACRO *NextMacro;\r
+ \r
+ Macro = mGlobals.MacroList;\r
+ while (Macro) {\r
+ NextMacro = Macro->Next;\r
+ free (Macro);\r
+ Macro = NextMacro;\r
+ }\r
+ mGlobals.MacroList = NULL;\r
+ \r
+ return;\r
+}\r
+\r
+static\r
+STATUS\r
+ReplaceMacros (\r
+ UINT8 *InputFile,\r
+ UINT8 *OutputFile\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Replace all the macros in InputFile to create the OutputFile.\r
+\r
+Arguments:\r
+\r
+ InputFile - Input package file for macro replacement\r
+ OutputFile - Output package file after macro replacement\r
+\r
+Returns:\r
+\r
+ STATUS_SUCCESS - Output package file is created successfully after the macro replacement.\r
+ STATUS_WARNING - Output package file is not created because of no macro replacement.\r
+ STATUS_ERROR - Some error occurred during execution.\r
+\r
+--*/ \r
+{\r
+ FILE *Fptr;\r
+ UINT8 *SaveStart;\r
+ UINT8 *FromPtr;\r
+ UINT8 *ToPtr;\r
+ UINT8 *Value;\r
+ UINT8 *FileBuffer;\r
+ UINTN FileSize;\r
+ \r
+ //\r
+ // Get the file size, and then read the entire thing into memory.\r
+ // Allocate extra space for a terminator character.\r
+ //\r
+ if ((Fptr = fopen (InputFile, "r")) == NULL) {\r
+ Error (NULL, 0, 0, InputFile, "can't open input file");\r
+ return STATUS_ERROR; \r
+ }\r
+ fseek (Fptr, 0, SEEK_END);\r
+ FileSize = ftell (Fptr);\r
+ fseek (Fptr, 0, SEEK_SET);\r
+ FileBuffer = malloc (FileSize + 1);\r
+ if (FileBuffer == NULL) {\r
+ fclose (Fptr);\r
+ Error (NULL, 0, 0, InputFile, "file buffer memory allocation failure");\r
+ return STATUS_ERROR;\r
+ }\r
+ fread (FileBuffer, FileSize, 1, Fptr);\r
+ FileBuffer[FileSize] = '\0';\r
+ fclose (Fptr);\r
+ \r
+ //\r
+ // Walk the entire file, replacing $(MACRO_NAME).\r
+ //\r
+ Fptr = NULL;\r
+ FromPtr = FileBuffer;\r
+ SaveStart = FromPtr;\r
+ while (*FromPtr) {\r
+ if ((*FromPtr == '$') && (*(FromPtr + 1) == '(')) {\r
+ FromPtr += 2;\r
+ for (ToPtr = FromPtr; *ToPtr && (*ToPtr != ')'); ToPtr++);\r
+ if (*ToPtr) {\r
+ //\r
+ // Find an $(MACRO_NAME), replace it\r
+ //\r
+ *ToPtr = '\0';\r
+ Value = GetMacroValue (FromPtr);\r
+ *(FromPtr-2)= '\0';\r
+ if (Fptr == NULL) {\r
+ if ((Fptr = fopen (OutputFile, "w")) == NULL) {\r
+ free (FileBuffer);\r
+ Error (NULL, 0, 0, OutputFile, "can't open output file");\r
+ return STATUS_ERROR; \r
+ }\r
+ }\r
+ if (Value != NULL) {\r
+ fprintf (Fptr, "%s%s", SaveStart, Value);\r
+ } else {\r
+ fprintf (Fptr, "%s", SaveStart);\r
+ }\r
+ //\r
+ // Continue macro replacement for the remaining string line\r
+ //\r
+ FromPtr = ToPtr+1;\r
+ SaveStart = FromPtr;\r
+ continue;\r
+ } else {\r
+ break;\r
+ }\r
+ } else {\r
+ FromPtr++;\r
+ }\r
+ }\r
+ if (Fptr != NULL) {\r
+ fprintf (Fptr, "%s", SaveStart);\r
+ }\r
+ \r
+ free (FileBuffer);\r
+ if (Fptr != NULL) {\r
+ fclose (Fptr);\r
+ return STATUS_SUCCESS;\r
+ } else {\r
+ return STATUS_WARNING;\r
+ }\r
+}\r