]> git.donarmstrong.com Git - lilypond.git/blob - flower/string.cc
74ae9a7865b3e8c553422acdb5078f24c0e8f94c
[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 bool 
143 String::empty_b () const
144 {
145   return !length_i ();
146 }
147 /**
148   Do a signed comparison,  analogous to memcmp;
149  */
150 int
151 String::compare_i (String const& s1, String const& s2) 
152 {
153   Byte const* p1 = s1.byte_C();
154   Byte const* p2 = s2.byte_C();
155   if (p1 == p2)
156         return 0;
157
158   int i1 = s1.length_i();
159   int i2 = s2.length_i();
160
161   int result=  memcmp (p1, p2, i1 <? i2);
162   return result ? result : i1-i2;
163 }
164
165 \f
166 int
167 String::index_last_i (char const c) const
168 {
169   if (!length_i()) 
170         return -1;
171
172   char const* me = strh_.ch_C();
173   char const* p = memrchr (me, length_i(), c);
174   if (p)
175         return p - me;
176   return -1;
177 }
178
179 int
180 String::index_last_i (char const* string) const // UGK!
181 {
182   assert (false);               // broken
183   int length = strlen (string); // ugrh
184   if (!length_i() || !length) 
185         return -1;
186   
187   int next_i = index_i (string);
188   if (next_i == -1)
189         return -1;
190   
191   int index_i = 0;
192   while (next_i >= 0) 
193     {
194         index_i += next_i;
195         next_i = right_str (length_i() - index_i - length).index_i (string );
196     }
197   return index_i;
198 }
199
200 /** find  a character.
201
202   @return
203   the index of the leftmost character #c# (0 <= return < length_i()),
204   or   -1 if not found. 
205
206   ? should return length_i()?, as in string.left_str (index_i (delimiter))
207 */
208 int
209 String::index_i (char c) const
210 {
211   char const* me = strh_.ch_C();
212   char const* p = (char const *) memchr (me,c,  length_i());
213   if (p)
214         return p - me;
215   return -1;
216 }
217
218 /**
219   find the substring.
220
221   @return
222 1  index of leftmost occurrence of #searchfor#
223  */
224 int
225 String::index_i (String searchfor) const
226 {
227   char const* me = strh_.ch_C();
228   char const* p = (char const *) memmem (
229         me, length_i(), searchfor.ch_C(), searchfor.length_i ());
230   
231   if (p)
232         return p - me;
233   else
234         return -1;
235 }
236
237 /** find chars of a set.
238
239   @return
240   the index of the leftmost occurance of an element of #set#
241   */
242 int
243 String::index_any_i (String set) const
244 {
245   int n = length_i();
246   if (!n)
247         return -1;
248
249   void const * me_l = (void const *) strh_.ch_C();
250   for (int i=0; i  < set.length_i(); i++) 
251     {
252         char * found=(char*) memchr (me_l, set[i], n );
253         if (found) 
254           {
255             return found - me_l;
256           }
257     }
258   return -1;
259 }
260 \f
261 String
262 String::left_str (int n) const
263 {
264   if (n >= length_i())
265         return *this;
266
267   String retval;        
268   if (n < 1)
269       return retval;
270   
271   retval = *this;
272   retval.strh_.trunc (n);
273   return retval;
274 }
275
276 String
277 String::right_str (int n) const
278 {
279   if (n > length_i())
280         return *this;
281   
282   if (n < 1)
283       return "";
284   
285   return String (strh_.byte_C() + length_i() - n, n); 
286 }
287
288
289 String
290 String::nomid_str (int index_i, int n) const
291 {
292   if (index_i < 0) 
293     {
294         n += index_i;
295         index_i = 0;
296     }
297   if (n <= 0)
298         return *this;
299   
300   return
301         left_str (index_i)   +
302         right_str (length_i() - index_i - n) ;
303 }
304
305 /*
306   proposal: change to "cut()"
307  */
308 String
309 String::mid_str (int index_i, int n) const
310 {
311   if (index_i <0) 
312     {
313         n += index_i;
314         index_i=0;
315     }
316   
317   if (!length_i() || (index_i < 0) || (index_i >= length_i () ) || (n < 1 ) )
318         return String();
319
320   if ((n > length_i()) ||  (index_i + n > length_i () ) )
321         n = length_i() - index_i;
322
323   return String (byte_C() + index_i, n);
324 }
325 \f
326 String
327 String::upper_str() const
328 {
329   String str = *this;
330   str.to_upper();
331   return str;
332 }
333 void
334 String::to_upper()
335 {
336   char *s = (char*)strh_.byte_l();
337   strnupr (s ,length_i());
338 }
339
340 void
341 String::to_lower()
342 {
343   char* s = strh_.ch_l();
344   strnlwr (s,length_i());    
345 }
346
347
348 String 
349 String::lower_str() const
350 {
351   String str = *this;
352   str.to_lower();
353   return str;
354 }
355 String 
356 String::reversed_str() const
357 {
358   String str = *this;
359   strrev (str.byte_l(), str.length_i ());
360   return str;    
361 }
362
363 int
364 String::value_i() const
365 {
366   return String_convert::dec2_i (*this);
367 }
368
369 double
370 String::value_f() const
371 {
372   return String_convert::dec2_f (*this);
373 }
374
375