<commit_before>/*
 * Copyright 2006-2008 The FLWOR Foundation.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#include "stdafx.h"

#include "dynamic_loader.h"
#include "static_context.h"
#include <zorbamisc/ns_consts.h>
#include <system/globalenv.h>
#include <store/api/item_factory.h>

#ifdef UNIX
#  include <dlfcn.h>
#endif

#ifdef WIN32
#  include <strsafe.h>
#endif

#include <diagnostics/xquery_diagnostics.h>
#include <zorbatypes/URI.h>
#include <zorba/external_module.h>
#include <zorba/zorba_string.h>
#include <context/get_current_lib_suffix.h>
#include <fstream>
#include <util/error_util.h>

namespace zorba {

static std::string computeVersionInfix(zstring const& aImportedVersion)
{
  if (aImportedVersion == "") {
    return "";
  }
  std::ostringstream lInfix;
  lInfix << "_" << aImportedVersion;
  return lInfix.str();
}


static zstring computeLibraryName(
    const URI& aURI,
    const zstring& aImportedVersion, 
    bool aUseDebugDir = false)
{
  zstring lPathNotation = aURI.toPathNotation();

  // get the module file name
  size_t lIndexOfLastSlash = lPathNotation.find_last_of("/");

  zstring lFileName;
  zstring lBranchPath;

  // if the URI ends in '/'
  if (lIndexOfLastSlash == lPathNotation.size())
  {
    lBranchPath = lPathNotation;
  }
  else
  {
    // if '/' is not found
    if (lIndexOfLastSlash == std::string::npos)
    {
      lFileName = lPathNotation;
    }
    else
    {
      lFileName = lPathNotation.substr(lIndexOfLastSlash + 1);
      lBranchPath = lPathNotation.substr(0, lIndexOfLastSlash + 1);
    }

    // remove .xq from the end of the file if present
    // bugfix: find_last_of didn't do the right thing
    size_t lIndexOfXQ = lFileName.find(".xq");
    if (lIndexOfXQ != std::string::npos && lIndexOfXQ == lFileName.size() - 3)
    {
      lFileName.erase(lIndexOfXQ);
    }
  }

  // create the name of the file
  // win32: module.dll
  // apple: libmodule.dylib
  // other unix: libmodule.so
  // If version number is not blank, insert it into the path before the extension
  std::ostringstream lLibraryName;
  lLibraryName << lBranchPath;

#ifdef WIN32
  if (aUseDebugDir) 
  {
#ifndef NDEBUG
    lLibraryName << "Debug\\";
#else
    lLibraryName << "Release\\";
#endif
  }
  lLibraryName << lFileName << get_current_lib_suffix()
               << computeVersionInfix(aImportedVersion) << ".dll";

#else // !WIN32

  if (aUseDebugDir) 
  {
    lLibraryName << "Debug/";
  }
#ifdef APPLE
  lLibraryName << "lib" << lFileName << get_current_lib_suffix()
               << computeVersionInfix(aImportedVersion) << ".dylib";
#else
  lLibraryName << "lib" << lFileName << get_current_lib_suffix()
               << computeVersionInfix(aImportedVersion) << ".so";
#endif
#endif

  return lLibraryName.str();
}


ExternalModule*
DynamicLoader::loadModule(const zstring& aFile) const
{
  handle_t handle;
  std::map<const zstring, handle_t>::const_iterator lIter;

  lIter = theLibraries.find(aFile);
  if (lIter != theLibraries.end())
  {
    handle = lIter->second;
    return createModule(handle, aFile);
  }

#ifdef WIN32
  WCHAR wpath_str[1024];
  wpath_str[0] = 0;
  if(MultiByteToWideChar(CP_UTF8,
                      0, aFile.c_str(), -1,
                      wpath_str, sizeof(wpath_str)/sizeof(WCHAR)) == 0)
  {//probably there is some invalid utf8 char, try the Windows ACP
    MultiByteToWideChar(CP_ACP,
                      0, aFile.c_str(), -1,
                      wpath_str, sizeof(wpath_str)/sizeof(WCHAR));
  }

  handle = LoadLibraryW(wpath_str);
  if (!handle)
    throw ZORBA_EXCEPTION(
      zerr::ZOSE0005_DLL_LOAD_FAILED,
      ERROR_PARAMS( aFile, os_error::get_err_string() )<commit_msg>Fix to avoid message box on windows and the error can be handled by Zorba only. Approved: <NAME>, <NAME><commit_after>/*
 * Copyright 2006-2008 The FLWOR Foundation.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#include "stdafx.h"

#include "dynamic_loader.h"
#include "static_context.h"
#include <zorbamisc/ns_consts.h>
#include <system/globalenv.h>
#include <store/api/item_factory.h>

#ifdef UNIX
#  include <dlfcn.h>
#endif

#ifdef WIN32
#  include <strsafe.h>
#endif

#include <diagnostics/xquery_diagnostics.h>
#include <zorbatypes/URI.h>
#include <zorba/external_module.h>
#include <zorba/zorba_string.h>
#include <context/get_current_lib_suffix.h>
#include <fstream>
#include <util/error_util.h>

namespace zorba {

static std::string computeVersionInfix(zstring const& aImportedVersion)
{
  if (aImportedVersion == "") {
    return "";
  }
  std::ostringstream lInfix;
  lInfix << "_" << aImportedVersion;
  return lInfix.str();
}


static zstring computeLibraryName(
    const URI& aURI,
    const zstring& aImportedVersion, 
    bool aUseDebugDir = false)
{
  zstring lPathNotation = aURI.toPathNotation();

  // get the module file name
  size_t lIndexOfLastSlash = lPathNotation.find_last_of("/");

  zstring lFileName;
  zstring lBranchPath;

  // if the URI ends in '/'
  if (lIndexOfLastSlash == lPathNotation.size())
  {
    lBranchPath = lPathNotation;
  }
  else
  {
    // if '/' is not found
    if (lIndexOfLastSlash == std::string::npos)
    {
      lFileName = lPathNotation;
    }
    else
    {
      lFileName = lPathNotation.substr(lIndexOfLastSlash + 1);
      lBranchPath = lPathNotation.substr(0, lIndexOfLastSlash + 1);
    }

    // remove .xq from the end of the file if present
    // bugfix: find_last_of didn't do the right thing
    size_t lIndexOfXQ = lFileName.find(".xq");
    if (lIndexOfXQ != std::string::npos && lIndexOfXQ == lFileName.size() - 3)
    {
      lFileName.erase(lIndexOfXQ);
    }
  }

  // create the name of the file
  // win32: module.dll
  // apple: libmodule.dylib
  // other unix: libmodule.so
  // If version number is not blank, insert it into the path before the extension
  std::ostringstream lLibraryName;
  lLibraryName << lBranchPath;

#ifdef WIN32
  if (aUseDebugDir) 
  {
#ifndef NDEBUG
    lLibraryName << "Debug\\";
#else
    lLibraryName << "Release\\";
#endif
  }
  lLibraryName << lFileName << get_current_lib_suffix()
               << computeVersionInfix(aImportedVersion) << ".dll";

#else // !WIN32

  if (aUseDebugDir) 
  {
    lLibraryName << "Debug/";
  }
#ifdef APPLE
  lLibraryName << "lib" << lFileName << get_current_lib_suffix()
               << computeVersionInfix(aImportedVersion) << ".dylib";
#else
  lLibraryName << "lib" << lFileName << get_current_lib_suffix()
               << computeVersionInfix(aImportedVersion) << ".so";
#endif
#endif

  return lLibraryName.str();
}


ExternalModule*
DynamicLoader::loadModule(const zstring& aFile) const
{
  handle_t handle;
  std::map<const zstring, handle_t>::const_iterator lIter;

  lIter = theLibraries.find(aFile);
  if (lIter != theLibraries.end())
  {
    handle = lIter->second;
    return createModule(handle, aFile);
  }

#ifdef WIN32
  WCHAR wpath_str[1024];
  wpath_str[0] = 0;
  if(MultiByteToWideChar(CP_UTF8,
                      0, aFile.c_str(), -1,
                      wpath_str, sizeof(wpath_str)/sizeof(WCHAR)) == 0)
  {//probably there is some invalid utf8 char, try the Windows ACP
    MultiByteToWideChar(CP_ACP,
                      0, aFile.c_str(), -1,
                      wpath_str, sizeof(wpath_str)/sizeof(WCHAR));
  }
  SetErrorMode(SEM_NOOPENFILEERRORBOX|SEM_FAILCRITICALERRORS);
  handle = LoadLibraryW(wpath_str);
  SetErrorMode(0);
  if (!handle)
    throw ZORBA_EXCEPTION(
      zerr::ZOSE0005_DLL_LOAD_FAILED,
      ERROR_PARAMS( aFile, os_error::get_err_string() )
{'fraction_non_alphanumeric': 0.11719298245614035, 'fraction_numerical': 0.010175438596491228, 'mean_word_length': 3.4145585957666493, 'pattern_counts': {'":': 0, '<': 111, '<?xml version=': 0, '>': 33, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6588739', 'n_tokens_mistral': 2995, 'n_tokens_neox': 2893, 'n_words': 724}