/*============================================================================
  CMake - Cross Platform Makefile Generator
  Copyright 2004-2009 Kitware, Inc.
  Copyright 2004 Alexander Neundorf (neundorf@kde.org)
  Copyright 2007 Miguel A. Figueroa-Villanueva

  Distributed under the OSI-approved BSD License (the "License");
  see accompanying file Copyright.txt for details.

  This software is distributed WITHOUT ANY WARRANTY; without even the
  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  See the License for more information.
============================================================================*/
#include "cmExtraEclipseCDT4Generator.h"
#include "cmGlobalUnixMakefileGenerator3.h"
#include "cmLocalUnixMakefileGenerator3.h"
#include "cmMakefile.h"
#include "cmGeneratedFileStream.h"
#include "cmTarget.h"

#include "cmSystemTools.h"
#include <stdlib.h>
#include <assert.h>

//----------------------------------------------------------------------------
cmExtraEclipseCDT4Generator
::cmExtraEclipseCDT4Generator() : cmExternalMakefileProjectGenerator()
{
// TODO: Verify if __CYGWIN__ should be checked.
//#if defined(_WIN32) && !defined(__CYGWIN__)
#if defined(_WIN32)
  this->SupportedGlobalGenerators.push_back("NMake Makefiles");
  this->SupportedGlobalGenerators.push_back("MinGW Makefiles");
//  this->SupportedGlobalGenerators.push_back("MSYS Makefiles");
#endif
  this->SupportedGlobalGenerators.push_back("Unix Makefiles");
}

//----------------------------------------------------------------------------
void cmExtraEclipseCDT4Generator
::GetDocumentation(cmDocumentationEntry& entry, const char*) const
{
  entry.Name = this->GetName();
  entry.Brief = "Generates Eclipse CDT 4.0 project files.";
  entry.Full =
    "Project files for Eclipse will be created in the top directory. "
    "In out of source builds, a linked resource to the top level source "
    "directory will be created."
    "Additionally a hierarchy of makefiles is generated into the "
    "build tree. The appropriate make program can build the project through "
    "the default make target. A \"make install\" target is also provided.";
}

//----------------------------------------------------------------------------
void cmExtraEclipseCDT4Generator
::SetGlobalGenerator(cmGlobalGenerator* generator)
{
  cmExternalMakefileProjectGenerator::SetGlobalGenerator(generator);
  cmGlobalUnixMakefileGenerator3* mf
    = static_cast<cmGlobalUnixMakefileGenerator3*>(generator);
  mf->SetToolSupportsColor(true);
}

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

  // TODO: Decide if these are local or member variables
  this->HomeDirectory       = mf->GetHomeDirectory();
  this->HomeOutputDirectory = mf->GetHomeOutputDirectory();

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

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

  // 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() const
{
  assert(this->HomeDirectory != this->HomeOutputDirectory);

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

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

  fout << 
    "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
    "<projectDescription>\n"
    "\t<name>" << name << "</name>\n"
    "\t<comment></comment>\n"
    "\t<projects>\n"
    "\t</projects>\n"
    "\t<buildSpec>\n"
    "\t</buildSpec>\n"
    "\t<natures>\n"
    "\t</natures>\n"
    "</projectDescription>\n"
    ;
}


//----------------------------------------------------------------------------
void cmExtraEclipseCDT4Generator::AddEnvVar(cmGeneratedFileStream& fout,
                                            const char* envVar, cmMakefile* mf)
{
  // get the variables from the environment and from the cache and then 
  // figure out which one to use:

  const char* envVarValue = getenv(envVar);

  std::string cacheEntryName = "CMAKE_ECLIPSE_ENVVAR_";
  cacheEntryName += envVar;
  const char* cacheValue = mf->GetCacheManager()->GetCacheValue(
                                                       cacheEntryName.c_str());

  // now we have both, decide which one to use
  std::string valueToUse;
  if (envVarValue==0 && cacheValue==0)
    {
    // nothing known, do nothing
    valueToUse = "";
    }
  else if (envVarValue!=0 && cacheValue==0)
    {
    // The variable is in the env, but not in the cache. Use it and put it 
    // in the cache
    valueToUse = envVarValue;
    mf->AddCacheDefinition(cacheEntryName.c_str(), valueToUse.c_str(),
                           cacheEntryName.c_str(), cmCacheManager::STRING,
                           true);
    mf->GetCacheManager()->SaveCache(mf->GetHomeOutputDirectory());
    }
  else if (envVarValue==0 && cacheValue!=0)
    {
    // 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.c_str(), valueToUse.c_str(),
                             cacheEntryName.c_str(), cmCacheManager::STRING,
                             true);
      mf->GetCacheManager()->SaveCache(mf->GetHomeOutputDirectory());
      }
    }

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


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

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

  cmGeneratedFileStream fout(filename.c_str());
  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");
    }

  fout << 
    "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
    "<projectDescription>\n"
    "\t<name>" <<
    this->GenerateProjectName(mf->GetProjectName(),
                              mf->GetDefinition("CMAKE_BUILD_TYPE"),
                              this->GetPathBasename(this->HomeOutputDirectory))
    << "</name>\n"
    "\t<comment></comment>\n"
    "\t<projects>\n"
    "\t</projects>\n"
    "\t<buildSpec>\n"
    "\t\t<buildCommand>\n"
    "\t\t\t<name>org.eclipse.cdt.make.core.makeBuilder</name>\n"
    "\t\t\t<triggers>clean,full,incremental,</triggers>\n"
    "\t\t\t<arguments>\n"
    ;

  // use clean target
  fout << 
    "\t\t\t\t<dictionary>\n"
    "\t\t\t\t\t<key>org.eclipse.cdt.make.core.cleanBuildTarget</key>\n"
    "\t\t\t\t\t<value>clean</value>\n"
    "\t\t\t\t</dictionary>\n"
    "\t\t\t\t<dictionary>\n"
    "\t\t\t\t\t<key>org.eclipse.cdt.make.core.enableCleanBuild</key>\n"
    "\t\t\t\t\t<value>true</value>\n"
    "\t\t\t\t</dictionary>\n"
    "\t\t\t\t<dictionary>\n"
    "\t\t\t\t\t<key>org.eclipse.cdt.make.core.append_environment</key>\n"
    "\t\t\t\t\t<value>true</value>\n"
    "\t\t\t\t</dictionary>\n"
    "\t\t\t\t<dictionary>\n"
    "\t\t\t\t\t<key>org.eclipse.cdt.make.core.stopOnError</key>\n"
    "\t\t\t\t\t<value>true</value>\n"
    "\t\t\t\t</dictionary>\n"
    ;

  // set the make command
  std::string make = mf->GetRequiredDefinition("CMAKE_MAKE_PROGRAM");
  fout << 
    "\t\t\t\t<dictionary>\n"
    "\t\t\t\t\t<key>org.eclipse.cdt.make.core.enabledIncrementalBuild</key>\n"
    "\t\t\t\t\t<value>true</value>\n"
    "\t\t\t\t</dictionary>\n"
    "\t\t\t\t<dictionary>\n"
    "\t\t\t\t\t<key>org.eclipse.cdt.make.core.build.command</key>\n"
    "\t\t\t\t\t<value>" + this->GetEclipsePath(make) + "</value>\n"
    "\t\t\t\t</dictionary>\n"
    "\t\t\t\t<dictionary>\n"
    "\t\t\t\t\t<key>org.eclipse.cdt.make.core.contents</key>\n"
    "\t\t\t\t\t<value>org.eclipse.cdt.make.core.activeConfigSettings</value>\n"
    "\t\t\t\t</dictionary>\n"
    "\t\t\t\t<dictionary>\n"
    "\t\t\t\t\t<key>org.eclipse.cdt.make.core.build.target.inc</key>\n"
    "\t\t\t\t\t<value>all</value>\n"
    "\t\t\t\t</dictionary>\n"
    "\t\t\t\t<dictionary>\n"
    "\t\t\t\t\t<key>org.eclipse.cdt.make.core.build.arguments</key>\n"
    "\t\t\t\t\t<value></value>\n"
    "\t\t\t\t</dictionary>\n"
    "\t\t\t\t<dictionary>\n"
    "\t\t\t\t\t<key>org.eclipse.cdt.make.core.buildLocation</key>\n"
    "\t\t\t\t\t<value>"
     << this->GetEclipsePath(this->HomeOutputDirectory) << "</value>\n"
    "\t\t\t\t</dictionary>\n"
    "\t\t\t\t<dictionary>\n"
    "\t\t\t\t\t<key>org.eclipse.cdt.make.core.useDefaultBuildCmd</key>\n"
    "\t\t\t\t\t<value>false</value>\n"
    "\t\t\t\t</dictionary>\n"
    ;

  // set project specific environment
  fout <<
    "\t\t\t\t<dictionary>\n"
    "\t\t\t\t\t<key>org.eclipse.cdt.make.core.environment</key>\n"
    "\t\t\t\t\t<value>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(fout, "PATH", mf);
    AddEnvVar(fout, "INCLUDE", mf);
    AddEnvVar(fout, "LIB", mf);
    AddEnvVar(fout, "LIBPATH", mf);
    AddEnvVar(fout, "INCLUDE", mf);
    }
  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(fout, "INTEL_LICENSE_FILE", mf);
    }
  fout <<
    "</value>\n"
    "\t\t\t\t</dictionary>\n"
    ;

  fout <<
    "\t\t\t\t<dictionary>\n"
    "\t\t\t\t\t<key>org.eclipse.cdt.make.core.enableFullBuild</key>\n"
    "\t\t\t\t\t<value>true</value>\n"
    "\t\t\t\t</dictionary>\n"
    "\t\t\t\t<dictionary>\n"
    "\t\t\t\t\t<key>org.eclipse.cdt.make.core.build.target.auto</key>\n"
    "\t\t\t\t\t<value>all</value>\n"
    "\t\t\t\t</dictionary>\n"
    "\t\t\t\t<dictionary>\n"
    "\t\t\t\t\t<key>org.eclipse.cdt.make.core.enableAutoBuild</key>\n"
    "\t\t\t\t\t<value>false</value>\n"
    "\t\t\t\t</dictionary>\n"
    "\t\t\t\t<dictionary>\n"
    "\t\t\t\t\t<key>org.eclipse.cdt.make.core.build.target.clean</key>\n"
    "\t\t\t\t\t<value>clean</value>\n"
    "\t\t\t\t</dictionary>\n"
    "\t\t\t\t<dictionary>\n"
    "\t\t\t\t\t<key>org.eclipse.cdt.make.core.fullBuildTarget</key>\n"
    "\t\t\t\t\t<value>all</value>\n"
    "\t\t\t\t</dictionary>\n"
    "\t\t\t\t<dictionary>\n"
    "\t\t\t\t\t<key>org.eclipse.cdt.make.core.buildArguments</key>\n"
    "\t\t\t\t\t<value></value>\n"
    "\t\t\t\t</dictionary>\n"
    "\t\t\t\t<dictionary>\n"
    "\t\t\t\t\t<key>org.eclipse.cdt.make.core.build.location</key>\n"
    "\t\t\t\t\t<value>"
    << this->GetEclipsePath(this->HomeOutputDirectory) << "</value>\n"
    "\t\t\t\t</dictionary>\n"
    "\t\t\t\t<dictionary>\n"
    "\t\t\t\t\t<key>org.eclipse.cdt.make.core.autoBuildTarget</key>\n"
    "\t\t\t\t\t<value>all</value>\n"
    "\t\t\t\t</dictionary>\n"
    ;

  // set error parsers
  fout <<
    "\t\t\t\t<dictionary>\n"
    "\t\t\t\t\t<key>org.eclipse.cdt.core.errorOutputParser</key>\n"
    "\t\t\t\t\t<value>"
    ;
  if (compilerId == "MSVC")
    {
    fout << "org.eclipse.cdt.core.VCErrorParser;";
    }
  else if (compilerId == "Intel")
    {
    fout << "org.eclipse.cdt.core.ICCErrorParser;";
    }
  fout <<
    "org.eclipse.cdt.core.MakeErrorParser;"
    "org.eclipse.cdt.core.GCCErrorParser;"
    "org.eclipse.cdt.core.GASErrorParser;"
    "org.eclipse.cdt.core.GLDErrorParser;"
    "</value>\n"
    "\t\t\t\t</dictionary>\n"
    ;

  fout <<
    "\t\t\t</arguments>\n"
    "\t\t</buildCommand>\n"
    "\t\t<buildCommand>\n"
    "\t\t\t<name>org.eclipse.cdt.make.core.ScannerConfigBuilder</name>\n"
    "\t\t\t<arguments>\n"
    "\t\t\t</arguments>\n"
    "\t\t</buildCommand>\n"
    "\t</buildSpec>\n"
    ;

  // set natures for c/c++ projects
  fout <<
    "\t<natures>\n"
    // TODO: ccnature only if it is c++ ???
    "\t\t<nature>org.eclipse.cdt.core.ccnature</nature>\n"
    "\t\t<nature>org.eclipse.cdt.make.core.makeNature</nature>\n"
    "\t\t<nature>org.eclipse.cdt.make.core.ScannerConfigNature</nature>\n"
    "\t\t<nature>org.eclipse.cdt.core.cnature</nature>\n"
    "\t</natures>\n"
    ;

  // TODO: refactor this
  // create linked resources
  if (this->IsOutOfSourceBuild)
    {
    fout << "\t<linkedResources>\n";
    // create a linked resource to CMAKE_SOURCE_DIR
    // (this is not done anymore for each project because of 
    // http://public.kitware.com/Bug/view.php?id=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 = this->GetEclipsePath(
                                                      mf->GetStartDirectory());
    // .project dir can't be subdir of a linked resource dir
    if (!cmSystemTools::IsSubDirectory(this->HomeOutputDirectory.c_str(),
                                         linkSourceDirectory.c_str()))
      {
      this->AppendLinkedResource(fout, sourceLinkedResourceName,
                                 this->GetEclipsePath(linkSourceDirectory));
      this->SrcLinkedResources.push_back(sourceLinkedResourceName);
      }

    // for EXECUTABLE_OUTPUT_PATH when not in binary dir
    this->AppendOutLinkedResource(fout,
      mf->GetSafeDefinition("CMAKE_RUNTIME_OUTPUT_DIRECTORY"),
      mf->GetSafeDefinition("EXECUTABLE_OUTPUT_PATH"));
    // for LIBRARY_OUTPUT_PATH when not in binary dir
    this->AppendOutLinkedResource(fout,
      mf->GetSafeDefinition("CMAKE_LIBRARY_OUTPUT_DIRECTORY"),
      mf->GetSafeDefinition("LIBRARY_OUTPUT_PATH"));

    fout << "\t</linkedResources>\n";
    }

  fout << "</projectDescription>\n";
}

