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