#ifndef UTIL_H #define UTIL_H #include #include #include #include #include #include #include #include std::string replace(std::string subject, const std::string& search, const std::string& replace) { size_t pos = 0; while ((pos = subject.find(search, pos)) != std::string::npos) { subject.replace(pos, search.length(), replace); pos += replace.length(); } return subject; } template void split(const std::string &s, char delim, Out result, int limit) { int it = 0; std::istringstream iss(s); std::string item; while (std::getline(iss, item, delim) && it <= limit) { *result++ = item; if (limit > 0) it++; } } std::vector split(const std::string &s, char delim, int limit) { std::vector elems; split(s, delim, std::back_inserter(elems), limit); return elems; } static std::string toLower(std::string str) { std::transform(str.begin(), str.end(), str.begin(), [](unsigned char c){ return std::tolower(c); }); return str; } static std::string toUpper(std::string str) { std::transform(str.begin(), str.end(), str.begin(), [](unsigned char c){ return std::toupper(c); }); return str; } static std::vector parseArgs(std::string line) { if (line.size() == 0) { return {}; } int state = 0; std::vector result; std::string current; bool lastTokenHasBeenQuoted = false; bool lastTokenWasEscaped = false; for (int i = 0; i < line.size(); i++) { char nextTok = line[i]; switch (state) { case 1: if (nextTok == '\\') { lastTokenWasEscaped = true; } else if (nextTok == '\'' && !lastTokenWasEscaped) { lastTokenHasBeenQuoted = true; state = 0; } else { if (lastTokenWasEscaped) { if (nextTok == 't') nextTok = '\t'; if (nextTok == 'b') nextTok = '\b'; if (nextTok == 'n') nextTok = '\n'; if (nextTok == 'r') nextTok = '\r'; if (nextTok == 'f') nextTok = '\f'; } current.push_back(nextTok); lastTokenWasEscaped = false; } break; case 2: if (nextTok == '\\') { lastTokenWasEscaped = true; } else if (nextTok == '\"' && !lastTokenWasEscaped) { lastTokenHasBeenQuoted = true; state = 0; } else { if (lastTokenWasEscaped) { if (nextTok == 't') nextTok = '\t'; if (nextTok == 'b') nextTok = '\b'; if (nextTok == 'n') nextTok = '\n'; if (nextTok == 'r') nextTok = '\r'; if (nextTok == 'f') nextTok = '\f'; } current.push_back(nextTok); lastTokenWasEscaped = false; } break; default: switch (nextTok) { case '\\': lastTokenWasEscaped = true; break; case '\'': state = 1; break; case '\"': state = 2; break; case ' ': if (!lastTokenWasEscaped && (lastTokenHasBeenQuoted || current.length() != 0)) { result.push_back(current); current = ""; } break; default: if (lastTokenWasEscaped) { if (nextTok == 't') nextTok = '\t'; if (nextTok == 'b') nextTok = '\b'; if (nextTok == 'n') nextTok = '\n'; if (nextTok == 'r') nextTok = '\r'; if (nextTok == 'f') nextTok = '\f'; lastTokenWasEscaped = false; } current.push_back(nextTok); break; } lastTokenHasBeenQuoted = false; break; } } if (lastTokenHasBeenQuoted || current.size() != 0) { result.push_back(current); } return result; } std::string concatPath(std::string dir1, std::string dir2) { return std::filesystem::weakly_canonical(dir1+"/"+dir2).string(); } static char* trim(char *str) { char *end; while(isspace(*str)) str++; if(*str == 0) return str; end = str + strnlen(str, 128) - 1; while(end > str && isspace(*end)) end--; *(end+1) = '\0'; return str; } #endif