/*============================================================================
  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 "cmGeneratorExpression.h"

#include "cmMakefile.h"
#include "cmTarget.h"

//----------------------------------------------------------------------------
cmGeneratorExpression::cmGeneratorExpression(
  cmMakefile* mf, const char* config,
  cmListFileBacktrace const& backtrace):
  Makefile(mf), Config(config), Backtrace(backtrace)
{
  this->TargetInfo.compile("^\\$<TARGET"
                           "(|_SONAME|_LINKER)"  // File with what purpose?
                           "_FILE(|_NAME|_DIR):" // Filename component.
                           "([A-Za-z0-9_-]+)"    // Target name.
                           ">$");
}

//----------------------------------------------------------------------------
const char* cmGeneratorExpression::Process(std::string const& input)
{
  return this->Process(input.c_str());
}

//----------------------------------------------------------------------------
const char* cmGeneratorExpression::Process(const char* input)
{
  this->Data.clear();

  // We construct and evaluate expressions directly in the output
  // buffer.  Each expression is replaced by its own output value
  // after evaluation.  A stack of barriers records the starting
  // indices of open (pending) expressions.
  for(const char* c = input; *c; ++c)
    {
    if(c[0] == '$' && c[1] == '<')
      {
      this->Barriers.push(this->Data.size());
      this->Data.push_back('$');
      this->Data.push_back('<');
      c += 1;
      }
    else if(c[0] == '>' && !this->Barriers.empty())
      {
      this->Data.push_back('>');
      if(!this->Evaluate()) { break; }
      this->Barriers.pop();
      }
    else
      {
      this->Data.push_back(c[0]);
      }
    }

  // Return a null-terminated output value.
  this->Data.push_back('\0');
  return &*this->Data.begin();
}

//----------------------------------------------------------------------------
bool cmGeneratorExpression::Evaluate()
{
  // The top-most barrier points at the beginning of the expression.
  size_t barrier = this->Barriers.top();

  // Construct a null-terminated representation of the expression.
  this->Data.push_back('\0');
  const char* expr = &*(this->Data.begin()+barrier);

  // Evaluate the expression.
  std::string result;
  if(this->Evaluate(expr, result))
    {
    // Success.  Replace the expression with its evaluation result.
    this->Data.erase(this->Data.begin()+barrier, this->Data.end());
    this->Data.insert(this->Data.end(), result.begin(), result.end());
    return true;
    }
  else
    {
    // Failure.  Report the error message.
    cmOStringStream e;
    e << "Error evaluating generator expression:\n"
      << "  " << expr << "\n"
      << result;
    this->Makefile->GetCMakeInstance()
      ->IssueMessage(cmake::FATAL_ERROR, e.str().c_str(),
                     this->Backtrace);
    return false;
    }
}

//----------------------------------------------------------------------------
bool cmGeneratorExpression::Evaluate(const char* expr, std::string& result)
{
  if(this->TargetInfo.find(expr))
    {
    if(!this->EvaluateTargetInfo(result))
      {
      return false;
      }
    }
  else if(strcmp(expr, "$<CONFIGURATION>") == 0)
    {
    result = this->Config? this->Config : "";
    }
  else
    {
    result = "Expression syntax not recognized.";
    return false;
    }
  return true;
}

//----------------------------------------------------------------------------
bool cmGeneratorExpression::EvaluateTargetInfo(std::string& result)
{
  // Lookup the referenced target.
  std::string name = this->TargetInfo.match(3);
  cmTarget* target = this->Makefile->FindTargetToUse(name.c_str());
  if(!target)
    {
    result = "No target \"" + name + "\"";
    return false;
    }
  if(target->GetType() >= cmTarget::UTILITY &&
     target->GetType() != cmTarget::UNKNOWN_LIBRARY)
    {
    result = "Target \"" + name + "\" is not an executable or library.";
    return false;
    }

  // Lookup the target file with the given purpose.
  std::string purpose = this->TargetInfo.match(1);
  if(purpose == "")
    {
    // The target implementation file (.so.1.2, .dll, .exe, .a).
    result = target->GetFullPath(this->Config, false, true);
    }
  else if(purpose == "_LINKER")
    {
    // The file used to link to the target (.so, .lib, .a).
    if(!target->IsLinkable())
      {
      result = ("TARGET_LINKER_FILE is allowed only for libraries and "
                "executables with ENABLE_EXPORTS.");
      return false;
      }
    result = target->GetFullPath(this->Config, target->HasImportLibrary());
    }
  else if(purpose == "_SONAME")
    {
    // The target soname file (.so.1).
    if(target->IsDLLPlatform())
      {
      result = "TARGET_SONAME_FILE is not allowed for DLL target platforms.";
      return false;
      }
    if(target->GetType() != cmTarget::SHARED_LIBRARY)
      {
      result = "TARGET_SONAME_FILE is allowed only for SHARED libraries.";
      return false;
      }
    result = target->GetDirectory(this->Config);
    result += "/";
    result += target->GetSOName(this->Config);
    }

  // Extract the requested portion of the full path.
  std::string part = this->TargetInfo.match(2);
  if(part == "_NAME")
    {
    result = cmSystemTools::GetFilenameName(result);
    }
  else if(part == "_DIR")
    {
    result = cmSystemTools::GetFilenamePath(result);
    }
  return true;
}
