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