mirror of
https://github.com/transmission/transmission.git
synced 2025-12-24 20:35:36 +00:00
perf: tr_sys_path_dirname() returns a std::string_view (#2990)
* refactor: use nodejs impl of path.win32.dirname() * refactor: use nodejs impl of path.posix.dirname()
This commit is contained in:
@@ -8,6 +8,7 @@
|
||||
#include <ostream>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <utility>
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <sys/types.h>
|
||||
@@ -181,6 +182,32 @@ protected:
|
||||
}
|
||||
}
|
||||
|
||||
static void testPathXname(
|
||||
XnameTestData const* data,
|
||||
size_t data_size,
|
||||
std::string_view (*func)(std::string_view, tr_error**))
|
||||
{
|
||||
for (size_t i = 0; i < data_size; ++i)
|
||||
{
|
||||
tr_error* err = nullptr;
|
||||
auto const name = func(data[i].input, &err);
|
||||
std::cerr << __FILE__ << ':' << __LINE__ << " in [" << data[i].input << "] out [" << name << ']' << std::endl;
|
||||
|
||||
if (data[i].output != nullptr)
|
||||
{
|
||||
EXPECT_NE(""sv, name);
|
||||
EXPECT_EQ(nullptr, err) << *err;
|
||||
EXPECT_EQ(std::string{ data[i].output }, name);
|
||||
}
|
||||
else
|
||||
{
|
||||
EXPECT_EQ(""sv, name);
|
||||
EXPECT_NE(nullptr, err);
|
||||
tr_error_clear(&err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void testDirReadImpl(tr_pathbuf const& path, bool* have1, bool* have2)
|
||||
{
|
||||
*have1 = *have2 = false;
|
||||
@@ -687,7 +714,7 @@ TEST_F(FileTest, pathResolve)
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST_F(FileTest, pathBasenameDirname)
|
||||
TEST_F(FileTest, pathBasename)
|
||||
{
|
||||
auto const common_xname_tests = std::vector<XnameTestData>{
|
||||
XnameTestData{ "/", "/" },
|
||||
@@ -725,7 +752,7 @@ TEST_F(FileTest, pathBasenameDirname)
|
||||
};
|
||||
|
||||
testPathXname(common_xname_tests.data(), common_xname_tests.size(), tr_sys_path_basename);
|
||||
testPathXname(common_xname_tests.data(), common_xname_tests.size(), tr_sys_path_dirname);
|
||||
// testPathXname(common_xname_tests.data(), common_xname_tests.size(), tr_sys_path_dirname);
|
||||
|
||||
auto const basename_tests = std::vector<XnameTestData>{
|
||||
XnameTestData{ "a", "a" },
|
||||
@@ -751,36 +778,91 @@ TEST_F(FileTest, pathBasenameDirname)
|
||||
};
|
||||
|
||||
testPathXname(basename_tests.data(), basename_tests.size(), tr_sys_path_basename);
|
||||
}
|
||||
|
||||
auto const dirname_tests = std::vector<XnameTestData>{
|
||||
XnameTestData{ "/a/b/c", "/a/b" },
|
||||
{ "a/b/c", "a/b" },
|
||||
{ "a/b/c/", "a/b" },
|
||||
{ "a", "." },
|
||||
{ "a/", "." },
|
||||
TEST_F(FileTest, pathDirname)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
{ "C:\\a/b\\c", "C:\\a/b" },
|
||||
{ "C:\\a/b\\c\\", "C:\\a/b" },
|
||||
{ "C:\\a/b", "C:\\a" },
|
||||
{ "C:/a", "C:" },
|
||||
{ "C:", "C:" },
|
||||
{ "C:/", "C:" },
|
||||
{ "C:\\", "C:" },
|
||||
{ "c:a/b", "c:a" },
|
||||
{ "c:a", "c:." },
|
||||
{ "c:.", "c:." },
|
||||
{ "\\\\a\\b\\c", "\\\\a\\b" },
|
||||
{ "\\\\a\\b\\c/", "\\\\a\\b" },
|
||||
{ "//a/b", "//a" },
|
||||
{ "//1.2.3.4/b", "//1.2.3.4" },
|
||||
{ "\\\\a", "\\\\" },
|
||||
{ "\\\\1.2.3.4", "\\\\" },
|
||||
{ "\\\\", "\\\\" },
|
||||
{ "a/b\\c", "a/b" },
|
||||
static auto constexpr DirnameTests = std::array<std::pair<std::string_view, std::string_view>, 48>{ {
|
||||
{ "C:\\a/b\\c"sv, "C:\\a/b"sv },
|
||||
{ "C:\\a/b\\c\\"sv, "C:\\a/b"sv },
|
||||
{ "C:\\a/b"sv, "C:\\a"sv },
|
||||
{ "C:/a"sv, "C:/"sv },
|
||||
{ "C:"sv, "C:"sv },
|
||||
{ "C:/"sv, "C:/"sv },
|
||||
{ "c:a/b"sv, "c:a"sv },
|
||||
{ "c:a"sv, "c:"sv },
|
||||
{ "\\\\a"sv, "\\"sv },
|
||||
{ "\\\\1.2.3.4"sv, "\\"sv },
|
||||
{ "\\\\"sv, "\\"sv },
|
||||
{ "a/b\\c"sv, "a/b"sv },
|
||||
// taken from Node.js unit tests
|
||||
// https://github.com/nodejs/node/blob/e46c680bf2b211bbd52cf959ca17ee98c7f657f5/test/parallel/test-path-dirname.js
|
||||
{ "c:\\"sv, "c:\\"sv },
|
||||
{ "c:\\foo"sv, "c:\\"sv },
|
||||
{ "c:\\foo\\"sv, "c:\\"sv },
|
||||
{ "c:\\foo\\bar"sv, "c:\\foo"sv },
|
||||
{ "c:\\foo\\bar\\"sv, "c:\\foo"sv },
|
||||
{ "c:\\foo\\bar\\baz"sv, "c:\\foo\\bar"sv },
|
||||
{ "c:\\foo bar\\baz"sv, "c:\\foo bar"sv },
|
||||
{ "\\"sv, "\\"sv },
|
||||
{ "\\foo"sv, "\\"sv },
|
||||
{ "\\foo\\"sv, "\\"sv },
|
||||
{ "\\foo\\bar"sv, "\\foo"sv },
|
||||
{ "\\foo\\bar\\"sv, "\\foo"sv },
|
||||
{ "\\foo\\bar\\baz"sv, "\\foo\\bar"sv },
|
||||
{ "\\foo bar\\baz"sv, "\\foo bar"sv },
|
||||
{ "c:"sv, "c:"sv },
|
||||
{ "c:foo"sv, "c:"sv },
|
||||
{ "c:foo\\"sv, "c:"sv },
|
||||
{ "c:foo\\bar"sv, "c:foo"sv },
|
||||
{ "c:foo\\bar\\"sv, "c:foo"sv },
|
||||
{ "c:foo\\bar\\baz"sv, "c:foo\\bar"sv },
|
||||
{ "c:foo bar\\baz"sv, "c:foo bar"sv },
|
||||
{ "file:stream"sv, "."sv },
|
||||
{ "dir\\file:stream"sv, "dir"sv },
|
||||
{ "\\\\unc\\share"sv, "\\\\unc\\share"sv },
|
||||
{ "\\\\unc\\share\\foo"sv, "\\\\unc\\share\\"sv },
|
||||
{ "\\\\unc\\share\\foo\\"sv, "\\\\unc\\share\\"sv },
|
||||
{ "\\\\unc\\share\\foo\\bar"sv, "\\\\unc\\share\\foo"sv },
|
||||
{ "\\\\unc\\share\\foo\\bar\\"sv, "\\\\unc\\share\\foo"sv },
|
||||
{ "\\\\unc\\share\\foo\\bar\\baz"sv, "\\\\unc\\share\\foo\\bar"sv },
|
||||
{ "/a/b/"sv, "/a"sv },
|
||||
{ "/a/b"sv, "/a"sv },
|
||||
{ "/a"sv, "/"sv },
|
||||
{ ""sv, "."sv },
|
||||
{ "/"sv, "/"sv },
|
||||
{ "////"sv, "/"sv },
|
||||
{ "foo"sv, "."sv },
|
||||
} };
|
||||
#else
|
||||
static auto constexpr DirnameTests = std::array<std::pair<std::string_view, std::string_view>, 15>{ {
|
||||
// taken from Node.js unit tests
|
||||
// https://github.com/nodejs/node/blob/e46c680bf2b211bbd52cf959ca17ee98c7f657f5/test/parallel/test-path-dirname.js
|
||||
{ "/a/b/"sv, "/a"sv },
|
||||
{ "/a/b"sv, "/a"sv },
|
||||
{ "/a"sv, "/"sv },
|
||||
{ ""sv, "."sv },
|
||||
{ "/"sv, "/"sv },
|
||||
{ "////"sv, "/"sv },
|
||||
{ "//a"sv, "//"sv },
|
||||
{ "foo"sv, "."sv },
|
||||
// taken from dirname(3) manpage
|
||||
{ "usr"sv, "."sv },
|
||||
{ "/usr/lib", "/usr"sv },
|
||||
{ "/usr/"sv, "/"sv },
|
||||
{ "/usr/"sv, "/"sv },
|
||||
{ "/"sv, "/"sv },
|
||||
{ "."sv, "."sv },
|
||||
{ ".."sv, "."sv },
|
||||
} };
|
||||
#endif
|
||||
};
|
||||
|
||||
testPathXname(dirname_tests.data(), dirname_tests.size(), tr_sys_path_dirname);
|
||||
for (auto const& [input, expected] : DirnameTests)
|
||||
{
|
||||
EXPECT_EQ(expected, tr_sys_path_dirname(input)) << "input[" << input << "] expected [" << expected << "] actual ["
|
||||
<< tr_sys_path_dirname(input) << ']' << std::endl;
|
||||
}
|
||||
|
||||
/* TODO: is_same(dirname(x) + '/' + basename(x), x) */
|
||||
}
|
||||
|
||||
@@ -180,10 +180,11 @@ protected:
|
||||
createFileWithContents(filename, std::data(Content), std::size(Content));
|
||||
paths.emplace(filename);
|
||||
|
||||
while (!tr_sys_path_is_same(parent, filename))
|
||||
auto walk = std::string_view{ filename.sv() };
|
||||
while (!tr_sys_path_is_same(parent, std::string{ walk }.c_str()))
|
||||
{
|
||||
filename = tr_sys_path_dirname(filename);
|
||||
paths.emplace(filename);
|
||||
walk = tr_sys_path_dirname(walk);
|
||||
paths.emplace(walk);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -301,7 +302,7 @@ TEST_F(RemoveTest, LeavesNonJunkAlone)
|
||||
EXPECT_EQ(expected_tree, getSubtreeContents(parent));
|
||||
|
||||
files.remove(parent, "tmpdir_prefix"sv, sysPathRemove);
|
||||
expected_tree = { parent, tr_sys_path_dirname(nonjunk_file), nonjunk_file.c_str() };
|
||||
expected_tree = { parent, std::string{ tr_sys_path_dirname(nonjunk_file) }, nonjunk_file.c_str() };
|
||||
EXPECT_EQ(expected_tree, getSubtreeContents(parent));
|
||||
}
|
||||
|
||||
|
||||
@@ -350,7 +350,7 @@ TEST_F(RenameTest, multifileTorrent)
|
||||
str = tr_torrentFindFile(tor, 2);
|
||||
EXPECT_NE(nullptr, str);
|
||||
tr_sys_path_remove(str);
|
||||
tr_sys_path_remove(tr_sys_path_dirname(str).c_str());
|
||||
tr_sys_path_remove(std::string{ tr_sys_path_dirname(str) }.c_str());
|
||||
tr_free(str);
|
||||
sync();
|
||||
blockingTorrentVerify(tor);
|
||||
|
||||
@@ -35,7 +35,7 @@ std::string getTestProgramPath(std::string const& filename)
|
||||
{
|
||||
auto const exe_path = makeString(tr_sys_path_resolve(testing::internal::GetArgvs().front().data()));
|
||||
auto const exe_dir = tr_sys_path_dirname(exe_path);
|
||||
return exe_dir + TR_PATH_DELIMITER + filename;
|
||||
return std::string{ exe_dir } + TR_PATH_DELIMITER + filename;
|
||||
}
|
||||
|
||||
class SubprocessTest
|
||||
|
||||
@@ -184,7 +184,7 @@ protected:
|
||||
|
||||
auto const dir = tr_sys_path_dirname(path);
|
||||
tr_error* error = nullptr;
|
||||
tr_sys_dir_create(dir.data(), TR_SYS_DIR_CREATE_PARENTS, 0700, &error);
|
||||
tr_sys_dir_create(std::string{ dir }.c_str(), TR_SYS_DIR_CREATE_PARENTS, 0700, &error);
|
||||
EXPECT_EQ(nullptr, error) << "path[" << path << "] dir[" << dir << "] " << *error;
|
||||
|
||||
errno = tmperr;
|
||||
@@ -411,7 +411,7 @@ protected:
|
||||
auto const filename = tr_pathbuf{ base, '/', subpath, suffix };
|
||||
|
||||
auto const dirname = tr_sys_path_dirname(filename);
|
||||
tr_sys_dir_create(dirname.c_str(), TR_SYS_DIR_CREATE_PARENTS, 0700);
|
||||
tr_sys_dir_create(std::string{ dirname }.c_str(), TR_SYS_DIR_CREATE_PARENTS, 0700);
|
||||
|
||||
auto fd = tr_sys_file_open(filename, TR_SYS_FILE_WRITE | TR_SYS_FILE_CREATE | TR_SYS_FILE_TRUNCATE, 0600);
|
||||
auto const file_size = metainfo->fileSize(i);
|
||||
|
||||
Reference in New Issue
Block a user