Back to the 1.0 version of gettext, I can't figure this one out to save my life =(

git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@631 35c25a1d-7b9e-4130-9fde-d3aeb78583b8
master
Chris Allegretta 2001-04-30 14:04:44 +00:00
parent b0bce4b429
commit 0bafa91096
19 changed files with 2239 additions and 1189 deletions

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
# Makefile for directory with message catalog handling in GNU NLS Utilities. # Makefile for directory with message catalog handling in GNU NLS Utilities.
# Copyright (C) 1995-1998, 2000, 2001 Free Software Foundation, Inc. # Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
# #
# This program is free software; you can redistribute it and/or modify # This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
@ -30,104 +30,73 @@ exec_prefix = @exec_prefix@
transform = @program_transform_name@ transform = @program_transform_name@
libdir = $(exec_prefix)/lib libdir = $(exec_prefix)/lib
includedir = $(prefix)/include includedir = $(prefix)/include
datadir = $(prefix)/share datadir = $(prefix)/@DATADIRNAME@
localedir = $(datadir)/locale localedir = $(datadir)/locale
gnulocaledir = $(prefix)/share/locale
gettextsrcdir = @datadir@/gettext/intl gettextsrcdir = @datadir@/gettext/intl
aliaspath = $(localedir) aliaspath = $(localedir):.
subdir = intl subdir = intl
INSTALL = @INSTALL@ INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@ INSTALL_DATA = @INSTALL_DATA@
MKINSTALLDIRS = @MKINSTALLDIRS@ MKINSTALLDIRS = @MKINSTALLDIRS@
mkinstalldirs = $(SHELL) `case "$(MKINSTALLDIRS)" in /*) echo "$(MKINSTALLDIRS)" ;; *) echo "$(top_builddir)/$(MKINSTALLDIRS)" ;; esac`
l = @INTL_LIBTOOL_SUFFIX_PREFIX@ l = @l@
AR = ar AR = ar
CC = @CC@ CC = @CC@
LIBTOOL = @LIBTOOL@ LIBTOOL = @LIBTOOL@
RANLIB = @RANLIB@ RANLIB = @RANLIB@
YACC = @INTLBISON@ -y -d
YFLAGS = --name-prefix=__gettext
DEFS = -DLOCALEDIR=\"$(localedir)\" -DLOCALE_ALIAS_PATH=\"$(aliaspath)\" \ DEFS = -DLOCALEDIR=\"$(localedir)\" -DGNULOCALEDIR=\"$(gnulocaledir)\" \
-DLIBDIR=\"$(libdir)\" @DEFS@ -DLOCALE_ALIAS_PATH=\"$(aliaspath)\" @DEFS@
CPPFLAGS = @CPPFLAGS@ CPPFLAGS = @CPPFLAGS@
CFLAGS = @CFLAGS@ CFLAGS = @CFLAGS@
LDFLAGS = @LDFLAGS@ LDFLAGS = @LDFLAGS@
COMPILE = $(CC) -c $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) $(XCFLAGS) COMPILE = $(CC) -c $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) $(XCFLAGS)
HEADERS = $(COMHDRS) libgnuintl.h libgettext.h loadinfo.h HEADERS = $(COMHDRS) libgettext.h loadinfo.h
COMHDRS = gettext.h gettextP.h hash-string.h COMHDRS = gettext.h gettextP.h hash-string.h
SOURCES = $(COMSRCS) intl-compat.c SOURCES = $(COMSRCS) intl-compat.c cat-compat.c
COMSRCS = bindtextdom.c dcgettext.c dgettext.c gettext.c \ COMSRCS = bindtextdom.c dcgettext.c dgettext.c gettext.c \
finddomain.c loadmsgcat.c localealias.c textdomain.c l10nflist.c \ finddomain.c loadmsgcat.c localealias.c textdomain.c l10nflist.c \
explodename.c dcigettext.c dcngettext.c dngettext.c ngettext.c plural.y \ explodename.c
localcharset.c
OBJECTS = @INTLOBJS@ bindtextdom.$lo dcgettext.$lo dgettext.$lo gettext.$lo \ OBJECTS = @INTLOBJS@ bindtextdom.$lo dcgettext.$lo dgettext.$lo gettext.$lo \
finddomain.$lo loadmsgcat.$lo localealias.$lo textdomain.$lo l10nflist.$lo \ finddomain.$lo loadmsgcat.$lo localealias.$lo textdomain.$lo l10nflist.$lo \
explodename.$lo dcigettext.$lo dcngettext.$lo dngettext.$lo ngettext.$lo \ explodename.$lo
plural.$lo localcharset.$lo CATOBJS = cat-compat.$lo ../po/cat-id-tbl.$lo
GETTOBJS = intl-compat.$lo GETTOBJS = intl-compat.$lo
DISTFILES.common = Makefile.in \ DISTFILES.common = ChangeLog Makefile.in linux-msg.sed po2tbl.sed.in \
config.charset locale.alias ref-add.sin ref-del.sin $(HEADERS) $(SOURCES) xopen-msg.sed $(HEADERS) $(SOURCES)
DISTFILES.generated = plural.c
DISTFILES.normal = VERSION DISTFILES.normal = VERSION
DISTFILES.gettext = libintl.glibc DISTFILES.gettext = libintl.glibc intlh.inst.in
DISTFILES.obsolete = xopen-msg.sed linux-msg.sed po2tbl.sed.in cat-compat.c
# Libtool's library version information for libintl.
# Before making a gettext release, the gettext maintainer must change this
# according to the libtool documentation, section "Library interface versions".
# Maintainers of other packages that include the intl directory must *not*
# change these values.
LTV_CURRENT=1
LTV_REVISION=0
LTV_AGE=0
.SUFFIXES: .SUFFIXES:
.SUFFIXES: .c .y .o .lo .sin .sed .SUFFIXES: .c .o .lo
.c.o: .c.o:
$(COMPILE) $< $(COMPILE) $<
.c.lo: .c.lo:
$(LIBTOOL) --mode=compile $(COMPILE) $< $(LIBTOOL) --mode=compile $(COMPILE) $<
.y.c: INCLUDES = -I.. -I. -I$(top_srcdir)/intl -I$(top_srcdir)/lib
$(YACC) $(YFLAGS) --output $@ $<
rm -f $*.h
.sin.sed:
sed -e '/^#/d' -e 's/@''PACKAGE''@/@PACKAGE@/g' $< > t-$@
mv t-$@ $@
INCLUDES = -I.. -I. -I$(top_srcdir)/intl
all: all-@USE_INCLUDED_LIBINTL@ all: all-@USE_INCLUDED_LIBINTL@
all-yes: libintl.$la libintl.h charset.alias ref-add.sed ref-del.sed
all-no: all-no-@BUILD_INCLUDED_LIBINTL@
all-no-yes: libgnuintl.$la
all-no-no:
libintl.a libgnuintl.a: $(OBJECTS) all-yes: libintl.$la intlh.inst
all-no:
libintl.a: $(OBJECTS)
rm -f $@ rm -f $@
$(AR) cru $@ $(OBJECTS) $(AR) cru $@ $(OBJECTS)
$(RANLIB) $@ $(RANLIB) $@
libintl.la libgnuintl.la: $(OBJECTS) libintl.la: $(OBJECTS)
$(LIBTOOL) --mode=link \ $(LIBTOOL) --mode=link $(CC) $(LDFLAGS) -o $@ $(OBJECTS) \
$(CC) $(CPPFLAGS) $(CFLAGS) $(XCFLAGS) $(LDFLAGS) -o $@ \ -version-info 1:0 -rpath $(libdir)
$(OBJECTS) @LIBICONV@ \
-version-info $(LTV_CURRENT):$(LTV_REVISION):$(LTV_AGE) \
-rpath $(libdir) \
-no-undefined
libintl.h: libgnuintl.h ../po/cat-id-tbl.$lo: ../po/cat-id-tbl.c $(top_srcdir)/po/$(PACKAGE).pot
cp $(srcdir)/libgnuintl.h libintl.h cd ../po && $(MAKE) cat-id-tbl.$lo
charset.alias: config.charset
$(SHELL) $(srcdir)/config.charset '@host@' > t-$@
mv t-$@ $@
check: all check: all
@ -135,57 +104,36 @@ check: all
# only use the library should use install instead. # only use the library should use install instead.
# We must not install the libintl.h/libintl.a files if we are on a # We must not install the libintl.h/libintl.a files if we are on a
# system which has the GNU gettext() function in its C library or in a # system which has the gettext() function in its C library or in a
# separate library. # separate library or use the catgets interface. A special case is
# where configure found a previously installed GNU gettext library.
# If you want to use the one which comes with this version of the # If you want to use the one which comes with this version of the
# package, you have to use `configure --with-included-gettext'. # package, you have to use `configure --with-included-gettext'.
install: install-exec install-data install: install-exec install-data
install-exec: all install-exec: all
if test "$(PACKAGE)" = "gettext" \ if test "$(PACKAGE)" = "gettext" \
&& test '@INTLOBJS@' = '$(GETTOBJS)'; then \ && test '@INTLOBJS@' = '$(GETTOBJS)'; then \
$(mkinstalldirs) $(DESTDIR)$(libdir) $(DESTDIR)$(includedir); \ if test -r $(MKINSTALLDIRS); then \
$(INSTALL_DATA) libintl.h $(DESTDIR)$(includedir)/libintl.h; \ $(MKINSTALLDIRS) $(libdir) $(includedir); \
$(LIBTOOL) --mode=install \
$(INSTALL_DATA) libintl.$la $(DESTDIR)$(libdir)/libintl.$la; \
else \ else \
: ; \ $(top_srcdir)/mkinstalldirs $(libdir) $(includedir); \
fi fi; \
if test '@USE_INCLUDED_LIBINTL@' = yes; then \ $(INSTALL_DATA) intlh.inst $(includedir)/libintl.h; \
$(mkinstalldirs) $(DESTDIR)$(libdir); \ $(INSTALL_DATA) libintl.a $(libdir)/libintl.a; \
test -f $(DESTDIR)$(libdir)/charset.alias \
&& orig=$(DESTDIR)$(libdir)/charset.alias \
|| orig=charset.alias; \
temp=$(DESTDIR)$(libdir)/t-charset.alias; \
dest=$(DESTDIR)$(libdir)/charset.alias; \
sed -f ref-add.sed $$orig > $$temp; \
$(INSTALL_DATA) $$temp $$dest; \
rm -f $$temp; \
$(mkinstalldirs) $(DESTDIR)$(localedir); \
test -f $(DESTDIR)$(localedir)/locale.alias \
&& orig=$(DESTDIR)$(localedir)/locale.alias \
|| orig=$(srcdir)/locale.alias; \
temp=$(DESTDIR)$(localedir)/t-locale.alias; \
dest=$(DESTDIR)$(localedir)/locale.alias; \
sed -f ref-add.sed $$orig > $$temp; \
$(INSTALL_DATA) $$temp $$dest; \
rm -f $$temp; \
else \ else \
: ; \ : ; \
fi fi
install-data: all install-data: all
if test "$(PACKAGE)" = "gettext"; then \ if test "$(PACKAGE)" = "gettext"; then \
$(mkinstalldirs) $(DESTDIR)$(gettextsrcdir); \ if test -r $(MKINSTALLDIRS); then \
$(INSTALL_DATA) VERSION $(DESTDIR)$(gettextsrcdir)/VERSION; \ $(MKINSTALLDIRS) $(gettextsrcdir); \
$(INSTALL_DATA) ChangeLog.inst $(DESTDIR)$(gettextsrcdir)/ChangeLog; \ else \
$(top_srcdir)/mkinstalldirs $(gettextsrcdir); \
fi; \
$(INSTALL_DATA) VERSION $(gettextsrcdir)/VERSION; \
dists="$(DISTFILES.common)"; \ dists="$(DISTFILES.common)"; \
for file in $$dists; do \ for file in $$dists; do \
$(INSTALL_DATA) $(srcdir)/$$file \ $(INSTALL_DATA) $(srcdir)/$$file $(gettextsrcdir)/$$file; \
$(DESTDIR)$(gettextsrcdir)/$$file; \
done; \
chmod a+x $(DESTDIR)$(gettextsrcdir)/config.charset; \
dists="$(DISTFILES.obsolete)"; \
for file in $$dists; do \
rm -f $(DESTDIR)$(gettextsrcdir)/$$file; \
done; \ done; \
else \ else \
: ; \ : ; \
@ -195,51 +143,14 @@ install-data: all
installcheck: installcheck:
uninstall: uninstall:
if test "$(PACKAGE)" = "gettext" \ dists="$(DISTFILES.common)"; \
&& test '@INTLOBJS@' = '$(GETTOBJS)'; then \ for file in $$dists; do \
rm -f $(DESTDIR)$(includedir)/libintl.h; \ rm -f $(gettextsrcdir)/$$file; \
$(LIBTOOL) --mode=uninstall \ done
rm -f $(DESTDIR)$(libdir)/libintl.$la; \
else \
: ; \
fi
if test '@USE_INCLUDED_LIBINTL@' = yes; then \
if test -f $(DESTDIR)$(libdir)/charset.alias; then \
temp=$(DESTDIR)$(libdir)/t-charset.alias; \
dest=$(DESTDIR)$(libdir)/charset.alias; \
sed -f ref-del.sed $$dest > $$temp; \
if grep '^# Packages using this file: $$' $$temp > /dev/null; then \
rm -f $$dest; \
else \
$(INSTALL_DATA) $$temp $$dest; \
fi; \
rm -f $$temp; \
fi; \
if test -f $(DESTDIR)$(localedir)/locale.alias; then \
temp=$(DESTDIR)$(localedir)/t-locale.alias; \
dest=$(DESTDIR)$(localedir)/locale.alias; \
sed -f ref-del.sed $$dest > $$temp; \
if grep '^# Packages using this file: $$' $$temp > /dev/null; then \
rm -f $$dest; \
else \
$(INSTALL_DATA) $$temp $$dest; \
fi; \
rm -f $$temp; \
fi; \
else \
: ; \
fi
if test "$(PACKAGE)" = "gettext"; then \
for file in VERSION ChangeLog $(DISTFILES.common); do \
rm -f $(DESTDIR)$(gettextsrcdir)/$$file; \
done; \
else \
: ; \
fi
info dvi: info dvi:
$(OBJECTS): ../config.h libgnuintl.h $(OBJECTS): ../config.h libgettext.h
bindtextdom.$lo finddomain.$lo loadmsgcat.$lo: gettextP.h gettext.h loadinfo.h bindtextdom.$lo finddomain.$lo loadmsgcat.$lo: gettextP.h gettext.h loadinfo.h
dcgettext.$lo: gettextP.h gettext.h hash-string.h loadinfo.h dcgettext.$lo: gettextP.h gettext.h hash-string.h loadinfo.h
@ -255,19 +166,12 @@ ID: $(HEADERS) $(SOURCES)
mostlyclean: mostlyclean:
rm -f *.a *.la *.o *.lo core core.* rm -f *.a *.o *.lo core core.*
rm -f libintl.h charset.alias ref-add.sed ref-del.sed
rm -f -r .libs _libs
clean: mostlyclean clean: mostlyclean
distclean: clean distclean: clean
rm -f Makefile ID TAGS rm -f Makefile ID TAGS po2msg.sed po2tbl.sed libintl.h
if test "$(PACKAGE)" = gettext; then \
rm -f ChangeLog.inst $(DISTFILES.normal); \
else \
: ; \
fi
maintainer-clean: distclean maintainer-clean: distclean
@echo "This command is intended for maintainers to use;" @echo "This command is intended for maintainers to use;"
@ -277,22 +181,34 @@ maintainer-clean: distclean
# GNU gettext needs not contain the file `VERSION' but contains some # GNU gettext needs not contain the file `VERSION' but contains some
# other files which should not be distributed in other packages. # other files which should not be distributed in other packages.
distdir = ../$(PACKAGE)-$(VERSION)/$(subdir) distdir = ../$(PACKAGE)-$(VERSION)/$(subdir)
dist distdir: Makefile dist distdir: Makefile $(DISTFILES)
if test "$(PACKAGE)" = gettext; then \ if test "$(PACKAGE)" = gettext; then \
additional="$(DISTFILES.gettext)"; \ additional="$(DISTFILES.gettext)"; \
else \ else \
additional="$(DISTFILES.normal)"; \ additional="$(DISTFILES.normal)"; \
fi; \ fi; \
$(MAKE) $(DISTFILES.common) $(DISTFILES.generated) $$additional; \ for file in $(DISTFILES.common) $$additional; do \
for file in ChangeLog $(DISTFILES.common) $(DISTFILES.generated) $$additional; do \
ln $(srcdir)/$$file $(distdir) 2> /dev/null \ ln $(srcdir)/$$file $(distdir) 2> /dev/null \
|| cp -p $(srcdir)/$$file $(distdir); \ || cp -p $(srcdir)/$$file $(distdir); \
done done
dist-libc:
tar zcvf intl-glibc.tar.gz $(COMSRCS) $(COMHDRS) libintl.h.glibc
Makefile: Makefile.in ../config.status Makefile: Makefile.in ../config.status
cd .. \ cd .. \
&& CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
# The dependency for intlh.inst is different in gettext and all other
# packages. Because we cannot you GNU make features we have to solve
# the problem while rewriting Makefile.in.
@GT_YES@intlh.inst: intlh.inst.in ../config.status
@GT_YES@ cd .. \
@GT_YES@ && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= \
@GT_YES@ $(SHELL) ./config.status
@GT_NO@.PHONY: intlh.inst
@GT_NO@intlh.inst:
# Tell versions [3.59,3.63) of GNU make not to export all variables. # Tell versions [3.59,3.63) of GNU make not to export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded. # Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT: .NOEXPORT:

