]> Git Repo - binutils.git/blob - gdbsupport/common-utils.cc
Automatic date update in version.in
[binutils.git] / gdbsupport / common-utils.cc
1 /* Shared general utility routines for GDB, the GNU debugger.
2
3    Copyright (C) 1986-2022 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 "safe-ctype.h"
24 #include "gdbsupport/gdb-xfree.h"
25
26 void *
27 xzalloc (size_t size)
28 {
29   return xcalloc (1, size);
30 }
31
32 /* Like asprintf/vasprintf but get an internal_error if the call
33    fails. */
34
35 gdb::unique_xmalloc_ptr<char>
36 xstrprintf (const char *format, ...)
37 {
38   va_list args;
39
40   va_start (args, format);
41   gdb::unique_xmalloc_ptr<char> ret = xstrvprintf (format, args);
42   va_end (args);
43   return ret;
44 }
45
46 gdb::unique_xmalloc_ptr<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 (_("vasprintf call failed"));
58   return gdb::unique_xmalloc_ptr<char> (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 std::string &
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   return str;
132 }
133
134
135 /* See documentation in common-utils.h.  */
136
137 std::string &
138 string_vappendf (std::string &str, const char *fmt, va_list args)
139 {
140   va_list vp;
141   int grow_size;
142
143   va_copy (vp, args);
144   grow_size = vsnprintf (NULL, 0, fmt, vp);
145   va_end (vp);
146
147   size_t curr_size = str.size ();
148   str.resize (curr_size + grow_size);
149
150   /* C++11 and later guarantee std::string uses contiguous memory and
151      always includes the terminating '\0'.  */
152   vsprintf (&str[curr_size], fmt, args); /* ARI: vsprintf */
153
154   return str;
155 }
156
157 char *
158 savestring (const char *ptr, size_t len)
159 {
160   char *p = (char *) xmalloc (len + 1);
161
162   memcpy (p, ptr, len);
163   p[len] = 0;
164   return p;
165 }
166
167 /* See documentation in common-utils.h.  */
168
169 std::string
170 extract_string_maybe_quoted (const char **arg)
171 {
172   bool squote = false;
173   bool dquote = false;
174   bool bsquote = false;
175   std::string result;
176   const char *p = *arg;
177
178   /* Find the start of the argument.  */
179   p = skip_spaces (p);
180
181   /* Parse p similarly to gdb_argv buildargv function.  */
182   while (*p != '\0')
183     {
184       if (ISSPACE (*p) && !squote && !dquote && !bsquote)
185         break;
186       else
187         {
188           if (bsquote)
189             {
190               bsquote = false;
191               result += *p;
192             }
193           else if (*p == '\\')
194             bsquote = true;
195           else if (squote)
196             {
197               if (*p == '\'')
198                 squote = false;
199               else
200                 result += *p;
201             }
202           else if (dquote)
203             {
204               if (*p == '"')
205                 dquote = false;
206               else
207                 result += *p;
208             }
209           else
210             {
211               if (*p == '\'')
212                 squote = true;
213               else if (*p == '"')
214                 dquote = true;
215               else
216                 result += *p;
217             }
218           p++;
219         }
220     }
221
222   *arg = p;
223   return result;
224 }
225
226 /* The bit offset of the highest byte in a ULONGEST, for overflow
227    checking.  */
228
229 #define HIGH_BYTE_POSN ((sizeof (ULONGEST) - 1) * HOST_CHAR_BIT)
230
231 /* True (non-zero) iff DIGIT is a valid digit in radix BASE,
232    where 2 <= BASE <= 36.  */
233
234 static int
235 is_digit_in_base (unsigned char digit, int base)
236 {
237   if (!ISALNUM (digit))
238     return 0;
239   if (base <= 10)
240     return (ISDIGIT (digit) && digit < base + '0');
241   else
242     return (ISDIGIT (digit) || TOLOWER (digit) < base - 10 + 'a');
243 }
244
245 static int
246 digit_to_int (unsigned char c)
247 {
248   if (ISDIGIT (c))
249     return c - '0';
250   else
251     return TOLOWER (c) - 'a' + 10;
252 }
253
254 /* As for strtoul, but for ULONGEST results.  */
255
256 ULONGEST
257 strtoulst (const char *num, const char **trailer, int base)
258 {
259   unsigned int high_part;
260   ULONGEST result;
261   int minus = 0;
262   int i = 0;
263
264   /* Skip leading whitespace.  */
265   while (ISSPACE (num[i]))
266     i++;
267
268   /* Handle prefixes.  */
269   if (num[i] == '+')
270     i++;
271   else if (num[i] == '-')
272     {
273       minus = 1;
274       i++;
275     }
276
277   if (base == 0 || base == 16)
278     {
279       if (num[i] == '0' && (num[i + 1] == 'x' || num[i + 1] == 'X'))
280         {
281           i += 2;
282           if (base == 0)
283             base = 16;
284         }
285     }
286
287   if (base == 0 && num[i] == '0')
288     base = 8;
289
290   if (base == 0)
291     base = 10;
292
293   if (base < 2 || base > 36)
294     {
295       errno = EINVAL;
296       return 0;
297     }
298
299   result = high_part = 0;
300   for (; is_digit_in_base (num[i], base); i += 1)
301     {
302       result = result * base + digit_to_int (num[i]);
303       high_part = high_part * base + (unsigned int) (result >> HIGH_BYTE_POSN);
304       result &= ((ULONGEST) 1 << HIGH_BYTE_POSN) - 1;
305       if (high_part > 0xff)
306         {
307           errno = ERANGE;
308           result = ~ (ULONGEST) 0;
309           high_part = 0;
310           minus = 0;
311           break;
312         }
313     }
314
315   if (trailer != NULL)
316     *trailer = &num[i];
317
318   result = result + ((ULONGEST) high_part << HIGH_BYTE_POSN);
319   if (minus)
320     return -result;
321   else
322     return result;
323 }
324
325 /* See documentation in common-utils.h.  */
326
327 char *
328 skip_spaces (char *chp)
329 {
330   if (chp == NULL)
331     return NULL;
332   while (*chp && ISSPACE (*chp))
333     chp++;
334   return chp;
335 }
336
337 /* A const-correct version of the above.  */
338
339 const char *
340 skip_spaces (const char *chp)
341 {
342   if (chp == NULL)
343     return NULL;
344   while (*chp && ISSPACE (*chp))
345     chp++;
346   return chp;
347 }
348
349 /* See documentation in common-utils.h.  */
350
351 const char *
352 skip_to_space (const char *chp)
353 {
354   if (chp == NULL)
355     return NULL;
356   while (*chp && !ISSPACE (*chp))
357     chp++;
358   return chp;
359 }
360
361 /* See documentation in common-utils.h.  */
362
363 char *
364 skip_to_space (char *chp)
365 {
366   return (char *) skip_to_space ((const char *) chp);
367 }
368
369 /* See gdbsupport/common-utils.h.  */
370
371 void
372 free_vector_argv (std::vector<char *> &v)
373 {
374   for (char *el : v)
375     xfree (el);
376
377   v.clear ();
378 }
379
380 /* See gdbsupport/common-utils.h.  */
381
382 ULONGEST
383 align_up (ULONGEST v, int n)
384 {
385   /* Check that N is really a power of two.  */
386   gdb_assert (n && (n & (n-1)) == 0);
387   return (v + n - 1) & -n;
388 }
389
390 /* See gdbsupport/common-utils.h.  */
391
392 ULONGEST
393 align_down (ULONGEST v, int n)
394 {
395   /* Check that N is really a power of two.  */
396   gdb_assert (n && (n & (n-1)) == 0);
397   return (v & -n);
398 }
399
400 /* See gdbsupport/common-utils.h.  */
401
402 int
403 fromhex (int a)
404 {
405   if (a >= '0' && a <= '9')
406     return a - '0';
407   else if (a >= 'a' && a <= 'f')
408     return a - 'a' + 10;
409   else if (a >= 'A' && a <= 'F')
410     return a - 'A' + 10;
411   else
412     error (_("Invalid hex digit %d"), a);
413 }
414
415 /* See gdbsupport/common-utils.h.  */
416
417 int
418 hex2bin (const char *hex, gdb_byte *bin, int count)
419 {
420   int i;
421
422   for (i = 0; i < count; i++)
423     {
424       if (hex[0] == 0 || hex[1] == 0)
425         {
426           /* Hex string is short, or of uneven length.
427              Return the count that has been converted so far.  */
428           return i;
429         }
430       *bin++ = fromhex (hex[0]) * 16 + fromhex (hex[1]);
431       hex += 2;
432     }
433   return i;
434 }
435
436 /* See gdbsupport/common-utils.h.  */
437
438 gdb::byte_vector
439 hex2bin (const char *hex)
440 {
441   size_t bin_len = strlen (hex) / 2;
442   gdb::byte_vector bin (bin_len);
443
444   hex2bin (hex, bin.data (), bin_len);
445
446   return bin;
447 }
This page took 0.049972 seconds and 4 git commands to generate.