/* RAII wrapper for buildargv

   Copyright (C) 2021-2025 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 */