View File

@ -1 +1 @@
GNU gettext library from gettext-0.10.36 GNU gettext library from gettext-0.10.35

View File

@ -1,5 +1,5 @@
/* Implementation of the bindtextdomain(3) function /* Implementation of the bindtextdomain(3) function
Copyright (C) 1995-1998, 2000, 2001 Free Software Foundation, Inc. Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -19,40 +19,33 @@
# include <config.h> # include <config.h>
#endif #endif
#include <stddef.h> #if defined STDC_HEADERS || defined _LIBC
#include <stdlib.h> # include <stdlib.h>
#include <string.h> #else
# ifdef HAVE_MALLOC_H
# include <malloc.h>
# else
void free ();
# endif
#endif
#if defined HAVE_STRING_H || defined _LIBC
# include <string.h>
#else
# include <strings.h>
# ifndef memcpy
# define memcpy(Dst, Src, Num) bcopy (Src, Dst, Num)
# endif
#endif
#ifdef _LIBC #ifdef _LIBC
# include <libintl.h> # include <libintl.h>
#else #else
# include "libgnuintl.h" # include "libgettext.h"
#endif #endif
#include "gettext.h"
#include "gettextP.h" #include "gettextP.h"
#ifdef _LIBC
/* We have to handle multi-threaded applications. */
# include <bits/libc-lock.h>
#else
/* Provide dummy implementation if this is outside glibc. */
# define __libc_rwlock_define(CLASS, NAME)
# define __libc_rwlock_wrlock(NAME)
# define __libc_rwlock_unlock(NAME)
#endif
/* The internal variables in the standalone libintl.a must have different
names than the internal variables in GNU libc, otherwise programs
using libintl.a cannot be linked statically. */
#if !defined _LIBC
# define _nl_default_dirname _nl_default_dirname__
# define _nl_domain_bindings _nl_domain_bindings__
#endif
/* Some compilers, like SunOS4 cc, don't have offsetof in <stddef.h>. */
#ifndef offsetof
# define offsetof(type,ident) ((size_t)&(((type*)0)->ident))
#endif
/* @@ end of prolog @@ */ /* @@ end of prolog @@ */
/* Contains the default location of the message catalogs. */ /* Contains the default location of the message catalogs. */
@ -61,9 +54,6 @@ extern const char _nl_default_dirname[];
/* List with bindings of specific domains. */ /* List with bindings of specific domains. */
extern struct binding *_nl_domain_bindings; extern struct binding *_nl_domain_bindings;
/* Lock variable to protect the global data in the gettext implementation. */
__libc_rwlock_define (extern, _nl_state_lock)
/* Names for the libintl functions are a problem. They must not clash /* Names for the libintl functions are a problem. They must not clash
with existing names and they should follow ANSI C. But this source with existing names and they should follow ANSI C. But this source
@ -71,48 +61,25 @@ __libc_rwlock_define (extern, _nl_state_lock)
prefix. So we have to make a difference here. */ prefix. So we have to make a difference here. */
#ifdef _LIBC #ifdef _LIBC
# define BINDTEXTDOMAIN __bindtextdomain # define BINDTEXTDOMAIN __bindtextdomain
# define BIND_TEXTDOMAIN_CODESET __bind_textdomain_codeset
# ifndef strdup # ifndef strdup
# define strdup(str) __strdup (str) # define strdup(str) __strdup (str)
# endif # endif
#else #else
# define BINDTEXTDOMAIN bindtextdomain__ # define BINDTEXTDOMAIN bindtextdomain__
# define BIND_TEXTDOMAIN_CODESET bind_textdomain_codeset__
#endif #endif
/* Prototypes for local functions. */ /* Specify that the DOMAINNAME message catalog will be found
static void set_binding_values PARAMS ((const char *domainname, in DIRNAME rather than in the system locale data base. */
const char **dirnamep, char *
const char **codesetp)); BINDTEXTDOMAIN (domainname, dirname)
/* Specifies the directory name *DIRNAMEP and the output codeset *CODESETP
to be used for the DOMAINNAME message catalog.
If *DIRNAMEP or *CODESETP is NULL, the corresponding attribute is not
modified, only the current value is returned.
If DIRNAMEP or CODESETP is NULL, the corresponding attribute is neither
modified nor returned. */
static void
set_binding_values (domainname, dirnamep, codesetp)
const char *domainname; const char *domainname;
const char **dirnamep; const char *dirname;
const char **codesetp;
{ {
struct binding *binding; struct binding *binding;
int modified;
/* Some sanity checks. */ /* Some sanity checks. */
if (domainname == NULL || domainname[0] == '\0') if (domainname == NULL || domainname[0] == '\0')
{ return NULL;
if (dirnamep)
*dirnamep = NULL;
if (codesetp)
*codesetp = NULL;
return;
}
__libc_rwlock_wrlock (_nl_state_lock);
modified = 0;
for (binding = _nl_domain_bindings; binding != NULL; binding = binding->next) for (binding = _nl_domain_bindings; binding != NULL; binding = binding->next)
{ {
@ -128,169 +95,83 @@ set_binding_values (domainname, dirnamep, codesetp)
} }
} }
if (binding != NULL)
{
if (dirnamep)
{
const char *dirname = *dirnamep;
if (dirname == NULL) if (dirname == NULL)
/* The current binding has be to returned. */ /* The current binding has be to returned. */
*dirnamep = binding->dirname; return binding == NULL ? (char *) _nl_default_dirname : binding->dirname;
else
if (binding != NULL)
{ {
/* The domain is already bound. If the new value and the old /* The domain is already bound. If the new value and the old
one are equal we simply do nothing. Otherwise replace the one are equal we simply do nothing. Otherwise replace the
old binding. */ old binding. */
char *result = binding->dirname; if (strcmp (dirname, binding->dirname) != 0)
if (strcmp (dirname, result) != 0)
{ {
char *new_dirname;
if (strcmp (dirname, _nl_default_dirname) == 0) if (strcmp (dirname, _nl_default_dirname) == 0)
result = (char *) _nl_default_dirname; new_dirname = (char *) _nl_default_dirname;
else else
{ {
#if defined _LIBC || defined HAVE_STRDUP #if defined _LIBC || defined HAVE_STRDUP
result = strdup (dirname); new_dirname = strdup (dirname);
if (new_dirname == NULL)
return NULL;
#else #else
size_t len = strlen (dirname) + 1; size_t len = strlen (dirname) + 1;
result = (char *) malloc (len); new_dirname = (char *) malloc (len);
if (__builtin_expect (result != NULL, 1)) if (new_dirname == NULL)
memcpy (result, dirname, len); return NULL;
memcpy (new_dirname, dirname, len);
#endif #endif
} }
if (__builtin_expect (result != NULL, 1))
{
if (binding->dirname != _nl_default_dirname) if (binding->dirname != _nl_default_dirname)
free (binding->dirname); free (binding->dirname);
binding->dirname = result; binding->dirname = new_dirname;
modified = 1;
} }
} }
*dirnamep = result;
}
}
if (codesetp)
{
const char *codeset = *codesetp;
if (codeset == NULL)
/* The current binding has be to returned. */
*codesetp = binding->codeset;
else
{
/* The domain is already bound. If the new value and the old
one are equal we simply do nothing. Otherwise replace the
old binding. */
char *result = binding->codeset;
if (result == NULL || strcmp (codeset, result) != 0)
{
#if defined _LIBC || defined HAVE_STRDUP
result = strdup (codeset);
#else
size_t len = strlen (codeset) + 1;
result = (char *) malloc (len);
if (__builtin_expect (result != NULL, 1))
memcpy (result, codeset, len);
#endif
if (__builtin_expect (result != NULL, 1))
{
if (binding->codeset != NULL)
free (binding->codeset);
binding->codeset = result;
modified = 1;
}
}
*codesetp = result;
}
}
}
else if ((dirnamep == NULL || *dirnamep == NULL)
&& (codesetp == NULL || *codesetp == NULL))
{
/* Simply return the default values. */
if (dirnamep)
*dirnamep = _nl_default_dirname;
if (codesetp)
*codesetp = NULL;
}
else else
{ {
/* We have to create a new binding. */ /* We have to create a new binding. */
size_t len = strlen (domainname) + 1; #if !defined _LIBC && !defined HAVE_STRDUP
size_t len;
#endif
struct binding *new_binding = struct binding *new_binding =
(struct binding *) malloc (offsetof (struct binding, domainname) + len); (struct binding *) malloc (sizeof (*new_binding));
if (__builtin_expect (new_binding == NULL, 0)) if (new_binding == NULL)
goto failed; return NULL;
#if defined _LIBC || defined HAVE_STRDUP
new_binding->domainname = strdup (domainname);
if (new_binding->domainname == NULL)
return NULL;
#else
len = strlen (domainname) + 1;
new_binding->domainname = (char *) malloc (len);
if (new_binding->domainname == NULL)
return NULL;
memcpy (new_binding->domainname, domainname, len); memcpy (new_binding->domainname, domainname, len);
#endif
if (dirnamep)
{
const char *dirname = *dirnamep;
if (dirname == NULL)
/* The default value. */
dirname = _nl_default_dirname;
else
{
if (strcmp (dirname, _nl_default_dirname) == 0) if (strcmp (dirname, _nl_default_dirname) == 0)
dirname = _nl_default_dirname;
else
{
char *result;
#if defined _LIBC || defined HAVE_STRDUP
result = strdup (dirname);
if (__builtin_expect (result == NULL, 0))
goto failed_dirname;
#else
size_t len = strlen (dirname) + 1;
result = (char *) malloc (len);
if (__builtin_expect (result == NULL, 0))
goto failed_dirname;
memcpy (result, dirname, len);
#endif
dirname = result;
}
}
*dirnamep = dirname;
new_binding->dirname = (char *) dirname;
}
else
/* The default value. */
new_binding->dirname = (char *) _nl_default_dirname; new_binding->dirname = (char *) _nl_default_dirname;
if (codesetp)
{
const char *codeset = *codesetp;
if (codeset != NULL)
{
char *result;
#if defined _LIBC || defined HAVE_STRDUP
result = strdup (codeset);
if (__builtin_expect (result == NULL, 0))
goto failed_codeset;
#else
size_t len = strlen (codeset) + 1;
result = (char *) malloc (len);
if (__builtin_expect (result == NULL, 0))
goto failed_codeset;
memcpy (result, codeset, len);
#endif
codeset = result;
}
*codesetp = codeset;
new_binding->codeset = (char *) codeset;
}
else else
new_binding->codeset = NULL; {
#if defined _LIBC || defined HAVE_STRDUP
new_binding->dirname = strdup (dirname);
if (new_binding->dirname == NULL)
return NULL;
#else
len = strlen (dirname) + 1;
new_binding->dirname = (char *) malloc (len);
if (new_binding->dirname == NULL)
return NULL;
memcpy (new_binding->dirname, dirname, len);
#endif
}
/* Now enqueue it. */ /* Now enqueue it. */
if (_nl_domain_bindings == NULL if (_nl_domain_bindings == NULL
@ -310,55 +191,13 @@ set_binding_values (domainname, dirnamep, codesetp)
binding->next = new_binding; binding->next = new_binding;
} }
modified = 1; binding = new_binding;
/* Here we deal with memory allocation failures. */
if (0)
{
failed_codeset:
if (new_binding->dirname != _nl_default_dirname)
free (new_binding->dirname);
failed_dirname:
free (new_binding);
failed:
if (dirnamep)
*dirnamep = NULL;
if (codesetp)
*codesetp = NULL;
}
} }
/* If we modified any binding, we flush the caches. */ return binding->dirname;
if (modified)
++_nl_msg_cat_cntr;
__libc_rwlock_unlock (_nl_state_lock);
}
/* Specify that the DOMAINNAME message catalog will be found
in DIRNAME rather than in the system locale data base. */
char *
BINDTEXTDOMAIN (domainname, dirname)
const char *domainname;
const char *dirname;
{
set_binding_values (domainname, &dirname, NULL);
return (char *) dirname;
}
/* Specify the character encoding in which the messages from the
DOMAINNAME message catalog will be returned. */
char *
BIND_TEXTDOMAIN_CODESET (domainname, codeset)
const char *domainname;
const char *codeset;
{
set_binding_values (domainname, NULL, &codeset);
return (char *) codeset;
} }
#ifdef _LIBC #ifdef _LIBC
/* Aliases for function names in GNU C Library. */ /* Alias for function name in GNU C Library. */
weak_alias (__bindtextdomain, bindtextdomain); weak_alias (__bindtextdomain, bindtextdomain);
weak_alias (__bind_textdomain_codeset, bind_textdomain_codeset);
#endif #endif

