]> git.proxmox.com Git - mirror_edk2.git/blobdiff - EdkCompatibilityPkg/Sample/Tools/Source/MakeDeps/MakeDeps.c
1) Sync EdkCompatibilityPkg with EDK 1.04. The changes includes:
[mirror_edk2.git] / EdkCompatibilityPkg / Sample / Tools / Source / MakeDeps / MakeDeps.c
index bf086e64a44563b2a8afe64f7b623ee2cc4c0698..fb090bc930eb34950d363ee69e488b31200c26e4 100644 (file)
@@ -1,6 +1,6 @@
 /*++\r
 \r
 /*++\r
 \r
-Copyright (c) 2004 - 2006, Intel Corporation                                                         \r
+Copyright (c) 2004 - 2007, Intel Corporation                                                         \r
 All rights reserved. This program and the accompanying materials                          \r
 are licensed and made available under the terms and conditions of the BSD License         \r
 which accompanies this distribution.  The full text of the license may be found at        \r
 All rights reserved. This program and the accompanying materials                          \r
 are licensed and made available under the terms and conditions of the BSD License         \r
 which accompanies this distribution.  The full text of the license may be found at        \r
@@ -101,6 +101,12 @@ typedef struct _SYMBOL {
   INT8            *Value;\r
 } SYMBOL;\r
 \r
   INT8            *Value;\r
 } SYMBOL;\r
 \r
+typedef enum {\r
+  SearchCurrentDir,\r
+  SearchIncludePaths,\r
+  SearchAllPaths,\r
+} FILE_SEARCH_TYPE;\r
+\r
 //\r
 // Here's all our globals. We need a linked list of include paths, a linked\r
 // list of source files, a linked list of subdirectories (appended to each\r
 //\r
 // Here's all our globals. We need a linked list of include paths, a linked\r
 // list of source files, a linked list of subdirectories (appended to each\r
@@ -108,6 +114,7 @@ typedef struct _SYMBOL {
 //\r
 static struct {\r
   STRING_LIST *IncludePaths;            // all include paths to search\r
 //\r
 static struct {\r
   STRING_LIST *IncludePaths;            // all include paths to search\r
+  STRING_LIST *ParentPaths;             // all parent paths to search\r
   STRING_LIST *SourceFiles;             // all source files to parse\r
   STRING_LIST *SubDirs;                 // appended to each include path when searching\r
   SYMBOL      *SymbolTable;             // for replacement strings\r
   STRING_LIST *SourceFiles;             // all source files to parse\r
   STRING_LIST *SubDirs;                 // appended to each include path when searching\r
   SYMBOL      *SymbolTable;             // for replacement strings\r
@@ -120,25 +127,37 @@ static struct {
   BOOLEAN     NoDupes;                  // to not list duplicate dependency files (for timing purposes)\r
   BOOLEAN     UseSumDeps;               // use summary dependency files if found\r
   BOOLEAN     IsAsm;                    // The SourceFiles are assembler files\r
   BOOLEAN     NoDupes;                  // to not list duplicate dependency files (for timing purposes)\r
   BOOLEAN     UseSumDeps;               // use summary dependency files if found\r
   BOOLEAN     IsAsm;                    // The SourceFiles are assembler files\r
+  BOOLEAN     IsCl;                     // The SourceFiles are the output of cl with /showIncludes\r
   INT8        TargetFileName[MAX_PATH]; // target object filename\r
   INT8        SumDepsPath[MAX_PATH];    // path to summary files\r
   INT8        TargetFileName[MAX_PATH]; // target object filename\r
   INT8        SumDepsPath[MAX_PATH];    // path to summary files\r
+  INT8        TmpFileName[MAX_PATH];    // temp file name for output file\r
   INT8        *OutFileName;             // -o option\r
 } mGlobals;\r
 \r
 static\r
 STATUS\r
 ProcessFile (\r
   INT8        *OutFileName;             // -o option\r
 } mGlobals;\r
 \r
 static\r
 STATUS\r
 ProcessFile (\r
+  INT8              *TargetFileName,\r
+  INT8              *FileName,\r
+  UINT32            NestDepth,\r
+  STRING_LIST       *ProcessedFiles,\r
+  FILE_SEARCH_TYPE  FileSearchType\r
+  );\r
+\r
+static\r
+STATUS\r
+ProcessClOutput (\r
   INT8            *TargetFileName,\r
   INT8            *FileName,\r
   INT8            *TargetFileName,\r
   INT8            *FileName,\r
-  UINT32          NestDepth,\r
   STRING_LIST     *ProcessedFiles\r
   );\r
 \r
 static\r
 FILE  *\r
 FindFile (\r
   STRING_LIST     *ProcessedFiles\r
   );\r
 \r
 static\r
 FILE  *\r
 FindFile (\r
-  INT8    *FileName,\r
-  UINT32  FileNameLen\r
+  INT8              *FileName,\r
+  UINT32            FileNameLen,\r
+  FILE_SEARCH_TYPE  FileSearchType\r
   );\r
 \r
 static\r
   );\r
 \r
 static\r
@@ -258,7 +277,12 @@ Returns:
       strcpy (TargetFileName, mGlobals.TargetFileName);\r
     }\r
 \r
       strcpy (TargetFileName, mGlobals.TargetFileName);\r
     }\r
 \r
-    Status = ProcessFile (TargetFileName, File->Str, START_NEST_DEPTH, &ProcessedFiles);\r
+    if (mGlobals.IsCl) {\r
+      Status = ProcessClOutput (TargetFileName, File->Str, &ProcessedFiles);\r
+    } else {\r
+      Status = ProcessFile (TargetFileName, File->Str, START_NEST_DEPTH, \r
+                            &ProcessedFiles, SearchCurrentDir);\r
+    }\r
     if (Status != STATUS_SUCCESS) {\r
       goto Finish;\r
     }\r
     if (Status != STATUS_SUCCESS) {\r
       goto Finish;\r
     }\r
@@ -282,7 +306,7 @@ Finish:
     ProcessedFiles.Next = TempList;\r
   }\r
   //\r
     ProcessedFiles.Next = TempList;\r
   }\r
   //\r
-  // Close our output file\r
+  // Close our temp output file\r
   //\r
   if ((mGlobals.OutFptr != stdout) && (mGlobals.OutFptr != NULL)) {\r
     fclose (mGlobals.OutFptr);\r
   //\r
   if ((mGlobals.OutFptr != stdout) && (mGlobals.OutFptr != NULL)) {\r
     fclose (mGlobals.OutFptr);\r
@@ -291,12 +315,22 @@ Finish:
   if (mGlobals.NeverFail) {\r
     return STATUS_SUCCESS;\r
   }\r
   if (mGlobals.NeverFail) {\r
     return STATUS_SUCCESS;\r
   }\r
-  //\r
-  // If any errors, then delete our output so that it will get created\r
-  // again on a rebuild.\r
-  //\r
-  if ((GetUtilityStatus () == STATUS_ERROR) && (mGlobals.OutFileName != NULL)) {\r
-    remove (mGlobals.OutFileName);\r
+\r
+  if (mGlobals.OutFileName != NULL) {\r
+    if (GetUtilityStatus () == STATUS_ERROR) {\r
+      //\r
+      // If any errors, then delete our temp output\r
+      // Also try to delete target file to improve the incremental build\r
+      //      \r
+      remove (mGlobals.TmpFileName);\r
+      remove (TargetFileName);\r
+    } else {\r
+      //\r
+      // Otherwise, rename temp file to output file\r
+      //\r
+      remove (mGlobals.OutFileName);\r
+      rename (mGlobals.TmpFileName, mGlobals.OutFileName);\r
+    }\r
   }\r
 \r
   return GetUtilityStatus ();\r
   }\r
 \r
   return GetUtilityStatus ();\r
@@ -305,10 +339,11 @@ Finish:
 static\r
 STATUS\r
 ProcessFile (\r
 static\r
 STATUS\r
 ProcessFile (\r
-  INT8            *TargetFileName,\r
-  INT8            *FileName,\r
-  UINT32          NestDepth,\r
-  STRING_LIST     *ProcessedFiles\r
+  INT8              *TargetFileName,\r
+  INT8              *FileName,\r
+  UINT32            NestDepth,\r
+  STRING_LIST       *ProcessedFiles,\r
+  FILE_SEARCH_TYPE  FileSearchType\r
   )\r
 /*++\r
 \r
   )\r
 /*++\r
 \r
@@ -322,6 +357,7 @@ Arguments:
   FileName       - name of the file to process\r
   NestDepth      - how deep we're nested in includes\r
   ProcessedFiles - list of processed files.\r
   FileName       - name of the file to process\r
   NestDepth      - how deep we're nested in includes\r
   ProcessedFiles - list of processed files.\r
+  FileSearchType - search type for FileName\r
 \r
 Returns:\r
 \r
 \r
 Returns:\r
 \r
@@ -342,6 +378,7 @@ Returns:
   UINT32      Index;\r
   UINT32      LineNum;\r
   STRING_LIST *ListPtr;\r
   UINT32      Index;\r
   UINT32      LineNum;\r
   STRING_LIST *ListPtr;\r
+  STRING_LIST ParentPath;\r
 \r
   Status  = STATUS_SUCCESS;\r
   Fptr    = NULL;\r
 \r
   Status  = STATUS_SUCCESS;\r
   Fptr    = NULL;\r
@@ -380,37 +417,6 @@ Returns:
       return STATUS_SUCCESS;\r
     }\r
   }\r
       return STATUS_SUCCESS;\r
     }\r
   }\r
-  //\r
-  // If we're not doing duplicates, and we've already seen this filename,\r
-  // then return\r
-  //\r
-  if (mGlobals.NoDupes) {\r
-    for (ListPtr = ProcessedFiles->Next; ListPtr != NULL; ListPtr = ListPtr->Next) {\r
-      if (_stricmp (FileName, ListPtr->Str) == 0) {\r
-        break;\r
-      }\r
-    }\r
-    //\r
-    // If we found a match, we're done. If we didn't, create a new element\r
-    // and add it to the list.\r
-    //\r
-    if (ListPtr != NULL) {\r
-      //\r
-      // Print a message if verbose mode\r
-      //\r
-      if (mGlobals.Verbose) {\r
-        DebugMsg (NULL, 0, 0, FileName, "duplicate include -- not processed again");\r
-      }\r
-\r
-      return STATUS_SUCCESS;\r
-    }\r
-\r
-    ListPtr       = malloc (sizeof (STRING_LIST));\r
-    ListPtr->Str  = malloc (strlen (FileName) + 1);\r
-    strcpy (ListPtr->Str, FileName);\r
-    ListPtr->Next         = ProcessedFiles->Next;\r
-    ProcessedFiles->Next  = ListPtr;\r
-  }\r
 \r
   //\r
   // Make sure we didn't exceed our maximum nesting depth\r
 \r
   //\r
   // Make sure we didn't exceed our maximum nesting depth\r
@@ -424,14 +430,20 @@ Returns:
   // if we have to.\r
   //\r
   strcpy (FileNameCopy, FileName);\r
   // if we have to.\r
   //\r
   strcpy (FileNameCopy, FileName);\r
-  //\r
-  // Try to open the file locally\r
-  //\r
-  if ((Fptr = fopen (FileNameCopy, "r")) == NULL) {\r
+  \r
+  if (FileSearchType == SearchCurrentDir) {\r
+    //\r
+    // Try to open the source file locally\r
+    //\r
+    if ((Fptr = fopen (FileNameCopy, "r")) == NULL) {\r
+      Error (NULL, 0, 0, FileNameCopy, "could not open source file");\r
+      return STATUS_ERROR;\r
+    }\r
+  } else {\r
     //\r
     // Try to find it among the paths.\r
     //\r
     //\r
     // Try to find it among the paths.\r
     //\r
-    Fptr = FindFile (FileNameCopy, sizeof (FileNameCopy));\r
+    Fptr = FindFile (FileNameCopy, sizeof (FileNameCopy), FileSearchType);\r
     if (Fptr == NULL) {\r
       //\r
       // If this is not the top-level file, and the command-line argument\r
     if (Fptr == NULL) {\r
       //\r
       // If this is not the top-level file, and the command-line argument\r
@@ -457,11 +469,58 @@ Returns:
       }\r
     }\r
   }\r
       }\r
     }\r
   }\r
+\r
+  //\r
+  // If we're not doing duplicates, and we've already seen this filename,\r
+  // then return\r
+  //\r
+  if (mGlobals.NoDupes) {\r
+    for (ListPtr = ProcessedFiles->Next; ListPtr != NULL; ListPtr = ListPtr->Next) {\r
+      if (_stricmp (FileNameCopy, ListPtr->Str) == 0) {\r
+        break;\r
+      }\r
+    }\r
+    //\r
+    // If we found a match, we're done. If we didn't, create a new element\r
+    // and add it to the list.\r
+    //\r
+    if (ListPtr != NULL) {\r
+      //\r
+      // Print a message if verbose mode\r
+      //\r
+      if (mGlobals.Verbose) {\r
+        DebugMsg (NULL, 0, 0, FileNameCopy, "duplicate include -- not processed again");\r
+      }\r
+      fclose (Fptr);\r
+      return STATUS_SUCCESS;\r
+    }\r
+\r
+    ListPtr       = malloc (sizeof (STRING_LIST));\r
+    ListPtr->Str  = malloc (strlen (FileNameCopy) + 1);\r
+    strcpy (ListPtr->Str, FileNameCopy);\r
+    ListPtr->Next         = ProcessedFiles->Next;\r
+    ProcessedFiles->Next  = ListPtr;\r
+  }\r
+    \r
   //\r
   // Print the dependency, with string substitution\r
   //\r
   PrintDependency (TargetFileName, FileNameCopy);\r
   //\r
   // Print the dependency, with string substitution\r
   //\r
   PrintDependency (TargetFileName, FileNameCopy);\r
-\r
+  \r
+  //\r
+  // Get the file path and push to ParentPaths\r
+  //\r
+  Cptr = FileNameCopy + strlen (FileNameCopy) - 1;\r
+  for (; (Cptr > FileNameCopy) && (*Cptr != '\\') && (*Cptr != '/'); Cptr--);\r
+  if ((*Cptr == '\\') || (*Cptr == '/')) {\r
+    *(Cptr + 1) = 0;\r
+  } else {\r
+    strcpy (FileNameCopy, ".\\");\r
+  }\r
+  ParentPath.Next = mGlobals.ParentPaths;\r
+  ParentPath.Str = FileNameCopy;\r
+  mGlobals.ParentPaths = &ParentPath;\r
+  \r
   //\r
   // Now read in lines and find all #include lines. Allow them to indent, and\r
   // to put spaces between the # and include.\r
   //\r
   // Now read in lines and find all #include lines. Allow them to indent, and\r
   // to put spaces between the # and include.\r
@@ -523,7 +582,8 @@ Returns:
           // Null terminate the filename and try to process it.\r
           //\r
           *EndPtr = 0;\r
           // Null terminate the filename and try to process it.\r
           //\r
           *EndPtr = 0;\r
-          Status  = ProcessFile (TargetFileName, Cptr, NestDepth + 1, ProcessedFiles);\r
+          Status  = ProcessFile (TargetFileName, Cptr, NestDepth + 1, \r
+                                 ProcessedFiles, SearchAllPaths);\r
         } else {\r
           //\r
           // Handle special #include MACRO_NAME(file)\r
         } else {\r
           //\r
           // Handle special #include MACRO_NAME(file)\r
@@ -579,7 +639,8 @@ Returns:
                 //\r
                 // Process immediately, then break out of the outside FOR loop.\r
                 //\r
                 //\r
                 // Process immediately, then break out of the outside FOR loop.\r
                 //\r
-                Status = ProcessFile (TargetFileName, MacroIncludeFileName, NestDepth + 1, ProcessedFiles);\r
+                Status = ProcessFile (TargetFileName, MacroIncludeFileName, NestDepth + 1, \r
+                                      ProcessedFiles, SearchAllPaths);\r
                 break;\r
               }\r
             }\r
                 break;\r
               }\r
             }\r
@@ -615,12 +676,20 @@ Returns:
             //\r
             // If we're processing it, do it\r
             //\r
             //\r
             // If we're processing it, do it\r
             //\r
-            if ((EndChar != '>') || (!mGlobals.NoSystem)) {\r
+            if (EndChar != '>') {\r
               //\r
               // Null terminate the filename and try to process it.\r
               //\r
               *EndPtr = 0;\r
               //\r
               // Null terminate the filename and try to process it.\r
               //\r
               *EndPtr = 0;\r
-              Status  = ProcessFile (TargetFileName, Cptr, NestDepth + 1, ProcessedFiles);\r
+              Status  = ProcessFile (TargetFileName, Cptr, NestDepth + 1, \r
+                                     ProcessedFiles, SearchAllPaths);\r
+            } else if (!mGlobals.NoSystem) {\r
+              //\r
+              // Null terminate the filename and try to process it.\r
+              //\r
+              *EndPtr = 0;\r
+              Status  = ProcessFile (TargetFileName, Cptr, NestDepth + 1, \r
+                                     ProcessedFiles, SearchIncludePaths);\r
             }\r
           } else {\r
             Warning (FileNameCopy, LineNum, 0, "malformed include", "missing closing %c", EndChar);\r
             }\r
           } else {\r
             Warning (FileNameCopy, LineNum, 0, "malformed include", "missing closing %c", EndChar);\r
@@ -631,6 +700,10 @@ Returns:
       }\r
     }\r
   }\r
       }\r
     }\r
   }\r
+  //\r
+  // Pop the file path from ParentPaths\r
+  //\r
+  mGlobals.ParentPaths = ParentPath.Next;  \r
 \r
 Finish:\r
   //\r
 \r
 Finish:\r
   //\r
@@ -643,6 +716,120 @@ Finish:
   return Status;\r
 }\r
 \r
   return Status;\r
 }\r
 \r
+static\r
+STATUS\r
+ProcessClOutput (\r
+  INT8            *TargetFileName,\r
+  INT8            *FileName,\r
+  STRING_LIST     *ProcessedFiles\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Given a source file name, open the file and parse all "Note: including file: xxx.h" lines.\r
+  \r
+Arguments:\r
+\r
+  TargetFileName - name of the usually .obj target\r
+  FileName       - name of the file to process\r
+  ProcessedFiles - list of processed files.\r
+\r
+Returns:\r
+\r
+  standard status.\r
+  \r
+--*/\r
+{\r
+  FILE        *Fptr;\r
+  INT8        Line[MAX_LINE_LEN];\r
+  INT8        IncludeFileName[MAX_LINE_LEN];\r
+  STRING_LIST *ListPtr;\r
+  BOOLEAN     ClError;\r
+  INT32       Ret;\r
+  INT8        Char;\r
+\r
+  if ((Fptr = fopen (FileName, "r")) == NULL) {\r
+    Error (NULL, 0, 0, FileName, "could not open file for reading");\r
+    return STATUS_ERROR;\r
+  }\r
+  if (fgets (Line, sizeof (Line), Fptr) != NULL) {\r
+    //\r
+    // First line is the source file name, print it\r
+    //\r
+    printf ("%s", Line);\r
+  } else {\r
+    //\r
+    // No output from cl\r
+    //\r
+    fclose (Fptr);\r
+    Error (NULL, 0, 0, NULL, "incorrect cl tool path may be used ");\r
+    return STATUS_ERROR;\r
+  }\r
+  \r
+  ClError = FALSE;\r
+  while (fgets (Line, sizeof (Line), Fptr) != NULL) {\r
+    Ret = sscanf (Line, "Note: including file: %s %c", IncludeFileName, &Char);\r
+    if (Ret == 2) {\r
+      //\r
+      // There is space in include file name. It's VS header file. Ignore it.\r
+      //\r
+      continue;\r
+    } else if ( Ret != 1) {\r
+      //\r
+      // Cl error info, print it\r
+      // the tool will return error code to stop the nmake\r
+      //\r
+      ClError = TRUE;\r
+      printf ("%s", Line);\r
+      continue;\r
+    }\r
+    \r
+    //\r
+    // If we're not doing duplicates, and we've already seen this filename,\r
+    // then continue\r
+    //\r
+    if (mGlobals.NoDupes) {\r
+      for (ListPtr = ProcessedFiles->Next; ListPtr != NULL; ListPtr = ListPtr->Next) {\r
+        if (_stricmp (IncludeFileName, ListPtr->Str) == 0) {\r
+          break;\r
+        }\r
+      }\r
+      //\r
+      // If we found a match, we're done. If we didn't, create a new element\r
+      // and add it to the list.\r
+      //\r
+      if (ListPtr != NULL) {\r
+        //\r
+        // Print a message if verbose mode\r
+        //\r
+        if (mGlobals.Verbose) {\r
+          DebugMsg (NULL, 0, 0, IncludeFileName, "duplicate include -- not processed again");\r
+        }\r
+  \r
+        continue;\r
+      }\r
+  \r
+      ListPtr       = malloc (sizeof (STRING_LIST));\r
+      ListPtr->Str  = malloc (strlen (IncludeFileName) + 1);\r
+      strcpy (ListPtr->Str, IncludeFileName);\r
+      ListPtr->Next         = ProcessedFiles->Next;\r
+      ProcessedFiles->Next  = ListPtr;\r
+    }\r
+    \r
+    PrintDependency (TargetFileName, IncludeFileName);\r
+  }\r
+  \r
+  fclose (Fptr);\r
+  \r
+  if (ClError) {\r
+    Error (NULL, 0, 0, NULL, "cl error");\r
+    return STATUS_ERROR;\r
+  } else {\r
+    return STATUS_SUCCESS;\r
+  }\r
+}\r
+\r
 static\r
 void\r
 PrintDependency (\r
 static\r
 void\r
 PrintDependency (\r
@@ -754,8 +941,9 @@ ReplaceSymbols (
 static\r
 FILE *\r
 FindFile (\r
 static\r
 FILE *\r
 FindFile (\r
-  INT8    *FileName,\r
-  UINT32  FileNameLen\r
+  INT8              *FileName,\r
+  UINT32            FileNameLen,\r
+  FILE_SEARCH_TYPE  FileSearchType\r
   )\r
 {\r
   FILE        *Fptr;\r
   )\r
 {\r
   FILE        *Fptr;\r
@@ -766,6 +954,49 @@ FindFile (
   //\r
   // Traverse the list of paths and try to find the file\r
   //\r
   //\r
   // Traverse the list of paths and try to find the file\r
   //\r
+  if (FileSearchType == SearchAllPaths) {\r
+    List = mGlobals.ParentPaths;\r
+    while (List != NULL) {\r
+      //\r
+      // Put the path and filename together\r
+      //\r
+      if (strlen (List->Str) + strlen (FileName) + 1 > sizeof (FullFileName)) {\r
+        Error (\r
+          __FILE__,\r
+          __LINE__,\r
+          0,\r
+          "application error",\r
+          "cannot concatenate '%s' + '%s'",\r
+          List->Str,\r
+          FileName\r
+          );\r
+        return NULL;\r
+      }\r
+      //\r
+      // Append the filename to this include path and try to open the file.\r
+      //\r
+      strcpy (FullFileName, List->Str);\r
+      strcat (FullFileName, FileName);\r
+      if ((Fptr = fopen (FullFileName, "r")) != NULL) {\r
+        //\r
+        // Return the file name\r
+        //\r
+        if (FileNameLen <= strlen (FullFileName)) {\r
+          Error (__FILE__, __LINE__, 0, "application error", "internal path name of insufficient length");\r
+          //\r
+          // fprintf (stdout, "File length > %d: %s\n", FileNameLen, FullFileName);\r
+          //\r
+          return NULL;\r
+        }\r
+  \r
+        strcpy (FileName, FullFileName);\r
+        return Fptr;\r
+      }\r
+  \r
+      List = List->Next;\r
+    }    \r
+  }\r
+  \r
   List = mGlobals.IncludePaths;\r
   while (List != NULL) {\r
     //\r
   List = mGlobals.IncludePaths;\r
   while (List != NULL) {\r
     //\r
@@ -846,7 +1077,7 @@ ProcessArgs (
   STRING_LIST *LastIncludePath;\r
   STRING_LIST *LastSourceFile;\r
   SYMBOL      *Symbol;\r
   STRING_LIST *LastIncludePath;\r
   STRING_LIST *LastSourceFile;\r
   SYMBOL      *Symbol;\r
-  int         Index;\r
+\r
   //\r
   // Clear our globals\r
   //\r
   //\r
   // Clear our globals\r
   //\r
@@ -957,50 +1188,7 @@ ProcessArgs (
         Usage ();\r
         return STATUS_ERROR;\r
       }\r
         Usage ();\r
         return STATUS_ERROR;\r
       }\r
-      //\r
-      // The C compiler first looks for #include files in the directory where\r
-      // the source file came from. Add the file's source directory to the\r
-      // list of include paths.\r
-      //\r
-      NewList = malloc (sizeof (STRING_LIST));\r
-      if (NewList == NULL) {\r
-        Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL);\r
-        return STATUS_ERROR;\r
-      }\r
-\r
-      NewList->Next = NULL;\r
-      NewList->Str  = malloc (strlen (Argv[1]) + 3);\r
-      if (NewList->Str == NULL) {\r
-        free (NewList);\r
-        Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL);\r
-        return STATUS_ERROR;\r
-      }\r
-\r
-      strcpy (NewList->Str, Argv[1]);\r
-      //\r
-      // Back up in the source file name to the last backslash and terminate after it.\r
-      //\r
-      for (Index = strlen (NewList->Str) - 1; (Index > 0) && (NewList->Str[Index] != '\\'); Index--)\r
-        ;\r
-      if (Index < 0) {\r
-        strcpy (NewList->Str, ".\\");\r
-      } else {\r
-        NewList->Str[Index + 1] = 0;\r
-      }\r
-      //\r
-      // Add it to the end of the our list of include paths\r
-      //\r
-      if (mGlobals.IncludePaths == NULL) {\r
-        mGlobals.IncludePaths = NewList;\r
-      } else {\r
-        LastIncludePath->Next = NewList;\r
-      }\r
 \r
 \r
-      if (mGlobals.Verbose) {\r
-        fprintf (stdout, "Adding include path: %s\n", NewList->Str);\r
-      }\r
-\r
-      LastIncludePath = NewList;\r
       Argc--;\r
       Argv++;\r
     } else if (_stricmp (Argv[0], "-s") == 0) {\r
       Argc--;\r
       Argv++;\r
     } else if (_stricmp (Argv[0], "-s") == 0) {\r
@@ -1145,15 +1333,20 @@ ProcessArgs (
       // check for one more arg\r
       //\r
       if (Argc > 1) {\r
       // check for one more arg\r
       //\r
       if (Argc > 1) {\r
+        mGlobals.OutFileName = Argv[1];\r
+        //\r
+        // Use temp file for output\r
+        // This can avoid overwriting previous existed dep file when error \r
+        // ocurred in this tool\r
         //\r
         //\r
-        // Try to open the file\r
+        sprintf (mGlobals.TmpFileName, "%s2", mGlobals.OutFileName);\r
         //\r
         //\r
-        if ((mGlobals.OutFptr = fopen (Argv[1], "w")) == NULL) {\r
-          Error (NULL, 0, 0, Argv[1], "could not open file for writing");\r
+        // Try to open the temp file\r
+        //\r
+        if ((mGlobals.OutFptr = fopen (mGlobals.TmpFileName, "w")) == NULL) {\r
+          Error (NULL, 0, 0, mGlobals.TmpFileName, "could not open file for writing");\r
           return STATUS_ERROR;\r
         }\r
           return STATUS_ERROR;\r
         }\r
-\r
-        mGlobals.OutFileName = Argv[1];\r
       } else {\r
         Error (NULL, 0, 0, Argv[0], "option requires output file name");\r
         Usage ();\r
       } else {\r
         Error (NULL, 0, 0, Argv[0], "option requires output file name");\r
         Usage ();\r
@@ -1171,7 +1364,17 @@ ProcessArgs (
     } else if (_stricmp (Argv[0], "-ignorenotfound") == 0) {\r
       mGlobals.IgnoreNotFound = TRUE;\r
     } else if (_stricmp (Argv[0], "-asm") == 0) {\r
     } else if (_stricmp (Argv[0], "-ignorenotfound") == 0) {\r
       mGlobals.IgnoreNotFound = TRUE;\r
     } else if (_stricmp (Argv[0], "-asm") == 0) {\r
+      if (mGlobals.IsCl) {\r
+        Error (NULL, 0, 0, Argv[0], "option conflict with -cl");\r
+        return STATUS_ERROR;\r
+      }      \r
       mGlobals.IsAsm = TRUE;\r
       mGlobals.IsAsm = TRUE;\r
+    } else if (_stricmp (Argv[0], "-cl") == 0) {\r
+      if (mGlobals.IsAsm) {\r
+        Error (NULL, 0, 0, Argv[0], "option conflict with -asm");\r
+        return STATUS_ERROR;\r
+      }\r
+      mGlobals.IsCl = TRUE; \r
     } else if ((_stricmp (Argv[0], "-h") == 0) || (strcmp (Argv[0], "-?") == 0)) {\r
       Usage ();\r
       return STATUS_ERROR;\r
     } else if ((_stricmp (Argv[0], "-h") == 0) || (strcmp (Argv[0], "-?") == 0)) {\r
       Usage ();\r
       return STATUS_ERROR;\r
@@ -1306,7 +1509,8 @@ Returns:
     //    "      -nodupes         keep track of include files, don't rescan duplicates",\r
     //\r
     "      -usesumdeps path use summary dependency files in 'path' directory.",\r
     //    "      -nodupes         keep track of include files, don't rescan duplicates",\r
     //\r
     "      -usesumdeps path use summary dependency files in 'path' directory.",\r
-    "      -asm             The SourceFile is assembler file",\r
+    "      -asm             The SourceFiles are assembler files",\r
+    "      -cl              The SourceFiles are the output of cl with /showIncludes",\r
     "",\r
     NULL\r
   };\r
     "",\r
     NULL\r
   };\r