| #include <string.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) |
| |
| #if defined(USE_COBALT_CUSTOMIZATIONS) |
| #ifdef __GNUC__ |
| __attribute__((no_sanitize("address"))) |
| #endif // __GNUC__ |
| #endif // defined(USE_COBALT_CUSTOMIZATIONS) |
| char *__stpncpy(char *restrict d, const char *restrict s, size_t n) |
| { |
| #ifdef __GNUC__ |
| typedef size_t __attribute__((__may_alias__)) word; |
| word *wd; |
| const word *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; |
| } |
| #endif |
| for (; n && (*d=*s); n--, s++, d++); |
| tail: |
| memset(d, 0, n); |
| return d; |
| } |
| |
| weak_alias(__stpncpy, stpncpy); |
| |