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