/* Character set conversion support for GDB.

   Copyright (C) 2001, 2003, 2007, 2008, 2009 Free Software Foundation, Inc.

   This file is part of GDB.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 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 of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

#include "defs.h"
#include "charset.h"
#include "gdbcmd.h"
#include "gdb_assert.h"
#include "gdb_obstack.h"
#include "gdb_wait.h"
#include "charset-list.h"
#include "vec.h"

#include <stddef.h>
#include "gdb_string.h"
#include <ctype.h>


/* How GDB's character set support works

   GDB has three global settings:

   - The `current host character set' is the character set GDB should
     use in talking to the user, and which (hopefully) the user's
     terminal knows how to display properly.  Most users should not
     change this.

   - The `current target character set' is the character set the
     program being debugged uses.

   - The `current target wide character set' is the wide character set
     the program being debugged uses, that is, the encoding used for
     wchar_t.

   There are commands to set each of these, and mechanisms for
   choosing reasonable default values.  GDB has a global list of
   character sets that it can use as its host or target character
   sets.

   The header file `charset.h' declares various functions that
   different pieces of GDB need to perform tasks like:

   - printing target strings and characters to the user's terminal
     (mostly target->host conversions),

   - building target-appropriate representations of strings and
     characters the user enters in expressions (mostly host->target
     conversions),

     and so on.
     
   To avoid excessive code duplication and maintenance efforts,
   GDB simply requires a capable iconv function.  Users on platforms
   without a suitable iconv can use the GNU iconv library.  */


#ifdef PHONY_ICONV

/* Provide a phony iconv that does as little as possible.  Also,
   arrange for there to be a single available character set.  */

#undef GDB_DEFAULT_HOST_CHARSET
#define GDB_DEFAULT_HOST_CHARSET "ISO-8859-1"
#define GDB_DEFAULT_TARGET_CHARSET "ISO-8859-1"
#define GDB_DEFAULT_TARGET_WIDE_CHARSET "ISO-8859-1"
#undef DEFAULT_CHARSET_NAMES
#define DEFAULT_CHARSET_NAMES GDB_DEFAULT_HOST_CHARSET ,

#undef iconv_t
#define iconv_t int
#undef iconv_open
#undef iconv
#undef iconv_close

#undef ICONV_CONST
#define ICONV_CONST const

/* Some systems don't have EILSEQ, so we define it here, but not as
   EINVAL, because callers of `iconv' want to distinguish EINVAL and
   EILSEQ.  This is what iconv.h from libiconv does as well.  Note
   that wchar.h may also define EILSEQ, so this needs to be after we
   include wchar.h, which happens in defs.h through gdb_wchar.h.  */
#ifndef EILSEQ
#define EILSEQ ENOENT
#endif

iconv_t
iconv_open (const char *to, const char *from)
{
  /* We allow conversions from UTF-32BE, wchar_t, and the host charset.
     We allow conversions to wchar_t and the host charset.  */
  if (strcmp (from, "UTF-32BE") && strcmp (from, "wchar_t")
      && strcmp (from, GDB_DEFAULT_HOST_CHARSET))
    return -1;
  if (strcmp (to, "wchar_t") && strcmp (to, GDB_DEFAULT_HOST_CHARSET))
    return -1;

  /* Return 1 if we are converting from UTF-32BE, 0 otherwise.  This is
     used as a flag in calls to iconv.  */
  return !strcmp (from, "UTF-32BE");
}

int
iconv_close (iconv_t arg)
{
  return 0;
}

