/* Copyright (C) 1998-2014 Free Software Foundation, Inc.
   This file is part of the GNU C Library.
   Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.

   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 <ctype.h>
#include <langinfo.h>
#include <limits.h>
#include <stdlib.h>
#include <string.h>

#include <locale/localeinfo.h>
#include <wcsmbsload.h>
#include <bits/libc-lock.h>


/* These are the descriptions for the default conversion functions.  */
static const struct __gconv_step to_wc =
{
  .__shlib_handle = NULL,
  .__modname = NULL,
  .__counter = INT_MAX,
  .__from_name = (char *) "ANSI_X3.4-1968//TRANSLIT",
  .__to_name = (char *) "INTERNAL",
  .__fct = __gconv_transform_ascii_internal,
  .__btowc_fct = __gconv_btwoc_ascii,
  .__init_fct = NULL,
  .__end_fct = NULL,
  .__min_needed_from = 1,
  .__max_needed_from = 1,
  .__min_needed_to = 4,
  .__max_needed_to = 4,
  .__stateful = 0,
  .__data = NULL
};

static const struct __gconv_step to_mb =
{
  .__shlib_handle = NULL,
  .__modname = NULL,
  .__counter = INT_MAX,
  .__from_name = (char *) "INTERNAL",
  .__to_name = (char *) "ANSI_X3.4-1968//TRANSLIT",
  .__fct = __gconv_transform_internal_ascii,
  .__btowc_fct = NULL,
  .__init_fct = NULL,
  .__end_fct = NULL,
  .__min_needed_from = 4,
  .__max_needed_from = 4,
  .__min_needed_to = 1,
  .__max_needed_to = 1,
  .__stateful = 0,
  .__data = NULL
};


/* For the default locale we only have to handle ANSI_X3.4-1968.  */
const struct gconv_fcts __wcsmbs_gconv_fcts_c =
{
  .towc = (struct __gconv_step *) &to_wc,
  .towc_nsteps = 1,
  .tomb = (struct __gconv_step *) &to_mb,
  .tomb_nsteps = 1,
};


attribute_hidden
struct __gconv_step *
__wcsmbs_getfct (const char *to, const char *from, size_t *nstepsp)
{
  size_t nsteps;
  struct __gconv_step *result;
#if 0
  size_t nstateful;
  size_t cnt;
#endif

  if (__gconv_find_transform (to, from, &result, &nsteps, 0) != __GCONV_OK)
    /* Loading the conversion step is not possible.  */
    return NULL;

  /* Maybe it is someday necessary to allow more than one step.
     Currently this is not the case since the conversions handled here
     are from and to INTERNAL and there always is a converted for
     that.  It the directly following code is enabled the libio
     functions will have to allocate appropriate __gconv_step_data
     elements instead of only one.  */
#if 0
  /* Count the number of stateful conversions.  Since we will only
     have one 'mbstate_t' object available we can only deal with one
     stateful conversion.  */
  nstateful = 0;
  for (cnt = 0; cnt < nsteps; ++cnt)
    if (result[cnt].__stateful)
      ++nstateful;
  if (nstateful > 1)
#else
  if (nsteps > 1)
#endif
    {
      /* We cannot handle this case.  */
      __gconv_close_transform (result, nsteps);
      result = NULL;
    }
  else
    *nstepsp = nsteps;

  return result;
}


/* Extract from the given locale name the character set portion.  Since
   only the XPG form of the name includes this information we don't have
   to take care for the CEN form.  */
#define extract_charset_name(str) \
  ({									      \
    const char *cp = str;						      \
    char *result = NULL;						      \
									      \
    cp += strcspn (cp, "@.+,");						      \
    if (*cp == '.')							      \
      {									      \
	const char *endp = ++cp;					      \
	while (*endp != '\0' && *endp != '@')				      \
	  ++endp;							      \
	if (endp != cp)							      \
	  result = strndupa (cp, endp - cp);				      \
      }									      \
    result;								      \
  })


