/* General utility routines for GDB, the GNU debugger.
- Copyright 1986, 89, 90, 91, 92, 95, 1996 Free Software Foundation, Inc.
+ Copyright 1986, 89, 90, 91, 92, 95, 96, 1998 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"
-#ifdef ANSI_PROTOTYPES
-#include <stdarg.h>
-#else
-#include <varargs.h>
-#endif
#include <ctype.h>
#include "gdb_string.h"
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
+#ifdef HAVE_CURSES_H
+#include <curses.h>
+#endif
+#ifdef HAVE_TERM_H
+#include <term.h>
+#endif
+
+/* SunOS's curses.h has a '#define reg register' in it. Thank you Sun. */
+#ifdef reg
+#undef reg
+#endif
+
#include "signals.h"
#include "gdbcmd.h"
#include "serial.h"
#include "language.h"
#include "annotate.h"
-#include "readline.h"
+#include <readline/readline.h>
/* readline defines this. */
#undef savestring
+void (*error_begin_hook) PARAMS ((void));
+
/* Prototypes for local functions */
-static void vfprintf_maybe_filtered PARAMS ((FILE *, const char *, va_list, int));
+static void vfprintf_maybe_filtered PARAMS ((GDB_FILE *, const char *,
+ va_list, int));
-static void fputs_maybe_filtered PARAMS ((const char *, FILE *, int));
+static void fputs_maybe_filtered PARAMS ((const char *, GDB_FILE *, int));
-#if !defined (NO_MMALLOC) && !defined (NO_MMCHECK)
+#if defined (USE_MMALLOC) && !defined (NO_MMCHECK)
static void malloc_botch PARAMS ((void));
#endif
-static void
-fatal_dump_core PARAMS((char *, ...));
-
static void
prompt_for_continue PARAMS ((void));
-static void
+static void
set_width_command PARAMS ((char *, int, struct cmd_list_element *));
+static void
+set_width PARAMS ((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
+#ifndef GDB_FILE_ISATTY
+#define GDB_FILE_ISATTY(GDB_FILE_PTR) (gdb_file_isatty(GDB_FILE_PTR))
+#endif
+
/* 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 *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 */
+
+/* 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;
/* Nonzero if we have job control. */
/* String to be printed before warning messages, if any. */
char *warning_pre_print = "\nwarning: ";
+
+int pagination_enabled = 1;
\f
+
/* Add a new cleanup to the cleanup_chain,
and return the previous chain pointer
to be passed later to do_cleanups or discard_cleanups.
void (*function) PARAMS ((PTR));
PTR arg;
{
- return make_my_cleanup (&cleanup_chain, function, arg);
+ return make_my_cleanup (&cleanup_chain, function, arg);
}
struct cleanup *
void (*function) PARAMS ((PTR));
PTR arg;
{
- return make_my_cleanup (&final_cleanup_chain, function, arg);
+ return make_my_cleanup (&final_cleanup_chain, function, arg);
+}
+
+struct cleanup *
+make_run_cleanup (function, arg)
+ void (*function) PARAMS ((PTR));
+ PTR arg;
+{
+ return make_my_cleanup (&run_cleanup_chain, function, arg);
+}
+
+struct cleanup *
+make_exec_cleanup (function, arg)
+ void (*function) PARAMS ((PTR));
+ PTR arg;
+{
+ return make_my_cleanup (&exec_cleanup_chain, function, arg);
+}
+
+static void
+do_freeargv (arg)
+ void *arg;
+{
+ freeargv ((char **) arg);
+}
+
+struct cleanup *
+make_cleanup_freeargv (arg)
+ char **arg;
+{
+ return make_my_cleanup (&cleanup_chain, do_freeargv, arg);
}
+
struct cleanup *
make_my_cleanup (pmy_chain, function, arg)
struct cleanup **pmy_chain;
PTR 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;
do_cleanups (old_chain)
register struct cleanup *old_chain;
{
- do_my_cleanups (&cleanup_chain, old_chain);
+ do_my_cleanups (&cleanup_chain, old_chain);
}
void
do_final_cleanups (old_chain)
register struct cleanup *old_chain;
{
- do_my_cleanups (&final_cleanup_chain, old_chain);
+ do_my_cleanups (&final_cleanup_chain, old_chain);
+}
+
+void
+do_run_cleanups (old_chain)
+ register struct cleanup *old_chain;
+{
+ do_my_cleanups (&run_cleanup_chain, old_chain);
+}
+
+void
+do_exec_cleanups (old_chain)
+ register struct cleanup *old_chain;
+{
+ do_my_cleanups (&exec_cleanup_chain, old_chain);
}
void
discard_cleanups (old_chain)
register struct cleanup *old_chain;
{
- discard_my_cleanups (&cleanup_chain, old_chain);
+ discard_my_cleanups (&cleanup_chain, old_chain);
}
void
discard_final_cleanups (old_chain)
register struct cleanup *old_chain;
{
- discard_my_cleanups (&final_cleanup_chain, old_chain);
+ discard_my_cleanups (&final_cleanup_chain, old_chain);
}
void
while ((ptr = *pmy_chain) != old_chain)
{
*pmy_chain = ptr->next;
- free ((PTR)ptr);
+ free ((PTR) ptr);
}
}
struct cleanup *
save_cleanups ()
{
- return save_my_cleanups (&cleanup_chain);
+ return save_my_cleanups (&cleanup_chain);
}
struct cleanup *
save_final_cleanups ()
{
- 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;
+ struct cleanup **pmy_chain;
{
struct cleanup *old_chain = *pmy_chain;
restore_cleanups (chain)
struct cleanup *chain;
{
- restore_my_cleanups (&cleanup_chain, chain);
+ restore_my_cleanups (&cleanup_chain, chain);
}
void
restore_final_cleanups (chain)
struct cleanup *chain;
{
- restore_my_cleanups (&final_cleanup_chain, chain);
+ restore_my_cleanups (&final_cleanup_chain, chain);
}
void
/* 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. */
/* ARGSUSED */
void
null_cleanup (arg)
- PTR arg;
+ PTR arg;
+{
+}
+
+/* Add a continuation to the continuation list, the gloabl list
+ cmd_continuation. */
+void
+add_continuation (continuation_hook, arg_list)
+ void (*continuation_hook) PARAMS ((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. */
+void
+do_all_continuations ()
+{
+ struct continuation *continuation_ptr;
+
+ while (cmd_continuation)
+ {
+ (cmd_continuation->continuation_hook) (cmd_continuation->arg_list);
+ continuation_ptr = cmd_continuation;
+ cmd_continuation = continuation_ptr->next;
+ free (continuation_ptr);
+ }
+}
\f
+
/* 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
warning_begin ()
{
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);
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
- warning_begin ();
- vfprintf_unfiltered (gdb_stderr, string, args);
- fprintf_unfiltered (gdb_stderr, "\n");
- va_end (args);
+ if (warning_hook)
+ (*warning_hook) (string, args);
+ else
+ {
+ 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
void
error_begin ()
{
+ 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 ();
The first argument STRING is the error message, used as a fprintf string,
and the remaining args are passed as arguments to it. */
-#ifdef ANSI_PROTOTYPES
NORETURN void
-error (const char *string, ...)
-#else
-void
-error (va_alist)
- va_dcl
-#endif
+error (const char *string,...)
{
va_list args;
-#ifdef ANSI_PROTOTYPES
va_start (args, string);
-#else
- va_start (args);
-#endif
if (error_hook)
(*error_hook) ();
- else
+ 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);
}
-/* 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. */
+/* Print a message reporting an internal error. Ask the user if they
+ want to continue, dump core, or just exit. */
-/* VARARGS */
NORETURN void
-#ifdef ANSI_PROTOTYPES
-fatal (char *string, ...)
-#else
-fatal (va_alist)
- va_dcl
-#endif
+internal_error (char *string, ...)
{
+ static char msg[] = "Internal GDB error: recursive internal error.\n";
+ static int dejavu = 0;
va_list args;
-#ifdef ANSI_PROTOTYPES
+ int continue_p;
+ int dump_core_p;
+
+ /* don't allow infinite error recursion. */
+ switch (dejavu)
+ {
+ 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);
+ }
+
+ /* Try to get the message out */
+ fputs_unfiltered ("gdb-internal-error: ", gdb_stderr);
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");
va_end (args);
- exit (1);
-}
+ fputs_unfiltered ("\n", gdb_stderr);
-/* Print an error message and exit, dumping core.
- The arguments are printed a la printf (). */
+ /* 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? ");
-/* VARARGS */
-static void
-#ifdef ANSI_PROTOTYPES
-fatal_dump_core (char *string, ...)
-#else
-fatal_dump_core (va_alist)
- va_dcl
-#endif
-{
- va_list args;
-#ifdef ANSI_PROTOTYPES
- va_start (args, string);
-#else
- char *string;
+ /* 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? ");
- 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);
+ if (continue_p)
+ {
+ if (dump_core_p)
+ {
+ if (fork () == 0)
+ abort ();
+ }
+ }
+ else
+ {
+ if (dump_core_p)
+ abort ();
+ else
+ exit (1);
+ }
- signal (SIGQUIT, SIG_DFL);
- kill (getpid (), SIGQUIT);
- /* We should never get here, but just in case... */
- exit (1);
+ dejavu = 0;
+ return_to_top_level (RETURN_ERROR);
}
/* The strerror() function can return NULL for errno values that are
as the file name for which the error was encountered.
Then return to command level. */
-void
+NORETURN void
perror_with_name (string)
char *string;
{
too): */
/* 1. The _filtered buffer. */
- wrap_here ((char *)0);
+ wrap_here ((char *) 0);
/* 2. The stdio buffer. */
gdb_flush (gdb_stdout);
gdb_flush (gdb_stderr);
/* 3. The system-level buffer. */
- SERIAL_FLUSH_OUTPUT (gdb_stdout_serial);
+ SERIAL_DRAIN_OUTPUT (gdb_stdout_serial);
SERIAL_UN_FDOPEN (gdb_stdout_serial);
annotate_error_begin ();
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__) || defined (_WIN32)
-
-#ifndef _MSC_VER
-/* In the absence of signals, poll keyboard for a quit.
- Called from #define QUIT pollquit() in xm-go32.h. */
-
-void
-pollquit()
-{
- if (kbhit ())
- {
- int k = getkey ();
- if (k == 1) {
- quit_flag = 1;
- quit();
- }
- else if (k == 2) {
- immediate_quit = 1;
- quit ();
- }
- else
- {
- /* 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");
- }
- }
-}
-#else /* !_MSC_VER */
+#if defined(_MSC_VER) /* should test for wingdb instead? */
-/* This above code is not valid for wingdb unless
- * getkey and kbhit were to be rewritten.
+/*
* Windows translates all keyboard and mouse events
* into a message which is appended to the message
* queue for the process.
*/
+
void
-pollquit()
+notice_quit ()
{
- int k = win32pollquit();
+ int k = win32pollquit ();
if (k == 1)
- {
quit_flag = 1;
- quit ();
- }
else if (k == 2)
- {
immediate_quit = 1;
- quit ();
- }
-}
-#endif /* !_MSC_VER */
-
-
-#ifndef _MSC_VER
-void notice_quit()
-{
- if (kbhit ())
- {
- int k = getkey ();
- if (k == 1) {
- quit_flag = 1;
- }
- else if (k == 2)
- {
- immediate_quit = 1;
- }
- else
- {
- fprintf_unfiltered (gdb_stderr, "CTRL-A to quit, CTRL-B to quit harder\n");
- }
- }
}
-#else /* !_MSC_VER */
-void notice_quit()
-{
- int k = win32pollquit();
- if (k == 1)
- quit_flag = 1;
- else if (k == 2)
- immediate_quit = 1;
-}
-#endif /* !_MSC_VER */
+#else /* !defined(__GO32__) && !defined(_MSC_VER) */
-#else
-void notice_quit()
+void
+notice_quit ()
{
/* Done by signals */
}
-#endif /* defined(__GO32__) || defined(_WIN32) */
-/* Control C comes here */
+#endif /* !defined(__GO32__) && !defined(_MSC_VER) */
+/* Control C comes here */
void
request_quit (signo)
int signo;
about USG defines and stuff like that. */
signal (signo, request_quit);
-/* start-sanitize-gm */
-#ifdef GENERAL_MAGIC
- target_kill ();
-#endif /* GENERAL_MAGIC */
-/* end-sanitize-gm */
-
#ifdef REQUEST_QUIT
REQUEST_QUIT;
#else
- if (immediate_quit)
+ if (immediate_quit)
quit ();
#endif
}
-
\f
/* Memory management stuff (malloc friends). */
#endif
#endif
-#if defined (NO_MMALLOC)
+#if !defined (USE_MMALLOC)
PTR
mmalloc (md, size)
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);
free (ptr);
}
-#endif /* NO_MMALLOC */
+#endif /* USE_MMALLOC */
-#if defined (NO_MMALLOC) || defined (NO_MMCHECK)
+#if !defined (USE_MMALLOC) || defined (NO_MMCHECK)
void
init_malloc (md)
static void
malloc_botch ()
{
- 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
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; ");
{
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.");
}
}
{
return (xmrealloc ((PTR) NULL, ptr, size));
}
-
\f
+
/* My replacement for the read system call.
Used like `read' but keeps going if `read' returns too soon. */
void
print_spaces (n, file)
register int n;
- register FILE *file;
+ register GDB_FILE *file;
{
- while (n-- > 0)
- fputc (' ', file);
+ fputs_unfiltered (n_spaces (n), file);
}
/* Print a host address. */
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.
/* 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)
{
#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 ("");
gdb_flush (gdb_stdout);
- answer = fgetc (stdin);
+
+#if defined(TUI)
+ if (!tui_version || cmdWin == tuiWinWithFocus ())
+#endif
+ answer = fgetc (stdin);
+#if defined(TUI)
+ else
+ answer = (unsigned char) tuiBufferGetc ();
+
+#endif
clearerr (stdin); /* in case of C-d */
if (answer == EOF) /* C-d */
- {
+ {
retval = 1;
break;
}
- if (answer != '\n') /* Eat rest of input line, to EOF or newline */
- do
+ /* Eat rest of input line, to EOF or newline */
+ if ((answer != '\n') || (tui_version && answer != '\r'))
+ do
{
- ans2 = fgetc (stdin);
+#if defined(TUI)
+ if (!tui_version || cmdWin == tuiWinWithFocus ())
+#endif
+ ans2 = fgetc (stdin);
+#if defined(TUI)
+ else
+ ans2 = (unsigned char) tuiBufferGetc ();
+#endif
clearerr (stdin);
}
- while (ans2 != EOF && ans2 != '\n');
+ while (ans2 != EOF && ans2 != '\n' && ans2 != '\r');
+ TUIDO (((TuiOpaqueFuncPtr) tui_vStartNewLines, 1));
+
if (answer >= 'a')
answer -= 040;
if (answer == 'Y')
printf_filtered ("\n\032\032post-query\n");
return retval;
}
-
\f
+
/* 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
if (c == '?')
return 0177;
return (c & 0200) | (c & 037);
-
+
case '0':
case '1':
case '2':
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;
- FILE *stream;
+static void printchar PARAMS ((int c, void (*do_fputs) (const char *, GDB_FILE*), void (*do_fprintf) (GDB_FILE*, const char *, ...), GDB_FILE *stream, int quoter));
+
+static void
+printchar (c, do_fputs, do_fprintf, stream, quoter)
+ int c;
+ void (*do_fputs) PARAMS ((const char *, GDB_FILE*));
+ void (*do_fprintf) PARAMS ((GDB_FILE*, const char *, ...));
+ GDB_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 (str, quoter, stream)
+ const char *str;
+ int quoter;
+ GDB_FILE *stream;
+{
+ while (*str)
+ printchar (*str++, fputs_filtered, fprintf_filtered, stream, quoter);
+}
+
+void
+fputstr_unfiltered (str, quoter, stream)
+ const char *str;
+ int quoter;
+ GDB_FILE *stream;
+{
+ while (*str)
+ printchar (*str++, fputs_unfiltered, fprintf_unfiltered, stream, quoter);
+}
+
+void
+fputstrn_unfiltered (str, n, quoter, stream)
+ const char *str;
+ int n;
+ int quoter;
+ GDB_FILE *stream;
+{
+ int i;
+ for (i = 0; i < n; i++)
+ printchar (str[i], fputs_unfiltered, fprintf_unfiltered, stream, quoter);
}
+
\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 UNIT_MAX is line folding is disabled. */
/* Column number on the screen where wrap_buffer begins, or 0 if wrapping
is not in effect. */
static int wrap_column;
+\f
-/* ARGSUSED */
-static void
-set_width_command (args, from_tty, c)
- char *args;
- int from_tty;
- struct cmd_list_element *c;
+/* Inialize the lines and chars per page */
+void
+init_page_info ()
{
- if (!wrap_buffer)
+#if defined(TUI)
+ if (tui_version && m_winPtrNotNull (cmdWin))
{
- wrap_buffer = (char *) xmalloc (chars_per_line + 2);
- wrap_buffer[0] = '\0';
+ lines_per_page = cmdWin->generic.height;
+ chars_per_line = cmdWin->generic.width;
}
else
- wrap_buffer = (char *) xrealloc (wrap_buffer, chars_per_line + 2);
- wrap_pointer = wrap_buffer; /* Start it at the beginning */
-}
+#endif
+ {
+ /* 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 = 24;
+ chars_per_line = 80;
-/* Wait, so the user can read what's on the screen. Prompt the user
- to continue by pressing RETURN. */
+#if !defined (MPW) && !defined (_WIN32)
+ /* No termcap under MPW, although might be cool to do something
+ by looking at worksheet or console window sizes. */
+ /* Initialize the screen height and width from termcap. */
+ {
+ char *termtype = getenv ("TERM");
-static void
+ /* 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 /* MPW */
+
+#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 (!GDB_FILE_ISATTY (gdb_stdout))
+ lines_per_page = UINT_MAX;
+ } /* the command_line_version */
+ set_width ();
+}
+
+static void
+set_width ()
+{
+ if (chars_per_line == 0)
+ init_page_info ();
+
+ if (!wrap_buffer)
+ {
+ wrap_buffer = (char *) xmalloc (chars_per_line + 2);
+ wrap_buffer[0] = '\0';
+ }
+ else
+ wrap_buffer = (char *) xrealloc (wrap_buffer, chars_per_line + 2);
+ 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;
+{
+ set_width ();
+}
+
+/* Wait, so the user can read what's on the screen. Prompt the user
+ to continue by pressing RETURN. */
+
+static void
prompt_for_continue ()
{
char *ignore;
while (*p == ' ' || *p == '\t')
++p;
if (p[0] == 'q')
- request_quit (SIGINT);
+ {
+ if (!async_p)
+ request_quit (SIGINT);
+ else
+ async_request_quit (0);
+ }
free (ignore);
}
immediate_quit--;
used to force out output from the wrap_buffer. */
void
-wrap_here(indent)
+wrap_here (indent)
char *indent;
{
/* This should have been allocated, but be paranoid anyway. */
}
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;
}
}
+/* ``struct gdb_file'' implementation that maps directly onto
+ <stdio.h>'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_fopen (name, mode)
- char * name;
- char * mode;
+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;
{
- return fopen (name, mode);
+ 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_flush (stream)
- FILE *stream;
+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
- && (stream == gdb_stdout
- || stream == gdb_stderr))
+ && (file == gdb_stdout
+ || file == gdb_stderr))
{
- flush_hook (stream);
+ flush_hook (file);
return;
}
- fflush (stream);
+ 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.
static void
fputs_maybe_filtered (linebuffer, stream, filter)
const char *linebuffer;
- FILE *stream;
+ GDB_FILE *stream;
int filter;
{
const char *lineptr;
return;
/* Don't do any filtering if it is disabled. */
- if (stream != gdb_stdout
- || (lines_per_page == UINT_MAX && chars_per_line == UINT_MAX))
+ if ((stream != gdb_stdout) || !pagination_enabled
+ || (lines_per_page == UINT_MAX && chars_per_line == UINT_MAX))
{
fputs_unfiltered (linebuffer, stream);
return;
/* Go through and output each character. Show line extension
when this is necessary; prompt user for new page when this is
necessary. */
-
+
lineptr = linebuffer;
while (*lineptr)
{
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++;
}
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;
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);
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
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++;
void
fputs_filtered (linebuffer, stream)
const char *linebuffer;
- FILE *stream;
+ GDB_FILE *stream;
{
fputs_maybe_filtered (linebuffer, stream, 1);
}
int
fputc_unfiltered (c, stream)
int c;
- FILE * stream;
+ GDB_FILE *stream;
{
char buf[2];
return c;
}
+int
+fputc_filtered (c, stream)
+ int c;
+ GDB_FILE *stream;
+{
+ char buf[2];
+
+ buf[0] = c;
+ buf[1] = 0;
+ fputs_filtered (buf, stream);
+ return c;
+}
+
+/* puts_debug is like fputs_unfiltered, except it prints special
+ characters in printable fashion. */
+
+void
+puts_debug (prefix, string, suffix)
+ char *prefix;
+ char *string;
+ char *suffix;
+{
+ int ch;
+
+ /* Print prefix and suffix after each line. */
+ static int new_line = 1;
+ static int return_p = 0;
+ static char *prev_prefix = "";
+ static char *prev_suffix = "";
+
+ if (*string == '\n')
+ return_p = 0;
+
+ /* 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)
+ {
+ 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_stdlog);
+ }
+
+ prev_prefix = prefix;
+ prev_suffix = suffix;
+
+ /* Output characters in a printable format. */
+ while ((ch = *string++) != '\0')
+ {
+ switch (ch)
+ {
+ default:
+ if (isprint (ch))
+ fputc_unfiltered (ch, gdb_stdlog);
+
+ else
+ fprintf_unfiltered (gdb_stdlog, "\\x%02x", ch & 0xff);
+ 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';
+ }
+
+ /* Print suffix if we printed a newline. */
+ if (new_line)
+ {
+ fputs_unfiltered (suffix, gdb_stdlog);
+ fputs_unfiltered ("\n", gdb_stdlog);
+ }
+}
+
/* Print a variable number of ARGS using format FORMAT. If this
information is going to put the amount written (since the last call
static void
vfprintf_maybe_filtered (stream, format, args, filter)
- FILE *stream;
+ GDB_FILE *stream;
const char *format;
va_list args;
int filter;
void
vfprintf_filtered (stream, format, args)
- FILE *stream;
+ GDB_FILE *stream;
const char *format;
va_list args;
{
void
vfprintf_unfiltered (stream, format, args)
- FILE *stream;
+ GDB_FILE *stream;
const char *format;
va_list args;
{
vfprintf_unfiltered (gdb_stdout, format, args);
}
-/* VARARGS */
void
-#ifdef ANSI_PROTOTYPES
-fprintf_filtered (FILE *stream, const char *format, ...)
-#else
-fprintf_filtered (va_alist)
- va_dcl
-#endif
+fprintf_filtered (GDB_FILE * stream, const char *format,...)
{
va_list args;
-#ifdef ANSI_PROTOTYPES
va_start (args, format);
-#else
- FILE *stream;
- char *format;
-
- va_start (args);
- stream = va_arg (args, FILE *);
- format = va_arg (args, char *);
-#endif
vfprintf_filtered (stream, format, args);
va_end (args);
}
-/* VARARGS */
void
-#ifdef ANSI_PROTOTYPES
-fprintf_unfiltered (FILE *stream, const char *format, ...)
-#else
-fprintf_unfiltered (va_alist)
- va_dcl
-#endif
+fprintf_unfiltered (GDB_FILE * stream, const char *format,...)
{
va_list args;
-#ifdef ANSI_PROTOTYPES
va_start (args, format);
-#else
- FILE *stream;
- char *format;
-
- va_start (args);
- stream = va_arg (args, FILE *);
- format = va_arg (args, char *);
-#endif
vfprintf_unfiltered (stream, format, args);
va_end (args);
}
/* Like fprintf_filtered, but prints its result indented.
Called as fprintfi_filtered (spaces, stream, format, ...); */
-/* VARARGS */
void
-#ifdef ANSI_PROTOTYPES
-fprintfi_filtered (int spaces, FILE *stream, const char *format, ...)
-#else
-fprintfi_filtered (va_alist)
- va_dcl
-#endif
+fprintfi_filtered (int spaces, GDB_FILE * stream, const char *format,...)
{
va_list args;
-#ifdef ANSI_PROTOTYPES
va_start (args, format);
-#else
- int spaces;
- FILE *stream;
- char *format;
-
- va_start (args);
- spaces = va_arg (args, int);
- stream = va_arg (args, FILE *);
- format = va_arg (args, char *);
-#endif
print_spaces_filtered (spaces, stream);
vfprintf_filtered (stream, format, args);
}
-/* 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);
}
/* 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);
n_spaces (n)
int n;
{
- register char *t;
- static char *spaces;
- static int max_spaces;
+ char *t;
+ static char *spaces = 0;
+ static int max_spaces = -1;
if (n > max_spaces)
{
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;
void
print_spaces_filtered (n, stream)
int n;
- FILE *stream;
+ GDB_FILE *stream;
{
fputs_filtered (n_spaces (n), stream);
}
void
fprintf_symbol_filtered (stream, name, lang, arg_mode)
- FILE *stream;
+ GDB_FILE *stream;
char *name;
enum language lang;
int arg_mode;
case language_cplus:
demangled = cplus_demangle (name, arg_mode);
break;
+ case language_java:
+ demangled = cplus_demangle (name, arg_mode | DMGL_JAVA);
+ break;
case language_chill:
demangled = chill_demangle (name);
break;
/* 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++
}
return (*string1 != '\0' && *string1 != '(') || (*string2 != '\0');
}
+\f
+
+/*
+ ** 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;
+{
+ 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);
+ else
+ match = 0;
+ return match;
+}
+
+
+static void pagination_on_command PARAMS ((char *arg, int from_tty));
+static void
+pagination_on_command (arg, from_tty)
+ char *arg;
+ int from_tty;
+{
+ pagination_enabled = 1;
+}
+static void pagination_on_command PARAMS ((char *arg, int from_tty));
+static void
+pagination_off_command (arg, from_tty)
+ char *arg;
+ int from_tty;
+{
+ pagination_enabled = 0;
+}
\f
+
void
initialize_utils ()
{
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);
-
- /* 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 = 24;
- chars_per_line = 80;
-#if !defined (MPW) && !defined (_WIN32)
- /* No termcap under MPW, although might be cool to do something
- by looking at worksheet or console window sizes. */
- /* Initialize the screen height and width from termcap. */
- {
- char *termtype = getenv ("TERM");
-
- /* Positive means success, nonpositive means failure. */
- int status;
-
- /* 2048 is large enough for all known terminals, according to the
- GNU termcap manual. */
- char term_buffer[2048];
+ init_page_info ();
- if (termtype)
- {
- status = tgetent (term_buffer, termtype);
- if (status > 0)
- {
- int val;
-
- val = tgetnum ("li");
- if (val >= 0)
- lines_per_page = val;
- else
- /* The number of lines per page is not mentioned
- in the terminal description. This probably means
- that paging is not useful (e.g. emacs shell window),
- so disable paging. */
- lines_per_page = UINT_MAX;
-
- val = tgetnum ("co");
- if (val >= 0)
- chars_per_line = val;
- }
- }
- }
-#endif /* MPW */
-
-#if defined(SIGWINCH) && defined(SIGWINCH_HANDLER)
-
- /* If there is a better way to determine the window size, use it. */
- SIGWINCH_HANDLER ();
-#endif
-#endif
/* If the output is not a terminal, don't paginate it. */
- if (!ISATTY (gdb_stdout))
+ if (!GDB_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 ("sevenbit-strings", class_support, var_boolean,
- (char *)&sevenbit_strings,
- "Set printing of 8-bit characters in strings as \\nnn.",
+ (add_set_cmd ("pagination", class_support,
+ 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_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
- (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);
}
/* Machine specific function to handle SIGWINCH signal. */
#ifdef SIGWINCH_HANDLER_BODY
- SIGWINCH_HANDLER_BODY
+SIGWINCH_HANDLER_BODY
#endif
\f
/* Support for converting target fp numbers into host DOUBLEST format. */
/* Start at the least significant part of the field. */
cur_byte = (start + len) / FLOATFORMAT_CHAR_BIT;
- if (order == floatformat_little)
+ 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);
cur_bitshift += FLOATFORMAT_CHAR_BIT;
- if (order == floatformat_little)
+ if (order == floatformat_little || order == floatformat_littlebyte_bigword)
++cur_byte;
else
--cur_byte;
this field. */
result |=
(*(data + cur_byte) & ((1 << (len - cur_bitshift)) - 1))
- << cur_bitshift;
+ << cur_bitshift;
else
result |= *(data + cur_byte) << cur_bitshift;
cur_bitshift += FLOATFORMAT_CHAR_BIT;
- if (order == floatformat_little)
+ if (order == floatformat_little || order == floatformat_littlebyte_bigword)
++cur_byte;
else
--cur_byte;
}
return result;
}
-
+
/* Convert from FMT to a DOUBLEST.
FROM is the address of the extended float.
Store the DOUBLEST in *TO. */
char *from;
DOUBLEST *to;
{
- unsigned char *ufrom = (unsigned char *)from;
+ unsigned char *ufrom = (unsigned char *) from;
DOUBLEST dto;
long exponent;
unsigned long mant;
int mant_bits_left;
int special_exponent; /* It's a NaN, denorm or zero */
+ /* If the mantissa bits are not contiguous from one end of the
+ mantissa to the other, we need to make a private copy of the
+ source bytes that is in the right order since the unpacking
+ algorithm assumes that the bits are contiguous.
+
+ Swap the bytes individually rather than accessing them through
+ "long *" since we have no guarantee that they start on a long
+ alignment, and also sizeof(long) for the host could be different
+ than sizeof(long) for the target. FIXME: Assumes sizeof(long)
+ for the target is 4. */
+
+ if (fmt->byteorder == floatformat_littlebyte_bigword)
+ {
+ static unsigned char *newfrom;
+ unsigned char *swapin, *swapout;
+ int longswaps;
+
+ longswaps = fmt->totalsize / FLOATFORMAT_CHAR_BIT;
+ longswaps >>= 3;
+
+ if (newfrom == NULL)
+ {
+ newfrom = (unsigned char *) xmalloc (fmt->totalsize);
+ }
+ swapout = newfrom;
+ swapin = ufrom;
+ ufrom = newfrom;
+ while (longswaps-- > 0)
+ {
+ /* This is ugly, but efficient */
+ *swapout++ = swapin[4];
+ *swapout++ = swapin[5];
+ *swapout++ = swapin[6];
+ *swapout++ = swapin[7];
+ *swapout++ = swapin[0];
+ *swapout++ = swapin[1];
+ *swapout++ = swapin[2];
+ *swapout++ = swapin[3];
+ swapin += 8;
+ }
+ }
+
exponent = get_field (ufrom, fmt->byteorder, fmt->totalsize,
fmt->exp_start, fmt->exp_len);
/* Note that if exponent indicates a NaN, we can't really do anything useful
increment the exponent by one to account for the integer bit. */
if (!special_exponent)
- if (fmt->intbit == floatformat_intbit_no)
- dto = ldexp (1.0, exponent);
- else
- exponent++;
+ {
+ if (fmt->intbit == floatformat_intbit_no)
+ dto = ldexp (1.0, exponent);
+ else
+ exponent++;
+ }
while (mant_bits_left > 0)
{
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;
/* Start at the least significant part of the field. */
cur_byte = (start + len) / FLOATFORMAT_CHAR_BIT;
- if (order == floatformat_little)
+ 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) |=
(stuff_to_put & ((1 << FLOATFORMAT_CHAR_BIT) - 1)) << (-cur_bitshift);
cur_bitshift += FLOATFORMAT_CHAR_BIT;
- if (order == floatformat_little)
+ if (order == floatformat_little || order == floatformat_littlebyte_bigword)
++cur_byte;
else
--cur_byte;
*(data + cur_byte) = ((stuff_to_put >> cur_bitshift)
& ((1 << FLOATFORMAT_CHAR_BIT) - 1));
cur_bitshift += FLOATFORMAT_CHAR_BIT;
- if (order == floatformat_little)
+ if (order == floatformat_little || order == floatformat_littlebyte_bigword)
++cur_byte;
else
--cur_byte;
}
*eptr = exp;
- return value/tmp;
+ return value / tmp;
}
#endif /* HAVE_LONG_DOUBLE */
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);
if (dfrom == 0)
return; /* Result is zero */
- if (dfrom != dfrom)
+ if (dfrom != dfrom) /* Result is NaN */
{
/* From is NaN */
put_field (uto, fmt->byteorder, fmt->totalsize, fmt->exp_start,
dfrom = -dfrom;
}
- /* How to tell an infinity from an ordinary number? FIXME-someday */
+ if (dfrom + dfrom == dfrom && dfrom != 0.0) /* Result is Infinity */
+ {
+ /* Infinity exponent is same as NaN's. */
+ put_field (uto, fmt->byteorder, fmt->totalsize, fmt->exp_start,
+ fmt->exp_len, fmt->exp_nan);
+ /* Infinity mantissa is all zeroes. */
+ put_field (uto, fmt->byteorder, fmt->totalsize, fmt->man_start,
+ fmt->man_len, 0);
+ return;
+ }
#ifdef HAVE_LONG_DOUBLE
mant = ldfrexp (dfrom, &exponent);
mant_bits = mant_bits_left < 32 ? mant_bits_left : 32;
mant *= 4294967296.0;
- mant_long = (unsigned long)mant;
+ mant_long = (unsigned long) mant;
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_off += mant_bits;
mant_bits_left -= mant_bits;
}
+ if (fmt->byteorder == floatformat_littlebyte_bigword)
+ {
+ int count;
+ unsigned char *swaplow = uto;
+ unsigned char *swaphigh = uto + 4;
+ unsigned char tmp;
+
+ for (count = 0; count < 4; count++)
+ {
+ tmp = *swaplow;
+ *swaplow++ = *swaphigh;
+ *swaphigh++ = tmp;
+ }
+ }
}
/* temporary storage using circular buffer */
#define NUMCELLS 16
#define CELLSIZE 32
-static char*
-get_cell()
+static char *
+get_cell ()
{
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 */
+/* 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
+
+ */
+
static int thirty_two = 32; /* eliminate warning from compiler on 32-bit systems */
-char*
-paddr(addr)
- t_addr addr;
+char *
+paddr (addr)
+ t_addr addr;
{
- char *paddr_str=get_cell();
- switch (sizeof(t_addr))
+ char *paddr_str = get_cell ();
+ switch (sizeof (t_addr))
{
- case 8:
- sprintf(paddr_str,"%08x%08x",
- (unsigned long)(addr>>thirty_two),(unsigned long)(addr&0xffffffff));
- break;
- case 4:
- sprintf(paddr_str,"%08x",(unsigned long)addr);
- break;
- case 2:
- sprintf(paddr_str,"%04x",(unsigned short)(addr&0xffff));
- break;
- default:
- sprintf(paddr_str,"%x",addr);
+ 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);
}
return paddr_str;
}
-char*
-preg(reg)
- t_reg reg;
+char *
+preg (reg)
+ t_reg reg;
{
- char *preg_str=get_cell();
- switch (sizeof(t_reg))
+ char *preg_str = get_cell ();
+ switch (sizeof (t_reg))
{
- case 8:
- sprintf(preg_str,"%08x%08x",
- (unsigned long)(reg>>thirty_two),(unsigned long)(reg&0xffffffff));
- break;
- case 4:
- sprintf(preg_str,"%08x",(unsigned long)reg);
- break;
- case 2:
- sprintf(preg_str,"%04x",(unsigned short)(reg&0xffff));
- break;
- default:
- sprintf(preg_str,"%x",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_nz(addr)
- t_addr addr;
+char *
+paddr_nz (addr)
+ t_addr addr;
{
- char *paddr_str=get_cell();
- switch (sizeof(t_addr))
+ char *paddr_str = get_cell ();
+ switch (sizeof (t_addr))
{
- case 8:
- {
- unsigned long high = (unsigned long)(addr>>thirty_two);
- if (high == 0)
- sprintf(paddr_str,"%x", (unsigned long)(addr&0xffffffff));
- else
- sprintf(paddr_str,"%x%08x",
- high, (unsigned long)(addr&0xffffffff));
- break;
- }
- case 4:
- sprintf(paddr_str,"%x",(unsigned long)addr);
- break;
- case 2:
- sprintf(paddr_str,"%x",(unsigned short)(addr&0xffff));
+ 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;
- default:
- sprintf(paddr_str,"%x",addr);
+ }
+ 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);
}
return paddr_str;
}
-char*
-preg_nz(reg)
- t_reg reg;
+char *
+preg_nz (reg)
+ t_reg reg;
{
- char *preg_str=get_cell();
- switch (sizeof(t_reg))
+ char *preg_str = get_cell ();
+ switch (sizeof (t_reg))
{
- case 8:
- {
- unsigned long high = (unsigned long)(reg>>thirty_two);
- if (high == 0)
- sprintf(preg_str,"%x", (unsigned long)(reg&0xffffffff));
- else
- sprintf(preg_str,"%x%08x",
- high, (unsigned long)(reg&0xffffffff));
- break;
- }
- case 4:
- sprintf(preg_str,"%x",(unsigned long)reg);
- break;
- case 2:
- sprintf(preg_str,"%x",(unsigned short)(reg&0xffff));
+ 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;
- default:
- sprintf(preg_str,"%x",reg);
+ }
+ case 4:
+ sprintf (preg_str, "%lx", (unsigned long) reg);
+ break;
+ case 2:
+ sprintf (preg_str, "%x", (unsigned short) (reg & 0xffff));
+ break;
+ default:
+ sprintf (preg_str, "%lx", (unsigned long) reg);
}
return preg_str;
}
+
+/* Helper functions for INNER_THAN */
+int
+core_addr_lessthan (lhs, rhs)
+ CORE_ADDR lhs;
+ CORE_ADDR rhs;
+{
+ return (lhs < rhs);
+}
+
+int
+core_addr_greaterthan (lhs, rhs)
+ CORE_ADDR lhs;
+ CORE_ADDR rhs;
+{
+ return (lhs > rhs);
+}