/* RAII wrapper for buildargv

   Copyright (C) 2021 Free Software Foundation, Inc.

   This file is part of GDB.

   This program 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 3 of the License, or
   (at your option) any later version.

   This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.  */

#ifndef GDBSUPPORT_BUILDARGV_H
#define GDBSUPPORT_BUILDARGV_H

#include "libiberty.h"

/* A wrapper for an array of char* that was allocated in the way that
   'buildargv' does, and should be freed with 'freeargv'.  */

class gdb_argv
{
public:

  /* A constructor that initializes to NULL.  */

  gdb_argv ()
    : m_argv (NULL)
  {
  }

  /* A constructor that calls buildargv on STR.  STR may be NULL, in
     which case this object is initialized with a NULL array.  */

  explicit gdb_argv (const char *str)
    : m_argv (NULL)
  {
    reset (str);
  }

  /* A constructor that takes ownership of an existing array.  */

  explicit gdb_argv (char **array)
    : m_argv (array)
  {
  }

  gdb_argv (const gdb_argv &) = delete;
  gdb_argv &operator= (const gdb_argv &) = delete;

  gdb_argv &operator= (gdb_argv &&other)
  {
    freeargv (m_argv);
    m_argv = other.m_argv;
    other.m_argv = nullptr;
    return *this;
  }

  gdb_argv (gdb_argv &&other)
  {
    m_argv = other.m_argv;
    other.m_argv = nullptr;
  }

  ~gdb_argv ()
  {
    freeargv (m_argv);
  }

  /* Call buildargv on STR, storing the result in this object.  Any
     previous state is freed.  STR may be NULL, in which case this
     object is reset with a NULL array.  If buildargv fails due to
     out-of-memory, call malloc_failure.  Therefore, the value is
     guaranteed to be non-NULL, unless the parameter itself is
     NULL.  */

  void reset (const char *str)
  {
    char **argv = buildargv (str);
    freeargv (m_argv);
    m_argv = argv;
  }

  /* Return the underlying array.  */

  char **get ()
  {
    return m_argv;
  }

  const char * const * get () const
  {
    return m_argv;
  }

  /* Return the underlying array, transferring ownership to the
     caller.  */

  ATTRIBUTE_UNUSED_RESULT char **release ()
  {
    char **result = m_argv;
    m_argv = NULL;
    return result;
  }

  /* Return the number of items in the array.  */

  int count () const
  {
    return countargv (m_argv);
  }

  /* Index into the array.  */

  char *operator[] (int arg)
  {
    gdb_assert (m_argv != NULL);
    return m_argv[arg];
  }

  /* Return the arguments array as an array view.  */

  gdb::array_view<char *> as_array_view ()
  {
    return gdb::array_view<char *> (this->get (), this->count ());
  }

  gdb::array_view<const char * const> as_array_view () const
  {
    return gdb::array_view<const char * const> (this->get (), this->count ());
  }

  /* Append arguments to this array.  */
  void append (gdb_argv &&other)
  {
    int size = count ();
    int argc = other.count ();
    m_argv = XRESIZEVEC (char *, m_argv, (size + argc + 1));

    for (int argi = 0; argi < argc; argi++)
      {
	/* Transfer ownership of the string.  */
	m_argv[size++] = other.m_argv[argi];
	/* Ensure that destruction of OTHER works correctly.  */
	other.m_argv[argi] = nullptr;
      }
    m_argv[size] = nullptr;
  }

  /* Append arguments to this array.  */
  void append (const gdb_argv &other)
  {
    int size = count ();
    int argc = other.count ();
    m_argv = XRESIZEVEC (char *, m_argv, (size + argc + 1));

    for (int argi = 0; argi < argc; argi++)
      m_argv[size++] = xstrdup (other.m_argv[argi]);
    m_argv[size] = nullptr;
  }

  /* The iterator type.  */

  typedef char **iterator;

  /* Return an iterator pointing to the start of the array.  */

  iterator begin ()
  {
    return m_argv;
  }

  /* Return an iterator pointing to the end of the array.  */

  iterator end ()
  {
    return m_argv + count ();
  }

  bool operator!= (std::nullptr_t)
  {
    return m_argv != NULL;
  }

  bool operator== (std::nullptr_t)
  {
    return m_argv == NULL;
  }

private:

  /* The wrapped array.  */

  char **m_argv;
};

#endif /* GDBSUPPORT_BUILDARGV_H */
