Blame intl/finddomain.c

Packit 8a864e
/* Handle list of needed message catalogs
Packit 8a864e
   Copyright (C) 1995-1999, 2000-2001, 2003 Free Software Foundation, Inc.
Packit 8a864e
   Written by Ulrich Drepper <drepper@gnu.org>, 1995.
Packit 8a864e
Packit 8a864e
   This program is free software; you can redistribute it and/or modify it
Packit 8a864e
   under the terms of the GNU Library General Public License as published
Packit 8a864e
   by the Free Software Foundation; either version 2, or (at your option)
Packit 8a864e
   any later version.
Packit 8a864e
Packit 8a864e
   This program is distributed in the hope that it will be useful,
Packit 8a864e
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 8a864e
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 8a864e
   Library General Public License for more details.
Packit 8a864e
Packit 8a864e
   You should have received a copy of the GNU Library General Public
Packit 8a864e
   License along with this program; if not, write to the Free Software
Packit 8a864e
   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
Packit 8a864e
   USA.  */
Packit 8a864e
Packit 8a864e
#ifdef HAVE_CONFIG_H
Packit 8a864e
# include <config.h>
Packit 8a864e
#endif
Packit 8a864e
Packit 8a864e
#include <stdio.h>
Packit 8a864e
#include <sys/types.h>
Packit 8a864e
#include <stdlib.h>
Packit 8a864e
#include <string.h>
Packit 8a864e
Packit 8a864e
#if defined HAVE_UNISTD_H || defined _LIBC
Packit 8a864e
# include <unistd.h>
Packit 8a864e
#endif
Packit 8a864e
Packit 8a864e
#include "gettextP.h"
Packit 8a864e
#ifdef _LIBC
Packit 8a864e
# include <libintl.h>
Packit 8a864e
#else
Packit 8a864e
# include "libgnuintl.h"
Packit 8a864e
#endif
Packit 8a864e
Packit 8a864e
/* @@ end of prolog @@ */
Packit 8a864e
/* List of already loaded domains.  */
Packit 8a864e
static struct loaded_l10nfile *_nl_loaded_domains;
Packit 8a864e
Packit 8a864e
Packit 8a864e
/* Return a data structure describing the message catalog described by
Packit 8a864e
   the DOMAINNAME and CATEGORY parameters with respect to the currently
Packit 8a864e
   established bindings.  */
Packit 8a864e
struct loaded_l10nfile *
Packit 8a864e
internal_function
Packit 8a864e
_nl_find_domain (const char *dirname, char *locale,
Packit 8a864e
		 const char *domainname, struct binding *domainbinding)
