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
36 int compare_no_case(string const & s, string const & s2)
38 string::const_iterator p = s.begin();
39 string::const_iterator p2 = s2.begin();
41 while (p != s.end() && p2 != s2.end()) {
42 int const lc1 = tolower(*p);
43 int const lc2 = tolower(*p2);
45 return (lc1 < lc2) ? -1 : 1;
50 if (s.size() == s2.size())
52 if (s.size() < s2.size())
58 int compare_no_case(string const & s, string const & s2, unsigned int len)
60 string::const_iterator p = s.begin();
61 string::const_iterator p2 = s2.begin();
63 while (i < len && p != s.end() && p2 != s2.end()) {
64 int const lc1 = tolower(*p);
65 int const lc2 = tolower(*p2);
67 return (lc1 < lc2) ? -1 : 1;
73 if (s.size() >= len && s2.size() >= len)
75 if (s.size() < s2.size())
81 bool isStrInt(string const & str)
83 if (str.empty()) return false;
85 // Remove leading and trailing white space chars.
86 string const tmpstr = frontStrip(strip(str, ' '), ' ');
87 if (tmpstr.empty()) return false;
89 string::const_iterator cit = tmpstr.begin();
90 if ((*cit) == '-') ++cit;
91 string::const_iterator end = tmpstr.end();
92 for (; cit != end; ++cit) {
93 if (!isdigit((*cit))) return false;
99 bool isStrUnsignedInt(string const & str)
101 if (str.empty()) return false;
103 // Remove leading and trailing white space chars.
104 string const tmpstr = frontStrip(strip(str, ' '), ' ');
105 if (tmpstr.empty()) return false;
107 string::const_iterator cit = tmpstr.begin();
108 string::const_iterator end = tmpstr.end();
109 for (; cit != end; ++cit) {
110 if (!isdigit((*cit))) return false;
116 int strToInt(string const & str)
119 // Remove leading and trailing white space chars.
120 string const tmpstr = frontStrip(strip(str, ' '), ' ');
121 // Do the conversion proper.
122 return lyx::atoi(tmpstr);
129 unsigned int strToUnsignedInt(string const & str)
131 if (isStrUnsignedInt(str)) {
132 // Remove leading and trailing white space chars.
133 string const tmpstr = frontStrip(strip(str, ' '), ' ');
134 // Do the conversion proper.
135 return lyx::atoi(tmpstr);
142 bool isStrDbl(string const & str)
144 if (str.empty()) return false;
146 // Remove leading and trailing white space chars.
147 string const tmpstr = frontStrip(strip(str, ' '), ' ');
148 if (tmpstr.empty()) return false;
149 // if (1 < tmpstr.count('.')) return false;
151 string::const_iterator cit = tmpstr.begin();
152 bool found_dot(false);
153 if ((*cit) == '-') ++cit;
154 string::const_iterator end = tmpstr.end();
155 for (; cit != end; ++cit) {
172 double strToDbl(string const & str)
175 // Remove leading and trailing white space chars.
176 string const tmpstr = frontStrip(strip(str, ' '), ' ');
177 // Do the conversion proper.
178 return ::atof(tmpstr.c_str());
185 char lowercase(char c)
187 return char( tolower(c) );
191 char uppercase(char c)
193 return char( toupper(c) );
199 // since we cannot use std::tolower and std::toupper directly in the
200 // calls to std::transform yet, we use these helper clases. (Lgb)
202 struct local_lowercase {
203 char operator()(char c) const {
208 struct local_uppercase {
209 char operator()(char c) const {
214 } // end of anon namespace
216 string const lowercase(string const & a)
219 transform(tmp.begin(), tmp.end(), tmp.begin(), local_lowercase());
223 string const uppercase(string const & a)
226 transform(tmp.begin(), tmp.end(), tmp.begin(), local_uppercase());
231 bool prefixIs(string const & a, char const * pre)
235 size_t const l = strlen(pre);
236 string::size_type const alen = a.length();
238 if (l > alen || a.empty())
241 #if !defined(USE_INCLUDED_STRING) && !defined(STD_STRING_IS_GOOD)
242 // Delete this code when the compilers get a bit better.
243 return ::strncmp(a.c_str(), pre, l) == 0;
245 // This is the code that we really want to use
246 // but until gcc ships with a basic_string that
247 // implements std::string correctly we have to
248 // use the code above.
249 return a.compare(0, l, pre, l) == 0;
255 bool prefixIs(string const & a, string const & pre)
257 string::size_type const prelen = pre.length();
258 string::size_type const alen = a.length();
260 if (prelen > alen || a.empty())
263 #if !defined(USE_INCLUDED_STRING) && !defined(STD_STRING_IS_GOOD)
264 return ::strncmp(a.c_str(), pre.c_str(), prelen) == 0;
266 return a.compare(0, prelen, pre) == 0;
272 bool suffixIs(string const & a, char c)
274 if (a.empty()) return false;
275 return a[a.length() - 1] == c;
279 bool suffixIs(string const & a, char const * suf)
283 size_t const suflen = strlen(suf);
284 string::size_type const alen = a.length();
289 #if !defined(USE_INCLUDED_STRING) && !defined(STD_STRING_IS_GOOD)
290 // Delete this code when the compilers get a bit better.
291 string tmp(a, alen - suflen);
292 return ::strncmp(tmp.c_str(), suf, suflen) == 0;
294 // This is the code that we really want to use
295 // but until gcc ships with a basic_string that
296 // implements std::string correctly we have to
297 // use the code above.
298 return a.compare(alen - suflen, suflen, suf) == 0;
304 bool suffixIs(string const & a, string const & suf)
306 string::size_type const suflen = suf.length();
307 string::size_type const alen = a.length();
312 #if !defined(USE_INCLUDED_STRING) && !defined(STD_STRING_IS_GOOD)
313 string tmp(a, alen - suflen);
314 return ::strncmp(tmp.c_str(), suf.c_str(), suflen) == 0;
316 return a.compare(alen - suflen, suflen, suf) == 0;
322 bool contains(char const * a, string const & b)
326 return contains(at, b);
330 bool contains(string const & a, char const * b)
334 return contains(a, bt);
338 bool contains(string const & a, string const & b)
342 return a.find(b) != string::npos;
346 bool contains(string const & a, char b)
350 return a.find(b) != string::npos;
354 bool contains(char const * a, char const * b)
359 return contains(at, bt);
363 bool containsOnly(string const & s, char const * cset)
367 return s.find_first_not_of(cset) == string::npos;
371 bool containsOnly(string const & s, string const & cset)
373 return s.find_first_not_of(cset) == string::npos;
377 bool containsOnly(char const * s, char const * cset)
379 lyx::Assert(s && cset);
381 return string(s).find_first_not_of(cset) == string::npos;
385 bool containsOnly(char const * s, string const & cset)
389 return string(s).find_first_not_of(cset) == string::npos;
393 string::size_type countChar(string const & a, char c)
395 #ifdef HAVE_STD_COUNT
396 return count(a.begin(), a.end(), c);
399 count(a.begin(), a.end(), c, n);
405 // ale970405+lasgoutt-970425
406 // rewritten to use new string (Lgb)
407 string const token(string const & a, char delim, int n)
409 if (a.empty()) return string();
411 string::size_type k = 0;
412 string::size_type i = 0;
414 // Find delimiter or end of string
416 if ((i = a.find(delim, i)) == string::npos)
420 // i is now the n'th delim (or string::npos)
421 if (i == string::npos) return string();
422 k = a.find(delim, i);
423 // k is now the n'th + 1 delim (or string::npos)
425 return a.substr(i, k - i);
429 // this could probably be faster and/or cleaner, but it seems to work (JMarc)
430 // rewritten to use new string (Lgb)
431 int tokenPos(string const & a, char delim, string const & tok)
437 while (!str.empty()) {
438 str = split(str, tmptok, delim);
447 bool regexMatch(string const & a, string const & pattern)
449 // We massage the pattern a bit so that the usual
450 // shell pattern we all are used to will work.
451 // One nice thing about using a real regex is that
452 // things like "*.*[^~]" will work also.
453 // build the regex string.
454 string regex(pattern);
455 regex = subst(regex, ".", "\\.");
456 regex = subst(regex, "*", ".*");
458 return reg.exact_match(a);
462 string const subst(string const & a, char oldchar, char newchar)
465 string::iterator lit = tmp.begin();
466 string::iterator end = tmp.end();
467 for (; lit != end; ++lit)
468 if ((*lit) == oldchar)
474 string const subst(string const & a,
475 char const * oldstr, string const & newstr)
480 string::size_type i = 0;
481 string::size_type olen = strlen(oldstr);
482 while((i = lstr.find(oldstr, i)) != string::npos) {
483 lstr.replace(i, olen, newstr);
484 i += newstr.length(); // We need to be sure that we dont
485 // use the same i over and over again.
491 string const subst(string const & a,
492 string const & oldstr, string const & newstr)
495 string::size_type i = 0;
496 string::size_type const olen = oldstr.length();
497 while((i = lstr.find(oldstr, i)) != string::npos) {
498 lstr.replace(i, olen, newstr);
499 i += newstr.length(); // We need to be sure that we dont
500 // use the same i over and over again.
506 string const strip(string const & a, char c)
508 if (a.empty()) return a;
510 string::size_type i = tmp.find_last_not_of(c);
511 if (i == a.length() - 1) return tmp; // no c's at end of a
512 if (i != string::npos)
513 tmp.erase(i + 1, string::npos);
514 #if !defined(USE_INCLUDED_STRING) && !defined(STD_STRING_IS_GOOD)
515 /// Needed for broken string::find_last_not_of
516 else if (tmp[0] != c) {
517 if (a.length() == 1) return tmp;
518 tmp.erase(1, string::npos);
522 tmp.erase(); // only c in the whole string
527 string const frontStrip(string const & a, char const * p)
531 if (a.empty() || !*p) return a;
533 string::size_type i = tmp.find_first_not_of(p);
540 string const frontStrip(string const & a, char c)
542 if (a.empty()) return a;
544 string::size_type i = tmp.find_first_not_of(c);
551 string const split(string const & a, string & piece, char delim)
554 string::size_type i = a.find(delim);
555 if (i == a.length() - 1) {
556 piece = a.substr(0, i);
557 } else if (i != string::npos) {
558 piece = a.substr(0, i);
559 tmp = a.substr(i + 1);
562 tmp = a.substr(i + 1);
570 string const split(string const & a, char delim)
573 string::size_type i = a.find(delim);
574 if (i != string::npos) // found delim
575 tmp = a.substr(i + 1);
581 string const rsplit(string const & a, string & piece, char delim)
584 string::size_type i = a.rfind(delim);
585 if (i != string::npos) { // delimiter was found
586 piece = a.substr(0, i);
587 tmp = a.substr(i + 1);
588 } else { // delimter was not found