release 1.2.5
[musl.git] / src / locale / strfmon.c
blob7cf2136a06fb211dcc357630cc4e4cc1611676b8
1 #include <stdio.h>
2 #include <ctype.h>
3 #include <stdarg.h>
4 #include <monetary.h>
5 #include <errno.h>
6 #include "locale_impl.h"
8 static ssize_t vstrfmon_l(char *s, size_t n, locale_t loc, const char *fmt, va_list ap)
10 size_t l;
11 double x;
12 int fill, nogrp, negpar, nosym, left, intl;
13 int lp, rp, w, fw;
14 char *s0=s;
15 for (; n && *fmt; ) {
16 if (*fmt != '%') {
17 literal:
18 *s++ = *fmt++;
19 n--;
20 continue;
22 fmt++;
23 if (*fmt == '%') goto literal;
25 fill = ' ';
26 nogrp = 0;
27 negpar = 0;
28 nosym = 0;
29 left = 0;
30 for (; ; fmt++) {
31 switch (*fmt) {
32 case '=':
33 fill = *++fmt;
34 continue;
35 case '^':
36 nogrp = 1;
37 continue;
38 case '(':
39 negpar = 1;
40 case '+':
41 continue;
42 case '!':
43 nosym = 1;
44 continue;
45 case '-':
46 left = 1;
47 continue;
49 break;
52 for (fw=0; isdigit(*fmt); fmt++)
53 fw = 10*fw + (*fmt-'0');
54 lp = 0;
55 rp = 2;
56 if (*fmt=='#') for (lp=0, fmt++; isdigit(*fmt); fmt++)
57 lp = 10*lp + (*fmt-'0');
58 if (*fmt=='.') for (rp=0, fmt++; isdigit(*fmt); fmt++)
59 rp = 10*rp + (*fmt-'0');
61 intl = *fmt++ == 'i';
63 w = lp + 1 + rp;
64 if (!left && fw>w) w = fw;
66 x = va_arg(ap, double);
67 l = snprintf(s, n, "%*.*f", w, rp, x);
68 if (l >= n) {
69 errno = E2BIG;
70 return -1;
72 s += l;
73 n -= l;
75 return s-s0;
78 ssize_t strfmon_l(char *restrict s, size_t n, locale_t loc, const char *restrict fmt, ...)
80 va_list ap;
81 ssize_t ret;
83 va_start(ap, fmt);
84 ret = vstrfmon_l(s, n, loc, fmt, ap);
85 va_end(ap);
87 return ret;
91 ssize_t strfmon(char *restrict s, size_t n, const char *restrict fmt, ...)
93 va_list ap;
94 ssize_t ret;
96 va_start(ap, fmt);
97 ret = vstrfmon_l(s, n, CURRENT_LOCALE, fmt, ap);
98 va_end(ap);
100 return ret;