

static char rcsid[] = "@(#)$Header: /home/vi/gregk/wjr/src/support-gregk/strings.c gregk Exp $";


#include "strings.h"



String strNew(int mxlen)
{
  String str;

  if (mxlen <= 0)
    mxlen = 10;
  
  if ((str = (String) malloc(sizeof(StringHeader))) == NULLSTRING)
    return NULLSTRING;

  if ((str->data = (char *) malloc(mxlen+1)) == (char *) NULL) {
    free(str);
    return NULLSTRING;
  }

  str->mxlen   = mxlen;
  str->data[0] = (char) 0;

  return str;  
}

void strFree(String str)
{
  if (str != NULLSTRING) {
    free(str->data);
    free(str);
  }
}

String strClear(String str)
{
  if (str != NULLSTRING) {
    str->data[0] = (char) 0;
  }

  return str;
}

String strInit_(String *dest, char *s)
{
  int slen;


  if (s == (char *) NULL)
    return strClear(*dest);
  else {
    slen = strlen(s);

    if (*dest == NULLSTRING) {
      *dest = strNew(slen);

      if (*dest == NULLSTRING)
	return NULLSTRING;
    }
    else if ((*dest)->mxlen < slen) {
      char *new = (char *) malloc(slen+1);

      if (new == (char *) NULL)
	return NULLSTRING;
    
      free((*dest)->data);
      (*dest)->data  = new;
      (*dest)->mxlen = slen;
    }

    strcpy((*dest)->data, s);
    return *dest;
  }
}

String strCopy_(String *dest, String src)
{
  return strInit_(dest, strGet(src));
}

String strNewCopy(String str)
{
  String tmp;
  
  if (str == NULLSTRING)
    return NULLSTRING;

  tmp = strNew(strLen(str));
  return strCopy(tmp, str);
}

String strCat_(String *dest, String src)
{
  int dlen, slen;


  slen = strLen(src);
  dlen = strLen(*dest);
  
  if (*dest == NULLSTRING) {
    *dest = strNew(slen);

    if (*dest == NULLSTRING)
      return NULLSTRING;
  }
  
  if (dlen + slen > (*dest)->mxlen  &&  strNewLen_(dest, 2*(dlen + slen)))
    return NULLSTRING;

  strcpy((*dest)->data + dlen, src->data);
  return *dest;
}

String strAddChar_(String *dest, char ch)
{
  int dlen;
  
  if (*dest == NULLSTRING) {
    *dest = strNew(20);

    if (*dest == NULLSTRING)
      return NULLSTRING;
  }

  dlen = strlen((*dest)->data);
  if (dlen >= (*dest)->mxlen  &&  strNewLen_(dest, 2*dlen))
    return NULLSTRING;

  (*dest)->data[dlen]     = ch;
  (*dest)->data[dlen + 1] = (char) 0;
  return *dest;
}

int strNewLen_(String *dest, int newlen)
{
  char *new;
  int dlen;

  
  if (*dest == NULLSTRING) {
    return ((*dest = strNew(newlen)) == NULLSTRING);
  }
  else {
    if ((dlen = strlen((*dest)->data)) > newlen)
      return 1;

    new = (char *) malloc(newlen + 1);

    if (new == (char *) NULL)
      return 1;

    strcpy(new, (*dest)->data);
    free((*dest)->data);
    (*dest)->data  = new;
    (*dest)->mxlen = newlen;

    return 0;
  }
}
  
String strMake(char *s)
{
  String tmp = NULLSTRING;
  
  return strInit(tmp, s);
}

int    strLen(String str)
{
  return (str == NULLSTRING) ? 0 : strlen(str->data);
}

int    strCmp(String a, String b)
{
  char *aa = (a == NULLSTRING) ? "" : a->data;
  char *bb = (b == NULLSTRING) ? "" : b->data;

  return strcmp(aa, bb);
}

int    strMaxLen(String str)
{
  return (str == NULLSTRING) ? 0 : str->mxlen;
}

char  *strGet(String str)
{
  return (str == NULLSTRING) ? "" : str->data;
}

char    strRef(String str, int i)
{
  if (str == NULLSTRING) {
    return (char) 0;
  }
  else if (i >= str->mxlen  ||  i < 0) {
    assert(0);
    return (char) 0;
  }
#ifdef STRING_CHK_REF
  else if (i >= strlen(str->data)) {
    assert(0);
    return (char) 0;
  }
#endif
  else
    return str->data[i];
}