View File

@ -1,5 +1,5 @@
/* Implementation of the dcgettext(3) function. /* Implementation of the dcgettext(3) function.
Copyright (C) 1995-1999, 2000, 2001 Free Software Foundation, Inc. Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -19,25 +19,220 @@
# include <config.h> # include <config.h>
#endif #endif
#include <sys/types.h>
#if defined __GNUC__ && !defined C_ALLOCA
# define alloca __builtin_alloca
# define HAVE_ALLOCA 1
#else
# if (defined HAVE_ALLOCA_H || defined _LIBC) && !defined C_ALLOCA
# 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" #include "gettextP.h"
#ifdef _LIBC #ifdef _LIBC
# include <libintl.h> # include <libintl.h>
#else #else
# include "libgnuintl.h" # include "libgettext.h"
#endif #endif
#include "hash-string.h"
/* @@ end of prolog @@ */ /* @@ 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
# ifndef stpcpy
# define stpcpy __stpcpy
# endif
#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)) internal_function;
static const char *category_to_name PARAMS ((int category)) internal_function;
static const char *guess_category_value PARAMS ((int category,
const char *categoryname))
internal_function;
/* 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 /* Names for the libintl functions are a problem. They must not clash
with existing names and they should follow ANSI C. But this source with existing names and they should follow ANSI C. But this source
code is also used in GNU C Library where the names have a __ code is also used in GNU C Library where the names have a __
prefix. So we have to make a difference here. */ prefix. So we have to make a difference here. */
#ifdef _LIBC #ifdef _LIBC
# define DCGETTEXT __dcgettext # define DCGETTEXT __dcgettext
# define DCIGETTEXT __dcigettext
#else #else
# define DCGETTEXT dcgettext__ # define DCGETTEXT dcgettext__
# define DCIGETTEXT dcigettext__ #endif
/* Checking whether the binaries runs SUID must be done and glibc provides
easier methods therefore we make a difference here. */
#ifdef _LIBC
# define ENABLE_SECURE __libc_enable_secure
# define DETERMINE_SECURE
#else
static int enable_secure;
# define ENABLE_SECURE (enable_secure == 1)
# define DETERMINE_SECURE \
if (enable_secure == 0) \
{ \
if (getuid () != geteuid () || getgid () != getegid ()) \
enable_secure = 1; \
else \
enable_secure = -1; \
}
#endif #endif
/* Look up MSGID in the DOMAINNAME message catalog for the current CATEGORY /* Look up MSGID in the DOMAINNAME message catalog for the current CATEGORY
@ -48,10 +243,413 @@ DCGETTEXT (domainname, msgid, category)
const char *msgid; const char *msgid;
int category; int category;
{ {
return DCIGETTEXT (domainname, msgid, NULL, 0, 0, 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;
/* See whether this is a SUID binary or not. */
DETERMINE_SECURE;
/* 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
definition 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 int) 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;
}
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);
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 the 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';
/* When this is a SUID binary we must not allow accessing files
outside the dedicated directories. */
if (ENABLE_SECURE
&& (memchr (single_locale, '/',
_nl_find_language (single_locale) - single_locale)
!= NULL))
/* Ingore this entry. */
continue;
}
/* 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 #ifdef _LIBC
/* Alias for function name in GNU C Library. */ /* Alias for function name in GNU C Library. */
weak_alias (__dcgettext, dcgettext); weak_alias (__dcgettext, dcgettext);
#endif #endif
static char *
internal_function
find_msg (domain_file, msgid)
struct loaded_l10nfile *domain_file;
const char *msgid;
{
size_t act = 0;
size_t top, 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 *
internal_function
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 *
internal_function
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
#ifdef _LIBC
/* If we want to free all resources we have to do some work at
program's end. */
static void __attribute__ ((unused))
free_mem (void)
{
struct binding *runp;
for (runp = _nl_domain_bindings; runp != NULL; runp = runp->next)
{
free (runp->domainname);
if (runp->dirname != _nl_default_dirname)
/* Yes, this is a pointer comparison. */
free (runp->dirname);
}
if (_nl_current_default_domain != _nl_default_default_domain)
/* Yes, again a pointer comparison. */
free ((char *) _nl_current_default_domain);
}
text_set_element (__libc_subfreeres, free_mem);
#endif

View File

@ -1,5 +1,5 @@
/* Implementation of the dgettext(3) function. /* Implementation of the dgettext(3) function
Copyright (C) 1995-1997, 2000, 2001 Free Software Foundation, Inc. Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -19,13 +19,14 @@
# include <config.h> # include <config.h>
#endif #endif
#include <locale.h> #if defined HAVE_LOCALE_H || defined _LIBC
# include <locale.h>
#endif
#include "gettextP.h"
#ifdef _LIBC #ifdef _LIBC
# include <libintl.h> # include <libintl.h>
#else #else
# include "libgnuintl.h" # include "libgettext.h"
#endif #endif
/* @@ end of prolog @@ */ /* @@ end of prolog @@ */

View File

@ -1,4 +1,4 @@
/* Copyright (C) 1995-1998, 2000, 2001 Free Software Foundation, Inc. /* Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995. Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
@ -19,8 +19,15 @@
# include <config.h> # include <config.h>
#endif #endif
#include <stdlib.h> #if defined STDC_HEADERS || defined _LIBC
#include <string.h> # include <stdlib.h>
#endif
#if defined HAVE_STRING_H || defined _LIBC
# include <string.h>
#else
# include <strings.h>
#endif
#include <sys/types.h> #include <sys/types.h>
#include "loadinfo.h" #include "loadinfo.h"

View File

@ -1,6 +1,6 @@
/* Handle list of needed message catalogs /* Handle list of needed message catalogs
Copyright (C) 1995-1999, 2000, 2001 Free Software Foundation, Inc. Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
Written by Ulrich Drepper <drepper@gnu.org>, 1995. Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -20,20 +20,45 @@
# include <config.h> # include <config.h>
#endif #endif
#include <ctype.h>
#include <errno.h>
#include <stdio.h> #include <stdio.h>
#include <sys/types.h> #include <sys/types.h>
#include <stdlib.h>
#include <string.h> #if defined STDC_HEADERS || defined _LIBC
# include <stdlib.h>
#else
# ifdef HAVE_MALLOC_H
# include <malloc.h>
# else
void free ();
# endif
#endif
#if defined HAVE_STRING_H || defined _LIBC
# include <string.h>
#else
# include <strings.h>
# ifndef memcpy
# define memcpy(Dst, Src, Num) bcopy (Src, Dst, Num)
# endif
#endif
#if !HAVE_STRCHR && !defined _LIBC
# ifndef strchr
# define strchr index
# endif
#endif
#if defined HAVE_UNISTD_H || defined _LIBC #if defined HAVE_UNISTD_H || defined _LIBC
# include <unistd.h> # include <unistd.h>
#endif #endif
#include "gettext.h"
#include "gettextP.h" #include "gettextP.h"
#ifdef _LIBC #ifdef _LIBC
# include <libintl.h> # include <libintl.h>
#else #else
# include "libgnuintl.h" # include "libgettext.h"
#endif #endif
/* @@ end of prolog @@ */ /* @@ end of prolog @@ */
@ -46,11 +71,10 @@ static struct loaded_l10nfile *_nl_loaded_domains;
established bindings. */ established bindings. */
struct loaded_l10nfile * struct loaded_l10nfile *
internal_function internal_function
_nl_find_domain (dirname, locale, domainname, domainbinding) _nl_find_domain (dirname, locale, domainname)
const char *dirname; const char *dirname;
char *locale; char *locale;
const char *domainname; const char *domainname;
struct binding *domainbinding;
{ {
struct loaded_l10nfile *retval; struct loaded_l10nfile *retval;
const char *language; const char *language;
@ -89,8 +113,7 @@ _nl_find_domain (dirname, locale, domainname, domainbinding)
be one data set in the list of loaded domains. */ be one data set in the list of loaded domains. */
retval = _nl_make_l10nflist (&_nl_loaded_domains, dirname, retval = _nl_make_l10nflist (&_nl_loaded_domains, dirname,
strlen (dirname) + 1, 0, locale, NULL, NULL, strlen (dirname) + 1, 0, locale, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, domainname, NULL, NULL, NULL, NULL, NULL, domainname, 0);
domainbinding, 0);
if (retval != NULL) if (retval != NULL)
{ {
/* We know something about this locale. */ /* We know something about this locale. */
@ -146,8 +169,7 @@ _nl_find_domain (dirname, locale, domainname, domainbinding)
retval = _nl_make_l10nflist (&_nl_loaded_domains, dirname, retval = _nl_make_l10nflist (&_nl_loaded_domains, dirname,
strlen (dirname) + 1, mask, language, territory, strlen (dirname) + 1, mask, language, territory,
codeset, normalized_codeset, modifier, special, codeset, normalized_codeset, modifier, special,
sponsor, revision, domainname, domainbinding, sponsor, revision, domainname, 1);
1);
if (retval == NULL) if (retval == NULL)
/* This means we are out of core. */ /* This means we are out of core. */
return NULL; return NULL;
@ -170,10 +192,6 @@ _nl_find_domain (dirname, locale, domainname, domainbinding)
if (alias_value != NULL) if (alias_value != NULL)
free (locale); free (locale);
/* The space for normalized_codeset is dynamically allocated. Free it. */
if (mask & XPG_NORM_CODESET)
free ((void *) normalized_codeset);
return retval; return retval;
} }
@ -190,7 +208,6 @@ free_mem (void)
if (runp->data != NULL) if (runp->data != NULL)
_nl_unload_domain ((struct loaded_domain *) runp->data); _nl_unload_domain ((struct loaded_domain *) runp->data);
runp = runp->next; runp = runp->next;
free ((char *) here->filename);
free (here); free (here);
} }
} }

