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:
Roland McGrath 1996-05-03 17:44:31 +00:00
parent 9e72046871
commit 7a12c6bba7
68 changed files with 1693 additions and 964 deletions

129
ChangeLog
View File

@ -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.

View File

@ -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

View File

@ -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
View 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;
}

View File

@ -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

View File

@ -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
View 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
View 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));

View File

@ -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
View 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

View File

@ -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. */

View File

@ -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,
};

View File

@ -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,
{

View File

@ -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,
{

View File

@ -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,
{

View File

@ -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,
{

View File

@ -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,
{

View File

@ -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
View 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;
}

View File

@ -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

View File

@ -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);
}

View File

@ -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 */

View File

@ -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. */

View File

@ -24,7 +24,6 @@
typedef int wint_t;
typedef unsigned short int u16_t;
#include_next <config.h>

View File

@ -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;

View File

@ -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

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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;

View File

@ -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;
}

View File

@ -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])

View File

@ -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
View 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
View 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)

View File

@ -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__ */

View File

@ -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;

View File

@ -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__ */

View File

@ -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
View 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;
}

View File

@ -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,

View File

@ -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 */

View File

@ -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);

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View 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;
}

View File

@ -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. */

View File

@ -1,2 +1 @@
#include <linux/socket.h>
#include <linux/socket.h>

View File

@ -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

View File

@ -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); \