/*============================================================================
  CMake - Cross Platform Makefile Generator
  Copyright 2000-2009 Kitware, Inc., Insight Software Consortium

  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 "cmGlobalGenerator.h"
#include "cmLocalVisualStudio6Generator.h"
#include "cmMakefile.h"
#include "cmSystemTools.h"
#include "cmSourceFile.h"
#include "cmGeneratorTarget.h"
#include "cmCustomCommandGenerator.h"
#include "cmake.h"

#include "cmComputeLinkInformation.h"

#include <cmsys/RegularExpression.hxx>
#include <cmsys/FStream.hxx>

cmLocalVisualStudio6Generator
::cmLocalVisualStudio6Generator(cmGlobalGenerator* gg, cmMakefile* mf):
  cmLocalVisualStudioGenerator(gg, mf)
{
}

cmLocalVisualStudio6Generator::~cmLocalVisualStudio6Generator()
{
}

//----------------------------------------------------------------------------
// Helper class to write build events.
class cmLocalVisualStudio6Generator::EventWriter
{
public:
  EventWriter(cmLocalVisualStudio6Generator* lg,
              const std::string& config, std::string& code):
    LG(lg), Config(config), Code(code), First(true) {}
  void Start(const char* event)
    {
    this->First = true;
    this->Event = event;
    }
  void Finish()
    {
    this->Code += (this->First? "" : "\n");
    }
  void Write(std::vector<cmCustomCommand> const& ccs)
    {
    for(std::vector<cmCustomCommand>::const_iterator ci = ccs.begin();
        ci != ccs.end(); ++ci)
      {
      this->Write(*ci);
      }
    }
  void Write(cmCustomCommand const& cc)
    {
    cmCustomCommandGenerator ccg(cc, this->Config, this->LG);
    if(this->First)
      {
      this->Code += this->Event + "_Cmds=";
      this->First = false;
      }
    else
      {
      this->Code += "\\\n\t";
      }
    this->Code += this->LG->ConstructScript(ccg, "\\\n\t");
    }
private:
  cmLocalVisualStudio6Generator* LG;
  std::string Config;
  std::string& Code;
  bool First;
  std::string Event;
};

void cmLocalVisualStudio6Generator::AddCMakeListsRules()
{
  cmTargets &tgts = this->Makefile->GetTargets();
  for(cmTargets::iterator l = tgts.begin();
      l != tgts.end(); l++)
    {
    if (l->second.GetType() == cmTarget::INTERFACE_LIBRARY
        || l->second.GetType() == cmTarget::GLOBAL_TARGET)
      {
      continue;
      }

    // Add a rule to regenerate the build system when the target
    // specification source changes.
    const char* suppRegenRule =
      this->Makefile->GetDefinition("CMAKE_SUPPRESS_REGENERATION");
    if (!cmSystemTools::IsOn(suppRegenRule))
      {
      this->AddDSPBuildRule(l->second);
      }
    }
}

void cmLocalVisualStudio6Generator::Generate()
{
  this->OutputDSPFile();
}

void cmLocalVisualStudio6Generator::OutputDSPFile()
{
  // If not an in source build, then create the output directory
  if(strcmp(this->Makefile->GetCurrentBinaryDirectory(),
            this->Makefile->GetHomeDirectory()) != 0)
    {
    if(!cmSystemTools::MakeDirectory
       (this->Makefile->GetCurrentBinaryDirectory()))
      {
      cmSystemTools::Error("Error creating directory ",
                           this->Makefile->GetCurrentBinaryDirectory());
      }
    }

  // Create the DSP or set of DSP's for libraries and executables

  cmTargets &tgts = this->Makefile->GetTargets();

  // build any targets
  for(cmTargets::iterator l = tgts.begin();
      l != tgts.end(); l++)
    {
    switch(l->second.GetType())
      {
      case cmTarget::STATIC_LIBRARY:
      case cmTarget::OBJECT_LIBRARY:
        this->SetBuildType(STATIC_LIBRARY, l->first.c_str(), l->second);
        break;
      case cmTarget::SHARED_LIBRARY:
      case cmTarget::MODULE_LIBRARY:
        this->SetBuildType(DLL, l->first.c_str(), l->second);
        break;
      case cmTarget::EXECUTABLE:
        this->SetBuildType(EXECUTABLE,l->first.c_str(), l->second);
        break;
      case cmTarget::UTILITY:
      case cmTarget::GLOBAL_TARGET:
        this->SetBuildType(UTILITY, l->first.c_str(), l->second);
        break;
      case cmTarget::INTERFACE_LIBRARY:
        continue;
      default:
        cmSystemTools::Error("Bad target type: ", l->first.c_str());
        break;
      }
    // INCLUDE_EXTERNAL_MSPROJECT command only affects the workspace
    // so don't build a projectfile for it
    const char* path =
      l->second.GetProperty("EXTERNAL_MSPROJECT");
    if(!path)
      {
      // check to see if the dsp is going into a sub-directory
      std::string::size_type pos = l->first.rfind('/');
      if(pos != std::string::npos)
        {
        std::string dir = this->Makefile->GetCurrentBinaryDirectory();
        dir += "/";
        dir += l->first.substr(0, pos);
        if(!cmSystemTools::MakeDirectory(dir.c_str()))
          {
          cmSystemTools::Error("Error creating directory: ", dir.c_str());
          }
        }
      this->CreateSingleDSP(l->first.c_str(),l->second);
      }
    }
}

// Utility function to make a valid VS6 *.dsp filename out
// of a CMake target name:
//
extern std::string GetVS6TargetName(const std::string& targetName);

void cmLocalVisualStudio6Generator::CreateSingleDSP(const std::string& lname,
                                                    cmTarget &target)
{
  // add to the list of projects
  std::string pname = GetVS6TargetName(lname);

  // create the dsp.cmake file
  std::string fname;
  fname = this->Makefile->GetCurrentBinaryDirectory();
  fname += "/";
  fname += pname;
  fname += ".dsp";
  // save the name of the real dsp file
  std::string realDSP = fname;
  fname += ".cmake";
  cmsys::ofstream fout(fname.c_str());
  if(!fout)
    {
    cmSystemTools::Error("Error Writing ", fname.c_str());
    cmSystemTools::ReportLastSystemError("");
    }
  this->WriteDSPFile(fout,pname.c_str(),target);
  fout.close();
  // if the dsp file has changed, then write it.
  cmSystemTools::CopyFileIfDifferent(fname.c_str(), realDSP.c_str());
}


void cmLocalVisualStudio6Generator::AddDSPBuildRule(cmTarget& tgt)
{
  std::string dspname = GetVS6TargetName(tgt.GetName());
  dspname += ".dsp.cmake";
  cmCustomCommandLine commandLine;
  commandLine.push_back(cmSystemTools::GetCMakeCommand());
  std::string makefileIn = this->Makefile->GetCurrentSourceDirectory();
  makefileIn += "/";
  makefileIn += "CMakeLists.txt";
  if(!cmSystemTools::FileExists(makefileIn.c_str()))
    {
    return;
    }
  std::string comment = "Building Custom Rule ";
  comment += makefileIn;
  std::string args;
  args = "-H";
  args += this->Makefile->GetHomeDirectory();
  commandLine.push_back(args);
  args = "-B";
  args += this->Makefile->GetHomeOutputDirectory();
  commandLine.push_back(args);

  std::vector<std::string> const& listFiles = this->Makefile->GetListFiles();

  cmCustomCommandLines commandLines;
  commandLines.push_back(commandLine);
  const char* no_working_directory = 0;
  this->Makefile->AddCustomCommandToOutput(dspname.c_str(), listFiles,
                                           makefileIn.c_str(), commandLines,
                                           comment.c_str(),
                                           no_working_directory, true);
  if(this->Makefile->GetSource(makefileIn.c_str()))
    {
    tgt.AddSource(makefileIn);
    }
  else
    {
    cmSystemTools::Error("Error adding rule for ", makefileIn.c_str());
    }
}


void cmLocalVisualStudio6Generator::WriteDSPFile(std::ostream& fout,
                                                 const std::string& libName,
                                                 cmTarget &target)
{
  // For utility targets need custom command since pre- and post-
  // build does not do anything in Visual Studio 6.  In order for the
  // rules to run in the correct order as custom commands, we need
  // special care for dependencies.  The first rule must depend on all
  // the dependencies of all the rules.  The later rules must each
  // depend only on the previous rule.
  if ((target.GetType() == cmTarget::UTILITY ||
      target.GetType() == cmTarget::GLOBAL_TARGET) &&
      (!target.GetPreBuildCommands().empty() ||
       !target.GetPostBuildCommands().empty()))
    {
    // Accumulate the dependencies of all the commands.
    std::vector<std::string> depends;
    for (std::vector<cmCustomCommand>::const_iterator cr =
           target.GetPreBuildCommands().begin();
         cr != target.GetPreBuildCommands().end(); ++cr)
      {
      depends.insert(depends.end(),
                     cr->GetDepends().begin(), cr->GetDepends().end());
      }
    for (std::vector<cmCustomCommand>::const_iterator cr =
           target.GetPostBuildCommands().begin();
         cr != target.GetPostBuildCommands().end(); ++cr)
      {
      depends.insert(depends.end(),
                     cr->GetDepends().begin(), cr->GetDepends().end());
      }

    // Add the pre- and post-build commands in order.
    int count = 1;
    for (std::vector<cmCustomCommand>::const_iterator cr =
           target.GetPreBuildCommands().begin();
         cr != target.GetPreBuildCommands().end(); ++cr)
      {
      this->AddUtilityCommandHack(target, count++, depends, *cr);
      }
    for (std::vector<cmCustomCommand>::const_iterator cr =
           target.GetPostBuildCommands().begin();
         cr != target.GetPostBuildCommands().end(); ++cr)
      {
      this->AddUtilityCommandHack(target, count++, depends, *cr);
      }
    }

  // We may be modifying the source groups temporarily, so make a copy.
  std::vector<cmSourceGroup> sourceGroups = this->Makefile->GetSourceGroups();

  cmGeneratorTarget* gt =
    this->GlobalGenerator->GetGeneratorTarget(&target);

  // get the classes from the source lists then add them to the groups
  std::vector<cmSourceFile*> classes;
  if (!gt->GetConfigCommonSourceFiles(classes))
    {
    return;
    }

  // now all of the source files have been properly assigned to the target
  // now stick them into source groups using the reg expressions
  for(std::vector<cmSourceFile*>::const_iterator i = classes.begin();
      i != classes.end(); i++)
    {
    if (!(*i)->GetObjectLibrary().empty())
      {
      continue;
      }

    // Add the file to the list of sources.
    std::string source = (*i)->GetFullPath();
    cmSourceGroup* sourceGroup =
      this->Makefile->FindSourceGroup(source.c_str(), sourceGroups);
    sourceGroup->AssignSource(*i);
    // while we are at it, if it is a .rule file then for visual studio 6 we
    // must generate it
    if ((*i)->GetPropertyAsBool("__CMAKE_RULE"))
      {
      if(!cmSystemTools::FileExists(source.c_str()))
        {
        cmSystemTools::ReplaceString(source, "$(IntDir)/", "");
        // Make sure the path exists for the file
        std::string path = cmSystemTools::GetFilenamePath(source);
        cmSystemTools::MakeDirectory(path.c_str());
#if defined(_WIN32) || defined(__CYGWIN__)
        cmsys::ofstream sourceFout(source.c_str(),
                           std::ios::binary | std::ios::out
                           | std::ios::trunc);
#else
        cmsys::ofstream sourceFout(source.c_str(),
                           std::ios::out | std::ios::trunc);
#endif
        if(sourceFout)
          {
          sourceFout.write("# generated from CMake",22);
          sourceFout.flush();
          sourceFout.close();
          }
        }
      }
    }

  // Write the DSP file's header.
  this->WriteDSPHeader(fout, libName, target, sourceGroups);


  // Loop through every source group.
  for(std::vector<cmSourceGroup>::const_iterator sg = sourceGroups.begin();
      sg != sourceGroups.end(); ++sg)
    {
    this->WriteGroup(&(*sg), target, fout, libName);
    }

  // Write the DSP file's footer.
  this->WriteDSPFooter(fout);
}

void cmLocalVisualStudio6Generator
::WriteGroup(const cmSourceGroup *sg, cmTarget& target,
             std::ostream &fout, const std::string& libName)
{
  cmGeneratorTarget* gt =
    this->GlobalGenerator->GetGeneratorTarget(&target);
  const std::vector<const cmSourceFile *> &sourceFiles =
    sg->GetSourceFiles();
  // If the group is empty, don't write it at all.

  if(sourceFiles.empty() && sg->GetGroupChildren().empty())
    {
    return;
    }

  // If the group has a name, write the header.
  std::string name = sg->GetName();
  if(name != "")
    {
    this->WriteDSPBeginGroup(fout, name.c_str(), "");
    }

  // Loop through each source in the source group.
  for(std::vector<const cmSourceFile *>::const_iterator sf =
        sourceFiles.begin(); sf != sourceFiles.end(); ++sf)
    {
    if (!(*sf)->GetObjectLibrary().empty())
      {
      continue;
      }

    std::string source = (*sf)->GetFullPath();
    const cmCustomCommand *command =
      (*sf)->GetCustomCommand();
    std::string compileFlags;
    std::vector<std::string> depends;
    std::string objectNameDir;
    if(gt->HasExplicitObjectName(*sf))
      {
      objectNameDir = cmSystemTools::GetFilenamePath(gt->GetObjectName(*sf));
      }

    // Add per-source file flags.
    if(const char* cflags = (*sf)->GetProperty("COMPILE_FLAGS"))
      {
      compileFlags += cflags;
      }

    const std::string& lang = this->GetSourceFileLanguage(*(*sf));
    if(lang == "CXX")
      {
      // force a C++ file type
      compileFlags += " /TP ";
      }
    else if(lang == "C")
      {
      // force to c file type
      compileFlags += " /TC ";
      }

    // Add per-source and per-configuration preprocessor definitions.
    std::map<std::string, std::string> cdmap;

      {
      std::set<std::string> targetCompileDefinitions;

      this->AppendDefines(targetCompileDefinitions,
                        (*sf)->GetProperty("COMPILE_DEFINITIONS"));
      this->JoinDefines(targetCompileDefinitions, compileFlags, lang);
      }

    if(const char* cdefs = (*sf)->GetProperty("COMPILE_DEFINITIONS_DEBUG"))
      {
      std::set<std::string> debugCompileDefinitions;
      this->AppendDefines(debugCompileDefinitions, cdefs);
      this->JoinDefines(debugCompileDefinitions, cdmap["DEBUG"], lang);
      }
    if(const char* cdefs = (*sf)->GetProperty("COMPILE_DEFINITIONS_RELEASE"))
      {
      std::set<std::string> releaseCompileDefinitions;
      this->AppendDefines(releaseCompileDefinitions, cdefs);
      this->JoinDefines(releaseCompileDefinitions, cdmap["RELEASE"], lang);
      }
    if(const char* cdefs =
       (*sf)->GetProperty("COMPILE_DEFINITIONS_MINSIZEREL"))
      {
      std::set<std::string> minsizerelCompileDefinitions;
      this->AppendDefines(minsizerelCompileDefinitions, cdefs);
      this->JoinDefines(minsizerelCompileDefinitions, cdmap["MINSIZEREL"],
                        lang);
      }
    if(const char* cdefs =
       (*sf)->GetProperty("COMPILE_DEFINITIONS_RELWITHDEBINFO"))
      {
      std::set<std::string> relwithdebinfoCompileDefinitions;
      this->AppendDefines(relwithdebinfoCompileDefinitions, cdefs);
      this->JoinDefines(relwithdebinfoCompileDefinitions,
                        cdmap["RELWITHDEBINFO"], lang);
      }

    bool excludedFromBuild =
      (!lang.empty() && (*sf)->GetPropertyAsBool("HEADER_FILE_ONLY"));

    // Check for extra object-file dependencies.
    const char* dependsValue = (*sf)->GetProperty("OBJECT_DEPENDS");
    if(dependsValue)
      {
      cmSystemTools::ExpandListArgument(dependsValue, depends);
      }
    if (GetVS6TargetName(source) != libName ||
      target.GetType() == cmTarget::UTILITY ||
      target.GetType() == cmTarget::GLOBAL_TARGET)
      {
      fout << "# Begin Source File\n\n";

      // Tell MS-Dev what the source is.  If the compiler knows how to
      // build it, then it will.
      fout << "SOURCE=" <<
        this->ConvertToOutputFormat(source.c_str(), SHELL) << "\n\n";
      if(!depends.empty())
        {
        // Write out the dependencies for the rule.
        fout << "USERDEP__HACK=";
        for(std::vector<std::string>::const_iterator d = depends.begin();
            d != depends.end(); ++d)
          {
          fout << "\\\n\t" <<
            this->ConvertToOutputFormat(d->c_str(), SHELL);
          }
        fout << "\n";
        }
      if (command)
        {
        const char* flags = compileFlags.size() ? compileFlags.c_str(): 0;
        this->WriteCustomRule(fout, source.c_str(), *command, flags);
        }
      else if(!compileFlags.empty() || !objectNameDir.empty() ||
              excludedFromBuild || !cdmap.empty())
        {
        for(std::vector<std::string>::iterator i
              = this->Configurations.begin();
            i != this->Configurations.end(); ++i)
          {
          // Strip the subdirectory name out of the configuration name.
          std::string config = this->GetConfigName(*i);
          if (i == this->Configurations.begin())
            {
            fout << "!IF  \"$(CFG)\" == " << i->c_str() << std::endl;
            }
          else
            {
            fout << "!ELSEIF  \"$(CFG)\" == " << i->c_str() << std::endl;
            }
          if(excludedFromBuild)
            {
            fout << "# PROP Exclude_From_Build 1\n";
            }
          if(!compileFlags.empty())
            {
            fout << "\n# ADD CPP " << compileFlags << "\n\n";
            }
          std::map<std::string, std::string>::iterator cdi =
            cdmap.find(cmSystemTools::UpperCase(config));
          if(cdi != cdmap.end() && !cdi->second.empty())
            {
            fout << "\n# ADD CPP " << cdi->second << "\n\n";
            }
          if(!objectNameDir.empty())
            {
            // Setup an alternate object file directory.
            fout << "\n# PROP Intermediate_Dir \""
                 << config << "/" << objectNameDir << "\"\n\n";
            }
          }
        fout << "!ENDIF\n\n";
        }
      fout << "# End Source File\n";
      }
    }

  std::vector<cmSourceGroup> const& children  = sg->GetGroupChildren();

  for(unsigned int i=0;i<children.size();++i)
    {
    this->WriteGroup(&children[i], target, fout, libName);
    }




  // If the group has a name, write the footer.
  if(name != "")
    {
    this->WriteDSPEndGroup(fout);
    }

}


void
cmLocalVisualStudio6Generator
::AddUtilityCommandHack(cmTarget& target, int count,
                        std::vector<std::string>& depends,
                        const cmCustomCommand& origCommand)
{
  // Create a fake output that forces the rule to run.
  char* output = new char[(strlen(this->Makefile->GetCurrentBinaryDirectory())
                           + target.GetName().size() + 30)];
  sprintf(output,"%s/%s_force_%i", this->Makefile->GetCurrentBinaryDirectory(),
          target.GetName().c_str(), count);
  const char* comment = origCommand.GetComment();
  if(!comment && origCommand.GetOutputs().empty())
    {
    comment = "<hack>";
    }

  // Add the rule with the given dependencies and commands.
  std::string no_main_dependency = "";
  if(cmSourceFile* outsf =
     this->Makefile->AddCustomCommandToOutput(
       output, depends, no_main_dependency,
       origCommand.GetCommandLines(), comment,
       origCommand.GetWorkingDirectory().c_str()))
    {
    target.AddSource(outsf->GetFullPath());
    }

  // Replace the dependencies with the output of this rule so that the
  // next rule added will run after this one.
  depends.clear();
  depends.push_back(output);

  // Free the fake output name.
  delete [] output;
}

void
cmLocalVisualStudio6Generator
::WriteCustomRule(std::ostream& fout,
                  const char* source,
                  const cmCustomCommand& command,
                  const char* flags)
{
  // Write the rule for each configuration.
  std::vector<std::string>::iterator i;
  for(i = this->Configurations.begin(); i != this->Configurations.end(); ++i)
    {
    std::string config = this->GetConfigName(*i);
    cmCustomCommandGenerator ccg(command, config, this);
    std::string comment =
      this->ConstructComment(ccg, "Building Custom Rule $(InputPath)");
    if(comment == "<hack>")
      {
      comment = "";
      }

    std::string script =
      this->ConstructScript(ccg, "\\\n\t");

    if (i == this->Configurations.begin())
      {
      fout << "!IF  \"$(CFG)\" == " << i->c_str() << std::endl;
      }
    else
      {
      fout << "!ELSEIF  \"$(CFG)\" == " << i->c_str() << std::endl;
      }
    if(flags)
      {
      fout << "\n# ADD CPP " << flags << "\n\n";
      }
    // Write out the dependencies for the rule.
    fout << "USERDEP__HACK=";
    for(std::vector<std::string>::const_iterator d =
          ccg.GetDepends().begin();
        d != ccg.GetDepends().end();
        ++d)
      {
      // Lookup the real name of the dependency in case it is a CMake target.
      std::string dep;
      if(this->GetRealDependency(d->c_str(), config.c_str(), dep))
        {
        fout << "\\\n\t" <<
          this->ConvertToOutputFormat(dep.c_str(), SHELL);
        }
      }
    fout << "\n";

    fout << "# PROP Ignore_Default_Tool 1\n";
    fout << "# Begin Custom Build -";
    if(!comment.empty())
      {
      fout << " " << comment.c_str();
      }
    fout << "\n\n";
    if(ccg.GetOutputs().empty())
      {
      fout << source
           << "_force :  \"$(SOURCE)\" \"$(INTDIR)\" \"$(OUTDIR)\"\n\t";
      fout << script.c_str() << "\n\n";
      }
    else
      {
      for(std::vector<std::string>::const_iterator o =
          ccg.GetOutputs().begin();
          o != ccg.GetOutputs().end();
          ++o)
        {
        // Write a rule for every output generated by this command.
        fout << this->ConvertToOutputFormat(o->c_str(), SHELL)
             << " :  \"$(SOURCE)\" \"$(INTDIR)\" \"$(OUTDIR)\"\n\t";
        fout << script.c_str() << "\n\n";
        }
      }
    fout << "# End Custom Build\n\n";
    }

  fout << "!ENDIF\n\n";
}


void cmLocalVisualStudio6Generator::WriteDSPBeginGroup(std::ostream& fout,
                                                       const char* group,
                                                       const char* filter)
{
  fout << "# Begin Group \"" << group << "\"\n"
    "# PROP Default_Filter \"" << filter << "\"\n";
}


void cmLocalVisualStudio6Generator::WriteDSPEndGroup(std::ostream& fout)
{
  fout << "# End Group\n";
}




void cmLocalVisualStudio6Generator::SetBuildType(BuildType b,
                                                 const std::string& libName,
                                                 cmTarget& target)
{
  std::string root= this->Makefile->GetRequiredDefinition("CMAKE_ROOT");
  const char *def=
    this->Makefile->GetDefinition( "MSPROJECT_TEMPLATE_DIRECTORY");

  if( def)
    {
    root = def;
    }
  else
    {
    root += "/Templates";
    }

  switch(b)
    {
    case WIN32_EXECUTABLE:
      break;
    case STATIC_LIBRARY:
      this->DSPHeaderTemplate = root;
      this->DSPHeaderTemplate += "/staticLibHeader.dsptemplate";
      this->DSPFooterTemplate = root;
      this->DSPFooterTemplate += "/staticLibFooter.dsptemplate";
      break;
    case DLL:
      this->DSPHeaderTemplate =  root;
      this->DSPHeaderTemplate += "/DLLHeader.dsptemplate";
      this->DSPFooterTemplate =  root;
      this->DSPFooterTemplate += "/DLLFooter.dsptemplate";
      break;
    case EXECUTABLE:
      if ( target.GetPropertyAsBool("WIN32_EXECUTABLE") )
        {
        this->DSPHeaderTemplate = root;
        this->DSPHeaderTemplate += "/EXEWinHeader.dsptemplate";
        this->DSPFooterTemplate = root;
        this->DSPFooterTemplate += "/EXEFooter.dsptemplate";
        }
      else
        {
        this->DSPHeaderTemplate = root;
        this->DSPHeaderTemplate += "/EXEHeader.dsptemplate";
        this->DSPFooterTemplate = root;
        this->DSPFooterTemplate += "/EXEFooter.dsptemplate";
        }
      break;
    case UTILITY:
      this->DSPHeaderTemplate = root;
      this->DSPHeaderTemplate += "/UtilityHeader.dsptemplate";
      this->DSPFooterTemplate = root;
      this->DSPFooterTemplate += "/UtilityFooter.dsptemplate";
      break;
    }

  // once the build type is set, determine what configurations are
  // possible
  cmsys::ifstream fin(this->DSPHeaderTemplate.c_str());

  cmsys::RegularExpression reg("# Name ");
  if(!fin)
    {
    cmSystemTools::Error("Error Reading ", this->DSPHeaderTemplate.c_str());
    }

  // reset this->Configurations
  this->Configurations.erase(this->Configurations.begin(),
                             this->Configurations.end());

  // now add all the configurations possible
  std::string vs6name = GetVS6TargetName(libName);
  std::string line;
  while(cmSystemTools::GetLineFromStream(fin, line))
    {
    cmSystemTools::ReplaceString(line, "OUTPUT_LIBNAME", vs6name.c_str());
    if (reg.find(line))
      {
      this->Configurations.push_back(line.substr(reg.end()));
      }
    }
}

//----------------------------------------------------------------------------
cmsys::auto_ptr<cmCustomCommand>
cmLocalVisualStudio6Generator::MaybeCreateOutputDir(cmTarget& target,
                                                    const std::string& config)
{
  cmsys::auto_ptr<cmCustomCommand> pcc;

  // VS6 forgets to create the output directory for archives if it
  // differs from the intermediate directory.
  if(target.GetType() != cmTarget::STATIC_LIBRARY) { return pcc; }
  std::string outDir = target.GetDirectory(config, false);

  // Add a pre-link event to create the directory.
  cmCustomCommandLine command;
  command.push_back(cmSystemTools::GetCMakeCommand());
  command.push_back("-E");
  command.push_back("make_directory");
  command.push_back(outDir);
  std::vector<std::string> no_output;
  std::vector<std::string> no_byproducts;
  std::vector<std::string> no_depends;
  cmCustomCommandLines commands;
  commands.push_back(command);
  pcc.reset(new cmCustomCommand(0, no_output, no_byproducts,
                                no_depends, commands, 0, 0));
  pcc->SetEscapeOldStyle(false);
  pcc->SetEscapeAllowMakeVars(true);
  return pcc;
}

// look for custom rules on a target and collect them together
std::string
cmLocalVisualStudio6Generator::CreateTargetRules(cmTarget &target,
                                              const std::string& configName,
                                              const std::string& /* libName */)
{
  if (target.GetType() >= cmTarget::UTILITY )
    {
    return "";
    }

  std::string customRuleCode = "# Begin Special Build Tool\n";
  EventWriter event(this, configName, customRuleCode);

  // Write the pre-build and pre-link together (VS6 does not support both).
  event.Start("PreLink");
  event.Write(target.GetPreBuildCommands());
  event.Write(target.GetPreLinkCommands());
  cmsys::auto_ptr<cmCustomCommand> pcc(
    this->MaybeCreateImplibDir(target, configName, false));
  if(pcc.get())
    {
    event.Write(*pcc);
    }
  pcc = this->MaybeCreateOutputDir(target, configName);
  if(pcc.get())
    {
    event.Write(*pcc);
    }
  event.Finish();

  // Write the post-build rules.
  event.Start("PostBuild");
  event.Write(target.GetPostBuildCommands());
  event.Finish();

  customRuleCode += "# End Special Build Tool\n";
  return customRuleCode;
}


