/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
   file Copyright.txt or https://cmake.org/licensing for details.  */
#include "cmExtraEclipseCDT4Generator.h"

#include "cmsys/RegularExpression.hxx"
#include <algorithm>
#include <assert.h>
#include <map>
#include <sstream>
#include <stdio.h>
#include <utility>

#include "cmGeneratedFileStream.h"
#include "cmGeneratorExpression.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalGenerator.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmSourceFile.h"
#include "cmSourceGroup.h"
#include "cmState.h"
#include "cmStateTypes.h"
#include "cmSystemTools.h"
#include "cmXMLWriter.h"
#include "cmake.h"

static void AppendAttribute(cmXMLWriter& xml, const char* keyval)
{
  xml.StartElement("attribute");
  xml.Attribute("key", keyval);
  xml.Attribute("value", keyval);
  xml.EndElement();
}

template <typename T>
void AppendDictionary(cmXMLWriter& xml, const char* key, T const& value)
{
  xml.StartElement("dictionary");
  xml.Element("key", key);
  xml.Element("value", value);
  xml.EndElement();
}

cmExtraEclipseCDT4Generator::cmExtraEclipseCDT4Generator()
{
  this->SupportsVirtualFolders = true;
  this->GenerateLinkedResources = true;
  this->SupportsGmakeErrorParser = true;
  this->SupportsMachO64Parser = true;
  this->CEnabled = false;
  this->CXXEnabled = false;
}

cmExternalMakefileProjectGeneratorFactory*
cmExtraEclipseCDT4Generator::GetFactory()
{
  static cmExternalMakefileProjectGeneratorSimpleFactory<
    cmExtraEclipseCDT4Generator>
    factory("Eclipse CDT4", "Generates Eclipse CDT 4.0 project files.");

  if (factory.GetSupportedGlobalGenerators().empty()) {
// TODO: Verify if __CYGWIN__ should be checked.
//#if defined(_WIN32) && !defined(__CYGWIN__)
#if defined(_WIN32)
    factory.AddSupportedGlobalGenerator("NMake Makefiles");
    factory.AddSupportedGlobalGenerator("MinGW Makefiles");
// factory.AddSupportedGlobalGenerator("MSYS Makefiles");
#endif
    factory.AddSupportedGlobalGenerator("Ninja");
    factory.AddSupportedGlobalGenerator("Unix Makefiles");
  }

  return &factory;
}

void cmExtraEclipseCDT4Generator::EnableLanguage(
  std::vector<std::string> const& languages, cmMakefile* /*unused*/,
  bool /*optional*/)
{
  for (std::string const& l : languages) {
    if (l == "CXX") {
      this->Natures.insert("org.eclipse.cdt.core.ccnature");
      this->Natures.insert("org.eclipse.cdt.core.cnature");
      this->CXXEnabled = true;
    } else if (l == "C") {
      this->Natures.insert("org.eclipse.cdt.core.cnature");
      this->CEnabled = true;
    } else if (l == "Java") {
      this->Natures.insert("org.eclipse.jdt.core.javanature");
    }
  }
}

void cmExtraEclipseCDT4Generator::Generate()
{
  cmLocalGenerator* lg = this->GlobalGenerator->GetLocalGenerators()[0];
  const cmMakefile* mf = lg->GetMakefile();

  std::string eclipseVersion = mf->GetSafeDefinition("CMAKE_ECLIPSE_VERSION");
  cmsys::RegularExpression regex(".*([0-9]+\\.[0-9]+).*");
  if (regex.find(eclipseVersion)) {
    unsigned int majorVersion = 0;
    unsigned int minorVersion = 0;
    int res =
      sscanf(regex.match(1).c_str(), "%u.%u", &majorVersion, &minorVersion);
    if (res == 2) {
      int version = majorVersion * 1000 + minorVersion;
      if (version < 3006) // 3.6 is Helios
      {
        this->SupportsVirtualFolders = false;
        this->SupportsMachO64Parser = false;
      }
      if (version < 3007) // 3.7 is Indigo
      {
        this->SupportsGmakeErrorParser = false;
      }
    }
  }

  // TODO: Decide if these are local or member variables
  this->HomeDirectory = lg->GetSourceDirectory();
  this->HomeOutputDirectory = lg->GetBinaryDirectory();

  this->GenerateLinkedResources =
    mf->IsOn("CMAKE_ECLIPSE_GENERATE_LINKED_RESOURCES");

  this->IsOutOfSourceBuild =
    (this->HomeDirectory != this->HomeOutputDirectory);

  this->GenerateSourceProject =
    (this->IsOutOfSourceBuild &&
     mf->IsOn("CMAKE_ECLIPSE_GENERATE_SOURCE_PROJECT"));

  if (!this->GenerateSourceProject &&
      (mf->IsOn("ECLIPSE_CDT4_GENERATE_SOURCE_PROJECT"))) {
    mf->IssueMessage(
      MessageType::WARNING,
      "ECLIPSE_CDT4_GENERATE_SOURCE_PROJECT is set to TRUE, "
      "but this variable is not supported anymore since CMake 2.8.7.\n"
      "Enable CMAKE_ECLIPSE_GENERATE_SOURCE_PROJECT instead.");
  }

  if (cmSystemTools::IsSubDirectory(this->HomeOutputDirectory,
                                    this->HomeDirectory)) {
    mf->IssueMessage(MessageType::WARNING,
                     "The build directory is a subdirectory "
                     "of the source directory.\n"
                     "This is not supported well by Eclipse. It is strongly "
                     "recommended to use a build directory which is a "
                     "sibling of the source directory.");
  }

  // NOTE: This is not good, since it pollutes the source tree. However,
  //       Eclipse doesn't allow CVS/SVN to work when the .project is not in
  //       the cvs/svn root directory. Hence, this is provided as an option.
  if (this->GenerateSourceProject) {
    // create .project file in the source tree
    this->CreateSourceProjectFile();
  }

  // create a .project file
  this->CreateProjectFile();

  // create a .cproject file
  this->CreateCProjectFile();
}

