134 lines
3.8 KiB
C++
134 lines
3.8 KiB
C++
#include "argparse_util.hpp"
|
|
#include <cstring>
|
|
#include <algorithm>
|
|
|
|
namespace argparse {
|
|
|
|
std::array<std::string,2> split_leading_dashes(std::string str) {
|
|
auto iter = str.begin();
|
|
while(*iter == '-') {
|
|
++iter;
|
|
}
|
|
|
|
std::string dashes(str.begin(), iter);
|
|
std::string name(iter, str.end());
|
|
std::array<std::string,2> array = {dashes, name};
|
|
|
|
return array;
|
|
}
|
|
|
|
bool is_argument(std::string str, const std::map<std::string,std::shared_ptr<Argument>>& arg_map) {
|
|
|
|
for (const auto& kv : arg_map) {
|
|
auto iter = arg_map.find(str);
|
|
|
|
if (iter != arg_map.end()) {
|
|
//Exact match to short/long option
|
|
return true;
|
|
}
|
|
|
|
if (kv.first.size() == 2 && kv.first[0] == '-') {
|
|
//Check iff this is a short option with no spaces
|
|
if (str[0] == kv.first[0] && str[1] == kv.first[1]) {
|
|
//Matches first two characters
|
|
return true;
|
|
}
|
|
}
|
|
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool is_valid_choice(std::string str, const std::vector<std::string>& choices) {
|
|
if (choices.empty()) return true;
|
|
|
|
auto find_iter = std::find(choices.begin(), choices.end(), str);
|
|
if (find_iter == choices.end()) {
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
std::string toupper(std::string str) {
|
|
std::string upper;
|
|
for (size_t i = 0; i < str.size(); ++i) {
|
|
char C = ::toupper(str[i]);
|
|
upper.push_back(C);
|
|
}
|
|
return upper;
|
|
}
|
|
|
|
std::string tolower(std::string str) {
|
|
std::string lower;
|
|
for (size_t i = 0; i < str.size(); ++i) {
|
|
char C = ::tolower(str[i]);
|
|
lower.push_back(C);
|
|
}
|
|
return lower;
|
|
}
|
|
|
|
char* strdup(const char* str) {
|
|
size_t len = std::strlen(str);
|
|
char* res = new char[len+1]; //+1 for terminator
|
|
std::strcpy(res, str);
|
|
return res;
|
|
}
|
|
|
|
std::vector<std::string> wrap_width(std::string str, size_t width, std::vector<std::string> break_strs) {
|
|
std::vector<std::string> wrapped_lines;
|
|
|
|
size_t start = 0;
|
|
size_t end = 0;
|
|
size_t last_break = 0;
|
|
for(end = 0; end < str.size(); ++end) {
|
|
|
|
size_t len = end - start;
|
|
|
|
if (len > width) {
|
|
auto wrapped_line = std::string(str, start, last_break - start) + "\n";
|
|
wrapped_lines.push_back(wrapped_line);
|
|
start = last_break;
|
|
}
|
|
|
|
//Find the next break
|
|
for (const auto& brk_str : break_strs) {
|
|
auto pos = str.find(brk_str, end); //FIXME: this is inefficient
|
|
if (pos == end) {
|
|
last_break = end + 1;
|
|
}
|
|
}
|
|
|
|
//If there are embedded new-lines then take them as forced breaks
|
|
char c = str[end];
|
|
if (c == '\n') {
|
|
last_break = end + 1;
|
|
auto wrapped_line = std::string(str, start, last_break - start);
|
|
wrapped_lines.push_back(wrapped_line);
|
|
start = last_break;
|
|
}
|
|
}
|
|
|
|
auto last_line = std::string(str, start, end - start);
|
|
wrapped_lines.push_back(last_line);
|
|
|
|
return wrapped_lines;
|
|
}
|
|
|
|
std::string basename(std::string filepath) {
|
|
#ifdef _WIN32
|
|
//Windows uses back-slash as directory divider
|
|
auto pos = filepath.rfind("\\");
|
|
#else
|
|
//*nix-like uses forward-slash as directory divider
|
|
auto pos = filepath.rfind("/");
|
|
#endif
|
|
if (pos == std::string::npos) {
|
|
pos = 0;
|
|
} else {
|
|
pos += 1;
|
|
}
|
|
|
|
return std::string(filepath, pos, filepath.size() - pos);
|
|
}
|
|
} //namespace
|