1 /* Shared general utility routines for GDB, the GNU debugger. 2 3 Copyright (C) 1986-2020 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 #include "common-defs.h" 21 #include "common-utils.h" 22 #include "host-defs.h" 23 #include <ctype.h> 24 25 void * 26 xzalloc (size_t size) 27 { 28 return xcalloc (1, size); 29 } 30 31 /* Like asprintf/vasprintf but get an internal_error if the call 32 fails. */ 33 34 char * 35 xstrprintf (const char *format, ...) 36 { 37 char *ret; 38 va_list args; 39 40 va_start (args, format); 41 ret = xstrvprintf (format, args); 42 va_end (args); 43 return ret; 44 } 45 46 char * 47 xstrvprintf (const char *format, va_list ap) 48 { 49 char *ret = NULL; 50 int status = vasprintf (&ret, format, ap); 51 52 /* NULL is returned when there was a memory allocation problem, or 53 any other error (for instance, a bad format string). A negative 54 status (the printed length) with a non-NULL buffer should never 55 happen, but just to be sure. */ 56 if (ret == NULL || status < 0) 57 internal_error (__FILE__, __LINE__, _("vasprintf call failed")); 58 return ret; 59 } 60 61 int 62 xsnprintf (char *str, size_t size, const char *format, ...) 63 { 64 va_list args; 65 int ret; 66 67 va_start (args, format); 68 ret = vsnprintf (str, size, format, args); 69 gdb_assert (ret < size); 70 va_end (args); 71 72 return ret; 73 } 74 75 /* See documentation in common-utils.h. */ 76 77 std::string 78 string_printf (const char* fmt, ...) 79 { 80 va_list vp; 81 int size; 82 83 va_start (vp, fmt); 84 size = vsnprintf (NULL, 0, fmt, vp); 85 va_end (vp); 86 87 std::string str (size, '\0'); 88 89 /* C++11 and later guarantee std::string uses contiguous memory and 90 always includes the terminating '\0'. */ 91 va_start (vp, fmt); 92 vsprintf (&str[0], fmt, vp); /* ARI: vsprintf */ 93 va_end (vp); 94 95 return str; 96 } 97 98 /* See documentation in common-utils.h. */ 99 100 std::string 101 string_vprintf (const char* fmt, va_list args) 102 { 103 va_list vp; 104 size_t size; 105 106 va_copy (vp, args); 107 size = vsnprintf (NULL, 0, fmt, vp); 108 va_end (vp); 109 110 std::string str (size, '\0'); 111 112 /* C++11 and later guarantee std::string uses contiguous memory and 113 always includes the terminating '\0'. */ 114 vsprintf (&str[0], fmt, args); /* ARI: vsprintf */ 115 116 return str; 117 } 118 119 120 /* See documentation in common-utils.h. */ 121 122 void 123 string_appendf (std::string &str, const char *fmt, ...) 124 { 125 va_list vp; 126 127 va_start (vp, fmt); 128 string_vappendf (str, fmt, vp); 129 va_end (vp); 130 } 131 132 133 /* See documentation in common-utils.h. */ 134 135 void 136 string_vappendf (std::string &str, const char *fmt, va_list args) 137 { 138 va_list vp; 139 int grow_size; 140 141 va_copy (vp, args); 142 grow_size = vsnprintf (NULL, 0, fmt, vp); 143 va_end (vp); 144 145 size_t curr_size = str.size (); 146 str.resize (curr_size + grow_size); 147 148 /* C++11 and later guarantee std::string uses contiguous memory and 149 always includes the terminating '\0'. */ 150 vsprintf (&str[curr_size], fmt, args); /* ARI: vsprintf */ 151 } 152 153 char * 154 savestring (const char *ptr, size_t len) 155 { 156 char *p = (char *) xmalloc (len + 1); 157 158 memcpy (p, ptr, len); 159 p[len] = 0; 160 return p; 161 } 162 163 /* See documentation in common-utils.h. */ 164 165 std::string 166 extract_string_maybe_quoted (const char **arg) 167 { 168 bool squote = false; 169 bool dquote = false; 170 bool bsquote = false; 171 std::string result; 172 const char *p = *arg; 173 174 /* Find the start of the argument. */ 175 p = skip_spaces (p); 176 177 /* Parse p similarly to gdb_argv buildargv function. */ 178 while (*p != '\0') 179 { 180 if (isspace (*p) && !squote && !dquote && !bsquote) 181 break; 182 else 183 { 184 if (bsquote) 185 { 186 bsquote = false; 187 result += *p; 188 } 189 else if (*p == '\\') 190 bsquote = true; 191 else if (squote) 192 { 193 if (*p == '\'') 194 squote = false; 195 else 196 result += *p; 197 } 198 else if (dquote) 199 { 200 if (*p == '"') 201 dquote = false; 202 else 203 result += *p; 204 } 205 else 206 { 207 if (*p == '\'') 208 squote = true; 209 else if (*p == '"') 210 dquote = true; 211 else 212 result += *p; 213 } 214 p++; 215 } 216 } 217 218 *arg = p; 219 return result; 220 } 221 222 /* The bit offset of the highest byte in a ULONGEST, for overflow 223 checking. */ 224 225 #define HIGH_BYTE_POSN ((sizeof (ULONGEST) - 1) * HOST_CHAR_BIT) 226 227 /* True (non-zero) iff DIGIT is a valid digit in radix BASE, 228 where 2 <= BASE <= 36. */ 229 230 static int 231 is_digit_in_base (unsigned char digit, int base) 232 { 233 if (!isalnum (digit)) 234 return 0; 235 if (base <= 10) 236 return (isdigit (digit) && digit < base + '0'); 237 else 238 return (isdigit (digit) || tolower (digit) < base - 10 + 'a'); 239 } 240 241 static int 242 digit_to_int (unsigned char c) 243 { 244 if (isdigit (c)) 245 return c - '0'; 246 else 247 return tolower (c) - 'a' + 10; 248 } 249 250 /* As for strtoul, but for ULONGEST results. */ 251 252 ULONGEST 253 strtoulst (const char *num, const char **trailer, int base) 254 { 255 unsigned int high_part; 256 ULONGEST result; 257 int minus = 0; 258 int i = 0; 259 260 /* Skip leading whitespace. */ 261 while (isspace (num[i])) 262 i++; 263 264 /* Handle prefixes. */ 265 if (num[i] == '+') 266 i++; 267 else if (num[i] == '-') 268 { 269 minus = 1; 270 i++; 271 } 272 273 if (base == 0 || base == 16) 274 { 275 if (num[i] == '0' && (num[i + 1] == 'x' || num[i + 1] == 'X')) 276 { 277 i += 2; 278 if (base == 0) 279 base = 16; 280 } 281 } 282 283 if (base == 0 && num[i] == '0') 284 base = 8; 285 286 if (base == 0) 287 base = 10; 288 289 if (base < 2 || base > 36) 290 { 291 errno = EINVAL; 292 return 0; 293 } 294 295 result = high_part = 0; 296 for (; is_digit_in_base (num[i], base); i += 1) 297 { 298 result = result * base + digit_to_int (num[i]); 299 high_part = high_part * base + (unsigned int) (result >> HIGH_BYTE_POSN); 300 result &= ((ULONGEST) 1 << HIGH_BYTE_POSN) - 1; 301 if (high_part > 0xff) 302 { 303 errno = ERANGE; 304 result = ~ (ULONGEST) 0; 305 high_part = 0; 306 minus = 0; 307 break; 308 } 309 } 310 311 if (trailer != NULL) 312 *trailer = &num[i]; 313 314 result = result + ((ULONGEST) high_part << HIGH_BYTE_POSN); 315 if (minus) 316 return -result; 317 else 318 return result; 319 } 320 321 /* See documentation in common-utils.h. */ 322 323 char * 324 skip_spaces (char *chp) 325 { 326 if (chp == NULL) 327 return NULL; 328 while (*chp && isspace (*chp)) 329 chp++; 330 return chp; 331 } 332 333 /* A const-correct version of the above. */ 334 335 const char * 336 skip_spaces (const char *chp) 337 { 338 if (chp == NULL) 339 return NULL; 340 while (*chp && isspace (*chp)) 341 chp++; 342 return chp; 343 } 344 345 /* See documentation in common-utils.h. */ 346 347 const char * 348 skip_to_space (const char *chp) 349 { 350 if (chp == NULL) 351 return NULL; 352 while (*chp && !isspace (*chp)) 353 chp++; 354 return chp; 355 } 356 357 /* See documentation in common-utils.h. */ 358 359 char * 360 skip_to_space (char *chp) 361 { 362 return (char *) skip_to_space ((const char *) chp); 363 } 364 365 /* See gdbsupport/common-utils.h. */ 366 367 void 368 free_vector_argv (std::vector<char *> &v) 369 { 370 for (char *el : v) 371 xfree (el); 372 373 v.clear (); 374 } 375 376 /* See gdbsupport/common-utils.h. */ 377 378 ULONGEST 379 align_up (ULONGEST v, int n) 380 { 381 /* Check that N is really a power of two. */ 382 gdb_assert (n && (n & (n-1)) == 0); 383 return (v + n - 1) & -n; 384 } 385 386 /* See gdbsupport/common-utils.h. */ 387 388 ULONGEST 389 align_down (ULONGEST v, int n) 390 { 391 /* Check that N is really a power of two. */ 392 gdb_assert (n && (n & (n-1)) == 0); 393 return (v & -n); 394 } 395