int
ada_value_print (struct value *val0, struct ui_file *stream, int format,
		 enum val_prettyprint pretty)
{
  char *valaddr = VALUE_CONTENTS (val0);
  CORE_ADDR address = VALUE_ADDRESS (val0) + VALUE_OFFSET (val0);
  struct type *type =
    ada_to_fixed_type (VALUE_TYPE (val0), valaddr, address, NULL);
  struct value *val =
    value_from_contents_and_address (type, valaddr, address);

  /* If it is a pointer, indicate what it points to.  */
  if (TYPE_CODE (type) == TYPE_CODE_PTR)
    {
      /* Hack:  don't print (char *) for char strings.  Their
         type is indicated by the quoted string anyway.  */
      if (TYPE_LENGTH (TYPE_TARGET_TYPE (type)) != sizeof (char)
	  || TYPE_CODE (TYPE_TARGET_TYPE (type)) != TYPE_CODE_INT 
	  || TYPE_UNSIGNED (TYPE_TARGET_TYPE (type)))
	{
	  fprintf_filtered (stream, "(");
	  type_print (type, "", stream, -1);
	  fprintf_filtered (stream, ") ");
	}
    }
  else if (ada_is_array_descriptor_type (type))
    {
      fprintf_filtered (stream, "(");
      type_print (type, "", stream, -1);
      fprintf_filtered (stream, ") ");
    }
  else if (ada_is_bogus_array_descriptor (type))
    {
      fprintf_filtered (stream, "(");
      type_print (type, "", stream, -1);
      fprintf_filtered (stream, ") (...?)");
      return 0;
    }

  if (TYPE_CODE (type) == TYPE_CODE_ARRAY
      && TYPE_LENGTH (TYPE_TARGET_TYPE (type)) == 0
      && TYPE_CODE (TYPE_INDEX_TYPE (type)) == TYPE_CODE_RANGE)
    {
      /* This is an array of zero-length elements, that is an array
         of null records.  This array needs to be printed by hand,
         as the standard routine to print arrays relies on the size of
         the array elements to be nonzero.  This is because it computes
         the number of elements in the array by dividing the array size
         by the array element size.  */
      fprintf_filtered (stream, "(%d .. %d => ())",
                        TYPE_LOW_BOUND (TYPE_INDEX_TYPE (type)),
                        TYPE_HIGH_BOUND (TYPE_INDEX_TYPE (type)));
      return 0;
    }
  
  return (val_print (type, VALUE_CONTENTS (val), 0, address,
		     stream, format, 1, 0, pretty));
}
Example #2
0
int
java_value_print (struct value *val, struct ui_file *stream, int format,
		  enum val_prettyprint pretty)
{
  struct type *type;
  CORE_ADDR address;
  int i;
  char *name;

  type = VALUE_TYPE (val);
  address = VALUE_ADDRESS (val) + VALUE_OFFSET (val);

  if (is_object_type (type))
    {
      CORE_ADDR obj_addr;

      /* Get the run-time type, and cast the object into that */

      obj_addr = unpack_pointer (type, VALUE_CONTENTS (val));

      if (obj_addr != 0)
	{
	  type = type_from_class (java_class_from_object (val));
	  type = lookup_pointer_type (type);

	  val = value_at (type, address, NULL);
	}
    }

  if (TYPE_CODE (type) == TYPE_CODE_PTR && !value_logical_not (val))
    type_print (TYPE_TARGET_TYPE (type), "", stream, -1);

