123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259 |
- #include <iostream>
- #include "Exception.h"
- #include "stringtools.h"
- #include "Lexer.h"
- using namespace std;
- string delSpaces(const string& s)
- {
- string res = "";
- for (unsigned int i = 0; i < s.size(); ++i)
- {
- if (!isspace(s[i]))
- res += s[i];
- }
- return res;
- }
- void substitute(std::string& s, char c1, char c2)
- {
- for (unsigned int i = 0; i < s.size(); ++i)
- if (s[i] == c1) s[i] = c2;
- }
- void reduceToOne(std::string& s, char c)
- {
- unsigned int pr = 0;
- unsigned int pw = 0;
- while (pr < s.size())
- {
- char ac = s[pr];
- s[pw] = ac;
- ++pr;
- ++pw;
- if (ac == c)
- {
- while (pr < s.size() && s[pr] == c) // skip further characters c
- ++pr;
- }
- }
- s.resize(pw);
- }
- string trim(const string& s)
- {
- string res = "";
- int last = s.size() - 1;
- while (last >= 0 && isspace(s[last]))
- --last;
- int first = 0;
- while (first < (int)s.size() && isspace(s[first]))
- ++first;
- for (int i = first; i <= last; ++i)
- res += s[i];
- return res;
- }
- bool startsWith(const string& s, const string& start)
- {
- int len = start.length();
- return s.substr(0, len) == start;
- }
- int split(const string& s, Strings& parts, char del, int expectedParts)
- {
- parts.clear();
- string p = "";
- if (!s.empty())
- {
- for (unsigned int i = 0; i < s.size(); ++i)
- {
- if (s[i] == del)
- {
- parts.push_back(p);
- p.clear();
- }
- else
- p += s[i];
- }
- parts.push_back(p);
- }
- if (expectedParts > 0 && expectedParts != (int)parts.size())
- throw Exception("split", string("Unexpected number of parts: ") + s);
- return parts.size();
- }
- void skipWS(const string& s, unsigned int& i)
- {
- static const string ws = " \t\n";
- while (i < s.size() && ws.find(s[i]) != string::npos)
- ++i;
- }
- int getInt(const string& s, unsigned int& i)
- {
- if (!isdigit(s[i]))
- throw Exception("getInt", "digit expected");
- string is;
- while (i < s.size() && isdigit(s[i]))
- {
- is += s[i];
- ++i;
- }
- int res = stoi(is);
- skipWS(s, i);
- return res;
- }
- long int getLongInt(const string& s, unsigned int& i)
- {
- if (!isdigit(s[i]))
- throw Exception("getLongInt", "digit expected");
- string is;
- while (i < s.size() && isdigit(s[i]))
- {
- is += s[i];
- ++i;
- }
- long int res = stol(is);
- skipWS(s, i);
- return res;
- }
- string getWord(const string& s, unsigned int& i)
- {
- if (!isalpha(s[i]) && s[i] != '-' && s[i] != '_')
- throw Exception("getWord", "letter expected");
- string is;
- while (i < s.size() && (isalpha(s[i]) || s[i] == '-' || s[i] == '_'))
- {
- is += s[i];
- ++i;
- }
- skipWS(s, i);
- return is;
- }
- time_t stot(const string& str)
- {
- // converts a string describing time periods to
- // time in seconds
- // numbers without units are in seconds
- // all given values are accumulated
- // use of sign is optional
- // 1 hour
- // 3 hours 5 minutes
- // 1 day -5 minutes
- // 25 -3
- Lexer s(str);
- time_t value = 0;
- while (!s.empty())
- {
- bool minus = false;
- if (s.type == Lexer::singlecharacter)
- {
- if (s.token == "-")
- minus = true;
- else if (s.token != "+")
- throw Exception("string to time", "expected sign");
- s.nextToken();
- }
- time_t thisValue = s.getInt();
- string unit = "s";
- if (s.type == Lexer::identifier)
- unit = s.getWord();
- //eliminate plural s to simplify comparisn
- if (unit.size() > 1 && unit[unit.size() - 1] == 's')
- unit.resize(unit.size() - 1);
- // check all units and common abbreviations
- if (unit == "s" || unit == "sec" || unit == "second")
- thisValue = thisValue;
- else if (unit == "min" || unit == "minute")
- thisValue = thisValue * 60;
- else if (unit == "h" || unit == "hour")
- thisValue = thisValue * 60 * 60;
- else if (unit == "d" || unit == "day")
- thisValue = thisValue * 60 * 60 * 24;
- else if (unit == "week")
- thisValue = thisValue * 60 * 60 * 24 * 7;
- else if (unit == "month")
- thisValue = thisValue * 60 * 60 * 24 * 30;
- else if (unit == "a" || unit == "year")
- thisValue = thisValue * 60 * 60 * 24 * 365;
- else
- throw Exception("string to time", "unknown unit " + unit);
- if (!minus)
- value += thisValue;
- else
- value -= thisValue;
- }
- return value;
- }
- string timeString(time_t t)
- {
- string res;
- if (t < 0)
- {
- res = "- ";
- t = -t;
- }
- int sec = t % 60;
- t /= 60;
- int min = t % 60;
- t /= 60;
- int hour = t % 24;
- t /= 24;
- int days = t;
- if (days > 0)
- res += to_string(days) + " days ";
- if (hour > 0)
- res += to_string(hour) + " hours ";
- if (min > 0)
- res += to_string(min) + " minutes ";
- if (sec > 0 || res.empty())
- res += to_string(sec) + " seconds ";
- return res;
- }
- long int getNumber(const string& l)
- {
- // read *all* digits from string l ignoring all other characters
- // "read 3,000,421 Bytes" => 3000421
- string d;
- for (unsigned int i = 0; i < l.size(); ++i)
- if (isdigit(l[i]))
- d += l[i];
- // return long int value of digits
- long int res = 0;
- try
- {
- res = stol(d);
- }
- catch (...)
- {
- // we ignore overflow here because value is only informative
- cout << "stol failed on " << l << endl;
- res = -1;
- }
- return res;
- }
- void replacePlaceHolder(string& s,
- const string& placeholder,
- const string& content)
- {
- int psize = placeholder.size();
- size_t pos = s.find(placeholder);
- while (pos != string::npos)
- {
- s = s.substr(0, pos) + content + s.substr(pos + psize);
- pos = s.find(placeholder);
- }
- }
|