xref: /freebsd/lib/libc/stdlib/strfroml.c (revision d15f2551b25f79ddcbe289faa95e655100b952da)
1 /*
2  * Copyright (c) 2026 Faraz Vahedi <kfv@kfv.io>
3  *
4  * SPDX-License-Identifier: BSD-2-Clause
5  */
6 
7 #include <ctype.h>
8 #include <stdlib.h>
9 
10 #include "strfrom.h"
11 
12 int
13 strfroml(char * __restrict s, size_t n, const char * __restrict fmt,
14     long double fp)
15 {
16 	char conv, lc, *digits, *dend;
17 	int prec, decpt, signflag, ret, mode, ndig_req;
18 
19 	conv = __sf_parse_fmt(fmt, &prec);
20 	if (conv == '\0')
21 		return (__sf_edoofus(s, n));
22 	lc = tolower((unsigned char)conv);
23 
24 	if (lc == 'a') {
25 		digits = __hldtoa(fp, __sf_xdigits(conv),
26 		    prec >= 0 ? prec + 1 : -1, &decpt, &signflag, &dend);
27 		ret = __sf_render_hex(s, n, conv, prec, digits, dend, decpt,
28 		    signflag);
29 		freedtoa(digits);
30 		return (ret);
31 	}
32 
33 	if (prec < 0)
34 		prec = 6;
35 
36 	__sf_decimal_mode(lc, prec, &mode, &ndig_req);
37 
38 	digits = __ldtoa(&fp, mode, ndig_req, &decpt, &signflag, &dend);
39 
40 	ret = __sf_render_decimal(s, n, conv, lc, prec, digits, dend, decpt,
41 	    signflag, decpt == INT_MAX);
42 
43 	freedtoa(digits);
44 
45 	return (ret);
46 }
47