diff --git a/src/utils/pathut.cpp b/src/utils/pathut.cpp index bd3672d1..78839bd4 100644 --- a/src/utils/pathut.cpp +++ b/src/utils/pathut.cpp @@ -75,10 +75,6 @@ #ifdef _WIN32 -#if !defined(S_IFLNK) -#define S_IFLNK 0 -#endif - #ifndef _MSC_VER #undef WINVER #define WINVER 0x0601 @@ -98,6 +94,10 @@ #include #include + +#if !defined(S_IFLNK) +#define S_IFLNK 0 +#endif #ifndef S_ISDIR # define S_ISDIR(ST_MODE) (((ST_MODE) & _S_IFMT) == _S_IFDIR) #endif @@ -122,6 +122,7 @@ #define MKDIR(a,b) _wmkdir(a) #define OPEN ::_wopen #define UNLINK _wunlink +#define CHDIR _wchdir #define ftruncate _chsize_s @@ -153,7 +154,8 @@ #define MKDIR(a,b) mkdir(a,b) #define O_BINARY 0 #define OPEN ::open -#define UNLINK unlink +#define UNLINK ::unlink +#define CHDIR ::chdir #endif /* !_WIN32 */ @@ -161,29 +163,39 @@ using namespace std; #ifdef _WIN32 -bool wchartoutf8(const wchar_t *in, std::string& out) +std::string wchartoutf8(const wchar_t *in, size_t len) { - // fprintf(stderr, "WCHARTOUTF8: in [%S]\n", in); + std::string out; + wchartoutf8(in, out, len); + return out; +} + +bool wchartoutf8(const wchar_t *in, std::string& out, size_t wlen) +{ + LOGDEB1("WCHARTOUTF8: in [" << in << "]\n"); out.clear(); if (nullptr == in) { return true; } - size_t wlen = wcslen(in); + if (wlen == 0) { + wlen = wcslen(in); + } + int flags = WC_ERR_INVALID_CHARS|WC_NO_BEST_FIT_CHARS; int bytes = ::WideCharToMultiByte( - CP_UTF8, WC_ERR_INVALID_CHARS, in, wlen, nullptr, 0, nullptr, nullptr); + CP_UTF8, flags, in, wlen, nullptr, 0, nullptr, nullptr); if (bytes <= 0) { - std::cerr << "wchartoutf8: CONVERSION ERROR1\n"; + LOGERR("wchartoutf8: conversion error1\n"); return false; } char *cp = (char *)malloc(bytes+1); if (nullptr == cp) { - std::cerr << "wchartoutf8: MALLOC FAILED\n"; + LOGERR("wchartoutf8: malloc failed\n"); return false; } bytes = ::WideCharToMultiByte( - CP_UTF8, WC_ERR_INVALID_CHARS, in, wlen, cp, bytes, nullptr, nullptr); + CP_UTF8, flags, in, wlen, cp, bytes, nullptr, nullptr); if (bytes <= 0) { - std::cerr << "wchartoutf8: CONVERSION ERROR2\n"; + LOGERR("wchartoutf8: CONVERSION ERROR2\n"); free(cp); return false; } @@ -204,17 +216,17 @@ bool utf8towchar(const std::string& in, wchar_t *out, size_t obytescap) int wcharcnt = MultiByteToWideChar( CP_UTF8, MB_ERR_INVALID_CHARS, in.c_str(), in.size(), nullptr, 0); if (wcharcnt <= 0) { - std::cerr << "utf8towchar: CONVERSION ERROR\n"; + LOGERR("utf8towchar: conversion error for [" << in << "]\n"); return false; } if (wcharcnt + 1 > int(wcharsavail)) { - std::cerr << "utf8towchar: NOT ENOUGH SPACE\n"; + LOGERR("utf8towchar: not enough space\n"); return false; } wcharcnt = MultiByteToWideChar( CP_UTF8, MB_ERR_INVALID_CHARS, in.c_str(), in.size(), out, wcharsavail); if (wcharcnt <= 0) { - std::cerr << "utf8towchar: CONVERSION ERROR\n"; + LOGERR("utf8towchar: conversion error for [" << in << "]\n"); return false; } out[wcharcnt] = 0; @@ -836,6 +848,12 @@ bool path_makepath(const string& ipath, int mode) return true; } +bool path_chdir(const std::string& path) +{ + SYSPATH(path, syspath); + return CHDIR(syspath) == 0; +} + #if !defined(__GNUC__) || __GNUC__ > 4 || defined(__clang__) // Not sure what g++ version supports fstream assignment but 4.9 // (jessie) certainly does not diff --git a/src/utils/pathut.h b/src/utils/pathut.h index 3bcfc874..646a0517 100644 --- a/src/utils/pathut.h +++ b/src/utils/pathut.h @@ -109,7 +109,8 @@ extern bool path_readable(const std::string& path); extern std::string path_PATHsep(); #ifdef _WIN32 -extern bool wchartoutf8(const wchar_t *in, std::string& out); +extern bool wchartoutf8(const wchar_t *in, std::string& out, size_t len = 0); +extern std::string wchartoutf8(const wchar_t *in, size_t len = 0); extern bool utf8towchar(const std::string& in, wchar_t *out, size_t obytescap); #define SYSPATH(PATH, SPATH) wchar_t PATH ## _buf[2048]; \ utf8towchar(PATH, PATH ## _buf, 2048); \ @@ -132,6 +133,9 @@ bool fsocc(const std::string& path, int *pc, long long *avmbs = 0); /// mkdir -p extern bool path_makepath(const std::string& path, int mode); +/// +extern bool path_chdir(const std::string& path); + /* Open file, trying to do the right thing with non-ASCII paths on * Windows, where it only works with MSVC at the moment if the path is * not ASCII, because it uses fstream(wchar_t*), which is an MSVC