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

unix.superglobalmegacorp.com

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