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 //#warning verify this func please
63 string::const_iterator p = s.begin();
64 string::const_iterator p2 = s2.begin();
66 while (i < len && p != s.end() && p2 != s2.end()) {
67 int const lc1 = tolower(*p);
68 int const lc2 = tolower(*p2);
70 return (lc1 < lc2) ? -1 : 1;
75 if (s.size() == s2.size())
77 if (s.size() < s2.size())
83 bool isStrInt(string const & str)
85 if (str.empty()) return false;
87 // Remove leading and trailing white space chars.
88 string const tmpstr = frontStrip(strip(str, ' '), ' ');
89 if (tmpstr.empty()) return false;
91 string::const_iterator cit = tmpstr.begin();
92 if ( (*cit) == '-') ++cit;
93 string::const_iterator end = tmpstr.end();
94 for (; cit != end; ++cit) {
95 if (!isdigit((*cit))) return false;
101 int strToInt(string const & str)
104 // Remove leading and trailing white space chars.
105 string const tmpstr = frontStrip(strip(str, ' '), ' ');
106 // Do the conversion proper.
107 return lyx::atoi(tmpstr);
114 bool isStrDbl(string const & str)
116 if (str.empty()) return false;
118 // Remove leading and trailing white space chars.
119 string const tmpstr = frontStrip(strip(str, ' '), ' ');
120 if (tmpstr.empty()) return false;
121 // if (1 < tmpstr.count('.')) return false;
123 string::const_iterator cit = tmpstr.begin();
124 bool found_dot(false);
125 if ( (*cit) == '-') ++cit;
126 string::const_iterator end = tmpstr.end();
127 for (; cit != end; ++cit) {
144 double strToDbl(string const & str)
147 // Remove leading and trailing white space chars.
148 string const tmpstr = frontStrip(strip(str, ' '), ' ');
149 // Do the conversion proper.
150 return ::atof(tmpstr.c_str());
157 char lowercase(char c)
163 char uppercase(char c)
169 string const lowercase(string const & a)
173 string::iterator result = tmp.begin();
174 string::iterator end = tmp.end();
175 for (string::iterator first = tmp.begin();
176 first != end; ++first, ++result) {
177 *result = lowercase(*first);
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 // transform(tmp.begin(), tmp.end(), tmp.begin(), toupper);
203 bool prefixIs(string const & a, char const * pre)
207 unsigned int const l = strlen(pre);
208 string::size_type const alen = a.length();
210 if (l > alen || a.empty())
213 #if !defined(USE_INCLUDED_STRING) && !defined(STD_STRING_IS_GOOD)
214 // Delete this code when the compilers get a bit better.
215 return ::strncmp(a.c_str(), pre, l) == 0;
217 // This is the code that we really want to use
218 // but until gcc ships with a basic_string that
219 // implements std::string correctly we have to
220 // use the code above.
221 return a.compare(0, l, pre, l) == 0;
227 bool prefixIs(string const & a, string const & pre)
229 string::size_type const prelen = pre.length();
230 string::size_type const alen = a.length();
232 if (prelen < alen || a.empty())
235 #if !defined(USE_INCLUDED_STRING) && !defined(STD_STRING_IS_GOOD)
236 return ::strncmp(a.c_str(), pre.c_str(), prelen) == 0;
238 return a.compare(0, prelen, pre) == 0;
244 bool suffixIs(string const & a, char c)
246 if (a.empty()) return false;
247 return a[a.length() - 1] == c;
251 bool suffixIs(string const & a, char const * suf)
255 unsigned int const suflen = strlen(suf);
256 if (suflen > a.length())
259 #if !defined(USE_INCLUDED_STRING) && !defined(STD_STRING_IS_GOOD)
260 // Delete this code when the compilers get a bit better.
261 string tmp(a, a.length() - suflen);
262 return ::strncmp(tmp.c_str(), suf, suflen) == 0;
264 // This is the code that we really want to use
265 // but until gcc ships with a basic_string that
266 // implements std::string correctly we have to
267 // use the code above.
268 return a.compare(a.length() - suflen, suflen, suf) == 0;
274 bool suffixIs(string const & a, string const & suf)
276 string::size_type const suflen = suf.length();
277 string::size_type const alen = a.length();
282 #if !defined(USE_INCLUDED_STRING) && !defined(STD_STRING_IS_GOOD)
283 string tmp(a, alen - suflen);
284 return ::strncmp(tmp.c_str(), suf.c_str(), suflen) == 0;
286 return a.compare(alen - suflen, suflen, suf) == 0;
292 bool contains(char const * a, string const & b)
296 return contains(at, b);
300 bool contains(string const & a, char const * b)
304 return contains(a, bt);
308 bool contains(string const & a, string const & b)
312 return a.find(b) != string::npos;
316 bool contains(char const * a, char const * b)
321 return contains(at, bt);
325 bool containsOnly(string const & s, char const * cset)
329 return s.find_first_not_of(cset) == string::npos;
333 bool containsOnly(string const & s, string const & cset)
335 return s.find_first_not_of(cset) == string::npos;
339 bool containsOnly(char const * s, char const * cset)
343 return string(s).find_first_not_of(cset) == string::npos;
347 bool containsOnly(char const * s, string const & cset)
351 return string(s).find_first_not_of(cset) == string::npos;
355 unsigned int countChar(string const & a, char c)
357 #ifdef HAVE_STD_COUNT
358 return count(a.begin(), a.end(), c);
361 count(a.begin(), a.end(), c, n);
367 // ale970405+lasgoutt-970425
368 // rewritten to use new string (Lgb)
369 string const token(string const & a, char delim, int n)
371 if (a.empty()) return string();
373 string::size_type k = 0;
374 string::size_type i = 0;
376 // Find delimiter or end of string
378 if ((i = a.find(delim, i)) == string::npos)
382 // i is now the n'th delim (or string::npos)
383 if (i == string::npos) return string();
384 k = a.find(delim, i);
385 // k is now the n'th + 1 delim (or string::npos)
387 return a.substr(i, k - i);
391 // this could probably be faster and/or cleaner, but it seems to work (JMarc)
392 // rewritten to use new string (Lgb)
393 int tokenPos(string const & a, char delim, string const & tok)
399 while (!str.empty()) {
400 str = split(str, tmptok, delim);
409 bool regexMatch(string const & a, string const & pattern)
411 // We massage the pattern a bit so that the usual
412 // shell pattern we all are used to will work.
413 // One nice thing about using a real regex is that
414 // things like "*.*[^~]" will work also.
415 // build the regex string.
416 string regex(pattern);
417 regex = subst(regex, ".", "\\.");
418 regex = subst(regex, "*", ".*");
420 return reg.exact_match(a);
424 string const subst(string const & a, char oldchar, char newchar)
427 string::iterator lit = tmp.begin();
428 string::iterator end = tmp.end();
429 for(; lit != end; ++lit)
430 if ((*lit) == oldchar)
436 string const subst(string const & a,
437 char const * oldstr, string const & newstr)
442 string::size_type i = 0;
443 int olen = strlen(oldstr);
444 while((i = lstr.find(oldstr, i)) != string::npos) {
445 lstr.replace(i, olen, newstr);
446 i += newstr.length(); // We need to be sure that we dont
447 // use the same i over and over again.
453 string const subst(string const & a,
454 string const & oldstr, string const & newstr)
457 string::size_type i = 0;
458 string::size_type const olen = oldstr.length();
459 while((i = lstr.find(oldstr, i)) != string::npos) {
460 lstr.replace(i, olen, newstr);
461 i += newstr.length(); // We need to be sure that we dont
462 // use the same i over and over again.
468 string const strip(string const & a, char c)
470 if (a.empty()) return a;
472 string::size_type i = tmp.find_last_not_of(c);
473 if (i == a.length() - 1) return tmp; // no c's at end of a
474 if (i != string::npos)
475 tmp.erase(i + 1, string::npos);
477 tmp.erase(); // only c in the whole string
482 string const frontStrip(string const & a, char const * p)
486 if (a.empty() || !*p) return a;
488 string::size_type i = tmp.find_first_not_of(p);
495 string const frontStrip(string const & a, char c)
497 if (a.empty()) return a;
499 string::size_type i = tmp.find_first_not_of(c);
506 string const split(string const & a, string & piece, char delim)
509 string::size_type i = a.find(delim);
510 if (i == a.length() - 1) {
511 piece = a.substr(0, i);
512 } else if (i != string::npos) {
513 piece = a.substr(0, i);
514 tmp = a.substr(i + 1);
517 tmp = a.substr(i + 1);
525 string const split(string const & a, char delim)
528 string::size_type i = a.find(delim);
529 if (i != string::npos) // found delim
530 tmp = a.substr(i + 1);
536 string const rsplit(string const & a, string & piece, char delim)
539 string::size_type i = a.rfind(delim);
540 if (i != string::npos) { // delimiter was found
541 piece = a.substr(0, i);
542 tmp = a.substr(i + 1);
543 } else { // delimter was not found