products/Sources/formale Sprachen/C/Lyx/intl image not shown  

Quellcode-Bibliothek

© Kompilation durch diese Firma

[Weder Korrektheit noch Funktionsfähigkeit der Software werden zugesichert.]

Datei: dcgettext.c   Sprache: C

Original von: Lyx©

/* Implementation of the dcgettext(3) function
   Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.

   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
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software Foundation,
   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */


#ifdef HAVE_CONFIG_H
include <config.h>
#endif

#include <sys/types.h>

#ifdef __GNUC__
define alloca __builtin_alloca
define HAVE_ALLOCA 1
#else
if defined HAVE_ALLOCA_H || defined _LIBC
#  include <alloca.h>
else
#  ifdef _AIX
 #pragma alloca
#  else
#   ifndef alloca
char *alloca ();
#   endif
#  endif
endif
#endif

#include <errno.h>
#ifndef errno
extern int errno;
#endif
#ifndef __set_errno
define __set_errno(val) errno = (val)
#endif

#if defined STDC_HEADERS || defined _LIBC
include <stdlib.h>
#else
char *getenv ();
ifdef HAVE_MALLOC_H
#  include <malloc.h>
else
void free ();
endif
#endif

#if defined HAVE_STRING_H || defined _LIBC
ifndef _GNU_SOURCE
#  define _GNU_SOURCE 1
endif
include <string.h>
#else
include <strings.h>
#endif
#if !HAVE_STRCHR && !defined _LIBC
ifndef strchr
#  define strchr index
endif
#endif

#if defined HAVE_UNISTD_H || defined _LIBC
include <unistd.h>
#endif

#include "gettext.h"
#include "gettextP.h"
#ifdef _LIBC
include <libintl.h>
#else
include "libgettext.h"
#endif
#include "hash-string.h"

/* @@ end of prolog @@ */

#ifdef _LIBC
/* Rename the non ANSI C functions.  This is required by the standard
   because some ANSI C functions will require linking with this object
   file and the name space must not be polluted.  */

define getcwd __getcwd
define stpcpy __stpcpy
#else
if !defined HAVE_GETCWD
char *getwd ();
#  define getcwd(buf, max) getwd (buf)
else
char *getcwd ();
endif
ifndef HAVE_STPCPY
static char *stpcpy PARAMS ((char *dest, const char *src));
endif
#endif

/* Amount to increase buffer size by in each try.  */
#define PATH_INCR 32

/* The following is from pathmax.h.  */
/* 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
   later included (as on MORE/BSD 4.3).  */

#if defined(_POSIX_VERSION) || (defined(HAVE_LIMITS_H) && !defined(__GNUC__))
include <limits.h>
#endif

#ifndef _POSIX_PATH_MAX
define _POSIX_PATH_MAX 255
#endif

#if !defined(PATH_MAX) && defined(_PC_PATH_MAX)
define PATH_MAX (pathconf ("/", _PC_PATH_MAX) < 1 ? 1024 : pathconf ("/", _PC_PATH_MAX))
#endif

/* Don't include sys/param.h if it already has been.  */
#if defined(HAVE_SYS_PARAM_H) && !defined(PATH_MAX) && !defined(MAXPATHLEN)
include <sys/param.h>
#endif

#if !defined(PATH_MAX) && defined(MAXPATHLEN)
define PATH_MAX MAXPATHLEN
#endif

#ifndef PATH_MAX
define PATH_MAX _POSIX_PATH_MAX
#endif

/* XPG3 defines the result of `setlocale (category, NULL)' as:
   ``Directs `setlocale()' to query `category' and return the current
     setting of `local'.''
   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
   system (e.g. those using GNU C Library).  */

#ifdef _LIBC
define HAVE_LOCALE_NULL
#endif

/* Name of the default domain used for gettext(3) prior any call to
   textdomain(3).  The default value for this is "messages".  */

const char _nl_default_default_domain[] = "messages";

/* Value used as the default domain for gettext(3).  */
const char *_nl_current_default_domain = _nl_default_default_domain;

/* Contains the default location of the message catalogs.  */
const char _nl_default_dirname[] = GNULOCALEDIR;

/* List with bindings of specific domains created by bindtextdomain()
   calls.  */

struct binding *_nl_domain_bindings;

/* Prototypes for local functions.  */
static char *find_msg PARAMS ((struct loaded_l10nfile *domain_file,
          const char *msgid));
static const char *category_to_name PARAMS ((int category));
static const char *guess_category_value PARAMS ((int category,
       const char *categoryname));


/* For those loosing systems which don't have `alloca' we have to add
   some additional code emulating it.  */

#ifdef HAVE_ALLOCA
/* Nothing has to be done.  */
define ADD_BLOCK(list, address) /* nothing */
define FREE_BLOCKS(list) /* nothing */
#else
struct block_list
{
  void *address;
  struct block_list *next;
};
define ADD_BLOCK(list, addr)            \
  do {               \
    struct block_list *newp = (struct block_list *) malloc (sizeof (*newp));  \
    /* If we cannot get a free block we cannot add the new element to       \
       the list.  */

    if (newp != NULL) {             \
      newp->address = (addr);            \
      newp->next = (list);            \
      (list) = newp;             \
    }               \
  } while (0)
define FREE_BLOCKS(list)            \
  do {               \
    while (list != NULL) {            \
      struct block_list *old = list;           \
      list = list->next;            \
      free (old);             \
    }               \
  } while (0)
undef alloca
define alloca(size) (malloc (size))
#endif /* have alloca */


/* Names for the libintl functions are a problem.  They must not clash
   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 __
   prefix.  So we have to make a difference here.  */

#ifdef _LIBC
define DCGETTEXT __dcgettext
#else
define DCGETTEXT dcgettext__
#endif

/* Look up MSGID in the DOMAINNAME message catalog for the current CATEGORY
   locale.  */

char *
DCGETTEXT (domainname, msgid, category)
     const char *domainname;
     const char *msgid;
     int category;
{
#ifndef HAVE_ALLOCA
  struct block_list *block_list = NULL;
#endif
  struct loaded_l10nfile *domain;
  struct binding *binding;
  const char *categoryname;
  const char *categoryvalue;
  char *dirname, *xdomainname;
  char *single_locale;
  char *retval;
  int saved_errno = errno;

  /* If no real MSGID is given return NULL.  */
  if (msgid == NULL)
    return NULL;

  /* 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
     defintion left this undefined.  */

  if (domainname == NULL)
    domainname = _nl_current_default_domain;

  /* First find matching binding.  */
  for (binding = _nl_domain_bindings; binding != NULL; binding = binding->next)
    {
      int compare = strcmp (domainname, binding->domainname);
      if (compare == 0)
 /* We found it!  */
 break;
      if (compare < 0)
 {
   /* It is not in the list.  */
   binding = NULL;
   break;
 }
    }

  if (binding == NULL)
    dirname = (char *) _nl_default_dirname;
  else if (binding->dirname[0] == '/')
    dirname = binding->dirname;
  else
    {
      /* We have a relative path.  Make it absolute now.  */
      size_t dirname_len = strlen (binding->dirname) + 1;
      size_t path_max;
      char *ret;

      path_max = (unsigned) PATH_MAX;
      path_max += 2;  /* The getcwd docs say to do this.  */

      dirname = (char *) alloca (path_max + dirname_len);
      ADD_BLOCK (block_list, dirname);

      __set_errno (0);
      while ((ret = getcwd (dirname, path_max)) == NULL && errno == ERANGE)
 {
   path_max += PATH_INCR;
   dirname = (char *) alloca (path_max + dirname_len);
   ADD_BLOCK (block_list, dirname);
   __set_errno (0);
 }

      if (ret == NULL)
 {
   /* We cannot get the current working directory.  Don't signal an
     error but simply return the default string.  */

   FREE_BLOCKS (block_list);
   __set_errno (saved_errno);
   return (char *) msgid;
 }

      /* 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 function is available, though.  Also allow the symbol
 HAVE_STPCPY to be defined.  */

      stpcpy (stpcpy (strchr (dirname, '\0'), "/"), binding->dirname);
    }

  /* Now determine the symbolic name of CATEGORY and its value.  */
  categoryname = category_to_name (category);
  categoryvalue = guess_category_value (category, categoryname);

  xdomainname = (char *) alloca (strlen (categoryname)
     + strlen (domainname) + 5);
  ADD_BLOCK (block_list, xdomainname);
  /* 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
     function is available, though.  Also allow the symbol HAVE_STPCPY
     to be defined.  */

  stpcpy (stpcpy (stpcpy (stpcpy (xdomainname, categoryname), "/"),
    domainname),
   ".mo");

  /* Creating working area.  */
  single_locale = (char *) alloca (strlen (categoryvalue) + 1);
  ADD_BLOCK (block_list, single_locale);


  /* Search for the given string.  This is a loop because we perhaps
     got an ordered list of languages to consider for th translation.  */

  while (1)
    {
      /* Make CATEGORYVALUE point to the next element of the list.  */
      while (categoryvalue[0] != '\0' && categoryvalue[0] == ':')
 ++categoryvalue;
      if (categoryvalue[0] == '\0')
 {
   /* The whole contents of CATEGORYVALUE has been searched but
     no valid entry has been found.  We solve this situation
     by implicitly appending a "C" entry, i.e. no translation
     will take place.  */

   single_locale[0] = 'C';
   single_locale[1] = '\0';
 }
      else
 {
   char *cp = single_locale;
   while (categoryvalue[0] != '\0' && categoryvalue[0] != ':')
     *cp++ = *categoryvalue++;
   *cp = '\0';
 }

      /* If the current locale value is C (or POSIX) we don't load a
 domain.  Return the MSGID.  */

      if (strcmp (single_locale, "C") == 0
   || strcmp (single_locale, "POSIX") == 0)
 {
   FREE_BLOCKS (block_list);
   __set_errno (saved_errno);
   return (char *) msgid;
 }


      /* Find structure describing the message catalog matching the
 DOMAINNAME and CATEGORY.  */

      domain = _nl_find_domain (dirname, single_locale, xdomainname);

      if (domain != NULL)
 {
   retval = find_msg (domain, msgid);

   if (retval == NULL)
     {
       int cnt;

       for (cnt = 0; domain->successor[cnt] != NULL; ++cnt)
  {
    retval = find_msg (domain->successor[cnt], msgid);

    if (retval != NULL)
      break;
  }
     }

   if (retval != NULL)
     {
       FREE_BLOCKS (block_list);
       __set_errno (saved_errno);
       return retval;
     }
 }
    }
  /* NOTREACHED */
}

#ifdef _LIBC
/* Alias for function name in GNU C Library.  */
weak_alias (__dcgettext, dcgettext);
#endif


static char *
find_msg (domain_file, msgid)
     struct loaded_l10nfile *domain_file;
     const char *msgid;
{
  size_t top, act, bottom;
  struct loaded_domain *domain;

  if (domain_file->decided == 0)
    _nl_load_domain (domain_file);

  if (domain_file->data == NULL)
    return NULL;

  domain = (struct loaded_domain *) domain_file->data;

  /* Locate the MSGID and its translation.  */
  if (domain->hash_size > 2 && domain->hash_tab != NULL)
    {
      /* Use the hashing table.  */
      nls_uint32 len = strlen (msgid);
      nls_uint32 hash_val = hash_string (msgid);
      nls_uint32 idx = hash_val % domain->hash_size;
      nls_uint32 incr = 1 + (hash_val % (domain->hash_size - 2));
      nls_uint32 nstr = W (domain->must_swap, domain->hash_tab[idx]);

      if (nstr == 0)
 /* Hash table entry is empty.  */
 return NULL;

      if (W (domain->must_swap, domain->orig_tab[nstr - 1].length) == len
   && strcmp (msgid,
       domain->data + W (domain->must_swap,
           domain->orig_tab[nstr - 1].offset)) == 0)
 return (char *) domain->data + W (domain->must_swap,
       domain->trans_tab[nstr - 1].offset);

      while (1)
 {
   if (idx >= domain->hash_size - incr)
     idx -= domain->hash_size - incr;
   else
     idx += incr;

   nstr = W (domain->must_swap, domain->hash_tab[idx]);
   if (nstr == 0)
     /* Hash table entry is empty.  */
     return NULL;

   if (W (domain->must_swap, domain->orig_tab[nstr - 1].length) == len
       && strcmp (msgid,
    domain->data + W (domain->must_swap,
        domain->orig_tab[nstr - 1].offset))
          == 0)
     return (char *) domain->data
       + W (domain->must_swap, domain->trans_tab[nstr - 1].offset);
 }
      /* NOTREACHED */
    }

  /* Now we try the default method:  binary search in the sorted
     array of messages.  */

  bottom = 0;
  top = domain->nstrings;
  while (bottom < top)
    {
      int cmp_val;

      act = (bottom + top) / 2;
      cmp_val = strcmp (msgid, domain->data
          + W (domain->must_swap,
        domain->orig_tab[act].offset));
      if (cmp_val < 0)
 top = act;
      else if (cmp_val > 0)
 bottom = act + 1;
      else
 break;
    }

  /* If an translation is found return this.  */
  return bottom >= top ? NULL : (char *) domain->data
                                + W (domain->must_swap,
         domain->trans_tab[act].offset);
}


