Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(482)

Side by Side Diff: fusl/src/stdio/vfwprintf.c

Issue 1714623002: [fusl] clang-format fusl (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: headers too Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 #include "stdio_impl.h" 1 #include "stdio_impl.h"
2 #include <errno.h> 2 #include <errno.h>
3 #include <ctype.h> 3 #include <ctype.h>
4 #include <limits.h> 4 #include <limits.h>
5 #include <string.h> 5 #include <string.h>
6 #include <stdarg.h> 6 #include <stdarg.h>
7 #include <wchar.h> 7 #include <wchar.h>
8 #include <inttypes.h> 8 #include <inttypes.h>
9 9
10 /* Convenient bit representation for modifier flags, which all fall 10 /* Convenient bit representation for modifier flags, which all fall
11 * within 31 codepoints of the space character. */ 11 * within 31 codepoints of the space character. */
12 12
13 #define ALT_FORM (1U<<('#'-' ')) 13 #define ALT_FORM (1U << ('#' - ' '))
14 #define ZERO_PAD (1U<<('0'-' ')) 14 #define ZERO_PAD (1U << ('0' - ' '))
15 #define LEFT_ADJ (1U<<('-'-' ')) 15 #define LEFT_ADJ (1U << ('-' - ' '))
16 #define PAD_POS (1U<<(' '-' ')) 16 #define PAD_POS (1U << (' ' - ' '))
17 #define MARK_POS (1U<<('+'-' ')) 17 #define MARK_POS (1U << ('+' - ' '))
18 #define GROUPED (1U<<('\''-' ')) 18 #define GROUPED (1U << ('\'' - ' '))
19 19
20 #define FLAGMASK (ALT_FORM|ZERO_PAD|LEFT_ADJ|PAD_POS|MARK_POS|GROUPED) 20 #define FLAGMASK (ALT_FORM | ZERO_PAD | LEFT_ADJ | PAD_POS | MARK_POS | GROUPED)
21 21
22 #if UINT_MAX == ULONG_MAX 22 #if UINT_MAX == ULONG_MAX
23 #define LONG_IS_INT 23 #define LONG_IS_INT
24 #endif 24 #endif
25 25
26 #if SIZE_MAX != ULONG_MAX || UINTMAX_MAX != ULLONG_MAX 26 #if SIZE_MAX != ULONG_MAX || UINTMAX_MAX != ULLONG_MAX
27 #define ODD_TYPES 27 #define ODD_TYPES
28 #endif 28 #endif
29 29
30 /* State machine to accept length modifiers + conversion specifiers. 30 /* State machine to accept length modifiers + conversion specifiers.
31 * Result is 0 on failure, or an argument type to pop on success. */ 31 * Result is 0 on failure, or an argument type to pop on success. */
32 32
33 enum { 33 enum {
34 » BARE, LPRE, LLPRE, HPRE, HHPRE, BIGLPRE, 34 BARE,
35 » ZTPRE, JPRE, 35 LPRE,
36 » STOP, 36 LLPRE,
37 » PTR, INT, UINT, ULLONG, 37 HPRE,
38 HHPRE,
39 BIGLPRE,
40 ZTPRE,
41 JPRE,
42 STOP,
43 PTR,
44 INT,
45 UINT,
46 ULLONG,
38 #ifndef LONG_IS_INT 47 #ifndef LONG_IS_INT
39 » LONG, ULONG, 48 LONG,
49 ULONG,
40 #else 50 #else
41 #define LONG INT 51 #define LONG INT
42 #define ULONG UINT 52 #define ULONG UINT
43 #endif 53 #endif
44 » SHORT, USHORT, CHAR, UCHAR, 54 SHORT,
55 USHORT,
56 CHAR,
57 UCHAR,
45 #ifdef ODD_TYPES 58 #ifdef ODD_TYPES
46 » LLONG, SIZET, IMAX, UMAX, PDIFF, UIPTR, 59 LLONG,
60 SIZET,
61 IMAX,
62 UMAX,
63 PDIFF,
64 UIPTR,
47 #else 65 #else
48 #define LLONG ULLONG 66 #define LLONG ULLONG
49 #define SIZET ULONG 67 #define SIZET ULONG
50 #define IMAX LLONG 68 #define IMAX LLONG
51 #define UMAX ULLONG 69 #define UMAX ULLONG
52 #define PDIFF LONG 70 #define PDIFF LONG
53 #define UIPTR ULONG 71 #define UIPTR ULONG
54 #endif 72 #endif
55 » DBL, LDBL, 73 DBL,
56 » NOARG, 74 LDBL,
57 » MAXSTATE 75 NOARG,
76 MAXSTATE
58 }; 77 };
59 78
60 #define S(x) [(x)-'A'] 79 #define S(x) [(x) - 'A']
61 80
62 static const unsigned char states[]['z'-'A'+1] = { 81 static const unsigned char states[]['z' - 'A' + 1] = {
63 » { /* 0: bare types */ 82 {
64 » » S('d') = INT, S('i') = INT, 83 /* 0: bare types */
65 » » S('o') = UINT, S('u') = UINT, S('x') = UINT, S('X') = UINT, 84 S('d') = INT, S('i') = INT, S('o') = UINT, S('u') = UINT,
66 » » S('e') = DBL, S('f') = DBL, S('g') = DBL, S('a') = DBL, 85 S('x') = UINT, S('X') = UINT, S('e') = DBL, S('f') = DBL,
67 » » S('E') = DBL, S('F') = DBL, S('G') = DBL, S('A') = DBL, 86 S('g') = DBL, S('a') = DBL, S('E') = DBL, S('F') = DBL,
68 » » S('c') = CHAR, S('C') = INT, 87 S('G') = DBL, S('A') = DBL, S('c') = CHAR, S('C') = INT,
69 » » S('s') = PTR, S('S') = PTR, S('p') = UIPTR, S('n') = PTR, 88 S('s') = PTR, S('S') = PTR, S('p') = UIPTR, S('n') = PTR,
70 » » S('m') = NOARG, 89 S('m') = NOARG, S('l') = LPRE, S('h') = HPRE, S('L') = BIGLPRE,
71 » » S('l') = LPRE, S('h') = HPRE, S('L') = BIGLPRE, 90 S('z') = ZTPRE, S('j') = JPRE, S('t') = ZTPRE,
72 » » S('z') = ZTPRE, S('j') = JPRE, S('t') = ZTPRE, 91 },
73 » }, { /* 1: l-prefixed */ 92 {
74 » » S('d') = LONG, S('i') = LONG, 93 /* 1: l-prefixed */
75 » » S('o') = ULONG, S('u') = ULONG, S('x') = ULONG, S('X') = ULONG, 94 S('d') = LONG, S('i') = LONG, S('o') = ULONG, S('u') = ULONG,
76 » » S('c') = INT, S('s') = PTR, S('n') = PTR, 95 S('x') = ULONG, S('X') = ULONG, S('c') = INT, S('s') = PTR,
77 » » S('l') = LLPRE, 96 S('n') = PTR, S('l') = LLPRE,
78 » }, { /* 2: ll-prefixed */ 97 },
79 » » S('d') = LLONG, S('i') = LLONG, 98 {
80 » » S('o') = ULLONG, S('u') = ULLONG, 99 /* 2: ll-prefixed */
81 » » S('x') = ULLONG, S('X') = ULLONG, 100 S('d') = LLONG, S('i') = LLONG, S('o') = ULLONG, S('u') = ULLONG,
82 » » S('n') = PTR, 101 S('x') = ULLONG, S('X') = ULLONG, S('n') = PTR,
83 » }, { /* 3: h-prefixed */ 102 },
84 » » S('d') = SHORT, S('i') = SHORT, 103 {
85 » » S('o') = USHORT, S('u') = USHORT, 104 /* 3: h-prefixed */
86 » » S('x') = USHORT, S('X') = USHORT, 105 S('d') = SHORT, S('i') = SHORT, S('o') = USHORT, S('u') = USHORT,
87 » » S('n') = PTR, 106 S('x') = USHORT, S('X') = USHORT, S('n') = PTR, S('h') = HHPRE,
88 » » S('h') = HHPRE, 107 },
89 » }, { /* 4: hh-prefixed */ 108 {
90 » » S('d') = CHAR, S('i') = CHAR, 109 /* 4: hh-prefixed */
91 » » S('o') = UCHAR, S('u') = UCHAR, 110 S('d') = CHAR, S('i') = CHAR, S('o') = UCHAR, S('u') = UCHAR,
92 » » S('x') = UCHAR, S('X') = UCHAR, 111 S('x') = UCHAR, S('X') = UCHAR, S('n') = PTR,
93 » » S('n') = PTR, 112 },
94 » }, { /* 5: L-prefixed */ 113 {
95 » » S('e') = LDBL, S('f') = LDBL, S('g') = LDBL, S('a') = LDBL, 114 /* 5: L-prefixed */
96 » » S('E') = LDBL, S('F') = LDBL, S('G') = LDBL, S('A') = LDBL, 115 S('e') = LDBL, S('f') = LDBL, S('g') = LDBL, S('a') = LDBL,
97 » » S('n') = PTR, 116 S('E') = LDBL, S('F') = LDBL, S('G') = LDBL, S('A') = LDBL,
98 » }, { /* 6: z- or t-prefixed (assumed to be same size) */ 117 S('n') = PTR,
99 » » S('d') = PDIFF, S('i') = PDIFF, 118 },
100 » » S('o') = SIZET, S('u') = SIZET, 119 {
101 » » S('x') = SIZET, S('X') = SIZET, 120 /* 6: z- or t-prefixed (assumed to be same size) */
102 » » S('n') = PTR, 121 S('d') = PDIFF, S('i') = PDIFF, S('o') = SIZET, S('u') = SIZET,
103 » }, { /* 7: j-prefixed */ 122 S('x') = SIZET, S('X') = SIZET, S('n') = PTR,
104 » » S('d') = IMAX, S('i') = IMAX, 123 },
105 » » S('o') = UMAX, S('u') = UMAX, 124 {
106 » » S('x') = UMAX, S('X') = UMAX, 125 /* 7: j-prefixed */
107 » » S('n') = PTR, 126 S('d') = IMAX, S('i') = IMAX, S('o') = UMAX, S('u') = UMAX,
108 » } 127 S('x') = UMAX, S('X') = UMAX, S('n') = PTR,
128 }};
129
130 #define OOB(x) ((unsigned)(x) - 'A' > 'z' - 'A')
131
132 union arg {
133 uintmax_t i;
134 long double f;
135 void* p;
109 }; 136 };
110 137
111 #define OOB(x) ((unsigned)(x)-'A' > 'z'-'A') 138 static void pop_arg(union arg* arg, int type, va_list* ap) {
112 139 /* Give the compiler a hint for optimizing the switch. */
113 union arg 140 if ((unsigned)type > MAXSTATE)
114 { 141 return;
115 » uintmax_t i; 142 switch (type) {
116 » long double f; 143 case PTR:
117 » void *p; 144 arg->p = va_arg(*ap, void*);
118 }; 145 break;
119 146 case INT:
120 static void pop_arg(union arg *arg, int type, va_list *ap) 147 arg->i = va_arg(*ap, int);
121 { 148 break;
122 » /* Give the compiler a hint for optimizing the switch. */ 149 case UINT:
123 » if ((unsigned)type > MAXSTATE) return; 150 arg->i = va_arg(*ap, unsigned int);
124 » switch (type) {
125 » case PTR:» arg->p = va_arg(*ap, void *);
126 » break; case INT:» arg->i = va_arg(*ap, int);
127 » break; case UINT:» arg->i = va_arg(*ap, unsigned int);
128 #ifndef LONG_IS_INT 151 #ifndef LONG_IS_INT
129 » break; case LONG:» arg->i = va_arg(*ap, long); 152 break;
130 » break; case ULONG:» arg->i = va_arg(*ap, unsigned long); 153 case LONG:
154 arg->i = va_arg(*ap, long);
155 break;
156 case ULONG:
157 arg->i = va_arg(*ap, unsigned long);
131 #endif 158 #endif
132 » break; case ULLONG:» arg->i = va_arg(*ap, unsigned long long); 159 break;
133 » break; case SHORT:» arg->i = (short)va_arg(*ap, int); 160 case ULLONG:
134 » break; case USHORT:» arg->i = (unsigned short)va_arg(*ap, int); 161 arg->i = va_arg(*ap, unsigned long long);
135 » break; case CHAR:» arg->i = (signed char)va_arg(*ap, int); 162 break;
136 » break; case UCHAR:» arg->i = (unsigned char)va_arg(*ap, int); 163 case SHORT:
164 arg->i = (short)va_arg(*ap, int);
165 break;
166 case USHORT:
167 arg->i = (unsigned short)va_arg(*ap, int);
168 break;
169 case CHAR:
170 arg->i = (signed char)va_arg(*ap, int);
171 break;
172 case UCHAR:
173 arg->i = (unsigned char)va_arg(*ap, int);
137 #ifdef ODD_TYPES 174 #ifdef ODD_TYPES
138 » break; case LLONG:» arg->i = va_arg(*ap, long long); 175 break;
139 » break; case SIZET:» arg->i = va_arg(*ap, size_t); 176 case LLONG:
140 » break; case IMAX:» arg->i = va_arg(*ap, intmax_t); 177 arg->i = va_arg(*ap, long long);
141 » break; case UMAX:» arg->i = va_arg(*ap, uintmax_t); 178 break;
142 » break; case PDIFF:» arg->i = va_arg(*ap, ptrdiff_t); 179 case SIZET:
143 » break; case UIPTR:» arg->i = (uintptr_t)va_arg(*ap, void *); 180 arg->i = va_arg(*ap, size_t);
181 break;
182 case IMAX:
183 arg->i = va_arg(*ap, intmax_t);
184 break;
185 case UMAX:
186 arg->i = va_arg(*ap, uintmax_t);
187 break;
188 case PDIFF:
189 arg->i = va_arg(*ap, ptrdiff_t);
190 break;
191 case UIPTR:
192 arg->i = (uintptr_t)va_arg(*ap, void*);
144 #endif 193 #endif
145 » break; case DBL:» arg->f = va_arg(*ap, double); 194 break;
146 » break; case LDBL:» arg->f = va_arg(*ap, long double); 195 case DBL:
147 » } 196 arg->f = va_arg(*ap, double);
197 break;
198 case LDBL:
199 arg->f = va_arg(*ap, long double);
200 }
148 } 201 }
149 202
150 static void out(FILE *f, const wchar_t *s, size_t l) 203 static void out(FILE* f, const wchar_t* s, size_t l) {
151 { 204 while (l-- && !(f->flags & F_ERR))
152 » while (l-- && !(f->flags & F_ERR)) fputwc(*s++, f); 205 fputwc(*s++, f);
153 } 206 }
154 207
155 static int getint(wchar_t **s) { 208 static int getint(wchar_t** s) {
156 » int i; 209 int i;
157 » for (i=0; iswdigit(**s); (*s)++) 210 for (i = 0; iswdigit(**s); (*s)++)
158 » » i = 10*i + (**s-'0'); 211 i = 10 * i + (**s - '0');
159 » return i; 212 return i;
160 } 213 }
161 214
162 static const char sizeprefix['y'-'a'] = { 215 static const char sizeprefix['y' - 'a'] =
163 ['a'-'a']='L', ['e'-'a']='L', ['f'-'a']='L', ['g'-'a']='L', 216 {['a' - 'a'] = 'L', ['e' - 'a'] = 'L', ['f' - 'a'] = 'L', ['g' - 'a'] = 'L',
164 ['d'-'a']='j', ['i'-'a']='j', ['o'-'a']='j', ['u'-'a']='j', ['x'-'a']='j', 217 ['d' - 'a'] = 'j', ['i' - 'a'] = 'j', ['o' - 'a'] = 'j', ['u' - 'a'] = 'j',
165 ['p'-'a']='j' 218 ['x' - 'a'] = 'j', ['p' - 'a'] = 'j'};
166 }; 219
167 220 static int wprintf_core(FILE* f,
168 static int wprintf_core(FILE *f, const wchar_t *fmt, va_list *ap, union arg *nl_ arg, int *nl_type) 221 const wchar_t* fmt,
169 { 222 va_list* ap,
170 » wchar_t *a, *z, *s=(wchar_t *)fmt; 223 union arg* nl_arg,
171 » unsigned l10n=0, litpct, fl; 224 int* nl_type) {
172 » int w, p; 225 wchar_t *a, *z, *s = (wchar_t *)fmt;
173 » union arg arg; 226 unsigned l10n = 0, litpct, fl;
174 » int argpos; 227 int w, p;
175 » unsigned st, ps; 228 union arg arg;
176 » int cnt=0, l=0; 229 int argpos;
177 » int i; 230 unsigned st, ps;
178 » int t; 231 int cnt = 0, l = 0;
179 » char *bs; 232 int i;
180 » char charfmt[16]; 233 int t;
181 » wchar_t wc; 234 char* bs;
182 235 char charfmt[16];
183 » for (;;) { 236 wchar_t wc;
184 » » /* Update output count, end loop when fmt is exhausted */ 237
185 » » if (cnt >= 0) { 238 for (;;) {
186 » » » if (l > INT_MAX - cnt) { 239 /* Update output count, end loop when fmt is exhausted */
187 » » » » if (!ferror(f)) errno = EOVERFLOW; 240 if (cnt >= 0) {
188 » » » » cnt = -1; 241 if (l > INT_MAX - cnt) {
189 » » » } else cnt += l; 242 if (!ferror(f))
190 » » } 243 errno = EOVERFLOW;
191 » » if (!*s) break; 244 cnt = -1;
192 245 } else
193 » » /* Handle literal text and %% format specifiers */ 246 cnt += l;
194 » » for (a=s; *s && *s!='%'; s++); 247 }
195 » » litpct = wcsspn(s, L"%")/2; /* Optimize %%%% runs */ 248 if (!*s)
196 » » z = s+litpct; 249 break;
197 » » s += 2*litpct; 250
198 » » l = z-a; 251 /* Handle literal text and %% format specifiers */
199 » » if (f) out(f, a, l); 252 for (a = s; *s && *s != '%'; s++)
200 » » if (l) continue; 253 ;
201 254 litpct = wcsspn(s, L"%") / 2; /* Optimize %%%% runs */
202 » » if (iswdigit(s[1]) && s[2]=='$') { 255 z = s + litpct;
203 » » » l10n=1; 256 s += 2 * litpct;
204 » » » argpos = s[1]-'0'; 257 l = z - a;
205 » » » s+=3; 258 if (f)
206 » » } else { 259 out(f, a, l);
207 » » » argpos = -1; 260 if (l)
208 » » » s++; 261 continue;
209 » » } 262
210 263 if (iswdigit(s[1]) && s[2] == '$') {
211 » » /* Read modifier flags */ 264 l10n = 1;
212 » » for (fl=0; (unsigned)*s-' '<32 && (FLAGMASK&(1U<<(*s-' '))); s++ ) 265 argpos = s[1] - '0';
213 » » » fl |= 1U<<(*s-' '); 266 s += 3;
214 267 } else {
215 » » /* Read field width */ 268 argpos = -1;
216 » » if (*s=='*') { 269 s++;
217 » » » if (iswdigit(s[1]) && s[2]=='$') { 270 }
218 » » » » l10n=1; 271
219 » » » » nl_type[s[1]-'0'] = INT; 272 /* Read modifier flags */
220 » » » » w = nl_arg[s[1]-'0'].i; 273 for (fl = 0; (unsigned)*s - ' ' < 32 && (FLAGMASK & (1U << (*s - ' ')));
221 » » » » s+=3; 274 s++)
222 » » » } else if (!l10n) { 275 fl |= 1U << (*s - ' ');
223 » » » » w = f ? va_arg(*ap, int) : 0; 276
224 » » » » s++; 277 /* Read field width */
225 » » » } else return -1; 278 if (*s == '*') {
226 » » » if (w<0) fl|=LEFT_ADJ, w=-w; 279 if (iswdigit(s[1]) && s[2] == '$') {
227 » » } else if ((w=getint(&s))<0) return -1; 280 l10n = 1;
228 281 nl_type[s[1] - '0'] = INT;
229 » » /* Read precision */ 282 w = nl_arg[s[1] - '0'].i;
230 » » if (*s=='.' && s[1]=='*') { 283 s += 3;
231 » » » if (isdigit(s[2]) && s[3]=='$') { 284 } else if (!l10n) {
232 » » » » nl_type[s[2]-'0'] = INT; 285 w = f ? va_arg(*ap, int) : 0;
233 » » » » p = nl_arg[s[2]-'0'].i; 286 s++;
234 » » » » s+=4; 287 } else
235 » » » } else if (!l10n) { 288 return -1;
236 » » » » p = f ? va_arg(*ap, int) : 0; 289 if (w < 0)
237 » » » » s+=2; 290 fl |= LEFT_ADJ, w = -w;
238 » » » } else return -1; 291 } else if ((w = getint(&s)) < 0)
239 » » } else if (*s=='.') { 292 return -1;
240 » » » s++; 293
241 » » » p = getint(&s); 294 /* Read precision */
242 » » } else p = -1; 295 if (*s == '.' && s[1] == '*') {
243 296 if (isdigit(s[2]) && s[3] == '$') {
244 » » /* Format specifier state machine */ 297 nl_type[s[2] - '0'] = INT;
245 » » st=0; 298 p = nl_arg[s[2] - '0'].i;
246 » » do { 299 s += 4;
247 » » » if (OOB(*s)) return -1; 300 } else if (!l10n) {
248 » » » ps=st; 301 p = f ? va_arg(*ap, int) : 0;
249 » » » st=states[st]S(*s++); 302 s += 2;
250 » » } while (st-1<STOP); 303 } else
251 » » if (!st) return -1; 304 return -1;
252 305 } else if (*s == '.') {
253 » » /* Check validity of argument type (nl/normal) */ 306 s++;
254 » » if (st==NOARG) { 307 p = getint(&s);
255 » » » if (argpos>=0) return -1; 308 } else
256 » » } else { 309 p = -1;
257 » » » if (argpos>=0) nl_type[argpos]=st, arg=nl_arg[argpos]; 310
258 » » » else if (f) pop_arg(&arg, st, ap); 311 /* Format specifier state machine */
259 » » » else return 0; 312 st = 0;
260 » » } 313 do {
261 314 if (OOB(*s))
262 » » if (!f) continue; 315 return -1;
263 » » t = s[-1]; 316 ps = st;
264 » » if (ps && (t&15)==3) t&=~32; 317 st = states[st] S(*s++);
265 318 } while (st - 1 < STOP);
266 » » switch (t) { 319 if (!st)
267 » » case 'n': 320 return -1;
268 » » » switch(ps) { 321
269 » » » case BARE: *(int *)arg.p = cnt; break; 322 /* Check validity of argument type (nl/normal) */
270 » » » case LPRE: *(long *)arg.p = cnt; break; 323 if (st == NOARG) {
271 » » » case LLPRE: *(long long *)arg.p = cnt; break; 324 if (argpos >= 0)
272 » » » case HPRE: *(unsigned short *)arg.p = cnt; break; 325 return -1;
273 » » » case HHPRE: *(unsigned char *)arg.p = cnt; break; 326 } else {
274 » » » case ZTPRE: *(size_t *)arg.p = cnt; break; 327 if (argpos >= 0)
275 » » » case JPRE: *(uintmax_t *)arg.p = cnt; break; 328 nl_type[argpos] = st, arg = nl_arg[argpos];
276 » » » } 329 else if (f)
277 » » » continue; 330 pop_arg(&arg, st, ap);
278 » » case 'c': 331 else
279 » » » fputwc(btowc(arg.i), f); 332 return 0;
280 » » » l = 1; 333 }
281 » » » continue; 334
282 » » case 'C': 335 if (!f)
283 » » » fputwc(arg.i, f); 336 continue;
284 » » » l = 1; 337 t = s[-1];
285 » » » continue; 338 if (ps && (t & 15) == 3)
286 » » case 'S': 339 t &= ~32;
287 » » » a = arg.p; 340
288 » » » z = wmemchr(a, 0, p); 341 switch (t) {
289 » » » if (z) p=z-a; 342 case 'n':
290 » » » if (w<p) w=p; 343 switch (ps) {
291 » » » if (!(fl&LEFT_ADJ)) fprintf(f, "%.*s", w-p, ""); 344 case BARE:
292 » » » out(f, a, p); 345 *(int*)arg.p = cnt;
293 » » » if ((fl&LEFT_ADJ)) fprintf(f, "%.*s", w-p, ""); 346 break;
294 » » » l=w; 347 case LPRE:
295 » » » continue; 348 *(long*)arg.p = cnt;
296 » » case 'm': 349 break;
297 » » » arg.p = strerror(errno); 350 case LLPRE:
298 » » case 's': 351 *(long long*)arg.p = cnt;
299 » » » if (!arg.p) arg.p = "(null)"; 352 break;
300 » » » bs = arg.p; 353 case HPRE:
301 » » » if (p<0) p = INT_MAX; 354 *(unsigned short*)arg.p = cnt;
302 » » » for (i=l=0; l<p && (i=mbtowc(&wc, bs, MB_LEN_MAX))>0; bs +=i, l++); 355 break;
303 » » » if (i<0) return -1; 356 case HHPRE:
304 » » » p=l; 357 *(unsigned char*)arg.p = cnt;
305 » » » if (w<p) w=p; 358 break;
306 » » » if (!(fl&LEFT_ADJ)) fprintf(f, "%.*s", w-p, ""); 359 case ZTPRE:
307 » » » bs = arg.p; 360 *(size_t*)arg.p = cnt;
308 » » » while (l--) { 361 break;
309 » » » » i=mbtowc(&wc, bs, MB_LEN_MAX); 362 case JPRE:
310 » » » » bs+=i; 363 *(uintmax_t*)arg.p = cnt;
311 » » » » fputwc(wc, f); 364 break;
312 » » » } 365 }
313 » » » if ((fl&LEFT_ADJ)) fprintf(f, "%.*s", w-p, ""); 366 continue;
314 » » » l=w; 367 case 'c':
315 » » » continue; 368 fputwc(btowc(arg.i), f);
316 » » } 369 l = 1;
317 370 continue;
318 » » snprintf(charfmt, sizeof charfmt, "%%%s%s%s%s%s*.*%c%c", 371 case 'C':
319 » » » (fl & ALT_FORM) ? "#" : "", 372 fputwc(arg.i, f);
320 » » » (fl & MARK_POS) ? "+" : "", 373 l = 1;
321 » » » (fl & LEFT_ADJ) ? "-" : "", 374 continue;
322 » » » (fl & PAD_POS) ? " " : "", 375 case 'S':
323 » » » (fl & ZERO_PAD) ? "0" : "", 376 a = arg.p;
324 » » » sizeprefix[(t|32)-'a'], t); 377 z = wmemchr(a, 0, p);
325 378 if (z)
326 » » switch (t|32) { 379 p = z - a;
327 » » case 'a': case 'e': case 'f': case 'g': 380 if (w < p)
328 » » » l = fprintf(f, charfmt, w, p, arg.f); 381 w = p;
329 » » » break; 382 if (!(fl & LEFT_ADJ))
330 » » case 'd': case 'i': case 'o': case 'u': case 'x': case 'p': 383 fprintf(f, "%.*s", w - p, "");
331 » » » l = fprintf(f, charfmt, w, p, arg.i); 384 out(f, a, p);
332 » » » break; 385 if ((fl & LEFT_ADJ))
333 » » } 386 fprintf(f, "%.*s", w - p, "");
334 » } 387 l = w;
335 388 continue;
336 » if (f) return cnt; 389 case 'm':
337 » if (!l10n) return 0; 390 arg.p = strerror(errno);
338 391 case 's':
339 » for (i=1; i<=NL_ARGMAX && nl_type[i]; i++) 392 if (!arg.p)
340 » » pop_arg(nl_arg+i, nl_type[i], ap); 393 arg.p = "(null)";
341 » for (; i<=NL_ARGMAX && !nl_type[i]; i++); 394 bs = arg.p;
342 » if (i<=NL_ARGMAX) return -1; 395 if (p < 0)
343 » return 1; 396 p = INT_MAX;
397 for (i = l = 0; l < p && (i = mbtowc(&wc, bs, MB_LEN_MAX)) > 0;
398 bs += i, l++)
399 ;
400 if (i < 0)
401 return -1;
402 p = l;
403 if (w < p)
404 w = p;
405 if (!(fl & LEFT_ADJ))
406 fprintf(f, "%.*s", w - p, "");
407 bs = arg.p;
408 while (l--) {
409 i = mbtowc(&wc, bs, MB_LEN_MAX);
410 bs += i;
411 fputwc(wc, f);
412 }
413 if ((fl & LEFT_ADJ))
414 fprintf(f, "%.*s", w - p, "");
415 l = w;
416 continue;
417 }
418
419 snprintf(charfmt, sizeof charfmt, "%%%s%s%s%s%s*.*%c%c",
420 (fl & ALT_FORM) ? "#" : "", (fl & MARK_POS) ? "+" : "",
421 (fl & LEFT_ADJ) ? "-" : "", (fl & PAD_POS) ? " " : "",
422 (fl & ZERO_PAD) ? "0" : "", sizeprefix[(t | 32) - 'a'], t);
423
424 switch (t | 32) {
425 case 'a':
426 case 'e':
427 case 'f':
428 case 'g':
429 l = fprintf(f, charfmt, w, p, arg.f);
430 break;
431 case 'd':
432 case 'i':
433 case 'o':
434 case 'u':
435 case 'x':
436 case 'p':
437 l = fprintf(f, charfmt, w, p, arg.i);
438 break;
439 }
440 }
441
442 if (f)
443 return cnt;
444 if (!l10n)
445 return 0;
446
447 for (i = 1; i <= NL_ARGMAX && nl_type[i]; i++)
448 pop_arg(nl_arg + i, nl_type[i], ap);
449 for (; i <= NL_ARGMAX && !nl_type[i]; i++)
450 ;
451 if (i <= NL_ARGMAX)
452 return -1;
453 return 1;
344 } 454 }
345 455
346 int vfwprintf(FILE *restrict f, const wchar_t *restrict fmt, va_list ap) 456 int vfwprintf(FILE* restrict f, const wchar_t* restrict fmt, va_list ap) {
347 { 457 va_list ap2;
348 » va_list ap2; 458 int nl_type[NL_ARGMAX] = {0};
349 » int nl_type[NL_ARGMAX] = {0}; 459 union arg nl_arg[NL_ARGMAX];
350 » union arg nl_arg[NL_ARGMAX]; 460 int olderr;
351 » int olderr; 461 int ret;
352 » int ret; 462
353 463 /* the copy allows passing va_list* even if va_list is an array */
354 » /* the copy allows passing va_list* even if va_list is an array */ 464 va_copy(ap2, ap);
355 » va_copy(ap2, ap); 465 if (wprintf_core(0, fmt, &ap2, nl_arg, nl_type) < 0) {
356 » if (wprintf_core(0, fmt, &ap2, nl_arg, nl_type) < 0) { 466 va_end(ap2);
357 » » va_end(ap2); 467 return -1;
358 » » return -1; 468 }
359 » } 469
360 470 FLOCK(f);
361 » FLOCK(f); 471 fwide(f, 1);
362 » fwide(f, 1); 472 olderr = f->flags & F_ERR;
363 » olderr = f->flags & F_ERR; 473 f->flags &= ~F_ERR;
364 » f->flags &= ~F_ERR; 474 ret = wprintf_core(f, fmt, &ap2, nl_arg, nl_type);
365 » ret = wprintf_core(f, fmt, &ap2, nl_arg, nl_type); 475 if (f->flags & F_ERR)
366 » if (f->flags & F_ERR) ret = -1; 476 ret = -1;
367 » f->flags |= olderr; 477 f->flags |= olderr;
368 » FUNLOCK(f); 478 FUNLOCK(f);
369 » va_end(ap2); 479 va_end(ap2);
370 » return ret; 480 return ret;
371 } 481 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698