diff options
author | Ulrich Drepper <drepper@redhat.com> | 2008-05-15 02:54:33 +0000 |
---|---|---|
committer | Ulrich Drepper <drepper@redhat.com> | 2008-05-15 02:54:33 +0000 |
commit | 2f9a1be867489eb4fdc46e052163eb3cab99aef1 (patch) | |
tree | 61ce5241b637ef45b048ea4fc0485847b127bfc7 /string | |
parent | c8d49f05e7048f84bb8a60381c290f4831f3bd57 (diff) | |
download | glibc-2f9a1be867489eb4fdc46e052163eb3cab99aef1.tar.gz glibc-2f9a1be867489eb4fdc46e052163eb3cab99aef1.tar.xz glibc-2f9a1be867489eb4fdc46e052163eb3cab99aef1.zip |
[BZ #6442]
* string/endian.h: Add macros for fixed-size endian conversion. * bits/byteswap.h: Allow inclusion from <endian.h>. * sysdeps/i386/bits/byteswap.h: Likewise. * sysdeps/ia64/bits/byteswap.h: Likewise. * sysdeps/s390/bits/byteswap.h: Likewise. * sysdeps/x86_64/bits/byteswap.h: Likewise. * string/Makefile (tests): Add tst-endian. * string/tst-endian.c: New file.
Diffstat (limited to 'string')
-rw-r--r-- | string/Makefile | 4 | ||||
-rw-r--r-- | string/endian.h | 38 | ||||
-rw-r--r-- | string/tst-endian.c | 112 |
3 files changed, 151 insertions, 3 deletions
diff --git a/string/Makefile b/string/Makefile index d4ec22457d..ccdc497c70 100644 --- a/string/Makefile +++ b/string/Makefile @@ -1,4 +1,4 @@ -# Copyright (C) 1991-2002, 2005, 2006, 2007 Free Software Foundation, Inc. +# Copyright (C) 1991-2002, 2005-2007, 2008 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 + bug-envz1 tst-strxfrm2 tst-endian distribute := memcopy.h pagecopy.h tst-svc.expect test-string.h diff --git a/string/endian.h b/string/endian.h index 2f7bce100b..430fb3a5c4 100644 --- a/string/endian.h +++ b/string/endian.h @@ -1,4 +1,4 @@ -/* Copyright (C) 1992, 1996, 1997, 2000 Free Software Foundation, Inc. +/* Copyright (C) 1992, 1996, 1997, 2000, 2008 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 @@ -55,4 +55,40 @@ # define __LONG_LONG_PAIR(HI, LO) HI, LO #endif + +/* Conversion interfaces. */ +#include <bits/byteswap.h> + +#if __BYTE_ORDER == __LITTLE_ENDIAN +# define htobe16(x) __bswap_16 (x) +# define htole16(x) (x) +# define be16toh(x) __bswap_16 (x) +# define le16toh(x) (x) + +# define htobe32(x) __bswap_32 (x) +# define htole32(x) (x) +# define be32toh(x) __bswap_32 (x) +# define le32toh(x) (x) + +# define htobe64(x) __bswap_64 (x) +# define htole64(x) (x) +# define be64toh(x) __bswap_64 (x) +# define le64toh(x) (x) +#else +# define htobe16(x) (x) +# define htole16(x) __bswap_16 (x) +# define be16toh(x) (x) +# define le16toh(x) __bswap_16 (x) + +# define htobe32(x) (x) +# define htole32(x) __bswap_32 (x) +# define be32toh(x) (x) +# define le32toh(x) __bswap_32 (x) + +# define htobe64(x) (x) +# define htole64(x) __bswap_64 (x) +# define be64toh(x) (x) +# define le64toh(x) __bswap_64 (x) +#endif + #endif /* endian.h */ diff --git a/string/tst-endian.c b/string/tst-endian.c new file mode 100644 index 0000000000..c34dc456a7 --- /dev/null +++ b/string/tst-endian.c @@ -0,0 +1,112 @@ +#include <byteswap.h> +#include <endian.h> +#include <inttypes.h> +#include <stdio.h> + + +static int +do_test (void) +{ + int result = 0; + + for (uint64_t i = 0; i < (~UINT64_C (0)) >> 2; i = (i << 1) + 3) + { + if (i < UINT64_C (65536)) + { + if (htobe16 (be16toh (i)) != i) + { + printf ("htobe16 (be16toh (%" PRIx64 ")) == %" PRIx16 "\n", + i, (uint16_t) htobe16 (be16toh (i))); + result = 1; + } + if (htole16 (le16toh (i)) != i) + { + printf ("htole16 (le16toh (%" PRIx64 ")) == %" PRIx16 "\n", + i, (uint16_t) htole16 (le16toh (i))); + result = 1; + } + + uint16_t n[2]; + n[__BYTE_ORDER == __LITTLE_ENDIAN] = bswap_16 (i); + n[__BYTE_ORDER == __BIG_ENDIAN] = i; + if (htole16 (i) != n[0]) + { + printf ("htole16 (%" PRIx64 ") == %" PRIx16 " != %" PRIx16 "\n", + i, (uint16_t) htole16 (i), n[0]); + result = 1; + } + if (htobe16 (i) != n[1]) + { + printf ("htobe16 (%" PRIx64 ") == %" PRIx16 " != %" PRIx16 "\n", + i, (uint16_t) htobe16 (i), n[1]); + result = 1; + } + } + + if (i < UINT64_C (4294967296)) + { + if (htobe32 (be32toh (i)) != i) + { + printf ("htobe32 (be32toh (%" PRIx64 ")) == %" PRIx32 "\n", + i, (uint32_t) htobe32 (be32toh (i))); + result = 1; + } + if (htole32 (le32toh (i)) != i) + { + printf ("htole32 (le32toh (%" PRIx64 ")) == %" PRIx32 "\n", + i, (uint32_t) htole32 (le32toh (i))); + result = 1; + } + + uint32_t n[2]; + n[__BYTE_ORDER == __LITTLE_ENDIAN] = bswap_32 (i); + n[__BYTE_ORDER == __BIG_ENDIAN] = i; + if (htole32 (i) != n[0]) + { + printf ("htole32 (%" PRIx64 ") == %" PRIx32 " != %" PRIx32 "\n", + i, (uint32_t) htole32 (i), n[0]); + result = 1; + } + if (htobe32 (i) != n[1]) + { + printf ("htobe32 (%" PRIx64 ") == %" PRIx32 " != %" PRIx32 "\n", + i, (uint32_t) htobe32 (i), n[1]); + result = 1; + } + } + + if (htobe64 (be64toh (i)) != i) + { + printf ("htobe64 (be64toh (%" PRIx64 ")) == %" PRIx64 "\n", + i, htobe64 (be64toh (i))); + result = 1; + } + if (htole64 (le64toh (i)) != i) + { + printf ("htole64 (le64toh (%" PRIx64 ")) == %" PRIx64 "\n", + i, htole64 (le64toh (i))); + result = 1; + } + + uint64_t n[2]; + n[__BYTE_ORDER == __LITTLE_ENDIAN] = bswap_64 (i); + n[__BYTE_ORDER == __BIG_ENDIAN] = i; + if (htole64 (i) != n[0]) + { + printf ("htole64 (%" PRIx64 ") == %" PRIx64 " != %" PRIx64 "\n", + i, htole64 (i), n[0]); + result = 1; + } + if (htobe64 (i) != n[1]) + { + printf ("htobe64 (%" PRIx64 ") == %" PRIx64 " != %" PRIx64 "\n", + i, htobe64 (i), n[1]); + result = 1; + } + } + + return result; +} + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" |