View File

@ -1,5 +1,5 @@
/* Implementation of gettext(3) function. /* Implementation of gettext(3) function.
Copyright (C) 1995, 1997, 2000, 2001 Free Software Foundation, Inc. Copyright (C) 1995, 1997 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -23,14 +23,21 @@
# define __need_NULL # define __need_NULL
# include <stddef.h> # include <stddef.h>
#else #else
# ifdef STDC_HEADERS
# include <stdlib.h> /* Just for NULL. */ # include <stdlib.h> /* Just for NULL. */
# else
# ifdef HAVE_STRING_H
# include <string.h>
# else
# define NULL ((void *) 0)
# endif
# endif
#endif #endif
#include "gettextP.h"
#ifdef _LIBC #ifdef _LIBC
# include <libintl.h> # include <libintl.h>
#else #else
# include "libgnuintl.h" # include "libgettext.h"
#endif #endif
/* @@ end of prolog @@ */ /* @@ end of prolog @@ */
@ -41,10 +48,10 @@
prefix. So we have to make a difference here. */ prefix. So we have to make a difference here. */
#ifdef _LIBC #ifdef _LIBC
# define GETTEXT __gettext # define GETTEXT __gettext
# define DCGETTEXT __dcgettext # define DGETTEXT __dgettext
#else #else
# define GETTEXT gettext__ # define GETTEXT gettext__
# define DCGETTEXT dcgettext__ # define DGETTEXT dgettext__
#endif #endif
/* Look up MSGID in the current default message catalog for the current /* Look up MSGID in the current default message catalog for the current
@ -54,7 +61,7 @@ char *
GETTEXT (msgid) GETTEXT (msgid)
const char *msgid; const char *msgid;
{ {
return DCGETTEXT (NULL, msgid, LC_MESSAGES); return DGETTEXT (NULL, msgid);
} }
#ifdef _LIBC #ifdef _LIBC

View File

@ -1,5 +1,5 @@
/* Description of GNU message catalog format: general file layout. /* Internal header for GNU gettext internationalization functions.
Copyright (C) 1995, 1997, 2000, 2001 Free Software Foundation, Inc. Copyright (C) 1995, 1997 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -11,13 +11,16 @@
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU Library General Public
along with this program; if not, write to the Free Software Foundation, License along with the GNU C Library; see the file COPYING.LIB. If not,
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#ifndef _GETTEXT_H #ifndef _GETTEXT_H
#define _GETTEXT_H 1 #define _GETTEXT_H 1
#include <stdio.h>
#if HAVE_LIMITS_H || _LIBC #if HAVE_LIMITS_H || _LIBC
# include <limits.h> # include <limits.h>
#endif #endif
@ -34,8 +37,9 @@
/* The following contortions are an attempt to use the C preprocessor /* The following contortions are an attempt to use the C preprocessor
to determine an unsigned integral type that is 32 bits wide. An to determine an unsigned integral type that is 32 bits wide. An
alternative approach is to use autoconf's AC_CHECK_SIZEOF macro, but 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 doing that would require that the configure script compile and *run*
when cross-compiling. */ the resulting executable. Locally running cross-compiled executables
is usually not possible. */
#if __STDC__ #if __STDC__
# define UINT_MAX_32_BITS 4294967295U # define UINT_MAX_32_BITS 4294967295U

View File

