/****************************************************************************
*
*  var.cpp
*
*  Create:  Dec 12 2004
*  Update:  Sep 23 2005
*  © Jan-Erik Lärka 2004 - 2005
*
****************************************************************************/
//#pragma inline_depth 0;
#include "var.hpp"
#include <iostream>
#include <ctype.h>

int var :: len() const {
   int slength = 0;
   if ( string[ 0 ] != NULL ) // If not empty string
     while ( string[ slength ] != '\0' && slength <= alloc_size ) slength++; // increment count while no end found
   return slength; // Return number of characters
}

int var :: len( const char* s1 ) const {
   int slength = 0;
   if ( s1[ 0 ] != NULL ) // If not empty string
     while ( s1[ slength ] != '\0' ) slength++; // increment count while no end found
   return slength; // Return number of characters
}

var& var :: flush() {
   delete [] string; // Delete string
   alloc_size = static_size?alloc_size:0; // Reset size allocated
   string = new char[ alloc_size + 1 ]; // Create a new string specified by size
   for( int i = 0; i <= alloc_size; i++ ) string[ i ] = '\0'; // Ensure that it's filled with '\0'
   return ( *this ); // Return reference to this object
}

var& var :: clean() {
   for( int i = 0; i <= alloc_size && string[ i ] != '\0'; i++ ) string[ i ] = '\0'; // Overwrite with '\0'
   return ( *this ); // Return reference to this object
}

var& var :: reSize( int stat_size, bool stat, bool truncate ) {
   int i = 0, slength = len();
   static_size = stat;
   alloc_size = ( stat_size > -1 )?truncate?min( stat_size, slength ):min( stat_size, slength ):slength;
   // Determine size to allocate
   char* temp = new char[ slength + 1 ]; // Create a temporary string
   for( i = 0; i <= slength; i++ ) temp[ i ] = string[ i ]; // Copy parts of string to temp storage
   delete [] string; // Delete string
   string = new char[ alloc_size + 1 ]; // Create a new string specified by size
   for( i = 0; i < min( alloc_size, slength ); i++ ) string[ i ] = temp[ i ]; // Copy desired string back
   delete [] temp; // Delete temp storage
   for( ; i <= alloc_size; i++ ) string[ i ] = '\0'; // Fill remaining part of string with '\0'
   return ( *this ); // Return reference to this object
}

int cmp( var &v, const var &v2, bool exact ){
   return v.cmp( v2.string, exact ); // Reuse method (member function)
}

int cmp( char* s1, const char* s2, bool exact ) {
   var temp( s1 ); // Create a temporary copy
   return temp.cmp( s2, exact ); // Reuse method (member function)
}

int var :: cmp( const char* s2, bool exact ) const {
   long s1_long = atof( string ), s2_long = atof( s2 ); // Convert strings to long
   if ( ( s1_long != 0 || string[0] == '0' )  && ( s2_long != 0  || s2[0] == '0' ) ) return s1_long - s2_long;
   // If both are valid numbers, compare them
   int slength = 0, stop = min( alloc_size, len( s2 ) ); // Calculate length of string
   if ( exact ) // If we want non-caseless match
     while ( string[ slength ] == s2[ slength ] && slength < stop ) slength++; // While equal
   else
     while ( toupper( string[ slength ] ) == toupper( s2[ slength ] ) && slength < stop ) slength++; // While equal
   return ( slength == 0 )?1:( slength == stop )?0:( ( int )( string[ slength ] ) > ( int )( s2[ slength ] ) )?slength:-slength; // Determine if they are equal or where they differ.
   // Equal
   // Ascii code number.
   // s2 larger than string
}

int cmp( var &v, const char c, bool exact ) {
   return v.cmp( c, exact ); // Reuse method (member function)
}


int var :: cmp( const char c, bool exact ) const {
   if ( string[ 0 ] == '\0' || c == '\0' ) return 0; // If string start with or character equals '\0'
   if ( exact ) // If we want non-caseless match
     if ( ( int )( string[ 0 ] ) > ( int )( c ) ) return 1; // Larger
     else if ( ( int )( string[ 0 ] ) == ( int )( c ) ) return 0// Equal
     else return -1; // Smaller
   else if ( toupper( string[ 0 ] ) > toupper( c ) ) return 1; // Larger
   else if ( toupper( string[ 0 ] ) == toupper( c ) ) return 0; // Equal
   else return -1; // Smaller
}

var cpy( var &v, const var &v2 ) { //Copy string to another
   return v.cpy( v2 ); // Reuse method (member function)
}

var& var :: cpy( const var &v2 ) { //Copy string to another
   int i = 0;
   alloc_size = ( static_size )?alloc_size:v2.alloc_size; // Determine size to allocate
   if ( !static_size ) { // Static size?
     delete [] string;
     string = new char[ alloc_size + 1 ];
   }
   for( ; i <= v2.alloc_size; i++ ) string[ i ] = v2.string[ i ];
   for( ; i <= alloc_size; i++ ) string[ i ] = '\0';
   return ( *this );
}

