1 /* 2 Copyright (C) 2005-2012 Rich Felker 3 4 Permission is hereby granted, free of charge, to any person obtaining 5 a copy of this software and associated documentation files (the 6 "Software"), to deal in the Software without restriction, including 7 without limitation the rights to use, copy, modify, merge, publish, 8 distribute, sublicense, and/or sell copies of the Software, and to 9 permit persons to whom the Software is furnished to do so, subject to 10 the following conditions: 11 12 The above copyright notice and this permission notice shall be 13 included in all copies or substantial portions of the Software. 14 15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 18 IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 19 CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 20 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 21 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 23 Modified in 2013 for the Android Open Source Project. 24 */ 25 #include <errno.h> 26 #include <ctype.h> 27 #include <limits.h> 28 #include <string.h> 29 #include <stdarg.h> 30 #include <stdlib.h> 31 #include <wchar.h> 32 #include <inttypes.h> 33 #include <math.h> 34 #include <float.h> 35 36 #include "stdio_impl.h" 37 38 /* Some useful macros */ 39 40 #define MAX(a,b) ((a)>(b) ? (a) : (b)) 41 #define MIN(a,b) ((a)<(b) ? (a) : (b)) 42 #define CONCAT2(x,y) x ## y 43 #define CONCAT(x,y) CONCAT2(x,y) 44 45 /* Convenient bit representation for modifier flags, which all fall 46 * within 31 codepoints of the space character. */ 47 48 #define ALT_FORM (1U<<'#'-' ') 49 #define ZERO_PAD (1U<<'0'-' ') 50 #define LEFT_ADJ (1U<<'-'-' ') 51 #define PAD_POS (1U<<' '-' ') 52 #define MARK_POS (1U<<'+'-' ') 53 #define GROUPED (1U<<'\''-' ') 54 55 #define FLAGMASK (ALT_FORM|ZERO_PAD|LEFT_ADJ|PAD_POS|MARK_POS|GROUPED) 56 57 #if UINT_MAX == ULONG_MAX 58 #define LONG_IS_INT 59 #endif 60 61 #if SIZE_MAX != ULONG_MAX || UINTMAX_MAX != ULLONG_MAX 62 #define ODD_TYPES 63 #endif 64 65 /* State machine to accept length modifiers + conversion specifiers. 66 * Result is 0 on failure, or an argument type to pop on success. */ 67 68 enum { 69 BARE, LPRE, LLPRE, HPRE, HHPRE, BIGLPRE, 70 ZTPRE, JPRE, 71 STOP, 72 PTR, INT, UINT, ULLONG, 73 #ifndef LONG_IS_INT 74 LONG, ULONG, 75 #else 76 #define LONG INT 77 #define ULONG UINT 78 #endif 79 SHORT, USHORT, CHAR, UCHAR, 80 #ifdef ODD_TYPES 81 LLONG, SIZET, IMAX, UMAX, PDIFF, UIPTR, 82 #else 83 #define LLONG ULLONG 84 #define SIZET ULONG 85 #define IMAX LLONG 86 #define UMAX ULLONG 87 #define PDIFF LONG 88 #define UIPTR ULONG 89 #endif 90 DBL, LDBL, 91 NOARG, 92 MAXSTATE 93 }; 94 95 #define S(x) [(x)-'A'] 96 97 static const unsigned char states[]['z'-'A'+1] = { 98 { /* 0: bare types */ 99 S('d') = INT, S('i') = INT, 100 S('o') = UINT, S('u') = UINT, S('x') = UINT, S('X') = UINT, 101 S('e') = DBL, S('f') = DBL, S('g') = DBL, S('a') = DBL, 102 S('E') = DBL, S('F') = DBL, S('G') = DBL, S('A') = DBL, 103 S('c') = CHAR, S('C') = INT, 104 S('s') = PTR, S('S') = PTR, S('p') = UIPTR, S('n') = PTR, 105 S('m') = NOARG, 106 S('l') = LPRE, S('h') = HPRE, S('L') = BIGLPRE, 107 S('z') = ZTPRE, S('j') = JPRE, S('t') = ZTPRE, 108 }, { /* 1: l-prefixed */ 109 S('d') = LONG, S('i') = LONG, 110 S('o') = ULONG, S('u') = ULONG, S('x') = ULONG, S('X') = ULONG, 111 S('e') = DBL, S('f') = DBL, S('g') = DBL, S('a') = DBL, 112 S('E') = DBL, S('F') = DBL, S('G') = DBL, S('A') = DBL, 113 S('c') = INT, S('s') = PTR, S('n') = PTR, 114 S('l') = LLPRE, 115 }, { /* 2: ll-prefixed */ 116 S('d') = LLONG, S('i') = LLONG, 117 S('o') = ULLONG, S('u') = ULLONG, 118 S('x') = ULLONG, S('X') = ULLONG, 119 S('n') = PTR, 120 }, { /* 3: h-prefixed */ 121 S('d') = SHORT, S('i') = SHORT, 122 S('o') = USHORT, S('u') = USHORT, 123 S('x') = USHORT, S('X') = USHORT, 124 S('n') = PTR, 125 S('h') = HHPRE, 126 }, { /* 4: hh-prefixed */ 127 S('d') = CHAR, S('i') = CHAR, 128 S('o') = UCHAR, S('u') = UCHAR, 129 S('x') = UCHAR, S('X') = UCHAR, 130 S('n') = PTR, 131 }, { /* 5: L-prefixed */ 132 S('e') = LDBL, S('f') = LDBL, S('g') = LDBL, S('a') = LDBL, 133 S('E') = LDBL, S('F') = LDBL, S('G') = LDBL, S('A') = LDBL, 134 S('n') = PTR, 135 }, { /* 6: z- or t-prefixed (assumed to be same size) */ 136 S('d') = PDIFF, S('i') = PDIFF, 137 S('o') = SIZET, S('u') = SIZET, 138 S('x') = SIZET, S('X') = SIZET, 139 S('n') = PTR, 140 }, { /* 7: j-prefixed */ 141 S('d') = IMAX, S('i') = IMAX, 142 S('o') = UMAX, S('u') = UMAX, 143 S('x') = UMAX, S('X') = UMAX, 144 S('n') = PTR, 145 } 146 }; 147 148 #define OOB(x) ((unsigned)(x)-'A' > 'z'-'A') 149 150 union arg 151 { 152 uintmax_t i; 153 long double f; 154 void *p; 155 }; 156 157 static void pop_arg(union arg *arg, int type, va_list *ap) 158 { 159 /* Give the compiler a hint for optimizing the switch. */ 160 if ((unsigned)type > MAXSTATE) return; 161 switch (type) { 162 case PTR: arg->p = va_arg(*ap, void *); 163 break; case INT: arg->i = va_arg(*ap, int); 164 break; case UINT: arg->i = va_arg(*ap, unsigned int); 165 #ifndef LONG_IS_INT 166 break; case LONG: arg->i = va_arg(*ap, long); 167 break; case ULONG: arg->i = va_arg(*ap, unsigned long); 168 #endif 169 break; case ULLONG: arg->i = va_arg(*ap, unsigned long long); 170 break; case SHORT: arg->i = (short)va_arg(*ap, int); 171 break; case USHORT: arg->i = (unsigned short)va_arg(*ap, int); 172 break; case CHAR: arg->i = (signed char)va_arg(*ap, int); 173 break; case UCHAR: arg->i = (unsigned char)va_arg(*ap, int); 174 #ifdef ODD_TYPES 175 break; case LLONG: arg->i = va_arg(*ap, long long); 176 break; case SIZET: arg->i = va_arg(*ap, size_t); 177 break; case IMAX: arg->i = va_arg(*ap, intmax_t); 178 break; case UMAX: arg->i = va_arg(*ap, uintmax_t); 179 break; case PDIFF: arg->i = va_arg(*ap, ptrdiff_t); 180 break; case UIPTR: arg->i = (uintptr_t)va_arg(*ap, void *); 181 #endif 182 break; case DBL: arg->f = va_arg(*ap, double); 183 break; case LDBL: arg->f = va_arg(*ap, long double); 184 } 185 } 186 187 static void out(FILE *f, const char *s, size_t l) 188 { 189 #if defined(__ANDROID__) 190 fake_file_out(f, s, l); 191 #else 192 __fwritex((void *)s, l, f); 193 #endif 194 } 195 196 static void pad(FILE *f, char c, int w, int l, int fl) 197 { 198 char pad[256]; 199 if (fl & (LEFT_ADJ | ZERO_PAD) || l >= w) return; 200 l = w - l; 201 memset(pad, c, l>sizeof pad ? sizeof pad : l); 202 for (; l >= sizeof pad; l -= sizeof pad) 203 out(f, pad, sizeof pad); 204 out(f, pad, l); 205 } 206 207 static const char xdigits[16] = { 208 "0123456789ABCDEF" 209 }; 210 211 static char *fmt_x(uintmax_t x, char *s, int lower) 212 { 213 for (; x; x>>=4) *--s = xdigits[(x&15)]|lower; 214 return s; 215 } 216 217 static char *fmt_o(uintmax_t x, char *s) 218 { 219 for (; x; x>>=3) *--s = '0' + (x&7); 220 return s; 221 } 222 223 static char *fmt_u(uintmax_t x, char *s) 224 { 225 unsigned long y; 226 for ( ; x>ULONG_MAX; x/=10) *--s = '0' + x%10; 227 for (y=x; y; y/=10) *--s = '0' + y%10; 228 return s; 229 } 230 231 static int fmt_fp(FILE *f, long double y, int w, int p, int fl, int t) 232 { 233 uint32_t big[(LDBL_MAX_EXP+LDBL_MANT_DIG)/9+1]; 234 uint32_t *a, *d, *r, *z; 235 int e2=0, e, i, j, l; 236 char buf[9+LDBL_MANT_DIG/4], *s; 237 const char *prefix="-0X+0X 0X-0x+0x 0x"; 238 int pl; 239 char ebuf0[3*sizeof(int)], *ebuf=&ebuf0[3*sizeof(int)], *estr; 240 241 pl=1; 242 if (signbit(y)) { 243 y=-y; 244 } else if (fl & MARK_POS) { 245 prefix+=3; 246 } else if (fl & PAD_POS) { 247 prefix+=6; 248 } else prefix++, pl=0; 249 250 if (!isfinite(y)) { 251 char *s = (t&32)?"inf":"INF"; 252 if (y!=y) s=(t&32)?"nan":"NAN", pl=0; 253 pad(f, ' ', w, 3+pl, fl&~ZERO_PAD); 254 out(f, prefix, pl); 255 out(f, s, 3); 256 pad(f, ' ', w, 3+pl, fl^LEFT_ADJ); 257 return MAX(w, 3+pl); 258 } 259 260 y = frexpl(y, &e2) * 2; 261 if (y) e2--; 262 263 if ((t|32)=='a') { 264 long double round = 8.0; 265 int re; 266 267 if (t&32) prefix += 9; 268 pl += 2; 269 270 if (p<0 || p>=LDBL_MANT_DIG/4-1) re=0; 271 else re=LDBL_MANT_DIG/4-1-p; 272 273 if (re) { 274 while (re--) round*=16; 275 if (*prefix=='-') { 276 y=-y; 277 y-=round; 278 y+=round; 279 y=-y; 280 } else { 281 y+=round; 282 y-=round; 283 } 284 } 285 286 estr=fmt_u(e2<0 ? -e2 : e2, ebuf); 287 if (estr==ebuf) *--estr='0'; 288 *--estr = (e2<0 ? '-' : '+'); 289 *--estr = t+('p'-'a'); 290 291 s=buf; 292 do { 293 int x=y; 294 *s++=xdigits[x]|(t&32); 295 y=16*(y-x); 296 if (s-buf==1 && (y||p>0||(fl&ALT_FORM))) *s++='.'; 297 } while (y); 298 299 if (p && s-buf-2 < p) 300 l = (p+2) + (ebuf-estr); 301 else 302 l = (s-buf) + (ebuf-estr); 303 304 pad(f, ' ', w, pl+l, fl); 305 out(f, prefix, pl); 306 pad(f, '0', w, pl+l, fl^ZERO_PAD); 307 out(f, buf, s-buf); 308 pad(f, '0', l-(ebuf-estr)-(s-buf), 0, 0); 309 out(f, estr, ebuf-estr); 310 pad(f, ' ', w, pl+l, fl^LEFT_ADJ); 311 return MAX(w, pl+l); 312 } 313 if (p<0) p=6; 314 315 if (y) y *= 0x1p28, e2-=28; 316 317 if (e2<0) a=r=z=big; 318 else a=r=z=big+sizeof(big)/sizeof(*big) - LDBL_MANT_DIG - 1; 319 320 do { 321 *z = y; 322 y = 1000000000*(y-*z++); 323 } while (y); 324 325 while (e2>0) { 326 uint32_t carry=0; 327 int sh=MIN(29,e2); 328 for (d=z-1; d>=a; d--) { 329 uint64_t x = ((uint64_t)*d<<sh)+carry; 330 *d = x % 1000000000; 331 carry = x / 1000000000; 332 } 333 if (!z[-1] && z>a) z--; 334 if (carry) *--a = carry; 335 e2-=sh; 336 } 337 while (e2<0) { 338 uint32_t carry=0, *b; 339 int sh=MIN(9,-e2); 340 for (d=a; d<z; d++) { 341 uint32_t rm = *d & (1<<sh)-1; 342 *d = (*d>>sh) + carry; 343 carry = (1000000000>>sh) * rm; 344 } 345 if (!*a) a++; 346 if (carry) *z++ = carry; 347 /* Avoid (slow!) computation past requested precision */ 348 b = (t|32)=='f' ? r : a; 349 if (z-b > 2+p/9) z = b+2+p/9; 350 e2+=sh; 351 } 352 353 if (a<z) for (i=10, e=9*(r-a); *a>=i; i*=10, e++); 354 else e=0; 355 356 /* Perform rounding: j is precision after the radix (possibly neg) */ 357 j = p - ((t|32)!='f')*e - ((t|32)=='g' && p); 358 if (j < 9*(z-r-1)) { 359 uint32_t x; 360 /* We avoid C's broken division of negative numbers */ 361 d = r + 1 + ((j+9*LDBL_MAX_EXP)/9 - LDBL_MAX_EXP); 362 j += 9*LDBL_MAX_EXP; 363 j %= 9; 364 for (i=10, j++; j<9; i*=10, j++); 365 x = *d % i; 366 /* Are there any significant digits past j? */ 367 if (x || d+1!=z) { 368 long double round = CONCAT(0x1p,LDBL_MANT_DIG); 369 long double small; 370 if (*d/i & 1) round += 2; 371 if (x<i/2) small=0x0.8p0; 372 else if (x==i/2 && d+1==z) small=0x1.0p0; 373 else small=0x1.8p0; 374 if (pl && *prefix=='-') round*=-1, small*=-1; 375 *d -= x; 376 /* Decide whether to round by probing round+small */ 377 if (round+small != round) { 378 *d = *d + i; 379 while (*d > 999999999) { 380 *d--=0; 381 (*d)++; 382 } 383 if (d<a) a=d; 384 for (i=10, e=9*(r-a); *a>=i; i*=10, e++); 385 } 386 } 387 if (z>d+1) z=d+1; 388 for (; !z[-1] && z>a; z--); 389 } 390 391 if ((t|32)=='g') { 392 if (!p) p++; 393 if (p>e && e>=-4) { 394 t--; 395 p-=e+1; 396 } else { 397 t-=2; 398 p--; 399 } 400 if (!(fl&ALT_FORM)) { 401 /* Count trailing zeros in last place */ 402 if (z>a && z[-1]) for (i=10, j=0; z[-1]%i==0; i*=10, j++); 403 else j=9; 404 if ((t|32)=='f') 405 p = MIN(p,MAX(0,9*(z-r-1)-j)); 406 else 407 p = MIN(p,MAX(0,9*(z-r-1)+e-j)); 408 } 409 } 410 l = 1 + p + (p || (fl&ALT_FORM)); 411 if ((t|32)=='f') { 412 if (e>0) l+=e; 413 } else { 414 estr=fmt_u(e<0 ? -e : e, ebuf); 415 while(ebuf-estr<2) *--estr='0'; 416 *--estr = (e<0 ? '-' : '+'); 417 *--estr = t; 418 l += ebuf-estr; 419 } 420 421 pad(f, ' ', w, pl+l, fl); 422 out(f, prefix, pl); 423 pad(f, '0', w, pl+l, fl^ZERO_PAD); 424 425 if ((t|32)=='f') { 426 if (a>r) a=r; 427 for (d=a; d<=r; d++) { 428 char *s = fmt_u(*d, buf+9); 429 if (d!=a) while (s>buf) *--s='0'; 430 else if (s==buf+9) *--s='0'; 431 out(f, s, buf+9-s); 432 } 433 if (p || (fl&ALT_FORM)) out(f, ".", 1); 434 for (; d<z && p>0; d++, p-=9) { 435 char *s = fmt_u(*d, buf+9); 436 while (s>buf) *--s='0'; 437 out(f, s, MIN(9,p)); 438 } 439 pad(f, '0', p+9, 9, 0); 440 } else { 441 if (z<=a) z=a+1; 442 for (d=a; d<z && p>=0; d++) { 443 char *s = fmt_u(*d, buf+9); 444 if (s==buf+9) *--s='0'; 445 if (d!=a) while (s>buf) *--s='0'; 446 else { 447 out(f, s++, 1); 448 if (p>0||(fl&ALT_FORM)) out(f, ".", 1); 449 } 450 out(f, s, MIN(buf+9-s, p)); 451 p -= buf+9-s; 452 } 453 pad(f, '0', p+18, 18, 0); 454 out(f, estr, ebuf-estr); 455 } 456 457 pad(f, ' ', w, pl+l, fl^LEFT_ADJ); 458 459 return MAX(w, pl+l); 460 } 461 462 static int getint(char **s) { 463 int i; 464 for (i=0; isdigit(**s); (*s)++) 465 i = 10*i + (**s-'0'); 466 return i; 467 } 468 469 static int printf_core(FILE *f, const char *fmt, va_list *ap, union arg *nl_arg, int *nl_type) 470 { 471 char *a, *z, *s=(char *)fmt; 472 unsigned l10n=0, fl; 473 int w, p; 474 union arg arg; 475 int argpos; 476 unsigned st, ps; 477 int cnt=0, l=0; 478 int i; 479 char buf[sizeof(uintmax_t)*3+3+LDBL_MANT_DIG/4]; 480 const char *prefix; 481 int t, pl; 482 wchar_t wc[2], *ws; 483 char mb[4]; 484 485 for (;;) { 486 /* Update output count, end loop when fmt is exhausted */ 487 if (cnt >= 0) { 488 if (l > INT_MAX - cnt) { 489 errno = EOVERFLOW; 490 cnt = -1; 491 } else cnt += l; 492 } 493 if (!*s) break; 494 495 /* Handle literal text and %% format specifiers */ 496 for (a=s; *s && *s!='%'; s++); 497 for (z=s; s[0]=='%' && s[1]=='%'; z++, s+=2); 498 l = z-a; 499 if (f) out(f, a, l); 500 if (l) continue; 501 502 if (isdigit(s[1]) && s[2]=='$') { 503 l10n=1; 504 argpos = s[1]-'0'; 505 s+=3; 506 } else { 507 argpos = -1; 508 s++; 509 } 510 511 /* Read modifier flags */ 512 for (fl=0; (unsigned)*s-' '<32 && (FLAGMASK&(1U<<*s-' ')); s++) 513 fl |= 1U<<*s-' '; 514 515 /* Read field width */ 516 if (*s=='*') { 517 if (isdigit(s[1]) && s[2]=='$') { 518 l10n=1; 519 nl_type[s[1]-'0'] = INT; 520 w = nl_arg[s[1]-'0'].i; 521 s+=3; 522 } else if (!l10n) { 523 w = f ? va_arg(*ap, int) : 0; 524 s++; 525 } else return -1; 526 if (w<0) fl|=LEFT_ADJ, w=-w; 527 } else if ((w=getint(&s))<0) return -1; 528 529 /* Read precision */ 530 if (*s=='.' && s[1]=='*') { 531 if (isdigit(s[2]) && s[3]=='$') { 532 nl_type[s[2]-'0'] = INT; 533 p = nl_arg[s[2]-'0'].i; 534 s+=4; 535 } else if (!l10n) { 536 p = f ? va_arg(*ap, int) : 0; 537 s+=2; 538 } else return -1; 539 } else if (*s=='.') { 540 s++; 541 p = getint(&s); 542 } else p = -1; 543 544 /* Format specifier state machine */ 545 st=0; 546 do { 547 if (OOB(*s)) return -1; 548 ps=st; 549 st=states[st]S(*s++); 550 } while (st-1<STOP); 551 if (!st) return -1; 552 553 /* Check validity of argument type (nl/normal) */ 554 if (st==NOARG) { 555 if (argpos>=0) return -1; 556 else if (!f) continue; 557 } else { 558 if (argpos>=0) nl_type[argpos]=st, arg=nl_arg[argpos]; 559 else if (f) pop_arg(&arg, st, ap); 560 else return 0; 561 } 562 563 if (!f) continue; 564 565 z = buf + sizeof(buf); 566 prefix = "-+ 0X0x"; 567 pl = 0; 568 t = s[-1]; 569 570 /* Transform ls,lc -> S,C */ 571 if (ps && (t&15)==3) t&=~32; 572 573 /* - and 0 flags are mutually exclusive */ 574 if (fl & LEFT_ADJ) fl &= ~ZERO_PAD; 575 576 switch(t) { 577 case 'n': 578 #ifndef __ANDROID__ /* Disabled on Android for security reasons. */ 579 switch(ps) { 580 case BARE: *(int *)arg.p = cnt; break; 581 case LPRE: *(long *)arg.p = cnt; break; 582 case LLPRE: *(long long *)arg.p = cnt; break; 583 case HPRE: *(unsigned short *)arg.p = cnt; break; 584 case HHPRE: *(unsigned char *)arg.p = cnt; break; 585 case ZTPRE: *(size_t *)arg.p = cnt; break; 586 case JPRE: *(uintmax_t *)arg.p = cnt; break; 587 } 588 #endif /* !__ANDROID__ */ 589 continue; 590 case 'p': 591 p = MAX(p, 2*sizeof(void*)); 592 t = 'x'; 593 fl |= ALT_FORM; 594 case 'x': case 'X': 595 a = fmt_x(arg.i, z, t&32); 596 if (arg.i && (fl & ALT_FORM)) prefix+=(t>>4), pl=2; 597 if (0) { 598 case 'o': 599 a = fmt_o(arg.i, z); 600 if ((fl&ALT_FORM) && arg.i) prefix+=5, pl=1; 601 } if (0) { 602 case 'd': case 'i': 603 pl=1; 604 if (arg.i>INTMAX_MAX) { 605 arg.i=-arg.i; 606 } else if (fl & MARK_POS) { 607 prefix++; 608 } else if (fl & PAD_POS) { 609 prefix+=2; 610 } else pl=0; 611 case 'u': 612 a = fmt_u(arg.i, z); 613 } 614 if (p>=0) fl &= ~ZERO_PAD; 615 if (!arg.i && !p) { 616 a=z; 617 break; 618 } 619 p = MAX(p, z-a + !arg.i); 620 break; 621 case 'c': 622 *(a=z-(p=1))=arg.i; 623 fl &= ~ZERO_PAD; 624 break; 625 case 'm': 626 if (1) a = strerror(errno); else 627 case 's': 628 a = arg.p ? arg.p : "(null)"; 629 #if defined(__ANDROID__) 630 /* On Android, memchr() will return NULL for 631 * out-of-bound requests, e.g. if |p == -1|. */ 632 if (p >= 0) { 633 z = memchr(a, 0, p); 634 if (!z) z=a+p; 635 else p=z-a; 636 } else { 637 p=strlen(a); 638 z=a+p; 639 } 640 #else /* !__ANDROID__ */ 641 if (!z) z=a+p; 642 else p=z-a; 643 #endif /* !__ANDROID__ */ 644 fl &= ~ZERO_PAD; 645 break; 646 case 'C': 647 wc[0] = arg.i; 648 wc[1] = 0; 649 arg.p = wc; 650 p = -1; 651 case 'S': 652 ws = arg.p; 653 for (i=l=0; i<0U+p && *ws && (l=wctomb(mb, *ws++))>=0 && l<=0U+p-i; i+=l); 654 if (l<0) return -1; 655 p = i; 656 pad(f, ' ', w, p, fl); 657 ws = arg.p; 658 for (i=0; i<0U+p && *ws && i+(l=wctomb(mb, *ws++))<=p; i+=l) 659 out(f, mb, l); 660 pad(f, ' ', w, p, fl^LEFT_ADJ); 661 l = w>p ? w : p; 662 continue; 663 case 'e': case 'f': case 'g': case 'a': 664 case 'E': case 'F': case 'G': case 'A': 665 l = fmt_fp(f, arg.f, w, p, fl, t); 666 continue; 667 } 668 669 if (p < z-a) p = z-a; 670 if (w < pl+p) w = pl+p; 671 672 pad(f, ' ', w, pl+p, fl); 673 out(f, prefix, pl); 674 pad(f, '0', w, pl+p, fl^ZERO_PAD); 675 pad(f, '0', p, z-a, 0); 676 out(f, a, z-a); 677 pad(f, ' ', w, pl+p, fl^LEFT_ADJ); 678 679 l = w; 680 } 681 682 if (f) return cnt; 683 if (!l10n) return 0; 684 685 for (i=1; i<=NL_ARGMAX && nl_type[i]; i++) 686 pop_arg(nl_arg+i, nl_type[i], ap); 687 for (; i<=NL_ARGMAX && !nl_type[i]; i++); 688 if (i<=NL_ARGMAX) return -1; 689 return 1; 690 } 691 692 #ifdef __ANDROID__ 693 #undef FILE /* no longer needed */ 694 695 int vfprintf(FILE *restrict f, const char *restrict fmt, va_list ap) 696 { 697 va_list ap2; 698 int nl_type[NL_ARGMAX+1] = {0}; 699 union arg nl_arg[NL_ARGMAX+1]; 700 int ret; 701 FakeFILE out[1]; 702 fake_file_init_file(out, f); 703 704 va_copy(ap2, ap); 705 ret = printf_core(0, fmt, &ap2, nl_arg, nl_type); 706 va_end(ap2); 707 if (ret < 0) 708 return -1; 709 710 va_copy(ap2, ap); 711 ret = printf_core(out, fmt, &ap2, nl_arg, nl_type); 712 va_end(ap2); 713 return ret; 714 } 715 716 int vsnprintf(char *restrict s, size_t n, const char *restrict fmt, va_list ap) 717 { 718 va_list ap2; 719 int nl_type[NL_ARGMAX+1] = {0}; 720 union arg nl_arg[NL_ARGMAX+1]; 721 int r; 722 char b; 723 FakeFILE out[1]; 724 725 if (n-1 > INT_MAX-1) { 726 if (n) { 727 errno = EOVERFLOW; 728 return -1; 729 } 730 s = &b; 731 n = 1; 732 } 733 734 /* Ensure pointers don't wrap if "infinite" n is passed in */ 735 if (n > (char *)0+SIZE_MAX-s-1) n = (char *)0+SIZE_MAX-s-1; 736 fake_file_init_buffer(out, s, n); 737 738 va_copy(ap2, ap); 739 r = printf_core(out, fmt, &ap2, nl_arg, nl_type); 740 va_end(ap2); 741 742 if (r < n) 743 s[r] = '\0'; 744 else 745 s[n - 1] = '\0'; 746 747 return r; 748 } 749 750 #else /* !__ANDROID__ */ 751 int vfprintf(FILE *restrict f, const char *restrict fmt, va_list ap) 752 { 753 va_list ap2; 754 int nl_type[NL_ARGMAX+1] = {0}; 755 union arg nl_arg[NL_ARGMAX+1]; 756 unsigned char internal_buf[80], *saved_buf = 0; 757 int ret; 758 759 va_copy(ap2, ap); 760 if (printf_core(0, fmt, &ap2, nl_arg, nl_type) < 0) return -1; 761 762 FLOCK(f); 763 if (!f->buf_size) { 764 saved_buf = f->buf; 765 f->wpos = f->wbase = f->buf = internal_buf; 766 f->buf_size = sizeof internal_buf; 767 f->wend = internal_buf + sizeof internal_buf; 768 } 769 ret = printf_core(f, fmt, &ap2, nl_arg, nl_type); 770 if (saved_buf) { 771 f->write(f, 0, 0); 772 if (!f->wpos) ret = -1; 773 f->buf = saved_buf; 774 f->buf_size = 0; 775 f->wpos = f->wbase = f->wend = 0; 776 } 777 FUNLOCK(f); 778 va_end(ap2); 779 return ret; 780 } 781 #endif /* !__ANDROID__ */ 782