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
8static 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
78ssize_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
91ssize_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