Home | History | Annotate | Line # | Download | only in gdbsupport
      1      1.1  christos /* RAII wrapper for buildargv
      2      1.1  christos 
      3  1.1.1.2  christos    Copyright (C) 2021-2024 Free Software Foundation, Inc.
      4      1.1  christos 
      5      1.1  christos    This file is part of GDB.
      6      1.1  christos 
      7      1.1  christos    This program is free software; you can redistribute it and/or modify
      8      1.1  christos    it under the terms of the GNU General Public License as published by
      9      1.1  christos    the Free Software Foundation; either version 3 of the License, or
     10      1.1  christos    (at your option) any later version.
     11      1.1  christos 
     12      1.1  christos    This program is distributed in the hope that it will be useful,
     13      1.1  christos    but WITHOUT ANY WARRANTY; without even the implied warranty of
     14      1.1  christos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15      1.1  christos    GNU General Public License for more details.
     16      1.1  christos 
     17      1.1  christos    You should have received a copy of the GNU General Public License
     18      1.1  christos    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
     19      1.1  christos 
     20      1.1  christos #ifndef GDBSUPPORT_BUILDARGV_H
     21      1.1  christos #define GDBSUPPORT_BUILDARGV_H
     22      1.1  christos 
     23      1.1  christos #include "libiberty.h"
     24      1.1  christos 
     25      1.1  christos /* A wrapper for an array of char* that was allocated in the way that
     26      1.1  christos    'buildargv' does, and should be freed with 'freeargv'.  */
     27      1.1  christos 
     28      1.1  christos class gdb_argv
     29      1.1  christos {
     30      1.1  christos public:
     31      1.1  christos 
     32      1.1  christos   /* A constructor that initializes to NULL.  */
     33      1.1  christos 
     34      1.1  christos   gdb_argv ()
     35      1.1  christos     : m_argv (NULL)
     36      1.1  christos   {
     37      1.1  christos   }
     38      1.1  christos 
     39      1.1  christos   /* A constructor that calls buildargv on STR.  STR may be NULL, in
     40      1.1  christos      which case this object is initialized with a NULL array.  */
     41      1.1  christos 
     42      1.1  christos   explicit gdb_argv (const char *str)
     43      1.1  christos     : m_argv (NULL)
     44      1.1  christos   {
     45      1.1  christos     reset (str);
     46      1.1  christos   }
     47      1.1  christos 
     48      1.1  christos   /* A constructor that takes ownership of an existing array.  */
     49      1.1  christos 
     50      1.1  christos   explicit gdb_argv (char **array)
     51      1.1  christos     : m_argv (array)
     52      1.1  christos   {
     53      1.1  christos   }
     54      1.1  christos 
     55      1.1  christos   gdb_argv (const gdb_argv &) = delete;
     56      1.1  christos   gdb_argv &operator= (const gdb_argv &) = delete;
     57      1.1  christos 
     58      1.1  christos   gdb_argv &operator= (gdb_argv &&other)
     59      1.1  christos   {
     60      1.1  christos     freeargv (m_argv);
     61      1.1  christos     m_argv = other.m_argv;
     62      1.1  christos     other.m_argv = nullptr;
     63      1.1  christos     return *this;
     64      1.1  christos   }
     65      1.1  christos 
     66      1.1  christos   gdb_argv (gdb_argv &&other)
     67      1.1  christos   {
     68      1.1  christos     m_argv = other.m_argv;
     69      1.1  christos     other.m_argv = nullptr;
     70      1.1  christos   }
     71      1.1  christos 
     72      1.1  christos   ~gdb_argv ()
     73      1.1  christos   {
     74      1.1  christos     freeargv (m_argv);
     75      1.1  christos   }
     76      1.1  christos 
     77      1.1  christos   /* Call buildargv on STR, storing the result in this object.  Any
     78      1.1  christos      previous state is freed.  STR may be NULL, in which case this
     79      1.1  christos      object is reset with a NULL array.  If buildargv fails due to
     80      1.1  christos      out-of-memory, call malloc_failure.  Therefore, the value is
     81      1.1  christos      guaranteed to be non-NULL, unless the parameter itself is
     82      1.1  christos      NULL.  */
     83      1.1  christos 
     84      1.1  christos   void reset (const char *str)
     85      1.1  christos   {
     86      1.1  christos     char **argv = buildargv (str);
     87      1.1  christos     freeargv (m_argv);
     88      1.1  christos     m_argv = argv;
     89      1.1  christos   }
     90      1.1  christos 
     91      1.1  christos   /* Return the underlying array.  */
     92      1.1  christos 
     93      1.1  christos   char **get ()
     94      1.1  christos   {
     95      1.1  christos     return m_argv;
     96      1.1  christos   }
     97      1.1  christos 
     98      1.1  christos   const char * const * get () const
     99      1.1  christos   {
    100      1.1  christos     return m_argv;
    101      1.1  christos   }
    102      1.1  christos 
    103      1.1  christos   /* Return the underlying array, transferring ownership to the
    104      1.1  christos      caller.  */
    105      1.1  christos 
    106      1.1  christos   ATTRIBUTE_UNUSED_RESULT char **release ()
    107      1.1  christos   {
    108      1.1  christos     char **result = m_argv;
    109      1.1  christos     m_argv = NULL;
    110      1.1  christos     return result;
    111      1.1  christos   }
    112      1.1  christos 
    113      1.1  christos   /* Return the number of items in the array.  */
    114      1.1  christos 
    115      1.1  christos   int count () const
    116      1.1  christos   {
    117      1.1  christos     return countargv (m_argv);
    118      1.1  christos   }
    119      1.1  christos 
    120      1.1  christos   /* Index into the array.  */
    121      1.1  christos 
    122      1.1  christos   char *operator[] (int arg)
    123      1.1  christos   {
    124      1.1  christos     gdb_assert (m_argv != NULL);
    125      1.1  christos     return m_argv[arg];
    126      1.1  christos   }
    127      1.1  christos 
    128      1.1  christos   /* Return the arguments array as an array view.  */
    129      1.1  christos 
    130      1.1  christos   gdb::array_view<char *> as_array_view ()
    131      1.1  christos   {
    132      1.1  christos     return gdb::array_view<char *> (this->get (), this->count ());
    133      1.1  christos   }
    134      1.1  christos 
    135      1.1  christos   gdb::array_view<const char * const> as_array_view () const
    136      1.1  christos   {
    137      1.1  christos     return gdb::array_view<const char * const> (this->get (), this->count ());
    138      1.1  christos   }
    139      1.1  christos 
    140      1.1  christos   /* Append arguments to this array.  */
    141      1.1  christos   void append (gdb_argv &&other)
    142      1.1  christos   {
    143      1.1  christos     int size = count ();
    144      1.1  christos     int argc = other.count ();
    145      1.1  christos     m_argv = XRESIZEVEC (char *, m_argv, (size + argc + 1));
    146      1.1  christos 
    147      1.1  christos     for (int argi = 0; argi < argc; argi++)
    148      1.1  christos       {
    149      1.1  christos 	/* Transfer ownership of the string.  */
    150      1.1  christos 	m_argv[size++] = other.m_argv[argi];
    151      1.1  christos 	/* Ensure that destruction of OTHER works correctly.  */
    152      1.1  christos 	other.m_argv[argi] = nullptr;
    153      1.1  christos       }
    154      1.1  christos     m_argv[size] = nullptr;
    155      1.1  christos   }
    156      1.1  christos 
    157      1.1  christos   /* Append arguments to this array.  */
    158      1.1  christos   void append (const gdb_argv &other)
    159      1.1  christos   {
    160      1.1  christos     int size = count ();
    161      1.1  christos     int argc = other.count ();
    162      1.1  christos     m_argv = XRESIZEVEC (char *, m_argv, (size + argc + 1));
    163      1.1  christos 
    164      1.1  christos     for (int argi = 0; argi < argc; argi++)
    165      1.1  christos       m_argv[size++] = xstrdup (other.m_argv[argi]);
    166      1.1  christos     m_argv[size] = nullptr;
    167      1.1  christos   }
    168      1.1  christos 
    169      1.1  christos   /* The iterator type.  */
    170      1.1  christos 
    171      1.1  christos   typedef char **iterator;
    172      1.1  christos 
    173      1.1  christos   /* Return an iterator pointing to the start of the array.  */
    174      1.1  christos 
    175      1.1  christos   iterator begin ()
    176      1.1  christos   {
    177      1.1  christos     return m_argv;
    178      1.1  christos   }
    179      1.1  christos 
    180      1.1  christos   /* Return an iterator pointing to the end of the array.  */
    181      1.1  christos 
    182      1.1  christos   iterator end ()
    183      1.1  christos   {
    184      1.1  christos     return m_argv + count ();
    185      1.1  christos   }
    186      1.1  christos 
    187      1.1  christos   bool operator!= (std::nullptr_t)
    188      1.1  christos   {
    189      1.1  christos     return m_argv != NULL;
    190      1.1  christos   }
    191      1.1  christos 
    192      1.1  christos   bool operator== (std::nullptr_t)
    193      1.1  christos   {
    194      1.1  christos     return m_argv == NULL;
    195      1.1  christos   }
    196      1.1  christos 
    197      1.1  christos private:
    198      1.1  christos 
    199      1.1  christos   /* The wrapped array.  */
    200      1.1  christos 
    201      1.1  christos   char **m_argv;
    202      1.1  christos };
    203      1.1  christos 
    204      1.1  christos #endif /* GDBSUPPORT_BUILDARGV_H */
    205