1 /* Copyright (C) 1995-1999, 2000, 2001 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
3 Contributed by Ulrich Drepper <drepper@gnu.org>, 1995.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, write to the Free
17 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
28 #include <sys/param.h>
31 #include "localeinfo.h"
32 #include "linereader.h"
34 #include "localedef.h"
35 #include "elem-hash.h"
37 /* Uncomment the following line in the production version. */
38 /* #define NDEBUG 1 */
41 #define obstack_chunk_alloc malloc
42 #define obstack_chunk_free free
45 obstack_int32_grow (struct obstack *obstack, int32_t data)
47 if (sizeof (int32_t) == sizeof (int))
48 obstack_int_grow (obstack, data);
50 obstack_grow (obstack, &data, sizeof (int32_t));
54 obstack_int32_grow_fast (struct obstack *obstack, int32_t data)
56 if (sizeof (int32_t) == sizeof (int))
57 obstack_int_grow_fast (obstack, data);
59 obstack_grow (obstack, &data, sizeof (int32_t));
62 /* Forward declaration. */
65 /* Data type for list of strings. */
68 /* Successor in the known_sections list. */
69 struct section_list *def_next;
70 /* Successor in the sections list. */
71 struct section_list *next;
72 /* Name of the section. */
74 /* First element of this section. */
75 struct element_t *first;
76 /* Last element of this section. */
77 struct element_t *last;
78 /* These are the rules for this section. */
79 enum coll_sort_rule *rules;
80 /* Index of the rule set in the appropriate section of the output file. */
88 /* Number of elements. */
94 /* Data type for collating element. */
106 /* The following is a bit mask which bits are set if this element is
107 used in the appropriate level. Interesting for the singlebyte
110 XXX The type here restricts the number of levels to 32. It could
111 be changed if necessary but I doubt this is necessary. */
112 unsigned int used_in_level;
114 struct element_list_t *weights;
116 /* Nonzero if this is a real character definition. */
119 /* Order of the character in the sequence. This information will
120 be used in range expressions. */
124 /* Where does the definition come from. */
128 /* Which section does this belong to. */
129 struct section_list *section;
131 /* Predecessor and successor in the order list. */
132 struct element_t *last;
133 struct element_t *next;
135 /* Next element in multibyte output list. */
136 struct element_t *mbnext;
137 struct element_t *mblast;
139 /* Next element in wide character output list. */
140 struct element_t *wcnext;
141 struct element_t *wclast;
144 /* Special element value. */
145 #define ELEMENT_ELLIPSIS2 ((struct element_t *) 1)
146 #define ELEMENT_ELLIPSIS3 ((struct element_t *) 2)
147 #define ELEMENT_ELLIPSIS4 ((struct element_t *) 3)
149 /* Data type for collating symbol. */
154 /* Point to place in the order list. */
155 struct element_t *order;
157 /* Where does the definition come from. */
162 /* Sparse table of struct element_t *. */
163 #define TABLE wchead_table
164 #define ELEMENT struct element_t *
170 /* Sparse table of int32_t. */
171 #define TABLE collidx_table
172 #define ELEMENT int32_t
176 /* Sparse table of uint32_t. */
177 #define TABLE collseq_table
178 #define ELEMENT uint32_t
179 #define DEFAULT ~((uint32_t) 0)
183 /* The real definition of the struct for the LC_COLLATE locale. */
184 struct locale_collate_t
189 /* List of known scripts. */
190 struct section_list *known_sections;
191 /* List of used sections. */
192 struct section_list *sections;
193 /* Current section using definition. */
194 struct section_list *current_section;
195 /* There always can be an unnamed section. */
196 struct section_list unnamed_section;
197 /* To make handling of errors easier we have another section. */
198 struct section_list error_section;
199 /* Sometimes we are defining the values for collating symbols before
200 the first actual section. */
201 struct section_list symbol_section;
203 /* Start of the order list. */
204 struct element_t *start;
206 /* The undefined element. */
207 struct element_t undefined;
209 /* This is the cursor for `reorder_after' insertions. */
210 struct element_t *cursor;
212 /* This value is used when handling ellipsis. */
213 struct element_t ellipsis_weight;
215 /* Known collating elements. */
216 hash_table elem_table;
218 /* Known collating symbols. */
219 hash_table sym_table;
221 /* Known collation sequences. */
222 hash_table seq_table;
224 struct obstack mempool;
226 /* The LC_COLLATE category is a bit special as it is sometimes possible
227 that the definitions from more than one input file contains information.
228 Therefore we keep all relevant input in a list. */
229 struct locale_collate_t *next;
231 /* Arrays with heads of the list for each of the leading bytes in
232 the multibyte sequences. */
233 struct element_t *mbheads[256];
235 /* Arrays with heads of the list for each of the leading bytes in
236 the multibyte sequences. */
237 struct wchead_table wcheads;
239 /* The arrays with the collation sequence order. */
240 unsigned char mbseqorder[256];
241 struct collseq_table wcseqorder;
245 /* We have a few global variables which are used for reading all
246 LC_COLLATE category descriptions in all files. */
247 static uint32_t nrules;
250 /* We need UTF-8 encoding of numbers. */
252 utf8_encode (char *buf, int val)
265 for (step = 2; step < 6; ++step)
266 if ((val & (~(uint32_t)0 << (5 * step + 1))) == 0)
270 *buf = (unsigned char) (~0xff >> step);
274 buf[step] = 0x80 | (val & 0x3f);
285 static struct section_list *
286 make_seclist_elem (struct locale_collate_t *collate, const char *string,
287 struct section_list *next)
289 struct section_list *newp;
291 newp = (struct section_list *) obstack_alloc (&collate->mempool,
302 static struct element_t *
303 new_element (struct locale_collate_t *collate, const char *mbs, size_t mbslen,
304 const uint32_t *wcs, const char *name, size_t namelen,
307 struct element_t *newp;
309 newp = (struct element_t *) obstack_alloc (&collate->mempool,
311 newp->name = name == NULL ? NULL : obstack_copy0 (&collate->mempool,
315 newp->mbs = obstack_copy0 (&collate->mempool, mbs, mbslen);
325 size_t nwcs = wcslen ((wchar_t *) wcs);
327 obstack_grow (&collate->mempool, wcs, nwcs * sizeof (uint32_t));
328 obstack_grow (&collate->mempool, &zero, sizeof (uint32_t));
329 newp->wcs = (uint32_t *) obstack_finish (&collate->mempool);
337 newp->mborder = NULL;
339 newp->used_in_level = 0;
340 newp->is_character = is_character;
342 /* Will be assigned later. XXX */
343 newp->mbseqorder = 0;
344 newp->wcseqorder = 0;
346 /* Will be allocated later. */
347 newp->weights = NULL;
352 newp->section = collate->current_section;
367 static struct symbol_t *
368 new_symbol (struct locale_collate_t *collate, const char *name, size_t len)
370 struct symbol_t *newp;
372 newp = (struct symbol_t *) obstack_alloc (&collate->mempool, sizeof (*newp));
374 newp->name = obstack_copy0 (&collate->mempool, name, len);
384 /* Test whether this name is already defined somewhere. */
386 check_duplicate (struct linereader *ldfile, struct locale_collate_t *collate,
387 struct charmap_t *charmap, struct repertoire_t *repertoire,
388 const char *symbol, size_t symbol_len)
392 if (find_entry (&charmap->char_table, symbol, symbol_len, &ignore) == 0)
394 lr_error (ldfile, _("`%.*s' already defined in charmap"),
395 (int) symbol_len, symbol);
399 if (repertoire != NULL
400 && (find_entry (&repertoire->char_table, symbol, symbol_len, &ignore)
403 lr_error (ldfile, _("`%.*s' already defined in repertoire"),
404 (int) symbol_len, symbol);
408 if (find_entry (&collate->sym_table, symbol, symbol_len, &ignore) == 0)
410 lr_error (ldfile, _("`%.*s' already defined as collating symbol"),
411 (int) symbol_len, symbol);
415 if (find_entry (&collate->elem_table, symbol, symbol_len, &ignore) == 0)
417 lr_error (ldfile, _("`%.*s' already defined as collating element"),
418 (int) symbol_len, symbol);
426 /* Read the direction specification. */
428 read_directions (struct linereader *ldfile, struct token *arg,
429 struct charmap_t *charmap, struct repertoire_t *repertoire,
430 struct locale_collate_t *collate)
433 int max = nrules ?: 10;
434 enum coll_sort_rule *rules = calloc (max, sizeof (*rules));
441 if (arg->tok == tok_forward)
443 if (rules[cnt] & sort_backward)
447 lr_error (ldfile, _("\
448 %s: `forward' and `backward' are mutually excluding each other"),
453 else if (rules[cnt] & sort_forward)
457 lr_error (ldfile, _("\
458 %s: `%s' mentioned more than once in definition of weight %d"),
459 "LC_COLLATE", "forward", cnt + 1);
463 rules[cnt] |= sort_forward;
467 else if (arg->tok == tok_backward)
469 if (rules[cnt] & sort_forward)
473 lr_error (ldfile, _("\
474 %s: `forward' and `backward' are mutually excluding each other"),
479 else if (rules[cnt] & sort_backward)
483 lr_error (ldfile, _("\
484 %s: `%s' mentioned more than once in definition of weight %d"),
485 "LC_COLLATE", "backward", cnt + 1);
489 rules[cnt] |= sort_backward;
493 else if (arg->tok == tok_position)
495 if (rules[cnt] & sort_position)
499 lr_error (ldfile, _("\
500 %s: `%s' mentioned more than once in definition of weight %d"),
501 "LC_COLLATE", "position", cnt + 1);
505 rules[cnt] |= sort_position;
511 arg = lr_token (ldfile, charmap, repertoire, verbose);
513 if (arg->tok == tok_eof || arg->tok == tok_eol || arg->tok == tok_comma
514 || arg->tok == tok_semicolon)
516 if (! valid && ! warned)
518 lr_error (ldfile, _("%s: syntax error"), "LC_COLLATE");
522 /* See whether we have to increment the counter. */
523 if (arg->tok != tok_comma && rules[cnt] != 0)
525 /* Add the default `forward' if we have seen only `position'. */
526 if (rules[cnt] == sort_position)
527 rules[cnt] = sort_position | sort_forward;
532 if (arg->tok == tok_eof || arg->tok == tok_eol)
533 /* End of line or file, so we exit the loop. */
538 /* See whether we have enough room in the array. */
542 rules = (enum coll_sort_rule *) xrealloc (rules,
545 memset (&rules[cnt], '\0', (max - cnt) * sizeof (*rules));
552 /* There must not be any more rule. */
555 lr_error (ldfile, _("\
556 %s: too many rules; first entry only had %d"),
557 "LC_COLLATE", nrules);
561 lr_ignore_rest (ldfile, 0);
570 lr_error (ldfile, _("%s: syntax error"), "LC_COLLATE");
575 arg = lr_token (ldfile, charmap, repertoire, verbose);
580 /* Now we know how many rules we have. */
582 rules = (enum coll_sort_rule *) xrealloc (rules,
583 nrules * sizeof (*rules));
589 /* Not enough rules in this specification. */
591 lr_error (ldfile, _("%s: not enough sorting rules"), "LC_COLLATE");
594 rules[cnt] = sort_forward;
595 while (++cnt < nrules);
599 collate->current_section->rules = rules;
603 static struct element_t *
604 find_element (struct linereader *ldfile, struct locale_collate_t *collate,
605 const char *str, size_t len)
607 struct element_t *result = NULL;
609 /* Search for the entries among the collation sequences already define. */
610 if (find_entry (&collate->seq_table, str, len, (void **) &result) != 0)
612 /* Nope, not define yet. So we see whether it is a
616 if (find_entry (&collate->sym_table, str, len, &ptr) == 0)
618 /* It's a collation symbol. */
619 struct symbol_t *sym = (struct symbol_t *) ptr;
623 result = sym->order = new_element (collate, NULL, 0, NULL,
626 else if (find_entry (&collate->elem_table, str, len,
627 (void **) &result) != 0)
629 /* It's also no collation element. So it is a character
630 element defined later. */
631 result = new_element (collate, NULL, 0, NULL, str, len, 1);
632 /* Insert it into the sequence table. */
633 insert_entry (&collate->seq_table, str, len, result);
642 unlink_element (struct locale_collate_t *collate)
644 if (collate->cursor == collate->start)
646 assert (collate->cursor->next == NULL);
647 assert (collate->cursor->last == NULL);
648 collate->cursor = NULL;
652 if (collate->cursor->next != NULL)
653 collate->cursor->next->last = collate->cursor->last;
654 if (collate->cursor->last != NULL)
655 collate->cursor->last->next = collate->cursor->next;
656 collate->cursor = collate->cursor->last;
662 insert_weights (struct linereader *ldfile, struct element_t *elem,
663 struct charmap_t *charmap, struct repertoire_t *repertoire,
664 struct locale_collate_t *collate, enum token_t ellipsis)
669 /* Initialize all the fields. */
670 elem->file = ldfile->fname;
671 elem->line = ldfile->lineno;
673 elem->last = collate->cursor;
674 elem->next = collate->cursor ? collate->cursor->next : NULL;
675 if (collate->cursor != NULL && collate->cursor->next != NULL)
676 collate->cursor->next->last = elem;
677 if (collate->cursor != NULL)
678 collate->cursor->next = elem;
679 if (collate->start == NULL)
681 assert (collate->cursor == NULL);
682 collate->start = elem;
685 elem->section = collate->current_section;
687 if (collate->current_section->first == NULL)
688 collate->current_section->first = elem;
689 if (collate->current_section->last == collate->cursor)
690 collate->current_section->last = elem;
692 collate->cursor = elem;
694 elem->weights = (struct element_list_t *)
695 obstack_alloc (&collate->mempool, nrules * sizeof (struct element_list_t));
696 memset (elem->weights, '\0', nrules * sizeof (struct element_list_t));
700 arg = lr_token (ldfile, charmap, repertoire, verbose);
703 if (arg->tok == tok_eof || arg->tok == tok_eol)
706 if (arg->tok == tok_ignore)
708 /* The weight for this level has to be ignored. We use the
709 null pointer to indicate this. */
710 elem->weights[weight_cnt].w = (struct element_t **)
711 obstack_alloc (&collate->mempool, sizeof (struct element_t *));
712 elem->weights[weight_cnt].w[0] = NULL;
713 elem->weights[weight_cnt].cnt = 1;
715 else if (arg->tok == tok_bsymbol || arg->tok == tok_ucs4)
718 struct element_t *val;
722 if (arg->tok == tok_bsymbol)
724 symstr = arg->val.str.startmb;
725 symlen = arg->val.str.lenmb;
729 snprintf (ucs4str, sizeof (ucs4str), "U%08X", arg->val.ucs4);
734 val = find_element (ldfile, collate, symstr, symlen);
738 elem->weights[weight_cnt].w = (struct element_t **)
739 obstack_alloc (&collate->mempool, sizeof (struct element_t *));
740 elem->weights[weight_cnt].w[0] = val;
741 elem->weights[weight_cnt].cnt = 1;
743 else if (arg->tok == tok_string)
745 /* Split the string up in the individual characters and put
746 the element definitions in the list. */
747 const char *cp = arg->val.str.startmb;
749 struct element_t *charelem;
750 struct element_t **weights = NULL;
755 lr_error (ldfile, _("%s: empty weight string not allowed"),
757 lr_ignore_rest (ldfile, 0);
765 /* Ahh, it's a bsymbol or an UCS4 value. If it's
766 the latter we have to unify the name. */
767 const char *startp = ++cp;
772 if (*cp == ldfile->escape_char)
775 /* It's a syntax error. */
781 if (cp - startp == 5 && startp[0] == 'U'
782 && isxdigit (startp[1]) && isxdigit (startp[2])
783 && isxdigit (startp[3]) && isxdigit (startp[4]))
785 unsigned int ucs4 = strtoul (startp + 1, NULL, 16);
788 newstr = (char *) xmalloc (10);
789 snprintf (newstr, 10, "U%08X", ucs4);
797 charelem = find_element (ldfile, collate, startp, len);
802 /* People really shouldn't use characters directly in
803 the string. Especially since it's not really clear
804 what this means. We interpret all characters in the
805 string as if that would be bsymbols. Otherwise we
806 would have to match back to bsymbols somehow and this
807 is normally not what people normally expect. */
808 charelem = find_element (ldfile, collate, cp++, 1);
811 if (charelem == NULL)
813 /* We ignore the rest of the line. */
814 lr_ignore_rest (ldfile, 0);
818 /* Add the pointer. */
821 struct element_t **newp;
823 newp = (struct element_t **)
824 alloca (max * sizeof (struct element_t *));
825 memcpy (newp, weights, cnt * sizeof (struct element_t *));
828 weights[cnt++] = charelem;
832 /* Now store the information. */
833 elem->weights[weight_cnt].w = (struct element_t **)
834 obstack_alloc (&collate->mempool,
835 cnt * sizeof (struct element_t *));
836 memcpy (elem->weights[weight_cnt].w, weights,
837 cnt * sizeof (struct element_t *));
838 elem->weights[weight_cnt].cnt = cnt;
840 /* We don't need the string anymore. */
841 free (arg->val.str.startmb);
843 else if (ellipsis != tok_none
844 && (arg->tok == tok_ellipsis2
845 || arg->tok == tok_ellipsis3
846 || arg->tok == tok_ellipsis4))
848 /* It must be the same ellipsis as used in the initial column. */
849 if (arg->tok != ellipsis)
850 lr_error (ldfile, _("\
851 %s: weights must use the same ellipsis symbol as the name"),
854 /* The weight for this level will depend on the element
855 iterating over the range. Put a placeholder. */
856 elem->weights[weight_cnt].w = (struct element_t **)
857 obstack_alloc (&collate->mempool, sizeof (struct element_t *));
858 elem->weights[weight_cnt].w[0] = ELEMENT_ELLIPSIS2;
859 elem->weights[weight_cnt].cnt = 1;
864 /* It's a syntax error. */
865 lr_error (ldfile, _("%s: syntax error"), "LC_COLLATE");
866 lr_ignore_rest (ldfile, 0);
870 arg = lr_token (ldfile, charmap, repertoire, verbose);
871 /* This better should be the end of the line or a semicolon. */
872 if (arg->tok == tok_semicolon)
873 /* OK, ignore this and read the next token. */
874 arg = lr_token (ldfile, charmap, repertoire, verbose);
875 else if (arg->tok != tok_eof && arg->tok != tok_eol)
877 /* It's a syntax error. */
878 lr_error (ldfile, _("%s: syntax error"), "LC_COLLATE");
879 lr_ignore_rest (ldfile, 0);
883 while (++weight_cnt < nrules);
885 if (weight_cnt < nrules)
887 /* This means the rest of the line uses the current element as
891 elem->weights[weight_cnt].w = (struct element_t **)
892 obstack_alloc (&collate->mempool, sizeof (struct element_t *));
893 if (ellipsis == tok_none)
894 elem->weights[weight_cnt].w[0] = elem;
896 elem->weights[weight_cnt].w[0] = ELEMENT_ELLIPSIS2;
897 elem->weights[weight_cnt].cnt = 1;
899 while (++weight_cnt < nrules);
903 if (arg->tok == tok_ignore || arg->tok == tok_bsymbol)
905 /* Too many rule values. */
906 lr_error (ldfile, _("%s: too many values"), "LC_COLLATE");
907 lr_ignore_rest (ldfile, 0);
910 lr_ignore_rest (ldfile, arg->tok != tok_eol && arg->tok != tok_eof);
916 insert_value (struct linereader *ldfile, const char *symstr, size_t symlen,
917 struct charmap_t *charmap, struct repertoire_t *repertoire,
918 struct locale_collate_t *collate)
920 /* First find out what kind of symbol this is. */
923 struct element_t *elem = NULL;
925 /* Try to find the character in the charmap. */
926 seq = charmap_find_value (charmap, symstr, symlen);
928 /* Determine the wide character. */
929 if (seq == NULL || seq->ucs4 == UNINITIALIZED_CHAR_VALUE)
931 wc = repertoire_find_value (repertoire, symstr, symlen);
938 if (wc == ILLEGAL_CHAR_VALUE && seq == NULL)
940 /* It's no character, so look through the collation elements and
944 if (find_entry (&collate->sym_table, symstr, symlen, &result) == 0)
946 /* It's a collation symbol. */
947 struct symbol_t *sym = (struct symbol_t *) result;
951 elem = sym->order = new_element (collate, NULL, 0, NULL,
952 sym->name, strlen (sym->name), 0);
954 else if (find_entry (&collate->elem_table, symstr, symlen,
955 (void **) &elem) != 0)
957 /* It's also no collation element. Therefore ignore it. */
958 lr_ignore_rest (ldfile, 0);
964 /* Otherwise the symbols stands for a character. */
965 if (find_entry (&collate->seq_table, symstr, symlen,
966 (void **) &elem) != 0)
968 uint32_t wcs[2] = { wc, 0 };
970 /* We have to allocate an entry. */
971 elem = new_element (collate, seq != NULL ? seq->bytes : NULL,
972 seq != NULL ? seq->nbytes : 0,
973 wc == ILLEGAL_CHAR_VALUE ? NULL : wcs,
976 /* And add it to the table. */
977 if (insert_entry (&collate->seq_table, symstr, symlen, elem) != 0)
978 /* This cannot happen. */
979 assert (! "Internal error");
983 /* Maybe the character was used before the definition. In this case
984 we have to insert the byte sequences now. */
985 if (elem->mbs == NULL && seq != NULL)
987 elem->mbs = obstack_copy0 (&collate->mempool,
988 seq->bytes, seq->nbytes);
989 elem->nmbs = seq->nbytes;
992 if (elem->wcs == NULL && wc != ILLEGAL_CHAR_VALUE)
994 uint32_t wcs[2] = { wc, 0 };
996 elem->wcs = obstack_copy (&collate->mempool, wcs, sizeof (wcs));
1002 /* Test whether this element is not already in the list. */
1003 if (elem->next != NULL || elem == collate->cursor)
1005 lr_error (ldfile, _("order for `%.*s' already defined at %s:%Zu"),
1006 (int) symlen, symstr, elem->file, elem->line);
1007 lr_ignore_rest (ldfile, 0);
1011 insert_weights (ldfile, elem, charmap, repertoire, collate, tok_none);
1018 handle_ellipsis (struct linereader *ldfile, const char *symstr, size_t symlen,
1019 enum token_t ellipsis, struct charmap_t *charmap,
1020 struct repertoire_t *repertoire,
1021 struct locale_collate_t *collate)
1023 struct element_t *startp;
1024 struct element_t *endp;
1026 /* Unlink the entry added for the ellipsis. */
1027 unlink_element (collate);
1028 startp = collate->cursor;
1030 /* Process and add the end-entry. */
1032 && insert_value (ldfile, symstr, symlen, charmap, repertoire, collate))
1033 /* Something went wrong with inserting the to-value. This means
1034 we cannot process the ellipsis. */
1037 /* Reset the cursor. */
1038 collate->cursor = startp;
1040 /* Now we have to handle many different situations:
1041 - we have to distinguish between the three different ellipsis forms
1042 - the is the ellipsis at the beginning, in the middle, or at the end.
1044 endp = collate->cursor->next;
1045 assert (symstr == NULL || endp != NULL);
1047 /* XXX The following is probably very wrong since also collating symbols
1048 can appear in ranges. But do we want/can refine the test for that? */
1050 /* Both, the start and the end symbol, must stand for characters. */
1051 if ((startp != NULL && (startp->name == NULL || ! startp->is_character))
1052 || (endp != NULL && (endp->name == NULL|| ! endp->is_character)))
1054 lr_error (ldfile, _("\
1055 %s: the start and the end symbol of a range must stand for characters"),
1061 if (ellipsis == tok_ellipsis3)
1063 /* One requirement we make here: the length of the byte
1064 sequences for the first and end character must be the same.
1065 This is mainly to prevent unwanted effects and this is often
1066 not what is wanted. */
1067 size_t len = (startp->mbs != NULL ? startp->nmbs
1068 : (endp->mbs != NULL ? endp->nmbs : 0));
1069 char mbcnt[len + 1];
1070 char mbend[len + 1];
1072 /* Well, this should be caught somewhere else already. Just to
1074 assert (startp == NULL || startp->wcs == NULL || startp->wcs[1] == 0);
1075 assert (endp == NULL || endp->wcs == NULL || endp->wcs[1] == 0);
1077 if (startp != NULL && endp != NULL
1078 && startp->mbs != NULL && endp->mbs != NULL
1079 && startp->nmbs != endp->nmbs)
1081 lr_error (ldfile, _("\
1082 %s: byte sequences of first and last character must have the same length"),
1087 /* Determine whether we have to generate multibyte sequences. */
1088 if ((startp == NULL || startp->mbs != NULL)
1089 && (endp == NULL || endp->mbs != NULL))
1094 /* Prepare the beginning byte sequence. This is either from the
1095 beginning byte sequence or it is all nulls if it was an
1096 initial ellipsis. */
1097 if (startp == NULL || startp->mbs == NULL)
1098 memset (mbcnt, '\0', len);
1101 memcpy (mbcnt, startp->mbs, len);
1103 /* And increment it so that the value is the first one we will
1105 for (cnt = len - 1; cnt >= 0; --cnt)
1106 if (++mbcnt[cnt] != '\0')
1111 /* And the end sequence. */
1112 if (endp == NULL || endp->mbs == NULL)
1113 memset (mbend, '\0', len);
1115 memcpy (mbend, endp->mbs, len);
1118 /* Test whether we have a correct range. */
1119 ret = memcmp (mbcnt, mbend, len);
1123 lr_error (ldfile, _("%s: byte sequence of first character of \
1124 sequence is not lower than that of the last character"), "LC_COLLATE");
1128 /* Generate the byte sequences data. */
1131 struct charseq *seq;
1133 /* Quite a bit of work ahead. We have to find the character
1134 definition for the byte sequence and then determine the
1135 wide character belonging to it. */
1136 seq = charmap_find_symbol (charmap, mbcnt, len);
1139 struct element_t *elem;
1142 /* I don't this this can ever happen. */
1143 assert (seq->name != NULL);
1144 namelen = strlen (seq->name);
1146 if (seq->ucs4 == UNINITIALIZED_CHAR_VALUE)
1147 seq->ucs4 = repertoire_find_value (repertoire, seq->name,
1150 /* Now we are ready to insert the new value in the
1151 sequence. Find out whether the element is
1153 if (find_entry (&collate->seq_table, seq->name, namelen,
1154 (void **) &elem) != 0)
1156 uint32_t wcs[2] = { seq->ucs4, 0 };
1158 /* We have to allocate an entry. */
1159 elem = new_element (collate, mbcnt, len,
1160 seq->ucs4 == ILLEGAL_CHAR_VALUE
1161 ? NULL : wcs, seq->name,
1164 /* And add it to the table. */
1165 if (insert_entry (&collate->seq_table, seq->name,
1166 namelen, elem) != 0)
1167 /* This cannot happen. */
1168 assert (! "Internal error");
1171 /* Test whether this element is not already in the list. */
1172 if (elem->next != NULL || (collate->cursor != NULL
1173 && elem->next == collate->cursor))
1175 lr_error (ldfile, _("\
1176 order for `%.*s' already defined at %s:%Zu"),
1177 (int) namelen, seq->name,
1178 elem->file, elem->line);
1182 /* Enqueue the new element. */
1183 elem->last = collate->cursor;
1184 if (collate->cursor == NULL)
1188 elem->next = collate->cursor->next;
1189 elem->last->next = elem;
1190 if (elem->next != NULL)
1191 elem->next->last = elem;
1193 if (collate->start == NULL)
1195 assert (collate->cursor == NULL);
1196 collate->start = elem;
1198 collate->cursor = elem;
1200 /* Add the weight value. We take them from the
1201 `ellipsis_weights' member of `collate'. */
1202 elem->weights = (struct element_list_t *)
1203 obstack_alloc (&collate->mempool,
1204 nrules * sizeof (struct element_list_t));
1205 for (cnt = 0; cnt < nrules; ++cnt)
1206 if (collate->ellipsis_weight.weights[cnt].cnt == 1
1207 && (collate->ellipsis_weight.weights[cnt].w[0]
1208 == ELEMENT_ELLIPSIS2))
1210 elem->weights[cnt].w = (struct element_t **)
1211 obstack_alloc (&collate->mempool,
1212 sizeof (struct element_t *));
1213 elem->weights[cnt].w[0] = elem;
1214 elem->weights[cnt].cnt = 1;
1218 /* Simply use the weight from `ellipsis_weight'. */
1219 elem->weights[cnt].w =
1220 collate->ellipsis_weight.weights[cnt].w;
1221 elem->weights[cnt].cnt =
1222 collate->ellipsis_weight.weights[cnt].cnt;
1226 /* Increment for the next round. */
1228 for (cnt = len - 1; cnt >= 0; --cnt)
1229 if (++mbcnt[cnt] != '\0')
1232 /* Find out whether this was all. */
1233 if (cnt < 0 || memcmp (mbcnt, mbend, len) >= 0)
1234 /* Yep, that's all. */
1241 /* For symbolic range we naturally must have a beginning and an
1242 end specified by the user. */
1244 lr_error (ldfile, _("\
1245 %s: symbolic range ellipsis must not directly follow `order_start'"),
1247 else if (endp == NULL)
1248 lr_error (ldfile, _("\
1249 %s: symbolic range ellipsis must not be directly followed by `order_end'"),
1253 /* Determine the range. To do so we have to determine the
1254 common prefix of the both names and then the numeric
1255 values of both ends. */
1256 size_t lenfrom = strlen (startp->name);
1257 size_t lento = strlen (endp->name);
1258 char buf[lento + 1];
1263 int base = ellipsis == tok_ellipsis2 ? 16 : 10;
1265 if (lenfrom != lento)
1268 lr_error (ldfile, _("\
1269 `%s' and `%.*s' are no valid names for symbolic range"),
1270 startp->name, (int) lento, endp->name);
1274 while (startp->name[preflen] == endp->name[preflen])
1275 if (startp->name[preflen] == '\0')
1276 /* Nothing to be done. The start and end point are identical
1277 and while inserting the end point we have already given
1278 the user an error message. */
1284 from = strtol (startp->name + preflen, &cp, base);
1285 if ((from == UINT_MAX && errno == ERANGE) || *cp != '\0')
1289 to = strtol (endp->name + preflen, &cp, base);
1290 if ((to == UINT_MAX && errno == ERANGE) || *cp != '\0')
1293 /* Copy the prefix. */
1294 memcpy (buf, startp->name, preflen);
1296 /* Loop over all values. */
1297 for (++from; from < to; ++from)
1299 struct element_t *elem = NULL;
1300 struct charseq *seq;
1304 /* Generate the the name. */
1305 sprintf (buf + preflen, base == 10 ? "%ld" : "%lx", from);
1307 /* Look whether this name is already defined. */
1308 if (find_entry (&collate->seq_table, buf, symlen,
1309 (void **) &elem) == 0)
1311 if (elem->next != NULL || (collate->cursor != NULL
1312 && elem->next == collate->cursor))
1314 lr_error (ldfile, _("\
1315 %s: order for `%.*s' already defined at %s:%Zu"),
1316 "LC_COLLATE", (int) lenfrom, buf,
1317 elem->file, elem->line);
1321 if (elem->name == NULL)
1323 lr_error (ldfile, _("%s: `%s' must be a character"),
1329 if (elem == NULL || (elem->mbs == NULL && elem->wcs == NULL))
1331 /* Search for a character of this name. */
1332 seq = charmap_find_value (charmap, buf, lenfrom);
1333 if (seq == NULL || seq->ucs4 == UNINITIALIZED_CHAR_VALUE)
1335 wc = repertoire_find_value (repertoire, buf, lenfrom);
1343 if (wc == ILLEGAL_CHAR_VALUE && seq == NULL)
1344 /* We don't know anything about a character with this
1345 name. XXX Should we warn? */
1350 uint32_t wcs[2] = { wc, 0 };
1352 /* We have to allocate an entry. */
1353 elem = new_element (collate,
1354 seq != NULL ? seq->bytes : NULL,
1355 seq != NULL ? seq->nbytes : 0,
1356 wc == ILLEGAL_CHAR_VALUE
1357 ? NULL : wcs, buf, lenfrom, 1);
1361 /* Update the element. */
1364 elem->mbs = obstack_copy0 (&collate->mempool,
1365 seq->bytes, seq->nbytes);
1366 elem->nmbs = seq->nbytes;
1369 if (wc != ILLEGAL_CHAR_VALUE)
1373 obstack_grow (&collate->mempool,
1374 &wc, sizeof (uint32_t));
1375 obstack_grow (&collate->mempool,
1376 &zero, sizeof (uint32_t));
1377 elem->wcs = obstack_finish (&collate->mempool);
1382 elem->file = ldfile->fname;
1383 elem->line = ldfile->lineno;
1384 elem->section = collate->current_section;
1387 /* Enqueue the new element. */
1388 elem->last = collate->cursor;
1389 elem->next = collate->cursor->next;
1390 elem->last->next = elem;
1391 if (elem->next != NULL)
1392 elem->next->last = elem;
1393 collate->cursor = elem;
1395 /* Now add the weights. They come from the `ellipsis_weights'
1396 member of `collate'. */
1397 elem->weights = (struct element_list_t *)
1398 obstack_alloc (&collate->mempool,
1399 nrules * sizeof (struct element_list_t));
1400 for (cnt = 0; cnt < nrules; ++cnt)
1401 if (collate->ellipsis_weight.weights[cnt].cnt == 1
1402 && (collate->ellipsis_weight.weights[cnt].w[0]
1403 == ELEMENT_ELLIPSIS2))
1405 elem->weights[cnt].w = (struct element_t **)
1406 obstack_alloc (&collate->mempool,
1407 sizeof (struct element_t *));
1408 elem->weights[cnt].w[0] = elem;
1409 elem->weights[cnt].cnt = 1;
1413 /* Simly use the weight from `ellipsis_weight'. */
1414 elem->weights[cnt].w =
1415 collate->ellipsis_weight.weights[cnt].w;
1416 elem->weights[cnt].cnt =
1417 collate->ellipsis_weight.weights[cnt].cnt;
1426 collate_startup (struct linereader *ldfile, struct localedef_t *locale,
1427 struct localedef_t *copy_locale, int ignore_content)
1429 if (!ignore_content && locale->categories[LC_COLLATE].collate == NULL)
1431 struct locale_collate_t *collate;
1433 if (copy_locale == NULL)
1435 collate = locale->categories[LC_COLLATE].collate =
1436 (struct locale_collate_t *)
1437 xcalloc (1, sizeof (struct locale_collate_t));
1439 /* Init the various data structures. */
1440 init_hash (&collate->elem_table, 100);
1441 init_hash (&collate->sym_table, 100);
1442 init_hash (&collate->seq_table, 500);
1443 obstack_init (&collate->mempool);
1445 collate->col_weight_max = -1;
1448 /* Reuse the copy_locale's data structures. */
1449 collate = locale->categories[LC_COLLATE].collate =
1450 copy_locale->categories[LC_COLLATE].collate;
1453 ldfile->translate_strings = 0;
1454 ldfile->return_widestr = 0;
1459 collate_finish (struct localedef_t *locale, struct charmap_t *charmap)
1461 /* Now is the time when we can assign the individual collation
1462 values for all the symbols. We have possibly different values
1463 for the wide- and the multibyte-character symbols. This is done
1464 since it might make a difference in the encoding if there is in
1465 some cases no multibyte-character but there are wide-characters.
1466 (The other way around it is not important since theencoded
1467 collation value in the wide-character case is 32 bits wide and
1468 therefore requires no encoding).
1470 The lowest collation value assigned is 2. Zero is reserved for
1471 the NUL byte terminating the strings in the `strxfrm'/`wcsxfrm'
1472 functions and 1 is used to separate the individual passes for the
1475 We also have to construct is list with all the bytes/words which
1476 can come first in a sequence, followed by all the elements which
1477 also start with this byte/word. The order is reverse which has
1478 among others the important effect that longer strings are located
1479 first in the list. This is required for the output data since
1480 the algorithm used in `strcoll' etc depends on this.
1482 The multibyte case is easy. We simply sort into an array with
1484 struct locale_collate_t *collate = locale->categories[LC_COLLATE].collate;
1489 struct element_t *runp;
1491 int need_undefined = 0;
1492 struct section_list *sect;
1494 int nr_wide_elems = 0;
1496 if (collate == NULL)
1498 /* No data, no check. */
1500 error (0, 0, _("No definition for %s category found"), "LC_COLLATE");
1504 /* If this assertion is hit change the type in `element_t'. */
1505 assert (nrules <= sizeof (runp->used_in_level) * 8);
1507 /* Make sure that the `position' rule is used either in all sections
1509 for (i = 0; i < nrules; ++i)
1510 for (sect = collate->sections; sect != NULL; sect = sect->next)
1511 if (sect->rules != NULL
1512 && ((sect->rules[i] & sort_position)
1513 != (collate->sections->rules[i] & sort_position)))
1516 %s: `position' must be used for a specific level in all sections or none"),
1521 /* Find out which elements are used at which level. At the same
1522 time we find out whether we have any undefined symbols. */
1523 runp = collate->start;
1524 while (runp != NULL)
1526 if (runp->mbs != NULL)
1528 for (i = 0; i < nrules; ++i)
1532 for (j = 0; j < runp->weights[i].cnt; ++j)
1533 /* A NULL pointer as the weight means IGNORE. */
1534 if (runp->weights[i].w[j] != NULL)
1536 if (runp->weights[i].w[j]->weights == NULL)
1538 error_at_line (0, 0, runp->file, runp->line,
1539 _("symbol `%s' not defined"),
1540 runp->weights[i].w[j]->name);
1543 runp->weights[i].w[j] = &collate->undefined;
1546 /* Set the bit for the level. */
1547 runp->weights[i].w[j]->used_in_level |= 1 << i;
1552 /* Up to the next entry. */
1556 /* Walk through the list of defined sequences and assign weights. Also
1557 create the data structure which will allow generating the single byte
1558 character based tables.
1560 Since at each time only the weights for each of the rules are
1561 only compared to other weights for this rule it is possible to
1562 assign more compact weight values than simply counting all
1563 weights in sequence. We can assign weights from 3, one for each
1564 rule individually and only for those elements, which are actually
1567 Why is this important? It is not for the wide char table. But
1568 it is for the singlebyte output since here larger numbers have to
1569 be encoded to make it possible to emit the value as a byte
1571 for (i = 0; i < nrules; ++i)
1576 runp = collate->start;
1577 while (runp != NULL)
1579 /* Determine the order. */
1580 if (runp->used_in_level != 0)
1582 runp->mborder = (int *) obstack_alloc (&collate->mempool,
1583 nrules * sizeof (int));
1585 for (i = 0; i < nrules; ++i)
1586 if ((runp->used_in_level & (1 << i)) != 0)
1587 runp->mborder[i] = mbact[i]++;
1589 runp->mborder[i] = 0;
1592 if (runp->mbs != NULL)
1594 struct element_t **eptr;
1595 struct element_t *lastp = NULL;
1597 /* Find the point where to insert in the list. */
1598 eptr = &collate->mbheads[((unsigned char *) runp->mbs)[0]];
1599 while (*eptr != NULL)
1601 if ((*eptr)->nmbs < runp->nmbs)
1604 if ((*eptr)->nmbs == runp->nmbs)
1606 int c = memcmp ((*eptr)->mbs, runp->mbs, runp->nmbs);
1610 /* This should not happen. It means that we have
1611 to symbols with the same byte sequence. It is
1612 of course an error. */
1613 error_at_line (0, 0, (*eptr)->file, (*eptr)->line,
1614 _("symbol `%s' has the same encoding as"),
1616 error_at_line (0, 0, runp->file, runp->line,
1617 _("symbol `%s'"), runp->name);
1621 /* Insert it here. */
1625 /* To the next entry. */
1627 eptr = &(*eptr)->mbnext;
1630 /* Set the pointers. */
1631 runp->mbnext = *eptr;
1632 runp->mblast = lastp;
1634 (*eptr)->mblast = runp;
1640 if (runp->used_in_level)
1642 runp->wcorder = wcact++;
1644 /* We take the opportunity to count the elements which have
1649 if (runp->is_character)
1651 if (runp->nmbs == 1)
1652 collate->mbseqorder[((unsigned char *) runp->mbs)[0]] = mbseqact++;
1654 runp->wcseqorder = wcseqact++;
1657 /* Up to the next entry. */
1661 /* Find out whether any of the `mbheads' entries is unset. In this
1662 case we use the UNDEFINED entry. */
1663 for (i = 1; i < 256; ++i)
1664 if (collate->mbheads[i] == NULL)
1667 collate->mbheads[i] = &collate->undefined;
1670 /* Now to the wide character case. */
1671 collate->wcheads.p = 6;
1672 collate->wcheads.q = 10;
1673 wchead_table_init (&collate->wcheads);
1675 collate->wcseqorder.p = 6;
1676 collate->wcseqorder.q = 10;
1677 collseq_table_init (&collate->wcseqorder);
1680 runp = collate->start;
1681 while (runp != NULL)
1683 if (runp->wcs != NULL)
1685 struct element_t *e;
1686 struct element_t **eptr;
1687 struct element_t *lastp;
1689 /* Insert the collation sequence value. */
1690 collseq_table_add (&collate->wcseqorder, runp->wcs[0],
1693 /* Find the point where to insert in the list. */
1694 e = wchead_table_get (&collate->wcheads, runp->wcs[0]);
1697 while (*eptr != NULL)
1699 if ((*eptr)->nwcs < runp->nwcs)
1702 if ((*eptr)->nwcs == runp->nwcs)
1704 int c = wmemcmp ((wchar_t *) (*eptr)->wcs,
1705 (wchar_t *) runp->wcs, runp->nwcs);
1709 /* This should not happen. It means that we have
1710 two symbols with the same byte sequence. It is
1711 of course an error. */
1712 error_at_line (0, 0, (*eptr)->file, (*eptr)->line,
1713 _("symbol `%s' has the same encoding as"),
1715 error_at_line (0, 0, runp->file, runp->line,
1716 _("symbol `%s'"), runp->name);
1720 /* Insert it here. */
1724 /* To the next entry. */
1726 eptr = &(*eptr)->wcnext;
1729 /* Set the pointers. */
1730 runp->wcnext = *eptr;
1731 runp->wclast = lastp;
1733 (*eptr)->wclast = runp;
1736 wchead_table_add (&collate->wcheads, runp->wcs[0], e);
1741 /* Up to the next entry. */
1745 collseq_table_finalize (&collate->wcseqorder);
1747 /* Now determine whether the UNDEFINED entry is needed and if yes,
1748 whether it was defined. */
1749 collate->undefined.used_in_level = need_undefined ? ~0ul : 0;
1750 if (collate->undefined.file == NULL)
1754 /* This seems not to be enforced by recent standards. Don't
1755 emit an error, simply append UNDEFINED at the end. */
1757 error (0, 0, _("no definition of `UNDEFINED'"));
1759 /* Add UNDEFINED at the end. */
1760 collate->undefined.mborder =
1761 (int *) obstack_alloc (&collate->mempool, nrules * sizeof (int));
1763 for (i = 0; i < nrules; ++i)
1764 collate->undefined.mborder[i] = mbact[i]++;
1767 /* In any case we will need the definition for the wide character
1768 case. But we will not complain that it is missing since the
1769 specification strangely enough does not seem to account for
1771 collate->undefined.wcorder = wcact++;
1774 /* Finally, try to unify the rules for the sections. Whenever the rules
1775 for a section are the same as those for another section give the
1776 ruleset the same index. Since there are never many section we can
1777 use an O(n^2) algorithm here. */
1778 sect = collate->sections;
1779 while (sect != NULL && sect->rules == NULL)
1781 assert (sect != NULL);
1785 struct section_list *osect = collate->sections;
1787 while (osect != sect)
1788 if (osect->rules != NULL
1789 && memcmp (osect->rules, sect->rules, nrules) == 0)
1792 osect = osect->next;
1795 sect->ruleidx = ruleidx++;
1797 sect->ruleidx = osect->ruleidx;
1802 while (sect != NULL && sect->rules == NULL);
1804 while (sect != NULL);
1805 /* We are currently not prepared for more than 128 rulesets. But this
1806 should never really be a problem. */
1807 assert (ruleidx <= 128);
1812 output_weight (struct obstack *pool, struct locale_collate_t *collate,
1813 struct element_t *elem)
1818 /* Optimize the use of UNDEFINED. */
1819 if (elem == &collate->undefined)
1820 /* The weights are already inserted. */
1823 /* This byte can start exactly one collation element and this is
1824 a single byte. We can directly give the index to the weights. */
1825 retval = obstack_object_size (pool);
1827 /* Construct the weight. */
1828 for (cnt = 0; cnt < nrules; ++cnt)
1830 char buf[elem->weights[cnt].cnt * 7];
1834 for (i = 0; i < elem->weights[cnt].cnt; ++i)
1835 /* Encode the weight value. We do nothing for IGNORE entries. */
1836 if (elem->weights[cnt].w[i] != NULL)
1837 len += utf8_encode (&buf[len],
1838 elem->weights[cnt].w[i]->mborder[cnt]);
1840 /* And add the buffer content. */
1841 obstack_1grow (pool, len);
1842 obstack_grow (pool, buf, len);
1845 return retval | ((elem->section->ruleidx & 0x7f) << 24);
1850 output_weightwc (struct obstack *pool, struct locale_collate_t *collate,
1851 struct element_t *elem)
1856 /* Optimize the use of UNDEFINED. */
1857 if (elem == &collate->undefined)
1858 /* The weights are already inserted. */
1861 /* This byte can start exactly one collation element and this is
1862 a single byte. We can directly give the index to the weights. */
1863 retval = obstack_object_size (pool) / sizeof (int32_t);
1865 /* Construct the weight. */
1866 for (cnt = 0; cnt < nrules; ++cnt)
1868 int32_t buf[elem->weights[cnt].cnt];
1872 for (i = 0, j = 0; i < elem->weights[cnt].cnt; ++i)
1873 if (elem->weights[cnt].w[i] != NULL)
1874 buf[j++] = elem->weights[cnt].w[i]->wcorder;
1876 /* And add the buffer content. */
1877 obstack_int32_grow (pool, j);
1879 obstack_grow (pool, buf, j * sizeof (int32_t));
1882 return retval | ((elem->section->ruleidx & 0x7f) << 24);
1887 collate_output (struct localedef_t *locale, struct charmap_t *charmap,
1888 const char *output_path)
1890 struct locale_collate_t *collate = locale->categories[LC_COLLATE].collate;
1891 const size_t nelems = _NL_ITEM_INDEX (_NL_NUM_LC_COLLATE);
1892 struct iovec iov[2 + nelems];
1893 struct locale_file data;
1894 uint32_t idx[nelems];
1897 int32_t tablemb[256];
1898 struct obstack weightpool;
1899 struct obstack extrapool;
1900 struct obstack indirectpool;
1901 struct section_list *sect;
1902 struct collidx_table tablewc;
1904 uint32_t *elem_table;
1906 struct element_t *runp;
1908 data.magic = LIMAGIC (LC_COLLATE);
1910 iov[0].iov_base = (void *) &data;
1911 iov[0].iov_len = sizeof (data);
1913 iov[1].iov_base = (void *) idx;
1914 iov[1].iov_len = sizeof (idx);
1916 idx[0] = iov[0].iov_len + iov[1].iov_len;
1919 assert (cnt == _NL_ITEM_INDEX (_NL_COLLATE_NRULES));
1920 iov[2 + cnt].iov_base = &nrules;
1921 iov[2 + cnt].iov_len = sizeof (uint32_t);
1922 idx[1 + cnt] = idx[cnt] + iov[2 + cnt].iov_len;
1925 /* If we have no LC_COLLATE data emit only the number of rules as zero. */
1926 if (collate == NULL)
1930 while (cnt < _NL_ITEM_INDEX (_NL_NUM_LC_COLLATE))
1932 /* The words have to be handled specially. */
1933 if (cnt == _NL_ITEM_INDEX (_NL_COLLATE_SYMB_HASH_SIZEMB))
1935 iov[2 + cnt].iov_base = &dummy;
1936 iov[2 + cnt].iov_len = sizeof (int32_t);
1940 iov[2 + cnt].iov_base = NULL;
1941 iov[2 + cnt].iov_len = 0;
1944 if (cnt + 1 < _NL_ITEM_INDEX (_NL_NUM_LC_COLLATE))
1945 idx[1 + cnt] = idx[cnt] + iov[2 + cnt].iov_len;
1949 assert (cnt == _NL_ITEM_INDEX (_NL_NUM_LC_COLLATE));
1951 write_locale_data (output_path, "LC_COLLATE", 2 + cnt, iov);
1956 obstack_init (&weightpool);
1957 obstack_init (&extrapool);
1958 obstack_init (&indirectpool);
1960 /* Since we are using the sign of an integer to mark indirection the
1961 offsets in the arrays we are indirectly referring to must not be
1962 zero since -0 == 0. Therefore we add a bit of dummy content. */
1963 obstack_int32_grow (&extrapool, 0);
1964 obstack_int32_grow (&indirectpool, 0);
1966 /* Prepare the ruleset table. */
1967 for (sect = collate->sections, i = 0; sect != NULL; sect = sect->next)
1968 if (sect->rules != NULL && sect->ruleidx == i)
1972 obstack_make_room (&weightpool, nrules);
1974 for (j = 0; j < nrules; ++j)
1975 obstack_1grow_fast (&weightpool, sect->rules[j]);
1978 /* And align the output. */
1979 i = (nrules * i) % __alignof__ (int32_t);
1982 obstack_1grow (&weightpool, '\0');
1983 while (++i < __alignof__ (int32_t));
1985 assert (cnt == _NL_ITEM_INDEX (_NL_COLLATE_RULESETS));
1986 iov[2 + cnt].iov_len = obstack_object_size (&weightpool);
1987 iov[2 + cnt].iov_base = obstack_finish (&weightpool);
1988 idx[1 + cnt] = idx[cnt] + iov[2 + cnt].iov_len;
1991 /* Generate the 8-bit table. Walk through the lists of sequences
1992 starting with the same byte and add them one after the other to
1993 the table. In case we have more than one sequence starting with
1994 the same byte we have to use extra indirection.
1996 First add a record for the NUL byte. This entry will never be used
1997 so it does not matter. */
2000 /* Now insert the `UNDEFINED' value if it is used. Since this value
2001 will probably be used more than once it is good to store the
2002 weights only once. */
2003 if (collate->undefined.used_in_level != 0)
2004 output_weight (&weightpool, collate, &collate->undefined);
2006 for (ch = 1; ch < 256; ++ch)
2007 if (collate->mbheads[ch]->mbnext == NULL
2008 && collate->mbheads[ch]->nmbs <= 1)
2010 tablemb[ch] = output_weight (&weightpool, collate,
2011 collate->mbheads[ch]);
2015 /* The entries in the list are sorted by length and then
2016 alphabetically. This is the order in which we will add the
2017 elements to the collation table. This allows simply walking
2018 the table in sequence and stopping at the first matching
2019 entry. Since the longer sequences are coming first in the
2020 list they have the possibility to match first, just as it
2021 has to be. In the worst case we are walking to the end of
2022 the list where we put, if no singlebyte sequence is defined
2023 in the locale definition, the weights for UNDEFINED.
2025 To reduce the length of the search list we compress them a bit.
2026 This happens by collecting sequences of consecutive byte
2027 sequences in one entry (having and begin and end byte sequence)
2028 and add only one index into the weight table. We can find the
2029 consecutive entries since they are also consecutive in the list. */
2030 struct element_t *runp = collate->mbheads[ch];
2031 struct element_t *lastp;
2033 assert ((obstack_object_size (&extrapool)
2034 & (__alignof__ (int32_t) - 1)) == 0);
2036 tablemb[ch] = -obstack_object_size (&extrapool);
2040 /* Store the current index in the weight table. We know that
2041 the current position in the `extrapool' is aligned on a
2046 /* Find out wether this is a single entry or we have more than
2047 one consecutive entry. */
2048 if (runp->mbnext != NULL
2049 && runp->nmbs == runp->mbnext->nmbs
2050 && memcmp (runp->mbs, runp->mbnext->mbs, runp->nmbs - 1) == 0
2051 && (runp->mbs[runp->nmbs - 1]
2052 == runp->mbnext->mbs[runp->nmbs - 1] + 1))
2055 struct element_t *series_startp = runp;
2056 struct element_t *curp;
2058 /* Compute how much space we will need. */
2059 added = ((sizeof (int32_t) + 1 + 2 * (runp->nmbs - 1)
2060 + __alignof__ (int32_t) - 1)
2061 & ~(__alignof__ (int32_t) - 1));
2062 assert ((obstack_object_size (&extrapool)
2063 & (__alignof__ (int32_t) - 1)) == 0);
2064 obstack_make_room (&extrapool, added);
2066 /* More than one consecutive entry. We mark this by having
2067 a negative index into the indirect table. */
2068 obstack_int32_grow_fast (&extrapool,
2069 -(obstack_object_size (&indirectpool)
2070 / sizeof (int32_t)));
2072 /* Now search first the end of the series. */
2074 runp = runp->mbnext;
2075 while (runp->mbnext != NULL
2076 && runp->nmbs == runp->mbnext->nmbs
2077 && memcmp (runp->mbs, runp->mbnext->mbs,
2078 runp->nmbs - 1) == 0
2079 && (runp->mbs[runp->nmbs - 1]
2080 == runp->mbnext->mbs[runp->nmbs - 1] + 1));
2082 /* Now walk backward from here to the beginning. */
2085 assert (runp->nmbs <= 256);
2086 obstack_1grow_fast (&extrapool, curp->nmbs - 1);
2087 for (i = 1; i < curp->nmbs; ++i)
2088 obstack_1grow_fast (&extrapool, curp->mbs[i]);
2090 /* Now find the end of the consecutive sequence and
2091 add all the indeces in the indirect pool. */
2094 weightidx = output_weight (&weightpool, collate, curp);
2095 obstack_int32_grow (&indirectpool, weightidx);
2097 curp = curp->mblast;
2099 while (curp != series_startp);
2101 /* Add the final weight. */
2102 weightidx = output_weight (&weightpool, collate, curp);
2103 obstack_int32_grow (&indirectpool, weightidx);
2105 /* And add the end byte sequence. Without length this
2107 for (i = 1; i < curp->nmbs; ++i)
2108 obstack_1grow_fast (&extrapool, curp->mbs[i]);
2112 /* A single entry. Simply add the index and the length and
2113 string (except for the first character which is already
2117 /* Output the weight info. */
2118 weightidx = output_weight (&weightpool, collate, runp);
2120 added = ((sizeof (int32_t) + 1 + runp->nmbs - 1
2121 + __alignof__ (int32_t) - 1)
2122 & ~(__alignof__ (int32_t) - 1));
2123 assert ((obstack_object_size (&extrapool)
2124 & (__alignof__ (int32_t) - 1)) == 0);
2125 obstack_make_room (&extrapool, added);
2127 obstack_int32_grow_fast (&extrapool, weightidx);
2128 assert (runp->nmbs <= 256);
2129 obstack_1grow_fast (&extrapool, runp->nmbs - 1);
2131 for (i = 1; i < runp->nmbs; ++i)
2132 obstack_1grow_fast (&extrapool, runp->mbs[i]);
2135 /* Add alignment bytes if necessary. */
2136 while ((obstack_object_size (&extrapool)
2137 & (__alignof__ (int32_t) - 1)) != 0)
2138 obstack_1grow_fast (&extrapool, '\0');
2142 runp = runp->mbnext;
2144 while (runp != NULL);
2146 assert ((obstack_object_size (&extrapool)
2147 & (__alignof__ (int32_t) - 1)) == 0);
2149 /* If the final entry in the list is not a single character we
2150 add an UNDEFINED entry here. */
2151 if (lastp->nmbs != 1)
2153 int added = ((sizeof (int32_t) + 1 + 1 + __alignof__ (int32_t) - 1)
2154 & ~(__alignof__ (int32_t) - 1));
2155 obstack_make_room (&extrapool, added);
2157 obstack_int32_grow_fast (&extrapool, 0);
2158 /* XXX What rule? We just pick the first. */
2159 obstack_1grow_fast (&extrapool, 0);
2160 /* Length is zero. */
2161 obstack_1grow_fast (&extrapool, 0);
2163 /* Add alignment bytes if necessary. */
2164 while ((obstack_object_size (&extrapool)
2165 & (__alignof__ (int32_t) - 1)) != 0)
2166 obstack_1grow_fast (&extrapool, '\0');
2170 /* Add padding to the tables if necessary. */
2171 while ((obstack_object_size (&weightpool) & (__alignof__ (int32_t) - 1))
2173 obstack_1grow (&weightpool, 0);
2175 /* Now add the four tables. */
2176 assert (cnt == _NL_ITEM_INDEX (_NL_COLLATE_TABLEMB));
2177 iov[2 + cnt].iov_base = tablemb;
2178 iov[2 + cnt].iov_len = sizeof (tablemb);
2179 idx[1 + cnt] = idx[cnt] + iov[2 + cnt].iov_len;
2180 assert ((iov[2 + cnt].iov_len & (__alignof__ (int32_t) - 1)) == 0);
2183 assert (cnt == _NL_ITEM_INDEX (_NL_COLLATE_WEIGHTMB));
2184 iov[2 + cnt].iov_len = obstack_object_size (&weightpool);
2185 iov[2 + cnt].iov_base = obstack_finish (&weightpool);
2186 idx[1 + cnt] = idx[cnt] + iov[2 + cnt].iov_len;
2189 assert (cnt == _NL_ITEM_INDEX (_NL_COLLATE_EXTRAMB));
2190 iov[2 + cnt].iov_len = obstack_object_size (&extrapool);
2191 iov[2 + cnt].iov_base = obstack_finish (&extrapool);
2192 idx[1 + cnt] = idx[cnt] + iov[2 + cnt].iov_len;
2195 assert (cnt == _NL_ITEM_INDEX (_NL_COLLATE_INDIRECTMB));
2196 iov[2 + cnt].iov_len = obstack_object_size (&indirectpool);
2197 iov[2 + cnt].iov_base = obstack_finish (&indirectpool);
2198 idx[1 + cnt] = idx[cnt] + iov[2 + cnt].iov_len;
2199 assert ((iov[2 + cnt].iov_len & (__alignof__ (int32_t) - 1)) == 0);
2203 /* Now the same for the wide character table. We need to store some
2204 more information here. */
2205 assert (cnt == _NL_ITEM_INDEX (_NL_COLLATE_GAP1));
2206 iov[2 + cnt].iov_base = NULL;
2207 iov[2 + cnt].iov_len = 0;
2208 idx[1 + cnt] = idx[cnt] + iov[2 + cnt].iov_len;
2209 assert (idx[cnt] % __alignof__ (int32_t) == 0);
2212 assert (cnt == _NL_ITEM_INDEX (_NL_COLLATE_GAP2));
2213 iov[2 + cnt].iov_base = NULL;
2214 iov[2 + cnt].iov_len = 0;
2215 idx[1 + cnt] = idx[cnt] + iov[2 + cnt].iov_len;
2216 assert (idx[cnt] % __alignof__ (int32_t) == 0);
2219 assert (cnt == _NL_ITEM_INDEX (_NL_COLLATE_GAP3));
2220 iov[2 + cnt].iov_base = NULL;
2221 iov[2 + cnt].iov_len = 0;
2222 idx[1 + cnt] = idx[cnt] + iov[2 + cnt].iov_len;
2223 assert (idx[cnt] % __alignof__ (int32_t) == 0);
2226 /* Since we are using the sign of an integer to mark indirection the
2227 offsets in the arrays we are indirectly referring to must not be
2228 zero since -0 == 0. Therefore we add a bit of dummy content. */
2229 obstack_int32_grow (&extrapool, 0);
2230 obstack_int32_grow (&indirectpool, 0);
2232 /* Now insert the `UNDEFINED' value if it is used. Since this value
2233 will probably be used more than once it is good to store the
2234 weights only once. */
2235 if (output_weightwc (&weightpool, collate, &collate->undefined) != 0)
2238 /* Generate the table. Walk through the lists of sequences starting
2239 with the same wide character and add them one after the other to
2240 the table. In case we have more than one sequence starting with
2241 the same byte we have to use extra indirection. */
2243 auto void add_to_tablewc (uint32_t ch, struct element_t *runp);
2245 void add_to_tablewc (uint32_t ch, struct element_t *runp)
2247 if (runp->wcnext == NULL && runp->nwcs == 1)
2249 int32_t weigthidx = output_weightwc (&weightpool, collate, runp);
2250 collidx_table_add (&tablewc, ch, weigthidx);
2254 /* As for the singlebyte table, we recognize sequences and
2256 struct element_t *lastp;
2258 collidx_table_add (&tablewc, ch,
2259 -(obstack_object_size (&extrapool) / sizeof (uint32_t)));
2263 /* Store the current index in the weight table. We know that
2264 the current position in the `extrapool' is aligned on a
2269 /* Find out wether this is a single entry or we have more than
2270 one consecutive entry. */
2271 if (runp->wcnext != NULL
2272 && runp->nwcs == runp->wcnext->nwcs
2273 && wmemcmp ((wchar_t *) runp->wcs,
2274 (wchar_t *)runp->wcnext->wcs,
2275 runp->nwcs - 1) == 0
2276 && (runp->wcs[runp->nwcs - 1]
2277 == runp->wcnext->wcs[runp->nwcs - 1] + 1))
2280 struct element_t *series_startp = runp;
2281 struct element_t *curp;
2283 /* Now add first the initial byte sequence. */
2284 added = (1 + 1 + 2 * (runp->nwcs - 1)) * sizeof (int32_t);
2285 if (sizeof (int32_t) == sizeof (int))
2286 obstack_make_room (&extrapool, added);
2288 /* More than one consecutive entry. We mark this by having
2289 a negative index into the indirect table. */
2290 obstack_int32_grow_fast (&extrapool,
2291 -(obstack_object_size (&indirectpool)
2292 / sizeof (int32_t)));
2293 obstack_int32_grow_fast (&extrapool, runp->nwcs - 1);
2296 runp = runp->wcnext;
2297 while (runp->wcnext != NULL
2298 && runp->nwcs == runp->wcnext->nwcs
2299 && wmemcmp ((wchar_t *) runp->wcs,
2300 (wchar_t *)runp->wcnext->wcs,
2301 runp->nwcs - 1) == 0
2302 && (runp->wcs[runp->nwcs - 1]
2303 == runp->wcnext->wcs[runp->nwcs - 1] + 1));
2305 /* Now walk backward from here to the beginning. */
2308 for (i = 1; i < runp->nwcs; ++i)
2309 obstack_int32_grow_fast (&extrapool, curp->wcs[i]);
2311 /* Now find the end of the consecutive sequence and
2312 add all the indeces in the indirect pool. */
2315 weightidx = output_weightwc (&weightpool, collate,
2317 obstack_int32_grow (&indirectpool, weightidx);
2319 curp = curp->wclast;
2321 while (curp != series_startp);
2323 /* Add the final weight. */
2324 weightidx = output_weightwc (&weightpool, collate, curp);
2325 obstack_int32_grow (&indirectpool, weightidx);
2327 /* And add the end byte sequence. Without length this
2329 for (i = 1; i < curp->nwcs; ++i)
2330 obstack_int32_grow (&extrapool, curp->wcs[i]);
2334 /* A single entry. Simply add the index and the length and
2335 string (except for the first character which is already
2339 /* Output the weight info. */
2340 weightidx = output_weightwc (&weightpool, collate, runp);
2342 added = (1 + 1 + runp->nwcs - 1) * sizeof (int32_t);
2343 if (sizeof (int) == sizeof (int32_t))
2344 obstack_make_room (&extrapool, added);
2346 obstack_int32_grow_fast (&extrapool, weightidx);
2347 obstack_int32_grow_fast (&extrapool, runp->nwcs - 1);
2348 for (i = 1; i < runp->nwcs; ++i)
2349 obstack_int32_grow_fast (&extrapool, runp->wcs[i]);
2354 runp = runp->wcnext;
2356 while (runp != NULL);
2362 collidx_table_init (&tablewc);
2364 wchead_table_iterate (&collate->wcheads, add_to_tablewc);
2366 collidx_table_finalize (&tablewc);
2369 /* Now add the four tables. */
2370 assert (cnt == _NL_ITEM_INDEX (_NL_COLLATE_TABLEWC));
2371 iov[2 + cnt].iov_base = tablewc.result;
2372 iov[2 + cnt].iov_len = tablewc.result_size;
2373 idx[1 + cnt] = idx[cnt] + iov[2 + cnt].iov_len;
2374 assert (iov[2 + cnt].iov_len % sizeof (int32_t) == 0);
2375 assert (idx[cnt] % __alignof__ (int32_t) == 0);
2378 assert (cnt == _NL_ITEM_INDEX (_NL_COLLATE_WEIGHTWC));
2379 iov[2 + cnt].iov_len = obstack_object_size (&weightpool);
2380 iov[2 + cnt].iov_base = obstack_finish (&weightpool);
2381 idx[1 + cnt] = idx[cnt] + iov[2 + cnt].iov_len;
2382 assert (iov[2 + cnt].iov_len % sizeof (int32_t) == 0);
2383 assert (idx[cnt] % __alignof__ (int32_t) == 0);
2386 assert (cnt == _NL_ITEM_INDEX (_NL_COLLATE_EXTRAWC));
2387 iov[2 + cnt].iov_len = obstack_object_size (&extrapool);
2388 iov[2 + cnt].iov_base = obstack_finish (&extrapool);
2389 idx[1 + cnt] = idx[cnt] + iov[2 + cnt].iov_len;
2390 assert (iov[2 + cnt].iov_len % sizeof (int32_t) == 0);
2391 assert (idx[cnt] % __alignof__ (int32_t) == 0);
2394 assert (cnt == _NL_ITEM_INDEX (_NL_COLLATE_INDIRECTWC));
2395 iov[2 + cnt].iov_len = obstack_object_size (&indirectpool);
2396 iov[2 + cnt].iov_base = obstack_finish (&indirectpool);
2397 idx[1 + cnt] = idx[cnt] + iov[2 + cnt].iov_len;
2398 assert (iov[2 + cnt].iov_len % sizeof (int32_t) == 0);
2399 assert (idx[cnt] % __alignof__ (int32_t) == 0);
2403 /* Finally write the table with collation element names out. It is
2404 a hash table with a simple function which gets the name of the
2405 character as the input. One character might have many names. The
2406 value associated with the name is an index into the weight table
2407 where we are then interested in the first-level weight value.
2409 To determine how large the table should be we are counting the
2410 elements have to put in. Since we are using internal chaining
2411 using a secondary hash function we have to make the table a bit
2412 larger to avoid extremely long search times. We can achieve
2413 good results with a 40% larger table than there are entries. */
2415 runp = collate->start;
2416 while (runp != NULL)
2418 if (runp->mbs != NULL && runp->weights != NULL)
2419 /* Yep, the element really counts. */
2424 /* Add 40% and find the next prime number. */
2425 elem_size = MIN (next_prime (elem_size * 1.4), 257);
2427 /* Allocate the table. Each entry consists of two words: the hash
2428 value and an index in a secondary table which provides the index
2429 into the weight table and the string itself (so that a match can
2431 elem_table = (uint32_t *) obstack_alloc (&extrapool,
2432 elem_size * 2 * sizeof (uint32_t));
2433 memset (elem_table, '\0', elem_size * 2 * sizeof (uint32_t));
2435 /* Now add the elements. */
2436 runp = collate->start;
2437 while (runp != NULL)
2439 if (runp->mbs != NULL && runp->weights != NULL)
2441 /* Compute the hash value of the name. */
2442 uint32_t namelen = strlen (runp->name);
2443 uint32_t hash = elem_hash (runp->name, namelen);
2444 size_t idx = hash % elem_size;
2446 if (elem_table[idx * 2] != 0)
2448 /* The spot is already take. Try iterating using the value
2449 from the secondary hashing function. */
2450 size_t iter = hash % (elem_size - 2);
2455 if (idx >= elem_size)
2458 while (elem_table[idx * 2] != 0);
2460 /* This is the spot where we will insert the value. */
2461 elem_table[idx * 2] = hash;
2462 elem_table[idx * 2 + 1] = obstack_object_size (&extrapool);
2464 /* The the string itself including length. */
2465 obstack_1grow (&extrapool, namelen);
2466 obstack_grow (&extrapool, runp->name, namelen);
2468 /* And the multibyte representation. */
2469 obstack_1grow (&extrapool, runp->nmbs);
2470 obstack_grow (&extrapool, runp->mbs, runp->nmbs);
2472 /* And align again to 32 bits. */
2473 if ((1 + namelen + 1 + runp->nmbs) % sizeof (int32_t) != 0)
2474 obstack_grow (&extrapool, "\0\0",
2476 - ((1 + namelen + 1 + runp->nmbs)
2477 % sizeof (int32_t))));
2479 /* Now some 32-bit values: multibyte collation sequence,
2480 wide char string (including length), and wide char
2481 collation sequence. */
2482 obstack_int32_grow (&extrapool, runp->mbseqorder);
2484 obstack_int32_grow (&extrapool, runp->nwcs);
2485 obstack_grow (&extrapool, runp->wcs,
2486 runp->nwcs * sizeof (uint32_t));
2488 obstack_int32_grow (&extrapool, runp->wcseqorder);
2495 /* Prepare to write out this data. */
2496 assert (cnt == _NL_ITEM_INDEX (_NL_COLLATE_SYMB_HASH_SIZEMB));
2497 iov[2 + cnt].iov_base = &elem_size;
2498 iov[2 + cnt].iov_len = sizeof (int32_t);
2499 idx[1 + cnt] = idx[cnt] + iov[2 + cnt].iov_len;
2500 assert (idx[cnt] % __alignof__ (int32_t) == 0);
2503 assert (cnt == _NL_ITEM_INDEX (_NL_COLLATE_SYMB_TABLEMB));
2504 iov[2 + cnt].iov_base = elem_table;
2505 iov[2 + cnt].iov_len = elem_size * 2 * sizeof (int32_t);
2506 idx[1 + cnt] = idx[cnt] + iov[2 + cnt].iov_len;
2507 assert (idx[cnt] % __alignof__ (int32_t) == 0);
2510 assert (cnt == _NL_ITEM_INDEX (_NL_COLLATE_SYMB_EXTRAMB));
2511 iov[2 + cnt].iov_len = obstack_object_size (&extrapool);
2512 iov[2 + cnt].iov_base = obstack_finish (&extrapool);
2513 idx[1 + cnt] = idx[cnt] + iov[2 + cnt].iov_len;
2516 assert (cnt == _NL_ITEM_INDEX (_NL_COLLATE_COLLSEQMB));
2517 iov[2 + cnt].iov_base = collate->mbseqorder;
2518 iov[2 + cnt].iov_len = 256;
2519 idx[1 + cnt] = idx[cnt] + iov[2 + cnt].iov_len;
2522 assert (cnt == _NL_ITEM_INDEX (_NL_COLLATE_COLLSEQWC));
2523 iov[2 + cnt].iov_base = collate->wcseqorder.result;
2524 iov[2 + cnt].iov_len = collate->wcseqorder.result_size;
2525 idx[1 + cnt] = idx[cnt] + iov[2 + cnt].iov_len;
2526 assert (idx[cnt] % __alignof__ (int32_t) == 0);
2529 assert (cnt == _NL_ITEM_INDEX (_NL_COLLATE_CODESET));
2530 iov[2 + cnt].iov_base = (void *) charmap->code_set_name;
2531 iov[2 + cnt].iov_len = strlen (iov[2 + cnt].iov_base) + 1;
2534 assert (cnt == _NL_ITEM_INDEX (_NL_NUM_LC_COLLATE));
2536 write_locale_data (output_path, "LC_COLLATE", 2 + cnt, iov);
2538 obstack_free (&weightpool, NULL);
2539 obstack_free (&extrapool, NULL);
2540 obstack_free (&indirectpool, NULL);
2545 collate_read (struct linereader *ldfile, struct localedef_t *result,
2546 struct charmap_t *charmap, const char *repertoire_name,
2549 struct repertoire_t *repertoire = NULL;
2550 struct locale_collate_t *collate;
2552 struct token *arg = NULL;
2553 enum token_t nowtok;
2554 enum token_t was_ellipsis = tok_none;
2555 struct localedef_t *copy_locale = NULL;
2558 1 - between `order-start' and `order-end'
2559 2 - after `order-end'
2560 3 - after `reorder-after', waiting for `reorder-end'
2561 4 - after `reorder-end'
2562 5 - after `reorder-sections-after', waiting for `reorder-sections-end'
2563 6 - after `reorder-sections-end'
2567 /* Get the repertoire we have to use. */
2568 if (repertoire_name != NULL)
2569 repertoire = repertoire_read (repertoire_name);
2571 /* The rest of the line containing `LC_COLLATE' must be free. */
2572 lr_ignore_rest (ldfile, 1);
2576 now = lr_token (ldfile, charmap, NULL, verbose);
2579 while (nowtok == tok_eol);
2581 if (nowtok == tok_copy)
2584 now = lr_token (ldfile, charmap, NULL, verbose);
2585 if (now->tok != tok_string)
2587 SYNTAX_ERROR (_("%s: syntax error"), "LC_COLLATE");
2591 now = lr_token (ldfile, charmap, NULL, verbose);
2592 while (now->tok != tok_eof && now->tok != tok_end);
2594 if (now->tok != tok_eof
2595 || (now = lr_token (ldfile, charmap, NULL, verbose),
2596 now->tok == tok_eof))
2597 lr_error (ldfile, _("%s: premature end of file"), "LC_COLLATE");
2598 else if (now->tok != tok_lc_collate)
2600 lr_error (ldfile, _("\
2601 %1$s: definition does not end with `END %1$s'"), "LC_COLLATE");
2602 lr_ignore_rest (ldfile, 0);
2605 lr_ignore_rest (ldfile, 1);
2610 if (! ignore_content)
2612 /* Get the locale definition. */
2613 copy_locale = load_locale (LC_COLLATE, now->val.str.startmb,
2614 repertoire_name, charmap, NULL);
2615 if ((copy_locale->avail & COLLATE_LOCALE) == 0)
2617 /* Not yet loaded. So do it now. */
2618 if (locfile_read (copy_locale, charmap) != 0)
2623 lr_ignore_rest (ldfile, 1);
2625 now = lr_token (ldfile, charmap, NULL, verbose);
2629 /* Prepare the data structures. */
2630 collate_startup (ldfile, result, copy_locale, ignore_content);
2631 collate = result->categories[LC_COLLATE].collate;
2639 /* Of course we don't proceed beyond the end of file. */
2640 if (nowtok == tok_eof)
2643 /* Ingore empty lines. */
2644 if (nowtok == tok_eol)
2646 now = lr_token (ldfile, charmap, NULL, verbose);
2654 /* Allow copying other locales. */
2655 now = lr_token (ldfile, charmap, NULL, verbose);
2656 if (now->tok != tok_string)
2659 if (! ignore_content)
2660 load_locale (LC_COLLATE, now->val.str.startmb, repertoire_name,
2663 lr_ignore_rest (ldfile, 1);
2666 case tok_coll_weight_max:
2667 /* Ignore the rest of the line if we don't need the input of
2671 lr_ignore_rest (ldfile, 0);
2678 arg = lr_token (ldfile, charmap, NULL, verbose);
2679 if (arg->tok != tok_number)
2681 if (collate->col_weight_max != -1)
2682 lr_error (ldfile, _("%s: duplicate definition of `%s'"),
2683 "LC_COLLATE", "col_weight_max");
2685 collate->col_weight_max = arg->val.num;
2686 lr_ignore_rest (ldfile, 1);
2689 case tok_section_symbol:
2690 /* Ignore the rest of the line if we don't need the input of
2694 lr_ignore_rest (ldfile, 0);
2701 arg = lr_token (ldfile, charmap, repertoire, verbose);
2702 if (arg->tok != tok_bsymbol)
2704 else if (!ignore_content)
2706 /* Check whether this section is already known. */
2707 struct section_list *known = collate->sections;
2708 while (known != NULL)
2710 if (strcmp (known->name, arg->val.str.startmb) == 0)
2712 known = known->next;
2718 _("%s: duplicate declaration of section `%s'"),
2719 "LC_COLLATE", arg->val.str.startmb);
2720 free (arg->val.str.startmb);
2723 collate->sections = make_seclist_elem (collate,
2724 arg->val.str.startmb,
2727 lr_ignore_rest (ldfile, known == NULL);
2731 free (arg->val.str.startmb);
2732 lr_ignore_rest (ldfile, 0);
2736 case tok_collating_element:
2737 /* Ignore the rest of the line if we don't need the input of
2741 lr_ignore_rest (ldfile, 0);
2745 if (state != 0 && state != 2)
2748 arg = lr_token (ldfile, charmap, repertoire, verbose);
2749 if (arg->tok != tok_bsymbol)
2753 const char *symbol = arg->val.str.startmb;
2754 size_t symbol_len = arg->val.str.lenmb;
2756 /* Next the `from' keyword. */
2757 arg = lr_token (ldfile, charmap, repertoire, verbose);
2758 if (arg->tok != tok_from)
2760 free ((char *) symbol);
2764 ldfile->return_widestr = 1;
2765 ldfile->translate_strings = 1;
2767 /* Finally the string with the replacement. */
2768 arg = lr_token (ldfile, charmap, repertoire, verbose);
2770 ldfile->return_widestr = 0;
2771 ldfile->translate_strings = 0;
2773 if (arg->tok != tok_string)
2776 if (!ignore_content && symbol != NULL)
2778 /* The name is already defined. */
2779 if (check_duplicate (ldfile, collate, charmap,
2780 repertoire, symbol, symbol_len))
2783 if (arg->val.str.startmb != NULL)
2784 insert_entry (&collate->elem_table, symbol, symbol_len,
2785 new_element (collate,
2786 arg->val.str.startmb,
2787 arg->val.str.lenmb - 1,
2788 arg->val.str.startwc,
2789 symbol, symbol_len, 0));
2795 free ((char *) symbol);
2796 if (arg->val.str.startmb != NULL)
2797 free (arg->val.str.startmb);
2798 if (arg->val.str.startwc != NULL)
2799 free (arg->val.str.startwc);
2801 lr_ignore_rest (ldfile, 1);
2805 case tok_collating_symbol:
2806 /* Ignore the rest of the line if we don't need the input of
2810 lr_ignore_rest (ldfile, 0);
2814 if (state != 0 && state != 2)
2817 arg = lr_token (ldfile, charmap, repertoire, verbose);
2818 if (arg->tok != tok_bsymbol)
2822 char *symbol = arg->val.str.startmb;
2823 size_t symbol_len = arg->val.str.lenmb;
2824 char *endsymbol = NULL;
2825 size_t endsymbol_len = 0;
2826 enum token_t ellipsis = tok_none;
2828 arg = lr_token (ldfile, charmap, repertoire, verbose);
2829 if (arg->tok == tok_ellipsis2 || arg->tok == tok_ellipsis4)
2831 ellipsis = arg->tok;
2833 arg = lr_token (ldfile, charmap, repertoire, verbose);
2834 if (arg->tok != tok_bsymbol)
2840 endsymbol = arg->val.str.startmb;
2841 endsymbol_len = arg->val.str.lenmb;
2843 lr_ignore_rest (ldfile, 1);
2845 else if (arg->tok != tok_eol)
2851 if (!ignore_content)
2854 || (ellipsis != tok_none && endsymbol == NULL))
2856 lr_error (ldfile, _("\
2857 %s: unknown character in collating symbol name"),
2861 else if (ellipsis == tok_none)
2863 /* A single symbol, no ellipsis. */
2864 if (check_duplicate (ldfile, collate, charmap,
2865 repertoire, symbol, symbol_len))
2866 /* The name is already defined. */
2869 insert_entry (&collate->sym_table, symbol, symbol_len,
2870 new_symbol (collate, symbol, symbol_len));
2872 else if (symbol_len != endsymbol_len)
2876 _("invalid names for character range"));
2881 /* Oh my, we have to handle an ellipsis. First, as
2882 usual, determine the common prefix and then
2883 convert the rest into a range. */
2885 unsigned long int from;
2886 unsigned long int to;
2889 for (prefixlen = 0; prefixlen < symbol_len; ++prefixlen)
2890 if (symbol[prefixlen] != endsymbol[prefixlen])
2893 /* Convert the rest into numbers. */
2894 symbol[symbol_len] = '\0';
2895 from = strtoul (&symbol[prefixlen], &endp,
2896 ellipsis == tok_ellipsis2 ? 16 : 10);
2898 goto col_sym_inv_range;
2900 endsymbol[symbol_len] = '\0';
2901 to = strtoul (&endsymbol[prefixlen], &endp,
2902 ellipsis == tok_ellipsis2 ? 16 : 10);
2904 goto col_sym_inv_range;
2907 goto col_sym_inv_range;
2909 /* Now loop over all entries. */
2914 symbuf = (char *) obstack_alloc (&collate->mempool,
2917 /* Create the name. */
2919 ellipsis == tok_ellipsis2
2920 ? "%.*s%.*lX" : "%.*s%.*lu",
2921 (int) prefixlen, symbol,
2922 (int) (symbol_len - prefixlen), from);
2924 if (check_duplicate (ldfile, collate, charmap,
2925 repertoire, symbuf, symbol_len))
2926 /* The name is already defined. */
2929 insert_entry (&collate->sym_table, symbuf,
2931 new_symbol (collate, symbuf,
2934 /* Increment the counter. */
2946 if (endsymbol != NULL)
2952 case tok_symbol_equivalence:
2953 /* Ignore the rest of the line if we don't need the input of
2957 lr_ignore_rest (ldfile, 0);
2964 arg = lr_token (ldfile, charmap, repertoire, verbose);
2965 if (arg->tok != tok_bsymbol)
2969 const char *newname = arg->val.str.startmb;
2970 size_t newname_len = arg->val.str.lenmb;
2971 const char *symname;
2973 struct symbol_t *symval;
2975 arg = lr_token (ldfile, charmap, repertoire, verbose);
2976 if (arg->tok != tok_bsymbol)
2978 if (newname != NULL)
2979 free ((char *) newname);
2983 symname = arg->val.str.startmb;
2984 symname_len = arg->val.str.lenmb;
2986 if (newname == NULL)
2988 lr_error (ldfile, _("\
2989 %s: unknown character in equivalent definition name"),
2993 if (newname != NULL)
2994 free ((char *) newname);
2995 if (symname != NULL)
2996 free ((char *) symname);
2999 if (symname == NULL)
3001 lr_error (ldfile, _("\
3002 %s: unknown character in equivalent definition value"),
3004 goto sym_equiv_free;
3007 /* See whether the symbol name is already defined. */
3008 if (find_entry (&collate->sym_table, symname, symname_len,
3009 (void **) &symval) != 0)
3011 lr_error (ldfile, _("\
3012 %s: unknown symbol `%s' in equivalent definition"),
3013 "LC_COLLATE", symname);
3017 if (insert_entry (&collate->sym_table,
3018 newname, newname_len, symval) < 0)
3020 lr_error (ldfile, _("\
3021 error while adding equivalent collating symbol"));
3022 goto sym_equiv_free;
3025 free ((char *) symname);
3027 lr_ignore_rest (ldfile, 1);
3031 /* We get told about the scripts we know. */
3032 arg = lr_token (ldfile, charmap, repertoire, verbose);
3033 if (arg->tok != tok_bsymbol)
3037 struct section_list *runp = collate->known_sections;
3040 while (runp != NULL)
3041 if (strncmp (runp->name, arg->val.str.startmb,
3042 arg->val.str.lenmb) == 0
3043 && runp->name[arg->val.str.lenmb] == '\0')
3046 runp = runp->def_next;
3050 lr_error (ldfile, _("duplicate definition of script `%s'"),
3052 lr_ignore_rest (ldfile, 0);
3056 runp = (struct section_list *) xcalloc (1, sizeof (*runp));
3057 name = (char *) xmalloc (arg->val.str.lenmb + 1);
3058 memcpy (name, arg->val.str.startmb, arg->val.str.lenmb);
3059 name[arg->val.str.lenmb] = '\0';
3062 runp->def_next = collate->known_sections;
3063 collate->known_sections = runp;
3065 lr_ignore_rest (ldfile, 1);
3068 case tok_order_start:
3069 /* Ignore the rest of the line if we don't need the input of
3073 lr_ignore_rest (ldfile, 0);
3077 if (state != 0 && state != 1)
3081 /* The 14652 draft does not specify whether all `order_start' lines
3082 must contain the same number of sort-rules, but 14651 does. So
3083 we require this here as well. */
3084 arg = lr_token (ldfile, charmap, repertoire, verbose);
3085 if (arg->tok == tok_bsymbol)
3087 /* This better should be a section name. */
3088 struct section_list *sp = collate->known_sections;
3090 && (sp->name == NULL
3091 || strncmp (sp->name, arg->val.str.startmb,
3092 arg->val.str.lenmb) != 0
3093 || sp->name[arg->val.str.lenmb] != '\0'))
3098 lr_error (ldfile, _("\
3099 %s: unknown section name `%s'"),
3100 "LC_COLLATE", arg->val.str.startmb);
3101 /* We use the error section. */
3102 collate->current_section = &collate->error_section;
3104 if (collate->error_section.first == NULL)
3106 /* Insert &collate->error_section at the end of
3107 the collate->sections list. */
3108 if (collate->sections == NULL)
3109 collate->sections = &collate->error_section;
3112 sp = collate->sections;
3113 while (sp->next != NULL)
3116 sp->next = &collate->error_section;
3118 collate->error_section.next = NULL;
3123 /* One should not be allowed to open the same
3125 if (sp->first != NULL)
3126 lr_error (ldfile, _("\
3127 %s: multiple order definitions for section `%s'"),
3128 "LC_COLLATE", sp->name);
3131 /* Insert sp in the collate->sections list,
3132 right after collate->current_section. */
3133 if (collate->current_section == NULL)
3134 collate->current_section = sp;
3137 sp->next = collate->current_section->next;
3138 collate->current_section->next = sp;
3142 /* Next should come the end of the line or a semicolon. */
3143 arg = lr_token (ldfile, charmap, repertoire, verbose);
3144 if (arg->tok == tok_eol)
3148 /* This means we have exactly one rule: `forward'. */
3150 lr_error (ldfile, _("\
3151 %s: invalid number of sorting rules"),
3155 sp->rules = obstack_alloc (&collate->mempool,
3156 (sizeof (enum coll_sort_rule)
3158 for (cnt = 0; cnt < nrules; ++cnt)
3159 sp->rules[cnt] = sort_forward;
3165 /* Get the next token. */
3166 arg = lr_token (ldfile, charmap, repertoire, verbose);
3171 /* There is no section symbol. Therefore we use the unnamed
3173 collate->current_section = &collate->unnamed_section;
3175 if (collate->unnamed_section.first != NULL)
3176 lr_error (ldfile, _("\
3177 %s: multiple order definitions for unnamed section"),
3181 /* Insert &collate->unnamed_section at the beginning of
3182 the collate->sections list. */
3183 collate->unnamed_section.next = collate->sections;
3184 collate->sections = &collate->unnamed_section;
3188 /* Now read the direction names. */
3189 read_directions (ldfile, arg, charmap, repertoire, collate);
3191 /* From now we need the strings untranslated. */
3192 ldfile->translate_strings = 0;
3196 /* Ignore the rest of the line if we don't need the input of
3200 lr_ignore_rest (ldfile, 0);
3207 /* Handle ellipsis at end of list. */
3208 if (was_ellipsis != tok_none)
3210 handle_ellipsis (ldfile, NULL, 0, was_ellipsis, charmap,
3211 repertoire, collate);
3212 was_ellipsis = tok_none;
3216 lr_ignore_rest (ldfile, 1);
3219 case tok_reorder_after:
3220 /* Ignore the rest of the line if we don't need the input of
3224 lr_ignore_rest (ldfile, 0);
3230 lr_error (ldfile, _("%s: missing `order_end' keyword"),
3234 /* Handle ellipsis at end of list. */
3235 if (was_ellipsis != tok_none)
3237 handle_ellipsis (ldfile, arg->val.str.startmb,
3238 arg->val.str.lenmb, was_ellipsis, charmap,
3239 repertoire, collate);
3240 was_ellipsis = tok_none;
3243 else if (state != 2 && state != 3)
3247 arg = lr_token (ldfile, charmap, repertoire, verbose);
3248 if (arg->tok == tok_bsymbol || arg->tok == tok_ucs4)
3250 /* Find this symbol in the sequence table. */
3254 struct element_t *insp;
3257 if (arg->tok == tok_bsymbol)
3259 startmb = arg->val.str.startmb;
3260 lenmb = arg->val.str.lenmb;
3264 sprintf (ucsbuf, "U%08X", arg->val.ucs4);
3269 if (find_entry (&collate->seq_table, startmb, lenmb,
3270 (void **) &insp) == 0)
3271 /* Yes, the symbol exists. Simply point the cursor
3273 collate->cursor = insp;
3276 struct symbol_t *symbp;
3278 if (find_entry (&collate->sym_table, startmb, lenmb,
3279 (void **) &symbp) == 0)
3281 if (symbp->order->last != NULL
3282 || symbp->order->next != NULL)
3283 collate->cursor = symbp->order;
3286 /* This is a collating symbol but its position
3287 is not yet defined. */
3288 lr_error (ldfile, _("\
3289 %s: order for collating symbol %.*s not yet defined"),
3290 "LC_COLLATE", (int) lenmb, startmb);
3291 collate->cursor = NULL;
3295 else if (find_entry (&collate->elem_table, startmb, lenmb,
3296 (void **) &insp) == 0)
3298 if (insp->last != NULL || insp->next != NULL)
3299 collate->cursor = insp;
3302 /* This is a collating element but its position
3303 is not yet defined. */
3304 lr_error (ldfile, _("\
3305 %s: order for collating element %.*s not yet defined"),
3306 "LC_COLLATE", (int) lenmb, startmb);
3307 collate->cursor = NULL;
3313 /* This is bad. The symbol after which we have to
3314 insert does not exist. */
3315 lr_error (ldfile, _("\
3316 %s: cannot reorder after %.*s: symbol not known"),
3317 "LC_COLLATE", (int) lenmb, startmb);
3318 collate->cursor = NULL;
3323 lr_ignore_rest (ldfile, no_error);
3326 /* This must not happen. */
3330 case tok_reorder_end:
3331 /* Ignore the rest of the line if we don't need the input of
3339 lr_ignore_rest (ldfile, 1);
3342 case tok_reorder_sections_after:
3343 /* Ignore the rest of the line if we don't need the input of
3347 lr_ignore_rest (ldfile, 0);
3353 lr_error (ldfile, _("%s: missing `order_end' keyword"),
3357 /* Handle ellipsis at end of list. */
3358 if (was_ellipsis != tok_none)
3360 handle_ellipsis (ldfile, NULL, 0, was_ellipsis, charmap,
3361 repertoire, collate);
3362 was_ellipsis = tok_none;
3365 else if (state == 3)
3367 error (0, 0, _("%s: missing `reorder-end' keyword"),
3371 else if (state != 2 && state != 4)
3375 /* Get the name of the sections we are adding after. */
3376 arg = lr_token (ldfile, charmap, repertoire, verbose);
3377 if (arg->tok == tok_bsymbol)
3379 /* Now find a section with this name. */
3380 struct section_list *runp = collate->sections;
3382 while (runp != NULL)
3384 if (runp->name != NULL
3385 && strlen (runp->name) == arg->val.str.lenmb
3386 && memcmp (runp->name, arg->val.str.startmb,
3387 arg->val.str.lenmb) == 0)
3394 collate->current_section = runp;
3397 /* This is bad. The section after which we have to
3398 reorder does not exist. Therefore we cannot
3399 process the whole rest of this reorder
3401 lr_error (ldfile, _("%s: section `%.*s' not known"),
3402 "LC_COLLATE", (int) arg->val.str.lenmb,
3403 arg->val.str.startmb);
3407 lr_ignore_rest (ldfile, 0);
3409 now = lr_token (ldfile, charmap, NULL, verbose);
3411 while (now->tok == tok_reorder_sections_after
3412 || now->tok == tok_reorder_sections_end
3413 || now->tok == tok_end);
3415 /* Process the token we just saw. */
3421 /* This must not happen. */
3425 case tok_reorder_sections_end:
3426 /* Ignore the rest of the line if we don't need the input of
3434 lr_ignore_rest (ldfile, 1);
3439 /* Ignore the rest of the line if we don't need the input of
3443 lr_ignore_rest (ldfile, 0);
3447 if (state != 0 && state != 1 && state != 3 && state != 5)
3450 if ((state == 0 || state == 5) && nowtok == tok_ucs4)
3453 if (nowtok == tok_ucs4)
3455 snprintf (ucs4buf, sizeof (ucs4buf), "U%08X", now->val.ucs4);
3461 symstr = arg->val.str.startmb;
3462 symlen = arg->val.str.lenmb;
3467 /* We are outside an `order_start' region. This means
3468 we must only accept definitions of values for
3469 collation symbols since these are purely abstract
3470 values and don't need directions associated. */
3471 struct element_t *seqp;
3473 if (find_entry (&collate->seq_table, symstr, symlen,
3474 (void **) &seqp) == 0)
3476 /* It's already defined. First check whether this
3477 is really a collating symbol. */
3478 if (seqp->is_character)
3487 if (find_entry (&collate->sym_table, symstr, symlen,
3489 /* No collating symbol, it's an error. */
3492 /* Maybe this is the first time we define a symbol
3493 value and it is before the first actual section. */
3494 if (collate->sections == NULL)
3495 collate->sections = collate->current_section =
3496 &collate->symbol_section;
3499 if (was_ellipsis != tok_none)
3502 handle_ellipsis (ldfile, symstr, symlen, was_ellipsis,
3503 charmap, repertoire, collate);
3505 /* Remember that we processed the ellipsis. */
3506 was_ellipsis = tok_none;
3508 /* And don't add the value a second time. */
3512 else if (state == 3)
3514 /* It is possible that we already have this collation sequence.
3515 In this case we move the entry. */
3516 struct element_t *seqp;
3519 /* If the symbol after which we have to insert was not found
3520 ignore all entries. */
3521 if (collate->cursor == NULL)
3523 lr_ignore_rest (ldfile, 0);
3527 if (find_entry (&collate->seq_table, symstr, symlen,
3528 (void **) &seqp) == 0)
3531 if (find_entry (&collate->sym_table, symstr, symlen, &sym) == 0
3532 && (seqp = ((struct symbol_t *) sym)->order) != NULL)
3535 if (find_entry (&collate->elem_table, symstr, symlen,
3536 (void **) &seqp) == 0
3537 && (seqp->last != NULL || seqp->next != NULL
3538 || (collate->start != NULL && seqp == collate->start)))
3541 /* Remove the entry from the old position. */
3542 if (seqp->last == NULL)
3543 collate->start = seqp->next;
3545 seqp->last->next = seqp->next;
3546 if (seqp->next != NULL)
3547 seqp->next->last = seqp->last;
3549 /* We also have to check whether this entry is the
3550 first or last of a section. */
3551 if (seqp->section->first == seqp)
3553 if (seqp->section->first == seqp->section->last)
3554 /* This section has no content anymore. */
3555 seqp->section->first = seqp->section->last = NULL;
3557 seqp->section->first = seqp->next;
3559 else if (seqp->section->last == seqp)
3560 seqp->section->last = seqp->last;
3562 /* Now insert it in the new place. */
3563 insert_weights (ldfile, seqp, charmap, repertoire, collate,
3568 /* Otherwise we just add a new entry. */
3570 else if (state == 5)
3572 /* We are reordering sections. Find the named section. */
3573 struct section_list *runp = collate->sections;
3574 struct section_list *prevp = NULL;
3576 while (runp != NULL)
3578 if (runp->name != NULL
3579 && strlen (runp->name) == symlen
3580 && memcmp (runp->name, symstr, symlen) == 0)
3589 lr_error (ldfile, _("%s: section `%.*s' not known"),
3590 "LC_COLLATE", (int) symlen, symstr);
3591 lr_ignore_rest (ldfile, 0);
3595 if (runp != collate->current_section)
3597 /* Remove the named section from the old place and
3598 insert it in the new one. */
3599 prevp->next = runp->next;
3601 runp->next = collate->current_section->next;
3602 collate->current_section->next = runp;
3603 collate->current_section = runp;
3606 /* Process the rest of the line which might change
3607 the collation rules. */
3608 arg = lr_token (ldfile, charmap, repertoire, verbose);
3609 if (arg->tok != tok_eof && arg->tok != tok_eol)
3610 read_directions (ldfile, arg, charmap, repertoire,
3615 else if (was_ellipsis != tok_none)
3617 /* Using the information in the `ellipsis_weight'
3618 element and this and the last value we have to handle
3619 the ellipsis now. */
3620 assert (state == 1);
3622 handle_ellipsis (ldfile, symstr, symlen, was_ellipsis, charmap,
3623 repertoire, collate);
3625 /* Remember that we processed the ellipsis. */
3626 was_ellipsis = tok_none;
3628 /* And don't add the value a second time. */
3632 /* Now insert in the new place. */
3633 insert_value (ldfile, symstr, symlen, charmap, repertoire, collate);
3637 /* Ignore the rest of the line if we don't need the input of
3641 lr_ignore_rest (ldfile, 0);
3648 if (was_ellipsis != tok_none)
3651 _("%s: cannot have `%s' as end of ellipsis range"),
3652 "LC_COLLATE", "UNDEFINED");
3654 unlink_element (collate);
3655 was_ellipsis = tok_none;
3658 /* See whether UNDEFINED already appeared somewhere. */
3659 if (collate->undefined.next != NULL
3660 || &collate->undefined == collate->cursor)
3663 _("%s: order for `%.*s' already defined at %s:%Zu"),
3664 "LC_COLLATE", 9, "UNDEFINED",
3665 collate->undefined.file,
3666 collate->undefined.line);
3667 lr_ignore_rest (ldfile, 0);
3670 /* Parse the weights. */
3671 insert_weights (ldfile, &collate->undefined, charmap,
3672 repertoire, collate, tok_none);
3675 case tok_ellipsis2: /* symbolic hexadecimal ellipsis */
3676 case tok_ellipsis3: /* absolute ellipsis */
3677 case tok_ellipsis4: /* symbolic decimal ellipsis */
3678 /* This is the symbolic (decimal or hexadecimal) or absolute
3680 if (was_ellipsis != tok_none)
3683 if (state != 0 && state != 1 && state != 3)
3686 was_ellipsis = nowtok;
3688 insert_weights (ldfile, &collate->ellipsis_weight, charmap,
3689 repertoire, collate, nowtok);
3693 /* Next we assume `LC_COLLATE'. */
3694 if (!ignore_content)
3697 /* We must either see a copy statement or have
3700 _("%s: empty category description not allowed"),
3702 else if (state == 1)
3704 lr_error (ldfile, _("%s: missing `order_end' keyword"),
3707 /* Handle ellipsis at end of list. */
3708 if (was_ellipsis != tok_none)
3710 handle_ellipsis (ldfile, NULL, 0, was_ellipsis, charmap,
3711 repertoire, collate);
3712 was_ellipsis = tok_none;
3715 else if (state == 3)
3716 error (0, 0, _("%s: missing `reorder-end' keyword"),
3718 else if (state == 5)
3719 error (0, 0, _("%s: missing `reorder-sections-end' keyword"),
3722 arg = lr_token (ldfile, charmap, NULL, verbose);
3723 if (arg->tok == tok_eof)
3725 if (arg->tok == tok_eol)
3726 lr_error (ldfile, _("%s: incomplete `END' line"), "LC_COLLATE");
3727 else if (arg->tok != tok_lc_collate)
3728 lr_error (ldfile, _("\
3729 %1$s: definition does not end with `END %1$s'"), "LC_COLLATE");
3730 lr_ignore_rest (ldfile, arg->tok == tok_lc_collate);
3735 SYNTAX_ERROR (_("%s: syntax error"), "LC_COLLATE");
3738 /* Prepare for the next round. */
3739 now = lr_token (ldfile, charmap, NULL, verbose);
3743 /* When we come here we reached the end of the file. */
3744 lr_error (ldfile, _("%s: premature end of file"), "LC_COLLATE");