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