1/* 2 * strspn, strcspn 3 */ 4 5#include <string.h> 6#include <stddef.h> 7#include <inttypes.h> 8#include <limits.h> 9 10#ifndef LONG_BIT 11#define LONG_BIT (CHAR_BIT*sizeof(long)) 12#endif 13 14static void set_bit(unsigned long *bitmap, unsigned int bit) 15{ 16 bitmap[bit / LONG_BIT] |= 1UL << (bit % LONG_BIT); 17} 18 19static int test_bit(unsigned long *bitmap, unsigned int bit) 20{ 21 return (int)(bitmap[bit / LONG_BIT] >> (bit % LONG_BIT)) & 1; 22} 23 24static size_t strxspn(const char *s, const char *map, int parity) 25{ 26 unsigned long matchmap[((1 << CHAR_BIT) + LONG_BIT - 1) / LONG_BIT]; 27 size_t n = 0; 28 29 /* Create bitmap */ 30 memset(matchmap, 0, sizeof matchmap); 31 while (*map) 32 set_bit(matchmap, (unsigned char)*map++); 33 34 /* Make sure the null character never matches */ 35 if (parity) 36 set_bit(matchmap, 0); 37 38 /* Calculate span length */ 39 while (test_bit(matchmap, (unsigned char)*s++) ^ parity) 40 n++; 41 42 return n; 43} 44 45size_t strspn(const char *s, const char *accept) 46{ 47 return strxspn(s, accept, 0); 48} 49 50size_t strcspn(const char *s, const char *reject) 51{ 52 return strxspn(s, reject, 1); 53} 54 55char *strpbrk(const char *s, const char *accept) 56{ 57 const char *ss = s + strxspn(s, accept, 1); 58 59 return *ss ? (char *)ss : NULL; 60} 61