1 /* This file is part of
2 * ======================================================
4 * LyX, The Document Processor
6 * Copyright 1995 Matthias Ettrich
7 * Copyright 1995-2001 The LyX Team.
9 * ====================================================== */
14 #pragma implementation
30 #ifndef CXX_GLOBAL_CSTD
37 int compare_no_case(string const & s, string const & s2)
39 string::const_iterator p = s.begin();
40 string::const_iterator p2 = s2.begin();
42 while (p != s.end() && p2 != s2.end()) {
43 int const lc1 = tolower(*p);
44 int const lc2 = tolower(*p2);
46 return (lc1 < lc2) ? -1 : 1;
51 if (s.size() == s2.size())
53 if (s.size() < s2.size())
59 int ascii_tolower(int c) {
60 if (c >= 'A' && c <= 'Z')
65 int compare_ascii_no_case(string const & s, string const & s2)
67 string::const_iterator p = s.begin();
68 string::const_iterator p2 = s2.begin();
70 while (p != s.end() && p2 != s2.end()) {
71 int const lc1 = ascii_tolower(*p);
72 int const lc2 = ascii_tolower(*p2);
74 return (lc1 < lc2) ? -1 : 1;
79 if (s.size() == s2.size())
81 if (s.size() < s2.size())
87 int compare_no_case(string const & s, string const & s2, unsigned int len)
89 string::const_iterator p = s.begin();
90 string::const_iterator p2 = s2.begin();
92 while (i < len && p != s.end() && p2 != s2.end()) {
93 int const lc1 = tolower(*p);
94 int const lc2 = tolower(*p2);
96 return (lc1 < lc2) ? -1 : 1;
102 if (s.size() >= len && s2.size() >= len)
104 if (s.size() < s2.size())
110 bool isStrInt(string const & str)
112 if (str.empty()) return false;
114 // Remove leading and trailing white space chars.
115 string const tmpstr = frontStrip(strip(str, ' '), ' ');
116 if (tmpstr.empty()) return false;
118 string::const_iterator cit = tmpstr.begin();
119 if ((*cit) == '-') ++cit;
120 string::const_iterator end = tmpstr.end();
121 for (; cit != end; ++cit) {
122 if (!isdigit((*cit))) return false;
128 bool isStrUnsignedInt(string const & str)
130 if (str.empty()) return false;
132 // Remove leading and trailing white space chars.
133 string const tmpstr = frontStrip(strip(str, ' '), ' ');
134 if (tmpstr.empty()) return false;
136 string::const_iterator cit = tmpstr.begin();
137 string::const_iterator end = tmpstr.end();
138 for (; cit != end; ++cit) {
139 if (!isdigit((*cit))) return false;
145 int strToInt(string const & str)
148 // Remove leading and trailing white space chars.
149 string const tmpstr = frontStrip(strip(str, ' '), ' ');
150 // Do the conversion proper.
151 return lyx::atoi(tmpstr);
158 unsigned int strToUnsignedInt(string const & str)
160 if (isStrUnsignedInt(str)) {
161 // Remove leading and trailing white space chars.
162 string const tmpstr = frontStrip(strip(str, ' '), ' ');
163 // Do the conversion proper.
164 return lyx::atoi(tmpstr);
171 bool isStrDbl(string const & str)
173 if (str.empty()) return false;
175 // Remove leading and trailing white space chars.
176 string const tmpstr = frontStrip(strip(str, ' '), ' ');
177 if (tmpstr.empty()) return false;
178 // if (1 < tmpstr.count('.')) return false;
180 string::const_iterator cit = tmpstr.begin();
181 bool found_dot(false);
182 if ((*cit) == '-') ++cit;
183 string::const_iterator end = tmpstr.end();
184 for (; cit != end; ++cit) {
201 double strToDbl(string const & str)
204 // Remove leading and trailing white space chars.
205 string const tmpstr = frontStrip(strip(str, ' '), ' ');
206 // Do the conversion proper.
207 return ::atof(tmpstr.c_str());
214 char lowercase(char c)
216 return char( tolower(c) );
220 char uppercase(char c)
222 return char( toupper(c) );
228 // since we cannot use std::tolower and std::toupper directly in the
229 // calls to std::transform yet, we use these helper clases. (Lgb)
231 struct local_lowercase {
232 char operator()(char c) const {
237 struct local_uppercase {
238 char operator()(char c) const {
243 } // end of anon namespace
245 string const lowercase(string const & a)
248 transform(tmp.begin(), tmp.end(), tmp.begin(), local_lowercase());
252 string const uppercase(string const & a)
255 transform(tmp.begin(), tmp.end(), tmp.begin(), local_uppercase());
260 bool prefixIs(string const & a, char const * pre)
264 size_t const l = strlen(pre);
265 string::size_type const alen = a.length();
267 if (l > alen || a.empty())
270 #if !defined(USE_INCLUDED_STRING) && !defined(STD_STRING_IS_GOOD)
271 // Delete this code when the compilers get a bit better.
272 return ::strncmp(a.c_str(), pre, l) == 0;
274 // This is the code that we really want to use
275 // but until gcc ships with a basic_string that
276 // implements std::string correctly we have to
277 // use the code above.
278 return a.compare(0, l, pre, l) == 0;
284 bool prefixIs(string const & a, string const & pre)
286 string::size_type const prelen = pre.length();
287 string::size_type const alen = a.length();
289 if (prelen > alen || a.empty())
292 #if !defined(USE_INCLUDED_STRING) && !defined(STD_STRING_IS_GOOD)
293 return ::strncmp(a.c_str(), pre.c_str(), prelen) == 0;
295 return a.compare(0, prelen, pre) == 0;
301 bool suffixIs(string const & a, char c)
303 if (a.empty()) return false;
304 return a[a.length() - 1] == c;
308 bool suffixIs(string const & a, char const * suf)
312 size_t const suflen = strlen(suf);
313 string::size_type const alen = a.length();
318 #if !defined(USE_INCLUDED_STRING) && !defined(STD_STRING_IS_GOOD)
319 // Delete this code when the compilers get a bit better.
320 string tmp(a, alen - suflen);
321 return ::strncmp(tmp.c_str(), suf, suflen) == 0;
323 // This is the code that we really want to use
324 // but until gcc ships with a basic_string that
325 // implements std::string correctly we have to
326 // use the code above.
327 return a.compare(alen - suflen, suflen, suf) == 0;
333 bool suffixIs(string const & a, string const & suf)
335 string::size_type const suflen = suf.length();
336 string::size_type const alen = a.length();
341 #if !defined(USE_INCLUDED_STRING) && !defined(STD_STRING_IS_GOOD)
342 string tmp(a, alen - suflen);
343 return ::strncmp(tmp.c_str(), suf.c_str(), suflen) == 0;
345 return a.compare(alen - suflen, suflen, suf) == 0;
351 bool contains(char const * a, string const & b)
355 return contains(at, b);
359 bool contains(string const & a, char const * b)
363 return contains(a, bt);
367 bool contains(string const & a, string const & b)
371 return a.find(b) != string::npos;
375 bool contains(string const & a, char b)
379 return a.find(b) != string::npos;
383 bool contains(char const * a, char const * b)
388 return contains(at, bt);
392 bool containsOnly(string const & s, char const * cset)
396 return s.find_first_not_of(cset) == string::npos;
400 bool containsOnly(string const & s, string const & cset)
402 return s.find_first_not_of(cset) == string::npos;
406 bool containsOnly(char const * s, char const * cset)
408 lyx::Assert(s && cset);
410 return string(s).find_first_not_of(cset) == string::npos;
414 bool containsOnly(char const * s, string const & cset)
418 return string(s).find_first_not_of(cset) == string::npos;
422 string::size_type countChar(string const & a, char c)
424 #ifdef HAVE_STD_COUNT
425 return count(a.begin(), a.end(), c);
428 count(a.begin(), a.end(), c, n);
434 // ale970405+lasgoutt-970425
435 // rewritten to use new string (Lgb)
436 string const token(string const & a, char delim, int n)
438 if (a.empty()) return string();
440 string::size_type k = 0;
441 string::size_type i = 0;
443 // Find delimiter or end of string
445 if ((i = a.find(delim, i)) == string::npos)
449 // i is now the n'th delim (or string::npos)
450 if (i == string::npos) return string();
451 k = a.find(delim, i);
452 // k is now the n'th + 1 delim (or string::npos)
454 return a.substr(i, k - i);
458 // this could probably be faster and/or cleaner, but it seems to work (JMarc)
459 // rewritten to use new string (Lgb)
460 int tokenPos(string const & a, char delim, string const & tok)
466 while (!str.empty()) {
467 str = split(str, tmptok, delim);
476 bool regexMatch(string const & a, string const & pattern)
478 // We massage the pattern a bit so that the usual
479 // shell pattern we all are used to will work.
480 // One nice thing about using a real regex is that
481 // things like "*.*[^~]" will work also.
482 // build the regex string.
483 string regex(pattern);
484 regex = subst(regex, ".", "\\.");
485 regex = subst(regex, "*", ".*");
487 return reg.exact_match(a);
491 string const subst(string const & a, char oldchar, char newchar)
494 string::iterator lit = tmp.begin();
495 string::iterator end = tmp.end();
496 for (; lit != end; ++lit)
497 if ((*lit) == oldchar)
503 string const subst(string const & a,
504 char const * oldstr, string const & newstr)
509 string::size_type i = 0;
510 string::size_type olen = strlen(oldstr);
511 while((i = lstr.find(oldstr, i)) != string::npos) {
512 lstr.replace(i, olen, newstr);
513 i += newstr.length(); // We need to be sure that we dont
514 // use the same i over and over again.
520 string const subst(string const & a,
521 string const & oldstr, string const & newstr)
524 string::size_type i = 0;
525 string::size_type const olen = oldstr.length();
526 while((i = lstr.find(oldstr, i)) != string::npos) {
527 lstr.replace(i, olen, newstr);
528 i += newstr.length(); // We need to be sure that we dont
529 // use the same i over and over again.
535 string const strip(string const & a, char c)
537 if (a.empty()) return a;
539 string::size_type i = tmp.find_last_not_of(c);
540 if (i == a.length() - 1) return tmp; // no c's at end of a
541 if (i != string::npos)
542 tmp.erase(i + 1, string::npos);
543 #if !defined(USE_INCLUDED_STRING) && !defined(STD_STRING_IS_GOOD)
544 /// Needed for broken string::find_last_not_of
545 else if (tmp[0] != c) {
546 if (a.length() == 1) return tmp;
547 tmp.erase(1, string::npos);
551 tmp.erase(); // only c in the whole string
556 string const frontStrip(string const & a, char const * p)
560 if (a.empty() || !*p) return a;
562 string::size_type i = tmp.find_first_not_of(p);
569 string const frontStrip(string const & a, char c)
571 if (a.empty()) return a;
573 string::size_type i = tmp.find_first_not_of(c);
580 string const split(string const & a, string & piece, char delim)
583 string::size_type i = a.find(delim);
584 if (i == a.length() - 1) {
585 piece = a.substr(0, i);
586 } else if (i != string::npos) {
587 piece = a.substr(0, i);
588 tmp = a.substr(i + 1);
591 tmp = a.substr(i + 1);
599 string const split(string const & a, char delim)
602 string::size_type i = a.find(delim);
603 if (i != string::npos) // found delim
604 tmp = a.substr(i + 1);
610 string const rsplit(string const & a, string & piece, char delim)
613 string::size_type i = a.rfind(delim);
614 if (i != string::npos) { // delimiter was found
615 piece = a.substr(0, i);
616 tmp = a.substr(i + 1);
617 } else { // delimter was not found