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"
7
vstrfmon_l(char * s,size_t n,locale_t loc,const char * fmt,va_list ap)8 static ssize_t vstrfmon_l(char *s, size_t n, locale_t loc, const char *fmt, va_list ap)
9 {
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;
21 }
22 fmt++;
23 if (*fmt == '%') goto literal;
24
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;
48 }
49 break;
50 }
51
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');
60
61 intl = *fmt++ == 'i';
62
63 w = lp + 1 + rp;
64 if (!left && fw>w) w = fw;
65
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;
71 }
72 s += l;
73 n -= l;
74 }
75 return s-s0;
76 }
77
strfmon_l(char * restrict s,size_t n,locale_t loc,const char * restrict fmt,...)78 ssize_t strfmon_l(char *restrict s, size_t n, locale_t loc, const char *restrict fmt, ...)
79 {
80 va_list ap;
81 ssize_t ret;
82
83 va_start(ap, fmt);
84 ret = vstrfmon_l(s, n, loc, fmt, ap);
85 va_end(ap);
86
87 return ret;
88 }
89
90
strfmon(char * restrict s,size_t n,const char * restrict fmt,...)91 ssize_t strfmon(char *restrict s, size_t n, const char *restrict fmt, ...)
92 {
93 va_list ap;
94 ssize_t ret;
95
96 va_start(ap, fmt);
97 ret = vstrfmon_l(s, n, CURRENT_LOCALE, fmt, ap);
98 va_end(ap);
99
100 return ret;
101 }
102