<commit_before>//------------------------------------------------------------------------------
// CLING - the C++ LLVM-based InterpreterG :)
// author:  Vassil Vassilev <vasil.georgiev.vasilev@cern.ch>
//
// This file is dual-licensed: you can choose to license it under the University
// of Illinois Open Source License or the GNU Lesser General Public License. See
// LICENSE.TXT for details.
//------------------------------------------------------------------------------

#include "cling/Interpreter/DynamicLibraryManager.h"
#include "cling/Interpreter/InvocationOptions.h"

#include "llvm/Support/DynamicLibrary.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/raw_ostream.h"

#include <stdlib.h>
#include <algorithm>
#include <iostream>
#include <stdio.h>

#ifdef WIN32
#include <Windows.h>
#include <shlobj.h>
#else
#include <limits.h> /* PATH_MAX */
#include <dlfcn.h>
#endif

namespace {
#if defined(LLVM_ON_UNIX)
  static void GetSystemLibraryPaths(llvm::SmallVectorImpl<std::string>& Paths) {
    char* env_var = getenv("LD_LIBRARY_PATH");
#if __APPLE__
    if (!env_var)
      env_var = getenv("DYLD_LIBRARY_PATH");
    if (!env_var)
      env_var = getenv("DYLD_FALLBACK_LIBRARY_PATH");
#endif
    if (env_var != 0) {
      static const char PathSeparator = ':';
      const char* at = env_var;
      const char* delim = strchr(at, PathSeparator);
      while (delim != 0) {
        std::string tmp(at, size_t(delim-at));
        if (llvm::sys::fs::is_directory(tmp.c_str()))
          Paths.push_back(tmp);
        at = delim + 1;
        delim = strchr(at, PathSeparator);
      }

      if (*at != 0)
        if (llvm::sys::fs::is_directory(llvm::StringRef(at)))
          Paths.push_back(at);
    }
#if defined(__APPLE__) || defined(__CYGWIN__)
    Paths.push_back("/usr/local/lib/");
    Paths.push_back("/usr/X11R6/lib/");
    Paths.push_back("/usr/lib/");
    Paths.push_back("/lib/");

    Paths.push_back("/lib/x86_64-linux-gnu/");
    Paths.push_back("/usr/local/lib64/");
    Paths.push_back("/usr/lib64/");
    Paths.push_back("/lib64/");
#else
    static bool initialized = false;
    static std::vector<std::string> SysPaths;
    if (!initialized) {
      // trick to get the system search path
      std::string cmd("LD_DEBUG=libs LD_PRELOAD=DOESNOTEXIST ls 2>&1");
      FILE *pf = popen(cmd.c_str (), "r");
      std::string result = "";
      std::string sys_path = "";
      char buffer[128];
      while (!feof(pf)) {
        if (fgets(buffer, 128, pf) != NULL)
          result += buffer;
      }
      pclose(pf);
      std::size_t from
        = result.find("search path=", result.find("(LD_LIBRARY_PATH)"));
      std::size_t to = result.find("(system search path)");
      if (from != std::string::npos && to != std::string::npos) {
        from += 12;
        sys_path = result.substr(from, to-from);
        sys_path.erase(std::remove_if(sys_path.begin(), sys_path.end(), isspace),
                       sys_path.end());
        sys_path += ':';
      }
      static const char PathSeparator = ':';
      const char* at = sys_path.c_str();
      const char* delim = strchr(at, PathSeparator);
      while (delim != 0) {
        std::string tmp(at, size_t(delim-at));
        if (llvm::sys::fs::is_directory(tmp.c_str()))
          SysPaths.push_back(tmp);
        at = delim + 1;
        delim = strchr(at, PathSeparator);
      }
      initialized = true;
    }

    for (std::vector<std::string>::const_iterator I = SysPaths.begin(),
           E = SysPaths.end(); I != E; ++I)
      Paths.push_back((*I).c_str());
#endif
  }
#elif defined(LLVM_ON_WIN32)
  static void GetSystemLibraryPaths(llvm::SmallVectorImpl<std::string>& Paths) {
    char buff[MAX_PATH];
    // Generic form of C:\Windows\System32
    HRESULT res =  SHGetFolderPathA(NULL,
                                    CSIDL_FLAG_CREATE | CSIDL_SYSTEM,
                                    NULL,
                                    SHGFP_TYPE_CURRENT,
                                    buff);
    if (res != S_OK) {
      assert(0 && "Failed to get system directory");
      return;
    }
    Paths.push_back(buff);

    // Reset buff.
    buff[0] = 0;
    // Generic form of C:\Windows
    res =  SHGetFolderPathA(NULL,
                            CSIDL_FLAG_CREATE | CSIDL_WINDOWS,
                            NULL,
                            SHGFP_TYPE_CURRENT,
                            buff);
    if (res != S_OK) {
      assert(0 && "Failed to get windows directory");
      return;
    }
    Paths.push_back(buff);
  }
#else
# error "Unsupported platform."
#endif

}

namespace cling {
  DynamicLibraryManager::DynamicLibraryManager(const InvocationOptions& Opts)
    : m_Opts(Opts) {
    GetSystemLibraryPaths(m_SystemSearchPaths);
    m_SystemSearchPaths.push_back(".");
  }

  DynamicLibraryManager::~DynamicLibraryManager() {}

  static bool isSharedLib(llvm::StringRef LibName, bool* exists = 0) {
    using namespace llvm::sys::fs;
    file_magic Magic;
    llvm::error_code Error = identify_magic(LibName, Magic);
    bool onDisk = (Error == llvm::errc::success);
    if (exists)
      *exists = onDisk;

    return onDisk &&
#ifdef __APPLE__
      (Magic == file_magic::macho_fixed_virtual_memory_shared_lib
       || Magic == file_magic::macho_dynamically_linked_shared_lib
       || Magic == file_magic::macho_dynamically_linked_shared_lib_stub)
#elif defined(LLVM_ON_UNIX)
#ifdef __CYGWIN__
      (Magic == file_magic::pecoff_executable)
#else
      (Magic == file_magic::elf_shared_object)
#endif
#elif defined(LLVM_ON_WIN32)
      (Magic == file_magic::pecoff_executable)
#else
# error "Unsupported platform."
#endif
      ;
  }

  std::string
  DynamicLibraryManager::lookupLibInPaths(llvm::StringRef libStem) const {
    llvm::SmallVector<std::string, 128>
      Paths(m_Opts.LibSearchPath.begin(), m_Opts.LibSearchPath.end());
    Paths.append(m_SystemSearchPaths.begin(), m_SystemSearchPaths.end());

    for (llvm::SmallVectorImpl<std::string>::const_iterator
           IPath = Paths.begin(), E = Paths.end();IPath != E; ++IPath) {
      llvm::SmallString<512> ThisPath(*IPath); // FIXME: move alloc outside loop
      llvm::sys::path::append(ThisPath, libStem);
      bool exists;
      if (isSharedLib(ThisPath.str(), &exists))
        return ThisPath.str();
      if (exists)
        return "";
    }
    return "";
  }

  std::string
  DynamicLibraryManager::lookupLibMaybeAddExt(llvm::StringRef libStem) const {
    using namespace llvm::sys;

    std::string foundDyLib = lookupLibInPaths(libStem);

    if (foundDyLib.empty()) {
      // Add DyLib extension:
      llvm::SmallString<512> filenameWithExt(libStem);
#if defined(LLVM_ON_UNIX)
#ifdef __APPLE__
      llvm::SmallString<512>::iterator IStemEnd = filenameWithExt.end() - 1;
#endif
      static const char* DyLibExt = ".so";
#elif defined(LLVM_ON_WIN32)
      static const char* DyLibExt = ".dll";
#else
# error "Unsupported platform."
#endif
      filenameWithExt += DyLibExt;
      foundDyLib = lookupLibInPaths(filenameWithExt);
#ifdef __APPLE__
      if (foundDyLib.empty()) {
        filenameWithExt.erase(IStemEnd + 1, filenameWithExt.end());
        filenameWithExt += ".dylib";
        foundDyLib = lookupLibInPaths(filenameWithExt);
      }
#endif
    }

    if (foundDyLib.empty())
      return "";

    // get canonical path name and check if already loaded
#if defined(LLVM_ON_WIN32)
    llvm::SmallString<_MAX_PATH> FullPath("");
    char *res = _fullpath((char *)FullPath.data(), foundDyLib.c_str(), _MAX_PATH);
#else
    llvm::SmallString<PATH_MAX+1> FullPath("");
    char *res = realpath(foundDyLib.c_str(), (char *)FullPath.data());
#endif
    if (res == 0) {
      llvm::errs() << "cling::Interpreter::tryLinker(): error getting real "
        "(canonical) path of library " << foundDyLib << '\n';
      return foundDyLib;
    }
    FullPath.set_size(strlen(res));
    return FullPath.str();
  }

  std::string
  DynamicLibraryManager::lookupLibrary(llvm::StringRef libStem) const {
    llvm::SmallString<128> Absolute(libStem);
    llvm::sys::fs::make_absolute(Absolute);
    bool isAbsolute = libStem == Absolute;

    // If it is an absolute path, don't try iterate over the paths.
    if (isAbsolute) {
      if (isSharedLib(libStem))
        return libStem;
      else
        return "";
    }

    std::string foundName = lookupLibMaybeAddExt(libStem);
    if (foundName.empty() && !libStem.startswith("lib")) {
      // try with "lib" prefix:
      foundName = lookupLibMaybeAddExt("lib" + libStem.str());
    }

    if (isSharedLib(foundName))
      return foundName;
    return "";
  }

  DynamicLibraryManager::LoadLibResult
  DynamicLibraryManager::loadLibrary(const std::string& libStem,
                                     bool permanent) {
    std::string canonicalLoadedLib = lookupLibrary(libStem);
    if (canonicalLoadedLib.empty())
      return kLoadLibNotFound;

    if (m_LoadedLibraries.find(canonicalLoadedLib) != m_LoadedLibraries.end())
      return kLoadLibAlreadyLoaded;

    std::string errMsg;
    // TODO: !permanent case
#if defined(LLVM_ON_WIN32)
    HMODULE dyLibHandle = LoadLibraryEx(canonicalLoadedLib.c_str(), NULL,
                                        DONT_RESOLVE_DLL_REFERENCES);
    errMsg = "LoadLibraryEx: GetLastError() returned ";
    errMsg += GetLastError();
#else
    const void* dyLibHandle = dlopen(canonicalLoadedLib.c_str(),
                                     RTLD_LAZY|RTLD_GLOBAL);
    if (const char* DyLibError = dlerror()) {
      errMsg = DyLibError;
    }
#endif
    if (!dyLibHandle) {
      llvm::errs() << "cling::DyLibMan::loadLibrary(): " << errMsg << '\n';
      return kLoadLibLoadError;
    }
    std::pair<DyLibs::iterator, bool> insRes
      = m_DyLibs.insert(std::pair<DyLibHandle, std::string>(dyLibHandle,
                                                            canonicalLoadedLib));
    if (!insRes.second)
      return kLoadLibAlreadyLoaded;
    m_LoadedLibraries.insert(canonicalLoadedLib);
    return kLoadLibSuccess;
  }

  void DynamicLibraryManager::unloadLibrary(llvm::StringRef libStem) {
    std::string canonicalLoadedLib = lookupLibrary(libStem);
    if (!isLibraryLoaded(canonicalLoadedLib))
      return;

    DyLibHandle dyLibHandle = 0;
    for (DyLibs::const_iterator I = m_DyLibs.begin(), E = m_DyLibs.end();
         I != E; ++I) {
      if (I->second == canonicalLoadedLib)
        dyLibHandle = I->first;
    }

    std::string errMsg;
    // TODO: !permanent case
#if defined(LLVM_ON_WIN32)
    UnloadLibraryEx(dyLibHandle);
    errMsg = "UnoadLibraryEx: GetLastError() returned ";
    errMsg += GetLastError();
#else
    dlclose(const_cast<void*>(dyLibHandle));
    if (const char* DyLibError = dlerror()) {
      errMsg = DyLibError;
    }
#endif
    m_DyLibs.erase(dyLibHandle);
    m_LoadedLibraries.erase(canonicalLoadedLib);
  }

