1f0ceb98fSDavid Schultz /*- 2f0ceb98fSDavid Schultz * Copyright (c) 2005 David Schultz <das@FreeBSD.ORG> 3f0ceb98fSDavid Schultz * All rights reserved. 475737f34SGleb Smirnoff * 575737f34SGleb Smirnoff * Redistribution and use in source and binary forms, with or without 675737f34SGleb Smirnoff * modification, are permitted provided that the following conditions 775737f34SGleb Smirnoff * are met: 875737f34SGleb Smirnoff * 1. Redistributions of source code must retain the above copyright 975737f34SGleb Smirnoff * notice, this list of conditions and the following disclaimer. 1075737f34SGleb Smirnoff * 2. Redistributions in binary form must reproduce the above copyright 1175737f34SGleb Smirnoff * notice, this list of conditions and the following disclaimer in the 1275737f34SGleb Smirnoff * documentation and/or other materials provided with the distribution. 1375737f34SGleb Smirnoff * 14f0ceb98fSDavid Schultz * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1575737f34SGleb Smirnoff * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1675737f34SGleb Smirnoff * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17f0ceb98fSDavid Schultz * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1875737f34SGleb Smirnoff * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1975737f34SGleb Smirnoff * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2075737f34SGleb Smirnoff * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2175737f34SGleb Smirnoff * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2275737f34SGleb Smirnoff * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2375737f34SGleb Smirnoff * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2475737f34SGleb Smirnoff * SUCH DAMAGE. 2575737f34SGleb Smirnoff */ 2675737f34SGleb Smirnoff 2775737f34SGleb Smirnoff #include <sys/cdefs.h> 2875737f34SGleb Smirnoff __FBSDID("$FreeBSD$"); 2975737f34SGleb Smirnoff 3075737f34SGleb Smirnoff #include <sys/libkern.h> 31f0ceb98fSDavid Schultz #include <sys/limits.h> 32f0ceb98fSDavid Schultz #include <sys/types.h> 3375737f34SGleb Smirnoff 34f0ceb98fSDavid Schultz #define IDX(c) ((u_char)(c) / LONG_BIT) 35f0ceb98fSDavid Schultz #define BIT(c) ((u_long)1 << ((u_char)(c) % LONG_BIT)) 36f0ceb98fSDavid Schultz 3775737f34SGleb Smirnoff size_t 38f0ceb98fSDavid Schultz strspn(const char *s, const char *charset) 3975737f34SGleb Smirnoff { 4075737f34SGleb Smirnoff /* 41f0ceb98fSDavid Schultz * NB: idx and bit are temporaries whose use causes gcc 3.4.2 to 42f0ceb98fSDavid Schultz * generate better code. Without them, gcc gets a little confused. 4375737f34SGleb Smirnoff */ 44f0ceb98fSDavid Schultz const char *s1; 45f0ceb98fSDavid Schultz u_long bit; 46f0ceb98fSDavid Schultz u_long tbl[(UCHAR_MAX + 1) / LONG_BIT]; 47f0ceb98fSDavid Schultz int idx; 48f0ceb98fSDavid Schultz 49f0ceb98fSDavid Schultz if(*s == '\0') 50f0ceb98fSDavid Schultz return (0); 51f0ceb98fSDavid Schultz 52f0ceb98fSDavid Schultz #if LONG_BIT == 64 /* always better to unroll on 64-bit architectures */ 53f0ceb98fSDavid Schultz tbl[3] = tbl[2] = tbl[1] = tbl[0] = 0; 54f0ceb98fSDavid Schultz #else 55f0ceb98fSDavid Schultz for (idx = 0; idx < sizeof(tbl) / sizeof(tbl[0]); idx++) 56f0ceb98fSDavid Schultz tbl[idx] = 0; 57f0ceb98fSDavid Schultz #endif 58f0ceb98fSDavid Schultz for (; *charset != '\0'; charset++) { 59f0ceb98fSDavid Schultz idx = IDX(*charset); 60f0ceb98fSDavid Schultz bit = BIT(*charset); 61f0ceb98fSDavid Schultz tbl[idx] |= bit; 62f0ceb98fSDavid Schultz } 63f0ceb98fSDavid Schultz 64f0ceb98fSDavid Schultz for(s1 = s; ; s1++) { 65f0ceb98fSDavid Schultz idx = IDX(*s1); 66f0ceb98fSDavid Schultz bit = BIT(*s1); 67f0ceb98fSDavid Schultz if ((tbl[idx] & bit) == 0) 68f0ceb98fSDavid Schultz break; 69f0ceb98fSDavid Schultz } 70f0ceb98fSDavid Schultz return (s1 - s); 7175737f34SGleb Smirnoff } 72