blob: b63b7f54d4185b80dd2649240e86e29a3cf4dab9
1 | /* vi: set sw=4 ts=4: */ |
2 | /* |
3 | * ascii-to-numbers implementations for busybox |
4 | * |
5 | * Copyright (C) 2003 Manuel Novoa III <mjn3@codepoet.org> |
6 | * |
7 | * Licensed under GPLv2, see file LICENSE in this source tree. |
8 | */ |
9 | |
10 | #include "libbb.h" |
11 | |
12 | #define type long long |
13 | #define xstrtou(rest) xstrtoull##rest |
14 | #define xstrto(rest) xstrtoll##rest |
15 | #define xatou(rest) xatoull##rest |
16 | #define xato(rest) xatoll##rest |
17 | #define XSTR_UTYPE_MAX ULLONG_MAX |
18 | #define XSTR_TYPE_MAX LLONG_MAX |
19 | #define XSTR_TYPE_MIN LLONG_MIN |
20 | #define XSTR_STRTOU strtoull |
21 | #include "xatonum_template.c" |
22 | |
23 | #if ULONG_MAX != ULLONG_MAX |
24 | #define type long |
25 | #define xstrtou(rest) xstrtoul##rest |
26 | #define xstrto(rest) xstrtol##rest |
27 | #define xatou(rest) xatoul##rest |
28 | #define xato(rest) xatol##rest |
29 | #define XSTR_UTYPE_MAX ULONG_MAX |
30 | #define XSTR_TYPE_MAX LONG_MAX |
31 | #define XSTR_TYPE_MIN LONG_MIN |
32 | #define XSTR_STRTOU strtoul |
33 | #include "xatonum_template.c" |
34 | #endif |
35 | |
36 | #if UINT_MAX != ULONG_MAX |
37 | static ALWAYS_INLINE |
38 | unsigned bb_strtoui(const char *str, char **end, int b) |
39 | { |
40 | unsigned long v = strtoul(str, end, b); |
41 | if (v > UINT_MAX) { |
42 | errno = ERANGE; |
43 | return UINT_MAX; |
44 | } |
45 | return v; |
46 | } |
47 | #define type int |
48 | #define xstrtou(rest) xstrtou##rest |
49 | #define xstrto(rest) xstrtoi##rest |
50 | #define xatou(rest) xatou##rest |
51 | #define xato(rest) xatoi##rest |
52 | #define XSTR_UTYPE_MAX UINT_MAX |
53 | #define XSTR_TYPE_MAX INT_MAX |
54 | #define XSTR_TYPE_MIN INT_MIN |
55 | /* libc has no strtoui, so we need to create/use our own */ |
56 | #define XSTR_STRTOU bb_strtoui |
57 | #include "xatonum_template.c" |
58 | #endif |
59 | |
60 | /* A few special cases */ |
61 | |
62 | int FAST_FUNC xatoi_positive(const char *numstr) |
63 | { |
64 | return xatou_range(numstr, 0, INT_MAX); |
65 | } |
66 | |
67 | uint16_t FAST_FUNC xatou16(const char *numstr) |
68 | { |
69 | return xatou_range(numstr, 0, 0xffff); |
70 | } |
71 | |
72 | const struct suffix_mult bkm_suffixes[] = { |
73 | { "b", 512 }, |
74 | { "k", 1024 }, |
75 | { "m", 1024*1024 }, |
76 | { "", 0 } |
77 | }; |
78 | |
79 | const struct suffix_mult cwbkMG_suffixes[] = { |
80 | { "c", 1 }, |
81 | { "w", 2 }, |
82 | { "b", 512 }, |
83 | { "kB", 1000 }, |
84 | { "kD", 1000 }, |
85 | { "k", 1024 }, |
86 | { "KB", 1000 }, /* compat with coreutils dd */ |
87 | { "KD", 1000 }, /* compat with coreutils dd */ |
88 | { "K", 1024 }, /* compat with coreutils dd */ |
89 | { "MB", 1000000 }, |
90 | { "MD", 1000000 }, |
91 | { "M", 1024*1024 }, |
92 | { "GB", 1000000000 }, |
93 | { "GD", 1000000000 }, |
94 | { "G", 1024*1024*1024 }, |
95 | /* "D" suffix for decimal is not in coreutils manpage, looks like it's deprecated */ |
96 | /* coreutils also understands TPEZY suffixes for tera- and so on, with B suffix for decimal */ |
97 | { "", 0 } |
98 | }; |
99 | |
100 | const struct suffix_mult kmg_i_suffixes[] = { |
101 | { "KiB", 1024 }, |
102 | { "kiB", 1024 }, |
103 | { "K", 1024 }, |
104 | { "k", 1024 }, |
105 | { "MiB", 1048576 }, |
106 | { "miB", 1048576 }, |
107 | { "M", 1048576 }, |
108 | { "m", 1048576 }, |
109 | { "GiB", 1073741824 }, |
110 | { "giB", 1073741824 }, |
111 | { "G", 1073741824 }, |
112 | { "g", 1073741824 }, |
113 | { "KB", 1000 }, |
114 | { "MB", 1000000 }, |
115 | { "GB", 1000000000 }, |
116 | { "", 0 } |
117 | }; |
118 |