Skip to content
Snippets Groups Projects
System.cpp 8.17 KiB
Newer Older
//-----------------------------
//Includes
//-----------------------------
#include "MantidKernel/System.h"
Campbell, Stuart's avatar
Campbell, Stuart committed
#include <Poco/Path.h>
#include <boost/shared_ptr.hpp>
#include <limits>

// Need OS defined functions
#ifdef _WIN32
  #include <windows.h>
#elif defined __linux__
  #include <sstream>
#elif defined __APPLE__
  #include <mach-o/dyld.h>
// MG 16/07/09: Some forward declarations of things from API. I need this so
// that the typeid function in getUnmangledTypeName knows about them
// This way I don't need to actually include the headers and I don't
// introduce unwanted dependencies
namespace Mantid
{
  namespace API
  {
    class Workspace;
    class MatrixWorkspace;
    class ITableWorkspace;
    class IMDEventWorkspace;
    class IMDWorkspace;
    class IEventWorkspace;
  }
  namespace DataObjects
  {
    class EventWorkspace;
    class PeaksWorkspace;
  }
  namespace MDDataObjects
  {
    class MDWorkspace;
  return DBL_MAX/2;
/// Constructor
Mantid::Kernel::RegistrationHelper::RegistrationHelper(int)
{
}

/**
 * Get the directory containing the program executable
 * @returns A string containing the path of the directory 
 * containing the executable, including a trailing slash
 */
std::string Mantid::Kernel::getDirectoryOfExecutable()
  //std::cout << "getDirectoryOfExecutable is " << Poco::Path(getPathToExecutable()).parent().toString() << std::endl
  return Poco::Path(getPathToExecutable()).parent().toString();
}

/**
  * Get the  full path the the program executable. This is not necessarily MantidPlot or a main
  * program since if we are running through Python, it is the Python executable that is considered
  * as the executing program
  * @returns A string containing the full path the the executable
  */
std::string Mantid::Kernel::getPathToExecutable()
{
  std::string execpath("");
  const size_t LEN(1024);
  char pBuf[LEN];
// The linux function returns an int, the Windows & Mac ones an unsigned type
#ifndef __linux__
  unsigned 
#endif
#ifdef _WIN32
  bytes = GetModuleFileName(NULL, pBuf, LEN);
#elif defined __linux__
  char szTmp[32];
  sprintf(szTmp, "/proc/%d/exe", getpid());
  bytes = readlink(szTmp, pBuf, LEN);
#elif defined __APPLE__
  // Two calls to _NSGetExecutablePath required - first to get size of buffer
  _NSGetExecutablePath(pBuf,&bytes);
  const int success = _NSGetExecutablePath(pBuf,&bytes);
  if (success < 0) bytes = 1025;
  if( bytes > 0 && bytes < 1024 )
  {
    pBuf[bytes] = '\0';
    execpath = std::string(pBuf);
  }
bool Mantid::Kernel::isNetworkDrive(const std::string & path)
  // if path is relative get the full one
  char buff[MAX_PATH];
  GetFullPathName(path.c_str(),MAX_PATH,buff,NULL);
  std::string fullName(buff);
  size_t i = fullName.find(':');

  // if the full path doesn't contain a drive letter assume it's on the network
  if (i == std::string::npos) return true;

  fullName.erase(i+1);
  fullName += '\\';  // make sure the name has the trailing backslash
  UINT type = GetDriveType(fullName.c_str());
  return DRIVE_REMOTE == type;
#elif defined __linux__
  // This information is only present in the /proc/mounts file on linux. There are no drives on
  // linux only mount locations therefore the test will have to check the path against
  // entries in /proc/mounts to see if the filesystem type is NFS or SMB (any others ????)
  // Each line corresponds to a particular mounted location
  // 1st column - device name
  // 2nd column - mounted location
  // 3rd column - filesystem type commonly ext2, ext3 for hard drives and NFS or SMB for
  //              network locations
  std::ifstream mntfile("/proc/mounts");
  std::string txtread("");
  while( getline(mntfile, txtread) )
  {
    std::istringstream strm(txtread);
    std::string devname(""), mntpoint(""), fstype("");
    strm >> devname >> mntpoint >> fstype;
    if( !strm ) continue;
    // I can't be sure that the file system type is always lower case
    std::transform(fstype.begin(), fstype.end(), fstype.begin(), toupper);
    // Skip the current line if the file system isn't a network one
    if( fstype != "NFS" && fstype != "SMB" ) continue;
    // Now we have a line containing a network filesystem and just need to check if the path
    // supplied contains the mount location. There is a small complication in that the mount
    // points within the file have certain characters transformed into their octal 
    // representations, for example spaces->040.
    std::string::size_type idx = mntpoint.find("\\0");
    if( idx != std::string::npos ) 
      std::string oct = mntpoint.substr(idx + 1, 3);
      strm.str(oct);
      int printch(-1);
      strm.setf( std::ios::oct, std::ios::basefield );  
      strm >> printch;
      if( printch != -1 )
      { 
        mntpoint = mntpoint.substr(0, idx) + static_cast<char>(printch) + mntpoint.substr(idx + 4);
      }
      // Search for this at the start of the path
      if( path.find(mntpoint) == 0 ) return true;
    }     
  }
  return false;
#else
  // Not yet implemented for the mac
  return false;

/**
 * Get the unmangled name of the given typestring for some common types that we use. Note that
 * this is just a lookup and NOT an unmangling algorithm
 * @param type :: A pointer to the type_info object for this type
 * @returns An unmangled version of the name
 */
std::string  Mantid::Kernel::getUnmangledTypeName(const std::type_info& type)
{
  // Compile a lookup table. This is a static local variable that
  // will get initialized when the function is first used
  static std::map<std::string, std::string> typestrings;
  if( typestrings.empty() ) 
  {
    typestrings.insert(std::make_pair(typeid(char).name(), std::string("letter")));
    typestrings.insert(std::make_pair(typeid(int).name(), std::string("number")));
    typestrings.insert(std::make_pair(typeid(long long).name(), std::string("number")));
    typestrings.insert(std::make_pair(typeid(double).name(), std::string("number")));
    typestrings.insert(std::make_pair(typeid(bool).name(), std::string("boolean")));
    typestrings.insert(std::make_pair(typeid(std::string).name(), std::string("string")));
    typestrings.insert(std::make_pair(typeid(std::vector<std::string>).name(), std::string("str list")));
    typestrings.insert(std::make_pair(typeid(std::vector<int>).name(), std::string("int list")));
    typestrings.insert(std::make_pair(typeid(std::vector<double>).name(), std::string("dbl list")));
    typestrings.insert(std::make_pair(typeid(boost::shared_ptr<Mantid::API::Workspace>).name(), std::string("Workspace")));
    typestrings.insert(std::make_pair(typeid(boost::shared_ptr<Mantid::API::MatrixWorkspace>).name(), std::string("MatrixWorkspace")));
    typestrings.insert(std::make_pair(typeid(boost::shared_ptr<Mantid::API::ITableWorkspace>).name(), std::string("TableWorkspace")));
    typestrings.insert(std::make_pair(typeid(boost::shared_ptr<Mantid::API::IMDWorkspace>).name(), std::string("IMDWorkspace")));
    typestrings.insert(std::make_pair(typeid(boost::shared_ptr<Mantid::API::IMDEventWorkspace>).name(), std::string("MDEventWorkspace")));
    typestrings.insert(std::make_pair(typeid(boost::shared_ptr<Mantid::API::IEventWorkspace>).name(), std::string("IEventWorkspace")));
    typestrings.insert(std::make_pair(typeid(boost::shared_ptr<Mantid::DataObjects::EventWorkspace>).name(), std::string("EventWorkspace")));
    typestrings.insert(std::make_pair(typeid(boost::shared_ptr<Mantid::DataObjects::PeaksWorkspace>).name(), std::string("PeaksWorkspace")));
    typestrings.insert(std::make_pair(typeid(boost::shared_ptr<Mantid::MDDataObjects::MDWorkspace>).name(), std::string("MDWorkspace")));


  }
  std::map<std::string, std::string>::const_iterator mitr = typestrings.find(type.name());
  if( mitr != typestrings.end() )
  {
    return mitr->second;
  }

  return type.name();

}