void cmExtraEclipseCDT4Generator::CreateSourceProjectFile()
{
  assert(this->HomeDirectory != this->HomeOutputDirectory);

  // set up the project name: <project>-Source@<baseSourcePathName>
  cmLocalGenerator* lg = this->GlobalGenerator->GetLocalGenerators()[0];
  std::string name = cmExtraEclipseCDT4Generator::GenerateProjectName(
    lg->GetProjectName(), "Source",
    cmExtraEclipseCDT4Generator::GetPathBasename(this->HomeDirectory));

  const std::string filename = this->HomeDirectory + "/.project";
  cmGeneratedFileStream fout(filename);
  if (!fout) {
    return;
  }

  cmXMLWriter xml(fout);
  xml.StartDocument("UTF-8");
  xml.StartElement("projectDescription");
  xml.Element("name", name);
  xml.Element("comment", "");
  xml.Element("projects", "");
  xml.Element("buildSpec", "");
  xml.Element("natures", "");
  xml.StartElement("linkedResources");

  if (this->SupportsVirtualFolders) {
    this->CreateLinksToSubprojects(xml, this->HomeDirectory);
    this->SrcLinkedResources.clear();
  }

  xml.EndElement(); // linkedResources
  xml.EndElement(); // projectDescription
  xml.EndDocument();
}

void cmExtraEclipseCDT4Generator::AddEnvVar(std::ostream& out,
                                            const char* envVar,
                                            cmLocalGenerator* lg)
{
  cmMakefile* mf = lg->GetMakefile();

  // get the variables from the environment and from the cache and then
  // figure out which one to use:

  std::string envVarValue;
  const bool envVarSet = cmSystemTools::GetEnv(envVar, envVarValue);

  std::string cacheEntryName = "CMAKE_ECLIPSE_ENVVAR_";
  cacheEntryName += envVar;
  const std::string* cacheValue =
    lg->GetState()->GetInitializedCacheValue(cacheEntryName);

  // now we have both, decide which one to use
  std::string valueToUse;
  if (!envVarSet && cacheValue == nullptr) {
    // nothing known, do nothing
    valueToUse.clear();
  } else if (envVarSet && cacheValue == nullptr) {
    // The variable is in the env, but not in the cache. Use it and put it
    // in the cache
    valueToUse = envVarValue;
    mf->AddCacheDefinition(cacheEntryName, valueToUse.c_str(),
                           cacheEntryName.c_str(), cmStateEnums::STRING, true);
    mf->GetCMakeInstance()->SaveCache(lg->GetBinaryDirectory());
  } else if (!envVarSet && cacheValue != nullptr) {
    // It is already in the cache, but not in the env, so use it from the cache
    valueToUse = *cacheValue;
  } else {
    // It is both in the cache and in the env.
    // Use the version from the env. except if the value from the env is
    // completely contained in the value from the cache (for the case that we
    // now have a PATH without MSVC dirs in the env. but had the full PATH with
    // all MSVC dirs during the cmake run which stored the var in the cache:
    valueToUse = *cacheValue;
    if (valueToUse.find(envVarValue) == std::string::npos) {
      valueToUse = envVarValue;
      mf->AddCacheDefinition(cacheEntryName, valueToUse.c_str(),
                             cacheEntryName.c_str(), cmStateEnums::STRING,
                             true);
      mf->GetCMakeInstance()->SaveCache(lg->GetBinaryDirectory());
    }
  }

  if (!valueToUse.empty()) {
    out << envVar << "=" << valueToUse << "|";
  }
}

