/* General utility routines for GDB, the GNU debugger.
Copyright 1986, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995,
- 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 Free Software
+ 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software
Foundation, Inc.
This file is part of GDB.
#include "gdb_string.h"
#include "event-top.h"
+#ifdef TUI
+#include "tui/tui.h" /* For tui_get_command_dimension. */
+#endif
+
#ifdef __GO32__
#include <pc.h>
#endif
#include <term.h>
#endif
-#include <readline/readline.h>
-
-#ifdef USE_MMALLOC
-#include "mmalloc.h"
-#endif
+#include "readline/readline.h"
#ifdef NEED_DECLARATION_MALLOC
extern PTR malloc (); /* OK: PTR */
/* readline defines this. */
#undef savestring
-void (*error_begin_hook) (void);
+void (*deprecated_error_begin_hook) (void);
/* Holds the last error message issued by gdb */
static void fputs_maybe_filtered (const char *, struct ui_file *, int);
-#if defined (USE_MMALLOC) && !defined (NO_MMCHECK)
-static void malloc_botch (void);
-#endif
+static void do_my_cleanups (struct cleanup **, struct cleanup *);
static void prompt_for_continue (void);
-static void set_width_command (char *, int, struct cmd_list_element *);
-
+static void set_screen_size (void);
static void set_width (void);
/* Chain of cleanup actions established with make_cleanup,
make_my_cleanup (struct cleanup **pmy_chain, make_cleanup_ftype *function,
void *arg)
{
- register struct cleanup *new
+ struct cleanup *new
= (struct cleanup *) xmalloc (sizeof (struct cleanup));
- register struct cleanup *old_chain = *pmy_chain;
+ struct cleanup *old_chain = *pmy_chain;
new->next = *pmy_chain;
new->function = function;
until we get back to the point OLD_CHAIN in the cleanup_chain. */
void
-do_cleanups (register struct cleanup *old_chain)
+do_cleanups (struct cleanup *old_chain)
{
do_my_cleanups (&cleanup_chain, old_chain);
}
void
-do_final_cleanups (register struct cleanup *old_chain)
+do_final_cleanups (struct cleanup *old_chain)
{
do_my_cleanups (&final_cleanup_chain, old_chain);
}
void
-do_run_cleanups (register struct cleanup *old_chain)
+do_run_cleanups (struct cleanup *old_chain)
{
do_my_cleanups (&run_cleanup_chain, old_chain);
}
void
-do_exec_cleanups (register struct cleanup *old_chain)
+do_exec_cleanups (struct cleanup *old_chain)
{
do_my_cleanups (&exec_cleanup_chain, old_chain);
}
void
-do_exec_error_cleanups (register struct cleanup *old_chain)
+do_exec_error_cleanups (struct cleanup *old_chain)
{
do_my_cleanups (&exec_error_cleanup_chain, old_chain);
}
-void
-do_my_cleanups (register struct cleanup **pmy_chain,
- register struct cleanup *old_chain)
+static void
+do_my_cleanups (struct cleanup **pmy_chain,
+ struct cleanup *old_chain)
{
- register struct cleanup *ptr;
+ struct cleanup *ptr;
while ((ptr = *pmy_chain) != old_chain)
{
*pmy_chain = ptr->next; /* Do this first incase recursion */
until we get back to the point OLD_CHAIN in the cleanup_chain. */
void
-discard_cleanups (register struct cleanup *old_chain)
+discard_cleanups (struct cleanup *old_chain)
{
discard_my_cleanups (&cleanup_chain, old_chain);
}
void
-discard_final_cleanups (register struct cleanup *old_chain)
+discard_final_cleanups (struct cleanup *old_chain)
{
discard_my_cleanups (&final_cleanup_chain, old_chain);
}
void
-discard_exec_error_cleanups (register struct cleanup *old_chain)
+discard_exec_error_cleanups (struct cleanup *old_chain)
{
discard_my_cleanups (&exec_error_cleanup_chain, old_chain);
}
void
-discard_my_cleanups (register struct cleanup **pmy_chain,
- register struct cleanup *old_chain)
+discard_my_cleanups (struct cleanup **pmy_chain,
+ struct cleanup *old_chain)
{
- register struct cleanup *ptr;
+ struct cleanup *ptr;
while ((ptr = *pmy_chain) != old_chain)
{
*pmy_chain = ptr->next;
In such cases, we may not be certain where the first cleanup is, unless
we have a do-nothing one to always use as the base. */
-/* ARGSUSED */
void
null_cleanup (void *arg)
{
void
vwarning (const char *string, va_list args)
{
- if (warning_hook)
- (*warning_hook) (string, args);
+ if (deprecated_warning_hook)
+ (*deprecated_warning_hook) (string, args);
else
{
target_terminal_ours ();
wrap_here (""); /* Force out any buffered output */
gdb_flush (gdb_stdout);
if (warning_pre_print)
- fprintf_unfiltered (gdb_stderr, warning_pre_print);
+ fputs_unfiltered (warning_pre_print, gdb_stderr);
vfprintf_unfiltered (gdb_stderr, string, args);
fprintf_unfiltered (gdb_stderr, "\n");
va_end (args);
ui_file_write (data, buffer, length_buffer);
}
+/* Cause a silent error to occur. Any error message is recorded
+ though it is not issued. */
+NORETURN void
+error_silent (const char *string, ...)
+{
+ va_list args;
+ struct ui_file *tmp_stream = mem_fileopen ();
+ va_start (args, string);
+ make_cleanup_ui_file_delete (tmp_stream);
+ vfprintf_unfiltered (tmp_stream, string, args);
+ /* Copy the stream into the GDB_LASTERR buffer. */
+ ui_file_rewind (gdb_lasterr);
+ ui_file_put (tmp_stream, do_write, gdb_lasterr);
+ va_end (args);
+
+ throw_exception (RETURN_ERROR);
+}
+
+/* Output an error message including any pre-print text to gdb_stderr. */
+void
+error_output_message (char *pre_print, char *msg)
+{
+ target_terminal_ours ();
+ wrap_here (""); /* Force out any buffered output */
+ gdb_flush (gdb_stdout);
+ annotate_error_begin ();
+ if (pre_print)
+ fputs_filtered (pre_print, gdb_stderr);
+ fputs_filtered (msg, gdb_stderr);
+ fprintf_filtered (gdb_stderr, "\n");
+}
+
NORETURN void
error_stream (struct ui_file *stream)
{
- if (error_begin_hook)
- error_begin_hook ();
+ if (deprecated_error_begin_hook)
+ deprecated_error_begin_hook ();
/* Copy the stream into the GDB_LASTERR buffer. */
ui_file_rewind (gdb_lasterr);
gdb_flush (gdb_stdout);
annotate_error_begin ();
if (error_pre_print)
- fprintf_filtered (gdb_stderr, error_pre_print);
+ fputs_filtered (error_pre_print, gdb_stderr);
ui_file_put (stream, do_write, gdb_stderr);
fprintf_filtered (gdb_stderr, "\n");
internal_vproblem (struct internal_problem *problem,
const char *file, int line, const char *fmt, va_list ap)
{
- static char msg[] = "Recursive internal problem.\n";
static int dejavu;
int quit_p;
int dump_core_p;
+ char *reason;
/* Don't allow infinite error/warning recursion. */
- switch (dejavu)
- {
- case 0:
- dejavu = 1;
- break;
- case 1:
- dejavu = 2;
- fputs_unfiltered (msg, gdb_stderr);
- abort (); /* NOTE: GDB has only three calls to abort(). */
- default:
- dejavu = 3;
- write (STDERR_FILENO, msg, sizeof (msg));
- exit (1);
- }
+ {
+ static char msg[] = "Recursive internal problem.\n";
+ switch (dejavu)
+ {
+ case 0:
+ dejavu = 1;
+ break;
+ case 1:
+ dejavu = 2;
+ fputs_unfiltered (msg, gdb_stderr);
+ abort (); /* NOTE: GDB has only three calls to abort(). */
+ default:
+ dejavu = 3;
+ write (STDERR_FILENO, msg, sizeof (msg));
+ exit (1);
+ }
+ }
/* Try to get the message out and at the start of a new line. */
target_terminal_ours ();
begin_line ();
- /* The error/warning message. Format using a style similar to a
- compiler error message. */
- fprintf_unfiltered (gdb_stderr, "%s:%d: %s: ", file, line, problem->name);
- vfprintf_unfiltered (gdb_stderr, fmt, ap);
- fputs_unfiltered ("\n", gdb_stderr);
-
- /* Provide more details so that the user knows that they are living
- on the edge. */
- fprintf_unfiltered (gdb_stderr, "\
-A problem internal to GDB has been detected. Further\n\
-debugging may prove unreliable.\n");
+ /* Create a string containing the full error/warning message. Need
+ to call query with this full string, as otherwize the reason
+ (error/warning) and question become separated. Format using a
+ style similar to a compiler error message. Include extra detail
+ so that the user knows that they are living on the edge. */
+ {
+ char *msg;
+ msg = xstrvprintf (fmt, ap);
+ reason = xstrprintf ("\
+%s:%d: %s: %s\n\
+A problem internal to GDB has been detected,\n\
+further debugging may prove unreliable.", file, line, problem->name, msg);
+ xfree (msg);
+ make_cleanup (xfree, reason);
+ }
switch (problem->should_quit)
{
/* Default (yes/batch case) is to quit GDB. When in batch mode
this lessens the likelhood of GDB going into an infinate
loop. */
- quit_p = query ("Quit this debugging session? ");
+ quit_p = query ("%s\nQuit this debugging session? ", reason);
break;
case AUTO_BOOLEAN_TRUE:
quit_p = 1;
/* Default (yes/batch case) is to dump core. This leaves a GDB
`dropping' so that it is easier to see that something went
wrong in GDB. */
- dump_core_p = query ("Create a core file of GDB? ");
+ dump_core_p = query ("%s\nCreate a core file of GDB? ", reason);
break;
break;
case AUTO_BOOLEAN_TRUE:
}
static struct internal_problem internal_warning_problem = {
- "internal-error", AUTO_BOOLEAN_AUTO, AUTO_BOOLEAN_AUTO
+ "internal-warning", AUTO_BOOLEAN_AUTO, AUTO_BOOLEAN_AUTO
};
void
/* Don't use *_filtered; we don't want to prompt the user to continue. */
if (quit_pre_print)
- fprintf_unfiltered (gdb_stderr, quit_pre_print);
+ fputs_unfiltered (quit_pre_print, gdb_stderr);
#ifdef __MSDOS__
/* No steenking SIGINT will ever be coming our way when the
about USG defines and stuff like that. */
signal (signo, request_quit);
-#ifdef REQUEST_QUIT
- REQUEST_QUIT;
-#else
if (immediate_quit)
quit ();
-#endif
}
\f
-/* Memory management stuff (malloc friends). */
-
-#if !defined (USE_MMALLOC)
-
-static void *
-mmalloc (void *md, size_t size)
-{
- return malloc (size); /* NOTE: GDB's only call to malloc() */
-}
-
-static void *
-mrealloc (void *md, void *ptr, size_t size)
-{
- if (ptr == 0) /* Guard against old realloc's */
- return mmalloc (md, size);
- else
- return realloc (ptr, size); /* NOTE: GDB's only call to ralloc() */
-}
-
-static void *
-mcalloc (void *md, size_t number, size_t size)
-{
- return calloc (number, size); /* NOTE: GDB's only call to calloc() */
-}
-
-static void
-mfree (void *md, void *ptr)
-{
- free (ptr); /* NOTE: GDB's only call to free() */
-}
-
-#endif /* USE_MMALLOC */
-
-#if !defined (USE_MMALLOC) || defined (NO_MMCHECK)
-
-void
-init_malloc (void *md)
-{
-}
-
-#else /* Have mmalloc and want corruption checking */
-
-static void
-malloc_botch (void)
-{
- fprintf_unfiltered (gdb_stderr, "Memory corruption\n");
- internal_error (__FILE__, __LINE__, "failed internal consistency check");
-}
-
-/* Attempt to install hooks in mmalloc/mrealloc/mfree for the heap specified
- by MD, to detect memory corruption. Note that MD may be NULL to specify
- the default heap that grows via sbrk.
-
- Note that for freshly created regions, we must call mmcheckf prior to any
- mallocs in the region. Otherwise, any region which was allocated prior to
- installing the checking hooks, which is later reallocated or freed, will
- fail the checks! The mmcheck function only allows initial hooks to be
- installed before the first mmalloc. However, anytime after we have called
- mmcheck the first time to install the checking hooks, we can call it again
- to update the function pointer to the memory corruption handler.
-
- Returns zero on failure, non-zero on success. */
-
-#ifndef MMCHECK_FORCE
-#define MMCHECK_FORCE 0
-#endif
-
-void
-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(). */
-
- fprintf_unfiltered
- (gdb_stderr,
- "warning: failed to install memory consistency checks; ");
- fprintf_unfiltered (gdb_stderr,
- "configuration should define NO_MMCHECK or MMCHECK_FORCE\n");
- }
-
- mmtrace ();
-}
-
-#endif /* Have mmalloc and want corruption checking */
-
/* Called when a memory allocation fails, with the number of bytes of
memory requested in SIZE. */
}
}
-/* The xmmalloc() family of memory management routines.
+/* The xmalloc() (libiberty.h) family of memory management routines.
- These are are like the mmalloc() family except that they implement
+ These are like the ISO-C malloc() family except that they implement
consistent semantics and guard against typical memory management
- problems: if a malloc fails, an internal error is thrown; if
- free(NULL) is called, it is ignored; if *alloc(0) is called, NULL
- is returned.
+ problems. */
- All these routines are implemented using the mmalloc() family. */
+/* NOTE: These are declared using PTR to ensure consistency with
+ "libiberty.h". xfree() is GDB local. */
-void *
-xmmalloc (void *md, size_t size)
+PTR /* OK: PTR */
+xmalloc (size_t size)
{
void *val;
+ /* See libiberty/xmalloc.c. This function need's to match that's
+ semantics. It never returns NULL. */
if (size == 0)
- {
- val = NULL;
- }
- else
- {
- val = mmalloc (md, size);
- if (val == NULL)
- nomem (size);
- }
+ size = 1;
+
+ val = malloc (size); /* OK: malloc */
+ if (val == NULL)
+ nomem (size);
+
return (val);
}
-void *
-xmrealloc (void *md, void *ptr, size_t size)
+PTR /* OK: PTR */
+xrealloc (PTR ptr, size_t size) /* OK: PTR */
{
void *val;
+ /* See libiberty/xmalloc.c. This function need's to match that's
+ semantics. It never returns NULL. */
if (size == 0)
- {
- if (ptr != NULL)
- mfree (md, ptr);
- val = NULL;
- }
+ size = 1;
+
+ if (ptr != NULL)
+ val = realloc (ptr, size); /* OK: realloc */
else
- {
- if (ptr != NULL)
- {
- val = mrealloc (md, ptr, size);
- }
- else
- {
- val = mmalloc (md, size);
- }
- if (val == NULL)
- {
- nomem (size);
- }
- }
+ val = malloc (size); /* OK: malloc */
+ if (val == NULL)
+ nomem (size);
+
return (val);
}
-void *
-xmcalloc (void *md, size_t number, size_t size)
+PTR /* OK: PTR */
+xcalloc (size_t number, size_t size)
{
void *mem;
+
+ /* See libiberty/xmalloc.c. This function need's to match that's
+ semantics. It never returns NULL. */
if (number == 0 || size == 0)
- mem = NULL;
- else
{
- mem = mcalloc (md, number, size);
- if (mem == NULL)
- nomem (number * size);
+ number = 1;
+ size = 1;
}
- return mem;
-}
-void
-xmfree (void *md, void *ptr)
-{
- if (ptr != NULL)
- mfree (md, ptr);
-}
-
-/* The xmalloc() (libiberty.h) family of memory management routines.
-
- These are like the ISO-C malloc() family except that they implement
- consistent semantics and guard against typical memory management
- problems. See xmmalloc() above for further information.
-
- All these routines are wrappers to the xmmalloc() family. */
-
-/* NOTE: These are declared using PTR to ensure consistency with
- "libiberty.h". xfree() is GDB local. */
-
-PTR /* OK: PTR */
-xmalloc (size_t size)
-{
- return xmmalloc (NULL, size);
-}
-
-PTR /* OK: PTR */
-xrealloc (PTR ptr, size_t size) /* OK: PTR */
-{
- return xmrealloc (NULL, ptr, size);
-}
+ mem = calloc (number, size); /* OK: xcalloc */
+ if (mem == NULL)
+ nomem (number * size);
-PTR /* OK: PTR */
-xcalloc (size_t number, size_t size)
-{
- return xmcalloc (NULL, number, size);
+ return mem;
}
void
xfree (void *ptr)
{
- xmfree (NULL, ptr);
+ if (ptr != NULL)
+ free (ptr); /* OK: free */
}
\f
/* Like asprintf/vasprintf but get an internal_error if the call
fails. */
+char *
+xstrprintf (const char *format, ...)
+{
+ char *ret;
+ va_list args;
+ va_start (args, format);
+ ret = xstrvprintf (format, args);
+ va_end (args);
+ return ret;
+}
+
void
xasprintf (char **ret, const char *format, ...)
{
va_list args;
va_start (args, format);
- xvasprintf (ret, format, args);
+ (*ret) = xstrvprintf (format, args);
va_end (args);
}
void
xvasprintf (char **ret, const char *format, va_list ap)
{
- int status = vasprintf (ret, format, ap);
- /* NULL could be returned due to a memory allocation problem; a
- badly format string; or something else. */
- if ((*ret) == NULL)
- internal_error (__FILE__, __LINE__,
- "vasprintf returned NULL buffer (errno %d)", errno);
- /* A negative status with a non-NULL buffer shouldn't never
- happen. But to be sure. */
+ (*ret) = xstrvprintf (format, ap);
+}
+
+char *
+xstrvprintf (const char *format, va_list ap)
+{
+ char *ret = NULL;
+ int status = vasprintf (&ret, format, ap);
+ /* NULL is returned when there was a memory allocation problem. */
+ if (ret == NULL)
+ nomem (0);
+ /* A negative status (the printed length) with a non-NULL buffer
+ should never happen, but just to be sure. */
if (status < 0)
internal_error (__FILE__, __LINE__,
"vasprintf call failed (errno %d)", errno);
+ return ret;
}
-
/* My replacement for the read system call.
Used like `read' but keeps going if `read' returns too soon. */
int
myread (int desc, char *addr, int len)
{
- register int val;
+ int val;
int orglen = len;
while (len > 0)
char *
savestring (const char *ptr, size_t size)
{
- register char *p = (char *) xmalloc (size + 1);
+ char *p = (char *) xmalloc (size + 1);
memcpy (p, ptr, size);
p[size] = 0;
return p;
char *
msavestring (void *md, const char *ptr, size_t size)
{
- register char *p = (char *) xmmalloc (md, size + 1);
+ char *p = (char *) xmalloc (size + 1);
memcpy (p, ptr, size);
p[size] = 0;
return p;
}
void
-print_spaces (register int n, register struct ui_file *file)
+print_spaces (int n, struct ui_file *file)
{
fputs_unfiltered (n_spaces (n), file);
}
/* Print a host address. */
void
-gdb_print_host_address (void *addr, struct ui_file *stream)
+gdb_print_host_address (const void *addr, struct ui_file *stream)
{
/* We could use the %p conversion specifier to fprintf if we had any
query (const char *ctlstr, ...)
{
va_list args;
- register int answer;
- register int ans2;
+ int answer;
+ int ans2;
int retval;
- va_start (args, ctlstr);
-
- if (query_hook)
+ if (deprecated_query_hook)
{
- return query_hook (ctlstr, args);
+ va_start (args, ctlstr);
+ return deprecated_query_hook (ctlstr, args);
}
/* Automatically answer "yes" if input is not from a terminal. */
if (annotation_level > 1)
printf_filtered ("\n\032\032pre-query\n");
+ va_start (args, ctlstr);
vfprintf_filtered (gdb_stdout, ctlstr, args);
+ va_end (args);
printf_filtered ("(y or n) ");
if (annotation_level > 1)
}
\f
+/* This function supports the nquery() and yquery() functions.
+ Ask user a y-or-n question and return 0 if answer is no, 1 if
+ answer is yes, or default the answer to the specified default.
+ DEFCHAR is either 'y' or 'n' and refers to the default answer.
+ CTLSTR is the control string and should end in "? ". It should
+ not say how to answer, because we do that.
+ ARGS are the arguments passed along with the CTLSTR argument to
+ printf. */
+
+static int
+defaulted_query (const char *ctlstr, const char defchar, va_list args)
+{
+ int answer;
+ int ans2;
+ int retval;
+ int def_value;
+ char def_answer, not_def_answer;
+ char *y_string, *n_string;
+
+ /* Set up according to which answer is the default. */
+ if (defchar == 'y')
+ {
+ def_value = 1;
+ def_answer = 'Y';
+ not_def_answer = 'N';
+ y_string = "[y]";
+ n_string = "n";
+ }
+ else
+ {
+ def_value = 0;
+ def_answer = 'N';
+ not_def_answer = 'Y';
+ y_string = "y";
+ n_string = "[n]";
+ }
+
+ if (deprecated_query_hook)
+ {
+ return deprecated_query_hook (ctlstr, args);
+ }
+
+ /* Automatically answer default value if input is not from a terminal. */
+ if (!input_from_terminal_p ())
+ return def_value;
+
+ while (1)
+ {
+ wrap_here (""); /* Flush any buffered output */
+ gdb_flush (gdb_stdout);
+
+ if (annotation_level > 1)
+ printf_filtered ("\n\032\032pre-query\n");
+
+ vfprintf_filtered (gdb_stdout, ctlstr, args);
+ printf_filtered ("(%s or %s) ", y_string, n_string);
+
+ if (annotation_level > 1)
+ printf_filtered ("\n\032\032query\n");
+
+ wrap_here ("");
+ gdb_flush (gdb_stdout);
+
+ answer = fgetc (stdin);
+ clearerr (stdin); /* in case of C-d */
+ if (answer == EOF) /* C-d */
+ {
+ retval = def_value;
+ break;
+ }
+ /* Eat rest of input line, to EOF or newline */
+ if (answer != '\n')
+ do
+ {
+ ans2 = fgetc (stdin);
+ clearerr (stdin);
+ }
+ while (ans2 != EOF && ans2 != '\n' && ans2 != '\r');
+
+ if (answer >= 'a')
+ answer -= 040;
+ /* Check answer. For the non-default, the user must specify
+ the non-default explicitly. */
+ if (answer == not_def_answer)
+ {
+ retval = !def_value;
+ break;
+ }
+ /* Otherwise, for the default, the user may either specify
+ the required input or have it default by entering nothing. */
+ if (answer == def_answer || answer == '\n' ||
+ answer == '\r' || answer == EOF)
+ {
+ retval = def_value;
+ break;
+ }
+ /* Invalid entries are not defaulted and require another selection. */
+ printf_filtered ("Please answer %s or %s.\n",
+ y_string, n_string);
+ }
+
+ if (annotation_level > 1)
+ printf_filtered ("\n\032\032post-query\n");
+ return retval;
+}
+\f
+
+/* Ask user a y-or-n question and return 0 if answer is no, 1 if
+ answer is yes, or 0 if answer is defaulted.
+ 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
+nquery (const char *ctlstr, ...)
+{
+ va_list args;
+
+ va_start (args, ctlstr);
+ return defaulted_query (ctlstr, 'n', args);
+ va_end (args);
+}
+
+/* Ask user a y-or-n question and return 0 if answer is no, 1 if
+ answer is yes, or 1 if answer is defaulted.
+ 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
+yquery (const char *ctlstr, ...)
+{
+ va_list args;
+
+ va_start (args, ctlstr);
+ return defaulted_query (ctlstr, 'y', args);
+ va_end (args);
+}
+
/* Print an error message saying that we couldn't make sense of a
\^mumble sequence in a string or character constant. START and END
indicate a substring of some larger string that contains the
parse_escape (char **string_ptr)
{
int target_char;
- register int c = *(*string_ptr)++;
+ int c = *(*string_ptr)++;
if (c_parse_backslash (c, &target_char))
return target_char;
else
case '6':
case '7':
{
- register int i = c - '0';
- register int count = 0;
+ int i = c - '0';
+ int count = 0;
while (++count < 3)
{
c = (**string_ptr);
}
\f
-
/* Number of lines per page or UINT_MAX if paging is disabled. */
static unsigned int lines_per_page;
+
/* 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;
static int wrap_column;
\f
-/* Inialize the lines and chars per page */
+/* Inialize the number of lines per page and chars per line. */
+
void
init_page_info (void)
{
if (!tui_get_command_dimension (&chars_per_line, &lines_per_page))
#endif
{
- /* These defaults will be used if we are unable to get the correct
- values from termcap. */
+ int rows, cols;
+
#if defined(__GO32__)
- lines_per_page = ScreenRows ();
- chars_per_line = ScreenCols ();
+ rows = ScreenRows ();
+ cols = ScreenCols ();
+ lines_per_page = rows;
+ chars_per_line = cols;
#else
- lines_per_page = 24;
- chars_per_line = 80;
+ /* Make sure Readline has initialized its terminal settings. */
+ rl_reset_terminal (NULL);
-#if !defined (_WIN32)
- /* Initialize the screen height and width from termcap. */
- {
- char *termtype = getenv ("TERM");
+ /* Get the screen size from Readline. */
+ rl_get_screen_size (&rows, &cols);
+ lines_per_page = rows;
+ chars_per_line = cols;
- /* 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;
- 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
- 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;
- }
- }
- }
-#endif
+ /* Readline should have fetched the termcap entry for us. */
+ if (tgetnum ("li") < 0 || getenv ("EMACS"))
+ {
+ /* 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;
+ }
+ /* FIXME: Get rid of this junk. */
#if defined(SIGWINCH) && defined(SIGWINCH_HANDLER)
-
- /* If there is a better way to determine the window size, use it. */
SIGWINCH_HANDLER (SIGWINCH);
#endif
-#endif
+
/* If the output is not a terminal, don't paginate it. */
if (!ui_file_isatty (gdb_stdout))
lines_per_page = UINT_MAX;
- } /* the command_line_version */
+#endif
+ }
+
+ set_screen_size ();
set_width ();
}
+/* Set the screen size based on LINES_PER_PAGE and CHARS_PER_LINE. */
+
+static void
+set_screen_size (void)
+{
+ int rows = lines_per_page;
+ int cols = chars_per_line;
+
+ if (rows <= 0)
+ rows = INT_MAX;
+
+ if (cols <= 0)
+ rl_get_screen_size (NULL, &cols);
+
+ /* Update Readline's idea of the terminal size. */
+ rl_set_screen_size (rows, cols);
+}
+
+/* Reinitialize WRAP_BUFFER according to the current value of
+ CHARS_PER_LINE. */
+
static void
set_width (void)
{
}
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 (char *args, int from_tty, struct cmd_list_element *c)
{
+ set_screen_size ();
set_width ();
}
+static void
+set_height_command (char *args, int from_tty, struct cmd_list_element *c)
+{
+ set_screen_size ();
+}
+
/* Wait, so the user can read what's on the screen. Prompt the user
to continue by pressing RETURN. */
char *linebuffer;
struct cleanup *old_cleanups;
- xvasprintf (&linebuffer, format, args);
+ linebuffer = xstrvprintf (format, args);
old_cleanups = make_cleanup (xfree, linebuffer);
fputs_maybe_filtered (linebuffer, stream, filter);
do_cleanups (old_cleanups);
char *linebuffer;
struct cleanup *old_cleanups;
- xvasprintf (&linebuffer, format, args);
+ linebuffer = xstrvprintf (format, args);
old_cleanups = make_cleanup (xfree, linebuffer);
fputs_unfiltered (linebuffer, stream);
do_cleanups (old_cleanups);
}
else
{
- switch (lang)
- {
- case language_cplus:
- demangled = cplus_demangle (name, arg_mode);
- break;
- case language_java:
- demangled = cplus_demangle (name, arg_mode | DMGL_JAVA);
- break;
- case language_objc:
- /* Commented out until ObjC handling is enabled. */
- /*demangled = objc_demangle (name); */
- /*break; */
- default:
- demangled = NULL;
- break;
- }
+ demangled = language_demangle (language_def (lang), name, arg_mode);
fputs_filtered (demangled ? demangled : name, stream);
if (demangled != NULL)
{
return (*string1 != '\0' && *string1 != '(') || (*string2 != '\0');
}
+/* This is like strcmp except that it ignores whitespace and treats
+ '(' as the first non-NULL character in terms of ordering. Like
+ strcmp (and unlike strcmp_iw), it returns negative if STRING1 <
+ STRING2, 0 if STRING2 = STRING2, and positive if STRING1 > STRING2
+ according to that ordering.
+
+ If a list is sorted according to this function and if you want to
+ find names in the list that match some fixed NAME according to
+ strcmp_iw(LIST_ELT, NAME), then the place to start looking is right
+ where this function would put NAME.
+
+ Here are some examples of why using strcmp to sort is a bad idea:
+
+ Whitespace example:
+
+ Say your partial symtab contains: "foo<char *>", "goo". Then, if
+ we try to do a search for "foo<char*>", strcmp will locate this
+ after "foo<char *>" and before "goo". Then lookup_partial_symbol
+ will start looking at strings beginning with "goo", and will never
+ see the correct match of "foo<char *>".
+
+ Parenthesis example:
+
+ In practice, this is less like to be an issue, but I'll give it a
+ shot. Let's assume that '$' is a legitimate character to occur in
+ symbols. (Which may well even be the case on some systems.) Then
+ say that the partial symbol table contains "foo$" and "foo(int)".
+ strcmp will put them in this order, since '$' < '('. Now, if the
+ user searches for "foo", then strcmp will sort "foo" before "foo$".
+ Then lookup_partial_symbol will notice that strcmp_iw("foo$",
+ "foo") is false, so it won't proceed to the actual match of
+ "foo(int)" with "foo". */
+
+int
+strcmp_iw_ordered (const char *string1, const char *string2)
+{
+ while ((*string1 != '\0') && (*string2 != '\0'))
+ {
+ while (isspace (*string1))
+ {
+ string1++;
+ }
+ while (isspace (*string2))
+ {
+ string2++;
+ }
+ if (*string1 != *string2)
+ {
+ break;
+ }
+ if (*string1 != '\0')
+ {
+ string1++;
+ string2++;
+ }
+ }
+
+ switch (*string1)
+ {
+ /* Characters are non-equal unless they're both '\0'; we want to
+ make sure we get the comparison right according to our
+ comparison in the cases where one of them is '\0' or '('. */
+ case '\0':
+ if (*string2 == '\0')
+ return 0;
+ else
+ return -1;
+ case '(':
+ if (*string2 == '\0')
+ return 1;
+ else
+ return -1;
+ default:
+ if (*string2 == '(')
+ return 1;
+ else
+ return *string1 - *string2;
+ }
+}
+
/* A simple comparison function with opposite semantics to strcmp. */
int
{
struct cmd_list_element *c;
- c = add_set_cmd ("width", class_support, var_uinteger,
- (char *) &chars_per_line,
+ c = add_set_cmd ("width", class_support, var_uinteger, &chars_per_line,
"Set number of characters gdb thinks are in a line.",
&setlist);
- add_show_from_set (c, &showlist);
+ deprecated_add_show_from_set (c, &showlist);
set_cmd_sfunc (c, set_width_command);
- add_show_from_set
- (add_set_cmd ("height", class_support,
- var_uinteger, (char *) &lines_per_page,
- "Set number of lines gdb thinks are in a page.", &setlist),
- &showlist);
+ c = add_set_cmd ("height", class_support, var_uinteger, &lines_per_page,
+ "Set number of lines gdb thinks are in a page.", &setlist);
+ deprecated_add_show_from_set (c, &showlist);
+ set_cmd_sfunc (c, set_height_command);
init_page_info ();
- /* If the output is not a terminal, don't paginate it. */
- if (!ui_file_isatty (gdb_stdout))
- lines_per_page = UINT_MAX;
-
- set_width_command ((char *) NULL, 0, c);
-
- add_show_from_set
+ deprecated_add_show_from_set
(add_set_cmd ("demangle", class_support, var_boolean,
(char *) &demangle,
"Set demangling of encoded C++/ObjC names when displaying symbols.",
&setprintlist), &showprintlist);
- add_show_from_set
+ deprecated_add_show_from_set
(add_set_cmd ("pagination", class_support,
var_boolean, (char *) &pagination_enabled,
"Set state of pagination.", &setlist), &showlist);
"Disable pagination");
}
- add_show_from_set
+ deprecated_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.",
&setprintlist), &showprintlist);
- add_show_from_set
+ deprecated_add_show_from_set
(add_set_cmd ("asm-demangle", class_support, var_boolean,
(char *) &asm_demangle,
"Set demangling of C++/ObjC names in disassembly listings.",
if (rp == NULL)
rp = filename;
return xstrdup (rp);
- }
# endif
+ }
#endif /* HAVE_REALPATH */
/* Method 2: The host system (i.e., GNU) has the function
crc = crc32_table[(crc ^ *buf) & 0xff] ^ (crc >> 8);
return ~crc & 0xffffffff;;
}
+
+ULONGEST
+align_up (ULONGEST v, int n)
+{
+ /* Check that N is really a power of two. */
+ gdb_assert (n && (n & (n-1)) == 0);
+ return (v + n - 1) & -n;
+}
+
+ULONGEST
+align_down (ULONGEST v, int n)
+{
+ /* Check that N is really a power of two. */
+ gdb_assert (n && (n & (n-1)) == 0);
+ return (v & -n);
+}