|
Message-Id: <1365280696-16525-2-git-send-email-nwmcsween@gmail.com> Date: Sat, 6 Apr 2013 20:38:16 +0000 From: Nathan McSween <nwmcsween@...il.com> To: musl@...ts.openwall.com Cc: Nathan McSween <nwmcsween@...il.com> Subject: [PATCH] String: expand to word size && refactor || refactor --- src/string/memccpy.c | 50 ++++++++++++++++++++++++++---------------------- src/string/memchr.c | 42 +++++++++++++++++++++++----------------- src/string/memcmp.c | 33 ++++++++++++++++++++++++++++---- src/string/memcpy.c | 44 +++++++++++++++++++++--------------------- src/string/memrchr.c | 30 +++++++++++++++++++++++++---- src/string/memset.c | 37 ++++++++++++++++++++--------------- src/string/stpcpy.c | 32 +++++++++++++++++-------------- src/string/stpncpy.c | 38 +++++++++++++++++++----------------- src/string/strcat.c | 7 ++++--- src/string/strchrnul.c | 26 ++++++++++++++----------- src/string/strcmp.c | 30 ++++++++++++++++++++++++++++- src/string/strcpy.c | 7 ------- src/string/strlcpy.c | 52 +++++++++++++++++++++++++++++--------------------- 13 files changed, 268 insertions(+), 160 deletions(-) diff --git a/src/string/memccpy.c b/src/string/memccpy.c index b85009c..f032030 100644 --- a/src/string/memccpy.c +++ b/src/string/memccpy.c @@ -1,32 +1,36 @@ #include <string.h> -#include <stdlib.h> #include <stdint.h> -#include <limits.h> -#define ALIGN (sizeof(size_t)-1) -#define ONES ((size_t)-1/UCHAR_MAX) -#define HIGHS (ONES * (UCHAR_MAX/2+1)) -#define HASZERO(x) ((x)-ONES & ~(x) & HIGHS) +#define HIGHS(x) ((x) - ((x)*0-1) / 255 * 128) +#define LOWS(x) (((x)*0-1) / 255) +#define has_char(x, c) ((x) - LOWS(x) & ~(x) & HIGHS(x) ^ LOWS(x) * (c)) -void *memccpy(void *restrict dest, const void *restrict src, int c, size_t n) +void *memccpy(void *restrict d, const void *restrict s, int c, size_t n) { - unsigned char *d = dest; - const unsigned char *s = src; - size_t *wd, k; + unsigned char *cd = (unsigned char *)d; + const unsigned char *cs = (const unsigned char *)s; + size_t *wd; const size_t *ws; c = (unsigned char)c; - if (((uintptr_t)s & ALIGN) == ((uintptr_t)d & ALIGN)) { - for (; ((uintptr_t)s & ALIGN) && n && (*d=*s)!=c; n--, s++, d++); - if ((uintptr_t)s & ALIGN) goto tail; - k = ONES * c; - wd=(void *)d; ws=(const void *)s; - for (; n>=sizeof(size_t) && !HASZERO(*ws^k); - n-=sizeof(size_t), ws++, wd++) *wd = *ws; - d=(void *)wd; s=(const void *)ws; - } - for (; n && (*d=*s)!=c; n--, s++, d++); -tail: - if (*s==c) return d+1; - return 0; + + if ((uintptr_t)s % sizeof(size_t) != (uintptr_t)d % sizeof(size_t) + || n < sizeof(size_t)) + goto bytewise; + + for (; (uintptr_t)s % sizeof(size_t); *cd = *cs, cd++, cs++) + if (*cs == c) return cd + 1; + + for (wd = (size_t *)d, ws = (const size_t *)s + ; !has_char(*ws, c) && n >= sizeof(size_t) + ; ws++, wd++, *wd = *ws); + + cd = (unsigned char *)wd; + cs = (const unsigned char *)ws; + +bytewise: + for (; *cs != c; *cd = *cs, cs++, cd++, n--) + if (!n) return NULL; + + return cd + 1; } diff --git a/src/string/memchr.c b/src/string/memchr.c index a0472f7..9a69a85 100644 --- a/src/string/memchr.c +++ b/src/string/memchr.c @@ -1,24 +1,32 @@ -#include <string.h> -#include <stdlib.h> +#include <stddef.h> #include <stdint.h> -#include <limits.h> +#include <string.h> -#define SS (sizeof(size_t)) -#define ALIGN (sizeof(size_t)-1) -#define ONES ((size_t)-1/UCHAR_MAX) -#define HIGHS (ONES * (UCHAR_MAX/2+1)) -#define HASZERO(x) ((x)-ONES & ~(x) & HIGHS) +#define HIGHS(x) ((x) - ((x)*0-1) / 255 * 128) +#define LOWS(x) (((x)*0-1) / 255) +#define has_char(x, c) ((x) - LOWS(x) & ~(x) & HIGHS(x) ^ LOWS(x) * (c)) -void *memchr(const void *src, int c, size_t n) +void *memchr(const void *s, int c, size_t n) { - const unsigned char *s = src; + const unsigned char *cs = (const unsigned char *)s; + const size_t *ws; + c = (unsigned char)c; - for (; ((uintptr_t)s & ALIGN) && n && *s != c; s++, n--); - if (n && *s != c) { - const size_t *w; - size_t k = ONES * c; - for (w = (const void *)s; n>=SS && !HASZERO(*w^k); w++, n-=SS); - for (s = (const void *)w; n && *s != c; s++, n--); + + if (n < sizeof(size_t)) goto bytewise; + + for (; (uintptr_t)cs % sizeof(size_t); cs++, n--) { + if (*cs == c) return (void *)cs; } - return n ? (void *)s : 0; + + for (ws = (const size_t *)cs + ; !has_char(*ws, c) && n >= sizeof(size_t) + ; ws++, n -= sizeof(size_t)); + cs = (const unsigned char *)ws; + +bytewise: + for (; *cs != c; cs++, n--) + if (!n) return NULL; + + return (void *)cs; } diff --git a/src/string/memcmp.c b/src/string/memcmp.c index bdbce9f..81b1e80 100644 --- a/src/string/memcmp.c +++ b/src/string/memcmp.c @@ -1,8 +1,33 @@ +#include <stddef.h> +#include <stdint.h> #include <string.h> -int memcmp(const void *vl, const void *vr, size_t n) +int memcmp(const void *s, const void *c, size_t n) { - const unsigned char *l=vl, *r=vr; - for (; n && *l == *r; n--, l++, r++); - return n ? *l-*r : 0; + const unsigned char *cs = (const unsigned char *)s; + const unsigned char *cc = (const unsigned char *)c; + const size_t *ws; + const size_t *wc; + + if ((uintptr_t)cs % sizeof(size_t) != (uintptr_t)cc % sizeof(size_t) + || n < sizeof(size_t)) { + goto bytewise; + } + + for (; (uintptr_t)cs % sizeof(size_t); cs++, cc++, n--) + if (*cs == *cc) return *cs - *cc; + + for (ws = (const size_t *)cs, wc = (const size_t *)cc + ; *ws == *wc && n >= sizeof(size_t) + ; ws++, wc++, n -= sizeof(size_t)); + cs = (const unsigned char *)ws; + cc = (const unsigned char *)wc; + +bytewise: + for(; *cs == *cc; cs++, cc++, n--) { + if (!n) return 0; + } + + return *cs - *cc; } + diff --git a/src/string/memcpy.c b/src/string/memcpy.c index 8e98302..c34185c 100644 --- a/src/string/memcpy.c +++ b/src/string/memcpy.c @@ -1,29 +1,29 @@ -#include <string.h> -#include <stdlib.h> +#include <stddef.h> #include <stdint.h> +#include <string.h> -#define SS (sizeof(size_t)) -#define ALIGN (sizeof(size_t)-1) -#define ONES ((size_t)-1/UCHAR_MAX) - -void *memcpy(void *restrict dest, const void *restrict src, size_t n) +void *memcpy(void *restrict d, const void *restrict s, size_t n) { - unsigned char *d = dest; - const unsigned char *s = src; + unsigned char *cd = (unsigned char *)d; + const unsigned char *cs = (const unsigned char *)s; + size_t *wd; + const size_t *ws; - if (((uintptr_t)d & ALIGN) != ((uintptr_t)s & ALIGN)) - goto misaligned; + if ((uintptr_t)cd % sizeof(size_t) != (uintptr_t)cs % sizeof(size_t) + || n < sizeof(size_t)) { + goto bytewise; + } - for (; ((uintptr_t)d & ALIGN) && n; n--) *d++ = *s++; - if (n) { - size_t *wd = (void *)d; - const size_t *ws = (const void *)s; + for (; (uintptr_t)cd % sizeof(size_t); *cd++ = *cs++, n--); - for (; n>=SS; n-=SS) *wd++ = *ws++; - d = (void *)wd; - s = (const void *)ws; -misaligned: - for (; n; n--) *d++ = *s++; - } - return dest; + for (wd = (size_t *)cd, ws = (const size_t *)cs + ; n >= sizeof(size_t) + ; n -= sizeof(size_t), *wd++ = *ws++); + cd = (unsigned char *)wd; + cs = (const unsigned char *)ws; + +bytewise: + for (; n; *cd++ = *cs++, n--); + + return d; } diff --git a/src/string/memrchr.c b/src/string/memrchr.c index a78e9d6..e9bb838 100644 --- a/src/string/memrchr.c +++ b/src/string/memrchr.c @@ -1,12 +1,34 @@ +#include <stddef.h> +#include <stdint.h> #include <string.h> #include "libc.h" -void *__memrchr(const void *m, int c, size_t n) +#define HIGHS(x) ((x) - ((x)*0-1) / 255 * 128) +#define LOWS(x) (((x)*0-1) / 255) +#define has_char(x, c) ((x) - LOWS(x) & ~(x) & HIGHS(x) ^ LOWS(x) * (c)) + +void *__memrchr(const void *s, int c, size_t n) { - const unsigned char *s = m; + const unsigned char *cs = s; + const size_t *ws; + c = (unsigned char)c; - while (n--) if (s[n]==c) return (void *)(s+n); - return 0; + + if (n < sizeof(size_t)) goto bytewise; + + for (; (uintptr_t)s % sizeof(size_t); cs++, n--) + if (cs[n] == c) return (void *)(cs + n); + + for (ws = (const size_t *)cs + n + ; !has_char(*ws, c) && n >= sizeof(size_t) + ; ws--, n -= sizeof(size_t)); + cs = (const unsigned char *)ws; + +bytewise: + for (; n; n--) + if (cs[n] == c) return (void *)(cs + n); + + return NULL; } weak_alias(__memrchr, memrchr); diff --git a/src/string/memset.c b/src/string/memset.c index 20e47c4..774829d 100644 --- a/src/string/memset.c +++ b/src/string/memset.c @@ -1,21 +1,28 @@ -#include <string.h> -#include <stdlib.h> +#include <stddef.h> #include <stdint.h> -#include <limits.h> +#include <string.h> -#define SS (sizeof(size_t)) -#define ALIGN (sizeof(size_t)-1) -#define ONES ((size_t)-1/UCHAR_MAX) +#define LOWS(x) (((x)*0-1) / 255) -void *memset(void *dest, int c, size_t n) +void *memset(void *d, int c, size_t n) { - unsigned char *s = dest; + unsigned char *cd = (unsigned char *)d; + const size_t wc = LOWS(wc) * (unsigned char)c; + size_t *wd; + c = (unsigned char)c; - for (; ((uintptr_t)s & ALIGN) && n; n--) *s++ = c; - if (n) { - size_t *w, k = ONES * c; - for (w = (void *)s; n>=SS; n-=SS, w++) *w = k; - for (s = (void *)w; n; n--, s++) *s = c; - } - return dest; + + if (n < sizeof(size_t)) goto bytewise; + + for (; (uintptr_t)d % sizeof(size_t); *cd++ = c, n--); + + for (wd = (size_t *)cd + ; n >= sizeof(size_t) + ; *wd++ = wc, n -= sizeof(size_t)); + cd = (unsigned char *)wd; + +bytewise: + for (; n; *cd++ = c, n--); + + return d; } diff --git a/src/string/stpcpy.c b/src/string/stpcpy.c index feb9eb8..6608c38 100644 --- a/src/string/stpcpy.c +++ b/src/string/stpcpy.c @@ -1,27 +1,31 @@ +#include <stddef.h> #include <string.h> -#include <stdlib.h> #include <stdint.h> -#include <limits.h> #include "libc.h" -#define ALIGN (sizeof(size_t)) -#define ONES ((size_t)-1/UCHAR_MAX) -#define HIGHS (ONES * (UCHAR_MAX/2+1)) -#define HASZERO(x) ((x)-ONES & ~(x) & HIGHS) +#define HIGHS(x) ((x) - ((x)*0-1) / 255 * 128) +#define LOWS(x) (((x)*0-1) / 255) +#define has_zero(x) ((x) - LOWS(x) & ~(x) & HIGHS(x)) char *__stpcpy(char *restrict d, const char *restrict s) { size_t *wd; const size_t *ws; - if ((uintptr_t)s % ALIGN == (uintptr_t)d % ALIGN) { - for (; (uintptr_t)s % ALIGN; s++, d++) - if (!(*d=*s)) return d; - wd=(void *)d; ws=(const void *)s; - for (; !HASZERO(*ws); *wd++ = *ws++); - d=(void *)wd; s=(const void *)ws; - } - for (; (*d=*s); s++, d++); + if ((uintptr_t)s % sizeof(size_t) != (uintptr_t)d % sizeof(size_t)) + goto bytewise; + + for (; (uintptr_t)s % sizeof(size_t); s++, d++) + if (!(*d = *s)) return d; + + for (wd = (size_t *)d, ws = (const size_t *)s + ; !has_zero(*ws); wd++, ws++, *wd = *ws); + + d = (char *)wd; + s = (const char *)ws; + +bytewise: + for (; (*d = *s); d++, s++); return d; } diff --git a/src/string/stpncpy.c b/src/string/stpncpy.c index 0a2c2a9..c38d98d 100644 --- a/src/string/stpncpy.c +++ b/src/string/stpncpy.c @@ -1,32 +1,36 @@ +#include <stddef.h> #include <string.h> -#include <stdlib.h> #include <stdint.h> -#include <limits.h> #include "libc.h" -#define ALIGN (sizeof(size_t)-1) -#define ONES ((size_t)-1/UCHAR_MAX) -#define HIGHS (ONES * (UCHAR_MAX/2+1)) -#define HASZERO(x) ((x)-ONES & ~(x) & HIGHS) +#define HIGHS(x) ((x) - ((x)*0-1) / 255 * 128) +#define LOWS(x) (((x)*0-1) / 255) +#define has_zero(x) ((x) - LOWS(x) & ~(x) & HIGHS(x)) char *__stpncpy(char *restrict d, const char *restrict s, size_t n) { size_t *wd; const size_t *ws; - if (((uintptr_t)s & ALIGN) == ((uintptr_t)d & ALIGN)) { - for (; ((uintptr_t)s & ALIGN) && n && (*d=*s); n--, s++, d++); - if (!n || !*s) goto tail; - wd=(void *)d; ws=(const void *)s; - for (; n>=sizeof(size_t) && !HASZERO(*ws); - n-=sizeof(size_t), ws++, wd++) *wd = *ws; - d=(void *)wd; s=(const void *)ws; - } - for (; n && (*d=*s); n--, s++, d++); -tail: + if ((uintptr_t)s % sizeof(size_t) == (uintptr_t)d % sizeof(size_t)) + goto bytewise; + + for (; (uintptr_t)s % sizeof(size_t) && (*d = *s); d++, s++, n--) + if (!n || !*s) goto terminate; + + for (wd = (size_t *)d, ws = (const size_t *)s + ; !has_zero(*ws) && n >= sizeof(size_t) + ; n -= sizeof(size_t), ws++, wd++, *wd = *ws); + + d = (char *)wd; + s = (const char *)ws; + +bytewise: + for (; (*d = *s) && n; d++, s++, n--); +terminate: memset(d, 0, n); + return d; } weak_alias(__stpncpy, stpncpy); - diff --git a/src/string/strcat.c b/src/string/strcat.c index 33f749b..0919793 100644 --- a/src/string/strcat.c +++ b/src/string/strcat.c @@ -1,7 +1,8 @@ #include <string.h> -char *strcat(char *restrict dest, const char *restrict src) +char *strcat(char *restrict d, const char *restrict s) { - strcpy(dest + strlen(dest), src); - return dest; + strcpy(d + strlen(d), s); + + return d; } diff --git a/src/string/strchrnul.c b/src/string/strchrnul.c index ceae4d4..cebd063 100644 --- a/src/string/strchrnul.c +++ b/src/string/strchrnul.c @@ -1,26 +1,30 @@ +#include <stddef.h> #include <string.h> -#include <stdlib.h> #include <stdint.h> -#include <limits.h> #include "libc.h" -#define ALIGN (sizeof(size_t)) -#define ONES ((size_t)-1/UCHAR_MAX) -#define HIGHS (ONES * (UCHAR_MAX/2+1)) -#define HASZERO(x) ((x)-ONES & ~(x) & HIGHS) +#define HIGHS(x) ((x) - ((x)*0-1) / 255 * 128) +#define LOWS(x) (((x)*0-1) / 255) +#define has_zero(x) ((x) - LOWS(x) & ~(x) & HIGHS(x)) +#define has_char(x, c) ((x) - LOWS(x) & ~(x) & HIGHS(x) ^ LOWS(x) * (c)) char *__strchrnul(const char *s, int c) { - size_t *w, k; + const size_t *ws; c = (unsigned char)c; + if (!c) return (char *)s + strlen(s); - for (; (uintptr_t)s % ALIGN; s++) + for (; (uintptr_t)s % sizeof(size_t); s++) if (!*s || *(unsigned char *)s == c) return (char *)s; - k = ONES * c; - for (w = (void *)s; !HASZERO(*w) && !HASZERO(*w^k); w++); - for (s = (void *)w; *s && *(unsigned char *)s != c; s++); + + for (ws = (const size_t *)s; !has_zero(*ws) && !has_char(*ws, c); ws++); + + s = (const char *)ws; + + for (; *s && *(unsigned char *)s != c; s++); + return (char *)s; } diff --git a/src/string/strcmp.c b/src/string/strcmp.c index 91eb740..98b5e58 100644 --- a/src/string/strcmp.c +++ b/src/string/strcmp.c @@ -1,7 +1,35 @@ +#include <stddef.h> +#include <stdint.h> #include <string.h> +#define HIGHS(x) ((x) - ((x)*0-1) / 255 * 128) +#define LOWS(x) (((x)*0-1) / 255) +#define has_zero(x) ((x) - LOWS(x) & ~(x) & HIGHS(x)) + +#undef strcmp int strcmp(const char *l, const char *r) { - for (; *l==*r && *l && *r; l++, r++); + const size_t *wl; + const size_t *wr; + + if ((uintptr_t)l % sizeof(size_t) != (uintptr_t)r % sizeof(size_t)) + goto bytewise; + + for (; (uintptr_t)l % sizeof(size_t); l++, r++) { + if (*l != *r || !*l || !*r) { + return *(unsigned char *)l + - *(unsigned char *)r; + } + } + + for (wl = (const size_t *)l, wr = (const size_t *)r + ; has_zero(*wl) || has_zero(*wr) && *wl == *wr + ; wl++, wr++); + l = (const char *)wl; + r = (const char *)wr; + +bytewise: + for(; *l == *r && *l && *r; l++, r++); + return *(unsigned char *)l - *(unsigned char *)r; } diff --git a/src/string/strcpy.c b/src/string/strcpy.c index f7e3ba3..2883e93 100644 --- a/src/string/strcpy.c +++ b/src/string/strcpy.c @@ -4,13 +4,6 @@ char *__stpcpy(char *, const char *); char *strcpy(char *restrict dest, const char *restrict src) { -#if 1 __stpcpy(dest, src); return dest; -#else - const unsigned char *s = src; - unsigned char *d = dest; - while ((*d++ = *s++)); - return dest; -#endif } diff --git a/src/string/strlcpy.c b/src/string/strlcpy.c index 4d3ff92..42b63e1 100644 --- a/src/string/strlcpy.c +++ b/src/string/strlcpy.c @@ -1,32 +1,40 @@ -#include <string.h> -#include <stdlib.h> +#include <stddef.h> #include <stdint.h> -#include <limits.h> -#include "libc.h" +#include <string.h> -#define ALIGN (sizeof(size_t)-1) -#define ONES ((size_t)-1/UCHAR_MAX) -#define HIGHS (ONES * (UCHAR_MAX/2+1)) -#define HASZERO(x) ((x)-ONES & ~(x) & HIGHS) +#define HIGHS(x) ((x) - ((x)*0-1) / 255 * 128) +#define LOWS(x) (((x)*0-1) / 255) +#define has_zero(x) ((x) - LOWS(x) & ~(x) & HIGHS(x)) size_t strlcpy(char *d, const char *s, size_t n) { - char *d0 = d; + char *ds = d; size_t *wd; const size_t *ws; - if (!n--) goto finish; - if (((uintptr_t)s & ALIGN) == ((uintptr_t)d & ALIGN)) { - for (; ((uintptr_t)s & ALIGN) && n && (*d=*s); n--, s++, d++); - if (n && *s) { - wd=(void *)d; ws=(const void *)s; - for (; n>=sizeof(size_t) && !HASZERO(*ws); - n-=sizeof(size_t), ws++, wd++) *wd = *ws; - d=(void *)wd; s=(const void *)ws; - } + if (!n--) goto ret; + + if ((uintptr_t)d % sizeof(size_t) != (uintptr_t)s % sizeof(size_t) + || n < sizeof(size_t)) { + goto bytewise; } - for (; n && (*d=*s); n--, s++, d++); - *d = 0; -finish: - return d-d0 + strlen(s); + + for (; (uintptr_t)s % sizeof(size_t); *d++ = *s++, n--) + if (!*s) goto terminate; + + for (wd = (size_t *)d, ws = (const size_t *)s + ; !has_zero(*ws) && n >= sizeof(size_t) + ; *wd++ = *ws++, n -= sizeof(size_t)) + + d = (char *)wd; + s = (const char *)ws; + +bytewise: + for (; (*d = *s) && n; d++, s++, n--); + +terminate: + *d = '\0'; + +ret: + return (d - ds + strlen(s)); } -- 1.8.1.2
Powered by blists - more mailing lists
Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.