var& var :: cpy( const char* s, const int size  ) { //Copy string to another
   int i = 0;
   alloc_size = ( static_size )?alloc_size:size;
   if ( !static_size ) {
     delete [] string;
     string = new char[ alloc_size + 1 ];
   }
   for( ; i <= size; i++ ) string[ i ] = s[ i ];
   for( ; i <= alloc_size; i++ ) string[ i ] = '\0';
   return ( *this );
}

var cpy( var &v, const char c ) { //Copy character to string
   return v.cpy( c );
}

var& var :: cpy( const char c ) { //Copy character to string
   alloc_size = ( static_size )?alloc_size:2;
   if ( !static_size ) {
      delete [] string;
      string = new char[ alloc_size + 1 ];
   }
   string[ 0 ] = c;
   for( int i = 1; i <= alloc_size; i++  ) string[ i ] = '\0';
   return ( *this );
}

var& var :: set( RXSTRING* &rxString ) {
   strcpy( rxString->strptr, string );
   rxString->strlength = alloc_size;
   return ( *this );
}

var& var :: get( const RXSTRING* rxString ) {
   cpy( rxString->strptr );
   alloc_size = rxString->strlength;
   return ( *this );
}

var& var :: cat( const var &v2 ) { //Join two strings
   int s2length = ( v2.isAutoResizable() )?v2.allocated():v2.len(), i = 0;
   if ( !static_size ) {
      char* temp = new char[ alloc_size + s2length + 1 ];
      for ( ; i < alloc_size; i++  ) temp[ i ] = string[ i ];
      delete [] string;
      string = new char[ alloc_size + s2length + 1 ];
      for( i = 0; i < alloc_size && temp[ i ] != '\0'; i++  ) string[ i ] = temp[ i ];
      delete [] temp;
      alloc_size += s2length;
   } else i = len();
   for ( int j = 0; j < s2length && i < alloc_size; j++  ) string[ i++ ] = v2.string[ j ];
   for( ; i <= alloc_size; i++  ) string[ i ] = '\0';
   return ( *this );
}

var& var :: revCat( const var &v2 ) { //Join two strings
   int s2length = ( v2.isAutoResizable() )?v2.allocated():v2.len(), slength = ( static_size )?len():alloc_size, i = 0;
   char* temp = new char[ slength + 1 ];
   for ( ; i <= slength; i++ ) temp[ i ] = string[ i ];
   if ( !static_size ) {
      delete [] string;
      string = new char[ slength + s2length + 1 ];
      alloc_size = slength + s2length;
   }
   for( i = 0; i < s2length && i < alloc_size; i++ ) string[ i ] = v2.string[ i ];
   for( int j = 0; j < slength && i < alloc_size; j++ ) string[ i++ ] = temp[ j ];
   delete [] temp;
   for( ; i <= alloc_size; i++ ) string[ i ] = '\0';
   return ( *this );
}

var cat( var &v, const var &v2 ) { //Join two strings
   return v.cat( v2 );
}

var& var :: cat( const char c ) { //Join string and character
   int i = 0;
   if ( !static_size ) {
      char* temp = new char[ alloc_size + 1 ];
      for ( ; i < alloc_size; i++  ) temp[ i ] = string[ i ];
      temp[ alloc_size ] = '\0';
      delete [] string;
      string = new char[ alloc_size + 2 ];
      for ( i = 0; i < alloc_size && temp[ i ] != '\0'; i++  ) string[ i ] = temp[ i ];
      delete [] temp;
   } else while( string[ i ] != '\0' && i < alloc_size ) i++ ;
   string[ alloc_size ] = c;
   alloc_size = ( static_size )?alloc_size:++i;
   for( ; i <= alloc_size; i++  ) string[ i ] = '\0';
   return ( *this );
}

var cat( var &v, const char c ) { //Join string and character
   return v.cat( c );
}

var& var :: cat( const int i2 ) { //Join string and number
   char num[ 35 ];
   itoa( i2, num, 10 );
   return cat( num );
}

var cat( var &v1, const int i2 ) { //Join string and number
   char num[ 35 ];
   itoa( i2, num, 10 );
   return v1.cat( num );
}

var var :: split( const int pos, int skip ) { //Split and return string( s )
   int i = 0, v_pos = abs( pos ), v_skip = abs( skip );
   var retval;
   if ( alloc_size >= v_pos - v_skip ) {
     retval.reSize( alloc_size - v_pos - v_skip + 1 );
     char* temp = new char[ v_pos + 1 ];
     for ( ; i < v_pos; i++  ) temp[ i ] = string[ i ];
     temp[ v_pos ] = '\0';
     for ( i  += v_skip; i < alloc_size; i++  ) retval[ i - v_pos - v_skip ] = string[ i ];
     retval[ i - v_pos - v_skip ] = '\0';
     alloc_size = ( static_size )?alloc_size:v_pos;
     if ( !static_size ) {
        delete [] string;
        string = new char[ alloc_size + 1 ];
        i = alloc_size;
     } else for ( ; i > v_pos - 1; i-- ) string[ i ] = '\0';
     for ( ; i > -1; i-- ) string[ i ] = temp[ i ];
     delete [] temp;
   }
   return retval;
}

