Annotation of 43BSDReno/contrib/emacs-18.55/gdb/utils.c, revision 1.1.1.1

1.1       root        1: /* General utility routines for GDB, the GNU debugger.
                      2:    Copyright (C) 1986 Free Software Foundation, Inc.
                      3: 
                      4: GDB is distributed in the hope that it will be useful, but WITHOUT ANY
                      5: WARRANTY.  No author or distributor accepts responsibility to anyone
                      6: for the consequences of using it or for whether it serves any
                      7: particular purpose or works at all, unless he says so in writing.
                      8: Refer to the GDB General Public License for full details.
                      9: 
                     10: Everyone is granted permission to copy, modify and redistribute GDB,
                     11: but only under the conditions described in the GDB General Public
                     12: License.  A copy of this license is supposed to have been given to you
                     13: along with GDB so you can know your rights and responsibilities.  It
                     14: should be in a file named COPYING.  Among other things, the copyright
                     15: notice and this notice must be preserved on all copies.
                     16: 
                     17: In other words, go ahead and share GDB, but don't try to stop
                     18: anyone else from sharing it farther.  Help stamp out software hoarding!
                     19: */
                     20: 
                     21: #include <stdio.h>
                     22: #include <signal.h>
                     23: #include <sys/ioctl.h>
                     24: #include "defs.h"
                     25: #include "param.h"
                     26: #ifdef HAVE_TERMIO
                     27: #include <termio.h>
                     28: #endif
                     29: 
                     30: void error ();
                     31: void fatal ();
                     32: 
                     33: /* Chain of cleanup actions established with make_cleanup,
                     34:    to be executed if an error happens.  */
                     35: 
                     36: static struct cleanup *cleanup_chain;
                     37: 
                     38: /* Nonzero means a quit has been requested.  */
                     39: 
                     40: int quit_flag;
                     41: 
                     42: /* Nonzero means quit immediately if Control-C is typed now,
                     43:    rather than waiting until QUIT is executed.  */
                     44: 
                     45: int immediate_quit;
                     46: 
                     47: /* Add a new cleanup to the cleanup_chain,
                     48:    and return the previous chain pointer
                     49:    to be passed later to do_cleanups or discard_cleanups.
                     50:    Args are FUNCTION to clean up with, and ARG to pass to it.  */
                     51: 
                     52: struct cleanup *
                     53: make_cleanup (function, arg)
                     54:      void (*function) ();
                     55:      int arg;
                     56: {
                     57:   register struct cleanup *new
                     58:     = (struct cleanup *) xmalloc (sizeof (struct cleanup));
                     59:   register struct cleanup *old_chain = cleanup_chain;
                     60: 
                     61:   new->next = cleanup_chain;
                     62:   new->function = function;
                     63:   new->arg = arg;
                     64:   cleanup_chain = new;
                     65: 
                     66:   return old_chain;
                     67: }
                     68: 
                     69: /* Discard cleanups and do the actions they describe
                     70:    until we get back to the point OLD_CHAIN in the cleanup_chain.  */
                     71: 
                     72: void
                     73: do_cleanups (old_chain)
                     74:      register struct cleanup *old_chain;
                     75: {
                     76:   register struct cleanup *ptr;
                     77:   while ((ptr = cleanup_chain) != old_chain)
                     78:     {
                     79:       (*ptr->function) (ptr->arg);
                     80:       cleanup_chain = ptr->next;
                     81:       free (ptr);
                     82:     }
                     83: }
                     84: 
                     85: /* Discard cleanups, not doing the actions they describe,
                     86:    until we get back to the point OLD_CHAIN in the cleanup_chain.  */
                     87: 
                     88: void
                     89: discard_cleanups (old_chain)
                     90:      register struct cleanup *old_chain;
                     91: {
                     92:   register struct cleanup *ptr;
                     93:   while ((ptr = cleanup_chain) != old_chain)
                     94:     {
                     95:       cleanup_chain = ptr->next;
                     96:       free (ptr);
                     97:     }
                     98: }
                     99: 
                    100: /* This function is useful for cleanups.
                    101:    Do
                    102: 
                    103:      foo = xmalloc (...);
                    104:      old_chain = make_cleanup (free_current_contents, &foo);
                    105: 
                    106:    to arrange to free the object thus allocated.  */
                    107: 
                    108: void
                    109: free_current_contents (location)
                    110:      char **location;
                    111: {
                    112:   free (*location);
                    113: }
                    114: 
                    115: /* Generally useful subroutines used throughout the program.  */
                    116: 
                    117: /* Like malloc but get error if no storage available.  */
                    118: 
                    119: char *
                    120: xmalloc (size)
                    121:      long size;
                    122: {
                    123:   register char *val = (char *) malloc (size);
                    124:   if (!val)
                    125:     fatal ("virtual memory exhausted.", 0);
                    126:   return val;
                    127: }
                    128: 
                    129: /* Like realloc but get error if no storage available.  */
                    130: 
                    131: char *
                    132: xrealloc (ptr, size)
                    133:      char *ptr;
                    134:      long size;
                    135: {
                    136:   register char *val = (char *) realloc (ptr, size);
                    137:   if (!val)
                    138:     fatal ("virtual memory exhausted.", 0);
                    139:   return val;
                    140: }
                    141: 
                    142: /* Print the system error message for errno, and also mention STRING
                    143:    as the file name for which the error was encountered.
                    144:    Then return to command level.  */
                    145: 
                    146: void
                    147: perror_with_name (string)
                    148:      char *string;
                    149: {
                    150:   extern int sys_nerr;
                    151:   extern char *sys_errlist[];
                    152:   extern int errno;
                    153:   char *err;
                    154:   char *combined;
                    155: 
                    156:   if (errno < sys_nerr)
                    157:     err = sys_errlist[errno];
                    158:   else
                    159:     err = "unknown error";
                    160: 
                    161:   combined = (char *) alloca (strlen (err) + strlen (string) + 3);
                    162:   strcpy (combined, string);
                    163:   strcat (combined, ": ");
                    164:   strcat (combined, err);
                    165: 
                    166:   error ("%s.", combined);
                    167: }
                    168: 
                    169: /* Print the system error message for ERRCODE, and also mention STRING
                    170:    as the file name for which the error was encountered.  */
                    171: 
                    172: void
                    173: print_sys_errmsg (string, errcode)
                    174:      char *string;
                    175:      int errcode;
                    176: {
                    177:   extern int sys_nerr;
                    178:   extern char *sys_errlist[];
                    179:   char *err;
                    180:   char *combined;
                    181: 
                    182:   if (errcode < sys_nerr)
                    183:     err = sys_errlist[errcode];
                    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:   printf ("%s.\n", combined);
                    193: }
                    194: 
                    195: void
                    196: quit ()
                    197: {
                    198:   fflush (stdout);
                    199: #ifdef HAVE_TERMIO
                    200:   ioctl (fileno (stdout), TCFLSH, 1);
                    201: #else /* not HAVE_TERMIO */
                    202:   ioctl (fileno (stdout), TIOCFLUSH, 0);
                    203: #endif /* not HAVE_TERMIO */
                    204: #ifdef TIOCGPGRP
                    205:   error ("Quit");
                    206: #else
                    207:   error ("Quit (expect signal %d when inferior is resumed)", SIGINT);
                    208: #endif /* TIOCGPGRP */
                    209: }
                    210: 
                    211: /* Control C comes here */
                    212: 
                    213: void
                    214: request_quit ()
                    215: {
                    216:   quit_flag = 1;
                    217:   if (immediate_quit)
                    218:     quit ();
                    219: }
                    220: 
                    221: /* Print an error message and return to command level.
                    222:    STRING is the error message, used as a fprintf string,
                    223:    and ARG is passed as an argument to it.  */
                    224: 
                    225: void
                    226: error (string, arg1, arg2, arg3)
                    227:      char *string;
                    228:      int arg1, arg2, arg3;
                    229: {
                    230:   fflush (stdout);
                    231:   fprintf (stderr, string, arg1, arg2, arg3);
                    232:   fprintf (stderr, "\n");
                    233:   return_to_top_level ();
                    234: }
                    235: 
                    236: /* Print an error message and exit reporting failure.
                    237:    This is for a error that we cannot continue from.
                    238:    STRING and ARG are passed to fprintf.  */
                    239: 
                    240: void
                    241: fatal (string, arg)
                    242:      char *string;
                    243:      int arg;
                    244: {
                    245:   fprintf (stderr, "gdb: ");
                    246:   fprintf (stderr, string, arg);
                    247:   fprintf (stderr, "\n");
                    248:   exit (1);
                    249: }
                    250: 
                    251: /* Make a copy of the string at PTR with SIZE characters
                    252:    (and add a null character at the end in the copy).
                    253:    Uses malloc to get the space.  Returns the address of the copy.  */
                    254: 
                    255: char *
                    256: savestring (ptr, size)
                    257:      char *ptr;
                    258:      int size;
                    259: {
                    260:   register char *p = (char *) xmalloc (size + 1);
                    261:   bcopy (ptr, p, size);
                    262:   p[size] = 0;
                    263:   return p;
                    264: }
                    265: 
                    266: char *
                    267: concat (s1, s2, s3)
                    268:      char *s1, *s2, *s3;
                    269: {
                    270:   register int len = strlen (s1) + strlen (s2) + strlen (s3) + 1;
                    271:   register char *val = (char *) xmalloc (len);
                    272:   strcpy (val, s1);
                    273:   strcat (val, s2);
                    274:   strcat (val, s3);
                    275:   return val;
                    276: }
                    277: 
                    278: void
                    279: print_spaces (n, file)
                    280:      register int n;
                    281:      register FILE *file;
                    282: {
                    283:   while (n-- > 0)
                    284:     fputc (' ', file);
                    285: }
                    286: 
                    287: /* Ask user a y-or-n question and return 1 iff answer is yes.
                    288:    Takes three args which are given to printf to print the question.
                    289:    The first, a control string, should end in "? ".
                    290:    It should not say how to answer, because we do that.  */
                    291: 
                    292: int
                    293: query (ctlstr, arg1, arg2)
                    294:      char *ctlstr;
                    295: {
                    296:   register int answer;
                    297: 
                    298:   /* Automatically answer "yes" if input is not from a terminal.  */
                    299:   if (!input_from_terminal_p ())
                    300:     return 1;
                    301: 
                    302:   while (1)
                    303:     {
                    304:       printf (ctlstr, arg1, arg2);
                    305:       printf ("(y or n) ");
                    306:       fflush (stdout);
                    307:       answer = fgetc (stdin);
                    308:       clearerr (stdin);                /* in case of C-d */
                    309:       if (answer != '\n')
                    310:        while (fgetc (stdin) != '\n') clearerr (stdin);
                    311:       if (answer >= 'a')
                    312:        answer -= 040;
                    313:       if (answer == 'Y')
                    314:        return 1;
                    315:       if (answer == 'N')
                    316:        return 0;
                    317:       printf ("Please answer y or n.\n");
                    318:     }
                    319: }
                    320: 
                    321: /* Parse a C escape sequence.  STRING_PTR points to a variable
                    322:    containing a pointer to the string to parse.  That pointer
                    323:    is updated past the characters we use.  The value of the
                    324:    escape sequence is returned.
                    325: 
                    326:    A negative value means the sequence \ newline was seen,
                    327:    which is supposed to be equivalent to nothing at all.
                    328: 
                    329:    If \ is followed by a null character, we return a negative
                    330:    value and leave the string pointer pointing at the null character.
                    331: 
                    332:    If \ is followed by 000, we return 0 and leave the string pointer
                    333:    after the zeros.  A value of 0 does not mean end of string.  */
                    334: 
                    335: int
                    336: parse_escape (string_ptr)
                    337:      char **string_ptr;
                    338: {
                    339:   register int c = *(*string_ptr)++;
                    340:   switch (c)
                    341:     {
                    342:     case 'a':
                    343:       return '\a';
                    344:     case 'b':
                    345:       return '\b';
                    346:     case 'e':
                    347:       return 033;
                    348:     case 'f':
                    349:       return '\f';
                    350:     case 'n':
                    351:       return '\n';
                    352:     case 'r':
                    353:       return '\r';
                    354:     case 't':
                    355:       return '\t';
                    356:     case 'v':
                    357:       return '\v';
                    358:     case '\n':
                    359:       return -2;
                    360:     case 0:
                    361:       (*string_ptr)--;
                    362:       return 0;
                    363:     case '^':
                    364:       c = *(*string_ptr)++;
                    365:       if (c == '\\')
                    366:        c = parse_escape (string_ptr);
                    367:       if (c == '?')
                    368:        return 0177;
                    369:       return (c & 0200) | (c & 037);
                    370:       
                    371:     case '0':
                    372:     case '1':
                    373:     case '2':
                    374:     case '3':
                    375:     case '4':
                    376:     case '5':
                    377:     case '6':
                    378:     case '7':
                    379:       {
                    380:        register int i = c - '0';
                    381:        register int count = 0;
                    382:        while (++count < 3)
                    383:          {
                    384:            if ((c = *(*string_ptr)++) >= '0' && c <= '7')
                    385:              {
                    386:                i *= 8;
                    387:                i += c - '0';
                    388:              }
                    389:            else
                    390:              {
                    391:                (*string_ptr)--;
                    392:                break;
                    393:              }
                    394:          }
                    395:        return i;
                    396:       }
                    397:     default:
                    398:       return c;
                    399:     }
                    400: }
                    401: 
                    402: /* Print the character CH on STREAM as part of the contents
                    403:    of a literal string whose delimiter is QUOTER.  */
                    404: 
                    405: void
                    406: printchar (ch, stream, quoter)
                    407:      unsigned char ch;
                    408:      FILE *stream;
                    409:      int quoter;
                    410: {
                    411:   register int c = ch;
                    412:   if (c < 040 || c >= 0177)
                    413:     {
                    414:       if (c == '\n')
                    415:        fprintf (stream, "\\n");
                    416:       else if (c == '\b')
                    417:        fprintf (stream, "\\b");
                    418:       else if (c == '\t')
                    419:        fprintf (stream, "\\t");
                    420:       else if (c == '\f')
                    421:        fprintf (stream, "\\f");
                    422:       else if (c == '\r')
                    423:        fprintf (stream, "\\r");
                    424:       else if (c == 033)
                    425:        fprintf (stream, "\\e");
                    426:       else if (c == '\a')
                    427:        fprintf (stream, "\\a");
                    428:       else
                    429:        fprintf (stream, "\\%03o", c);
                    430:     }
                    431:   else
                    432:     {
                    433:       if (c == '\\' || c == quoter)
                    434:        fputc ('\\', stream);
                    435:       fputc (c, stream);
                    436:     }
                    437: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.