aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog2
-rw-r--r--include/qpdf/QUtil.hh16
-rw-r--r--libqpdf/QUtil.cc31
-rw-r--r--libtests/qtest/qutil/qutil.out7
-rw-r--r--libtests/qutil.cc25
-rw-r--r--manual/qpdf-manual.xml6
6 files changed, 83 insertions, 4 deletions
diff --git a/ChangeLog b/ChangeLog
index 2a3f1780..4a758b54 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,7 @@
2021-02-18 Jay Berkenbilt <ejb@ql.org>
+ * Add QUtil::path_basename to get last element of a path.
+
* Add examples/pdf-attach-file.cc to illustrate new file
attachment method and also new parse that takes indirect objects.
diff --git a/include/qpdf/QUtil.hh b/include/qpdf/QUtil.hh
index 769c5fd7..dd42fe1c 100644
--- a/include/qpdf/QUtil.hh
+++ b/include/qpdf/QUtil.hh
@@ -130,14 +130,22 @@ namespace QUtil
// Write the contents of filename as a binary file to the
// pipeline.
QPDF_DLL
- void
- pipe_file(char const* filename, Pipeline* p);
+ void pipe_file(char const* filename, Pipeline* p);
// Return a function that will send the contents of the given file
// through the given pipeline as binary data.
QPDF_DLL
- std::function<void(Pipeline*)>
- file_provider(std::string const& filename);
+ std::function<void(Pipeline*)> file_provider(std::string const& filename);
+
+ // Return the last path element. On Windows, either / or \ are
+ // path separators. Otherwise, only / is a path separator. Strip
+ // any trailing path separators. Then, if any path separators
+ // remain, return everything after the last path separator.
+ // Otherwise, return the whole string. As a special case, if a
+ // string consists entirely of path separators, the first
+ // character is returned.
+ QPDF_DLL
+ std::string path_basename(std::string const& filename);
QPDF_DLL
char* copy_string(std::string const&);
diff --git a/libqpdf/QUtil.cc b/libqpdf/QUtil.cc
index a3fa94f4..17b163f5 100644
--- a/libqpdf/QUtil.cc
+++ b/libqpdf/QUtil.cc
@@ -663,6 +663,37 @@ QUtil::file_provider(std::string const& filename)
};
}
+std::string
+QUtil::path_basename(std::string const& filename)
+{
+#ifdef _WIN32
+ char const* pathsep = "/\\";
+#else
+ char const* pathsep = "/";
+#endif
+ std::string last = filename;
+ auto len = last.length();
+ while (len > 1)
+ {
+ auto pos = last.find_last_of(pathsep);
+ if (pos == len - 1)
+ {
+ last.pop_back();
+ --len;
+ }
+ else if (pos == std::string::npos)
+ {
+ break;
+ }
+ else
+ {
+ last = last.substr(pos + 1);
+ break;
+ }
+ }
+ return last;
+}
+
char*
QUtil::copy_string(std::string const& str)
{
diff --git a/libtests/qtest/qutil/qutil.out b/libtests/qtest/qutil/qutil.out
index 7dded2e3..90f1fd16 100644
--- a/libtests/qtest/qutil/qutil.out
+++ b/libtests/qtest/qutil/qutil.out
@@ -97,6 +97,13 @@ file1: -qutil.out-, file2: -other-file-; same: 0: PASS
file1: -qutil.out-, file2: --; same: 0: PASS
file1: -qutil.out-, file2: -(null)-; same: 0: PASS
file1: --, file2: -qutil.out-; same: 0: PASS
+---- path
+//// -> /
+a/b/cdef -> cdef
+a/b/cdef/ -> cdef
+/ -> /
+ ->
+quack -> quack
---- read from file
This file is used for qutil testing.
It has mixed newlines.
diff --git a/libtests/qutil.cc b/libtests/qutil.cc
index abe05f35..7b1a8788 100644
--- a/libtests/qutil.cc
+++ b/libtests/qutil.cc
@@ -439,6 +439,29 @@ void same_file_test()
assert_same_file("", "qutil.out", false);
}
+void path_test()
+{
+ auto check = [](bool print, std::string const& a, std::string const& b) {
+ auto result = QUtil::path_basename(a);
+ if (print)
+ {
+ std::cout << a << " -> " << result << std::endl;
+ }
+ assert(result == b);
+ };
+
+#ifdef _WIN32
+ check(false, "asdf\\qwer", "qwer");
+ check(false, "asdf\\qwer/\\", "qwer");
+#endif
+ check(true, "////", "/");
+ check(true, "a/b/cdef", "cdef");
+ check(true, "a/b/cdef/", "cdef");
+ check(true, "/", "/");
+ check(true, "", "");
+ check(true, "quack", "quack");
+}
+
void read_from_file_test()
{
std::list<std::string> lines = QUtil::read_lines_from_file("other-file");
@@ -636,6 +659,8 @@ int main(int argc, char* argv[])
get_whoami_test();
std::cout << "---- file" << std::endl;
same_file_test();
+ std::cout << "---- path" << std::endl;
+ path_test();
std::cout << "---- read from file" << std::endl;
read_from_file_test();
std::cout << "---- hex encode/decode" << std::endl;
diff --git a/manual/qpdf-manual.xml b/manual/qpdf-manual.xml
index 4a294cb3..2c1c235a 100644
--- a/manual/qpdf-manual.xml
+++ b/manual/qpdf-manual.xml
@@ -5283,6 +5283,12 @@ print "\n";
matrices.
</para>
</listitem>
+ <listitem>
+ <para>
+ Add <function>QUtil::path_basename</function> to return the
+ last element of a path.
+ </para>
+ </listitem>
</itemizedlist>
</listitem>
<listitem>