var var :: split( const var &needle, bool skip ) {
   int slength, pos = boyerMooreSearch( needle );
   if ( skip )
      slength = needle.isAutoResizable()?needle.allocated():needle.len();
   else
      slength = 0;
   if ( pos == -1 )
      return NULL;
   else
      return split( pos, slength );
}

var var :: split( const char needle, int start, int n ) {
   int pos = bruteForceSearch( needle, start );
   if ( pos == -1 )
      return ( *this );
   else
      return split( pos, n );
}

var split( char* &s1, const int pos, int skip ) { //Split and return string( s )
   var retval( s1 );
   int i = 0, slength = retval.allocated(), v_pos = abs( pos ), v_skip = abs( skip );
   retval.flush();
   if ( slength >= v_pos - v_skip ) {
     int totlength = slength - v_pos - v_skip;
     retval.reSize( v_pos + 1 );
     char* temp = new char[ totlength + 1 ];
     for ( ; i < v_pos; i++  ) retval[ i ] = s1[ i ];
     retval[ v_pos ] = '\0';
     for ( i += v_skip; i < slength; i++  ) temp[ i-v_pos-v_skip ] = s1[ i ];
     temp[ totlength ] = '\0';
     delete [] s1;
     s1 = new char[ totlength + 1 ];
     i = slength-v_pos-v_skip;
     for ( ; i > -1; i-- ) s1[ i ] = temp[ i ];
     delete []temp;
   }
   return retval;
}

var& var :: remstr( const int pos, int n ) { //Remove ( middle ) and return resulting string
   int i = 0, v_pos = abs( pos );
   n = abs( n );
   if ( !static_size ) {
      char* temp = new char[ alloc_size - n + 1 ];
      for ( ; i < v_pos; i++  ) temp[ i ] = string[ i ];
      for ( ; i <= alloc_size - n; i++  ) temp[ i ] = string[ i + n ];
      delete [] string;
      alloc_size -= n;
      string = new char[ alloc_size + 1 ];
      for( ; i >= alloc_size; i--  ) string[ i ] = '\0';
      for ( ; i > -1; i-- ) string[ i ] = temp[ i ];
      delete [] temp;
   } else {
      for ( int i = v_pos + n; i < alloc_size; i++  ) {
         string[ i - n ] = string[ i ];
         string[ i ] = '\0';
      }
   }
   return ( *this );
}

var remstr( var &v, const int pos, int n ) { //Remove ( middle ) and return resulting string
   return v.remstr( pos, n );
}

var remstr( char* s1, const int pos, int n ) { //Remove ( middle ) and return resulting string
   var temp( s1 );
   return temp.remstr( pos, n );
}

var& var :: substr( int start, int stop, char pad ) { //Return part of string
   if ( stop < 0 ) stop = alloc_size;
   if ( start > stop ) {
      int t_num = start;
      start = stop;
      stop = t_num;
   }
   start = min( abs( start ), alloc_size );
   int n = min( abs( stop - start ), alloc_size - start );
   int i = 0;
   var temp( n );
   for ( ; i < n; i++  ) temp[ i ] = string[ i + start ];
   if (!static_size) {
     delete [] string;
     alloc_size = n;
     string = new char[ alloc_size + 1 ];
   } /* endif */
   for ( i = 0; i < n; i++  ) string[ i ] = temp[ i ];
   for ( ; i < min( stop, alloc_size ); i++  ) string[ i ] = pad;
   for ( ; i < alloc_size + 1; i++  ) string[ i ] = '\0';
   return ( *this );
}

var var :: substr2( var &v, int start, int stop, char pad ) const { //Return part of string
   return v.substr( start, stop, pad );
}

var var :: substr2( int start, int stop, char pad ) const {
   var retval( *this );
   return retval.substr( start, stop, pad );
}

var var :: substr2( const char* s1, int start, int stop, char pad ) const { //Return part of string
   var temp( s1 );
   return temp.substr( start, stop, pad );
}

var& var :: cal( const var& s2, Calc calc ) {
   if ( isDigit() && s2.isDigit() ) {
      double s1num = atof( string ), s2num = atof( s2.string );
      var s1pre( 35 ), s1post( 35 ), s2pre( 35 );
      gcvt( s1num, 10, s1pre ); //Double to string
      gcvt( s2num, 10, s2pre ); //Double to string
      s1pre.reSize();
      s2pre.reSize();
      switch ( calc ) {
      case Sub:
         s1num -= s2num;
         break;
      case Div:
         s1num /= s2num;
         break;
      case Mult:
         s1num *= s2num;
         break;
      default:
        s1num += s2num;
        break;
      } /* endswitch */
      gcvt( s1num, 10, s1post );
      s1post.reSize();
      if ( !isAlpha() && s2.isAlpha() ) {
        cpy( s1post.cat( s2.substr2( s2pre.alloc_size ) ) );
      } else if ( isAlpha() && !s2.isAlpha() ) {
        cpy( s1post.cat( rightOf( s1pre ) ) );
      } else
        substr( s1pre.allocated() ).revCat( s1post ).cat( s2.substr2( s2pre.alloc_size ) );
   } else {
      if ( calc == Sub ) removeText( s2 );
      else if ( calc == Div ) split( s2, false );
      else if ( calc == Add ) cat( s2 );
   } /* else if */
   return ( *this );
}