size_t
iconv (iconv_t utf_flag, const char **inbuf, size_t *inbytesleft,
       char **outbuf, size_t *outbytesleft)
{
  if (utf_flag)
    {
      while (*inbytesleft >= 4)
	{
	  size_t j;
	  unsigned long c = 0;

	  for (j = 0; j < 4; ++j)
	    {
	      c <<= 8;
	      c += (*inbuf)[j] & 0xff;
	    }

	  if (c >= 256)
	    {
	      errno = EILSEQ;
	      return -1;
	    }
	  **outbuf = c & 0xff;
	  ++*outbuf;
	  --*outbytesleft;

	  ++*inbuf;
	  *inbytesleft -= 4;
	}
      if (*inbytesleft < 4)
	{
	  errno = EINVAL;
	  return -1;
	}
    }
  else
    {
      /* In all other cases we simply copy input bytes to the
	 output.  */
      size_t amt = *inbytesleft;
      if (amt > *outbytesleft)
	amt = *outbytesleft;
      memcpy (*outbuf, *inbuf, amt);
      *inbuf += amt;
      *outbuf += amt;
      *inbytesleft -= amt;
      *outbytesleft -= amt;
    }

  if (*inbytesleft)
    {
      errno = E2BIG;
      return -1;
    }

  /* The number of non-reversible conversions -- but they were all
     reversible.  */
  return 0;
}

#endif



/* The global lists of character sets and translations.  */


#ifndef GDB_DEFAULT_TARGET_CHARSET
#define GDB_DEFAULT_TARGET_CHARSET "ISO-8859-1"
#endif

#ifndef GDB_DEFAULT_TARGET_WIDE_CHARSET
#define GDB_DEFAULT_TARGET_WIDE_CHARSET "UTF-32"
#endif

static const char *auto_host_charset_name = GDB_DEFAULT_HOST_CHARSET;
static const char *host_charset_name = "auto";
static void
show_host_charset_name (struct ui_file *file, int from_tty,
			struct cmd_list_element *c,
			const char *value)
{
  if (!strcmp (value, "auto"))
    fprintf_filtered (file,
		      _("The host character set is \"auto; currently %s\".\n"),
		      auto_host_charset_name);
  else
    fprintf_filtered (file, _("The host character set is \"%s\".\n"), value);
}

static const char *target_charset_name = GDB_DEFAULT_TARGET_CHARSET;
static void
show_target_charset_name (struct ui_file *file, int from_tty,
			  struct cmd_list_element *c, const char *value)
{
  fprintf_filtered (file, _("The target character set is \"%s\".\n"),
		    value);
}

static const char *target_wide_charset_name = GDB_DEFAULT_TARGET_WIDE_CHARSET;
static void
show_target_wide_charset_name (struct ui_file *file, int from_tty,
			       struct cmd_list_element *c, const char *value)
{
  fprintf_filtered (file, _("The target wide character set is \"%s\".\n"),
		    value);
}

static const char *default_charset_names[] =
{
  DEFAULT_CHARSET_NAMES
  0
};

static const char **charset_enum;


/* If the target wide character set has big- or little-endian
   variants, these are the corresponding names.  */
static const char *target_wide_charset_be_name;
static const char *target_wide_charset_le_name;

/* A helper function for validate which sets the target wide big- and
   little-endian character set names, if possible.  */

static void
set_be_le_names (void)
{
  int i, len;

  target_wide_charset_le_name = NULL;
  target_wide_charset_be_name = NULL;

  len = strlen (target_wide_charset_name);
  for (i = 0; charset_enum[i]; ++i)
    {
      if (strncmp (target_wide_charset_name, charset_enum[i], len))
	continue;
      if ((charset_enum[i][len] == 'B'
	   || charset_enum[i][len] == 'L')
	  && charset_enum[i][len + 1] == 'E'
	  && charset_enum[i][len + 2] == '\0')
	{
	  if (charset_enum[i][len] == 'B')
	    target_wide_charset_be_name = charset_enum[i];
	  else
	    target_wide_charset_le_name = charset_enum[i];
	}
    }
}

/* 'Set charset', 'set host-charset', 'set target-charset', 'set
   target-wide-charset', 'set charset' sfunc's.  */

static void
validate (void)
{
  iconv_t desc;
  const char *host_cset = host_charset ();

  desc = iconv_open (target_wide_charset_name, host_cset);
  if (desc == (iconv_t) -1)
    error ("Cannot convert between character sets `%s' and `%s'",
	   target_wide_charset_name, host_cset);
  iconv_close (desc);

  desc = iconv_open (target_charset_name, host_cset);
  if (desc == (iconv_t) -1)
    error ("Cannot convert between character sets `%s' and `%s'",
	   target_charset_name, host_cset);
  iconv_close (desc);

  set_be_le_names ();
}

