Esempio n. 1
0
void	add_prec_wchar(t_wc *wc, t_infos *infos, wchar_t *ws)
{
	if (infos->prec > 0)
	{
		if (infos->prec > 1)
			while (wc->ret < infos->prec - 1)
				wc->ret += print_wchar(ws[wc->i++]);
		else if (infos->prec == 1)
		{
			while (wc->ret < infos->prec)
				wc->ret += print_wchar(ws[wc->i++]);
		}
	}
	else
		while (ws[wc->i])
			wc->ret += print_wchar(ws[wc->i++]);
}
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);
}
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);
}
Esempio n. 4
0
void	arg_is_wchar(t_flags *flags, va_list list, int *i)
{
	(void)flags;
	print_wchar(list, i);
}