MatN work for versatile appimage creation for all types of os
[goodguy/cinelerra.git] / cinelerra-5.1 / tools / makeappimagetool / includes / misc.h
diff --git a/cinelerra-5.1/tools/makeappimagetool/includes/misc.h b/cinelerra-5.1/tools/makeappimagetool/includes/misc.h
new file mode 100644 (file)
index 0000000..0d7e5f6
--- /dev/null
@@ -0,0 +1,135 @@
+#pragma once
+
+// system headers
+#include <algorithm>
+#include <climits>
+#include <cstring>
+#include <sstream>
+#include <string>
+#include <unistd.h>
+#include <vector>
+
+// libraries
+#include <boost/filesystem.hpp>
+
+namespace linuxdeploy {
+    namespace util {
+        namespace misc {
+            static inline bool ltrim(std::string& s, char to_trim = ' ') {
+                // TODO: find more efficient way to check whether elements have been removed
+                size_t initialLength = s.length();
+                s.erase(s.begin(), std::find_if(s.begin(), s.end(), [to_trim](int ch) {
+                    return ch != to_trim;
+                }));
+                return s.length() < initialLength;
+            }
+
+            static inline bool rtrim(std::string& s, char to_trim = ' ') {
+                // TODO: find more efficient way to check whether elements have been removed
+                auto initialLength = s.length();
+                s.erase(std::find_if(s.rbegin(), s.rend(), [to_trim](int ch) {
+                    return ch != to_trim;
+                }).base(), s.end());
+                return s.length() < initialLength;
+            }
+
+            static inline bool trim(std::string& s, char to_trim = ' ') {
+                // returns true if either modifies s
+                auto ltrim_result = ltrim(s, to_trim);
+                return rtrim(s, to_trim) && ltrim_result;
+            }
+
+            static std::vector<std::string> split(const std::string& s, char delim = ' ') {
+                std::vector<std::string> result;
+
+                std::stringstream ss(s);
+                std::string item;
+
+                while (std::getline(ss, item, delim)) {
+                    result.push_back(item);
+                }
+
+                return result;
+            }
+
+            static std::vector<std::string> splitLines(const std::string& s) {
+                return split(s, '\n');
+            }
+
+            static std::string join(const std::vector<std::string> &strings, const std::string &delimiter) {
+                std::string result;
+                for (size_t i = 0; i < strings.size(); i++) {
+                    result += strings[i];
+
+                    if (i != strings.size() - 1) {
+                        result += delimiter;
+                    }
+                }
+                return result;
+            }
+
+            static inline std::string strLower(std::string s) {
+                std::transform(s.begin(), s.end(), s.begin(), [](unsigned char c) { return std::tolower(c); });
+                return s;
+            }
+
+            static bool stringStartsWith(const std::string& string, const std::string& prefix) {
+                // sanity check
+                if (string.size() < prefix.size())
+                    return false;
+
+                return strncmp(string.c_str(), prefix.c_str(), prefix.size()) == 0;
+            }
+
+            static bool stringEndsWith(const std::string& string, const std::string& suffix) {
+                // sanity check
+                if (string.size() < suffix.size())
+                    return false;
+
+                return strcmp(string.c_str() + (string.size() - suffix.size()), suffix.c_str()) == 0;
+            }
+
+            static bool stringContains(const std::string& string, const std::string& part) {
+                return string.find(part) != std::string::npos;
+            }
+
+            static std::string getOwnExecutablePath() {
+                // FIXME: reading /proc/self/exe line is Linux specific
+                std::vector<char> buf(PATH_MAX, '\0');
+
+                if (readlink("/proc/self/exe", buf.data(), buf.size()) < 0) {
+                    return "";
+                }
+
+                return buf.data();
+            }
+
+            // very simple but for our purposes good enough which like algorithm to find binaries in $PATH
+            static boost::filesystem::path which(const std::string& name) {
+                const auto* path = getenv("PATH");
+
+                namespace bf = boost::filesystem;
+
+                if (path == nullptr)
+                    return "";
+
+                for (const auto& binDir : split(path, ':')) {
+                    if (!bf::is_directory(binDir)) {
+                        continue;
+                    }
+
+                    for (bf::directory_iterator it(binDir); it != bf::directory_iterator{}; ++it) {
+                        const auto binary = it->path();
+
+                        if (binary.filename() == name) {
+                            // TODO: check if file is executable (skip otherwise)
+                            return binary;
+                        }
+                    }
+                }
+
+                return {};
+            };
+        }
+    }
+}