home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / cmds / gdb / foo / utils.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-11-05  |  21.2 KB  |  1,001 lines

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