#include "String.h"

bool streq (const char* p, const char* q) {
  if(p==q) return true;
  if(!(p&&q)) return false;
  char a=*p, b=*q;
  while(a==b) {
    if(a==0) return true;
    p++;
    q++;
    a=*p; b=*q;
  }
  return false;
}

int strlen (const char* p) {
  int l=0;
  if(p) 
    while(*p) {
      l++;
      p++;
    }
  return l;
}

char* strdup (const char* p) {
  if(!p) {
    return 0;
  }
  else {
    int l = strlen(p);
    char* string = new char[l+1];
    char* s = string;
    for(int i=l+1; i; i--) {
      *s = *p;
      p++;
      s++;
    }
    return string;
  }
}

char* strcat (const char* a, const char* b) {
  if(!a)
    return strdup(b);
  if(!b)
    return strdup(a);
  int la = strlen(a);
  int lb = strlen(b);
  char* string = new char[la+lb+1];
  char* s = string;
  for(int i=la; i; i--) {
    *s = *a;
    a++;
    s++;
  }
  for(int i=lb+1; i; i--) {
    *s = *b;
    b++;
    s++;
  }
  return string;
}

String& String::operator = (const char *p)
{
  delete[] string;
  string = strdup(p);
  len = strlen(p);  
  return *this;  
}

String::String(const char* p = 0) {
  string=0;
  this->operator=(p);
}

String::String(const String& x) {
  this->operator=(x());
}

String& String::operator = (const String& x) {
  delete[] string;
  string = strdup(x());
  len = x.len;
  return *this;
}

String::~String() {
  delete[] string;
}

String& String::operator += (const char* p) {
  char* __temp = strcat(string, p);
  delete[] string;
  string = __temp;
  len = strlen(__temp);
  return *this;
}

String& String::operator += (const String & S) {
  char* __temp = strcat(string, S.string);
  delete[] string;
  string = __temp;
  len = strlen(__temp);
  return *this;
}


String operator + (const String &x, const String &y) {
  return String(strcat(x(), y()));
}

bool operator == (const String& x, const char *p) __attribute__ ((const));

bool operator == (const String& x, const char *p) {
  return streq(x(), p);
}

bool operator == (const String& x, const String& y) __attribute__ ((const));

bool operator == (const String& x, const String& y) {
  return streq(x(), y());
}

ostream& operator << (ostream& s, const String& x) __attribute__ ((const));

ostream& operator << (ostream& s, const String& x) {
  return (s<<x());
}
