summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/rs_utils.h2
-rw-r--r--rust/libnewsboat-ffi/src/utils.rs15
-rw-r--r--rust/libnewsboat/src/utils.rs32
-rw-r--r--src/utils.cpp9
4 files changed, 50 insertions, 8 deletions
diff --git a/include/rs_utils.h b/include/rs_utils.h
index b35468ff..cbef8e0a 100644
--- a/include/rs_utils.h
+++ b/include/rs_utils.h
@@ -82,6 +82,8 @@ unsigned int rs_newsboat_version_major();
int rs_mkdir_parents(const char* path, const std::uint32_t mode);
+char* rs_strip_comments(const char* line);
+
class RustString {
private:
char* str;
diff --git a/rust/libnewsboat-ffi/src/utils.rs b/rust/libnewsboat-ffi/src/utils.rs
index 1da94c53..40a7946d 100644
--- a/rust/libnewsboat-ffi/src/utils.rs
+++ b/rust/libnewsboat-ffi/src/utils.rs
@@ -489,3 +489,18 @@ pub extern "C" fn rs_program_version() -> *mut c_char {
pub extern "C" fn rs_newsboat_version_major() -> u32 {
abort_on_panic(|| utils::newsboat_major_version())
}
+
+#[no_mangle]
+pub unsafe extern "C" fn rs_strip_comments(line: *const c_char) -> *mut c_char {
+ abort_on_panic(|| {
+ let line = CStr::from_ptr(line);
+ let line = line.to_str().expect("line contained invalid UTF-8");
+
+ let result = utils::strip_comments(line);
+
+ // `result` contains a subset of `line`, which is a C string. Thus, we conclude that
+ // `result` doesn't contain null bytes. Therefore, `CString::new` always returns `Some`.
+ let result = CString::new(result.into_owned()).unwrap();
+ result.into_raw()
+ })
+}
diff --git a/rust/libnewsboat/src/utils.rs b/rust/libnewsboat/src/utils.rs
index 91ee9cfe..40f6ad39 100644
--- a/rust/libnewsboat/src/utils.rs
+++ b/rust/libnewsboat/src/utils.rs
@@ -16,6 +16,7 @@ use self::url::percent_encoding::*;
use self::url::Url;
use libc::c_ulong;
use logger::{self, Level};
+use std::borrow::Cow;
use std::fs::DirBuilder;
use std::io::{self, Write};
use std::os::unix::fs::DirBuilderExt;
@@ -545,6 +546,16 @@ pub fn newsboat_major_version() -> u32 {
env!("CARGO_PKG_VERSION_MAJOR").parse::<u32>().unwrap()
}
+/// Returns the part of the string before first # character (or the whole input string if there are
+/// no # character in it).
+pub fn strip_comments(line: &str) -> Cow<str> {
+ if let Some(index) = line.find('#') {
+ Cow::from(&line[0..index])
+ } else {
+ Cow::from(line)
+ }
+}
+
#[cfg(test)]
mod tests {
extern crate tempfile;
@@ -1042,4 +1053,25 @@ mod tests {
assert_eq!(strnaturalcmp("aa10", "aa2"), Ordering::Greater);
}
+
+ #[test]
+ fn t_strip_comments() {
+ // no comments in line
+ assert_eq!(strip_comments(""), "");
+ assert_eq!(strip_comments("\t\n"), "\t\n");
+ assert_eq!(strip_comments("some directive "), "some directive ");
+
+ // fully commented line
+ assert_eq!(strip_comments("#"), "");
+ assert_eq!(strip_comments("# #"), "");
+ assert_eq!(strip_comments("# comment"), "");
+
+ // partially commented line
+ assert_eq!(strip_comments("directive # comment"), "directive ");
+ assert_eq!(
+ strip_comments("directive # comment # another"),
+ "directive "
+ );
+ assert_eq!(strip_comments("directive#comment"), "directive");
+ }
}
diff --git a/src/utils.cpp b/src/utils.cpp
index d7351425..9b50a492 100644
--- a/src/utils.cpp
+++ b/src/utils.cpp
@@ -78,14 +78,7 @@ void append_escapes(std::string& str, char c)
std::string utils::strip_comments(const std::string& line)
{
- /*
- * This functions returns only the non-comment part of the line,
- * which can then be safely evaluated and tokenized.
- *
- * If no comments are present on the line, the whole line is returned.
- */
- auto hash_pos = line.find_first_of("#");
- return line.substr(0, hash_pos);
+ return RustString(rs_strip_comments(line.c_str()));
}
std::vector<std::string> utils::tokenize_quoted(const std::string& str,