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 #include <stdarg.h>
      7 
      8 static 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 
     78 ssize_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 
     91 ssize_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, 0, fmt, ap);
     98 	va_end(ap);
     99 
    100 	return ret;
    101 }
    102