⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 valprint.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 4 页
字号:
/* Print values for GDB, the GNU debugger.   Copyright 1986, 1988, 1989, 1991 Free Software Foundation, Inc.This file is part of GDB.This program is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; either version 2 of the License, or(at your option) any later version.This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with this program; if not, write to the Free SoftwareFoundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */#include "defs.h"#include <string.h>#include "symtab.h"#include "gdbtypes.h"#include "value.h"#include "gdbcore.h"#include "gdbcmd.h"#include "target.h"#include "obstack.h"#include "language.h"#include "demangle.h"#include <errno.h>/* Prototypes for local functions */static voidprint_string PARAMS ((FILE *, char *, unsigned int, int));static voidshow_print PARAMS ((char *, int));static voidset_print PARAMS ((char *, int));static voidset_radix PARAMS ((char *, int, struct cmd_list_element *));static voidset_output_radix PARAMS ((char *, int, struct cmd_list_element *));static voidtype_print_base PARAMS ((struct type *, FILE *, int, int));static voidtype_print_args PARAMS ((struct type *, FILE *));static voidtype_print_varspec_suffix PARAMS ((struct type *, FILE *, int, int, int));static voidtype_print_varspec_prefix PARAMS ((struct type *, FILE *, int, int));static voidtype_print_derivation_info PARAMS ((FILE *, struct type *));static voidtype_print_method_args PARAMS ((struct type **, char *, char *, int, FILE *));static voidcplus_val_print PARAMS ((struct type *, char *, FILE *, int, int,			 enum val_prettyprint, struct type **));static voidval_print_fields PARAMS ((struct type *, char *, FILE *, int, int,			  enum val_prettyprint, struct type **));static intis_vtbl_member PARAMS ((struct type *));static intis_vtbl_ptr_type PARAMS ((struct type *));static voidprint_hex_chars PARAMS ((FILE *, unsigned char *, unsigned));extern int demangle;	/* whether to print C++ syms raw or source-form *//* Maximum number of chars to print for a string pointer value   or vector contents, or UINT_MAX for no limit.  */static unsigned int print_max;/* Default input and output radixes, and output format letter.  */unsigned input_radix = 10;unsigned output_radix = 10;int output_format = 0;/* Print repeat counts if there are more than this   many repetitions of an element in an array.  */#define	REPEAT_COUNT_THRESHOLD	10/* Define a mess of print controls.  */int prettyprint;	/* Controls pretty printing of structures */int vtblprint;		/* Controls printing of vtbl's */int unionprint;		/* Controls printing of nested unions.  */int arrayprint;		/* Controls pretty printing of arrays.  */int addressprint;	/* Controls pretty printing of addresses.  */int objectprint;	/* Controls looking up an object's derived type			   using what we find in its vtables.  */struct obstack dont_print_obstack;/* Print the character string STRING, printing at most LENGTH characters.   Printing stops early if the number hits print_max; repeat counts   are printed as appropriate.  Print ellipses at the end if we   had to stop before printing LENGTH characters, or if FORCE_ELLIPSES.  */static voidprint_string (stream, string, length, force_ellipses)     FILE *stream;     char *string;     unsigned int length;     int force_ellipses;{  register unsigned int i;  unsigned int things_printed = 0;  int in_quotes = 0;  int need_comma = 0;  extern int inspect_it;  if (length == 0)    {      fputs_filtered ("\"\"", stdout);      return;    }  for (i = 0; i < length && things_printed < print_max; ++i)    {      /* Position of the character we are examining	 to see whether it is repeated.  */      unsigned int rep1;      /* Number of repetitions we have detected so far.  */      unsigned int reps;      QUIT;      if (need_comma)	{	  fputs_filtered (", ", stream);	  need_comma = 0;	}      rep1 = i + 1;      reps = 1;      while (rep1 < length && string[rep1] == string[i])	{	  ++rep1;	  ++reps;	}      if (reps > REPEAT_COUNT_THRESHOLD)	{	  if (in_quotes)	    {	      if (inspect_it)		fputs_filtered ("\\\", ", stream);	      else		fputs_filtered ("\", ", stream);	      in_quotes = 0;	    }	  fputs_filtered ("'", stream);	  printchar (string[i], stream, '\'');	  fprintf_filtered (stream, "' <repeats %u times>", reps);	  i = rep1 - 1;	  things_printed += REPEAT_COUNT_THRESHOLD;	  need_comma = 1;	}      else	{	  if (!in_quotes)	    {	      if (inspect_it)		fputs_filtered ("\\\"", stream);	      else		fputs_filtered ("\"", stream);	      in_quotes = 1;	    }	  printchar (string[i], stream, '"');	  ++things_printed;	}    }  /* Terminate the quotes if necessary.  */  if (in_quotes)    {      if (inspect_it)	fputs_filtered ("\\\"", stream);      else	fputs_filtered ("\"", stream);    }  if (force_ellipses || i < length)    fputs_filtered ("...", stream);}/* Print a floating point value of type TYPE, pointed to in GDB by VALADDR,   on STREAM.  */voidprint_floating (valaddr, type, stream)     char *valaddr;     struct type *type;     FILE *stream;{  double doub;  int inv;  unsigned len = TYPE_LENGTH (type);  #if defined (IEEE_FLOAT)  /* Check for NaN's.  Note that this code does not depend on us being     on an IEEE conforming system.  It only depends on the target     machine using IEEE representation.  This means (a)     cross-debugging works right, and (2) IEEE_FLOAT can (and should)     be defined for systems like the 68881, which uses IEEE     representation, but is not IEEE conforming.  */  {    long low, high;    /* Is the sign bit 0?  */    int nonnegative;    /* Is it is a NaN (i.e. the exponent is all ones and       the fraction is nonzero)?  */    int is_nan;    if (len == sizeof (float))      {	/* It's single precision. */	memcpy ((char *) &low, valaddr, sizeof (low));	/* target -> host.  */	SWAP_TARGET_AND_HOST (&low, sizeof (float));	nonnegative = low >= 0;	is_nan = ((((low >> 23) & 0xFF) == 0xFF) 		  && 0 != (low & 0x7FFFFF));	low &= 0x7fffff;	high = 0;      }    else      {	/* It's double precision.  Get the high and low words.  */#if TARGET_BYTE_ORDER == BIG_ENDIAN	memcpy (&low, valaddr+4,  sizeof (low));	memcpy (&high, valaddr+0, sizeof (high));#else	memcpy (&low, valaddr+0,  sizeof (low));	memcpy (&high, valaddr+4, sizeof (high));#endif	SWAP_TARGET_AND_HOST (&low, sizeof (low));	SWAP_TARGET_AND_HOST (&high, sizeof (high));	nonnegative = high >= 0;	is_nan = (((high >> 20) & 0x7ff) == 0x7ff		  && ! ((((high & 0xfffff) == 0)) && (low == 0)));	high &= 0xfffff;      }    if (is_nan)      {	/* The meaning of the sign and fraction is not defined by IEEE.	   But the user might know what they mean.  For example, they	   (in an implementation-defined manner) distinguish between	   signaling and quiet NaN's.  */	if (high)	  fprintf_filtered (stream, "-NaN(0x%lx%.8lx)" + nonnegative,			    high, low);	else	  fprintf_filtered (stream, "-NaN(0x%lx)" + nonnegative, low);	return;      }  }#endif /* IEEE_FLOAT.  */  doub = unpack_double (type, valaddr, &inv);  if (inv)    fprintf_filtered (stream, "<invalid float value>");  else    fprintf_filtered (stream, len <= sizeof(float) ? "%.9g" : "%.17g", doub);}/* VALADDR points to an integer of LEN bytes.  Print it in hex on stream.  */static voidprint_hex_chars (stream, valaddr, len)     FILE *stream;     unsigned char *valaddr;     unsigned len;{  unsigned char *p;    fprintf_filtered (stream, "0x");#if TARGET_BYTE_ORDER == BIG_ENDIAN  for (p = valaddr;       p < valaddr + len;       p++)#else /* Little endian.  */  for (p = valaddr + len - 1;       p >= valaddr;       p--)#endif    {      fprintf_filtered (stream, "%02x", *p);    }}/* Print the value VAL in C-ish syntax on stream STREAM.   FORMAT is a format-letter, or 0 for print in natural format of data type.   If the object printed is a string pointer, returns   the number of string bytes printed.  */intvalue_print (val, stream, format, pretty)     value val;     FILE *stream;     int format;     enum val_prettyprint pretty;{  register unsigned int i, n, typelen;  if (val == 0)    {      printf_filtered ("<address of value unknown>");      return 0;    }  if (VALUE_OPTIMIZED_OUT (val))    {      printf_filtered ("<value optimized out>");      return 0;    }  /* A "repeated" value really contains several values in a row.     They are made by the @ operator.     Print such values as if they were arrays.  */  else if (VALUE_REPEATED (val))    {      n = VALUE_REPETITIONS (val);      typelen = TYPE_LENGTH (VALUE_TYPE (val));      fprintf_filtered (stream, "{");      /* Print arrays of characters using string syntax.  */      if (typelen == 1 && TYPE_CODE (VALUE_TYPE (val)) == TYPE_CODE_INT	  && format == 0)	print_string (stream, VALUE_CONTENTS (val), n, 0);      else	{	  unsigned int things_printed = 0;	  	  for (i = 0; i < n && things_printed < print_max; i++)	    {	      /* Position of the array element we are examining to see		 whether it is repeated.  */	      unsigned int rep1;	      /* Number of repetitions we have detected so far.  */	      unsigned int reps;	      if (i != 0)		fprintf_filtered (stream, ", ");	      wrap_here ("");	      rep1 = i + 1;	      reps = 1;	      while (rep1 < n		     && !memcmp (VALUE_CONTENTS (val) + typelen * i,			       VALUE_CONTENTS (val) + typelen * rep1, typelen))		{		  ++reps;		  ++rep1;		}	      if (reps > REPEAT_COUNT_THRESHOLD)		{		  val_print (VALUE_TYPE (val),			     VALUE_CONTENTS (val) + typelen * i,			     VALUE_ADDRESS (val) + typelen * i,			     stream, format, 1, 0, pretty);		  fprintf (stream, " <repeats %u times>", reps);		  i = rep1 - 1;		  things_printed += REPEAT_COUNT_THRESHOLD;		}	      else		{		  val_print (VALUE_TYPE (val),			     VALUE_CONTENTS (val) + typelen * i,			     VALUE_ADDRESS (val) + typelen * i,			     stream, format, 1, 0, pretty);		  things_printed++;		}	    }	  if (i < n)	    fprintf_filtered (stream, "...");	}      fprintf_filtered (stream, "}");      return n * typelen;    }  else    {      struct type *type = VALUE_TYPE (val);      /* If it is a pointer, indicate what it points to.	 Print type also if it is a reference.         C++: if it is a member pointer, we will take care	 of that when we print it.  */      if (TYPE_CODE (type) == TYPE_CODE_PTR	  || TYPE_CODE (type) == TYPE_CODE_REF)	{	  /* Hack:  remove (char *) for char strings.  Their	     type is indicated by the quoted string anyway. */          if (TYPE_CODE (type) == TYPE_CODE_PTR	      && TYPE_LENGTH (TYPE_TARGET_TYPE (type)) == sizeof(char)	      && TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_INT	      && !TYPE_UNSIGNED (TYPE_TARGET_TYPE (type)))	    {		/* Print nothing */	    }	  else	    {	      fprintf_filtered (stream, "(");	      type_print (type, "", stream, -1);	      fprintf_filtered (stream, ") ");	    }	}      return val_print (type, VALUE_CONTENTS (val),			VALUE_ADDRESS (val), stream, format, 1, 0, pretty);    }}/* Return truth value for assertion that TYPE is of the type   "pointer to virtual function".  */static intis_vtbl_ptr_type(type)     struct type *type;{  char *typename = type_name_no_tag (type);  static const char vtbl_ptr_name[] =    { CPLUS_MARKER,'v','t','b','l','_','p','t','r','_','t','y','p','e', 0 };  return (typename != NULL && !strcmp(typename, vtbl_ptr_name));}/* Return truth value for the assertion that TYPE is of the type   "pointer to virtual function table".  */static intis_vtbl_member(type)     struct type *type;{  if (TYPE_CODE (type) == TYPE_CODE_PTR)    type = TYPE_TARGET_TYPE (type);  else    return 0;  if (TYPE_CODE (type) == TYPE_CODE_ARRAY      && TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_STRUCT)    /* Virtual functions tables are full of pointers to virtual functions.  */    return is_vtbl_ptr_type (TYPE_TARGET_TYPE (type));  return 0;}/* Mutually recursive subroutines of cplus_val_print and val_print to print out   a structure's fields: val_print_fields and cplus_val_print.   TYPE, VALADDR, STREAM, RECURSE, and PRETTY have the   same meanings as in cplus_val_print and val_print.   DONT_PRINT is an array of baseclass types that we   should not print, or zero if called from top level.  */static voidval_print_fields (type, valaddr, stream, format, recurse, pretty, dont_print)     struct type *type;     char *valaddr;     FILE *stream;     int format;     int recurse;     enum val_prettyprint pretty;     struct type **dont_print;{  int i, len, n_baseclasses;  check_stub_type (type);  fprintf_filtered (stream, "{");  len = TYPE_NFIELDS (type);  n_baseclasses = TYPE_N_BASECLASSES (type);  /* Print out baseclasses such that we don't print     duplicates of virtual baseclasses.  */  if (n_baseclasses > 0)    cplus_val_print (type, valaddr, stream, format, recurse+1, pretty, dont_print);  if (!len && n_baseclasses == 1)    fprintf_filtered (stream, "<No data fields>");  else    {      extern int inspect_it;      int fields_seen = 0;      for (i = n_baseclasses; i < len; i++)	{	  /* Check if static field */	  if (TYPE_FIELD_STATIC (type, i))	    continue;	  if (fields_seen)	    fprintf_filtered (stream, ", ");	  else if (n_baseclasses > 0)	    {	      if (pretty)		{		  fprintf_filtered (stream, "\n");		  print_spaces_filtered (2 + 2 * recurse, stream);		  fputs_filtered ("members of ", stream);		  fputs_filtered (type_name_no_tag (type), stream);		  fputs_filtered (": ", stream);		}	    }	  fields_seen = 1;	  if (pretty)	    {	      fprintf_filtered (stream, "\n");	      print_spaces_filtered (2 + 2 * recurse, stream);	    }	  else 	    {	      wrap_here (n_spaces (2 + 2 * recurse));	    }	  if (inspect_it)	    {	      if (TYPE_CODE (TYPE_FIELD_TYPE (type, i)) == TYPE_CODE_PTR)		fputs_filtered ("\"( ptr \"", stream);	      else		fputs_filtered ("\"( nodef \"", stream);	      fprint_symbol (stream, TYPE_FIELD_NAME (type, i));	      fputs_filtered ("\" \"", stream);	      fprint_symbol (stream, TYPE_FIELD_NAME (type, i));	      fputs_filtered ("\") \"", stream);	    }	  else	    {	      fprint_symbol (stream, TYPE_FIELD_NAME (type, i));	      fputs_filtered (" = ", stream);	    }	  if (TYPE_FIELD_PACKED (type, i))	    {	      value v;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -