Merge from vendor branch LIBARCHIVE:
[dragonfly.git] / contrib / bind-9.3 / lib / isc / string.c
1 /*
2  * Copyright (C) 2004  Internet Systems Consortium, Inc. ("ISC")
3  * Copyright (C) 1999-2001, 2003  Internet Software Consortium.
4  *
5  * Permission to use, copy, modify, and 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.6.164.5 2004/09/16 01:00:58 marka Exp $ */
19
20 #include <config.h>
21
22 #include <ctype.h>
23
24 #include <isc/string.h>
25
26 static char digits[] = "0123456789abcdefghijklmnoprstuvwxyz";
27
28 isc_uint64_t
29 isc_string_touint64(char *source, char **end, int base) {
30         isc_uint64_t tmp;
31         isc_uint64_t overflow;
32         char *s = source;
33         char *o;
34         char c;
35
36         if ((base < 0) || (base == 1) || (base > 36)) {
37                 *end = source;
38                 return (0);
39         }
40
41         while (*s != 0 && isascii(*s&0xff) && isspace(*s&0xff))
42                 s++;
43         if (*s == '+' /* || *s == '-' */)
44                 s++;
45         if (base == 0) {
46                 if (*s == '0' && (*(s+1) == 'X' || *(s+1) == 'x')) {
47                         s += 2;
48                         base = 16;
49                 } else if (*s == '0')
50                         base = 8;
51                 else
52                         base = 10;
53         }
54         if (*s == 0) {
55                 *end = source;
56                 return (0);
57         }
58         overflow = ~0;
59         overflow /= base;
60         tmp = 0;
61
62         while ((c = *s) != 0) {
63                 c = tolower(c&0xff);
64                 /* end ? */
65                 if ((o = strchr(digits, c)) == NULL) {
66                         *end = s;
67                         return (tmp);
68                 }
69                 /* end ? */
70                 if ((o - digits) >= base) {
71                         *end = s;
72                         return (tmp);
73                 }
74                 /* overflow ? */
75                 if (tmp > overflow) {
76                         *end = source;
77                         return (0);
78                 }
79                 tmp *= base;
80                 /* overflow ? */
81                 if ((tmp + (o - digits)) < tmp) {
82                         *end = source;
83                         return (0);
84                 }
85                 tmp += o - digits;
86                 s++;
87         }
88         *end = s;
89         return (tmp);
90 }
91
92 char *
93 isc_string_separate(char **stringp, const char *delim) {
94         char *string = *stringp;
95         char *s;
96         const char *d;
97         char sc, dc;
98
99         if (string == NULL)
100                 return (NULL);
101
102         for (s = string; (sc = *s) != '\0'; s++)
103                 for (d = delim; (dc = *d) != '\0'; d++)
104                         if (sc == dc) {
105                                 *s++ = '\0';
106                                 *stringp = s;
107                                 return (string);
108                         }
109         *stringp = NULL;
110         return (string);
111 }
112
113 size_t
114 isc_string_strlcpy(char *dst, const char *src, size_t size)
115 {
116         char *d = dst;
117         const char *s = src;
118         size_t n = size;
119
120         /* Copy as many bytes as will fit */
121         if (n != 0U && --n != 0U) {
122                 do {
123                         if ((*d++ = *s++) == 0)
124                                 break;
125                 } while (--n != 0U);
126         }
127
128         /* Not enough room in dst, add NUL and traverse rest of src */
129         if (n == 0U) {
130                 if (size != 0U)
131                         *d = '\0';              /* NUL-terminate dst */
132                 while (*s++)
133                         ;
134         }
135
136         return(s - src - 1);    /* count does not include NUL */
137 }
138
139 size_t
140 isc_string_strlcat(char *dst, const char *src, size_t size)
141 {
142         char *d = dst;
143         const char *s = src;
144         size_t n = size;
145         size_t dlen;
146
147         /* Find the end of dst and adjust bytes left but don't go past end */
148         while (n-- != 0U && *d != '\0')
149                 d++;
150         dlen = d - dst;
151         n = size - dlen;
152
153         if (n == 0U)
154                 return(dlen + strlen(s));
155         while (*s != '\0') {
156                 if (n != 1U) {
157                         *d++ = *s;
158                         n--;
159                 }
160                 s++;
161         }
162         *d = '\0';
163
164         return(dlen + (s - src));       /* count does not include NUL */
165 }