]> git.donarmstrong.com Git - lilypond.git/blob - flower/string.cc
2003 -> 2004
[lilypond.git] / flower / string.cc
1 /*
2
3  string.cc - implement String
4  
5   (c) 1997--2004 Han-Wen Nienhuys & Jan Nieuwenhuizen
6
7  */
8
9 #ifndef _GNU_SOURCE // we want memmem
10 #define _GNU_SOURCE
11 #endif
12
13 #include <stdlib.h>
14 #include <stdio.h>
15 #include <assert.h>
16 #include <string.h>
17 #include <stdarg.h>
18
19 #include <iostream>
20
21 #include "string.hh"
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 1  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   else
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
321     left_string (index_i)   +
322     right_string (length () - index_i - n) ;
323 }
324
325 String
326 String::cut_string (int index_i, int n) const
327 {
328   if (index_i <0) 
329     {
330       n += index_i;
331       index_i=0;
332     }
333   
334   if (!length () || (index_i < 0) || (index_i >= length () ) || (n < 1 ) )
335     return String ();
336
337   if ((n > length ()) || (index_i + n > length () ) )
338     n = length () - index_i;
339
340   return String (to_bytes () + index_i, n);
341 }
342 \f
343 String
344 String::upper_string () const
345 {
346   String str = *this;
347   str.to_upper ();
348   return str;
349 }
350 void
351 String::to_upper ()
352 {
353   char *s = (char*)strh_.get_bytes ();
354   strnupr (s ,length ());
355 }
356
357 void
358 String::to_lower ()
359 {
360   char* s = strh_.get_str0 ();
361   strnlwr (s,length ());    
362 }
363
364
365 String 
366 String::lower_string () const
367 {
368   String str = *this;
369   str.to_lower ();
370   return str;
371 }
372 String 
373 String::reversed_string () const
374 {
375   String str = *this;
376   strrev (str.get_bytes (), str.length ());
377   return str;    
378 }
379
380 int
381 String::to_int () const
382 {
383   return String_convert::dec2int (*this);
384 }
385
386 double
387 String::to_double () const
388 {
389   return String_convert::dec2double (*this);
390 }
391
392 #ifdef STREAM_SUPPORT
393 ostream &
394 operator << (ostream& os, String d)
395 {
396   d.print_on (os);
397   return os;
398 }
399
400
401 void
402 String::print_on (ostream& os) const
403 {
404   if (!strh_.is_binary_bo ())
405     os << to_str0 ();
406   else
407     for (int i = 0; i < length (); i++)
408       os << (Byte) (*this)[ i ];
409 }
410 #endif