30 #include <boost/array.hpp>
31 #include <boost/lexical_cast.hpp>
34 #define ERR_GENERAL LOG_STREAM(err, lg::general())
35 #define ERR_NG LOG_STREAM(err, log_engine)
50 return c ==
'\r' || c ==
'\n';
58 if (static_cast<unsigned char>(c) >= 128)
72 std::string::size_type
pos = 0;
73 while ( (pos = str.find(src, pos)) != std::string::npos ) {
74 str.replace( pos, src.size(),
dst );
88 str.erase(str.begin(), it);
89 str.erase(std::find_if(str.rbegin(), str.rend(),
notspace).base(), str.end());
96 str.erase(std::find_if(str.rbegin(), str.rend(),
notspace).base(), str.end());
112 std::vector< std::string >
res;
114 std::string::const_iterator i1 = val.begin();
115 std::string::const_iterator i2;
122 while (i2 != val.end()) {
125 if (flags & STRIP_SPACES)
128 res.push_back(new_val);
130 if (flags & STRIP_SPACES) {
142 if (flags & STRIP_SPACES)
145 res.push_back(new_val);
154 std::vector< std::string >
res;
155 std::vector<char> part;
156 bool in_parenthesis =
false;
157 std::vector<std::string::const_iterator> square_left;
158 std::vector<std::string::const_iterator> square_right;
159 std::vector< std::string > square_expansion;
164 std::string::const_iterator i1 = val.begin();
165 std::string::const_iterator i2;
166 std::string::const_iterator j1;
174 if (i1 == val.end())
return res;
177 ERR_GENERAL <<
"Separator must be specified for square bracket split funtion." << std::endl;
181 if(left.size()!=right.size()){
182 ERR_GENERAL <<
"Left and Right Parenthesis lists not same length" << std::endl;
187 if(i2 == val.end() || (!in_parenthesis && *i2 == separator)) {
189 size_t size_square_exp = 0;
190 for (
size_t i=0;
i < square_left.size();
i++) {
192 std::vector< std::string > tmp =
split(tmp_val);
193 std::vector<std::string>::const_iterator
itor = tmp.begin();
194 for(; itor != tmp.end(); ++
itor) {
195 size_t found_tilde = (*itor).find_first_of(
'~');
196 if (found_tilde == std::string::npos) {
197 size_t found_asterisk = (*itor).find_first_of(
'*');
198 if (found_asterisk == std::string::npos) {
200 square_expansion.push_back(
strip(tmp));
203 std::string s_begin = (*itor).substr(0,found_asterisk);
204 s_begin =
strip(s_begin);
205 std::string s_end = (*itor).substr(found_asterisk+1);
206 s_end =
strip(s_end);
207 for (
int ast=std::stoi(s_end); ast>0; --ast)
208 square_expansion.push_back(s_begin);
212 std::string s_begin = (*itor).substr(0,found_tilde);
213 s_begin =
strip(s_begin);
214 int begin = std::stoi(s_begin);
215 size_t padding = 0, padding_end = 0;
216 while (padding<s_begin.size() && s_begin[padding]==
'0') {
220 s_end =
strip(s_end);
221 int end = std::stoi(s_end);
222 while (padding_end<s_end.size() && s_end[padding_end]==
'0') {
225 if (padding*padding_end > 0 && s_begin.size() != s_end.size()) {
226 ERR_GENERAL <<
"Square bracket padding sizes not matching: "
227 << s_begin <<
" and " << s_end <<
".\n";
229 if (padding_end > padding) padding = padding_end;
231 int increment = (end >= begin ? 1 : -1);
233 for (
int k=begin; k!=
end; k+=increment) {
235 for (
size_t p=pb.size();
p<=padding;
p++)
237 square_expansion.push_back(pb);
241 if (i*square_expansion.size() != (i+1)*size_square_exp ) {
243 ERR_GENERAL <<
"Square bracket lengths do not match up: "+tmp+
"" << std::endl;
246 size_square_exp = square_expansion.size();
252 if (square_left.size() != 0)
253 j_max = square_expansion.size() / square_left.size();
257 for (
size_t i=0;
i < square_left.size();
i++) {
259 new_val.append(tmp_val);
260 size_t k = j+i*j_max;
261 if (k < square_expansion.size())
262 new_val.append(square_expansion[k]);
263 j1 = square_right[
i]+1;
266 new_val.append(tmp_val);
267 if (flags & STRIP_SPACES)
270 res.push_back(new_val);
277 if (flags & STRIP_SPACES) {
283 square_right.clear();
284 square_expansion.clear();
287 if(!part.empty() && *i2 == part.back()) {
289 if (*i2 ==
']') square_right.push_back(i2);
291 in_parenthesis =
false;
296 for(
size_t i=0;
i < lp.size();
i++) {
299 square_left.push_back(i2);
301 part.push_back(rp[i]);
309 in_parenthesis =
true;
313 ERR_GENERAL <<
"Mismatched parenthesis:\n"<<val<< std::endl;;
327 std::vector< std::string >
v =
split(val, major, flags);
330 std::map< std::string, std::string >
res;
333 size_t pos =
i->find_first_of(minor);
336 if(pos == std::string::npos) {
338 value = default_value;
340 key =
i->substr(0, pos);
341 value =
i->substr(pos + 1);
354 std::vector< std::string >
res;
355 std::vector<char> part;
356 bool in_parenthesis =
false;
361 std::string::const_iterator i1 = val.begin();
362 std::string::const_iterator i2;
369 if(left.size()!=right.size()){
370 ERR_GENERAL <<
"Left and Right Parenthesis lists not same length" << std::endl;
374 while (i2 != val.end()) {
375 if(!in_parenthesis && separator && *i2 == separator){
377 if (flags & STRIP_SPACES)
380 res.push_back(new_val);
382 if (flags & STRIP_SPACES) {
389 if(!part.empty() && *i2 == part.back()){
391 if(!separator && part.empty()){
393 if (flags & STRIP_SPACES)
395 res.push_back(new_val);
400 in_parenthesis =
false;
406 for(
size_t i=0;
i < lp.size();
i++){
408 if (!separator && part.empty()){
410 if (flags & STRIP_SPACES)
412 res.push_back(new_val);
418 part.push_back(rp[i]);
426 in_parenthesis =
true;
430 if (flags & STRIP_SPACES)
433 res.push_back(new_val);
436 ERR_GENERAL <<
"Mismatched parenthesis:\n"<<val<< std::endl;;
445 int value = std::stoi(amount);
446 if(amount[amount.size()-1] ==
'%') {
450 if (( minimum > 0 ) && ( value < minimum ))
457 std::string::size_type
pos = str.find_first_of(special_chars);
458 if (pos == std::string::npos) {
464 res.insert(pos, 1,
'\\');
465 pos = res.find_first_of(special_chars, pos + 2);
466 }
while (pos != std::string::npos);
472 std::string::size_type
pos = str.find(
'\\');
473 if (pos == std::string::npos) {
480 pos = res.find(
'\\', pos + 1);
481 }
while (pos != std::string::npos);
490 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
492 "abcdefghijklmnopqrstuvwxyz"
497 for(
size_t n = 0;
n < str.length(); ++
n) {
498 const char&
c = str[
n];
500 if(nonresv.find(c) != std::string::npos) {
506 snprintf(buf,
sizeof(buf),
"%%%02X", c);
514 if (str.empty())
return def;
517 if (str ==
"yes")
return true;
518 if (str ==
"no"|| str ==
"false" || str ==
"off" || str ==
"0" || str ==
"0.0")
527 std::ostringstream oss;
534 std::ostringstream oss;
542 std::streamsize oldprec = ss.precision();
557 ss.precision(oldprec);
561 const double multiplier = base2 ? 1024 : 1000;
563 typedef boost::array<std::string, 9> strings9;
566 strings9::const_iterator prefix;
568 strings9 tmp = { {
"",
"",
"",
"",
"",
"",
"",
"",
"" } };
570 prefix = prefixes.begin();
571 }
else if (input < 1.0) {
584 prefix = prefixes.begin();
585 while (input < 1.0 && *prefix != prefixes.back()) {
605 prefix = prefixes.begin();
606 while (input > multiplier && *prefix != prefixes.back()) {
612 std::stringstream ss;
616 << (base2 && (*prefix !=
"") ?
_(
"infix_binary^i") :
"")
622 return ((c ==
'_') || (c ==
'-'));
626 return ((c ==
'?') || (c ==
'*'));
630 const size_t alnum = std::count_if(username.begin(), username.end(), isalnum);
631 const size_t valid_char =
633 if ((alnum + valid_char != username.size())
634 || valid_char == username.size() || username.empty() )
642 const size_t alnum = std::count_if(username.begin(), username.end(), isalnum);
643 const size_t valid_char =
645 const size_t wild_char =
647 if ((alnum + valid_char + wild_char != username.size())
648 || valid_char == username.size() || username.empty() )
657 std::vector<std::string> matches;
658 const size_t last_space = text.rfind(
" ");
660 if (last_space == text.size() -1) {
667 if (last_space == std::string::npos) {
672 semiword.assign(text, last_space + 1, text.size());
676 for (std::vector<std::string>::const_iterator word = wordlist.begin();
677 word != wordlist.end(); ++word)
679 if (word->size() < semiword.size()
680 || !std::equal(semiword.begin(), semiword.end(), word->begin(),
685 if (matches.empty()) {
689 while (toupper(best_match[j]) == toupper((*word)[j])) j++;
690 if (best_match.begin() + j < best_match.end()) {
691 best_match.erase(best_match.begin() + j, best_match.end());
694 matches.push_back(*word);
696 if(!matches.empty()) {
697 text.replace(last_space + 1, best_match.size(), best_match);
704 return (c ==
' ' || c ==
',' || c ==
':' || c ==
'\'' || c ==
'"' || c ==
'-');
708 size_t first = message.find(word);
709 if (first == std::string::npos)
return false;
711 size_t next = first + word.size();
720 const bool wild_matching = (!match.empty() && match[0] ==
'*');
721 const std::string::size_type solid_begin = match.find_first_not_of(
'*');
722 const bool have_solids = (solid_begin != std::string::npos);
724 if(str.empty() || !have_solids) {
725 return wild_matching || str ==
match;
727 const std::string::size_type solid_end = match.find_first_of(
'*', solid_begin);
728 const std::string::size_type solid_len = (solid_end == std::string::npos)
729 ? match.length() - solid_begin : solid_end - solid_begin;
730 std::string::size_type current = 0;
735 const std::string::size_type test_len = str.length() - current;
736 for(std::string::size_type
i=0;
i < solid_len && matches; ++
i) {
737 char solid_c = match[solid_begin +
i];
738 if(
i > test_len || !(solid_c ==
'?' || solid_c == str[current+
i])) {
744 const std::string consumed_match = (solid_begin+solid_len < match.length())
745 ? match.substr(solid_end) :
"";
746 const std::string consumed_str = (solid_len < test_len)
747 ? str.substr(current+solid_len) :
"";
750 }
while(wild_matching && !matches && ++current < str.length());
756 if(indent_size == 0) {
766 const std::vector<std::string>& lines =
split(
string,
'\x0A', 0);
769 for(
size_t lno = 0; lno < lines.size();) {
773 if(!line.empty() && line !=
"\x0D") {
779 if(++lno < lines.size()) {
789 std::vector<std::string>
res;
791 std::string::const_iterator i1 = val.begin();
792 std::string::const_iterator i2 = val.begin();
794 while (i2 != val.end()) {
798 if (i2 != val.end()) ++i2;
799 }
else if (*i2 == c) {
804 res.push_back(new_val);
806 if (flags & STRIP_SPACES) {
807 while(i2 != val.end() && *i2 ==
' ')
821 res.push_back(new_val);
828 const std::string::const_iterator dash =
std::find(str.begin(), str.end(),
'-');
831 std::pair<int,int>
res(std::stoi(
a), std::stoi(b));
832 if (res.second < res.first)
833 res.second = res.first;
840 std::vector< std::pair< int, int > > to_return;
842 std::vector<std::string>::const_iterator
i, i_end=strs.end();
843 for(i = strs.begin(); i != i_end; ++
i) {
852 const size_t prev_size = str.length();
856 if(str.length() != prev_size) {
std::string si_string(double input, bool base2, std::string unit)
Convert into a string with an SI-postfix.
bool isvalid_wildcard(const std::string &username)
Check if the username pattern contains only valid characters.
std::string urlencode(const std::string &str)
Percent-escape characters in a UTF-8 string intended to be part of a URL.
bool isvalid_username(const std::string &username)
Check if the username contains only valid characters.
int div100rounded(int num)
Guarantees portable results for division by 100; round towards 0.
GLenum GLenum GLenum input
std::map< std::string, std::string > map_split(std::string const &val, char major, char minor, int flags, std::string const &default_value)
Splits a string based on two separators into a map.
REMOVE_EMPTY : remove empty elements.
std::string unescape(const std::string &str)
Remove all escape characters (backslash)
bool wildcard_string_match(const std::string &str, const std::string &match)
Match using '*' as any number of characters (including none), and '?' as any one character.
GLuint const GLfloat * val
bool notspace(const char c)
static bool is_username_char(char c)
const std::string unicode_multiplication_sign
const std::string number
template to number regex
std::string quote(const std::string &str)
Surround the string 'str' with double quotes.
std::string & strip(std::string &str)
Remove whitespace from the front and back of the string 'str'.
GLdouble GLdouble GLdouble b
STRIP_SPACES : strips leading and trailing blank spaces.
const std::string unicode_minus
void ellipsis_truncate(std::string &str, const size_t size)
Truncates a string to a given utf-8 character count and then appends an ellipsis. ...
std::string half_signed_value(int val)
Sign with Unicode "−" if negative.
static UNUSEDNOWARN std::string _(const char *str)
bool chars_equal_insensitive(char a, char b)
const std::string unicode_en_dash
static bool is_wildcard_char(char c)
GLsizei const GLfloat * value
GLboolean GLboolean GLboolean GLboolean a
std::string & strip_end(std::string &str)
Remove whitespace from the back of the string 'str'.
GLenum GLuint GLsizei const char * buf
const std::string unicode_em_dash
utf8::string & truncate(utf8::string &str, const size_t size)
Truncates a UTF-8 string to the specified number of characters.
Templates and utility-routines for strings and numbers.
cl_event GLbitfield flags
const std::string ¶meters float amount
std::string indent(const std::string &string, size_t indent_size)
Indent a block of text.
std::string escape(const std::string &str, const char *special_chars)
Prepends a configurable set of characters with a backslash.
std::pair< int, int > parse_range(std::string const &str)
std::vector< std::string > quoted_split(std::string const &val, char c, int flags, char quote)
This function is identical to split(), except it does not split when it otherwise would if the previo...
const std::string unicode_figure_dash
std::map< std::string, tfilter >::iterator itor
std::vector< std::pair< int, int > > parse_ranges(std::string const &str)
const std::string ellipsis
bool string_bool(const std::string &str, bool def)
Convert no, false, off, 0, 0.0 to false, empty to def, and others to true.
bool isnewline(const char c)
std::string replace(std::string str, const std::string &src, const std::string &dst)
Replace all instances of src in str with dst.
static lg::log_domain log_engine("engine")
std::vector< std::string > parenthetical_split(std::string const &val, const char separator, std::string const &left, std::string const &right, const int flags)
Splits a string based either on a separator where text within parenthesis is protected from splitting...
bool find(E event, F functor)
Tests whether an event handler is available.
int apply_modifier(const int number, const std::string &amount, const int minimum)
static bool is_word_boundary(char c)
Standard logging facilities (interface).
static const char * match(MatchState *ms, const char *s, const char *p)
GLsizei GLenum GLuint GLuint GLsizei char * message
std::vector< std::string > split(std::string const &val, const char c, const int flags)
Splits a (comma-)separated string into a vector of pieces.
bool portable_isspace(const char c)
std::string signed_value(int val)
Convert into a signed value (using the Unicode "−" and +0 convention.
std::vector< std::string > square_parenthetical_split(std::string const &val, const char separator, std::string const &left, std::string const &right, const int flags)
Similar to parenthetical_split, but also expands embedded square brackets.
GLsizei const GLcharARB ** string
bool word_completion(std::string &text, std::vector< std::string > &wordlist)
Try to complete the last word of 'text' with the 'wordlist'.
const std::string unicode_bullet
static void si_string_impl_stream_write(std::stringstream &ss, double input)
bool word_match(const std::string &message, const std::string &word)
Check if a message contains a word.