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