예제 #1
0
static void
signal_catchpoint_print_one (struct breakpoint *b,
			     struct bp_location **last_loc)
{
  struct signal_catchpoint *c = (void *) b;
  struct value_print_options opts;
  struct ui_out *uiout = current_uiout;

  get_user_print_options (&opts);

  /* Field 4, the address, is omitted (which makes the columns
     not line up too nicely with the headers, but the effect
     is relatively readable).  */
  if (opts.addressprint)
    ui_out_field_skip (uiout, "addr");
  annotate_field (5);

  if (c->signals_to_be_caught
      && VEC_length (gdb_signal_type, c->signals_to_be_caught) > 1)
    ui_out_text (uiout, "signals \"");
  else
    ui_out_text (uiout, "signal \"");

  if (c->signals_to_be_caught)
    {
      int i;
      gdb_signal_type iter;
      struct obstack text;
      struct cleanup *cleanup;

      obstack_init (&text);
      cleanup = make_cleanup_obstack_free (&text);

      for (i = 0;
           VEC_iterate (gdb_signal_type, c->signals_to_be_caught, i, iter);
           i++)
        {
	  const char *name = signal_to_name_or_int (iter);

	  if (i > 0)
	    obstack_grow (&text, " ", 1);
	  obstack_grow (&text, name, strlen (name));
        }
      obstack_grow (&text, "", 1);
      ui_out_field_string (uiout, "what", obstack_base (&text));
      do_cleanups (cleanup);
    }
  else
    ui_out_field_string (uiout, "what",
			 c->catch_all ? "<any signal>" : "<standard signals>");
  ui_out_text (uiout, "\" ");

  if (ui_out_is_mi_like_p (uiout))
    ui_out_field_string (uiout, "catch-type", "signal");
}
예제 #2
0
파일: c-lang.c 프로젝트: NalaGinrut/gdb
struct value *
evaluate_subexp_c (struct type *expect_type, struct expression *exp,
		   int *pos, enum noside noside)
{
  enum exp_opcode op = exp->elts[*pos].opcode;

  switch (op)
    {
    case OP_STRING:
      {
	int oplen, limit;
	struct type *type;
	struct obstack output;
	struct cleanup *cleanup;
	struct value *result;
	enum c_string_type dest_type;
	const char *dest_charset;
	int satisfy_expected = 0;

	obstack_init (&output);
	cleanup = make_cleanup_obstack_free (&output);

	++*pos;
	oplen = longest_to_int (exp->elts[*pos].longconst);

	++*pos;
	limit = *pos + BYTES_TO_EXP_ELEM (oplen + 1);
	dest_type
	  = (enum c_string_type) longest_to_int (exp->elts[*pos].longconst);
	switch (dest_type & ~C_CHAR)
	  {
	  case C_STRING:
	    type = language_string_char_type (exp->language_defn,
					      exp->gdbarch);
	    break;
	  case C_WIDE_STRING:
	    type = lookup_typename (exp->language_defn, exp->gdbarch,
				    "wchar_t", NULL, 0);
	    break;
	  case C_STRING_16:
	    type = lookup_typename (exp->language_defn, exp->gdbarch,
				    "char16_t", NULL, 0);
	    break;
	  case C_STRING_32:
	    type = lookup_typename (exp->language_defn, exp->gdbarch,
				    "char32_t", NULL, 0);
	    break;
	  default:
	    internal_error (__FILE__, __LINE__, _("unhandled c_string_type"));
	  }

	/* Ensure TYPE_LENGTH is valid for TYPE.  */
	check_typedef (type);

	/* If the caller expects an array of some integral type,
	   satisfy them.  If something odder is expected, rely on the
	   caller to cast.  */
	if (expect_type && TYPE_CODE (expect_type) == TYPE_CODE_ARRAY)
	  {
	    struct type *element_type
	      = check_typedef (TYPE_TARGET_TYPE (expect_type));

	    if (TYPE_CODE (element_type) == TYPE_CODE_INT
		|| TYPE_CODE (element_type) == TYPE_CODE_CHAR)
	      {
		type = element_type;
		satisfy_expected = 1;
	      }
	  }

	dest_charset = charset_for_string_type (dest_type, exp->gdbarch);

	++*pos;
	while (*pos < limit)
	  {
	    int len;

	    len = longest_to_int (exp->elts[*pos].longconst);

	    ++*pos;
	    if (noside != EVAL_SKIP)
	      parse_one_string (&output, &exp->elts[*pos].string, len,
				dest_charset, type);
	    *pos += BYTES_TO_EXP_ELEM (len);
	  }

	/* Skip the trailing length and opcode.  */
	*pos += 2;

	if (noside == EVAL_SKIP)
	  {
	    /* Return a dummy value of the appropriate type.  */
	    if (expect_type != NULL)
	      result = allocate_value (expect_type);
	    else if ((dest_type & C_CHAR) != 0)
	      result = allocate_value (type);
	    else
	      result = value_cstring ("", 0, type);
	    do_cleanups (cleanup);
	    return result;
	  }

	if ((dest_type & C_CHAR) != 0)
	  {
	    LONGEST value;

	    if (obstack_object_size (&output) != TYPE_LENGTH (type))
	      error (_("Could not convert character "
		       "constant to target character set"));
	    value = unpack_long (type, (gdb_byte *) obstack_base (&output));
	    result = value_from_longest (type, value);
	  }
	else
	  {
	    int i;

	    /* Write the terminating character.  */
	    for (i = 0; i < TYPE_LENGTH (type); ++i)
	      obstack_1grow (&output, 0);

	    if (satisfy_expected)
	      {
		LONGEST low_bound, high_bound;
		int element_size = TYPE_LENGTH (type);

		if (get_discrete_bounds (TYPE_INDEX_TYPE (expect_type),
					 &low_bound, &high_bound) < 0)
		  {
		    low_bound = 0;
		    high_bound = (TYPE_LENGTH (expect_type) / element_size) - 1;
		  }
		if (obstack_object_size (&output) / element_size
		    > (high_bound - low_bound + 1))
		  error (_("Too many array elements"));

		result = allocate_value (expect_type);
		memcpy (value_contents_raw (result), obstack_base (&output),
			obstack_object_size (&output));
	      }
	    else
	      result = value_cstring (obstack_base (&output),
				      obstack_object_size (&output),
				      type);
	  }
	do_cleanups (cleanup);
	return result;
      }
      break;

    default:
      break;
    }
  return evaluate_subexp_standard (expect_type, exp, pos, noside);
}
void
c_printstr (struct ui_file *stream, struct type *type, const gdb_byte *string,
	    unsigned int length, const char *user_encoding, int force_ellipses,
	    const struct value_print_options *options)
{
  enum bfd_endian byte_order = gdbarch_byte_order (get_type_arch (type));
  unsigned int i;
  unsigned int things_printed = 0;
  int in_quotes = 0;
  int need_comma = 0;
  int width = TYPE_LENGTH (type);
  struct obstack wchar_buf, output;
  struct cleanup *cleanup;
  enum c_string_type str_type;
  const char *type_encoding;
  const char *encoding;
  struct wchar_iterator *iter;
  int finished = 0;
  int need_escape = 0;

  if (length == -1)
    {
      unsigned long current_char = 1;

      for (i = 0; current_char; ++i)
	{
	  QUIT;
	  current_char = extract_unsigned_integer (string + i * width,
						   width, byte_order);
	}
      length = i;
    }

  /* If the string was not truncated due to `set print elements', and
     the last byte of it is a null, we don't print that, in traditional C
     style.  */
  if (!force_ellipses
      && length > 0
      && (extract_unsigned_integer (string + (length - 1) * width,
				    width, byte_order) == 0))
    length--;

  str_type = (classify_type (type, get_type_arch (type), &type_encoding)
	      & ~C_CHAR);
  switch (str_type)
    {
    case C_STRING:
      break;
    case C_WIDE_STRING:
      fputs_filtered ("L", stream);
      break;
    case C_STRING_16:
      fputs_filtered ("u", stream);
      break;
    case C_STRING_32:
      fputs_filtered ("U", stream);
      break;
    }

  encoding = (user_encoding && *user_encoding) ? user_encoding : type_encoding;

  if (length == 0)
    {
      fputs_filtered ("\"\"", stream);
      return;
    }

  /* Arrange to iterate over the characters, in wchar_t form.  */
  iter = make_wchar_iterator (string, length * width, encoding, width);
  cleanup = make_cleanup_wchar_iterator (iter);

  /* WCHAR_BUF is the obstack we use to represent the string in
     wchar_t form.  */
  obstack_init (&wchar_buf);
  make_cleanup_obstack_free (&wchar_buf);

  while (!finished && things_printed < options->print_max)
    {
      int num_chars;
      enum wchar_iterate_result result;
      gdb_wchar_t *chars;
      const gdb_byte *buf;
      size_t buflen;

      QUIT;

      if (need_comma)
	{
	  obstack_grow_wstr (&wchar_buf, LCST (", "));
	  need_comma = 0;
	}

      num_chars = wchar_iterate (iter, &result, &chars, &buf, &buflen);
      /* We only look at repetitions when we were able to convert a
	 single character in isolation.  This makes the code simpler
	 and probably does the sensible thing in the majority of
	 cases.  */
      while (num_chars == 1 && things_printed < options->print_max)
	{
	  /* Count the number of repetitions.  */
	  unsigned int reps = 0;
	  gdb_wchar_t current_char = chars[0];
	  const gdb_byte *orig_buf = buf;
	  int orig_len = buflen;

	  if (need_comma)
	    {
	      obstack_grow_wstr (&wchar_buf, LCST (", "));
	      need_comma = 0;
	    }

	  while (num_chars == 1 && current_char == chars[0])
	    {
	      num_chars = wchar_iterate (iter, &result, &chars, &buf, &buflen);
	      ++reps;
	    }

	  /* Emit CURRENT_CHAR according to the repetition count and
	     options.  */
	  if (reps > options->repeat_count_threshold)
	    {
	      if (in_quotes)
		{
		  if (options->inspect_it)
		    obstack_grow_wstr (&wchar_buf, LCST ("\\\", "));
		  else
		    obstack_grow_wstr (&wchar_buf, LCST ("\", "));
		  in_quotes = 0;
		}
	      obstack_grow_wstr (&wchar_buf, LCST ("'"));
	      need_escape = 0;
	      print_wchar (current_char, orig_buf, orig_len, width,
			   byte_order, &wchar_buf, '\'', &need_escape);
	      obstack_grow_wstr (&wchar_buf, LCST ("'"));
	      {
		/* Painful gyrations.  */
		int j;
		char *s = xstrprintf (_(" <repeats %u times>"), reps);

		for (j = 0; s[j]; ++j)
		  {
		    gdb_wchar_t w = gdb_btowc (s[j]);
		    obstack_grow (&wchar_buf, &w, sizeof (gdb_wchar_t));
		  }
		xfree (s);
	      }
	      things_printed += options->repeat_count_threshold;
	      need_comma = 1;
	    }
	  else
	    {
	      /* Saw the character one or more times, but fewer than
		 the repetition threshold.  */
	      if (!in_quotes)
		{
		  if (options->inspect_it)
		    obstack_grow_wstr (&wchar_buf, LCST ("\\\""));
		  else
		    obstack_grow_wstr (&wchar_buf, LCST ("\""));
		  in_quotes = 1;
		  need_escape = 0;
		}

	      while (reps-- > 0)
		{
		  print_wchar (current_char, orig_buf, orig_len, width,
			       byte_order, &wchar_buf, '"', &need_escape);
		  ++things_printed;
		}
	    }
	}

      /* NUM_CHARS and the other outputs from wchar_iterate are valid
	 here regardless of which branch was taken above.  */
      if (num_chars < 0)
	{
	  /* Hit EOF.  */
	  finished = 1;
	  break;
	}

      switch (result)
	{
	case wchar_iterate_invalid:
	  if (!in_quotes)
	    {
	      if (options->inspect_it)
		obstack_grow_wstr (&wchar_buf, LCST ("\\\""));
	      else
		obstack_grow_wstr (&wchar_buf, LCST ("\""));
	      in_quotes = 1;
	    }
	  need_escape = 0;
	  print_wchar (gdb_WEOF, buf, buflen, width, byte_order, &wchar_buf,
		       '"', &need_escape);
	  break;

	case wchar_iterate_incomplete:
	  if (in_quotes)
	    {
	      if (options->inspect_it)
		obstack_grow_wstr (&wchar_buf, LCST ("\\\","));
	      else
		obstack_grow_wstr (&wchar_buf, LCST ("\","));
	      in_quotes = 0;
	    }
	  obstack_grow_wstr (&wchar_buf, LCST (" <incomplete sequence "));
	  print_wchar (gdb_WEOF, buf, buflen, width, byte_order, &wchar_buf,
		       0, &need_escape);
	  obstack_grow_wstr (&wchar_buf, LCST (">"));
	  finished = 1;
	  break;
	}
    }

  /* Terminate the quotes if necessary.  */
  if (in_quotes)
    {
      if (options->inspect_it)
	obstack_grow_wstr (&wchar_buf, LCST ("\\\""));
      else
	obstack_grow_wstr (&wchar_buf, LCST ("\""));
    }

  if (force_ellipses || !finished)
    obstack_grow_wstr (&wchar_buf, LCST ("..."));

  /* OUTPUT is where we collect `char's for printing.  */
  obstack_init (&output);
  make_cleanup_obstack_free (&output);

  convert_between_encodings (INTERMEDIATE_ENCODING, host_charset (),
			     obstack_base (&wchar_buf),
			     obstack_object_size (&wchar_buf),
			     1, &output, translit_char);
  obstack_1grow (&output, '\0');

  fputs_filtered (obstack_base (&output), stream);

  do_cleanups (cleanup);
}
static struct value *
evaluate_subexp_c (struct type *expect_type, struct expression *exp,
		   int *pos, enum noside noside)
{
  enum exp_opcode op = exp->elts[*pos].opcode;

  switch (op)
    {
    case OP_STRING:
      {
	int oplen, limit;
	struct type *type;
	struct obstack output;
	struct cleanup *cleanup;
	struct value *result;
	enum c_string_type dest_type;
	const char *dest_charset;

	obstack_init (&output);
	cleanup = make_cleanup_obstack_free (&output);

	++*pos;
	oplen = longest_to_int (exp->elts[*pos].longconst);

	++*pos;
	limit = *pos + BYTES_TO_EXP_ELEM (oplen + 1);
	dest_type
	  = (enum c_string_type) longest_to_int (exp->elts[*pos].longconst);
	switch (dest_type & ~C_CHAR)
	  {
	  case C_STRING:
	    type = language_string_char_type (exp->language_defn,
					      exp->gdbarch);
	    break;
	  case C_WIDE_STRING:
	    type = lookup_typename (exp->language_defn, exp->gdbarch,
				    "wchar_t", NULL, 0);
	    break;
	  case C_STRING_16:
	    type = lookup_typename (exp->language_defn, exp->gdbarch,
				    "char16_t", NULL, 0);
	    break;
	  case C_STRING_32:
	    type = lookup_typename (exp->language_defn, exp->gdbarch,
				    "char32_t", NULL, 0);
	    break;
	  default:
	    internal_error (__FILE__, __LINE__, "unhandled c_string_type");
	  }

	/* Ensure TYPE_LENGTH is valid for TYPE.  */
	check_typedef (type);

	dest_charset = charset_for_string_type (dest_type, exp->gdbarch);

	++*pos;
	while (*pos < limit)
	  {
	    int len;

	    len = longest_to_int (exp->elts[*pos].longconst);

	    ++*pos;
	    if (noside != EVAL_SKIP)
	      parse_one_string (&output, &exp->elts[*pos].string, len,
				dest_charset, type);
	    *pos += BYTES_TO_EXP_ELEM (len);
	  }

	/* Skip the trailing length and opcode.  */
	*pos += 2;

	if (noside == EVAL_SKIP)
	  {
	    /* Return a dummy value of the appropriate type.  */
	    if ((dest_type & C_CHAR) != 0)
	      result = allocate_value (type);
	    else
	      result = value_cstring ("", 0, type);
	    do_cleanups (cleanup);
	    return result;
	  }

	if ((dest_type & C_CHAR) != 0)
	  {
	    LONGEST value;

	    if (obstack_object_size (&output) != TYPE_LENGTH (type))
	      error (_("Could not convert character constant to target character set"));
	    value = unpack_long (type, obstack_base (&output));
	    result = value_from_longest (type, value);
	  }
	else
	  {
	    int i;

	    /* Write the terminating character.  */
	    for (i = 0; i < TYPE_LENGTH (type); ++i)
	      obstack_1grow (&output, 0);
	    result = value_cstring (obstack_base (&output),
				    obstack_object_size (&output),
				    type);
	  }
	do_cleanups (cleanup);
	return result;
      }
      break;

    default:
      break;
    }
  return evaluate_subexp_standard (expect_type, exp, pos, noside);
}
void
c_emit_char (int c, struct type *type,
	     struct ui_file *stream, int quoter)
{
  enum bfd_endian byte_order = gdbarch_byte_order (get_type_arch (type));
  struct obstack wchar_buf, output;
  struct cleanup *cleanups;
  const char *encoding;
  gdb_byte *buf;
  struct wchar_iterator *iter;
  int need_escape = 0;