/* This is the sfunc for the 'set charset' command.  */
static void
set_charset_sfunc (char *charset, int from_tty, struct cmd_list_element *c)
{
  /* CAREFUL: set the target charset here as well. */
  target_charset_name = host_charset_name;
  validate ();
}

/* 'set host-charset' command sfunc.  We need a wrapper here because
   the function needs to have a specific signature.  */
static void
set_host_charset_sfunc (char *charset, int from_tty,
			struct cmd_list_element *c)
{
  validate ();
}

/* Wrapper for the 'set target-charset' command.  */
static void
set_target_charset_sfunc (char *charset, int from_tty,
			  struct cmd_list_element *c)
{
  validate ();
}

/* Wrapper for the 'set target-wide-charset' command.  */
static void
set_target_wide_charset_sfunc (char *charset, int from_tty,
			       struct cmd_list_element *c)
{
  validate ();
}

/* sfunc for the 'show charset' command.  */
static void
show_charset (struct ui_file *file, int from_tty, struct cmd_list_element *c,
	      const char *name)
{
  show_host_charset_name (file, from_tty, c, host_charset_name);
  show_target_charset_name (file, from_tty, c, target_charset_name);
  show_target_wide_charset_name (file, from_tty, c, target_wide_charset_name);
}


/* Accessor functions.  */

const char *
host_charset (void)
{
  if (!strcmp (host_charset_name, "auto"))
    return auto_host_charset_name;
  return host_charset_name;
}

const char *
target_charset (void)
{
  return target_charset_name;
}

const char *
target_wide_charset (enum bfd_endian byte_order)
{
  if (byte_order == BFD_ENDIAN_BIG)
    {
      if (target_wide_charset_be_name)
	return target_wide_charset_be_name;
    }
  else
    {
      if (target_wide_charset_le_name)
	return target_wide_charset_le_name;
    }

  return target_wide_charset_name;
}


/* Host character set management.  For the time being, we assume that
   the host character set is some superset of ASCII.  */

char
host_letter_to_control_character (char c)
{
  if (c == '?')
    return 0177;
  return c & 0237;
}

/* Convert a host character, C, to its hex value.  C must already have
   been validated using isxdigit.  */

int
host_hex_value (char c)
{
  if (isdigit (c))
    return c - '0';
  if (c >= 'a' && c <= 'f')
    return 10 + c - 'a';
  gdb_assert (c >= 'A' && c <= 'F');
  return 10 + c - 'A';
}


/* Public character management functions.  */

/* A cleanup function which is run to close an iconv descriptor.  */

static void
cleanup_iconv (void *p)
{
  iconv_t *descp = p;
  iconv_close (*descp);
}

void
convert_between_encodings (const char *from, const char *to,
			   const gdb_byte *bytes, unsigned int num_bytes,
			   int width, struct obstack *output,
			   enum transliterations translit)
{
  iconv_t desc;
  struct cleanup *cleanups;
  size_t inleft;
  char *inp;
  unsigned int space_request;

  /* Often, the host and target charsets will be the same.  */
  if (!strcmp (from, to))
    {
      obstack_grow (output, bytes, num_bytes);
      return;
    }

  desc = iconv_open (to, from);
  if (desc == (iconv_t) -1)
    perror_with_name ("Converting character sets");
  cleanups = make_cleanup (cleanup_iconv, &desc);

  inleft = num_bytes;
  inp = (char *) bytes;

  space_request = num_bytes;

  while (inleft > 0)
    {
      char *outp;
      size_t outleft, r;
      int old_size;

      old_size = obstack_object_size (output);
      obstack_blank (output, space_request);

      outp = obstack_base (output) + old_size;
      outleft = space_request;

      r = iconv (desc, (ICONV_CONST char **) &inp, &inleft, &outp, &outleft);

      /* Now make sure that the object on the obstack only includes
	 bytes we have converted.  */
      obstack_blank (output, - (int) outleft);

      if (r == (size_t) -1)
	{
	  switch (errno)
	    {
	    case EILSEQ:
	      {
		int i;

		/* Invalid input sequence.  */
		if (translit == translit_none)
		  error (_("Could not convert character to `%s' character set"),
			 to);

		/* We emit escape sequence for the bytes, skip them,
		   and try again.  */
		for (i = 0; i < width; ++i)
		  {
		    char octal[5];

		    sprintf (octal, "\\%.3o", *inp & 0xff);
		    obstack_grow_str (output, octal);

		    ++inp;
		    --inleft;
		  }
	      }
	      break;

	    case E2BIG:
	      /* We ran out of space in the output buffer.  Make it
		 bigger next time around.  */
	      space_request *= 2;
	      break;

	    case EINVAL:
	      /* Incomplete input sequence.  FIXME: ought to report this
		 to the caller somehow.  */
	      inleft = 0;
	      break;

	    default:
	      perror_with_name ("Internal error while converting character sets");
	    }
	}
    }

  do_cleanups (cleanups);
}



/* An iterator that returns host wchar_t's from a target string.  */
struct wchar_iterator
{
  /* The underlying iconv descriptor.  */
  iconv_t desc;

  /* The input string.  This is updated as convert characters.  */
  char *input;
  /* The number of bytes remaining in the input.  */
  size_t bytes;

  /* The width of an input character.  */
  size_t width;

  /* The output buffer and its size.  */
  gdb_wchar_t *out;
  size_t out_size;
};

/* Create a new iterator.  */
struct wchar_iterator *
make_wchar_iterator (const gdb_byte *input, size_t bytes, const char *charset,
		     size_t width)
{
  struct wchar_iterator *result;
  iconv_t desc;

  desc = iconv_open (INTERMEDIATE_ENCODING, charset);
  if (desc == (iconv_t) -1)
    perror_with_name ("Converting character sets");

  result = XNEW (struct wchar_iterator);
  result->desc = desc;
  result->input = (char *) input;
  result->bytes = bytes;
  result->width = width;

  result->out = XNEW (gdb_wchar_t);
  result->out_size = 1;

  return result;
}

static void
do_cleanup_iterator (void *p)
{
  struct wchar_iterator *iter = p;

  iconv_close (iter->desc);
  xfree (iter->out);
  xfree (iter);
}

struct cleanup *
make_cleanup_wchar_iterator (struct wchar_iterator *iter)
{
  return make_cleanup (do_cleanup_iterator, iter);
}

int
wchar_iterate (struct wchar_iterator *iter,
	       enum wchar_iterate_result *out_result,
	       gdb_wchar_t **out_chars,
	       const gdb_byte **ptr,
	       size_t *len)
{
  size_t out_request;

  /* Try to convert some characters.  At first we try to convert just
     a single character.  The reason for this is that iconv does not
     necessarily update its outgoing arguments when it encounters an
     invalid input sequence -- but we want to reliably report this to
     our caller so it can emit an escape sequence.  */
  out_request = 1;
  while (iter->bytes > 0)
    {
      char *outptr = (char *) &iter->out[0];
      char *orig_inptr = iter->input;
      size_t orig_in = iter->bytes;
      size_t out_avail = out_request * sizeof (gdb_wchar_t);
      size_t num;
      gdb_wchar_t result;

      size_t r = iconv (iter->desc,
			(ICONV_CONST char **) &iter->input, &iter->bytes,
			&outptr, &out_avail);
      if (r == (size_t) -1)
	{
	  switch (errno)
	    {
	    case EILSEQ:
	      /* Invalid input sequence.  Skip it, and let the caller
		 know about it.  */
	      *out_result = wchar_iterate_invalid;
	      *ptr = iter->input;
	      *len = iter->width;
	      iter->input += iter->width;
	      iter->bytes -= iter->width;
	      return 0;

	    case E2BIG:
	      /* We ran out of space.  We still might have converted a
		 character; if so, return it.  Otherwise, grow the
		 buffer and try again.  */
	      if (out_avail < out_request * sizeof (gdb_wchar_t))
		break;

	      ++out_request;
	      if (out_request > iter->out_size)
		{
		  iter->out_size = out_request;
		  iter->out = xrealloc (iter->out,
					out_request * sizeof (gdb_wchar_t));
		}
	      continue;

	    case EINVAL:
	      /* Incomplete input sequence.  Let the caller know, and
		 arrange for future calls to see EOF.  */
	      *out_result = wchar_iterate_incomplete;
	      *ptr = iter->input;
	      *len = iter->bytes;
	      iter->bytes = 0;
	      return 0;

	    default:
	      perror_with_name ("Internal error while converting character sets");
	    }
	}

      /* We converted something.  */
      num = out_request - out_avail / sizeof (gdb_wchar_t);
      *out_result = wchar_iterate_ok;
      *out_chars = iter->out;
      *ptr = orig_inptr;
      *len = orig_in - iter->bytes;
      return num;
    }

  /* Really done.  */
  *out_result = wchar_iterate_eof;
  return -1;
}


