mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-21 12:30:06 +00:00
Add localedef --big-endian and --little-endian options.
This commit is contained in:
parent
39bf0bb44c
commit
6055173a0f
39
ChangeLog
39
ChangeLog
@ -1,3 +1,42 @@
|
||||
2013-09-24 Joseph Myers <joseph@codesourcery.com>
|
||||
Richard Sandiford <richard@codesourcery.com>
|
||||
|
||||
* locale/programs/locfile.h: Include <byteswap.h> and <stdbool.h>.
|
||||
(swap_endianness_p): New extern variable.
|
||||
(set_big_endian): New inline function.
|
||||
(maybe_swap_uint32): Likewise.
|
||||
(maybe_swap_uint32_array): Likewise.
|
||||
(maybe_swap_uint32_obstack): Likewise.
|
||||
* locale/programs/locfile.c: Include <stdbool.h>.
|
||||
(swap_endianness_p): New variable.
|
||||
(add_locale_uint32): Call maybe_swap_uint32.
|
||||
(add_locale_uint32_array): Call maybe_swap_uint32_obstack.
|
||||
(write_locale_data): Call maybe_swap_uint32_array.
|
||||
* locale/programs/ld-collate.c (obstack_int32_grow): Call
|
||||
maybe_swap_uint32.
|
||||
(obstack_int32_grow_fast): Likewise.
|
||||
(output_weightwc): Call maybe_swap_uint32_obstack.
|
||||
(collate_output): Likewise.
|
||||
* locale/programs/localedef.c (OPT_LITTLE_ENDIAN): New macro.
|
||||
(OPT_LITTLE_ENDIAN): Likewise.
|
||||
(options): Add --little-endian and --big-endian options.
|
||||
(parse_opt): Handle OPT_LITTLE_ENDIAN and OPT_BIG_ENDIAN.
|
||||
* locale/programs/locarchive.c: Include "locfile.h".
|
||||
(GET): New macro.
|
||||
(SET): Likewise.
|
||||
(INC): Likewise.
|
||||
(create_archive): Use the new macros to access fields of
|
||||
structures directly mapped from or written to locale archives.
|
||||
(oldlocrecentcmp): Likewise.
|
||||
(enlarge_archive): Likewise.
|
||||
(insert_name): Likewise.
|
||||
(add_alias): Likewise.
|
||||
(add_locale): Likewise.
|
||||
(delete_locales_from_archive): Likewise.
|
||||
(show_archive_content): Likewise.
|
||||
(add_locale_to_archive): Likewise. Use maybe_swap_uint32 on
|
||||
locale data.
|
||||
|
||||
2013-09-24 Roland McGrath <roland@hack.frob.com>
|
||||
|
||||
* manual/freemanuals.texi: Updated from (newly) canonical copy at
|
||||
|
4
NEWS
4
NEWS
@ -48,6 +48,10 @@ Version 2.19
|
||||
|
||||
* ISO 1427 definitions were updated.
|
||||
|
||||
* The localedef utility now supports --big-endian and --little-endian
|
||||
command-line options to generate locales for a different system from that
|
||||
for which the C library was built.
|
||||
|
||||
* The configure option --disable-versioning has been removed. Builds with
|
||||
--disable-versioning had not worked for several years.
|
||||
|
||||
|
@ -44,6 +44,7 @@ static inline void
|
||||
__attribute ((always_inline))
|
||||
obstack_int32_grow (struct obstack *obstack, int32_t data)
|
||||
{
|
||||
data = maybe_swap_uint32 (data);
|
||||
if (sizeof (int32_t) == sizeof (int))
|
||||
obstack_int_grow (obstack, data);
|
||||
else
|
||||
@ -54,6 +55,7 @@ static inline void
|
||||
__attribute ((always_inline))
|
||||
obstack_int32_grow_fast (struct obstack *obstack, int32_t data)
|
||||
{
|
||||
data = maybe_swap_uint32 (data);
|
||||
if (sizeof (int32_t) == sizeof (int))
|
||||
obstack_int_grow_fast (obstack, data);
|
||||
else
|
||||
@ -1955,6 +1957,7 @@ output_weightwc (struct obstack *pool, struct locale_collate_t *collate,
|
||||
obstack_int32_grow (pool, j);
|
||||
|
||||
obstack_grow (pool, buf, j * sizeof (int32_t));
|
||||
maybe_swap_uint32_obstack (pool, j);
|
||||
}
|
||||
|
||||
return retval | ((elem->section->ruleidx & 0x7f) << 24);
|
||||
@ -2479,6 +2482,7 @@ collate_output (struct localedef_t *locale, const struct charmap_t *charmap,
|
||||
obstack_int32_grow (&extrapool, runp->nwcs);
|
||||
obstack_grow (&extrapool, runp->wcs,
|
||||
runp->nwcs * sizeof (uint32_t));
|
||||
maybe_swap_uint32_obstack (&extrapool, runp->nwcs);
|
||||
|
||||
obstack_int32_grow (&extrapool, runp->wcseqorder);
|
||||
}
|
||||
|
@ -112,6 +112,8 @@ void (*argp_program_version_hook) (FILE *, struct argp_state *) = print_version;
|
||||
#define OPT_REPLACE 307
|
||||
#define OPT_DELETE_FROM_ARCHIVE 308
|
||||
#define OPT_LIST_ARCHIVE 309
|
||||
#define OPT_LITTLE_ENDIAN 400
|
||||
#define OPT_BIG_ENDIAN 401
|
||||
|
||||
/* Definitions of arguments for argp functions. */
|
||||
static const struct argp_option options[] =
|
||||
@ -144,6 +146,10 @@ static const struct argp_option options[] =
|
||||
{ "list-archive", OPT_LIST_ARCHIVE, NULL, 0, N_("List content of archive") },
|
||||
{ "alias-file", 'A', N_("FILE"), 0,
|
||||
N_("locale.alias file to consult when making archive")},
|
||||
{ "little-endian", OPT_LITTLE_ENDIAN, NULL, 0,
|
||||
N_("Generate little-endian output") },
|
||||
{ "big-endian", OPT_BIG_ENDIAN, NULL, 0,
|
||||
N_("Generate big-endian output") },
|
||||
{ NULL, 0, NULL, 0, NULL }
|
||||
};
|
||||
|
||||
@ -326,6 +332,12 @@ parse_opt (int key, char *arg, struct argp_state *state)
|
||||
case OPT_LIST_ARCHIVE:
|
||||
list_archive = true;
|
||||
break;
|
||||
case OPT_LITTLE_ENDIAN:
|
||||
set_big_endian (false);
|
||||
break;
|
||||
case OPT_BIG_ENDIAN:
|
||||
set_big_endian (true);
|
||||
break;
|
||||
case 'c':
|
||||
force_output = 1;
|
||||
break;
|
||||
|
@ -46,6 +46,7 @@
|
||||
#include "../localeinfo.h"
|
||||
#include "../locarchive.h"
|
||||
#include "localedef.h"
|
||||
#include "locfile.h"
|
||||
|
||||
/* Define the hash function. We define the function as static inline.
|
||||
We must change the name so as not to conflict with simple-hash.h. */
|
||||
@ -74,6 +75,13 @@ static const char *locnames[] =
|
||||
#define INITIAL_NUM_SUMS 2000
|
||||
|
||||
|
||||
/* Get and set values (possibly endian-swapped) in structures mapped
|
||||
from or written directly to locale archives. */
|
||||
#define GET(FIELD) maybe_swap_uint32 (FIELD)
|
||||
#define SET(FIELD, VALUE) ((FIELD) = maybe_swap_uint32 (VALUE))
|
||||
#define INC(FIELD, INCREMENT) SET (FIELD, GET (FIELD) + (INCREMENT))
|
||||
|
||||
|
||||
/* Size of the reserved address space area. */
|
||||
#define RESERVE_MMAP_SIZE 512 * 1024 * 1024
|
||||
|
||||
@ -125,27 +133,31 @@ create_archive (const char *archivefname, struct locarhandle *ah)
|
||||
error (EXIT_FAILURE, errno, _("cannot create temporary file: %s"), fname);
|
||||
|
||||
/* Create the initial content of the archive. */
|
||||
head.magic = AR_MAGIC;
|
||||
head.serial = 0;
|
||||
head.namehash_offset = sizeof (struct locarhead);
|
||||
head.namehash_used = 0;
|
||||
head.namehash_size = next_prime (INITIAL_NUM_NAMES);
|
||||
SET (head.magic, AR_MAGIC);
|
||||
SET (head.serial, 0);
|
||||
SET (head.namehash_offset, sizeof (struct locarhead));
|
||||
SET (head.namehash_used, 0);
|
||||
SET (head.namehash_size, next_prime (INITIAL_NUM_NAMES));
|
||||
|
||||
head.string_offset = (head.namehash_offset
|
||||
+ head.namehash_size * sizeof (struct namehashent));
|
||||
head.string_used = 0;
|
||||
head.string_size = INITIAL_SIZE_STRINGS;
|
||||
SET (head.string_offset,
|
||||
(GET (head.namehash_offset)
|
||||
+ GET (head.namehash_size) * sizeof (struct namehashent)));
|
||||
SET (head.string_used, 0);
|
||||
SET (head.string_size, INITIAL_SIZE_STRINGS);
|
||||
|
||||
head.locrectab_offset = head.string_offset + head.string_size;
|
||||
head.locrectab_used = 0;
|
||||
head.locrectab_size = INITIAL_NUM_LOCREC;
|
||||
SET (head.locrectab_offset,
|
||||
GET (head.string_offset) + GET (head.string_size));
|
||||
SET (head.locrectab_used, 0);
|
||||
SET (head.locrectab_size, INITIAL_NUM_LOCREC);
|
||||
|
||||
head.sumhash_offset = (head.locrectab_offset
|
||||
+ head.locrectab_size * sizeof (struct locrecent));
|
||||
head.sumhash_used = 0;
|
||||
head.sumhash_size = next_prime (INITIAL_NUM_SUMS);
|
||||
SET (head.sumhash_offset,
|
||||
(GET (head.locrectab_offset)
|
||||
+ GET (head.locrectab_size) * sizeof (struct locrecent)));
|
||||
SET (head.sumhash_used, 0);
|
||||
SET (head.sumhash_size, next_prime (INITIAL_NUM_SUMS));
|
||||
|
||||
total = head.sumhash_offset + head.sumhash_size * sizeof (struct sumhashent);
|
||||
total = (GET (head.sumhash_offset)
|
||||
+ GET (head.sumhash_size) * sizeof (struct sumhashent));
|
||||
|
||||
/* Write out the header and create room for the other data structures. */
|
||||
if (TEMP_FAILURE_RETRY (write (fd, &head, sizeof (head))) != sizeof (head))
|
||||
@ -240,10 +252,10 @@ oldlocrecentcmp (const void *a, const void *b)
|
||||
for (cnt = 0; cnt < __LC_LAST; ++cnt)
|
||||
if (cnt != LC_ALL)
|
||||
{
|
||||
if (la->record[cnt].offset < start_a)
|
||||
start_a = la->record[cnt].offset;
|
||||
if (la->record[cnt].offset + la->record[cnt].len > end_a)
|
||||
end_a = la->record[cnt].offset + la->record[cnt].len;
|
||||
if (GET (la->record[cnt].offset) < start_a)
|
||||
start_a = GET (la->record[cnt].offset);
|
||||
if (GET (la->record[cnt].offset) + GET (la->record[cnt].len) > end_a)
|
||||
end_a = GET (la->record[cnt].offset) + GET (la->record[cnt].len);
|
||||
}
|
||||
assert (start_a != (uint32_t)-1);
|
||||
assert (end_a != 0);
|
||||
@ -251,10 +263,10 @@ oldlocrecentcmp (const void *a, const void *b)
|
||||
for (cnt = 0; cnt < __LC_LAST; ++cnt)
|
||||
if (cnt != LC_ALL)
|
||||
{
|
||||
if (lb->record[cnt].offset < start_b)
|
||||
start_b = lb->record[cnt].offset;
|
||||
if (lb->record[cnt].offset + lb->record[cnt].len > end_b)
|
||||
end_b = lb->record[cnt].offset + lb->record[cnt].len;
|
||||
if (GET (lb->record[cnt].offset) < start_b)
|
||||
start_b = GET (lb->record[cnt].offset);
|
||||
if (GET (lb->record[cnt].offset) + GET (lb->record[cnt].len) > end_b)
|
||||
end_b = GET (lb->record[cnt].offset) + GET (lb->record[cnt].len);
|
||||
}
|
||||
assert (start_b != (uint32_t)-1);
|
||||
assert (end_b != 0);
|
||||
@ -371,38 +383,42 @@ enlarge_archive (struct locarhandle *ah, const struct locarhead *head)
|
||||
|
||||
/* Create the new archive header. The sizes of the various tables
|
||||
should be double from what is currently used. */
|
||||
newhead.namehash_size = MAX (next_prime (2 * newhead.namehash_used),
|
||||
newhead.namehash_size);
|
||||
SET (newhead.namehash_size,
|
||||
MAX (next_prime (2 * GET (newhead.namehash_used)),
|
||||
GET (newhead.namehash_size)));
|
||||
if (verbose)
|
||||
printf ("name: size: %u, used: %d, new: size: %u\n",
|
||||
head->namehash_size, head->namehash_used, newhead.namehash_size);
|
||||
GET (head->namehash_size),
|
||||
GET (head->namehash_used), GET (newhead.namehash_size));
|
||||
|
||||
newhead.string_offset = (newhead.namehash_offset
|
||||
+ (newhead.namehash_size
|
||||
* sizeof (struct namehashent)));
|
||||
SET (newhead.string_offset, (GET (newhead.namehash_offset)
|
||||
+ (GET (newhead.namehash_size)
|
||||
* sizeof (struct namehashent))));
|
||||
/* Keep the string table size aligned to 4 bytes, so that
|
||||
all the struct { uint32_t } types following are happy. */
|
||||
newhead.string_size = MAX ((2 * newhead.string_used + 3) & -4,
|
||||
newhead.string_size);
|
||||
SET (newhead.string_size, MAX ((2 * GET (newhead.string_used) + 3) & -4,
|
||||
GET (newhead.string_size)));
|
||||
|
||||
newhead.locrectab_offset = newhead.string_offset + newhead.string_size;
|
||||
newhead.locrectab_size = MAX (2 * newhead.locrectab_used,
|
||||
newhead.locrectab_size);
|
||||
SET (newhead.locrectab_offset,
|
||||
GET (newhead.string_offset) + GET (newhead.string_size));
|
||||
SET (newhead.locrectab_size, MAX (2 * GET (newhead.locrectab_used),
|
||||
GET (newhead.locrectab_size)));
|
||||
|
||||
newhead.sumhash_offset = (newhead.locrectab_offset
|
||||
+ (newhead.locrectab_size
|
||||
* sizeof (struct locrecent)));
|
||||
newhead.sumhash_size = MAX (next_prime (2 * newhead.sumhash_used),
|
||||
newhead.sumhash_size);
|
||||
SET (newhead.sumhash_offset, (GET (newhead.locrectab_offset)
|
||||
+ (GET (newhead.locrectab_size)
|
||||
* sizeof (struct locrecent))));
|
||||
SET (newhead.sumhash_size,
|
||||
MAX (next_prime (2 * GET (newhead.sumhash_used)),
|
||||
GET (newhead.sumhash_size)));
|
||||
|
||||
total = (newhead.sumhash_offset
|
||||
+ newhead.sumhash_size * sizeof (struct sumhashent));
|
||||
total = (GET (newhead.sumhash_offset)
|
||||
+ GET (newhead.sumhash_size) * sizeof (struct sumhashent));
|
||||
|
||||
/* The new file is empty now. */
|
||||
newhead.namehash_used = 0;
|
||||
newhead.string_used = 0;
|
||||
newhead.locrectab_used = 0;
|
||||
newhead.sumhash_used = 0;
|
||||
SET (newhead.namehash_used, 0);
|
||||
SET (newhead.string_used, 0);
|
||||
SET (newhead.locrectab_used, 0);
|
||||
SET (newhead.sumhash_used, 0);
|
||||
|
||||
/* Write out the header and create room for the other data structures. */
|
||||
if (TEMP_FAILURE_RETRY (write (fd, &newhead, sizeof (newhead)))
|
||||
@ -453,17 +469,17 @@ enlarge_archive (struct locarhandle *ah, const struct locarhead *head)
|
||||
/* Walk through the hash name hash table to find out what data is
|
||||
still referenced and transfer it into the new file. */
|
||||
oldnamehashtab = (struct namehashent *) ((char *) ah->addr
|
||||
+ head->namehash_offset);
|
||||
+ GET (head->namehash_offset));
|
||||
|
||||
/* Sort the old locrec table in order of data position. */
|
||||
struct oldlocrecent oldlocrecarray[head->namehash_size];
|
||||
for (cnt = 0, loccnt = 0; cnt < head->namehash_size; ++cnt)
|
||||
if (oldnamehashtab[cnt].locrec_offset != 0)
|
||||
struct oldlocrecent oldlocrecarray[GET (head->namehash_size)];
|
||||
for (cnt = 0, loccnt = 0; cnt < GET (head->namehash_size); ++cnt)
|
||||
if (GET (oldnamehashtab[cnt].locrec_offset) != 0)
|
||||
{
|
||||
oldlocrecarray[loccnt].cnt = cnt;
|
||||
oldlocrecarray[loccnt++].locrec
|
||||
= (struct locrecent *) ((char *) ah->addr
|
||||
+ oldnamehashtab[cnt].locrec_offset);
|
||||
+ GET (oldnamehashtab[cnt].locrec_offset));
|
||||
}
|
||||
qsort (oldlocrecarray, loccnt, sizeof (struct oldlocrecent),
|
||||
oldlocrecentcmp);
|
||||
@ -479,9 +495,9 @@ enlarge_archive (struct locarhandle *ah, const struct locarhead *head)
|
||||
for (idx = 0; idx < __LC_LAST; ++idx)
|
||||
if (idx != LC_ALL)
|
||||
{
|
||||
old_data[idx].size = oldlocrec->record[idx].len;
|
||||
old_data[idx].size = GET (oldlocrec->record[idx].len);
|
||||
old_data[idx].addr
|
||||
= ((char *) ah->addr + oldlocrec->record[idx].offset);
|
||||
= ((char *) ah->addr + GET (oldlocrec->record[idx].offset));
|
||||
|
||||
__md5_buffer (old_data[idx].addr, old_data[idx].size,
|
||||
old_data[idx].sum);
|
||||
@ -491,20 +507,23 @@ enlarge_archive (struct locarhandle *ah, const struct locarhead *head)
|
||||
{
|
||||
const char *oldname
|
||||
= ((char *) ah->addr
|
||||
+ oldnamehashtab[oldlocrecarray[cnt - 1].cnt].name_offset);
|
||||
+ GET (oldnamehashtab[oldlocrecarray[cnt
|
||||
- 1].cnt].name_offset));
|
||||
|
||||
add_alias (&new_ah,
|
||||
((char *) ah->addr
|
||||
+ oldnamehashtab[oldlocrecarray[cnt].cnt].name_offset),
|
||||
0, oldname, &last_locrec_offset);
|
||||
add_alias
|
||||
(&new_ah,
|
||||
((char *) ah->addr
|
||||
+ GET (oldnamehashtab[oldlocrecarray[cnt].cnt].name_offset)),
|
||||
0, oldname, &last_locrec_offset);
|
||||
continue;
|
||||
}
|
||||
|
||||
last_locrec_offset =
|
||||
add_locale (&new_ah,
|
||||
((char *) ah->addr
|
||||
+ oldnamehashtab[oldlocrecarray[cnt].cnt].name_offset),
|
||||
old_data, 0);
|
||||
add_locale
|
||||
(&new_ah,
|
||||
((char *) ah->addr
|
||||
+ GET (oldnamehashtab[oldlocrecarray[cnt].cnt].name_offset)),
|
||||
old_data, 0);
|
||||
if (last_locrec_offset == 0)
|
||||
error (EXIT_FAILURE, 0, _("cannot extend locale archive file"));
|
||||
}
|
||||
@ -672,26 +691,28 @@ insert_name (struct locarhandle *ah,
|
||||
{
|
||||
const struct locarhead *const head = ah->addr;
|
||||
struct namehashent *namehashtab
|
||||
= (struct namehashent *) ((char *) ah->addr + head->namehash_offset);
|
||||
= (struct namehashent *) ((char *) ah->addr
|
||||
+ GET (head->namehash_offset));
|
||||
unsigned int insert_idx, idx, incr;
|
||||
|
||||
/* Hash value of the locale name. */
|
||||
uint32_t hval = archive_hashval (name, name_len);
|
||||
|
||||
insert_idx = -1;
|
||||
idx = hval % head->namehash_size;
|
||||
incr = 1 + hval % (head->namehash_size - 2);
|
||||
idx = hval % GET (head->namehash_size);
|
||||
incr = 1 + hval % (GET (head->namehash_size) - 2);
|
||||
|
||||
/* If the name_offset field is zero this means this is a
|
||||
deleted entry and therefore no entry can be found. */
|
||||
while (namehashtab[idx].name_offset != 0)
|
||||
while (GET (namehashtab[idx].name_offset) != 0)
|
||||
{
|
||||
if (namehashtab[idx].hashval == hval
|
||||
&& strcmp (name,
|
||||
(char *) ah->addr + namehashtab[idx].name_offset) == 0)
|
||||
if (GET (namehashtab[idx].hashval) == hval
|
||||
&& (strcmp (name,
|
||||
(char *) ah->addr + GET (namehashtab[idx].name_offset))
|
||||
== 0))
|
||||
{
|
||||
/* Found the entry. */
|
||||
if (namehashtab[idx].locrec_offset != 0 && ! replace)
|
||||
if (GET (namehashtab[idx].locrec_offset) != 0 && ! replace)
|
||||
{
|
||||
if (! be_quiet)
|
||||
error (0, 0, _("locale '%s' already exists"), name);
|
||||
@ -701,26 +722,27 @@ insert_name (struct locarhandle *ah,
|
||||
break;
|
||||
}
|
||||
|
||||
if (namehashtab[idx].hashval == hval && ! be_quiet)
|
||||
if (GET (namehashtab[idx].hashval) == hval && ! be_quiet)
|
||||
{
|
||||
error (0, 0, "hash collision (%u) %s, %s",
|
||||
hval, name, (char *) ah->addr + namehashtab[idx].name_offset);
|
||||
hval, name,
|
||||
(char *) ah->addr + GET (namehashtab[idx].name_offset));
|
||||
}
|
||||
|
||||
/* Remember the first place we can insert the new entry. */
|
||||
if (namehashtab[idx].locrec_offset == 0 && insert_idx == -1)
|
||||
if (GET (namehashtab[idx].locrec_offset) == 0 && insert_idx == -1)
|
||||
insert_idx = idx;
|
||||
|
||||
idx += incr;
|
||||
if (idx >= head->namehash_size)
|
||||
idx -= head->namehash_size;
|
||||
if (idx >= GET (head->namehash_size))
|
||||
idx -= GET (head->namehash_size);
|
||||
}
|
||||
|
||||
/* Add as early as possible. */
|
||||
if (insert_idx != -1)
|
||||
idx = insert_idx;
|
||||
|
||||
namehashtab[idx].hashval = hval; /* no-op if replacing an old entry. */
|
||||
SET (namehashtab[idx].hashval, hval); /* no-op if replacing an old entry. */
|
||||
return &namehashtab[idx];
|
||||
}
|
||||
|
||||
@ -736,12 +758,13 @@ add_alias (struct locarhandle *ah, const char *alias, bool replace,
|
||||
if (namehashent == NULL && ! replace)
|
||||
return;
|
||||
|
||||
if (namehashent->name_offset == 0)
|
||||
if (GET (namehashent->name_offset) == 0)
|
||||
{
|
||||
/* We are adding a new hash entry for this alias.
|
||||
Determine whether we have to resize the file. */
|
||||
if (head->string_used + name_len + 1 > head->string_size
|
||||
|| 100 * head->namehash_used > 75 * head->namehash_size)
|
||||
if (GET (head->string_used) + name_len + 1 > GET (head->string_size)
|
||||
|| (100 * GET (head->namehash_used)
|
||||
> 75 * GET (head->namehash_size)))
|
||||
{
|
||||
/* The current archive is not large enough. */
|
||||
enlarge_archive (ah, head);
|
||||
@ -749,9 +772,9 @@ add_alias (struct locarhandle *ah, const char *alias, bool replace,
|
||||
/* The locrecent might have moved, so we have to look up
|
||||
the old name afresh. */
|
||||
namehashent = insert_name (ah, oldname, strlen (oldname), true);
|
||||
assert (namehashent->name_offset != 0);
|
||||
assert (namehashent->locrec_offset != 0);
|
||||
*locrec_offset_p = namehashent->locrec_offset;
|
||||
assert (GET (namehashent->name_offset) != 0);
|
||||
assert (GET (namehashent->locrec_offset) != 0);
|
||||
*locrec_offset_p = GET (namehashent->locrec_offset);
|
||||
|
||||
/* Tail call to try the whole thing again. */
|
||||
add_alias (ah, alias, replace, oldname, locrec_offset_p);
|
||||
@ -759,26 +782,27 @@ add_alias (struct locarhandle *ah, const char *alias, bool replace,
|
||||
}
|
||||
|
||||
/* Add the name string. */
|
||||
memcpy (ah->addr + head->string_offset + head->string_used,
|
||||
memcpy (ah->addr + GET (head->string_offset) + GET (head->string_used),
|
||||
alias, name_len + 1);
|
||||
namehashent->name_offset = head->string_offset + head->string_used;
|
||||
head->string_used += name_len + 1;
|
||||
SET (namehashent->name_offset,
|
||||
GET (head->string_offset) + GET (head->string_used));
|
||||
INC (head->string_used, name_len + 1);
|
||||
|
||||
++head->namehash_used;
|
||||
INC (head->namehash_used, 1);
|
||||
}
|
||||
|
||||
if (namehashent->locrec_offset != 0)
|
||||
if (GET (namehashent->locrec_offset) != 0)
|
||||
{
|
||||
/* Replacing an existing entry.
|
||||
Mark that we are no longer using the old locrecent. */
|
||||
struct locrecent *locrecent
|
||||
= (struct locrecent *) ((char *) ah->addr
|
||||
+ namehashent->locrec_offset);
|
||||
--locrecent->refs;
|
||||
+ GET (namehashent->locrec_offset));
|
||||
INC (locrecent->refs, -1);
|
||||
}
|
||||
|
||||
/* Point this entry at the locrecent installed for the main name. */
|
||||
namehashent->locrec_offset = locrec_offset;
|
||||
SET (namehashent->locrec_offset, locrec_offset);
|
||||
}
|
||||
|
||||
static int /* qsort comparator used below */
|
||||
@ -819,7 +843,7 @@ add_locale (struct locarhandle *ah,
|
||||
|
||||
head = ah->addr;
|
||||
sumhashtab = (struct sumhashent *) ((char *) ah->addr
|
||||
+ head->sumhash_offset);
|
||||
+ GET (head->sumhash_offset));
|
||||
|
||||
memset (file_offsets, 0, sizeof (file_offsets));
|
||||
|
||||
@ -877,10 +901,10 @@ add_locale (struct locarhandle *ah,
|
||||
table. */
|
||||
hval = archive_hashval (data[cnt].sum, 16);
|
||||
|
||||
idx = hval % head->sumhash_size;
|
||||
incr = 1 + hval % (head->sumhash_size - 2);
|
||||
idx = hval % GET (head->sumhash_size);
|
||||
incr = 1 + hval % (GET (head->sumhash_size) - 2);
|
||||
|
||||
while (sumhashtab[idx].file_offset != 0)
|
||||
while (GET (sumhashtab[idx].file_offset) != 0)
|
||||
{
|
||||
if (memcmp (data[cnt].sum, sumhashtab[idx].sum, 16) == 0)
|
||||
{
|
||||
@ -890,40 +914,42 @@ add_locale (struct locarhandle *ah,
|
||||
Unfortunately the sumhashent record does not include
|
||||
the size of the stored data. So we have to search for
|
||||
it. */
|
||||
locrecent = (struct locrecent *) ((char *) ah->addr
|
||||
+ head->locrectab_offset);
|
||||
locrecent
|
||||
= (struct locrecent *) ((char *) ah->addr
|
||||
+ GET (head->locrectab_offset));
|
||||
size_t iloc;
|
||||
for (iloc = 0; iloc < head->locrectab_used; ++iloc)
|
||||
if (locrecent[iloc].refs != 0
|
||||
&& (locrecent[iloc].record[cnt].offset
|
||||
== sumhashtab[idx].file_offset))
|
||||
for (iloc = 0; iloc < GET (head->locrectab_used); ++iloc)
|
||||
if (GET (locrecent[iloc].refs) != 0
|
||||
&& (GET (locrecent[iloc].record[cnt].offset)
|
||||
== GET (sumhashtab[idx].file_offset)))
|
||||
break;
|
||||
|
||||
if (iloc != head->locrectab_used
|
||||
&& data[cnt].size == locrecent[iloc].record[cnt].len
|
||||
if (iloc != GET (head->locrectab_used)
|
||||
&& data[cnt].size == GET (locrecent[iloc].record[cnt].len)
|
||||
/* We have to compare the content. Either we can
|
||||
have the data mmaped or we have to read from
|
||||
the file. */
|
||||
&& (file_data_available_p (ah, sumhashtab[idx].file_offset,
|
||||
data[cnt].size)
|
||||
&& (file_data_available_p
|
||||
(ah, GET (sumhashtab[idx].file_offset),
|
||||
data[cnt].size)
|
||||
? memcmp (data[cnt].addr,
|
||||
(char *) ah->addr
|
||||
+ sumhashtab[idx].file_offset,
|
||||
+ GET (sumhashtab[idx].file_offset),
|
||||
data[cnt].size) == 0
|
||||
: compare_from_file (ah, data[cnt].addr,
|
||||
sumhashtab[idx].file_offset,
|
||||
GET (sumhashtab[idx].file_offset),
|
||||
data[cnt].size) == 0))
|
||||
{
|
||||
/* Found it. */
|
||||
file_offsets[cnt] = sumhashtab[idx].file_offset;
|
||||
file_offsets[cnt] = GET (sumhashtab[idx].file_offset);
|
||||
--num_new_offsets;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
idx += incr;
|
||||
if (idx >= head->sumhash_size)
|
||||
idx -= head->sumhash_size;
|
||||
if (idx >= GET (head->sumhash_size))
|
||||
idx -= GET (head->sumhash_size);
|
||||
}
|
||||
}
|
||||
|
||||
@ -933,11 +959,14 @@ add_locale (struct locarhandle *ah,
|
||||
return 0;
|
||||
|
||||
/* Determine whether we have to resize the file. */
|
||||
if (100 * (head->sumhash_used + num_new_offsets) > 75 * head->sumhash_size
|
||||
|| (namehashent->locrec_offset == 0
|
||||
&& (head->locrectab_used == head->locrectab_size
|
||||
|| head->string_used + name_len + 1 > head->string_size
|
||||
|| 100 * head->namehash_used > 75 * head->namehash_size)))
|
||||
if ((100 * (GET (head->sumhash_used) + num_new_offsets)
|
||||
> 75 * GET (head->sumhash_size))
|
||||
|| (GET (namehashent->locrec_offset) == 0
|
||||
&& (GET (head->locrectab_used) == GET (head->locrectab_size)
|
||||
|| (GET (head->string_used) + name_len + 1
|
||||
> GET (head->string_size))
|
||||
|| (100 * GET (head->namehash_used)
|
||||
> 75 * GET (head->namehash_size)))))
|
||||
{
|
||||
/* The current archive is not large enough. */
|
||||
enlarge_archive (ah, head);
|
||||
@ -1000,20 +1029,20 @@ add_locale (struct locarhandle *ah,
|
||||
/* Add the hash value to the hash table. */
|
||||
md5hval = archive_hashval (data[cnt].sum, 16);
|
||||
|
||||
idx = md5hval % head->sumhash_size;
|
||||
incr = 1 + md5hval % (head->sumhash_size - 2);
|
||||
idx = md5hval % GET (head->sumhash_size);
|
||||
incr = 1 + md5hval % (GET (head->sumhash_size) - 2);
|
||||
|
||||
while (sumhashtab[idx].file_offset != 0)
|
||||
while (GET (sumhashtab[idx].file_offset) != 0)
|
||||
{
|
||||
idx += incr;
|
||||
if (idx >= head->sumhash_size)
|
||||
idx -= head->sumhash_size;
|
||||
if (idx >= GET (head->sumhash_size))
|
||||
idx -= GET (head->sumhash_size);
|
||||
}
|
||||
|
||||
memcpy (sumhashtab[idx].sum, data[cnt].sum, 16);
|
||||
sumhashtab[idx].file_offset = file_offsets[cnt];
|
||||
SET (sumhashtab[idx].file_offset, file_offsets[cnt]);
|
||||
|
||||
++head->sumhash_used;
|
||||
INC (head->sumhash_used, 1);
|
||||
}
|
||||
|
||||
lastoffset = file_offsets[LC_ALL];
|
||||
@ -1024,25 +1053,28 @@ add_locale (struct locarhandle *ah,
|
||||
lastoffset += (data[cnt].size + 15) & -16;
|
||||
}
|
||||
|
||||
if (namehashent->name_offset == 0)
|
||||
if (GET (namehashent->name_offset) == 0)
|
||||
{
|
||||
/* Add the name string. */
|
||||
memcpy ((char *) ah->addr + head->string_offset + head->string_used,
|
||||
memcpy ((char *) ah->addr + GET (head->string_offset)
|
||||
+ GET (head->string_used),
|
||||
name, name_len + 1);
|
||||
namehashent->name_offset = head->string_offset + head->string_used;
|
||||
head->string_used += name_len + 1;
|
||||
++head->namehash_used;
|
||||
SET (namehashent->name_offset,
|
||||
GET (head->string_offset) + GET (head->string_used));
|
||||
INC (head->string_used, name_len + 1);
|
||||
INC (head->namehash_used, 1);
|
||||
}
|
||||
|
||||
if (namehashent->locrec_offset == 0)
|
||||
if (GET (namehashent->locrec_offset == 0))
|
||||
{
|
||||
/* Allocate a name location record. */
|
||||
namehashent->locrec_offset = (head->locrectab_offset
|
||||
+ (head->locrectab_used++
|
||||
* sizeof (struct locrecent)));
|
||||
SET (namehashent->locrec_offset, (GET (head->locrectab_offset)
|
||||
+ (GET (head->locrectab_used)
|
||||
* sizeof (struct locrecent))));
|
||||
INC (head->locrectab_used, 1);
|
||||
locrecent = (struct locrecent *) ((char *) ah->addr
|
||||
+ namehashent->locrec_offset);
|
||||
locrecent->refs = 1;
|
||||
+ GET (namehashent->locrec_offset));
|
||||
SET (locrecent->refs, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1050,27 +1082,29 @@ add_locale (struct locarhandle *ah,
|
||||
we still need a new one. If not, reuse the old one. */
|
||||
|
||||
locrecent = (struct locrecent *) ((char *) ah->addr
|
||||
+ namehashent->locrec_offset);
|
||||
if (locrecent->refs > 1)
|
||||
+ GET (namehashent->locrec_offset));
|
||||
if (GET (locrecent->refs) > 1)
|
||||
{
|
||||
--locrecent->refs;
|
||||
namehashent->locrec_offset = (head->locrectab_offset
|
||||
+ (head->locrectab_used++
|
||||
* sizeof (struct locrecent)));
|
||||
locrecent = (struct locrecent *) ((char *) ah->addr
|
||||
+ namehashent->locrec_offset);
|
||||
locrecent->refs = 1;
|
||||
INC (locrecent->refs, -1);
|
||||
SET (namehashent->locrec_offset, (GET (head->locrectab_offset)
|
||||
+ (GET (head->locrectab_used)
|
||||
* sizeof (struct locrecent))));
|
||||
INC (head->locrectab_used, 1);
|
||||
locrecent
|
||||
= (struct locrecent *) ((char *) ah->addr
|
||||
+ GET (namehashent->locrec_offset));
|
||||
SET (locrecent->refs, 1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Fill in the table with the locations of the locale data. */
|
||||
for (cnt = 0; cnt < __LC_LAST; ++cnt)
|
||||
{
|
||||
locrecent->record[cnt].offset = file_offsets[cnt];
|
||||
locrecent->record[cnt].len = data[cnt].size;
|
||||
SET (locrecent->record[cnt].offset, file_offsets[cnt]);
|
||||
SET (locrecent->record[cnt].len, data[cnt].size);
|
||||
}
|
||||
|
||||
return namehashent->locrec_offset;
|
||||
return GET (namehashent->locrec_offset);
|
||||
}
|
||||
|
||||
|
||||
@ -1129,7 +1163,8 @@ add_locale_to_archive (ah, name, data, replace)
|
||||
unsigned int strindex[0];
|
||||
} *filedata = data[LC_CTYPE].addr;
|
||||
codeset = (char *) filedata
|
||||
+ filedata->strindex[_NL_ITEM_INDEX (_NL_CTYPE_CODESET_NAME)];
|
||||
+ maybe_swap_uint32 (filedata->strindex[_NL_ITEM_INDEX
|
||||
(_NL_CTYPE_CODESET_NAME)]);
|
||||
char *normalized_codeset_name = NULL;
|
||||
|
||||
normalized_codeset = _nl_normalize_codeset (codeset, strlen (codeset));
|
||||
@ -1492,7 +1527,7 @@ delete_locales_from_archive (nlist, list)
|
||||
|
||||
head = ah.addr;
|
||||
namehashtab = (struct namehashent *) ((char *) ah.addr
|
||||
+ head->namehash_offset);
|
||||
+ GET (head->namehash_offset));
|
||||
|
||||
while (nlist-- > 0)
|
||||
{
|
||||
@ -1504,30 +1539,31 @@ delete_locales_from_archive (nlist, list)
|
||||
/* Search for this locale in the archive. */
|
||||
hval = archive_hashval (locname, strlen (locname));
|
||||
|
||||
idx = hval % head->namehash_size;
|
||||
incr = 1 + hval % (head->namehash_size - 2);
|
||||
idx = hval % GET (head->namehash_size);
|
||||
incr = 1 + hval % (GET (head->namehash_size) - 2);
|
||||
|
||||
/* If the name_offset field is zero this means this is no
|
||||
deleted entry and therefore no entry can be found. */
|
||||
while (namehashtab[idx].name_offset != 0)
|
||||
while (GET (namehashtab[idx].name_offset) != 0)
|
||||
{
|
||||
if (namehashtab[idx].hashval == hval
|
||||
if (GET (namehashtab[idx].hashval) == hval
|
||||
&& (strcmp (locname,
|
||||
(char *) ah.addr + namehashtab[idx].name_offset)
|
||||
((char *) ah.addr
|
||||
+ GET (namehashtab[idx].name_offset)))
|
||||
== 0))
|
||||
{
|
||||
/* Found the entry. Now mark it as removed by zero-ing
|
||||
the reference to the locale record. */
|
||||
namehashtab[idx].locrec_offset = 0;
|
||||
SET (namehashtab[idx].locrec_offset, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
idx += incr;
|
||||
if (idx >= head->namehash_size)
|
||||
idx -= head->namehash_size;
|
||||
if (idx >= GET (head->namehash_size))
|
||||
idx -= GET (head->namehash_size);
|
||||
}
|
||||
|
||||
if (namehashtab[idx].name_offset == 0 && ! be_quiet)
|
||||
if (GET (namehashtab[idx].name_offset) == 0 && ! be_quiet)
|
||||
error (0, 0, _("locale \"%s\" not in archive"), locname);
|
||||
}
|
||||
|
||||
@ -1590,17 +1626,17 @@ show_archive_content (int verbose)
|
||||
|
||||
head = ah.addr;
|
||||
|
||||
names = (struct nameent *) xmalloc (head->namehash_used
|
||||
names = (struct nameent *) xmalloc (GET (head->namehash_used)
|
||||
* sizeof (struct nameent));
|
||||
|
||||
namehashtab = (struct namehashent *) ((char *) ah.addr
|
||||
+ head->namehash_offset);
|
||||
for (cnt = used = 0; cnt < head->namehash_size; ++cnt)
|
||||
if (namehashtab[cnt].locrec_offset != 0)
|
||||
+ GET (head->namehash_offset));
|
||||
for (cnt = used = 0; cnt < GET (head->namehash_size); ++cnt)
|
||||
if (GET (namehashtab[cnt].locrec_offset) != 0)
|
||||
{
|
||||
assert (used < head->namehash_used);
|
||||
names[used].name = ah.addr + namehashtab[cnt].name_offset;
|
||||
names[used++].locrec_offset = namehashtab[cnt].locrec_offset;
|
||||
assert (used < GET (head->namehash_used));
|
||||
names[used].name = ah.addr + GET (namehashtab[cnt].name_offset);
|
||||
names[used++].locrec_offset = GET (namehashtab[cnt].locrec_offset);
|
||||
}
|
||||
|
||||
/* Sort the names. */
|
||||
@ -1612,17 +1648,17 @@ show_archive_content (int verbose)
|
||||
struct sumhashent *sumhashtab;
|
||||
int sumused;
|
||||
|
||||
files = (struct dataent *) xmalloc (head->sumhash_used
|
||||
files = (struct dataent *) xmalloc (GET (head->sumhash_used)
|
||||
* sizeof (struct dataent));
|
||||
|
||||
sumhashtab = (struct sumhashent *) ((char *) ah.addr
|
||||
+ head->sumhash_offset);
|
||||
for (cnt = sumused = 0; cnt < head->sumhash_size; ++cnt)
|
||||
if (sumhashtab[cnt].file_offset != 0)
|
||||
+ GET (head->sumhash_offset));
|
||||
for (cnt = sumused = 0; cnt < GET (head->sumhash_size); ++cnt)
|
||||
if (GET (sumhashtab[cnt].file_offset) != 0)
|
||||
{
|
||||
assert (sumused < head->sumhash_used);
|
||||
assert (sumused < GET (head->sumhash_used));
|
||||
files[sumused].sum = (const unsigned char *) sumhashtab[cnt].sum;
|
||||
files[sumused].file_offset = sumhashtab[cnt].file_offset;
|
||||
files[sumused].file_offset = GET (sumhashtab[cnt].file_offset);
|
||||
files[sumused++].nlink = 0;
|
||||
}
|
||||
|
||||
@ -1638,18 +1674,19 @@ show_archive_content (int verbose)
|
||||
locrec = (struct locrecent *) ((char *) ah.addr
|
||||
+ names[cnt].locrec_offset);
|
||||
for (idx = 0; idx < __LC_LAST; ++idx)
|
||||
if (locrec->record[LC_ALL].offset != 0
|
||||
if (GET (locrec->record[LC_ALL].offset) != 0
|
||||
? (idx == LC_ALL
|
||||
|| (locrec->record[idx].offset
|
||||
< locrec->record[LC_ALL].offset)
|
||||
|| (locrec->record[idx].offset + locrec->record[idx].len
|
||||
> (locrec->record[LC_ALL].offset
|
||||
+ locrec->record[LC_ALL].len)))
|
||||
|| (GET (locrec->record[idx].offset)
|
||||
< GET (locrec->record[LC_ALL].offset))
|
||||
|| ((GET (locrec->record[idx].offset)
|
||||
+ GET (locrec->record[idx].len))
|
||||
> (GET (locrec->record[LC_ALL].offset)
|
||||
+ GET (locrec->record[LC_ALL].len))))
|
||||
: idx != LC_ALL)
|
||||
{
|
||||
struct dataent *data, dataent;
|
||||
|
||||
dataent.file_offset = locrec->record[idx].offset;
|
||||
dataent.file_offset = GET (locrec->record[idx].offset);
|
||||
data = (struct dataent *) bsearch (&dataent, files, sumused,
|
||||
sizeof (struct dataent),
|
||||
dataentcmp);
|
||||
@ -1671,21 +1708,24 @@ show_archive_content (int verbose)
|
||||
{
|
||||
struct dataent *data, dataent;
|
||||
|
||||
dataent.file_offset = locrec->record[idx].offset;
|
||||
if (locrec->record[LC_ALL].offset != 0
|
||||
&& dataent.file_offset >= locrec->record[LC_ALL].offset
|
||||
&& (dataent.file_offset + locrec->record[idx].len
|
||||
<= (locrec->record[LC_ALL].offset
|
||||
+ locrec->record[LC_ALL].len)))
|
||||
dataent.file_offset = locrec->record[LC_ALL].offset;
|
||||
dataent.file_offset = GET (locrec->record[idx].offset);
|
||||
if (GET (locrec->record[LC_ALL].offset) != 0
|
||||
&& (dataent.file_offset
|
||||
>= GET (locrec->record[LC_ALL].offset))
|
||||
&& (dataent.file_offset + GET (locrec->record[idx].len)
|
||||
<= (GET (locrec->record[LC_ALL].offset)
|
||||
+ GET (locrec->record[LC_ALL].len))))
|
||||
dataent.file_offset = GET (locrec->record[LC_ALL].offset);
|
||||
|
||||
data = (struct dataent *) bsearch (&dataent, files, sumused,
|
||||
sizeof (struct dataent),
|
||||
dataentcmp);
|
||||
printf ("%6d %7x %3d%c ",
|
||||
locrec->record[idx].len, locrec->record[idx].offset,
|
||||
GET (locrec->record[idx].len),
|
||||
GET (locrec->record[idx].offset),
|
||||
data->nlink,
|
||||
dataent.file_offset == locrec->record[LC_ALL].offset
|
||||
(dataent.file_offset
|
||||
== GET (locrec->record[LC_ALL].offset))
|
||||
? '+' : ' ');
|
||||
for (i = 0; i < 16; i += 4)
|
||||
printf ("%02x%02x%02x%02x",
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
@ -538,6 +539,10 @@ compare_files (const char *filename1, const char *filename2, size_t size,
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* True if the locale files use the opposite endianness to the
|
||||
machine running localedef. */
|
||||
bool swap_endianness_p;
|
||||
|
||||
/* 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.
|
||||
@ -624,6 +629,7 @@ add_locale_uint32 (struct locale_file *file, uint32_t value)
|
||||
{
|
||||
align_locale_data (file, sizeof (uint32_t));
|
||||
record_offset (file);
|
||||
value = maybe_swap_uint32 (value);
|
||||
obstack_grow (&file->data, &value, sizeof (value));
|
||||
}
|
||||
|
||||
@ -636,6 +642,7 @@ add_locale_uint32_array (struct locale_file *file,
|
||||
align_locale_data (file, sizeof (uint32_t));
|
||||
record_offset (file);
|
||||
obstack_grow (&file->data, data, n_elems * sizeof (uint32_t));
|
||||
maybe_swap_uint32_obstack (&file->data, n_elems);
|
||||
}
|
||||
|
||||
/* Record that FILE's next element is the single byte given by VALUE. */
|
||||
@ -708,6 +715,8 @@ write_locale_data (const char *output_path, int catidx, const char *category,
|
||||
vec[1].iov_base = file->offsets;
|
||||
vec[2].iov_len = obstack_object_size (&file->data);
|
||||
vec[2].iov_base = obstack_finish (&file->data);
|
||||
maybe_swap_uint32_array (vec[0].iov_base, 2);
|
||||
maybe_swap_uint32_array (vec[1].iov_base, file->n_elements);
|
||||
n_elem = 3;
|
||||
if (! no_archive)
|
||||
{
|
||||
|
@ -18,6 +18,8 @@
|
||||
#ifndef _LOCFILE_H
|
||||
#define _LOCFILE_H 1
|
||||
|
||||
#include <byteswap.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <sys/uio.h>
|
||||
|
||||
@ -67,6 +69,41 @@ extern void write_all_categories (struct localedef_t *definitions,
|
||||
const char *locname,
|
||||
const char *output_path);
|
||||
|
||||
extern bool swap_endianness_p;
|
||||
|
||||
/* Change the output to be big-endian if BIG_ENDIAN is true and
|
||||
little-endian otherwise. */
|
||||
static inline void
|
||||
set_big_endian (bool big_endian)
|
||||
{
|
||||
swap_endianness_p = (big_endian != (__BYTE_ORDER == __BIG_ENDIAN));
|
||||
}
|
||||
|
||||
/* Munge VALUE so that, when stored, it has the correct byte order
|
||||
for the output files. */
|
||||
static inline uint32_t
|
||||
maybe_swap_uint32 (uint32_t value)
|
||||
{
|
||||
return swap_endianness_p ? bswap_32 (value) : value;
|
||||
}
|
||||
|
||||
/* Likewise, but munge an array of N uint32_ts starting at ARRAY. */
|
||||
static inline void
|
||||
maybe_swap_uint32_array (uint32_t *array, size_t n)
|
||||
{
|
||||
if (swap_endianness_p)
|
||||
while (n-- > 0)
|
||||
array[n] = bswap_32 (array[n]);
|
||||
}
|
||||
|
||||
/* Like maybe_swap_uint32_array, but the array of N elements is at
|
||||
the end of OBSTACK's current object. */
|
||||
static inline void
|
||||
maybe_swap_uint32_obstack (struct obstack *obstack, size_t n)
|
||||
{
|
||||
maybe_swap_uint32_array ((uint32_t *) obstack_next_free (obstack) - n, n);
|
||||
}
|
||||
|
||||
/* 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);
|
||||
|
Loading…
Reference in New Issue
Block a user