2023-12-30 22:42:11 +00:00
|
|
|
//SPDX-FileCopyrightText: 2023 Yury Gubich <blue@macaw.me>
|
|
|
|
//SPDX-License-Identifier: GPL-3.0-or-later
|
2023-12-10 23:23:15 +00:00
|
|
|
|
|
|
|
#include "helpers.h"
|
|
|
|
|
|
|
|
#include "iostream"
|
2023-12-11 23:29:55 +00:00
|
|
|
#include <functional>
|
2023-12-10 23:23:15 +00:00
|
|
|
|
|
|
|
#include "config.h"
|
|
|
|
|
|
|
|
static bool installed = false;
|
|
|
|
static std::filesystem::path sPath;
|
|
|
|
|
2023-12-11 23:29:55 +00:00
|
|
|
bool isSpace(char ch){
|
|
|
|
return std::isspace(static_cast<unsigned char>(ch));
|
|
|
|
}
|
|
|
|
|
2023-12-10 23:23:15 +00:00
|
|
|
void setAbsoluteSharedPath () {
|
|
|
|
installed = true;
|
|
|
|
sPath = FULL_DATA_DIR "/" PROJECT_NAME; // should be something like /usr/share/pica or /local/usr/share/pica
|
|
|
|
}
|
|
|
|
|
|
|
|
void initPaths(const char* programPath) {
|
|
|
|
std::filesystem::path pp(programPath);
|
|
|
|
if (pp.filename() == programPath)
|
|
|
|
return setAbsoluteSharedPath();
|
|
|
|
|
|
|
|
std::filesystem::path cp;
|
|
|
|
try {
|
|
|
|
cp = std::filesystem::canonical(pp);
|
|
|
|
} catch (const std::filesystem::filesystem_error& e) {
|
|
|
|
setAbsoluteSharedPath();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (cp.parent_path() == FULL_BIN_DIR)
|
|
|
|
return setAbsoluteSharedPath();
|
|
|
|
|
2024-01-11 21:33:46 +00:00
|
|
|
//std::cout << cp << std::endl;
|
2023-12-10 23:23:15 +00:00
|
|
|
std::filesystem::path parent = cp.parent_path();
|
|
|
|
if (endsWith(parent.string(), BIN_DIR)) { //this is the case when the program is installed somewhere but not system root
|
|
|
|
std::filesystem::path bin(BIN_DIR); //so it will read from something like ../share/pica/ relative to the binary
|
|
|
|
for (const auto& hop : bin) {
|
2023-12-11 23:29:55 +00:00
|
|
|
UNUSED(hop); //I do this just to make as many ups as many members are in bin
|
2023-12-10 23:23:15 +00:00
|
|
|
parent = parent.parent_path();
|
|
|
|
}
|
|
|
|
sPath = parent / DATA_DIR / PROJECT_NAME;
|
|
|
|
} else {
|
|
|
|
sPath = parent / DATA_DIR; //this should read something like ./share relative to the binary
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const std::filesystem::path& sharedPath() {
|
|
|
|
return sPath;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool endsWith(const std::string& string, const std::string& query) {
|
|
|
|
std::string::size_type sl = string.length();
|
|
|
|
std::string::size_type ql = query.length();
|
|
|
|
if (sl >= ql) {
|
|
|
|
unsigned int result = string.compare(sl - ql, ql, query);
|
|
|
|
return result == 0;
|
|
|
|
} else {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
2023-12-11 23:29:55 +00:00
|
|
|
|
|
|
|
void ltrim(std::string& string) {
|
|
|
|
string.erase(
|
|
|
|
string.begin(),
|
|
|
|
std::find_if(
|
|
|
|
string.begin(),
|
|
|
|
string.end(),
|
|
|
|
std::not_fn(isSpace)
|
|
|
|
)
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
void rtrim(std::string& string) {
|
|
|
|
string.erase(
|
|
|
|
std::find_if(
|
|
|
|
string.rbegin(),
|
|
|
|
string.rend(),
|
|
|
|
std::not_fn(isSpace)
|
|
|
|
).base(),
|
|
|
|
string.end()
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
void trim(std::string& string) {
|
|
|
|
ltrim(string);
|
|
|
|
rtrim(string);
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string extract(std::string& string, std::string::size_type begin, std::string::size_type end) {
|
|
|
|
std::string result = string.substr(begin, end);
|
|
|
|
if (end == std::string::npos)
|
|
|
|
string.erase(begin, end);
|
|
|
|
else
|
|
|
|
string.erase(begin, result.length() + 1);
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|