mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-25 06:20:06 +00:00
Update.
1999-12-13 Andreas Jaeger <aj@suse.de> * resolv/resolv.h: Remove K&R compatibility. * resolv/res_libc.c: Move definition of _res after res_init, res_init should use the threaded specific context. * resolv/Makefile (+cflags): Remove -Wno-comment since it's not needed anymore. * locale/langinfo.h: Add constants for wide character collation data. * locale/categories.def: Add appropriate entries for collate entries. * locale/C-collate.c: Add initializers for new entries. * locale/programs/ld-collate.c: Implement output of wide character tables. * locale/programs/ld-ctype.c (allocate_arrays): Change algorithm to compute wide character table size a bit: it now gives up a bit of total table size for fewer levels.
This commit is contained in:
parent
d876f53279
commit
66ac0abe03
20
ChangeLog
20
ChangeLog
@ -1,5 +1,25 @@
|
|||||||
|
1999-12-13 Andreas Jaeger <aj@suse.de>
|
||||||
|
|
||||||
|
* resolv/resolv.h: Remove K&R compatibility.
|
||||||
|
|
||||||
|
* resolv/res_libc.c: Move definition of _res after res_init,
|
||||||
|
res_init should use the threaded specific context.
|
||||||
|
|
||||||
|
* resolv/Makefile (+cflags): Remove -Wno-comment since it's not
|
||||||
|
needed anymore.
|
||||||
|
|
||||||
1999-12-29 Ulrich Drepper <drepper@cygnus.com>
|
1999-12-29 Ulrich Drepper <drepper@cygnus.com>
|
||||||
|
|
||||||
|
* locale/langinfo.h: Add constants for wide character collation data.
|
||||||
|
* locale/categories.def: Add appropriate entries for collate entries.
|
||||||
|
* locale/C-collate.c: Add initializers for new entries.
|
||||||
|
* locale/programs/ld-collate.c: Implement output of wide character
|
||||||
|
tables.
|
||||||
|
|
||||||
|
* locale/programs/ld-ctype.c (allocate_arrays): Change algorithm to
|
||||||
|
compute wide character table size a bit: it now gives up a bit of
|
||||||
|
total table size for fewer levels.
|
||||||
|
|
||||||
* soft-fp/*: Tons of new files to implement floating-point arithmetic
|
* soft-fp/*: Tons of new files to implement floating-point arithmetic
|
||||||
in software.
|
in software.
|
||||||
Contributed by Richard Henderson, Jakub Jelinek and others.
|
Contributed by Richard Henderson, Jakub Jelinek and others.
|
||||||
|
4
NEWS
4
NEWS
@ -22,6 +22,10 @@ Version 2.2
|
|||||||
|
|
||||||
* ldconfig program added by Andreas Jaeger and Jakub Jelinek.
|
* ldconfig program added by Andreas Jaeger and Jakub Jelinek.
|
||||||
|
|
||||||
|
* The resolver code has been updated from bind 8.2.2-5 which supports
|
||||||
|
threads. No changes should be necessary for user programs. The
|
||||||
|
integration was done by Andreas Jaeger and Adam D. Bradley.
|
||||||
|
|
||||||
|
|
||||||
Version 2.1.2
|
Version 2.1.2
|
||||||
|
|
||||||
|
@ -150,8 +150,15 @@ const struct locale_data _nl_C_LC_COLLATE =
|
|||||||
_nl_C_name,
|
_nl_C_name,
|
||||||
NULL, 0, 0, /* no file mapped */
|
NULL, 0, 0, /* no file mapped */
|
||||||
UNDELETABLE,
|
UNDELETABLE,
|
||||||
6,
|
13,
|
||||||
{
|
{
|
||||||
|
{ word: 0 },
|
||||||
|
{ string: NULL },
|
||||||
|
{ string: NULL },
|
||||||
|
{ string: NULL },
|
||||||
|
{ string: NULL },
|
||||||
|
{ string: NULL },
|
||||||
|
{ word: 0 },
|
||||||
{ word: 0 },
|
{ word: 0 },
|
||||||
{ string: NULL },
|
{ string: NULL },
|
||||||
{ string: NULL },
|
{ string: NULL },
|
||||||
|
@ -48,6 +48,13 @@ DEFINE_CATEGORY
|
|||||||
DEFINE_ELEMENT (_NL_COLLATE_WEIGHTMB, "collate-weightmb", std, string)
|
DEFINE_ELEMENT (_NL_COLLATE_WEIGHTMB, "collate-weightmb", std, string)
|
||||||
DEFINE_ELEMENT (_NL_COLLATE_EXTRAMB, "collate-extramb", std, string)
|
DEFINE_ELEMENT (_NL_COLLATE_EXTRAMB, "collate-extramb", std, string)
|
||||||
DEFINE_ELEMENT (_NL_COLLATE_INDIRECTMB, "collate-indirectmb", std, string)
|
DEFINE_ELEMENT (_NL_COLLATE_INDIRECTMB, "collate-indirectmb", std, string)
|
||||||
|
DEFINE_ELEMENT (_NL_COLLATE_HASH_SIZE, "collate-hash-size", std, word)
|
||||||
|
DEFINE_ELEMENT (_NL_COLLATE_HASH_LAYERS, "collate-hash-layers", std, word)
|
||||||
|
DEFINE_ELEMENT (_NL_COLLATE_NAMES, "collate-names", std, string)
|
||||||
|
DEFINE_ELEMENT (_NL_COLLATE_TABLEWC, "collate-tablewc", std, string)
|
||||||
|
DEFINE_ELEMENT (_NL_COLLATE_WEIGHTWC, "collate-weightwc", std, string)
|
||||||
|
DEFINE_ELEMENT (_NL_COLLATE_EXTRAWC, "collate-extrawc", std, string)
|
||||||
|
DEFINE_ELEMENT (_NL_COLLATE_INDIRECTWC, "collate-indirectwc", std, string)
|
||||||
), NO_POSTLOAD)
|
), NO_POSTLOAD)
|
||||||
|
|
||||||
|
|
||||||
|
@ -236,6 +236,13 @@ enum
|
|||||||
_NL_COLLATE_WEIGHTMB,
|
_NL_COLLATE_WEIGHTMB,
|
||||||
_NL_COLLATE_EXTRAMB,
|
_NL_COLLATE_EXTRAMB,
|
||||||
_NL_COLLATE_INDIRECTMB,
|
_NL_COLLATE_INDIRECTMB,
|
||||||
|
_NL_COLLATE_HASH_SIZE,
|
||||||
|
_NL_COLLATE_HASH_LAYERS,
|
||||||
|
_NL_COLLATE_NAMES,
|
||||||
|
_NL_COLLATE_TABLEWC,
|
||||||
|
_NL_COLLATE_WEIGHTWC,
|
||||||
|
_NL_COLLATE_EXTRAWC,
|
||||||
|
_NL_COLLATE_INDIRECTWC,
|
||||||
_NL_NUM_LC_COLLATE,
|
_NL_NUM_LC_COLLATE,
|
||||||
|
|
||||||
/* LC_CTYPE category: character classification.
|
/* LC_CTYPE category: character classification.
|
||||||
|
@ -106,6 +106,9 @@ struct element_t
|
|||||||
|
|
||||||
/* Next element in multibyte output list. */
|
/* Next element in multibyte output list. */
|
||||||
struct element_t *mbnext;
|
struct element_t *mbnext;
|
||||||
|
|
||||||
|
/* Next element in wide character output list. */
|
||||||
|
struct element_t *wcnext;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Special element value. */
|
/* Special element value. */
|
||||||
@ -171,6 +174,14 @@ struct locale_collate_t
|
|||||||
/* Arrays with heads of the list for each of the leading bytes in
|
/* Arrays with heads of the list for each of the leading bytes in
|
||||||
the multibyte sequences. */
|
the multibyte sequences. */
|
||||||
struct element_t *mbheads[256];
|
struct element_t *mbheads[256];
|
||||||
|
|
||||||
|
/* Table size of wide character hash table. */
|
||||||
|
size_t plane_size;
|
||||||
|
size_t plane_cnt;
|
||||||
|
|
||||||
|
/* Arrays with heads of the list for each of the leading bytes in
|
||||||
|
the multibyte sequences. */
|
||||||
|
struct element_t **wcheads;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -1381,6 +1392,9 @@ collate_finish (struct localedef_t *locale, struct charmap_t *charmap)
|
|||||||
int need_undefined = 0;
|
int need_undefined = 0;
|
||||||
struct section_list *sect;
|
struct section_list *sect;
|
||||||
int ruleidx;
|
int ruleidx;
|
||||||
|
int nr_wide_elems = 0;
|
||||||
|
size_t min_total;
|
||||||
|
size_t act_size;
|
||||||
|
|
||||||
if (collate == NULL)
|
if (collate == NULL)
|
||||||
{
|
{
|
||||||
@ -1457,8 +1471,8 @@ collate_finish (struct localedef_t *locale, struct charmap_t *charmap)
|
|||||||
be encoded to make it possible to emit the value as a byte
|
be encoded to make it possible to emit the value as a byte
|
||||||
string. */
|
string. */
|
||||||
for (i = 0; i < nrules; ++i)
|
for (i = 0; i < nrules; ++i)
|
||||||
mbact[i] = 3;
|
mbact[i] = 2;
|
||||||
wcact = 3;
|
wcact = 2;
|
||||||
runp = collate->start;
|
runp = collate->start;
|
||||||
while (runp != NULL)
|
while (runp != NULL)
|
||||||
{
|
{
|
||||||
@ -1518,8 +1532,14 @@ collate_finish (struct localedef_t *locale, struct charmap_t *charmap)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (runp->wcs != NULL)
|
if (runp->wcs != NULL)
|
||||||
|
{
|
||||||
runp->wcorder = wcact++;
|
runp->wcorder = wcact++;
|
||||||
|
|
||||||
|
/* We take the opportunity to count the elements which have
|
||||||
|
wide characters. */
|
||||||
|
++nr_wide_elems;
|
||||||
|
}
|
||||||
|
|
||||||
/* Up to the next entry. */
|
/* Up to the next entry. */
|
||||||
runp = runp->next;
|
runp = runp->next;
|
||||||
}
|
}
|
||||||
@ -1533,6 +1553,165 @@ collate_finish (struct localedef_t *locale, struct charmap_t *charmap)
|
|||||||
collate->mbheads[i] = &collate->undefined;
|
collate->mbheads[i] = &collate->undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Now to the wide character case. Here we have to find first a good
|
||||||
|
mapping function to get the wide range of wide character values
|
||||||
|
(0x00000000 to 0x7fffffff) to a managable table. This might take
|
||||||
|
some time so we issue a warning.
|
||||||
|
|
||||||
|
We use a very trivial hashing function to store the sparse
|
||||||
|
table. CH % TABSIZE is used as an index. To solve multiple hits
|
||||||
|
we have N planes. This guarantees a fixed search time for a
|
||||||
|
character [N / 2]. In the following code we determine the minimum
|
||||||
|
value for TABSIZE * N, where TABSIZE >= 256.
|
||||||
|
|
||||||
|
Some people complained that this algorithm takes too long. Well,
|
||||||
|
go on, improve it. But changing the step size is *not* an
|
||||||
|
option. Some people changed this to use only sizes of prime
|
||||||
|
numbers. Think again, do some math. We are looking for the
|
||||||
|
optimal solution, not something which works in general. Unless
|
||||||
|
somebody can provide a dynamic programming solution I think this
|
||||||
|
implementation is as good as it can get. */
|
||||||
|
if (nr_wide_elems > 512 && !be_quiet)
|
||||||
|
fputs (_("\
|
||||||
|
Computing table size for collation table might take a while..."),
|
||||||
|
stderr);
|
||||||
|
|
||||||
|
min_total = UINT_MAX;
|
||||||
|
act_size = 256;
|
||||||
|
|
||||||
|
/* While we want to have a small total size we are willing to use a
|
||||||
|
little bit larger table if this reduces the number of layers.
|
||||||
|
Therefore we add a little penalty to the number of planes.
|
||||||
|
Maybe this constant has to be adjusted a bit. */
|
||||||
|
#define PENALTY 128
|
||||||
|
do
|
||||||
|
{
|
||||||
|
size_t cnt[act_size];
|
||||||
|
struct element_t *elem[act_size];
|
||||||
|
size_t act_planes = 1;
|
||||||
|
|
||||||
|
memset (cnt, '\0', sizeof cnt);
|
||||||
|
memset (elem, '\0', sizeof elem);
|
||||||
|
|
||||||
|
runp = collate->start;
|
||||||
|
while (runp != NULL)
|
||||||
|
{
|
||||||
|
if (runp->wcs != NULL)
|
||||||
|
{
|
||||||
|
size_t nr = runp->wcs[0] % act_size;
|
||||||
|
struct element_t *elemp = elem[nr];
|
||||||
|
|
||||||
|
while (elemp != NULL)
|
||||||
|
{
|
||||||
|
if (elemp->wcs[0] == runp->wcs[0])
|
||||||
|
break;
|
||||||
|
elemp = elemp->wcnext;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (elemp == NULL && ++cnt[nr] > act_planes)
|
||||||
|
{
|
||||||
|
act_planes = cnt[nr];
|
||||||
|
|
||||||
|
runp->wcnext = elem[nr];
|
||||||
|
elem[nr] = runp;
|
||||||
|
|
||||||
|
if ((act_size + PENALTY) * act_planes >= min_total)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Up to the next entry. */
|
||||||
|
runp = runp->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((act_size + PENALTY) * act_planes < min_total)
|
||||||
|
{
|
||||||
|
min_total = (act_size + PENALTY) * act_planes;
|
||||||
|
collate->plane_size = act_size;
|
||||||
|
collate->plane_cnt = act_planes;
|
||||||
|
}
|
||||||
|
|
||||||
|
++act_size;
|
||||||
|
}
|
||||||
|
while (act_size < min_total);
|
||||||
|
|
||||||
|
if (nr_wide_elems > 512 && !be_quiet)
|
||||||
|
fputs (_(" done\n"), stderr);
|
||||||
|
|
||||||
|
/* Now that we know how large the table has to be we are able to
|
||||||
|
allocate the array and start adding the characters to the lists
|
||||||
|
in the same way we did it for the multibyte characters. */
|
||||||
|
collate->wcheads = (struct element_t **)
|
||||||
|
obstack_alloc (&collate->mempool, (collate->plane_size
|
||||||
|
* collate->plane_cnt
|
||||||
|
* sizeof (struct element_t *)));
|
||||||
|
memset (collate->wcheads, '\0', (collate->plane_size
|
||||||
|
* collate->plane_cnt
|
||||||
|
* sizeof (struct element_t *)));
|
||||||
|
|
||||||
|
/* Start adding. */
|
||||||
|
runp = collate->start;
|
||||||
|
while (runp != NULL)
|
||||||
|
{
|
||||||
|
if (runp->wcs != NULL)
|
||||||
|
{
|
||||||
|
struct element_t **eptr;
|
||||||
|
size_t idx;
|
||||||
|
|
||||||
|
/* Find a free index. */
|
||||||
|
idx = runp->wcs[0] % collate->plane_size;
|
||||||
|
while (collate->wcheads[idx] != NULL)
|
||||||
|
{
|
||||||
|
/* Stop if this is an entry with the same starting character. */
|
||||||
|
if (collate->wcheads[idx]->wcs[0] == runp->wcs[0])
|
||||||
|
break;
|
||||||
|
|
||||||
|
idx += collate->plane_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Find the point where to insert in the list. */
|
||||||
|
eptr = &collate->wcheads[idx];
|
||||||
|
while (*eptr != NULL)
|
||||||
|
{
|
||||||
|
if ((*eptr)->nwcs < runp->nwcs)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if ((*eptr)->nwcs == runp->nwcs)
|
||||||
|
{
|
||||||
|
int c = wmemcmp ((wchar_t *) (*eptr)->wcs,
|
||||||
|
(wchar_t *) runp->wcs, runp->nwcs);
|
||||||
|
|
||||||
|
if (c == 0)
|
||||||
|
{
|
||||||
|
/* This should not happen. It means that we have
|
||||||
|
to symbols with the same byte sequence. It is
|
||||||
|
of course an error. */
|
||||||
|
error_at_line (0, 0, (*eptr)->file, (*eptr)->line,
|
||||||
|
_("symbol `%s' has same encoding as"),
|
||||||
|
(*eptr)->name);
|
||||||
|
error_at_line (0, 0, runp->file, runp->line,
|
||||||
|
_("symbol `%s'"), runp->name);
|
||||||
|
goto dont_insertwc;
|
||||||
|
}
|
||||||
|
else if (c < 0)
|
||||||
|
/* Insert it here. */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* To the next entry. */
|
||||||
|
eptr = &(*eptr)->wcnext;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set the pointers. */
|
||||||
|
runp->wcnext = *eptr;
|
||||||
|
*eptr = runp;
|
||||||
|
dont_insertwc:
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Up to the next entry. */
|
||||||
|
runp = runp->next;
|
||||||
|
}
|
||||||
|
|
||||||
/* 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;
|
||||||
@ -1620,6 +1799,45 @@ output_weight (struct obstack *pool, struct locale_collate_t *collate,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int32_t
|
||||||
|
output_weightwc (struct obstack *pool, struct locale_collate_t *collate,
|
||||||
|
struct element_t *elem)
|
||||||
|
{
|
||||||
|
size_t cnt;
|
||||||
|
int32_t retval;
|
||||||
|
|
||||||
|
/* Optimize the use of UNDEFINED. */
|
||||||
|
if (elem == &collate->undefined)
|
||||||
|
/* The weights are already inserted. */
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* This byte can start exactly one collation element and this is
|
||||||
|
a single byte. We can directly give the index to the weights. */
|
||||||
|
retval = obstack_object_size (pool);
|
||||||
|
|
||||||
|
/* Construct the weight. */
|
||||||
|
for (cnt = 0; cnt < nrules; ++cnt)
|
||||||
|
{
|
||||||
|
int32_t buf[elem->weights[cnt].cnt];
|
||||||
|
int32_t i;
|
||||||
|
|
||||||
|
for (i = 0; i < elem->weights[cnt].cnt; ++i)
|
||||||
|
if (elem->weights[cnt].w[i] != NULL)
|
||||||
|
buf[i] = elem->weights[cnt].w[i]->wcorder;
|
||||||
|
|
||||||
|
/* And add the buffer content. */
|
||||||
|
if (sizeof (int) == sizeof (int32_t))
|
||||||
|
obstack_int_grow (pool, i);
|
||||||
|
else
|
||||||
|
obstack_grow (pool, &i, sizeof (int32_t));
|
||||||
|
|
||||||
|
obstack_grow (pool, buf, i * sizeof (int32_t));
|
||||||
|
}
|
||||||
|
|
||||||
|
return retval | ((elem->section->ruleidx & 0x7f) << 24);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
collate_output (struct localedef_t *locale, struct charmap_t *charmap,
|
collate_output (struct localedef_t *locale, struct charmap_t *charmap,
|
||||||
const char *output_path)
|
const char *output_path)
|
||||||
@ -1636,6 +1854,9 @@ collate_output (struct localedef_t *locale, struct charmap_t *charmap,
|
|||||||
struct obstack extrapool;
|
struct obstack extrapool;
|
||||||
struct obstack indirectpool;
|
struct obstack indirectpool;
|
||||||
struct section_list *sect;
|
struct section_list *sect;
|
||||||
|
uint32_t *names;
|
||||||
|
uint32_t *tablewc;
|
||||||
|
size_t table_size;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
data.magic = LIMAGIC (LC_COLLATE);
|
data.magic = LIMAGIC (LC_COLLATE);
|
||||||
@ -1783,7 +2004,7 @@ collate_output (struct localedef_t *locale, struct charmap_t *charmap,
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
/* Now add first the initial byte sequence. */
|
/* Now add first the initial byte sequence. */
|
||||||
added = ((sizeof (int32_t) + 1 + 1 + 2 * (runp->nmbs - 1)
|
added = ((sizeof (int32_t) + 1 + 2 * (runp->nmbs - 1)
|
||||||
+ __alignof__ (int32_t) - 1)
|
+ __alignof__ (int32_t) - 1)
|
||||||
& ~(__alignof__ (int32_t) - 1));
|
& ~(__alignof__ (int32_t) - 1));
|
||||||
obstack_make_room (&extrapool, added);
|
obstack_make_room (&extrapool, added);
|
||||||
@ -1809,7 +2030,7 @@ collate_output (struct localedef_t *locale, struct charmap_t *charmap,
|
|||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
if (sizeof (int32_t) == sizeof (int))
|
if (sizeof (int32_t) == sizeof (int))
|
||||||
obstack_int_grow_fast (&extrapool, weightidx);
|
obstack_int_grow (&extrapool, weightidx);
|
||||||
else
|
else
|
||||||
obstack_grow (&extrapool, &weightidx, sizeof (int32_t));
|
obstack_grow (&extrapool, &weightidx, sizeof (int32_t));
|
||||||
|
|
||||||
@ -1833,7 +2054,7 @@ collate_output (struct localedef_t *locale, struct charmap_t *charmap,
|
|||||||
|
|
||||||
weightidx = output_weight (&weightpool, collate, runp);
|
weightidx = output_weight (&weightpool, collate, runp);
|
||||||
if (sizeof (int32_t) == sizeof (int))
|
if (sizeof (int32_t) == sizeof (int))
|
||||||
obstack_int_grow_fast (&extrapool, weightidx);
|
obstack_int_grow (&extrapool, weightidx);
|
||||||
else
|
else
|
||||||
obstack_grow (&extrapool, &weightidx, sizeof (int32_t));
|
obstack_grow (&extrapool, &weightidx, sizeof (int32_t));
|
||||||
}
|
}
|
||||||
@ -1844,7 +2065,7 @@ collate_output (struct localedef_t *locale, struct charmap_t *charmap,
|
|||||||
tested for). */
|
tested for). */
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
added = ((sizeof (int32_t) + 1 + 1 + runp->nmbs - 1
|
added = ((sizeof (int32_t) + 1 + runp->nmbs - 1
|
||||||
+ __alignof__ (int32_t) - 1)
|
+ __alignof__ (int32_t) - 1)
|
||||||
& ~(__alignof__ (int32_t) - 1));
|
& ~(__alignof__ (int32_t) - 1));
|
||||||
obstack_make_room (&extrapool, added);
|
obstack_make_room (&extrapool, added);
|
||||||
@ -1900,7 +2121,7 @@ collate_output (struct localedef_t *locale, struct charmap_t *charmap,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now add the three tables. */
|
/* Now add the four tables. */
|
||||||
assert (cnt == _NL_ITEM_INDEX (_NL_COLLATE_TABLEMB));
|
assert (cnt == _NL_ITEM_INDEX (_NL_COLLATE_TABLEMB));
|
||||||
iov[2 + cnt].iov_base = tablemb;
|
iov[2 + cnt].iov_base = tablemb;
|
||||||
iov[2 + cnt].iov_len = sizeof (tablemb);
|
iov[2 + cnt].iov_len = sizeof (tablemb);
|
||||||
@ -1926,6 +2147,211 @@ collate_output (struct localedef_t *locale, struct charmap_t *charmap,
|
|||||||
++cnt;
|
++cnt;
|
||||||
|
|
||||||
|
|
||||||
|
/* Now the same for the wide character table. We need to store some
|
||||||
|
more information here. */
|
||||||
|
assert (cnt == _NL_ITEM_INDEX (_NL_COLLATE_HASH_SIZE));
|
||||||
|
iov[2 + cnt].iov_base = &collate->plane_size;
|
||||||
|
iov[2 + cnt].iov_len = sizeof (collate->plane_size);
|
||||||
|
idx[1 + cnt] = idx[cnt] + iov[2 + cnt].iov_len;
|
||||||
|
++cnt;
|
||||||
|
|
||||||
|
assert (cnt == _NL_ITEM_INDEX (_NL_COLLATE_HASH_LAYERS));
|
||||||
|
iov[2 + cnt].iov_base = &collate->plane_cnt;
|
||||||
|
iov[2 + cnt].iov_len = sizeof (collate->plane_cnt);
|
||||||
|
idx[1 + cnt] = idx[cnt] + iov[2 + cnt].iov_len;
|
||||||
|
++cnt;
|
||||||
|
|
||||||
|
/* Construct a table with the names. The size of the table is the same
|
||||||
|
as the table with the pointers. */
|
||||||
|
table_size = collate->plane_size * collate->plane_cnt;
|
||||||
|
names = (uint32_t *) alloca (table_size * sizeof (uint32_t));
|
||||||
|
for (ch = 0; ch < table_size; ++ch)
|
||||||
|
if (collate->wcheads[ch] == NULL)
|
||||||
|
names[ch] = 0;
|
||||||
|
else
|
||||||
|
names[ch] = collate->wcheads[ch]->wcs[0];
|
||||||
|
|
||||||
|
assert (cnt == _NL_ITEM_INDEX (_NL_COLLATE_NAMES));
|
||||||
|
iov[2 + cnt].iov_base = names;
|
||||||
|
iov[2 + cnt].iov_len = table_size * sizeof (uint32_t);
|
||||||
|
idx[1 + cnt] = idx[cnt] + iov[2 + cnt].iov_len;
|
||||||
|
++cnt;
|
||||||
|
|
||||||
|
/* Generate the table. Walk through the lists of sequences
|
||||||
|
starting with the same byte and add them one after the other to
|
||||||
|
the table. In case we have more than one sequence starting with
|
||||||
|
the same byte we have to use extra indirection. */
|
||||||
|
tablewc = (uint32_t *) alloca (table_size * sizeof (uint32_t));
|
||||||
|
for (ch = 0; ch < table_size; ++ch)
|
||||||
|
if (collate->wcheads[ch] == NULL)
|
||||||
|
{
|
||||||
|
/* Set the entry to zero. */
|
||||||
|
tablewc[ch] = 0;
|
||||||
|
}
|
||||||
|
else if (collate->wcheads[ch]->wcnext == NULL
|
||||||
|
&& collate->wcheads[ch]->nwcs == 1)
|
||||||
|
{
|
||||||
|
tablewc[ch] = output_weightwc (&weightpool, collate,
|
||||||
|
collate->wcheads[ch]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* As for the singlebyte table, we recognize sequences and
|
||||||
|
compress them. */
|
||||||
|
struct element_t *runp = collate->wcheads[ch];
|
||||||
|
struct element_t *lastp;
|
||||||
|
|
||||||
|
tablewc[ch] = -obstack_object_size (&extrapool);
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
/* Store the current index in the weight table. We know that
|
||||||
|
the current position in the `extrapool' is aligned on a
|
||||||
|
32-bit address. */
|
||||||
|
int32_t weightidx;
|
||||||
|
int added;
|
||||||
|
|
||||||
|
/* Output the weight info. */
|
||||||
|
weightidx = output_weightwc (&weightpool, collate, runp);
|
||||||
|
|
||||||
|
/* Find out wether this is a single entry or we have more than
|
||||||
|
one consecutive entry. */
|
||||||
|
if (runp->wcnext != NULL
|
||||||
|
&& runp->nwcs == runp->wcnext->nwcs
|
||||||
|
&& wmemcmp ((wchar_t *) runp->wcs,
|
||||||
|
(wchar_t *)runp->wcnext->wcs, runp->nwcs - 1) == 0
|
||||||
|
&& (runp->wcs[runp->nwcs - 1] + 1
|
||||||
|
== runp->wcnext->wcs[runp->nwcs - 1]))
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* Now add first the initial byte sequence. */
|
||||||
|
added = (1 + 1 + 2 * (runp->nwcs - 1)) * sizeof (int32_t);
|
||||||
|
if (sizeof (int32_t) == sizeof (int))
|
||||||
|
obstack_make_room (&extrapool, added);
|
||||||
|
|
||||||
|
/* More than one consecutive entry. We mark this by having
|
||||||
|
a negative index into the indirect table. */
|
||||||
|
if (sizeof (int32_t) == sizeof (int))
|
||||||
|
{
|
||||||
|
obstack_int_grow_fast (&extrapool,
|
||||||
|
obstack_object_size (&indirectpool)
|
||||||
|
/ sizeof (int32_t));
|
||||||
|
obstack_int_grow_fast (&extrapool, runp->nwcs - 1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int32_t i = (obstack_object_size (&indirectpool)
|
||||||
|
/ sizeof (int32_t));
|
||||||
|
obstack_grow (&extrapool, &i, sizeof (int32_t));
|
||||||
|
i = runp->nwcs - 1;
|
||||||
|
obstack_grow (&extrapool, &i, sizeof (int32_t));
|
||||||
|
}
|
||||||
|
for (i = 1; i < runp->nwcs; ++i)
|
||||||
|
if (sizeof (int32_t) == sizeof (int))
|
||||||
|
obstack_int_grow_fast (&extrapool, runp->wcs[i]);
|
||||||
|
else
|
||||||
|
obstack_grow (&extrapool, &runp->wcs[i], sizeof (int32_t));
|
||||||
|
|
||||||
|
/* Now find the end of the consecutive sequence and
|
||||||
|
add all the indeces in the indirect pool. */
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
if (sizeof (int32_t) == sizeof (int))
|
||||||
|
obstack_int_grow (&extrapool, weightidx);
|
||||||
|
else
|
||||||
|
obstack_grow (&extrapool, &weightidx, sizeof (int32_t));
|
||||||
|
|
||||||
|
runp = runp->next;
|
||||||
|
if (runp->wcnext == NULL
|
||||||
|
|| runp->nwcs != runp->wcnext->nwcs
|
||||||
|
|| wmemcmp ((wchar_t *) runp->wcs,
|
||||||
|
(wchar_t *) runp->wcnext->wcs,
|
||||||
|
runp->nwcs - 1) != 0
|
||||||
|
|| (runp->wcs[runp->nwcs - 1] + 1
|
||||||
|
!= runp->wcnext->wcs[runp->nwcs - 1]))
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* Insert the weight. */
|
||||||
|
weightidx = output_weightwc (&weightpool, collate, runp);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* And add the end byte sequence. Without length this
|
||||||
|
time. */
|
||||||
|
for (i = 1; i < runp->nwcs; ++i)
|
||||||
|
if (sizeof (int32_t) == sizeof (int))
|
||||||
|
obstack_int_grow (&extrapool, runp->wcs[i]);
|
||||||
|
else
|
||||||
|
obstack_grow (&extrapool, &runp->wcs[i], sizeof (int32_t));
|
||||||
|
|
||||||
|
weightidx = output_weightwc (&weightpool, collate, runp);
|
||||||
|
if (sizeof (int32_t) == sizeof (int))
|
||||||
|
obstack_int_grow (&extrapool, weightidx);
|
||||||
|
else
|
||||||
|
obstack_grow (&extrapool, &weightidx, sizeof (int32_t));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* A single entry. Simply add the index and the length and
|
||||||
|
string (except for the first character which is already
|
||||||
|
tested for). */
|
||||||
|
int i;
|
||||||
|
|
||||||
|
added = (1 + 1 + runp->nwcs - 1) * sizeof (int32_t);
|
||||||
|
if (sizeof (int) == sizeof (int32_t))
|
||||||
|
obstack_make_room (&extrapool, added);
|
||||||
|
|
||||||
|
if (sizeof (int32_t) == sizeof (int))
|
||||||
|
{
|
||||||
|
obstack_int_grow_fast (&extrapool, weightidx);
|
||||||
|
obstack_int_grow_fast (&extrapool, runp->nwcs - 1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int32_t l = runp->nwcs - 1;
|
||||||
|
obstack_grow (&extrapool, &weightidx, sizeof (int32_t));
|
||||||
|
obstack_grow (&extrapool, &l, sizeof (int32_t));
|
||||||
|
}
|
||||||
|
for (i = 1; i < runp->nwcs; ++i)
|
||||||
|
if (sizeof (int32_t) == sizeof (int))
|
||||||
|
obstack_int_grow_fast (&extrapool, runp->wcs[i]);
|
||||||
|
else
|
||||||
|
obstack_grow (&extrapool, &runp->wcs[i], sizeof (int32_t));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Next entry. */
|
||||||
|
lastp = runp;
|
||||||
|
runp = runp->wcnext;
|
||||||
|
}
|
||||||
|
while (runp != NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now add the four tables. */
|
||||||
|
assert (cnt == _NL_ITEM_INDEX (_NL_COLLATE_TABLEWC));
|
||||||
|
iov[2 + cnt].iov_base = tablewc;
|
||||||
|
iov[2 + cnt].iov_len = table_size * sizeof (int32_t);
|
||||||
|
idx[1 + cnt] = idx[cnt] + iov[2 + cnt].iov_len;
|
||||||
|
++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;
|
||||||
|
++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;
|
||||||
|
++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;
|
||||||
|
++cnt;
|
||||||
|
|
||||||
|
|
||||||
assert (cnt == _NL_ITEM_INDEX (_NL_NUM_LC_COLLATE));
|
assert (cnt == _NL_ITEM_INDEX (_NL_NUM_LC_COLLATE));
|
||||||
|
|
||||||
write_locale_data (output_path, "LC_COLLATE", 2 + cnt, iov);
|
write_locale_data (output_path, "LC_COLLATE", 2 + cnt, iov);
|
||||||
|
@ -2937,16 +2937,29 @@ allocate_arrays (struct locale_ctype_t *ctype, struct charmap_t *charmap,
|
|||||||
table. CH % TABSIZE is used as an index. To solve multiple hits
|
table. CH % TABSIZE is used as an index. To solve multiple hits
|
||||||
we have N planes. This guarantees a fixed search time for a
|
we have N planes. This guarantees a fixed search time for a
|
||||||
character [N / 2]. In the following code we determine the minimum
|
character [N / 2]. In the following code we determine the minimum
|
||||||
value for TABSIZE * N, where TABSIZE >= 256. */
|
value for TABSIZE * N, where TABSIZE >= 256.
|
||||||
|
|
||||||
|
Some people complained that this algorithm takes too long. Well,
|
||||||
|
go on, improve it. But changing the step size is *not* an
|
||||||
|
option. Some people changed this to use only sizes of prime
|
||||||
|
numbers. Think again, do some math. We are looking for the
|
||||||
|
optimal solution, not something which works in general. Unless
|
||||||
|
somebody can provide a dynamic programming solution I think this
|
||||||
|
implementation is as good as it can get. */
|
||||||
size_t min_total = UINT_MAX;
|
size_t min_total = UINT_MAX;
|
||||||
size_t act_size = 256;
|
size_t act_size = 256;
|
||||||
|
|
||||||
if (!be_quiet)
|
if (!be_quiet && ctype->charnames_act > 512)
|
||||||
fputs (_("\
|
fputs (_("\
|
||||||
Computing table size for character classes might take a while..."),
|
Computing table size for character classes might take a while..."),
|
||||||
stderr);
|
stderr);
|
||||||
|
|
||||||
while (act_size < min_total)
|
/* While we want to have a small total size we are willing to use a
|
||||||
|
little bit larger table if this reduces the number of layers.
|
||||||
|
Therefore we add a little penalty to the number of planes.
|
||||||
|
Maybe this constant has to be adjusted a bit. */
|
||||||
|
#define PENALTY 128
|
||||||
|
do
|
||||||
{
|
{
|
||||||
size_t cnt[act_size];
|
size_t cnt[act_size];
|
||||||
size_t act_planes = 1;
|
size_t act_planes = 1;
|
||||||
@ -2964,22 +2977,23 @@ Computing table size for character classes might take a while..."),
|
|||||||
if (++cnt[nr] > act_planes)
|
if (++cnt[nr] > act_planes)
|
||||||
{
|
{
|
||||||
act_planes = cnt[nr];
|
act_planes = cnt[nr];
|
||||||
if (act_size * act_planes >= min_total)
|
if ((act_size + PENALTY) * act_planes >= min_total)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (act_size * act_planes < min_total)
|
if ((act_size + PENALTY) * act_planes < min_total)
|
||||||
{
|
{
|
||||||
min_total = act_size * act_planes;
|
min_total = (act_size + PENALTY) * act_planes;
|
||||||
ctype->plane_size = act_size;
|
ctype->plane_size = act_size;
|
||||||
ctype->plane_cnt = act_planes;
|
ctype->plane_cnt = act_planes;
|
||||||
}
|
}
|
||||||
|
|
||||||
++act_size;
|
++act_size;
|
||||||
}
|
}
|
||||||
|
while (act_size < min_total);
|
||||||
|
|
||||||
if (!be_quiet)
|
if (!be_quiet && ctype->charnames_act > 512)
|
||||||
fputs (_(" done\n"), stderr);
|
fputs (_(" done\n"), stderr);
|
||||||
|
|
||||||
|
|
||||||
|
@ -57,7 +57,7 @@ CPPFLAGS += -Dgethostbyname=res_gethostbyname \
|
|||||||
-Dgetnetbyaddr=res_getnetbyaddr
|
-Dgetnetbyaddr=res_getnetbyaddr
|
||||||
|
|
||||||
# The BIND code elicits some harmless warnings.
|
# The BIND code elicits some harmless warnings.
|
||||||
+cflags += -Wno-strict-prototypes -Wno-comment -Wno-write-strings
|
+cflags += -Wno-strict-prototypes -Wno-write-strings
|
||||||
|
|
||||||
# Depend on libc.so so a DT_NEEDED is generated in the shared objects.
|
# Depend on libc.so so a DT_NEEDED is generated in the shared objects.
|
||||||
# This ensures they will load libc.so for needed symbols if loaded by
|
# This ensures they will load libc.so for needed symbols if loaded by
|
||||||
|
@ -38,9 +38,6 @@ static const char rcsid[] = "$Id$";
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#undef _res
|
|
||||||
|
|
||||||
struct __res_state _res;
|
|
||||||
|
|
||||||
/* This is the old res_init function. It has been moved from
|
/* This is the old res_init function. It has been moved from
|
||||||
res_data.c to this file since res_init should go into libc.so but
|
res_data.c to this file since res_init should go into libc.so but
|
||||||
@ -90,6 +87,11 @@ res_init(void) {
|
|||||||
/* We need a resolver context - in unthreaded apps, this weak function
|
/* We need a resolver context - in unthreaded apps, this weak function
|
||||||
provides it. */
|
provides it. */
|
||||||
|
|
||||||
|
#undef _res
|
||||||
|
|
||||||
|
struct __res_state _res;
|
||||||
|
|
||||||
|
|
||||||
struct __res_state *
|
struct __res_state *
|
||||||
weak_const_function
|
weak_const_function
|
||||||
__res_state(void)
|
__res_state(void)
|
||||||
|
@ -136,19 +136,19 @@ struct __res_state; /* forward */
|
|||||||
typedef enum { res_goahead, res_nextns, res_modified, res_done, res_error }
|
typedef enum { res_goahead, res_nextns, res_modified, res_done, res_error }
|
||||||
res_sendhookact;
|
res_sendhookact;
|
||||||
|
|
||||||
typedef res_sendhookact (*res_send_qhook)__P((struct sockaddr_in * const *ns,
|
typedef res_sendhookact (*res_send_qhook) (struct sockaddr_in * const *ns,
|
||||||
const u_char **query,
|
const u_char **query,
|
||||||
int *querylen,
|
int *querylen,
|
||||||
u_char *ans,
|
u_char *ans,
|
||||||
int anssiz,
|
int anssiz,
|
||||||
int *resplen));
|
int *resplen);
|
||||||
|
|
||||||
typedef res_sendhookact (*res_send_rhook)__P((const struct sockaddr_in *ns,
|
typedef res_sendhookact (*res_send_rhook) (const struct sockaddr_in *ns,
|
||||||
const u_char *query,
|
const u_char *query,
|
||||||
int querylen,
|
int querylen,
|
||||||
u_char *ans,
|
u_char *ans,
|
||||||
int anssiz,
|
int anssiz,
|
||||||
int *resplen));
|
int *resplen);
|
||||||
|
|
||||||
struct res_sym {
|
struct res_sym {
|
||||||
int number; /* Identifying number, like T_MX */
|
int number; /* Identifying number, like T_MX */
|
||||||
@ -270,20 +270,20 @@ extern struct __res_state _res;
|
|||||||
#define res_send __res_send
|
#define res_send __res_send
|
||||||
|
|
||||||
__BEGIN_DECLS
|
__BEGIN_DECLS
|
||||||
void fp_nquery __P((const u_char *, int, FILE *));
|
void fp_nquery (const u_char *, int, FILE *) __THROW;
|
||||||
void fp_query __P((const u_char *, FILE *));
|
void fp_query (const u_char *, FILE *) __THROW;
|
||||||
const char * hostalias __P((const char *));
|
const char * hostalias (const char *) __THROW;
|
||||||
void p_query __P((const u_char *));
|
void p_query (const u_char *) __THROW;
|
||||||
void res_close __P((void));
|
void res_close (void) __THROW;
|
||||||
int res_init __P((void));
|
int res_init (void) __THROW;
|
||||||
int res_isourserver __P((const struct sockaddr_in *));
|
int res_isourserver (const struct sockaddr_in *) __THROW;
|
||||||
int res_mkquery __P((int, const char *, int, int, const u_char *,
|
int res_mkquery (int, const char *, int, int, const u_char *,
|
||||||
int, const u_char *, u_char *, int));
|
int, const u_char *, u_char *, int) __THROW;
|
||||||
int res_query __P((const char *, int, int, u_char *, int));
|
int res_query (const char *, int, int, u_char *, int) __THROW;
|
||||||
int res_querydomain __P((const char *, const char *, int, int,
|
int res_querydomain (const char *, const char *, int, int,
|
||||||
u_char *, int));
|
u_char *, int) __THROW;
|
||||||
int res_search __P((const char *, int, int, u_char *, int));
|
int res_search (const char *, int, int, u_char *, int) __THROW;
|
||||||
int res_send __P((const u_char *, int, u_char *, int));
|
int res_send (const u_char *, int, u_char *, int) __THROW;
|
||||||
__END_DECLS
|
__END_DECLS
|
||||||
|
|
||||||
#if !defined(SHARED_LIBBIND) || defined(_LIBC)
|
#if !defined(SHARED_LIBBIND) || defined(_LIBC)
|
||||||
|
Loading…
Reference in New Issue
Block a user