1 /* $NetBSD: string.h,v 1.11 2021/12/19 11:45:01 riastradh Exp $ */ 2 3 /*- 4 * Copyright (c) 2013 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Taylor R. Campbell. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 #ifndef _LINUX_STRING_H_ 33 #define _LINUX_STRING_H_ 34 35 #include <sys/types.h> 36 #include <sys/cdefs.h> 37 #include <sys/errno.h> 38 #include <sys/null.h> 39 40 #include <linux/slab.h> 41 42 static inline void * 43 memchr_inv(const void *buffer, int c, size_t len) 44 { 45 const uint8_t byte = c; /* XXX lose */ 46 const char *p; 47 48 for (p = buffer; len-- > 0; p++) 49 if (*p != byte) 50 return __UNCONST(p); 51 52 return NULL; 53 } 54 55 static inline void * 56 kmemdup(const void *src, size_t len, gfp_t gfp) 57 { 58 void *dst; 59 60 dst = kmalloc(len, gfp); 61 if (dst == NULL) 62 return NULL; 63 64 (void)memcpy(dst, src, len); 65 return dst; 66 } 67 68 static inline char * 69 kstrndup(const char *src, size_t maxlen, gfp_t gfp) 70 { 71 char *dst; 72 size_t len; 73 74 if (src == NULL) 75 return NULL; 76 77 len = strnlen(src, maxlen); 78 dst = kmalloc(len + 1, gfp); 79 if (dst == NULL) 80 return NULL; 81 82 (void)memcpy(dst, src, len); 83 dst[len] = '\0'; 84 85 return dst; 86 } 87 88 static inline char * 89 kstrdup(const char *src, gfp_t gfp) 90 { 91 92 if (src == NULL) 93 return NULL; 94 return kstrndup(src, strlen(src), gfp); 95 } 96 97 static inline ssize_t 98 strscpy(char *dst, const char *src, size_t dstsize) 99 { 100 size_t n = dstsize; 101 102 /* If no space for a NUL terminator, fail. */ 103 if (n == 0) 104 return -E2BIG; 105 106 /* Copy until we get a NUL terminator or the end of the buffer. */ 107 while ((*dst++ = *src++) != '\0') { 108 if (__predict_false(--n == 0)) { 109 dst[-1] = '\0'; /* NUL-terminate */ 110 return -E2BIG; 111 } 112 } 113 114 /* Return the number of bytes copied, excluding NUL. */ 115 return dstsize - n; 116 } 117 118 static inline void * 119 memset32(uint32_t *buf, uint32_t v, size_t n) 120 { 121 uint32_t *p = buf; 122 123 while (n --> 0) 124 *p++ = v; 125 126 return buf; 127 } 128 129 static inline void * 130 memset64(uint64_t *buf, uint64_t v, size_t n) 131 { 132 uint64_t *p = buf; 133 134 while (n --> 0) 135 *p++ = v; 136 137 return buf; 138 } 139 140 static inline void * 141 memset_p(void **buf, void *v, size_t n) 142 { 143 void **p = buf; 144 145 while (n --> 0) 146 *p++ = v; 147 148 return buf; 149 } 150 151 #define str_has_prefix(str, prefix) strncmp(str, prefix, strlen(prefix)) 152 153 static inline int 154 match_string(const char *const *haystack, size_t n, const char *needle) 155 { 156 int i; 157 158 for (i = 0; i < n; i++) { 159 if (haystack[i] == NULL) 160 break; 161 if (strcmp(haystack[i], needle) == 0) 162 return i; 163 if (i == INT_MAX) 164 break; 165 } 166 return -EINVAL; 167 } 168 169 #endif /* _LINUX_STRING_H_ */ 170