Remove building with NOCRYPTO option
[minix.git] / external / bsd / bind / dist / lib / isc / string.c
blob6c14d2ad7764a93076adab3091a4e983c4b945f7
1 /* $NetBSD: string.c,v 1.6 2014/12/10 04:37:59 christos Exp $ */
3 /*
4 * Copyright (C) 2004-2007, 2011, 2012, 2014 Internet Systems Consortium, Inc. ("ISC")
5 * Copyright (C) 1999-2001, 2003 Internet Software Consortium.
7 * Permission to use, copy, modify, and/or distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
11 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
12 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
13 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
14 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
16 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17 * PERFORMANCE OF THIS SOFTWARE.
21 * Copyright (c) 1990, 1993
22 * The Regents of the University of California. All rights reserved.
24 * Redistribution and use in source and binary forms, with or without
25 * modification, are permitted provided that the following conditions
26 * are met:
27 * 1. Redistributions of source code must retain the above copyright
28 * notice, this list of conditions and the following disclaimer.
29 * 2. Redistributions in binary form must reproduce the above copyright
30 * notice, this list of conditions and the following disclaimer in the
31 * documentation and/or other materials provided with the distribution.
32 * 3. Neither the name of the University nor the names of its contributors
33 * may be used to endorse or promote products derived from this software
34 * without specific prior written permission.
36 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
37 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
38 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
39 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
40 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
41 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
42 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
43 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
44 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
45 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
46 * SUCH DAMAGE.
49 /*! \file */
51 #include <config.h>
53 #include <ctype.h>
55 #include <isc/mem.h>
56 #include <isc/print.h>
57 #include <isc/region.h>
58 #include <isc/string.h>
59 #include <isc/util.h>
61 static char digits[] = "0123456789abcdefghijklmnoprstuvwxyz";
63 isc_uint64_t
64 isc_string_touint64(char *source, char **end, int base) {
65 isc_uint64_t tmp;
66 isc_uint64_t overflow;
67 char *s = source;
68 char *o;
69 char c;
71 if ((base < 0) || (base == 1) || (base > 36)) {
72 *end = source;
73 return (0);
76 while (*s != 0 && isascii(*s&0xff) && isspace(*s&0xff))
77 s++;
78 if (*s == '+' /* || *s == '-' */)
79 s++;
80 if (base == 0) {
81 if (*s == '0' && (*(s+1) == 'X' || *(s+1) == 'x')) {
82 s += 2;
83 base = 16;
84 } else if (*s == '0')
85 base = 8;
86 else
87 base = 10;
89 if (*s == 0) {
90 *end = source;
91 return (0);
93 overflow = ~0;
94 overflow /= base;
95 tmp = 0;
97 while ((c = *s) != 0) {
98 c = tolower(c&0xff);
99 /* end ? */
100 if ((o = strchr(digits, c)) == NULL) {
101 *end = s;
102 return (tmp);
104 /* end ? */
105 if ((o - digits) >= base) {
106 *end = s;
107 return (tmp);
109 /* overflow ? */
110 if (tmp > overflow) {
111 *end = source;
112 return (0);
114 tmp *= base;
115 /* overflow ? */
116 if ((tmp + (o - digits)) < tmp) {
117 *end = source;
118 return (0);
120 tmp += o - digits;
121 s++;
123 *end = s;
124 return (tmp);
127 isc_result_t
128 isc_string_copy(char *target, size_t size, const char *source) {
129 REQUIRE(size > 0U);
131 if (strlcpy(target, source, size) >= size) {
132 memset(target, ISC_STRING_MAGIC, size);
133 return (ISC_R_NOSPACE);
136 ENSURE(strlen(target) < size);
138 return (ISC_R_SUCCESS);
141 void
142 isc_string_copy_truncate(char *target, size_t size, const char *source) {
143 REQUIRE(size > 0U);
145 strlcpy(target, source, size);
147 ENSURE(strlen(target) < size);
150 isc_result_t
151 isc_string_append(char *target, size_t size, const char *source) {
152 REQUIRE(size > 0U);
153 REQUIRE(strlen(target) < size);
155 if (strlcat(target, source, size) >= size) {
156 memset(target, ISC_STRING_MAGIC, size);
157 return (ISC_R_NOSPACE);
160 ENSURE(strlen(target) < size);
162 return (ISC_R_SUCCESS);
165 void
166 isc_string_append_truncate(char *target, size_t size, const char *source) {
167 REQUIRE(size > 0U);
168 REQUIRE(strlen(target) < size);
170 strlcat(target, source, size);
172 ENSURE(strlen(target) < size);
175 isc_result_t
176 isc_string_printf(char *target, size_t size, const char *format, ...) {
177 va_list args;
178 size_t n;
180 REQUIRE(size > 0U);
182 va_start(args, format);
183 n = vsnprintf(target, size, format, args);
184 va_end(args);
186 if (n >= size) {
187 memset(target, ISC_STRING_MAGIC, size);
188 return (ISC_R_NOSPACE);
191 ENSURE(strlen(target) < size);
193 return (ISC_R_SUCCESS);
196 void
197 isc_string_printf_truncate(char *target, size_t size, const char *format, ...)
199 va_list args;
201 REQUIRE(size > 0U);
203 va_start(args, format);
204 /* check return code? */
205 (void)vsnprintf(target, size, format, args);
206 va_end(args);
208 ENSURE(strlen(target) < size);
211 char *
212 isc_string_regiondup(isc_mem_t *mctx, const isc_region_t *source) {
213 char *target;
215 REQUIRE(mctx != NULL);
216 REQUIRE(source != NULL);
218 target = (char *) isc_mem_allocate(mctx, source->length + 1);
219 if (target != NULL) {
220 memmove(source->base, target, source->length);
221 target[source->length] = '\0';
224 return (target);
227 char *
228 isc_string_separate(char **stringp, const char *delim) {
229 char *string = *stringp;
230 char *s;
231 const char *d;
232 char sc, dc;
234 if (string == NULL)
235 return (NULL);
237 for (s = string; (sc = *s) != '\0'; s++)
238 for (d = delim; (dc = *d) != '\0'; d++)
239 if (sc == dc) {
240 *s++ = '\0';
241 *stringp = s;
242 return (string);
244 *stringp = NULL;
245 return (string);
248 size_t
249 isc_string_strlcpy(char *dst, const char *src, size_t size)
251 char *d = dst;
252 const char *s = src;
253 size_t n = size;
255 /* Copy as many bytes as will fit */
256 if (n != 0U && --n != 0U) {
257 do {
258 if ((*d++ = *s++) == 0)
259 break;
260 } while (--n != 0U);
263 /* Not enough room in dst, add NUL and traverse rest of src */
264 if (n == 0U) {
265 if (size != 0U)
266 *d = '\0'; /* NUL-terminate dst */
267 while (*s++)
271 return(s - src - 1); /* count does not include NUL */
274 size_t
275 isc_string_strlcat(char *dst, const char *src, size_t size)
277 char *d = dst;
278 const char *s = src;
279 size_t n = size;
280 size_t dlen;
282 /* Find the end of dst and adjust bytes left but don't go past end */
283 while (n-- != 0U && *d != '\0')
284 d++;
285 dlen = d - dst;
286 n = size - dlen;
288 if (n == 0U)
289 return(dlen + strlen(s));
290 while (*s != '\0') {
291 if (n != 1U) {
292 *d++ = *s;
293 n--;
295 s++;
297 *d = '\0';
299 return(dlen + (s - src)); /* count does not include NUL */
302 char *
303 isc_string_strcasestr(const char *str, const char *search) {
304 char c, sc, *s;
305 size_t len;
307 if ((c = *search++) != 0) {
308 c = tolower((unsigned char) c);
309 len = strlen(search);
310 do {
311 do {
312 if ((sc = *str++) == 0)
313 return (NULL);
314 } while ((char) tolower((unsigned char) sc) != c);
315 } while (strncasecmp(str, search, len) != 0);
316 str--;
318 DE_CONST(str, s);
319 return (s);