1
0
mirror of https://sourceware.org/git/glibc.git synced 2025-07-29 11:41:21 +03:00
2004-01-09  Bruno Haible  <bruno@clisp.org>

	* intl/gmo.h (MO_REVISION_NUMBER_WITH_SYSDEP_I): New definition.
	* intl/loadmsgcat.c (get_sysdep_segment_value): Handle "I".
	(_nl_load_domain): Treat major revision 1 like major revision 0.

2004-01-11  Bruno Haible  <bruno@clisp.org>

	* stdio-common/vfprintf.c (vfprintf): Disallow the 'I' flag after
	width or precision has been seen.

2004-01-08  Bruno Haible  <bruno@clisp.org>

	* intl/loadmsgcat.c (_nl_load_domain): When a string pair uses a system
	dependent segment not known to this version of the library, ignore
	the string pair instead of crashing.
This commit is contained in:
Ulrich Drepper
2004-01-14 05:38:11 +00:00
parent 5de90b7c61
commit 083dc54a01
5 changed files with 270 additions and 144 deletions

View File

@ -1,3 +1,20 @@
2004-01-09 Bruno Haible <bruno@clisp.org>
* intl/gmo.h (MO_REVISION_NUMBER_WITH_SYSDEP_I): New definition.
* intl/loadmsgcat.c (get_sysdep_segment_value): Handle "I".
(_nl_load_domain): Treat major revision 1 like major revision 0.
2004-01-11 Bruno Haible <bruno@clisp.org>
* stdio-common/vfprintf.c (vfprintf): Disallow the 'I' flag after
width or precision has been seen.
2004-01-08 Bruno Haible <bruno@clisp.org>
* intl/loadmsgcat.c (_nl_load_domain): When a string pair uses a system
dependent segment not known to this version of the library, ignore
the string pair instead of crashing.
2004-01-13 Ulrich Drepper <drepper@redhat.com> 2004-01-13 Ulrich Drepper <drepper@redhat.com>
* configure.in: Rewrite test to give gcc to clean up after itself. * configure.in: Rewrite test to give gcc to clean up after itself.

2
configure vendored
View File

@ -6286,7 +6286,7 @@ if { ac_try='$libc_unwind_check >&5'
(exit $ac_status); }; } (exit $ac_status); }; }
then then
if $libc_unwind_check -v 2>&1 >/dev/null \ if $libc_unwind_check -v 2>&1 >/dev/null \
| grep -q -- --eh-frame-hdr; then | grep -- --eh-frame-hdr 2>&1 >/dev/null; then
libc_cv_gcc_dwarf2_unwind_info=no_registry_needed libc_cv_gcc_dwarf2_unwind_info=no_registry_needed
else else
libc_cv_gcc_dwarf2_unwind_info=static libc_cv_gcc_dwarf2_unwind_info=static

View File

@ -1,5 +1,5 @@
/* Internal header for GNU gettext internationalization functions. /* Internal header for GNU gettext internationalization functions.
Copyright (C) 1995, 1997, 2000-2002 Free Software Foundation, Inc. Copyright (C) 1995, 1997, 2000-2002, 2004 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or The GNU C Library is free software; you can redistribute it and/or
@ -30,6 +30,7 @@
/* Revision number of the currently used .mo (binary) file format. */ /* Revision number of the currently used .mo (binary) file format. */
#define MO_REVISION_NUMBER 0 #define MO_REVISION_NUMBER 0
#define MO_REVISION_NUMBER_WITH_SYSDEP_I 1
/* The following contortions are an attempt to use the C preprocessor /* The following contortions are an attempt to use the C preprocessor
to determine an unsigned integral type that is 32 bits wide. An to determine an unsigned integral type that is 32 bits wide. An
@ -77,7 +78,7 @@ struct mo_file_header
/* The revision number of the file format. */ /* The revision number of the file format. */
nls_uint32 revision; nls_uint32 revision;
/* The following are only used in .mo files with major revision 0. */ /* The following are only used in .mo files with major revision 0 or 1. */
/* The number of strings pairs. */ /* The number of strings pairs. */
nls_uint32 nstrings; nls_uint32 nstrings;

View File

