xref: /netbsd-src/common/lib/libc/string/strpbrk.c (revision 12ddec6097ece86a323a34fa78a7b9c66427619e)
1*12ddec60Schristos /*	$NetBSD: strpbrk.c,v 1.3 2024/01/20 14:55:11 christos 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*12ddec60Schristos __RCSID("$NetBSD: strpbrk.c,v 1.3 2024/01/20 14:55:11 christos 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 #define FAST_STRPBRK 1
414ab4902eSlneto #define UC(a) ((unsigned int)(unsigned char)(a))
424ab4902eSlneto 
434ab4902eSlneto #ifdef FAST_STRPBRK
444ab4902eSlneto #define ADD_NEW_TO_SET(i) (set[inv[i] = idx++] = (i))
454ab4902eSlneto #define IS_IN_SET(i) (inv[i] < idx && set[inv[i]] == (i))
464ab4902eSlneto #define ADD_TO_SET(i) (void)(IS_IN_SET(i) || /*LINTED no effect*/ADD_NEW_TO_SET(i))
474ab4902eSlneto #else
484ab4902eSlneto #define IS_IN_SET(i) (set[(i) >> 3] & idx[(i) & 7])
494ab4902eSlneto #define ADD_TO_SET(i) (void)(set[(i) >> 3] |= idx[(i) & 7])
504ab4902eSlneto #endif
514ab4902eSlneto 
524ab4902eSlneto char *
strpbrk(const char * s,const char * charset)534ab4902eSlneto strpbrk(const char *s, const char *charset)
544ab4902eSlneto {
554ab4902eSlneto #ifdef FAST_STRPBRK
564ab4902eSlneto 	uint8_t set[256], inv[256], idx = 0;
574ab4902eSlneto #else
584ab4902eSlneto 	static const size_t idx[8] = { 1, 2, 4, 8, 16, 32, 64, 128 };
594ab4902eSlneto 	uint8_t set[32];
604ab4902eSlneto 
614ab4902eSlneto 	(void)memset(set, 0, sizeof(set));
624ab4902eSlneto #endif
634ab4902eSlneto 
644ab4902eSlneto 	if (charset[0] == '\0')
654ab4902eSlneto 		return NULL;
664ab4902eSlneto 	if (charset[1] == '\0')
67*12ddec60Schristos 		return __UNCONST(strchr(s, charset[0]));
684ab4902eSlneto 
694ab4902eSlneto 	for (; *charset != '\0'; ++charset)
704ab4902eSlneto 		ADD_TO_SET(UC(*charset));
714ab4902eSlneto 
724ab4902eSlneto 	for (; *s != '\0'; ++s)
734ab4902eSlneto 		if (IS_IN_SET(UC(*s)))
744ab4902eSlneto 			return __UNCONST(s);
754ab4902eSlneto 	return NULL;
764ab4902eSlneto }
77