int var :: boyerMooreSearch( const var &needle ) const {
  int i, j;
  int skip[256];
  int M = needle.isAutoResizable()?needle.allocated():needle.len();

  for ( i = 0; i < 256; ++i ) skip[ i ] = M;
  for ( i = 0; i < M; ++i ) skip[ needle.string[ i ] ] = M - 1 - i;

  for ( i = j = M - 1; j >= 0; --i, --j )
    while ( string[ i ] != needle.string[ j ] ) {
      i += max( M - j, skip[ string[ i ] ] );
      if ( i >= alloc_size ) return -1;
      j = M - 1;
    }
  return i + 1;
}

int boyerMooreSearch( var &haystack, const var &needle ) {
   return haystack.boyerMooreSearch( needle );
}

int var :: bruteForceSearch( const char needle, int start, bool exact ) const {
   int i = ( start < 0 )?0:min( start, alloc_size );
   if ( exact )
     for( ; i < alloc_size; i++  ) if( string[ i ] == needle ) return i;
   else
     for( ; i < alloc_size; i++  ) if( toupper( string[ i ] ) == toupper( needle ) ) return i;
   return -1;
}

int bruteForceSearch( var &haystack, const char needle, int start, bool exact ) {
   return haystack.bruteForceSearch( needle, start, exact );
}

int var :: reverseBruteForceSearch( const char needle, int start, bool exact ) const {
   int i = ( start < 0 )?alloc_size:min( start, alloc_size );
   if ( exact )
     for( ; i > -1; i-- ) if( string[ i ] == needle ) return i;
   else
     for( ; i > -1; i-- ) if( toupper( string[ i ] ) == toupper( needle ) ) return i;
   return -1;
}

int reverseBruteForceSearch( var &haystack, const char needle, int start, bool exact ) {
   return haystack.reverseBruteForceSearch( needle, start, exact );
}

var& var :: left( int pos ) {
   return substr( 0, pos, '\0' );
}

var& var :: middle( int length ) {
   return remstr( ( alloc_size - length ) / 2, length );
}

var& var :: right( int pos ) {
   return substr( pos, -1, '\0' );
}

var& var :: right( const var &v ) {
   int pos = boyerMooreSearch( v ); // "this" implied
   if ( pos == -1 )
      return ( *this );
   else
     return substr( pos, -1, '\0' );
}

var var :: right2( const var &v ) {
   int pos = boyerMooreSearch( v );
   if ( pos == -1 )
      return this;
   else
     return substr2( pos, -1, '\0' );
}

var& var :: leftOf( const var &v ) {
   int pos = boyerMooreSearch( v );
   if ( pos == -1 )
      return ( *this );
   else
      return substr( 0, pos, '\0' );
}

var var :: splitTo( const int pos, int skip ) { //Split and return string( s )
   int i = 0, v_pos = abs( pos ), v_skip = abs( skip );
   var retval;
   if ( alloc_size >= v_pos - v_skip ) {
     retval.reSize( v_pos + 1 );
     char* temp = new char[ alloc_size - v_pos - v_skip + 1 ];
     for ( ; i < v_pos; i++  ) retval[ i ] = string[ i ];
     retval[ v_pos ] = '\0';
     for ( i  += v_skip; i < alloc_size; i++  ) temp[ i - v_pos - v_skip ] = string[ i ];
     temp[ i - v_pos - v_skip ] = '\0';
     alloc_size -= ( static_size )?0:v_pos - v_skip;
     if ( !static_size ) {
        delete [] string;
        string = new char[ alloc_size + 1 ];
        i = alloc_size;
     } else for ( ; i > alloc_size - 1; i-- ) string[ i ] = '\0';
     for ( ; i > -1; i-- ) string[ i ] = temp[ i ];
     delete [] temp;
   }
   return retval;
}

var var :: splitTo( const var &needle, bool skip ) {
   int slength, pos = boyerMooreSearch( needle );
   if ( pos == -1 )
      return ( *this );
   else if ( skip )
      slength = needle.isAutoResizable()?needle.allocated():needle.len();
   else
      slength = 0;
   return splitTo( pos, slength );
}

var var :: splitTo( const char needle, int start, int n ) {
   int pos = bruteForceSearch( needle, start );
   if ( pos == -1 )
      return ( *this );
   else
      return splitTo( pos, n );
}

var var :: toLast2( const char needle ) const {
   int pos = reverseBruteForceSearch( needle );
   if ( pos == -1 )
      return ( *this );
   else
      return substr2( 0, pos + 1, '\0' );
}

var var :: afterLast2( const char needle ) const {
   int pos = reverseBruteForceSearch( needle );
   if ( pos == -1 )
      return ( *this );
   else
      return substr2( pos + 1, alloc_size, '\0' );
}

var& var :: rightOf( const var &v ) {
   int pos = boyerMooreSearch( v );
   if ( pos == -1 )
      return ( *this );
   else
      return substr( pos + (v.isAutoResizable()?v.allocated():v.len()), -1, '\0' );
}

