/* Copyright (C) 1991, 1992, 1995-2000, 2002, 2003, 2004, 2006, 2008, 2010
   Free Software Foundation, Inc.
   This file is part of the GNU C Library.

   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, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */

#include <alloca.h>
#include <argz.h>
#include <errno.h>
#include <bits/libc-lock.h>
#include <locale.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include "localeinfo.h"

#ifdef NL_CURRENT_INDIRECT

/* For each category declare a special external symbol
   _nl_current_CATEGORY_used with a weak reference.
   This symbol will is defined in lc-CATEGORY.c and will be linked in
   if anything uses _nl_current_CATEGORY (also defined in that module).
   Also use a weak reference for the _nl_current_CATEGORY thread variable.  */

# define DEFINE_CATEGORY(category, category_name, items, a) \
    extern char _nl_current_##category##_used; \
    weak_extern (_nl_current_##category##_used) \
    weak_extern (_nl_current_##category)
# include "categories.def"
# undef	DEFINE_CATEGORY

/* Now define a table of flags based on those special weak symbols' values.
   _nl_current_used[CATEGORY] will be zero if _nl_current_CATEGORY is not
   linked in.  */
static char *const _nl_current_used[] =
  {
# define DEFINE_CATEGORY(category, category_name, items, a) \
    [category] = &_nl_current_##category##_used,
# include "categories.def"
# undef	DEFINE_CATEGORY
  };

# define CATEGORY_USED(category)	(_nl_current_used[category] != 0)

#else

/* The shared library always loads all the categories,
   and the current global settings are kept in _nl_global_locale.  */

# define CATEGORY_USED(category)	(1)

#endif


/* Define an array of category names (also the environment variable names).  */
const union catnamestr_t _nl_category_names attribute_hidden =
  {
    {
#define DEFINE_CATEGORY(category, category_name, items, a) \
      category_name,
#include "categories.def"
#undef DEFINE_CATEGORY
    }
  };

const uint8_t _nl_category_name_idxs[__LC_LAST] attribute_hidden =
  {
#define DEFINE_CATEGORY(category, category_name, items, a) \
    [category] = offsetof (union catnamestr_t, CATNAMEMF (__LINE__)),
#include "categories.def"
#undef DEFINE_CATEGORY
  };

/* An array of their lengths, for convenience.  */
const uint8_t _nl_category_name_sizes[] attribute_hidden =
  {
#define DEFINE_CATEGORY(category, category_name, items, a) \
    [category] = sizeof (category_name) - 1,
#include "categories.def"
#undef	DEFINE_CATEGORY
    [LC_ALL] = sizeof ("LC_ALL") - 1
  };


#ifdef NL_CURRENT_INDIRECT
# define WEAK_POSTLOAD(postload) weak_extern (postload)
#else
# define WEAK_POSTLOAD(postload) /* Need strong refs in static linking.  */
#endif

/* Declare the postload functions used below.  */
#undef	NO_POSTLOAD
#define NO_POSTLOAD _nl_postload_ctype /* Harmless thing known to exist.  */
#define DEFINE_CATEGORY(category, category_name, items, postload) \
extern void postload (void); WEAK_POSTLOAD (postload)
#include "categories.def"
#undef	DEFINE_CATEGORY
#undef	NO_POSTLOAD

/* Define an array indexed by category of postload functions to call after
   loading and installing that category's data.  */
static void (*const _nl_category_postload[]) (void) =
  {
#define DEFINE_CATEGORY(category, category_name, items, postload) \
    [category] = postload,
#include "categories.def"
#undef	DEFINE_CATEGORY
  };


/* Lock for protecting global data.  */
__libc_rwlock_define_initialized (, __libc_setlocale_lock attribute_hidden)

/* Defined in loadmsgcat.c.  */
extern int _nl_msg_cat_cntr;


/* Use this when we come along an error.  */
#define ERROR_RETURN							      \
  do {									      \
    __set_errno (EINVAL);						      \
    return NULL;							      \
  } while (0)


/* Construct a new composite name.  */
static char *
new_composite_name (int category, const char *newnames[__LC_LAST])
{
  size_t last_len = 0;
  size_t cumlen = 0;
  int i;
  char *new, *p;
  int same = 1;

  for (i = 0; i < __LC_LAST; ++i)
    if (i != LC_ALL)
      {
	const char *name = (category == LC_ALL ? newnames[i] :
			    category == i ? newnames[0] :
			    _nl_global_locale.__names[i]);
	last_len = strlen (name);
	cumlen += _nl_category_name_sizes[i] + 1 + last_len + 1;
	if (i > 0 && same && strcmp (name, newnames[0]) != 0)
	  same = 0;
      }

  if (same)
    {
      /* All the categories use the same name.  */
      if (strcmp (newnames[0], _nl_C_name) == 0
	  || strcmp (newnames[0], _nl_POSIX_name) == 0)
	return (char *) _nl_C_name;

      new = malloc (last_len + 1);

      return new == NULL ? NULL : memcpy (new, newnames[0], last_len + 1);
    }

  new = malloc (cumlen);
  if (new == NULL)
    return NULL;
  p = new;
  for (i = 0; i < __LC_LAST; ++i)
    if (i != LC_ALL)
      {
	/* Add "CATEGORY=NAME;" to the string.  */
	const char *name = (category == LC_ALL ? newnames[i] :
			    category == i ? newnames[0] :
			    _nl_global_locale.__names[i]);
	p = __stpcpy (p, _nl_category_names.str + _nl_category_name_idxs[i]);
	*p++ = '=';
	p = __stpcpy (p, name);
	*p++ = ';';
      }
  p[-1] = '\0';		/* Clobber the last ';'.  */
  return new;
}


/* Put NAME in _nl_global_locale.__names.  */
static void
setname (int category, const char *name)
{
  if (_nl_global_locale.__names[category] == name)
    return;

  if (_nl_global_locale.__names[category] != _nl_C_name)
    free ((char *) _nl_global_locale.__names[category]);

  _nl_global_locale.__names[category] = name;
}

/* Put DATA in *_nl_current[CATEGORY].  */
static inline void
setdata (int category, struct __locale_data *data)
{
  if (CATEGORY_USED (category))
    {
      _nl_global_locale.__locales[category] = data;
      if (_nl_category_postload[category])
	(*_nl_category_postload[category]) ();
    }
}

char *
setlocale (int category, const char *locale)
{
  char *locale_path;
  size_t locale_path_len;
  const char *locpath_var;
  char *composite;

  /* Sanity check for CATEGORY argument.  */
  if (__builtin_expect (category, 0) < 0
      || __builtin_expect (category, 0) >= __LC_LAST)
    ERROR_RETURN;

  /* Does user want name of current locale?  */
  if (locale == NULL)
    return (char *) _nl_global_locale.__names[category];

  /* Protect global data.  */
  __libc_rwlock_wrlock (__libc_setlocale_lock);

  if (strcmp (locale, _nl_global_locale.__names[category]) == 0)
    {
      /* Changing to the same thing.  */
      __libc_rwlock_unlock (__libc_setlocale_lock);

      return (char *) _nl_global_locale.__names[category];
    }

  /* We perhaps really have to load some data.  So we determine the
     path in which to look for the data now.  The environment variable
     `LOCPATH' must only be used when the binary has no SUID or SGID
     bit set.  If using the default path, we tell _nl_find_locale
     by passing null and it can check the canonical locale archive.  */
  locale_path = NULL;
  locale_path_len = 0;

  locpath_var = getenv ("LOCPATH");
  if (locpath_var != NULL && locpath_var[0] != '\0')
    {
      if (__argz_create_sep (locpath_var, ':',
			     &locale_path, &locale_path_len) != 0
	  || __argz_add_sep (&locale_path, &locale_path_len,
			     _nl_default_locale_path, ':') != 0)
	{
	  __libc_rwlock_unlock (__libc_setlocale_lock);
	  return NULL;
	}
    }

  if (category == LC_ALL)
    {
      /* The user wants to set all categories.  The desired locales
	 for the individual categories can be selected by using a
	 composite locale name.  This is a semi-colon separated list
	 of entries of the form `CATEGORY=VALUE'.  */
      const char *newnames[__LC_LAST];
      struct __locale_data *newdata[__LC_LAST];

      /* Set all name pointers to the argument name.  */
      for (category = 0; category < __LC_LAST; ++category)
	if (category != LC_ALL)
	  newnames[category] = (char *) locale;

      if (__builtin_expect (strchr (locale, ';') != NULL, 0))
	{
	  /* This is a composite name.  Make a copy and split it up.  */
	  char *np = strdupa (locale);
	  char *cp;
	  int cnt;

	  while ((cp = strchr (np, '=')) != NULL)
	    {
	      for (cnt = 0; cnt < __LC_LAST; ++cnt)
		if (cnt != LC_ALL
		    && (size_t) (cp - np) == _nl_category_name_sizes[cnt]
		    && (memcmp (np, (_nl_category_names.str
				     + _nl_category_name_idxs[cnt]), cp - np)
			== 0))
		  break;

	      if (cnt == __LC_LAST)
		{
		error_return:
		  __libc_rwlock_unlock (__libc_setlocale_lock);

		  /* Bogus category name.  */
		  ERROR_RETURN;
		}

	      /* Found the category this clause sets.  */
	      newnames[cnt] = ++cp;
	      cp = strchr (cp, ';');
	      if (cp != NULL)
		{
		  /* Examine the next clause.  */
		  *cp = '\0';
		  np = cp + 1;
		}
	      else
		/* This was the last clause.  We are done.  */
		break;
	    }

	  for (cnt = 0; cnt < __LC_LAST; ++cnt)
	    if (cnt != LC_ALL && newnames[cnt] == locale)
	      /* The composite name did not specify all categories.  */
	      goto error_return;
	}

      /* Load the new data for each category.  */
      while (category-- > 0)
	if (category != LC_ALL)
	  {
	    newdata[category] = _nl_find_locale (locale_path, locale_path_len,
						 category,
						 &newnames[category]);

	    if (newdata[category] == NULL)
	      {
#ifdef NL_CURRENT_INDIRECT
		if (newnames[category] == _nl_C_name)
		  /* Null because it's the weak value of _nl_C_LC_FOO.  */
		  continue;
#endif
		break;
	      }

	    /* We must not simply free a global locale since we have
	       no control over the usage.  So we mark it as
	       un-deletable.  And yes, the 'if' is needed, the data
	       might be in read-only memory.  */
	    if (newdata[category]->usage_count != UNDELETABLE)
	      newdata[category]->usage_count = UNDELETABLE;

	    /* Make a copy of locale name.  */
	    if (newnames[category] != _nl_C_name)
	      {
		if (strcmp (newnames[category],
			    _nl_global_locale.__names[category]) == 0)
		  newnames[category] = _nl_global_locale.__names[category];
		else
		  {
		    newnames[category] = __strdup (newnames[category]);
		    if (newnames[category] == NULL)
		      break;
		  }
	      }
	  }

      /* Create new composite name.  */
      composite = (category >= 0
		   ? NULL : new_composite_name (LC_ALL, newnames));
      if (composite != NULL)
	{
	  /* Now we have loaded all the new data.  Put it in place.  */
	  for (category = 0; category < __LC_LAST; ++category)
	    if (category != LC_ALL)
	      {
		setdata (category, newdata[category]);
		setname (category, newnames[category]);
	      }
	  setname (LC_ALL, composite);

	  /* We successfully loaded a new locale.  Let the message catalog
	     functions know about this.  */
	  ++_nl_msg_cat_cntr;
	}
      else
	for (++category; category < __LC_LAST; ++category)
	  if (category != LC_ALL && newnames[category] != _nl_C_name
	      && newnames[category] != _nl_global_locale.__names[category])
	    free ((char *) newnames[category]);

      /* Critical section left.  */
      __libc_rwlock_unlock (__libc_setlocale_lock);

      /* Free the resources (the locale path variable).  */
      free (locale_path);

      return composite;
    }
  else
    {
      struct __locale_data *newdata = NULL;
      const char *newname[1] = { locale };

      if (CATEGORY_USED (category))
	{
	  /* Only actually load the data if anything will use it.  */
	  newdata = _nl_find_locale (locale_path, locale_path_len, category,
				     &newname[0]);
	  if (newdata == NULL)
	    goto abort_single;

	  /* We must not simply free a global locale since we have no
	     control over the usage.  So we mark it as un-deletable.

	     Note: do not remove the `if', it's necessary to copy with
	     the builtin locale data.  */
	  if (newdata->usage_count != UNDELETABLE)
	    newdata->usage_count = UNDELETABLE;
	}

      /* Make a copy of locale name.  */
      if (newname[0] != _nl_C_name)
	{
	  newname[0] = __strdup (newname[0]);
	  if (newname[0] == NULL)
	    goto abort_single;
	}

      /* Create new composite name.  */
      composite = new_composite_name (category, newname);
      if (composite == NULL)
	{
	  if (newname[0] != _nl_C_name)
	    free ((char *) newname[0]);

	  /* Say that we don't have any data loaded.  */
	abort_single:
	  newname[0] = NULL;
	}
      else
	{
	  if (CATEGORY_USED (category))
	    setdata (category, newdata);

	  setname (category, newname[0]);
	  setname (LC_ALL, composite);

	  /* We successfully loaded a new locale.  Let the message catalog
	     functions know about this.  */
	  ++_nl_msg_cat_cntr;
	}

      /* Critical section left.  */
      __libc_rwlock_unlock (__libc_setlocale_lock);

      /* Free the resources (the locale path variable.  */
      free (locale_path);

      return (char *) newname[0];
    }
}
libc_hidden_def (setlocale)

static void __libc_freeres_fn_section
free_category (int category,
	       struct __locale_data *here, struct __locale_data *c_data)
{
  struct loaded_l10nfile *runp = _nl_locale_file_list[category];

  /* If this category is already "C" don't do anything.  */
  if (here != c_data)
    {
      /* We have to be prepared that sometime later we still
	 might need the locale information.  */
      setdata (category, c_data);
      setname (category, _nl_C_name);
    }

  while (runp != NULL)
    {
      struct loaded_l10nfile *curr = runp;
      struct __locale_data *data = (struct __locale_data *) runp->data;

      if (data != NULL && data != c_data)
	_nl_unload_locale (data);
      runp = runp->next;
      free ((char *) curr->filename);
      free (curr);
    }
}

/* This is called from iconv/gconv_db.c's free_mem, as locales must
   be freed before freeing gconv steps arrays.  */
void __libc_freeres_fn_section
_nl_locale_subfreeres (void)
{
#ifdef NL_CURRENT_INDIRECT
  /* We don't use the loop because we want to have individual weak
     symbol references here.  */
# define DEFINE_CATEGORY(category, category_name, items, a)		      \
  if (CATEGORY_USED (category))						      \
    {									      \
      extern struct __locale_data _nl_C_##category;			      \
      weak_extern (_nl_C_##category)					      \
      free_category (category, *_nl_current_##category, &_nl_C_##category);   \
    }
# include "categories.def"
# undef	DEFINE_CATEGORY
#else
  int category;

  for (category = 0; category < __LC_LAST; ++category)
    if (category != LC_ALL)
      free_category (category, _NL_CURRENT_DATA (category),
		     _nl_C_locobj.__locales[category]);
#endif

  setname (LC_ALL, _nl_C_name);

  /* This frees the data structures associated with the locale archive.
     The locales from the archive are not in the file list, so we have
     not called _nl_unload_locale on them above.  */
  _nl_archive_subfreeres ();
}
