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 14 static void set_bit(unsigned long *bitmap, unsigned int bit) 15 { 16 bitmap[bit / LONG_BIT] |= 1UL << (bit % LONG_BIT); 17 } 18 19 static int test_bit(unsigned long *bitmap, unsigned int bit) 20 { 21 return (int)(bitmap[bit / LONG_BIT] >> (bit % LONG_BIT)) & 1; 22 } 23 24 static 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 45 size_t strspn(const char *s, const char *accept) 46 { 47 return strxspn(s, accept, 0); 48 } 49 50 size_t strcspn(const char *s, const char *reject) 51 { 52 return strxspn(s, reject, 1); 53 } 54 55 char *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