// ************************************************************************** /** @file tools.cc @todo - Resolve the dependancies with dim - Move code to a more appropriate place - put stuff in namespaces */ // ************************************************************************** #include "tools.h" #include #include #include #include #include using namespace std; string Tools::Format(const char *fmt, va_list &ap) { int n=256; char *ret=0; while (1) { ret = new char[n+1]; const int sz = vsnprintf(ret, n, fmt, ap); if (sz<=n) break; n *= 2; delete [] ret; }; string str(ret); delete [] ret; return str; } string Tools::Form(const char *fmt, ...) { va_list ap; va_start(ap, fmt); string str = Format(fmt, ap); va_end(ap); return str; } // -------------------------------------------------------------------------- // //! This is a static helper to remove leading and trailing whitespaces. //! //! @param buf //! a pointer to the char array from which the whitespaces should be //! removed //! //! @returns //! a std::string with the whitespaces removed from buf // string Tools::Trim(const string &str) { // Trim Both leading and trailing spaces const size_t start = str.find_first_not_of(' '); // Find the first character position after excluding leading blank spaces const size_t end = str.find_last_not_of(' '); // Find the first character position from reverse af // if all spaces or empty return an empty string if (string::npos==start || string::npos==end) return string(); return str.substr(start, end-start+1); } // -------------------------------------------------------------------------- // //! This is a static helper to remove leading and trailing whitespaces and //! if available leading and trailing quotes, can be either ' or " //! //! @param buf //! a pointer to the char array to be trimmed //! //! @returns //! a std::string with the content trimmed // string Tools::TrimQuotes(const string &str) { string rc = Trim(str); if (rc.length()<2) return rc; const char b = rc[0]; const char e = rc[rc.length()-1]; if ((b=='\"' && e=='\"') || (b=='\'' && e=='\'')) return rc.substr(1, rc.length()-2); return rc; } // -------------------------------------------------------------------------- // //! This is a static helper to remove leading and trailing whitespaces. //! //! Usage example: //! //! \code //! string str = " Dies ist ein test fuer einen ganz langen Satz " //! "und ob er korrekt umgebrochen und formatiert wird. Alles " //! "nur ein simpler test aber trotzdem ganz wichtig."; //! //! cout << setfill('-') << setw(40) << "+" << endl; //! while (1) //! { //! const string rc = Tools::Wrap(str, 40); //! if (rc.empty()) //! break; //! cout << rc << endl; //! } //! \endcode //! string Tools::Wrap(string &str, size_t width) { const size_t pos = str.length()1) { rc << val << " "; return rc.str(); } if (abs>1e-3) { rc << val*1000 << " m"; return rc.str(); } if (abs>1e-6) { rc << val*1000000 << " u"; return rc.str(); } if (abs>1e-9) { rc << val*1000000000 << " n"; return rc.str(); } if (abs>1e-12) { rc << val*1000000000000. << " p"; return rc.str(); } rc << abs*1000000000000000. << " f"; return rc.str(); } // -------------------------------------------------------------------------- // //! Splits a string into a filename and command line arguments, like: //! //! file.txt arg1=argument1 arg2="argument 2" arg3="argument \"3\"" //! //! 'file.txt' will be returned on opt, the arguments will be returned in //! the returned map. //! //! If the returned file name is empty, an error has occured: //! If the map is also empty the file name was empty, if the map has //! one entry then for this entry the equal sign was missing. // //! allow==true allows for positional (empty) arguments, like in //! file.txt arg1 arg2="argument 2" arg3 //! map Tools::Split(string &opt, bool allow) { using namespace boost; typedef escaped_list_separator separator; const string data(opt); const tokenizer tok(data, separator("\\", " ", "\"'")); auto it=tok.begin(); if (it==tok.end()) { opt = ""; return map(); } opt = string(*it).find_first_of('=')==string::npos ? *it++ : ""; map rc; int cnt=0; for (; it!=tok.end(); it++) { if (it->empty()) continue; const size_t pos = it->find_first_of('='); if (pos==string::npos) { if (allow) { rc[to_string(cnt++)] = *it; continue; } opt = ""; rc.clear(); rc[*it] = ""; return rc; } rc[it->substr(0, pos)] = it->substr(pos+1); } return rc; } vector Tools::Split(const string &str, const string &delim) { vector rc; boost::split(rc, str, boost::is_any_of(delim)); return rc; } // -------------------------------------------------------------------------- // //! Returns the string with a comment (introduced by a #) stripped. The //! comment mark can be escaped by either \# or "#" //! string Tools::Uncomment(const string &opt) { using namespace boost; typedef escaped_list_separator separator; const auto it = tokenizer(opt, separator("\\", "#", "\"'")).begin(); const int charPos = it.base() - opt.begin(); return charPos<1 ? "" : opt.substr(0, opt[charPos-1]=='#' ? charPos-1 : charPos); } // -------------------------------------------------------------------------- // //! Wraps a given text into a vector of strings with not more than //! max size lines //! vector Tools::WordWrap(string text, const uint16_t &max) { if (text.size() rc; while (1) { // Remove trailing white spaces const size_t st = text.find_first_not_of(' '); if (st==string::npos) break; text.erase(0, st); if (text.size()