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