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