]> git.ipfire.org Git - people/ms/u-boot.git/blob - lib/strto.c
include/net.h: add max_speed member in struct eth_pdata
[people/ms/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 }