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