* locale/programs/ld-collate.c (collate_output): Don't start with empty
	extrapool and indirectpool obstacks since we need the offsets to be
	nonzero.
	(collate_read): Call load_locale, not find_locale.
	* locale/programs/ld-ctype.c (ctype_finish): If LC_CTYPE category
	wasn't defined in the file also initialize repertoire if possible.
	* locale/programs/ld-time.c (time_finish): Fix message string.
	* locale/programs/linereader.c: Cast parameters of lr_error to
	correct type to prevnet warning.
	* locale/programs/localedef.c (load_locale): New file.
	* locale/programs/localedef.h: Add its prototype.
	* locale/programs/repertoire.c (repertoire_new_char): Add missing
	parameters to lr_error call.

	* localedata/Makefile: Enable running tests again.
	* localedata/tests/test2.def: Adjust syntax to new specification.
	* localedata/tests/test3.def: Likewise.
	* localedata/tst-trans.sh: Redirect output of program into file.

	* string/strcoll.c: Fix many error in new implementation to make it
	pass (at least) the test suite.

	* locale/Makefile: Don't link localedef statically anymore.

	* locale/ld-collate.c (struct element_t): Add field is_character and
	use it to distinguish real character from collating elements and
	symbols.
	* locale/programs/ld-time.c: Likewise.
This commit is contained in:
Ulrich Drepper 1999-12-27 05:05:12 +00:00
parent c392db7c4b
commit 70e51ab9f3
14 changed files with 353 additions and 277 deletions

View file

@ -1,7 +1,32 @@
1999-12-26 Ulrich Drepper <drepper@cygnus.com>
* ld-collate.c (struct element_t): Add field is_character and use it
to distinguish real character from collating elements and symbols.
* locale/programs/ld-collate.c (collate_output): Don't start with empty
extrapool and indirectpool obstacks since we need the offsets to be
nonzero.
(collate_read): Call load_locale, not find_locale.
* locale/programs/ld-ctype.c (ctype_finish): If LC_CTYPE category
wasn't defined in the file also initialize repertoire if possible.
* locale/programs/ld-time.c (time_finish): Fix message string.
* locale/programs/linereader.c: Cast parameters of lr_error to
correct type to prevnet warning.
* locale/programs/localedef.c (load_locale): New file.
* locale/programs/localedef.h: Add its prototype.
* locale/programs/repertoire.c (repertoire_new_char): Add missing
parameters to lr_error call.
* localedata/Makefile: Enable running tests again.
* localedata/tests/test2.def: Adjust syntax to new specification.
* localedata/tests/test3.def: Likewise.
* localedata/tst-trans.sh: Redirect output of program into file.
* string/strcoll.c: Fix many error in new implementation to make it
pass (at least) the test suite.
* locale/Makefile: Don't link localedef statically anymore.
* locale/ld-collate.c (struct element_t): Add field is_character and
use it to distinguish real character from collating elements and
symbols.
(new_element): Take new parameter to initialize is_character. Change
all callers.
(handle_ellipsis): Use is_character field to make sure ellipsis is
@ -29,6 +54,7 @@
* locale/programs/ld-numeric.c: Likewise.
* locale/programs/ld-paper.c: Likewise.
* locale/programs/ld-telephone.c: Likewise.
* locale/programs/ld-time.c: Likewise.
* locale/programs/locfile.c (write_locale_data): Correct memory
allocation for fname.

View file

@ -40,9 +40,8 @@ routines = setlocale findlocale loadlocale localeconv nl_langinfo \
categories = ctype messages monetary numeric time paper name \
address telephone measurement identification collate
aux = $(categories:%=lc-%) $(categories:%=C-%) SYS_libc C_name
# XXX For testing this is now others-static instead of others.
others = localedef locale
others-static = localedef locale
#others-static = localedef locale
install-bin = localedef locale
extra-objs = $(localedef-modules:=.o) $(locale-modules:=.o) \
$(lib-modules:=.o)

View file

@ -1677,6 +1677,21 @@ collate_output (struct localedef_t *locale, struct charmap_t *charmap,
obstack_init (&extrapool);
obstack_init (&indirectpool);
/* Since we are using the sign of an integer to mark indirection the
offsets in the arrays we are indirectly referring to must not be
zero since -0 == 0. Therefore we add a bit of dummy content. */
if (sizeof (int) == sizeof (int32_t))
{
obstack_int_grow (&extrapool, 0);
obstack_int_grow (&indirectpool, 0);
}
else
{
int32_t zero = 0;
obstack_grow (&extrapool, &zero, sizeof (zero));
obstack_grow (&indirectpool, &zero, sizeof (zero));
}
/* Prepare the ruleset table. */
for (sect = collate->sections, i = 0; sect != NULL; sect = sect->next)
if (sect->ruleidx == i)
@ -1978,7 +1993,7 @@ collate_read (struct linereader *ldfile, struct localedef_t *result,
}
/* Get the locale definition. */
copy_locale = find_locale (LC_COLLATE, now->val.str.startmb,
copy_locale = load_locale (LC_COLLATE, now->val.str.startmb,
repertoire_name, charmap);
if ((copy_locale->avail & COLLATE_LOCALE) == 0)
{

View file

@ -324,6 +324,8 @@ ctype_finish (struct localedef_t *locale, struct charmap_t *charmap)
/* Now resolve copying and also handle completely missing definitions. */
if (ctype == NULL)
{
const char *repertoire_name;
/* First see whether we were supposed to copy. If yes, find the
actual definition. */
if (locale->copy_name[LC_CTYPE] != NULL)
@ -351,6 +353,11 @@ ctype_finish (struct localedef_t *locale, struct charmap_t *charmap)
ctype_startup (NULL, locale, charmap, 0);
ctype = locale->categories[LC_CTYPE].ctype;
}
/* Get the repertoire we have to use. */
repertoire_name = locale->repertoire_name ?: repertoire_global;
if (repertoire_name != NULL)
ctype->repertoire = repertoire_read (repertoire_name);
}
/* Set default value for classes not specified. */

View file

@ -154,7 +154,8 @@ time_finish (struct localedef_t *locale, struct charmap_t *charmap)
empty one. */
if (time == NULL)
{
error (0, 0, _("No definition for %s category found"), "LC_TIME");
if (! be_quiet)
error (0, 0, _("No definition for %s category found"), "LC_TIME");
time_startup (NULL, locale, 0);
time = locale->categories[LC_TIME].time;
nothing = 1;
@ -481,7 +482,7 @@ time_finish (struct localedef_t *locale, struct charmap_t *charmap)
time->cal_direction = 1;
else if (time->cal_direction > 3)
error (0, 0, _("\
%s: values for field `%s' must not be larger than 3"),
%s: values for field `%s' must not be larger than %d"),
"LC_TIME", "cal_direction", 3);
/* XXX We don't perform any tests on the timezone value since this is

View file

@ -711,7 +711,7 @@ non-symbolic character value should not be used"));
{
/* This name is not in the repertoire map. */
lr_error (lr, _("symbol `%.*s' not in repertoire map"),
bufact - startidx, &buf[startidx]);
(int) (bufact - startidx), &buf[startidx]);
illegal_string = 1;
}
else
@ -726,7 +726,7 @@ non-symbolic character value should not be used"));
{
/* This name is not in the charmap. */
lr_error (lr, _("symbol `%.*s' not in charmap"),
bufact - startidx, &buf[startidx]);
(int) (bufact - startidx), &buf[startidx]);
illegal_string = 1;
/* Now forget about the name we just added. */

View file

@ -490,3 +490,23 @@ find_locale (int locale, const char *name, const char *repertoire_name,
return result;
}
struct localedef_t *
load_locale (int locale, const char *name, const char *repertoire_name,
struct charmap_t *charmap)
{
struct localedef_t *result;
/* Generate the locale if it does not exist. */
result = add_to_readlist (locale, name, repertoire_name, 1);
assert (result != NULL);
if ((result->avail & (1 << locale)) == 0
&& locfile_read (result, charmap) != 0)
error (4, errno, _("cannot open locale definition file `%s'"),
result->name);
return result;
}

View file

@ -131,4 +131,9 @@ extern struct localedef_t *find_locale (int locale, const char *name,
const char *repertoire_name,
struct charmap_t *charmap);
/* Load (if necessary) the information for the locale NAME. */
extern struct localedef_t *load_locale (int locale, const char *name,
const char *repertoire_name,
struct charmap_t *charmap);
#endif /* localedef.h */

View file

@ -431,7 +431,8 @@ hexadecimal range format should use only capital characters"));
&& errno == ERANGE)
|| *to_end != '\0')
{
lr_error (lr, _("<%s> and <%s> are invalid names for range"));
lr_error (lr, _("<%s> and <%s> are invalid names for range"),
from, to);
return;
}

View file

@ -72,7 +72,7 @@ $(inst_i18ndir)/repertoiremaps/%: repertoiremaps/% $(+force); $(do-install)
ifeq (no,$(cross-compiling))
ifeq (yes,$(build-shared))
.PHONY: do-collate-test do-tst-fmon do-tst-locale do-tst-rpmatch do-tst-trans
#tests: do-collate-test do-tst-fmon do-tst-locale do-tst-rpmatch do-tst-trans
tests: do-collate-test do-tst-fmon do-tst-locale do-tst-rpmatch do-tst-trans
do-collate-test: sort-test.sh $(objpfx)collate-test $(objpfx)xfrm-test \
$(test-input-data)
$(SHELL) -e $< $(common-objpfx) $(test-input)

View file

@ -4,6 +4,6 @@ upper <A>
lower <a>
space <SP>
blank <SP>
alpha <A>;<a>;<b01>;...;<b03>
alpha <A>;<a>;<b01>..<b03>
END LC_CTYPE

View file

@ -4,6 +4,6 @@ upper <A>
lower <a>
space <SP>
blank <SP>
alpha <A>;<a>;<b1>;...;<b3>
alpha <A>;<a>;<b1>..<b3>
END LC_CTYPE

View file

@ -31,6 +31,6 @@ exit 1
# Run the test program.
LOCPATH=${common_objpfx}localedata LC_ALL=tt_TT \
${common_objpfx}elf/ld.so --library-path $common_objpfx \
${common_objpfx}localedata/tst-trans
${common_objpfx}localedata/tst-trans > ${common_objpfx}localedata/tst-trans.out
exit $?

View file

