xref: /netbsd-src/common/lib/libc/string/strcspn.c (revision 8fdd01b3ee3648a1f82d1d1e902a4d74eef2c998)
1*8fdd01b3Smrg /*	$NetBSD: strcspn.c,v 1.2 2018/02/04 01:13:45 mrg Exp $	*/
24ab4902eSlneto 
34ab4902eSlneto /*-
44ab4902eSlneto  * Copyright (c) 2008 Joerg Sonnenberger
54ab4902eSlneto  * All rights reserved.
64ab4902eSlneto  *
74ab4902eSlneto  * Redistribution and use in source and binary forms, with or without
84ab4902eSlneto  * modification, are permitted provided that the following conditions
94ab4902eSlneto  * are met:
104ab4902eSlneto  * 1. Redistributions of source code must retain the above copyright
114ab4902eSlneto  *    notice, this list of conditions and the following disclaimer.
124ab4902eSlneto  * 2. Redistributions in binary form must reproduce the above copyright
134ab4902eSlneto  *    notice, this list of conditions and the following disclaimer in the
144ab4902eSlneto  *    documentation and/or other materials provided with the distribution.
154ab4902eSlneto  *
164ab4902eSlneto  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
174ab4902eSlneto  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
184ab4902eSlneto  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
194ab4902eSlneto  * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
204ab4902eSlneto  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
214ab4902eSlneto  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
224ab4902eSlneto  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
234ab4902eSlneto  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
244ab4902eSlneto  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
254ab4902eSlneto  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
264ab4902eSlneto  */
274ab4902eSlneto 
284ab4902eSlneto #include <sys/cdefs.h>
29*8fdd01b3Smrg __RCSID("$NetBSD: strcspn.c,v 1.2 2018/02/04 01:13:45 mrg Exp $");
304ab4902eSlneto 
314ab4902eSlneto #if !defined(_KERNEL) && !defined(_STANDALONE)
324ab4902eSlneto #include <assert.h>
334ab4902eSlneto #include <inttypes.h>
344ab4902eSlneto #include <limits.h>
354ab4902eSlneto #include <string.h>
364ab4902eSlneto #else
374ab4902eSlneto #include <lib/libkern/libkern.h>
384ab4902eSlneto #endif
394ab4902eSlneto 
404ab4902eSlneto /* 64bit version is in strspn.c */
414ab4902eSlneto #if ULONG_MAX != 0xffffffffffffffffull
424ab4902eSlneto 
434ab4902eSlneto size_t
strcspn(const char * s,const char * charset)444ab4902eSlneto strcspn(const char *s, const char *charset)
454ab4902eSlneto {
464ab4902eSlneto 	static const uint8_t idx[8] = { 1, 2, 4, 8, 16, 32, 64, 128 };
474ab4902eSlneto 	const char *t;
484ab4902eSlneto 	uint8_t set[32];
494ab4902eSlneto #define UC(a) ((unsigned int)(unsigned char)(a))
504ab4902eSlneto 
514ab4902eSlneto 	if (charset[0] == '\0')
524ab4902eSlneto 		return strlen(s);
534ab4902eSlneto 	if (charset[1] == '\0') {
544ab4902eSlneto 		for (t = s; *t != '\0'; ++t)
554ab4902eSlneto 			if (*t == *charset)
564ab4902eSlneto 				break;
574ab4902eSlneto 		return t - s;
584ab4902eSlneto 	}
594ab4902eSlneto 
604ab4902eSlneto 	(void)memset(set, 0, sizeof(set));
614ab4902eSlneto 
624ab4902eSlneto 	for (; *charset != '\0'; ++charset)
634ab4902eSlneto 		set[UC(*charset) >> 3] |= idx[UC(*charset) & 7];
644ab4902eSlneto 
654ab4902eSlneto 	for (t = s; *t != '\0'; ++t)
664ab4902eSlneto 		if (set[UC(*t) >> 3] & idx[UC(*t) & 7])
674ab4902eSlneto 			break;
684ab4902eSlneto 	return t - s;
694ab4902eSlneto }
704ab4902eSlneto 
714ab4902eSlneto #endif
72