inline std::string removeQuotes(const std::string& s)
{
  if(s[0] == '\"' && s[s.size()-1] == '\"')
    {
    return s.substr(1, s.size()-2);
    }
  return s;
}


std::string
cmLocalVisualStudio6Generator::GetTargetIncludeOptions(cmTarget &target,
                                                  const std::string& config)
{
  std::string includeOptions;

  // Setup /I and /LIBPATH options for the resulting DSP file.  VS 6
  // truncates long include paths so make it as short as possible if
  // the length threatens this problem.
  unsigned int maxIncludeLength = 3000;
  bool useShortPath = false;

  cmGeneratorTarget* gt =
    this->GlobalGenerator->GetGeneratorTarget(&target);
  for(int j=0; j < 2; ++j)
    {
    std::vector<std::string> includes;
    this->GetIncludeDirectories(includes, gt, "C", config);

    std::vector<std::string>::iterator i;
    for(i = includes.begin(); i != includes.end(); ++i)
      {
      std::string tmp =
        this->ConvertToOutputFormat(i->c_str(), SHELL);
      if(useShortPath)
        {
        cmSystemTools::GetShortPath(tmp.c_str(), tmp);
        }
      includeOptions +=  " /I ";

      // quote if not already quoted
      if (tmp[0] != '"')
        {
        includeOptions += "\"";
        includeOptions += tmp;
        includeOptions += "\"";
        }
      else
        {
        includeOptions += tmp;
        }
      }

    if(j == 0 && includeOptions.size() > maxIncludeLength)
      {
      includeOptions = "";
      useShortPath = true;
      }
    else
      {
      break;
      }
    }

  return includeOptions;
}