  name = TYPE_TAG_NAME (type);
  if (TYPE_CODE (type) == TYPE_CODE_STRUCT && name != NULL
      && (i = strlen (name), name[i - 1] == ']'))
    {
      char buf4[4];
      long length;
      unsigned int things_printed = 0;
      int reps;
      struct type *el_type = java_primitive_type_from_name (name, i - 2);

      i = 0;
      read_memory (address + JAVA_OBJECT_SIZE, buf4, 4);

      length = (long) extract_signed_integer (buf4, 4);
      fprintf_filtered (stream, "{length: %ld", length);

      if (el_type == NULL)
	{
	  CORE_ADDR element;
	  CORE_ADDR next_element = -1; /* dummy initial value */

	  address += JAVA_OBJECT_SIZE + 4;	/* Skip object header and length. */

	  while (i < length && things_printed < print_max)
	    {
	      char *buf;

	      buf = alloca (TARGET_PTR_BIT / HOST_CHAR_BIT);
	      fputs_filtered (", ", stream);
	      wrap_here (n_spaces (2));

	      if (i > 0)
		element = next_element;
	      else
		{
		  read_memory (address, buf, sizeof (buf));
		  address += TARGET_PTR_BIT / HOST_CHAR_BIT;
		  element = extract_address (buf, sizeof (buf));
		}

	      for (reps = 1; i + reps < length; reps++)
		{
		  read_memory (address, buf, sizeof (buf));
		  address += TARGET_PTR_BIT / HOST_CHAR_BIT;
		  next_element = extract_address (buf, sizeof (buf));
		  if (next_element != element)
		    break;
		}

	      if (reps == 1)
		fprintf_filtered (stream, "%d: ", i);
	      else
		fprintf_filtered (stream, "%d..%d: ", i, i + reps - 1);

	      if (element == 0)
		fprintf_filtered (stream, "null");
	      else
		fprintf_filtered (stream, "@%s", paddr_nz (element));

	      things_printed++;
	      i += reps;
	    }
	}
      else
	{
	  struct value *v = allocate_value (el_type);
	  struct value *next_v = allocate_value (el_type);

	  VALUE_ADDRESS (v) = address + JAVA_OBJECT_SIZE + 4;
	  VALUE_ADDRESS (next_v) = VALUE_ADDRESS (v);

	  while (i < length && things_printed < print_max)
	    {
	      fputs_filtered (", ", stream);
	      wrap_here (n_spaces (2));

	      if (i > 0)
		{
		  struct value *tmp;

		  tmp = next_v;
		  next_v = v;
		  v = tmp;
		}
	      else
		{
		  VALUE_LAZY (v) = 1;
		  VALUE_OFFSET (v) = 0;
		}

	      VALUE_OFFSET (next_v) = VALUE_OFFSET (v);

	      for (reps = 1; i + reps < length; reps++)
		{
		  VALUE_LAZY (next_v) = 1;
		  VALUE_OFFSET (next_v) += TYPE_LENGTH (el_type);
		  if (memcmp (VALUE_CONTENTS (v), VALUE_CONTENTS (next_v),
			      TYPE_LENGTH (el_type)) != 0)
		    break;
		}

	      if (reps == 1)
		fprintf_filtered (stream, "%d: ", i);
	      else
		fprintf_filtered (stream, "%d..%d: ", i, i + reps - 1);

	      val_print (VALUE_TYPE (v), VALUE_CONTENTS (v), 0, 0,
			 stream, format, 2, 1, pretty);

	      things_printed++;
	      i += reps;
	    }
	}

      if (i < length)
	fprintf_filtered (stream, "...");

      fprintf_filtered (stream, "}");

      return 0;
    }

  /* If it's type String, print it */

  if (TYPE_CODE (type) == TYPE_CODE_PTR
      && TYPE_TARGET_TYPE (type)
      && TYPE_NAME (TYPE_TARGET_TYPE (type))
      && strcmp (TYPE_NAME (TYPE_TARGET_TYPE (type)), "java.lang.String") == 0
      && (format == 0 || format == 's')
      && address != 0
      && value_as_address (val) != 0)
    {
      struct value *data_val;
      CORE_ADDR data;
      struct value *boffset_val;
      unsigned long boffset;
      struct value *count_val;
      unsigned long count;
      struct value *mark;

      mark = value_mark ();	/* Remember start of new values */

      data_val = value_struct_elt (&val, NULL, "data", NULL, NULL);
      data = value_as_address (data_val);

      boffset_val = value_struct_elt (&val, NULL, "boffset", NULL, NULL);
      boffset = value_as_address (boffset_val);

      count_val = value_struct_elt (&val, NULL, "count", NULL, NULL);
      count = value_as_address (count_val);

      value_free_to_mark (mark);	/* Release unnecessary values */

      val_print_string (data + boffset, count, 2, stream);

      return 0;
    }

  return (val_print (type, VALUE_CONTENTS (val), 0, address,
		     stream, format, 1, 0, pretty));
}