/* Some of the functions here must not be used while setlocale is called.  */
__libc_rwlock_define (extern, __libc_setlocale_lock attribute_hidden)

/* Load conversion functions for the currently selected locale.  */
void
internal_function
__wcsmbs_load_conv (struct __locale_data *new_category)
{
  /* Acquire the lock.  */
  __libc_rwlock_wrlock (__libc_setlocale_lock);

  /* We should repeat the test since while we waited some other thread
     might have run this function.  */
  if (__builtin_expect (new_category->private.ctype == NULL, 1))
    {
      /* We must find the real functions.  */
      const char *charset_name;
      const char *complete_name;
      struct gconv_fcts *new_fcts;
      int use_translit;

      /* Allocate the gconv_fcts structure.  */
      new_fcts = calloc (1, sizeof *new_fcts);
      if (new_fcts == NULL)
	goto failed;

      /* Get name of charset of the locale.  */
      charset_name = new_category->values[_NL_ITEM_INDEX(CODESET)].string;

      /* Does the user want transliteration?  */
      use_translit = new_category->use_translit;

      /* Normalize the name and add the slashes necessary for a
	 complete lookup.  */
      complete_name = norm_add_slashes (charset_name,
					use_translit ? "TRANSLIT" : "");

      /* It is not necessary to use transliteration in this direction
	 since the internal character set is supposed to be able to
	 represent all others.  */
      new_fcts->towc = __wcsmbs_getfct ("INTERNAL", complete_name,
					&new_fcts->towc_nsteps);
      if (new_fcts->towc != NULL)
	new_fcts->tomb = __wcsmbs_getfct (complete_name, "INTERNAL",
					  &new_fcts->tomb_nsteps);

      /* If any of the conversion functions is not available we don't
	 use any since this would mean we cannot convert back and
	 forth.  NB: NEW_FCTS was allocated with calloc.  */
      if (new_fcts->tomb == NULL)
	{
	  if (new_fcts->towc != NULL)
	    __gconv_close_transform (new_fcts->towc, new_fcts->towc_nsteps);

	  free (new_fcts);

	failed:
	  new_category->private.ctype = &__wcsmbs_gconv_fcts_c;
	}
      else
	{
	  new_category->private.ctype = new_fcts;
	  new_category->private.cleanup = &_nl_cleanup_ctype;
	}
    }

  __libc_rwlock_unlock (__libc_setlocale_lock);
}


/* Clone the current conversion function set.  */
void
internal_function
__wcsmbs_clone_conv (struct gconv_fcts *copy)
{
  const struct gconv_fcts *orig;

  orig = get_gconv_fcts (_NL_CURRENT_DATA (LC_CTYPE));

  /* Copy the data.  */
  *copy = *orig;

  /* Now increment the usage counters.
     Note: This assumes copy->*_nsteps == 1.  */
  if (copy->towc->__shlib_handle != NULL)
    ++copy->towc->__counter;
  if (copy->tomb->__shlib_handle != NULL)
    ++copy->tomb->__counter;
}


/* Get converters for named charset.  */
int
internal_function
__wcsmbs_named_conv (struct gconv_fcts *copy, const char *name)
{
  copy->towc = __wcsmbs_getfct ("INTERNAL", name, &copy->towc_nsteps);
  if (copy->towc == NULL)
    return 1;

  copy->tomb = __wcsmbs_getfct (name, "INTERNAL", &copy->tomb_nsteps);
  if (copy->tomb == NULL)
    {
      __gconv_close_transform (copy->towc, copy->towc_nsteps);
      return 1;
    }

  return 0;
}

void internal_function
_nl_cleanup_ctype (struct __locale_data *locale)
{
  const struct gconv_fcts *const data = locale->private.ctype;
  if (data != NULL)
    {
      locale->private.ctype = NULL;
      locale->private.cleanup = NULL;

      /* Free the old conversions.  */
      __gconv_close_transform (data->tomb, data->tomb_nsteps);
      __gconv_close_transform (data->towc, data->towc_nsteps);
      free ((char *) data);
    }
}
