<commit_before>/*
* Copyright (c) 2003-2016 <NAME> <<EMAIL>>.
* All rights reserved. Use of the code is allowed under the
* Artistic License 2.0 terms, as specified in the LICENSE file
* distributed with this code, or available from
* http://www.opensource.org/licenses/artistic-license-2.0.php
*/

/**
 * \file Windows-specific implementation of run.h
 */

#include "../typedefs.h"
#include <shellapi.h>

#include "../run.h"
#include "../debug.h"
#include "../dir.h"
#include "../env.h"
#include "../file.h"
#include "../utf8conv.h"
#include "../lib.h"

#include "pws_autotype/pws_at.h"

#include <vector>
#include <algorithm>

typedef AT_API BOOL (* AT_PROC_BOOL) (HWND);
typedef AT_API int  (* AT_PROC_INT) ();

struct st_run_impl {
  AT_PROC_BOOL pInit;   // Pointer to   Initialise function in pws_at(_D).dll
  AT_PROC_BOOL pUnInit; // Pointer to UnInitialise function in pws_at(_D).dll
  AT_PROC_INT  pGetVer; // Pointer to   GetVersion function in pws_at(_D).dll
  HWND hCBWnd;     // Handle to Window to receive SendMessage for processing
                   //   It is the main DboxMain window.
  HINSTANCE m_AT_HK_module;

  bool isValid() const {return m_AT_HK_module != NULL;}

  st_run_impl()
    : pInit(NULL), pUnInit(NULL), hCBWnd(NULL), m_AT_HK_module(NULL) {
    // Support Autotype with Launch Browser and Run Command
    // Try to load DLL to call back when window active for Autotype
#if defined( _DEBUG ) || defined( DEBUG )
    TCHAR *dll_name = _T("pws_at_D.dll");
#else
    TCHAR *dll_name = _T("pws_at.dll");
#endif
    m_AT_HK_module = HMODULE(pws_os::LoadLibrary(dll_name, pws_os::LOAD_LIBRARY_APP));
    if (m_AT_HK_module != NULL) {
      pws_os::Trace(_T("st_run_impl::st_run_impl - AutoType DLL Loaded: OK\n"));
      pInit  = AT_PROC_BOOL(pws_os::GetFunction(m_AT_HK_module, "AT_HK_Initialise"));
      pws_os::Trace(_T("st_run_impl::st_run_impl - Found AT_HK_Initialise: %s\n"),
            pInit != NULL ? _T("OK") : _T("FAILED"));

      pUnInit = AT_PROC_BOOL(pws_os::GetFunction(m_AT_HK_module, "AT_HK_UnInitialise"));
      pws_os::Trace(_T("st_run_impl::st_run_impl - Found AT_HK_UnInitialise: %s\n"),
            pUnInit != NULL ? _T("OK") : _T("FAILED"));

      pGetVer = AT_PROC_INT(pws_os::GetFunction(m_AT_HK_module, "AT_HK_GetVersion"));
      pws_os::Trace(_T("st_run_impl::st_run_impl - Found AT_HK_GetVersion: %s\n"),
            pGetVer != NULL ? _T("OK") : _T("FAILED"));

      if (pGetVer == NULL || pGetVer() != AT_DLL_VERSION) {
        pws_os::Trace(_T("st_run_impl::st_run_impl - Unable to determine DLL version")
                      _T(" or incorrect version\n"));
        BOOL brc = pws_os::FreeLibrary(m_AT_HK_module);
        pws_os::Trace(_T("st_run_impl::st_run_impl - Free Autotype DLL: %s\n"),
                      brc == TRUE ? _T("OK") : _T("FAILED"));
        m_AT_HK_module = NULL;
      }
    }
  }

  st_run_impl(const st_run_impl &that)
    : pInit(that.pInit), pUnInit(that.pUnInit), pGetVer(that.pGetVer),
      hCBWnd(that.hCBWnd), m_AT_HK_module(that.m_AT_HK_module) {}

  st_run_impl &operator=(const st_run_impl &that)
  {
    if (this != &that) {
      pInit = that.pInit;
      pUnInit = that.pUnInit;
      pGetVer = that.pGetVer;
      hCBWnd = that.hCBWnd;
      m_AT_HK_module = that.m_AT_HK_module;
    }
    return *this;
  }

  ~st_run_impl() {
    if (m_AT_HK_module != NULL) {
      // Autotype UnInitialise just in case - should have been done
      // during the callback process.  It will probably return failed
      // but we don't care.
      pUnInit(hCBWnd);
      BOOL brc = pws_os::FreeLibrary(m_AT_HK_module);
      pws_os::Trace(_T("st_run_impl::~st_run_impl - Free Autotype DLL: %s\n"),
                    brc == TRUE ? _T("OK") : _T("FAILED"));
      m_AT_HK_module = NULL;
    }
  }
};

