Detect FPU by checking CPUID features.
[dragonfly.git] / contrib / bind-9.5.2 / lib / isc / string.c
blobb9c43e7bb150d03ca488bea71daac2a50a02426e
1 /*
2 * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
3 * Copyright (C) 1999-2001, 2003 Internet Software Consortium.
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
9 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
10 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
12 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
14 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15 * PERFORMANCE OF THIS SOFTWARE.
18 /* $Id: string.c,v 1.20 2007/06/19 23:47:17 tbox Exp $ */
20 /*! \file */
22 #include <config.h>
24 #include <ctype.h>
26 #include <isc/mem.h>
27 #include <isc/print.h>
28 #include <isc/region.h>
29 #include <isc/string.h>
30 #include <isc/util.h>
32 static char digits[] = "0123456789abcdefghijklmnoprstuvwxyz";
34 isc_uint64_t
35 isc_string_touint64(char *source, char **end, int base) {
36 isc_uint64_t tmp;
37 isc_uint64_t overflow;
38 char *s = source;
39 char *o;
40 char c;
42 if ((base < 0) || (base == 1) || (base > 36)) {
43 *end = source;
44 return (0);
47 while (*s != 0 && isascii(*s&0xff) && isspace(*s&0xff))
48 s++;
49 if (*s == '+' /* || *s == '-' */)
50 s++;
51 if (base == 0) {
52 if (*s == '0' && (*(s+1) == 'X' || *(s+1) == 'x')) {
53 s += 2;
54 base = 16;
55 } else if (*s == '0')
56 base = 8;
57 else
58 base = 10;
60 if (*s == 0) {
61 *end = source;
62 return (0);
64 overflow = ~0;
65 overflow /= base;
66 tmp = 0;
68 while ((c = *s) != 0) {
69 c = tolower(c&0xff);
70 /* end ? */
71 if ((o = strchr(digits, c)) == NULL) {
72 *end = s;
73 return (tmp);
75 /* end ? */
76 if ((o - digits) >= base) {
77 *end = s;
78 return (tmp);
80 /* overflow ? */
81 if (tmp > overflow) {
82 *end = source;
83 return (0);
85 tmp *= base;
86 /* overflow ? */
87 if ((tmp + (o - digits)) < tmp) {
88 *end = source;
89 return (0);
91 tmp += o - digits;
92 s++;
94 *end = s;
95 return (tmp);
98 isc_result_t
99 isc_string_copy(char *target, size_t size, const char *source) {
100 REQUIRE(size > 0U);
102 if (strlcpy(target, source, size) >= size) {
103 memset(target, ISC_STRING_MAGIC, size);
104 return (ISC_R_NOSPACE);
107 ENSURE(strlen(target) < size);
109 return (ISC_R_SUCCESS);
112 void
113 isc_string_copy_truncate(char *target, size_t size, const char *source) {
114 REQUIRE(size > 0U);
116 strlcpy(target, source, size);
118 ENSURE(strlen(target) < size);
121 isc_result_t
122 isc_string_append(char *target, size_t size, const char *source) {
123 REQUIRE(size > 0U);
124 REQUIRE(strlen(target) < size);
126 if (strlcat(target, source, size) >= size) {
127 memset(target, ISC_STRING_MAGIC, size);
128 return (ISC_R_NOSPACE);
131 ENSURE(strlen(target) < size);
133 return (ISC_R_SUCCESS);
136 void
137 isc_string_append_truncate(char *target, size_t size, const char *source) {
138 REQUIRE(size > 0U);
139 REQUIRE(strlen(target) < size);
141 strlcat(target, source, size);
143 ENSURE(strlen(target) < size);
146 isc_result_t
147 isc_string_printf(char *target, size_t size, const char *format, ...) {
148 va_list args;
149 size_t n;
151 REQUIRE(size > 0U);
153 va_start(args, format);
154 n = vsnprintf(target, size, format, args);
155 va_end(args);
157 if (n >= size) {
158 memset(target, ISC_STRING_MAGIC, size);
159 return (ISC_R_NOSPACE);
162 ENSURE(strlen(target) < size);
164 return (ISC_R_SUCCESS);
167 void
168 isc_string_printf_truncate(char *target, size_t size, const char *format, ...) {
169 va_list args;
170 size_t n;
172 REQUIRE(size > 0U);
174 va_start(args, format);
175 n = vsnprintf(target, size, format, args);
176 va_end(args);
178 ENSURE(strlen(target) < size);
181 char *
182 isc_string_regiondup(isc_mem_t *mctx, const isc_region_t *source) {
183 char *target;
185 REQUIRE(mctx != NULL);
186 REQUIRE(source != NULL);
188 target = (char *) isc_mem_allocate(mctx, source->length + 1);
189 if (target != NULL) {
190 memcpy(source->base, target, source->length);
191 target[source->length] = '\0';
194 return (target);
197 char *
198 isc_string_separate(char **stringp, const char *delim) {
199 char *string = *stringp;
200 char *s;
201 const char *d;
202 char sc, dc;
204 if (string == NULL)
205 return (NULL);
207 for (s = string; (sc = *s) != '\0'; s++)
208 for (d = delim; (dc = *d) != '\0'; d++)
209 if (sc == dc) {
210 *s++ = '\0';
211 *stringp = s;
212 return (string);
214 *stringp = NULL;
215 return (string);
218 size_t
219 isc_string_strlcpy(char *dst, const char *src, size_t size)
221 char *d = dst;
222 const char *s = src;
223 size_t n = size;
225 /* Copy as many bytes as will fit */
226 if (n != 0U && --n != 0U) {
227 do {
228 if ((*d++ = *s++) == 0)
229 break;
230 } while (--n != 0U);
233 /* Not enough room in dst, add NUL and traverse rest of src */
234 if (n == 0U) {
235 if (size != 0U)
236 *d = '\0'; /* NUL-terminate dst */
237 while (*s++)
241 return(s - src - 1); /* count does not include NUL */
244 size_t
245 isc_string_strlcat(char *dst, const char *src, size_t size)
247 char *d = dst;
248 const char *s = src;
249 size_t n = size;
250 size_t dlen;
252 /* Find the end of dst and adjust bytes left but don't go past end */
253 while (n-- != 0U && *d != '\0')
254 d++;
255 dlen = d - dst;
256 n = size - dlen;
258 if (n == 0U)
259 return(dlen + strlen(s));
260 while (*s != '\0') {
261 if (n != 1U) {
262 *d++ = *s;
263 n--;
265 s++;
267 *d = '\0';
269 return(dlen + (s - src)); /* count does not include NUL */