  bool DynamicLibraryManager::isLibraryLoaded(llvm::StringRef fullPath) const {
    // get canonical path name and check if already loaded
#if defined(LLVM_ON_WIN32)
    char buf[_MAX_PATH];
    char *res = _fullpath(buf, fullPath.str().c_str(), _MAX_PATH);
#else
    char buf[PATH_MAX+1];
    char *res = realpath(fullPath.str().c_str(), buf);
#endif
    if (res == 0) {
      llvm::errs() << "cling::Interpreter::isDynamicLibraryLoaded(): error getting real (canonical) path\n";
      return false;
    }
    if (m_LoadedLibraries.find(buf) != m_LoadedLibraries.end()) return true;
    return false;
  }

  void DynamicLibraryManager::ExposeHiddenSharedLibrarySymbols(void* handle) {
    llvm::sys::DynamicLibrary::addPermanentLibrary(const_cast<void*>(handle));
  }
} // end namespace cling
<commit_msg>Name order.<commit_after>//------------------------------------------------------------------------------
// CLING - the C++ LLVM-based InterpreterG :)
// author:  Vassil Vassilev <vasil.georgiev.vasilev@cern.ch>
//
// This file is dual-licensed: you can choose to license it under the University
// of Illinois Open Source License or the GNU Lesser General Public License. See
// LICENSE.TXT for details.
//------------------------------------------------------------------------------

#include "cling/Interpreter/DynamicLibraryManager.h"
#include "cling/Interpreter/InvocationOptions.h"

#include "llvm/Support/DynamicLibrary.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/raw_ostream.h"

#include <algorithm>
#include <iostream>
#include <stdio.h>
#include <stdlib.h>

#ifdef WIN32
#include <Windows.h>
#include <shlobj.h>
#else
#include <limits.h> /* PATH_MAX */
#include <dlfcn.h>
#endif

namespace {
#if defined(LLVM_ON_UNIX)
  static void GetSystemLibraryPaths(llvm::SmallVectorImpl<std::string>& Paths) {
    char* env_var = getenv("LD_LIBRARY_PATH");
#if __APPLE__
    if (!env_var)
      env_var = getenv("DYLD_LIBRARY_PATH");
    if (!env_var)
      env_var = getenv("DYLD_FALLBACK_LIBRARY_PATH");
#endif
    if (env_var != 0) {
      static const char PathSeparator = ':';
      const char* at = env_var;
      const char* delim = strchr(at, PathSeparator);
      while (delim != 0) {
        std::string tmp(at, size_t(delim-at));
        if (llvm::sys::fs::is_directory(tmp.c_str()))
          Paths.push_back(tmp);
        at = delim + 1;
        delim = strchr(at, PathSeparator);
      }

      if (*at != 0)
        if (llvm::sys::fs::is_directory(llvm::StringRef(at)))
          Paths.push_back(at);
    }
#if defined(__APPLE__) || defined(__CYGWIN__)
    Paths.push_back("/usr/local/lib/");
    Paths.push_back("/usr/X11R6/lib/");
    Paths.push_back("/usr/lib/");
    Paths.push_back("/lib/");

    Paths.push_back("/lib/x86_64-linux-gnu/");
    Paths.push_back("/usr/local/lib64/");
    Paths.push_back("/usr/lib64/");
    Paths.push_back("/lib64/");
#else
    static bool initialized = false;
    static std::vector<std::string> SysPaths;
    if (!initialized) {
      // trick to get the system search path
      std::string cmd("LD_DEBUG=libs LD_PRELOAD=DOESNOTEXIST ls 2>&1");
      FILE *pf = popen(cmd.c_str (), "r");
      std::string result = "";
      std::string sys_path = "";
      char buffer[128];
      while (!feof(pf)) {
        if (fgets(buffer, 128, pf) != NULL)
          result += buffer;
      }
      pclose(pf);
      std::size_t from
        = result.find("search path=", result.find("(LD_LIBRARY_PATH)"));
      std::size_t to = result.find("(system search path)");
      if (from != std::string::npos && to != std::string::npos) {
        from += 12;
        sys_path = result.substr(from, to-from);
        sys_path.erase(std::remove_if(sys_path.begin(), sys_path.end(), isspace),
                       sys_path.end());
        sys_path += ':';
      }
      static const char PathSeparator = ':';
      const char* at = sys_path.c_str();
      const char* delim = strchr(at, PathSeparator);
      while (delim != 0) {
        std::string tmp(at, size_t(delim-at));
        if (llvm::sys::fs::is_directory(tmp.c_str()))
          SysPaths.push_back(tmp);
        at = delim + 1;
        delim = strchr(at, PathSeparator);
      }
      initialized = true;
    }

    for (std::vector<std::string>::const_iterator I = SysPaths.begin(),
           E = SysPaths.end(); I != E; ++I)
      Paths.push_back((*I).c_str());
#endif
  }
#elif defined(LLVM_ON_WIN32)
  static void GetSystemLibraryPaths(llvm::SmallVectorImpl<std::string>& Paths) {
    char buff[MAX_PATH];
    // Generic form of C:\Windows\System32
    HRESULT res =  SHGetFolderPathA(NULL,
                                    CSIDL_FLAG_CREATE | CSIDL_SYSTEM,
                                    NULL,
                                    SHGFP_TYPE_CURRENT,
                                    buff);
    if (res != S_OK) {
      assert(0 && "Failed to get system directory");
      return;
    }
    Paths.push_back(buff);

    // Reset buff.
    buff[0] = 0;
    // Generic form of C:\Windows
    res =  SHGetFolderPathA(NULL,
                            CSIDL_FLAG_CREATE | CSIDL_WINDOWS,
                            NULL,
                            SHGFP_TYPE_CURRENT,
                            buff);
    if (res != S_OK) {
      assert(0 && "Failed to get windows directory");
      return;
    }
    Paths.push_back(buff);
  }
#else
# error "Unsupported platform."
#endif

}

namespace cling {
  DynamicLibraryManager::DynamicLibraryManager(const InvocationOptions& Opts)
    : m_Opts(Opts) {
    GetSystemLibraryPaths(m_SystemSearchPaths);
    m_SystemSearchPaths.push_back(".");
  }

  DynamicLibraryManager::~DynamicLibraryManager() {}

  static bool isSharedLib(llvm::StringRef LibName, bool* exists = 0) {
    using namespace llvm::sys::fs;
    file_magic Magic;
    llvm::error_code Error = identify_magic(LibName, Magic);
    bool onDisk = (Error == llvm::errc::success);
    if (exists)
      *exists = onDisk;

    return onDisk &&
#ifdef __APPLE__
      (Magic == file_magic::macho_fixed_virtual_memory_shared_lib
       || Magic == file_magic::macho_dynamically_linked_shared_lib
       || Magic == file_magic::macho_dynamically_linked_shared_lib_stub)
#elif defined(LLVM_ON_UNIX)
#ifdef __CYGWIN__
      (Magic == file_magic::pecoff_executable)
#else
      (Magic == file_magic::elf_shared_object)
#endif
#elif defined(LLVM_ON_WIN32)
      (Magic == file_magic::pecoff_executable)
#else
# error "Unsupported platform."
#endif
      ;
  }

  std::string
  DynamicLibraryManager::lookupLibInPaths(llvm::StringRef libStem) const {
    llvm::SmallVector<std::string, 128>
      Paths(m_Opts.LibSearchPath.begin(), m_Opts.LibSearchPath.end());
    Paths.append(m_SystemSearchPaths.begin(), m_SystemSearchPaths.end());

    for (llvm::SmallVectorImpl<std::string>::const_iterator
           IPath = Paths.begin(), E = Paths.end();IPath != E; ++IPath) {
      llvm::SmallString<512> ThisPath(*IPath); // FIXME: move alloc outside loop
      llvm::sys::path::append(ThisPath, libStem);
      bool exists;
      if (isSharedLib(ThisPath.str(), &exists))
        return ThisPath.str();
      if (exists)
        return "";
    }
    return "";
  }

  std::string
  DynamicLibraryManager::lookupLibMaybeAddExt(llvm::StringRef libStem) const {
    using namespace llvm::sys;

    std::string foundDyLib = lookupLibInPaths(libStem);

    if (foundDyLib.empty()) {
      // Add DyLib extension:
      llvm::SmallString<512> filenameWithExt(libStem);
#if defined(LLVM_ON_UNIX)
#ifdef __APPLE__
      llvm::SmallString<512>::iterator IStemEnd = filenameWithExt.end() - 1;
#endif
      static const char* DyLibExt = ".so";
#elif defined(LLVM_ON_WIN32)
      static const char* DyLibExt = ".dll";
#else
# error "Unsupported platform."
#endif
      filenameWithExt += DyLibExt;
      foundDyLib = lookupLibInPaths(filenameWithExt);
#ifdef __APPLE__
      if (foundDyLib.empty()) {
        filenameWithExt.erase(IStemEnd + 1, filenameWithExt.end());
        filenameWithExt += ".dylib";
        foundDyLib = lookupLibInPaths(filenameWithExt);
      }
#endif
    }

    if (foundDyLib.empty())
      return "";

    // get canonical path name and check if already loaded
#if defined(LLVM_ON_WIN32)
    llvm::SmallString<_MAX_PATH> FullPath("");
    char *res = _fullpath((char *)FullPath.data(), foundDyLib.c_str(), _MAX_PATH);
#else
    llvm::SmallString<PATH_MAX+1> FullPath("");
    char *res = realpath(foundDyLib.c_str(), (char *)FullPath.data());
#endif
    if (res == 0) {
      llvm::errs() << "cling::Interpreter::tryLinker(): error getting real "
        "(canonical) path of library " << foundDyLib << '\n';
      return foundDyLib;
    }
    FullPath.set_size(strlen(res));
    return FullPath.str();
  }

  std::string
  DynamicLibraryManager::lookupLibrary(llvm::StringRef libStem) const {
    llvm::SmallString<128> Absolute(libStem);
    llvm::sys::fs::make_absolute(Absolute);
    bool isAbsolute = libStem == Absolute;

    // If it is an absolute path, don't try iterate over the paths.
    if (isAbsolute) {
      if (isSharedLib(libStem))
        return libStem;
      else
        return "";
    }

    std::string foundName = lookupLibMaybeAddExt(libStem);
    if (foundName.empty() && !libStem.startswith("lib")) {
      // try with "lib" prefix:
      foundName = lookupLibMaybeAddExt("lib" + libStem.str());
    }

    if (isSharedLib(foundName))
      return foundName;
    return "";
  }

