lilypond-0.0.27
[lilypond.git] / flower / string.cc
blobeb5822cf32685e8bbce079668c472ff68cde7d47
1 /****************************************************************************
2 PROJECT: FlowerSoft C++ library
3 FILE : string.cc
5 Rehacked by HWN 3/nov/95
6 removed String &
7 introduced Class String_handle
8 --*/
10 #include <string.h>
11 #include <stdlib.h>
12 #include <stdio.h>
13 #include <ctype.h>
14 #include <assert.h>
16 #include "string.hh"
19 static char* strlwr( char* s )
21 char* p = s;
23 while( *p )
25 *p = tolower( *p ); /* a macro on some compilers */
26 p++;
28 return s;
31 static char* strupr( char* s )
33 char* p = s;
35 while( *p )
37 *p = toupper( *p ); /* a macro on some compilers */
38 p++;
40 return s;
43 String::String(Rational r)
45 char * n = Itoa(r.numerator()); // LEAK????
47 *this = n;
48 if (r.denominator() != 1) {
49 char * d = Itoa(r.denominator());
50 *this += String( '/' ) + String(d);
51 //delete d;
53 /* delete n;
57 // return array, alloced with new.
58 char *
59 String::copy_array() const
61 const char *src = data;
62 char *dest = new char[data.len() + 1];
63 strcpy(dest, src);
64 return dest;
67 void
68 String::printOn(ostream& os) const
70 os << (const char*) data;
73 String::String (bool b)
75 *this = (const char *) (b ? "true" : "false");
77 String::String( const char* source )
79 assert(source);
80 data = source;
83 void
84 String::operator +=(String s)
86 *this += (const char *) s;
89 int
90 String::len() const
92 return data.len();
95 String::String(char c, int n)
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;
106 String::String(int i)
108 char digits[ 81 ]; // who the FUCK is 80???
109 digits[ 0 ] = '\0';
110 sprintf(digits, "%d", i ); // assume radix 10
111 data = digits;
114 String::String( const int i, const int n, const char c )
116 char fillChar = c;
117 if ( fillChar)
118 fillChar = '0';
120 String v( i );
122 data = String( fillChar, n - v.len() ) + String( v );
123 // String convd to const char *
126 const char*
127 String::cptr() const
129 return data;
134 // signed comparison, analogous to strcmp;
136 String::compare(const String& s1,const String &s2 )
138 const char * p1=s1.cptr();
139 const char * p2 = s2.cptr();
140 if (p1 == p2)
141 return 0;
143 return strcmp(p1,p2);
148 String::lastPos( const char c ) const
150 const char *me = data;
151 int pos = 0;
152 if ( len() )
154 const char* p = strrchr(me, c );
155 if ( p )
156 pos = p - me + 1;
158 return pos;
162 String::lastPos( const char* string ) const
164 int pos = 0;
165 int length = strlen( string );
166 if ( len() && length )
168 int nextpos = this->pos( string );
169 while( nextpos )
171 pos += nextpos;
172 nextpos = right( len() - pos - length + 1 ).pos( string );
175 return pos;
178 // find c
179 // return 0 if not found.
181 // ? should return len()?, as in string.left(pos(delimiter))
183 String::pos(char c ) const
185 const char *me = data;
186 int pos = 0;
187 if ( len() )
189 const char* p = strchr( me, c );
190 if ( p )
191 pos = p - me + 1;
193 return pos;
196 // find searchfor. (what if this == "" && searchfor == "") ???
198 String::pos( const char* searchfor ) const
200 const char *me = data;
201 int pos = 0;
202 if ( len() && searchfor)
204 const char* p = strstr(me, searchfor);
205 if ( p )
206 pos = p - me + 1;
208 return pos;
211 // find chars of a set.
213 String::posAny( const char* string ) const
215 int pos = 0;
216 const char *s = (const char *)data;
217 if ( len() && string )
219 const char* p = strpbrk( s, string );
220 if ( p )
221 pos = p - s + 1;
223 return pos;
226 String
227 String::left( int n ) const
229 if (n >= len())
230 return *this;
232 String retval;
233 if (n < 1)
234 return retval;
236 retval = *this;
237 retval.data.trunc(n);
238 return retval;
242 // n rightmst chars
243 String
244 String::right( int n ) const
246 if (n > len())
247 return *this;
249 String retval;
250 if ( n < 1)
251 return retval;
253 const char *src = (const char *)data + len() - n;
254 retval += src;
256 return retval;
260 String
261 String::nomid( const int pos, const int n ) const
263 String retval;
265 if ( pos < 1 )
266 return String("");
267 if ( pos > len())
268 return *this;
270 return String( String( left( pos - 1 ) ) + right( len() - pos - n + 1 ));
274 String
275 String::mid( int pos, int n ) const
277 String retval;
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;
285 retval = ((const char *) data) + pos -1;
286 if (n > retval.len())
287 n =retval.len();
288 retval.data.trunc(n);
289 return retval;
293 // to uppercase
294 String
295 String::upper()
297 char *s = data.array_for_modify();
298 strupr(s );
299 return *this;
303 // to lowercase
304 String String::lower()
306 char *s = data.array_for_modify();
307 strlwr(s);
308 return *this;
311 String::String (double f, const char *fmt)
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.
316 1024 is a safe length for the buffer
319 char buf[1024];
320 if (!fmt)
321 sprintf(buf, "%f", f);
322 else
323 sprintf(buf, fmt,f);
324 *this = buf;
327 long
328 String::value() const
330 long l =0;
331 if (len()) {
332 int conv = sscanf(data, "%ld", &l);
333 assert(conv);
335 return l;
338 double
339 String::fvalue() const
341 double d =0;
342 if (len()) {
343 int conv = sscanf(data, "%lf", &d);
344 assert(conv);
346 return d;
350 String quoteString( String msg, String quote)
352 return msg + " `" + quote + "' ";
356 char *strrev(char *s)
358 char c;
359 char *p = s;
360 char *q = s + strlen(s) - 1;
362 while (q > p) {
363 c = *p;
364 *p++ = *q;
365 *q-- = c;
367 return s;
371 String
372 String::reversed() const
374 String retval=*this;
375 char *s = retval.data.array_for_modify();
376 strrev(s);
377 return retval;