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