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
29 #ifndef CXX_GLOBAL_CSTD
35 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;
72 if (s.size() == s2.size())
74 if (s.size() < s2.size())
80 bool isStrInt(string const & str)
82 if (str.empty()) return false;
84 // Remove leading and trailing white space chars.
85 string const tmpstr = frontStrip(strip(str, ' '), ' ');
86 if (tmpstr.empty()) return false;
88 string::const_iterator cit = tmpstr.begin();
89 if ((*cit) == '-') ++cit;
90 string::const_iterator end = tmpstr.end();
91 for (; cit != end; ++cit) {
92 if (!isdigit((*cit))) return false;
98 int strToInt(string const & str)
101 // Remove leading and trailing white space chars.
102 string const tmpstr = frontStrip(strip(str, ' '), ' ');
103 // Do the conversion proper.
104 return lyx::atoi(tmpstr);
111 bool isStrDbl(string const & str)
113 if (str.empty()) return false;
115 // Remove leading and trailing white space chars.
116 string const tmpstr = frontStrip(strip(str, ' '), ' ');
117 if (tmpstr.empty()) return false;
118 // if (1 < tmpstr.count('.')) return false;
120 string::const_iterator cit = tmpstr.begin();
121 bool found_dot(false);
122 if ((*cit) == '-') ++cit;
123 string::const_iterator end = tmpstr.end();
124 for (; cit != end; ++cit) {
141 double strToDbl(string const & str)
144 // Remove leading and trailing white space chars.
145 string const tmpstr = frontStrip(strip(str, ' '), ' ');
146 // Do the conversion proper.
147 return ::atof(tmpstr.c_str());
154 char lowercase(char c)
156 return char( tolower(c) );
160 char uppercase(char c)
162 return char( toupper(c) );
166 string const lowercase(string const & a)
170 string::iterator result = tmp.begin();
171 string::iterator end = tmp.end();
172 for (string::iterator first = tmp.begin();
173 first != end; ++first, ++result) {
174 *result = lowercase(*first);
177 // We want to use this one. (Lgb)
178 transform(tmp.begin(), tmp.end(), tmp.begin(), tolower);
184 string const uppercase(string const & a)
188 string::iterator result = tmp.begin();
189 string::iterator end = tmp.end();
190 for (string::iterator first = tmp.begin();
191 first != end; ++first, ++result) {
192 *result = uppercase(*first);
195 // We want to use this one. (Lgb)
196 transform(tmp.begin(), tmp.end(), tmp.begin(), toupper);
202 bool prefixIs(string const & a, char const * pre)
206 size_t const l = strlen(pre);
207 string::size_type const alen = a.length();
209 if (l > alen || a.empty())
212 #if !defined(USE_INCLUDED_STRING) && !defined(STD_STRING_IS_GOOD)
213 // Delete this code when the compilers get a bit better.
214 return ::strncmp(a.c_str(), pre, l) == 0;
216 // This is the code that we really want to use
217 // but until gcc ships with a basic_string that
218 // implements std::string correctly we have to
219 // use the code above.
220 return a.compare(0, l, pre, l) == 0;
226 bool prefixIs(string const & a, string const & pre)
228 string::size_type const prelen = pre.length();
229 string::size_type const alen = a.length();
231 if (prelen < alen || a.empty())
234 #if !defined(USE_INCLUDED_STRING) && !defined(STD_STRING_IS_GOOD)
235 return ::strncmp(a.c_str(), pre.c_str(), prelen) == 0;
237 return a.compare(0, prelen, pre) == 0;
243 bool suffixIs(string const & a, char c)
245 if (a.empty()) return false;
246 return a[a.length() - 1] == c;
250 bool suffixIs(string const & a, char const * suf)
254 size_t const suflen = strlen(suf);
255 if (suflen > a.length())
258 #if !defined(USE_INCLUDED_STRING) && !defined(STD_STRING_IS_GOOD)
259 // Delete this code when the compilers get a bit better.
260 string tmp(a, a.length() - suflen);
261 return ::strncmp(tmp.c_str(), suf, suflen) == 0;
263 // This is the code that we really want to use
264 // but until gcc ships with a basic_string that
265 // implements std::string correctly we have to
266 // use the code above.
267 return a.compare(a.length() - suflen, suflen, suf) == 0;
273 bool suffixIs(string const & a, string const & suf)
275 string::size_type const suflen = suf.length();
276 string::size_type const alen = a.length();
281 #if !defined(USE_INCLUDED_STRING) && !defined(STD_STRING_IS_GOOD)
282 string tmp(a, alen - suflen);
283 return ::strncmp(tmp.c_str(), suf.c_str(), suflen) == 0;
285 return a.compare(alen - suflen, suflen, suf) == 0;
291 bool contains(char const * a, string const & b)
295 return contains(at, b);
299 bool contains(string const & a, char const * b)
303 return contains(a, bt);
307 bool contains(string const & a, string const & b)
311 return a.find(b) != string::npos;
315 bool contains(char const * a, char const * b)
320 return contains(at, bt);
324 bool containsOnly(string const & s, char const * cset)
328 return s.find_first_not_of(cset) == string::npos;
332 bool containsOnly(string const & s, string const & cset)
334 return s.find_first_not_of(cset) == string::npos;
338 bool containsOnly(char const * s, char const * cset)
342 return string(s).find_first_not_of(cset) == string::npos;
346 bool containsOnly(char const * s, string const & cset)
350 return string(s).find_first_not_of(cset) == string::npos;
354 string::size_type countChar(string const & a, char c)
356 #ifdef HAVE_STD_COUNT
357 return count(a.begin(), a.end(), c);
360 count(a.begin(), a.end(), c, n);
366 // ale970405+lasgoutt-970425
367 // rewritten to use new string (Lgb)
368 string const token(string const & a, char delim, int n)
370 if (a.empty()) return string();
372 string::size_type k = 0;
373 string::size_type i = 0;
375 // Find delimiter or end of string
377 if ((i = a.find(delim, i)) == string::npos)
381 // i is now the n'th delim (or string::npos)
382 if (i == string::npos) return string();
383 k = a.find(delim, i);
384 // k is now the n'th + 1 delim (or string::npos)
386 return a.substr(i, k - i);
390 // this could probably be faster and/or cleaner, but it seems to work (JMarc)
391 // rewritten to use new string (Lgb)
392 int tokenPos(string const & a, char delim, string const & tok)
398 while (!str.empty()) {
399 str = split(str, tmptok, delim);
408 bool regexMatch(string const & a, string const & pattern)
410 // We massage the pattern a bit so that the usual
411 // shell pattern we all are used to will work.
412 // One nice thing about using a real regex is that
413 // things like "*.*[^~]" will work also.
414 // build the regex string.
415 string regex(pattern);
416 regex = subst(regex, ".", "\\.");
417 regex = subst(regex, "*", ".*");
419 return reg.exact_match(a);
423 string const subst(string const & a, char oldchar, char newchar)
426 string::iterator lit = tmp.begin();
427 string::iterator end = tmp.end();
428 for (; lit != end; ++lit)
429 if ((*lit) == oldchar)
435 string const subst(string const & a,
436 char const * oldstr, string const & newstr)
441 string::size_type i = 0;
442 string::size_type olen = strlen(oldstr);
443 while((i = lstr.find(oldstr, i)) != string::npos) {
444 lstr.replace(i, olen, newstr);
445 i += newstr.length(); // We need to be sure that we dont
446 // use the same i over and over again.
452 string const subst(string const & a,
453 string const & oldstr, string const & newstr)
456 string::size_type i = 0;
457 string::size_type const olen = oldstr.length();
458 while((i = lstr.find(oldstr, i)) != string::npos) {
459 lstr.replace(i, olen, newstr);
460 i += newstr.length(); // We need to be sure that we dont
461 // use the same i over and over again.
467 string const strip(string const & a, char c)
469 if (a.empty()) return a;
471 string::size_type i = tmp.find_last_not_of(c);
472 if (i == a.length() - 1) return tmp; // no c's at end of a
473 if (i != string::npos)
474 tmp.erase(i + 1, string::npos);
476 tmp.erase(); // only c in the whole string
481 string const frontStrip(string const & a, char const * p)
485 if (a.empty() || !*p) return a;
487 string::size_type i = tmp.find_first_not_of(p);
494 string const frontStrip(string const & a, char c)
496 if (a.empty()) return a;
498 string::size_type i = tmp.find_first_not_of(c);
505 string const split(string const & a, string & piece, char delim)
508 string::size_type i = a.find(delim);
509 if (i == a.length() - 1) {
510 piece = a.substr(0, i);
511 } else if (i != string::npos) {
512 piece = a.substr(0, i);
513 tmp = a.substr(i + 1);
516 tmp = a.substr(i + 1);
524 string const split(string const & a, char delim)
527 string::size_type i = a.find(delim);
528 if (i != string::npos) // found delim
529 tmp = a.substr(i + 1);
535 string const rsplit(string const & a, string & piece, char delim)
538 string::size_type i = a.rfind(delim);
539 if (i != string::npos) { // delimiter was found
540 piece = a.substr(0, i);
541 tmp = a.substr(i + 1);
542 } else { // delimter was not found