xref: /openbmc/linux/tools/include/nolibc/stdlib.h (revision b1c21e7d99cdab987fb858679fbc012868caac40)
1 /* SPDX-License-Identifier: LGPL-2.1 OR MIT */
2 /*
3  * stdlib function definitions for NOLIBC
4  * Copyright (C) 2017-2021 Willy Tarreau <w@1wt.eu>
5  */
6 
7 #ifndef _NOLIBC_STDLIB_H
8 #define _NOLIBC_STDLIB_H
9 
10 #include "std.h"
11 #include "arch.h"
12 #include "types.h"
13 #include "sys.h"
14 
15 
16 /* Buffer used to store int-to-ASCII conversions. Will only be implemented if
17  * any of the related functions is implemented. The area is large enough to
18  * store "18446744073709551615" or "-9223372036854775808" and the final zero.
19  */
20 static __attribute__((unused)) char itoa_buffer[21];
21 
22 /*
23  * As much as possible, please keep functions alphabetically sorted.
24  */
25 
26 static __attribute__((unused))
27 long atol(const char *s)
28 {
29 	unsigned long ret = 0;
30 	unsigned long d;
31 	int neg = 0;
32 
33 	if (*s == '-') {
34 		neg = 1;
35 		s++;
36 	}
37 
38 	while (1) {
39 		d = (*s++) - '0';
40 		if (d > 9)
41 			break;
42 		ret *= 10;
43 		ret += d;
44 	}
45 
46 	return neg ? -ret : ret;
47 }
48 
49 static __attribute__((unused))
50 int atoi(const char *s)
51 {
52 	return atol(s);
53 }
54 
55 /* Converts the unsigned long integer <in> to its string representation into
56  * buffer <buffer>, which must be long enough to store the number and the
57  * trailing zero (21 bytes for 18446744073709551615 in 64-bit, 11 for
58  * 4294967295 in 32-bit). The buffer is filled from the first byte, and the
59  * number of characters emitted (not counting the trailing zero) is returned.
60  * The function is constructed in a way to optimize the code size and avoid
61  * any divide that could add a dependency on large external functions.
62  */
63 static __attribute__((unused))
64 int utoa_r(unsigned long in, char *buffer)
65 {
66 	unsigned long lim;
67 	int digits = 0;
68 	int pos = (~0UL > 0xfffffffful) ? 19 : 9;
69 	int dig;
70 
71 	do {
72 		for (dig = 0, lim = 1; dig < pos; dig++)
73 			lim *= 10;
74 
75 		if (digits || in >= lim || !pos) {
76 			for (dig = 0; in >= lim; dig++)
77 				in -= lim;
78 			buffer[digits++] = '0' + dig;
79 		}
80 	} while (pos--);
81 
82 	buffer[digits] = 0;
83 	return digits;
84 }
85 
86 /* Converts the signed long integer <in> to its string representation into
87  * buffer <buffer>, which must be long enough to store the number and the
88  * trailing zero (21 bytes for -9223372036854775808 in 64-bit, 12 for
89  * -2147483648 in 32-bit). The buffer is filled from the first byte, and the
90  * number of characters emitted (not counting the trailing zero) is returned.
91  */
92 static __attribute__((unused))
93 int itoa_r(long in, char *buffer)
94 {
95 	char *ptr = buffer;
96 	int len = 0;
97 
98 	if (in < 0) {
99 		in = -in;
100 		*(ptr++) = '-';
101 		len++;
102 	}
103 	len += utoa_r(in, ptr);
104 	return len;
105 }
106 
107 /* for historical compatibility, same as above but returns the pointer to the
108  * buffer.
109  */
110 static inline __attribute__((unused))
111 char *ltoa_r(long in, char *buffer)
112 {
113 	itoa_r(in, buffer);
114 	return buffer;
115 }
116 
117 /* converts long integer <in> to a string using the static itoa_buffer and
118  * returns the pointer to that string.
119  */
120 static inline __attribute__((unused))
121 char *itoa(long in)
122 {
123 	itoa_r(in, itoa_buffer);
124 	return itoa_buffer;
125 }
126 
127 /* converts long integer <in> to a string using the static itoa_buffer and
128  * returns the pointer to that string. Same as above, for compatibility.
129  */
130 static inline __attribute__((unused))
131 char *ltoa(long in)
132 {
133 	itoa_r(in, itoa_buffer);
134 	return itoa_buffer;
135 }
136 
137 /* converts unsigned long integer <in> to a string using the static itoa_buffer
138  * and returns the pointer to that string.
139  */
140 static inline __attribute__((unused))
141 char *utoa(unsigned long in)
142 {
143 	utoa_r(in, itoa_buffer);
144 	return itoa_buffer;
145 }
146 
147 /* Converts the unsigned 64-bit integer <in> to its string representation into
148  * buffer <buffer>, which must be long enough to store the number and the
149  * trailing zero (21 bytes for 18446744073709551615). The buffer is filled from
150  * the first byte, and the number of characters emitted (not counting the
151  * trailing zero) is returned. The function is constructed in a way to optimize
152  * the code size and avoid any divide that could add a dependency on large
153  * external functions.
154  */
155 static __attribute__((unused))
156 int u64toa_r(uint64_t in, char *buffer)
157 {
158 	unsigned long long lim;
159 	int digits = 0;
160 	int pos = 19; /* start with the highest possible digit */
161 	int dig;
162 
163 	do {
164 		for (dig = 0, lim = 1; dig < pos; dig++)
165 			lim *= 10;
166 
167 		if (digits || in >= lim || !pos) {
168 			for (dig = 0; in >= lim; dig++)
169 				in -= lim;
170 			buffer[digits++] = '0' + dig;
171 		}
172 	} while (pos--);
173 
174 	buffer[digits] = 0;
175 	return digits;
176 }
177 
178 /* Converts the signed 64-bit integer <in> to its string representation into
179  * buffer <buffer>, which must be long enough to store the number and the
180  * trailing zero (21 bytes for -9223372036854775808). The buffer is filled from
181  * the first byte, and the number of characters emitted (not counting the
182  * trailing zero) is returned.
183  */
184 static __attribute__((unused))
185 int i64toa_r(int64_t in, char *buffer)
186 {
187 	char *ptr = buffer;
188 	int len = 0;
189 
190 	if (in < 0) {
191 		in = -in;
192 		*(ptr++) = '-';
193 		len++;
194 	}
195 	len += u64toa_r(in, ptr);
196 	return len;
197 }
198 
199 /* converts int64_t <in> to a string using the static itoa_buffer and returns
200  * the pointer to that string.
201  */
202 static inline __attribute__((unused))
203 char *i64toa(int64_t in)
204 {
205 	i64toa_r(in, itoa_buffer);
206 	return itoa_buffer;
207 }
208 
209 /* converts uint64_t <in> to a string using the static itoa_buffer and returns
210  * the pointer to that string.
211  */
212 static inline __attribute__((unused))
213 char *u64toa(uint64_t in)
214 {
215 	u64toa_r(in, itoa_buffer);
216 	return itoa_buffer;
217 }
218 
219 static __attribute__((unused))
220 int msleep(unsigned int msecs)
221 {
222 	struct timeval my_timeval = { msecs / 1000, (msecs % 1000) * 1000 };
223 
224 	if (sys_select(0, 0, 0, 0, &my_timeval) < 0)
225 		return (my_timeval.tv_sec * 1000) +
226 			(my_timeval.tv_usec / 1000) +
227 			!!(my_timeval.tv_usec % 1000);
228 	else
229 		return 0;
230 }
231 
232 /* This one is not marked static as it's needed by libgcc for divide by zero */
233 __attribute__((weak,unused))
234 int raise(int signal)
235 {
236 	return kill(getpid(), signal);
237 }
238 
239 static __attribute__((unused))
240 unsigned int sleep(unsigned int seconds)
241 {
242 	struct timeval my_timeval = { seconds, 0 };
243 
244 	if (sys_select(0, 0, 0, 0, &my_timeval) < 0)
245 		return my_timeval.tv_sec + !!my_timeval.tv_usec;
246 	else
247 		return 0;
248 }
249 
250 static __attribute__((unused))
251 int tcsetpgrp(int fd, pid_t pid)
252 {
253 	return ioctl(fd, TIOCSPGRP, &pid);
254 }
255 
256 #endif /* _NOLIBC_STDLIB_H */
257