]> Git Repo - binutils.git/blob - gdbsupport/print-utils.cc
Automatic date update in version.in
[binutils.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 (_("failed internal consistency check"));
77     }
78
79   return str;
80 }
81
82 static char *
83 octal2str (ULONGEST addr, int width)
84 {
85   unsigned long temp[3];
86   char *str = get_print_cell ();
87   int i = 0;
88
89   do
90     {
91       temp[i] = addr % (0100000 * 0100000);
92       addr /= (0100000 * 0100000);
93       i++;
94       width -= 10;
95     }
96   while (addr != 0 && i < (sizeof (temp) / sizeof (temp[0])));
97
98   width += 10;
99   if (width < 0)
100     width = 0;
101
102   switch (i)
103     {
104     case 1:
105       if (temp[0] == 0)
106         xsnprintf (str, PRINT_CELL_SIZE, "%*o", width, 0);
107       else
108         xsnprintf (str, PRINT_CELL_SIZE, "0%0*lo", width, temp[0]);
109       break;
110     case 2:
111       xsnprintf (str, PRINT_CELL_SIZE, "0%0*lo%010lo", width, temp[1], temp[0]);
112       break;
113     case 3:
114       xsnprintf (str, PRINT_CELL_SIZE, "0%0*lo%010lo%010lo", width,
115                  temp[2], temp[1], temp[0]);
116       break;
117     default:
118       internal_error (_("failed internal consistency check"));
119     }
120
121   return str;
122 }
123
124 /* See print-utils.h.  */
125
126 char *
127 pulongest (ULONGEST u)
128 {
129   return decimal2str ("", u, 0);
130 }
131
132 /* See print-utils.h.  */
133
134 char *
135 plongest (LONGEST l)
136 {
137   if (l < 0)
138     return decimal2str ("-", -l, 0);
139   else
140     return decimal2str ("", l, 0);
141 }
142
143 /* Eliminate warning from compiler on 32-bit systems.  */
144 static int thirty_two = 32;
145
146 /* See print-utils.h.  */
147
148 char *
149 phex (ULONGEST l, int sizeof_l)
150 {
151   char *str;
152
153   switch (sizeof_l)
154     {
155     case 8:
156       str = get_print_cell ();
157       xsnprintf (str, PRINT_CELL_SIZE, "%08lx%08lx",
158                  (unsigned long) (l >> thirty_two),
159                  (unsigned long) (l & 0xffffffff));
160       break;
161     case 4:
162       str = get_print_cell ();
163       xsnprintf (str, PRINT_CELL_SIZE, "%08lx", (unsigned long) l);
164       break;
165     case 2:
166       str = get_print_cell ();
167       xsnprintf (str, PRINT_CELL_SIZE, "%04x", (unsigned short) (l & 0xffff));
168       break;
169     case 1:
170       str = get_print_cell ();
171       xsnprintf (str, PRINT_CELL_SIZE, "%02x", (unsigned short) (l & 0xff));
172       break;
173     default:
174       str = phex (l, sizeof (l));
175       break;
176     }
177
178   return str;
179 }
180
181 /* See print-utils.h.  */
182
183 char *
184 phex_nz (ULONGEST l, int sizeof_l)
185 {
186   char *str;
187
188   switch (sizeof_l)
189     {
190     case 8:
191       {
192         unsigned long high = (unsigned long) (l >> thirty_two);
193
194         str = get_print_cell ();
195         if (high == 0)
196           xsnprintf (str, PRINT_CELL_SIZE, "%lx",
197                      (unsigned long) (l & 0xffffffff));
198         else
199           xsnprintf (str, PRINT_CELL_SIZE, "%lx%08lx", high,
200                      (unsigned long) (l & 0xffffffff));
201         break;
202       }
203     case 4:
204       str = get_print_cell ();
205       xsnprintf (str, PRINT_CELL_SIZE, "%lx", (unsigned long) l);
206       break;
207     case 2:
208       str = get_print_cell ();
209       xsnprintf (str, PRINT_CELL_SIZE, "%x", (unsigned short) (l & 0xffff));
210       break;
211     case 1:
212       str = get_print_cell ();
213       xsnprintf (str, PRINT_CELL_SIZE, "%x", (unsigned short) (l & 0xff));
214       break;
215     default:
216       str = phex_nz (l, sizeof (l));
217       break;
218     }
219
220   return str;
221 }
222
223 /* See print-utils.h.  */
224
225 char *
226 hex_string (LONGEST num)
227 {
228   char *result = get_print_cell ();
229
230   xsnprintf (result, PRINT_CELL_SIZE, "0x%s", phex_nz (num, sizeof (num)));
231   return result;
232 }
233
234 /* See print-utils.h.  */
235
236 char *
237 hex_string_custom (LONGEST num, int width)
238 {
239   char *result = get_print_cell ();
240   char *result_end = result + PRINT_CELL_SIZE - 1;
241   const char *hex = phex_nz (num, sizeof (num));
242   int hex_len = strlen (hex);
243
244   if (hex_len > width)
245     width = hex_len;
246   if (width + 2 >= PRINT_CELL_SIZE)
247     internal_error (_("\
248 hex_string_custom: insufficient space to store result"));
249
250   strcpy (result_end - width - 2, "0x");
251   memset (result_end - width, '0', width);
252   strcpy (result_end - hex_len, hex);
253   return result_end - width - 2;
254 }
255
256 /* See print-utils.h.  */
257
258 char *
259 int_string (LONGEST val, int radix, int is_signed, int width,
260             int use_c_format)
261 {
262   switch (radix)
263     {
264     case 16:
265       {
266         char *result;
267
268         if (width == 0)
269           result = hex_string (val);
270         else
271           result = hex_string_custom (val, width);
272         if (! use_c_format)
273           result += 2;
274         return result;
275       }
276     case 10:
277       {
278         if (is_signed && val < 0)
279           /* Cast to unsigned before negating, to prevent runtime error:
280              negation of -9223372036854775808 cannot be represented in type
281              'long int'; cast to an unsigned type to negate this value to
282              itself.  */
283           return decimal2str ("-", -(ULONGEST)val, width);
284         else
285           return decimal2str ("", val, width);
286       }
287     case 8:
288       {
289         char *result = octal2str (val, width);
290
291         if (use_c_format || val == 0)
292           return result;
293         else
294           return result + 1;
295       }
296     default:
297       internal_error (_("failed internal consistency check"));
298     }
299 }
300
301 /* See print-utils.h.  */
302
303 const char *
304 core_addr_to_string (const CORE_ADDR addr)
305 {
306   char *str = get_print_cell ();
307
308   strcpy (str, "0x");
309   strcat (str, phex (addr, sizeof (addr)));
310   return str;
311 }
312
313 /* See print-utils.h.  */
314
315 const char *
316 core_addr_to_string_nz (const CORE_ADDR addr)
317 {
318   char *str = get_print_cell ();
319
320   strcpy (str, "0x");
321   strcat (str, phex_nz (addr, sizeof (addr)));
322   return str;
323 }
324
325 /* See print-utils.h.  */
326
327 const char *
328 host_address_to_string_1 (const void *addr)
329 {
330   char *str = get_print_cell ();
331
332   xsnprintf (str, PRINT_CELL_SIZE, "0x%s",
333              phex_nz ((uintptr_t) addr, sizeof (addr)));
334   return str;
335 }
This page took 0.040464 seconds and 4 git commands to generate.