diff --git a/src/tools/streamheaderpack.cpp b/src/tools/streamheaderpack.cpp index a63b1bc2..6a1a1337 100644 --- a/src/tools/streamheaderpack.cpp +++ b/src/tools/streamheaderpack.cpp @@ -4,6 +4,9 @@ #include #include +#include +#include + struct WavHeader { // RIFF Header char riff[4]; // RIFF Header Magic header @@ -29,6 +32,140 @@ struct WavHeader { #define DCStreamedNameTable DCStreamedNameTable_miami #include "../miami/audio/sampman_dc_streams.h" #undef DCStreamedNameTable + +// Case-insensitivity on linux (from https://github.com/OneSadCookie/fcaseopen) +// Returned string should freed manually (if exists) +char* casepath(char const* path, bool checkPathFirst = true) +{ + //TODO: Implement this + bool access_ok = false; //access(path, F_OK) != -1 + // printf("TODO: FIXME %s\n", __func__); + + if (checkPathFirst && access_ok ) { + // File path is correct + return nullptr; + } + + size_t l = strlen(path); + if (l > 2 && path[0] == '.' && (path[1] == '/' || path[1] == '\\')) { + // remove ./ from the start of the path + path += 2; + } + char* p = (char*)alloca(l + 1); + char* out = (char*)malloc(l + 3); // for extra ./ + strcpy(p, path); + + size_t rl = 0; + + DIR* d; + char* c; + + #if defined(__SWITCH__) || defined(PSP2) + if( (c = strstr(p, ":/")) != NULL) // scheme used by some environments, eg. switch, vita + { + size_t deviceNameOffset = c - p + 3; + char* deviceNamePath = (char*)alloca(deviceNameOffset + 1); + strlcpy(deviceNamePath, p, deviceNameOffset); + deviceNamePath[deviceNameOffset] = 0; + d = opendir(deviceNamePath); + p = c + 1; + } + else + #endif + if (p[0] == '/' || p[0] == '\\') + { + d = opendir("/"); + } + else + { + d = opendir("."); + out[0] = '.'; + out[1] = 0; + rl = 1; + } + + bool cantProceed = false; // just convert slashes in what's left in string, don't correct case of letters(because we can't) + bool mayBeTrailingSlash = false; + + while (c = strsep(&p, "/\\")) + { + // May be trailing slash(allow), slash at the start(avoid), or multiple slashes(avoid) + if (*c == '\0') + { + mayBeTrailingSlash = true; + continue; + } else { + mayBeTrailingSlash = false; + } + + out[rl] = '/'; + rl += 1; + out[rl] = 0; + + if (cantProceed) + { + strcpy(out + rl, c); + rl += strlen(c); + continue; + } + + struct dirent* e; + while (e = readdir(d)) + { + if (strcasecmp(c, e->d_name) == 0) + { + strcpy(out + rl, e->d_name); + int reportedLen = (int)strlen(e->d_name); + rl += reportedLen; + assert(reportedLen == strlen(c) && "casepath: This is not good at all"); + + closedir(d); + d = opendir(out); + + // Either it wasn't a folder, or permission error, I/O error etc. + if (!d) { + cantProceed = true; + } + + break; + } + } + + if (!e) + { + printf("casepath couldn't find dir/file \"%s\", full path was %s\n", c, path); + // No match, add original name and continue converting further slashes. + strcpy(out + rl, c); + rl += strlen(c); + cantProceed = true; + } + } + + if (d) closedir(d); + if (mayBeTrailingSlash) { + out[rl] = '/'; rl += 1; + out[rl] = '\0'; + } + + if (rl > l + 2) { + printf("\n\ncasepath: Corrected path length is longer then original+2:\n\tOriginal: %s (%zu chars)\n\tCorrected: %s (%zu chars)\n\n", path, l, out, rl); + } + return out; +} + +FILE* fcaseopen(char const* filename, char const* mode) +{ + FILE* result; + char* real = casepath(filename); + if (!real) + result = fopen(filename, mode); + else { + result = fopen(real, mode); + free(real); + } + return result; +} + int main(int argc, const char** argv) { size_t table_len = 0; @@ -50,7 +187,7 @@ int main(int argc, const char** argv) { return 1; } - FILE* fout=fopen(argv[3], "wb"); + FILE* fout=fcaseopen(argv[3], "wb"); if (!fout) { std::cerr << "Failed to open " << argv[3] << " for writing" << std::endl; return 1; @@ -59,7 +196,7 @@ int main(int argc, const char** argv) { for (int i = 0; i < table_len; i++) { std::string filename = std::string(argv[2]) + "/" + table[i]; - FILE* f = fopen(filename.c_str(), "rb"); + FILE* f = fcaseopen(filename.c_str(), "rb"); if (!f) { std::cerr << "Failed to open " << filename << std::endl; fclose(fout);