]> git.donarmstrong.com Git - lilypond.git/blob - flower/string.cc
* flower/include/std-string.hh: Oops, bugfix for --disable-std-string.
[lilypond.git] / flower / string.cc
1 /*
2   string.cc - implement String
3
4   (c) 1997--2006 Han-Wen Nienhuys & Jan Nieuwenhuizen
5 */
6
7 #ifndef _GNU_SOURCE // we want memmem
8 #define _GNU_SOURCE
9 #endif
10
11 #include "string.hh"
12
13 #include <cstdlib>
14 #include <cstdio>
15 #include <cassert>
16 #include <cstring>
17
18 #include <iostream>
19 using namespace std;
20
21 #include "libc-extension.hh"
22 #include "string-convert.hh"
23
24 /* std::string conversion helpers */
25
26 #if STD_STRING
27
28 #include "std-string.hh"
29
30 String::String (Std_string const &s)
31 {
32   *this = String (s.c_str ());
33 }
34
35 String::operator Std_string () const
36 {
37   return Std_string (this->c_str ());
38 }
39
40 #endif
41
42 /* std::string interface */
43
44 String::String (String const &s, int pos, int n)
45 {
46   if (n == -1)
47     n = s.length () - pos;
48   if (pos == 0)
49     *this = s.left_string (n);
50   else
51     *this = s.right_string (s.length () - pos).left_string (n);
52 }
53
54 String::String (int n, char c)
55 {
56   *this = String_convert::char_string (c, n);
57 }
58
59 char const *
60 String::c_str () const
61 {
62   return to_str0 ();
63 }
64
65 bool
66 String::empty () const
67 {
68   return is_empty ();
69 }
70
71 int
72 String::find (char c) const
73 {
74   return index (c);
75 }
76
77 int
78 String::find (String &s, int pos) const
79 {
80   if (!pos)
81     return index (s);
82   String f = right_string (length () - pos);
83   int n = f.index (s);
84   if (n != -1)
85     return pos + n;
86   return -1;
87 }
88
89 int
90 String::rfind (char c) const
91 {
92   return index_last (c);
93 }
94
95 String
96 String::replace (int pos, int n, String str)
97 {
98   return String (*this, 0, pos) + str + String (*this, pos + n);
99 }
100
101
102
103 /* String */
104
105 #ifdef STRING_DEBUG
106 void *mymemmove (void *dest, void const *src, size_t n);
107 #define memmove mymemmove
108 #endif
109
110 // return array, alloced with new.
111 Byte *
112 String::get_copy_byte () const
113 {
114   Byte const *src = strh_.to_bytes ();
115   Byte *dest = new Byte[strh_.length () + 1];
116   memcpy (dest, src, strh_.length () + 1);
117   return dest;
118 }
119
120 char *
121 String::get_copy_str0 () const
122 {
123   return (char *)get_copy_byte ();
124 }
125
126 \f
127 /*
128   copying, constructing.
129 */
130 String &
131 String::operator = (String const &source)
132 {
133   strh_ = source.strh_;
134   return *this;
135 }
136
137 String::String (Byte const *byte, int len_i)
138 {
139   strh_.set (byte, len_i);
140 }
141
142 /**
143    @see
144    String_convert::
145 */
146 String
147 to_string (char c, int n)
148 {
149   return String_convert::char_string (c, n);
150 }
151
152 String
153 to_string (double f, char const *format)
154 {
155   return String_convert::double_string (f, format);
156 }
157
158 String
159 to_string (int i, char const *format)
160 {
161   return String_convert::int_string (i, format);
162 }
163
164 String
165 to_string (bool b)
166 {
167   return String_convert::bool_string (b);
168 }
169 String
170 to_string (long b)
171 {
172   return String_convert::long_string (b);
173 }
174
175 String
176 to_string (char const *format, ...)
177 {
178   va_list args;
179   va_start (args, format);
180   String str = String_convert::vform_string (format, args);
181   va_end (args);
182   return str;
183 }
184
185 \f
186 void
187 String::append (String s)
188 {
189   strh_.append (s.to_bytes (), s.length ());
190 }
191 void
192 String::operator += (String s)
193 {
194   append (s);
195 }
196
197 void
198 String::prepend (String s)
199 {
200   s += *this;
201   *this = s;
202 }
203
204 int
205 String::length () const
206 {
207   return strh_.length ();
208 }
209
210 Byte const *
211 String::to_bytes () const
212 {
213   return strh_.to_bytes ();
214 }
215
216 Byte *
217 String::get_bytes ()
218 {
219   return strh_.get_bytes ();
220 }
221
222 char *
223 String::get_str0 ()
224 {
225   return strh_.get_str0 ();
226 }
227
228 bool
229 String::is_empty () const
230 {
231   return !length ();
232 }
233 /**
234    Do a signed comparison,  analogous to memcmp;
235 */
236 int
237 String::compare (String const &s1, String const &s2)
238 {
239   Byte const *p1 = s1.to_bytes ();
240   Byte const *p2 = s2.to_bytes ();
241   if (p1 == p2)
242     return 0;
243
244   /*
245     don't forget the terminating '\0'
246   */
247   int f = min (s1.length (), s2.length ());
248   int cmp_length = 1+ f;
249   int i = memcmp (p1, p2, cmp_length);
250   return i;
251 }
252
253 \f
254 int
255 String::index_last (char const c) const
256 {
257   if (!length ())
258     return -1;
259
260   char const *me = strh_.to_str0 ();
261   char const *p = (char const *)memrchr ((Byte *)me, length (), c);
262   if (p)
263     return p - me;
264   return -1;
265 }
266
267 int
268 String::index_last (char const *string) const // UGK!
269 {
270   assert (false);               // broken
271   int len = strlen (string); // ugrh
272   if (!length () || !len)
273     return -1;
274
275   int next_i = index (string);
276   if (next_i == -1)
277     return -1;
278
279   int index_i = 0;
280   while (next_i >= 0)
281     {
282       index_i += next_i;
283       next_i = right_string (length () - index_i - len).index (string);
284     }
285   return index_i;
286 }
287
288 /** find  a character.
289
290 @return
291 the index of the leftmost character #c# (0 <= return < length ()),
292 or   -1 if not found.
293
294 ? should return length ()?, as in string.left_string (index (delimiter))
295 */
296 int
297 String::index (char c) const
298 {
299   char const *me = strh_.to_str0 ();
300   char const *p = (char const *) memchr (me, c, length ());
301   if (p)
302     return p - me;
303   return -1;
304 }
305
306 /**
307    find a substring.
308
309    @return
310    index of leftmost occurrence of #searchfor#
311 */
312 int
313 String::index (String searchfor) const
314 {
315   char const *me = strh_.to_str0 ();
316
317   char const *p
318     = (char const *) memmem (me, length (),
319                              searchfor.to_str0 (), searchfor.length ());
320
321   if (p)
322     return p - me;
323
324   return -1;
325 }
326
327 /** find chars of a set.
328
329 @return
330
331 the index of the leftmost occurance of an element of #set#.  -1 if
332 nothing is found.
333 */
334 int
335 String::index_any (String set) const
336 {
337   int n = length ();
338   if (!n)
339     return -1;
340
341   void const *me = (void const *) strh_.to_str0 ();
342   for (int i = 0; i < set.length (); i++)
343     {
344       char *found = (char *) memchr (me, set[i], n);
345       if (found)
346         return found - (char const *)me;
347     }
348   return -1;
349 }
350 \f
351 String
352 String::left_string (int n) const
353 {
354   if (n >= length ())
355     return *this;
356
357   String retval;
358   if (n < 1)
359     return retval;
360
361   retval = *this;
362   retval.strh_.trunc (n);
363   return retval;
364 }
365
366 String
367 String::right_string (int n) const
368 {
369   if (n > length ())
370     return *this;
371
372   if (n < 1)
373     return "";
374
375   return String (strh_.to_bytes () + length () - n, n);
376 }
377
378 String
379 String::nomid_string (int index_i, int n) const
380 {
381   if (index_i < 0)
382     {
383       n += index_i;
384       index_i = 0;
385     }
386   if (n <= 0)
387     return *this;
388
389   return left_string (index_i) + right_string (length () - index_i - n);
390 }
391
392 String
393 String::cut_string (int index_i, int n) const
394 {
395   if (index_i < 0)
396     {
397       n += index_i;
398       index_i = 0;
399     }
400
401   if (!length () || (index_i < 0) || (index_i >= length ()) || (n < 1))
402     return String ();
403
404   if ((n > length ()) || (index_i + n > length ()))
405     n = length () - index_i;
406
407   return String (to_bytes () + index_i, n);
408 }
409 \f
410
411 void
412 String::to_upper ()
413 {
414   strnupr (get_str0 (), length ());
415 }
416
417 void
418 String::to_lower ()
419 {
420   strnlwr (get_str0 (), length ());
421 }
422
423 void
424 String::reverse ()
425 {
426   memrev (get_bytes (), length ());
427 }
428
429 int
430 String::to_int () const
431 {
432   return String_convert::dec2int (*this);
433 }
434
435 double
436 String::to_double () const
437 {
438   return String_convert::dec2double (*this);
439 }
440
441 #ifdef STREAM_SUPPORT
442 ostream &
443 operator << (ostream &os, String d)
444 {
445   d.print_on (os);
446   return os;
447 }
448
449 void
450 String::print_on (ostream &os) const
451 {
452   if (!strh_.is_binary_bo ())
453     os << to_str0 ();
454   else
455     for (int i = 0; i < length (); i++)
456       os << (Byte) (*this)[ i ];
457 }
458 #endif
459
460 String
461 String::substitute (String find, String replace)
462 {
463   int n = find.length ();
464   int m = replace.length ();
465   for (int i = index (find), j = 0; i > -1;
466        i = right_string (length () - j).index (find))
467     {
468       *this = left_string (i + j)
469         + replace
470         + right_string (length () - j - i - n);
471       j += i + m;
472     }
473   return *this;
474 }
475
476 String
477 String::substitute (char find, char replace)
478 {
479   for (int i = index (find); i > - 1; i = index (find))
480     (*this)[i] = replace;
481   return *this;
482 }