Add file and string utility functions
parent
f559730d2f
commit
b5bfd437a6
@ -0,0 +1,99 @@
|
||||
#include "file_utils.h"
|
||||
#include "string_utils.h"
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <dirent.h>
|
||||
#include <linux/limits.h>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <cstring>
|
||||
|
||||
std::string read_line(const std::string& filename)
|
||||
{
|
||||
std::string line;
|
||||
std::ifstream file(filename);
|
||||
std::getline(file, line);
|
||||
return line;
|
||||
}
|
||||
|
||||
bool find_folder(const char* root, const char* prefix, std::string& dest)
|
||||
{
|
||||
struct dirent* dp;
|
||||
DIR* dirp = opendir(root);
|
||||
if (!dirp) {
|
||||
std::cerr << "Error opening directory '" << root << "': ";
|
||||
perror("");
|
||||
return false;
|
||||
}
|
||||
|
||||
while ((dp = readdir(dirp))) {
|
||||
if ((dp->d_type == DT_LNK || dp->d_type == DT_DIR) && starts_with(dp->d_name, prefix)) {
|
||||
dest = dp->d_name;
|
||||
closedir(dirp);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
closedir(dirp);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool find_folder(const std::string& root, const std::string& prefix, std::string& dest)
|
||||
{
|
||||
return find_folder(root.c_str(), prefix.c_str(), dest);
|
||||
}
|
||||
|
||||
std::vector<std::string> ls(const char* root, const char* prefix, LS_FLAGS flags)
|
||||
{
|
||||
std::vector<std::string> list;
|
||||
struct dirent* dp;
|
||||
|
||||
DIR* dirp = opendir(root);
|
||||
if (!dirp) {
|
||||
std::cerr << "Error opening directory '" << root << "': ";
|
||||
perror("");
|
||||
return list;
|
||||
}
|
||||
|
||||
while ((dp = readdir(dirp))) {
|
||||
if (dp->d_type == DT_LNK) {
|
||||
struct stat s;
|
||||
std::string path(root);
|
||||
if (path.back() != '/')
|
||||
path += "/";
|
||||
path += dp->d_name;
|
||||
|
||||
if (stat(path.c_str(), &s))
|
||||
continue;
|
||||
|
||||
if (((flags & LS_DIRS) && S_ISDIR(s.st_mode))
|
||||
|| ((flags & LS_FILES) && !S_ISDIR(s.st_mode))) {
|
||||
list.push_back(dp->d_name);
|
||||
}
|
||||
} else if (((flags & LS_DIRS) && dp->d_type == DT_DIR)
|
||||
|| ((flags & LS_FILES) && dp->d_type == DT_REG)
|
||||
) {
|
||||
if ((prefix && !starts_with(dp->d_name, prefix))
|
||||
|| !strcmp(dp->d_name, ".")
|
||||
|| !strcmp(dp->d_name, ".."))
|
||||
continue;
|
||||
list.push_back(dp->d_name);
|
||||
}
|
||||
}
|
||||
|
||||
closedir(dirp);
|
||||
return list;
|
||||
}
|
||||
|
||||
bool file_exists(const std::string& path)
|
||||
{
|
||||
struct stat s;
|
||||
return !stat(path.c_str(), &s) && !S_ISDIR(s.st_mode);
|
||||
}
|
||||
|
||||
bool dir_exists(const std::string& path)
|
||||
{
|
||||
struct stat s;
|
||||
return !stat(path.c_str(), &s) && S_ISDIR(s.st_mode);
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
enum LS_FLAGS
|
||||
{
|
||||
LS_ALL = 0x00,
|
||||
LS_DIRS = 0x01,
|
||||
LS_FILES = 0x02,
|
||||
};
|
||||
|
||||
std::string read_line(const std::string& filename);
|
||||
bool find_folder(const char* root, const char* prefix, std::string& dest);
|
||||
bool find_folder(const std::string& root, const std::string& prefix, std::string& dest);
|
||||
std::vector<std::string> ls(const char* root, const char* prefix = nullptr, LS_FLAGS flags = LS_DIRS);
|
||||
bool file_exists(const std::string& path);
|
||||
bool dir_exists(const std::string& path);
|
@ -0,0 +1,76 @@
|
||||
#pragma once
|
||||
#include <string>
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <algorithm>
|
||||
#include <cctype>
|
||||
#include <locale>
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wunused-function"
|
||||
|
||||
// https://stackoverflow.com/questions/216823/whats-the-best-way-to-trim-stdstring#217605
|
||||
// trim from start (in place)
|
||||
static inline void ltrim(std::string &s) {
|
||||
s.erase(s.begin(), std::find_if(s.begin(), s.end(), [](int ch) {
|
||||
return !std::isspace(ch);
|
||||
}));
|
||||
}
|
||||
|
||||
// trim from end (in place)
|
||||
static inline void rtrim(std::string &s) {
|
||||
s.erase(std::find_if(s.rbegin(), s.rend(), [](int ch) {
|
||||
return !std::isspace(ch);
|
||||
}).base(), s.end());
|
||||
}
|
||||
|
||||
// trim from both ends (in place)
|
||||
static inline void trim(std::string &s) {
|
||||
ltrim(s);
|
||||
rtrim(s);
|
||||
}
|
||||
|
||||
// trim from start (copying)
|
||||
static inline std::string ltrim_copy(std::string s) {
|
||||
ltrim(s);
|
||||
return s;
|
||||
}
|
||||
|
||||
// trim from end (copying)
|
||||
static inline std::string rtrim_copy(std::string s) {
|
||||
rtrim(s);
|
||||
return s;
|
||||
}
|
||||
|
||||
// trim from both ends (copying)
|
||||
static inline std::string trim_copy(std::string s) {
|
||||
trim(s);
|
||||
return s;
|
||||
}
|
||||
|
||||
static bool starts_with(const std::string& s, const char *t) {
|
||||
return s.rfind(t, 0) == 0;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static std::string itox(T i) {
|
||||
std::stringstream ss;
|
||||
ss << "0x"
|
||||
<< std::setfill ('0') << std::setw(sizeof(T) * 2)
|
||||
<< std::hex << i;
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
static bool try_stoi(int& val, const std::string& str, std::size_t* pos = 0, int base = 10)
|
||||
{
|
||||
try {
|
||||
val = std::stoi(str, pos, base);
|
||||
return true;
|
||||
} catch (std::invalid_argument& e) {
|
||||
std::cerr << __func__ << ": invalid argument: '" << str << "'" << std::endl;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#pragma GCC diagnostic pop
|
Loading…
Reference in New Issue