OS.cpp (getdp-3.4.0-source.tgz) | : | OS.cpp (getdp-3.5.0-source.tgz) | ||
---|---|---|---|---|
// GetDP - Copyright (C) 1997-2021 P. Dular and C. Geuzaine, University of Liege | // GetDP - Copyright (C) 1997-2022 P. Dular and C. Geuzaine, University of Liege | |||
// | // | |||
// See the LICENSE.txt file for license information. Please report all | // See the LICENSE.txt file for license information. Please report all | |||
// issues on https://gitlab.onelab.info/getdp/getdp/issues. | // issues on https://gitlab.onelab.info/getdp/getdp/issues. | |||
// This file contains a bunch of functions that depend on OS-dependent | // This file contains a bunch of functions that depend on OS-dependent | |||
// features and/or system calls | // features and/or system calls | |||
// these are available on all OSes | // these are available on all OSes | |||
#include <stdlib.h> | #include <stdlib.h> | |||
#include <stdio.h> | #include <stdio.h> | |||
skipping to change at line 47 | skipping to change at line 47 | |||
#include <io.h> | #include <io.h> | |||
#include <sys/timeb.h> | #include <sys/timeb.h> | |||
#endif | #endif | |||
#include "Message.h" | #include "Message.h" | |||
#if defined(WIN32) && !defined(__CYGWIN__) | #if defined(WIN32) && !defined(__CYGWIN__) | |||
// Unicode utility routines borrowed from FLTK | // Unicode utility routines borrowed from FLTK | |||
static unsigned int utf8decode(const char* p, const char* end, int* len) | static unsigned int utf8decode(const char *p, const char *end, int *len) | |||
{ | { | |||
static unsigned short cp1252[32] = { | static unsigned short cp1252[32] = { | |||
0x20ac, 0x0081, 0x201a, 0x0192, 0x201e, 0x2026, 0x2020, 0x2021, | 0x20ac, 0x0081, 0x201a, 0x0192, 0x201e, 0x2026, 0x2020, 0x2021, | |||
0x02c6, 0x2030, 0x0160, 0x2039, 0x0152, 0x008d, 0x017d, 0x008f, | 0x02c6, 0x2030, 0x0160, 0x2039, 0x0152, 0x008d, 0x017d, 0x008f, | |||
0x0090, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, | 0x0090, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, | |||
0x02dc, 0x2122, 0x0161, 0x203a, 0x0153, 0x009d, 0x017e, 0x0178 | 0x02dc, 0x2122, 0x0161, 0x203a, 0x0153, 0x009d, 0x017e, 0x0178}; | |||
}; | unsigned char c = *(unsigned char *)p; | |||
unsigned char c = *(unsigned char*)p; | if(c < 0x80) { | |||
if (c < 0x80) { | if(len) *len = 1; | |||
if (len) *len = 1; | ||||
return c; | return c; | |||
} else if (c < 0xa0) { | } | |||
if (len) *len = 1; | else if(c < 0xa0) { | |||
return cp1252[c-0x80]; | if(len) *len = 1; | |||
} else if (c < 0xc2) { | return cp1252[c - 0x80]; | |||
} | ||||
else if(c < 0xc2) { | ||||
goto FAIL; | goto FAIL; | |||
} | } | |||
if ( (end && p+1 >= end) || (p[1]&0xc0) != 0x80) goto FAIL; | if((end && p + 1 >= end) || (p[1] & 0xc0) != 0x80) goto FAIL; | |||
if (c < 0xe0) { | if(c < 0xe0) { | |||
if (len) *len = 2; | if(len) *len = 2; | |||
return | return ((p[0] & 0x1f) << 6) + ((p[1] & 0x3f)); | |||
((p[0] & 0x1f) << 6) + | } | |||
((p[1] & 0x3f)); | else if(c == 0xe0) { | |||
} else if (c == 0xe0) { | if(((unsigned char *)p)[1] < 0xa0) goto FAIL; | |||
if (((unsigned char*)p)[1] < 0xa0) goto FAIL; | ||||
goto UTF8_3; | goto UTF8_3; | |||
} else if (c < 0xf0) { | } | |||
else if(c < 0xf0) { | ||||
UTF8_3: | UTF8_3: | |||
if ( (end && p+2 >= end) || (p[2]&0xc0) != 0x80) goto FAIL; | if((end && p + 2 >= end) || (p[2] & 0xc0) != 0x80) goto FAIL; | |||
if (len) *len = 3; | if(len) *len = 3; | |||
return | return ((p[0] & 0x0f) << 12) + ((p[1] & 0x3f) << 6) + ((p[2] & 0x3f)); | |||
((p[0] & 0x0f) << 12) + | } | |||
((p[1] & 0x3f) << 6) + | else if(c == 0xf0) { | |||
((p[2] & 0x3f)); | if(((unsigned char *)p)[1] < 0x90) goto FAIL; | |||
} else if (c == 0xf0) { | ||||
if (((unsigned char*)p)[1] < 0x90) goto FAIL; | ||||
goto UTF8_4; | goto UTF8_4; | |||
} else if (c < 0xf4) { | } | |||
else if(c < 0xf4) { | ||||
UTF8_4: | UTF8_4: | |||
if ( (end && p+3 >= end) || (p[2]&0xc0) != 0x80 || (p[3]&0xc0) != 0x80) goto | if((end && p + 3 >= end) || (p[2] & 0xc0) != 0x80 || (p[3] & 0xc0) != 0x80) | |||
FAIL; | goto FAIL; | |||
if (len) *len = 4; | if(len) *len = 4; | |||
return | return ((p[0] & 0x07) << 18) + ((p[1] & 0x3f) << 12) + | |||
((p[0] & 0x07) << 18) + | ((p[2] & 0x3f) << 6) + ((p[3] & 0x3f)); | |||
((p[1] & 0x3f) << 12) + | } | |||
((p[2] & 0x3f) << 6) + | else if(c == 0xf4) { | |||
((p[3] & 0x3f)); | if(((unsigned char *)p)[1] > 0x8f) goto FAIL; // after 0x10ffff | |||
} else if (c == 0xf4) { | ||||
if (((unsigned char*)p)[1] > 0x8f) goto FAIL; // after 0x10ffff | ||||
goto UTF8_4; | goto UTF8_4; | |||
} else { | } | |||
else { | ||||
FAIL: | FAIL: | |||
if (len) *len = 1; | if(len) *len = 1; | |||
return c; | return c; | |||
} | } | |||
} | } | |||
static unsigned int utf8toUtf16(const char* src, unsigned int srclen, | static unsigned int utf8toUtf16(const char *src, unsigned int srclen, | |||
unsigned short* dst, unsigned int dstlen) | unsigned short *dst, unsigned int dstlen) | |||
{ | { | |||
const char* p = src; | const char *p = src; | |||
const char* e = src+srclen; | const char *e = src + srclen; | |||
unsigned int count = 0; | unsigned int count = 0; | |||
if (dstlen) for (;;) { | if(dstlen) | |||
if (p >= e) {dst[count] = 0; return count;} | for(;;) { | |||
if (!(*p & 0x80)) { // ascii | if(p >= e) { | |||
dst[count] = *p++; | dst[count] = 0; | |||
} else { | return count; | |||
int len; unsigned int ucs = utf8decode(p,e,&len); | } | |||
p += len; | if(!(*p & 0x80)) { // ascii | |||
if (ucs < 0x10000) { | dst[count] = *p++; | |||
dst[count] = ucs; | } | |||
} else { | else { | |||
// make a surrogate pair: | int len; | |||
if (count+2 >= dstlen) {dst[count] = 0; count += 2; break;} | unsigned int ucs = utf8decode(p, e, &len); | |||
dst[count] = (((ucs-0x10000u)>>10)&0x3ff) | 0xd800; | p += len; | |||
dst[++count] = (ucs&0x3ff) | 0xdc00; | if(ucs < 0x10000) { dst[count] = ucs; } | |||
else { | ||||
// make a surrogate pair: | ||||
if(count + 2 >= dstlen) { | ||||
dst[count] = 0; | ||||
count += 2; | ||||
break; | ||||
} | ||||
dst[count] = (((ucs - 0x10000u) >> 10) & 0x3ff) | 0xd800; | ||||
dst[++count] = (ucs & 0x3ff) | 0xdc00; | ||||
} | ||||
} | ||||
if(++count == dstlen) { | ||||
dst[count - 1] = 0; | ||||
break; | ||||
} | } | |||
} | } | |||
if (++count == dstlen) {dst[count-1] = 0; break;} | ||||
} | ||||
// we filled dst, measure the rest: | // we filled dst, measure the rest: | |||
while (p < e) { | while(p < e) { | |||
if (!(*p & 0x80)) p++; | if(!(*p & 0x80)) | |||
p++; | ||||
else { | else { | |||
int len; unsigned int ucs = utf8decode(p,e,&len); | int len; | |||
unsigned int ucs = utf8decode(p, e, &len); | ||||
p += len; | p += len; | |||
if (ucs >= 0x10000) ++count; | if(ucs >= 0x10000) ++count; | |||
} | } | |||
++count; | ++count; | |||
} | } | |||
return count; | return count; | |||
} | } | |||
static unsigned int utf8FromUtf16(char* dst, unsigned int dstlen, | static unsigned int utf8FromUtf16(char *dst, unsigned int dstlen, | |||
const wchar_t* src, unsigned int srclen) | const wchar_t *src, unsigned int srclen) | |||
{ | { | |||
unsigned int i = 0; | unsigned int i = 0; | |||
unsigned int count = 0; | unsigned int count = 0; | |||
if (dstlen) { | if(dstlen) { | |||
for (;;) { | for(;;) { | |||
unsigned int ucs; | unsigned int ucs; | |||
if (i >= srclen) {dst[count] = 0; return count;} | if(i >= srclen) { | |||
dst[count] = 0; | ||||
return count; | ||||
} | ||||
ucs = src[i++]; | ucs = src[i++]; | |||
if (ucs < 0x80U) { | if(ucs < 0x80U) { | |||
dst[count++] = ucs; | dst[count++] = ucs; | |||
if (count >= dstlen) {dst[count-1] = 0; break;} | if(count >= dstlen) { | |||
dst[count - 1] = 0; | ||||
break; | ||||
} | ||||
} | } | |||
else if (ucs < 0x800U) { /* 2 bytes */ | else if(ucs < 0x800U) { /* 2 bytes */ | |||
if (count+2 >= dstlen) {dst[count] = 0; count += 2; break;} | if(count + 2 >= dstlen) { | |||
dst[count] = 0; | ||||
count += 2; | ||||
break; | ||||
} | ||||
dst[count++] = 0xc0 | (ucs >> 6); | dst[count++] = 0xc0 | (ucs >> 6); | |||
dst[count++] = 0x80 | (ucs & 0x3F); | dst[count++] = 0x80 | (ucs & 0x3F); | |||
} | } | |||
else if (ucs >= 0xd800 && ucs <= 0xdbff && i < srclen && | else if(ucs >= 0xd800 && ucs <= 0xdbff && i < srclen && | |||
src[i] >= 0xdc00 && src[i] <= 0xdfff) { | src[i] >= 0xdc00 && src[i] <= 0xdfff) { | |||
/* surrogate pair */ | /* surrogate pair */ | |||
unsigned int ucs2 = src[i++]; | unsigned int ucs2 = src[i++]; | |||
ucs = 0x10000U + ((ucs&0x3ff)<<10) + (ucs2&0x3ff); | ucs = 0x10000U + ((ucs & 0x3ff) << 10) + (ucs2 & 0x3ff); | |||
/* all surrogate pairs turn into 4-byte utf8 */ | /* all surrogate pairs turn into 4-byte utf8 */ | |||
if (count+4 >= dstlen) {dst[count] = 0; count += 4; break;} | if(count + 4 >= dstlen) { | |||
dst[count] = 0; | ||||
count += 4; | ||||
break; | ||||
} | ||||
dst[count++] = 0xf0 | (ucs >> 18); | dst[count++] = 0xf0 | (ucs >> 18); | |||
dst[count++] = 0x80 | ((ucs >> 12) & 0x3F); | dst[count++] = 0x80 | ((ucs >> 12) & 0x3F); | |||
dst[count++] = 0x80 | ((ucs >> 6) & 0x3F); | dst[count++] = 0x80 | ((ucs >> 6) & 0x3F); | |||
dst[count++] = 0x80 | (ucs & 0x3F); | dst[count++] = 0x80 | (ucs & 0x3F); | |||
} | } | |||
else { | else { | |||
/* all others are 3 bytes: */ | /* all others are 3 bytes: */ | |||
if (count+3 >= dstlen) {dst[count] = 0; count += 3; break;} | if(count + 3 >= dstlen) { | |||
dst[count] = 0; | ||||
count += 3; | ||||
break; | ||||
} | ||||
dst[count++] = 0xe0 | (ucs >> 12); | dst[count++] = 0xe0 | (ucs >> 12); | |||
dst[count++] = 0x80 | ((ucs >> 6) & 0x3F); | dst[count++] = 0x80 | ((ucs >> 6) & 0x3F); | |||
dst[count++] = 0x80 | (ucs & 0x3F); | dst[count++] = 0x80 | (ucs & 0x3F); | |||
} | } | |||
} | } | |||
} | } | |||
/* we filled dst, measure the rest: */ | /* we filled dst, measure the rest: */ | |||
while (i < srclen) { | while(i < srclen) { | |||
unsigned int ucs = src[i++]; | unsigned int ucs = src[i++]; | |||
if (ucs < 0x80U) { | if(ucs < 0x80U) { count++; } | |||
count++; | else if(ucs < 0x800U) { /* 2 bytes */ | |||
} | ||||
else if (ucs < 0x800U) { /* 2 bytes */ | ||||
count += 2; | count += 2; | |||
} | } | |||
else if (ucs >= 0xd800 && ucs <= 0xdbff && i < srclen-1 && | else if(ucs >= 0xd800 && ucs <= 0xdbff && i < srclen - 1 && | |||
src[i+1] >= 0xdc00 && src[i+1] <= 0xdfff) { | src[i + 1] >= 0xdc00 && src[i + 1] <= 0xdfff) { | |||
/* surrogate pair */ | /* surrogate pair */ | |||
++i; | ++i; | |||
count += 4; | count += 4; | |||
} | } | |||
else { | else { | |||
count += 3; | count += 3; | |||
} | } | |||
} | } | |||
return count; | return count; | |||
} | } | |||
static wchar_t *wbuf[2] = {NULL, NULL}; | static wchar_t *wbuf[2] = {NULL, NULL}; | |||
static void setwbuf(int i, const char *f) | static void setwbuf(int i, const char *f) | |||
{ | { | |||
// all strings in GetDP are supposed to be UTF8-encoded, which is natively | // all strings in GetDP are supposed to be UTF8-encoded, which is natively | |||
// supported by Mac and Linux. Windows does not support UTF-8, but UTF-16 | // supported by Mac and Linux. Windows does not support UTF-8, but UTF-16 | |||
// (through wchar_t), so we need to convert. | // (through wchar_t), so we need to convert. | |||
if(i != 0 && i != 1) return; | if(i != 0 && i != 1) return; | |||
size_t l = strlen(f); | size_t l = strlen(f); | |||
unsigned int wn = utf8toUtf16(f, (unsigned int) l, NULL, 0) + 1; | unsigned int wn = utf8toUtf16(f, (unsigned int)l, NULL, 0) + 1; | |||
wbuf[i] = (wchar_t*)realloc(wbuf[i], sizeof(wchar_t)*wn); | wbuf[i] = (wchar_t *)realloc(wbuf[i], sizeof(wchar_t) * wn); | |||
wn = utf8toUtf16(f, (unsigned int) l, (unsigned short *)wbuf[i], wn); | wn = utf8toUtf16(f, (unsigned int)l, (unsigned short *)wbuf[i], wn); | |||
wbuf[i][wn] = 0; | wbuf[i][wn] = 0; | |||
} | } | |||
#endif | #endif | |||
FILE *FOpen(const char *f, const char *mode) | FILE *FOpen(const char *f, const char *mode) | |||
{ | { | |||
#if defined(HAVE_NX) && !defined(__APPLE__) | #if defined(HAVE_NX) && !defined(__APPLE__) | |||
return fopen64(f, mode); | return fopen64(f, mode); | |||
#elif defined (WIN32) && !defined(__CYGWIN__) | #elif defined(WIN32) && !defined(__CYGWIN__) | |||
setwbuf(0, f); | setwbuf(0, f); | |||
setwbuf(1, mode); | setwbuf(1, mode); | |||
return _wfopen(wbuf[0], wbuf[1]); | return _wfopen(wbuf[0], wbuf[1]); | |||
#else | #else | |||
return fopen(f, mode); | return fopen(f, mode); | |||
#endif | #endif | |||
} | } | |||
void GetResources(double *s, long *mem) | void GetResources(double *s, long *mem) | |||
{ | { | |||
#if defined(WIN32) && !defined(__CYGWIN__) | #if defined(WIN32) && !defined(__CYGWIN__) | |||
FILETIME creation, exit, kernel, user; | FILETIME creation, exit, kernel, user; | |||
if(GetProcessTimes(GetCurrentProcess(), &creation, &exit, &kernel, &user)){ | if(GetProcessTimes(GetCurrentProcess(), &creation, &exit, &kernel, &user)) { | |||
*s = 1.e-7 * 4294967296. * (double)user.dwHighDateTime + | *s = 1.e-7 * 4294967296. * (double)user.dwHighDateTime + | |||
1.e-7 * (double)user.dwLowDateTime; | 1.e-7 * (double)user.dwLowDateTime; | |||
} | } | |||
PROCESS_MEMORY_COUNTERS info; | PROCESS_MEMORY_COUNTERS info; | |||
GetProcessMemoryInfo(GetCurrentProcess(), &info, sizeof(info)); | GetProcessMemoryInfo(GetCurrentProcess(), &info, sizeof(info)); | |||
*mem = (long)info.PeakWorkingSetSize; | *mem = (long)info.PeakWorkingSetSize; | |||
#else | #else | |||
static struct rusage r; | static struct rusage r; | |||
getrusage(RUSAGE_SELF, &r); | getrusage(RUSAGE_SELF, &r); | |||
*s = (double)r.ru_utime.tv_sec + 1.e-6 * (double)r.ru_utime.tv_usec; | *s = (double)r.ru_utime.tv_sec + 1.e-6 * (double)r.ru_utime.tv_usec; | |||
skipping to change at line 263 | skipping to change at line 293 | |||
#endif | #endif | |||
} | } | |||
double GetTotalRam() | double GetTotalRam() | |||
{ | { | |||
double ram = 0; | double ram = 0; | |||
#if defined(__APPLE__) | #if defined(__APPLE__) | |||
int name[] = {CTL_HW, HW_MEMSIZE}; | int name[] = {CTL_HW, HW_MEMSIZE}; | |||
int64_t value; | int64_t value; | |||
size_t len = sizeof(value); | size_t len = sizeof(value); | |||
if(sysctl(name, 2, &value, &len, NULL, 0) != -1) | if(sysctl(name, 2, &value, &len, NULL, 0) != -1) ram = value / (1024 * 1024); | |||
ram = value / (1024 * 1024); | #elif defined(WIN32) | |||
#elif defined (WIN32) | ||||
MEMORYSTATUSEX status; | MEMORYSTATUSEX status; | |||
status.dwLength = sizeof(status); | status.dwLength = sizeof(status); | |||
GlobalMemoryStatusEx(&status); | GlobalMemoryStatusEx(&status); | |||
ram = status.ullTotalPhys / ((double)1024 * 1024); | ram = status.ullTotalPhys / ((double)1024 * 1024); | |||
#elif defined(BUILD_ANDROID) | #elif defined(BUILD_ANDROID) | |||
ram = 1024; | ram = 1024; | |||
#elif defined(__linux__) | #elif defined(__linux__) | |||
struct sysinfo infos; | struct sysinfo infos; | |||
if(sysinfo(&infos) != -1) | if(sysinfo(&infos) != -1) | |||
ram = infos.totalram * (unsigned long)infos.mem_unit / ((double)1024 * 1024) | ram = | |||
; | infos.totalram * (unsigned long)infos.mem_unit / ((double)1024 * 1024); | |||
#endif | #endif | |||
return ram; | return ram; | |||
} | } | |||
double GetTimeOfDay() | double GetTimeOfDay() | |||
{ | { | |||
#if defined(WIN32) && !defined(__CYGWIN__) | #if defined(WIN32) && !defined(__CYGWIN__) | |||
struct _timeb localTime; | struct _timeb localTime; | |||
_ftime(&localTime); | _ftime(&localTime); | |||
return localTime.time + 1.e-3 * localTime.millitm; | return localTime.time + 1.e-3 * localTime.millitm; | |||
#else | #else | |||
struct timeval t; | struct timeval t; | |||
gettimeofday(&t, NULL); | gettimeofday(&t, NULL); | |||
return t.tv_sec + 1.e-6 * t.tv_usec; | return t.tv_sec + 1.e-6 * t.tv_usec; | |||
#endif | #endif | |||
} | } | |||
void IncreaseStackSize() | void IncreaseStackSize() | |||
{ | { | |||
#if !defined (WIN32) || defined(__CYGWIN__) | #if !defined(WIN32) || defined(__CYGWIN__) | |||
static struct rlimit r; | static struct rlimit r; | |||
getrlimit(RLIMIT_STACK, &r); | getrlimit(RLIMIT_STACK, &r); | |||
// Try to get at least 16 MB of stack. Running with too small a stack | // Try to get at least 16 MB of stack. Running with too small a stack | |||
// can cause crashes in the recursive calls (cf. Cal_Quantity) | // can cause crashes in the recursive calls (cf. Cal_Quantity) | |||
if(r.rlim_cur < 16 * 1024 * 1024){ | if(r.rlim_cur < 16 * 1024 * 1024) { | |||
Message::Info("Increasing process stack size (%d kB < 16 MB)", r.rlim_cur / | Message::Info("Increasing process stack size (%d kB < 16 MB)", | |||
1024); | r.rlim_cur / 1024); | |||
r.rlim_cur = r.rlim_max; | r.rlim_cur = r.rlim_max; | |||
setrlimit(RLIMIT_STACK, &r); | setrlimit(RLIMIT_STACK, &r); | |||
} | } | |||
#endif | #endif | |||
} | } | |||
void SleepSeconds(double s) | void SleepSeconds(double s) | |||
{ | { | |||
#if defined(WIN32) && !defined(__CYGWIN__) | #if defined(WIN32) && !defined(__CYGWIN__) | |||
Sleep((long)(1.e3 * s)); | Sleep((long)(1.e3 * s)); | |||
skipping to change at line 327 | skipping to change at line 358 | |||
} | } | |||
int BlockingSystemCall(const char *command) | int BlockingSystemCall(const char *command) | |||
{ | { | |||
#if defined(WIN32) | #if defined(WIN32) | |||
STARTUPINFO suInfo; | STARTUPINFO suInfo; | |||
PROCESS_INFORMATION prInfo; | PROCESS_INFORMATION prInfo; | |||
memset(&suInfo, 0, sizeof(suInfo)); | memset(&suInfo, 0, sizeof(suInfo)); | |||
suInfo.cb = sizeof(suInfo); | suInfo.cb = sizeof(suInfo); | |||
Message::Info("Calling '%s'", command); | Message::Info("Calling '%s'", command); | |||
CreateProcess(NULL, (char*)command, NULL, NULL, FALSE, | CreateProcess(NULL, (char *)command, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, | |||
NORMAL_PRIORITY_CLASS, NULL, NULL, &suInfo, &prInfo); | NULL, NULL, &suInfo, &prInfo); | |||
// wait until child process exits. | // wait until child process exits. | |||
WaitForSingleObject(prInfo.hProcess, INFINITE); | WaitForSingleObject(prInfo.hProcess, INFINITE); | |||
// close process and thread handles. | // close process and thread handles. | |||
CloseHandle(prInfo.hProcess); | CloseHandle(prInfo.hProcess); | |||
CloseHandle(prInfo.hThread); | CloseHandle(prInfo.hThread); | |||
return 0; | return 0; | |||
#elif(BUILD_IOS) | #elif(BUILD_IOS) | |||
Message::Warning("SystemCall is not supported on iOS"); | Message::Warning("SystemCall is not supported on iOS"); | |||
#else | #else | |||
if(!system(NULL)) { | if(!system(NULL)) { | |||
skipping to change at line 407 | skipping to change at line 438 | |||
do { | do { | |||
cur = dirName.find("/", cur + 1); | cur = dirName.find("/", cur + 1); | |||
if(!CreateDir(dirName.substr(0, cur))) ret = 0; | if(!CreateDir(dirName.substr(0, cur))) ret = 0; | |||
} while(cur != std::string::npos); | } while(cur != std::string::npos); | |||
return ret; | return ret; | |||
} | } | |||
static std::vector<std::string> splitFileName(const std::string &fileName) | static std::vector<std::string> splitFileName(const std::string &fileName) | |||
{ | { | |||
std::vector<std::string> s; s.resize(3); | std::vector<std::string> s; | |||
if(fileName.size()){ | s.resize(3); | |||
if(fileName.size()) { | ||||
// returns [path, baseName, extension] | // returns [path, baseName, extension] | |||
int idot = (int)fileName.find_last_of('.'); | int idot = (int)fileName.find_last_of('.'); | |||
int islash = (int)fileName.find_last_of("/\\"); | int islash = (int)fileName.find_last_of("/\\"); | |||
if(idot == (int)std::string::npos) idot = -1; | if(idot == (int)std::string::npos) idot = -1; | |||
if(islash == (int)std::string::npos) islash = -1; | if(islash == (int)std::string::npos) islash = -1; | |||
if(idot > 0) | if(idot > 0) s[2] = fileName.substr(idot); | |||
s[2] = fileName.substr(idot); | if(islash > 0) s[0] = fileName.substr(0, islash + 1); | |||
if(islash > 0) | s[1] = | |||
s[0] = fileName.substr(0, islash + 1); | fileName.substr(s[0].size(), fileName.size() - s[0].size() - s[2].size()); | |||
s[1] = fileName.substr(s[0].size(), fileName.size() - s[0].size() - s[2].siz | ||||
e()); | ||||
} | } | |||
return s; | return s; | |||
} | } | |||
std::string GetDirName(const std::string &fileName) | std::string GetDirName(const std::string &fileName) | |||
{ | { | |||
return splitFileName(fileName)[0]; | return splitFileName(fileName)[0]; | |||
} | } | |||
std::string GetBaseName(const std::string &fileName) | std::string GetBaseName(const std::string &fileName) | |||
{ | { | |||
return splitFileName(fileName)[1]; | return splitFileName(fileName)[1]; | |||
} | } | |||
std::string GetFullPath(const std::string &fileName) | std::string GetFullPath(const std::string &fileName) | |||
{ | { | |||
#if defined(WIN32) && !defined(__CYGWIN__) | #if defined(WIN32) && !defined(__CYGWIN__) | |||
setwbuf(0, fileName.c_str()); | setwbuf(0, fileName.c_str()); | |||
wchar_t path[MAX_PATH]; | wchar_t path[MAX_PATH]; | |||
unsigned long size = GetFullPathNameW(wbuf[0], MAX_PATH, path, NULL); | unsigned long size = GetFullPathNameW(wbuf[0], MAX_PATH, path, NULL); | |||
if(size){ | if(size) { | |||
char dst[MAX_PATH]; | char dst[MAX_PATH]; | |||
utf8FromUtf16(dst, MAX_PATH, path, size); | utf8FromUtf16(dst, MAX_PATH, path, size); | |||
return std::string(dst); | return std::string(dst); | |||
} | } | |||
#else | #else | |||
char path[4096]; | char path[4096]; | |||
if(realpath(fileName.c_str(), path)) | if(realpath(fileName.c_str(), path)) return path; | |||
return path; | ||||
#endif | #endif | |||
return fileName; | return fileName; | |||
} | } | |||
End of changes. 45 change blocks. | ||||
115 lines changed or deleted | 141 lines changed or added |