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