Merge from vendor branch LIBARCHIVE:
[dragonfly.git] / contrib / bind-9.2.4rc7 / lib / isc / string.c
1 /*
2  * Copyright (C) 2004  Internet Systems Consortium, Inc. ("ISC")
3  * Copyright (C) 1999-2001  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.2.1 2004/03/09 06:11:52 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);
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 }