@ -1,5 +1,5 @@
/* Load needed message catalogs. /* Load needed message catalogs.
Copyright (C) 1995-2002, 2003 Free Software Foundation, Inc. Copyright (C) 1995-2004 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or The GNU C Library is free software; you can redistribute it and/or
@ -735,6 +735,18 @@ get_sysdep_segment_value (name)
} }
} }
} }
/* Test for a glibc specific printf() format directive flag. */
if (name[0] == 'I' && name[1] == '\0')
{
#if defined _LIBC || __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 2)
/* The 'I' flag, in numeric format directives, replaces ASCII digits
with the 'outdigits' defined in the LC_CTYPE locale facet. This is
used for Farsi (Persian) and maybe Arabic. */
return "I";
#else
return "";
#endif
}
/* Other system dependent strings are not valid. */ /* Other system dependent strings are not valid. */
return NULL; return NULL;
} }
@ -1009,10 +1021,11 @@ _nl_load_domain (domain_file, domainbinding)
/* Fill in the information about the available tables. */ /* Fill in the information about the available tables. */
revision = W (domain->must_swap, data->revision); revision = W (domain->must_swap, data->revision);
/* We support only the major revision 0. */ /* We support only the major revisions 0 and 1. */
switch (revision >> 16) switch (revision >> 16)
{ {
case 0: case 0:
case 1:
domain->nstrings = W (domain->must_swap, data->nstrings); domain->nstrings = W (domain->must_swap, data->nstrings);
domain->orig_tab = (const struct string_desc *) domain->orig_tab = (const struct string_desc *)
((char *) data + W (domain->must_swap, data->orig_tab_offset)); ((char *) data + W (domain->must_swap, data->orig_tab_offset));
@ -1052,12 +1065,13 @@ _nl_load_domain (domain_file, domainbinding)
const char **sysdep_segment_values; const char **sysdep_segment_values;
const nls_uint32 *orig_sysdep_tab; const nls_uint32 *orig_sysdep_tab;
const nls_uint32 *trans_sysdep_tab; const nls_uint32 *trans_sysdep_tab;
nls_uint32 n_inmem_sysdep_strings;
size_t memneed; size_t memneed;
char *mem; char *mem;
struct sysdep_string_desc *inmem_orig_sysdep_tab; struct sysdep_string_desc *inmem_orig_sysdep_tab;
struct sysdep_string_desc *inmem_trans_sysdep_tab; struct sysdep_string_desc *inmem_trans_sysdep_tab;
nls_uint32 *inmem_hash_tab; nls_uint32 *inmem_hash_tab;
unsigned int i; unsigned int i, j;
/* Get the values of the system dependent segments. */ /* Get the values of the system dependent segments. */
n_sysdep_segments = n_sysdep_segments =
@ -1092,19 +1106,25 @@ _nl_load_domain (domain_file, domainbinding)
+ W (domain->must_swap, data->trans_sysdep_tab_offset)); + W (domain->must_swap, data->trans_sysdep_tab_offset));
/* Compute the amount of additional memory needed for the /* Compute the amount of additional memory needed for the
system dependent strings and the augmented hash table. */ system dependent strings and the augmented hash table.
memneed = 2 * n_sysdep_strings At the same time, also drop string pairs which refer to
* sizeof (struct sysdep_string_desc) an undefined system dependent segment. */
+ domain->hash_size * sizeof (nls_uint32); n_inmem_sysdep_strings = 0;
for (i = 0; i < 2 * n_sysdep_strings; i++) memneed = domain->hash_size * sizeof (nls_uint32);
for (i = 0; i < n_sysdep_strings; i++)
{
int valid = 1;
size_t needs[2];
for (j = 0; j < 2; j++)
{ {
const struct sysdep_string *sysdep_string = const struct sysdep_string *sysdep_string =
(const struct sysdep_string *) (const struct sysdep_string *)
((char *) data ((char *) data
+ W (domain->must_swap, + W (domain->must_swap,
i < n_sysdep_strings j == 0
? orig_sysdep_tab[i] ? orig_sysdep_tab[i]
: trans_sysdep_tab[i - n_sysdep_strings])); : trans_sysdep_tab[i]));
size_t need = 0; size_t need = 0;
const struct segment_pair *p = sysdep_string->segments; const struct segment_pair *p = sysdep_string->segments;
@ -1126,12 +1146,34 @@ _nl_load_domain (domain_file, domainbinding)
goto invalid; goto invalid;
} }
if (sysdep_segment_values[sysdepref] == NULL)
{
/* This particular string pair is invalid. */
valid = 0;
break;
}
need += strlen (sysdep_segment_values[sysdepref]); need += strlen (sysdep_segment_values[sysdepref]);
} }
memneed += need; needs[j] = need;
if (!valid)
break;
} }
if (valid)
{
n_inmem_sysdep_strings++;
memneed += needs[0] + needs[1];
}
}
memneed += 2 * n_inmem_sysdep_strings
* sizeof (struct sysdep_string_desc);
if (n_inmem_sysdep_strings > 0)
{
unsigned int k;
/* Allocate additional memory. */ /* Allocate additional memory. */
mem = (char *) malloc (memneed); mem = (char *) malloc (memneed);
if (mem == NULL) if (mem == NULL)
@ -1139,42 +1181,94 @@ _nl_load_domain (domain_file, domainbinding)
domain->malloced = mem; domain->malloced = mem;
inmem_orig_sysdep_tab = (struct sysdep_string_desc *) mem; inmem_orig_sysdep_tab = (struct sysdep_string_desc *) mem;
mem += n_sysdep_strings * sizeof (struct sysdep_string_desc); mem += n_inmem_sysdep_strings
* sizeof (struct sysdep_string_desc);
inmem_trans_sysdep_tab = (struct sysdep_string_desc *) mem; inmem_trans_sysdep_tab = (struct sysdep_string_desc *) mem;
mem += n_sysdep_strings * sizeof (struct sysdep_string_desc); mem += n_inmem_sysdep_strings
* sizeof (struct sysdep_string_desc);
inmem_hash_tab = (nls_uint32 *) mem; inmem_hash_tab = (nls_uint32 *) mem;
mem += domain->hash_size * sizeof (nls_uint32); mem += domain->hash_size * sizeof (nls_uint32);
/* Compute the system dependent strings. */ /* Compute the system dependent strings. */
for (i = 0; i < 2 * n_sysdep_strings; i++) k = 0;
for (i = 0; i < n_sysdep_strings; i++)
{
int valid = 1;
for (j = 0; j < 2; j++)
{ {
const struct sysdep_string *sysdep_string = const struct sysdep_string *sysdep_string =
(const struct sysdep_string *) (const struct sysdep_string *)
((char *) data ((char *) data
+ W (domain->must_swap, + W (domain->must_swap,
i < n_sysdep_strings j == 0
? orig_sysdep_tab[i] ? orig_sysdep_tab[i]
: trans_sysdep_tab[i - n_sysdep_strings])); : trans_sysdep_tab[i]));
const struct segment_pair *p =
sysdep_string->segments;
if (W (domain->must_swap, p->sysdepref)
!= SEGMENTS_END)
for (p = sysdep_string->segments;; p++)
{
nls_uint32 sysdepref;
sysdepref =
W (domain->must_swap, p->sysdepref);
if (sysdepref == SEGMENTS_END)
break;
if (sysdep_segment_values[sysdepref] == NULL)
{
/* This particular string pair is
invalid. */
valid = 0;
break;
}
}
if (!valid)
break;
}
if (valid)
{
for (j = 0; j < 2; j++)
{
const struct sysdep_string *sysdep_string =
(const struct sysdep_string *)
((char *) data
+ W (domain->must_swap,
j == 0
? orig_sysdep_tab[i]
: trans_sysdep_tab[i]));
const char *static_segments = const char *static_segments =
(char *) data (char *) data
+ W (domain->must_swap, sysdep_string->offset); + W (domain->must_swap, sysdep_string->offset);
const struct segment_pair *p = sysdep_string->segments; const struct segment_pair *p =
sysdep_string->segments;
/* Concatenate the segments, and fill /* Concatenate the segments, and fill
inmem_orig_sysdep_tab[i] (for i < n_sysdep_strings) and inmem_orig_sysdep_tab[k] (for j == 0) and
inmem_trans_sysdep_tab[i-n_sysdep_strings] (for inmem_trans_sysdep_tab[k] (for j == 1). */
i >= n_sysdep_strings). */
if (W (domain->must_swap, p->sysdepref) == SEGMENTS_END) struct sysdep_string_desc *inmem_tab_entry =
(j == 0
? inmem_orig_sysdep_tab
: inmem_trans_sysdep_tab)
+ k;
if (W (domain->must_swap, p->sysdepref)
== SEGMENTS_END)
{ {
/* Only one static segment. */ /* Only one static segment. */
inmem_orig_sysdep_tab[i].length = inmem_tab_entry->length =
W (domain->must_swap, p->segsize); W (domain->must_swap, p->segsize);
inmem_orig_sysdep_tab[i].pointer = static_segments; inmem_tab_entry->pointer = static_segments;
} }
else else
{ {
inmem_orig_sysdep_tab[i].pointer = mem; inmem_tab_entry->pointer = mem;
for (p = sysdep_string->segments;; p++) for (p = sysdep_string->segments;; p++)
{ {
@ -1199,21 +1293,28 @@ _nl_load_domain (domain_file, domainbinding)
mem += n; mem += n;
} }
inmem_orig_sysdep_tab[i].length = inmem_tab_entry->length =
mem - inmem_orig_sysdep_tab[i].pointer; mem - inmem_tab_entry->pointer;
} }
} }
k++;
}
}
if (k != n_inmem_sysdep_strings)
abort ();
/* Compute the augmented hash table. */ /* Compute the augmented hash table. */
for (i = 0; i < domain->hash_size; i++) for (i = 0; i < domain->hash_size; i++)
inmem_hash_tab[i] = inmem_hash_tab[i] =
W (domain->must_swap_hash_tab, domain->hash_tab[i]); W (domain->must_swap_hash_tab, domain->hash_tab[i]);
for (i = 0; i < n_sysdep_strings; i++) for (i = 0; i < n_inmem_sysdep_strings; i++)
{ {
const char *msgid = inmem_orig_sysdep_tab[i].pointer; const char *msgid = inmem_orig_sysdep_tab[i].pointer;
nls_uint32 hash_val = __hash_string (msgid); nls_uint32 hash_val = __hash_string (msgid);
nls_uint32 idx = hash_val % domain->hash_size; nls_uint32 idx = hash_val % domain->hash_size;
nls_uint32 incr = 1 + (hash_val % (domain->hash_size - 2)); nls_uint32 incr =
1 + (hash_val % (domain->hash_size - 2));
for (;;) for (;;)
{ {
@ -1231,9 +1332,7 @@ _nl_load_domain (domain_file, domainbinding)
} }
} }
freea (sysdep_segment_values); domain->n_sysdep_strings = n_inmem_sysdep_strings;
domain->n_sysdep_strings = n_sysdep_strings;
domain->orig_sysdep_tab = inmem_orig_sysdep_tab; domain->orig_sysdep_tab = inmem_orig_sysdep_tab;
domain->trans_sysdep_tab = inmem_trans_sysdep_tab; domain->trans_sysdep_tab = inmem_trans_sysdep_tab;
@ -1246,6 +1345,15 @@ _nl_load_domain (domain_file, domainbinding)
domain->orig_sysdep_tab = NULL; domain->orig_sysdep_tab = NULL;
domain->trans_sysdep_tab = NULL; domain->trans_sysdep_tab = NULL;
} }
freea (sysdep_segment_values);
}
else
{
domain->n_sysdep_strings = 0;
domain->orig_sysdep_tab = NULL;
domain->trans_sysdep_tab = NULL;
}
} }
break; break;
} }

