1 | // SPDX-License-Identifier: GPL-3.0-or-later |
2 | |
3 | #include "mos_stdlib.h" |
4 | |
5 | #include <mos/types.h> |
6 | #include <mos_stdio.h> |
7 | #include <mos_string.h> |
8 | |
9 | unsigned char tolower(unsigned char c) |
10 | { |
11 | if (c >= 'A' && c <= 'Z') |
12 | return c - 'A' + 'a'; |
13 | return c; |
14 | } |
15 | |
16 | static int isspace(int _c) |
17 | { |
18 | return ((_c > 8 && _c < 14) || (_c == 32)); |
19 | } |
20 | |
21 | s32 abs(s32 x) |
22 | { |
23 | return (x < 0) ? -x : x; |
24 | } |
25 | |
26 | long labs(long x) |
27 | { |
28 | return (x < 0) ? -x : x; |
29 | } |
30 | |
31 | s64 llabs(s64 x) |
32 | { |
33 | return (x < 0) ? -x : x; |
34 | } |
35 | |
36 | s32 atoi(const char *nptr) |
37 | { |
38 | s32 c; |
39 | s32 neg = 0; |
40 | s32 val = 0; |
41 | |
42 | while (isspace(c: *nptr)) |
43 | nptr++; |
44 | |
45 | if (*nptr == '-') |
46 | { |
47 | neg = 1; |
48 | nptr++; |
49 | } |
50 | else if (*nptr == '+') |
51 | { |
52 | nptr++; |
53 | } |
54 | |
55 | while ((c = *nptr++) >= '0' && c <= '9') |
56 | { |
57 | val = val * 10 + (c - '0'); |
58 | } |
59 | |
60 | return neg ? -val : val; |
61 | } |
62 | |
63 | unsigned long strtoul(const char *restrict nptr, char **restrict endptr, int base) |
64 | { |
65 | return strtoll(str: nptr, endptr, base); |
66 | } |
67 | |
68 | s64 strtoll(const char *str, char **endptr, int base) |
69 | { |
70 | return strntoll(str, endptr, base, n: strlen(str)); |
71 | } |
72 | |
73 | s64 strntoll(const char *str, char **endptr, int base, size_t n) |
74 | { |
75 | s64 result = 0; |
76 | bool negative = false; |
77 | size_t i = 0; |
78 | |
79 | if (*str == '-') |
80 | negative = true, str++, i++; |
81 | else if (*str == '+') |
82 | str++, i++; |
83 | |
84 | while (i < n && *str) |
85 | { |
86 | char c = *str; |
87 | if (c >= '0' && c <= '9') |
88 | result *= base, result += c - '0'; |
89 | else if (c >= 'a' && c <= 'z') |
90 | result *= base, result += c - 'a' + 10; |
91 | else if (c >= 'A' && c <= 'Z') |
92 | result *= base, result += c - 'A' + 10; |
93 | else |
94 | break; |
95 | str++; |
96 | i++; |
97 | } |
98 | if (endptr) |
99 | *endptr = (char *) str; |
100 | return negative ? -result : result; |
101 | } |
102 | |
103 | void format_size(char *buf, size_t buf_size, u64 size) |
104 | { |
105 | static const char *const units[] = { "B" , "KiB" , "MiB" , "GiB" , "TiB" , "PiB" , "EiB" , "ZiB" , "YiB" }; |
106 | size_t i = 0; |
107 | size_t diff = 0; |
108 | while (size >= 1024 && i < MOS_ARRAY_SIZE(units) - 1) |
109 | { |
110 | diff = size % 1024; |
111 | size /= 1024; |
112 | i++; |
113 | } |
114 | if (unlikely(diff == 0 || i == 0)) |
115 | { |
116 | snprintf(str: buf, size: buf_size, format: "%llu %s" , size, units[i]); |
117 | } |
118 | else |
119 | { |
120 | snprintf(str: buf, size: buf_size, format: "%llu %s + %zu %s" , size, units[i], diff, units[i - 1]); |
121 | } |
122 | } |
123 | |
124 | char *string_trim(char *in) |
125 | { |
126 | if (in == NULL) |
127 | return NULL; |
128 | |
129 | char *end; |
130 | |
131 | // Trim leading space |
132 | while (*in == ' ') |
133 | in++; |
134 | |
135 | if (*in == 0) // All spaces? |
136 | return in; |
137 | |
138 | // Trim trailing space |
139 | end = in + strlen(str: in) - 1; |
140 | while (end > in && *end == ' ') |
141 | end--; |
142 | |
143 | // Write new null terminator |
144 | *(end + 1) = '\0'; |
145 | return in; |
146 | } |
147 | |