Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/elfmz/far2l.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/utils
diff options
context:
space:
mode:
authorelfmz <fenix1905@tut.by>2022-09-06 23:53:52 +0300
committerelfmz <fenix1905@tut.by>2022-09-07 00:41:19 +0300
commit6203953dd76218dcdd9fdf39dcfcc17397d733c5 (patch)
treef944be06b46cfb0bb27ff2a2c7fa3f90a136d0cd /utils
parent398b4dc626aa9f00c02941afae2e588e50871b19 (diff)
multiarc - yet more refactoring and optimizations
Diffstat (limited to 'utils')
-rw-r--r--utils/CMakeLists.txt1
-rw-r--r--utils/include/PathParts.h51
-rw-r--r--utils/include/utils.h11
-rw-r--r--utils/src/PathParts.cpp51
4 files changed, 114 insertions, 0 deletions
diff --git a/utils/CMakeLists.txt b/utils/CMakeLists.txt
index 984efab8..44333da9 100644
--- a/utils/CMakeLists.txt
+++ b/utils/CMakeLists.txt
@@ -29,6 +29,7 @@ set(SOURCES
src/FSNotify.cpp
src/TestPath.cpp
src/PipeIPC.cpp
+ src/PathParts.cpp
)
add_library (utils ${SOURCES})
diff --git a/utils/include/PathParts.h b/utils/include/PathParts.h
new file mode 100644
index 00000000..f5aeae5d
--- /dev/null
+++ b/utils/include/PathParts.h
@@ -0,0 +1,51 @@
+#pragma once
+#include <vector>
+#include <string>
+#include <map>
+
+struct PathParts : std::vector<std::string>
+{
+ void Traverse(const std::string &path);
+
+ std::string Join() const;
+ bool Starts(PathParts &root) const;
+};
+
+///
+
+template <class PathNodeAttributesT> struct PathNode;
+
+template <class PathNodeAttributesT>
+ struct PathNode : PathNodeAttributesT, std::map<std::string, PathNode<PathNodeAttributesT> >
+{
+ PathNode<PathNodeAttributesT> *Find(PathParts::const_iterator root, PathParts::const_iterator edge)
+ {
+ if (root == edge)
+ return this;
+
+ auto it = std::map<std::string, PathNode<PathNodeAttributesT> >::find(*root);
+ if (it == std::map<std::string, PathNode<PathNodeAttributesT> >::end())
+ return nullptr;
+
+ ++root;
+ return it->second.Find(root, edge);
+ }
+
+ PathNode<PathNodeAttributesT> *Ensure(PathParts::const_iterator root, PathParts::const_iterator edge)
+ {
+ if (root == edge)
+ return this;
+
+ auto &subnode = std::map<std::string, PathNode<PathNodeAttributesT> >::operator[](*root);
+
+ ++root;
+ return subnode.Ensure(root, edge);
+ }
+
+ void Clear()
+ {
+ std::map<std::string, PathNode<PathNodeAttributesT> >::clear();
+ PathNodeAttributesT::operator =(PathNodeAttributesT());
+ }
+};
+
diff --git a/utils/include/utils.h b/utils/include/utils.h
index edd1c68e..5e305730 100644
--- a/utils/include/utils.h
+++ b/utils/include/utils.h
@@ -317,4 +317,15 @@ template <class STRING_T, typename ARRAY_T>
return s.size() == l && s.compare(0, std::string::npos, a, l) == 0;
}
+template <typename ARRAY_T, class CHAR_T>
+ void ArrayCpyZ(ARRAY_T &dst, const CHAR_T *src)
+{
+ static_assert ( sizeof(dst) != sizeof(void *), "ArrayCpyZ should be used with arrays but not pointers");
+ size_t i;
+ for (i = 0; src[i] && i + 1 < ARRAYSIZE(dst); ++i) {
+ dst[i] = src[i];
+ }
+ dst[i] = 0;
+}
+
#define DBGLINE fprintf(stderr, "%d %d @%s\n", getpid(), __LINE__, __FILE__)
diff --git a/utils/src/PathParts.cpp b/utils/src/PathParts.cpp
new file mode 100644
index 00000000..94b834ee
--- /dev/null
+++ b/utils/src/PathParts.cpp
@@ -0,0 +1,51 @@
+#include "PathParts.h"
+#include "utils.h"
+
+void PathParts::Traverse(const std::string &path)
+{
+ size_t i = size();
+ StrExplode(*this, path, "/");
+ while (i < size()) {
+ if (operator[](i) == ".") {
+ erase(begin() + i);
+
+ } else if (operator[](i) == "..") {
+ erase(begin() + i);
+ if (i != 0) {
+ erase(begin() + i - 1);
+ --i;
+ } else {
+ fprintf(stderr, "PathParts::Traverse: impossible <..> in '%s'\n", path.c_str());
+ }
+ } else {
+ ++i;
+ }
+ }
+}
+
+bool PathParts::Starts(PathParts &root) const
+{
+ if (size() < root.size()) {
+ return false;
+ }
+
+ for (size_t i = 0; i != root.size(); ++i) {
+ if (operator[](i) != root[i]) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+std::string PathParts::Join() const
+{
+ std::string out;
+ for (const auto &p : *this) {
+ if (!out.empty()) {
+ out+= '/';
+ }
+ out+= p;
+ }
+ return out;
+}