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