summaryrefslogtreecommitdiff
path: root/locale/programs/ld-collate.c
diff options
context:
space:
mode:
Diffstat (limited to 'locale/programs/ld-collate.c')
-rw-r--r--locale/programs/ld-collate.c85
1 files changed, 56 insertions, 29 deletions
diff --git a/locale/programs/ld-collate.c b/locale/programs/ld-collate.c
index f7aaf0d34f..da3cfa7744 100644
--- a/locale/programs/ld-collate.c
+++ b/locale/programs/ld-collate.c
@@ -65,7 +65,9 @@ struct element_t;
/* Data type for list of strings. */
struct section_list
{
+ /* Successor in the known_sections list. */
struct section_list *def_next;
+ /* Successor in the sections list. */
struct section_list *next;
/* Name of the section. */
const char *name;
@@ -291,6 +293,7 @@ make_seclist_elem (struct locale_collate_t *collate, const char *string,
newp->next = next;
newp->name = string;
newp->first = NULL;
+ newp->last = NULL;
return newp;
}
@@ -336,6 +339,10 @@ new_element (struct locale_collate_t *collate, const char *mbs, size_t mbslen,
newp->used_in_level = 0;
newp->is_character = is_character;
+ /* Will be assigned later. XXX */
+ newp->mbseqorder = 0;
+ newp->wcseqorder = 0;
+
/* Will be allocated later. */
newp->weights = NULL;
@@ -350,6 +357,9 @@ new_element (struct locale_collate_t *collate, const char *mbs, size_t mbslen,
newp->mbnext = NULL;
newp->mblast = NULL;
+ newp->wcnext = NULL;
+ newp->wclast = NULL;
+
return newp;
}
@@ -619,9 +629,8 @@ find_element (struct linereader *ldfile, struct locale_collate_t *collate,
/* It's also no collation element. So it is a character
element defined later. */
result = new_element (collate, NULL, 0, NULL, str, len, 1);
- if (result != NULL)
- /* Insert it into the sequence table. */
- insert_entry (&collate->seq_table, str, len, result);
+ /* Insert it into the sequence table. */
+ insert_entry (&collate->seq_table, str, len, result);
}
}
@@ -660,11 +669,11 @@ insert_weights (struct linereader *ldfile, struct element_t *elem,
/* Initialize all the fields. */
elem->file = ldfile->fname;
elem->line = ldfile->lineno;
+
elem->last = collate->cursor;
elem->next = collate->cursor ? collate->cursor->next : NULL;
if (collate->cursor != NULL && collate->cursor->next != NULL)
collate->cursor->next->last = elem;
- elem->section = collate->current_section;
if (collate->cursor != NULL)
collate->cursor->next = elem;
if (collate->start == NULL)
@@ -672,9 +681,8 @@ insert_weights (struct linereader *ldfile, struct element_t *elem,
assert (collate->cursor == NULL);
collate->start = elem;
}
- elem->weights = (struct element_list_t *)
- obstack_alloc (&collate->mempool, nrules * sizeof (struct element_list_t));
- memset (elem->weights, '\0', nrules * sizeof (struct element_list_t));
+
+ elem->section = collate->current_section;
if (collate->current_section->first == NULL)
collate->current_section->first = elem;
@@ -683,6 +691,10 @@ insert_weights (struct linereader *ldfile, struct element_t *elem,
collate->cursor = elem;
+ elem->weights = (struct element_list_t *)
+ obstack_alloc (&collate->mempool, nrules * sizeof (struct element_list_t));
+ memset (elem->weights, '\0', nrules * sizeof (struct element_list_t));
+
weight_cnt = 0;
arg = lr_token (ldfile, charmap, repertoire);
@@ -839,8 +851,8 @@ insert_weights (struct linereader *ldfile, struct element_t *elem,
%s: weights must use the same ellipsis symbol as the name"),
"LC_COLLATE");
- /* The weight for this level has to be ignored. We use the
- null pointer to indicate this. */
+ /* The weight for this level will depend on the element
+ iterating over the range. Put a placeholder. */
elem->weights[weight_cnt].w = (struct element_t **)
obstack_alloc (&collate->mempool, sizeof (struct element_t *));
elem->weights[weight_cnt].w[0] = ELEMENT_ELLIPSIS2;
@@ -988,8 +1000,7 @@ insert_value (struct linereader *ldfile, const char *symstr, size_t symlen,
}
/* Test whether this element is not already in the list. */
- if (elem->next != NULL || (collate->cursor != NULL
- && elem->next == collate->cursor))
+ if (elem->next != NULL || elem == collate->cursor)
{
lr_error (ldfile, _("order for `%.*s' already defined at %s:%Zu"),
(int) symlen, symstr, elem->file, elem->line);
@@ -1434,6 +1445,7 @@ collate_startup (struct linereader *ldfile, struct localedef_t *locale,
collate->col_weight_max = -1;
}
else
+ /* Reuse the copy_locale's data structures. */
collate = locale->categories[LC_COLLATE].collate =
copy_locale->categories[LC_COLLATE].collate;
}
@@ -1788,9 +1800,9 @@ collate_finish (struct localedef_t *locale, struct charmap_t *charmap)
while (sect != NULL && sect->rules == NULL);
}
while (sect != NULL);
- /* We are currently not prepared for more than 256 rulesets. But this
+ /* We are currently not prepared for more than 128 rulesets. But this
should never really be a problem. */
- assert (ruleidx <= 256);
+ assert (ruleidx <= 128);
}
@@ -2529,9 +2541,18 @@ collate_read (struct linereader *ldfile, struct localedef_t *result,
struct token *now;
struct token *arg = NULL;
enum token_t nowtok;
- int state = 0;
enum token_t was_ellipsis = tok_none;
struct localedef_t *copy_locale = NULL;
+ /* Parsing state:
+ 0 - start
+ 1 - between `order-start' and `order-end'
+ 2 - after `order-end'
+ 3 - after `reorder-after', waiting for `reorder-end'
+ 4 - after `reorder-end'
+ 5 - after `reorder-sections-after', waiting for `reorder-sections-end'
+ 6 - after `reorder-sections-end'
+ */
+ int state = 0;
/* Get the repertoire we have to use. */
if (repertoire_name != NULL)
@@ -2828,9 +2849,10 @@ collate_read (struct linereader *ldfile, struct localedef_t *result,
}
else if (ellipsis == tok_none)
{
- /* The name is already defined. */
+ /* A single symbol, no ellipsis. */
if (check_duplicate (ldfile, collate, charmap,
repertoire, symbol, symbol_len))
+ /* The name is already defined. */
goto col_sym_free;
insert_entry (&collate->sym_table, symbol, symbol_len,
@@ -2884,13 +2906,13 @@ collate_read (struct linereader *ldfile, struct localedef_t *result,
/* Create the name. */
sprintf (symbuf,
ellipsis == tok_ellipsis2
- ? "%.*s%.*lX" : "%.*s%.*lX",
+ ? "%.*s%.*lX" : "%.*s%.*lu",
(int) prefixlen, symbol,
(int) (symbol_len - prefixlen), from);
- /* The name is already defined. */
if (check_duplicate (ldfile, collate, charmap,
repertoire, symbuf, symbol_len))
+ /* The name is already defined. */
goto col_sym_free;
insert_entry (&collate->sym_table, symbuf,
@@ -3021,8 +3043,8 @@ error while adding equivalent collating symbol"));
}
runp = (struct section_list *) xcalloc (1, sizeof (*runp));
- name = strncpy (xmalloc (arg->val.str.lenmb + 1),
- arg->val.str.startmb, arg->val.str.lenmb);
+ name = (char *) xmalloc (arg->val.str.lenmb + 1);
+ memcpy (name, arg->val.str.startmb, arg->val.str.lenmb);
name[arg->val.str.lenmb] = '\0';
runp->name = name;
@@ -3070,6 +3092,8 @@ error while adding equivalent collating symbol"));
if (collate->error_section.first == NULL)
{
+ /* Insert &collate->error_section at the end of
+ the collate->sections list. */
if (collate->sections == NULL)
collate->sections = &collate->error_section;
else
@@ -3078,9 +3102,9 @@ error while adding equivalent collating symbol"));
while (sp->next != NULL)
sp = sp->next;
- collate->error_section.next = NULL;
sp->next = &collate->error_section;
}
+ collate->error_section.next = NULL;
}
}
else
@@ -3093,6 +3117,8 @@ error while adding equivalent collating symbol"));
"LC_COLLATE", sp->name);
else
{
+ /* Insert sp in the collate->sections list,
+ right after collate->current_section. */
if (collate->current_section == NULL)
collate->current_section = sp;
else
@@ -3141,6 +3167,8 @@ error while adding equivalent collating symbol"));
"LC_COLLATE");
else
{
+ /* Insert &collate->unnamed_section at the beginning of
+ the collate->sections list. */
collate->unnamed_section.next = collate->sections;
collate->sections = &collate->unnamed_section;
}
@@ -3149,7 +3177,7 @@ error while adding equivalent collating symbol"));
/* Now read the direction names. */
read_directions (ldfile, arg, charmap, repertoire, collate);
- /* From now be need the strings untranslated. */
+ /* From now we need the strings untranslated. */
ldfile->translate_strings = 0;
break;
@@ -3231,7 +3259,7 @@ error while adding equivalent collating symbol"));
(void **) &insp) == 0)
/* Yes, the symbol exists. Simply point the cursor
to it. */
- collate->cursor = insp;
+ collate->cursor = insp;
else
{
struct symbol_t *symbp;
@@ -3428,7 +3456,7 @@ error while adding equivalent collating symbol"));
/* We are outside an `order_start' region. This means
we must only accept definitions of values for
collation symbols since these are purely abstract
- values and don't need dorections associated. */
+ values and don't need directions associated. */
struct element_t *seqp;
if (find_entry (&collate->seq_table, symstr, symlen,
@@ -3510,7 +3538,7 @@ error while adding equivalent collating symbol"));
if (seqp->section->first == seqp)
{
if (seqp->section->first == seqp->section->last)
- /* This setion has no content anymore. */
+ /* This section has no content anymore. */
seqp->section->first = seqp->section->last = NULL;
else
seqp->section->first = seqp->next;
@@ -3616,8 +3644,7 @@ error while adding equivalent collating symbol"));
/* See whether UNDEFINED already appeared somewhere. */
if (collate->undefined.next != NULL
- || (collate->cursor != NULL
- && collate->undefined.next == collate->cursor))
+ || &collate->undefined == collate->cursor)
{
lr_error (ldfile,
_("%s: order for `%.*s' already defined at %s:%Zu"),
@@ -3632,9 +3659,9 @@ error while adding equivalent collating symbol"));
repertoire, collate, tok_none);
break;
- case tok_ellipsis2:
- case tok_ellipsis3:
- case tok_ellipsis4:
+ case tok_ellipsis2: /* symbolic hexadecimal ellipsis */
+ case tok_ellipsis3: /* absolute ellipsis */
+ case tok_ellipsis4: /* symbolic decimal ellipsis */
/* This is the symbolic (decimal or hexadecimal) or absolute
ellipsis. */
if (was_ellipsis != tok_none)