strspn.c revision 256281
1234353Sdim/*- 2198090Srdivacky * Copyright (c) 2005 David Schultz <das@FreeBSD.ORG> 3198090Srdivacky * All rights reserved. 4198090Srdivacky * 5198090Srdivacky * Redistribution and use in source and binary forms, with or without 6198090Srdivacky * modification, are permitted provided that the following conditions 7198090Srdivacky * are met: 8198090Srdivacky * 1. Redistributions of source code must retain the above copyright 9198090Srdivacky * notice, this list of conditions and the following disclaimer. 10198090Srdivacky * 2. Redistributions in binary form must reproduce the above copyright 11198090Srdivacky * notice, this list of conditions and the following disclaimer in the 12198090Srdivacky * documentation and/or other materials provided with the distribution. 13198090Srdivacky * 14198090Srdivacky * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15198090Srdivacky * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16198090Srdivacky * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17198090Srdivacky * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18249423Sdim * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19249423Sdim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20198090Srdivacky * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21198090Srdivacky * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22198090Srdivacky * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23224145Sdim * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24224145Sdim * SUCH DAMAGE. 25224145Sdim */ 26198090Srdivacky 27212904Sdim#include <sys/cdefs.h> 28212904Sdim__FBSDID("$FreeBSD: stable/10/lib/libc/string/strspn.c 144545 2005-04-02 18:52:44Z das $"); 29198090Srdivacky 30224145Sdim#include <sys/types.h> 31212904Sdim#include <limits.h> 32218893Sdim#include <string.h> 33198090Srdivacky 34198090Srdivacky#define IDX(c) ((u_char)(c) / LONG_BIT) 35198892Srdivacky#define BIT(c) ((u_long)1 << ((u_char)(c) % LONG_BIT)) 36218893Sdim 37198090Srdivackysize_t 38234353Sdimstrspn(const char *s, const char *charset) 39234353Sdim{ 40234353Sdim /* 41198090Srdivacky * NB: idx and bit are temporaries whose use causes gcc 3.4.2 to 42198090Srdivacky * generate better code. Without them, gcc gets a little confused. 43198090Srdivacky */ 44198090Srdivacky const char *s1; 45198090Srdivacky u_long bit; 46198090Srdivacky u_long tbl[(UCHAR_MAX + 1) / LONG_BIT]; 47198090Srdivacky int idx; 48198090Srdivacky 49263508Sdim if(*s == '\0') 50198892Srdivacky return (0); 51198090Srdivacky 52218893Sdim#if LONG_BIT == 64 /* always better to unroll on 64-bit architectures */ 53218893Sdim tbl[3] = tbl[2] = tbl[1] = tbl[0] = 0; 54218893Sdim#else 55208599Srdivacky for (idx = 0; idx < sizeof(tbl) / sizeof(tbl[0]); idx++) 56218893Sdim tbl[idx] = 0; 57218893Sdim#endif 58218893Sdim for (; *charset != '\0'; charset++) { 59218893Sdim idx = IDX(*charset); 60198090Srdivacky bit = BIT(*charset); 61198090Srdivacky tbl[idx] |= bit; 62198090Srdivacky } 63198090Srdivacky 64212904Sdim for(s1 = s; ; s1++) { 65198090Srdivacky idx = IDX(*s1); 66198090Srdivacky bit = BIT(*s1); 67198090Srdivacky if ((tbl[idx] & bit) == 0) 68210299Sed break; 69210299Sed } 70198090Srdivacky return (s1 - s); 71198090Srdivacky} 72198090Srdivacky