@ -1,6 +1,6 @@
/* Header describing internals of libintl library. /* Header describing internals of gettext library
Copyright (C) 1995-1999, 2000, 2001 Free Software Foundation, Inc. Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
Written by Ulrich Drepper <drepper@cygnus.com>, 1995. Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -19,20 +19,8 @@
#ifndef _GETTEXTP_H #ifndef _GETTEXTP_H
#define _GETTEXTP_H #define _GETTEXTP_H
#include <stddef.h> /* Get size_t. */
#ifdef _LIBC
# include "../iconv/gconv_int.h"
#else
# if HAVE_ICONV
# include <iconv.h>
# endif
#endif
#include "loadinfo.h" #include "loadinfo.h"
#include "gettext.h" /* Get nls_uint32. */
/* @@ end of prolog @@ */ /* @@ end of prolog @@ */
#ifndef PARAMS #ifndef PARAMS
@ -47,12 +35,6 @@
# define internal_function # define internal_function
#endif #endif
/* Tell the compiler when a conditional or integer expression is
almost always true or almost always false. */
#ifndef HAVE_BUILTIN_EXPECT
# define __builtin_expect(expr, val) (expr)
#endif
#ifndef W #ifndef W
# define W(flag, data) ((flag) ? SWAP (data) : (data)) # define W(flag, data) ((flag) ? SWAP (data) : (data))
#endif #endif
@ -62,6 +44,8 @@
# include <byteswap.h> # include <byteswap.h>
# define SWAP(i) bswap_32 (i) # define SWAP(i) bswap_32 (i)
#else #else
static nls_uint32 SWAP PARAMS ((nls_uint32 i));
static inline nls_uint32 static inline nls_uint32
SWAP (i) SWAP (i)
nls_uint32 i; nls_uint32 i;
@ -71,52 +55,6 @@ SWAP (i)
#endif #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, /* Module operation. */
plus, /* Addition. */
minus, /* Subtraction. */
less_than, /* Comparison. */
greater_than, /* Comparison. */
less_or_equal, /* Comparison. */
greater_or_equal, /* Comparison. */
equal, /* Comparision for equality. */
not_equal, /* Comparision 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;
};
/* The representation of an opened message catalog. */
struct loaded_domain struct loaded_domain
{ {
const char *data; const char *data;
@ -128,110 +66,24 @@ struct loaded_domain
struct string_desc *trans_tab; struct string_desc *trans_tab;
nls_uint32 hash_size; nls_uint32 hash_size;
nls_uint32 *hash_tab; nls_uint32 *hash_tab;
#ifdef _LIBC
__gconv_t conv;
#else
# if HAVE_ICONV
iconv_t conv;
# endif
#endif
char **conv_tab;
struct expression *plural;
unsigned long int nplurals;
}; };
/* We want to allocate a string at the end of the struct. But ISO C
doesn't allow zero sized arrays. */
#ifdef __GNUC__
# define ZERO 0
#else
# define ZERO 1
#endif
/* A set of settings bound to a message domain. Used to store settings
from bindtextdomain() and bind_textdomain_codeset(). */
struct binding struct binding
{ {
struct binding *next; struct binding *next;
char *domainname;
char *dirname; char *dirname;
char *codeset;
char domainname[ZERO];
}; };
/* A counter which is incremented each time some previous translations
become invalid.
This variable is part of the external ABI of the GNU libintl. */
extern int _nl_msg_cat_cntr;
struct loaded_l10nfile *_nl_find_domain PARAMS ((const char *__dirname, struct loaded_l10nfile *_nl_find_domain PARAMS ((const char *__dirname,
char *__locale, char *__locale,
const char *__domainname, const char *__domainname))
struct binding *__domainbinding))
internal_function; internal_function;
void _nl_load_domain PARAMS ((struct loaded_l10nfile *__domain)) void _nl_load_domain PARAMS ((struct loaded_l10nfile *__domain))
internal_function; internal_function;
void _nl_unload_domain PARAMS ((struct loaded_domain *__domain)) void _nl_unload_domain PARAMS ((struct loaded_domain *__domain))
internal_function; internal_function;
#ifdef _LIBC
extern char *__gettext PARAMS ((const char *__msgid));
extern char *__dgettext PARAMS ((const char *__domainname,
const char *__msgid));
extern char *__dcgettext PARAMS ((const char *__domainname,
const char *__msgid, int __category));
extern char *__ngettext PARAMS ((const char *__msgid1, const char *__msgid2,
unsigned long int __n));
extern char *__dngettext PARAMS ((const char *__domainname,
const char *__msgid1, const char *__msgid2,
unsigned long int n));
extern char *__dcngettext PARAMS ((const char *__domainname,
const char *__msgid1, const char *__msgid2,
unsigned long int __n, int __category));
extern char *__dcigettext PARAMS ((const char *__domainname,
const char *__msgid1, const char *__msgid2,
int __plural, unsigned long int __n,
int __category));
extern char *__textdomain PARAMS ((const char *__domainname));
extern char *__bindtextdomain PARAMS ((const char *__domainname,
const char *__dirname));
extern char *__bind_textdomain_codeset PARAMS ((const char *__domainname,
const char *__codeset));
#else
extern char *gettext__ PARAMS ((const char *__msgid));
extern char *dgettext__ PARAMS ((const char *__domainname,
const char *__msgid));
extern char *dcgettext__ PARAMS ((const char *__domainname,
const char *__msgid, int __category));
extern char *ngettext__ PARAMS ((const char *__msgid1, const char *__msgid2,
unsigned long int __n));
extern char *dngettext__ PARAMS ((const char *__domainname,
const char *__msgid1, const char *__msgid2,
unsigned long int __n));
extern char *dcngettext__ PARAMS ((const char *__domainname,
const char *__msgid1, const char *__msgid2,
unsigned long int __n, int __category));
extern char *dcigettext__ PARAMS ((const char *__domainname,
const char *__msgid1, const char *__msgid2,
int __plural, unsigned long int __n,
int __category));
extern char *textdomain__ PARAMS ((const char *__domainname));
extern char *bindtextdomain__ PARAMS ((const char *__domainname,
const char *__dirname));
extern char *bind_textdomain_codeset__ PARAMS ((const char *__domainname,
const char *__codeset));
#endif
#ifdef _LIBC
extern void __gettext_free_exp PARAMS ((struct expression *exp))
internal_function;
extern int __gettextparse PARAMS ((void *arg));
#else
extern void gettext_free_exp__ PARAMS ((struct expression *exp))
internal_function;
extern int gettextparse__ PARAMS ((void *arg));
#endif
/* @@ begin of epilog @@ */ /* @@ begin of epilog @@ */
#endif /* gettextP.h */ #endif /* gettextP.h */

View File

@ -1,5 +1,5 @@
/* Description of GNU message catalog format: string hashing function. /* Implements a string hashing function.
Copyright (C) 1995, 1997, 1998, 2000, 2001 Free Software Foundation, Inc. Copyright (C) 1995, 1997 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -11,9 +11,10 @@
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU Library General Public
along with this program; if not, write to the Free Software Foundation, License along with the GNU C Library; see the file COPYING.LIB. If not,
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
/* @@ end of prolog @@ */ /* @@ end of prolog @@ */

View File

@ -1,6 +1,6 @@
/* intl-compat.c - Stub functions to call gettext functions from GNU gettext /* intl-compat.c - Stub functions to call gettext functions from GNU gettext
Library. Library.
Copyright (C) 1995, 2000, 2001 Software Foundation, Inc. Copyright (C) 1995 Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -20,79 +20,24 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
# include <config.h> # include <config.h>
#endif #endif
#include "libgnuintl.h" #include "libgettext.h"
#include "gettextP.h"
/* @@ end of prolog @@ */ /* @@ end of prolog @@ */
/* This file redirects the gettext functions (without prefix or suffix) to
those defined in the included GNU gettext library (with "__" suffix).
It is compiled into libintl when the included GNU gettext library is
configured --with-included-gettext.
This redirection works also in the case that the system C library or
the system libintl library contain gettext/textdomain/... functions.
If it didn't, we would need to add preprocessor level redirections to
libgnuintl.h of the following form:
# define gettext gettext__
# define dgettext dgettext__
# define dcgettext dcgettext__
# define ngettext ngettext__
# define dngettext dngettext__
# define dcngettext dcngettext__
# define textdomain textdomain__
# define bindtextdomain bindtextdomain__
# define bind_textdomain_codeset bind_textdomain_codeset__
How does this redirection work? There are two cases.
A. When libintl.a is linked into an executable, it works because
functions defined in the executable always override functions in
the shared libraries.
B. When libintl.so is used, it works because
1. those systems defining gettext/textdomain/... in the C library
(namely, Solaris 2.4 and newer, and GNU libc 2.0 and newer) are
ELF systems and define these symbols as weak, thus explicitly
letting other shared libraries override it.
2. those systems defining gettext/textdomain/... in a standalone
libintl.so library (namely, Solaris 2.3 and newer) have this
shared library in /usr/lib, and the linker will search /usr/lib
*after* the directory where the GNU gettext library is installed.
A third case, namely when libintl.a is linked into a shared library
whose name is not libintl.so, is not supported. In this case, on
Solaris, when -lintl precedes the linker option for the shared library
containing GNU gettext, the system's gettext would indeed override
the GNU gettext. Anyone doing this kind of stuff must be clever enough
to 1. compile libintl.a with -fPIC, 2. remove -lintl from his linker
command line. */
#undef gettext #undef gettext
#undef dgettext #undef dgettext
#undef dcgettext #undef dcgettext
#undef ngettext
#undef dngettext
#undef dcngettext
#undef textdomain #undef textdomain
#undef bindtextdomain #undef bindtextdomain
#undef bind_textdomain_codeset
char * char *
gettext (msgid) bindtextdomain (domainname, dirname)
const char *msgid;
{
return gettext__ (msgid);
}
char *
dgettext (domainname, msgid)
const char *domainname; const char *domainname;
const char *msgid; const char *dirname;
{ {
return dgettext__ (domainname, msgid); return bindtextdomain__ (domainname, dirname);
} }
@ -107,35 +52,19 @@ dcgettext (domainname, msgid, category)
char * char *
ngettext (msgid1, msgid2, n) dgettext (domainname, msgid)
const char *msgid1; const char *domainname;
const char *msgid2; const char *msgid;
unsigned long int n;
{ {
return ngettext__ (msgid1, msgid2, n); return dgettext__ (domainname, msgid);
} }
char * char *
dngettext (domainname, msgid1, msgid2, n) gettext (msgid)
const char *domainname; const char *msgid;
const char *msgid1;
const char *msgid2;
unsigned long int n;
{ {
return dngettext__ (domainname, msgid1, msgid2, n); return gettext__ (msgid);
}
char *
dcngettext (domainname, msgid1, msgid2, n, category)
const char *domainname;
const char *msgid1;
const char *msgid2;
unsigned long int n;
int category;
{
return dcngettext__ (domainname, msgid1, msgid2, n, category);
} }
@ -145,21 +74,3 @@ textdomain (domainname)
{ {
return textdomain__ (domainname); return textdomain__ (domainname);
} }
char *
bindtextdomain (domainname, dirname)
const char *domainname;
const char *dirname;
{
return bindtextdomain__ (domainname, dirname);
}
char *
bind_textdomain_codeset (domainname, codeset)
const char *domainname;
const char *codeset;
{
return bind_textdomain_codeset__ (domainname, codeset);
}

View File

