added real_path function; bumped version to 1.1

This commit is contained in:
Bob Polis 2020-08-23 17:21:19 +02:00
parent 66f0de4970
commit 6e0c828404
3 changed files with 80 additions and 74 deletions

View File

@ -1,6 +1,6 @@
LIBNAME := $(shell basename $$(pwd)) LIBNAME := $(shell basename $$(pwd))
MAJOR := 1 MAJOR := 1
MINOR := 0.0 MINOR := 1.0
UNAME_S := $(shell uname -s) UNAME_S := $(shell uname -s)

View File

@ -17,38 +17,38 @@ using namespace std;
vector<string> sc::split(const string& str, const string& sep) vector<string> sc::split(const string& str, const string& sep)
{ {
vector<string> components; vector<string> components;
string::size_type start = 0; string::size_type start = 0;
string::size_type pos = str.find(sep); string::size_type pos = str.find(sep);
while (pos != string::npos) { // found separator => add substring to vector while (pos != string::npos) { // found separator => add substring to vector
components.push_back(str.substr(start, pos - start)); components.push_back(str.substr(start, pos - start));
start = pos + sep.length(); // next search starts just after found separator start = pos + sep.length(); // next search starts just after found separator
pos = str.find(sep, start); pos = str.find(sep, start);
} }
// at end of string => add last component // at end of string => add last component
components.push_back(str.substr(start, str.length() - start)); components.push_back(str.substr(start, str.length() - start));
return components; return components;
} }
vector<string> sc::split(const string& str, const regex& sep) { vector<string> sc::split(const string& str, const regex& sep) {
vector<string> components; vector<string> components;
sregex_token_iterator end {}; sregex_token_iterator end {};
for (sregex_token_iterator p {str.begin(), str.end(), sep, -1}; p != end; ++p) { for (sregex_token_iterator p {str.begin(), str.end(), sep, -1}; p != end; ++p) {
components.push_back(*p); components.push_back(*p);
} }
return components; return components;
} }
string sc::join(const vector<string>& components, const string& join) string sc::join(const vector<string>& components, const string& join)
{ {
string result; string result;
for (vector<string>::const_iterator i = components.cbegin(); i != components.cend(); ++i) { for (vector<string>::const_iterator i = components.cbegin(); i != components.cend(); ++i) {
if (i != components.cbegin()) { if (i != components.cbegin()) {
result += join; result += join;
} }
result += *i; result += *i;
} }
return result; return result;
} }
string sc::trim(const string& str, const string& del) string sc::trim(const string& str, const string& del)
@ -78,8 +78,8 @@ string sc::file_get_contents(const string& path)
{ {
ifstream file {path}; ifstream file {path};
file.exceptions(ios::failbit | ios::badbit); file.exceptions(ios::failbit | ios::badbit);
file.seekg(0, ios::end); file.seekg(0, ios::end);
ios::pos_type file_len {file.tellg()}; ios::pos_type file_len {file.tellg()};
file.seekg(0); file.seekg(0);
vector<char> buf; vector<char> buf;
buf.resize(file_len); buf.resize(file_len);
@ -92,7 +92,7 @@ map<string, string> sc::parse_ini_file(const string& path)
map<string, string> result; map<string, string> result;
string line; string line;
ifstream file {path}; ifstream file {path};
file.exceptions(/*ios::failbit |*/ ios::badbit); // it seems that getline() will set failbit when confronted with eof immediately file.exceptions(/*ios::failbit |*/ ios::badbit); // it seems that getline() will set failbit when confronted with eof immediately
while (getline(file, line)) { while (getline(file, line)) {
if (line[0] == '[') continue; if (line[0] == '[') continue;
vector<string> parts {split(line, "=")}; vector<string> parts {split(line, "=")};
@ -114,27 +114,27 @@ string sc::str_replace(const string& what, const string& replacement, const stri
result += target.substr(from, pos - from); result += target.substr(from, pos - from);
result += replacement; result += replacement;
from = pos + what.length(); from = pos + what.length();
if (from >= target.length()) break; if (from >= target.length()) break;
} }
result += target.substr(from); result += target.substr(from);
return result; return result;
} }
wstring sc::replace_all(const std::wstring& what, wstring sc::replace_all(const std::wstring& what,
const std::wstring& replacement, const std::wstring& replacement,
const std::wstring& target) const std::wstring& target)
{ {
wstring term {target}; wstring term {target};
wstring::size_type pos = wstring::npos; wstring::size_type pos = wstring::npos;
wstring::size_type from = 0; wstring::size_type from = 0;
do { do {
pos = term.find(what, from); pos = term.find(what, from);
if (pos != wstring::npos) { if (pos != wstring::npos) {
term.replace(pos, what.length(), replacement); term.replace(pos, what.length(), replacement);
from = pos + replacement.length(); from = pos + replacement.length();
} }
} while (pos != wstring::npos); } while (pos != wstring::npos);
return term; return term;
} }
void sc::create_dir(const std::string &path, int mode) void sc::create_dir(const std::string &path, int mode)
@ -165,12 +165,12 @@ string sc::dirname(const string& path) {
string sc::basename(const string& path, bool remove_extension) { string sc::basename(const string& path, bool remove_extension) {
string result {path}; string result {path};
if (remove_extension) { if (remove_extension) {
auto dot = path.rfind("."); auto dot = path.rfind(".");
if (dot != string::npos) { if (dot != string::npos) {
result = result.substr(0, dot); result = result.substr(0, dot);
} }
} }
auto pos = result.rfind("/"); auto pos = result.rfind("/");
if (pos != string::npos) { if (pos != string::npos) {
return result.substr(pos + 1); return result.substr(pos + 1);
@ -189,20 +189,16 @@ string sc::replace_tilde(const string& path) {
} }
string sc::filename_extension(const string& path) { string sc::filename_extension(const string& path) {
auto pos = path.rfind("."); auto pos = path.rfind(".");
if (pos != string::npos) { if (pos != string::npos) {
return path.substr(pos); return path.substr(pos);
} }
return ""; return "";
} }
string sc::tool_path(const string& name) { string sc::tool_path(const string& name) {
if (name.find('/') != string::npos) { // name has (at least one) slash if (name.find('/') != string::npos) { // name has (at least one) slash
vector<char> buf; return sc::real_path(name);
buf.resize(PATH_MAX);
if (::realpath(name.c_str(), buf.data())) {
return string(buf.data());
}
} else { // no slash in name => command from PATH? } else { // no slash in name => command from PATH?
string envpath {::getenv("PATH")}; string envpath {::getenv("PATH")};
vector<string> paths {sc::split(envpath, ":")}; vector<string> paths {sc::split(envpath, ":")};
@ -238,7 +234,7 @@ string sc::uppercase(const string& str, const locale& loc) {
} }
bool sc::is_valid_utf8(const string& str) { bool sc::is_valid_utf8(const string& str) {
// From: http://www.zedwood.com/article/cpp-is-valid-utf8-string-function // From: http://www.zedwood.com/article/cpp-is-valid-utf8-string-function
int c,i,ix,n,j; int c,i,ix,n,j;
for (i=0, ix=str.length(); i < ix; i++) for (i=0, ix=str.length(); i < ix; i++)
{ {
@ -259,3 +255,12 @@ bool sc::is_valid_utf8(const string& str) {
} }
return true; return true;
} }
string sc::real_path(const string& path) {
vector<char> buf;
buf.resize(PATH_MAX);
if (::realpath(path.c_str(), buf.data())) {
return string(buf.data());
}
return "";
}

View File

@ -19,27 +19,27 @@ namespace sc {
std::vector<std::string> split (const std::string& str, std::vector<std::string> split (const std::string& str,
const std::string& sep); const std::string& sep);
std::vector<std::string> split (const std::string& str, std::vector<std::string> split (const std::string& str,
const std::regex& sep); const std::regex& sep);
std::string join (const std::vector<std::string>& components, std::string join (const std::vector<std::string>& components,
const std::string& join); const std::string& join);
std::string trim (const std::string& str, std::string trim (const std::string& str,
const std::string& del = " "); const std::string& del = " ");
std::string str_replace (const std::string& what, std::string str_replace (const std::string& what,
const std::string& replacement, const std::string& replacement,
const std::string& target); const std::string& target);
std::wstring replace_all (const std::wstring& what, std::wstring replace_all (const std::wstring& what,
const std::wstring& replacement, const std::wstring& replacement,
const std::wstring& target); const std::wstring& target);
bool file_exists (const std::string& path);
bool file_exists (const std::string& path);
std::string file_get_contents (const std::string& path); std::string file_get_contents (const std::string& path);
std::map<std::string, std::string> parse_ini_file (const std::string& path); std::map<std::string, std::string> parse_ini_file (const std::string& path);
void create_dir (const std::string& path, void create_dir (const std::string& path,
@ -50,8 +50,8 @@ namespace sc {
std::string basename (const std::string& path, bool remove_extension = false); std::string basename (const std::string& path, bool remove_extension = false);
std::string replace_tilde (const std::string& path); std::string replace_tilde (const std::string& path);
std::string filename_extension (const std::string& path); std::string filename_extension (const std::string& path);
std::string tool_path (const std::string& name); std::string tool_path (const std::string& name);
@ -61,8 +61,9 @@ namespace sc {
std::string uppercase (const std::string& str, const std::locale& loc); std::string uppercase (const std::string& str, const std::locale& loc);
bool is_valid_utf8 (const std::string& str); bool is_valid_utf8 (const std::string& str);
std::string real_path (const std::string& path);
} }
#endif // _string_utils_ #endif // _string_utils_