aboutsummaryrefslogtreecommitdiff
path: root/locale/programs/ld-ctype.c
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2000-08-29 01:20:23 +0000
committerUlrich Drepper <drepper@redhat.com>2000-08-29 01:20:23 +0000
commit04ea3b0fbb9ca56a04b437c57c2878842d331c77 (patch)
tree3f03f09731b5185c8a25609af1507866ca5783e9 /locale/programs/ld-ctype.c
parent50fd913bece94eba2aa8394b1b6958708e4dcd4d (diff)
downloadglibc-04ea3b0fbb9ca56a04b437c57c2878842d331c77.zip
glibc-04ea3b0fbb9ca56a04b437c57c2878842d331c77.tar.gz
glibc-04ea3b0fbb9ca56a04b437c57c2878842d331c77.tar.bz2
Update.
2000-08-27 Bruno Haible <haible@clisp.cons.org> * string/strxfrm.c (strxfrm, wcsxfrm): Include <sys/param.h>. If nrules == 0 and srclen < n, copy only srclen + 1 characters. * sysdeps/generic/getdomain.c (getdomainname): Include <sys/param.h>. If the result is fits in the buffer, copy only as many bytes as needed. * sysdeps/generic/_strerror.c (__strerror_r): Don't zero-fill the buffer after copying numbuf into it. * sysdeps/mach/_strerror.c (__strerror_r): Likewise. 2000-08-27 Bruno Haible <haible@clisp.cons.org> * posix/confstr.c (confstr): When string_len > len, NUL-terminate the result. When string_len < len, don't clear the rest of the buffer. 2000-08-27 Bruno Haible <haible@clisp.cons.org> Support for new LC_COLLATE format. * locale/coll-lookup.h: New file. * locale/weightwc.h (findidx): When size == 0, call collidx_table_lookup. * wcsmbs/wcscoll.c: Include coll-lookup.h. * wcsmbs/wcsxfrm.c: Likewise. * posix/fnmatch.c: Likewise. * posix/fnmatch_loop.c (internal_fnwmatch): When size == 0, call collseq_table_lookup. * locale/programs/3level.h: New file. * locale/programs/ld-ctype.c: (wcwidth_table, wctrans_table): Define by including "3level.h". * locale/programs/ld-collate.c (wchead_table, collidx_table, collseq_table): New types, defined by including "3level.h". (locale_collate_t): New wcheads_3level, wcseqorder_3level fields. (encoding_mask, encoding_byte): Remove. (utf8_encode): Use simple shifts instead. (collate_finish): When !oldstyle_tables, set plane_size and plane_cnt to 0, and initialize and fill wcheads_3level and wcseqorder_3level. (collate_output): New local variable tablewc_3level. When !oldstyle_tables, set table_size to 0 and names to NULL and fill tablewc_3level instead of tablewc. Change format of TABLEWC and COLLSEQWC entries written to the file. * locale/C-collate.c (collseqwc): Change format. (_nl_C_LC_COLLATE): Set HASH_SIZE and HASH_LAYERS to 0, change format of COLLSEQWC. * locale/Makefile (distribute): Add coll-lookup.h, programs/3level.h. 2000-08-27 Bruno Haible <haible@clisp.cons.org> * locale/programs/ld-ctype.c (MAX_CHARNAMES_IDX): New macro. (locale_ctype_t): New charnames_idx field. (ctype_startup): Initialize charnames_idx field. (find_idx): Speed up dramatically by using charnames_idx inverse table. 2000-08-27 Bruno Haible <haible@clisp.cons.org> * locale/C-ctype.c: Switch to new locale format. (_nl_C_LC_CTYPE_names): Remove array. (STRUCT_CTYPE_CLASS): New macro. (_nl_C_LC_CTYPE_class_{upper,lower,alpha,digit,xdigit,space,print, graph,blank,cntrl,punct,alnum}, _nl_C_LC_CTYPE_map_{toupper,tolower}): New three-level tables. (_nl_C_LC_CTYPE_width): Change from array to three-level table. (_nl_C_LC_CTYPE): Fix nstrings value. Set HASH_SIZE and HASH_LAYERS to 0. Change WIDTH format. Set CLASS_OFFSET and MAP_OFFSET. Add 12 class tables and 2 map tables at the end. * ctype/ctype-info.c (_nl_C_LC_CTYPE_names): Remove declaration. (_nl_C_LC_CTYPE_class_{upper,lower,alpha,digit,xdigit,space,print, graph,blank,cntrl,punct,alnum}, _nl_C_LC_CTYPE_map_{toupper,tolower}): New declarations. (b): Remove trailing semicolon. (__ctype_names, __ctype_width): Don't initialize. (__ctype32_wctype, __ctype32_wctrans, __ctype32_width): Initialize. 2000-08-27 Bruno Haible <haible@clisp.cons.org> * elf/dl-load.c (open_path): Add a argument telling whether *dirsp is guaranteed to be allocated with the same malloc() and may be passed to free(). (_dl_map_object): Update open_path calls. If rtld_search_dirs has been set to empty by an earlier open_path call, don't pass it again.
Diffstat (limited to 'locale/programs/ld-ctype.c')
-rw-r--r--locale/programs/ld-ctype.c507
1 files changed, 40 insertions, 467 deletions
diff --git a/locale/programs/ld-ctype.c b/locale/programs/ld-ctype.c
index e2d76b0..1f40fe8 100644
--- a/locale/programs/ld-ctype.c
+++ b/locale/programs/ld-ctype.c
@@ -112,6 +112,9 @@ struct locale_ctype_t
uint32_t *charnames;
size_t charnames_max;
size_t charnames_act;
+ /* An index lookup table, to speedup find_idx. */
+#define MAX_CHARNAMES_IDX 0x10000
+ uint32_t *charnames_idx;
struct repertoire_t *repertoire;
@@ -253,6 +256,10 @@ ctype_startup (struct linereader *lr, struct localedef_t *locale,
for (cnt = 0; cnt < 256; ++cnt)
ctype->charnames[cnt] = cnt;
ctype->charnames_act = 256;
+ ctype->charnames_idx =
+ (uint32_t *) xmalloc (MAX_CHARNAMES_IDX * sizeof (uint32_t));
+ for (cnt = 0; cnt < MAX_CHARNAMES_IDX; ++cnt)
+ ctype->charnames_idx[cnt] = ~((uint32_t) 0);
/* Fill character class information. */
ctype->last_class_char = ILLEGAL_CHAR_VALUE;
@@ -1299,9 +1306,23 @@ find_idx (struct locale_ctype_t *ctype, uint32_t **table, size_t *max,
if (idx < 256)
return table == NULL ? NULL : &(*table)[idx];
- for (cnt = 256; cnt < ctype->charnames_act; ++cnt)
- if (ctype->charnames[cnt] == idx)
- break;
+ /* If idx is in the usual range, use the charnames_idx lookup table
+ instead of the slow search loop. */
+ if (idx < MAX_CHARNAMES_IDX)
+ {
+ if (ctype->charnames_idx[idx] != ~((uint32_t) 0))
+ /* Found. */
+ cnt = ctype->charnames_idx[idx];
+ else
+ /* Not found. */
+ cnt = ctype->charnames_act;
+ }
+ else
+ {
+ for (cnt = 256; cnt < ctype->charnames_act; ++cnt)
+ if (ctype->charnames[cnt] == idx)
+ break;
+ }
/* We have to distinguish two cases: the name is found or not. */
if (cnt == ctype->charnames_act)
@@ -1315,6 +1336,8 @@ find_idx (struct locale_ctype_t *ctype, uint32_t **table, size_t *max,
sizeof (uint32_t) * ctype->charnames_max);
}
ctype->charnames[ctype->charnames_act++] = idx;
+ if (idx < MAX_CHARNAMES_IDX)
+ ctype->charnames_idx[idx] = cnt;
}
if (table == NULL)
@@ -3582,473 +3605,23 @@ wctype_table_finalize (struct wctype_table *t)
free (t->level3);
}
-struct wcwidth_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;
- uint8_t *level3;
- /* Compressed representation. */
- size_t result_size;
- char *result;
-};
-
-/* Initialize. Assumes t->p and t->q have already been set. */
+#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
-wcwidth_table_init (struct wcwidth_table *t)
-{
- t->level1_alloc = t->level1_size = 0;
- t->level2_alloc = t->level2_size = 0;
- t->level3_alloc = t->level3_size = 0;
-}
-
-/* Retrieve an entry. */
-static inline uint8_t
-wcwidth_table_get (struct wcwidth_table *t, uint32_t wc)
-{
- uint32_t index1 = wc >> (t->q + t->p);
- if (index1 < t->level1_size)
- {
- uint32_t lookup1 = t->level1[index1];
- if (lookup1 != ~((uint32_t) 0))
- {
- uint32_t index2 = ((wc >> t->p) & ((1 << t->q) - 1))
- + (lookup1 << t->q);
- uint32_t lookup2 = t->level2[index2];
- if (lookup2 != ~((uint32_t) 0))
- {
- uint32_t index3 = (wc & ((1 << t->p) - 1))
- + (lookup2 << t->p);
- uint8_t lookup3 = t->level3[index3];
-
- return lookup3;
- }
- }
- }
- return 0xff;
-}
-
-/* Add one entry. */
-static void
-wcwidth_table_add (struct wcwidth_table *t, uint32_t wc, uint8_t width)
-{
- uint32_t index1 = wc >> (t->q + t->p);
- uint32_t index2 = (wc >> t->p) & ((1 << t->q) - 1);
- uint32_t index3 = wc & ((1 << t->p) - 1);
- size_t i, i1, i2;
-
- if (width == wcwidth_table_get (t, wc))
- return;
-
- if (index1 >= t->level1_size)
- {
- if (index1 >= t->level1_alloc)
- {
- size_t alloc = 2 * t->level1_alloc;
- if (alloc <= index1)
- alloc = index1 + 1;
- t->level1 = (t->level1_alloc > 0
- ? (uint32_t *) xrealloc ((char *) t->level1,
- alloc * sizeof (uint32_t))
- : (uint32_t *) xmalloc (alloc * sizeof (uint32_t)));
- t->level1_alloc = alloc;
- }
- while (index1 >= t->level1_size)
- t->level1[t->level1_size++] = ~((uint32_t) 0);
- }
-
- if (t->level1[index1] == ~((uint32_t) 0))
- {
- if (t->level2_size == t->level2_alloc)
- {
- size_t alloc = 2 * t->level2_alloc + 1;
- t->level2 = (t->level2_alloc > 0
- ? (uint32_t *) xrealloc ((char *) t->level2,
- (alloc << t->q) * sizeof (uint32_t))
- : (uint32_t *) xmalloc ((alloc << t->q) * sizeof (uint32_t)));
- t->level2_alloc = alloc;
- }
- i1 = t->level2_size << t->q;
- i2 = (t->level2_size + 1) << t->q;
- for (i = i1; i < i2; i++)
- t->level2[i] = ~((uint32_t) 0);
- t->level1[index1] = t->level2_size++;
- }
-
- index2 += t->level1[index1] << t->q;
-
- if (t->level2[index2] == ~((uint32_t) 0))
- {
- if (t->level3_size == t->level3_alloc)
- {
- size_t alloc = 2 * t->level3_alloc + 1;
- t->level3 = (t->level3_alloc > 0
- ? (uint8_t *) xrealloc ((char *) t->level3,
- (alloc << t->p) * sizeof (uint8_t))
- : (uint8_t *) xmalloc ((alloc << t->p) * sizeof (uint8_t)));
- t->level3_alloc = alloc;
- }
- i1 = t->level3_size << t->p;
- i2 = (t->level3_size + 1) << t->p;
- for (i = i1; i < i2; i++)
- t->level3[i] = 0xff;
- t->level2[index2] = t->level3_size++;
- }
-
- index3 += t->level2[index2] << t->p;
-
- t->level3[index3] = width;
-}
-
-/* Finalize and shrink. */
-static void
-wcwidth_table_finalize (struct wcwidth_table *t)
-{
- size_t i, j, k;
- uint32_t reorder3[t->level3_size];
- uint32_t reorder2[t->level2_size];
- uint32_t level1_offset, level2_offset, level3_offset, last_offset;
-
- /* Uniquify level3 blocks. */
- k = 0;
- for (j = 0; j < t->level3_size; j++)
- {
- for (i = 0; i < k; i++)
- if (memcmp (&t->level3[i << t->p], &t->level3[j << t->p],
- (1 << t->p) * sizeof (uint8_t)) == 0)
- break;
- /* Relocate block j to block i. */
- reorder3[j] = i;
- if (i == k)
- {
- if (i != j)
- memcpy (&t->level3[i << t->p], &t->level3[j << t->p],
- (1 << t->p) * sizeof (uint8_t));
- k++;
- }
- }
- t->level3_size = k;
-
- for (i = 0; i < (t->level2_size << t->q); i++)
- if (t->level2[i] != ~((uint32_t) 0))
- t->level2[i] = reorder3[t->level2[i]];
-
- /* Uniquify level2 blocks. */
- k = 0;
- for (j = 0; j < t->level2_size; j++)
- {
- for (i = 0; i < k; i++)
- if (memcmp (&t->level2[i << t->q], &t->level2[j << t->q],
- (1 << t->q) * sizeof (uint32_t)) == 0)
- break;
- /* Relocate block j to block i. */
- reorder2[j] = i;
- if (i == k)
- {
- if (i != j)
- memcpy (&t->level2[i << t->q], &t->level2[j << t->q],
- (1 << t->q) * sizeof (uint32_t));
- k++;
- }
- }
- t->level2_size = k;
-
- for (i = 0; i < t->level1_size; i++)
- if (t->level1[i] != ~((uint32_t) 0))
- t->level1[i] = reorder2[t->level1[i]];
-
- /* Create and fill the resulting compressed representation. */
- last_offset =
- 5 * sizeof (uint32_t)
- + t->level1_size * sizeof (uint32_t)
- + (t->level2_size << t->q) * sizeof (uint32_t)
- + (t->level3_size << t->p) * sizeof (uint8_t);
- t->result_size = (last_offset + 3) & ~3ul;
- t->result = (char *) xmalloc (t->result_size);
-
- level1_offset =
- 5 * sizeof (uint32_t);
- level2_offset =
- 5 * sizeof (uint32_t)
- + t->level1_size * sizeof (uint32_t);
- level3_offset =
- 5 * sizeof (uint32_t)
- + t->level1_size * sizeof (uint32_t)
- + (t->level2_size << t->q) * sizeof (uint32_t);
-
- ((uint32_t *) t->result)[0] = t->q + t->p;
- ((uint32_t *) t->result)[1] = t->level1_size;
- ((uint32_t *) t->result)[2] = t->p;
- ((uint32_t *) t->result)[3] = (1 << t->q) - 1;
- ((uint32_t *) t->result)[4] = (1 << t->p) - 1;
-
- for (i = 0; i < t->level1_size; i++)
- ((uint32_t *) (t->result + level1_offset))[i] =
- (t->level1[i] == ~((uint32_t) 0)
- ? 0
- : (t->level1[i] << t->q) * sizeof (uint32_t) + level2_offset);
-
- for (i = 0; i < (t->level2_size << t->q); i++)
- ((uint32_t *) (t->result + level2_offset))[i] =
- (t->level2[i] == ~((uint32_t) 0)
- ? 0
- : (t->level2[i] << t->p) * sizeof (uint8_t) + level3_offset);
-
- for (i = 0; i < (t->level3_size << t->p); i++)
- ((uint8_t *) (t->result + level3_offset))[i] = t->level3[i];
-
- if (last_offset < t->result_size)
- memset (t->result + last_offset, 0, t->result_size - last_offset);
-
- if (t->level1_alloc > 0)
- free (t->level1);
- if (t->level2_alloc > 0)
- free (t->level2);
- if (t->level3_alloc > 0)
- free (t->level3);
-}
-
-struct wctrans_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;
- int32_t *level3;
- /* Compressed representation. */
- size_t result_size;
- char *result;
-};
-
-/* Initialize. Assumes t->p and t->q have already been set. */
-static inline void
-wctrans_table_init (struct wctrans_table *t)
-{
- t->level1_alloc = t->level1_size = 0;
- t->level2_alloc = t->level2_size = 0;
- t->level3_alloc = t->level3_size = 0;
-}
-
-/* Retrieve an entry. */
-static inline uint32_t
-wctrans_table_get (struct wctrans_table *t, uint32_t wc)
-{
- uint32_t index1 = wc >> (t->q + t->p);
- if (index1 < t->level1_size)
- {
- uint32_t lookup1 = t->level1[index1];
- if (lookup1 != ~((uint32_t) 0))
- {
- uint32_t index2 = ((wc >> t->p) & ((1 << t->q) - 1))
- + (lookup1 << t->q);
- uint32_t lookup2 = t->level2[index2];
- if (lookup2 != ~((uint32_t) 0))
- {
- uint32_t index3 = (wc & ((1 << t->p) - 1))
- + (lookup2 << t->p);
- int32_t lookup3 = t->level3[index3];
-
- return wc + lookup3;
- }
- }
- }
- return wc;
-}
-
-/* Add one entry. */
-static void
wctrans_table_add (struct wctrans_table *t, uint32_t wc, uint32_t mapped_wc)
{
- uint32_t index1 = wc >> (t->q + t->p);
- uint32_t index2 = (wc >> t->p) & ((1 << t->q) - 1);
- uint32_t index3 = wc & ((1 << t->p) - 1);
- int32_t value;
- size_t i, i1, i2;
-
- if (mapped_wc == wctrans_table_get (t, wc))
- return;
-
- value = (int32_t) mapped_wc - (int32_t) wc;
-
- if (index1 >= t->level1_size)
- {
- if (index1 >= t->level1_alloc)
- {
- size_t alloc = 2 * t->level1_alloc;
- if (alloc <= index1)
- alloc = index1 + 1;
- t->level1 = (t->level1_alloc > 0
- ? (uint32_t *) xrealloc ((char *) t->level1,
- alloc * sizeof (uint32_t))
- : (uint32_t *) xmalloc (alloc * sizeof (uint32_t)));
- t->level1_alloc = alloc;
- }
- while (index1 >= t->level1_size)
- t->level1[t->level1_size++] = ~((uint32_t) 0);
- }
-
- if (t->level1[index1] == ~((uint32_t) 0))
- {
- if (t->level2_size == t->level2_alloc)
- {
- size_t alloc = 2 * t->level2_alloc + 1;
- t->level2 = (t->level2_alloc > 0
- ? (uint32_t *) xrealloc ((char *) t->level2,
- (alloc << t->q) * sizeof (uint32_t))
- : (uint32_t *) xmalloc ((alloc << t->q) * sizeof (uint32_t)));
- t->level2_alloc = alloc;
- }
- i1 = t->level2_size << t->q;
- i2 = (t->level2_size + 1) << t->q;
- for (i = i1; i < i2; i++)
- t->level2[i] = ~((uint32_t) 0);
- t->level1[index1] = t->level2_size++;
- }
-
- index2 += t->level1[index1] << t->q;
-
- if (t->level2[index2] == ~((uint32_t) 0))
- {
- if (t->level3_size == t->level3_alloc)
- {
- size_t alloc = 2 * t->level3_alloc + 1;
- t->level3 = (t->level3_alloc > 0
- ? (int32_t *) xrealloc ((char *) t->level3,
- (alloc << t->p) * sizeof (int32_t))
- : (int32_t *) xmalloc ((alloc << t->p) * sizeof (int32_t)));
- t->level3_alloc = alloc;
- }
- i1 = t->level3_size << t->p;
- i2 = (t->level3_size + 1) << t->p;
- for (i = i1; i < i2; i++)
- t->level3[i] = 0;
- t->level2[index2] = t->level3_size++;
- }
-
- index3 += t->level2[index2] << t->p;
-
- t->level3[index3] = value;
-}
-
-/* Finalize and shrink. */
-static void
-wctrans_table_finalize (struct wctrans_table *t)
-{
- size_t i, j, k;
- uint32_t reorder3[t->level3_size];
- uint32_t reorder2[t->level2_size];
- uint32_t level1_offset, level2_offset, level3_offset;
-
- /* Uniquify level3 blocks. */
- k = 0;
- for (j = 0; j < t->level3_size; j++)
- {
- for (i = 0; i < k; i++)
- if (memcmp (&t->level3[i << t->p], &t->level3[j << t->p],
- (1 << t->p) * sizeof (int32_t)) == 0)
- break;
- /* Relocate block j to block i. */
- reorder3[j] = i;
- if (i == k)
- {
- if (i != j)
- memcpy (&t->level3[i << t->p], &t->level3[j << t->p],
- (1 << t->p) * sizeof (int32_t));
- k++;
- }
- }
- t->level3_size = k;
-
- for (i = 0; i < (t->level2_size << t->q); i++)
- if (t->level2[i] != ~((uint32_t) 0))
- t->level2[i] = reorder3[t->level2[i]];
-
- /* Uniquify level2 blocks. */
- k = 0;
- for (j = 0; j < t->level2_size; j++)
- {
- for (i = 0; i < k; i++)
- if (memcmp (&t->level2[i << t->q], &t->level2[j << t->q],
- (1 << t->q) * sizeof (uint32_t)) == 0)
- break;
- /* Relocate block j to block i. */
- reorder2[j] = i;
- if (i == k)
- {
- if (i != j)
- memcpy (&t->level2[i << t->q], &t->level2[j << t->q],
- (1 << t->q) * sizeof (uint32_t));
- k++;
- }
- }
- t->level2_size = k;
-
- for (i = 0; i < t->level1_size; i++)
- if (t->level1[i] != ~((uint32_t) 0))
- t->level1[i] = reorder2[t->level1[i]];
-
- /* Create and fill the resulting compressed representation. */
- t->result_size =
- 5 * sizeof (uint32_t)
- + t->level1_size * sizeof (uint32_t)
- + (t->level2_size << t->q) * sizeof (uint32_t)
- + (t->level3_size << t->p) * sizeof (int32_t);
- t->result = (char *) xmalloc (t->result_size);
-
- level1_offset =
- 5 * sizeof (uint32_t);
- level2_offset =
- 5 * sizeof (uint32_t)
- + t->level1_size * sizeof (uint32_t);
- level3_offset =
- 5 * sizeof (uint32_t)
- + t->level1_size * sizeof (uint32_t)
- + (t->level2_size << t->q) * sizeof (uint32_t);
-
- ((uint32_t *) t->result)[0] = t->q + t->p;
- ((uint32_t *) t->result)[1] = t->level1_size;
- ((uint32_t *) t->result)[2] = t->p;
- ((uint32_t *) t->result)[3] = (1 << t->q) - 1;
- ((uint32_t *) t->result)[4] = (1 << t->p) - 1;
-
- for (i = 0; i < t->level1_size; i++)
- ((uint32_t *) (t->result + level1_offset))[i] =
- (t->level1[i] == ~((uint32_t) 0)
- ? 0
- : (t->level1[i] << t->q) * sizeof (uint32_t) + level2_offset);
-
- for (i = 0; i < (t->level2_size << t->q); i++)
- ((uint32_t *) (t->result + level2_offset))[i] =
- (t->level2[i] == ~((uint32_t) 0)
- ? 0
- : (t->level2[i] << t->p) * sizeof (int32_t) + level3_offset);
-
- for (i = 0; i < (t->level3_size << t->p); i++)
- ((int32_t *) (t->result + level3_offset))[i] = t->level3[i];
-
- if (t->level1_alloc > 0)
- free (t->level1);
- if (t->level2_alloc > 0)
- free (t->level2);
- if (t->level3_alloc > 0)
- free (t->level3);
+ wctrans_table_add_internal (t, wc, mapped_wc - wc);
}