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