Fri May 3 13:32:08 1996 Roland McGrath <roland@delasyd.gnu.ai.mit.edu>
* intl/Makefile (CPPFLAGS): Change $(nlsdir) to $(i18ndir) in LOCALE_ALIAS_PATH. Fri May 3 03:14:02 1996 Ulrich Drepper <drepper@cygnus.com> * intl/Makefile (routines): Add l10nflist and explodename. (distribute): Add loadinfo.h and locale.alias. (install-others): New variable to install locale.alias. * intl/dcgettext.c, intl/finddomain.c, intl/gettextP.h, intl/loadmsgcat.c: Adapt for upcoming gettext-0.10.13. Some code is now shared with the locale implementation. * intl/explodename.c, intl/l10nflist.c, intl/loadinfo.h: New file. Extracted from finddomain.c. This is also used in the locale implementation. * intl/locale.alias: New file. Locale alias database compatible with X Window System's locale alias file. Can now be used in locale and gettext code. * libio/stdio.h: Add prototypes for asprint and vasprintf. * locale/C-collate.c, locale/C-ctype.c, locale/C-messages.c, locale/C-monetary.c, locale/C-numeric.c, locale/C-time.c: Add new field in structure with name of locale ("C" in this case). * locale/Makefile (routines): Add findlocale. * locale/findlocale.c: New file. Instead of trying to load the directly described file we now try to be much smarter when this fails. Use the same code as gettext does. * locale/loadlocale.c, locale/setlocale.c: Rewrite to know about new loading scheme. * locale/localeinfo.h: Adapt prototypes and declarations for new setlocale implementation. Remove definition of u32_t type. We now use u_int32_t from <sys/types.h>. * locale/programs/charset.h (ILLEGAL_CHAR_VALUE): Provide type with constant. * locale/programs/config.h, locale/lc-collate.c, locale/localeinfo.h, locale/programs/ld-collate.c, locale/programs/ld-ctype.c, locale/programs/ld-messages.c, locale/programs/ld-monetary.c, locale/programs/ld-numeric.c, locale/programs/ld-time.c, locale/weight.h, string/strcoll.c: Change to use u_int32_t and u_int16_t. * locale/programs/localedef.c (construct_output_path): Change name of output locale to contain normalized form of the character set portion. * string/Makefile (routines): Add agrz-ctsep and argz-next. (tests): Add tst-strlen. * string/argz-ctsep.c: New file. Implement reverse operation from argz-stringify. * string/argz-next.c: Non-inline version of function from argz.h. * string/argz.h, string/envz.h: Make usable as global header file. * string/envz.c: Fix declarations to use size_t where prototypes say so. * string/tst-strlen.c: New file. Another test for critical situation in strlen implementations. * sysdeps/i386/i586/strlen.S: Fix bug with highest byte in word being zero. * wctype/test_wctype.c: Fix controlling comparison after change to 32 bit character class array. Fri May 3 12:53:12 1996 Roland McGrath <roland@delasyd.gnu.ai.mit.edu> * sysdeps/unix/sysv/linux/sys/socket.h: Remove spurious doubled line. Thu May 2 22:50:52 1996 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> * sysdeps/unix/sysv/linux/getpriority.c: New file. * sysdeps/unix/sysv/linux/syscalls.list: Add s_getpriority. Thu May 2 22:41:31 1996 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> * sysdeps/unix/sysv/linux/m68k/fpu_control.h (_FPU_DEFAULT): Disable all exceptions. Thu May 2 22:33:14 1996 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> * sysdeps/m68k/fpu/e_acos.c, sysdeps/m68k/fpu/e_acosf.c, sysdeps/m68k/fpu/e_fmod.c, sysdeps/m68k/fpu/e_fmodf.c, sysdeps/m68k/fpu/isinfl.c, sysdeps/m68k/fpu/isnanl.c, sysdeps/m68k/fpu/s_atan.c, sysdeps/m68k/fpu/s_atanf.c, sysdeps/m68k/fpu/s_frexp.c, sysdeps/m68k/fpu/s_frexpf.c, sysdeps/m68k/fpu/s_ilogb.c, sysdeps/m68k/fpu/s_ilogbf.c, sysdeps/m68k/fpu/s_isinf.c, sysdeps/m68k/fpu/s_isinff.c, sysdeps/m68k/fpu/s_ldexp.c, sysdeps/m68k/fpu/s_ldexpf.c, sysdeps/m68k/fpu/s_modf.c, sysdeps/m68k/fpu/s_modff.c: Don't define __NO_MATH_INLINES, which is already defined on command line. Thu May 2 22:18:28 1996 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> * sysdeps/libm-ieee754/e_j0f.c (__ieee754_j0f, __ieee754_y0f): Replace 0x80000000 by 0x48000000. * sysdeps/libm-ieee754/e_j1f.c (__ieee754_j1f): Likewise. Thu May 2 21:30:33 1996 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> * sunrpc/svc_simple.c: Make global variable pl local to registerrpc. Thu May 2 00:24:04 1996 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> * time/Makefile (tz-cflags): New variable. (CFLAGS-tzfile.c): New variable. (CFLAGS-zic.c): Add $(tz-cflags). (tz-cc): Remove variable. ($(objpfx)tzfile.o, $(objpfx)zic.o): Remove targets. * sysdeps/mach/hurd/getcwd.c: Jump out of both loops when we find a name, instead of checking for reaching end of buffer, which happens when the match is the last entry in the buffer.
This commit is contained in:
parent
9e72046871
commit
7a12c6bba7
129
ChangeLog
129
ChangeLog
@ -1,5 +1,134 @@
|
||||
Fri May 3 13:32:08 1996 Roland McGrath <roland@delasyd.gnu.ai.mit.edu>
|
||||
|
||||
* intl/Makefile (CPPFLAGS): Change $(nlsdir) to $(i18ndir) in
|
||||
LOCALE_ALIAS_PATH.
|
||||
|
||||
Fri May 3 03:14:02 1996 Ulrich Drepper <drepper@cygnus.com>
|
||||
|
||||
* intl/Makefile (routines): Add l10nflist and explodename.
|
||||
(distribute): Add loadinfo.h and locale.alias.
|
||||
(install-others): New variable to install locale.alias.
|
||||
|
||||
* intl/dcgettext.c, intl/finddomain.c, intl/gettextP.h,
|
||||
intl/loadmsgcat.c: Adapt for upcoming gettext-0.10.13. Some code
|
||||
is now shared with the locale implementation.
|
||||
|
||||
* intl/explodename.c, intl/l10nflist.c, intl/loadinfo.h: New file.
|
||||
Extracted from finddomain.c. This is also used in the locale
|
||||
implementation.
|
||||
|
||||
* intl/locale.alias: New file. Locale alias database compatible
|
||||
with X Window System's locale alias file. Can now be used in
|
||||
locale and gettext code.
|
||||
|
||||
* libio/stdio.h: Add prototypes for asprint and vasprintf.
|
||||
|
||||
* locale/C-collate.c, locale/C-ctype.c, locale/C-messages.c,
|
||||
locale/C-monetary.c, locale/C-numeric.c, locale/C-time.c: Add new
|
||||
field in structure with name of locale ("C" in this case).
|
||||
|
||||
* locale/Makefile (routines): Add findlocale.
|
||||
|
||||
* locale/findlocale.c: New file. Instead of trying to load the
|
||||
directly described file we now try to be much smarter when this
|
||||
fails. Use the same code as gettext does.
|
||||
|
||||
* locale/loadlocale.c, locale/setlocale.c: Rewrite to know about
|
||||
new loading scheme.
|
||||
|
||||
* locale/localeinfo.h: Adapt prototypes and declarations for new
|
||||
setlocale implementation. Remove definition of u32_t type. We
|
||||
now use u_int32_t from <sys/types.h>.
|
||||
|
||||
* locale/programs/charset.h (ILLEGAL_CHAR_VALUE): Provide type
|
||||
with constant.
|
||||
|
||||
* locale/programs/config.h, locale/lc-collate.c,
|
||||
locale/localeinfo.h, locale/programs/ld-collate.c,
|
||||
locale/programs/ld-ctype.c, locale/programs/ld-messages.c,
|
||||
locale/programs/ld-monetary.c, locale/programs/ld-numeric.c,
|
||||
locale/programs/ld-time.c, locale/weight.h, string/strcoll.c:
|
||||
Change to use u_int32_t and u_int16_t.
|
||||
|
||||
* locale/programs/localedef.c (construct_output_path): Change name
|
||||
of output locale to contain normalized form of the character set
|
||||
portion.
|
||||
|
||||
* string/Makefile (routines): Add agrz-ctsep and argz-next.
|
||||
(tests): Add tst-strlen.
|
||||
|
||||
* string/argz-ctsep.c: New file. Implement reverse operation
|
||||
from argz-stringify.
|
||||
|
||||
* string/argz-next.c: Non-inline version of function from argz.h.
|
||||
|
||||
* string/argz.h, string/envz.h: Make usable as global header file.
|
||||
|
||||
* string/envz.c: Fix declarations to use size_t where prototypes
|
||||
say so.
|
||||
|
||||
* string/tst-strlen.c: New file. Another test for critical
|
||||
situation in strlen implementations.
|
||||
|
||||
* sysdeps/i386/i586/strlen.S: Fix bug with highest byte in word
|
||||
being zero.
|
||||
|
||||
* wctype/test_wctype.c: Fix controlling comparison after change to
|
||||
32 bit character class array.
|
||||
|
||||
Fri May 3 12:53:12 1996 Roland McGrath <roland@delasyd.gnu.ai.mit.edu>
|
||||
|
||||
* sysdeps/unix/sysv/linux/sys/socket.h: Remove spurious doubled line.
|
||||
|
||||
Thu May 2 22:50:52 1996 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
|
||||
|
||||
* sysdeps/unix/sysv/linux/getpriority.c: New file.
|
||||
* sysdeps/unix/sysv/linux/syscalls.list: Add s_getpriority.
|
||||
|
||||
Thu May 2 22:41:31 1996 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
|
||||
|
||||
* sysdeps/unix/sysv/linux/m68k/fpu_control.h (_FPU_DEFAULT):
|
||||
Disable all exceptions.
|
||||
|
||||
Thu May 2 22:33:14 1996 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
|
||||
|
||||
* sysdeps/m68k/fpu/e_acos.c, sysdeps/m68k/fpu/e_acosf.c,
|
||||
sysdeps/m68k/fpu/e_fmod.c, sysdeps/m68k/fpu/e_fmodf.c,
|
||||
sysdeps/m68k/fpu/isinfl.c, sysdeps/m68k/fpu/isnanl.c,
|
||||
sysdeps/m68k/fpu/s_atan.c, sysdeps/m68k/fpu/s_atanf.c,
|
||||
sysdeps/m68k/fpu/s_frexp.c, sysdeps/m68k/fpu/s_frexpf.c,
|
||||
sysdeps/m68k/fpu/s_ilogb.c, sysdeps/m68k/fpu/s_ilogbf.c,
|
||||
sysdeps/m68k/fpu/s_isinf.c, sysdeps/m68k/fpu/s_isinff.c,
|
||||
sysdeps/m68k/fpu/s_ldexp.c, sysdeps/m68k/fpu/s_ldexpf.c,
|
||||
sysdeps/m68k/fpu/s_modf.c, sysdeps/m68k/fpu/s_modff.c: Don't
|
||||
define __NO_MATH_INLINES, which is already defined on command
|
||||
line.
|
||||
|
||||
Thu May 2 22:18:28 1996 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
|
||||
|
||||
* sysdeps/libm-ieee754/e_j0f.c (__ieee754_j0f, __ieee754_y0f):
|
||||
Replace 0x80000000 by 0x48000000.
|
||||
* sysdeps/libm-ieee754/e_j1f.c (__ieee754_j1f): Likewise.
|
||||
|
||||
Thu May 2 21:30:33 1996 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
|
||||
|
||||
* sunrpc/svc_simple.c: Make global variable pl local to
|
||||
registerrpc.
|
||||
|
||||
Thu May 2 00:24:04 1996 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
|
||||
|
||||
* time/Makefile (tz-cflags): New variable.
|
||||
(CFLAGS-tzfile.c): New variable.
|
||||
(CFLAGS-zic.c): Add $(tz-cflags).
|
||||
(tz-cc): Remove variable.
|
||||
($(objpfx)tzfile.o, $(objpfx)zic.o): Remove targets.
|
||||
|
||||
Wed May 1 09:10:04 1996 Roland McGrath <roland@delasyd.gnu.ai.mit.edu>
|
||||
|
||||
* sysdeps/mach/hurd/getcwd.c: Jump out of both loops when we find a
|
||||
name, instead of checking for reaching end of buffer, which happens
|
||||
when the match is the last entry in the buffer.
|
||||
|
||||
* time/strftime.c: Use canonical autoconf nugget for time.h+sys/time.h
|
||||
include.
|
||||
|
||||
|
@ -21,19 +21,26 @@
|
||||
subdir = intl
|
||||
headers = libintl.h
|
||||
routines = bindtextdom dcgettext dgettext gettext \
|
||||
finddomain loadmsgcat localealias textdomain
|
||||
distribute = gettext.h gettextP.h hash-string.h
|
||||
finddomain loadmsgcat localealias textdomain \
|
||||
l10nflist explodename
|
||||
distribute = gettext.h gettextP.h hash-string.h loadinfo.h locale.alias
|
||||
|
||||
install-others = $(localedir)/locale.alias
|
||||
|
||||
include ../Rules
|
||||
|
||||
CPPFLAGS += -D'GNULOCALEDIR="$(localedir)"' \
|
||||
-D'LOCALE_ALIAS_PATH="$(localedir):$(nlsdir)"'
|
||||
-D'LOCALE_ALIAS_PATH="$(localedir):$(i18ndir)"'
|
||||
|
||||
$(localedir)/locale.alias: locale.alias
|
||||
$(do-install)
|
||||
|
||||
ifdef gettext-srcdir
|
||||
|
||||
%.h:: ../gpl2lgpl.sed $(gettext-srcdir)/intl/%.glibc; $(copysrc)
|
||||
%.c:: ../gpl2lgpl.sed $(gettext-srcdir)/intl/%.c; $(copysrc)
|
||||
%.h:: ../gpl2lgpl.sed $(gettext-srcdir)/intl/%.h; $(copysrc)
|
||||
locale.alias:: ../gpl2lgpl.sed $(gettext-srcdir)/misc/locale.alias; $(copysrc)
|
||||
|
||||
define copysrc
|
||||
sed -f $^ > $@.new
|
||||
|
@ -1,8 +1,6 @@
|
||||
/* dcgettext.c -- implementation of the dcgettext(3) function
|
||||
Copyright (C) 1995 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of the GNU C Library. Its master source is NOT part of
|
||||
the C library, however. The master source lives in /gd/gnu/lib.
|
||||
Copyright (C) 1995, 1996 Free Software Foundation, Inc.
|
||||
Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
@ -16,8 +14,8 @@ Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If
|
||||
not, write to the Free Software Foundation, Inc., 675 Mass Ave,
|
||||
Cambridge, MA 02139, USA. */
|
||||
not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
@ -155,7 +153,7 @@ const char _nl_default_dirname[] = GNULOCALEDIR;
|
||||
struct binding *_nl_domain_bindings;
|
||||
|
||||
/* Prototypes for local functions. */
|
||||
static char *find_msg PARAMS ((struct loaded_domain *domain,
|
||||
static char *find_msg PARAMS ((struct loaded_l10nfile *domain_file,
|
||||
const char *msgid));
|
||||
static const char *category_to_name PARAMS ((int category));
|
||||
static const char *guess_category_value PARAMS ((int category,
|
||||
@ -180,7 +178,7 @@ DCGETTEXT (domainname, msgid, category)
|
||||
const char *msgid;
|
||||
int category;
|
||||
{
|
||||
struct loaded_domain *domain;
|
||||
struct loaded_l10nfile *domain;
|
||||
struct binding *binding;
|
||||
const char *categoryname;
|
||||
const char *categoryvalue;
|
||||
@ -355,18 +353,21 @@ weak_alias (__dcgettext, dcgettext);
|
||||
|
||||
|
||||
static char *
|
||||
find_msg (domain, msgid)
|
||||
struct loaded_domain *domain;
|
||||
find_msg (domain_file, msgid)
|
||||
struct loaded_l10nfile *domain_file;
|
||||
const char *msgid;
|
||||
{
|
||||
size_t top, act, bottom;
|
||||
struct loaded_domain *domain;
|
||||
|
||||
if (domain->decided == 0)
|
||||
_nl_load_domain (domain);
|
||||
if (domain_file->decided == 0)
|
||||
_nl_load_domain (domain_file);
|
||||
|
||||
if (domain->data == NULL)
|
||||
if (domain_file->data == NULL)
|
||||
return NULL;
|
||||
|
||||
domain = (struct loaded_domain *) domain_file->data;
|
||||
|
||||
/* Locate the MSGID and its translation. */
|
||||
if (domain->hash_size > 2 && domain->hash_tab != NULL)
|
||||
{
|
||||
@ -439,7 +440,8 @@ find_msg (domain, msgid)
|
||||
|
||||
|
||||
/* Return string representation of locale CATEGORY. */
|
||||
static const char *category_to_name (category)
|
||||
static const char *
|
||||
category_to_name (category)
|
||||
int category;
|
||||
{
|
||||
const char *retval;
|
||||
|
167
intl/explodename.c
Normal file
167
intl/explodename.c
Normal file
@ -0,0 +1,167 @@
|
||||
/* Copyright (C) 1995, 1996 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If
|
||||
not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "loadinfo.h"
|
||||
|
||||
int
|
||||
_nl_explode_name (name, language, modifier, territory, codeset,
|
||||
normalized_codeset, special, sponsor, revision)
|
||||
char *name;
|
||||
const char **language;
|
||||
const char **modifier;
|
||||
const char **territory;
|
||||
const char **codeset;
|
||||
const char **normalized_codeset;
|
||||
const char **special;
|
||||
const char **sponsor;
|
||||
const char **revision;
|
||||
{
|
||||
enum { undecided, xpg, cen } syntax;
|
||||
char *cp;
|
||||
int mask;
|
||||
|
||||
*modifier = NULL;
|
||||
*territory = NULL;
|
||||
*codeset = NULL;
|
||||
*normalized_codeset = NULL;
|
||||
*special = NULL;
|
||||
*sponsor = NULL;
|
||||
*revision = NULL;
|
||||
|
||||
/* 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. */
|
||||
mask = 0;
|
||||
syntax = undecided;
|
||||
*language = cp = name;
|
||||
while (cp[0] != '\0' && cp[0] != '_' && cp[0] != '@'
|
||||
&& cp[0] != '+' && cp[0] != ',')
|
||||
++cp;
|
||||
|
||||
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 = strchr (*language, '\0');
|
||||
else if (cp[0] == '_')
|
||||
{
|
||||
/* Next is the territory. */
|
||||
cp[0] = '\0';
|
||||
*territory = ++cp;
|
||||
|
||||
while (cp[0] != '\0' && cp[0] != '.' && cp[0] != '@'
|
||||
&& cp[0] != '+' && cp[0] != ',' && cp[0] != '_')
|
||||
++cp;
|
||||
|
||||
mask |= TERRITORY;
|
||||
|
||||
if (cp[0] == '.')
|
||||
{
|
||||
/* Next is the codeset. */
|
||||
syntax = xpg;
|
||||
cp[0] = '\0';
|
||||
*codeset = ++cp;
|
||||
|
||||
while (cp[0] != '\0' && cp[0] != '@')
|
||||
++cp;
|
||||
|
||||
mask |= XPG_CODESET;
|
||||
|
||||
if (*codeset != cp && (*codeset)[0] != '\0')
|
||||
{
|
||||
*normalized_codeset = _nl_normalize_codeset (*codeset,
|
||||
cp - *codeset);
|
||||
if (strcmp (*codeset, *normalized_codeset) == 0)
|
||||
free ((char *) *normalized_codeset);
|
||||
else
|
||||
mask |= XPG_NORM_CODESET;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (cp[0] == '@' || (syntax != xpg && cp[0] == '+'))
|
||||
{
|
||||
/* Next is the modifier. */
|
||||
syntax = cp[0] == '@' ? xpg : cen;
|
||||
cp[0] = '\0';
|
||||
*modifier = ++cp;
|
||||
|
||||
while (syntax == cen && cp[0] != '\0' && cp[0] != '+'
|
||||
&& cp[0] != ',' && cp[0] != '_')
|
||||
++cp;
|
||||
|
||||
mask |= XPG_MODIFIER | CEN_AUDIENCE;
|
||||
}
|
||||
|
||||
if (syntax != xpg && (cp[0] == '+' || cp[0] == ',' || cp[0] == '_'))
|
||||
{
|
||||
syntax = cen;
|
||||
|
||||
if (cp[0] == '+')
|
||||
{
|
||||
/* Next is special application (CEN syntax). */
|
||||
cp[0] = '\0';
|
||||
*special = ++cp;
|
||||
|
||||
while (cp[0] != '\0' && cp[0] != ',' && cp[0] != '_')
|
||||
++cp;
|
||||
|
||||
mask |= CEN_SPECIAL;
|
||||
}
|
||||
|
||||
if (cp[0] == ',')
|
||||
{
|
||||
/* Next is sponsor (CEN syntax). */
|
||||
cp[0] = '\0';
|
||||
*sponsor = ++cp;
|
||||
|
||||
while (cp[0] != '\0' && cp[0] != '_')
|
||||
++cp;
|
||||
|
||||
mask |= CEN_SPONSOR;
|
||||
}
|
||||
|
||||
if (cp[0] == '_')
|
||||
{
|
||||
/* Next is revision (CEN syntax). */
|
||||
cp[0] = '\0';
|
||||
*revision = ++cp;
|
||||
|
||||
mask |= CEN_REVISION;
|
||||
}
|
||||
}
|
||||
|
||||
/* For CEN sytnax values it might be important to have the
|
||||
separator character in the file name, not for XPG syntax. */
|
||||
if (syntax == xpg)
|
||||
{
|
||||
if (*territory != NULL && (*territory)[0] == '\0')
|
||||
mask &= ~TERRITORY;
|
||||
|
||||
if (*codeset != NULL && (*codeset)[0] == '\0')
|
||||
mask &= ~XPG_CODESET;
|
||||
|
||||
if (*modifier != NULL && (*modifier)[0] == '\0')
|
||||
mask &= ~XPG_MODIFIER;
|
||||
}
|
||||
|
||||
return mask;
|
||||
}
|
@ -1,9 +1,6 @@
|
||||
/* finddomain.c -- handle list of needed message catalogs
|
||||
Copyright (C) 1995, 1996 Free Software Foundation, Inc.
|
||||
Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
|
||||
|
||||
This file is part of the GNU C Library. Its master source is NOT part of
|
||||
the C library, however. The master source lives in /gd/gnu/lib.
|
||||
Copyright (C) 1995, 1996 Free Software Foundation, Inc.
|
||||
Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
@ -17,8 +14,8 @@ Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If
|
||||
not, write to the Free Software Foundation, Inc., 675 Mass Ave,
|
||||
Cambridge, MA 02139, USA. */
|
||||
not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
@ -71,39 +68,8 @@ void free ();
|
||||
# define stpcpy(dest, src) __stpcpy(dest, src)
|
||||
#endif
|
||||
|
||||
/* Encoding of locale name parts. */
|
||||
#define CEN_REVISION 1
|
||||
#define CEN_SPONSOR 2
|
||||
#define CEN_SPECIAL 4
|
||||
#define XPG_NORM_CODESET 8
|
||||
#define XPG_CODESET 16
|
||||
#define TERRITORY 32
|
||||
#define CEN_AUDIENCE 64
|
||||
#define XPG_MODIFIER 128
|
||||
|
||||
#define CEN_SPECIFIC (CEN_REVISION|CEN_SPONSOR|CEN_SPECIAL|CEN_AUDIENCE)
|
||||
#define XPG_SPECIFIC (XPG_CODESET|XPG_NORM_CODESET|XPG_MODIFIER)
|
||||
|
||||
|
||||
/* List of already loaded domains. */
|
||||
static struct loaded_domain *_nl_loaded_domains;
|
||||
|
||||
/* Prototypes for local functions. */
|
||||
static struct loaded_domain *make_entry_rec PARAMS ((const char *dirname,
|
||||
int mask,
|
||||
const char *language,
|
||||
const char *territory,
|
||||
const char *codeset,
|
||||
const char *normalized_codeset,
|
||||
const char *modifier,
|
||||
const char *special,
|
||||
const char *sponsor,
|
||||
const char *revision,
|
||||
const char *domainname,
|
||||
int do_allocate));
|
||||
|
||||
/* Normalize name of selected codeset. */
|
||||
static const char *normalize_codeset PARAMS ((const char *codeset));
|
||||
static struct loaded_l10nfile *_nl_loaded_domains;
|
||||
|
||||
/* Substitution for systems lacking this function in their C library. */
|
||||
#if !_LIBC && !HAVE_STPCPY
|
||||
@ -115,29 +81,25 @@ static char *stpcpy__ PARAMS ((char *dest, const char *src));
|
||||
/* Return a data structure describing the message catalog described by
|
||||
the DOMAINNAME and CATEGORY parameters with respect to the currently
|
||||
established bindings. */
|
||||
struct loaded_domain *
|
||||
struct loaded_l10nfile *
|
||||
_nl_find_domain (dirname, locale, domainname)
|
||||
const char *dirname;
|
||||
char *locale;
|
||||
const char *domainname;
|
||||
{
|
||||
enum { undecided, xpg, cen } syntax;
|
||||
struct loaded_domain *retval;
|
||||
struct loaded_l10nfile *retval;
|
||||
const char *language;
|
||||
const char *modifier = NULL;
|
||||
const char *territory = NULL;
|
||||
const char *codeset = NULL;
|
||||
const char *normalized_codeset = NULL;
|
||||
const char *special = NULL;
|
||||
const char *sponsor = NULL;
|
||||
const char *revision = NULL;
|
||||
const char *alias_value = NULL;
|
||||
char *cp;
|
||||
const char *modifier;
|
||||
const char *territory;
|
||||
const char *codeset;
|
||||
const char *normalized_codeset;
|
||||
const char *special;
|
||||
const char *sponsor;
|
||||
const char *revision;
|
||||
const char *alias_value;
|
||||
int mask;
|
||||
|
||||
/* CATEGORYVALUE now possibly contains a colon separated list of
|
||||
locales. Each single locale can consist of up to four recognized
|
||||
parts for the XPG syntax:
|
||||
/* LOCALE can consist of up to four recognized parts for the XPG syntax:
|
||||
|
||||
language[_territory[.codeset]][@modifier]
|
||||
|
||||
@ -160,15 +122,16 @@ _nl_find_domain (dirname, locale, domainname)
|
||||
|
||||
/* If we have already tested for this locale entry there has to
|
||||
be one data set in the list of loaded domains. */
|
||||
retval = make_entry_rec (dirname, 0, locale, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, domainname, 0);
|
||||
retval = _nl_make_l10nflist (&_nl_loaded_domains, dirname,
|
||||
strlen (dirname) + 1, 0, locale, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, domainname, 0);
|
||||
if (retval != NULL)
|
||||
{
|
||||
/* We know something about this locale. */
|
||||
int cnt;
|
||||
|
||||
if (retval->decided == 0)
|
||||
_nl_load_domain (retval); /* @@@ */
|
||||
_nl_load_domain (retval);
|
||||
|
||||
if (retval->data != NULL)
|
||||
return retval;
|
||||
@ -181,8 +144,6 @@ _nl_find_domain (dirname, locale, domainname)
|
||||
if (retval->successor[cnt]->data != NULL)
|
||||
break;
|
||||
}
|
||||
|
||||
/* We really found some usable information. */
|
||||
return cnt >= 0 ? retval : NULL;
|
||||
/* NOTREACHED */
|
||||
}
|
||||
@ -204,123 +165,16 @@ _nl_find_domain (dirname, locale, domainname)
|
||||
/* 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. */
|
||||
mask = 0;
|
||||
syntax = undecided;
|
||||
language = cp = locale;
|
||||
while (cp[0] != '\0' && cp[0] != '_' && cp[0] != '@'
|
||||
&& cp[0] != '+' && cp[0] != ',')
|
||||
++cp;
|
||||
|
||||
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 = strchr (language, '\0');
|
||||
else if (cp[0] == '_')
|
||||
{
|
||||
/* Next is the territory. */
|
||||
cp[0] = '\0';
|
||||
territory = ++cp;
|
||||
|
||||
while (cp[0] != '\0' && cp[0] != '.' && cp[0] != '@'
|
||||
&& cp[0] != '+' && cp[0] != ',' && cp[0] != '_')
|
||||
++cp;
|
||||
|
||||
mask |= TERRITORY;
|
||||
|
||||
if (cp[0] == '.')
|
||||
{
|
||||
/* Next is the codeset. */
|
||||
syntax = xpg;
|
||||
cp[0] = '\0';
|
||||
codeset = ++cp;
|
||||
|
||||
while (cp[0] != '\0' && cp[0] != '@')
|
||||
++cp;
|
||||
|
||||
mask |= XPG_CODESET;
|
||||
|
||||
if (codeset != cp && codeset[0] != '\0')
|
||||
{
|
||||
normalized_codeset = normalize_codeset (codeset);
|
||||
if (strcmp (codeset, normalized_codeset) == 0)
|
||||
free ((char *) normalized_codeset);
|
||||
else
|
||||
mask |= XPG_NORM_CODESET;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (cp[0] == '@' || (syntax != xpg && cp[0] == '+'))
|
||||
{
|
||||
/* Next is the modifier. */
|
||||
syntax = cp[0] == '@' ? xpg : cen;
|
||||
cp[0] = '\0';
|
||||
modifier = ++cp;
|
||||
|
||||
while (syntax == cen && cp[0] != '\0' && cp[0] != '+'
|
||||
&& cp[0] != ',' && cp[0] != '_')
|
||||
++cp;
|
||||
|
||||
mask |= XPG_MODIFIER | CEN_AUDIENCE;
|
||||
}
|
||||
|
||||
if (syntax != xpg && (cp[0] == '+' || cp[0] == ',' || cp[0] == '_'))
|
||||
{
|
||||
syntax = cen;
|
||||
|
||||
if (cp[0] == '+')
|
||||
{
|
||||
/* Next is special application (CEN syntax). */
|
||||
cp[0] = '\0';
|
||||
special = ++cp;
|
||||
|
||||
while (cp[0] != '\0' && cp[0] != ',' && cp[0] != '_')
|
||||
++cp;
|
||||
|
||||
mask |= CEN_SPECIAL;
|
||||
}
|
||||
|
||||
if (cp[0] == ',')
|
||||
{
|
||||
/* Next is sponsor (CEN syntax). */
|
||||
cp[0] = '\0';
|
||||
sponsor = ++cp;
|
||||
|
||||
while (cp[0] != '\0' && cp[0] != '_')
|
||||
++cp;
|
||||
|
||||
mask |= CEN_SPONSOR;
|
||||
}
|
||||
|
||||
if (cp[0] == '_')
|
||||
{
|
||||
/* Next is revision (CEN syntax). */
|
||||
cp[0] = '\0';
|
||||
revision = ++cp;
|
||||
|
||||
mask |= CEN_REVISION;
|
||||
}
|
||||
}
|
||||
|
||||
/* For CEN sytnax values it might be important to have the
|
||||
separator character in the file name, not for XPG syntax. */
|
||||
if (syntax == xpg)
|
||||
{
|
||||
if (territory != NULL && territory[0] == '\0')
|
||||
mask &= ~TERRITORY;
|
||||
|
||||
if (codeset != NULL && codeset[0] == '\0')
|
||||
mask &= ~XPG_CODESET;
|
||||
|
||||
if (modifier != NULL && modifier[0] == '\0')
|
||||
mask &= ~XPG_MODIFIER;
|
||||
}
|
||||
mask = _nl_explode_name (locale, &language, &modifier, &territory,
|
||||
&codeset, &normalized_codeset, &special,
|
||||
&sponsor, &revision);
|
||||
|
||||
/* Create all possible locale entries which might be interested in
|
||||
generalzation. */
|
||||
retval = make_entry_rec (dirname, mask, language, territory, codeset,
|
||||
normalized_codeset, modifier, special, sponsor,
|
||||
revision, domainname, 1);
|
||||
retval = _nl_make_l10nflist (&_nl_loaded_domains, dirname,
|
||||
strlen (dirname) + 1, mask, language, territory,
|
||||
codeset, normalized_codeset, modifier, special,
|
||||
sponsor, revision, domainname, 1);
|
||||
if (retval == NULL)
|
||||
/* This means we are out of core. */
|
||||
return NULL;
|
||||
@ -336,12 +190,7 @@ _nl_find_domain (dirname, locale, domainname)
|
||||
_nl_load_domain (retval->successor[cnt]);
|
||||
if (retval->successor[cnt]->data != NULL)
|
||||
break;
|
||||
|
||||
/* Signal that locale is not available. */
|
||||
retval->successor[cnt] = NULL;
|
||||
}
|
||||
if (retval->successor[cnt] == NULL)
|
||||
retval = NULL;
|
||||
}
|
||||
|
||||
/* The room for an alias was dynamically allocated. Free it now. */
|
||||
@ -351,215 +200,6 @@ _nl_find_domain (dirname, locale, domainname)
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
static struct loaded_domain *
|
||||
make_entry_rec (dirname, mask, language, territory, codeset,
|
||||
normalized_codeset, modifier, special, sponsor, revision,
|
||||
domain, do_allocate)
|
||||
const char *dirname;
|
||||
int mask;
|
||||
const char *language;
|
||||
const char *territory;
|
||||
const char *codeset;
|
||||
const char *normalized_codeset;
|
||||
const char *modifier;
|
||||
const char *special;
|
||||
const char *sponsor;
|
||||
const char *revision;
|
||||
const char *domain;
|
||||
int do_allocate;
|
||||
{
|
||||
char *filename = NULL;
|
||||
struct loaded_domain *last = NULL;
|
||||
struct loaded_domain *retval;
|
||||
char *cp;
|
||||
size_t entries;
|
||||
int cnt;
|
||||
|
||||
|
||||
/* Process the current entry described by the MASK only when it is
|
||||
valid. Because the mask can have in the first call bits from
|
||||
both syntaces set this is necessary to prevent constructing
|
||||
illegal local names. */
|
||||
/* FIXME: Rewrite because test is necessary only in first round. */
|
||||
if ((mask & CEN_SPECIFIC) == 0 || (mask & XPG_SPECIFIC) == 0
|
||||
|| ((mask & XPG_CODESET) != 0 && (mask & XPG_NORM_CODESET) != 0))
|
||||
{
|
||||
/* Allocate room for the full file name. */
|
||||
filename = (char *) malloc (strlen (dirname) + 1
|
||||
+ strlen (language)
|
||||
+ ((mask & TERRITORY) != 0
|
||||
? strlen (territory) + 1 : 0)
|
||||
+ ((mask & XPG_CODESET) != 0
|
||||
? strlen (codeset) + 1 : 0)
|
||||
+ ((mask & XPG_NORM_CODESET) != 0
|
||||
? strlen (normalized_codeset) + 1 : 0)
|
||||
+ ((mask & XPG_MODIFIER) != 0 ?
|
||||
strlen (modifier) + 1 : 0)
|
||||
+ ((mask & CEN_SPECIAL) != 0
|
||||
? strlen (special) + 1 : 0)
|
||||
+ ((mask & CEN_SPONSOR) != 0
|
||||
? strlen (sponsor) + 1 : 0)
|
||||
+ ((mask & CEN_REVISION) != 0
|
||||
? strlen (revision) + 1 : 0) + 1
|
||||
+ strlen (domain) + 1);
|
||||
|
||||
if (filename == NULL)
|
||||
return NULL;
|
||||
|
||||
retval = NULL;
|
||||
last = NULL;
|
||||
|
||||
/* Construct file name. */
|
||||
cp = stpcpy (filename, dirname);
|
||||
*cp++ = '/';
|
||||
cp = stpcpy (cp, language);
|
||||
|
||||
if ((mask & TERRITORY) != 0)
|
||||
{
|
||||
*cp++ = '_';
|
||||
cp = stpcpy (cp, territory);
|
||||
}
|
||||
if ((mask & XPG_CODESET) != 0)
|
||||
{
|
||||
*cp++ = '.';
|
||||
cp = stpcpy (cp, codeset);
|
||||
}
|
||||
if ((mask & XPG_NORM_CODESET) != 0)
|
||||
{
|
||||
*cp++ = '.';
|
||||
cp = stpcpy (cp, normalized_codeset);
|
||||
}
|
||||
if ((mask & (XPG_MODIFIER | CEN_AUDIENCE)) != 0)
|
||||
{
|
||||
/* This component can be part of both syntaces but has different
|
||||
leading characters. For CEN we use `+', else `@'. */
|
||||
*cp++ = (mask & CEN_AUDIENCE) != 0 ? '+' : '@';
|
||||
cp = stpcpy (cp, modifier);
|
||||
}
|
||||
if ((mask & CEN_SPECIAL) != 0)
|
||||
{
|
||||
*cp++ = '+';
|
||||
cp = stpcpy (cp, special);
|
||||
}
|
||||
if ((mask & CEN_SPONSOR) != 0)
|
||||
{
|
||||
*cp++ = ',';
|
||||
cp = stpcpy (cp, sponsor);
|
||||
}
|
||||
if ((mask & CEN_REVISION) != 0)
|
||||
{
|
||||
*cp++ = '_';
|
||||
cp = stpcpy (cp, revision);
|
||||
}
|
||||
|
||||
*cp++ = '/';
|
||||
stpcpy (cp, domain);
|
||||
|
||||
/* Look in list of already loaded domains whether it is already
|
||||
available. */
|
||||
last = NULL;
|
||||
for (retval = _nl_loaded_domains; retval != NULL; retval = retval->next)
|
||||
if (retval->filename != NULL)
|
||||
{
|
||||
int compare = strcmp (retval->filename, filename);
|
||||
if (compare == 0)
|
||||
/* We found it! */
|
||||
break;
|
||||
if (compare < 0)
|
||||
{
|
||||
/* It's not in the list. */
|
||||
retval = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
last = retval;
|
||||
}
|
||||
|
||||
if (retval != NULL || do_allocate == 0)
|
||||
{
|
||||
free (filename);
|
||||
return retval;
|
||||
}
|
||||
}
|
||||
|
||||
retval = (struct loaded_domain *) malloc (sizeof (*retval));
|
||||
if (retval == NULL)
|
||||
return NULL;
|
||||
|
||||
retval->filename = filename;
|
||||
retval->decided = 0;
|
||||
|
||||
if (last == NULL)
|
||||
{
|
||||
retval->next = _nl_loaded_domains;
|
||||
_nl_loaded_domains = retval;
|
||||
}
|
||||
else
|
||||
{
|
||||
retval->next = last->next;
|
||||
last->next = retval;
|
||||
}
|
||||
|
||||
entries = 0;
|
||||
for (cnt = 254; cnt >= 0; --cnt)
|
||||
if (cnt < mask && (cnt & ~mask) == 0
|
||||
&& ((cnt & CEN_SPECIFIC) == 0 || (cnt & XPG_SPECIFIC) == 0)
|
||||
&& ((cnt & XPG_CODESET) == 0 || (cnt & XPG_NORM_CODESET) == 0))
|
||||
retval->successor[entries++] = make_entry_rec (dirname, cnt,
|
||||
language, territory,
|
||||
codeset,
|
||||
normalized_codeset,
|
||||
modifier, special,
|
||||
sponsor, revision,
|
||||
domain, 1);
|
||||
retval->successor[entries] = NULL;
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
static const char *
|
||||
normalize_codeset (codeset)
|
||||
const char *codeset;
|
||||
{
|
||||
int len = 0;
|
||||
int only_digit = 1;
|
||||
const char *cp;
|
||||
char *retval;
|
||||
char *wp;
|
||||
|
||||
for (cp = codeset; cp[0] != '\0'; ++cp)
|
||||
if (isalnum (cp[0]))
|
||||
{
|
||||
++len;
|
||||
|
||||
if (isalpha (cp[0]))
|
||||
only_digit = 0;
|
||||
}
|
||||
|
||||
retval = (char *) malloc ((only_digit ? 3 : 0) + len + 1);
|
||||
|
||||
if (retval != NULL)
|
||||
{
|
||||
if (only_digit)
|
||||
wp = stpcpy (retval, "ISO");
|
||||
else
|
||||
wp = retval;
|
||||
|
||||
for (cp = codeset; cp[0] != '\0'; ++cp)
|
||||
if (isalpha (cp[0]))
|
||||
*wp++ = toupper (cp[0]);
|
||||
else if (isdigit (cp[0]))
|
||||
*wp++ = cp[0];
|
||||
|
||||
*wp = '\0';
|
||||
}
|
||||
|
||||
return (const char *) retval;
|
||||
}
|
||||
|
||||
|
||||
/* @@ begin of epilog @@ */
|
||||
|
||||
/* We don't want libintl.a to depend on any other library. So we
|
||||
|
@ -1,8 +1,6 @@
|
||||
/* gettextP.h -- header describing internals of gettext library
|
||||
Copyright (C) 1995, 1996 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of the GNU C Library. Its master source is NOT part of
|
||||
the C library, however. The master source lives in /gd/gnu/lib.
|
||||
Copyright (C) 1995, 1996 Free Software Foundation, Inc.
|
||||
Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
@ -16,12 +14,14 @@ Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If
|
||||
not, write to the Free Software Foundation, Inc., 675 Mass Ave,
|
||||
Cambridge, MA 02139, USA. */
|
||||
not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#ifndef _GETTEXTP_H
|
||||
#define _GETTEXTP_H
|
||||
|
||||
#include "loadinfo.h"
|
||||
|
||||
/* @@ end of prolog @@ */
|
||||
|
||||
#ifndef PARAMS
|
||||
@ -49,12 +49,6 @@ SWAP (i)
|
||||
|
||||
struct loaded_domain
|
||||
{
|
||||
struct loaded_domain *next;
|
||||
struct loaded_domain *successor[63];
|
||||
|
||||
const char *filename;
|
||||
int decided;
|
||||
|
||||
const char *data;
|
||||
int must_swap;
|
||||
nls_uint32 nstrings;
|
||||
@ -71,12 +65,10 @@ struct binding
|
||||
char *dirname;
|
||||
};
|
||||
|
||||
struct loaded_domain *_nl_find_domain PARAMS ((const char *__dirname,
|
||||
char *__locale,
|
||||
const char *__domainname));
|
||||
void _nl_load_domain PARAMS ((struct loaded_domain *__domain));
|
||||
|
||||
const char *_nl_expand_alias PARAMS ((const char *__name));
|
||||
struct loaded_l10nfile *_nl_find_domain PARAMS ((const char *__dirname,
|
||||
char *__locale,
|
||||
const char *__domainname));
|
||||
void _nl_load_domain PARAMS ((struct loaded_l10nfile *__domain));
|
||||
|
||||
/* @@ begin of epilog @@ */
|
||||
|
||||
|
262
intl/l10nflist.c
Normal file
262
intl/l10nflist.c
Normal file
@ -0,0 +1,262 @@
|
||||
/* Copyright (C) 1995, 1996 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If
|
||||
not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <argz.h>
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "loadinfo.h"
|
||||
|
||||
/* Return number of bits set in X. */
|
||||
static int pop __P ((int x));
|
||||
|
||||
static inline int
|
||||
pop (x)
|
||||
int x;
|
||||
{
|
||||
/* We assume that no more than 16 bits are used. */
|
||||
x = ((x & ~0x5555) >> 1) + (x & 0x5555);
|
||||
x = ((x & ~0x3333) >> 2) + (x & 0x3333);
|
||||
x = ((x >> 4) + x) & 0x0f0f;
|
||||
x = ((x >> 8) + x) & 0xff;
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
|
||||
struct loaded_l10nfile *
|
||||
_nl_make_l10nflist (l10nfile_list, dirlist, dirlist_len, mask, language,
|
||||
territory, codeset, normalized_codeset, modifier, special,
|
||||
sponsor, revision, 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 *special;
|
||||
const char *sponsor;
|
||||
const char *revision;
|
||||
const char *filename;
|
||||
int do_allocate;
|
||||
{
|
||||
char *abs_filename;
|
||||
struct loaded_l10nfile *last = NULL;
|
||||
struct loaded_l10nfile *retval;
|
||||
char *cp;
|
||||
size_t entries;
|
||||
int cnt;
|
||||
|
||||
/* Allocate room for the full file name. */
|
||||
abs_filename = (char *) malloc (dirlist_len
|
||||
+ strlen (language)
|
||||
+ ((mask & TERRITORY) != 0
|
||||
? strlen (territory) + 1 : 0)
|
||||
+ ((mask & XPG_CODESET) != 0
|
||||
? strlen (codeset) + 1 : 0)
|
||||
+ ((mask & XPG_NORM_CODESET) != 0
|
||||
? strlen (normalized_codeset) + 1 : 0)
|
||||
+ (((mask & XPG_MODIFIER) != 0
|
||||
|| (mask & CEN_AUDIENCE) != 0) ?
|
||||
strlen (modifier) + 1 : 0)
|
||||
+ ((mask & CEN_SPECIAL) != 0
|
||||
? strlen (special) + 1 : 0)
|
||||
+ ((mask & CEN_SPONSOR) != 0
|
||||
? strlen (sponsor) + 1 : 0)
|
||||
+ ((mask & CEN_REVISION) != 0
|
||||
? strlen (revision) + 1 : 0)
|
||||
+ 1 + strlen (filename) + 1);
|
||||
|
||||
if (abs_filename == NULL)
|
||||
return NULL;
|
||||
|
||||
retval = NULL;
|
||||
last = NULL;
|
||||
|
||||
/* Construct file name. */
|
||||
memcpy (abs_filename, dirlist, dirlist_len);
|
||||
__argz_stringify (abs_filename, dirlist_len, ':');
|
||||
cp = abs_filename + (dirlist_len - 1);
|
||||
*cp++ = '/';
|
||||
cp = stpcpy (cp, language);
|
||||
|
||||
if ((mask & TERRITORY) != 0)
|
||||
{
|
||||
*cp++ = '_';
|
||||
cp = stpcpy (cp, territory);
|
||||
}
|
||||
if ((mask & XPG_CODESET) != 0)
|
||||
{
|
||||
*cp++ = '.';
|
||||
cp = stpcpy (cp, codeset);
|
||||
}
|
||||
if ((mask & XPG_NORM_CODESET) != 0)
|
||||
{
|
||||
*cp++ = '.';
|
||||
cp = stpcpy (cp, normalized_codeset);
|
||||
}
|
||||
if ((mask & (XPG_MODIFIER | CEN_AUDIENCE)) != 0)
|
||||
{
|
||||
/* This component can be part of both syntaces but has different
|
||||
leading characters. For CEN we use `+', else `@'. */
|
||||
*cp++ = (mask & CEN_AUDIENCE) != 0 ? '+' : '@';
|
||||
cp = stpcpy (cp, modifier);
|
||||
}
|
||||
if ((mask & CEN_SPECIAL) != 0)
|
||||
{
|
||||
*cp++ = '+';
|
||||
cp = stpcpy (cp, special);
|
||||
}
|
||||
if ((mask & CEN_SPONSOR) != 0)
|
||||
{
|
||||
*cp++ = ',';
|
||||
cp = stpcpy (cp, sponsor);
|
||||
}
|
||||
if ((mask & CEN_REVISION) != 0)
|
||||
{
|
||||
*cp++ = '_';
|
||||
cp = stpcpy (cp, revision);
|
||||
}
|
||||
|
||||
*cp++ = '/';
|
||||
stpcpy (cp, filename);
|
||||
|
||||
/* Look in list of already loaded domains whether it is already
|
||||
available. */
|
||||
last = NULL;
|
||||
for (retval = *l10nfile_list; retval != NULL; retval = retval->next)
|
||||
if (retval->filename != NULL)
|
||||
{
|
||||
int compare = strcmp (retval->filename, abs_filename);
|
||||
if (compare == 0)
|
||||
/* We found it! */
|
||||
break;
|
||||
if (compare < 0)
|
||||
{
|
||||
/* It's not in the list. */
|
||||
retval = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
last = retval;
|
||||
}
|
||||
|
||||
if (retval != NULL || do_allocate == 0)
|
||||
{
|
||||
free (abs_filename);
|
||||
return retval;
|
||||
}
|
||||
|
||||
retval = (struct loaded_l10nfile *)
|
||||
malloc (sizeof (*retval) + (__argz_count (dirlist, dirlist_len)
|
||||
* (1 << pop (mask))
|
||||
* sizeof (struct loaded_l10nfile *)));
|
||||
if (retval == NULL)
|
||||
return NULL;
|
||||
|
||||
retval->filename = abs_filename;
|
||||
retval->decided = (__argz_count (dirlist, dirlist_len) != 1
|
||||
|| ((mask & XPG_CODESET) != 0
|
||||
&& (mask & XPG_NORM_CODESET) != 0));
|
||||
retval->data = NULL;
|
||||
|
||||
if (last == NULL)
|
||||
{
|
||||
retval->next = *l10nfile_list;
|
||||
*l10nfile_list = retval;
|
||||
}
|
||||
else
|
||||
{
|
||||
retval->next = last->next;
|
||||
last->next = retval;
|
||||
}
|
||||
|
||||
entries = 0;
|
||||
/* If the DIRLIST is a real list the RETVAL entry correcponds not to
|
||||
a real file. So we have to use the DIRLIST separation machanism
|
||||
of the inner loop. */
|
||||
cnt = __argz_count (dirlist, dirlist_len) == 1 ? mask - 1 : mask;
|
||||
for (; cnt >= 0; --cnt)
|
||||
if ((cnt & ~mask) == 0
|
||||
&& ((cnt & CEN_SPECIFIC) == 0 || (cnt & XPG_SPECIFIC) == 0)
|
||||
&& ((cnt & XPG_CODESET) == 0 || (cnt & XPG_NORM_CODESET) == 0))
|
||||
{
|
||||
/* Iterate over all elements of the DIRLIST. */
|
||||
char *dir = NULL;
|
||||
|
||||
while ((dir = __argz_next ((char *) dirlist, dirlist_len, dir))
|
||||
!= NULL)
|
||||
retval->successor[entries++]
|
||||
= _nl_make_l10nflist (l10nfile_list, dir, strlen (dir) + 1, cnt,
|
||||
language, territory, codeset,
|
||||
normalized_codeset, modifier, special,
|
||||
sponsor, revision, filename, 1);
|
||||
}
|
||||
retval->successor[entries] = NULL;
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* Normalize codeset name. There is no standard for the codeset
|
||||
names. Normalization allows the user to use any of the common
|
||||
names. */
|
||||
const char *
|
||||
_nl_normalize_codeset (codeset, name_len)
|
||||
const char *codeset;
|
||||
size_t name_len;
|
||||
{
|
||||
int len = 0;
|
||||
int only_digit = 1;
|
||||
char *retval;
|
||||
char *wp;
|
||||
size_t cnt;
|
||||
|
||||
for (cnt = 0; cnt < name_len; ++cnt)
|
||||
if (isalnum (codeset[cnt]))
|
||||
{
|
||||
++len;
|
||||
|
||||
if (isalpha (codeset[cnt]))
|
||||
only_digit = 0;
|
||||
}
|
||||
|
||||
retval = (char *) malloc ((only_digit ? 3 : 0) + len + 1);
|
||||
|
||||
if (retval != NULL)
|
||||
{
|
||||
if (only_digit)
|
||||
wp = stpcpy (retval, "ISO");
|
||||
else
|
||||
wp = retval;
|
||||
|
||||
for (cnt = 0; cnt < name_len; ++cnt)
|
||||
if (isalpha (codeset[cnt]))
|
||||
*wp++ = tolower (codeset[cnt]);
|
||||
else if (isdigit (codeset[cnt]))
|
||||
*wp++ = codeset[cnt];
|
||||
|
||||
*wp = '\0';
|
||||
}
|
||||
|
||||
return (const char *) retval;
|
||||
}
|
48
intl/loadinfo.h
Normal file
48
intl/loadinfo.h
Normal file
@ -0,0 +1,48 @@
|
||||
/* Encoding of locale name parts. */
|
||||
#define CEN_REVISION 1
|
||||
#define CEN_SPONSOR 2
|
||||
#define CEN_SPECIAL 4
|
||||
#define XPG_NORM_CODESET 8
|
||||
#define XPG_CODESET 16
|
||||
#define TERRITORY 32
|
||||
#define CEN_AUDIENCE 64
|
||||
#define XPG_MODIFIER 128
|
||||
|
||||
#define CEN_SPECIFIC (CEN_REVISION|CEN_SPONSOR|CEN_SPECIAL|CEN_AUDIENCE)
|
||||
#define XPG_SPECIFIC (XPG_CODESET|XPG_NORM_CODESET|XPG_MODIFIER)
|
||||
|
||||
|
||||
struct loaded_l10nfile
|
||||
{
|
||||
const char *filename;
|
||||
int decided;
|
||||
|
||||
const void *data;
|
||||
|
||||
struct loaded_l10nfile *next;
|
||||
struct loaded_l10nfile *successor[1];
|
||||
};
|
||||
|
||||
|
||||
extern const char *_nl_normalize_codeset __P ((const char *codeset,
|
||||
size_t name_len));
|
||||
|
||||
extern struct loaded_l10nfile *
|
||||
_nl_make_l10nflist __P ((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 *special,
|
||||
const char *sponsor, const char *revision,
|
||||
const char *filename, int do_allocate));
|
||||
|
||||
|
||||
extern const char *_nl_expand_alias __P ((const char *name));
|
||||
|
||||
extern int _nl_explode_name __P ((char *name, const char **language,
|
||||
const char **modifier,
|
||||
const char **territory,
|
||||
const char **codeset,
|
||||
const char **normalized_codeset,
|
||||
const char **special, const char **sponsor,
|
||||
const char **revision));
|
@ -1,8 +1,6 @@
|
||||
/* loadmsgcat.c -- load needed message catalogs
|
||||
Copyright (C) 1995 Software Foundation, Inc.
|
||||
|
||||
This file is part of the GNU C Library. Its master source is NOT part of
|
||||
the C library, however. The master source lives in /gd/gnu/lib.
|
||||
Copyright (C) 1995, 1996 Free Software Foundation, Inc.
|
||||
Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
@ -16,8 +14,8 @@ Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If
|
||||
not, write to the Free Software Foundation, Inc., 675 Mass Ave,
|
||||
Cambridge, MA 02139, USA. */
|
||||
not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
@ -65,8 +63,8 @@ int _nl_msg_cat_cntr;
|
||||
/* Load the message catalogs specified by FILENAME. If it is no valid
|
||||
message catalog do nothing. */
|
||||
void
|
||||
_nl_load_domain (domain)
|
||||
struct loaded_domain *domain;
|
||||
_nl_load_domain (domain_file)
|
||||
struct loaded_l10nfile *domain_file;
|
||||
{
|
||||
int fd;
|
||||
struct stat st;
|
||||
@ -75,19 +73,20 @@ _nl_load_domain (domain)
|
||||
|| defined _LIBC
|
||||
int use_mmap = 0;
|
||||
#endif
|
||||
struct loaded_domain *domain;
|
||||
|
||||
domain->decided = 1;
|
||||
domain->data = NULL;
|
||||
domain_file->decided = 1;
|
||||
domain_file->data = NULL;
|
||||
|
||||
/* If the record does not represent a valid locale the FILENAME
|
||||
might be NULL. This can happen when according to the given
|
||||
specification the locale file name is different for XPG and CEN
|
||||
syntax. */
|
||||
if (domain->filename == NULL)
|
||||
if (domain_file->filename == NULL)
|
||||
return;
|
||||
|
||||
/* Try to open the addressed file. */
|
||||
fd = open (domain->filename, O_RDONLY);
|
||||
fd = open (domain_file->filename, O_RDONLY);
|
||||
if (fd == -1)
|
||||
return;
|
||||
|
||||
@ -160,6 +159,12 @@ _nl_load_domain (domain)
|
||||
return;
|
||||
}
|
||||
|
||||
domain_file->data
|
||||
= (struct loaded_domain *) malloc (sizeof (struct loaded_domain *));
|
||||
if (domain->data == NULL)
|
||||
return;
|
||||
|
||||
domain = (struct loaded_domain *) domain_file->data;
|
||||
domain->data = (char *) data;
|
||||
domain->must_swap = data->magic != _MAGIC;
|
||||
|
||||
@ -185,11 +190,12 @@ _nl_load_domain (domain)
|
||||
else
|
||||
#endif
|
||||
free (data);
|
||||
domain->data = NULL;
|
||||
free (domain);
|
||||
domain_file->data = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Show that one domain is changed. This might make some cached
|
||||
translation invalid. */
|
||||
translations invalid. */
|
||||
++_nl_msg_cat_cntr;
|
||||
}
|
||||
|
52
intl/locale.alias
Normal file
52
intl/locale.alias
Normal file
@ -0,0 +1,52 @@
|
||||
# Locale name alias data base
|
||||
# Copyright (C) 1996 Free Software Foundation, Inc.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
# The format of this file is the same as for the corresponding file of
|
||||
# the X Window System, which normally can be found in
|
||||
# /usr/lib/X11/locale/locale.alias
|
||||
# A single line contains two fields: an alias and a substitution value.
|
||||
# All entries are case independent.
|
||||
|
||||
# Note: This file is far from being complete. If you have a value for
|
||||
# your own site which you think might be useful for others too, share it
|
||||
# with the rest of us. Send it to bug-gnu-utils@prep.ai.mit.edu.
|
||||
|
||||
czech cz_CZ.ISO-8859-2
|
||||
danish da_DK.ISO-8859-1
|
||||
dansk da_DK.ISO-8859-1
|
||||
deutsch de_DE.ISO-8859-1
|
||||
dutch nl_NL.ISO-8859-1
|
||||
finnish fi_FI.ISO-8859-1
|
||||
français fr_FR.ISO-8859-1
|
||||
french fr_FR.ISO-8859-1
|
||||
german de_DE.ISO-8859-1
|
||||
greek el_GR.ISO-8859-7
|
||||
hebrew iw_IL.ISO-8859-8
|
||||
hungarian hu_HU.ISO-8859-2
|
||||
icelandic is_IS.ISO-8859-1
|
||||
italian it_CH.ISO-8859-1
|
||||
japanese ja_JP.EUC
|
||||
norwegian no_NO.ISO-8859-1
|
||||
polish pl_PL.ISO-8859-2
|
||||
portuguese pt_PT.ISO-8859-1
|
||||
rumanian ro_RO.ISO-8859-2
|
||||
russian ru_SU.ISO-8859-5
|
||||
slovak sk_SK.ISO-8859-2
|
||||
slovene sl_CS.ISO-8859-2
|
||||
spanish es_ES.ISO-8859-1
|
||||
swedish sv_SE.ISO-8859-1
|
||||
turkish tr_TR.ISO-8859-9
|
@ -1,6 +1,6 @@
|
||||
/* This is part of the iostream/stdio library, providing -*- C -*- I/O.
|
||||
Define ANSI C stdio on top of C++ iostreams.
|
||||
Copyright (C) 1991, 1994, 1995 Free Software Foundation, Inc.
|
||||
Copyright (C) 1991, 1994, 1995, 1996 Free Software Foundation, Inc.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
@ -166,6 +166,9 @@ extern int snprintf __P ((char *, size_t, __const char *, ...));
|
||||
extern int __snprintf __P ((char *, size_t, __const char *, ...));
|
||||
extern int vsnprintf __P ((char *, size_t, __const char *, _G_va_list));
|
||||
|
||||
extern int asprintf __P ((char **, const char *, ...));
|
||||
extern int vasprintf __P ((char **, const char *, _G_va_list));
|
||||
|
||||
/* Open a stream that writes into a malloc'd buffer that is expanded as
|
||||
necessary. *BUFLOC and *SIZELOC are updated with the buffer's location
|
||||
and the number of characters written on fflush or fclose. */
|
||||
|
@ -21,6 +21,7 @@ Boston, MA 02111-1307, USA. */
|
||||
|
||||
const struct locale_data _nl_C_LC_COLLATE =
|
||||
{
|
||||
_nl_C_name,
|
||||
NULL, 0, /* no file mapped */
|
||||
0,
|
||||
};
|
||||
|
@ -896,6 +896,7 @@ const char _nl_C_LC_CTYPE_width[256] =
|
||||
|
||||
const struct locale_data _nl_C_LC_CTYPE =
|
||||
{
|
||||
_nl_C_name,
|
||||
NULL, 0, /* no file mapped */
|
||||
13,
|
||||
{
|
||||
|
@ -21,6 +21,7 @@ Boston, MA 02111-1307, USA. */
|
||||
|
||||
const struct locale_data _nl_C_LC_MESSAGES =
|
||||
{
|
||||
_nl_C_name,
|
||||
NULL, 0, /* no file mapped */
|
||||
4,
|
||||
{
|
||||
|
@ -21,6 +21,7 @@ Boston, MA 02111-1307, USA. */
|
||||
|
||||
const struct locale_data _nl_C_LC_MONETARY =
|
||||
{
|
||||
_nl_C_name,
|
||||
NULL, 0, /* no file mapped */
|
||||
15,
|
||||
{
|
||||
|
@ -21,6 +21,7 @@ Boston, MA 02111-1307, USA. */
|
||||
|
||||
const struct locale_data _nl_C_LC_NUMERIC =
|
||||
{
|
||||
_nl_C_name,
|
||||
NULL, 0, /* no file mapped */
|
||||
3,
|
||||
{
|
||||
|
@ -21,6 +21,7 @@ Boston, MA 02111-1307, USA. */
|
||||
|
||||
const struct locale_data _nl_C_LC_TIME =
|
||||
{
|
||||
_nl_C_name,
|
||||
NULL, 0, /* no file mapped */
|
||||
45,
|
||||
{
|
||||
|
@ -28,7 +28,7 @@ distribute = localeinfo.h categories.def \
|
||||
charmap-kw.gperf charmap-kw.h locfile-token.h \
|
||||
locfile-kw.gperf locfile-kw.h linereader.h \
|
||||
locales.h locfile.h stringtrans.h
|
||||
routines = setlocale loadlocale localeconv nl_langinfo
|
||||
routines = setlocale findlocale loadlocale localeconv nl_langinfo
|
||||
categories = ctype messages monetary numeric time collate
|
||||
aux = $(categories:%=lc-%) $(categories:%=C-%) SYS_libc
|
||||
others = localedef locale
|
||||
|
192
locale/findlocale.c
Normal file
192
locale/findlocale.c
Normal file
@ -0,0 +1,192 @@
|
||||
/* Copyright (C) 1996 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1996.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If
|
||||
not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <locale.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "localeinfo.h"
|
||||
|
||||
|
||||
/* Constant data defined in setlocale.c. */
|
||||
extern const struct locale_data *const _nl_C[];
|
||||
|
||||
|
||||
static inline char *
|
||||
copy (const char *string)
|
||||
{
|
||||
size_t len;
|
||||
char *new;
|
||||
len = strlen (string) + 1;
|
||||
new = (char *) malloc (len);
|
||||
return new != NULL ? memcpy (new, string, len) : NULL;
|
||||
}
|
||||
|
||||
|
||||
/* For each category we keep a list of records for the locale files
|
||||
which are somehow addressed. */
|
||||
static struct loaded_l10nfile *locale_file_list[LC_ALL];
|
||||
|
||||
|
||||
const struct locale_data *
|
||||
_nl_find_locale (const char *locale_path, size_t locale_path_len,
|
||||
int category, char **name)
|
||||
{
|
||||
int mask;
|
||||
/* Name of the locale for this category. */
|
||||
char *loc_name;
|
||||
const char *language;
|
||||
const char *modifier;
|
||||
const char *territory;
|
||||
const char *codeset;
|
||||
const char *normalized_codeset;
|
||||
const char *special;
|
||||
const char *sponsor;
|
||||
const char *revision;
|
||||
struct loaded_l10nfile *locale_file;
|
||||
|
||||
if ((*name)[0] == '\0')
|
||||
{
|
||||
/* The user decides which locale to use by setting environment
|
||||
variables. */
|
||||
*name = getenv ("LC_ALL");
|
||||
if (*name == NULL || (*name)[0] == '\0')
|
||||
*name = getenv (_nl_category_names[category]);
|
||||
if (*name == NULL || (*name)[0] == '\0')
|
||||
*name = getenv ("LANG");
|
||||
if (*name == NULL || (*name)[0] == '\0')
|
||||
*name = (char *) _nl_C_name;
|
||||
}
|
||||
|
||||
if (strcmp (*name, _nl_C_name) == 0 || strcmp (*name, "POSIX") == 0)
|
||||
{
|
||||
/* We need not load anything. The needed data is contained in
|
||||
the library itself. */
|
||||
*name = (char *) _nl_C_name;
|
||||
return _nl_C[category];
|
||||
}
|
||||
|
||||
/* We really have to load some data. First see whether the name is
|
||||
an alias. Please note that this makes it impossible to have "C"
|
||||
or "POSIX" as aliases. */
|
||||
loc_name = _nl_expand_alias (*name);
|
||||
if (loc_name == NULL)
|
||||
/* It is no alias. */
|
||||
loc_name = *name;
|
||||
|
||||
/* Make a writable copy of the locale name. */
|
||||
loc_name = copy (loc_name);
|
||||
|
||||
/* LOCALE can consist of up to four recognized parts for the XPG syntax:
|
||||
|
||||
language[_territory[.codeset]][@modifier]
|
||||
|
||||
and six parts for the CEN syntax:
|
||||
|
||||
language[_territory][+audience][+special][,sponsor][_revision]
|
||||
|
||||
Beside the first all of them are allowed to be missing. If the
|
||||
full specified locale is not found, the less specific one are
|
||||
looked for. The various part will be stripped of according to
|
||||
the following order:
|
||||
(1) revision
|
||||
(2) sponsor
|
||||
(3) special
|
||||
(4) codeset
|
||||
(5) normalized codeset
|
||||
(6) territory
|
||||
(7) audience/modifier
|
||||
*/
|
||||
mask = _nl_explode_name (loc_name, &language, &modifier, &territory,
|
||||
&codeset, &normalized_codeset, &special,
|
||||
&sponsor, &revision);
|
||||
|
||||
/* If exactly this locale was already asked for we have an entry with
|
||||
the complete name. */
|
||||
locale_file = _nl_make_l10nflist (&locale_file_list[category],
|
||||
locale_path, locale_path_len, mask,
|
||||
language, territory, codeset,
|
||||
normalized_codeset, modifier, special,
|
||||
sponsor, revision,
|
||||
_nl_category_names[category], 0);
|
||||
|
||||
if (locale_file == NULL)
|
||||
{
|
||||
/* Find status record for addressed locale file. We have to search
|
||||
through all directories in the locale path. */
|
||||
locale_file = _nl_make_l10nflist (&locale_file_list[category],
|
||||
locale_path, locale_path_len, mask,
|
||||
language, territory, codeset,
|
||||
normalized_codeset, modifier, special,
|
||||
sponsor, revision,
|
||||
_nl_category_names[category], 1);
|
||||
if (locale_file == NULL)
|
||||
/* This means we are out of core. */
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
/* If the addressed locale is already available it should be freed.
|
||||
If we would not do this switching back and force between two
|
||||
locales would slowly eat up all memory.*/
|
||||
free (loc_name);
|
||||
|
||||
if (locale_file->decided == 0)
|
||||
_nl_load_locale (locale_file, category);
|
||||
|
||||
if (locale_file->data == NULL)
|
||||
{
|
||||
int cnt;
|
||||
for (cnt = 0; locale_file->successor[cnt] != NULL; ++cnt)
|
||||
{
|
||||
if (locale_file->successor[cnt]->decided == 0)
|
||||
_nl_load_locale (locale_file->successor[cnt], category);
|
||||
if (locale_file->successor[cnt]->data != NULL)
|
||||
break;
|
||||
}
|
||||
/* Move the entry we found (or NULL) to the first place of
|
||||
successors. */
|
||||
locale_file->successor[0] = locale_file->successor[cnt];
|
||||
locale_file = locale_file->successor[cnt];
|
||||
}
|
||||
|
||||
if (locale_file == NULL)
|
||||
return NULL;
|
||||
|
||||
/* Determine the locale name for which loading succeeded. This
|
||||
information comes from the file name. The form is
|
||||
<path>/<locale>/LC_foo. We must extract this <locale> part. */
|
||||
if (((struct locale_data *) locale_file->data)->name == NULL)
|
||||
{
|
||||
char *newp, *cp, *endp;
|
||||
|
||||
endp = strrchr (locale_file->filename, '/');
|
||||
cp = endp - 1;
|
||||
while (cp[-1] != '/')
|
||||
--cp;
|
||||
newp = (char *) malloc (endp - cp + 1);
|
||||
if (newp == NULL)
|
||||
return NULL;
|
||||
memcpy (newp, cp, endp - cp);
|
||||
newp[endp - cp] = '\0';
|
||||
((struct locale_data *) locale_file->data)->name = newp;
|
||||
}
|
||||
*name = (char *) ((struct locale_data *) locale_file->data)->name;
|
||||
|
||||
return (struct locale_data *) locale_file->data;
|
||||
}
|
@ -22,8 +22,8 @@ Boston, MA 02111-1307, USA. */
|
||||
|
||||
_NL_CURRENT_DEFINE (LC_COLLATE);
|
||||
|
||||
const u32_t *__collate_table;
|
||||
const u32_t *__collate_extra;
|
||||
const u_int32_t *__collate_table;
|
||||
const u_int32_t *__collate_extra;
|
||||
|
||||
|
||||
void
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* Functions to read locale data files.
|
||||
Copyright (C) 1995, 1996 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1996 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1996.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
@ -14,20 +14,21 @@ Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If
|
||||
not, write to the Free Software Foundation, Inc., 675 Mass Ave,
|
||||
Cambridge, MA 02139, USA. */
|
||||
not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "localeinfo.h"
|
||||
|
||||
const size_t _nl_category_num_items[] =
|
||||
|
||||
static const size_t _nl_category_num_items[] =
|
||||
{
|
||||
#define DEFINE_CATEGORY(category, category_name, items, a, b, c, d) \
|
||||
[category] = _NL_ITEM_INDEX (_NL_NUM_##category),
|
||||
@ -54,8 +55,8 @@ static const enum value_type *_nl_value_types[] =
|
||||
};
|
||||
|
||||
|
||||
struct locale_data *
|
||||
_nl_load_locale (int category, char **name)
|
||||
void
|
||||
_nl_load_locale (struct loaded_l10nfile *file, int category)
|
||||
{
|
||||
int fd;
|
||||
struct
|
||||
@ -66,7 +67,9 @@ _nl_load_locale (int category, char **name)
|
||||
} *filedata;
|
||||
struct stat st;
|
||||
struct locale_data *newdata;
|
||||
int save_err;
|
||||
int swap = 0;
|
||||
size_t cnt;
|
||||
inline unsigned int SWAP (const unsigned int *inw)
|
||||
{
|
||||
const unsigned char *inc = (const unsigned char *) inw;
|
||||
@ -74,98 +77,86 @@ _nl_load_locale (int category, char **name)
|
||||
return *inw;
|
||||
return (inc[3] << 24) | (inc[2] << 16) | (inc[1] << 8) | inc[0];
|
||||
}
|
||||
unsigned int i;
|
||||
|
||||
if ((*name)[0] == '\0')
|
||||
file->decided = 1;
|
||||
file->data = NULL;
|
||||
|
||||
fd = __open (file->filename, O_RDONLY);
|
||||
if (fd < 0)
|
||||
/* Cannot open the file. */
|
||||
return;
|
||||
|
||||
if (__fstat (fd, &st) < 0)
|
||||
goto puntfd;
|
||||
if (S_ISDIR (st.st_mode))
|
||||
{
|
||||
*name = getenv ("LC_ALL");
|
||||
if (! *name || (*name)[0] == '\0')
|
||||
*name = getenv (_nl_category_names[category]);
|
||||
if (! *name || (*name)[0] == '\0')
|
||||
*name = getenv ("LANG");
|
||||
if (! *name || (*name)[0] == '\0')
|
||||
*name = (char *) "local";
|
||||
/* LOCALE/LC_foo is a directory; open LOCALE/LC_foo/SYS_LC_foo
|
||||
instead. */
|
||||
char *newp;
|
||||
|
||||
__close (fd);
|
||||
|
||||
newp = (char *) alloca (strlen (file->filename)
|
||||
+ 5 + _nl_category_name_sizes[category] + 1);
|
||||
__stpcpy (__stpcpy (__stpcpy (newp, file->filename), "/SYS_"),
|
||||
_nl_category_names[category]);
|
||||
|
||||
fd = __open (newp, O_RDONLY);
|
||||
if (fd < 0)
|
||||
return;
|
||||
|
||||
if (__fstat (fd, &st) < 0)
|
||||
goto puntfd;
|
||||
}
|
||||
|
||||
{
|
||||
const char *catname = _nl_category_names[category];
|
||||
size_t namelen = strlen (*name);
|
||||
size_t catlen = strlen (catname);
|
||||
char file[sizeof LOCALE_PATH + 1 + namelen + catlen * 2 + 4];
|
||||
if (strchr (*name, '/') != NULL)
|
||||
sprintf (file, "%s/%s", *name, catname);
|
||||
else
|
||||
sprintf (file, "%s/%s/%s", LOCALE_PATH, *name, catname);
|
||||
fd = __open (file, O_RDONLY);
|
||||
if (fd < 0)
|
||||
return NULL;
|
||||
if (__fstat (fd, &st) < 0)
|
||||
goto puntfd;
|
||||
if (S_ISDIR (st.st_mode))
|
||||
{
|
||||
/* LOCALE/LC_foo is a directory; open LOCALE/LC_foo/SYS_LC_foo
|
||||
instead. */
|
||||
__close (fd);
|
||||
memcpy (stpcpy (strchr (file, '\0'), "SYS_"), catname, catlen);
|
||||
fd = __open (file, O_RDONLY);
|
||||
if (fd < 0)
|
||||
return NULL;
|
||||
if (__fstat (fd, &st) < 0)
|
||||
goto puntfd;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
/* Map in the file's data. */
|
||||
int save = errno;
|
||||
/* Map in the file's data. */
|
||||
save_err = errno;
|
||||
#ifndef MAP_COPY
|
||||
/* Linux seems to lack read-only copy-on-write. */
|
||||
/* Linux seems to lack read-only copy-on-write. */
|
||||
#define MAP_COPY MAP_PRIVATE
|
||||
#endif
|
||||
#ifndef MAP_FILE
|
||||
/* Some systems do not have this flag; it is superfluous. */
|
||||
/* Some systems do not have this flag; it is superfluous. */
|
||||
#define MAP_FILE 0
|
||||
#endif
|
||||
#ifndef MAP_INHERIT
|
||||
/* Some systems might lack this; they lose. */
|
||||
/* Some systems might lack this; they lose. */
|
||||
#define MAP_INHERIT 0
|
||||
#endif
|
||||
filedata = (void *) __mmap ((caddr_t) 0, st.st_size,
|
||||
PROT_READ, MAP_FILE|MAP_COPY|MAP_INHERIT,
|
||||
fd, 0);
|
||||
if (filedata == (void *) -1)
|
||||
{
|
||||
if (errno == ENOSYS)
|
||||
{
|
||||
/* No mmap; allocate a buffer and read from the file. */
|
||||
filedata = malloc (st.st_size);
|
||||
if (filedata)
|
||||
{
|
||||
off_t to_read = st.st_size;
|
||||
ssize_t nread;
|
||||
char *p = (char *) filedata;
|
||||
while (to_read > 0)
|
||||
{
|
||||
nread = __read (fd, p, to_read);
|
||||
if (nread <= 0)
|
||||
{
|
||||
free (filedata);
|
||||
if (nread == 0)
|
||||
errno = EINVAL; /* Bizarreness going on. */
|
||||
goto puntfd;
|
||||
}
|
||||
p += nread;
|
||||
to_read -= nread;
|
||||
}
|
||||
}
|
||||
else
|
||||
goto puntfd;
|
||||
errno = save;
|
||||
}
|
||||
else
|
||||
goto puntfd;
|
||||
}
|
||||
}
|
||||
filedata = (void *) __mmap ((caddr_t) 0, st.st_size, PROT_READ,
|
||||
MAP_FILE|MAP_COPY|MAP_INHERIT, fd, 0);
|
||||
if (filedata == (void *) -1)
|
||||
{
|
||||
if (errno == ENOSYS)
|
||||
{
|
||||
/* No mmap; allocate a buffer and read from the file. */
|
||||
filedata = malloc (st.st_size);
|
||||
if (filedata != NULL)
|
||||
{
|
||||
off_t to_read = st.st_size;
|
||||
ssize_t nread;
|
||||
char *p = (char *) filedata;
|
||||
while (to_read > 0)
|
||||
{
|
||||
nread = __read (fd, p, to_read);
|
||||
if (nread <= 0)
|
||||
{
|
||||
free (filedata);
|
||||
if (nread == 0)
|
||||
errno = EINVAL; /* Bizarreness going on. */
|
||||
goto puntfd;
|
||||
}
|
||||
p += nread;
|
||||
to_read -= nread;
|
||||
}
|
||||
}
|
||||
else
|
||||
goto puntfd;
|
||||
errno = save_err;
|
||||
}
|
||||
else
|
||||
goto puntfd;
|
||||
}
|
||||
|
||||
if (filedata->magic == LIMAGIC (category))
|
||||
/* Good data file in our byte order. */
|
||||
@ -181,7 +172,7 @@ _nl_load_locale (int category, char **name)
|
||||
__munmap ((caddr_t) filedata, st.st_size);
|
||||
puntfd:
|
||||
__close (fd);
|
||||
return NULL;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@ -201,41 +192,46 @@ _nl_load_locale (int category, char **name)
|
||||
if (! newdata)
|
||||
goto puntmap;
|
||||
|
||||
newdata->name = NULL; /* This will be filled if necessary in findlocale.c. */
|
||||
newdata->filedata = (void *) filedata;
|
||||
newdata->filesize = st.st_size;
|
||||
newdata->nstrings = W (filedata->nstrings);
|
||||
for (i = 0; i < newdata->nstrings; ++i)
|
||||
for (cnt = 0; cnt < newdata->nstrings; ++cnt)
|
||||
{
|
||||
unsigned int idx = W (filedata->strindex[i]);
|
||||
off_t idx = W (filedata->strindex[cnt]);
|
||||
if (idx >= newdata->filesize)
|
||||
{
|
||||
free (newdata);
|
||||
errno = EINVAL;
|
||||
goto puntmap;
|
||||
}
|
||||
if (_nl_value_types[category][i] == word)
|
||||
newdata->values[i].word = W (*((u32_t *) (newdata->filedata + idx)));
|
||||
if (_nl_value_types[category][cnt] == word)
|
||||
newdata->values[cnt].word = W (*((u_int32_t *) (newdata->filedata
|
||||
+ idx)));
|
||||
else
|
||||
newdata->values[i].string = newdata->filedata + idx;
|
||||
newdata->values[cnt].string = newdata->filedata + idx;
|
||||
}
|
||||
|
||||
__close (fd);
|
||||
return newdata;
|
||||
file->data = newdata;
|
||||
}
|
||||
|
||||
void
|
||||
_nl_free_locale (struct locale_data *data)
|
||||
_nl_free_locale (const struct locale_data *data)
|
||||
{
|
||||
int save = errno;
|
||||
if (! data)
|
||||
if (data == NULL)
|
||||
/* Ignore a null pointer, like free does. */
|
||||
return;
|
||||
if (data->name != NULL)
|
||||
free ((void *) data->name);
|
||||
if (__munmap ((caddr_t) data->filedata, data->filesize) < 0)
|
||||
{
|
||||
if (errno == ENOSYS)
|
||||
free ((void *) data->filedata);
|
||||
errno = save;
|
||||
}
|
||||
free (data);
|
||||
free ((void *) data);
|
||||
}
|
||||
|
||||
|
||||
|
@ -24,17 +24,20 @@ Cambridge, MA 02139, USA. */
|
||||
#include <langinfo.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "../intl/loadinfo.h" /* For loaded_l10nfile definition. */
|
||||
|
||||
/* Magic number at the beginning of a locale data file for CATEGORY. */
|
||||
#define LIMAGIC(category) (0x960316de ^ (category))
|
||||
|
||||
/* Two special weight constants for the collation data. */
|
||||
#define FORWARD_CHAR 0xfffffffd
|
||||
#define ELLIPSIS_CHAR 0xfffffffe
|
||||
#define IGNORE_CHAR 0xffffffff
|
||||
#define FORWARD_CHAR ((wchar_t) 0xfffffffd)
|
||||
#define ELLIPSIS_CHAR ((wchar_t) 0xfffffffe)
|
||||
#define IGNORE_CHAR ((wchar_t) 0xffffffff)
|
||||
|
||||
/* Structure describing locale data in core for a category. */
|
||||
struct locale_data
|
||||
{
|
||||
const char *name;
|
||||
const char *filedata; /* Region mapping the file data. */
|
||||
off_t filesize; /* Size of the file (and the region). */
|
||||
|
||||
@ -78,9 +81,13 @@ extern const struct locale_data *_nl_current_##category;
|
||||
#include "categories.def"
|
||||
#undef DEFINE_CATEGORY
|
||||
|
||||
extern const char *const _nl_category_names[LC_ALL];
|
||||
extern const char *const _nl_category_names[LC_ALL + 1];
|
||||
extern const size_t _nl_category_name_sizes[LC_ALL + 1];
|
||||
extern const struct locale_data * *const _nl_current[LC_ALL];
|
||||
|
||||
/* Name of the standard locale. */
|
||||
extern const char _nl_C_name[];
|
||||
|
||||
/* Extract the current CATEGORY locale's string for ITEM. */
|
||||
#define _NL_CURRENT(category, item) \
|
||||
(_nl_current_##category->values[_NL_ITEM_INDEX (item)].string)
|
||||
@ -96,18 +103,21 @@ extern const struct locale_data * *const _nl_current[LC_ALL];
|
||||
|
||||
/* Load the locale data for CATEGORY from the file specified by *NAME.
|
||||
If *NAME is "", use environment variables as specified by POSIX,
|
||||
and fill in *NAME with the actual name used. */
|
||||
extern struct locale_data *_nl_load_locale (int category, char **name);
|
||||
and fill in *NAME with the actual name used. The directories
|
||||
listed in LOCALE_PATH are searched for the locale files. */
|
||||
extern const struct locale_data *_nl_find_locale (const char *locale_path,
|
||||
size_t locale_path_len,
|
||||
int category, char **name);
|
||||
|
||||
/* Try to load the file described by FILE. */
|
||||
extern void _nl_load_locale (struct loaded_l10nfile *file, int category);
|
||||
|
||||
/* Free the locale data read in by a `_nl_load_locale' call. */
|
||||
extern void _nl_free_locale (struct locale_data *);
|
||||
extern void _nl_free_locale (const struct locale_data *);
|
||||
|
||||
|
||||
/* XXX For now. */
|
||||
typedef unsigned int u32_t;
|
||||
|
||||
/* Global variables for LC_COLLATE category data. */
|
||||
extern const u32_t *__collate_table;
|
||||
extern const u32_t *__collate_extra;
|
||||
extern const u_int32_t *__collate_table;
|
||||
extern const u_int32_t *__collate_extra;
|
||||
|
||||
#endif /* localeinfo.h */
|
||||
|
@ -53,7 +53,7 @@ struct charset_t
|
||||
/* We need one value to mark the error case. Let's use 0xffffffff.
|
||||
I.e., it is placed in the last page of ISO 10646. For now only the
|
||||
first is used and we have plenty of room. */
|
||||
#define ILLEGAL_CHAR_VALUE 0xffffffffu
|
||||
#define ILLEGAL_CHAR_VALUE ((wchar_t) 0xffffffffu)
|
||||
|
||||
|
||||
/* Prototypes for charmap handling functions. */
|
||||
|
@ -24,7 +24,6 @@
|
||||
|
||||
|
||||
typedef int wint_t;
|
||||
typedef unsigned short int u16_t;
|
||||
|
||||
|
||||
#include_next <config.h>
|
||||
|
@ -253,7 +253,7 @@ collate_finish (struct localedef_t *locale, struct charset_t *charset)
|
||||
|* XXX We should test whether really an unspecified character *|
|
||||
|* exists before giving the message. *|
|
||||
\**************************************************************/
|
||||
u32_t weight;
|
||||
u_int32_t weight;
|
||||
|
||||
error (0, 0, _("no definition of `UNDEFINED'"));
|
||||
|
||||
@ -262,7 +262,7 @@ collate_finish (struct localedef_t *locale, struct charset_t *charset)
|
||||
|
||||
for (cnt = 0; cnt < collate->nrules; ++cnt)
|
||||
{
|
||||
u32_t one = 1;
|
||||
u_int32_t one = 1;
|
||||
obstack_grow (&collate->element_mem, &one, sizeof (one));
|
||||
}
|
||||
|
||||
@ -286,7 +286,7 @@ void
|
||||
collate_output (struct localedef_t *locale, const char *output_path)
|
||||
{
|
||||
struct locale_collate_t *collate = locale->categories[LC_COLLATE].collate;
|
||||
u32_t table_size, table_best, level_best, sum_best;
|
||||
u_int32_t table_size, table_best, level_best, sum_best;
|
||||
void *last;
|
||||
element_t *pelem;
|
||||
wchar_t *name;
|
||||
@ -294,11 +294,11 @@ collate_output (struct localedef_t *locale, const char *output_path)
|
||||
const size_t nelems = _NL_ITEM_INDEX (_NL_NUM_LC_COLLATE);
|
||||
struct iovec iov[2 + nelems];
|
||||
struct locale_file data;
|
||||
u32_t idx[nelems];
|
||||
u_int32_t idx[nelems];
|
||||
struct obstack non_simple;
|
||||
size_t cnt, entry_size;
|
||||
u32_t undefined_offset = UINT_MAX;
|
||||
u32_t *table, *extra, *table2, *extra2;
|
||||
u_int32_t undefined_offset = UINT_MAX;
|
||||
u_int32_t *table, *extra, *table2, *extra2;
|
||||
size_t extra_len;
|
||||
|
||||
sum_best = UINT_MAX;
|
||||
@ -352,12 +352,12 @@ Computing table size for collation information might take a while..."),
|
||||
iov[1].iov_len = sizeof (idx);
|
||||
|
||||
iov[2 + _NL_ITEM_INDEX (_NL_COLLATE_NRULES)].iov_base = &collate->nrules;
|
||||
iov[2 + _NL_ITEM_INDEX (_NL_COLLATE_NRULES)].iov_len = sizeof (u32_t);
|
||||
iov[2 + _NL_ITEM_INDEX (_NL_COLLATE_NRULES)].iov_len = sizeof (u_int32_t);
|
||||
|
||||
table = (u32_t *) alloca (collate->nrules * sizeof (u32_t));
|
||||
table = (u_int32_t *) alloca (collate->nrules * sizeof (u_int32_t));
|
||||
iov[2 + _NL_ITEM_INDEX (_NL_COLLATE_RULES)].iov_base = table;
|
||||
iov[2 + _NL_ITEM_INDEX (_NL_COLLATE_RULES)].iov_len
|
||||
= collate->nrules * sizeof (u32_t);
|
||||
= collate->nrules * sizeof (u_int32_t);
|
||||
/* Another trick here. Describing the collation method needs only a
|
||||
few bits (3, to be exact). But the binary file should be
|
||||
accessible by maschines with both endianesses and so we store both
|
||||
@ -366,15 +366,16 @@ Computing table size for collation information might take a while..."),
|
||||
table[cnt] = collate->rules[cnt] | SWAPU32 (collate->rules[cnt]);
|
||||
|
||||
iov[2 + _NL_ITEM_INDEX (_NL_COLLATE_HASH_SIZE)].iov_base = &table_best;
|
||||
iov[2 + _NL_ITEM_INDEX (_NL_COLLATE_HASH_SIZE)].iov_len = sizeof (u32_t);
|
||||
iov[2 + _NL_ITEM_INDEX (_NL_COLLATE_HASH_SIZE)].iov_len = sizeof (u_int32_t);
|
||||
|
||||
iov[2 + _NL_ITEM_INDEX (_NL_COLLATE_HASH_LAYERS)].iov_base = &level_best;
|
||||
iov[2 + _NL_ITEM_INDEX (_NL_COLLATE_HASH_LAYERS)].iov_len = sizeof (u32_t);
|
||||
iov[2 + _NL_ITEM_INDEX (_NL_COLLATE_HASH_LAYERS)].iov_len
|
||||
= sizeof (u_int32_t);
|
||||
|
||||
entry_size = 1 + MAX (collate->nrules, 2);
|
||||
|
||||
table = (u32_t *) alloca (table_best * level_best * entry_size
|
||||
* sizeof (table[0]));
|
||||
table = (u_int32_t *) alloca (table_best * level_best * entry_size
|
||||
* sizeof (table[0]));
|
||||
memset (table, '\0', table_best * level_best * entry_size
|
||||
* sizeof (table[0]));
|
||||
|
||||
@ -382,7 +383,7 @@ Computing table size for collation information might take a while..."),
|
||||
/* Macros for inserting in output table. */
|
||||
#define ADD_VALUE(expr) \
|
||||
do { \
|
||||
u32_t to_write = (u32_t) expr; \
|
||||
u_int32_t to_write = (u_int32_t) expr; \
|
||||
obstack_grow (&non_simple, &to_write, sizeof (to_write)); \
|
||||
} while (0)
|
||||
|
||||
@ -393,7 +394,7 @@ Computing table size for collation information might take a while..."),
|
||||
ADD_VALUE (len); \
|
||||
\
|
||||
wlen = wcslen (pelem->name); \
|
||||
obstack_grow (&non_simple, pelem->name, (wlen + 1) * sizeof (u32_t)); \
|
||||
obstack_grow (&non_simple, pelem->name, (wlen + 1) * sizeof (u_int32_t)); \
|
||||
\
|
||||
idx = collate->nrules; \
|
||||
for (cnt = 0; cnt < collate->nrules; ++cnt) \
|
||||
@ -417,14 +418,14 @@ Computing table size for collation information might take a while..."),
|
||||
table[(level * table_best + slot) * entry_size + 1] \
|
||||
= FORWARD_CHAR; \
|
||||
table[(level * table_best + slot) * entry_size + 2] \
|
||||
= obstack_object_size (&non_simple) / sizeof (u32_t); \
|
||||
= obstack_object_size (&non_simple) / sizeof (u_int32_t); \
|
||||
\
|
||||
/* Here we have to construct the non-simple table entry. First \
|
||||
compute the total length of this entry. */ \
|
||||
for (runp = (pelem); runp != NULL; runp = runp->next) \
|
||||
if (runp->ordering != NULL) \
|
||||
{ \
|
||||
u32_t value; \
|
||||
u_int32_t value; \
|
||||
size_t cnt; \
|
||||
\
|
||||
value = 1 + wcslen (runp->name) + 1; \
|
||||
@ -513,7 +514,7 @@ Computing table size for collation information might take a while..."),
|
||||
{
|
||||
/* We have to fill in the information from the UNDEFINED
|
||||
entry. */
|
||||
table[cnt * entry_size] = (u32_t) cnt;
|
||||
table[cnt * entry_size] = (u_int32_t) cnt;
|
||||
|
||||
if (collate->undefined.ordering_len == collate->nrules)
|
||||
{
|
||||
@ -593,18 +594,18 @@ Computing table size for collation information might take a while..."),
|
||||
|
||||
/* Finish the extra block. */
|
||||
extra_len = obstack_object_size (&non_simple);
|
||||
extra = (u32_t *) obstack_finish (&non_simple);
|
||||
assert ((extra_len % sizeof (u32_t)) == 0);
|
||||
extra = (u_int32_t *) obstack_finish (&non_simple);
|
||||
assert ((extra_len % sizeof (u_int32_t)) == 0);
|
||||
|
||||
/* Now we have to build the two array for the other byte ordering. */
|
||||
table2 = (u32_t *) alloca (table_best * level_best * entry_size
|
||||
* sizeof (table[0]));
|
||||
extra2 = (u32_t *) alloca (extra_len);
|
||||
table2 = (u_int32_t *) alloca (table_best * level_best * entry_size
|
||||
* sizeof (table[0]));
|
||||
extra2 = (u_int32_t *) alloca (extra_len);
|
||||
|
||||
for (cnt = 0; cnt < table_best * level_best * entry_size; ++cnt)
|
||||
table2[cnt] = SWAPU32 (table[cnt]);
|
||||
|
||||
for (cnt = 0; cnt < extra_len / sizeof (u32_t); ++cnt)
|
||||
for (cnt = 0; cnt < extra_len / sizeof (u_int32_t); ++cnt)
|
||||
extra2[cnt] = SWAPU32 (extra2[cnt]);
|
||||
|
||||
/* Store table adresses and lengths. */
|
||||
@ -639,7 +640,7 @@ Computing table size for collation information might take a while..."),
|
||||
#endif
|
||||
|
||||
iov[2 + _NL_ITEM_INDEX (_NL_COLLATE_UNDEFINED)].iov_base = &undefined_offset;
|
||||
iov[2 + _NL_ITEM_INDEX (_NL_COLLATE_UNDEFINED)].iov_len = sizeof (u32_t);
|
||||
iov[2 + _NL_ITEM_INDEX (_NL_COLLATE_UNDEFINED)].iov_len = sizeof (u_int32_t);
|
||||
|
||||
/* Update idx array. */
|
||||
idx[0] = iov[0].iov_len + iov[1].iov_len;
|
||||
|
@ -59,9 +59,9 @@ void *xrealloc (void *__ptr, size_t __n);
|
||||
/* To be compatible with former implementations we for now restrict
|
||||
the number of bits for character classes to 16. When compatibility
|
||||
is not necessary anymore increase the number to 32. */
|
||||
#define char_class_t u16_t
|
||||
#define char_class_t u_int16_t
|
||||
#define CHAR_CLASS_TRANS SWAPU16
|
||||
#define char_class32_t u32_t
|
||||
#define char_class32_t u_int32_t
|
||||
#define CHAR_CLASS32_TRANS SWAPU32
|
||||
|
||||
|
||||
@ -72,13 +72,13 @@ struct locale_ctype_t
|
||||
size_t charnames_max;
|
||||
size_t charnames_act;
|
||||
|
||||
/* We will allow up to 8 * sizeof(u32_t) - 1 character classes. */
|
||||
#define MAX_NR_CHARCLASS (8 * sizeof (u32_t) - 1)
|
||||
/* We will allow up to 8 * sizeof(u_int32_t) - 1 character classes. */
|
||||
#define MAX_NR_CHARCLASS (8 * sizeof (u_int32_t) - 1)
|
||||
int nr_charclass;
|
||||
const char *classnames[MAX_NR_CHARCLASS];
|
||||
unsigned long int current_class_mask;
|
||||
unsigned int last_class_char;
|
||||
u32_t *class_collection;
|
||||
u_int32_t *class_collection;
|
||||
size_t class_collection_max;
|
||||
size_t class_collection_act;
|
||||
unsigned long int class_done;
|
||||
@ -87,7 +87,7 @@ struct locale_ctype_t
|
||||
increase it. But I doubt it will. --drepper@gnu */
|
||||
#define MAX_NR_CHARMAP 16
|
||||
const char *mapnames[MAX_NR_CHARMAP];
|
||||
u32_t *map_collection[MAX_NR_CHARMAP];
|
||||
u_int32_t *map_collection[MAX_NR_CHARMAP];
|
||||
unsigned int map_collection_max[MAX_NR_CHARMAP];
|
||||
unsigned int map_collection_act[MAX_NR_CHARMAP];
|
||||
size_t map_collection_nr;
|
||||
@ -97,16 +97,16 @@ struct locale_ctype_t
|
||||
int tolower_done;
|
||||
|
||||
/* The arrays for the binary representation. */
|
||||
u32_t plane_size;
|
||||
u32_t plane_cnt;
|
||||
u_int32_t plane_size;
|
||||
u_int32_t plane_cnt;
|
||||
char_class_t *ctype_b;
|
||||
char_class32_t *ctype32_b;
|
||||
u32_t *names_el;
|
||||
u32_t *names_eb;
|
||||
u32_t **map_eb;
|
||||
u32_t **map_el;
|
||||
u32_t *class_name_ptr;
|
||||
u32_t *map_name_ptr;
|
||||
u_int32_t *names_el;
|
||||
u_int32_t *names_eb;
|
||||
u_int32_t **map_eb;
|
||||
u_int32_t **map_el;
|
||||
u_int32_t *class_name_ptr;
|
||||
u_int32_t *map_name_ptr;
|
||||
unsigned char *width;
|
||||
};
|
||||
|
||||
@ -117,8 +117,8 @@ static void ctype_class_newP (struct linereader *lr,
|
||||
static void ctype_map_newP (struct linereader *lr,
|
||||
struct locale_ctype_t *ctype,
|
||||
const char *name, struct charset_t *charset);
|
||||
static u32_t *find_idx (struct locale_ctype_t *ctype, u32_t **table,
|
||||
size_t *max, size_t *act, unsigned int idx);
|
||||
static u_int32_t *find_idx (struct locale_ctype_t *ctype, u_int32_t **table,
|
||||
size_t *max, size_t *act, unsigned int idx);
|
||||
static void set_class_defaults (struct locale_ctype_t *ctype,
|
||||
struct charset_t *charset);
|
||||
static void allocate_arrays (struct locale_ctype_t *ctype,
|
||||
@ -167,8 +167,9 @@ ctype_startup (struct linereader *lr, struct localedef_t *locale,
|
||||
ctype_class_newP (lr, ctype, "alnum");
|
||||
|
||||
ctype->class_collection_max = charset->mb_cur_max == 1 ? 256 : 512;
|
||||
ctype->class_collection = (u32_t *) xmalloc (sizeof (unsigned long int)
|
||||
* ctype->class_collection_max);
|
||||
ctype->class_collection
|
||||
= (u_int32_t *) xmalloc (sizeof (unsigned long int)
|
||||
* ctype->class_collection_max);
|
||||
memset (ctype->class_collection, '\0',
|
||||
sizeof (unsigned long int) * ctype->class_collection_max);
|
||||
ctype->class_collection_act = 256;
|
||||
@ -348,7 +349,7 @@ ctype_output (struct localedef_t *locale, struct charset_t *charset,
|
||||
struct iovec iov[2 + nelems + ctype->nr_charclass
|
||||
+ ctype->map_collection_nr];
|
||||
struct locale_file data;
|
||||
u32_t idx[nelems];
|
||||
u_int32_t idx[nelems];
|
||||
size_t elem, cnt, offset, total;
|
||||
|
||||
|
||||
@ -397,20 +398,20 @@ ctype_output (struct localedef_t *locale, struct charset_t *charset,
|
||||
CTYPE_DATA (_NL_CTYPE_TOUPPER_EB,
|
||||
ctype->map_eb[0],
|
||||
(ctype->plane_size * ctype->plane_cnt + 128)
|
||||
* sizeof (u32_t));
|
||||
* sizeof (u_int32_t));
|
||||
CTYPE_DATA (_NL_CTYPE_TOLOWER_EB,
|
||||
ctype->map_eb[1],
|
||||
(ctype->plane_size * ctype->plane_cnt + 128)
|
||||
* sizeof (u32_t));
|
||||
* sizeof (u_int32_t));
|
||||
|
||||
CTYPE_DATA (_NL_CTYPE_TOUPPER_EL,
|
||||
ctype->map_el[0],
|
||||
(ctype->plane_size * ctype->plane_cnt + 128)
|
||||
* sizeof (u32_t));
|
||||
* sizeof (u_int32_t));
|
||||
CTYPE_DATA (_NL_CTYPE_TOLOWER_EL,
|
||||
ctype->map_el[1],
|
||||
(ctype->plane_size * ctype->plane_cnt + 128)
|
||||
* sizeof (u32_t));
|
||||
* sizeof (u_int32_t));
|
||||
|
||||
CTYPE_DATA (_NL_CTYPE_CLASS32,
|
||||
ctype->ctype32_b,
|
||||
@ -418,16 +419,16 @@ ctype_output (struct localedef_t *locale, struct charset_t *charset,
|
||||
* sizeof (char_class32_t)));
|
||||
|
||||
CTYPE_DATA (_NL_CTYPE_NAMES_EB,
|
||||
ctype->names_eb,
|
||||
ctype->plane_size * ctype->plane_cnt * sizeof (u32_t));
|
||||
ctype->names_eb, (ctype->plane_size * ctype->plane_cnt
|
||||
* sizeof (u_int32_t)));
|
||||
CTYPE_DATA (_NL_CTYPE_NAMES_EL,
|
||||
ctype->names_el,
|
||||
ctype->plane_size * ctype->plane_cnt * sizeof (u32_t));
|
||||
ctype->names_el, (ctype->plane_size * ctype->plane_cnt
|
||||
* sizeof (u_int32_t)));
|
||||
|
||||
CTYPE_DATA (_NL_CTYPE_HASH_SIZE,
|
||||
&ctype->plane_size, sizeof (u32_t));
|
||||
&ctype->plane_size, sizeof (u_int32_t));
|
||||
CTYPE_DATA (_NL_CTYPE_HASH_LAYERS,
|
||||
&ctype->plane_cnt, sizeof (u32_t));
|
||||
&ctype->plane_cnt, sizeof (u_int32_t));
|
||||
|
||||
case _NL_ITEM_INDEX (_NL_CTYPE_CLASS_NAMES):
|
||||
/* The class name array. */
|
||||
@ -485,7 +486,7 @@ ctype_output (struct localedef_t *locale, struct charset_t *charset,
|
||||
|
||||
iov[2 + elem + offset].iov_len = ((ctype->plane_size
|
||||
* ctype->plane_cnt + 128)
|
||||
* sizeof (u32_t));
|
||||
* sizeof (u_int32_t));
|
||||
|
||||
if (elem + 1 < nelems)
|
||||
idx[elem + 1] = idx[elem] + iov[2 + elem + offset].iov_len;
|
||||
@ -825,10 +826,10 @@ implementation limit: no more than %d character maps allowed"),
|
||||
else
|
||||
ctype->map_collection_max[cnt] = max_chars;
|
||||
|
||||
ctype->map_collection[cnt] =
|
||||
(u32_t *) xmalloc (sizeof (u32_t) * ctype->map_collection_max[cnt]);
|
||||
ctype->map_collection[cnt] = (u_int32_t *)
|
||||
xmalloc (sizeof (u_int32_t) * ctype->map_collection_max[cnt]);
|
||||
memset (ctype->map_collection[cnt], '\0',
|
||||
sizeof (u32_t) * ctype->map_collection_max[cnt]);
|
||||
sizeof (u_int32_t) * ctype->map_collection_max[cnt]);
|
||||
ctype->map_collection_act[cnt] = 256;
|
||||
|
||||
++ctype->map_collection_nr;
|
||||
@ -837,8 +838,8 @@ implementation limit: no more than %d character maps allowed"),
|
||||
|
||||
/* We have to be prepared that TABLE, MAX, and ACT can be NULL. This
|
||||
is possible if we only want ot extend the name array. */
|
||||
static u32_t *
|
||||
find_idx (struct locale_ctype_t *ctype, u32_t **table, size_t *max,
|
||||
static u_int32_t *
|
||||
find_idx (struct locale_ctype_t *ctype, u_int32_t **table, size_t *max,
|
||||
size_t *act, unsigned int idx)
|
||||
{
|
||||
size_t cnt;
|
||||
@ -878,8 +879,9 @@ find_idx (struct locale_ctype_t *ctype, u32_t **table, size_t *max,
|
||||
while (*max <= cnt);
|
||||
|
||||
*table =
|
||||
(u32_t *) xrealloc (*table, *max * sizeof (unsigned long int));
|
||||
memset (&(*table)[old_max], '\0', (*max - old_max) * sizeof (u32_t));
|
||||
(u_int32_t *) xrealloc (*table, *max * sizeof (unsigned long int));
|
||||
memset (&(*table)[old_max], '\0',
|
||||
(*max - old_max) * sizeof (u_int32_t));
|
||||
}
|
||||
|
||||
(*table)[cnt] = 0;
|
||||
@ -1219,10 +1221,12 @@ Computing table size for character classes might take a while..."),
|
||||
# define NAMES_B2 ctype->names_el
|
||||
#endif
|
||||
|
||||
ctype->names_eb = (u32_t *) xcalloc (ctype->plane_size * ctype->plane_cnt,
|
||||
sizeof (u32_t));
|
||||
ctype->names_el = (u32_t *) xcalloc (ctype->plane_size * ctype->plane_cnt,
|
||||
sizeof (u32_t));
|
||||
ctype->names_eb = (u_int32_t *) xcalloc (ctype->plane_size
|
||||
* ctype->plane_cnt,
|
||||
sizeof (u_int32_t));
|
||||
ctype->names_el = (u_int32_t *) xcalloc (ctype->plane_size
|
||||
* ctype->plane_cnt,
|
||||
sizeof (u_int32_t));
|
||||
|
||||
for (idx = 1; idx < 256; ++idx)
|
||||
NAMES_B1[idx] = idx;
|
||||
@ -1286,10 +1290,10 @@ Computing table size for character classes might take a while..."),
|
||||
= TRANS32 (ctype->class_collection[idx]);
|
||||
|
||||
/* Room for table of mappings. */
|
||||
ctype->map_eb = (u32_t **) xmalloc (ctype->map_collection_nr
|
||||
* sizeof (u32_t *));
|
||||
ctype->map_el = (u32_t **) xmalloc (ctype->map_collection_nr
|
||||
* sizeof (u32_t *));
|
||||
ctype->map_eb = (u_int32_t **) xmalloc (ctype->map_collection_nr
|
||||
* sizeof (u_int32_t *));
|
||||
ctype->map_el = (u_int32_t **) xmalloc (ctype->map_collection_nr
|
||||
* sizeof (u_int32_t *));
|
||||
|
||||
/* Fill in all mappings. */
|
||||
for (idx = 0; idx < ctype->map_collection_nr; ++idx)
|
||||
@ -1297,12 +1301,12 @@ Computing table size for character classes might take a while..."),
|
||||
unsigned int idx2;
|
||||
|
||||
/* Allocate table. */
|
||||
ctype->map_eb[idx] = (u32_t *) xmalloc ((ctype->plane_size
|
||||
* ctype->plane_cnt + 128)
|
||||
* sizeof (u32_t));
|
||||
ctype->map_el[idx] = (u32_t *) xmalloc ((ctype->plane_size
|
||||
* ctype->plane_cnt + 128)
|
||||
* sizeof (u32_t));
|
||||
ctype->map_eb[idx] = (u_int32_t *) xmalloc ((ctype->plane_size
|
||||
* ctype->plane_cnt + 128)
|
||||
* sizeof (u_int32_t));
|
||||
ctype->map_el[idx] = (u_int32_t *) xmalloc ((ctype->plane_size
|
||||
* ctype->plane_cnt + 128)
|
||||
* sizeof (u_int32_t));
|
||||
|
||||
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
# define MAP_B1 ctype->map_el
|
||||
@ -1314,7 +1318,7 @@ Computing table size for character classes might take a while..."),
|
||||
|
||||
/* Copy default value (identity mapping). */
|
||||
memcpy (&MAP_B1[idx][128], NAMES_B1,
|
||||
ctype->plane_size * ctype->plane_cnt * sizeof (u32_t));
|
||||
ctype->plane_size * ctype->plane_cnt * sizeof (u_int32_t));
|
||||
|
||||
/* Copy values from collection. */
|
||||
for (idx2 = 0; idx2 < ctype->map_collection_act[idx]; ++idx2)
|
||||
@ -1336,10 +1340,10 @@ Computing table size for character classes might take a while..."),
|
||||
}
|
||||
|
||||
/* Extra array for class and map names. */
|
||||
ctype->class_name_ptr = (u32_t *) xmalloc (ctype->nr_charclass
|
||||
* sizeof (u32_t));
|
||||
ctype->map_name_ptr = (u32_t *) xmalloc (ctype->map_collection_nr
|
||||
* sizeof (u32_t));
|
||||
ctype->class_name_ptr = (u_int32_t *) xmalloc (ctype->nr_charclass
|
||||
* sizeof (u_int32_t));
|
||||
ctype->map_name_ptr = (u_int32_t *) xmalloc (ctype->map_collection_nr
|
||||
* sizeof (u_int32_t));
|
||||
|
||||
/* Array for width information. Because the expected width are very
|
||||
small we use only one single byte. This save space and we need
|
||||
|
@ -128,7 +128,7 @@ messages_output (struct localedef_t *locale, const char *output_path)
|
||||
= locale->categories[LC_MESSAGES].messages;
|
||||
struct iovec iov[2 + _NL_ITEM_INDEX (_NL_NUM_LC_MESSAGES)];
|
||||
struct locale_file data;
|
||||
u32_t idx[_NL_ITEM_INDEX (_NL_NUM_LC_MESSAGES)];
|
||||
u_int32_t idx[_NL_ITEM_INDEX (_NL_NUM_LC_MESSAGES)];
|
||||
size_t cnt = 0;
|
||||
|
||||
if ((locale->binary & (1 << LC_MESSAGES)) != 0)
|
||||
|
@ -182,7 +182,7 @@ monetary_output (struct localedef_t *locale, const char *output_path)
|
||||
= locale->categories[LC_MONETARY].monetary;
|
||||
struct iovec iov[2 + _NL_ITEM_INDEX (_NL_NUM_LC_MONETARY)];
|
||||
struct locale_file data;
|
||||
u32_t idx[_NL_ITEM_INDEX (_NL_NUM_LC_MONETARY)];
|
||||
u_int32_t idx[_NL_ITEM_INDEX (_NL_NUM_LC_MONETARY)];
|
||||
size_t cnt = 0;
|
||||
|
||||
if ((locale->binary & (1 << LC_MONETARY)) != 0)
|
||||
|
@ -102,7 +102,7 @@ numeric_output (struct localedef_t *locale, const char *output_path)
|
||||
struct locale_numeric_t *numeric = locale->categories[LC_NUMERIC].numeric;
|
||||
struct iovec iov[2 + _NL_ITEM_INDEX (_NL_NUM_LC_NUMERIC)];
|
||||
struct locale_file data;
|
||||
u32_t idx[_NL_ITEM_INDEX (_NL_NUM_LC_NUMERIC)];
|
||||
u_int32_t idx[_NL_ITEM_INDEX (_NL_NUM_LC_NUMERIC)];
|
||||
size_t cnt = 0;
|
||||
|
||||
if ((locale->binary & (1 << LC_NUMERIC)) != 0)
|
||||
|
@ -117,7 +117,7 @@ time_output (struct localedef_t *locale, const char *output_path)
|
||||
struct iovec iov[2 + _NL_ITEM_INDEX (_NL_NUM_LC_TIME)
|
||||
+ time->cur_num_alt_digits];
|
||||
struct locale_file data;
|
||||
u32_t idx[_NL_ITEM_INDEX (_NL_NUM_LC_TIME)];
|
||||
u_int32_t idx[_NL_ITEM_INDEX (_NL_NUM_LC_TIME)];
|
||||
size_t cnt, last_idx, num;
|
||||
|
||||
if ((locale->binary & (1 << LC_TIME)) != 0)
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* Copyright (C) 1995, 1996 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Ulrich Drepper, <drepper@gnu.ai.mit.edu>.
|
||||
Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
@ -36,6 +36,7 @@ Boston, MA 02111-1307, USA. */
|
||||
#include "error.h"
|
||||
#include "charset.h"
|
||||
#include "locfile.h"
|
||||
#include "../intl/loadinfo.h"
|
||||
|
||||
/* Undefine the following line in the production version. */
|
||||
/* #define NDEBUG 1 */
|
||||
@ -95,7 +96,7 @@ void *xmalloc (size_t __n);
|
||||
/* Prototypes for local functions. */
|
||||
static void usage (int status) __attribute__ ((noreturn));
|
||||
static void error_print (void);
|
||||
static const char *construct_output_path (const char *path);
|
||||
static const char *construct_output_path (char *path);
|
||||
|
||||
|
||||
int
|
||||
@ -424,25 +425,50 @@ error_print ()
|
||||
contain a '/' character it is a relativ path. Otherwise it names the
|
||||
locale this definition is for. */
|
||||
static const char *
|
||||
construct_output_path (const char *path)
|
||||
construct_output_path (char *path)
|
||||
{
|
||||
char *normal = NULL;
|
||||
char *result;
|
||||
|
||||
if (strchr (path, '/') == NULL)
|
||||
{
|
||||
/* This is a system path. */
|
||||
int path_max_len = pathconf (LOCALE_PATH, _PC_PATH_MAX) + 1;
|
||||
result = (char *) xmalloc (path_max_len);
|
||||
/* This is a system path. First examine whether the locale name
|
||||
contains a reference to the codeset. This should be
|
||||
normalized. */
|
||||
char *startp, *endp;
|
||||
|
||||
snprintf (result, path_max_len, "%s/%s", LOCALE_PATH, path);
|
||||
startp = path;
|
||||
/* We must be prepared for finding a CEN name or a location of
|
||||
the introducing `.' where it is not possible anymore. */
|
||||
while (*startp != '\0' && *startp != '@' && *startp != '.'
|
||||
&& *startp != '+' && *startp != ',')
|
||||
++startp;
|
||||
if (*startp == '.')
|
||||
{
|
||||
/* We found a codeset specification. Now find the end. */
|
||||
endp = ++startp;
|
||||
while (*endp != '\0' && *endp != '@')
|
||||
++endp;
|
||||
|
||||
if (endp > startp)
|
||||
normal = _nl_normalize_codeset (startp, endp - startp);
|
||||
}
|
||||
|
||||
/* We put an additional '\0' at the end of the string because at
|
||||
the end of the function we need another byte for the trailing
|
||||
'/'. */
|
||||
if (normal == NULL)
|
||||
asprintf (&result, "%s/%s\0", LOCALE_PATH, path);
|
||||
else
|
||||
asprintf (&result, "%s/%.*s%s%s\0", LOCALE_PATH, startp - path, path,
|
||||
normal, endp);
|
||||
}
|
||||
else
|
||||
{
|
||||
char *t;
|
||||
/* This is a user path. */
|
||||
/* This is a user path. Please note the additional byte in the
|
||||
memory allocation. */
|
||||
result = xmalloc (strlen (path) + 2);
|
||||
t = stpcpy (result, path);
|
||||
*t = '\0';
|
||||
strcpy (result, path);
|
||||
}
|
||||
|
||||
errno = 0;
|
||||
|
@ -13,14 +13,17 @@ Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If
|
||||
not, write to the Free Software Foundation, Inc., 675 Mass Ave,
|
||||
Cambridge, MA 02139, USA. */
|
||||
not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <alloca.h>
|
||||
#include <argz.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <locale.h>
|
||||
#include <langinfo.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "localeinfo.h"
|
||||
|
||||
/* For each category declare two external variables (with weak references):
|
||||
@ -33,20 +36,19 @@ Cambridge, MA 02139, USA. */
|
||||
#define DEFINE_CATEGORY(category, category_name, items, a, b, c, d) \
|
||||
extern const struct locale_data *_nl_current_##category; \
|
||||
extern const struct locale_data _nl_C_##category; \
|
||||
/* XXX The linker is broken so we cannot do the weak symbols right just now. */
|
||||
/* weak_symbol (_nl_current_##category) weak_symbol (_nl_C_##category) */
|
||||
weak_symbol (_nl_current_##category) weak_symbol (_nl_C_##category)
|
||||
#include "categories.def"
|
||||
#undef DEFINE_CATEGORY
|
||||
|
||||
/* Array indexed by category of pointers to _nl_current_CATEGORY slots.
|
||||
Elements are zero for categories whose data is never used. */
|
||||
const struct locale_data * *const _nl_current[] =
|
||||
{
|
||||
static const struct locale_data * *const _nl_current[] =
|
||||
{
|
||||
#define DEFINE_CATEGORY(category, category_name, items, a, b, c, d) \
|
||||
[category] = &_nl_current_##category,
|
||||
[category] = &_nl_current_##category,
|
||||
#include "categories.def"
|
||||
#undef DEFINE_CATEGORY
|
||||
};
|
||||
};
|
||||
|
||||
/* Array indexed by category of pointers to _nl_C_CATEGORY slots.
|
||||
Elements are zero for categories whose data is never used. */
|
||||
@ -67,6 +69,7 @@ const char *const _nl_category_names[] =
|
||||
[category] = category_name,
|
||||
#include "categories.def"
|
||||
#undef DEFINE_CATEGORY
|
||||
[LC_ALL] = "LC_ALL"
|
||||
};
|
||||
/* An array of their lengths, for convenience. */
|
||||
const size_t _nl_category_name_sizes[] =
|
||||
@ -75,6 +78,7 @@ const size_t _nl_category_name_sizes[] =
|
||||
[category] = sizeof (category_name) - 1,
|
||||
#include "categories.def"
|
||||
#undef DEFINE_CATEGORY
|
||||
[LC_ALL] = sizeof ("LC_ALL") - 1
|
||||
};
|
||||
|
||||
|
||||
@ -98,256 +102,257 @@ void (*const _nl_category_postload[]) (void) =
|
||||
};
|
||||
|
||||
|
||||
/* Name of our standard locale. */
|
||||
const char _nl_C_name[] = "C";
|
||||
|
||||
/* Name of current locale for each individual category.
|
||||
Each is malloc'd unless it is nl_C_name. */
|
||||
const char *_nl_current_names[] =
|
||||
static const char *_nl_current_names[] =
|
||||
{
|
||||
#define DEFINE_CATEGORY(category, category_name, items, a, b, c, d) \
|
||||
_nl_C_name,
|
||||
[category] = _nl_C_name,
|
||||
#include "categories.def"
|
||||
#undef DEFINE_CATEGORY
|
||||
[LC_ALL] = _nl_C_name /* For LC_ALL. */
|
||||
};
|
||||
|
||||
/* Composite LC_ALL name for current locale.
|
||||
This is malloc'd unless it's _nl_C_name. */
|
||||
char *_nl_current_composite_name = (char *) _nl_C_name;
|
||||
|
||||
|
||||
/* Switch to the locale called NAME in CATEGORY. Return a string
|
||||
describing the locale. This string can be used as the NAME argument in
|
||||
a later call. If NAME is NULL, don't switch locales, but return the
|
||||
current one. If NAME is "", switch to a locale based on the environment
|
||||
variables, as per POSIX. Return NULL on error. */
|
||||
/* Use this when we come along an error. */
|
||||
#define ERROR_RETURN \
|
||||
do { \
|
||||
errno = EINVAL; \
|
||||
return NULL; \
|
||||
} while (0)
|
||||
|
||||
|
||||
static inline char *
|
||||
clever_copy (const char *string)
|
||||
{
|
||||
size_t len;
|
||||
char *new;
|
||||
|
||||
if (strcmp (string, "C") == 0 || strcmp (string, "POSIX") == 0)
|
||||
/* This return is dangerous because the returned string might be
|
||||
placed in read-only memory. But everything should be set up to
|
||||
handle this case. */
|
||||
return (char *) _nl_C_name;
|
||||
|
||||
len = strlen (string) + 1;
|
||||
new = (char *) malloc (len);
|
||||
return new != NULL ? memcpy (new, string, len) : NULL;
|
||||
}
|
||||
|
||||
|
||||
/* Construct a new composite name. */
|
||||
static inline char *
|
||||
new_composite_name (int category, char *newnames[LC_ALL])
|
||||
{
|
||||
size_t last_len;
|
||||
size_t cumlen = 0;
|
||||
int i;
|
||||
char *new, *p;
|
||||
int same = 1;
|
||||
|
||||
for (i = 0; i < LC_ALL; ++i)
|
||||
{
|
||||
char *name = (category == LC_ALL ? newnames[i] :
|
||||
category == i ? newnames[0] :
|
||||
(char *) _nl_current_names[i]);
|
||||
last_len = strlen (name);
|
||||
cumlen += _nl_category_name_sizes[i] + 1 + last_len + 1;
|
||||
if (i > 0 && same && strcmp (name, newnames[0]) != 0)
|
||||
same = 0;
|
||||
}
|
||||
|
||||
if (same)
|
||||
{
|
||||
/* All the categories use the same name. */
|
||||
if (strcmp (newnames[0], "C") == 0 || strcmp (newnames[0], "POSIX") == 0)
|
||||
return (char *) _nl_C_name;
|
||||
|
||||
new = malloc (last_len + 1);
|
||||
if (new == NULL)
|
||||
return NULL;
|
||||
|
||||
memcpy (new, newnames[0], last_len + 1);
|
||||
return new;
|
||||
}
|
||||
|
||||
new = malloc (cumlen);
|
||||
if (new == NULL)
|
||||
return NULL;
|
||||
p = new;
|
||||
for (i = 0; i < LC_ALL; ++i)
|
||||
{
|
||||
/* Add "CATEGORY=NAME;" to the string. */
|
||||
char *name = (category == LC_ALL ? newnames[i] :
|
||||
category == i ? newnames[0] :
|
||||
(char *) _nl_current_names[i]);
|
||||
p = __stpcpy (p, _nl_category_names[i]);
|
||||
*p++ = '=';
|
||||
p = __stpcpy (p, name);
|
||||
*p++ = ';';
|
||||
}
|
||||
p[-1] = '\0'; /* Clobber the last ';'. */
|
||||
return new;
|
||||
}
|
||||
|
||||
|
||||
/* Put NAME in _nl_current_names. */
|
||||
static inline void
|
||||
setname (int category, const char *name)
|
||||
{
|
||||
if (_nl_current[category] == NULL
|
||||
&& _nl_current_names[category] != _nl_C_name)
|
||||
free ((void *) _nl_current_names[category]);
|
||||
|
||||
_nl_current_names[category] = name;
|
||||
}
|
||||
|
||||
|
||||
/* Put DATA in *_nl_current[CATEGORY]. */
|
||||
static inline void
|
||||
setdata (int category, const struct locale_data *data)
|
||||
{
|
||||
if (_nl_current[category] != NULL)
|
||||
{
|
||||
*_nl_current[category] = data;
|
||||
if (_nl_category_postload[category])
|
||||
(*_nl_category_postload[category]) ();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
char *
|
||||
setlocale (int category, const char *name)
|
||||
setlocale (int category, const char *locale)
|
||||
{
|
||||
/* Return a malloc'd copy of STRING. */
|
||||
char *copy (const char *string)
|
||||
{
|
||||
size_t len = strlen (string) + 1;
|
||||
char *new = malloc (len);
|
||||
return new ? memcpy (new, string, len) : NULL;
|
||||
}
|
||||
|
||||
/* Construct a new composite name. */
|
||||
char *new_composite_name (int category, char *newnames[LC_ALL])
|
||||
{
|
||||
size_t lens[LC_ALL], cumlen = 0;
|
||||
int i;
|
||||
char *new, *p;
|
||||
int same = 1;
|
||||
|
||||
for (i = 0; i < LC_ALL; ++i)
|
||||
{
|
||||
char *name = (category == LC_ALL ? newnames[i] :
|
||||
category == i ? newnames[0] :
|
||||
(char *) _nl_current_names[i]);
|
||||
lens[i] = strlen (name);
|
||||
cumlen += _nl_category_name_sizes[i] + 1 + lens[i] + 1;
|
||||
if (i > 0 && same && strcmp (name, newnames[0]))
|
||||
same = 0;
|
||||
}
|
||||
|
||||
if (same)
|
||||
{
|
||||
/* All the categories use the same name. */
|
||||
new = malloc (lens[0] + 1);
|
||||
if (! new)
|
||||
{
|
||||
if (!strcmp (newnames[0], "C") || !strcmp (newnames[0], "POSIX"))
|
||||
return (char *) _nl_C_name;
|
||||
return NULL;
|
||||
}
|
||||
memcpy (new, newnames[0], lens[0] + 1);
|
||||
return new;
|
||||
}
|
||||
|
||||
new = malloc (cumlen);
|
||||
if (! new)
|
||||
return NULL;
|
||||
p = new;
|
||||
for (i = 0; i < LC_ALL; ++i)
|
||||
{
|
||||
/* Add "CATEGORY=NAME;" to the string. */
|
||||
char *name = (category == LC_ALL ? newnames[i] :
|
||||
category == i ? newnames[0] :
|
||||
(char *) _nl_current_names[i]);
|
||||
memcpy (p, _nl_category_names[i], _nl_category_name_sizes[i]);
|
||||
p += _nl_category_name_sizes[i];
|
||||
*p++ = '=';
|
||||
memcpy (p, name, lens[i]);
|
||||
p += lens[i];
|
||||
*p++ = ';';
|
||||
}
|
||||
p[-1] = '\0'; /* Clobber the last ';'. */
|
||||
return new;
|
||||
}
|
||||
/* Put COMPOSITE in _nl_current_composite_name and free the old value. */
|
||||
void setcomposite (char *composite)
|
||||
{
|
||||
char *old = _nl_current_composite_name;
|
||||
_nl_current_composite_name = composite;
|
||||
if (old != _nl_C_name)
|
||||
free (old);
|
||||
}
|
||||
/* Put NAME in _nl_current_names and free the old value. */
|
||||
void setname (int category, const char *name)
|
||||
{
|
||||
const char *oldname = _nl_current_names[category];
|
||||
_nl_current_names[category] = name;
|
||||
if (oldname != _nl_C_name)
|
||||
free ((char *) oldname);
|
||||
}
|
||||
/* Put DATA in *_nl_current[CATEGORY] and free the old value. */
|
||||
void setdata (int category, struct locale_data *data)
|
||||
{
|
||||
if (_nl_current[category])
|
||||
{
|
||||
const struct locale_data *olddata = *_nl_current[category];
|
||||
*_nl_current[category] = data;
|
||||
if (_nl_category_postload[category])
|
||||
(*_nl_category_postload[category]) ();
|
||||
if (olddata != _nl_C[category])
|
||||
_nl_free_locale ((struct locale_data *) olddata);
|
||||
}
|
||||
}
|
||||
|
||||
const char *current_name;
|
||||
char *locpath_var;
|
||||
char *locale_path;
|
||||
size_t locale_path_len;
|
||||
char *composite;
|
||||
|
||||
/* Sanity check for CATEGORY argument. */
|
||||
if (category < 0 || category > LC_ALL)
|
||||
{
|
||||
errno = EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
ERROR_RETURN;
|
||||
|
||||
if (category == LC_ALL)
|
||||
current_name = _nl_current_composite_name;
|
||||
else
|
||||
current_name = _nl_current_names[category];
|
||||
/* Does user want name of current locale? */
|
||||
if (locale == NULL)
|
||||
return (char *) _nl_current_names[category];
|
||||
|
||||
if (name == NULL)
|
||||
/* Return the name of the current locale. */
|
||||
return (char *) current_name;
|
||||
|
||||
if (name == current_name)
|
||||
if (strcmp (locale, _nl_current_names[category]) == 0)
|
||||
/* Changing to the same thing. */
|
||||
return (char *) current_name;
|
||||
return (char *) _nl_current_names[category];
|
||||
|
||||
/* We perhaps really have to load some data. So we determine the
|
||||
path in which to look for the data now. But this environment
|
||||
variable must only be used when the binary has no SUID or SGID
|
||||
bit set. */
|
||||
locale_path = NULL;
|
||||
locale_path_len = 0;
|
||||
|
||||
locpath_var = getenv ("LOCPATH");
|
||||
if (locpath_var != NULL && locpath_var[0] != '\0'
|
||||
&& __getuid () == __geteuid () && __getgid () == __getegid ())
|
||||
if (__argz_create_sep (locpath_var, ':',
|
||||
&locale_path, &locale_path_len) != 0)
|
||||
return NULL;
|
||||
|
||||
if (__argz_append (&locale_path, &locale_path_len,
|
||||
LOCALE_PATH, sizeof (LOCALE_PATH)) != 0)
|
||||
return NULL;
|
||||
|
||||
if (category == LC_ALL)
|
||||
{
|
||||
const size_t len = strlen (name) + 1;
|
||||
/* The user wants to set all categories. The desired locales
|
||||
for the individual categories can be selected by using a
|
||||
composite locale name. This is a semi-colon separated list
|
||||
of entries of the form `CATEGORY=VALUE'. */
|
||||
char *newnames[LC_ALL];
|
||||
char *p;
|
||||
struct locale_data *newdata[LC_ALL];
|
||||
const struct locale_data *newdata[LC_ALL];
|
||||
|
||||
/* Set all name pointers to the argument name. */
|
||||
for (category = 0; category < LC_ALL; ++category)
|
||||
newnames[category] = (char *) name;
|
||||
|
||||
p = strchr (name, ';');
|
||||
if (p)
|
||||
newnames[category] = (char *) locale;
|
||||
|
||||
if (strchr (locale, ';') != NULL)
|
||||
{
|
||||
/* This is a composite name. Make a local copy and split it up. */
|
||||
int i;
|
||||
char *n = alloca (len);
|
||||
memcpy (n, name, len);
|
||||
/* This is a composite name. Make a copy and split it up. */
|
||||
char *np = strdupa (locale);
|
||||
char *cp;
|
||||
int cnt;
|
||||
|
||||
while ((p = strchr (n, '=')) != NULL)
|
||||
while ((cp = strchr (np, '=')) != NULL)
|
||||
{
|
||||
for (i = 0; i < LC_ALL; ++i)
|
||||
if (_nl_category_name_sizes[i] == p - n &&
|
||||
!memcmp (_nl_category_names[i], n, p - n))
|
||||
for (cnt = 0; cnt < LC_ALL; ++cnt)
|
||||
if (cp - np == _nl_category_name_sizes[cnt]
|
||||
&& memcmp (np, _nl_category_names[cnt], cp - np) == 0)
|
||||
break;
|
||||
if (i == LC_ALL)
|
||||
|
||||
if (cnt == LC_ALL)
|
||||
/* Bogus category name. */
|
||||
ERROR_RETURN;
|
||||
|
||||
/* Found the category this clause sets. */
|
||||
newnames[cnt] = ++cp;
|
||||
cp = strchr (cp, ';');
|
||||
if (cp != NULL)
|
||||
{
|
||||
/* Bogus category name. */
|
||||
errno = EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
if (i < LC_ALL)
|
||||
{
|
||||
/* Found the category this clause sets. */
|
||||
char *end = strchr (++p, ';');
|
||||
newnames[i] = p;
|
||||
if (end)
|
||||
{
|
||||
/* Examine the next clause. */
|
||||
*end = '\0';
|
||||
n = end + 1;
|
||||
}
|
||||
else
|
||||
/* This was the last clause. We are done. */
|
||||
break;
|
||||
/* Examine the next clause. */
|
||||
*cp = '\0';
|
||||
np = cp + 1;
|
||||
}
|
||||
else
|
||||
/* This was the last clause. We are done. */
|
||||
break;
|
||||
}
|
||||
|
||||
for (i = 0; i < LC_ALL; ++i)
|
||||
if (newnames[i] == name)
|
||||
for (cnt = 0; cnt < LC_ALL; ++cnt)
|
||||
if (newnames[cnt] == locale)
|
||||
/* The composite name did not specify all categories. */
|
||||
return NULL;
|
||||
ERROR_RETURN;
|
||||
}
|
||||
|
||||
/* Load the new data for each category. */
|
||||
while (category-- > 0)
|
||||
/* Only actually load the data if anything will use it. */
|
||||
if (_nl_current[category])
|
||||
if (_nl_current[category] != NULL)
|
||||
{
|
||||
newdata[category] = _nl_load_locale (category,
|
||||
newdata[category] = _nl_find_locale (locale_path, locale_path_len,
|
||||
category,
|
||||
&newnames[category]);
|
||||
if (newdata[category])
|
||||
newnames[category] = copy (newnames[category]);
|
||||
if (! newdata[category] || ! newnames[category])
|
||||
|
||||
if (newdata[category] == NULL)
|
||||
{
|
||||
if (!strcmp (newnames[category], "C") ||
|
||||
!strcmp (newnames[category], "POSIX"))
|
||||
{
|
||||
/* Loading from a file failed, but this is a request
|
||||
for the default locale. Use the built-in data. */
|
||||
if (! newdata[category])
|
||||
newdata[category]
|
||||
= (struct locale_data *) _nl_C[category];
|
||||
newnames[category] = (char *) _nl_C_name;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Loading this part of the locale failed.
|
||||
Abort the composite load. */
|
||||
abort_composite:
|
||||
while (++category < LC_ALL)
|
||||
{
|
||||
if (_nl_current[category])
|
||||
_nl_free_locale (newdata[category]);
|
||||
if (newnames[category] != _nl_C_name)
|
||||
free (newnames[category]);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
/* Loading this part of the locale failed. Abort the
|
||||
composite load. */
|
||||
int save_errno;
|
||||
abort_composite:
|
||||
save_errno = errno;
|
||||
|
||||
while (++category < LC_ALL)
|
||||
if (_nl_current[category] != NULL)
|
||||
_nl_free_locale (newdata[category]);
|
||||
else
|
||||
if (_nl_current[category] == NULL
|
||||
&& newnames[category] != _nl_C_name)
|
||||
free (newnames[category]);
|
||||
|
||||
errno = save_errno;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The data is never used; just change the name. */
|
||||
newnames[category] = copy (newnames[category]);
|
||||
if (! newnames[category])
|
||||
{
|
||||
if (!strcmp (newnames[category], "C") ||
|
||||
!strcmp (newnames[category], "POSIX"))
|
||||
newnames[category] = (char *) _nl_C_name;
|
||||
else
|
||||
{
|
||||
while (++category < LC_ALL)
|
||||
if (newnames[category] != _nl_C_name)
|
||||
free (newnames[category]);
|
||||
}
|
||||
}
|
||||
newnames[category] = clever_copy (newnames[category]);
|
||||
if (newnames[category] == NULL)
|
||||
goto abort_composite;
|
||||
}
|
||||
|
||||
/* Create new composite name. */
|
||||
composite = new_composite_name (LC_ALL, newnames);
|
||||
if (! composite)
|
||||
if (composite == NULL)
|
||||
{
|
||||
category = -1;
|
||||
goto abort_composite;
|
||||
@ -359,46 +364,45 @@ setlocale (int category, const char *name)
|
||||
setdata (category, newdata[category]);
|
||||
setname (category, newnames[category]);
|
||||
}
|
||||
setcomposite (composite);
|
||||
setname (LC_ALL, composite);
|
||||
|
||||
return composite;
|
||||
}
|
||||
else
|
||||
{
|
||||
char *newname = copy (name);
|
||||
if (! newname)
|
||||
const struct locale_data *newdata;
|
||||
char *newname;
|
||||
|
||||
if (_nl_current[category] != NULL)
|
||||
{
|
||||
if (!strcmp (name, "C") || !strcmp (name, "POSIX"))
|
||||
newname = (char *) _nl_C_name;
|
||||
else
|
||||
/* Only actually load the data if anything will use it. */
|
||||
newname = (char *) locale;
|
||||
newdata = _nl_find_locale (locale_path, locale_path_len, category,
|
||||
(char **) &newname);
|
||||
if (newdata == NULL)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Create new composite name. */
|
||||
composite = new_composite_name (category, &newname);
|
||||
if (! composite)
|
||||
if (composite == NULL)
|
||||
{
|
||||
if (newname != _nl_C_name)
|
||||
free (newname);
|
||||
/* If anything went wrong free what we managed to allocate
|
||||
so far. */
|
||||
int save_errno = errno;
|
||||
|
||||
if (_nl_current[category] != NULL)
|
||||
_nl_free_locale (newdata);
|
||||
|
||||
errno = save_errno;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Only actually load the data if anything will use it. */
|
||||
if (_nl_current[category])
|
||||
{
|
||||
struct locale_data *newdata = _nl_load_locale (category,
|
||||
(char **) &name);
|
||||
if (! newdata)
|
||||
{
|
||||
if (!strcmp (name, "C") || !strcmp (name, "POSIX"))
|
||||
newdata = (struct locale_data *) _nl_C[category];
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
setdata (category, newdata);
|
||||
}
|
||||
if (_nl_current[category] != NULL)
|
||||
setdata (category, newdata);
|
||||
|
||||
setname (category, newname);
|
||||
setcomposite (composite);
|
||||
setname (LC_ALL, composite);
|
||||
|
||||
return newname;
|
||||
}
|
||||
|
@ -35,7 +35,7 @@ typedef struct weight_t
|
||||
struct weight_t *next;
|
||||
struct data_pair
|
||||
{
|
||||
size_t number;
|
||||
int number;
|
||||
const u_int32_t *value;
|
||||
} data[0];
|
||||
} weight_t;
|
||||
@ -115,7 +115,7 @@ get_weight (const STRING_TYPE **str, weight_t *result)
|
||||
{
|
||||
size_t idx;
|
||||
|
||||
/* This is a comparison between a u32_t array (aka wchar_t) and
|
||||
/* This is a comparison between a u_int32_t array (aka wchar_t) and
|
||||
an 8-bit string. */
|
||||
for (idx = 0; __collate_extra[slot + 2 + idx] != 0; ++idx)
|
||||
if (__collate_extra[slot + 2 + idx] != (u_int32_t) str[idx])
|
||||
|
@ -33,11 +33,11 @@ routines := strcat strchr strcmp strcoll strcpy strcspn strdup \
|
||||
strcasecmp strncase \
|
||||
memccpy memcpy wordcopy strsep \
|
||||
swab strfry memfrob memmem \
|
||||
$(addprefix argz-,append count create \
|
||||
$(addprefix argz-,append count create ctsep next \
|
||||
delete extract insert stringify) \
|
||||
envz
|
||||
|
||||
tests := tester testcopy test-ffs
|
||||
tests := tester testcopy test-ffs tst-strlen
|
||||
distribute := memcopy.h pagecopy.h
|
||||
|
||||
|
||||
|
60
string/argz-ctsep.c
Normal file
60
string/argz-ctsep.c
Normal file
@ -0,0 +1,60 @@
|
||||
/* Copyright (C) 1996 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1996.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If
|
||||
not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <argz.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
error_t
|
||||
__argz_create_sep (const char *string, int delim, char **argz, size_t *len)
|
||||
{
|
||||
size_t nlen = strlen (string) + 1;
|
||||
|
||||
if (nlen != 0)
|
||||
{
|
||||
const char *rp;
|
||||
char *wp;
|
||||
|
||||
*argz = (char *) malloc (nlen);
|
||||
if (*argz == NULL)
|
||||
return ENOMEM;
|
||||
|
||||
rp = string;
|
||||
wp = *argz;
|
||||
do
|
||||
if (*rp == delim)
|
||||
{
|
||||
if (wp > *argz && wp[-1] != '\0')
|
||||
*wp++ = '\0';
|
||||
else
|
||||
--nlen;
|
||||
}
|
||||
else
|
||||
*wp++ = *rp;
|
||||
while (*rp++ != '\0');
|
||||
}
|
||||
if (nlen == 0)
|
||||
*argz = NULL;
|
||||
*len = nlen;
|
||||
|
||||
return 0;
|
||||
}
|
||||
weak_alias (__argz_create_sep, argz_create_sep)
|
39
string/argz-next.c
Normal file
39
string/argz-next.c
Normal file
@ -0,0 +1,39 @@
|
||||
/* Iterate through the elements of an argz block.
|
||||
Copyright (C) 1995, 1996 Free Software Foundation, Inc.
|
||||
|
||||
Written by Miles Bader <miles@gnu.ai.mit.edu>
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2, or (at
|
||||
your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#include <argz.h>
|
||||
#include <string.h>
|
||||
|
||||
char *
|
||||
__argz_next (char *argz, size_t argz_len, const char *entry)
|
||||
{
|
||||
if (entry)
|
||||
{
|
||||
if (entry < argz + argz_len)
|
||||
entry = strchr (entry, '\0') + 1;
|
||||
|
||||
return entry >= argz + argz_len ? NULL : entry;
|
||||
}
|
||||
else
|
||||
if (argz_len > 0)
|
||||
return argz;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
weak_alias (__argz_next, argz_next)
|
@ -20,42 +20,59 @@
|
||||
|
||||
#ifndef __ARGZ_H__
|
||||
#define __ARGZ_H__ 1
|
||||
|
||||
#include <features.h>
|
||||
|
||||
#include <errno.h> /* Define error_t. */
|
||||
#include <string.h> /* Need size_t, and strchr is called below. */
|
||||
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
/* Make a '\0' separated arg vector from a unix argv vector, returning it in
|
||||
ARGZ, and the total length in LEN. If a memory allocation error occurs,
|
||||
ENOMEM is returned, otherwise 0. The result can be destroyed using free. */
|
||||
error_t __argz_create (char **argv, char **argz, size_t *len);
|
||||
error_t argz_create (char **argv, char **argz, size_t *len);
|
||||
error_t __argz_create __P ((char **__argv, char **__argz, size_t *__len));
|
||||
error_t argz_create __P ((char **__argv, char **__argz, size_t *__len));
|
||||
|
||||
/* Make a '\0' separated arg vector from a SEP separated list in
|
||||
STRING, returning it in ARGZ, and the total length in LEN. If a
|
||||
memory allocation error occurs, ENOMEM is returned, otherwise 0.
|
||||
The result can be destroyed using free. */
|
||||
error_t __argz_create_sep __P ((__const char *__string, int __sep,
|
||||
char **__argz, size_t *__len));
|
||||
error_t argz_create_sep __P ((__const char *__string, int __sep,
|
||||
char **__argz, size_t *__len));
|
||||
|
||||
/* Returns the number of strings in ARGZ. */
|
||||
size_t __argz_count (const char *argz, size_t len);
|
||||
size_t argz_count (const char *argz, size_t len);
|
||||
size_t __argz_count __P ((__const char *__argz, size_t __len));
|
||||
size_t argz_count __P ((__const char *__argz, size_t __len));
|
||||
|
||||
/* Puts pointers to each string in ARGZ into ARGV, which must be large enough
|
||||
to hold them all. */
|
||||
void __argz_extract (const char *argz, size_t len, char **argv);
|
||||
void argz_extract (const char *argz, size_t len, char **argv);
|
||||
void __argz_extract __P ((__const char *__argz, size_t __len, char **__argv));
|
||||
void argz_extract __P ((__const char *__argz, size_t __len, char **__argv));
|
||||
|
||||
/* Make '\0' separated arg vector ARGZ printable by converting all the '\0's
|
||||
except the last into the character SEP. */
|
||||
void __argz_stringify (char *argz, size_t len, int sep);
|
||||
void argz_stringify (char *argz, size_t len, int sep);
|
||||
void __argz_stringify __P ((char *__argz, size_t __len, int __sep));
|
||||
void argz_stringify __P ((char *__argz, size_t __len, int __sep));
|
||||
|
||||
/* Append BUF, of length BUF_LEN to the argz vector in ARGZ & ARGZ_LEN. */
|
||||
error_t __argz_append (char **argz, size_t *argz_len,
|
||||
const char *buf, size_t buf_len);
|
||||
error_t argz_append (char **argz, size_t *argz_len,
|
||||
const char *buf, size_t buf_len);
|
||||
error_t __argz_append __P ((char **__argz, size_t *__argz_len,
|
||||
__const char *__buf, size_t __buf_len));
|
||||
error_t argz_append __P ((char **__argz, size_t *__argz_len,
|
||||
__const char *__buf, size_t __buf_len));
|
||||
|
||||
/* Append STR to the argz vector in ARGZ & ARGZ_LEN. */
|
||||
error_t __argz_add (char **argz, size_t *argz_len, const char *str);
|
||||
error_t argz_add (char **argz, size_t *argz_len, const char *str);
|
||||
error_t __argz_add __P ((char **__argz, size_t *__argz_len,
|
||||
__const char *__str));
|
||||
error_t argz_add __P ((char **__argz, size_t *__argz_len,
|
||||
__const char *__str));
|
||||
|
||||
/* Delete ENTRY from ARGZ & ARGZ_LEN, if it appears there. */
|
||||
void __argz_delete (char **argz, size_t *argz_len, char *entry);
|
||||
void argz_delete (char **argz, size_t *argz_len, char *entry);
|
||||
void __argz_delete __P ((char **__argz, size_t *__argz_len, char *__entry));
|
||||
void argz_delete __P ((char **__argz, size_t *__argz_len, char *__entry));
|
||||
|
||||
/* Insert ENTRY into ARGZ & ARGZ_LEN before BEFORE, which should be an
|
||||
existing entry in ARGZ; if BEFORE is NULL, ENTRY is appended to the end.
|
||||
@ -63,17 +80,17 @@ void argz_delete (char **argz, size_t *argz_len, char *entry);
|
||||
ARGZ, ENTRY) will insert ENTRY at the beginning of ARGZ. If BEFORE is not
|
||||
in ARGZ, EINVAL is returned, else if memory can't be allocated for the new
|
||||
ARGZ, ENOMEM is returned, else 0. */
|
||||
error_t __argz_insert (char **argz, size_t *argz_len,
|
||||
char *before, const char *entry);
|
||||
error_t argz_insert (char **argz, size_t *argz_len,
|
||||
char *before, const char *entry);
|
||||
error_t __argz_insert __P ((char **__argz, size_t *__argz_len,
|
||||
char *__before, __const char *__entry));
|
||||
error_t argz_insert __P ((char **__argz, size_t *__argz_len,
|
||||
char *__before, __const char *__entry));
|
||||
|
||||
/* Returns the next entry in ARGZ & ARGZ_LEN after ENTRY, or NULL if there
|
||||
are no more. If entry is NULL, then the first entry is returned. This
|
||||
behavior allows two convenient iteration styles:
|
||||
|
||||
char *entry = 0;
|
||||
while (entry = argz_next (argz, argz_len, entry))
|
||||
while ((entry = argz_next (argz, argz_len, entry)))
|
||||
...;
|
||||
|
||||
or
|
||||
@ -82,19 +99,33 @@ error_t argz_insert (char **argz, size_t *argz_len,
|
||||
for (entry = argz; entry; entry = argz_next (argz, argz_len, entry))
|
||||
...;
|
||||
*/
|
||||
extern char *__argz_next __P ((char *__argz, size_t __argz_len,
|
||||
__const char *__entry));
|
||||
extern char *argz_next __P ((char *__argz, size_t __argz_len,
|
||||
__const char *__entry));
|
||||
|
||||
#if defined (__OPTIMIZE__) && __GNUC__ >= 2
|
||||
extern inline char *
|
||||
argz_next (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)
|
||||
return 0;
|
||||
else
|
||||
return strchr (entry, '\0') + 1;
|
||||
{
|
||||
if (entry < argz + argz_len)
|
||||
entry = strchr (entry, '\0') + 1;
|
||||
|
||||
return entry >= argz + argz_len ? NULL : entry;
|
||||
}
|
||||
else
|
||||
if (argz_len > 0)
|
||||
return argz;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
extern inline char *
|
||||
argz_next (char *argz, size_t argz_len, const char *entry)
|
||||
{
|
||||
return __argz_next (argz, argz_len, entry);
|
||||
}
|
||||
#endif /* optimizing GCC2 */
|
||||
|
||||
#endif /* __ARGZ_H__ */
|
||||
|
@ -29,8 +29,8 @@
|
||||
/* Returns a pointer to the entry in ENVZ for NAME, or 0 if there is none.
|
||||
If NAME contains the separator character, only the portion before it is
|
||||
used in the comparison. */
|
||||
char *
|
||||
envz_entry (char *envz, unsigned envz_len, char *name)
|
||||
const char *
|
||||
envz_entry (const char *envz, size_t envz_len, const char *name)
|
||||
{
|
||||
while (envz_len)
|
||||
{
|
||||
@ -57,8 +57,8 @@ envz_entry (char *envz, unsigned envz_len, char *name)
|
||||
|
||||
/* Returns a pointer to the value portion of the entry in ENVZ for NAME, or 0
|
||||
if there is none. */
|
||||
char *
|
||||
envz_get (char *envz, unsigned envz_len, char *name)
|
||||
const char *
|
||||
envz_get (const char *envz, size_t envz_len, const char *name)
|
||||
{
|
||||
char *entry = envz_entry (envz, envz_len, name);
|
||||
if (entry)
|
||||
@ -75,7 +75,7 @@ envz_get (char *envz, unsigned envz_len, char *name)
|
||||
|
||||
/* Remove the entry for NAME from ENVZ & ENVZ_LEN, if any. */
|
||||
void
|
||||
envz_remove (char **envz, unsigned *envz_len, char *name)
|
||||
envz_remove (char **envz, size_t *envz_len, char *name)
|
||||
{
|
||||
char *entry = envz_entry (*envz, *envz_len, name);
|
||||
if (entry)
|
||||
@ -89,7 +89,7 @@ envz_remove (char **envz, unsigned *envz_len, char *name)
|
||||
because when merging with another envz, the null entry can override an
|
||||
entry in the other one. Null entries can be removed with envz_strip (). */
|
||||
error_t
|
||||
envz_add (char **envz, unsigned *envz_len, char *name, char *value)
|
||||
envz_add (char **envz, unsigned *envz_len, const char *name, const char *value)
|
||||
{
|
||||
envz_remove (envz, envz_len, name);
|
||||
|
||||
@ -126,8 +126,8 @@ envz_add (char **envz, unsigned *envz_len, char *name, char *value)
|
||||
OVERRIDE is true, then values in ENVZ2 will supercede those with the same
|
||||
name in ENV, otherwise not. */
|
||||
error_t
|
||||
envz_merge (char **envz, unsigned *envz_len, char *envz2, unsigned envz2_len,
|
||||
int override)
|
||||
envz_merge (char **envz, unsigned *envz_len, const char *envz2,
|
||||
size_t envz2_len, int override)
|
||||
{
|
||||
error_t err = 0;
|
||||
|
||||
|
@ -28,11 +28,13 @@
|
||||
#include <argz.h>
|
||||
|
||||
/* Returns a pointer to the entry in ENVZ for NAME, or 0 if there is none. */
|
||||
char *envz_entry (const char *envz, size_t envz_len, const char *name);
|
||||
const char *envz_entry __P ((__const char *__envz, size_t __envz_len,
|
||||
__const char *__name));
|
||||
|
||||
/* Returns a pointer to the value portion of the entry in ENVZ for NAME, or 0
|
||||
if there is none. */
|
||||
char *envz_get (const char *envz, size_t envz_len, const char *name);
|
||||
const char *envz_get __P ((__const char *__envz, size_t __envz_len,
|
||||
__const char *__name));
|
||||
|
||||
/* Adds an entry for NAME with value VALUE to ENVZ & ENVZ_LEN. If an entry
|
||||
with the same name already exists in ENVZ, it is removed. If VALUE is
|
||||
@ -40,17 +42,17 @@ char *envz_get (const char *envz, size_t envz_len, const char *name);
|
||||
return NULL, although envz_entry will still return an entry; this is handy
|
||||
because when merging with another envz, the null entry can override an
|
||||
entry in the other one. Null entries can be removed with envz_strip (). */
|
||||
error_t envz_add (char **envz, size_t *envz_len,
|
||||
const char *name, const char *value);
|
||||
error_t envz_add __P ((char **__envz, size_t *__envz_len,
|
||||
__const char *__name, __const char *__value));
|
||||
|
||||
/* Adds each entry in ENVZ2 to ENVZ & ENVZ_LEN, as if with envz_add(). If
|
||||
OVERRIDE is true, then values in ENVZ2 will supercede those with the same
|
||||
name in ENV, otherwise not. */
|
||||
error_t envz_merge (char **envz, size_t *envz_len,
|
||||
const char *envz2, size_t envz2_len,
|
||||
int override);
|
||||
error_t envz_merge __P ((char **__envz, size_t *__envz_len,
|
||||
__const char *__envz2, size_t __envz2_len,
|
||||
int __override));
|
||||
|
||||
/* Remove null entries. */
|
||||
void envz_strip (char **envz, size_t *envz_len);
|
||||
void envz_strip __P ((char **__envz, size_t *__envz_len));
|
||||
|
||||
#endif /* __ENVZ_H__ */
|
||||
|
@ -71,7 +71,7 @@ STRCOLL (s1, s2)
|
||||
{
|
||||
int s1ignore = 0;
|
||||
int s2ignore = 0;
|
||||
u32_t w1, w2;
|
||||
u_int32_t w1, w2;
|
||||
|
||||
/* Here we have to check for IGNORE entries. If these are
|
||||
found we count them and go on witht he next value. */
|
||||
|
32
string/tst-strlen.c
Normal file
32
string/tst-strlen.c
Normal file
@ -0,0 +1,32 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
static const lens[16] = { 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4 };
|
||||
char buf[24];
|
||||
int words;
|
||||
|
||||
for (words = 0; words < 4; ++words)
|
||||
{
|
||||
int last;
|
||||
memset (buf, 'a', words * 4);
|
||||
|
||||
for (last = 0; last < 16; ++last)
|
||||
{
|
||||
buf[words * 4 + 0] = (last & 1) != 0 ? 'b' : '\0';
|
||||
buf[words * 4 + 1] = (last & 2) != 0 ? 'c' : '\0';
|
||||
buf[words * 4 + 2] = (last & 4) != 0 ? 'd' : '\0';
|
||||
buf[words * 4 + 3] = (last & 8) != 0 ? 'e' : '\0';
|
||||
buf[words * 4 + 4] = '\0';
|
||||
|
||||
if (strlen (buf) != words * 4 + lens[last])
|
||||
{
|
||||
printf ("failed for words=%d and last=%d\n", words, last);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
@ -52,12 +52,12 @@ static struct proglst {
|
||||
} *proglst;
|
||||
static void universal();
|
||||
static SVCXPRT *transp;
|
||||
struct proglst *pl;
|
||||
|
||||
registerrpc(prognum, versnum, procnum, progname, inproc, outproc)
|
||||
char *(*progname)();
|
||||
xdrproc_t inproc, outproc;
|
||||
{
|
||||
struct proglst *pl;
|
||||
|
||||
if (procnum == NULLPROC) {
|
||||
(void) fprintf(stderr,
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* strlen -- Compute length og NUL terminated string.
|
||||
Highly optimized version for ix86, x>=5.
|
||||
Copyright (C) 1995 Free Software Foundation, Inc.
|
||||
Copyright (C) 1995, 1996 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Ulrich Drepper, <drepper@gnu.ai.mit.edu>.
|
||||
|
||||
@ -102,7 +102,6 @@ L1:
|
||||
jnc L3 /* previous addl caused overflow? */
|
||||
|
||||
xorl %ecx, %edx /* (word+magic)^word */
|
||||
subl $magic, %ecx /* undo previous addl to restore word */
|
||||
|
||||
andl $~magic, %edx /* any of the carry flags set? */
|
||||
|
||||
@ -119,7 +118,6 @@ L1:
|
||||
jnc L3 /* previous addl caused overflow? */
|
||||
|
||||
xorl %ecx, %edx /* (word+magic)^word */
|
||||
subl $magic, %ecx /* undo previous addl to restore word */
|
||||
|
||||
andl $~magic, %edx /* any of the carry flags set? */
|
||||
|
||||
@ -136,7 +134,6 @@ L1:
|
||||
jnc L3 /* previous addl caused overflow? */
|
||||
|
||||
xorl %ecx, %edx /* (word+magic)^word */
|
||||
subl $magic, %ecx /* undo previous addl to restore word */
|
||||
|
||||
andl $~magic, %edx /* any of the carry flags set? */
|
||||
|
||||
@ -149,11 +146,10 @@ L1:
|
||||
subl %ecx, %edx /* first step to negate word */
|
||||
addl $magic, %ecx /* add magic word */
|
||||
|
||||
decl %edx /* wcomplete negation of ord */
|
||||
decl %edx /* complete negation of word */
|
||||
jnc L3 /* previous addl caused overflow? */
|
||||
|
||||
xorl %ecx, %edx /* (word+magic)^word */
|
||||
subl $magic, %ecx /* undo previous addl to restore word */
|
||||
|
||||
andl $~magic, %edx /* any of the carry flags set? */
|
||||
|
||||
@ -161,8 +157,9 @@ L1:
|
||||
|
||||
|
||||
L3: subl $4, %eax /* correct too early pointer increment */
|
||||
testb %cl, %cl /* lowest byte NUL? */
|
||||
subl $magic, %ecx
|
||||
|
||||
cmpb $0, %cl /* lowest byte NUL? */
|
||||
jz L2 /* yes => return */
|
||||
|
||||
inc %eax /* increment pointer */
|
||||
|
@ -79,7 +79,7 @@ static float zero = 0.0;
|
||||
* j0(x) = 1/sqrt(pi) * (P(0,x)*cc - Q(0,x)*ss) / sqrt(x)
|
||||
* y0(x) = 1/sqrt(pi) * (P(0,x)*ss + Q(0,x)*cc) / sqrt(x)
|
||||
*/
|
||||
if(ix>0x80000000) z = (invsqrtpi*cc)/__sqrtf(x);
|
||||
if(ix>0x48000000) z = (invsqrtpi*cc)/__sqrtf(x);
|
||||
else {
|
||||
u = pzerof(x); v = qzerof(x);
|
||||
z = invsqrtpi*(u*cc-v*ss)/__sqrtf(x);
|
||||
@ -161,7 +161,7 @@ v04 = 4.4111031494e-10; /* 0x2ff280c2 */
|
||||
if ((s*c)<zero) cc = z/ss;
|
||||
else ss = z/cc;
|
||||
}
|
||||
if(ix>0x80000000) z = (invsqrtpi*ss)/__sqrtf(x);
|
||||
if(ix>0x48000000) z = (invsqrtpi*ss)/__sqrtf(x);
|
||||
else {
|
||||
u = pzerof(x); v = qzerof(x);
|
||||
z = invsqrtpi*(u*ss+v*cc)/__sqrtf(x);
|
||||
|
@ -80,7 +80,7 @@ static float zero = 0.0;
|
||||
* j1(x) = 1/sqrt(pi) * (P(1,x)*cc - Q(1,x)*ss) / sqrt(x)
|
||||
* y1(x) = 1/sqrt(pi) * (P(1,x)*ss + Q(1,x)*cc) / sqrt(x)
|
||||
*/
|
||||
if(ix>0x80000000) z = (invsqrtpi*cc)/__sqrtf(y);
|
||||
if(ix>0x48000000) z = (invsqrtpi*cc)/__sqrtf(y);
|
||||
else {
|
||||
u = ponef(y); v = qonef(y);
|
||||
z = invsqrtpi*(u*cc-v*ss)/__sqrtf(y);
|
||||
|
@ -17,7 +17,6 @@ not, write to the Free Software Foundation, Inc., 675 Mass Ave,
|
||||
Cambridge, MA 02139, USA. */
|
||||
|
||||
#include <ansidecl.h>
|
||||
#define __NO_MATH_INLINES
|
||||
#include <math.h>
|
||||
|
||||
#ifndef FUNC
|
||||
|
@ -17,7 +17,6 @@ not, write to the Free Software Foundation, Inc., 675 Mass Ave,
|
||||
Cambridge, MA 02139, USA. */
|
||||
|
||||
#include <ansidecl.h>
|
||||
#define __NO_MATH_INLINES
|
||||
#include <math.h>
|
||||
|
||||
#ifndef FUNC
|
||||
|
@ -17,7 +17,6 @@ not, write to the Free Software Foundation, Inc., 675 Mass Ave,
|
||||
Cambridge, MA 02139, USA. */
|
||||
|
||||
#include <ansidecl.h>
|
||||
#define __NO_MATH_INLINES
|
||||
#include <math.h>
|
||||
|
||||
#ifndef FUNC
|
||||
|
@ -17,7 +17,6 @@ not, write to the Free Software Foundation, Inc., 675 Mass Ave,
|
||||
Cambridge, MA 02139, USA. */
|
||||
|
||||
#include <ansidecl.h>
|
||||
#define __NO_MATH_INLINES
|
||||
#include <math.h>
|
||||
|
||||
#ifndef FUNC
|
||||
|
@ -17,7 +17,6 @@ not, write to the Free Software Foundation, Inc., 675 Mass Ave,
|
||||
Cambridge, MA 02139, USA. */
|
||||
|
||||
#include <ansidecl.h>
|
||||
#define __NO_MATH_INLINES
|
||||
#include <math.h>
|
||||
|
||||
int
|
||||
|
@ -17,7 +17,6 @@ not, write to the Free Software Foundation, Inc., 675 Mass Ave,
|
||||
Cambridge, MA 02139, USA. */
|
||||
|
||||
#include <ansidecl.h>
|
||||
#define __NO_MATH_INLINES
|
||||
#include <math.h>
|
||||
|
||||
int
|
||||
|
@ -17,7 +17,6 @@ not, write to the Free Software Foundation, Inc., 675 Mass Ave,
|
||||
Cambridge, MA 02139, USA. */
|
||||
|
||||
#include <ansidecl.h>
|
||||
#define __NO_MATH_INLINES
|
||||
#include <math.h>
|
||||
|
||||
#ifndef FUNC
|
||||
|
@ -17,7 +17,6 @@ not, write to the Free Software Foundation, Inc., 675 Mass Ave,
|
||||
Cambridge, MA 02139, USA. */
|
||||
|
||||
#include <ansidecl.h>
|
||||
#define __NO_MATH_INLINES
|
||||
#include <math.h>
|
||||
|
||||
#ifndef FUNC
|
||||
|
@ -17,7 +17,6 @@ not, write to the Free Software Foundation, Inc., 675 Mass Ave,
|
||||
Cambridge, MA 02139, USA. */
|
||||
|
||||
#include <ansidecl.h>
|
||||
#define __NO_MATH_INLINES
|
||||
#include <math.h>
|
||||
|
||||
double
|
||||
|
@ -17,7 +17,6 @@ not, write to the Free Software Foundation, Inc., 675 Mass Ave,
|
||||
Cambridge, MA 02139, USA. */
|
||||
|
||||
#include <ansidecl.h>
|
||||
#define __NO_MATH_INLINES
|
||||
#include <math.h>
|
||||
|
||||
float
|
||||
|
@ -17,7 +17,6 @@ not, write to the Free Software Foundation, Inc., 675 Mass Ave,
|
||||
Cambridge, MA 02139, USA. */
|
||||
|
||||
#include <ansidecl.h>
|
||||
#define __NO_MATH_INLINES
|
||||
#include <math.h>
|
||||
|
||||
int
|
||||
|
@ -17,7 +17,6 @@ not, write to the Free Software Foundation, Inc., 675 Mass Ave,
|
||||
Cambridge, MA 02139, USA. */
|
||||
|
||||
#include <ansidecl.h>
|
||||
#define __NO_MATH_INLINES
|
||||
#include <math.h>
|
||||
|
||||
int
|
||||
|
@ -17,7 +17,6 @@ not, write to the Free Software Foundation, Inc., 675 Mass Ave,
|
||||
Cambridge, MA 02139, USA. */
|
||||
|
||||
#include <ansidecl.h>
|
||||
#define __NO_MATH_INLINES
|
||||
#include <math.h>
|
||||
|
||||
#ifndef FUNC
|
||||
|
@ -17,7 +17,6 @@ not, write to the Free Software Foundation, Inc., 675 Mass Ave,
|
||||
Cambridge, MA 02139, USA. */
|
||||
|
||||
#include <ansidecl.h>
|
||||
#define __NO_MATH_INLINES
|
||||
#include <math.h>
|
||||
|
||||
#ifndef FUNC
|
||||
|
@ -17,7 +17,6 @@ not, write to the Free Software Foundation, Inc., 675 Mass Ave,
|
||||
Cambridge, MA 02139, USA. */
|
||||
|
||||
#include <ansidecl.h>
|
||||
#define __NO_MATH_INLINES
|
||||
#include <math.h>
|
||||
|
||||
#ifndef FUNC
|
||||
|
@ -17,7 +17,6 @@ not, write to the Free Software Foundation, Inc., 675 Mass Ave,
|
||||
Cambridge, MA 02139, USA. */
|
||||
|
||||
#include <ansidecl.h>
|
||||
#define __NO_MATH_INLINES
|
||||
#include <math.h>
|
||||
|
||||
#ifndef FUNC
|
||||
|
@ -17,7 +17,6 @@ not, write to the Free Software Foundation, Inc., 675 Mass Ave,
|
||||
Cambridge, MA 02139, USA. */
|
||||
|
||||
#include <ansidecl.h>
|
||||
#define __NO_MATH_INLINES
|
||||
#include <math.h>
|
||||
|
||||
double
|
||||
|
@ -17,7 +17,6 @@ not, write to the Free Software Foundation, Inc., 675 Mass Ave,
|
||||
Cambridge, MA 02139, USA. */
|
||||
|
||||
#include <ansidecl.h>
|
||||
#define __NO_MATH_INLINES
|
||||
#include <math.h>
|
||||
|
||||
float
|
||||
|
42
sysdeps/unix/sysv/linux/getpriority.c
Normal file
42
sysdeps/unix/sysv/linux/getpriority.c
Normal file
@ -0,0 +1,42 @@
|
||||
/* getpriority for Linux.
|
||||
Copyright (C) 1996 Free Software Foundation, Inc.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If
|
||||
not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <errno.h>
|
||||
#include <sys/resource.h>
|
||||
|
||||
extern int __syscall_getpriority (int, int);
|
||||
|
||||
/* The return value of __syscall_getpriority is biased by this value
|
||||
to avoid returning negative values. */
|
||||
#define PZERO 20
|
||||
|
||||
/* Return the highest priority of any process specified by WHICH and WHO
|
||||
(see above); if WHO is zero, the current process, process group, or user
|
||||
(as specified by WHO) is used. A lower priority number means higher
|
||||
priority. Priorities range from PRIO_MIN to PRIO_MAX. */
|
||||
|
||||
int
|
||||
getpriority (enum __priority_which which, int who)
|
||||
{
|
||||
int res;
|
||||
|
||||
res = __syscall_getpriority ((int) which, who);
|
||||
if (res >= 0)
|
||||
res = PZERO - res;
|
||||
return res;
|
||||
}
|
@ -80,11 +80,9 @@ Cambridge, MA 02139, USA. */
|
||||
|
||||
/* Now two recommended fpucr */
|
||||
|
||||
/* Linux default:
|
||||
- extended precision
|
||||
- rounding to nearest
|
||||
- exceptions on overflow, zero divide and NaN */
|
||||
#define _FPU_DEFAULT 0x00005400
|
||||
/* The fdlibm code requires no interrupts for exceptions. Don't
|
||||
change the rounding mode, it would break long double I/O! */
|
||||
#define _FPU_DEFAULT 0x00000000
|
||||
|
||||
/* IEEE: same as above, but exceptions. We must make it non-zero so
|
||||
that __setfpucw works. This bit will be ignored. */
|
||||
|
@ -1,2 +1 @@
|
||||
#include <linux/socket.h>
|
||||
#include <linux/socket.h>
|
||||
|
@ -20,6 +20,7 @@ nanosleep - nanosleep 2 nanosleep
|
||||
personality init-first personality 1 __personality personality
|
||||
pipe - pipe 1 __pipe pipe
|
||||
reboot - reboot 3 reboot
|
||||
s_getpriority getpriority getpriority 2 __syscall_getpriority
|
||||
s_ptrace ptrace ptrace 4 __syscall_ptrace
|
||||
s_sigsuspend sigsuspend sigsuspend 3 __syscall_sigsuspend
|
||||
sched_setp - sched_setparam 2 __sched_setparam sched_setparam
|
||||
|
@ -48,7 +48,7 @@ main (int argc, char *argv[])
|
||||
{
|
||||
#define TEST(test) \
|
||||
do \
|
||||
if (is##test (ch) != iswctype ((wchar_t) ch, bit_##test)) \
|
||||
if ((is##test (ch) == 0) != (iswctype (ch, bit_##test)) == 0) \
|
||||
{ \
|
||||
printf ("class `%s' test for character \\%o failed\n", \
|
||||
#test, ch); \
|
||||
|
Loading…
x
Reference in New Issue
Block a user