]> git.donarmstrong.com Git - lilypond.git/blob - flower/string.cc
release: 0.0.37
[lilypond.git] / flower / string.cc
1 /*
2   PROJECT: FlowerSoft C++ library
3   FILE   : string.cc
4
5   Rehacked by HWN 3/nov/95
6   removed String &
7   introduced class String_handle
8   */
9
10 #include <string.h>
11 #include <stdlib.h>
12 #include <stdio.h>
13 #include <ctype.h>
14 #include <assert.h>
15
16 #include "string.hh"
17
18 #ifdef STRING_DEBUG
19 void* mymemmove( void* dest, void const* src, size_t n );
20 #define memmove mymemmove
21 #endif
22
23 static char* 
24 strlwr( char* s )
25 {
26     char* p = s;
27
28     while( *p ) {
29         *p = tolower( *p );    /* a macro on some compilers */
30         p++;
31     }
32     return s;
33 }
34
35 static char* 
36 strupr( char* s )
37 {
38     char* p = s;
39
40     while( *p ) {
41         *p = toupper( *p );    /* a macro on some compilers */
42         p++;
43     }
44     return s;
45 }
46
47 String::String(Rational r)
48 {
49     char * n = Itoa(r.numerator()); // LEAK????
50     
51     *this = n;
52     if (r.denominator() != 1) {
53         char * d = Itoa(r.denominator());
54         *this +=  String( '/' ) + String(d);
55         //delete d;
56     }
57 /*    delete n;
58     */
59 }
60
61 // return array, alloced with new.
62 Byte*
63 String::copy_byte_p() const
64 {
65     Byte const* src = strh_.byte_c_l();
66     Byte* dest = new Byte[strh_.length_i() + 1];
67     memmove( dest, src, strh_.length_i() + 1 );
68     return dest;    
69 }
70
71 void
72 String::print_on(ostream& os) const
73 {
74     if ( length_i() == strlen( ch_c_l() ) )
75         os << ch_c_l();
76     else
77         for ( int i = 0; i < length_i(); i++ )
78             os << (Byte)(*this)[ i ];
79 }
80
81 String::String (bool b)
82 {
83     *this = (char const* ) (b ? "true" : "false");
84 }
85 String::String( char const* source )
86 {   
87     assert(source);    
88     strh_ = source;    
89 }
90
91 String::String( Byte const* byte_l, int length_i )
92 {   
93 //    assert( !length_i || byte_l );// ugh.  Storing null pointers? 
94     strh_.set( byte_l, length_i );    
95 }
96
97 void
98 String::operator +=(String s)
99 {
100     strh_.append( s.byte_c_l(), s.length_i() );
101 }
102
103 int
104 String::length_i() const
105 {
106     return strh_.length_i();
107 }
108
109 // will go away, fixed anyway
110 String::String( char c,  int n )
111 {
112     n = n >= 0 ? n : 0;
113     char* ch_p = new char[ n ];
114     memset( ch_p, c, n );
115     strh_.set( (Byte*)ch_p, n );
116     delete ch_p;
117 }
118
119 String::String(int i)
120 {
121     char digits[ 81 ];             // who the fuck is 80???
122     digits[ 0 ] = '\0';
123     sprintf(digits, "%d", i );     // assume radix 10
124     strh_ = digits;
125 }
126
127 String::String( const int i, const int n, char const c )
128 {
129     char fill_ch = c;
130     if ( fill_ch)
131         fill_ch = '0';
132
133     String v( i );
134     
135     String str = String( fill_ch, n - v.length_i() ) + String( v );
136     strh_.set( str.byte_c_l(), str.length_i() );
137 }
138
139 Byte const*
140 String::byte_c_l() const
141 {
142     return strh_.byte_c_l();
143 }
144
145 char const*
146 String::ch_c_l() const
147 {
148     return strh_.ch_c_l();
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 // signed comparison,  analogous to memcmp;
164 int
165 String::compare_i(String const& s1, String const& s2 ) 
166 {
167     Byte const* p1 = s1.byte_c_l();
168     Byte const* p2 = s2.byte_c_l();
169     if ( p1 == p2 )
170         return 0;
171
172     int i1 = s1.length_i();
173     int i2 = s2.length_i();
174     int i = i1 <? i2;
175
176     int result=  memcmp( p1, p2, i );
177     return result ? result : i1-i2;
178 }
179
180
181 int
182 String::index_last_i( char const c ) const
183 {
184         // not binary safe
185         assert( length_i() == strlen( ch_c_l() ) );
186         if ( !length_i() ) 
187                 return -1;
188
189         char const* me = strh_.ch_c_l();
190         char const* p = strrchr(me, c );
191         if ( p )
192                 return p - me;
193         return -1;
194 }
195
196 int
197 String::index_last_i( char const* string ) const
198 {
199         // not binary safe
200         assert( length_i() == strlen( ch_c_l() ) );
201
202         int length = strlen( string );
203         if ( !length_i() || !length ) 
204                 return -1;
205
206         int next_i = index_i( string );
207         if ( next_i == -1 )
208                 return -1;
209                 
210         int index_i = 0;
211         while( next_i >= 0 ) {
212                 index_i += next_i;
213                 next_i = right_str( length_i() - index_i - length ).index_i( string );
214         }
215         return index_i;
216 }
217
218 // find c
219 // return -1 if not found. 
220
221 // ? should return length_i()?, as in string.left_str(index_i(delimiter))
222 int
223 String::index_i(char c ) const
224 {
225         // not binary safe
226         assert( length_i() == strlen( ch_c_l() ) );
227         if ( !length_i() )
228                 return -1;
229
230         char const* me = strh_.ch_c_l();
231         char const* p = strchr( me, c );
232         if ( p )
233                 return p - me;
234         return -1;
235 }
236
237 // find searchfor. (what if this == "" && searchfor == "") ???
238 int
239 String::index_i( char const* searchfor ) const
240 {
241         // not binary safe
242         assert( length_i() == strlen( ch_c_l() ) );
243         if ( !length_i() || !searchfor )
244                 return -1;
245                 
246         char const* me = strh_.ch_c_l();
247         char const* p = strstr(me, searchfor);
248         if ( p )
249                 return p - me;
250         return -1;
251 }
252
253 // find chars of a set.
254 int
255 String::index_any_i( char const* string ) const
256 {
257         // not binary safe
258         assert( length_i() == strlen( ch_c_l() ) );
259
260         if ( !length_i() || !string )
261                 return -1;
262                 
263         char const* s = (char const* )strh_.ch_c_l();
264         char const* p = strpbrk( s, string );
265         if ( p )
266                 return p - s;
267         return -1;
268 }
269
270 String
271 String::left_str( int n ) const
272 {
273     if (n >= length_i())
274         return *this;
275
276     String retval;      
277     if (n < 1)
278         return retval;
279     
280     retval = *this;
281     retval.strh_.trunc(n);
282     return retval;
283 }
284
285
286 // n rightmst chars
287 String
288 String::right_str( int n ) const
289 {
290     if (n > length_i())
291         return *this;
292     
293     if ( n < 1)
294         String(); 
295     
296     return String( strh_.byte_c_l() + length_i() - n, n ); 
297 }
298
299
300 String
301 String::nomid_str( int index_i, int n ) const
302 {
303         if ( index_i < 0 )
304                 return String();
305         if ( index_i >= length_i() )
306                 return *this;
307     
308         return String( String( left_str( index_i ) ) + right_str( length_i() - index_i - n ));
309 }
310
311
312 String
313 String::mid_str( int index_i, int n ) const
314 {
315         if ( !length_i() || ( index_i < 0 ) || ( index_i >= length_i() ) || ( n < 1 ) )
316                 return String();
317
318         if ( ( n > length_i() ) ||  ( index_i + n > length_i() ) )
319                 n = length_i() - index_i;
320
321         return String( byte_c_l() + index_i, n );
322 }
323
324
325 // return uppercase
326 String
327 String::upper_str() const
328 {
329     // not binary safe
330     assert( length_i() == strlen( ch_c_l() ) );
331     String str = *this;
332     char *s = str.strh_.byte_l();
333     strupr( s );
334     return str;
335 }
336
337
338 // return lowercase
339 String 
340 String::lower_str() const
341 {
342     // not binary safe
343     assert( length_i() == strlen( ch_c_l() ) );
344     String str = *this;
345     char* s = str.strh_.ch_l();
346     strlwr(s);
347     return str;
348 }
349
350 String::String (double f, char const* fmt)
351 {
352     /* worst case would be printing HUGE (or 1/HUGE), which is approx
353        2e318, this number would have approx 318 zero's in its string.
354
355       1024 is a safe length for the buffer
356       */
357
358     char buf[1024]; 
359     if (!fmt)
360         sprintf(buf, "%f", f);
361     else
362         sprintf(buf, fmt,f);
363     *this = buf;
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
378
379 #if 0
380 String 
381 quoteString( String msg, String quote)
382 {
383      return msg + " `" + quote  + "' ";
384 }
385 #endif // 0
386
387 Byte*
388 strrev( Byte* byte_l, int length_i )
389 {
390   Byte byte;
391   Byte* left_byte_l = byte_l;
392   Byte* right_byte_l = byte_l + length_i;
393
394   while ( right_byte_l > left_byte_l ) {
395     byte = *left_byte_l;
396     *left_byte_l++ = *right_byte_l;
397     *right_byte_l-- = byte;
398   }
399   return byte_l;
400 }
401
402
403 String 
404 String::reversed_str() const
405 {
406     String str = *this;
407     strrev( str.byte_l(), str.length_i() );
408     return str;    
409 }