PWSRun::PWSRun()
{
  pImpl = new st_run_impl;
}

PWSRun::~PWSRun()
{
  delete pImpl;
}

bool PWSRun::isValid() const
{
  return ((pImpl != NULL) && pImpl->isValid());
}

void PWSRun::Set(void *data) const
{
  if (pImpl != NULL)
    pImpl->hCBWnd = reinterpret_cast<HWND>(data);
}

bool PWSRun::UnInit()
{
  if (pImpl != NULL) {
    return pImpl->pUnInit(pImpl->hCBWnd) == TRUE;
  } else
    return false;
}

bool PWSRun::runcmd(const StringX &run_command, const bool &bAutotype) const
{
  // Get first parameter either enclosed by quotes or delimited by a space
  StringX full_string(run_command), first_part(_T("")), the_rest(_T(""));
  StringX env_var, sx_temp(_T(""));
  StringX::size_type end_delim;
  bool bfound(true);

  TrimLeft(full_string, _T(" "));
  if (full_string.c_str()[0] == _T('"')) {
    end_delim = full_string.find(_T('"'), 1);
    first_part = full_string.substr(1, end_delim - 1);
    the_rest = full_string.substr(end_delim + 1);
  } else {
    end_delim = full_string.find(_T(' '));
    if (end_delim != StringX::npos) {
      first_part = full_string.substr(0, end_delim);
      the_rest = full_string.substr(end_delim + 1);
    } else
      first_part = full_string;
  }

  // tokenize into separate elements using % as the field separator.
  // If this corresponds to a set envrionmental variable - replace it
  // and rebuild the command
  for (StringX::size_type st_startpos = 0;
       st_startpos < first_part.size();
       /* st_startpos advanced in body */) {
    StringX::size_type st_next = first_part.find(_T('%'), st_startpos);
    if (st_next == StringX::npos) {
      sx_temp += first_part.substr(st_startpos);
      break;
    }<commit_msg>spelling: environmental<commit_after>/*
* Copyright (c) 2003-2016 <NAME> <<EMAIL>>.
* All rights reserved. Use of the code is allowed under the
* Artistic License 2.0 terms, as specified in the LICENSE file
* distributed with this code, or available from
* http://www.opensource.org/licenses/artistic-license-2.0.php
*/

/**
 * \file Windows-specific implementation of run.h
 */

#include "../typedefs.h"
#include <shellapi.h>

#include "../run.h"
#include "../debug.h"
#include "../dir.h"
#include "../env.h"
#include "../file.h"
#include "../utf8conv.h"
#include "../lib.h"

#include "pws_autotype/pws_at.h"

#include <vector>
#include <algorithm>

typedef AT_API BOOL (* AT_PROC_BOOL) (HWND);
typedef AT_API int  (* AT_PROC_INT) ();

struct st_run_impl {
  AT_PROC_BOOL pInit;   // Pointer to   Initialise function in pws_at(_D).dll
  AT_PROC_BOOL pUnInit; // Pointer to UnInitialise function in pws_at(_D).dll
  AT_PROC_INT  pGetVer; // Pointer to   GetVersion function in pws_at(_D).dll
  HWND hCBWnd;     // Handle to Window to receive SendMessage for processing
                   //   It is the main DboxMain window.
  HINSTANCE m_AT_HK_module;

  bool isValid() const {return m_AT_HK_module != NULL;}

  st_run_impl()
    : pInit(NULL), pUnInit(NULL), hCBWnd(NULL), m_AT_HK_module(NULL) {
    // Support Autotype with Launch Browser and Run Command
    // Try to load DLL to call back when window active for Autotype
#if defined( _DEBUG ) || defined( DEBUG )
    TCHAR *dll_name = _T("pws_at_D.dll");
#else
    TCHAR *dll_name = _T("pws_at.dll");
#endif
    m_AT_HK_module = HMODULE(pws_os::LoadLibrary(dll_name, pws_os::LOAD_LIBRARY_APP));
    if (m_AT_HK_module != NULL) {
      pws_os::Trace(_T("st_run_impl::st_run_impl - AutoType DLL Loaded: OK\n"));
      pInit  = AT_PROC_BOOL(pws_os::GetFunction(m_AT_HK_module, "AT_HK_Initialise"));
      pws_os::Trace(_T("st_run_impl::st_run_impl - Found AT_HK_Initialise: %s\n"),
            pInit != NULL ? _T("OK") : _T("FAILED"));

      pUnInit = AT_PROC_BOOL(pws_os::GetFunction(m_AT_HK_module, "AT_HK_UnInitialise"));
      pws_os::Trace(_T("st_run_impl::st_run_impl - Found AT_HK_UnInitialise: %s\n"),
            pUnInit != NULL ? _T("OK") : _T("FAILED"));

      pGetVer = AT_PROC_INT(pws_os::GetFunction(m_AT_HK_module, "AT_HK_GetVersion"));
      pws_os::Trace(_T("st_run_impl::st_run_impl - Found AT_HK_GetVersion: %s\n"),
            pGetVer != NULL ? _T("OK") : _T("FAILED"));

      if (pGetVer == NULL || pGetVer() != AT_DLL_VERSION) {
        pws_os::Trace(_T("st_run_impl::st_run_impl - Unable to determine DLL version")
                      _T(" or incorrect version\n"));
        BOOL brc = pws_os::FreeLibrary(m_AT_HK_module);
        pws_os::Trace(_T("st_run_impl::st_run_impl - Free Autotype DLL: %s\n"),
                      brc == TRUE ? _T("OK") : _T("FAILED"));
        m_AT_HK_module = NULL;
      }
    }
  }

  st_run_impl(const st_run_impl &that)
    : pInit(that.pInit), pUnInit(that.pUnInit), pGetVer(that.pGetVer),
      hCBWnd(that.hCBWnd), m_AT_HK_module(that.m_AT_HK_module) {}

  st_run_impl &operator=(const st_run_impl &that)
  {
    if (this != &that) {
      pInit = that.pInit;
      pUnInit = that.pUnInit;
      pGetVer = that.pGetVer;
      hCBWnd = that.hCBWnd;
      m_AT_HK_module = that.m_AT_HK_module;
    }
    return *this;
  }

  ~st_run_impl() {
    if (m_AT_HK_module != NULL) {
      // Autotype UnInitialise just in case - should have been done
      // during the callback process.  It will probably return failed
      // but we don't care.
      pUnInit(hCBWnd);
      BOOL brc = pws_os::FreeLibrary(m_AT_HK_module);
      pws_os::Trace(_T("st_run_impl::~st_run_impl - Free Autotype DLL: %s\n"),
                    brc == TRUE ? _T("OK") : _T("FAILED"));
      m_AT_HK_module = NULL;
    }
  }
};

PWSRun::PWSRun()
{
  pImpl = new st_run_impl;
}

PWSRun::~PWSRun()
{
  delete pImpl;
}

bool PWSRun::isValid() const
{
  return ((pImpl != NULL) && pImpl->isValid());
}

void PWSRun::Set(void *data) const
{
  if (pImpl != NULL)
    pImpl->hCBWnd = reinterpret_cast<HWND>(data);
}

bool PWSRun::UnInit()
{
  if (pImpl != NULL) {
    return pImpl->pUnInit(pImpl->hCBWnd) == TRUE;
  } else
    return false;
}

bool PWSRun::runcmd(const StringX &run_command, const bool &bAutotype) const
{
  // Get first parameter either enclosed by quotes or delimited by a space
  StringX full_string(run_command), first_part(_T("")), the_rest(_T(""));
  StringX env_var, sx_temp(_T(""));
  StringX::size_type end_delim;
  bool bfound(true);

  TrimLeft(full_string, _T(" "));
  if (full_string.c_str()[0] == _T('"')) {
    end_delim = full_string.find(_T('"'), 1);
    first_part = full_string.substr(1, end_delim - 1);
    the_rest = full_string.substr(end_delim + 1);
  } else {
    end_delim = full_string.find(_T(' '));
    if (end_delim != StringX::npos) {
      first_part = full_string.substr(0, end_delim);
      the_rest = full_string.substr(end_delim + 1);
    } else
      first_part = full_string;
  }

  // tokenize into separate elements using % as the field separator.
  // If this corresponds to a set environmental variable - replace it
  // and rebuild the command
  for (StringX::size_type st_startpos = 0;
       st_startpos < first_part.size();
       /* st_startpos advanced in body */) {
    StringX::size_type st_next = first_part.find(_T('%'), st_startpos);
    if (st_next == StringX::npos) {
      sx_temp += first_part.substr(st_startpos);
      break;
    }
{'fraction_non_alphanumeric': 0.1442255062944718, 'fraction_numerical': 0.0038314176245210726, 'mean_word_length': 3.3538522637013504, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 25, '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': '1035930', 'n_tokens_mistral': 4226, 'n_tokens_neox': 4057, 'n_words': 881}