X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=flower%2Fstring.cc;h=5279b6a2d5e7ff6f9f83390aee7b463e926cd33a;hb=32f10f1e5741ddadbae0ed5d4bd3008a22fb6fb9;hp=0804c5bbdc7d30e6ed50235fea460ac46548772a;hpb=b9de385139e4607b126f150d76db7905c75a6d89;p=lilypond.git diff --git a/flower/string.cc b/flower/string.cc index 0804c5bbdc..5279b6a2d5 100644 --- a/flower/string.cc +++ b/flower/string.cc @@ -1,378 +1,390 @@ -/**************************************************************************** - PROJECT: FlowerSoft C++ library - FILE : string.cc +/* + string.cc - implement String - Rehacked by HWN 3/nov/95 - removed String & - introduced Class String_handle ---*/ + (c) 1997--2005 Han-Wen Nienhuys & Jan Nieuwenhuizen +*/ -#include -#include -#include -#include -#include +#ifndef _GNU_SOURCE // we want memmem +#define _GNU_SOURCE +#endif #include "string.hh" +#include +#include +#include +#include -static char* strlwr( char* s ) +#include + +#include "libc-extension.hh" +#include "string-convert.hh" + +#ifdef STRING_DEBUG +void *mymemmove (void *dest, void const *src, size_t n); +#define memmove mymemmove +#endif + +// return array, alloced with new. +Byte * +String::get_copy_byte () const { - char* p = s; + Byte const *src = strh_.to_bytes (); + Byte *dest = new Byte[strh_.length () + 1]; + memcpy (dest, src, strh_.length () + 1); + return dest; +} - while( *p ) - { - *p = tolower( *p ); /* a macro on some compilers */ - p++; - } - return s; +char * +String::get_copy_str0 () const +{ + return (char *)get_copy_byte (); } -static char* strupr( char* s ) + +/* + copying, constructing. +*/ +String & +String::operator = (String const &source) { - char* p = s; + strh_ = source.strh_; + return *this; +} - while( *p ) - { - *p = toupper( *p ); /* a macro on some compilers */ - p++; - } - return s; +String::String (Byte const *byte, int len_i) +{ + strh_.set (byte, len_i); } -String::String(Rational r) +/** + @see + String_convert:: +*/ +String +to_string (char c, int n) { - char * n = Itoa(r.numerator()); // LEAK???? - - *this = n; - if (r.denominator() != 1) { - char * d = Itoa(r.denominator()); - *this += '/' + String(d); - //delete d; - } -/* delete n; - */ + return String_convert::char_string (c, n); } -// return array, alloced with new. -char * -String::copy_array() const +String +to_string (double f, char const *format) { - const char *src = data; - char *dest = new char[data.len() + 1]; - strcpy(dest, src); - return dest; + return String_convert::double_string (f, format); } -void -String::printOn(ostream& os) const +String +to_string (int i, char const *format) { - os << (const char*) data; + return String_convert::int_string (i, format); } -String::String (bool b) +String +to_string (bool b) { - *this = (const char *) (b ? "true" : "false"); + return String_convert::bool_string (b); } -String::String( const char* source ) -{ - assert(source); - data = source; +String +to_string (long b) +{ + return String_convert::long_string (b); } -void -String::operator +=(String s) +String +to_string (char const *format, ...) { - *this += (const char *) s; + va_list args; + va_start (args, format); + String str = String_convert::vform_string (format, args); + va_end (args); + return str; } -int -String::len() const + +void +String::append (String s) { - return data.len(); + strh_.append (s.to_bytes (), s.length ()); } - -String::String(char c, int n) +void +String::operator += (String s) { - int l = n; - assert(n >= 0 && n <= 80); // what the fuck is 80? -//min(max( n, 0 ), 80); - char s[81]; - memset(s, c, l); - s[l] = 0; - data = s; + append (s); } -String::String(int i) +void +String::prepend (String s) { - char digits[ 81 ]; // who the FUCK is 80??? - digits[ 0 ] = '\0'; - sprintf(digits, "%d", i ); // assume radix 10 - data = digits; + s += *this; + *this = s; } -String::String( const int i, const int n, const char c ) +int +String::length () const { - char fillChar = c; - if ( fillChar) - fillChar = '0'; - - String v( i ); - - data = String( fillChar, n - v.len() ) + String( v ); - // String convd to const char * + return strh_.length (); } -const char* -String::cptr() const +Byte const * +String::to_bytes () const { - return data; + return strh_.to_bytes (); } - - -// signed comparison, analogous to strcmp; -int -String::compare(const String& s1,const String &s2 ) +char const * +String::to_str0 () const { - const char * p1=s1.cptr(); - const char * p2 = s2.cptr(); - if (p1 == p2) - return 0; + return strh_.to_str0 (); +} - return strcmp(p1,p2); +Byte * +String::get_bytes () +{ + return strh_.get_bytes (); } +char * +String::get_str0 () +{ + return strh_.get_str0 (); +} +bool +String::is_empty () const +{ + return !length (); +} +/** + Do a signed comparison, analogous to memcmp; +*/ int -String::lastPos( const char c ) const +String::compare (String const &s1, String const &s2) { - const char *me = data; - int pos = 0; - if ( len() ) - { - const char* p = strrchr(me, c ); - if ( p ) - pos = p - me + 1; - } - return pos; + Byte const *p1 = s1.to_bytes (); + Byte const *p2 = s2.to_bytes (); + if (p1 == p2) + return 0; + + /* + don't forget the terminating '\0' + */ + int f = (s1.length () pos( string ); - while( nextpos ) - { - pos += nextpos; - nextpos = right( len() - pos - length + 1 ).pos( string ); - } - } - return pos; -} - -// find c -// return 0 if not found. - -// ? should return len()?, as in string.left(pos(delimiter)) -int -String::pos(char c ) const +String::index_last (char const c) const { - const char *me = data; - int pos = 0; - if ( len() ) - { - const char* p = strchr( me, c ); - if ( p ) - pos = p - me + 1; - } - return pos; + if (!length ()) + return -1; + + char const *me = strh_.to_str0 (); + char const *p = (char const *)memrchr ((Byte *)me, length (), c); + if (p) + return p - me; + return -1; } -// find searchfor. (what if this == "" && searchfor == "") ??? int -String::pos( const char* searchfor ) const +String::index_last (char const *string) const // UGK! { - const char *me = data; - int pos = 0; - if ( len() && searchfor) - { - const char* p = strstr(me, searchfor); - if ( p ) - pos = p - me + 1; - } - return pos; + assert (false); // broken + int len = strlen (string); // ugrh + if (!length () || !len) + return -1; + + int next_i = index (string); + if (next_i == -1) + return -1; + + int index_i = 0; + while (next_i >= 0) + { + index_i += next_i; + next_i = right_string (length () - index_i - len).index (string); + } + return index_i; } -// find chars of a set. +/** find a character. + +@return +the index of the leftmost character #c# (0 <= return < length ()), +or -1 if not found. + +? should return length ()?, as in string.left_string (index (delimiter)) +*/ int -String::posAny( const char* string ) const +String::index (char c) const { - int pos = 0; - const char *s = (const char *)data; - if ( len() && string ) - { - const char* p = strpbrk( s, string ); - if ( p ) - pos = p - s + 1; - } - return pos; + char const *me = strh_.to_str0 (); + char const *p = (char const *) memchr (me, c, length ()); + if (p) + return p - me; + return -1; } -String -String::left( int n ) const -{ - if (n >= len()) - return *this; +/** + find a substring. - String retval; - if (n < 1) - return retval; - - retval = *this; - retval.data.trunc(n); - return retval; -} + @return + index of leftmost occurrence of #searchfor# +*/ +int +String::index (String searchfor) const +{ + char const *me = strh_.to_str0 (); + char const *p = (char const *) + memmem (me, length (), searchfor.to_str0 (), searchfor.length ()); -// n rightmst chars -String -String::right( int n ) const -{ - if (n > len()) - return *this; - - String retval; - if ( n < 1) - return retval; - - const char *src = (const char *)data + len() - n; - retval += src; + if (p) + return p - me; - return retval; + return -1; } +/** find chars of a set. -String -String::nomid( const int pos, const int n ) const +@return + +the index of the leftmost occurance of an element of #set#. -1 if +nothing is found. +*/ +int +String::index_any (String set) const { - String retval; - - if ( pos < 1 ) - return String(""); - if ( pos > len()) - return *this; - - return String( String( left( pos - 1 ) ) + right( len() - pos - n + 1 )); + int n = length (); + if (!n) + return -1; + + void const *me = (void const *) strh_.to_str0 (); + for (int i = 0; i < set.length (); i++) + { + char *found = (char *) memchr (me, set[i], n); + if (found) + { + return found - (char const *)me; + } + } + return -1; } - - + String -String::mid( int pos, int n ) const +String::left_string (int n) const { - String retval; - - // HWN. This SUX: - // pos 1 == data->string[ 0 ]; - // pos 0 allowed for convenience - if ( !len() || ( pos < 0 ) || ( pos > len() ) && ( n < 1 ) ) - return retval; + if (n >= length ()) + return *this; - retval = ((const char *) data) + pos -1; - if (n > retval.len()) - n =retval.len(); - retval.data.trunc(n); + String retval; + if (n < 1) return retval; -} + retval = *this; + retval.strh_.trunc (n); + return retval; +} -// to uppercase String -String::upper() +String::right_string (int n) const { - char *s = data.array_for_modify(); - strupr(s ); + if (n > length ()) return *this; -} + if (n < 1) + return ""; + + return String (strh_.to_bytes () + length () - n, n); +} -// to lowercase -String String::lower() +String +String::nomid_string (int index_i, int n) const { - char *s = data.array_for_modify(); - strlwr(s); + if (index_i < 0) + { + n += index_i; + index_i = 0; + } + if (n <= 0) return *this; + + return left_string (index_i) + right_string (length () - index_i - n); } -String::String (double f, const char *fmt) +String +String::cut_string (int index_i, int n) const { - /* worst case would be printing HUGE (or 1/HUGE), which is approx - 2e318, this number would have approx 318 zero's in its string. + if (index_i < 0) + { + n += index_i; + index_i = 0; + } - 1024 is a safe length for the buffer - */ + if (!length () || (index_i < 0) || (index_i >= length ()) || (n < 1)) + return String (); - char buf[1024]; - if (!fmt) - sprintf(buf, "%f", f); - else - sprintf(buf, fmt,f); - *this = buf; + if ((n > length ()) || (index_i + n > length ())) + n = length () - index_i; + + return String (to_bytes () + index_i, n); } + -long -String::value() const +void +String::to_upper () { - long l =0; - if (len()) { - int conv = sscanf(data, "%ld", &l); - assert(conv); - } - return l; + strnupr (get_str0 (), length ()); } -double -String::fvalue() const +void +String::to_lower () { - double d =0; - if (len()) { - int conv = sscanf(data, "%lf", &d); - assert(conv); - } - return d; + strnlwr (get_str0 (), length ()); } - -String quoteString( String msg, String quote) +void +String::reverse () { - return msg + " `" + quote + "' "; + strrev (get_bytes (), length ()); } +int +String::to_int () const +{ + return String_convert::dec2int (*this); +} -char *strrev(char *s) +double +String::to_double () const { - char c; - char *p = s; - char *q = s + strlen(s) - 1; + return String_convert::dec2double (*this); +} - while (q > p) { - c = *p; - *p++ = *q; - *q-- = c; - } - return s; +#ifdef STREAM_SUPPORT +ostream & +operator << (ostream &os, String d) +{ + d.print_on (os); + return os; } +void +String::print_on (ostream &os) const +{ + if (!strh_.is_binary_bo ()) + os << to_str0 (); + else + for (int i = 0; i < length (); i++) + os << (Byte) (*this)[ i ]; +} +#endif -String -String::reversed() const +void +String::substitute_char (char chr, String sub) { - String retval=*this; - char *s = retval.data.array_for_modify(); - strrev(s); - return retval; + for (int i = index (chr); i > -1; i = index (chr)) + *this = left_string (i) + sub + right_string (length () - i - 1); }