Skip to content

Instantly share code, notes, and snippets.

@jpcima
Created January 26, 2020 14:05
Show Gist options
  • Save jpcima/a871c04c956c5ec15d7bf28ee30938aa to your computer and use it in GitHub Desktop.
Save jpcima/a871c04c956c5ec15d7bf28ee30938aa to your computer and use it in GitHub Desktop.
/*
clang++ -O2 -g -Isrc/external -Iexternal/abseil-cpp -Isrc/sfizz -o FixPathCase \
FixPathCase.cpp \
external/abseil-cpp/absl/strings/ascii.cc \
external/abseil-cpp/absl/strings/match.cc \
external/abseil-cpp/absl/strings/internal/memutil.cc \
external/abseil-cpp/absl/base/internal/throw_delegate.cc
*/
#include <iostream>
#include "ghc/fs_std.hpp"
#include "absl/strings/match.h"
#include "Debug.h"
/**
Resolve a path without case-sensitivity
@return true if path was incorrect and a fix was applied, otherwise false
*/
bool FixPathCase(fs::path &path)
{
#ifdef _WIN32
return false;
#else
std::error_code ec;
if (fs::exists(path, ec))
return false;
fs::path oldPath = std::move(path);
path = oldPath.root_path();
static const fs::path dot{"."};
static const fs::path dotdot{".."};
for (const fs::path &part : oldPath.relative_path()) {
if (part == dot || part == dotdot) {
path /= part;
continue;
}
if (fs::exists(path / part, ec)) {
path /= part;
continue;
}
fs::directory_iterator it;
if (path.empty())
it = fs::directory_iterator{dot, ec};
else
it = fs::directory_iterator{path, ec};
auto searchPredicate = [&part](const fs::directory_entry &ent) -> bool {
return absl::EqualsIgnoreCase(
ent.path().filename().native(), part.native());
};
while (it != fs::directory_iterator{} && !searchPredicate(*it))
it.increment(ec);
if (it == fs::directory_iterator{}) {
DBG("[sfizz] File not found, could not resolve " << oldPath);
path = std::move(oldPath);
return false;
}
path /= it->path().filename();
}
return true;
#endif
}
#include <iostream>
int main(int argc, char *argv[])
{
if (argc != 2) {
std::cerr << "Please indicate the test path.\n";
return 1;
}
fs::path path{argv[1]};
if (FixPathCase(path)) {
std::cerr << "The path was resolved as " << path << ".\n";
}
else {
std::cerr << "The path was kept.\n";
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment