OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [intl/] [dcgettext.c] - Diff between revs 578 and 1765

Go to most recent revision | Only display areas with differences | Details | Blame | View Log

Rev 578 Rev 1765
/* Implementation of the dcgettext(3) function
/* Implementation of the dcgettext(3) function
   Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
   Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
 
 
   This program is free software; you can redistribute it and/or modify
   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
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   the Free Software Foundation; either version 2, or (at your option)
   any later version.
   any later version.
 
 
   This program is distributed in the hope that it will be useful,
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
   GNU General Public License for more details.
 
 
   You should have received a copy of the GNU General Public License
   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software Foundation,
   along with this program; if not, write to the Free Software Foundation,
   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
 
#ifdef HAVE_CONFIG_H
#ifdef HAVE_CONFIG_H
# include <config.h>
# include <config.h>
#endif
#endif
 
 
#include <sys/types.h>
#include <sys/types.h>
 
 
#ifdef __GNUC__
#ifdef __GNUC__
# define alloca __builtin_alloca
# define alloca __builtin_alloca
# define HAVE_ALLOCA 1
# define HAVE_ALLOCA 1
#else
#else
# if defined HAVE_ALLOCA_H || defined _LIBC
# if defined HAVE_ALLOCA_H || defined _LIBC
#  include <alloca.h>
#  include <alloca.h>
# else
# else
#  ifdef _AIX
#  ifdef _AIX
 #pragma alloca
 #pragma alloca
#  else
#  else
#   ifndef alloca
#   ifndef alloca
char *alloca ();
char *alloca ();
#   endif
#   endif
#  endif
#  endif
# endif
# endif
#endif
#endif
 
 
#include <errno.h>
#include <errno.h>
#ifndef errno
#ifndef errno
extern int errno;
extern int errno;
#endif
#endif
#ifndef __set_errno
#ifndef __set_errno
# define __set_errno(val) errno = (val)
# define __set_errno(val) errno = (val)
#endif
#endif
 
 
#if defined STDC_HEADERS || defined _LIBC
#if defined STDC_HEADERS || defined _LIBC
# include <stdlib.h>
# include <stdlib.h>
#else
#else
char *getenv ();
char *getenv ();
# ifdef HAVE_MALLOC_H
# ifdef HAVE_MALLOC_H
#  include <malloc.h>
#  include <malloc.h>
# else
# else
void free ();
void free ();
# endif
# endif
#endif
#endif
 
 
#if defined HAVE_STRING_H || defined _LIBC
#if defined HAVE_STRING_H || defined _LIBC
# ifndef _GNU_SOURCE
# ifndef _GNU_SOURCE
#  define _GNU_SOURCE   1
#  define _GNU_SOURCE   1
# endif
# endif
# include <string.h>
# include <string.h>
#else
#else
# include <strings.h>
# include <strings.h>
#endif
#endif
#if !HAVE_STRCHR && !defined _LIBC
#if !HAVE_STRCHR && !defined _LIBC
# ifndef strchr
# ifndef strchr
#  define strchr index
#  define strchr index
# endif
# endif
#endif
#endif
 
 
#if defined HAVE_UNISTD_H || defined _LIBC
#if defined HAVE_UNISTD_H || defined _LIBC
# include <unistd.h>
# include <unistd.h>
#endif
#endif
 
 
#include "gettext.h"
#include "gettext.h"
#include "gettextP.h"
#include "gettextP.h"
#ifdef _LIBC
#ifdef _LIBC
# include <libintl.h>
# include <libintl.h>
#else
#else
# include "libgettext.h"
# include "libgettext.h"
#endif
#endif
#include "hash-string.h"
#include "hash-string.h"
 
 
/* @@ end of prolog @@ */
/* @@ end of prolog @@ */
 
 
#ifdef _LIBC
#ifdef _LIBC
/* Rename the non ANSI C functions.  This is required by the standard
/* Rename the non ANSI C functions.  This is required by the standard
   because some ANSI C functions will require linking with this object
   because some ANSI C functions will require linking with this object
   file and the name space must not be polluted.  */
   file and the name space must not be polluted.  */
# define getcwd __getcwd
# define getcwd __getcwd
# define stpcpy __stpcpy
# define stpcpy __stpcpy
#else
#else
# if !defined HAVE_GETCWD
# if !defined HAVE_GETCWD
char *getwd ();
char *getwd ();
#  define getcwd(buf, max) getwd (buf)
#  define getcwd(buf, max) getwd (buf)
# else
# else
char *getcwd ();
char *getcwd ();
# endif
# endif
# ifndef HAVE_STPCPY
# ifndef HAVE_STPCPY
static char *stpcpy PARAMS ((char *dest, const char *src));
static char *stpcpy PARAMS ((char *dest, const char *src));
# endif
# endif
#endif
#endif
 
 
/* Amount to increase buffer size by in each try.  */
/* Amount to increase buffer size by in each try.  */
#define PATH_INCR 32
#define PATH_INCR 32
 
 
/* The following is from pathmax.h.  */
/* The following is from pathmax.h.  */
/* Non-POSIX BSD systems might have gcc's limits.h, which doesn't define
/* Non-POSIX BSD systems might have gcc's limits.h, which doesn't define
   PATH_MAX but might cause redefinition warnings when sys/param.h is
   PATH_MAX but might cause redefinition warnings when sys/param.h is
   later included (as on MORE/BSD 4.3).  */
   later included (as on MORE/BSD 4.3).  */
#if defined(_POSIX_VERSION) || (defined(HAVE_LIMITS_H) && !defined(__GNUC__))
#if defined(_POSIX_VERSION) || (defined(HAVE_LIMITS_H) && !defined(__GNUC__))
# include <limits.h>
# include <limits.h>
#endif
#endif
 
 
#ifndef _POSIX_PATH_MAX
#ifndef _POSIX_PATH_MAX
# define _POSIX_PATH_MAX 255
# define _POSIX_PATH_MAX 255
#endif
#endif
 
 
#if !defined(PATH_MAX) && defined(_PC_PATH_MAX)
#if !defined(PATH_MAX) && defined(_PC_PATH_MAX)
# define PATH_MAX (pathconf ("/", _PC_PATH_MAX) < 1 ? 1024 : pathconf ("/", _PC_PATH_MAX))
# define PATH_MAX (pathconf ("/", _PC_PATH_MAX) < 1 ? 1024 : pathconf ("/", _PC_PATH_MAX))
#endif
#endif
 
 
/* Don't include sys/param.h if it already has been.  */
/* Don't include sys/param.h if it already has been.  */
#if defined(HAVE_SYS_PARAM_H) && !defined(PATH_MAX) && !defined(MAXPATHLEN)
#if defined(HAVE_SYS_PARAM_H) && !defined(PATH_MAX) && !defined(MAXPATHLEN)
# include <sys/param.h>
# include <sys/param.h>
#endif
#endif
 
 
#if !defined(PATH_MAX) && defined(MAXPATHLEN)
#if !defined(PATH_MAX) && defined(MAXPATHLEN)
# define PATH_MAX MAXPATHLEN
# define PATH_MAX MAXPATHLEN
#endif
#endif
 
 
#ifndef PATH_MAX
#ifndef PATH_MAX
# define PATH_MAX _POSIX_PATH_MAX
# define PATH_MAX _POSIX_PATH_MAX
#endif
#endif
 
 
/* XPG3 defines the result of `setlocale (category, NULL)' as:
/* XPG3 defines the result of `setlocale (category, NULL)' as:
   ``Directs `setlocale()' to query `category' and return the current
   ``Directs `setlocale()' to query `category' and return the current
     setting of `local'.''
     setting of `local'.''
   However it does not specify the exact format.  And even worse: POSIX
   However it does not specify the exact format.  And even worse: POSIX
   defines this not at all.  So we can use this feature only on selected
   defines this not at all.  So we can use this feature only on selected
   system (e.g. those using GNU C Library).  */
   system (e.g. those using GNU C Library).  */
#ifdef _LIBC
#ifdef _LIBC
# define HAVE_LOCALE_NULL
# define HAVE_LOCALE_NULL
#endif
#endif
 
 
/* Name of the default domain used for gettext(3) prior any call to
/* Name of the default domain used for gettext(3) prior any call to
   textdomain(3).  The default value for this is "messages".  */
   textdomain(3).  The default value for this is "messages".  */
const char _nl_default_default_domain[] = "messages";
const char _nl_default_default_domain[] = "messages";
 
 
/* Value used as the default domain for gettext(3).  */
/* Value used as the default domain for gettext(3).  */
const char *_nl_current_default_domain = _nl_default_default_domain;
const char *_nl_current_default_domain = _nl_default_default_domain;
 
 
/* Contains the default location of the message catalogs.  */
/* Contains the default location of the message catalogs.  */
const char _nl_default_dirname[] = GNULOCALEDIR;
const char _nl_default_dirname[] = GNULOCALEDIR;
 
 
/* List with bindings of specific domains created by bindtextdomain()
/* List with bindings of specific domains created by bindtextdomain()
   calls.  */
   calls.  */
struct binding *_nl_domain_bindings;
struct binding *_nl_domain_bindings;
 
 
/* Prototypes for local functions.  */
/* Prototypes for local functions.  */
static char *find_msg PARAMS ((struct loaded_l10nfile *domain_file,
static char *find_msg PARAMS ((struct loaded_l10nfile *domain_file,
                               const char *msgid));
                               const char *msgid));
static const char *category_to_name PARAMS ((int category));
static const char *category_to_name PARAMS ((int category));
static const char *guess_category_value PARAMS ((int category,
static const char *guess_category_value PARAMS ((int category,
                                                 const char *categoryname));
                                                 const char *categoryname));
 
 
 
 
/* For those loosing systems which don't have `alloca' we have to add
/* For those loosing systems which don't have `alloca' we have to add
   some additional code emulating it.  */
   some additional code emulating it.  */
#ifdef HAVE_ALLOCA
#ifdef HAVE_ALLOCA
/* Nothing has to be done.  */
/* Nothing has to be done.  */
# define ADD_BLOCK(list, address) /* nothing */
# define ADD_BLOCK(list, address) /* nothing */
# define FREE_BLOCKS(list) /* nothing */
# define FREE_BLOCKS(list) /* nothing */
#else
#else
struct block_list
struct block_list
{
{
  void *address;
  void *address;
  struct block_list *next;
  struct block_list *next;
};
};
# define ADD_BLOCK(list, addr)                                                \
# define ADD_BLOCK(list, addr)                                                \
  do {                                                                        \
  do {                                                                        \
    struct block_list *newp = (struct block_list *) malloc (sizeof (*newp));  \
    struct block_list *newp = (struct block_list *) malloc (sizeof (*newp));  \
    /* If we cannot get a free block we cannot add the new element to         \
    /* If we cannot get a free block we cannot add the new element to         \
       the list.  */                                                          \
       the list.  */                                                          \
    if (newp != NULL) {                                                       \
    if (newp != NULL) {                                                       \
      newp->address = (addr);                                                 \
      newp->address = (addr);                                                 \
      newp->next = (list);                                                    \
      newp->next = (list);                                                    \
      (list) = newp;                                                          \
      (list) = newp;                                                          \
    }                                                                         \
    }                                                                         \
  } while (0)
  } while (0)
# define FREE_BLOCKS(list)                                                    \
# define FREE_BLOCKS(list)                                                    \
  do {                                                                        \
  do {                                                                        \
    while (list != NULL) {                                                    \
    while (list != NULL) {                                                    \
      struct block_list *old = list;                                          \
      struct block_list *old = list;                                          \
      list = list->next;                                                      \
      list = list->next;                                                      \
      free (old);                                                             \
      free (old);                                                             \
    }                                                                         \
    }                                                                         \
  } while (0)
  } while (0)
# undef alloca
# undef alloca
# define alloca(size) (malloc (size))
# define alloca(size) (malloc (size))
#endif  /* have alloca */
#endif  /* have alloca */
 
 
 
 
/* Names for the libintl functions are a problem.  They must not clash
/* Names for the libintl functions are a problem.  They must not clash
   with existing names and they should follow ANSI C.  But this source
   with existing names and they should follow ANSI C.  But this source
   code is also used in GNU C Library where the names have a __
   code is also used in GNU C Library where the names have a __
   prefix.  So we have to make a difference here.  */
   prefix.  So we have to make a difference here.  */
#ifdef _LIBC
#ifdef _LIBC
# define DCGETTEXT __dcgettext
# define DCGETTEXT __dcgettext
#else
#else
# define DCGETTEXT dcgettext__
# define DCGETTEXT dcgettext__
#endif
#endif
 
 
/* Look up MSGID in the DOMAINNAME message catalog for the current CATEGORY
/* Look up MSGID in the DOMAINNAME message catalog for the current CATEGORY
   locale.  */
   locale.  */
