]> git.lyx.org Git - lyx.git/blob - src/support/lstrings.C
Small things in my tree.
[lyx.git] / src / support / lstrings.C
1 #include <config.h>
2
3 #include <algorithm>
4
5 #include <cctype>
6 #include <cstdlib>
7
8 #include "LString.h"
9 #include "lstrings.h"
10 #include "LRegex.h"
11
12 using std::count;
13 using std::transform;
14 #ifndef __GLIBCPP__
15 // The new glibstdc++-v3 has not worked out all the quirks regarding cctype
16 // yet. So currently it failes if the to using lines below are stated.
17 using std::tolower;
18 using std::toupper;
19 #endif
20         
21 int compare_no_case(string const & s, string const & s2)
22 {
23         // ANSI C
24         string::const_iterator p = s.begin();
25         string::const_iterator p2 = s2.begin();
26
27         while (p != s.end() && p2 != s2.end()) {
28                 int const lc1 = tolower(*p);
29                 int const lc2 = tolower(*p2);
30                 if (lc1 != lc2)
31                         return (lc1 < lc2) ? -1 : 1;
32                 ++p;
33                 ++p2;
34         }
35         
36         if (s.size() == s2.size())
37                 return 0;
38         if (s.size() < s2.size())
39                 return -1;
40         return 1;
41 }
42
43
44 int compare_no_case(string const & s, string const & s2, unsigned int len)
45 {
46 //#warning verify this func please
47         string::const_iterator p = s.begin();
48         string::const_iterator p2 = s2.begin();
49         unsigned int i = 0;
50         while (i < len && p != s.end() && p2 != s2.end()) {
51                 int const lc1 = tolower(*p);
52                 int const lc2 = tolower(*p2);
53                 if (lc1 != lc2)
54                         return (lc1 < lc2) ? -1 : 1;
55                 ++i;
56                 ++p;
57                 ++p2;
58         }
59         if (s.size() == s2.size())
60                 return 0;
61         if (s.size() < s2.size())
62                 return -1;
63         return 1;
64 }
65
66
67 bool isStrInt(string const & str)
68 {
69         if (str.empty()) return false;
70        
71         // Remove leading and trailing white space chars.
72         string tmpstr = frontStrip(strip(str, ' '), ' ');
73         if (tmpstr.empty()) return false;
74        
75         string::const_iterator cit = tmpstr.begin();
76         if ( (*cit) == '-') ++cit;
77         for (; cit != tmpstr.end(); ++cit) {
78                 if (!isdigit((*cit))) return false;
79         }
80         return true;
81 }
82
83
84 int  strToInt(string const & str)
85 {
86         string tmpstr;
87
88         if (isStrInt(str)) {
89                 // Remove leading and trailing white space chars.
90                 tmpstr = frontStrip(strip(str, ' '), ' ');
91                 // Do the conversion proper.
92                 return atoi(tmpstr.c_str());
93         } else {
94                 return 0;
95         }
96 }
97
98
99
100 ///
101 bool isStrDbl(string const & str)
102 {
103         if (str.empty()) return false;
104         
105         // Remove leading and trailing white space chars.
106         string tmpstr = frontStrip(strip(str, ' '), ' ');
107         if (tmpstr.empty()) return false;
108         //      if (1 < tmpstr.count('.')) return false;
109
110         string::const_iterator cit = tmpstr.begin();
111         bool found_dot(false);
112         if ( (*cit) == '-') ++cit;
113         for (; cit != tmpstr.end(); ++cit) {
114                 if (!isdigit((*cit))
115                     && '.' != (*cit)) {
116                         return false;
117                 }
118                 if ('.' == (*cit)) {
119                         if (found_dot) {
120                                 return false;
121                         } else {
122                                 found_dot = true;
123                         }
124                 }
125         }
126         return true;
127 }
128
129 ///
130 double strToDbl(string const & str)
131 {
132         string tmpstr;
133
134         if (isStrDbl(str)) {
135                 // Remove leading and trailing white space chars.
136                 tmpstr = frontStrip(strip(str, ' '), ' ');
137                 // Do the conversion proper.
138                 return atof(tmpstr.c_str());
139         } else {
140                 return 0.0;
141         }
142 }
143
144
145
146 string lowercase(string const & a)
147 {
148         string tmp(a);
149 //#ifdef __GLIBCPP__
150         string::iterator result = tmp.begin();
151         for (string::iterator first = tmp.begin();
152              first != tmp.end(); ++first, ++result) {
153                 *result = tolower(*first);
154         }
155 //#else
156 //      transform(tmp.begin(), tmp.end(), tmp.begin(), tolower);
157 //#endif
158         return tmp;
159 }
160
161
162 string uppercase(string const & a)
163 {
164         string tmp(a);
165 //#ifdef __GLIBCPP__
166         string::iterator result = tmp.begin();
167         for (string::iterator first = tmp.begin();
168              first != tmp.end(); ++first, ++result) {
169                 *result = toupper(*first);
170         }
171 //#else
172 //      transform(tmp.begin(), tmp.end(), tmp.begin(), toupper);
173 //#endif
174         return tmp;
175 }
176
177
178 bool prefixIs(string const & a, char const * pre)
179 {
180         unsigned int l = strlen(pre);
181         if (l > a.length() || a.empty())
182                 return false;
183         else
184                 return a.compare(0, l, pre, l) == 0;
185 }
186
187
188 bool suffixIs(string const & a, char c)
189 {
190         if (a.empty()) return false;
191         return a[a.length() - 1] == c;
192 }
193
194
195 bool suffixIs(string const & a, char const * suf)
196 {
197         unsigned int suflen = strlen(suf);
198         if (suflen > a.length())
199                 return false;
200         else {
201                 return a.compare(a.length() - suflen, suflen, suf) == 0;
202         }
203 }
204
205
206 bool contains(char const * a, string const & b)
207 {
208         if (!a || !*a || b.empty()) return false;
209         return strstr(a, b.c_str()) != 0;
210 }
211
212
213 bool contains(string const & a, char const * b)
214 {
215         if (a.empty())
216                 return false;
217         return a.find(b) != string::npos;
218 }
219
220
221 bool contains(string const & a, string const & b)
222 {
223         if (a.empty())
224                 return false;
225         return a.find(b) != string::npos;
226 }
227
228
229 bool contains(char const * a, char const * b)
230 {
231         if (!a || !b || !*a || !*b) return false;
232         return strstr(a, b) != 0;
233 }
234
235
236 bool containsOnly(string const & s, char const * cset)
237 {
238         return s.find_first_not_of(cset) == string::npos;
239 }
240
241
242 bool containsOnly(string const & s, string const & cset)
243 {
244         return s.find_first_not_of(cset) == string::npos;
245 }
246
247
248 bool containsOnly(char const * s, char const * cset)
249 {
250         return string(s).find_first_not_of(cset) == string::npos;
251 }
252
253
254 bool containsOnly(char const * s, string const & cset)
255 {
256         return string(s).find_first_not_of(cset) == string::npos;
257 }
258
259
260 unsigned int countChar(string const & a, char const c)
261 {
262 #ifdef HAVE_STD_COUNT
263         return count(a.begin(), a.end(), c);
264 #else
265         unsigned int n = 0;
266         count(a.begin(), a.end(), c, n);
267         return n;
268 #endif
269 }
270
271
272 // ale970405+lasgoutt-970425
273 // rewritten to use new string (Lgb)
274 string token(string const & a, char delim, int n)
275 {
276         if (a.empty()) return string();
277         
278         string::size_type k = 0;
279         string::size_type i = 0;
280
281         // Find delimiter or end of string
282         for (; n--;)
283                 if ((i = a.find(delim, i)) == string::npos)
284                         break;
285                 else
286                         ++i; // step delim
287         // i is now the n'th delim (or string::npos)
288         if (i == string::npos) return string();
289         k = a.find(delim, i);
290         // k is now the n'th + 1 delim (or string::npos)
291
292         return a.substr(i, k - i);
293 }
294
295
296 // this could probably be faster and/or cleaner, but it seems to work (JMarc)
297 // rewritten to use new string (Lgb)
298 int tokenPos(string const & a, char delim, string const & tok)
299 {
300         int i = 0;
301         string str = a;
302         string tmptok;
303
304         while (!str.empty()) {
305                 str = split(str, tmptok, delim);
306                 if (tok == tmptok)
307                         return i;
308                 ++i;
309         }
310         return -1;
311 }
312
313
314 bool regexMatch(string const & a, string const & pattern)
315 {
316         // We massage the pattern a bit so that the usual
317         // shell pattern we all are used to will work.
318         // One nice thing about using a real regex is that
319         // things like "*.*[^~]" will work also.
320         // build the regex string.
321         string regex(pattern);
322         regex = subst(regex, ".", "\\.");
323         regex = subst(regex, "*", ".*");
324         LRegex reg(regex);
325         return reg.exact_match(a);
326 }
327
328
329 string subst(string const & a, char oldchar, char newchar)
330 {
331         string tmp = a;
332         string::iterator lit = tmp.begin();
333         for(; lit != tmp.end(); ++lit)
334                 if ((*lit) == oldchar)
335                         (*lit) = newchar;
336         return tmp;
337 }
338
339
340 string subst(string const & a,
341              char const * oldstr, string const & newstr)
342 {
343         string lstr(a);
344         string::size_type i = 0;
345         int olen = strlen(oldstr);
346         while((i = lstr.find(oldstr, i)) != string::npos) {
347                 lstr.replace(i, olen, newstr);
348                 i += newstr.length(); // We need to be sure that we dont
349                 // use the same i over and over again.
350         }
351         return lstr;
352 }
353
354
355 string strip(string const & a, char const c)
356 {
357         if (a.empty()) return a;
358         string tmp = a;
359         string::size_type i = tmp.find_last_not_of(c);
360         if (i == a.length() - 1) return tmp; // no c's at end of a
361         if (i != string::npos) 
362                 tmp.erase(i + 1, string::npos);
363         else
364                 tmp.erase(); // only c in the whole string
365         return tmp;
366 }
367
368
369 string frontStrip(string const & a, char const * p)
370 {
371         if (a.empty() || !p || !*p) return a;
372         string tmp = a;
373         string::size_type i = tmp.find_first_not_of(p);
374         if (i > 0)
375                 tmp.erase(0, i);
376         return tmp;
377 }
378
379
380 string frontStrip(string const & a, char const c)
381 {
382         if (a.empty()) return a;
383         string tmp = a;
384         string::size_type i = tmp.find_first_not_of(c);
385         if (i > 0)
386                 tmp.erase(0, i);
387         return tmp;
388 }
389
390
391 string split(string const & a, string & piece, char delim)
392 {
393         string tmp;
394         string::size_type i = a.find(delim);
395         if (i == a.length() - 1) {
396                 piece = a.substr(0, i);
397         } else if (i != string::npos) {
398                 piece = a.substr(0, i);
399                 tmp = a.substr(i + 1);
400         } else if (i == 0) {
401                 piece.erase();
402                 tmp = a.substr(i + 1);
403         } else {
404                 piece = a;
405         }
406         return tmp;
407 }
408
409
410 string split(string const & a, char delim)
411 {
412         string tmp;
413         string::size_type i = a.find(delim);
414         if (i != string::npos) // found delim
415                 tmp = a.substr(i + 1);
416         return tmp;
417 }
418
419
420 // ale970521
421 string rsplit(string const & a, string & piece, char delim)
422 {
423         string tmp;
424         string::size_type i = a.rfind(delim);
425         if (i != string::npos) { // delimiter was found
426                 piece = a.substr(0, i);
427                 tmp = a.substr(i + 1);
428         } else { // delimter was not found
429                 piece.erase();
430         }
431         return tmp;
432 }