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