From 3fdd7f50ea238f6a62952ecea18c625a58f893ef Mon Sep 17 00:00:00 2001 From: i30817 Date: Sun, 25 Mar 2018 18:53:18 +0100 Subject: [PATCH 1/4] fix gdi track parsing in unixx Same problem as https://github.com/libretro/reicast-emulator/pull/24 in unix that iteration would not work if the path of the original .gdi file (where we are finding the 'parent directory') was: 1. not existent, ie a gdi on the same directory as the current. It was iterating until the index 3 and stop there. Disaster strikes later ofc, if the first characters weren't C:\ or other thing like that. 2. in a relative subdirectory that is 'small enough' ie: a/crazy-taxi.gdi. In this case the last '/' wouldn't be found, the derived string would be 'crazy-taxi.gdi' and the file not found ofc. Anyway, this can be solved simply by searching the whole string and using a signed integer. It will go up to -1, stop iteration and increase to 0 on the len++. Dunno if using relative subdirectories for the tracks on *other* platforms works because of the path separator being different from what's inside the gdi but with this code fixed it works on linux with / at least. --- core/imgread/gdi.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/imgread/gdi.cpp b/core/imgread/gdi.cpp index 5eaf87859..e1f650e93 100644 --- a/core/imgread/gdi.cpp +++ b/core/imgread/gdi.cpp @@ -36,9 +36,9 @@ Disc* load_gdi(const char* file) strncpy(path, file, sizeof(path)); path[sizeof(path) - 1] = '\0'; - size_t len = strlen(path); + ssize_t len = strlen(path); - while (len>2) + while (len>=0) { if (path[len]=='\\' || path[len]=='/') break; @@ -118,4 +118,4 @@ Disc* gdi_parse(const char* file) void iso_term() { -} \ No newline at end of file +} From 052c5c1cb352016a31334e3e137eef250bc32d65 Mon Sep 17 00:00:00 2001 From: TwistedUmbrella Date: Mon, 2 Apr 2018 02:46:46 -0400 Subject: [PATCH 2/4] Fix for Windows missing definition of ssize_t --- core/imgread/gdi.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/core/imgread/gdi.cpp b/core/imgread/gdi.cpp index e1f650e93..f975e86f8 100644 --- a/core/imgread/gdi.cpp +++ b/core/imgread/gdi.cpp @@ -1,6 +1,10 @@ #include "common.h" #include #include +#ifdef WIN32 +#include +typedef SSIZE_T ssize_t; +#endif Disc* load_gdi(const char* file) { From 4300951b5101d20a846908ec7442c15a3c9d629e Mon Sep 17 00:00:00 2001 From: Stefanos Kornilios Mitsis Poiitidis Date: Wed, 11 Apr 2018 11:40:15 +0200 Subject: [PATCH 3/4] gdi: Cleanup path code, use C++ strings --- core/imgread/gdi.cpp | 57 +++++++++++++++++++++++++++++--------------- 1 file changed, 38 insertions(+), 19 deletions(-) diff --git a/core/imgread/gdi.cpp b/core/imgread/gdi.cpp index f975e86f8..3ab1d6ad5 100644 --- a/core/imgread/gdi.cpp +++ b/core/imgread/gdi.cpp @@ -1,9 +1,40 @@ #include "common.h" #include #include -#ifdef WIN32 -#include -typedef SSIZE_T ssize_t; + +// given file/name.ext or file\name.ext returns file/ or file\, depending on the platform +// given name.ext returns ./ or .\, depending on the platform +string OS_dirname(string file) +{ + #if HOST_OS == OS_WINDOWS + const char sep = '\\'; + #else + const char sep = '/'; + #endif + + size_t last_slash = file.find_last_of(sep); + + if (last_slash == string::npos) + { + string local_dir = "."; + local_dir += sep; + return local_dir; + } + + return file.substr(0, last_slash + 1); +} + +#if 0 // TODO: Move this to some tests, make it platform agnostic +namespace { + struct OS_dirname_Test { + OS_dirname_Test() { + verify(OS_dirname("local/path") == "local/"); + verify(OS_dirname("local/path/two") == "local/path/"); + verify(OS_dirname("local/path/three\\a.exe") == "local/path/"); + verify(OS_dirname("local.ext") == "./"); + } + } test; +} #endif Disc* load_gdi(const char* file) @@ -35,21 +66,9 @@ Disc* load_gdi(const char* file) gdi >> iso_tc; printf("\nGDI : %d tracks\n",iso_tc); - // FIXME: Data loss if buffer is too small - char path[512]; - strncpy(path, file, sizeof(path)); - path[sizeof(path) - 1] = '\0'; + + string basepath = OS_dirname(file); - ssize_t len = strlen(path); - - while (len>=0) - { - if (path[len]=='\\' || path[len]=='/') - break; - len--; - } - len++; - char* pathptr=&path[len]; u32 TRACK=0,FADS=0,CTRL=0,SSIZE=0; s32 OFFSET=0; for (u32 i=0;itracks.push_back(t); } From 90e901f4a3106517d857ba5ff90afca593511f99 Mon Sep 17 00:00:00 2001 From: Stefanos Kornilios Mitsis Poiitidis Date: Wed, 18 Apr 2018 22:28:05 +0200 Subject: [PATCH 4/4] gdi: Normalize paths, add test gdi files --- core/imgread/gdi.cpp | 28 +++++++++++++++++++++++-- tests/files/test_gdis/a/cs.gdi | 4 ++++ tests/files/test_gdis/a/tracks/cs01.bin | 0 tests/files/test_gdis/a/tracks/cs02.raw | 0 tests/files/test_gdis/a/tracks/cs03.bin | 0 tests/files/test_gdis/b/cs.gdi | 4 ++++ tests/files/test_gdis/b/cs01.bin | 0 tests/files/test_gdis/b/cs02.raw | 0 tests/files/test_gdis/b/cs03.bin | 0 tests/files/test_gdis/c/cs.gdi | 4 ++++ tests/files/test_gdis/c/tracks/cs01.bin | 0 tests/files/test_gdis/c/tracks/cs02.raw | 0 tests/files/test_gdis/c/tracks/cs03.bin | 0 13 files changed, 38 insertions(+), 2 deletions(-) create mode 100644 tests/files/test_gdis/a/cs.gdi create mode 100644 tests/files/test_gdis/a/tracks/cs01.bin create mode 100644 tests/files/test_gdis/a/tracks/cs02.raw create mode 100644 tests/files/test_gdis/a/tracks/cs03.bin create mode 100644 tests/files/test_gdis/b/cs.gdi create mode 100644 tests/files/test_gdis/b/cs01.bin create mode 100644 tests/files/test_gdis/b/cs02.raw create mode 100644 tests/files/test_gdis/b/cs03.bin create mode 100644 tests/files/test_gdis/c/cs.gdi create mode 100644 tests/files/test_gdis/c/tracks/cs01.bin create mode 100644 tests/files/test_gdis/c/tracks/cs02.raw create mode 100644 tests/files/test_gdis/c/tracks/cs03.bin diff --git a/core/imgread/gdi.cpp b/core/imgread/gdi.cpp index 3ab1d6ad5..4c19a1310 100644 --- a/core/imgread/gdi.cpp +++ b/core/imgread/gdi.cpp @@ -1,6 +1,7 @@ #include "common.h" #include #include +#include // given file/name.ext or file\name.ext returns file/ or file\, depending on the platform // given name.ext returns ./ or .\, depending on the platform @@ -24,6 +25,19 @@ string OS_dirname(string file) return file.substr(0, last_slash + 1); } +// On windows, transform / to \\ +// On linux, transform \\ to / +string normalize_path_separator(string path) +{ + #if HOST_OS == OS_WINDOWS + std::replace( path.begin(), path.end(), '/', '\\'); + #else + std::replace( path.begin(), path.end(), '\\', '/'); + #endif + + return path; +} + #if 0 // TODO: Move this to some tests, make it platform agnostic namespace { struct OS_dirname_Test { @@ -33,7 +47,17 @@ namespace { verify(OS_dirname("local/path/three\\a.exe") == "local/path/"); verify(OS_dirname("local.ext") == "./"); } - } test; + } test1; + + struct normalize_path_separator_Test { + normalize_path_separator_Test() { + verify(normalize_path_separator("local/path") == "local/path"); + verify(normalize_path_separator("local\\path") == "local/path"); + verify(normalize_path_separator("local\\path\\") == "local/path/"); + verify(normalize_path_separator("\\local\\path\\") == "/local/path/"); + verify(normalize_path_separator("loc\\al\\pa\\th") == "loc/al/pa/th"); + } + } test2; } #endif @@ -114,7 +138,7 @@ Disc* load_gdi(const char* file) if (SSIZE!=0) { - string path = basepath + track_filename; + string path = basepath + normalize_path_separator(track_filename); t.file = new RawTrackFile(core_fopen(path.c_str()),OFFSET,t.StartFAD,SSIZE); } disc->tracks.push_back(t); diff --git a/tests/files/test_gdis/a/cs.gdi b/tests/files/test_gdis/a/cs.gdi new file mode 100644 index 000000000..faca45760 --- /dev/null +++ b/tests/files/test_gdis/a/cs.gdi @@ -0,0 +1,4 @@ +3 +1 0 4 2352 tracks\cs01.bin 0 +2 450 0 2352 tracks\cs02.raw 0 +3 45000 4 2352 tracks\cs03.bin 0 diff --git a/tests/files/test_gdis/a/tracks/cs01.bin b/tests/files/test_gdis/a/tracks/cs01.bin new file mode 100644 index 000000000..e69de29bb diff --git a/tests/files/test_gdis/a/tracks/cs02.raw b/tests/files/test_gdis/a/tracks/cs02.raw new file mode 100644 index 000000000..e69de29bb diff --git a/tests/files/test_gdis/a/tracks/cs03.bin b/tests/files/test_gdis/a/tracks/cs03.bin new file mode 100644 index 000000000..e69de29bb diff --git a/tests/files/test_gdis/b/cs.gdi b/tests/files/test_gdis/b/cs.gdi new file mode 100644 index 000000000..5562ee8c8 --- /dev/null +++ b/tests/files/test_gdis/b/cs.gdi @@ -0,0 +1,4 @@ +3 +1 0 4 2352 cs01.bin 0 +2 450 0 2352 cs02.raw 0 +3 45000 4 2352 cs03.bin 0 diff --git a/tests/files/test_gdis/b/cs01.bin b/tests/files/test_gdis/b/cs01.bin new file mode 100644 index 000000000..e69de29bb diff --git a/tests/files/test_gdis/b/cs02.raw b/tests/files/test_gdis/b/cs02.raw new file mode 100644 index 000000000..e69de29bb diff --git a/tests/files/test_gdis/b/cs03.bin b/tests/files/test_gdis/b/cs03.bin new file mode 100644 index 000000000..e69de29bb diff --git a/tests/files/test_gdis/c/cs.gdi b/tests/files/test_gdis/c/cs.gdi new file mode 100644 index 000000000..73563f35e --- /dev/null +++ b/tests/files/test_gdis/c/cs.gdi @@ -0,0 +1,4 @@ +3 +1 0 4 2352 tracks/cs01.bin 0 +2 450 0 2352 tracks/cs02.raw 0 +3 45000 4 2352 tracks/cs03.bin 0 diff --git a/tests/files/test_gdis/c/tracks/cs01.bin b/tests/files/test_gdis/c/tracks/cs01.bin new file mode 100644 index 000000000..e69de29bb diff --git a/tests/files/test_gdis/c/tracks/cs02.raw b/tests/files/test_gdis/c/tracks/cs02.raw new file mode 100644 index 000000000..e69de29bb diff --git a/tests/files/test_gdis/c/tracks/cs03.bin b/tests/files/test_gdis/c/tracks/cs03.bin new file mode 100644 index 000000000..e69de29bb