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