diff options
author | John Gilmore <gnu@cygnus> | 1990-09-05 17:54:31 +0000 |
---|---|---|
committer | John Gilmore <gnu@cygnus> | 1990-09-05 17:54:31 +0000 |
commit | 831c851165e112139af1265f294e198401814c1f (patch) | |
tree | 5f155fecb9b690be9c428e822d519c2710fefd47 /gdb/utils.c | |
parent | 7a67dd45ca1c191a0220697a3ec9fa92993caf8c (diff) | |
download | gdb-831c851165e112139af1265f294e198401814c1f.zip gdb-831c851165e112139af1265f294e198401814c1f.tar.gz gdb-831c851165e112139af1265f294e198401814c1f.tar.bz2 |
Initial revision
Diffstat (limited to 'gdb/utils.c')
-rw-r--r-- | gdb/utils.c | 1000 |
1 files changed, 0 insertions, 1000 deletions
diff --git a/gdb/utils.c b/gdb/utils.c deleted file mode 100644 index 18e0fe8..0000000 --- a/gdb/utils.c +++ /dev/null @@ -1,1000 +0,0 @@ -/* General utility routines for GDB, the GNU debugger. - Copyright (C) 1986, 1989 Free Software Foundation, Inc. - -This file is part of GDB. - -GDB is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 1, or (at your option) -any later version. - -GDB is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GDB; see the file COPYING. If not, write to -the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#include <stdio.h> -#include <signal.h> -#include <sys/ioctl.h> -#include <sys/param.h> -#include <pwd.h> -#include "defs.h" -#include "param.h" -#ifdef HAVE_TERMIO -#include <termio.h> -#endif - -/* If this definition isn't overridden by the header files, assume - that isatty and fileno exist on this system. */ -#ifndef ISATTY -#define ISATTY(FP) (isatty (fileno (FP))) -#endif - -void error (); -void fatal (); - -/* Chain of cleanup actions established with make_cleanup, - to be executed if an error happens. */ - -static struct cleanup *cleanup_chain; - -/* Nonzero means a quit has been requested. */ - -int quit_flag; - -/* Nonzero means quit immediately if Control-C is typed now, - rather than waiting until QUIT is executed. */ - -int immediate_quit; - -/* Add a new cleanup to the cleanup_chain, - and return the previous chain pointer - to be passed later to do_cleanups or discard_cleanups. - Args are FUNCTION to clean up with, and ARG to pass to it. */ - -struct cleanup * -make_cleanup (function, arg) - void (*function) (); - int arg; -{ - register struct cleanup *new - = (struct cleanup *) xmalloc (sizeof (struct cleanup)); - register struct cleanup *old_chain = cleanup_chain; - - new->next = cleanup_chain; - new->function = function; - new->arg = arg; - cleanup_chain = new; - - return old_chain; -} - -/* Discard cleanups and do the actions they describe - until we get back to the point OLD_CHAIN in the cleanup_chain. */ - -void -do_cleanups (old_chain) - register struct cleanup *old_chain; -{ - register struct cleanup *ptr; - while ((ptr = cleanup_chain) != old_chain) - { - (*ptr->function) (ptr->arg); - cleanup_chain = ptr->next; - free (ptr); - } -} - -/* Discard cleanups, not doing the actions they describe, - until we get back to the point OLD_CHAIN in the cleanup_chain. */ - -void -discard_cleanups (old_chain) - register struct cleanup *old_chain; -{ - register struct cleanup *ptr; - while ((ptr = cleanup_chain) != old_chain) - { - cleanup_chain = ptr->next; - free (ptr); - } -} - -/* Set the cleanup_chain to 0, and return the old cleanup chain. */ -struct cleanup * -save_cleanups () -{ - struct cleanup *old_chain = cleanup_chain; - - cleanup_chain = 0; - return old_chain; -} - -/* Restore the cleanup chain from a previously saved chain. */ -void -restore_cleanups (chain) - struct cleanup *chain; -{ - cleanup_chain = chain; -} - -/* This function is useful for cleanups. - Do - - foo = xmalloc (...); - old_chain = make_cleanup (free_current_contents, &foo); - - to arrange to free the object thus allocated. */ - -void -free_current_contents (location) - char **location; -{ - free (*location); -} - -/* Generally useful subroutines used throughout the program. */ - -/* Like malloc but get error if no storage available. */ - -char * -xmalloc (size) - long size; -{ - register char *val = (char *) malloc (size); - if (!val) - fatal ("virtual memory exhausted.", 0); - return val; -} - -/* Like realloc but get error if no storage available. */ - -char * -xrealloc (ptr, size) - char *ptr; - long size; -{ - register char *val = (char *) realloc (ptr, size); - if (!val) - fatal ("virtual memory exhausted.", 0); - return val; -} - -/* Print the system error message for errno, and also mention STRING - as the file name for which the error was encountered. - Then return to command level. */ - -void -perror_with_name (string) - char *string; -{ - extern int sys_nerr; - extern char *sys_errlist[]; - extern int errno; - char *err; - char *combined; - - if (errno < sys_nerr) - err = sys_errlist[errno]; - else - err = "unknown error"; - - combined = (char *) alloca (strlen (err) + strlen (string) + 3); - strcpy (combined, string); - strcat (combined, ": "); - strcat (combined, err); - - error ("%s.", combined); -} - -/* Print the system error message for ERRCODE, and also mention STRING - as the file name for which the error was encountered. */ - -void -print_sys_errmsg (string, errcode) - char *string; - int errcode; -{ - extern int sys_nerr; - extern char *sys_errlist[]; - char *err; - char *combined; - - if (errcode < sys_nerr) - err = sys_errlist[errcode]; - else - err = "unknown error"; - - combined = (char *) alloca (strlen (err) + strlen (string) + 3); - strcpy (combined, string); - strcat (combined, ": "); - strcat (combined, err); - - printf ("%s.\n", combined); -} - -void -quit () -{ -#ifdef HAVE_TERMIO - ioctl (fileno (stdout), TCFLSH, 1); -#else /* not HAVE_TERMIO */ - ioctl (fileno (stdout), TIOCFLUSH, 0); -#endif /* not HAVE_TERMIO */ -#ifdef TIOCGPGRP - error ("Quit"); -#else - error ("Quit (expect signal %d when inferior is resumed)", SIGINT); -#endif /* TIOCGPGRP */ -} - -/* Control C comes here */ - -void -request_quit () -{ - quit_flag = 1; - -#ifdef USG - /* Restore the signal handler. */ - signal (SIGINT, request_quit); -#endif - - if (immediate_quit) - quit (); -} - -/* Print an error message and return to command level. - STRING is the error message, used as a fprintf string, - and ARG is passed as an argument to it. */ - -void -error (string, arg1, arg2, arg3) - char *string; - int arg1, arg2, arg3; -{ - terminal_ours (); /* Should be ok even if no inf. */ - fflush (stdout); - fprintf (stderr, string, arg1, arg2, arg3); - fprintf (stderr, "\n"); - return_to_top_level (); -} - -/* Print an error message and exit reporting failure. - This is for a error that we cannot continue from. - STRING and ARG are passed to fprintf. */ - -void -fatal (string, arg) - char *string; - int arg; -{ - fprintf (stderr, "gdb: "); - fprintf (stderr, string, arg); - fprintf (stderr, "\n"); - exit (1); -} - -/* Print an error message and exit, dumping core. - STRING is a printf-style control string, and ARG is a corresponding - argument. */ -void -fatal_dump_core (string, arg) - char *string; - int arg; -{ - /* "internal error" is always correct, since GDB should never dump - core, no matter what the input. */ - fprintf (stderr, "gdb internal error: "); - fprintf (stderr, string, arg); - fprintf (stderr, "\n"); - signal (SIGQUIT, SIG_DFL); - kill (getpid (), SIGQUIT); - /* We should never get here, but just in case... */ - exit (1); -} - -/* Make a copy of the string at PTR with SIZE characters - (and add a null character at the end in the copy). - Uses malloc to get the space. Returns the address of the copy. */ - -char * -savestring (ptr, size) - char *ptr; - int size; -{ - register char *p = (char *) xmalloc (size + 1); - bcopy (ptr, p, size); - p[size] = 0; - return p; -} - -char * -concat (s1, s2, s3) - char *s1, *s2, *s3; -{ - register int len = strlen (s1) + strlen (s2) + strlen (s3) + 1; - register char *val = (char *) xmalloc (len); - strcpy (val, s1); - strcat (val, s2); - strcat (val, s3); - return val; -} - -void -print_spaces (n, file) - register int n; - register FILE *file; -{ - while (n-- > 0) - fputc (' ', file); -} - -/* Ask user a y-or-n question and return 1 iff answer is yes. - Takes three args which are given to printf to print the question. - The first, a control string, should end in "? ". - It should not say how to answer, because we do that. */ - -int -query (ctlstr, arg1, arg2) - char *ctlstr; -{ - register int answer; - - /* Automatically answer "yes" if input is not from a terminal. */ - if (!input_from_terminal_p ()) - return 1; - - while (1) - { - printf (ctlstr, arg1, arg2); - printf ("(y or n) "); - fflush (stdout); - answer = fgetc (stdin); - clearerr (stdin); /* in case of C-d */ - if (answer != '\n') - while (fgetc (stdin) != '\n') clearerr (stdin); - if (answer >= 'a') - answer -= 040; - if (answer == 'Y') - return 1; - if (answer == 'N') - return 0; - printf ("Please answer y or n.\n"); - } -} - -/* Parse a C escape sequence. STRING_PTR points to a variable - containing a pointer to the string to parse. That pointer - is updated past the characters we use. The value of the - escape sequence is returned. - - A negative value means the sequence \ newline was seen, - which is supposed to be equivalent to nothing at all. - - If \ is followed by a null character, we return a negative - value and leave the string pointer pointing at the null character. - - If \ is followed by 000, we return 0 and leave the string pointer - after the zeros. A value of 0 does not mean end of string. */ - -int -parse_escape (string_ptr) - char **string_ptr; -{ - register int c = *(*string_ptr)++; - switch (c) - { - case 'a': - return '\a'; - case 'b': - return '\b'; - case 'e': - return 033; - case 'f': - return '\f'; - case 'n': - return '\n'; - case 'r': - return '\r'; - case 't': - return '\t'; - case 'v': - return '\v'; - case '\n': - return -2; - case 0: - (*string_ptr)--; - return 0; - case '^': - c = *(*string_ptr)++; - if (c == '\\') - c = parse_escape (string_ptr); - if (c == '?') - return 0177; - return (c & 0200) | (c & 037); - - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - { - register int i = c - '0'; - register int count = 0; - while (++count < 3) - { - if ((c = *(*string_ptr)++) >= '0' && c <= '7') - { - i *= 8; - i += c - '0'; - } - else - { - (*string_ptr)--; - break; - } - } - return i; - } - default: - return c; - } -} - -/* Print the character CH on STREAM as part of the contents - of a literal string whose delimiter is QUOTER. */ - -void -printchar (ch, stream, quoter) - unsigned char ch; - FILE *stream; - int quoter; -{ - register int c = ch; - if (c < 040 || c >= 0177) - switch (c) - { - case '\n': - fputs_filtered ("\\n", stream); - break; - case '\b': - fputs_filtered ("\\b", stream); - break; - case '\t': - fputs_filtered ("\\t", stream); - break; - case '\f': - fputs_filtered ("\\f", stream); - break; - case '\r': - fputs_filtered ("\\r", stream); - break; - case '\033': - fputs_filtered ("\\e", stream); - break; - case '\007': - fputs_filtered ("\\a", stream); - break; - default: - fprintf_filtered (stream, "\\%.3o", (unsigned int) c); - break; - } - else - { - if (c == '\\' || c == quoter) - fputs_filtered ("\\", stream); - fprintf_filtered (stream, "%c", c); - } -} - -static int lines_per_page, lines_printed, chars_per_line, chars_printed; - -/* Set values of page and line size. */ -static void -set_screensize_command (arg, from_tty) - char *arg; - int from_tty; -{ - char *p = arg; - char *p1; - int tolinesize = lines_per_page; - int tocharsize = chars_per_line; - - if (p == 0) - error_no_arg ("set screensize"); - - while (*p >= '0' && *p <= '9') - p++; - - if (*p && *p != ' ' && *p != '\t') - error ("Non-integral argument given to \"set screensize\"."); - - tolinesize = atoi (arg); - - while (*p == ' ' || *p == '\t') - p++; - - if (*p) - { - p1 = p; - while (*p1 >= '0' && *p1 <= '9') - p1++; - - if (*p1) - error ("Non-integral second argument given to \"set screensize\"."); - - tocharsize = atoi (p); - } - - lines_per_page = tolinesize; - chars_per_line = tocharsize; -} - -static void -prompt_for_continue () -{ - immediate_quit++; - gdb_readline ("---Type <return> to continue---", 0); - chars_printed = lines_printed = 0; - immediate_quit--; -} - -/* Reinitialize filter; ie. tell it to reset to original values. */ - -void -reinitialize_more_filter () -{ - lines_printed = 0; - chars_printed = 0; -} - -static void -screensize_info (arg, from_tty) - char *arg; - int from_tty; -{ - if (arg) - error ("\"info screensize\" does not take any arguments."); - - if (!lines_per_page) - printf ("Output more filtering is disabled.\n"); - else - { - printf ("Output more filtering is enabled with\n"); - printf ("%d lines per page and %d characters per line.\n", - lines_per_page, chars_per_line); - } -} - -/* Like fputs but pause after every screenful. - Unlike fputs, fputs_filtered does not return a value. - It is OK for LINEBUFFER to be NULL, in which case just don't print - anything. - - Note that a longjmp to top level may occur in this routine - (since prompt_for_continue may do so) so this routine should not be - called when cleanups are not in place. */ - -void -fputs_filtered (linebuffer, stream) - char *linebuffer; - FILE *stream; -{ - char *lineptr; - - if (linebuffer == 0) - return; - - /* Don't do any filtering if it is disabled. */ - if (stream != stdout || !ISATTY(stdout) || lines_per_page == 0) - { - fputs (linebuffer, stream); - return; - } - - /* Go through and output each character. Show line extension - when this is necessary; prompt user for new page when this is - necessary. */ - - lineptr = linebuffer; - while (*lineptr) - { - /* Possible new page. */ - if (lines_printed >= lines_per_page - 1) - prompt_for_continue (); - - while (*lineptr && *lineptr != '\n') - { - /* Print a single line. */ - if (*lineptr == '\t') - { - putc ('\t', stream); - /* Shifting right by 3 produces the number of tab stops - we have already passed, and then adding one and - shifting left 3 advances to the next tab stop. */ - chars_printed = ((chars_printed >> 3) + 1) << 3; - lineptr++; - } - else - { - putc (*lineptr, stream); - chars_printed++; - lineptr++; - } - - if (chars_printed >= chars_per_line) - { - chars_printed = 0; - lines_printed++; - /* Possible new page. */ - if (lines_printed >= lines_per_page - 1) - prompt_for_continue (); - } - } - - if (*lineptr == '\n') - { - lines_printed++; - putc ('\n', stream); - lineptr++; - chars_printed = 0; - } - } -} - -/* Print ARG1, ARG2, and ARG3 on stdout using format FORMAT. If this - information is going to put the amount written since the last call - to INIIALIZE_MORE_FILTER or the last page break over the page size, - print out a pause message and do a gdb_readline to get the users - permision to continue. - - Unlike fprintf, this function does not return a value. - - Note that this routine has a restriction that the length of the - final output line must be less than 255 characters *or* it must be - less than twice the size of the format string. This is a very - arbitrary restriction, but it is an internal restriction, so I'll - put it in. This means that the %s format specifier is almost - useless; unless the caller can GUARANTEE that the string is short - enough, fputs_filtered should be used instead. - - Note also that a longjmp to top level may occur in this routine - (since prompt_for_continue may do so) so this routine should not be - called when cleanups are not in place. */ - -void -fprintf_filtered (stream, format, arg1, arg2, arg3, arg4, arg5, arg6) - FILE *stream; - char *format; - int arg1, arg2, arg3, arg4, arg5, arg6; -{ - static char *linebuffer = (char *) 0; - static int line_size; - int format_length = strlen (format); - int numchars; - - /* Allocated linebuffer for the first time. */ - if (!linebuffer) - { - linebuffer = (char *) xmalloc (255); - line_size = 255; - } - - /* Reallocate buffer to a larger size if this is necessary. */ - if (format_length * 2 > line_size) - { - line_size = format_length * 2; - - /* You don't have to copy. */ - free (linebuffer); - linebuffer = (char *) xmalloc (line_size); - } - - /* This won't blow up if the restrictions described above are - followed. */ - (void) sprintf (linebuffer, format, arg1, arg2, arg3, arg4, arg5, arg6); - - fputs_filtered (linebuffer, stream); -} - -void -printf_filtered (format, arg1, arg2, arg3, arg4, arg5, arg6) - char *format; - int arg1, arg2, arg3, arg4, arg5, arg6; -{ - fprintf_filtered (stdout, format, arg1, arg2, arg3, arg4, arg5, arg6); -} - -/* Print N spaces. */ -void -print_spaces_filtered (n, stream) - int n; - FILE *stream; -{ - register char *s = (char *) alloca (n + 1); - register char *t = s; - - while (n--) - *t++ = ' '; - *t = '\0'; - - fputs_filtered (s, stream); -} - - -#ifdef USG -bcopy (from, to, count) -char *from, *to; -{ - memcpy (to, from, count); -} - -bcmp (from, to, count) -{ - return (memcmp (to, from, count)); -} - -bzero (to, count) -char *to; -{ - while (count--) - *to++ = 0; -} - -getwd (buf) -char *buf; -{ - getcwd (buf, MAXPATHLEN); -} - -char * -index (s, c) - char *s; -{ - char *strchr (); - return strchr (s, c); -} - -char * -rindex (s, c) - char *s; -{ - char *strrchr (); - return strrchr (s, c); -} - -#ifndef USG -char *sys_siglist[32] = { - "SIG0", - "SIGHUP", - "SIGINT", - "SIGQUIT", - "SIGILL", - "SIGTRAP", - "SIGIOT", - "SIGEMT", - "SIGFPE", - "SIGKILL", - "SIGBUS", - "SIGSEGV", - "SIGSYS", - "SIGPIPE", - "SIGALRM", - "SIGTERM", - "SIGUSR1", - "SIGUSR2", - "SIGCLD", - "SIGPWR", - "SIGWIND", - "SIGPHONE", - "SIGPOLL", -}; -#endif - -/* Queue routines */ - -struct queue { - struct queue *forw; - struct queue *back; -}; - -insque (item, after) -struct queue *item; -struct queue *after; -{ - item->forw = after->forw; - after->forw->back = item; - - item->back = after; - after->forw = item; -} - -remque (item) -struct queue *item; -{ - item->forw->back = item->back; - item->back->forw = item->forw; -} -#endif /* USG */ - -#ifdef USG -/* There is too much variation in Sys V signal numbers and names, so - we must initialize them at runtime. */ -static char undoc[] = "(undocumented)"; - -char *sys_siglist[NSIG]; -#endif /* USG */ - -extern struct cmd_list_element *setlist; - -void -_initialize_utils () -{ - int i; - add_cmd ("screensize", class_support, set_screensize_command, - "Change gdb's notion of the size of the output screen.\n\ -The first argument is the number of lines on a page.\n\ -The second argument (optional) is the number of characters on a line.", - &setlist); - add_info ("screensize", screensize_info, - "Show gdb's current notion of the size of the output screen."); - - /* These defaults will be used if we are unable to get the correct - values from termcap. */ - lines_per_page = 24; - chars_per_line = 80; - /* Initialize the screen height and width from termcap. */ - { - int termtype = getenv ("TERM"); - - /* Positive means success, nonpositive means failure. */ - int status; - - /* 2048 is large enough for all known terminals, according to the - GNU termcap manual. */ - char term_buffer[2048]; - - if (termtype) - { - status = tgetent (term_buffer, termtype); - if (status > 0) - { - int val; - - val = tgetnum ("li"); - if (val >= 0) - lines_per_page = val; - else - /* The number of lines per page is not mentioned - in the terminal description. This probably means - that paging is not useful (e.g. emacs shell window), - so disable paging. */ - lines_per_page = 0; - - val = tgetnum ("co"); - if (val >= 0) - chars_per_line = val; - } - } - } - -#ifdef USG - /* Initialize signal names. */ - for (i = 0; i < NSIG; i++) - sys_siglist[i] = undoc; - -#ifdef SIGHUP - sys_siglist[SIGHUP ] = "SIGHUP"; -#endif -#ifdef SIGINT - sys_siglist[SIGINT ] = "SIGINT"; -#endif -#ifdef SIGQUIT - sys_siglist[SIGQUIT ] = "SIGQUIT"; -#endif -#ifdef SIGILL - sys_siglist[SIGILL ] = "SIGILL"; -#endif -#ifdef SIGTRAP - sys_siglist[SIGTRAP ] = "SIGTRAP"; -#endif -#ifdef SIGIOT - sys_siglist[SIGIOT ] = "SIGIOT"; -#endif -#ifdef SIGEMT - sys_siglist[SIGEMT ] = "SIGEMT"; -#endif -#ifdef SIGFPE - sys_siglist[SIGFPE ] = "SIGFPE"; -#endif -#ifdef SIGKILL - sys_siglist[SIGKILL ] = "SIGKILL"; -#endif -#ifdef SIGBUS - sys_siglist[SIGBUS ] = "SIGBUS"; -#endif -#ifdef SIGSEGV - sys_siglist[SIGSEGV ] = "SIGSEGV"; -#endif -#ifdef SIGSYS - sys_siglist[SIGSYS ] = "SIGSYS"; -#endif -#ifdef SIGPIPE - sys_siglist[SIGPIPE ] = "SIGPIPE"; -#endif -#ifdef SIGALRM - sys_siglist[SIGALRM ] = "SIGALRM"; -#endif -#ifdef SIGTERM - sys_siglist[SIGTERM ] = "SIGTERM"; -#endif -#ifdef SIGUSR1 - sys_siglist[SIGUSR1 ] = "SIGUSR1"; -#endif -#ifdef SIGUSR2 - sys_siglist[SIGUSR2 ] = "SIGUSR2"; -#endif -#ifdef SIGCLD - sys_siglist[SIGCLD ] = "SIGCLD"; -#endif -#ifdef SIGCHLD - sys_siglist[SIGCHLD ] = "SIGCHLD"; -#endif -#ifdef SIGPWR - sys_siglist[SIGPWR ] = "SIGPWR"; -#endif -#ifdef SIGTSTP - sys_siglist[SIGTSTP ] = "SIGTSTP"; -#endif -#ifdef SIGTTIN - sys_siglist[SIGTTIN ] = "SIGTTIN"; -#endif -#ifdef SIGTTOU - sys_siglist[SIGTTOU ] = "SIGTTOU"; -#endif -#ifdef SIGSTOP - sys_siglist[SIGSTOP ] = "SIGSTOP"; -#endif -#ifdef SIGXCPU - sys_siglist[SIGXCPU ] = "SIGXCPU"; -#endif -#ifdef SIGXFSZ - sys_siglist[SIGXFSZ ] = "SIGXFSZ"; -#endif -#ifdef SIGVTALRM - sys_siglist[SIGVTALRM ] = "SIGVTALRM"; -#endif -#ifdef SIGPROF - sys_siglist[SIGPROF ] = "SIGPROF"; -#endif -#ifdef SIGWINCH - sys_siglist[SIGWINCH ] = "SIGWINCH"; -#endif -#ifdef SIGCONT - sys_siglist[SIGCONT ] = "SIGCONT"; -#endif -#ifdef SIGURG - sys_siglist[SIGURG ] = "SIGURG"; -#endif -#ifdef SIGIO - sys_siglist[SIGIO ] = "SIGIO"; -#endif -#ifdef SIGWIND - sys_siglist[SIGWIND ] = "SIGWIND"; -#endif -#ifdef SIGPHONE - sys_siglist[SIGPHONE ] = "SIGPHONE"; -#endif -#ifdef SIGPOLL - sys_siglist[SIGPOLL ] = "SIGPOLL"; -#endif -#endif /* USG */ -} |