]> git.donarmstrong.com Git - lilypond.git/blob - flower/string.cc
release: 0.1.8
[lilypond.git] / flower / string.cc
1 /*
2
3  string.cc - implement String
4  
5  (c) 1997 Han-Wen Nienhuys & Jan Nieuwenhuizen
6
7  */
8
9 #include <stdlib.h>
10 #include <stdio.h>
11
12 #include <assert.h>
13 #include <string.h>
14
15 #include "string.hh"
16 #include "libc-extension.hh"
17 #include "string-convert.hh"
18
19 #ifdef STRING_DEBUG
20 void* mymemmove (void* dest, void const* src, size_t n);
21 #define memmove mymemmove
22 #endif
23
24 // return array, alloced with new.
25 Byte*
26 String::copy_byte_p() const
27 {
28     Byte const* src = strh_.byte_C();
29     Byte* dest = new Byte[strh_.length_i() + 1];
30     memcpy (dest, src, strh_.length_i() + 1);
31     return dest;    
32 }
33 void
34 String::print_on (ostream& os) const
35 {
36     if (!strh_.is_binary_bo())
37         os << ch_C();
38     else
39         for ( int i = 0; i < length_i(); i++)
40             os << (Byte)(*this)[ i ];
41 }
42 \f
43 /*
44   copying, constructing.
45  */
46 String&
47 String::operator = (String const&source)
48 {
49     strh_ = source.strh_;
50     return *this;
51 }
52
53
54 String::String (Rational r)
55 {
56     *this = String_convert::rational_str (r);
57 }
58
59 String::String (double f, char const* fmt)
60 {
61     *this= String_convert::double_str (f,fmt);
62 }
63
64 String::String (char c,  int n)
65 {
66     *this = String_convert::char_str (c,n);
67 }
68
69 /**
70   @see
71   String_convert::int_str
72  */
73 String::String (int i, char const * format)
74 {
75     *this = String_convert::int_str (i,format);
76 }
77
78 String::String (bool b)
79 {
80     *this = (char const*) (b ? "true" : "false");
81 }
82
83 String::String (char const* source)
84 {   
85     assert (source);    
86     strh_ = source;    
87 }
88
89 String::String (Byte const* byte_l, int length_i)
90 {   
91     strh_.set (byte_l, length_i);    
92 }
93 \f
94 void
95 String::append (String s)
96 {
97     strh_.append (s.byte_C(), s.length_i());
98 }
99 void
100 String::operator +=(String s)
101 {
102     append (s);
103 }
104
105 void
106 String::prepend (String s)
107 {
108     s += *this;
109     *this = s;
110 }
111
112 int
113 String::length_i() const
114 {
115     return strh_.length_i();
116 }
117
118 Byte const*
119 String::byte_C() const
120 {
121     return strh_.byte_C();
122 }
123
124 char const*
125 String::ch_C() const
126 {
127     return strh_.ch_C();
128 }
129
130 Byte*
131 String::byte_l()
132 {
133     return strh_.byte_l();
134 }
135
136 char*
137 String::ch_l()
138 {
139     return strh_.ch_l();
140 }
141
142 /**
143   Do a signed comparison,  analogous to memcmp;
144  */
145 int
146 String::compare_i (String const& s1, String const& s2) 
147 {
148     Byte const* p1 = s1.byte_C();
149     Byte const* p2 = s2.byte_C();
150     if ( p1 == p2)
151         return 0;
152
153     int i1 = s1.length_i();
154     int i2 = s2.length_i();
155
156     int result=  memcmp (p1, p2, i1 <? i2);
157     return result ? result : i1-i2;
158 }
159
160 \f
161 int
162 String::index_last_i (char const c) const
163 {
164     if ( !length_i()) 
165         return -1;
166
167     char const* me = strh_.ch_C();
168     char const* p = memrchr (me, length_i(), c);
169     if ( p)
170         return p - me;
171     return -1;
172 }
173
174 int
175 String::index_last_i (char const* string) const // UGK!
176 {
177     assert (false);             // broken
178     int length = strlen (string); // ugrh
179     if ( !length_i() || !length) 
180         return -1;
181     
182     int next_i = index_i (string);
183     if ( next_i == -1)
184         return -1;
185     
186     int index_i = 0;
187     while (next_i >= 0) {
188         index_i += next_i;
189         next_i = right_str (length_i() - index_i - length).index_i (string );
190     }
191     return index_i;
192 }
193
194 /** find  a character.
195
196   @return
197   the index of the leftmost character #c# (0 <= return < length_i()),
198   or   -1 if not found. 
199
200   ? should return length_i()?, as in string.left_str (index_i (delimiter))
201 */
202 int
203 String::index_i (char c) const
204 {
205     char const* me = strh_.ch_C();
206     char const* p = (char const *) memchr (me,c,  length_i());
207     if ( p)
208         return p - me;
209     return -1;
210 }
211
212 /**
213   find the substring.
214
215   @return
216   index of leftmost occurrence of #searchfor#
217  */
218 int
219 String::index_i (String searchfor) const
220 {
221     char const* me = strh_.ch_C();
222     char const* p = (char const *) memmem (
223         me, length_i(), searchfor.ch_C(), searchfor.length_i ());
224     
225     if ( p)
226         return p - me;
227     else
228         return -1;
229 }
230
231 /** find chars of a set.
232
233   @return
234   the index of the leftmost occurance of an element of #set#
235   */
236 int
237 String::index_any_i (String set) const
238 {
239     int n = length_i();
240     if ( !n)
241         return -1;
242
243     void const * me_l = (void const *) strh_.ch_C();
244     for (int i=0; i  < set.length_i(); i++) {
245         char * found=(char*) memchr (me_l, set[i], n );
246         if (found) {
247             return found - me_l;
248         }
249     }
250     return -1;
251 }
252 \f
253 String
254 String::left_str (int n) const
255 {
256     if (n >= length_i())
257         return *this;
258
259     String retval;      
260     if (n < 1)
261         return retval;
262     
263     retval = *this;
264     retval.strh_.trunc (n);
265     return retval;
266 }
267
268 String
269 String::right_str (int n) const
270 {
271     if (n > length_i())
272         return *this;
273     
274     if ( n < 1)
275         return "";
276     
277     return String (strh_.byte_C() + length_i() - n, n); 
278 }
279
280
281 String
282 String::nomid_str (int index_i, int n) const
283 {
284     if ( index_i < 0) {
285         n += index_i;
286         index_i = 0;
287     }
288     if ( n <= 0)
289         return *this;
290     
291     return
292         left_str (index_i)   +
293         right_str (length_i() - index_i - n) ;
294 }
295
296 /*
297   proposal: change to "cut()"
298  */
299 String
300 String::mid_str (int index_i, int n) const
301 {
302     if (index_i <0) {
303         n += index_i;
304         index_i=0;
305     }
306     
307     if ( !length_i() || ( index_i < 0) || ( index_i >= length_i () ) || ( n < 1 ) )
308         return String();
309
310     if ( ( n > length_i()) ||  ( index_i + n > length_i () ) )
311         n = length_i() - index_i;
312
313     return String (byte_C() + index_i, n);
314 }
315 \f
316 String
317 String::upper_str() const
318 {
319     String str = *this;
320     str.to_upper();
321     return str;
322 }
323 void
324 String::to_upper()
325 {
326     char *s = (char*)strh_.byte_l();
327     strnupr (s ,length_i());
328 }
329
330 void
331 String::to_lower()
332 {
333     char* s = strh_.ch_l();
334     strnlwr (s,length_i());    
335 }
336
337
338 String 
339 String::lower_str() const
340 {
341     String str = *this;
342     str.to_lower();
343     return str;
344 }
345 String 
346 String::reversed_str() const
347 {
348     String str = *this;
349     strrev (str.byte_l(), str.length_i ());
350     return str;    
351 }
352
353 int
354 String::value_i() const
355 {
356     return String_convert::dec2_i (*this);
357 }
358
359 double
360 String::value_f() const
361 {
362     return String_convert::dec2_f (*this);
363 }
364
365