void cmExtraEclipseCDT4Generator::CreateProjectFile()
{
  cmLocalGenerator* lg = this->GlobalGenerator->GetLocalGenerators()[0];
  cmMakefile* mf = lg->GetMakefile();

  const std::string filename = this->HomeOutputDirectory + "/.project";

  cmGeneratedFileStream fout(filename);
  if (!fout) {
    return;
  }

  std::string compilerId = mf->GetSafeDefinition("CMAKE_C_COMPILER_ID");
  if (compilerId.empty()) // no C compiler, try the C++ compiler:
  {
    compilerId = mf->GetSafeDefinition("CMAKE_CXX_COMPILER_ID");
  }

  cmXMLWriter xml(fout);

  xml.StartDocument("UTF-8");
  xml.StartElement("projectDescription");

  xml.Element("name",
              cmExtraEclipseCDT4Generator::GenerateProjectName(
                lg->GetProjectName(),
                mf->GetSafeDefinition("CMAKE_BUILD_TYPE"),
                cmExtraEclipseCDT4Generator::GetPathBasename(
                  this->HomeOutputDirectory)));

  xml.Element("comment", "");
  xml.Element("projects", "");

  xml.StartElement("buildSpec");
  xml.StartElement("buildCommand");
  xml.Element("name", "org.eclipse.cdt.make.core.makeBuilder");
  xml.Element("triggers", "clean,full,incremental,");
  xml.StartElement("arguments");

  // use clean target
  AppendDictionary(xml, "org.eclipse.cdt.make.core.cleanBuildTarget", "clean");
  AppendDictionary(xml, "org.eclipse.cdt.make.core.enableCleanBuild", "true");
  AppendDictionary(xml, "org.eclipse.cdt.make.core.append_environment",
                   "true");
  AppendDictionary(xml, "org.eclipse.cdt.make.core.stopOnError", "true");

  // set the make command
  AppendDictionary(xml, "org.eclipse.cdt.make.core.enabledIncrementalBuild",
                   "true");
  AppendDictionary(xml, "org.eclipse.cdt.make.core.build.command",
                   cmExtraEclipseCDT4Generator::GetEclipsePath(
                     mf->GetRequiredDefinition("CMAKE_MAKE_PROGRAM")));
  AppendDictionary(xml, "org.eclipse.cdt.make.core.contents",
                   "org.eclipse.cdt.make.core.activeConfigSettings");
  AppendDictionary(xml, "org.eclipse.cdt.make.core.build.target.inc", "all");
  AppendDictionary(xml, "org.eclipse.cdt.make.core.build.arguments",
                   mf->GetSafeDefinition("CMAKE_ECLIPSE_MAKE_ARGUMENTS"));
  AppendDictionary(
    xml, "org.eclipse.cdt.make.core.buildLocation",
    cmExtraEclipseCDT4Generator::GetEclipsePath(this->HomeOutputDirectory));
  AppendDictionary(xml, "org.eclipse.cdt.make.core.useDefaultBuildCmd",
                   "false");

  // set project specific environment
  std::ostringstream environment;
  environment << "VERBOSE=1|CMAKE_NO_VERBOSE=1|"; // verbose Makefile output
  // set vsvars32.bat environment available at CMake time,
  //   but not necessarily when eclipse is open
  if (compilerId == "MSVC") {
    AddEnvVar(environment, "PATH", lg);
    AddEnvVar(environment, "INCLUDE", lg);
    AddEnvVar(environment, "LIB", lg);
    AddEnvVar(environment, "LIBPATH", lg);
  } else if (compilerId == "Intel") {
    // if the env.var is set, use this one and put it in the cache
    // if the env.var is not set, but the value is in the cache,
    // use it from the cache:
    AddEnvVar(environment, "INTEL_LICENSE_FILE", lg);
  }
  AppendDictionary(xml, "org.eclipse.cdt.make.core.environment",
                   environment.str());

  AppendDictionary(xml, "org.eclipse.cdt.make.core.enableFullBuild", "true");
  AppendDictionary(xml, "org.eclipse.cdt.make.core.build.target.auto", "all");
  AppendDictionary(xml, "org.eclipse.cdt.make.core.enableAutoBuild", "false");
  AppendDictionary(xml, "org.eclipse.cdt.make.core.build.target.clean",
                   "clean");
  AppendDictionary(xml, "org.eclipse.cdt.make.core.fullBuildTarget", "all");
  AppendDictionary(xml, "org.eclipse.cdt.make.core.buildArguments", "");
  AppendDictionary(
    xml, "org.eclipse.cdt.make.core.build.location",
    cmExtraEclipseCDT4Generator::GetEclipsePath(this->HomeOutputDirectory));
  AppendDictionary(xml, "org.eclipse.cdt.make.core.autoBuildTarget", "all");

  // set error parsers
  std::ostringstream errorOutputParser;

  if (compilerId == "MSVC") {
    errorOutputParser << "org.eclipse.cdt.core.VCErrorParser;";
  } else if (compilerId == "Intel") {
    errorOutputParser << "org.eclipse.cdt.core.ICCErrorParser;";
  }

  if (this->SupportsGmakeErrorParser) {
    errorOutputParser << "org.eclipse.cdt.core.GmakeErrorParser;";
  } else {
    errorOutputParser << "org.eclipse.cdt.core.MakeErrorParser;";
  }

  errorOutputParser << "org.eclipse.cdt.core.GCCErrorParser;"
                       "org.eclipse.cdt.core.GASErrorParser;"
                       "org.eclipse.cdt.core.GLDErrorParser;";
  AppendDictionary(xml, "org.eclipse.cdt.core.errorOutputParser",
                   errorOutputParser.str());

  xml.EndElement(); // arguments
  xml.EndElement(); // buildCommand
  xml.StartElement("buildCommand");
  xml.Element("name", "org.eclipse.cdt.make.core.ScannerConfigBuilder");
  xml.StartElement("arguments");
  xml.EndElement(); // arguments
  xml.EndElement(); // buildCommand
  xml.EndElement(); // buildSpec

  // set natures for c/c++ projects
  xml.StartElement("natures");
  xml.Element("nature", "org.eclipse.cdt.make.core.makeNature");
  xml.Element("nature", "org.eclipse.cdt.make.core.ScannerConfigNature");

  for (std::string const& n : this->Natures) {
    xml.Element("nature", n);
  }

  if (const char* extraNaturesProp =
        mf->GetState()->GetGlobalProperty("ECLIPSE_EXTRA_NATURES")) {
    std::vector<std::string> extraNatures;
    cmSystemTools::ExpandListArgument(extraNaturesProp, extraNatures);
    for (std::string const& n : extraNatures) {
      xml.Element("nature", n);
    }
  }

  xml.EndElement(); // natures

  xml.StartElement("linkedResources");
  // create linked resources
  if (this->IsOutOfSourceBuild) {
    // create a linked resource to CMAKE_SOURCE_DIR
    // (this is not done anymore for each project because of
    // https://gitlab.kitware.com/cmake/cmake/issues/9978 and because I found
    // it actually quite confusing in bigger projects with many directories and
    // projects, Alex

    std::string sourceLinkedResourceName = "[Source directory]";
    std::string linkSourceDirectory =
      cmExtraEclipseCDT4Generator::GetEclipsePath(
        lg->GetCurrentSourceDirectory());
    // .project dir can't be subdir of a linked resource dir
    if (!cmSystemTools::IsSubDirectory(this->HomeOutputDirectory,
                                       linkSourceDirectory)) {
      cmExtraEclipseCDT4Generator::AppendLinkedResource(
        xml, sourceLinkedResourceName,
        cmExtraEclipseCDT4Generator::GetEclipsePath(linkSourceDirectory),
        LinkToFolder);
      this->SrcLinkedResources.push_back(std::move(sourceLinkedResourceName));
    }
  }

  if (this->SupportsVirtualFolders) {
    this->CreateLinksToSubprojects(xml, this->HomeOutputDirectory);

    this->CreateLinksForTargets(xml);
  }

  xml.EndElement(); // linkedResources
  xml.EndElement(); // projectDescription
}

