/* A buffer that accumulates a string by piecewise concatenation, from the end
   to the start.
   Copyright (C) 2021-2026 Free Software Foundation, Inc.

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

   This file 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 Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public License
   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */

/* Written by Bruno Haible <bruno@clisp.org>, 2025.  */

#include <config.h>

/* Specification.  */
#include "string-buffer-reversed.h"

/* Undocumented.  */
extern int sbr_ensure_more_bytes (struct string_buffer_reversed *buffer,
                                  size_t increment);

#include <errno.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int
sbr_prependvf (struct string_buffer_reversed *buffer, const char *formatstring,
               va_list list)
{

  /* Make a bit of room, so that the probability that the first vsnzprintf()
     call succeeds is high.  */
  size_t room = buffer->allocated - buffer->length;
  if (room < 64)
    {
      if (sbr_ensure_more_bytes (buffer, 64) < 0)
        {
          buffer->oom = true;
          errno = ENOMEM;
          return -1;
        }
      room = buffer->allocated - buffer->length;
    }

  va_list list_copy;
  va_copy (list_copy, list);

  /* First vsnzprintf() call.  */
  ptrdiff_t ret = vsnzprintf (buffer->data, room, formatstring, list);
  if (ret < 0)
    {
      /* Failed.  errno is set.  */
      if (errno == ENOMEM)
        buffer->oom = true;
      else
        buffer->error = true;
      ret = -1;
    }
  else
    {
      if (ret <= room)
        {
          /* The result has fit into room bytes.  */
          memmove (buffer->data + buffer->allocated - buffer->length - (size_t) ret,
                   buffer->data,
                   (size_t) ret);
          buffer->length += (size_t) ret;
          ret = 0;
        }
      else
        {
          /* The result was truncated.  Make more room, for a second
             vsnzprintf() call.  */
          if (sbr_ensure_more_bytes (buffer, (size_t) ret) < 0)
            {
              buffer->oom = true;
              errno = ENOMEM;
              ret = -1;
            }
          else
            {
              /* Second vsnzprintf() call.  */
              room = buffer->allocated - buffer->length;
              ret = vsnzprintf (buffer->data, room, formatstring, list_copy);
              if (ret < 0)
                {
                  /* Failed.  errno is set.  */
                  if (errno == ENOMEM)
                    buffer->oom = true;
                  else
                    buffer->error = true;
                  ret = -1;
                }
              else
                {
                  if (ret <= room)
                    {
                      /* The result has fit into room bytes.  */
                      memmove (buffer->data + buffer->allocated - buffer->length - (size_t) ret,
                               buffer->data,
                               (size_t) ret);
                      buffer->length += (size_t) ret;
                      ret = 0;
                    }
                  else
                    /* The return values of the vsnzprintf() calls are not
                       consistent.  */
                    abort ();
                }
            }
        }
    }

  va_end (list_copy);
  return ret;
}

int
sbr_prependf (struct string_buffer_reversed *buffer, const char *formatstring,
              ...)
{

  /* Make a bit of room, so that the probability that the first vsnzprintf()
     call succeeds is high.  */
  size_t room = buffer->allocated - buffer->length;
  if (room < 64)
    {
      if (sbr_ensure_more_bytes (buffer, 64) < 0)
        {
          buffer->oom = true;
          errno = ENOMEM;
          return -1;
        }
      room = buffer->allocated - buffer->length;
    }

  va_list args;
  va_start (args, formatstring);

  /* First vsnzprintf() call.  */
  ptrdiff_t ret = vsnzprintf (buffer->data, room, formatstring, args);
  if (ret < 0)
    {
      /* Failed.  errno is set.  */
      if (errno == ENOMEM)
        buffer->oom = true;
      else
        buffer->error = true;
      ret = -1;
    }
  else
    {
      if (ret <= room)
        {
          /* The result has fit into room bytes.  */
          memmove (buffer->data + buffer->allocated - buffer->length - (size_t) ret,
                   buffer->data,
                   (size_t) ret);
          buffer->length += (size_t) ret;
          ret = 0;
        }
      else
        {
          /* The result was truncated.  Make more room, for a second
             vsnzprintf() call.  */
          if (sbr_ensure_more_bytes (buffer, (size_t) ret) < 0)
            {
              buffer->oom = true;
              errno = ENOMEM;
              ret = -1;
            }
          else
            {
              /* Second vsnzprintf() call.  */
              room = buffer->allocated - buffer->length;
              va_end (args);
              va_start (args, formatstring);
              ret = vsnzprintf (buffer->data, room, formatstring, args);
              if (ret < 0)
                {
                  /* Failed.  errno is set.  */
                  if (errno == ENOMEM)
                    buffer->oom = true;
                  else
                    buffer->error = true;
                  ret = -1;
                }
              else
                {
                  if (ret <= room)
                    {
                      /* The result has fit into room bytes.  */
                      memmove (buffer->data + buffer->allocated - buffer->length - (size_t) ret,
                               buffer->data,
                               (size_t) ret);
                      buffer->length += (size_t) ret;
                      ret = 0;
                    }
                  else
                    /* The return values of the vsnzprintf() calls are not
                       consistent.  */
                    abort ();
                }
            }
        }
    }

  va_end (args);
  return ret;
}