/* Return string representation of locale CATEGORY.  */
static const char *
category_to_name (category)
     int category;
{
  const char *retval;

  switch (category)
  {
#ifdef LC_COLLATE
  case LC_COLLATE:
    retval = "LC_COLLATE";
    break;
#endif
#ifdef LC_CTYPE
  case LC_CTYPE:
    retval = "LC_CTYPE";
    break;
#endif
#ifdef LC_MONETARY
  case LC_MONETARY:
    retval = "LC_MONETARY";
    break;
#endif
#ifdef LC_NUMERIC
  case LC_NUMERIC:
    retval = "LC_NUMERIC";
    break;
#endif
#ifdef LC_TIME
  case LC_TIME:
    retval = "LC_TIME";
    break;
#endif
#ifdef LC_MESSAGES
  case LC_MESSAGES:
    retval = "LC_MESSAGES";
    break;
#endif
#ifdef LC_RESPONSE
  case LC_RESPONSE:
    retval = "LC_RESPONSE";
    break;
#endif
#ifdef LC_ALL
  case LC_ALL:
    /* This might not make sense but is perhaps better than any other
       value.  */

    retval = "LC_ALL";
    break;
#endif
  default:
    /* If you have a better idea for a default value let me know.  */
    retval = "LC_XXX";
  }

  return retval;
}

/* Guess value of current locale from value of the environment variables.  */
static const char *
guess_category_value (category, categoryname)
     int category;
     const char *categoryname;
{
  const char *retval;

  /* The highest priority value is the `LANGUAGE' environment
     variable.  This is a GNU extension.  */

  retval = getenv ("LANGUAGE");
  if (retval != NULL && retval[0] != '\0')
    return retval;

  /* `LANGUAGE' is not set.  So we have to proceed with the POSIX
     methods of looking to `LC_ALL', `LC_xxx', and `LANG'.  On some
     systems this can be done by the `setlocale' function itself.  */

#if defined HAVE_SETLOCALE && defined HAVE_LC_MESSAGES && defined HAVE_LOCALE_NULL
  return setlocale (category, NULL);
#else
  /* Setting of LC_ALL overwrites all other.  */
  retval = getenv ("LC_ALL");
  if (retval != NULL && retval[0] != '\0')
    return retval;

  /* Next comes the name of the desired category.  */
  retval = getenv (categoryname);
  if (retval != NULL && retval[0] != '\0')
    return retval;

  /* Last possibility is the LANG environment variable.  */
  retval = getenv ("LANG");
  if (retval != NULL && retval[0] != '\0')
    return retval;

  /* We use C as the default domain.  POSIX says this is implementation
     defined.  */

  return "C";
#endif
}

/* @@ begin of epilog @@ */

/* 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
   function is available, though.  Also allow the symbol HAVE_STPCPY
   to be defined.  */

#if !_LIBC && !HAVE_STPCPY
static char *
stpcpy (dest, src)
     char *dest;
     const char *src;
{
  while ((*dest++ = *src++) != '\0')
    /* Do nothing. */ ;
  return dest - 1;
}
#endif

¤ Dauer der Verarbeitung: 0.22 Sekunden  (vorverarbeitet)  ¤





Download des
Quellennavigators
Download des
sprechenden Kalenders

in der Quellcodebibliothek suchen




Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.


Bemerkung:

Die farbliche Syntaxdarstellung ist noch experimentell.


Bot Zugriff