#include #include #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 BITOP(A, B, OP) \ ((A)[(size_t)(B) / (8 * sizeof *(A))] OP(size_t) 1 \ << ((size_t)(B) % (8 * sizeof *(A)))) char *strchrnul(const char *s, int c) { size_t *w; size_t k; c = (unsigned char)c; if (!c) { return (char *)s + strlen(s); } for (; (uintptr_t)s % ALIGN; 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++) ; return (char *)s; } char *strchr(const char *s, int c) { char *r = strchrnul(s, c); return *(unsigned char *)r == (unsigned char)c ? r : 0; } size_t lfind(const char *str, const char accept) { return (size_t)strchr(str, accept); } size_t strspn(const char *s, const char *c) { const char *a = s; size_t byteset[32 / sizeof(size_t)] = {0}; if (!c[0]) { return 0; } if (!c[1]) { for (; *s == *c; s++) { return s - a; } } for (; *c && BITOP(byteset, *(unsigned char *)c, |=); c++) ; for (; *s && BITOP(byteset, *(unsigned char *)s, &); s++) ; return s - a; } size_t strcspn(const char *s, const char *c) { const char *a = s; if (c[0] && c[1]) { size_t byteset[32 / sizeof(size_t)] = {0}; for (; *c && BITOP(byteset, *(unsigned char *)c, |=); c++) ; for (; *s && !BITOP(byteset, *(unsigned char *)s, &); s++) ; return s - a; } return strchrnul(s, *c) - a; } char *strpbrk(const char *s, const char *b) { s += strcspn(s, b); return *s ? (char *)s : 0; } char *strtok_r(char *str, const char *delim, char **sp) { int i = 0; int len = strlen(delim); /* Were we given any delimiters? */ if (len == 0) { return NULL; } /* If we weren't given a string, and save pointer is NULL, return. */ if (!str && !sp) { return NULL; } /* If we were given a string, initialise sp for subsequent calls. */ if (str) { *sp = str; } /* Go to the start of the substring, skipping any delimiters. */ char *p_start = *sp; while (1) { for (i = 0; i < len; i++) { if (*p_start == delim[i]) { p_start++; break; } } if (i == len) { *sp = p_start; break; } } /* Are we at the end of the string? */ if (**sp == '\0') { *sp = NULL; return *sp; } /* Find the end of the substring, and replace the delimiter with null */ while (**sp != '\0') { for (i = 0; i < len; i++) { if (**sp == delim[i]) { **sp = '\0'; break; } } (*sp)++; if (i < len) { break; } } return p_start; }