//===--- DependencyFile.cpp - Generate dependency file --------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This code generates dependency files.
//
//===----------------------------------------------------------------------===//

#include "clang/Frontend/Utils.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Basic/FileManager.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Lex/PPCallbacks.h"
#include "clang/Lex/DirectoryLookup.h"
#include "clang/Basic/SourceLocation.h"
#include "llvm/ADT/StringSet.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/raw_ostream.h"
#include <string>

using namespace clang;

namespace {
class VISIBILITY_HIDDEN DependencyFileCallback : public PPCallbacks {
  std::vector<std::string> Files;
  llvm::StringSet<> FilesSet;
  const Preprocessor *PP;
  std::vector<std::string> Targets;
  llvm::raw_ostream *OS;
  bool IncludeSystemHeaders;
  bool PhonyTarget;
private:
  bool FileMatchesDepCriteria(const char *Filename,
                              SrcMgr::CharacteristicKind FileType);
  void OutputDependencyFile();

public:
  DependencyFileCallback(const Preprocessor *_PP, 
                         llvm::raw_ostream *_OS, 
                         const std::vector<std::string> &_Targets,
                         bool _IncludeSystemHeaders,
                         bool _PhonyTarget)
    : PP(_PP), Targets(_Targets), OS(_OS),
      IncludeSystemHeaders(_IncludeSystemHeaders), PhonyTarget(_PhonyTarget) {}

  ~DependencyFileCallback() {
    OutputDependencyFile();
    OS->flush();
    delete OS;
  }

  virtual void FileChanged(SourceLocation Loc, FileChangeReason Reason,
                           SrcMgr::CharacteristicKind FileType);
};
}



void clang::AttachDependencyFileGen(Preprocessor *PP, llvm::raw_ostream *OS,
                                    std::vector<std::string> &Targets,
                                    bool IncludeSystemHeaders,
                                    bool PhonyTarget) {
  assert(!Targets.empty() && "Target required for dependency generation");

  DependencyFileCallback *PPDep = 
    new DependencyFileCallback(PP, OS, Targets, IncludeSystemHeaders, 
                               PhonyTarget);
  PP->setPPCallbacks(PPDep);
}

/// FileMatchesDepCriteria - Determine whether the given Filename should be
/// considered as a dependency.
bool DependencyFileCallback::FileMatchesDepCriteria(const char *Filename,
                                          SrcMgr::CharacteristicKind FileType) {
  if (strcmp("<built-in>", Filename) == 0)
    return false;

  if (IncludeSystemHeaders)
    return true;

  return FileType == SrcMgr::C_User;
}

void DependencyFileCallback::FileChanged(SourceLocation Loc,
                                         FileChangeReason Reason,
                                         SrcMgr::CharacteristicKind FileType) {
  if (Reason != PPCallbacks::EnterFile)
    return;
  
  // Dependency generation really does want to go all the way to the
  // file entry for a source location to find out what is depended on.
  // We do not want #line markers to affect dependency generation!
  SourceManager &SM = PP->getSourceManager();
  
  const FileEntry *FE =
    SM.getFileEntryForID(SM.getFileID(SM.getInstantiationLoc(Loc)));
  if (FE == 0) return;
  
  const char *Filename = FE->getName();
  if (!FileMatchesDepCriteria(Filename, FileType))
    return;

  // Remove leading "./"
  if (Filename[0] == '.' && Filename[1] == '/')
    Filename = &Filename[2];

  if (FilesSet.insert(Filename))
    Files.push_back(Filename);
}

void DependencyFileCallback::OutputDependencyFile() {
  // Write out the dependency targets, trying to avoid overly long
  // lines when possible. We try our best to emit exactly the same
  // dependency file as GCC (4.2), assuming the included files are the
  // same.
  const unsigned MaxColumns = 75;
  unsigned Columns = 0;

  for (std::vector<std::string>::iterator
         I = Targets.begin(), E = Targets.end(); I != E; ++I) {
    unsigned N = I->length();
    if (Columns == 0) {
      Columns += N;
      *OS << *I;
    } else if (Columns + N + 2 > MaxColumns) {
      Columns = N + 2;
      *OS << " \\\n  " << *I;
    } else {
      Columns += N + 1;
      *OS << ' ' << *I;
    }
  }

  *OS << ':';
  Columns += 1;
  
  // Now add each dependency in the order it was seen, but avoiding
  // duplicates.
  for (std::vector<std::string>::iterator I = Files.begin(),
         E = Files.end(); I != E; ++I) {
    // Start a new line if this would exceed the column limit. Make
    // sure to leave space for a trailing " \" in case we need to
    // break the line on the next iteration.
    unsigned N = I->length();
    if (Columns + (N + 1) + 2 > MaxColumns) {
      *OS << " \\\n ";
      Columns = 2;
    }
    *OS << ' ' << *I;
    Columns += N + 1;
  }
  *OS << '\n';

  // Create phony targets if requested.
  if (PhonyTarget) {
    // Skip the first entry, this is always the input file itself.
    for (std::vector<std::string>::iterator I = Files.begin() + 1,
           E = Files.end(); I != E; ++I) {
      *OS << '\n';
      *OS << *I << ":\n";
    }
  }
}

