mirror of
https://git.libcamera.org/libcamera/libcamera.git
synced 2025-07-13 07:19:45 +03:00
libcamera: utils: Add a C++ dirname implementation
Provide a std::string based implementation which conforms to the behaviour of the dirname() fucntion defined by POSIX. Tests are added to cover expected corner cases of the implementation. Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
This commit is contained in:
parent
a8be6e94e7
commit
a15e8d92ea
3 changed files with 103 additions and 0 deletions
|
@ -33,6 +33,7 @@ namespace utils {
|
||||||
const char *basename(const char *path);
|
const char *basename(const char *path);
|
||||||
|
|
||||||
char *secure_getenv(const char *name);
|
char *secure_getenv(const char *name);
|
||||||
|
std::string dirname(const std::string &path);
|
||||||
|
|
||||||
template<class InputIt1, class InputIt2>
|
template<class InputIt1, class InputIt2>
|
||||||
unsigned int set_overlap(InputIt1 first1, InputIt1 last1,
|
unsigned int set_overlap(InputIt1 first1, InputIt1 last1,
|
||||||
|
|
|
@ -70,6 +70,54 @@ char *secure_getenv(const char *name)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \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,
|
* \fn libcamera::utils::set_overlap(InputIt1 first1, InputIt1 last1,
|
||||||
* InputIt2 first2, InputIt2 last2)
|
* InputIt2 first2, InputIt2 last2)
|
||||||
|
|
|
@ -19,6 +19,56 @@ using namespace libcamera;
|
||||||
class UtilsTest : public Test
|
class UtilsTest : public Test
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
|
int testDirname()
|
||||||
|
{
|
||||||
|
static const std::vector<std::string> paths = {
|
||||||
|
"",
|
||||||
|
"///",
|
||||||
|
"/bin",
|
||||||
|
"/usr/bin",
|
||||||
|
"//etc////",
|
||||||
|
"//tmp//d//",
|
||||||
|
"current_file",
|
||||||
|
"./current_file",
|
||||||
|
"./current_dir/",
|
||||||
|
"current_dir/",
|
||||||
|
};
|
||||||
|
|
||||||
|
static const std::vector<std::string> expected = {
|
||||||
|
".",
|
||||||
|
"/",
|
||||||
|
"/",
|
||||||
|
"/usr",
|
||||||
|
"/",
|
||||||
|
"//tmp",
|
||||||
|
".",
|
||||||
|
".",
|
||||||
|
".",
|
||||||
|
".",
|
||||||
|
};
|
||||||
|
|
||||||
|
std::vector<std::string> results;
|
||||||
|
|
||||||
|
for (const auto &path : paths)
|
||||||
|
results.push_back(utils::dirname(path));
|
||||||
|
|
||||||
|
if (results != expected) {
|
||||||
|
cerr << "utils::dirname() tests failed" << endl;
|
||||||
|
|
||||||
|
cerr << "expected: " << endl;
|
||||||
|
for (const auto &path : expected)
|
||||||
|
cerr << "\t" << path << endl;
|
||||||
|
|
||||||
|
cerr << "results: " << endl;
|
||||||
|
for (const auto &path : results)
|
||||||
|
cerr << "\t" << path << endl;
|
||||||
|
|
||||||
|
return TestFail;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TestPass;
|
||||||
|
}
|
||||||
|
|
||||||
int run()
|
int run()
|
||||||
{
|
{
|
||||||
/* utils::hex() test. */
|
/* utils::hex() test. */
|
||||||
|
@ -71,6 +121,10 @@ protected:
|
||||||
return TestFail;
|
return TestFail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* utils::dirname() tests. */
|
||||||
|
if (TestPass != testDirname())
|
||||||
|
return TestFail;
|
||||||
|
|
||||||
return TestPass;
|
return TestPass;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue