summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/filepath.h4
-rw-r--r--rust/libnewsboat-ffi/src/filepath.rs5
-rw-r--r--src/dirbrowserformaction.cpp31
-rw-r--r--src/filebrowserformaction.cpp28
-rw-r--r--src/filepath.cpp20
-rw-r--r--test/filepath.cpp91
6 files changed, 144 insertions, 35 deletions
diff --git a/include/filepath.h b/include/filepath.h
index be148b10..795a6dfb 100644
--- a/include/filepath.h
+++ b/include/filepath.h
@@ -64,6 +64,10 @@ public:
bool operator==(const Filepath&) const;
bool operator!=(const Filepath&) const;
+ bool operator<(const Filepath&) const;
+ bool operator<=(const Filepath&) const;
+ bool operator>(const Filepath&) const;
+ bool operator>=(const Filepath&) const;
/// Returns the filepath as a string in locale encoding.
///
diff --git a/rust/libnewsboat-ffi/src/filepath.rs b/rust/libnewsboat-ffi/src/filepath.rs
index 65ed82b8..602c3fa2 100644
--- a/rust/libnewsboat-ffi/src/filepath.rs
+++ b/rust/libnewsboat-ffi/src/filepath.rs
@@ -19,6 +19,7 @@ mod bridged {
fn create_empty() -> Box<PathBuf>;
fn create(filepath: Vec<u8>) -> Box<PathBuf>;
fn equals(lhs: &PathBuf, rhs: &PathBuf) -> bool;
+ fn less_than(lhs: &PathBuf, rhs: &PathBuf) -> bool;
fn into_bytes(filepath: &PathBuf) -> Vec<u8>;
fn display(filepath: &PathBuf) -> String;
fn push(filepath: &mut PathBuf, component: &PathBuf);
@@ -44,6 +45,10 @@ fn equals(lhs: &PathBuf, rhs: &PathBuf) -> bool {
lhs.0 == rhs.0
}
+fn less_than(lhs: &PathBuf, rhs: &PathBuf) -> bool {
+ lhs.0 < rhs.0
+}
+
fn into_bytes(filepath: &PathBuf) -> Vec<u8> {
filepath.0.as_os_str().as_bytes().to_owned()
}
diff --git a/src/dirbrowserformaction.cpp b/src/dirbrowserformaction.cpp
index 5c932d04..56f470da 100644
--- a/src/dirbrowserformaction.cpp
+++ b/src/dirbrowserformaction.cpp
@@ -1,5 +1,3 @@
-#define ENABLE_IMPLICIT_FILEPATH_CONVERSIONS
-
#include "dirbrowserformaction.h"
#include <algorithm>
@@ -177,31 +175,31 @@ void DirBrowserFormAction::update_title(const Filepath& working_directory)
FmtStrFormatter fmt;
fmt.register_fmt('N', PROGRAM_NAME);
fmt.register_fmt('V', utils::program_version());
- fmt.register_fmt('f', working_directory);
+ fmt.register_fmt('f', working_directory.display());
set_title(fmt.do_format(
cfg->get_configvalue("dirbrowser-title-format"), width));
}
-std::vector<std::string> get_sorted_dirlist()
+std::vector<Filepath> get_sorted_dirlist()
{
- std::vector<std::string> ret;
+ std::vector<Filepath> ret;
- const std::string cwdtmp = utils::getcwd();
+ const auto cwdtmp = utils::getcwd();
- DIR* dirp = ::opendir(cwdtmp.c_str());
+ DIR* dirp = ::opendir(cwdtmp.to_locale_string().c_str());
if (dirp) {
struct dirent* de = ::readdir(dirp);
while (de) {
if (strcmp(de->d_name, ".") != 0 &&
strcmp(de->d_name, "..") != 0) {
struct stat sb;
- auto dpath = strprintf::fmt(
- "%s/%s", cwdtmp, de->d_name);
- if (::lstat(dpath.c_str(), &sb) == 0) {
+ auto entry = Filepath::from_locale_string(de->d_name);
+ const auto dpath = cwdtmp.join(entry);
+ if (::lstat(dpath.to_locale_string().c_str(), &sb) == 0) {
const auto ftype = file_system::mode_to_filetype(sb.st_mode);
if (ftype == file_system::FileType::Directory) {
- ret.push_back(de->d_name);
+ ret.emplace_back(std::move(entry));
}
}
}
@@ -213,8 +211,8 @@ std::vector<std::string> get_sorted_dirlist()
std::sort(ret.begin(), ret.end());
- if (cwdtmp != "/") {
- ret.insert(ret.begin(), "..");
+ if (cwdtmp != Filepath::from_locale_string("/")) {
+ ret.emplace(ret.begin(), Filepath::from_locale_string(".."));
}
return ret;
@@ -228,14 +226,11 @@ void DirBrowserFormAction::prepare()
* in the current directory.
*/
if (do_redraw) {
- const std::string cwdtmp = utils::getcwd();
- update_title(cwdtmp);
-
- std::vector<std::string> directories = get_sorted_dirlist();
+ update_title(utils::getcwd());
id_at_position.clear();
lines.clear();
- for (std::string directory : directories) {
+ for (auto directory : get_sorted_dirlist()) {
add_directory(id_at_position, directory);
}
diff --git a/src/filebrowserformaction.cpp b/src/filebrowserformaction.cpp
index ba8884d3..e6e1f83c 100644
--- a/src/filebrowserformaction.cpp
+++ b/src/filebrowserformaction.cpp
@@ -1,5 +1,3 @@
-#define ENABLE_IMPLICIT_FILEPATH_CONVERSIONS
-
#include "filebrowserformaction.h"
#include <algorithm>
@@ -201,25 +199,25 @@ void FileBrowserFormAction::update_title(const Filepath& working_directory)
FmtStrFormatter fmt;
fmt.register_fmt('N', PROGRAM_NAME);
fmt.register_fmt('V', utils::program_version());
- fmt.register_fmt('f', working_directory);
+ fmt.register_fmt('f', working_directory.display());
set_title(fmt.do_format(
cfg->get_configvalue("filebrowser-title-format"), width));
}
-std::vector<std::string> get_sorted_filelist()
+std::vector<Filepath> get_sorted_filelist()
{
- std::vector<std::string> ret;
+ std::vector<Filepath> ret;
- const std::string cwdtmp = utils::getcwd();
+ const auto cwdtmp = utils::getcwd();
- DIR* dirp = ::opendir(cwdtmp.c_str());
+ DIR* dirp = ::opendir(cwdtmp.to_locale_string().c_str());
if (dirp) {
struct dirent* de = ::readdir(dirp);
while (de) {
if (strcmp(de->d_name, ".") != 0 &&
strcmp(de->d_name, "..") != 0) {
- ret.push_back(de->d_name);
+ ret.push_back(Filepath::from_locale_string(de->d_name));
}
de = ::readdir(dirp);
}
@@ -228,8 +226,8 @@ std::vector<std::string> get_sorted_filelist()
std::sort(ret.begin(), ret.end());
- if (cwdtmp != "/") {
- ret.insert(ret.begin(), "..");
+ if (cwdtmp != Filepath::from_locale_string("/")) {
+ ret.emplace(ret.begin(), Filepath::from_locale_string(".."));
}
return ret;
@@ -243,18 +241,14 @@ void FileBrowserFormAction::prepare()
* in the current directory.
*/
if (do_redraw) {
- const std::string cwdtmp = utils::getcwd();
- update_title(cwdtmp);
-
- std::vector<std::string> files = get_sorted_filelist();
+ update_title(utils::getcwd());
id_at_position.clear();
lines.clear();
- for (std::string filename : files) {
+ for (auto filename : get_sorted_filelist()) {
add_file(id_at_position, filename);
}
-
auto render_line = [this](std::uint32_t line, std::uint32_t width) -> StflRichText {
(void)width;
return lines[line];
@@ -295,7 +289,7 @@ void FileBrowserFormAction::init()
const int status = ::chdir(save_path.c_str());
LOG(Level::DEBUG, "view::filebrowser: chdir(%s) = %i", save_path, status);
- set_value("filenametext", default_filename);
+ set_value("filenametext", default_filename.to_locale_string());
// Set position to 0 and back to ensure that the text is visible
draw_form();
diff --git a/src/filepath.cpp b/src/filepath.cpp
index 6ff48526..caaf7da5 100644
--- a/src/filepath.cpp
+++ b/src/filepath.cpp
@@ -63,6 +63,26 @@ bool Filepath::operator!=(const Filepath& other) const
return !(*this == other);
}
+bool Filepath::operator<(const Filepath& other) const
+{
+ return filepath::bridged::less_than(*rs_object, *other.rs_object);
+}
+
+bool Filepath::operator<=(const Filepath& other) const
+{
+ return !(*this > other);
+}
+
+bool Filepath::operator>(const Filepath& other) const
+{
+ return !(*this < other) && (*this != other);
+}
+
+bool Filepath::operator>=(const Filepath& other) const
+{
+ return !(*this < other);
+}
+
void Filepath::push(const Filepath& component)
{
filepath::bridged::push(*rs_object, *component.rs_object);
diff --git a/test/filepath.cpp b/test/filepath.cpp
index a0d05ba3..5d500489 100644
--- a/test/filepath.cpp
+++ b/test/filepath.cpp
@@ -206,3 +206,94 @@ TEST_CASE("Can extract the final component of the path (file or directory name)"
REQUIRE(path.file_name().value() == Filepath::from_locale_string("one\x80two"));
}
}
+
+TEST_CASE("Can be ordered lexicographically", "[Filepath]")
+{
+ const auto root = Filepath::from_locale_string("/");
+ const auto var_log = Filepath::from_locale_string("/var/log");
+ const auto home_minoru = Filepath::from_locale_string("/home/minoru");
+ const auto home_minoru_src_newsboat =
+ Filepath::from_locale_string("/home/minoru/src/newsboat");
+
+ SECTION("operator<") {
+ SECTION("Path to directory is less than the path to its subdirectory") {
+ REQUIRE(root < var_log);
+ REQUIRE(root < home_minoru);
+ REQUIRE(home_minoru < home_minoru_src_newsboat);
+
+ REQUIRE_FALSE(home_minoru_src_newsboat < root);
+ }
+
+ SECTION("Disparate paths are ordered lexicographically") {
+ REQUIRE(home_minoru < var_log);
+ REQUIRE(home_minoru_src_newsboat < var_log);
+
+ REQUIRE_FALSE(home_minoru_src_newsboat < home_minoru);
+ }
+ }
+
+ SECTION("operator>") {
+ SECTION("Path to subdirectory is greater than the path to its parent directory") {
+ REQUIRE(var_log > root);
+ REQUIRE(home_minoru > root);
+ REQUIRE(home_minoru_src_newsboat > home_minoru);
+
+ REQUIRE_FALSE(root > home_minoru_src_newsboat);
+ }
+
+ SECTION("Disparate paths are ordered lexicographically") {
+ REQUIRE(var_log > home_minoru);
+ REQUIRE(var_log > home_minoru_src_newsboat);
+
+ REQUIRE_FALSE(home_minoru > home_minoru_src_newsboat);
+ }
+ }
+
+ SECTION("operator<=") {
+ SECTION("Any path is less than or equal to itself") {
+ REQUIRE(root <= root);
+ REQUIRE(var_log <= var_log);
+ REQUIRE(home_minoru <= home_minoru);
+ REQUIRE(home_minoru_src_newsboat <= home_minoru_src_newsboat);
+ }
+
+ SECTION("Path to directory is less than or equal to the path to its subdirectory") {
+ REQUIRE(root <= var_log);
+ REQUIRE(root <= home_minoru);
+ REQUIRE(home_minoru <= home_minoru_src_newsboat);
+
+ REQUIRE_FALSE(home_minoru_src_newsboat <= root);
+ }
+
+ SECTION("Disparate paths are ordered lexicographically") {
+ REQUIRE(home_minoru <= var_log);
+ REQUIRE(home_minoru_src_newsboat <= var_log);
+
+ REQUIRE_FALSE(home_minoru_src_newsboat <= home_minoru);
+ }
+ }
+
+ SECTION("operator>=") {
+ SECTION("Any path is greater than or equal to itself") {
+ REQUIRE(root >= root);
+ REQUIRE(var_log >= var_log);
+ REQUIRE(home_minoru >= home_minoru);
+ REQUIRE(home_minoru_src_newsboat >= home_minoru_src_newsboat);
+ }
+
+ SECTION("Path to subdirectory is greater than or equal to the path to its parent directory") {
+ REQUIRE(var_log >= root);
+ REQUIRE(home_minoru >= root);
+ REQUIRE(home_minoru_src_newsboat >= home_minoru);
+
+ REQUIRE_FALSE(root >= home_minoru_src_newsboat);
+ }
+
+ SECTION("Disparate paths are ordered lexicographically") {
+ REQUIRE(var_log >= home_minoru);
+ REQUIRE(var_log >= home_minoru_src_newsboat);
+
+ REQUIRE_FALSE(home_minoru >= home_minoru_src_newsboat);
+ }
+ }
+}