/* The charset.c module initialization function.  */

extern initialize_file_ftype _initialize_charset; /* -Wmissing-prototype */

typedef char *char_ptr;
DEF_VEC_P (char_ptr);

static VEC (char_ptr) *charsets;

#ifdef PHONY_ICONV

static void
find_charset_names (void)
{
  VEC_safe_push (char_ptr, charsets, GDB_DEFAULT_HOST_CHARSET);
  VEC_safe_push (char_ptr, charsets, NULL);
}

#else /* PHONY_ICONV */

/* Sometimes, libiconv redefines iconvlist as libiconvlist -- but
   provides different symbols in the static and dynamic libraries.
   So, configure may see libiconvlist but not iconvlist.  But, calling
   iconvlist is the right thing to do and will work.  Hence we do a
   check here but unconditionally call iconvlist below.  */
#if defined (HAVE_ICONVLIST) || defined (HAVE_LIBICONVLIST)

/* A helper function that adds some character sets to the vector of
   all character sets.  This is a callback function for iconvlist.  */

static int
add_one (unsigned int count, const char *const *names, void *data)
{
  unsigned int i;

  for (i = 0; i < count; ++i)
    VEC_safe_push (char_ptr, charsets, xstrdup (names[i]));

  return 0;
}

static void
find_charset_names (void)
{
  iconvlist (add_one, NULL);
  VEC_safe_push (char_ptr, charsets, NULL);
}

#else

static void
find_charset_names (void)
{
  struct pex_obj *child;
  char *args[3];
  int err, status;
  int fail = 1;

  child = pex_init (0, "iconv", NULL);

  args[0] = "iconv";
  args[1] = "-l";
  args[2] = NULL;
  /* Note that we simply ignore errors here.  */
  if (!pex_run (child, PEX_SEARCH | PEX_STDERR_TO_STDOUT, "iconv",
		args, NULL, NULL, &err))
    {
      FILE *in = pex_read_output (child, 0);

      /* POSIX says that iconv -l uses an unspecified format.  We
	 parse the glibc and libiconv formats; feel free to add others
	 as needed.  */
      while (!feof (in))
	{
	  /* The size of buf is chosen arbitrarily.  */
	  char buf[1024];
	  char *start, *r;
	  int len, keep_going;

	  r = fgets (buf, sizeof (buf), in);
	  if (!r)
	    break;
	  len = strlen (r);
	  if (len <= 3)
	    continue;
	  /* Strip off the newline.  */
	  --len;
	  /* Strip off one or two '/'s.  glibc will print lines like
	     "8859_7//", but also "10646-1:1993/UCS4/".  */
	  if (buf[len - 1] == '/')
	    --len;
	  if (buf[len - 1] == '/')
	    --len;
	  buf[len] = '\0';

	  /* libiconv will print multiple entries per line, separated
	     by spaces.  */
	  start = buf;
	  while (1)
	    {
	      int keep_going;
	      char *p;

	      /* Find the next space, or end-of-line.  */
	      for (p = start; *p && *p != ' '; ++p)
		;
	      /* Ignore an empty result.  */
	      if (p == start)
		break;
	      keep_going = *p;
	      *p = '\0';
	      VEC_safe_push (char_ptr, charsets, xstrdup (start));
	      if (!keep_going)
		break;
	      /* Skip any extra spaces.  */
	      for (start = p + 1; *start && *start == ' '; ++start)
		;
	    }
	}

      if (pex_get_status (child, 1, &status)
	  && WIFEXITED (status) && !WEXITSTATUS (status))
	fail = 0;

    }

  pex_free (child);

  if (fail)
    {
      /* Some error occurred, so drop the vector.  */
      int ix;
      char *elt;
      for (ix = 0; VEC_iterate (char_ptr, charsets, ix, elt); ++ix)
	xfree (elt);
      VEC_truncate (char_ptr, charsets, 0);
    }
  else
    VEC_safe_push (char_ptr, charsets, NULL);
}