// Code in blocks surrounded by a test for this definition is needed
// only for compatibility with user project's replacement DSP
// templates.  The CMake templates no longer use them.
#define CM_USE_OLD_VS6

void cmLocalVisualStudio6Generator
::WriteDSPHeader(std::ostream& fout,
                 const std::string& libName, cmTarget &target,
                 std::vector<cmSourceGroup> &)
{
  bool targetBuilds = (target.GetType() >= cmTarget::EXECUTABLE &&
                       target.GetType() <= cmTarget::MODULE_LIBRARY);
#ifdef CM_USE_OLD_VS6
  // Lookup the library and executable output directories.
  std::string libPath;
  if(this->Makefile->GetDefinition("LIBRARY_OUTPUT_PATH"))
    {
    libPath = this->Makefile->GetDefinition("LIBRARY_OUTPUT_PATH");
    }
  std::string exePath;
  if(this->Makefile->GetDefinition("EXECUTABLE_OUTPUT_PATH"))
    {
    exePath = this->Makefile->GetDefinition("EXECUTABLE_OUTPUT_PATH");
    }

  // Make sure there are trailing slashes.
  if(!libPath.empty())
    {
    if(libPath[libPath.size()-1] != '/')
      {
      libPath += "/";
      }
    }
  if(!exePath.empty())
    {
    if(exePath[exePath.size()-1] != '/')
      {
      exePath += "/";
      }
    }

  std::set<std::string> pathEmitted;

  // determine the link directories
  std::string libOptions;
  std::string libDebugOptions;
  std::string libOptimizedOptions;

  std::string libMultiLineOptions;
  std::string libMultiLineOptionsForDebug;
  std::string libMultiLineDebugOptions;
  std::string libMultiLineOptimizedOptions;

  if(!libPath.empty())
    {
    std::string lpath =
      this->ConvertToOutputFormat(libPath.c_str(), SHELL);
    if(lpath.empty())
      {
      lpath = ".";
      }
    std::string lpathIntDir = libPath + "$(INTDIR)";
    lpathIntDir =
      this->ConvertToOutputFormat(lpathIntDir.c_str(), SHELL);
    if(pathEmitted.insert(lpath).second)
      {
      libOptions += " /LIBPATH:";
      libOptions += lpathIntDir;
      libOptions += " ";
      libOptions += " /LIBPATH:";
      libOptions += lpath;
      libOptions += " ";
      libMultiLineOptions += "# ADD LINK32 /LIBPATH:";
      libMultiLineOptions += lpathIntDir;
      libMultiLineOptions += " ";
      libMultiLineOptions += " /LIBPATH:";
      libMultiLineOptions += lpath;
      libMultiLineOptions += " \n";
      libMultiLineOptionsForDebug += "# ADD LINK32 /LIBPATH:";
      libMultiLineOptionsForDebug += lpathIntDir;
      libMultiLineOptionsForDebug += " ";
      libMultiLineOptionsForDebug += " /LIBPATH:";
      libMultiLineOptionsForDebug += lpath;
      libMultiLineOptionsForDebug += " \n";
      }
    }
  if(!exePath.empty())
    {
    std::string lpath =
      this->ConvertToOutputFormat(exePath.c_str(), SHELL);
    if(lpath.empty())
      {
      lpath = ".";
      }
    std::string lpathIntDir = exePath + "$(INTDIR)";
    lpathIntDir =
      this->ConvertToOutputFormat(lpathIntDir.c_str(), SHELL);

    if(pathEmitted.insert(lpath).second)
      {
      libOptions += " /LIBPATH:";
      libOptions += lpathIntDir;
      libOptions += " ";
      libOptions += " /LIBPATH:";
      libOptions += lpath;
      libOptions += " ";
      libMultiLineOptions += "# ADD LINK32 /LIBPATH:";
      libMultiLineOptions += lpathIntDir;
      libMultiLineOptions += " ";
      libMultiLineOptions += " /LIBPATH:";
      libMultiLineOptions += lpath;
      libMultiLineOptions += " \n";
      libMultiLineOptionsForDebug += "# ADD LINK32 /LIBPATH:";
      libMultiLineOptionsForDebug += lpathIntDir;
      libMultiLineOptionsForDebug += " ";
      libMultiLineOptionsForDebug += " /LIBPATH:";
      libMultiLineOptionsForDebug += lpath;
      libMultiLineOptionsForDebug += " \n";
      }
    }
  std::vector<std::string>::const_iterator i;
  const std::vector<std::string>& libdirs = target.GetLinkDirectories();
  for(i = libdirs.begin(); i != libdirs.end(); ++i)
    {
    std::string path = *i;
    if(path[path.size()-1] != '/')
      {
      path += "/";
      }
    std::string lpath =
      this->ConvertToOutputFormat(path.c_str(), SHELL);
    if(lpath.empty())
      {
      lpath = ".";
      }
    std::string lpathIntDir = path + "$(INTDIR)";
    lpathIntDir =
      this->ConvertToOutputFormat(lpathIntDir.c_str(), SHELL);
    if(pathEmitted.insert(lpath).second)
      {
      libOptions += " /LIBPATH:";
      libOptions += lpathIntDir;
      libOptions += " ";
      libOptions += " /LIBPATH:";
      libOptions += lpath;
      libOptions += " ";

      libMultiLineOptions += "# ADD LINK32 /LIBPATH:";
      libMultiLineOptions += lpathIntDir;
      libMultiLineOptions += " ";
      libMultiLineOptions += " /LIBPATH:";
      libMultiLineOptions += lpath;
      libMultiLineOptions += " \n";
      libMultiLineOptionsForDebug += "# ADD LINK32 /LIBPATH:";
      libMultiLineOptionsForDebug += lpathIntDir;
      libMultiLineOptionsForDebug += " ";
      libMultiLineOptionsForDebug += " /LIBPATH:";
      libMultiLineOptionsForDebug += lpath;
      libMultiLineOptionsForDebug += " \n";
      }
    }
  // find link libraries
  const cmTarget::LinkLibraryVectorType& libs =
    target.GetLinkLibrariesForVS6();
  cmTarget::LinkLibraryVectorType::const_iterator j;
  for(j = libs.begin(); j != libs.end(); ++j)
    {
    // add libraries to executables and dlls (but never include
    // a library in a library, bad recursion)
    // NEVER LINK STATIC LIBRARIES TO OTHER STATIC LIBRARIES
    if ((target.GetType() != cmTarget::SHARED_LIBRARY
         && target.GetType() != cmTarget::STATIC_LIBRARY
         && target.GetType() != cmTarget::MODULE_LIBRARY) ||
        (target.GetType()==cmTarget::SHARED_LIBRARY
         && libName != GetVS6TargetName(j->first)) ||
        (target.GetType()==cmTarget::MODULE_LIBRARY
         && libName != GetVS6TargetName(j->first)))
      {
      // Compute the proper name to use to link this library.
      std::string lib;
      std::string libDebug;
      cmTarget* tgt = this->GlobalGenerator->FindTarget(j->first.c_str());
      if(tgt)
        {
        cmGeneratorTarget* gt =
          this->GlobalGenerator->GetGeneratorTarget(tgt);
        lib = cmSystemTools::GetFilenameWithoutExtension
          (gt->GetFullName().c_str());
        libDebug = cmSystemTools::GetFilenameWithoutExtension
          (gt->GetFullName("Debug").c_str());
        lib += ".lib";
        libDebug += ".lib";
        }
      else
        {
        lib = j->first.c_str();
        libDebug = j->first.c_str();
        if(j->first.find(".lib") == std::string::npos)
          {
          lib += ".lib";
          libDebug += ".lib";
          }
        }
      lib = this->ConvertToOutputFormat(lib.c_str(), SHELL);
      libDebug =
        this->ConvertToOutputFormat(libDebug.c_str(), SHELL);

      if (j->second == cmTarget::GENERAL)
        {
        libOptions += " ";
        libOptions += lib;
        libMultiLineOptions += "# ADD LINK32 ";
        libMultiLineOptions +=  lib;
        libMultiLineOptions += "\n";
        libMultiLineOptionsForDebug += "# ADD LINK32 ";
        libMultiLineOptionsForDebug +=  libDebug;
        libMultiLineOptionsForDebug += "\n";
        }
      if (j->second == cmTarget::DEBUG)
        {
        libDebugOptions += " ";
        libDebugOptions += lib;

        libMultiLineDebugOptions += "# ADD LINK32 ";
        libMultiLineDebugOptions += libDebug;
        libMultiLineDebugOptions += "\n";
        }
      if (j->second == cmTarget::OPTIMIZED)
        {
        libOptimizedOptions += " ";
        libOptimizedOptions += lib;

        libMultiLineOptimizedOptions += "# ADD LINK32 ";
        libMultiLineOptimizedOptions += lib;
        libMultiLineOptimizedOptions += "\n";
        }
      }
    }
#endif

  // Get include options for this target.
  std::string includeOptionsDebug = this->GetTargetIncludeOptions(target,
                                                                  "DEBUG");
  std::string includeOptionsRelease = this->GetTargetIncludeOptions(target,
                                                                  "RELEASE");
  std::string includeOptionsRelWithDebInfo = this->GetTargetIncludeOptions(
                                                            target,
                                                            "RELWITHDEBINFO");
  std::string includeOptionsMinSizeRel = this->GetTargetIncludeOptions(target,
                                                                "MINSIZEREL");

  // Get extra linker options for this target type.
  std::string extraLinkOptions;
  std::string extraLinkOptionsDebug;
  std::string extraLinkOptionsRelease;
  std::string extraLinkOptionsMinSizeRel;
  std::string extraLinkOptionsRelWithDebInfo;
  if(target.GetType() == cmTarget::EXECUTABLE)
    {
    extraLinkOptions = this->Makefile->
      GetRequiredDefinition("CMAKE_EXE_LINKER_FLAGS");
    extraLinkOptionsDebug = this->Makefile->
      GetRequiredDefinition("CMAKE_EXE_LINKER_FLAGS_DEBUG");
    extraLinkOptionsRelease = this->Makefile->
      GetRequiredDefinition("CMAKE_EXE_LINKER_FLAGS_RELEASE");
    extraLinkOptionsMinSizeRel = this->Makefile->
      GetRequiredDefinition("CMAKE_EXE_LINKER_FLAGS_MINSIZEREL");
    extraLinkOptionsRelWithDebInfo = this->Makefile->
      GetRequiredDefinition("CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO");
    }
  if(target.GetType() == cmTarget::SHARED_LIBRARY)
    {
    extraLinkOptions = this->Makefile->
      GetRequiredDefinition("CMAKE_SHARED_LINKER_FLAGS");
    extraLinkOptionsDebug = this->Makefile->
      GetRequiredDefinition("CMAKE_SHARED_LINKER_FLAGS_DEBUG");
    extraLinkOptionsRelease = this->Makefile->
      GetRequiredDefinition("CMAKE_SHARED_LINKER_FLAGS_RELEASE");
    extraLinkOptionsMinSizeRel = this->Makefile->
      GetRequiredDefinition("CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL");
    extraLinkOptionsRelWithDebInfo = this->Makefile->
      GetRequiredDefinition("CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO");
    }
  if(target.GetType() == cmTarget::MODULE_LIBRARY)
    {
    extraLinkOptions = this->Makefile->
      GetRequiredDefinition("CMAKE_MODULE_LINKER_FLAGS");
    extraLinkOptionsDebug = this->Makefile->
      GetRequiredDefinition("CMAKE_MODULE_LINKER_FLAGS_DEBUG");
    extraLinkOptionsRelease = this->Makefile->
      GetRequiredDefinition("CMAKE_MODULE_LINKER_FLAGS_RELEASE");
    extraLinkOptionsMinSizeRel = this->Makefile->
      GetRequiredDefinition("CMAKE_MODULE_LINKER_FLAGS_MINSIZEREL");
    extraLinkOptionsRelWithDebInfo = this->Makefile->
      GetRequiredDefinition("CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO");
    }

  // Get extra linker options for this target.
  if(const char* targetLinkFlags = target.GetProperty("LINK_FLAGS"))
    {
    extraLinkOptions += " ";
    extraLinkOptions += targetLinkFlags;
    }

  if(const char* targetLinkFlags = target.GetProperty("LINK_FLAGS_DEBUG"))
    {
    extraLinkOptionsDebug += " ";
    extraLinkOptionsDebug += targetLinkFlags;
    }

  if(const char* targetLinkFlags = target.GetProperty("LINK_FLAGS_RELEASE"))
    {
    extraLinkOptionsRelease += " ";
    extraLinkOptionsRelease += targetLinkFlags;
    }

  if(const char* targetLinkFlags = target.GetProperty("LINK_FLAGS_MINSIZEREL"))
    {
    extraLinkOptionsMinSizeRel += " ";
    extraLinkOptionsMinSizeRel += targetLinkFlags;
    }

  if(const char* targetLinkFlags =
     target.GetProperty("LINK_FLAGS_RELWITHDEBINFO"))
    {
    extraLinkOptionsRelWithDebInfo += " ";
    extraLinkOptionsRelWithDebInfo += targetLinkFlags;
    }

  cmGeneratorTarget* gt =
    this->GlobalGenerator->GetGeneratorTarget(&target);

  // Get standard libraries for this language.
  if(targetBuilds)
    {
    // Get the language to use for linking.
    std::vector<std::string> configs;
    target.GetMakefile()->GetConfigurations(configs);
    std::vector<std::string>::const_iterator it = configs.begin();
    const std::string& linkLanguage = gt->GetLinkerLanguage(*it);
    for ( ; it != configs.end(); ++it)
      {
      const std::string& configLinkLanguage = gt->GetLinkerLanguage(*it);
      if (configLinkLanguage != linkLanguage)
        {
        cmSystemTools::Error
          ("Linker language must not vary by configuration for target: ",
          target.GetName().c_str());
        }
      }
    if(linkLanguage.empty())
      {
      cmSystemTools::Error
        ("CMake can not determine linker language for target: ",
         target.GetName().c_str());
      return;
      }

    // Compute the variable name to lookup standard libraries for this
    // language.
    std::string standardLibsVar = "CMAKE_";
    standardLibsVar += linkLanguage;
    standardLibsVar += "_STANDARD_LIBRARIES";

    // Add standard libraries.
    if(const char* stdLibs =
       this->Makefile->GetDefinition(standardLibsVar.c_str()))
      {
      extraLinkOptions += " ";
      extraLinkOptions += stdLibs;
      }
    }

  // Compute version number information.
  std::string targetVersionFlag;
  if(target.GetType() == cmTarget::EXECUTABLE ||
     target.GetType() == cmTarget::SHARED_LIBRARY ||
     target.GetType() == cmTarget::MODULE_LIBRARY)
    {
    int major;
    int minor;
    target.GetTargetVersion(major, minor);
    std::ostringstream targetVersionStream;
    targetVersionStream << "/version:" << major << "." << minor;
    targetVersionFlag = targetVersionStream.str();
    }

  // Compute the real name of the target.
  std::string outputName =
    "(OUTPUT_NAME is for libraries and executables only)";
  std::string outputNameDebug = outputName;
  std::string outputNameRelease = outputName;
  std::string outputNameMinSizeRel = outputName;
  std::string outputNameRelWithDebInfo = outputName;
  if(target.GetType() == cmTarget::EXECUTABLE ||
     target.GetType() == cmTarget::STATIC_LIBRARY ||
     target.GetType() == cmTarget::SHARED_LIBRARY ||
     target.GetType() == cmTarget::MODULE_LIBRARY)
    {
    outputName = gt->GetFullName();
    outputNameDebug = gt->GetFullName("Debug");
    outputNameRelease = gt->GetFullName("Release");
    outputNameMinSizeRel = gt->GetFullName("MinSizeRel");
    outputNameRelWithDebInfo = gt->GetFullName("RelWithDebInfo");
    }
  else if(target.GetType() == cmTarget::OBJECT_LIBRARY)
    {
    outputName = target.GetName();
    outputName += ".lib";
    outputNameDebug = outputName;
    outputNameRelease = outputName;
    outputNameMinSizeRel = outputName;
    outputNameRelWithDebInfo = outputName;
    }

  // Compute the output directory for the target.
  std::string outputDirOld;
  std::string outputDirDebug;
  std::string outputDirRelease;
  std::string outputDirMinSizeRel;
  std::string outputDirRelWithDebInfo;
  if(target.GetType() == cmTarget::EXECUTABLE ||
     target.GetType() == cmTarget::STATIC_LIBRARY ||
     target.GetType() == cmTarget::SHARED_LIBRARY ||
     target.GetType() == cmTarget::MODULE_LIBRARY)
    {
#ifdef CM_USE_OLD_VS6
    outputDirOld =
      removeQuotes(this->ConvertToOutputFormat
                   (target.GetDirectory().c_str(), SHELL));
#endif
    outputDirDebug =
        removeQuotes(this->ConvertToOutputFormat(
                       target.GetDirectory("Debug").c_str(), SHELL));
    outputDirRelease =
        removeQuotes(this->ConvertToOutputFormat(
                 target.GetDirectory("Release").c_str(), SHELL));
    outputDirMinSizeRel =
        removeQuotes(this->ConvertToOutputFormat(
                 target.GetDirectory("MinSizeRel").c_str(), SHELL));
    outputDirRelWithDebInfo =
        removeQuotes(this->ConvertToOutputFormat(
                 target.GetDirectory("RelWithDebInfo").c_str(), SHELL));
    }
  else if(target.GetType() == cmTarget::OBJECT_LIBRARY)
    {
    std::string outputDir = cmake::GetCMakeFilesDirectoryPostSlash();
    outputDirDebug = outputDir + "Debug";
    outputDirRelease = outputDir + "Release";
    outputDirMinSizeRel = outputDir + "MinSizeRel";
    outputDirRelWithDebInfo = outputDir + "RelWithDebInfo";
    }

  // Compute the proper link information for the target.
  std::string optionsDebug;
  std::string optionsRelease;
  std::string optionsMinSizeRel;
  std::string optionsRelWithDebInfo;
  if(target.GetType() == cmTarget::EXECUTABLE ||
     target.GetType() == cmTarget::SHARED_LIBRARY ||
     target.GetType() == cmTarget::MODULE_LIBRARY)
    {
    extraLinkOptionsDebug =
      extraLinkOptions + " " + extraLinkOptionsDebug;
    extraLinkOptionsRelease =
      extraLinkOptions + " " + extraLinkOptionsRelease;
    extraLinkOptionsMinSizeRel =
      extraLinkOptions + " " + extraLinkOptionsMinSizeRel;
    extraLinkOptionsRelWithDebInfo =
      extraLinkOptions + " " + extraLinkOptionsRelWithDebInfo;
    this->ComputeLinkOptions(target, "Debug", extraLinkOptionsDebug,
                             optionsDebug);
    this->ComputeLinkOptions(target, "Release", extraLinkOptionsRelease,
                             optionsRelease);
    this->ComputeLinkOptions(target, "MinSizeRel", extraLinkOptionsMinSizeRel,
                             optionsMinSizeRel);
    this->ComputeLinkOptions(target, "RelWithDebInfo",
                             extraLinkOptionsRelWithDebInfo,
                             optionsRelWithDebInfo);
    }

  // Compute the path of the import library.
  std::string targetImplibFlagDebug;
  std::string targetImplibFlagRelease;
  std::string targetImplibFlagMinSizeRel;
  std::string targetImplibFlagRelWithDebInfo;
  if(target.GetType() == cmTarget::SHARED_LIBRARY ||
     target.GetType() == cmTarget::MODULE_LIBRARY ||
     target.GetType() == cmTarget::EXECUTABLE)
    {
    std::string fullPathImpDebug = target.GetDirectory("Debug", true);
    std::string fullPathImpRelease = target.GetDirectory("Release", true);
    std::string fullPathImpMinSizeRel =
      target.GetDirectory("MinSizeRel", true);
    std::string fullPathImpRelWithDebInfo =
      target.GetDirectory("RelWithDebInfo", true);
    fullPathImpDebug += "/";
    fullPathImpRelease += "/";
    fullPathImpMinSizeRel += "/";
    fullPathImpRelWithDebInfo += "/";
    fullPathImpDebug += gt->GetFullName("Debug", true);
    fullPathImpRelease += gt->GetFullName("Release", true);
    fullPathImpMinSizeRel += gt->GetFullName("MinSizeRel", true);
    fullPathImpRelWithDebInfo += gt->GetFullName("RelWithDebInfo", true);

    targetImplibFlagDebug = "/implib:";
    targetImplibFlagRelease = "/implib:";
    targetImplibFlagMinSizeRel = "/implib:";
    targetImplibFlagRelWithDebInfo = "/implib:";
    targetImplibFlagDebug +=
      this->ConvertToOutputFormat(fullPathImpDebug.c_str(), SHELL);
    targetImplibFlagRelease +=
      this->ConvertToOutputFormat(fullPathImpRelease.c_str(), SHELL);
    targetImplibFlagMinSizeRel +=
      this->ConvertToOutputFormat(fullPathImpMinSizeRel.c_str(), SHELL);
    targetImplibFlagRelWithDebInfo +=
      this->ConvertToOutputFormat(fullPathImpRelWithDebInfo.c_str(), SHELL);
    }

#ifdef CM_USE_OLD_VS6
  // Compute link information for the target.
  if(!extraLinkOptions.empty())
    {
    libOptions += " ";
    libOptions += extraLinkOptions;
    libOptions += " ";
    libMultiLineOptions += "# ADD LINK32 ";
    libMultiLineOptions +=  extraLinkOptions;
    libMultiLineOptions += " \n";
    libMultiLineOptionsForDebug += "# ADD LINK32 ";
    libMultiLineOptionsForDebug +=  extraLinkOptions;
    libMultiLineOptionsForDebug += " \n";
    }
#endif

  // are there any custom rules on the target itself
  // only if the target is a lib or exe
  std::string customRuleCodeRelease
      = this->CreateTargetRules(target, "RELEASE",        libName);
  std::string customRuleCodeDebug
      = this->CreateTargetRules(target, "DEBUG",          libName);
  std::string customRuleCodeMinSizeRel
      = this->CreateTargetRules(target, "MINSIZEREL",     libName);
  std::string customRuleCodeRelWithDebInfo
      = this->CreateTargetRules(target, "RELWITHDEBINFO", libName);

  cmsys::ifstream fin(this->DSPHeaderTemplate.c_str());
  if(!fin)
    {
    cmSystemTools::Error("Error Reading ", this->DSPHeaderTemplate.c_str());
    }
  std::string staticLibOptions;
  std::string staticLibOptionsDebug;
  std::string staticLibOptionsRelease;
  std::string staticLibOptionsMinSizeRel;
  std::string staticLibOptionsRelWithDebInfo;
  if(target.GetType() == cmTarget::STATIC_LIBRARY )
    {
    const char *libflagsGlobal =
      this->Makefile->GetSafeDefinition("CMAKE_STATIC_LINKER_FLAGS");
    this->AppendFlags(staticLibOptions, libflagsGlobal);
    this->AppendFlags(staticLibOptionsDebug, libflagsGlobal);
    this->AppendFlags(staticLibOptionsRelease, libflagsGlobal);
    this->AppendFlags(staticLibOptionsMinSizeRel, libflagsGlobal);
    this->AppendFlags(staticLibOptionsRelWithDebInfo, libflagsGlobal);

    this->AppendFlags(staticLibOptionsDebug, this->Makefile->
      GetSafeDefinition("CMAKE_STATIC_LINKER_FLAGS_DEBUG"));
    this->AppendFlags(staticLibOptionsRelease, this->Makefile->
      GetSafeDefinition("CMAKE_STATIC_LINKER_FLAGS_RELEASE"));
    this->AppendFlags(staticLibOptionsMinSizeRel, this->Makefile->
      GetSafeDefinition("CMAKE_STATIC_LINKER_FLAGS_MINSIZEREL"));
    this->AppendFlags(staticLibOptionsRelWithDebInfo, this->Makefile->
      GetSafeDefinition("CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO"));

    const char *libflags = target.GetProperty("STATIC_LIBRARY_FLAGS");
    this->AppendFlags(staticLibOptions, libflags);
    this->AppendFlags(staticLibOptionsDebug, libflags);
    this->AppendFlags(staticLibOptionsRelease, libflags);
    this->AppendFlags(staticLibOptionsMinSizeRel, libflags);
    this->AppendFlags(staticLibOptionsRelWithDebInfo, libflags);

    this->AppendFlags(staticLibOptionsDebug,
      target.GetProperty("STATIC_LIBRARY_FLAGS_DEBUG"));
    this->AppendFlags(staticLibOptionsRelease,
      target.GetProperty("STATIC_LIBRARY_FLAGS_RELEASE"));
    this->AppendFlags(staticLibOptionsMinSizeRel,
      target.GetProperty("STATIC_LIBRARY_FLAGS_MINSIZEREL"));
    this->AppendFlags(staticLibOptionsRelWithDebInfo,
      target.GetProperty("STATIC_LIBRARY_FLAGS_RELWITHDEBINFO"));

    std::string objects;
    this->OutputObjects(target, "LIB", objects);
    if(!objects.empty())
      {
      objects = "\n" + objects;
      staticLibOptionsDebug += objects;
      staticLibOptionsRelease += objects;
      staticLibOptionsMinSizeRel += objects;
      staticLibOptionsRelWithDebInfo += objects;
      }
    }

  // Add the export symbol definition for shared library objects.
  std::string exportSymbol;
  if(const char* exportMacro = target.GetExportMacro())
    {
    exportSymbol = exportMacro;
    }

  std::string line;
  std::string libnameExports;
  if(!exportSymbol.empty())
    {
    libnameExports = "/D \"";
    libnameExports += exportSymbol;
    libnameExports += "\"";
    }
  while(cmSystemTools::GetLineFromStream(fin, line))
    {
    const char* mfcFlag = this->Makefile->GetDefinition("CMAKE_MFC_FLAG");
    if(!mfcFlag)
      {
      mfcFlag = "0";
      }
    cmSystemTools::ReplaceString(line, "OUTPUT_LIBNAME_EXPORTS",
                                 libnameExports.c_str());
    cmSystemTools::ReplaceString(line, "CMAKE_MFC_FLAG",
                                 mfcFlag);
    if(target.GetType() == cmTarget::STATIC_LIBRARY ||
       target.GetType() == cmTarget::OBJECT_LIBRARY)
      {
      cmSystemTools::ReplaceString(line, "CM_STATIC_LIB_ARGS_DEBUG",
                                   staticLibOptionsDebug.c_str());
      cmSystemTools::ReplaceString(line, "CM_STATIC_LIB_ARGS_RELEASE",
                                   staticLibOptionsRelease.c_str());
      cmSystemTools::ReplaceString(line, "CM_STATIC_LIB_ARGS_MINSIZEREL",
                                   staticLibOptionsMinSizeRel.c_str());
      cmSystemTools::ReplaceString(line, "CM_STATIC_LIB_ARGS_RELWITHDEBINFO",
                                   staticLibOptionsRelWithDebInfo.c_str());
      cmSystemTools::ReplaceString(line, "CM_STATIC_LIB_ARGS",
                                   staticLibOptions.c_str());
      }
    if(this->Makefile->IsOn("CMAKE_VERBOSE_MAKEFILE"))
      {
      cmSystemTools::ReplaceString(line, "/nologo", "");
      }

#ifdef CM_USE_OLD_VS6
    cmSystemTools::ReplaceString(line, "CM_LIBRARIES",
                                 libOptions.c_str());
    cmSystemTools::ReplaceString(line, "CM_DEBUG_LIBRARIES",
                                 libDebugOptions.c_str());
    cmSystemTools::ReplaceString(line, "CM_OPTIMIZED_LIBRARIES",
                                 libOptimizedOptions.c_str());
    cmSystemTools::ReplaceString(line, "CM_MULTILINE_LIBRARIES_FOR_DEBUG",
                                 libMultiLineOptionsForDebug.c_str());
    cmSystemTools::ReplaceString(line, "CM_MULTILINE_LIBRARIES",
                                 libMultiLineOptions.c_str());
    cmSystemTools::ReplaceString(line, "CM_MULTILINE_DEBUG_LIBRARIES",
                                 libMultiLineDebugOptions.c_str());
    cmSystemTools::ReplaceString(line, "CM_MULTILINE_OPTIMIZED_LIBRARIES",
                                 libMultiLineOptimizedOptions.c_str());
#endif

    // Substitute the rules for custom command. When specifying just the
    // target name for the command the command can be different for
    // different configs
    cmSystemTools::ReplaceString(line, "CMAKE_CUSTOM_RULE_CODE_RELEASE",
                                 customRuleCodeRelease.c_str());
    cmSystemTools::ReplaceString(line, "CMAKE_CUSTOM_RULE_CODE_DEBUG",
                                 customRuleCodeDebug.c_str());
    cmSystemTools::ReplaceString(line, "CMAKE_CUSTOM_RULE_CODE_MINSIZEREL",
                                 customRuleCodeMinSizeRel.c_str());
    cmSystemTools::ReplaceString(line, "CMAKE_CUSTOM_RULE_CODE_RELWITHDEBINFO",
                                 customRuleCodeRelWithDebInfo.c_str());

    // Substitute the real output name into the template.
    cmSystemTools::ReplaceString(line, "OUTPUT_NAME_DEBUG",
                                 outputNameDebug.c_str());
    cmSystemTools::ReplaceString(line, "OUTPUT_NAME_RELEASE",
                                 outputNameRelease.c_str());
    cmSystemTools::ReplaceString(line, "OUTPUT_NAME_MINSIZEREL",
                                 outputNameMinSizeRel.c_str());
    cmSystemTools::ReplaceString(line, "OUTPUT_NAME_RELWITHDEBINFO",
                                 outputNameRelWithDebInfo.c_str());
    cmSystemTools::ReplaceString(line, "OUTPUT_NAME", outputName.c_str());

    // Substitute the proper link information into the template.
    cmSystemTools::ReplaceString(line, "CM_MULTILINE_OPTIONS_DEBUG",
                                 optionsDebug.c_str());
    cmSystemTools::ReplaceString(line, "CM_MULTILINE_OPTIONS_RELEASE",
                                 optionsRelease.c_str());
    cmSystemTools::ReplaceString(line, "CM_MULTILINE_OPTIONS_MINSIZEREL",
                                 optionsMinSizeRel.c_str());
    cmSystemTools::ReplaceString(line, "CM_MULTILINE_OPTIONS_RELWITHDEBINFO",
                                 optionsRelWithDebInfo.c_str());

    cmSystemTools::ReplaceString(line, "BUILD_INCLUDES_DEBUG",
                                 includeOptionsDebug.c_str());
    cmSystemTools::ReplaceString(line, "BUILD_INCLUDES_RELEASE",
                                 includeOptionsRelease.c_str());
    cmSystemTools::ReplaceString(line, "BUILD_INCLUDES_MINSIZEREL",
                                 includeOptionsMinSizeRel.c_str());
    cmSystemTools::ReplaceString(line, "BUILD_INCLUDES_RELWITHDEBINFO",
                                 includeOptionsRelWithDebInfo.c_str());

    cmSystemTools::ReplaceString(line, "TARGET_VERSION_FLAG",
                                 targetVersionFlag.c_str());
    cmSystemTools::ReplaceString(line, "TARGET_IMPLIB_FLAG_DEBUG",
                                 targetImplibFlagDebug.c_str());
    cmSystemTools::ReplaceString(line, "TARGET_IMPLIB_FLAG_RELEASE",
                                 targetImplibFlagRelease.c_str());
    cmSystemTools::ReplaceString(line, "TARGET_IMPLIB_FLAG_MINSIZEREL",
                                 targetImplibFlagMinSizeRel.c_str());
    cmSystemTools::ReplaceString(line, "TARGET_IMPLIB_FLAG_RELWITHDEBINFO",
                                 targetImplibFlagRelWithDebInfo.c_str());

    std::string vs6name = GetVS6TargetName(libName);
    cmSystemTools::ReplaceString(line, "OUTPUT_LIBNAME", vs6name.c_str());

#ifdef CM_USE_OLD_VS6
    // because LIBRARY_OUTPUT_PATH and EXECUTABLE_OUTPUT_PATH
    // are already quoted in the template file,
    // we need to remove the quotes here, we still need
    // to convert to output path for unix to win32 conversion
    cmSystemTools::ReplaceString
      (line, "LIBRARY_OUTPUT_PATH",
       removeQuotes(this->ConvertToOutputFormat
                    (libPath.c_str(), SHELL)).c_str());
    cmSystemTools::ReplaceString
      (line, "EXECUTABLE_OUTPUT_PATH",
       removeQuotes(this->ConvertToOutputFormat
                    (exePath.c_str(), SHELL)).c_str());
#endif

    if(targetBuilds || target.GetType() == cmTarget::OBJECT_LIBRARY)
      {
      cmSystemTools::ReplaceString(line, "OUTPUT_DIRECTORY_DEBUG",
                                   outputDirDebug.c_str());
      cmSystemTools::ReplaceString(line, "OUTPUT_DIRECTORY_RELEASE",
                                   outputDirRelease.c_str());
      cmSystemTools::ReplaceString(line, "OUTPUT_DIRECTORY_MINSIZEREL",
                                   outputDirMinSizeRel.c_str());
      cmSystemTools::ReplaceString(line, "OUTPUT_DIRECTORY_RELWITHDEBINFO",
                                   outputDirRelWithDebInfo.c_str());
      if(!outputDirOld.empty())
        {
        cmSystemTools::ReplaceString(line, "OUTPUT_DIRECTORY",
                                     outputDirOld.c_str());
        }
      }

    cmSystemTools::ReplaceString(line,
                                 "EXTRA_DEFINES",
                                 this->Makefile->GetDefineFlags());
    const char* debugPostfix
      = this->Makefile->GetDefinition("CMAKE_DEBUG_POSTFIX");
    cmSystemTools::ReplaceString(line, "DEBUG_POSTFIX",
                                 debugPostfix?debugPostfix:"");
    if(target.GetType() >= cmTarget::EXECUTABLE &&
       target.GetType() <= cmTarget::OBJECT_LIBRARY)
      {
      // store flags for each configuration
      std::string flags = " ";
      std::string flagsRelease = " ";
      std::string flagsMinSizeRel = " ";
      std::string flagsDebug = " ";
      std::string flagsRelWithDebInfo = " ";
      std::vector<std::string> configs;
      target.GetMakefile()->GetConfigurations(configs);
      std::vector<std::string>::const_iterator it = configs.begin();
      const std::string& linkLanguage = gt->GetLinkerLanguage(*it);
      for ( ; it != configs.end(); ++it)
        {
        const std::string& configLinkLanguage = gt->GetLinkerLanguage(*it);
        if (configLinkLanguage != linkLanguage)
          {
          cmSystemTools::Error
            ("Linker language must not vary by configuration for target: ",
            target.GetName().c_str());
          }
        }
      if(linkLanguage.empty())
        {
        cmSystemTools::Error
          ("CMake can not determine linker language for target: ",
           target.GetName().c_str());
        return;
        }
      // if CXX is on and the target contains cxx code then add the cxx flags
      std::string baseFlagVar = "CMAKE_";
      baseFlagVar += linkLanguage;
      baseFlagVar += "_FLAGS";
      flags = this->Makefile->GetSafeDefinition(baseFlagVar.c_str());

      std::string flagVar = baseFlagVar + "_RELEASE";
      flagsRelease = this->Makefile->GetSafeDefinition(flagVar.c_str());
      flagsRelease += " -DCMAKE_INTDIR=\\\"Release\\\" ";

      flagVar = baseFlagVar + "_MINSIZEREL";
      flagsMinSizeRel = this->Makefile->GetSafeDefinition(flagVar.c_str());
      flagsMinSizeRel += " -DCMAKE_INTDIR=\\\"MinSizeRel\\\" ";

      flagVar = baseFlagVar + "_DEBUG";
      flagsDebug = this->Makefile->GetSafeDefinition(flagVar.c_str());
      flagsDebug += " -DCMAKE_INTDIR=\\\"Debug\\\" ";

      flagVar = baseFlagVar + "_RELWITHDEBINFO";
      flagsRelWithDebInfo = this->Makefile->GetSafeDefinition(flagVar.c_str());
      flagsRelWithDebInfo += " -DCMAKE_INTDIR=\\\"RelWithDebInfo\\\" ";

      this->AddCompileOptions(flags, &target, linkLanguage, "");
      this->AddCompileOptions(flagsDebug, &target, linkLanguage, "Debug");
      this->AddCompileOptions(flagsRelease, &target, linkLanguage, "Release");
      this->AddCompileOptions(flagsMinSizeRel, &target, linkLanguage,
                              "MinSizeRel");
      this->AddCompileOptions(flagsRelWithDebInfo, &target, linkLanguage,
                              "RelWithDebInfo");

      // if _UNICODE and _SBCS are not found, then add -D_MBCS
      std::string defs = this->Makefile->GetDefineFlags();
      if(flags.find("D_UNICODE") == flags.npos &&
         defs.find("D_UNICODE") == flags.npos &&
         flags.find("D_SBCS") == flags.npos &&
         defs.find("D_SBCS") == flags.npos)
        {
        flags += " /D \"_MBCS\"";
        }

      // Add per-target and per-configuration preprocessor definitions.
      std::set<std::string> definesSet;
      std::set<std::string> debugDefinesSet;
      std::set<std::string> releaseDefinesSet;
      std::set<std::string> minsizeDefinesSet;
      std::set<std::string> debugrelDefinesSet;

      this->AddCompileDefinitions(definesSet, &target, "", linkLanguage);
      this->AddCompileDefinitions(debugDefinesSet, &target,
                                  "DEBUG", linkLanguage);
      this->AddCompileDefinitions(releaseDefinesSet, &target,
                                  "RELEASE", linkLanguage);
      this->AddCompileDefinitions(minsizeDefinesSet, &target,
                                  "MINSIZEREL", linkLanguage);
      this->AddCompileDefinitions(debugrelDefinesSet, &target,
                                  "RELWITHDEBINFO", linkLanguage);

      std::string defines = " ";
      std::string debugDefines = " ";
      std::string releaseDefines = " ";
      std::string minsizeDefines = " ";
      std::string debugrelDefines = " ";

      this->JoinDefines(definesSet, defines, "");
      this->JoinDefines(debugDefinesSet, debugDefines, "");
      this->JoinDefines(releaseDefinesSet, releaseDefines, "");
      this->JoinDefines(minsizeDefinesSet, minsizeDefines, "");
      this->JoinDefines(debugrelDefinesSet, debugrelDefines, "");

      flags += defines;
      flagsDebug += debugDefines;
      flagsRelease += releaseDefines;
      flagsMinSizeRel += minsizeDefines;
      flagsRelWithDebInfo += debugrelDefines;

      // The template files have CXX FLAGS in them, that need to be replaced.
      // There are not separate CXX and C template files, so we use the same
      // variable names.   The previous code sets up flags* variables to
      // contain the correct C or CXX flags
      cmSystemTools::ReplaceString(line, "CMAKE_CXX_FLAGS_MINSIZEREL",
                                   flagsMinSizeRel.c_str());
      cmSystemTools::ReplaceString(line, "CMAKE_CXX_FLAGS_DEBUG",
                                   flagsDebug.c_str());
      cmSystemTools::ReplaceString(line, "CMAKE_CXX_FLAGS_RELWITHDEBINFO",
                                   flagsRelWithDebInfo.c_str());
      cmSystemTools::ReplaceString(line, "CMAKE_CXX_FLAGS_RELEASE",
                                   flagsRelease.c_str());
      cmSystemTools::ReplaceString(line, "CMAKE_CXX_FLAGS", flags.c_str());

      cmSystemTools::ReplaceString(line, "COMPILE_DEFINITIONS_MINSIZEREL",
                                   minsizeDefines.c_str());
      cmSystemTools::ReplaceString(line, "COMPILE_DEFINITIONS_DEBUG",
                                   debugDefines.c_str());
      cmSystemTools::ReplaceString(line, "COMPILE_DEFINITIONS_RELWITHDEBINFO",
                                   debugrelDefines.c_str());
      cmSystemTools::ReplaceString(line, "COMPILE_DEFINITIONS_RELEASE",
                                   releaseDefines.c_str());
      cmSystemTools::ReplaceString(line, "COMPILE_DEFINITIONS",
                                   defines.c_str());
      }

    fout << line.c_str() << std::endl;
    }
}

