source: mainline/uspace/lib/c/generic/stdlib.c@ 05882233

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 05882233 was 9d8307a, checked in by Jiri Svoboda <jiri@…>, 7 years ago

Reimplement strtold function in libc.

  • Property mode set to 100644
File size: 7.0 KB
Line 
1/*
2 * Copyright (c) 2006 Ondrej Palkovsky
3 * Copyright (c) 2018 Jiri Svoboda
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * - Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * - Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * - The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30/** @addtogroup libc
31 * @{
32 */
33/** @file
34 */
35
36#include <adt/list.h>
37#include <fibril_synch.h>
38#include <stdlib.h>
39#include "private/libc.h"
40#include "private/scanf.h"
41#include "private/stdlib.h"
42#include "private/stdio.h"
43#include "private/sstream.h"
44
45static int glbl_seed = 1;
46
47static LIST_INITIALIZE(exit_handlers);
48static FIBRIL_MUTEX_INITIALIZE(exit_handlers_lock);
49
50static LIST_INITIALIZE(quick_exit_handlers);
51static FIBRIL_MUTEX_INITIALIZE(quick_exit_handlers_lock);
52
53/** Convert string to long double.
54 *
55 */
56long double strtold(const char *nptr, char **endptr)
57{
58 int numchar;
59 long double ld;
60 errno_t rc;
61 FILE f;
62
63 numchar = 0;
64 __sstream_init(nptr, &f);
65
66 rc = __fstrtold(&f, &numchar, SIZE_MAX, &ld);
67 if (rc != EOK) {
68 ld = 0;
69 if (endptr != NULL)
70 *endptr = (char *) nptr;
71 errno = rc;
72 } else {
73 if (endptr != NULL)
74 *endptr = (char *) __sstream_getpos(&f);
75 }
76
77 return ld;
78}
79
80int rand(void)
81{
82 return glbl_seed = ((1366 * glbl_seed + 150889) % RAND_MAX);
83}
84
85void srand(unsigned int seed)
86{
87 glbl_seed = seed % RAND_MAX;
88}
89
90/** Register exit handler.
91 *
92 * @param func Function to be called during program terimnation
93 * @return Zero on success, nonzero on failure
94 */
95int atexit(void (*func)(void))
96{
97 __exit_handler_t *entry;
98
99 entry = malloc(sizeof(__exit_handler_t));
100 if (entry == NULL)
101 return -1;
102
103 entry->func = func;
104
105 fibril_mutex_lock(&exit_handlers_lock);
106 list_prepend(&entry->llist, &exit_handlers);
107 fibril_mutex_unlock(&exit_handlers_lock);
108 return 0;
109}
110
111/** Terminate program with exit status.
112 *
113 * @param status Exit status
114 */
115void exit(int status)
116{
117 link_t *link;
118 __exit_handler_t *eh;
119
120 /* Call exit handlers */
121 fibril_mutex_lock(&exit_handlers_lock);
122 while (!list_empty(&exit_handlers)) {
123 link = list_first(&exit_handlers);
124 list_remove(link);
125 fibril_mutex_unlock(&exit_handlers_lock);
126
127 eh = list_get_instance(link, __exit_handler_t, llist);
128 eh->func();
129 free(eh);
130 fibril_mutex_lock(&exit_handlers_lock);
131 }
132
133 fibril_mutex_unlock(&exit_handlers_lock);
134
135 _Exit(status);
136}
137
138/** Register quick exit handler.
139 *
140 * @param func Function to be called during quick program terimnation
141 * @return Zero on success, nonzero on failure
142 */
143int at_quick_exit(void (*func)(void))
144{
145 __exit_handler_t *entry;
146
147 entry = malloc(sizeof(__exit_handler_t));
148 if (entry == NULL)
149 return -1;
150
151 entry->func = func;
152
153 fibril_mutex_lock(&exit_handlers_lock);
154 list_prepend(&entry->llist, &exit_handlers);
155 fibril_mutex_unlock(&exit_handlers_lock);
156 return 0;
157}
158
159/** Quickly terminate program with exit status.
160 *
161 * @param status Exit status
162 */
163void quick_exit(int status)
164{
165 link_t *link;
166 __exit_handler_t *eh;
167
168 /* Call quick exit handlers */
169 fibril_mutex_lock(&quick_exit_handlers_lock);
170 while (!list_empty(&quick_exit_handlers)) {
171 link = list_first(&quick_exit_handlers);
172 list_remove(link);
173 fibril_mutex_unlock(&quick_exit_handlers_lock);
174
175 eh = list_get_instance(link, __exit_handler_t, llist);
176 eh->func();
177 free(eh);
178 fibril_mutex_lock(&quick_exit_handlers_lock);
179 }
180
181 fibril_mutex_unlock(&quick_exit_handlers_lock);
182
183 _Exit(status);
184}
185
186void _Exit(int status)
187{
188 __libc_exit(status);
189}
190
191/** Abnormal program termination */
192void abort(void)
193{
194 __libc_abort();
195}
196
197/** Get environment list entry.
198 *
199 * Note that this function is not reentrant. The returned string is only
200 * guaranteed to be valid until the next call to @c getenv.
201 *
202 * @param name Entry name
203 * @return Pointer to string or @c NULL if not found
204 */
205char *getenv(const char *name)
206{
207 (void) name;
208 return NULL;
209}
210
211/** Execute command.
212 *
213 * @param string Command to execute or @c NULL
214 *
215 * @return If @a string is @c NULL, return zero (no command processor
216 * available). If @a string is not @c NULL, return 1 (failure).
217 */
218int system(const char *string)
219{
220 if (string == NULL)
221 return 0;
222
223 return 1;
224}
225
226/** Compute the absolute value of an integer.
227 *
228 * If the result cannot be represented, the behavior is undefined.
229 *
230 * @param j Integer
231 * @return The absolute value of @a j
232 */
233int abs(int j)
234{
235 int aj;
236
237 if (j < 0) {
238 aj = -j;
239 assert(aj >= 0);
240 } else {
241 aj = j;
242 }
243
244 return aj;
245}
246
247/** Compute the absolute value of a long integer.
248 *
249 * If the result cannot be represented, the behavior is undefined.
250 *
251 * @param j Long integer
252 * @return The absolute value of @a j
253 */
254long labs(long j)
255{
256 long aj;
257
258 if (j < 0) {
259 aj = -j;
260 assert(aj >= 0);
261 } else {
262 aj = j;
263 }
264
265 return aj;
266}
267
268/** Compute the absolute value of a long long integer.
269 *
270 * If the result cannot be represented, the behavior is undefined.
271 *
272 * @param j Long long integer
273 * @return The absolute value of @a j
274 */
275long long llabs(long long j)
276{
277 long long aj;
278
279 if (j < 0) {
280 aj = -j;
281 assert(aj >= 0);
282 } else {
283 aj = j;
284 }
285
286 return aj;
287}
288
289/** Compute quotient and remainder of int division.
290 *
291 * @param numer Numerator
292 * @param denom Denominator
293 * @return Structure containing quotient and remainder
294 */
295div_t div(int numer, int denom)
296{
297 div_t d;
298
299 d.quot = numer / denom;
300 d.rem = numer % denom;
301
302 return d;
303}
304
305/** Compute quotient and remainder of long division.
306 *
307 * @param numer Numerator
308 * @param denom Denominator
309 * @return Structure containing quotient and remainder
310 */
311ldiv_t ldiv(long numer, long denom)
312{
313 ldiv_t d;
314
315 d.quot = numer / denom;
316 d.rem = numer % denom;
317
318 return d;
319}
320
321/** Compute quotient and remainder of long long division.
322 *
323 * @param numer Numerator
324 * @param denom Denominator
325 * @return Structure containing quotient and remainder
326 */
327lldiv_t lldiv(long long numer, long long denom)
328{
329 lldiv_t d;
330
331 d.quot = numer / denom;
332 d.rem = numer % denom;
333
334 return d;
335}
336
337/** @}
338 */
Note: See TracBrowser for help on using the repository browser.