/* An abstract string datatype.
   Copyright (C) 1998-2021 Free Software Foundation, Inc.
   Contributed by Mark Mitchell (mark@markmitchell.com).

This file is part of GNU CC.
   
GNU CC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

In addition to the permissions in the GNU General Public License, the
Free Software Foundation gives you unlimited permission to link the
compiled version of this file into combinations with other programs,
and to distribute those combinations without any restriction coming
from the use of this file.  (The General Public License restrictions
do apply in other respects; for example, they cover modification of
the file, and distribution when not linked into a combined
executable.)

GNU CC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU CC; see the file COPYING.  If not, write to
the Free Software Foundation, 51 Franklin Street - Fifth Floor,
Boston, MA 02110-1301, USA.  */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <stdio.h>

#ifdef HAVE_STRING_H
#include <string.h>
#endif

#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif

#include "libiberty.h"
#include "dyn-string.h"

/* Performs in-place initialization of a dyn_string struct.  This
   function can be used with a dyn_string struct on the stack or
   embedded in another object.  The contents of of the string itself
   are still dynamically allocated.  The string initially is capable
   of holding at least SPACE characeters, including the terminating
   NUL.  If SPACE is 0, it will silently be increated to 1.  

   If RETURN_ON_ALLOCATION_FAILURE is defined and memory allocation
   fails, returns 0.  Otherwise returns 1.  */

int
dyn_string_init (struct dyn_string *ds_struct_ptr, int space)
{
  /* We need at least one byte in which to store the terminating NUL.  */
  if (space == 0)
    space = 1;

#ifdef RETURN_ON_ALLOCATION_FAILURE
  ds_struct_ptr->s = (char *) malloc (space);
  if (ds_struct_ptr->s == NULL)
    return 0;
#else
  ds_struct_ptr->s = XNEWVEC (char, space);
#endif
  ds_struct_ptr->allocated = space;
  ds_struct_ptr->length = 0;
  ds_struct_ptr->s[0] = '\0';

  return 1;
}

/* Create a new dynamic string capable of holding at least SPACE
   characters, including the terminating NUL.  If SPACE is 0, it will
   be silently increased to 1.  If RETURN_ON_ALLOCATION_FAILURE is
   defined and memory allocation fails, returns NULL.  Otherwise
   returns the newly allocated string.  */

dyn_string_t 
dyn_string_new (int space)
{
  dyn_string_t result;
#ifdef RETURN_ON_ALLOCATION_FAILURE
  result = (dyn_string_t) malloc (sizeof (struct dyn_string));
  if (result == NULL)
    return NULL;
  if (!dyn_string_init (result, space))
    {
      free (result);
      return NULL;
    }
#else
  result = XNEW (struct dyn_string);
  dyn_string_init (result, space);
#endif
  return result;
}

/* Free the memory used by DS.  */

void 
dyn_string_delete (dyn_string_t ds)
{
  free (ds->s);
  free (ds);
}

/* Returns the contents of DS in a buffer allocated with malloc.  It
   is the caller's responsibility to deallocate the buffer using free.
   DS is then set to the empty string.  Deletes DS itself.  */

char*
dyn_string_release (dyn_string_t ds)
{
  /* Store the old buffer.  */
  char* result = ds->s;
  /* The buffer is no longer owned by DS.  */
  ds->s = NULL;
  /* Delete DS.  */
  free (ds);
  /* Return the old buffer.  */
  return result;
}

/* Increase the capacity of DS so it can hold at least SPACE
   characters, plus the terminating NUL.  This function will not (at
   present) reduce the capacity of DS.  Returns DS on success. 

   If RETURN_ON_ALLOCATION_FAILURE is defined and a memory allocation
   operation fails, deletes DS and returns NULL.  */

