• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
set_bit(unsigned long * bitmap,unsigned int bit)14 static void set_bit(unsigned long *bitmap, unsigned int bit)
15 {
16     bitmap[bit / LONG_BIT] |= 1UL << (bit % LONG_BIT);
17 }
18 
test_bit(unsigned long * bitmap,unsigned int bit)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 
strxspn(const char * s,const char * map,int parity)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 
strspn(const char * s,const char * accept)45 size_t strspn(const char *s, const char *accept)
46 {
47     return strxspn(s, accept, 0);
48 }
49 
strcspn(const char * s,const char * reject)50 size_t strcspn(const char *s, const char *reject)
51 {
52     return strxspn(s, reject, 1);
53 }
54 
strpbrk(const char * s,const char * accept)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