#include "utils.h" #include #include #include /* for abs() */ #include /* for strerror_r() */ ///// would not be an improvement ///// due to lack of interger abs() ///// and ambiguous (and inefficient) promotion #include /* for isalnum() */ using namespace std; // strip off the directory part of a path, leaving just // the basic filename string basename(const string path){ size_t where = path.rfind("/"); if (where != string::npos) return path.substr(1+where); return path; } //////////////// // little utility to help with argument parsing: // int prefix(const string shorter, const string longer){ return shorter == longer.substr(0, shorter.length()); } /////////////// // print a time as (-)hh:mm:ss // string time_out(const int _ttt){ int ttt(abs(_ttt)); int sec(ttt % 60); int min((ttt / 60) % 60); int hr(ttt / 3600); stringstream foo; int didsome(0); if (_ttt < 0) foo << "-"; if (hr) { foo << hr << ":"; didsome++; } if (didsome || min){ foo << setw(didsome?2:1) << setfill('0') << min << ":"; didsome++; } foo << setw(didsome?2:1) << setfill('0') << sec; return foo.str(); } string toLower(const string a){ string rslt = a; string::iterator rr; for (rr = rslt.begin(); rr != rslt.end(); rr++){ *rr = tolower(*rr); } return rslt; } string ltrim(const string foo, const string strip){ size_t where = foo.find_first_not_of(strip); if (where == foo.npos) return foo; return foo.substr(where); } string rtrim(const string foo, const string strip){ size_t where = foo.find_last_not_of(strip); if (where == foo.npos) return ""; return foo.substr(0, where+1); } string trim(const string foo, const string bar){ return ltrim(rtrim(foo, bar), bar); } static const string Pure_Enough("+-_.,@%~"); string purify(const string arg){ string rslt(arg); for (string::iterator ptr = rslt.begin(); ptr != rslt.end(); ptr++){ char ch = *ptr; if (isalnum(ch)) continue; if (Pure_Enough.find(ch) != string::npos) continue; *ptr = '~'; } return rslt; } // Returns negative if a is less than b in alphabetical order // returns 0 if they are the same, or positive if a is greater. // Like perl cmp operator, but ignores case. int cmp_casefold(const std::string& a, const std::string& b) { string::const_iterator aa, bb; aa = a.begin(); bb = b.begin(); while (aa != a.end() && bb != b.end()){ char ca = tolower(*aa++); char cb = tolower(*bb++); if (ca != cb) return ca < cb ? -2 : 2; } if (aa != a.end()) return 1; // a is longer if (bb != b.end()) return -1; // b is longer return 0; } string noCR(const string bar){ string foo(bar); int len = foo.length(); if (len){ if (foo[len-1] == '\r') { foo.erase(len-1); } } return foo; } // sorta like Perl's join(...) string join(const string sep, const list stuff){ string rslt; for (list::const_iterator ptr = stuff.begin(); ptr != stuff.end(); ptr++){ if (rslt.length()) rslt += sep; rslt += *ptr; } return rslt; } string strError(const int errnum){ char buf[1000]; char* rslt = strerror_r(errnum, buf, sizeof(buf)); return rslt; #ifdef XSI_not_gnu if (rslt) { cerr << "strerror_r() failed: " << rslt << " " perror(0); exit(1); } #endif } extern int errno; string strError(){ return strError(errno); }