Fix building Loongarch BFD with a 32-bit compiler
[binutils-gdb.git] / gdbsupport / common-utils.cc
blob91c14a0f139fb71dc96c111126f15828b7b76c07
1 /* Shared general utility routines for GDB, the GNU debugger.
3 Copyright (C) 1986-2024 Free Software Foundation, Inc.
5 This file is part of GDB.
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.
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.
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/>. */
20 #include "common-utils.h"
21 #include "host-defs.h"
22 #include "gdbsupport/gdb-safe-ctype.h"
23 #include "gdbsupport/gdb-xfree.h"
25 void *
26 xzalloc (size_t size)
28 return xcalloc (1, size);
31 /* Like asprintf/vasprintf but get an internal_error if the call
32 fails. */
34 gdb::unique_xmalloc_ptr<char>
35 xstrprintf (const char *format, ...)
37 va_list args;
39 va_start (args, format);
40 gdb::unique_xmalloc_ptr<char> ret = xstrvprintf (format, args);
41 va_end (args);
42 return ret;
45 gdb::unique_xmalloc_ptr<char>
46 xstrvprintf (const char *format, va_list ap)
48 char *ret = NULL;
49 int status = vasprintf (&ret, format, ap);
51 /* NULL is returned when there was a memory allocation problem, or
52 any other error (for instance, a bad format string). A negative
53 status (the printed length) with a non-NULL buffer should never
54 happen, but just to be sure. */
55 if (ret == NULL || status < 0)
56 internal_error (_("vasprintf call failed"));
57 return gdb::unique_xmalloc_ptr<char> (ret);
60 int
61 xsnprintf (char *str, size_t size, const char *format, ...)
63 va_list args;
64 int ret;
66 va_start (args, format);
67 ret = vsnprintf (str, size, format, args);
68 gdb_assert (ret < size);
69 va_end (args);
71 return ret;
74 /* See documentation in common-utils.h. */
76 std::string
77 string_printf (const char* fmt, ...)
79 va_list vp;
80 int size;
82 va_start (vp, fmt);
83 size = vsnprintf (NULL, 0, fmt, vp);
84 va_end (vp);
86 std::string str (size, '\0');
88 /* C++11 and later guarantee std::string uses contiguous memory and
89 always includes the terminating '\0'. */
90 va_start (vp, fmt);
91 vsprintf (&str[0], fmt, vp); /* ARI: vsprintf */
92 va_end (vp);
94 return str;
97 /* See documentation in common-utils.h. */
99 std::string
100 string_vprintf (const char* fmt, va_list args)
102 va_list vp;
103 size_t size;
105 va_copy (vp, args);
106 size = vsnprintf (NULL, 0, fmt, vp);
107 va_end (vp);
109 std::string str (size, '\0');
111 /* C++11 and later guarantee std::string uses contiguous memory and
112 always includes the terminating '\0'. */
113 vsprintf (&str[0], fmt, args); /* ARI: vsprintf */
115 return str;
119 /* See documentation in common-utils.h. */
121 std::string &
122 string_appendf (std::string &str, const char *fmt, ...)
124 va_list vp;
126 va_start (vp, fmt);
127 string_vappendf (str, fmt, vp);
128 va_end (vp);
130 return str;
134 /* See documentation in common-utils.h. */
136 std::string &
137 string_vappendf (std::string &str, const char *fmt, va_list args)
139 va_list vp;
140 int grow_size;
142 va_copy (vp, args);
143 grow_size = vsnprintf (NULL, 0, fmt, vp);
144 va_end (vp);
146 size_t curr_size = str.size ();
147 str.resize (curr_size + grow_size);
149 /* C++11 and later guarantee std::string uses contiguous memory and
150 always includes the terminating '\0'. */
151 vsprintf (&str[curr_size], fmt, args); /* ARI: vsprintf */
153 return str;
156 char *
157 savestring (const char *ptr, size_t len)
159 char *p = (char *) xmalloc (len + 1);
161 memcpy (p, ptr, len);
162 p[len] = 0;
163 return p;
166 /* See documentation in common-utils.h. */
168 std::string
169 extract_string_maybe_quoted (const char **arg)
171 bool squote = false;
172 bool dquote = false;
173 bool bsquote = false;
174 std::string result;
175 const char *p = *arg;
177 /* Find the start of the argument. */
178 p = skip_spaces (p);
180 /* Parse p similarly to gdb_argv buildargv function. */
181 while (*p != '\0')
183 if (ISSPACE (*p) && !squote && !dquote && !bsquote)
184 break;
185 else
187 if (bsquote)
189 bsquote = false;
190 result += *p;
192 else if (*p == '\\')
193 bsquote = true;
194 else if (squote)
196 if (*p == '\'')
197 squote = false;
198 else
199 result += *p;
201 else if (dquote)
203 if (*p == '"')
204 dquote = false;
205 else
206 result += *p;
208 else
210 if (*p == '\'')
211 squote = true;
212 else if (*p == '"')
213 dquote = true;
214 else
215 result += *p;
217 p++;
221 *arg = p;
222 return result;
225 /* The bit offset of the highest byte in a ULONGEST, for overflow
226 checking. */
228 #define HIGH_BYTE_POSN ((sizeof (ULONGEST) - 1) * HOST_CHAR_BIT)
230 /* True (non-zero) iff DIGIT is a valid digit in radix BASE,
231 where 2 <= BASE <= 36. */
233 static int
234 is_digit_in_base (unsigned char digit, int base)
236 if (!ISALNUM (digit))
237 return 0;
238 if (base <= 10)
239 return (ISDIGIT (digit) && digit < base + '0');
240 else
241 return (ISDIGIT (digit) || TOLOWER (digit) < base - 10 + 'a');
244 static int
245 digit_to_int (unsigned char c)
247 if (ISDIGIT (c))
248 return c - '0';
249 else
250 return TOLOWER (c) - 'a' + 10;
253 /* As for strtoul, but for ULONGEST results. */
255 ULONGEST
256 strtoulst (const char *num, const char **trailer, int base)
258 unsigned int high_part;
259 ULONGEST result;
260 int minus = 0;
261 int i = 0;
263 /* Skip leading whitespace. */
264 while (ISSPACE (num[i]))
265 i++;
267 /* Handle prefixes. */
268 if (num[i] == '+')
269 i++;
270 else if (num[i] == '-')
272 minus = 1;
273 i++;
276 if (base == 0 || base == 16)
278 if (num[i] == '0' && (num[i + 1] == 'x' || num[i + 1] == 'X'))
280 i += 2;
281 if (base == 0)
282 base = 16;
286 if (base == 0 && num[i] == '0')
287 base = 8;
289 if (base == 0)
290 base = 10;
292 if (base < 2 || base > 36)
294 errno = EINVAL;
295 return 0;
298 result = high_part = 0;
299 for (; is_digit_in_base (num[i], base); i += 1)
301 result = result * base + digit_to_int (num[i]);
302 high_part = high_part * base + (unsigned int) (result >> HIGH_BYTE_POSN);
303 result &= ((ULONGEST) 1 << HIGH_BYTE_POSN) - 1;
304 if (high_part > 0xff)
306 errno = ERANGE;
307 result = ~ (ULONGEST) 0;
308 high_part = 0;
309 minus = 0;
310 break;
314 if (trailer != NULL)
315 *trailer = &num[i];
317 result = result + ((ULONGEST) high_part << HIGH_BYTE_POSN);
318 if (minus)
319 return -result;
320 else
321 return result;
324 /* See documentation in common-utils.h. */
326 char *
327 skip_spaces (char *chp)
329 if (chp == NULL)
330 return NULL;
331 while (*chp && ISSPACE (*chp))
332 chp++;
333 return chp;
336 /* A const-correct version of the above. */
338 const char *
339 skip_spaces (const char *chp)
341 if (chp == NULL)
342 return NULL;
343 while (*chp && ISSPACE (*chp))
344 chp++;
345 return chp;
348 /* See documentation in common-utils.h. */
350 const char *
351 skip_to_space (const char *chp)
353 if (chp == NULL)
354 return NULL;
355 while (*chp && !ISSPACE (*chp))
356 chp++;
357 return chp;
360 /* See documentation in common-utils.h. */
362 char *
363 skip_to_space (char *chp)
365 return (char *) skip_to_space ((const char *) chp);
368 /* See gdbsupport/common-utils.h. */
370 void
371 free_vector_argv (std::vector<char *> &v)
373 for (char *el : v)
374 xfree (el);
376 v.clear ();
379 /* See gdbsupport/common-utils.h. */
381 ULONGEST
382 align_up (ULONGEST v, int n)
384 /* Check that N is really a power of two. */
385 gdb_assert (n && (n & (n-1)) == 0);
386 return (v + n - 1) & -n;
389 /* See gdbsupport/common-utils.h. */
391 ULONGEST
392 align_down (ULONGEST v, int n)
394 /* Check that N is really a power of two. */
395 gdb_assert (n && (n & (n-1)) == 0);
396 return (v & -n);
399 /* See gdbsupport/common-utils.h. */
402 fromhex (int a)
404 if (a >= '0' && a <= '9')
405 return a - '0';
406 else if (a >= 'a' && a <= 'f')
407 return a - 'a' + 10;
408 else if (a >= 'A' && a <= 'F')
409 return a - 'A' + 10;
410 else
411 error (_("Invalid hex digit %d"), a);
414 /* See gdbsupport/common-utils.h. */
417 hex2bin (const char *hex, gdb_byte *bin, int count)
419 int i;
421 for (i = 0; i < count; i++)
423 if (hex[0] == 0 || hex[1] == 0)
425 /* Hex string is short, or of uneven length.
426 Return the count that has been converted so far. */
427 return i;
429 *bin++ = fromhex (hex[0]) * 16 + fromhex (hex[1]);
430 hex += 2;
432 return i;
435 /* See gdbsupport/common-utils.h. */
437 gdb::byte_vector
438 hex2bin (const char *hex)
440 size_t bin_len = strlen (hex) / 2;
441 gdb::byte_vector bin (bin_len);
443 hex2bin (hex, bin.data (), bin_len);
445 return bin;
448 /* See gdbsupport/common-utils.h. */
450 std::string
451 bytes_to_string (gdb::array_view<const gdb_byte> bytes)
453 std::string ret;
455 for (size_t i = 0; i < bytes.size (); i++)
457 if (i == 0)
458 ret += string_printf ("%02x", bytes[i]);
459 else
460 ret += string_printf (" %02x", bytes[i]);
463 return ret;