var& var :: addRightOf( const var &v2 ) { //Join two strings
   int s2length = v2.isAutoResizable()?v2.allocated():v2.len(), i = 0;
   char* temp = new char[ alloc_size + s2length + 1 ];
   for ( ; i < alloc_size; i++  ) temp[ i ] = string[ i ];
   if ( !static_size ) {
      delete [] string;
      string = new char[ alloc_size + s2length + 1 ];
   }
   for( i = 0; i < s2length && v2.string[ i ] != '\0'; i++ ) string[ i ] = v2.string[ i ];
   for ( int j = 0; j < alloc_size; j++ ) string[ i++ ] = temp[ j ];
   delete [] temp;
   alloc_size = ( static_size )?alloc_size:i;
   for( ; i <= alloc_size; i++  ) string[ i ] = '\0';
   return ( *this );
}

int var :: words( const char c ) const {
   int i = 0, pos = 0;
   pos = bruteForceSearch( c, pos );
   while ( pos > -1 ) {
      i++ ;
      pos = bruteForceSearch( c, pos );
   } /* endwhile */
   return i;
}

var var :: word( int n, const char c ) const {
   int startpos = 0, stoppos;
   for( int i = 0; i < n && startpos < alloc_size; i++  ) startpos = bruteForceSearch( c, startpos );
   stoppos = ( startpos > -1 )?bruteForceSearch( c, startpos ):-1;
   return substr2( startpos > -1?startpos:0, ( stoppos > -1 )?stoppos:alloc_size );
}

var& var :: removeText( const var &needle ) {
   int slength = needle.isAutoResizable()?needle.allocated():needle.len(), pos = boyerMooreSearch( needle );
   if ( pos == -1 )
      return ( *this );
   else
      return remstr( pos, slength );
}

var& removeText( var &haystack, const var &needle ) {
   return haystack.removeText( needle );
}

var& var :: removeChar( const char needle ) {
   int pos = bruteForceSearch( needle );
   pos = ( pos < 0 )?alloc_size:pos;
   for ( ; pos < alloc_size; pos++  ) {
      remstr( pos, 1 );
      pos = bruteForceSearch( needle, pos ) - 1;
      pos = ( pos < 0 )?alloc_size:pos;
   } /* endfor */
   return ( *this );
}

var& removeChar( var &haystack, const char needle ) {
   return haystack.removeChar( needle );
}

var& var :: removeByChar( const var &needle ) {
   for ( int i = 0; i < needle.alloc_size; i++  ) removeChar( needle.string[ i ] );
   return ( *this );
}

var& var :: translateChar( const char from, const char to ) {
   int pos = bruteForceSearch( from );
   pos = ( pos < 0 )?alloc_size:pos;
   for ( ; pos < alloc_size; pos++  ) {
/*      if ( to == '\0' ) remstr( pos, 1 );
      else*/ this[ pos ] = to;
      pos = bruteForceSearch( from, pos ) - 1;
      pos = ( pos < 0 )?alloc_size:pos;
   } /* endfor */
   return ( *this );
}

var& var :: translateByChar( const var &from, const var &to ) {
   int i = 0, pos = 0, flength = from.alloc_size, slength = min( flength, to.alloc_size ); //From larger...remove other, to larger...ignore
   for ( ; i < slength; i++  ) translateChar( from.string[ i ], to.string[ i ] );
   for ( ; i < flength; i++  ) translateChar( from.string[ i ], '\0' );
   return ( *this );
}

var& var :: upper( ) {
   for ( int i = 0; i <= alloc_size; i++ )
      string[ i ] = toupper( string[ i ] );
   return ( *this );
}

var& var :: lower( ) {
   for ( int i = 0; i <= alloc_size; i++ )
      string[ i ] = tolower( string[ i ] );
   return ( *this );
}

var& var :: strip( const char c ) {
   int start = 0, stop = alloc_size;
   while( string[ start ] == c && start < alloc_size ) {
      start++;
   }
   while( string[ stop ] == c && 0 < stop ) {
      stop--;
   }
   return substr( start, stop );
}

var var :: strip2( const char c ) const {
   int start = 0, stop = alloc_size;
   while( string[ start ] == c && start < alloc_size ) {
      start++;
   }
   while( string[ stop ] == c && 0 < stop ) {
      stop--;
   }
   return substr2( start, stop );
}

var& var :: stripTrailing( const char c ) {
   int stop = static_size?len() - 1:alloc_size;
   while( string[ stop ] == c && 0 < stop ) {
      if ( static_size ) string[ stop ] = '\0';
      stop--;
   }
   if ( static_size ) return ( *this );
   else return substr( 0, stop );
}

var var :: stripTrailing2( const char c ) const {

   int stop = static_size?len() - 1:alloc_size;
   while( string[ stop ] == c && 0 < stop ) {
      stop--;
   }
   return substr2( 0, stop );
}

