diff options
Diffstat (limited to '')
-rw-r--r-- | src/skel/crossplatform.cpp | 130 |
1 files changed, 125 insertions, 5 deletions
diff --git a/src/skel/crossplatform.cpp b/src/skel/crossplatform.cpp index f9464bb6..40f4f053 100644 --- a/src/skel/crossplatform.cpp +++ b/src/skel/crossplatform.cpp @@ -1,7 +1,9 @@ #include "common.h" -#define USEALTERNATIVEWINFUNCS #include "crossplatform.h" +// Codes compatible with Windows and Linux +#ifndef _WIN32 + // For internal use // wMilliseconds is not needed void tmToSystemTime(const tm *tm, SYSTEMTIME *out) { @@ -19,8 +21,10 @@ void GetLocalTime_CP(SYSTEMTIME *out) { tm *localTm = localtime(×tamp); tmToSystemTime(localTm, out); } +#endif -#if !defined _WIN32 || defined __MINGW32__ +// Compatible with Linux/POSIX and MinGW on Windows +#ifndef _WIN32 HANDLE FindFirstFile(const char* pathname, WIN32_FIND_DATA* firstfile) { char newpathname[32]; strncpy(newpathname, pathname, 32); @@ -34,7 +38,7 @@ HANDLE FindFirstFile(const char* pathname, WIN32_FIND_DATA* firstfile) { strncpy(firstfile->extension, "", sizeof(firstfile->extension)); HANDLE d; - if ((d = opendir(path)) == NULL || !FindNextFile(d, firstfile)) + if ((d = (HANDLE)opendir(path)) == NULL || !FindNextFile(d, firstfile)) return NULL; return d; @@ -45,7 +49,7 @@ bool FindNextFile(HANDLE d, WIN32_FIND_DATA* finddata) { static struct stat fileStats; static char path[PATH_MAX], relativepath[NAME_MAX + sizeof(finddata->folder) + 1]; int extensionLen = strlen(finddata->extension); - while ((file = readdir(d)) != NULL) { + while ((file = readdir((DIR*)d)) != NULL) { // We only want "DT_REG"ular Files, but reportedly some FS and OSes gives DT_UNKNOWN as type. if ((file->d_type == DT_UNKNOWN || file->d_type == DT_REG) && @@ -78,4 +82,120 @@ void FileTimeToSystemTime(time_t* writeTime, SYSTEMTIME* out) { tm *ptm = gmtime(writeTime); tmToSystemTime(ptm, out); } -#endif
\ No newline at end of file +#endif + +// Funcs/features from Windows that we need on other platforms +#ifndef _WIN32 +char *strupr(char *s) { + char* tmp = s; + + for (;*tmp;++tmp) { + *tmp = toupper((unsigned char) *tmp); + } + + return s; +} +char *strlwr(char *s) { + char* tmp = s; + + for (;*tmp;++tmp) { + *tmp = tolower((unsigned char) *tmp); + } + + return s; +} + +char *trim(char *s) { + char *ptr; + if (!s) + return NULL; // handle NULL string + if (!*s) + return s; // handle empty string + for (ptr = s + strlen(s) - 1; (ptr >= s) && isspace(*ptr); --ptr); + ptr[1] = '\0'; + return s; +} + +// Case-insensitivity on linux (from https://github.com/OneSadCookie/fcaseopen) +// r must have strlen(path) + 2 bytes +int casepath(char const *path, char *r) +{ + size_t l = strlen(path); + char *p = (char*)alloca(l + 1); + strcpy(p, path); + + // my addon: change \'s with / + char *nextBs; + while(nextBs = strstr(p, "\\")){ + *nextBs = '/'; + } + + // my addon: linux doesn't handle filenames with spaces at the end nicely + p = trim(p); + + size_t rl = 0; + + DIR *d; + if (p[0] == '/') + { + d = opendir("/"); + p = p + 1; + } + else + { + d = opendir("."); + r[0] = '.'; + r[1] = 0; + rl = 1; + } + + int last = 0; + char *c = strsep(&p, "/"); + while (c) + { + if (!d) + { + return 0; + } + + if (last) + { + closedir(d); + return 0; + } + + r[rl] = '/'; + rl += 1; + r[rl] = 0; + + struct dirent *e = readdir(d); + while (e) + { + if (strcasecmp(c, e->d_name) == 0) + { + strcpy(r + rl, e->d_name); + rl += strlen(e->d_name); + + closedir(d); + d = opendir(r); + + break; + } + + e = readdir(d); + } + + if (!e) + { + strcpy(r + rl, c); + rl += strlen(c); + last = 1; + } + + c = strsep(&p, "/"); + } + + if (d) closedir(d); + return 1; +} +#endif |