/* Find matching transformation algorithms and initialize steps.
   Copyright (C) 1997-2018 Free Software Foundation, Inc.
   This file is part of the GNU C Library.
   Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.

   The GNU C Library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 of the License, or (at your option) any later version.

   The GNU C Library 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
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, see
   <http://www.gnu.org/licenses/>.  */

#include <errno.h>
#include <locale.h>
#include "../locale/localeinfo.h"
#include <stdlib.h>
#include <string.h>

#include <gconv_int.h>


int
__gconv_open (struct gconv_spec *conv_spec, __gconv_t *handle,
	      int flags)
{
  struct __gconv_step *steps;
  size_t nsteps;
  __gconv_t result = NULL;
  size_t cnt = 0;
  int res;
  int conv_flags = 0;
  bool translit = false;
  char *tocode, *fromcode;

  /* Find out whether any error handling method is specified.  */
  translit = conv_spec->translit;

  if (conv_spec->ignore)
    conv_flags |= __GCONV_IGNORE_ERRORS;

  tocode = conv_spec->tocode;
  fromcode = conv_spec->fromcode;

  /* If the string is empty define this to mean the charset of the
     currently selected locale.  */
  if (strcmp (tocode, "//") == 0)
    {
      const char *codeset = _NL_CURRENT (LC_CTYPE, CODESET);
      size_t len = strlen (codeset);
      char *dest;
      tocode = dest = (char *) alloca (len + 3);
      memcpy (__mempcpy (dest, codeset, len), "//", 3);
    }
  if (strcmp (fromcode, "//") == 0)
    {
      const char *codeset = _NL_CURRENT (LC_CTYPE, CODESET);
      size_t len = strlen (codeset);
      char *dest;
      fromcode = dest = (char *) alloca (len + 3);
      memcpy (__mempcpy (dest, codeset, len), "//", 3);
    }

  res = __gconv_find_transform (tocode, fromcode, &steps, &nsteps, flags);
  if (res == __GCONV_OK)
    {
      /* Allocate room for handle.  */
      result = (__gconv_t) malloc (sizeof (struct __gconv_info)
				   + (nsteps
				      * sizeof (struct __gconv_step_data)));
      if (result == NULL)
	res = __GCONV_NOMEM;
      else
	{
	  /* Remember the list of steps.  */
	  result->__steps = steps;
	  result->__nsteps = nsteps;

	  /* Clear the array for the step data.  */
	  memset (result->__data, '\0',
		  nsteps * sizeof (struct __gconv_step_data));

	  /* Call all initialization functions for the transformation
	     step implementations.  */
	  for (cnt = 0; cnt < nsteps; ++cnt)
	    {
	      size_t size;

	      /* Would have to be done if we would not clear the whole
                 array above.  */
#if 0
	      /* Reset the counter.  */
	      result->__data[cnt].__invocation_counter = 0;

	      /* It's a regular use.  */
	      result->__data[cnt].__internal_use = 0;
#endif

	      /* We use the `mbstate_t' member in DATA.  */
	      result->__data[cnt].__statep = &result->__data[cnt].__state;

	      /* The builtin transliteration handling only
		 supports the internal encoding.  */
	      if (translit
		  && __strcasecmp_l (steps[cnt].__from_name,
				     "INTERNAL", _nl_C_locobj_ptr) == 0)
		conv_flags |= __GCONV_TRANSLIT;

	      /* If this is the last step we must not allocate an
		 output buffer.  */
	      if (cnt < nsteps - 1)
		{
		  result->__data[cnt].__flags = conv_flags;

		  /* Allocate the buffer.  */
		  size = (GCONV_NCHAR_GOAL * steps[cnt].__max_needed_to);

		  result->__data[cnt].__outbuf = malloc (size);
		  if (result->__data[cnt].__outbuf == NULL)
		    {
		      res = __GCONV_NOMEM;
		      goto bail;
		    }

		  result->__data[cnt].__outbufend =
		    result->__data[cnt].__outbuf + size;
		}
	      else
		{
		  /* Handle the last entry.  */
		  result->__data[cnt].__flags = conv_flags | __GCONV_IS_LAST;

		  break;
		}
	    }
	}

      if (res != __GCONV_OK)
	{
	  /* Something went wrong.  Free all the resources.  */
	  int serrno;
	bail:
	  serrno = errno;

	  if (result != NULL)
	    {
	      while (cnt-- > 0)
		free (result->__data[cnt].__outbuf);

	      free (result);
	      result = NULL;
	    }

	  __gconv_close_transform (steps, nsteps);

	  __set_errno (serrno);
	}
    }

  *handle = result;
  return res;
}
libc_hidden_def (__gconv_open)
