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