master
  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}