| 37 | #define BIT(c) ((u_long)1 << ((u_char)(c) % LONG_BIT)) |
| 38 | |
| 39 | size_t |
| 40 | strcspn(const char * __restrict s, const char * __restrict charset) |
| 41 | { |
| 42 | /* |
| 43 | * NB: idx and bit are temporaries whose use causes gcc 3.4.2 to |
| 44 | * generate better code. Without them, gcc gets a little confused. |
| 45 | */ |
| 46 | const char *s1; |
| 47 | u_long bit; |
| 48 | u_long tbl[(UCHAR_MAX + 1) / LONG_BIT]; |
| 49 | int idx; |
| 50 | |
| 51 | if(*s == '\0') |
| 52 | return (0); |
| 53 | |
| 54 | #if LONG_BIT == 64 /* always better to unroll on 64-bit architectures */ |
| 55 | tbl[0] = 1; |
| 56 | tbl[3] = tbl[2] = tbl[1] = 0; |
| 57 | #else |
| 58 | for (tbl[0] = idx = 1; idx < sizeof(tbl) / sizeof(tbl[0]); idx++) |
| 59 | tbl[idx] = 0; |
| 60 | #endif |
| 61 | for (; *charset != '\0'; charset++) { |
| 62 | idx = IDX(*charset); |
| 63 | bit = BIT(*charset); |
| 64 | tbl[idx] |= bit; |
| 65 | } |
| 66 | |
| 67 | for(s1 = s; ; s1++) { |
| 68 | idx = IDX(*s1); |
| 69 | bit = BIT(*s1); |
| 70 | if ((tbl[idx] & bit) != 0) |
| 71 | break; |
| 72 | } |
| 73 | return (s1 - s); |
| 74 | } |
no outgoing calls
no test coverage detected