char *
char *
DCGETTEXT (domainname, msgid, category)
DCGETTEXT (domainname, msgid, category)
     const char *domainname;
     const char *domainname;
     const char *msgid;
     const char *msgid;
     int category;
     int category;
{
{
#ifndef HAVE_ALLOCA
#ifndef HAVE_ALLOCA
  struct block_list *block_list = NULL;
  struct block_list *block_list = NULL;
#endif
#endif
  struct loaded_l10nfile *domain;
  struct loaded_l10nfile *domain;
  struct binding *binding;
  struct binding *binding;
  const char *categoryname;
  const char *categoryname;
  const char *categoryvalue;
  const char *categoryvalue;
  char *dirname, *xdomainname;
  char *dirname, *xdomainname;
  char *single_locale;
  char *single_locale;
  char *retval;
  char *retval;
  int saved_errno = errno;
  int saved_errno = errno;
 
 
  /* If no real MSGID is given return NULL.  */
  /* If no real MSGID is given return NULL.  */
  if (msgid == NULL)
  if (msgid == NULL)
    return NULL;
    return NULL;
 
 
  /* If DOMAINNAME is NULL, we are interested in the default domain.  If
  /* If DOMAINNAME is NULL, we are interested in the default domain.  If
     CATEGORY is not LC_MESSAGES this might not make much sense but the
     CATEGORY is not LC_MESSAGES this might not make much sense but the
     defintion left this undefined.  */
     defintion left this undefined.  */
  if (domainname == NULL)
  if (domainname == NULL)
    domainname = _nl_current_default_domain;
    domainname = _nl_current_default_domain;
 
 
  /* First find matching binding.  */
  /* First find matching binding.  */
  for (binding = _nl_domain_bindings; binding != NULL; binding = binding->next)
  for (binding = _nl_domain_bindings; binding != NULL; binding = binding->next)
    {
    {
      int compare = strcmp (domainname, binding->domainname);
      int compare = strcmp (domainname, binding->domainname);
      if (compare == 0)
      if (compare == 0)
        /* We found it!  */
        /* We found it!  */
        break;
        break;
      if (compare < 0)
      if (compare < 0)
        {
        {
          /* It is not in the list.  */
          /* It is not in the list.  */
          binding = NULL;
          binding = NULL;
          break;
          break;
        }
        }
    }
    }
 
 
  if (binding == NULL)
  if (binding == NULL)
    dirname = (char *) _nl_default_dirname;
    dirname = (char *) _nl_default_dirname;
  else if (binding->dirname[0] == '/')
  else if (binding->dirname[0] == '/')
    dirname = binding->dirname;
    dirname = binding->dirname;
  else
  else
    {
    {
      /* We have a relative path.  Make it absolute now.  */
      /* We have a relative path.  Make it absolute now.  */
      size_t dirname_len = strlen (binding->dirname) + 1;
      size_t dirname_len = strlen (binding->dirname) + 1;
      size_t path_max;
      size_t path_max;
      char *ret;
      char *ret;
 
 
      path_max = (unsigned) PATH_MAX;
      path_max = (unsigned) PATH_MAX;
      path_max += 2;            /* The getcwd docs say to do this.  */
      path_max += 2;            /* The getcwd docs say to do this.  */
 
 
      dirname = (char *) alloca (path_max + dirname_len);
      dirname = (char *) alloca (path_max + dirname_len);
      ADD_BLOCK (block_list, dirname);
      ADD_BLOCK (block_list, dirname);
 
 
      __set_errno (0);
      __set_errno (0);
      while ((ret = getcwd (dirname, path_max)) == NULL && errno == ERANGE)
      while ((ret = getcwd (dirname, path_max)) == NULL && errno == ERANGE)
        {
        {
          path_max += PATH_INCR;
          path_max += PATH_INCR;
          dirname = (char *) alloca (path_max + dirname_len);
          dirname = (char *) alloca (path_max + dirname_len);
          ADD_BLOCK (block_list, dirname);
          ADD_BLOCK (block_list, dirname);
          __set_errno (0);
          __set_errno (0);
        }
        }
 
 
      if (ret == NULL)
      if (ret == NULL)
        {
        {
          /* We cannot get the current working directory.  Don't signal an
          /* We cannot get the current working directory.  Don't signal an
             error but simply return the default string.  */
             error but simply return the default string.  */
          FREE_BLOCKS (block_list);
          FREE_BLOCKS (block_list);
          __set_errno (saved_errno);
          __set_errno (saved_errno);
          return (char *) msgid;
          return (char *) msgid;
        }
        }
 
 
      stpcpy (stpcpy (strchr (dirname, '\0'), "/"), binding->dirname);
      stpcpy (stpcpy (strchr (dirname, '\0'), "/"), binding->dirname);
    }
    }
 
 
  /* Now determine the symbolic name of CATEGORY and its value.  */
  /* Now determine the symbolic name of CATEGORY and its value.  */
  categoryname = category_to_name (category);
  categoryname = category_to_name (category);
  categoryvalue = guess_category_value (category, categoryname);
  categoryvalue = guess_category_value (category, categoryname);
 
 
  xdomainname = (char *) alloca (strlen (categoryname)
  xdomainname = (char *) alloca (strlen (categoryname)
                                 + strlen (domainname) + 5);
                                 + strlen (domainname) + 5);
  ADD_BLOCK (block_list, xdomainname);
  ADD_BLOCK (block_list, xdomainname);
 
 
  stpcpy (stpcpy (stpcpy (stpcpy (xdomainname, categoryname), "/"),
  stpcpy (stpcpy (stpcpy (stpcpy (xdomainname, categoryname), "/"),
                  domainname),
                  domainname),
          ".mo");
          ".mo");
 
 
  /* Creating working area.  */
  /* Creating working area.  */
  single_locale = (char *) alloca (strlen (categoryvalue) + 1);
  single_locale = (char *) alloca (strlen (categoryvalue) + 1);
  ADD_BLOCK (block_list, single_locale);
  ADD_BLOCK (block_list, single_locale);
 
 
 
 
  /* Search for the given string.  This is a loop because we perhaps
  /* Search for the given string.  This is a loop because we perhaps
     got an ordered list of languages to consider for th translation.  */
     got an ordered list of languages to consider for th translation.  */
  while (1)
  while (1)
    {
    {
      /* Make CATEGORYVALUE point to the next element of the list.  */
      /* Make CATEGORYVALUE point to the next element of the list.  */
      while (categoryvalue[0] != '\0' && categoryvalue[0] == ':')
      while (categoryvalue[0] != '\0' && categoryvalue[0] == ':')
        ++categoryvalue;
        ++categoryvalue;
      if (categoryvalue[0] == '\0')
      if (categoryvalue[0] == '\0')
        {
        {
          /* The whole contents of CATEGORYVALUE has been searched but
          /* The whole contents of CATEGORYVALUE has been searched but
             no valid entry has been found.  We solve this situation
             no valid entry has been found.  We solve this situation
             by implicitly appending a "C" entry, i.e. no translation
             by implicitly appending a "C" entry, i.e. no translation
             will take place.  */
             will take place.  */
          single_locale[0] = 'C';
          single_locale[0] = 'C';
          single_locale[1] = '\0';
          single_locale[1] = '\0';
        }
        }
      else
      else
        {
        {
          char *cp = single_locale;
          char *cp = single_locale;
          while (categoryvalue[0] != '\0' && categoryvalue[0] != ':')
          while (categoryvalue[0] != '\0' && categoryvalue[0] != ':')
            *cp++ = *categoryvalue++;
            *cp++ = *categoryvalue++;
          *cp = '\0';
          *cp = '\0';
        }
        }
 
 
      /* If the current locale value is C (or POSIX) we don't load a
      /* If the current locale value is C (or POSIX) we don't load a
         domain.  Return the MSGID.  */
         domain.  Return the MSGID.  */
      if (strcmp (single_locale, "C") == 0
      if (strcmp (single_locale, "C") == 0
          || strcmp (single_locale, "POSIX") == 0)
          || strcmp (single_locale, "POSIX") == 0)
        {
        {
          FREE_BLOCKS (block_list);
          FREE_BLOCKS (block_list);
          __set_errno (saved_errno);
          __set_errno (saved_errno);
          return (char *) msgid;
          return (char *) msgid;
        }
        }
 
 
 
 
      /* Find structure describing the message catalog matching the
      /* Find structure describing the message catalog matching the
         DOMAINNAME and CATEGORY.  */
         DOMAINNAME and CATEGORY.  */
      domain = _nl_find_domain (dirname, single_locale, xdomainname);
      domain = _nl_find_domain (dirname, single_locale, xdomainname);
 
 
      if (domain != NULL)
      if (domain != NULL)
        {
        {
          retval = find_msg (domain, msgid);
          retval = find_msg (domain, msgid);
 
 
          if (retval == NULL)
          if (retval == NULL)
            {
            {
              int cnt;
              int cnt;
 
 
              for (cnt = 0; domain->successor[cnt] != NULL; ++cnt)
              for (cnt = 0; domain->successor[cnt] != NULL; ++cnt)
                {
                {
                  retval = find_msg (domain->successor[cnt], msgid);
                  retval = find_msg (domain->successor[cnt], msgid);
 
 
                  if (retval != NULL)
                  if (retval != NULL)
                    break;
                    break;
                }
                }
            }
            }
 
 
          if (retval != NULL)
          if (retval != NULL)
            {
            {
              FREE_BLOCKS (block_list);
              FREE_BLOCKS (block_list);
              __set_errno (saved_errno);
              __set_errno (saved_errno);
              return retval;
              return retval;
            }
            }
        }
        }
    }
    }
  /* NOTREACHED */
  /* NOTREACHED */
}
}
 
 
#ifdef _LIBC
#ifdef _LIBC
/* Alias for function name in GNU C Library.  */
/* Alias for function name in GNU C Library.  */
weak_alias (__dcgettext, dcgettext);
weak_alias (__dcgettext, dcgettext);
#endif
#endif
 
 
 
 
static char *
static char *
find_msg (domain_file, msgid)
find_msg (domain_file, msgid)
     struct loaded_l10nfile *domain_file;
     struct loaded_l10nfile *domain_file;
     const char *msgid;
     const char *msgid;
{
{
  size_t top, act, bottom;
  size_t top, act, bottom;
  struct loaded_domain *domain;
  struct loaded_domain *domain;
 
 
  if (domain_file->decided == 0)
  if (domain_file->decided == 0)
    _nl_load_domain (domain_file);
    _nl_load_domain (domain_file);
 
 
  if (domain_file->data == NULL)
  if (domain_file->data == NULL)
    return NULL;
    return NULL;
 
 
  domain = (struct loaded_domain *) domain_file->data;
  domain = (struct loaded_domain *) domain_file->data;
 
 
  /* Locate the MSGID and its translation.  */
  /* Locate the MSGID and its translation.  */
  if (domain->hash_size > 2 && domain->hash_tab != NULL)
  if (domain->hash_size > 2 && domain->hash_tab != NULL)
    {
    {
      /* Use the hashing table.  */
      /* Use the hashing table.  */
      nls_uint32 len = strlen (msgid);
      nls_uint32 len = strlen (msgid);
      nls_uint32 hash_val = hash_string (msgid);
      nls_uint32 hash_val = hash_string (msgid);
      nls_uint32 idx = hash_val % domain->hash_size;
      nls_uint32 idx = hash_val % domain->hash_size;
      nls_uint32 incr = 1 + (hash_val % (domain->hash_size - 2));
      nls_uint32 incr = 1 + (hash_val % (domain->hash_size - 2));
      nls_uint32 nstr = W (domain->must_swap, domain->hash_tab[idx]);
      nls_uint32 nstr = W (domain->must_swap, domain->hash_tab[idx]);
 
 
      if (nstr == 0)
      if (nstr == 0)
        /* Hash table entry is empty.  */
        /* Hash table entry is empty.  */
        return NULL;
        return NULL;
 
 
      if (W (domain->must_swap, domain->orig_tab[nstr - 1].length) == len
      if (W (domain->must_swap, domain->orig_tab[nstr - 1].length) == len
          && strcmp (msgid,
          && strcmp (msgid,
                     domain->data + W (domain->must_swap,
                     domain->data + W (domain->must_swap,
                                       domain->orig_tab[nstr - 1].offset)) == 0)
                                       domain->orig_tab[nstr - 1].offset)) == 0)
        return (char *) domain->data + W (domain->must_swap,
        return (char *) domain->data + W (domain->must_swap,
                                          domain->trans_tab[nstr - 1].offset);
                                          domain->trans_tab[nstr - 1].offset);
 
 
      while (1)
      while (1)
        {
        {
          if (idx >= domain->hash_size - incr)
          if (idx >= domain->hash_size - incr)
            idx -= domain->hash_size - incr;
            idx -= domain->hash_size - incr;
          else
          else
            idx += incr;
            idx += incr;
 
 
          nstr = W (domain->must_swap, domain->hash_tab[idx]);
          nstr = W (domain->must_swap, domain->hash_tab[idx]);
          if (nstr == 0)
          if (nstr == 0)
            /* Hash table entry is empty.  */
            /* Hash table entry is empty.  */
            return NULL;
            return NULL;
 
 
          if (W (domain->must_swap, domain->orig_tab[nstr - 1].length) == len
          if (W (domain->must_swap, domain->orig_tab[nstr - 1].length) == len
              && strcmp (msgid,
              && strcmp (msgid,
                         domain->data + W (domain->must_swap,
                         domain->data + W (domain->must_swap,
                                           domain->orig_tab[nstr - 1].offset))
                                           domain->orig_tab[nstr - 1].offset))
                 == 0)
                 == 0)
            return (char *) domain->data
            return (char *) domain->data
              + W (domain->must_swap, domain->trans_tab[nstr - 1].offset);
              + W (domain->must_swap, domain->trans_tab[nstr - 1].offset);
        }
        }
      /* NOTREACHED */
      /* NOTREACHED */
    }
    }
 
 
  /* Now we try the default method:  binary search in the sorted
  /* Now we try the default method:  binary search in the sorted
     array of messages.  */
     array of messages.  */
  bottom = 0;
  bottom = 0;
  top = domain->nstrings;
  top = domain->nstrings;
  while (bottom < top)
  while (bottom < top)
    {
    {
      int cmp_val;
      int cmp_val;
 
 
      act = (bottom + top) / 2;
      act = (bottom + top) / 2;
      cmp_val = strcmp (msgid, domain->data
      cmp_val = strcmp (msgid, domain->data
                               + W (domain->must_swap,
                               + W (domain->must_swap,
                                    domain->orig_tab[act].offset));
                                    domain->orig_tab[act].offset));
      if (cmp_val < 0)
      if (cmp_val < 0)
        top = act;
        top = act;
      else if (cmp_val > 0)
      else if (cmp_val > 0)
        bottom = act + 1;
        bottom = act + 1;
      else
      else
        break;
        break;
    }
    }
 
 
  /* If an translation is found return this.  */
  /* If an translation is found return this.  */
  return bottom >= top ? NULL : (char *) domain->data
  return bottom >= top ? NULL : (char *) domain->data
                                + W (domain->must_swap,
                                + W (domain->must_swap,
                                     domain->trans_tab[act].offset);
                                     domain->trans_tab[act].offset);
}
}
 
 
 
 
/* Return string representation of locale CATEGORY.  */
/* Return string representation of locale CATEGORY.  */
static const char *
static const char *
category_to_name (category)
category_to_name (category)
     int category;
     int category;
{
{
  const char *retval;
  const char *retval;
 
 
  switch (category)
  switch (category)
  {
  {
#ifdef LC_COLLATE
#ifdef LC_COLLATE
  case LC_COLLATE:
  case LC_COLLATE:
    retval = "LC_COLLATE";
    retval = "LC_COLLATE";
    break;
    break;
#endif
#endif
#ifdef LC_CTYPE
#ifdef LC_CTYPE
  case LC_CTYPE:
  case LC_CTYPE:
    retval = "LC_CTYPE";
    retval = "LC_CTYPE";
    break;
    break;
#endif
#endif
#ifdef LC_MONETARY
#ifdef LC_MONETARY
  case LC_MONETARY:
  case LC_MONETARY:
    retval = "LC_MONETARY";
    retval = "LC_MONETARY";
    break;
    break;
#endif
#endif
#ifdef LC_NUMERIC
#ifdef LC_NUMERIC
  case LC_NUMERIC:
  case LC_NUMERIC:
    retval = "LC_NUMERIC";
    retval = "LC_NUMERIC";
    break;
    break;
#endif
#endif
#ifdef LC_TIME
#ifdef LC_TIME
  case LC_TIME:
  case LC_TIME:
    retval = "LC_TIME";
    retval = "LC_TIME";
    break;
    break;
#endif
#endif
#ifdef LC_MESSAGES
#ifdef LC_MESSAGES
  case LC_MESSAGES:
  case LC_MESSAGES:
    retval = "LC_MESSAGES";
    retval = "LC_MESSAGES";
    break;
    break;
#endif
#endif
#ifdef LC_RESPONSE
#ifdef LC_RESPONSE
  case LC_RESPONSE:
  case LC_RESPONSE:
    retval = "LC_RESPONSE";
    retval = "LC_RESPONSE";
    break;
    break;
#endif
#endif
#ifdef LC_ALL
#ifdef LC_ALL
  case LC_ALL:
  case LC_ALL:
    /* This might not make sense but is perhaps better than any other
    /* This might not make sense but is perhaps better than any other
       value.  */
       value.  */
    retval = "LC_ALL";
    retval = "LC_ALL";
    break;
    break;
#endif
#endif
  default:
  default:
    /* If you have a better idea for a default value let me know.  */
    /* If you have a better idea for a default value let me know.  */
    retval = "LC_XXX";
    retval = "LC_XXX";
  }
  }
 
 
  return retval;
  return retval;
}
}
 
 
/* Guess value of current locale from value of the environment variables.  */
/* Guess value of current locale from value of the environment variables.  */
static const char *
static const char *
guess_category_value (category, categoryname)
guess_category_value (category, categoryname)
     int category;
     int category;
     const char *categoryname;
     const char *categoryname;
{
{
  const char *retval;
  const char *retval;
 
 
  /* The highest priority value is the `LANGUAGE' environment
  /* The highest priority value is the `LANGUAGE' environment
     variable.  This is a GNU extension.  */
     variable.  This is a GNU extension.  */
  retval = getenv ("LANGUAGE");
  retval = getenv ("LANGUAGE");
  if (retval != NULL && retval[0] != '\0')
  if (retval != NULL && retval[0] != '\0')
    return retval;
    return retval;
 
 
  /* `LANGUAGE' is not set.  So we have to proceed with the POSIX
  /* `LANGUAGE' is not set.  So we have to proceed with the POSIX
     methods of looking to `LC_ALL', `LC_xxx', and `LANG'.  On some
     methods of looking to `LC_ALL', `LC_xxx', and `LANG'.  On some
     systems this can be done by the `setlocale' function itself.  */
     systems this can be done by the `setlocale' function itself.  */
#if defined HAVE_SETLOCALE && defined HAVE_LC_MESSAGES && defined HAVE_LOCALE_NULL
#if defined HAVE_SETLOCALE && defined HAVE_LC_MESSAGES && defined HAVE_LOCALE_NULL
  return setlocale (category, NULL);
  return setlocale (category, NULL);
#else
#else
  /* Setting of LC_ALL overwrites all other.  */
  /* Setting of LC_ALL overwrites all other.  */
  retval = getenv ("LC_ALL");
  retval = getenv ("LC_ALL");
  if (retval != NULL && retval[0] != '\0')
  if (retval != NULL && retval[0] != '\0')
    return retval;
    return retval;
 
 
  /* Next comes the name of the desired category.  */
  /* Next comes the name of the desired category.  */
  retval = getenv (categoryname);
  retval = getenv (categoryname);
  if (retval != NULL && retval[0] != '\0')
  if (retval != NULL && retval[0] != '\0')
    return retval;
    return retval;
 
 
  /* Last possibility is the LANG environment variable.  */
  /* Last possibility is the LANG environment variable.  */
  retval = getenv ("LANG");
  retval = getenv ("LANG");
  if (retval != NULL && retval[0] != '\0')
  if (retval != NULL && retval[0] != '\0')
    return retval;
    return retval;
 
 
  /* We use C as the default domain.  POSIX says this is implementation
  /* We use C as the default domain.  POSIX says this is implementation
     defined.  */
     defined.  */
  return "C";
  return "C";
#endif
#endif
}
}
 
 
/* @@ begin of epilog @@ */
/* @@ begin of epilog @@ */
 
 
/* We don't want libintl.a to depend on any other library.  So we
/* We don't want libintl.a to depend on any other library.  So we
   avoid the non-standard function stpcpy.  In GNU C Library this
   avoid the non-standard function stpcpy.  In GNU C Library this
   function is available, though.  Also allow the symbol HAVE_STPCPY
   function is available, though.  Also allow the symbol HAVE_STPCPY
   to be defined.  */
   to be defined.  */
#if !_LIBC && !HAVE_STPCPY
#if !_LIBC && !HAVE_STPCPY
static char *
static char *
stpcpy (dest, src)
stpcpy (dest, src)
     char *dest;
     char *dest;
     const char *src;
     const char *src;
{
{
  while ((*dest++ = *src++) != '\0')
  while ((*dest++ = *src++) != '\0')
    /* Do nothing. */ ;
    /* Do nothing. */ ;
  return dest - 1;
  return dest - 1;
}
}
#endif
#endif
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.