  classify_type (type, get_type_arch (type), &encoding);

  buf = alloca (TYPE_LENGTH (type));
  pack_long (buf, type, c);

  iter = make_wchar_iterator (buf, TYPE_LENGTH (type), encoding,
			      TYPE_LENGTH (type));
  cleanups = make_cleanup_wchar_iterator (iter);

  /* This holds the printable form of the wchar_t data.  */
  obstack_init (&wchar_buf);
  make_cleanup_obstack_free (&wchar_buf);

  while (1)
    {
      int num_chars;
      gdb_wchar_t *chars;
      const gdb_byte *buf;
      size_t buflen;
      int print_escape = 1;
      enum wchar_iterate_result result;

      num_chars = wchar_iterate (iter, &result, &chars, &buf, &buflen);
      if (num_chars < 0)
	break;
      if (num_chars > 0)
	{
	  /* If all characters are printable, print them.  Otherwise,
	     we're going to have to print an escape sequence.  We
	     check all characters because we want to print the target
	     bytes in the escape sequence, and we don't know character
	     boundaries there.  */
	  int i;

	  print_escape = 0;
	  for (i = 0; i < num_chars; ++i)
	    if (!wchar_printable (chars[i]))
	      {
		print_escape = 1;
		break;
	      }

	  if (!print_escape)
	    {
	      for (i = 0; i < num_chars; ++i)
		print_wchar (chars[i], buf, buflen, TYPE_LENGTH (type),
			     byte_order, &wchar_buf, quoter, &need_escape);
	    }
	}

      /* This handles the NUM_CHARS == 0 case as well.  */
      if (print_escape)
	print_wchar (gdb_WEOF, buf, buflen, TYPE_LENGTH (type), byte_order,
		     &wchar_buf, quoter, &need_escape);
    }

  /* The output in the host encoding.  */
  obstack_init (&output);
  make_cleanup_obstack_free (&output);

  convert_between_encodings (INTERMEDIATE_ENCODING, host_charset (),
			     obstack_base (&wchar_buf),
			     obstack_object_size (&wchar_buf),
			     1, &output, translit_char);
  obstack_1grow (&output, '\0');

  fputs_filtered (obstack_base (&output), stream);

  do_cleanups (cleanups);
}