  DynamicLibraryManager::LoadLibResult
  DynamicLibraryManager::loadLibrary(const std::string& libStem,
                                     bool permanent) {
    std::string canonicalLoadedLib = lookupLibrary(libStem);
    if (canonicalLoadedLib.empty())
      return kLoadLibNotFound;

    if (m_LoadedLibraries.find(canonicalLoadedLib) != m_LoadedLibraries.end())
      return kLoadLibAlreadyLoaded;

    std::string errMsg;
    // TODO: !permanent case
#if defined(LLVM_ON_WIN32)
    HMODULE dyLibHandle = LoadLibraryEx(canonicalLoadedLib.c_str(), NULL,
                                        DONT_RESOLVE_DLL_REFERENCES);
    errMsg = "LoadLibraryEx: GetLastError() returned ";
    errMsg += GetLastError();
#else
    const void* dyLibHandle = dlopen(canonicalLoadedLib.c_str(),
                                     RTLD_LAZY|RTLD_GLOBAL);
    if (const char* DyLibError = dlerror()) {
      errMsg = DyLibError;
    }
#endif
    if (!dyLibHandle) {
      llvm::errs() << "cling::DyLibMan::loadLibrary(): " << errMsg << '\n';
      return kLoadLibLoadError;
    }
    std::pair<DyLibs::iterator, bool> insRes
      = m_DyLibs.insert(std::pair<DyLibHandle, std::string>(dyLibHandle,
                                                            canonicalLoadedLib));
    if (!insRes.second)
      return kLoadLibAlreadyLoaded;
    m_LoadedLibraries.insert(canonicalLoadedLib);
    return kLoadLibSuccess;
  }

  void DynamicLibraryManager::unloadLibrary(llvm::StringRef libStem) {
    std::string canonicalLoadedLib = lookupLibrary(libStem);
    if (!isLibraryLoaded(canonicalLoadedLib))
      return;

    DyLibHandle dyLibHandle = 0;
    for (DyLibs::const_iterator I = m_DyLibs.begin(), E = m_DyLibs.end();
         I != E; ++I) {
      if (I->second == canonicalLoadedLib)
        dyLibHandle = I->first;
    }

    std::string errMsg;
    // TODO: !permanent case
#if defined(LLVM_ON_WIN32)
    UnloadLibraryEx(dyLibHandle);
    errMsg = "UnoadLibraryEx: GetLastError() returned ";
    errMsg += GetLastError();
#else
    dlclose(const_cast<void*>(dyLibHandle));
    if (const char* DyLibError = dlerror()) {
      errMsg = DyLibError;
    }
#endif
    m_DyLibs.erase(dyLibHandle);
    m_LoadedLibraries.erase(canonicalLoadedLib);
  }

  bool DynamicLibraryManager::isLibraryLoaded(llvm::StringRef fullPath) const {
    // get canonical path name and check if already loaded
#if defined(LLVM_ON_WIN32)
    char buf[_MAX_PATH];
    char *res = _fullpath(buf, fullPath.str().c_str(), _MAX_PATH);
#else
    char buf[PATH_MAX+1];
    char *res = realpath(fullPath.str().c_str(), buf);
#endif
    if (res == 0) {
      llvm::errs() << "cling::Interpreter::isDynamicLibraryLoaded(): error getting real (canonical) path\n";
      return false;
    }
    if (m_LoadedLibraries.find(buf) != m_LoadedLibraries.end()) return true;
    return false;
  }

  void DynamicLibraryManager::ExposeHiddenSharedLibrarySymbols(void* handle) {
    llvm::sys::DynamicLibrary::addPermanentLibrary(const_cast<void*>(handle));
  }
} // end namespace cling
<|endoftext|>


<commit_before>//------------------------------------------------------------------------------
// CLING - the C++ LLVM-based InterpreterG :)
// version: $Id$
// author:  Vassil Vassilev <vasil.georgiev.vasilev@cern.ch>
//------------------------------------------------------------------------------

#include "cling/Interpreter/DynamicLibraryManager.h"
#include "cling/Interpreter/InvocationOptions.h"

#include "llvm/Support/DynamicLibrary.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/raw_ostream.h"

#ifdef WIN32
#include <Windows.h>
#else
#include <dlfcn.h>
#endif

namespace cling {
  DynamicLibraryManager::DynamicLibraryManager(const InvocationOptions& Opts)
    : m_Opts(Opts) { }

  DynamicLibraryManager::~DynamicLibraryManager() {}

  static bool isSharedLib(llvm::StringRef LibName, bool& exists) {
    using namespace llvm::sys::fs;
    file_magic Magic;
    llvm::error_code Error = identify_magic(LibName, Magic);
    exists = (Error == llvm::errc::success);
    return exists &&
#ifdef __APPLE__
        (Magic == file_magic::macho_fixed_virtual_memory_shared_lib
         || Magic == file_magic::macho_dynamically_linked_shared_lib
         || Magic == file_magic::macho_dynamically_linked_shared_lib_stub)
#elif defined(LLVM_ON_UNIX)
        Magic == file_magic::elf_shared_object
#elif defined(LLVM_ON_WIN32)
# error "Windows DLLs  not yet implemented!"
        //Magic == file_magic::pecoff_executable?
#else
# error "Unsupported platform."
#endif
      ;
  }

  static void
  findSharedLibrary(llvm::StringRef fileStem,
                    const llvm::SmallVectorImpl<std::string>& Paths,
                    llvm::SmallString<512>& FoundDyLib,
                    bool& exists, bool& isDyLib) {
    for (llvm::SmallVectorImpl<std::string>::const_iterator
        IPath = Paths.begin(), EPath = Paths.end(); IPath != EPath; ++IPath) {
      llvm::SmallString<512> ThisPath(*IPath);
      llvm::sys::path::append(ThisPath, fileStem);
      isDyLib = isSharedLib(ThisPath.str(), exists);
      if (isDyLib)
        ThisPath.swap(FoundDyLib);
      if (exists)
        return;
    }
  }

#if defined(LLVM_ON_UNIX)
  static void GetSystemLibraryPaths(llvm::SmallVectorImpl<std::string>& Paths) {
    char* env_var = getenv("LD_LIBRARY_PATH");
#if __APPLE__
    if (!env_var)
      env_var = getenv("DYLD_LIBRARY_PATH");
    if (!env_var)
      env_var = getenv("DYLD_FALLBACK_LIBRARY_PATH");
#endif
    if (env_var != 0) {
      static const char PathSeparator = ':';
      const char* at = env_var;
      const char* delim = strchr(at, PathSeparator);
      while (delim != 0) {
        std::string tmp(at, size_t(delim-at));
        if (llvm::sys::fs::is_directory(tmp.c_str()))
            Paths.push_back(tmp);
        at = delim + 1;
        delim = strchr(at, PathSeparator);
      }

      if (*at != 0)
        if (llvm::sys::fs::is_directory(llvm::StringRef(at)))
          Paths.push_back(at);
    }

    Paths.push_back("/usr/local/lib/");
    Paths.push_back("/usr/X11R6/lib/");
    Paths.push_back("/usr/lib/");
    Paths.push_back("/lib/");
  }
#elif defined(LLVM_ON_WIN32)
  static void GetSystemLibraryPaths(llvm::SmallVectorImpl<std::string>& Paths) {
    char buff[MAX_PATH];
    // Generic form of C:\Windows\System32
    HRESULT res =  SHGetFolderPathA(NULL,
                                    CSIDL_FLAG_CREATE | CSIDL_SYSTEM,
                                    NULL,
                                    SHGFP_TYPE_CURRENT,
                                    buff);
    if (res != S_OK) {
      assert(0 && "Failed to get system directory");
      return;
    }
    Paths.push_back(buff);

    // Reset buff.
    buff[0] = 0;
    // Generic form of C:\Windows
    res =  SHGetFolderPathA(NULL,
                            CSIDL_FLAG_CREATE | CSIDL_WINDOWS,
                            NULL,
                            SHGFP_TYPE_CURRENT,
                            buff);
    if (res != S_OK) {
      assert(0 && "Failed to get windows directory");
      return;
    }
    Paths.push_back(buff);
  }
#else
# error "Unsupported platform."
#endif

  DynamicLibraryManager::LoadLibResult
  DynamicLibraryManager::tryLinker(const std::string& filename, bool permanent,
                                   bool isAbsolute, bool& exists,
                                   bool& isDyLib) {
    using namespace llvm::sys;
    exists = false;
    isDyLib = false;

    llvm::SmallString<512> FoundDyLib;

    if (isAbsolute) {
      isDyLib = isSharedLib(filename, exists);
      if (isDyLib)
        FoundDyLib = filename;
    } else {
      llvm::SmallVector<std::string, 16>
        SearchPaths(m_Opts.LibSearchPath.begin(), m_Opts.LibSearchPath.end());
      GetSystemLibraryPaths(SearchPaths);

      findSharedLibrary(filename, SearchPaths, FoundDyLib, exists, isDyLib);

      if (!exists) {
        // Add DyLib extension:
        llvm::SmallString<512> filenameWithExt(filename);
#if defined(LLVM_ON_UNIX)
#ifdef __APPLE__
        llvm::SmallString<512>::iterator IStemEnd = filenameWithExt.end() - 1;
#endif
        static const char* DyLibExt = ".so";
#elif defined(LLVM_ON_WIN32)
        static const char* DyLibExt = ".dll";
#else
# error "Unsupported platform."
#endif
        filenameWithExt += DyLibExt;
        findSharedLibrary(filenameWithExt, SearchPaths, FoundDyLib, exists,
                          isDyLib);
#ifdef __APPLE__
        if (!exists) {
           filenameWithExt.erase(IStemEnd + 1, filenameWithExt.end());
           filenameWithExt += ".dylib";
           findSharedLibrary(filenameWithExt, SearchPaths, FoundDyLib, exists,
                             isDyLib);
        }
#endif
      }
    }

    if (!isDyLib)
      return kLoadLibError;

    assert(!FoundDyLib.empty() && "The shared lib exists but can't find it!");

    // TODO: !permanent case
#ifdef WIN32
# error "Windows DLL opening still needs to be implemented!"
    void* dyLibHandle = needs to be implemented!;
    std::string errMsg;
#else
    const void* dyLibHandle
      = dlopen(FoundDyLib.c_str(), RTLD_LAZY|RTLD_GLOBAL);
    std::string errMsg;
    if (const char* DyLibError = dlerror()) {
      errMsg = DyLibError;
    }
#endif
    if (!dyLibHandle) {
      llvm::errs() << "cling::Interpreter::tryLinker(): " << errMsg << '\n';
      return kLoadLibError;
    }
    std::pair<DyLibs::iterator, bool> insRes
      = m_DyLibs.insert(std::pair<DyLibHandle, std::string>(dyLibHandle,
                                                            FoundDyLib.str()));
    if (!insRes.second)
      return kLoadLibExists;
    return kLoadLibSuccess;
  }

  DynamicLibraryManager::LoadLibResult
  DynamicLibraryManager::loadLibrary(const std::string& filename,
                                     bool permanent, bool* tryCode) {
    // If it's not an absolute path, prepend "lib"
    llvm::SmallString<128> Absolute((llvm::StringRef(filename)));
    llvm::sys::fs::make_absolute(Absolute);
    bool isAbsolute = filename == Absolute.c_str();
    bool exists = false;
    bool isDyLib = false;
    LoadLibResult res = tryLinker(filename, permanent, isAbsolute, exists,
                                  isDyLib);
    if (tryCode) {
      *tryCode = !isDyLib;
      if (isAbsolute)
        *tryCode &= exists;
    }
    if (exists)
      return res;

    if (!isAbsolute && filename.compare(0, 3, "lib")) {
      // try with "lib" prefix:
      res = tryLinker("lib" + filename, permanent, false, exists, isDyLib);
      if (tryCode) {
        *tryCode = !isDyLib;
        if (isAbsolute)
          *tryCode &= exists;
      }
      if (res != kLoadLibError)
        return res;
    }
    return kLoadLibError;
  }

  bool
  DynamicLibraryManager::isDynamicLibraryLoaded(llvm::StringRef fullPath) const{
    for(DyLibs::const_iterator I = m_DyLibs.begin(), E = m_DyLibs.end();
        I != E; ++I) {
      if (fullPath.equals((I->second)))
        return true;
    }
    return false;
  }

  void DynamicLibraryManager::ExposeHiddenSharedLibrarySymbols(void* handle) {
    llvm::sys::DynamicLibrary::addPermanentLibrary(const_cast<void*>(handle));
  }
} // end namespace cling
<commit_msg>Remove misplaced and duplicate comment.<commit_after>//------------------------------------------------------------------------------
// CLING - the C++ LLVM-based InterpreterG :)
// version: $Id$
// author:  Vassil Vassilev <vasil.georgiev.vasilev@cern.ch>
//------------------------------------------------------------------------------

#include "cling/Interpreter/DynamicLibraryManager.h"
#include "cling/Interpreter/InvocationOptions.h"

#include "llvm/Support/DynamicLibrary.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/raw_ostream.h"

#ifdef WIN32
#include <Windows.h>
#else
#include <dlfcn.h>
#endif

namespace cling {
  DynamicLibraryManager::DynamicLibraryManager(const InvocationOptions& Opts)
    : m_Opts(Opts) { }

  DynamicLibraryManager::~DynamicLibraryManager() {}

  static bool isSharedLib(llvm::StringRef LibName, bool& exists) {
    using namespace llvm::sys::fs;
    file_magic Magic;
    llvm::error_code Error = identify_magic(LibName, Magic);
    exists = (Error == llvm::errc::success);
    return exists &&
#ifdef __APPLE__
        (Magic == file_magic::macho_fixed_virtual_memory_shared_lib
         || Magic == file_magic::macho_dynamically_linked_shared_lib
         || Magic == file_magic::macho_dynamically_linked_shared_lib_stub)
#elif defined(LLVM_ON_UNIX)
        Magic == file_magic::elf_shared_object
#elif defined(LLVM_ON_WIN32)
# error "Windows DLLs  not yet implemented!"
        //Magic == file_magic::pecoff_executable?
#else
# error "Unsupported platform."
#endif
      ;
  }

  static void
  findSharedLibrary(llvm::StringRef fileStem,
                    const llvm::SmallVectorImpl<std::string>& Paths,
                    llvm::SmallString<512>& FoundDyLib,
                    bool& exists, bool& isDyLib) {
    for (llvm::SmallVectorImpl<std::string>::const_iterator
        IPath = Paths.begin(), EPath = Paths.end(); IPath != EPath; ++IPath) {
      llvm::SmallString<512> ThisPath(*IPath);
      llvm::sys::path::append(ThisPath, fileStem);
      isDyLib = isSharedLib(ThisPath.str(), exists);
      if (isDyLib)
        ThisPath.swap(FoundDyLib);
      if (exists)
        return;
    }
  }

#if defined(LLVM_ON_UNIX)
  static void GetSystemLibraryPaths(llvm::SmallVectorImpl<std::string>& Paths) {
    char* env_var = getenv("LD_LIBRARY_PATH");
#if __APPLE__
    if (!env_var)
      env_var = getenv("DYLD_LIBRARY_PATH");
    if (!env_var)
      env_var = getenv("DYLD_FALLBACK_LIBRARY_PATH");
#endif
    if (env_var != 0) {
      static const char PathSeparator = ':';
      const char* at = env_var;
      const char* delim = strchr(at, PathSeparator);
      while (delim != 0) {
        std::string tmp(at, size_t(delim-at));
        if (llvm::sys::fs::is_directory(tmp.c_str()))
            Paths.push_back(tmp);
        at = delim + 1;
        delim = strchr(at, PathSeparator);
      }

      if (*at != 0)
        if (llvm::sys::fs::is_directory(llvm::StringRef(at)))
          Paths.push_back(at);
    }

    Paths.push_back("/usr/local/lib/");
    Paths.push_back("/usr/X11R6/lib/");
    Paths.push_back("/usr/lib/");
    Paths.push_back("/lib/");
  }
#elif defined(LLVM_ON_WIN32)
  static void GetSystemLibraryPaths(llvm::SmallVectorImpl<std::string>& Paths) {
    char buff[MAX_PATH];
    // Generic form of C:\Windows\System32
    HRESULT res =  SHGetFolderPathA(NULL,
                                    CSIDL_FLAG_CREATE | CSIDL_SYSTEM,
                                    NULL,
                                    SHGFP_TYPE_CURRENT,
                                    buff);
    if (res != S_OK) {
      assert(0 && "Failed to get system directory");
      return;
    }
    Paths.push_back(buff);

    // Reset buff.
    buff[0] = 0;
    // Generic form of C:\Windows
    res =  SHGetFolderPathA(NULL,
                            CSIDL_FLAG_CREATE | CSIDL_WINDOWS,
                            NULL,
                            SHGFP_TYPE_CURRENT,
                            buff);
    if (res != S_OK) {
      assert(0 && "Failed to get windows directory");
      return;
    }
    Paths.push_back(buff);
  }
#else
# error "Unsupported platform."
#endif

  DynamicLibraryManager::LoadLibResult
  DynamicLibraryManager::tryLinker(const std::string& filename, bool permanent,
                                   bool isAbsolute, bool& exists,
                                   bool& isDyLib) {
    using namespace llvm::sys;
    exists = false;
    isDyLib = false;

    llvm::SmallString<512> FoundDyLib;

    if (isAbsolute) {
      isDyLib = isSharedLib(filename, exists);
      if (isDyLib)
        FoundDyLib = filename;
    } else {
      llvm::SmallVector<std::string, 16>
        SearchPaths(m_Opts.LibSearchPath.begin(), m_Opts.LibSearchPath.end());
      GetSystemLibraryPaths(SearchPaths);

      findSharedLibrary(filename, SearchPaths, FoundDyLib, exists, isDyLib);

      if (!exists) {
        // Add DyLib extension:
        llvm::SmallString<512> filenameWithExt(filename);
#if defined(LLVM_ON_UNIX)
#ifdef __APPLE__
        llvm::SmallString<512>::iterator IStemEnd = filenameWithExt.end() - 1;
#endif
        static const char* DyLibExt = ".so";
#elif defined(LLVM_ON_WIN32)
        static const char* DyLibExt = ".dll";
#else
# error "Unsupported platform."
#endif
        filenameWithExt += DyLibExt;
        findSharedLibrary(filenameWithExt, SearchPaths, FoundDyLib, exists,
                          isDyLib);
#ifdef __APPLE__
        if (!exists) {
           filenameWithExt.erase(IStemEnd + 1, filenameWithExt.end());
           filenameWithExt += ".dylib";
           findSharedLibrary(filenameWithExt, SearchPaths, FoundDyLib, exists,
                             isDyLib);
        }
#endif
      }
    }

    if (!isDyLib)
      return kLoadLibError;

    assert(!FoundDyLib.empty() && "The shared lib exists but can't find it!");

    // TODO: !permanent case
#ifdef WIN32
# error "Windows DLL opening still needs to be implemented!"
    void* dyLibHandle = needs to be implemented!;
    std::string errMsg;
#else
    const void* dyLibHandle
      = dlopen(FoundDyLib.c_str(), RTLD_LAZY|RTLD_GLOBAL);
    std::string errMsg;
    if (const char* DyLibError = dlerror()) {
      errMsg = DyLibError;
    }
#endif
    if (!dyLibHandle) {
      llvm::errs() << "cling::Interpreter::tryLinker(): " << errMsg << '\n';
      return kLoadLibError;
    }
    std::pair<DyLibs::iterator, bool> insRes
      = m_DyLibs.insert(std::pair<DyLibHandle, std::string>(dyLibHandle,
                                                            FoundDyLib.str()));
    if (!insRes.second)
      return kLoadLibExists;
    return kLoadLibSuccess;
  }

  DynamicLibraryManager::LoadLibResult
  DynamicLibraryManager::loadLibrary(const std::string& filename,
                                     bool permanent, bool* tryCode) {
    llvm::SmallString<128> Absolute((llvm::StringRef(filename)));
    llvm::sys::fs::make_absolute(Absolute);
    bool isAbsolute = filename == Absolute.c_str();
    bool exists = false;
    bool isDyLib = false;
    LoadLibResult res = tryLinker(filename, permanent, isAbsolute, exists,
                                  isDyLib);
    if (tryCode) {
      *tryCode = !isDyLib;
      if (isAbsolute)
        *tryCode &= exists;
    }
    if (exists)
      return res;

    if (!isAbsolute && filename.compare(0, 3, "lib")) {
      // try with "lib" prefix:
      res = tryLinker("lib" + filename, permanent, false, exists, isDyLib);
      if (tryCode) {
        *tryCode = !isDyLib;
        if (isAbsolute)
          *tryCode &= exists;
      }
      if (res != kLoadLibError)
        return res;
    }
    return kLoadLibError;
  }

  bool
  DynamicLibraryManager::isDynamicLibraryLoaded(llvm::StringRef fullPath) const{
    for(DyLibs::const_iterator I = m_DyLibs.begin(), E = m_DyLibs.end();
        I != E; ++I) {
      if (fullPath.equals((I->second)))
        return true;
    }
    return false;
  }

  void DynamicLibraryManager::ExposeHiddenSharedLibrarySymbols(void* handle) {
    llvm::sys::DynamicLibrary::addPermanentLibrary(const_cast<void*>(handle));
  }
} // end namespace cling
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: simpleinteractionrequest.hxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-09 16:31:42 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef _UCBHELPER_SIMPLEINTERACTIONREQUEST_HXX
#define _UCBHELPER_SIMPLEINTERACTIONREQUEST_HXX

#ifndef _UCBHELPER_INTERATIONREQUEST_HXX
#include <ucbhelper/interactionrequest.hxx>
#endif
#ifndef INCLUDED_UCBHELPERDLLAPI_H
#include "ucbhelper/ucbhelperdllapi.h"
#endif

namespace ucbhelper {

/** These are the constants that can be passed to the constructor of class
  * SimpleInteractionRequest and that are returned by method
  * SimpleInteractionRequest::getResponse().
  */

/** The request was not (yet) handled by the interaction handler. */
static const sal_Int32 CONTINUATION_UNKNOWN    = 0;

/** The interaction handler selected XInteractionAbort. */
static const sal_Int32 CONTINUATION_ABORT      = 1;

/** The interaction handler selected XInteractionRetry. */
static const sal_Int32 CONTINUATION_RETRY      = 2;

/** The interaction handler selected XInteractionApprove. */
static const sal_Int32 CONTINUATION_APPROVE    = 4;

/** The interaction handler selected XInteractionDisapprove. */
static const sal_Int32 CONTINUATION_DISAPPROVE = 8;

/**
  * This class implements a simple interaction request. The user must not deal
  * with XInteractionContinuations directly, but can use constants that are
  * mapped internally to the according objects. This class encapsulates the
  * standard Interaction Continuations "Abort", "Retry", "Approve" and
  * "Disaprrove". Instances can be passed directly to
  * XInteractionHandler::handle(...).
  *
  * @see InteractionRequest
  * @see InteractionAbort
  * @see InteractionRetry
  * @see InteractionApprove
  * @see InteractionDisapprove
  */
class UCBHELPER_DLLPUBLIC SimpleInteractionRequest : public ucbhelper::InteractionRequest
{
public:
    /**
      * Constructor.
      *
      * @param rRequest is the exception describing the error.
      * @param nContinuations contains the possible "answers" for the request.
      *        This can be any of the CONTINUATION_* constants combinations
      *        listed above.
      */
    SimpleInteractionRequest( const com::sun::star::uno::Any & rRequest,
                              const sal_Int32 nContinuations );

    /**
      * After passing this request to XInteractionHandler::handle, this method
      * returns the continuation that was choosen by the interaction handler.
      *
      * @return the continuation choosen by an interaction handler or
      *         CONTINUATION_UNKNOWN, if the request was not (yet) handled.
      */
    const sal_Int32 getResponse() const;
};

} // namespace ucbhelper

