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