1#include <stdio.h>
2#include <ctype.h>
3#include <stdarg.h>
4#include <monetary.h>
5#include <errno.h>
6
7static 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
77ssize_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
90ssize_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