Annotation of 43BSDReno/contrib/emacs-18.55/gdb/printcmd.c, revision 1.1

1.1     ! root        1: /* Print values for GNU debugger GDB.
        !             2:    Copyright (C) 1986, 1987, 1988 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 "defs.h"
        !            23: #include "initialize.h"
        !            24: #include "param.h"
        !            25: #include "symtab.h"
        !            26: #include "value.h"
        !            27: #include "expression.h"
        !            28: 
        !            29: struct format_data
        !            30: {
        !            31:   int count;
        !            32:   char format;
        !            33:   char size;
        !            34: };
        !            35: 
        !            36: /* Last specified output format.  */
        !            37: 
        !            38: static char last_format = 'x';
        !            39: 
        !            40: /* Last specified examination size.  'b', 'h', 'w' or `q'.  */
        !            41: 
        !            42: static char last_size = 'w';
        !            43: 
        !            44: /* Default address to examine next.  */
        !            45: 
        !            46: static CORE_ADDR next_address;
        !            47: 
        !            48: /* Last address examined.  */
        !            49: 
        !            50: static CORE_ADDR last_examine_address;
        !            51: 
        !            52: /* Contents of last address examined.
        !            53:    This is not valid past the end of the `x' command!  */
        !            54: 
        !            55: static value last_examine_value;
        !            56: 
        !            57: /* Number of auto-display expression currently being displayed.
        !            58:    So that we can deleted it if we get an error or a signal within it.
        !            59:    -1 when not doing one.  */
        !            60: 
        !            61: int current_display_number;
        !            62: 
        !            63: static void do_one_display ();
        !            64: 
        !            65: void do_displays ();
        !            66: void print_address ();
        !            67: void print_scalar_formatted ();
        !            68: 
        !            69: START_FILE
        !            70: 
        !            71: /* Decode a format specification.  *STRING_PTR should point to it.
        !            72:    OFORMAT and OSIZE are used as defaults for the format and size
        !            73:    if none are given in the format specification.
        !            74:    The structure returned describes all the data
        !            75:    found in the specification.  In addition, *STRING_PTR is advanced
        !            76:    past the specification and past all whitespace following it.  */
        !            77: 
        !            78: struct format_data
        !            79: decode_format (string_ptr, oformat, osize)
        !            80:      char **string_ptr;
        !            81:      char oformat;
        !            82:      char osize;
        !            83: {
        !            84:   struct format_data val;
        !            85:   register char *p = *string_ptr;
        !            86: 
        !            87:   val.format = oformat;
        !            88:   val.size = osize;
        !            89:   val.count = 1;
        !            90: 
        !            91:   if (*p >= '0' && *p <= '9')
        !            92:     val.count = atoi (p);
        !            93:   while (*p >= '0' && *p <= '9') p++;
        !            94: 
        !            95:   /* Now process size or format letters that follow.  */
        !            96: 
        !            97:   while (1)
        !            98:     {
        !            99:       if (*p == 'b' || *p == 'h' || *p == 'w' || *p == 'g')
        !           100:        val.size = *p++;
        !           101:       else if (*p >= 'a' && *p <= 'z')
        !           102:        val.format = *p++;
        !           103:       else
        !           104:        break;
        !           105:     }
        !           106: 
        !           107:   /* Make sure 'g' size is not used on integer types.  */
        !           108:   if (val.size == 'g' && val.format != 'f')
        !           109:     val.size = 'w';
        !           110: 
        !           111:   while (*p == ' ' || *p == '\t') p++;
        !           112:   *string_ptr = p;
        !           113: 
        !           114:   return val;
        !           115: }
        !           116: 
        !           117: /* Print value VAL on stdout according to FORMAT, a letter or 0.
        !           118:    Do not end with a newline.
        !           119:    0 means print VAL according to its own type.
        !           120:    SIZE is the letter for the size of datum being printed.
        !           121:    This is used to pad hex numbers so they line up.  */
        !           122: 
        !           123: static void
        !           124: print_formatted (val, format, size)
        !           125:      register value val;
        !           126:      register char format;
        !           127:      char size;
        !           128: {
        !           129:   register CORE_ADDR val_long;
        !           130:   int len = TYPE_LENGTH (VALUE_TYPE (val));
        !           131: 
        !           132:   if (VALUE_LVAL (val) == lval_memory)
        !           133:     next_address = VALUE_ADDRESS (val) + len;
        !           134: 
        !           135:   switch (format)
        !           136:     {
        !           137:     case 's':
        !           138:       next_address = VALUE_ADDRESS (val)
        !           139:        + value_print (value_addr (val), stdout, 0);
        !           140:       break;
        !           141: 
        !           142:     case 'i':
        !           143:       next_address = VALUE_ADDRESS (val)
        !           144:        + print_insn (VALUE_ADDRESS (val), stdout);
        !           145:       break;
        !           146: 
        !           147:     default:
        !           148:       if (format == 0
        !           149:          || TYPE_CODE (VALUE_TYPE (val)) == TYPE_CODE_ARRAY
        !           150:          || TYPE_CODE (VALUE_TYPE (val)) == TYPE_CODE_STRUCT
        !           151:          || TYPE_CODE (VALUE_TYPE (val)) == TYPE_CODE_UNION)
        !           152:        value_print (val, stdout, format);
        !           153:       else
        !           154:        print_scalar_formatted (VALUE_CONTENTS (val), VALUE_TYPE (val),
        !           155:                                format, size, stdout);
        !           156:     }
        !           157: }
        !           158: 
        !           159: /* Print a scalar of data of type TYPE, pointed to in GDB by VALADDR,
        !           160:    according to letters FORMAT and SIZE on STREAM.
        !           161:    FORMAT may not be zero.  Formats s and i are not supported at this level.
        !           162: 
        !           163:    This is how the elements of an array or structure are printed
        !           164:    with a format.  */
        !           165: 
        !           166: void
        !           167: print_scalar_formatted (valaddr, type, format, size, stream)
        !           168:      char *valaddr;
        !           169:      struct type *type;
        !           170:      char format;
        !           171:      int size;
        !           172:      FILE *stream;
        !           173: {
        !           174:   long val_long;
        !           175:   int len = TYPE_LENGTH (type);
        !           176: 
        !           177:   val_long = unpack_long (type, valaddr);
        !           178: 
        !           179:   /* If value is unsigned, truncate it in case negative.  */
        !           180:   if (format != 'd')
        !           181:     {
        !           182:       if (len == sizeof (char))
        !           183:        val_long &= (1 << 8 * sizeof(char)) - 1;
        !           184:       else if (len == sizeof (short))
        !           185:        val_long &= (1 << 8 * sizeof(short)) - 1;
        !           186:     }
        !           187: 
        !           188:   switch (format)
        !           189:     {
        !           190:     case 'x':
        !           191:       switch (size)
        !           192:        {
        !           193:        case 'b':
        !           194:          printf ("0x%02x", val_long);
        !           195:          break;
        !           196:        case 'h':
        !           197:          printf ("0x%04x", val_long);
        !           198:          break;
        !           199:        case 0:         /* no size specified, like in print */
        !           200:        case 'w':
        !           201:          printf ("0x%08x", val_long);
        !           202:          break;
        !           203:        case 'g':
        !           204:          printf ("0x%16x", val_long);
        !           205:          break;
        !           206:        default:
        !           207:          error ("Undefined output size \"%c\".", size);
        !           208:        }
        !           209:       break;
        !           210: 
        !           211:     case 'd':
        !           212:       printf ("%d", val_long);
        !           213:       break;
        !           214: 
        !           215:     case 'u':
        !           216:       printf ("%u", val_long);
        !           217:       break;
        !           218: 
        !           219:     case 'o':
        !           220:       if (val_long)
        !           221:        printf ("0%o", val_long);
        !           222:       else
        !           223:        printf ("0");
        !           224:       break;
        !           225: 
        !           226:     case 'a':
        !           227:       print_address (val_long, stream);
        !           228:       break;
        !           229: 
        !           230:     case 'c':
        !           231:       value_print (value_from_long (builtin_type_char, val_long), stream, 0);
        !           232:       break;
        !           233: 
        !           234:     case 'f':
        !           235:       if (len == sizeof (float))
        !           236:        type = builtin_type_float;
        !           237:       if (len == sizeof (double))
        !           238:        type = builtin_type_double;
        !           239: #ifdef IEEE_FLOAT
        !           240:       if (is_nan (unpack_double (type, valaddr)))
        !           241:        {
        !           242:          printf ("Nan");
        !           243:          break;
        !           244:        }
        !           245: #endif
        !           246:       printf ("%g", unpack_double (type, valaddr));
        !           247:       break;
        !           248: 
        !           249:     case 0:
        !           250:       abort ();
        !           251: 
        !           252:     default:
        !           253:       error ("Undefined output format \"%c\".", format);
        !           254:     }
        !           255: }
        !           256: 
        !           257: /* Specify default address for `x' command.
        !           258:    `info lines' uses this.  */
        !           259: 
        !           260: void
        !           261: set_next_address (addr)
        !           262:      CORE_ADDR addr;
        !           263: {
        !           264:   next_address = addr;
        !           265: 
        !           266:   /* Make address available to the user as $_.  */
        !           267:   set_internalvar (lookup_internalvar ("_"),
        !           268:                   value_from_long (builtin_type_int, addr));
        !           269: }
        !           270: 
        !           271: /* Print address ADDR symbolically on STREAM.
        !           272:    First print it as a number.  Then perhaps print
        !           273:    <SYMBOL + OFFSET> after the number.  */
        !           274: 
        !           275: void
        !           276: print_address (addr, stream)
        !           277:      CORE_ADDR addr;
        !           278:      FILE *stream;
        !           279: {
        !           280:   register int i;
        !           281: 
        !           282:   fprintf (stream, "0x%x", addr);
        !           283: 
        !           284:   i = find_pc_misc_function (addr);
        !           285:   if (i >= 0)
        !           286:     if (misc_function_vector[i].address != addr)
        !           287:       fprintf (stream, " <%s+%d>",
        !           288:               misc_function_vector[i].name,
        !           289:               addr - misc_function_vector[i].address);
        !           290:     else
        !           291:       fprintf (stream, " <%s>", misc_function_vector[i].name);
        !           292: 
        !           293: }
        !           294: 
        !           295: /* Examine data at address ADDR in format FMT.
        !           296:    Fetch it from memory and print on stdout.  */
        !           297: 
        !           298: static void
        !           299: do_examine (fmt, addr)
        !           300:      struct format_data fmt;
        !           301:      CORE_ADDR addr;
        !           302: {
        !           303:   register char format = 0;
        !           304:   register char size;
        !           305:   register int count = 1;
        !           306:   struct type *val_type;
        !           307:   register int i;
        !           308:   register int maxelts;
        !           309: 
        !           310:   format = fmt.format;
        !           311:   size = fmt.size;
        !           312:   count = fmt.count;
        !           313:   next_address = addr;
        !           314: 
        !           315:   /* String or instruction format implies fetch single bytes
        !           316:      regardless of the specified size.  */
        !           317:   if (format == 's' || format == 'i')
        !           318:     size = 'b';
        !           319: 
        !           320:   if (size == 'b')
        !           321:     val_type = builtin_type_char;
        !           322:   else if (size == 'h')
        !           323:     val_type = builtin_type_short;
        !           324:   else if (size == 'w')
        !           325:     val_type = builtin_type_long;
        !           326:   else if (size == 'g')
        !           327:     val_type = builtin_type_double;
        !           328: 
        !           329:   maxelts = 8;
        !           330:   if (size == 'w')
        !           331:     maxelts = 4;
        !           332:   if (size == 'g')
        !           333:     maxelts = 2;
        !           334:   if (format == 's' || format == 'i')
        !           335:     maxelts = 1;
        !           336: 
        !           337:   /* Print as many objects as specified in COUNT, at most maxelts per line,
        !           338:      with the address of the next one at the start of each line.  */
        !           339: 
        !           340:   while (count > 0)
        !           341:     {
        !           342:       print_address (next_address, stdout);
        !           343:       fputc (':', stdout);
        !           344:       for (i = maxelts;
        !           345:           i > 0 && count > 0;
        !           346:           i--, count--)
        !           347:        {
        !           348:          fputc ('\t', stdout);
        !           349:          /* Note that this sets next_address for the next object.  */
        !           350:          last_examine_address = next_address;
        !           351:          last_examine_value = value_at (val_type, next_address);
        !           352:          print_formatted (last_examine_value, format, size);
        !           353:        }
        !           354:       fputc ('\n', stdout);
        !           355:       fflush (stdout);
        !           356:     }
        !           357: }
        !           358: 
        !           359: static void
        !           360: validate_format (fmt, cmdname)
        !           361:      struct format_data fmt;
        !           362:      char *cmdname;
        !           363: {
        !           364:   if (fmt.size != 0)
        !           365:     error ("Size letters are meaningless in \"%s\" command.", cmdname);
        !           366:   if (fmt.count != 1)
        !           367:     error ("Item count other than 1 is meaningless in \"%s\" command.",
        !           368:           cmdname);
        !           369:   if (fmt.format == 'i' || fmt.format == 's')
        !           370:     error ("Format letter \"%c\" is meaningless in \"%s\" command.",
        !           371:           fmt.format, cmdname);
        !           372: }
        !           373: 
        !           374: static void
        !           375: print_command (exp)
        !           376:      char *exp;
        !           377: {
        !           378:   struct expression *expr;
        !           379:   register struct cleanup *old_chain = 0;
        !           380:   register char format = 0;
        !           381:   register value val;
        !           382:   struct format_data fmt;
        !           383:   int histindex;
        !           384:   int cleanup = 0;
        !           385: 
        !           386:   if (exp && *exp == '/')
        !           387:     {
        !           388:       exp++;
        !           389:       fmt = decode_format (&exp, last_format, 0);
        !           390:       validate_format (fmt, "print");
        !           391:       last_format = format = fmt.format;
        !           392:     }
        !           393: 
        !           394:   if (exp && *exp)
        !           395:     {
        !           396:       expr = parse_c_expression (exp);
        !           397:       old_chain = make_cleanup (free_current_contents, &expr);
        !           398:       cleanup = 1;
        !           399:       val = evaluate_expression (expr);
        !           400:     }
        !           401:   else
        !           402:     val = access_value_history (0);
        !           403: 
        !           404:   histindex = record_latest_value (val);
        !           405:   printf ("$%d = ", histindex);
        !           406: 
        !           407:   print_formatted (val, format, fmt.size);
        !           408:   printf ("\n");
        !           409: 
        !           410:   if (cleanup)
        !           411:     do_cleanups (old_chain);
        !           412: }
        !           413: 
        !           414: static void
        !           415: output_command (exp)
        !           416:      char *exp;
        !           417: {
        !           418:   struct expression *expr;
        !           419:   register struct cleanup *old_chain;
        !           420:   register char format = 0;
        !           421:   register value val;
        !           422:   struct format_data fmt;
        !           423: 
        !           424:   if (exp && *exp == '/')
        !           425:     {
        !           426:       exp++;
        !           427:       fmt = decode_format (&exp, 0, 0);
        !           428:       validate_format (fmt, "print");
        !           429:       format = fmt.format;
        !           430:     }
        !           431: 
        !           432:   expr = parse_c_expression (exp);
        !           433:   old_chain = make_cleanup (free_current_contents, &expr);
        !           434: 
        !           435:   val = evaluate_expression (expr);
        !           436: 
        !           437:   print_formatted (val, format, fmt.size);
        !           438: 
        !           439:   do_cleanups (old_chain);
        !           440: }
        !           441: 
        !           442: static void
        !           443: set_command (exp)
        !           444:      char *exp;
        !           445: {
        !           446:   struct expression *expr = parse_c_expression (exp);
        !           447:   register struct cleanup *old_chain
        !           448:     = make_cleanup (free_current_contents, &expr);
        !           449:   evaluate_expression (expr);
        !           450:   do_cleanups (old_chain);
        !           451: }
        !           452: 
        !           453: static void
        !           454: address_info (exp)
        !           455:      char *exp;
        !           456: {
        !           457:   register struct symbol *sym;
        !           458:   register CORE_ADDR val;
        !           459: 
        !           460:   if (exp == 0)
        !           461:     error ("Argument required.");
        !           462: 
        !           463:   sym = lookup_symbol (exp, get_selected_block (), VAR_NAMESPACE);
        !           464:   if (sym == 0)
        !           465:     {
        !           466:       register int i;
        !           467: 
        !           468:       for (i = 0; i < misc_function_count; i++)
        !           469:        if (!strcmp (misc_function_vector[i].name, exp))
        !           470:          break;
        !           471: 
        !           472:       if (i < misc_function_count)
        !           473:        printf ("Symbol \"%s\" is at 0x%x in a file compiled without -g.\n",
        !           474:                exp, misc_function_vector[i].address);
        !           475:       else
        !           476:        error ("No symbol \"%s\" in current context.", exp);
        !           477:       return;
        !           478:     }
        !           479: 
        !           480:   printf ("Symbol \"%s\" is ", SYMBOL_NAME (sym));
        !           481:   val = SYMBOL_VALUE (sym);
        !           482: 
        !           483:   switch (SYMBOL_CLASS (sym))
        !           484:     {
        !           485:     case LOC_CONST:
        !           486:     case LOC_CONST_BYTES:
        !           487:       printf ("constant");
        !           488:       break;
        !           489: 
        !           490:     case LOC_LABEL:
        !           491:       printf ("a label at address 0x%x", val);
        !           492:       break;
        !           493: 
        !           494:     case LOC_REGISTER:
        !           495:       printf ("a variable in register %s", reg_names[val]);
        !           496:       break;
        !           497: 
        !           498:     case LOC_STATIC:
        !           499:       printf ("static at address 0x%x", val);
        !           500:       break;
        !           501: 
        !           502:     case LOC_ARG:
        !           503:       printf ("an argument at offset %d", val);
        !           504:       break;
        !           505: 
        !           506:     case LOC_LOCAL:
        !           507:       printf ("a local variable at frame offset %d", val);
        !           508:       break;
        !           509: 
        !           510:     case LOC_TYPEDEF:
        !           511:       printf ("a typedef");
        !           512:       break;
        !           513: 
        !           514:     case LOC_BLOCK:
        !           515:       printf ("a function at address 0x%x",
        !           516:              BLOCK_START (SYMBOL_BLOCK_VALUE (sym)));
        !           517:       break;
        !           518:     }
        !           519:   printf (".\n");
        !           520: }
        !           521: 
        !           522: static void
        !           523: x_command (exp, from_tty)
        !           524:      char *exp;
        !           525:      int from_tty;
        !           526: {
        !           527:   struct expression *expr;
        !           528:   struct format_data fmt;
        !           529:   struct cleanup *old_chain;
        !           530: 
        !           531:   fmt.format = last_format;
        !           532:   fmt.size = last_size;
        !           533:   fmt.count = 1;
        !           534: 
        !           535:   if (exp && *exp == '/')
        !           536:     {
        !           537:       exp++;
        !           538:       fmt = decode_format (&exp, last_format, last_size);
        !           539:       last_size = fmt.size;
        !           540:       last_format = fmt.format;
        !           541:     }
        !           542: 
        !           543:   /* If we have an expression, evaluate it and use it as the address.  */
        !           544: 
        !           545:   if (exp != 0 && *exp != 0)
        !           546:     {
        !           547:       expr = parse_c_expression (exp);
        !           548:       /* Cause expression not to be there any more
        !           549:         if this command is repeated with Newline.
        !           550:         But don't clobber a user-defined command's definition.  */
        !           551:       if (from_tty)
        !           552:        *exp = 0;
        !           553:       old_chain = make_cleanup (free_current_contents, &expr);
        !           554:       next_address = value_as_long (evaluate_expression (expr));
        !           555:       do_cleanups (old_chain);
        !           556:     }
        !           557: 
        !           558:   do_examine (fmt, next_address);
        !           559: 
        !           560:   /* Make last address examined available to the user as $_.  */
        !           561:   set_internalvar (lookup_internalvar ("_"),
        !           562:                   value_from_long (builtin_type_int, last_examine_address));
        !           563: 
        !           564:   /* Make contents of last address examined available to the user as $__.  */
        !           565:   set_internalvar (lookup_internalvar ("__"), last_examine_value);
        !           566: }
        !           567: 
        !           568: /* Commands for printing types of things.  */
        !           569: 
        !           570: static void
        !           571: whatis_command (exp)
        !           572:      char *exp;
        !           573: {
        !           574:   struct expression *expr;
        !           575:   register value val;
        !           576:   register struct cleanup *old_chain;
        !           577: 
        !           578:   if (exp)
        !           579:     {
        !           580:       expr = parse_c_expression (exp);
        !           581:       old_chain = make_cleanup (free_current_contents, &expr);
        !           582:       val = evaluate_type (expr);
        !           583:     }
        !           584:   else
        !           585:     val = access_value_history (0);
        !           586: 
        !           587:   printf ("type = ");
        !           588:   type_print (VALUE_TYPE (val), "", stdout, 1);
        !           589:   printf ("\n");
        !           590: 
        !           591:   if (exp)
        !           592:     do_cleanups (old_chain);
        !           593: }
        !           594: 
        !           595: static void
        !           596: ptype_command (typename)
        !           597:      char *typename;
        !           598: {
        !           599:   register char *p = typename;
        !           600:   register int len;
        !           601:   extern struct block *get_current_block ();
        !           602:   register struct block *b
        !           603:     = (have_inferior_p () || have_core_file_p ()) ? get_current_block () : 0;
        !           604:   register struct type *type;
        !           605: 
        !           606:   if (typename == 0)
        !           607:     error_no_arg ("type name");
        !           608: 
        !           609:   while (*p && *p != ' ' && *p != '\t') p++;
        !           610:   len = p - typename;
        !           611:   while (*p == ' ' || *p == '\t') p++;
        !           612: 
        !           613:   if (len == 6 && !strncmp (typename, "struct", 6))
        !           614:     type = lookup_struct (p, b);
        !           615:   else if (len == 5 && !strncmp (typename, "union", 5))
        !           616:     type = lookup_union (p, b);
        !           617:   else if (len == 4 && !strncmp (typename, "enum", 4))
        !           618:     type = lookup_enum (p, b);
        !           619:   else
        !           620:     {
        !           621:       type = lookup_typename (typename, b, 1);
        !           622:       if (type == 0)
        !           623:        {
        !           624:          register struct symbol *sym
        !           625:            = lookup_symbol (typename, b, STRUCT_NAMESPACE);
        !           626:          if (sym == 0)
        !           627:            error ("No type named %s.", typename);
        !           628:          printf ("No type named %s, but there is a ",
        !           629:                  typename);
        !           630:          switch (TYPE_CODE (SYMBOL_TYPE (sym)))
        !           631:            {
        !           632:            case TYPE_CODE_STRUCT:
        !           633:              printf ("struct");
        !           634:              break;
        !           635: 
        !           636:            case TYPE_CODE_UNION:
        !           637:              printf ("union");
        !           638:              break;
        !           639: 
        !           640:            case TYPE_CODE_ENUM:
        !           641:              printf ("enum");
        !           642:            }
        !           643:          printf (" %s.  Type \"help ptype\".\n", typename);
        !           644:          type = SYMBOL_TYPE (sym);
        !           645:        }
        !           646:     }
        !           647: 
        !           648:   type_print (type, "", stdout, 1);
        !           649:   printf ("\n");
        !           650: }
        !           651: 
        !           652: struct display
        !           653: {
        !           654:   /* Chain link to next auto-display item.  */
        !           655:   struct display *next;
        !           656:   /* Expression to be evaluated and displayed.  */
        !           657:   struct expression *exp;
        !           658:   /* Item number of this auto-display item.  */
        !           659:   int number;
        !           660:   /* Display format specified.  */
        !           661:   struct format_data format;
        !           662:   /* Block in which expression is to be evaluated.  */
        !           663:   struct block *block;
        !           664: };
        !           665: 
        !           666: /* Chain of expressions whose values should be displayed
        !           667:    automatically each time the program stops.  */
        !           668: 
        !           669: static struct display *display_chain;
        !           670: 
        !           671: static int display_number;
        !           672: 
        !           673: /* Add an expression to the auto-display chain.
        !           674:    Specify the expression.  */
        !           675: 
        !           676: static void
        !           677: display_command (exp, from_tty)
        !           678:      char *exp;
        !           679:      int from_tty;
        !           680: {
        !           681:   struct format_data fmt;
        !           682:   register struct expression *expr;
        !           683:   register struct display *new;
        !           684: 
        !           685:   if (exp == 0)
        !           686:     {
        !           687:       do_displays ();
        !           688:       return;
        !           689:     }
        !           690: 
        !           691:   if (*exp == '/')
        !           692:     {
        !           693:       exp++;
        !           694:       fmt = decode_format (&exp, 0, 0);
        !           695:       if (fmt.size && fmt.format == 0)
        !           696:        fmt.format = 'x';
        !           697:       if (fmt.format == 'i' || fmt.format == 's')
        !           698:        fmt.size = 'b';
        !           699:     }
        !           700:   else
        !           701:     {
        !           702:       fmt.format = 0;
        !           703:       fmt.size = 0;
        !           704:       fmt.count = 0;
        !           705:     }
        !           706: 
        !           707:   expr = parse_c_expression (exp);
        !           708: 
        !           709:   new = (struct display *) xmalloc (sizeof (struct display));
        !           710: 
        !           711:   new->exp = expr;
        !           712:   new->next = display_chain;
        !           713:   new->number = ++display_number;
        !           714:   new->format = fmt;
        !           715:   display_chain = new;
        !           716: 
        !           717:   if (from_tty)
        !           718:     do_one_display (new);
        !           719: 
        !           720:   dont_repeat ();
        !           721: }
        !           722: 
        !           723: static void
        !           724: free_display (d)
        !           725:      struct display *d;
        !           726: {
        !           727:   free (d->exp);
        !           728:   free (d);
        !           729: }
        !           730: 
        !           731: /* Clear out the display_chain.
        !           732:    Done when new symtabs are loaded, since this invalidates
        !           733:    the types stored in many expressions.  */
        !           734: 
        !           735: void
        !           736: clear_displays ()
        !           737: {
        !           738:   register struct display *d;
        !           739: 
        !           740:   while (d = display_chain)
        !           741:     {
        !           742:       free (d->exp);
        !           743:       display_chain = d->next;
        !           744:       free (d);
        !           745:     }
        !           746: }
        !           747: 
        !           748: /* Delete the auto-display number NUM.  */
        !           749: 
        !           750: void
        !           751: delete_display (num)
        !           752:      int num;
        !           753: {
        !           754:   register struct display *d1, *d;
        !           755: 
        !           756:   if (!display_chain)
        !           757:     error ("No display number %d.", num);
        !           758: 
        !           759:   if (display_chain->number == num)
        !           760:     {
        !           761:       d1 = display_chain;
        !           762:       display_chain = d1->next;
        !           763:       free_display (d1);
        !           764:     }
        !           765:   else
        !           766:     for (d = display_chain; ; d = d->next)
        !           767:       {
        !           768:        if (d->next == 0)
        !           769:          error ("No display number %d.", num);
        !           770:        if (d->next->number == num)
        !           771:          {
        !           772:            d1 = d->next;
        !           773:            d->next = d1->next;
        !           774:            free_display (d1);
        !           775:            break;
        !           776:          }
        !           777:       }
        !           778: }
        !           779: 
        !           780: /* Delete some values from the auto-display chain.
        !           781:    Specify the element numbers.  */
        !           782: 
        !           783: static void
        !           784: undisplay_command (args)
        !           785:      char *args;
        !           786: {
        !           787:   register char *p = args;
        !           788:   register char *p1;
        !           789:   register int num;
        !           790:   register struct display *d, *d1;
        !           791: 
        !           792:   if (args == 0)
        !           793:     {
        !           794:       if (query ("Delete all auto-display expressions? "))
        !           795:        clear_displays ();
        !           796:       dont_repeat ();
        !           797:       return;
        !           798:     }
        !           799: 
        !           800:   while (*p)
        !           801:     {
        !           802:       p1 = p;
        !           803:       while (*p1 >= '0' && *p1 <= '9') p1++;
        !           804:       if (*p1 && *p1 != ' ' && *p1 != '\t')
        !           805:        error ("Arguments must be display numbers.");
        !           806: 
        !           807:       num = atoi (p);
        !           808: 
        !           809:       delete_display (num);
        !           810: 
        !           811:       p = p1;
        !           812:       while (*p == ' ' || *p == '\t') p++;
        !           813:     }
        !           814:   dont_repeat ();
        !           815: }
        !           816: 
        !           817: /* Display a single auto-display.  */
        !           818: 
        !           819: static void
        !           820: do_one_display (d)
        !           821:      struct display *d;
        !           822: {
        !           823:   current_display_number = d->number;
        !           824: 
        !           825:   printf ("%d: ", d->number);
        !           826:   if (d->format.size)
        !           827:     {
        !           828:       printf ("x/");
        !           829:       if (d->format.count != 1)
        !           830:        printf ("%d", d->format.count);
        !           831:       printf ("%c", d->format.format);
        !           832:       if (d->format.format != 'i' && d->format.format != 's')
        !           833:        printf ("%c", d->format.size);
        !           834:       printf (" ");
        !           835:       print_expression (d->exp, stdout);
        !           836:       if (d->format.count != 1)
        !           837:        printf ("\n");
        !           838:       else
        !           839:        printf ("  ");
        !           840:       do_examine (d->format,
        !           841:                  value_as_long (evaluate_expression (d->exp)));
        !           842:     }
        !           843:   else
        !           844:     {
        !           845:       if (d->format.format)
        !           846:        printf ("/%c ", d->format.format);
        !           847:       print_expression (d->exp, stdout);
        !           848:       printf (" = ");
        !           849:       print_formatted (evaluate_expression (d->exp),
        !           850:                       d->format.format, d->format.size);
        !           851:       printf ("\n");
        !           852:     }
        !           853: 
        !           854:   fflush (stdout);
        !           855:   current_display_number = -1;
        !           856: }
        !           857: 
        !           858: /* Display all of the values on the auto-display chain.  */
        !           859: 
        !           860: void
        !           861: do_displays ()
        !           862: {
        !           863:   register struct display *d;
        !           864: 
        !           865:   for (d = display_chain; d; d = d->next)
        !           866:     do_one_display (d);
        !           867: }
        !           868: 
        !           869: /* Delete the auto-display which we were in the process of displaying.
        !           870:    This is done when there is an error or a signal.  */
        !           871: 
        !           872: void
        !           873: delete_current_display ()
        !           874: {
        !           875:   if (current_display_number >= 0)
        !           876:     {
        !           877:       delete_display (current_display_number);
        !           878:       fprintf (stderr, "Deleting display %d to avoid infinite recursion.\n",
        !           879:               current_display_number);
        !           880:     }
        !           881:   current_display_number = -1;
        !           882: }
        !           883: 
        !           884: static void
        !           885: display_info ()
        !           886: {
        !           887:   register struct display *d;
        !           888: 
        !           889:   if (!display_chain)
        !           890:     printf ("There are no auto-display expressions now.\n");
        !           891:   else
        !           892:     printf ("Auto-display expressions now in effect:\n");
        !           893:   for (d = display_chain; d; d = d->next)
        !           894:     {
        !           895:       printf ("%d: ", d->number);
        !           896:       if (d->format.size)
        !           897:        printf ("/%d%c%c ", d->format.count, d->format.size,
        !           898:                d->format.format);
        !           899:       else if (d->format.format)
        !           900:        printf ("/%c ", d->format.format);
        !           901:       print_expression (d->exp, stdout);
        !           902:       printf ("\n");
        !           903:       fflush (stdout);
        !           904:     }
        !           905: }
        !           906: 
        !           907: /* Print the value in stack frame FRAME of a variable
        !           908:    specified by a struct symbol.  */
        !           909: 
        !           910: void
        !           911: print_variable_value (var, frame, stream)
        !           912:      struct symbol *var;
        !           913:      CORE_ADDR frame;
        !           914:      FILE *stream;
        !           915: {
        !           916:   value val = read_var_value (var, frame);
        !           917:   value_print (val, stream, 0);
        !           918: }
        !           919: 
        !           920: /* Print the arguments of a stack frame, given the function FUNC
        !           921:    running in that frame (as a symbol), the address of the arglist,
        !           922:    and the number of args according to the stack frame (or -1 if unknown).  */
        !           923: 
        !           924: static void print_frame_nameless_args ();
        !           925: 
        !           926: print_frame_args (func, addr, num, stream)
        !           927:      struct symbol *func;
        !           928:      register CORE_ADDR addr;
        !           929:      int num;
        !           930:      FILE *stream;
        !           931: {
        !           932:   struct block *b;
        !           933:   int nsyms = 0;
        !           934:   int first = 1;
        !           935:   register int i;
        !           936:   register int last_offset = FRAME_ARGS_SKIP;
        !           937:   register struct symbol *sym, *nextsym;
        !           938:   register value val;
        !           939: 
        !           940:   if (func)
        !           941:     {
        !           942:       b = SYMBOL_BLOCK_VALUE (func);
        !           943:       nsyms = BLOCK_NSYMS (b);
        !           944:     }
        !           945: 
        !           946:   while (1)
        !           947:     {
        !           948:       /* Find first arg that is not before LAST_OFFSET.  */
        !           949:       nextsym = 0;
        !           950:       for (i = 0; i < nsyms; i++)
        !           951:        {
        !           952:          QUIT;
        !           953:          sym = BLOCK_SYM (b, i);
        !           954:          if (SYMBOL_CLASS (sym) == LOC_ARG
        !           955:              && SYMBOL_VALUE (sym) >= last_offset
        !           956:              && (nextsym == 0
        !           957:                  || SYMBOL_VALUE (sym) < SYMBOL_VALUE (nextsym)))
        !           958:            nextsym = sym;
        !           959:        }
        !           960:       if (nextsym == 0)
        !           961:        break;
        !           962:       sym = nextsym;
        !           963:       /* Print any nameless args between the last arg printed
        !           964:         and the next arg.  */
        !           965:       if (last_offset != (SYMBOL_VALUE (sym) / sizeof (int)) * sizeof (int))
        !           966:        {
        !           967:          print_frame_nameless_args (addr, last_offset, SYMBOL_VALUE (sym),
        !           968:                                     stream);
        !           969:          first = 0;
        !           970:        }
        !           971:       /* Print the next arg.  */
        !           972:       val = value_at (SYMBOL_TYPE (sym), addr + SYMBOL_VALUE (sym));
        !           973:       if (! first)
        !           974:        fprintf (stream, ", ");
        !           975:       fprintf (stream, "%s=", SYMBOL_NAME (sym));
        !           976:       value_print (val, stream, 0);
        !           977:       first = 0;
        !           978:       last_offset = SYMBOL_VALUE (sym) + TYPE_LENGTH (SYMBOL_TYPE (sym));
        !           979:       /* Round up address of next arg to multiple of size of int.  */
        !           980:       last_offset
        !           981:        = ((last_offset + sizeof (int) - 1) / sizeof (int)) * sizeof (int);
        !           982:     }
        !           983:   if (num >= 0 && num * sizeof (int) + FRAME_ARGS_SKIP > last_offset)
        !           984:     print_frame_nameless_args (addr, last_offset,
        !           985:                               num * sizeof (int) + FRAME_ARGS_SKIP, stream);
        !           986: }
        !           987: 
        !           988: static void
        !           989: print_frame_nameless_args (argsaddr, start, end, stream)
        !           990:      CORE_ADDR argsaddr;
        !           991:      int start;
        !           992:      int end;
        !           993:      FILE *stream;
        !           994: {
        !           995:   while (start < end)
        !           996:     {
        !           997:       QUIT;
        !           998:       if (start != FRAME_ARGS_SKIP)
        !           999:        fprintf (stream, ", ");
        !          1000:       fprintf (stream, "%d",
        !          1001:               read_memory_integer (argsaddr + start, sizeof (int)));
        !          1002:       start += sizeof (int);
        !          1003:     }
        !          1004: }
        !          1005: 
        !          1006: static void
        !          1007: printf_command (arg)
        !          1008:      char *arg;
        !          1009: {
        !          1010:   register char *f;
        !          1011:   register char *s = arg;
        !          1012:   char *string;
        !          1013:   value *val_args;
        !          1014:   int nargs = 0;
        !          1015:   int allocated_args = 20;
        !          1016:   char *arg_bytes;
        !          1017:   char *argclass;
        !          1018:   int i;
        !          1019:   int argindex;
        !          1020:   int nargs_wanted;
        !          1021: 
        !          1022:   val_args = (value *) xmalloc (allocated_args * sizeof (value));
        !          1023: 
        !          1024:   if (s == 0)
        !          1025:     error_no_arg ("format-control string and values to print");
        !          1026: 
        !          1027:   /* Skip white space before format string */
        !          1028:   while (*s == ' ' || *s == '\t') s++;
        !          1029: 
        !          1030:   /* A format string should follow, enveloped in double quotes */
        !          1031:   if (*s++ != '"')
        !          1032:     error ("Bad format string, missing '\"'.");
        !          1033: 
        !          1034:   /* Parse the format-control string and copy it into the string STRING,
        !          1035:      processing some kinds of escape sequence.  */
        !          1036: 
        !          1037:   f = string = (char *) alloca (strlen (s) + 1);
        !          1038:   while (*s != '"')
        !          1039:     {
        !          1040:       int c = *s++;
        !          1041:       switch (c)
        !          1042:        {
        !          1043:        case '\0':
        !          1044:          error ("Bad format string, non-terminated '\"'.");
        !          1045:          /* doesn't return */
        !          1046: 
        !          1047:        case '\\':
        !          1048:          switch (c = *s++)
        !          1049:            {
        !          1050:            case '\\':
        !          1051:              *f++ = '\\';
        !          1052:              break;
        !          1053:            case 'n':
        !          1054:              *f++ = '\n';
        !          1055:              break;
        !          1056:            case 't':
        !          1057:              *f++ = '\t';
        !          1058:              break;
        !          1059:            case 'r':
        !          1060:              *f++ = '\r';
        !          1061:              break;
        !          1062:            case '"':
        !          1063:              *f++ = '"';
        !          1064:              break;
        !          1065:            default:
        !          1066:              /* ??? TODO: handle other escape sequences */
        !          1067:              error ("Unrecognized \\ escape character in format string.");
        !          1068:            }
        !          1069:          break;
        !          1070: 
        !          1071:        default:
        !          1072:          *f++ = c;
        !          1073:        }
        !          1074:     }
        !          1075: 
        !          1076:   /* Skip over " and following space and comma.  */
        !          1077:   s++;
        !          1078:   *f++ = '\0';
        !          1079:   while (*s == ' ' || *s == '\t') s++;
        !          1080: 
        !          1081:   if (*s != ',' && *s != 0)
        !          1082:     error ("Invalid argument syntax");
        !          1083: 
        !          1084:   if (*s == ',') s++;
        !          1085:   while (*s == ' ' || *s == '\t') s++;
        !          1086: 
        !          1087:   /* Now scan the string for %-specs and see what kinds of args they want.
        !          1088:      argclass[I] is set to 1 if the Ith arg should be a string.  */
        !          1089: 
        !          1090:   argclass = (char *) alloca (strlen (s));
        !          1091:   nargs_wanted = 0;
        !          1092:   f = string;
        !          1093:   while (*f)
        !          1094:     if (*f++ == '%')
        !          1095:       {
        !          1096:        while (index ("0123456789.hlL-+ #", *f)) f++;
        !          1097:        if (*f == 's')
        !          1098:          argclass[nargs_wanted++] = 1;
        !          1099:        else if (*f != '%')
        !          1100:          argclass[nargs_wanted++] = 0;
        !          1101:        f++;
        !          1102:       }
        !          1103: 
        !          1104:   /* Now, parse all arguments and evaluate them.
        !          1105:      Store the VALUEs in VAL_ARGS.  */
        !          1106: 
        !          1107:   while (*s != '\0')
        !          1108:     {
        !          1109:       char *s1;
        !          1110:       if (nargs == allocated_args)
        !          1111:        val_args = (value *) xrealloc (val_args,
        !          1112:                                       (allocated_args *= 2)
        !          1113:                                       * sizeof (value));
        !          1114:       s1 = s;
        !          1115:       val_args[nargs++] = parse_to_comma_and_eval (&s1);
        !          1116:       s = s1;
        !          1117:       if (*s == ',')
        !          1118:        s++;
        !          1119:     }
        !          1120: 
        !          1121:   if (nargs != nargs_wanted)
        !          1122:     error ("Wrong number of arguments for specified format-string");
        !          1123: 
        !          1124:   /* Now lay out an argument-list containing the arguments
        !          1125:      as doubles, integers and C pointers.  */
        !          1126: 
        !          1127:   arg_bytes = (char *) alloca (sizeof (double) * nargs);
        !          1128:   argindex = 0;
        !          1129:   for (i = 0; i < nargs; i++)
        !          1130:     {
        !          1131:       if (argclass[i])
        !          1132:        {
        !          1133:          char *str;
        !          1134:          int tem, j;
        !          1135:          tem = value_as_long (val_args[i]);
        !          1136: 
        !          1137:          /* This is a %s argument.  Find the length of the string.  */
        !          1138:          for (j = 0; ; j++)
        !          1139:            {
        !          1140:              char c;
        !          1141:              QUIT;
        !          1142:              read_memory (tem + j, &c, 1);
        !          1143:              if (c == 0)
        !          1144:                break;
        !          1145:            }
        !          1146: 
        !          1147:          /* Copy the string contents into a string inside GDB.  */
        !          1148:          str = (char *) alloca (j + 1);
        !          1149:          read_memory (tem, str, j);
        !          1150:          str[j] = 0;
        !          1151: 
        !          1152:          /* Pass address of internal copy as the arg to vprintf.  */
        !          1153:          *((int *) &arg_bytes[argindex]) = (int) str;
        !          1154:          argindex += sizeof (int);
        !          1155:        }
        !          1156:       else if (VALUE_TYPE (val_args[i])->code == TYPE_CODE_FLT)
        !          1157:        {
        !          1158:          *((double *) &arg_bytes[argindex]) = value_as_double (val_args[i]);
        !          1159:          argindex += sizeof (double);
        !          1160:        }
        !          1161:       else
        !          1162:        {
        !          1163:          *((int *) &arg_bytes[argindex]) = value_as_long (val_args[i]);
        !          1164:          argindex += sizeof (int);
        !          1165:        }
        !          1166:     }
        !          1167: 
        !          1168:   vprintf (string, arg_bytes);
        !          1169: }
        !          1170: 
        !          1171: static
        !          1172: initialize ()
        !          1173: {
        !          1174:   current_display_number = -1;
        !          1175: 
        !          1176:   add_info ("address", address_info,
        !          1177:           "Describe where variable VAR is stored.");
        !          1178: 
        !          1179:   add_com ("x", class_vars, x_command,
        !          1180:           "Examine memory: x/FMT ADDRESS.\n\
        !          1181: ADDRESS is an expression for the memory address to examine.\n\
        !          1182: FMT is a repeat count followed by a format letter and a size letter.\n\
        !          1183: Format letters are o(octal), x(hex), d(decimal), u(unsigned decimal),\n\
        !          1184:  f(float), a(address), i(instruction), c(char) and s(string).\n\
        !          1185: Size letters are b(byte), h(halfword), w(word), g(giant, 8 bytes).\n\
        !          1186:   g is meaningful only with f, for type double.\n\
        !          1187: The specified number of objects of the specified size are printed\n\
        !          1188: according to the format.\n\n\
        !          1189: Defaults for format and size letters are those previously used.\n\
        !          1190: Default count is 1.  Default address is following last thing printed\n\
        !          1191: with this command or \"print\".");
        !          1192: 
        !          1193:   add_com ("ptype", class_vars, ptype_command,
        !          1194:           "Print definition of type TYPE.\n\
        !          1195: Argument may be a type name defined by typedef, or \"struct STRUCTNAME\"\n\
        !          1196: or \"union UNIONNAME\" or \"enum ENUMNAME\".\n\
        !          1197: The selected stack frame's lexical context is used to look up the name.");
        !          1198: 
        !          1199:   add_com ("whatis", class_vars, whatis_command,
        !          1200:           "Print data type of expression EXP.");
        !          1201: 
        !          1202:   add_info ("display", display_info,
        !          1203:            "Expressions to display when program stops, with code numbers.");
        !          1204:   add_com ("undisplay", class_vars, undisplay_command,
        !          1205:           "Cancel some expressions to be displayed whenever program stops.\n\
        !          1206: Arguments are the code numbers of the expressions to stop displaying.\n\
        !          1207: No argument means cancel all automatic-display expressions.\n\
        !          1208: Do \"info display\" to see current list of code numbers.");
        !          1209:   add_com ("display", class_vars, display_command,
        !          1210:           "Print value of expression EXP each time the program stops.\n\
        !          1211: /FMT may be used before EXP as in the \"print\" command.\n\
        !          1212: /FMT \"i\" or \"s\" or including a size-letter is allowed,\n\
        !          1213: as in the \"x\" command, and then EXP is used to get the address to examine\n\
        !          1214: and examining is done as in the \"x\" command.\n\n\
        !          1215: With no argument, display all currently requested auto-display expressions.\n\
        !          1216: Use \"undisplay\" to cancel display requests previously made.");
        !          1217: 
        !          1218:   add_com ("printf", class_vars, printf_command,
        !          1219:        "printf \"printf format string\", arg1, arg2, arg3, ..., argn\n\
        !          1220: This is useful for formatted output in user-defined commands.");
        !          1221:   add_com ("output", class_vars, output_command,
        !          1222:           "Like \"print\" but don't put in value history and don't print newline.\n\
        !          1223: This is useful in user-defined commands.");
        !          1224: 
        !          1225:   add_com ("set", class_vars, set_command,
        !          1226:           "Perform an assignment VAR = EXP.  You must type the \"=\".\n\
        !          1227: VAR may be a debugger \"convenience\" variables (names starting with $),\n\
        !          1228: a register (a few standard names starting with $), or an actual variable\n\
        !          1229: in the program being debugger.  EXP is any expression.");
        !          1230: 
        !          1231:   add_com ("print", class_vars, print_command,
        !          1232:           concat ("Print value of expression EXP.\n\
        !          1233: Variables accessible are those of the lexical environment of the selected\n\
        !          1234: stack frame, plus all those whose scope is global or an entire file.\n\
        !          1235: \n\
        !          1236: $NUM gets previous value number NUM.  $ and $$ are the last two values.\n\
        !          1237: $$NUM refers to NUM'th value back from the last one.\n\
        !          1238: Names starting with $ refer to registers (with the values they would have\n\
        !          1239: if the program were to return to the stack frame now selected, restoring\n\
        !          1240: all registers saved by frames farther in) or else to debugger\n\
        !          1241: \"convenience\" variables (any such name not a known register).\n\
        !          1242: Use assignment expressions to give values to convenience variables.\n",
        !          1243:                   "\n\
        !          1244: \{TYPE}ADREXP refers to a datum of data type TYPE, located at address ADREXP.\n\
        !          1245: @ is a binary operator for treating consecutive data objects\n\
        !          1246: anywhere in memory as an array.  FOO@NUM gives an array whose first\n\
        !          1247: element is FOO, whose second element is stored in the space following\n\
        !          1248: where FOO is stored, etc.  FOO must be an expression whose value\n\
        !          1249: resides in memory.\n",
        !          1250:                   "\n\
        !          1251: EXP may be preceded with /FMT, where FMT is a format letter\n\
        !          1252: but no count or size letter (see \"x\" command)."));
        !          1253:   add_com_alias ("p", "print", class_vars, 1);
        !          1254: }
        !          1255: 
        !          1256: END_FILE

unix.superglobalmegacorp.com

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