[PATCH 2/7] localedef: fix rules definitions in LC_COLLATE
From: Denis Barbier <bouzim@gmail.com>
Date: Tue, 23 Oct 2007 09:24:51 -0500
Several bugs in ld-collate.c make localedef produce wrong collation
data.
Sorting with French locales is special because diacritics are
considered from right to left, as described in ISO-14651 and many
other documents. And indeed, localedata/locales/iso14651_t1 contains
order_start <LATIN>;forward;backward;forward;forward,position
An example is available at
http://www.open-std.org/jtc1/sc22/wg20/docs/n602.htm#AnnexC
and fr_FR sort this text as if the backward directive had no effect.
Backward/forward rules were sometimes affected to a wrong section,
some rules could wrongly be declared as identical, and localedef
segfaults are also fixed. Special French collation now works as
described in ISO-14651.
Originally from belocs-locales-bin 2.3.3-11, 2005-01-08.
Submitted upstream: BZ645
[clint@debian.org, 2007-10-23: rebased against glibc-2.7]
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
locale/programs/ld-collate.c | 16 +++++++++++++++-
1 files changed, 15 insertions(+), 1 deletions(-)
diff --git a/locale/programs/ld-collate.c b/locale/programs/ld-collate.c
index 88b6890..a26da46 100644
--- a/locale/programs/ld-collate.c
+++ b/locale/programs/ld-collate.c
@@ -1548,6 +1548,7 @@ collate_finish (struct localedef_t *locale, const struct charmap_t *charmap)
int i;
int need_undefined = 0;
struct section_list *sect;
+ enum coll_sort_rule *orules;
int ruleidx;
int nr_wide_elems = 0;
@@ -1559,18 +1560,28 @@ collate_finish (struct localedef_t *locale, const struct charmap_t *charmap)
"LC_COLLATE"));
return;
}
+ if (nrules == 0)
+ {
+ /* An error message has already been printed:
+ empty category description not allowed. */
+ return;
+ }
/* If this assertion is hit change the type in `element_t'. */
assert (nrules <= sizeof (runp->used_in_level) * 8);
/* Make sure that the `position' rule is used either in all sections
or in none. */
+ sect = collate->sections;
+ while (sect != NULL && sect->rules == NULL)
+ sect = sect->next;
+ orules = sect->rules;
for (i = 0; i < nrules; ++i)
for (sect = collate->sections; sect != NULL; sect = sect->next)
if (sect != collate->current_section
&& sect->rules != NULL
&& ((sect->rules[i] & sort_position)
- != (collate->current_section->rules[i] & sort_position)))
+ != (orules[i] & sort_position)))
{
WITH_CUR_LOCALE (error (0, 0, _("\
%s: `position' must be used for a specific level in all sections or none"),
@@ -3506,6 +3517,9 @@ error while adding equivalent collating symbol"));
no_error = 0;
}
}
+ /* Update current section. */
+ if (collate->cursor != NULL)
+ collate->current_section = collate->cursor->section;
lr_ignore_rest (ldfile, no_error);
}
--
1.7.5.1
Reply to: