]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/utils.c
gdb-2.5.1
[thirdparty/binutils-gdb.git] / gdb / utils.c
CommitLineData
7b4ac7e1 1/* General utility routines for GDB, the GNU debugger.
2 Copyright (C) 1986 Free Software Foundation, Inc.
3
4GDB is distributed in the hope that it will be useful, but WITHOUT ANY
5WARRANTY. No author or distributor accepts responsibility to anyone
6for the consequences of using it or for whether it serves any
7particular purpose or works at all, unless he says so in writing.
8Refer to the GDB General Public License for full details.
9
10Everyone is granted permission to copy, modify and redistribute GDB,
11but only under the conditions described in the GDB General Public
12License. A copy of this license is supposed to have been given to you
13along with GDB so you can know your rights and responsibilities. It
14should be in a file named COPYING. Among other things, the copyright
15notice and this notice must be preserved on all copies.
16
17In other words, go ahead and share GDB, but don't try to stop
18anyone else from sharing it farther. Help stamp out software hoarding!
19*/
20
21#include <stdio.h>
22#include <sys/ioctl.h>
23#include "defs.h"
24
25void error ();
26void fatal ();
27
28/* Chain of cleanup actions established with make_cleanup,
29 to be executed if an error happens. */
30
31static struct cleanup *cleanup_chain;
32
33/* Nonzero means a quit has been requested. */
34
35int quit_flag;
36
37/* Nonzero means quit immediately if Control-C is typed now,
38 rather than waiting until QUIT is executed. */
39
40int immediate_quit;
41\f
42/* Add a new cleanup to the cleanup_chain,
43 and return the previous chain pointer
44 to be passed later to do_cleanups or discard_cleanups.
45 Args are FUNCTION to clean up with, and ARG to pass to it. */
46
47struct cleanup *
48make_cleanup (function, arg)
49 void (*function) ();
50 int arg;
51{
52 register struct cleanup *new
53 = (struct cleanup *) xmalloc (sizeof (struct cleanup));
54 register struct cleanup *old_chain = cleanup_chain;
55
56 new->next = cleanup_chain;
57 new->function = function;
58 new->arg = arg;
59 cleanup_chain = new;
60
61 return old_chain;
62}
63
64/* Discard cleanups and do the actions they describe
65 until we get back to the point OLD_CHAIN in the cleanup_chain. */
66
67void
68do_cleanups (old_chain)
69 register struct cleanup *old_chain;
70{
71 register struct cleanup *ptr;
72 while ((ptr = cleanup_chain) != old_chain)
73 {
74 (*ptr->function) (ptr->arg);
75 cleanup_chain = ptr->next;
76 free (ptr);
77 }
78}
79
80/* Discard cleanups, not doing the actions they describe,
81 until we get back to the point OLD_CHAIN in the cleanup_chain. */
82
83void
84discard_cleanups (old_chain)
85 register struct cleanup *old_chain;
86{
87 register struct cleanup *ptr;
88 while ((ptr = cleanup_chain) != old_chain)
89 {
90 cleanup_chain = ptr->next;
91 free (ptr);
92 }
93}
94
95/* This function is useful for cleanups.
96 Do
97
98 foo = xmalloc (...);
99 old_chain = make_cleanup (free_current_contents, &foo);
100
101 to arrange to free the object thus allocated. */
102
103void
104free_current_contents (location)
105 char **location;
106{
107 free (*location);
108}
109\f
110/* Generally useful subroutines used throughout the program. */
111
112/* Like malloc but get error if no storage available. */
113
114char *
115xmalloc (size)
116 long size;
117{
118 register char *val = (char *) malloc (size);
119 if (!val)
120 fatal ("virtual memory exhausted.", 0);
121 return val;
122}
123
124/* Like realloc but get error if no storage available. */
125
126char *
127xrealloc (ptr, size)
128 char *ptr;
129 long size;
130{
131 register char *val = (char *) realloc (ptr, size);
132 if (!val)
133 fatal ("virtual memory exhausted.", 0);
134 return val;
135}
136
137/* Print the system error message for errno, and also mention STRING
138 as the file name for which the error was encountered.
139 Then return to command level. */
140
141void
142perror_with_name (string)
143 char *string;
144{
145 extern int sys_nerr;
146 extern char *sys_errlist[];
147 extern int errno;
148 char *err;
149 char *combined;
150
151 if (errno < sys_nerr)
152 err = sys_errlist[errno];
153 else
154 err = "unknown error";
155
156 combined = (char *) alloca (strlen (err) + strlen (string) + 3);
157 strcpy (combined, string);
158 strcat (combined, ": ");
159 strcat (combined, err);
160
161 error ("%s.", combined);
162}
163
164/* Print the system error message for ERRCODE, and also mention STRING
165 as the file name for which the error was encountered. */
166
167void
168print_sys_errmsg (string, errcode)
169 char *string;
170 int errcode;
171{
172 extern int sys_nerr;
173 extern char *sys_errlist[];
174 char *err;
175 char *combined;
176
177 if (errcode < sys_nerr)
178 err = sys_errlist[errcode];
179 else
180 err = "unknown error";
181
182 combined = (char *) alloca (strlen (err) + strlen (string) + 3);
183 strcpy (combined, string);
184 strcat (combined, ": ");
185 strcat (combined, err);
186
187 printf ("%s.\n", combined);
188}
189
190void
191quit ()
192{
193 fflush (stdout);
7b4ac7e1 194 ioctl (fileno (stdout), TIOCFLUSH, 0);
7b4ac7e1 195 error ("Quit");
196}
197
198/* Control C comes here */
199
200void
201request_quit ()
202{
203 quit_flag = 1;
204 if (immediate_quit)
205 quit ();
206}
207
208/* Print an error message and return to command level.
209 STRING is the error message, used as a fprintf string,
210 and ARG is passed as an argument to it. */
211
212void
213error (string, arg1, arg2, arg3)
214 char *string;
215 int arg1, arg2, arg3;
216{
217 fflush (stdout);
218 fprintf (stderr, string, arg1, arg2, arg3);
219 fprintf (stderr, "\n");
220 return_to_top_level ();
221}
222
223/* Print an error message and exit reporting failure.
224 This is for a error that we cannot continue from.
225 STRING and ARG are passed to fprintf. */
226
227void
228fatal (string, arg)
229 char *string;
230 int arg;
231{
232 fprintf (stderr, "gdb: ");
233 fprintf (stderr, string, arg);
234 fprintf (stderr, "\n");
235 exit (1);
236}
237
238/* Make a copy of the string at PTR with SIZE characters
239 (and add a null character at the end in the copy).
240 Uses malloc to get the space. Returns the address of the copy. */
241
242char *
243savestring (ptr, size)
244 char *ptr;
245 int size;
246{
247 register char *p = (char *) xmalloc (size + 1);
248 bcopy (ptr, p, size);
249 p[size] = 0;
250 return p;
251}
252
253char *
254concat (s1, s2, s3)
255 char *s1, *s2, *s3;
256{
257 register int len = strlen (s1) + strlen (s2) + strlen (s3) + 1;
258 register char *val = (char *) xmalloc (len);
259 strcpy (val, s1);
260 strcat (val, s2);
261 strcat (val, s3);
262 return val;
263}
264
265void
266print_spaces (n, file)
267 register int n;
268 register FILE *file;
269{
270 while (n-- > 0)
271 fputc (' ', file);
272}
273
274/* Ask user a y-or-n question and return 1 iff answer is yes.
275 Takes three args which are given to printf to print the question.
276 The first, a control string, should end in "? ".
277 It should not say how to answer, because we do that. */
278
279int
280query (ctlstr, arg1, arg2)
281 char *ctlstr;
282{
283 register int answer;
284
285 /* Automatically answer "yes" if input is not from a terminal. */
286 if (!input_from_terminal_p ())
287 return 1;
288
289 while (1)
290 {
291 printf (ctlstr, arg1, arg2);
292 printf ("(y or n) ");
293 fflush (stdout);
294 answer = fgetc (stdin);
295 clearerr (stdin); /* in case of C-d */
296 if (answer != '\n')
297 while (fgetc (stdin) != '\n') clearerr (stdin);
298 if (answer >= 'a')
299 answer -= 040;
300 if (answer == 'Y')
301 return 1;
302 if (answer == 'N')
303 return 0;
304 printf ("Please answer y or n.\n");
305 }
306}
307\f
308/* Parse a C escape sequence. STRING_PTR points to a variable
309 containing a pointer to the string to parse. That pointer
310 is updated past the characters we use. The value of the
311 escape sequence is returned.
312
313 A negative value means the sequence \ newline was seen,
314 which is supposed to be equivalent to nothing at all.
315
316 If \ is followed by a null character, we return a negative
317 value and leave the string pointer pointing at the null character.
318
319 If \ is followed by 000, we return 0 and leave the string pointer
320 after the zeros. A value of 0 does not mean end of string. */
321
322int
323parse_escape (string_ptr)
324 char **string_ptr;
325{
326 register int c = *(*string_ptr)++;
327 switch (c)
328 {
329 case 'a':
330 return '\a';
331 case 'b':
332 return '\b';
333 case 'e':
334 return 033;
335 case 'f':
336 return '\f';
337 case 'n':
338 return '\n';
339 case 'r':
340 return '\r';
341 case 't':
342 return '\t';
343 case 'v':
344 return '\v';
345 case '\n':
346 return -2;
347 case 0:
348 (*string_ptr)--;
349 return 0;
350 case '^':
351 c = *(*string_ptr)++;
352 if (c == '\\')
353 c = parse_escape (string_ptr);
354 if (c == '?')
355 return 0177;
356 return (c & 0200) | (c & 037);
357
358 case '0':
359 case '1':
360 case '2':
361 case '3':
362 case '4':
363 case '5':
364 case '6':
365 case '7':
366 {
367 register int i = c - '0';
368 register int count = 0;
369 while (++count < 3)
370 {
371 if ((c = *(*string_ptr)++) >= '0' && c <= '7')
372 {
373 i *= 8;
374 i += c - '0';
375 }
376 else
377 {
378 (*string_ptr)--;
379 break;
380 }
381 }
382 return i;
383 }
384 default:
385 return c;
386 }
387}
388\f
389void
390printchar (ch, stream)
391 unsigned char ch;
392 FILE *stream;
393{
394 register int c = ch;
395 if (c < 040 || c >= 0177)
396 {
397 if (c == '\n')
398 fprintf (stream, "\\n");
399 else if (c == '\b')
400 fprintf (stream, "\\b");
401 else if (c == '\t')
402 fprintf (stream, "\\t");
403 else if (c == '\f')
404 fprintf (stream, "\\f");
405 else if (c == '\r')
406 fprintf (stream, "\\r");
407 else if (c == 033)
408 fprintf (stream, "\\e");
409 else if (c == '\a')
410 fprintf (stream, "\\a");
411 else
412 fprintf (stream, "\\%03o", c);
413 }
414 else
415 {
416 if (c == '\\' || c == '"' || c == '\'')
417 fputc ('\\', stream);
418 fputc (c, stream);
419 }
420}