summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/libcamera/include/utils.h1
-rw-r--r--src/libcamera/utils.cpp48
2 files changed, 49 insertions, 0 deletions
diff --git a/src/libcamera/include/utils.h b/src/libcamera/include/utils.h
index 080ea661..94059776 100644
--- a/src/libcamera/include/utils.h
+++ b/src/libcamera/include/utils.h
@@ -33,6 +33,7 @@ namespace utils {
const char *basename(const char *path);
char *secure_getenv(const char *name);
+std::string dirname(const std::string &path);
template<class InputIt1, class InputIt2>
unsigned int set_overlap(InputIt1 first1, InputIt1 last1,
diff --git a/src/libcamera/utils.cpp b/src/libcamera/utils.cpp
index 453e3b3b..f566e88c 100644
--- a/src/libcamera/utils.cpp
+++ b/src/libcamera/utils.cpp
@@ -71,6 +71,54 @@ char *secure_getenv(const char *name)
}
/**
+ * \brief Identify the dirname portion of a path
+ * \param[in] path The full path to parse
+ *
+ * This function conforms with the behaviour of the %dirname() function as
+ * defined by POSIX.
+ *
+ * \return A string of the directory component of the path
+ */
+std::string dirname(const std::string &path)
+{
+ if (path.empty())
+ return ".";
+
+ /*
+ * Skip all trailing slashes. If the path is only made of slashes,
+ * return "/".
+ */
+ size_t pos = path.size() - 1;
+ while (path[pos] == '/') {
+ if (!pos)
+ return "/";
+ pos--;
+ }
+
+ /*
+ * Find the previous slash. If the path contains no non-trailing slash,
+ * return ".".
+ */
+ while (path[pos] != '/') {
+ if (!pos)
+ return ".";
+ pos--;
+ }
+
+ /*
+ * Return the directory name up to (but not including) any trailing
+ * slash. If this would result in an empty string, return "/".
+ */
+ while (path[pos] == '/') {
+ if (!pos)
+ return "/";
+ pos--;
+ }
+
+ return path.substr(0, pos + 1);
+}
+
+/**
* \fn libcamera::utils::set_overlap(InputIt1 first1, InputIt1 last1,
* InputIt2 first2, InputIt2 last2)
* \brief Count the number of elements in the intersection of two ranges