Make localedef output generation use more logical interfaces.

This commit is contained in:
Richard Sandiford 2013-09-06 17:20:45 +00:00 committed by Joseph Myers
parent 2618d9db2d
commit 1ecbb381ae
16 changed files with 724 additions and 1597 deletions

View File

@ -1,3 +1,83 @@
2013-09-06 Richard Sandiford <richard@codesourcery.com>
Joseph Myers <joseph@codesourcery.com>
* locale/programs/locfile.c: Include <assert.h>, <wchar.h> and
"localeinfo.h".
(obstack_chunk_alloc): New macro.
(obstack_chunk_free): Likewise.
(record_offset): New function.
(init_locale_data): Likewise.
(align_locale_data): Likewise.
(add_locale_empty): Likewise.
(add_locale_raw_data): Likewise.
(add_locale_raw_obstack): Likewise.
(add_locale_string): Likewise.
(add_locale_wstring): Likewise.
(add_locale_uint32): Likewise.
(add_locale_uint32_array): Likewise.
(add_locale_char): Likewise.
(start_locale_structure): Likewise.
(end_locale_structure): Likewise.
(start_locale_prelude): Likewise.
(end_locale_prelude): Likewise.
(write_locale_data): Take locale_file structure rather than an
iovec.
* locale/programs/locfile.h: Include "obstack.h".
(struct locale_file): Change to store locale file contents instead
of header.
(init_locale_data): New prototype.
(align_locale_data): Likewise.
(add_locale_empty): Likewise.
(add_locale_raw_data): Likewise.
(add_locale_raw_obstack): Likewise.
(add_locale_string): Likewise.
(add_locale_wstring): Likewise.
(add_locale_uint32): Likewise.
(add_locale_uint32_array): Likewise.
(add_locale_char): Likewise.
(start_locale_structure): Likewise.
(end_locale_structure): Likewise.
(start_locale_prelude): Likewise.
(end_locale_prelude): Likewise.
(write_locale_data): Update prototype.
* locale/programs/3level.h (struct TABLE): Remove result field.
(CONCAT(TABLE,_finalize)): Change to CONCAT(add_locale_,TABLE).
Use new locale_file interface.
[!NO_FINALIZE]: Change condition to [!NO_ADD_LOCALE].
(NO_FINALIZE): Change #undef to #undef of NO_ADD_LOCALE.
* locale/programs/ld-address.c (address_output): Use new
locale_file interface.
* locale/programs/ld-collate.c (NO_FINALIZE): Change to
NO_ADD_LOCALE.
(collate_finish): Don't call collseq_table_finalize.
(collate_output): Use new locale_file interface.
* locale/programs/ld-ctype.c: Move includes of "3level.h" earlier
in file.
(NO_FINALIZE): Change to NO_ADD_LOCALE.
(TABLE): Move defines earlier in file.
(ELEMENT): Likewise.
(DEFAULT): Likewise.
(wctrans_table_add): Move macro and inline function earlier in
file.
(struct wctype_table): Move type earlier in file.
(add_locale_wctype_table): New static prototype.
(struct locale_ctype_t): Use logical types instead of struct iovec
pointers for members.
(ctype_output): Use new locale_file interface.
(wctype_table_finalize): Change to add_locale_wctype_table. Use
new locale_file interface.
(allocate_arrays): Update for use of new locale_file interface.
* locale/programs/ld-identification.c (identification_output): Use
new locale_file interface.
* locale/programs/ld-measurement.c (measurement_output): Likewise.
* locale/programs/ld-messages.c (messages_output): Likewise.
* locale/programs/ld-monetary.c (monetary_output): Likewise.
* locale/programs/ld-name.c (name_output): Likewise.
* locale/programs/ld-numeric.c (numeric_output): Likewise.
* locale/programs/ld-paper.c (paper_output): Likewise.
* locale/programs/ld-telephone.c (telephone_output): Likewise.
* locale/programs/ld-time.c (time_output): Likewise.
2013-09-06 Adhemerval Zanella <azanella@linux.vnet.ibm.com> 2013-09-06 Adhemerval Zanella <azanella@linux.vnet.ibm.com>
* benchtests/Makefile: Add memrchr benchmark. * benchtests/Makefile: Add memrchr benchmark.

View File

