/*============================================================================
  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.h"
#include "cmCPluginAPI.cxx"
#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 const char* 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.c_str());

  // 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.c_str(), path);
    }

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

  // Report what file was loaded for this command.
  this->Makefile->AddDefinition(reportVar.c_str(), 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->AddCommand(f);
    return true;
    }
  this->SetError("Attempt to load command failed. "
                 "No init function found.");
  return false;
}

