mirror of
git://git.gnupg.org/gnupg.git
synced 2025-07-02 22:46:30 +02:00
gettext: Upgrade to version 0.18
* configure.ac (AM_GNU_GETTEXT_VERSION): Bump to 0.18. * po/Makefile.in.in: Upgrade to gettext-0.18. Keep option --previous of msgmerge. * intl/: Upgrade to gettext-0.18. * m4/gettext.m4: Upgrade to gettext-0.18.1. * m4/iconv.m4: Upgrade to gettext-0.18.1. * m4/lib-ld.m4: Upgrade to gettext-0.18.1. * m4/lib-link.m4: Upgrade to gettext-0.18.1. * m4/lib-prefix.m4: Upgrade to gettext-0.18.1. * m4/nls.m4: Upgrade to gettext-0.18.1. * m4/po.m4: Upgrade to gettext-0.18.1. * m4/progtest.m4: Upgrade to gettext-0.18.1. * m4/codeset.m4: Upgrade to gettext-0.18.1. * m4/fcntl-o.m4: New file, from gettext-0.18.1. * m4/glibc2.m4: Upgrade to gettext-0.18.1. * m4/glibc21.m4: Upgrade to gettext-0.18.1. * m4/intdiv0.m4: Upgrade to gettext-0.18.1. * m4/intl.m4: Upgrade to gettext-0.18.1. * m4/intldir.m4: Upgrade to gettext-0.18.1. * m4/intlmacosx.m4: Upgrade to gettext-0.18.1. * m4/intmax.m4: Upgrade to gettext-0.18.1. * m4/inttypes_h.m4: Upgrade to gettext-0.18.1. * m4/inttypes-pri.m4: Upgrade to gettext-0.18.1. * m4/lcmessage.m4: Upgrade to gettext-0.18.1. * m4/lock.m4: Upgrade to gettext-0.18.1. * m4/longlong.m4: Upgrade to gettext-0.18.1. * m4/printf-posix.m4: Upgrade to gettext-0.18.1. * m4/size_max.m4: Upgrade to gettext-0.18.1. * m4/stdint_h.m4: Upgrade to gettext-0.18.1. * m4/threadlib.m4: New file, from gettext-0.18.1. * m4/uintmax_t.m4: Upgrade to gettext-0.18.1. * m4/visibility.m4: Upgrade to gettext-0.18.1. * m4/wchar_t.m4: Upgrade to gettext-0.18.1. * m4/wint_t.m4: Upgrade to gettext-0.18.1. * m4/xsize.m4: Upgrade to gettext-0.18.1. * m4/Makefile.am (EXTRA_DIST): Add the new files.
This commit is contained in:
parent
0fee571260
commit
4032aa8be8
85 changed files with 16677 additions and 6457 deletions
3
intl/ChangeLog
Normal file
3
intl/ChangeLog
Normal file
|
@ -0,0 +1,3 @@
|
|||
2010-06-04 GNU <bug-gnu-gettext@gnu.org>
|
||||
|
||||
* Version 0.18.1 released.
|
188
intl/Makefile.in
188
intl/Makefile.in
|
@ -1,5 +1,5 @@
|
|||
# Makefile for directory with message catalog handling library of GNU gettext
|
||||
# Copyright (C) 1995-1998, 2000-2006 Free Software Foundation, Inc.
|
||||
# Copyright (C) 1995-1998, 2000-2007, 2009-2010 Free Software Foundation, Inc.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU Library General Public License as published
|
||||
|
@ -72,6 +72,30 @@ LIBTOOL = @LIBTOOL@
|
|||
RANLIB = @RANLIB@
|
||||
YACC = @INTLBISON@ -y -d
|
||||
YFLAGS = --name-prefix=__gettext
|
||||
# Windows resource compiler (windres). Used when libtool is not used.
|
||||
WINDRES = @WINDRES@
|
||||
# Windows resource compiler (windres). Used via libtool.
|
||||
RC = @RC@
|
||||
|
||||
# Support for silent-rules.
|
||||
AM_V_at = $(am__v_at_$(V))
|
||||
am__v_at_ = $(am__v_at_@INTL_DEFAULT_VERBOSITY@)
|
||||
am__v_at_0 = @
|
||||
AM_V_AR = $(am__v_AR_$(V))
|
||||
am__v_AR_ = $(am__v_AR_@INTL_DEFAULT_VERBOSITY@)
|
||||
am__v_AR_0 = @echo " AR " $@;
|
||||
AM_V_CC = $(am__v_CC_$(V))
|
||||
am__v_CC_ = $(am__v_CC_@INTL_DEFAULT_VERBOSITY@)
|
||||
am__v_CC_0 = @echo " CC " $@;
|
||||
AM_V_GEN = $(am__v_GEN_$(V))
|
||||
am__v_GEN_ = $(am__v_GEN_@INTL_DEFAULT_VERBOSITY@)
|
||||
am__v_GEN_0 = @echo " GEN " $@;
|
||||
AM_V_YACC = $(am__v_YACC_$(V))
|
||||
am__v_YACC_ = $(am__v_YACC_@INTL_DEFAULT_VERBOSITY@)
|
||||
am__v_YACC_0 = @echo " YACC " $@;
|
||||
AM_V_lt = $(am__v_lt_$(V))
|
||||
am__v_lt_ = $(am__v_lt_@INTL_DEFAULT_VERBOSITY@)
|
||||
am__v_lt_0 = --silent
|
||||
|
||||
# -DBUILDING_LIBINTL: Change expansion of LIBINTL_DLL_EXPORTED macro.
|
||||
# -DBUILDING_DLL: Change expansion of RELOCATABLE_DLL_EXPORTED macro.
|
||||
|
@ -100,6 +124,7 @@ HEADERS = \
|
|||
localcharset.h \
|
||||
lock.h \
|
||||
relocatable.h \
|
||||
tsearch.h tsearch.c \
|
||||
xsize.h \
|
||||
printf-args.h printf-args.c \
|
||||
printf-parse.h wprintf-parse.h printf-parse.c \
|
||||
|
@ -125,12 +150,14 @@ SOURCES = \
|
|||
plural.y \
|
||||
plural-exp.c \
|
||||
localcharset.c \
|
||||
threadlib.c \
|
||||
lock.c \
|
||||
relocatable.c \
|
||||
langprefs.c \
|
||||
localename.c \
|
||||
log.c \
|
||||
printf.c \
|
||||
setlocale.c \
|
||||
version.c \
|
||||
osdep.c \
|
||||
os2compat.c \
|
||||
|
@ -155,17 +182,21 @@ OBJECTS = \
|
|||
plural.$lo \
|
||||
plural-exp.$lo \
|
||||
localcharset.$lo \
|
||||
threadlib.$lo \
|
||||
lock.$lo \
|
||||
relocatable.$lo \
|
||||
langprefs.$lo \
|
||||
localename.$lo \
|
||||
log.$lo \
|
||||
printf.$lo \
|
||||
setlocale.$lo \
|
||||
version.$lo \
|
||||
osdep.$lo \
|
||||
intl-compat.$lo
|
||||
OBJECTS_RES_yes = libintl.res.$lo
|
||||
OBJECTS_RES_no =
|
||||
DISTFILES.common = Makefile.in \
|
||||
config.charset locale.alias ref-add.sin ref-del.sin export.h \
|
||||
config.charset locale.alias ref-add.sin ref-del.sin export.h libintl.rc \
|
||||
$(HEADERS) $(SOURCES)
|
||||
DISTFILES.generated = plural.c
|
||||
DISTFILES.normal = VERSION
|
||||
|
@ -182,14 +213,15 @@ all-no-yes: libgnuintl.$la
|
|||
all-no-no:
|
||||
|
||||
libintl.a libgnuintl.a: $(OBJECTS)
|
||||
rm -f $@
|
||||
$(AR) cru $@ $(OBJECTS)
|
||||
$(RANLIB) $@
|
||||
$(AM_V_at)rm -f $@
|
||||
$(AM_V_AR)$(AR) cru $@ $(OBJECTS)
|
||||
$(AM_V_at)$(RANLIB) $@
|
||||
|
||||
libintl.la libgnuintl.la: $(OBJECTS)
|
||||
$(LIBTOOL) --mode=link \
|
||||
libintl.la libgnuintl.la: $(OBJECTS) $(OBJECTS_RES_@WOE32@)
|
||||
$(AM_V_GEN)$(LIBTOOL) $(AM_V_lt) --tag=CC --mode=link \
|
||||
$(CC) $(CPPFLAGS) $(CFLAGS) $(XCFLAGS) $(LDFLAGS) -o $@ \
|
||||
$(OBJECTS) @LTLIBICONV@ @INTL_MACOSX_LIBS@ $(LIBS) @LTLIBTHREAD@ -lc \
|
||||
$(OBJECTS) @LTLIBICONV@ @INTL_MACOSX_LIBS@ $(LIBS) @LTLIBTHREAD@ @LTLIBC@ \
|
||||
$(OBJECTS_RES_@WOE32@) \
|
||||
-version-info $(LTV_CURRENT):$(LTV_REVISION):$(LTV_AGE) \
|
||||
-rpath $(libdir) \
|
||||
-no-undefined
|
||||
|
@ -199,74 +231,106 @@ libintl.la libgnuintl.la: $(OBJECTS)
|
|||
# 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=8
|
||||
LTV_CURRENT=9
|
||||
LTV_REVISION=1
|
||||
LTV_AGE=0
|
||||
LTV_AGE=1
|
||||
|
||||
.SUFFIXES:
|
||||
.SUFFIXES: .c .y .o .lo .sin .sed
|
||||
|
||||
.c.o:
|
||||
$(COMPILE) $<
|
||||
$(AM_V_CC)$(COMPILE) $<
|
||||
|
||||
.y.c:
|
||||
$(YACC) $(YFLAGS) --output $@ $<
|
||||
rm -f $*.h
|
||||
$(AM_V_YACC)$(YACC) $(YFLAGS) --output $@ $<
|
||||
$(AM_V_at)rm -f $*.h
|
||||
|
||||
bindtextdom.lo: $(srcdir)/bindtextdom.c
|
||||
$(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/bindtextdom.c
|
||||
$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC --mode=compile $(COMPILE) $(srcdir)/bindtextdom.c
|
||||
dcgettext.lo: $(srcdir)/dcgettext.c
|
||||
$(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/dcgettext.c
|
||||
$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC --mode=compile $(COMPILE) $(srcdir)/dcgettext.c
|
||||
dgettext.lo: $(srcdir)/dgettext.c
|
||||
$(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/dgettext.c
|
||||
$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC --mode=compile $(COMPILE) $(srcdir)/dgettext.c
|
||||
gettext.lo: $(srcdir)/gettext.c
|
||||
$(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/gettext.c
|
||||
$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC --mode=compile $(COMPILE) $(srcdir)/gettext.c
|
||||
finddomain.lo: $(srcdir)/finddomain.c
|
||||
$(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/finddomain.c
|
||||
$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC --mode=compile $(COMPILE) $(srcdir)/finddomain.c
|
||||
hash-string.lo: $(srcdir)/hash-string.c
|
||||
$(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/hash-string.c
|
||||
$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC --mode=compile $(COMPILE) $(srcdir)/hash-string.c
|
||||
loadmsgcat.lo: $(srcdir)/loadmsgcat.c
|
||||
$(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/loadmsgcat.c
|
||||
$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC --mode=compile $(COMPILE) $(srcdir)/loadmsgcat.c
|
||||
localealias.lo: $(srcdir)/localealias.c
|
||||
$(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/localealias.c
|
||||
$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC --mode=compile $(COMPILE) $(srcdir)/localealias.c
|
||||
textdomain.lo: $(srcdir)/textdomain.c
|
||||
$(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/textdomain.c
|
||||
$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC --mode=compile $(COMPILE) $(srcdir)/textdomain.c
|
||||
l10nflist.lo: $(srcdir)/l10nflist.c
|
||||
$(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/l10nflist.c
|
||||
$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC --mode=compile $(COMPILE) $(srcdir)/l10nflist.c
|
||||
explodename.lo: $(srcdir)/explodename.c
|
||||
$(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/explodename.c
|
||||
$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC --mode=compile $(COMPILE) $(srcdir)/explodename.c
|
||||
dcigettext.lo: $(srcdir)/dcigettext.c
|
||||
$(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/dcigettext.c
|
||||
$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC --mode=compile $(COMPILE) $(srcdir)/dcigettext.c
|
||||
dcngettext.lo: $(srcdir)/dcngettext.c
|
||||
$(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/dcngettext.c
|
||||
$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC --mode=compile $(COMPILE) $(srcdir)/dcngettext.c
|
||||
dngettext.lo: $(srcdir)/dngettext.c
|
||||
$(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/dngettext.c
|
||||
$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC --mode=compile $(COMPILE) $(srcdir)/dngettext.c
|
||||
ngettext.lo: $(srcdir)/ngettext.c
|
||||
$(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/ngettext.c
|
||||
$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC --mode=compile $(COMPILE) $(srcdir)/ngettext.c
|
||||
plural.lo: $(srcdir)/plural.c
|
||||
$(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/plural.c
|
||||
$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC --mode=compile $(COMPILE) $(srcdir)/plural.c
|
||||
plural-exp.lo: $(srcdir)/plural-exp.c
|
||||
$(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/plural-exp.c
|
||||
$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC --mode=compile $(COMPILE) $(srcdir)/plural-exp.c
|
||||
localcharset.lo: $(srcdir)/localcharset.c
|
||||
$(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/localcharset.c
|
||||
$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC --mode=compile $(COMPILE) $(srcdir)/localcharset.c
|
||||
threadlib.lo: $(srcdir)/threadlib.c
|
||||
$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC --mode=compile $(COMPILE) $(srcdir)/threadlib.c
|
||||
lock.lo: $(srcdir)/lock.c
|
||||
$(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/lock.c
|
||||
$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC --mode=compile $(COMPILE) $(srcdir)/lock.c
|
||||
relocatable.lo: $(srcdir)/relocatable.c
|
||||
$(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/relocatable.c
|
||||
$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC --mode=compile $(COMPILE) $(srcdir)/relocatable.c
|
||||
langprefs.lo: $(srcdir)/langprefs.c
|
||||
$(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/langprefs.c
|
||||
$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC --mode=compile $(COMPILE) $(srcdir)/langprefs.c
|
||||
localename.lo: $(srcdir)/localename.c
|
||||
$(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/localename.c
|
||||
$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC --mode=compile $(COMPILE) $(srcdir)/localename.c
|
||||
log.lo: $(srcdir)/log.c
|
||||
$(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/log.c
|
||||
$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC --mode=compile $(COMPILE) $(srcdir)/log.c
|
||||
printf.lo: $(srcdir)/printf.c
|
||||
$(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/printf.c
|
||||
$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC --mode=compile $(COMPILE) $(srcdir)/printf.c
|
||||
setlocale.lo: $(srcdir)/setlocale.c
|
||||
$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC --mode=compile $(COMPILE) $(srcdir)/setlocale.c
|
||||
version.lo: $(srcdir)/version.c
|
||||
$(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/version.c
|
||||
$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC --mode=compile $(COMPILE) $(srcdir)/version.c
|
||||
osdep.lo: $(srcdir)/osdep.c
|
||||
$(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/osdep.c
|
||||
$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC --mode=compile $(COMPILE) $(srcdir)/osdep.c
|
||||
intl-compat.lo: $(srcdir)/intl-compat.c
|
||||
$(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/intl-compat.c
|
||||
$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC --mode=compile $(COMPILE) $(srcdir)/intl-compat.c
|
||||
|
||||
# This rule is executed only on Woe32 systems.
|
||||
# The following sed expressions come from the windres-options script. They are
|
||||
# inlined here, so that they can be written in a Makefile without requiring a
|
||||
# temporary file. They must contain literal newlines rather than semicolons,
|
||||
# so that they work with the sed-3.02 that is shipped with MSYS.
|
||||
libintl.res.o: $(srcdir)/libintl.rc
|
||||
nlinit=`echo 'nl="'; echo '"'`; eval "$$nlinit"; \
|
||||
sed_extract_major='/^[0-9]/{'$${nl}'s/^\([0-9]*\).*/\1/p'$${nl}q$${nl}'}'$${nl}'c\'$${nl}0$${nl}q; \
|
||||
sed_extract_minor='/^[0-9][0-9]*[.][0-9]/{'$${nl}'s/^[0-9]*[.]\([0-9]*\).*/\1/p'$${nl}q$${nl}'}'$${nl}'c\'$${nl}0$${nl}q; \
|
||||
sed_extract_subminor='/^[0-9][0-9]*[.][0-9][0-9]*[.][0-9]/{'$${nl}'s/^[0-9]*[.][0-9]*[.]\([0-9]*\).*/\1/p'$${nl}q$${nl}'}'$${nl}'c\'$${nl}0$${nl}q; \
|
||||
$(WINDRES) \
|
||||
"-DPACKAGE_VERSION_STRING=\\\"$(VERSION)\\\"" \
|
||||
"-DPACKAGE_VERSION_MAJOR="`echo '$(VERSION)' | sed -n -e "$$sed_extract_major"` \
|
||||
"-DPACKAGE_VERSION_MINOR="`echo '$(VERSION)' | sed -n -e "$$sed_extract_minor"` \
|
||||
"-DPACKAGE_VERSION_SUBMINOR="`echo '$(VERSION)' | sed -n -e "$$sed_extract_subminor"` \
|
||||
-i $(srcdir)/libintl.rc -o libintl.res.o --output-format=coff
|
||||
libintl.res.lo: $(srcdir)/libintl.rc
|
||||
nlinit=`echo 'nl="'; echo '"'`; eval "$$nlinit"; \
|
||||
sed_extract_major='/^[0-9]/{'$${nl}'s/^\([0-9]*\).*/\1/p'$${nl}q$${nl}'}'$${nl}'c\'$${nl}0$${nl}q; \
|
||||
sed_extract_minor='/^[0-9][0-9]*[.][0-9]/{'$${nl}'s/^[0-9]*[.]\([0-9]*\).*/\1/p'$${nl}q$${nl}'}'$${nl}'c\'$${nl}0$${nl}q; \
|
||||
sed_extract_subminor='/^[0-9][0-9]*[.][0-9][0-9]*[.][0-9]/{'$${nl}'s/^[0-9]*[.][0-9]*[.]\([0-9]*\).*/\1/p'$${nl}q$${nl}'}'$${nl}'c\'$${nl}0$${nl}q; \
|
||||
$(LIBTOOL) --mode=compile --tag=RC $(RC) \
|
||||
"-DPACKAGE_VERSION_STRING=\\\"$(VERSION)\\\"" \
|
||||
"-DPACKAGE_VERSION_MAJOR="`echo '$(VERSION)' | sed -n -e "$$sed_extract_major"` \
|
||||
"-DPACKAGE_VERSION_MINOR="`echo '$(VERSION)' | sed -n -e "$$sed_extract_minor"` \
|
||||
"-DPACKAGE_VERSION_SUBMINOR="`echo '$(VERSION)' | sed -n -e "$$sed_extract_subminor"` \
|
||||
-i $(srcdir)/libintl.rc -o libintl.res.lo --output-format=coff
|
||||
|
||||
ref-add.sed: $(srcdir)/ref-add.sin
|
||||
sed -e '/^#/d' -e 's/@''PACKAGE''@/@PACKAGE@/g' $(srcdir)/ref-add.sin > t-ref-add.sed
|
||||
|
@ -281,6 +345,7 @@ libgnuintl.h: $(srcdir)/libgnuintl.h.in
|
|||
sed -e '/IN_LIBGLOCALE/d' \
|
||||
-e 's,@''HAVE_POSIX_PRINTF''@,@HAVE_POSIX_PRINTF@,g' \
|
||||
-e 's,@''HAVE_ASPRINTF''@,@HAVE_ASPRINTF@,g' \
|
||||
-e 's,@''HAVE_NEWLOCALE''@,@HAVE_NEWLOCALE@,g' \
|
||||
-e 's,@''HAVE_SNPRINTF''@,@HAVE_SNPRINTF@,g' \
|
||||
-e 's,@''HAVE_WPRINTF''@,@HAVE_WPRINTF@,g' \
|
||||
< $(srcdir)/libgnuintl.h.in \
|
||||
|
@ -298,6 +363,7 @@ libintl.h: $(srcdir)/libgnuintl.h.in
|
|||
sed -e '/IN_LIBGLOCALE/d' \
|
||||
-e 's,@''HAVE_POSIX_PRINTF''@,@HAVE_POSIX_PRINTF@,g' \
|
||||
-e 's,@''HAVE_ASPRINTF''@,@HAVE_ASPRINTF@,g' \
|
||||
-e 's,@''HAVE_NEWLOCALE''@,@HAVE_NEWLOCALE@,g' \
|
||||
-e 's,@''HAVE_SNPRINTF''@,@HAVE_SNPRINTF@,g' \
|
||||
-e 's,@''HAVE_WPRINTF''@,@HAVE_WPRINTF@,g' \
|
||||
< $(srcdir)/libgnuintl.h.in > libintl.h
|
||||
|
@ -344,7 +410,21 @@ install-exec: all
|
|||
: ; \
|
||||
fi
|
||||
if test '@USE_INCLUDED_LIBINTL@' = yes; then \
|
||||
test @GLIBC21@ != no || $(mkdir_p) $(DESTDIR)$(libdir); \
|
||||
if test @GLIBC21@ = no; then \
|
||||
case '@host_os@' in \
|
||||
darwin[56]*) \
|
||||
need_charset_alias=true ;; \
|
||||
darwin* | cygwin* | mingw* | pw32* | cegcc*) \
|
||||
need_charset_alias=false ;; \
|
||||
*) \
|
||||
need_charset_alias=true ;; \
|
||||
esac; \
|
||||
else \
|
||||
need_charset_alias=false; \
|
||||
fi; \
|
||||
if $$need_charset_alias; then \
|
||||
$(mkdir_p) $(DESTDIR)$(libdir); \
|
||||
fi; \
|
||||
temp=$(DESTDIR)$(libdir)/t-charset.alias; \
|
||||
dest=$(DESTDIR)$(libdir)/charset.alias; \
|
||||
if test -f $(DESTDIR)$(libdir)/charset.alias; then \
|
||||
|
@ -353,7 +433,7 @@ install-exec: all
|
|||
$(INSTALL_DATA) $$temp $$dest; \
|
||||
rm -f $$temp; \
|
||||
else \
|
||||
if test @GLIBC21@ = no; then \
|
||||
if $$need_charset_alias; then \
|
||||
orig=charset.alias; \
|
||||
sed -f ref-add.sed $$orig > $$temp; \
|
||||
$(INSTALL_DATA) $$temp $$dest; \
|
||||
|
@ -376,6 +456,7 @@ install-data: all
|
|||
if test "$(PACKAGE)" = "gettext-tools"; then \
|
||||
$(mkdir_p) $(DESTDIR)$(gettextsrcdir); \
|
||||
$(INSTALL_DATA) VERSION $(DESTDIR)$(gettextsrcdir)/VERSION; \
|
||||
$(INSTALL_DATA) ChangeLog.inst $(DESTDIR)$(gettextsrcdir)/ChangeLog; \
|
||||
dists="COPYING.LIB-2.0 COPYING.LIB-2.1 $(DISTFILES.common)"; \
|
||||
for file in $$dists; do \
|
||||
$(INSTALL_DATA) $(srcdir)/$$file \
|
||||
|
@ -398,6 +479,8 @@ install-data: all
|
|||
|
||||
install-strip: install
|
||||
|
||||
install-dvi install-html install-info install-ps install-pdf:
|
||||
|
||||
installdirs:
|
||||
if { test "$(PACKAGE)" = "gettext-runtime" || test "$(PACKAGE)" = "gettext-tools"; } \
|
||||
&& test '@USE_INCLUDED_LIBINTL@' = yes; then \
|
||||
|
@ -413,7 +496,21 @@ installdirs:
|
|||
: ; \
|
||||
fi
|
||||
if test '@USE_INCLUDED_LIBINTL@' = yes; then \
|
||||
test @GLIBC21@ != no || $(mkdir_p) $(DESTDIR)$(libdir); \
|
||||
if test @GLIBC21@ = no; then \
|
||||
case '@host_os@' in \
|
||||
darwin[56]*) \
|
||||
need_charset_alias=true ;; \
|
||||
darwin* | cygwin* | mingw* | pw32* | cegcc*) \
|
||||
need_charset_alias=false ;; \
|
||||
*) \
|
||||
need_charset_alias=true ;; \
|
||||
esac; \
|
||||
else \
|
||||
need_charset_alias=false; \
|
||||
fi; \
|
||||
if $$need_charset_alias; then \
|
||||
$(mkdir_p) $(DESTDIR)$(libdir); \
|
||||
fi; \
|
||||
$(mkdir_p) $(DESTDIR)$(localedir); \
|
||||
else \
|
||||
: ; \
|
||||
|
@ -480,7 +577,8 @@ uninstall:
|
|||
info dvi ps pdf html:
|
||||
|
||||
$(OBJECTS): ../config.h libgnuintl.h
|
||||
bindtextdom.$lo dcgettext.$lo dcigettext.$lo dcngettext.$lo dgettext.$lo dngettext.$lo finddomain.$lo gettext.$lo intl-compat.$lo loadmsgcat.$lo localealias.$lo ngettext.$lo textdomain.$lo: $(srcdir)/gettextP.h $(srcdir)/gmo.h $(srcdir)/loadinfo.h
|
||||
bindtextdom.$lo dcgettext.$lo dcigettext.$lo dcngettext.$lo dgettext.$lo dngettext.$lo finddomain.$lo gettext.$lo intl-compat.$lo loadmsgcat.$lo localealias.$lo ngettext.$lo setlocale.$lo textdomain.$lo: $(srcdir)/gettextP.h $(srcdir)/gmo.h $(srcdir)/loadinfo.h
|
||||
localename.$lo: $(srcdir)/gettextP.h
|
||||
hash-string.$lo dcigettext.$lo loadmsgcat.$lo: $(srcdir)/hash-string.h
|
||||
explodename.$lo l10nflist.$lo: $(srcdir)/loadinfo.h
|
||||
dcigettext.$lo loadmsgcat.$lo plural.$lo plural-exp.$lo: $(srcdir)/plural-exp.h
|
||||
|
@ -544,7 +642,7 @@ dist distdir: Makefile
|
|||
additional="$(DISTFILES.normal)"; \
|
||||
fi; \
|
||||
$(MAKE) $(DISTFILES.common) $(DISTFILES.generated) $$additional; \
|
||||
for file in $(DISTFILES.common) $(DISTFILES.generated) $$additional; do \
|
||||
for file in ChangeLog $(DISTFILES.common) $(DISTFILES.generated) $$additional; do \
|
||||
if test -f $$file; then dir=.; else dir=$(srcdir); fi; \
|
||||
cp -p $$dir/$$file $(distdir) || test $$file = Makefile.in || exit 1; \
|
||||
done; \
|
||||
|
|
|
@ -1 +1 @@
|
|||
GNU gettext library from gettext-0.16.1
|
||||
GNU gettext library from gettext-0.18.1
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
/* Implementation of the bindtextdomain(3) function
|
||||
Copyright (C) 1995-1998, 2000-2003, 2005-2006 Free Software Foundation, Inc.
|
||||
Copyright (C) 1995-1998, 2000-2003, 2005-2006, 2008 Free Software
|
||||
Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Library General Public License as published
|
||||
|
@ -41,14 +42,6 @@
|
|||
# include "lock.h"
|
||||
#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 libintl_nl_default_dirname
|
||||
# define _nl_domain_bindings libintl_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))
|
||||
|
@ -56,15 +49,6 @@
|
|||
|
||||
/* @@ end of prolog @@ */
|
||||
|
||||
/* Contains the default location of the message catalogs. */
|
||||
extern const char _nl_default_dirname[];
|
||||
#ifdef _LIBC
|
||||
libc_hidden_proto (_nl_default_dirname)
|
||||
#endif
|
||||
|
||||
/* List with bindings of specific domains. */
|
||||
extern struct binding *_nl_domain_bindings;
|
||||
|
||||
/* Lock variable to protect the global data in the gettext implementation. */
|
||||
gl_rwlock_define (extern, _nl_state_lock attribute_hidden)
|
||||
|
||||
|
@ -195,8 +179,7 @@ set_binding_values (const char *domainname,
|
|||
|
||||
if (__builtin_expect (result != NULL, 1))
|
||||
{
|
||||
if (binding->codeset != NULL)
|
||||
free (binding->codeset);
|
||||
free (binding->codeset);
|
||||
|
||||
binding->codeset = result;
|
||||
modified = 1;
|
||||
|
|
1132
intl/config.charset
1132
intl/config.charset
File diff suppressed because it is too large
Load diff
|
@ -1,5 +1,5 @@
|
|||
/* Implementation of the internal dcigettext function.
|
||||
Copyright (C) 1995-1999, 2000-2006 Free Software Foundation, Inc.
|
||||
Copyright (C) 1995-1999, 2000-2009 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Library General Public License as published
|
||||
|
@ -27,9 +27,6 @@
|
|||
# include <config.h>
|
||||
#endif
|
||||
|
||||
/* NL_LOCALE_NAME does not work in glibc-2.4. Ignore it. */
|
||||
#undef HAVE_NL_LOCALE_NAME
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#ifdef __GNUC__
|
||||
|
@ -90,8 +87,8 @@ extern int errno;
|
|||
# include <sys/param.h>
|
||||
#endif
|
||||
|
||||
#if !defined _LIBC && HAVE_NL_LOCALE_NAME
|
||||
# include <langinfo.h>
|
||||
#if !defined _LIBC
|
||||
# include "localcharset.h"
|
||||
#endif
|
||||
|
||||
#include "gettextP.h"
|
||||
|
@ -125,16 +122,6 @@ extern int errno;
|
|||
((int) &((struct { char dummy1; TYPE dummy2; } *) 0)->dummy2)
|
||||
#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 libintl_nl_default_default_domain
|
||||
# define _nl_current_default_domain libintl_nl_current_default_domain
|
||||
# define _nl_default_dirname libintl_nl_default_dirname
|
||||
# define _nl_domain_bindings libintl_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))
|
||||
|
@ -170,6 +157,22 @@ static void *mempcpy (void *dest, const void *src, size_t n);
|
|||
# endif
|
||||
#endif
|
||||
|
||||
/* Use a replacement if the system does not provide the `tsearch' function
|
||||
family. */
|
||||
#if HAVE_TSEARCH || defined _LIBC
|
||||
# include <search.h>
|
||||
#else
|
||||
# define tsearch libintl_tsearch
|
||||
# define tfind libintl_tfind
|
||||
# define tdelete libintl_tdelete
|
||||
# define twalk libintl_twalk
|
||||
# include "tsearch.h"
|
||||
#endif
|
||||
|
||||
#ifdef _LIBC
|
||||
# define tsearch __tsearch
|
||||
#endif
|
||||
|
||||
/* Amount to increase buffer size by in each try. */
|
||||
#define PATH_INCR 32
|
||||
|
||||
|
@ -225,7 +228,7 @@ static void *mempcpy (void *dest, const void *src, size_t n);
|
|||
#endif
|
||||
|
||||
/* Whether to support different locales in different threads. */
|
||||
#if defined _LIBC || HAVE_NL_LOCALE_NAME || (HAVE_STRUCT___LOCALE_STRUCT___NAMES && defined USE_IN_GETTEXT_TESTS) || defined IN_LIBGLOCALE
|
||||
#if defined _LIBC || HAVE_USELOCALE || defined IN_LIBGLOCALE
|
||||
# define HAVE_PER_THREAD_LOCALE
|
||||
#endif
|
||||
|
||||
|
@ -260,22 +263,19 @@ struct known_translation_t
|
|||
size_t translation_length;
|
||||
|
||||
/* Pointer to the string in question. */
|
||||
char msgid[ZERO];
|
||||
union
|
||||
{
|
||||
char appended[ZERO]; /* used if domain != NULL */
|
||||
const char *ptr; /* used if domain == NULL */
|
||||
}
|
||||
msgid;
|
||||
};
|
||||
|
||||
/* Root of the search tree with known translations. We can use this
|
||||
only if the system provides the `tsearch' function family. */
|
||||
#if defined HAVE_TSEARCH || defined _LIBC
|
||||
# include <search.h>
|
||||
|
||||
gl_rwlock_define_initialized (static, tree_lock)
|
||||
|
||||
/* Root of the search tree with known translations. */
|
||||
static void *root;
|
||||
|
||||
# ifdef _LIBC
|
||||
# define tsearch __tsearch
|
||||
# endif
|
||||
|
||||
/* Function to compare two entries in the table of known translations. */
|
||||
static int
|
||||
transcmp (const void *p1, const void *p2)
|
||||
|
@ -287,7 +287,8 @@ transcmp (const void *p1, const void *p2)
|
|||
s1 = (const struct known_translation_t *) p1;
|
||||
s2 = (const struct known_translation_t *) p2;
|
||||
|
||||
result = strcmp (s1->msgid, s2->msgid);
|
||||
result = strcmp (s1->domain != NULL ? s1->msgid.appended : s1->msgid.ptr,
|
||||
s2->domain != NULL ? s2->msgid.appended : s2->msgid.ptr);
|
||||
if (result == 0)
|
||||
{
|
||||
result = strcmp (s1->domainname, s2->domainname);
|
||||
|
@ -312,7 +313,6 @@ transcmp (const void *p1, const void *p2)
|
|||
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Name of the default domain used for gettext(3) prior any call to
|
||||
textdomain(3). The default value for this is "messages". */
|
||||
|
@ -501,13 +501,10 @@ DCIGETTEXT (const char *domainname, const char *msgid1, const char *msgid2,
|
|||
char *retval;
|
||||
size_t retlen;
|
||||
int saved_errno;
|
||||
#if defined HAVE_TSEARCH || defined _LIBC
|
||||
struct known_translation_t *search;
|
||||
struct known_translation_t search;
|
||||
struct known_translation_t **foundp = NULL;
|
||||
size_t msgid_len;
|
||||
# if defined HAVE_PER_THREAD_LOCALE && !defined IN_LIBGLOCALE
|
||||
#if defined HAVE_PER_THREAD_LOCALE && !defined IN_LIBGLOCALE
|
||||
const char *localename;
|
||||
# endif
|
||||
#endif
|
||||
size_t domainname_len;
|
||||
|
||||
|
@ -524,6 +521,14 @@ DCIGETTEXT (const char *domainname, const char *msgid1, const char *msgid2,
|
|||
: n == 1 ? (char *) msgid1 : (char *) msgid2);
|
||||
#endif
|
||||
|
||||
/* Preserve the `errno' value. */
|
||||
saved_errno = errno;
|
||||
|
||||
#ifdef _LIBC
|
||||
__libc_rwlock_define (extern, __libc_setlocale_lock attribute_hidden)
|
||||
__libc_rwlock_rdlock (__libc_setlocale_lock);
|
||||
#endif
|
||||
|
||||
gl_rwlock_rdlock (_nl_state_lock);
|
||||
|
||||
/* If DOMAINNAME is NULL, we are interested in the default domain. If
|
||||
|
@ -538,54 +543,37 @@ DCIGETTEXT (const char *domainname, const char *msgid1, const char *msgid2,
|
|||
category = LC_MESSAGES;
|
||||
#endif
|
||||
|
||||
#if defined HAVE_TSEARCH || defined _LIBC
|
||||
msgid_len = strlen (msgid1) + 1;
|
||||
|
||||
/* Try to find the translation among those which we found at
|
||||
some time. */
|
||||
search = (struct known_translation_t *)
|
||||
alloca (offsetof (struct known_translation_t, msgid) + msgid_len);
|
||||
memcpy (search->msgid, msgid1, msgid_len);
|
||||
search->domainname = domainname;
|
||||
search->category = category;
|
||||
# ifdef HAVE_PER_THREAD_LOCALE
|
||||
# ifndef IN_LIBGLOCALE
|
||||
# ifdef _LIBC
|
||||
localename = __current_locale_name (category);
|
||||
# else
|
||||
# if HAVE_NL_LOCALE_NAME
|
||||
/* NL_LOCALE_NAME is public glibc API introduced in glibc-2.4. */
|
||||
localename = nl_langinfo (NL_LOCALE_NAME (category));
|
||||
# else
|
||||
# if HAVE_STRUCT___LOCALE_STRUCT___NAMES && defined USE_IN_GETTEXT_TESTS
|
||||
/* The __names field is not public glibc API and must therefore not be used
|
||||
in code that is installed in public locations. */
|
||||
{
|
||||
locale_t thread_locale = uselocale (NULL);
|
||||
if (thread_locale != LC_GLOBAL_LOCALE)
|
||||
localename = thread_locale->__names[category];
|
||||
else
|
||||
localename = "";
|
||||
}
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
search->localename = localename;
|
||||
# ifdef IN_LIBGLOCALE
|
||||
search->encoding = encoding;
|
||||
search.domain = NULL;
|
||||
search.msgid.ptr = msgid1;
|
||||
search.domainname = domainname;
|
||||
search.category = category;
|
||||
#ifdef HAVE_PER_THREAD_LOCALE
|
||||
# ifndef IN_LIBGLOCALE
|
||||
# ifdef _LIBC
|
||||
localename = _strdupa (_current_locale_name (category));
|
||||
# else
|
||||
categoryname = category_to_name (category);
|
||||
# define CATEGORYNAME_INITIALIZED
|
||||
localename = _nl_locale_name_thread_unsafe (category, categoryname);
|
||||
if (localename == NULL)
|
||||
localename = "";
|
||||
# endif
|
||||
# endif
|
||||
search.localename = localename;
|
||||
# ifdef IN_LIBGLOCALE
|
||||
search.encoding = encoding;
|
||||
# endif
|
||||
|
||||
/* Since tfind/tsearch manage a balanced tree, concurrent tfind and
|
||||
tsearch calls can be fatal. */
|
||||
gl_rwlock_rdlock (tree_lock);
|
||||
|
||||
foundp = (struct known_translation_t **) tfind (search, &root, transcmp);
|
||||
foundp = (struct known_translation_t **) tfind (&search, &root, transcmp);
|
||||
|
||||
gl_rwlock_unlock (tree_lock);
|
||||
|
||||
freea (search);
|
||||
if (foundp != NULL && (*foundp)->counter == _nl_msg_cat_cntr)
|
||||
{
|
||||
/* Now deal with plural. */
|
||||
|
@ -596,13 +584,14 @@ DCIGETTEXT (const char *domainname, const char *msgid1, const char *msgid2,
|
|||
retval = (char *) (*foundp)->translation;
|
||||
|
||||
gl_rwlock_unlock (_nl_state_lock);
|
||||
# ifdef _LIBC
|
||||
__libc_rwlock_unlock (__libc_setlocale_lock);
|
||||
# endif
|
||||
__set_errno (saved_errno);
|
||||
return retval;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Preserve the `errno' value. */
|
||||
saved_errno = errno;
|
||||
|
||||
/* See whether this is a SUID binary or not. */
|
||||
DETERMINE_SECURE;
|
||||
|
||||
|
@ -671,7 +660,9 @@ DCIGETTEXT (const char *domainname, const char *msgid1, const char *msgid2,
|
|||
#endif
|
||||
|
||||
/* Now determine the symbolic name of CATEGORY and its value. */
|
||||
#ifndef CATEGORYNAME_INITIALIZED
|
||||
categoryname = category_to_name (category);
|
||||
#endif
|
||||
#ifdef IN_LIBGLOCALE
|
||||
categoryvalue = guess_category_value (category, categoryname, localename);
|
||||
#else
|
||||
|
@ -683,8 +674,8 @@ DCIGETTEXT (const char *domainname, const char *msgid1, const char *msgid2,
|
|||
+ domainname_len + 5);
|
||||
ADD_BLOCK (block_list, xdomainname);
|
||||
|
||||
stpcpy (mempcpy (stpcpy (stpcpy (xdomainname, categoryname), "/"),
|
||||
domainname, domainname_len),
|
||||
stpcpy ((char *) mempcpy (stpcpy (stpcpy (xdomainname, categoryname), "/"),
|
||||
domainname, domainname_len),
|
||||
".mo");
|
||||
|
||||
/* Creating working area. */
|
||||
|
@ -773,40 +764,43 @@ DCIGETTEXT (const char *domainname, const char *msgid1, const char *msgid2,
|
|||
/* Found the translation of MSGID1 in domain DOMAIN:
|
||||
starting at RETVAL, RETLEN bytes. */
|
||||
FREE_BLOCKS (block_list);
|
||||
#if defined HAVE_TSEARCH || defined _LIBC
|
||||
if (foundp == NULL)
|
||||
{
|
||||
/* Create a new entry and add it to the search tree. */
|
||||
size_t msgid_len;
|
||||
size_t size;
|
||||
struct known_translation_t *newp;
|
||||
|
||||
msgid_len = strlen (msgid1) + 1;
|
||||
size = offsetof (struct known_translation_t, msgid)
|
||||
+ msgid_len + domainname_len + 1;
|
||||
# ifdef HAVE_PER_THREAD_LOCALE
|
||||
#ifdef HAVE_PER_THREAD_LOCALE
|
||||
size += strlen (localename) + 1;
|
||||
# endif
|
||||
#endif
|
||||
newp = (struct known_translation_t *) malloc (size);
|
||||
if (newp != NULL)
|
||||
{
|
||||
char *new_domainname;
|
||||
# ifdef HAVE_PER_THREAD_LOCALE
|
||||
#ifdef HAVE_PER_THREAD_LOCALE
|
||||
char *new_localename;
|
||||
# endif
|
||||
#endif
|
||||
|
||||
new_domainname = mempcpy (newp->msgid, msgid1, msgid_len);
|
||||
new_domainname =
|
||||
(char *) mempcpy (newp->msgid.appended, msgid1,
|
||||
msgid_len);
|
||||
memcpy (new_domainname, domainname, domainname_len + 1);
|
||||
# ifdef HAVE_PER_THREAD_LOCALE
|
||||
#ifdef HAVE_PER_THREAD_LOCALE
|
||||
new_localename = new_domainname + domainname_len + 1;
|
||||
strcpy (new_localename, localename);
|
||||
# endif
|
||||
#endif
|
||||
newp->domainname = new_domainname;
|
||||
newp->category = category;
|
||||
# ifdef HAVE_PER_THREAD_LOCALE
|
||||
#ifdef HAVE_PER_THREAD_LOCALE
|
||||
newp->localename = new_localename;
|
||||
# endif
|
||||
# ifdef IN_LIBGLOCALE
|
||||
#endif
|
||||
#ifdef IN_LIBGLOCALE
|
||||
newp->encoding = encoding;
|
||||
# endif
|
||||
#endif
|
||||
newp->counter = _nl_msg_cat_cntr;
|
||||
newp->domain = domain;
|
||||
newp->translation = retval;
|
||||
|
@ -834,7 +828,7 @@ DCIGETTEXT (const char *domainname, const char *msgid1, const char *msgid2,
|
|||
(*foundp)->translation = retval;
|
||||
(*foundp)->translation_length = retlen;
|
||||
}
|
||||
#endif
|
||||
|
||||
__set_errno (saved_errno);
|
||||
|
||||
/* Now deal with plural. */
|
||||
|
@ -842,6 +836,9 @@ DCIGETTEXT (const char *domainname, const char *msgid1, const char *msgid2,
|
|||
retval = plural_lookup (domain, n, retval, retlen);
|
||||
|
||||
gl_rwlock_unlock (_nl_state_lock);
|
||||
#ifdef _LIBC
|
||||
__libc_rwlock_unlock (__libc_setlocale_lock);
|
||||
#endif
|
||||
return retval;
|
||||
}
|
||||
}
|
||||
|
@ -851,6 +848,9 @@ DCIGETTEXT (const char *domainname, const char *msgid1, const char *msgid2,
|
|||
/* Return the untranslated MSGID. */
|
||||
FREE_BLOCKS (block_list);
|
||||
gl_rwlock_unlock (_nl_state_lock);
|
||||
#ifdef _LIBC
|
||||
__libc_rwlock_unlock (__libc_setlocale_lock);
|
||||
#endif
|
||||
#ifndef _LIBC
|
||||
if (!ENABLE_SECURE)
|
||||
{
|
||||
|
@ -1005,12 +1005,17 @@ _nl_find_msg (struct loaded_l10nfile *domain_file,
|
|||
# ifndef IN_LIBGLOCALE
|
||||
const char *encoding = get_output_charset (domainbinding);
|
||||
# endif
|
||||
size_t nconversions;
|
||||
struct converted_domain *convd;
|
||||
size_t i;
|
||||
|
||||
/* Protect against reallocation of the table. */
|
||||
gl_rwlock_rdlock (domain->conversions_lock);
|
||||
|
||||
/* Search whether a table with converted translations for this
|
||||
encoding has already been allocated. */
|
||||
size_t nconversions = domain->nconversions;
|
||||
struct converted_domain *convd = NULL;
|
||||
size_t i;
|
||||
nconversions = domain->nconversions;
|
||||
convd = NULL;
|
||||
|
||||
for (i = nconversions; i > 0; )
|
||||
{
|
||||
|
@ -1022,134 +1027,165 @@ _nl_find_msg (struct loaded_l10nfile *domain_file,
|
|||
}
|
||||
}
|
||||
|
||||
gl_rwlock_unlock (domain->conversions_lock);
|
||||
|
||||
if (convd == NULL)
|
||||
{
|
||||
/* Allocate a table for the converted translations for this
|
||||
encoding. */
|
||||
struct converted_domain *new_conversions =
|
||||
(struct converted_domain *)
|
||||
(domain->conversions != NULL
|
||||
? realloc (domain->conversions,
|
||||
(nconversions + 1) * sizeof (struct converted_domain))
|
||||
: malloc ((nconversions + 1) * sizeof (struct converted_domain)));
|
||||
/* We have to allocate a new conversions table. */
|
||||
gl_rwlock_wrlock (domain->conversions_lock);
|
||||
nconversions = domain->nconversions;
|
||||
|
||||
if (__builtin_expect (new_conversions == NULL, 0))
|
||||
/* Nothing we can do, no more memory. We cannot use the
|
||||
translation because it might be encoded incorrectly. */
|
||||
return (char *) -1;
|
||||
/* Maybe in the meantime somebody added the translation.
|
||||
Recheck. */
|
||||
for (i = nconversions; i > 0; )
|
||||
{
|
||||
i--;
|
||||
if (strcmp (domain->conversions[i].encoding, encoding) == 0)
|
||||
{
|
||||
convd = &domain->conversions[i];
|
||||
goto found_convd;
|
||||
}
|
||||
}
|
||||
|
||||
domain->conversions = new_conversions;
|
||||
{
|
||||
/* Allocate a table for the converted translations for this
|
||||
encoding. */
|
||||
struct converted_domain *new_conversions =
|
||||
(struct converted_domain *)
|
||||
(domain->conversions != NULL
|
||||
? realloc (domain->conversions,
|
||||
(nconversions + 1) * sizeof (struct converted_domain))
|
||||
: malloc ((nconversions + 1) * sizeof (struct converted_domain)));
|
||||
|
||||
/* Copy the 'encoding' string to permanent storage. */
|
||||
encoding = strdup (encoding);
|
||||
if (__builtin_expect (encoding == NULL, 0))
|
||||
/* Nothing we can do, no more memory. We cannot use the
|
||||
translation because it might be encoded incorrectly. */
|
||||
return (char *) -1;
|
||||
if (__builtin_expect (new_conversions == NULL, 0))
|
||||
{
|
||||
/* Nothing we can do, no more memory. We cannot use the
|
||||
translation because it might be encoded incorrectly. */
|
||||
unlock_fail:
|
||||
gl_rwlock_unlock (domain->conversions_lock);
|
||||
return (char *) -1;
|
||||
}
|
||||
|
||||
convd = &new_conversions[nconversions];
|
||||
convd->encoding = encoding;
|
||||
domain->conversions = new_conversions;
|
||||
|
||||
/* Find out about the character set the file is encoded with.
|
||||
This can be found (in textual form) in the entry "". If this
|
||||
entry does not exist or if this does not contain the 'charset='
|
||||
information, we will assume the charset matches the one the
|
||||
current locale and we don't have to perform any conversion. */
|
||||
/* Copy the 'encoding' string to permanent storage. */
|
||||
encoding = strdup (encoding);
|
||||
if (__builtin_expect (encoding == NULL, 0))
|
||||
/* Nothing we can do, no more memory. We cannot use the
|
||||
translation because it might be encoded incorrectly. */
|
||||
goto unlock_fail;
|
||||
|
||||
convd = &new_conversions[nconversions];
|
||||
convd->encoding = encoding;
|
||||
|
||||
/* Find out about the character set the file is encoded with.
|
||||
This can be found (in textual form) in the entry "". If this
|
||||
entry does not exist or if this does not contain the 'charset='
|
||||
information, we will assume the charset matches the one the
|
||||
current locale and we don't have to perform any conversion. */
|
||||
# ifdef _LIBC
|
||||
convd->conv = (__gconv_t) -1;
|
||||
convd->conv = (__gconv_t) -1;
|
||||
# else
|
||||
# if HAVE_ICONV
|
||||
convd->conv = (iconv_t) -1;
|
||||
convd->conv = (iconv_t) -1;
|
||||
# endif
|
||||
# endif
|
||||
{
|
||||
char *nullentry;
|
||||
size_t nullentrylen;
|
||||
{
|
||||
char *nullentry;
|
||||
size_t nullentrylen;
|
||||
|
||||
/* Get the header entry. This is a recursion, but it doesn't
|
||||
reallocate domain->conversions because we pass
|
||||
encoding = NULL or convert = 0, respectively. */
|
||||
nullentry =
|
||||
/* Get the header entry. This is a recursion, but it doesn't
|
||||
reallocate domain->conversions because we pass
|
||||
encoding = NULL or convert = 0, respectively. */
|
||||
nullentry =
|
||||
# ifdef IN_LIBGLOCALE
|
||||
_nl_find_msg (domain_file, domainbinding, NULL, "",
|
||||
&nullentrylen);
|
||||
_nl_find_msg (domain_file, domainbinding, NULL, "",
|
||||
&nullentrylen);
|
||||
# else
|
||||
_nl_find_msg (domain_file, domainbinding, "", 0, &nullentrylen);
|
||||
_nl_find_msg (domain_file, domainbinding, "", 0, &nullentrylen);
|
||||
# endif
|
||||
|
||||
if (nullentry != NULL)
|
||||
{
|
||||
const char *charsetstr;
|
||||
if (nullentry != NULL)
|
||||
{
|
||||
const char *charsetstr;
|
||||
|
||||
charsetstr = strstr (nullentry, "charset=");
|
||||
if (charsetstr != NULL)
|
||||
{
|
||||
size_t len;
|
||||
char *charset;
|
||||
const char *outcharset;
|
||||
charsetstr = strstr (nullentry, "charset=");
|
||||
if (charsetstr != NULL)
|
||||
{
|
||||
size_t len;
|
||||
char *charset;
|
||||
const char *outcharset;
|
||||
|
||||
charsetstr += strlen ("charset=");
|
||||
len = strcspn (charsetstr, " \t\n");
|
||||
charsetstr += strlen ("charset=");
|
||||
len = strcspn (charsetstr, " \t\n");
|
||||
|
||||
charset = (char *) alloca (len + 1);
|
||||
charset = (char *) alloca (len + 1);
|
||||
# if defined _LIBC || HAVE_MEMPCPY
|
||||
*((char *) mempcpy (charset, charsetstr, len)) = '\0';
|
||||
*((char *) mempcpy (charset, charsetstr, len)) = '\0';
|
||||
# else
|
||||
memcpy (charset, charsetstr, len);
|
||||
charset[len] = '\0';
|
||||
memcpy (charset, charsetstr, len);
|
||||
charset[len] = '\0';
|
||||
# endif
|
||||
|
||||
outcharset = encoding;
|
||||
outcharset = encoding;
|
||||
|
||||
# ifdef _LIBC
|
||||
/* We always want to use transliteration. */
|
||||
outcharset = norm_add_slashes (outcharset, "TRANSLIT");
|
||||
charset = norm_add_slashes (charset, "");
|
||||
int r = __gconv_open (outcharset, charset, &convd->conv,
|
||||
GCONV_AVOID_NOCONV);
|
||||
if (__builtin_expect (r != __GCONV_OK, 0))
|
||||
{
|
||||
/* If the output encoding is the same there is
|
||||
nothing to do. Otherwise do not use the
|
||||
translation at all. */
|
||||
if (__builtin_expect (r != __GCONV_NOCONV, 1))
|
||||
return NULL;
|
||||
/* We always want to use transliteration. */
|
||||
outcharset = norm_add_slashes (outcharset, "TRANSLIT");
|
||||
charset = norm_add_slashes (charset, "");
|
||||
int r = __gconv_open (outcharset, charset, &convd->conv,
|
||||
GCONV_AVOID_NOCONV);
|
||||
if (__builtin_expect (r != __GCONV_OK, 0))
|
||||
{
|
||||
/* If the output encoding is the same there is
|
||||
nothing to do. Otherwise do not use the
|
||||
translation at all. */
|
||||
if (__builtin_expect (r != __GCONV_NULCONV, 1))
|
||||
{
|
||||
gl_rwlock_unlock (domain->conversions_lock);
|
||||
free ((char *) encoding);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
convd->conv = (__gconv_t) -1;
|
||||
}
|
||||
convd->conv = (__gconv_t) -1;
|
||||
}
|
||||
# else
|
||||
# if HAVE_ICONV
|
||||
/* When using GNU libc >= 2.2 or GNU libiconv >= 1.5,
|
||||
we want to use transliteration. */
|
||||
/* When using GNU libc >= 2.2 or GNU libiconv >= 1.5,
|
||||
we want to use transliteration. */
|
||||
# if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 2) || __GLIBC__ > 2 \
|
||||
|| _LIBICONV_VERSION >= 0x0105
|
||||
if (strchr (outcharset, '/') == NULL)
|
||||
{
|
||||
char *tmp;
|
||||
if (strchr (outcharset, '/') == NULL)
|
||||
{
|
||||
char *tmp;
|
||||
|
||||
len = strlen (outcharset);
|
||||
tmp = (char *) alloca (len + 10 + 1);
|
||||
memcpy (tmp, outcharset, len);
|
||||
memcpy (tmp + len, "//TRANSLIT", 10 + 1);
|
||||
outcharset = tmp;
|
||||
len = strlen (outcharset);
|
||||
tmp = (char *) alloca (len + 10 + 1);
|
||||
memcpy (tmp, outcharset, len);
|
||||
memcpy (tmp + len, "//TRANSLIT", 10 + 1);
|
||||
outcharset = tmp;
|
||||
|
||||
convd->conv = iconv_open (outcharset, charset);
|
||||
convd->conv = iconv_open (outcharset, charset);
|
||||
|
||||
freea (outcharset);
|
||||
}
|
||||
else
|
||||
freea (outcharset);
|
||||
}
|
||||
else
|
||||
# endif
|
||||
convd->conv = iconv_open (outcharset, charset);
|
||||
convd->conv = iconv_open (outcharset, charset);
|
||||
# endif
|
||||
# endif
|
||||
|
||||
freea (charset);
|
||||
}
|
||||
}
|
||||
freea (charset);
|
||||
}
|
||||
}
|
||||
}
|
||||
convd->conv_tab = NULL;
|
||||
/* Here domain->conversions is still == new_conversions. */
|
||||
domain->nconversions++;
|
||||
}
|
||||
convd->conv_tab = NULL;
|
||||
/* Here domain->conversions is still == new_conversions. */
|
||||
domain->nconversions++;
|
||||
|
||||
found_convd:
|
||||
gl_rwlock_unlock (domain->conversions_lock);
|
||||
}
|
||||
|
||||
if (
|
||||
|
@ -1171,13 +1207,29 @@ _nl_find_msg (struct loaded_l10nfile *domain_file,
|
|||
handle this case by converting RESULTLEN bytes, including
|
||||
NULs. */
|
||||
|
||||
if (convd->conv_tab == NULL
|
||||
&& ((convd->conv_tab =
|
||||
/* This lock primarily protects the memory management variables
|
||||
freemem, freemem_size. It also protects write accesses to
|
||||
convd->conv_tab. It's not worth using a separate lock (such
|
||||
as domain->conversions_lock) for this purpose, because when
|
||||
modifying convd->conv_tab, we also need to lock freemem,
|
||||
freemem_size for most of the time. */
|
||||
__libc_lock_define_initialized (static, lock)
|
||||
|
||||
if (__builtin_expect (convd->conv_tab == NULL, 0))
|
||||
{
|
||||
__libc_lock_lock (lock);
|
||||
if (convd->conv_tab == NULL)
|
||||
{
|
||||
convd->conv_tab =
|
||||
(char **) calloc (nstrings + domain->n_sysdep_strings,
|
||||
sizeof (char *)))
|
||||
== NULL))
|
||||
/* Mark that we didn't succeed allocating a table. */
|
||||
convd->conv_tab = (char **) -1;
|
||||
sizeof (char *));
|
||||
if (convd->conv_tab != NULL)
|
||||
goto not_translated_yet;
|
||||
/* Mark that we didn't succeed allocating a table. */
|
||||
convd->conv_tab = (char **) -1;
|
||||
}
|
||||
__libc_lock_unlock (lock);
|
||||
}
|
||||
|
||||
if (__builtin_expect (convd->conv_tab == (char **) -1, 0))
|
||||
/* Nothing we can do, no more memory. We cannot use the
|
||||
|
@ -1191,7 +1243,6 @@ _nl_find_msg (struct loaded_l10nfile *domain_file,
|
|||
/* We use a bit more efficient memory handling.
|
||||
We allocate always larger blocks which get used over
|
||||
time. This is faster than many small allocations. */
|
||||
__libc_lock_define_initialized (static, lock)
|
||||
# define INITIAL_BLOCK_SIZE 4080
|
||||
static unsigned char *freemem;
|
||||
static size_t freemem_size;
|
||||
|
@ -1200,13 +1251,17 @@ _nl_find_msg (struct loaded_l10nfile *domain_file,
|
|||
unsigned char *outbuf;
|
||||
int malloc_count;
|
||||
# ifndef _LIBC
|
||||
transmem_block_t *transmem_list = NULL;
|
||||
transmem_block_t *transmem_list;
|
||||
# endif
|
||||
|
||||
__libc_lock_lock (lock);
|
||||
not_translated_yet:
|
||||
|
||||
inbuf = (const unsigned char *) result;
|
||||
outbuf = freemem + sizeof (size_t);
|
||||
# ifndef _LIBC
|
||||
transmem_list = NULL;
|
||||
# endif
|
||||
|
||||
malloc_count = 0;
|
||||
while (1)
|
||||
|
@ -1483,20 +1538,13 @@ guess_category_value (int category, const char *categoryname)
|
|||
# ifdef _LIBC
|
||||
locale = __current_locale_name (category);
|
||||
# else
|
||||
# if HAVE_STRUCT___LOCALE_STRUCT___NAMES && defined USE_IN_GETTEXT_TESTS
|
||||
/* The __names field is not public glibc API and must therefore not be used
|
||||
in code that is installed in public locations. */
|
||||
locale_t thread_locale = uselocale (NULL);
|
||||
if (thread_locale != LC_GLOBAL_LOCALE)
|
||||
{
|
||||
locale = thread_locale->__names[category];
|
||||
locale_defaulted = 0;
|
||||
}
|
||||
else
|
||||
locale_defaulted = 0;
|
||||
# if HAVE_USELOCALE
|
||||
locale = _nl_locale_name_thread_unsafe (category, categoryname);
|
||||
if (locale == NULL)
|
||||
# endif
|
||||
{
|
||||
locale = _nl_locale_name_posix (category, categoryname);
|
||||
locale_defaulted = 0;
|
||||
if (locale == NULL)
|
||||
{
|
||||
locale = _nl_locale_name_default ();
|
||||
|
@ -1584,7 +1632,6 @@ get_output_charset (struct binding *domainbinding)
|
|||
return _NL_CURRENT (LC_CTYPE, CODESET);
|
||||
# else
|
||||
# if HAVE_ICONV
|
||||
extern const char *locale_charset (void);
|
||||
return locale_charset ();
|
||||
# endif
|
||||
# endif
|
||||
|
@ -1617,6 +1664,10 @@ mempcpy (void *dest, const void *src, size_t n)
|
|||
}
|
||||
#endif
|
||||
|
||||
#if !_LIBC && !HAVE_TSEARCH
|
||||
# include "tsearch.c"
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef _LIBC
|
||||
/* If we want to free all resources we have to do some work at
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* Plural expression evaluation.
|
||||
Copyright (C) 2000-2003 Free Software Foundation, Inc.
|
||||
Copyright (C) 2000-2003, 2007 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Library General Public License as published
|
||||
|
@ -24,7 +24,7 @@
|
|||
STATIC
|
||||
unsigned long int
|
||||
internal_function
|
||||
plural_eval (struct expression *pexp, unsigned long int n)
|
||||
plural_eval (const struct expression *pexp, unsigned long int n)
|
||||
{
|
||||
switch (pexp->nargs)
|
||||
{
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (C) 1995-1998, 2000-2001, 2003, 2005 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1995-1998, 2000-2001, 2003, 2005, 2007 Free Software Foundation, Inc.
|
||||
Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
|
@ -105,7 +105,9 @@ _nl_explode_name (char *name,
|
|||
{
|
||||
*normalized_codeset = _nl_normalize_codeset (*codeset,
|
||||
cp - *codeset);
|
||||
if (strcmp (*codeset, *normalized_codeset) == 0)
|
||||
if (*normalized_codeset == NULL)
|
||||
return -1;
|
||||
else if (strcmp (*codeset, *normalized_codeset) == 0)
|
||||
free ((char *) *normalized_codeset);
|
||||
else
|
||||
mask |= XPG_NORM_CODESET;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* Handle list of needed message catalogs
|
||||
Copyright (C) 1995-1999, 2000-2001, 2003-2006 Free Software Foundation, Inc.
|
||||
Copyright (C) 1995-1999, 2000-2001, 2003-2007 Free Software Foundation, Inc.
|
||||
Written by Ulrich Drepper <drepper@gnu.org>, 1995.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
|
@ -144,6 +144,9 @@ _nl_find_domain (const char *dirname, char *locale,
|
|||
look for the language. Termination symbols are `_', '.', and `@'. */
|
||||
mask = _nl_explode_name (locale, &language, &modifier, &territory,
|
||||
&codeset, &normalized_codeset);
|
||||
if (mask == -1)
|
||||
/* This means we are out of core. */
|
||||
return NULL;
|
||||
|
||||
/* We need to protect modifying the _NL_LOADED_DOMAINS data. */
|
||||
gl_rwlock_wrlock (lock);
|
||||
|
@ -159,7 +162,7 @@ _nl_find_domain (const char *dirname, char *locale,
|
|||
|
||||
if (retval == NULL)
|
||||
/* This means we are out of core. */
|
||||
return NULL;
|
||||
goto out;
|
||||
|
||||
if (retval->decided <= 0)
|
||||
_nl_load_domain (retval, domainbinding);
|
||||
|
@ -179,6 +182,7 @@ _nl_find_domain (const char *dirname, char *locale,
|
|||
if (alias_value != NULL)
|
||||
free (locale);
|
||||
|
||||
out:
|
||||
/* The space for normalized_codeset is dynamically allocated. Free it. */
|
||||
if (mask & XPG_NORM_CODESET)
|
||||
free ((void *) normalized_codeset);
|
||||
|
|
102
intl/gettext.h
102
intl/gettext.h
|
@ -1,102 +0,0 @@
|
|||
/* Description of GNU message catalog format: general file layout.
|
||||
Copyright (C) 1995, 1997, 2000, 2001 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Library General Public License as published
|
||||
by the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
USA. */
|
||||
|
||||
#ifndef _GETTEXT_H
|
||||
#define _GETTEXT_H 1
|
||||
|
||||
#if HAVE_LIMITS_H || _LIBC
|
||||
# include <limits.h>
|
||||
#endif
|
||||
|
||||
/* @@ end of prolog @@ */
|
||||
|
||||
/* The magic number of the GNU message catalog format. */
|
||||
#define _MAGIC 0x950412de
|
||||
#define _MAGIC_SWAPPED 0xde120495
|
||||
|
||||
/* Revision number of the currently used .mo (binary) file format. */
|
||||
#define MO_REVISION_NUMBER 0
|
||||
|
||||
/* The following contortions are an attempt to use the C preprocessor
|
||||
to determine an unsigned integral type that is 32 bits wide. An
|
||||
alternative approach is to use autoconf's AC_CHECK_SIZEOF macro, but
|
||||
as of version autoconf-2.13, the AC_CHECK_SIZEOF macro doesn't work
|
||||
when cross-compiling. */
|
||||
|
||||
#if __STDC__
|
||||
# define UINT_MAX_32_BITS 4294967295U
|
||||
#else
|
||||
# define UINT_MAX_32_BITS 0xFFFFFFFF
|
||||
#endif
|
||||
|
||||
/* If UINT_MAX isn't defined, assume it's a 32-bit type.
|
||||
This should be valid for all systems GNU cares about because
|
||||
that doesn't include 16-bit systems, and only modern systems
|
||||
(that certainly have <limits.h>) have 64+-bit integral types. */
|
||||
|
||||
#ifndef UINT_MAX
|
||||
# define UINT_MAX UINT_MAX_32_BITS
|
||||
#endif
|
||||
|
||||
#if UINT_MAX == UINT_MAX_32_BITS
|
||||
typedef unsigned nls_uint32;
|
||||
#else
|
||||
# if USHRT_MAX == UINT_MAX_32_BITS
|
||||
typedef unsigned short nls_uint32;
|
||||
# else
|
||||
# if ULONG_MAX == UINT_MAX_32_BITS
|
||||
typedef unsigned long nls_uint32;
|
||||
# else
|
||||
/* The following line is intended to throw an error. Using #error is
|
||||
not portable enough. */
|
||||
"Cannot determine unsigned 32-bit data type."
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
/* Header for binary .mo file format. */
|
||||
struct mo_file_header
|
||||
{
|
||||
/* The magic number. */
|
||||
nls_uint32 magic;
|
||||
/* The revision number of the file format. */
|
||||
nls_uint32 revision;
|
||||
/* The number of strings pairs. */
|
||||
nls_uint32 nstrings;
|
||||
/* Offset of table with start offsets of original strings. */
|
||||
nls_uint32 orig_tab_offset;
|
||||
/* Offset of table with start offsets of translation strings. */
|
||||
nls_uint32 trans_tab_offset;
|
||||
/* Size of hashing table. */
|
||||
nls_uint32 hash_tab_size;
|
||||
/* Offset of first hashing entry. */
|
||||
nls_uint32 hash_tab_offset;
|
||||
};
|
||||
|
||||
struct string_desc
|
||||
{
|
||||
/* Length of addressed string. */
|
||||
nls_uint32 length;
|
||||
/* Offset of string in file. */
|
||||
nls_uint32 offset;
|
||||
};
|
||||
|
||||
/* @@ begin of epilog @@ */
|
||||
|
||||
#endif /* gettext.h */
|
|
@ -1,5 +1,5 @@
|
|||
/* Header describing internals of libintl library.
|
||||
Copyright (C) 1995-1999, 2000-2005 Free Software Foundation, Inc.
|
||||
Copyright (C) 1995-1999, 2000-2007, 2009-2010 Free Software Foundation, Inc.
|
||||
Written by Ulrich Drepper <drepper@cygnus.com>, 1995.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
|
@ -30,6 +30,14 @@
|
|||
# endif
|
||||
#endif
|
||||
|
||||
/* Handle multi-threaded applications. */
|
||||
#ifdef _LIBC
|
||||
# include <bits/libc-lock.h>
|
||||
# define gl_rwlock_define __libc_rwlock_define
|
||||
#else
|
||||
# include "lock.h"
|
||||
#endif
|
||||
|
||||
#ifdef _LIBC
|
||||
extern char *__gettext (const char *__msgid);
|
||||
extern char *__dgettext (const char *__domainname, const char *__msgid);
|
||||
|
@ -106,8 +114,12 @@ extern char *libintl_dcigettext (const char *__domainname,
|
|||
# define SWAP(i) bswap_32 (i)
|
||||
#else
|
||||
static inline nls_uint32
|
||||
# ifdef __cplusplus
|
||||
SWAP (nls_uint32 i)
|
||||
# else
|
||||
SWAP (i)
|
||||
nls_uint32 i;
|
||||
# endif
|
||||
{
|
||||
return (i << 24) | ((i & 0xff00) << 8) | ((i >> 8) & 0xff00) | (i >> 24);
|
||||
}
|
||||
|
@ -181,8 +193,9 @@ struct loaded_domain
|
|||
/* Cache of charset conversions of the translated strings. */
|
||||
struct converted_domain *conversions;
|
||||
size_t nconversions;
|
||||
gl_rwlock_define (, conversions_lock)
|
||||
|
||||
struct expression *plural;
|
||||
const struct expression *plural;
|
||||
unsigned long int nplurals;
|
||||
};
|
||||
|
||||
|
@ -215,10 +228,30 @@ extern LIBINTL_DLL_EXPORTED int _nl_msg_cat_cntr;
|
|||
#endif
|
||||
|
||||
#ifndef _LIBC
|
||||
const char *_nl_language_preferences_default (void);
|
||||
const char *_nl_locale_name_posix (int category, const char *categoryname);
|
||||
const char *_nl_locale_name_default (void);
|
||||
const char *_nl_locale_name (int category, const char *categoryname);
|
||||
extern const char *_nl_language_preferences_default (void);
|
||||
# define gl_locale_name_canonicalize _nl_locale_name_canonicalize
|
||||
extern void _nl_locale_name_canonicalize (char *name);
|
||||
# define gl_locale_name_from_win32_LANGID _nl_locale_name_from_win32_LANGID
|
||||
/* extern const char *_nl_locale_name_from_win32_LANGID (LANGID langid); */
|
||||
# define gl_locale_name_from_win32_LCID _nl_locale_name_from_win32_LCID
|
||||
/* extern const char *_nl_locale_name_from_win32_LCID (LCID lcid); */
|
||||
# define gl_locale_name_thread_unsafe _nl_locale_name_thread_unsafe
|
||||
extern const char *_nl_locale_name_thread_unsafe (int category,
|
||||
const char *categoryname);
|
||||
# define gl_locale_name_thread _nl_locale_name_thread
|
||||
/* extern const char *_nl_locale_name_thread (int category,
|
||||
const char *categoryname); */
|
||||
# define gl_locale_name_posix _nl_locale_name_posix
|
||||
extern const char *_nl_locale_name_posix (int category,
|
||||
const char *categoryname);
|
||||
# define gl_locale_name_environ _nl_locale_name_environ
|
||||
extern const char *_nl_locale_name_environ (int category,
|
||||
const char *categoryname);
|
||||
# define gl_locale_name_default _nl_locale_name_default
|
||||
extern const char *_nl_locale_name_default (void);
|
||||
# define gl_locale_name _nl_locale_name
|
||||
/* extern const char *_nl_locale_name (int category,
|
||||
const char *categoryname); */
|
||||
#endif
|
||||
|
||||
struct loaded_l10nfile *_nl_find_domain (const char *__dirname, char *__locale,
|
||||
|
@ -242,6 +275,37 @@ char *_nl_find_msg (struct loaded_l10nfile *domain_file,
|
|||
internal_function;
|
||||
#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 libintl_nl_default_dirname
|
||||
# define _nl_domain_bindings libintl_nl_domain_bindings
|
||||
#endif
|
||||
|
||||
/* Contains the default location of the message catalogs. */
|
||||
extern const char _nl_default_dirname[];
|
||||
#ifdef _LIBC
|
||||
libc_hidden_proto (_nl_default_dirname)
|
||||
#endif
|
||||
|
||||
/* List with bindings of specific domains. */
|
||||
extern struct binding *_nl_domain_bindings;
|
||||
|
||||
/* 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 libintl_nl_default_default_domain
|
||||
# define _nl_current_default_domain libintl_nl_current_default_domain
|
||||
#endif
|
||||
|
||||
/* Name of the default text domain. */
|
||||
extern const char _nl_default_default_domain[] attribute_hidden;
|
||||
|
||||
/* Default text domain in which entries for gettext(3) are to be found. */
|
||||
extern const char *_nl_current_default_domain attribute_hidden;
|
||||
|
||||
/* @@ begin of epilog @@ */
|
||||
|
||||
#endif /* gettextP.h */
|
||||
|
|
19
intl/gmo.h
19
intl/gmo.h
|
@ -1,5 +1,5 @@
|
|||
/* Description of GNU message catalog format: general file layout.
|
||||
Copyright (C) 1995, 1997, 2000-2002, 2004 Free Software Foundation, Inc.
|
||||
Copyright (C) 1995, 1997, 2000-2002, 2004, 2006 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Library General Public License as published
|
||||
|
@ -124,6 +124,15 @@ struct sysdep_segment
|
|||
nls_uint32 offset;
|
||||
};
|
||||
|
||||
/* Pair of a static and a system dependent segment, in struct sysdep_string. */
|
||||
struct segment_pair
|
||||
{
|
||||
/* Size of static segment. */
|
||||
nls_uint32 segsize;
|
||||
/* Reference to system dependent string segment, or ~0 at the end. */
|
||||
nls_uint32 sysdepref;
|
||||
};
|
||||
|
||||
/* Descriptor for system dependent string. */
|
||||
struct sysdep_string
|
||||
{
|
||||
|
@ -131,13 +140,7 @@ struct sysdep_string
|
|||
nls_uint32 offset;
|
||||
/* Alternating sequence of static and system dependent segments.
|
||||
The last segment is a static segment, including the trailing NUL. */
|
||||
struct segment_pair
|
||||
{
|
||||
/* Size of static segment. */
|
||||
nls_uint32 segsize;
|
||||
/* Reference to system dependent string segment, or ~0 at the end. */
|
||||
nls_uint32 sysdepref;
|
||||
} segments[1];
|
||||
struct segment_pair segments[1];
|
||||
};
|
||||
|
||||
/* Marker for the end of the segments[] array. This has the value 0xFFFFFFFF,
|
||||
|
|
|
@ -93,7 +93,7 @@ ngettext (const char *msgid1, const char *msgid2, unsigned long int n)
|
|||
DLL_EXPORTED
|
||||
char *
|
||||
dngettext (const char *domainname,
|
||||
const char *msgid1, const char *msgid2, unsigned long int n)
|
||||
const char *msgid1, const char *msgid2, unsigned long int n)
|
||||
{
|
||||
return libintl_dngettext (domainname, msgid1, msgid2, n);
|
||||
}
|
||||
|
@ -102,8 +102,8 @@ dngettext (const char *domainname,
|
|||
DLL_EXPORTED
|
||||
char *
|
||||
dcngettext (const char *domainname,
|
||||
const char *msgid1, const char *msgid2, unsigned long int n,
|
||||
int category)
|
||||
const char *msgid1, const char *msgid2, unsigned long int n,
|
||||
int category)
|
||||
{
|
||||
return libintl_dcngettext (domainname, msgid1, msgid2, n, category);
|
||||
}
|
||||
|
|
|
@ -23,14 +23,14 @@
|
|||
/* Ensure that the variable x is exported from the library, and that a
|
||||
pseudo-variable IMP(x) is available. */
|
||||
#define VARIABLE(x) \
|
||||
/* Export x without redefining x. This code was found by compiling a \
|
||||
snippet: \
|
||||
extern __declspec(dllexport) int x; int x = 42; */ \
|
||||
asm (".section .drectve\n"); \
|
||||
asm (".ascii \" -export:" #x ",data\"\n"); \
|
||||
asm (".data\n"); \
|
||||
/* Allocate a pseudo-variable IMP(x). */ \
|
||||
extern int x; \
|
||||
/* Export x without redefining x. This code was found by compiling a \
|
||||
snippet: \
|
||||
extern __declspec(dllexport) int x; int x = 42; */ \
|
||||
asm (".section .drectve\n"); \
|
||||
asm (".ascii \" -export:" #x ",data\"\n"); \
|
||||
asm (".data\n"); \
|
||||
/* Allocate a pseudo-variable IMP(x). */ \
|
||||
extern int x; \
|
||||
void * IMP(x) = &x;
|
||||
|
||||
VARIABLE(libintl_version)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (C) 1995-1999, 2000-2006 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1995-1999, 2000-2007 Free Software Foundation, Inc.
|
||||
Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
|
@ -346,7 +346,7 @@ _nl_make_l10nflist (struct loaded_l10nfile **l10nfile_list,
|
|||
const char *
|
||||
_nl_normalize_codeset (const char *codeset, size_t name_len)
|
||||
{
|
||||
int len = 0;
|
||||
size_t len = 0;
|
||||
int only_digit = 1;
|
||||
char *retval;
|
||||
char *wp;
|
||||
|
|
359
intl/langprefs.c
359
intl/langprefs.c
|
@ -1,5 +1,5 @@
|
|||
/* Determine the user's language preferences.
|
||||
Copyright (C) 2004-2006 Free Software Foundation, Inc.
|
||||
Copyright (C) 2004-2007 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Library General Public License as published
|
||||
|
@ -16,7 +16,8 @@
|
|||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
USA. */
|
||||
|
||||
/* Written by Bruno Haible <bruno@clisp.org>. */
|
||||
/* Written by Bruno Haible <bruno@clisp.org>.
|
||||
Win32 code originally by Michele Cicciotti <hackbunny@reactos.com>. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
|
@ -33,6 +34,197 @@
|
|||
extern void _nl_locale_name_canonicalize (char *name);
|
||||
#endif
|
||||
|
||||
#if defined _WIN32 || defined __WIN32__
|
||||
# define WIN32_NATIVE
|
||||
#endif
|
||||
|
||||
#ifdef WIN32_NATIVE
|
||||
# define WIN32_LEAN_AND_MEAN
|
||||
# include <windows.h>
|
||||
|
||||
# ifndef MUI_LANGUAGE_NAME
|
||||
# define MUI_LANGUAGE_NAME 8
|
||||
# endif
|
||||
# ifndef STATUS_BUFFER_OVERFLOW
|
||||
# define STATUS_BUFFER_OVERFLOW 0x80000005
|
||||
# endif
|
||||
|
||||
extern void _nl_locale_name_canonicalize (char *name);
|
||||
extern const char *_nl_locale_name_from_win32_LANGID (LANGID langid);
|
||||
extern const char *_nl_locale_name_from_win32_LCID (LCID lcid);
|
||||
|
||||
/* Get the preferences list through the MUI APIs. This works on Windows Vista
|
||||
and newer. */
|
||||
static const char *
|
||||
_nl_language_preferences_win32_mui (HMODULE kernel32)
|
||||
{
|
||||
/* DWORD GetUserPreferredUILanguages (ULONG dwFlags,
|
||||
PULONG pulNumLanguages,
|
||||
PWSTR pwszLanguagesBuffer,
|
||||
PULONG pcchLanguagesBuffer); */
|
||||
typedef DWORD (WINAPI *GetUserPreferredUILanguages_func) (ULONG, PULONG, PWSTR, PULONG);
|
||||
GetUserPreferredUILanguages_func p_GetUserPreferredUILanguages;
|
||||
|
||||
p_GetUserPreferredUILanguages =
|
||||
(GetUserPreferredUILanguages_func)
|
||||
GetProcAddress (kernel32, "GetUserPreferredUILanguages");
|
||||
if (p_GetUserPreferredUILanguages != NULL)
|
||||
{
|
||||
ULONG num_languages;
|
||||
ULONG bufsize;
|
||||
DWORD ret;
|
||||
|
||||
bufsize = 0;
|
||||
ret = p_GetUserPreferredUILanguages (MUI_LANGUAGE_NAME,
|
||||
&num_languages,
|
||||
NULL, &bufsize);
|
||||
if (ret == 0
|
||||
&& GetLastError () == STATUS_BUFFER_OVERFLOW
|
||||
&& bufsize > 0)
|
||||
{
|
||||
WCHAR *buffer = (WCHAR *) malloc (bufsize * sizeof (WCHAR));
|
||||
if (buffer != NULL)
|
||||
{
|
||||
ret = p_GetUserPreferredUILanguages (MUI_LANGUAGE_NAME,
|
||||
&num_languages,
|
||||
buffer, &bufsize);
|
||||
if (ret)
|
||||
{
|
||||
/* Convert the list from NUL-delimited WCHAR[] Win32 locale
|
||||
names to colon-delimited char[] Unix locale names.
|
||||
We assume that all these locale names are in ASCII,
|
||||
nonempty and contain no colons. */
|
||||
char *languages =
|
||||
(char *) malloc (bufsize + num_languages * 10 + 1);
|
||||
if (languages != NULL)
|
||||
{
|
||||
const WCHAR *p = buffer;
|
||||
char *q = languages;
|
||||
ULONG i;
|
||||
for (i = 0; i < num_languages; i++)
|
||||
{
|
||||
char *q1;
|
||||
char *q2;
|
||||
|
||||
q1 = q;
|
||||
if (i > 0)
|
||||
*q++ = ':';
|
||||
q2 = q;
|
||||
for (; *p != (WCHAR)'\0'; p++)
|
||||
{
|
||||
if ((unsigned char) *p != *p || *p == ':')
|
||||
{
|
||||
/* A non-ASCII character or a colon inside
|
||||
the Win32 locale name! Punt. */
|
||||
q = q1;
|
||||
break;
|
||||
}
|
||||
*q++ = (unsigned char) *p;
|
||||
}
|
||||
if (q == q1)
|
||||
/* An unexpected Win32 locale name occurred. */
|
||||
break;
|
||||
*q = '\0';
|
||||
_nl_locale_name_canonicalize (q2);
|
||||
q = q2 + strlen (q2);
|
||||
p++;
|
||||
}
|
||||
*q = '\0';
|
||||
if (q > languages)
|
||||
{
|
||||
free (buffer);
|
||||
return languages;
|
||||
}
|
||||
free (languages);
|
||||
}
|
||||
}
|
||||
free (buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Get a preference. This works on Windows ME and newer. */
|
||||
static const char *
|
||||
_nl_language_preferences_win32_ME (HMODULE kernel32)
|
||||
{
|
||||
/* LANGID GetUserDefaultUILanguage (void); */
|
||||
typedef LANGID (WINAPI *GetUserDefaultUILanguage_func) (void);
|
||||
GetUserDefaultUILanguage_func p_GetUserDefaultUILanguage;
|
||||
|
||||
p_GetUserDefaultUILanguage =
|
||||
(GetUserDefaultUILanguage_func)
|
||||
GetProcAddress (kernel32, "GetUserDefaultUILanguage");
|
||||
if (p_GetUserDefaultUILanguage != NULL)
|
||||
return _nl_locale_name_from_win32_LANGID (p_GetUserDefaultUILanguage ());
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Get a preference. This works on Windows 95 and newer. */
|
||||
static const char *
|
||||
_nl_language_preferences_win32_95 ()
|
||||
{
|
||||
HKEY desktop_resource_locale_key;
|
||||
|
||||
if (RegOpenKeyExA (HKEY_CURRENT_USER,
|
||||
"Control Panel\\Desktop\\ResourceLocale",
|
||||
0, KEY_QUERY_VALUE, &desktop_resource_locale_key)
|
||||
== NO_ERROR)
|
||||
{
|
||||
DWORD type;
|
||||
char data[8 + 1];
|
||||
DWORD data_size = sizeof (data);
|
||||
DWORD ret;
|
||||
|
||||
ret = RegQueryValueExA (desktop_resource_locale_key, NULL, NULL,
|
||||
&type, data, &data_size);
|
||||
RegCloseKey (desktop_resource_locale_key);
|
||||
|
||||
if (ret == NO_ERROR)
|
||||
{
|
||||
/* We expect a string, at most 8 bytes long, that parses as a
|
||||
hexadecimal number. */
|
||||
if (type == REG_SZ
|
||||
&& data_size <= sizeof (data)
|
||||
&& (data_size < sizeof (data)
|
||||
|| data[sizeof (data) - 1] == '\0'))
|
||||
{
|
||||
LCID lcid;
|
||||
char *endp;
|
||||
/* Ensure it's NUL terminated. */
|
||||
if (data_size < sizeof (data))
|
||||
data[data_size] = '\0';
|
||||
/* Parse it as a hexadecimal number. */
|
||||
lcid = strtoul (data, &endp, 16);
|
||||
if (endp > data && *endp == '\0')
|
||||
return _nl_locale_name_from_win32_LCID (lcid);
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Get the system's preference. This can be used as a fallback. */
|
||||
static BOOL CALLBACK
|
||||
ret_first_language (HMODULE h, LPCSTR type, LPCSTR name, WORD lang, LONG_PTR param)
|
||||
{
|
||||
*(const char **)param = _nl_locale_name_from_win32_LANGID (lang);
|
||||
return FALSE;
|
||||
}
|
||||
static const char *
|
||||
_nl_language_preferences_win32_system (HMODULE kernel32)
|
||||
{
|
||||
const char *languages = NULL;
|
||||
/* Ignore the warning on mingw here. mingw has a wrong definition of the last
|
||||
parameter type of ENUMRESLANGPROC. */
|
||||
EnumResourceLanguages (kernel32, RT_VERSION, MAKEINTRESOURCE (1),
|
||||
ret_first_language, (LONG_PTR)&languages);
|
||||
return languages;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* Determine the user's language preferences, as a colon separated list of
|
||||
locale names in XPG syntax
|
||||
language[_territory][.codeset][@modifier]
|
||||
|
@ -51,75 +243,108 @@ _nl_language_preferences_default (void)
|
|||
|
||||
if (!cache_initialized)
|
||||
{
|
||||
CFTypeRef preferences =
|
||||
CFPreferencesCopyAppValue (CFSTR ("AppleLanguages"),
|
||||
kCFPreferencesCurrentApplication);
|
||||
if (preferences != NULL
|
||||
&& CFGetTypeID (preferences) == CFArrayGetTypeID ())
|
||||
{
|
||||
CFArrayRef prefArray = (CFArrayRef)preferences;
|
||||
int n = CFArrayGetCount (prefArray);
|
||||
char buf[256];
|
||||
size_t size = 0;
|
||||
int i;
|
||||
CFTypeRef preferences =
|
||||
CFPreferencesCopyAppValue (CFSTR ("AppleLanguages"),
|
||||
kCFPreferencesCurrentApplication);
|
||||
if (preferences != NULL
|
||||
&& CFGetTypeID (preferences) == CFArrayGetTypeID ())
|
||||
{
|
||||
CFArrayRef prefArray = (CFArrayRef)preferences;
|
||||
int n = CFArrayGetCount (prefArray);
|
||||
char buf[256];
|
||||
size_t size = 0;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
CFTypeRef element = CFArrayGetValueAtIndex (prefArray, i);
|
||||
if (element != NULL
|
||||
&& CFGetTypeID (element) == CFStringGetTypeID ()
|
||||
&& CFStringGetCString ((CFStringRef)element,
|
||||
buf, sizeof (buf),
|
||||
kCFStringEncodingASCII))
|
||||
{
|
||||
_nl_locale_name_canonicalize (buf);
|
||||
size += strlen (buf) + 1;
|
||||
/* Most GNU programs use msgids in English and don't ship
|
||||
an en.mo message catalog. Therefore when we see "en"
|
||||
in the preferences list, arrange for gettext() to
|
||||
return the msgid, and ignore all further elements of
|
||||
the preferences list. */
|
||||
if (strcmp (buf, "en") == 0)
|
||||
break;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
if (size > 0)
|
||||
{
|
||||
char *languages = (char *) malloc (size);
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
CFTypeRef element = CFArrayGetValueAtIndex (prefArray, i);
|
||||
if (element != NULL
|
||||
&& CFGetTypeID (element) == CFStringGetTypeID ()
|
||||
&& CFStringGetCString ((CFStringRef)element,
|
||||
buf, sizeof (buf),
|
||||
kCFStringEncodingASCII))
|
||||
{
|
||||
_nl_locale_name_canonicalize (buf);
|
||||
size += strlen (buf) + 1;
|
||||
/* Most GNU programs use msgids in English and don't ship
|
||||
an en.mo message catalog. Therefore when we see "en"
|
||||
in the preferences list, arrange for gettext() to
|
||||
return the msgid, and ignore all further elements of
|
||||
the preferences list. */
|
||||
if (strcmp (buf, "en") == 0)
|
||||
break;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
if (size > 0)
|
||||
{
|
||||
char *languages = (char *) malloc (size);
|
||||
|
||||
if (languages != NULL)
|
||||
{
|
||||
char *p = languages;
|
||||
if (languages != NULL)
|
||||
{
|
||||
char *p = languages;
|
||||
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
CFTypeRef element =
|
||||
CFArrayGetValueAtIndex (prefArray, i);
|
||||
if (element != NULL
|
||||
&& CFGetTypeID (element) == CFStringGetTypeID ()
|
||||
&& CFStringGetCString ((CFStringRef)element,
|
||||
buf, sizeof (buf),
|
||||
kCFStringEncodingASCII))
|
||||
{
|
||||
_nl_locale_name_canonicalize (buf);
|
||||
strcpy (p, buf);
|
||||
p += strlen (buf);
|
||||
*p++ = ':';
|
||||
if (strcmp (buf, "en") == 0)
|
||||
break;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
*--p = '\0';
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
CFTypeRef element =
|
||||
CFArrayGetValueAtIndex (prefArray, i);
|
||||
if (element != NULL
|
||||
&& CFGetTypeID (element) == CFStringGetTypeID ()
|
||||
&& CFStringGetCString ((CFStringRef)element,
|
||||
buf, sizeof (buf),
|
||||
kCFStringEncodingASCII))
|
||||
{
|
||||
_nl_locale_name_canonicalize (buf);
|
||||
strcpy (p, buf);
|
||||
p += strlen (buf);
|
||||
*p++ = ':';
|
||||
if (strcmp (buf, "en") == 0)
|
||||
break;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
*--p = '\0';
|
||||
|
||||
cached_languages = languages;
|
||||
}
|
||||
}
|
||||
}
|
||||
cache_initialized = 1;
|
||||
cached_languages = languages;
|
||||
}
|
||||
}
|
||||
}
|
||||
cache_initialized = 1;
|
||||
}
|
||||
if (cached_languages != NULL)
|
||||
return cached_languages;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef WIN32_NATIVE
|
||||
{
|
||||
/* Cache the preferences list, since computing it is expensive. */
|
||||
static const char *cached_languages;
|
||||
static int cache_initialized;
|
||||
|
||||
/* Activate the new code only when the GETTEXT_MUI environment variable is
|
||||
set, for the time being, since the new code is not well tested. */
|
||||
if (!cache_initialized && getenv ("GETTEXT_MUI") != NULL)
|
||||
{
|
||||
const char *languages = NULL;
|
||||
HMODULE kernel32 = GetModuleHandle ("kernel32");
|
||||
|
||||
if (kernel32 != NULL)
|
||||
languages = _nl_language_preferences_win32_mui (kernel32);
|
||||
|
||||
if (languages == NULL && kernel32 != NULL)
|
||||
languages = _nl_language_preferences_win32_ME (kernel32);
|
||||
|
||||
if (languages == NULL)
|
||||
languages = _nl_language_preferences_win32_95 ();
|
||||
|
||||
if (languages == NULL && kernel32 != NULL)
|
||||
languages = _nl_language_preferences_win32_system (kernel32);
|
||||
|
||||
cached_languages = languages;
|
||||
cache_initialized = 1;
|
||||
}
|
||||
if (cached_languages != NULL)
|
||||
return cached_languages;
|
||||
|
|
|
@ -1,49 +0,0 @@
|
|||
/* Convenience header for conditional use of GNU <libintl.h>.
|
||||
Copyright (C) 1995-1998, 2000, 2001 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Library General Public License as published
|
||||
by the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
USA. */
|
||||
|
||||
#ifndef _LIBGETTEXT_H
|
||||
#define _LIBGETTEXT_H 1
|
||||
|
||||
/* NLS can be disabled through the configure --disable-nls option. */
|
||||
#if ENABLE_NLS
|
||||
|
||||
/* Get declarations of GNU message catalog functions. */
|
||||
# include <libintl.h>
|
||||
|
||||
#else
|
||||
|
||||
# define gettext(Msgid) (Msgid)
|
||||
# define dgettext(Domainname, Msgid) (Msgid)
|
||||
# define dcgettext(Domainname, Msgid, Category) (Msgid)
|
||||
# define ngettext(Msgid1, Msgid2, N) \
|
||||
((N) == 1 ? (char *) (Msgid1) : (char *) (Msgid2))
|
||||
# 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
|
||||
|
||||
/* For automatical extraction of messages sometimes no real
|
||||
translation is needed. Instead the string itself is the result. */
|
||||
#define gettext_noop(Str) (Str)
|
||||
|
||||
#endif /* _LIBGETTEXT_H */
|
|
@ -1,5 +1,5 @@
|
|||
/* Message catalogs for internationalization.
|
||||
Copyright (C) 1995-1997, 2000-2006 Free Software Foundation, Inc.
|
||||
Copyright (C) 1995-1997, 2000-2010 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Library General Public License as published
|
||||
|
@ -17,9 +17,12 @@
|
|||
USA. */
|
||||
|
||||
#ifndef _LIBINTL_H
|
||||
#define _LIBINTL_H 1
|
||||
#define _LIBINTL_H 1
|
||||
|
||||
#include <locale.h>
|
||||
#if (defined __APPLE__ && defined __MACH__) && @HAVE_NEWLOCALE@
|
||||
# include <xlocale.h>
|
||||
#endif
|
||||
|
||||
/* The LC_MESSAGES locale category is the category used by the functions
|
||||
gettext() and dgettext(). It is specified in POSIX, but not in ANSI C.
|
||||
|
@ -53,7 +56,7 @@ extern "C" {
|
|||
|
||||
|
||||
/* Version number: (major<<16) + (minor<<8) + subminor */
|
||||
#define LIBINTL_VERSION 0x001000
|
||||
#define LIBINTL_VERSION 0x001201
|
||||
extern int libintl_version;
|
||||
|
||||
|
||||
|
@ -88,7 +91,7 @@ extern int libintl_version;
|
|||
If he doesn't, we choose the method. A third possible method is
|
||||
_INTL_REDIRECT_ASM, supported only by GCC. */
|
||||
#if !(defined _INTL_REDIRECT_INLINE || defined _INTL_REDIRECT_MACROS)
|
||||
# if __GNUC__ >= 2 && !(__APPLE_CC__ > 1) && !defined __MINGW32__ && !(__GNUC__ == 2 && defined _AIX) && (defined __STDC__ || defined __cplusplus)
|
||||
# if defined __GNUC__ && __GNUC__ >= 2 && !(defined __APPLE_CC__ && __APPLE_CC__ > 1) && !defined __MINGW32__ && !(__GNUC__ == 2 && defined _AIX) && (defined __STDC__ || defined __cplusplus)
|
||||
# define _INTL_REDIRECT_ASM
|
||||
# else
|
||||
# ifdef __cplusplus
|
||||
|
@ -110,7 +113,7 @@ extern int libintl_version;
|
|||
/* _INTL_MAY_RETURN_STRING_ARG(n) declares that the given function may return
|
||||
its n-th argument literally. This enables GCC to warn for example about
|
||||
printf (gettext ("foo %y")). */
|
||||
#if __GNUC__ >= 3 && !(__APPLE_CC__ > 1 && defined __cplusplus)
|
||||
#if defined __GNUC__ && __GNUC__ >= 3 && !(defined __APPLE_CC__ && __APPLE_CC__ > 1 && defined __cplusplus)
|
||||
# define _INTL_MAY_RETURN_STRING_ARG(n) __attribute__ ((__format_arg__ (n)))
|
||||
#else
|
||||
# define _INTL_MAY_RETURN_STRING_ARG(n)
|
||||
|
@ -157,10 +160,10 @@ extern char *dgettext (const char *__domainname, const char *__msgid)
|
|||
locale. */
|
||||
#ifdef _INTL_REDIRECT_INLINE
|
||||
extern char *libintl_dcgettext (const char *__domainname, const char *__msgid,
|
||||
int __category)
|
||||
int __category)
|
||||
_INTL_MAY_RETURN_STRING_ARG (2);
|
||||
static inline char *dcgettext (const char *__domainname, const char *__msgid,
|
||||
int __category)
|
||||
int __category)
|
||||
{
|
||||
return libintl_dcgettext (__domainname, __msgid, __category);
|
||||
}
|
||||
|
@ -169,7 +172,7 @@ static inline char *dcgettext (const char *__domainname, const char *__msgid,
|
|||
# define dcgettext libintl_dcgettext
|
||||
#endif
|
||||
extern char *dcgettext (const char *__domainname, const char *__msgid,
|
||||
int __category)
|
||||
int __category)
|
||||
_INTL_ASM (libintl_dcgettext)
|
||||
_INTL_MAY_RETURN_STRING_ARG (2);
|
||||
#endif
|
||||
|
@ -179,10 +182,10 @@ extern char *dcgettext (const char *__domainname, const char *__msgid,
|
|||
number N. */
|
||||
#ifdef _INTL_REDIRECT_INLINE
|
||||
extern char *libintl_ngettext (const char *__msgid1, const char *__msgid2,
|
||||
unsigned long int __n)
|
||||
unsigned long int __n)
|
||||
_INTL_MAY_RETURN_STRING_ARG (1) _INTL_MAY_RETURN_STRING_ARG (2);
|
||||
static inline char *ngettext (const char *__msgid1, const char *__msgid2,
|
||||
unsigned long int __n)
|
||||
unsigned long int __n)
|
||||
{
|
||||
return libintl_ngettext (__msgid1, __msgid2, __n);
|
||||
}
|
||||
|
@ -191,7 +194,7 @@ static inline char *ngettext (const char *__msgid1, const char *__msgid2,
|
|||
# define ngettext libintl_ngettext
|
||||
#endif
|
||||
extern char *ngettext (const char *__msgid1, const char *__msgid2,
|
||||
unsigned long int __n)
|
||||
unsigned long int __n)
|
||||
_INTL_ASM (libintl_ngettext)
|
||||
_INTL_MAY_RETURN_STRING_ARG (1) _INTL_MAY_RETURN_STRING_ARG (2);
|
||||
#endif
|
||||
|
@ -200,10 +203,10 @@ extern char *ngettext (const char *__msgid1, const char *__msgid2,
|
|||
number N. */
|
||||
#ifdef _INTL_REDIRECT_INLINE
|
||||
extern char *libintl_dngettext (const char *__domainname, const char *__msgid1,
|
||||
const char *__msgid2, unsigned long int __n)
|
||||
const char *__msgid2, unsigned long int __n)
|
||||
_INTL_MAY_RETURN_STRING_ARG (2) _INTL_MAY_RETURN_STRING_ARG (3);
|
||||
static inline char *dngettext (const char *__domainname, const char *__msgid1,
|
||||
const char *__msgid2, unsigned long int __n)
|
||||
const char *__msgid2, unsigned long int __n)
|
||||
{
|
||||
return libintl_dngettext (__domainname, __msgid1, __msgid2, __n);
|
||||
}
|
||||
|
@ -212,8 +215,8 @@ static inline char *dngettext (const char *__domainname, const char *__msgid1,
|
|||
# define dngettext libintl_dngettext
|
||||
#endif
|
||||
extern char *dngettext (const char *__domainname,
|
||||
const char *__msgid1, const char *__msgid2,
|
||||
unsigned long int __n)
|
||||
const char *__msgid1, const char *__msgid2,
|
||||
unsigned long int __n)
|
||||
_INTL_ASM (libintl_dngettext)
|
||||
_INTL_MAY_RETURN_STRING_ARG (2) _INTL_MAY_RETURN_STRING_ARG (3);
|
||||
#endif
|
||||
|
@ -222,12 +225,12 @@ extern char *dngettext (const char *__domainname,
|
|||
number N. */
|
||||
#ifdef _INTL_REDIRECT_INLINE
|
||||
extern char *libintl_dcngettext (const char *__domainname,
|
||||
const char *__msgid1, const char *__msgid2,
|
||||
unsigned long int __n, int __category)
|
||||
const char *__msgid1, const char *__msgid2,
|
||||
unsigned long int __n, int __category)
|
||||
_INTL_MAY_RETURN_STRING_ARG (2) _INTL_MAY_RETURN_STRING_ARG (3);
|
||||
static inline char *dcngettext (const char *__domainname,
|
||||
const char *__msgid1, const char *__msgid2,
|
||||
unsigned long int __n, int __category)
|
||||
const char *__msgid1, const char *__msgid2,
|
||||
unsigned long int __n, int __category)
|
||||
{
|
||||
return libintl_dcngettext (__domainname, __msgid1, __msgid2, __n, __category);
|
||||
}
|
||||
|
@ -236,8 +239,8 @@ static inline char *dcngettext (const char *__domainname,
|
|||
# define dcngettext libintl_dcngettext
|
||||
#endif
|
||||
extern char *dcngettext (const char *__domainname,
|
||||
const char *__msgid1, const char *__msgid2,
|
||||
unsigned long int __n, int __category)
|
||||
const char *__msgid1, const char *__msgid2,
|
||||
unsigned long int __n, int __category)
|
||||
_INTL_ASM (libintl_dcngettext)
|
||||
_INTL_MAY_RETURN_STRING_ARG (2) _INTL_MAY_RETURN_STRING_ARG (3);
|
||||
#endif
|
||||
|
@ -266,9 +269,9 @@ extern char *textdomain (const char *__domainname)
|
|||
in DIRNAME rather than in the system locale data base. */
|
||||
#ifdef _INTL_REDIRECT_INLINE
|
||||
extern char *libintl_bindtextdomain (const char *__domainname,
|
||||
const char *__dirname);
|
||||
const char *__dirname);
|
||||
static inline char *bindtextdomain (const char *__domainname,
|
||||
const char *__dirname)
|
||||
const char *__dirname)
|
||||
{
|
||||
return libintl_bindtextdomain (__domainname, __dirname);
|
||||
}
|
||||
|
@ -284,9 +287,9 @@ extern char *bindtextdomain (const char *__domainname, const char *__dirname)
|
|||
DOMAINNAME message catalog will be returned. */
|
||||
#ifdef _INTL_REDIRECT_INLINE
|
||||
extern char *libintl_bind_textdomain_codeset (const char *__domainname,
|
||||
const char *__codeset);
|
||||
const char *__codeset);
|
||||
static inline char *bind_textdomain_codeset (const char *__domainname,
|
||||
const char *__codeset)
|
||||
const char *__codeset)
|
||||
{
|
||||
return libintl_bind_textdomain_codeset (__domainname, __codeset);
|
||||
}
|
||||
|
@ -295,7 +298,7 @@ static inline char *bind_textdomain_codeset (const char *__domainname,
|
|||
# define bind_textdomain_codeset libintl_bind_textdomain_codeset
|
||||
#endif
|
||||
extern char *bind_textdomain_codeset (const char *__domainname,
|
||||
const char *__codeset)
|
||||
const char *__codeset)
|
||||
_INTL_ASM (libintl_bind_textdomain_codeset);
|
||||
#endif
|
||||
|
||||
|
@ -316,58 +319,84 @@ extern char *bind_textdomain_codeset (const char *__domainname,
|
|||
#include <stddef.h>
|
||||
|
||||
/* Get va_list. */
|
||||
#if __STDC__ || defined __cplusplus || defined _MSC_VER
|
||||
#if (defined __STDC__ && __STDC__) || defined __cplusplus || defined _MSC_VER
|
||||
# include <stdarg.h>
|
||||
#else
|
||||
# include <varargs.h>
|
||||
#endif
|
||||
|
||||
#if !(defined fprintf && defined _GL_STDIO_H) /* don't override gnulib */
|
||||
#undef fprintf
|
||||
#define fprintf libintl_fprintf
|
||||
extern int fprintf (FILE *, const char *, ...);
|
||||
#endif
|
||||
#if !(defined vfprintf && defined _GL_STDIO_H) /* don't override gnulib */
|
||||
#undef vfprintf
|
||||
#define vfprintf libintl_vfprintf
|
||||
extern int vfprintf (FILE *, const char *, va_list);
|
||||
#endif
|
||||
|
||||
#if !(defined printf && defined _GL_STDIO_H) /* don't override gnulib */
|
||||
#undef printf
|
||||
#if defined __NetBSD__ || defined __CYGWIN__ || defined __MINGW32__
|
||||
#if defined __NetBSD__ || defined __BEOS__ || defined __CYGWIN__ || defined __MINGW32__
|
||||
/* Don't break __attribute__((format(printf,M,N))).
|
||||
This redefinition is only possible because the libc in NetBSD, Cygwin,
|
||||
mingw does not have a function __printf__. */
|
||||
mingw does not have a function __printf__.
|
||||
Alternatively, we could have done this redirection only when compiling with
|
||||
__GNUC__, together with a symbol redirection:
|
||||
extern int printf (const char *, ...)
|
||||
__asm__ (#__USER_LABEL_PREFIX__ "libintl_printf");
|
||||
But doing it now would introduce a binary incompatibility with already
|
||||
distributed versions of libintl on these systems. */
|
||||
# define libintl_printf __printf__
|
||||
#endif
|
||||
#define printf libintl_printf
|
||||
extern int printf (const char *, ...);
|
||||
#endif
|
||||
#if !(defined vprintf && defined _GL_STDIO_H) /* don't override gnulib */
|
||||
#undef vprintf
|
||||
#define vprintf libintl_vprintf
|
||||
extern int vprintf (const char *, va_list);
|
||||
#endif
|
||||
|
||||
#if !(defined sprintf && defined _GL_STDIO_H) /* don't override gnulib */
|
||||
#undef sprintf
|
||||
#define sprintf libintl_sprintf
|
||||
extern int sprintf (char *, const char *, ...);
|
||||
#endif
|
||||
#if !(defined vsprintf && defined _GL_STDIO_H) /* don't override gnulib */
|
||||
#undef vsprintf
|
||||
#define vsprintf libintl_vsprintf
|
||||
extern int vsprintf (char *, const char *, va_list);
|
||||
#endif
|
||||
|
||||
#if @HAVE_SNPRINTF@
|
||||
|
||||
#if !(defined snprintf && defined _GL_STDIO_H) /* don't override gnulib */
|
||||
#undef snprintf
|
||||
#define snprintf libintl_snprintf
|
||||
extern int snprintf (char *, size_t, const char *, ...);
|
||||
#endif
|
||||
#if !(defined vsnprintf && defined _GL_STDIO_H) /* don't override gnulib */
|
||||
#undef vsnprintf
|
||||
#define vsnprintf libintl_vsnprintf
|
||||
extern int vsnprintf (char *, size_t, const char *, va_list);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#if @HAVE_ASPRINTF@
|
||||
|
||||
#if !(defined asprintf && defined _GL_STDIO_H) /* don't override gnulib */
|
||||
#undef asprintf
|
||||
#define asprintf libintl_asprintf
|
||||
extern int asprintf (char **, const char *, ...);
|
||||
#endif
|
||||
#if !(defined vasprintf && defined _GL_STDIO_H) /* don't override gnulib */
|
||||
#undef vasprintf
|
||||
#define vasprintf libintl_vasprintf
|
||||
extern int vasprintf (char **, const char *, va_list);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -399,6 +428,24 @@ extern int vswprintf (wchar_t *, size_t, const wchar_t *, va_list);
|
|||
#endif
|
||||
|
||||
|
||||
/* Support for the locale chosen by the user. */
|
||||
#if (defined __APPLE__ && defined __MACH__) || defined _WIN32 || defined __WIN32__ || defined __CYGWIN__
|
||||
|
||||
#undef setlocale
|
||||
#define setlocale libintl_setlocale
|
||||
extern char *setlocale (int, const char *);
|
||||
|
||||
#if @HAVE_NEWLOCALE@
|
||||
|
||||
#undef newlocale
|
||||
#define newlocale libintl_newlocale
|
||||
extern locale_t newlocale (int, const char *, locale_t);
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/* Support for relocatable packages. */
|
||||
|
||||
/* Sets the original and the current installation prefix of the package.
|
||||
|
@ -409,7 +456,7 @@ extern int vswprintf (wchar_t *, size_t, const wchar_t *, va_list);
|
|||
#define libintl_set_relocation_prefix libintl_set_relocation_prefix
|
||||
extern void
|
||||
libintl_set_relocation_prefix (const char *orig_prefix,
|
||||
const char *curr_prefix);
|
||||
const char *curr_prefix);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
38
intl/libintl.rc
Normal file
38
intl/libintl.rc
Normal file
|
@ -0,0 +1,38 @@
|
|||
/* Resources for intl.dll */
|
||||
|
||||
#include <winver.h>
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION PACKAGE_VERSION_MAJOR,PACKAGE_VERSION_MINOR,PACKAGE_VERSION_SUBMINOR,0
|
||||
PRODUCTVERSION PACKAGE_VERSION_MAJOR,PACKAGE_VERSION_MINOR,PACKAGE_VERSION_SUBMINOR,0
|
||||
FILEFLAGSMASK 0x3fL /* VS_FFI_FILEFLAGSMASK */
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L /* VS_FF_DEBUG */
|
||||
#else
|
||||
FILEFLAGS 0x0L
|
||||
#endif
|
||||
FILEOS 0x10004L /* VOS_DOS_WINDOWS32 */
|
||||
FILETYPE 0x2L /* VFT_DLL */
|
||||
FILESUBTYPE 0x0L /* VFT2_UNKNOWN */
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "04090000" /* Lang = US English, Charset = ASCII */
|
||||
BEGIN
|
||||
VALUE "Comments", "This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA\0"
|
||||
VALUE "CompanyName", "Free Software Foundation\0"
|
||||
VALUE "FileDescription", "LGPLed libintl for Windows NT/2000/XP/Vista/7 and Windows 95/98/ME\0"
|
||||
VALUE "FileVersion", PACKAGE_VERSION_STRING "\0"
|
||||
VALUE "InternalName", "intl.dll\0"
|
||||
VALUE "LegalCopyright", "Copyright (C) 1995-2010\0"
|
||||
VALUE "LegalTrademarks", "\0"
|
||||
VALUE "OriginalFilename", "intl.dll\0"
|
||||
VALUE "ProductName", "libintl: accessing NLS message catalogs\0"
|
||||
VALUE "ProductVersion", PACKAGE_VERSION_STRING "\0"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x0409, 0 /* US English, ASCII */
|
||||
END
|
||||
END
|
|
@ -1,5 +1,5 @@
|
|||
/* Load needed message catalogs.
|
||||
Copyright (C) 1995-1999, 2000-2005 Free Software Foundation, Inc.
|
||||
Copyright (C) 1995-1999, 2000-2008 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Library General Public License as published
|
||||
|
@ -976,6 +976,7 @@ _nl_load_domain (struct loaded_l10nfile *domain_file,
|
|||
((char *) data
|
||||
+ W (domain->must_swap, data->sysdep_segments_offset));
|
||||
sysdep_segment_values =
|
||||
(const char **)
|
||||
alloca (n_sysdep_segments * sizeof (const char *));
|
||||
for (i = 0; i < n_sysdep_segments; i++)
|
||||
{
|
||||
|
@ -1258,8 +1259,7 @@ _nl_load_domain (struct loaded_l10nfile *domain_file,
|
|||
/* This is an invalid revision. */
|
||||
invalid:
|
||||
/* This is an invalid .mo file. */
|
||||
if (domain->malloced)
|
||||
free (domain->malloced);
|
||||
free (domain->malloced);
|
||||
#ifdef HAVE_MMAP
|
||||
if (use_mmap)
|
||||
munmap ((caddr_t) data, size);
|
||||
|
@ -1274,6 +1274,7 @@ _nl_load_domain (struct loaded_l10nfile *domain_file,
|
|||
/* No caches of converted translations so far. */
|
||||
domain->conversions = NULL;
|
||||
domain->nconversions = 0;
|
||||
gl_rwlock_init (domain->conversions_lock);
|
||||
|
||||
/* Get the header entry and look for a plural specification. */
|
||||
#ifdef IN_LIBGLOCALE
|
||||
|
@ -1303,7 +1304,7 @@ _nl_unload_domain (struct loaded_domain *domain)
|
|||
size_t i;
|
||||
|
||||
if (domain->plural != &__gettext_germanic_plural)
|
||||
__gettext_free_exp (domain->plural);
|
||||
__gettext_free_exp ((struct expression *) domain->plural);
|
||||
|
||||
for (i = 0; i < domain->nconversions; i++)
|
||||
{
|
||||
|
@ -1315,11 +1316,10 @@ _nl_unload_domain (struct loaded_domain *domain)
|
|||
if (convd->conv != (__gconv_t) -1)
|
||||
__gconv_close (convd->conv);
|
||||
}
|
||||
if (domain->conversions != NULL)
|
||||
free (domain->conversions);
|
||||
free (domain->conversions);
|
||||
__libc_rwlock_fini (domain->conversions_lock);
|
||||
|
||||
if (domain->malloced)
|
||||
free (domain->malloced);
|
||||
free (domain->malloced);
|
||||
|
||||
# ifdef _POSIX_MAPPED_FILES
|
||||
if (domain->use_mmap)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* Determine a canonical name for the current locale's character encoding.
|
||||
|
||||
Copyright (C) 2000-2006 Free Software Foundation, Inc.
|
||||
Copyright (C) 2000-2006, 2008-2010 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Library General Public License as published
|
||||
|
@ -24,21 +24,29 @@
|
|||
/* Specification. */
|
||||
#include "localcharset.h"
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#if defined __APPLE__ && defined __MACH__ && HAVE_LANGINFO_CODESET
|
||||
# define DARWIN7 /* Darwin 7 or newer, i.e. MacOS X 10.3 or newer */
|
||||
#endif
|
||||
|
||||
#if defined _WIN32 || defined __WIN32__
|
||||
# define WIN32_NATIVE
|
||||
#endif
|
||||
|
||||
#if defined __EMX__
|
||||
/* Assume EMX program runs on OS/2, even if compiled under DOS. */
|
||||
# define OS2
|
||||
# ifndef OS2
|
||||
# define OS2
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if !defined WIN32_NATIVE
|
||||
# include <unistd.h>
|
||||
# if HAVE_LANGINFO_CODESET
|
||||
# include <langinfo.h>
|
||||
# else
|
||||
|
@ -70,6 +78,11 @@
|
|||
# include "configmake.h"
|
||||
#endif
|
||||
|
||||
/* Define O_NOFOLLOW to 0 on platforms where it does not exist. */
|
||||
#ifndef O_NOFOLLOW
|
||||
# define O_NOFOLLOW 0
|
||||
#endif
|
||||
|
||||
#if defined _WIN32 || defined __WIN32__ || defined __CYGWIN__ || defined __EMX__ || defined __DJGPP__
|
||||
/* Win32, Cygwin, OS/2, DOS */
|
||||
# define ISSLASH(C) ((C) == '/' || (C) == '\\')
|
||||
|
@ -111,160 +124,220 @@ get_charset_aliases (void)
|
|||
cp = charset_aliases;
|
||||
if (cp == NULL)
|
||||
{
|
||||
#if !(defined VMS || defined WIN32_NATIVE || defined __CYGWIN__)
|
||||
FILE *fp;
|
||||
#if !(defined DARWIN7 || defined VMS || defined WIN32_NATIVE || defined __CYGWIN__)
|
||||
const char *dir;
|
||||
const char *base = "charset.alias";
|
||||
char *file_name;
|
||||
|
||||
/* Make it possible to override the charset.alias location. This is
|
||||
necessary for running the testsuite before "make install". */
|
||||
necessary for running the testsuite before "make install". */
|
||||
dir = getenv ("CHARSETALIASDIR");
|
||||
if (dir == NULL || dir[0] == '\0')
|
||||
dir = relocate (LIBDIR);
|
||||
dir = relocate (LIBDIR);
|
||||
|
||||
/* Concatenate dir and base into freshly allocated file_name. */
|
||||
{
|
||||
size_t dir_len = strlen (dir);
|
||||
size_t base_len = strlen (base);
|
||||
int add_slash = (dir_len > 0 && !ISSLASH (dir[dir_len - 1]));
|
||||
file_name = (char *) malloc (dir_len + add_slash + base_len + 1);
|
||||
if (file_name != NULL)
|
||||
{
|
||||
memcpy (file_name, dir, dir_len);
|
||||
if (add_slash)
|
||||
file_name[dir_len] = DIRECTORY_SEPARATOR;
|
||||
memcpy (file_name + dir_len + add_slash, base, base_len + 1);
|
||||
}
|
||||
size_t dir_len = strlen (dir);
|
||||
size_t base_len = strlen (base);
|
||||
int add_slash = (dir_len > 0 && !ISSLASH (dir[dir_len - 1]));
|
||||
file_name = (char *) malloc (dir_len + add_slash + base_len + 1);
|
||||
if (file_name != NULL)
|
||||
{
|
||||
memcpy (file_name, dir, dir_len);
|
||||
if (add_slash)
|
||||
file_name[dir_len] = DIRECTORY_SEPARATOR;
|
||||
memcpy (file_name + dir_len + add_slash, base, base_len + 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (file_name == NULL || (fp = fopen (file_name, "r")) == NULL)
|
||||
/* Out of memory or file not found, treat it as empty. */
|
||||
cp = "";
|
||||
if (file_name == NULL)
|
||||
/* Out of memory. Treat the file as empty. */
|
||||
cp = "";
|
||||
else
|
||||
{
|
||||
/* Parse the file's contents. */
|
||||
char *res_ptr = NULL;
|
||||
size_t res_size = 0;
|
||||
{
|
||||
int fd;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
int c;
|
||||
char buf1[50+1];
|
||||
char buf2[50+1];
|
||||
size_t l1, l2;
|
||||
char *old_res_ptr;
|
||||
/* Open the file. Reject symbolic links on platforms that support
|
||||
O_NOFOLLOW. This is a security feature. Without it, an attacker
|
||||
could retrieve parts of the contents (namely, the tail of the
|
||||
first line that starts with "* ") of an arbitrary file by placing
|
||||
a symbolic link to that file under the name "charset.alias" in
|
||||
some writable directory and defining the environment variable
|
||||
CHARSETALIASDIR to point to that directory. */
|
||||
fd = open (file_name,
|
||||
O_RDONLY | (HAVE_WORKING_O_NOFOLLOW ? O_NOFOLLOW : 0));
|
||||
if (fd < 0)
|
||||
/* File not found. Treat it as empty. */
|
||||
cp = "";
|
||||
else
|
||||
{
|
||||
FILE *fp;
|
||||
|
||||
c = getc (fp);
|
||||
if (c == EOF)
|
||||
break;
|
||||
if (c == '\n' || c == ' ' || c == '\t')
|
||||
continue;
|
||||
if (c == '#')
|
||||
{
|
||||
/* Skip comment, to end of line. */
|
||||
do
|
||||
c = getc (fp);
|
||||
while (!(c == EOF || c == '\n'));
|
||||
if (c == EOF)
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
ungetc (c, fp);
|
||||
if (fscanf (fp, "%50s %50s", buf1, buf2) < 2)
|
||||
break;
|
||||
l1 = strlen (buf1);
|
||||
l2 = strlen (buf2);
|
||||
old_res_ptr = res_ptr;
|
||||
if (res_size == 0)
|
||||
{
|
||||
res_size = l1 + 1 + l2 + 1;
|
||||
res_ptr = (char *) malloc (res_size + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
res_size += l1 + 1 + l2 + 1;
|
||||
res_ptr = (char *) realloc (res_ptr, res_size + 1);
|
||||
}
|
||||
if (res_ptr == NULL)
|
||||
{
|
||||
/* Out of memory. */
|
||||
res_size = 0;
|
||||
if (old_res_ptr != NULL)
|
||||
free (old_res_ptr);
|
||||
break;
|
||||
}
|
||||
strcpy (res_ptr + res_size - (l2 + 1) - (l1 + 1), buf1);
|
||||
strcpy (res_ptr + res_size - (l2 + 1), buf2);
|
||||
}
|
||||
fclose (fp);
|
||||
if (res_size == 0)
|
||||
cp = "";
|
||||
else
|
||||
{
|
||||
*(res_ptr + res_size) = '\0';
|
||||
cp = res_ptr;
|
||||
}
|
||||
}
|
||||
fp = fdopen (fd, "r");
|
||||
if (fp == NULL)
|
||||
{
|
||||
/* Out of memory. Treat the file as empty. */
|
||||
close (fd);
|
||||
cp = "";
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Parse the file's contents. */
|
||||
char *res_ptr = NULL;
|
||||
size_t res_size = 0;
|
||||
|
||||
if (file_name != NULL)
|
||||
free (file_name);
|
||||
for (;;)
|
||||
{
|
||||
int c;
|
||||
char buf1[50+1];
|
||||
char buf2[50+1];
|
||||
size_t l1, l2;
|
||||
char *old_res_ptr;
|
||||
|
||||
c = getc (fp);
|
||||
if (c == EOF)
|
||||
break;
|
||||
if (c == '\n' || c == ' ' || c == '\t')
|
||||
continue;
|
||||
if (c == '#')
|
||||
{
|
||||
/* Skip comment, to end of line. */
|
||||
do
|
||||
c = getc (fp);
|
||||
while (!(c == EOF || c == '\n'));
|
||||
if (c == EOF)
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
ungetc (c, fp);
|
||||
if (fscanf (fp, "%50s %50s", buf1, buf2) < 2)
|
||||
break;
|
||||
l1 = strlen (buf1);
|
||||
l2 = strlen (buf2);
|
||||
old_res_ptr = res_ptr;
|
||||
if (res_size == 0)
|
||||
{
|
||||
res_size = l1 + 1 + l2 + 1;
|
||||
res_ptr = (char *) malloc (res_size + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
res_size += l1 + 1 + l2 + 1;
|
||||
res_ptr = (char *) realloc (res_ptr, res_size + 1);
|
||||
}
|
||||
if (res_ptr == NULL)
|
||||
{
|
||||
/* Out of memory. */
|
||||
res_size = 0;
|
||||
if (old_res_ptr != NULL)
|
||||
free (old_res_ptr);
|
||||
break;
|
||||
}
|
||||
strcpy (res_ptr + res_size - (l2 + 1) - (l1 + 1), buf1);
|
||||
strcpy (res_ptr + res_size - (l2 + 1), buf2);
|
||||
}
|
||||
fclose (fp);
|
||||
if (res_size == 0)
|
||||
cp = "";
|
||||
else
|
||||
{
|
||||
*(res_ptr + res_size) = '\0';
|
||||
cp = res_ptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
free (file_name);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
# if defined DARWIN7
|
||||
/* To avoid the trouble of installing a file that is shared by many
|
||||
GNU packages -- many packaging systems have problems with this --,
|
||||
simply inline the aliases here. */
|
||||
cp = "ISO8859-1" "\0" "ISO-8859-1" "\0"
|
||||
"ISO8859-2" "\0" "ISO-8859-2" "\0"
|
||||
"ISO8859-4" "\0" "ISO-8859-4" "\0"
|
||||
"ISO8859-5" "\0" "ISO-8859-5" "\0"
|
||||
"ISO8859-7" "\0" "ISO-8859-7" "\0"
|
||||
"ISO8859-9" "\0" "ISO-8859-9" "\0"
|
||||
"ISO8859-13" "\0" "ISO-8859-13" "\0"
|
||||
"ISO8859-15" "\0" "ISO-8859-15" "\0"
|
||||
"KOI8-R" "\0" "KOI8-R" "\0"
|
||||
"KOI8-U" "\0" "KOI8-U" "\0"
|
||||
"CP866" "\0" "CP866" "\0"
|
||||
"CP949" "\0" "CP949" "\0"
|
||||
"CP1131" "\0" "CP1131" "\0"
|
||||
"CP1251" "\0" "CP1251" "\0"
|
||||
"eucCN" "\0" "GB2312" "\0"
|
||||
"GB2312" "\0" "GB2312" "\0"
|
||||
"eucJP" "\0" "EUC-JP" "\0"
|
||||
"eucKR" "\0" "EUC-KR" "\0"
|
||||
"Big5" "\0" "BIG5" "\0"
|
||||
"Big5HKSCS" "\0" "BIG5-HKSCS" "\0"
|
||||
"GBK" "\0" "GBK" "\0"
|
||||
"GB18030" "\0" "GB18030" "\0"
|
||||
"SJIS" "\0" "SHIFT_JIS" "\0"
|
||||
"ARMSCII-8" "\0" "ARMSCII-8" "\0"
|
||||
"PT154" "\0" "PT154" "\0"
|
||||
/*"ISCII-DEV" "\0" "?" "\0"*/
|
||||
"*" "\0" "UTF-8" "\0";
|
||||
# endif
|
||||
|
||||
# if defined VMS
|
||||
/* To avoid the troubles of an extra file charset.alias_vms in the
|
||||
sources of many GNU packages, simply inline the aliases here. */
|
||||
sources of many GNU packages, simply inline the aliases here. */
|
||||
/* The list of encodings is taken from the OpenVMS 7.3-1 documentation
|
||||
"Compaq C Run-Time Library Reference Manual for OpenVMS systems"
|
||||
section 10.7 "Handling Different Character Sets". */
|
||||
"Compaq C Run-Time Library Reference Manual for OpenVMS systems"
|
||||
section 10.7 "Handling Different Character Sets". */
|
||||
cp = "ISO8859-1" "\0" "ISO-8859-1" "\0"
|
||||
"ISO8859-2" "\0" "ISO-8859-2" "\0"
|
||||
"ISO8859-5" "\0" "ISO-8859-5" "\0"
|
||||
"ISO8859-7" "\0" "ISO-8859-7" "\0"
|
||||
"ISO8859-8" "\0" "ISO-8859-8" "\0"
|
||||
"ISO8859-9" "\0" "ISO-8859-9" "\0"
|
||||
/* Japanese */
|
||||
"eucJP" "\0" "EUC-JP" "\0"
|
||||
"SJIS" "\0" "SHIFT_JIS" "\0"
|
||||
"DECKANJI" "\0" "DEC-KANJI" "\0"
|
||||
"SDECKANJI" "\0" "EUC-JP" "\0"
|
||||
/* Chinese */
|
||||
"eucTW" "\0" "EUC-TW" "\0"
|
||||
"DECHANYU" "\0" "DEC-HANYU" "\0"
|
||||
"DECHANZI" "\0" "GB2312" "\0"
|
||||
/* Korean */
|
||||
"DECKOREAN" "\0" "EUC-KR" "\0";
|
||||
"ISO8859-2" "\0" "ISO-8859-2" "\0"
|
||||
"ISO8859-5" "\0" "ISO-8859-5" "\0"
|
||||
"ISO8859-7" "\0" "ISO-8859-7" "\0"
|
||||
"ISO8859-8" "\0" "ISO-8859-8" "\0"
|
||||
"ISO8859-9" "\0" "ISO-8859-9" "\0"
|
||||
/* Japanese */
|
||||
"eucJP" "\0" "EUC-JP" "\0"
|
||||
"SJIS" "\0" "SHIFT_JIS" "\0"
|
||||
"DECKANJI" "\0" "DEC-KANJI" "\0"
|
||||
"SDECKANJI" "\0" "EUC-JP" "\0"
|
||||
/* Chinese */
|
||||
"eucTW" "\0" "EUC-TW" "\0"
|
||||
"DECHANYU" "\0" "DEC-HANYU" "\0"
|
||||
"DECHANZI" "\0" "GB2312" "\0"
|
||||
/* Korean */
|
||||
"DECKOREAN" "\0" "EUC-KR" "\0";
|
||||
# endif
|
||||
|
||||
# if defined WIN32_NATIVE || defined __CYGWIN__
|
||||
/* To avoid the troubles of installing a separate file in the same
|
||||
directory as the DLL and of retrieving the DLL's directory at
|
||||
runtime, simply inline the aliases here. */
|
||||
directory as the DLL and of retrieving the DLL's directory at
|
||||
runtime, simply inline the aliases here. */
|
||||
|
||||
cp = "CP936" "\0" "GBK" "\0"
|
||||
"CP1361" "\0" "JOHAB" "\0"
|
||||
"CP20127" "\0" "ASCII" "\0"
|
||||
"CP20866" "\0" "KOI8-R" "\0"
|
||||
"CP20936" "\0" "GB2312" "\0"
|
||||
"CP21866" "\0" "KOI8-RU" "\0"
|
||||
"CP28591" "\0" "ISO-8859-1" "\0"
|
||||
"CP28592" "\0" "ISO-8859-2" "\0"
|
||||
"CP28593" "\0" "ISO-8859-3" "\0"
|
||||
"CP28594" "\0" "ISO-8859-4" "\0"
|
||||
"CP28595" "\0" "ISO-8859-5" "\0"
|
||||
"CP28596" "\0" "ISO-8859-6" "\0"
|
||||
"CP28597" "\0" "ISO-8859-7" "\0"
|
||||
"CP28598" "\0" "ISO-8859-8" "\0"
|
||||
"CP28599" "\0" "ISO-8859-9" "\0"
|
||||
"CP28605" "\0" "ISO-8859-15" "\0"
|
||||
"CP38598" "\0" "ISO-8859-8" "\0"
|
||||
"CP51932" "\0" "EUC-JP" "\0"
|
||||
"CP51936" "\0" "GB2312" "\0"
|
||||
"CP51949" "\0" "EUC-KR" "\0"
|
||||
"CP51950" "\0" "EUC-TW" "\0"
|
||||
"CP54936" "\0" "GB18030" "\0"
|
||||
"CP65001" "\0" "UTF-8" "\0";
|
||||
"CP1361" "\0" "JOHAB" "\0"
|
||||
"CP20127" "\0" "ASCII" "\0"
|
||||
"CP20866" "\0" "KOI8-R" "\0"
|
||||
"CP20936" "\0" "GB2312" "\0"
|
||||
"CP21866" "\0" "KOI8-RU" "\0"
|
||||
"CP28591" "\0" "ISO-8859-1" "\0"
|
||||
"CP28592" "\0" "ISO-8859-2" "\0"
|
||||
"CP28593" "\0" "ISO-8859-3" "\0"
|
||||
"CP28594" "\0" "ISO-8859-4" "\0"
|
||||
"CP28595" "\0" "ISO-8859-5" "\0"
|
||||
"CP28596" "\0" "ISO-8859-6" "\0"
|
||||
"CP28597" "\0" "ISO-8859-7" "\0"
|
||||
"CP28598" "\0" "ISO-8859-8" "\0"
|
||||
"CP28599" "\0" "ISO-8859-9" "\0"
|
||||
"CP28605" "\0" "ISO-8859-15" "\0"
|
||||
"CP38598" "\0" "ISO-8859-8" "\0"
|
||||
"CP51932" "\0" "EUC-JP" "\0"
|
||||
"CP51936" "\0" "GB2312" "\0"
|
||||
"CP51949" "\0" "EUC-KR" "\0"
|
||||
"CP51950" "\0" "EUC-TW" "\0"
|
||||
"CP54936" "\0" "GB18030" "\0"
|
||||
"CP65001" "\0" "UTF-8" "\0";
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
@ -297,10 +370,9 @@ locale_charset (void)
|
|||
codeset = nl_langinfo (CODESET);
|
||||
|
||||
# ifdef __CYGWIN__
|
||||
/* Cygwin 2006 does not have locales. nl_langinfo (CODESET) always
|
||||
returns "US-ASCII". As long as this is not fixed, return the suffix
|
||||
of the locale name from the environment variables (if present) or
|
||||
the codepage as a number. */
|
||||
/* Cygwin < 1.7 does not have locales. nl_langinfo (CODESET) always
|
||||
returns "US-ASCII". Return the suffix of the locale name from the
|
||||
environment variables (if present) or the codepage as a number. */
|
||||
if (codeset != NULL && strcmp (codeset, "US-ASCII") == 0)
|
||||
{
|
||||
const char *locale;
|
||||
|
@ -308,36 +380,46 @@ locale_charset (void)
|
|||
|
||||
locale = getenv ("LC_ALL");
|
||||
if (locale == NULL || locale[0] == '\0')
|
||||
{
|
||||
locale = getenv ("LC_CTYPE");
|
||||
if (locale == NULL || locale[0] == '\0')
|
||||
locale = getenv ("LANG");
|
||||
}
|
||||
{
|
||||
locale = getenv ("LC_CTYPE");
|
||||
if (locale == NULL || locale[0] == '\0')
|
||||
locale = getenv ("LANG");
|
||||
}
|
||||
if (locale != NULL && locale[0] != '\0')
|
||||
{
|
||||
/* If the locale name contains an encoding after the dot, return
|
||||
it. */
|
||||
const char *dot = strchr (locale, '.');
|
||||
{
|
||||
/* If the locale name contains an encoding after the dot, return
|
||||
it. */
|
||||
const char *dot = strchr (locale, '.');
|
||||
|
||||
if (dot != NULL)
|
||||
{
|
||||
const char *modifier;
|
||||
if (dot != NULL)
|
||||
{
|
||||
const char *modifier;
|
||||
|
||||
dot++;
|
||||
/* Look for the possible @... trailer and remove it, if any. */
|
||||
modifier = strchr (dot, '@');
|
||||
if (modifier == NULL)
|
||||
return dot;
|
||||
if (modifier - dot < sizeof (buf))
|
||||
{
|
||||
memcpy (buf, dot, modifier - dot);
|
||||
buf [modifier - dot] = '\0';
|
||||
return buf;
|
||||
}
|
||||
}
|
||||
}
|
||||
dot++;
|
||||
/* Look for the possible @... trailer and remove it, if any. */
|
||||
modifier = strchr (dot, '@');
|
||||
if (modifier == NULL)
|
||||
return dot;
|
||||
if (modifier - dot < sizeof (buf))
|
||||
{
|
||||
memcpy (buf, dot, modifier - dot);
|
||||
buf [modifier - dot] = '\0';
|
||||
return buf;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Woe32 has a function returning the locale's codepage as a number. */
|
||||
/* Woe32 has a function returning the locale's codepage as a number:
|
||||
GetACP(). This encoding is used by Cygwin, unless the user has set
|
||||
the environment variable CYGWIN=codepage:oem (which very few people
|
||||
do).
|
||||
Output directed to console windows needs to be converted (to
|
||||
GetOEMCP() if the console is using a raster font, or to
|
||||
GetConsoleOutputCP() if it is using a TrueType font). Cygwin does
|
||||
this conversion transparently (see winsup/cygwin/fhandler_console.cc),
|
||||
converting to GetConsoleOutputCP(). This leads to correct results,
|
||||
except when SetConsoleOutputCP has been called and a raster font is
|
||||
in use. */
|
||||
sprintf (buf, "CP%u", GetACP ());
|
||||
codeset = buf;
|
||||
}
|
||||
|
@ -359,11 +441,11 @@ locale_charset (void)
|
|||
{
|
||||
locale = getenv ("LC_ALL");
|
||||
if (locale == NULL || locale[0] == '\0')
|
||||
{
|
||||
locale = getenv ("LC_CTYPE");
|
||||
if (locale == NULL || locale[0] == '\0')
|
||||
locale = getenv ("LANG");
|
||||
}
|
||||
{
|
||||
locale = getenv ("LC_CTYPE");
|
||||
if (locale == NULL || locale[0] == '\0')
|
||||
locale = getenv ("LANG");
|
||||
}
|
||||
}
|
||||
|
||||
/* On some old systems, one used to set locale = "iso8859_1". On others,
|
||||
|
@ -377,7 +459,13 @@ locale_charset (void)
|
|||
|
||||
static char buf[2 + 10 + 1];
|
||||
|
||||
/* Woe32 has a function returning the locale's codepage as a number. */
|
||||
/* Woe32 has a function returning the locale's codepage as a number:
|
||||
GetACP().
|
||||
When the output goes to a console window, it needs to be provided in
|
||||
GetOEMCP() encoding if the console is using a raster font, or in
|
||||
GetConsoleOutputCP() encoding if it is using a TrueType font.
|
||||
But in GUI programs and for output sent to files and pipes, GetACP()
|
||||
encoding is the best bet. */
|
||||
sprintf (buf, "CP%u", GetACP ());
|
||||
codeset = buf;
|
||||
|
||||
|
@ -395,7 +483,7 @@ locale_charset (void)
|
|||
{
|
||||
locale = getenv ("LC_CTYPE");
|
||||
if (locale == NULL || locale[0] == '\0')
|
||||
locale = getenv ("LANG");
|
||||
locale = getenv ("LANG");
|
||||
}
|
||||
if (locale != NULL && locale[0] != '\0')
|
||||
{
|
||||
|
@ -403,21 +491,21 @@ locale_charset (void)
|
|||
const char *dot = strchr (locale, '.');
|
||||
|
||||
if (dot != NULL)
|
||||
{
|
||||
const char *modifier;
|
||||
{
|
||||
const char *modifier;
|
||||
|
||||
dot++;
|
||||
/* Look for the possible @... trailer and remove it, if any. */
|
||||
modifier = strchr (dot, '@');
|
||||
if (modifier == NULL)
|
||||
return dot;
|
||||
if (modifier - dot < sizeof (buf))
|
||||
{
|
||||
memcpy (buf, dot, modifier - dot);
|
||||
buf [modifier - dot] = '\0';
|
||||
return buf;
|
||||
}
|
||||
}
|
||||
dot++;
|
||||
/* Look for the possible @... trailer and remove it, if any. */
|
||||
modifier = strchr (dot, '@');
|
||||
if (modifier == NULL)
|
||||
return dot;
|
||||
if (modifier - dot < sizeof (buf))
|
||||
{
|
||||
memcpy (buf, dot, modifier - dot);
|
||||
buf [modifier - dot] = '\0';
|
||||
return buf;
|
||||
}
|
||||
}
|
||||
|
||||
/* Resolve through the charset.alias file. */
|
||||
codeset = locale;
|
||||
|
@ -426,12 +514,12 @@ locale_charset (void)
|
|||
{
|
||||
/* OS/2 has a function returning the locale's codepage as a number. */
|
||||
if (DosQueryCp (sizeof (cp), cp, &cplen))
|
||||
codeset = "";
|
||||
codeset = "";
|
||||
else
|
||||
{
|
||||
sprintf (buf, "CP%u", cp[0]);
|
||||
codeset = buf;
|
||||
}
|
||||
{
|
||||
sprintf (buf, "CP%u", cp[0]);
|
||||
codeset = buf;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -445,10 +533,10 @@ locale_charset (void)
|
|||
*aliases != '\0';
|
||||
aliases += strlen (aliases) + 1, aliases += strlen (aliases) + 1)
|
||||
if (strcmp (codeset, aliases) == 0
|
||||
|| (aliases[0] == '*' && aliases[1] == '\0'))
|
||||
|| (aliases[0] == '*' && aliases[1] == '\0'))
|
||||
{
|
||||
codeset = aliases + strlen (aliases) + 1;
|
||||
break;
|
||||
codeset = aliases + strlen (aliases) + 1;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Don't return an empty string. GNU libc and GNU libiconv interpret
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Locale name alias data base.
|
||||
# Copyright (C) 1996-2001,2003 Free Software Foundation, Inc.
|
||||
# Copyright (C) 1996-2001,2003,2007 Free Software Foundation, Inc.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU Library General Public License as published
|
||||
|
@ -22,10 +22,9 @@
|
|||
# A single line contains two fields: an alias and a substitution value.
|
||||
# All entries are case independent.
|
||||
|
||||
# Note: This file is far from being complete. If you have a value for
|
||||
# your own site which you think might be useful for others too, share
|
||||
# it with the rest of us. Send it using the `glibcbug' script to
|
||||
# bugs@gnu.org.
|
||||
# Note: This file is obsolete and is kept around for the time being for
|
||||
# backward compatibility. Nobody should rely on the names defined here.
|
||||
# Locales should always be specified by their full name.
|
||||
|
||||
# Packages using this file:
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* Handle aliases for locale names.
|
||||
Copyright (C) 1995-1999, 2000-2001, 2003, 2005 Free Software Foundation, Inc.
|
||||
Copyright (C) 1995-1999, 2000-2001, 2003, 2005-2006 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Library General Public License as published
|
||||
|
@ -349,12 +349,14 @@ read_alias_file (const char *fname, int fname_len)
|
|||
string_space_max = new_size;
|
||||
}
|
||||
|
||||
map[nmap].alias = memcpy (&string_space[string_space_act],
|
||||
alias, alias_len);
|
||||
map[nmap].alias =
|
||||
(const char *) memcpy (&string_space[string_space_act],
|
||||
alias, alias_len);
|
||||
string_space_act += alias_len;
|
||||
|
||||
map[nmap].value = memcpy (&string_space[string_space_act],
|
||||
value, value_len);
|
||||
map[nmap].value =
|
||||
(const char *) memcpy (&string_space[string_space_act],
|
||||
value, value_len);
|
||||
string_space_act += value_len;
|
||||
|
||||
++nmap;
|
||||
|
|
2482
intl/localename.c
2482
intl/localename.c
File diff suppressed because it is too large
Load diff
891
intl/lock.c
891
intl/lock.c
File diff suppressed because it is too large
Load diff
599
intl/lock.h
599
intl/lock.h
|
@ -1,5 +1,5 @@
|
|||
/* Locking in multithreaded situations.
|
||||
Copyright (C) 2005-2006 Free Software Foundation, Inc.
|
||||
Copyright (C) 2005-2008 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Library General Public License as published
|
||||
|
@ -32,6 +32,11 @@
|
|||
Taking the lock: gl_lock_lock (name);
|
||||
Releasing the lock: gl_lock_unlock (name);
|
||||
De-initialization: gl_lock_destroy (name);
|
||||
Equivalent functions with control of error handling:
|
||||
Initialization: err = glthread_lock_init (&name);
|
||||
Taking the lock: err = glthread_lock_lock (&name);
|
||||
Releasing the lock: err = glthread_lock_unlock (&name);
|
||||
De-initialization: err = glthread_lock_destroy (&name);
|
||||
|
||||
Read-Write (non-recursive) locks:
|
||||
Type: gl_rwlock_t
|
||||
|
@ -42,6 +47,12 @@
|
|||
gl_rwlock_wrlock (name);
|
||||
Releasing the lock: gl_rwlock_unlock (name);
|
||||
De-initialization: gl_rwlock_destroy (name);
|
||||
Equivalent functions with control of error handling:
|
||||
Initialization: err = glthread_rwlock_init (&name);
|
||||
Taking the lock: err = glthread_rwlock_rdlock (&name);
|
||||
err = glthread_rwlock_wrlock (&name);
|
||||
Releasing the lock: err = glthread_rwlock_unlock (&name);
|
||||
De-initialization: err = glthread_rwlock_destroy (&name);
|
||||
|
||||
Recursive locks:
|
||||
Type: gl_recursive_lock_t
|
||||
|
@ -51,17 +62,27 @@
|
|||
Taking the lock: gl_recursive_lock_lock (name);
|
||||
Releasing the lock: gl_recursive_lock_unlock (name);
|
||||
De-initialization: gl_recursive_lock_destroy (name);
|
||||
Equivalent functions with control of error handling:
|
||||
Initialization: err = glthread_recursive_lock_init (&name);
|
||||
Taking the lock: err = glthread_recursive_lock_lock (&name);
|
||||
Releasing the lock: err = glthread_recursive_lock_unlock (&name);
|
||||
De-initialization: err = glthread_recursive_lock_destroy (&name);
|
||||
|
||||
Once-only execution:
|
||||
Type: gl_once_t
|
||||
Initializer: gl_once_define(extern, name)
|
||||
Execution: gl_once (name, initfunction);
|
||||
Equivalent functions with control of error handling:
|
||||
Execution: err = glthread_once (&name, initfunction);
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _LOCK_H
|
||||
#define _LOCK_H
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
#if USE_POSIX_THREADS
|
||||
|
@ -69,7 +90,6 @@
|
|||
/* Use the POSIX threads library. */
|
||||
|
||||
# include <pthread.h>
|
||||
# include <stdlib.h>
|
||||
|
||||
# ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
@ -147,14 +167,14 @@ typedef pthread_mutex_t gl_lock_t;
|
|||
STORAGECLASS pthread_mutex_t NAME = gl_lock_initializer;
|
||||
# define gl_lock_initializer \
|
||||
PTHREAD_MUTEX_INITIALIZER
|
||||
# define gl_lock_init(NAME) \
|
||||
if (pthread_in_use () && pthread_mutex_init (&NAME, NULL) != 0) abort ()
|
||||
# define gl_lock_lock(NAME) \
|
||||
if (pthread_in_use () && pthread_mutex_lock (&NAME) != 0) abort ()
|
||||
# define gl_lock_unlock(NAME) \
|
||||
if (pthread_in_use () && pthread_mutex_unlock (&NAME) != 0) abort ()
|
||||
# define gl_lock_destroy(NAME) \
|
||||
if (pthread_in_use () && pthread_mutex_destroy (&NAME) != 0) abort ()
|
||||
# define glthread_lock_init(LOCK) \
|
||||
(pthread_in_use () ? pthread_mutex_init (LOCK, NULL) : 0)
|
||||
# define glthread_lock_lock(LOCK) \
|
||||
(pthread_in_use () ? pthread_mutex_lock (LOCK) : 0)
|
||||
# define glthread_lock_unlock(LOCK) \
|
||||
(pthread_in_use () ? pthread_mutex_unlock (LOCK) : 0)
|
||||
# define glthread_lock_destroy(LOCK) \
|
||||
(pthread_in_use () ? pthread_mutex_destroy (LOCK) : 0)
|
||||
|
||||
/* ------------------------- gl_rwlock_t datatype ------------------------- */
|
||||
|
||||
|
@ -169,16 +189,16 @@ typedef pthread_rwlock_t gl_rwlock_t;
|
|||
STORAGECLASS pthread_rwlock_t NAME = gl_rwlock_initializer;
|
||||
# define gl_rwlock_initializer \
|
||||
PTHREAD_RWLOCK_INITIALIZER
|
||||
# define gl_rwlock_init(NAME) \
|
||||
if (pthread_in_use () && pthread_rwlock_init (&NAME, NULL) != 0) abort ()
|
||||
# define gl_rwlock_rdlock(NAME) \
|
||||
if (pthread_in_use () && pthread_rwlock_rdlock (&NAME) != 0) abort ()
|
||||
# define gl_rwlock_wrlock(NAME) \
|
||||
if (pthread_in_use () && pthread_rwlock_wrlock (&NAME) != 0) abort ()
|
||||
# define gl_rwlock_unlock(NAME) \
|
||||
if (pthread_in_use () && pthread_rwlock_unlock (&NAME) != 0) abort ()
|
||||
# define gl_rwlock_destroy(NAME) \
|
||||
if (pthread_in_use () && pthread_rwlock_destroy (&NAME) != 0) abort ()
|
||||
# define glthread_rwlock_init(LOCK) \
|
||||
(pthread_in_use () ? pthread_rwlock_init (LOCK, NULL) : 0)
|
||||
# define glthread_rwlock_rdlock(LOCK) \
|
||||
(pthread_in_use () ? pthread_rwlock_rdlock (LOCK) : 0)
|
||||
# define glthread_rwlock_wrlock(LOCK) \
|
||||
(pthread_in_use () ? pthread_rwlock_wrlock (LOCK) : 0)
|
||||
# define glthread_rwlock_unlock(LOCK) \
|
||||
(pthread_in_use () ? pthread_rwlock_unlock (LOCK) : 0)
|
||||
# define glthread_rwlock_destroy(LOCK) \
|
||||
(pthread_in_use () ? pthread_rwlock_destroy (LOCK) : 0)
|
||||
|
||||
# else
|
||||
|
||||
|
@ -195,21 +215,21 @@ typedef struct
|
|||
STORAGECLASS gl_rwlock_t NAME = gl_rwlock_initializer;
|
||||
# define gl_rwlock_initializer \
|
||||
{ 0, PTHREAD_MUTEX_INITIALIZER }
|
||||
# define gl_rwlock_init(NAME) \
|
||||
if (pthread_in_use ()) glthread_rwlock_init (&NAME)
|
||||
# define gl_rwlock_rdlock(NAME) \
|
||||
if (pthread_in_use ()) glthread_rwlock_rdlock (&NAME)
|
||||
# define gl_rwlock_wrlock(NAME) \
|
||||
if (pthread_in_use ()) glthread_rwlock_wrlock (&NAME)
|
||||
# define gl_rwlock_unlock(NAME) \
|
||||
if (pthread_in_use ()) glthread_rwlock_unlock (&NAME)
|
||||
# define gl_rwlock_destroy(NAME) \
|
||||
if (pthread_in_use ()) glthread_rwlock_destroy (&NAME)
|
||||
extern void glthread_rwlock_init (gl_rwlock_t *lock);
|
||||
extern void glthread_rwlock_rdlock (gl_rwlock_t *lock);
|
||||
extern void glthread_rwlock_wrlock (gl_rwlock_t *lock);
|
||||
extern void glthread_rwlock_unlock (gl_rwlock_t *lock);
|
||||
extern void glthread_rwlock_destroy (gl_rwlock_t *lock);
|
||||
# define glthread_rwlock_init(LOCK) \
|
||||
(pthread_in_use () ? glthread_rwlock_init_multithreaded (LOCK) : 0)
|
||||
# define glthread_rwlock_rdlock(LOCK) \
|
||||
(pthread_in_use () ? glthread_rwlock_rdlock_multithreaded (LOCK) : 0)
|
||||
# define glthread_rwlock_wrlock(LOCK) \
|
||||
(pthread_in_use () ? glthread_rwlock_wrlock_multithreaded (LOCK) : 0)
|
||||
# define glthread_rwlock_unlock(LOCK) \
|
||||
(pthread_in_use () ? glthread_rwlock_unlock_multithreaded (LOCK) : 0)
|
||||
# define glthread_rwlock_destroy(LOCK) \
|
||||
(pthread_in_use () ? glthread_rwlock_destroy_multithreaded (LOCK) : 0)
|
||||
extern int glthread_rwlock_init_multithreaded (gl_rwlock_t *lock);
|
||||
extern int glthread_rwlock_rdlock_multithreaded (gl_rwlock_t *lock);
|
||||
extern int glthread_rwlock_wrlock_multithreaded (gl_rwlock_t *lock);
|
||||
extern int glthread_rwlock_unlock_multithreaded (gl_rwlock_t *lock);
|
||||
extern int glthread_rwlock_destroy_multithreaded (gl_rwlock_t *lock);
|
||||
|
||||
# endif
|
||||
|
||||
|
@ -230,21 +250,21 @@ typedef struct
|
|||
STORAGECLASS gl_rwlock_t NAME = gl_rwlock_initializer;
|
||||
# define gl_rwlock_initializer \
|
||||
{ PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER, PTHREAD_COND_INITIALIZER, 0, 0 }
|
||||
# define gl_rwlock_init(NAME) \
|
||||
if (pthread_in_use ()) glthread_rwlock_init (&NAME)
|
||||
# define gl_rwlock_rdlock(NAME) \
|
||||
if (pthread_in_use ()) glthread_rwlock_rdlock (&NAME)
|
||||
# define gl_rwlock_wrlock(NAME) \
|
||||
if (pthread_in_use ()) glthread_rwlock_wrlock (&NAME)
|
||||
# define gl_rwlock_unlock(NAME) \
|
||||
if (pthread_in_use ()) glthread_rwlock_unlock (&NAME)
|
||||
# define gl_rwlock_destroy(NAME) \
|
||||
if (pthread_in_use ()) glthread_rwlock_destroy (&NAME)
|
||||
extern void glthread_rwlock_init (gl_rwlock_t *lock);
|
||||
extern void glthread_rwlock_rdlock (gl_rwlock_t *lock);
|
||||
extern void glthread_rwlock_wrlock (gl_rwlock_t *lock);
|
||||
extern void glthread_rwlock_unlock (gl_rwlock_t *lock);
|
||||
extern void glthread_rwlock_destroy (gl_rwlock_t *lock);
|
||||
# define glthread_rwlock_init(LOCK) \
|
||||
(pthread_in_use () ? glthread_rwlock_init_multithreaded (LOCK) : 0)
|
||||
# define glthread_rwlock_rdlock(LOCK) \
|
||||
(pthread_in_use () ? glthread_rwlock_rdlock_multithreaded (LOCK) : 0)
|
||||
# define glthread_rwlock_wrlock(LOCK) \
|
||||
(pthread_in_use () ? glthread_rwlock_wrlock_multithreaded (LOCK) : 0)
|
||||
# define glthread_rwlock_unlock(LOCK) \
|
||||
(pthread_in_use () ? glthread_rwlock_unlock_multithreaded (LOCK) : 0)
|
||||
# define glthread_rwlock_destroy(LOCK) \
|
||||
(pthread_in_use () ? glthread_rwlock_destroy_multithreaded (LOCK) : 0)
|
||||
extern int glthread_rwlock_init_multithreaded (gl_rwlock_t *lock);
|
||||
extern int glthread_rwlock_rdlock_multithreaded (gl_rwlock_t *lock);
|
||||
extern int glthread_rwlock_wrlock_multithreaded (gl_rwlock_t *lock);
|
||||
extern int glthread_rwlock_unlock_multithreaded (gl_rwlock_t *lock);
|
||||
extern int glthread_rwlock_destroy_multithreaded (gl_rwlock_t *lock);
|
||||
|
||||
# endif
|
||||
|
||||
|
@ -266,14 +286,15 @@ typedef pthread_mutex_t gl_recursive_lock_t;
|
|||
# define gl_recursive_lock_initializer \
|
||||
PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
|
||||
# endif
|
||||
# define gl_recursive_lock_init(NAME) \
|
||||
if (pthread_in_use () && pthread_mutex_init (&NAME, NULL) != 0) abort ()
|
||||
# define gl_recursive_lock_lock(NAME) \
|
||||
if (pthread_in_use () && pthread_mutex_lock (&NAME) != 0) abort ()
|
||||
# define gl_recursive_lock_unlock(NAME) \
|
||||
if (pthread_in_use () && pthread_mutex_unlock (&NAME) != 0) abort ()
|
||||
# define gl_recursive_lock_destroy(NAME) \
|
||||
if (pthread_in_use () && pthread_mutex_destroy (&NAME) != 0) abort ()
|
||||
# define glthread_recursive_lock_init(LOCK) \
|
||||
(pthread_in_use () ? glthread_recursive_lock_init_multithreaded (LOCK) : 0)
|
||||
# define glthread_recursive_lock_lock(LOCK) \
|
||||
(pthread_in_use () ? pthread_mutex_lock (LOCK) : 0)
|
||||
# define glthread_recursive_lock_unlock(LOCK) \
|
||||
(pthread_in_use () ? pthread_mutex_unlock (LOCK) : 0)
|
||||
# define glthread_recursive_lock_destroy(LOCK) \
|
||||
(pthread_in_use () ? pthread_mutex_destroy (LOCK) : 0)
|
||||
extern int glthread_recursive_lock_init_multithreaded (gl_recursive_lock_t *lock);
|
||||
|
||||
# else
|
||||
|
||||
|
@ -290,18 +311,18 @@ typedef struct
|
|||
STORAGECLASS gl_recursive_lock_t NAME = gl_recursive_lock_initializer;
|
||||
# define gl_recursive_lock_initializer \
|
||||
{ PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, 0 }
|
||||
# define gl_recursive_lock_init(NAME) \
|
||||
if (pthread_in_use ()) glthread_recursive_lock_init (&NAME)
|
||||
# define gl_recursive_lock_lock(NAME) \
|
||||
if (pthread_in_use ()) glthread_recursive_lock_lock (&NAME)
|
||||
# define gl_recursive_lock_unlock(NAME) \
|
||||
if (pthread_in_use ()) glthread_recursive_lock_unlock (&NAME)
|
||||
# define gl_recursive_lock_destroy(NAME) \
|
||||
if (pthread_in_use ()) glthread_recursive_lock_destroy (&NAME)
|
||||
extern void glthread_recursive_lock_init (gl_recursive_lock_t *lock);
|
||||
extern void glthread_recursive_lock_lock (gl_recursive_lock_t *lock);
|
||||
extern void glthread_recursive_lock_unlock (gl_recursive_lock_t *lock);
|
||||
extern void glthread_recursive_lock_destroy (gl_recursive_lock_t *lock);
|
||||
# define glthread_recursive_lock_init(LOCK) \
|
||||
(pthread_in_use () ? glthread_recursive_lock_init_multithreaded (LOCK) : 0)
|
||||
# define glthread_recursive_lock_lock(LOCK) \
|
||||
(pthread_in_use () ? glthread_recursive_lock_lock_multithreaded (LOCK) : 0)
|
||||
# define glthread_recursive_lock_unlock(LOCK) \
|
||||
(pthread_in_use () ? glthread_recursive_lock_unlock_multithreaded (LOCK) : 0)
|
||||
# define glthread_recursive_lock_destroy(LOCK) \
|
||||
(pthread_in_use () ? glthread_recursive_lock_destroy_multithreaded (LOCK) : 0)
|
||||
extern int glthread_recursive_lock_init_multithreaded (gl_recursive_lock_t *lock);
|
||||
extern int glthread_recursive_lock_lock_multithreaded (gl_recursive_lock_t *lock);
|
||||
extern int glthread_recursive_lock_unlock_multithreaded (gl_recursive_lock_t *lock);
|
||||
extern int glthread_recursive_lock_destroy_multithreaded (gl_recursive_lock_t *lock);
|
||||
|
||||
# endif
|
||||
|
||||
|
@ -323,18 +344,18 @@ typedef struct
|
|||
STORAGECLASS gl_recursive_lock_t NAME = gl_recursive_lock_initializer;
|
||||
# define gl_recursive_lock_initializer \
|
||||
{ PTHREAD_MUTEX_INITIALIZER, (pthread_t) 0, 0 }
|
||||
# define gl_recursive_lock_init(NAME) \
|
||||
if (pthread_in_use ()) glthread_recursive_lock_init (&NAME)
|
||||
# define gl_recursive_lock_lock(NAME) \
|
||||
if (pthread_in_use ()) glthread_recursive_lock_lock (&NAME)
|
||||
# define gl_recursive_lock_unlock(NAME) \
|
||||
if (pthread_in_use ()) glthread_recursive_lock_unlock (&NAME)
|
||||
# define gl_recursive_lock_destroy(NAME) \
|
||||
if (pthread_in_use ()) glthread_recursive_lock_destroy (&NAME)
|
||||
extern void glthread_recursive_lock_init (gl_recursive_lock_t *lock);
|
||||
extern void glthread_recursive_lock_lock (gl_recursive_lock_t *lock);
|
||||
extern void glthread_recursive_lock_unlock (gl_recursive_lock_t *lock);
|
||||
extern void glthread_recursive_lock_destroy (gl_recursive_lock_t *lock);
|
||||
# define glthread_recursive_lock_init(LOCK) \
|
||||
(pthread_in_use () ? glthread_recursive_lock_init_multithreaded (LOCK) : 0)
|
||||
# define glthread_recursive_lock_lock(LOCK) \
|
||||
(pthread_in_use () ? glthread_recursive_lock_lock_multithreaded (LOCK) : 0)
|
||||
# define glthread_recursive_lock_unlock(LOCK) \
|
||||
(pthread_in_use () ? glthread_recursive_lock_unlock_multithreaded (LOCK) : 0)
|
||||
# define glthread_recursive_lock_destroy(LOCK) \
|
||||
(pthread_in_use () ? glthread_recursive_lock_destroy_multithreaded (LOCK) : 0)
|
||||
extern int glthread_recursive_lock_init_multithreaded (gl_recursive_lock_t *lock);
|
||||
extern int glthread_recursive_lock_lock_multithreaded (gl_recursive_lock_t *lock);
|
||||
extern int glthread_recursive_lock_unlock_multithreaded (gl_recursive_lock_t *lock);
|
||||
extern int glthread_recursive_lock_destroy_multithreaded (gl_recursive_lock_t *lock);
|
||||
|
||||
# endif
|
||||
|
||||
|
@ -343,21 +364,10 @@ extern void glthread_recursive_lock_destroy (gl_recursive_lock_t *lock);
|
|||
typedef pthread_once_t gl_once_t;
|
||||
# define gl_once_define(STORAGECLASS, NAME) \
|
||||
STORAGECLASS pthread_once_t NAME = PTHREAD_ONCE_INIT;
|
||||
# define gl_once(NAME, INITFUNCTION) \
|
||||
do \
|
||||
{ \
|
||||
if (pthread_in_use ()) \
|
||||
{ \
|
||||
if (pthread_once (&NAME, INITFUNCTION) != 0) \
|
||||
abort (); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
if (glthread_once_singlethreaded (&NAME)) \
|
||||
INITFUNCTION (); \
|
||||
} \
|
||||
} \
|
||||
while (0)
|
||||
# define glthread_once(ONCE_CONTROL, INITFUNCTION) \
|
||||
(pthread_in_use () \
|
||||
? pthread_once (ONCE_CONTROL, INITFUNCTION) \
|
||||
: (glthread_once_singlethreaded (ONCE_CONTROL) ? (INITFUNCTION (), 0) : 0))
|
||||
extern int glthread_once_singlethreaded (pthread_once_t *once_control);
|
||||
|
||||
# ifdef __cplusplus
|
||||
|
@ -373,7 +383,6 @@ extern int glthread_once_singlethreaded (pthread_once_t *once_control);
|
|||
/* Use the GNU Pth threads library. */
|
||||
|
||||
# include <pth.h>
|
||||
# include <stdlib.h>
|
||||
|
||||
# ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
@ -409,14 +418,14 @@ typedef pth_mutex_t gl_lock_t;
|
|||
STORAGECLASS pth_mutex_t NAME = gl_lock_initializer;
|
||||
# define gl_lock_initializer \
|
||||
PTH_MUTEX_INIT
|
||||
# define gl_lock_init(NAME) \
|
||||
if (pth_in_use() && !pth_mutex_init (&NAME)) abort ()
|
||||
# define gl_lock_lock(NAME) \
|
||||
if (pth_in_use() && !pth_mutex_acquire (&NAME, 0, NULL)) abort ()
|
||||
# define gl_lock_unlock(NAME) \
|
||||
if (pth_in_use() && !pth_mutex_release (&NAME)) abort ()
|
||||
# define gl_lock_destroy(NAME) \
|
||||
(void)(&NAME)
|
||||
# define glthread_lock_init(LOCK) \
|
||||
(pth_in_use () && !pth_mutex_init (LOCK) ? errno : 0)
|
||||
# define glthread_lock_lock(LOCK) \
|
||||
(pth_in_use () && !pth_mutex_acquire (LOCK, 0, NULL) ? errno : 0)
|
||||
# define glthread_lock_unlock(LOCK) \
|
||||
(pth_in_use () && !pth_mutex_release (LOCK) ? errno : 0)
|
||||
# define glthread_lock_destroy(LOCK) \
|
||||
((void)(LOCK), 0)
|
||||
|
||||
/* ------------------------- gl_rwlock_t datatype ------------------------- */
|
||||
|
||||
|
@ -427,16 +436,16 @@ typedef pth_rwlock_t gl_rwlock_t;
|
|||
STORAGECLASS pth_rwlock_t NAME = gl_rwlock_initializer;
|
||||
# define gl_rwlock_initializer \
|
||||
PTH_RWLOCK_INIT
|
||||
# define gl_rwlock_init(NAME) \
|
||||
if (pth_in_use() && !pth_rwlock_init (&NAME)) abort ()
|
||||
# define gl_rwlock_rdlock(NAME) \
|
||||
if (pth_in_use() && !pth_rwlock_acquire (&NAME, PTH_RWLOCK_RD, 0, NULL)) abort ()
|
||||
# define gl_rwlock_wrlock(NAME) \
|
||||
if (pth_in_use() && !pth_rwlock_acquire (&NAME, PTH_RWLOCK_RW, 0, NULL)) abort ()
|
||||
# define gl_rwlock_unlock(NAME) \
|
||||
if (pth_in_use() && !pth_rwlock_release (&NAME)) abort ()
|
||||
# define gl_rwlock_destroy(NAME) \
|
||||
(void)(&NAME)
|
||||
# define glthread_rwlock_init(LOCK) \
|
||||
(pth_in_use () && !pth_rwlock_init (LOCK) ? errno : 0)
|
||||
# define glthread_rwlock_rdlock(LOCK) \
|
||||
(pth_in_use () && !pth_rwlock_acquire (LOCK, PTH_RWLOCK_RD, 0, NULL) ? errno : 0)
|
||||
# define glthread_rwlock_wrlock(LOCK) \
|
||||
(pth_in_use () && !pth_rwlock_acquire (LOCK, PTH_RWLOCK_RW, 0, NULL) ? errno : 0)
|
||||
# define glthread_rwlock_unlock(LOCK) \
|
||||
(pth_in_use () && !pth_rwlock_release (LOCK) ? errno : 0)
|
||||
# define glthread_rwlock_destroy(LOCK) \
|
||||
((void)(LOCK), 0)
|
||||
|
||||
/* --------------------- gl_recursive_lock_t datatype --------------------- */
|
||||
|
||||
|
@ -448,37 +457,25 @@ typedef pth_mutex_t gl_recursive_lock_t;
|
|||
STORAGECLASS pth_mutex_t NAME = gl_recursive_lock_initializer;
|
||||
# define gl_recursive_lock_initializer \
|
||||
PTH_MUTEX_INIT
|
||||
# define gl_recursive_lock_init(NAME) \
|
||||
if (pth_in_use() && !pth_mutex_init (&NAME)) abort ()
|
||||
# define gl_recursive_lock_lock(NAME) \
|
||||
if (pth_in_use() && !pth_mutex_acquire (&NAME, 0, NULL)) abort ()
|
||||
# define gl_recursive_lock_unlock(NAME) \
|
||||
if (pth_in_use() && !pth_mutex_release (&NAME)) abort ()
|
||||
# define gl_recursive_lock_destroy(NAME) \
|
||||
(void)(&NAME)
|
||||
# define glthread_recursive_lock_init(LOCK) \
|
||||
(pth_in_use () && !pth_mutex_init (LOCK) ? errno : 0)
|
||||
# define glthread_recursive_lock_lock(LOCK) \
|
||||
(pth_in_use () && !pth_mutex_acquire (LOCK, 0, NULL) ? errno : 0)
|
||||
# define glthread_recursive_lock_unlock(LOCK) \
|
||||
(pth_in_use () && !pth_mutex_release (LOCK) ? errno : 0)
|
||||
# define glthread_recursive_lock_destroy(LOCK) \
|
||||
((void)(LOCK), 0)
|
||||
|
||||
/* -------------------------- gl_once_t datatype -------------------------- */
|
||||
|
||||
typedef pth_once_t gl_once_t;
|
||||
# define gl_once_define(STORAGECLASS, NAME) \
|
||||
STORAGECLASS pth_once_t NAME = PTH_ONCE_INIT;
|
||||
# define gl_once(NAME, INITFUNCTION) \
|
||||
do \
|
||||
{ \
|
||||
if (pth_in_use ()) \
|
||||
{ \
|
||||
void (*gl_once_temp) (void) = INITFUNCTION; \
|
||||
if (!pth_once (&NAME, glthread_once_call, &gl_once_temp)) \
|
||||
abort (); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
if (glthread_once_singlethreaded (&NAME)) \
|
||||
INITFUNCTION (); \
|
||||
} \
|
||||
} \
|
||||
while (0)
|
||||
extern void glthread_once_call (void *arg);
|
||||
# define glthread_once(ONCE_CONTROL, INITFUNCTION) \
|
||||
(pth_in_use () \
|
||||
? glthread_once_multithreaded (ONCE_CONTROL, INITFUNCTION) \
|
||||
: (glthread_once_singlethreaded (ONCE_CONTROL) ? (INITFUNCTION (), 0) : 0))
|
||||
extern int glthread_once_multithreaded (pth_once_t *once_control, void (*initfunction) (void));
|
||||
extern int glthread_once_singlethreaded (pth_once_t *once_control);
|
||||
|
||||
# ifdef __cplusplus
|
||||
|
@ -495,7 +492,6 @@ extern int glthread_once_singlethreaded (pth_once_t *once_control);
|
|||
|
||||
# include <thread.h>
|
||||
# include <synch.h>
|
||||
# include <stdlib.h>
|
||||
|
||||
# ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
@ -534,14 +530,14 @@ typedef mutex_t gl_lock_t;
|
|||
STORAGECLASS mutex_t NAME = gl_lock_initializer;
|
||||
# define gl_lock_initializer \
|
||||
DEFAULTMUTEX
|
||||
# define gl_lock_init(NAME) \
|
||||
if (thread_in_use () && mutex_init (&NAME, USYNC_THREAD, NULL) != 0) abort ()
|
||||
# define gl_lock_lock(NAME) \
|
||||
if (thread_in_use () && mutex_lock (&NAME) != 0) abort ()
|
||||
# define gl_lock_unlock(NAME) \
|
||||
if (thread_in_use () && mutex_unlock (&NAME) != 0) abort ()
|
||||
# define gl_lock_destroy(NAME) \
|
||||
if (thread_in_use () && mutex_destroy (&NAME) != 0) abort ()
|
||||
# define glthread_lock_init(LOCK) \
|
||||
(thread_in_use () ? mutex_init (LOCK, USYNC_THREAD, NULL) : 0)
|
||||
# define glthread_lock_lock(LOCK) \
|
||||
(thread_in_use () ? mutex_lock (LOCK) : 0)
|
||||
# define glthread_lock_unlock(LOCK) \
|
||||
(thread_in_use () ? mutex_unlock (LOCK) : 0)
|
||||
# define glthread_lock_destroy(LOCK) \
|
||||
(thread_in_use () ? mutex_destroy (LOCK) : 0)
|
||||
|
||||
/* ------------------------- gl_rwlock_t datatype ------------------------- */
|
||||
|
||||
|
@ -552,16 +548,16 @@ typedef rwlock_t gl_rwlock_t;
|
|||
STORAGECLASS rwlock_t NAME = gl_rwlock_initializer;
|
||||
# define gl_rwlock_initializer \
|
||||
DEFAULTRWLOCK
|
||||
# define gl_rwlock_init(NAME) \
|
||||
if (thread_in_use () && rwlock_init (&NAME, USYNC_THREAD, NULL) != 0) abort ()
|
||||
# define gl_rwlock_rdlock(NAME) \
|
||||
if (thread_in_use () && rw_rdlock (&NAME) != 0) abort ()
|
||||
# define gl_rwlock_wrlock(NAME) \
|
||||
if (thread_in_use () && rw_wrlock (&NAME) != 0) abort ()
|
||||
# define gl_rwlock_unlock(NAME) \
|
||||
if (thread_in_use () && rw_unlock (&NAME) != 0) abort ()
|
||||
# define gl_rwlock_destroy(NAME) \
|
||||
if (thread_in_use () && rwlock_destroy (&NAME) != 0) abort ()
|
||||
# define glthread_rwlock_init(LOCK) \
|
||||
(thread_in_use () ? rwlock_init (LOCK, USYNC_THREAD, NULL) : 0)
|
||||
# define glthread_rwlock_rdlock(LOCK) \
|
||||
(thread_in_use () ? rw_rdlock (LOCK) : 0)
|
||||
# define glthread_rwlock_wrlock(LOCK) \
|
||||
(thread_in_use () ? rw_wrlock (LOCK) : 0)
|
||||
# define glthread_rwlock_unlock(LOCK) \
|
||||
(thread_in_use () ? rw_unlock (LOCK) : 0)
|
||||
# define glthread_rwlock_destroy(LOCK) \
|
||||
(thread_in_use () ? rwlock_destroy (LOCK) : 0)
|
||||
|
||||
/* --------------------- gl_recursive_lock_t datatype --------------------- */
|
||||
|
||||
|
@ -581,18 +577,18 @@ typedef struct
|
|||
STORAGECLASS gl_recursive_lock_t NAME = gl_recursive_lock_initializer;
|
||||
# define gl_recursive_lock_initializer \
|
||||
{ DEFAULTMUTEX, (thread_t) 0, 0 }
|
||||
# define gl_recursive_lock_init(NAME) \
|
||||
if (thread_in_use ()) glthread_recursive_lock_init (&NAME)
|
||||
# define gl_recursive_lock_lock(NAME) \
|
||||
if (thread_in_use ()) glthread_recursive_lock_lock (&NAME)
|
||||
# define gl_recursive_lock_unlock(NAME) \
|
||||
if (thread_in_use ()) glthread_recursive_lock_unlock (&NAME)
|
||||
# define gl_recursive_lock_destroy(NAME) \
|
||||
if (thread_in_use ()) glthread_recursive_lock_destroy (&NAME)
|
||||
extern void glthread_recursive_lock_init (gl_recursive_lock_t *lock);
|
||||
extern void glthread_recursive_lock_lock (gl_recursive_lock_t *lock);
|
||||
extern void glthread_recursive_lock_unlock (gl_recursive_lock_t *lock);
|
||||
extern void glthread_recursive_lock_destroy (gl_recursive_lock_t *lock);
|
||||
# define glthread_recursive_lock_init(LOCK) \
|
||||
(thread_in_use () ? glthread_recursive_lock_init_multithreaded (LOCK) : 0)
|
||||
# define glthread_recursive_lock_lock(LOCK) \
|
||||
(thread_in_use () ? glthread_recursive_lock_lock_multithreaded (LOCK) : 0)
|
||||
# define glthread_recursive_lock_unlock(LOCK) \
|
||||
(thread_in_use () ? glthread_recursive_lock_unlock_multithreaded (LOCK) : 0)
|
||||
# define glthread_recursive_lock_destroy(LOCK) \
|
||||
(thread_in_use () ? glthread_recursive_lock_destroy_multithreaded (LOCK) : 0)
|
||||
extern int glthread_recursive_lock_init_multithreaded (gl_recursive_lock_t *lock);
|
||||
extern int glthread_recursive_lock_lock_multithreaded (gl_recursive_lock_t *lock);
|
||||
extern int glthread_recursive_lock_unlock_multithreaded (gl_recursive_lock_t *lock);
|
||||
extern int glthread_recursive_lock_destroy_multithreaded (gl_recursive_lock_t *lock);
|
||||
|
||||
/* -------------------------- gl_once_t datatype -------------------------- */
|
||||
|
||||
|
@ -604,21 +600,11 @@ typedef struct
|
|||
gl_once_t;
|
||||
# define gl_once_define(STORAGECLASS, NAME) \
|
||||
STORAGECLASS gl_once_t NAME = { 0, DEFAULTMUTEX };
|
||||
# define gl_once(NAME, INITFUNCTION) \
|
||||
do \
|
||||
{ \
|
||||
if (thread_in_use ()) \
|
||||
{ \
|
||||
glthread_once (&NAME, INITFUNCTION); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
if (glthread_once_singlethreaded (&NAME)) \
|
||||
INITFUNCTION (); \
|
||||
} \
|
||||
} \
|
||||
while (0)
|
||||
extern void glthread_once (gl_once_t *once_control, void (*initfunction) (void));
|
||||
# define glthread_once(ONCE_CONTROL, INITFUNCTION) \
|
||||
(thread_in_use () \
|
||||
? glthread_once_multithreaded (ONCE_CONTROL, INITFUNCTION) \
|
||||
: (glthread_once_singlethreaded (ONCE_CONTROL) ? (INITFUNCTION (), 0) : 0))
|
||||
extern int glthread_once_multithreaded (gl_once_t *once_control, void (*initfunction) (void));
|
||||
extern int glthread_once_singlethreaded (gl_once_t *once_control);
|
||||
|
||||
# ifdef __cplusplus
|
||||
|
@ -664,18 +650,18 @@ typedef struct
|
|||
STORAGECLASS gl_lock_t NAME = gl_lock_initializer;
|
||||
# define gl_lock_initializer \
|
||||
{ { 0, -1 } }
|
||||
# define gl_lock_init(NAME) \
|
||||
glthread_lock_init (&NAME)
|
||||
# define gl_lock_lock(NAME) \
|
||||
glthread_lock_lock (&NAME)
|
||||
# define gl_lock_unlock(NAME) \
|
||||
glthread_lock_unlock (&NAME)
|
||||
# define gl_lock_destroy(NAME) \
|
||||
glthread_lock_destroy (&NAME)
|
||||
extern void glthread_lock_init (gl_lock_t *lock);
|
||||
extern void glthread_lock_lock (gl_lock_t *lock);
|
||||
extern void glthread_lock_unlock (gl_lock_t *lock);
|
||||
extern void glthread_lock_destroy (gl_lock_t *lock);
|
||||
# define glthread_lock_init(LOCK) \
|
||||
(glthread_lock_init_func (LOCK), 0)
|
||||
# define glthread_lock_lock(LOCK) \
|
||||
glthread_lock_lock_func (LOCK)
|
||||
# define glthread_lock_unlock(LOCK) \
|
||||
glthread_lock_unlock_func (LOCK)
|
||||
# define glthread_lock_destroy(LOCK) \
|
||||
glthread_lock_destroy_func (LOCK)
|
||||
extern void glthread_lock_init_func (gl_lock_t *lock);
|
||||
extern int glthread_lock_lock_func (gl_lock_t *lock);
|
||||
extern int glthread_lock_unlock_func (gl_lock_t *lock);
|
||||
extern int glthread_lock_destroy_func (gl_lock_t *lock);
|
||||
|
||||
/* ------------------------- gl_rwlock_t datatype ------------------------- */
|
||||
|
||||
|
@ -690,13 +676,13 @@ typedef struct
|
|||
unsigned int alloc; /* length of allocated array */
|
||||
unsigned int offset; /* index of first waiting thread in array */
|
||||
}
|
||||
gl_waitqueue_t;
|
||||
gl_carray_waitqueue_t;
|
||||
typedef struct
|
||||
{
|
||||
gl_spinlock_t guard; /* protects the initialization */
|
||||
CRITICAL_SECTION lock; /* protects the remaining fields */
|
||||
gl_waitqueue_t waiting_readers; /* waiting readers */
|
||||
gl_waitqueue_t waiting_writers; /* waiting writers */
|
||||
gl_carray_waitqueue_t waiting_readers; /* waiting readers */
|
||||
gl_carray_waitqueue_t waiting_writers; /* waiting writers */
|
||||
int runcount; /* number of readers running, or -1 when a writer runs */
|
||||
}
|
||||
gl_rwlock_t;
|
||||
|
@ -706,21 +692,21 @@ typedef struct
|
|||
STORAGECLASS gl_rwlock_t NAME = gl_rwlock_initializer;
|
||||
# define gl_rwlock_initializer \
|
||||
{ { 0, -1 } }
|
||||
# define gl_rwlock_init(NAME) \
|
||||
glthread_rwlock_init (&NAME)
|
||||
# define gl_rwlock_rdlock(NAME) \
|
||||
glthread_rwlock_rdlock (&NAME)
|
||||
# define gl_rwlock_wrlock(NAME) \
|
||||
glthread_rwlock_wrlock (&NAME)
|
||||
# define gl_rwlock_unlock(NAME) \
|
||||
glthread_rwlock_unlock (&NAME)
|
||||
# define gl_rwlock_destroy(NAME) \
|
||||
glthread_rwlock_destroy (&NAME)
|
||||
extern void glthread_rwlock_init (gl_rwlock_t *lock);
|
||||
extern void glthread_rwlock_rdlock (gl_rwlock_t *lock);
|
||||
extern void glthread_rwlock_wrlock (gl_rwlock_t *lock);
|
||||
extern void glthread_rwlock_unlock (gl_rwlock_t *lock);
|
||||
extern void glthread_rwlock_destroy (gl_rwlock_t *lock);
|
||||
# define glthread_rwlock_init(LOCK) \
|
||||
(glthread_rwlock_init_func (LOCK), 0)
|
||||
# define glthread_rwlock_rdlock(LOCK) \
|
||||
glthread_rwlock_rdlock_func (LOCK)
|
||||
# define glthread_rwlock_wrlock(LOCK) \
|
||||
glthread_rwlock_wrlock_func (LOCK)
|
||||
# define glthread_rwlock_unlock(LOCK) \
|
||||
glthread_rwlock_unlock_func (LOCK)
|
||||
# define glthread_rwlock_destroy(LOCK) \
|
||||
glthread_rwlock_destroy_func (LOCK)
|
||||
extern void glthread_rwlock_init_func (gl_rwlock_t *lock);
|
||||
extern int glthread_rwlock_rdlock_func (gl_rwlock_t *lock);
|
||||
extern int glthread_rwlock_wrlock_func (gl_rwlock_t *lock);
|
||||
extern int glthread_rwlock_unlock_func (gl_rwlock_t *lock);
|
||||
extern int glthread_rwlock_destroy_func (gl_rwlock_t *lock);
|
||||
|
||||
/* --------------------- gl_recursive_lock_t datatype --------------------- */
|
||||
|
||||
|
@ -742,18 +728,18 @@ typedef struct
|
|||
STORAGECLASS gl_recursive_lock_t NAME = gl_recursive_lock_initializer;
|
||||
# define gl_recursive_lock_initializer \
|
||||
{ { 0, -1 }, 0, 0 }
|
||||
# define gl_recursive_lock_init(NAME) \
|
||||
glthread_recursive_lock_init (&NAME)
|
||||
# define gl_recursive_lock_lock(NAME) \
|
||||
glthread_recursive_lock_lock (&NAME)
|
||||
# define gl_recursive_lock_unlock(NAME) \
|
||||
glthread_recursive_lock_unlock (&NAME)
|
||||
# define gl_recursive_lock_destroy(NAME) \
|
||||
glthread_recursive_lock_destroy (&NAME)
|
||||
extern void glthread_recursive_lock_init (gl_recursive_lock_t *lock);
|
||||
extern void glthread_recursive_lock_lock (gl_recursive_lock_t *lock);
|
||||
extern void glthread_recursive_lock_unlock (gl_recursive_lock_t *lock);
|
||||
extern void glthread_recursive_lock_destroy (gl_recursive_lock_t *lock);
|
||||
# define glthread_recursive_lock_init(LOCK) \
|
||||
(glthread_recursive_lock_init_func (LOCK), 0)
|
||||
# define glthread_recursive_lock_lock(LOCK) \
|
||||
glthread_recursive_lock_lock_func (LOCK)
|
||||
# define glthread_recursive_lock_unlock(LOCK) \
|
||||
glthread_recursive_lock_unlock_func (LOCK)
|
||||
# define glthread_recursive_lock_destroy(LOCK) \
|
||||
glthread_recursive_lock_destroy_func (LOCK)
|
||||
extern void glthread_recursive_lock_init_func (gl_recursive_lock_t *lock);
|
||||
extern int glthread_recursive_lock_lock_func (gl_recursive_lock_t *lock);
|
||||
extern int glthread_recursive_lock_unlock_func (gl_recursive_lock_t *lock);
|
||||
extern int glthread_recursive_lock_destroy_func (gl_recursive_lock_t *lock);
|
||||
|
||||
/* -------------------------- gl_once_t datatype -------------------------- */
|
||||
|
||||
|
@ -766,9 +752,9 @@ typedef struct
|
|||
gl_once_t;
|
||||
# define gl_once_define(STORAGECLASS, NAME) \
|
||||
STORAGECLASS gl_once_t NAME = { -1, -1 };
|
||||
# define gl_once(NAME, INITFUNCTION) \
|
||||
glthread_once (&NAME, INITFUNCTION)
|
||||
extern void glthread_once (gl_once_t *once_control, void (*initfunction) (void));
|
||||
# define glthread_once(ONCE_CONTROL, INITFUNCTION) \
|
||||
(glthread_once_func (ONCE_CONTROL, INITFUNCTION), 0)
|
||||
extern void glthread_once_func (gl_once_t *once_control, void (*initfunction) (void));
|
||||
|
||||
# ifdef __cplusplus
|
||||
}
|
||||
|
@ -787,47 +773,156 @@ extern void glthread_once (gl_once_t *once_control, void (*initfunction) (void))
|
|||
typedef int gl_lock_t;
|
||||
# define gl_lock_define(STORAGECLASS, NAME)
|
||||
# define gl_lock_define_initialized(STORAGECLASS, NAME)
|
||||
# define gl_lock_init(NAME)
|
||||
# define gl_lock_lock(NAME)
|
||||
# define gl_lock_unlock(NAME)
|
||||
# define glthread_lock_init(NAME) 0
|
||||
# define glthread_lock_lock(NAME) 0
|
||||
# define glthread_lock_unlock(NAME) 0
|
||||
# define glthread_lock_destroy(NAME) 0
|
||||
|
||||
/* ------------------------- gl_rwlock_t datatype ------------------------- */
|
||||
|
||||
typedef int gl_rwlock_t;
|
||||
# define gl_rwlock_define(STORAGECLASS, NAME)
|
||||
# define gl_rwlock_define_initialized(STORAGECLASS, NAME)
|
||||
# define gl_rwlock_init(NAME)
|
||||
# define gl_rwlock_rdlock(NAME)
|
||||
# define gl_rwlock_wrlock(NAME)
|
||||
# define gl_rwlock_unlock(NAME)
|
||||
# define glthread_rwlock_init(NAME) 0
|
||||
# define glthread_rwlock_rdlock(NAME) 0
|
||||
# define glthread_rwlock_wrlock(NAME) 0
|
||||
# define glthread_rwlock_unlock(NAME) 0
|
||||
# define glthread_rwlock_destroy(NAME) 0
|
||||
|
||||
/* --------------------- gl_recursive_lock_t datatype --------------------- */
|
||||
|
||||
typedef int gl_recursive_lock_t;
|
||||
# define gl_recursive_lock_define(STORAGECLASS, NAME)
|
||||
# define gl_recursive_lock_define_initialized(STORAGECLASS, NAME)
|
||||
# define gl_recursive_lock_init(NAME)
|
||||
# define gl_recursive_lock_lock(NAME)
|
||||
# define gl_recursive_lock_unlock(NAME)
|
||||
# define glthread_recursive_lock_init(NAME) 0
|
||||
# define glthread_recursive_lock_lock(NAME) 0
|
||||
# define glthread_recursive_lock_unlock(NAME) 0
|
||||
# define glthread_recursive_lock_destroy(NAME) 0
|
||||
|
||||
/* -------------------------- gl_once_t datatype -------------------------- */
|
||||
|
||||
typedef int gl_once_t;
|
||||
# define gl_once_define(STORAGECLASS, NAME) \
|
||||
STORAGECLASS gl_once_t NAME = 0;
|
||||
# define gl_once(NAME, INITFUNCTION) \
|
||||
do \
|
||||
{ \
|
||||
if (NAME == 0) \
|
||||
{ \
|
||||
NAME = ~ 0; \
|
||||
INITFUNCTION (); \
|
||||
} \
|
||||
} \
|
||||
while (0)
|
||||
# define glthread_once(ONCE_CONTROL, INITFUNCTION) \
|
||||
(*(ONCE_CONTROL) == 0 ? (*(ONCE_CONTROL) = ~ 0, INITFUNCTION (), 0) : 0)
|
||||
|
||||
#endif
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
/* Macros with built-in error handling. */
|
||||
|
||||
/* -------------------------- gl_lock_t datatype -------------------------- */
|
||||
|
||||
#define gl_lock_init(NAME) \
|
||||
do \
|
||||
{ \
|
||||
if (glthread_lock_init (&NAME)) \
|
||||
abort (); \
|
||||
} \
|
||||
while (0)
|
||||
#define gl_lock_lock(NAME) \
|
||||
do \
|
||||
{ \
|
||||
if (glthread_lock_lock (&NAME)) \
|
||||
abort (); \
|
||||
} \
|
||||
while (0)
|
||||
#define gl_lock_unlock(NAME) \
|
||||
do \
|
||||
{ \
|
||||
if (glthread_lock_unlock (&NAME)) \
|
||||
abort (); \
|
||||
} \
|
||||
while (0)
|
||||
#define gl_lock_destroy(NAME) \
|
||||
do \
|
||||
{ \
|
||||
if (glthread_lock_destroy (&NAME)) \
|
||||
abort (); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
/* ------------------------- gl_rwlock_t datatype ------------------------- */
|
||||
|
||||
#define gl_rwlock_init(NAME) \
|
||||
do \
|
||||
{ \
|
||||
if (glthread_rwlock_init (&NAME)) \
|
||||
abort (); \
|
||||
} \
|
||||
while (0)
|
||||
#define gl_rwlock_rdlock(NAME) \
|
||||
do \
|
||||
{ \
|
||||
if (glthread_rwlock_rdlock (&NAME)) \
|
||||
abort (); \
|
||||
} \
|
||||
while (0)
|
||||
#define gl_rwlock_wrlock(NAME) \
|
||||
do \
|
||||
{ \
|
||||
if (glthread_rwlock_wrlock (&NAME)) \
|
||||
abort (); \
|
||||
} \
|
||||
while (0)
|
||||
#define gl_rwlock_unlock(NAME) \
|
||||
do \
|
||||
{ \
|
||||
if (glthread_rwlock_unlock (&NAME)) \
|
||||
abort (); \
|
||||
} \
|
||||
while (0)
|
||||
#define gl_rwlock_destroy(NAME) \
|
||||
do \
|
||||
{ \
|
||||
if (glthread_rwlock_destroy (&NAME)) \
|
||||
abort (); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
/* --------------------- gl_recursive_lock_t datatype --------------------- */
|
||||
|
||||
#define gl_recursive_lock_init(NAME) \
|
||||
do \
|
||||
{ \
|
||||
if (glthread_recursive_lock_init (&NAME)) \
|
||||
abort (); \
|
||||
} \
|
||||
while (0)
|
||||
#define gl_recursive_lock_lock(NAME) \
|
||||
do \
|
||||
{ \
|
||||
if (glthread_recursive_lock_lock (&NAME)) \
|
||||
abort (); \
|
||||
} \
|
||||
while (0)
|
||||
#define gl_recursive_lock_unlock(NAME) \
|
||||
do \
|
||||
{ \
|
||||
if (glthread_recursive_lock_unlock (&NAME)) \
|
||||
abort (); \
|
||||
} \
|
||||
while (0)
|
||||
#define gl_recursive_lock_destroy(NAME) \
|
||||
do \
|
||||
{ \
|
||||
if (glthread_recursive_lock_destroy (&NAME)) \
|
||||
abort (); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
/* -------------------------- gl_once_t datatype -------------------------- */
|
||||
|
||||
#define gl_once(NAME, INITFUNCTION) \
|
||||
do \
|
||||
{ \
|
||||
if (glthread_once (&NAME, INITFUNCTION)) \
|
||||
abort (); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
#endif /* _LOCK_H */
|
||||
|
|
64
intl/log.c
64
intl/log.c
|
@ -1,5 +1,5 @@
|
|||
/* Log file output.
|
||||
Copyright (C) 2003, 2005 Free Software Foundation, Inc.
|
||||
Copyright (C) 2003, 2005, 2009 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Library General Public License as published
|
||||
|
@ -33,24 +33,27 @@
|
|||
# include "lock.h"
|
||||
#endif
|
||||
|
||||
/* Separator between msgctxt and msgid in .mo files. */
|
||||
#define MSGCTXT_SEPARATOR '\004' /* EOT */
|
||||
|
||||
/* Print an ASCII string with quotes and escape sequences where needed. */
|
||||
static void
|
||||
print_escaped (FILE *stream, const char *str)
|
||||
print_escaped (FILE *stream, const char *str, const char *str_end)
|
||||
{
|
||||
putc ('"', stream);
|
||||
for (; *str != '\0'; str++)
|
||||
for (; str != str_end; str++)
|
||||
if (*str == '\n')
|
||||
{
|
||||
fputs ("\\n\"", stream);
|
||||
if (str[1] == '\0')
|
||||
return;
|
||||
fputs ("\n\"", stream);
|
||||
fputs ("\\n\"", stream);
|
||||
if (str + 1 == str_end)
|
||||
return;
|
||||
fputs ("\n\"", stream);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (*str == '"' || *str == '\\')
|
||||
putc ('\\', stream);
|
||||
putc (*str, stream);
|
||||
if (*str == '"' || *str == '\\')
|
||||
putc ('\\', stream);
|
||||
putc (*str, stream);
|
||||
}
|
||||
putc ('"', stream);
|
||||
}
|
||||
|
@ -61,43 +64,52 @@ __libc_lock_define_initialized (static, lock)
|
|||
|
||||
static inline void
|
||||
_nl_log_untranslated_locked (const char *logfilename, const char *domainname,
|
||||
const char *msgid1, const char *msgid2, int plural)
|
||||
const char *msgid1, const char *msgid2, int plural)
|
||||
{
|
||||
FILE *logfile;
|
||||
const char *separator;
|
||||
|
||||
/* Can we reuse the last opened logfile? */
|
||||
if (last_logfilename == NULL || strcmp (logfilename, last_logfilename) != 0)
|
||||
{
|
||||
/* Close the last used logfile. */
|
||||
if (last_logfilename != NULL)
|
||||
{
|
||||
if (last_logfile != NULL)
|
||||
{
|
||||
fclose (last_logfile);
|
||||
last_logfile = NULL;
|
||||
}
|
||||
free (last_logfilename);
|
||||
last_logfilename = NULL;
|
||||
}
|
||||
{
|
||||
if (last_logfile != NULL)
|
||||
{
|
||||
fclose (last_logfile);
|
||||
last_logfile = NULL;
|
||||
}
|
||||
free (last_logfilename);
|
||||
last_logfilename = NULL;
|
||||
}
|
||||
/* Open the logfile. */
|
||||
last_logfilename = (char *) malloc (strlen (logfilename) + 1);
|
||||
if (last_logfilename == NULL)
|
||||
return;
|
||||
return;
|
||||
strcpy (last_logfilename, logfilename);
|
||||
last_logfile = fopen (logfilename, "a");
|
||||
if (last_logfile == NULL)
|
||||
return;
|
||||
return;
|
||||
}
|
||||
logfile = last_logfile;
|
||||
|
||||
fprintf (logfile, "domain ");
|
||||
print_escaped (logfile, domainname);
|
||||
print_escaped (logfile, domainname, domainname + strlen (domainname));
|
||||
separator = strchr (msgid1, MSGCTXT_SEPARATOR);
|
||||
if (separator != NULL)
|
||||
{
|
||||
/* The part before the MSGCTXT_SEPARATOR is the msgctxt. */
|
||||
fprintf (logfile, "\nmsgctxt ");
|
||||
print_escaped (logfile, msgid1, separator);
|
||||
msgid1 = separator + 1;
|
||||
}
|
||||
fprintf (logfile, "\nmsgid ");
|
||||
print_escaped (logfile, msgid1);
|
||||
print_escaped (logfile, msgid1, msgid1 + strlen (msgid1));
|
||||
if (plural)
|
||||
{
|
||||
fprintf (logfile, "\nmsgid_plural ");
|
||||
print_escaped (logfile, msgid2);
|
||||
print_escaped (logfile, msgid2, msgid2 + strlen (msgid2));
|
||||
fprintf (logfile, "\nmsgstr[0] \"\"\n");
|
||||
}
|
||||
else
|
||||
|
@ -108,7 +120,7 @@ _nl_log_untranslated_locked (const char *logfilename, const char *domainname,
|
|||
/* Add to the log file an entry denoting a failed translation. */
|
||||
void
|
||||
_nl_log_untranslated (const char *logfilename, const char *domainname,
|
||||
const char *msgid1, const char *msgid2, int plural)
|
||||
const char *msgid1, const char *msgid2, int plural)
|
||||
{
|
||||
__libc_lock_lock (lock);
|
||||
_nl_log_untranslated_locked (logfilename, domainname, msgid1, msgid2, plural);
|
||||
|
|
|
@ -21,15 +21,15 @@
|
|||
#ifndef OS2_AWARE
|
||||
|
||||
#undef LIBDIR
|
||||
#define LIBDIR _nlos2_libdir
|
||||
#define LIBDIR _nlos2_libdir
|
||||
extern char *_nlos2_libdir;
|
||||
|
||||
#undef LOCALEDIR
|
||||
#define LOCALEDIR _nlos2_localedir
|
||||
#define LOCALEDIR _nlos2_localedir
|
||||
extern char *_nlos2_localedir;
|
||||
|
||||
#undef LOCALE_ALIAS_PATH
|
||||
#define LOCALE_ALIAS_PATH _nlos2_localealiaspath
|
||||
#define LOCALE_ALIAS_PATH _nlos2_localealiaspath
|
||||
extern char *_nlos2_localealiaspath;
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* Expression parsing for plural form selection.
|
||||
Copyright (C) 2000-2001, 2003, 2005 Free Software Foundation, Inc.
|
||||
Copyright (C) 2000-2001, 2003, 2005-2007 Free Software Foundation, Inc.
|
||||
Written by Ulrich Drepper <drepper@cygnus.com>, 2000.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
|
@ -27,7 +27,7 @@
|
|||
|
||||
#include "plural-exp.h"
|
||||
|
||||
#if (defined __GNUC__ && !(__APPLE_CC__ > 1)) \
|
||||
#if (defined __GNUC__ && !(__APPLE_CC__ > 1) && !defined __cplusplus) \
|
||||
|| (defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L)
|
||||
|
||||
/* These structs are the constant expression for the germanic plural
|
||||
|
@ -96,7 +96,8 @@ init_germanic_plural ()
|
|||
|
||||
void
|
||||
internal_function
|
||||
EXTRACT_PLURAL_EXPRESSION (const char *nullentry, struct expression **pluralp,
|
||||
EXTRACT_PLURAL_EXPRESSION (const char *nullentry,
|
||||
const struct expression **pluralp,
|
||||
unsigned long int *npluralsp)
|
||||
{
|
||||
if (nullentry != NULL)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* Expression parsing and evaluation for plural form selection.
|
||||
Copyright (C) 2000-2003, 2005 Free Software Foundation, Inc.
|
||||
Copyright (C) 2000-2003, 2005-2007 Free Software Foundation, Inc.
|
||||
Written by Ulrich Drepper <drepper@cygnus.com>, 2000.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
|
@ -28,36 +28,42 @@
|
|||
# define attribute_hidden
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
enum expression_operator
|
||||
{
|
||||
/* Without arguments: */
|
||||
var, /* The variable "n". */
|
||||
num, /* Decimal number. */
|
||||
/* Unary operators: */
|
||||
lnot, /* Logical NOT. */
|
||||
/* Binary operators: */
|
||||
mult, /* Multiplication. */
|
||||
divide, /* Division. */
|
||||
module, /* Modulo operation. */
|
||||
plus, /* Addition. */
|
||||
minus, /* Subtraction. */
|
||||
less_than, /* Comparison. */
|
||||
greater_than, /* Comparison. */
|
||||
less_or_equal, /* Comparison. */
|
||||
greater_or_equal, /* Comparison. */
|
||||
equal, /* Comparison for equality. */
|
||||
not_equal, /* Comparison for inequality. */
|
||||
land, /* Logical AND. */
|
||||
lor, /* Logical OR. */
|
||||
/* Ternary operators: */
|
||||
qmop /* Question mark operator. */
|
||||
};
|
||||
|
||||
/* This is the representation of the expressions to determine the
|
||||
plural form. */
|
||||
struct expression
|
||||
{
|
||||
int nargs; /* Number of arguments. */
|
||||
enum operator
|
||||
{
|
||||
/* Without arguments: */
|
||||
var, /* The variable "n". */
|
||||
num, /* Decimal number. */
|
||||
/* Unary operators: */
|
||||
lnot, /* Logical NOT. */
|
||||
/* Binary operators: */
|
||||
mult, /* Multiplication. */
|
||||
divide, /* Division. */
|
||||
module, /* Modulo operation. */
|
||||
plus, /* Addition. */
|
||||
minus, /* Subtraction. */
|
||||
less_than, /* Comparison. */
|
||||
greater_than, /* Comparison. */
|
||||
less_or_equal, /* Comparison. */
|
||||
greater_or_equal, /* Comparison. */
|
||||
equal, /* Comparison for equality. */
|
||||
not_equal, /* Comparison for inequality. */
|
||||
land, /* Logical AND. */
|
||||
lor, /* Logical OR. */
|
||||
/* Ternary operators: */
|
||||
qmop /* Question mark operator. */
|
||||
} operation;
|
||||
enum expression_operator operation;
|
||||
union
|
||||
{
|
||||
unsigned long int num; /* Number value for `num'. */
|
||||
|
@ -106,13 +112,18 @@ extern void FREE_EXPRESSION (struct expression *exp)
|
|||
extern int PLURAL_PARSE (void *arg);
|
||||
extern struct expression GERMANIC_PLURAL attribute_hidden;
|
||||
extern void EXTRACT_PLURAL_EXPRESSION (const char *nullentry,
|
||||
struct expression **pluralp,
|
||||
const struct expression **pluralp,
|
||||
unsigned long int *npluralsp)
|
||||
internal_function;
|
||||
|
||||
#if !defined (_LIBC) && !defined (IN_LIBINTL) && !defined (IN_LIBGLOCALE)
|
||||
extern unsigned long int plural_eval (struct expression *pexp,
|
||||
extern unsigned long int plural_eval (const struct expression *pexp,
|
||||
unsigned long int n);
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _PLURAL_EXP_H */
|
||||
|
|
2010
intl/plural.c
2010
intl/plural.c
File diff suppressed because it is too large
Load diff
|
@ -1,6 +1,6 @@
|
|||
%{
|
||||
/* Expression parsing for plural form selection.
|
||||
Copyright (C) 2000-2001, 2003, 2005 Free Software Foundation, Inc.
|
||||
Copyright (C) 2000-2001, 2003, 2005-2006 Free Software Foundation, Inc.
|
||||
Written by Ulrich Drepper <drepper@cygnus.com>, 2000.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
|
@ -50,7 +50,7 @@
|
|||
|
||||
%union {
|
||||
unsigned long int num;
|
||||
enum operator op;
|
||||
enum expression_operator op;
|
||||
struct expression *exp;
|
||||
}
|
||||
|
||||
|
@ -62,7 +62,8 @@ static void yyerror (const char *str);
|
|||
/* Allocation of expressions. */
|
||||
|
||||
static struct expression *
|
||||
new_exp (int nargs, enum operator op, struct expression * const *args)
|
||||
new_exp (int nargs, enum expression_operator op,
|
||||
struct expression * const *args)
|
||||
{
|
||||
int i;
|
||||
struct expression *newp;
|
||||
|
@ -91,13 +92,13 @@ new_exp (int nargs, enum operator op, struct expression * const *args)
|
|||
}
|
||||
|
||||
static inline struct expression *
|
||||
new_exp_0 (enum operator op)
|
||||
new_exp_0 (enum expression_operator op)
|
||||
{
|
||||
return new_exp (0, op, NULL);
|
||||
}
|
||||
|
||||
static inline struct expression *
|
||||
new_exp_1 (enum operator op, struct expression *right)
|
||||
new_exp_1 (enum expression_operator op, struct expression *right)
|
||||
{
|
||||
struct expression *args[1];
|
||||
|
||||
|
@ -106,7 +107,8 @@ new_exp_1 (enum operator op, struct expression *right)
|
|||
}
|
||||
|
||||
static struct expression *
|
||||
new_exp_2 (enum operator op, struct expression *left, struct expression *right)
|
||||
new_exp_2 (enum expression_operator op, struct expression *left,
|
||||
struct expression *right)
|
||||
{
|
||||
struct expression *args[2];
|
||||
|
||||
|
@ -116,7 +118,7 @@ new_exp_2 (enum operator op, struct expression *left, struct expression *right)
|
|||
}
|
||||
|
||||
static inline struct expression *
|
||||
new_exp_3 (enum operator op, struct expression *bexp,
|
||||
new_exp_3 (enum expression_operator op, struct expression *bexp,
|
||||
struct expression *tbranch, struct expression *fbranch)
|
||||
{
|
||||
struct expression *args[3];
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* Decomposed printf argument list.
|
||||
Copyright (C) 1999, 2002-2003, 2005-2006 Free Software Foundation, Inc.
|
||||
Copyright (C) 1999, 2002-2003, 2005-2007 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Library General Public License as published
|
||||
|
@ -16,16 +16,25 @@
|
|||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
USA. */
|
||||
|
||||
#include <config.h>
|
||||
/* This file can be parametrized with the following macros:
|
||||
ENABLE_UNISTDIO Set to 1 to enable the unistdio extensions.
|
||||
PRINTF_FETCHARGS Name of the function to be defined.
|
||||
STATIC Set to 'static' to declare the function static. */
|
||||
|
||||
#ifndef PRINTF_FETCHARGS
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
/* Specification. */
|
||||
#include "printf-args.h"
|
||||
#ifndef PRINTF_FETCHARGS
|
||||
# include "printf-args.h"
|
||||
#endif
|
||||
|
||||
#ifdef STATIC
|
||||
STATIC
|
||||
#endif
|
||||
int
|
||||
printf_fetchargs (va_list args, arguments *a)
|
||||
PRINTF_FETCHARGS (va_list args, arguments *a)
|
||||
{
|
||||
size_t i;
|
||||
argument *ap;
|
||||
|
@ -34,109 +43,146 @@ printf_fetchargs (va_list args, arguments *a)
|
|||
switch (ap->type)
|
||||
{
|
||||
case TYPE_SCHAR:
|
||||
ap->a.a_schar = va_arg (args, /*signed char*/ int);
|
||||
break;
|
||||
ap->a.a_schar = va_arg (args, /*signed char*/ int);
|
||||
break;
|
||||
case TYPE_UCHAR:
|
||||
ap->a.a_uchar = va_arg (args, /*unsigned char*/ int);
|
||||
break;
|
||||
ap->a.a_uchar = va_arg (args, /*unsigned char*/ int);
|
||||
break;
|
||||
case TYPE_SHORT:
|
||||
ap->a.a_short = va_arg (args, /*short*/ int);
|
||||
break;
|
||||
ap->a.a_short = va_arg (args, /*short*/ int);
|
||||
break;
|
||||
case TYPE_USHORT:
|
||||
ap->a.a_ushort = va_arg (args, /*unsigned short*/ int);
|
||||
break;
|
||||
ap->a.a_ushort = va_arg (args, /*unsigned short*/ int);
|
||||
break;
|
||||
case TYPE_INT:
|
||||
ap->a.a_int = va_arg (args, int);
|
||||
break;
|
||||
ap->a.a_int = va_arg (args, int);
|
||||
break;
|
||||
case TYPE_UINT:
|
||||
ap->a.a_uint = va_arg (args, unsigned int);
|
||||
break;
|
||||
ap->a.a_uint = va_arg (args, unsigned int);
|
||||
break;
|
||||
case TYPE_LONGINT:
|
||||
ap->a.a_longint = va_arg (args, long int);
|
||||
break;
|
||||
ap->a.a_longint = va_arg (args, long int);
|
||||
break;
|
||||
case TYPE_ULONGINT:
|
||||
ap->a.a_ulongint = va_arg (args, unsigned long int);
|
||||
break;
|
||||
#ifdef HAVE_LONG_LONG_INT
|
||||
ap->a.a_ulongint = va_arg (args, unsigned long int);
|
||||
break;
|
||||
#if HAVE_LONG_LONG_INT
|
||||
case TYPE_LONGLONGINT:
|
||||
ap->a.a_longlongint = va_arg (args, long long int);
|
||||
break;
|
||||
ap->a.a_longlongint = va_arg (args, long long int);
|
||||
break;
|
||||
case TYPE_ULONGLONGINT:
|
||||
ap->a.a_ulonglongint = va_arg (args, unsigned long long int);
|
||||
break;
|
||||
ap->a.a_ulonglongint = va_arg (args, unsigned long long int);
|
||||
break;
|
||||
#endif
|
||||
case TYPE_DOUBLE:
|
||||
ap->a.a_double = va_arg (args, double);
|
||||
break;
|
||||
#ifdef HAVE_LONG_DOUBLE
|
||||
ap->a.a_double = va_arg (args, double);
|
||||
break;
|
||||
case TYPE_LONGDOUBLE:
|
||||
ap->a.a_longdouble = va_arg (args, long double);
|
||||
break;
|
||||
#endif
|
||||
ap->a.a_longdouble = va_arg (args, long double);
|
||||
break;
|
||||
case TYPE_CHAR:
|
||||
ap->a.a_char = va_arg (args, int);
|
||||
break;
|
||||
#ifdef HAVE_WINT_T
|
||||
ap->a.a_char = va_arg (args, int);
|
||||
break;
|
||||
#if HAVE_WINT_T
|
||||
case TYPE_WIDE_CHAR:
|
||||
/* Although ISO C 99 7.24.1.(2) says that wint_t is "unchanged by
|
||||
default argument promotions", this is not the case in mingw32,
|
||||
where wint_t is 'unsigned short'. */
|
||||
ap->a.a_wide_char =
|
||||
(sizeof (wint_t) < sizeof (int)
|
||||
? va_arg (args, int)
|
||||
: va_arg (args, wint_t));
|
||||
break;
|
||||
/* Although ISO C 99 7.24.1.(2) says that wint_t is "unchanged by
|
||||
default argument promotions", this is not the case in mingw32,
|
||||
where wint_t is 'unsigned short'. */
|
||||
ap->a.a_wide_char =
|
||||
(sizeof (wint_t) < sizeof (int)
|
||||
? va_arg (args, int)
|
||||
: va_arg (args, wint_t));
|
||||
break;
|
||||
#endif
|
||||
case TYPE_STRING:
|
||||
ap->a.a_string = va_arg (args, const char *);
|
||||
/* A null pointer is an invalid argument for "%s", but in practice
|
||||
it occurs quite frequently in printf statements that produce
|
||||
debug output. Use a fallback in this case. */
|
||||
if (ap->a.a_string == NULL)
|
||||
ap->a.a_string = "(NULL)";
|
||||
break;
|
||||
#ifdef HAVE_WCHAR_T
|
||||
ap->a.a_string = va_arg (args, const char *);
|
||||
/* A null pointer is an invalid argument for "%s", but in practice
|
||||
it occurs quite frequently in printf statements that produce
|
||||
debug output. Use a fallback in this case. */
|
||||
if (ap->a.a_string == NULL)
|
||||
ap->a.a_string = "(NULL)";
|
||||
break;
|
||||
#if HAVE_WCHAR_T
|
||||
case TYPE_WIDE_STRING:
|
||||
ap->a.a_wide_string = va_arg (args, const wchar_t *);
|
||||
/* A null pointer is an invalid argument for "%ls", but in practice
|
||||
it occurs quite frequently in printf statements that produce
|
||||
debug output. Use a fallback in this case. */
|
||||
if (ap->a.a_wide_string == NULL)
|
||||
{
|
||||
static const wchar_t wide_null_string[] =
|
||||
{
|
||||
(wchar_t)'(',
|
||||
(wchar_t)'N', (wchar_t)'U', (wchar_t)'L', (wchar_t)'L',
|
||||
(wchar_t)')',
|
||||
(wchar_t)0
|
||||
};
|
||||
ap->a.a_wide_string = wide_null_string;
|
||||
}
|
||||
break;
|
||||
ap->a.a_wide_string = va_arg (args, const wchar_t *);
|
||||
/* A null pointer is an invalid argument for "%ls", but in practice
|
||||
it occurs quite frequently in printf statements that produce
|
||||
debug output. Use a fallback in this case. */
|
||||
if (ap->a.a_wide_string == NULL)
|
||||
{
|
||||
static const wchar_t wide_null_string[] =
|
||||
{
|
||||
(wchar_t)'(',
|
||||
(wchar_t)'N', (wchar_t)'U', (wchar_t)'L', (wchar_t)'L',
|
||||
(wchar_t)')',
|
||||
(wchar_t)0
|
||||
};
|
||||
ap->a.a_wide_string = wide_null_string;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
case TYPE_POINTER:
|
||||
ap->a.a_pointer = va_arg (args, void *);
|
||||
break;
|
||||
ap->a.a_pointer = va_arg (args, void *);
|
||||
break;
|
||||
case TYPE_COUNT_SCHAR_POINTER:
|
||||
ap->a.a_count_schar_pointer = va_arg (args, signed char *);
|
||||
break;
|
||||
ap->a.a_count_schar_pointer = va_arg (args, signed char *);
|
||||
break;
|
||||
case TYPE_COUNT_SHORT_POINTER:
|
||||
ap->a.a_count_short_pointer = va_arg (args, short *);
|
||||
break;
|
||||
ap->a.a_count_short_pointer = va_arg (args, short *);
|
||||
break;
|
||||
case TYPE_COUNT_INT_POINTER:
|
||||
ap->a.a_count_int_pointer = va_arg (args, int *);
|
||||
break;
|
||||
ap->a.a_count_int_pointer = va_arg (args, int *);
|
||||
break;
|
||||
case TYPE_COUNT_LONGINT_POINTER:
|
||||
ap->a.a_count_longint_pointer = va_arg (args, long int *);
|
||||
break;
|
||||
#ifdef HAVE_LONG_LONG_INT
|
||||
ap->a.a_count_longint_pointer = va_arg (args, long int *);
|
||||
break;
|
||||
#if HAVE_LONG_LONG_INT
|
||||
case TYPE_COUNT_LONGLONGINT_POINTER:
|
||||
ap->a.a_count_longlongint_pointer = va_arg (args, long long int *);
|
||||
break;
|
||||
ap->a.a_count_longlongint_pointer = va_arg (args, long long int *);
|
||||
break;
|
||||
#endif
|
||||
#if ENABLE_UNISTDIO
|
||||
/* The unistdio extensions. */
|
||||
case TYPE_U8_STRING:
|
||||
ap->a.a_u8_string = va_arg (args, const uint8_t *);
|
||||
/* A null pointer is an invalid argument for "%U", but in practice
|
||||
it occurs quite frequently in printf statements that produce
|
||||
debug output. Use a fallback in this case. */
|
||||
if (ap->a.a_u8_string == NULL)
|
||||
{
|
||||
static const uint8_t u8_null_string[] =
|
||||
{ '(', 'N', 'U', 'L', 'L', ')', 0 };
|
||||
ap->a.a_u8_string = u8_null_string;
|
||||
}
|
||||
break;
|
||||
case TYPE_U16_STRING:
|
||||
ap->a.a_u16_string = va_arg (args, const uint16_t *);
|
||||
/* A null pointer is an invalid argument for "%lU", but in practice
|
||||
it occurs quite frequently in printf statements that produce
|
||||
debug output. Use a fallback in this case. */
|
||||
if (ap->a.a_u16_string == NULL)
|
||||
{
|
||||
static const uint16_t u16_null_string[] =
|
||||
{ '(', 'N', 'U', 'L', 'L', ')', 0 };
|
||||
ap->a.a_u16_string = u16_null_string;
|
||||
}
|
||||
break;
|
||||
case TYPE_U32_STRING:
|
||||
ap->a.a_u32_string = va_arg (args, const uint32_t *);
|
||||
/* A null pointer is an invalid argument for "%llU", but in practice
|
||||
it occurs quite frequently in printf statements that produce
|
||||
debug output. Use a fallback in this case. */
|
||||
if (ap->a.a_u32_string == NULL)
|
||||
{
|
||||
static const uint32_t u32_null_string[] =
|
||||
{ '(', 'N', 'U', 'L', 'L', ')', 0 };
|
||||
ap->a.a_u32_string = u32_null_string;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
/* Unknown type. */
|
||||
return -1;
|
||||
/* Unknown type. */
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* Decomposed printf argument list.
|
||||
Copyright (C) 1999, 2002-2003, 2006 Free Software Foundation, Inc.
|
||||
Copyright (C) 1999, 2002-2003, 2006-2007 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Library General Public License as published
|
||||
|
@ -19,16 +19,26 @@
|
|||
#ifndef _PRINTF_ARGS_H
|
||||
#define _PRINTF_ARGS_H
|
||||
|
||||
/* This file can be parametrized with the following macros:
|
||||
ENABLE_UNISTDIO Set to 1 to enable the unistdio extensions.
|
||||
PRINTF_FETCHARGS Name of the function to be declared.
|
||||
STATIC Set to 'static' to declare the function static. */
|
||||
|
||||
/* Default parameters. */
|
||||
#ifndef PRINTF_FETCHARGS
|
||||
# define PRINTF_FETCHARGS printf_fetchargs
|
||||
#endif
|
||||
|
||||
/* Get size_t. */
|
||||
#include <stddef.h>
|
||||
|
||||
/* Get wchar_t. */
|
||||
#ifdef HAVE_WCHAR_T
|
||||
#if HAVE_WCHAR_T
|
||||
# include <stddef.h>
|
||||
#endif
|
||||
|
||||
/* Get wint_t. */
|
||||
#ifdef HAVE_WINT_T
|
||||
#if HAVE_WINT_T
|
||||
# include <wchar.h>
|
||||
#endif
|
||||
|
||||
|
@ -48,20 +58,18 @@ typedef enum
|
|||
TYPE_UINT,
|
||||
TYPE_LONGINT,
|
||||
TYPE_ULONGINT,
|
||||
#ifdef HAVE_LONG_LONG_INT
|
||||
#if HAVE_LONG_LONG_INT
|
||||
TYPE_LONGLONGINT,
|
||||
TYPE_ULONGLONGINT,
|
||||
#endif
|
||||
TYPE_DOUBLE,
|
||||
#ifdef HAVE_LONG_DOUBLE
|
||||
TYPE_LONGDOUBLE,
|
||||
#endif
|
||||
TYPE_CHAR,
|
||||
#ifdef HAVE_WINT_T
|
||||
#if HAVE_WINT_T
|
||||
TYPE_WIDE_CHAR,
|
||||
#endif
|
||||
TYPE_STRING,
|
||||
#ifdef HAVE_WCHAR_T
|
||||
#if HAVE_WCHAR_T
|
||||
TYPE_WIDE_STRING,
|
||||
#endif
|
||||
TYPE_POINTER,
|
||||
|
@ -69,9 +77,15 @@ typedef enum
|
|||
TYPE_COUNT_SHORT_POINTER,
|
||||
TYPE_COUNT_INT_POINTER,
|
||||
TYPE_COUNT_LONGINT_POINTER
|
||||
#ifdef HAVE_LONG_LONG_INT
|
||||
#if HAVE_LONG_LONG_INT
|
||||
, TYPE_COUNT_LONGLONGINT_POINTER
|
||||
#endif
|
||||
#if ENABLE_UNISTDIO
|
||||
/* The unistdio extensions. */
|
||||
, TYPE_U8_STRING
|
||||
, TYPE_U16_STRING
|
||||
, TYPE_U32_STRING
|
||||
#endif
|
||||
} arg_type;
|
||||
|
||||
/* Polymorphic argument */
|
||||
|
@ -80,38 +94,42 @@ typedef struct
|
|||
arg_type type;
|
||||
union
|
||||
{
|
||||
signed char a_schar;
|
||||
unsigned char a_uchar;
|
||||
short a_short;
|
||||
unsigned short a_ushort;
|
||||
int a_int;
|
||||
unsigned int a_uint;
|
||||
long int a_longint;
|
||||
unsigned long int a_ulongint;
|
||||
#ifdef HAVE_LONG_LONG_INT
|
||||
long long int a_longlongint;
|
||||
unsigned long long int a_ulonglongint;
|
||||
signed char a_schar;
|
||||
unsigned char a_uchar;
|
||||
short a_short;
|
||||
unsigned short a_ushort;
|
||||
int a_int;
|
||||
unsigned int a_uint;
|
||||
long int a_longint;
|
||||
unsigned long int a_ulongint;
|
||||
#if HAVE_LONG_LONG_INT
|
||||
long long int a_longlongint;
|
||||
unsigned long long int a_ulonglongint;
|
||||
#endif
|
||||
float a_float;
|
||||
double a_double;
|
||||
#ifdef HAVE_LONG_DOUBLE
|
||||
long double a_longdouble;
|
||||
float a_float;
|
||||
double a_double;
|
||||
long double a_longdouble;
|
||||
int a_char;
|
||||
#if HAVE_WINT_T
|
||||
wint_t a_wide_char;
|
||||
#endif
|
||||
int a_char;
|
||||
#ifdef HAVE_WINT_T
|
||||
wint_t a_wide_char;
|
||||
const char* a_string;
|
||||
#if HAVE_WCHAR_T
|
||||
const wchar_t* a_wide_string;
|
||||
#endif
|
||||
const char* a_string;
|
||||
#ifdef HAVE_WCHAR_T
|
||||
const wchar_t* a_wide_string;
|
||||
void* a_pointer;
|
||||
signed char * a_count_schar_pointer;
|
||||
short * a_count_short_pointer;
|
||||
int * a_count_int_pointer;
|
||||
long int * a_count_longint_pointer;
|
||||
#if HAVE_LONG_LONG_INT
|
||||
long long int * a_count_longlongint_pointer;
|
||||
#endif
|
||||
void* a_pointer;
|
||||
signed char * a_count_schar_pointer;
|
||||
short * a_count_short_pointer;
|
||||
int * a_count_int_pointer;
|
||||
long int * a_count_longint_pointer;
|
||||
#ifdef HAVE_LONG_LONG_INT
|
||||
long long int * a_count_longlongint_pointer;
|
||||
#if ENABLE_UNISTDIO
|
||||
/* The unistdio extensions. */
|
||||
const uint8_t * a_u8_string;
|
||||
const uint16_t * a_u16_string;
|
||||
const uint32_t * a_u32_string;
|
||||
#endif
|
||||
}
|
||||
a;
|
||||
|
@ -132,6 +150,6 @@ STATIC
|
|||
#else
|
||||
extern
|
||||
#endif
|
||||
int printf_fetchargs (va_list args, arguments *a);
|
||||
int PRINTF_FETCHARGS (va_list args, arguments *a);
|
||||
|
||||
#endif /* _PRINTF_ARGS_H */
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -23,15 +23,15 @@
|
|||
|
||||
|
||||
/* Flags */
|
||||
#define FLAG_GROUP 1 /* ' flag */
|
||||
#define FLAG_LEFT 2 /* - flag */
|
||||
#define FLAG_SHOWSIGN 4 /* + flag */
|
||||
#define FLAG_SPACE 8 /* space flag */
|
||||
#define FLAG_ALT 16 /* # flag */
|
||||
#define FLAG_ZERO 32
|
||||
#define FLAG_GROUP 1 /* ' flag */
|
||||
#define FLAG_LEFT 2 /* - flag */
|
||||
#define FLAG_SHOWSIGN 4 /* + flag */
|
||||
#define FLAG_SPACE 8 /* space flag */
|
||||
#define FLAG_ALT 16 /* # flag */
|
||||
#define FLAG_ZERO 32
|
||||
|
||||
/* arg_index value indicating that no argument is consumed. */
|
||||
#define ARG_NONE (~(size_t)0)
|
||||
#define ARG_NONE (~(size_t)0)
|
||||
|
||||
/* A parsed directive. */
|
||||
typedef struct
|
||||
|
|
153
intl/printf.c
153
intl/printf.c
|
@ -1,5 +1,5 @@
|
|||
/* Formatted output to strings, using POSIX/XSI format strings with positions.
|
||||
Copyright (C) 2003, 2006 Free Software Foundation, Inc.
|
||||
Copyright (C) 2003, 2006-2007, 2009 Free Software Foundation, Inc.
|
||||
Written by Bruno Haible <bruno@clisp.org>, 2003.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
|
@ -60,7 +60,9 @@ char *alloca ();
|
|||
/* When building a DLL, we must export some functions. Note that because
|
||||
the functions are only defined for binary backward compatibility, we
|
||||
don't need to use __declspec(dllimport) in any case. */
|
||||
#if defined _MSC_VER && BUILDING_DLL
|
||||
#if HAVE_VISIBILITY && BUILDING_DLL
|
||||
# define DLL_EXPORTED __attribute__((__visibility__("default")))
|
||||
#elif defined _MSC_VER && BUILDING_DLL
|
||||
# define DLL_EXPORTED __declspec(dllexport)
|
||||
#else
|
||||
# define DLL_EXPORTED
|
||||
|
@ -69,7 +71,7 @@ char *alloca ();
|
|||
#define STATIC static
|
||||
|
||||
/* This needs to be consistent with libgnuintl.h.in. */
|
||||
#if defined __NetBSD__ || defined __CYGWIN__ || defined __MINGW32__
|
||||
#if defined __NetBSD__ || defined __BEOS__ || defined __CYGWIN__ || defined __MINGW32__
|
||||
/* Don't break __attribute__((format(printf,M,N))).
|
||||
This redefinition is only possible because the libc in NetBSD, Cygwin,
|
||||
mingw does not have a function __printf__. */
|
||||
|
@ -102,17 +104,17 @@ libintl_vfprintf (FILE *stream, const char *format, va_list args)
|
|||
char *result = libintl_vasnprintf (NULL, &length, format, args);
|
||||
int retval = -1;
|
||||
if (result != NULL)
|
||||
{
|
||||
size_t written = fwrite (result, 1, length, stream);
|
||||
free (result);
|
||||
if (written == length)
|
||||
{
|
||||
if (length > INT_MAX)
|
||||
errno = EOVERFLOW;
|
||||
else
|
||||
retval = length;
|
||||
}
|
||||
}
|
||||
{
|
||||
size_t written = fwrite (result, 1, length, stream);
|
||||
free (result);
|
||||
if (written == length)
|
||||
{
|
||||
if (length > INT_MAX)
|
||||
errno = EOVERFLOW;
|
||||
else
|
||||
retval = length;
|
||||
}
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
}
|
||||
|
@ -161,17 +163,17 @@ libintl_vsprintf (char *resultbuf, const char *format, va_list args)
|
|||
size_t length = (size_t) ~0 / (4 * sizeof (char));
|
||||
char *result = libintl_vasnprintf (resultbuf, &length, format, args);
|
||||
if (result != resultbuf)
|
||||
{
|
||||
free (result);
|
||||
return -1;
|
||||
}
|
||||
{
|
||||
free (result);
|
||||
return -1;
|
||||
}
|
||||
if (length > INT_MAX)
|
||||
{
|
||||
errno = EOVERFLOW;
|
||||
return -1;
|
||||
}
|
||||
{
|
||||
errno = EOVERFLOW;
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
return length;
|
||||
return length;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -209,23 +211,23 @@ libintl_vsnprintf (char *resultbuf, size_t length, const char *format, va_list a
|
|||
size_t maxlength = length;
|
||||
char *result = libintl_vasnprintf (resultbuf, &length, format, args);
|
||||
if (result != resultbuf)
|
||||
{
|
||||
if (maxlength > 0)
|
||||
{
|
||||
size_t pruned_length =
|
||||
(length < maxlength ? length : maxlength - 1);
|
||||
memcpy (resultbuf, result, pruned_length);
|
||||
resultbuf[pruned_length] = '\0';
|
||||
}
|
||||
free (result);
|
||||
}
|
||||
{
|
||||
if (maxlength > 0)
|
||||
{
|
||||
size_t pruned_length =
|
||||
(length < maxlength ? length : maxlength - 1);
|
||||
memcpy (resultbuf, result, pruned_length);
|
||||
resultbuf[pruned_length] = '\0';
|
||||
}
|
||||
free (result);
|
||||
}
|
||||
if (length > INT_MAX)
|
||||
{
|
||||
errno = EOVERFLOW;
|
||||
return -1;
|
||||
}
|
||||
{
|
||||
errno = EOVERFLOW;
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
return length;
|
||||
return length;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -285,7 +287,12 @@ libintl_asprintf (char **resultp, const char *format, ...)
|
|||
|
||||
#define WIDE_CHAR_VERSION 1
|
||||
|
||||
#include "wprintf-parse.h"
|
||||
/* Define auxiliary functions declared in "wprintf-parse.h". */
|
||||
#define CHAR_T wchar_t
|
||||
#define DIRECTIVE wchar_t_directive
|
||||
#define DIRECTIVES wchar_t_directives
|
||||
#define PRINTF_PARSE wprintf_parse
|
||||
#include "printf-parse.c"
|
||||
|
||||
/* Define functions declared in "vasnprintf.h". */
|
||||
|
@ -316,20 +323,20 @@ libintl_vfwprintf (FILE *stream, const wchar_t *format, va_list args)
|
|||
wchar_t *result = libintl_vasnwprintf (NULL, &length, format, args);
|
||||
int retval = -1;
|
||||
if (result != NULL)
|
||||
{
|
||||
size_t i;
|
||||
for (i = 0; i < length; i++)
|
||||
if (fputwc (result[i], stream) == WEOF)
|
||||
break;
|
||||
free (result);
|
||||
if (i == length)
|
||||
{
|
||||
if (length > INT_MAX)
|
||||
errno = EOVERFLOW;
|
||||
else
|
||||
retval = length;
|
||||
}
|
||||
}
|
||||
{
|
||||
size_t i;
|
||||
for (i = 0; i < length; i++)
|
||||
if (fputwc (result[i], stream) == WEOF)
|
||||
break;
|
||||
free (result);
|
||||
if (i == length)
|
||||
{
|
||||
if (length > INT_MAX)
|
||||
errno = EOVERFLOW;
|
||||
else
|
||||
retval = length;
|
||||
}
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
}
|
||||
|
@ -378,29 +385,29 @@ libintl_vswprintf (wchar_t *resultbuf, size_t length, const wchar_t *format, va_
|
|||
size_t maxlength = length;
|
||||
wchar_t *result = libintl_vasnwprintf (resultbuf, &length, format, args);
|
||||
if (result != resultbuf)
|
||||
{
|
||||
if (maxlength > 0)
|
||||
{
|
||||
size_t pruned_length =
|
||||
(length < maxlength ? length : maxlength - 1);
|
||||
memcpy (resultbuf, result, pruned_length * sizeof (wchar_t));
|
||||
resultbuf[pruned_length] = 0;
|
||||
}
|
||||
free (result);
|
||||
/* Unlike vsnprintf, which has to return the number of character that
|
||||
would have been produced if the resultbuf had been sufficiently
|
||||
large, the vswprintf function has to return a negative value if
|
||||
the resultbuf was not sufficiently large. */
|
||||
if (length >= maxlength)
|
||||
return -1;
|
||||
}
|
||||
{
|
||||
if (maxlength > 0)
|
||||
{
|
||||
size_t pruned_length =
|
||||
(length < maxlength ? length : maxlength - 1);
|
||||
memcpy (resultbuf, result, pruned_length * sizeof (wchar_t));
|
||||
resultbuf[pruned_length] = 0;
|
||||
}
|
||||
free (result);
|
||||
/* Unlike vsnprintf, which has to return the number of character that
|
||||
would have been produced if the resultbuf had been sufficiently
|
||||
large, the vswprintf function has to return a negative value if
|
||||
the resultbuf was not sufficiently large. */
|
||||
if (length >= maxlength)
|
||||
return -1;
|
||||
}
|
||||
if (length > INT_MAX)
|
||||
{
|
||||
errno = EOVERFLOW;
|
||||
return -1;
|
||||
}
|
||||
{
|
||||
errno = EOVERFLOW;
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
return length;
|
||||
return length;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* Provide relocatable packages.
|
||||
Copyright (C) 2003-2006 Free Software Foundation, Inc.
|
||||
Copyright (C) 2003-2006, 2008-2009 Free Software Foundation, Inc.
|
||||
Written by Bruno Haible <bruno@clisp.org>, 2003.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
|
@ -22,7 +22,7 @@
|
|||
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
|
||||
# define _GNU_SOURCE 1
|
||||
#endif
|
||||
|
||||
#include <config.h>
|
||||
|
@ -102,11 +102,11 @@ static size_t curr_prefix_len;
|
|||
instead of "/"). */
|
||||
static void
|
||||
set_this_relocation_prefix (const char *orig_prefix_arg,
|
||||
const char *curr_prefix_arg)
|
||||
const char *curr_prefix_arg)
|
||||
{
|
||||
if (orig_prefix_arg != NULL && curr_prefix_arg != NULL
|
||||
/* Optimization: if orig_prefix and curr_prefix are equal, the
|
||||
relocation is a nop. */
|
||||
relocation is a nop. */
|
||||
&& strcmp (orig_prefix_arg, curr_prefix_arg) != 0)
|
||||
{
|
||||
/* Duplicate the argument strings. */
|
||||
|
@ -118,14 +118,14 @@ set_this_relocation_prefix (const char *orig_prefix_arg,
|
|||
#ifdef NO_XMALLOC
|
||||
if (memory != NULL)
|
||||
#endif
|
||||
{
|
||||
memcpy (memory, orig_prefix_arg, orig_prefix_len + 1);
|
||||
orig_prefix = memory;
|
||||
memory += orig_prefix_len + 1;
|
||||
memcpy (memory, curr_prefix_arg, curr_prefix_len + 1);
|
||||
curr_prefix = memory;
|
||||
return;
|
||||
}
|
||||
{
|
||||
memcpy (memory, orig_prefix_arg, orig_prefix_len + 1);
|
||||
orig_prefix = memory;
|
||||
memory += orig_prefix_len + 1;
|
||||
memcpy (memory, curr_prefix_arg, curr_prefix_len + 1);
|
||||
curr_prefix = memory;
|
||||
return;
|
||||
}
|
||||
}
|
||||
orig_prefix = NULL;
|
||||
curr_prefix = NULL;
|
||||
|
@ -160,17 +160,18 @@ set_relocation_prefix (const char *orig_prefix_arg, const char *curr_prefix_arg)
|
|||
/* Convenience function:
|
||||
Computes the current installation prefix, based on the original
|
||||
installation prefix, the original installation directory of a particular
|
||||
file, and the current pathname of this file. Returns NULL upon failure. */
|
||||
file, and the current pathname of this file.
|
||||
Returns it, freshly allocated. Returns NULL upon failure. */
|
||||
#ifdef IN_LIBRARY
|
||||
#define compute_curr_prefix local_compute_curr_prefix
|
||||
static
|
||||
#endif
|
||||
const char *
|
||||
char *
|
||||
compute_curr_prefix (const char *orig_installprefix,
|
||||
const char *orig_installdir,
|
||||
const char *curr_pathname)
|
||||
const char *orig_installdir,
|
||||
const char *curr_pathname)
|
||||
{
|
||||
const char *curr_installdir;
|
||||
char *curr_installdir;
|
||||
const char *rel_installdir;
|
||||
|
||||
if (curr_pathname == NULL)
|
||||
|
@ -193,9 +194,9 @@ compute_curr_prefix (const char *orig_installprefix,
|
|||
|
||||
while (p > p_base)
|
||||
{
|
||||
p--;
|
||||
if (ISSLASH (*p))
|
||||
break;
|
||||
p--;
|
||||
if (ISSLASH (*p))
|
||||
break;
|
||||
}
|
||||
|
||||
q = (char *) xmalloc (p - curr_pathname + 1);
|
||||
|
@ -218,44 +219,47 @@ compute_curr_prefix (const char *orig_installprefix,
|
|||
|
||||
while (rp > rel_installdir && cp > cp_base)
|
||||
{
|
||||
bool same = false;
|
||||
const char *rpi = rp;
|
||||
const char *cpi = cp;
|
||||
bool same = false;
|
||||
const char *rpi = rp;
|
||||
const char *cpi = cp;
|
||||
|
||||
while (rpi > rel_installdir && cpi > cp_base)
|
||||
{
|
||||
rpi--;
|
||||
cpi--;
|
||||
if (ISSLASH (*rpi) || ISSLASH (*cpi))
|
||||
{
|
||||
if (ISSLASH (*rpi) && ISSLASH (*cpi))
|
||||
same = true;
|
||||
break;
|
||||
}
|
||||
/* Do case-insensitive comparison if the filesystem is always or
|
||||
often case-insensitive. It's better to accept the comparison
|
||||
if the difference is only in case, rather than to fail. */
|
||||
while (rpi > rel_installdir && cpi > cp_base)
|
||||
{
|
||||
rpi--;
|
||||
cpi--;
|
||||
if (ISSLASH (*rpi) || ISSLASH (*cpi))
|
||||
{
|
||||
if (ISSLASH (*rpi) && ISSLASH (*cpi))
|
||||
same = true;
|
||||
break;
|
||||
}
|
||||
/* Do case-insensitive comparison if the file system is always or
|
||||
often case-insensitive. It's better to accept the comparison
|
||||
if the difference is only in case, rather than to fail. */
|
||||
#if defined _WIN32 || defined __WIN32__ || defined __CYGWIN__ || defined __EMX__ || defined __DJGPP__
|
||||
/* Win32, Cygwin, OS/2, DOS - case insignificant filesystem */
|
||||
if ((*rpi >= 'a' && *rpi <= 'z' ? *rpi - 'a' + 'A' : *rpi)
|
||||
!= (*cpi >= 'a' && *cpi <= 'z' ? *cpi - 'a' + 'A' : *cpi))
|
||||
break;
|
||||
/* Win32, Cygwin, OS/2, DOS - case insignificant file system */
|
||||
if ((*rpi >= 'a' && *rpi <= 'z' ? *rpi - 'a' + 'A' : *rpi)
|
||||
!= (*cpi >= 'a' && *cpi <= 'z' ? *cpi - 'a' + 'A' : *cpi))
|
||||
break;
|
||||
#else
|
||||
if (*rpi != *cpi)
|
||||
break;
|
||||
if (*rpi != *cpi)
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
if (!same)
|
||||
break;
|
||||
/* The last pathname component was the same. opi and cpi now point
|
||||
to the slash before it. */
|
||||
rp = rpi;
|
||||
cp = cpi;
|
||||
}
|
||||
if (!same)
|
||||
break;
|
||||
/* The last pathname component was the same. opi and cpi now point
|
||||
to the slash before it. */
|
||||
rp = rpi;
|
||||
cp = cpi;
|
||||
}
|
||||
|
||||
if (rp > rel_installdir)
|
||||
/* Unexpected: The curr_installdir does not end with rel_installdir. */
|
||||
return NULL;
|
||||
{
|
||||
/* Unexpected: The curr_installdir does not end with rel_installdir. */
|
||||
free (curr_installdir);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
{
|
||||
size_t curr_prefix_len = cp - curr_installdir;
|
||||
|
@ -264,11 +268,16 @@ compute_curr_prefix (const char *orig_installprefix,
|
|||
curr_prefix = (char *) xmalloc (curr_prefix_len + 1);
|
||||
#ifdef NO_XMALLOC
|
||||
if (curr_prefix == NULL)
|
||||
return NULL;
|
||||
{
|
||||
free (curr_installdir);
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
memcpy (curr_prefix, curr_installdir, curr_prefix_len);
|
||||
curr_prefix[curr_prefix_len] = '\0';
|
||||
|
||||
free (curr_installdir);
|
||||
|
||||
return curr_prefix;
|
||||
}
|
||||
}
|
||||
|
@ -296,30 +305,30 @@ DllMain (HINSTANCE module_handle, DWORD event, LPVOID reserved)
|
|||
static char location[MAX_PATH];
|
||||
|
||||
if (!GetModuleFileName (module_handle, location, sizeof (location)))
|
||||
/* Shouldn't happen. */
|
||||
return FALSE;
|
||||
/* Shouldn't happen. */
|
||||
return FALSE;
|
||||
|
||||
if (!IS_PATH_WITH_DIR (location))
|
||||
/* Shouldn't happen. */
|
||||
return FALSE;
|
||||
/* Shouldn't happen. */
|
||||
return FALSE;
|
||||
|
||||
{
|
||||
#if defined __CYGWIN__
|
||||
/* On Cygwin, we need to convert paths coming from Win32 system calls
|
||||
to the Unix-like slashified notation. */
|
||||
static char location_as_posix_path[2 * MAX_PATH];
|
||||
/* There's no error return defined for cygwin_conv_to_posix_path.
|
||||
See cygwin-api/func-cygwin-conv-to-posix-path.html.
|
||||
Does it overflow the buffer of expected size MAX_PATH or does it
|
||||
truncate the path? I don't know. Let's catch both. */
|
||||
cygwin_conv_to_posix_path (location, location_as_posix_path);
|
||||
location_as_posix_path[MAX_PATH - 1] = '\0';
|
||||
if (strlen (location_as_posix_path) >= MAX_PATH - 1)
|
||||
/* A sign of buffer overflow or path truncation. */
|
||||
return FALSE;
|
||||
shared_library_fullname = strdup (location_as_posix_path);
|
||||
/* On Cygwin, we need to convert paths coming from Win32 system calls
|
||||
to the Unix-like slashified notation. */
|
||||
static char location_as_posix_path[2 * MAX_PATH];
|
||||
/* There's no error return defined for cygwin_conv_to_posix_path.
|
||||
See cygwin-api/func-cygwin-conv-to-posix-path.html.
|
||||
Does it overflow the buffer of expected size MAX_PATH or does it
|
||||
truncate the path? I don't know. Let's catch both. */
|
||||
cygwin_conv_to_posix_path (location, location_as_posix_path);
|
||||
location_as_posix_path[MAX_PATH - 1] = '\0';
|
||||
if (strlen (location_as_posix_path) >= MAX_PATH - 1)
|
||||
/* A sign of buffer overflow or path truncation. */
|
||||
return FALSE;
|
||||
shared_library_fullname = strdup (location_as_posix_path);
|
||||
#else
|
||||
shared_library_fullname = strdup (location);
|
||||
shared_library_fullname = strdup (location);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
@ -342,37 +351,37 @@ find_shared_library_fullname ()
|
|||
{
|
||||
unsigned long address = (unsigned long) &find_shared_library_fullname;
|
||||
for (;;)
|
||||
{
|
||||
unsigned long start, end;
|
||||
int c;
|
||||
{
|
||||
unsigned long start, end;
|
||||
int c;
|
||||
|
||||
if (fscanf (fp, "%lx-%lx", &start, &end) != 2)
|
||||
break;
|
||||
if (address >= start && address <= end - 1)
|
||||
{
|
||||
/* Found it. Now see if this line contains a filename. */
|
||||
while (c = getc (fp), c != EOF && c != '\n' && c != '/')
|
||||
continue;
|
||||
if (c == '/')
|
||||
{
|
||||
size_t size;
|
||||
int len;
|
||||
if (fscanf (fp, "%lx-%lx", &start, &end) != 2)
|
||||
break;
|
||||
if (address >= start && address <= end - 1)
|
||||
{
|
||||
/* Found it. Now see if this line contains a filename. */
|
||||
while (c = getc (fp), c != EOF && c != '\n' && c != '/')
|
||||
continue;
|
||||
if (c == '/')
|
||||
{
|
||||
size_t size;
|
||||
int len;
|
||||
|
||||
ungetc (c, fp);
|
||||
shared_library_fullname = NULL; size = 0;
|
||||
len = getline (&shared_library_fullname, &size, fp);
|
||||
if (len >= 0)
|
||||
{
|
||||
/* Success: filled shared_library_fullname. */
|
||||
if (len > 0 && shared_library_fullname[len - 1] == '\n')
|
||||
shared_library_fullname[len - 1] = '\0';
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
while (c = getc (fp), c != EOF && c != '\n')
|
||||
continue;
|
||||
}
|
||||
ungetc (c, fp);
|
||||
shared_library_fullname = NULL; size = 0;
|
||||
len = getline (&shared_library_fullname, &size, fp);
|
||||
if (len >= 0)
|
||||
{
|
||||
/* Success: filled shared_library_fullname. */
|
||||
if (len > 0 && shared_library_fullname[len - 1] == '\n')
|
||||
shared_library_fullname[len - 1] = '\0';
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
while (c = getc (fp), c != EOF && c != '\n')
|
||||
continue;
|
||||
}
|
||||
fclose (fp);
|
||||
}
|
||||
#endif
|
||||
|
@ -400,7 +409,9 @@ get_shared_library_fullname ()
|
|||
#endif /* PIC */
|
||||
|
||||
/* Returns the pathname, relocated according to the current installation
|
||||
directory. */
|
||||
directory.
|
||||
The returned string is either PATHNAME unmodified or a freshly allocated
|
||||
string that you can free with free() after casting it to 'char *'. */
|
||||
const char *
|
||||
relocate (const char *pathname)
|
||||
{
|
||||
|
@ -411,55 +422,69 @@ relocate (const char *pathname)
|
|||
if (!initialized)
|
||||
{
|
||||
/* At this point, orig_prefix and curr_prefix likely have already been
|
||||
set through the main program's set_program_name_and_installdir
|
||||
function. This is sufficient in the case that the library has
|
||||
initially been installed in the same orig_prefix. But we can do
|
||||
better, to also cover the cases that 1. it has been installed
|
||||
in a different prefix before being moved to orig_prefix and (later)
|
||||
to curr_prefix, 2. unlike the program, it has not moved away from
|
||||
orig_prefix. */
|
||||
set through the main program's set_program_name_and_installdir
|
||||
function. This is sufficient in the case that the library has
|
||||
initially been installed in the same orig_prefix. But we can do
|
||||
better, to also cover the cases that 1. it has been installed
|
||||
in a different prefix before being moved to orig_prefix and (later)
|
||||
to curr_prefix, 2. unlike the program, it has not moved away from
|
||||
orig_prefix. */
|
||||
const char *orig_installprefix = INSTALLPREFIX;
|
||||
const char *orig_installdir = INSTALLDIR;
|
||||
const char *curr_prefix_better;
|
||||
char *curr_prefix_better;
|
||||
|
||||
curr_prefix_better =
|
||||
compute_curr_prefix (orig_installprefix, orig_installdir,
|
||||
get_shared_library_fullname ());
|
||||
if (curr_prefix_better == NULL)
|
||||
curr_prefix_better = curr_prefix;
|
||||
compute_curr_prefix (orig_installprefix, orig_installdir,
|
||||
get_shared_library_fullname ());
|
||||
|
||||
set_relocation_prefix (orig_installprefix, curr_prefix_better);
|
||||
set_relocation_prefix (orig_installprefix,
|
||||
curr_prefix_better != NULL
|
||||
? curr_prefix_better
|
||||
: curr_prefix);
|
||||
|
||||
if (curr_prefix_better != NULL)
|
||||
free (curr_prefix_better);
|
||||
|
||||
initialized = 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Note: It is not necessary to perform case insensitive comparison here,
|
||||
even for DOS-like filesystems, because the pathname argument was
|
||||
even for DOS-like file systems, because the pathname argument was
|
||||
typically created from the same Makefile variable as orig_prefix came
|
||||
from. */
|
||||
if (orig_prefix != NULL && curr_prefix != NULL
|
||||
&& strncmp (pathname, orig_prefix, orig_prefix_len) == 0)
|
||||
{
|
||||
if (pathname[orig_prefix_len] == '\0')
|
||||
/* pathname equals orig_prefix. */
|
||||
return curr_prefix;
|
||||
if (ISSLASH (pathname[orig_prefix_len]))
|
||||
{
|
||||
/* pathname starts with orig_prefix. */
|
||||
const char *pathname_tail = &pathname[orig_prefix_len];
|
||||
char *result =
|
||||
(char *) xmalloc (curr_prefix_len + strlen (pathname_tail) + 1);
|
||||
{
|
||||
/* pathname equals orig_prefix. */
|
||||
char *result = (char *) xmalloc (strlen (curr_prefix) + 1);
|
||||
|
||||
#ifdef NO_XMALLOC
|
||||
if (result != NULL)
|
||||
if (result != NULL)
|
||||
#endif
|
||||
{
|
||||
memcpy (result, curr_prefix, curr_prefix_len);
|
||||
strcpy (result + curr_prefix_len, pathname_tail);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
{
|
||||
strcpy (result, curr_prefix);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
else if (ISSLASH (pathname[orig_prefix_len]))
|
||||
{
|
||||
/* pathname starts with orig_prefix. */
|
||||
const char *pathname_tail = &pathname[orig_prefix_len];
|
||||
char *result =
|
||||
(char *) xmalloc (curr_prefix_len + strlen (pathname_tail) + 1);
|
||||
|
||||
#ifdef NO_XMALLOC
|
||||
if (result != NULL)
|
||||
#endif
|
||||
{
|
||||
memcpy (result, curr_prefix, curr_prefix_len);
|
||||
strcpy (result + curr_prefix_len, pathname_tail);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Nothing to relocate. */
|
||||
return pathname;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* Provide relocatable packages.
|
||||
Copyright (C) 2003, 2005 Free Software Foundation, Inc.
|
||||
Copyright (C) 2003, 2005, 2008 Free Software Foundation, Inc.
|
||||
Written by Bruno Haible <bruno@clisp.org>, 2003.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
|
@ -46,23 +46,27 @@ extern "C" {
|
|||
instead of "/"). */
|
||||
extern RELOCATABLE_DLL_EXPORTED void
|
||||
set_relocation_prefix (const char *orig_prefix,
|
||||
const char *curr_prefix);
|
||||
const char *curr_prefix);
|
||||
|
||||
/* Returns the pathname, relocated according to the current installation
|
||||
directory. */
|
||||
directory.
|
||||
The returned string is either PATHNAME unmodified or a freshly allocated
|
||||
string that you can free with free() after casting it to 'char *'. */
|
||||
extern const char * relocate (const char *pathname);
|
||||
|
||||
/* Memory management: relocate() leaks memory, because it has to construct
|
||||
a fresh pathname. If this is a problem because your program calls
|
||||
relocate() frequently, think about caching the result. */
|
||||
/* Memory management: relocate() potentially allocates memory, because it has
|
||||
to construct a fresh pathname. If this is a problem because your program
|
||||
calls relocate() frequently, think about caching the result. Or free the
|
||||
return value if it was different from the argument pathname. */
|
||||
|
||||
/* Convenience function:
|
||||
Computes the current installation prefix, based on the original
|
||||
installation prefix, the original installation directory of a particular
|
||||
file, and the current pathname of this file. Returns NULL upon failure. */
|
||||
extern const char * compute_curr_prefix (const char *orig_installprefix,
|
||||
const char *orig_installdir,
|
||||
const char *curr_pathname);
|
||||
file, and the current pathname of this file.
|
||||
Returns it, freshly allocated. Returns NULL upon failure. */
|
||||
extern char * compute_curr_prefix (const char *orig_installprefix,
|
||||
const char *orig_installdir,
|
||||
const char *curr_pathname);
|
||||
|
||||
#else
|
||||
|
||||
|
|
1015
intl/setlocale.c
Normal file
1015
intl/setlocale.c
Normal file
File diff suppressed because it is too large
Load diff
|
@ -40,22 +40,8 @@
|
|||
# include "lock.h"
|
||||
#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 libintl_nl_default_default_domain
|
||||
# define _nl_current_default_domain libintl_nl_current_default_domain
|
||||
#endif
|
||||
|
||||
/* @@ end of prolog @@ */
|
||||
|
||||
/* Name of the default text domain. */
|
||||
extern const char _nl_default_default_domain[] attribute_hidden;
|
||||
|
||||
/* Default text domain in which entries for gettext(3) are to be found. */
|
||||
extern const char *_nl_current_default_domain attribute_hidden;
|
||||
|
||||
|
||||
/* Names for the libintl functions are a problem. They must not clash
|
||||
with existing names and they should follow ANSI C. But this source
|
||||
|
|
75
intl/threadlib.c
Normal file
75
intl/threadlib.c
Normal file
|
@ -0,0 +1,75 @@
|
|||
/* Multithreading primitives.
|
||||
Copyright (C) 2005-2009 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Library General Public License as published
|
||||
by the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
USA. */
|
||||
|
||||
/* Written by Bruno Haible <bruno@clisp.org>, 2005. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
#if USE_POSIX_THREADS
|
||||
|
||||
/* Use the POSIX threads library. */
|
||||
|
||||
# include <pthread.h>
|
||||
# include <stdlib.h>
|
||||
|
||||
# if PTHREAD_IN_USE_DETECTION_HARD
|
||||
|
||||
/* The function to be executed by a dummy thread. */
|
||||
static void *
|
||||
dummy_thread_func (void *arg)
|
||||
{
|
||||
return arg;
|
||||
}
|
||||
|
||||
int
|
||||
glthread_in_use (void)
|
||||
{
|
||||
static int tested;
|
||||
static int result; /* 1: linked with -lpthread, 0: only with libc */
|
||||
|
||||
if (!tested)
|
||||
{
|
||||
pthread_t thread;
|
||||
|
||||
if (pthread_create (&thread, NULL, dummy_thread_func, NULL) != 0)
|
||||
/* Thread creation failed. */
|
||||
result = 0;
|
||||
else
|
||||
{
|
||||
/* Thread creation works. */
|
||||
void *retval;
|
||||
if (pthread_join (thread, &retval) != 0)
|
||||
abort ();
|
||||
result = 1;
|
||||
}
|
||||
tested = 1;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
# endif
|
||||
|
||||
#endif
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
/* This declaration is solely to ensure that after preprocessing
|
||||
this file is never empty. */
|
||||
typedef int dummy;
|
684
intl/tsearch.c
Normal file
684
intl/tsearch.c
Normal file
|
@ -0,0 +1,684 @@
|
|||
/* Copyright (C) 1995, 1996, 1997, 2000, 2006 Free Software Foundation, Inc.
|
||||
Contributed by Bernd Schmidt <crux@Pool.Informatik.RWTH-Aachen.DE>, 1997.
|
||||
|
||||
NOTE: The canonical source of this file is maintained with the GNU C
|
||||
Library. Bugs can be reported to bug-glibc@gnu.org.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Library General Public License as published
|
||||
by the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
USA. */
|
||||
|
||||
/* Tree search for red/black trees.
|
||||
The algorithm for adding nodes is taken from one of the many "Algorithms"
|
||||
books by Robert Sedgewick, although the implementation differs.
|
||||
The algorithm for deleting nodes can probably be found in a book named
|
||||
"Introduction to Algorithms" by Cormen/Leiserson/Rivest. At least that's
|
||||
the book that my professor took most algorithms from during the "Data
|
||||
Structures" course...
|
||||
|
||||
Totally public domain. */
|
||||
|
||||
/* Red/black trees are binary trees in which the edges are colored either red
|
||||
or black. They have the following properties:
|
||||
1. The number of black edges on every path from the root to a leaf is
|
||||
constant.
|
||||
2. No two red edges are adjacent.
|
||||
Therefore there is an upper bound on the length of every path, it's
|
||||
O(log n) where n is the number of nodes in the tree. No path can be longer
|
||||
than 1+2*P where P is the length of the shortest path in the tree.
|
||||
Useful for the implementation:
|
||||
3. If one of the children of a node is NULL, then the other one is red
|
||||
(if it exists).
|
||||
|
||||
In the implementation, not the edges are colored, but the nodes. The color
|
||||
interpreted as the color of the edge leading to this node. The color is
|
||||
meaningless for the root node, but we color the root node black for
|
||||
convenience. All added nodes are red initially.
|
||||
|
||||
Adding to a red/black tree is rather easy. The right place is searched
|
||||
with a usual binary tree search. Additionally, whenever a node N is
|
||||
reached that has two red successors, the successors are colored black and
|
||||
the node itself colored red. This moves red edges up the tree where they
|
||||
pose less of a problem once we get to really insert the new node. Changing
|
||||
N's color to red may violate rule 2, however, so rotations may become
|
||||
necessary to restore the invariants. Adding a new red leaf may violate
|
||||
the same rule, so afterwards an additional check is run and the tree
|
||||
possibly rotated.
|
||||
|
||||
Deleting is hairy. There are mainly two nodes involved: the node to be
|
||||
deleted (n1), and another node that is to be unchained from the tree (n2).
|
||||
If n1 has a successor (the node with a smallest key that is larger than
|
||||
n1), then the successor becomes n2 and its contents are copied into n1,
|
||||
otherwise n1 becomes n2.
|
||||
Unchaining a node may violate rule 1: if n2 is black, one subtree is
|
||||
missing one black edge afterwards. The algorithm must try to move this
|
||||
error upwards towards the root, so that the subtree that does not have
|
||||
enough black edges becomes the whole tree. Once that happens, the error
|
||||
has disappeared. It may not be necessary to go all the way up, since it
|
||||
is possible that rotations and recoloring can fix the error before that.
|
||||
|
||||
Although the deletion algorithm must walk upwards through the tree, we
|
||||
do not store parent pointers in the nodes. Instead, delete allocates a
|
||||
small array of parent pointers and fills it while descending the tree.
|
||||
Since we know that the length of a path is O(log n), where n is the number
|
||||
of nodes, this is likely to use less memory. */
|
||||
|
||||
/* Tree rotations look like this:
|
||||
A C
|
||||
/ \ / \
|
||||
B C A G
|
||||
/ \ / \ --> / \
|
||||
D E F G B F
|
||||
/ \
|
||||
D E
|
||||
|
||||
In this case, A has been rotated left. This preserves the ordering of the
|
||||
binary tree. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
/* Specification. */
|
||||
#ifdef IN_LIBINTL
|
||||
# include "tsearch.h"
|
||||
#else
|
||||
# include <search.h>
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
typedef int (*__compar_fn_t) (const void *, const void *);
|
||||
typedef void (*__action_fn_t) (const void *, VISIT, int);
|
||||
|
||||
#ifndef weak_alias
|
||||
# define __tsearch tsearch
|
||||
# define __tfind tfind
|
||||
# define __tdelete tdelete
|
||||
# define __twalk twalk
|
||||
#endif
|
||||
|
||||
#ifndef internal_function
|
||||
/* Inside GNU libc we mark some function in a special way. In other
|
||||
environments simply ignore the marking. */
|
||||
# define internal_function
|
||||
#endif
|
||||
|
||||
typedef struct node_t
|
||||
{
|
||||
/* Callers expect this to be the first element in the structure - do not
|
||||
move! */
|
||||
const void *key;
|
||||
struct node_t *left;
|
||||
struct node_t *right;
|
||||
unsigned int red:1;
|
||||
} *node;
|
||||
typedef const struct node_t *const_node;
|
||||
|
||||
#undef DEBUGGING
|
||||
|
||||
#ifdef DEBUGGING
|
||||
|
||||
/* Routines to check tree invariants. */
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#define CHECK_TREE(a) check_tree(a)
|
||||
|
||||
static void
|
||||
check_tree_recurse (node p, int d_sofar, int d_total)
|
||||
{
|
||||
if (p == NULL)
|
||||
{
|
||||
assert (d_sofar == d_total);
|
||||
return;
|
||||
}
|
||||
|
||||
check_tree_recurse (p->left, d_sofar + (p->left && !p->left->red), d_total);
|
||||
check_tree_recurse (p->right, d_sofar + (p->right && !p->right->red), d_total);
|
||||
if (p->left)
|
||||
assert (!(p->left->red && p->red));
|
||||
if (p->right)
|
||||
assert (!(p->right->red && p->red));
|
||||
}
|
||||
|
||||
static void
|
||||
check_tree (node root)
|
||||
{
|
||||
int cnt = 0;
|
||||
node p;
|
||||
if (root == NULL)
|
||||
return;
|
||||
root->red = 0;
|
||||
for(p = root->left; p; p = p->left)
|
||||
cnt += !p->red;
|
||||
check_tree_recurse (root, 0, cnt);
|
||||
}
|
||||
|
||||
|
||||
#else
|
||||
|
||||
#define CHECK_TREE(a)
|
||||
|
||||
#endif
|
||||
|
||||
/* Possibly "split" a node with two red successors, and/or fix up two red
|
||||
edges in a row. ROOTP is a pointer to the lowest node we visited, PARENTP
|
||||
and GPARENTP pointers to its parent/grandparent. P_R and GP_R contain the
|
||||
comparison values that determined which way was taken in the tree to reach
|
||||
ROOTP. MODE is 1 if we need not do the split, but must check for two red
|
||||
edges between GPARENTP and ROOTP. */
|
||||
static void
|
||||
maybe_split_for_insert (node *rootp, node *parentp, node *gparentp,
|
||||
int p_r, int gp_r, int mode)
|
||||
{
|
||||
node root = *rootp;
|
||||
node *rp, *lp;
|
||||
rp = &(*rootp)->right;
|
||||
lp = &(*rootp)->left;
|
||||
|
||||
/* See if we have to split this node (both successors red). */
|
||||
if (mode == 1
|
||||
|| ((*rp) != NULL && (*lp) != NULL && (*rp)->red && (*lp)->red))
|
||||
{
|
||||
/* This node becomes red, its successors black. */
|
||||
root->red = 1;
|
||||
if (*rp)
|
||||
(*rp)->red = 0;
|
||||
if (*lp)
|
||||
(*lp)->red = 0;
|
||||
|
||||
/* If the parent of this node is also red, we have to do
|
||||
rotations. */
|
||||
if (parentp != NULL && (*parentp)->red)
|
||||
{
|
||||
node gp = *gparentp;
|
||||
node p = *parentp;
|
||||
/* There are two main cases:
|
||||
1. The edge types (left or right) of the two red edges differ.
|
||||
2. Both red edges are of the same type.
|
||||
There exist two symmetries of each case, so there is a total of
|
||||
4 cases. */
|
||||
if ((p_r > 0) != (gp_r > 0))
|
||||
{
|
||||
/* Put the child at the top of the tree, with its parent
|
||||
and grandparent as successors. */
|
||||
p->red = 1;
|
||||
gp->red = 1;
|
||||
root->red = 0;
|
||||
if (p_r < 0)
|
||||
{
|
||||
/* Child is left of parent. */
|
||||
p->left = *rp;
|
||||
*rp = p;
|
||||
gp->right = *lp;
|
||||
*lp = gp;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Child is right of parent. */
|
||||
p->right = *lp;
|
||||
*lp = p;
|
||||
gp->left = *rp;
|
||||
*rp = gp;
|
||||
}
|
||||
*gparentp = root;
|
||||
}
|
||||
else
|
||||
{
|
||||
*gparentp = *parentp;
|
||||
/* Parent becomes the top of the tree, grandparent and
|
||||
child are its successors. */
|
||||
p->red = 0;
|
||||
gp->red = 1;
|
||||
if (p_r < 0)
|
||||
{
|
||||
/* Left edges. */
|
||||
gp->left = p->right;
|
||||
p->right = gp;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Right edges. */
|
||||
gp->right = p->left;
|
||||
p->left = gp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Find or insert datum into search tree.
|
||||
KEY is the key to be located, ROOTP is the address of tree root,
|
||||
COMPAR the ordering function. */
|
||||
void *
|
||||
__tsearch (const void *key, void **vrootp, __compar_fn_t compar)
|
||||
{
|
||||
node q;
|
||||
node *parentp = NULL, *gparentp = NULL;
|
||||
node *rootp = (node *) vrootp;
|
||||
node *nextp;
|
||||
int r = 0, p_r = 0, gp_r = 0; /* No they might not, Mr Compiler. */
|
||||
|
||||
if (rootp == NULL)
|
||||
return NULL;
|
||||
|
||||
/* This saves some additional tests below. */
|
||||
if (*rootp != NULL)
|
||||
(*rootp)->red = 0;
|
||||
|
||||
CHECK_TREE (*rootp);
|
||||
|
||||
nextp = rootp;
|
||||
while (*nextp != NULL)
|
||||
{
|
||||
node root = *rootp;
|
||||
r = (*compar) (key, root->key);
|
||||
if (r == 0)
|
||||
return root;
|
||||
|
||||
maybe_split_for_insert (rootp, parentp, gparentp, p_r, gp_r, 0);
|
||||
/* If that did any rotations, parentp and gparentp are now garbage.
|
||||
That doesn't matter, because the values they contain are never
|
||||
used again in that case. */
|
||||
|
||||
nextp = r < 0 ? &root->left : &root->right;
|
||||
if (*nextp == NULL)
|
||||
break;
|
||||
|
||||
gparentp = parentp;
|
||||
parentp = rootp;
|
||||
rootp = nextp;
|
||||
|
||||
gp_r = p_r;
|
||||
p_r = r;
|
||||
}
|
||||
|
||||
q = (struct node_t *) malloc (sizeof (struct node_t));
|
||||
if (q != NULL)
|
||||
{
|
||||
*nextp = q; /* link new node to old */
|
||||
q->key = key; /* initialize new node */
|
||||
q->red = 1;
|
||||
q->left = q->right = NULL;
|
||||
|
||||
if (nextp != rootp)
|
||||
/* There may be two red edges in a row now, which we must avoid by
|
||||
rotating the tree. */
|
||||
maybe_split_for_insert (nextp, rootp, parentp, r, p_r, 1);
|
||||
}
|
||||
|
||||
return q;
|
||||
}
|
||||
#ifdef weak_alias
|
||||
weak_alias (__tsearch, tsearch)
|
||||
#endif
|
||||
|
||||
|
||||
/* Find datum in search tree.
|
||||
KEY is the key to be located, ROOTP is the address of tree root,
|
||||
COMPAR the ordering function. */
|
||||
void *
|
||||
__tfind (key, vrootp, compar)
|
||||
const void *key;
|
||||
void *const *vrootp;
|
||||
__compar_fn_t compar;
|
||||
{
|
||||
node *rootp = (node *) vrootp;
|
||||
|
||||
if (rootp == NULL)
|
||||
return NULL;
|
||||
|
||||
CHECK_TREE (*rootp);
|
||||
|
||||
while (*rootp != NULL)
|
||||
{
|
||||
node root = *rootp;
|
||||
int r;
|
||||
|
||||
r = (*compar) (key, root->key);
|
||||
if (r == 0)
|
||||
return root;
|
||||
|
||||
rootp = r < 0 ? &root->left : &root->right;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
#ifdef weak_alias
|
||||
weak_alias (__tfind, tfind)
|
||||
#endif
|
||||
|
||||
|
||||
/* Delete node with given key.
|
||||
KEY is the key to be deleted, ROOTP is the address of the root of tree,
|
||||
COMPAR the comparison function. */
|
||||
void *
|
||||
__tdelete (const void *key, void **vrootp, __compar_fn_t compar)
|
||||
{
|
||||
node p, q, r, retval;
|
||||
int cmp;
|
||||
node *rootp = (node *) vrootp;
|
||||
node root, unchained;
|
||||
/* Stack of nodes so we remember the parents without recursion. It's
|
||||
_very_ unlikely that there are paths longer than 40 nodes. The tree
|
||||
would need to have around 250.000 nodes. */
|
||||
int stacksize = 100;
|
||||
int sp = 0;
|
||||
node *nodestack[100];
|
||||
|
||||
if (rootp == NULL)
|
||||
return NULL;
|
||||
p = *rootp;
|
||||
if (p == NULL)
|
||||
return NULL;
|
||||
|
||||
CHECK_TREE (p);
|
||||
|
||||
while ((cmp = (*compar) (key, (*rootp)->key)) != 0)
|
||||
{
|
||||
if (sp == stacksize)
|
||||
abort ();
|
||||
|
||||
nodestack[sp++] = rootp;
|
||||
p = *rootp;
|
||||
rootp = ((cmp < 0)
|
||||
? &(*rootp)->left
|
||||
: &(*rootp)->right);
|
||||
if (*rootp == NULL)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* This is bogus if the node to be deleted is the root... this routine
|
||||
really should return an integer with 0 for success, -1 for failure
|
||||
and errno = ESRCH or something. */
|
||||
retval = p;
|
||||
|
||||
/* We don't unchain the node we want to delete. Instead, we overwrite
|
||||
it with its successor and unchain the successor. If there is no
|
||||
successor, we really unchain the node to be deleted. */
|
||||
|
||||
root = *rootp;
|
||||
|
||||
r = root->right;
|
||||
q = root->left;
|
||||
|
||||
if (q == NULL || r == NULL)
|
||||
unchained = root;
|
||||
else
|
||||
{
|
||||
node *parent = rootp, *up = &root->right;
|
||||
for (;;)
|
||||
{
|
||||
if (sp == stacksize)
|
||||
abort ();
|
||||
nodestack[sp++] = parent;
|
||||
parent = up;
|
||||
if ((*up)->left == NULL)
|
||||
break;
|
||||
up = &(*up)->left;
|
||||
}
|
||||
unchained = *up;
|
||||
}
|
||||
|
||||
/* We know that either the left or right successor of UNCHAINED is NULL.
|
||||
R becomes the other one, it is chained into the parent of UNCHAINED. */
|
||||
r = unchained->left;
|
||||
if (r == NULL)
|
||||
r = unchained->right;
|
||||
if (sp == 0)
|
||||
*rootp = r;
|
||||
else
|
||||
{
|
||||
q = *nodestack[sp-1];
|
||||
if (unchained == q->right)
|
||||
q->right = r;
|
||||
else
|
||||
q->left = r;
|
||||
}
|
||||
|
||||
if (unchained != root)
|
||||
root->key = unchained->key;
|
||||
if (!unchained->red)
|
||||
{
|
||||
/* Now we lost a black edge, which means that the number of black
|
||||
edges on every path is no longer constant. We must balance the
|
||||
tree. */
|
||||
/* NODESTACK now contains all parents of R. R is likely to be NULL
|
||||
in the first iteration. */
|
||||
/* NULL nodes are considered black throughout - this is necessary for
|
||||
correctness. */
|
||||
while (sp > 0 && (r == NULL || !r->red))
|
||||
{
|
||||
node *pp = nodestack[sp - 1];
|
||||
p = *pp;
|
||||
/* Two symmetric cases. */
|
||||
if (r == p->left)
|
||||
{
|
||||
/* Q is R's brother, P is R's parent. The subtree with root
|
||||
R has one black edge less than the subtree with root Q. */
|
||||
q = p->right;
|
||||
if (q->red)
|
||||
{
|
||||
/* If Q is red, we know that P is black. We rotate P left
|
||||
so that Q becomes the top node in the tree, with P below
|
||||
it. P is colored red, Q is colored black.
|
||||
This action does not change the black edge count for any
|
||||
leaf in the tree, but we will be able to recognize one
|
||||
of the following situations, which all require that Q
|
||||
is black. */
|
||||
q->red = 0;
|
||||
p->red = 1;
|
||||
/* Left rotate p. */
|
||||
p->right = q->left;
|
||||
q->left = p;
|
||||
*pp = q;
|
||||
/* Make sure pp is right if the case below tries to use
|
||||
it. */
|
||||
nodestack[sp++] = pp = &q->left;
|
||||
q = p->right;
|
||||
}
|
||||
/* We know that Q can't be NULL here. We also know that Q is
|
||||
black. */
|
||||
if ((q->left == NULL || !q->left->red)
|
||||
&& (q->right == NULL || !q->right->red))
|
||||
{
|
||||
/* Q has two black successors. We can simply color Q red.
|
||||
The whole subtree with root P is now missing one black
|
||||
edge. Note that this action can temporarily make the
|
||||
tree invalid (if P is red). But we will exit the loop
|
||||
in that case and set P black, which both makes the tree
|
||||
valid and also makes the black edge count come out
|
||||
right. If P is black, we are at least one step closer
|
||||
to the root and we'll try again the next iteration. */
|
||||
q->red = 1;
|
||||
r = p;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Q is black, one of Q's successors is red. We can
|
||||
repair the tree with one operation and will exit the
|
||||
loop afterwards. */
|
||||
if (q->right == NULL || !q->right->red)
|
||||
{
|
||||
/* The left one is red. We perform the same action as
|
||||
in maybe_split_for_insert where two red edges are
|
||||
adjacent but point in different directions:
|
||||
Q's left successor (let's call it Q2) becomes the
|
||||
top of the subtree we are looking at, its parent (Q)
|
||||
and grandparent (P) become its successors. The former
|
||||
successors of Q2 are placed below P and Q.
|
||||
P becomes black, and Q2 gets the color that P had.
|
||||
This changes the black edge count only for node R and
|
||||
its successors. */
|
||||
node q2 = q->left;
|
||||
q2->red = p->red;
|
||||
p->right = q2->left;
|
||||
q->left = q2->right;
|
||||
q2->right = q;
|
||||
q2->left = p;
|
||||
*pp = q2;
|
||||
p->red = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* It's the right one. Rotate P left. P becomes black,
|
||||
and Q gets the color that P had. Q's right successor
|
||||
also becomes black. This changes the black edge
|
||||
count only for node R and its successors. */
|
||||
q->red = p->red;
|
||||
p->red = 0;
|
||||
|
||||
q->right->red = 0;
|
||||
|
||||
/* left rotate p */
|
||||
p->right = q->left;
|
||||
q->left = p;
|
||||
*pp = q;
|
||||
}
|
||||
|
||||
/* We're done. */
|
||||
sp = 1;
|
||||
r = NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Comments: see above. */
|
||||
q = p->left;
|
||||
if (q->red)
|
||||
{
|
||||
q->red = 0;
|
||||
p->red = 1;
|
||||
p->left = q->right;
|
||||
q->right = p;
|
||||
*pp = q;
|
||||
nodestack[sp++] = pp = &q->right;
|
||||
q = p->left;
|
||||
}
|
||||
if ((q->right == NULL || !q->right->red)
|
||||
&& (q->left == NULL || !q->left->red))
|
||||
{
|
||||
q->red = 1;
|
||||
r = p;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (q->left == NULL || !q->left->red)
|
||||
{
|
||||
node q2 = q->right;
|
||||
q2->red = p->red;
|
||||
p->left = q2->right;
|
||||
q->right = q2->left;
|
||||
q2->left = q;
|
||||
q2->right = p;
|
||||
*pp = q2;
|
||||
p->red = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
q->red = p->red;
|
||||
p->red = 0;
|
||||
q->left->red = 0;
|
||||
p->left = q->right;
|
||||
q->right = p;
|
||||
*pp = q;
|
||||
}
|
||||
sp = 1;
|
||||
r = NULL;
|
||||
}
|
||||
}
|
||||
--sp;
|
||||
}
|
||||
if (r != NULL)
|
||||
r->red = 0;
|
||||
}
|
||||
|
||||
free (unchained);
|
||||
return retval;
|
||||
}
|
||||
#ifdef weak_alias
|
||||
weak_alias (__tdelete, tdelete)
|
||||
#endif
|
||||
|
||||
|
||||
/* Walk the nodes of a tree.
|
||||
ROOT is the root of the tree to be walked, ACTION the function to be
|
||||
called at each node. LEVEL is the level of ROOT in the whole tree. */
|
||||
static void
|
||||
internal_function
|
||||
trecurse (const void *vroot, __action_fn_t action, int level)
|
||||
{
|
||||
const_node root = (const_node) vroot;
|
||||
|
||||
if (root->left == NULL && root->right == NULL)
|
||||
(*action) (root, leaf, level);
|
||||
else
|
||||
{
|
||||
(*action) (root, preorder, level);
|
||||
if (root->left != NULL)
|
||||
trecurse (root->left, action, level + 1);
|
||||
(*action) (root, postorder, level);
|
||||
if (root->right != NULL)
|
||||
trecurse (root->right, action, level + 1);
|
||||
(*action) (root, endorder, level);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Walk the nodes of a tree.
|
||||
ROOT is the root of the tree to be walked, ACTION the function to be
|
||||
called at each node. */
|
||||
void
|
||||
__twalk (const void *vroot, __action_fn_t action)
|
||||
{
|
||||
const_node root = (const_node) vroot;
|
||||
|
||||
CHECK_TREE (root);
|
||||
|
||||
if (root != NULL && action != NULL)
|
||||
trecurse (root, action, 0);
|
||||
}
|
||||
#ifdef weak_alias
|
||||
weak_alias (__twalk, twalk)
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef _LIBC
|
||||
|
||||
/* The standardized functions miss an important functionality: the
|
||||
tree cannot be removed easily. We provide a function to do this. */
|
||||
static void
|
||||
internal_function
|
||||
tdestroy_recurse (node root, __free_fn_t freefct)
|
||||
{
|
||||
if (root->left != NULL)
|
||||
tdestroy_recurse (root->left, freefct);
|
||||
if (root->right != NULL)
|
||||
tdestroy_recurse (root->right, freefct);
|
||||
(*freefct) ((void *) root->key);
|
||||
/* Free the node itself. */
|
||||
free (root);
|
||||
}
|
||||
|
||||
void
|
||||
__tdestroy (void *vroot, __free_fn_t freefct)
|
||||
{
|
||||
node root = (node) vroot;
|
||||
|
||||
CHECK_TREE (root);
|
||||
|
||||
if (root != NULL)
|
||||
tdestroy_recurse (root, freefct);
|
||||
}
|
||||
weak_alias (__tdestroy, tdestroy)
|
||||
|
||||
#endif /* _LIBC */
|
83
intl/tsearch.h
Normal file
83
intl/tsearch.h
Normal file
|
@ -0,0 +1,83 @@
|
|||
/* Binary tree data structure.
|
||||
Copyright (C) 2006 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Library General Public License as published
|
||||
by the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
USA. */
|
||||
|
||||
#ifndef _TSEARCH_H
|
||||
#define _TSEARCH_H
|
||||
|
||||
#if HAVE_TSEARCH
|
||||
|
||||
/* Get tseach(), tfind(), tdelete(), twalk() declarations. */
|
||||
#include <search.h>
|
||||
|
||||
#else
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* See <http://www.opengroup.org/susv3xbd/search.h.html>,
|
||||
<http://www.opengroup.org/susv3xsh/tsearch.html>
|
||||
for details. */
|
||||
|
||||
typedef enum
|
||||
{
|
||||
preorder,
|
||||
postorder,
|
||||
endorder,
|
||||
leaf
|
||||
}
|
||||
VISIT;
|
||||
|
||||
/* Searches an element in the tree *VROOTP that compares equal to KEY.
|
||||
If one is found, it is returned. Otherwise, a new element equal to KEY
|
||||
is inserted in the tree and is returned. */
|
||||
extern void * tsearch (const void *key, void **vrootp,
|
||||
int (*compar) (const void *, const void *));
|
||||
|
||||
/* Searches an element in the tree *VROOTP that compares equal to KEY.
|
||||
If one is found, it is returned. Otherwise, NULL is returned. */
|
||||
extern void * tfind (const void *key, void *const *vrootp,
|
||||
int (*compar) (const void *, const void *));
|
||||
|
||||
/* Searches an element in the tree *VROOTP that compares equal to KEY.
|
||||
If one is found, it is removed from the tree, and its parent node is
|
||||
returned. Otherwise, NULL is returned. */
|
||||
extern void * tdelete (const void *key, void **vrootp,
|
||||
int (*compar) (const void *, const void *));
|
||||
|
||||
/* Perform a depth-first, left-to-right traversal of the tree VROOT.
|
||||
The ACTION function is called:
|
||||
- for non-leaf nodes: 3 times, before the left subtree traversal,
|
||||
after the left subtree traversal but before the right subtree traversal,
|
||||
and after the right subtree traversal,
|
||||
- for leaf nodes: once.
|
||||
The arguments passed to ACTION are:
|
||||
1. the node; it can be casted to a 'const void * const *', i.e. into a
|
||||
pointer to the key,
|
||||
2. an indicator which visit of the node this is,
|
||||
3. the level of the node in the tree (0 for the root). */
|
||||
extern void twalk (const void *vroot,
|
||||
void (*action) (const void *, VISIT, int));
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* _TSEARCH_H */
|
6062
intl/vasnprintf.c
6062
intl/vasnprintf.c
File diff suppressed because it is too large
Load diff
|
@ -38,7 +38,7 @@
|
|||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
@ -71,7 +71,7 @@ extern char * asnprintf (char *resultbuf, size_t *lengthp, const char *format, .
|
|||
extern char * vasnprintf (char *resultbuf, size_t *lengthp, const char *format, va_list args)
|
||||
__attribute__ ((__format__ (__printf__, 3, 0)));
|
||||
|
||||
#ifdef __cplusplus
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
/* Get wchar_t, size_t. */
|
||||
#include <stddef.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
@ -39,7 +39,7 @@ extern "C" {
|
|||
extern wchar_t * asnwprintf (wchar_t *resultbuf, size_t *lengthp, const wchar_t *format, ...);
|
||||
extern wchar_t * vasnwprintf (wchar_t *resultbuf, size_t *lengthp, const wchar_t *format, va_list args);
|
||||
|
||||
#ifdef __cplusplus
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -23,15 +23,15 @@
|
|||
|
||||
|
||||
/* Flags */
|
||||
#define FLAG_GROUP 1 /* ' flag */
|
||||
#define FLAG_LEFT 2 /* - flag */
|
||||
#define FLAG_SHOWSIGN 4 /* + flag */
|
||||
#define FLAG_SPACE 8 /* space flag */
|
||||
#define FLAG_ALT 16 /* # flag */
|
||||
#define FLAG_ZERO 32
|
||||
#define FLAG_GROUP 1 /* ' flag */
|
||||
#define FLAG_LEFT 2 /* - flag */
|
||||
#define FLAG_SHOWSIGN 4 /* + flag */
|
||||
#define FLAG_SPACE 8 /* space flag */
|
||||
#define FLAG_ALT 16 /* # flag */
|
||||
#define FLAG_ZERO 32
|
||||
|
||||
/* arg_index value indicating that no argument is consumed. */
|
||||
#define ARG_NONE (~(size_t)0)
|
||||
#define ARG_NONE (~(size_t)0)
|
||||
|
||||
/* A parsed directive. */
|
||||
typedef struct
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* xsize.h -- Checked size_t computations.
|
||||
|
||||
Copyright (C) 2003 Free Software Foundation, Inc.
|
||||
Copyright (C) 2003, 2008 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Library General Public License as published
|
||||
|
@ -95,7 +95,7 @@ xmax (size_t size1, size_t size2)
|
|||
/* Multiplication of a count with an element size, with overflow check.
|
||||
The count must be >= 0 and the element size must be > 0.
|
||||
This is a macro, not an inline function, so that it works correctly even
|
||||
when N is of a wider tupe and N > SIZE_MAX. */
|
||||
when N is of a wider type and N > SIZE_MAX. */
|
||||
#define xtimes(N, ELSIZE) \
|
||||
((N) <= SIZE_MAX / (ELSIZE) ? (size_t) (N) * (ELSIZE) : SIZE_MAX)
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue