use restrict everywhere it's required by c99 and/or posix 2008
[musl] / src / locale / strfmon.c
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 }