#endif /* HAVE_ICONVLIST || HAVE_LIBICONVLIST */
#endif /* PHONY_ICONV */

void
_initialize_charset (void)
{
  struct cmd_list_element *new_cmd;

  /* The first element is always "auto"; then we skip it for the
     commands where it is not allowed.  */
  VEC_safe_push (char_ptr, charsets, xstrdup ("auto"));
  find_charset_names ();

  if (VEC_length (char_ptr, charsets) > 1)
    charset_enum = (const char **) VEC_address (char_ptr, charsets);
  else
    charset_enum = default_charset_names;

#ifndef PHONY_ICONV
#ifdef HAVE_LANGINFO_CODESET
  auto_host_charset_name = nl_langinfo (CODESET);
  /* Solaris will return `646' here -- but the Solaris iconv then
     does not accept this.  */
  if (!strcmp (auto_host_charset_name, "646"))
    auto_host_charset_name = "ASCII";
  target_charset_name = auto_host_charset_name;

  set_be_le_names ();
#endif
#endif

  add_setshow_enum_cmd ("charset", class_support,
			&charset_enum[1], &host_charset_name, _("\
Set the host and target character sets."), _("\
Show the host and target character sets."), _("\
The `host character set' is the one used by the system GDB is running on.\n\
The `target character set' is the one used by the program being debugged.\n\
You may only use supersets of ASCII for your host character set; GDB does\n\
not support any others.\n\
To see a list of the character sets GDB supports, type `set charset <TAB>'."),
			/* Note that the sfunc below needs to set
			   target_charset_name, because the 'set
			   charset' command sets two variables.  */
			set_charset_sfunc,
			show_charset,
			&setlist, &showlist);

  add_setshow_enum_cmd ("host-charset", class_support,
			charset_enum, &host_charset_name, _("\
Set the host character set."), _("\
Show the host character set."), _("\
The `host character set' is the one used by the system GDB is running on.\n\
You may only use supersets of ASCII for your host character set; GDB does\n\
not support any others.\n\
To see a list of the character sets GDB supports, type `set host-charset <TAB>'."),
			set_host_charset_sfunc,
			show_host_charset_name,
			&setlist, &showlist);

  add_setshow_enum_cmd ("target-charset", class_support,
			&charset_enum[1], &target_charset_name, _("\
Set the target character set."), _("\
Show the target character set."), _("\
The `target character set' is the one used by the program being debugged.\n\
GDB translates characters and strings between the host and target\n\
character sets as needed.\n\
To see a list of the character sets GDB supports, type `set target-charset'<TAB>"),
			set_target_charset_sfunc,
			show_target_charset_name,
			&setlist, &showlist);

  add_setshow_enum_cmd ("target-wide-charset", class_support,
			&charset_enum[1], &target_wide_charset_name,
			_("\
Set the target wide character set."), _("\
Show the target wide character set."), _("\
The `target wide character set' is the one used by the program being debugged.\n\
In particular it is the encoding used by `wchar_t'.\n\
GDB translates characters and strings between the host and target\n\
character sets as needed.\n\
To see a list of the character sets GDB supports, type\n\
`set target-wide-charset'<TAB>"),
			set_target_wide_charset_sfunc,
			show_target_wide_charset_name,
			&setlist, &showlist);
}