#endif /* !_UCBHELPER_SIMPLEINTERACTIONREQUEST_HXX */
<commit_msg>INTEGRATION: CWS changefileheader (1.3.104); FILE MERGED 2008/04/01 12:58:45 thb 1.3.104.2: #i85898# Stripping all external header guards 2008/03/31 15:31:30 rt 1.3.104.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: simpleinteractionrequest.hxx,v $
 * $Revision: 1.4 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#ifndef _UCBHELPER_SIMPLEINTERACTIONREQUEST_HXX
#define _UCBHELPER_SIMPLEINTERACTIONREQUEST_HXX

#include <ucbhelper/interactionrequest.hxx>
#include "ucbhelper/ucbhelperdllapi.h"

namespace ucbhelper {

/** These are the constants that can be passed to the constructor of class
  * SimpleInteractionRequest and that are returned by method
  * SimpleInteractionRequest::getResponse().
  */

/** The request was not (yet) handled by the interaction handler. */
static const sal_Int32 CONTINUATION_UNKNOWN    = 0;

/** The interaction handler selected XInteractionAbort. */
static const sal_Int32 CONTINUATION_ABORT      = 1;

/** The interaction handler selected XInteractionRetry. */
static const sal_Int32 CONTINUATION_RETRY      = 2;

/** The interaction handler selected XInteractionApprove. */
static const sal_Int32 CONTINUATION_APPROVE    = 4;

/** The interaction handler selected XInteractionDisapprove. */
static const sal_Int32 CONTINUATION_DISAPPROVE = 8;

/**
  * This class implements a simple interaction request. The user must not deal
  * with XInteractionContinuations directly, but can use constants that are
  * mapped internally to the according objects. This class encapsulates the
  * standard Interaction Continuations "Abort", "Retry", "Approve" and
  * "Disaprrove". Instances can be passed directly to
  * XInteractionHandler::handle(...).
  *
  * @see InteractionRequest
  * @see InteractionAbort
  * @see InteractionRetry
  * @see InteractionApprove
  * @see InteractionDisapprove
  */
class UCBHELPER_DLLPUBLIC SimpleInteractionRequest : public ucbhelper::InteractionRequest
{
public:
    /**
      * Constructor.
      *
      * @param rRequest is the exception describing the error.
      * @param nContinuations contains the possible "answers" for the request.
      *        This can be any of the CONTINUATION_* constants combinations
      *        listed above.
      */
    SimpleInteractionRequest( const com::sun::star::uno::Any & rRequest,
                              const sal_Int32 nContinuations );

    /**
      * After passing this request to XInteractionHandler::handle, this method
      * returns the continuation that was choosen by the interaction handler.
      *
      * @return the continuation choosen by an interaction handler or
      *         CONTINUATION_UNKNOWN, if the request was not (yet) handled.
      */
    const sal_Int32 getResponse() const;
};

} // namespace ucbhelper

#endif /* !_UCBHELPER_SIMPLEINTERACTIONREQUEST_HXX */
<|endoftext|>


<commit_before>/*
 * Copyright 2012-2013 BrewPi/Elco Jacobs.
 *
 * This file is part of BrewPi.
 *
 * BrewPi is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * BrewPi is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with BrewPi.  If not, see <http://www.gnu.org/licenses/>.
 */

/*
 * This Atmel Studio 6 project automatically includes all needed Arduino source files, you just have to point it to the right directories.
 * To compile this project on your computer, you will have to set an environment variable to find your local Arduino installation.
 * Set the variable ARDUINO_HOME to point to your local Arduino path, without trailing slash, e.g. 'D:\arduino-1.01'. Instructions on the wiki here:
 * http://wiki.brewpi.com/index.php/Setting_up_the_brewpi-avr_Project
 * 'ArduinoFunctions.cpp' includes all the source files from Arduino that are used. You might have to edit it if you are not using a Leonardo.
 * That is all that is needed! No hassle with makefiles and compiling libraries.
 */
#include "Brewpi.h"
#include "Ticks.h"
#include "Display.h"
#include "TempControl.h"
#include "PiLink.h"
#include "Menu.h"
#include "Pins.h"
#include "RotaryEncoder.h"
#include "Buzzer.h"
#include "TempSensor.h"
#include "TempSensorMock.h"
#include "OneWireTempSensor.h"
#include "TempSensorExternal.h"
#include "Ticks.h"
#include "Sensor.h"
#include "FastDigitalPin.h"
#include "OneWireActuator.h"
#include "SettingsManager.h"

#if BREWPI_SIMULATE
	#include "Simulator.h"
#endif

// global class objects static and defined in class cpp and h files

// instantiate and configure the sensors, actuators and controllers we want to use

void setup(void);
void loop (void);

/* Configure the counter and delay timer. The actual type of these will vary depending upon the environment.
 * They are non-virtual to keep code size minimal, so typedefs and preprocessing are used to select the actual compile-time type used. */
TicksImpl ticks = TicksImpl(TICKS_IMPL_CONFIG);
DelayImpl wait = DelayImpl(DELAY_IMPL_CONFIG);

DisplayType realDisplay;
DisplayType DISPLAY_REF display = realDisplay;

void setup()
{
	piLink.init();

	logDebug("started");
	tempControl.init();
	settingsManager.loadSettings();

#if BREWPI_SIMULATE
	simulator.step();
	// initialize the filters with the assigned initial temp value
	tempControl.beerSensor->init();
	tempControl.fridgeSensor->init();
#endif

	display.init();
	display.printStationaryText();
	display.printState();

	rotaryEncoder.init();

#if BREWPI_BUZZER
	buzzer.init();
	buzzer.beep(2, 500);
#endif

	logDebug("init complete");
}

void brewpiLoop(void)
{
	static unsigned long lastUpdate = 0;

	if(ticks.millis() - lastUpdate >= (1000)) { //update settings every second
		lastUpdate = ticks.millis();

		tempControl.updateTemperatures();
		tempControl.detectPeaks();
		tempControl.updatePID();
		tempControl.updateState();
		tempControl.updateOutputs();

#if BREWPI_MENU
		if(rotaryEncoder.pushed()){
			rotaryEncoder.resetPushed();
			menu.pickSettingToChange();
		}
#endif

		// update the lcd for the chamber being displayed
		display.printState();
		display.printAllTemperatures();
		display.printMode();
		display.updateBacklight();
	}

	//listen for incoming serial connections while waiting to update
	piLink.receive();

}

void loop() {
	#if BREWPI_SIMULATE
	simulateLoop();
	#else
	brewpiLoop();
	#endif
}

<commit_msg>output a data point on every state transition for better analysis<commit_after>/*
 * Copyright 2012-2013 BrewPi/Elco Jacobs.
 *
 * This file is part of BrewPi.
 *
 * BrewPi is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * BrewPi is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with BrewPi.  If not, see <http://www.gnu.org/licenses/>.
 */

/*
 * This Atmel Studio 6 project automatically includes all needed Arduino source files, you just have to point it to the right directories.
 * To compile this project on your computer, you will have to set an environment variable to find your local Arduino installation.
 * Set the variable ARDUINO_HOME to point to your local Arduino path, without trailing slash, e.g. 'D:\arduino-1.01'. Instructions on the wiki here:
 * http://wiki.brewpi.com/index.php/Setting_up_the_brewpi-avr_Project
 * 'ArduinoFunctions.cpp' includes all the source files from Arduino that are used. You might have to edit it if you are not using a Leonardo.
 * That is all that is needed! No hassle with makefiles and compiling libraries.
 */
#include "Brewpi.h"
#include "Ticks.h"
#include "Display.h"
#include "TempControl.h"
#include "PiLink.h"
#include "Menu.h"
#include "Pins.h"
#include "RotaryEncoder.h"
#include "Buzzer.h"
#include "TempSensor.h"
#include "TempSensorMock.h"
#include "OneWireTempSensor.h"
#include "TempSensorExternal.h"
#include "Ticks.h"
#include "Sensor.h"
#include "FastDigitalPin.h"
#include "OneWireActuator.h"
#include "SettingsManager.h"

#if BREWPI_SIMULATE
	#include "Simulator.h"
#endif

// global class objects static and defined in class cpp and h files

// instantiate and configure the sensors, actuators and controllers we want to use

void setup(void);
void loop (void);

/* Configure the counter and delay timer. The actual type of these will vary depending upon the environment.
 * They are non-virtual to keep code size minimal, so typedefs and preprocessing are used to select the actual compile-time type used. */
TicksImpl ticks = TicksImpl(TICKS_IMPL_CONFIG);
DelayImpl wait = DelayImpl(DELAY_IMPL_CONFIG);

DisplayType realDisplay;
DisplayType DISPLAY_REF display = realDisplay;

void setup()
{
	piLink.init();

	logDebug("started");
	tempControl.init();
	settingsManager.loadSettings();

#if BREWPI_SIMULATE
	simulator.step();
	// initialize the filters with the assigned initial temp value
	tempControl.beerSensor->init();
	tempControl.fridgeSensor->init();
#endif

	display.init();
	display.printStationaryText();
	display.printState();

	rotaryEncoder.init();

#if BREWPI_BUZZER
	buzzer.init();
	buzzer.beep(2, 500);
#endif

	logDebug("init complete");
}

void brewpiLoop(void)
{
	static unsigned long lastUpdate = 0;
	uint8_t oldState;

	if(ticks.millis() - lastUpdate >= (1000)) { //update settings every second
		lastUpdate = ticks.millis();

		tempControl.updateTemperatures();
		tempControl.detectPeaks();
		tempControl.updatePID();
		oldState = tempControl.getState();
		tempControl.updateState();
		if(oldState != tempControl.getState()){
			piLink.printTemperatures(); // add a data point at every state transition
		}
		tempControl.updateOutputs();

#if BREWPI_MENU
		if(rotaryEncoder.pushed()){
			rotaryEncoder.resetPushed();
			menu.pickSettingToChange();
		}
#endif

		// update the lcd for the chamber being displayed
		display.printState();
		display.printAllTemperatures();
		display.printMode();
		display.updateBacklight();
	}

	//listen for incoming serial connections while waiting to update
	piLink.receive();

}

void loop() {
	#if BREWPI_SIMULATE
	simulateLoop();
	#else
	brewpiLoop();
	#endif
}

<|endoftext|>


<commit_before>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/command_line.h"
#include "base/file_path.h"
#include "base/file_util.h"
#include "base/memory/ref_counted.h"
#include "base/scoped_temp_dir.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/test/in_process_browser_test.h"
#include "chrome/test/testing_profile.h"
#include "chrome/test/thread_test_helper.h"
#include "chrome/test/ui_test_utils.h"
#include "content/browser/in_process_webkit/indexed_db_context.h"
#include "content/browser/in_process_webkit/webkit_context.h"
#include "content/browser/tab_contents/tab_contents.h"
#include "content/common/content_switches.h"

// This browser test is aimed towards exercising the IndexedDB bindings and
// the actual implementation that lives in the browser side (in_process_webkit).
class IndexedDBBrowserTest : public InProcessBrowserTest {
 public:
  IndexedDBBrowserTest() {
    EnableDOMAutomation();
  }

  virtual void SetUpCommandLine(CommandLine* command_line) {
    command_line->AppendSwitch(switches::kUnlimitedQuotaForIndexedDB);
  }

  GURL testUrl(const FilePath& file_path) {
    const FilePath kTestDir(FILE_PATH_LITERAL("indexeddb"));
    return ui_test_utils::GetTestUrl(kTestDir, file_path);
  }

