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