]> git.donarmstrong.com Git - lilypond.git/blob - flower/string.cc
release: 0.0.34
[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* 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         {
30         *p = tolower( *p );    /* a macro on some compilers */
31         p++;
32         }
33     return s;
34 }
35
36 static char* 
37 strupr( char* s )
38 {
39     char* p = s;
40
41     while( *p )
42         {
43         *p = toupper( *p );    /* a macro on some compilers */
44         p++;
45         }
46     return s;
47 }
48
49 String::String(Rational r)
50 {
51     char * n = Itoa(r.numerator()); // LEAK????
52     
53     *this = n;
54     if (r.denominator() != 1) {
55         char * d = Itoa(r.denominator());
56         *this +=  String( '/' ) + String(d);
57         //delete d;
58     }
59 /*    delete n;
60     */
61 }
62
63 // return array, alloced with new.
64 Byte*
65 String::copy_byte_p() const
66 {
67     Byte const* src = strh_.byte_c_l();
68     Byte* dest = new Byte[strh_.length_i() + 1];
69     memmove( dest, src, strh_.length_i() + 1 );
70     return dest;    
71 }
72
73 void
74 String::printOn(ostream& os) const
75 {
76     if ( length_i() == strlen( ch_c_l() ) )
77         os << ch_c_l();
78     else
79         for ( int i = 0; i < length_i(); i++ )
80             os << (Byte)(*this)[ i ];
81 }
82
83 String::String (bool b)
84 {
85     *this = (char const* ) (b ? "true" : "false");
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     assert( !length_i || byte_l );
96     strh_.set( byte_l, length_i );    
97 }
98
99 void
100 String::operator +=(String s)
101 {
102     strh_.append( s.byte_c_l(), s.length_i() );
103 }
104
105 int
106 String::length_i() const
107 {
108     return strh_.length_i();
109 }
110
111 // will go away, fixed anyway
112 String::String( char c,  int n )
113 {
114     n = n >= 0 ? n : 0;
115     char* ch_p = new char[ n ];
116     memset( ch_p, c, n );
117     strh_.set( (Byte*)ch_p, n );
118     delete ch_p;
119 }
120
121 String::String(int i)
122 {
123     char digits[ 81 ];             // who the fuck is 80???
124     digits[ 0 ] = '\0';
125     sprintf(digits, "%d", i );     // assume radix 10
126     strh_ = digits;
127 }
128
129 String::String( const int i, const int n, char const c )
130 {
131     char fillChar = c;
132     if ( fillChar)
133         fillChar = '0';
134
135     String v( i );
136     
137     String str = String( fillChar, n - v.length_i() ) + String( v );
138     strh_.set( str.byte_c_l(), str.length_i() );
139 }
140
141 Byte const*
142 String::byte_c_l() const
143 {
144     return strh_.byte_c_l();
145 }
146
147 char const*
148 String::ch_c_l() const
149 {
150     return strh_.ch_c_l();
151 }
152
153 Byte*
154 String::byte_l()
155 {
156     return strh_.byte_l();
157 }
158
159 char*
160 String::ch_l()
161 {
162     return strh_.ch_l();
163 }
164
165 // signed comparison,  analogous to memcmp;
166 int
167 String::compare(String const& s1, String const& s2 ) 
168 {
169     Byte const* p1 = s1.byte_c_l();
170     Byte const* p2 = s2.byte_c_l();
171     if ( p1 == p2 )
172         return 0;
173
174     int i1 = s1.length_i();
175     int i2 = s2.length_i();
176     int i = i1 <? i2;
177
178     int result=  memcmp( p1, p2, i );
179     return result ? result : i1-i2;
180 }
181
182
183 int
184 String::lastPos( char const c ) const
185 {
186     // not binary safe
187     assert( length_i() == strlen( ch_c_l() ) );
188     char const* me = strh_.ch_c_l();
189     int pos = 0;
190     if ( length_i() )
191         {
192         char const* p = strrchr(me, c );
193         if ( p )
194             pos = p - me + 1;
195         }
196     return pos;
197 }
198
199 int
200 String::lastPos( char const* string ) const
201 {
202     // not binary safe
203     assert( length_i() == strlen( ch_c_l() ) );
204     int pos = 0;
205     int length = strlen( string );
206     if ( length_i() && length )
207         {
208         int nextpos = this->pos( string );
209         while( nextpos )
210             {
211             pos += nextpos;
212             nextpos = right( length_i() - pos - length + 1 ).pos( string );
213             }
214         }
215     return pos;
216 }
217
218 // find c
219 // return 0 if not found. 
220
221 // ? should return length_i()?, as in string.left(pos(delimiter))
222 int
223 String::pos(char c ) const
224 {
225     // not binary safe
226     assert( length_i() == strlen( ch_c_l() ) );
227     char const* me = strh_.ch_c_l();
228     int pos = 0;
229     if ( length_i() )
230         {
231         char const* p = strchr( me, c );
232         if ( p )
233             pos = p - me + 1;
234         }
235     return pos;
236 }
237
238 // find searchfor. (what if this == "" && searchfor == "") ???
239 int
240 String::pos( char const* searchfor ) const
241 {
242     // not binary safe
243     assert( length_i() == strlen( ch_c_l() ) );
244     char const* me = strh_.ch_c_l();
245     int pos = 0;
246     if ( length_i() && searchfor)
247         {
248         char const* p = strstr(me, searchfor);
249         if ( p )
250             pos = p - me + 1;
251         }
252     return pos;
253 }
254
255 // find chars of a set.
256 int
257 String::posAny( char const* string ) const
258 {
259     // not binary safe
260     assert( length_i() == strlen( ch_c_l() ) );
261     int pos = 0;
262     char const* s = (char const* )strh_.ch_c_l();
263     if ( length_i() && string )
264         {
265         char const* p = strpbrk( s, string );
266         if ( p )
267             pos = p - s + 1;
268         }
269     return pos;
270 }
271
272 String
273 String::left( int n ) const
274 {
275     if (n >= length_i())
276         return *this;
277
278     String retval;      
279     if (n < 1)
280         return retval;
281     
282     retval = *this;
283     retval.strh_.trunc(n);
284     return retval;
285 }
286
287
288 // n rightmst chars
289 String
290 String::right( int n ) const
291 {
292     if (n > length_i())
293         return *this;
294     
295     if ( n < 1)
296         String(); 
297     
298     return String( strh_.byte_c_l() + length_i() - n, n ); 
299 }
300
301
302 String
303 String::nomid( const int pos, const int n ) const
304 {
305     String retval;
306         
307     if ( pos < 1 )
308         return String("");
309     if ( pos > length_i())
310         return *this;
311     
312     return String( String( left( pos - 1 ) ) + right( length_i() - pos - n + 1 ));
313 }
314
315
316 String
317 String::mid( int pos, int n ) const
318 {
319     // HWN. This SUX: JCN: yep, please change me + all my invocations
320     // pos 1 == strh_->string[ 0 ];
321     // pos 0 allowed for convenience
322     if ( !length_i() || ( pos < 0 ) || ( pos > length_i() ) && ( n < 1 ) )
323         return String();
324
325     // overflow...
326     if ( ( n > length_i() ) ||  ( pos + n - 1 > length_i() ) )
327         n = length_i() - pos + 1;
328
329     return String( byte_c_l() + pos -1, n );
330 }
331
332
333 // to  uppercase
334 String
335 String::upper()
336 {
337     // not binary safe
338     assert( length_i() == strlen( ch_c_l() ) );
339     char *s = strh_.byte_l();
340     strupr( s );
341     return *this;
342 }
343
344
345 // to lowercase
346 String 
347 String::lower()
348 {
349     // not binary safe
350     assert( length_i() == strlen( ch_c_l() ) );
351     char* s = strh_.byte_l();
352     strlwr(s);
353     return *this;
354 }
355
356 String::String (double f, char const* fmt)
357 {
358     /* worst case would be printing HUGE (or 1/HUGE), which is approx
359        2e318, this number would have approx 318 zero's in its string.
360
361       1024 is a safe length for the buffer
362       */
363
364     char buf[1024]; 
365     if (!fmt)
366         sprintf(buf, "%f", f);
367     else
368         sprintf(buf, fmt,f);
369     *this = buf;
370 }
371
372 long
373 String::value() const
374 {
375     long l =0;
376     if (length_i()) {
377         int conv = sscanf(strh_.ch_c_l(), "%ld", &l);
378         assert(conv);
379     }
380     return l;
381 }
382
383 double
384 String::fvalue() const
385 {
386     double d =0;
387     if (length_i()) {
388         int conv = sscanf(strh_.ch_c_l(), "%lf", &d);
389         assert(conv);
390     }
391     return d;
392 }
393
394
395 String quoteString( String msg, String quote)
396 {
397     return msg + " `" + quote  + "' ";
398 }
399
400
401 Byte*
402 strrev( Byte* byte_l, int length_i )
403 {
404   Byte by;
405   Byte* left_byte_l = byte_l;
406   Byte* right_byte_l = byte_l + length_i;
407
408   while ( right_byte_l > left_byte_l ) {
409     by = *left_byte_l;
410     *left_byte_l++ = *right_byte_l;
411     *right_byte_l-- = by;
412   }
413   return byte_l;
414 }
415
416
417 String 
418 String::reversed() const
419 {
420     String str = *this;
421     strrev( str.byte_l(), str.length_i() );
422     return str;    
423 }