diff options
author | Jakub Jelinek <jakub@redhat.com> | 2009-03-20 20:00:20 +0000 |
---|---|---|
committer | Jakub Jelinek <jakub@redhat.com> | 2009-03-20 20:00:20 +0000 |
commit | ef860a878bf532436a469fc1f89fe3366862a949 (patch) | |
tree | c4a2666ac77cdaa00f41bd8f66a828b39e2642ff /string | |
parent | d4c583b4466962a9d9d4ca54ab6108dc7b42cdcc (diff) |
Updated to fedora-glibc-20090320T1944cvs/fedora-glibc-2_9_90-11
Diffstat (limited to 'string')
-rw-r--r-- | string/Makefile | 4 | ||||
-rw-r--r-- | string/strlen.c | 52 | ||||
-rw-r--r-- | string/strverscmp.c | 61 | ||||
-rw-r--r-- | string/tst-svc2.c | 62 |
4 files changed, 96 insertions, 83 deletions
diff --git a/string/Makefile b/string/Makefile index cccd68cf45..127e25fbd9 100644 --- a/string/Makefile +++ b/string/Makefile @@ -1,4 +1,4 @@ -# Copyright (C) 1991-2002, 2005-2007, 2008 Free Software Foundation, Inc. +# Copyright (C) 1991-2002, 2005-2008, 2009 Free Software Foundation, Inc. # This file is part of the GNU C Library. # The GNU C Library is free software; you can redistribute it and/or @@ -54,7 +54,7 @@ tests := tester inl-tester noinl-tester testcopy test-ffs \ bug-strncat1 bug-strspn1 bug-strpbrk1 tst-bswap \ tst-strtok tst-strxfrm bug-strcoll1 tst-strfry \ bug-strtok1 $(addprefix test-,$(strop-tests)) \ - bug-envz1 tst-strxfrm2 tst-endian + bug-envz1 tst-strxfrm2 tst-endian tst-svc2 distribute := memcopy.h pagecopy.h tst-svc.expect test-string.h \ str-two-way.h diff --git a/string/strlen.c b/string/strlen.c index 9bc9db68f7..5f22ce9509 100644 --- a/string/strlen.c +++ b/string/strlen.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1991, 1993, 1997, 2000, 2003 Free Software Foundation, Inc. +/* Copyright (C) 1991,1993,1997,2000,2003,2009 Free Software Foundation, Inc. This file is part of the GNU C Library. Written by Torbjorn Granlund (tege@sics.se), with help from Dan Sahlin (dan@sics.se); @@ -32,7 +32,7 @@ strlen (str) { const char *char_ptr; const unsigned long int *longword_ptr; - unsigned long int longword, magic_bits, himagic, lomagic; + unsigned long int longword, himagic, lomagic; /* Handle the first few characters by reading one character at a time. Do this until CHAR_PTR is aligned on a longword boundary. */ @@ -56,14 +56,12 @@ strlen (str) The 1-bits make sure that carries propagate to the next 0-bit. The 0-bits provide holes for carries to fall into. */ - magic_bits = 0x7efefeffL; himagic = 0x80808080L; lomagic = 0x01010101L; if (sizeof (longword) > 4) { /* 64-bit version of the magic. */ /* Do the shift in two steps to avoid a warning if long has 32 bits. */ - magic_bits = ((0x7efefefeL << 16) << 16) | 0xfefefeffL; himagic = ((himagic << 16) << 16) | himagic; lomagic = ((lomagic << 16) << 16) | lomagic; } @@ -75,53 +73,9 @@ strlen (str) if *any of the four* bytes in the longword in question are zero. */ for (;;) { - /* We tentatively exit the loop if adding MAGIC_BITS to - LONGWORD fails to change any of the hole bits of LONGWORD. - - 1) Is this safe? Will it catch all the zero bytes? - Suppose there is a byte with all zeros. Any carry bits - propagating from its left will fall into the hole at its - least significant bit and stop. Since there will be no - carry from its most significant bit, the LSB of the - byte to the left will be unchanged, and the zero will be - detected. - - 2) Is this worthwhile? Will it ignore everything except - zero bytes? Suppose every byte of LONGWORD has a bit set - somewhere. There will be a carry into bit 8. If bit 8 - is set, this will carry into bit 16. If bit 8 is clear, - one of bits 9-15 must be set, so there will be a carry - into bit 16. Similarly, there will be a carry into bit - 24. If one of bits 24-30 is set, there will be a carry - into bit 31, so all of the hole bits will be changed. - - The one misfire occurs when bits 24-30 are clear and bit - 31 is set; in this case, the hole at bit 31 is not - changed. If we had access to the processor carry flag, - we could close this loophole by putting the fourth hole - at bit 32! - - So it ignores everything except 128's, when they're aligned - properly. */ - longword = *longword_ptr++; - if ( -#if 0 - /* Add MAGIC_BITS to LONGWORD. */ - (((longword + magic_bits) - - /* Set those bits that were unchanged by the addition. */ - ^ ~longword) - - /* Look at only the hole bits. If any of the hole bits - are unchanged, most likely one of the bytes was a - zero. */ - & ~magic_bits) -#else - ((longword - lomagic) & himagic) -#endif - != 0) + if (((longword - lomagic) & ~longword & himagic) != 0) { /* Which of the bytes was the zero? If none of them were, it was a misfire; continue the search. */ diff --git a/string/strverscmp.c b/string/strverscmp.c index 8efac30383..2b7ebcb8a8 100644 --- a/string/strverscmp.c +++ b/string/strverscmp.c @@ -1,5 +1,5 @@ /* Compare strings while treating digits characters numerically. - Copyright (C) 1997, 2002 Free Software Foundation, Inc. + Copyright (C) 1997, 2002, 2009 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Jean-François Bignolles <bignolle@ecoledoc.ibp.fr>, 1997. @@ -18,15 +18,16 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ +#include <stdint.h> #include <string.h> #include <ctype.h> /* states: S_N: normal, S_I: comparing integral part, S_F: comparing fractionnal parts, S_Z: idem but with leading Zeroes only */ #define S_N 0x0 -#define S_I 0x4 -#define S_F 0x8 -#define S_Z 0xC +#define S_I 0x3 +#define S_F 0x6 +#define S_Z 0x9 /* result_type: CMP: return diff; LEN: compare using len_diff/diff */ #define CMP 2 @@ -45,53 +46,49 @@ __strverscmp (s1, s2) { const unsigned char *p1 = (const unsigned char *) s1; const unsigned char *p2 = (const unsigned char *) s2; - unsigned char c1, c2; - int state; - int diff; - /* Symbol(s) 0 [1-9] others (padding) - Transition (10) 0 (01) d (00) x (11) - */ - static const unsigned int next_state[] = + /* Symbol(s) 0 [1-9] others + Transition (10) 0 (01) d (00) x */ + static const uint8_t next_state[] = { - /* state x d 0 - */ - /* S_N */ S_N, S_I, S_Z, S_N, - /* S_I */ S_N, S_I, S_I, S_I, - /* S_F */ S_N, S_F, S_F, S_F, - /* S_Z */ S_N, S_F, S_Z, S_Z + /* state x d 0 */ + /* S_N */ S_N, S_I, S_Z, + /* S_I */ S_N, S_I, S_I, + /* S_F */ S_N, S_F, S_F, + /* S_Z */ S_N, S_F, S_Z }; - static const int result_type[] = + static const int8_t result_type[] = { - /* state x/x x/d x/0 x/- d/x d/d d/0 d/- - 0/x 0/d 0/0 0/- -/x -/d -/0 -/- */ - - /* S_N */ CMP, CMP, CMP, CMP, CMP, LEN, CMP, CMP, - CMP, CMP, CMP, CMP, CMP, CMP, CMP, CMP, - /* S_I */ CMP, -1, -1, CMP, +1, LEN, LEN, CMP, - +1, LEN, LEN, CMP, CMP, CMP, CMP, CMP, - /* S_F */ CMP, CMP, CMP, CMP, CMP, LEN, CMP, CMP, - CMP, CMP, CMP, CMP, CMP, CMP, CMP, CMP, - /* S_Z */ CMP, +1, +1, CMP, -1, CMP, CMP, CMP, - -1, CMP, CMP, CMP + /* state x/x x/d x/0 d/x d/d d/0 0/x 0/d 0/0 */ + + /* S_N */ CMP, CMP, CMP, CMP, LEN, CMP, CMP, CMP, CMP, + /* S_I */ CMP, -1, -1, +1, LEN, LEN, +1, LEN, LEN, + /* S_F */ CMP, CMP, CMP, CMP, CMP, CMP, CMP, CMP, CMP, + /* S_Z */ CMP, +1, +1, -1, CMP, CMP, -1, CMP, CMP }; if (p1 == p2) return 0; - c1 = *p1++; - c2 = *p2++; + unsigned char c1 = *p1++; + unsigned char c2 = *p2++; /* Hint: '0' is a digit too. */ - state = S_N | ((c1 == '0') + (isdigit (c1) != 0)); + int state = S_N | ((c1 == '0') + (isdigit (c1) != 0)); - while ((diff = c1 - c2) == 0 && c1 != '\0') + int diff; + while ((diff = c1 - c2) == 0) { + if (c1 == '\0') + return diff; + state = next_state[state]; c1 = *p1++; c2 = *p2++; state |= (c1 == '0') + (isdigit (c1) != 0); } - state = result_type[state << 2 | (((c2 == '0') + (isdigit (c2) != 0)))]; + state = result_type[state * 3 | (((c2 == '0') + (isdigit (c2) != 0)))]; switch (state) { diff --git a/string/tst-svc2.c b/string/tst-svc2.c new file mode 100644 index 0000000000..12c88aa2b8 --- /dev/null +++ b/string/tst-svc2.c @@ -0,0 +1,62 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + + +static struct +{ + const char *str1; + const char *str2; +} tests[] = + { + { "B0075022800016.gbp.corp.com", "B007502280067.gbp.corp.com" }, + { "B0075022800016.gbp.corp.com", "B007502357019.GBP.CORP.COM" }, + { "B007502280067.gbp.corp.com", "B007502357019.GBP.CORP.COM" } + }; +#define ntests (sizeof (tests) / sizeof (tests[0])) + + +int +compare (const char *str1, const char *str2, int exp) +{ + int c = strverscmp (str1, str2); + if (c != 0) + c /= abs (c); + return c != exp; +} + + +static int +do_test (void) +{ + int res = 0; + for (int i = 0; i < ntests; ++i) + { + if (compare (tests[i].str1, tests[i].str2, -1)) + { + printf ("FAIL: \"%s\" > \"%s\"\n", tests[i].str1, tests[i].str2); + res = 1; + } + if (compare (tests[i].str2, tests[i].str1, +1)) + { + printf ("FAIL: \"%s\" > \"%s\"\n", tests[i].str2, tests[i].str1); + res = 1; + } + char *copy1 = strdupa (tests[i].str1); + if (compare (tests[i].str1, copy1, 0)) + { + printf ("FAIL: \"%s\" != \"%s\"\n", tests[i].str1, copy1); + res = 1; + } + char *copy2 = strdupa (tests[i].str2); + if (compare (tests[i].str2, copy2, 0)) + { + printf ("FAIL: \"%s\" != \"%s\"\n", tests[i].str2, copy2); + res = 1; + } + } + return res; +} + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" |