void cmExtraEclipseCDT4Generator::WriteGroups(
  std::vector<cmSourceGroup> const& sourceGroups, std::string& linkName,
  cmXMLWriter& xml)
{
  for (cmSourceGroup const& sg : sourceGroups) {
    std::string linkName3 = linkName;
    linkName3 += "/";
    linkName3 += sg.GetFullName();

    std::replace(linkName3.begin(), linkName3.end(), '\\', '/');

    cmExtraEclipseCDT4Generator::AppendLinkedResource(
      xml, linkName3, "virtual:/virtual", VirtualFolder);
    std::vector<cmSourceGroup> const& children = sg.GetGroupChildren();
    if (!children.empty()) {
      this->WriteGroups(children, linkName, xml);
    }
    std::vector<const cmSourceFile*> sFiles = sg.GetSourceFiles();
    for (cmSourceFile const* file : sFiles) {
      std::string const& fullPath = file->GetFullPath();

      if (!cmSystemTools::FileIsDirectory(fullPath)) {
        std::string linkName4 = linkName3;
        linkName4 += "/";
        linkName4 += cmSystemTools::GetFilenameName(fullPath);
        cmExtraEclipseCDT4Generator::AppendLinkedResource(
          xml, linkName4,
          cmExtraEclipseCDT4Generator::GetEclipsePath(fullPath), LinkToFile);
      }
    }
  }
}

void cmExtraEclipseCDT4Generator::CreateLinksForTargets(cmXMLWriter& xml)
{
  std::string linkName = "[Targets]";
  cmExtraEclipseCDT4Generator::AppendLinkedResource(
    xml, linkName, "virtual:/virtual", VirtualFolder);

  for (cmLocalGenerator* lg : this->GlobalGenerator->GetLocalGenerators()) {
    cmMakefile* makefile = lg->GetMakefile();
    const std::vector<cmGeneratorTarget*>& targets = lg->GetGeneratorTargets();

    for (cmGeneratorTarget* target : targets) {
      std::string linkName2 = linkName;
      linkName2 += "/";
      switch (target->GetType()) {
        case cmStateEnums::EXECUTABLE:
        case cmStateEnums::STATIC_LIBRARY:
        case cmStateEnums::SHARED_LIBRARY:
        case cmStateEnums::MODULE_LIBRARY:
        case cmStateEnums::OBJECT_LIBRARY: {
          const char* prefix =
            (target->GetType() == cmStateEnums::EXECUTABLE ? "[exe] "
                                                           : "[lib] ");
          linkName2 += prefix;
          linkName2 += target->GetName();
          cmExtraEclipseCDT4Generator::AppendLinkedResource(
            xml, linkName2, "virtual:/virtual", VirtualFolder);
          if (!this->GenerateLinkedResources) {
            break; // skip generating the linked resources to the source files
          }
          std::vector<cmSourceGroup> sourceGroups =
            makefile->GetSourceGroups();
          // get the files from the source lists then add them to the groups
          cmGeneratorTarget* gt = const_cast<cmGeneratorTarget*>(target);
          std::vector<cmSourceFile*> files;
          gt->GetSourceFiles(files,
                             makefile->GetSafeDefinition("CMAKE_BUILD_TYPE"));
          for (cmSourceFile* sf : files) {
            // Add the file to the list of sources.
            std::string const& source = sf->GetFullPath();
            cmSourceGroup* sourceGroup =
              makefile->FindSourceGroup(source, sourceGroups);
            sourceGroup->AssignSource(sf);
          }

          this->WriteGroups(sourceGroups, linkName2, xml);
        } break;
        // ignore all others:
        default:
          break;
      }
    }
  }
}

void cmExtraEclipseCDT4Generator::CreateLinksToSubprojects(
  cmXMLWriter& xml, const std::string& baseDir)
{
  if (!this->GenerateLinkedResources) {
    return;
  }

  // for each sub project create a linked resource to the source dir
  // - only if it is an out-of-source build
  cmExtraEclipseCDT4Generator::AppendLinkedResource(
    xml, "[Subprojects]", "virtual:/virtual", VirtualFolder);

  for (auto const& it : this->GlobalGenerator->GetProjectMap()) {
    std::string linkSourceDirectory =
      cmExtraEclipseCDT4Generator::GetEclipsePath(
        it.second[0]->GetCurrentSourceDirectory());
    // a linked resource must not point to a parent directory of .project or
    // .project itself
    if ((baseDir != linkSourceDirectory) &&
        !cmSystemTools::IsSubDirectory(baseDir, linkSourceDirectory)) {
      std::string linkName = "[Subprojects]/";
      linkName += it.first;
      cmExtraEclipseCDT4Generator::AppendLinkedResource(
        xml, linkName,
        cmExtraEclipseCDT4Generator::GetEclipsePath(linkSourceDirectory),
        LinkToFolder);
      // Don't add it to the srcLinkedResources, because listing multiple
      // directories confuses the Eclipse indexer (#13596).
    }
  }
}

void cmExtraEclipseCDT4Generator::AppendIncludeDirectories(
  cmXMLWriter& xml, const std::vector<std::string>& includeDirs,
  std::set<std::string>& emittedDirs)
{
  for (std::string const& inc : includeDirs) {
    if (!inc.empty()) {
      std::string dir = cmSystemTools::CollapseFullPath(inc);

      // handle framework include dirs on OSX, the remainder after the
      // Frameworks/ part has to be stripped
      //   /System/Library/Frameworks/GLUT.framework/Headers
      cmsys::RegularExpression frameworkRx("(.+/Frameworks)/.+\\.framework/");
      if (frameworkRx.find(dir)) {
        dir = frameworkRx.match(1);
      }

      if (emittedDirs.find(dir) == emittedDirs.end()) {
        emittedDirs.insert(dir);
        xml.StartElement("pathentry");
        xml.Attribute("include",
                      cmExtraEclipseCDT4Generator::GetEclipsePath(dir));
        xml.Attribute("kind", "inc");
        xml.Attribute("path", "");
        xml.Attribute("system", "true");
        xml.EndElement();
      }
    }
  }
}

void cmExtraEclipseCDT4Generator::CreateCProjectFile() const
{
  std::set<std::string> emmited;

  cmLocalGenerator* lg = this->GlobalGenerator->GetLocalGenerators()[0];
  const cmMakefile* mf = lg->GetMakefile();

  const std::string filename = this->HomeOutputDirectory + "/.cproject";

  cmGeneratedFileStream fout(filename);
  if (!fout) {
    return;
  }

  cmXMLWriter xml(fout);

  // add header
  xml.StartDocument("UTF-8");
  xml.ProcessingInstruction("fileVersion", "4.0.0");
  xml.StartElement("cproject");
  xml.StartElement("storageModule");
  xml.Attribute("moduleId", "org.eclipse.cdt.core.settings");

  xml.StartElement("cconfiguration");
  xml.Attribute("id", "org.eclipse.cdt.core.default.config.1");

  // Configuration settings...
  xml.StartElement("storageModule");
  xml.Attribute("buildSystemId",
                "org.eclipse.cdt.core.defaultConfigDataProvider");
  xml.Attribute("id", "org.eclipse.cdt.core.default.config.1");
  xml.Attribute("moduleId", "org.eclipse.cdt.core.settings");
  xml.Attribute("name", "Configuration");
  xml.Element("externalSettings");
  xml.StartElement("extensions");

  // TODO: refactor this out...
  std::string executableFormat =
    mf->GetSafeDefinition("CMAKE_EXECUTABLE_FORMAT");
  if (executableFormat == "ELF") {
    xml.StartElement("extension");
    xml.Attribute("id", "org.eclipse.cdt.core.ELF");
    xml.Attribute("point", "org.eclipse.cdt.core.BinaryParser");
    xml.EndElement(); // extension

    xml.StartElement("extension");
    xml.Attribute("id", "org.eclipse.cdt.core.GNU_ELF");
    xml.Attribute("point", "org.eclipse.cdt.core.BinaryParser");
    AppendAttribute(xml, "addr2line");
    AppendAttribute(xml, "c++filt");
    xml.EndElement(); // extension
  } else {
    std::string systemName = mf->GetSafeDefinition("CMAKE_SYSTEM_NAME");
    if (systemName == "CYGWIN") {
      xml.StartElement("extension");
      xml.Attribute("id", "org.eclipse.cdt.core.Cygwin_PE");
      xml.Attribute("point", "org.eclipse.cdt.core.BinaryParser");
      AppendAttribute(xml, "addr2line");
      AppendAttribute(xml, "c++filt");
      AppendAttribute(xml, "cygpath");
      AppendAttribute(xml, "nm");
      xml.EndElement(); // extension
    } else if (systemName == "Windows") {
      xml.StartElement("extension");
      xml.Attribute("id", "org.eclipse.cdt.core.PE");
      xml.Attribute("point", "org.eclipse.cdt.core.BinaryParser");
      xml.EndElement(); // extension
    } else if (systemName == "Darwin") {
      xml.StartElement("extension");
      xml.Attribute("id",
                    this->SupportsMachO64Parser
                      ? "org.eclipse.cdt.core.MachO64"
                      : "org.eclipse.cdt.core.MachO");
      xml.Attribute("point", "org.eclipse.cdt.core.BinaryParser");
      AppendAttribute(xml, "c++filt");
      xml.EndElement(); // extension
    } else {
      // *** Should never get here ***
      xml.Element("error_toolchain_type");
    }
  }

  xml.EndElement(); // extensions
  xml.EndElement(); // storageModule

  // ???
  xml.StartElement("storageModule");
  xml.Attribute("moduleId", "org.eclipse.cdt.core.language.mapping");
  xml.Element("project-mappings");
  xml.EndElement(); // storageModule

  // ???
  xml.StartElement("storageModule");
  xml.Attribute("moduleId", "org.eclipse.cdt.core.externalSettings");
  xml.EndElement(); // storageModule

  // set the path entries (includes, libs, source dirs, etc.)
  xml.StartElement("storageModule");
  xml.Attribute("moduleId", "org.eclipse.cdt.core.pathentry");

  // for each sub project with a linked resource to the source dir:
  // - make it type 'src'
  // - and exclude it from type 'out'
  std::string excludeFromOut;
  /* I don't know what the pathentry kind="src" are good for, e.g.
   * autocompletion
   * works also without them. Done wrong, the indexer complains, see #12417
   * and #12213.
   * According to #13596, this entry at least limits the directories the
   * indexer is searching for files. So now the "src" entry contains only
   * the linked resource to CMAKE_SOURCE_DIR.
   * The CDT documentation is very terse on that:
   * "CDT_SOURCE: Entry kind constant describing a path entry identifying a
   * folder containing source code to be compiled."
   * Also on the cdt-dev list didn't bring any information:
   * http://web.archiveorange.com/archive/v/B4NlJDNIpYoOS1SbxFNy
   * Alex */
  // include subprojects directory to the src pathentry
  // eclipse cdt indexer uses this entries as reference to index source files
  if (this->GenerateLinkedResources) {
    xml.StartElement("pathentry");
    xml.Attribute("kind", "src");
    xml.Attribute("path", "[Subprojects]");
    xml.EndElement();
  }

  for (std::string const& p : this->SrcLinkedResources) {
    xml.StartElement("pathentry");
    xml.Attribute("kind", "src");
    xml.Attribute("path", p);
    xml.EndElement();

    // exclude source directory from output search path
    // - only if not named the same as an output directory
    if (!cmSystemTools::FileIsDirectory(
          std::string(this->HomeOutputDirectory + "/" + p))) {
      excludeFromOut += p + "/|";
    }
  }

  excludeFromOut += "**/CMakeFiles/";

  xml.StartElement("pathentry");
  xml.Attribute("excluding", excludeFromOut);
  xml.Attribute("kind", "out");
  xml.Attribute("path", "");
  xml.EndElement();

  // add pre-processor definitions to allow eclipse to gray out sections
  emmited.clear();
  for (cmLocalGenerator* lgen : this->GlobalGenerator->GetLocalGenerators()) {

    if (const char* cdefs =
          lgen->GetMakefile()->GetProperty("COMPILE_DEFINITIONS")) {
      // Expand the list.
      std::vector<std::string> defs;
      cmGeneratorExpression::Split(cdefs, defs);

      for (std::string const& d : defs) {
        if (cmGeneratorExpression::Find(d) != std::string::npos) {
          continue;
        }

        std::string::size_type equals = d.find('=', 0);
        std::string::size_type enddef = d.length();

        std::string def;
        std::string val;
        if (equals != std::string::npos && equals < enddef) {
          // we have -DFOO=BAR
          def = d.substr(0, equals);
          val = d.substr(equals + 1, enddef - equals + 1);
        } else {
          // we have -DFOO
          def = d;
        }

        // insert the definition if not already added.
        if (emmited.find(def) == emmited.end()) {
          emmited.insert(def);
          xml.StartElement("pathentry");
          xml.Attribute("kind", "mac");
          xml.Attribute("name", def);
          xml.Attribute("path", "");
          xml.Attribute("value", val);
          xml.EndElement();
        }
      }
    }
  }
  // add system defined c macros
  const char* cDefs =
    mf->GetDefinition("CMAKE_EXTRA_GENERATOR_C_SYSTEM_DEFINED_MACROS");
  if (this->CEnabled && cDefs) {
    // Expand the list.
    std::vector<std::string> defs;
    cmSystemTools::ExpandListArgument(cDefs, defs, true);

    // the list must contain only definition-value pairs:
    if ((defs.size() % 2) == 0) {
      std::vector<std::string>::const_iterator di = defs.begin();
      while (di != defs.end()) {
        std::string def = *di;
        ++di;
        std::string val;
        if (di != defs.end()) {
          val = *di;
          ++di;
        }

        // insert the definition if not already added.
        if (emmited.find(def) == emmited.end()) {
          emmited.insert(def);
          xml.StartElement("pathentry");
          xml.Attribute("kind", "mac");
          xml.Attribute("name", def);
          xml.Attribute("path", "");
          xml.Attribute("value", val);
          xml.EndElement();
        }
      }
    }
  }
  // add system defined c++ macros
  const char* cxxDefs =
    mf->GetDefinition("CMAKE_EXTRA_GENERATOR_CXX_SYSTEM_DEFINED_MACROS");
  if (this->CXXEnabled && cxxDefs) {
    // Expand the list.
    std::vector<std::string> defs;
    cmSystemTools::ExpandListArgument(cxxDefs, defs, true);

    // the list must contain only definition-value pairs:
    if ((defs.size() % 2) == 0) {
      std::vector<std::string>::const_iterator di = defs.begin();
      while (di != defs.end()) {
        std::string def = *di;
        ++di;
        std::string val;
        if (di != defs.end()) {
          val = *di;
          ++di;
        }

        // insert the definition if not already added.
        if (emmited.find(def) == emmited.end()) {
          emmited.insert(def);
          xml.StartElement("pathentry");
          xml.Attribute("kind", "mac");
          xml.Attribute("name", def);
          xml.Attribute("path", "");
          xml.Attribute("value", val);
          xml.EndElement();
        }
      }
    }
  }

  // include dirs
  emmited.clear();
  for (cmLocalGenerator* lgen : this->GlobalGenerator->GetLocalGenerators()) {
    const std::vector<cmGeneratorTarget*>& targets =
      lgen->GetGeneratorTargets();
    for (cmGeneratorTarget* target : targets) {
      if (target->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
        continue;
      }
      std::vector<std::string> includeDirs;
      std::string config = mf->GetSafeDefinition("CMAKE_BUILD_TYPE");
      lgen->GetIncludeDirectories(includeDirs, target, "C", config);
      this->AppendIncludeDirectories(xml, includeDirs, emmited);
    }
  }
  // now also the system include directories, in case we found them in
  // CMakeSystemSpecificInformation.cmake. This makes Eclipse find the
  // standard headers.
  std::string compiler = mf->GetSafeDefinition("CMAKE_C_COMPILER");
  if (this->CEnabled && !compiler.empty()) {
    std::string systemIncludeDirs =
      mf->GetSafeDefinition("CMAKE_EXTRA_GENERATOR_C_SYSTEM_INCLUDE_DIRS");
    std::vector<std::string> dirs;
    cmSystemTools::ExpandListArgument(systemIncludeDirs, dirs);
    this->AppendIncludeDirectories(xml, dirs, emmited);
  }
  compiler = mf->GetSafeDefinition("CMAKE_CXX_COMPILER");
  if (this->CXXEnabled && !compiler.empty()) {
    std::string systemIncludeDirs =
      mf->GetSafeDefinition("CMAKE_EXTRA_GENERATOR_CXX_SYSTEM_INCLUDE_DIRS");
    std::vector<std::string> dirs;
    cmSystemTools::ExpandListArgument(systemIncludeDirs, dirs);
    this->AppendIncludeDirectories(xml, dirs, emmited);
  }

  xml.EndElement(); // storageModule

  // add build targets
  xml.StartElement("storageModule");
  xml.Attribute("moduleId", "org.eclipse.cdt.make.core.buildtargets");
  xml.StartElement("buildTargets");
  emmited.clear();
  const std::string make = mf->GetRequiredDefinition("CMAKE_MAKE_PROGRAM");
  const std::string makeArgs =
    mf->GetSafeDefinition("CMAKE_ECLIPSE_MAKE_ARGUMENTS");

  cmGlobalGenerator* generator =
    const_cast<cmGlobalGenerator*>(this->GlobalGenerator);

  std::string allTarget;
  std::string cleanTarget;
  if (generator->GetAllTargetName()) {
    allTarget = generator->GetAllTargetName();
  }
  if (generator->GetCleanTargetName()) {
    cleanTarget = generator->GetCleanTargetName();
  }

  // add all executable and library targets and some of the GLOBAL
  // and UTILITY targets
  for (cmLocalGenerator* lgen : this->GlobalGenerator->GetLocalGenerators()) {
    const std::vector<cmGeneratorTarget*>& targets =
      lgen->GetGeneratorTargets();
    std::string subdir = lgen->MaybeConvertToRelativePath(
      this->HomeOutputDirectory, lgen->GetCurrentBinaryDirectory());
    if (subdir == ".") {
      subdir.clear();
    }

    for (cmGeneratorTarget* target : targets) {
      std::string targetName = target->GetName();
      switch (target->GetType()) {
        case cmStateEnums::GLOBAL_TARGET: {
          // Only add the global targets from CMAKE_BINARY_DIR,
          // not from the subdirs
          if (subdir.empty()) {
            cmExtraEclipseCDT4Generator::AppendTarget(xml, targetName, make,
                                                      makeArgs, subdir, ": ");
          }
        } break;
        case cmStateEnums::UTILITY:
          // Add all utility targets, except the Nightly/Continuous/
          // Experimental-"sub"targets as e.g. NightlyStart
          if (((targetName.find("Nightly") == 0) &&
               (targetName != "Nightly")) ||
              ((targetName.find("Continuous") == 0) &&
               (targetName != "Continuous")) ||
              ((targetName.find("Experimental") == 0) &&
               (targetName != "Experimental"))) {
            break;
          }

          cmExtraEclipseCDT4Generator::AppendTarget(xml, targetName, make,
                                                    makeArgs, subdir, ": ");
          break;
        case cmStateEnums::EXECUTABLE:
        case cmStateEnums::STATIC_LIBRARY:
        case cmStateEnums::SHARED_LIBRARY:
        case cmStateEnums::MODULE_LIBRARY:
        case cmStateEnums::OBJECT_LIBRARY: {
          const char* prefix =
            (target->GetType() == cmStateEnums::EXECUTABLE ? "[exe] "
                                                           : "[lib] ");
          cmExtraEclipseCDT4Generator::AppendTarget(xml, targetName, make,
                                                    makeArgs, subdir, prefix);
          std::string fastTarget = targetName;
          fastTarget += "/fast";
          cmExtraEclipseCDT4Generator::AppendTarget(xml, fastTarget, make,
                                                    makeArgs, subdir, prefix);

          // Add Build and Clean targets in the virtual folder of targets:
          if (this->SupportsVirtualFolders) {
            std::string virtDir = "[Targets]/";
            virtDir += prefix;
            virtDir += targetName;
            std::string buildArgs = "-C \"";
            buildArgs += lgen->GetBinaryDirectory();
            buildArgs += "\" ";
            buildArgs += makeArgs;
            cmExtraEclipseCDT4Generator::AppendTarget(
              xml, "Build", make, buildArgs, virtDir, "", targetName.c_str());

            std::string cleanArgs = "-E chdir \"";
            cleanArgs += lgen->GetCurrentBinaryDirectory();
            cleanArgs += "\" \"";
            cleanArgs += cmSystemTools::GetCMakeCommand();
            cleanArgs += "\" -P \"";
            cmGeneratorTarget* gt = target;
            cleanArgs += lgen->GetTargetDirectory(gt);
            cleanArgs += "/cmake_clean.cmake\"";
            cmExtraEclipseCDT4Generator::AppendTarget(
              xml, "Clean", cmSystemTools::GetCMakeCommand(), cleanArgs,
              virtDir, "", "");
          }
        } break;
        case cmStateEnums::INTERFACE_LIBRARY:
          break;
        default:
          break;
      }
    }

    // insert the all and clean targets in every subdir
    if (!allTarget.empty()) {
      cmExtraEclipseCDT4Generator::AppendTarget(xml, allTarget, make, makeArgs,
                                                subdir, ": ");
    }
    if (!cleanTarget.empty()) {
      cmExtraEclipseCDT4Generator::AppendTarget(xml, cleanTarget, make,
                                                makeArgs, subdir, ": ");
    }

    // insert rules for compiling, preprocessing and assembling individual
    // files
    std::vector<std::string> objectFileTargets;
    lg->GetIndividualFileTargets(objectFileTargets);
    for (std::string const& f : objectFileTargets) {
      const char* prefix = "[obj] ";
      if (f.back() == 's') {
        prefix = "[to asm] ";
      } else if (f.back() == 'i') {
        prefix = "[pre] ";
      }
      cmExtraEclipseCDT4Generator::AppendTarget(xml, f, make, makeArgs, subdir,
                                                prefix);
    }
  }

  xml.EndElement(); // buildTargets
  xml.EndElement(); // storageModule

  cmExtraEclipseCDT4Generator::AppendStorageScanners(xml, *mf);

  xml.EndElement(); // cconfiguration
  xml.EndElement(); // storageModule

  xml.StartElement("storageModule");
  xml.Attribute("moduleId", "cdtBuildSystem");
  xml.Attribute("version", "4.0.0");

  xml.StartElement("project");
  xml.Attribute("id", std::string(lg->GetProjectName()) + ".null.1");
  xml.Attribute("name", lg->GetProjectName());
  xml.EndElement(); // project

  xml.EndElement(); // storageModule

  // Append additional cproject contents without applying any XML formatting
  if (const char* extraCProjectContents =
        mf->GetState()->GetGlobalProperty("ECLIPSE_EXTRA_CPROJECT_CONTENTS")) {
    fout << extraCProjectContents;
  }

  xml.EndElement(); // cproject
}

