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

#include "cmCPluginAPI.cxx"
#include "cmCPluginAPI.h"
#include "cmDynamicLoader.h"

#include <cmsys/DynamicLoader.hxx>

#include <stdlib.h>

#ifdef __QNX__
#include <malloc.h> /* for malloc/free on QNX */
#endif

#include <signal.h>
extern "C" void TrapsForSignalsCFunction(int sig);

// a class for loadabple commands
class cmLoadedCommand : public cmCommand
{
public:
  cmLoadedCommand()
  {
    memset(&this->info, 0, sizeof(this->info));
    this->info.CAPI = &cmStaticCAPI;
  }

  ///! clean up any memory allocated by the plugin
  ~cmLoadedCommand();

  /**
   * This is a virtual constructor for the command.
   */
  virtual cmCommand* Clone()
  {
    cmLoadedCommand* newC = new cmLoadedCommand;
    // we must copy when we clone
    memcpy(&newC->info, &this->info, sizeof(info));
    return newC;
  }

  /**
   * This is called when the command is first encountered in
   * the CMakeLists.txt file.
   */
  virtual bool InitialPass(std::vector<std::string> const& args,
                           cmExecutionStatus&);

  /**
   * This is called at the end after all the information
   * specified by the command is accumulated. Most commands do
   * not implement this method.  At this point, reading and
   * writing to the cache can be done.
   */
  virtual void FinalPass();
  virtual bool HasFinalPass() const
  {
    return this->info.FinalPass ? true : false;
  }

  /**
   * The name of the command as specified in CMakeList.txt.
   */
  virtual std::string GetName() const { return info.Name; }

  static const char* LastName;
  static void TrapsForSignals(int sig)
  {
    fprintf(stderr, "CMake loaded command %s crashed with signal: %d.\n",
            cmLoadedCommand::LastName, sig);
  }
  static void InstallSignalHandlers(const char* name, int remove = 0)
  {
    cmLoadedCommand::LastName = name;
    if (!name) {
      cmLoadedCommand::LastName = "????";
    }

    if (!remove) {
      signal(SIGSEGV, TrapsForSignalsCFunction);
#ifdef SIGBUS
      signal(SIGBUS, TrapsForSignalsCFunction);
#endif
      signal(SIGILL, TrapsForSignalsCFunction);
    } else {
      signal(SIGSEGV, 0);
#ifdef SIGBUS
      signal(SIGBUS, 0);
#endif
      signal(SIGILL, 0);
    }
  }

  cmTypeMacro(cmLoadedCommand, cmCommand);

  cmLoadedCommandInfo info;
};

extern "C" void TrapsForSignalsCFunction(int sig)
{
  cmLoadedCommand::TrapsForSignals(sig);
}

const char* cmLoadedCommand::LastName = 0;

bool cmLoadedCommand::InitialPass(std::vector<std::string> const& args,
                                  cmExecutionStatus&)
{
  if (!info.InitialPass) {
    return true;
  }

  // clear the error string
  if (this->info.Error) {
    free(this->info.Error);
  }

  // create argc and argv and then invoke the command
  int argc = static_cast<int>(args.size());
  char** argv = 0;
  if (argc) {
    argv = (char**)malloc(argc * sizeof(char*));
  }
  int i;
  for (i = 0; i < argc; ++i) {
    argv[i] = strdup(args[i].c_str());
  }
  cmLoadedCommand::InstallSignalHandlers(info.Name);
  int result =
    info.InitialPass((void*)&info, (void*)this->Makefile, argc, argv);
  cmLoadedCommand::InstallSignalHandlers(info.Name, 1);
  cmFreeArguments(argc, argv);

  if (result) {
    return true;
  }

  /* Initial Pass must have failed so set the error string */
  if (this->info.Error) {
    this->SetError(this->info.Error);
  }
  return false;
}

void cmLoadedCommand::FinalPass()
{
  if (this->info.FinalPass) {
    cmLoadedCommand::InstallSignalHandlers(info.Name);
    this->info.FinalPass((void*)&this->info, (void*)this->Makefile);
    cmLoadedCommand::InstallSignalHandlers(info.Name, 1);
  }
}

cmLoadedCommand::~cmLoadedCommand()
{
  if (this->info.Destructor) {
    cmLoadedCommand::InstallSignalHandlers(info.Name);
    this->info.Destructor((void*)&this->info);
    cmLoadedCommand::InstallSignalHandlers(info.Name, 1);
  }
  if (this->info.Error) {
    free(this->info.Error);
  }
}

// cmLoadCommandCommand
bool cmLoadCommandCommand::InitialPass(std::vector<std::string> const& args,
                                       cmExecutionStatus&)
{
  if (this->Disallowed(
        cmPolicies::CMP0031,
        "The load_command command should not be called; see CMP0031.")) {
    return true;
  }
  if (args.size() < 1) {
    return true;
  }

  // Construct a variable to report what file was loaded, if any.
  // Start by removing the definition in case of failure.
  std::string reportVar = "CMAKE_LOADED_COMMAND_";
  reportVar += args[0];
  this->Makefile->RemoveDefinition(reportVar);

  // the file must exist
  std::string moduleName =
    this->Makefile->GetRequiredDefinition("CMAKE_SHARED_MODULE_PREFIX");
  moduleName += "cm" + args[0];
  moduleName +=
    this->Makefile->GetRequiredDefinition("CMAKE_SHARED_MODULE_SUFFIX");

  // search for the file
  std::vector<std::string> path;
  for (unsigned int j = 1; j < args.size(); j++) {
    // expand variables
    std::string exp = args[j];
    cmSystemTools::ExpandRegistryValues(exp);

    // Glob the entry in case of wildcards.
    cmSystemTools::GlobDirs(exp, path);
  }

  // Try to find the program.
  std::string fullPath = cmSystemTools::FindFile(moduleName.c_str(), path);
  if (fullPath == "") {
    std::ostringstream e;
    e << "Attempt to load command failed from file \"" << moduleName << "\"";
    this->SetError(e.str());
    return false;
  }

  // try loading the shared library / dll
  cmsys::DynamicLoader::LibraryHandle lib =
    cmDynamicLoader::OpenLibrary(fullPath.c_str());
  if (!lib) {
    std::string err = "Attempt to load the library ";
    err += fullPath + " failed.";
    const char* error = cmsys::DynamicLoader::LastError();
    if (error) {
      err += " Additional error info is:\n";
      err += error;
    }
    this->SetError(err);
    return false;
  }

  // Report what file was loaded for this command.
  this->Makefile->AddDefinition(reportVar, fullPath.c_str());

  // find the init function
  std::string initFuncName = args[0] + "Init";
  CM_INIT_FUNCTION initFunction =
    (CM_INIT_FUNCTION)cmsys::DynamicLoader::GetSymbolAddress(
      lib, initFuncName.c_str());
  if (!initFunction) {
    initFuncName = "_";
    initFuncName += args[0];
    initFuncName += "Init";
    initFunction = (CM_INIT_FUNCTION)(
      cmsys::DynamicLoader::GetSymbolAddress(lib, initFuncName.c_str()));
  }
  // if the symbol is found call it to set the name on the
  // function blocker
  if (initFunction) {
    // create a function blocker and set it up
    cmLoadedCommand* f = new cmLoadedCommand();
    (*initFunction)(&f->info);
    this->Makefile->GetState()->AddCommand(f);
    return true;
  }
  this->SetError("Attempt to load command failed. "
                 "No init function found.");
  return false;
}