var& var :: insert( var &v, int pos, bool truncate ) {
   int i = 0, v_pos = abs( pos ), slength = static_size?len():alloc_size, vlength = v.isAutoResizable()?v.allocated():v.len();
   alloc_size += ( static_size && ( truncate || slength + vlength <= alloc_size ) )?0:slength;
   char* temp = new char[ alloc_size + 1 ];
   for( i = 0; i < v_pos; i++ ) temp[ i ] = string[ i ];
   for( ; i < v_pos + vlength; i++ ) temp[ i ] = v[ i - v_pos ];
   for( ; i <= alloc_size; i++ ) temp[ i ] = string[ i - vlength ];
   delete [] string;
   string = new char[ alloc_size + 1 ];
   for( i = 0; i < alloc_size; i++ ) string[ i ] = temp[ i ];
   delete [] temp;
   return ( *this );
}

bool var :: isDigit() const {
   return atof( string ) != 0;
}

bool var :: isDigit( const char* s1 ) const {
   return atof( s1 ) != 0;
}

bool var :: isAlpha() const {
   double num = atof( string );
   var temp( 35 );
   gcvt( num, 10, temp );
   temp.reSize();
   return ( temp.alloc_size < alloc_size );
}

bool var :: isAlpha( const char* s1 ) const {
   double num = atof( s1 );
   var temp( 35 );
   gcvt( num, 10, temp );
   temp.reSize();
   return ( temp.alloc_size < len( s1 ) );
}

ostream& operator << ( ostream& out, const var& v ) {
   out << v.string;
   return out;
}

istream& operator >> ( istream& in, const var& v ) {
   in >> v.string;
   return in;
}

var operator + ( const char* s1, const var& v ) {
   var temp( s1 );
   temp += v;
   return temp;
}

var operator + ( const char c, const var& v ) {
    var temp( 2 );
    temp[ 0 ] = c;
    temp[ 1 ] = '\0';
    return temp.cal( v, Add );
}

var operator + ( const int i, const var& v ) {
   var temp( 17 );
   itoa( i, temp, 10 );
   temp.reSize();
   return temp.cal( v, Add );
}

var operator + ( const long l, const var& v ) {
   var temp( 17 );
   ltoa( l, temp, 10 );
   temp.reSize();
   return temp.cal( v, Add );
}

var operator + ( const double d, const var& v ) {
   var temp( 35 );
   gcvt( d, 10, temp );
   temp.reSize();
   return temp.cal( v, Add );
}

var operator - ( const char* s1, const var& v ) {
   var temp( s1 );
   temp -= v;
   return temp;
}

var operator - ( const char c, const var& v ) {
    var temp( 2 );
    temp[ 0 ] = c;
    temp[ 1 ] = '\0';
    return temp.cal( v, Sub );
}

var operator - ( const int i, const var& v ) {
   var temp( 17 );
   itoa( i, temp, 10 );
   temp.reSize();
   return temp.cal( v, Sub );
}

var operator - ( const long l, const var& v ) {
   var temp( 17 );
   ltoa( l, temp, 10 );
   temp.reSize();
   return temp.cal( v, Sub );
}

var operator - ( const double d, const var& v ) {
   var temp( 35 );
   gcvt( d, 10, temp );
   temp.reSize();
   return temp.cal( v, Sub );
}

var operator * ( const int i, const var& v ) {
   var temp( 17 );
   itoa( i, temp, 10 );
   temp.reSize();
   return temp.cal( v, Mult );
}

var operator * ( const long l, const var& v ) {
   var temp( 17 );
   ltoa( l, temp, 10 );
   temp.reSize();
   return temp.cal( v, Mult );
}

var operator * ( const double d, const var& v ) {
   var temp( 35 );
   gcvt( d, 10, temp );
   temp.reSize();
   return temp.cal( v, Mult );
}

var operator / ( const char* s1, const var& v ) {
   var temp( s1 );
   temp /= v;
   return temp;
}

var operator / ( const char c, const var& v ) {
    var temp( 2 );
    temp[ 0 ] = c;
    temp[ 1 ] = '\0';
    return temp.cal( v, Div );
}

var operator / ( const int i, const var& v ) {
   var temp( 17 );
   itoa( i, temp, 10 );
   temp.reSize();
   return temp.cal( v, Div );
}

var operator / ( const long l, const var& v ) {
   var temp( 17 );
   ltoa( l, temp, 10 );
   temp.reSize();
   return temp.cal( v, Div );
}

var operator / ( const double d, const var& v ) {
   var temp( 35 );
   gcvt( d, 10, temp );
   temp.reSize();
   return temp.cal( v, Div );
}

var& var :: operator = ( const char* s2 ) {
   return cpy( s2 );
}

var& var :: operator = ( const char c ) {
   return cpy( c );
}

var& var :: operator = ( const var& v ) {
   return cpy( v );
}

var& var :: operator = ( const int i ) {
   if ( !static_size )
     reSize( max( alloc_size, 35 ), false );
   itoa( i, string, 10 );
   if ( !static_size )
      reSize();
   return ( *this );
}

var& var :: operator = ( const long l ) {
   if ( !static_size )
     reSize( max( alloc_size, 35 ), false );
   ltoa( l, string, 10 );
   if ( !static_size )
      reSize();
   return ( *this );
}

var& var :: operator = ( const double d ) {
   if ( !static_size )
     reSize( max( alloc_size, 35 ), false );
   gcvt( d, 10, string );
   if ( !static_size )
      reSize();
   return ( *this );
}

bool var :: operator < ( const char* s2 ) const {
   return cmp( s2 ) < 0;
}

bool var :: operator < ( const char c ) const {
   return cmp( c ) < 0;
}

bool var :: operator < ( const var& v ) const {
   return cmp( v.string ) < 0;
}

bool var :: operator < ( const int i ) const {
   char num[ 17 ];
   itoa( i, num, 10 );
   return ( string < num );
}

bool var :: operator < ( const long l ) const {
   char num[ 35 ];
   ltoa( l, num, 10 );
   return ( string < num );
}

bool var :: operator < ( const double d ) const {
   char num[ 35 ];
   gcvt( d, 10, num );
   return ( string < num );
}

bool var :: operator > ( const char* s2 ) const {
   return cmp( s2 );
}

bool var :: operator > ( const char c ) const {
   return string > ( char* )c;
}

bool var :: operator > ( const var& v ) const {
   return string > v.string;
}

bool var :: operator > ( const int i ) const {
   char num[ 17 ];
   itoa( i, num, 10 );
   return string > num;
}

bool var :: operator > ( const long l ) const {
   char num[ 35 ];
   ltoa( l, num, 10 );
   return ( string > num );
}

bool var :: operator > ( const double d ) const {
   char num[ 35 ];
   gcvt( d, 10, num );
   return ( string > num );
}

bool var :: operator <= ( const char* s2 ) const {
   return cmp( s2 )>0?false:true;
}

bool var :: operator <= ( const char c ) const {
   return cmp( c )>0?false:true;
}

bool var :: operator <= ( const var& v ) const {
   return cmp( v.string )>0?false:true;
}

bool var :: operator <= ( const int i ) const {
   char num[ 17 ];
   itoa( i, num, 10 );
   return cmp( num )>0?false:true;
}

bool var :: operator <= ( const long l ) const {
   char num[ 35 ];
   ltoa( l, num, 10 );
   return cmp( num )>0?false:true;
}

bool var :: operator <= ( const double d ) const {
   char num[ 35 ];
   gcvt( d, 10, num );
   return cmp( num )>0?false:true;
}

bool var :: operator >= ( const char* s2 ) const {
   return cmp( s2 )<0?false:true;
}

bool var :: operator >= ( const char c ) const {
   return cmp( c )<0?false:true;
}

bool var :: operator >= ( const var& v ) const {
   return cmp( v.string )<0?false:true;
}

bool var :: operator >= ( const int i ) const {
   char num[ 17 ];
   itoa( i, num, 10 );
   return cmp( num )<0?false:true;
}

bool var :: operator >= ( const long l ) const {
   char num[ 35 ];
   ltoa( l, num, 10 );
   return cmp( num )<0?false:true;
}

bool var :: operator >= ( const double d ) const {
   char num[ 35 ];
   gcvt( d, 10, num );
   return cmp( num )<0?false:true;
}

return_type

bool
var :: operator == ( const char* s2 ) const {
   return ( cmp( s2 ) == 0 );
}

bool var :: operator == ( const char c ) const {
   return ( cmp( ( char* )c ) == 0 );
}

bool var :: operator == ( const var& v ) const {
   return ( cmp( v.string ) == 0 );
}

bool var :: operator == ( const int i ) const {
   char num[ 17 ];
   itoa( i, num, 10 );
   return ( cmp( num ) == 0 );
}

bool var :: operator == ( const long l ) const {
   char num[ 35 ];
   ltoa( l, num, 10 );
   return ( cmp( num ) == 0 );
}

bool var :: operator == ( const double d ) const {
   char num[ 35 ];
   gcvt( d, 10, num );
   return ( cmp( num ) == 0 );
}

bool var :: operator ^= ( const char* s2 ) const {
   return ( cmp( s2, false ) == 0 );
}

bool var :: operator ^= ( const char c ) const {
   return ( cmp( ( char * )c, false ) == 0 );
}

bool var :: operator ^= ( const var& v ) const {
   return ( cmp( v.string, false ) == 0 );
}

bool var :: operator ^= ( const int i ) const {
   char num[ 17 ];
   itoa( i, num, 10 );
   return ( cmp( num, false ) == 0 );
}

bool var :: operator ^= ( const long l ) const {
   char num[ 35 ];
   ltoa( l, num, 10 );
   return ( cmp( num, false ) == 0 );
}

bool var :: operator ^= ( const double d ) const {
   char num[ 35 ];
   gcvt( d, 10, num );
   return ( cmp( num, false ) == 0 );
}

bool var :: operator != ( const char* s2 ) const {
   return ( cmp( s2 ) != 0 );
}

bool var :: operator != ( const char s2 ) const {
   return ( cmp( s2 ) != 0 );
}

bool var :: operator != ( const var& v ) const {
   return ( cmp( v.string ) != 0 );
}

bool var :: operator != ( const int i ) const {
   return ( cmp( i ) != 0 );
}

bool var :: operator != ( const long l ) const {
   char num[ 17 ];
   ltoa( l, num, 10 );
   return ( cmp( num ) != 0 );
}

bool var :: operator != ( const double d ) const {
   char num[ 35 ];
   gcvt( d, 10, num );
   return ( cmp( num ) != 0 );
}

