From 2c84ea90cd1c7b326c3f3712343449729c42176f Mon Sep 17 00:00:00 2001 From: LI Daobing Date: Mon, 3 May 2021 17:56:23 +0800 Subject: [PATCH 1/4] #462 change the filename dup algorithm --- src/iptux-utils/UtilsTest.cpp | 15 ++++++++++ src/iptux-utils/utils.cpp | 53 ++++++++++++++++++++++++++--------- src/iptux-utils/utils.h | 1 + 3 files changed, 55 insertions(+), 14 deletions(-) diff --git a/src/iptux-utils/UtilsTest.cpp b/src/iptux-utils/UtilsTest.cpp index add38fc6..7bb3c43a 100644 --- a/src/iptux-utils/UtilsTest.cpp +++ b/src/iptux-utils/UtilsTest.cpp @@ -125,3 +125,18 @@ TEST(Utils, utf8MakeValid) { ASSERT_EQ(utf8MakeValid("\xe4\xe6\x96\x87"), "�文"); ASSERT_EQ(utf8MakeValid("\xe4\xb8\xad\xe6"), "中�"); } + +TEST(Utils, dupPath) { + ASSERT_EQ(dupPath("/", 1), "/(1)"); + ASSERT_EQ(dupPath("/a.b", 1), "/a (1).b"); + ASSERT_EQ(dupPath("/a.b/.", 1), "/a.b/(1)"); + ASSERT_EQ(dupPath("/a.b/c.d", 1), "/a.b/c (1).d"); + ASSERT_EQ(dupPath("a.b/.", 1), "a.b/(1)"); + ASSERT_EQ(dupPath("a.b/c.d", 1), "a.b/c (1).d"); + ASSERT_EQ(dupPath("", 1), "(1)"); + ASSERT_EQ(dupPath("a", 1), "a (1)"); + ASSERT_EQ(dupPath("a.b", 1), "a (1).b"); + ASSERT_EQ(dupPath("a.b.c", 1), "a.b (1).c"); + ASSERT_EQ(dupPath("a.b", 2), "a (2).b"); + ASSERT_EQ(dupPath("a.b", 10), "a (10).b"); +} diff --git a/src/iptux-utils/utils.cpp b/src/iptux-utils/utils.cpp index a599e01c..e78dda89 100644 --- a/src/iptux-utils/utils.cpp +++ b/src/iptux-utils/utils.cpp @@ -109,25 +109,50 @@ char* convert_encode(const char* string, * @return 新文件路径 * */ char* assert_filename_inexist(const char* path) { - const char* ptr; - uint16_t count; - if (access(path, F_OK) != 0) return g_strdup(path); - ptr = strrchr(path, '/'); - ptr = ptr ? ptr + 1 : path; - count = 1; - string res; - while (count) { - res = - stringFormat("%.*s%" PRIu16 "_%s", (int)(ptr - path), path, count, ptr); - if (access(res.c_str(), F_OK) != 0) - break; - count++; + int idx = 1; + while (true) { + string newPath = dupPath(path, idx); + if (access(newPath.c_str(), F_OK) != 0) { + return g_strdup(newPath.c_str()); + } + idx++; + } +} + +string dupFilename(const string& filename, int idx) { + if (filename == "." || filename == "/") { + return stringFormat("(%d)", idx); } - return g_strdup(res.c_str()); + auto pos = filename.find_last_of('.'); + if (pos == string::npos) { + return stringFormat("%s (%d)", filename.c_str(), idx); + } + + return stringFormat("%s (%d).%s", filename.substr(0, pos).c_str(), idx, + filename.substr(pos + 1, filename.size()).c_str()); +} + +string dupPath(const string& path, int idx) { + auto basename_ = g_path_get_basename(path.c_str()); + auto dirname_ = g_path_get_dirname(path.c_str()); + + string basename = basename_; + string dirname = dirname_; + g_free(basename_); + g_free(dirname_); + + if (dirname == ".") { + return dupFilename(basename, idx); + } + if (dirname == "/") { + return "/" + dupFilename(basename, idx); + } + return stringFormat("%s/%s", dirname.c_str(), + dupFilename(basename, idx).c_str()); } /** diff --git a/src/iptux-utils/utils.h b/src/iptux-utils/utils.h index 77a8d028..3de14e5c 100644 --- a/src/iptux-utils/utils.h +++ b/src/iptux-utils/utils.h @@ -46,6 +46,7 @@ char* convert_encode(const char* string, const char* tocode, const char* fromcode); char* assert_filename_inexist(const char* path); +std::string dupPath(const std::string& fname, int idx); char* getformattime(gboolean date, const char* format, ...); gboolean giter_compare_foreach(gunichar src, gunichar dst); From 522e895601e7eb88631ba787ba285629929cbb2b Mon Sep 17 00:00:00 2001 From: LI Daobing Date: Mon, 3 May 2021 17:58:14 +0800 Subject: [PATCH 2/4] Update NEWS.md --- NEWS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/NEWS.md b/NEWS.md index f8bfc150..aad2b122 100644 --- a/NEWS.md +++ b/NEWS.md @@ -4,6 +4,7 @@ * [#439] try to fix compile problem under Hurd. * [#447] fix bug: use defined icon no longer works. * [#441] use `GtkHeaderBar` under Linux. +* [#462] when recv file, if file exist, save to `foo (1).ext` (was `1_foo.ext`). * Translation updated * Simplified Chinese * Russian - Thanks to @KovalevArtem From 43603269c38ed698912491ce39896be542f291a9 Mon Sep 17 00:00:00 2001 From: LI Daobing Date: Mon, 3 May 2021 18:02:03 +0800 Subject: [PATCH 3/4] fix API --- src/iptux-core/internal/AnalogFS.cpp | 9 ++++----- src/iptux-utils/utils.cpp | 6 +++--- src/iptux-utils/utils.h | 2 +- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/src/iptux-core/internal/AnalogFS.cpp b/src/iptux-core/internal/AnalogFS.cpp index 1a6525e5..eab1dd84 100644 --- a/src/iptux-core/internal/AnalogFS.cpp +++ b/src/iptux-core/internal/AnalogFS.cpp @@ -83,17 +83,16 @@ int AnalogFS::open(const char* fn, int flags) { */ int AnalogFS::open(const char* fn, int flags, mode_t mode) { char tpath[MAX_PATHLEN]; - char* tfn; int fd; strcpy(tpath, path); mergepath(tpath, fn); if ((flags & O_ACCMODE) == O_WRONLY) { - tfn = assert_filename_inexist(tpath); - if ((fd = ::open(tfn, flags, mode)) == -1) { - pwarning(_("Open() file \"%s\" failed, %s"), tfn, strerror(errno)); + auto tfn = assert_filename_inexist(tpath); + if ((fd = ::open(tfn.c_str(), flags, mode)) == -1) { + pwarning(_("Open() file \"%s\" failed, %s"), tfn.c_str(), + strerror(errno)); } - g_free(tfn); } else { if ((fd = ::open(tpath, flags, mode)) == -1) { pwarning(_("Open() file \"%s\" failed, %s"), tpath, strerror(errno)); diff --git a/src/iptux-utils/utils.cpp b/src/iptux-utils/utils.cpp index e78dda89..9176623d 100644 --- a/src/iptux-utils/utils.cpp +++ b/src/iptux-utils/utils.cpp @@ -108,15 +108,15 @@ char* convert_encode(const char* string, * @param path 文件路径 * @return 新文件路径 * */ -char* assert_filename_inexist(const char* path) { +string assert_filename_inexist(const char* path) { if (access(path, F_OK) != 0) - return g_strdup(path); + return path; int idx = 1; while (true) { string newPath = dupPath(path, idx); if (access(newPath.c_str(), F_OK) != 0) { - return g_strdup(newPath.c_str()); + return newPath; } idx++; } diff --git a/src/iptux-utils/utils.h b/src/iptux-utils/utils.h index 3de14e5c..dcd09c44 100644 --- a/src/iptux-utils/utils.h +++ b/src/iptux-utils/utils.h @@ -45,7 +45,7 @@ char* iptux_string_validate(const char* s, char* convert_encode(const char* string, const char* tocode, const char* fromcode); -char* assert_filename_inexist(const char* path); +std::string assert_filename_inexist(const char* path); std::string dupPath(const std::string& fname, int idx); char* getformattime(gboolean date, const char* format, ...); From 60f8e3ac0c17fde229ccadb50fbee3783916b7de Mon Sep 17 00:00:00 2001 From: LI Daobing Date: Mon, 3 May 2021 18:04:08 +0800 Subject: [PATCH 4/4] fix codecov ignore files --- codecov.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/codecov.yml b/codecov.yml index 894faef5..9b56082a 100644 --- a/codecov.yml +++ b/codecov.yml @@ -2,6 +2,8 @@ coverage: ignore: - "^src/iptux-core/Test.*" - "^src/iptux-core/.*Test.cpp$" + - "^src/iptux-utils/Test.*" + - "^src/iptux-utils/.*Test.cpp$" - "^src/iptux/Test.*" - "^src/iptux/.*Test.cpp$" - "^src/googletest.*"