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)
37 string::const_iterator p = s.begin();
38 string::const_iterator p2 = s2.begin();
40 while (p != s.end() && p2 != s2.end()) {
41 int const lc1 = tolower(*p);
42 int const lc2 = tolower(*p2);
44 return (lc1 < lc2) ? -1 : 1;
49 if (s.size() == s2.size())
51 if (s.size() < s2.size())
57 int compare_no_case(string const & s, string const & s2, unsigned int len)
59 string::const_iterator p = s.begin();
60 string::const_iterator p2 = s2.begin();
62 while (i < len && p != s.end() && p2 != s2.end()) {
63 int const lc1 = tolower(*p);
64 int const lc2 = tolower(*p2);
66 return (lc1 < lc2) ? -1 : 1;
72 if (s.size() >= len && s2.size() >= len)
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 bool isStrUnsignedInt(string const & str)
100 if (str.empty()) return false;
102 // Remove leading and trailing white space chars.
103 string const tmpstr = frontStrip(strip(str, ' '), ' ');
104 if (tmpstr.empty()) return false;
106 string::const_iterator cit = tmpstr.begin();
107 string::const_iterator end = tmpstr.end();
108 for (; cit != end; ++cit) {
109 if (!isdigit((*cit))) return false;
115 int strToInt(string const & str)
118 // Remove leading and trailing white space chars.
119 string const tmpstr = frontStrip(strip(str, ' '), ' ');
120 // Do the conversion proper.
121 return lyx::atoi(tmpstr);
128 unsigned int strToUnsignedInt(string const & str)
130 if (isStrUnsignedInt(str)) {
131 // Remove leading and trailing white space chars.
132 string const tmpstr = frontStrip(strip(str, ' '), ' ');
133 // Do the conversion proper.
134 return lyx::atoi(tmpstr);
141 bool isStrDbl(string const & str)
143 if (str.empty()) return false;
145 // Remove leading and trailing white space chars.
146 string const tmpstr = frontStrip(strip(str, ' '), ' ');
147 if (tmpstr.empty()) return false;
148 // if (1 < tmpstr.count('.')) return false;
150 string::const_iterator cit = tmpstr.begin();
151 bool found_dot(false);
152 if ((*cit) == '-') ++cit;
153 string::const_iterator end = tmpstr.end();
154 for (; cit != end; ++cit) {
171 double strToDbl(string const & str)
174 // Remove leading and trailing white space chars.
175 string const tmpstr = frontStrip(strip(str, ' '), ' ');
176 // Do the conversion proper.
177 return ::atof(tmpstr.c_str());
184 char lowercase(char c)
186 return char( tolower(c) );
190 char uppercase(char c)
192 return char( toupper(c) );
196 string const lowercase(string const & a)
200 string::iterator result = tmp.begin();
201 string::iterator end = tmp.end();
202 for (string::iterator first = tmp.begin();
203 first != end; ++first, ++result) {
204 *result = lowercase(*first);
207 // We want to use this one. (Lgb)
208 transform(tmp.begin(), tmp.end(), tmp.begin(), lowercase);
214 string const uppercase(string const & a)
218 string::iterator result = tmp.begin();
219 string::iterator end = tmp.end();
220 for (string::iterator first = tmp.begin();
221 first != end; ++first, ++result) {
222 *result = uppercase(*first);
225 // We want to use this one. (Lgb)
226 transform(tmp.begin(), tmp.end(), tmp.begin(), uppercase);
232 bool prefixIs(string const & a, char const * pre)
236 size_t const l = strlen(pre);
237 string::size_type const alen = a.length();
239 if (l > alen || a.empty())
242 #if !defined(USE_INCLUDED_STRING) && !defined(STD_STRING_IS_GOOD)
243 // Delete this code when the compilers get a bit better.
244 return ::strncmp(a.c_str(), pre, l) == 0;
246 // This is the code that we really want to use
247 // but until gcc ships with a basic_string that
248 // implements std::string correctly we have to
249 // use the code above.
250 return a.compare(0, l, pre, l) == 0;
256 bool prefixIs(string const & a, string const & pre)
258 string::size_type const prelen = pre.length();
259 string::size_type const alen = a.length();
261 if (prelen > alen || a.empty())
264 #if !defined(USE_INCLUDED_STRING) && !defined(STD_STRING_IS_GOOD)
265 return ::strncmp(a.c_str(), pre.c_str(), prelen) == 0;
267 return a.compare(0, prelen, pre) == 0;
273 bool suffixIs(string const & a, char c)
275 if (a.empty()) return false;
276 return a[a.length() - 1] == c;
280 bool suffixIs(string const & a, char const * suf)
284 size_t const suflen = strlen(suf);
285 string::size_type const alen = a.length();
290 #if !defined(USE_INCLUDED_STRING) && !defined(STD_STRING_IS_GOOD)
291 // Delete this code when the compilers get a bit better.
292 string tmp(a, alen - suflen);
293 return ::strncmp(tmp.c_str(), suf, suflen) == 0;
295 // This is the code that we really want to use
296 // but until gcc ships with a basic_string that
297 // implements std::string correctly we have to
298 // use the code above.
299 return a.compare(alen - suflen, suflen, suf) == 0;
305 bool suffixIs(string const & a, string const & suf)
307 string::size_type const suflen = suf.length();
308 string::size_type const alen = a.length();
313 #if !defined(USE_INCLUDED_STRING) && !defined(STD_STRING_IS_GOOD)
314 string tmp(a, alen - suflen);
315 return ::strncmp(tmp.c_str(), suf.c_str(), suflen) == 0;
317 return a.compare(alen - suflen, suflen, suf) == 0;
323 bool contains(char const * a, string const & b)
327 return contains(at, b);
331 bool contains(string const & a, char const * b)
335 return contains(a, bt);
339 bool contains(string const & a, string const & b)
343 return a.find(b) != string::npos;
347 bool contains(char const * a, char const * b)
352 return contains(at, bt);
356 bool containsOnly(string const & s, char const * cset)
360 return s.find_first_not_of(cset) == string::npos;
364 bool containsOnly(string const & s, string const & cset)
366 return s.find_first_not_of(cset) == string::npos;
370 bool containsOnly(char const * s, char const * cset)
374 return string(s).find_first_not_of(cset) == string::npos;
378 bool containsOnly(char const * s, string const & cset)
382 return string(s).find_first_not_of(cset) == string::npos;
386 string::size_type countChar(string const & a, char c)
388 #ifdef HAVE_STD_COUNT
389 return count(a.begin(), a.end(), c);
392 count(a.begin(), a.end(), c, n);
398 // ale970405+lasgoutt-970425
399 // rewritten to use new string (Lgb)
400 string const token(string const & a, char delim, int n)
402 if (a.empty()) return string();
404 string::size_type k = 0;
405 string::size_type i = 0;
407 // Find delimiter or end of string
409 if ((i = a.find(delim, i)) == string::npos)
413 // i is now the n'th delim (or string::npos)
414 if (i == string::npos) return string();
415 k = a.find(delim, i);
416 // k is now the n'th + 1 delim (or string::npos)
418 return a.substr(i, k - i);
422 // this could probably be faster and/or cleaner, but it seems to work (JMarc)
423 // rewritten to use new string (Lgb)
424 int tokenPos(string const & a, char delim, string const & tok)
430 while (!str.empty()) {
431 str = split(str, tmptok, delim);
440 bool regexMatch(string const & a, string const & pattern)
442 // We massage the pattern a bit so that the usual
443 // shell pattern we all are used to will work.
444 // One nice thing about using a real regex is that
445 // things like "*.*[^~]" will work also.
446 // build the regex string.
447 string regex(pattern);
448 regex = subst(regex, ".", "\\.");
449 regex = subst(regex, "*", ".*");
451 return reg.exact_match(a);
455 string const subst(string const & a, char oldchar, char newchar)
458 string::iterator lit = tmp.begin();
459 string::iterator end = tmp.end();
460 for (; lit != end; ++lit)
461 if ((*lit) == oldchar)
467 string const subst(string const & a,
468 char const * oldstr, string const & newstr)
473 string::size_type i = 0;
474 string::size_type olen = strlen(oldstr);
475 while((i = lstr.find(oldstr, i)) != string::npos) {
476 lstr.replace(i, olen, newstr);
477 i += newstr.length(); // We need to be sure that we dont
478 // use the same i over and over again.
484 string const subst(string const & a,
485 string const & oldstr, string const & newstr)
488 string::size_type i = 0;
489 string::size_type const olen = oldstr.length();
490 while((i = lstr.find(oldstr, i)) != string::npos) {
491 lstr.replace(i, olen, newstr);
492 i += newstr.length(); // We need to be sure that we dont
493 // use the same i over and over again.
499 string const strip(string const & a, char c)
501 if (a.empty()) return a;
503 string::size_type i = tmp.find_last_not_of(c);
504 if (i == a.length() - 1) return tmp; // no c's at end of a
505 if (i != string::npos)
506 tmp.erase(i + 1, string::npos);
508 tmp.erase(); // only c in the whole string
513 string const frontStrip(string const & a, char const * p)
517 if (a.empty() || !*p) return a;
519 string::size_type i = tmp.find_first_not_of(p);
526 string const frontStrip(string const & a, char c)
528 if (a.empty()) return a;
530 string::size_type i = tmp.find_first_not_of(c);
537 string const split(string const & a, string & piece, char delim)
540 string::size_type i = a.find(delim);
541 if (i == a.length() - 1) {
542 piece = a.substr(0, i);
543 } else if (i != string::npos) {
544 piece = a.substr(0, i);
545 tmp = a.substr(i + 1);
548 tmp = a.substr(i + 1);
556 string const split(string const & a, char delim)
559 string::size_type i = a.find(delim);
560 if (i != string::npos) // found delim
561 tmp = a.substr(i + 1);
567 string const rsplit(string const & a, string & piece, char delim)
570 string::size_type i = a.rfind(delim);
571 if (i != string::npos) { // delimiter was found
572 piece = a.substr(0, i);
573 tmp = a.substr(i + 1);
574 } else { // delimter was not found