Home | History | Annotate | Download | only in lib
      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