1 /* This file is part of
2 * ======================================================
4 * LyX, The Document Processor
6 * Copyright 1995 Matthias Ettrich
7 * Copyright 1995-2000 The LyX Team.
9 * ====================================================== */
14 #pragma implementation
30 // The new glibstdc++-v3 has not worked out all the quirks regarding cctype
31 // yet. So currently it failes if the to using lines below are stated.
37 int compare_no_case(string const & s, string const & s2)
40 string::const_iterator p = s.begin();
41 string::const_iterator p2 = s2.begin();
43 while (p != s.end() && p2 != s2.end()) {
44 int const lc1 = tolower(*p);
45 int const lc2 = tolower(*p2);
47 return (lc1 < lc2) ? -1 : 1;
52 if (s.size() == s2.size())
54 if (s.size() < s2.size())
60 int compare_no_case(string const & s, string const & s2, unsigned int len)
62 string::const_iterator p = s.begin();
63 string::const_iterator p2 = s2.begin();
65 while (i < len && p != s.end() && p2 != s2.end()) {
66 int const lc1 = tolower(*p);
67 int const lc2 = tolower(*p2);
69 return (lc1 < lc2) ? -1 : 1;
74 if (s.size() == s2.size())
76 if (s.size() < s2.size())
82 bool isStrInt(string const & str)
84 if (str.empty()) return false;
86 // Remove leading and trailing white space chars.
87 string const tmpstr = frontStrip(strip(str, ' '), ' ');
88 if (tmpstr.empty()) return false;
90 string::const_iterator cit = tmpstr.begin();
91 if ( (*cit) == '-') ++cit;
92 string::const_iterator end = tmpstr.end();
93 for (; cit != end; ++cit) {
94 if (!isdigit((*cit))) return false;
100 int strToInt(string const & str)
103 // Remove leading and trailing white space chars.
104 string const tmpstr = frontStrip(strip(str, ' '), ' ');
105 // Do the conversion proper.
106 return lyx::atoi(tmpstr);
113 bool isStrDbl(string const & str)
115 if (str.empty()) return false;
117 // Remove leading and trailing white space chars.
118 string const tmpstr = frontStrip(strip(str, ' '), ' ');
119 if (tmpstr.empty()) return false;
120 // if (1 < tmpstr.count('.')) return false;
122 string::const_iterator cit = tmpstr.begin();
123 bool found_dot(false);
124 if ( (*cit) == '-') ++cit;
125 string::const_iterator end = tmpstr.end();
126 for (; cit != end; ++cit) {
143 double strToDbl(string const & str)
146 // Remove leading and trailing white space chars.
147 string const tmpstr = frontStrip(strip(str, ' '), ' ');
148 // Do the conversion proper.
149 return ::atof(tmpstr.c_str());
156 char lowercase(char c)
158 return char( tolower(c) );
162 char uppercase(char c)
164 return char( toupper(c) );
168 string const lowercase(string const & a)
172 string::iterator result = tmp.begin();
173 string::iterator end = tmp.end();
174 for (string::iterator first = tmp.begin();
175 first != end; ++first, ++result) {
176 *result = lowercase(*first);
179 // We want to use this one. (Lgb)
180 transform(tmp.begin(), tmp.end(), tmp.begin(), tolower);
186 string const uppercase(string const & a)
190 string::iterator result = tmp.begin();
191 string::iterator end = tmp.end();
192 for (string::iterator first = tmp.begin();
193 first != end; ++first, ++result) {
194 *result = uppercase(*first);
197 // We want to use this one. (Lgb)
198 transform(tmp.begin(), tmp.end(), tmp.begin(), toupper);
204 bool prefixIs(string const & a, char const * pre)
208 size_t const l = strlen(pre);
209 string::size_type const alen = a.length();
211 if (l > alen || a.empty())
214 #if !defined(USE_INCLUDED_STRING) && !defined(STD_STRING_IS_GOOD)
215 // Delete this code when the compilers get a bit better.
216 return ::strncmp(a.c_str(), pre, l) == 0;
218 // This is the code that we really want to use
219 // but until gcc ships with a basic_string that
220 // implements std::string correctly we have to
221 // use the code above.
222 return a.compare(0, l, pre, l) == 0;
228 bool prefixIs(string const & a, string const & pre)
230 string::size_type const prelen = pre.length();
231 string::size_type const alen = a.length();
233 if (prelen < alen || a.empty())
236 #if !defined(USE_INCLUDED_STRING) && !defined(STD_STRING_IS_GOOD)
237 return ::strncmp(a.c_str(), pre.c_str(), prelen) == 0;
239 return a.compare(0, prelen, pre) == 0;
245 bool suffixIs(string const & a, char c)
247 if (a.empty()) return false;
248 return a[a.length() - 1] == c;
252 bool suffixIs(string const & a, char const * suf)
256 size_t const suflen = strlen(suf);
257 if (suflen > a.length())
260 #if !defined(USE_INCLUDED_STRING) && !defined(STD_STRING_IS_GOOD)
261 // Delete this code when the compilers get a bit better.
262 string tmp(a, a.length() - suflen);
263 return ::strncmp(tmp.c_str(), suf, suflen) == 0;
265 // This is the code that we really want to use
266 // but until gcc ships with a basic_string that
267 // implements std::string correctly we have to
268 // use the code above.
269 return a.compare(a.length() - suflen, suflen, suf) == 0;
275 bool suffixIs(string const & a, string const & suf)
277 string::size_type const suflen = suf.length();
278 string::size_type const alen = a.length();
283 #if !defined(USE_INCLUDED_STRING) && !defined(STD_STRING_IS_GOOD)
284 string tmp(a, alen - suflen);
285 return ::strncmp(tmp.c_str(), suf.c_str(), suflen) == 0;
287 return a.compare(alen - suflen, suflen, suf) == 0;
293 bool contains(char const * a, string const & b)
297 return contains(at, b);
301 bool contains(string const & a, char const * b)
305 return contains(a, bt);
309 bool contains(string const & a, string const & b)
313 return a.find(b) != string::npos;
317 bool contains(char const * a, char const * b)
322 return contains(at, bt);
326 bool containsOnly(string const & s, char const * cset)
330 return s.find_first_not_of(cset) == string::npos;
334 bool containsOnly(string const & s, string const & cset)
336 return s.find_first_not_of(cset) == string::npos;
340 bool containsOnly(char const * s, char const * cset)
344 return string(s).find_first_not_of(cset) == string::npos;
348 bool containsOnly(char const * s, string const & cset)
352 return string(s).find_first_not_of(cset) == string::npos;
356 string::size_type countChar(string const & a, char c)
358 #ifdef HAVE_STD_COUNT
359 return count(a.begin(), a.end(), c);
362 count(a.begin(), a.end(), c, n);
368 // ale970405+lasgoutt-970425
369 // rewritten to use new string (Lgb)
370 string const token(string const & a, char delim, int n)
372 if (a.empty()) return string();
374 string::size_type k = 0;
375 string::size_type i = 0;
377 // Find delimiter or end of string
379 if ((i = a.find(delim, i)) == string::npos)
383 // i is now the n'th delim (or string::npos)
384 if (i == string::npos) return string();
385 k = a.find(delim, i);
386 // k is now the n'th + 1 delim (or string::npos)
388 return a.substr(i, k - i);
392 // this could probably be faster and/or cleaner, but it seems to work (JMarc)
393 // rewritten to use new string (Lgb)
394 int tokenPos(string const & a, char delim, string const & tok)
400 while (!str.empty()) {
401 str = split(str, tmptok, delim);
410 bool regexMatch(string const & a, string const & pattern)
412 // We massage the pattern a bit so that the usual
413 // shell pattern we all are used to will work.
414 // One nice thing about using a real regex is that
415 // things like "*.*[^~]" will work also.
416 // build the regex string.
417 string regex(pattern);
418 regex = subst(regex, ".", "\\.");
419 regex = subst(regex, "*", ".*");
421 return reg.exact_match(a);
425 string const subst(string const & a, char oldchar, char newchar)
428 string::iterator lit = tmp.begin();
429 string::iterator end = tmp.end();
430 for(; lit != end; ++lit)
431 if ((*lit) == oldchar)
437 string const subst(string const & a,
438 char const * oldstr, string const & newstr)
443 string::size_type i = 0;
444 string::size_type olen = strlen(oldstr);
445 while((i = lstr.find(oldstr, i)) != string::npos) {
446 lstr.replace(i, olen, newstr);
447 i += newstr.length(); // We need to be sure that we dont
448 // use the same i over and over again.
454 string const subst(string const & a,
455 string const & oldstr, string const & newstr)
458 string::size_type i = 0;
459 string::size_type const olen = oldstr.length();
460 while((i = lstr.find(oldstr, i)) != string::npos) {
461 lstr.replace(i, olen, newstr);
462 i += newstr.length(); // We need to be sure that we dont
463 // use the same i over and over again.
469 string const strip(string const & a, char c)
471 if (a.empty()) return a;
473 string::size_type i = tmp.find_last_not_of(c);
474 if (i == a.length() - 1) return tmp; // no c's at end of a
475 if (i != string::npos)
476 tmp.erase(i + 1, string::npos);
478 tmp.erase(); // only c in the whole string
483 string const frontStrip(string const & a, char const * p)
487 if (a.empty() || !*p) return a;
489 string::size_type i = tmp.find_first_not_of(p);
496 string const frontStrip(string const & a, char c)
498 if (a.empty()) return a;
500 string::size_type i = tmp.find_first_not_of(c);
507 string const split(string const & a, string & piece, char delim)
510 string::size_type i = a.find(delim);
511 if (i == a.length() - 1) {
512 piece = a.substr(0, i);
513 } else if (i != string::npos) {
514 piece = a.substr(0, i);
515 tmp = a.substr(i + 1);
518 tmp = a.substr(i + 1);
526 string const split(string const & a, char delim)
529 string::size_type i = a.find(delim);
530 if (i != string::npos) // found delim
531 tmp = a.substr(i + 1);
537 string const rsplit(string const & a, string & piece, char delim)
540 string::size_type i = a.rfind(delim);
541 if (i != string::npos) { // delimiter was found
542 piece = a.substr(0, i);
543 tmp = a.substr(i + 1);
544 } else { // delimter was not found