@ -26,7 +26,8 @@
ELEMENT to the type of every entry ELEMENT to the type of every entry
DEFAULT to the default value for empty entries DEFAULT to the default value for empty entries
ITERATE if you want the TABLE_iterate function to be defined ITERATE if you want the TABLE_iterate function to be defined
NO_FINALIZE if you don't want the TABLE_finalize function to be defined NO_ADD_LOCALE if you don't want the add_locale_TABLE function
to be defined
This will define This will define
@ -36,7 +37,7 @@
void TABLE_add (struct TABLE *t, uint32_t wc, ELEMENT value); void TABLE_add (struct TABLE *t, uint32_t wc, ELEMENT value);
void TABLE_iterate (struct TABLE *t, void TABLE_iterate (struct TABLE *t,
void (*fn) (uint32_t wc, ELEMENT value)); void (*fn) (uint32_t wc, ELEMENT value));
void TABLE_finalize (struct TABLE *t); void add_locale_TABLE (struct locale_file *file, struct TABLE *t);
*/ */
#define CONCAT(a,b) CONCAT1(a,b) #define CONCAT(a,b) CONCAT1(a,b)
@ -57,9 +58,8 @@ struct TABLE
size_t level3_alloc; size_t level3_alloc;
size_t level3_size; size_t level3_size;
ELEMENT *level3; ELEMENT *level3;
/* Compressed representation. */ /* Size of compressed representation. */
size_t result_size; size_t result_size;
char *result;
}; };
/* Initialize. Assumes t->p and t->q have already been set. */ /* Initialize. Assumes t->p and t->q have already been set. */
@ -206,15 +206,15 @@ CONCAT(TABLE,_iterate) (struct TABLE *t,
} }
#endif #endif
#ifndef NO_FINALIZE #ifndef NO_ADD_LOCALE
/* Finalize and shrink. */ /* Finalize and shrink. */
static void static void
CONCAT(TABLE,_finalize) (struct TABLE *t) CONCAT(add_locale_,TABLE) (struct locale_file *file, struct TABLE *t)
{ {
size_t i, j, k; size_t i, j, k;
uint32_t reorder3[t->level3_size]; uint32_t reorder3[t->level3_size];
uint32_t reorder2[t->level2_size]; uint32_t reorder2[t->level2_size];
uint32_t level1_offset, level2_offset, level3_offset, last_offset; uint32_t level2_offset, level3_offset, last_offset;
/* Uniquify level3 blocks. */ /* Uniquify level3 blocks. */
k = 0; k = 0;
@ -271,10 +271,7 @@ CONCAT(TABLE,_finalize) (struct TABLE *t)
+ (t->level2_size << t->q) * sizeof (uint32_t) + (t->level2_size << t->q) * sizeof (uint32_t)
+ (t->level3_size << t->p) * sizeof (ELEMENT); + (t->level3_size << t->p) * sizeof (ELEMENT);
t->result_size = (last_offset + 3) & ~3ul; t->result_size = (last_offset + 3) & ~3ul;
t->result = (char *) xmalloc (t->result_size);
level1_offset =
5 * sizeof (uint32_t);
level2_offset = level2_offset =
5 * sizeof (uint32_t) 5 * sizeof (uint32_t)
+ t->level1_size * sizeof (uint32_t); + t->level1_size * sizeof (uint32_t);
@ -283,29 +280,36 @@ CONCAT(TABLE,_finalize) (struct TABLE *t)
+ t->level1_size * sizeof (uint32_t) + t->level1_size * sizeof (uint32_t)
+ (t->level2_size << t->q) * sizeof (uint32_t); + (t->level2_size << t->q) * sizeof (uint32_t);
((uint32_t *) t->result)[0] = t->q + t->p; start_locale_structure (file);
((uint32_t *) t->result)[1] = t->level1_size; add_locale_uint32 (file, t->q + t->p);
((uint32_t *) t->result)[2] = t->p; add_locale_uint32 (file, t->level1_size);
((uint32_t *) t->result)[3] = (1 << t->q) - 1; add_locale_uint32 (file, t->p);
((uint32_t *) t->result)[4] = (1 << t->p) - 1; add_locale_uint32 (file, (1 << t->q) - 1);
add_locale_uint32 (file, (1 << t->p) - 1);
for (i = 0; i < t->level1_size; i++) for (i = 0; i < t->level1_size; i++)
((uint32_t *) (t->result + level1_offset))[i] = add_locale_uint32
(t->level1[i] == EMPTY (file,
t->level1[i] == EMPTY
? 0 ? 0
: (t->level1[i] << t->q) * sizeof (uint32_t) + level2_offset); : (t->level1[i] << t->q) * sizeof (uint32_t) + level2_offset);
for (i = 0; i < (t->level2_size << t->q); i++) for (i = 0; i < (t->level2_size << t->q); i++)
((uint32_t *) (t->result + level2_offset))[i] = add_locale_uint32
(t->level2[i] == EMPTY (file,
t->level2[i] == EMPTY
? 0 ? 0
: (t->level2[i] << t->p) * sizeof (ELEMENT) + level3_offset); : (t->level2[i] << t->p) * sizeof (ELEMENT) + level3_offset);
for (i = 0; i < (t->level3_size << t->p); i++) if (sizeof (ELEMENT) == 1)
((ELEMENT *) (t->result + level3_offset))[i] = t->level3[i]; add_locale_raw_data (file, t->level3, t->level3_size << t->p);
else if (sizeof (ELEMENT) == sizeof (uint32_t))
if (last_offset < t->result_size) add_locale_uint32_array (file, (uint32_t *) t->level3,
memset (t->result + last_offset, 0, t->result_size - last_offset); t->level3_size << t->p);
else
abort ();
align_locale_data (file, 4);
end_locale_structure (file);
if (t->level1_alloc > 0) if (t->level1_alloc > 0)
free (t->level1); free (t->level1);
@ -321,4 +325,4 @@ CONCAT(TABLE,_finalize) (struct TABLE *t)
#undef ELEMENT #undef ELEMENT
#undef DEFAULT #undef DEFAULT
#undef ITERATE #undef ITERATE
#undef NO_FINALIZE #undef NO_ADD_LOCALE

View File

@ -349,97 +349,23 @@ address_output (struct localedef_t *locale, const struct charmap_t *charmap,
const char *output_path) const char *output_path)
{ {
struct locale_address_t *address = locale->categories[LC_ADDRESS].address; struct locale_address_t *address = locale->categories[LC_ADDRESS].address;
struct iovec iov[3 + _NL_ITEM_INDEX (_NL_NUM_LC_ADDRESS)]; struct locale_file file;
struct locale_file data;
uint32_t idx[_NL_ITEM_INDEX (_NL_NUM_LC_ADDRESS)];
size_t cnt = 0;
data.magic = LIMAGIC (LC_ADDRESS); init_locale_data (&file, _NL_ITEM_INDEX (_NL_NUM_LC_ADDRESS));
data.n = _NL_ITEM_INDEX (_NL_NUM_LC_ADDRESS); add_locale_string (&file, address->postal_fmt);
iov[cnt].iov_base = (void *) &data; add_locale_string (&file, address->country_name);
iov[cnt].iov_len = sizeof (data); add_locale_string (&file, address->country_post);
++cnt; add_locale_string (&file, address->country_ab2);
add_locale_string (&file, address->country_ab3);
iov[cnt].iov_base = (void *) idx; add_locale_string (&file, address->country_car);
iov[cnt].iov_len = sizeof (idx); add_locale_uint32 (&file, address->country_num);
++cnt; add_locale_string (&file, address->country_isbn);
add_locale_string (&file, address->lang_name);
idx[cnt - 2] = iov[0].iov_len + iov[1].iov_len; add_locale_string (&file, address->lang_ab);
iov[cnt].iov_base = (void *) address->postal_fmt; add_locale_string (&file, address->lang_term);
iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1; add_locale_string (&file, address->lang_lib);
++cnt; add_locale_string (&file, charmap->code_set_name);
write_locale_data (output_path, LC_ADDRESS, "LC_ADDRESS", &file);
idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
iov[cnt].iov_base = (void *) address->country_name;
iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
++cnt;
idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
iov[cnt].iov_base = (void *) address->country_post;
iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
++cnt;
idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
iov[cnt].iov_base = (void *) address->country_ab2;
iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
++cnt;
idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
iov[cnt].iov_base = (void *) address->country_ab3;
iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
++cnt;
idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
iov[cnt].iov_base = (void *) address->country_car;
iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
++cnt;
idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
/* Align following data */
iov[cnt].iov_base = (void *) "\0\0";
iov[cnt].iov_len = ((idx[cnt - 2] + 3) & ~3) - idx[cnt - 2];
idx[cnt - 2] = (idx[cnt - 2] + 3) & ~3;
++cnt;
iov[cnt].iov_base = (void *) &address->country_num;
iov[cnt].iov_len = sizeof (uint32_t);
++cnt;
idx[cnt - 3] = idx[cnt - 4] + iov[cnt - 1].iov_len;
iov[cnt].iov_base = (void *) address->country_isbn;
iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
++cnt;
idx[cnt - 3] = idx[cnt - 4] + iov[cnt - 1].iov_len;
iov[cnt].iov_base = (void *) address->lang_name;
iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
++cnt;
idx[cnt - 3] = idx[cnt - 4] + iov[cnt - 1].iov_len;
iov[cnt].iov_base = (void *) address->lang_ab;
iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
++cnt;
idx[cnt - 3] = idx[cnt - 4] + iov[cnt - 1].iov_len;
iov[cnt].iov_base = (void *) address->lang_term;
iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
++cnt;
idx[cnt - 3] = idx[cnt - 4] + iov[cnt - 1].iov_len;
iov[cnt].iov_base = (void *) address->lang_lib;
iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
++cnt;
idx[cnt - 3] = idx[cnt - 4] + iov[cnt - 1].iov_len;
iov[cnt].iov_base = (void *) charmap->code_set_name;
iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
++cnt;
assert (cnt == 3 + _NL_ITEM_INDEX (_NL_NUM_LC_ADDRESS));
write_locale_data (output_path, LC_ADDRESS, "LC_ADDRESS",
3 + _NL_ITEM_INDEX (_NL_NUM_LC_ADDRESS), iov);
} }

View File

@ -165,7 +165,7 @@ struct symbol_t
#define ELEMENT struct element_t * #define ELEMENT struct element_t *
#define DEFAULT NULL #define DEFAULT NULL
#define ITERATE #define ITERATE
#define NO_FINALIZE #define NO_ADD_LOCALE
#include "3level.h" #include "3level.h"
/* Sparse table of int32_t. */ /* Sparse table of int32_t. */
@ -1813,8 +1813,6 @@ symbol `%s' has the same encoding as"), (*eptr)->name);
runp = runp->next; runp = runp->next;
} }
collseq_table_finalize (&collate->wcseqorder);
/* Now determine whether the UNDEFINED entry is needed and if yes, /* Now determine whether the UNDEFINED entry is needed and if yes,
whether it was defined. */ whether it was defined. */
collate->undefined.used_in_level = need_undefined ? ~0ul : 0; collate->undefined.used_in_level = need_undefined ? ~0ul : 0;
@ -2098,10 +2096,7 @@ collate_output (struct localedef_t *locale, const struct charmap_t *charmap,
{ {
struct locale_collate_t *collate = locale->categories[LC_COLLATE].collate; struct locale_collate_t *collate = locale->categories[LC_COLLATE].collate;
const size_t nelems = _NL_ITEM_INDEX (_NL_NUM_LC_COLLATE); const size_t nelems = _NL_ITEM_INDEX (_NL_NUM_LC_COLLATE);
struct iovec iov[2 + nelems]; struct locale_file file;
struct locale_file data;
uint32_t idx[nelems];
size_t cnt;
size_t ch; size_t ch;
int32_t tablemb[256]; int32_t tablemb[256];
struct obstack weightpool; struct obstack weightpool;
@ -2114,51 +2109,22 @@ collate_output (struct localedef_t *locale, const struct charmap_t *charmap,
int i; int i;
struct element_t *runp; struct element_t *runp;
data.magic = LIMAGIC (LC_COLLATE); init_locale_data (&file, nelems);
data.n = nelems; add_locale_uint32 (&file, nrules);
iov[0].iov_base = (void *) &data;
iov[0].iov_len = sizeof (data);
iov[1].iov_base = (void *) idx;
iov[1].iov_len = sizeof (idx);
idx[0] = iov[0].iov_len + iov[1].iov_len;
cnt = 0;
assert (cnt == _NL_ITEM_INDEX (_NL_COLLATE_NRULES));
iov[2 + cnt].iov_base = &nrules;
iov[2 + cnt].iov_len = sizeof (uint32_t);
idx[1 + cnt] = idx[cnt] + iov[2 + cnt].iov_len;
++cnt;
/* If we have no LC_COLLATE data emit only the number of rules as zero. */ /* If we have no LC_COLLATE data emit only the number of rules as zero. */
if (collate == NULL) if (collate == NULL)
{ {
int32_t dummy = 0; size_t idx;
for (idx = 1; idx < nelems; idx++)
while (cnt < _NL_ITEM_INDEX (_NL_NUM_LC_COLLATE))
{ {
/* The words have to be handled specially. */ /* The words have to be handled specially. */
if (cnt == _NL_ITEM_INDEX (_NL_COLLATE_SYMB_HASH_SIZEMB)) if (idx == _NL_ITEM_INDEX (_NL_COLLATE_SYMB_HASH_SIZEMB))
{ add_locale_uint32 (&file, 0);
iov[2 + cnt].iov_base = &dummy;
iov[2 + cnt].iov_len = sizeof (int32_t);
}
else else
{ add_locale_empty (&file);
iov[2 + cnt].iov_base = NULL;
iov[2 + cnt].iov_len = 0;
}
if (cnt + 1 < _NL_ITEM_INDEX (_NL_NUM_LC_COLLATE))
idx[1 + cnt] = idx[cnt] + iov[2 + cnt].iov_len;
++cnt;
} }
write_locale_data (output_path, LC_COLLATE, "LC_COLLATE", &file);
assert (cnt == _NL_ITEM_INDEX (_NL_NUM_LC_COLLATE));
write_locale_data (output_path, LC_COLLATE, "LC_COLLATE", 2 + cnt, iov);
return; return;
} }
@ -2191,11 +2157,7 @@ collate_output (struct localedef_t *locale, const struct charmap_t *charmap,
obstack_1grow (&weightpool, '\0'); obstack_1grow (&weightpool, '\0');
while (++i < __alignof__ (int32_t)); while (++i < __alignof__ (int32_t));
assert (cnt == _NL_ITEM_INDEX (_NL_COLLATE_RULESETS)); add_locale_raw_obstack (&file, &weightpool);
iov[2 + cnt].iov_len = obstack_object_size (&weightpool);
iov[2 + cnt].iov_base = obstack_finish (&weightpool);
idx[1 + cnt] = idx[cnt] + iov[2 + cnt].iov_len;
++cnt;
/* Generate the 8-bit table. Walk through the lists of sequences /* Generate the 8-bit table. Walk through the lists of sequences
starting with the same byte and add them one after the other to starting with the same byte and add them one after the other to
@ -2382,55 +2344,16 @@ collate_output (struct localedef_t *locale, const struct charmap_t *charmap,
obstack_1grow (&weightpool, 0); obstack_1grow (&weightpool, 0);
/* Now add the four tables. */ /* Now add the four tables. */
assert (cnt == _NL_ITEM_INDEX (_NL_COLLATE_TABLEMB)); add_locale_uint32_array (&file, (const uint32_t *) tablemb, 256);
iov[2 + cnt].iov_base = tablemb; add_locale_raw_obstack (&file, &weightpool);
iov[2 + cnt].iov_len = sizeof (tablemb); add_locale_raw_obstack (&file, &extrapool);
idx[1 + cnt] = idx[cnt] + iov[2 + cnt].iov_len; add_locale_raw_obstack (&file, &indirectpool);
assert ((iov[2 + cnt].iov_len & (__alignof__ (int32_t) - 1)) == 0);
++cnt;
assert (cnt == _NL_ITEM_INDEX (_NL_COLLATE_WEIGHTMB));
iov[2 + cnt].iov_len = obstack_object_size (&weightpool);
iov[2 + cnt].iov_base = obstack_finish (&weightpool);
idx[1 + cnt] = idx[cnt] + iov[2 + cnt].iov_len;
++cnt;
assert (cnt == _NL_ITEM_INDEX (_NL_COLLATE_EXTRAMB));
iov[2 + cnt].iov_len = obstack_object_size (&extrapool);
iov[2 + cnt].iov_base = obstack_finish (&extrapool);
idx[1 + cnt] = idx[cnt] + iov[2 + cnt].iov_len;
++cnt;
assert (cnt == _NL_ITEM_INDEX (_NL_COLLATE_INDIRECTMB));
iov[2 + cnt].iov_len = obstack_object_size (&indirectpool);
iov[2 + cnt].iov_base = obstack_finish (&indirectpool);
idx[1 + cnt] = idx[cnt] + iov[2 + cnt].iov_len;
assert ((iov[2 + cnt].iov_len & (__alignof__ (int32_t) - 1)) == 0);
++cnt;
/* Now the same for the wide character table. We need to store some /* Now the same for the wide character table. We need to store some
more information here. */ more information here. */
assert (cnt == _NL_ITEM_INDEX (_NL_COLLATE_GAP1)); add_locale_empty (&file);
iov[2 + cnt].iov_base = NULL; add_locale_empty (&file);
iov[2 + cnt].iov_len = 0; add_locale_empty (&file);
idx[1 + cnt] = idx[cnt] + iov[2 + cnt].iov_len;
assert (idx[cnt] % __alignof__ (int32_t) == 0);
++cnt;
assert (cnt == _NL_ITEM_INDEX (_NL_COLLATE_GAP2));
iov[2 + cnt].iov_base = NULL;
iov[2 + cnt].iov_len = 0;
idx[1 + cnt] = idx[cnt] + iov[2 + cnt].iov_len;
assert (idx[cnt] % __alignof__ (int32_t) == 0);
++cnt;
assert (cnt == _NL_ITEM_INDEX (_NL_COLLATE_GAP3));
iov[2 + cnt].iov_base = NULL;
iov[2 + cnt].iov_len = 0;
idx[1 + cnt] = idx[cnt] + iov[2 + cnt].iov_len;
assert (idx[cnt] % __alignof__ (int32_t) == 0);
++cnt;
/* Since we are using the sign of an integer to mark indirection the /* Since we are using the sign of an integer to mark indirection the
offsets in the arrays we are indirectly referring to must not be offsets in the arrays we are indirectly referring to must not be
@ -2462,41 +2385,11 @@ collate_output (struct localedef_t *locale, const struct charmap_t *charmap,
memset (&atwc, 0, sizeof (atwc)); memset (&atwc, 0, sizeof (atwc));
collidx_table_finalize (&tablewc);
/* Now add the four tables. */ /* Now add the four tables. */
assert (cnt == _NL_ITEM_INDEX (_NL_COLLATE_TABLEWC)); add_locale_collidx_table (&file, &tablewc);
iov[2 + cnt].iov_base = tablewc.result; add_locale_raw_obstack (&file, &weightpool);
iov[2 + cnt].iov_len = tablewc.result_size; add_locale_raw_obstack (&file, &extrapool);
idx[1 + cnt] = idx[cnt] + iov[2 + cnt].iov_len; add_locale_raw_obstack (&file, &indirectpool);
assert (iov[2 + cnt].iov_len % sizeof (int32_t) == 0);
assert (idx[cnt] % __alignof__ (int32_t) == 0);
++cnt;
assert (cnt == _NL_ITEM_INDEX (_NL_COLLATE_WEIGHTWC));
iov[2 + cnt].iov_len = obstack_object_size (&weightpool);
iov[2 + cnt].iov_base = obstack_finish (&weightpool);
idx[1 + cnt] = idx[cnt] + iov[2 + cnt].iov_len;
assert (iov[2 + cnt].iov_len % sizeof (int32_t) == 0);
assert (idx[cnt] % __alignof__ (int32_t) == 0);
++cnt;
assert (cnt == _NL_ITEM_INDEX (_NL_COLLATE_EXTRAWC));
iov[2 + cnt].iov_len = obstack_object_size (&extrapool);
iov[2 + cnt].iov_base = obstack_finish (&extrapool);
idx[1 + cnt] = idx[cnt] + iov[2 + cnt].iov_len;
assert (iov[2 + cnt].iov_len % sizeof (int32_t) == 0);
assert (idx[cnt] % __alignof__ (int32_t) == 0);
++cnt;
assert (cnt == _NL_ITEM_INDEX (_NL_COLLATE_INDIRECTWC));
iov[2 + cnt].iov_len = obstack_object_size (&indirectpool);
iov[2 + cnt].iov_base = obstack_finish (&indirectpool);
idx[1 + cnt] = idx[cnt] + iov[2 + cnt].iov_len;
assert (iov[2 + cnt].iov_len % sizeof (int32_t) == 0);
assert (idx[cnt] % __alignof__ (int32_t) == 0);
++cnt;
/* Finally write the table with collation element names out. It is /* Finally write the table with collation element names out. It is
a hash table with a simple function which gets the name of the a hash table with a simple function which gets the name of the
@ -2594,47 +2487,13 @@ collate_output (struct localedef_t *locale, const struct charmap_t *charmap,
} }
/* Prepare to write out this data. */ /* Prepare to write out this data. */
assert (cnt == _NL_ITEM_INDEX (_NL_COLLATE_SYMB_HASH_SIZEMB)); add_locale_uint32 (&file, elem_size);
iov[2 + cnt].iov_base = &elem_size; add_locale_uint32_array (&file, elem_table, 2 * elem_size);
iov[2 + cnt].iov_len = sizeof (int32_t); add_locale_raw_obstack (&file, &extrapool);
idx[1 + cnt] = idx[cnt] + iov[2 + cnt].iov_len; add_locale_raw_data (&file, collate->mbseqorder, 256);
assert (idx[cnt] % __alignof__ (int32_t) == 0); add_locale_collseq_table (&file, &collate->wcseqorder);
++cnt; add_locale_string (&file, charmap->code_set_name);
write_locale_data (output_path, LC_COLLATE, "LC_COLLATE", &file);
assert (cnt == _NL_ITEM_INDEX (_NL_COLLATE_SYMB_TABLEMB));
iov[2 + cnt].iov_base = elem_table;
iov[2 + cnt].iov_len = elem_size * 2 * sizeof (int32_t);
idx[1 + cnt] = idx[cnt] + iov[2 + cnt].iov_len;
assert (idx[cnt] % __alignof__ (int32_t) == 0);
++cnt;
assert (cnt == _NL_ITEM_INDEX (_NL_COLLATE_SYMB_EXTRAMB));
iov[2 + cnt].iov_len = obstack_object_size (&extrapool);
iov[2 + cnt].iov_base = obstack_finish (&extrapool);
idx[1 + cnt] = idx[cnt] + iov[2 + cnt].iov_len;
++cnt;
assert (cnt == _NL_ITEM_INDEX (_NL_COLLATE_COLLSEQMB));
iov[2 + cnt].iov_base = collate->mbseqorder;
iov[2 + cnt].iov_len = 256;
idx[1 + cnt] = idx[cnt] + iov[2 + cnt].iov_len;
++cnt;
assert (cnt == _NL_ITEM_INDEX (_NL_COLLATE_COLLSEQWC));
iov[2 + cnt].iov_base = collate->wcseqorder.result;
iov[2 + cnt].iov_len = collate->wcseqorder.result_size;
idx[1 + cnt] = idx[cnt] + iov[2 + cnt].iov_len;
assert (idx[cnt] % __alignof__ (int32_t) == 0);
++cnt;
assert (cnt == _NL_ITEM_INDEX (_NL_COLLATE_CODESET));
iov[2 + cnt].iov_base = (void *) charmap->code_set_name;
iov[2 + cnt].iov_len = strlen (iov[2 + cnt].iov_base) + 1;
++cnt;
assert (cnt == _NL_ITEM_INDEX (_NL_NUM_LC_COLLATE));
write_locale_data (output_path, LC_COLLATE, "LC_COLLATE", 2 + cnt, iov);
obstack_free (&weightpool, NULL); obstack_free (&weightpool, NULL);
obstack_free (&extrapool, NULL); obstack_free (&extrapool, NULL);

View File

@ -119,9 +119,51 @@ struct translit_include_t
#define TABLE idx_table #define TABLE idx_table
#define ELEMENT uint32_t #define ELEMENT uint32_t
#define DEFAULT ((uint32_t) ~0) #define DEFAULT ((uint32_t) ~0)
#define NO_FINALIZE #define NO_ADD_LOCALE
#include "3level.h" #include "3level.h"
#define TABLE wcwidth_table
#define ELEMENT uint8_t
#define DEFAULT 0xff
#include "3level.h"
#define TABLE wctrans_table
#define ELEMENT int32_t
#define DEFAULT 0
#define wctrans_table_add wctrans_table_add_internal
#include "3level.h"
#undef wctrans_table_add
/* The wctrans_table must actually store the difference between the
desired result and the argument. */
static inline void
wctrans_table_add (struct wctrans_table *t, uint32_t wc, uint32_t mapped_wc)
{
wctrans_table_add_internal (t, wc, mapped_wc - wc);
}
/* Construction of sparse 3-level tables.
See wchar-lookup.h for their structure and the meaning of p and q. */
struct wctype_table
{
/* Parameters. */
unsigned int p;
unsigned int q;
/* Working representation. */
size_t level1_alloc;
size_t level1_size;
uint32_t *level1;
size_t level2_alloc;
size_t level2_size;
uint32_t *level2;
size_t level3_alloc;
size_t level3_size;
uint32_t *level3;
size_t result_size;
};
static void add_locale_wctype_table (struct locale_file *file,
struct wctype_table *t);
/* The real definition of the struct for the LC_CTYPE locale. */ /* The real definition of the struct for the LC_CTYPE locale. */
struct locale_ctype_t struct locale_ctype_t
@ -189,11 +231,11 @@ struct locale_ctype_t
uint32_t **map_b; uint32_t **map_b;
uint32_t **map32_b; uint32_t **map32_b;
uint32_t **class_b; uint32_t **class_b;
struct iovec *class_3level; struct wctype_table *class_3level;
struct iovec *map_3level; struct wctrans_table *map_3level;
uint32_t *class_name_ptr; uint32_t *class_name_ptr;
uint32_t *map_name_ptr; uint32_t *map_name_ptr;
struct iovec width; struct wcwidth_table width;
uint32_t mb_cur_max; uint32_t mb_cur_max;
const char *codeset_name; const char *codeset_name;
uint32_t *translit_from_idx; uint32_t *translit_from_idx;
@ -905,33 +947,21 @@ void
ctype_output (struct localedef_t *locale, const struct charmap_t *charmap, ctype_output (struct localedef_t *locale, const struct charmap_t *charmap,
const char *output_path) const char *output_path)
{ {
static const char nulbytes[4] = { 0, 0, 0, 0 };
struct locale_ctype_t *ctype = locale->categories[LC_CTYPE].ctype; struct locale_ctype_t *ctype = locale->categories[LC_CTYPE].ctype;
const size_t nelems = (_NL_ITEM_INDEX (_NL_CTYPE_EXTRA_MAP_1) const size_t nelems = (_NL_ITEM_INDEX (_NL_CTYPE_EXTRA_MAP_1)
+ ctype->nr_charclass + ctype->map_collection_nr); + ctype->nr_charclass + ctype->map_collection_nr);
struct iovec *iov = alloca (sizeof *iov struct locale_file file;
* (2 + nelems + 2 * ctype->nr_charclass
+ ctype->map_collection_nr + 4));
struct locale_file data;
uint32_t *idx = alloca (sizeof *idx * (nelems + 1));
uint32_t default_missing_len; uint32_t default_missing_len;
size_t elem, cnt, offset, total; size_t elem, cnt;
char *cp;
/* Now prepare the output: Find the sizes of the table we can use. */ /* Now prepare the output: Find the sizes of the table we can use. */
allocate_arrays (ctype, charmap, ctype->repertoire); allocate_arrays (ctype, charmap, ctype->repertoire);
data.magic = LIMAGIC (LC_CTYPE); default_missing_len = (ctype->default_missing
data.n = nelems; ? wcslen ((wchar_t *) ctype->default_missing)
iov[0].iov_base = (void *) &data; : 0);
iov[0].iov_len = sizeof (data);
iov[1].iov_base = (void *) idx;
iov[1].iov_len = nelems * sizeof (uint32_t);
idx[0] = iov[0].iov_len + iov[1].iov_len;
offset = 0;
init_locale_data (&file, nelems);
for (elem = 0; elem < nelems; ++elem) for (elem = 0; elem < nelems; ++elem)
{ {
if (elem < _NL_ITEM_INDEX (_NL_CTYPE_EXTRA_MAP_1)) if (elem < _NL_ITEM_INDEX (_NL_CTYPE_EXTRA_MAP_1))
@ -939,9 +969,7 @@ ctype_output (struct localedef_t *locale, const struct charmap_t *charmap,
{ {
#define CTYPE_EMPTY(name) \ #define CTYPE_EMPTY(name) \
case name: \ case name: \
iov[2 + elem + offset].iov_base = NULL; \ add_locale_empty (&file); \
iov[2 + elem + offset].iov_len = 0; \
idx[elem + 1] = idx[elem]; \
break break
CTYPE_EMPTY(_NL_CTYPE_GAP1); CTYPE_EMPTY(_NL_CTYPE_GAP1);
@ -951,273 +979,156 @@ ctype_output (struct localedef_t *locale, const struct charmap_t *charmap,
CTYPE_EMPTY(_NL_CTYPE_GAP5); CTYPE_EMPTY(_NL_CTYPE_GAP5);
CTYPE_EMPTY(_NL_CTYPE_GAP6); CTYPE_EMPTY(_NL_CTYPE_GAP6);
#define CTYPE_DATA(name, base, len) \ #define CTYPE_RAW_DATA(name, base, size) \
case _NL_ITEM_INDEX (name): \ case _NL_ITEM_INDEX (name): \
iov[2 + elem + offset].iov_base = (base); \ add_locale_raw_data (&file, base, size); \
iov[2 + elem + offset].iov_len = (len); \
idx[elem + 1] = idx[elem] + iov[2 + elem + offset].iov_len; \
break break
CTYPE_DATA (_NL_CTYPE_CLASS, CTYPE_RAW_DATA (_NL_CTYPE_CLASS,
ctype->ctype_b, ctype->ctype_b,
(256 + 128) * sizeof (char_class_t)); (256 + 128) * sizeof (char_class_t));
CTYPE_DATA (_NL_CTYPE_TOUPPER, #define CTYPE_UINT32_ARRAY(name, base, n_elems) \
ctype->map_b[0], case _NL_ITEM_INDEX (name): \
(256 + 128) * sizeof (uint32_t)); add_locale_uint32_array (&file, base, n_elems); \
CTYPE_DATA (_NL_CTYPE_TOLOWER, break
ctype->map_b[1],
(256 + 128) * sizeof (uint32_t));
CTYPE_DATA (_NL_CTYPE_TOUPPER32, CTYPE_UINT32_ARRAY (_NL_CTYPE_TOUPPER, ctype->map_b[0], 256 + 128);
ctype->map32_b[0], CTYPE_UINT32_ARRAY (_NL_CTYPE_TOLOWER, ctype->map_b[1], 256 + 128);
256 * sizeof (uint32_t)); CTYPE_UINT32_ARRAY (_NL_CTYPE_TOUPPER32, ctype->map32_b[0], 256);
CTYPE_DATA (_NL_CTYPE_TOLOWER32, CTYPE_UINT32_ARRAY (_NL_CTYPE_TOLOWER32, ctype->map32_b[1], 256);
ctype->map32_b[1], CTYPE_RAW_DATA (_NL_CTYPE_CLASS32,
256 * sizeof (uint32_t)); ctype->ctype32_b,
256 * sizeof (char_class32_t));
CTYPE_DATA (_NL_CTYPE_CLASS32, #define CTYPE_UINT32(name, value) \
ctype->ctype32_b, case _NL_ITEM_INDEX (name): \
256 * sizeof (char_class32_t)); add_locale_uint32 (&file, value); \
break
CTYPE_DATA (_NL_CTYPE_CLASS_OFFSET, CTYPE_UINT32 (_NL_CTYPE_CLASS_OFFSET, ctype->class_offset);
&ctype->class_offset, sizeof (uint32_t)); CTYPE_UINT32 (_NL_CTYPE_MAP_OFFSET, ctype->map_offset);
CTYPE_UINT32 (_NL_CTYPE_TRANSLIT_TAB_SIZE, ctype->translit_idx_size);
CTYPE_DATA (_NL_CTYPE_MAP_OFFSET, CTYPE_UINT32_ARRAY (_NL_CTYPE_TRANSLIT_FROM_IDX,
&ctype->map_offset, sizeof (uint32_t)); ctype->translit_from_idx,
ctype->translit_idx_size);
CTYPE_DATA (_NL_CTYPE_TRANSLIT_TAB_SIZE, CTYPE_UINT32_ARRAY (_NL_CTYPE_TRANSLIT_FROM_TBL,
&ctype->translit_idx_size, sizeof (uint32_t)); ctype->translit_from_tbl,
ctype->translit_from_tbl_size
/ sizeof (uint32_t));
CTYPE_DATA (_NL_CTYPE_TRANSLIT_FROM_IDX, CTYPE_UINT32_ARRAY (_NL_CTYPE_TRANSLIT_TO_IDX,
ctype->translit_from_idx, ctype->translit_to_idx,
ctype->translit_idx_size * sizeof (uint32_t)); ctype->translit_idx_size);
CTYPE_DATA (_NL_CTYPE_TRANSLIT_FROM_TBL, CTYPE_UINT32_ARRAY (_NL_CTYPE_TRANSLIT_TO_TBL,
ctype->translit_from_tbl, ctype->translit_to_tbl,
ctype->translit_from_tbl_size); ctype->translit_to_tbl_size / sizeof (uint32_t));
CTYPE_DATA (_NL_CTYPE_TRANSLIT_TO_IDX,
ctype->translit_to_idx,
ctype->translit_idx_size * sizeof (uint32_t));
CTYPE_DATA (_NL_CTYPE_TRANSLIT_TO_TBL,
ctype->translit_to_tbl, ctype->translit_to_tbl_size);
case _NL_ITEM_INDEX (_NL_CTYPE_CLASS_NAMES): case _NL_ITEM_INDEX (_NL_CTYPE_CLASS_NAMES):
/* The class name array. */ /* The class name array. */
total = 0; start_locale_structure (&file);
for (cnt = 0; cnt < ctype->nr_charclass; ++cnt, ++offset) for (cnt = 0; cnt < ctype->nr_charclass; ++cnt)
{ add_locale_string (&file, ctype->classnames[cnt]);
iov[2 + elem + offset].iov_base add_locale_char (&file, 0);
= (void *) ctype->classnames[cnt]; align_locale_data (&file, 4);
iov[2 + elem + offset].iov_len end_locale_structure (&file);
= strlen (ctype->classnames[cnt]) + 1;
total += iov[2 + elem + offset].iov_len;
}
iov[2 + elem + offset].iov_base = (void *) nulbytes;
iov[2 + elem + offset].iov_len = 4 - (total % 4);
total += 4 - (total % 4);
idx[elem + 1] = idx[elem] + total;
break; break;
case _NL_ITEM_INDEX (_NL_CTYPE_MAP_NAMES): case _NL_ITEM_INDEX (_NL_CTYPE_MAP_NAMES):
/* The class name array. */ /* The class name array. */
total = 0; start_locale_structure (&file);
for (cnt = 0; cnt < ctype->map_collection_nr; ++cnt, ++offset) for (cnt = 0; cnt < ctype->map_collection_nr; ++cnt)
{ add_locale_string (&file, ctype->mapnames[cnt]);
iov[2 + elem + offset].iov_base add_locale_char (&file, 0);
= (void *) ctype->mapnames[cnt]; align_locale_data (&file, 4);
iov[2 + elem + offset].iov_len end_locale_structure (&file);
= strlen (ctype->mapnames[cnt]) + 1;
total += iov[2 + elem + offset].iov_len;
}
iov[2 + elem + offset].iov_base = (void *) nulbytes;
iov[2 + elem + offset].iov_len = 4 - (total % 4);
total += 4 - (total % 4);
idx[elem + 1] = idx[elem] + total;
break; break;
CTYPE_DATA (_NL_CTYPE_WIDTH, case _NL_ITEM_INDEX (_NL_CTYPE_WIDTH):
ctype->width.iov_base, add_locale_wcwidth_table (&file, &ctype->width);
ctype->width.iov_len); break;
CTYPE_DATA (_NL_CTYPE_MB_CUR_MAX, CTYPE_UINT32 (_NL_CTYPE_MB_CUR_MAX, ctype->mb_cur_max);
&ctype->mb_cur_max, sizeof (uint32_t));
case _NL_ITEM_INDEX (_NL_CTYPE_CODESET_NAME): case _NL_ITEM_INDEX (_NL_CTYPE_CODESET_NAME):
total = strlen (ctype->codeset_name) + 1; add_locale_string (&file, ctype->codeset_name);
if (total % 4 == 0)
iov[2 + elem + offset].iov_base = (char *) ctype->codeset_name;
else
{
iov[2 + elem + offset].iov_base = alloca ((total + 3) & ~3);
memset (mempcpy (iov[2 + elem + offset].iov_base,
ctype->codeset_name, total),
'\0', 4 - (total & 3));
total = (total + 3) & ~3;
}
iov[2 + elem + offset].iov_len = total;
idx[elem + 1] = idx[elem] + iov[2 + elem + offset].iov_len;
break; break;
CTYPE_UINT32 (_NL_CTYPE_MAP_TO_NONASCII, ctype->to_nonascii);
CTYPE_DATA (_NL_CTYPE_MAP_TO_NONASCII, CTYPE_UINT32 (_NL_CTYPE_NONASCII_CASE, ctype->nonascii_case);
&ctype->to_nonascii, sizeof (uint32_t));
CTYPE_DATA (_NL_CTYPE_NONASCII_CASE,
&ctype->nonascii_case, sizeof (uint32_t));
case _NL_ITEM_INDEX (_NL_CTYPE_INDIGITS_MB_LEN): case _NL_ITEM_INDEX (_NL_CTYPE_INDIGITS_MB_LEN):
iov[2 + elem + offset].iov_base = alloca (sizeof (uint32_t)); add_locale_uint32 (&file, ctype->mbdigits_act / 10);
iov[2 + elem + offset].iov_len = sizeof (uint32_t);
*(uint32_t *) iov[2 + elem + offset].iov_base =
ctype->mbdigits_act / 10;
idx[elem + 1] = idx[elem] + sizeof (uint32_t);
break; break;
case _NL_ITEM_INDEX (_NL_CTYPE_INDIGITS_WC_LEN): case _NL_ITEM_INDEX (_NL_CTYPE_INDIGITS_WC_LEN):
/* Align entries. */ add_locale_uint32 (&file, ctype->wcdigits_act / 10);
iov[2 + elem + offset].iov_base = (void *) nulbytes;
iov[2 + elem + offset].iov_len = (4 - idx[elem] % 4) % 4;
idx[elem] += iov[2 + elem + offset].iov_len;
++offset;
iov[2 + elem + offset].iov_base = alloca (sizeof (uint32_t));
iov[2 + elem + offset].iov_len = sizeof (uint32_t);
*(uint32_t *) iov[2 + elem + offset].iov_base =
ctype->wcdigits_act / 10;
idx[elem + 1] = idx[elem] + sizeof (uint32_t);
break; break;
case _NL_ITEM_INDEX (_NL_CTYPE_INDIGITS0_MB) ... _NL_ITEM_INDEX (_NL_CTYPE_INDIGITS9_MB): case _NL_ITEM_INDEX (_NL_CTYPE_INDIGITS0_MB) ... _NL_ITEM_INDEX (_NL_CTYPE_INDIGITS9_MB):
/* Compute the length of all possible characters. For INDIGITS start_locale_structure (&file);
there might be more than one. We simply concatenate all of
them with a NUL byte following. The NUL byte wouldn't be
necessary but it makes it easier for the user. */
total = 0;
for (cnt = elem - _NL_ITEM_INDEX (_NL_CTYPE_INDIGITS0_MB);
cnt < ctype->mbdigits_act; cnt += 10)
total += ctype->mbdigits[cnt]->nbytes + 1;
iov[2 + elem + offset].iov_base = (char *) alloca (total);
iov[2 + elem + offset].iov_len = total;
cp = iov[2 + elem + offset].iov_base;
for (cnt = elem - _NL_ITEM_INDEX (_NL_CTYPE_INDIGITS0_MB); for (cnt = elem - _NL_ITEM_INDEX (_NL_CTYPE_INDIGITS0_MB);
cnt < ctype->mbdigits_act; cnt += 10) cnt < ctype->mbdigits_act; cnt += 10)
{ {
cp = mempcpy (cp, ctype->mbdigits[cnt]->bytes, add_locale_raw_data (&file, ctype->mbdigits[cnt]->bytes,
ctype->mbdigits[cnt]->nbytes); ctype->mbdigits[cnt]->nbytes);
*cp++ = '\0'; add_locale_char (&file, 0);
} }
idx[elem + 1] = idx[elem] + iov[2 + elem + offset].iov_len; end_locale_structure (&file);
break; break;
case _NL_ITEM_INDEX (_NL_CTYPE_OUTDIGIT0_MB) ... _NL_ITEM_INDEX (_NL_CTYPE_OUTDIGIT9_MB): case _NL_ITEM_INDEX (_NL_CTYPE_OUTDIGIT0_MB) ... _NL_ITEM_INDEX (_NL_CTYPE_OUTDIGIT9_MB):
/* Compute the length of all possible characters. For INDIGITS start_locale_structure (&file);
there might be more than one. We simply concatenate all of
them with a NUL byte following. The NUL byte wouldn't be
necessary but it makes it easier for the user. */
cnt = elem - _NL_ITEM_INDEX (_NL_CTYPE_OUTDIGIT0_MB); cnt = elem - _NL_ITEM_INDEX (_NL_CTYPE_OUTDIGIT0_MB);
total = ctype->mboutdigits[cnt]->nbytes + 1; add_locale_raw_data (&file, ctype->mboutdigits[cnt]->bytes,
iov[2 + elem + offset].iov_base = (char *) alloca (total); ctype->mboutdigits[cnt]->nbytes);
iov[2 + elem + offset].iov_len = total; add_locale_char (&file, 0);
end_locale_structure (&file);
*(char *) mempcpy (iov[2 + elem + offset].iov_base,
ctype->mboutdigits[cnt]->bytes,
ctype->mboutdigits[cnt]->nbytes) = '\0';
idx[elem + 1] = idx[elem] + iov[2 + elem + offset].iov_len;
break; break;
case _NL_ITEM_INDEX (_NL_CTYPE_INDIGITS0_WC) ... _NL_ITEM_INDEX (_NL_CTYPE_INDIGITS9_WC): case _NL_ITEM_INDEX (_NL_CTYPE_INDIGITS0_WC) ... _NL_ITEM_INDEX (_NL_CTYPE_INDIGITS9_WC):
total = ctype->wcdigits_act / 10; start_locale_structure (&file);
iov[2 + elem + offset].iov_base =
(uint32_t *) alloca (total * sizeof (uint32_t));
iov[2 + elem + offset].iov_len = total * sizeof (uint32_t);
for (cnt = elem - _NL_ITEM_INDEX (_NL_CTYPE_INDIGITS0_WC); for (cnt = elem - _NL_ITEM_INDEX (_NL_CTYPE_INDIGITS0_WC);
cnt < ctype->wcdigits_act; cnt += 10) cnt < ctype->wcdigits_act; cnt += 10)
((uint32_t *) iov[2 + elem + offset].iov_base)[cnt / 10] add_locale_uint32 (&file, ctype->wcdigits[cnt]);
= ctype->wcdigits[cnt]; end_locale_structure (&file);
idx[elem + 1] = idx[elem] + iov[2 + elem + offset].iov_len;
break; break;
case _NL_ITEM_INDEX (_NL_CTYPE_OUTDIGIT0_WC): case _NL_ITEM_INDEX (_NL_CTYPE_OUTDIGIT0_WC) ... _NL_ITEM_INDEX (_NL_CTYPE_OUTDIGIT9_WC):
/* Align entries. */
iov[2 + elem + offset].iov_base = (void *) nulbytes;
iov[2 + elem + offset].iov_len = (4 - idx[elem] % 4) % 4;
idx[elem] += iov[2 + elem + offset].iov_len;
++offset;
/* FALLTRHOUGH */
case _NL_ITEM_INDEX (_NL_CTYPE_OUTDIGIT1_WC) ... _NL_ITEM_INDEX (_NL_CTYPE_OUTDIGIT9_WC):
cnt = elem - _NL_ITEM_INDEX (_NL_CTYPE_OUTDIGIT0_WC); cnt = elem - _NL_ITEM_INDEX (_NL_CTYPE_OUTDIGIT0_WC);
iov[2 + elem + offset].iov_base = &ctype->wcoutdigits[cnt]; add_locale_uint32 (&file, ctype->wcoutdigits[cnt]);
iov[2 + elem + offset].iov_len = sizeof (uint32_t);
idx[elem + 1] = idx[elem] + iov[2 + elem + offset].iov_len;
break; break;
case _NL_ITEM_INDEX(_NL_CTYPE_TRANSLIT_DEFAULT_MISSING_LEN): case _NL_ITEM_INDEX(_NL_CTYPE_TRANSLIT_DEFAULT_MISSING_LEN):
/* Align entries. */ add_locale_uint32 (&file, default_missing_len);
iov[2 + elem + offset].iov_base = (void *) nulbytes;
iov[2 + elem + offset].iov_len = (4 - idx[elem] % 4) % 4;
idx[elem] += iov[2 + elem + offset].iov_len;
++offset;
default_missing_len = (ctype->default_missing
? wcslen ((wchar_t *)ctype->default_missing)
: 0);
iov[2 + elem + offset].iov_base = &default_missing_len;
iov[2 + elem + offset].iov_len = sizeof (uint32_t);
idx[elem + 1] = idx[elem] + iov[2 + elem + offset].iov_len;
break; break;
case _NL_ITEM_INDEX(_NL_CTYPE_TRANSLIT_DEFAULT_MISSING): case _NL_ITEM_INDEX(_NL_CTYPE_TRANSLIT_DEFAULT_MISSING):
iov[2 + elem + offset].iov_base = add_locale_uint32_array (&file, ctype->default_missing,
ctype->default_missing ?: (uint32_t *) L""; default_missing_len);
iov[2 + elem + offset].iov_len =
wcslen (iov[2 + elem + offset].iov_base) * sizeof (uint32_t);
idx[elem + 1] = idx[elem] + iov[2 + elem + offset].iov_len;
break; break;
case _NL_ITEM_INDEX(_NL_CTYPE_TRANSLIT_IGNORE_LEN): case _NL_ITEM_INDEX(_NL_CTYPE_TRANSLIT_IGNORE_LEN):
/* Align entries. */ add_locale_uint32 (&file, ctype->ntranslit_ignore);
iov[2 + elem + offset].iov_base = (void *) nulbytes;
iov[2 + elem + offset].iov_len = (4 - idx[elem] % 4) % 4;
idx[elem] += iov[2 + elem + offset].iov_len;
++offset;
iov[2 + elem + offset].iov_base = &ctype->ntranslit_ignore;
iov[2 + elem + offset].iov_len = sizeof (uint32_t);
idx[elem + 1] = idx[elem] + iov[2 + elem + offset].iov_len;
break; break;
case _NL_ITEM_INDEX(_NL_CTYPE_TRANSLIT_IGNORE): case _NL_ITEM_INDEX(_NL_CTYPE_TRANSLIT_IGNORE):
start_locale_structure (&file);
{ {
uint32_t *ranges = (uint32_t *) alloca (ctype->ntranslit_ignore
* 3 * sizeof (uint32_t));
struct translit_ignore_t *runp; struct translit_ignore_t *runp;
iov[2 + elem + offset].iov_base = ranges;
iov[2 + elem + offset].iov_len = (ctype->ntranslit_ignore
* 3 * sizeof (uint32_t));
for (runp = ctype->translit_ignore; runp != NULL; for (runp = ctype->translit_ignore; runp != NULL;
runp = runp->next) runp = runp->next)
{ {
*ranges++ = runp->from; add_locale_uint32 (&file, runp->from);
*ranges++ = runp->to; add_locale_uint32 (&file, runp->to);
*ranges++ = runp->step; add_locale_uint32 (&file, runp->step);
} }
} }
/* Remove the following line in case a new entry is added end_locale_structure (&file);
after _NL_CTYPE_TRANSLIT_DEFAULT_MISSING_LEN. */
if (elem < nelems)
idx[elem + 1] = idx[elem] + iov[2 + elem + offset].iov_len;
break; break;
default: default:
@ -1229,28 +1140,21 @@ ctype_output (struct localedef_t *locale, const struct charmap_t *charmap,
size_t nr = elem - _NL_ITEM_INDEX (_NL_CTYPE_EXTRA_MAP_1); size_t nr = elem - _NL_ITEM_INDEX (_NL_CTYPE_EXTRA_MAP_1);
if (nr < ctype->nr_charclass) if (nr < ctype->nr_charclass)
{ {
iov[2 + elem + offset].iov_base = ctype->class_b[nr]; start_locale_prelude (&file);
iov[2 + elem + offset].iov_len = 256 / 32 * sizeof (uint32_t); add_locale_uint32_array (&file, ctype->class_b[nr], 256 / 32);
idx[elem] += iov[2 + elem + offset].iov_len; end_locale_prelude (&file);
++offset; add_locale_wctype_table (&file, &ctype->class_3level[nr]);
iov[2 + elem + offset] = ctype->class_3level[nr];
} }
else else
{ {
nr -= ctype->nr_charclass; nr -= ctype->nr_charclass;
assert (nr < ctype->map_collection_nr); assert (nr < ctype->map_collection_nr);
iov[2 + elem + offset] = ctype->map_3level[nr]; add_locale_wctrans_table (&file, &ctype->map_3level[nr]);
} }
idx[elem + 1] = idx[elem] + iov[2 + elem + offset].iov_len;
} }
} }
assert (2 + elem + offset == (nelems + 2 * ctype->nr_charclass write_locale_data (output_path, LC_CTYPE, "LC_CTYPE", &file);
+ ctype->map_collection_nr + 4 + 2));
write_locale_data (output_path, LC_CTYPE, "LC_CTYPE", 2 + elem + offset,
iov);
} }
@ -3529,29 +3433,6 @@ no output digits defined and none of the standard names in the charmap")));
} }
/* Construction of sparse 3-level tables.
See wchar-lookup.h for their structure and the meaning of p and q. */
struct wctype_table
{
/* Parameters. */
unsigned int p;
unsigned int q;
/* Working representation. */
size_t level1_alloc;
size_t level1_size;
uint32_t *level1;
size_t level2_alloc;
size_t level2_size;
uint32_t *level2;
size_t level3_alloc;
size_t level3_size;
uint32_t *level3;
/* Compressed representation. */
size_t result_size;
char *result;
};
/* Initialize. Assumes t->p and t->q have already been set. */ /* Initialize. Assumes t->p and t->q have already been set. */
static inline void static inline void
wctype_table_init (struct wctype_table *t) wctype_table_init (struct wctype_table *t)
@ -3657,12 +3538,12 @@ wctype_table_add (struct wctype_table *t, uint32_t wc)
/* Finalize and shrink. */ /* Finalize and shrink. */
static void static void
wctype_table_finalize (struct wctype_table *t) add_locale_wctype_table (struct locale_file *file, struct wctype_table *t)
{ {
size_t i, j, k; size_t i, j, k;
uint32_t reorder3[t->level3_size]; uint32_t reorder3[t->level3_size];
uint32_t reorder2[t->level2_size]; uint32_t reorder2[t->level2_size];
uint32_t level1_offset, level2_offset, level3_offset; uint32_t level2_offset, level3_offset;
/* Uniquify level3 blocks. */ /* Uniquify level3 blocks. */
k = 0; k = 0;
@ -3712,16 +3593,12 @@ wctype_table_finalize (struct wctype_table *t)
if (t->level1[i] != EMPTY) if (t->level1[i] != EMPTY)
t->level1[i] = reorder2[t->level1[i]]; t->level1[i] = reorder2[t->level1[i]];
/* Create and fill the resulting compressed representation. */
t->result_size = t->result_size =
5 * sizeof (uint32_t) 5 * sizeof (uint32_t)
+ t->level1_size * sizeof (uint32_t) + t->level1_size * sizeof (uint32_t)
+ (t->level2_size << t->q) * sizeof (uint32_t) + (t->level2_size << t->q) * sizeof (uint32_t)
+ (t->level3_size << t->p) * sizeof (uint32_t); + (t->level3_size << t->p) * sizeof (uint32_t);
t->result = (char *) xmalloc (t->result_size);
level1_offset =
5 * sizeof (uint32_t);
level2_offset = level2_offset =
5 * sizeof (uint32_t) 5 * sizeof (uint32_t)
+ t->level1_size * sizeof (uint32_t); + t->level1_size * sizeof (uint32_t);
@ -3730,26 +3607,29 @@ wctype_table_finalize (struct wctype_table *t)
+ t->level1_size * sizeof (uint32_t) + t->level1_size * sizeof (uint32_t)
+ (t->level2_size << t->q) * sizeof (uint32_t); + (t->level2_size << t->q) * sizeof (uint32_t);
((uint32_t *) t->result)[0] = t->q + t->p + 5; start_locale_structure (file);
((uint32_t *) t->result)[1] = t->level1_size; add_locale_uint32 (file, t->q + t->p + 5);
((uint32_t *) t->result)[2] = t->p + 5; add_locale_uint32 (file, t->level1_size);
((uint32_t *) t->result)[3] = (1 << t->q) - 1; add_locale_uint32 (file, t->p + 5);
((uint32_t *) t->result)[4] = (1 << t->p) - 1; add_locale_uint32 (file, (1 << t->q) - 1);
add_locale_uint32 (file, (1 << t->p) - 1);
for (i = 0; i < t->level1_size; i++) for (i = 0; i < t->level1_size; i++)
((uint32_t *) (t->result + level1_offset))[i] = add_locale_uint32
(t->level1[i] == EMPTY (file,
t->level1[i] == EMPTY
? 0 ? 0
: (t->level1[i] << t->q) * sizeof (uint32_t) + level2_offset); : (t->level1[i] << t->q) * sizeof (uint32_t) + level2_offset);
for (i = 0; i < (t->level2_size << t->q); i++) for (i = 0; i < (t->level2_size << t->q); i++)
((uint32_t *) (t->result + level2_offset))[i] = add_locale_uint32
(t->level2[i] == EMPTY (file,
t->level2[i] == EMPTY
? 0 ? 0
: (t->level2[i] << t->p) * sizeof (uint32_t) + level3_offset); : (t->level2[i] << t->p) * sizeof (uint32_t) + level3_offset);
for (i = 0; i < (t->level3_size << t->p); i++) add_locale_uint32_array (file, t->level3, t->level3_size << t->p);
((uint32_t *) (t->result + level3_offset))[i] = t->level3[i]; end_locale_structure (file);
if (t->level1_alloc > 0) if (t->level1_alloc > 0)
free (t->level1); free (t->level1);
@ -3759,26 +3639,6 @@ wctype_table_finalize (struct wctype_table *t)
free (t->level3); free (t->level3);
} }
#define TABLE wcwidth_table
#define ELEMENT uint8_t
#define DEFAULT 0xff
#include "3level.h"
#define TABLE wctrans_table
#define ELEMENT int32_t
#define DEFAULT 0
#define wctrans_table_add wctrans_table_add_internal
#include "3level.h"
#undef wctrans_table_add
/* The wctrans_table must actually store the difference between the
desired result and the argument. */
static inline void
wctrans_table_add (struct wctrans_table *t, uint32_t wc, uint32_t mapped_wc)
{
wctrans_table_add_internal (t, wc, mapped_wc - wc);
}
/* Flattens the included transliterations into a translit list. /* Flattens the included transliterations into a translit list.
Inserts them in the list at `cursor', and returns the new cursor. */ Inserts them in the list at `cursor', and returns the new cursor. */
static struct translit_t ** static struct translit_t **
@ -3855,8 +3715,8 @@ allocate_arrays (struct locale_ctype_t *ctype, const struct charmap_t *charmap,
ctype->ctype32_b = (char_class32_t *) xcalloc (256, sizeof (char_class32_t)); ctype->ctype32_b = (char_class32_t *) xcalloc (256, sizeof (char_class32_t));
ctype->class_b = (uint32_t **) ctype->class_b = (uint32_t **)
xmalloc (ctype->nr_charclass * sizeof (uint32_t *)); xmalloc (ctype->nr_charclass * sizeof (uint32_t *));
ctype->class_3level = (struct iovec *) ctype->class_3level = (struct wctype_table *)
xmalloc (ctype->nr_charclass * sizeof (struct iovec)); xmalloc (ctype->nr_charclass * sizeof (struct wctype_table));
/* This is the array accessed using the multibyte string elements. */ /* This is the array accessed using the multibyte string elements. */
for (idx = 0; idx < 256; ++idx) for (idx = 0; idx < 256; ++idx)
@ -3888,34 +3748,30 @@ allocate_arrays (struct locale_ctype_t *ctype, const struct charmap_t *charmap,
for (nr = 0; nr < ctype->nr_charclass; nr++) for (nr = 0; nr < ctype->nr_charclass; nr++)
{ {
struct wctype_table t; struct wctype_table *t;
t.p = 4; /* or: 5 */ t = &ctype->class_3level[nr];
t.q = 7; /* or: 6 */ t->p = 4; /* or: 5 */
wctype_table_init (&t); t->q = 7; /* or: 6 */
wctype_table_init (t);
for (idx = 0; idx < ctype->class_collection_act; ++idx) for (idx = 0; idx < ctype->class_collection_act; ++idx)
if (ctype->class_collection[idx] & _ISwbit (nr)) if (ctype->class_collection[idx] & _ISwbit (nr))
wctype_table_add (&t, ctype->charnames[idx]); wctype_table_add (t, ctype->charnames[idx]);
wctype_table_finalize (&t);
if (verbose) if (verbose)
WITH_CUR_LOCALE (fprintf (stderr, _("\ WITH_CUR_LOCALE (fprintf (stderr, _("\
%s: table for class \"%s\": %lu bytes\n"), %s: table for class \"%s\": %lu bytes\n"),
"LC_CTYPE", ctype->classnames[nr], "LC_CTYPE", ctype->classnames[nr],
(unsigned long int) t.result_size)); (unsigned long int) t->result_size));
ctype->class_3level[nr].iov_base = t.result;
ctype->class_3level[nr].iov_len = t.result_size;
} }
/* Room for table of mappings. */ /* Room for table of mappings. */
ctype->map_b = (uint32_t **) xmalloc (2 * sizeof (uint32_t *)); ctype->map_b = (uint32_t **) xmalloc (2 * sizeof (uint32_t *));
ctype->map32_b = (uint32_t **) xmalloc (ctype->map_collection_nr ctype->map32_b = (uint32_t **) xmalloc (ctype->map_collection_nr
* sizeof (uint32_t *)); * sizeof (uint32_t *));
ctype->map_3level = (struct iovec *) ctype->map_3level = (struct wctrans_table *)
xmalloc (ctype->map_collection_nr * sizeof (struct iovec)); xmalloc (ctype->map_collection_nr * sizeof (struct wctrans_table));
/* Fill in all mappings. */ /* Fill in all mappings. */
for (idx = 0; idx < 2; ++idx) for (idx = 0; idx < 2; ++idx)
@ -3956,27 +3812,23 @@ allocate_arrays (struct locale_ctype_t *ctype, const struct charmap_t *charmap,
for (nr = 0; nr < ctype->map_collection_nr; nr++) for (nr = 0; nr < ctype->map_collection_nr; nr++)
{ {
struct wctrans_table t; struct wctrans_table *t;
t.p = 7; t = &ctype->map_3level[nr];
t.q = 9; t->p = 7;
wctrans_table_init (&t); t->q = 9;
wctrans_table_init (t);
for (idx = 0; idx < ctype->map_collection_act[nr]; ++idx) for (idx = 0; idx < ctype->map_collection_act[nr]; ++idx)
if (ctype->map_collection[nr][idx] != 0) if (ctype->map_collection[nr][idx] != 0)
wctrans_table_add (&t, ctype->charnames[idx], wctrans_table_add (t, ctype->charnames[idx],
ctype->map_collection[nr][idx]); ctype->map_collection[nr][idx]);
wctrans_table_finalize (&t);
if (verbose) if (verbose)
WITH_CUR_LOCALE (fprintf (stderr, _("\ WITH_CUR_LOCALE (fprintf (stderr, _("\
%s: table for map \"%s\": %lu bytes\n"), %s: table for map \"%s\": %lu bytes\n"),
"LC_CTYPE", ctype->mapnames[nr], "LC_CTYPE", ctype->mapnames[nr],
(unsigned long int) t.result_size)); (unsigned long int) t->result_size));
ctype->map_3level[nr].iov_base = t.result;
ctype->map_3level[nr].iov_len = t.result_size;
} }
/* Extra array for class and map names. */ /* Extra array for class and map names. */
@ -3996,11 +3848,12 @@ allocate_arrays (struct locale_ctype_t *ctype, const struct charmap_t *charmap,
saves a run-time check. saves a run-time check.
But we put L'\0' in the table. This again saves a run-time check. */ But we put L'\0' in the table. This again saves a run-time check. */
{ {
struct wcwidth_table t; struct wcwidth_table *t;
t.p = 7; t = &ctype->width;
t.q = 9; t->p = 7;
wcwidth_table_init (&t); t->q = 9;
wcwidth_table_init (t);
/* First set all the printable characters of the character set to /* First set all the printable characters of the character set to
the default width. */ the default width. */
@ -4020,7 +3873,7 @@ allocate_arrays (struct locale_ctype_t *ctype, const struct charmap_t *charmap,
&ctype->class_collection_act, data->ucs4); &ctype->class_collection_act, data->ucs4);
if (class_bits != NULL && (*class_bits & BITw (tok_print))) if (class_bits != NULL && (*class_bits & BITw (tok_print)))
wcwidth_table_add (&t, data->ucs4, charmap->width_default); wcwidth_table_add (t, data->ucs4, charmap->width_default);
} }
} }
@ -4068,7 +3921,7 @@ allocate_arrays (struct locale_ctype_t *ctype, const struct charmap_t *charmap,
&ctype->class_collection_act, wch); &ctype->class_collection_act, wch);
if (class_bits != NULL && (*class_bits & BITw (tok_print))) if (class_bits != NULL && (*class_bits & BITw (tok_print)))
wcwidth_table_add (&t, wch, wcwidth_table_add (t, wch,
charmap->width_rules[cnt].width); charmap->width_rules[cnt].width);
} }
@ -4098,16 +3951,11 @@ allocate_arrays (struct locale_ctype_t *ctype, const struct charmap_t *charmap,
} }
/* Set the width of L'\0' to 0. */ /* Set the width of L'\0' to 0. */
wcwidth_table_add (&t, 0, 0); wcwidth_table_add (t, 0, 0);
wcwidth_table_finalize (&t);
if (verbose) if (verbose)
WITH_CUR_LOCALE (fprintf (stderr, _("%s: table for width: %lu bytes\n"), WITH_CUR_LOCALE (fprintf (stderr, _("%s: table for width: %lu bytes\n"),
"LC_CTYPE", (unsigned long int) t.result_size)); "LC_CTYPE", (unsigned long int) t->result_size));
ctype->width.iov_base = t.result;
ctype->width.iov_len = t.result_size;
} }
/* Set MB_CUR_MAX. */ /* Set MB_CUR_MAX. */

