11.2Smrg/*	$NetBSD: strcspn.c,v 1.2 2018/02/04 01:13:45 mrg Exp $	*/
21.1Slneto
31.1Slneto/*-
41.1Slneto * Copyright (c) 2008 Joerg Sonnenberger
51.1Slneto * All rights reserved.
61.1Slneto *
71.1Slneto * Redistribution and use in source and binary forms, with or without
81.1Slneto * modification, are permitted provided that the following conditions
91.1Slneto * are met:
101.1Slneto * 1. Redistributions of source code must retain the above copyright
111.1Slneto *    notice, this list of conditions and the following disclaimer.
121.1Slneto * 2. Redistributions in binary form must reproduce the above copyright
131.1Slneto *    notice, this list of conditions and the following disclaimer in the
141.1Slneto *    documentation and/or other materials provided with the distribution.
151.1Slneto *
161.1Slneto * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
171.1Slneto * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
181.1Slneto * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
191.1Slneto * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
201.1Slneto * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
211.1Slneto * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
221.1Slneto * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
231.1Slneto * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
241.1Slneto * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
251.1Slneto * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
261.1Slneto */
271.1Slneto
281.1Slneto#include <sys/cdefs.h>
291.2Smrg__RCSID("$NetBSD: strcspn.c,v 1.2 2018/02/04 01:13:45 mrg Exp $");
301.1Slneto
311.1Slneto#if !defined(_KERNEL) && !defined(_STANDALONE)
321.1Slneto#include <assert.h>
331.1Slneto#include <inttypes.h>
341.1Slneto#include <limits.h>
351.1Slneto#include <string.h>
361.1Slneto#else
371.1Slneto#include <lib/libkern/libkern.h>
381.1Slneto#endif
391.1Slneto
401.1Slneto/* 64bit version is in strspn.c */
411.1Slneto#if ULONG_MAX != 0xffffffffffffffffull
421.1Slneto
431.1Slnetosize_t
441.1Slnetostrcspn(const char *s, const char *charset)
451.1Slneto{
461.1Slneto	static const uint8_t idx[8] = { 1, 2, 4, 8, 16, 32, 64, 128 };
471.1Slneto	const char *t;
481.1Slneto	uint8_t set[32];
491.1Slneto#define UC(a) ((unsigned int)(unsigned char)(a))
501.1Slneto
511.1Slneto	if (charset[0] == '\0')
521.1Slneto		return strlen(s);
531.1Slneto	if (charset[1] == '\0') {
541.1Slneto		for (t = s; *t != '\0'; ++t)
551.1Slneto			if (*t == *charset)
561.1Slneto				break;
571.1Slneto		return t - s;
581.1Slneto	}
591.1Slneto
601.1Slneto	(void)memset(set, 0, sizeof(set));
611.1Slneto
621.1Slneto	for (; *charset != '\0'; ++charset)
631.1Slneto		set[UC(*charset) >> 3] |= idx[UC(*charset) & 7];
641.1Slneto
651.1Slneto	for (t = s; *t != '\0'; ++t)
661.1Slneto		if (set[UC(*t) >> 3] & idx[UC(*t) & 7])
671.1Slneto			break;
681.1Slneto	return t - s;
691.1Slneto}
701.1Slneto
711.1Slneto#endif
72