std::string cmExtraEclipseCDT4Generator::GetEclipsePath(
  const std::string& path)
{
#if defined(__CYGWIN__)
  std::string cmd = "cygpath -m " + path;
  std::string out;
  if (!cmSystemTools::RunSingleCommand(cmd.c_str(), &out, &out)) {
    return path;
  } else {
    out.erase(out.find_last_of('\n'));
    return out;
  }
#else
  return path;
#endif
}

std::string cmExtraEclipseCDT4Generator::GetPathBasename(
  const std::string& path)
{
  std::string outputBasename = path;
  while (!outputBasename.empty() &&
         (outputBasename.back() == '/' || outputBasename.back() == '\\')) {
    outputBasename.resize(outputBasename.size() - 1);
  }
  std::string::size_type loc = outputBasename.find_last_of("/\\");
  if (loc != std::string::npos) {
    outputBasename = outputBasename.substr(loc + 1);
  }

  return outputBasename;
}

std::string cmExtraEclipseCDT4Generator::GenerateProjectName(
  const std::string& name, const std::string& type, const std::string& path)
{
  return name + (type.empty() ? "" : "-") + type + "@" + path;
}

// Helper functions
void cmExtraEclipseCDT4Generator::AppendStorageScanners(
  cmXMLWriter& xml, const cmMakefile& makefile)
{
  // we need the "make" and the C (or C++) compiler which are used, Alex
  std::string make = makefile.GetRequiredDefinition("CMAKE_MAKE_PROGRAM");
  std::string compiler = makefile.GetSafeDefinition("CMAKE_C_COMPILER");
  std::string arg1 = makefile.GetSafeDefinition("CMAKE_C_COMPILER_ARG1");
  if (compiler.empty()) {
    compiler = makefile.GetSafeDefinition("CMAKE_CXX_COMPILER");
    arg1 = makefile.GetSafeDefinition("CMAKE_CXX_COMPILER_ARG1");
  }
  if (compiler.empty()) // Hmm, what to do now ?
  {
    compiler = "gcc";
  }

  // the following right now hardcodes gcc behaviour :-/
  std::string compilerArgs =
    "-E -P -v -dD ${plugin_state_location}/${specs_file}";
  if (!arg1.empty()) {
    arg1 += " ";
    compilerArgs = arg1 + compilerArgs;
  }

  xml.StartElement("storageModule");
  xml.Attribute("moduleId", "scannerConfiguration");

  xml.StartElement("autodiscovery");
  xml.Attribute("enabled", "true");
  xml.Attribute("problemReportingEnabled", "true");
  xml.Attribute("selectedProfileId",
                "org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile");
  xml.EndElement(); // autodiscovery

  cmExtraEclipseCDT4Generator::AppendScannerProfile(
    xml, "org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile", true,
    "", true, "specsFile", compilerArgs, compiler, true, true);
  cmExtraEclipseCDT4Generator::AppendScannerProfile(
    xml, "org.eclipse.cdt.make.core.GCCStandardMakePerFileProfile", true, "",
    true, "makefileGenerator", "-f ${project_name}_scd.mk", make, true, true);

  xml.EndElement(); // storageModule
}

