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