Implement completion for Ada attributes
[binutils-gdb.git] / gdbsupport / print-utils.cc
1 /* Cell-based print 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 "print-utils.h"
22 /* Temporary storage using circular buffer. */
23
24 /* Number of cells in the circular buffer. */
25 #define NUMCELLS 16
26
27 /* Return the next entry in the circular buffer. */
28
29 char *
30 get_print_cell (void)
31 {
32 static char buf[NUMCELLS][PRINT_CELL_SIZE];
33 static int cell = 0;
34
35 if (++cell >= NUMCELLS)
36 cell = 0;
37 return buf[cell];
38 }
39
40 static char *
41 decimal2str (const char *sign, ULONGEST addr, int width)
42 {
43 /* Steal code from valprint.c:print_decimal(). Should this worry
44 about the real size of addr as the above does? */
45 unsigned long temp[3];
46 char *str = get_print_cell ();
47 int i = 0;
48
49 do
50 {
51 temp[i] = addr % (1000 * 1000 * 1000);
52 addr /= (1000 * 1000 * 1000);
53 i++;
54 width -= 9;
55 }
56 while (addr != 0 && i < (sizeof (temp) / sizeof (temp[0])));
57
58 width += 9;
59 if (width < 0)
60 width = 0;
61
62 switch (i)
63 {
64 case 1:
65 xsnprintf (str, PRINT_CELL_SIZE, "%s%0*lu", sign, width, temp[0]);
66 break;
67 case 2:
68 xsnprintf (str, PRINT_CELL_SIZE, "%s%0*lu%09lu", sign, width,
69 temp[1], temp[0]);
70 break;
71 case 3:
72 xsnprintf (str, PRINT_CELL_SIZE, "%s%0*lu%09lu%09lu", sign, width,
73 temp[2], temp[1], temp[0]);
74 break;
75 default:
76 internal_error (__FILE__, __LINE__,
77 _("failed internal consistency check"));
78 }
79
80 return str;
81 }
82
83 static char *
84 octal2str (ULONGEST addr, int width)
85 {
86 unsigned long temp[3];
87 char *str = get_print_cell ();
88 int i = 0;
89
90 do
91 {
92 temp[i] = addr % (0100000 * 0100000);
93 addr /= (0100000 * 0100000);
94 i++;
95 width -= 10;
96 }
97 while (addr != 0 && i < (sizeof (temp) / sizeof (temp[0])));
98
99 width += 10;
100 if (width < 0)
101 width = 0;
102
103 switch (i)
104 {
105 case 1:
106 if (temp[0] == 0)
107 xsnprintf (str, PRINT_CELL_SIZE, "%*o", width, 0);
108 else
109 xsnprintf (str, PRINT_CELL_SIZE, "0%0*lo", width, temp[0]);
110 break;
111 case 2:
112 xsnprintf (str, PRINT_CELL_SIZE, "0%0*lo%010lo", width, temp[1], temp[0]);
113 break;
114 case 3:
115 xsnprintf (str, PRINT_CELL_SIZE, "0%0*lo%010lo%010lo", width,
116 temp[2], temp[1], temp[0]);
117 break;
118 default:
119 internal_error (__FILE__, __LINE__,
120 _("failed internal consistency check"));
121 }
122
123 return str;
124 }
125
126 /* See print-utils.h. */
127
128 char *
129 pulongest (ULONGEST u)
130 {
131 return decimal2str ("", u, 0);
132 }
133
134 /* See print-utils.h. */
135
136 char *
137 plongest (LONGEST l)
138 {
139 if (l < 0)
140 return decimal2str ("-", -l, 0);
141 else
142 return decimal2str ("", l, 0);
143 }
144
145 /* Eliminate warning from compiler on 32-bit systems. */
146 static int thirty_two = 32;
147
148 /* See print-utils.h. */
149
150 char *
151 phex (ULONGEST l, int sizeof_l)
152 {
153 char *str;
154
155 switch (sizeof_l)
156 {
157 case 8:
158 str = get_print_cell ();
159 xsnprintf (str, PRINT_CELL_SIZE, "%08lx%08lx",
160 (unsigned long) (l >> thirty_two),
161 (unsigned long) (l & 0xffffffff));
162 break;
163 case 4:
164 str = get_print_cell ();
165 xsnprintf (str, PRINT_CELL_SIZE, "%08lx", (unsigned long) l);
166 break;
167 case 2:
168 str = get_print_cell ();
169 xsnprintf (str, PRINT_CELL_SIZE, "%04x", (unsigned short) (l & 0xffff));
170 break;
171 case 1:
172 str = get_print_cell ();
173 xsnprintf (str, PRINT_CELL_SIZE, "%02x", (unsigned short) (l & 0xff));
174 break;
175 default:
176 str = phex (l, sizeof (l));
177 break;
178 }
179
180 return str;
181 }
182
183 /* See print-utils.h. */
184
185 char *
186 phex_nz (ULONGEST l, int sizeof_l)
187 {
188 char *str;
189
190 switch (sizeof_l)
191 {
192 case 8:
193 {
194 unsigned long high = (unsigned long) (l >> thirty_two);
195
196 str = get_print_cell ();
197 if (high == 0)
198 xsnprintf (str, PRINT_CELL_SIZE, "%lx",
199 (unsigned long) (l & 0xffffffff));
200 else
201 xsnprintf (str, PRINT_CELL_SIZE, "%lx%08lx", high,
202 (unsigned long) (l & 0xffffffff));
203 break;
204 }
205 case 4:
206 str = get_print_cell ();
207 xsnprintf (str, PRINT_CELL_SIZE, "%lx", (unsigned long) l);
208 break;
209 case 2:
210 str = get_print_cell ();
211 xsnprintf (str, PRINT_CELL_SIZE, "%x", (unsigned short) (l & 0xffff));
212 break;
213 case 1:
214 str = get_print_cell ();
215 xsnprintf (str, PRINT_CELL_SIZE, "%x", (unsigned short) (l & 0xff));
216 break;
217 default:
218 str = phex_nz (l, sizeof (l));
219 break;
220 }
221
222 return str;
223 }
224
225 /* See print-utils.h. */
226
227 char *
228 hex_string (LONGEST num)
229 {
230 char *result = get_print_cell ();
231
232 xsnprintf (result, PRINT_CELL_SIZE, "0x%s", phex_nz (num, sizeof (num)));
233 return result;
234 }
235
236 /* See print-utils.h. */
237
238 char *
239 hex_string_custom (LONGEST num, int width)
240 {
241 char *result = get_print_cell ();
242 char *result_end = result + PRINT_CELL_SIZE - 1;
243 const char *hex = phex_nz (num, sizeof (num));
244 int hex_len = strlen (hex);
245
246 if (hex_len > width)
247 width = hex_len;
248 if (width + 2 >= PRINT_CELL_SIZE)
249 internal_error (__FILE__, __LINE__, _("\
250 hex_string_custom: insufficient space to store result"));
251
252 strcpy (result_end - width - 2, "0x");
253 memset (result_end - width, '0', width);
254 strcpy (result_end - hex_len, hex);
255 return result_end - width - 2;
256 }
257
258 /* See print-utils.h. */
259
260 char *
261 int_string (LONGEST val, int radix, int is_signed, int width,
262 int use_c_format)
263 {
264 switch (radix)
265 {
266 case 16:
267 {
268 char *result;
269
270 if (width == 0)
271 result = hex_string (val);
272 else
273 result = hex_string_custom (val, width);
274 if (! use_c_format)
275 result += 2;
276 return result;
277 }
278 case 10:
279 {
280 if (is_signed && val < 0)
281 return decimal2str ("-", -val, width);
282 else
283 return decimal2str ("", val, width);
284 }
285 case 8:
286 {
287 char *result = octal2str (val, width);
288
289 if (use_c_format || val == 0)
290 return result;
291 else
292 return result + 1;
293 }
294 default:
295 internal_error (__FILE__, __LINE__,
296 _("failed internal consistency check"));
297 }
298 }
299
300 /* See print-utils.h. */
301
302 const char *
303 core_addr_to_string (const CORE_ADDR addr)
304 {
305 char *str = get_print_cell ();
306
307 strcpy (str, "0x");
308 strcat (str, phex (addr, sizeof (addr)));
309 return str;
310 }
311
312 /* See print-utils.h. */
313
314 const char *
315 core_addr_to_string_nz (const CORE_ADDR addr)
316 {
317 char *str = get_print_cell ();
318
319 strcpy (str, "0x");
320 strcat (str, phex_nz (addr, sizeof (addr)));
321 return str;
322 }
323
324 /* See print-utils.h. */
325
326 const char *
327 host_address_to_string_1 (const void *addr)
328 {
329 char *str = get_print_cell ();
330
331 xsnprintf (str, PRINT_CELL_SIZE, "0x%s",
332 phex_nz ((uintptr_t) addr, sizeof (addr)));
333 return str;
334 }