  void SimpleTest(const GURL& test_url) {
    // The test page will perform tests on IndexedDB, then navigate to either
    // a #pass or #fail ref.
    LOG(INFO) << "Navigating to URL and blocking.";
    ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(
        browser(), test_url, 2);
    LOG(INFO) << "Navigation done.";
    std::string result = browser()->GetSelectedTabContents()->GetURL().ref();
    if (result != "pass") {
      std::string js_result;
      ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractString(
          browser()->GetSelectedTabContents()->render_view_host(), L"",
          L"window.domAutomationController.send(getLog())", &js_result));
      FAIL() << "Failed: " << js_result;
    }
  }
};

class IndexedDBLevelDBBrowserTest : public IndexedDBBrowserTest {
 public:
  virtual void SetUpCommandLine(CommandLine* command_line) {
    command_line->AppendSwitch(switches::kLevelDBIndexedDatabase);
  }
};

IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, CursorTest) {
  SimpleTest(testUrl(FilePath(FILE_PATH_LITERAL("cursor_test.html"))));
}

IN_PROC_BROWSER_TEST_F(IndexedDBLevelDBBrowserTest, CursorTest) {
  SimpleTest(testUrl(FilePath(FILE_PATH_LITERAL("cursor_test.html"))));
}

// TODO(hans): If this starts failing, please disable and ping crbug.com/70773.
IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, IndexTest) {
  SimpleTest(testUrl(FilePath(FILE_PATH_LITERAL("index_test.html"))));
}

// TODO(hans): If this starts failing, please disable and ping crbug.com/70773.
IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, KeyPathTest) {
  SimpleTest(testUrl(FilePath(FILE_PATH_LITERAL("key_path_test.html"))));
}

IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, TransactionGetTest) {
  SimpleTest(testUrl(FilePath(FILE_PATH_LITERAL("transaction_get_test.html"))));
}

// TODO(hans): If this starts failing, please disable and ping crbug.com/70773.
IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, ObjectStoreTest) {
  SimpleTest(testUrl(FilePath(FILE_PATH_LITERAL("object_store_test.html"))));
}

IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, DatabaseTest) {
  SimpleTest(testUrl(FilePath(FILE_PATH_LITERAL("database_test.html"))));
}

// TODO(hans): If this starts failing, please disable and ping crbug.com/70773.
IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, TransactionTest) {
  SimpleTest(testUrl(FilePath(FILE_PATH_LITERAL("transaction_test.html"))));
}

// TODO(hans): If this starts failing, please disable and ping crbug.com/70773.
IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, DoesntHangTest) {
  SimpleTest(testUrl(FilePath(
      FILE_PATH_LITERAL("transaction_run_forever.html"))));
  ui_test_utils::CrashTab(browser()->GetSelectedTabContents());
  SimpleTest(testUrl(FilePath(FILE_PATH_LITERAL("transaction_test.html"))));
}

IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, Bug84933Test) {
  const GURL url = testUrl(FilePath(FILE_PATH_LITERAL("bug_84933.html")));

  // Just navigate to the URL. Test will crash if it fails.
  ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(browser(), url, 1);
}

// In proc browser test is needed here because ClearLocalState indirectly calls
// WebKit's isMainThread through WebSecurityOrigin->SecurityOrigin.
IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, ClearLocalState) {
  // Create test files.
  ScopedTempDir temp_dir;
  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
  FilePath indexeddb_dir = temp_dir.path().Append(
      IndexedDBContext::kIndexedDBDirectory);
  ASSERT_TRUE(file_util::CreateDirectory(indexeddb_dir));

  FilePath::StringType file_name_1(FILE_PATH_LITERAL("http_foo_0"));
  file_name_1.append(IndexedDBContext::kIndexedDBExtension);
  FilePath::StringType file_name_2(FILE_PATH_LITERAL("chrome-extension_foo_0"));
  file_name_2.append(IndexedDBContext::kIndexedDBExtension);
  FilePath temp_file_path_1 = indexeddb_dir.Append(file_name_1);
  FilePath temp_file_path_2 = indexeddb_dir.Append(file_name_2);

  ASSERT_EQ(1, file_util::WriteFile(temp_file_path_1, ".", 1));
  ASSERT_EQ(1, file_util::WriteFile(temp_file_path_2, "o", 1));

  // Create the scope which will ensure we run the destructor of the webkit
  // context which should trigger the clean up.
  {
    TestingProfile profile;
    WebKitContext *webkit_context = profile.GetWebKitContext();
    webkit_context->indexed_db_context()->set_data_path(indexeddb_dir);
    webkit_context->set_clear_local_state_on_exit(true);
  }
  // Make sure we wait until the destructor has run.
  scoped_refptr<ThreadTestHelper> helper(
      new ThreadTestHelper(BrowserThread::WEBKIT));
  ASSERT_TRUE(helper->Run());

  // Because we specified https for scheme to be skipped the second file
  // should survive and the first go into vanity.
  ASSERT_FALSE(file_util::PathExists(temp_file_path_1));
  ASSERT_TRUE(file_util::PathExists(temp_file_path_2));
}

class IndexedDBBrowserTestWithGCExposed : public IndexedDBBrowserTest {
 public:
  virtual void SetUpCommandLine(CommandLine* command_line) {
    command_line->AppendSwitchASCII(switches::kJavaScriptFlags, "--expose-gc");
  }
};

IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTestWithGCExposed,
                       DatabaseCallbacksTest) {
  SimpleTest(
      testUrl(FilePath(FILE_PATH_LITERAL("database_callbacks_first.html"))));
}
<commit_msg>Disable IndexedDB tests again (basically revert r89153), they are still flaky.<commit_after>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/command_line.h"
#include "base/file_path.h"
#include "base/file_util.h"
#include "base/memory/ref_counted.h"
#include "base/scoped_temp_dir.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/test/in_process_browser_test.h"
#include "chrome/test/testing_profile.h"
#include "chrome/test/thread_test_helper.h"
#include "chrome/test/ui_test_utils.h"
#include "content/browser/in_process_webkit/indexed_db_context.h"
#include "content/browser/in_process_webkit/webkit_context.h"
#include "content/browser/tab_contents/tab_contents.h"
#include "content/common/content_switches.h"

// This browser test is aimed towards exercising the IndexedDB bindings and
// the actual implementation that lives in the browser side (in_process_webkit).
class IndexedDBBrowserTest : public InProcessBrowserTest {
 public:
  IndexedDBBrowserTest() {
    EnableDOMAutomation();
  }

  virtual void SetUpCommandLine(CommandLine* command_line) {
    command_line->AppendSwitch(switches::kUnlimitedQuotaForIndexedDB);
  }

  GURL testUrl(const FilePath& file_path) {
    const FilePath kTestDir(FILE_PATH_LITERAL("indexeddb"));
    return ui_test_utils::GetTestUrl(kTestDir, file_path);
  }

  void SimpleTest(const GURL& test_url) {
    // The test page will perform tests on IndexedDB, then navigate to either
    // a #pass or #fail ref.
    LOG(INFO) << "Navigating to URL and blocking.";
    ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(
        browser(), test_url, 2);
    LOG(INFO) << "Navigation done.";
    std::string result = browser()->GetSelectedTabContents()->GetURL().ref();
    if (result != "pass") {
      std::string js_result;
      ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractString(
          browser()->GetSelectedTabContents()->render_view_host(), L"",
          L"window.domAutomationController.send(getLog())", &js_result));
      FAIL() << "Failed: " << js_result;
    }
  }
};

class IndexedDBLevelDBBrowserTest : public IndexedDBBrowserTest {
 public:
  virtual void SetUpCommandLine(CommandLine* command_line) {
    command_line->AppendSwitch(switches::kLevelDBIndexedDatabase);
  }
};

IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, CursorTest) {
  SimpleTest(testUrl(FilePath(FILE_PATH_LITERAL("cursor_test.html"))));
}

IN_PROC_BROWSER_TEST_F(IndexedDBLevelDBBrowserTest, CursorTest) {
  SimpleTest(testUrl(FilePath(FILE_PATH_LITERAL("cursor_test.html"))));
}

// Flaky: http://crbug.com/70773
IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, DISABLED_IndexTest) {
  SimpleTest(testUrl(FilePath(FILE_PATH_LITERAL("index_test.html"))));
}

// Flaky: http://crbug.com/70773
IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, DISABLED_KeyPathTest) {
  SimpleTest(testUrl(FilePath(FILE_PATH_LITERAL("key_path_test.html"))));
}

IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, TransactionGetTest) {
  SimpleTest(testUrl(FilePath(FILE_PATH_LITERAL("transaction_get_test.html"))));
}

// Flaky: http://crbug.com/70773
IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, DISABLED_ObjectStoreTest) {
  SimpleTest(testUrl(FilePath(FILE_PATH_LITERAL("object_store_test.html"))));
}

IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, DatabaseTest) {
  SimpleTest(testUrl(FilePath(FILE_PATH_LITERAL("database_test.html"))));
}

// Flaky: http://crbug.com/70773
IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, DISABLED_TransactionTest) {
  SimpleTest(testUrl(FilePath(FILE_PATH_LITERAL("transaction_test.html"))));
}

// Flaky: http://crbug.com/70773
IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, DISABLED_DoesntHangTest) {
  SimpleTest(testUrl(FilePath(
      FILE_PATH_LITERAL("transaction_run_forever.html"))));
  ui_test_utils::CrashTab(browser()->GetSelectedTabContents());
  SimpleTest(testUrl(FilePath(FILE_PATH_LITERAL("transaction_test.html"))));
}

IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, Bug84933Test) {
  const GURL url = testUrl(FilePath(FILE_PATH_LITERAL("bug_84933.html")));

  // Just navigate to the URL. Test will crash if it fails.
  ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(browser(), url, 1);
}

// In proc browser test is needed here because ClearLocalState indirectly calls
// WebKit's isMainThread through WebSecurityOrigin->SecurityOrigin.
IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, ClearLocalState) {
  // Create test files.
  ScopedTempDir temp_dir;
  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
  FilePath indexeddb_dir = temp_dir.path().Append(
      IndexedDBContext::kIndexedDBDirectory);
  ASSERT_TRUE(file_util::CreateDirectory(indexeddb_dir));

  FilePath::StringType file_name_1(FILE_PATH_LITERAL("http_foo_0"));
  file_name_1.append(IndexedDBContext::kIndexedDBExtension);
  FilePath::StringType file_name_2(FILE_PATH_LITERAL("chrome-extension_foo_0"));
  file_name_2.append(IndexedDBContext::kIndexedDBExtension);
  FilePath temp_file_path_1 = indexeddb_dir.Append(file_name_1);
  FilePath temp_file_path_2 = indexeddb_dir.Append(file_name_2);

  ASSERT_EQ(1, file_util::WriteFile(temp_file_path_1, ".", 1));
  ASSERT_EQ(1, file_util::WriteFile(temp_file_path_2, "o", 1));

  // Create the scope which will ensure we run the destructor of the webkit
  // context which should trigger the clean up.
  {
    TestingProfile profile;
    WebKitContext *webkit_context = profile.GetWebKitContext();
    webkit_context->indexed_db_context()->set_data_path(indexeddb_dir);
    webkit_context->set_clear_local_state_on_exit(true);
  }
  // Make sure we wait until the destructor has run.
  scoped_refptr<ThreadTestHelper> helper(
      new ThreadTestHelper(BrowserThread::WEBKIT));
  ASSERT_TRUE(helper->Run());

  // Because we specified https for scheme to be skipped the second file
  // should survive and the first go into vanity.
  ASSERT_FALSE(file_util::PathExists(temp_file_path_1));
  ASSERT_TRUE(file_util::PathExists(temp_file_path_2));
}

class IndexedDBBrowserTestWithGCExposed : public IndexedDBBrowserTest {
 public:
  virtual void SetUpCommandLine(CommandLine* command_line) {
    command_line->AppendSwitchASCII(switches::kJavaScriptFlags, "--expose-gc");
  }
};

IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTestWithGCExposed,
                       DatabaseCallbacksTest) {
  SimpleTest(
      testUrl(FilePath(FILE_PATH_LITERAL("database_callbacks_first.html"))));
}
<|endoftext|>


<commit_before>/*
 * arcball.cpp
 *
 * Created on: 10.05.2012
 * @author Ralph Schurade
 */
#include "arcball.h"

#include "../../data/models.h"

#include <QtDebug>

#include <math.h>

ArcBall::ArcBall( int width, int height ) :
    CameraBase( width, height ),
    Epsilon( 0.00001 ),
    m_moveX( 0 ),
    m_moveY( 0 ),
    m_oldMoveX( 0 ),
    m_oldMoveY( 0 ),
    m_midClickX( 0 ),
    m_midClickY( 0 )
{

    m_currentRot.setToIdentity();
    m_lastRot.setToIdentity();
}

ArcBall::~ArcBall()
{
}

// maps the specified mouse position to the sphere defined
// with center and radius. the resulting vector lies on the
// surface of the sphere.
QVector3D ArcBall::map_sphere( int x, int y )
{
    float tmpx = ( x * m_adjust_width ) - 1.0;
    float tmpy = 1.0 - ( y * m_adjust_height );

    float length = ( tmpx * tmpx ) + ( tmpy * tmpy );

    QVector3D bm;
    if ( length > 1.0 )
    {
        float norm = 1.0 / sqrt( length );
        bm.setX( tmpx * norm );
        bm.setY( tmpy * norm );
        bm.setZ( 0.0 );
    }
    else
    {
        bm.setX( tmpx );
        bm.setY( tmpy );
        bm.setZ( sqrt( 1.0 - length ) );
    }
    return bm;
}

/// sets the current position and calculates the current
/// rotation matrix.
void ArcBall::drag( int x, int y )
{
    QVector3D v_to = map_sphere( x, y );
    QVector3D perp = QVector3D::crossProduct( v_from, v_to);

    if ( perp.length() > Epsilon )
    {
        q_current_rotation.setX( perp.x() );
        q_current_rotation.setY( perp.y() );
        q_current_rotation.setZ( perp.z() );;
        q_current_rotation.setScalar( ( v_from.x() * v_to.x() ) + ( v_from.y() * v_to.y() ) + ( v_from.z() * v_to.z() ) );
    }
    else
    {
        q_current_rotation.setX( 0.0 );
        q_current_rotation.setY( 0.0 );
        q_current_rotation.setZ( 0.0 );
        q_current_rotation.setScalar( 0.0 );
    }
    m_currentRot.setToIdentity();
    m_currentRot.rotate( q_current_rotation );
    m_currentRot = m_currentRot * m_lastRot ;
}

/// indicates the beginning of the dragging.
void ArcBall::click( int x, int y )
{
    m_lastRot = m_currentRot;
    v_mouse_down.setX( x );
    v_mouse_down.setY( y );
    v_mouse_down.setZ( 0.0 );
    v_from = map_sphere( x, y );
}

void ArcBall::midClick( int x, int y )
{
    m_midClickX = x;
    m_midClickY = y;
    m_oldMoveX = m_moveX;
    m_oldMoveY = m_moveY;
}

void ArcBall::mouseWheel( float step )
{
    if ( step < 0 )
    {
        m_zoom *= 1.1;
    }
    else
    {
        m_zoom /= 1.1;
        m_zoom = qMax( 0.2f, m_zoom );
    }
}

void ArcBall::midDrag( int x, int y )
{
    m_moveX = m_oldMoveX + ( ( m_midClickX - x ) / 2 ) / m_zoom;
    m_moveY = m_oldMoveY + ( ( m_midClickY - y ) / 2 ) / m_zoom;
}

void ArcBall::setRotCenter( float x, float y, float z )
{
    m_rotCenter = QVector3D( -x, -y, -z );
}

void ArcBall::setView( Fn::Orient view )
{
    m_zoom = 1.0;
    m_moveX = 0;
    m_moveY = 0;
    m_oldMoveX = 0;
    m_oldMoveY = 0;
    m_currentRot.setToIdentity();
    m_lastRot.setToIdentity();

    QQuaternion rotx( sqrt(0.5), 0, 0, sqrt(0.5) );
    QQuaternion rot_x( -sqrt(0.5), 0, 0, sqrt(0.5) );
    QQuaternion roty( 0, sqrt(0.5), 0, sqrt(0.5) );
    QQuaternion rot_y( 0, -sqrt(0.5), 0, sqrt(0.5) );
    QQuaternion rotz( 0, 0, sqrt(0.5), sqrt(0.5) );
    QQuaternion rot_z( 0, 0, -sqrt(0.5), sqrt(0.5) );

    switch( view )
    {
        case Fn::Orient::NONE:
            break;
        case Fn::Orient::AXIAL:
            break;
        case Fn::Orient::CORONAL:
            m_currentRot.rotate( rotz );
            m_currentRot.rotate( rotx );
            m_currentRot.rotate( rotx );
            break;
        case Fn::Orient::SAGITTAL:
            m_currentRot.rotate( rot_x );
            m_currentRot.rotate( rot_y );
            break;
        case Fn::Orient::AXIAL2:
            m_currentRot.rotate( rot_y );
            m_currentRot.rotate( roty );
            break;
        case Fn::Orient::CORONAL2:
            m_currentRot.rotate( rotz );
            break;
        case Fn::Orient::SAGITTAL2:
            m_currentRot.rotate( rotx );
            m_currentRot.rotate( roty );
            break;
    }
}

/// returns the rotation matrix to be used directly
QMatrix4x4 ArcBall::getMVMat()
{
    QMatrix4x4 mv;
    mv.setToIdentity();

    mv = m_currentRot * mv ;

    float dist = Models::getGlobal( Fn::Property::G_ARCBALL_DISTANCE ).toFloat();

    QVector3D halfMove( -m_moveX, m_moveY, -dist );
    QMatrix4x4 tmp;
    tmp.setToIdentity();
    tmp.translate( halfMove );
    tmp = tmp * m_currentRot;

    mv = mv + tmp;

    mv.translate( m_rotCenter );

    return mv;
}

float ArcBall::getMoveX()
{
    return m_moveX;
}

float ArcBall::getMoveY()
{
    return m_moveY;
}

void ArcBall::setMoveX( float x )
{
    m_moveX = x;
}

void ArcBall::setMoveY( float y )
{
    m_moveY = y;
}

QList<QVariant> ArcBall::getState()
{
    QList<QVariant> state;
    state.push_back( "currentRot" );
    state.push_back( m_currentRot );
    state.push_back( "lastRot" );
    state.push_back( m_lastRot );
    state.push_back( "moveX" );
    state.push_back( m_moveX );
    state.push_back( "moveY" );
    state.push_back( m_moveY );
    state.push_back( "oldMoveX" );
    state.push_back( m_oldMoveX );
    state.push_back( "oldMoveY" );
    state.push_back( m_oldMoveY );
    state.push_back( "midClickX" );
    state.push_back( m_midClickX );
    state.push_back( "midClickY" );
    state.push_back( m_midClickY );
    state.push_back( "zoom" );
    state.push_back( m_zoom );
    state.push_back( "rotCenter" );
    state.push_back( m_rotCenter );
    state.push_back( "current_rotation" );
    state.push_back( q_current_rotation );
    return state;
}

void ArcBall::setState( QList<QVariant> state )
{
    m_currentRot = state[0].value<QMatrix4x4>();
    m_lastRot = state[1].value<QMatrix4x4>();
    m_moveX = state[2].toInt();
    m_moveY = state[3].toInt();
    m_oldMoveX = state[4].toInt();
    m_oldMoveY = state[5].toInt();
    m_midClickX = state[6].toInt();
    m_midClickY = state[7].toInt();
    m_zoom = state[8].toFloat();
    m_rotCenter = state[9].value<QVector3D>();
    q_current_rotation = state[10].value<QQuaternion>();
}

void ArcBall::setState( QMap<QString, QVariant> state )
{
    m_currentRot = state["currentRot"].value<QMatrix4x4>();
    m_lastRot = state["lastRot"].value<QMatrix4x4>();
    m_moveX = state["moveX"].toInt();
    m_moveY = state["moveY"].toInt();
    m_oldMoveX = state["oldMoveX"].toInt();
    m_oldMoveY = state["oldMoveY"].toInt();
    m_midClickX = state["midClickX"].toInt();
    m_midClickY = state["midClickY"].toInt();
    m_zoom = state["zoom"].toFloat();
    m_rotCenter = state["rotCenter"].value<QVector3D>();
    q_current_rotation = state["current_rotation"].value<QQuaternion>();
}

QQuaternion ArcBall::getRotation()
{
    return mat2quat( m_currentRot );
}

void ArcBall::setRotation( QQuaternion quat )
{
    m_currentRot.setToIdentity();
    m_lastRot.setToIdentity();
    m_currentRot.rotate( quat );
}

inline float SIGN(float x) {return (x >= 0.0f) ? +1.0f : -1.0f;}
inline float NORM(float a, float b, float c, float d) {return sqrt(a * a + b * b + c * c + d * d);}

QQuaternion ArcBall::mat2quat( QMatrix4x4 &mat )
{
    double r11 = mat( 0, 0 );
    double r12 = mat( 0, 1 );
    double r13 = mat( 0, 2 );
    double r21 = mat( 1, 0 );
    double r22 = mat( 1, 1 );
    double r23 = mat( 1, 2 );
    double r31 = mat( 2, 0 );
    double r32 = mat( 2, 1 );
    double r33 = mat( 2, 2 );

    double q0 = ( r11 + r22 + r33 + 1.0f ) / 4.0f;
    double q1 = ( r11 - r22 - r33 + 1.0f ) / 4.0f;
    double q2 = ( -r11 + r22 - r33 + 1.0f ) / 4.0f;
    double q3 = ( -r11 - r22 + r33 + 1.0f ) / 4.0f;

    if ( q0 < 0.0f )
        q0 = 0.0f;
    if ( q1 < 0.0f )
        q1 = 0.0f;
    if ( q2 < 0.0f )
        q2 = 0.0f;
    if ( q3 < 0.0f )
        q3 = 0.0f;
    q0 = sqrt( q0 );
    q1 = sqrt( q1 );
    q2 = sqrt( q2 );
    q3 = sqrt( q3 );
    if ( q0 >= q1 && q0 >= q2 && q0 >= q3 )
    {
        q0 *= +1.0f;
        q1 *= SIGN( r32 - r23 );
        q2 *= SIGN( r13 - r31 );
        q3 *= SIGN( r21 - r12 );
    }
    else if ( q1 >= q0 && q1 >= q2 && q1 >= q3 )
    {
        q0 *= SIGN( r32 - r23 );
        q1 *= +1.0f;
        q2 *= SIGN( r21 + r12 );
        q3 *= SIGN( r13 + r31 );
    }
    else if ( q2 >= q0 && q2 >= q1 && q2 >= q3 )
    {
        q0 *= SIGN( r13 - r31 );
        q1 *= SIGN( r21 + r12 );
        q2 *= +1.0f;
        q3 *= SIGN( r32 + r23 );
    }
    else if ( q3 >= q0 && q3 >= q1 && q3 >= q2 )
    {
        q0 *= SIGN( r21 - r12 );
        q1 *= SIGN( r31 + r13 );
        q2 *= SIGN( r32 + r23 );
        q3 *= +1.0f;
    }
    else
    {
        printf( "coding error\n" );
    }
    double r = NORM( q0, q1, q2, q3 );
    q0 /= r;
    q1 /= r;
    q2 /= r;
    q3 /= r;

    return QQuaternion( q0, q1, q2, q3 );
}

