1 /// Case insensitive path functions 2 module nwnlibd.path; 3 4 import std.exception; 5 6 /// 7 string buildPathCI(T...)(in string basePath, T subFiles){ 8 import std.file; 9 import std.path; 10 import std.string: toUpper; 11 12 enforce(basePath.exists, "basePath '"~basePath~"' does not exist"); 13 string path = basePath; 14 15 foreach(subFile ; subFiles){ 16 //Case is correct, cool ! 17 if(buildPath(path, subFile).exists){ 18 path = buildPath(path, subFile); 19 } 20 //Most likely only the extension is fucked up 21 else if(buildPath(path, subFile.stripExtension ~ subFile.extension.toUpper).exists){ 22 path = buildPath(path, subFile.stripExtension ~ subFile.extension.toUpper); 23 } 24 //Perform full scan of the directory 25 else{ 26 bool bFound = false; 27 foreach(file ; path.dirEntries(SpanMode.shallow)){ 28 if(filenameCmp!(CaseSensitive.no)(file.baseName, subFile) == 0){ 29 bFound = true; 30 path = file.name; 31 break; 32 } 33 } 34 if(!bFound) 35 path = buildPath(path, subFile); 36 } 37 } 38 return path; 39 } 40 41 /// 42 unittest{ 43 version(Posix){ 44 // First directory must exist and case must be correct 45 assertThrown(buildPathCI("UNITTEST", "PLC_MC_BALCONY3.MDB")); 46 47 // Fix case in file paths 48 assert(buildPathCI(".", "unittest", "PLC_MC_BALCONY3.MDB") == "./unittest/PLC_MC_BALCONY3.MDB"); 49 assert(buildPathCI(".", "UNITTEST", "PLC_MC_BALCONY3.mdb") == "./unittest/PLC_MC_BALCONY3.MDB"); 50 assert(buildPathCI(".", "unittest", "plc_mc_balcony3.mdb") == "./unittest/PLC_MC_BALCONY3.MDB"); 51 assert(buildPathCI(".", "UNITTEST", "pLc_mc_balConY3.mdB") == "./unittest/PLC_MC_BALCONY3.MDB"); 52 53 // Non existing files keep the provided case 54 assert(buildPathCI(".", "Unittest", "YoLo.pNg") == "./unittest/YoLo.pNg"); 55 } 56 } 57