//----------------------------------------------------------------------------
void cmExtraEclipseCDT4Generator::AppendIncludeDirectories(
                            cmGeneratedFileStream& fout,
                            const std::vector<std::string>& includeDirs,
                            std::set<std::string>& emittedDirs)
{
  for(std::vector<std::string>::const_iterator inc = includeDirs.begin();
      inc != includeDirs.end();
      ++inc)
    {
    if (!inc->empty())
      {
      std::string dir = cmSystemTools::CollapseFullPath(inc->c_str());
      if(emittedDirs.find(dir) == emittedDirs.end())
        {
        emittedDirs.insert(dir);
        fout << "<pathentry include=\"" 
             << cmExtraEclipseCDT4Generator::GetEclipsePath(dir)
             << "\" kind=\"inc\" path=\"\" system=\"true\"/>\n";
        }
      }
    }
}

//----------------------------------------------------------------------------
void cmExtraEclipseCDT4Generator::CreateCProjectFile() const
{
  std::set<std::string> emmited;
  
  const cmMakefile* mf
    = this->GlobalGenerator->GetLocalGenerators()[0]->GetMakefile();

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

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

  // add header
  fout << 
    "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n"
    "<?fileVersion 4.0.0?>\n\n"
    "<cproject>\n"
    "<storageModule moduleId=\"org.eclipse.cdt.core.settings\">\n"
    ;

  fout << "<cconfiguration id=\"org.eclipse.cdt.core.default.config.1\">\n";

  // Configuration settings...
  fout << 
    "<storageModule"
    " buildSystemId=\"org.eclipse.cdt.core.defaultConfigDataProvider\""
    " id=\"org.eclipse.cdt.core.default.config.1\""
    " moduleId=\"org.eclipse.cdt.core.settings\" name=\"Configuration\">\n"
    "<externalSettings/>\n"
    "<extensions>\n"
    ;
  // TODO: refactor this out...
  std::string executableFormat = mf->GetSafeDefinition(
                                                    "CMAKE_EXECUTABLE_FORMAT");
  if (executableFormat == "ELF")
    {
    fout << "<extension id=\"org.eclipse.cdt.core.ELF\""
            " point=\"org.eclipse.cdt.core.BinaryParser\"/>\n"
            ;
    fout << "<extension id=\"org.eclipse.cdt.core.GNU_ELF\""
            " point=\"org.eclipse.cdt.core.BinaryParser\">\n"
            "<attribute key=\"addr2line\" value=\"addr2line\"/>\n"
            "<attribute key=\"c++filt\" value=\"c++filt\"/>\n"
            "</extension>\n"
            ;
    }
  else
    {
    std::string systemName = mf->GetSafeDefinition("CMAKE_SYSTEM_NAME");
    if (systemName == "CYGWIN")
      {
      fout << "<extension id=\"org.eclipse.cdt.core.Cygwin_PE\""
              " point=\"org.eclipse.cdt.core.BinaryParser\">\n"
              "<attribute key=\"addr2line\" value=\"addr2line\"/>\n"
              "<attribute key=\"c++filt\" value=\"c++filt\"/>\n"
              "<attribute key=\"cygpath\" value=\"cygpath\"/>\n"
              "<attribute key=\"nm\" value=\"nm\"/>\n"
              "</extension>\n"
              ;
      }
    else if (systemName == "Windows")
      {
      fout << "<extension id=\"org.eclipse.cdt.core.PE\""
              " point=\"org.eclipse.cdt.core.BinaryParser\"/>\n"
              ;
      }
    else if (systemName == "Darwin")
      {
      fout << "<extension id=\"org.eclipse.cdt.core.MachO\""
              " point=\"org.eclipse.cdt.core.BinaryParser\">\n"
              "<attribute key=\"c++filt\" value=\"c++filt\"/>\n"
              "</extension>\n"
              ;
      }
    else
      {
      // *** Should never get here ***
      fout << "<error_toolchain_type/>\n";
      }
    }

  fout << "</extensions>\n"
          "</storageModule>\n"
          ;
  
  // ???
  fout << 
    "<storageModule moduleId=\"org.eclipse.cdt.core.language.mapping\">\n"
    "<project-mappings/>\n"
    "</storageModule>\n"
    ;

  // ???
  fout<<"<storageModule moduleId=\"org.eclipse.cdt.core.externalSettings\"/>\n"
          ;

  // set the path entries (includes, libs, source dirs, etc.)
  fout << "<storageModule moduleId=\"org.eclipse.cdt.core.pathentry\">\n"
          ;
  // 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;
  for (std::vector<std::string>::const_iterator
       it = this->SrcLinkedResources.begin();
       it != this->SrcLinkedResources.end();
       ++it)
    {
    fout << "<pathentry kind=\"src\" path=\"" << *it << "\"/>\n";

    // exlude source directory from output search path
    // - only if not named the same as an output directory
    if (!cmSystemTools::FileIsDirectory(
           std::string(this->HomeOutputDirectory + "/" + *it).c_str()))
      {
      excludeFromOut += *it + "/|";
      }
    }
  excludeFromOut += "**/CMakeFiles/";
  fout << "<pathentry excluding=\"" << excludeFromOut
       << "\" kind=\"out\" path=\"\"/>\n";
  // add output entry for EXECUTABLE_OUTPUT_PATH and LIBRARY_OUTPUT_PATH
  // - if it is a subdir of homeOutputDirectory, there is no need to add it
  // - if it is not then create a linked resource and add the linked name
  //   but check it doesn't conflict with other linked resources names
  for (std::vector<std::string>::const_iterator
       it = this->OutLinkedResources.begin();
       it != this->OutLinkedResources.end();
       ++it)
    {
    fout << "<pathentry kind=\"out\" path=\"" << *it << "\"/>\n";
    }

  // add pre-processor definitions to allow eclipse to gray out sections
  emmited.clear();
  for (std::vector<cmLocalGenerator*>::const_iterator
        it = this->GlobalGenerator->GetLocalGenerators().begin();
       it != this->GlobalGenerator->GetLocalGenerators().end();
       ++it)
    {

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

      for(std::vector<std::string>::const_iterator di = defs.begin();
          di != defs.end(); ++di)
        {
        std::string::size_type equals = di->find('=', 0);
        std::string::size_type enddef = di->length();

        std::string def;
        std::string val;
        if (equals != std::string::npos && equals < enddef)
          {
          // we have -DFOO=BAR
          def = di->substr(0, equals);
          val = di->substr(equals + 1, enddef - equals + 1);
          }
        else
          {
          // we have -DFOO
          def = *di;
          }
          
        // insert the definition if not already added.
        if(emmited.find(def) == emmited.end())
          {
          emmited.insert(def);
          fout << "<pathentry kind=\"mac\" name=\"" << def
               << "\" path=\"\" value=\"" << this->EscapeForXML(val) 
               << "\"/>\n";
          }
        }
      }
    }
  // add system defined c macros
  const char* cDefs=mf->GetDefinition("CMAKE_ECLIPSE_C_SYSTEM_DEFINED_MACROS");
  if(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);
          fout << "<pathentry kind=\"mac\" name=\"" << def
               << "\" path=\"\" value=\"" << this->EscapeForXML(val)
               << "\"/>\n";
          }
        }
      }
    }
  // add system defined c++ macros
  const char* cxxDefs = mf->GetDefinition(
                                    "CMAKE_ECLIPSE_CXX_SYSTEM_DEFINED_MACROS");
  if(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);
          fout << "<pathentry kind=\"mac\" name=\"" << def
               << "\" path=\"\" value=\"" << this->EscapeForXML(val)
               << "\"/>\n";
          }
        }
      }
    }

  // include dirs
  emmited.clear();
  for (std::vector<cmLocalGenerator*>::const_iterator
        it = this->GlobalGenerator->GetLocalGenerators().begin();
       it != this->GlobalGenerator->GetLocalGenerators().end();
       ++it)
    {
    const std::vector<std::string>& includeDirs
      = (*it)->GetMakefile()->GetIncludeDirectories();
    this->AppendIncludeDirectories(fout, includeDirs, emmited);
    }
  // now also the system include directories, in case we found them in 
  // CMakeSystemSpecificInformation.cmake. This makes Eclipse find the 
  // standard headers.
  mf->GetDefinition("CMAKE_ECLIPSE_C_SYSTEM_INCLUDE_DIRS");
  std::string compiler = mf->GetSafeDefinition("CMAKE_C_COMPILER");
  if (!compiler.empty())
    {
    std::string systemIncludeDirs = mf->GetSafeDefinition(
                                      "CMAKE_ECLIPSE_C_SYSTEM_INCLUDE_DIRS");
    std::vector<std::string> dirs;
    cmSystemTools::ExpandListArgument(systemIncludeDirs.c_str(), dirs);
    this->AppendIncludeDirectories(fout, dirs, emmited);
    }
  compiler = mf->GetSafeDefinition("CMAKE_CXX_COMPILER");
  if (!compiler.empty())
    {
    std::string systemIncludeDirs = mf->GetSafeDefinition(
                                      "CMAKE_ECLIPSE_CXX_SYSTEM_INCLUDE_DIRS");
    std::vector<std::string> dirs;
    cmSystemTools::ExpandListArgument(systemIncludeDirs.c_str(), dirs);
    this->AppendIncludeDirectories(fout, dirs, emmited);
    }

  fout << "</storageModule>\n";

  // add build targets
  fout << 
    "<storageModule moduleId=\"org.eclipse.cdt.make.core.buildtargets\">\n"
    "<buildTargets>\n"
    ;
  emmited.clear();
  const std::string make = mf->GetRequiredDefinition("CMAKE_MAKE_PROGRAM");
  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 (std::vector<cmLocalGenerator*>::const_iterator
        it = this->GlobalGenerator->GetLocalGenerators().begin();
       it != this->GlobalGenerator->GetLocalGenerators().end();
       ++it)
    {
    const cmTargets& targets = (*it)->GetMakefile()->GetTargets();
    cmMakefile* makefile=(*it)->GetMakefile();
    std::string subdir = (*it)->Convert(makefile->GetCurrentOutputDirectory(),
                           cmLocalGenerator::HOME_OUTPUT);
    if (subdir == ".")
      {
      subdir = "";
      }

    for(cmTargets::const_iterator ti=targets.begin(); ti!=targets.end(); ++ti)
      {
      switch(ti->second.GetType())
        {
        case cmTarget::GLOBAL_TARGET:
          {
          bool insertTarget = false;
          // Only add the global targets from CMAKE_BINARY_DIR, 
          // not from the subdirs
          if (subdir.empty())
           {
           insertTarget = true;
           // only add the "edit_cache" target if it's not ccmake, because
           // this will not work within the IDE
           if (ti->first == "edit_cache")
             {
             const char* editCommand = makefile->GetDefinition
                                                        ("CMAKE_EDIT_COMMAND");
             if (editCommand == 0)
               {
               insertTarget = false;
               }
             else if (strstr(editCommand, "ccmake")!=NULL)
               {
               insertTarget = false;
               }
             }
           }
         if (insertTarget)
           {
           this->AppendTarget(fout, ti->first, make, subdir, ": ");
           }
         }
         break;
       case cmTarget::UTILITY:
         // Add all utility targets, except the Nightly/Continuous/
         // Experimental-"sub"targets as e.g. NightlyStart
         if (((ti->first.find("Nightly")==0)   &&(ti->first!="Nightly"))
          || ((ti->first.find("Continuous")==0)&&(ti->first!="Continuous"))
          || ((ti->first.find("Experimental")==0) 
                                            && (ti->first!="Experimental")))
           {
           break;
           }

         this->AppendTarget(fout, ti->first, make, subdir, ": ");
         break;
       case cmTarget::EXECUTABLE:
       case cmTarget::STATIC_LIBRARY:
       case cmTarget::SHARED_LIBRARY:
       case cmTarget::MODULE_LIBRARY:
         {
         const char* prefix = (ti->second.GetType()==cmTarget::EXECUTABLE ?
                                                          "[exe] " : "[lib] ");
         this->AppendTarget(fout, ti->first, make, subdir, prefix);
         std::string fastTarget = ti->first;
         fastTarget += "/fast";
         this->AppendTarget(fout, fastTarget, make, subdir, prefix);
         }
         break;
        // ignore these:
        case cmTarget::INSTALL_FILES:
        case cmTarget::INSTALL_PROGRAMS:
        case cmTarget::INSTALL_DIRECTORY:
        default:
          break;
        }
      }
      
    // insert the all and clean targets in every subdir
    if (!allTarget.empty())
      {
      this->AppendTarget(fout, allTarget, make, subdir, ": ");
      }
    if (!cleanTarget.empty())
      {
      this->AppendTarget(fout, cleanTarget, make, subdir, ": ");
      }

    //insert rules for compiling, preprocessing and assembling individual files
    cmLocalUnixMakefileGenerator3* lumg=(cmLocalUnixMakefileGenerator3*)*it;
    std::vector<std::string> objectFileTargets;
    lumg->GetIndividualFileTargets(objectFileTargets);
    for(std::vector<std::string>::const_iterator fit=objectFileTargets.begin();
        fit != objectFileTargets.end();
        ++fit)
      {
      const char* prefix = "[obj] ";
      if ((*fit)[fit->length()-1] == 's')
        {
        prefix = "[to asm] ";
        }
      else if ((*fit)[fit->length()-1] == 'i')
        {
        prefix = "[pre] ";
        }
      this->AppendTarget(fout, *fit, make, subdir, prefix);
      }
    }

  fout << "</buildTargets>\n"
          "</storageModule>\n"
          ;

  this->AppendStorageScanners(fout, *mf);

  fout << "</cconfiguration>\n"
          "</storageModule>\n"
          "<storageModule moduleId=\"cdtBuildSystem\" version=\"4.0.0\">\n"
          "<project id=\"" << mf->GetProjectName() << ".null.1\""
          " name=\"" << mf->GetProjectName() << "\"/>\n"
          "</storageModule>\n"
          "</cproject>\n"
          ;
}

