summaryrefslogtreecommitdiffstats
path: root/src/skel/crossplatform.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/skel/crossplatform.cpp130
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(&timestamp);
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