QVector3D ArcBall::getRotCenter()
{
    return m_rotCenter;
}
<commit_msg>reversed mousewheel zoom<commit_after>/*
 * arcball.cpp
 *
 * Created on: 10.05.2012
 * @author Ralph Schurade
 */
#include "arcball.h"

#include "../../data/models.h"

#include <QtDebug>

#include <math.h>

ArcBall::ArcBall( int width, int height ) :
    CameraBase( width, height ),
    Epsilon( 0.00001 ),
    m_moveX( 0 ),
    m_moveY( 0 ),
    m_oldMoveX( 0 ),
    m_oldMoveY( 0 ),
    m_midClickX( 0 ),
    m_midClickY( 0 )
{

    m_currentRot.setToIdentity();
    m_lastRot.setToIdentity();
}

ArcBall::~ArcBall()
{
}

// maps the specified mouse position to the sphere defined
// with center and radius. the resulting vector lies on the
// surface of the sphere.
QVector3D ArcBall::map_sphere( int x, int y )
{
    float tmpx = ( x * m_adjust_width ) - 1.0;
    float tmpy = 1.0 - ( y * m_adjust_height );

    float length = ( tmpx * tmpx ) + ( tmpy * tmpy );

    QVector3D bm;
    if ( length > 1.0 )
    {
        float norm = 1.0 / sqrt( length );
        bm.setX( tmpx * norm );
        bm.setY( tmpy * norm );
        bm.setZ( 0.0 );
    }
    else
    {
        bm.setX( tmpx );
        bm.setY( tmpy );
        bm.setZ( sqrt( 1.0 - length ) );
    }
    return bm;
}

/// sets the current position and calculates the current
/// rotation matrix.
void ArcBall::drag( int x, int y )
{
    QVector3D v_to = map_sphere( x, y );
    QVector3D perp = QVector3D::crossProduct( v_from, v_to);

    if ( perp.length() > Epsilon )
    {
        q_current_rotation.setX( perp.x() );
        q_current_rotation.setY( perp.y() );
        q_current_rotation.setZ( perp.z() );;
        q_current_rotation.setScalar( ( v_from.x() * v_to.x() ) + ( v_from.y() * v_to.y() ) + ( v_from.z() * v_to.z() ) );
    }
    else
    {
        q_current_rotation.setX( 0.0 );
        q_current_rotation.setY( 0.0 );
        q_current_rotation.setZ( 0.0 );
        q_current_rotation.setScalar( 0.0 );
    }
    m_currentRot.setToIdentity();
    m_currentRot.rotate( q_current_rotation );
    m_currentRot = m_currentRot * m_lastRot ;
}

/// indicates the beginning of the dragging.
void ArcBall::click( int x, int y )
{
    m_lastRot = m_currentRot;
    v_mouse_down.setX( x );
    v_mouse_down.setY( y );
    v_mouse_down.setZ( 0.0 );
    v_from = map_sphere( x, y );
}

void ArcBall::midClick( int x, int y )
{
    m_midClickX = x;
    m_midClickY = y;
    m_oldMoveX = m_moveX;
    m_oldMoveY = m_moveY;
}

void ArcBall::mouseWheel( float step )
{
    if ( step < 0 )
    {
        m_zoom /= 1.1;
        m_zoom = qMax( 0.2f, m_zoom );
    }
    else
    {
        m_zoom *= 1.1;
    }
}

void ArcBall::midDrag( int x, int y )
{
    m_moveX = m_oldMoveX + ( ( m_midClickX - x ) / 2 ) / m_zoom;
    m_moveY = m_oldMoveY + ( ( m_midClickY - y ) / 2 ) / m_zoom;
}

void ArcBall::setRotCenter( float x, float y, float z )
{
    m_rotCenter = QVector3D( -x, -y, -z );
}

void ArcBall::setView( Fn::Orient view )
{
    m_zoom = 1.0;
    m_moveX = 0;
    m_moveY = 0;
    m_oldMoveX = 0;
    m_oldMoveY = 0;
    m_currentRot.setToIdentity();
    m_lastRot.setToIdentity();

    QQuaternion rotx( sqrt(0.5), 0, 0, sqrt(0.5) );
    QQuaternion rot_x( -sqrt(0.5), 0, 0, sqrt(0.5) );
    QQuaternion roty( 0, sqrt(0.5), 0, sqrt(0.5) );
    QQuaternion rot_y( 0, -sqrt(0.5), 0, sqrt(0.5) );
    QQuaternion rotz( 0, 0, sqrt(0.5), sqrt(0.5) );
    QQuaternion rot_z( 0, 0, -sqrt(0.5), sqrt(0.5) );

    switch( view )
    {
        case Fn::Orient::NONE:
            break;
        case Fn::Orient::AXIAL:
            break;
        case Fn::Orient::CORONAL:
            m_currentRot.rotate( rotz );
            m_currentRot.rotate( rotx );
            m_currentRot.rotate( rotx );
            break;
        case Fn::Orient::SAGITTAL:
            m_currentRot.rotate( rot_x );
            m_currentRot.rotate( rot_y );
            break;
        case Fn::Orient::AXIAL2:
            m_currentRot.rotate( rot_y );
            m_currentRot.rotate( roty );
            break;
        case Fn::Orient::CORONAL2:
            m_currentRot.rotate( rotz );
            break;
        case Fn::Orient::SAGITTAL2:
            m_currentRot.rotate( rotx );
            m_currentRot.rotate( roty );
            break;
    }
}

/// returns the rotation matrix to be used directly
QMatrix4x4 ArcBall::getMVMat()
{
    QMatrix4x4 mv;
    mv.setToIdentity();

    mv = m_currentRot * mv ;

    float dist = Models::getGlobal( Fn::Property::G_ARCBALL_DISTANCE ).toFloat();

    QVector3D halfMove( -m_moveX, m_moveY, -dist );
    QMatrix4x4 tmp;
    tmp.setToIdentity();
    tmp.translate( halfMove );
    tmp = tmp * m_currentRot;

    mv = mv + tmp;

    mv.translate( m_rotCenter );

    return mv;
}

float ArcBall::getMoveX()
{
    return m_moveX;
}

float ArcBall::getMoveY()
{
    return m_moveY;
}

void ArcBall::setMoveX( float x )
{
    m_moveX = x;
}

void ArcBall::setMoveY( float y )
{
    m_moveY = y;
}

QList<QVariant> ArcBall::getState()
{
    QList<QVariant> state;
    state.push_back( "currentRot" );
    state.push_back( m_currentRot );
    state.push_back( "lastRot" );
    state.push_back( m_lastRot );
    state.push_back( "moveX" );
    state.push_back( m_moveX );
    state.push_back( "moveY" );
    state.push_back( m_moveY );
    state.push_back( "oldMoveX" );
    state.push_back( m_oldMoveX );
    state.push_back( "oldMoveY" );
    state.push_back( m_oldMoveY );
    state.push_back( "midClickX" );
    state.push_back( m_midClickX );
    state.push_back( "midClickY" );
    state.push_back( m_midClickY );
    state.push_back( "zoom" );
    state.push_back( m_zoom );
    state.push_back( "rotCenter" );
    state.push_back( m_rotCenter );
    state.push_back( "current_rotation" );
    state.push_back( q_current_rotation );
    return state;
}

void ArcBall::setState( QList<QVariant> state )
{
    m_currentRot = state[0].value<QMatrix4x4>();
    m_lastRot = state[1].value<QMatrix4x4>();
    m_moveX = state[2].toInt();
    m_moveY = state[3].toInt();
    m_oldMoveX = state[4].toInt();
    m_oldMoveY = state[5].toInt();
    m_midClickX = state[6].toInt();
    m_midClickY = state[7].toInt();
    m_zoom = state[8].toFloat();
    m_rotCenter = state[9].value<QVector3D>();
    q_current_rotation = state[10].value<QQuaternion>();
}

void ArcBall::setState( QMap<QString, QVariant> state )
{
    m_currentRot = state["currentRot"].value<QMatrix4x4>();
    m_lastRot = state["lastRot"].value<QMatrix4x4>();
    m_moveX = state["moveX"].toInt();
    m_moveY = state["moveY"].toInt();
    m_oldMoveX = state["oldMoveX"].toInt();
    m_oldMoveY = state["oldMoveY"].toInt();
    m_midClickX = state["midClickX"].toInt();
    m_midClickY = state["midClickY"].toInt();
    m_zoom = state["zoom"].toFloat();
    m_rotCenter = state["rotCenter"].value<QVector3D>();
    q_current_rotation = state["current_rotation"].value<QQuaternion>();
}

QQuaternion ArcBall::getRotation()
{
    return mat2quat( m_currentRot );
}

void ArcBall::setRotation( QQuaternion quat )
{
    m_currentRot.setToIdentity();
    m_lastRot.setToIdentity();
    m_currentRot.rotate( quat );
}

inline float SIGN(float x) {return (x >= 0.0f) ? +1.0f : -1.0f;}
inline float NORM(float a, float b, float c, float d) {return sqrt(a * a + b * b + c * c + d * d);}

QQuaternion ArcBall::mat2quat( QMatrix4x4 &mat )
{
    double r11 = mat( 0, 0 );
    double r12 = mat( 0, 1 );
    double r13 = mat( 0, 2 );
    double r21 = mat( 1, 0 );
    double r22 = mat( 1, 1 );
    double r23 = mat( 1, 2 );
    double r31 = mat( 2, 0 );
    double r32 = mat( 2, 1 );
    double r33 = mat( 2, 2 );

    double q0 = ( r11 + r22 + r33 + 1.0f ) / 4.0f;
    double q1 = ( r11 - r22 - r33 + 1.0f ) / 4.0f;
    double q2 = ( -r11 + r22 - r33 + 1.0f ) / 4.0f;
    double q3 = ( -r11 - r22 + r33 + 1.0f ) / 4.0f;

    if ( q0 < 0.0f )
        q0 = 0.0f;
    if ( q1 < 0.0f )
        q1 = 0.0f;
    if ( q2 < 0.0f )
        q2 = 0.0f;
    if ( q3 < 0.0f )
        q3 = 0.0f;
    q0 = sqrt( q0 );
    q1 = sqrt( q1 );
    q2 = sqrt( q2 );
    q3 = sqrt( q3 );
    if ( q0 >= q1 && q0 >= q2 && q0 >= q3 )
    {
        q0 *= +1.0f;
        q1 *= SIGN( r32 - r23 );
        q2 *= SIGN( r13 - r31 );
        q3 *= SIGN( r21 - r12 );
    }
    else if ( q1 >= q0 && q1 >= q2 && q1 >= q3 )
    {
        q0 *= SIGN( r32 - r23 );
        q1 *= +1.0f;
        q2 *= SIGN( r21 + r12 );
        q3 *= SIGN( r13 + r31 );
    }
    else if ( q2 >= q0 && q2 >= q1 && q2 >= q3 )
    {
        q0 *= SIGN( r13 - r31 );
        q1 *= SIGN( r21 + r12 );
        q2 *= +1.0f;
        q3 *= SIGN( r32 + r23 );
    }
    else if ( q3 >= q0 && q3 >= q1 && q3 >= q2 )
    {
        q0 *= SIGN( r21 - r12 );
        q1 *= SIGN( r31 + r13 );
        q2 *= SIGN( r32 + r23 );
        q3 *= +1.0f;
    }
    else
    {
        printf( "coding error\n" );
    }
    double r = NORM( q0, q1, q2, q3 );
    q0 /= r;
    q1 /= r;
    q2 /= r;
    q3 /= r;

    return QQuaternion( q0, q1, q2, q3 );
}

QVector3D ArcBall::getRotCenter()
{
    return m_rotCenter;
}
<|endoftext|>