void cmLocalVisualStudio6Generator::WriteDSPFooter(std::ostream& fout)
{
  cmsys::ifstream fin(this->DSPFooterTemplate.c_str());
  if(!fin)
    {
    cmSystemTools::Error("Error Reading ",
                         this->DSPFooterTemplate.c_str());
    }
  std::string line;
  while(cmSystemTools::GetLineFromStream(fin, line))
    {
    fout << line << std::endl;
    }
}

//----------------------------------------------------------------------------
void cmLocalVisualStudio6Generator
::ComputeLinkOptions(cmTarget& target,
                     const std::string& configName,
                     const std::string extraOptions,
                     std::string& options)
{
  cmGeneratorTarget* gt =
    this->GlobalGenerator->GetGeneratorTarget(&target);
  // Compute the link information for this configuration.
  cmComputeLinkInformation* pcli = gt->GetLinkInformation(configName);
  if(!pcli)
    {
    return;
    }
  cmComputeLinkInformation& cli = *pcli;
  typedef cmComputeLinkInformation::ItemVector ItemVector;
  ItemVector const& linkLibs = cli.GetItems();
  std::vector<std::string> const& linkDirs = cli.GetDirectories();

  this->OutputObjects(target, "LINK", options);

  // Build the link options code.
  for(std::vector<std::string>::const_iterator d = linkDirs.begin();
      d != linkDirs.end(); ++d)
    {
    std::string dir = *d;
    if(!dir.empty())
      {
      if(dir[dir.size()-1] != '/')
        {
        dir += "/";
        }
      dir += "$(IntDir)";
      options += "# ADD LINK32 /LIBPATH:";
      options += this->ConvertToOutputFormat(dir.c_str(), SHELL);
      options += " /LIBPATH:";
      options += this->ConvertToOutputFormat(d->c_str(), SHELL);
      options += "\n";
      }
    }
  for(ItemVector::const_iterator l = linkLibs.begin();
      l != linkLibs.end(); ++l)
    {
    options += "# ADD LINK32 ";
    if(l->IsPath)
      {
      options +=
        this->ConvertToOutputFormat(l->Value.c_str(), SHELL);
      }
    else if (!l->Target
        || l->Target->GetType() != cmTarget::INTERFACE_LIBRARY)
      {
      options += l->Value;
      }
    options += "\n";
    }

  // Add extra options if any.
  if(!extraOptions.empty())
    {
    options += "# ADD LINK32 ";
    options += extraOptions;
    options += "\n";
    }
}

