From patchwork Wed Dec 10 15:15:36 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Will Newton X-Patchwork-Id: 42089 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-wi0-f200.google.com (mail-wi0-f200.google.com [209.85.212.200]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id C880626666 for ; Wed, 10 Dec 2014 15:16:25 +0000 (UTC) Received: by mail-wi0-f200.google.com with SMTP id ex7sf2419430wid.11 for ; Wed, 10 Dec 2014 07:16:25 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:delivered-to:mailing-list :precedence:list-id:list-unsubscribe:list-subscribe:list-archive :list-post:list-help:sender:delivered-to:from:to:cc:subject:date :message-id:x-original-sender:x-original-authentication-results; bh=LTOOngh52CaSg6X4PM0SSH/RATZRvvher14ZWScugko=; b=SM4qQbQsvgbIZ1t0z2Q4CLHt1W9OaoFfTehV66jv66QQQCNFqwa2Ta/uBXZhdVb+8h NOShC9AE7HWw2jKrBZMFga63RrO9Yxcdqdc3DUIJje3N4QlEuRSNmsk9ne3m3ywcX0Hd w9QOSzJyW3/PYyiVMmc0CVfPTs0rEgbtG74uElkgpEWL4Pa9DoJtYzCsSmYbub71gHnJ bWva6Q3GwbTR1MQ0NH2AXLoWYZXv0nHBex/b2w0MM5894jvjJK4DlbXl+QWSnjarR7cA tm3y8mbFAimwv/kZIr8gkhFfJM7xdTJsRnu813atNW+dWI3L5V2rkUMzuUafAQPIM27C QPDA== X-Gm-Message-State: ALoCoQkWCWexcJQztGyvRKlTuiIlsXrO2IGihsnPITTpWSLRh23yY+3bJ/Gh6KuIbAEtI+HfjE53 X-Received: by 10.152.42.196 with SMTP id q4mr418930lal.6.1418224585101; Wed, 10 Dec 2014 07:16:25 -0800 (PST) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.152.88.49 with SMTP id bd17ls203840lab.14.gmail; Wed, 10 Dec 2014 07:16:24 -0800 (PST) X-Received: by 10.152.44.167 with SMTP id f7mr4745666lam.30.1418224584871; Wed, 10 Dec 2014 07:16:24 -0800 (PST) Received: from mail-la0-x235.google.com (mail-la0-x235.google.com. [2a00:1450:4010:c03::235]) by mx.google.com with ESMTPS id lc9si2923665lac.54.2014.12.10.07.16.24 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Wed, 10 Dec 2014 07:16:24 -0800 (PST) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 2a00:1450:4010:c03::235 as permitted sender) client-ip=2a00:1450:4010:c03::235; Received: by mail-la0-f53.google.com with SMTP id gm9so2629681lab.12 for ; Wed, 10 Dec 2014 07:16:24 -0800 (PST) X-Received: by 10.152.21.227 with SMTP id y3mr4727966lae.50.1418224584487; Wed, 10 Dec 2014 07:16:24 -0800 (PST) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patch@linaro.org Received: by 10.112.142.69 with SMTP id ru5csp232733lbb; Wed, 10 Dec 2014 07:16:20 -0800 (PST) X-Received: by 10.68.106.68 with SMTP id gs4mr8127464pbb.23.1418224579918; Wed, 10 Dec 2014 07:16:19 -0800 (PST) Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id f2si5558236pdp.85.2014.12.10.07.16.18 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 10 Dec 2014 07:16:19 -0800 (PST) Received-SPF: pass (google.com: domain of libc-alpha-return-55221-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) client-ip=209.132.180.131; Received: (qmail 31719 invoked by alias); 10 Dec 2014 15:16:01 -0000 Mailing-List: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org Precedence: list List-Id: List-Unsubscribe: , List-Subscribe: List-Archive: List-Post: , List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 31709 invoked by uid 89); 10 Dec 2014 15:16:00 -0000 X-Virus-Found: No X-Spam-SWARE-Status: No, score=2.3 required=5.0 tests=AWL, BAYES_50, KAM_STOCKTIP, RCVD_IN_DNSWL_LOW, SPF_PASS, T_FILL_THIS_FORM_SHORT autolearn=no version=3.3.2 X-HELO: mail-wg0-f49.google.com X-Received: by 10.180.103.38 with SMTP id ft6mr14223488wib.19.1418224543587; Wed, 10 Dec 2014 07:15:43 -0800 (PST) From: Will Newton To: libc-alpha@sourceware.org Cc: bug-gettext@gnu.org Subject: [PATCH] intl: Merge with gettext version 0.19.3 Date: Wed, 10 Dec 2014 15:15:36 +0000 Message-Id: <1418224536-12899-1-git-send-email-will.newton@linaro.org> X-Original-Sender: will.newton@linaro.org X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 2a00:1450:4010:c03::235 as permitted sender) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org; dkim=pass header.i=@sourceware.org X-Google-Group-Id: 836684582541 This patch merges the latest release of gettext into the intl subdirectory. The initial motivation was to include the plural.y changes which enable building with bison 3.0, but the majority of the other changes are merely cosmetic so it seemed like merging the whole directory was simpler than trying to take it piecemeal. The merge was done by copying across the latext gettext code and adding in a few small glibc changes that have been added over the years that seemed beneficial, as well as a couple of small build fixes that should be merged back to gettext. I also reverted the gettext commit: commit 279b57fc367251666f00e8e2b599b83703451afb Author: Bruno Haible Date: Fri Jun 14 12:03:49 2002 +0000 Make absolute pathnames inside $LANGUAGE work. As it caused localedata/tst-setlocale3 to fail and it wasn't clear that glibc wanted that behaviour. The merge has dropped many uses of __glibc_likely/unlikely. This is intentional given that it eases merging. It seems to me that the cost of continually rewriting these lines when merging and the risk of adding bugs when doing so outweighs the benefits of using these macros when code is shared with another project. Tested with make check on x86_64. ChangeLog: 2014-12-10 Will Newton Merge gettext 0.19.3 into intl/. This involves a number of cosmetic changes to comments and ANSI function definitions and prototypes throughout all the files. The gettext copyright header is used but with the date ranges taken from the glibc copy. * intl/bindtextdom.c: Switch to gettext copyright. Use ANSI definitions and prototypes. Use gl_* locking primitives rather than __libc_* ones. Use __builtin_expect rather than __glibc_likely/unlikely. * intl/dcgettext.c: Switch to gettext copyright. Use ANSI definitions and prototypes. * intl/dcigettext.c: Switch to gettext copyright. Use ANSI definitions and prototypes. (INTDIV0_RAISES_SIGFPE): New define. Use gl_* locking primitives rather than __libc_* ones. Include eval-plural.h instead of plural-eval.c. Use __builtin_expect rather than __glibc_likely/unlikely. * intl/dcngettext.c: Switch to gettext copyright. Use ANSI definitions and prototypes. * intl/dgettext.c: Likewise. * intl/dngettext.c: Likewise. * intl/plural-eval.c: Renamed to... * intl/eval-plural.h: ...this. * intl/explodename.c: Switch to gettext copyright. Use ANSI definitions and prototypes. (_nl_explode_name): Use strchr instead of __rawmemchr. * intl/finddomain.c: Switch to gettext copyright. Use ANSI definitions and prototypes. Use gl_* locking primitives rather than __libc_* ones. (_nl_find_domain): Use malloc rather than alloca for allocation of temporary locale name. * intl/gettext.c: Switch to gettext copyright. Use ANSI definitions and prototypes. * intl/gettextP.h: Switch to gettext copyright. Use ANSI definitions and prototypes. Use gl_* locking primitives rather than __libc_* ones. * intl/gmo.h: Switch to gettext copyright. (struct sysdep_string): Move struct segment_pair outside of struct definition. * intl/hash-string.c: Use ANSI definitions and prototypes. * intl/hash-string.h: Switch to gettext copyright. Use ANSI definitions and prototypes. * intl/l10nflist.c: Switch to gettext copyright. Use ANSI definitions and prototypes. (_nl_normalize_codeset): Avoid integer overflow. * intl/loadinfo.h: Switch to gettext copyright. Use ANSI definitions and prototypes. (LIBINTL_DLL_EXPORTED): New define. (PATH_SEPARATOR): New define. * intl/loadmsgcat.c: Switch to gettext copyright. * intl/localealias.c: Switch to gettext copyright. Use ANSI definitions and prototypes. (_nl_expand_alias): Use PATH_SEPARATOR. * intl/ngettext.c: Switch to gettext copyright. Use ANSI definitions and prototypes. * intl/plural-exp.c: Likewise. * intl/plural-exp.h: Switch to gettext copyright. Use ANSI definitions and prototypes. (struct expression): Move definition of enum operator outside of struct definition. * intl/plural.c: Regenerate. * intl/plural.y: Switch to gettext copyright. Use ANSI definitions and prototypes. Port to bison 3.0. * intl/textdomain.c: Switch to gettext copyright. Use ANSI definitions and prototypes. Use gl_* locking primitives rather than __libc_* ones. --- intl/bindtextdom.c | 92 ++---- intl/dcgettext.c | 25 +- intl/dcigettext.c | 851 +++++++++++++++++++++++++++++++++-------------------- intl/dcngettext.c | 29 +- intl/dgettext.c | 27 +- intl/dngettext.c | 30 +- intl/eval-plural.h | 106 +++++++ intl/explodename.c | 44 ++- intl/finddomain.c | 75 +++-- intl/gettext.c | 23 +- intl/gettextP.h | 235 +++++++++------ intl/gmo.h | 39 +-- intl/hash-string.c | 8 +- intl/hash-string.h | 41 ++- intl/l10nflist.c | 108 +++---- intl/loadinfo.h | 116 +++++--- intl/loadmsgcat.c | 20 +- intl/localealias.c | 186 +++++++----- intl/ngettext.c | 25 +- intl/plural-eval.c | 100 ------- intl/plural-exp.c | 30 +- intl/plural-exp.h | 104 +++---- intl/plural.c | 200 ++++++------- intl/plural.y | 98 +++--- intl/textdomain.c | 55 ++-- 25 files changed, 1452 insertions(+), 1215 deletions(-) create mode 100644 intl/eval-plural.h delete mode 100644 intl/plural-eval.c diff --git a/intl/bindtextdom.c b/intl/bindtextdom.c index c362496..29a1b12 100644 --- a/intl/bindtextdom.c +++ b/intl/bindtextdom.c @@ -1,20 +1,18 @@ /* Implementation of the bindtextdomain(3) function Copyright (C) 1995-2014 Free Software Foundation, Inc. - This file is part of the GNU C Library. - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. - The GNU C Library is distributed in the hope that it will be useful, + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ #ifdef HAVE_CONFIG_H # include @@ -24,29 +22,21 @@ #include #include +#include "gettextP.h" #ifdef _LIBC # include #else # include "libgnuintl.h" #endif -#include "gettextP.h" +/* Handle multi-threaded applications. */ #ifdef _LIBC -/* We have to handle multi-threaded applications. */ # include +# define gl_rwlock_define __libc_rwlock_define +# define gl_rwlock_wrlock __libc_rwlock_wrlock +# define gl_rwlock_unlock __libc_rwlock_unlock #else -/* Provide dummy implementation if this is outside glibc. */ -# define __libc_rwlock_define(CLASS, NAME) -# define __libc_rwlock_wrlock(NAME) -# define __libc_rwlock_unlock(NAME) -#endif - -/* The internal variables in the standalone libintl.a must have different - names than the internal variables in GNU libc, otherwise programs - using libintl.a cannot be linked statically. */ -#if !defined _LIBC -# define _nl_default_dirname libintl_nl_default_dirname -# define _nl_domain_bindings libintl_nl_domain_bindings +# include "lock.h" #endif /* Some compilers, like SunOS4 cc, don't have offsetof in . */ @@ -56,17 +46,8 @@ /* @@ 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. */ -__libc_rwlock_define (extern, _nl_state_lock attribute_hidden) +gl_rwlock_define (extern, _nl_state_lock attribute_hidden) /* Names for the libintl functions are a problem. They must not clash @@ -84,11 +65,6 @@ __libc_rwlock_define (extern, _nl_state_lock attribute_hidden) # define BIND_TEXTDOMAIN_CODESET libintl_bind_textdomain_codeset #endif -/* Prototypes for local functions. */ -static void set_binding_values PARAMS ((const char *domainname, - const char **dirnamep, - const char **codesetp)); - /* Specifies the directory name *DIRNAMEP and the output codeset *CODESETP to be used for the DOMAINNAME message catalog. If *DIRNAMEP or *CODESETP is NULL, the corresponding attribute is not @@ -96,10 +72,8 @@ static void set_binding_values PARAMS ((const char *domainname, If DIRNAMEP or CODESETP is NULL, the corresponding attribute is neither modified nor returned. */ static void -set_binding_values (domainname, dirnamep, codesetp) - const char *domainname; - const char **dirnamep; - const char **codesetp; +set_binding_values (const char *domainname, + const char **dirnamep, const char **codesetp) { struct binding *binding; int modified; @@ -114,7 +88,7 @@ set_binding_values (domainname, dirnamep, codesetp) return; } - __libc_rwlock_wrlock (_nl_state_lock); + gl_rwlock_wrlock (_nl_state_lock); modified = 0; @@ -158,12 +132,12 @@ set_binding_values (domainname, dirnamep, codesetp) #else size_t len = strlen (dirname) + 1; result = (char *) malloc (len); - if (__glibc_likely (result != NULL)) + if (__builtin_expect (result != NULL, 1)) memcpy (result, dirname, len); #endif } - if (__glibc_likely (result != NULL)) + if (__builtin_expect (result != NULL, 1)) { if (binding->dirname != _nl_default_dirname) free (binding->dirname); @@ -196,11 +170,11 @@ set_binding_values (domainname, dirnamep, codesetp) #else size_t len = strlen (codeset) + 1; result = (char *) malloc (len); - if (__glibc_likely (result != NULL)) + if (__builtin_expect (result != NULL, 1)) memcpy (result, codeset, len); #endif - if (__glibc_likely (result != NULL)) + if (__builtin_expect (result != NULL, 1)) { free (binding->codeset); @@ -228,7 +202,7 @@ set_binding_values (domainname, dirnamep, codesetp) struct binding *new_binding = (struct binding *) malloc (offsetof (struct binding, domainname) + len); - if (__glibc_unlikely (new_binding == NULL)) + if (__builtin_expect (new_binding == NULL, 0)) goto failed; memcpy (new_binding->domainname, domainname, len); @@ -249,12 +223,12 @@ set_binding_values (domainname, dirnamep, codesetp) char *result; #if defined _LIBC || defined HAVE_STRDUP result = strdup (dirname); - if (__glibc_unlikely (result == NULL)) + if (__builtin_expect (result == NULL, 0)) goto failed_dirname; #else size_t len = strlen (dirname) + 1; result = (char *) malloc (len); - if (__glibc_unlikely (result == NULL)) + if (__builtin_expect (result == NULL, 0)) goto failed_dirname; memcpy (result, dirname, len); #endif @@ -278,12 +252,12 @@ set_binding_values (domainname, dirnamep, codesetp) #if defined _LIBC || defined HAVE_STRDUP result = strdup (codeset); - if (__glibc_unlikely (result == NULL)) + if (__builtin_expect (result == NULL, 0)) goto failed_codeset; #else size_t len = strlen (codeset) + 1; result = (char *) malloc (len); - if (__glibc_unlikely (result == NULL)) + if (__builtin_expect (result == NULL, 0)) goto failed_codeset; memcpy (result, codeset, len); #endif @@ -335,15 +309,13 @@ set_binding_values (domainname, dirnamep, codesetp) if (modified) ++_nl_msg_cat_cntr; - __libc_rwlock_unlock (_nl_state_lock); + gl_rwlock_unlock (_nl_state_lock); } /* Specify that the DOMAINNAME message catalog will be found in DIRNAME rather than in the system locale data base. */ char * -BINDTEXTDOMAIN (domainname, dirname) - const char *domainname; - const char *dirname; +BINDTEXTDOMAIN (const char *domainname, const char *dirname) { set_binding_values (domainname, &dirname, NULL); return (char *) dirname; @@ -352,9 +324,7 @@ BINDTEXTDOMAIN (domainname, dirname) /* Specify the character encoding in which the messages from the DOMAINNAME message catalog will be returned. */ char * -BIND_TEXTDOMAIN_CODESET (domainname, codeset) - const char *domainname; - const char *codeset; +BIND_TEXTDOMAIN_CODESET (const char *domainname, const char *codeset) { set_binding_values (domainname, NULL, &codeset); return (char *) codeset; diff --git a/intl/dcgettext.c b/intl/dcgettext.c index 4daae55..95dccad 100644 --- a/intl/dcgettext.c +++ b/intl/dcgettext.c @@ -1,20 +1,18 @@ /* Implementation of the dcgettext(3) function. Copyright (C) 1995-2014 Free Software Foundation, Inc. - This file is part of the GNU C Library. - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. - The GNU C Library is distributed in the hope that it will be useful, + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ #ifdef HAVE_CONFIG_H # include @@ -44,10 +42,7 @@ /* Look up MSGID in the DOMAINNAME message catalog for the current CATEGORY locale. */ char * -DCGETTEXT (domainname, msgid, category) - const char *domainname; - const char *msgid; - int category; +DCGETTEXT (const char *domainname, const char *msgid, int category) { return DCIGETTEXT (domainname, msgid, NULL, 0, 0, category); } diff --git a/intl/dcigettext.c b/intl/dcigettext.c index 723dd7e..7af4a76 100644 --- a/intl/dcigettext.c +++ b/intl/dcigettext.c @@ -1,20 +1,18 @@ /* Implementation of the internal dcigettext function. Copyright (C) 1995-2014 Free Software Foundation, Inc. - This file is part of the GNU C Library. - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. - The GNU C Library is distributed in the hope that it will be useful, + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ /* Tell glibc's to provide a prototype for mempcpy(). This must come before because may include @@ -33,14 +31,19 @@ # define alloca __builtin_alloca # define HAVE_ALLOCA 1 #else -# if defined HAVE_ALLOCA_H || defined _LIBC -# include +# ifdef _MSC_VER +# include +# define alloca _alloca # else -# ifdef _AIX - #pragma alloca +# if defined HAVE_ALLOCA_H || defined _LIBC +# include # else -# ifndef alloca +# ifdef _AIX + #pragma alloca +# else +# ifndef alloca char *alloca (); +# endif # endif # endif # endif @@ -64,30 +67,49 @@ extern int errno; #include +#ifdef _LIBC + /* Guess whether integer division by zero raises signal SIGFPE. + Set to 1 only if you know for sure. In case of doubt, set to 0. */ +# if defined __alpha__ || defined __arm__ || defined __i386__ \ + || defined __m68k__ || defined __s390__ +# define INTDIV0_RAISES_SIGFPE 1 +# else +# define INTDIV0_RAISES_SIGFPE 0 +# endif +#endif +#if !INTDIV0_RAISES_SIGFPE +# include +#endif + #if defined HAVE_SYS_PARAM_H || defined _LIBC # include #endif +#if !defined _LIBC +# include "localcharset.h" +#endif + #include "gettextP.h" #include "plural-exp.h" #ifdef _LIBC # include #else +# ifdef IN_LIBGLOCALE +# include +# endif # include "libgnuintl.h" #endif #include "hash-string.h" -/* Thread safetyness. */ +/* Handle multi-threaded applications. */ #ifdef _LIBC # include +# define gl_rwlock_define_initialized __libc_rwlock_define_initialized +# define gl_rwlock_rdlock __libc_rwlock_rdlock +# define gl_rwlock_wrlock __libc_rwlock_wrlock +# define gl_rwlock_unlock __libc_rwlock_unlock #else -/* Provide dummy implementation if this is outside glibc. */ -# define __libc_lock_define_initialized(CLASS, NAME) -# define __libc_lock_lock(NAME) -# define __libc_lock_unlock(NAME) -# define __libc_rwlock_define_initialized(CLASS, NAME) -# define __libc_rwlock_rdlock(NAME) -# define __libc_rwlock_unlock(NAME) +# include "lock.h" #endif /* Alignment of types. */ @@ -98,16 +120,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 . */ #ifndef offsetof # define offsetof(type,ident) ((size_t)&(((type*)0)->ident)) @@ -129,16 +141,36 @@ extern int errno; char *getwd (); # define getcwd(buf, max) getwd (buf) # else +# if VMS +# define getcwd(buf, max) (getcwd) (buf, max, 0) +# else char *getcwd (); +# endif # endif # ifndef HAVE_STPCPY -static char *stpcpy PARAMS ((char *dest, const char *src)); +static char *stpcpy (char *dest, const char *src); # endif # ifndef HAVE_MEMPCPY -static void *mempcpy PARAMS ((void *dest, const void *src, size_t n)); +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 defined HAVE_TSEARCH || defined _LIBC +# include +#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 @@ -171,8 +203,30 @@ static void *mempcpy PARAMS ((void *dest, const void *src, size_t n)); # define PATH_MAX _POSIX_PATH_MAX #endif +/* Pathname support. + ISSLASH(C) tests whether C is a directory separator character. + IS_ABSOLUTE_PATH(P) tests whether P is an absolute path. If it is not, + it may be concatenated to a directory pathname. + IS_PATH_WITH_DIR(P) tests whether P contains a directory specification. + */ +#if defined _WIN32 || defined __WIN32__ || defined __CYGWIN__ || defined __EMX__ || defined __DJGPP__ + /* Win32, Cygwin, OS/2, DOS */ +# define ISSLASH(C) ((C) == '/' || (C) == '\\') +# define HAS_DEVICE(P) \ + ((((P)[0] >= 'A' && (P)[0] <= 'Z') || ((P)[0] >= 'a' && (P)[0] <= 'z')) \ + && (P)[1] == ':') +# define IS_ABSOLUTE_PATH(P) (ISSLASH ((P)[0]) || HAS_DEVICE (P)) +# define IS_PATH_WITH_DIR(P) \ + (strchr (P, '/') != NULL || strchr (P, '\\') != NULL || HAS_DEVICE (P)) +#else + /* Unix */ +# define ISSLASH(C) ((C) == '/') +# define IS_ABSOLUTE_PATH(P) ISSLASH ((P)[0]) +# define IS_PATH_WITH_DIR(P) (strchr (P, '/') != NULL) +#endif + /* Whether to support different locales in different threads. */ -#if defined _LIBC || HAVE_NL_LOCALE_NAME +#if defined _LIBC || HAVE_USELOCALE || defined IN_LIBGLOCALE # define HAVE_PER_THREAD_LOCALE #endif @@ -191,6 +245,11 @@ struct known_translation_t const char *localename; #endif +#ifdef IN_LIBGLOCALE + /* The character encoding. */ + const char *encoding; +#endif + /* State of the catalog counter at the point the string was found. */ int counter; @@ -210,23 +269,14 @@ struct known_translation_t 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 +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 PARAMS ((const void *p1, const void *p2)); static int -transcmp (p1, p2) - const void *p1; - const void *p2; +transcmp (const void *p1, const void *p2) { const struct known_translation_t *s1; const struct known_translation_t *s2; @@ -246,59 +296,83 @@ transcmp (p1, p2) result = strcmp (s1->localename, s2->localename); if (result == 0) #endif - /* We compare the category last (though this is the cheapest - operation) since it is hopefully always the same (namely - LC_MESSAGES). */ - result = s1->category - s2->category; + { +#ifdef IN_LIBGLOCALE + result = strcmp (s1->encoding, s2->encoding); + if (result == 0) +#endif + /* We compare the category last (though this is the cheapest + operation) since it is hopefully always the same (namely + LC_MESSAGES). */ + result = s1->category - s2->category; + } } } 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". */ const char _nl_default_default_domain[] attribute_hidden = "messages"; +#ifndef IN_LIBGLOCALE /* Value used as the default domain for gettext(3). */ const char *_nl_current_default_domain attribute_hidden = _nl_default_default_domain; +#endif /* Contains the default location of the message catalogs. */ - -#ifdef _LIBC +#if defined __EMX__ +extern const char _nl_default_dirname[]; +#else +# ifdef _LIBC extern const char _nl_default_dirname[]; libc_hidden_proto (_nl_default_dirname) -#endif +# endif const char _nl_default_dirname[] = LOCALEDIR; -#ifdef _LIBC +# ifdef _LIBC libc_hidden_data_def (_nl_default_dirname) +# endif #endif +#ifndef IN_LIBGLOCALE /* List with bindings of specific domains created by bindtextdomain() calls. */ struct binding *_nl_domain_bindings; +#endif /* Prototypes for local functions. */ -static char *plural_lookup PARAMS ((struct loaded_l10nfile *domain, - unsigned long int n, - const char *translation, - size_t translation_len)) +static char *plural_lookup (struct loaded_l10nfile *domain, + unsigned long int n, + const char *translation, size_t translation_len) + internal_function; + +#ifdef IN_LIBGLOCALE +static const char *guess_category_value (int category, + const char *categoryname, + const char *localename) internal_function; -static const char *guess_category_value PARAMS ((int category, - const char *categoryname)) +#else +static const char *guess_category_value (int category, + const char *categoryname) internal_function; +#endif + #ifdef _LIBC # include "../locale/localeinfo.h" # define category_to_name(category) \ _nl_category_names.str + _nl_category_name_idxs[category] #else -static const char *category_to_name PARAMS ((int category)) internal_function; +static const char *category_to_name (int category) internal_function; +#endif +#if (defined _LIBC || HAVE_ICONV) && !defined IN_LIBGLOCALE +static const char *get_output_charset (struct binding *domainbinding) + internal_function; #endif -/* For those loosing systems which don't have `alloca' we have to add +/* For those losing systems which don't have `alloca' we have to add some additional code emulating it. */ #ifdef HAVE_ALLOCA /* Nothing has to be done. */ @@ -348,10 +422,6 @@ static struct transmem_list *transmem_list; #else typedef unsigned char transmem_block_t; #endif -#if defined _LIBC || HAVE_ICONV -static const char *get_output_charset PARAMS ((struct binding *domainbinding)) - internal_function; -#endif /* Names for the libintl functions are a problem. They must not clash @@ -365,9 +435,7 @@ static const char *get_output_charset PARAMS ((struct binding *domainbinding)) #endif /* Lock variable to protect the global data in the gettext implementation. */ -#ifdef _LIBC -__libc_rwlock_define_initialized (, _nl_state_lock attribute_hidden) -#endif +gl_rwlock_define_initialized (, _nl_state_lock attribute_hidden) /* Checking whether the binaries runs SUID must be done and glibc provides easier methods therefore we make a difference here. */ @@ -400,19 +468,23 @@ static int enable_secure; #endif /* Get the function to evaluate the plural expression. */ -#include "plural-eval.c" +#include "eval-plural.h" /* Look up MSGID in the DOMAINNAME message catalog for the current CATEGORY locale and, if PLURAL is nonzero, search over string depending on the plural form determined by N. */ +#ifdef IN_LIBGLOCALE char * -DCIGETTEXT (domainname, msgid1, msgid2, plural, n, category) - const char *domainname; - const char *msgid1; - const char *msgid2; - int plural; - unsigned long int n; - int category; +gl_dcigettext (const char *domainname, + const char *msgid1, const char *msgid2, + int plural, unsigned long int n, + int category, + const char *localename, const char *encoding) +#else +char * +DCIGETTEXT (const char *domainname, const char *msgid1, const char *msgid2, + int plural, unsigned long int n, int category) +#endif { #ifndef HAVE_ALLOCA struct block_list *block_list = NULL; @@ -421,17 +493,16 @@ DCIGETTEXT (domainname, msgid1, msgid2, plural, n, category) struct binding *binding; const char *categoryname; const char *categoryvalue; - char *dirname, *xdomainname; + const char *dirname; + char *xdomainname; char *single_locale; char *retval; size_t retlen; int saved_errno; -#if defined HAVE_TSEARCH || defined _LIBC struct known_translation_t search; struct known_translation_t **foundp = NULL; -# ifdef HAVE_PER_THREAD_LOCALE +#if defined HAVE_PER_THREAD_LOCALE && !defined IN_LIBGLOCALE const char *localename; -# endif #endif size_t domainname_len; @@ -448,12 +519,15 @@ DCIGETTEXT (domainname, msgid1, msgid2, plural, n, category) : 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 - __libc_rwlock_rdlock (_nl_state_lock); + gl_rwlock_rdlock (_nl_state_lock); /* If DOMAINNAME is NULL, we are interested in the default domain. If CATEGORY is not LC_MESSAGES this might not make much sense but the @@ -461,28 +535,42 @@ DCIGETTEXT (domainname, msgid1, msgid2, plural, n, category) if (domainname == NULL) domainname = _nl_current_default_domain; -#if defined HAVE_TSEARCH || defined _LIBC + /* OS/2 specific: backward compatibility with older libintl versions */ +#ifdef LC_MESSAGES_COMPAT + if (category == LC_MESSAGES_COMPAT) + category = LC_MESSAGES; +#endif + /* Try to find the translation among those which we found at some time. */ search.domain = NULL; search.msgid.ptr = msgid1; search.domainname = domainname; search.category = category; -# ifdef HAVE_PER_THREAD_LOCALE +#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. */ - __libc_rwlock_define_initialized (static, tree_lock); - __libc_rwlock_rdlock (tree_lock); + gl_rwlock_rdlock (tree_lock); foundp = (struct known_translation_t **) tfind (&search, &root, transcmp); - __libc_rwlock_unlock (tree_lock); + gl_rwlock_unlock (tree_lock); if (foundp != NULL && (*foundp)->counter == _nl_msg_cat_cntr) { @@ -493,21 +581,25 @@ DCIGETTEXT (domainname, msgid1, msgid2, plural, n, category) else retval = (char *) (*foundp)->translation; + gl_rwlock_unlock (_nl_state_lock); # ifdef _LIBC __libc_rwlock_unlock (__libc_setlocale_lock); # endif - __libc_rwlock_unlock (_nl_state_lock); + __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; /* First find matching binding. */ +#ifdef IN_LIBGLOCALE + /* We can use a trivial binding, since _nl_find_msg will ignore it anyway, + and _nl_load_domain and _nl_find_domain just pass it through. */ + binding = NULL; + dirname = bindtextdomain (domainname, NULL); +#else for (binding = _nl_domain_bindings; binding != NULL; binding = binding->next) { int compare = strcmp (domainname, binding->domainname); @@ -523,50 +615,65 @@ DCIGETTEXT (domainname, msgid1, msgid2, plural, n, category) } if (binding == NULL) - dirname = (char *) _nl_default_dirname; - else if (binding->dirname[0] == '/') - dirname = binding->dirname; + dirname = _nl_default_dirname; else { - /* We have a relative path. Make it absolute now. */ - size_t dirname_len = strlen (binding->dirname) + 1; - size_t path_max; - char *ret; + dirname = binding->dirname; +#endif + if (!IS_ABSOLUTE_PATH (dirname)) + { + /* We have a relative path. Make it absolute now. */ + size_t dirname_len = strlen (dirname) + 1; + size_t path_max; + char *resolved_dirname; + char *ret; - path_max = (unsigned int) PATH_MAX; - path_max += 2; /* The getcwd docs say to do this. */ + path_max = (unsigned int) PATH_MAX; + path_max += 2; /* The getcwd docs say to do this. */ - for (;;) - { - dirname = (char *) alloca (path_max + dirname_len); - ADD_BLOCK (block_list, dirname); + for (;;) + { + resolved_dirname = (char *) alloca (path_max + dirname_len); + ADD_BLOCK (block_list, tmp_dirname); - __set_errno (0); - ret = getcwd (dirname, path_max); - if (ret != NULL || errno != ERANGE) - break; + __set_errno (0); + ret = getcwd (resolved_dirname, path_max); + if (ret != NULL || errno != ERANGE) + break; - path_max += path_max / 2; - path_max += PATH_INCR; - } + path_max += path_max / 2; + path_max += PATH_INCR; + } - if (ret == NULL) - goto no_translation; + if (ret == NULL) + /* We cannot get the current working directory. Don't signal an + error but simply return the default string. */ + goto return_untranslated; - stpcpy (stpcpy (strchr (dirname, '\0'), "/"), binding->dirname); + stpcpy (stpcpy (strchr (resolved_dirname, '\0'), "/"), dirname); + dirname = resolved_dirname; + } +#ifndef IN_LIBGLOCALE } +#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 categoryvalue = guess_category_value (category, categoryname); +#endif domainname_len = strlen (domainname); xdomainname = (char *) alloca (strlen (categoryname) + 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. */ @@ -599,7 +706,7 @@ DCIGETTEXT (domainname, msgid1, msgid2, plural, n, category) /* When this is a SUID binary we must not allow accessing files outside the dedicated directories. */ - if (ENABLE_SECURE && strchr (single_locale, '/') != NULL) + if (ENABLE_SECURE && IS_PATH_WITH_DIR (single_locale)) /* Ingore this entry. */ continue; } @@ -608,18 +715,7 @@ DCIGETTEXT (domainname, msgid1, msgid2, plural, n, category) domain. Return the MSGID. */ if (strcmp (single_locale, "C") == 0 || strcmp (single_locale, "POSIX") == 0) - { - no_translation: - FREE_BLOCKS (block_list); - __libc_rwlock_unlock (__libc_setlocale_lock); - __libc_rwlock_unlock (_nl_state_lock); - __set_errno (saved_errno); - return (plural == 0 - ? (char *) msgid1 - /* Use the Germanic plural rule. */ - : n == 1 ? (char *) msgid1 : (char *) msgid2); - } - + break; /* Find structure describing the message catalog matching the DOMAINNAME and CATEGORY. */ @@ -627,7 +723,11 @@ DCIGETTEXT (domainname, msgid1, msgid2, plural, n, category) if (domain != NULL) { +#if defined IN_LIBGLOCALE + retval = _nl_find_msg (domain, binding, encoding, msgid1, &retlen); +#else retval = _nl_find_msg (domain, binding, msgid1, 1, &retlen); +#endif if (retval == NULL) { @@ -635,13 +735,18 @@ DCIGETTEXT (domainname, msgid1, msgid2, plural, n, category) for (cnt = 0; domain->successor[cnt] != NULL; ++cnt) { +#if defined IN_LIBGLOCALE + retval = _nl_find_msg (domain->successor[cnt], binding, + encoding, msgid1, &retlen); +#else retval = _nl_find_msg (domain->successor[cnt], binding, msgid1, 1, &retlen); +#endif /* Resource problems are not fatal, instead we return no translation. */ - if (__glibc_unlikely (retval == (char *) -1)) - goto no_translation; + if (__builtin_expect (retval == (char *) -1, 0)) + goto return_untranslated; if (retval != NULL) { @@ -654,15 +759,14 @@ DCIGETTEXT (domainname, msgid1, msgid2, plural, n, category) /* Returning -1 means that some resource problem exists (likely memory) and that the strings could not be converted. Return the original strings. */ - if (__glibc_unlikely (retval == (char *) -1)) - goto no_translation; + if (__builtin_expect (retval == (char *) -1, 0)) + break; if (retval != NULL) { /* 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. */ @@ -673,41 +777,45 @@ DCIGETTEXT (domainname, msgid1, msgid2, plural, n, category) 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.appended, msgid1, msgid_len); + (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 +#endif +#ifdef IN_LIBGLOCALE + newp->encoding = encoding; +#endif newp->counter = _nl_msg_cat_cntr; newp->domain = domain; newp->translation = retval; newp->translation_length = retlen; - __libc_rwlock_wrlock (tree_lock); + gl_rwlock_wrlock (tree_lock); /* Insert the entry in the search tree. */ foundp = (struct known_translation_t **) tsearch (newp, &root, transcmp); - __libc_rwlock_unlock (tree_lock); + gl_rwlock_unlock (tree_lock); if (foundp == NULL || __builtin_expect (*foundp != newp, 0)) @@ -723,31 +831,68 @@ DCIGETTEXT (domainname, msgid1, msgid2, plural, n, category) (*foundp)->translation = retval; (*foundp)->translation_length = retlen; } -#endif + __set_errno (saved_errno); /* Now deal with plural. */ if (plural) retval = plural_lookup (domain, n, retval, retlen); + gl_rwlock_unlock (_nl_state_lock); +#ifdef _LIBC __libc_rwlock_unlock (__libc_setlocale_lock); - __libc_rwlock_unlock (_nl_state_lock); +#endif return retval; } } } - /* NOTREACHED */ + + return_untranslated: + /* 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) + { + extern void _nl_log_untranslated (const char *logfilename, + const char *domainname, + const char *msgid1, const char *msgid2, + int plural); + const char *logfilename = getenv ("GETTEXT_LOG_UNTRANSLATED"); + + if (logfilename != NULL && logfilename[0] != '\0') + _nl_log_untranslated (logfilename, domainname, msgid1, msgid2, plural); + } +#endif + __set_errno (saved_errno); + return (plural == 0 + ? (char *) msgid1 + /* Use the Germanic plural rule. */ + : n == 1 ? (char *) msgid1 : (char *) msgid2); } +/* Look up the translation of msgid within DOMAIN_FILE and DOMAINBINDING. + Return it if found. Return NULL if not found or in case of a conversion + failure (problem in the particular message catalog). Return (char *) -1 + in case of a memory allocation failure during conversion (only if + ENCODING != NULL resp. CONVERT == true). */ char * internal_function -_nl_find_msg (domain_file, domainbinding, msgid, convert, lengthp) - struct loaded_l10nfile *domain_file; - struct binding *domainbinding; - const char *msgid; - int convert; - size_t *lengthp; +#ifdef IN_LIBGLOCALE +_nl_find_msg (struct loaded_l10nfile *domain_file, + struct binding *domainbinding, const char *encoding, + const char *msgid, + size_t *lengthp) +#else +_nl_find_msg (struct loaded_l10nfile *domain_file, + struct binding *domainbinding, + const char *msgid, int convert, + size_t *lengthp) +#endif { struct loaded_domain *domain; nls_uint32 nstrings; @@ -853,19 +998,27 @@ _nl_find_msg (domain_file, domainbinding, msgid, convert, lengthp) } #if defined _LIBC || HAVE_ICONV +# ifdef IN_LIBGLOCALE + if (encoding != NULL) +# else if (convert) +# endif { /* We are supposed to do a conversion. */ +# 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. */ - __libc_rwlock_rdlock (domain->conversions_lock); + 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; ) { @@ -877,12 +1030,12 @@ _nl_find_msg (domain_file, domainbinding, msgid, convert, lengthp) } } - __libc_rwlock_unlock (domain->conversions_lock); + gl_rwlock_unlock (domain->conversions_lock); if (convd == NULL) { /* We have to allocate a new conversions table. */ - __libc_rwlock_wrlock (domain->conversions_lock); + gl_rwlock_wrlock (domain->conversions_lock); nconversions = domain->nconversions; /* Maybe in the meantime somebody added the translation. @@ -897,140 +1050,151 @@ _nl_find_msg (domain_file, domainbinding, msgid, convert, lengthp) } } - /* Allocate a table for the converted translations for this - encoding. */ - struct converted_domain *new_conversions = - (struct converted_domain *) - realloc (domain->conversions, - (nconversions + 1) * sizeof (struct converted_domain)); + { + /* 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))); + + 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; + } - if (__glibc_unlikely (new_conversions == NULL)) - { + domain->conversions = new_conversions; + + /* 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. */ - unlock_fail: - __libc_rwlock_unlock (domain->conversions_lock); - return (char *) -1; - } - - domain->conversions = new_conversions; - - /* Copy the 'encoding' string to permanent storage. */ - encoding = strdup (encoding); - if (__glibc_unlikely (encoding == NULL)) - /* Nothing we can do, no more memory. We cannot use the - translation because it might be encoded incorrectly. */ - goto unlock_fail; + goto unlock_fail; - convd = &new_conversions[nconversions]; - convd->encoding = encoding; + 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. */ + /* 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; - - /* Get the header entry. This is a recursion, but it doesn't - reallocate domain->conversions because we pass convert = 0. */ - nullentry = - _nl_find_msg (domain_file, domainbinding, "", 0, &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 = +# ifdef IN_LIBGLOCALE + _nl_find_msg (domain_file, domainbinding, NULL, "", + &nullentrylen); +# else + _nl_find_msg (domain_file, domainbinding, "", 0, &nullentrylen); +# endif - /* Resource problems are fatal. If we continue onwards we will - only attempt to calloc a new conv_tab and fail later. */ - if (__glibc_unlikely (nullentry == (char *) -1)) - return (char *) -1; + /* Resource problems are fatal. If we continue onwards we will + only attempt to calloc a new conv_tab and fail later. */ + if (__builtin_expect (nullentry == (char *) -1, 0)) + return (char *) -1; - 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 (__glibc_unlikely (r != __GCONV_OK)) - { - /* If the output encoding is the same there is - nothing to do. Otherwise do not use the - translation at all. */ - if (__glibc_likely (r != __GCONV_NULCONV)) - { - __libc_rwlock_unlock (domain->conversions_lock); - free ((char *) encoding); - return NULL; - } - - convd->conv = (__gconv_t) -1; - } + /* 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; + } # else # if HAVE_ICONV - /* When using GNU libc >= 2.2 or GNU libiconv >= 1.5, - we want to use transliteration. */ -# if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 2) || __GLIBC__ > 2 \ + /* When using GNU libc >= 2.2 or GNU libiconv >= 1.5, + we want to use transliteration. */ +# if (((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 2) || __GLIBC__ > 2) \ + && !defined __UCLIBC__) \ || _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: - __libc_rwlock_unlock (domain->conversions_lock); + gl_rwlock_unlock (domain->conversions_lock); } if ( @@ -1043,7 +1207,6 @@ _nl_find_msg (domain_file, domainbinding, msgid, convert, lengthp) # endif ) { - __libc_lock_define_initialized (static, lock) /* We are supposed to do a conversion. First allocate an appropriate table with the same structure as the table of translations in the file, where we can put the pointers @@ -1053,14 +1216,22 @@ _nl_find_msg (domain_file, domainbinding, msgid, convert, lengthp) handle this case by converting RESULTLEN bytes, including NULs. */ - if (__glibc_unlikely (convd->conv_tab == NULL)) + /* 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 - = calloc (nstrings + domain->n_sysdep_strings, - sizeof (char *)); + convd->conv_tab = + (char **) calloc (nstrings + domain->n_sysdep_strings, + sizeof (char *)); if (convd->conv_tab != NULL) goto not_translated_yet; /* Mark that we didn't succeed allocating a table. */ @@ -1069,16 +1240,13 @@ _nl_find_msg (domain_file, domainbinding, msgid, convert, lengthp) __libc_lock_unlock (lock); } - if (__glibc_unlikely (convd->conv_tab == (char **) -1)) + if (__builtin_expect (convd->conv_tab == (char **) -1, 0)) /* Nothing we can do, no more memory. We cannot use the translation because it might be encoded incorrectly. */ return (char *) -1; if (convd->conv_tab[act] == NULL) { - __libc_lock_lock (lock); - not_translated_yet:; - /* We haven't used this string so far, so it is not translated yet. Do this now. */ /* We use a bit more efficient memory handling. @@ -1092,11 +1260,17 @@ _nl_find_msg (domain_file, domainbinding, msgid, convert, lengthp) 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) @@ -1190,7 +1364,7 @@ _nl_find_msg (domain_file, domainbinding, msgid, convert, lengthp) /* Fall through and return -1. */ # endif } - if (__glibc_unlikely (newmem == NULL)) + if (__builtin_expect (newmem == NULL, 0)) { freemem = NULL; freemem_size = 0; @@ -1241,11 +1415,8 @@ _nl_find_msg (domain_file, domainbinding, msgid, convert, lengthp) /* Look up a plural variant. */ static char * internal_function -plural_lookup (domain, n, translation, translation_len) - struct loaded_l10nfile *domain; - unsigned long int n; - const char *translation; - size_t translation_len; +plural_lookup (struct loaded_l10nfile *domain, unsigned long int n, + const char *translation, size_t translation_len) { struct loaded_domain *domaindata = (struct loaded_domain *) domain->data; unsigned long int index; @@ -1282,8 +1453,7 @@ plural_lookup (domain, n, translation, translation_len) /* Return string representation of locale CATEGORY. */ static const char * internal_function -category_to_name (category) - int category; +category_to_name (int category) { const char *retval; @@ -1340,41 +1510,102 @@ category_to_name (category) } #endif -/* Guess value of current locale from value of the environment variables. */ +/* Guess value of current locale from value of the environment variables + or system-dependent defaults. */ static const char * internal_function -guess_category_value (category, categoryname) - int category; - const char *categoryname; +#ifdef IN_LIBGLOCALE +guess_category_value (int category, const char *categoryname, + const char *locale) + +#else +guess_category_value (int category, const char *categoryname) +#endif { const char *language; - const char *retval; - - /* The highest priority value is the `LANGUAGE' environment - variable. But we don't use the value if the currently selected - locale is the C locale. This is a GNU extension. */ - language = getenv ("LANGUAGE"); - if (language != NULL && language[0] == '\0') - language = NULL; +#ifndef IN_LIBGLOCALE + const char *locale; +# ifndef _LIBC + const char *language_default; + int locale_defaulted; +# endif +#endif - /* We have to proceed with the POSIX methods of looking to `LC_ALL', + /* We use the settings in the following order: + 1. The value of the environment variable 'LANGUAGE'. This is a GNU + extension. Its value can be a colon-separated list of locale names. + 2. The value of the environment variable 'LC_ALL', 'LC_xxx', or 'LANG'. + More precisely, the first among these that is set to a non-empty value. + This is how POSIX specifies it. The value is a single locale name. + 3. A system-dependent preference list of languages. Its value can be a + colon-separated list of locale names. + 4. A system-dependent default locale name. + This way: + - System-dependent settings can be overridden by environment variables. + - If the system provides both a list of languages and a default locale, + the former is used. */ + +#ifndef IN_LIBGLOCALE + /* Fetch the locale name, through the POSIX method of looking to `LC_ALL', `LC_xxx', and `LANG'. On some systems this can be done by the `setlocale' function itself. */ -#ifdef _LIBC - retval = __current_locale_name (category); -#else - retval = _nl_locale_name (category, categoryname); +# ifdef _LIBC + locale = __current_locale_name (category); +# 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); + if (locale == NULL) + { + locale = _nl_locale_name_default (); + locale_defaulted = 1; + } + } +# endif #endif - return language != NULL && strcmp (retval, "C") != 0 ? language : retval; + /* Ignore LANGUAGE and its system-dependent analogon if the locale is set + to "C" because + 1. "C" locale usually uses the ASCII encoding, and most international + messages use non-ASCII characters. These characters get displayed + as question marks (if using glibc's iconv()) or as invalid 8-bit + characters (because other iconv()s refuse to convert most non-ASCII + characters to ASCII). In any case, the output is ugly. + 2. The precise output of some programs in the "C" locale is specified + by POSIX and should not depend on environment variables like + "LANGUAGE" or system-dependent information. We allow such programs + to use gettext(). */ + if (strcmp (locale, "C") == 0) + return locale; + + /* The highest priority value is the value of the 'LANGUAGE' environment + variable. */ + language = getenv ("LANGUAGE"); + if (language != NULL && language[0] != '\0') + return language; +#if !defined IN_LIBGLOCALE && !defined _LIBC + /* The next priority value is the locale name, if not defaulted. */ + if (locale_defaulted) + { + /* The next priority value is the default language preferences list. */ + language_default = _nl_language_preferences_default (); + if (language_default != NULL) + return language_default; + } + /* The least priority value is the locale name, if defaulted. */ +#endif + return locale; } -#if defined _LIBC || HAVE_ICONV +#if (defined _LIBC || HAVE_ICONV) && !defined IN_LIBGLOCALE /* Returns the output charset. */ static const char * internal_function -get_output_charset (domainbinding) - struct binding *domainbinding; +get_output_charset (struct binding *domainbinding) { /* The output charset should normally be determined by the locale. But sometimes the locale is not used or not correctly set up, so we provide @@ -1415,7 +1646,6 @@ get_output_charset (domainbinding) return _NL_CURRENT (LC_CTYPE, CODESET); # else # if HAVE_ICONV - extern const char *locale_charset PARAMS ((void)); return locale_charset (); # endif # endif @@ -1432,9 +1662,7 @@ get_output_charset (domainbinding) to be defined. */ #if !_LIBC && !HAVE_STPCPY static char * -stpcpy (dest, src) - char *dest; - const char *src; +stpcpy (char *dest, const char *src) { while ((*dest++ = *src++) != '\0') /* Do nothing. */ ; @@ -1444,15 +1672,16 @@ stpcpy (dest, src) #if !_LIBC && !HAVE_MEMPCPY static void * -mempcpy (dest, src, n) - void *dest; - const void *src; - size_t n; +mempcpy (void *dest, const void *src, size_t n) { return (void *) ((char *) memcpy (dest, src, n) + 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 diff --git a/intl/dcngettext.c b/intl/dcngettext.c index f3404f3..67dcbcf 100644 --- a/intl/dcngettext.c +++ b/intl/dcngettext.c @@ -1,20 +1,18 @@ /* Implementation of the dcngettext(3) function. Copyright (C) 1995-2014 Free Software Foundation, Inc. - This file is part of the GNU C Library. - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. - The GNU C Library is distributed in the hope that it will be useful, + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ #ifdef HAVE_CONFIG_H # include @@ -44,12 +42,9 @@ /* Look up MSGID in the DOMAINNAME message catalog for the current CATEGORY locale. */ char * -DCNGETTEXT (domainname, msgid1, msgid2, n, category) - const char *domainname; - const char *msgid1; - const char *msgid2; - unsigned long int n; - int category; +DCNGETTEXT (const char *domainname, + const char *msgid1, const char *msgid2, unsigned long int n, + int category) { return DCIGETTEXT (domainname, msgid1, msgid2, 1, n, category); } diff --git a/intl/dgettext.c b/intl/dgettext.c index d7c2331..c0e6cd0 100644 --- a/intl/dgettext.c +++ b/intl/dgettext.c @@ -1,28 +1,27 @@ /* Implementation of the dgettext(3) function. Copyright (C) 1995-2014 Free Software Foundation, Inc. - This file is part of the GNU C Library. - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. - The GNU C Library is distributed in the hope that it will be useful, + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ #ifdef HAVE_CONFIG_H # include #endif +#include "gettextP.h" + #include -#include "gettextP.h" #ifdef _LIBC # include #else @@ -46,9 +45,7 @@ /* Look up MSGID in the DOMAINNAME message catalog of the current LC_MESSAGES locale. */ char * -DGETTEXT (domainname, msgid) - const char *domainname; - const char *msgid; +DGETTEXT (const char *domainname, const char *msgid) { return DCGETTEXT (domainname, msgid, LC_MESSAGES); } diff --git a/intl/dngettext.c b/intl/dngettext.c index 38cfdac..4d900e7 100644 --- a/intl/dngettext.c +++ b/intl/dngettext.c @@ -1,28 +1,27 @@ /* Implementation of the dngettext(3) function. Copyright (C) 1995-2014 Free Software Foundation, Inc. - This file is part of the GNU C Library. - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. - The GNU C Library is distributed in the hope that it will be useful, + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ #ifdef HAVE_CONFIG_H # include #endif +#include "gettextP.h" + #include -#include "gettextP.h" #ifdef _LIBC # include #else @@ -46,11 +45,8 @@ /* Look up MSGID in the DOMAINNAME message catalog of the current LC_MESSAGES locale and skip message according to the plural form. */ char * -DNGETTEXT (domainname, msgid1, msgid2, n) - const char *domainname; - const char *msgid1; - const char *msgid2; - unsigned long int n; +DNGETTEXT (const char *domainname, + const char *msgid1, const char *msgid2, unsigned long int n) { return DCNGETTEXT (domainname, msgid1, msgid2, n, LC_MESSAGES); } diff --git a/intl/eval-plural.h b/intl/eval-plural.h new file mode 100644 index 0000000..924c8c3 --- /dev/null +++ b/intl/eval-plural.h @@ -0,0 +1,106 @@ +/* Plural expression evaluation. + 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 Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +#ifndef STATIC +#define STATIC static +#endif + +/* Evaluate the plural expression and return an index value. */ +STATIC +unsigned long int +internal_function +plural_eval (const struct expression *pexp, unsigned long int n) +{ + switch (pexp->nargs) + { + case 0: + switch (pexp->operation) + { + case var: + return n; + case num: + return pexp->val.num; + default: + break; + } + /* NOTREACHED */ + break; + case 1: + { + /* pexp->operation must be lnot. */ + unsigned long int arg = plural_eval (pexp->val.args[0], n); + return ! arg; + } + case 2: + { + unsigned long int leftarg = plural_eval (pexp->val.args[0], n); + if (pexp->operation == lor) + return leftarg || plural_eval (pexp->val.args[1], n); + else if (pexp->operation == land) + return leftarg && plural_eval (pexp->val.args[1], n); + else + { + unsigned long int rightarg = plural_eval (pexp->val.args[1], n); + + switch (pexp->operation) + { + case mult: + return leftarg * rightarg; + case divide: +#if !INTDIV0_RAISES_SIGFPE + if (rightarg == 0) + raise (SIGFPE); +#endif + return leftarg / rightarg; + case module: +#if !INTDIV0_RAISES_SIGFPE + if (rightarg == 0) + raise (SIGFPE); +#endif + return leftarg % rightarg; + case plus: + return leftarg + rightarg; + case minus: + return leftarg - rightarg; + case less_than: + return leftarg < rightarg; + case greater_than: + return leftarg > rightarg; + case less_or_equal: + return leftarg <= rightarg; + case greater_or_equal: + return leftarg >= rightarg; + case equal: + return leftarg == rightarg; + case not_equal: + return leftarg != rightarg; + default: + break; + } + } + /* NOTREACHED */ + break; + } + case 3: + { + /* pexp->operation must be qmop. */ + unsigned long int boolarg = plural_eval (pexp->val.args[0], n); + return plural_eval (pexp->val.args[boolarg ? 1 : 2], n); + } + } + /* NOTREACHED */ + return 0; +} diff --git a/intl/explodename.c b/intl/explodename.c index 31fcf3d..9e049c7 100644 --- a/intl/explodename.c +++ b/intl/explodename.c @@ -1,20 +1,18 @@ /* Copyright (C) 1995-2014 Free Software Foundation, Inc. - This file is part of the GNU C Library. Contributed by Ulrich Drepper , 1995. - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. - The GNU C Library is distributed in the hope that it will be useful, + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ #ifdef HAVE_CONFIG_H # include @@ -37,11 +35,13 @@ /* @@ end of prolog @@ */ -static char *_nl_find_language PARAMS ((const char *name)); +/* Split a locale name NAME into a leading language part and all the + rest. Return a pointer to the first character after the language, + i.e. to the first byte of the rest. */ +static char *_nl_find_language (const char *name); static char * -_nl_find_language (name) - const char *name; +_nl_find_language (const char *name) { while (name[0] != '\0' && name[0] != '_' && name[0] != '@' && name[0] != '.') ++name; @@ -51,14 +51,10 @@ _nl_find_language (name) int -_nl_explode_name (name, language, modifier, territory, codeset, - normalized_codeset) - char *name; - const char **language; - const char **modifier; - const char **territory; - const char **codeset; - const char **normalized_codeset; +_nl_explode_name (char *name, + const char **language, const char **modifier, + const char **territory, const char **codeset, + const char **normalized_codeset) { char *cp; int mask; @@ -77,8 +73,8 @@ _nl_explode_name (name, language, modifier, territory, codeset, if (*language == cp) /* This does not make sense: language has to be specified. Use this entry as it is without exploding. Perhaps it is an alias. */ - cp = __rawmemchr (*language, '\0'); - else if (cp[0] != '@') + cp = strchr (*language, '\0'); + else { if (cp[0] == '_') { diff --git a/intl/finddomain.c b/intl/finddomain.c index 8a588bc..b5a48a5 100644 --- a/intl/finddomain.c +++ b/intl/finddomain.c @@ -1,21 +1,19 @@ /* Handle list of needed message catalogs Copyright (C) 1995-2014 Free Software Foundation, Inc. - This file is part of the GNU C Library. Written by Ulrich Drepper , 1995. - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. - The GNU C Library is distributed in the hope that it will be useful, + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ #ifdef HAVE_CONFIG_H # include @@ -33,11 +31,21 @@ #include "gettextP.h" #ifdef _LIBC # include -# include #else # include "libgnuintl.h" #endif +/* Handle multi-threaded applications. */ +#ifdef _LIBC +# include +# define gl_rwlock_define_initialized __libc_rwlock_define_initialized +# define gl_rwlock_rdlock __libc_rwlock_rdlock +# define gl_rwlock_wrlock __libc_rwlock_wrlock +# define gl_rwlock_unlock __libc_rwlock_unlock +#else +# include "lock.h" +#endif + /* @@ end of prolog @@ */ /* List of already loaded domains. */ static struct loaded_l10nfile *_nl_loaded_domains; @@ -48,11 +56,8 @@ static struct loaded_l10nfile *_nl_loaded_domains; established bindings. */ struct loaded_l10nfile * internal_function -_nl_find_domain (dirname, locale, domainname, domainbinding) - const char *dirname; - char *locale; - const char *domainname; - struct binding *domainbinding; +_nl_find_domain (const char *dirname, char *locale, + const char *domainname, struct binding *domainbinding) { struct loaded_l10nfile *retval; const char *language; @@ -65,7 +70,7 @@ _nl_find_domain (dirname, locale, domainname, domainbinding) /* LOCALE can consist of up to four recognized parts for the XPG syntax: - language[_territory[.codeset]][@modifier] + language[_territory][.codeset][@modifier] Beside the first part all of them are allowed to be missing. If the full specified locale is not found, the less specific one are @@ -78,15 +83,16 @@ _nl_find_domain (dirname, locale, domainname, domainbinding) */ /* We need to protect modifying the _NL_LOADED_DOMAINS data. */ - __libc_rwlock_define_initialized (static, lock); - __libc_rwlock_rdlock (lock); + gl_rwlock_define_initialized (static, lock); + gl_rwlock_rdlock (lock); /* If we have already tested for this locale entry there has to be one data set in the list of loaded domains. */ retval = _nl_make_l10nflist (&_nl_loaded_domains, dirname, strlen (dirname) + 1, 0, locale, NULL, NULL, NULL, NULL, domainname, 0); - __libc_rwlock_unlock (lock); + + gl_rwlock_unlock (lock); if (retval != NULL) { @@ -117,11 +123,23 @@ _nl_find_domain (dirname, locale, domainname, domainbinding) done. */ alias_value = _nl_expand_alias (locale); if (alias_value != NULL) - locale = strdupa (alias_value); + { +#if defined _LIBC || defined HAVE_STRDUP + locale = strdup (alias_value); + if (locale == NULL) + return NULL; +#else + size_t len = strlen (alias_value) + 1; + locale = (char *) malloc (len); + if (locale == NULL) + return NULL; + + memcpy (locale, alias_value, len); +#endif + } /* Now we determine the single parts of the locale name. First - look for the language. Termination symbols are `_' and `@' if - we use XPG4 style, and `_', `+', and `,' if we use CEN syntax. */ + look for the language. Termination symbols are `_', '.', and `@'. */ mask = _nl_explode_name (locale, &language, &modifier, &territory, &codeset, &normalized_codeset); if (mask == -1) @@ -129,7 +147,7 @@ _nl_find_domain (dirname, locale, domainname, domainbinding) return NULL; /* We need to protect modifying the _NL_LOADED_DOMAINS data. */ - __libc_rwlock_wrlock (lock); + gl_rwlock_wrlock (lock); /* Create all possible locale entries which might be interested in generalization. */ @@ -137,7 +155,8 @@ _nl_find_domain (dirname, locale, domainname, domainbinding) strlen (dirname) + 1, mask, language, territory, codeset, normalized_codeset, modifier, domainname, 1); - __libc_rwlock_unlock (lock); + + gl_rwlock_unlock (lock); if (retval == NULL) /* This means we are out of core. */ @@ -157,6 +176,10 @@ _nl_find_domain (dirname, locale, domainname, domainbinding) } } + /* The room for an alias was dynamically allocated. Free it now. */ + if (alias_value != NULL) + free (locale); + out: /* The space for normalized_codeset is dynamically allocated. Free it. */ if (mask & XPG_NORM_CODESET) diff --git a/intl/gettext.c b/intl/gettext.c index 3864a03..4a1af7e 100644 --- a/intl/gettext.c +++ b/intl/gettext.c @@ -1,20 +1,18 @@ /* Implementation of gettext(3) function. Copyright (C) 1995-2014 Free Software Foundation, Inc. - This file is part of the GNU C Library. - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. - The GNU C Library is distributed in the hope that it will be useful, + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ #ifdef HAVE_CONFIG_H # include @@ -52,8 +50,7 @@ LC_MESSAGES locale. If not found, returns MSGID itself (the default text). */ char * -GETTEXT (msgid) - const char *msgid; +GETTEXT (const char *msgid) { return DCGETTEXT (NULL, msgid, LC_MESSAGES); } diff --git a/intl/gettextP.h b/intl/gettextP.h index 3da2322..6f4c684 100644 --- a/intl/gettextP.h +++ b/intl/gettextP.h @@ -1,21 +1,19 @@ /* Header describing internals of libintl library. Copyright (C) 1995-2014 Free Software Foundation, Inc. - This file is part of the GNU C Library. Written by Ulrich Drepper , 1995. - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. - The GNU C Library is distributed in the hope that it will be useful, + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ #ifndef _GETTEXTP_H #define _GETTEXTP_H @@ -30,20 +28,67 @@ # endif #endif +/* Handle multi-threaded applications. */ +#ifdef _LIBC +# include +# define gl_rwlock_define __libc_rwlock_define +#else +# include "lock.h" +#endif + +#ifdef _LIBC +struct loaded_domain; +extern char *__gettext (const char *__msgid); +extern char *__dgettext (const char *__domainname, const char *__msgid); +extern char *__dcgettext (const char *__domainname, const char *__msgid, + int __category); +extern char *__ngettext (const char *__msgid1, const char *__msgid2, + unsigned long int __n); +extern char *__dngettext (const char *__domainname, + const char *__msgid1, const char *__msgid2, + unsigned long int n); +extern char *__dcngettext (const char *__domainname, + const char *__msgid1, const char *__msgid2, + unsigned long int __n, int __category); +extern char *__dcigettext (const char *__domainname, + const char *__msgid1, const char *__msgid2, + int __plural, unsigned long int __n, + int __category); +extern char *__textdomain (const char *__domainname); +extern char *__bindtextdomain (const char *__domainname, + const char *__dirname); +extern char *__bind_textdomain_codeset (const char *__domainname, + const char *__codeset); +extern void _nl_finddomain_subfreeres (void) attribute_hidden; +extern void _nl_unload_domain (struct loaded_domain *__domain) + internal_function attribute_hidden; +#else +/* Declare the exported libintl_* functions, in a way that allows us to + call them under their real name. */ +# undef _INTL_REDIRECT_INLINE +# undef _INTL_REDIRECT_MACROS +# define _INTL_REDIRECT_MACROS +# include "libgnuintl.h" +# ifdef IN_LIBGLOCALE +extern char *gl_dcigettext (const char *__domainname, + const char *__msgid1, const char *__msgid2, + int __plural, unsigned long int __n, + int __category, + const char *__localename, const char *__encoding); +# else +extern char *libintl_dcigettext (const char *__domainname, + const char *__msgid1, const char *__msgid2, + int __plural, unsigned long int __n, + int __category); +# endif +#endif + #include "loadinfo.h" #include "gmo.h" /* Get nls_uint32. */ /* @@ end of prolog @@ */ -#ifndef PARAMS -# if __STDC__ || defined __GNUC__ || defined __SUNPRO_C || defined __cplusplus || __PROTOTYPES -# define PARAMS(args) args -# else -# define PARAMS(args) () -# endif -#endif - #ifndef internal_function # define internal_function #endif @@ -52,6 +97,12 @@ # define attribute_hidden #endif +/* Tell the compiler when a conditional or integer expression is + almost always true or almost always false. */ +#ifndef HAVE_BUILTIN_EXPECT +# define __builtin_expect(expr, val) (expr) +#endif + #ifndef W # define W(flag, data) ((flag) ? SWAP (data) : (data)) #endif @@ -61,11 +112,13 @@ # include # define SWAP(i) bswap_32 (i) #else -static nls_uint32 SWAP PARAMS ((nls_uint32 i)); - 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); } @@ -139,7 +192,7 @@ struct loaded_domain /* Cache of charset conversions of the translated strings. */ struct converted_domain *conversions; size_t nconversions; - __libc_rwlock_define (, conversions_lock); + gl_rwlock_define (, conversions_lock) const struct expression *plural; unsigned long int nplurals; @@ -166,82 +219,92 @@ struct binding /* A counter which is incremented each time some previous translations become invalid. This variable is part of the external ABI of the GNU libintl. */ -extern int _nl_msg_cat_cntr; +#ifdef IN_LIBGLOCALE +# include +extern LIBGLOCALE_DLL_EXPORTED int _nl_msg_cat_cntr; +#else +extern LIBINTL_DLL_EXPORTED int _nl_msg_cat_cntr; +#endif #ifndef _LIBC -const char *_nl_locale_name PARAMS ((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 PARAMS ((const char *__dirname, - char *__locale, - const char *__domainname, - struct binding *__domainbinding)) +struct loaded_l10nfile *_nl_find_domain (const char *__dirname, char *__locale, + const char *__domainname, + struct binding *__domainbinding) internal_function; -void _nl_load_domain PARAMS ((struct loaded_l10nfile *__domain, - struct binding *__domainbinding)) +void _nl_load_domain (struct loaded_l10nfile *__domain, + struct binding *__domainbinding) internal_function; -char *_nl_find_msg PARAMS ((struct loaded_l10nfile *domain_file, - struct binding *domainbinding, const char *msgid, - int convert, size_t *lengthp)) +#ifdef IN_LIBGLOCALE +char *_nl_find_msg (struct loaded_l10nfile *domain_file, + struct binding *domainbinding, const char *encoding, + const char *msgid, + size_t *lengthp) internal_function; +#else +char *_nl_find_msg (struct loaded_l10nfile *domain_file, + struct binding *domainbinding, const char *msgid, + int convert, size_t *lengthp) + 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 -extern char *__gettext PARAMS ((const char *__msgid)); -extern char *__dgettext PARAMS ((const char *__domainname, - const char *__msgid)); -extern char *__dcgettext PARAMS ((const char *__domainname, - const char *__msgid, int __category)); -extern char *__ngettext PARAMS ((const char *__msgid1, const char *__msgid2, - unsigned long int __n)); -extern char *__dngettext PARAMS ((const char *__domainname, - const char *__msgid1, const char *__msgid2, - unsigned long int n)); -extern char *__dcngettext PARAMS ((const char *__domainname, - const char *__msgid1, const char *__msgid2, - unsigned long int __n, int __category)); -extern char *__dcigettext PARAMS ((const char *__domainname, - const char *__msgid1, const char *__msgid2, - int __plural, unsigned long int __n, - int __category)); -extern char *__textdomain PARAMS ((const char *__domainname)); -extern char *__bindtextdomain PARAMS ((const char *__domainname, - const char *__dirname)); -extern char *__bind_textdomain_codeset PARAMS ((const char *__domainname, - const char *__codeset)); -extern void _nl_finddomain_subfreeres PARAMS ((void)) attribute_hidden; -extern void _nl_unload_domain PARAMS ((struct loaded_domain *__domain)) - internal_function attribute_hidden; -#else -extern char *libintl_gettext PARAMS ((const char *__msgid)); -extern char *libintl_dgettext PARAMS ((const char *__domainname, - const char *__msgid)); -extern char *libintl_dcgettext PARAMS ((const char *__domainname, - const char *__msgid, int __category)); -extern char *libintl_ngettext PARAMS ((const char *__msgid1, - const char *__msgid2, - unsigned long int __n)); -extern char *libintl_dngettext PARAMS ((const char *__domainname, - const char *__msgid1, - const char *__msgid2, - unsigned long int __n)); -extern char *libintl_dcngettext PARAMS ((const char *__domainname, - const char *__msgid1, - const char *__msgid2, - unsigned long int __n, - int __category)); -extern char *libintl_dcigettext PARAMS ((const char *__domainname, - const char *__msgid1, - const char *__msgid2, - int __plural, unsigned long int __n, - int __category)); -extern char *libintl_textdomain PARAMS ((const char *__domainname)); -extern char *libintl_bindtextdomain PARAMS ((const char *__domainname, - const char *__dirname)); -extern char *libintl_bind_textdomain_codeset PARAMS ((const char *__domainname, - const char *__codeset)); +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 */ diff --git a/intl/gmo.h b/intl/gmo.h index c9330db..4d18e9a 100644 --- a/intl/gmo.h +++ b/intl/gmo.h @@ -1,20 +1,18 @@ -/* Internal header for GNU gettext internationalization functions. +/* Description of GNU message catalog format: general file layout. Copyright (C) 1995-2014 Free Software Foundation, Inc. - This file is part of the GNU C Library. - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. - The GNU C Library is distributed in the hope that it will be useful, + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ #ifndef _GETTEXT_H #define _GETTEXT_H 1 @@ -124,6 +122,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 +138,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, diff --git a/intl/hash-string.c b/intl/hash-string.c index 3e53e2a..f44ebc0 100644 --- a/intl/hash-string.c +++ b/intl/hash-string.c @@ -16,6 +16,11 @@ License along with the GNU C Library; if not, see . */ +#ifdef HAVE_CONFIG_H +# include +#endif + +/* Specification. */ #include "hash-string.h" @@ -23,8 +28,7 @@ [see Aho/Sethi/Ullman, COMPILERS: Principles, Techniques and Tools, 1986, 1987 Bell Telephone Laboratories, Inc.] */ unsigned long int -__hash_string (str_param) - const char *str_param; +__hash_string (const char *str_param) { unsigned long int hval, g; const char *str = str_param; diff --git a/intl/hash-string.h b/intl/hash-string.h index 646631f..339a4f8 100644 --- a/intl/hash-string.h +++ b/intl/hash-string.h @@ -1,37 +1,34 @@ -/* Implements a string hashing function. +/* Description of GNU message catalog format: string hashing function. Copyright (C) 1995-2014 Free Software Foundation, Inc. - This file is part of the GNU C Library. - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. - The GNU C Library is distributed in the hope that it will be useful, + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ /* @@ end of prolog @@ */ -#ifndef PARAMS -# if __STDC__ || defined __GNUC__ || defined __SUNPRO_C || defined __cplusplus || __PROTOTYPES -# define PARAMS(Args) Args -# else -# define PARAMS(Args) () -# endif -#endif - /* We assume to have `unsigned long int' value with at least 32 bits. */ #define HASHWORDBITS 32 +#ifndef _LIBC +# ifdef IN_LIBINTL +# define __hash_string libintl_hash_string +# else +# define __hash_string hash_string +# endif +#endif + /* Defines the so called `hashpjw' function by P.J. Weinberger [see Aho/Sethi/Ullman, COMPILERS: Principles, Techniques and Tools, 1986, 1987 Bell Telephone Laboratories, Inc.] */ -extern unsigned long int __hash_string PARAMS ((const char *__str_param)) - attribute_hidden; +extern unsigned long int __hash_string (const char *str_param); diff --git a/intl/l10nflist.c b/intl/l10nflist.c index ca04ad3..c02bb88 100644 --- a/intl/l10nflist.c +++ b/intl/l10nflist.c @@ -1,20 +1,18 @@ /* Copyright (C) 1995-2014 Free Software Foundation, Inc. - This file is part of the GNU C Library. Contributed by Ulrich Drepper , 1995. - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. - The GNU C Library is distributed in the hope that it will be useful, + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ /* Tell glibc's to provide a prototype for stpcpy(). This must come before because may include @@ -58,20 +56,19 @@ # endif #else # ifndef HAVE_STPCPY -static char *stpcpy PARAMS ((char *dest, const char *src)); +static char *stpcpy (char *dest, const char *src); # endif #endif /* Define function which are usually not available. */ -#if !defined _LIBC && !defined HAVE___ARGZ_COUNT +#if defined HAVE_ARGZ_COUNT +# undef __argz_count +# define __argz_count argz_count +#else /* Returns the number of strings in ARGZ. */ -static size_t argz_count__ PARAMS ((const char *argz, size_t len)); - static size_t -argz_count__ (argz, len) - const char *argz; - size_t len; +argz_count__ (const char *argz, size_t len) { size_t count = 0; while (len > 0) @@ -85,18 +82,16 @@ argz_count__ (argz, len) } # undef __argz_count # define __argz_count(argz, len) argz_count__ (argz, len) -#endif /* !_LIBC && !HAVE___ARGZ_COUNT */ +#endif /* !_LIBC && !HAVE_ARGZ_COUNT */ -#if !defined _LIBC && !defined HAVE___ARGZ_STRINGIFY +#if defined HAVE_ARGZ_STRINGIFY +# undef __argz_stringify +# define __argz_stringify argz_stringify +#else /* Make '\0' separated arg vector ARGZ printable by converting all the '\0's except the last into the character SEP. */ -static void argz_stringify__ PARAMS ((char *argz, size_t len, int sep)); - static void -argz_stringify__ (argz, len, sep) - char *argz; - size_t len; - int sep; +argz_stringify__ (char *argz, size_t len, int sep) { while (len > 0) { @@ -109,22 +104,20 @@ argz_stringify__ (argz, len, sep) } # undef __argz_stringify # define __argz_stringify(argz, len, sep) argz_stringify__ (argz, len, sep) -#endif /* !_LIBC && !HAVE___ARGZ_STRINGIFY */ - -#if !defined _LIBC && !defined HAVE___ARGZ_NEXT -static char *argz_next__ PARAMS ((char *argz, size_t argz_len, - const char *entry)); +#endif /* !_LIBC && !HAVE_ARGZ_STRINGIFY */ +#ifdef _LIBC +#elif defined HAVE_ARGZ_NEXT +# undef __argz_next +# define __argz_next argz_next +#else static char * -argz_next__ (argz, argz_len, entry) - char *argz; - size_t argz_len; - const char *entry; +argz_next__ (char *argz, size_t argz_len, const char *entry) { if (entry) { if (entry < argz + argz_len) - entry = strchr (entry, '\0') + 1; + entry = strchr (entry, '\0') + 1; return entry >= argz + argz_len ? NULL : (char *) entry; } @@ -136,16 +129,12 @@ argz_next__ (argz, argz_len, entry) } # undef __argz_next # define __argz_next(argz, len, entry) argz_next__ (argz, len, entry) -#endif /* !_LIBC && !HAVE___ARGZ_NEXT */ - +#endif /* !_LIBC && !HAVE_ARGZ_NEXT */ /* Return number of bits set in X. */ #ifndef ARCH_POP -static int pop PARAMS ((int x)); - static inline int -pop (x) - int x; +pop (int x) { /* We assume that no more than 16 bits are used. */ x = ((x & ~0x5555) >> 1) + (x & 0x5555); @@ -159,20 +148,12 @@ pop (x) struct loaded_l10nfile * -_nl_make_l10nflist (l10nfile_list, dirlist, dirlist_len, mask, language, - territory, codeset, normalized_codeset, modifier, - filename, do_allocate) - struct loaded_l10nfile **l10nfile_list; - const char *dirlist; - size_t dirlist_len; - int mask; - const char *language; - const char *territory; - const char *codeset; - const char *normalized_codeset; - const char *modifier; - const char *filename; - int do_allocate; +_nl_make_l10nflist (struct loaded_l10nfile **l10nfile_list, + const char *dirlist, size_t dirlist_len, + int mask, const char *language, const char *territory, + const char *codeset, const char *normalized_codeset, + const char *modifier, + const char *filename, int do_allocate) { char *abs_filename; struct loaded_l10nfile *last = NULL; @@ -315,11 +296,9 @@ _nl_make_l10nflist (l10nfile_list, dirlist, dirlist_len, mask, language, names. The return value is dynamically allocated and has to be freed by the caller. */ const char * -_nl_normalize_codeset (codeset, name_len) - const char *codeset; - size_t name_len; +_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; @@ -343,9 +322,10 @@ _nl_normalize_codeset (codeset, name_len) if (retval != NULL) { - wp = retval; if (only_digit) - wp = stpcpy (wp, "iso"); + wp = stpcpy (retval, "iso"); + else + wp = retval; for (cnt = 0; cnt < name_len; ++cnt) if (__isalpha_l ((unsigned char) codeset[cnt], locale)) @@ -368,9 +348,7 @@ _nl_normalize_codeset (codeset, name_len) to be defined. */ #if !_LIBC && !HAVE_STPCPY static char * -stpcpy (dest, src) - char *dest; - const char *src; +stpcpy (char *dest, const char *src) { while ((*dest++ = *src++) != '\0') /* Do nothing. */ ; diff --git a/intl/loadinfo.h b/intl/loadinfo.h index e11b2e8..adf5bc9 100644 --- a/intl/loadinfo.h +++ b/intl/loadinfo.h @@ -2,19 +2,18 @@ This file is part of the GNU C Library. Contributed by Ulrich Drepper , 1996. - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. - The GNU C Library is distributed in the hope that it will be useful, + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ #ifndef _LOADINFO_H #define _LOADINFO_H 1 @@ -31,18 +30,29 @@ in gettextP.h. */ -#ifndef PARAMS -# if __STDC__ || defined __GNUC__ || defined __SUNPRO_C || defined __cplusplus || __PROTOTYPES -# define PARAMS(args) args -# else -# define PARAMS(args) () -# endif -#endif - #ifndef internal_function # define internal_function #endif +#ifndef LIBINTL_DLL_EXPORTED +# define LIBINTL_DLL_EXPORTED +#endif + +/* Tell the compiler when a conditional or integer expression is + almost always true or almost always false. */ +#ifndef HAVE_BUILTIN_EXPECT +# define __builtin_expect(expr, val) (expr) +#endif + +/* Separator in PATH like lists of pathnames. */ +#if ((defined _WIN32 || defined __WIN32__) && !defined __CYGWIN__) || defined __EMX__ || defined __DJGPP__ + /* Win32, OS/2, DOS */ +# define PATH_SEPARATOR ';' +#else + /* Unix */ +# define PATH_SEPARATOR ':' +#endif + /* Encoding of locale name parts. */ #define XPG_NORM_CODESET 1 #define XPG_CODESET 2 @@ -66,27 +76,55 @@ struct loaded_l10nfile names. Normalization allows the user to use any of the common names. The return value is dynamically allocated and has to be freed by the caller. */ -extern const char *_nl_normalize_codeset PARAMS ((const char *codeset, - size_t name_len)); - +extern const char *_nl_normalize_codeset (const char *codeset, + size_t name_len); + +/* Lookup a locale dependent file. + *L10NFILE_LIST denotes a pool of lookup results of locale dependent + files of the same kind, sorted in decreasing order of ->filename. + DIRLIST and DIRLIST_LEN are an argz list of directories in which to + look, containing at least one directory (i.e. DIRLIST_LEN > 0). + MASK, LANGUAGE, TERRITORY, CODESET, NORMALIZED_CODESET, MODIFIER + are the pieces of the locale name, as produced by _nl_explode_name(). + FILENAME is the filename suffix. + The return value is the lookup result, either found in *L10NFILE_LIST, + or - if DO_ALLOCATE is nonzero - freshly allocated, or possibly NULL. + If the return value is non-NULL, it is added to *L10NFILE_LIST, and + its ->next field denotes the chaining inside *L10NFILE_LIST, and + furthermore its ->successor[] field contains a list of other lookup + results from which this lookup result inherits. */ extern struct loaded_l10nfile * -_nl_make_l10nflist PARAMS ((struct loaded_l10nfile **l10nfile_list, - const char *dirlist, size_t dirlist_len, int mask, - const char *language, const char *territory, - const char *codeset, - const char *normalized_codeset, - const char *modifier, const char *filename, - int do_allocate)); - - -extern const char *_nl_expand_alias PARAMS ((const char *name)); - -/* normalized_codeset is dynamically allocated and has to be freed by - the caller. */ -extern int _nl_explode_name PARAMS ((char *name, const char **language, - const char **modifier, - const char **territory, - const char **codeset, - const char **normalized_codeset)); +_nl_make_l10nflist (struct loaded_l10nfile **l10nfile_list, + const char *dirlist, size_t dirlist_len, int mask, + const char *language, const char *territory, + const char *codeset, const char *normalized_codeset, + const char *modifier, + const char *filename, int do_allocate); + +/* Lookup the real locale name for a locale alias NAME, or NULL if + NAME is not a locale alias (but possibly a real locale name). + The return value is statically allocated and must not be freed. */ +/* Part of the libintl ABI only for the sake of the gettext.m4 macro. */ +extern LIBINTL_DLL_EXPORTED const char *_nl_expand_alias (const char *name); + +/* Split a locale name NAME into its pieces: language, modifier, + territory, codeset. + NAME gets destructively modified: NUL bytes are inserted here and + there. *LANGUAGE gets assigned NAME. Each of *MODIFIER, *TERRITORY, + *CODESET gets assigned either a pointer into the old NAME string, or + NULL. *NORMALIZED_CODESET gets assigned the expanded *CODESET, if it + is different from *CODESET; this one is dynamically allocated and has + to be freed by the caller. + The return value is a bitmask, where each bit corresponds to one + filled-in value: + XPG_MODIFIER for *MODIFIER, + XPG_TERRITORY for *TERRITORY, + XPG_CODESET for *CODESET, + XPG_NORM_CODESET for *NORMALIZED_CODESET. + */ +extern int _nl_explode_name (char *name, const char **language, + const char **modifier, const char **territory, + const char **codeset, + const char **normalized_codeset); #endif /* loadinfo.h */ diff --git a/intl/loadmsgcat.c b/intl/loadmsgcat.c index 2ea0f10..4074c4c 100644 --- a/intl/loadmsgcat.c +++ b/intl/loadmsgcat.c @@ -1,20 +1,18 @@ /* Load needed message catalogs. Copyright (C) 1995-2014 Free Software Foundation, Inc. - This file is part of the GNU C Library. - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. - The GNU C Library is distributed in the hope that it will be useful, + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ /* Tell glibc's to provide a prototype for mempcpy(). This must come before because may include diff --git a/intl/localealias.c b/intl/localealias.c index 1d3f8eb..ff13dde 100644 --- a/intl/localealias.c +++ b/intl/localealias.c @@ -1,20 +1,18 @@ /* Handle aliases for locale names. Copyright (C) 1995-2014 Free Software Foundation, Inc. - This file is part of the GNU C Library. - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. - The GNU C Library is distributed in the hope that it will be useful, + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ /* Tell glibc's to provide a prototype for mempcpy(). This must come before because may include @@ -39,14 +37,19 @@ # define alloca __builtin_alloca # define HAVE_ALLOCA 1 #else -# if defined HAVE_ALLOCA_H || defined _LIBC -# include +# ifdef _MSC_VER +# include +# define alloca _alloca # else -# ifdef _AIX - #pragma alloca +# if defined HAVE_ALLOCA_H || defined _LIBC +# include # else -# ifndef alloca +# ifdef _AIX + #pragma alloca +# else +# ifndef alloca char *alloca (); +# endif # endif # endif # endif @@ -57,6 +60,12 @@ char *alloca (); #include "gettextP.h" +#ifdef ENABLE_RELOCATABLE +# include "relocatable.h" +#else +# define relocate(pathname) (pathname) +#endif + /* @@ end of prolog @@ */ #ifdef _LIBC @@ -70,11 +79,13 @@ char *alloca (); # endif # define HAVE_MEMPCPY 1 # define HAVE___FSETLOCKING 1 +#endif -/* We need locking here since we can be called from different places. */ +/* Handle multi-threaded applications. */ +#ifdef _LIBC # include - -__libc_lock_define_initialized (static, lock); +#else +# include "lock.h" #endif #ifndef internal_function @@ -99,16 +110,19 @@ __libc_lock_define_initialized (static, lock); # define freea(p) free (p) #endif -#if defined _LIBC_REENTRANT || defined HAVE_FGETS_UNLOCKED +#if defined _LIBC_REENTRANT || defined HAVE_DECL_FGETS_UNLOCKED # undef fgets # define fgets(buf, len, s) fgets_unlocked (buf, len, s) #endif -#if defined _LIBC_REENTRANT || defined HAVE_FEOF_UNLOCKED +#if defined _LIBC_REENTRANT || defined HAVE_DECL_FEOF_UNLOCKED # undef feof # define feof(s) feof_unlocked (s) #endif +__libc_lock_define_initialized (static, lock) + + struct alias_map { const char *alias; @@ -129,25 +143,25 @@ static size_t maxmap; /* Prototypes for local functions. */ -static size_t read_alias_file PARAMS ((const char *fname, int fname_len)) +static size_t read_alias_file (const char *fname, int fname_len) internal_function; -static int extend_alias_table PARAMS ((void)); -static int alias_compare PARAMS ((const struct alias_map *map1, - const struct alias_map *map2)); +static int extend_alias_table (void); +static int alias_compare (const struct alias_map *map1, + const struct alias_map *map2); const char * -_nl_expand_alias (name) - const char *name; +_nl_expand_alias (const char *name) { - static const char *locale_alias_path = LOCALE_ALIAS_PATH; + static const char *locale_alias_path; struct alias_map *retval; const char *result = NULL; size_t added; -#ifdef _LIBC __libc_lock_lock (lock); -#endif + + if (locale_alias_path == NULL) + locale_alias_path = LOCALE_ALIAS_PATH; do { @@ -158,8 +172,8 @@ _nl_expand_alias (name) if (nmap > 0) retval = (struct alias_map *) bsearch (&item, map, nmap, sizeof (struct alias_map), - (int (*) PARAMS ((const void *, - const void *)) + (int (*) (const void *, + const void *) ) alias_compare); else retval = NULL; @@ -177,11 +191,12 @@ _nl_expand_alias (name) { const char *start; - while (locale_alias_path[0] == ':') + while (locale_alias_path[0] == PATH_SEPARATOR) ++locale_alias_path; start = locale_alias_path; - while (locale_alias_path[0] != '\0' && locale_alias_path[0] != ':') + while (locale_alias_path[0] != '\0' + && locale_alias_path[0] != PATH_SEPARATOR) ++locale_alias_path; if (start < locale_alias_path) @@ -190,9 +205,7 @@ _nl_expand_alias (name) } while (added != 0); -#ifdef _LIBC __libc_lock_unlock (lock); -#endif return result; } @@ -200,9 +213,7 @@ _nl_expand_alias (name) static size_t internal_function -read_alias_file (fname, fname_len) - const char *fname; - int fname_len; +read_alias_file (const char *fname, int fname_len) { FILE *fp; char *full_fname; @@ -218,9 +229,13 @@ read_alias_file (fname, fname_len) memcpy (&full_fname[fname_len], aliasfile, sizeof aliasfile); #endif +#ifdef _LIBC /* Note the file is opened with cancellation in the I/O functions disabled. */ - fp = fopen (full_fname, "rce"); + fp = fopen (relocate (full_fname), "rce"); +#else + fp = fopen (relocate (full_fname), "r"); +#endif freea (full_fname); if (fp == NULL) return 0; @@ -274,9 +289,6 @@ read_alias_file (fname, fname_len) if (cp[0] != '\0') { - size_t alias_len; - size_t value_len; - value = cp++; while (cp[0] != '\0' && !isspace ((unsigned char) cp[0])) ++cp; @@ -292,48 +304,62 @@ read_alias_file (fname, fname_len) else if (cp[0] != '\0') *cp++ = '\0'; - if (nmap >= maxmap) - if (__glibc_unlikely (extend_alias_table ())) - goto out; +#ifdef IN_LIBGLOCALE + /* glibc's locale.alias contains entries for ja_JP and ko_KR + that make it impossible to use a Japanese or Korean UTF-8 + locale under the name "ja_JP" or "ko_KR". Ignore these + entries. */ + if (strchr (alias, '_') == NULL) +#endif + { + size_t alias_len; + size_t value_len; - alias_len = strlen (alias) + 1; - value_len = strlen (value) + 1; + if (nmap >= maxmap) + if (__builtin_expect (extend_alias_table (), 0)) + goto out; - if (string_space_act + alias_len + value_len > string_space_max) - { - /* Increase size of memory pool. */ - size_t new_size = (string_space_max - + (alias_len + value_len > 1024 - ? alias_len + value_len : 1024)); - char *new_pool = (char *) realloc (string_space, new_size); - if (new_pool == NULL) - goto out; - - if (__glibc_unlikely (string_space != new_pool)) - { - size_t i; + alias_len = strlen (alias) + 1; + value_len = strlen (value) + 1; - for (i = 0; i < nmap; i++) + if (string_space_act + alias_len + value_len > string_space_max) + { + /* Increase size of memory pool. */ + size_t new_size = (string_space_max + + (alias_len + value_len > 1024 + ? alias_len + value_len : 1024)); + char *new_pool = (char *) realloc (string_space, new_size); + if (new_pool == NULL) + goto out; + + if (__builtin_expect (string_space != new_pool, 0)) { - map[i].alias += new_pool - string_space; - map[i].value += new_pool - string_space; + size_t i; + + for (i = 0; i < nmap; i++) + { + map[i].alias += new_pool - string_space; + map[i].value += new_pool - string_space; + } } - } - string_space = new_pool; - string_space_max = new_size; - } + string_space = new_pool; + string_space_max = new_size; + } - map[nmap].alias = memcpy (&string_space[string_space_act], - alias, alias_len); - string_space_act += 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); - string_space_act += value_len; + map[nmap].value = + (const char *) memcpy (&string_space[string_space_act], + value, value_len); + string_space_act += value_len; - ++nmap; - ++added; + ++nmap; + ++added; + } } } @@ -348,14 +374,14 @@ read_alias_file (fname, fname_len) while (strchr (buf, '\n') == NULL); } -out: + out: /* Should we test for ferror()? I think we have to silently ignore errors. --drepper */ fclose (fp); if (added > 0) qsort (map, nmap, sizeof (struct alias_map), - (int (*) PARAMS ((const void *, const void *))) alias_compare); + (int (*) (const void *, const void *)) alias_compare); return added; } @@ -381,9 +407,7 @@ extend_alias_table (void) static int -alias_compare (map1, map2) - const struct alias_map *map1; - const struct alias_map *map2; +alias_compare (const struct alias_map *map1, const struct alias_map *map2) { #if defined _LIBC || defined HAVE_STRCASECMP return strcasecmp (map1->alias, map2->alias); diff --git a/intl/ngettext.c b/intl/ngettext.c index 7bf8e21..7fe7e7f 100644 --- a/intl/ngettext.c +++ b/intl/ngettext.c @@ -1,20 +1,18 @@ /* Implementation of ngettext(3) function. Copyright (C) 1995-2014 Free Software Foundation, Inc. - This file is part of the GNU C Library. - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. - The GNU C Library is distributed in the hope that it will be useful, + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ #ifdef HAVE_CONFIG_H # include @@ -54,10 +52,7 @@ LC_MESSAGES locale. If not found, returns MSGID itself (the default text). */ char * -NGETTEXT (msgid1, msgid2, n) - const char *msgid1; - const char *msgid2; - unsigned long int n; +NGETTEXT (const char *msgid1, const char *msgid2, unsigned long int n) { return DCNGETTEXT (NULL, msgid1, msgid2, n, LC_MESSAGES); } diff --git a/intl/plural-eval.c b/intl/plural-eval.c deleted file mode 100644 index 6fc2460..0000000 --- a/intl/plural-eval.c +++ /dev/null @@ -1,100 +0,0 @@ -/* Plural expression evaluation. - Copyright (C) 2000-2014 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -static unsigned long int plural_eval (const struct expression *pexp, - unsigned long int n) - internal_function; - -static unsigned long int -internal_function -plural_eval (pexp, n) - const struct expression *pexp; - unsigned long int n; -{ - switch (pexp->nargs) - { - case 0: - switch (pexp->operation) - { - case var: - return n; - case num: - return pexp->val.num; - default: - break; - } - /* NOTREACHED */ - break; - case 1: - { - /* pexp->operation must be lnot. */ - unsigned long int arg = plural_eval (pexp->val.args[0], n); - return ! arg; - } - case 2: - { - unsigned long int leftarg = plural_eval (pexp->val.args[0], n); - if (pexp->operation == lor) - return leftarg || plural_eval (pexp->val.args[1], n); - else if (pexp->operation == land) - return leftarg && plural_eval (pexp->val.args[1], n); - else - { - unsigned long int rightarg = plural_eval (pexp->val.args[1], n); - - switch (pexp->operation) - { - case mult: - return leftarg * rightarg; - case divide: - return leftarg / rightarg; - case module: - return leftarg % rightarg; - case plus: - return leftarg + rightarg; - case minus: - return leftarg - rightarg; - case less_than: - return leftarg < rightarg; - case greater_than: - return leftarg > rightarg; - case less_or_equal: - return leftarg <= rightarg; - case greater_or_equal: - return leftarg >= rightarg; - case equal: - return leftarg == rightarg; - case not_equal: - return leftarg != rightarg; - default: - break; - } - } - /* NOTREACHED */ - break; - } - case 3: - { - /* pexp->operation must be qmop. */ - unsigned long int boolarg = plural_eval (pexp->val.args[0], n); - return plural_eval (pexp->val.args[boolarg ? 1 : 2], n); - } - } - /* NOTREACHED */ - return 0; -} diff --git a/intl/plural-exp.c b/intl/plural-exp.c index 9a536c7..97cd93a 100644 --- a/intl/plural-exp.c +++ b/intl/plural-exp.c @@ -1,21 +1,19 @@ /* Expression parsing for plural form selection. Copyright (C) 2000-2014 Free Software Foundation, Inc. Written by Ulrich Drepper , 2000. - This file is part of the GNU C Library. - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. - The GNU C Library is distributed in the hope that it will be useful, + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ #ifdef HAVE_CONFIG_H # include @@ -27,7 +25,8 @@ #include "plural-exp.h" -#if (defined __GNUC__ && !defined __APPLE_CC__) \ +#if (defined __GNUC__ && !(defined __APPLE_CC_ && __APPLE_CC__ > 1) && \ + !defined __cplusplus) \ || (defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L) /* These structs are the constant expression for the germanic plural @@ -96,10 +95,9 @@ init_germanic_plural (void) void internal_function -EXTRACT_PLURAL_EXPRESSION (nullentry, pluralp, npluralsp) - const char *nullentry; - const struct expression **pluralp; - unsigned long int *npluralsp; +EXTRACT_PLURAL_EXPRESSION (const char *nullentry, + const struct expression **pluralp, + unsigned long int *npluralsp) { if (nullentry != NULL) { diff --git a/intl/plural-exp.h b/intl/plural-exp.h index 9ec8901..beaa326 100644 --- a/intl/plural-exp.h +++ b/intl/plural-exp.h @@ -1,33 +1,23 @@ /* Expression parsing and evaluation for plural form selection. Copyright (C) 2000-2014 Free Software Foundation, Inc. Written by Ulrich Drepper , 2000. - This file is part of the GNU C Library. - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. - The GNU C Library is distributed in the hope that it will be useful, + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ #ifndef _PLURAL_EXP_H #define _PLURAL_EXP_H -#ifndef PARAMS -# if __STDC__ || defined __GNUC__ || defined __SUNPRO_C || defined __cplusplus || __PROTOTYPES -# define PARAMS(args) args -# else -# define PARAMS(args) () -# endif -#endif - #ifndef internal_function # define internal_function #endif @@ -36,36 +26,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'. */ @@ -109,17 +105,23 @@ struct parse_args # define EXTRACT_PLURAL_EXPRESSION extract_plural_expression #endif -extern void FREE_EXPRESSION PARAMS ((struct expression *exp)) +extern void FREE_EXPRESSION (struct expression *exp) internal_function; -extern int PLURAL_PARSE PARAMS ((void *arg)); +extern int PLURAL_PARSE (struct parse_args *arg); extern const struct expression GERMANIC_PLURAL attribute_hidden; -extern void EXTRACT_PLURAL_EXPRESSION PARAMS - ((const char *nullentry, const struct expression **pluralp, - unsigned long int *npluralsp)) internal_function; +extern void EXTRACT_PLURAL_EXPRESSION (const char *nullentry, + 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 (const struct expression *pexp, + unsigned long int n); +#endif + -#if !defined (_LIBC) && !defined (IN_LIBINTL) -extern unsigned long int plural_eval PARAMS ((const struct expression *pexp, - unsigned long int n)); +#ifdef __cplusplus +} #endif #endif /* _PLURAL_EXP_H */ diff --git a/intl/plural.c b/intl/plural.c index 1bac3c0..61146d8 100644 --- a/intl/plural.c +++ b/intl/plural.c @@ -1,19 +1,19 @@ /* A Bison parser, made by GNU Bison 2.7. */ /* Bison implementation for Yacc-like parsers in C - + Copyright (C) 1984, 1989-1990, 2000-2012 Free Software Foundation, Inc. - + This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program. If not, see . */ @@ -26,7 +26,7 @@ special exception, which will cause the skeleton and the resulting Bison output files to be licensed under the GNU General Public License without this special exception. - + This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ @@ -50,7 +50,7 @@ #define YYSKELETON_NAME "yacc.c" /* Pure parsers. */ -#define YYPURE 1 +#define YYPURE 2 /* Push parsers. */ #define YYPUSH 0 @@ -74,30 +74,30 @@ /* Expression parsing for plural form selection. Copyright (C) 2000-2014 Free Software Foundation, Inc. - This file is part of the GNU C Library. Written by Ulrich Drepper , 2000. - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. - The GNU C Library is distributed in the hope that it will be useful, + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ -/* The bison generated parser uses alloca. AIX 3 forces us to put this - declaration at the beginning of the file. The declaration in bison's - skeleton file comes too late. This must come before - because may include arbitrary system headers. */ +/* For bison < 2.0, the bison generated parser uses alloca. AIX 3 forces us + to put this declaration at the beginning of the file. The declaration in + bison's skeleton file comes too late. This must come before + because may include arbitrary system headers. + This can go away once the AM_INTL_SUBDIR macro requires bison >= 2.0. */ #if defined _AIX && !defined __GNUC__ #pragma alloca #endif + #ifdef HAVE_CONFIG_H # include #endif @@ -113,11 +113,9 @@ # define __gettextparse PLURAL_PARSE #endif -#define YYLEX_PARAM &((struct parse_args *) arg)->cp -#define YYPARSE_PARAM arg /* Line 371 of yacc.c */ -#line 121 "plural.c" +#line 119 "plural.c" # ifndef YY_NULL # if defined __cplusplus && 201103L <= __cplusplus @@ -173,12 +171,12 @@ typedef union YYSTYPE #line 49 "plural.y" unsigned long int num; - enum operator op; + enum expression_operator op; struct expression *exp; /* Line 387 of yacc.c */ -#line 182 "plural.c" +#line 180 "plural.c" } YYSTYPE; # define YYSTYPE_IS_TRIVIAL 1 # define yystype YYSTYPE /* obsolescent; will be withdrawn */ @@ -194,7 +192,7 @@ int __gettextparse (); #endif #else /* ! YYPARSE_PARAM */ #if defined __STDC__ || defined __cplusplus -int __gettextparse (void); +int __gettextparse (struct parse_args *arg); #else int __gettextparse (); #endif @@ -207,28 +205,14 @@ int __gettextparse (); #line 55 "plural.y" /* Prototypes for local functions. */ -static struct expression *new_exp PARAMS ((int nargs, enum operator op, - struct expression * const *args)); -static inline struct expression *new_exp_0 PARAMS ((enum operator op)); -static inline struct expression *new_exp_1 PARAMS ((enum operator op, - struct expression *right)); -static struct expression *new_exp_2 PARAMS ((enum operator op, - struct expression *left, - struct expression *right)); -static inline struct expression *new_exp_3 PARAMS ((enum operator op, - struct expression *bexp, - struct expression *tbranch, - struct expression *fbranch)); -static int yylex PARAMS ((YYSTYPE *lval, const char **pexp)); -static void yyerror PARAMS ((const char *str)); +static int yylex (YYSTYPE *lval, struct parse_args *arg); +static void yyerror (struct parse_args *arg, const char *str); /* Allocation of expressions. */ static struct expression * -new_exp (nargs, op, args) - 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; @@ -257,16 +241,13 @@ new_exp (nargs, op, args) } static inline struct expression * -new_exp_0 (op) - enum operator op; +new_exp_0 (enum expression_operator op) { return new_exp (0, op, NULL); } static inline struct expression * -new_exp_1 (op, right) - enum operator op; - struct expression *right; +new_exp_1 (enum expression_operator op, struct expression *right) { struct expression *args[1]; @@ -275,10 +256,8 @@ new_exp_1 (op, right) } static struct expression * -new_exp_2 (op, left, right) - 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]; @@ -288,11 +267,8 @@ new_exp_2 (op, left, right) } static inline struct expression * -new_exp_3 (op, bexp, tbranch, fbranch) - enum operator op; - struct expression *bexp; - struct expression *tbranch; - struct expression *fbranch; +new_exp_3 (enum expression_operator op, struct expression *bexp, + struct expression *tbranch, struct expression *fbranch) { struct expression *args[3]; @@ -304,7 +280,7 @@ new_exp_3 (op, bexp, tbranch, fbranch) /* Line 390 of yacc.c */ -#line 308 "plural.c" +#line 284 "plural.c" #ifdef short # undef short @@ -596,8 +572,8 @@ static const yytype_int8 yyrhs[] = /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ static const yytype_uint8 yyrline[] = { - 0, 174, 174, 182, 186, 190, 194, 198, 202, 206, - 210, 214, 218, 223 + 0, 152, 152, 160, 164, 168, 172, 176, 180, 184, + 188, 192, 196, 201 }; #endif @@ -746,7 +722,7 @@ do \ } \ else \ { \ - yyerror (YY_("syntax error: cannot back up")); \ + yyerror (arg, YY_("syntax error: cannot back up")); \ YYERROR; \ } \ while (YYID (0)) @@ -766,7 +742,7 @@ while (YYID (0)) #ifdef YYLEX_PARAM # define YYLEX yylex (&yylval, YYLEX_PARAM) #else -# define YYLEX yylex (&yylval) +# define YYLEX yylex (&yylval, arg) #endif /* Enable debugging if requested. */ @@ -789,7 +765,7 @@ do { \ { \ YYFPRINTF (stderr, "%s ", Title); \ yy_symbol_print (stderr, \ - Type, Value); \ + Type, Value, arg); \ YYFPRINTF (stderr, "\n"); \ } \ } while (YYID (0)) @@ -803,19 +779,21 @@ do { \ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void -yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) +yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, struct parse_args *arg) #else static void -yy_symbol_value_print (yyoutput, yytype, yyvaluep) +yy_symbol_value_print (yyoutput, yytype, yyvaluep, arg) FILE *yyoutput; int yytype; YYSTYPE const * const yyvaluep; + struct parse_args *arg; #endif { FILE *yyo = yyoutput; YYUSE (yyo); if (!yyvaluep) return; + YYUSE (arg); # ifdef YYPRINT if (yytype < YYNTOKENS) YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); @@ -837,13 +815,14 @@ yy_symbol_value_print (yyoutput, yytype, yyvaluep) #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void -yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) +yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, struct parse_args *arg) #else static void -yy_symbol_print (yyoutput, yytype, yyvaluep) +yy_symbol_print (yyoutput, yytype, yyvaluep, arg) FILE *yyoutput; int yytype; YYSTYPE const * const yyvaluep; + struct parse_args *arg; #endif { if (yytype < YYNTOKENS) @@ -851,7 +830,7 @@ yy_symbol_print (yyoutput, yytype, yyvaluep) else YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); - yy_symbol_value_print (yyoutput, yytype, yyvaluep); + yy_symbol_value_print (yyoutput, yytype, yyvaluep, arg); YYFPRINTF (yyoutput, ")"); } @@ -894,12 +873,13 @@ do { \ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void -yy_reduce_print (YYSTYPE *yyvsp, int yyrule) +yy_reduce_print (YYSTYPE *yyvsp, int yyrule, struct parse_args *arg) #else static void -yy_reduce_print (yyvsp, yyrule) +yy_reduce_print (yyvsp, yyrule, arg) YYSTYPE *yyvsp; int yyrule; + struct parse_args *arg; #endif { int yynrhs = yyr2[yyrule]; @@ -913,7 +893,7 @@ yy_reduce_print (yyvsp, yyrule) YYFPRINTF (stderr, " $%d = ", yyi + 1); yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], &(yyvsp[(yyi + 1) - (yynrhs)]) - ); + , arg); YYFPRINTF (stderr, "\n"); } } @@ -921,7 +901,7 @@ yy_reduce_print (yyvsp, yyrule) # define YY_REDUCE_PRINT(Rule) \ do { \ if (yydebug) \ - yy_reduce_print (yyvsp, Rule); \ + yy_reduce_print (yyvsp, Rule, arg); \ } while (YYID (0)) /* Nonzero means print parse trace. It is left uninitialized so that @@ -1201,16 +1181,18 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void -yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep) +yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, struct parse_args *arg) #else static void -yydestruct (yymsg, yytype, yyvaluep) +yydestruct (yymsg, yytype, yyvaluep, arg) const char *yymsg; int yytype; YYSTYPE *yyvaluep; + struct parse_args *arg; #endif { YYUSE (yyvaluep); + YYUSE (arg); if (!yymsg) yymsg = "Deleting"; @@ -1245,11 +1227,11 @@ yyparse (YYPARSE_PARAM) #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) int -yyparse (void) +yyparse (struct parse_args *arg) #else int -yyparse () - +yyparse (arg) + struct parse_args *arg; #endif #endif { @@ -1519,17 +1501,17 @@ yyreduce: { case 2: /* Line 1792 of yacc.c */ -#line 175 "plural.y" +#line 153 "plural.y" { if ((yyvsp[(1) - (1)].exp) == NULL) YYABORT; - ((struct parse_args *) arg)->res = (yyvsp[(1) - (1)].exp); + arg->res = (yyvsp[(1) - (1)].exp); } break; case 3: /* Line 1792 of yacc.c */ -#line 183 "plural.y" +#line 161 "plural.y" { (yyval.exp) = new_exp_3 (qmop, (yyvsp[(1) - (5)].exp), (yyvsp[(3) - (5)].exp), (yyvsp[(5) - (5)].exp)); } @@ -1537,7 +1519,7 @@ yyreduce: case 4: /* Line 1792 of yacc.c */ -#line 187 "plural.y" +#line 165 "plural.y" { (yyval.exp) = new_exp_2 (lor, (yyvsp[(1) - (3)].exp), (yyvsp[(3) - (3)].exp)); } @@ -1545,7 +1527,7 @@ yyreduce: case 5: /* Line 1792 of yacc.c */ -#line 191 "plural.y" +#line 169 "plural.y" { (yyval.exp) = new_exp_2 (land, (yyvsp[(1) - (3)].exp), (yyvsp[(3) - (3)].exp)); } @@ -1553,7 +1535,7 @@ yyreduce: case 6: /* Line 1792 of yacc.c */ -#line 195 "plural.y" +#line 173 "plural.y" { (yyval.exp) = new_exp_2 ((yyvsp[(2) - (3)].op), (yyvsp[(1) - (3)].exp), (yyvsp[(3) - (3)].exp)); } @@ -1561,7 +1543,7 @@ yyreduce: case 7: /* Line 1792 of yacc.c */ -#line 199 "plural.y" +#line 177 "plural.y" { (yyval.exp) = new_exp_2 ((yyvsp[(2) - (3)].op), (yyvsp[(1) - (3)].exp), (yyvsp[(3) - (3)].exp)); } @@ -1569,7 +1551,7 @@ yyreduce: case 8: /* Line 1792 of yacc.c */ -#line 203 "plural.y" +#line 181 "plural.y" { (yyval.exp) = new_exp_2 ((yyvsp[(2) - (3)].op), (yyvsp[(1) - (3)].exp), (yyvsp[(3) - (3)].exp)); } @@ -1577,7 +1559,7 @@ yyreduce: case 9: /* Line 1792 of yacc.c */ -#line 207 "plural.y" +#line 185 "plural.y" { (yyval.exp) = new_exp_2 ((yyvsp[(2) - (3)].op), (yyvsp[(1) - (3)].exp), (yyvsp[(3) - (3)].exp)); } @@ -1585,7 +1567,7 @@ yyreduce: case 10: /* Line 1792 of yacc.c */ -#line 211 "plural.y" +#line 189 "plural.y" { (yyval.exp) = new_exp_1 (lnot, (yyvsp[(2) - (2)].exp)); } @@ -1593,7 +1575,7 @@ yyreduce: case 11: /* Line 1792 of yacc.c */ -#line 215 "plural.y" +#line 193 "plural.y" { (yyval.exp) = new_exp_0 (var); } @@ -1601,7 +1583,7 @@ yyreduce: case 12: /* Line 1792 of yacc.c */ -#line 219 "plural.y" +#line 197 "plural.y" { if (((yyval.exp) = new_exp_0 (num)) != NULL) (yyval.exp)->val.num = (yyvsp[(1) - (1)].num); @@ -1610,7 +1592,7 @@ yyreduce: case 13: /* Line 1792 of yacc.c */ -#line 224 "plural.y" +#line 202 "plural.y" { (yyval.exp) = (yyvsp[(2) - (3)].exp); } @@ -1618,7 +1600,7 @@ yyreduce: /* Line 1792 of yacc.c */ -#line 1622 "plural.c" +#line 1604 "plural.c" default: break; } /* User semantic actions sometimes alter yychar, and that requires @@ -1668,7 +1650,7 @@ yyerrlab: { ++yynerrs; #if ! YYERROR_VERBOSE - yyerror (YY_("syntax error")); + yyerror (arg, YY_("syntax error")); #else # define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \ yyssp, yytoken) @@ -1695,7 +1677,7 @@ yyerrlab: yymsgp = yymsg; } } - yyerror (yymsgp); + yyerror (arg, yymsgp); if (yysyntax_error_status == 2) goto yyexhaustedlab; } @@ -1719,7 +1701,7 @@ yyerrlab: else { yydestruct ("Error: discarding", - yytoken, &yylval); + yytoken, &yylval, arg); yychar = YYEMPTY; } } @@ -1775,7 +1757,7 @@ yyerrlab1: yydestruct ("Error: popping", - yystos[yystate], yyvsp); + yystos[yystate], yyvsp, arg); YYPOPSTACK (1); yystate = *yyssp; YY_STACK_PRINT (yyss, yyssp); @@ -1812,7 +1794,7 @@ yyabortlab: | yyexhaustedlab -- memory exhaustion comes here. | `-------------------------------------------------*/ yyexhaustedlab: - yyerror (YY_("memory exhausted")); + yyerror (arg, YY_("memory exhausted")); yyresult = 2; /* Fall through. */ #endif @@ -1824,7 +1806,7 @@ yyreturn: user semantic actions for why this is necessary. */ yytoken = YYTRANSLATE (yychar); yydestruct ("Cleanup: discarding lookahead", - yytoken, &yylval); + yytoken, &yylval, arg); } /* Do not reclaim the symbols of the rule which action triggered this YYABORT or YYACCEPT. */ @@ -1833,7 +1815,7 @@ yyreturn: while (yyssp != yyss) { yydestruct ("Cleanup: popping", - yystos[*yyssp], yyvsp); + yystos[*yyssp], yyvsp, arg); YYPOPSTACK (1); } #ifndef yyoverflow @@ -1850,13 +1832,12 @@ yyreturn: /* Line 2055 of yacc.c */ -#line 229 "plural.y" +#line 207 "plural.y" void internal_function -FREE_EXPRESSION (exp) - struct expression *exp; +FREE_EXPRESSION (struct expression *exp) { if (exp == NULL) return; @@ -1882,18 +1863,16 @@ FREE_EXPRESSION (exp) static int -yylex (lval, pexp) - YYSTYPE *lval; - const char **pexp; +yylex (YYSTYPE *lval, struct parse_args *arg) { - const char *exp = *pexp; + const char *exp = arg->cp; int result; while (1) { if (exp[0] == '\0') { - *pexp = exp; + arg->cp = exp; return YYEOF; } @@ -2020,15 +1999,14 @@ yylex (lval, pexp) break; } - *pexp = exp; + arg->cp = exp; return result; } static void -yyerror (str) - const char *str; +yyerror (struct parse_args *arg, const char *str) { /* Do nothing. We don't print error messages here. */ } diff --git a/intl/plural.y b/intl/plural.y index 105fe0d..d74de07 100644 --- a/intl/plural.y +++ b/intl/plural.y @@ -1,30 +1,30 @@ %{ /* Expression parsing for plural form selection. Copyright (C) 2000-2014 Free Software Foundation, Inc. - This file is part of the GNU C Library. Written by Ulrich Drepper , 2000. - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. - The GNU C Library is distributed in the hope that it will be useful, + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ -/* The bison generated parser uses alloca. AIX 3 forces us to put this - declaration at the beginning of the file. The declaration in bison's - skeleton file comes too late. This must come before - because may include arbitrary system headers. */ +/* For bison < 2.0, the bison generated parser uses alloca. AIX 3 forces us + to put this declaration at the beginning of the file. The declaration in + bison's skeleton file comes too late. This must come before + because may include arbitrary system headers. + This can go away once the AM_INTL_SUBDIR macro requires bison >= 2.0. */ #if defined _AIX && !defined __GNUC__ #pragma alloca #endif + #ifdef HAVE_CONFIG_H # include #endif @@ -40,42 +40,28 @@ # define __gettextparse PLURAL_PARSE #endif -#define YYLEX_PARAM &((struct parse_args *) arg)->cp -#define YYPARSE_PARAM arg %} -%pure_parser +%parse-param {struct parse_args *arg} +%lex-param {struct parse_args *arg} +%define api.pure full %expect 7 %union { unsigned long int num; - enum operator op; + enum expression_operator op; struct expression *exp; } %{ /* Prototypes for local functions. */ -static struct expression *new_exp PARAMS ((int nargs, enum operator op, - struct expression * const *args)); -static inline struct expression *new_exp_0 PARAMS ((enum operator op)); -static inline struct expression *new_exp_1 PARAMS ((enum operator op, - struct expression *right)); -static struct expression *new_exp_2 PARAMS ((enum operator op, - struct expression *left, - struct expression *right)); -static inline struct expression *new_exp_3 PARAMS ((enum operator op, - struct expression *bexp, - struct expression *tbranch, - struct expression *fbranch)); -static int yylex PARAMS ((YYSTYPE *lval, const char **pexp)); -static void yyerror PARAMS ((const char *str)); +static int yylex (YYSTYPE *lval, struct parse_args *arg); +static void yyerror (struct parse_args *arg, const char *str); /* Allocation of expressions. */ static struct expression * -new_exp (nargs, op, args) - 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; @@ -104,16 +90,13 @@ new_exp (nargs, op, args) } static inline struct expression * -new_exp_0 (op) - enum operator op; +new_exp_0 (enum expression_operator op) { return new_exp (0, op, NULL); } static inline struct expression * -new_exp_1 (op, right) - enum operator op; - struct expression *right; +new_exp_1 (enum expression_operator op, struct expression *right) { struct expression *args[1]; @@ -122,10 +105,8 @@ new_exp_1 (op, right) } static struct expression * -new_exp_2 (op, left, right) - 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]; @@ -135,11 +116,8 @@ new_exp_2 (op, left, right) } static inline struct expression * -new_exp_3 (op, bexp, tbranch, fbranch) - enum operator op; - struct expression *bexp; - struct expression *tbranch; - struct expression *fbranch; +new_exp_3 (enum expression_operator op, struct expression *bexp, + struct expression *tbranch, struct expression *fbranch) { struct expression *args[3]; @@ -175,7 +153,7 @@ start: exp { if ($1 == NULL) YYABORT; - ((struct parse_args *) arg)->res = $1; + arg->res = $1; } ; @@ -230,8 +208,7 @@ exp: exp '?' exp ':' exp void internal_function -FREE_EXPRESSION (exp) - struct expression *exp; +FREE_EXPRESSION (struct expression *exp) { if (exp == NULL) return; @@ -257,18 +234,16 @@ FREE_EXPRESSION (exp) static int -yylex (lval, pexp) - YYSTYPE *lval; - const char **pexp; +yylex (YYSTYPE *lval, struct parse_args *arg) { - const char *exp = *pexp; + const char *exp = arg->cp; int result; while (1) { if (exp[0] == '\0') { - *pexp = exp; + arg->cp = exp; return YYEOF; } @@ -395,15 +370,14 @@ yylex (lval, pexp) break; } - *pexp = exp; + arg->cp = exp; return result; } static void -yyerror (str) - const char *str; +yyerror (struct parse_args *arg, const char *str) { /* Do nothing. We don't print error messages here. */ } diff --git a/intl/textdomain.c b/intl/textdomain.c index 3b5a6c1..d1ab52a 100644 --- a/intl/textdomain.c +++ b/intl/textdomain.c @@ -1,20 +1,18 @@ /* Implementation of the textdomain(3) function. Copyright (C) 1995-2014 Free Software Foundation, Inc. - This file is part of the GNU C Library. - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. - The GNU C Library is distributed in the hope that it will be useful, + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ #ifdef HAVE_CONFIG_H # include @@ -23,39 +21,25 @@ #include #include +#include "gettextP.h" #ifdef _LIBC # include #else # include "libgnuintl.h" #endif -#include "gettextP.h" +/* Handle multi-threaded applications. */ #ifdef _LIBC -/* We have to handle multi-threaded applications. */ # include +# define gl_rwlock_define __libc_rwlock_define +# define gl_rwlock_wrlock __libc_rwlock_wrlock +# define gl_rwlock_unlock __libc_rwlock_unlock #else -/* Provide dummy implementation if this is outside glibc. */ -# define __libc_rwlock_define(CLASS, NAME) -# define __libc_rwlock_wrlock(NAME) -# define __libc_rwlock_unlock(NAME) -#endif - -/* The internal variables in the standalone libintl.a must have different - names than the internal variables in GNU libc, otherwise programs - using libintl.a cannot be linked statically. */ -#if !defined _LIBC -# define _nl_default_default_domain libintl_nl_default_default_domain -# define _nl_current_default_domain libintl_nl_current_default_domain +# include "lock.h" #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 @@ -71,14 +55,13 @@ extern const char *_nl_current_default_domain attribute_hidden; #endif /* Lock variable to protect the global data in the gettext implementation. */ -__libc_rwlock_define (extern, _nl_state_lock attribute_hidden) +gl_rwlock_define (extern, _nl_state_lock attribute_hidden) /* Set the current default message catalog to DOMAINNAME. If DOMAINNAME is null, return the current default. If DOMAINNAME is "", reset to the default of "messages". */ char * -TEXTDOMAIN (domainname) - const char *domainname; +TEXTDOMAIN (const char *domainname) { char *new_domain; char *old_domain; @@ -87,7 +70,7 @@ TEXTDOMAIN (domainname) if (domainname == NULL) return (char *) _nl_current_default_domain; - __libc_rwlock_wrlock (_nl_state_lock); + gl_rwlock_wrlock (_nl_state_lock); old_domain = (char *) _nl_current_default_domain; @@ -131,7 +114,7 @@ TEXTDOMAIN (domainname) free (old_domain); } - __libc_rwlock_unlock (_nl_state_lock); + gl_rwlock_unlock (_nl_state_lock); return new_domain; }