Skip to content

Commit b0b54b1

Browse files
grasci-armedriouk
andauthored
FsUtils::Equivalent() method to compare files (#1370) (#2297)
Co-authored-by: Evgueni Driouk <[email protected]>
1 parent e7b5d81 commit b0b54b1

File tree

6 files changed

+92
-11
lines changed

6 files changed

+92
-11
lines changed

libs/rtefsutils/include/RteFsUtils.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,15 @@ class RteFsUtils
223223
*/
224224
static std::string ParentPath(const std::string& path);
225225

226+
/**
227+
* @brief checks if two paths are equivalent
228+
* @param p1 first path to be compared
229+
* @param p2 second path to be compared
230+
* @return true if p1 == p2 or both refer to the same file or both are empty
231+
*/
232+
static bool Equivalent(const std::string& p1, const std::string& p2);
233+
234+
226235
/**
227236
* @brief get lexically normalized path
228237
* @param path path to be processed

libs/rtefsutils/src/RteFsUtils.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -558,6 +558,25 @@ string RteFsUtils::ParentPath(const string& path) {
558558
return fs::path(path).parent_path().generic_string();
559559
}
560560

561+
bool RteFsUtils::Equivalent(const std::string& p1, const std::string& p2) {
562+
if(p1 == p2) {
563+
return true;
564+
}
565+
566+
if(p1.empty() || p2.empty()) {
567+
return false;
568+
}
569+
error_code _ec;
570+
if(fs::equivalent(p1, p2, _ec)) {
571+
return true;
572+
}
573+
if(MakePathCanonical(p1) == MakePathCanonical(p2)) {
574+
return true;
575+
}
576+
return false;
577+
}
578+
579+
561580
string RteFsUtils::LexicallyNormal(const string& path) {
562581
string lexicallyNormal = fs::path(path).lexically_normal().generic_string();
563582
if ((lexicallyNormal.length() > 1) && (lexicallyNormal.back() == '/')) {

libs/rtefsutils/test/src/RteFsUtilsTest.cpp

Lines changed: 58 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,12 @@ const string filenameBackup0 = RteUtils::SlashesToOsSlashes(filenameRegular + ".
4747
const string filenameBackup1 = RteUtils::SlashesToOsSlashes(filenameRegular + ".0001");
4848
const string pathInvalid = dirnameSubdir + "/Invalid";
4949

50-
// For Canonical Tests
50+
// For Canonical and Equivalent tests
5151
const string filenameBackslashForCanonical = dirnameSubdirBackslash + "\\file.txt";
5252
const string dirnameSubdirBackslashForCanonical = dirnameBase + "\\dir\\subdir";
5353
const string dirnameMixedWithTrailingForCanonical = dirnameBase + "/dir\\subdir/";
5454
const string dirnameBackslashWithTrailingForCanonical = dirnameBase + "\\dir\\subdir\\";
55+
const string filenameMixedForCanonical = dirnameMixedWithTrailingForCanonical + "\\file.txt";
5556

5657
static set<string, VersionCmp::Greater> sortedFileSet = {
5758
"foo.h",
@@ -859,7 +860,7 @@ TEST_F(RteFsUtilsTest, MakePathCanonical) {
859860
EXPECT_EQ(ret, filenameCanonical);
860861

861862
// Test filename with mixed separators
862-
ret = RteFsUtils::MakePathCanonical(filenameBackslashForCanonical);
863+
ret = RteFsUtils::MakePathCanonical(filenameMixedForCanonical);
863864
EXPECT_EQ(ret, filenameCanonical);
864865

865866
// Test dirname with regular separators and trailing
@@ -885,6 +886,61 @@ TEST_F(RteFsUtilsTest, MakePathCanonical) {
885886
RteFsUtils::RemoveDir(dirnameSubdir);
886887
}
887888

889+
TEST_F(RteFsUtilsTest, Equivalent) {
890+
891+
892+
EXPECT_TRUE(RteFsUtils::Equivalent("",""));
893+
EXPECT_TRUE(RteFsUtils::Equivalent("foo","foo"));
894+
895+
EXPECT_FALSE(RteFsUtils::Equivalent("","foo"));
896+
EXPECT_FALSE(RteFsUtils::Equivalent("foo",""));
897+
898+
899+
// now test different combinations: files must exist!
900+
string ret;
901+
error_code ec;
902+
const string filenameCanonical = fs::current_path(ec).append(filenameRegular).generic_string();
903+
const string dirnameCanonical = fs::current_path(ec).append(dirnameSubdir).generic_string();
904+
905+
// create file and with parent directories for reliability of the tests
906+
RteFsUtils::CreateTextFile(filenameRegular, "foo");
907+
908+
// check filename with regular separators
909+
EXPECT_TRUE(RteFsUtils::Equivalent(filenameRegular, filenameCanonical));
910+
911+
// Even longer path are equal
912+
string nonExistingFileRel = dirnameSubdir + "/non/existing/path/../file.txt";
913+
string nonExistingFileAbs = dirnameCanonical + "/non/existing/file.txt";
914+
EXPECT_TRUE(RteFsUtils::Equivalent(nonExistingFileRel, nonExistingFileAbs));
915+
916+
// Test filenames with backslashes separators
917+
EXPECT_TRUE(RteFsUtils::Equivalent(filenameBackslashForCanonical, filenameCanonical));
918+
919+
// Test filename with mixed separators
920+
EXPECT_TRUE(RteFsUtils::Equivalent(filenameMixedForCanonical, filenameCanonical));
921+
922+
//Test filename with mixed separators against backslashes
923+
EXPECT_TRUE(RteFsUtils::Equivalent(filenameMixedForCanonical, filenameBackslashForCanonical));
924+
925+
// Test dirname with regular separators and trailing
926+
EXPECT_TRUE(RteFsUtils::Equivalent(dirnameSubdirWithTrailing, dirnameCanonical));
927+
928+
// Test dirname with backslashes separators and trailing
929+
EXPECT_TRUE(RteFsUtils::Equivalent(dirnameBackslashWithTrailingForCanonical, dirnameCanonical));
930+
931+
// Test dirname with mixed separators and trailing
932+
EXPECT_TRUE(RteFsUtils::Equivalent(dirnameMixedWithTrailingForCanonical, dirnameCanonical));
933+
934+
// Test path with dot inside
935+
EXPECT_TRUE(RteFsUtils::Equivalent(dirnameDotSubdir, dirnameCanonical));
936+
937+
// Test path with two dots inside
938+
EXPECT_TRUE(RteFsUtils::Equivalent(dirnameDotDotSubdir, dirnameCanonical));
939+
940+
RteFsUtils::RemoveDir(dirnameSubdir);
941+
}
942+
943+
888944
TEST_F(RteFsUtilsTest, GetCurrentFolder) {
889945
error_code ec;
890946
string currDir;

libs/rtemodel/src/RteProject.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -710,8 +710,7 @@ void RteProject::UpdateConfigFileBackups(RteFileInstance* fi, RteItem* f)
710710
RteFsUtils::GrepFileNames(backupFileNames, dir, baseName + "@*");
711711
RteFsUtils::GrepFileNames(backupFileNames, dir, updateName + "@*");
712712
for (string fileName : backupFileNames) {
713-
error_code ec;
714-
if (!fs::equivalent(fileName, baseFile, ec) && !fs::equivalent(fileName, updateFile, ec)) {
713+
if (!RteFsUtils::Equivalent(fileName, baseFile) && !RteFsUtils::Equivalent(fileName, updateFile)) {
715714
RteFsUtils::DeleteFileAutoRetry(fileName);
716715
}
717716
}

tools/projmgr/src/ProjMgrRpcServer.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -407,7 +407,7 @@ RpcArgs::PackReference& RpcHandler::EnsurePackReferenceForPack(const string& con
407407
auto& packRefs = GetPackReferences(context);
408408
for(auto& ref : packRefs) {
409409
if(ref.resolvedPack.has_value() && ref.resolvedPack == packId &&
410-
(origin.empty() || ref.origin == origin)) {
410+
(origin.empty() || RteFsUtils::Equivalent(ref.origin, origin))) {
411411
ref.selected = true; // ensure selected
412412
return ref;
413413
}
@@ -428,8 +428,8 @@ RpcArgs::PackReference& RpcHandler::EnsurePackReference(const string& context, c
428428
auto& packRefs = GetPackReferences(context);
429429
for(auto& ref : packRefs) {
430430
if(ref.pack == packRef.pack &&
431-
(!packRef.path.has_value() || ref.path == packRef.path) &&
432-
(packRef.origin.empty() || ref.origin == packRef.origin)) {
431+
(packRef.origin.empty() || RteFsUtils::Equivalent(ref.origin, packRef.origin)) &&
432+
(RteFsUtils::Equivalent(ref.path.value_or(""), packRef.path.value_or("")))) {
433433
return ref;
434434
}
435435
}

tools/projmgr/src/ProjMgrWorker.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2690,8 +2690,7 @@ bool ProjMgrWorker::IsPreIncludeByTarget(const RteTarget* activeTarget, const st
26902690
const auto& preIncludeFiles = activeTarget->GetPreIncludeFiles();
26912691
for (const auto& [_, fileSet] : preIncludeFiles) {
26922692
for (auto file : fileSet) {
2693-
error_code ec;
2694-
if (fs::equivalent(file, preInclude, ec)) {
2693+
if (RteFsUtils::Equivalent(file, preInclude)) {
26952694
return true;
26962695
}
26972696
}
@@ -3621,9 +3620,8 @@ bool ProjMgrWorker::ProcessSequenceRelative(ContextItem& context, string& item,
36213620
}
36223621
}
36233622
if (!pathReplace && !ref.empty()) {
3624-
error_code ec;
36253623
// adjust relative path according to the given reference
3626-
if (!fs::equivalent(outDir, ref, ec)) {
3624+
if (!RteFsUtils::Equivalent(outDir, ref)) {
36273625
const string absPath = RteFsUtils::MakePathCanonical(fs::path(item).is_relative() ? ref + "/" + item : item);
36283626
const string relPath = RteFsUtils::RelativePath(absPath, outDir, withHeadingDot);
36293627
if (!relPath.empty()) {

0 commit comments

Comments
 (0)