dyn_string_t 
dyn_string_resize (dyn_string_t ds, int space)
{
  int new_allocated = ds->allocated;

  /* Increase SPACE to hold the NUL termination.  */
  ++space;

  /* Increase allocation by factors of two.  */
  while (space > new_allocated)
    new_allocated *= 2;
    
  if (new_allocated != ds->allocated)
    {
      ds->allocated = new_allocated;
      /* We actually need more space.  */
#ifdef RETURN_ON_ALLOCATION_FAILURE
      ds->s = (char *) realloc (ds->s, ds->allocated);
      if (ds->s == NULL)
	{
	  free (ds);
	  return NULL;
	}
#else
      ds->s = XRESIZEVEC (char, ds->s, ds->allocated);
#endif
    }

  return ds;
}

/* Sets the contents of DS to the empty string.  */

void
dyn_string_clear (dyn_string_t ds)
{
  /* A dyn_string always has room for at least the NUL terminator.  */
  ds->s[0] = '\0';
  ds->length = 0;
}

/* Makes the contents of DEST the same as the contents of SRC.  DEST
   and SRC must be distinct.  Returns 1 on success.  On failure, if
   RETURN_ON_ALLOCATION_FAILURE, deletes DEST and returns 0.  */

int
dyn_string_copy (dyn_string_t dest, dyn_string_t src)
{
  if (dest == src)
    abort ();

  /* Make room in DEST.  */
  if (dyn_string_resize (dest, src->length) == NULL)
    return 0;
  /* Copy DEST into SRC.  */
  strcpy (dest->s, src->s);
  /* Update the size of DEST.  */
  dest->length = src->length;
  return 1;
}

/* Copies SRC, a NUL-terminated string, into DEST.  Returns 1 on
   success.  On failure, if RETURN_ON_ALLOCATION_FAILURE, deletes DEST
   and returns 0.  */

int
dyn_string_copy_cstr (dyn_string_t dest, const char *src)
{
  int length = strlen (src);
  /* Make room in DEST.  */
  if (dyn_string_resize (dest, length) == NULL)
    return 0;
  /* Copy DEST into SRC.  */
  strcpy (dest->s, src);
  /* Update the size of DEST.  */
  dest->length = length;
  return 1;
}

/* Inserts SRC at the beginning of DEST.  DEST is expanded as
   necessary.  SRC and DEST must be distinct.  Returns 1 on success.
   On failure, if RETURN_ON_ALLOCATION_FAILURE, deletes DEST and
   returns 0.  */

int
dyn_string_prepend (dyn_string_t dest, dyn_string_t src)
{
  return dyn_string_insert (dest, 0, src);
}

/* Inserts SRC, a NUL-terminated string, at the beginning of DEST.
   DEST is expanded as necessary.  Returns 1 on success.  On failure,
   if RETURN_ON_ALLOCATION_FAILURE, deletes DEST and returns 0. */

int
dyn_string_prepend_cstr (dyn_string_t dest, const char *src)
{
  return dyn_string_insert_cstr (dest, 0, src);
}

/* Inserts SRC into DEST starting at position POS.  DEST is expanded
   as necessary.  SRC and DEST must be distinct.  Returns 1 on
   success.  On failure, if RETURN_ON_ALLOCATION_FAILURE, deletes DEST
   and returns 0.  */

int
dyn_string_insert (dyn_string_t dest, int pos, dyn_string_t src)
{
  int i;

  if (src == dest)
    abort ();

  if (dyn_string_resize (dest, dest->length + src->length) == NULL)
    return 0;
  /* Make room for the insertion.  Be sure to copy the NUL.  */
  for (i = dest->length; i >= pos; --i)
    dest->s[i + src->length] = dest->s[i];
  /* Splice in the new stuff.  */
  strncpy (dest->s + pos, src->s, src->length);
  /* Compute the new length.  */
  dest->length += src->length;
  return 1;
}

/* Inserts SRC, a NUL-terminated string, into DEST starting at
   position POS.  DEST is expanded as necessary.  Returns 1 on
   success.  On failure, RETURN_ON_ALLOCATION_FAILURE, deletes DEST
   and returns 0.  */

