This source file includes following definitions.
- bkm_scale
- bkm_scale_by_power
- xstrtoumax
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 #include <config.h>
22
23
24
25 #include <stdio.h>
26
27 #include <ctype.h>
28 #include <errno.h>
29 #include <inttypes.h>
30 #include <limits.h>
31 #include <stdlib.h>
32 #include <string.h>
33
34 #include "lib/strutil.h"
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50 static strtol_error_t
51 bkm_scale (uintmax_t * x, int scale_factor)
52 {
53 if (UINTMAX_MAX / scale_factor < *x)
54 {
55 *x = UINTMAX_MAX;
56 return LONGINT_OVERFLOW;
57 }
58
59 *x *= scale_factor;
60 return LONGINT_OK;
61 }
62
63
64
65 static strtol_error_t
66 bkm_scale_by_power (uintmax_t * x, int base, int power)
67 {
68 strtol_error_t err = LONGINT_OK;
69 while (power-- != 0)
70 err |= bkm_scale (x, base);
71 return err;
72 }
73
74
75
76
77
78 strtol_error_t
79 xstrtoumax (const char *s, char **ptr, int base, uintmax_t * val, const char *valid_suffixes)
80 {
81 char *t_ptr;
82 char **p;
83 uintmax_t tmp;
84 strtol_error_t err = LONGINT_OK;
85
86 g_assert (0 <= base && base <= 36);
87
88 p = (ptr != NULL ? ptr : &t_ptr);
89
90 {
91 const char *q = s;
92 unsigned char ch = *q;
93
94 while (isspace (ch))
95 ch = *++q;
96
97 if (ch == '-')
98 return LONGINT_INVALID;
99 }
100
101 errno = 0;
102 tmp = strtol (s, p, base);
103
104 if (*p == s)
105 {
106
107
108 if (valid_suffixes != NULL && **p != '\0' && strchr (valid_suffixes, **p) != NULL)
109 tmp = 1;
110 else
111 return LONGINT_INVALID;
112 }
113 else if (errno != 0)
114 {
115 if (errno != ERANGE)
116 return LONGINT_INVALID;
117 err = LONGINT_OVERFLOW;
118 }
119
120
121
122
123 if (valid_suffixes == NULL)
124 {
125 *val = tmp;
126 return err;
127 }
128
129 if (**p != '\0')
130 {
131 int suffixes = 1;
132 strtol_error_t overflow;
133
134 if (strchr (valid_suffixes, **p) == NULL)
135 {
136 *val = tmp;
137 return err | LONGINT_INVALID_SUFFIX_CHAR;
138 }
139
140 base = 1024;
141
142 switch (**p)
143 {
144 case 'E':
145 case 'G':
146 case 'g':
147 case 'k':
148 case 'K':
149 case 'M':
150 case 'm':
151 case 'P':
152 case 'Q':
153 case 'R':
154 case 'T':
155 case 't':
156 case 'Y':
157 case 'Z':
158 if (strchr (valid_suffixes, '0') != NULL)
159 {
160
161
162
163
164
165
166
167 switch (p[0][1])
168 {
169 case 'i':
170 if (p[0][2] == 'B')
171 suffixes += 2;
172 break;
173
174 case 'B':
175 case 'D':
176 base = 1000;
177 suffixes++;
178 break;
179 default:
180 break;
181 }
182 }
183 break;
184 default:
185 break;
186 }
187
188 switch (**p)
189 {
190 case 'b':
191 overflow = bkm_scale (&tmp, 512);
192 break;
193
194 case 'B':
195
196
197
198 overflow = bkm_scale (&tmp, 1024);
199 break;
200
201 case 'c':
202 overflow = LONGINT_OK;
203 break;
204
205 case 'E':
206 overflow = bkm_scale_by_power (&tmp, base, 6);
207 break;
208
209 case 'G':
210 case 'g':
211 overflow = bkm_scale_by_power (&tmp, base, 3);
212 break;
213
214 case 'k':
215 case 'K':
216 overflow = bkm_scale_by_power (&tmp, base, 1);
217 break;
218
219 case 'M':
220 case 'm':
221 overflow = bkm_scale_by_power (&tmp, base, 2);
222 break;
223
224 case 'P':
225 overflow = bkm_scale_by_power (&tmp, base, 5);
226 break;
227
228 case 'Q':
229 overflow = bkm_scale_by_power (&tmp, base, 10);
230 break;
231
232 case 'R':
233 overflow = bkm_scale_by_power (&tmp, base, 9);
234 break;
235
236 case 'T':
237 case 't':
238 overflow = bkm_scale_by_power (&tmp, base, 4);
239 break;
240
241 case 'w':
242 overflow = bkm_scale (&tmp, 2);
243 break;
244
245 case 'Y':
246 overflow = bkm_scale_by_power (&tmp, base, 8);
247 break;
248
249 case 'Z':
250 overflow = bkm_scale_by_power (&tmp, base, 7);
251 break;
252
253 default:
254 *val = tmp;
255 return err | LONGINT_INVALID_SUFFIX_CHAR;
256 }
257
258 err |= overflow;
259 *p += suffixes;
260 if (**p != '\0')
261 err |= LONGINT_INVALID_SUFFIX_CHAR;
262 }
263
264 *val = tmp;
265 return err;
266 }
267
268