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