//----------------------------------------------------------------------------
std::string
cmExtraEclipseCDT4Generator::GetEclipsePath(const std::string& path)
{
#if defined(__CYGWIN__)
  std::string cmd = "cygpath -m " + path;
  std::string out;
  if (!cmSystemTools::RunCommand(cmd.c_str(), out, 0, false))
    {
    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.size() > 0 &&
         (outputBasename[outputBasename.size() - 1] == '/' ||
          outputBasename[outputBasename.size() - 1] == '\\'))
    {
    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;
}

std::string cmExtraEclipseCDT4Generator::EscapeForXML(const std::string& value)
{
  std::string str = value;
  cmSystemTools::ReplaceString(str, "&", "&amp;");
  cmSystemTools::ReplaceString(str, "<", "&lt;");
  cmSystemTools::ReplaceString(str, ">", "&gt;");
  cmSystemTools::ReplaceString(str, "\"", "&quot;");
  // NOTE: This one is not necessary, since as of Eclipse CDT4 it will
  //       automatically change this to the original value (').
  //cmSystemTools::ReplaceString(str, "'", "&apos;");
  return str;
}

//----------------------------------------------------------------------------
// Helper functions
//----------------------------------------------------------------------------
void cmExtraEclipseCDT4Generator
::AppendStorageScanners(cmGeneratedFileStream& fout, 
                        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");
  if (compiler.empty())
    {
    compiler = makefile.GetSafeDefinition("CMAKE_CXX_COMPILER");
    }
  if (compiler.empty())  //Hmm, what to do now ?
    {
    compiler = "gcc";
    }


  // the following right now hardcodes gcc behaviour :-/
  fout << 
    "<storageModule moduleId=\"scannerConfiguration\">\n"
    "<autodiscovery enabled=\"true\" problemReportingEnabled=\"true\""
    " selectedProfileId="
    "\"org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile\"/>\n"
    ;
  cmExtraEclipseCDT4Generator::AppendScannerProfile(fout,
    "org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile",
    true, "", true, "specsFile",
    "-E -P -v -dD ${plugin_state_location}/${specs_file}",
    compiler, true, true);
  cmExtraEclipseCDT4Generator::AppendScannerProfile(fout,
    "org.eclipse.cdt.make.core.GCCStandardMakePerFileProfile",
    true, "", true, "makefileGenerator",
    "-f ${project_name}_scd.mk",
    make, true, true);

  fout << "</storageModule>\n";
}

// 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(cmGeneratedFileStream& fout,
                                               const std::string&     target,
                                               const std::string&     make,
                                               const std::string&     path,
                                               const char* prefix)
{
  fout << 
    "<target name=\"" << prefix << target << "\""
    " path=\"" << path.c_str() << "\""
    " targetID=\"org.eclipse.cdt.make.MakeTargetBuilder\">\n"
    "<buildCommand>"
    << cmExtraEclipseCDT4Generator::GetEclipsePath(make)
    << "</buildCommand>\n"
    "<buildArguments/>\n"
    "<buildTarget>" << target << "</buildTarget>\n"
    "<stopOnError>true</stopOnError>\n"
    "<useDefaultCommand>false</useDefaultCommand>\n"
    "</target>\n"
    ;
}