var& var :: operator  += ( const char* s2 ) {
   cal( s2, Add );
   return ( *this );
}

var& var :: operator  += ( const char c ) {
   cal( ( char * )c, Add );
   return ( *this );
}

var& var :: operator  += ( const var& v ) {
   cal( v, Add );
   return ( *this );
}

var& var :: operator  += ( const int i ) {
   var num( 17 );
   itoa( i, num, 10 );
   cal( num, Add );
   return ( *this );
}

var& var :: operator  += ( const long l ) {
   var num( 35 );
   ltoa( l, num, 10 );
   cal( num, Add );
   return ( *this );
}

var& var :: operator  += ( const double d ) {
   var num( 35 );
   gcvt( d, 10, num );
   cal( num, Add );
   return ( *this );
}

var& var :: operator -= ( const char* s2 ) {
   cal( s2, Sub );
   return ( *this );
}

var& var :: operator -= ( const char c ) {
   cal( ( char * )c, Sub );
   return ( *this );
}

var& var :: operator -= ( const var& v ) {
   cal( v, Sub );
   return ( *this );
}

var& var :: operator -= ( const int i ) {
   var num( 17 );
   itoa( i, num, 10 );
   cal( num, Sub );
   return ( *this );
}

var& var :: operator -= ( const long l ) {
   var num( 35 );
   ltoa( l, num, 10 );
   cal( num, Sub );
   return ( *this );
}

var& var :: operator -= ( const double d ) {
   var num( 35 );
   gcvt( d, 10, num );
   cal( num, Sub );
   return ( *this );
}

var& var :: operator *= ( const int i ) {
   var num( 17 );
   itoa( i, num, 10 );
   cal( num, Mult );
   return ( *this );
}

var& var :: operator *= ( const long l ) {
   var num( 35 );
   ltoa( l, num, 10 );
   cal( num, Mult );
   return ( *this );
}

var& var :: operator *= ( const double d ) {
   var num( 35 );
   gcvt( d, 10, num );
   cal( num, Mult );
   return ( *this );
}

var& var :: operator /= ( const char* s2 ) {
   cal( s2, Div );
   return ( *this );
}

var& var :: operator /= ( const char c ) {
   cal( ( char * )c, Div );
   return ( *this );
}

var& var :: operator /= ( const var& v ) {
   cal( v, Div );
   return ( *this );
}

var& var :: operator /= ( const int i ) {
   var num( 17 );
   itoa( i, num, 10 );
   cal( num, Div );
   return ( *this );
}

var& var :: operator /= ( const long l ) {
   var num( 35 );
   ltoa( l, num, 10 );
   cal( num, Div );
   return ( *this );
}

var& var :: operator /= ( const double d ) {
   var num( 35 );
   gcvt( d, 10, num );
   cal( num, Div );
   return ( *this );
}

var var :: operator + ( const char* s2 ) const {
   var temp( *this );
   temp += s2;
   return temp;
}

var var :: operator + ( const char c ) const {
   var temp( *this );
   temp += c;
   return temp;
}

var var :: operator + ( const var& v ) const {
   var temp( *this );
   temp += v;
   return temp;
}

var var :: operator + ( const int i ) const {
   var temp( *this );
   temp += i;
   return temp;
}

var var :: operator + ( const long l ) const {
   var temp( *this );
   temp += l;
   return temp;
}

var var :: operator + ( const double d ) const {
   var temp( *this );
   temp += d;
   return temp;
}

var var :: operator - ( const char* s2 ) const {
   var temp( *this );
   temp -= s2;
   return temp;
}

var var :: operator - ( const char c ) const {
   var temp( *this );
   temp -= c;
   return temp;
}

var var :: operator - ( const var& v ) const {
   var temp( *this );
   temp -= v;
   return temp;
}

var var :: operator - ( const int i ) const {
   var temp( *this );
   temp -= i;
   return temp;
}

var var :: operator - ( const long l ) const {
   var temp( *this );
   temp -= l;
   return temp;
}

var var :: operator - ( const double d ) const {
   var temp( *this );
   temp -= d;
   return temp;
}

var var :: operator * ( const int i ) const {
   var temp( *this );
   temp *= i;
   return temp;
}

var var :: operator * ( const long l ) const {
   var temp( *this );
   temp *= l;
   return temp;
}

var var :: operator * ( const double d ) const {
   var temp( *this );
   temp *= d;
   return temp;
}

var var :: operator / ( const char* s2 ) const {
   var temp( *this );
   temp /= s2;
   return temp;
}

var var :: operator / ( const char c ) const {
   var temp( *this );
   temp /= c;
   return temp;
}

var var :: operator / ( const var& v ) const {
   var temp( *this );
   temp /= v;
   return temp;
}

var var :: operator / ( const int i ) const {
   var temp( *this );
   temp /= i;
   return temp;
}

var var :: operator / ( const long l ) const {
   var temp( *this );
   temp /= l;
   return temp;
}

var var :: operator / ( const double d ) const {
   var temp( *this );
   temp /= d;
   return temp;
}

char& var :: operator [] ( const int i ) { // Safe, but missleading when i > alloc_size.
   return string[ alloc_size > 0?i % alloc_size:0 ];
}