X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Futils.c;h=e3e88dffae99a1647cbb9f56484808d583c15895;hb=fba45db2faf619e71856ee38ec63949c0ef6903e;hp=03f0aa4d99685ad1f3c51fc3e3e7eb4c5129b8a6;hpb=085dd6e638eca9d348100c8f0e8cae04e20d58a1;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/utils.c b/gdb/utils.c index 03f0aa4d99..e3e88dffae 100644 --- a/gdb/utils.c +++ b/gdb/utils.c @@ -1,28 +1,28 @@ /* General utility routines for GDB, the GNU debugger. - Copyright 1986, 89, 90, 91, 92, 95, 96, 1998 Free Software Foundation, Inc. + Copyright 1986, 1989, 1990-1992, 1995, 1996, 1998, 2000 + Free Software Foundation, Inc. -This file is part of GDB. + This file is part of GDB. -This program 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 2 of the License, or -(at your option) any later version. + This program 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 2 of the License, or + (at your option) any later version. -This program 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. + This program 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 this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ #include "defs.h" #include #include "gdb_string.h" -#ifdef HAVE_UNISTD_H -#include -#endif +#include "event-top.h" #ifdef HAVE_CURSES_H #include @@ -31,6 +31,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #endif +#ifdef __GO32__ +#include +#endif + /* SunOS's curses.h has a '#define reg register' in it. Thank you Sun. */ #ifdef reg #undef reg @@ -46,52 +50,55 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "language.h" #include "annotate.h" +#include "inferior.h" /* for signed_pointer_to_address */ + #include +#undef XMALLOC +#define XMALLOC(TYPE) ((TYPE*) xmalloc (sizeof (TYPE))) + /* readline defines this. */ #undef savestring -void (*error_begin_hook) PARAMS ((void)); +void (*error_begin_hook) (void); + +/* Holds the last error message issued by gdb */ + +static struct ui_file *gdb_lasterr; /* Prototypes for local functions */ -static void vfprintf_maybe_filtered PARAMS ((GDB_FILE *, const char *, - va_list, int)); +static void vfprintf_maybe_filtered (struct ui_file *, const char *, + va_list, int); -static void fputs_maybe_filtered PARAMS ((const char *, GDB_FILE *, int)); +static void fputs_maybe_filtered (const char *, struct ui_file *, int); #if defined (USE_MMALLOC) && !defined (NO_MMCHECK) -static void malloc_botch PARAMS ((void)); +static void malloc_botch (void); #endif -static void -fatal_dump_core PARAMS((char *, ...)); - -static void -prompt_for_continue PARAMS ((void)); - -static void -set_width_command PARAMS ((char *, int, struct cmd_list_element *)); - -static void -set_width PARAMS ((void)); +static void prompt_for_continue (void); -/* 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 +static void set_width_command (char *, int, struct cmd_list_element *); -#ifndef GDB_FILE_ISATTY -#define GDB_FILE_ISATTY(GDB_FILE_PTR) (gdb_file_isatty(GDB_FILE_PTR)) -#endif +static void set_width (void); /* Chain of cleanup actions established with make_cleanup, to be executed if an error happens. */ -static struct cleanup *cleanup_chain; /* cleaned up after a failed command */ -static struct cleanup *final_cleanup_chain; /* cleaned up when gdb exits */ -static struct cleanup *run_cleanup_chain; /* cleaned up on each 'run' */ +static struct cleanup *cleanup_chain; /* cleaned up after a failed command */ +static struct cleanup *final_cleanup_chain; /* cleaned up when gdb exits */ +static struct cleanup *run_cleanup_chain; /* cleaned up on each 'run' */ +static struct cleanup *exec_cleanup_chain; /* cleaned up on each execution command */ +/* cleaned up on each error from within an execution command */ +static struct cleanup *exec_error_cleanup_chain; + +/* Pointer to what is left to do for an execution command after the + target stops. Used only in asynchronous mode, by targets that + support async execution. The finish and until commands use it. So + does the target extended-remote command. */ +struct continuation *cmd_continuation; +struct continuation *intermediate_continuation; /* Nonzero if we have job control. */ @@ -144,59 +151,98 @@ char *quit_pre_print; char *warning_pre_print = "\nwarning: "; int pagination_enabled = 1; - + /* 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) PARAMS ((PTR)); - PTR arg; +make_cleanup (make_cleanup_ftype *function, void *arg) +{ + return make_my_cleanup (&cleanup_chain, function, arg); +} + +struct cleanup * +make_final_cleanup (make_cleanup_ftype *function, void *arg) +{ + return make_my_cleanup (&final_cleanup_chain, function, arg); +} + +struct cleanup * +make_run_cleanup (make_cleanup_ftype *function, void *arg) { - return make_my_cleanup (&cleanup_chain, function, arg); + return make_my_cleanup (&run_cleanup_chain, function, arg); } struct cleanup * -make_final_cleanup (function, arg) - void (*function) PARAMS ((PTR)); - PTR arg; +make_exec_cleanup (make_cleanup_ftype *function, void *arg) { - return make_my_cleanup (&final_cleanup_chain, function, arg); + return make_my_cleanup (&exec_cleanup_chain, function, arg); } struct cleanup * -make_run_cleanup (function, arg) - void (*function) PARAMS ((PTR)); - PTR arg; +make_exec_error_cleanup (make_cleanup_ftype *function, void *arg) { - return make_my_cleanup (&run_cleanup_chain, function, arg); + return make_my_cleanup (&exec_error_cleanup_chain, function, arg); } static void -do_freeargv (arg) - void *arg; +do_freeargv (void *arg) { - freeargv ((char**) arg); + freeargv ((char **) arg); } struct cleanup * -make_cleanup_freeargv (arg) - char **arg; +make_cleanup_freeargv (char **arg) { return make_my_cleanup (&cleanup_chain, do_freeargv, arg); } +static void +do_bfd_close_cleanup (void *arg) +{ + bfd_close (arg); +} + +struct cleanup * +make_cleanup_bfd_close (bfd *abfd) +{ + return make_cleanup (do_bfd_close_cleanup, abfd); +} + +static void +do_close_cleanup (void *arg) +{ + close ((int) arg); +} + +struct cleanup * +make_cleanup_close (int fd) +{ + /* int into void*. Outch!! */ + return make_cleanup (do_close_cleanup, (void *) fd); +} + +static void +do_ui_file_delete (void *arg) +{ + ui_file_delete (arg); +} + +struct cleanup * +make_cleanup_ui_file_delete (struct ui_file *arg) +{ + return make_my_cleanup (&cleanup_chain, do_ui_file_delete, arg); +} + struct cleanup * -make_my_cleanup (pmy_chain, function, arg) - struct cleanup **pmy_chain; - void (*function) PARAMS ((PTR)); - PTR arg; +make_my_cleanup (struct cleanup **pmy_chain, make_cleanup_ftype *function, + void *arg) { register struct cleanup *new - = (struct cleanup *) xmalloc (sizeof (struct cleanup)); + = (struct cleanup *) xmalloc (sizeof (struct cleanup)); register struct cleanup *old_chain = *pmy_chain; new->next = *pmy_chain; @@ -211,30 +257,38 @@ make_my_cleanup (pmy_chain, function, arg) until we get back to the point OLD_CHAIN in the cleanup_chain. */ void -do_cleanups (old_chain) - register struct cleanup *old_chain; +do_cleanups (register struct cleanup *old_chain) +{ + do_my_cleanups (&cleanup_chain, old_chain); +} + +void +do_final_cleanups (register struct cleanup *old_chain) +{ + do_my_cleanups (&final_cleanup_chain, old_chain); +} + +void +do_run_cleanups (register struct cleanup *old_chain) { - do_my_cleanups (&cleanup_chain, old_chain); + do_my_cleanups (&run_cleanup_chain, old_chain); } void -do_final_cleanups (old_chain) - register struct cleanup *old_chain; +do_exec_cleanups (register struct cleanup *old_chain) { - do_my_cleanups (&final_cleanup_chain, old_chain); + do_my_cleanups (&exec_cleanup_chain, old_chain); } void -do_run_cleanups (old_chain) - register struct cleanup *old_chain; +do_exec_error_cleanups (register struct cleanup *old_chain) { - do_my_cleanups (&run_cleanup_chain, old_chain); + do_my_cleanups (&exec_error_cleanup_chain, old_chain); } void -do_my_cleanups (pmy_chain, old_chain) - register struct cleanup **pmy_chain; - register struct cleanup *old_chain; +do_my_cleanups (register struct cleanup **pmy_chain, + register struct cleanup *old_chain) { register struct cleanup *ptr; while ((ptr = *pmy_chain) != old_chain) @@ -249,48 +303,50 @@ do_my_cleanups (pmy_chain, old_chain) until we get back to the point OLD_CHAIN in the cleanup_chain. */ void -discard_cleanups (old_chain) - register struct cleanup *old_chain; +discard_cleanups (register struct cleanup *old_chain) +{ + discard_my_cleanups (&cleanup_chain, old_chain); +} + +void +discard_final_cleanups (register struct cleanup *old_chain) { - discard_my_cleanups (&cleanup_chain, old_chain); + discard_my_cleanups (&final_cleanup_chain, old_chain); } void -discard_final_cleanups (old_chain) - register struct cleanup *old_chain; +discard_exec_error_cleanups (register struct cleanup *old_chain) { - discard_my_cleanups (&final_cleanup_chain, old_chain); + discard_my_cleanups (&exec_error_cleanup_chain, old_chain); } void -discard_my_cleanups (pmy_chain, old_chain) - register struct cleanup **pmy_chain; - register struct cleanup *old_chain; +discard_my_cleanups (register struct cleanup **pmy_chain, + register struct cleanup *old_chain) { register struct cleanup *ptr; while ((ptr = *pmy_chain) != old_chain) { *pmy_chain = ptr->next; - free ((PTR)ptr); + free (ptr); } } /* Set the cleanup_chain to 0, and return the old cleanup chain. */ struct cleanup * -save_cleanups () +save_cleanups (void) { - return save_my_cleanups (&cleanup_chain); + return save_my_cleanups (&cleanup_chain); } struct cleanup * -save_final_cleanups () +save_final_cleanups (void) { - return save_my_cleanups (&final_cleanup_chain); + return save_my_cleanups (&final_cleanup_chain); } struct cleanup * -save_my_cleanups (pmy_chain) - struct cleanup **pmy_chain; +save_my_cleanups (struct cleanup **pmy_chain) { struct cleanup *old_chain = *pmy_chain; @@ -300,23 +356,19 @@ save_my_cleanups (pmy_chain) /* Restore the cleanup chain from a previously saved chain. */ void -restore_cleanups (chain) - struct cleanup *chain; +restore_cleanups (struct cleanup *chain) { - restore_my_cleanups (&cleanup_chain, chain); + restore_my_cleanups (&cleanup_chain, chain); } void -restore_final_cleanups (chain) - struct cleanup *chain; +restore_final_cleanups (struct cleanup *chain) { - restore_my_cleanups (&final_cleanup_chain, chain); + restore_my_cleanups (&final_cleanup_chain, chain); } void -restore_my_cleanups (pmy_chain, chain) - struct cleanup **pmy_chain; - struct cleanup *chain; +restore_my_cleanups (struct cleanup **pmy_chain, struct cleanup *chain) { *pmy_chain = chain; } @@ -324,16 +376,22 @@ restore_my_cleanups (pmy_chain, chain) /* This function is useful for cleanups. Do - foo = xmalloc (...); - old_chain = make_cleanup (free_current_contents, &foo); + 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_current_contents (void *ptr) { - free (*location); + void **location = ptr; + if (location == NULL) + internal_error ("free_current_contents: NULL pointer"); + if (*location != NULL) + { + free (*location); + *location = NULL; + } } /* Provide a known function that does nothing, to use as a base for @@ -345,12 +403,136 @@ free_current_contents (location) /* ARGSUSED */ void -null_cleanup (arg) - PTR arg; +null_cleanup (void *arg) +{ +} + +/* Add a continuation to the continuation list, the gloabl list + cmd_continuation. The new continuation will be added at the front.*/ +void +add_continuation (continuation_hook, arg_list) + void (*continuation_hook) (struct continuation_arg *); + struct continuation_arg *arg_list; +{ + struct continuation *continuation_ptr; + + continuation_ptr = (struct continuation *) xmalloc (sizeof (struct continuation)); + continuation_ptr->continuation_hook = continuation_hook; + continuation_ptr->arg_list = arg_list; + continuation_ptr->next = cmd_continuation; + cmd_continuation = continuation_ptr; +} + +/* Walk down the cmd_continuation list, and execute all the + continuations. There is a problem though. In some cases new + continuations may be added while we are in the middle of this + loop. If this happens they will be added in the front, and done + before we have a chance of exhausting those that were already + there. We need to then save the beginning of the list in a pointer + and do the continuations from there on, instead of using the + global beginning of list as our iteration pointer.*/ +void +do_all_continuations (void) +{ + struct continuation *continuation_ptr; + struct continuation *saved_continuation; + + /* Copy the list header into another pointer, and set the global + list header to null, so that the global list can change as a side + effect of invoking the continuations and the processing of + the preexisting continuations will not be affected. */ + continuation_ptr = cmd_continuation; + cmd_continuation = NULL; + + /* Work now on the list we have set aside. */ + while (continuation_ptr) + { + (continuation_ptr->continuation_hook) (continuation_ptr->arg_list); + saved_continuation = continuation_ptr; + continuation_ptr = continuation_ptr->next; + free (saved_continuation); + } +} + +/* Walk down the cmd_continuation list, and get rid of all the + continuations. */ +void +discard_all_continuations (void) +{ + struct continuation *continuation_ptr; + + while (cmd_continuation) + { + continuation_ptr = cmd_continuation; + cmd_continuation = continuation_ptr->next; + free (continuation_ptr); + } +} + +/* Add a continuation to the continuation list, the global list + intermediate_continuation. The new continuation will be added at the front.*/ +void +add_intermediate_continuation (continuation_hook, arg_list) + void (*continuation_hook) (struct continuation_arg *); + struct continuation_arg *arg_list; +{ + struct continuation *continuation_ptr; + + continuation_ptr = (struct continuation *) xmalloc (sizeof (struct continuation)); + continuation_ptr->continuation_hook = continuation_hook; + continuation_ptr->arg_list = arg_list; + continuation_ptr->next = intermediate_continuation; + intermediate_continuation = continuation_ptr; +} + +/* Walk down the cmd_continuation list, and execute all the + continuations. There is a problem though. In some cases new + continuations may be added while we are in the middle of this + loop. If this happens they will be added in the front, and done + before we have a chance of exhausting those that were already + there. We need to then save the beginning of the list in a pointer + and do the continuations from there on, instead of using the + global beginning of list as our iteration pointer.*/ +void +do_all_intermediate_continuations (void) +{ + struct continuation *continuation_ptr; + struct continuation *saved_continuation; + + /* Copy the list header into another pointer, and set the global + list header to null, so that the global list can change as a side + effect of invoking the continuations and the processing of + the preexisting continuations will not be affected. */ + continuation_ptr = intermediate_continuation; + intermediate_continuation = NULL; + + /* Work now on the list we have set aside. */ + while (continuation_ptr) + { + (continuation_ptr->continuation_hook) (continuation_ptr->arg_list); + saved_continuation = continuation_ptr; + continuation_ptr = continuation_ptr->next; + free (saved_continuation); + } +} + +/* Walk down the cmd_continuation list, and get rid of all the + continuations. */ +void +discard_all_intermediate_continuations (void) { + struct continuation *continuation_ptr; + + while (intermediate_continuation) + { + continuation_ptr = intermediate_continuation; + intermediate_continuation = continuation_ptr->next; + free (continuation_ptr); + } } + /* Print a warning message. Way to use this is to call warning_begin, output the warning message (use unfiltered output to gdb_stderr), ending in a newline. There is not currently a warning_end that you @@ -361,10 +543,10 @@ null_cleanup (arg) Is this anything other than a historical accident? */ void -warning_begin () +warning_begin (void) { target_terminal_ours (); - wrap_here(""); /* Force out any buffered output */ + wrap_here (""); /* Force out any buffered output */ gdb_flush (gdb_stdout); if (warning_pre_print) fprintf_unfiltered (gdb_stderr, warning_pre_print); @@ -376,33 +558,20 @@ warning_begin () The primary difference between warnings and errors is that a warning does not force the return to command level. */ -/* VARARGS */ void -#ifdef ANSI_PROTOTYPES -warning (const char *string, ...) -#else -warning (va_alist) - va_dcl -#endif +warning (const char *string,...) { va_list args; -#ifdef ANSI_PROTOTYPES va_start (args, string); -#else - char *string; - - va_start (args); - string = va_arg (args, char *); -#endif if (warning_hook) (*warning_hook) (string, args); else - { - warning_begin (); - vfprintf_unfiltered (gdb_stderr, string, args); - fprintf_unfiltered (gdb_stderr, "\n"); - va_end (args); - } + { + warning_begin (); + vfprintf_unfiltered (gdb_stderr, string, args); + fprintf_unfiltered (gdb_stderr, "\n"); + va_end (args); + } } /* Start the printing of an error message. Way to use this is to call @@ -413,13 +582,13 @@ warning (va_alist) that the error message can be formatted with a single printf call, but this is more general. */ void -error_begin () +error_begin (void) { if (error_begin_hook) error_begin_hook (); target_terminal_ours (); - wrap_here (""); /* Force out any buffered output */ + wrap_here (""); /* Force out any buffered output */ gdb_flush (gdb_stdout); annotate_error_begin (); @@ -432,154 +601,167 @@ error_begin () The first argument STRING is the error message, used as a fprintf string, and the remaining args are passed as arguments to it. */ -/* VARARGS */ NORETURN void -#ifdef ANSI_PROTOTYPES -error (const char *string, ...) -#else -error (va_alist) - va_dcl -#endif -{ - va_list args; -#ifdef ANSI_PROTOTYPES - va_start (args, string); -#else - va_start (args); -#endif - if (error_hook) - (*error_hook) (); - else - { - error_begin (); -#ifdef ANSI_PROTOTYPES - vfprintf_filtered (gdb_stderr, string, args); -#else - { - char *string1; - - string1 = va_arg (args, char *); - vfprintf_filtered (gdb_stderr, string1, args); - } -#endif - fprintf_filtered (gdb_stderr, "\n"); - va_end (args); - return_to_top_level (RETURN_ERROR); - } +verror (const char *string, va_list args) +{ + char *err_string; + struct cleanup *err_string_cleanup; + /* FIXME: cagney/1999-11-10: All error calls should come here. + Unfortunatly some code uses the sequence: error_begin(); print + error message; return_to_top_level. That code should be + flushed. */ + error_begin (); + /* NOTE: It's tempting to just do the following... + vfprintf_filtered (gdb_stderr, string, args); + and then follow with a similar looking statement to cause the message + to also go to gdb_lasterr. But if we do this, we'll be traversing the + va_list twice which works on some platforms and fails miserably on + others. */ + /* Save it as the last error */ + ui_file_rewind (gdb_lasterr); + vfprintf_filtered (gdb_lasterr, string, args); + /* Retrieve the last error and print it to gdb_stderr */ + err_string = error_last_message (); + err_string_cleanup = make_cleanup (free, err_string); + fputs_filtered (err_string, gdb_stderr); + fprintf_filtered (gdb_stderr, "\n"); + do_cleanups (err_string_cleanup); + return_to_top_level (RETURN_ERROR); } - -/* Print an error message and exit reporting failure. - This is for a error that we cannot continue from. - The arguments are printed a la printf. - - This function cannot be declared volatile (NORETURN) in an - ANSI environment because exit() is not declared volatile. */ - -/* VARARGS */ NORETURN void -#ifdef ANSI_PROTOTYPES -fatal (char *string, ...) -#else -fatal (va_alist) - va_dcl -#endif +error (const char *string,...) { va_list args; -#ifdef ANSI_PROTOTYPES va_start (args, string); -#else - char *string; - va_start (args); - string = va_arg (args, char *); -#endif - fprintf_unfiltered (gdb_stderr, "\ngdb: "); - vfprintf_unfiltered (gdb_stderr, string, args); - fprintf_unfiltered (gdb_stderr, "\n"); + verror (string, args); va_end (args); - exit (1); } -/* Print an error message and exit, dumping core. - The arguments are printed a la printf (). */ - -/* VARARGS */ -static void -#ifdef ANSI_PROTOTYPES -fatal_dump_core (char *string, ...) -#else -fatal_dump_core (va_alist) - va_dcl -#endif +NORETURN void +error_stream (struct ui_file *stream) { - va_list args; -#ifdef ANSI_PROTOTYPES - va_start (args, string); -#else - char *string; + long size; + char *msg = ui_file_xstrdup (stream, &size); + make_cleanup (free, msg); + error ("%s", msg); +} - va_start (args); - string = va_arg (args, char *); -#endif - /* "internal error" is always correct, since GDB should never dump - core, no matter what the input. */ - fprintf_unfiltered (gdb_stderr, "\ngdb internal error: "); - vfprintf_unfiltered (gdb_stderr, string, args); - fprintf_unfiltered (gdb_stderr, "\n"); - va_end (args); +/* Get the last error message issued by gdb */ - signal (SIGQUIT, SIG_DFL); - kill (getpid (), SIGQUIT); - /* We should never get here, but just in case... */ - exit (1); +char * +error_last_message (void) +{ + long len; + return ui_file_xstrdup (gdb_lasterr, &len); } + +/* This is to be called by main() at the very beginning */ -/* The strerror() function can return NULL for errno values that are - out of range. Provide a "safe" version that always returns a - printable string. */ +void +error_init (void) +{ + gdb_lasterr = mem_fileopen (); +} -char * -safe_strerror (errnum) - int errnum; +/* Print a message reporting an internal error. Ask the user if they + want to continue, dump core, or just exit. */ + +NORETURN void +internal_verror (const char *fmt, va_list ap) { - char *msg; - static char buf[32]; + static char msg[] = "Internal GDB error: recursive internal error.\n"; + static int dejavu = 0; + int continue_p; + int dump_core_p; - if ((msg = strerror (errnum)) == NULL) + /* don't allow infinite error recursion. */ + switch (dejavu) { - sprintf (buf, "(undocumented errno %d)", errnum); - msg = buf; + case 0: + dejavu = 1; + break; + case 1: + dejavu = 2; + fputs_unfiltered (msg, gdb_stderr); + abort (); + default: + dejavu = 3; + write (STDERR_FILENO, msg, sizeof (msg)); + exit (1); } - return (msg); + + /* Try to get the message out */ + target_terminal_ours (); + fputs_unfiltered ("gdb-internal-error: ", gdb_stderr); + vfprintf_unfiltered (gdb_stderr, fmt, ap); + fputs_unfiltered ("\n", gdb_stderr); + + /* Default (no case) is to quit GDB. When in batch mode this + lessens the likelhood of GDB going into an infinate loop. */ + continue_p = query ("\ +An internal GDB error was detected. This may make make further\n\ +debugging unreliable. Continue this debugging session? "); + + /* Default (no case) is to not dump core. Lessen the chance of GDB + leaving random core files around. */ + dump_core_p = query ("\ +Create a core file containing the current state of GDB? "); + + if (continue_p) + { + if (dump_core_p) + { + if (fork () == 0) + abort (); + } + } + else + { + if (dump_core_p) + abort (); + else + exit (1); + } + + dejavu = 0; + return_to_top_level (RETURN_ERROR); +} + +NORETURN void +internal_error (char *string, ...) +{ + va_list ap; + va_start (ap, string); + + internal_verror (string, ap); + va_end (ap); } -/* The strsignal() function can return NULL for signal values that are +/* The strerror() function can return NULL for errno values that are out of range. Provide a "safe" version that always returns a printable string. */ char * -safe_strsignal (signo) - int signo; +safe_strerror (int errnum) { char *msg; static char buf[32]; - if ((msg = strsignal (signo)) == NULL) + if ((msg = strerror (errnum)) == NULL) { - sprintf (buf, "(undocumented signal %d)", signo); + sprintf (buf, "(undocumented errno %d)", errnum); msg = buf; } return (msg); } - /* 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. */ NORETURN void -perror_with_name (string) - char *string; +perror_with_name (char *string) { char *err; char *combined; @@ -596,16 +778,14 @@ perror_with_name (string) bfd_set_error (bfd_error_no_error); errno = 0; - error ("%s.", combined); + 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; +print_sys_errmsg (char *string, int errcode) { char *err; char *combined; @@ -625,7 +805,7 @@ print_sys_errmsg (string, errcode) /* Control C eventually causes this to be called, at a convenient time. */ void -quit () +quit (void) { serial_t gdb_stdout_serial = serial_fdopen (1); @@ -637,7 +817,7 @@ quit () too): */ /* 1. The _filtered buffer. */ - wrap_here ((char *)0); + wrap_here ((char *) 0); /* 2. The stdio buffer. */ gdb_flush (gdb_stdout); @@ -653,44 +833,25 @@ quit () if (quit_pre_print) fprintf_unfiltered (gdb_stderr, quit_pre_print); +#ifdef __MSDOS__ + /* No steenking SIGINT will ever be coming our way when the + program is resumed. Don't lie. */ + fprintf_unfiltered (gdb_stderr, "Quit\n"); +#else if (job_control - /* If there is no terminal switching for this target, then we can't - possibly get screwed by the lack of job control. */ + /* If there is no terminal switching for this target, then we can't + possibly get screwed by the lack of job control. */ || current_target.to_terminal_ours == NULL) fprintf_unfiltered (gdb_stderr, "Quit\n"); else fprintf_unfiltered (gdb_stderr, - "Quit (expect signal SIGINT when the program is resumed)\n"); + "Quit (expect signal SIGINT when the program is resumed)\n"); +#endif return_to_top_level (RETURN_QUIT); } -#if defined(__GO32__) - -/* In the absence of signals, poll keyboard for a quit. - Called from #define QUIT pollquit() in xm-go32.h. */ - -void -notice_quit() -{ - if (kbhit ()) - switch (getkey ()) - { - case 1: - quit_flag = 1; - break; - case 2: - immediate_quit = 2; - break; - default: - /* We just ignore it */ - /* FIXME!! Don't think this actually works! */ - fprintf_unfiltered (gdb_stderr, "CTRL-A to quit, CTRL-B to quit harder\n"); - break; - } -} - -#elif defined(_MSC_VER) /* should test for wingdb instead? */ +#if defined(_MSC_VER) /* should test for wingdb instead? */ /* * Windows translates all keyboard and mouse events @@ -698,28 +859,29 @@ notice_quit() * queue for the process. */ -void notice_quit() +void +notice_quit (void) { - int k = win32pollquit(); + int k = win32pollquit (); if (k == 1) quit_flag = 1; else if (k == 2) immediate_quit = 1; } -#else /* !defined(__GO32__) && !defined(_MSC_VER) */ +#else /* !defined(_MSC_VER) */ -void notice_quit() +void +notice_quit (void) { /* Done by signals */ } -#endif /* !defined(__GO32__) && !defined(_MSC_VER) */ +#endif /* !defined(_MSC_VER) */ /* Control C comes here */ void -request_quit (signo) - int signo; +request_quit (int signo) { quit_flag = 1; /* Restore the signal handler. Harmless with BSD-style signals, needed @@ -730,7 +892,7 @@ request_quit (signo) #ifdef REQUEST_QUIT REQUEST_QUIT; #else - if (immediate_quit) + if (immediate_quit) quit (); #endif } @@ -748,49 +910,48 @@ request_quit (signo) #if !defined (USE_MMALLOC) PTR -mmalloc (md, size) - PTR md; - size_t size; +mcalloc (PTR md, size_t number, size_t size) +{ + return calloc (number, size); +} + +PTR +mmalloc (PTR md, size_t size) { return malloc (size); } PTR -mrealloc (md, ptr, size) - PTR md; - PTR ptr; - size_t size; +mrealloc (PTR md, PTR ptr, size_t size) { - if (ptr == 0) /* Guard against old realloc's */ + if (ptr == 0) /* Guard against old realloc's */ return malloc (size); else return realloc (ptr, size); } void -mfree (md, ptr) - PTR md; - PTR ptr; +mfree (PTR md, PTR ptr) { free (ptr); } -#endif /* USE_MMALLOC */ +#endif /* USE_MMALLOC */ #if !defined (USE_MMALLOC) || defined (NO_MMCHECK) void -init_malloc (md) - PTR md; +init_malloc (void *md) { } #else /* Have mmalloc and want corruption checking */ static void -malloc_botch () +malloc_botch (void) { - fatal_dump_core ("Memory corruption"); + fprintf_unfiltered (gdb_stderr, "Memory corruption\n"); + abort (); } /* Attempt to install hooks in mmalloc/mrealloc/mfree for the heap specified @@ -812,14 +973,13 @@ malloc_botch () #endif void -init_malloc (md) - PTR md; +init_malloc (void *md) { if (!mmcheckf (md, malloc_botch, MMCHECK_FORCE)) { /* Don't use warning(), which relies on current_target being set - to something other than dummy_target, until after - initialize_all_files(). */ + to something other than dummy_target, until after + initialize_all_files(). */ fprintf_unfiltered (gdb_stderr, "warning: failed to install memory consistency checks; "); @@ -836,16 +996,15 @@ init_malloc (md) memory requested in SIZE. */ NORETURN void -nomem (size) - long size; +nomem (long size) { if (size > 0) { - fatal ("virtual memory exhausted: can't allocate %ld bytes.", size); + internal_error ("virtual memory exhausted: can't allocate %ld bytes.", size); } else { - fatal ("virtual memory exhausted."); + internal_error ("virtual memory exhausted."); } } @@ -855,9 +1014,7 @@ nomem (size) byte of zero'd storage, is a religious issue. */ PTR -xmmalloc (md, size) - PTR md; - long size; +xmmalloc (PTR md, long size) { register PTR val; @@ -875,10 +1032,7 @@ xmmalloc (md, size) /* Like mrealloc but get error if no storage available. */ PTR -xmrealloc (md, ptr, size) - PTR md; - PTR ptr; - long size; +xmrealloc (PTR md, PTR ptr, long size) { register PTR val; @@ -901,31 +1055,36 @@ xmrealloc (md, ptr, size) the caller wanting to allocate zero bytes. */ PTR -xmalloc (size) - size_t size; +xmalloc (size_t size) { return (xmmalloc ((PTR) NULL, size)); } +/* Like calloc but get error if no storage available */ + +PTR +xcalloc (size_t number, size_t size) +{ + void *mem = mcalloc (NULL, number, size); + if (mem == NULL) + nomem (number * size); + return mem; +} + /* Like mrealloc but get error if no storage available. */ PTR -xrealloc (ptr, size) - PTR ptr; - size_t size; +xrealloc (PTR ptr, size_t size) { return (xmrealloc ((PTR) NULL, ptr, size)); } - + /* My replacement for the read system call. Used like `read' but keeps going if `read' returns too soon. */ int -myread (desc, addr, len) - int desc; - char *addr; - int len; +myread (int desc, char *addr, int len) { register int val; int orglen = len; @@ -948,9 +1107,7 @@ myread (desc, addr, len) Uses malloc to get the space. Returns the address of the copy. */ char * -savestring (ptr, size) - const char *ptr; - int size; +savestring (const char *ptr, int size) { register char *p = (char *) xmalloc (size + 1); memcpy (p, ptr, size); @@ -959,10 +1116,7 @@ savestring (ptr, size) } char * -msavestring (md, ptr, size) - PTR md; - const char *ptr; - int size; +msavestring (void *md, const char *ptr, int size) { register char *p = (char *) xmmalloc (md, size + 1); memcpy (p, ptr, size); @@ -974,24 +1128,19 @@ msavestring (md, ptr, size) in . FIXME: This should be named "xstrsave", shouldn't it? Doesn't real strsave return NULL if out of memory? */ char * -strsave (ptr) - const char *ptr; +strsave (const char *ptr) { return savestring (ptr, strlen (ptr)); } char * -mstrsave (md, ptr) - PTR md; - const char *ptr; +mstrsave (void *md, const char *ptr) { return (msavestring (md, ptr, strlen (ptr))); } void -print_spaces (n, file) - register int n; - register GDB_FILE *file; +print_spaces (register int n, register struct ui_file *file) { fputs_unfiltered (n_spaces (n), file); } @@ -999,16 +1148,14 @@ print_spaces (n, file) /* Print a host address. */ void -gdb_print_address (addr, stream) - PTR addr; - GDB_FILE *stream; +gdb_print_host_address (void *addr, struct ui_file *stream) { /* We could use the %p conversion specifier to fprintf if we had any way of knowing whether this host supports it. But the following should work on the Alpha and on 32 bit machines. */ - fprintf_filtered (stream, "0x%lx", (unsigned long)addr); + fprintf_filtered (stream, "0x%lx", (unsigned long) addr); } /* Ask user a y-or-n question and return 1 iff answer is yes. @@ -1018,25 +1165,14 @@ gdb_print_address (addr, stream) /* VARARGS */ int -#ifdef ANSI_PROTOTYPES -query (char *ctlstr, ...) -#else -query (va_alist) - va_dcl -#endif +query (char *ctlstr,...) { va_list args; register int answer; register int ans2; int retval; -#ifdef ANSI_PROTOTYPES va_start (args, ctlstr); -#else - char *ctlstr; - va_start (args); - ctlstr = va_arg (args, char *); -#endif if (query_hook) { @@ -1068,47 +1204,45 @@ query (va_alist) #ifdef MPW /* If not in MacGDB, move to a new line so the entered line doesn't - have a prompt on the front of it. */ + have a prompt on the front of it. */ if (!mac_app) fputs_unfiltered ("\n", gdb_stdout); #endif /* MPW */ - wrap_here(""); + wrap_here (""); gdb_flush (gdb_stdout); #if defined(TUI) - if (!tui_version || cmdWin == tuiWinWithFocus()) + if (!tui_version || cmdWin == tuiWinWithFocus ()) #endif answer = fgetc (stdin); #if defined(TUI) else - - answer = (unsigned char)tuiBufferGetc(); + answer = (unsigned char) tuiBufferGetc (); #endif clearerr (stdin); /* in case of C-d */ if (answer == EOF) /* C-d */ - { + { retval = 1; break; } /* Eat rest of input line, to EOF or newline */ if ((answer != '\n') || (tui_version && answer != '\r')) - do + do { #if defined(TUI) - if (!tui_version || cmdWin == tuiWinWithFocus()) + if (!tui_version || cmdWin == tuiWinWithFocus ()) #endif ans2 = fgetc (stdin); #if defined(TUI) else - - ans2 = (unsigned char)tuiBufferGetc(); + ans2 = (unsigned char) tuiBufferGetc (); #endif clearerr (stdin); } - while (ans2 != EOF && ans2 != '\n' && ans2 != '\r'); - TUIDO(((TuiOpaqueFuncPtr)tui_vStartNewLines, 1)); + while (ans2 != EOF && ans2 != '\n' && ans2 != '\r'); + TUIDO (((TuiOpaqueFuncPtr) tui_vStartNewLines, 1)); if (answer >= 'a') answer -= 040; @@ -1129,8 +1263,8 @@ query (va_alist) printf_filtered ("\n\032\032post-query\n"); return retval; } - + /* Parse a C escape sequence. STRING_PTR points to a variable containing a pointer to the string to parse. That pointer should point to the character after the \. That pointer @@ -1147,8 +1281,7 @@ query (va_alist) after the zeros. A value of 0 does not mean end of string. */ int -parse_escape (string_ptr) - char **string_ptr; +parse_escape (char **string_ptr) { register int c = *(*string_ptr)++; switch (c) @@ -1181,7 +1314,7 @@ parse_escape (string_ptr) if (c == '?') return 0177; return (c & 0200) | (c & 037); - + case '0': case '1': case '2': @@ -1218,56 +1351,91 @@ parse_escape (string_ptr) be call for printing things which are independent of the language of the program being debugged. */ -void -gdb_printchar (c, stream, quoter) - register int c; - GDB_FILE *stream; +static void printchar (int c, void (*do_fputs) (const char *, struct ui_file*), void (*do_fprintf) (struct ui_file*, const char *, ...), struct ui_file *stream, int quoter); + +static void +printchar (c, do_fputs, do_fprintf, stream, quoter) + int c; + void (*do_fputs) (const char *, struct ui_file *); + void (*do_fprintf) (struct ui_file *, const char *, ...); + struct ui_file *stream; int quoter; { c &= 0xFF; /* Avoid sign bit follies */ - if ( c < 0x20 || /* Low control chars */ - (c >= 0x7F && c < 0xA0) || /* DEL, High controls */ - (sevenbit_strings && c >= 0x80)) { /* high order bit set */ - 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); - } + if (c < 0x20 || /* Low control chars */ + (c >= 0x7F && c < 0xA0) || /* DEL, High controls */ + (sevenbit_strings && c >= 0x80)) + { /* high order bit set */ + switch (c) + { + case '\n': + do_fputs ("\\n", stream); + break; + case '\b': + do_fputs ("\\b", stream); + break; + case '\t': + do_fputs ("\\t", stream); + break; + case '\f': + do_fputs ("\\f", stream); + break; + case '\r': + do_fputs ("\\r", stream); + break; + case '\033': + do_fputs ("\\e", stream); + break; + case '\007': + do_fputs ("\\a", stream); + break; + default: + do_fprintf (stream, "\\%.3o", (unsigned int) c); + break; + } + } + else + { + if (c == '\\' || c == quoter) + do_fputs ("\\", stream); + do_fprintf (stream, "%c", c); + } +} + +/* Print the character C on STREAM as part of the contents of a + literal string whose delimiter is QUOTER. Note that these routines + should only be call for printing things which are independent of + the language of the program being debugged. */ + +void +fputstr_filtered (const char *str, int quoter, struct ui_file *stream) +{ + while (*str) + printchar (*str++, fputs_filtered, fprintf_filtered, stream, quoter); +} + +void +fputstr_unfiltered (const char *str, int quoter, struct ui_file *stream) +{ + while (*str) + printchar (*str++, fputs_unfiltered, fprintf_unfiltered, stream, quoter); +} + +void +fputstrn_unfiltered (const char *str, int n, int quoter, struct ui_file *stream) +{ + int i; + for (i = 0; i < n; i++) + printchar (str[i], fputs_unfiltered, fprintf_unfiltered, stream, quoter); } + /* Number of lines per page or UINT_MAX if paging is disabled. */ static unsigned int lines_per_page; -/* Number of chars per line or UNIT_MAX is line folding is disabled. */ +/* Number of chars per line or UINT_MAX if line folding is disabled. */ static unsigned int chars_per_line; /* Current count of lines printed on this page, chars on this line. */ static unsigned int lines_printed, chars_printed; @@ -1295,14 +1463,14 @@ static char *wrap_indent; /* Column number on the screen where wrap_buffer begins, or 0 if wrapping is not in effect. */ static int wrap_column; - + /* Inialize the lines and chars per page */ void -init_page_info() +init_page_info (void) { #if defined(TUI) - if (tui_version && m_winPtrNotNull(cmdWin)) + if (tui_version && m_winPtrNotNull (cmdWin)) { lines_per_page = cmdWin->generic.height; chars_per_line = cmdWin->generic.width; @@ -1313,9 +1481,9 @@ init_page_info() /* These defaults will be used if we are unable to get the correct values from termcap. */ #if defined(__GO32__) - lines_per_page = ScreenRows(); - chars_per_line = ScreenCols(); -#else + lines_per_page = ScreenRows (); + chars_per_line = ScreenCols (); +#else lines_per_page = 24; chars_per_line = 80; @@ -1324,38 +1492,38 @@ init_page_info() by looking at worksheet or console window sizes. */ /* Initialize the screen height and width from termcap. */ { - char *termtype = getenv ("TERM"); + char *termtype = getenv ("TERM"); - /* Positive means success, nonpositive means failure. */ - int status; + /* 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]; + /* 2048 is large enough for all known terminals, according to the + GNU termcap manual. */ + char term_buffer[2048]; - if (termtype) - { + if (termtype) + { status = tgetent (term_buffer, termtype); if (status > 0) { - int val; + int val; int running_in_emacs = getenv ("EMACS") != NULL; - - val = tgetnum ("li"); - if (val >= 0 && !running_in_emacs) - lines_per_page = val; - else - /* The number of lines per page is not mentioned + + val = tgetnum ("li"); + if (val >= 0 && !running_in_emacs) + 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 = UINT_MAX; - - val = tgetnum ("co"); - if (val >= 0) - chars_per_line = val; + lines_per_page = UINT_MAX; + + val = tgetnum ("co"); + if (val >= 0) + chars_per_line = val; } - } + } } #endif /* MPW */ @@ -1366,17 +1534,17 @@ init_page_info() #endif #endif /* If the output is not a terminal, don't paginate it. */ - if (!GDB_FILE_ISATTY (gdb_stdout)) - lines_per_page = UINT_MAX; - } /* the command_line_version */ - set_width(); + if (!ui_file_isatty (gdb_stdout)) + lines_per_page = UINT_MAX; + } /* the command_line_version */ + set_width (); } static void -set_width() +set_width (void) { if (chars_per_line == 0) - init_page_info(); + init_page_info (); if (!wrap_buffer) { @@ -1385,15 +1553,12 @@ set_width() } else wrap_buffer = (char *) xrealloc (wrap_buffer, chars_per_line + 2); - wrap_pointer = wrap_buffer; /* Start it at the beginning */ + wrap_pointer = wrap_buffer; /* Start it at the beginning */ } /* ARGSUSED */ -static void -set_width_command (args, from_tty, c) - char *args; - int from_tty; - struct cmd_list_element *c; +static void +set_width_command (char *args, int from_tty, struct cmd_list_element *c) { set_width (); } @@ -1402,7 +1567,7 @@ set_width_command (args, from_tty, c) to continue by pressing RETURN. */ static void -prompt_for_continue () +prompt_for_continue (void) { char *ignore; char cont_prompt[120]; @@ -1443,10 +1608,10 @@ prompt_for_continue () ++p; if (p[0] == 'q') { - if (!async_p) + if (!event_loop_p) request_quit (SIGINT); else - async_request_quit (0); + async_request_quit (0); } free (ignore); } @@ -1462,7 +1627,7 @@ prompt_for_continue () /* Reinitialize filter; ie. tell it to reset to original values. */ void -reinitialize_more_filter () +reinitialize_more_filter (void) { lines_printed = 0; chars_printed = 0; @@ -1490,8 +1655,7 @@ reinitialize_more_filter () used to force out output from the wrap_buffer. */ void -wrap_here(indent) - char *indent; +wrap_here (char *indent) { /* This should have been allocated, but be paranoid anyway. */ if (!wrap_buffer) @@ -1504,7 +1668,7 @@ wrap_here(indent) } wrap_pointer = wrap_buffer; wrap_buffer[0] = '\0'; - if (chars_per_line == UINT_MAX) /* No line overflow checking */ + if (chars_per_line == UINT_MAX) /* No line overflow checking */ { wrap_column = 0; } @@ -1531,7 +1695,7 @@ wrap_here(indent) line. Otherwise do nothing. */ void -begin_line () +begin_line (void) { if (chars_printed > 0) { @@ -1540,476 +1704,6 @@ begin_line () } -/* ``struct gdb_file'' implementation that maps directly onto - 's FILE. */ - -static gdb_file_fputs_ftype stdio_file_fputs; -static gdb_file_isatty_ftype stdio_file_isatty; -static gdb_file_delete_ftype stdio_file_delete; -static struct gdb_file *stdio_file_new PARAMS ((FILE *file, int close_p)); -static gdb_file_flush_ftype stdio_file_flush; - -static int stdio_file_magic; - -struct stdio_file -{ - int *magic; - FILE *file; - int close_p; -}; - -static struct gdb_file * -stdio_file_new (file, close_p) - FILE *file; - int close_p; -{ - struct gdb_file *gdb_file = gdb_file_new (); - struct stdio_file *stdio = xmalloc (sizeof (struct stdio_file)); - stdio->magic = &stdio_file_magic; - stdio->file = file; - stdio->close_p = close_p; - set_gdb_file_data (gdb_file, stdio, stdio_file_delete); - set_gdb_file_flush (gdb_file, stdio_file_flush); - set_gdb_file_fputs (gdb_file, stdio_file_fputs); - set_gdb_file_isatty (gdb_file, stdio_file_isatty); - return gdb_file; -} - -static void -stdio_file_delete (file) - struct gdb_file *file; -{ - struct stdio_file *stdio = gdb_file_data (file); - if (stdio->magic != &stdio_file_magic) - error ("Internal error: bad magic number"); - if (stdio->close_p) - { - fclose (stdio->file); - } - free (stdio); -} - -static void -stdio_file_flush (file) - struct gdb_file *file; -{ - struct stdio_file *stdio = gdb_file_data (file); - if (stdio->magic != &stdio_file_magic) - error ("Internal error: bad magic number"); - fflush (stdio->file); -} - -static void -stdio_file_fputs (linebuffer, file) - const char *linebuffer; - struct gdb_file *file; -{ - struct stdio_file *stdio = gdb_file_data (file); - if (stdio->magic != &stdio_file_magic) - error ("Internal error: bad magic number"); - fputs (linebuffer, stdio->file); -} - -static int -stdio_file_isatty (file) - struct gdb_file *file; -{ - struct stdio_file *stdio = gdb_file_data (file); - if (stdio->magic != &stdio_file_magic) - error ("Internal error: bad magic number"); - return (isatty (fileno (stdio->file))); -} - -/* Like fdopen(). Create a gdb_file from a previously opened FILE. */ - -struct gdb_file * -stdio_fileopen (file) - FILE *file; -{ - return stdio_file_new (file, 0); -} - - -/* A ``struct gdb_file'' that is compatible with all the legacy - code. */ - -static gdb_file_flush_ftype tui_file_flush; -extern gdb_file_fputs_ftype tui_file_fputs; -static gdb_file_isatty_ftype tui_file_isatty; -static gdb_file_rewind_ftype tui_file_rewind; -static gdb_file_put_ftype tui_file_put; -static gdb_file_delete_ftype tui_file_delete; -static struct gdb_file *tui_file_new PARAMS ((void)); -static int tui_file_magic; - -static struct gdb_file * -tui_file_new () -{ - struct tui_stream *tui = xmalloc (sizeof (struct tui_stream)); - struct gdb_file *file = gdb_file_new (); - set_gdb_file_data (file, tui, tui_file_delete); - set_gdb_file_flush (file, tui_file_flush); - set_gdb_file_fputs (file, tui_file_fputs); - set_gdb_file_isatty (file, tui_file_isatty); - set_gdb_file_rewind (file, tui_file_rewind); - set_gdb_file_put (file, tui_file_put); - tui->ts_magic = &tui_file_magic; - return file; -} - -static void -tui_file_delete (file) - struct gdb_file *file; -{ - struct tui_stream *tmpstream = gdb_file_data (file); - if (tmpstream->ts_magic != &tui_file_magic) - error ("Internal error: bad magic number"); - if ((tmpstream->ts_streamtype == astring) && - (tmpstream->ts_strbuf != NULL)) - { - free (tmpstream->ts_strbuf); - } - free (tmpstream); -} - -struct gdb_file * -tui_fileopen (stream) - FILE *stream; -{ - struct gdb_file *file = tui_file_new (); - struct tui_stream *tmpstream = gdb_file_data (file); - tmpstream->ts_streamtype = afile; - tmpstream->ts_filestream = stream; - tmpstream->ts_strbuf = NULL; - tmpstream->ts_buflen = 0; - return file; -} - -static int -tui_file_isatty (file) - struct gdb_file *file; -{ - struct tui_stream *stream = gdb_file_data (file); - if (stream->ts_magic != &tui_file_magic) - error ("Internal error: bad magic number"); - if (stream->ts_streamtype == afile) - return (isatty(fileno(stream->ts_filestream))); - else return 0; -} - -static void -tui_file_rewind (file) - struct gdb_file *file; -{ - struct tui_stream *stream = gdb_file_data (file); - if (stream->ts_magic != &tui_file_magic) - error ("Internal error: bad magic number"); - stream->ts_strbuf[0] = '\0'; -} - -static void -tui_file_put (file, dest) - struct gdb_file *file; - struct gdb_file *dest; -{ - struct tui_stream *stream = gdb_file_data (file); - if (stream->ts_magic != &tui_file_magic) - error ("Internal error: bad magic number"); - if (stream->ts_streamtype == astring) - { - fputs_unfiltered (stream->ts_strbuf, dest); - } -} - -GDB_FILE * -gdb_file_init_astring (n) - int n; -{ - struct gdb_file *file = tui_file_new (); - struct tui_stream *tmpstream = gdb_file_data (file); - if (tmpstream->ts_magic != &tui_file_magic) - error ("Internal error: bad magic number"); - - tmpstream->ts_streamtype = astring; - tmpstream->ts_filestream = NULL; - if (n > 0) - { - tmpstream->ts_strbuf = xmalloc ((n + 1)*sizeof(char)); - tmpstream->ts_strbuf[0] = '\0'; - } - else - tmpstream->ts_strbuf = NULL; - tmpstream->ts_buflen = n; - - return file; -} - -void -gdb_file_deallocate (streamptr) - GDB_FILE **streamptr; -{ - gdb_file_delete (*streamptr); - *streamptr = NULL; -} - -char * -gdb_file_get_strbuf (file) - GDB_FILE *file; -{ - struct tui_stream *stream = gdb_file_data (file); - if (stream->ts_magic != &tui_file_magic) - error ("Internal error: bad magic number"); - return (stream->ts_strbuf); -} - -/* adjust the length of the buffer by the amount necessary - to accomodate appending a string of length N to the buffer contents */ -void -gdb_file_adjust_strbuf (n, file) - int n; - GDB_FILE *file; -{ - struct tui_stream *stream = gdb_file_data (file); - int non_null_chars; - if (stream->ts_magic != &tui_file_magic) - error ("Internal error: bad magic number"); - - if (stream->ts_streamtype != astring) - return; - - if (stream->ts_strbuf) - { - /* There is already a buffer allocated */ - non_null_chars = strlen(stream->ts_strbuf); - - if (n > (stream->ts_buflen - non_null_chars - 1)) - { - stream->ts_buflen = n + non_null_chars + 1; - stream->ts_strbuf = xrealloc (stream->ts_strbuf, stream->ts_buflen); - } - } - else - /* No buffer yet, so allocate one of the desired size */ - stream->ts_strbuf = xmalloc ((n + 1) * sizeof (char)); -} - -GDB_FILE * -gdb_fopen (name, mode) - char * name; - char * mode; -{ - FILE *f = fopen (name, mode); - if (f == NULL) - return NULL; - return stdio_file_new (f, 1); -} - -static void -tui_file_flush (file) - GDB_FILE *file; -{ - struct tui_stream *stream = gdb_file_data (file); - if (stream->ts_magic != &tui_file_magic) - error ("Internal error: bad magic number"); - if (flush_hook - && (file == gdb_stdout - || file == gdb_stderr)) - { - flush_hook (file); - return; - } - - fflush (stream->ts_filestream); -} - -void -gdb_fclose(streamptr) - GDB_FILE **streamptr; -{ - gdb_file_delete (*streamptr); - *streamptr = NULL; -} - - -/* Implement the ``struct gdb_file'' object. */ - -static gdb_file_isatty_ftype null_file_isatty; -static gdb_file_fputs_ftype null_file_fputs; -static gdb_file_flush_ftype null_file_flush; -static gdb_file_delete_ftype null_file_delete; -static gdb_file_rewind_ftype null_file_rewind; -static gdb_file_put_ftype null_file_put; - -struct gdb_file -{ - gdb_file_flush_ftype *to_flush; - gdb_file_fputs_ftype *to_fputs; - gdb_file_delete_ftype *to_delete; - gdb_file_isatty_ftype *to_isatty; - gdb_file_rewind_ftype *to_rewind; - gdb_file_put_ftype *to_put; - void *to_data; -}; - -struct gdb_file * -gdb_file_new () -{ - struct gdb_file *file = xmalloc (sizeof (struct gdb_file)); - set_gdb_file_data (file, NULL, null_file_delete); - set_gdb_file_flush (file, null_file_flush); - set_gdb_file_fputs (file, null_file_fputs); - set_gdb_file_isatty (file, null_file_isatty); - set_gdb_file_rewind (file, null_file_rewind); - set_gdb_file_put (file, null_file_put); - return file; -} - -void -gdb_file_delete (file) - struct gdb_file *file; -{ - file->to_delete (file); - free (file); -} - -static int -null_file_isatty (file) - struct gdb_file *file; -{ - return 0; -} - -static void -null_file_rewind (file) - struct gdb_file *file; -{ - return; -} - -static void -null_file_put (file, src) - struct gdb_file *file; - struct gdb_file *src; -{ - return; -} - -static void -null_file_flush (file) - struct gdb_file *file; -{ - return; -} - -static void -null_file_fputs (buf, file) - const char *buf; - struct gdb_file *file; -{ - return; -} - -static void -null_file_delete (file) - struct gdb_file *file; -{ - return; -} - -void * -gdb_file_data (file) - struct gdb_file *file; -{ - return file->to_data; -} - -void -gdb_flush (file) - struct gdb_file *file; -{ - file->to_flush (file); -} - -int -gdb_file_isatty (file) - struct gdb_file *file; -{ - return file->to_isatty (file); -} - -void -gdb_file_rewind (file) - struct gdb_file *file; -{ - file->to_rewind (file); -} - -void -gdb_file_put (file, dest) - struct gdb_file *file; - struct gdb_file *dest; -{ - file->to_put (file, dest); -} - -void -fputs_unfiltered (buf, file) - const char *buf; - struct gdb_file *file; -{ - file->to_fputs (buf, file); -} - -void -set_gdb_file_flush (file, flush) - struct gdb_file *file; - gdb_file_flush_ftype *flush; -{ - file->to_flush = flush; -} - -void -set_gdb_file_isatty (file, isatty) - struct gdb_file *file; - gdb_file_isatty_ftype *isatty; -{ - file->to_isatty = isatty; -} - -void -set_gdb_file_rewind (file, rewind) - struct gdb_file *file; - gdb_file_rewind_ftype *rewind; -{ - file->to_rewind = rewind; -} - -void -set_gdb_file_put (file, put) - struct gdb_file *file; - gdb_file_put_ftype *put; -{ - file->to_put = put; -} - -void -set_gdb_file_fputs (file, fputs) - struct gdb_file *file; - gdb_file_fputs_ftype *fputs; -{ - file->to_fputs = fputs; -} - -void -set_gdb_file_data (file, data, delete) - struct gdb_file *file; - void *data; - gdb_file_delete_ftype *delete; -{ - file->to_data = data; - file->to_delete = delete; -} - /* Like fputs but if FILTER is true, pause after every screenful. Regardless of FILTER can wrap at points other than the final @@ -2024,10 +1718,8 @@ set_gdb_file_data (file, data, delete) routine should not be called when cleanups are not in place. */ static void -fputs_maybe_filtered (linebuffer, stream, filter) - const char *linebuffer; - GDB_FILE *stream; - int filter; +fputs_maybe_filtered (const char *linebuffer, struct ui_file *stream, + int filter) { const char *lineptr; @@ -2036,7 +1728,7 @@ fputs_maybe_filtered (linebuffer, stream, filter) /* Don't do any filtering if it is disabled. */ if ((stream != gdb_stdout) || !pagination_enabled - || (lines_per_page == UINT_MAX && chars_per_line == UINT_MAX)) + || (lines_per_page == UINT_MAX && chars_per_line == UINT_MAX)) { fputs_unfiltered (linebuffer, stream); return; @@ -2045,7 +1737,7 @@ fputs_maybe_filtered (linebuffer, stream, filter) /* 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) { @@ -2065,7 +1757,7 @@ fputs_maybe_filtered (linebuffer, stream, filter) fputc_unfiltered ('\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. */ + shifting left 3 advances to the next tab stop. */ chars_printed = ((chars_printed >> 3) + 1) << 3; lineptr++; } @@ -2074,11 +1766,11 @@ fputs_maybe_filtered (linebuffer, stream, filter) if (wrap_column) *wrap_pointer++ = *lineptr; else - fputc_unfiltered (*lineptr, stream); + fputc_unfiltered (*lineptr, stream); chars_printed++; lineptr++; } - + if (chars_printed >= chars_per_line) { unsigned int save_chars = chars_printed; @@ -2086,8 +1778,8 @@ fputs_maybe_filtered (linebuffer, stream, filter) chars_printed = 0; lines_printed++; /* If we aren't actually wrapping, don't output newline -- - if chars_per_line is right, we probably just overflowed - anyway; if it's wrong, let us keep going. */ + if chars_per_line is right, we probably just overflowed + anyway; if it's wrong, let us keep going. */ if (wrap_column) fputc_unfiltered ('\n', stream); @@ -2099,8 +1791,8 @@ fputs_maybe_filtered (linebuffer, stream, filter) if (wrap_column) { fputs_unfiltered (wrap_indent, stream); - *wrap_pointer = '\0'; /* Null-terminate saved stuff */ - fputs_unfiltered (wrap_buffer, stream); /* and eject it */ + *wrap_pointer = '\0'; /* Null-terminate saved stuff */ + fputs_unfiltered (wrap_buffer, stream); /* and eject it */ /* FIXME, this strlen is what prevents wrap_indent from containing tabs. However, if we recurse to print it and count its chars, we risk trouble if wrap_indent is @@ -2108,18 +1800,18 @@ fputs_maybe_filtered (linebuffer, stream, filter) Note also that this can set chars_printed > chars_per_line if we are printing a long string. */ chars_printed = strlen (wrap_indent) - + (save_chars - wrap_column); + + (save_chars - wrap_column); wrap_pointer = wrap_buffer; /* Reset buffer */ wrap_buffer[0] = '\0'; - wrap_column = 0; /* And disable fancy wrap */ - } + wrap_column = 0; /* And disable fancy wrap */ + } } } if (*lineptr == '\n') { chars_printed = 0; - wrap_here ((char *)0); /* Spit out chars, cancel further wraps */ + wrap_here ((char *) 0); /* Spit out chars, cancel further wraps */ lines_printed++; fputc_unfiltered ('\n', stream); lineptr++; @@ -2128,42 +1820,29 @@ fputs_maybe_filtered (linebuffer, stream, filter) } void -fputs_filtered (linebuffer, stream) - const char *linebuffer; - GDB_FILE *stream; +fputs_filtered (const char *linebuffer, struct ui_file *stream) { fputs_maybe_filtered (linebuffer, stream, 1); } int -putchar_unfiltered (c) - int c; +putchar_unfiltered (int c) { - char buf[2]; - - buf[0] = c; - buf[1] = 0; - fputs_unfiltered (buf, gdb_stdout); + char buf = c; + ui_file_write (gdb_stdout, &buf, 1); return c; } int -fputc_unfiltered (c, stream) - int c; - GDB_FILE * stream; +fputc_unfiltered (int c, struct ui_file *stream) { - char buf[2]; - - buf[0] = c; - buf[1] = 0; - fputs_unfiltered (buf, stream); + char buf = c; + ui_file_write (stream, &buf, 1); return c; } int -fputc_filtered (c, stream) - int c; - GDB_FILE * stream; +fputc_filtered (int c, struct ui_file *stream) { char buf[2]; @@ -2177,10 +1856,7 @@ fputc_filtered (c, stream) characters in printable fashion. */ void -puts_debug (prefix, string, suffix) - char *prefix; - char *string; - char *suffix; +puts_debug (char *prefix, char *string, char *suffix) { int ch; @@ -2195,18 +1871,18 @@ puts_debug (prefix, string, suffix) /* If the prefix is changing, print the previous suffix, a new line, and the new prefix. */ - if ((return_p || (strcmp(prev_prefix, prefix) != 0)) && !new_line) + if ((return_p || (strcmp (prev_prefix, prefix) != 0)) && !new_line) { - fputs_unfiltered (prev_suffix, gdb_stderr); - fputs_unfiltered ("\n", gdb_stderr); - fputs_unfiltered (prefix, gdb_stderr); + fputs_unfiltered (prev_suffix, gdb_stdlog); + fputs_unfiltered ("\n", gdb_stdlog); + fputs_unfiltered (prefix, gdb_stdlog); } /* Print prefix if we printed a newline during the previous call. */ if (new_line) { new_line = 0; - fputs_unfiltered (prefix, gdb_stderr); + fputs_unfiltered (prefix, gdb_stdlog); } prev_prefix = prefix; @@ -2216,24 +1892,38 @@ puts_debug (prefix, string, suffix) while ((ch = *string++) != '\0') { switch (ch) - { + { default: if (isprint (ch)) - fputc_unfiltered (ch, gdb_stderr); + fputc_unfiltered (ch, gdb_stdlog); else - fprintf_unfiltered (gdb_stderr, "\\x%02x", ch & 0xff); + fprintf_unfiltered (gdb_stdlog, "\\x%02x", ch & 0xff); break; - case '\\': fputs_unfiltered ("\\\\", gdb_stderr); break; - case '\b': fputs_unfiltered ("\\b", gdb_stderr); break; - case '\f': fputs_unfiltered ("\\f", gdb_stderr); break; - case '\n': new_line = 1; - fputs_unfiltered ("\\n", gdb_stderr); break; - case '\r': fputs_unfiltered ("\\r", gdb_stderr); break; - case '\t': fputs_unfiltered ("\\t", gdb_stderr); break; - case '\v': fputs_unfiltered ("\\v", gdb_stderr); break; - } + case '\\': + fputs_unfiltered ("\\\\", gdb_stdlog); + break; + case '\b': + fputs_unfiltered ("\\b", gdb_stdlog); + break; + case '\f': + fputs_unfiltered ("\\f", gdb_stdlog); + break; + case '\n': + new_line = 1; + fputs_unfiltered ("\\n", gdb_stdlog); + break; + case '\r': + fputs_unfiltered ("\\r", gdb_stdlog); + break; + case '\t': + fputs_unfiltered ("\\t", gdb_stdlog); + break; + case '\v': + fputs_unfiltered ("\\v", gdb_stdlog); + break; + } return_p = ch == '\r'; } @@ -2241,8 +1931,8 @@ puts_debug (prefix, string, suffix) /* Print suffix if we printed a newline. */ if (new_line) { - fputs_unfiltered (suffix, gdb_stderr); - fputs_unfiltered ("\n", gdb_stderr); + fputs_unfiltered (suffix, gdb_stdlog); + fputs_unfiltered ("\n", gdb_stdlog); } } @@ -2262,11 +1952,8 @@ puts_debug (prefix, string, suffix) called when cleanups are not in place. */ static void -vfprintf_maybe_filtered (stream, format, args, filter) - GDB_FILE *stream; - const char *format; - va_list args; - int filter; +vfprintf_maybe_filtered (struct ui_file *stream, const char *format, + va_list args, int filter) { char *linebuffer; struct cleanup *old_cleanups; @@ -2284,19 +1971,13 @@ vfprintf_maybe_filtered (stream, format, args, filter) void -vfprintf_filtered (stream, format, args) - GDB_FILE *stream; - const char *format; - va_list args; +vfprintf_filtered (struct ui_file *stream, const char *format, va_list args) { vfprintf_maybe_filtered (stream, format, args, 1); } void -vfprintf_unfiltered (stream, format, args) - GDB_FILE *stream; - const char *format; - va_list args; +vfprintf_unfiltered (struct ui_file *stream, const char *format, va_list args) { char *linebuffer; struct cleanup *old_cleanups; @@ -2313,65 +1994,31 @@ vfprintf_unfiltered (stream, format, args) } void -vprintf_filtered (format, args) - const char *format; - va_list args; +vprintf_filtered (const char *format, va_list args) { vfprintf_maybe_filtered (gdb_stdout, format, args, 1); } void -vprintf_unfiltered (format, args) - const char *format; - va_list args; +vprintf_unfiltered (const char *format, va_list args) { vfprintf_unfiltered (gdb_stdout, format, args); } -/* VARARGS */ void -#ifdef ANSI_PROTOTYPES -fprintf_filtered (GDB_FILE *stream, const char *format, ...) -#else -fprintf_filtered (va_alist) - va_dcl -#endif +fprintf_filtered (struct ui_file * stream, const char *format,...) { va_list args; -#ifdef ANSI_PROTOTYPES va_start (args, format); -#else - GDB_FILE *stream; - char *format; - - va_start (args); - stream = va_arg (args, GDB_FILE *); - format = va_arg (args, char *); -#endif vfprintf_filtered (stream, format, args); va_end (args); } -/* VARARGS */ void -#ifdef ANSI_PROTOTYPES -fprintf_unfiltered (GDB_FILE *stream, const char *format, ...) -#else -fprintf_unfiltered (va_alist) - va_dcl -#endif +fprintf_unfiltered (struct ui_file * stream, const char *format,...) { va_list args; -#ifdef ANSI_PROTOTYPES va_start (args, format); -#else - GDB_FILE *stream; - char *format; - - va_start (args); - stream = va_arg (args, GDB_FILE *); - format = va_arg (args, char *); -#endif vfprintf_unfiltered (stream, format, args); va_end (args); } @@ -2379,28 +2026,11 @@ fprintf_unfiltered (va_alist) /* Like fprintf_filtered, but prints its result indented. Called as fprintfi_filtered (spaces, stream, format, ...); */ -/* VARARGS */ void -#ifdef ANSI_PROTOTYPES -fprintfi_filtered (int spaces, GDB_FILE *stream, const char *format, ...) -#else -fprintfi_filtered (va_alist) - va_dcl -#endif +fprintfi_filtered (int spaces, struct ui_file * stream, const char *format,...) { va_list args; -#ifdef ANSI_PROTOTYPES va_start (args, format); -#else - int spaces; - GDB_FILE *stream; - char *format; - - va_start (args); - spaces = va_arg (args, int); - stream = va_arg (args, GDB_FILE *); - format = va_arg (args, char *); -#endif print_spaces_filtered (spaces, stream); vfprintf_filtered (stream, format, args); @@ -2408,47 +2038,21 @@ fprintfi_filtered (va_alist) } -/* VARARGS */ void -#ifdef ANSI_PROTOTYPES -printf_filtered (const char *format, ...) -#else -printf_filtered (va_alist) - va_dcl -#endif +printf_filtered (const char *format,...) { va_list args; -#ifdef ANSI_PROTOTYPES va_start (args, format); -#else - char *format; - - va_start (args); - format = va_arg (args, char *); -#endif vfprintf_filtered (gdb_stdout, format, args); va_end (args); } -/* VARARGS */ void -#ifdef ANSI_PROTOTYPES -printf_unfiltered (const char *format, ...) -#else -printf_unfiltered (va_alist) - va_dcl -#endif +printf_unfiltered (const char *format,...) { va_list args; -#ifdef ANSI_PROTOTYPES va_start (args, format); -#else - char *format; - - va_start (args); - format = va_arg (args, char *); -#endif vfprintf_unfiltered (gdb_stdout, format, args); va_end (args); } @@ -2456,26 +2060,11 @@ printf_unfiltered (va_alist) /* Like printf_filtered, but prints it's result indented. Called as printfi_filtered (spaces, format, ...); */ -/* VARARGS */ void -#ifdef ANSI_PROTOTYPES -printfi_filtered (int spaces, const char *format, ...) -#else -printfi_filtered (va_alist) - va_dcl -#endif +printfi_filtered (int spaces, const char *format,...) { va_list args; -#ifdef ANSI_PROTOTYPES va_start (args, format); -#else - int spaces; - char *format; - - va_start (args); - spaces = va_arg (args, int); - format = va_arg (args, char *); -#endif print_spaces_filtered (spaces, gdb_stdout); vfprintf_filtered (gdb_stdout, format, args); va_end (args); @@ -2487,15 +2076,13 @@ printfi_filtered (va_alist) This one doesn't, and had better not! */ void -puts_filtered (string) - const char *string; +puts_filtered (const char *string) { fputs_filtered (string, gdb_stdout); } void -puts_unfiltered (string) - const char *string; +puts_unfiltered (const char *string) { fputs_unfiltered (string, gdb_stdout); } @@ -2503,8 +2090,7 @@ puts_unfiltered (string) /* Return a pointer to N spaces and a null. The pointer is good until the next call to here. */ char * -n_spaces (n) - int n; +n_spaces (int n) { char *t; static char *spaces = 0; @@ -2514,8 +2100,8 @@ n_spaces (n) { if (spaces) free (spaces); - spaces = (char *) xmalloc (n+1); - for (t = spaces+n; t != spaces;) + spaces = (char *) xmalloc (n + 1); + for (t = spaces + n; t != spaces;) *--t = ' '; spaces[n] = '\0'; max_spaces = n; @@ -2526,9 +2112,7 @@ n_spaces (n) /* Print N spaces. */ void -print_spaces_filtered (n, stream) - int n; - GDB_FILE *stream; +print_spaces_filtered (int n, struct ui_file *stream) { fputs_filtered (n_spaces (n), stream); } @@ -2541,11 +2125,8 @@ print_spaces_filtered (n, stream) demangling is off, the name is printed in its "raw" form. */ void -fprintf_symbol_filtered (stream, name, lang, arg_mode) - GDB_FILE *stream; - char *name; - enum language lang; - int arg_mode; +fprintf_symbol_filtered (struct ui_file *stream, char *name, enum language lang, + int arg_mode) { char *demangled; @@ -2585,16 +2166,14 @@ fprintf_symbol_filtered (stream, name, lang, arg_mode) /* Do a strcmp() type operation on STRING1 and STRING2, ignoring any differences in whitespace. Returns 0 if they match, non-zero if they don't (slightly different than strcmp()'s range of return values). - + As an extra hack, string1=="FOO(ARGS)" matches string2=="FOO". This "feature" is useful when searching for matching C++ function names (such as if the user types 'break FOO', where FOO is a mangled C++ function). */ int -strcmp_iw (string1, string2) - const char *string1; - const char *string2; +strcmp_iw (const char *string1, const char *string2) { while ((*string1 != '\0') && (*string2 != '\0')) { @@ -2618,107 +2197,102 @@ strcmp_iw (string1, string2) } return (*string1 != '\0' && *string1 != '(') || (*string2 != '\0'); } - + /* -** subset_compare() -** Answer whether string_to_compare is a full or partial match to -** template_string. The partial match must be in sequence starting -** at index 0. -*/ + ** subset_compare() + ** Answer whether string_to_compare is a full or partial match to + ** template_string. The partial match must be in sequence starting + ** at index 0. + */ int -subset_compare (string_to_compare, template_string) - char *string_to_compare; - char *template_string; +subset_compare (char *string_to_compare, char *template_string) { int match; - if (template_string != (char *)NULL && string_to_compare != (char *)NULL && - strlen(string_to_compare) <= strlen(template_string)) - match = (strncmp(template_string, - string_to_compare, - strlen(string_to_compare)) == 0); + if (template_string != (char *) NULL && string_to_compare != (char *) NULL && + strlen (string_to_compare) <= strlen (template_string)) + match = (strncmp (template_string, + string_to_compare, + strlen (string_to_compare)) == 0); else match = 0; return match; } -static void pagination_on_command PARAMS ((char *arg, int from_tty)); +static void pagination_on_command (char *arg, int from_tty); static void -pagination_on_command (arg, from_tty) - char *arg; - int from_tty; +pagination_on_command (char *arg, int from_tty) { pagination_enabled = 1; } -static void pagination_on_command PARAMS ((char *arg, int from_tty)); +static void pagination_on_command (char *arg, int from_tty); static void -pagination_off_command (arg, from_tty) - char *arg; - int from_tty; +pagination_off_command (char *arg, int from_tty) { pagination_enabled = 0; } - + void -initialize_utils () +initialize_utils (void) { struct cmd_list_element *c; - c = add_set_cmd ("width", class_support, var_uinteger, - (char *)&chars_per_line, - "Set number of characters gdb thinks are in a line.", - &setlist); + c = add_set_cmd ("width", class_support, var_uinteger, + (char *) &chars_per_line, + "Set number of characters gdb thinks are in a line.", + &setlist); add_show_from_set (c, &showlist); c->function.sfunc = set_width_command; add_show_from_set (add_set_cmd ("height", class_support, - var_uinteger, (char *)&lines_per_page, + var_uinteger, (char *) &lines_per_page, "Set number of lines gdb thinks are in a page.", &setlist), &showlist); - + init_page_info (); /* If the output is not a terminal, don't paginate it. */ - if (!GDB_FILE_ISATTY (gdb_stdout)) + if (!ui_file_isatty (gdb_stdout)) lines_per_page = UINT_MAX; - set_width_command ((char *)NULL, 0, c); + set_width_command ((char *) NULL, 0, c); add_show_from_set - (add_set_cmd ("demangle", class_support, var_boolean, - (char *)&demangle, - "Set demangling of encoded C++ names when displaying symbols.", + (add_set_cmd ("demangle", class_support, var_boolean, + (char *) &demangle, + "Set demangling of encoded C++ names when displaying symbols.", &setprintlist), &showprintlist); add_show_from_set (add_set_cmd ("pagination", class_support, - var_boolean, (char *)&pagination_enabled, + var_boolean, (char *) &pagination_enabled, "Set state of pagination.", &setlist), &showlist); + if (xdb_commands) { - add_com("am", class_support, pagination_on_command, - "Enable pagination"); - add_com("sm", class_support, pagination_off_command, - "Disable pagination"); + add_com ("am", class_support, pagination_on_command, + "Enable pagination"); + add_com ("sm", class_support, pagination_off_command, + "Disable pagination"); } add_show_from_set - (add_set_cmd ("sevenbit-strings", class_support, var_boolean, - (char *)&sevenbit_strings, - "Set printing of 8-bit characters in strings as \\nnn.", + (add_set_cmd ("sevenbit-strings", class_support, var_boolean, + (char *) &sevenbit_strings, + "Set printing of 8-bit characters in strings as \\nnn.", &setprintlist), &showprintlist); add_show_from_set - (add_set_cmd ("asm-demangle", class_support, var_boolean, - (char *)&asm_demangle, - "Set demangling of C++ names in disassembly listings.", + (add_set_cmd ("asm-demangle", class_support, var_boolean, + (char *) &asm_demangle, + "Set demangling of C++ names in disassembly listings.", &setprintlist), &showprintlist); } @@ -2726,7 +2300,7 @@ initialize_utils () /* Machine specific function to handle SIGWINCH signal. */ #ifdef SIGWINCH_HANDLER_BODY - SIGWINCH_HANDLER_BODY +SIGWINCH_HANDLER_BODY #endif /* Support for converting target fp numbers into host DOUBLEST format. */ @@ -2743,33 +2317,46 @@ initialize_utils () a system header, what we do if not, etc. */ #define FLOATFORMAT_CHAR_BIT 8 -static unsigned long get_field PARAMS ((unsigned char *, - enum floatformat_byteorders, - unsigned int, - unsigned int, - unsigned int)); +static unsigned long get_field (unsigned char *, + enum floatformat_byteorders, + unsigned int, unsigned int, unsigned int); /* Extract a field which starts at START and is LEN bytes long. DATA and TOTAL_LEN are the thing we are extracting it from, in byteorder ORDER. */ static unsigned long -get_field (data, order, total_len, start, len) - unsigned char *data; - enum floatformat_byteorders order; - unsigned int total_len; - unsigned int start; - unsigned int len; +get_field (unsigned char *data, enum floatformat_byteorders order, + unsigned int total_len, unsigned int start, unsigned int len) { unsigned long result; unsigned int cur_byte; int cur_bitshift; /* Start at the least significant part of the field. */ - cur_byte = (start + len) / FLOATFORMAT_CHAR_BIT; if (order == floatformat_little || order == floatformat_littlebyte_bigword) - cur_byte = (total_len / FLOATFORMAT_CHAR_BIT) - cur_byte - 1; - cur_bitshift = - ((start + len) % FLOATFORMAT_CHAR_BIT) - FLOATFORMAT_CHAR_BIT; - result = *(data + cur_byte) >> (-cur_bitshift); + { + /* We start counting from the other end (i.e, from the high bytes + rather than the low bytes). As such, we need to be concerned + with what happens if bit 0 doesn't start on a byte boundary. + I.e, we need to properly handle the case where total_len is + not evenly divisible by 8. So we compute ``excess'' which + represents the number of bits from the end of our starting + byte needed to get to bit 0. */ + int excess = FLOATFORMAT_CHAR_BIT - (total_len % FLOATFORMAT_CHAR_BIT); + cur_byte = (total_len / FLOATFORMAT_CHAR_BIT) + - ((start + len + excess) / FLOATFORMAT_CHAR_BIT); + cur_bitshift = ((start + len + excess) % FLOATFORMAT_CHAR_BIT) + - FLOATFORMAT_CHAR_BIT; + } + else + { + cur_byte = (start + len) / FLOATFORMAT_CHAR_BIT; + cur_bitshift = + ((start + len) % FLOATFORMAT_CHAR_BIT) - FLOATFORMAT_CHAR_BIT; + } + if (cur_bitshift > -FLOATFORMAT_CHAR_BIT) + result = *(data + cur_byte) >> (-cur_bitshift); + else + result = 0; cur_bitshift += FLOATFORMAT_CHAR_BIT; if (order == floatformat_little || order == floatformat_littlebyte_bigword) ++cur_byte; @@ -2779,34 +2366,28 @@ get_field (data, order, total_len, start, len) /* Move towards the most significant part of the field. */ while (cur_bitshift < len) { - if (len - cur_bitshift < FLOATFORMAT_CHAR_BIT) - /* This is the last byte; zero out the bits which are not part of - this field. */ - result |= - (*(data + cur_byte) & ((1 << (len - cur_bitshift)) - 1)) - << cur_bitshift; - else - result |= *(data + cur_byte) << cur_bitshift; + result |= (unsigned long)*(data + cur_byte) << cur_bitshift; cur_bitshift += FLOATFORMAT_CHAR_BIT; if (order == floatformat_little || order == floatformat_littlebyte_bigword) ++cur_byte; else --cur_byte; } + if (len < sizeof(result) * FLOATFORMAT_CHAR_BIT) + /* Mask out bits which are not part of the field */ + result &= ((1UL << len) - 1); return result; } - + /* Convert from FMT to a DOUBLEST. FROM is the address of the extended float. Store the DOUBLEST in *TO. */ void -floatformat_to_doublest (fmt, from, to) - const struct floatformat *fmt; - char *from; - DOUBLEST *to; +floatformat_to_doublest (const struct floatformat *fmt, char *from, + DOUBLEST *to) { - unsigned char *ufrom = (unsigned char *)from; + unsigned char *ufrom = (unsigned char *) from; DOUBLEST dto; long exponent; unsigned long mant; @@ -2825,18 +2406,18 @@ floatformat_to_doublest (fmt, from, to) than sizeof(long) for the target. FIXME: Assumes sizeof(long) for the target is 4. */ - if (fmt -> byteorder == floatformat_littlebyte_bigword) + if (fmt->byteorder == floatformat_littlebyte_bigword) { static unsigned char *newfrom; unsigned char *swapin, *swapout; int longswaps; - longswaps = fmt -> totalsize / FLOATFORMAT_CHAR_BIT; + longswaps = fmt->totalsize / FLOATFORMAT_CHAR_BIT; longswaps >>= 3; - + if (newfrom == NULL) { - newfrom = (unsigned char *) xmalloc (fmt -> totalsize); + newfrom = (unsigned char *) xmalloc (fmt->totalsize); } swapout = newfrom; swapin = ufrom; @@ -2868,9 +2449,12 @@ floatformat_to_doublest (fmt, from, to) special_exponent = exponent == 0 || exponent == fmt->exp_nan; -/* Don't bias zero's, denorms or NaNs. */ +/* Don't bias NaNs. Use minimum exponent for denorms. For simplicity, + we don't check for zero as the exponent doesn't matter. */ if (!special_exponent) exponent -= fmt->exp_bias; + else if (exponent == 0) + exponent = 1 - fmt->exp_bias; /* Build the result algebraically. Might go infinite, underflow, etc; who cares. */ @@ -2891,9 +2475,9 @@ floatformat_to_doublest (fmt, from, to) mant_bits = min (mant_bits_left, 32); mant = get_field (ufrom, fmt->byteorder, fmt->totalsize, - mant_off, mant_bits); + mant_off, mant_bits); - dto += ldexp ((double)mant, exponent - mant_bits); + dto += ldexp ((double) mant, exponent - mant_bits); exponent -= mant_bits; mant_off += mant_bits; mant_bits_left -= mant_bits; @@ -2905,36 +2489,43 @@ floatformat_to_doublest (fmt, from, to) *to = dto; } -static void put_field PARAMS ((unsigned char *, enum floatformat_byteorders, - unsigned int, - unsigned int, - unsigned int, - unsigned long)); +static void put_field (unsigned char *, enum floatformat_byteorders, + unsigned int, + unsigned int, unsigned int, unsigned long); /* Set a field which starts at START and is LEN bytes long. DATA and TOTAL_LEN are the thing we are extracting it from, in byteorder ORDER. */ static void -put_field (data, order, total_len, start, len, stuff_to_put) - unsigned char *data; - enum floatformat_byteorders order; - unsigned int total_len; - unsigned int start; - unsigned int len; - unsigned long stuff_to_put; +put_field (unsigned char *data, enum floatformat_byteorders order, + unsigned int total_len, unsigned int start, unsigned int len, + unsigned long stuff_to_put) { unsigned int cur_byte; int cur_bitshift; /* Start at the least significant part of the field. */ - cur_byte = (start + len) / FLOATFORMAT_CHAR_BIT; if (order == floatformat_little || order == floatformat_littlebyte_bigword) - cur_byte = (total_len / FLOATFORMAT_CHAR_BIT) - cur_byte - 1; - cur_bitshift = - ((start + len) % FLOATFORMAT_CHAR_BIT) - FLOATFORMAT_CHAR_BIT; - *(data + cur_byte) &= - ~(((1 << ((start + len) % FLOATFORMAT_CHAR_BIT)) - 1) << (-cur_bitshift)); - *(data + cur_byte) |= - (stuff_to_put & ((1 << FLOATFORMAT_CHAR_BIT) - 1)) << (-cur_bitshift); + { + int excess = FLOATFORMAT_CHAR_BIT - (total_len % FLOATFORMAT_CHAR_BIT); + cur_byte = (total_len / FLOATFORMAT_CHAR_BIT) + - ((start + len + excess) / FLOATFORMAT_CHAR_BIT); + cur_bitshift = ((start + len + excess) % FLOATFORMAT_CHAR_BIT) + - FLOATFORMAT_CHAR_BIT; + } + else + { + cur_byte = (start + len) / FLOATFORMAT_CHAR_BIT; + cur_bitshift = + ((start + len) % FLOATFORMAT_CHAR_BIT) - FLOATFORMAT_CHAR_BIT; + } + if (cur_bitshift > -FLOATFORMAT_CHAR_BIT) + { + *(data + cur_byte) &= + ~(((1 << ((start + len) % FLOATFORMAT_CHAR_BIT)) - 1) + << (-cur_bitshift)); + *(data + cur_byte) |= + (stuff_to_put & ((1 << FLOATFORMAT_CHAR_BIT) - 1)) << (-cur_bitshift); + } cur_bitshift += FLOATFORMAT_CHAR_BIT; if (order == floatformat_little || order == floatformat_littlebyte_bigword) ++cur_byte; @@ -2967,12 +2558,10 @@ put_field (data, order, total_len, start, len, stuff_to_put) The range of the returned value is >= 0.5 and < 1.0. This is equivalent to frexp, but operates on the long double data type. */ -static long double ldfrexp PARAMS ((long double value, int *eptr)); +static long double ldfrexp (long double value, int *eptr); static long double -ldfrexp (value, eptr) - long double value; - int *eptr; +ldfrexp (long double value, int *eptr) { long double tmp; int exp; @@ -3005,7 +2594,7 @@ ldfrexp (value, eptr) } *eptr = exp; - return value/tmp; + return value / tmp; } #endif /* HAVE_LONG_DOUBLE */ @@ -3015,20 +2604,19 @@ ldfrexp (value, eptr) restrictions. */ void -floatformat_from_doublest (fmt, from, to) - CONST struct floatformat *fmt; - DOUBLEST *from; - char *to; +floatformat_from_doublest (CONST struct floatformat *fmt, DOUBLEST *from, + char *to) { DOUBLEST dfrom; int exponent; DOUBLEST mant; unsigned int mant_bits, mant_off; int mant_bits_left; - unsigned char *uto = (unsigned char *)to; + unsigned char *uto = (unsigned char *) to; memcpy (&dfrom, from, sizeof (dfrom)); - memset (uto, 0, fmt->totalsize / FLOATFORMAT_CHAR_BIT); + memset (uto, 0, (fmt->totalsize + FLOATFORMAT_CHAR_BIT - 1) + / FLOATFORMAT_CHAR_BIT); if (dfrom == 0) return; /* Result is zero */ if (dfrom != dfrom) /* Result is NaN */ @@ -3077,17 +2665,18 @@ floatformat_from_doublest (fmt, from, to) mant_bits = mant_bits_left < 32 ? mant_bits_left : 32; mant *= 4294967296.0; - mant_long = (unsigned long)mant; + mant_long = ((unsigned long) mant) & 0xffffffffL; mant -= mant_long; /* If the integer bit is implicit, then we need to discard it. - If we are discarding a zero, we should be (but are not) creating - a denormalized number which means adjusting the exponent - (I think). */ + If we are discarding a zero, we should be (but are not) creating + a denormalized number which means adjusting the exponent + (I think). */ if (mant_bits_left == fmt->man_len && fmt->intbit == floatformat_intbit_no) { mant_long <<= 1; + mant_long &= 0xffffffffL; mant_bits -= 1; } @@ -3103,7 +2692,7 @@ floatformat_from_doublest (fmt, from, to) mant_off += mant_bits; mant_bits_left -= mant_bits; } - if (fmt -> byteorder == floatformat_littlebyte_bigword) + if (fmt->byteorder == floatformat_littlebyte_bigword) { int count; unsigned char *swaplow = uto; @@ -3119,154 +2708,164 @@ floatformat_from_doublest (fmt, from, to) } } +/* print routines to handle variable size regs, etc. */ + /* temporary storage using circular buffer */ #define NUMCELLS 16 #define CELLSIZE 32 -static char* -get_cell() +static char * +get_cell (void) { static char buf[NUMCELLS][CELLSIZE]; - static int cell=0; - if (++cell>=NUMCELLS) cell=0; + static int cell = 0; + if (++cell >= NUMCELLS) + cell = 0; return buf[cell]; } -/* print routines to handle variable size regs, etc. - - FIXME: Note that t_addr is a bfd_vma, which is currently either an - unsigned long or unsigned long long, determined at configure time. - If t_addr is an unsigned long long and sizeof (unsigned long long) - is greater than sizeof (unsigned long), then I believe this code will - probably lose, at least for little endian machines. I believe that - it would also be better to eliminate the switch on the absolute size - of t_addr and replace it with a sequence of if statements that compare - sizeof t_addr with sizeof the various types and do the right thing, - which includes knowing whether or not the host supports long long. - -fnf +int +strlen_paddr (void) +{ + return (TARGET_PTR_BIT / 8 * 2); +} - */ +char * +paddr (CORE_ADDR addr) +{ + return phex (addr, TARGET_PTR_BIT / 8); +} -static int thirty_two = 32; /* eliminate warning from compiler on 32-bit systems */ +char * +paddr_nz (CORE_ADDR addr) +{ + return phex_nz (addr, TARGET_PTR_BIT / 8); +} -char* -paddr(addr) - t_addr addr; +static void +decimal2str (char *paddr_str, char *sign, ULONGEST addr) { - char *paddr_str=get_cell(); - switch (sizeof(t_addr)) + /* steal code from valprint.c:print_decimal(). Should this worry + about the real size of addr as the above does? */ + unsigned long temp[3]; + int i = 0; + do { - case 8: - sprintf (paddr_str, "%08lx%08lx", - (unsigned long) (addr >> thirty_two), (unsigned long) (addr & 0xffffffff)); - break; - case 4: - sprintf (paddr_str, "%08lx", (unsigned long) addr); - break; - case 2: - sprintf (paddr_str, "%04x", (unsigned short) (addr & 0xffff)); - break; - default: - sprintf (paddr_str, "%lx", (unsigned long) addr); + temp[i] = addr % (1000 * 1000 * 1000); + addr /= (1000 * 1000 * 1000); + i++; } + while (addr != 0 && i < (sizeof (temp) / sizeof (temp[0]))); + switch (i) + { + case 1: + sprintf (paddr_str, "%s%lu", + sign, temp[0]); + break; + case 2: + sprintf (paddr_str, "%s%lu%09lu", + sign, temp[1], temp[0]); + break; + case 3: + sprintf (paddr_str, "%s%lu%09lu%09lu", + sign, temp[2], temp[1], temp[0]); + break; + default: + abort (); + } +} + +char * +paddr_u (CORE_ADDR addr) +{ + char *paddr_str = get_cell (); + decimal2str (paddr_str, "", addr); return paddr_str; } -char* -preg(reg) - t_reg reg; +char * +paddr_d (LONGEST addr) { - char *preg_str=get_cell(); - switch (sizeof(t_reg)) - { - case 8: - sprintf (preg_str, "%08lx%08lx", - (unsigned long) (reg >> thirty_two), (unsigned long) (reg & 0xffffffff)); - break; - case 4: - sprintf (preg_str, "%08lx", (unsigned long) reg); - break; - case 2: - sprintf (preg_str, "%04x", (unsigned short) (reg & 0xffff)); - break; - default: - sprintf (preg_str, "%lx", (unsigned long) reg); - } - return preg_str; + char *paddr_str = get_cell (); + if (addr < 0) + decimal2str (paddr_str, "-", -addr); + else + decimal2str (paddr_str, "", addr); + return paddr_str; } -char* -paddr_nz(addr) - t_addr addr; +/* eliminate warning from compiler on 32-bit systems */ +static int thirty_two = 32; + +char * +phex (ULONGEST l, int sizeof_l) { - char *paddr_str=get_cell(); - switch (sizeof(t_addr)) + char *str = get_cell (); + switch (sizeof_l) { - case 8: - { - unsigned long high = (unsigned long) (addr >> thirty_two); - if (high == 0) - sprintf (paddr_str, "%lx", (unsigned long) (addr & 0xffffffff)); - else - sprintf (paddr_str, "%lx%08lx", - high, (unsigned long) (addr & 0xffffffff)); - break; - } - case 4: - sprintf (paddr_str, "%lx", (unsigned long) addr); - break; - case 2: - sprintf (paddr_str, "%x", (unsigned short) (addr & 0xffff)); - break; - default: - sprintf (paddr_str,"%lx", (unsigned long) addr); + case 8: + sprintf (str, "%08lx%08lx", + (unsigned long) (l >> thirty_two), + (unsigned long) (l & 0xffffffff)); + break; + case 4: + sprintf (str, "%08lx", (unsigned long) l); + break; + case 2: + sprintf (str, "%04x", (unsigned short) (l & 0xffff)); + break; + default: + phex (l, sizeof (l)); + break; } - return paddr_str; + return str; } -char* -preg_nz(reg) - t_reg reg; +char * +phex_nz (ULONGEST l, int sizeof_l) { - char *preg_str=get_cell(); - switch (sizeof(t_reg)) + char *str = get_cell (); + switch (sizeof_l) { - case 8: - { - unsigned long high = (unsigned long) (reg >> thirty_two); - if (high == 0) - sprintf (preg_str, "%lx", (unsigned long) (reg & 0xffffffff)); - else - sprintf (preg_str, "%lx%08lx", - high, (unsigned long) (reg & 0xffffffff)); - break; - } - case 4: - sprintf (preg_str, "%lx", (unsigned long) reg); - break; - case 2: - sprintf (preg_str, "%x", (unsigned short) (reg & 0xffff)); + case 8: + { + unsigned long high = (unsigned long) (l >> thirty_two); + if (high == 0) + sprintf (str, "%lx", (unsigned long) (l & 0xffffffff)); + else + sprintf (str, "%lx%08lx", + high, (unsigned long) (l & 0xffffffff)); break; - default: - sprintf (preg_str, "%lx", (unsigned long) reg); + } + case 4: + sprintf (str, "%lx", (unsigned long) l); + break; + case 2: + sprintf (str, "%x", (unsigned short) (l & 0xffff)); + break; + default: + phex_nz (l, sizeof (l)); + break; } - return preg_str; + return str; } -/* Helper functions for INNER_THAN */ -int -core_addr_lessthan (lhs, rhs) - CORE_ADDR lhs; - CORE_ADDR rhs; + +/* Convert to / from the hosts pointer to GDB's internal CORE_ADDR + using the target's conversion routines. */ +CORE_ADDR +host_pointer_to_address (void *ptr) { - return (lhs < rhs); + if (sizeof (ptr) != TYPE_LENGTH (builtin_type_ptr)) + internal_error ("core_addr_to_void_ptr: bad cast"); + return POINTER_TO_ADDRESS (builtin_type_ptr, &ptr); } -int -core_addr_greaterthan (lhs, rhs) - CORE_ADDR lhs; - CORE_ADDR rhs; +void * +address_to_host_pointer (CORE_ADDR addr) { - return (lhs > rhs); + void *ptr; + if (sizeof (ptr) != TYPE_LENGTH (builtin_type_ptr)) + internal_error ("core_addr_to_void_ptr: bad cast"); + ADDRESS_TO_POINTER (builtin_type_ptr, &ptr, addr); + return ptr; } - -