From b09da165c00a17a435da6d41aef8ca24e84025e4 Mon Sep 17 00:00:00 2001 From: bbahnsen Date: Mon, 15 May 2006 17:25:39 +0000 Subject: [PATCH] Add MakeDeps git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@161 6f19259b-4bc3-4df7-8a09-765794883524 --- Tools/Source/TianoTools/MakeDeps/MakeDeps.c | 1285 +++++++++++++++++++ Tools/Source/TianoTools/MakeDeps/build.xml | 117 ++ 2 files changed, 1402 insertions(+) create mode 100755 Tools/Source/TianoTools/MakeDeps/MakeDeps.c create mode 100755 Tools/Source/TianoTools/MakeDeps/build.xml diff --git a/Tools/Source/TianoTools/MakeDeps/MakeDeps.c b/Tools/Source/TianoTools/MakeDeps/MakeDeps.c new file mode 100755 index 0000000000..a459348079 --- /dev/null +++ b/Tools/Source/TianoTools/MakeDeps/MakeDeps.c @@ -0,0 +1,1285 @@ +/*++ + +Copyright (c) 2004, 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: + + MakeDeps.c + +Abstract: + + Recursively scan source files to find include files and emit them to + create dependency lists. + +--*/ + +#include +#include +#include +#include + +#include +#include +#include "EfiUtilityMsgs.h" + +// +// Structure to maintain a linked list of strings +// +typedef struct _STRING_LIST { + struct _STRING_LIST *Next; + char *Str; +} STRING_LIST; + +#define UTILITY_NAME "MakeDeps" + +#define MAX_LINE_LEN 2048 +#define MAX_PATH 2048 +#define START_NEST_DEPTH 1 +#define MAX_NEST_DEPTH 1000 // just in case we get in an endless loop. +// +// Define the relative paths used by the special #include macros +// +#define PROTOCOL_DIR_PATH "Protocol\\" +#define GUID_DIR_PATH "Guid\\" +#define ARCH_PROTOCOL_DIR_PATH "ArchProtocol\\" +#define PPI_PROTOCOL_DIR_PATH "Ppi\\" + +// +// Use this structure to keep track of all the special #include forms +// +typedef struct { + INT8 *IncludeMacroName; + INT8 *PathName; +} INCLUDE_MACRO_CONVERSION; + +// +// This data is used to convert #include macros like: +// #include EFI_PROTOCOL_DEFINITION(xxx) +// into +// #include Protocol/xxx/xxx.h +// +static const INCLUDE_MACRO_CONVERSION mMacroConversion[] = { + "EFI_PROTOCOL_DEFINITION", + PROTOCOL_DIR_PATH, + "EFI_GUID_DEFINITION", + GUID_DIR_PATH, + "EFI_ARCH_PROTOCOL_DEFINITION", + ARCH_PROTOCOL_DIR_PATH, + "EFI_PROTOCOL_PRODUCER", + PROTOCOL_DIR_PATH, + "EFI_PROTOCOL_CONSUMER", + PROTOCOL_DIR_PATH, + "EFI_PROTOCOL_DEPENDENCY", + PROTOCOL_DIR_PATH, + "EFI_ARCH_PROTOCOL_PRODUCER", + ARCH_PROTOCOL_DIR_PATH, + "EFI_ARCH_PROTOCOL_CONSUMER", + ARCH_PROTOCOL_DIR_PATH, + "EFI_ARCH_PROTOCOL_DEPENDENCY", + ARCH_PROTOCOL_DIR_PATH, + "EFI_PPI_DEFINITION", + PPI_PROTOCOL_DIR_PATH, + "EFI_PPI_PRODUCER", + PPI_PROTOCOL_DIR_PATH, + "EFI_PPI_CONSUMER", + PPI_PROTOCOL_DIR_PATH, + "EFI_PPI_DEPENDENCY", + PPI_PROTOCOL_DIR_PATH, + NULL, + NULL +}; + +typedef struct _SYMBOL { + struct _SYMBOL *Next; + INT8 *Name; + INT8 *Value; +} SYMBOL; + +// +// Here's all our globals. We need a linked list of include paths, a linked +// list of source files, a linked list of subdirectories (appended to each +// include path when searching), and flags to keep track of command-line options. +// +static struct { + STRING_LIST *IncludePaths; // all include paths to search + STRING_LIST *SourceFiles; // all source files to parse + STRING_LIST *SubDirs; // appended to each include path when searching + SYMBOL *SymbolTable; // for replacement strings + FILE *OutFptr; // output dependencies to this file + BOOLEAN Verbose; // for more detailed output + BOOLEAN IgnoreNotFound; // no warnings if files not found + BOOLEAN QuietMode; // -q - don't print missing file warnings + BOOLEAN NoSystem; // don't process #include files + BOOLEAN NeverFail; // always return success + BOOLEAN NoDupes; // to not list duplicate dependency files (for timing purposes) + BOOLEAN UseSumDeps; // use summary dependency files if found + INT8 TargetFileName[MAX_PATH]; // target object filename + INT8 SumDepsPath[MAX_PATH]; // path to summary files + INT8 *OutFileName; // -o option +} mGlobals; + +static +STATUS +ProcessFile ( + INT8 *TargetFileName, + INT8 *FileName, + UINT32 NestDepth, + STRING_LIST *ProcessedFiles + ); + +static +FILE * +FindFile ( + INT8 *FileName, + UINT32 FileNameLen + ); + +static +void +PrintDependency ( + INT8 *Target, + INT8 *DependentFile + ); + +static +void +ReplaceSymbols ( + INT8 *Str, + UINT32 StrSize + ); + +static +STATUS +ProcessArgs ( + int Argc, + char *Argv[] + ); + +static +void +Usage ( + VOID + ); + +static +void +FreeLists ( + VOID + ); + +int +main ( + int Argc, + char *Argv[] + ) +/*++ + +Routine Description: + + Call the routine to parse the command-line options, then process each file + to build dependencies. + +Arguments: + + Argc - Standard C main() argc. + Argv - Standard C main() argv. + +Returns: + + 0 if successful + nonzero otherwise + +--*/ +{ + STRING_LIST *File; + STRING_LIST ProcessedFiles; + STRING_LIST *TempList; + STATUS Status; + INT8 *Cptr; + INT8 TargetFileName[MAX_PATH]; + + SetUtilityName (UTILITY_NAME); + // + // Process the command-line arguments + // + Status = ProcessArgs (Argc, Argv); + if (Status != STATUS_SUCCESS) { + return STATUS_ERROR; + } + // + // Go through the list of source files and process each. + // + memset (&ProcessedFiles, 0, sizeof (STRING_LIST)); + File = mGlobals.SourceFiles; + while (File != NULL) { + // + // Clear out our list of processed files + // + TempList = ProcessedFiles.Next; + while (ProcessedFiles.Next != NULL) { + TempList = ProcessedFiles.Next->Next; + free (ProcessedFiles.Next->Str); + free (ProcessedFiles.Next); + ProcessedFiles.Next = TempList; + } + // + // Replace filename extension with ".obj" if they did not + // specifically specify the target file + // + if (mGlobals.TargetFileName[0] == 0) { + strcpy (TargetFileName, File->Str); + // + // Find the .extension + // + for (Cptr = TargetFileName + strlen (TargetFileName) - 1; + (*Cptr != '\\') && (Cptr > TargetFileName) && (*Cptr != '.'); + Cptr-- + ) + ; + if (Cptr == TargetFileName) { + Error (NULL, 0, 0, File->Str, "could not locate extension in filename"); + goto Finish; + } + // + // Tack on the ".obj" + // + strcpy (Cptr, ".obj"); + } else { + // + // Copy the target filename they specified + // + strcpy (TargetFileName, mGlobals.TargetFileName); + } + + Status = ProcessFile (TargetFileName, File->Str, START_NEST_DEPTH, &ProcessedFiles); + if (Status != STATUS_SUCCESS) { + goto Finish; + } + + File = File->Next; + } + +Finish: + // + // Free up memory + // + FreeLists (); + // + // Free up our processed files list + // + TempList = ProcessedFiles.Next; + while (ProcessedFiles.Next != NULL) { + TempList = ProcessedFiles.Next->Next; + free (ProcessedFiles.Next->Str); + free (ProcessedFiles.Next); + ProcessedFiles.Next = TempList; + } + // + // Close our output file + // + if ((mGlobals.OutFptr != stdout) && (mGlobals.OutFptr != NULL)) { + fclose (mGlobals.OutFptr); + } + + if (mGlobals.NeverFail) { + return STATUS_SUCCESS; + } + // + // If any errors, then delete our output so that it will get created + // again on a rebuild. + // + if ((GetUtilityStatus () == STATUS_ERROR) && (mGlobals.OutFileName != NULL)) { + remove (mGlobals.OutFileName); + } + + return GetUtilityStatus (); +} + +static +STATUS +ProcessFile ( + INT8 *TargetFileName, + INT8 *FileName, + UINT32 NestDepth, + STRING_LIST *ProcessedFiles + ) +/*++ + +Routine Description: + + Given a source file name, open the file and parse all #include lines. + +Arguments: + + TargetFileName - name of the usually .obj target + FileName - name of the file to process + NestDepth - how deep we're nested in includes + ProcessedFiles - list of processed files. + +Returns: + + standard status. + +--*/ +{ + FILE *Fptr; + INT8 Line[MAX_LINE_LEN]; + INT8 *Cptr; + INT8 *EndPtr; + INT8 *SaveCptr; + INT8 EndChar; + INT8 FileNameCopy[MAX_PATH]; + INT8 MacroIncludeFileName[MAX_LINE_LEN]; + INT8 SumDepsFile[MAX_PATH]; + STATUS Status; + UINT32 Index; + UINT32 LineNum; + STRING_LIST *ListPtr; + + Status = STATUS_SUCCESS; + Fptr = NULL; + // + // Print the file being processed. Indent so you can tell the include nesting + // depth. + // + if (mGlobals.Verbose) { + fprintf (stdout, "%*cProcessing file '%s'\n", NestDepth * 2, ' ', FileName); + } + // + // If we're using summary dependency files, and a matching .dep file is + // found for this file, then just emit the summary dependency file as + // a dependency and return. + // + if (mGlobals.UseSumDeps) { + strcpy (SumDepsFile, mGlobals.SumDepsPath); + strcat (SumDepsFile, FileName); + for (Cptr = SumDepsFile + strlen (SumDepsFile) - 1; + (*Cptr != '\\') && (Cptr > SumDepsFile) && (*Cptr != '.'); + Cptr-- + ) + ; + if (*Cptr == '.') { + strcpy (Cptr, ".dep"); + } else { + strcat (SumDepsFile, ".dep"); + } + // + // See if the summary dep file exists. Could use _stat() function, but + // it's less portable. + // + if ((Fptr = fopen (SumDepsFile, "r")) != NULL) { + PrintDependency (TargetFileName, SumDepsFile); + return STATUS_SUCCESS; + } + } + // + // If we're not doing duplicates, and we've already seen this filename, + // then return + // + if (mGlobals.NoDupes) { + for (ListPtr = ProcessedFiles->Next; ListPtr != NULL; ListPtr = ListPtr->Next) { + if (stricmp (FileName, ListPtr->Str) == 0) { + break; + } + } + // + // If we found a match, we're done. If we didn't, create a new element + // and add it to the list. + // + if (ListPtr != NULL) { + // + // Print a message if verbose mode + // + if (mGlobals.Verbose) { + DebugMsg (NULL, 0, 0, FileName, "duplicate include -- not processed again"); + } + + return STATUS_SUCCESS; + } + + ListPtr = malloc (sizeof (STRING_LIST)); + ListPtr->Str = malloc (strlen (FileName) + 1); + strcpy (ListPtr->Str, FileName); + ListPtr->Next = ProcessedFiles->Next; + ProcessedFiles->Next = ListPtr; + } + + // + // Make sure we didn't exceed our maximum nesting depth + // + if (NestDepth > MAX_NEST_DEPTH) { + Error (NULL, 0, 0, FileName, "max nesting depth exceeded on file"); + goto Finish; + } + // + // Make a local copy of the filename. Then we can manipulate it + // if we have to. + // + strcpy (FileNameCopy, FileName); + // + // Try to open the file locally + // + if ((Fptr = fopen (FileNameCopy, "r")) == NULL) { + // + // Try to find it among the paths. + // + Fptr = FindFile (FileNameCopy, sizeof (FileNameCopy)); + if (Fptr == NULL) { + // + // If this is not the top-level file, and the command-line argument + // said to ignore missing files, then return ok + // + if (NestDepth != START_NEST_DEPTH) { + if (mGlobals.IgnoreNotFound) { + if (!mGlobals.QuietMode) { + DebugMsg (NULL, 0, 0, FileNameCopy, "could not find file"); + } + + return STATUS_SUCCESS; + } else { + Error (NULL, 0, 0, FileNameCopy, "could not find file"); + return STATUS_ERROR; + } + } else { + // + // Top-level (first) file. Emit an error. + // + Error (NULL, 0, 0, FileNameCopy, "could not find file"); + return STATUS_ERROR; + } + } + } + // + // Print the dependency, with string substitution + // + PrintDependency (TargetFileName, FileNameCopy); + + // + // Now read in lines and find all #include lines. Allow them to indent, and + // to put spaces between the # and include. + // + LineNum = 0; + while ((fgets (Line, sizeof (Line), Fptr) != NULL) && (Status == STATUS_SUCCESS)) { + LineNum++; + Cptr = Line; + // + // Skip preceeding spaces on the line + // + while (*Cptr && (isspace (*Cptr))) { + Cptr++; + } + // + // Check for # character + // + if (*Cptr == '#') { + Cptr++; + // + // Check for "include" + // + while (*Cptr && (isspace (*Cptr))) { + Cptr++; + } + + if (strncmp (Cptr, "include", 7) == 0) { + // + // Skip over "include" and move on to filename as "file" or + // + Cptr += 7; + while (*Cptr && (isspace (*Cptr))) { + Cptr++; + } + + if (*Cptr == '<') { + EndChar = '>'; + } else if (*Cptr == '"') { + EndChar = '"'; + } else { + // + // Handle special #include MACRO_NAME(file) + // Set EndChar to null so we fall through on processing below. + // + EndChar = 0; + // + // Look for all the special include macros and convert accordingly. + // + for (Index = 0; mMacroConversion[Index].IncludeMacroName != NULL; Index++) { + // + // Save the start of the string in case some macros are substrings + // of others. + // + SaveCptr = Cptr; + if (strncmp ( + Cptr, + mMacroConversion[Index].IncludeMacroName, + strlen (mMacroConversion[Index].IncludeMacroName) + ) == 0) { + // + // Skip over the macro name + // + Cptr += strlen (mMacroConversion[Index].IncludeMacroName); + // + // Skip over open parenthesis, blank spaces, then find closing + // parenthesis or blank space + // + while (*Cptr && (isspace (*Cptr))) { + Cptr++; + } + + if (*Cptr == '(') { + Cptr++; + while (*Cptr && (isspace (*Cptr))) { + Cptr++; + } + + EndPtr = Cptr; + while (*EndPtr && !isspace (*EndPtr) && (*EndPtr != ')')) { + EndPtr++; + } + + *EndPtr = 0; + // + // Create the path + // + strcpy (MacroIncludeFileName, mMacroConversion[Index].PathName); + strcat (MacroIncludeFileName, Cptr); + strcat (MacroIncludeFileName, "\\"); + strcat (MacroIncludeFileName, Cptr); + strcat (MacroIncludeFileName, ".h"); + // + // Process immediately, then break out of the outside FOR loop. + // + Status = ProcessFile (TargetFileName, MacroIncludeFileName, NestDepth + 1, ProcessedFiles); + break; + } + } + // + // Restore the start + // + Cptr = SaveCptr; + } + // + // Don't recognize the include line? Ignore it. We assume that the + // file compiles anyway. + // + if (mMacroConversion[Index].IncludeMacroName == NULL) { + // + // Warning (FileNameCopy, LineNum, 0, "could not parse line", NULL); + // Status = STATUS_WARNING; + // + } + } + // + // Process "normal" includes. If the endchar is 0, then the + // file has already been processed. Otherwise look for the + // endchar > or ", and process the include file. + // + if (EndChar != 0) { + Cptr++; + EndPtr = Cptr; + while (*EndPtr && (*EndPtr != EndChar)) { + EndPtr++; + } + + if (*EndPtr == EndChar) { + // + // If we're processing it, do it + // + if ((EndChar != '>') || (!mGlobals.NoSystem)) { + // + // Null terminate the filename and try to process it. + // + *EndPtr = 0; + Status = ProcessFile (TargetFileName, Cptr, NestDepth + 1, ProcessedFiles); + } + } else { + Warning (FileNameCopy, LineNum, 0, "malformed include", "missing closing %c", EndChar); + Status = STATUS_WARNING; + goto Finish; + } + } + } + } + } + +Finish: + // + // Close open files and return status + // + if (Fptr != NULL) { + fclose (Fptr); + } + + return Status; +} + +static +void +PrintDependency ( + INT8 *TargetFileName, + INT8 *DependentFile + ) +/*++ + +Routine Description: + + Given a target (.obj) file name, and a dependent file name, do any string + substitutions (per the command line options) on the file names, then + print the dependency line of form: + + TargetFileName : DependentFile + +Arguments: + + TargetFileName - build target file name + DependentFile - file on which TargetFileName depends + +Returns: + + None + +--*/ +{ + INT8 Str[MAX_PATH]; + + // + // Go through the symbols and do replacements + // + strcpy (Str, TargetFileName); + ReplaceSymbols (Str, sizeof (Str)); + fprintf (mGlobals.OutFptr, "%s : ", Str); + strcpy (Str, DependentFile); + ReplaceSymbols (Str, sizeof (Str)); + fprintf (mGlobals.OutFptr, "%s\n", Str); +} + +static +void +ReplaceSymbols ( + INT8 *Str, + UINT32 StrSize + ) +{ + SYMBOL *Sym; + INT8 StrCopy[MAX_LINE_LEN]; + INT8 *From; + INT8 *To; + BOOLEAN Replaced; + + // + // Go through the entire string to look for replacement strings at + // every position. + // + From = Str; + To = StrCopy; + while (*From) { + // + // Copy the character + // + *To = *From; + Replaced = FALSE; + // + // Go through each symbol and try to find a string substitution + // + Sym = mGlobals.SymbolTable; + while (Sym != NULL) { + if (strnicmp (From, Sym->Value, strlen (Sym->Value)) == 0) { + // + // Replace the string, then advance the pointers past the + // replaced strings + // + strcpy (To, Sym->Name); + To += strlen (Sym->Name); + From += strlen (Sym->Value); + Replaced = TRUE; + // + // Break from the while() + // + break; + } else { + Sym = Sym->Next; + } + } + + if (!Replaced) { + From++; + To++; + } + } + // + // Null terminate, and return it + // + *To = 0; + if (strlen (StrCopy) < StrSize) { + strcpy (Str, StrCopy); + } +} +// +// Given a filename, try to find it along the include paths. +// +static +FILE * +FindFile ( + INT8 *FileName, + UINT32 FileNameLen + ) +{ + FILE *Fptr; + STRING_LIST *List; + STRING_LIST *SubDir; + INT8 FullFileName[MAX_PATH * 2]; + + // + // Traverse the list of paths and try to find the file + // + List = mGlobals.IncludePaths; + while (List != NULL) { + // + // Put the path and filename together + // + if (strlen (List->Str) + strlen (FileName) + 1 > sizeof (FullFileName)) { + Error ( + __FILE__, + __LINE__, + 0, + "application error", + "cannot concatenate '%s' + '%s'", + List->Str, + FileName + ); + return NULL; + } + // + // Append the filename to this include path and try to open the file. + // + strcpy (FullFileName, List->Str); + strcat (FullFileName, FileName); + if ((Fptr = fopen (FullFileName, "r")) != NULL) { + // + // Return the file name + // + if (FileNameLen <= strlen (FullFileName)) { + Error (__FILE__, __LINE__, 0, "application error", "internal path name of insufficient length"); + // + // fprintf (stdout, "File length > %d: %s\n", FileNameLen, FullFileName); + // + return NULL; + } + + strcpy (FileName, FullFileName); + return Fptr; + } + // + // Didn't find it there. Now try this directory with every subdirectory + // the user specified on the command line + // + for (SubDir = mGlobals.SubDirs; SubDir != NULL; SubDir = SubDir->Next) { + strcpy (FullFileName, List->Str); + strcat (FullFileName, SubDir->Str); + strcat (FullFileName, FileName); + if ((Fptr = fopen (FullFileName, "r")) != NULL) { + // + // Return the file name + // + if (FileNameLen <= strlen (FullFileName)) { + Error (__FILE__, __LINE__, 0, "application error", "internal path name of insufficient length"); + return NULL; + } + + strcpy (FileName, FullFileName); + return Fptr; + } + } + + List = List->Next; + } + // + // Not found + // + return NULL; +} +// +// Process the command-line arguments +// +static +STATUS +ProcessArgs ( + int Argc, + char *Argv[] + ) +{ + STRING_LIST *NewList; + STRING_LIST *LastIncludePath; + STRING_LIST *LastSourceFile; + SYMBOL *Symbol; + int Index; + // + // Clear our globals + // + memset ((char *) &mGlobals, 0, sizeof (mGlobals)); + mGlobals.NoDupes = TRUE; + // + // Skip program name + // + Argc--; + Argv++; + // + // Initialize locals + // + LastIncludePath = NULL; + LastSourceFile = NULL; + // + // Process until no more args + // + while (Argc) { + // + // -i path add include search path + // + if (stricmp (Argv[0], "-i") == 0) { + // + // check for one more arg + // + if (Argc > 1) { + // + // Allocate memory for a new list element, fill it in, and + // add it to our list of include paths. Always make sure it + // has a "\" on the end of it. + // + NewList = malloc (sizeof (STRING_LIST)); + if (NewList == NULL) { + Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL); + return STATUS_ERROR; + } + + NewList->Next = NULL; + NewList->Str = malloc (strlen (Argv[1]) + 2); + if (NewList->Str == NULL) { + free (NewList); + Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL); + return STATUS_ERROR; + } + + strcpy (NewList->Str, Argv[1]); + if (NewList->Str[strlen (NewList->Str) - 1] != '\\') { + strcat (NewList->Str, "\\"); + } + // + // Add it to the end of the our list of include paths + // + if (mGlobals.IncludePaths == NULL) { + mGlobals.IncludePaths = NewList; + } else { + LastIncludePath->Next = NewList; + } + + LastIncludePath = NewList; + // + // fprintf (stdout, "Added path: %s\n", NewList->Str); + // + } else { + Error (NULL, 0, 0, Argv[0], "option requires an include path"); + Usage (); + return STATUS_ERROR; + } + + Argc--; + Argv++; + } else if (stricmp (Argv[0], "-f") == 0) { + // + // Check for one more arg + // + if (Argc > 1) { + // + // Allocate memory for a new list element, fill it in, and + // add it to our list of source files. + // + NewList = malloc (sizeof (STRING_LIST)); + if (NewList == NULL) { + Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL); + return STATUS_ERROR; + } + + NewList->Next = NULL; + // + // Allocate space to replace ".c" with ".obj", plus null termination + // + NewList->Str = malloc (strlen (Argv[1]) + 5); + if (NewList->Str == NULL) { + free (NewList); + Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL); + return STATUS_ERROR; + } + + strcpy (NewList->Str, Argv[1]); + if (mGlobals.SourceFiles == NULL) { + mGlobals.SourceFiles = NewList; + } else { + LastSourceFile->Next = NewList; + } + + LastSourceFile = NewList; + } else { + Error (NULL, 0, 0, Argv[0], "option requires a file name"); + Usage (); + return STATUS_ERROR; + } + // + // The C compiler first looks for #include files in the directory where + // the source file came from. Add the file's source directory to the + // list of include paths. + // + NewList = malloc (sizeof (STRING_LIST)); + if (NewList == NULL) { + Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL); + return STATUS_ERROR; + } + + NewList->Next = NULL; + NewList->Str = malloc (strlen (Argv[1]) + 3); + if (NewList->Str == NULL) { + free (NewList); + Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL); + return STATUS_ERROR; + } + + strcpy (NewList->Str, Argv[1]); + // + // Back up in the source file name to the last backslash and terminate after it. + // + for (Index = strlen (NewList->Str) - 1; (Index > 0) && (NewList->Str[Index] != '\\'); Index--) + ; + if (Index < 0) { + strcpy (NewList->Str, ".\\"); + } else { + NewList->Str[Index + 1] = 0; + } + // + // Add it to the end of the our list of include paths + // + if (mGlobals.IncludePaths == NULL) { + mGlobals.IncludePaths = NewList; + } else { + LastIncludePath->Next = NewList; + } + + if (mGlobals.Verbose) { + fprintf (stdout, "Adding include path: %s\n", NewList->Str); + } + + LastIncludePath = NewList; + Argc--; + Argv++; + } else if (stricmp (Argv[0], "-s") == 0) { + // + // -s subdir add subdirectory subdir to list of subdirecties to scan. + // Check for one more arg first. + // + if (Argc > 1) { + // + // Allocate memory for a new list element, fill it in, and + // add it to our list of subdirectory include paths. Always + // make sure it has a "\" on the end of it. + // + NewList = malloc (sizeof (STRING_LIST)); + if (NewList == NULL) { + Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL); + return STATUS_ERROR; + } + + NewList->Str = malloc (strlen (Argv[1]) + 2); + if (NewList->Str == NULL) { + free (NewList); + Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL); + return STATUS_ERROR; + } + + strcpy (NewList->Str, Argv[1]); + if (NewList->Str[strlen (NewList->Str) - 1] != '\\') { + strcat (NewList->Str, "\\"); + } + + NewList->Next = mGlobals.SubDirs; + mGlobals.SubDirs = NewList; + } else { + Error (NULL, 0, 0, Argv[0], "option requires a subdirectory name"); + Usage (); + return STATUS_ERROR; + } + + Argc--; + Argv++; + } else if (stricmp (Argv[0], "-sub") == 0) { + // + // -sub symname symvalue to do string substitution in the output + // + if (Argc > 2) { + // + // Allocate memory for the symbol object + // + Symbol = malloc (sizeof (SYMBOL)); + if (Symbol == NULL) { + Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL); + return STATUS_ERROR; + } + // + // Allocate memory for the symbol name and value, then save copies + // + Symbol->Name = malloc (strlen (Argv[1]) + 1); + if (Symbol->Name == NULL) { + free (Symbol); + Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL); + return STATUS_ERROR; + } + + strcpy (Symbol->Name, Argv[1]); + Symbol->Value = malloc (strlen (Argv[2]) + 1); + if (Symbol->Value == NULL) { + free (Symbol->Name); + free (Symbol); + Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL); + return STATUS_ERROR; + } + + strcpy (Symbol->Value, Argv[2]); + // + // Add it to the list + // + Symbol->Next = mGlobals.SymbolTable; + mGlobals.SymbolTable = Symbol; + } else { + Error (NULL, 0, 0, Argv[0], "option requires a symbol name and value"); + Usage (); + return STATUS_ERROR; + } + // + // Skip over args + // + Argc -= 2; + Argv += 2; + } else if (stricmp (Argv[0], "-nosystem") == 0) { + mGlobals.NoSystem = TRUE; + } else if (stricmp (Argv[0], "-nodupes") == 0) { + mGlobals.NoDupes = TRUE; + } else if (stricmp (Argv[0], "-nodups") == 0) { + mGlobals.NoDupes = TRUE; + } else if (stricmp (Argv[0], "-target") == 0) { + // + // -target TargetFileName - Target object file (only one allowed right + // now) is TargetFileName rather than SourceFile.obj + // + if (Argc > 1) { + strcpy (mGlobals.TargetFileName, Argv[1]); + } else { + Error (NULL, 0, 0, Argv[0], "option requires a target file name"); + Usage (); + return STATUS_ERROR; + } + + Argc--; + Argv++; + } else if (stricmp (Argv[0], "-usesumdeps") == 0) { + // + // -usesumdeps Path - if we find an included file xxx.h, and file + // Path/xxx.dep exists, list Path/xxx.dep as a dependency rather than + // xxx.h and don't parse xxx.h. This allows you to create a dependency + // file for a commonly included file, and have its dependency file updated + // only if its included files are updated. Then anyone else including this + // common include file can simply have a dependency on that file's .dep file + // rather than on all the files included by it. Confusing enough? + // + mGlobals.UseSumDeps = 1; + if (Argc > 1) { + strcpy (mGlobals.SumDepsPath, Argv[1]); + // + // Add slash on end if not there + // + if (mGlobals.SumDepsPath[strlen (mGlobals.SumDepsPath) - 1] != '\\') { + strcat (mGlobals.SumDepsPath, "\\"); + } + } else { + Error (NULL, 0, 0, Argv[0], "option requires path to summary dependency files"); + Usage (); + return STATUS_ERROR; + } + + Argc--; + Argv++; + + } else if (stricmp (Argv[0], "-o") == 0) { + // + // -o OutputFileName - specify an output filename for dependency list + // check for one more arg + // + if (Argc > 1) { + // + // Try to open the file + // + if ((mGlobals.OutFptr = fopen (Argv[1], "w")) == NULL) { + Error (NULL, 0, 0, Argv[1], "could not open file for writing"); + return STATUS_ERROR; + } + + mGlobals.OutFileName = Argv[1]; + } else { + Error (NULL, 0, 0, Argv[0], "option requires output file name"); + Usage (); + return STATUS_ERROR; + } + + Argc--; + Argv++; + } else if (stricmp (Argv[0], "-v") == 0) { + mGlobals.Verbose = TRUE; + } else if (stricmp (Argv[0], "-neverfail") == 0) { + mGlobals.NeverFail = TRUE; + } else if (stricmp (Argv[0], "-q") == 0) { + mGlobals.QuietMode = TRUE; + } else if (stricmp (Argv[0], "-ignorenotfound") == 0) { + mGlobals.IgnoreNotFound = TRUE; + } else if ((stricmp (Argv[0], "-h") == 0) || (strcmp (Argv[0], "-?") == 0)) { + Usage (); + return STATUS_ERROR; + } else { + Error (NULL, 0, 0, Argv[0], "unrecognized option"); + Usage (); + return STATUS_ERROR; + } + + Argc--; + Argv++; + } + // + // Had to specify at least one source file + // + if (mGlobals.SourceFiles == NULL) { + Error (NULL, 0, 0, "must specify one source file name", NULL); + Usage (); + return STATUS_ERROR; + } + // + // Assume output to stdout if not specified + // + if (mGlobals.OutFptr == NULL) { + mGlobals.OutFptr = stdout; + } + + return STATUS_SUCCESS; +} +// +// Free the global string lists we allocated memory for +// +static +void +FreeLists ( + VOID + ) +{ + STRING_LIST *Temp; + SYMBOL *NextSym; + + // + // printf ("Free lists....."); + // + // Traverse the include paths, freeing each + // printf ("freeing include paths\n"); + // + while (mGlobals.IncludePaths != NULL) { + Temp = mGlobals.IncludePaths->Next; + // + // printf ("Freeing include path string '%s' at 0x%X\n", + // mGlobals.IncludePaths->Str, (int)(mGlobals.IncludePaths->Str)); + // + free (mGlobals.IncludePaths->Str); + // + // printf ("Freeing include path object at 0x%X\n", (int)(mGlobals.IncludePaths)); + // + free (mGlobals.IncludePaths); + mGlobals.IncludePaths = Temp; + } + // + // Traverse the source files, freeing each + // + while (mGlobals.SourceFiles != NULL) { + Temp = mGlobals.SourceFiles->Next; + free (mGlobals.SourceFiles->Str); + free (mGlobals.SourceFiles); + mGlobals.SourceFiles = Temp; + } + // + // Traverse the subdirectory list, freeing each + // + while (mGlobals.SubDirs != NULL) { + Temp = mGlobals.SubDirs->Next; + free (mGlobals.SubDirs->Str); + free (mGlobals.SubDirs); + mGlobals.SubDirs = Temp; + } + // + // Free the symbol table + // + while (mGlobals.SymbolTable != NULL) { + NextSym = mGlobals.SymbolTable->Next; + free (mGlobals.SymbolTable->Name); + free (mGlobals.SymbolTable->Value); + mGlobals.SymbolTable = NextSym; + } + // + // printf ("done\n"); + // +} + +static +void +Usage ( + VOID + ) +/*++ + +Routine Description: + + Print usage information for this utility. + +Arguments: + + None. + +Returns: + + Nothing. + +--*/ +{ + int Index; + static const char *Str[] = { + UTILITY_NAME " -- make dependencies", + " Usage: MakeDeps [options]", + " Options include:", + " -h or -? for this help information", + " -f SourceFile add SourceFile to list of files to scan", + " -i IncludePath add IncludePath to list of search paths", + " -o OutputFile write output dependencies to OutputFile", + " -s SubDir for each IncludePath, also search IncludePath\\SubDir", + " -v for verbose output", + " -ignorenotfound don't warn for files not found", + " -target Target for single SourceFile, target is Target, not SourceFile.obj", + " -q quiet mode to not report files not found if ignored", + " -sub sym str replace all occurrances of 'str' with 'sym' in the output", + " -nosystem not process system files", + " -neverfail always return a success return code", + // + // " -nodupes keep track of include files, don't rescan duplicates", + // + " -usesumdeps path use summary dependency files in 'path' directory.", + "", + NULL + }; + for (Index = 0; Str[Index] != NULL; Index++) { + fprintf (stdout, "%s\n", Str[Index]); + } +} diff --git a/Tools/Source/TianoTools/MakeDeps/build.xml b/Tools/Source/TianoTools/MakeDeps/build.xml new file mode 100755 index 0000000000..10cad4e81f --- /dev/null +++ b/Tools/Source/TianoTools/MakeDeps/build.xml @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Unsupported Operating System + Please Contact Intel Corporation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- 2.39.2