]> git.donarmstrong.com Git - lilypond.git/blobdiff - flower/string.cc
release: 0.1.25
[lilypond.git] / flower / string.cc
index 9c6792c0217cb86d523e4aa68ba82f077ec63b3b..74ae9a7865b3e8c553422acdb5078f24c0e8f94c 100644 (file)
-/****************************************************************************
-  PROJECT: FlowerSoft C++ library
-  FILE   : string.cc
+/*
 
-  Rehacked by HWN 3/nov/95
-  removed String &
-  introduced Class String_handle
---*/
+ string.cc - implement String
+ (c) 1997 Han-Wen Nienhuys & Jan Nieuwenhuizen
+
+ */
 
-#include <string.h>
 #include <stdlib.h>
 #include <stdio.h>
-#include <ctype.h>
+
 #include <assert.h>
+#include <string.h>
 
 #include "string.hh"
+#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
 
-static char* strlwr( char* s )
+// return array, alloced with new.
+Byte*
+String::copy_byte_p() const
 {
-    char* p = s;
-
-    while( *p )
-        {
-        *p = tolower( *p );    /* a macro on some compilers */
-        p++;
-        }
-    return s;
+  Byte const* src = strh_.byte_C();
+  Byte* dest = new Byte[strh_.length_i() + 1];
+  memcpy (dest, src, strh_.length_i() + 1);
+  return dest;    
+}
+void
+String::print_on (ostream& os) const
+{
+  if (!strh_.is_binary_bo())
+      os << ch_C();
+  else
+       for (int i = 0; i < length_i(); i++)
+           os << (Byte)(*this)[ i ];
 }
+\f
+/*
+  copying, constructing.
+ */
+String&
+String::operator = (String const&source)
+{
+  strh_ = source.strh_;
+  return *this;
+}
+
 
-static char* strupr( char* s )
+String::String (Rational r)
 {
-    char* p = s;
+  *this = String_convert::rational_str (r);
+}
 
-    while( *p )
-        {
-        *p = toupper( *p );    /* a macro on some compilers */
-        p++;
-        }
-    return s;
+String::String (double f, char const* fmt)
+{
+  *this= String_convert::double_str (f,fmt);
 }
 
-// return array, alloced with new.
-char *
-String::copy_array() const
+String::String (char c,  int n)
 {
-    const char *src = data;
-    char *dest = new char[data.len() + 1];
-    strcpy(dest, src);
-    return dest;    
+  *this = String_convert::char_str (c,n);
 }
 
-void
-String::printOn(ostream& os) const
+/**
+  @see
+  String_convert::int_str
+ */
+String::String (int i, char const * format)
 {
-    os << (const char*) data;
+  *this = String_convert::int_str (i,format);
 }
 
 String::String (bool b)
 {
-    *this = (const char *) (b ? "true" : "false");
+  *this = (char const*) (b ? "true" : "false");
 }
-String::String( const char* source )
+
+String::String (char const* source)
 {   
-    assert(source);    
-    data = source;    
+  assert (source);    
+  strh_ = source;    
 }
 
+String::String (Byte const* byte_l, int length_i)
+{   
+  strh_.set (byte_l, length_i);    
+}
+\f
+void
+String::append (String s)
+{
+  strh_.append (s.byte_C(), s.length_i());
+}
 void
 String::operator +=(String s)
 {
-    *this += (const char *) s;
+  append (s);
 }
 
-int
-String::len() const
+void
+String::prepend (String s)
 {
-    return data.len();
+  s += *this;
+  *this = s;
 }
 
-String::String(char c,  int n)
+int
+String::length_i() const
 {
-    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;
+  return strh_.length_i();
 }
 
-String::String(int i)
+Byte const*
+String::byte_C() const
 {
-    char digits[ 81 ];             // who the FUCK is 80???
-    digits[ 0 ] = '\0';
-    sprintf(digits, "%d", i );     // assume radix 10
-    data = digits;
+  return strh_.byte_C();
 }
 
-String::String( const int i, const int n, const char c )
+char const*
+String::ch_C() 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_.ch_C();
 }
 
-const char*
-String::cptr() const
+Byte*
+String::byte_l()
 {
-    return data;
+  return strh_.byte_l();
 }
 
+char*
+String::ch_l()
+{
+  return strh_.ch_l();
+}
 
