diff options
| author | Rich Felker <dalias@aerifal.cx> | 2012-03-21 00:47:37 -0400 | 
|---|---|---|
| committer | Rich Felker <dalias@aerifal.cx> | 2012-03-21 00:47:37 -0400 | 
| commit | 25501c1079756c9b438842da649585c2a6983c24 (patch) | |
| tree | 422642ec7a55231a10ea7cac5c45f73bd31656f5 /src/locale/strfmon.c | |
| parent | 30df206cb0c66848142898115d301a0d80333d0f (diff) | |
| download | musl-25501c1079756c9b438842da649585c2a6983c24.tar.gz | |
initial, very primitive strfmon
Diffstat (limited to 'src/locale/strfmon.c')
| -rw-r--r-- | src/locale/strfmon.c | 77 | 
1 files changed, 77 insertions, 0 deletions
| diff --git a/src/locale/strfmon.c b/src/locale/strfmon.c new file mode 100644 index 00000000..66bee482 --- /dev/null +++ b/src/locale/strfmon.c @@ -0,0 +1,77 @@ +#include <stdio.h> +#include <ctype.h> +#include <stdarg.h> +#include <monetary.h> +#include <errno.h> + +ssize_t strfmon(char *s, size_t n, const char *fmt, ...) +{ +	size_t l; +	double x; +	int fill, nogrp, negpar, nosym, left, intl; +	int lp, rp, w, fw; +	char *s0=s; +	va_list ap; +	va_start(ap, fmt); +	for (; n && *fmt; ) { +		if (*fmt != '%') { +		literal: +			*s++ = *fmt++; +			n--; +			continue; +		} +		fmt++; +		if (*fmt == '%') goto literal; + +		fill = ' '; +		nogrp = 0; +		negpar = 0; +		nosym = 0; +		left = 0; +		for (; ; fmt++) { +			switch (*fmt) { +			case '=': +				fill = *++fmt; +				continue; +			case '^': +				nogrp = 1; +				continue; +			case '(': +				negpar = 1; +			case '+': +				continue; +			case '!': +				nosym = 1; +				continue; +			case '-': +				left = 1; +				continue; +			} +			break; +		} + +		for (fw=0; isdigit(*fmt); fmt++) +			fw = 10*fw + (*fmt-'0'); +		lp = 0; +		rp = 2; +		if (*fmt=='#') for (lp=0, fmt++; isdigit(*fmt); fmt++) +			lp = 10*lp + (*fmt-'0'); +		if (*fmt=='.') for (rp=0, fmt++; isdigit(*fmt); fmt++) +			rp = 10*rp + (*fmt-'0'); + +		intl = *fmt++ == 'i'; + +		w = lp + 1 + rp; +		if (!left && fw>w) w = fw; + +		x = va_arg(ap, double); +		l = snprintf(s, n, "%*.*f", w, rp, x); +		if (l >= n) { +			errno = E2BIG; +			return -1; +		} +		s += l; +		n -= l; +	} +	return s-s0; +} | 
