Automatic date update in version.in
[binutils-gdb.git] / gdbsupport / print-utils.cc
bloba2e43576a7cdaef84de24f967775a30351cf72e5
1 /* Cell-based print 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 "print-utils.h"
21 /* Temporary storage using circular buffer. */
23 /* Number of cells in the circular buffer. */
24 #define NUMCELLS 16
26 /* Return the next entry in the circular buffer. */
28 char *
29 get_print_cell (void)
31 static char buf[NUMCELLS][PRINT_CELL_SIZE];
32 static int cell = 0;
34 if (++cell >= NUMCELLS)
35 cell = 0;
36 return buf[cell];
39 static char *
40 decimal2str (const char *sign, ULONGEST addr, int width)
42 /* Steal code from valprint.c:print_decimal(). Should this worry
43 about the real size of addr as the above does? */
44 unsigned long temp[3];
45 char *str = get_print_cell ();
46 int i = 0;
50 temp[i] = addr % (1000 * 1000 * 1000);
51 addr /= (1000 * 1000 * 1000);
52 i++;
53 width -= 9;
55 while (addr != 0 && i < (sizeof (temp) / sizeof (temp[0])));
57 width += 9;
58 if (width < 0)
59 width = 0;
61 switch (i)
63 case 1:
64 xsnprintf (str, PRINT_CELL_SIZE, "%s%0*lu", sign, width, temp[0]);
65 break;
66 case 2:
67 xsnprintf (str, PRINT_CELL_SIZE, "%s%0*lu%09lu", sign, width,
68 temp[1], temp[0]);
69 break;
70 case 3:
71 xsnprintf (str, PRINT_CELL_SIZE, "%s%0*lu%09lu%09lu", sign, width,
72 temp[2], temp[1], temp[0]);
73 break;
74 default:
75 internal_error (_("failed internal consistency check"));
78 return str;
81 static char *
82 octal2str (ULONGEST addr, int width)
84 unsigned long temp[3];
85 char *str = get_print_cell ();
86 int i = 0;
90 temp[i] = addr % (0100000 * 0100000);
91 addr /= (0100000 * 0100000);
92 i++;
93 width -= 10;
95 while (addr != 0 && i < (sizeof (temp) / sizeof (temp[0])));
97 width += 10;
98 if (width < 0)
99 width = 0;
101 switch (i)
103 case 1:
104 if (temp[0] == 0)
105 xsnprintf (str, PRINT_CELL_SIZE, "%*o", width, 0);
106 else
107 xsnprintf (str, PRINT_CELL_SIZE, "0%0*lo", width, temp[0]);
108 break;
109 case 2:
110 xsnprintf (str, PRINT_CELL_SIZE, "0%0*lo%010lo", width, temp[1], temp[0]);
111 break;
112 case 3:
113 xsnprintf (str, PRINT_CELL_SIZE, "0%0*lo%010lo%010lo", width,
114 temp[2], temp[1], temp[0]);
115 break;
116 default:
117 internal_error (_("failed internal consistency check"));
120 return str;
123 /* See print-utils.h. */
125 const char *
126 pulongest (ULONGEST u)
128 return decimal2str ("", u, 0);
131 /* See print-utils.h. */
133 const char *
134 plongest (LONGEST l)
136 if (l < 0)
137 return decimal2str ("-", -l, 0);
138 else
139 return decimal2str ("", l, 0);
142 /* Eliminate warning from compiler on 32-bit systems. */
143 static int thirty_two = 32;
145 /* See print-utils.h. */
147 const char *
148 phex (ULONGEST l, int sizeof_l)
150 char *str;
152 switch (sizeof_l)
154 case 8:
155 str = get_print_cell ();
156 xsnprintf (str, PRINT_CELL_SIZE, "%08lx%08lx",
157 (unsigned long) (l >> thirty_two),
158 (unsigned long) (l & 0xffffffff));
159 break;
160 case 4:
161 str = get_print_cell ();
162 xsnprintf (str, PRINT_CELL_SIZE, "%08lx", (unsigned long) l);
163 break;
164 case 2:
165 str = get_print_cell ();
166 xsnprintf (str, PRINT_CELL_SIZE, "%04x", (unsigned short) (l & 0xffff));
167 break;
168 case 1:
169 str = get_print_cell ();
170 xsnprintf (str, PRINT_CELL_SIZE, "%02x", (unsigned short) (l & 0xff));
171 break;
172 default:
173 return phex (l, sizeof (l));
174 break;
177 return str;
180 /* See print-utils.h. */
182 const char *
183 phex_nz (ULONGEST l, int sizeof_l)
185 char *str;
187 switch (sizeof_l)
189 case 8:
191 unsigned long high = (unsigned long) (l >> thirty_two);
193 str = get_print_cell ();
194 if (high == 0)
195 xsnprintf (str, PRINT_CELL_SIZE, "%lx",
196 (unsigned long) (l & 0xffffffff));
197 else
198 xsnprintf (str, PRINT_CELL_SIZE, "%lx%08lx", high,
199 (unsigned long) (l & 0xffffffff));
200 break;
202 case 4:
203 str = get_print_cell ();
204 xsnprintf (str, PRINT_CELL_SIZE, "%lx", (unsigned long) l);
205 break;
206 case 2:
207 str = get_print_cell ();
208 xsnprintf (str, PRINT_CELL_SIZE, "%x", (unsigned short) (l & 0xffff));
209 break;
210 case 1:
211 str = get_print_cell ();
212 xsnprintf (str, PRINT_CELL_SIZE, "%x", (unsigned short) (l & 0xff));
213 break;
214 default:
215 return phex_nz (l, sizeof (l));
216 break;
219 return str;
222 /* See print-utils.h. */
224 const char *
225 hex_string (LONGEST num)
227 char *result = get_print_cell ();
229 xsnprintf (result, PRINT_CELL_SIZE, "0x%s", phex_nz (num, sizeof (num)));
230 return result;
233 /* See print-utils.h. */
235 const char *
236 hex_string_custom (LONGEST num, int width)
238 char *result = get_print_cell ();
239 char *result_end = result + PRINT_CELL_SIZE - 1;
240 const char *hex = phex_nz (num, sizeof (num));
241 int hex_len = strlen (hex);
243 if (hex_len > width)
244 width = hex_len;
245 if (width + 2 >= PRINT_CELL_SIZE)
246 internal_error (_("\
247 hex_string_custom: insufficient space to store result"));
249 strcpy (result_end - width - 2, "0x");
250 memset (result_end - width, '0', width);
251 strcpy (result_end - hex_len, hex);
252 return result_end - width - 2;
255 /* See print-utils.h. */
257 const char *
258 int_string (LONGEST val, int radix, int is_signed, int width,
259 int use_c_format)
261 switch (radix)
263 case 16:
265 const char *result;
267 if (width == 0)
268 result = hex_string (val);
269 else
270 result = hex_string_custom (val, width);
271 if (! use_c_format)
272 result += 2;
273 return result;
275 case 10:
277 if (is_signed && val < 0)
278 /* Cast to unsigned before negating, to prevent runtime error:
279 negation of -9223372036854775808 cannot be represented in type
280 'long int'; cast to an unsigned type to negate this value to
281 itself. */
282 return decimal2str ("-", -(ULONGEST)val, width);
283 else
284 return decimal2str ("", val, width);
286 case 8:
288 char *result = octal2str (val, width);
290 if (use_c_format || val == 0)
291 return result;
292 else
293 return result + 1;
295 default:
296 internal_error (_("failed internal consistency check"));
300 /* See print-utils.h. */
302 const char *
303 core_addr_to_string (const CORE_ADDR addr)
305 char *str = get_print_cell ();
307 strcpy (str, "0x");
308 strcat (str, phex (addr, sizeof (addr)));
309 return str;
312 /* See print-utils.h. */
314 const char *
315 core_addr_to_string_nz (const CORE_ADDR addr)
317 char *str = get_print_cell ();
319 strcpy (str, "0x");
320 strcat (str, phex_nz (addr, sizeof (addr)));
321 return str;
324 /* See print-utils.h. */
326 const char *
327 host_address_to_string_1 (const void *addr)
329 char *str = get_print_cell ();
331 xsnprintf (str, PRINT_CELL_SIZE, "0x%s",
332 phex_nz ((uintptr_t) addr, sizeof (addr)));
333 return str;