@ -1,4 +1,5 @@
/* Copyright (C) 1995-1999, 2000, 2001 Free Software Foundation, Inc. /* Handle list of needed message catalogs
Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995. Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
@ -15,18 +16,22 @@
along with this program; if not, write to the Free Software Foundation, along with this program; if not, write to the Free Software Foundation,
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
/* Tell glibc's <string.h> to provide a prototype for stpcpy().
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 #ifdef HAVE_CONFIG_H
# include <config.h> # include <config.h>
#endif #endif
#include <string.h>
#if defined HAVE_STRING_H || defined _LIBC
# ifndef _GNU_SOURCE
# define _GNU_SOURCE 1
# endif
# include <string.h>
#else
# include <strings.h>
# ifndef memcpy
# define memcpy(Dst, Src, Num) bcopy (Src, Dst, Num)
# endif
#endif
#if !HAVE_STRCHR && !defined _LIBC #if !HAVE_STRCHR && !defined _LIBC
# ifndef strchr # ifndef strchr
# define strchr index # define strchr index
@ -38,7 +43,10 @@
#endif #endif
#include <ctype.h> #include <ctype.h>
#include <sys/types.h> #include <sys/types.h>
#include <stdlib.h>
#if defined STDC_HEADERS || defined _LIBC
# include <stdlib.h>
#endif
#include "loadinfo.h" #include "loadinfo.h"
@ -163,7 +171,7 @@ pop (x)
struct loaded_l10nfile * struct loaded_l10nfile *
_nl_make_l10nflist (l10nfile_list, dirlist, dirlist_len, mask, language, _nl_make_l10nflist (l10nfile_list, dirlist, dirlist_len, mask, language,
territory, codeset, normalized_codeset, modifier, special, territory, codeset, normalized_codeset, modifier, special,
sponsor, revision, filename, domainbinding, do_allocate) sponsor, revision, filename, do_allocate)
struct loaded_l10nfile **l10nfile_list; struct loaded_l10nfile **l10nfile_list;
const char *dirlist; const char *dirlist;
size_t dirlist_len; size_t dirlist_len;
@ -177,7 +185,6 @@ _nl_make_l10nflist (l10nfile_list, dirlist, dirlist_len, mask, language,
const char *sponsor; const char *sponsor;
const char *revision; const char *revision;
const char *filename; const char *filename;
struct binding *domainbinding;
int do_allocate; int do_allocate;
{ {
char *abs_filename; char *abs_filename;
@ -217,7 +224,7 @@ _nl_make_l10nflist (l10nfile_list, dirlist, dirlist_len, mask, language,
/* Construct file name. */ /* Construct file name. */
memcpy (abs_filename, dirlist, dirlist_len); memcpy (abs_filename, dirlist, dirlist_len);
__argz_stringify (abs_filename, dirlist_len, PATH_SEPARATOR); __argz_stringify (abs_filename, dirlist_len, ':');
cp = abs_filename + (dirlist_len - 1); cp = abs_filename + (dirlist_len - 1);
*cp++ = '/'; *cp++ = '/';
cp = stpcpy (cp, language); cp = stpcpy (cp, language);
@ -298,7 +305,6 @@ _nl_make_l10nflist (l10nfile_list, dirlist, dirlist_len, mask, language,
return NULL; return NULL;
retval->filename = abs_filename; retval->filename = abs_filename;
retval->domainbinding = domainbinding;
retval->decided = (__argz_count (dirlist, dirlist_len) != 1 retval->decided = (__argz_count (dirlist, dirlist_len) != 1
|| ((mask & XPG_CODESET) != 0 || ((mask & XPG_CODESET) != 0
&& (mask & XPG_NORM_CODESET) != 0)); && (mask & XPG_NORM_CODESET) != 0));
@ -334,8 +340,7 @@ _nl_make_l10nflist (l10nfile_list, dirlist, dirlist_len, mask, language,
= _nl_make_l10nflist (l10nfile_list, dir, strlen (dir) + 1, cnt, = _nl_make_l10nflist (l10nfile_list, dir, strlen (dir) + 1, cnt,
language, territory, codeset, language, territory, codeset,
normalized_codeset, modifier, special, normalized_codeset, modifier, special,
sponsor, revision, filename, domainbinding, sponsor, revision, filename, 1);
1);
} }
retval->successor[entries] = NULL; retval->successor[entries] = NULL;
@ -344,8 +349,7 @@ _nl_make_l10nflist (l10nfile_list, dirlist, dirlist_len, mask, language,
/* Normalize codeset name. There is no standard for the codeset /* Normalize codeset name. There is no standard for the codeset
names. Normalization allows the user to use any of the common names. Normalization allows the user to use any of the common
names. The return value is dynamically allocated and has to be names. */
freed by the caller. */
const char * const char *
_nl_normalize_codeset (codeset, name_len) _nl_normalize_codeset (codeset, name_len)
const char *codeset; const char *codeset;

View File

@ -1,5 +1,5 @@
/* Convenience header for conditional use of GNU <libintl.h>. /* Message catalogs for internationalization.
Copyright (C) 1995-1998, 2000, 2001 Free Software Foundation, Inc. Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -15,34 +15,168 @@
along with this program; if not, write to the Free Software Foundation, along with this program; if not, write to the Free Software Foundation,
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#ifndef _LIBGETTEXT_H /* Because on some systems (e.g. Solaris) we sometimes have to include
the systems libintl.h as well as this file we have more complex
include protection above. But the systems header might perhaps also
define _LIBINTL_H and therefore we have to protect the definition here. */
#if !defined _LIBINTL_H || !defined _LIBGETTEXT_H
#ifndef _LIBINTL_H
# define _LIBINTL_H 1
#endif
#define _LIBGETTEXT_H 1 #define _LIBGETTEXT_H 1
/* NLS can be disabled through the configure --disable-nls option. */ /* We define an additional symbol to signal that we use the GNU
implementation of gettext. */
#define __USE_GNU_GETTEXT 1
#include <sys/types.h>
#if HAVE_LOCALE_H
# include <locale.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif
/* @@ end of prolog @@ */
#ifndef PARAMS
# if __STDC__ || defined __cplusplus
# define PARAMS(args) args
# else
# define PARAMS(args) ()
# endif
#endif
#ifndef NULL
# if !defined __cplusplus || defined __GNUC__
# define NULL ((void *) 0)
# else
# define NULL (0)
# endif
#endif
#if !HAVE_LC_MESSAGES
/* This value determines the behaviour of the gettext() and dgettext()
function. But some system does not have this defined. Define it
to a default value. */
# define LC_MESSAGES (-1)
#endif
/* Declarations for gettext-using-catgets interface. Derived from
Jim Meyering's libintl.h. */
struct _msg_ent
{
const char *_msg;
int _msg_number;
};
#if HAVE_CATGETS
/* These two variables are defined in the automatically by po-to-tbl.sed
generated file `cat-id-tbl.c'. */
extern const struct _msg_ent _msg_tbl[];
extern int _msg_tbl_length;
#endif
/* For automatical extraction of messages sometimes no real
translation is needed. Instead the string itself is the result. */
#define gettext_noop(Str) (Str)
/* Look up MSGID in the current default message catalog for the current
LC_MESSAGES locale. If not found, returns MSGID itself (the default
text). */
extern char *gettext PARAMS ((const char *__msgid));
extern char *gettext__ PARAMS ((const char *__msgid));
/* Look up MSGID in the DOMAINNAME message catalog for the current
LC_MESSAGES locale. */
extern char *dgettext PARAMS ((const char *__domainname, const char *__msgid));
extern char *dgettext__ PARAMS ((const char *__domainname,
const char *__msgid));
/* Look up MSGID in the DOMAINNAME message catalog for the current CATEGORY
locale. */
extern char *dcgettext PARAMS ((const char *__domainname, const char *__msgid,
int __category));
extern char *dcgettext__ PARAMS ((const char *__domainname,
const char *__msgid, int __category));
/* 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". */
extern char *textdomain PARAMS ((const char *__domainname));
extern char *textdomain__ PARAMS ((const char *__domainname));
/* Specify that the DOMAINNAME message catalog will be found
in DIRNAME rather than in the system locale data base. */
extern char *bindtextdomain PARAMS ((const char *__domainname,
const char *__dirname));
extern char *bindtextdomain__ PARAMS ((const char *__domainname,
const char *__dirname));
#if ENABLE_NLS #if ENABLE_NLS
/* Get declarations of GNU message catalog functions. */ /* Solaris 2.3 has the gettext function but dcgettext is missing.
# include <libintl.h> So we omit this optimization for Solaris 2.3. BTW, Solaris 2.4
has dcgettext. */
# if !HAVE_CATGETS && (!HAVE_GETTEXT || HAVE_DCGETTEXT)
# define gettext(Msgid) \
dgettext (NULL, Msgid)
# define dgettext(Domainname, Msgid) \
dcgettext (Domainname, Msgid, LC_MESSAGES)
# if defined __GNUC__ && __GNUC__ == 2 && __GNUC_MINOR__ >= 7
/* This global variable is defined in loadmsgcat.c. We need a sign,
whether a new catalog was loaded, which can be associated with all
translations. */
extern int _nl_msg_cat_cntr;
# define dcgettext(Domainname, Msgid, Category) \
(__extension__ \
({ \
char *__result; \
if (__builtin_constant_p (Msgid)) \
{ \
static char *__translation__; \
static int __catalog_counter__; \
if (! __translation__ || __catalog_counter__ != _nl_msg_cat_cntr) \
{ \
__translation__ = \
dcgettext__ (Domainname, Msgid, Category); \
__catalog_counter__ = _nl_msg_cat_cntr; \
} \
__result = __translation__; \
} \
else \
__result = dcgettext__ (Domainname, Msgid, Category); \
__result; \
}))
# endif
# endif
#else #else
# define gettext(Msgid) (Msgid) # define gettext(Msgid) (Msgid)
# define dgettext(Domainname, Msgid) (Msgid) # define dgettext(Domainname, Msgid) (Msgid)
# define dcgettext(Domainname, Msgid, Category) (Msgid) # define dcgettext(Domainname, Msgid, Category) (Msgid)
# define ngettext(Msgid1, Msgid2, N) \ # define textdomain(Domainname) ((char *) Domainname)
((N) == 1 ? (char *) (Msgid1) : (char *) (Msgid2)) # define bindtextdomain(Domainname, Dirname) ((char *) Dirname)
# define dngettext(Domainname, Msgid1, Msgid2, N) \
((N) == 1 ? (char *) (Msgid1) : (char *) (Msgid2))
# define dcngettext(Domainname, Msgid1, Msgid2, N, Category) \
((N) == 1 ? (char *) (Msgid1) : (char *) (Msgid2))
# define textdomain(Domainname) ((char *) (Domainname))
# define bindtextdomain(Domainname, Dirname) ((char *) (Dirname))
# define bind_textdomain_codeset(Domainname, Codeset) ((char *) (Codeset))
#endif #endif
/* For automatical extraction of messages sometimes no real /* @@ begin of epilog @@ */
translation is needed. Instead the string itself is the result. */
#define gettext_noop(Str) (Str)
#endif /* _LIBGETTEXT_H */ #ifdef __cplusplus
}
#endif
#endif

View File

