chiark / gitweb /
[PATCH] sync with latest version of klibc (0.107)
[elogind.git] / klibc / klibc / strspn.c
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 inline void
15 set_bit(unsigned long *bitmap, unsigned int bit)
16 {
17   bitmap[bit/LONG_BIT] |= 1UL << (bit%LONG_BIT);
18 }
19
20 static inline int
21 test_bit(unsigned long *bitmap, unsigned int bit)
22 {
23   return (int)(bitmap[bit/LONG_BIT] >> (bit%LONG_BIT)) & 1;
24 }
25
26 static size_t
27 strxspn(const char *s, const char *map, int parity)
28 {
29   unsigned long matchmap[((1 << CHAR_BIT)+LONG_BIT-1)/LONG_BIT];
30   size_t n = 0;
31
32   /* Create bitmap */
33   memset(matchmap, 0, sizeof matchmap);
34   while ( *map )
35     set_bit(matchmap, (unsigned char) *map++);
36
37   /* Make sure the null character never matches */
38   if ( parity )
39     set_bit(matchmap, 0);
40
41   /* Calculate span length */
42   while ( test_bit(matchmap, (unsigned char) *s++)^parity )
43     n++;
44
45   return n;
46 }
47
48 size_t
49 strspn(const char *s, const char *accept)
50 {
51   return strxspn(s, accept, 0);
52 }
53
54 size_t
55 strcspn(const char *s, const char *reject)
56 {
57   return strxspn(s, reject, 1);
58 }
59
60 char *
61 strpbrk(const char *s, const char *accept)
62 {
63   const char *ss = s+strxspn(s, accept, 1);
64   
65   return *ss ? (char *)ss : NULL;
66 }
67