Annotation of gdb/valprint.c, revision 1.1

1.1     ! root        1: /* Print values for GNU debugger gdb.
        !             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 "defs.h"
        !            23: #include "initialize.h"
        !            24: #include "symtab.h"
        !            25: #include "value.h"
        !            26: 
        !            27: /* Maximum number of chars to print for a string pointer value
        !            28:    or vector contents.  */
        !            29: 
        !            30: static int print_max;
        !            31: 
        !            32: static void type_print_varspec_suffix ();
        !            33: static void type_print_varspec_prefix ();
        !            34: static void type_print_base ();
        !            35: 
        !            36: START_FILE
        !            37: 
        !            38: char **unsigned_type_table;
        !            39: char **signed_type_table;
        !            40: char **float_type_table;
        !            41: 
        !            42: /* Print the value VAL in C-ish syntax on stream STREAM.
        !            43:    If the object printed is a string pointer, returns
        !            44:    the number of string bytes printed.  */
        !            45: 
        !            46: value_print (val, stream)
        !            47:      value val;
        !            48:      FILE *stream;
        !            49: {
        !            50:   register int i, n, typelen;
        !            51: 
        !            52:   /* A "repeated" value really contains several values in a row.
        !            53:      They are made by the @ operator.
        !            54:      Print such values as if they were arrays.  */
        !            55: 
        !            56:   if (VALUE_REPEATED (val))
        !            57:     {
        !            58:       n = VALUE_REPETITIONS (val);
        !            59:       typelen = TYPE_LENGTH (VALUE_TYPE (val));
        !            60:       fputc ('{', stream);
        !            61:       /* Print arrays of characters using string syntax.  */
        !            62:       if (VALUE_TYPE (val) == builtin_type_char
        !            63:          || VALUE_TYPE (val) == builtin_type_unsigned_char)
        !            64:        {
        !            65:          fputc ('"', stream);
        !            66:          for (i = 0; i < n && i < print_max; i++)
        !            67:            {
        !            68:              QUIT;
        !            69:              printchar (VALUE_CONTENTS (val)[i], stream);
        !            70:            }
        !            71:          if (i < n)
        !            72:            fprintf (stream, "...");
        !            73:          fputc ('"', stream);
        !            74:        }
        !            75:       else
        !            76:        {
        !            77:          for (i = 0; i < n && i < print_max; i++)
        !            78:            {
        !            79:              if (i)
        !            80:                fprintf (stream, ", ");
        !            81:              val_print (VALUE_TYPE (val), VALUE_CONTENTS (val) + typelen * i,
        !            82:                         VALUE_ADDRESS (val) + typelen * i, stream);
        !            83:            }
        !            84:          if (i < n)
        !            85:            fprintf (stream, "...");
        !            86:        }
        !            87:       fputc ('}', stream);
        !            88:     }
        !            89:   else
        !            90:     {
        !            91:       /* A simple (nonrepeated) value */
        !            92:       /* If it is a pointer, indicate what it points to.  */
        !            93:       if (TYPE_CODE (VALUE_TYPE (val)) == TYPE_CODE_PTR)
        !            94:        {
        !            95:          fprintf (stream, "(");
        !            96:          type_print (VALUE_TYPE (val), "", stream, -1);
        !            97:          fprintf (stream, ") ");
        !            98:        }
        !            99:       return val_print (VALUE_TYPE (val), VALUE_CONTENTS (val),
        !           100:                        VALUE_ADDRESS (val), stream);
        !           101:     }
        !           102: }
        !           103: 
        !           104: /* Print on STREAM data stored in debugger at address VALADDR
        !           105:    according to the format of type TYPE.
        !           106:    ADDRESS is the location in the inferior that the data
        !           107:    is supposed to have come from.
        !           108: 
        !           109:    If the data are a string pointer, returns the number of
        !           110:    sting characters printed.  */
        !           111: 
        !           112: int
        !           113: val_print (type, valaddr, address, stream)
        !           114:      struct type *type;
        !           115:      char *valaddr;
        !           116:      CORE_ADDR address;
        !           117:      FILE *stream;
        !           118: {
        !           119:   register int i;
        !           120:   int len;
        !           121:   struct type *elttype;
        !           122:   int eltlen;
        !           123:   int val;
        !           124:   unsigned char c;
        !           125: 
        !           126:   QUIT;
        !           127: 
        !           128:   switch (TYPE_CODE (type))
        !           129:     {
        !           130:     case TYPE_CODE_ARRAY:
        !           131:       if (TYPE_LENGTH (type) >= 0)
        !           132:        {
        !           133:          elttype = TYPE_TARGET_TYPE (type);
        !           134:          eltlen = TYPE_LENGTH (elttype);
        !           135:          len = TYPE_LENGTH (type) / eltlen;
        !           136:          fprintf (stream, "{");
        !           137:          /* For an array of chars, print with string syntax.  */
        !           138:          if (elttype == builtin_type_char
        !           139:              || elttype == builtin_type_unsigned_char)
        !           140:            {
        !           141:              fputc ('"', stream);
        !           142:              for (i = 0; i < len && i < print_max; i++)
        !           143:                {
        !           144:                  QUIT;
        !           145:                  printchar (valaddr[i], stream);
        !           146:                }
        !           147:              if (i < len)
        !           148:                fprintf (stream, "...");
        !           149:              fputc ('"', stream);
        !           150:            }
        !           151:          else
        !           152:            {
        !           153:              for (i = 0; i < len && i < print_max; i++)
        !           154:                {
        !           155:                  if (i) fprintf (stream, ", ");
        !           156:                  val_print (elttype, valaddr + i * eltlen,
        !           157:                             0, stream);
        !           158:                }
        !           159:              if (i < len)
        !           160:                fprintf (stream, "...");
        !           161:            }
        !           162:          fprintf (stream, "}");
        !           163:          break;
        !           164:        }
        !           165:       /* Array of unspecified length: treat like pointer.  */
        !           166: 
        !           167:     case TYPE_CODE_PTR:
        !           168:       fprintf (stream, "0x%x", * (int *) valaddr);
        !           169:       /* For a pointer to char or unsigned char,
        !           170:         also print the string pointed to, unless pointer is null.  */
        !           171:       if ((TYPE_TARGET_TYPE (type) == builtin_type_char
        !           172:           || TYPE_TARGET_TYPE (type) == builtin_type_unsigned_char)
        !           173:          && unpack_long (type, valaddr) != 0)
        !           174:        {
        !           175:          fputc (' ', stream);
        !           176:          fputc ('"', stream);
        !           177:          for (i = 0; i < print_max; i++)
        !           178:            {
        !           179:              QUIT;
        !           180:              read_memory (unpack_long (type, valaddr) + i, &c, 1);
        !           181:              if (c == 0)
        !           182:                break;
        !           183:              printchar (c, stream);
        !           184:            }
        !           185:          fputc ('"', stream);
        !           186:          if (i == print_max)
        !           187:            fprintf (stream, "...");
        !           188:          fflush (stream);
        !           189:          /* Return number of characters printed, plus one for the
        !           190:             terminating null if we have "reached the end".  */
        !           191:          return i + (i != print_max);
        !           192:        }
        !           193:       break;
        !           194: 
        !           195:     case TYPE_CODE_STRUCT:
        !           196:     case TYPE_CODE_UNION:
        !           197:       fprintf (stream, "{");
        !           198:       len = TYPE_NFIELDS (type);
        !           199:       for (i = 0; i < len; i++)
        !           200:        {
        !           201:          if (i) fprintf (stream, ", ");
        !           202:          fprintf (stream, "%s = ", TYPE_FIELD_NAME (type, i));
        !           203:          if (TYPE_FIELD_PACKED (type, i))
        !           204:            {
        !           205:              val = unpack_field_as_long (type, valaddr, i);
        !           206:              val_print (TYPE_FIELD_TYPE (type, i), &val, 0, stream);
        !           207:            }
        !           208:          else
        !           209:            val_print (TYPE_FIELD_TYPE (type, i), 
        !           210:                       valaddr + TYPE_FIELD_BITPOS (type, i) / 8,
        !           211:                       0, stream);
        !           212:        }
        !           213:       fprintf (stream, "}");
        !           214:       break;
        !           215: 
        !           216:     case TYPE_CODE_ENUM:
        !           217:       len = TYPE_NFIELDS (type);
        !           218:       val = unpack_long (builtin_type_int, valaddr);
        !           219:       for (i = 0; i < len; i++)
        !           220:        {
        !           221:          QUIT;
        !           222:          if (val == TYPE_FIELD_VALUE (type, i))
        !           223:            break;
        !           224:        }
        !           225:       if (i < len)
        !           226:        fprintf (stream, "%s", TYPE_FIELD_NAME (type, i));
        !           227:       else
        !           228:        fprintf (stream, "%d", val);
        !           229:       break;
        !           230: 
        !           231:     case TYPE_CODE_FUNC:
        !           232:       fprintf (stream, "{");
        !           233:       type_print (type, "", stream, -1);
        !           234:       fprintf (stream, "} ");
        !           235:       fprintf (stream, "0x%x", address);
        !           236:       break;
        !           237: 
        !           238:     case TYPE_CODE_INT:
        !           239:       fprintf (stream,
        !           240:               TYPE_UNSIGNED (type) ? "%u" : "%d",
        !           241:               unpack_long (type, valaddr));
        !           242:       if (type == builtin_type_char
        !           243:          || type == builtin_type_unsigned_char)
        !           244:        {
        !           245:          fprintf (stream, " '");
        !           246:          printchar (unpack_long (type, valaddr), stream);
        !           247:          fputc ('\'', stream);
        !           248:        }
        !           249:       break;
        !           250: 
        !           251:     case TYPE_CODE_FLT:
        !           252:       fprintf (stream, "%g", unpack_double (type, valaddr));
        !           253:       break;
        !           254: 
        !           255:     case TYPE_CODE_VOID:
        !           256:       fprintf (stream, "void");
        !           257:       break;
        !           258: 
        !           259:     default:
        !           260:       error ("Invalid type code in symbol table.");
        !           261:     }
        !           262:   fflush (stream);
        !           263: }
        !           264: 
        !           265: /* Print a description of a type TYPE
        !           266:    in the form of a declaration of a variable named VARSTRING.
        !           267:    Output goes to STREAM (via stdio).
        !           268:    If SHOW is positive, we show the contents of the outermost level
        !           269:    of structure even if there is a type name that could be used instead.
        !           270:    If SHOW is negative, we never show the details of elements' types.  */
        !           271: 
        !           272: type_print (type, varstring, stream, show)
        !           273:      struct type *type;
        !           274:      char *varstring;
        !           275:      FILE *stream;
        !           276:      int show;
        !           277: {
        !           278:   type_print_1 (type, varstring, stream, show, 0);
        !           279: }
        !           280: 
        !           281: /* LEVEL is the depth to indent lines by.  */
        !           282: 
        !           283: type_print_1 (type, varstring, stream, show, level)
        !           284:      struct type *type;
        !           285:      char *varstring;
        !           286:      FILE *stream;
        !           287:      int show;
        !           288:      int level;
        !           289: {
        !           290:   register enum type_code code;
        !           291:   type_print_base (type, stream, show, level);
        !           292:   code = TYPE_CODE (type);
        !           293:   if ((varstring && *varstring)
        !           294:       ||
        !           295:       /* Need a space if going to print stars or brackets;
        !           296:         but not if we will print just a type name.  */
        !           297:       ((show > 0 || TYPE_NAME (type) == 0)
        !           298:        &&
        !           299:        (code == TYPE_CODE_PTR || code == TYPE_CODE_FUNC
        !           300:        || code == TYPE_CODE_ARRAY)))
        !           301:     fprintf (stream, " ");
        !           302:   type_print_varspec_prefix (type, stream, show, 0);
        !           303:   fprintf (stream, "%s", varstring);
        !           304:   type_print_varspec_suffix (type, stream, show, 0);
        !           305: }
        !           306: 
        !           307: /* Print any asterisks or open-parentheses needed before the
        !           308:    variable name (to describe its type).
        !           309: 
        !           310:    On outermost call, pass 0 for PASSED_A_PTR.
        !           311:    On outermost call, SHOW > 0 means should ignore
        !           312:    any typename for TYPE and show its details.
        !           313:    SHOW is always zero on recursive calls.  */
        !           314: 
        !           315: static void
        !           316: type_print_varspec_prefix (type, stream, show, passed_a_ptr)
        !           317:      struct type *type;
        !           318:      FILE *stream;
        !           319:      int show;
        !           320:      int passed_a_ptr;
        !           321: {
        !           322:   if (TYPE_NAME (type) && show <= 0)
        !           323:     return;
        !           324: 
        !           325:   QUIT;
        !           326: 
        !           327:   switch (TYPE_CODE (type))
        !           328:     {
        !           329:     case TYPE_CODE_PTR:
        !           330:       type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, 0, 1);
        !           331:       fputc ('*', stream);
        !           332:       break;
        !           333: 
        !           334:     case TYPE_CODE_FUNC:
        !           335:       type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, 0,
        !           336:                                 passed_a_ptr);
        !           337:       if (passed_a_ptr)
        !           338:        fputc ('(', stream);
        !           339:       break;
        !           340: 
        !           341:     case TYPE_CODE_ARRAY:
        !           342:       type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, 0,
        !           343:                                 passed_a_ptr);
        !           344:     }
        !           345: }
        !           346: 
        !           347: /* Print any array sizes, function arguments or close parentheses
        !           348:    needed after the variable name (to describe its type).
        !           349:    Args work like type_print_varspec_prefix.  */
        !           350: 
        !           351: static void
        !           352: type_print_varspec_suffix (type, stream, show, passed_a_ptr)
        !           353:      struct type *type;
        !           354:      FILE *stream;
        !           355:      int show;
        !           356:      int passed_a_ptr;
        !           357: {
        !           358:   if (TYPE_NAME (type) && show <= 0)
        !           359:     return;
        !           360: 
        !           361:   QUIT;
        !           362: 
        !           363:   switch (TYPE_CODE (type))
        !           364:     {
        !           365:     case TYPE_CODE_ARRAY:
        !           366:       type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, 0,
        !           367:                                 passed_a_ptr);
        !           368:       fprintf (stream, "[");
        !           369:       if (TYPE_LENGTH (type) >= 0)
        !           370:        fprintf (stream, "%d",
        !           371:                 TYPE_LENGTH (type) / TYPE_LENGTH (TYPE_TARGET_TYPE (type)));
        !           372:       fprintf (stream, "]");
        !           373:       break;
        !           374: 
        !           375:     case TYPE_CODE_PTR:
        !           376:       type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, 0, 1);
        !           377:       break;
        !           378: 
        !           379:     case TYPE_CODE_FUNC:
        !           380:       type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, 0,
        !           381:                                 passed_a_ptr);
        !           382:       if (passed_a_ptr)
        !           383:        fprintf (stream, ")");
        !           384:       fprintf (stream, "()");
        !           385:       break;
        !           386:     }
        !           387: }
        !           388: 
        !           389: /* Print the name of the type (or the ultimate pointer target,
        !           390:    function value or array element), or the description of a
        !           391:    structure or union.
        !           392: 
        !           393:    SHOW nonzero means don't print this type as just its name;
        !           394:    show its real definition even if it has a name.
        !           395:    SHOW zero means print just typename or struct tag if there is one
        !           396:    SHOW negative means abbreviate structure elements.
        !           397:    SHOW is decremented for printing of structure elements.
        !           398: 
        !           399:    LEVEL is the depth to indent by.
        !           400:    We increase it for some recursive calls.  */
        !           401: 
        !           402: static void
        !           403: type_print_base (type, stream, show, level)
        !           404:      struct type *type;
        !           405:      FILE *stream;
        !           406:      int show;
        !           407:      int level;
        !           408: {
        !           409:   char *name;
        !           410:   register int i;
        !           411:   register int len;
        !           412:   register int lastval;
        !           413: 
        !           414:   QUIT;
        !           415: 
        !           416:   if (TYPE_NAME (type) && show <= 0)
        !           417:     {
        !           418:       fprintf (stream, TYPE_NAME (type));
        !           419:       return;
        !           420:     }
        !           421: 
        !           422:   switch (TYPE_CODE (type))
        !           423:     {
        !           424:     case TYPE_CODE_ARRAY:
        !           425:     case TYPE_CODE_PTR:
        !           426:     case TYPE_CODE_FUNC:
        !           427:       type_print_base (TYPE_TARGET_TYPE (type), stream, show, level);
        !           428:       break;
        !           429: 
        !           430:     case TYPE_CODE_STRUCT:
        !           431:       fprintf (stream, "struct ");
        !           432:       goto struct_union;
        !           433: 
        !           434:     case TYPE_CODE_UNION:
        !           435:       fprintf (stream, "union ");
        !           436:     struct_union:
        !           437:       if (TYPE_NAME (type) && (name = TYPE_NAME (type)))
        !           438:        {
        !           439:          while (*name != ' ') name++;
        !           440:          fprintf (stream, "%s ", name + 1);
        !           441:        }
        !           442:       if (show < 0)
        !           443:        fprintf (stream, "{...}");
        !           444:       else
        !           445:        {
        !           446:          fprintf (stream, "{");
        !           447:          len = TYPE_NFIELDS (type);
        !           448:          fprintf (stream, "\n");
        !           449:          for (i = 0; i < len; i++)
        !           450:            {
        !           451:              QUIT;
        !           452:              print_spaces (level + 4, stream);
        !           453:              type_print_1 (TYPE_FIELD_TYPE (type, i),
        !           454:                            TYPE_FIELD_NAME (type, i),
        !           455:                            stream, show - 1, level + 4);
        !           456:              if (TYPE_FIELD_PACKED (type, i))
        !           457:                {
        !           458:                  /* ??? don't know what to put here ??? */;
        !           459:                }
        !           460:              fprintf (stream, ";\n");
        !           461:            }
        !           462:          print_spaces (level, stream);
        !           463:          fputc ('}', stream);
        !           464:        }
        !           465:       break;
        !           466: 
        !           467:     case TYPE_CODE_ENUM:
        !           468:       fprintf (stream, "enum ");
        !           469:       if (TYPE_NAME (type))
        !           470:        {
        !           471:          name = TYPE_NAME (type);
        !           472:          while (*name != ' ') name++;
        !           473:          fprintf (stream, "%s ", name + 1);
        !           474:        }
        !           475:       if (show < 0)
        !           476:        fprintf (stream, "{...}");
        !           477:       else
        !           478:        {
        !           479:          fprintf (stream, "{");
        !           480:          len = TYPE_NFIELDS (type);
        !           481:          lastval = 0;
        !           482:          for (i = 0; i < len; i++)
        !           483:            {
        !           484:              QUIT;
        !           485:              if (i) fprintf (stream, ", ");
        !           486:              fprintf (stream, "%s", TYPE_FIELD_NAME (type, i));
        !           487:              if (lastval != TYPE_FIELD_VALUE (type, i))
        !           488:                {
        !           489:                  fprintf (stream, " : %d", TYPE_FIELD_VALUE (type, i));
        !           490:                  lastval = TYPE_FIELD_VALUE (type, i);
        !           491:                }
        !           492:              lastval++;
        !           493:            }
        !           494:          fprintf (stream, "}");
        !           495:        }
        !           496:       break;
        !           497: 
        !           498:     case TYPE_CODE_INT:
        !           499:       if (TYPE_UNSIGNED (type))
        !           500:        name = unsigned_type_table[TYPE_LENGTH (type)];
        !           501:       else
        !           502:        name = signed_type_table[TYPE_LENGTH (type)];
        !           503:       fprintf (stream, "%s", name);
        !           504:       break;
        !           505: 
        !           506:     case TYPE_CODE_FLT:
        !           507:       name = float_type_table[TYPE_LENGTH (type)];
        !           508:       fprintf (stream, "%s", name);
        !           509:       break;
        !           510: 
        !           511:     case TYPE_CODE_VOID:
        !           512:       fprintf (stream, "void");
        !           513:       break;
        !           514: 
        !           515:     case 0:
        !           516:       fprintf (stream, "struct unknown");
        !           517:       break;
        !           518: 
        !           519:     default:
        !           520:       error ("Invalid type code in symbol table.");
        !           521:     }
        !           522: }
        !           523: 
        !           524: static void
        !           525: set_maximum_command (arg)
        !           526:      char *arg;
        !           527: {
        !           528:   if (!arg) error_no_arg ("value for maximum elements to print");
        !           529:   print_max = atoi (arg);
        !           530: }
        !           531: 
        !           532: static
        !           533: initialize ()
        !           534: {
        !           535:   add_com ("set-maximum", class_vars, set_maximum_command,
        !           536:           "Set NUMBER as limit on string chars or array elements to print.");
        !           537: 
        !           538:   print_max = 200;
        !           539: 
        !           540:   unsigned_type_table
        !           541:     = (char **) xmalloc ((1 + sizeof (unsigned long)) * sizeof (char *));
        !           542:   bzero (unsigned_type_table, (1 + sizeof (unsigned long)));
        !           543:   unsigned_type_table[sizeof (unsigned char)] = "unsigned char";
        !           544:   unsigned_type_table[sizeof (unsigned short)] = "unsigned short";
        !           545:   unsigned_type_table[sizeof (unsigned long)] = "unsigned long";
        !           546:   unsigned_type_table[sizeof (unsigned int)] = "unsigned int";
        !           547: 
        !           548:   signed_type_table
        !           549:     = (char **) xmalloc ((1 + sizeof (long)) * sizeof (char *));
        !           550:   bzero (signed_type_table, (1 + sizeof (long)));
        !           551:   signed_type_table[sizeof (char)] = "char";
        !           552:   signed_type_table[sizeof (short)] = "short";
        !           553:   signed_type_table[sizeof (long)] = "long";
        !           554:   signed_type_table[sizeof (int)] = "int";
        !           555: 
        !           556:   float_type_table
        !           557:     = (char **) xmalloc ((1 + sizeof (double)) * sizeof (char *));
        !           558:   bzero (float_type_table, (1 + sizeof (double)));
        !           559:   float_type_table[sizeof (float)] = "float";
        !           560:   float_type_table[sizeof (double)] = "double";
        !           561: }
        !           562: 
        !           563: END_FILE

unix.superglobalmegacorp.com

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