29#if defined(_WIN32) && !defined(__CYGWIN__)
52#if !defined(_WIN32) || defined(__CYGWIN__)
54static std::map<std::string,std::string>
proc_env = std::map<std::string,std::string>();
68 std::lock_guard<std::mutex> lock(
m_mutex);
69 m_startTimes[std::this_thread::get_id()] = std::chrono::steady_clock::now();
74 std::lock_guard<std::mutex> lock(
m_mutex);
75 std::chrono::steady_clock::time_point endTime = std::chrono::steady_clock::now();
79 err(
"SysTimeKeeper stop() called without matching start()\n");
82 double timeSpent =
static_cast<double>(std::chrono::duration_cast<
83 std::chrono::microseconds>(endTime - it->second).count())/1000000.0;
95 std::map<std::thread::id,std::chrono::steady_clock::time_point>
m_startTimes;
123 if (command.
empty())
return 1;
126#if defined(_WIN32) && !defined(__CYGWIN__)
128 DString fullCmd=commandCorrectedPath;
136 fullCmd=
"\""+fullCmd+
"\"";
144#if !defined(_WIN32) || defined(__CYGWIN__)
145 (void)commandHasConsole;
161 execl(
"/bin/sh",
"sh",
"-c",fullCmd.
data(),(
char*)0);
166 while (waitpid(
pid,&status,0 )<0)
182 perror(
"fork error");
187 const char *
const argv[4] = {
"sh",
"-c", fullCmd.
data(), 0 };
188 execve(
"/bin/sh",
const_cast<char * const*
>(argv),
environ);
193 if (waitpid(
pid,&status,0)==-1)
195 if (errno!=EINTR)
return -1;
199 if (WIFEXITED(status))
201 return WEXITSTATUS(status);
212 if (commandHasConsole)
214 return ::system(fullCmd.
data());
218 uint16_t* fullCmdW =
nullptr;
221 STARTUPINFOW sStartupInfo;
222 std::memset(&sStartupInfo, 0,
sizeof(sStartupInfo));
223 sStartupInfo.cb =
sizeof(sStartupInfo);
224 sStartupInfo.dwFlags |= STARTF_USESHOWWINDOW;
225 sStartupInfo.wShowWindow = SW_HIDE;
227 PROCESS_INFORMATION sProcessInfo;
228 std::memset(&sProcessInfo, 0,
sizeof(sProcessInfo));
232 reinterpret_cast<wchar_t*
>(fullCmdW),
246 else if (sProcessInfo.hProcess)
248 WaitForSingleObject(sProcessInfo.hProcess,INFINITE);
251 bool retval = GetExitCodeProcess(sProcessInfo.hProcess,&exitCode);
252 CloseHandle(sProcessInfo.hProcess);
253 CloseHandle(sProcessInfo.hThread);
255 if (!retval)
return -1;
267#if !defined(_WIN32) || defined(__CYGWIN__)
268 pid =
static_cast<uint32_t
>(getpid());
270 pid =
static_cast<uint32_t
>(GetCurrentProcessId());
275#if !defined(_WIN32) || defined(__CYGWIN__)
283 while(current !=
nullptr)
285 std::string env_var(current);
286 size_t pos = env_var.find(
"=");
287 if(pos != std::string::npos)
289 std::string name = env_var.substr(0,pos);
290 std::string value = env_var.substr(pos + 1);
304#if defined(_WIN32) && !defined(__CYGWIN__)
305 SetEnvironmentVariable(name.
data(),!value.
empty() ? value.
data() :
"");
319#if defined(_WIN32) && !defined(__CYGWIN__)
320 SetEnvironmentVariable(variable.
data(),
nullptr);
339#if defined(_WIN32) && !defined(__CYGWIN__)
340 #define ENV_BUFSIZE 32768
341 LPTSTR pszVal = (LPTSTR) malloc(ENV_BUFSIZE*
sizeof(TCHAR));
342 if (GetEnvironmentVariable(variable.
data(),pszVal,ENV_BUFSIZE) == 0)
return "";
367#if defined(_WIN32) && !defined(__CYGWIN__)
368 uint16_t *fn =
nullptr;
370 uint16_t *m =
nullptr;
372 FILE *result =
nullptr;
373 if (fn_len!=(
size_t)-1 && m_len!=(
size_t)-1)
375 result = _wfopen((
wchar_t*)fn,(
wchar_t*)m);
381 return ::fopen(fileName.
data(),mode.
data());
392#if defined(_WIN32) && !defined(__CYGWIN__)
401#if defined(_WIN32) && !defined(__CYGWIN__)
411 if (fi1.
exists())
return true;
424 if (fi.
exists())
return true;
429 if (!locFile.
empty())
434 if (fi.
exists())
return true;
441#if defined(_WIN32) && !defined(__CYGWIN__)
442 const char *extensions[] = {
".bat",
".com",
".exe"};
443 for (
int i = 0; i <
sizeof(extensions) /
sizeof(*extensions); i++)
445 if (
ExistsOnPath(fileName + extensions[i]))
return true;
455#if defined(_WIN32) && !defined(__CYGWIN__)
456 static const char *gsexe =
nullptr;
459 const char *gsExec[] = {
"gswin32c.exe",
"gswin64c.exe"};
460 for (
int i = 0; i <
sizeof(gsExec) /
sizeof(*gsExec); i++)
479#if defined(_WIN32) && !defined(__CYGWIN__)
488#if defined(_WIN32) || defined(macintosh) || defined(__MACOSX__) || defined(__APPLE__) || defined(__CYGWIN__)
497 #if defined(_MSC_VER) || defined(__BORLANDC__)
498 return ::_popen(name.
data(),type.
data());
500 return ::popen(name.
data(),type.
data());
506 #if defined(_MSC_VER) || defined(__BORLANDC__)
507 return ::_pclose(stream);
509 return ::pclose(stream);
515 const char *fn = fileName.
data();
517 if (fileName.
length()>1 && isalpha(fileName[0]) && fileName[1]==
':') fn+=2;
519 char const fst = fn[0];
520 if (fst ==
'/')
return true;
522 if (fst ==
'\\')
return true;
537#if defined(_WIN32) && !defined(__CYGWIN__)
538 for (
const auto &path : extraPaths)
540 if (!first) result+=
';';
544 if (!result.
empty() && !p.
empty()) result+=
';';
547 for (
const auto &path : extraPaths)
549 if (!first) result+=
':';
553 if (!result.
empty() && !p.
empty()) result+=
':';
562#if defined(_WIN32) && !defined(__CYGWIN__)
563 _unlink(fileName.
data());
571#if defined(_WIN32) && !defined(__CYGWIN__)
573 TCHAR* buffer =
nullptr;
578 buffer =
new TCHAR[length];
589 const char *needle,
size_t needle_len)
591 const char *
const last_possible = haystack + haystack_len - needle_len;
600 if (haystack_len < needle_len)
607 if (
begin[0] == needle[0] && !memcmp(&
begin[1], needle + 1, needle_len - 1))
618 size_t needle_len = strnlen(needle, haystack_len);
619 if (needle_len < haystack_len || !needle[needle_len])
621 const char *x =
portable_memmem(haystack, haystack_len, needle, needle_len);
622 if (x && !memchr(haystack, 0, x - haystack))
632#if defined(_WIN32) && !defined(__CYGWIN__)
641 if (inputStr.
empty() || outBuf==
nullptr)
return 0;
643 if (handle==
reinterpret_cast<void *
>(-1))
return 0;
644 size_t len = inputStr.
length();
645 uint16_t *buf =
new uint16_t[len+1];
647 size_t inRemains = len;
648 size_t outRemains = len*
sizeof(uint16_t)+2;
649 const char *p = inputStr.
data();
650 portable_iconv(handle,&p,&inRemains,
reinterpret_cast<char **
>(&buf),&outRemains);
662 result = path.
mid(4);
677#include "filesystem.hpp"
679namespace fs = ghc::filesystem;
683 std::ios_base::openmode mode = std::ofstream::out | std::ofstream::binary;
684 if (append) mode |= std::ofstream::app;
685#if defined(__clang__) && defined(__MINGW32__)
686 return std::ofstream(fs::path(fileName.
str()).wstring(), mode);
688 return std::ofstream(fs::path(fileName.
str()), mode);
694 std::ios_base::openmode mode = std::ifstream::in | std::ifstream::binary;
695 if (binary) mode |= std::ios::binary;
696 if (openAtEnd) mode |= std::ios::ate;
697#if defined(__clang__) && defined(__MINGW32__)
698 return std::ifstream(fs::path(fileName.
str()).wstring(), mode);
700 return std::ifstream(fs::path(fileName.
str()), mode);
A String class for use with Doxygen wrapping std::string and adding some additional functionality off...
DString mid(size_t index, size_t len=npos) const
bool empty() const
Returns true iff the string is empty (std::string compatible alias for isEmpty()).
static constexpr size_t npos
value used to indicate 'not found' or 'to the end of the string', matching std::string::npos
char & at(size_t i)
Returns a reference to the character at index i.
size_t find(char c, size_t pos=0) const
DString stripWhiteSpace() const
returns a copy of this string with leading and trailing whitespace removed
const std::string & str() const
const char * data() const
Returns a pointer to the contents of the string in the form of a 0-terminated C string.
bool startsWith(const char *s) const
size_t length() const
Returns the length of the string, not counting the 0-terminator.
static void print(DebugMask mask, int prio, fmt::format_string< Args... > fmt, Args &&... args)
static std::string currentDirPath()
static bool setCurrent(const std::string &path)
Minimal replacement for QFileInfo.
void stop()
ends a timer for this thread, accumulate time difference since start
void start()
start a timer for this thread
double elapsedTime() const
static SysTimeKeeper & instance()
std::map< std::thread::id, std::chrono::steady_clock::time_point > m_startTimes
std::vector< std::string > StringVector
DirIterator begin(DirIterator it) noexcept
DString substitute(const DString &s, const DString &src, const DString &dst)
substitute all occurrences of src in s by dst
void correctPath(const StringVector &list)
Correct a possible wrong PATH variable.
FILE * popen(const DString &name, const DString &type)
std::ifstream openInputStream(const DString &name, bool binary=false, bool openAtEnd=false)
double getSysElapsedTime()
void setenv(const DString &variable, const DString &value)
const char * ghostScriptCommand()
int system(const DString &command, const DString &args, bool commandHasConsole=true)
DString getenv(const DString &variable)
void unlink(const DString &fileName)
DString removeLongPathMarker(const DString &path)
bool fileSystemIsCaseSensitive()
size_t recodeUtf8StringToW(const DString &inputStr, uint16_t **buf)
bool isAbsolutePath(const DString &fileName)
DString pathListSeparator()
std::ofstream openOutputStream(const DString &name, bool append=false)
FILE * fopen(const DString &fileName, const DString &mode)
const char * commandExtension()
const char * strnstr(const char *haystack, const char *needle, size_t haystack_len)
void unsetenv(const DString &variable)
bool checkForExecutable(const DString &fileName)
static bool environmentLoaded
static std::map< std::string, std::string > proc_env
static const char * portable_memmem(const char *haystack, size_t haystack_len, const char *needle, size_t needle_len)
static bool ExistsOnPath(const DString &fileName)
Portable versions of functions that are platform dependent.
int portable_iconv_close(void *cd)
size_t portable_iconv(void *cd, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft)
void * portable_iconv_open(const char *tocode, const char *fromcode)
std::chrono::steady_clock::time_point startTime
A bunch of utility functions.