// The prefix is prepended before the actual name of the target. The purpose
// of that is to sort the targets in the view of Eclipse, so that at first
// the global/utility/all/clean targets appear ": ", then the executable
// targets "[exe] ", then the libraries "[lib]", then the rules for the
// object files "[obj]", then for preprocessing only "[pre] " and
// finally the assembly files "[to asm] ". Note the "to" in "to asm",
// without it, "asm" would be the first targets in the list, with the "to"
// they are the last targets, which makes more sense.
void cmExtraEclipseCDT4Generator::AppendTarget(
  cmXMLWriter& xml, const std::string& target, const std::string& make,
  const std::string& makeArgs, const std::string& path, const char* prefix,
  const char* makeTarget)
{
  xml.StartElement("target");
  xml.Attribute("name", prefix + target);
  xml.Attribute("path", path);
  xml.Attribute("targetID", "org.eclipse.cdt.make.MakeTargetBuilder");
  xml.Element("buildCommand",
              cmExtraEclipseCDT4Generator::GetEclipsePath(make));
  xml.Element("buildArguments", makeArgs);
  xml.Element("buildTarget", makeTarget ? makeTarget : target.c_str());
  xml.Element("stopOnError", "true");
  xml.Element("useDefaultCommand", "false");
  xml.EndElement();
}