int
dyn_string_insert_cstr (dyn_string_t dest, int pos, const char *src)
{
  int i;
  int length = strlen (src);

  if (dyn_string_resize (dest, dest->length + length) == NULL)
    return 0;
  /* Make room for the insertion.  Be sure to copy the NUL.  */
  for (i = dest->length; i >= pos; --i)
    dest->s[i + length] = dest->s[i];
  /* Splice in the new stuff.  */
  memcpy (dest->s + pos, src, length);
  /* Compute the new length.  */
  dest->length += length;
  return 1;
}

/* Inserts character C into DEST starting at position POS.  DEST is
   expanded as necessary.  Returns 1 on success.  On failure,
   RETURN_ON_ALLOCATION_FAILURE, deletes DEST and returns 0.  */

int
dyn_string_insert_char (dyn_string_t dest, int pos, int c)
{
  int i;

  if (dyn_string_resize (dest, dest->length + 1) == NULL)
    return 0;
  /* Make room for the insertion.  Be sure to copy the NUL.  */
  for (i = dest->length; i >= pos; --i)
    dest->s[i + 1] = dest->s[i];
  /* Add the new character.  */
  dest->s[pos] = c;
  /* Compute the new length.  */
  ++dest->length;
  return 1;
}
     
/* Append S to DS, resizing DS if necessary.  Returns 1 on success.
   On failure, if RETURN_ON_ALLOCATION_FAILURE, deletes DEST and
   returns 0.  */

int
dyn_string_append (dyn_string_t dest, dyn_string_t s)
{
  if (dyn_string_resize (dest, dest->length + s->length) == 0)
    return 0;
  strcpy (dest->s + dest->length, s->s);
  dest->length += s->length;
  return 1;
}

/* Append the NUL-terminated string S to DS, resizing DS if necessary.
   Returns 1 on success.  On failure, if RETURN_ON_ALLOCATION_FAILURE,
   deletes DEST and returns 0.  */

int
dyn_string_append_cstr (dyn_string_t dest, const char *s)
{
  int len = strlen (s);

  /* The new length is the old length plus the size of our string, plus
     one for the null at the end.  */
  if (dyn_string_resize (dest, dest->length + len) == NULL)
    return 0;
  strcpy (dest->s + dest->length, s);
  dest->length += len;
  return 1;
}

/* Appends C to the end of DEST.  Returns 1 on success.  On failure,
   if RETURN_ON_ALLOCATION_FAILURE, deletes DEST and returns 0.  */

int
dyn_string_append_char (dyn_string_t dest, int c)
{
  /* Make room for the extra character.  */
  if (dyn_string_resize (dest, dest->length + 1) == NULL)
    return 0;
  /* Append the character; it will overwrite the old NUL.  */
  dest->s[dest->length] = c;
  /* Add a new NUL at the end.  */
  dest->s[dest->length + 1] = '\0';
  /* Update the length.  */
  ++(dest->length);
  return 1;
}

/* Sets the contents of DEST to the substring of SRC starting at START
   and ending before END.  START must be less than or equal to END,
   and both must be between zero and the length of SRC, inclusive.
   Returns 1 on success.  On failure, if RETURN_ON_ALLOCATION_FAILURE,
   deletes DEST and returns 0.  */

int
dyn_string_substring (dyn_string_t dest, dyn_string_t src,
                      int start, int end)
{
  int i;
  int length = end - start;

  if (start > end || start > src->length || end > src->length)
    abort ();

  /* Make room for the substring.  */
  if (dyn_string_resize (dest, length) == NULL)
    return 0;
  /* Copy the characters in the substring,  */
  for (i = length; --i >= 0; )
    dest->s[i] = src->s[start + i];
  /* NUL-terimate the result.  */
  dest->s[length] = '\0';
  /* Record the length of the substring.  */
  dest->length = length;

  return 1;
}

/* Returns non-zero if DS1 and DS2 have the same contents.  */

int
dyn_string_eq (dyn_string_t ds1, dyn_string_t ds2)
{
  /* If DS1 and DS2 have different lengths, they must not be the same.  */
  if (ds1->length != ds2->length)
    return 0;
  else
    return !strcmp (ds1->s, ds2->s);
}
