#include "utils.hpp" #include #include #include #include #include #include #include #include #include #include #include #include "ilogger.hpp" #include "syslogger.hpp" #include "filelogger.hpp" #include "stderrlogger.hpp" #include "aggregatelogger.hpp" #define MIN(a,b) ((a)<(b)?(a):(b)) vector &split(const string &str_in, char delim, vector &tokens) { #if 0 std::stringstream ss(str_in); string token; tokens.clear(); while(getline(ss, token, delim)) { if(!token.empty()) tokens.push_back(token); } return tokens; #endif string delims(1, delim); return split(str_in, delims, tokens); } vector &split(const string &str_in, const string &delims, vector &tokens) { int start = 0, next_delim_pos; int length = str_in.size(); bool found = false; tokens.clear(); while(true) { found = false; next_delim_pos = INT_MAX; for(int i=0; i<(int)delims.size(); i++) { for(int j=start; j=0; i--) { if(!IS_BLANK(in[i])) { if(i<(int)in.size()-1) in = in.substr(0, i+1); break; } } return in; } string& str_trim(string &in) { return str_trim_right(str_trim_left(in)); } bool str_extract_delimiter_content(const string& base_str, const string& delim0, const string& delim1, string &token) { size_t start = base_str.find(delim0); size_t end = base_str.find(delim1, start+delim0.size()); if(start == string::npos || end == string::npos) return false; token = base_str.substr(start + 1, end - start - 1); return true; } bool str_extract_before(const string& base_str, const string& delim, string &token, bool empty_token_if_delim_not_found) { string base_copy = base_str; return str_chop_before(base_copy, delim, token, false, empty_token_if_delim_not_found); } bool str_extract_after(const string& base_str, const string& delim, string &token, bool empty_token_if_delim_not_found) { string base_copy = base_str; return str_chop_after(base_copy, delim, token, false, empty_token_if_delim_not_found); } bool str_chop_before(string& base_str, const string& delim, string &token, bool throw_delim_away, bool empty_token_if_delim_not_found) { token = ""; size_t end = base_str.find(delim); if(end != string::npos) { token = base_str.substr(0, end); if(throw_delim_away) base_str = base_str.substr(end+delim.size()); else base_str = base_str.substr(end); return token != ""; } if(!empty_token_if_delim_not_found) { token = base_str; base_str = ""; } return token != ""; } bool str_chop_after(string& base_str, const string& delim, string &token, bool throw_delim_away, bool empty_token_if_delim_not_found) { token = ""; size_t start = base_str.find(delim); if(start != string::npos) { token = base_str.substr(start + delim.size()); if(throw_delim_away) base_str = base_str.substr(0, start); else base_str = base_str.substr(0, start + delim.size()); return token != ""; } if(!empty_token_if_delim_not_found) { token = base_str; base_str = ""; } return token != ""; } bool is_int(const string& in) { if(in.size() == 0) return false; for(int i=0; i<(int)in.size(); i++) if(!isdigit(in[i])) return false; return true; } bool is_double(const string& in) { if(in.size() == 0) return false; if(!isdigit(in[0])) return false; int nb_dots = 0; for(int i=1; i<(int)in.size(); i++) { if(!isdigit(in[i]) && in[i] != '.') return false; if(in[i] == '.') nb_dots++; } return nb_dots <= 1; } string& make_debug_message(string& initial_message, string& out, const char* filename, int lineno) { std::ostringstream oss; oss<<"[DEBUG - "< tokens; split(command, ' ', tokens); assert((int)tokens.size() < MAX_ARGS); int i; for(i=0; i<(int)tokens.size(); i++) argv[i] = tokens[i].c_str(); argv[i] = NULL; pipe(pipefd); pid = fork(); if(pid == 0) { dup2(pipefd[0], STDOUT_FILENO); dup2(pipefd[1], STDERR_FILENO); execl("/usr/bin/tail", "/usr/bin/tail", "-f", "path/to/your/file", (char*) NULL); } //Only parent gets here. Listen to what the tail says close(pipefd[1]); output = fdopen(pipefd[0], "r"); while(fgets(line, sizeof(line), output)) //listen to what tail writes to its standard output { //if you need to kill the tail application, just kill it: if(something_goes_wrong) kill(pid, SIGKILL); } //or wait for the child process to terminate waitpid(pid, &status, 0); } #endif /*MISC*/ char _hostname[1025]; string hostname = ""; const string* const get_hostname() { if(hostname == "") { if(gethostname(_hostname, 1024)) ASSERT_ERRNO("gethostname failed"); hostname = _hostname; } return &hostname; } /*MISC*/ /* STRINGIFY*/ string log_dest_to_str(Log_dest dest) { switch(dest) { case LOG_DEST_DEV_NULL: return "LOG_DEST_DEV_NULL"; case LOG_DEST_SYSLOG: return "LOG_DEST_SYSLOG"; case LOG_DEST_STDERR: return "LOG_DEST_STDERR"; case LOG_DEST_FILE: return "LOG_DEST_FILE"; } assert(false); return "WTH! INVALID_LOG_DEST"; } string non_composite_log_type_to_str(Log_type type, bool empty_on_invalid = true) { switch(type) { case LOG_TYPE_INVALID: return empty_on_invalid? "": "LOG_TYPE_INVALID"; case LOG_TYPE_INFO: return "INFO"; case LOG_TYPE_WARNING: return "WARNING"; case LOG_TYPE_ERROR: return "ERROR"; case LOG_TYPE_DEBUG: return "DEBUG"; } assert(false); return "WTH! INVALID LOG TYPE"; } string log_type_to_str(Log_type type) { if(type == LOG_TYPE_INVALID) return "LOG_TYPE_INVALID"; string ret = ""; string temp; Log_type lts[] = {LOG_TYPE_INFO, LOG_TYPE_WARNING, LOG_TYPE_ERROR, LOG_TYPE_DEBUG}; int nb = sizeof(lts)/sizeof(Log_type); for(int i=0; i< nb; i++) { temp = non_composite_log_type_to_str( type & lts[i]); if(temp != "") { if(ret != "") ret += ("|"+temp); else ret = temp; } } return ret; } void stringify_int_list(const vector& list, char separator, string &out) { if(list.size() == 0) { out = ""; return; } std::ostringstream ss; ss<& vect, string& str, const string& header) { string offset=""; for(int i=0; i<(int)header.size(); i++) offset += ' '; int max_per_line = 10; int i, j; std::ostringstream ss; for(i=0, j=0; i<(int)vect.size(); i++, j++) { if(j == max_per_line) { ss< tokens; split(str, " \t", tokens); return atoi(tokens[1].c_str()); } } file.close(); return UID_INVALID; } /*END SOME FILE I/O*/ /*FILESYSTEM*/ int mkdir_p(string path, mode_t mode) { int ret = mkdir(path.c_str(), mode); if(ret == 0 || errno == EEXIST) return ret; if(errno != ENOENT) return ret; vector tokens; split(path, '/', tokens); string cur = ""; if(path[0] == '/') cur="/"; for(int i=0; i<(int)tokens.size(); i++) { cur += tokens[i]; cur += '/'; ret = mkdir(cur.c_str(), mode); if(ret != 0 && errno != EEXIST) return ret; } return ret; } /*END FILESYSTEM*/ /*END SOME FILE I/O*/