View File

@ -182,116 +182,32 @@ identification_output (struct localedef_t *locale,
{ {
struct locale_identification_t *identification struct locale_identification_t *identification
= locale->categories[LC_IDENTIFICATION].identification; = locale->categories[LC_IDENTIFICATION].identification;
struct iovec iov[2 + _NL_ITEM_INDEX (_NL_NUM_LC_IDENTIFICATION) struct locale_file file;
+ (__LC_LAST - 2)];
struct locale_file data;
uint32_t idx[_NL_ITEM_INDEX (_NL_NUM_LC_IDENTIFICATION)];
size_t cnt = 0;
size_t num; size_t num;
size_t last_idx;
data.magic = LIMAGIC (LC_IDENTIFICATION); init_locale_data (&file, _NL_ITEM_INDEX (_NL_NUM_LC_IDENTIFICATION));
data.n = _NL_ITEM_INDEX (_NL_NUM_LC_IDENTIFICATION); add_locale_string (&file, identification->title);
iov[cnt].iov_base = (void *) &data; add_locale_string (&file, identification->source);
iov[cnt].iov_len = sizeof (data); add_locale_string (&file, identification->address);
++cnt; add_locale_string (&file, identification->contact);
add_locale_string (&file, identification->email);
iov[cnt].iov_base = (void *) idx; add_locale_string (&file, identification->tel);
iov[cnt].iov_len = sizeof (idx); add_locale_string (&file, identification->fax);
++cnt; add_locale_string (&file, identification->language);
add_locale_string (&file, identification->territory);
idx[cnt - 2] = iov[0].iov_len + iov[1].iov_len; add_locale_string (&file, identification->audience);
iov[cnt].iov_base = (void *) identification->title; add_locale_string (&file, identification->application);
iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1; add_locale_string (&file, identification->abbreviation);
++cnt; add_locale_string (&file, identification->revision);
add_locale_string (&file, identification->date);
idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len; start_locale_structure (&file);
iov[cnt].iov_base = (void *) identification->source;
iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
++cnt;
idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
iov[cnt].iov_base = (void *) identification->address;
iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
++cnt;
idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
iov[cnt].iov_base = (void *) identification->contact;
iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
++cnt;
idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
iov[cnt].iov_base = (void *) identification->email;
iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
++cnt;
idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
iov[cnt].iov_base = (void *) identification->tel;
iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
++cnt;
idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
iov[cnt].iov_base = (void *) identification->fax;
iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
++cnt;
idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
iov[cnt].iov_base = (void *) identification->language;
iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
++cnt;
idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
iov[cnt].iov_base = (void *) identification->territory;
iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
++cnt;
idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
iov[cnt].iov_base = (void *) identification->audience;
iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
++cnt;
idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
iov[cnt].iov_base = (void *) identification->application;
iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
++cnt;
idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
iov[cnt].iov_base = (void *) identification->abbreviation;
iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
++cnt;
idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
iov[cnt].iov_base = (void *) identification->revision;
iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
++cnt;
idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
iov[cnt].iov_base = (void *) identification->date;
iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
++cnt;
idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
last_idx = cnt - 1;
idx[last_idx] = idx[cnt - 2];
for (num = 0; num < __LC_LAST; ++num) for (num = 0; num < __LC_LAST; ++num)
if (num != LC_ALL) if (num != LC_ALL)
{ add_locale_string (&file, identification->category[num]);
iov[cnt].iov_base = (void *) identification->category[num]; end_locale_structure (&file);
iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1; add_locale_string (&file, charmap->code_set_name);
idx[last_idx] += iov[cnt].iov_len; write_locale_data (output_path, LC_IDENTIFICATION, "LC_IDENTIFICATION",
++cnt; &file);
}
assert (last_idx == _NL_ITEM_INDEX (_NL_NUM_LC_IDENTIFICATION) - 1);
iov[cnt].iov_base = (void *) charmap->code_set_name;
iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
++cnt;
assert (cnt == (2 + _NL_ITEM_INDEX (_NL_NUM_LC_IDENTIFICATION)
+ (__LC_LAST - 2)));
write_locale_data (output_path, LC_IDENTIFICATION, "LC_IDENTIFICATION", cnt,
iov);
} }

View File

@ -122,35 +122,12 @@ measurement_output (struct localedef_t *locale,
{ {
struct locale_measurement_t *measurement = struct locale_measurement_t *measurement =
locale->categories[LC_MEASUREMENT].measurement; locale->categories[LC_MEASUREMENT].measurement;
struct iovec iov[2 + _NL_ITEM_INDEX (_NL_NUM_LC_MEASUREMENT)]; struct locale_file file;
struct locale_file data;
uint32_t idx[_NL_ITEM_INDEX (_NL_NUM_LC_MEASUREMENT)];
size_t cnt = 0;
data.magic = LIMAGIC (LC_MEASUREMENT); init_locale_data (&file, _NL_ITEM_INDEX (_NL_NUM_LC_MEASUREMENT));
data.n = _NL_ITEM_INDEX (_NL_NUM_LC_MEASUREMENT); add_locale_char (&file, measurement->measurement);
iov[cnt].iov_base = (void *) &data; add_locale_string (&file, charmap->code_set_name);
iov[cnt].iov_len = sizeof (data); write_locale_data (output_path, LC_MEASUREMENT, "LC_MEASUREMENT", &file);
++cnt;
iov[cnt].iov_base = (void *) idx;
iov[cnt].iov_len = sizeof (idx);
++cnt;
idx[cnt - 2] = iov[0].iov_len + iov[1].iov_len;
iov[cnt].iov_base = &measurement->measurement;
iov[cnt].iov_len = 1;
++cnt;
idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
iov[cnt].iov_base = (void *) charmap->code_set_name;
iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
++cnt;
assert (cnt == 2 + _NL_ITEM_INDEX (_NL_NUM_LC_MEASUREMENT));
write_locale_data (output_path, LC_MEASUREMENT, "LC_MEASUREMENT",
2 + _NL_ITEM_INDEX (_NL_NUM_LC_MEASUREMENT), iov);
} }

View File

@ -184,49 +184,15 @@ messages_output (struct localedef_t *locale, const struct charmap_t *charmap,
{ {
struct locale_messages_t *messages struct locale_messages_t *messages
= locale->categories[LC_MESSAGES].messages; = locale->categories[LC_MESSAGES].messages;
struct iovec iov[2 + _NL_ITEM_INDEX (_NL_NUM_LC_MESSAGES)]; struct locale_file file;
struct locale_file data;
uint32_t idx[_NL_ITEM_INDEX (_NL_NUM_LC_MESSAGES)];
size_t cnt = 0;
data.magic = LIMAGIC (LC_MESSAGES); init_locale_data (&file, _NL_ITEM_INDEX (_NL_NUM_LC_MESSAGES));
data.n = _NL_ITEM_INDEX (_NL_NUM_LC_MESSAGES); add_locale_string (&file, messages->yesexpr);
iov[cnt].iov_base = (void *) &data; add_locale_string (&file, messages->noexpr);
iov[cnt].iov_len = sizeof (data); add_locale_string (&file, messages->yesstr);
++cnt; add_locale_string (&file, messages->nostr);
add_locale_string (&file, charmap->code_set_name);
iov[cnt].iov_base = (void *) idx; write_locale_data (output_path, LC_MESSAGES, "LC_MESSAGES", &file);
iov[cnt].iov_len = sizeof (idx);
++cnt;
idx[cnt - 2] = iov[0].iov_len + iov[1].iov_len;
iov[cnt].iov_base = (char *) messages->yesexpr;
iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
++cnt;
idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
iov[cnt].iov_base = (char *) messages->noexpr;
iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
++cnt;
idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
iov[cnt].iov_base = (char *) messages->yesstr;
iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
++cnt;
idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
iov[cnt].iov_base = (char *) messages->nostr;
iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
++cnt;
idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
iov[cnt].iov_base = (char *) charmap->code_set_name;
iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
assert (cnt + 1 == 2 + _NL_ITEM_INDEX (_NL_NUM_LC_MESSAGES));
write_locale_data (output_path, LC_MESSAGES, "LC_MESSAGES",
2 + _NL_ITEM_INDEX (_NL_NUM_LC_MESSAGES), iov);
} }

View File

@ -364,262 +364,57 @@ monetary_output (struct localedef_t *locale, const struct charmap_t *charmap,
{ {
struct locale_monetary_t *monetary struct locale_monetary_t *monetary
= locale->categories[LC_MONETARY].monetary; = locale->categories[LC_MONETARY].monetary;
struct iovec iov[3 + _NL_ITEM_INDEX (_NL_NUM_LC_MONETARY)]; struct locale_file file;
struct locale_file data;
uint32_t idx[_NL_ITEM_INDEX (_NL_NUM_LC_MONETARY)];
size_t cnt = 0;
data.magic = LIMAGIC (LC_MONETARY); init_locale_data (&file, _NL_ITEM_INDEX (_NL_NUM_LC_MONETARY));
data.n = _NL_ITEM_INDEX (_NL_NUM_LC_MONETARY); add_locale_string (&file, monetary->int_curr_symbol);
iov[cnt].iov_base = (void *) &data; add_locale_string (&file, monetary->currency_symbol);
iov[cnt].iov_len = sizeof (data); add_locale_string (&file, monetary->mon_decimal_point);
++cnt; add_locale_string (&file, monetary->mon_thousands_sep);
add_locale_raw_data (&file, monetary->mon_grouping,
iov[cnt].iov_base = (void *) idx; monetary->mon_grouping_len);
iov[cnt].iov_len = sizeof (idx); add_locale_string (&file, monetary->positive_sign);
++cnt; add_locale_string (&file, monetary->negative_sign);
add_locale_char (&file, monetary->int_frac_digits);
idx[cnt - 2] = iov[0].iov_len + iov[1].iov_len; add_locale_char (&file, monetary->frac_digits);
iov[cnt].iov_base = (void *) monetary->int_curr_symbol; add_locale_char (&file, monetary->p_cs_precedes);
iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1; add_locale_char (&file, monetary->p_sep_by_space);
++cnt; add_locale_char (&file, monetary->n_cs_precedes);
add_locale_char (&file, monetary->n_sep_by_space);
idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len; add_locale_char (&file, monetary->p_sign_posn);
iov[cnt].iov_base = (void *) monetary->currency_symbol; add_locale_char (&file, monetary->n_sign_posn);
iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1; add_locale_string (&file, monetary->crncystr);
++cnt; add_locale_char (&file, monetary->int_p_cs_precedes);
add_locale_char (&file, monetary->int_p_sep_by_space);
idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len; add_locale_char (&file, monetary->int_n_cs_precedes);
iov[cnt].iov_base = (void *) monetary->mon_decimal_point; add_locale_char (&file, monetary->int_n_sep_by_space);
iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1; add_locale_char (&file, monetary->int_p_sign_posn);
++cnt; add_locale_char (&file, monetary->int_n_sign_posn);
add_locale_string (&file, monetary->duo_int_curr_symbol);
idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len; add_locale_string (&file, monetary->duo_currency_symbol);
iov[cnt].iov_base = (void *) monetary->mon_thousands_sep; add_locale_char (&file, monetary->duo_int_frac_digits);
iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1; add_locale_char (&file, monetary->duo_frac_digits);
++cnt; add_locale_char (&file, monetary->duo_p_cs_precedes);
add_locale_char (&file, monetary->duo_p_sep_by_space);
idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len; add_locale_char (&file, monetary->duo_n_cs_precedes);
iov[cnt].iov_base = monetary->mon_grouping; add_locale_char (&file, monetary->duo_n_sep_by_space);
iov[cnt].iov_len = monetary->mon_grouping_len; add_locale_char (&file, monetary->duo_int_p_cs_precedes);
++cnt; add_locale_char (&file, monetary->duo_int_p_sep_by_space);
add_locale_char (&file, monetary->duo_int_n_cs_precedes);
idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len; add_locale_char (&file, monetary->duo_int_n_sep_by_space);
iov[cnt].iov_base = (void *) monetary->positive_sign; add_locale_char (&file, monetary->duo_p_sign_posn);
iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1; add_locale_char (&file, monetary->duo_n_sign_posn);
++cnt; add_locale_char (&file, monetary->duo_int_p_sign_posn);
add_locale_char (&file, monetary->duo_int_n_sign_posn);
idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len; add_locale_uint32 (&file, monetary->uno_valid_from);
iov[cnt].iov_base = (void *) monetary->negative_sign; add_locale_uint32 (&file, monetary->uno_valid_to);
iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1; add_locale_uint32 (&file, monetary->duo_valid_from);
++cnt; add_locale_uint32 (&file, monetary->duo_valid_to);
add_locale_uint32_array (&file, monetary->conversion_rate, 2);
idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len; add_locale_uint32 (&file, monetary->mon_decimal_point_wc);
iov[cnt].iov_base = (void *) &monetary->int_frac_digits; add_locale_uint32 (&file, monetary->mon_thousands_sep_wc);
iov[cnt].iov_len = 1; add_locale_string (&file, charmap->code_set_name);
++cnt; write_locale_data (output_path, LC_MONETARY, "LC_MONETARY", &file);
idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
iov[cnt].iov_base = (void *) &monetary->frac_digits;
iov[cnt].iov_len = 1;
++cnt;
idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
iov[cnt].iov_base = (void *) &monetary->p_cs_precedes;
iov[cnt].iov_len = 1;
++cnt;
idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
iov[cnt].iov_base = (void *) &monetary->p_sep_by_space;
iov[cnt].iov_len = 1;
++cnt;
idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
iov[cnt].iov_base = (void *) &monetary->n_cs_precedes;
iov[cnt].iov_len = 1;
++cnt;
idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
iov[cnt].iov_base = (void *) &monetary->n_sep_by_space;
iov[cnt].iov_len = 1;
++cnt;
idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
iov[cnt].iov_base = (void *) &monetary->p_sign_posn;
iov[cnt].iov_len = 1;
++cnt;
idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
iov[cnt].iov_base = (void *) &monetary->n_sign_posn;
iov[cnt].iov_len = 1;
++cnt;
idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
iov[cnt].iov_base = (void *) monetary->crncystr;
iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
++cnt;
idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
iov[cnt].iov_base = (void *) &monetary->int_p_cs_precedes;
iov[cnt].iov_len = 1;
++cnt;
idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
iov[cnt].iov_base = (void *) &monetary->int_p_sep_by_space;
iov[cnt].iov_len = 1;
++cnt;
idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
iov[cnt].iov_base = (void *) &monetary->int_n_cs_precedes;
iov[cnt].iov_len = 1;
++cnt;
idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
iov[cnt].iov_base = (void *) &monetary->int_n_sep_by_space;
iov[cnt].iov_len = 1;
++cnt;
idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
iov[cnt].iov_base = (void *) &monetary->int_p_sign_posn;
iov[cnt].iov_len = 1;
++cnt;
idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
iov[cnt].iov_base = (void *) &monetary->int_n_sign_posn;
iov[cnt].iov_len = 1;
++cnt;
idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
iov[cnt].iov_base = (void *) monetary->duo_int_curr_symbol;
iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
++cnt;
idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
iov[cnt].iov_base = (void *) monetary->duo_currency_symbol;
iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
++cnt;
idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
iov[cnt].iov_base = (void *) &monetary->duo_int_frac_digits;
iov[cnt].iov_len = 1;
++cnt;
idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
iov[cnt].iov_base = (void *) &monetary->duo_frac_digits;
iov[cnt].iov_len = 1;
++cnt;
idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
iov[cnt].iov_base = (void *) &monetary->duo_p_cs_precedes;
iov[cnt].iov_len = 1;
++cnt;
idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
iov[cnt].iov_base = (void *) &monetary->duo_p_sep_by_space;
iov[cnt].iov_len = 1;
++cnt;
idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
iov[cnt].iov_base = (void *) &monetary->duo_n_cs_precedes;
iov[cnt].iov_len = 1;
++cnt;
idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
iov[cnt].iov_base = (void *) &monetary->duo_n_sep_by_space;
iov[cnt].iov_len = 1;
++cnt;
idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
iov[cnt].iov_base = (void *) &monetary->duo_int_p_cs_precedes;
iov[cnt].iov_len = 1;
++cnt;
idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
iov[cnt].iov_base = (void *) &monetary->duo_int_p_sep_by_space;
iov[cnt].iov_len = 1;
++cnt;
idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
iov[cnt].iov_base = (void *) &monetary->duo_int_n_cs_precedes;
iov[cnt].iov_len = 1;
++cnt;
idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
iov[cnt].iov_base = (void *) &monetary->duo_int_n_sep_by_space;
iov[cnt].iov_len = 1;
++cnt;
idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
iov[cnt].iov_base = (void *) &monetary->duo_p_sign_posn;
iov[cnt].iov_len = 1;
++cnt;
idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
iov[cnt].iov_base = (void *) &monetary->duo_n_sign_posn;
iov[cnt].iov_len = 1;
++cnt;
idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
iov[cnt].iov_base = (void *) &monetary->duo_int_p_sign_posn;
iov[cnt].iov_len = 1;
++cnt;
idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
iov[cnt].iov_base = (void *) &monetary->duo_int_n_sign_posn;
iov[cnt].iov_len = 1;
++cnt;
idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
/* Align following data */
iov[cnt].iov_base = (void *) "\0\0";
iov[cnt].iov_len = ((idx[cnt - 2] + 3) & ~3) - idx[cnt - 2];
idx[cnt - 2] = (idx[cnt - 2] + 3) & ~3;
++cnt;
iov[cnt].iov_base = (void *) &monetary->uno_valid_from;
iov[cnt].iov_len = sizeof(uint32_t);
++cnt;
idx[cnt - 3] = idx[cnt - 4] + iov[cnt - 1].iov_len;
iov[cnt].iov_base = (void *) &monetary->uno_valid_to;
iov[cnt].iov_len = sizeof(uint32_t);
++cnt;
idx[cnt - 3] = idx[cnt - 4] + iov[cnt - 1].iov_len;
iov[cnt].iov_base = (void *) &monetary->duo_valid_from;
iov[cnt].iov_len = sizeof(uint32_t);
++cnt;
idx[cnt - 3] = idx[cnt - 4] + iov[cnt - 1].iov_len;
iov[cnt].iov_base = (void *) &monetary->duo_valid_to;
iov[cnt].iov_len = sizeof(uint32_t);
++cnt;
idx[cnt - 3] = idx[cnt - 4] + iov[cnt - 1].iov_len;
iov[cnt].iov_base = (void *) monetary->conversion_rate;
iov[cnt].iov_len = 2 * sizeof(uint32_t);
++cnt;
idx[cnt - 3] = idx[cnt - 4] + iov[cnt - 1].iov_len;
iov[cnt].iov_base = (void *) &monetary->mon_decimal_point_wc;
iov[cnt].iov_len = sizeof (uint32_t);
++cnt;
idx[cnt - 3] = idx[cnt - 4] + iov[cnt - 1].iov_len;
iov[cnt].iov_base = (void *) &monetary->mon_thousands_sep_wc;
iov[cnt].iov_len = sizeof (uint32_t);
++cnt;
idx[cnt - 3] = idx[cnt - 4] + iov[cnt - 1].iov_len;
iov[cnt].iov_base = (void *) charmap->code_set_name;
iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
++cnt;
assert (cnt == 3 + _NL_ITEM_INDEX (_NL_NUM_LC_MONETARY));
write_locale_data (output_path, LC_MONETARY, "LC_MONETARY",
3 + _NL_ITEM_INDEX (_NL_NUM_LC_MONETARY), iov);
} }

View File

@ -157,60 +157,17 @@ name_output (struct localedef_t *locale, const struct charmap_t *charmap,
const char *output_path) const char *output_path)
{ {
struct locale_name_t *name = locale->categories[LC_NAME].name; struct locale_name_t *name = locale->categories[LC_NAME].name;
struct iovec iov[2 + _NL_ITEM_INDEX (_NL_NUM_LC_NAME)]; struct locale_file file;
struct locale_file data;
uint32_t idx[_NL_ITEM_INDEX (_NL_NUM_LC_NAME)];
size_t cnt = 0;
data.magic = LIMAGIC (LC_NAME); init_locale_data (&file, _NL_ITEM_INDEX (_NL_NUM_LC_NAME));
data.n = _NL_ITEM_INDEX (_NL_NUM_LC_NAME); add_locale_string (&file, name->name_fmt);
iov[cnt].iov_base = (void *) &data; add_locale_string (&file, name->name_gen);
iov[cnt].iov_len = sizeof (data); add_locale_string (&file, name->name_mr);
++cnt; add_locale_string (&file, name->name_mrs);
add_locale_string (&file, name->name_miss);
iov[cnt].iov_base = (void *) idx; add_locale_string (&file, name->name_ms);
iov[cnt].iov_len = sizeof (idx); add_locale_string (&file, charmap->code_set_name);
++cnt; write_locale_data (output_path, LC_NAME, "LC_NAME", &file);
idx[cnt - 2] = iov[0].iov_len + iov[1].iov_len;
iov[cnt].iov_base = (void *) name->name_fmt;
iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
++cnt;
idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
iov[cnt].iov_base = (void *) name->name_gen;
iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
++cnt;
idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
iov[cnt].iov_base = (void *) name->name_mr;
iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
++cnt;
idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
iov[cnt].iov_base = (void *) name->name_mrs;
iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
++cnt;
idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
iov[cnt].iov_base = (void *) name->name_miss;
iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
++cnt;
idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
iov[cnt].iov_base = (void *) name->name_ms;
iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
++cnt;
idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
iov[cnt].iov_base = (void *) charmap->code_set_name;
iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
++cnt;
assert (cnt == 2 + _NL_ITEM_INDEX (_NL_NUM_LC_NAME));
write_locale_data (output_path, LC_NAME, "LC_NAME",
2 + _NL_ITEM_INDEX (_NL_NUM_LC_NAME), iov);
} }

View File

@ -133,61 +133,16 @@ numeric_output (struct localedef_t *locale, const struct charmap_t *charmap,
const char *output_path) const char *output_path)
{ {
struct locale_numeric_t *numeric = locale->categories[LC_NUMERIC].numeric; struct locale_numeric_t *numeric = locale->categories[LC_NUMERIC].numeric;
struct iovec iov[3 + _NL_ITEM_INDEX (_NL_NUM_LC_NUMERIC)]; struct locale_file file;
struct locale_file data;
uint32_t idx[_NL_ITEM_INDEX (_NL_NUM_LC_NUMERIC)];
size_t cnt = 0;
data.magic = LIMAGIC (LC_NUMERIC); init_locale_data (&file, _NL_ITEM_INDEX (_NL_NUM_LC_NUMERIC));
data.n = _NL_ITEM_INDEX (_NL_NUM_LC_NUMERIC); add_locale_string (&file, numeric->decimal_point ?: "");
iov[cnt].iov_base = (void *) &data; add_locale_string (&file, numeric->thousands_sep ?: "");
iov[cnt].iov_len = sizeof (data); add_locale_raw_data (&file, numeric->grouping, numeric->grouping_len);
++cnt; add_locale_uint32 (&file, numeric->decimal_point_wc);
add_locale_uint32 (&file, numeric->thousands_sep_wc);
iov[cnt].iov_base = (void *) idx; add_locale_string (&file, charmap->code_set_name);
iov[cnt].iov_len = sizeof (idx); write_locale_data (output_path, LC_NUMERIC, "LC_NUMERIC", &file);
++cnt;
idx[cnt - 2] = iov[0].iov_len + iov[1].iov_len;
iov[cnt].iov_base = (void *) (numeric->decimal_point ?: "");
iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
++cnt;
idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
iov[cnt].iov_base = (void *) (numeric->thousands_sep ?: "");
iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
++cnt;
idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
iov[cnt].iov_base = numeric->grouping;
iov[cnt].iov_len = numeric->grouping_len;
++cnt;
idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
/* Align following data */
iov[cnt].iov_base = (void *) "\0\0";
iov[cnt].iov_len = ((idx[cnt - 2] + 3) & ~3) - idx[cnt - 2];
idx[cnt - 2] = (idx[cnt - 2] + 3) & ~3;
++cnt;
iov[cnt].iov_base = (void *) &numeric->decimal_point_wc;
iov[cnt].iov_len = sizeof (uint32_t);
++cnt;
idx[cnt - 3] = idx[cnt - 4] + iov[cnt - 1].iov_len;
iov[cnt].iov_base = (void *) &numeric->thousands_sep_wc;
iov[cnt].iov_len = sizeof (uint32_t);
++cnt;
idx[cnt - 3] = idx[cnt - 4] + iov[cnt - 1].iov_len;
iov[cnt].iov_base = (void *) charmap->code_set_name;
iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
assert (cnt + 1 == 3 + _NL_ITEM_INDEX (_NL_NUM_LC_NUMERIC));
write_locale_data (output_path, LC_NUMERIC, "LC_NUMERIC",
3 + _NL_ITEM_INDEX (_NL_NUM_LC_NUMERIC), iov);
} }

View File

@ -121,40 +121,13 @@ paper_output (struct localedef_t *locale, const struct charmap_t *charmap,
const char *output_path) const char *output_path)
{ {
struct locale_paper_t *paper = locale->categories[LC_PAPER].paper; struct locale_paper_t *paper = locale->categories[LC_PAPER].paper;
struct iovec iov[2 + _NL_ITEM_INDEX (_NL_NUM_LC_PAPER)]; struct locale_file file;
struct locale_file data;
uint32_t idx[_NL_ITEM_INDEX (_NL_NUM_LC_PAPER)];
size_t cnt = 0;
data.magic = LIMAGIC (LC_PAPER); init_locale_data (&file, _NL_ITEM_INDEX (_NL_NUM_LC_PAPER));
data.n = _NL_ITEM_INDEX (_NL_NUM_LC_PAPER); add_locale_uint32 (&file, paper->height);
iov[cnt].iov_base = (void *) &data; add_locale_uint32 (&file, paper->width);
iov[cnt].iov_len = sizeof (data); add_locale_string (&file, charmap->code_set_name);
++cnt; write_locale_data (output_path, LC_PAPER, "LC_PAPER", &file);
iov[cnt].iov_base = (void *) idx;
iov[cnt].iov_len = sizeof (idx);
++cnt;
idx[cnt - 2] = iov[cnt - 2].iov_len + iov[cnt - 1].iov_len;
iov[cnt].iov_base = &paper->height;
iov[cnt].iov_len = 4;
++cnt;
idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
iov[cnt].iov_base = &paper->width;
iov[cnt].iov_len = 4;
++cnt;
idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
iov[cnt].iov_base = (void *) charmap->code_set_name;
iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
++cnt;
assert (cnt == 2 + _NL_ITEM_INDEX (_NL_NUM_LC_PAPER));
write_locale_data (output_path, LC_PAPER, "LC_PAPER",
2 + _NL_ITEM_INDEX (_NL_NUM_LC_PAPER), iov);
} }

View File

@ -175,50 +175,15 @@ telephone_output (struct localedef_t *locale, const struct charmap_t *charmap,
{ {
struct locale_telephone_t *telephone = struct locale_telephone_t *telephone =
locale->categories[LC_TELEPHONE].telephone; locale->categories[LC_TELEPHONE].telephone;
struct iovec iov[2 + _NL_ITEM_INDEX (_NL_NUM_LC_TELEPHONE)]; struct locale_file file;
struct locale_file data;
uint32_t idx[_NL_ITEM_INDEX (_NL_NUM_LC_TELEPHONE)];
size_t cnt = 0;
data.magic = LIMAGIC (LC_TELEPHONE); init_locale_data (&file, _NL_ITEM_INDEX (_NL_NUM_LC_TELEPHONE));
data.n = _NL_ITEM_INDEX (_NL_NUM_LC_TELEPHONE); add_locale_string (&file, telephone->tel_int_fmt);
iov[cnt].iov_base = (void *) &data; add_locale_string (&file, telephone->tel_dom_fmt);
iov[cnt].iov_len = sizeof (data); add_locale_string (&file, telephone->int_select);
++cnt; add_locale_string (&file, telephone->int_prefix);
add_locale_string (&file, charmap->code_set_name);
iov[cnt].iov_base = (void *) idx; write_locale_data (output_path, LC_TELEPHONE, "LC_TELEPHONE", &file);
iov[cnt].iov_len = sizeof (idx);
++cnt;
idx[cnt - 2] = iov[0].iov_len + iov[1].iov_len;
iov[cnt].iov_base = (void *) telephone->tel_int_fmt;
iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
++cnt;
idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
iov[cnt].iov_base = (void *) telephone->tel_dom_fmt;
iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
++cnt;
idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
iov[cnt].iov_base = (void *) telephone->int_select;
iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
++cnt;
idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
iov[cnt].iov_base = (void *) telephone->int_prefix;
iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
++cnt;
idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
iov[cnt].iov_base = (void *) charmap->code_set_name;;
iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
++cnt;
assert (cnt == 2 + _NL_ITEM_INDEX (_NL_NUM_LC_TELEPHONE));
write_locale_data (output_path, LC_TELEPHONE, "LC_TELEPHONE",
2 + _NL_ITEM_INDEX (_NL_NUM_LC_TELEPHONE), iov);
} }

View File

@ -539,394 +539,116 @@ time_output (struct localedef_t *locale, const struct charmap_t *charmap,
const char *output_path) const char *output_path)
{ {
struct locale_time_t *time = locale->categories[LC_TIME].time; struct locale_time_t *time = locale->categories[LC_TIME].time;
struct iovec *iov = alloca (sizeof *iov struct locale_file file;
* (2 + _NL_ITEM_INDEX (_NL_NUM_LC_TIME) size_t num, n;
+ time->num_era - 1
+ 2 * 99
+ 2 + time->num_era * 10));
struct locale_file data;
uint32_t idx[_NL_ITEM_INDEX (_NL_NUM_LC_TIME)];
size_t cnt, last_idx, num, n;
data.magic = LIMAGIC (LC_TIME); init_locale_data (&file, _NL_ITEM_INDEX (_NL_NUM_LC_TIME));
data.n = _NL_ITEM_INDEX (_NL_NUM_LC_TIME);
iov[0].iov_base = (void *) &data;
iov[0].iov_len = sizeof (data);
iov[1].iov_base = (void *) idx;
iov[1].iov_len = sizeof (idx);
idx[0] = iov[0].iov_len + iov[1].iov_len;
/* The ab'days. */ /* The ab'days. */
for (cnt = 0; cnt <= _NL_ITEM_INDEX (ABDAY_7); ++cnt) for (n = 0; n < 7; ++n)
{ add_locale_string (&file, time->abday[n] ?: "");
iov[2 + cnt].iov_base =
(void *) (time->abday[cnt - _NL_ITEM_INDEX (ABDAY_1)] ?: "");
iov[2 + cnt].iov_len = strlen (iov[2 + cnt].iov_base) + 1;
idx[1 + cnt] = idx[cnt] + iov[2 + cnt].iov_len;
}
/* The days. */ /* The days. */
for (; cnt <= _NL_ITEM_INDEX (DAY_7); ++cnt) for (n = 0; n < 7; ++n)
{ add_locale_string (&file, time->day[n] ?: "");
iov[2 + cnt].iov_base =
(void *) (time->day[cnt - _NL_ITEM_INDEX (DAY_1)] ?: "");
iov[2 + cnt].iov_len = strlen (iov[2 + cnt].iov_base) + 1;
idx[1 + cnt] = idx[cnt] + iov[2 + cnt].iov_len;
}
/* The ab'mons. */ /* The ab'mons. */
for (; cnt <= _NL_ITEM_INDEX (ABMON_12); ++cnt) for (n = 0; n < 12; ++n)
{ add_locale_string (&file, time->abmon[n] ?: "");
iov[2 + cnt].iov_base =
(void *) (time->abmon[cnt - _NL_ITEM_INDEX (ABMON_1)] ?: "");
iov[2 + cnt].iov_len = strlen (iov[2 + cnt].iov_base) + 1;
idx[1 + cnt] = idx[cnt] + iov[2 + cnt].iov_len;
}
/* The mons. */ /* The mons. */
for (; cnt <= _NL_ITEM_INDEX (MON_12); ++cnt) for (n = 0; n < 12; ++n)
{ add_locale_string (&file, time->mon[n] ?: "");
iov[2 + cnt].iov_base =
(void *) (time->mon[cnt - _NL_ITEM_INDEX (MON_1)] ?: "");
iov[2 + cnt].iov_len = strlen (iov[2 + cnt].iov_base) + 1;
idx[1 + cnt] = idx[cnt] + iov[2 + cnt].iov_len;
}
/* AM/PM. */ /* AM/PM. */
for (; cnt <= _NL_ITEM_INDEX (PM_STR); ++cnt) for (n = 0; n < 2; ++n)
{ add_locale_string (&file, time->am_pm[n]);
iov[2 + cnt].iov_base =
(void *) (time->am_pm[cnt - _NL_ITEM_INDEX (AM_STR)] ?: "");
iov[2 + cnt].iov_len = strlen (iov[2 + cnt].iov_base) + 1;
idx[1 + cnt] = idx[cnt] + iov[2 + cnt].iov_len;
}
iov[2 + cnt].iov_base = (void *) (time->d_t_fmt ?: ""); add_locale_string (&file, time->d_t_fmt ?: "");
iov[2 + cnt].iov_len = strlen (iov[2 + cnt].iov_base) + 1; add_locale_string (&file, time->d_fmt ?: "");
idx[1 + cnt] = idx[cnt] + iov[2 + cnt].iov_len; add_locale_string (&file, time->t_fmt ?: "");
++cnt; add_locale_string (&file, time->t_fmt_ampm ?: "");
iov[2 + cnt].iov_base = (void *) (time->d_fmt ?: ""); start_locale_structure (&file);
iov[2 + cnt].iov_len = strlen (iov[2 + cnt].iov_base) + 1; for (num = 0; num < time->num_era; ++num)
idx[1 + cnt] = idx[cnt] + iov[2 + cnt].iov_len; add_locale_string (&file, time->era[num]);
++cnt; end_locale_structure (&file);
iov[2 + cnt].iov_base = (void *) (time->t_fmt ?: ""); add_locale_string (&file, time->era_year ?: "");
iov[2 + cnt].iov_len = strlen (iov[2 + cnt].iov_base) + 1; add_locale_string (&file, time->era_d_fmt ?: "");
idx[1 + cnt] = idx[cnt] + iov[2 + cnt].iov_len;
++cnt;
iov[2 + cnt].iov_base = (void *) (time->t_fmt_ampm ?: ""); start_locale_structure (&file);
iov[2 + cnt].iov_len = strlen (iov[2 + cnt].iov_base) + 1; for (num = 0; num < 100; ++num)
idx[1 + cnt] = idx[cnt] + iov[2 + cnt].iov_len; add_locale_string (&file, time->alt_digits[num] ?: "");
last_idx = ++cnt; end_locale_structure (&file);
idx[1 + last_idx] = idx[last_idx]; add_locale_string (&file, time->era_d_t_fmt ?: "");
for (num = 0; num < time->num_era; ++num, ++cnt) add_locale_string (&file, time->era_t_fmt ?: "");
{ add_locale_uint32 (&file, time->num_era);
iov[2 + cnt].iov_base = (void *) time->era[num];
iov[2 + cnt].iov_len = strlen (iov[2 + cnt].iov_base) + 1;
idx[1 + last_idx] += iov[2 + cnt].iov_len;
}
++last_idx;
iov[2 + cnt].iov_base = (void *) (time->era_year ?: ""); start_locale_structure (&file);
iov[2 + cnt].iov_len = strlen (iov[2 + cnt].iov_base) + 1;
idx[1 + last_idx] = idx[last_idx] + iov[2 + cnt].iov_len;
++cnt;
++last_idx;
iov[2 + cnt].iov_base = (void *) (time->era_d_fmt ?: "");
iov[2 + cnt].iov_len = strlen (iov[2 + cnt].iov_base) + 1;
idx[1 + last_idx] = idx[last_idx] + iov[2 + cnt].iov_len;
++cnt;
++last_idx;
idx[1 + last_idx] = idx[last_idx];
for (num = 0; num < 100; ++num, ++cnt)
{
iov[2 + cnt].iov_base = (void *) (time->alt_digits[num] ?: "");
iov[2 + cnt].iov_len = strlen (iov[2 + cnt].iov_base) + 1;
idx[1 + last_idx] += iov[2 + cnt].iov_len;
}
++last_idx;
iov[2 + cnt].iov_base = (void *) (time->era_d_t_fmt ?: "");
iov[2 + cnt].iov_len = strlen (iov[2 + cnt].iov_base) + 1;
idx[1 + last_idx] = idx[last_idx] + iov[2 + cnt].iov_len;
++cnt;
++last_idx;
iov[2 + cnt].iov_base = (void *) (time->era_t_fmt ?: "");
iov[2 + cnt].iov_len = strlen (iov[2 + cnt].iov_base) + 1;
idx[1 + last_idx] = idx[last_idx] + iov[2 + cnt].iov_len;
++cnt;
++last_idx;
/* We must align the following data. */
iov[2 + cnt].iov_base = (void *) "\0\0";
iov[2 + cnt].iov_len = ((idx[last_idx] + 3) & ~3) - idx[last_idx];
idx[last_idx] = (idx[last_idx] + 3) & ~3;
++cnt;
/* The `era' data in usable form. */
iov[2 + cnt].iov_base = (void *) &time->num_era;
iov[2 + cnt].iov_len = sizeof (uint32_t);
idx[1 + last_idx] = idx[last_idx] + iov[2 + cnt].iov_len;
++cnt;
++last_idx;
idx[1 + last_idx] = idx[last_idx];
for (num = 0; num < time->num_era; ++num) for (num = 0; num < time->num_era; ++num)
{ {
size_t l, l2; add_locale_uint32 (&file, time->era_entries[num].direction);
add_locale_uint32 (&file, time->era_entries[num].offset);
iov[2 + cnt].iov_base = (void *) &time->era_entries[num].direction; add_locale_uint32 (&file, time->era_entries[num].start_date[0]);
iov[2 + cnt].iov_len = sizeof (int32_t); add_locale_uint32 (&file, time->era_entries[num].start_date[1]);
++cnt; add_locale_uint32 (&file, time->era_entries[num].start_date[2]);
iov[2 + cnt].iov_base = (void *) &time->era_entries[num].offset; add_locale_uint32 (&file, time->era_entries[num].stop_date[0]);
iov[2 + cnt].iov_len = sizeof (int32_t); add_locale_uint32 (&file, time->era_entries[num].stop_date[1]);
++cnt; add_locale_uint32 (&file, time->era_entries[num].stop_date[2]);
iov[2 + cnt].iov_base = (void *) &time->era_entries[num].start_date[0]; add_locale_string (&file, time->era_entries[num].name);
iov[2 + cnt].iov_len = sizeof (int32_t); add_locale_string (&file, time->era_entries[num].format);
++cnt; add_locale_wstring (&file, time->era_entries[num].wname);
iov[2 + cnt].iov_base = (void *) &time->era_entries[num].start_date[1]; add_locale_wstring (&file, time->era_entries[num].wformat);
iov[2 + cnt].iov_len = sizeof (int32_t);
++cnt;
iov[2 + cnt].iov_base = (void *) &time->era_entries[num].start_date[2];
iov[2 + cnt].iov_len = sizeof (int32_t);
++cnt;
iov[2 + cnt].iov_base = (void *) &time->era_entries[num].stop_date[0];
iov[2 + cnt].iov_len = sizeof (int32_t);
++cnt;
iov[2 + cnt].iov_base = (void *) &time->era_entries[num].stop_date[1];
iov[2 + cnt].iov_len = sizeof (int32_t);
++cnt;
iov[2 + cnt].iov_base = (void *) &time->era_entries[num].stop_date[2];
iov[2 + cnt].iov_len = sizeof (int32_t);
++cnt;
l = ((char *) rawmemchr (time->era_entries[num].format, '\0')
- time->era_entries[num].name) + 1;
l2 = (l + 3) & ~3;
iov[2 + cnt].iov_base = alloca (l2);
memset (mempcpy (iov[2 + cnt].iov_base, time->era_entries[num].name, l),
'\0', l2 - l);
iov[2 + cnt].iov_len = l2;
++cnt;
idx[1 + last_idx] += 8 * sizeof (int32_t) + l2;
assert (idx[1 + last_idx] % 4 == 0);
iov[2 + cnt].iov_base = (void *) time->era_entries[num].wname;
iov[2 + cnt].iov_len = ((wcschr ((wchar_t *) time->era_entries[num].wformat, L'\0')
- (wchar_t *) time->era_entries[num].wname + 1)
* sizeof (uint32_t));
idx[1 + last_idx] += iov[2 + cnt].iov_len;
++cnt;
} }
++last_idx; end_locale_structure (&file);
/* The wide character ab'days. */ /* The wide character ab'days. */
for (n = 0; n < 7; ++n, ++cnt, ++last_idx) for (n = 0; n < 7; ++n)
{ add_locale_wstring (&file, time->wabday[n] ?: empty_wstr);
iov[2 + cnt].iov_base =
(void *) (time->wabday[n] ?: empty_wstr);
iov[2 + cnt].iov_len = ((wcslen (iov[2 + cnt].iov_base) + 1)
* sizeof (uint32_t));
idx[1 + last_idx] = idx[last_idx] + iov[2 + cnt].iov_len;
}
/* The wide character days. */ /* The wide character days. */
for (n = 0; n < 7; ++n, ++cnt, ++last_idx) for (n = 0; n < 7; ++n)
{ add_locale_wstring (&file, time->wday[n] ?: empty_wstr);
iov[2 + cnt].iov_base =
(void *) (time->wday[n] ?: empty_wstr);
iov[2 + cnt].iov_len = ((wcslen (iov[2 + cnt].iov_base) + 1)
* sizeof (uint32_t));
idx[1 + last_idx] = idx[last_idx] + iov[2 + cnt].iov_len;
}
/* The wide character ab'mons. */ /* The wide character ab'mons. */
for (n = 0; n < 12; ++n, ++cnt, ++last_idx) for (n = 0; n < 12; ++n)
{ add_locale_wstring (&file, time->wabmon[n] ?: empty_wstr);
iov[2 + cnt].iov_base =
(void *) (time->wabmon[n] ?: empty_wstr);
iov[2 + cnt].iov_len = ((wcslen (iov[2 + cnt].iov_base) + 1)
* sizeof (uint32_t));
idx[1 + last_idx] = idx[last_idx] + iov[2 + cnt].iov_len;
}
/* The wide character mons. */ /* The wide character mons. */
for (n = 0; n < 12; ++n, ++cnt, ++last_idx) for (n = 0; n < 12; ++n)
{ add_locale_wstring (&file, time->wmon[n] ?: empty_wstr);
iov[2 + cnt].iov_base =
(void *) (time->wmon[n] ?: empty_wstr);
iov[2 + cnt].iov_len = ((wcslen (iov[2 + cnt].iov_base) + 1)
* sizeof (uint32_t));
idx[1 + last_idx] = idx[last_idx] + iov[2 + cnt].iov_len;
}
/* Wide character AM/PM. */ /* Wide character AM/PM. */
for (n = 0; n < 2; ++n, ++cnt, ++last_idx) for (n = 0; n < 2; ++n)
{ add_locale_wstring (&file, time->wam_pm[n] ?: empty_wstr);
iov[2 + cnt].iov_base =
(void *) (time->wam_pm[n] ?: empty_wstr);
iov[2 + cnt].iov_len = ((wcslen (iov[2 + cnt].iov_base) + 1)
* sizeof (uint32_t));
idx[1 + last_idx] = idx[last_idx] + iov[2 + cnt].iov_len;
}
iov[2 + cnt].iov_base = (void *) (time->wd_t_fmt ?: empty_wstr); add_locale_wstring (&file, time->wd_t_fmt ?: empty_wstr);
iov[2 + cnt].iov_len = ((wcslen (iov[2 + cnt].iov_base) + 1) add_locale_wstring (&file, time->wd_fmt ?: empty_wstr);
* sizeof (uint32_t)); add_locale_wstring (&file, time->wt_fmt ?: empty_wstr);
idx[1 + last_idx] = idx[last_idx] + iov[2 + cnt].iov_len; add_locale_wstring (&file, time->wt_fmt_ampm ?: empty_wstr);
++cnt; add_locale_wstring (&file, time->wera_year ?: empty_wstr);
++last_idx; add_locale_wstring (&file, time->wera_d_fmt ?: empty_wstr);
iov[2 + cnt].iov_base = (void *) (time->wd_fmt ?: empty_wstr); start_locale_structure (&file);
iov[2 + cnt].iov_len = ((wcslen (iov[2 + cnt].iov_base) + 1) for (num = 0; num < 100; ++num)
* sizeof (uint32_t)); add_locale_wstring (&file, time->walt_digits[num] ?: empty_wstr);
idx[1 + last_idx] = idx[last_idx] + iov[2 + cnt].iov_len; end_locale_structure (&file);
++cnt;
++last_idx;
iov[2 + cnt].iov_base = (void *) (time->wt_fmt ?: empty_wstr); add_locale_wstring (&file, time->wera_d_t_fmt ?: empty_wstr);
iov[2 + cnt].iov_len = ((wcslen (iov[2 + cnt].iov_base) + 1) add_locale_wstring (&file, time->wera_t_fmt ?: empty_wstr);
* sizeof (uint32_t)); add_locale_char (&file, time->week_ndays);
idx[1 + last_idx] = idx[last_idx] + iov[2 + cnt].iov_len; add_locale_uint32 (&file, time->week_1stday);
++cnt; add_locale_char (&file, time->week_1stweek);
++last_idx; add_locale_char (&file, time->first_weekday);
add_locale_char (&file, time->first_workday);
iov[2 + cnt].iov_base = (void *) (time->wt_fmt_ampm ?: empty_wstr); add_locale_char (&file, time->cal_direction);
iov[2 + cnt].iov_len = ((wcslen (iov[2 + cnt].iov_base) + 1) add_locale_string (&file, time->timezone);
* sizeof (uint32_t)); add_locale_string (&file, time->date_fmt);
idx[1 + last_idx] = idx[last_idx] + iov[2 + cnt].iov_len; add_locale_wstring (&file, time->wdate_fmt);
++cnt; add_locale_string (&file, charmap->code_set_name);
++last_idx; write_locale_data (output_path, LC_TIME, "LC_TIME", &file);
iov[2 + cnt].iov_base = (void *) (time->wera_year ?: empty_wstr);
iov[2 + cnt].iov_len = ((wcslen (iov[2 + cnt].iov_base) + 1)
* sizeof (uint32_t));
idx[1 + last_idx] = idx[last_idx] + iov[2 + cnt].iov_len;
++cnt;
++last_idx;
iov[2 + cnt].iov_base = (void *) (time->wera_d_fmt ?: empty_wstr);
iov[2 + cnt].iov_len = ((wcslen (iov[2 + cnt].iov_base) + 1)
* sizeof (uint32_t));
idx[1 + last_idx] = idx[last_idx] + iov[2 + cnt].iov_len;
++cnt;
++last_idx;
idx[1 + last_idx] = idx[last_idx];
for (num = 0; num < 100; ++num, ++cnt)
{
iov[2 + cnt].iov_base = (void *) (time->walt_digits[num]
?: empty_wstr);
iov[2 + cnt].iov_len = ((wcslen (iov[2 + cnt].iov_base) + 1)
* sizeof (uint32_t));
idx[1 + last_idx] += iov[2 + cnt].iov_len;
}
++last_idx;
iov[2 + cnt].iov_base = (void *) (time->wera_d_t_fmt ?: empty_wstr);
iov[2 + cnt].iov_len = ((wcslen (iov[2 + cnt].iov_base) + 1)
* sizeof (uint32_t));
idx[1 + last_idx] = idx[last_idx] + iov[2 + cnt].iov_len;
++cnt;
++last_idx;
iov[2 + cnt].iov_base = (void *) (time->wera_t_fmt ?: empty_wstr);
iov[2 + cnt].iov_len = ((wcslen (iov[2 + cnt].iov_base) + 1)
* sizeof (uint32_t));
idx[1 + last_idx] = idx[last_idx] + iov[2 + cnt].iov_len;
++cnt;
++last_idx;
iov[2 + cnt].iov_base = (void *) &time->week_ndays;
iov[2 + cnt].iov_len = 1;
idx[1 + last_idx] = idx[last_idx] + iov[2 + cnt].iov_len;
++cnt;
++last_idx;
/* We must align the following data. */
iov[2 + cnt].iov_base = (void *) "\0\0";
iov[2 + cnt].iov_len = ((idx[last_idx] + 3) & ~3) - idx[last_idx];
idx[last_idx] = (idx[last_idx] + 3) & ~3;
++cnt;
iov[2 + cnt].iov_base = (void *) &time->week_1stday;
iov[2 + cnt].iov_len = sizeof(uint32_t);
idx[1 + last_idx] = idx[last_idx] + iov[2 + cnt].iov_len;
++cnt;
++last_idx;
iov[2 + cnt].iov_base = (void *) &time->week_1stweek;
iov[2 + cnt].iov_len = 1;
idx[1 + last_idx] = idx[last_idx] + iov[2 + cnt].iov_len;
++cnt;
++last_idx;
iov[2 + cnt].iov_base = (void *) &time->first_weekday;
iov[2 + cnt].iov_len = 1;
idx[1 + last_idx] = idx[last_idx] + iov[2 + cnt].iov_len;
++cnt;
++last_idx;
iov[2 + cnt].iov_base = (void *) &time->first_workday;
iov[2 + cnt].iov_len = 1;
idx[1 + last_idx] = idx[last_idx] + iov[2 + cnt].iov_len;
++cnt;
++last_idx;
iov[2 + cnt].iov_base = (void *) &time->cal_direction;
iov[2 + cnt].iov_len = 1;
idx[1 + last_idx] = idx[last_idx] + iov[2 + cnt].iov_len;
++cnt;
++last_idx;
iov[2 + cnt].iov_base = (void *) time->timezone;
iov[2 + cnt].iov_len = strlen (time->timezone) + 1;
idx[1 + last_idx] = idx[last_idx] + iov[2 + cnt].iov_len;
++cnt;
++last_idx;
iov[2 + cnt].iov_base = (void *) time->date_fmt;
iov[2 + cnt].iov_len = strlen (iov[2 + cnt].iov_base) + 1;
idx[1 + last_idx] = idx[last_idx] + iov[2 + cnt].iov_len;
++cnt;
++last_idx;
/* We must align the following data. */
iov[2 + cnt].iov_base = (void *) "\0\0";
iov[2 + cnt].iov_len = -idx[last_idx] & 3;
idx[last_idx] += -idx[last_idx] & 3;
++cnt;
iov[2 + cnt].iov_base = (void *) time->wdate_fmt;
iov[2 + cnt].iov_len = ((wcslen (iov[2 + cnt].iov_base) + 1)
* sizeof (uint32_t));
idx[1 + last_idx] = idx[last_idx] + iov[2 + cnt].iov_len;
++cnt;
++last_idx;
iov[2 + cnt].iov_base = (void *) charmap->code_set_name;
iov[2 + cnt].iov_len = strlen (iov[2 + cnt].iov_base) + 1;
++cnt;
++last_idx;
assert (cnt == (_NL_ITEM_INDEX (_NL_NUM_LC_TIME)
+ time->num_era - 1
+ 2 * 99
+ 2 + time->num_era * 10));
assert (last_idx == _NL_ITEM_INDEX (_NL_NUM_LC_TIME));
write_locale_data (output_path, LC_TIME, "LC_TIME", 2 + cnt, iov);
} }

View File

@ -27,14 +27,19 @@
#include <unistd.h> #include <unistd.h>
#include <sys/param.h> #include <sys/param.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <assert.h>
#include <wchar.h>
#include "../../crypt/md5.h" #include "../../crypt/md5.h"
#include "localedef.h" #include "localedef.h"
#include "localeinfo.h"
#include "locfile.h" #include "locfile.h"
#include "simple-hash.h" #include "simple-hash.h"
#include "locfile-kw.h" #include "locfile-kw.h"
#define obstack_chunk_alloc xmalloc
#define obstack_chunk_free free
/* Temporary storage of the locale data before writing it to the archive. */ /* Temporary storage of the locale data before writing it to the archive. */
static locale_data_t to_archive; static locale_data_t to_archive;
@ -533,17 +538,177 @@ compare_files (const char *filename1, const char *filename2, size_t size,
return ret; return ret;
} }
/* When called outside a start_locale_structure/end_locale_structure
or start_locale_prelude/end_locale_prelude block, record that the
next byte in FILE's obstack will be the first byte of a new element.
Do likewise for the first call inside a start_locale_structure/
end_locale_structure block. */
static void
record_offset (struct locale_file *file)
{
if (file->structure_stage < 2)
{
assert (file->next_element < file->n_elements);
file->offsets[file->next_element++]
= (obstack_object_size (&file->data)
+ (file->n_elements + 2) * sizeof (uint32_t));
if (file->structure_stage == 1)
file->structure_stage = 2;
}
}
/* Write a locale file, with contents given by N_ELEM and VEC. */ /* Initialize FILE for a new output file. N_ELEMENTS is the number
of elements in the file. */
void
init_locale_data (struct locale_file *file, size_t n_elements)
{
file->n_elements = n_elements;
file->next_element = 0;
file->offsets = xmalloc (sizeof (uint32_t) * n_elements);
obstack_init (&file->data);
file->structure_stage = 0;
}
/* Align the size of FILE's obstack object to BOUNDARY bytes. */
void
align_locale_data (struct locale_file *file, size_t boundary)
{
size_t size = -obstack_object_size (&file->data) & (boundary - 1);
obstack_blank (&file->data, size);
memset (obstack_next_free (&file->data) - size, 0, size);
}
/* Record that FILE's next element contains no data. */
void
add_locale_empty (struct locale_file *file)
{
record_offset (file);
}
/* Record that FILE's next element consists of SIZE bytes starting at DATA. */
void
add_locale_raw_data (struct locale_file *file, const void *data, size_t size)
{
record_offset (file);
obstack_grow (&file->data, data, size);
}
/* Finish the current object on OBSTACK and use it as the data for FILE's
next element. */
void
add_locale_raw_obstack (struct locale_file *file, struct obstack *obstack)
{
size_t size = obstack_object_size (obstack);
record_offset (file);
obstack_grow (&file->data, obstack_finish (obstack), size);
}
/* Use STRING as FILE's next element. */
void
add_locale_string (struct locale_file *file, const char *string)
{
record_offset (file);
obstack_grow (&file->data, string, strlen (string) + 1);
}
/* Likewise for wide strings. */
void
add_locale_wstring (struct locale_file *file, const uint32_t *string)
{
add_locale_uint32_array (file, string, wcslen ((const wchar_t *) string) + 1);
}
/* Record that FILE's next element is the 32-bit integer VALUE. */
void
add_locale_uint32 (struct locale_file *file, uint32_t value)
{
align_locale_data (file, sizeof (uint32_t));
record_offset (file);
obstack_grow (&file->data, &value, sizeof (value));
}
/* Record that FILE's next element is an array of N_ELEMS integers
starting at DATA. */
void
add_locale_uint32_array (struct locale_file *file,
const uint32_t *data, size_t n_elems)
{
align_locale_data (file, sizeof (uint32_t));
record_offset (file);
obstack_grow (&file->data, data, n_elems * sizeof (uint32_t));
}
/* Record that FILE's next element is the single byte given by VALUE. */
void
add_locale_char (struct locale_file *file, char value)
{
record_offset (file);
obstack_1grow (&file->data, value);
}
/* Start building an element that contains several different pieces of data.
Subsequent calls to add_locale_* will add data to the same element up
till the next call to end_locale_structure. The element's alignment
is dictated by the first piece of data added to it. */
void
start_locale_structure (struct locale_file *file)
{
assert (file->structure_stage == 0);
file->structure_stage = 1;
}
/* Finish a structure element that was started by start_locale_structure.
Empty structures are OK and behave like add_locale_empty. */
void
end_locale_structure (struct locale_file *file)
{
record_offset (file);
assert (file->structure_stage == 2);
file->structure_stage = 0;
}
/* Start building data that goes before the next element's recorded offset.
Subsequent calls to add_locale_* will add data to the file without
treating any of it as the start of a new element. Calling
end_locale_prelude switches back to the usual behavior. */
void
start_locale_prelude (struct locale_file *file)
{
assert (file->structure_stage == 0);
file->structure_stage = 3;
}
/* End a block started by start_locale_prelude. */
void
end_locale_prelude (struct locale_file *file)
{
assert (file->structure_stage == 3);
file->structure_stage = 0;
}
/* Write a locale file, with contents given by FILE. */
void void
write_locale_data (const char *output_path, int catidx, const char *category, write_locale_data (const char *output_path, int catidx, const char *category,
size_t n_elem, struct iovec *vec) struct locale_file *file)
{ {
size_t cnt, step, maxiov; size_t cnt, step, maxiov;
int fd; int fd;
char *fname; char *fname;
const char **other_paths; const char **other_paths;
uint32_t header[2];
size_t n_elem;
struct iovec vec[3];
assert (file->n_elements == file->next_element);
header[0] = LIMAGIC (catidx);
header[1] = file->n_elements;
vec[0].iov_len = sizeof (header);
vec[0].iov_base = header;
vec[1].iov_len = sizeof (uint32_t) * file->n_elements;
vec[1].iov_base = file->offsets;
vec[2].iov_len = obstack_object_size (&file->data);
vec[2].iov_base = obstack_finish (&file->data);
n_elem = 3;
if (! no_archive) if (! no_archive)
{ {
/* The data will be added to the archive. For now we simply /* The data will be added to the archive. For now we simply

View File

@ -21,15 +21,17 @@
#include <stdint.h> #include <stdint.h>
#include <sys/uio.h> #include <sys/uio.h>
#include "obstack.h"
#include "linereader.h" #include "linereader.h"
#include "localedef.h" #include "localedef.h"
/* Structure for storing the contents of a category file. */
/* Header of the locale data files. */
struct locale_file struct locale_file
{ {
int magic; size_t n_elements, next_element;
int n; uint32_t *offsets;
struct obstack data;
int structure_stage;
}; };
@ -66,9 +68,26 @@ extern void write_all_categories (struct localedef_t *definitions,
const char *output_path); const char *output_path);
/* Write out the data. */ /* Write out the data. */
extern void init_locale_data (struct locale_file *file, size_t n_elements);
extern void align_locale_data (struct locale_file *file, size_t boundary);
extern void add_locale_empty (struct locale_file *file);
extern void add_locale_raw_data (struct locale_file *file, const void *data,
size_t size);
extern void add_locale_raw_obstack (struct locale_file *file,
struct obstack *obstack);
extern void add_locale_string (struct locale_file *file, const char *string);
extern void add_locale_wstring (struct locale_file *file,
const uint32_t *string);
extern void add_locale_uint32 (struct locale_file *file, uint32_t value);
extern void add_locale_uint32_array (struct locale_file *file,
const uint32_t *data, size_t n_elems);
extern void add_locale_char (struct locale_file *file, char value);
extern void start_locale_structure (struct locale_file *file);
extern void end_locale_structure (struct locale_file *file);
extern void start_locale_prelude (struct locale_file *file);
extern void end_locale_prelude (struct locale_file *file);
extern void write_locale_data (const char *output_path, int catidx, extern void write_locale_data (const char *output_path, int catidx,
const char *category, size_t n_elem, const char *category, struct locale_file *file);
struct iovec *vec);
/* Entrypoints for the parsers of the individual categories. */ /* Entrypoints for the parsers of the individual categories. */