summaryrefslogtreecommitdiff
path: root/string
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2009-03-20 20:00:20 +0000
committerJakub Jelinek <jakub@redhat.com>2009-03-20 20:00:20 +0000
commitef860a878bf532436a469fc1f89fe3366862a949 (patch)
treec4a2666ac77cdaa00f41bd8f66a828b39e2642ff /string
parentd4c583b4466962a9d9d4ca54ab6108dc7b42cdcc (diff)
Updated to fedora-glibc-20090320T1944cvs/fedora-glibc-2_9_90-11
Diffstat (limited to 'string')
-rw-r--r--string/Makefile4
-rw-r--r--string/strlen.c52
-rw-r--r--string/strverscmp.c61
-rw-r--r--string/tst-svc2.c62
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"