home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / bsd_srcs / usr.bin / gdb / utils.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-05-08  |  23.2 KB  |  1,097 lines

  1. /*-
  2.  * This code is derived from software copyrighted by the Free Software
  3.  * Foundation.
  4.  *
  5.  * Modified 1991 by Donn Seeley at UUNET Technologies, Inc.
  6.  * Modified 1990 by Van Jacobson at Lawrence Berkeley Laboratory.
  7.  *
  8.  * $Header: utils.c,v 1.6 91/03/07 17:44:30 mccanne Exp $;
  9.  */
  10.  
  11. #ifndef lint
  12. static char sccsid[] = "@(#)utils.c    6.4 (Berkeley) 5/8/91";
  13. #endif /* not lint */
  14.  
  15. /* General utility routines for GDB, the GNU debugger.
  16.    Copyright (C) 1986, 1989 Free Software Foundation, Inc.
  17.  
  18. This file is part of GDB.
  19.  
  20. GDB is free software; you can redistribute it and/or modify
  21. it under the terms of the GNU General Public License as published by
  22. the Free Software Foundation; either version 1, or (at your option)
  23. any later version.
  24.  
  25. GDB is distributed in the hope that it will be useful,
  26. but WITHOUT ANY WARRANTY; without even the implied warranty of
  27. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  28. GNU General Public License for more details.
  29.  
  30. You should have received a copy of the GNU General Public License
  31. along with GDB; see the file COPYING.  If not, write to
  32. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  33.  
  34. #include "param.h"
  35.  
  36. #include <stdio.h>
  37. #include <ctype.h>
  38. #include <signal.h>
  39. #include <sys/ioctl.h>
  40. #include <sys/param.h>
  41. #include <pwd.h>
  42. #include "defs.h"
  43. #ifdef HAVE_TERMIO
  44. #include <termio.h>
  45. #endif
  46.  
  47. /* If this definition isn't overridden by the header files, assume
  48.    that isatty and fileno exist on this system.  */
  49. #ifndef ISATTY
  50. #define ISATTY(FP)    (isatty (fileno (FP)))
  51. #endif
  52.  
  53. extern FILE *instream;
  54.  
  55. void error ();
  56. void fatal ();
  57.  
  58. /* Chain of cleanup actions established with make_cleanup,
  59.    to be executed if an error happens.  */
  60.  
  61. static struct cleanup *cleanup_chain;
  62.  
  63. /* Nonzero means a quit has been requested.  */
  64.  
  65. int quit_flag;
  66.  
  67. /* Nonzero means quit immediately if Control-C is typed now,
  68.    rather than waiting until QUIT is executed.  */
  69.  
  70. int immediate_quit;
  71.  
  72. /* Add a new cleanup to the cleanup_chain,
  73.    and return the previous chain pointer
  74.    to be passed later to do_cleanups or discard_cleanups.
  75.    Args are FUNCTION to clean up with, and ARG to pass to it.  */
  76.  
  77. struct cleanup *
  78. make_cleanup (function, arg)
  79.      void (*function) ();
  80.      int arg;
  81. {
  82.   register struct cleanup *new
  83.     = (struct cleanup *) xmalloc (sizeof (struct cleanup));
  84.   register struct cleanup *old_chain = cleanup_chain;
  85.  
  86.   new->next = cleanup_chain;
  87.   new->function = function;
  88.   new->arg = arg;
  89.   cleanup_chain = new;
  90.  
  91.   return old_chain;
  92. }
  93.  
  94. /* Discard cleanups and do the actions they describe
  95.    until we get back to the point OLD_CHAIN in the cleanup_chain.  */
  96.  
  97. void
  98. do_cleanups (old_chain)
  99.      register struct cleanup *old_chain;
  100. {
  101.   register struct cleanup *ptr;
  102.   while ((ptr = cleanup_chain) != old_chain)
  103.     {
  104.       (*ptr->function) (ptr->arg);
  105.       cleanup_chain = ptr->next;
  106.       free (ptr);
  107.     }
  108. }
  109.  
  110. /* Discard cleanups, not doing the actions they describe,
  111.    until we get back to the point OLD_CHAIN in the cleanup_chain.  */
  112.  
  113. void
  114. discard_cleanups (old_chain)
  115.      register struct cleanup *old_chain;
  116. {
  117.   register struct cleanup *ptr;
  118.   while ((ptr = cleanup_chain) != old_chain)
  119.     {
  120.       cleanup_chain = ptr->next;
  121.       free (ptr);
  122.     }
  123. }
  124.  
  125. /* Set the cleanup_chain to 0, and return the old cleanup chain.  */
  126. struct cleanup *
  127. save_cleanups ()
  128. {
  129.   struct cleanup *old_chain = cleanup_chain;
  130.  
  131.   cleanup_chain = 0;
  132.   return old_chain;
  133. }
  134.  
  135. /* Restore the cleanup chain from a previously saved chain.  */
  136. void
  137. restore_cleanups (chain)
  138.      struct cleanup *chain;
  139. {
  140.   cleanup_chain = chain;
  141. }
  142.  
  143. /* This function is useful for cleanups.
  144.    Do
  145.  
  146.      foo = xmalloc (...);
  147.      old_chain = make_cleanup (free_current_contents, &foo);
  148.  
  149.    to arrange to free the object thus allocated.  */
  150.  
  151. void
  152. free_current_contents (location)
  153.      char **location;
  154. {
  155.   free (*location);
  156. }
  157.  
  158. /* Generally useful subroutines used throughout the program.  */
  159.  
  160. /* Like malloc but get error if no storage available.  */
  161.  
  162. char *
  163. xmalloc (size)
  164.      long size;
  165. {
  166.   register char *val = (char *) malloc (size);
  167.   if (!val)
  168.     fatal ("virtual memory exhausted.", 0);
  169.   return val;
  170. }
  171.  
  172. /* Like realloc but get error if no storage available.  */
  173.  
  174. char *
  175. xrealloc (ptr, size)
  176.      char *ptr;
  177.      long size;
  178. {
  179.   register char *val = (char *) realloc (ptr, size);
  180.   if (!val)
  181.     fatal ("virtual memory exhausted.", 0);
  182.   return val;
  183. }
  184.  
  185. /* Print the system error message for errno, and also mention STRING
  186.    as the file name for which the error was encountered.
  187.    Then return to command level.  */
  188.  
  189. void
  190. perror_with_name (string)
  191.      char *string;
  192. {
  193.   extern int sys_nerr;
  194.   extern char *sys_errlist[];
  195.   extern int errno;
  196.   char *err;
  197.   char *combined;
  198.  
  199.   if (errno < sys_nerr)
  200.     err = sys_errlist[errno];
  201.   else
  202.     err = "unknown error";
  203.  
  204.   combined = (char *) alloca (strlen (err) + strlen (string) + 3);
  205.   strcpy (combined, string);
  206.   strcat (combined, ": ");
  207.   strcat (combined, err);
  208.  
  209.   error ("%s.", combined);
  210. }
  211.  
  212. /* Print the system error message for ERRCODE, and also mention STRING
  213.    as the file name for which the error was encountered.  */
  214.  
  215. void
  216. print_sys_errmsg (string, errcode)
  217.      char *string;
  218.      int errcode;
  219. {
  220.   extern int sys_nerr;
  221.   extern char *sys_errlist[];
  222.   char *err;
  223.   char *combined;
  224.  
  225.   if (errcode < sys_nerr)
  226.     err = sys_errlist[errcode];
  227.   else
  228.     err = "unknown error";
  229.  
  230.   combined = (char *) alloca (strlen (err) + strlen (string) + 3);
  231.   strcpy (combined, string);
  232.   strcat (combined, ": ");
  233.   strcat (combined, err);
  234.  
  235.   printf ("%s.\n", combined);
  236. }
  237.  
  238. void
  239. quit ()
  240. {
  241. #ifdef HAVE_TERMIO
  242.   ioctl (fileno (stdout), TCFLSH, 1);
  243. #else /* not HAVE_TERMIO */
  244.   ioctl (fileno (stdout), TIOCFLUSH, 0);
  245. #endif /* not HAVE_TERMIO */
  246. #ifdef TIOCGPGRP
  247.   error ("Quit");
  248. #else
  249.   error ("Quit (expect signal %d when inferior is resumed)", SIGINT);
  250. #endif /* TIOCGPGRP */
  251. }
  252.  
  253. /* Control C comes here */
  254.  
  255. void
  256. request_quit ()
  257. {
  258.   extern int remote_debugging;
  259.  
  260.   quit_flag = 1;
  261.  
  262. #ifdef USG
  263.   /* Restore the signal handler.  */
  264.   signal (SIGINT, request_quit);
  265. #endif
  266.  
  267.   if (immediate_quit)
  268.       quit();
  269. }
  270.  
  271. /* Print an error message and return to command level.
  272.    STRING is the error message, used as a fprintf string,
  273.    and ARG is passed as an argument to it.  */
  274.  
  275. void
  276. error (string, arg1, arg2, arg3)
  277.      char *string;
  278.      int arg1, arg2, arg3;
  279. {
  280.   terminal_ours ();        /* Should be ok even if no inf.  */
  281.   fflush (stdout);
  282.   fprintf (stderr, string, arg1, arg2, arg3);
  283.   fprintf (stderr, "\n");
  284.   return_to_top_level ();
  285. }
  286.  
  287. /* Print an error message and exit reporting failure.
  288.    This is for a error that we cannot continue from.
  289.    STRING and ARG are passed to fprintf.  */
  290.  
  291. void
  292. fatal (string, arg)
  293.      char *string;
  294.      int arg;
  295. {
  296.   fprintf (stderr, "gdb: ");
  297.   fprintf (stderr, string, arg);
  298.   fprintf (stderr, "\n");
  299.   exit (1);
  300. }
  301.  
  302. /* Print an error message and exit, dumping core.
  303.    STRING is a printf-style control string, and ARG is a corresponding
  304.    argument.  */
  305. void
  306. fatal_dump_core (string, arg)
  307.      char *string;
  308.      int arg;
  309. {
  310.   /* "internal error" is always correct, since GDB should never dump
  311.      core, no matter what the input.  */
  312.   fprintf (stderr, "gdb internal error: ");
  313.   fprintf (stderr, string, arg);
  314.   fprintf (stderr, "\n");
  315.   signal (SIGQUIT, SIG_DFL);
  316.   kill (getpid (), SIGQUIT);
  317.   /* We should never get here, but just in case...  */
  318.   exit (1);
  319. }
  320.  
  321. /* Make a copy of the string at PTR with SIZE characters
  322.    (and add a null character at the end in the copy).
  323.    Uses malloc to get the space.  Returns the address of the copy.  */
  324.  
  325. char *
  326. savestring (ptr, size)
  327.      char *ptr;
  328.      int size;
  329. {
  330.   register char *p = (char *) xmalloc (size + 1);
  331.   bcopy (ptr, p, size);
  332.   p[size] = 0;
  333.   return p;
  334. }
  335.  
  336. char *
  337. concat (s1, s2, s3)
  338.      char *s1, *s2, *s3;
  339. {
  340.   register int len = strlen (s1) + strlen (s2) + strlen (s3) + 1;
  341.   register char *val = (char *) xmalloc (len);
  342.   strcpy (val, s1);
  343.   strcat (val, s2);
  344.   strcat (val, s3);
  345.   return val;
  346. }
  347.  
  348. void
  349. print_spaces (n, file)
  350.      register int n;
  351.      register FILE *file;
  352. {
  353.   while (n-- > 0)
  354.     fputc (' ', file);
  355. }
  356.  
  357. /* Ask user a y-or-n question and return 1 iff answer is yes.
  358.    Takes three args which are given to printf to print the question.
  359.    The first, a control string, should end in "? ".
  360.    It should not say how to answer, because we do that.  */
  361.  
  362. int
  363. query (ctlstr, arg1, arg2)
  364.      char *ctlstr;
  365. {
  366.   register int answer;
  367.  
  368.   /* Automatically answer "yes" if input is not from a terminal.  */
  369.   if (!input_from_terminal_p ())
  370.     return 1;
  371.  
  372.   while (1)
  373.     {
  374.       printf (ctlstr, arg1, arg2);
  375.       printf ("(y or n) ");
  376.       fflush (stdout);
  377.       answer = fgetc (stdin);
  378.       clearerr (stdin);        /* in case of C-d */
  379.       if (answer != '\n')
  380.     while (fgetc (stdin) != '\n') clearerr (stdin);
  381.       if (answer >= 'a')
  382.     answer -= 040;
  383.       if (answer == 'Y')
  384.     return 1;
  385.       if (answer == 'N')
  386.     return 0;
  387.       printf ("Please answer y or n.\n");
  388.     }
  389. }
  390.  
  391. /* Parse a C escape sequence.  STRING_PTR points to a variable
  392.    containing a pointer to the string to parse.  That pointer
  393.    is updated past the characters we use.  The value of the
  394.    escape sequence is returned.
  395.  
  396.    A negative value means the sequence \ newline was seen,
  397.    which is supposed to be equivalent to nothing at all.
  398.  
  399.    If \ is followed by a null character, we return a negative
  400.    value and leave the string pointer pointing at the null character.
  401.  
  402.    If \ is followed by 000, we return 0 and leave the string pointer
  403.    after the zeros.  A value of 0 does not mean end of string.  */
  404.  
  405. int
  406. parse_escape (string_ptr)
  407.      char **string_ptr;
  408. {
  409.   register int c = *(*string_ptr)++;
  410.   switch (c)
  411.     {
  412.     case 'a':
  413.       return '\a';
  414.     case 'b':
  415.       return '\b';
  416.     case 'e':
  417.       return 033;
  418.     case 'f':
  419.       return '\f';
  420.     case 'n':
  421.       return '\n';
  422.     case 'r':
  423.       return '\r';
  424.     case 't':
  425.       return '\t';
  426.     case 'v':
  427.       return '\v';
  428.     case '\n':
  429.       return -2;
  430.     case 0:
  431.       (*string_ptr)--;
  432.       return 0;
  433.     case '^':
  434.       c = *(*string_ptr)++;
  435.       if (c == '\\')
  436.     c = parse_escape (string_ptr);
  437.       if (c == '?')
  438.     return 0177;
  439.       return (c & 0200) | (c & 037);
  440.       
  441.     case '0':
  442.     case '1':
  443.     case '2':
  444.     case '3':
  445.     case '4':
  446.     case '5':
  447.     case '6':
  448.     case '7':
  449.       {
  450.     register int i = c - '0';
  451.     register int count = 0;
  452.     while (++count < 3)
  453.       {
  454.         if ((c = *(*string_ptr)++) >= '0' && c <= '7')
  455.           {
  456.         i *= 8;
  457.         i += c - '0';
  458.           }
  459.         else
  460.           {
  461.         (*string_ptr)--;
  462.         break;
  463.           }
  464.       }
  465.     return i;
  466.       }
  467.     default:
  468.       return c;
  469.     }
  470. }
  471.  
  472. /* Print the character CH on STREAM as part of the contents
  473.    of a literal string whose delimiter is QUOTER.  */
  474.  
  475. void
  476. printchar (ch, stream, quoter)
  477.      unsigned char ch;
  478.      FILE *stream;
  479.      int quoter;
  480. {
  481.   register int c = ch;
  482.   if (c < 040 || c >= 0177)
  483.     switch (c)
  484.       {
  485.       case '\n':
  486.     fputs_filtered ("\\n", stream);
  487.     break;
  488.       case '\b':
  489.     fputs_filtered ("\\b", stream);
  490.     break;
  491.       case '\t':
  492.     fputs_filtered ("\\t", stream);
  493.     break;
  494.       case '\f':
  495.     fputs_filtered ("\\f", stream);
  496.     break;
  497.       case '\r':
  498.     fputs_filtered ("\\r", stream);
  499.     break;
  500.       case '\033':
  501.     fputs_filtered ("\\e", stream);
  502.     break;
  503.       case '\007':
  504.     fputs_filtered ("\\a", stream);
  505.     break;
  506.       default:
  507.     fprintf_filtered (stream, "\\%.3o", (unsigned int) c);
  508.     break;
  509.       }
  510.   else
  511.     {
  512.       if (c == '\\' || c == quoter)
  513.     fputs_filtered ("\\", stream);
  514.       fprintf_filtered (stream, "%c", c);
  515.     }
  516. }
  517.  
  518. static int lines_per_page, lines_printed, chars_per_line, chars_printed;
  519.  
  520. /* Set values of page and line size.  */
  521. static void
  522. set_screensize_command (arg, from_tty)
  523.      char *arg;
  524.      int from_tty;
  525. {
  526.   char *p = arg;
  527.   char *p1;
  528.   int tolinesize = lines_per_page;
  529.   int tocharsize = chars_per_line;
  530.  
  531.   if (p == 0)
  532.     error_no_arg ("set screensize");
  533.  
  534.   while (*p >= '0' && *p <= '9')
  535.     p++;
  536.  
  537.   if (*p && *p != ' ' && *p != '\t')
  538.     error ("Non-integral argument given to \"set screensize\".");
  539.  
  540.   tolinesize = atoi (arg);
  541.  
  542.   while (*p == ' ' || *p == '\t')
  543.     p++;
  544.  
  545.   if (*p)
  546.     {
  547.       p1 = p;
  548.       while (*p1 >= '0' && *p1 <= '9')
  549.     p1++;
  550.  
  551.       if (*p1)
  552.     error ("Non-integral second argument given to \"set screensize\".");
  553.  
  554.       tocharsize = atoi (p);
  555.     }
  556.  
  557.   lines_per_page = tolinesize;
  558.   chars_per_line = tocharsize;
  559. }
  560.  
  561. static void
  562. instream_cleanup(stream)
  563.     FILE *stream;
  564. {
  565.   instream = stream;
  566. }
  567.  
  568. static void
  569. prompt_for_continue ()
  570. {
  571.   if (ISATTY(stdin) && ISATTY(stdout))
  572.     {
  573.       struct cleanup *old_chain = make_cleanup(instream_cleanup, instream);
  574.       char *cp, *gdb_readline();
  575.  
  576.       instream = stdin;
  577.       immediate_quit++;
  578.       if (cp = gdb_readline ("---Type <return> to continue---"))
  579.     free(cp);
  580.       chars_printed = lines_printed = 0;
  581.       immediate_quit--;
  582.       do_cleanups(old_chain);
  583.     }
  584. }
  585.  
  586. /* Reinitialize filter; ie. tell it to reset to original values.  */
  587.  
  588. void
  589. reinitialize_more_filter ()
  590. {
  591.   lines_printed = 0;
  592.   chars_printed = 0;
  593. }
  594.  
  595. static void
  596. screensize_info (arg, from_tty)
  597.      char *arg;
  598.      int from_tty;
  599. {
  600.   if (arg)
  601.     error ("\"info screensize\" does not take any arguments.");
  602.   
  603.   if (!lines_per_page)
  604.     printf ("Output more filtering is disabled.\n");
  605.   else
  606.     {
  607.       printf ("Output more filtering is enabled with\n");
  608.       printf ("%d lines per page and %d characters per line.\n",
  609.           lines_per_page, chars_per_line);
  610.     }
  611. }
  612.  
  613. /* Like fputs but pause after every screenful.
  614.    Unlike fputs, fputs_filtered does not return a value.
  615.    It is OK for LINEBUFFER to be NULL, in which case just don't print
  616.    anything.
  617.  
  618.    Note that a longjmp to top level may occur in this routine
  619.    (since prompt_for_continue may do so) so this routine should not be
  620.    called when cleanups are not in place.  */
  621.  
  622. void
  623. fputs_filtered (linebuffer, stream)
  624.      char *linebuffer;
  625.      FILE *stream;
  626. {
  627.   char *lineptr;
  628.  
  629.   if (linebuffer == 0)
  630.     return;
  631.   
  632.   /* Don't do any filtering if it is disabled.  */
  633.   if (stream != stdout || !ISATTY(stdout) || lines_per_page == 0)
  634.     {
  635.       fputs (linebuffer, stream);
  636.       return;
  637.     }
  638.  
  639.   /* Go through and output each character.  Show line extension
  640.      when this is necessary; prompt user for new page when this is
  641.      necessary.  */
  642.   
  643.   lineptr = linebuffer;
  644.   while (*lineptr)
  645.     {
  646.       /* Possible new page.  */
  647.       if (lines_printed >= lines_per_page - 1)
  648.     prompt_for_continue ();
  649.  
  650.       while (*lineptr && *lineptr != '\n')
  651.     {
  652.       /* Print a single line.  */
  653.       if (*lineptr == '\t')
  654.         {
  655.           putc ('\t', stream);
  656.           /* Shifting right by 3 produces the number of tab stops
  657.              we have already passed, and then adding one and
  658.          shifting left 3 advances to the next tab stop.  */
  659.           chars_printed = ((chars_printed >> 3) + 1) << 3;
  660.           lineptr++;
  661.         }
  662.       else
  663.         {
  664.           putc (*lineptr, stream);
  665.           chars_printed++;
  666.           lineptr++;
  667.         }
  668.       
  669.       if (chars_printed >= chars_per_line)
  670.         {
  671.           chars_printed = 0;
  672.           lines_printed++;
  673.           /* Possible new page.  */
  674.           if (lines_printed >= lines_per_page - 1)
  675.         prompt_for_continue ();
  676.         }
  677.     }
  678.  
  679.       if (*lineptr == '\n')
  680.     {
  681.       lines_printed++;
  682.       putc ('\n', stream);
  683.       lineptr++;
  684.       chars_printed = 0;
  685.     }
  686.     }
  687. }
  688.  
  689. /* fputs_demangled is a variant of fputs_filtered that
  690.    demangles g++ names.*/
  691.  
  692. void
  693. fputs_demangled (linebuffer, stream, arg_mode)
  694.      char *linebuffer;
  695.      FILE *stream;
  696. {
  697. #ifdef __STDC__
  698.   extern char *cplus_demangle (const char *, int);
  699. #else
  700.   extern char *cplus_demangle ();
  701. #endif
  702. #define SYMBOL_MAX 1024
  703.  
  704. #define SYMBOL_CHAR(c) (isascii(c) && (isalnum(c) || (c) == '_' || (c) == '$'))
  705.  
  706.   char buf[SYMBOL_MAX+1];
  707.   char *p;
  708.  
  709.   if (linebuffer == NULL)
  710.     return;
  711.  
  712.   p = linebuffer;
  713.  
  714.   while ( *p != (char) 0 ) {
  715.     int i = 0;
  716.  
  717.     /* collect non-interesting characters into buf */
  718.     while ( *p != (char) 0 && !SYMBOL_CHAR(*p) ) {
  719.       buf[i++] = *p;
  720.       p++;
  721.     }
  722.     if (i > 0) {
  723.       /* output the non-interesting characters without demangling */
  724.       buf[i] = (char) 0;
  725.       fputs_filtered(buf, stream);
  726.       i = 0;  /* reset buf */
  727.     }
  728.  
  729.     /* and now the interesting characters */
  730.     while (i < SYMBOL_MAX && *p != (char) 0 && SYMBOL_CHAR(*p) ) {
  731.       buf[i++] = *p;
  732.       p++;
  733.     }
  734.     buf[i] = (char) 0;
  735.     if (i > 0) {
  736.       char * result;
  737.       
  738.       if ( (result = cplus_demangle(buf, arg_mode)) != NULL ) {
  739.     fputs_filtered(result, stream);
  740.     free(result);
  741.       }
  742.       else {
  743.     fputs_filtered(buf, stream);
  744.       }
  745.     }
  746.   }
  747. }
  748.  
  749. /* Print ARG1, ARG2, and ARG3 on stdout using format FORMAT.  If this
  750.    information is going to put the amount written since the last call
  751.    to INIIALIZE_MORE_FILTER or the last page break over the page size,
  752.    print out a pause message and do a gdb_readline to get the users
  753.    permision to continue.
  754.  
  755.    Unlike fprintf, this function does not return a value.
  756.  
  757.    Note that this routine has a restriction that the length of the
  758.    final output line must be less than 255 characters *or* it must be
  759.    less than twice the size of the format string.  This is a very
  760.    arbitrary restriction, but it is an internal restriction, so I'll
  761.    put it in.  This means that the %s format specifier is almost
  762.    useless; unless the caller can GUARANTEE that the string is short
  763.    enough, fputs_filtered should be used instead.
  764.  
  765.    Note also that a longjmp to top level may occur in this routine
  766.    (since prompt_for_continue may do so) so this routine should not be
  767.    called when cleanups are not in place.  */
  768.  
  769. void
  770. fprintf_filtered (stream, format, arg1, arg2, arg3, arg4, arg5, arg6)
  771.      FILE *stream;
  772.      char *format;
  773.      int arg1, arg2, arg3, arg4, arg5, arg6;
  774. {
  775.   static char *linebuffer = (char *) 0;
  776.   static int line_size;
  777.   int format_length = strlen (format);
  778.   int numchars;
  779.  
  780.   /* Allocated linebuffer for the first time.  */
  781.   if (!linebuffer)
  782.     {
  783.       linebuffer = (char *) xmalloc (255);
  784.       line_size = 255;
  785.     }
  786.  
  787.   /* Reallocate buffer to a larger size if this is necessary.  */
  788.   if (format_length * 2 > line_size)
  789.     {
  790.       line_size = format_length * 2;
  791.  
  792.       /* You don't have to copy.  */
  793.       free (linebuffer);
  794.       linebuffer = (char *) xmalloc (line_size);
  795.     }
  796.  
  797.   /* This won't blow up if the restrictions described above are
  798.      followed.   */
  799.   (void) sprintf (linebuffer, format, arg1, arg2, arg3, arg4, arg5, arg6);
  800.  
  801.   fputs_filtered (linebuffer, stream);
  802. }
  803.  
  804. void
  805. printf_filtered (format, arg1, arg2, arg3, arg4, arg5, arg6)
  806.      char *format;
  807.      int arg1, arg2, arg3, arg4, arg5, arg6;
  808. {
  809.   fprintf_filtered (stdout, format, arg1, arg2, arg3, arg4, arg5, arg6);
  810. }
  811.  
  812. /* Print N spaces.  */
  813. void
  814. print_spaces_filtered (n, stream)
  815.      int n;
  816.      FILE *stream;
  817. {
  818.   register char *s = (char *) alloca (n + 1);
  819.   register char *t = s;
  820.  
  821.   while (n--)
  822.     *t++ = ' ';
  823.   *t = '\0';
  824.  
  825.   fputs_filtered (s, stream);
  826. }
  827.  
  828.  
  829. #ifdef USG
  830. bcopy (from, to, count)
  831. char *from, *to;
  832. {
  833.     memcpy (to, from, count);
  834. }
  835.  
  836. bcmp (from, to, count)
  837. {
  838.     return (memcmp (to, from, count));
  839. }
  840.  
  841. bzero (to, count)
  842. char *to;
  843. {
  844.     while (count--)
  845.         *to++ = 0;
  846. }
  847.  
  848. getwd (buf)
  849. char *buf;
  850. {
  851.   getcwd (buf, MAXPATHLEN);
  852. }
  853.  
  854. char *
  855. index (s, c)
  856.      char *s;
  857. {
  858.   char *strchr ();
  859.   return strchr (s, c);
  860. }
  861.  
  862. char *
  863. rindex (s, c)
  864.      char *s;
  865. {
  866.   char *strrchr ();
  867.   return strrchr (s, c);
  868. }
  869.  
  870. #ifndef USG
  871. char *sys_siglist[32] = {
  872.     "SIG0",
  873.     "SIGHUP",
  874.     "SIGINT",
  875.     "SIGQUIT",
  876.     "SIGILL",
  877.     "SIGTRAP",
  878.     "SIGIOT",
  879.     "SIGEMT",
  880.     "SIGFPE",
  881.     "SIGKILL",
  882.     "SIGBUS",
  883.     "SIGSEGV",
  884.     "SIGSYS",
  885.     "SIGPIPE",
  886.     "SIGALRM",
  887.     "SIGTERM",
  888.     "SIGUSR1",
  889.     "SIGUSR2",
  890.     "SIGCLD",
  891.     "SIGPWR",
  892.     "SIGWIND",
  893.     "SIGPHONE",
  894.     "SIGPOLL",
  895. };
  896. #endif
  897.  
  898. /* Queue routines */
  899.  
  900. struct queue {
  901.     struct queue *forw;
  902.     struct queue *back;
  903. };
  904.  
  905. insque (item, after)
  906. struct queue *item;
  907. struct queue *after;
  908. {
  909.     item->forw = after->forw;
  910.     after->forw->back = item;
  911.  
  912.     item->back = after;
  913.     after->forw = item;
  914. }
  915.  
  916. remque (item)
  917. struct queue *item;
  918. {
  919.     item->forw->back = item->back;
  920.     item->back->forw = item->forw;
  921. }
  922. #endif /* USG */
  923.  
  924. #ifdef USG
  925. /* There is too much variation in Sys V signal numbers and names, so
  926.    we must initialize them at runtime.  */
  927. static char undoc[] = "(undocumented)";
  928.  
  929. char *sys_siglist[NSIG];
  930. #endif /* USG */
  931.  
  932. extern struct cmd_list_element *setlist;
  933.  
  934. void
  935. _initialize_utils ()
  936. {
  937.   int i;
  938.   add_cmd ("screensize", class_support, set_screensize_command,
  939.        "Change gdb's notion of the size of the output screen.\n\
  940. The first argument is the number of lines on a page.\n\
  941. The second argument (optional) is the number of characters on a line.",
  942.        &setlist);
  943.   add_info ("screensize", screensize_info,
  944.         "Show gdb's current notion of the size of the output screen.");
  945.  
  946.   /* These defaults will be used if we are unable to get the correct
  947.      values from termcap.  */
  948.   lines_per_page = 24;
  949.   chars_per_line = 80;
  950.   /* Initialize the screen height and width from termcap.  */
  951.   {
  952.     int termtype = getenv ("TERM");
  953.  
  954.     /* Positive means success, nonpositive means failure.  */
  955.     int status;
  956.  
  957.     /* 2048 is large enough for all known terminals, according to the
  958.        GNU termcap manual.  */
  959.     char term_buffer[2048];
  960.  
  961.     if (termtype)
  962.       {
  963.     status = tgetent (term_buffer, termtype);
  964.     if (status > 0)
  965.       {
  966.         int val;
  967.         
  968.         val = tgetnum ("li");
  969.         if (val >= 0)
  970.           lines_per_page = val;
  971.         else
  972.           /* The number of lines per page is not mentioned
  973.          in the terminal description.  This probably means
  974.          that paging is not useful (e.g. emacs shell window),
  975.          so disable paging.  */
  976.           lines_per_page = 0;
  977.         
  978.         val = tgetnum ("co");
  979.         if (val >= 0)
  980.           chars_per_line = val;
  981.       }
  982.       }
  983.   }
  984.  
  985. #ifdef USG
  986.   /* Initialize signal names.  */
  987.     for (i = 0; i < NSIG; i++)
  988.         sys_siglist[i] = undoc;
  989.  
  990. #ifdef SIGHUP
  991.     sys_siglist[SIGHUP    ] = "SIGHUP";
  992. #endif
  993. #ifdef SIGINT
  994.     sys_siglist[SIGINT    ] = "SIGINT";
  995. #endif
  996. #ifdef SIGQUIT
  997.     sys_siglist[SIGQUIT    ] = "SIGQUIT";
  998. #endif
  999. #ifdef SIGILL
  1000.     sys_siglist[SIGILL    ] = "SIGILL";
  1001. #endif
  1002. #ifdef SIGTRAP
  1003.     sys_siglist[SIGTRAP    ] = "SIGTRAP";
  1004. #endif
  1005. #ifdef SIGIOT
  1006.     sys_siglist[SIGIOT    ] = "SIGIOT";
  1007. #endif
  1008. #ifdef SIGEMT
  1009.     sys_siglist[SIGEMT    ] = "SIGEMT";
  1010. #endif
  1011. #ifdef SIGFPE
  1012.     sys_siglist[SIGFPE    ] = "SIGFPE";
  1013. #endif
  1014. #ifdef SIGKILL
  1015.     sys_siglist[SIGKILL    ] = "SIGKILL";
  1016. #endif
  1017. #ifdef SIGBUS
  1018.     sys_siglist[SIGBUS    ] = "SIGBUS";
  1019. #endif
  1020. #ifdef SIGSEGV
  1021.     sys_siglist[SIGSEGV    ] = "SIGSEGV";
  1022. #endif
  1023. #ifdef SIGSYS
  1024.     sys_siglist[SIGSYS    ] = "SIGSYS";
  1025. #endif
  1026. #ifdef SIGPIPE
  1027.     sys_siglist[SIGPIPE    ] = "SIGPIPE";
  1028. #endif
  1029. #ifdef SIGALRM
  1030.     sys_siglist[SIGALRM    ] = "SIGALRM";
  1031. #endif
  1032. #ifdef SIGTERM
  1033.     sys_siglist[SIGTERM    ] = "SIGTERM";
  1034. #endif
  1035. #ifdef SIGUSR1
  1036.     sys_siglist[SIGUSR1    ] = "SIGUSR1";
  1037. #endif
  1038. #ifdef SIGUSR2
  1039.     sys_siglist[SIGUSR2    ] = "SIGUSR2";
  1040. #endif
  1041. #ifdef SIGCLD
  1042.     sys_siglist[SIGCLD    ] = "SIGCLD";
  1043. #endif
  1044. #ifdef SIGCHLD
  1045.     sys_siglist[SIGCHLD    ] = "SIGCHLD";
  1046. #endif
  1047. #ifdef SIGPWR
  1048.     sys_siglist[SIGPWR    ] = "SIGPWR";
  1049. #endif
  1050. #ifdef SIGTSTP
  1051.     sys_siglist[SIGTSTP    ] = "SIGTSTP";
  1052. #endif
  1053. #ifdef SIGTTIN
  1054.     sys_siglist[SIGTTIN    ] = "SIGTTIN";
  1055. #endif
  1056. #ifdef SIGTTOU
  1057.     sys_siglist[SIGTTOU    ] = "SIGTTOU";
  1058. #endif
  1059. #ifdef SIGSTOP
  1060.     sys_siglist[SIGSTOP    ] = "SIGSTOP";
  1061. #endif
  1062. #ifdef SIGXCPU
  1063.     sys_siglist[SIGXCPU    ] = "SIGXCPU";
  1064. #endif
  1065. #ifdef SIGXFSZ
  1066.     sys_siglist[SIGXFSZ    ] = "SIGXFSZ";
  1067. #endif
  1068. #ifdef SIGVTALRM
  1069.     sys_siglist[SIGVTALRM    ] = "SIGVTALRM";
  1070. #endif
  1071. #ifdef SIGPROF
  1072.     sys_siglist[SIGPROF    ] = "SIGPROF";
  1073. #endif
  1074. #ifdef SIGWINCH
  1075.     sys_siglist[SIGWINCH    ] = "SIGWINCH";
  1076. #endif
  1077. #ifdef SIGCONT
  1078.     sys_siglist[SIGCONT    ] = "SIGCONT";
  1079. #endif
  1080. #ifdef SIGURG
  1081.     sys_siglist[SIGURG    ] = "SIGURG";
  1082. #endif
  1083. #ifdef SIGIO
  1084.     sys_siglist[SIGIO    ] = "SIGIO";
  1085. #endif
  1086. #ifdef SIGWIND
  1087.     sys_siglist[SIGWIND    ] = "SIGWIND";
  1088. #endif
  1089. #ifdef SIGPHONE
  1090.     sys_siglist[SIGPHONE    ] = "SIGPHONE";
  1091. #endif
  1092. #ifdef SIGPOLL
  1093.     sys_siglist[SIGPOLL    ] = "SIGPOLL";
  1094. #endif
  1095. #endif /* USG */
  1096. }
  1097.