@ -1,4 +1,4 @@
/* Copyright (C) 1996-1999, 2000, 2001 Free Software Foundation, Inc. /* Copyright (C) 1996, 1997 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
@ -16,9 +16,6 @@
along with this program; if not, write to the Free Software Foundation, along with this program; if not, write to the Free Software Foundation,
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#ifndef _LOADINFO_H
#define _LOADINFO_H 1
#ifndef PARAMS #ifndef PARAMS
# if __STDC__ # if __STDC__
# define PARAMS(args) args # define PARAMS(args) args
@ -27,25 +24,6 @@
# endif # endif
#endif #endif
#ifndef internal_function
# define internal_function
#endif
/* Tell the compiler when a conditional or integer expression is
almost always true or almost always false. */
#ifndef HAVE_BUILTIN_EXPECT
# define __builtin_expect(expr, val) (expr)
#endif
/* Separator in PATH like lists of pathnames. */
#if defined _WIN32 || defined __WIN32__ || defined __EMX__ || defined __DJGPP__
/* Win32, OS/2, DOS */
# define PATH_SEPARATOR ';'
#else
/* Unix */
# define PATH_SEPARATOR ':'
#endif
/* Encoding of locale name parts. */ /* Encoding of locale name parts. */
#define CEN_REVISION 1 #define CEN_REVISION 1
#define CEN_SPONSOR 2 #define CEN_SPONSOR 2
@ -63,7 +41,6 @@
struct loaded_l10nfile struct loaded_l10nfile
{ {
const char *filename; const char *filename;
struct binding *domainbinding;
int decided; int decided;
const void *data; const void *data;
@ -73,10 +50,6 @@ struct loaded_l10nfile
}; };
/* Normalize codeset name. There is no standard for the codeset
names. Normalization allows the user to use any of the common
names. The return value is dynamically allocated and has to be
freed by the caller. */
extern const char *_nl_normalize_codeset PARAMS ((const char *codeset, extern const char *_nl_normalize_codeset PARAMS ((const char *codeset,
size_t name_len)); size_t name_len));
@ -88,14 +61,11 @@ _nl_make_l10nflist PARAMS ((struct loaded_l10nfile **l10nfile_list,
const char *normalized_codeset, const char *normalized_codeset,
const char *modifier, const char *special, const char *modifier, const char *special,
const char *sponsor, const char *revision, const char *sponsor, const char *revision,
const char *filename, const char *filename, int do_allocate));
struct binding *domainbinding, int do_allocate));
extern const char *_nl_expand_alias PARAMS ((const char *name)); extern const char *_nl_expand_alias PARAMS ((const char *name));
/* normalized_codeset is dynamically allocated and has to be freed by
the caller. */
extern int _nl_explode_name PARAMS ((char *name, const char **language, extern int _nl_explode_name PARAMS ((char *name, const char **language,
const char **modifier, const char **modifier,
const char **territory, const char **territory,
@ -106,10 +76,3 @@ extern int _nl_explode_name PARAMS ((char *name, const char **language,
const char **revision)); const char **revision));
extern char *_nl_find_language PARAMS ((const char *name)); extern char *_nl_find_language PARAMS ((const char *name));
extern char *_nl_find_msg PARAMS ((struct loaded_l10nfile *domain_file,
const char *msgid, size_t *lengthp))
internal_function;
#endif /* loadinfo.h */

View File

@ -1,5 +1,5 @@
/* Load needed message catalogs. /* Load needed message catalogs.
Copyright (C) 1995-1999, 2000, 2001 Free Software Foundation, Inc. Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -15,52 +15,22 @@
along with this program; if not, write to the Free Software Foundation, along with this program; if not, write to the Free Software Foundation,
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
/* Tell glibc's <string.h> to provide a prototype for mempcpy().
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 #ifdef HAVE_CONFIG_H
# include <config.h> # include <config.h>
#endif #endif
#include <ctype.h>
#include <errno.h>
#include <fcntl.h> #include <fcntl.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
#ifdef __GNUC__ #if defined STDC_HEADERS || defined _LIBC
# define alloca __builtin_alloca # include <stdlib.h>
# 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 #endif
#include <stdlib.h>
#include <string.h>
#if defined HAVE_UNISTD_H || defined _LIBC #if defined HAVE_UNISTD_H || defined _LIBC
# include <unistd.h> # include <unistd.h>
#endif #endif
#ifdef _LIBC
# include <langinfo.h>
# include <locale.h>
#endif
#if (defined HAVE_MMAP && defined HAVE_MUNMAP && !defined DISALLOW_MMAP) \ #if (defined HAVE_MMAP && defined HAVE_MUNMAP && !defined DISALLOW_MMAP) \
|| (defined _LIBC && defined _POSIX_MAPPED_FILES) || (defined _LIBC && defined _POSIX_MAPPED_FILES)
# include <sys/mman.h> # include <sys/mman.h>
@ -73,10 +43,6 @@ char *alloca ();
#include "gettext.h" #include "gettext.h"
#include "gettextP.h" #include "gettextP.h"
#ifdef _LIBC
# include "../locale/localeinfo.h"
#endif
/* @@ end of prolog @@ */ /* @@ end of prolog @@ */
#ifdef _LIBC #ifdef _LIBC
@ -90,113 +56,10 @@ char *alloca ();
# define munmap __munmap # define munmap __munmap
#endif #endif
/* 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 PLURAL_PARSE __gettextparse
#else
# define PLURAL_PARSE gettextparse__
#endif
/* For those losing systems which don't have `alloca' we have to add
some additional code emulating it. */
#ifdef HAVE_ALLOCA
# define freea(p) /* nothing */
#else
# define alloca(n) malloc (n)
# define freea(p) free (p)
#endif
/* For systems that distinguish between text and binary I/O.
O_BINARY is usually declared in <fcntl.h>. */
#if !defined O_BINARY && defined _O_BINARY
/* For MSC-compatible compilers. */
# define O_BINARY _O_BINARY
# define O_TEXT _O_TEXT
#endif
#ifdef __BEOS__
/* BeOS 5 has O_BINARY and O_TEXT, but they have no effect. */
# undef O_BINARY
# undef O_TEXT
#endif
/* On reasonable systems, binary I/O is the default. */
#ifndef O_BINARY
# define O_BINARY 0
#endif
/* We need a sign, whether a new catalog was loaded, which can be associated /* We need a sign, whether a new catalog was loaded, which can be associated
with all translations. This is important if the translations are with all translations. This is important if the translations are
cached by one of GCC's features. */ cached by one of GCC's features. */
int _nl_msg_cat_cntr; int _nl_msg_cat_cntr = 0;
#if defined __GNUC__ \
|| (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
}
};
static 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;
static 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
/* Load the message catalogs specified by FILENAME. If it is no valid /* Load the message catalogs specified by FILENAME. If it is no valid
@ -208,16 +71,10 @@ _nl_load_domain (domain_file)
{ {
int fd; int fd;
size_t size; size_t size;
#ifdef _LIBC
struct stat64 st;
#else
struct stat st; struct stat st;
#endif
struct mo_file_header *data = (struct mo_file_header *) -1; struct mo_file_header *data = (struct mo_file_header *) -1;
int use_mmap = 0; int use_mmap = 0;
struct loaded_domain *domain; struct loaded_domain *domain;
char *nullentry;
size_t nullentrylen;
domain_file->decided = 1; domain_file->decided = 1;
domain_file->data = NULL; domain_file->data = NULL;
@ -230,19 +87,14 @@ _nl_load_domain (domain_file)
return; return;
/* Try to open the addressed file. */ /* Try to open the addressed file. */
fd = open (domain_file->filename, O_RDONLY | O_BINARY); fd = open (domain_file->filename, O_RDONLY);
if (fd == -1) if (fd == -1)
return; return;
/* We must know about the size of the file. */ /* We must know about the size of the file. */
if ( if (fstat (fd, &st) != 0
#ifdef _LIBC || (size = (size_t) st.st_size) != st.st_size
__builtin_expect (fstat64 (fd, &st) != 0, 0) || size < sizeof (struct mo_file_header))
#else
__builtin_expect (fstat (fd, &st) != 0, 0)
#endif
|| __builtin_expect ((size = (size_t) st.st_size) != st.st_size, 0)
|| __builtin_expect (size < sizeof (struct mo_file_header), 0))
{ {
/* Something went wrong. */ /* Something went wrong. */
close (fd); close (fd);
@ -255,7 +107,7 @@ _nl_load_domain (domain_file)
data = (struct mo_file_header *) mmap (NULL, size, PROT_READ, data = (struct mo_file_header *) mmap (NULL, size, PROT_READ,
MAP_PRIVATE, fd, 0); MAP_PRIVATE, fd, 0);
if (__builtin_expect (data != (struct mo_file_header *) -1, 1)) if (data != (struct mo_file_header *) -1)
{ {
/* mmap() call was successful. */ /* mmap() call was successful. */
close (fd); close (fd);
@ -279,15 +131,12 @@ _nl_load_domain (domain_file)
do do
{ {
long int nb = (long int) read (fd, read_ptr, to_read); long int nb = (long int) read (fd, read_ptr, to_read);
if (nb <= 0) if (nb == -1)
{ {
#ifdef EINTR
if (nb == -1 && errno == EINTR)
continue;
#endif
close (fd); close (fd);
return; return;
} }
read_ptr += nb; read_ptr += nb;
to_read -= nb; to_read -= nb;
} }
@ -298,8 +147,7 @@ _nl_load_domain (domain_file)
/* Using the magic number we can test whether it really is a message /* Using the magic number we can test whether it really is a message
catalog file. */ catalog file. */
if (__builtin_expect (data->magic != _MAGIC && data->magic != _MAGIC_SWAPPED, if (data->magic != _MAGIC && data->magic != _MAGIC_SWAPPED)
0))
{ {
/* The magic number is wrong: not a message catalog file. */ /* The magic number is wrong: not a message catalog file. */
#ifdef HAVE_MMAP #ifdef HAVE_MMAP
@ -311,11 +159,12 @@ _nl_load_domain (domain_file)
return; return;
} }
domain = (struct loaded_domain *) malloc (sizeof (struct loaded_domain)); domain_file->data
if (domain == NULL) = (struct loaded_domain *) malloc (sizeof (struct loaded_domain));
if (domain_file->data == NULL)
return; return;
domain_file->data = domain;
domain = (struct loaded_domain *) domain_file->data;
domain->data = (char *) data; domain->data = (char *) data;
domain->use_mmap = use_mmap; domain->use_mmap = use_mmap;
domain->mmap_size = size; domain->mmap_size = size;
@ -347,137 +196,9 @@ _nl_load_domain (domain_file)
return; return;
} }
/* Now find out about the character set the file is encoded with. /* Show that one domain is changed. This might make some cached
This can be found (in textual form) in the entry "". If this translations invalid. */
entry does not exist or if this does not contain the `charset=' ++_nl_msg_cat_cntr;
information, we will assume the charset matches the one the
current locale and we don't have to perform any conversion. */
#ifdef _LIBC
domain->conv = (__gconv_t) -1;
#else
# if HAVE_ICONV
domain->conv = (iconv_t) -1;
# endif
#endif
domain->conv_tab = NULL;
nullentry = _nl_find_msg (domain_file, "", &nullentrylen);
if (nullentry != NULL)
{
#if defined _LIBC || HAVE_ICONV
const char *charsetstr;
charsetstr = strstr (nullentry, "charset=");
if (charsetstr != NULL)
{
size_t len;
char *charset;
const char *outcharset;
charsetstr += strlen ("charset=");
len = strcspn (charsetstr, " \t\n");
charset = (char *) alloca (len + 1);
# if defined _LIBC || HAVE_MEMPCPY
*((char *) mempcpy (charset, charsetstr, len)) = '\0';
# else
memcpy (charset, charsetstr, len);
charset[len] = '\0';
# endif
/* The output charset should normally be determined by the
locale. But sometimes the locale is not used or not correctly
set up, so we provide a possibility for the user to override
this. Moreover, the value specified through
bind_textdomain_codeset overrides both. */
if (domain_file->domainbinding != NULL
&& domain_file->domainbinding->codeset != NULL)
outcharset = domain_file->domainbinding->codeset;
else
{
outcharset = getenv ("OUTPUT_CHARSET");
if (outcharset == NULL || outcharset[0] == '\0')
{
# ifdef _LIBC
outcharset = (*_nl_current[LC_CTYPE])->values[_NL_ITEM_INDEX (CODESET)].string;
# else
# if HAVE_ICONV
extern const char *locale_charset (void);
outcharset = locale_charset ();
# endif
# endif
}
}
# ifdef _LIBC
/* We always want to use transliteration. */
outcharset = norm_add_slashes (outcharset, "TRANSLIT");
charset = norm_add_slashes (charset, NULL);
if (__gconv_open (outcharset, charset, &domain->conv,
GCONV_AVOID_NOCONV)
!= __GCONV_OK)
domain->conv = (__gconv_t) -1;
# else
# if HAVE_ICONV
domain->conv = iconv_open (outcharset, charset);
# endif
# endif
freea (charset);
}
#endif /* _LIBC || HAVE_ICONV */
}
/* Also look for a plural specification. */
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
{
/* First get the number. */
char *endp;
unsigned long int n;
struct parse_args args;
nplurals += 9;
while (*nplurals != '\0' && isspace (*nplurals))
++nplurals;
#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
domain->nplurals = n;
if (nplurals == endp)
goto no_plural;
/* 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;
domain->plural = 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 ();
domain->plural = &germanic_plural;
domain->nplurals = 2;
}
} }
@ -487,20 +208,11 @@ internal_function
_nl_unload_domain (domain) _nl_unload_domain (domain)
struct loaded_domain *domain; struct loaded_domain *domain;
{ {
if (domain->plural != &germanic_plural) #ifdef _POSIX_MAPPED_FILES
__gettext_free_exp (domain->plural);
if (domain->conv_tab != NULL && domain->conv_tab != (char **) -1)
free (domain->conv_tab);
if (domain->conv != (__gconv_t) -1)
__gconv_close (domain->conv);
# ifdef _POSIX_MAPPED_FILES
if (domain->use_mmap) if (domain->use_mmap)
munmap ((caddr_t) domain->data, domain->mmap_size); munmap ((caddr_t) domain->data, domain->mmap_size);
else else
# endif /* _POSIX_MAPPED_FILES */ #endif /* _POSIX_MAPPED_FILES */
free ((void *) domain->data); free ((void *) domain->data);
free (domain); free (domain);

View File

@ -1,5 +1,6 @@
/* Handle aliases for locale names. /* Handle aliases for locale names.
Copyright (C) 1995-1999, 2000, 2001 Free Software Foundation, Inc. Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -15,13 +16,6 @@
along with this program; if not, write to the Free Software Foundation, along with this program; if not, write to the Free Software Foundation,
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
/* Tell glibc's <string.h> to provide a prototype for mempcpy().
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 #ifdef HAVE_CONFIG_H
# include <config.h> # include <config.h>
#endif #endif
@ -47,15 +41,35 @@ char *alloca ();
# endif # endif
#endif #endif
#include <stdlib.h> #if defined STDC_HEADERS || defined _LIBC
# include <stdlib.h>
#else
char *getenv ();
# ifdef HAVE_MALLOC_H
# include <malloc.h>
# else
void free ();
# endif
#endif
#include <string.h> #if defined HAVE_STRING_H || defined _LIBC
# ifndef _GNU_SOURCE
# define _GNU_SOURCE 1
# endif
# include <string.h>
#else
# include <strings.h>
# ifndef memcpy
# define memcpy(Dst, Src, Num) bcopy (Src, Dst, Num)
# endif
#endif
#if !HAVE_STRCHR && !defined _LIBC #if !HAVE_STRCHR && !defined _LIBC
# ifndef strchr # ifndef strchr
# define strchr index # define strchr index
# endif # endif
#endif #endif
#include "gettext.h"
#include "gettextP.h" #include "gettextP.h"
/* @@ end of prolog @@ */ /* @@ end of prolog @@ */
@ -81,14 +95,40 @@ __libc_lock_define_initialized (static, lock);
# define internal_function # define internal_function
#endif #endif
/* For those losing systems which don't have `alloca' we have to add /* For those loosing systems which don't have `alloca' we have to add
some additional code emulating it. */ some additional code emulating it. */
#ifdef HAVE_ALLOCA #ifdef HAVE_ALLOCA
# define freea(p) /* nothing */ /* Nothing has to be done. */
# define ADD_BLOCK(list, address) /* nothing */
# define FREE_BLOCKS(list) /* nothing */
#else #else
# define alloca(n) malloc (n) struct block_list
# define freea(p) free (p) {
#endif 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 */
#if defined _LIBC_REENTRANT || defined HAVE_FGETS_UNLOCKED #if defined _LIBC_REENTRANT || defined HAVE_FGETS_UNLOCKED
# undef fgets # undef fgets
@ -107,18 +147,18 @@ struct alias_map
}; };
static char *string_space; static char *string_space = NULL;
static size_t string_space_act; static size_t string_space_act = 0;
static size_t string_space_max; static size_t string_space_max = 0;
static struct alias_map *map; static struct alias_map *map;
static size_t nmap; static size_t nmap = 0;
static size_t maxmap; static size_t maxmap = 0;
/* Prototypes for local functions. */ /* Prototypes for local functions. */
static size_t read_alias_file PARAMS ((const char *fname, int fname_len)) static size_t read_alias_file PARAMS ((const char *fname, int fname_len))
internal_function; internal_function;
static int extend_alias_table PARAMS ((void)); static void extend_alias_table PARAMS ((void));
static int alias_compare PARAMS ((const struct alias_map *map1, static int alias_compare PARAMS ((const struct alias_map *map1,
const struct alias_map *map2)); const struct alias_map *map2));
@ -164,12 +204,11 @@ _nl_expand_alias (name)
{ {
const char *start; const char *start;
while (locale_alias_path[0] == PATH_SEPARATOR) while (locale_alias_path[0] == ':')
++locale_alias_path; ++locale_alias_path;
start = locale_alias_path; start = locale_alias_path;
while (locale_alias_path[0] != '\0' while (locale_alias_path[0] != '\0' && locale_alias_path[0] != ':')
&& locale_alias_path[0] != PATH_SEPARATOR)
++locale_alias_path; ++locale_alias_path;
if (start < locale_alias_path) if (start < locale_alias_path)
@ -192,12 +231,16 @@ read_alias_file (fname, fname_len)
const char *fname; const char *fname;
int fname_len; int fname_len;
{ {
#ifndef HAVE_ALLOCA
struct block_list *block_list = NULL;
#endif
FILE *fp; FILE *fp;
char *full_fname; char *full_fname;
size_t added; size_t added;
static const char aliasfile[] = "/locale.alias"; static const char aliasfile[] = "/locale.alias";
full_fname = (char *) alloca (fname_len + sizeof aliasfile); full_fname = (char *) alloca (fname_len + sizeof aliasfile);
ADD_BLOCK (block_list, full_fname);
#ifdef HAVE_MEMPCPY #ifdef HAVE_MEMPCPY
mempcpy (mempcpy (full_fname, fname, fname_len), mempcpy (mempcpy (full_fname, fname, fname_len),
aliasfile, sizeof aliasfile); aliasfile, sizeof aliasfile);
@ -207,9 +250,11 @@ read_alias_file (fname, fname_len)
#endif #endif
fp = fopen (full_fname, "r"); fp = fopen (full_fname, "r");
freea (full_fname);
if (fp == NULL) if (fp == NULL)
{
FREE_BLOCKS (block_list);
return 0; return 0;
}
added = 0; added = 0;
while (!feof (fp)) while (!feof (fp))
@ -281,8 +326,7 @@ read_alias_file (fname, fname_len)
*cp++ = '\0'; *cp++ = '\0';
if (nmap >= maxmap) if (nmap >= maxmap)
if (__builtin_expect (extend_alias_table (), 0)) extend_alias_table ();
return added;
alias_len = strlen (alias) + 1; alias_len = strlen (alias) + 1;
value_len = strlen (value) + 1; value_len = strlen (value) + 1;
@ -295,19 +339,10 @@ read_alias_file (fname, fname_len)
? alias_len + value_len : 1024)); ? alias_len + value_len : 1024));
char *new_pool = (char *) realloc (string_space, new_size); char *new_pool = (char *) realloc (string_space, new_size);
if (new_pool == NULL) if (new_pool == NULL)
{
FREE_BLOCKS (block_list);
return added; return added;
if (__builtin_expect (string_space != new_pool, 0))
{
size_t i;
for (i = 0; i < nmap; i++)
{
map[i].alias += new_pool - string_space;
map[i].value += new_pool - string_space;
} }
}
string_space = new_pool; string_space = new_pool;
string_space_max = new_size; string_space_max = new_size;
} }
@ -334,11 +369,12 @@ read_alias_file (fname, fname_len)
qsort (map, nmap, sizeof (struct alias_map), qsort (map, nmap, sizeof (struct alias_map),
(int (*) PARAMS ((const void *, const void *))) alias_compare); (int (*) PARAMS ((const void *, const void *))) alias_compare);
FREE_BLOCKS (block_list);
return added; return added;
} }
static int static void
extend_alias_table () extend_alias_table ()
{ {
size_t new_size; size_t new_size;
@ -349,11 +385,10 @@ extend_alias_table ()
* sizeof (struct alias_map))); * sizeof (struct alias_map)));
if (new_map == NULL) if (new_map == NULL)
/* Simply don't extend: we don't have any more core. */ /* Simply don't extend: we don't have any more core. */
return -1; return;
map = new_map; map = new_map;
maxmap = new_size; maxmap = new_size;
return 0;
} }

View File

@ -1,5 +1,6 @@
/* Implementation of the textdomain(3) function. /* Implementation of the textdomain(3) function.
Copyright (C) 1995-1998, 2000, 2001 Free Software Foundation, Inc. Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -19,32 +20,23 @@
# include <config.h> # include <config.h>
#endif #endif
#include <stdlib.h> #if defined STDC_HEADERS || defined _LIBC
#include <string.h> # include <stdlib.h>
#endif
#if defined STDC_HEADERS || defined HAVE_STRING_H || defined _LIBC
# include <string.h>
#else
# include <strings.h>
# ifndef memcpy
# define memcpy(Dst, Src, Num) bcopy (Src, Dst, Num)
# endif
#endif
#ifdef _LIBC #ifdef _LIBC
# include <libintl.h> # include <libintl.h>
#else #else
# include "libgnuintl.h" # include "libgettext.h"
#endif
#include "gettextP.h"
#ifdef _LIBC
/* We have to handle multi-threaded applications. */
# include <bits/libc-lock.h>
#else
/* Provide dummy implementation if this is outside glibc. */
# define __libc_rwlock_define(CLASS, NAME)
# define __libc_rwlock_wrlock(NAME)
# define __libc_rwlock_unlock(NAME)
#endif
/* The internal variables in the standalone libintl.a must have different
names than the internal variables in GNU libc, otherwise programs
using libintl.a cannot be linked statically. */
#if !defined _LIBC
# define _nl_default_default_domain _nl_default_default_domain__
# define _nl_current_default_domain _nl_current_default_domain__
#endif #endif
/* @@ end of prolog @@ */ /* @@ end of prolog @@ */
@ -69,9 +61,6 @@ extern const char *_nl_current_default_domain;
# define TEXTDOMAIN textdomain__ # define TEXTDOMAIN textdomain__
#endif #endif
/* Lock variable to protect the global data in the gettext implementation. */
__libc_rwlock_define (extern, _nl_state_lock)
/* Set the current default message catalog to DOMAINNAME. /* Set the current default message catalog to DOMAINNAME.
If DOMAINNAME is null, return the current default. If DOMAINNAME is null, return the current default.
If DOMAINNAME is "", reset to the default of "messages". */ If DOMAINNAME is "", reset to the default of "messages". */
@ -79,60 +68,38 @@ char *
TEXTDOMAIN (domainname) TEXTDOMAIN (domainname)
const char *domainname; const char *domainname;
{ {
char *new_domain; char *old;
char *old_domain;
/* A NULL pointer requests the current setting. */ /* A NULL pointer requests the current setting. */
if (domainname == NULL) if (domainname == NULL)
return (char *) _nl_current_default_domain; return (char *) _nl_current_default_domain;
__libc_rwlock_wrlock (_nl_state_lock); old = (char *) _nl_current_default_domain;
old_domain = (char *) _nl_current_default_domain;
/* If domain name is the null string set to default domain "messages". */ /* If domain name is the null string set to default domain "messages". */
if (domainname[0] == '\0' if (domainname[0] == '\0'
|| strcmp (domainname, _nl_default_default_domain) == 0) || strcmp (domainname, _nl_default_default_domain) == 0)
{
_nl_current_default_domain = _nl_default_default_domain; _nl_current_default_domain = _nl_default_default_domain;
new_domain = (char *) _nl_current_default_domain;
}
else if (strcmp (domainname, old_domain) == 0)
/* This can happen and people will use it to signal that some
environment variable changed. */
new_domain = old_domain;
else else
{ {
/* If the following malloc fails `_nl_current_default_domain' /* If the following malloc fails `_nl_current_default_domain'
will be NULL. This value will be returned and so signals we will be NULL. This value will be returned and so signals we
are out of core. */ are out of core. */
#if defined _LIBC || defined HAVE_STRDUP #if defined _LIBC || defined HAVE_STRDUP
new_domain = strdup (domainname); _nl_current_default_domain = strdup (domainname);
#else #else
size_t len = strlen (domainname) + 1; size_t len = strlen (domainname) + 1;
new_domain = (char *) malloc (len); char *cp = (char *) malloc (len);
if (new_domain != NULL) if (cp != NULL)
memcpy (new_domain, domainname, len); memcpy (cp, domainname, len);
_nl_current_default_domain = cp;
#endif #endif
if (new_domain != NULL)
_nl_current_default_domain = new_domain;
} }
/* We use this possibility to signal a change of the loaded catalogs if (old != _nl_default_default_domain)
since this is most likely the case and there is no other easy we free (old);
to do it. Do it only when the call was successful. */
if (new_domain != NULL)
{
++_nl_msg_cat_cntr;
if (old_domain != new_domain && old_domain != _nl_default_default_domain) return (char *) _nl_current_default_domain;
free (old_domain);
}
__libc_rwlock_unlock (_nl_state_lock);
return new_domain;
} }
#ifdef _LIBC #ifdef _LIBC