//----------------------------------------------------------------------------
void cmLocalVisualStudio6Generator
::OutputObjects(cmTarget& target, const char* tool,
                std::string& options)
{
  // VS 6 does not support per-config source locations so we
  // list object library content on the link line instead.
  cmGeneratorTarget* gt =
    this->GlobalGenerator->GetGeneratorTarget(&target);
  std::vector<std::string> objs;
  gt->UseObjectLibraries(objs, "");
  for(std::vector<std::string>::const_iterator
        oi = objs.begin(); oi != objs.end(); ++oi)
    {
    options += "# ADD ";
    options += tool;
    options += "32 ";
    options += this->ConvertToOutputFormat(oi->c_str(), SHELL);
    options += "\n";
    }
}

std::string
cmLocalVisualStudio6Generator
::GetTargetDirectory(cmTarget const&) const
{
  // No per-target directory for this generator (yet).
  return "";
}

//----------------------------------------------------------------------------
std::string
cmLocalVisualStudio6Generator
::ComputeLongestObjectDirectory(cmTarget&) const
{
  // Compute the maximum length configuration name.
  std::string config_max;
  for(std::vector<std::string>::const_iterator
        i = this->Configurations.begin();
      i != this->Configurations.end(); ++i)
    {
    // Strip the subdirectory name out of the configuration name.
    std::string config = this->GetConfigName(*i);
    if(config.size() > config_max.size())
      {
      config_max = config;
      }
    }

  // Compute the maximum length full path to the intermediate
  // files directory for any configuration.  This is used to construct
  // object file names that do not produce paths that are too long.
  std::string dir_max;
  dir_max += this->Makefile->GetCurrentBinaryDirectory();
  dir_max += "/";
  dir_max += config_max;
  dir_max += "/";
  return dir_max;
}

std::string
cmLocalVisualStudio6Generator
::GetConfigName(std::string const& configuration) const
{
  // Strip the subdirectory name out of the configuration name.
  std::string config = configuration;
  std::string::size_type pos = config.find_last_of(" ");
  config = config.substr(pos+1, std::string::npos);
  config = config.substr(0, config.size()-1);
  return config;
}

//----------------------------------------------------------------------------
bool
cmLocalVisualStudio6Generator
::CheckDefinition(std::string const& define) const
{
  // Perform the standard check first.
  if(!this->cmLocalGenerator::CheckDefinition(define))
    {
    return false;
    }

  // Now do the VS6-specific check.
  if(define.find_first_of(" ") != define.npos &&
     define.find_first_of("\"$;") != define.npos)
    {
    std::ostringstream e;
    e << "WARNING: The VS6 IDE does not support preprocessor definition "
      << "values with spaces and '\"', '$', or ';'.\n"
      << "CMake is dropping a preprocessor definition: " << define << "\n"
      << "Consider defining the macro in a (configured) header file.\n";
    cmSystemTools::Message(e.str().c_str());
    return false;
    }

  // Assume it is supported.
  return true;
}
