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