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