void cmExtraEclipseCDT4Generator
::AppendScannerProfile(cmGeneratedFileStream& fout,
                       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)
{
  fout << 
    "<profile id=\"" << profileID << "\">\n"
    "<buildOutputProvider>\n"
    "<openAction enabled=\"" << (openActionEnabled ? "true" : "false")
    << "\" filePath=\"" << openActionFilePath << "\"/>\n"
    "<parser enabled=\"" << (pParserEnabled ? "true" : "false") << "\"/>\n"
    "</buildOutputProvider>\n"
    "<scannerInfoProvider id=\"" << scannerInfoProviderID << "\">\n"
    "<runAction arguments=\"" << runActionArguments << "\""
    " command=\"" << runActionCommand
    << "\" useDefault=\"" << (runActionUseDefault ? "true":"false") << "\"/>\n"
    "<parser enabled=\"" << (sipParserEnabled ? "true" : "false") << "\"/>\n"
    "</scannerInfoProvider>\n"
    "</profile>\n"
    ;
}

void cmExtraEclipseCDT4Generator
::AppendLinkedResource (cmGeneratedFileStream& fout,
                        const std::string&     name,
                        const std::string&     path)
{
  fout <<
    "\t\t<link>\n"
    "\t\t\t<name>" << name << "</name>\n"
    "\t\t\t<type>2</type>\n"
    "\t\t\t<location>"
    << path
    << "</location>\n"
    "\t\t</link>\n"
    ;
}

bool cmExtraEclipseCDT4Generator
::AppendOutLinkedResource(cmGeneratedFileStream& fout,
                          const std::string&     defname,
                          const std::string&     altdefname)
{
  if (defname.empty() && altdefname.empty())
    {
    return false;
    }

  std::string outputPath = (defname.empty() ? altdefname : defname);

  if (!cmSystemTools::FileIsFullPath(outputPath.c_str()))
    {
    outputPath = this->HomeOutputDirectory + "/" + outputPath;
    }
  if (cmSystemTools::IsSubDirectory(outputPath.c_str(),
                                    this->HomeOutputDirectory.c_str()))
    {
    return false;
    }

  std::string name = this->GetPathBasename(outputPath);

  // make sure linked resource name is unique
  while (this->GlobalGenerator->GetProjectMap().find(name)
      != this->GlobalGenerator->GetProjectMap().end())
    {
    name += "_";
    }

  if (std::find(this->OutLinkedResources.begin(),
                this->OutLinkedResources.end(),
                name)
      != this->OutLinkedResources.end())
    {
    return false;
    }
  else
    {
    this->AppendLinkedResource(fout, name,
                               this->GetEclipsePath(outputPath));
    this->OutLinkedResources.push_back(name);
    return true;
    }
}

