<commit_before>// Path convenience functions

#include <other/core/utility/path.h>
#include <other/core/utility/format.h>

#ifdef _WIN32
#define WINDOWS_LEAN_AND_MEAN
#include <windows.h>
#endif

#include <stdexcept>
#include <iostream>

namespace other {
namespace path {

string join(const string& p, const string& q) {
  return p+sep+q;
}

string join(const string& p0, const string& p1, const string& p2) {
  return join(join(p0,p1),p2);
}

string join(const string& p0, const string& p1, const string& p2, const string& p3) {
  return join(join(p0,p1),join(p2,p3));
}

// WARNING: These do not work for escaped directory separators
string extension(const string& path) {
  for (int i=path.size()-1;i>=0;i--) {
    // we stop if we're at the beginning, or at the first directory separator
    // this will treat filenames that begin with a '.' (and have no other '.')
    // as having no extension
    if (!i || is_sep(path[i-1]))
      break;
    if (path[i]=='.')
      return path.substr(i);
  }
  return string();
}

string remove_extension(const string& path) {
  string ext = extension(path);
  if (ext.empty())
    return path;
  return path.substr(0,path.size()-ext.size());
}

string basename(const string& path) {
  for (int i=path.size()-1;i>=0;i--)
    if (is_sep(path[i]))
      return path.substr(i+1);
  return path;
}

string dirname(const string& path) {
  for (int i=path.size()-1;i>=0;i--)
    if (is_sep(path[i]))
      return path.substr(0,i);
  return string();
}

void copy_file(const string &from, const string &to) {
  int ret = 0;
#ifdef _WIN32
  bool fail_if_exists = false;
  if (!CopyFileW(from.c_str(), to.c_str(), fail_if_exists)) {
    ret = GetLastError();
  }
#else
  // WARNING: the file names are not escaped, so this is a severe security risk.
  string cmd = format("cp '%s' '%s'", from, to);
  std::cout << "running shell command: " << cmd << std::endl;
  ret = system(cmd.c_str());<commit_msg>Changed CopyFileW to CopyFileA, since the latter works with narrow strings<commit_after>// Path convenience functions

#include <other/core/utility/path.h>
#include <other/core/utility/format.h>

#ifdef _WIN32
#define WINDOWS_LEAN_AND_MEAN
#include <windows.h>
#endif

#include <stdexcept>
#include <iostream>

namespace other {
namespace path {

string join(const string& p, const string& q) {
  return p+sep+q;
}

string join(const string& p0, const string& p1, const string& p2) {
  return join(join(p0,p1),p2);
}

string join(const string& p0, const string& p1, const string& p2, const string& p3) {
  return join(join(p0,p1),join(p2,p3));
}

// WARNING: These do not work for escaped directory separators
string extension(const string& path) {
  for (int i=path.size()-1;i>=0;i--) {
    // we stop if we're at the beginning, or at the first directory separator
    // this will treat filenames that begin with a '.' (and have no other '.')
    // as having no extension
    if (!i || is_sep(path[i-1]))
      break;
    if (path[i]=='.')
      return path.substr(i);
  }
  return string();
}

string remove_extension(const string& path) {
  string ext = extension(path);
  if (ext.empty())
    return path;
  return path.substr(0,path.size()-ext.size());
}

string basename(const string& path) {
  for (int i=path.size()-1;i>=0;i--)
    if (is_sep(path[i]))
      return path.substr(i+1);
  return path;
}

string dirname(const string& path) {
  for (int i=path.size()-1;i>=0;i--)
    if (is_sep(path[i]))
      return path.substr(0,i);
  return string();
}

void copy_file(const string &from, const string &to) {
  int ret = 0;
#ifdef _WIN32
  BOOL fail_if_exists = FALSE;
  if (!CopyFileA(from.c_str(), to.c_str(), fail_if_exists)) {
    ret = GetLastError();
  }
#else
  // WARNING: the file names are not escaped, so this is a severe security risk.
  string cmd = format("cp '%s' '%s'", from, to);
  std::cout << "running shell command: " << cmd << std::endl;
  ret = system(cmd.c_str());
{'fraction_non_alphanumeric': 0.15636918382913806, 'fraction_numerical': 0.01474701245868294, 'mean_word_length': 3.7917174177831914, 'pattern_counts': {'":': 0, '<': 25, '<?xml version=': 0, '>': 19, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, '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': '301604', 'n_tokens_mistral': 1419, 'n_tokens_neox': 1419, 'n_words': 417}