utils.c revision 46283
119370Spst/* General utility routines for GDB, the GNU debugger.
246283Sdfr   Copyright 1986, 89, 90, 91, 92, 95, 96, 1998 Free Software Foundation, Inc.
319370Spst
419370SpstThis file is part of GDB.
519370Spst
619370SpstThis program is free software; you can redistribute it and/or modify
719370Spstit under the terms of the GNU General Public License as published by
819370Spstthe Free Software Foundation; either version 2 of the License, or
919370Spst(at your option) any later version.
1019370Spst
1119370SpstThis program is distributed in the hope that it will be useful,
1219370Spstbut WITHOUT ANY WARRANTY; without even the implied warranty of
1319370SpstMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1419370SpstGNU General Public License for more details.
1519370Spst
1619370SpstYou should have received a copy of the GNU General Public License
1719370Spstalong with this program; if not, write to the Free Software
1819370SpstFoundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
1919370Spst
2019370Spst#include "defs.h"
2119370Spst#include <ctype.h>
2219370Spst#include "gdb_string.h"
2319370Spst#ifdef HAVE_UNISTD_H
2419370Spst#include <unistd.h>
2519370Spst#endif
2619370Spst
2746283Sdfr#ifdef HAVE_CURSES_H
2846283Sdfr#include <curses.h>
2946283Sdfr#endif
3046283Sdfr#ifdef HAVE_TERM_H
3146283Sdfr#include <term.h>
3246283Sdfr#endif
3346283Sdfr
3446283Sdfr/* SunOS's curses.h has a '#define reg register' in it.  Thank you Sun. */
3546283Sdfr#ifdef reg
3646283Sdfr#undef reg
3746283Sdfr#endif
3846283Sdfr
3919370Spst#include "signals.h"
4019370Spst#include "gdbcmd.h"
4119370Spst#include "serial.h"
4219370Spst#include "bfd.h"
4319370Spst#include "target.h"
4419370Spst#include "demangle.h"
4519370Spst#include "expression.h"
4619370Spst#include "language.h"
4719370Spst#include "annotate.h"
4819370Spst
4946283Sdfr#include <readline/readline.h>
5019370Spst
5119370Spst/* readline defines this.  */
5219370Spst#undef savestring
5319370Spst
5446283Sdfrvoid (*error_begin_hook) PARAMS ((void));
5546283Sdfr
5619370Spst/* Prototypes for local functions */
5719370Spst
5846283Sdfrstatic void vfprintf_maybe_filtered PARAMS ((GDB_FILE *, const char *,
5946283Sdfr					     va_list, int));
6019370Spst
6146283Sdfrstatic void fputs_maybe_filtered PARAMS ((const char *, GDB_FILE *, int));
6219370Spst
6346283Sdfr#if defined (USE_MMALLOC) && !defined (NO_MMCHECK)
6446283Sdfrstatic void malloc_botch PARAMS ((void));
6546283Sdfr#endif
6619370Spst
6719370Spststatic void
6819370Spstfatal_dump_core PARAMS((char *, ...));
6919370Spst
7019370Spststatic void
7119370Spstprompt_for_continue PARAMS ((void));
7219370Spst
7319370Spststatic void
7419370Spstset_width_command PARAMS ((char *, int, struct cmd_list_element *));
7519370Spst
7646283Sdfrstatic void
7746283Sdfrset_width PARAMS ((void));
7846283Sdfr
7919370Spst/* If this definition isn't overridden by the header files, assume
8019370Spst   that isatty and fileno exist on this system.  */
8119370Spst#ifndef ISATTY
8219370Spst#define ISATTY(FP)	(isatty (fileno (FP)))
8319370Spst#endif
8419370Spst
8546283Sdfr#ifndef GDB_FILE_ISATTY
8646283Sdfr#define GDB_FILE_ISATTY(GDB_FILE_PTR)   (gdb_file_isatty(GDB_FILE_PTR))
8746283Sdfr#endif
8846283Sdfr
8919370Spst/* Chain of cleanup actions established with make_cleanup,
9019370Spst   to be executed if an error happens.  */
9119370Spst
9246283Sdfrstatic struct cleanup *cleanup_chain; /* cleaned up after a failed command */
9346283Sdfrstatic struct cleanup *final_cleanup_chain; /* cleaned up when gdb exits */
9446283Sdfrstatic struct cleanup *run_cleanup_chain; /* cleaned up on each 'run' */
9519370Spst
9619370Spst/* Nonzero if we have job control. */
9719370Spst
9819370Spstint job_control;
9919370Spst
10019370Spst/* Nonzero means a quit has been requested.  */
10119370Spst
10219370Spstint quit_flag;
10319370Spst
10419370Spst/* Nonzero means quit immediately if Control-C is typed now, rather
10519370Spst   than waiting until QUIT is executed.  Be careful in setting this;
10619370Spst   code which executes with immediate_quit set has to be very careful
10719370Spst   about being able to deal with being interrupted at any time.  It is
10819370Spst   almost always better to use QUIT; the only exception I can think of
10919370Spst   is being able to quit out of a system call (using EINTR loses if
11019370Spst   the SIGINT happens between the previous QUIT and the system call).
11119370Spst   To immediately quit in the case in which a SIGINT happens between
11219370Spst   the previous QUIT and setting immediate_quit (desirable anytime we
11319370Spst   expect to block), call QUIT after setting immediate_quit.  */
11419370Spst
11519370Spstint immediate_quit;
11619370Spst
11719370Spst/* Nonzero means that encoded C++ names should be printed out in their
11819370Spst   C++ form rather than raw.  */
11919370Spst
12019370Spstint demangle = 1;
12119370Spst
12219370Spst/* Nonzero means that encoded C++ names should be printed out in their
12319370Spst   C++ form even in assembler language displays.  If this is set, but
12419370Spst   DEMANGLE is zero, names are printed raw, i.e. DEMANGLE controls.  */
12519370Spst
12619370Spstint asm_demangle = 0;
12719370Spst
12819370Spst/* Nonzero means that strings with character values >0x7F should be printed
12919370Spst   as octal escapes.  Zero means just print the value (e.g. it's an
13019370Spst   international character, and the terminal or window can cope.)  */
13119370Spst
13219370Spstint sevenbit_strings = 0;
13319370Spst
13419370Spst/* String to be printed before error messages, if any.  */
13519370Spst
13619370Spstchar *error_pre_print;
13719370Spst
13819370Spst/* String to be printed before quit messages, if any.  */
13919370Spst
14019370Spstchar *quit_pre_print;
14119370Spst
14219370Spst/* String to be printed before warning messages, if any.  */
14319370Spst
14419370Spstchar *warning_pre_print = "\nwarning: ";
14546283Sdfr
14646283Sdfrint pagination_enabled = 1;
14746283Sdfr
14819370Spst
14919370Spst/* Add a new cleanup to the cleanup_chain,
15019370Spst   and return the previous chain pointer
15119370Spst   to be passed later to do_cleanups or discard_cleanups.
15219370Spst   Args are FUNCTION to clean up with, and ARG to pass to it.  */
15319370Spst
15419370Spststruct cleanup *
15519370Spstmake_cleanup (function, arg)
15619370Spst     void (*function) PARAMS ((PTR));
15719370Spst     PTR arg;
15819370Spst{
15946283Sdfr    return make_my_cleanup (&cleanup_chain, function, arg);
16046283Sdfr}
16146283Sdfr
16246283Sdfrstruct cleanup *
16346283Sdfrmake_final_cleanup (function, arg)
16446283Sdfr     void (*function) PARAMS ((PTR));
16546283Sdfr     PTR arg;
16646283Sdfr{
16746283Sdfr    return make_my_cleanup (&final_cleanup_chain, function, arg);
16846283Sdfr}
16946283Sdfrstruct cleanup *
17046283Sdfrmake_run_cleanup (function, arg)
17146283Sdfr     void (*function) PARAMS ((PTR));
17246283Sdfr     PTR arg;
17346283Sdfr{
17446283Sdfr    return make_my_cleanup (&run_cleanup_chain, function, arg);
17546283Sdfr}
17646283Sdfrstruct cleanup *
17746283Sdfrmake_my_cleanup (pmy_chain, function, arg)
17846283Sdfr     struct cleanup **pmy_chain;
17946283Sdfr     void (*function) PARAMS ((PTR));
18046283Sdfr     PTR arg;
18146283Sdfr{
18219370Spst  register struct cleanup *new
18319370Spst    = (struct cleanup *) xmalloc (sizeof (struct cleanup));
18446283Sdfr  register struct cleanup *old_chain = *pmy_chain;
18519370Spst
18646283Sdfr  new->next = *pmy_chain;
18719370Spst  new->function = function;
18819370Spst  new->arg = arg;
18946283Sdfr  *pmy_chain = new;
19019370Spst
19119370Spst  return old_chain;
19219370Spst}
19319370Spst
19419370Spst/* Discard cleanups and do the actions they describe
19519370Spst   until we get back to the point OLD_CHAIN in the cleanup_chain.  */
19619370Spst
19719370Spstvoid
19819370Spstdo_cleanups (old_chain)
19919370Spst     register struct cleanup *old_chain;
20019370Spst{
20146283Sdfr    do_my_cleanups (&cleanup_chain, old_chain);
20246283Sdfr}
20346283Sdfr
20446283Sdfrvoid
20546283Sdfrdo_final_cleanups (old_chain)
20646283Sdfr     register struct cleanup *old_chain;
20746283Sdfr{
20846283Sdfr    do_my_cleanups (&final_cleanup_chain, old_chain);
20946283Sdfr}
21046283Sdfr
21146283Sdfrvoid
21246283Sdfrdo_run_cleanups (old_chain)
21346283Sdfr     register struct cleanup *old_chain;
21446283Sdfr{
21546283Sdfr    do_my_cleanups (&run_cleanup_chain, old_chain);
21646283Sdfr}
21746283Sdfr
21846283Sdfrvoid
21946283Sdfrdo_my_cleanups (pmy_chain, old_chain)
22046283Sdfr     register struct cleanup **pmy_chain;
22146283Sdfr     register struct cleanup *old_chain;
22246283Sdfr{
22319370Spst  register struct cleanup *ptr;
22446283Sdfr  while ((ptr = *pmy_chain) != old_chain)
22519370Spst    {
22646283Sdfr      *pmy_chain = ptr->next;	/* Do this first incase recursion */
22719370Spst      (*ptr->function) (ptr->arg);
22819370Spst      free (ptr);
22919370Spst    }
23019370Spst}
23119370Spst
23219370Spst/* Discard cleanups, not doing the actions they describe,
23319370Spst   until we get back to the point OLD_CHAIN in the cleanup_chain.  */
23419370Spst
23519370Spstvoid
23619370Spstdiscard_cleanups (old_chain)
23719370Spst     register struct cleanup *old_chain;
23819370Spst{
23946283Sdfr    discard_my_cleanups (&cleanup_chain, old_chain);
24046283Sdfr}
24146283Sdfr
24246283Sdfrvoid
24346283Sdfrdiscard_final_cleanups (old_chain)
24446283Sdfr     register struct cleanup *old_chain;
24546283Sdfr{
24646283Sdfr    discard_my_cleanups (&final_cleanup_chain, old_chain);
24746283Sdfr}
24846283Sdfr
24946283Sdfrvoid
25046283Sdfrdiscard_my_cleanups (pmy_chain, old_chain)
25146283Sdfr     register struct cleanup **pmy_chain;
25246283Sdfr     register struct cleanup *old_chain;
25346283Sdfr{
25419370Spst  register struct cleanup *ptr;
25546283Sdfr  while ((ptr = *pmy_chain) != old_chain)
25619370Spst    {
25746283Sdfr      *pmy_chain = ptr->next;
25819370Spst      free ((PTR)ptr);
25919370Spst    }
26019370Spst}
26119370Spst
26219370Spst/* Set the cleanup_chain to 0, and return the old cleanup chain.  */
26319370Spststruct cleanup *
26419370Spstsave_cleanups ()
26519370Spst{
26646283Sdfr    return save_my_cleanups (&cleanup_chain);
26746283Sdfr}
26819370Spst
26946283Sdfrstruct cleanup *
27046283Sdfrsave_final_cleanups ()
27146283Sdfr{
27246283Sdfr    return save_my_cleanups (&final_cleanup_chain);
27346283Sdfr}
27446283Sdfr
27546283Sdfrstruct cleanup *
27646283Sdfrsave_my_cleanups (pmy_chain)
27746283Sdfr    struct cleanup **pmy_chain;
27846283Sdfr{
27946283Sdfr  struct cleanup *old_chain = *pmy_chain;
28046283Sdfr
28146283Sdfr  *pmy_chain = 0;
28219370Spst  return old_chain;
28319370Spst}
28419370Spst
28519370Spst/* Restore the cleanup chain from a previously saved chain.  */
28619370Spstvoid
28719370Spstrestore_cleanups (chain)
28819370Spst     struct cleanup *chain;
28919370Spst{
29046283Sdfr    restore_my_cleanups (&cleanup_chain, chain);
29119370Spst}
29219370Spst
29346283Sdfrvoid
29446283Sdfrrestore_final_cleanups (chain)
29546283Sdfr     struct cleanup *chain;
29646283Sdfr{
29746283Sdfr    restore_my_cleanups (&final_cleanup_chain, chain);
29846283Sdfr}
29946283Sdfr
30046283Sdfrvoid
30146283Sdfrrestore_my_cleanups (pmy_chain, chain)
30246283Sdfr     struct cleanup **pmy_chain;
30346283Sdfr     struct cleanup *chain;
30446283Sdfr{
30546283Sdfr  *pmy_chain = chain;
30646283Sdfr}
30746283Sdfr
30819370Spst/* This function is useful for cleanups.
30919370Spst   Do
31019370Spst
31119370Spst     foo = xmalloc (...);
31219370Spst     old_chain = make_cleanup (free_current_contents, &foo);
31319370Spst
31419370Spst   to arrange to free the object thus allocated.  */
31519370Spst
31619370Spstvoid
31719370Spstfree_current_contents (location)
31819370Spst     char **location;
31919370Spst{
32019370Spst  free (*location);
32119370Spst}
32219370Spst
32319370Spst/* Provide a known function that does nothing, to use as a base for
32419370Spst   for a possibly long chain of cleanups.  This is useful where we
32519370Spst   use the cleanup chain for handling normal cleanups as well as dealing
32619370Spst   with cleanups that need to be done as a result of a call to error().
32719370Spst   In such cases, we may not be certain where the first cleanup is, unless
32819370Spst   we have a do-nothing one to always use as the base. */
32919370Spst
33019370Spst/* ARGSUSED */
33119370Spstvoid
33219370Spstnull_cleanup (arg)
33346283Sdfr    PTR arg;
33419370Spst{
33519370Spst}
33619370Spst
33719370Spst
33819370Spst/* Print a warning message.  Way to use this is to call warning_begin,
33919370Spst   output the warning message (use unfiltered output to gdb_stderr),
34019370Spst   ending in a newline.  There is not currently a warning_end that you
34119370Spst   call afterwards, but such a thing might be added if it is useful
34219370Spst   for a GUI to separate warning messages from other output.
34319370Spst
34419370Spst   FIXME: Why do warnings use unfiltered output and errors filtered?
34519370Spst   Is this anything other than a historical accident?  */
34619370Spst
34719370Spstvoid
34819370Spstwarning_begin ()
34919370Spst{
35019370Spst  target_terminal_ours ();
35119370Spst  wrap_here("");			/* Force out any buffered output */
35219370Spst  gdb_flush (gdb_stdout);
35319370Spst  if (warning_pre_print)
35419370Spst    fprintf_unfiltered (gdb_stderr, warning_pre_print);
35519370Spst}
35619370Spst
35719370Spst/* Print a warning message.
35819370Spst   The first argument STRING is the warning message, used as a fprintf string,
35919370Spst   and the remaining args are passed as arguments to it.
36019370Spst   The primary difference between warnings and errors is that a warning
36119370Spst   does not force the return to command level.  */
36219370Spst
36319370Spst/* VARARGS */
36419370Spstvoid
36519370Spst#ifdef ANSI_PROTOTYPES
36646283Sdfrwarning (const char *string, ...)
36719370Spst#else
36819370Spstwarning (va_alist)
36919370Spst     va_dcl
37019370Spst#endif
37119370Spst{
37219370Spst  va_list args;
37319370Spst#ifdef ANSI_PROTOTYPES
37419370Spst  va_start (args, string);
37519370Spst#else
37619370Spst  char *string;
37719370Spst
37819370Spst  va_start (args);
37919370Spst  string = va_arg (args, char *);
38019370Spst#endif
38146283Sdfr  if (warning_hook)
38246283Sdfr    (*warning_hook) (string, args);
38346283Sdfr  else
38446283Sdfr  {
38546283Sdfr    warning_begin ();
38646283Sdfr    vfprintf_unfiltered (gdb_stderr, string, args);
38746283Sdfr    fprintf_unfiltered (gdb_stderr, "\n");
38846283Sdfr    va_end (args);
38946283Sdfr  }
39019370Spst}
39119370Spst
39219370Spst/* Start the printing of an error message.  Way to use this is to call
39319370Spst   this, output the error message (use filtered output to gdb_stderr
39419370Spst   (FIXME: Some callers, like memory_error, use gdb_stdout)), ending
39519370Spst   in a newline, and then call return_to_top_level (RETURN_ERROR).
39619370Spst   error() provides a convenient way to do this for the special case
39719370Spst   that the error message can be formatted with a single printf call,
39819370Spst   but this is more general.  */
39919370Spstvoid
40019370Spsterror_begin ()
40119370Spst{
40246283Sdfr  if (error_begin_hook)
40346283Sdfr    error_begin_hook ();
40446283Sdfr
40519370Spst  target_terminal_ours ();
40619370Spst  wrap_here ("");			/* Force out any buffered output */
40719370Spst  gdb_flush (gdb_stdout);
40819370Spst
40919370Spst  annotate_error_begin ();
41019370Spst
41119370Spst  if (error_pre_print)
41219370Spst    fprintf_filtered (gdb_stderr, error_pre_print);
41319370Spst}
41419370Spst
41519370Spst/* Print an error message and return to command level.
41619370Spst   The first argument STRING is the error message, used as a fprintf string,
41719370Spst   and the remaining args are passed as arguments to it.  */
41819370Spst
41946283Sdfr/* VARARGS */
42046283SdfrNORETURN void
42119370Spst#ifdef ANSI_PROTOTYPES
42246283Sdfrerror (const char *string, ...)
42319370Spst#else
42419370Spsterror (va_alist)
42519370Spst     va_dcl
42619370Spst#endif
42719370Spst{
42819370Spst  va_list args;
42919370Spst#ifdef ANSI_PROTOTYPES
43019370Spst  va_start (args, string);
43119370Spst#else
43219370Spst  va_start (args);
43319370Spst#endif
43419370Spst  if (error_hook)
43519370Spst    (*error_hook) ();
43619370Spst  else
43719370Spst    {
43819370Spst      error_begin ();
43919370Spst#ifdef ANSI_PROTOTYPES
44019370Spst      vfprintf_filtered (gdb_stderr, string, args);
44119370Spst#else
44219370Spst      {
44319370Spst	char *string1;
44419370Spst
44519370Spst	string1 = va_arg (args, char *);
44619370Spst	vfprintf_filtered (gdb_stderr, string1, args);
44719370Spst      }
44819370Spst#endif
44919370Spst      fprintf_filtered (gdb_stderr, "\n");
45019370Spst      va_end (args);
45119370Spst      return_to_top_level (RETURN_ERROR);
45219370Spst    }
45319370Spst}
45419370Spst
45519370Spst
45619370Spst/* Print an error message and exit reporting failure.
45719370Spst   This is for a error that we cannot continue from.
45819370Spst   The arguments are printed a la printf.
45919370Spst
46019370Spst   This function cannot be declared volatile (NORETURN) in an
46119370Spst   ANSI environment because exit() is not declared volatile. */
46219370Spst
46319370Spst/* VARARGS */
46419370SpstNORETURN void
46519370Spst#ifdef ANSI_PROTOTYPES
46619370Spstfatal (char *string, ...)
46719370Spst#else
46819370Spstfatal (va_alist)
46919370Spst     va_dcl
47019370Spst#endif
47119370Spst{
47219370Spst  va_list args;
47319370Spst#ifdef ANSI_PROTOTYPES
47419370Spst  va_start (args, string);
47519370Spst#else
47619370Spst  char *string;
47719370Spst  va_start (args);
47819370Spst  string = va_arg (args, char *);
47919370Spst#endif
48019370Spst  fprintf_unfiltered (gdb_stderr, "\ngdb: ");
48119370Spst  vfprintf_unfiltered (gdb_stderr, string, args);
48219370Spst  fprintf_unfiltered (gdb_stderr, "\n");
48319370Spst  va_end (args);
48419370Spst  exit (1);
48519370Spst}
48619370Spst
48719370Spst/* Print an error message and exit, dumping core.
48819370Spst   The arguments are printed a la printf ().  */
48919370Spst
49019370Spst/* VARARGS */
49119370Spststatic void
49219370Spst#ifdef ANSI_PROTOTYPES
49319370Spstfatal_dump_core (char *string, ...)
49419370Spst#else
49519370Spstfatal_dump_core (va_alist)
49619370Spst     va_dcl
49719370Spst#endif
49819370Spst{
49919370Spst  va_list args;
50019370Spst#ifdef ANSI_PROTOTYPES
50119370Spst  va_start (args, string);
50219370Spst#else
50319370Spst  char *string;
50419370Spst
50519370Spst  va_start (args);
50619370Spst  string = va_arg (args, char *);
50719370Spst#endif
50819370Spst  /* "internal error" is always correct, since GDB should never dump
50919370Spst     core, no matter what the input.  */
51019370Spst  fprintf_unfiltered (gdb_stderr, "\ngdb internal error: ");
51119370Spst  vfprintf_unfiltered (gdb_stderr, string, args);
51219370Spst  fprintf_unfiltered (gdb_stderr, "\n");
51319370Spst  va_end (args);
51419370Spst
51519370Spst  signal (SIGQUIT, SIG_DFL);
51619370Spst  kill (getpid (), SIGQUIT);
51719370Spst  /* We should never get here, but just in case...  */
51819370Spst  exit (1);
51919370Spst}
52019370Spst
52119370Spst/* The strerror() function can return NULL for errno values that are
52219370Spst   out of range.  Provide a "safe" version that always returns a
52319370Spst   printable string. */
52419370Spst
52519370Spstchar *
52619370Spstsafe_strerror (errnum)
52719370Spst     int errnum;
52819370Spst{
52919370Spst  char *msg;
53019370Spst  static char buf[32];
53119370Spst
53219370Spst  if ((msg = strerror (errnum)) == NULL)
53319370Spst    {
53419370Spst      sprintf (buf, "(undocumented errno %d)", errnum);
53519370Spst      msg = buf;
53619370Spst    }
53719370Spst  return (msg);
53819370Spst}
53919370Spst
54019370Spst/* The strsignal() function can return NULL for signal values that are
54119370Spst   out of range.  Provide a "safe" version that always returns a
54219370Spst   printable string. */
54319370Spst
54419370Spstchar *
54519370Spstsafe_strsignal (signo)
54619370Spst     int signo;
54719370Spst{
54819370Spst  char *msg;
54919370Spst  static char buf[32];
55019370Spst
55119370Spst  if ((msg = strsignal (signo)) == NULL)
55219370Spst    {
55319370Spst      sprintf (buf, "(undocumented signal %d)", signo);
55419370Spst      msg = buf;
55519370Spst    }
55619370Spst  return (msg);
55719370Spst}
55819370Spst
55919370Spst
56019370Spst/* Print the system error message for errno, and also mention STRING
56119370Spst   as the file name for which the error was encountered.
56219370Spst   Then return to command level.  */
56319370Spst
56446283SdfrNORETURN void
56519370Spstperror_with_name (string)
56619370Spst     char *string;
56719370Spst{
56819370Spst  char *err;
56919370Spst  char *combined;
57019370Spst
57119370Spst  err = safe_strerror (errno);
57219370Spst  combined = (char *) alloca (strlen (err) + strlen (string) + 3);
57319370Spst  strcpy (combined, string);
57419370Spst  strcat (combined, ": ");
57519370Spst  strcat (combined, err);
57619370Spst
57719370Spst  /* I understand setting these is a matter of taste.  Still, some people
57819370Spst     may clear errno but not know about bfd_error.  Doing this here is not
57919370Spst     unreasonable. */
58019370Spst  bfd_set_error (bfd_error_no_error);
58119370Spst  errno = 0;
58219370Spst
58346283Sdfr  error ("%s.", combined);
58419370Spst}
58519370Spst
58619370Spst/* Print the system error message for ERRCODE, and also mention STRING
58719370Spst   as the file name for which the error was encountered.  */
58819370Spst
58919370Spstvoid
59019370Spstprint_sys_errmsg (string, errcode)
59119370Spst     char *string;
59219370Spst     int errcode;
59319370Spst{
59419370Spst  char *err;
59519370Spst  char *combined;
59619370Spst
59719370Spst  err = safe_strerror (errcode);
59819370Spst  combined = (char *) alloca (strlen (err) + strlen (string) + 3);
59919370Spst  strcpy (combined, string);
60019370Spst  strcat (combined, ": ");
60119370Spst  strcat (combined, err);
60219370Spst
60319370Spst  /* We want anything which was printed on stdout to come out first, before
60419370Spst     this message.  */
60519370Spst  gdb_flush (gdb_stdout);
60619370Spst  fprintf_unfiltered (gdb_stderr, "%s.\n", combined);
60719370Spst}
60819370Spst
60919370Spst/* Control C eventually causes this to be called, at a convenient time.  */
61019370Spst
61119370Spstvoid
61219370Spstquit ()
61319370Spst{
61419370Spst  serial_t gdb_stdout_serial = serial_fdopen (1);
61519370Spst
61619370Spst  target_terminal_ours ();
61719370Spst
61819370Spst  /* We want all output to appear now, before we print "Quit".  We
61919370Spst     have 3 levels of buffering we have to flush (it's possible that
62019370Spst     some of these should be changed to flush the lower-level ones
62119370Spst     too):  */
62219370Spst
62319370Spst  /* 1.  The _filtered buffer.  */
62419370Spst  wrap_here ((char *)0);
62519370Spst
62619370Spst  /* 2.  The stdio buffer.  */
62719370Spst  gdb_flush (gdb_stdout);
62819370Spst  gdb_flush (gdb_stderr);
62919370Spst
63019370Spst  /* 3.  The system-level buffer.  */
63146283Sdfr  SERIAL_DRAIN_OUTPUT (gdb_stdout_serial);
63219370Spst  SERIAL_UN_FDOPEN (gdb_stdout_serial);
63319370Spst
63419370Spst  annotate_error_begin ();
63519370Spst
63619370Spst  /* Don't use *_filtered; we don't want to prompt the user to continue.  */
63719370Spst  if (quit_pre_print)
63819370Spst    fprintf_unfiltered (gdb_stderr, quit_pre_print);
63919370Spst
64019370Spst  if (job_control
64119370Spst      /* If there is no terminal switching for this target, then we can't
64219370Spst	 possibly get screwed by the lack of job control.  */
64319370Spst      || current_target.to_terminal_ours == NULL)
64419370Spst    fprintf_unfiltered (gdb_stderr, "Quit\n");
64519370Spst  else
64619370Spst    fprintf_unfiltered (gdb_stderr,
64719370Spst	     "Quit (expect signal SIGINT when the program is resumed)\n");
64819370Spst  return_to_top_level (RETURN_QUIT);
64919370Spst}
65019370Spst
65119370Spst
65246283Sdfr#if defined(__GO32__)
65319370Spst
65419370Spst/* In the absence of signals, poll keyboard for a quit.
65519370Spst   Called from #define QUIT pollquit() in xm-go32.h. */
65619370Spst
65719370Spstvoid
65846283Sdfrnotice_quit()
65919370Spst{
66019370Spst  if (kbhit ())
66146283Sdfr    switch (getkey ())
66246283Sdfr      {
66346283Sdfr      case 1:
66419370Spst	quit_flag = 1;
66546283Sdfr	break;
66646283Sdfr      case 2:
66746283Sdfr	immediate_quit = 2;
66846283Sdfr	break;
66946283Sdfr      default:
67046283Sdfr	/* We just ignore it */
67146283Sdfr	/* FIXME!! Don't think this actually works! */
67246283Sdfr	fprintf_unfiltered (gdb_stderr, "CTRL-A to quit, CTRL-B to quit harder\n");
67346283Sdfr	break;
67419370Spst      }
67519370Spst}
67619370Spst
67746283Sdfr#elif defined(_MSC_VER) /* should test for wingdb instead? */
67819370Spst
67946283Sdfr/*
68046283Sdfr * Windows translates all keyboard and mouse events
68146283Sdfr * into a message which is appended to the message
68246283Sdfr * queue for the process.
68346283Sdfr */
68446283Sdfr
68519370Spstvoid notice_quit()
68619370Spst{
68746283Sdfr  int k = win32pollquit();
68846283Sdfr  if (k == 1)
68946283Sdfr    quit_flag = 1;
69046283Sdfr  else if (k == 2)
69146283Sdfr    immediate_quit = 1;
69219370Spst}
69346283Sdfr
69446283Sdfr#else /* !defined(__GO32__) && !defined(_MSC_VER) */
69546283Sdfr
69619370Spstvoid notice_quit()
69719370Spst{
69819370Spst  /* Done by signals */
69919370Spst}
70046283Sdfr
70146283Sdfr#endif /* !defined(__GO32__) && !defined(_MSC_VER) */
70246283Sdfr
70346283Sdfrvoid
70446283Sdfrpollquit()
70546283Sdfr{
70646283Sdfr  notice_quit ();
70746283Sdfr  if (quit_flag || immediate_quit)
70846283Sdfr    quit ();
70946283Sdfr}
71046283Sdfr
71119370Spst/* Control C comes here */
71219370Spst
71319370Spstvoid
71419370Spstrequest_quit (signo)
71519370Spst     int signo;
71619370Spst{
71719370Spst  quit_flag = 1;
71819370Spst  /* Restore the signal handler.  Harmless with BSD-style signals, needed
71919370Spst     for System V-style signals.  So just always do it, rather than worrying
72019370Spst     about USG defines and stuff like that.  */
72119370Spst  signal (signo, request_quit);
72219370Spst
72319370Spst#ifdef REQUEST_QUIT
72419370Spst  REQUEST_QUIT;
72519370Spst#else
72619370Spst  if (immediate_quit)
72719370Spst    quit ();
72819370Spst#endif
72919370Spst}
73019370Spst
73119370Spst
73219370Spst/* Memory management stuff (malloc friends).  */
73319370Spst
73419370Spst/* Make a substitute size_t for non-ANSI compilers. */
73519370Spst
73646283Sdfr#ifndef HAVE_STDDEF_H
73719370Spst#ifndef size_t
73819370Spst#define size_t unsigned int
73919370Spst#endif
74019370Spst#endif
74119370Spst
74246283Sdfr#if !defined (USE_MMALLOC)
74346283Sdfr
74419370SpstPTR
74519370Spstmmalloc (md, size)
74619370Spst     PTR md;
74719370Spst     size_t size;
74819370Spst{
74919370Spst  return malloc (size);
75019370Spst}
75119370Spst
75219370SpstPTR
75319370Spstmrealloc (md, ptr, size)
75419370Spst     PTR md;
75519370Spst     PTR ptr;
75619370Spst     size_t size;
75719370Spst{
75819370Spst  if (ptr == 0)		/* Guard against old realloc's */
75919370Spst    return malloc (size);
76019370Spst  else
76119370Spst    return realloc (ptr, size);
76219370Spst}
76319370Spst
76419370Spstvoid
76519370Spstmfree (md, ptr)
76619370Spst     PTR md;
76719370Spst     PTR ptr;
76819370Spst{
76919370Spst  free (ptr);
77019370Spst}
77119370Spst
77246283Sdfr#endif	/* USE_MMALLOC */
77319370Spst
77446283Sdfr#if !defined (USE_MMALLOC) || defined (NO_MMCHECK)
77519370Spst
77619370Spstvoid
77719370Spstinit_malloc (md)
77819370Spst     PTR md;
77919370Spst{
78019370Spst}
78119370Spst
78246283Sdfr#else /* Have mmalloc and want corruption checking */
78319370Spst
78419370Spststatic void
78519370Spstmalloc_botch ()
78619370Spst{
78719370Spst  fatal_dump_core ("Memory corruption");
78819370Spst}
78919370Spst
79019370Spst/* Attempt to install hooks in mmalloc/mrealloc/mfree for the heap specified
79119370Spst   by MD, to detect memory corruption.  Note that MD may be NULL to specify
79219370Spst   the default heap that grows via sbrk.
79319370Spst
79446283Sdfr   Note that for freshly created regions, we must call mmcheckf prior to any
79519370Spst   mallocs in the region.  Otherwise, any region which was allocated prior to
79619370Spst   installing the checking hooks, which is later reallocated or freed, will
79719370Spst   fail the checks!  The mmcheck function only allows initial hooks to be
79819370Spst   installed before the first mmalloc.  However, anytime after we have called
79919370Spst   mmcheck the first time to install the checking hooks, we can call it again
80019370Spst   to update the function pointer to the memory corruption handler.
80119370Spst
80219370Spst   Returns zero on failure, non-zero on success. */
80319370Spst
80446283Sdfr#ifndef MMCHECK_FORCE
80546283Sdfr#define MMCHECK_FORCE 0
80646283Sdfr#endif
80746283Sdfr
80819370Spstvoid
80919370Spstinit_malloc (md)
81019370Spst     PTR md;
81119370Spst{
81246283Sdfr  if (!mmcheckf (md, malloc_botch, MMCHECK_FORCE))
81319370Spst    {
81446283Sdfr      /* Don't use warning(), which relies on current_target being set
81546283Sdfr	 to something other than dummy_target, until after
81646283Sdfr	 initialize_all_files(). */
81746283Sdfr
81846283Sdfr      fprintf_unfiltered
81946283Sdfr	(gdb_stderr, "warning: failed to install memory consistency checks; ");
82046283Sdfr      fprintf_unfiltered
82146283Sdfr	(gdb_stderr, "configuration should define NO_MMCHECK or MMCHECK_FORCE\n");
82219370Spst    }
82319370Spst
82419370Spst  mmtrace ();
82519370Spst}
82619370Spst
82719370Spst#endif /* Have mmalloc and want corruption checking  */
82819370Spst
82919370Spst/* Called when a memory allocation fails, with the number of bytes of
83019370Spst   memory requested in SIZE. */
83119370Spst
83219370SpstNORETURN void
83319370Spstnomem (size)
83419370Spst     long size;
83519370Spst{
83619370Spst  if (size > 0)
83719370Spst    {
83819370Spst      fatal ("virtual memory exhausted: can't allocate %ld bytes.", size);
83919370Spst    }
84019370Spst  else
84119370Spst    {
84219370Spst      fatal ("virtual memory exhausted.");
84319370Spst    }
84419370Spst}
84519370Spst
84619370Spst/* Like mmalloc but get error if no storage available, and protect against
84719370Spst   the caller wanting to allocate zero bytes.  Whether to return NULL for
84819370Spst   a zero byte request, or translate the request into a request for one
84919370Spst   byte of zero'd storage, is a religious issue. */
85019370Spst
85119370SpstPTR
85219370Spstxmmalloc (md, size)
85319370Spst     PTR md;
85419370Spst     long size;
85519370Spst{
85619370Spst  register PTR val;
85719370Spst
85819370Spst  if (size == 0)
85919370Spst    {
86019370Spst      val = NULL;
86119370Spst    }
86219370Spst  else if ((val = mmalloc (md, size)) == NULL)
86319370Spst    {
86419370Spst      nomem (size);
86519370Spst    }
86619370Spst  return (val);
86719370Spst}
86819370Spst
86919370Spst/* Like mrealloc but get error if no storage available.  */
87019370Spst
87119370SpstPTR
87219370Spstxmrealloc (md, ptr, size)
87319370Spst     PTR md;
87419370Spst     PTR ptr;
87519370Spst     long size;
87619370Spst{
87719370Spst  register PTR val;
87819370Spst
87919370Spst  if (ptr != NULL)
88019370Spst    {
88119370Spst      val = mrealloc (md, ptr, size);
88219370Spst    }
88319370Spst  else
88419370Spst    {
88519370Spst      val = mmalloc (md, size);
88619370Spst    }
88719370Spst  if (val == NULL)
88819370Spst    {
88919370Spst      nomem (size);
89019370Spst    }
89119370Spst  return (val);
89219370Spst}
89319370Spst
89419370Spst/* Like malloc but get error if no storage available, and protect against
89519370Spst   the caller wanting to allocate zero bytes.  */
89619370Spst
89719370SpstPTR
89819370Spstxmalloc (size)
89946283Sdfr     size_t size;
90019370Spst{
90119370Spst  return (xmmalloc ((PTR) NULL, size));
90219370Spst}
90319370Spst
90419370Spst/* Like mrealloc but get error if no storage available.  */
90519370Spst
90619370SpstPTR
90719370Spstxrealloc (ptr, size)
90819370Spst     PTR ptr;
90946283Sdfr     size_t size;
91019370Spst{
91119370Spst  return (xmrealloc ((PTR) NULL, ptr, size));
91219370Spst}
91319370Spst
91419370Spst
91519370Spst/* My replacement for the read system call.
91619370Spst   Used like `read' but keeps going if `read' returns too soon.  */
91719370Spst
91819370Spstint
91919370Spstmyread (desc, addr, len)
92019370Spst     int desc;
92119370Spst     char *addr;
92219370Spst     int len;
92319370Spst{
92419370Spst  register int val;
92519370Spst  int orglen = len;
92619370Spst
92719370Spst  while (len > 0)
92819370Spst    {
92919370Spst      val = read (desc, addr, len);
93019370Spst      if (val < 0)
93119370Spst	return val;
93219370Spst      if (val == 0)
93319370Spst	return orglen - len;
93419370Spst      len -= val;
93519370Spst      addr += val;
93619370Spst    }
93719370Spst  return orglen;
93819370Spst}
93919370Spst
94019370Spst/* Make a copy of the string at PTR with SIZE characters
94119370Spst   (and add a null character at the end in the copy).
94219370Spst   Uses malloc to get the space.  Returns the address of the copy.  */
94319370Spst
94419370Spstchar *
94519370Spstsavestring (ptr, size)
94619370Spst     const char *ptr;
94719370Spst     int size;
94819370Spst{
94919370Spst  register char *p = (char *) xmalloc (size + 1);
95019370Spst  memcpy (p, ptr, size);
95119370Spst  p[size] = 0;
95219370Spst  return p;
95319370Spst}
95419370Spst
95519370Spstchar *
95619370Spstmsavestring (md, ptr, size)
95719370Spst     PTR md;
95819370Spst     const char *ptr;
95919370Spst     int size;
96019370Spst{
96119370Spst  register char *p = (char *) xmmalloc (md, size + 1);
96219370Spst  memcpy (p, ptr, size);
96319370Spst  p[size] = 0;
96419370Spst  return p;
96519370Spst}
96619370Spst
96719370Spst/* The "const" is so it compiles under DGUX (which prototypes strsave
96819370Spst   in <string.h>.  FIXME: This should be named "xstrsave", shouldn't it?
96919370Spst   Doesn't real strsave return NULL if out of memory?  */
97019370Spstchar *
97119370Spststrsave (ptr)
97219370Spst     const char *ptr;
97319370Spst{
97419370Spst  return savestring (ptr, strlen (ptr));
97519370Spst}
97619370Spst
97719370Spstchar *
97819370Spstmstrsave (md, ptr)
97919370Spst     PTR md;
98019370Spst     const char *ptr;
98119370Spst{
98219370Spst  return (msavestring (md, ptr, strlen (ptr)));
98319370Spst}
98419370Spst
98519370Spstvoid
98619370Spstprint_spaces (n, file)
98719370Spst     register int n;
98846283Sdfr     register GDB_FILE *file;
98919370Spst{
99046283Sdfr  if (file->ts_streamtype == astring)
99146283Sdfr    {
99246283Sdfr      char *p;
99346283Sdfr
99446283Sdfr      gdb_file_adjust_strbuf (n, file);
99546283Sdfr      p = file->ts_strbuf + strlen (file->ts_strbuf);
99646283Sdfr
99746283Sdfr      memset (p, ' ', n);
99846283Sdfr      p[n] = '\000';
99946283Sdfr    }
100046283Sdfr  else
100146283Sdfr    {
100246283Sdfr      while (n-- > 0)
100346283Sdfr	fputc (' ', file->ts_filestream);
100446283Sdfr    }
100519370Spst}
100619370Spst
100719370Spst/* Print a host address.  */
100819370Spst
100919370Spstvoid
101019370Spstgdb_print_address (addr, stream)
101119370Spst     PTR addr;
101219370Spst     GDB_FILE *stream;
101319370Spst{
101419370Spst
101519370Spst  /* We could use the %p conversion specifier to fprintf if we had any
101619370Spst     way of knowing whether this host supports it.  But the following
101719370Spst     should work on the Alpha and on 32 bit machines.  */
101819370Spst
101919370Spst  fprintf_filtered (stream, "0x%lx", (unsigned long)addr);
102019370Spst}
102119370Spst
102219370Spst/* Ask user a y-or-n question and return 1 iff answer is yes.
102319370Spst   Takes three args which are given to printf to print the question.
102419370Spst   The first, a control string, should end in "? ".
102519370Spst   It should not say how to answer, because we do that.  */
102619370Spst
102719370Spst/* VARARGS */
102819370Spstint
102919370Spst#ifdef ANSI_PROTOTYPES
103019370Spstquery (char *ctlstr, ...)
103119370Spst#else
103219370Spstquery (va_alist)
103319370Spst     va_dcl
103419370Spst#endif
103519370Spst{
103619370Spst  va_list args;
103719370Spst  register int answer;
103819370Spst  register int ans2;
103919370Spst  int retval;
104019370Spst
104119370Spst#ifdef ANSI_PROTOTYPES
104219370Spst  va_start (args, ctlstr);
104319370Spst#else
104419370Spst  char *ctlstr;
104519370Spst  va_start (args);
104619370Spst  ctlstr = va_arg (args, char *);
104719370Spst#endif
104819370Spst
104919370Spst  if (query_hook)
105019370Spst    {
105119370Spst      return query_hook (ctlstr, args);
105219370Spst    }
105319370Spst
105419370Spst  /* Automatically answer "yes" if input is not from a terminal.  */
105519370Spst  if (!input_from_terminal_p ())
105619370Spst    return 1;
105719370Spst#ifdef MPW
105819370Spst  /* FIXME Automatically answer "yes" if called from MacGDB.  */
105919370Spst  if (mac_app)
106019370Spst    return 1;
106119370Spst#endif /* MPW */
106219370Spst
106319370Spst  while (1)
106419370Spst    {
106519370Spst      wrap_here ("");		/* Flush any buffered output */
106619370Spst      gdb_flush (gdb_stdout);
106719370Spst
106819370Spst      if (annotation_level > 1)
106919370Spst	printf_filtered ("\n\032\032pre-query\n");
107019370Spst
107119370Spst      vfprintf_filtered (gdb_stdout, ctlstr, args);
107219370Spst      printf_filtered ("(y or n) ");
107319370Spst
107419370Spst      if (annotation_level > 1)
107519370Spst	printf_filtered ("\n\032\032query\n");
107619370Spst
107719370Spst#ifdef MPW
107819370Spst      /* If not in MacGDB, move to a new line so the entered line doesn't
107919370Spst	 have a prompt on the front of it. */
108019370Spst      if (!mac_app)
108119370Spst	fputs_unfiltered ("\n", gdb_stdout);
108219370Spst#endif /* MPW */
108319370Spst
108446283Sdfr      wrap_here("");
108519370Spst      gdb_flush (gdb_stdout);
108646283Sdfr
108746283Sdfr#if defined(TUI)
108846283Sdfr      if (!tui_version || cmdWin == tuiWinWithFocus())
108946283Sdfr#endif
109046283Sdfr	answer = fgetc (stdin);
109146283Sdfr#if defined(TUI)
109246283Sdfr      else
109346283Sdfr
109446283Sdfr        answer = (unsigned char)tuiBufferGetc();
109546283Sdfr
109646283Sdfr#endif
109719370Spst      clearerr (stdin);		/* in case of C-d */
109819370Spst      if (answer == EOF)	/* C-d */
109919370Spst        {
110019370Spst	  retval = 1;
110119370Spst	  break;
110219370Spst	}
110346283Sdfr      /* Eat rest of input line, to EOF or newline */
110446283Sdfr      if ((answer != '\n') || (tui_version && answer != '\r'))
110519370Spst	do
110619370Spst	  {
110746283Sdfr#if defined(TUI)
110846283Sdfr	    if (!tui_version || cmdWin == tuiWinWithFocus())
110946283Sdfr#endif
111046283Sdfr	      ans2 = fgetc (stdin);
111146283Sdfr#if defined(TUI)
111246283Sdfr	    else
111346283Sdfr
111446283Sdfr              ans2 = (unsigned char)tuiBufferGetc();
111546283Sdfr#endif
111619370Spst	    clearerr (stdin);
111719370Spst	  }
111846283Sdfr        while (ans2 != EOF && ans2 != '\n' && ans2 != '\r');
111946283Sdfr      TUIDO(((TuiOpaqueFuncPtr)tui_vStartNewLines, 1));
112046283Sdfr
112119370Spst      if (answer >= 'a')
112219370Spst	answer -= 040;
112319370Spst      if (answer == 'Y')
112419370Spst	{
112519370Spst	  retval = 1;
112619370Spst	  break;
112719370Spst	}
112819370Spst      if (answer == 'N')
112919370Spst	{
113019370Spst	  retval = 0;
113119370Spst	  break;
113219370Spst	}
113319370Spst      printf_filtered ("Please answer y or n.\n");
113419370Spst    }
113519370Spst
113619370Spst  if (annotation_level > 1)
113719370Spst    printf_filtered ("\n\032\032post-query\n");
113819370Spst  return retval;
113919370Spst}
114019370Spst
114119370Spst
114219370Spst/* Parse a C escape sequence.  STRING_PTR points to a variable
114319370Spst   containing a pointer to the string to parse.  That pointer
114419370Spst   should point to the character after the \.  That pointer
114519370Spst   is updated past the characters we use.  The value of the
114619370Spst   escape sequence is returned.
114719370Spst
114819370Spst   A negative value means the sequence \ newline was seen,
114919370Spst   which is supposed to be equivalent to nothing at all.
115019370Spst
115119370Spst   If \ is followed by a null character, we return a negative
115219370Spst   value and leave the string pointer pointing at the null character.
115319370Spst
115419370Spst   If \ is followed by 000, we return 0 and leave the string pointer
115519370Spst   after the zeros.  A value of 0 does not mean end of string.  */
115619370Spst
115719370Spstint
115819370Spstparse_escape (string_ptr)
115919370Spst     char **string_ptr;
116019370Spst{
116119370Spst  register int c = *(*string_ptr)++;
116219370Spst  switch (c)
116319370Spst    {
116419370Spst    case 'a':
116519370Spst      return 007;		/* Bell (alert) char */
116619370Spst    case 'b':
116719370Spst      return '\b';
116819370Spst    case 'e':			/* Escape character */
116919370Spst      return 033;
117019370Spst    case 'f':
117119370Spst      return '\f';
117219370Spst    case 'n':
117319370Spst      return '\n';
117419370Spst    case 'r':
117519370Spst      return '\r';
117619370Spst    case 't':
117719370Spst      return '\t';
117819370Spst    case 'v':
117919370Spst      return '\v';
118019370Spst    case '\n':
118119370Spst      return -2;
118219370Spst    case 0:
118319370Spst      (*string_ptr)--;
118419370Spst      return 0;
118519370Spst    case '^':
118619370Spst      c = *(*string_ptr)++;
118719370Spst      if (c == '\\')
118819370Spst	c = parse_escape (string_ptr);
118919370Spst      if (c == '?')
119019370Spst	return 0177;
119119370Spst      return (c & 0200) | (c & 037);
119219370Spst
119319370Spst    case '0':
119419370Spst    case '1':
119519370Spst    case '2':
119619370Spst    case '3':
119719370Spst    case '4':
119819370Spst    case '5':
119919370Spst    case '6':
120019370Spst    case '7':
120119370Spst      {
120219370Spst	register int i = c - '0';
120319370Spst	register int count = 0;
120419370Spst	while (++count < 3)
120519370Spst	  {
120619370Spst	    if ((c = *(*string_ptr)++) >= '0' && c <= '7')
120719370Spst	      {
120819370Spst		i *= 8;
120919370Spst		i += c - '0';
121019370Spst	      }
121119370Spst	    else
121219370Spst	      {
121319370Spst		(*string_ptr)--;
121419370Spst		break;
121519370Spst	      }
121619370Spst	  }
121719370Spst	return i;
121819370Spst      }
121919370Spst    default:
122019370Spst      return c;
122119370Spst    }
122219370Spst}
122319370Spst
122419370Spst/* Print the character C on STREAM as part of the contents of a literal
122519370Spst   string whose delimiter is QUOTER.  Note that this routine should only
122619370Spst   be call for printing things which are independent of the language
122719370Spst   of the program being debugged. */
122819370Spst
122919370Spstvoid
123019370Spstgdb_printchar (c, stream, quoter)
123119370Spst     register int c;
123246283Sdfr     GDB_FILE *stream;
123319370Spst     int quoter;
123419370Spst{
123519370Spst
123619370Spst  c &= 0xFF;			/* Avoid sign bit follies */
123719370Spst
123819370Spst  if (              c < 0x20  ||		/* Low control chars */
123919370Spst      (c >= 0x7F && c < 0xA0) ||		/* DEL, High controls */
124019370Spst      (sevenbit_strings && c >= 0x80)) {	/* high order bit set */
124119370Spst    switch (c)
124219370Spst      {
124319370Spst      case '\n':
124419370Spst	fputs_filtered ("\\n", stream);
124519370Spst	break;
124619370Spst      case '\b':
124719370Spst	fputs_filtered ("\\b", stream);
124819370Spst	break;
124919370Spst      case '\t':
125019370Spst	fputs_filtered ("\\t", stream);
125119370Spst	break;
125219370Spst      case '\f':
125319370Spst	fputs_filtered ("\\f", stream);
125419370Spst	break;
125519370Spst      case '\r':
125619370Spst	fputs_filtered ("\\r", stream);
125719370Spst	break;
125819370Spst      case '\033':
125919370Spst	fputs_filtered ("\\e", stream);
126019370Spst	break;
126119370Spst      case '\007':
126219370Spst	fputs_filtered ("\\a", stream);
126319370Spst	break;
126419370Spst      default:
126519370Spst	fprintf_filtered (stream, "\\%.3o", (unsigned int) c);
126619370Spst	break;
126719370Spst      }
126819370Spst  } else {
126919370Spst    if (c == '\\' || c == quoter)
127019370Spst      fputs_filtered ("\\", stream);
127119370Spst    fprintf_filtered (stream, "%c", c);
127219370Spst  }
127319370Spst}
127446283Sdfr
127546283Sdfr
127646283Sdfr
127746283Sdfr
127846283Sdfrstatic char * hexlate = "0123456789abcdef" ;
127946283Sdfrint fmthex(inbuf,outbuff,length,linelength)
128046283Sdfr     unsigned char * inbuf ;
128146283Sdfr     unsigned char * outbuff;
128246283Sdfr     int length;
128346283Sdfr     int linelength;
128446283Sdfr{
128546283Sdfr  unsigned char byte , nib ;
128646283Sdfr  int outlength = 0 ;
128746283Sdfr
128846283Sdfr  while (length)
128946283Sdfr    {
129046283Sdfr      if (outlength >= linelength) break ;
129146283Sdfr      byte = *inbuf ;
129246283Sdfr      inbuf++ ;
129346283Sdfr      nib = byte >> 4 ;
129446283Sdfr      *outbuff++ = hexlate[nib] ;
129546283Sdfr      nib = byte &0x0f ;
129646283Sdfr      *outbuff++ = hexlate[nib] ;
129746283Sdfr      *outbuff++ = ' ' ;
129846283Sdfr      length-- ;
129946283Sdfr      outlength += 3 ;
130046283Sdfr    }
130146283Sdfr  *outbuff = '\0' ; /* null terminate our output line */
130246283Sdfr  return outlength ;
130346283Sdfr}
130446283Sdfr
130519370Spst
130619370Spst/* Number of lines per page or UINT_MAX if paging is disabled.  */
130719370Spststatic unsigned int lines_per_page;
130819370Spst/* Number of chars per line or UNIT_MAX is line folding is disabled.  */
130919370Spststatic unsigned int chars_per_line;
131019370Spst/* Current count of lines printed on this page, chars on this line.  */
131119370Spststatic unsigned int lines_printed, chars_printed;
131219370Spst
131319370Spst/* Buffer and start column of buffered text, for doing smarter word-
131419370Spst   wrapping.  When someone calls wrap_here(), we start buffering output
131519370Spst   that comes through fputs_filtered().  If we see a newline, we just
131619370Spst   spit it out and forget about the wrap_here().  If we see another
131719370Spst   wrap_here(), we spit it out and remember the newer one.  If we see
131819370Spst   the end of the line, we spit out a newline, the indent, and then
131919370Spst   the buffered output.  */
132019370Spst
132119370Spst/* Malloc'd buffer with chars_per_line+2 bytes.  Contains characters which
132219370Spst   are waiting to be output (they have already been counted in chars_printed).
132319370Spst   When wrap_buffer[0] is null, the buffer is empty.  */
132419370Spststatic char *wrap_buffer;
132519370Spst
132619370Spst/* Pointer in wrap_buffer to the next character to fill.  */
132719370Spststatic char *wrap_pointer;
132819370Spst
132919370Spst/* String to indent by if the wrap occurs.  Must not be NULL if wrap_column
133019370Spst   is non-zero.  */
133119370Spststatic char *wrap_indent;
133219370Spst
133319370Spst/* Column number on the screen where wrap_buffer begins, or 0 if wrapping
133419370Spst   is not in effect.  */
133519370Spststatic int wrap_column;
133619370Spst
133746283Sdfr
133846283Sdfr/* Inialize the lines and chars per page */
133946283Sdfrvoid
134046283Sdfrinit_page_info()
134119370Spst{
134246283Sdfr#if defined(TUI)
134346283Sdfr  if (tui_version && m_winPtrNotNull(cmdWin))
134446283Sdfr    {
134546283Sdfr      lines_per_page = cmdWin->generic.height;
134646283Sdfr      chars_per_line = cmdWin->generic.width;
134746283Sdfr    }
134846283Sdfr  else
134946283Sdfr#endif
135046283Sdfr    {
135146283Sdfr      /* These defaults will be used if we are unable to get the correct
135246283Sdfr         values from termcap.  */
135346283Sdfr#if defined(__GO32__)
135446283Sdfr      lines_per_page = ScreenRows();
135546283Sdfr      chars_per_line = ScreenCols();
135646283Sdfr#else
135746283Sdfr      lines_per_page = 24;
135846283Sdfr      chars_per_line = 80;
135946283Sdfr
136046283Sdfr#if !defined (MPW) && !defined (_WIN32)
136146283Sdfr      /* No termcap under MPW, although might be cool to do something
136246283Sdfr         by looking at worksheet or console window sizes. */
136346283Sdfr      /* Initialize the screen height and width from termcap.  */
136446283Sdfr      {
136546283Sdfr        char *termtype = getenv ("TERM");
136646283Sdfr
136746283Sdfr        /* Positive means success, nonpositive means failure.  */
136846283Sdfr        int status;
136946283Sdfr
137046283Sdfr        /* 2048 is large enough for all known terminals, according to the
137146283Sdfr           GNU termcap manual.  */
137246283Sdfr        char term_buffer[2048];
137346283Sdfr
137446283Sdfr        if (termtype)
137546283Sdfr          {
137646283Sdfr	    status = tgetent (term_buffer, termtype);
137746283Sdfr	    if (status > 0)
137846283Sdfr	      {
137946283Sdfr	        int val;
138046283Sdfr		int running_in_emacs = getenv ("EMACS") != NULL;
138146283Sdfr
138246283Sdfr	        val = tgetnum ("li");
138346283Sdfr	        if (val >= 0 && !running_in_emacs)
138446283Sdfr	          lines_per_page = val;
138546283Sdfr	        else
138646283Sdfr	          /* The number of lines per page is not mentioned
138746283Sdfr		     in the terminal description.  This probably means
138846283Sdfr		     that paging is not useful (e.g. emacs shell window),
138946283Sdfr		     so disable paging.  */
139046283Sdfr	          lines_per_page = UINT_MAX;
139146283Sdfr
139246283Sdfr	        val = tgetnum ("co");
139346283Sdfr	        if (val >= 0)
139446283Sdfr	          chars_per_line = val;
139546283Sdfr	      }
139646283Sdfr          }
139746283Sdfr      }
139846283Sdfr#endif /* MPW */
139946283Sdfr
140046283Sdfr#if defined(SIGWINCH) && defined(SIGWINCH_HANDLER)
140146283Sdfr
140246283Sdfr      /* If there is a better way to determine the window size, use it. */
140346283Sdfr      SIGWINCH_HANDLER (SIGWINCH);
140446283Sdfr#endif
140546283Sdfr#endif
140646283Sdfr      /* If the output is not a terminal, don't paginate it.  */
140746283Sdfr      if (!GDB_FILE_ISATTY (gdb_stdout))
140846283Sdfr        lines_per_page = UINT_MAX;
140946283Sdfr  } /* the command_line_version */
141046283Sdfr  set_width();
141146283Sdfr}
141246283Sdfr
141346283Sdfrstatic void
141446283Sdfrset_width()
141546283Sdfr{
141646283Sdfr  if (chars_per_line == 0)
141746283Sdfr    init_page_info();
141846283Sdfr
141919370Spst  if (!wrap_buffer)
142019370Spst    {
142119370Spst      wrap_buffer = (char *) xmalloc (chars_per_line + 2);
142219370Spst      wrap_buffer[0] = '\0';
142319370Spst    }
142419370Spst  else
142519370Spst    wrap_buffer = (char *) xrealloc (wrap_buffer, chars_per_line + 2);
142646283Sdfr  wrap_pointer = wrap_buffer;   /* Start it at the beginning */
142719370Spst}
142819370Spst
142946283Sdfr/* ARGSUSED */
143046283Sdfrstatic void
143146283Sdfrset_width_command (args, from_tty, c)
143246283Sdfr     char *args;
143346283Sdfr     int from_tty;
143446283Sdfr     struct cmd_list_element *c;
143546283Sdfr{
143646283Sdfr  set_width ();
143746283Sdfr}
143846283Sdfr
143919370Spst/* Wait, so the user can read what's on the screen.  Prompt the user
144019370Spst   to continue by pressing RETURN.  */
144119370Spst
144219370Spststatic void
144319370Spstprompt_for_continue ()
144419370Spst{
144519370Spst  char *ignore;
144619370Spst  char cont_prompt[120];
144719370Spst
144819370Spst  if (annotation_level > 1)
144919370Spst    printf_unfiltered ("\n\032\032pre-prompt-for-continue\n");
145019370Spst
145119370Spst  strcpy (cont_prompt,
145219370Spst	  "---Type <return> to continue, or q <return> to quit---");
145319370Spst  if (annotation_level > 1)
145419370Spst    strcat (cont_prompt, "\n\032\032prompt-for-continue\n");
145519370Spst
145619370Spst  /* We must do this *before* we call gdb_readline, else it will eventually
145719370Spst     call us -- thinking that we're trying to print beyond the end of the
145819370Spst     screen.  */
145919370Spst  reinitialize_more_filter ();
146019370Spst
146119370Spst  immediate_quit++;
146219370Spst  /* On a real operating system, the user can quit with SIGINT.
146319370Spst     But not on GO32.
146419370Spst
146519370Spst     'q' is provided on all systems so users don't have to change habits
146619370Spst     from system to system, and because telling them what to do in
146719370Spst     the prompt is more user-friendly than expecting them to think of
146819370Spst     SIGINT.  */
146919370Spst  /* Call readline, not gdb_readline, because GO32 readline handles control-C
147019370Spst     whereas control-C to gdb_readline will cause the user to get dumped
147119370Spst     out to DOS.  */
147219370Spst  ignore = readline (cont_prompt);
147319370Spst
147419370Spst  if (annotation_level > 1)
147519370Spst    printf_unfiltered ("\n\032\032post-prompt-for-continue\n");
147619370Spst
147719370Spst  if (ignore)
147819370Spst    {
147919370Spst      char *p = ignore;
148019370Spst      while (*p == ' ' || *p == '\t')
148119370Spst	++p;
148219370Spst      if (p[0] == 'q')
148319370Spst	request_quit (SIGINT);
148419370Spst      free (ignore);
148519370Spst    }
148619370Spst  immediate_quit--;
148719370Spst
148819370Spst  /* Now we have to do this again, so that GDB will know that it doesn't
148919370Spst     need to save the ---Type <return>--- line at the top of the screen.  */
149019370Spst  reinitialize_more_filter ();
149119370Spst
149219370Spst  dont_repeat ();		/* Forget prev cmd -- CR won't repeat it. */
149319370Spst}
149419370Spst
149519370Spst/* Reinitialize filter; ie. tell it to reset to original values.  */
149619370Spst
149719370Spstvoid
149819370Spstreinitialize_more_filter ()
149919370Spst{
150019370Spst  lines_printed = 0;
150119370Spst  chars_printed = 0;
150219370Spst}
150319370Spst
150419370Spst/* Indicate that if the next sequence of characters overflows the line,
150519370Spst   a newline should be inserted here rather than when it hits the end.
150619370Spst   If INDENT is non-null, it is a string to be printed to indent the
150719370Spst   wrapped part on the next line.  INDENT must remain accessible until
150819370Spst   the next call to wrap_here() or until a newline is printed through
150919370Spst   fputs_filtered().
151019370Spst
151119370Spst   If the line is already overfull, we immediately print a newline and
151219370Spst   the indentation, and disable further wrapping.
151319370Spst
151419370Spst   If we don't know the width of lines, but we know the page height,
151519370Spst   we must not wrap words, but should still keep track of newlines
151619370Spst   that were explicitly printed.
151719370Spst
151819370Spst   INDENT should not contain tabs, as that will mess up the char count
151919370Spst   on the next line.  FIXME.
152019370Spst
152119370Spst   This routine is guaranteed to force out any output which has been
152219370Spst   squirreled away in the wrap_buffer, so wrap_here ((char *)0) can be
152319370Spst   used to force out output from the wrap_buffer.  */
152419370Spst
152519370Spstvoid
152619370Spstwrap_here(indent)
152719370Spst     char *indent;
152819370Spst{
152919370Spst  /* This should have been allocated, but be paranoid anyway. */
153019370Spst  if (!wrap_buffer)
153119370Spst    abort ();
153219370Spst
153319370Spst  if (wrap_buffer[0])
153419370Spst    {
153519370Spst      *wrap_pointer = '\0';
153619370Spst      fputs_unfiltered (wrap_buffer, gdb_stdout);
153719370Spst    }
153819370Spst  wrap_pointer = wrap_buffer;
153919370Spst  wrap_buffer[0] = '\0';
154019370Spst  if (chars_per_line == UINT_MAX)		/* No line overflow checking */
154119370Spst    {
154219370Spst      wrap_column = 0;
154319370Spst    }
154419370Spst  else if (chars_printed >= chars_per_line)
154519370Spst    {
154619370Spst      puts_filtered ("\n");
154719370Spst      if (indent != NULL)
154819370Spst	puts_filtered (indent);
154919370Spst      wrap_column = 0;
155019370Spst    }
155119370Spst  else
155219370Spst    {
155319370Spst      wrap_column = chars_printed;
155419370Spst      if (indent == NULL)
155519370Spst	wrap_indent = "";
155619370Spst      else
155719370Spst	wrap_indent = indent;
155819370Spst    }
155919370Spst}
156019370Spst
156119370Spst/* Ensure that whatever gets printed next, using the filtered output
156219370Spst   commands, starts at the beginning of the line.  I.E. if there is
156319370Spst   any pending output for the current line, flush it and start a new
156419370Spst   line.  Otherwise do nothing. */
156519370Spst
156619370Spstvoid
156719370Spstbegin_line ()
156819370Spst{
156919370Spst  if (chars_printed > 0)
157019370Spst    {
157119370Spst      puts_filtered ("\n");
157219370Spst    }
157319370Spst}
157419370Spst
157546283Sdfrint
157646283Sdfrgdb_file_isatty (stream)
157746283Sdfr    GDB_FILE *stream;
157846283Sdfr{
157919370Spst
158046283Sdfr  if (stream->ts_streamtype == afile)
158146283Sdfr     return (isatty(fileno(stream->ts_filestream)));
158246283Sdfr  else return 0;
158346283Sdfr}
158446283Sdfr
158519370SpstGDB_FILE *
158646283Sdfrgdb_file_init_astring (n)
158746283Sdfr    int n;
158846283Sdfr{
158946283Sdfr  GDB_FILE *tmpstream;
159046283Sdfr
159146283Sdfr  tmpstream = xmalloc (sizeof(GDB_FILE));
159246283Sdfr  tmpstream->ts_streamtype = astring;
159346283Sdfr  tmpstream->ts_filestream = NULL;
159446283Sdfr  if (n > 0)
159546283Sdfr    {
159646283Sdfr      tmpstream->ts_strbuf = xmalloc ((n + 1)*sizeof(char));
159746283Sdfr      tmpstream->ts_strbuf[0] = '\0';
159846283Sdfr    }
159946283Sdfr  else
160046283Sdfr     tmpstream->ts_strbuf = NULL;
160146283Sdfr  tmpstream->ts_buflen = n;
160246283Sdfr
160346283Sdfr  return tmpstream;
160446283Sdfr}
160546283Sdfr
160646283Sdfrvoid
160746283Sdfrgdb_file_deallocate (streamptr)
160846283Sdfr    GDB_FILE **streamptr;
160946283Sdfr{
161046283Sdfr  GDB_FILE *tmpstream;
161146283Sdfr
161246283Sdfr  tmpstream = *streamptr;
161346283Sdfr  if ((tmpstream->ts_streamtype == astring) &&
161446283Sdfr      (tmpstream->ts_strbuf != NULL))
161546283Sdfr    {
161646283Sdfr      free (tmpstream->ts_strbuf);
161746283Sdfr    }
161846283Sdfr
161946283Sdfr  free (tmpstream);
162046283Sdfr  *streamptr = NULL;
162146283Sdfr}
162246283Sdfr
162346283Sdfrchar *
162446283Sdfrgdb_file_get_strbuf (stream)
162546283Sdfr     GDB_FILE *stream;
162646283Sdfr{
162746283Sdfr  return (stream->ts_strbuf);
162846283Sdfr}
162946283Sdfr
163046283Sdfr/* adjust the length of the buffer by the amount necessary
163146283Sdfr   to accomodate appending a string of length N to the buffer contents */
163246283Sdfrvoid
163346283Sdfrgdb_file_adjust_strbuf (n, stream)
163446283Sdfr     int n;
163546283Sdfr     GDB_FILE *stream;
163646283Sdfr{
163746283Sdfr  int non_null_chars;
163846283Sdfr
163946283Sdfr  non_null_chars = strlen(stream->ts_strbuf);
164046283Sdfr
164146283Sdfr  if (n > (stream->ts_buflen - non_null_chars - 1))
164246283Sdfr    {
164346283Sdfr      stream->ts_buflen = n + non_null_chars + 1;
164446283Sdfr      stream->ts_strbuf = xrealloc (stream->ts_strbuf, stream->ts_buflen);
164546283Sdfr    }
164646283Sdfr}
164746283Sdfr
164846283SdfrGDB_FILE *
164919370Spstgdb_fopen (name, mode)
165019370Spst     char * name;
165119370Spst     char * mode;
165219370Spst{
165346283Sdfr  int       gdb_file_size;
165446283Sdfr  GDB_FILE *tmp;
165546283Sdfr
165646283Sdfr  gdb_file_size = sizeof(GDB_FILE);
165746283Sdfr  tmp = (GDB_FILE *) xmalloc (gdb_file_size);
165846283Sdfr  tmp->ts_streamtype = afile;
165946283Sdfr  tmp->ts_filestream = fopen (name, mode);
166046283Sdfr  tmp->ts_strbuf = NULL;
166146283Sdfr  tmp->ts_buflen = 0;
166246283Sdfr
166346283Sdfr  return tmp;
166419370Spst}
166519370Spst
166619370Spstvoid
166719370Spstgdb_flush (stream)
166846283Sdfr     GDB_FILE *stream;
166919370Spst{
167046283Sdfr  if (flush_hook
167146283Sdfr      && (stream == gdb_stdout
167246283Sdfr	  || stream == gdb_stderr))
167319370Spst    {
167419370Spst      flush_hook (stream);
167519370Spst      return;
167619370Spst    }
167719370Spst
167846283Sdfr  fflush (stream->ts_filestream);
167919370Spst}
168019370Spst
168146283Sdfrvoid
168246283Sdfrgdb_fclose(streamptr)
168346283Sdfr     GDB_FILE **streamptr;
168446283Sdfr{
168546283Sdfr  GDB_FILE *tmpstream;
168646283Sdfr
168746283Sdfr  tmpstream = *streamptr;
168846283Sdfr  fclose (tmpstream->ts_filestream);
168946283Sdfr  gdb_file_deallocate (streamptr);
169046283Sdfr}
169146283Sdfr
169219370Spst/* Like fputs but if FILTER is true, pause after every screenful.
169319370Spst
169419370Spst   Regardless of FILTER can wrap at points other than the final
169519370Spst   character of a line.
169619370Spst
169719370Spst   Unlike fputs, fputs_maybe_filtered does not return a value.
169819370Spst   It is OK for LINEBUFFER to be NULL, in which case just don't print
169919370Spst   anything.
170019370Spst
170119370Spst   Note that a longjmp to top level may occur in this routine (only if
170219370Spst   FILTER is true) (since prompt_for_continue may do so) so this
170319370Spst   routine should not be called when cleanups are not in place.  */
170419370Spst
170519370Spststatic void
170619370Spstfputs_maybe_filtered (linebuffer, stream, filter)
170719370Spst     const char *linebuffer;
170846283Sdfr     GDB_FILE *stream;
170919370Spst     int filter;
171019370Spst{
171119370Spst  const char *lineptr;
171219370Spst
171319370Spst  if (linebuffer == 0)
171419370Spst    return;
171519370Spst
171619370Spst  /* Don't do any filtering if it is disabled.  */
171719370Spst  if (stream != gdb_stdout
171819370Spst   || (lines_per_page == UINT_MAX && chars_per_line == UINT_MAX))
171919370Spst    {
172019370Spst      fputs_unfiltered (linebuffer, stream);
172119370Spst      return;
172219370Spst    }
172319370Spst
172419370Spst  /* Go through and output each character.  Show line extension
172519370Spst     when this is necessary; prompt user for new page when this is
172619370Spst     necessary.  */
172719370Spst
172819370Spst  lineptr = linebuffer;
172919370Spst  while (*lineptr)
173019370Spst    {
173119370Spst      /* Possible new page.  */
173219370Spst      if (filter &&
173319370Spst	  (lines_printed >= lines_per_page - 1))
173419370Spst	prompt_for_continue ();
173519370Spst
173619370Spst      while (*lineptr && *lineptr != '\n')
173719370Spst	{
173819370Spst	  /* Print a single line.  */
173919370Spst	  if (*lineptr == '\t')
174019370Spst	    {
174119370Spst	      if (wrap_column)
174219370Spst		*wrap_pointer++ = '\t';
174319370Spst	      else
174419370Spst		fputc_unfiltered ('\t', stream);
174519370Spst	      /* Shifting right by 3 produces the number of tab stops
174619370Spst	         we have already passed, and then adding one and
174719370Spst		 shifting left 3 advances to the next tab stop.  */
174819370Spst	      chars_printed = ((chars_printed >> 3) + 1) << 3;
174919370Spst	      lineptr++;
175019370Spst	    }
175119370Spst	  else
175219370Spst	    {
175319370Spst	      if (wrap_column)
175419370Spst		*wrap_pointer++ = *lineptr;
175519370Spst	      else
175619370Spst	        fputc_unfiltered (*lineptr, stream);
175719370Spst	      chars_printed++;
175819370Spst	      lineptr++;
175919370Spst	    }
176019370Spst
176119370Spst	  if (chars_printed >= chars_per_line)
176219370Spst	    {
176319370Spst	      unsigned int save_chars = chars_printed;
176419370Spst
176519370Spst	      chars_printed = 0;
176619370Spst	      lines_printed++;
176719370Spst	      /* If we aren't actually wrapping, don't output newline --
176819370Spst		 if chars_per_line is right, we probably just overflowed
176919370Spst		 anyway; if it's wrong, let us keep going.  */
177019370Spst	      if (wrap_column)
177119370Spst		fputc_unfiltered ('\n', stream);
177219370Spst
177319370Spst	      /* Possible new page.  */
177419370Spst	      if (lines_printed >= lines_per_page - 1)
177519370Spst		prompt_for_continue ();
177619370Spst
177719370Spst	      /* Now output indentation and wrapped string */
177819370Spst	      if (wrap_column)
177919370Spst		{
178019370Spst		  fputs_unfiltered (wrap_indent, stream);
178119370Spst		  *wrap_pointer = '\0';	/* Null-terminate saved stuff */
178219370Spst		  fputs_unfiltered (wrap_buffer, stream); /* and eject it */
178319370Spst		  /* FIXME, this strlen is what prevents wrap_indent from
178419370Spst		     containing tabs.  However, if we recurse to print it
178519370Spst		     and count its chars, we risk trouble if wrap_indent is
178619370Spst		     longer than (the user settable) chars_per_line.
178719370Spst		     Note also that this can set chars_printed > chars_per_line
178819370Spst		     if we are printing a long string.  */
178919370Spst		  chars_printed = strlen (wrap_indent)
179019370Spst				+ (save_chars - wrap_column);
179119370Spst		  wrap_pointer = wrap_buffer;	/* Reset buffer */
179219370Spst		  wrap_buffer[0] = '\0';
179319370Spst		  wrap_column = 0;		/* And disable fancy wrap */
179419370Spst 		}
179519370Spst	    }
179619370Spst	}
179719370Spst
179819370Spst      if (*lineptr == '\n')
179919370Spst	{
180019370Spst	  chars_printed = 0;
180119370Spst	  wrap_here ((char *)0);  /* Spit out chars, cancel further wraps */
180219370Spst	  lines_printed++;
180319370Spst	  fputc_unfiltered ('\n', stream);
180419370Spst	  lineptr++;
180519370Spst	}
180619370Spst    }
180719370Spst}
180819370Spst
180919370Spstvoid
181019370Spstfputs_filtered (linebuffer, stream)
181119370Spst     const char *linebuffer;
181246283Sdfr     GDB_FILE *stream;
181319370Spst{
181419370Spst  fputs_maybe_filtered (linebuffer, stream, 1);
181519370Spst}
181619370Spst
181719370Spstint
181819370Spstputchar_unfiltered (c)
181919370Spst     int c;
182019370Spst{
182119370Spst  char buf[2];
182219370Spst
182319370Spst  buf[0] = c;
182419370Spst  buf[1] = 0;
182519370Spst  fputs_unfiltered (buf, gdb_stdout);
182619370Spst  return c;
182719370Spst}
182819370Spst
182919370Spstint
183019370Spstfputc_unfiltered (c, stream)
183119370Spst     int c;
183246283Sdfr     GDB_FILE * stream;
183319370Spst{
183419370Spst  char buf[2];
183519370Spst
183619370Spst  buf[0] = c;
183719370Spst  buf[1] = 0;
183819370Spst  fputs_unfiltered (buf, stream);
183919370Spst  return c;
184019370Spst}
184119370Spst
184246283Sdfrint
184346283Sdfrfputc_filtered (c, stream)
184446283Sdfr     int c;
184546283Sdfr     GDB_FILE * stream;
184646283Sdfr{
184746283Sdfr  char buf[2];
184819370Spst
184946283Sdfr  buf[0] = c;
185046283Sdfr  buf[1] = 0;
185146283Sdfr  fputs_filtered (buf, stream);
185246283Sdfr  return c;
185346283Sdfr}
185446283Sdfr
185546283Sdfr/* puts_debug is like fputs_unfiltered, except it prints special
185646283Sdfr   characters in printable fashion.  */
185746283Sdfr
185846283Sdfrvoid
185946283Sdfrputs_debug (prefix, string, suffix)
186046283Sdfr     char *prefix;
186146283Sdfr     char *string;
186246283Sdfr     char *suffix;
186346283Sdfr{
186446283Sdfr  int ch;
186546283Sdfr
186646283Sdfr  /* Print prefix and suffix after each line.  */
186746283Sdfr  static int new_line = 1;
186846283Sdfr  static int return_p = 0;
186946283Sdfr  static char *prev_prefix = "";
187046283Sdfr  static char *prev_suffix = "";
187146283Sdfr
187246283Sdfr  if (*string == '\n')
187346283Sdfr    return_p = 0;
187446283Sdfr
187546283Sdfr  /* If the prefix is changing, print the previous suffix, a new line,
187646283Sdfr     and the new prefix.  */
187746283Sdfr  if ((return_p || (strcmp(prev_prefix, prefix) != 0)) && !new_line)
187846283Sdfr    {
187946283Sdfr      fputs_unfiltered (prev_suffix, gdb_stderr);
188046283Sdfr      fputs_unfiltered ("\n", gdb_stderr);
188146283Sdfr      fputs_unfiltered (prefix, gdb_stderr);
188246283Sdfr    }
188346283Sdfr
188446283Sdfr  /* Print prefix if we printed a newline during the previous call.  */
188546283Sdfr  if (new_line)
188646283Sdfr    {
188746283Sdfr      new_line = 0;
188846283Sdfr      fputs_unfiltered (prefix, gdb_stderr);
188946283Sdfr    }
189046283Sdfr
189146283Sdfr  prev_prefix = prefix;
189246283Sdfr  prev_suffix = suffix;
189346283Sdfr
189446283Sdfr  /* Output characters in a printable format.  */
189546283Sdfr  while ((ch = *string++) != '\0')
189646283Sdfr    {
189746283Sdfr      switch (ch)
189846283Sdfr        {
189946283Sdfr	default:
190046283Sdfr	  if (isprint (ch))
190146283Sdfr	    fputc_unfiltered (ch, gdb_stderr);
190246283Sdfr
190346283Sdfr	  else
190446283Sdfr	    fprintf_unfiltered (gdb_stderr, "\\x%02x", ch & 0xff);
190546283Sdfr	  break;
190646283Sdfr
190746283Sdfr	case '\\': fputs_unfiltered ("\\\\",  gdb_stderr);	break;
190846283Sdfr	case '\b': fputs_unfiltered ("\\b",   gdb_stderr);	break;
190946283Sdfr	case '\f': fputs_unfiltered ("\\f",   gdb_stderr);	break;
191046283Sdfr	case '\n': new_line = 1;
191146283Sdfr		   fputs_unfiltered ("\\n",   gdb_stderr);	break;
191246283Sdfr	case '\r': fputs_unfiltered ("\\r",   gdb_stderr);	break;
191346283Sdfr	case '\t': fputs_unfiltered ("\\t",   gdb_stderr);	break;
191446283Sdfr	case '\v': fputs_unfiltered ("\\v",   gdb_stderr);	break;
191546283Sdfr        }
191646283Sdfr
191746283Sdfr      return_p = ch == '\r';
191846283Sdfr    }
191946283Sdfr
192046283Sdfr  /* Print suffix if we printed a newline.  */
192146283Sdfr  if (new_line)
192246283Sdfr    {
192346283Sdfr      fputs_unfiltered (suffix, gdb_stderr);
192446283Sdfr      fputs_unfiltered ("\n", gdb_stderr);
192546283Sdfr    }
192646283Sdfr}
192746283Sdfr
192846283Sdfr
192919370Spst/* Print a variable number of ARGS using format FORMAT.  If this
193019370Spst   information is going to put the amount written (since the last call
193119370Spst   to REINITIALIZE_MORE_FILTER or the last page break) over the page size,
193219370Spst   call prompt_for_continue to get the users permision to continue.
193319370Spst
193419370Spst   Unlike fprintf, this function does not return a value.
193519370Spst
193619370Spst   We implement three variants, vfprintf (takes a vararg list and stream),
193719370Spst   fprintf (takes a stream to write on), and printf (the usual).
193819370Spst
193919370Spst   Note also that a longjmp to top level may occur in this routine
194019370Spst   (since prompt_for_continue may do so) so this routine should not be
194119370Spst   called when cleanups are not in place.  */
194219370Spst
194319370Spststatic void
194419370Spstvfprintf_maybe_filtered (stream, format, args, filter)
194546283Sdfr     GDB_FILE *stream;
194646283Sdfr     const char *format;
194719370Spst     va_list args;
194819370Spst     int filter;
194919370Spst{
195019370Spst  char *linebuffer;
195119370Spst  struct cleanup *old_cleanups;
195219370Spst
195319370Spst  vasprintf (&linebuffer, format, args);
195419370Spst  if (linebuffer == NULL)
195519370Spst    {
195619370Spst      fputs_unfiltered ("\ngdb: virtual memory exhausted.\n", gdb_stderr);
195719370Spst      exit (1);
195819370Spst    }
195919370Spst  old_cleanups = make_cleanup (free, linebuffer);
196019370Spst  fputs_maybe_filtered (linebuffer, stream, filter);
196119370Spst  do_cleanups (old_cleanups);
196219370Spst}
196319370Spst
196419370Spst
196519370Spstvoid
196619370Spstvfprintf_filtered (stream, format, args)
196746283Sdfr     GDB_FILE *stream;
196819370Spst     const char *format;
196919370Spst     va_list args;
197019370Spst{
197119370Spst  vfprintf_maybe_filtered (stream, format, args, 1);
197219370Spst}
197319370Spst
197419370Spstvoid
197519370Spstvfprintf_unfiltered (stream, format, args)
197646283Sdfr     GDB_FILE *stream;
197719370Spst     const char *format;
197819370Spst     va_list args;
197919370Spst{
198019370Spst  char *linebuffer;
198119370Spst  struct cleanup *old_cleanups;
198219370Spst
198319370Spst  vasprintf (&linebuffer, format, args);
198419370Spst  if (linebuffer == NULL)
198519370Spst    {
198619370Spst      fputs_unfiltered ("\ngdb: virtual memory exhausted.\n", gdb_stderr);
198719370Spst      exit (1);
198819370Spst    }
198919370Spst  old_cleanups = make_cleanup (free, linebuffer);
199019370Spst  fputs_unfiltered (linebuffer, stream);
199119370Spst  do_cleanups (old_cleanups);
199219370Spst}
199319370Spst
199419370Spstvoid
199519370Spstvprintf_filtered (format, args)
199619370Spst     const char *format;
199719370Spst     va_list args;
199819370Spst{
199919370Spst  vfprintf_maybe_filtered (gdb_stdout, format, args, 1);
200019370Spst}
200119370Spst
200219370Spstvoid
200319370Spstvprintf_unfiltered (format, args)
200419370Spst     const char *format;
200519370Spst     va_list args;
200619370Spst{
200719370Spst  vfprintf_unfiltered (gdb_stdout, format, args);
200819370Spst}
200919370Spst
201019370Spst/* VARARGS */
201119370Spstvoid
201219370Spst#ifdef ANSI_PROTOTYPES
201346283Sdfrfprintf_filtered (GDB_FILE *stream, const char *format, ...)
201419370Spst#else
201519370Spstfprintf_filtered (va_alist)
201619370Spst     va_dcl
201719370Spst#endif
201819370Spst{
201919370Spst  va_list args;
202019370Spst#ifdef ANSI_PROTOTYPES
202119370Spst  va_start (args, format);
202219370Spst#else
202346283Sdfr  GDB_FILE *stream;
202419370Spst  char *format;
202519370Spst
202619370Spst  va_start (args);
202746283Sdfr  stream = va_arg (args, GDB_FILE *);
202819370Spst  format = va_arg (args, char *);
202919370Spst#endif
203019370Spst  vfprintf_filtered (stream, format, args);
203119370Spst  va_end (args);
203219370Spst}
203319370Spst
203419370Spst/* VARARGS */
203519370Spstvoid
203619370Spst#ifdef ANSI_PROTOTYPES
203746283Sdfrfprintf_unfiltered (GDB_FILE *stream, const char *format, ...)
203819370Spst#else
203919370Spstfprintf_unfiltered (va_alist)
204019370Spst     va_dcl
204119370Spst#endif
204219370Spst{
204319370Spst  va_list args;
204419370Spst#ifdef ANSI_PROTOTYPES
204519370Spst  va_start (args, format);
204619370Spst#else
204746283Sdfr  GDB_FILE *stream;
204819370Spst  char *format;
204919370Spst
205019370Spst  va_start (args);
205146283Sdfr  stream = va_arg (args, GDB_FILE *);
205219370Spst  format = va_arg (args, char *);
205319370Spst#endif
205419370Spst  vfprintf_unfiltered (stream, format, args);
205519370Spst  va_end (args);
205619370Spst}
205719370Spst
205819370Spst/* Like fprintf_filtered, but prints its result indented.
205919370Spst   Called as fprintfi_filtered (spaces, stream, format, ...);  */
206019370Spst
206119370Spst/* VARARGS */
206219370Spstvoid
206319370Spst#ifdef ANSI_PROTOTYPES
206446283Sdfrfprintfi_filtered (int spaces, GDB_FILE *stream, const char *format, ...)
206519370Spst#else
206619370Spstfprintfi_filtered (va_alist)
206719370Spst     va_dcl
206819370Spst#endif
206919370Spst{
207019370Spst  va_list args;
207119370Spst#ifdef ANSI_PROTOTYPES
207219370Spst  va_start (args, format);
207319370Spst#else
207419370Spst  int spaces;
207546283Sdfr  GDB_FILE *stream;
207619370Spst  char *format;
207719370Spst
207819370Spst  va_start (args);
207919370Spst  spaces = va_arg (args, int);
208046283Sdfr  stream = va_arg (args, GDB_FILE *);
208119370Spst  format = va_arg (args, char *);
208219370Spst#endif
208319370Spst  print_spaces_filtered (spaces, stream);
208419370Spst
208519370Spst  vfprintf_filtered (stream, format, args);
208619370Spst  va_end (args);
208719370Spst}
208819370Spst
208919370Spst
209019370Spst/* VARARGS */
209119370Spstvoid
209219370Spst#ifdef ANSI_PROTOTYPES
209319370Spstprintf_filtered (const char *format, ...)
209419370Spst#else
209519370Spstprintf_filtered (va_alist)
209619370Spst     va_dcl
209719370Spst#endif
209819370Spst{
209919370Spst  va_list args;
210019370Spst#ifdef ANSI_PROTOTYPES
210119370Spst  va_start (args, format);
210219370Spst#else
210319370Spst  char *format;
210419370Spst
210519370Spst  va_start (args);
210619370Spst  format = va_arg (args, char *);
210719370Spst#endif
210819370Spst  vfprintf_filtered (gdb_stdout, format, args);
210919370Spst  va_end (args);
211019370Spst}
211119370Spst
211219370Spst
211319370Spst/* VARARGS */
211419370Spstvoid
211519370Spst#ifdef ANSI_PROTOTYPES
211619370Spstprintf_unfiltered (const char *format, ...)
211719370Spst#else
211819370Spstprintf_unfiltered (va_alist)
211919370Spst     va_dcl
212019370Spst#endif
212119370Spst{
212219370Spst  va_list args;
212319370Spst#ifdef ANSI_PROTOTYPES
212419370Spst  va_start (args, format);
212519370Spst#else
212619370Spst  char *format;
212719370Spst
212819370Spst  va_start (args);
212919370Spst  format = va_arg (args, char *);
213019370Spst#endif
213119370Spst  vfprintf_unfiltered (gdb_stdout, format, args);
213219370Spst  va_end (args);
213319370Spst}
213419370Spst
213519370Spst/* Like printf_filtered, but prints it's result indented.
213619370Spst   Called as printfi_filtered (spaces, format, ...);  */
213719370Spst
213819370Spst/* VARARGS */
213919370Spstvoid
214019370Spst#ifdef ANSI_PROTOTYPES
214119370Spstprintfi_filtered (int spaces, const char *format, ...)
214219370Spst#else
214319370Spstprintfi_filtered (va_alist)
214419370Spst     va_dcl
214519370Spst#endif
214619370Spst{
214719370Spst  va_list args;
214819370Spst#ifdef ANSI_PROTOTYPES
214919370Spst  va_start (args, format);
215019370Spst#else
215119370Spst  int spaces;
215219370Spst  char *format;
215319370Spst
215419370Spst  va_start (args);
215519370Spst  spaces = va_arg (args, int);
215619370Spst  format = va_arg (args, char *);
215719370Spst#endif
215819370Spst  print_spaces_filtered (spaces, gdb_stdout);
215919370Spst  vfprintf_filtered (gdb_stdout, format, args);
216019370Spst  va_end (args);
216119370Spst}
216219370Spst
216319370Spst/* Easy -- but watch out!
216419370Spst
216519370Spst   This routine is *not* a replacement for puts()!  puts() appends a newline.
216619370Spst   This one doesn't, and had better not!  */
216719370Spst
216819370Spstvoid
216919370Spstputs_filtered (string)
217019370Spst     const char *string;
217119370Spst{
217219370Spst  fputs_filtered (string, gdb_stdout);
217319370Spst}
217419370Spst
217519370Spstvoid
217619370Spstputs_unfiltered (string)
217719370Spst     const char *string;
217819370Spst{
217919370Spst  fputs_unfiltered (string, gdb_stdout);
218019370Spst}
218119370Spst
218219370Spst/* Return a pointer to N spaces and a null.  The pointer is good
218319370Spst   until the next call to here.  */
218419370Spstchar *
218519370Spstn_spaces (n)
218619370Spst     int n;
218719370Spst{
218819370Spst  register char *t;
218919370Spst  static char *spaces;
219019370Spst  static int max_spaces;
219119370Spst
219219370Spst  if (n > max_spaces)
219319370Spst    {
219419370Spst      if (spaces)
219519370Spst	free (spaces);
219619370Spst      spaces = (char *) xmalloc (n+1);
219719370Spst      for (t = spaces+n; t != spaces;)
219819370Spst	*--t = ' ';
219919370Spst      spaces[n] = '\0';
220019370Spst      max_spaces = n;
220119370Spst    }
220219370Spst
220319370Spst  return spaces + max_spaces - n;
220419370Spst}
220519370Spst
220619370Spst/* Print N spaces.  */
220719370Spstvoid
220819370Spstprint_spaces_filtered (n, stream)
220919370Spst     int n;
221046283Sdfr     GDB_FILE *stream;
221119370Spst{
221219370Spst  fputs_filtered (n_spaces (n), stream);
221319370Spst}
221419370Spst
221519370Spst/* C++ demangler stuff.  */
221619370Spst
221719370Spst/* fprintf_symbol_filtered attempts to demangle NAME, a symbol in language
221819370Spst   LANG, using demangling args ARG_MODE, and print it filtered to STREAM.
221919370Spst   If the name is not mangled, or the language for the name is unknown, or
222019370Spst   demangling is off, the name is printed in its "raw" form. */
222119370Spst
222219370Spstvoid
222319370Spstfprintf_symbol_filtered (stream, name, lang, arg_mode)
222446283Sdfr     GDB_FILE *stream;
222519370Spst     char *name;
222619370Spst     enum language lang;
222719370Spst     int arg_mode;
222819370Spst{
222919370Spst  char *demangled;
223019370Spst
223119370Spst  if (name != NULL)
223219370Spst    {
223319370Spst      /* If user wants to see raw output, no problem.  */
223419370Spst      if (!demangle)
223519370Spst	{
223619370Spst	  fputs_filtered (name, stream);
223719370Spst	}
223819370Spst      else
223919370Spst	{
224019370Spst	  switch (lang)
224119370Spst	    {
224219370Spst	    case language_cplus:
224319370Spst	      demangled = cplus_demangle (name, arg_mode);
224419370Spst	      break;
224546283Sdfr	    case language_java:
224646283Sdfr	      demangled = cplus_demangle (name, arg_mode | DMGL_JAVA);
224746283Sdfr	      break;
224819370Spst	    case language_chill:
224919370Spst	      demangled = chill_demangle (name);
225019370Spst	      break;
225119370Spst	    default:
225219370Spst	      demangled = NULL;
225319370Spst	      break;
225419370Spst	    }
225519370Spst	  fputs_filtered (demangled ? demangled : name, stream);
225619370Spst	  if (demangled != NULL)
225719370Spst	    {
225819370Spst	      free (demangled);
225919370Spst	    }
226019370Spst	}
226119370Spst    }
226219370Spst}
226319370Spst
226419370Spst/* Do a strcmp() type operation on STRING1 and STRING2, ignoring any
226519370Spst   differences in whitespace.  Returns 0 if they match, non-zero if they
226619370Spst   don't (slightly different than strcmp()'s range of return values).
226719370Spst
226819370Spst   As an extra hack, string1=="FOO(ARGS)" matches string2=="FOO".
226919370Spst   This "feature" is useful when searching for matching C++ function names
227019370Spst   (such as if the user types 'break FOO', where FOO is a mangled C++
227119370Spst   function). */
227219370Spst
227319370Spstint
227419370Spststrcmp_iw (string1, string2)
227519370Spst     const char *string1;
227619370Spst     const char *string2;
227719370Spst{
227819370Spst  while ((*string1 != '\0') && (*string2 != '\0'))
227919370Spst    {
228019370Spst      while (isspace (*string1))
228119370Spst	{
228219370Spst	  string1++;
228319370Spst	}
228419370Spst      while (isspace (*string2))
228519370Spst	{
228619370Spst	  string2++;
228719370Spst	}
228819370Spst      if (*string1 != *string2)
228919370Spst	{
229019370Spst	  break;
229119370Spst	}
229219370Spst      if (*string1 != '\0')
229319370Spst	{
229419370Spst	  string1++;
229519370Spst	  string2++;
229619370Spst	}
229719370Spst    }
229819370Spst  return (*string1 != '\0' && *string1 != '(') || (*string2 != '\0');
229919370Spst}
230019370Spst
230119370Spst
230246283Sdfr/*
230346283Sdfr** subsetCompare()
230446283Sdfr**    Answer whether stringToCompare is a full or partial match to
230546283Sdfr**    templateString.  The partial match must be in sequence starting
230646283Sdfr**    at index 0.
230746283Sdfr*/
230846283Sdfrint
230946283Sdfr#ifdef _STDC__
231046283SdfrsubsetCompare(
231146283Sdfr    char *stringToCompare,
231246283Sdfr    char *templateString)
231346283Sdfr#else
231446283SdfrsubsetCompare(stringToCompare, templateString)
231546283Sdfr    char *stringToCompare;
231646283Sdfr    char *templateString;
231746283Sdfr#endif
231846283Sdfr{
231946283Sdfr    int    match = 0;
232046283Sdfr
232146283Sdfr    if (templateString != (char *)NULL && stringToCompare != (char *)NULL &&
232246283Sdfr	strlen(stringToCompare) <= strlen(templateString))
232346283Sdfr      match = (strncmp(templateString,
232446283Sdfr		       stringToCompare,
232546283Sdfr		       strlen(stringToCompare)) == 0);
232646283Sdfr
232746283Sdfr    return match;
232846283Sdfr} /* subsetCompare */
232946283Sdfr
233046283Sdfr
233146283Sdfrvoid pagination_on_command(arg, from_tty)
233246283Sdfr  char *arg;
233346283Sdfr  int from_tty;
233446283Sdfr{
233546283Sdfr  pagination_enabled = 1;
233646283Sdfr}
233746283Sdfr
233846283Sdfrvoid pagination_off_command(arg, from_tty)
233946283Sdfr  char *arg;
234046283Sdfr  int from_tty;
234146283Sdfr{
234246283Sdfr  pagination_enabled = 0;
234346283Sdfr}
234446283Sdfr
234546283Sdfr
234619370Spstvoid
234719370Spstinitialize_utils ()
234819370Spst{
234919370Spst  struct cmd_list_element *c;
235019370Spst
235119370Spst  c = add_set_cmd ("width", class_support, var_uinteger,
235219370Spst		  (char *)&chars_per_line,
235319370Spst		  "Set number of characters gdb thinks are in a line.",
235419370Spst		  &setlist);
235519370Spst  add_show_from_set (c, &showlist);
235619370Spst  c->function.sfunc = set_width_command;
235719370Spst
235819370Spst  add_show_from_set
235919370Spst    (add_set_cmd ("height", class_support,
236019370Spst		  var_uinteger, (char *)&lines_per_page,
236119370Spst		  "Set number of lines gdb thinks are in a page.", &setlist),
236219370Spst     &showlist);
236319370Spst
236446283Sdfr  init_page_info ();
236519370Spst
236619370Spst  /* If the output is not a terminal, don't paginate it.  */
236746283Sdfr  if (!GDB_FILE_ISATTY (gdb_stdout))
236819370Spst    lines_per_page = UINT_MAX;
236919370Spst
237019370Spst  set_width_command ((char *)NULL, 0, c);
237119370Spst
237219370Spst  add_show_from_set
237319370Spst    (add_set_cmd ("demangle", class_support, var_boolean,
237419370Spst		  (char *)&demangle,
237519370Spst		"Set demangling of encoded C++ names when displaying symbols.",
237619370Spst		  &setprintlist),
237719370Spst     &showprintlist);
237819370Spst
237919370Spst  add_show_from_set
238046283Sdfr    (add_set_cmd ("pagination", class_support,
238146283Sdfr		  var_boolean, (char *)&pagination_enabled,
238246283Sdfr		  "Set state of pagination.", &setlist),
238346283Sdfr     &showlist);
238446283Sdfr  if (xdb_commands)
238546283Sdfr    {
238646283Sdfr      add_com("am", class_support, pagination_on_command,
238746283Sdfr              "Enable pagination");
238846283Sdfr      add_com("sm", class_support, pagination_off_command,
238946283Sdfr              "Disable pagination");
239046283Sdfr    }
239146283Sdfr
239246283Sdfr  add_show_from_set
239319370Spst    (add_set_cmd ("sevenbit-strings", class_support, var_boolean,
239419370Spst		  (char *)&sevenbit_strings,
239519370Spst   "Set printing of 8-bit characters in strings as \\nnn.",
239619370Spst		  &setprintlist),
239719370Spst     &showprintlist);
239819370Spst
239919370Spst  add_show_from_set
240019370Spst    (add_set_cmd ("asm-demangle", class_support, var_boolean,
240119370Spst		  (char *)&asm_demangle,
240219370Spst	"Set demangling of C++ names in disassembly listings.",
240319370Spst		  &setprintlist),
240419370Spst     &showprintlist);
240519370Spst}
240619370Spst
240719370Spst/* Machine specific function to handle SIGWINCH signal. */
240819370Spst
240919370Spst#ifdef  SIGWINCH_HANDLER_BODY
241019370Spst        SIGWINCH_HANDLER_BODY
241119370Spst#endif
241246283Sdfr
241346283Sdfr/* Support for converting target fp numbers into host DOUBLEST format.  */
241419370Spst
241546283Sdfr/* XXX - This code should really be in libiberty/floatformat.c, however
241646283Sdfr   configuration issues with libiberty made this very difficult to do in the
241746283Sdfr   available time.  */
241846283Sdfr
241946283Sdfr#include "floatformat.h"
242046283Sdfr#include <math.h>		/* ldexp */
242146283Sdfr
242246283Sdfr/* The odds that CHAR_BIT will be anything but 8 are low enough that I'm not
242346283Sdfr   going to bother with trying to muck around with whether it is defined in
242446283Sdfr   a system header, what we do if not, etc.  */
242546283Sdfr#define FLOATFORMAT_CHAR_BIT 8
242646283Sdfr
242746283Sdfrstatic unsigned long get_field PARAMS ((unsigned char *,
242846283Sdfr					enum floatformat_byteorders,
242946283Sdfr					unsigned int,
243046283Sdfr					unsigned int,
243146283Sdfr					unsigned int));
243246283Sdfr
243346283Sdfr/* Extract a field which starts at START and is LEN bytes long.  DATA and
243446283Sdfr   TOTAL_LEN are the thing we are extracting it from, in byteorder ORDER.  */
243546283Sdfrstatic unsigned long
243646283Sdfrget_field (data, order, total_len, start, len)
243746283Sdfr     unsigned char *data;
243846283Sdfr     enum floatformat_byteorders order;
243946283Sdfr     unsigned int total_len;
244046283Sdfr     unsigned int start;
244146283Sdfr     unsigned int len;
244246283Sdfr{
244346283Sdfr  unsigned long result;
244446283Sdfr  unsigned int cur_byte;
244546283Sdfr  int cur_bitshift;
244646283Sdfr
244746283Sdfr  /* Start at the least significant part of the field.  */
244846283Sdfr  cur_byte = (start + len) / FLOATFORMAT_CHAR_BIT;
244946283Sdfr  if (order == floatformat_little || order == floatformat_littlebyte_bigword)
245046283Sdfr    cur_byte = (total_len / FLOATFORMAT_CHAR_BIT) - cur_byte - 1;
245146283Sdfr  cur_bitshift =
245246283Sdfr    ((start + len) % FLOATFORMAT_CHAR_BIT) - FLOATFORMAT_CHAR_BIT;
245346283Sdfr  result = *(data + cur_byte) >> (-cur_bitshift);
245446283Sdfr  cur_bitshift += FLOATFORMAT_CHAR_BIT;
245546283Sdfr  if (order == floatformat_little || order == floatformat_littlebyte_bigword)
245646283Sdfr    ++cur_byte;
245746283Sdfr  else
245846283Sdfr    --cur_byte;
245946283Sdfr
246046283Sdfr  /* Move towards the most significant part of the field.  */
246146283Sdfr  while (cur_bitshift < len)
246246283Sdfr    {
246346283Sdfr      if (len - cur_bitshift < FLOATFORMAT_CHAR_BIT)
246446283Sdfr	/* This is the last byte; zero out the bits which are not part of
246546283Sdfr	   this field.  */
246646283Sdfr	result |=
246746283Sdfr	  (*(data + cur_byte) & ((1 << (len - cur_bitshift)) - 1))
246846283Sdfr	    << cur_bitshift;
246946283Sdfr      else
247046283Sdfr	result |= *(data + cur_byte) << cur_bitshift;
247146283Sdfr      cur_bitshift += FLOATFORMAT_CHAR_BIT;
247246283Sdfr      if (order == floatformat_little || order == floatformat_littlebyte_bigword)
247346283Sdfr	++cur_byte;
247446283Sdfr      else
247546283Sdfr	--cur_byte;
247646283Sdfr    }
247746283Sdfr  return result;
247846283Sdfr}
247946283Sdfr
248046283Sdfr/* Convert from FMT to a DOUBLEST.
248146283Sdfr   FROM is the address of the extended float.
248246283Sdfr   Store the DOUBLEST in *TO.  */
248346283Sdfr
248446283Sdfrvoid
248546283Sdfrfloatformat_to_doublest (fmt, from, to)
248646283Sdfr     const struct floatformat *fmt;
248746283Sdfr     char *from;
248846283Sdfr     DOUBLEST *to;
248946283Sdfr{
249046283Sdfr  unsigned char *ufrom = (unsigned char *)from;
249146283Sdfr  DOUBLEST dto;
249246283Sdfr  long exponent;
249346283Sdfr  unsigned long mant;
249446283Sdfr  unsigned int mant_bits, mant_off;
249546283Sdfr  int mant_bits_left;
249646283Sdfr  int special_exponent;		/* It's a NaN, denorm or zero */
249746283Sdfr
249846283Sdfr  /* If the mantissa bits are not contiguous from one end of the
249946283Sdfr     mantissa to the other, we need to make a private copy of the
250046283Sdfr     source bytes that is in the right order since the unpacking
250146283Sdfr     algorithm assumes that the bits are contiguous.
250246283Sdfr
250346283Sdfr     Swap the bytes individually rather than accessing them through
250446283Sdfr     "long *" since we have no guarantee that they start on a long
250546283Sdfr     alignment, and also sizeof(long) for the host could be different
250646283Sdfr     than sizeof(long) for the target.  FIXME: Assumes sizeof(long)
250746283Sdfr     for the target is 4. */
250846283Sdfr
250946283Sdfr  if (fmt -> byteorder == floatformat_littlebyte_bigword)
251046283Sdfr    {
251146283Sdfr      static unsigned char *newfrom;
251246283Sdfr      unsigned char *swapin, *swapout;
251346283Sdfr      int longswaps;
251446283Sdfr
251546283Sdfr      longswaps = fmt -> totalsize / FLOATFORMAT_CHAR_BIT;
251646283Sdfr      longswaps >>= 3;
251746283Sdfr
251846283Sdfr      if (newfrom == NULL)
251946283Sdfr	{
252046283Sdfr	  newfrom = (unsigned char *) xmalloc (fmt -> totalsize);
252146283Sdfr	}
252246283Sdfr      swapout = newfrom;
252346283Sdfr      swapin = ufrom;
252446283Sdfr      ufrom = newfrom;
252546283Sdfr      while (longswaps-- > 0)
252646283Sdfr	{
252746283Sdfr	  /* This is ugly, but efficient */
252846283Sdfr	  *swapout++ = swapin[4];
252946283Sdfr	  *swapout++ = swapin[5];
253046283Sdfr	  *swapout++ = swapin[6];
253146283Sdfr	  *swapout++ = swapin[7];
253246283Sdfr	  *swapout++ = swapin[0];
253346283Sdfr	  *swapout++ = swapin[1];
253446283Sdfr	  *swapout++ = swapin[2];
253546283Sdfr	  *swapout++ = swapin[3];
253646283Sdfr	  swapin += 8;
253746283Sdfr	}
253846283Sdfr    }
253946283Sdfr
254046283Sdfr  exponent = get_field (ufrom, fmt->byteorder, fmt->totalsize,
254146283Sdfr			fmt->exp_start, fmt->exp_len);
254246283Sdfr  /* Note that if exponent indicates a NaN, we can't really do anything useful
254346283Sdfr     (not knowing if the host has NaN's, or how to build one).  So it will
254446283Sdfr     end up as an infinity or something close; that is OK.  */
254546283Sdfr
254646283Sdfr  mant_bits_left = fmt->man_len;
254746283Sdfr  mant_off = fmt->man_start;
254846283Sdfr  dto = 0.0;
254946283Sdfr
255046283Sdfr  special_exponent = exponent == 0 || exponent == fmt->exp_nan;
255146283Sdfr
255246283Sdfr/* Don't bias zero's, denorms or NaNs.  */
255346283Sdfr  if (!special_exponent)
255446283Sdfr    exponent -= fmt->exp_bias;
255546283Sdfr
255646283Sdfr  /* Build the result algebraically.  Might go infinite, underflow, etc;
255746283Sdfr     who cares. */
255846283Sdfr
255946283Sdfr/* If this format uses a hidden bit, explicitly add it in now.  Otherwise,
256046283Sdfr   increment the exponent by one to account for the integer bit.  */
256146283Sdfr
256246283Sdfr  if (!special_exponent)
256346283Sdfr    if (fmt->intbit == floatformat_intbit_no)
256446283Sdfr      dto = ldexp (1.0, exponent);
256546283Sdfr    else
256646283Sdfr      exponent++;
256746283Sdfr
256846283Sdfr  while (mant_bits_left > 0)
256946283Sdfr    {
257046283Sdfr      mant_bits = min (mant_bits_left, 32);
257146283Sdfr
257246283Sdfr      mant = get_field (ufrom, fmt->byteorder, fmt->totalsize,
257346283Sdfr			 mant_off, mant_bits);
257446283Sdfr
257546283Sdfr      dto += ldexp ((double)mant, exponent - mant_bits);
257646283Sdfr      exponent -= mant_bits;
257746283Sdfr      mant_off += mant_bits;
257846283Sdfr      mant_bits_left -= mant_bits;
257946283Sdfr    }
258046283Sdfr
258146283Sdfr  /* Negate it if negative.  */
258246283Sdfr  if (get_field (ufrom, fmt->byteorder, fmt->totalsize, fmt->sign_start, 1))
258346283Sdfr    dto = -dto;
258446283Sdfr  *to = dto;
258546283Sdfr}
258646283Sdfr
258746283Sdfrstatic void put_field PARAMS ((unsigned char *, enum floatformat_byteorders,
258846283Sdfr			       unsigned int,
258946283Sdfr			       unsigned int,
259046283Sdfr			       unsigned int,
259146283Sdfr			       unsigned long));
259246283Sdfr
259346283Sdfr/* Set a field which starts at START and is LEN bytes long.  DATA and
259446283Sdfr   TOTAL_LEN are the thing we are extracting it from, in byteorder ORDER.  */
259546283Sdfrstatic void
259646283Sdfrput_field (data, order, total_len, start, len, stuff_to_put)
259746283Sdfr     unsigned char *data;
259846283Sdfr     enum floatformat_byteorders order;
259946283Sdfr     unsigned int total_len;
260046283Sdfr     unsigned int start;
260146283Sdfr     unsigned int len;
260246283Sdfr     unsigned long stuff_to_put;
260346283Sdfr{
260446283Sdfr  unsigned int cur_byte;
260546283Sdfr  int cur_bitshift;
260646283Sdfr
260746283Sdfr  /* Start at the least significant part of the field.  */
260846283Sdfr  cur_byte = (start + len) / FLOATFORMAT_CHAR_BIT;
260946283Sdfr  if (order == floatformat_little || order == floatformat_littlebyte_bigword)
261046283Sdfr    cur_byte = (total_len / FLOATFORMAT_CHAR_BIT) - cur_byte - 1;
261146283Sdfr  cur_bitshift =
261246283Sdfr    ((start + len) % FLOATFORMAT_CHAR_BIT) - FLOATFORMAT_CHAR_BIT;
261346283Sdfr  *(data + cur_byte) &=
261446283Sdfr    ~(((1 << ((start + len) % FLOATFORMAT_CHAR_BIT)) - 1) << (-cur_bitshift));
261546283Sdfr  *(data + cur_byte) |=
261646283Sdfr    (stuff_to_put & ((1 << FLOATFORMAT_CHAR_BIT) - 1)) << (-cur_bitshift);
261746283Sdfr  cur_bitshift += FLOATFORMAT_CHAR_BIT;
261846283Sdfr  if (order == floatformat_little || order == floatformat_littlebyte_bigword)
261946283Sdfr    ++cur_byte;
262046283Sdfr  else
262146283Sdfr    --cur_byte;
262246283Sdfr
262346283Sdfr  /* Move towards the most significant part of the field.  */
262446283Sdfr  while (cur_bitshift < len)
262546283Sdfr    {
262646283Sdfr      if (len - cur_bitshift < FLOATFORMAT_CHAR_BIT)
262746283Sdfr	{
262846283Sdfr	  /* This is the last byte.  */
262946283Sdfr	  *(data + cur_byte) &=
263046283Sdfr	    ~((1 << (len - cur_bitshift)) - 1);
263146283Sdfr	  *(data + cur_byte) |= (stuff_to_put >> cur_bitshift);
263246283Sdfr	}
263346283Sdfr      else
263446283Sdfr	*(data + cur_byte) = ((stuff_to_put >> cur_bitshift)
263546283Sdfr			      & ((1 << FLOATFORMAT_CHAR_BIT) - 1));
263646283Sdfr      cur_bitshift += FLOATFORMAT_CHAR_BIT;
263746283Sdfr      if (order == floatformat_little || order == floatformat_littlebyte_bigword)
263846283Sdfr	++cur_byte;
263946283Sdfr      else
264046283Sdfr	--cur_byte;
264146283Sdfr    }
264246283Sdfr}
264346283Sdfr
264446283Sdfr#ifdef HAVE_LONG_DOUBLE
264546283Sdfr/* Return the fractional part of VALUE, and put the exponent of VALUE in *EPTR.
264646283Sdfr   The range of the returned value is >= 0.5 and < 1.0.  This is equivalent to
264746283Sdfr   frexp, but operates on the long double data type.  */
264846283Sdfr
264946283Sdfrstatic long double ldfrexp PARAMS ((long double value, int *eptr));
265046283Sdfr
265146283Sdfrstatic long double
265246283Sdfrldfrexp (value, eptr)
265346283Sdfr     long double value;
265446283Sdfr     int *eptr;
265546283Sdfr{
265646283Sdfr  long double tmp;
265746283Sdfr  int exp;
265846283Sdfr
265946283Sdfr  /* Unfortunately, there are no portable functions for extracting the exponent
266046283Sdfr     of a long double, so we have to do it iteratively by multiplying or dividing
266146283Sdfr     by two until the fraction is between 0.5 and 1.0.  */
266246283Sdfr
266346283Sdfr  if (value < 0.0l)
266446283Sdfr    value = -value;
266546283Sdfr
266646283Sdfr  tmp = 1.0l;
266746283Sdfr  exp = 0;
266846283Sdfr
266946283Sdfr  if (value >= tmp)		/* Value >= 1.0 */
267046283Sdfr    while (value >= tmp)
267146283Sdfr      {
267246283Sdfr	tmp *= 2.0l;
267346283Sdfr	exp++;
267446283Sdfr      }
267546283Sdfr  else if (value != 0.0l)	/* Value < 1.0  and > 0.0 */
267646283Sdfr    {
267746283Sdfr      while (value < tmp)
267846283Sdfr	{
267946283Sdfr	  tmp /= 2.0l;
268046283Sdfr	  exp--;
268146283Sdfr	}
268246283Sdfr      tmp *= 2.0l;
268346283Sdfr      exp++;
268446283Sdfr    }
268546283Sdfr
268646283Sdfr  *eptr = exp;
268746283Sdfr  return value/tmp;
268846283Sdfr}
268946283Sdfr#endif /* HAVE_LONG_DOUBLE */
269046283Sdfr
269146283Sdfr
269246283Sdfr/* The converse: convert the DOUBLEST *FROM to an extended float
269346283Sdfr   and store where TO points.  Neither FROM nor TO have any alignment
269446283Sdfr   restrictions.  */
269546283Sdfr
269646283Sdfrvoid
269746283Sdfrfloatformat_from_doublest (fmt, from, to)
269846283Sdfr     CONST struct floatformat *fmt;
269946283Sdfr     DOUBLEST *from;
270046283Sdfr     char *to;
270146283Sdfr{
270246283Sdfr  DOUBLEST dfrom;
270346283Sdfr  int exponent;
270446283Sdfr  DOUBLEST mant;
270546283Sdfr  unsigned int mant_bits, mant_off;
270646283Sdfr  int mant_bits_left;
270746283Sdfr  unsigned char *uto = (unsigned char *)to;
270846283Sdfr
270946283Sdfr  memcpy (&dfrom, from, sizeof (dfrom));
271046283Sdfr  memset (uto, 0, fmt->totalsize / FLOATFORMAT_CHAR_BIT);
271146283Sdfr  if (dfrom == 0)
271246283Sdfr    return;			/* Result is zero */
271346283Sdfr  if (dfrom != dfrom)		/* Result is NaN */
271446283Sdfr    {
271546283Sdfr      /* From is NaN */
271646283Sdfr      put_field (uto, fmt->byteorder, fmt->totalsize, fmt->exp_start,
271746283Sdfr		 fmt->exp_len, fmt->exp_nan);
271846283Sdfr      /* Be sure it's not infinity, but NaN value is irrel */
271946283Sdfr      put_field (uto, fmt->byteorder, fmt->totalsize, fmt->man_start,
272046283Sdfr		 32, 1);
272146283Sdfr      return;
272246283Sdfr    }
272346283Sdfr
272446283Sdfr  /* If negative, set the sign bit.  */
272546283Sdfr  if (dfrom < 0)
272646283Sdfr    {
272746283Sdfr      put_field (uto, fmt->byteorder, fmt->totalsize, fmt->sign_start, 1, 1);
272846283Sdfr      dfrom = -dfrom;
272946283Sdfr    }
273046283Sdfr
273146283Sdfr  if (dfrom + dfrom == dfrom && dfrom != 0.0)	/* Result is Infinity */
273246283Sdfr    {
273346283Sdfr      /* Infinity exponent is same as NaN's.  */
273446283Sdfr      put_field (uto, fmt->byteorder, fmt->totalsize, fmt->exp_start,
273546283Sdfr		 fmt->exp_len, fmt->exp_nan);
273646283Sdfr      /* Infinity mantissa is all zeroes.  */
273746283Sdfr      put_field (uto, fmt->byteorder, fmt->totalsize, fmt->man_start,
273846283Sdfr		 fmt->man_len, 0);
273946283Sdfr      return;
274046283Sdfr    }
274146283Sdfr
274246283Sdfr#ifdef HAVE_LONG_DOUBLE
274346283Sdfr  mant = ldfrexp (dfrom, &exponent);
274446283Sdfr#else
274546283Sdfr  mant = frexp (dfrom, &exponent);
274646283Sdfr#endif
274746283Sdfr
274846283Sdfr  put_field (uto, fmt->byteorder, fmt->totalsize, fmt->exp_start, fmt->exp_len,
274946283Sdfr	     exponent + fmt->exp_bias - 1);
275046283Sdfr
275146283Sdfr  mant_bits_left = fmt->man_len;
275246283Sdfr  mant_off = fmt->man_start;
275346283Sdfr  while (mant_bits_left > 0)
275446283Sdfr    {
275546283Sdfr      unsigned long mant_long;
275646283Sdfr      mant_bits = mant_bits_left < 32 ? mant_bits_left : 32;
275746283Sdfr
275846283Sdfr      mant *= 4294967296.0;
275946283Sdfr      mant_long = (unsigned long)mant;
276046283Sdfr      mant -= mant_long;
276146283Sdfr
276246283Sdfr      /* If the integer bit is implicit, then we need to discard it.
276346283Sdfr	 If we are discarding a zero, we should be (but are not) creating
276446283Sdfr	 a denormalized	number which means adjusting the exponent
276546283Sdfr	 (I think).  */
276646283Sdfr      if (mant_bits_left == fmt->man_len
276746283Sdfr	  && fmt->intbit == floatformat_intbit_no)
276846283Sdfr	{
276946283Sdfr	  mant_long <<= 1;
277046283Sdfr	  mant_bits -= 1;
277146283Sdfr	}
277246283Sdfr
277346283Sdfr      if (mant_bits < 32)
277446283Sdfr	{
277546283Sdfr	  /* The bits we want are in the most significant MANT_BITS bits of
277646283Sdfr	     mant_long.  Move them to the least significant.  */
277746283Sdfr	  mant_long >>= 32 - mant_bits;
277846283Sdfr	}
277946283Sdfr
278046283Sdfr      put_field (uto, fmt->byteorder, fmt->totalsize,
278146283Sdfr		 mant_off, mant_bits, mant_long);
278246283Sdfr      mant_off += mant_bits;
278346283Sdfr      mant_bits_left -= mant_bits;
278446283Sdfr    }
278546283Sdfr  if (fmt -> byteorder == floatformat_littlebyte_bigword)
278646283Sdfr    {
278746283Sdfr      int count;
278846283Sdfr      unsigned char *swaplow = uto;
278946283Sdfr      unsigned char *swaphigh = uto + 4;
279046283Sdfr      unsigned char tmp;
279146283Sdfr
279246283Sdfr      for (count = 0; count < 4; count++)
279346283Sdfr	{
279446283Sdfr	  tmp = *swaplow;
279546283Sdfr	  *swaplow++ = *swaphigh;
279646283Sdfr	  *swaphigh++ = tmp;
279746283Sdfr	}
279846283Sdfr    }
279946283Sdfr}
280046283Sdfr
280146283Sdfr/* temporary storage using circular buffer */
280246283Sdfr#define NUMCELLS 16
280346283Sdfr#define CELLSIZE 32
280446283Sdfrstatic char*
280546283Sdfrget_cell()
280646283Sdfr{
280746283Sdfr  static char buf[NUMCELLS][CELLSIZE];
280846283Sdfr  static int cell=0;
280946283Sdfr  if (++cell>=NUMCELLS) cell=0;
281046283Sdfr  return buf[cell];
281146283Sdfr}
281246283Sdfr
281346283Sdfr/* print routines to handle variable size regs, etc.
281446283Sdfr
281546283Sdfr   FIXME: Note that t_addr is a bfd_vma, which is currently either an
281646283Sdfr   unsigned long or unsigned long long, determined at configure time.
281746283Sdfr   If t_addr is an unsigned long long and sizeof (unsigned long long)
281846283Sdfr   is greater than sizeof (unsigned long), then I believe this code will
281946283Sdfr   probably lose, at least for little endian machines.  I believe that
282046283Sdfr   it would also be better to eliminate the switch on the absolute size
282146283Sdfr   of t_addr and replace it with a sequence of if statements that compare
282246283Sdfr   sizeof t_addr with sizeof the various types and do the right thing,
282346283Sdfr   which includes knowing whether or not the host supports long long.
282446283Sdfr   -fnf
282546283Sdfr
282646283Sdfr */
282746283Sdfr
282846283Sdfrstatic int thirty_two = 32;	/* eliminate warning from compiler on 32-bit systems */
282946283Sdfr
283046283Sdfrchar*
283146283Sdfrpaddr(addr)
283246283Sdfr  t_addr addr;
283346283Sdfr{
283446283Sdfr  char *paddr_str=get_cell();
283546283Sdfr  switch (sizeof(t_addr))
283646283Sdfr    {
283746283Sdfr      case 8:
283846283Sdfr        sprintf (paddr_str, "%08lx%08lx",
283946283Sdfr		(unsigned long) (addr >> thirty_two), (unsigned long) (addr & 0xffffffff));
284046283Sdfr	break;
284146283Sdfr      case 4:
284246283Sdfr        sprintf (paddr_str, "%08lx", (unsigned long) addr);
284346283Sdfr	break;
284446283Sdfr      case 2:
284546283Sdfr        sprintf (paddr_str, "%04x", (unsigned short) (addr & 0xffff));
284646283Sdfr	break;
284746283Sdfr      default:
284846283Sdfr        sprintf (paddr_str, "%lx", (unsigned long) addr);
284946283Sdfr    }
285046283Sdfr  return paddr_str;
285146283Sdfr}
285246283Sdfr
285346283Sdfrchar*
285446283Sdfrpreg(reg)
285546283Sdfr  t_reg reg;
285646283Sdfr{
285746283Sdfr  char *preg_str=get_cell();
285846283Sdfr  switch (sizeof(t_reg))
285946283Sdfr    {
286046283Sdfr      case 8:
286146283Sdfr        sprintf (preg_str, "%08lx%08lx",
286246283Sdfr		(unsigned long) (reg >> thirty_two), (unsigned long) (reg & 0xffffffff));
286346283Sdfr	break;
286446283Sdfr      case 4:
286546283Sdfr        sprintf (preg_str, "%08lx", (unsigned long) reg);
286646283Sdfr	break;
286746283Sdfr      case 2:
286846283Sdfr        sprintf (preg_str, "%04x", (unsigned short) (reg & 0xffff));
286946283Sdfr	break;
287046283Sdfr      default:
287146283Sdfr        sprintf (preg_str, "%lx", (unsigned long) reg);
287246283Sdfr    }
287346283Sdfr  return preg_str;
287446283Sdfr}
287546283Sdfr
287646283Sdfrchar*
287746283Sdfrpaddr_nz(addr)
287846283Sdfr  t_addr addr;
287946283Sdfr{
288046283Sdfr  char *paddr_str=get_cell();
288146283Sdfr  switch (sizeof(t_addr))
288246283Sdfr    {
288346283Sdfr      case 8:
288446283Sdfr	{
288546283Sdfr	  unsigned long high = (unsigned long) (addr >> thirty_two);
288646283Sdfr	  if (high == 0)
288746283Sdfr	    sprintf (paddr_str, "%lx", (unsigned long) (addr & 0xffffffff));
288846283Sdfr	  else
288946283Sdfr	    sprintf (paddr_str, "%lx%08lx",
289046283Sdfr		    high, (unsigned long) (addr & 0xffffffff));
289146283Sdfr	  break;
289246283Sdfr	}
289346283Sdfr      case 4:
289446283Sdfr        sprintf (paddr_str, "%lx", (unsigned long) addr);
289546283Sdfr	break;
289646283Sdfr      case 2:
289746283Sdfr        sprintf (paddr_str, "%x", (unsigned short) (addr & 0xffff));
289846283Sdfr	break;
289946283Sdfr      default:
290046283Sdfr        sprintf (paddr_str,"%lx", (unsigned long) addr);
290146283Sdfr    }
290246283Sdfr  return paddr_str;
290346283Sdfr}
290446283Sdfr
290546283Sdfrchar*
290646283Sdfrpreg_nz(reg)
290746283Sdfr  t_reg reg;
290846283Sdfr{
290946283Sdfr  char *preg_str=get_cell();
291046283Sdfr  switch (sizeof(t_reg))
291146283Sdfr    {
291246283Sdfr      case 8:
291346283Sdfr	{
291446283Sdfr	  unsigned long high = (unsigned long) (reg >> thirty_two);
291546283Sdfr	  if (high == 0)
291646283Sdfr	    sprintf (preg_str, "%lx", (unsigned long) (reg & 0xffffffff));
291746283Sdfr	  else
291846283Sdfr	    sprintf (preg_str, "%lx%08lx",
291946283Sdfr		    high, (unsigned long) (reg & 0xffffffff));
292046283Sdfr	  break;
292146283Sdfr	}
292246283Sdfr      case 4:
292346283Sdfr        sprintf (preg_str, "%lx", (unsigned long) reg);
292446283Sdfr	break;
292546283Sdfr      case 2:
292646283Sdfr        sprintf (preg_str, "%x", (unsigned short) (reg & 0xffff));
292746283Sdfr	break;
292846283Sdfr      default:
292946283Sdfr        sprintf (preg_str, "%lx", (unsigned long) reg);
293046283Sdfr    }
293146283Sdfr  return preg_str;
293246283Sdfr}
2933