OLD | NEW |
1 #include <stdio.h> | 1 #include <stdio.h> |
2 #include <ctype.h> | 2 #include <ctype.h> |
3 #include <stdarg.h> | 3 #include <stdarg.h> |
4 #include <monetary.h> | 4 #include <monetary.h> |
5 #include <errno.h> | 5 #include <errno.h> |
6 #include "locale_impl.h" | 6 #include "locale_impl.h" |
7 | 7 |
8 static ssize_t vstrfmon_l(char *s, size_t n, locale_t loc, const char *fmt, va_l
ist ap) | 8 static ssize_t vstrfmon_l(char* s, |
9 { | 9 size_t n, |
10 » size_t l; | 10 locale_t loc, |
11 » double x; | 11 const char* fmt, |
12 » int fill, nogrp, negpar, nosym, left, intl; | 12 va_list ap) { |
13 » int lp, rp, w, fw; | 13 size_t l; |
14 » char *s0=s; | 14 double x; |
15 » for (; n && *fmt; ) { | 15 int fill, nogrp, negpar, nosym, left, intl; |
16 » » if (*fmt != '%') { | 16 int lp, rp, w, fw; |
17 » » literal: | 17 char* s0 = s; |
18 » » » *s++ = *fmt++; | 18 for (; n && *fmt;) { |
19 » » » n--; | 19 if (*fmt != '%') { |
20 » » » continue; | 20 literal: |
21 » » } | 21 *s++ = *fmt++; |
22 » » fmt++; | 22 n--; |
23 » » if (*fmt == '%') goto literal; | 23 continue; |
| 24 } |
| 25 fmt++; |
| 26 if (*fmt == '%') |
| 27 goto literal; |
24 | 28 |
25 » » fill = ' '; | 29 fill = ' '; |
26 » » nogrp = 0; | 30 nogrp = 0; |
27 » » negpar = 0; | 31 negpar = 0; |
28 » » nosym = 0; | 32 nosym = 0; |
29 » » left = 0; | 33 left = 0; |
30 » » for (; ; fmt++) { | 34 for (;; fmt++) { |
31 » » » switch (*fmt) { | 35 switch (*fmt) { |
32 » » » case '=': | 36 case '=': |
33 » » » » fill = *++fmt; | 37 fill = *++fmt; |
34 » » » » continue; | 38 continue; |
35 » » » case '^': | 39 case '^': |
36 » » » » nogrp = 1; | 40 nogrp = 1; |
37 » » » » continue; | 41 continue; |
38 » » » case '(': | 42 case '(': |
39 » » » » negpar = 1; | 43 negpar = 1; |
40 » » » case '+': | 44 case '+': |
41 » » » » continue; | 45 continue; |
42 » » » case '!': | 46 case '!': |
43 » » » » nosym = 1; | 47 nosym = 1; |
44 » » » » continue; | 48 continue; |
45 » » » case '-': | 49 case '-': |
46 » » » » left = 1; | 50 left = 1; |
47 » » » » continue; | 51 continue; |
48 » » » } | 52 } |
49 » » » break; | 53 break; |
50 » » } | 54 } |
51 | 55 |
52 » » for (fw=0; isdigit(*fmt); fmt++) | 56 for (fw = 0; isdigit(*fmt); fmt++) |
53 » » » fw = 10*fw + (*fmt-'0'); | 57 fw = 10 * fw + (*fmt - '0'); |
54 » » lp = 0; | 58 lp = 0; |
55 » » rp = 2; | 59 rp = 2; |
56 » » if (*fmt=='#') for (lp=0, fmt++; isdigit(*fmt); fmt++) | 60 if (*fmt == '#') |
57 » » » lp = 10*lp + (*fmt-'0'); | 61 for (lp = 0, fmt++; isdigit(*fmt); fmt++) |
58 » » if (*fmt=='.') for (rp=0, fmt++; isdigit(*fmt); fmt++) | 62 lp = 10 * lp + (*fmt - '0'); |
59 » » » rp = 10*rp + (*fmt-'0'); | 63 if (*fmt == '.') |
| 64 for (rp = 0, fmt++; isdigit(*fmt); fmt++) |
| 65 rp = 10 * rp + (*fmt - '0'); |
60 | 66 |
61 » » intl = *fmt++ == 'i'; | 67 intl = *fmt++ == 'i'; |
62 | 68 |
63 » » w = lp + 1 + rp; | 69 w = lp + 1 + rp; |
64 » » if (!left && fw>w) w = fw; | 70 if (!left && fw > w) |
| 71 w = fw; |
65 | 72 |
66 » » x = va_arg(ap, double); | 73 x = va_arg(ap, double); |
67 » » l = snprintf(s, n, "%*.*f", w, rp, x); | 74 l = snprintf(s, n, "%*.*f", w, rp, x); |
68 » » if (l >= n) { | 75 if (l >= n) { |
69 » » » errno = E2BIG; | 76 errno = E2BIG; |
70 » » » return -1; | 77 return -1; |
71 » » } | 78 } |
72 » » s += l; | 79 s += l; |
73 » » n -= l; | 80 n -= l; |
74 » } | 81 } |
75 » return s-s0; | 82 return s - s0; |
76 } | 83 } |
77 | 84 |
78 ssize_t strfmon_l(char *restrict s, size_t n, locale_t loc, const char *restrict
fmt, ...) | 85 ssize_t strfmon_l(char* restrict s, |
79 { | 86 size_t n, |
80 » va_list ap; | 87 locale_t loc, |
81 » ssize_t ret; | 88 const char* restrict fmt, |
| 89 ...) { |
| 90 va_list ap; |
| 91 ssize_t ret; |
82 | 92 |
83 » va_start(ap, fmt); | 93 va_start(ap, fmt); |
84 » ret = vstrfmon_l(s, n, loc, fmt, ap); | 94 ret = vstrfmon_l(s, n, loc, fmt, ap); |
85 » va_end(ap); | 95 va_end(ap); |
86 | 96 |
87 » return ret; | 97 return ret; |
88 } | 98 } |
89 | 99 |
| 100 ssize_t strfmon(char* restrict s, size_t n, const char* restrict fmt, ...) { |
| 101 va_list ap; |
| 102 ssize_t ret; |
90 | 103 |
91 ssize_t strfmon(char *restrict s, size_t n, const char *restrict fmt, ...) | 104 va_start(ap, fmt); |
92 { | 105 ret = vstrfmon_l(s, n, CURRENT_LOCALE, fmt, ap); |
93 » va_list ap; | 106 va_end(ap); |
94 » ssize_t ret; | |
95 | 107 |
96 » va_start(ap, fmt); | 108 return ret; |
97 » ret = vstrfmon_l(s, n, CURRENT_LOCALE, fmt, ap); | |
98 » va_end(ap); | |
99 | |
100 » return ret; | |
101 } | 109 } |
OLD | NEW |