View File

@ -399,7 +399,7 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap)
REF (form_floathex), /* for 'A', 'a' */ \ REF (form_floathex), /* for 'A', 'a' */ \
REF (mod_ptrdiff_t), /* for 't' */ \ REF (mod_ptrdiff_t), /* for 't' */ \
REF (mod_intmax_t), /* for 'j' */ \ REF (mod_intmax_t), /* for 'j' */ \
REF (flag_i18n) /* for 'I' */ \ REF (form_unknown) /* for 'I' */ \
}; \ }; \
/* Step 2: after processing precision. */ \ /* Step 2: after processing precision. */ \
static JUMP_TABLE_TYPE step2_jumps[30] = \ static JUMP_TABLE_TYPE step2_jumps[30] = \
@ -433,7 +433,7 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap)
REF (form_floathex), /* for 'A', 'a' */ \ REF (form_floathex), /* for 'A', 'a' */ \
REF (mod_ptrdiff_t), /* for 't' */ \ REF (mod_ptrdiff_t), /* for 't' */ \
REF (mod_intmax_t), /* for 'j' */ \ REF (mod_intmax_t), /* for 'j' */ \
REF (flag_i18n) /* for 'I' */ \ REF (form_unknown) /* for 'I' */ \
}; \ }; \
/* Step 3a: after processing first 'h' modifier. */ \ /* Step 3a: after processing first 'h' modifier. */ \
static JUMP_TABLE_TYPE step3a_jumps[30] = \ static JUMP_TABLE_TYPE step3a_jumps[30] = \