#ifndef UTIL_H #define UTIL_H #include #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; } std::string conf_format(const std::string& fmt, const std::map& vars) { std::string result; result.reserve(fmt.length()); for (size_t i = 0; i < fmt.length(); ++i) { if (fmt[i] != '%') { result += fmt[i]; continue; } // Handle %% -> % if (i + 1 < fmt.length() && fmt[i + 1] == '%') { result += '%'; i++; continue; } // Look for variable name if (i + 1 < fmt.length()) { size_t start = i + 1; size_t end = start; // Find the end of the variable name while (end < fmt.length() && (isalnum(fmt[end]) || fmt[end] == '_')) { end++; } if (end > start) { std::string var = fmt.substr(start, end - start); auto it = vars.find(var); if (it != vars.end()) { result += it->second; } else { // Keep the original %var if not found result += fmt.substr(i, end - i); } i = end - 1; continue; } } // If we get here, it's a single % with no variable result += '%'; } return result; } 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(); } std::string getCurrentUTCTime() { auto now = std::chrono::system_clock::now(); auto time = std::chrono::system_clock::to_time_t(now); std::string result(9, '\0'); strftime(&result[0], result.size(), "%H:%M:%S", gmtime(&time)); return result; } std::string getCurrentUTCDate() { auto now = std::chrono::system_clock::now(); auto time = std::chrono::system_clock::to_time_t(now); std::string result(11, '\0'); strftime(&result[0], result.size(), "%Y-%m-%d", gmtime(&time)); return result; } 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