|
Message-ID: <20130407092327.GQ30576@port70.net> Date: Sun, 7 Apr 2013 11:23:27 +0200 From: Szabolcs Nagy <nsz@...t70.net> To: musl@...ts.openwall.com Subject: Re: [PATCH] String: expand to word size && refactor || refactor * Nathan McSween <nwmcsween@...il.com> [2013-04-06 20:38:16 +0000]: > 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)) the meaning of the new HIGHS is unclear the original macros are easier to read, HIGHS is probably not needed and i think size_t can be hardcoded, so #define ONES ((size_t)-1/255) #define HASZERO(x) ((x)-ONES & ~(x) & ONES*128) a has_char can be useful for clarity (but the original code made sure ones*c is only calculated once) and then i'd use #define HASCHAR(x,c) HASZERO((x) ^ ONES*(unsigned char)(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 (; ; *cd = *cs, cd++, cs++) > + if (*cs == c) return cd + 1; if ((*cd++ = *cs++) == c) return cd; is more idiomatic with your code the c at the end is not copied, this is a bug the n limit is not accounted for, this is a bug the code below is never reached, this is another bug > + 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; > } i think you should test and benchmark before submitting such code
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.