Detect FPU by checking CPUID features.
[dragonfly.git] / contrib / bind-9.5.2 / lib / isc / string.c
1 /*
2  * Copyright (C) 2004-2007  Internet Systems Consortium, Inc. ("ISC")
3  * Copyright (C) 1999-2001, 2003  Internet Software Consortium.
4  *
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.
8  *
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.
16  */
17
18 /* $Id: string.c,v 1.20 2007/06/19 23:47:17 tbox Exp $ */
19
20 /*! \file */
21
22 #include <config.h>
23
24 #include <ctype.h>
25
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>
31
32 static char digits[] = "0123456789abcdefghijklmnoprstuvwxyz";
33
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;
41
42         if ((base < 0) || (base == 1) || (base > 36)) {
43                 *end = source;
44                 return (0);
45         }
46
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;
59         }
60         if (*s == 0) {
61                 *end = source;
62                 return (0);
63         }
64         overflow = ~0;
65         overflow /= base;
66         tmp = 0;
67
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);
74                 }
75                 /* end ? */
76                 if ((o - digits) >= base) {
77                         *end = s;
78                         return (tmp);
79                 }
80                 /* overflow ? */
81                 if (tmp > overflow) {
82                         *end = source;
83                         return (0);
84                 }
85                 tmp *= base;
86                 /* overflow ? */
87                 if ((tmp + (o - digits)) < tmp) {
88                         *end = source;
89                         return (0);
90                 }
91                 tmp += o - digits;
92                 s++;
93         }
94         *end = s;
95         return (tmp);
96 }
97
98 isc_result_t
99 isc_string_copy(char *target, size_t size, const char *source) {
100         REQUIRE(size > 0U);
101
102         if (strlcpy(target, source, size) >= size) {
103                 memset(target, ISC_STRING_MAGIC, size);
104                 return (ISC_R_NOSPACE);
105         }
106
107         ENSURE(strlen(target) < size);
108
109         return (ISC_R_SUCCESS);
110 }
111
112 void
113 isc_string_copy_truncate(char *target, size_t size, const char *source) {
114         REQUIRE(size > 0U);
115
116         strlcpy(target, source, size);
117
118         ENSURE(strlen(target) < size);
119 }
120
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);
125
126         if (strlcat(target, source, size) >= size) {
127                 memset(target, ISC_STRING_MAGIC, size);
128                 return (ISC_R_NOSPACE);
129         }
130
131         ENSURE(strlen(target) < size);
132
133         return (ISC_R_SUCCESS);
134 }
135
136 void
137 isc_string_append_truncate(char *target, size_t size, const char *source) {
138         REQUIRE(size > 0U);
139         REQUIRE(strlen(target) < size);
140
141         strlcat(target, source, size);
142
143         ENSURE(strlen(target) < size);
144 }
145
146 isc_result_t
147 isc_string_printf(char *target, size_t size, const char *format, ...) {
148         va_list args;
149         size_t n;
150
151         REQUIRE(size > 0U);
152
153         va_start(args, format);
154         n = vsnprintf(target, size, format, args);
155         va_end(args);
156
157         if (n >= size) {
158                 memset(target, ISC_STRING_MAGIC, size);
159                 return (ISC_R_NOSPACE);
160         }
161
162         ENSURE(strlen(target) < size);
163
164         return (ISC_R_SUCCESS);
165 }
166
167 void
168 isc_string_printf_truncate(char *target, size_t size, const char *format, ...) {
169         va_list args;
170         size_t n;
171
172         REQUIRE(size > 0U);
173
174         va_start(args, format);
175         n = vsnprintf(target, size, format, args);
176         va_end(args);
177
178         ENSURE(strlen(target) < size);
179 }
180
181 char *
182 isc_string_regiondup(isc_mem_t *mctx, const isc_region_t *source) {
183         char *target;
184
185         REQUIRE(mctx != NULL);
186         REQUIRE(source != NULL);
187
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';
192         }
193
194         return (target);
195 }
196
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;
203
204         if (string == NULL)
205                 return (NULL);
206
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);
213                         }
214         *stringp = NULL;
215         return (string);
216 }
217
218 size_t
219 isc_string_strlcpy(char *dst, const char *src, size_t size)
220 {
221         char *d = dst;
222         const char *s = src;
223         size_t n = size;
224
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);
231         }
232
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++)
238                         ;
239         }
240
241         return(s - src - 1);    /* count does not include NUL */
242 }
243
244 size_t
245 isc_string_strlcat(char *dst, const char *src, size_t size)
246 {
247         char *d = dst;
248         const char *s = src;
249         size_t n = size;
250         size_t dlen;
251
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;
257
258         if (n == 0U)
259                 return(dlen + strlen(s));
260         while (*s != '\0') {
261                 if (n != 1U) {
262                         *d++ = *s;
263                         n--;
264                 }
265                 s++;
266         }
267         *d = '\0';
268
269         return(dlen + (s - src));       /* count does not include NUL */
270 }