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