@ -17,6 +17,7 @@
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include <assert.h>
#include <langinfo.h>
#include <stddef.h>
#include <stdint.h>
@ -71,6 +72,8 @@ STRCOLL (s1, s2, l)
size_t idx2max;
size_t idx1cnt;
size_t idx2cnt;
size_t idx1now;
size_t idx2now;
size_t backw1_stop;
size_t backw2_stop;
size_t backw1;
@ -78,6 +81,8 @@ STRCOLL (s1, s2, l)
int val1;
int val2;
int position;
int seq1len;
int seq2len;
int use_malloc = 0;
#include "../locale/weight.h"
@ -157,155 +162,149 @@ STRCOLL (s1, s2, l)
idx2cnt = 0;
idx1max = 0;
idx2max = 0;
idx1now = 0;
idx2now = 0;
backw1_stop = ~0ul;
backw2_stop = ~0ul;
backw1 = ~0ul;
backw2 = ~0ul;
position = rulesets[rule1arr[0] * nrules] & sort_position;
seq1len = 0;
seq2len = 0;
position = rulesets[0] & sort_position;
while (1)
{
size_t idx1now;
size_t idx2now;
int seq1len;
int seq2len;
int i;
val1 = 0;
val2 = 0;
/* Get the next non-IGNOREd element for string `s1'. */
do
{
++val1;
if (seq1len == 0)
do
{
++val1;
if (backw1_stop != ~0ul)
{
/* The is something pushed. */
if (backw1 == backw1_stop)
{
/* The last pushed character was handled. Continue
with forward characters. */
if (idx1cnt < idx1max)
idx1now = idx1cnt;
else
{
if (backw1_stop != ~0ul)
{
/* The is something pushed. */
if (backw1 == backw1_stop)
{
/* The last pushed character was handled. Continue
with forward characters. */
if (idx1cnt < idx1max)
idx1now = idx1cnt;
else
/* Nothing anymore. The backward sequence ended with
the last sequence in the string. */
idx1now = ~0ul;
the last sequence in the string. Note that seq1len
is still zero. */
break;
}
}
else
idx1now = --backw1;
}
else
{
backw1_stop = idx1max;
}
else
idx1now = --backw1;
}
else
{
backw1_stop = idx1max;
while (*us1 != '\0')
{
int32_t tmp = findidx (&us1);
rule1arr[idx1max] = tmp >> 24;
idx1arr[idx1max] = tmp & 0xffffff;
idx1cnt = idx1max++;
while (*us1 != '\0')
{
int32_t tmp = findidx (&us1);
rule1arr[idx1max] = tmp >> 24;
idx1arr[idx1max] = tmp & 0xffffff;
idx1cnt = idx1max++;
if ((rulesets[rule1arr[idx1cnt] * nrules]
& sort_backward) == 0)
/* No more backward characters to push. */
break;
++idx1cnt;
}
if (backw1_stop >= idx1cnt)
{
/* No sequence at all or just one. */
backw1_stop = ~0ul;
if (idx1cnt == idx1max || backw1_stop > idx1cnt)
{
idx1now = ~0ul;
if ((rulesets[rule1arr[idx1cnt] * nrules]
& sort_backward) == 0)
/* No more backward characters to push. */
break;
}
idx1now = idx1cnt;
}
else
/* We pushed backward sequences. */
idx1now = backw1 = idx1cnt - 1;
}
}
while (weights[idx1arr[idx1now]] == '\0');
++idx1cnt;
}
if (backw1_stop >= idx1cnt)
{
/* No sequence at all or just one. */
if (idx1cnt == idx1max || backw1_stop > idx1cnt)
/* Note that seq1len is still zero. */
break;
backw1_stop = ~0ul;
idx1now = idx1cnt;
}
else
/* We pushed backward sequences. */
idx1now = backw1 = idx1cnt - 1;
}
}
while ((seq1len = weights[idx1arr[idx1now]++]) == 0);
/* And the same for string `s2'. */
do
{
++val2;
if (seq2len == 0)
do
{
++val2;
if (backw2_stop != ~0ul)
{
/* The is something pushed. */
if (backw2 == backw2_stop)
{
/* The last pushed character was handled. Continue
with forward characters. */
if (idx2cnt < idx2max)
idx2now = idx2cnt;
else
{
if (backw2_stop != ~0ul)
{
/* The is something pushed. */
if (backw2 == backw2_stop)
{
/* The last pushed character was handled. Continue
with forward characters. */
if (idx2cnt < idx2max)
idx2now = idx2cnt;
else
/* Nothing anymore. The backward sequence ended with
the last sequence in the string. */
idx2now = ~0ul;
the last sequence in the string. Note that seq2len
is still zero. */
break;
}
}
else
idx2now = --backw2;
}
else
{
backw2_stop = idx2max;
}
else
idx2now = --backw2;
}
else
{
backw2_stop = idx2max;
while (*us2 != '\0')
{
int32_t tmp = findidx (&us2);
rule2arr[idx2max] = tmp >> 24;
idx2arr[idx2max] = tmp & 0xffffff;
idx2cnt = idx2max++;
while (*us2 != '\0')
{
int32_t tmp = findidx (&us2);
rule2arr[idx2max] = tmp >> 24;
idx2arr[idx2max] = tmp & 0xffffff;
idx2cnt = idx2max++;
if ((rulesets[rule2arr[idx2cnt] * nrules]
& sort_backward) == 0)
/* No more backward characters to push. */
break;
++idx2cnt;
}
if (backw2_stop >= idx2cnt)
{
/* No sequence at all or just one. */
backw2_stop = ~0ul;
if (idx2cnt == idx2max || backw2_stop > idx2cnt)
{
idx2now = ~0ul;
if ((rulesets[rule2arr[idx2cnt] * nrules]
& sort_backward) == 0)
/* No more backward characters to push. */
break;
}
idx2now = idx2cnt;
}
else
/* We pushed backward sequences. */
idx2now = backw2 = idx2cnt - 1;
}
}
while (weights[idx2arr[idx2now]] == '\0');
++idx2cnt;
}
if (backw2_stop >= idx2cnt)
{
/* No sequence at all or just one. */
if (idx2cnt == idx2max || backw2_stop > idx2cnt)
/* Note that seq1len is still zero. */
break;
backw2_stop = ~0ul;
idx2now = idx2cnt;
}
else
/* We pushed backward sequences. */
idx2now = backw2 = idx2cnt - 1;
}
}
while ((seq2len = weights[idx2arr[idx2now]++]) == 0);
/* See whether any or both strings are empty. */
if (idx1now == ~0ul || idx2now == ~0ul)
if (seq1len == 0 || seq2len == 0)
{
if (idx1now == idx2now)
if (seq1len == seq2len)
/* Both ended. So far so good, both strings are equal at the
first level. */
break;
/* This means one string is shorter than the other. Find out
which one and return an appropriate value. */
result = idx1now == ~0ul ? -1 : 1;
result = seq1len == 0 ? -1 : 1;
goto free_and_return;
}
@ -317,25 +316,29 @@ STRCOLL (s1, s2, l)
}
/* Compare the two sequences. */
seq1len = weights[idx1arr[idx1now]++];
seq2len = weights[idx2arr[idx2now]++];
for (i = 0; i < seq1len && i < seq2len; ++i)
if (weights[idx1arr[idx1now]] != weights[idx2arr[idx2now]])
{
/* The sequences differ. */
result = weights[idx1arr[idx1now]] - weights[idx2arr[idx2now]];
goto free_and_return;
}
else
{
/* Increment the offsets. */
++idx1arr[idx1now];
++idx2arr[idx2now];
}
do
{
if (weights[idx1arr[idx1now]] != weights[idx2arr[idx2now]])
{
/* The sequences differ. */
result = weights[idx1arr[idx1now]] - weights[idx2arr[idx2now]];
goto free_and_return;
}
result = seq1len - seq2len;
if (result != 0)
goto free_and_return;
/* Increment the offsets. */
++idx1arr[idx1now];
++idx2arr[idx2now];
--seq1len;
--seq2len;
}
while (seq1len > 0 && seq2len > 0);
if (position && seq1len != seq2len)
{
result = seq1len - seq2len;
goto free_and_return;
}
}
/* Now the remaining passes over the weights. We now use the
@ -354,138 +357,132 @@ STRCOLL (s1, s2, l)
while (1)
{
size_t idx1now;
size_t idx2now;
int seq1len;
int seq2len;
int i;
val1 = 0;
val2 = 0;
/* Get the next non-IGNOREd element for string `s1'. */
do
{
++val1;
if (seq1len == 0)
do
{
++val1;
if (backw1_stop != ~0ul)
{
/* The is something pushed. */
if (backw1 == backw1_stop)
{
/* The last pushed character was handled. Continue
with forward characters. */
if (idx1cnt < idx1max)
idx1now = idx1cnt;
else
{
/* Nothing anymore. The backward sequence ended with
the last sequence in the string. */
idx1now = ~0ul;
if (backw1_stop != ~0ul)
{
/* The is something pushed. */
if (backw1 == backw1_stop)
{
/* The last pushed character was handled. Continue
with forward characters. */
if (idx1cnt < idx1max)
idx1now = idx1cnt;
else
{
/* Nothing anymore. The backward sequence
ended with the last sequence in the string. */
idx1now = ~0ul;
break;
}
}
else
idx1now = --backw1;
}
else
{
backw1_stop = idx1cnt;
while (idx1cnt < idx1max)
{
if ((rulesets[rule1arr[idx1cnt] * nrules + pass]
& sort_backward) == 0)
/* No more backward characters to push. */
break;
}
}
else
idx1now = --backw1;
}
else
{
backw1_stop = idx1cnt;
++idx1cnt;
}
while (idx1cnt < idx1max)
{
if ((rulesets[rule1arr[idx1cnt] * nrules + pass]
& sort_backward) == 0)
/* No more backward characters to push. */
break;
++idx1cnt;
}
if (backw1_stop == idx1cnt)
{
/* No sequence at all or just one. */
backw1_stop = ~0ul;
if (idx1cnt == idx1max)
{
idx1now = ~0ul;
if (backw1_stop == idx1cnt)
{
/* No sequence at all or just one. */
if (idx1cnt == idx1max)
/* Note that seq2len is still zero. */
break;
}
idx1now = idx1cnt++;
}
else
/* We pushed backward sequences. */
idx1now = backw1 = idx1cnt - 1;
}
}
while (weights[idx1arr[idx1now]] == '\0');
backw1_stop = ~0ul;
idx1now = idx1cnt++;
}
else
/* We pushed backward sequences. */
idx1now = backw1 = idx1cnt - 1;
}
}
while ((seq1len = weights[idx1arr[idx1now]++]) == 0);
/* And the same for string `s2'. */
do
{
++val2;
if (seq2len == 0)
do
{
++val2;
if (backw2_stop != ~0ul)
{
/* The is something pushed. */
if (backw2 == backw2_stop)
{
/* The last pushed character was handled. Continue
with forward characters. */
if (idx2cnt < idx2max)
idx2now = idx2cnt;
else
{
/* Nothing anymore. The backward sequence ended with
the last sequence in the string. */
idx2now = ~0ul;
if (backw2_stop != ~0ul)
{
/* The is something pushed. */
if (backw2 == backw2_stop)
{
/* The last pushed character was handled. Continue
with forward characters. */
if (idx2cnt < idx2max)
idx2now = idx2cnt;
else
{
/* Nothing anymore. The backward sequence
ended with the last sequence in the string. */
idx2now = ~0ul;
break;
}
}
else
idx2now = --backw2;
}
else
{
backw2_stop = idx2cnt;
while (idx2cnt < idx2max)
{
if ((rulesets[rule2arr[idx2cnt] * nrules + pass]
& sort_backward) == 0)
/* No more backward characters to push. */
break;
}
}
else
idx2now = --backw2;
}
else
{
backw2_stop = idx2cnt;
++idx2cnt;
}
while (idx2cnt < idx2max)
{
if ((rulesets[rule2arr[idx2cnt] * nrules + pass]
& sort_backward) == 0)
/* No more backward characters to push. */
break;
++idx2cnt;
}
if (backw2_stop == idx2cnt)
{
/* No sequence at all or just one. */
backw2_stop = ~0ul;
if (idx2cnt == idx2max)
{
idx2now = ~0ul;
if (backw2_stop == idx2cnt)
{
/* No sequence at all or just one. */
if (idx2cnt == idx2max)
/* Note that seq2len is still zero. */
break;
}
idx2now = idx2cnt++;
}
else
/* We pushed backward sequences. */
idx2now = backw2 = idx2cnt - 1;
}
}
while (weights[idx2arr[idx2now]] == '\0');
backw2_stop = ~0ul;
idx2now = idx2cnt++;
}
else
/* We pushed backward sequences. */
idx2now = backw2 = idx2cnt - 1;
}
}
while ((seq2len = weights[idx2arr[idx2now]++]) == 0);
/* See whether any or both strings are empty. */
if (idx1now == ~0ul || idx2now == ~0ul)
if (seq1len == 0 || seq2len == 0)
{
if (idx1now == idx2now)
/* Both ended. So far so good, both strings are equal at the
first level. */
if (seq1len == seq2len)
/* Both ended. So far so good, both strings are equal
at this level. */
break;
/* This means one string is shorter than the other. Find out
which one and return an appropriate value. */
result = idx1now == ~0ul ? -1 : 1;
result = seq1len == 0 ? -1 : 1;
goto free_and_return;
}
@ -497,25 +494,30 @@ STRCOLL (s1, s2, l)
}
/* Compare the two sequences. */
seq1len = weights[idx1arr[idx1now]++];
seq2len = weights[idx2arr[idx2now]++];
for (i = 0; i < seq1len && i < seq2len; ++i)
if (weights[idx1arr[idx1now]] != weights[idx2arr[idx2now]])
{
/* The sequences differ. */
result = weights[idx1arr[idx1now]] - weights[idx2arr[idx2now]];
goto free_and_return;
}
else
{
/* Increment the offsets. */
++idx1arr[idx1now];
++idx2arr[idx2now];
}
do
{
if (weights[idx1arr[idx1now]] != weights[idx2arr[idx2now]])
{
/* The sequences differ. */
result = (weights[idx1arr[idx1now]]
- weights[idx2arr[idx2now]]);
goto free_and_return;
}
result = seq1len - seq2len;
if (result != 0)
goto free_and_return;
/* Increment the offsets. */
++idx1arr[idx1now];
++idx2arr[idx2now];
--seq1len;
--seq2len;
}
while (seq1len > 0 && seq2len > 0);
if (position && seq1len != seq2len)
{
result = seq1len - seq2len;
goto free_and_return;
}
}
}