Home | History | Annotate | Download | only in musl-locale
      1 #include <stdio.h>
      2 #include <ctype.h>
      3 #include <stdarg.h>
      4 #include <monetary.h>
      5 #include <errno.h>
      6 
      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 
     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 
     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