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