-
-// signed comparison,  analogous to strcmp;
+bool 
+String::empty_b () const
+{
+  return !length_i ();
+}
+/**
+  Do a signed comparison,  analogous to memcmp;
+ */
 int
-String::compare( const char* test ) const
+String::compare_i (String const& s1, String const& s2) 
 {
-    if (test == (const char *) data)
+  Byte const* p1 = s1.byte_C();
+  Byte const* p2 = s2.byte_C();
+  if (p1 == p2)
        return 0;
 
-    return strcmp(data, test);
-}
+  int i1 = s1.length_i();
+  int i2 = s2.length_i();
 
+  int result=  memcmp (p1, p2, i1 <? i2);
+  return result ? result : i1-i2;
+}
 
+\f
 int
-String::lastPos( const char c ) const
+String::index_last_i (char const c) const
 {
-    const char *me = data;
-    int pos = 0;
-    if ( len() )
-        {
-       const char* p = strrchr(me, c );
-        if ( p )
-            pos = p - me + 1;
-        }
-    return pos;
+  if (!length_i()) 
+       return -1;
+
+  char const* me = strh_.ch_C();
+  char const* p = memrchr (me, length_i(), c);
+  if (p)
+       return p - me;
+  return -1;
 }
 
 int
-String::lastPos( const char* string ) const
-{
-    int pos = 0;
-    int length = strlen( string );
-    if ( len() && length )
-        {
-        int nextpos = this->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_i (char const* string) const // UGK!
 {
-    const char *me = data;
-    int pos = 0;
-    if ( len() )
-        {
-       const char* p = strchr( me, c );
-        if ( p )
-            pos = p - me + 1;
-        }
-    return pos;
+  assert (false);              // broken
+  int length = strlen (string); // ugrh
+  if (!length_i() || !length) 
+       return -1;
+  
+  int next_i = index_i (string);
+  if (next_i == -1)
+       return -1;
+  
+  int index_i = 0;
+  while (next_i >= 0) 
+    {
+       index_i += next_i;
+       next_i = right_str (length_i() - index_i - length).index_i (string );
+    }
+  return index_i;
 }
 
-// find searchfor. (what if this == "" && searchfor == "") ???
+/** find  a character.
+
+  @return
+  the index of the leftmost character #c# (0 <= return < length_i()),
+  or   -1 if not found. 
+
+  ? should return length_i()?, as in string.left_str (index_i (delimiter))
+*/
 int
-String::pos( const char* searchfor ) const
+String::index_i (char c) const
 {
-    const char *me = data;
-    int pos = 0;
-    if ( len() && searchfor)
-        {
-       const char* p = strstr(me, searchfor);
-        if ( p )
-           pos = p - me + 1;
-        }
-    return pos;
+  char const* me = strh_.ch_C();
+  char const* p = (char const *) memchr (me,c,  length_i());
+  if (p)
+       return p - me;
+  return -1;
 }
 
-// find chars of a set.
+/**
+  find the substring.
+
+  @return
+1  index of leftmost occurrence of #searchfor#
+ */
 int
-String::posAny( const char* string ) const
+String::index_i (String searchfor) 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_.ch_C();
+  char const* p = (char const *) memmem (
+       me, length_i(), searchfor.ch_C(), searchfor.length_i ());
+  
+  if (p)
+       return p - me;
+  else
+       return -1;
 }
 
+/** find chars of a set.
+
+  @return
+  the index of the leftmost occurance of an element of #set#
+  */
+int
+String::index_any_i (String set) const
+{
+  int n = length_i();
+  if (!n)
+       return -1;
+
+  void const * me_l = (void const *) strh_.ch_C();
+  for (int i=0; i  < set.length_i(); i++) 
+    {
+       char * found=(char*) memchr (me_l, set[i], n );
+       if (found) 
+         {
+           return found - me_l;
+         }
+    }
+  return -1;
+}
+\f
 String
-String::left( int n ) const
+String::left_str (int n) const
 {
-    if (n >= len())
+  if (n >= length_i())
        return *this;
 
-    String retval;     
-    if (n < 1)
-        return retval;
-    
-    retval = *this;
-    retval.data.trunc(n);
-    return retval;
+  String retval;       
+  if (n < 1)
+      return retval;
+  
+  retval = *this;
+  retval.strh_.trunc (n);
+  return retval;
 }
 
-
-// n rightmst chars
 String
-String::right( int n ) const
+String::right_str (int n) const
 {
-    if (n > len())
+  if (n > length_i())
        return *this;
-    
-    String retval;
-    if ( n < 1)
-        return retval;
-    
-    const char *src = (const char *)data + len() - n; 
-    retval += src;
-
-    return retval;
+  
+  if (n < 1)
+      return "";
+  
+  return String (strh_.byte_C() + length_i() - n, n); 
 }
 
 
 String
-String::nomid( const int pos, const int n ) const
+String::nomid_str (int index_i, int n) const
 {
-    String retval;
-        
-    if ( pos < 1 )
-        return String("");
-    if ( pos > len())
+  if (index_i < 0) 
+    {
+       n += index_i;
+       index_i = 0;
+    }
+  if (n <= 0)
        return *this;
-    
-    return String( String( left( pos - 1 ) ) + right( len() - pos - n + 1 ));
+  
+  return
+       left_str (index_i)   +
+       right_str (length_i() - index_i - n) ;
 }
 
-
+/*
+  proposal: change to "cut()"
+ */
 String
-String::mid( int pos, int n ) const
+String::mid_str (int index_i, int n) const
 {
-    String retval;
+  if (index_i <0) 
+    {
+       n += index_i;
+       index_i=0;
+    }
+  
+  if (!length_i() || (index_i < 0) || (index_i >= length_i () ) || (n < 1 ) )
+       return String();
 
-    // 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_i()) ||  (index_i + n > length_i () ) )
+       n = length_i() - index_i;
 
-    retval = ((const char *) data) + pos -1;
-    if (n > retval.len())
-       n =retval.len();
-    retval.data.trunc(n);
-    return retval;
+  return String (byte_C() + index_i, n);
 }
-
-
-// to  uppercase
+\f
 String
-String::upper()
+String::upper_str() const
 {
-    char *s = data.array_for_modify();
-    strupr(s );
-    return *this;
+  String str = *this;
+  str.to_upper();
+  return str;
 }
-
-
-// to lowercase
-String String::lower()
+void
+String::to_upper()
 {
-    char  *s = data.array_for_modify();
-    strlwr(s);
-    return *this;
+  char *s = (char*)strh_.byte_l();
+  strnupr (s ,length_i());
 }
 
-String::String (double f, const char *fmt)
+void
+String::to_lower()
 {
-    /* worst case would be printing HUGE (or 1/HUGE), which is approx
-      2e318, this number would have approx 318 zero's in its string.
-
-      1024 is a safe length for the buffer
-      */
-
-    char buf[1024]; 
-    if (!fmt)
-       sprintf(buf, "%f", f);
-    else
-       sprintf(buf, fmt,f);
-    *this = buf;
+  char* s = strh_.ch_l();
+  strnlwr (s,length_i());    
 }
 
-long
-String::value() const
+
+String 
+String::lower_str() const
 {
-    long l =0;
-    if (len()) {
-       int conv = sscanf(data, "%ld", &l);
-       assert(conv);
-    }
-    return l;
+  String str = *this;
+  str.to_lower();
+  return str;
 }
-
-double
-String::fvalue() const
+String 
+String::reversed_str() const
 {
-    double d =0;
-    if (len()) {
-       int conv = sscanf(data, "%lf", &d);
-       assert(conv);
-    }
-    return d;
+  String str = *this;
+  strrev (str.byte_l(), str.length_i ());
+  return str;    
 }
 
-
-String quoteString( String msg, String quote)
+int
+String::value_i() const
 {
-    return msg + " `" + quote  + "' ";
+  return String_convert::dec2_i (*this);
 }
 
-
-char *strrev(char *s)
+double
+String::value_f() const
 {
-  char c;
-  char *p = s;
-  char *q = s + strlen(s) - 1;
-
-  while (q > p) {
-    c = *p;
-    *p++ = *q;
-    *q-- = c;
-  }
-  return s;
+  return String_convert::dec2_f (*this);
 }
 
 
-String 
-String::reversed() const
-{
-    String retval=*this;
-    char  *s = retval.data.array_for_modify();
-    strrev(s);
-    return retval;    
-}