mirror of
git://git.gnupg.org/gnupg.git
synced 2025-01-03 12:11:33 +01:00
Gettexized
This commit is contained in:
parent
23704255af
commit
8ed48ad2f8
114
intl/eval-plural.h
Normal file
114
intl/eval-plural.h
Normal file
@ -0,0 +1,114 @@
|
||||
/* Plural expression evaluation.
|
||||
Copyright (C) 2000-2002 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Library 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library 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. */
|
||||
|
||||
#ifndef STATIC
|
||||
#define STATIC static
|
||||
#endif
|
||||
|
||||
/* Evaluate the plural expression and return an index value. */
|
||||
STATIC unsigned long int plural_eval PARAMS ((struct expression *pexp,
|
||||
unsigned long int n))
|
||||
internal_function;
|
||||
|
||||
STATIC
|
||||
unsigned long int
|
||||
internal_function
|
||||
plural_eval (pexp, n)
|
||||
struct expression *pexp;
|
||||
unsigned long int n;
|
||||
{
|
||||
switch (pexp->nargs)
|
||||
{
|
||||
case 0:
|
||||
switch (pexp->operation)
|
||||
{
|
||||
case var:
|
||||
return n;
|
||||
case num:
|
||||
return pexp->val.num;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
/* NOTREACHED */
|
||||
break;
|
||||
case 1:
|
||||
{
|
||||
/* pexp->operation must be lnot. */
|
||||
unsigned long int arg = plural_eval (pexp->val.args[0], n);
|
||||
return ! arg;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
unsigned long int leftarg = plural_eval (pexp->val.args[0], n);
|
||||
if (pexp->operation == lor)
|
||||
return leftarg || plural_eval (pexp->val.args[1], n);
|
||||
else if (pexp->operation == land)
|
||||
return leftarg && plural_eval (pexp->val.args[1], n);
|
||||
else
|
||||
{
|
||||
unsigned long int rightarg = plural_eval (pexp->val.args[1], n);
|
||||
|
||||
switch (pexp->operation)
|
||||
{
|
||||
case mult:
|
||||
return leftarg * rightarg;
|
||||
case divide:
|
||||
#if !INTDIV0_RAISES_SIGFPE
|
||||
if (rightarg == 0)
|
||||
raise (SIGFPE);
|
||||
#endif
|
||||
return leftarg / rightarg;
|
||||
case module:
|
||||
#if !INTDIV0_RAISES_SIGFPE
|
||||
if (rightarg == 0)
|
||||
raise (SIGFPE);
|
||||
#endif
|
||||
return leftarg % rightarg;
|
||||
case plus:
|
||||
return leftarg + rightarg;
|
||||
case minus:
|
||||
return leftarg - rightarg;
|
||||
case less_than:
|
||||
return leftarg < rightarg;
|
||||
case greater_than:
|
||||
return leftarg > rightarg;
|
||||
case less_or_equal:
|
||||
return leftarg <= rightarg;
|
||||
case greater_or_equal:
|
||||
return leftarg >= rightarg;
|
||||
case equal:
|
||||
return leftarg == rightarg;
|
||||
case not_equal:
|
||||
return leftarg != rightarg;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* NOTREACHED */
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
/* pexp->operation must be qmop. */
|
||||
unsigned long int boolarg = plural_eval (pexp->val.args[0], n);
|
||||
return plural_eval (pexp->val.args[boolarg ? 1 : 2], n);
|
||||
}
|
||||
}
|
||||
/* NOTREACHED */
|
||||
return 0;
|
||||
}
|
148
intl/gmo.h
Normal file
148
intl/gmo.h
Normal file
@ -0,0 +1,148 @@
|
||||
/* Description of GNU message catalog format: general file layout.
|
||||
Copyright (C) 1995, 1997, 2000-2002 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Library 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library 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. */
|
||||
|
||||
#ifndef _GETTEXT_H
|
||||
#define _GETTEXT_H 1
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
/* @@ end of prolog @@ */
|
||||
|
||||
/* The magic number of the GNU message catalog format. */
|
||||
#define _MAGIC 0x950412de
|
||||
#define _MAGIC_SWAPPED 0xde120495
|
||||
|
||||
/* Revision number of the currently used .mo (binary) file format. */
|
||||
#define MO_REVISION_NUMBER 0
|
||||
|
||||
/* The following contortions are an attempt to use the C preprocessor
|
||||
to determine an unsigned integral type that is 32 bits wide. An
|
||||
alternative approach is to use autoconf's AC_CHECK_SIZEOF macro, but
|
||||
as of version autoconf-2.13, the AC_CHECK_SIZEOF macro doesn't work
|
||||
when cross-compiling. */
|
||||
|
||||
#if __STDC__
|
||||
# define UINT_MAX_32_BITS 4294967295U
|
||||
#else
|
||||
# define UINT_MAX_32_BITS 0xFFFFFFFF
|
||||
#endif
|
||||
|
||||
/* If UINT_MAX isn't defined, assume it's a 32-bit type.
|
||||
This should be valid for all systems GNU cares about because
|
||||
that doesn't include 16-bit systems, and only modern systems
|
||||
(that certainly have <limits.h>) have 64+-bit integral types. */
|
||||
|
||||
#ifndef UINT_MAX
|
||||
# define UINT_MAX UINT_MAX_32_BITS
|
||||
#endif
|
||||
|
||||
#if UINT_MAX == UINT_MAX_32_BITS
|
||||
typedef unsigned nls_uint32;
|
||||
#else
|
||||
# if USHRT_MAX == UINT_MAX_32_BITS
|
||||
typedef unsigned short nls_uint32;
|
||||
# else
|
||||
# if ULONG_MAX == UINT_MAX_32_BITS
|
||||
typedef unsigned long nls_uint32;
|
||||
# else
|
||||
/* The following line is intended to throw an error. Using #error is
|
||||
not portable enough. */
|
||||
"Cannot determine unsigned 32-bit data type."
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
/* Header for binary .mo file format. */
|
||||
struct mo_file_header
|
||||
{
|
||||
/* The magic number. */
|
||||
nls_uint32 magic;
|
||||
/* The revision number of the file format. */
|
||||
nls_uint32 revision;
|
||||
|
||||
/* The following are only used in .mo files with major revision 0. */
|
||||
|
||||
/* The number of strings pairs. */
|
||||
nls_uint32 nstrings;
|
||||
/* Offset of table with start offsets of original strings. */
|
||||
nls_uint32 orig_tab_offset;
|
||||
/* Offset of table with start offsets of translated strings. */
|
||||
nls_uint32 trans_tab_offset;
|
||||
/* Size of hash table. */
|
||||
nls_uint32 hash_tab_size;
|
||||
/* Offset of first hash table entry. */
|
||||
nls_uint32 hash_tab_offset;
|
||||
|
||||
/* The following are only used in .mo files with minor revision >= 1. */
|
||||
|
||||
/* The number of system dependent segments. */
|
||||
nls_uint32 n_sysdep_segments;
|
||||
/* Offset of table describing system dependent segments. */
|
||||
nls_uint32 sysdep_segments_offset;
|
||||
/* The number of system dependent strings pairs. */
|
||||
nls_uint32 n_sysdep_strings;
|
||||
/* Offset of table with start offsets of original sysdep strings. */
|
||||
nls_uint32 orig_sysdep_tab_offset;
|
||||
/* Offset of table with start offsets of translated sysdep strings. */
|
||||
nls_uint32 trans_sysdep_tab_offset;
|
||||
};
|
||||
|
||||
/* Descriptor for static string contained in the binary .mo file. */
|
||||
struct string_desc
|
||||
{
|
||||
/* Length of addressed string, not including the trailing NUL. */
|
||||
nls_uint32 length;
|
||||
/* Offset of string in file. */
|
||||
nls_uint32 offset;
|
||||
};
|
||||
|
||||
/* The following are only used in .mo files with minor revision >= 1. */
|
||||
|
||||
/* Descriptor for system dependent string segment. */
|
||||
struct sysdep_segment
|
||||
{
|
||||
/* Length of addressed string, including the trailing NUL. */
|
||||
nls_uint32 length;
|
||||
/* Offset of string in file. */
|
||||
nls_uint32 offset;
|
||||
};
|
||||
|
||||
/* Descriptor for system dependent string. */
|
||||
struct sysdep_string
|
||||
{
|
||||
/* Offset of static string segments in file. */
|
||||
nls_uint32 offset;
|
||||
/* Alternating sequence of static and system dependent segments.
|
||||
The last segment is a static segment, including the trailing NUL. */
|
||||
struct segment_pair
|
||||
{
|
||||
/* Size of static segment. */
|
||||
nls_uint32 segsize;
|
||||
/* Reference to system dependent string segment, or ~0 at the end. */
|
||||
nls_uint32 sysdepref;
|
||||
} segments[1];
|
||||
};
|
||||
|
||||
/* Marker for the end of the segments[] array. This has the value 0xFFFFFFFF,
|
||||
regardless whether 'int' is 16 bit, 32 bit, or 64 bit. */
|
||||
#define SEGMENTS_END ((nls_uint32) ~0)
|
||||
|
||||
/* @@ begin of epilog @@ */
|
||||
|
||||
#endif /* gettext.h */
|
309
intl/libgnuintl.h.in
Normal file
309
intl/libgnuintl.h.in
Normal file
@ -0,0 +1,309 @@
|
||||
/* Message catalogs for internationalization.
|
||||
Copyright (C) 1995-1997, 2000-2003 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Library 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library 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. */
|
||||
|
||||
#ifndef _LIBINTL_H
|
||||
#define _LIBINTL_H 1
|
||||
|
||||
#include <locale.h>
|
||||
|
||||
/* The LC_MESSAGES locale category is the category used by the functions
|
||||
gettext() and dgettext(). It is specified in POSIX, but not in ANSI C.
|
||||
On systems that don't define it, use an arbitrary value instead.
|
||||
On Solaris, <locale.h> defines __LOCALE_H (or _LOCALE_H in Solaris 2.5)
|
||||
then includes <libintl.h> (i.e. this file!) and then only defines
|
||||
LC_MESSAGES. To avoid a redefinition warning, don't define LC_MESSAGES
|
||||
in this case. */
|
||||
#if !defined LC_MESSAGES && !(defined __LOCALE_H || (defined _LOCALE_H && defined __sun))
|
||||
# define LC_MESSAGES 1729
|
||||
#endif
|
||||
|
||||
/* We define an additional symbol to signal that we use the GNU
|
||||
implementation of gettext. */
|
||||
#define __USE_GNU_GETTEXT 1
|
||||
|
||||
/* Provide information about the supported file formats. Returns the
|
||||
maximum minor revision number supported for a given major revision. */
|
||||
#define __GNU_GETTEXT_SUPPORTED_REVISION(major) \
|
||||
((major) == 0 ? 1 : -1)
|
||||
|
||||
/* Resolve a platform specific conflict on DJGPP. GNU gettext takes
|
||||
precedence over _conio_gettext. */
|
||||
#ifdef __DJGPP__
|
||||
# undef gettext
|
||||
#endif
|
||||
|
||||
/* Use _INTL_PARAMS, not PARAMS, in order to avoid clashes with identifiers
|
||||
used by programs. Similarly, test __PROTOTYPES, not PROTOTYPES. */
|
||||
#ifndef _INTL_PARAMS
|
||||
# if __STDC__ || defined __GNUC__ || defined __SUNPRO_C || defined __cplusplus || __PROTOTYPES
|
||||
# define _INTL_PARAMS(args) args
|
||||
# else
|
||||
# define _INTL_PARAMS(args) ()
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/* We redirect the functions to those prefixed with "libintl_". This is
|
||||
necessary, because some systems define gettext/textdomain/... in the C
|
||||
library (namely, Solaris 2.4 and newer, and GNU libc 2.0 and newer).
|
||||
If we used the unprefixed names, there would be cases where the
|
||||
definition in the C library would override the one in the libintl.so
|
||||
shared library. Recall that on ELF systems, the symbols are looked
|
||||
up in the following order:
|
||||
1. in the executable,
|
||||
2. in the shared libraries specified on the link command line, in order,
|
||||
3. in the dependencies of the shared libraries specified on the link
|
||||
command line,
|
||||
4. in the dlopen()ed shared libraries, in the order in which they were
|
||||
dlopen()ed.
|
||||
The definition in the C library would override the one in libintl.so if
|
||||
either
|
||||
* -lc is given on the link command line and -lintl isn't, or
|
||||
* -lc is given on the link command line before -lintl, or
|
||||
* libintl.so is a dependency of a dlopen()ed shared library but not
|
||||
linked to the executable at link time.
|
||||
Since Solaris gettext() behaves differently than GNU gettext(), this
|
||||
would be unacceptable.
|
||||
|
||||
The redirection happens by default through macros in C, so that &gettext
|
||||
is independent of the compilation unit, but through inline functions in
|
||||
C++, in order not to interfere with the name mangling of class fields or
|
||||
class methods called 'gettext'. */
|
||||
|
||||
/* The user can define _INTL_REDIRECT_INLINE or _INTL_REDIRECT_MACROS.
|
||||
If he doesn't, we choose the method. A third possible method is
|
||||
_INTL_REDIRECT_ASM, supported only by GCC. */
|
||||
#if !(defined _INTL_REDIRECT_INLINE || defined _INTL_REDIRECT_MACROS)
|
||||
# if __GNUC__ >= 2 && !defined __APPLE_CC__ && (defined __STDC__ || defined __cplusplus)
|
||||
# define _INTL_REDIRECT_ASM
|
||||
# else
|
||||
# ifdef __cplusplus
|
||||
# define _INTL_REDIRECT_INLINE
|
||||
# else
|
||||
# define _INTL_REDIRECT_MACROS
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
/* Auxiliary macros. */
|
||||
#ifdef _INTL_REDIRECT_ASM
|
||||
# define _INTL_ASM(cname) __asm__ (_INTL_ASMNAME (__USER_LABEL_PREFIX__, #cname))
|
||||
# define _INTL_ASMNAME(prefix,cnamestring) _INTL_STRINGIFY (prefix) cnamestring
|
||||
# define _INTL_STRINGIFY(prefix) #prefix
|
||||
#else
|
||||
# define _INTL_ASM(cname)
|
||||
#endif
|
||||
|
||||
/* Look up MSGID in the current default message catalog for the current
|
||||
LC_MESSAGES locale. If not found, returns MSGID itself (the default
|
||||
text). */
|
||||
#ifdef _INTL_REDIRECT_INLINE
|
||||
extern char *libintl_gettext (const char *__msgid);
|
||||
static inline char *gettext (const char *__msgid)
|
||||
{
|
||||
return libintl_gettext (__msgid);
|
||||
}
|
||||
#else
|
||||
#ifdef _INTL_REDIRECT_MACROS
|
||||
# define gettext libintl_gettext
|
||||
#endif
|
||||
extern char *gettext _INTL_PARAMS ((const char *__msgid))
|
||||
_INTL_ASM (libintl_gettext);
|
||||
#endif
|
||||
|
||||
/* Look up MSGID in the DOMAINNAME message catalog for the current
|
||||
LC_MESSAGES locale. */
|
||||
#ifdef _INTL_REDIRECT_INLINE
|
||||
extern char *libintl_dgettext (const char *__domainname, const char *__msgid);
|
||||
static inline char *dgettext (const char *__domainname, const char *__msgid)
|
||||
{
|
||||
return libintl_dgettext (__domainname, __msgid);
|
||||
}
|
||||
#else
|
||||
#ifdef _INTL_REDIRECT_MACROS
|
||||
# define dgettext libintl_dgettext
|
||||
#endif
|
||||
extern char *dgettext _INTL_PARAMS ((const char *__domainname,
|
||||
const char *__msgid))
|
||||
_INTL_ASM (libintl_dgettext);
|
||||
#endif
|
||||
|
||||
/* Look up MSGID in the DOMAINNAME message catalog for the current CATEGORY
|
||||
locale. */
|
||||
#ifdef _INTL_REDIRECT_INLINE
|
||||
extern char *libintl_dcgettext (const char *__domainname, const char *__msgid,
|
||||
int __category);
|
||||
static inline char *dcgettext (const char *__domainname, const char *__msgid,
|
||||
int __category)
|
||||
{
|
||||
return libintl_dcgettext (__domainname, __msgid, __category);
|
||||
}
|
||||
#else
|
||||
#ifdef _INTL_REDIRECT_MACROS
|
||||
# define dcgettext libintl_dcgettext
|
||||
#endif
|
||||
extern char *dcgettext _INTL_PARAMS ((const char *__domainname,
|
||||
const char *__msgid,
|
||||
int __category))
|
||||
_INTL_ASM (libintl_dcgettext);
|
||||
#endif
|
||||
|
||||
|
||||
/* Similar to `gettext' but select the plural form corresponding to the
|
||||
number N. */
|
||||
#ifdef _INTL_REDIRECT_INLINE
|
||||
extern char *libintl_ngettext (const char *__msgid1, const char *__msgid2,
|
||||
unsigned long int __n);
|
||||
static inline char *ngettext (const char *__msgid1, const char *__msgid2,
|
||||
unsigned long int __n)
|
||||
{
|
||||
return libintl_ngettext (__msgid1, __msgid2, __n);
|
||||
}
|
||||
#else
|
||||
#ifdef _INTL_REDIRECT_MACROS
|
||||
# define ngettext libintl_ngettext
|
||||
#endif
|
||||
extern char *ngettext _INTL_PARAMS ((const char *__msgid1,
|
||||
const char *__msgid2,
|
||||
unsigned long int __n))
|
||||
_INTL_ASM (libintl_ngettext);
|
||||
#endif
|
||||
|
||||
/* Similar to `dgettext' but select the plural form corresponding to the
|
||||
number N. */
|
||||
#ifdef _INTL_REDIRECT_INLINE
|
||||
extern char *libintl_dngettext (const char *__domainname, const char *__msgid1,
|
||||
const char *__msgid2, unsigned long int __n);
|
||||
static inline char *dngettext (const char *__domainname, const char *__msgid1,
|
||||
const char *__msgid2, unsigned long int __n)
|
||||
{
|
||||
return libintl_dngettext (__domainname, __msgid1, __msgid2, __n);
|
||||
}
|
||||
#else
|
||||
#ifdef _INTL_REDIRECT_MACROS
|
||||
# define dngettext libintl_dngettext
|
||||
#endif
|
||||
extern char *dngettext _INTL_PARAMS ((const char *__domainname,
|
||||
const char *__msgid1,
|
||||
const char *__msgid2,
|
||||
unsigned long int __n))
|
||||
_INTL_ASM (libintl_dngettext);
|
||||
#endif
|
||||
|
||||
/* Similar to `dcgettext' but select the plural form corresponding to the
|
||||
number N. */
|
||||
#ifdef _INTL_REDIRECT_INLINE
|
||||
extern char *libintl_dcngettext (const char *__domainname,
|
||||
const char *__msgid1, const char *__msgid2,
|
||||
unsigned long int __n, int __category);
|
||||
static inline char *dcngettext (const char *__domainname,
|
||||
const char *__msgid1, const char *__msgid2,
|
||||
unsigned long int __n, int __category)
|
||||
{
|
||||
return libintl_dcngettext (__domainname, __msgid1, __msgid2, __n, __category);
|
||||
}
|
||||
#else
|
||||
#ifdef _INTL_REDIRECT_MACROS
|
||||
# define dcngettext libintl_dcngettext
|
||||
#endif
|
||||
extern char *dcngettext _INTL_PARAMS ((const char *__domainname,
|
||||
const char *__msgid1,
|
||||
const char *__msgid2,
|
||||
unsigned long int __n,
|
||||
int __category))
|
||||
_INTL_ASM (libintl_dcngettext);
|
||||
#endif
|
||||
|
||||
|
||||
/* Set the current default message catalog to DOMAINNAME.
|
||||
If DOMAINNAME is null, return the current default.
|
||||
If DOMAINNAME is "", reset to the default of "messages". */
|
||||
#ifdef _INTL_REDIRECT_INLINE
|
||||
extern char *libintl_textdomain (const char *__domainname);
|
||||
static inline char *textdomain (const char *__domainname)
|
||||
{
|
||||
return libintl_textdomain (__domainname);
|
||||
}
|
||||
#else
|
||||
#ifdef _INTL_REDIRECT_MACROS
|
||||
# define textdomain libintl_textdomain
|
||||
#endif
|
||||
extern char *textdomain _INTL_PARAMS ((const char *__domainname))
|
||||
_INTL_ASM (libintl_textdomain);
|
||||
#endif
|
||||
|
||||
/* Specify that the DOMAINNAME message catalog will be found
|
||||
in DIRNAME rather than in the system locale data base. */
|
||||
#ifdef _INTL_REDIRECT_INLINE
|
||||
extern char *libintl_bindtextdomain (const char *__domainname,
|
||||
const char *__dirname);
|
||||
static inline char *bindtextdomain (const char *__domainname,
|
||||
const char *__dirname)
|
||||
{
|
||||
return libintl_bindtextdomain (__domainname, __dirname);
|
||||
}
|
||||
#else
|
||||
#ifdef _INTL_REDIRECT_MACROS
|
||||
# define bindtextdomain libintl_bindtextdomain
|
||||
#endif
|
||||
extern char *bindtextdomain _INTL_PARAMS ((const char *__domainname,
|
||||
const char *__dirname))
|
||||
_INTL_ASM (libintl_bindtextdomain);
|
||||
#endif
|
||||
|
||||
/* Specify the character encoding in which the messages from the
|
||||
DOMAINNAME message catalog will be returned. */
|
||||
#ifdef _INTL_REDIRECT_INLINE
|
||||
extern char *libintl_bind_textdomain_codeset (const char *__domainname,
|
||||
const char *__codeset);
|
||||
static inline char *bind_textdomain_codeset (const char *__domainname,
|
||||
const char *__codeset)
|
||||
{
|
||||
return libintl_bind_textdomain_codeset (__domainname, __codeset);
|
||||
}
|
||||
#else
|
||||
#ifdef _INTL_REDIRECT_MACROS
|
||||
# define bind_textdomain_codeset libintl_bind_textdomain_codeset
|
||||
#endif
|
||||
extern char *bind_textdomain_codeset _INTL_PARAMS ((const char *__domainname,
|
||||
const char *__codeset))
|
||||
_INTL_ASM (libintl_bind_textdomain_codeset);
|
||||
#endif
|
||||
|
||||
|
||||
/* Support for relocatable packages. */
|
||||
|
||||
/* Sets the original and the current installation prefix of the package.
|
||||
Relocation simply replaces a pathname starting with the original prefix
|
||||
by the corresponding pathname with the current prefix instead. Both
|
||||
prefixes should be directory names without trailing slash (i.e. use ""
|
||||
instead of "/"). */
|
||||
#define libintl_set_relocation_prefix libintl_set_relocation_prefix
|
||||
extern void
|
||||
libintl_set_relocation_prefix _INTL_PARAMS ((const char *orig_prefix,
|
||||
const char *curr_prefix));
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* libintl.h */
|
42
intl/localcharset.h
Normal file
42
intl/localcharset.h
Normal file
@ -0,0 +1,42 @@
|
||||
/* Determine a canonical name for the current locale's character encoding.
|
||||
Copyright (C) 2000-2003 Free Software Foundation, Inc.
|
||||
This file is part of the GNU CHARSET Library.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Library 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library 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. */
|
||||
|
||||
#ifndef _LOCALCHARSET_H
|
||||
#define _LOCALCHARSET_H
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/* Determine the current locale's character encoding, and canonicalize it
|
||||
into one of the canonical names listed in config.charset.
|
||||
The result must not be freed; it is statically allocated.
|
||||
If the canonical name cannot be determined, the result is a non-canonical
|
||||
name. */
|
||||
extern const char * locale_charset (void);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* _LOCALCHARSET_H */
|
772
intl/localename.c
Normal file
772
intl/localename.c
Normal file
@ -0,0 +1,772 @@
|
||||
/* Determine the current selected locale.
|
||||
Copyright (C) 1995-1999, 2000-2002 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Library 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library 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. */
|
||||
|
||||
/* Written by Ulrich Drepper <drepper@gnu.org>, 1995. */
|
||||
/* Win32 code written by Tor Lillqvist <tml@iki.fi>. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <locale.h>
|
||||
|
||||
#if defined _WIN32 || defined __WIN32__
|
||||
# undef WIN32 /* avoid warning on mingw32 */
|
||||
# define WIN32
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
# define WIN32_LEAN_AND_MEAN
|
||||
# include <windows.h>
|
||||
/* Mingw headers don't have latest language and sublanguage codes. */
|
||||
# ifndef LANG_AFRIKAANS
|
||||
# define LANG_AFRIKAANS 0x36
|
||||
# endif
|
||||
# ifndef LANG_ALBANIAN
|
||||
# define LANG_ALBANIAN 0x1c
|
||||
# endif
|
||||
# ifndef LANG_ARABIC
|
||||
# define LANG_ARABIC 0x01
|
||||
# endif
|
||||
# ifndef LANG_ARMENIAN
|
||||
# define LANG_ARMENIAN 0x2b
|
||||
# endif
|
||||
# ifndef LANG_ASSAMESE
|
||||
# define LANG_ASSAMESE 0x4d
|
||||
# endif
|
||||
# ifndef LANG_AZERI
|
||||
# define LANG_AZERI 0x2c
|
||||
# endif
|
||||
# ifndef LANG_BASQUE
|
||||
# define LANG_BASQUE 0x2d
|
||||
# endif
|
||||
# ifndef LANG_BELARUSIAN
|
||||
# define LANG_BELARUSIAN 0x23
|
||||
# endif
|
||||
# ifndef LANG_BENGALI
|
||||
# define LANG_BENGALI 0x45
|
||||
# endif
|
||||
# ifndef LANG_CATALAN
|
||||
# define LANG_CATALAN 0x03
|
||||
# endif
|
||||
# ifndef LANG_DIVEHI
|
||||
# define LANG_DIVEHI 0x65
|
||||
# endif
|
||||
# ifndef LANG_ESTONIAN
|
||||
# define LANG_ESTONIAN 0x25
|
||||
# endif
|
||||
# ifndef LANG_FAEROESE
|
||||
# define LANG_FAEROESE 0x38
|
||||
# endif
|
||||
# ifndef LANG_FARSI
|
||||
# define LANG_FARSI 0x29
|
||||
# endif
|
||||
# ifndef LANG_GALICIAN
|
||||
# define LANG_GALICIAN 0x56
|
||||
# endif
|
||||
# ifndef LANG_GEORGIAN
|
||||
# define LANG_GEORGIAN 0x37
|
||||
# endif
|
||||
# ifndef LANG_GUJARATI
|
||||
# define LANG_GUJARATI 0x47
|
||||
# endif
|
||||
# ifndef LANG_HEBREW
|
||||
# define LANG_HEBREW 0x0d
|
||||
# endif
|
||||
# ifndef LANG_HINDI
|
||||
# define LANG_HINDI 0x39
|
||||
# endif
|
||||
# ifndef LANG_INDONESIAN
|
||||
# define LANG_INDONESIAN 0x21
|
||||
# endif
|
||||
# ifndef LANG_KANNADA
|
||||
# define LANG_KANNADA 0x4b
|
||||
# endif
|
||||
# ifndef LANG_KASHMIRI
|
||||
# define LANG_KASHMIRI 0x60
|
||||
# endif
|
||||
# ifndef LANG_KAZAK
|
||||
# define LANG_KAZAK 0x3f
|
||||
# endif
|
||||
# ifndef LANG_KONKANI
|
||||
# define LANG_KONKANI 0x57
|
||||
# endif
|
||||
# ifndef LANG_KYRGYZ
|
||||
# define LANG_KYRGYZ 0x40
|
||||
# endif
|
||||
# ifndef LANG_LATVIAN
|
||||
# define LANG_LATVIAN 0x26
|
||||
# endif
|
||||
# ifndef LANG_LITHUANIAN
|
||||
# define LANG_LITHUANIAN 0x27
|
||||
# endif
|
||||
# ifndef LANG_MACEDONIAN
|
||||
# define LANG_MACEDONIAN 0x2f
|
||||
# endif
|
||||
# ifndef LANG_MALAY
|
||||
# define LANG_MALAY 0x3e
|
||||
# endif
|
||||
# ifndef LANG_MALAYALAM
|
||||
# define LANG_MALAYALAM 0x4c
|
||||
# endif
|
||||
# ifndef LANG_MANIPURI
|
||||
# define LANG_MANIPURI 0x58
|
||||
# endif
|
||||
# ifndef LANG_MARATHI
|
||||
# define LANG_MARATHI 0x4e
|
||||
# endif
|
||||
# ifndef LANG_MONGOLIAN
|
||||
# define LANG_MONGOLIAN 0x50
|
||||
# endif
|
||||
# ifndef LANG_NEPALI
|
||||
# define LANG_NEPALI 0x61
|
||||
# endif
|
||||
# ifndef LANG_ORIYA
|
||||
# define LANG_ORIYA 0x48
|
||||
# endif
|
||||
# ifndef LANG_PUNJABI
|
||||
# define LANG_PUNJABI 0x46
|
||||
# endif
|
||||
# ifndef LANG_SANSKRIT
|
||||
# define LANG_SANSKRIT 0x4f
|
||||
# endif
|
||||
# ifndef LANG_SERBIAN
|
||||
# define LANG_SERBIAN 0x1a
|
||||
# endif
|
||||
# ifndef LANG_SINDHI
|
||||
# define LANG_SINDHI 0x59
|
||||
# endif
|
||||
# ifndef LANG_SLOVAK
|
||||
# define LANG_SLOVAK 0x1b
|
||||
# endif
|
||||
# ifndef LANG_SORBIAN
|
||||
# define LANG_SORBIAN 0x2e
|
||||
# endif
|
||||
# ifndef LANG_SWAHILI
|
||||
# define LANG_SWAHILI 0x41
|
||||
# endif
|
||||
# ifndef LANG_SYRIAC
|
||||
# define LANG_SYRIAC 0x5a
|
||||
# endif
|
||||
# ifndef LANG_TAMIL
|
||||
# define LANG_TAMIL 0x49
|
||||
# endif
|
||||
# ifndef LANG_TATAR
|
||||
# define LANG_TATAR 0x44
|
||||
# endif
|
||||
# ifndef LANG_TELUGU
|
||||
# define LANG_TELUGU 0x4a
|
||||
# endif
|
||||
# ifndef LANG_THAI
|
||||
# define LANG_THAI 0x1e
|
||||
# endif
|
||||
# ifndef LANG_UKRAINIAN
|
||||
# define LANG_UKRAINIAN 0x22
|
||||
# endif
|
||||
# ifndef LANG_URDU
|
||||
# define LANG_URDU 0x20
|
||||
# endif
|
||||
# ifndef LANG_UZBEK
|
||||
# define LANG_UZBEK 0x43
|
||||
# endif
|
||||
# ifndef LANG_VIETNAMESE
|
||||
# define LANG_VIETNAMESE 0x2a
|
||||
# endif
|
||||
# ifndef SUBLANG_ARABIC_SAUDI_ARABIA
|
||||
# define SUBLANG_ARABIC_SAUDI_ARABIA 0x01
|
||||
# endif
|
||||
# ifndef SUBLANG_ARABIC_IRAQ
|
||||
# define SUBLANG_ARABIC_IRAQ 0x02
|
||||
# endif
|
||||
# ifndef SUBLANG_ARABIC_EGYPT
|
||||
# define SUBLANG_ARABIC_EGYPT 0x03
|
||||
# endif
|
||||
# ifndef SUBLANG_ARABIC_LIBYA
|
||||
# define SUBLANG_ARABIC_LIBYA 0x04
|
||||
# endif
|
||||
# ifndef SUBLANG_ARABIC_ALGERIA
|
||||
# define SUBLANG_ARABIC_ALGERIA 0x05
|
||||
# endif
|
||||
# ifndef SUBLANG_ARABIC_MOROCCO
|
||||
# define SUBLANG_ARABIC_MOROCCO 0x06
|
||||
# endif
|
||||
# ifndef SUBLANG_ARABIC_TUNISIA
|
||||
# define SUBLANG_ARABIC_TUNISIA 0x07
|
||||
# endif
|
||||
# ifndef SUBLANG_ARABIC_OMAN
|
||||
# define SUBLANG_ARABIC_OMAN 0x08
|
||||
# endif
|
||||
# ifndef SUBLANG_ARABIC_YEMEN
|
||||
# define SUBLANG_ARABIC_YEMEN 0x09
|
||||
# endif
|
||||
# ifndef SUBLANG_ARABIC_SYRIA
|
||||
# define SUBLANG_ARABIC_SYRIA 0x0a
|
||||
# endif
|
||||
# ifndef SUBLANG_ARABIC_JORDAN
|
||||
# define SUBLANG_ARABIC_JORDAN 0x0b
|
||||
# endif
|
||||
# ifndef SUBLANG_ARABIC_LEBANON
|
||||
# define SUBLANG_ARABIC_LEBANON 0x0c
|
||||
# endif
|
||||
# ifndef SUBLANG_ARABIC_KUWAIT
|
||||
# define SUBLANG_ARABIC_KUWAIT 0x0d
|
||||
# endif
|
||||
# ifndef SUBLANG_ARABIC_UAE
|
||||
# define SUBLANG_ARABIC_UAE 0x0e
|
||||
# endif
|
||||
# ifndef SUBLANG_ARABIC_BAHRAIN
|
||||
# define SUBLANG_ARABIC_BAHRAIN 0x0f
|
||||
# endif
|
||||
# ifndef SUBLANG_ARABIC_QATAR
|
||||
# define SUBLANG_ARABIC_QATAR 0x10
|
||||
# endif
|
||||
# ifndef SUBLANG_AZERI_LATIN
|
||||
# define SUBLANG_AZERI_LATIN 0x01
|
||||
# endif
|
||||
# ifndef SUBLANG_AZERI_CYRILLIC
|
||||
# define SUBLANG_AZERI_CYRILLIC 0x02
|
||||
# endif
|
||||
# ifndef SUBLANG_CHINESE_MACAU
|
||||
# define SUBLANG_CHINESE_MACAU 0x05
|
||||
# endif
|
||||
# ifndef SUBLANG_ENGLISH_SOUTH_AFRICA
|
||||
# define SUBLANG_ENGLISH_SOUTH_AFRICA 0x07
|
||||
# endif
|
||||
# ifndef SUBLANG_ENGLISH_JAMAICA
|
||||
# define SUBLANG_ENGLISH_JAMAICA 0x08
|
||||
# endif
|
||||
# ifndef SUBLANG_ENGLISH_CARIBBEAN
|
||||
# define SUBLANG_ENGLISH_CARIBBEAN 0x09
|
||||
# endif
|
||||
# ifndef SUBLANG_ENGLISH_BELIZE
|
||||
# define SUBLANG_ENGLISH_BELIZE 0x0a
|
||||
# endif
|
||||
# ifndef SUBLANG_ENGLISH_TRINIDAD
|
||||
# define SUBLANG_ENGLISH_TRINIDAD 0x0b
|
||||
# endif
|
||||
# ifndef SUBLANG_ENGLISH_ZIMBABWE
|
||||
# define SUBLANG_ENGLISH_ZIMBABWE 0x0c
|
||||
# endif
|
||||
# ifndef SUBLANG_ENGLISH_PHILIPPINES
|
||||
# define SUBLANG_ENGLISH_PHILIPPINES 0x0d
|
||||
# endif
|
||||
# ifndef SUBLANG_FRENCH_LUXEMBOURG
|
||||
# define SUBLANG_FRENCH_LUXEMBOURG 0x05
|
||||
# endif
|
||||
# ifndef SUBLANG_FRENCH_MONACO
|
||||
# define SUBLANG_FRENCH_MONACO 0x06
|
||||
# endif
|
||||
# ifndef SUBLANG_GERMAN_LUXEMBOURG
|
||||
# define SUBLANG_GERMAN_LUXEMBOURG 0x04
|
||||
# endif
|
||||
# ifndef SUBLANG_GERMAN_LIECHTENSTEIN
|
||||
# define SUBLANG_GERMAN_LIECHTENSTEIN 0x05
|
||||
# endif
|
||||
# ifndef SUBLANG_KASHMIRI_INDIA
|
||||
# define SUBLANG_KASHMIRI_INDIA 0x02
|
||||
# endif
|
||||
# ifndef SUBLANG_MALAY_MALAYSIA
|
||||
# define SUBLANG_MALAY_MALAYSIA 0x01
|
||||
# endif
|
||||
# ifndef SUBLANG_MALAY_BRUNEI_DARUSSALAM
|
||||
# define SUBLANG_MALAY_BRUNEI_DARUSSALAM 0x02
|
||||
# endif
|
||||
# ifndef SUBLANG_NEPALI_INDIA
|
||||
# define SUBLANG_NEPALI_INDIA 0x02
|
||||
# endif
|
||||
# ifndef SUBLANG_SERBIAN_LATIN
|
||||
# define SUBLANG_SERBIAN_LATIN 0x02
|
||||
# endif
|
||||
# ifndef SUBLANG_SERBIAN_CYRILLIC
|
||||
# define SUBLANG_SERBIAN_CYRILLIC 0x03
|
||||
# endif
|
||||
# ifndef SUBLANG_SPANISH_GUATEMALA
|
||||
# define SUBLANG_SPANISH_GUATEMALA 0x04
|
||||
# endif
|
||||
# ifndef SUBLANG_SPANISH_COSTA_RICA
|
||||
# define SUBLANG_SPANISH_COSTA_RICA 0x05
|
||||
# endif
|
||||
# ifndef SUBLANG_SPANISH_PANAMA
|
||||
# define SUBLANG_SPANISH_PANAMA 0x06
|
||||
# endif
|
||||
# ifndef SUBLANG_SPANISH_DOMINICAN_REPUBLIC
|
||||
# define SUBLANG_SPANISH_DOMINICAN_REPUBLIC 0x07
|
||||
# endif
|
||||
# ifndef SUBLANG_SPANISH_VENEZUELA
|
||||
# define SUBLANG_SPANISH_VENEZUELA 0x08
|
||||
# endif
|
||||
# ifndef SUBLANG_SPANISH_COLOMBIA
|
||||
# define SUBLANG_SPANISH_COLOMBIA 0x09
|
||||
# endif
|
||||
# ifndef SUBLANG_SPANISH_PERU
|
||||
# define SUBLANG_SPANISH_PERU 0x0a
|
||||
# endif
|
||||
# ifndef SUBLANG_SPANISH_ARGENTINA
|
||||
# define SUBLANG_SPANISH_ARGENTINA 0x0b
|
||||
# endif
|
||||
# ifndef SUBLANG_SPANISH_ECUADOR
|
||||
# define SUBLANG_SPANISH_ECUADOR 0x0c
|
||||
# endif
|
||||
# ifndef SUBLANG_SPANISH_CHILE
|
||||
# define SUBLANG_SPANISH_CHILE 0x0d
|
||||
# endif
|
||||
# ifndef SUBLANG_SPANISH_URUGUAY
|
||||
# define SUBLANG_SPANISH_URUGUAY 0x0e
|
||||
# endif
|
||||
# ifndef SUBLANG_SPANISH_PARAGUAY
|
||||
# define SUBLANG_SPANISH_PARAGUAY 0x0f
|
||||
# endif
|
||||
# ifndef SUBLANG_SPANISH_BOLIVIA
|
||||
# define SUBLANG_SPANISH_BOLIVIA 0x10
|
||||
# endif
|
||||
# ifndef SUBLANG_SPANISH_EL_SALVADOR
|
||||
# define SUBLANG_SPANISH_EL_SALVADOR 0x11
|
||||
# endif
|
||||
# ifndef SUBLANG_SPANISH_HONDURAS
|
||||
# define SUBLANG_SPANISH_HONDURAS 0x12
|
||||
# endif
|
||||
# ifndef SUBLANG_SPANISH_NICARAGUA
|
||||
# define SUBLANG_SPANISH_NICARAGUA 0x13
|
||||
# endif
|
||||
# ifndef SUBLANG_SPANISH_PUERTO_RICO
|
||||
# define SUBLANG_SPANISH_PUERTO_RICO 0x14
|
||||
# endif
|
||||
# ifndef SUBLANG_SWEDISH_FINLAND
|
||||
# define SUBLANG_SWEDISH_FINLAND 0x02
|
||||
# endif
|
||||
# ifndef SUBLANG_URDU_PAKISTAN
|
||||
# define SUBLANG_URDU_PAKISTAN 0x01
|
||||
# endif
|
||||
# ifndef SUBLANG_URDU_INDIA
|
||||
# define SUBLANG_URDU_INDIA 0x02
|
||||
# endif
|
||||
# ifndef SUBLANG_UZBEK_LATIN
|
||||
# define SUBLANG_UZBEK_LATIN 0x01
|
||||
# endif
|
||||
# ifndef SUBLANG_UZBEK_CYRILLIC
|
||||
# define SUBLANG_UZBEK_CYRILLIC 0x02
|
||||
# endif
|
||||
#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. Neither do SUSV2 and
|
||||
ISO C 99. So we can use this feature only on selected systems (e.g.
|
||||
those using GNU C Library). */
|
||||
#if defined _LIBC || (defined __GNU_LIBRARY__ && __GNU_LIBRARY__ >= 2)
|
||||
# define HAVE_LOCALE_NULL
|
||||
#endif
|
||||
|
||||
/* Determine the current locale's name, and canonicalize it into XPG syntax
|
||||
language[_territory[.codeset]][@modifier]
|
||||
The codeset part in the result is not reliable; the locale_charset()
|
||||
should be used for codeset information instead.
|
||||
The result must not be freed; it is statically allocated. */
|
||||
|
||||
const char *
|
||||
_nl_locale_name (category, categoryname)
|
||||
int category;
|
||||
const char *categoryname;
|
||||
{
|
||||
const char *retval;
|
||||
|
||||
#ifndef WIN32
|
||||
|
||||
/* Use 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
|
||||
retval = setlocale (category, NULL);
|
||||
# else
|
||||
/* Setting of LC_ALL overwrites all other. */
|
||||
retval = getenv ("LC_ALL");
|
||||
if (retval == NULL || retval[0] == '\0')
|
||||
{
|
||||
/* Next comes the name of the desired category. */
|
||||
retval = getenv (categoryname);
|
||||
if (retval == NULL || retval[0] == '\0')
|
||||
{
|
||||
/* Last possibility is the LANG environment variable. */
|
||||
retval = getenv ("LANG");
|
||||
if (retval == NULL || retval[0] == '\0')
|
||||
/* We use C as the default domain. POSIX says this is
|
||||
implementation defined. */
|
||||
retval = "C";
|
||||
}
|
||||
}
|
||||
# endif
|
||||
|
||||
return retval;
|
||||
|
||||
#else /* WIN32 */
|
||||
|
||||
/* Return an XPG style locale name language[_territory][@modifier].
|
||||
Don't even bother determining the codeset; it's not useful in this
|
||||
context, because message catalogs are not specific to a single
|
||||
codeset. */
|
||||
|
||||
LCID lcid;
|
||||
LANGID langid;
|
||||
int primary, sub;
|
||||
|
||||
/* Let the user override the system settings through environment
|
||||
variables, as on POSIX systems. */
|
||||
retval = getenv ("LC_ALL");
|
||||
if (retval != NULL && retval[0] != '\0')
|
||||
return retval;
|
||||
retval = getenv (categoryname);
|
||||
if (retval != NULL && retval[0] != '\0')
|
||||
return retval;
|
||||
retval = getenv ("LANG");
|
||||
if (retval != NULL && retval[0] != '\0')
|
||||
return retval;
|
||||
|
||||
/* Use native Win32 API locale ID. */
|
||||
lcid = GetThreadLocale ();
|
||||
|
||||
/* Strip off the sorting rules, keep only the language part. */
|
||||
langid = LANGIDFROMLCID (lcid);
|
||||
|
||||
/* Split into language and territory part. */
|
||||
primary = PRIMARYLANGID (langid);
|
||||
sub = SUBLANGID (langid);
|
||||
|
||||
/* Dispatch on language.
|
||||
See also http://www.unicode.org/unicode/onlinedat/languages.html .
|
||||
For details about languages, see http://www.ethnologue.com/ . */
|
||||
switch (primary)
|
||||
{
|
||||
case LANG_AFRIKAANS: return "af_ZA";
|
||||
case LANG_ALBANIAN: return "sq_AL";
|
||||
case 0x5e: /* AMHARIC */ return "am_ET";
|
||||
case LANG_ARABIC:
|
||||
switch (sub)
|
||||
{
|
||||
case SUBLANG_ARABIC_SAUDI_ARABIA: return "ar_SA";
|
||||
case SUBLANG_ARABIC_IRAQ: return "ar_IQ";
|
||||
case SUBLANG_ARABIC_EGYPT: return "ar_EG";
|
||||
case SUBLANG_ARABIC_LIBYA: return "ar_LY";
|
||||
case SUBLANG_ARABIC_ALGERIA: return "ar_DZ";
|
||||
case SUBLANG_ARABIC_MOROCCO: return "ar_MA";
|
||||
case SUBLANG_ARABIC_TUNISIA: return "ar_TN";
|
||||
case SUBLANG_ARABIC_OMAN: return "ar_OM";
|
||||
case SUBLANG_ARABIC_YEMEN: return "ar_YE";
|
||||
case SUBLANG_ARABIC_SYRIA: return "ar_SY";
|
||||
case SUBLANG_ARABIC_JORDAN: return "ar_JO";
|
||||
case SUBLANG_ARABIC_LEBANON: return "ar_LB";
|
||||
case SUBLANG_ARABIC_KUWAIT: return "ar_KW";
|
||||
case SUBLANG_ARABIC_UAE: return "ar_AE";
|
||||
case SUBLANG_ARABIC_BAHRAIN: return "ar_BH";
|
||||
case SUBLANG_ARABIC_QATAR: return "ar_QA";
|
||||
}
|
||||
return "ar";
|
||||
case LANG_ARMENIAN: return "hy_AM";
|
||||
case LANG_ASSAMESE: return "as_IN";
|
||||
case LANG_AZERI:
|
||||
switch (sub)
|
||||
{
|
||||
/* FIXME: Adjust this when Azerbaijani locales appear on Unix. */
|
||||
case SUBLANG_AZERI_LATIN: return "az_AZ@latin";
|
||||
case SUBLANG_AZERI_CYRILLIC: return "az_AZ@cyrillic";
|
||||
}
|
||||
return "az";
|
||||
case LANG_BASQUE:
|
||||
return "eu"; /* Ambiguous: could be "eu_ES" or "eu_FR". */
|
||||
case LANG_BELARUSIAN: return "be_BY";
|
||||
case LANG_BENGALI: return "bn_IN";
|
||||
case LANG_BULGARIAN: return "bg_BG";
|
||||
case 0x55: /* BURMESE */ return "my_MM";
|
||||
case 0x53: /* CAMBODIAN */ return "km_KH";
|
||||
case LANG_CATALAN: return "ca_ES";
|
||||
case 0x5c: /* CHEROKEE */ return "chr_US";
|
||||
case LANG_CHINESE:
|
||||
switch (sub)
|
||||
{
|
||||
case SUBLANG_CHINESE_TRADITIONAL: return "zh_TW";
|
||||
case SUBLANG_CHINESE_SIMPLIFIED: return "zh_CN";
|
||||
case SUBLANG_CHINESE_HONGKONG: return "zh_HK";
|
||||
case SUBLANG_CHINESE_SINGAPORE: return "zh_SG";
|
||||
case SUBLANG_CHINESE_MACAU: return "zh_MO";
|
||||
}
|
||||
return "zh";
|
||||
case LANG_CROATIAN: /* LANG_CROATIAN == LANG_SERBIAN
|
||||
* What used to be called Serbo-Croatian
|
||||
* should really now be two separate
|
||||
* languages because of political reasons.
|
||||
* (Says tml, who knows nothing about Serbian
|
||||
* or Croatian.)
|
||||
* (I can feel those flames coming already.)
|
||||
*/
|
||||
switch (sub)
|
||||
{
|
||||
case SUBLANG_DEFAULT: return "hr_HR";
|
||||
case SUBLANG_SERBIAN_LATIN: return "sr_YU";
|
||||
case SUBLANG_SERBIAN_CYRILLIC: return "sr_YU@cyrillic";
|
||||
}
|
||||
return "hr";
|
||||
case LANG_CZECH: return "cs_CZ";
|
||||
case LANG_DANISH: return "da_DK";
|
||||
case LANG_DIVEHI: return "div_MV";
|
||||
case LANG_DUTCH:
|
||||
switch (sub)
|
||||
{
|
||||
case SUBLANG_DUTCH: return "nl_NL";
|
||||
case SUBLANG_DUTCH_BELGIAN: /* FLEMISH, VLAAMS */ return "nl_BE";
|
||||
}
|
||||
return "nl";
|
||||
case 0x66: /* EDO */ return "bin_NG";
|
||||
case LANG_ENGLISH:
|
||||
switch (sub)
|
||||
{
|
||||
/* SUBLANG_ENGLISH_US == SUBLANG_DEFAULT. Heh. I thought
|
||||
* English was the language spoken in England.
|
||||
* Oh well.
|
||||
*/
|
||||
case SUBLANG_ENGLISH_US: return "en_US";
|
||||
case SUBLANG_ENGLISH_UK: return "en_GB";
|
||||
case SUBLANG_ENGLISH_AUS: return "en_AU";
|
||||
case SUBLANG_ENGLISH_CAN: return "en_CA";
|
||||
case SUBLANG_ENGLISH_NZ: return "en_NZ";
|
||||
case SUBLANG_ENGLISH_EIRE: return "en_IE";
|
||||
case SUBLANG_ENGLISH_SOUTH_AFRICA: return "en_ZA";
|
||||
case SUBLANG_ENGLISH_JAMAICA: return "en_JM";
|
||||
case SUBLANG_ENGLISH_CARIBBEAN: return "en_GD"; /* Grenada? */
|
||||
case SUBLANG_ENGLISH_BELIZE: return "en_BZ";
|
||||
case SUBLANG_ENGLISH_TRINIDAD: return "en_TT";
|
||||
case SUBLANG_ENGLISH_ZIMBABWE: return "en_ZW";
|
||||
case SUBLANG_ENGLISH_PHILIPPINES: return "en_PH";
|
||||
}
|
||||
return "en";
|
||||
case LANG_ESTONIAN: return "et_EE";
|
||||
case LANG_FAEROESE: return "fo_FO";
|
||||
case LANG_FARSI: return "fa_IR";
|
||||
case LANG_FINNISH: return "fi_FI";
|
||||
case LANG_FRENCH:
|
||||
switch (sub)
|
||||
{
|
||||
case SUBLANG_FRENCH: return "fr_FR";
|
||||
case SUBLANG_FRENCH_BELGIAN: /* WALLOON */ return "fr_BE";
|
||||
case SUBLANG_FRENCH_CANADIAN: return "fr_CA";
|
||||
case SUBLANG_FRENCH_SWISS: return "fr_CH";
|
||||
case SUBLANG_FRENCH_LUXEMBOURG: return "fr_LU";
|
||||
case SUBLANG_FRENCH_MONACO: return "fr_MC";
|
||||
}
|
||||
return "fr";
|
||||
case 0x62: /* FRISIAN */ return "fy_NL";
|
||||
case 0x67: /* FULFULDE */ return "ful_NG";
|
||||
case 0x3c: /* GAELIC */
|
||||
switch (sub)
|
||||
{
|
||||
case 0x01: /* SCOTTISH */ return "gd_GB";
|
||||
case 0x02: /* IRISH */ return "ga_IE";
|
||||
}
|
||||
return "C";
|
||||
case LANG_GALICIAN: return "gl_ES";
|
||||
case LANG_GEORGIAN: return "ka_GE";
|
||||
case LANG_GERMAN:
|
||||
switch (sub)
|
||||
{
|
||||
case SUBLANG_GERMAN: return "de_DE";
|
||||
case SUBLANG_GERMAN_SWISS: return "de_CH";
|
||||
case SUBLANG_GERMAN_AUSTRIAN: return "de_AT";
|
||||
case SUBLANG_GERMAN_LUXEMBOURG: return "de_LU";
|
||||
case SUBLANG_GERMAN_LIECHTENSTEIN: return "de_LI";
|
||||
}
|
||||
return "de";
|
||||
case LANG_GREEK: return "el_GR";
|
||||
case 0x74: /* GUARANI */ return "gn_PY";
|
||||
case LANG_GUJARATI: return "gu_IN";
|
||||
case 0x68: /* HAUSA */ return "ha_NG";
|
||||
case 0x75: /* HAWAIIAN */
|
||||
/* FIXME: Do they mean Hawaiian ("haw_US", 1000 speakers)
|
||||
or Hawaii Creole English ("cpe_US", 600000 speakers)? */
|
||||
return "cpe_US";
|
||||
case LANG_HEBREW: return "he_IL";
|
||||
case LANG_HINDI: return "hi_IN";
|
||||
case LANG_HUNGARIAN: return "hu_HU";
|
||||
case 0x69: /* IBIBIO */ return "nic_NG";
|
||||
case LANG_ICELANDIC: return "is_IS";
|
||||
case 0x70: /* IGBO */ return "ibo_NG";
|
||||
case LANG_INDONESIAN: return "id_ID";
|
||||
case 0x5d: /* INUKTITUT */ return "iu_CA";
|
||||
case LANG_ITALIAN:
|
||||
switch (sub)
|
||||
{
|
||||
case SUBLANG_ITALIAN: return "it_IT";
|
||||
case SUBLANG_ITALIAN_SWISS: return "it_CH";
|
||||
}
|
||||
return "it";
|
||||
case LANG_JAPANESE: return "ja_JP";
|
||||
case LANG_KANNADA: return "kn_IN";
|
||||
case 0x71: /* KANURI */ return "kau_NG";
|
||||
case LANG_KASHMIRI:
|
||||
switch (sub)
|
||||
{
|
||||
case SUBLANG_DEFAULT: return "ks_PK";
|
||||
case SUBLANG_KASHMIRI_INDIA: return "ks_IN";
|
||||
}
|
||||
return "ks";
|
||||
case LANG_KAZAK: return "kk_KZ";
|
||||
case LANG_KONKANI:
|
||||
/* FIXME: Adjust this when such locales appear on Unix. */
|
||||
return "kok_IN";
|
||||
case LANG_KOREAN: return "ko_KR";
|
||||
case LANG_KYRGYZ: return "ky_KG";
|
||||
case 0x54: /* LAO */ return "lo_LA";
|
||||
case 0x76: /* LATIN */ return "la_VA";
|
||||
case LANG_LATVIAN: return "lv_LV";
|
||||
case LANG_LITHUANIAN: return "lt_LT";
|
||||
case LANG_MACEDONIAN: return "mk_MK";
|
||||
case LANG_MALAY:
|
||||
switch (sub)
|
||||
{
|
||||
case SUBLANG_MALAY_MALAYSIA: return "ms_MY";
|
||||
case SUBLANG_MALAY_BRUNEI_DARUSSALAM: return "ms_BN";
|
||||
}
|
||||
return "ms";
|
||||
case LANG_MALAYALAM: return "ml_IN";
|
||||
case 0x3a: /* MALTESE */ return "mt_MT";
|
||||
case LANG_MANIPURI:
|
||||
/* FIXME: Adjust this when such locales appear on Unix. */
|
||||
return "mni_IN";
|
||||
case LANG_MARATHI: return "mr_IN";
|
||||
case LANG_MONGOLIAN:
|
||||
return "mn"; /* Ambiguous: could be "mn_CN" or "mn_MN". */
|
||||
case LANG_NEPALI:
|
||||
switch (sub)
|
||||
{
|
||||
case SUBLANG_DEFAULT: return "ne_NP";
|
||||
case SUBLANG_NEPALI_INDIA: return "ne_IN";
|
||||
}
|
||||
return "ne";
|
||||
case LANG_NORWEGIAN:
|
||||
switch (sub)
|
||||
{
|
||||
case SUBLANG_NORWEGIAN_BOKMAL: return "no_NO";
|
||||
case SUBLANG_NORWEGIAN_NYNORSK: return "nn_NO";
|
||||
}
|
||||
return "no";
|
||||
case LANG_ORIYA: return "or_IN";
|
||||
case 0x72: /* OROMO */ return "om_ET";
|
||||
case 0x79: /* PAPIAMENTU */ return "pap_AN";
|
||||
case 0x63: /* PASHTO */
|
||||
return "ps"; /* Ambiguous: could be "ps_PK" or "ps_AF". */
|
||||
case LANG_POLISH: return "pl_PL";
|
||||
case LANG_PORTUGUESE:
|
||||
switch (sub)
|
||||
{
|
||||
case SUBLANG_PORTUGUESE: return "pt_PT";
|
||||
/* Hmm. SUBLANG_PORTUGUESE_BRAZILIAN == SUBLANG_DEFAULT.
|
||||
Same phenomenon as SUBLANG_ENGLISH_US == SUBLANG_DEFAULT. */
|
||||
case SUBLANG_PORTUGUESE_BRAZILIAN: return "pt_BR";
|
||||
}
|
||||
return "pt";
|
||||
case LANG_PUNJABI: return "pa_IN";
|
||||
case 0x17: /* RHAETO-ROMANCE */ return "rm_CH";
|
||||
case LANG_ROMANIAN: return "ro_RO";
|
||||
case LANG_RUSSIAN:
|
||||
return "ru"; /* Ambiguous: could be "ru_RU" or "ru_UA". */
|
||||
case 0x3b: /* SAMI */ return "se_NO";
|
||||
case LANG_SANSKRIT: return "sa_IN";
|
||||
case LANG_SINDHI: return "sd";
|
||||
case 0x5b: /* SINHALESE */ return "si_LK";
|
||||
case LANG_SLOVAK: return "sk_SK";
|
||||
case LANG_SLOVENIAN: return "sl_SI";
|
||||
case 0x77: /* SOMALI */ return "so_SO";
|
||||
case LANG_SORBIAN:
|
||||
/* FIXME: Adjust this when such locales appear on Unix. */
|
||||
return "wen_DE";
|
||||
case LANG_SPANISH:
|
||||
switch (sub)
|
||||
{
|
||||
case SUBLANG_SPANISH: return "es_ES";
|
||||
case SUBLANG_SPANISH_MEXICAN: return "es_MX";
|
||||
case SUBLANG_SPANISH_MODERN:
|
||||
return "es_ES@modern"; /* not seen on Unix */
|
||||
case SUBLANG_SPANISH_GUATEMALA: return "es_GT";
|
||||
case SUBLANG_SPANISH_COSTA_RICA: return "es_CR";
|
||||
case SUBLANG_SPANISH_PANAMA: return "es_PA";
|
||||
case SUBLANG_SPANISH_DOMINICAN_REPUBLIC: return "es_DO";
|
||||
case SUBLANG_SPANISH_VENEZUELA: return "es_VE";
|
||||
case SUBLANG_SPANISH_COLOMBIA: return "es_CO";
|
||||
case SUBLANG_SPANISH_PERU: return "es_PE";
|
||||
case SUBLANG_SPANISH_ARGENTINA: return "es_AR";
|
||||
case SUBLANG_SPANISH_ECUADOR: return "es_EC";
|
||||
case SUBLANG_SPANISH_CHILE: return "es_CL";
|
||||
case SUBLANG_SPANISH_URUGUAY: return "es_UY";
|
||||
case SUBLANG_SPANISH_PARAGUAY: return "es_PY";
|
||||
case SUBLANG_SPANISH_BOLIVIA: return "es_BO";
|
||||
case SUBLANG_SPANISH_EL_SALVADOR: return "es_SV";
|
||||
case SUBLANG_SPANISH_HONDURAS: return "es_HN";
|
||||
case SUBLANG_SPANISH_NICARAGUA: return "es_NI";
|
||||
case SUBLANG_SPANISH_PUERTO_RICO: return "es_PR";
|
||||
}
|
||||
return "es";
|
||||
case 0x30: /* SUTU */ return "bnt_TZ";
|
||||
case LANG_SWAHILI: return "sw_KE";
|
||||
case LANG_SWEDISH:
|
||||
switch (sub)
|
||||
{
|
||||
case SUBLANG_DEFAULT: return "sv_SE";
|
||||
case SUBLANG_SWEDISH_FINLAND: return "sv_FI";
|
||||
}
|
||||
return "sv";
|
||||
case LANG_SYRIAC: return "syr_TR"; /* An extinct language. */
|
||||
case 0x64: /* TAGALOG */ return "tl_PH";
|
||||
case 0x28: /* TAJIK */ return "tg_TJ";
|
||||
case 0x5f: /* TAMAZIGHT */ return "ber_MA";
|
||||
case LANG_TAMIL:
|
||||
return "ta"; /* Ambiguous: could be "ta_IN" or "ta_LK" or "ta_SG". */
|
||||
case LANG_TATAR: return "tt_RU";
|
||||
case LANG_TELUGU: return "te_IN";
|
||||
case LANG_THAI: return "th_TH";
|
||||
case 0x51: /* TIBETAN */ return "bo_CN";
|
||||
case 0x73: /* TIGRINYA */ return "ti_ET";
|
||||
case 0x31: /* TSONGA */ return "ts_ZA";
|
||||
case LANG_TURKISH: return "tr_TR";
|
||||
case 0x42: /* TURKMEN */ return "tk_TM";
|
||||
case LANG_UKRAINIAN: return "uk_UA";
|
||||
case LANG_URDU:
|
||||
switch (sub)
|
||||
{
|
||||
case SUBLANG_URDU_PAKISTAN: return "ur_PK";
|
||||
case SUBLANG_URDU_INDIA: return "ur_IN";
|
||||
}
|
||||
return "ur";
|
||||
case LANG_UZBEK:
|
||||
switch (sub)
|
||||
{
|
||||
/* FIXME: Adjust this when Uzbek locales appear on Unix. */
|
||||
case SUBLANG_UZBEK_LATIN: return "uz_UZ@latin";
|
||||
case SUBLANG_UZBEK_CYRILLIC: return "uz_UZ@cyrillic";
|
||||
}
|
||||
return "uz";
|
||||
case 0x33: /* VENDA */ return "ven_ZA";
|
||||
case LANG_VIETNAMESE: return "vi_VN";
|
||||
case 0x52: /* WELSH */ return "cy_GB";
|
||||
case 0x34: /* XHOSA */ return "xh_ZA";
|
||||
case 0x78: /* YI */ return "sit_CN";
|
||||
case 0x3d: /* YIDDISH */ return "yi_IL";
|
||||
case 0x6a: /* YORUBA */ return "yo_NG";
|
||||
case 0x35: /* ZULU */ return "zu_ZA";
|
||||
default: return "C";
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
104
intl/log.c
Normal file
104
intl/log.c
Normal file
@ -0,0 +1,104 @@
|
||||
/* Log file output.
|
||||
Copyright (C) 2003 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Library 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library 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. */
|
||||
|
||||
/* Written by Bruno Haible <bruno@clisp.org>. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
/* Print an ASCII string with quotes and escape sequences where needed. */
|
||||
static void
|
||||
print_escaped (stream, str)
|
||||
FILE *stream;
|
||||
const char *str;
|
||||
{
|
||||
putc ('"', stream);
|
||||
for (; *str != '\0'; str++)
|
||||
if (*str == '\n')
|
||||
{
|
||||
fputs ("\\n\"", stream);
|
||||
if (str[1] == '\0')
|
||||
return;
|
||||
fputs ("\n\"", stream);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (*str == '"' || *str == '\\')
|
||||
putc ('\\', stream);
|
||||
putc (*str, stream);
|
||||
}
|
||||
putc ('"', stream);
|
||||
}
|
||||
|
||||
/* Add to the log file an entry denoting a failed translation. */
|
||||
void
|
||||
_nl_log_untranslated (logfilename, domainname, msgid1, msgid2, plural)
|
||||
const char *logfilename;
|
||||
const char *domainname;
|
||||
const char *msgid1;
|
||||
const char *msgid2;
|
||||
int plural;
|
||||
{
|
||||
static char *last_logfilename = NULL;
|
||||
static FILE *last_logfile = NULL;
|
||||
FILE *logfile;
|
||||
|
||||
/* Can we reuse the last opened logfile? */
|
||||
if (last_logfilename == NULL || strcmp (logfilename, last_logfilename) != 0)
|
||||
{
|
||||
/* Close the last used logfile. */
|
||||
if (last_logfilename != NULL)
|
||||
{
|
||||
if (last_logfile != NULL)
|
||||
{
|
||||
fclose (last_logfile);
|
||||
last_logfile = NULL;
|
||||
}
|
||||
free (last_logfilename);
|
||||
last_logfilename = NULL;
|
||||
}
|
||||
/* Open the logfile. */
|
||||
last_logfilename = (char *) malloc (strlen (logfilename) + 1);
|
||||
if (last_logfilename == NULL)
|
||||
return;
|
||||
strcpy (last_logfilename, logfilename);
|
||||
last_logfile = fopen (logfilename, "a");
|
||||
if (last_logfile == NULL)
|
||||
return;
|
||||
}
|
||||
logfile = last_logfile;
|
||||
|
||||
fprintf (logfile, "domain ");
|
||||
print_escaped (logfile, domainname);
|
||||
fprintf (logfile, "\nmsgid ");
|
||||
print_escaped (logfile, msgid1);
|
||||
if (plural)
|
||||
{
|
||||
fprintf (logfile, "\nmsgid_plural ");
|
||||
print_escaped (logfile, msgid2);
|
||||
fprintf (logfile, "\nmsgstr[0] \"\"\n");
|
||||
}
|
||||
else
|
||||
fprintf (logfile, "\nmsgstr \"\"\n");
|
||||
putc ('\n', logfile);
|
||||
}
|
98
intl/os2compat.c
Normal file
98
intl/os2compat.c
Normal file
@ -0,0 +1,98 @@
|
||||
/* OS/2 compatibility functions.
|
||||
Copyright (C) 2001-2002 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Library 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library 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. */
|
||||
|
||||
#define OS2_AWARE
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/param.h>
|
||||
|
||||
/* A version of getenv() that works from DLLs */
|
||||
extern unsigned long DosScanEnv (const unsigned char *pszName, unsigned char **ppszValue);
|
||||
|
||||
char *
|
||||
_nl_getenv (const char *name)
|
||||
{
|
||||
unsigned char *value;
|
||||
if (DosScanEnv (name, &value))
|
||||
return NULL;
|
||||
else
|
||||
return value;
|
||||
}
|
||||
|
||||
/* A fixed size buffer. */
|
||||
char libintl_nl_default_dirname[MAXPATHLEN+1];
|
||||
|
||||
char *_nlos2_libdir = NULL;
|
||||
char *_nlos2_localealiaspath = NULL;
|
||||
char *_nlos2_localedir = NULL;
|
||||
|
||||
static __attribute__((constructor)) void
|
||||
nlos2_initialize ()
|
||||
{
|
||||
char *root = getenv ("UNIXROOT");
|
||||
char *gnulocaledir = getenv ("GNULOCALEDIR");
|
||||
|
||||
_nlos2_libdir = gnulocaledir;
|
||||
if (!_nlos2_libdir)
|
||||
{
|
||||
if (root)
|
||||
{
|
||||
size_t sl = strlen (root);
|
||||
_nlos2_libdir = (char *) malloc (sl + strlen (LIBDIR) + 1);
|
||||
memcpy (_nlos2_libdir, root, sl);
|
||||
memcpy (_nlos2_libdir + sl, LIBDIR, strlen (LIBDIR) + 1);
|
||||
}
|
||||
else
|
||||
_nlos2_libdir = LIBDIR;
|
||||
}
|
||||
|
||||
_nlos2_localealiaspath = gnulocaledir;
|
||||
if (!_nlos2_localealiaspath)
|
||||
{
|
||||
if (root)
|
||||
{
|
||||
size_t sl = strlen (root);
|
||||
_nlos2_localealiaspath = (char *) malloc (sl + strlen (LOCALE_ALIAS_PATH) + 1);
|
||||
memcpy (_nlos2_localealiaspath, root, sl);
|
||||
memcpy (_nlos2_localealiaspath + sl, LOCALE_ALIAS_PATH, strlen (LOCALE_ALIAS_PATH) + 1);
|
||||
}
|
||||
else
|
||||
_nlos2_localealiaspath = LOCALE_ALIAS_PATH;
|
||||
}
|
||||
|
||||
_nlos2_localedir = gnulocaledir;
|
||||
if (!_nlos2_localedir)
|
||||
{
|
||||
if (root)
|
||||
{
|
||||
size_t sl = strlen (root);
|
||||
_nlos2_localedir = (char *) malloc (sl + strlen (LOCALEDIR) + 1);
|
||||
memcpy (_nlos2_localedir, root, sl);
|
||||
memcpy (_nlos2_localedir + sl, LOCALEDIR, strlen (LOCALEDIR) + 1);
|
||||
}
|
||||
else
|
||||
_nlos2_localedir = LOCALEDIR;
|
||||
}
|
||||
|
||||
if (strlen (_nlos2_localedir) <= MAXPATHLEN)
|
||||
strcpy (libintl_nl_default_dirname, _nlos2_localedir);
|
||||
}
|
46
intl/os2compat.h
Normal file
46
intl/os2compat.h
Normal file
@ -0,0 +1,46 @@
|
||||
/* OS/2 compatibility defines.
|
||||
This file is intended to be included from config.h
|
||||
Copyright (C) 2001-2002 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Library 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library 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. */
|
||||
|
||||
/* When included from os2compat.h we need all the original definitions */
|
||||
#ifndef OS2_AWARE
|
||||
|
||||
#undef LIBDIR
|
||||
#define LIBDIR _nlos2_libdir
|
||||
extern char *_nlos2_libdir;
|
||||
|
||||
#undef LOCALEDIR
|
||||
#define LOCALEDIR _nlos2_localedir
|
||||
extern char *_nlos2_localedir;
|
||||
|
||||
#undef LOCALE_ALIAS_PATH
|
||||
#define LOCALE_ALIAS_PATH _nlos2_localealiaspath
|
||||
extern char *_nlos2_localealiaspath;
|
||||
|
||||
#endif
|
||||
|
||||
#undef HAVE_STRCASECMP
|
||||
#define HAVE_STRCASECMP 1
|
||||
#define strcasecmp stricmp
|
||||
#define strncasecmp strnicmp
|
||||
|
||||
/* We have our own getenv() which works even if library is compiled as DLL */
|
||||
#define getenv _nl_getenv
|
||||
|
||||
/* Older versions of gettext used -1 as the value of LC_MESSAGES */
|
||||
#define LC_MESSAGES_COMPAT (-1)
|
24
intl/osdep.c
Normal file
24
intl/osdep.c
Normal file
@ -0,0 +1,24 @@
|
||||
/* OS dependent parts of libintl.
|
||||
Copyright (C) 2001-2002 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Library 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library 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. */
|
||||
|
||||
#if defined __EMX__
|
||||
# include "os2compat.c"
|
||||
#else
|
||||
/* Avoid AIX compiler warning. */
|
||||
typedef int dummy;
|
||||
#endif
|
156
intl/plural-exp.c
Normal file
156
intl/plural-exp.c
Normal file
@ -0,0 +1,156 @@
|
||||
/* Expression parsing for plural form selection.
|
||||
Copyright (C) 2000, 2001 Free Software Foundation, Inc.
|
||||
Written by Ulrich Drepper <drepper@cygnus.com>, 2000.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Library 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library 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 <ctype.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "plural-exp.h"
|
||||
|
||||
#if (defined __GNUC__ && !defined __APPLE_CC__) \
|
||||
|| (defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L)
|
||||
|
||||
/* These structs are the constant expression for the germanic plural
|
||||
form determination. It represents the expression "n != 1". */
|
||||
static const struct expression plvar =
|
||||
{
|
||||
.nargs = 0,
|
||||
.operation = var,
|
||||
};
|
||||
static const struct expression plone =
|
||||
{
|
||||
.nargs = 0,
|
||||
.operation = num,
|
||||
.val =
|
||||
{
|
||||
.num = 1
|
||||
}
|
||||
};
|
||||
struct expression GERMANIC_PLURAL =
|
||||
{
|
||||
.nargs = 2,
|
||||
.operation = not_equal,
|
||||
.val =
|
||||
{
|
||||
.args =
|
||||
{
|
||||
[0] = (struct expression *) &plvar,
|
||||
[1] = (struct expression *) &plone
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
# define INIT_GERMANIC_PLURAL()
|
||||
|
||||
#else
|
||||
|
||||
/* For compilers without support for ISO C 99 struct/union initializers:
|
||||
Initialization at run-time. */
|
||||
|
||||
static struct expression plvar;
|
||||
static struct expression plone;
|
||||
struct expression GERMANIC_PLURAL;
|
||||
|
||||
static void
|
||||
init_germanic_plural ()
|
||||
{
|
||||
if (plone.val.num == 0)
|
||||
{
|
||||
plvar.nargs = 0;
|
||||
plvar.operation = var;
|
||||
|
||||
plone.nargs = 0;
|
||||
plone.operation = num;
|
||||
plone.val.num = 1;
|
||||
|
||||
GERMANIC_PLURAL.nargs = 2;
|
||||
GERMANIC_PLURAL.operation = not_equal;
|
||||
GERMANIC_PLURAL.val.args[0] = &plvar;
|
||||
GERMANIC_PLURAL.val.args[1] = &plone;
|
||||
}
|
||||
}
|
||||
|
||||
# define INIT_GERMANIC_PLURAL() init_germanic_plural ()
|
||||
|
||||
#endif
|
||||
|
||||
void
|
||||
internal_function
|
||||
EXTRACT_PLURAL_EXPRESSION (nullentry, pluralp, npluralsp)
|
||||
const char *nullentry;
|
||||
struct expression **pluralp;
|
||||
unsigned long int *npluralsp;
|
||||
{
|
||||
if (nullentry != NULL)
|
||||
{
|
||||
const char *plural;
|
||||
const char *nplurals;
|
||||
|
||||
plural = strstr (nullentry, "plural=");
|
||||
nplurals = strstr (nullentry, "nplurals=");
|
||||
if (plural == NULL || nplurals == NULL)
|
||||
goto no_plural;
|
||||
else
|
||||
{
|
||||
char *endp;
|
||||
unsigned long int n;
|
||||
struct parse_args args;
|
||||
|
||||
/* First get the number. */
|
||||
nplurals += 9;
|
||||
while (*nplurals != '\0' && isspace ((unsigned char) *nplurals))
|
||||
++nplurals;
|
||||
if (!(*nplurals >= '0' && *nplurals <= '9'))
|
||||
goto no_plural;
|
||||
#if defined HAVE_STRTOUL || defined _LIBC
|
||||
n = strtoul (nplurals, &endp, 10);
|
||||
#else
|
||||
for (endp = nplurals, n = 0; *endp >= '0' && *endp <= '9'; endp++)
|
||||
n = n * 10 + (*endp - '0');
|
||||
#endif
|
||||
if (nplurals == endp)
|
||||
goto no_plural;
|
||||
*npluralsp = n;
|
||||
|
||||
/* Due to the restrictions bison imposes onto the interface of the
|
||||
scanner function we have to put the input string and the result
|
||||
passed up from the parser into the same structure which address
|
||||
is passed down to the parser. */
|
||||
plural += 7;
|
||||
args.cp = plural;
|
||||
if (PLURAL_PARSE (&args) != 0)
|
||||
goto no_plural;
|
||||
*pluralp = args.res;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* By default we are using the Germanic form: singular form only
|
||||
for `one', the plural form otherwise. Yes, this is also what
|
||||
English is using since English is a Germanic language. */
|
||||
no_plural:
|
||||
INIT_GERMANIC_PLURAL ();
|
||||
*pluralp = &GERMANIC_PLURAL;
|
||||
*npluralsp = 2;
|
||||
}
|
||||
}
|
126
intl/plural-exp.h
Normal file
126
intl/plural-exp.h
Normal file
@ -0,0 +1,126 @@
|
||||
/* Expression parsing and evaluation for plural form selection.
|
||||
Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc.
|
||||
Written by Ulrich Drepper <drepper@cygnus.com>, 2000.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Library 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library 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. */
|
||||
|
||||
#ifndef _PLURAL_EXP_H
|
||||
#define _PLURAL_EXP_H
|
||||
|
||||
#ifndef PARAMS
|
||||
# if __STDC__ || defined __GNUC__ || defined __SUNPRO_C || defined __cplusplus || __PROTOTYPES
|
||||
# define PARAMS(args) args
|
||||
# else
|
||||
# define PARAMS(args) ()
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef internal_function
|
||||
# define internal_function
|
||||
#endif
|
||||
|
||||
#ifndef attribute_hidden
|
||||
# define attribute_hidden
|
||||
#endif
|
||||
|
||||
|
||||
/* This is the representation of the expressions to determine the
|
||||
plural form. */
|
||||
struct expression
|
||||
{
|
||||
int nargs; /* Number of arguments. */
|
||||
enum operator
|
||||
{
|
||||
/* Without arguments: */
|
||||
var, /* The variable "n". */
|
||||
num, /* Decimal number. */
|
||||
/* Unary operators: */
|
||||
lnot, /* Logical NOT. */
|
||||
/* Binary operators: */
|
||||
mult, /* Multiplication. */
|
||||
divide, /* Division. */
|
||||
module, /* Modulo operation. */
|
||||
plus, /* Addition. */
|
||||
minus, /* Subtraction. */
|
||||
less_than, /* Comparison. */
|
||||
greater_than, /* Comparison. */
|
||||
less_or_equal, /* Comparison. */
|
||||
greater_or_equal, /* Comparison. */
|
||||
equal, /* Comparison for equality. */
|
||||
not_equal, /* Comparison for inequality. */
|
||||
land, /* Logical AND. */
|
||||
lor, /* Logical OR. */
|
||||
/* Ternary operators: */
|
||||
qmop /* Question mark operator. */
|
||||
} operation;
|
||||
union
|
||||
{
|
||||
unsigned long int num; /* Number value for `num'. */
|
||||
struct expression *args[3]; /* Up to three arguments. */
|
||||
} val;
|
||||
};
|
||||
|
||||
/* This is the data structure to pass information to the parser and get
|
||||
the result in a thread-safe way. */
|
||||
struct parse_args
|
||||
{
|
||||
const char *cp;
|
||||
struct expression *res;
|
||||
};
|
||||
|
||||
|
||||
/* Names for the libintl functions are a problem. This source code is used
|
||||
1. in the GNU C Library library,
|
||||
2. in the GNU libintl library,
|
||||
3. in the GNU gettext tools.
|
||||
The function names in each situation must be different, to allow for
|
||||
binary incompatible changes in 'struct expression'. Furthermore,
|
||||
1. in the GNU C Library library, the names have a __ prefix,
|
||||
2.+3. in the GNU libintl library and in the GNU gettext tools, the names
|
||||
must follow ANSI C and not start with __.
|
||||
So we have to distinguish the three cases. */
|
||||
#ifdef _LIBC
|
||||
# define FREE_EXPRESSION __gettext_free_exp
|
||||
# define PLURAL_PARSE __gettextparse
|
||||
# define GERMANIC_PLURAL __gettext_germanic_plural
|
||||
# define EXTRACT_PLURAL_EXPRESSION __gettext_extract_plural
|
||||
#elif defined (IN_LIBINTL)
|
||||
# define FREE_EXPRESSION libintl_gettext_free_exp
|
||||
# define PLURAL_PARSE libintl_gettextparse
|
||||
# define GERMANIC_PLURAL libintl_gettext_germanic_plural
|
||||
# define EXTRACT_PLURAL_EXPRESSION libintl_gettext_extract_plural
|
||||
#else
|
||||
# define FREE_EXPRESSION free_plural_expression
|
||||
# define PLURAL_PARSE parse_plural_expression
|
||||
# define GERMANIC_PLURAL germanic_plural
|
||||
# define EXTRACT_PLURAL_EXPRESSION extract_plural_expression
|
||||
#endif
|
||||
|
||||
extern void FREE_EXPRESSION PARAMS ((struct expression *exp))
|
||||
internal_function;
|
||||
extern int PLURAL_PARSE PARAMS ((void *arg));
|
||||
extern struct expression GERMANIC_PLURAL attribute_hidden;
|
||||
extern void EXTRACT_PLURAL_EXPRESSION PARAMS ((const char *nullentry,
|
||||
struct expression **pluralp,
|
||||
unsigned long int *npluralsp))
|
||||
internal_function;
|
||||
|
||||
#if !defined (_LIBC) && !defined (IN_LIBINTL)
|
||||
extern unsigned long int plural_eval PARAMS ((struct expression *pexp,
|
||||
unsigned long int n));
|
||||
#endif
|
||||
|
||||
#endif /* _PLURAL_EXP_H */
|
439
intl/relocatable.c
Normal file
439
intl/relocatable.c
Normal file
@ -0,0 +1,439 @@
|
||||
/* Provide relocatable packages.
|
||||
Copyright (C) 2003 Free Software Foundation, Inc.
|
||||
Written by Bruno Haible <bruno@clisp.org>, 2003.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Library 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library 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. */
|
||||
|
||||
|
||||
/* Tell glibc's <stdio.h> to provide a prototype for getline().
|
||||
This must come before <config.h> because <config.h> may include
|
||||
<features.h>, and once <features.h> has been included, it's too late. */
|
||||
#ifndef _GNU_SOURCE
|
||||
# define _GNU_SOURCE 1
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
/* Specification. */
|
||||
#include "relocatable.h"
|
||||
|
||||
#if ENABLE_RELOCATABLE
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef NO_XMALLOC
|
||||
# define xmalloc malloc
|
||||
#else
|
||||
# include "xmalloc.h"
|
||||
#endif
|
||||
|
||||
#if DEPENDS_ON_LIBCHARSET
|
||||
# include <libcharset.h>
|
||||
#endif
|
||||
#if DEPENDS_ON_LIBICONV && HAVE_ICONV
|
||||
# include <iconv.h>
|
||||
#endif
|
||||
#if DEPENDS_ON_LIBINTL && ENABLE_NLS
|
||||
# include <libintl.h>
|
||||
#endif
|
||||
|
||||
/* Faked cheap 'bool'. */
|
||||
#undef bool
|
||||
#undef false
|
||||
#undef true
|
||||
#define bool int
|
||||
#define false 0
|
||||
#define true 1
|
||||
|
||||
/* Pathname support.
|
||||
ISSLASH(C) tests whether C is a directory separator character.
|
||||
IS_PATH_WITH_DIR(P) tests whether P contains a directory specification.
|
||||
*/
|
||||
#if defined _WIN32 || defined __WIN32__ || defined __EMX__ || defined __DJGPP__
|
||||
/* Win32, OS/2, DOS */
|
||||
# define ISSLASH(C) ((C) == '/' || (C) == '\\')
|
||||
# define HAS_DEVICE(P) \
|
||||
((((P)[0] >= 'A' && (P)[0] <= 'Z') || ((P)[0] >= 'a' && (P)[0] <= 'z')) \
|
||||
&& (P)[1] == ':')
|
||||
# define IS_PATH_WITH_DIR(P) \
|
||||
(strchr (P, '/') != NULL || strchr (P, '\\') != NULL || HAS_DEVICE (P))
|
||||
# define FILESYSTEM_PREFIX_LEN(P) (HAS_DEVICE (P) ? 2 : 0)
|
||||
#else
|
||||
/* Unix */
|
||||
# define ISSLASH(C) ((C) == '/')
|
||||
# define IS_PATH_WITH_DIR(P) (strchr (P, '/') != NULL)
|
||||
# define FILESYSTEM_PREFIX_LEN(P) 0
|
||||
#endif
|
||||
|
||||
/* Original installation prefix. */
|
||||
static char *orig_prefix;
|
||||
static size_t orig_prefix_len;
|
||||
/* Current installation prefix. */
|
||||
static char *curr_prefix;
|
||||
static size_t curr_prefix_len;
|
||||
/* These prefixes do not end in a slash. Anything that will be concatenated
|
||||
to them must start with a slash. */
|
||||
|
||||
/* Sets the original and the current installation prefix of this module.
|
||||
Relocation simply replaces a pathname starting with the original prefix
|
||||
by the corresponding pathname with the current prefix instead. Both
|
||||
prefixes should be directory names without trailing slash (i.e. use ""
|
||||
instead of "/"). */
|
||||
static void
|
||||
set_this_relocation_prefix (const char *orig_prefix_arg,
|
||||
const char *curr_prefix_arg)
|
||||
{
|
||||
if (orig_prefix_arg != NULL && curr_prefix_arg != NULL
|
||||
/* Optimization: if orig_prefix and curr_prefix are equal, the
|
||||
relocation is a nop. */
|
||||
&& strcmp (orig_prefix_arg, curr_prefix_arg) != 0)
|
||||
{
|
||||
/* Duplicate the argument strings. */
|
||||
char *memory;
|
||||
|
||||
orig_prefix_len = strlen (orig_prefix_arg);
|
||||
curr_prefix_len = strlen (curr_prefix_arg);
|
||||
memory = (char *) xmalloc (orig_prefix_len + 1 + curr_prefix_len + 1);
|
||||
#ifdef NO_XMALLOC
|
||||
if (memory != NULL)
|
||||
#endif
|
||||
{
|
||||
memcpy (memory, orig_prefix_arg, orig_prefix_len + 1);
|
||||
orig_prefix = memory;
|
||||
memory += orig_prefix_len + 1;
|
||||
memcpy (memory, curr_prefix_arg, curr_prefix_len + 1);
|
||||
curr_prefix = memory;
|
||||
return;
|
||||
}
|
||||
}
|
||||
orig_prefix = NULL;
|
||||
curr_prefix = NULL;
|
||||
/* Don't worry about wasted memory here - this function is usually only
|
||||
called once. */
|
||||
}
|
||||
|
||||
/* Sets the original and the current installation prefix of the package.
|
||||
Relocation simply replaces a pathname starting with the original prefix
|
||||
by the corresponding pathname with the current prefix instead. Both
|
||||
prefixes should be directory names without trailing slash (i.e. use ""
|
||||
instead of "/"). */
|
||||
void
|
||||
set_relocation_prefix (const char *orig_prefix_arg, const char *curr_prefix_arg)
|
||||
{
|
||||
set_this_relocation_prefix (orig_prefix_arg, curr_prefix_arg);
|
||||
|
||||
/* Now notify all dependent libraries. */
|
||||
#if DEPENDS_ON_LIBCHARSET
|
||||
libcharset_set_relocation_prefix (orig_prefix_arg, curr_prefix_arg);
|
||||
#endif
|
||||
#if DEPENDS_ON_LIBICONV && HAVE_ICONV && _LIBICONV_VERSION >= 0x0109
|
||||
libiconv_set_relocation_prefix (orig_prefix_arg, curr_prefix_arg);
|
||||
#endif
|
||||
#if DEPENDS_ON_LIBINTL && ENABLE_NLS && defined libintl_set_relocation_prefix
|
||||
libintl_set_relocation_prefix (orig_prefix_arg, curr_prefix_arg);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Convenience function:
|
||||
Computes the current installation prefix, based on the original
|
||||
installation prefix, the original installation directory of a particular
|
||||
file, and the current pathname of this file. Returns NULL upon failure. */
|
||||
#ifdef IN_LIBRARY
|
||||
#define compute_curr_prefix local_compute_curr_prefix
|
||||
static
|
||||
#endif
|
||||
const char *
|
||||
compute_curr_prefix (const char *orig_installprefix,
|
||||
const char *orig_installdir,
|
||||
const char *curr_pathname)
|
||||
{
|
||||
const char *curr_installdir;
|
||||
const char *rel_installdir;
|
||||
|
||||
if (curr_pathname == NULL)
|
||||
return NULL;
|
||||
|
||||
/* Determine the relative installation directory, relative to the prefix.
|
||||
This is simply the difference between orig_installprefix and
|
||||
orig_installdir. */
|
||||
if (strncmp (orig_installprefix, orig_installdir, strlen (orig_installprefix))
|
||||
!= 0)
|
||||
/* Shouldn't happen - nothing should be installed outside $(prefix). */
|
||||
return NULL;
|
||||
rel_installdir = orig_installdir + strlen (orig_installprefix);
|
||||
|
||||
/* Determine the current installation directory. */
|
||||
{
|
||||
const char *p_base = curr_pathname + FILESYSTEM_PREFIX_LEN (curr_pathname);
|
||||
const char *p = curr_pathname + strlen (curr_pathname);
|
||||
char *q;
|
||||
|
||||
while (p > p_base)
|
||||
{
|
||||
p--;
|
||||
if (ISSLASH (*p))
|
||||
break;
|
||||
}
|
||||
|
||||
q = (char *) xmalloc (p - curr_pathname + 1);
|
||||
#ifdef NO_XMALLOC
|
||||
if (q == NULL)
|
||||
return NULL;
|
||||
#endif
|
||||
memcpy (q, curr_pathname, p - curr_pathname);
|
||||
q[p - curr_pathname] = '\0';
|
||||
curr_installdir = q;
|
||||
}
|
||||
|
||||
/* Compute the current installation prefix by removing the trailing
|
||||
rel_installdir from it. */
|
||||
{
|
||||
const char *rp = rel_installdir + strlen (rel_installdir);
|
||||
const char *cp = curr_installdir + strlen (curr_installdir);
|
||||
const char *cp_base =
|
||||
curr_installdir + FILESYSTEM_PREFIX_LEN (curr_installdir);
|
||||
|
||||
while (rp > rel_installdir && cp > cp_base)
|
||||
{
|
||||
bool same = false;
|
||||
const char *rpi = rp;
|
||||
const char *cpi = cp;
|
||||
|
||||
while (rpi > rel_installdir && cpi > cp_base)
|
||||
{
|
||||
rpi--;
|
||||
cpi--;
|
||||
if (ISSLASH (*rpi) || ISSLASH (*cpi))
|
||||
{
|
||||
if (ISSLASH (*rpi) && ISSLASH (*cpi))
|
||||
same = true;
|
||||
break;
|
||||
}
|
||||
#if defined _WIN32 || defined __WIN32__ || defined __EMX__ || defined __DJGPP__
|
||||
/* Win32, OS/2, DOS - case insignificant filesystem */
|
||||
if ((*rpi >= 'a' && *rpi <= 'z' ? *rpi - 'a' + 'A' : *rpi)
|
||||
!= (*cpi >= 'a' && *cpi <= 'z' ? *cpi - 'a' + 'A' : *cpi))
|
||||
break;
|
||||
#else
|
||||
if (*rpi != *cpi)
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
if (!same)
|
||||
break;
|
||||
/* The last pathname component was the same. opi and cpi now point
|
||||
to the slash before it. */
|
||||
rp = rpi;
|
||||
cp = cpi;
|
||||
}
|
||||
|
||||
if (rp > rel_installdir)
|
||||
/* Unexpected: The curr_installdir does not end with rel_installdir. */
|
||||
return NULL;
|
||||
|
||||
{
|
||||
size_t curr_prefix_len = cp - curr_installdir;
|
||||
char *curr_prefix;
|
||||
|
||||
curr_prefix = (char *) xmalloc (curr_prefix_len + 1);
|
||||
#ifdef NO_XMALLOC
|
||||
if (curr_prefix == NULL)
|
||||
return NULL;
|
||||
#endif
|
||||
memcpy (curr_prefix, curr_installdir, curr_prefix_len);
|
||||
curr_prefix[curr_prefix_len] = '\0';
|
||||
|
||||
return curr_prefix;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if defined PIC && defined INSTALLDIR
|
||||
|
||||
/* Full pathname of shared library, or NULL. */
|
||||
static char *shared_library_fullname;
|
||||
|
||||
#if defined _WIN32 || defined __WIN32__
|
||||
|
||||
/* Determine the full pathname of the shared library when it is loaded. */
|
||||
|
||||
BOOL WINAPI
|
||||
DllMain (HINSTANCE module_handle, DWORD event, LPVOID reserved)
|
||||
{
|
||||
(void) reserved;
|
||||
|
||||
if (event == DLL_PROCESS_ATTACH)
|
||||
{
|
||||
/* The DLL is being loaded into an application's address range. */
|
||||
static char location[MAX_PATH];
|
||||
|
||||
if (!GetModuleFileName (module_handle, location, sizeof (location)))
|
||||
/* Shouldn't happen. */
|
||||
return FALSE;
|
||||
|
||||
if (!IS_PATH_WITH_DIR (location))
|
||||
/* Shouldn't happen. */
|
||||
return FALSE;
|
||||
|
||||
shared_library_fullname = strdup (location);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#else /* Unix */
|
||||
|
||||
static void
|
||||
find_shared_library_fullname ()
|
||||
{
|
||||
#ifdef __linux__
|
||||
FILE *fp;
|
||||
|
||||
/* Open the current process' maps file. It describes one VMA per line. */
|
||||
fp = fopen ("/proc/self/maps", "r");
|
||||
if (fp)
|
||||
{
|
||||
unsigned long address = (unsigned long) &find_shared_library_fullname;
|
||||
for (;;)
|
||||
{
|
||||
unsigned long start, end;
|
||||
int c;
|
||||
|
||||
if (fscanf (fp, "%lx-%lx", &start, &end) != 2)
|
||||
break;
|
||||
if (address >= start && address <= end - 1)
|
||||
{
|
||||
/* Found it. Now see if this line contains a filename. */
|
||||
while (c = getc (fp), c != EOF && c != '\n' && c != '/')
|
||||
continue;
|
||||
if (c == '/')
|
||||
{
|
||||
size_t size;
|
||||
int len;
|
||||
|
||||
ungetc (c, fp);
|
||||
shared_library_fullname = NULL; size = 0;
|
||||
len = getline (&shared_library_fullname, &size, fp);
|
||||
if (len >= 0)
|
||||
{
|
||||
/* Success: filled shared_library_fullname. */
|
||||
if (len > 0 && shared_library_fullname[len - 1] == '\n')
|
||||
shared_library_fullname[len - 1] = '\0';
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
while (c = getc (fp), c != EOF && c != '\n')
|
||||
continue;
|
||||
}
|
||||
fclose (fp);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* WIN32 / Unix */
|
||||
|
||||
/* Return the full pathname of the current shared library.
|
||||
Return NULL if unknown.
|
||||
Guaranteed to work only on Linux and Woe32. */
|
||||
static char *
|
||||
get_shared_library_fullname ()
|
||||
{
|
||||
#if !(defined _WIN32 || defined __WIN32__)
|
||||
static bool tried_find_shared_library_fullname;
|
||||
if (!tried_find_shared_library_fullname)
|
||||
{
|
||||
find_shared_library_fullname ();
|
||||
tried_find_shared_library_fullname = true;
|
||||
}
|
||||
#endif
|
||||
return shared_library_fullname;
|
||||
}
|
||||
|
||||
#endif /* PIC */
|
||||
|
||||
/* Returns the pathname, relocated according to the current installation
|
||||
directory. */
|
||||
const char *
|
||||
relocate (const char *pathname)
|
||||
{
|
||||
#if defined PIC && defined INSTALLDIR
|
||||
static int initialized;
|
||||
|
||||
/* Initialization code for a shared library. */
|
||||
if (!initialized)
|
||||
{
|
||||
/* At this point, orig_prefix and curr_prefix likely have already been
|
||||
set through the main program's set_program_name_and_installdir
|
||||
function. This is sufficient in the case that the library has
|
||||
initially been installed in the same orig_prefix. But we can do
|
||||
better, to also cover the cases that 1. it has been installed
|
||||
in a different prefix before being moved to orig_prefix and (later)
|
||||
to curr_prefix, 2. unlike the program, it has not moved away from
|
||||
orig_prefix. */
|
||||
const char *orig_installprefix = INSTALLPREFIX;
|
||||
const char *orig_installdir = INSTALLDIR;
|
||||
const char *curr_prefix_better;
|
||||
|
||||
curr_prefix_better =
|
||||
compute_curr_prefix (orig_installprefix, orig_installdir,
|
||||
get_shared_library_fullname ());
|
||||
if (curr_prefix_better == NULL)
|
||||
curr_prefix_better = curr_prefix;
|
||||
|
||||
set_relocation_prefix (orig_installprefix, curr_prefix_better);
|
||||
|
||||
initialized = 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Note: It is not necessary to perform case insensitive comparison here,
|
||||
even for DOS-like filesystems, because the pathname argument was
|
||||
typically created from the same Makefile variable as orig_prefix came
|
||||
from. */
|
||||
if (orig_prefix != NULL && curr_prefix != NULL
|
||||
&& strncmp (pathname, orig_prefix, orig_prefix_len) == 0)
|
||||
{
|
||||
if (pathname[orig_prefix_len] == '\0')
|
||||
/* pathname equals orig_prefix. */
|
||||
return curr_prefix;
|
||||
if (ISSLASH (pathname[orig_prefix_len]))
|
||||
{
|
||||
/* pathname starts with orig_prefix. */
|
||||
const char *pathname_tail = &pathname[orig_prefix_len];
|
||||
char *result =
|
||||
(char *) xmalloc (curr_prefix_len + strlen (pathname_tail) + 1);
|
||||
|
||||
#ifdef NO_XMALLOC
|
||||
if (result != NULL)
|
||||
#endif
|
||||
{
|
||||
memcpy (result, curr_prefix, curr_prefix_len);
|
||||
strcpy (result + curr_prefix_len, pathname_tail);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Nothing to relocate. */
|
||||
return pathname;
|
||||
}
|
||||
|
||||
#endif
|
67
intl/relocatable.h
Normal file
67
intl/relocatable.h
Normal file
@ -0,0 +1,67 @@
|
||||
/* Provide relocatable packages.
|
||||
Copyright (C) 2003 Free Software Foundation, Inc.
|
||||
Written by Bruno Haible <bruno@clisp.org>, 2003.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Library 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library 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. */
|
||||
|
||||
#ifndef _RELOCATABLE_H
|
||||
#define _RELOCATABLE_H
|
||||
|
||||
/* This can be enabled through the configure --enable-relocatable option. */
|
||||
#if ENABLE_RELOCATABLE
|
||||
|
||||
/* When building a DLL, we must export some functions. Note that because
|
||||
this is a private .h file, we don't need to use __declspec(dllimport)
|
||||
in any case. */
|
||||
#if defined _MSC_VER && BUILDING_DLL
|
||||
# define RELOCATABLE_DLL_EXPORTED __declspec(dllexport)
|
||||
#else
|
||||
# define RELOCATABLE_DLL_EXPORTED
|
||||
#endif
|
||||
|
||||
/* Sets the original and the current installation prefix of the package.
|
||||
Relocation simply replaces a pathname starting with the original prefix
|
||||
by the corresponding pathname with the current prefix instead. Both
|
||||
prefixes should be directory names without trailing slash (i.e. use ""
|
||||
instead of "/"). */
|
||||
extern RELOCATABLE_DLL_EXPORTED void
|
||||
set_relocation_prefix (const char *orig_prefix,
|
||||
const char *curr_prefix);
|
||||
|
||||
/* Returns the pathname, relocated according to the current installation
|
||||
directory. */
|
||||
extern const char * relocate (const char *pathname);
|
||||
|
||||
/* Memory management: relocate() leaks memory, because it has to construct
|
||||
a fresh pathname. If this is a problem because your program calls
|
||||
relocate() frequently, think about caching the result. */
|
||||
|
||||
/* Convenience function:
|
||||
Computes the current installation prefix, based on the original
|
||||
installation prefix, the original installation directory of a particular
|
||||
file, and the current pathname of this file. Returns NULL upon failure. */
|
||||
extern const char * compute_curr_prefix (const char *orig_installprefix,
|
||||
const char *orig_installdir,
|
||||
const char *curr_pathname);
|
||||
|
||||
#else
|
||||
|
||||
/* By default, we use the hardwired pathnames. */
|
||||
#define relocate(pathname) (pathname)
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* _RELOCATABLE_H */
|
Loading…
x
Reference in New Issue
Block a user