void cmExtraEclipseCDT4Generator::AppendScannerProfile(
  cmXMLWriter& xml, const std::string& profileID, bool openActionEnabled,
  const std::string& openActionFilePath, bool pParserEnabled,
  const std::string& scannerInfoProviderID,
  const std::string& runActionArguments, const std::string& runActionCommand,
  bool runActionUseDefault, bool sipParserEnabled)
{
  xml.StartElement("profile");
  xml.Attribute("id", profileID);

  xml.StartElement("buildOutputProvider");
  xml.StartElement("openAction");
  xml.Attribute("enabled", openActionEnabled ? "true" : "false");
  xml.Attribute("filePath", openActionFilePath);
  xml.EndElement(); // openAction
  xml.StartElement("parser");
  xml.Attribute("enabled", pParserEnabled ? "true" : "false");
  xml.EndElement(); // parser
  xml.EndElement(); // buildOutputProvider

  xml.StartElement("scannerInfoProvider");
  xml.Attribute("id", scannerInfoProviderID);
  xml.StartElement("runAction");
  xml.Attribute("arguments", runActionArguments);
  xml.Attribute("command", runActionCommand);
  xml.Attribute("useDefault", runActionUseDefault ? "true" : "false");
  xml.EndElement(); // runAction
  xml.StartElement("parser");
  xml.Attribute("enabled", sipParserEnabled ? "true" : "false");
  xml.EndElement(); // parser
  xml.EndElement(); // scannerInfoProvider

  xml.EndElement(); // profile
}

void cmExtraEclipseCDT4Generator::AppendLinkedResource(cmXMLWriter& xml,
                                                       const std::string& name,
                                                       const std::string& path,
                                                       LinkType linkType)
{
  const char* locationTag = "location";
  int typeTag = 2;
  if (linkType == VirtualFolder) // ... and not a linked folder
  {
    locationTag = "locationURI";
  }
  if (linkType == LinkToFile) {
    typeTag = 1;
  }

  xml.StartElement("link");
  xml.Element("name", name);
  xml.Element("type", typeTag);
  xml.Element(locationTag, path);
  xml.EndElement();
}
