MatN work for versatile appimage creation for all types of os
[goodguy/cinelerra.git] / cinelerra-5.1 / tools / makeappimagetool / includes / misc.h
1 #pragma once
2
3 // system headers
4 #include <algorithm>
5 #include <climits>
6 #include <cstring>
7 #include <sstream>
8 #include <string>
9 #include <unistd.h>
10 #include <vector>
11
12 // libraries
13 #include <boost/filesystem.hpp>
14
15 namespace linuxdeploy {
16     namespace util {
17         namespace misc {
18             static inline bool ltrim(std::string& s, char to_trim = ' ') {
19                 // TODO: find more efficient way to check whether elements have been removed
20                 size_t initialLength = s.length();
21                 s.erase(s.begin(), std::find_if(s.begin(), s.end(), [to_trim](int ch) {
22                     return ch != to_trim;
23                 }));
24                 return s.length() < initialLength;
25             }
26
27             static inline bool rtrim(std::string& s, char to_trim = ' ') {
28                 // TODO: find more efficient way to check whether elements have been removed
29                 auto initialLength = s.length();
30                 s.erase(std::find_if(s.rbegin(), s.rend(), [to_trim](int ch) {
31                     return ch != to_trim;
32                 }).base(), s.end());
33                 return s.length() < initialLength;
34             }
35
36             static inline bool trim(std::string& s, char to_trim = ' ') {
37                 // returns true if either modifies s
38                 auto ltrim_result = ltrim(s, to_trim);
39                 return rtrim(s, to_trim) && ltrim_result;
40             }
41
42             static std::vector<std::string> split(const std::string& s, char delim = ' ') {
43                 std::vector<std::string> result;
44
45                 std::stringstream ss(s);
46                 std::string item;
47
48                 while (std::getline(ss, item, delim)) {
49                     result.push_back(item);
50                 }
51
52                 return result;
53             }
54
55             static std::vector<std::string> splitLines(const std::string& s) {
56                 return split(s, '\n');
57             }
58
59             static std::string join(const std::vector<std::string> &strings, const std::string &delimiter) {
60                 std::string result;
61                 for (size_t i = 0; i < strings.size(); i++) {
62                     result += strings[i];
63
64                     if (i != strings.size() - 1) {
65                         result += delimiter;
66                     }
67                 }
68                 return result;
69             }
70
71             static inline std::string strLower(std::string s) {
72                 std::transform(s.begin(), s.end(), s.begin(), [](unsigned char c) { return std::tolower(c); });
73                 return s;
74             }
75
76             static bool stringStartsWith(const std::string& string, const std::string& prefix) {
77                 // sanity check
78                 if (string.size() < prefix.size())
79                     return false;
80
81                 return strncmp(string.c_str(), prefix.c_str(), prefix.size()) == 0;
82             }
83
84             static bool stringEndsWith(const std::string& string, const std::string& suffix) {
85                 // sanity check
86                 if (string.size() < suffix.size())
87                     return false;
88
89                 return strcmp(string.c_str() + (string.size() - suffix.size()), suffix.c_str()) == 0;
90             }
91
92             static bool stringContains(const std::string& string, const std::string& part) {
93                 return string.find(part) != std::string::npos;
94             }
95
96             static std::string getOwnExecutablePath() {
97                 // FIXME: reading /proc/self/exe line is Linux specific
98                 std::vector<char> buf(PATH_MAX, '\0');
99
100                 if (readlink("/proc/self/exe", buf.data(), buf.size()) < 0) {
101                     return "";
102                 }
103
104                 return buf.data();
105             }
106
107             // very simple but for our purposes good enough which like algorithm to find binaries in $PATH
108             static boost::filesystem::path which(const std::string& name) {
109                 const auto* path = getenv("PATH");
110
111                 namespace bf = boost::filesystem;
112
113                 if (path == nullptr)
114                     return "";
115
116                 for (const auto& binDir : split(path, ':')) {
117                     if (!bf::is_directory(binDir)) {
118                         continue;
119                     }
120
121                     for (bf::directory_iterator it(binDir); it != bf::directory_iterator{}; ++it) {
122                         const auto binary = it->path();
123
124                         if (binary.filename() == name) {
125                             // TODO: check if file is executable (skip otherwise)
126                             return binary;
127                         }
128                     }
129                 }
130
131                 return {};
132             };
133         }
134     }
135 }