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