Packit 8a864e
{
Packit 8a864e
  struct loaded_l10nfile *retval;
Packit 8a864e
  const char *language;
Packit 8a864e
  const char *modifier;
Packit 8a864e
  const char *territory;
Packit 8a864e
  const char *codeset;
Packit 8a864e
  const char *normalized_codeset;
Packit 8a864e
  const char *special;
Packit 8a864e
  const char *sponsor;
Packit 8a864e
  const char *revision;
Packit 8a864e
  const char *alias_value;
Packit 8a864e
  int mask;
Packit 8a864e
Packit 8a864e
  /* LOCALE can consist of up to four recognized parts for the XPG syntax:
Packit 8a864e
Packit 8a864e
		language[_territory[.codeset]][@modifier]
Packit 8a864e
Packit 8a864e
     and six parts for the CEN syntax:
Packit 8a864e
Packit 8a864e
	language[_territory][+audience][+special][,[sponsor][_revision]]
Packit 8a864e
Packit 8a864e
     Beside the first part all of them are allowed to be missing.  If
Packit 8a864e
     the full specified locale is not found, the less specific one are
Packit 8a864e
     looked for.  The various parts will be stripped off according to
Packit 8a864e
     the following order:
Packit 8a864e
		(1) revision
Packit 8a864e
		(2) sponsor
Packit 8a864e
		(3) special
Packit 8a864e
		(4) codeset
Packit 8a864e
		(5) normalized codeset
Packit 8a864e
		(6) territory
Packit 8a864e
		(7) audience/modifier
Packit 8a864e
   */
Packit 8a864e
Packit 8a864e
  /* If we have already tested for this locale entry there has to
Packit 8a864e
     be one data set in the list of loaded domains.  */
Packit 8a864e
  retval = _nl_make_l10nflist (&_nl_loaded_domains, dirname,
Packit 8a864e
			       strlen (dirname) + 1, 0, locale, NULL, NULL,
Packit 8a864e
			       NULL, NULL, NULL, NULL, NULL, domainname, 0);
Packit 8a864e
  if (retval != NULL)
Packit 8a864e
    {
Packit 8a864e
      /* We know something about this locale.  */
Packit 8a864e
      int cnt;
Packit 8a864e
Packit 8a864e
      if (retval->decided == 0)
Packit 8a864e
	_nl_load_domain (retval, domainbinding);
Packit 8a864e
Packit 8a864e
      if (retval->data != NULL)
Packit 8a864e
	return retval;
Packit 8a864e
Packit 8a864e
      for (cnt = 0; retval->successor[cnt] != NULL; ++cnt)
Packit 8a864e
	{
Packit 8a864e
	  if (retval->successor[cnt]->decided == 0)
Packit 8a864e
	    _nl_load_domain (retval->successor[cnt], domainbinding);
Packit 8a864e
Packit 8a864e
	  if (retval->successor[cnt]->data != NULL)
Packit 8a864e
	    break;
Packit 8a864e
	}
Packit 8a864e
      return cnt >= 0 ? retval : NULL;
Packit 8a864e
      /* NOTREACHED */
Packit 8a864e
    }
Packit 8a864e
Packit 8a864e
  /* See whether the locale value is an alias.  If yes its value
Packit 8a864e
     *overwrites* the alias name.  No test for the original value is
Packit 8a864e
     done.  */
Packit 8a864e
  alias_value = _nl_expand_alias (locale);
Packit 8a864e
  if (alias_value != NULL)
Packit 8a864e
    {
Packit 8a864e
#if defined _LIBC || defined HAVE_STRDUP
Packit 8a864e
      locale = strdup (alias_value);
Packit 8a864e
      if (locale == NULL)
Packit 8a864e
	return NULL;
Packit 8a864e
#else
Packit 8a864e
      size_t len = strlen (alias_value) + 1;
Packit 8a864e
      locale = (char *) malloc (len);
Packit 8a864e
      if (locale == NULL)
Packit 8a864e
	return NULL;
Packit 8a864e
Packit 8a864e
      memcpy (locale, alias_value, len);
Packit 8a864e
#endif
Packit 8a864e
    }
Packit 8a864e
Packit 8a864e
  /* Now we determine the single parts of the locale name.  First
Packit 8a864e
     look for the language.  Termination symbols are `_' and `@' if
Packit 8a864e
     we use XPG4 style, and `_', `+', and `,' if we use CEN syntax.  */
Packit 8a864e
  mask = _nl_explode_name (locale, &language, &modifier, &territory,
Packit 8a864e
			   &codeset, &normalized_codeset, &special,
Packit 8a864e
			   &sponsor, &revision);
Packit 8a864e
Packit 8a864e
  /* Create all possible locale entries which might be interested in
Packit 8a864e
     generalization.  */
Packit 8a864e
  retval = _nl_make_l10nflist (&_nl_loaded_domains, dirname,
Packit 8a864e
			       strlen (dirname) + 1, mask, language, territory,
Packit 8a864e
			       codeset, normalized_codeset, modifier, special,
Packit 8a864e
			       sponsor, revision, domainname, 1);
Packit 8a864e
  if (retval == NULL)
Packit 8a864e
    /* This means we are out of core.  */
Packit 8a864e
    return NULL;
Packit 8a864e
Packit 8a864e
  if (retval->decided == 0)
Packit 8a864e
    _nl_load_domain (retval, domainbinding);
Packit 8a864e
  if (retval->data == NULL)
Packit 8a864e
    {
Packit 8a864e
      int cnt;
Packit 8a864e
      for (cnt = 0; retval->successor[cnt] != NULL; ++cnt)
Packit 8a864e
	{
Packit 8a864e
	  if (retval->successor[cnt]->decided == 0)
Packit 8a864e
	    _nl_load_domain (retval->successor[cnt], domainbinding);
Packit 8a864e
	  if (retval->successor[cnt]->data != NULL)
Packit 8a864e
	    break;
Packit 8a864e
	}
Packit 8a864e
    }
Packit 8a864e
Packit 8a864e
  /* The room for an alias was dynamically allocated.  Free it now.  */
Packit 8a864e
  if (alias_value != NULL)
Packit 8a864e
    free (locale);
Packit 8a864e
Packit 8a864e
  /* The space for normalized_codeset is dynamically allocated.  Free it.  */
Packit 8a864e
  if (mask & XPG_NORM_CODESET)
Packit 8a864e
    free ((void *) normalized_codeset);
Packit 8a864e
Packit 8a864e
  return retval;
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
Packit 8a864e
#ifdef _LIBC
Packit 8a864e
libc_freeres_fn (free_mem)
Packit 8a864e
{
Packit 8a864e
  struct loaded_l10nfile *runp = _nl_loaded_domains;
Packit 8a864e
Packit 8a864e
  while (runp != NULL)
Packit 8a864e
    {
Packit 8a864e
      struct loaded_l10nfile *here = runp;
Packit 8a864e
      if (runp->data != NULL)
Packit 8a864e
	_nl_unload_domain ((struct loaded_domain *) runp->data);
Packit 8a864e
      runp = runp->next;
Packit 8a864e
      free ((char *) here->filename);
Packit 8a864e
      free (here);
Packit 8a864e
    }
Packit 8a864e
}
Packit 8a864e
#endif