aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--locale/programs/ld-collate.c45
1 files changed, 44 insertions, 1 deletions
diff --git a/locale/programs/ld-collate.c b/locale/programs/ld-collate.c
index 445f835aa4..7aa51c31db 100644
--- a/locale/programs/ld-collate.c
+++ b/locale/programs/ld-collate.c
@@ -87,7 +87,7 @@ struct element_t
weight computation.
XXX The type here restricts the number of levels to 32. It could
- we changed if necessary but I doubt this is necessary. */
+ be changed if necessary but I doubt this is necessary. */
unsigned int used_in_level;
struct element_list_t *weights;
@@ -95,6 +95,11 @@ struct element_t
/* Nonzero if this is a real character definition. */
int is_character;
+ /* Order of the character in the sequence. This information will
+ be used in range expressions. */
+ int mbseqorder;
+ int wcseqorder;
+
/* Where does the definition come from. */
const char *file;
size_t line;
@@ -186,6 +191,10 @@ struct locale_collate_t
/* Arrays with heads of the list for each of the leading bytes in
the multibyte sequences. */
struct element_t **wcheads;
+
+ /* The arrays with the collation sequence order. */
+ unsigned char mbseqorder[256];
+ uint32_t *wcseqorder;
};
@@ -1401,6 +1410,8 @@ collate_finish (struct localedef_t *locale, struct charmap_t *charmap)
struct locale_collate_t *collate = locale->categories[LC_COLLATE].collate;
int mbact[nrules];
int wcact;
+ int mbseqact;
+ int wcseqact;
struct element_t *runp;
int i;
int need_undefined = 0;
@@ -1487,6 +1498,8 @@ collate_finish (struct localedef_t *locale, struct charmap_t *charmap)
for (i = 0; i < nrules; ++i)
mbact[i] = 2;
wcact = 2;
+ mbseqact = 0;
+ wcseqact = 0;
runp = collate->start;
while (runp != NULL)
{
@@ -1559,6 +1572,14 @@ collate_finish (struct localedef_t *locale, struct charmap_t *charmap)
++nr_wide_elems;
}
+ if (runp->is_character)
+ {
+ if (runp->nmbs == 1)
+ collate->mbseqorder[((unsigned char *) runp->mbs)[0]] = mbseqact++;
+
+ runp->wcseqorder = wcseqact++;
+ }
+
/* Up to the next entry. */
runp = runp->next;
}
@@ -1668,6 +1689,14 @@ Computing table size for collation table might take a while..."),
* collate->plane_cnt
* sizeof (struct element_t *)));
+ collate->wcseqorder = (uint32_t *)
+ obstack_alloc (&collate->mempool, (collate->plane_size
+ * collate->plane_cnt
+ * sizeof (uint32_t)));
+ memset (collate->wcseqorder, '\0', (collate->plane_size
+ * collate->plane_cnt
+ * sizeof (uint32_t)));
+
/* Start adding. */
runp = collate->start;
while (runp != NULL)
@@ -1689,6 +1718,9 @@ Computing table size for collation table might take a while..."),
idx += collate->plane_size;
}
+ /* Insert the collation sequence value. */
+ collate->wcseqorder[idx] = runp->wcseqorder;
+
/* Find the point where to insert in the list. */
eptr = &collate->wcheads[idx];
while (*eptr != NULL)
@@ -2560,8 +2592,19 @@ collate_output (struct localedef_t *locale, struct charmap_t *charmap,
assert (cnt == _NL_ITEM_INDEX (_NL_COLLATE_SYMB_EXTRAMB));
iov[2 + cnt].iov_len = obstack_object_size (&extrapool);
iov[2 + cnt].iov_base = obstack_finish (&extrapool);
+ idx[1 + cnt] = idx[cnt] + iov[2 + cnt].iov_len;
+ ++cnt;
+
+ assert (cnt == _NL_ITEM_INDEX (_NL_COLLATE_COLLSEQMB));
+ iov[2 + cnt].iov_base = collate->mbseqorder;
+ iov[2 + cnt].iov_len = 256;
+ idx[1 + cnt] = idx[cnt] + iov[2 + cnt].iov_len;
++cnt;
+ assert (cnt == _NL_ITEM_INDEX (_NL_COLLATE_COLLSEQWC));
+ iov[2 + cnt].iov_base = collate->wcseqorder;
+ iov[2 + cnt].iov_len = table_size * sizeof (uint32_t);
+ ++cnt;
assert (cnt == _NL_ITEM_INDEX (_NL_NUM_LC_COLLATE));