vsprintf.c: Always enable CONFIG_SYS_VSNPRINTF
[platform/kernel/u-boot.git] / lib / strto.c
1 /*
2  *  linux/lib/vsprintf.c
3  *
4  *  Copyright (C) 1991, 1992  Linus Torvalds
5  */
6
7 /* vsprintf.c -- Lars Wirzenius & Linus Torvalds. */
8 /*
9  * Wirzenius wrote this portably, Torvalds fucked it up :-)
10  */
11
12 #include <common.h>
13 #include <errno.h>
14 #include <linux/ctype.h>
15
16 unsigned long simple_strtoul(const char *cp, char **endp,
17                                 unsigned int base)
18 {
19         unsigned long result = 0;
20         unsigned long value;
21
22         if (*cp == '0') {
23                 cp++;
24                 if ((*cp == 'x') && isxdigit(cp[1])) {
25                         base = 16;
26                         cp++;
27                 }
28
29                 if (!base)
30                         base = 8;
31         }
32
33         if (!base)
34                 base = 10;
35
36         while (isxdigit(*cp) && (value = isdigit(*cp) ? *cp-'0' : (islower(*cp)
37             ? toupper(*cp) : *cp)-'A'+10) < base) {
38                 result = result*base + value;
39                 cp++;
40         }
41
42         if (endp)
43                 *endp = (char *)cp;
44
45         return result;
46 }
47
48 int strict_strtoul(const char *cp, unsigned int base, unsigned long *res)
49 {
50         char *tail;
51         unsigned long val;
52         size_t len;
53
54         *res = 0;
55         len = strlen(cp);
56         if (len == 0)
57                 return -EINVAL;
58
59         val = simple_strtoul(cp, &tail, base);
60         if (tail == cp)
61                 return -EINVAL;
62
63         if ((*tail == '\0') ||
64                 ((len == (size_t)(tail - cp) + 1) && (*tail == '\n'))) {
65                 *res = val;
66                 return 0;
67         }
68
69         return -EINVAL;
70 }
71
72 long simple_strtol(const char *cp, char **endp, unsigned int base)
73 {
74         if (*cp == '-')
75                 return -simple_strtoul(cp + 1, endp, base);
76
77         return simple_strtoul(cp, endp, base);
78 }
79
80 unsigned long ustrtoul(const char *cp, char **endp, unsigned int base)
81 {
82         unsigned long result = simple_strtoul(cp, endp, base);
83         switch (**endp) {
84         case 'G':
85                 result *= 1024;
86                 /* fall through */
87         case 'M':
88                 result *= 1024;
89                 /* fall through */
90         case 'K':
91         case 'k':
92                 result *= 1024;
93                 if ((*endp)[1] == 'i') {
94                         if ((*endp)[2] == 'B')
95                                 (*endp) += 3;
96                         else
97                                 (*endp) += 2;
98                 }
99         }
100         return result;
101 }
102
103 unsigned long long ustrtoull(const char *cp, char **endp, unsigned int base)
104 {
105         unsigned long long result = simple_strtoull(cp, endp, base);
106         switch (**endp) {
107         case 'G':
108                 result *= 1024;
109                 /* fall through */
110         case 'M':
111                 result *= 1024;
112                 /* fall through */
113         case 'K':
114         case 'k':
115                 result *= 1024;
116                 if ((*endp)[1] == 'i') {
117                         if ((*endp)[2] == 'B')
118                                 (*endp) += 3;
119                         else
120                                 (*endp) += 2;
121                 }
122         }
123         return result;
124 }
125
126 unsigned long long simple_strtoull(const char *cp, char **endp,
127                                         unsigned int base)
128 {
129         unsigned long long result = 0, value;
130
131         if (*cp == '0') {
132                 cp++;
133                 if ((*cp == 'x') && isxdigit(cp[1])) {
134                         base = 16;
135                         cp++;
136                 }
137
138                 if (!base)
139                         base = 8;
140         }
141
142         if (!base)
143                 base = 10;
144
145         while (isxdigit(*cp) && (value = isdigit(*cp) ? *cp - '0'
146                 : (islower(*cp) ? toupper(*cp) : *cp) - 'A' + 10) < base) {
147                 result = result * base + value;
148                 cp++;
149         }
150
151         if (endp)
152                 *endp = (char *) cp;
153
154         return result;
155 }
156
157 long trailing_strtoln(const char *str, const char *end)
158 {
159         const char *p;
160
161         if (!end)
162                 end = str + strlen(str);
163         for (p = end - 1; p > str; p--) {
164                 if (!isdigit(*p))
165                         return simple_strtoul(p + 1, NULL, 10);
166         }
167
168         return -1;
169 }
170
171 long trailing_strtol(const char *str)
172 {
173         return trailing_strtoln(str, NULL);
174 }