mutt stable branch with some hacks
at jcs 824 lines 19 kB view raw
1/************************************************************** 2 * Original: 3 * Patrick Powell Tue Apr 11 09:48:21 PDT 1995 4 * A bombproof version of doprnt (dopr) included. 5 * Sigh. This sort of thing is always nasty do deal with. Note that 6 * the version here does not include floating point... 7 * 8 * snprintf() is used instead of sprintf() as it does limit checks 9 * for string length. This covers a nasty loophole. 10 * 11 * The other functions are there to prevent NULL pointers from 12 * causing nast effects. 13 * 14 * More Recently: 15 * Brandon Long <blong@fiction.net> 9/15/96 for mutt 0.43 16 * This was ugly. It is still ugly. I opted out of floating point 17 * numbers, but the formatter understands just about everything 18 * from the normal C string format, at least as far as I can tell from 19 * the Solaris 2.5 printf(3S) man page. 20 * 21 * Brandon Long <blong@fiction.net> 10/22/97 for mutt 0.87.1 22 * Ok, added some minimal floating point support, which means this 23 * probably requires libm on most operating systems. Don't yet 24 * support the exponent (e,E) and sigfig (g,G). Also, fmtint() 25 * was pretty badly broken, it just wasn't being exercised in ways 26 * which showed it, so that's been fixed. Also, formatted the code 27 * to mutt conventions, and removed dead code left over from the 28 * original. Also, there is now a builtin-test, just compile with: 29 * gcc -DTEST_SNPRINTF -o snprintf snprintf.c -lm 30 * and run snprintf for results. 31 * 32 * Thomas Roessler <roessler@does-not-exist.org> 01/27/98 for mutt 0.89i 33 * The PGP code was using unsigned hexadecimal formats. 34 * Unfortunately, unsigned formats simply didn't work. 35 * 36 * Michael Elkins <me@mutt.org> 03/05/98 for mutt 0.90.8 37 * The original code assumed that both snprintf() and vsnprintf() were 38 * missing. Some systems only have snprintf() but not vsnprintf(), so 39 * the code is now broken down under HAVE_SNPRINTF and HAVE_VSNPRINTF. 40 * 41 * Holger Weiss <holger@zedat.fu-berlin.de> 07/23/06 for mutt 1.5.13 42 * A C99 compliant [v]snprintf() returns the number of characters that 43 * would have been written to a sufficiently sized buffer (excluding 44 * the '\0'). Mutt now relies on this behavior, but the original 45 * code simply returned the length of the resulting output string, so 46 * that's been fixed. 47 * 48 **************************************************************/ 49 50#if HAVE_CONFIG_H 51# include "config.h" 52#endif 53 54#if !defined(HAVE_SNPRINTF) || !defined(HAVE_VSNPRINTF) 55 56#include <string.h> 57# include <ctype.h> 58#include <sys/types.h> 59 60/* Define this as a fall through, HAVE_STDARG_H is probably already set */ 61 62#define HAVE_VARARGS_H 63 64/* varargs declarations: */ 65 66#if defined(HAVE_STDARG_H) 67# include <stdarg.h> 68# define HAVE_STDARGS /* let's hope that works everywhere (mj) */ 69# define VA_LOCAL_DECL va_list ap 70# define VA_START(f) va_start(ap, f) 71# define VA_SHIFT(v,t) ; /* no-op for ANSI */ 72# define VA_END va_end(ap) 73#else 74# if defined(HAVE_VARARGS_H) 75# include <varargs.h> 76# undef HAVE_STDARGS 77# define VA_LOCAL_DECL va_list ap 78# define VA_START(f) va_start(ap) /* f is ignored! */ 79# define VA_SHIFT(v,t) v = va_arg(ap,t) 80# define VA_END va_end(ap) 81# else 82/*XX ** NO VARARGS ** XX*/ 83# endif 84#endif 85 86/*int snprintf (char *str, size_t count, const char *fmt, ...);*/ 87/*int vsnprintf (char *str, size_t count, const char *fmt, va_list arg);*/ 88 89static int dopr (char *buffer, size_t maxlen, const char *format, 90 va_list args); 91static void fmtstr (char *buffer, size_t *currlen, size_t maxlen, 92 char *value, int flags, int min, int max); 93static void fmtint (char *buffer, size_t *currlen, size_t maxlen, 94 long value, int base, int min, int max, int flags); 95static void fmtfp (char *buffer, size_t *currlen, size_t maxlen, 96 long double fvalue, int min, int max, int flags); 97static void dopr_outch (char *buffer, size_t *currlen, size_t maxlen, char c ); 98 99/* 100 * dopr(): poor man's version of doprintf 101 */ 102 103/* format read states */ 104#define DP_S_DEFAULT 0 105#define DP_S_FLAGS 1 106#define DP_S_MIN 2 107#define DP_S_DOT 3 108#define DP_S_MAX 4 109#define DP_S_MOD 5 110#define DP_S_CONV 6 111#define DP_S_DONE 7 112 113/* format flags - Bits */ 114#define DP_F_MINUS (1 << 0) 115#define DP_F_PLUS (1 << 1) 116#define DP_F_SPACE (1 << 2) 117#define DP_F_NUM (1 << 3) 118#define DP_F_ZERO (1 << 4) 119#define DP_F_UP (1 << 5) 120#define DP_F_UNSIGNED (1 << 6) 121 122/* Conversion Flags */ 123#define DP_C_SHORT 1 124#define DP_C_LONG 2 125#define DP_C_LONGLONG 3 126#define DP_C_LDOUBLE 4 127 128#define char_to_int(p) (p - '0') 129#undef MAX 130#define MAX(p,q) ((p >= q) ? p : q) 131 132static int dopr (char *buffer, size_t maxlen, const char *format, va_list args) 133{ 134 char ch; 135 long value; 136 long double fvalue; 137 char *strvalue; 138 int min; 139 int max; 140 int state; 141 int flags; 142 int cflags; 143 size_t currlen; 144 145 state = DP_S_DEFAULT; 146 currlen = flags = cflags = min = 0; 147 max = -1; 148 ch = *format++; 149 150 while (state != DP_S_DONE) 151 { 152 if (ch == '\0') 153 state = DP_S_DONE; 154 155 switch (state) 156 { 157 case DP_S_DEFAULT: 158 if (ch == '%') 159 state = DP_S_FLAGS; 160 else 161 dopr_outch (buffer, &currlen, maxlen, ch); 162 ch = *format++; 163 break; 164 case DP_S_FLAGS: 165 switch (ch) 166 { 167 case '-': 168 flags |= DP_F_MINUS; 169 ch = *format++; 170 break; 171 case '+': 172 flags |= DP_F_PLUS; 173 ch = *format++; 174 break; 175 case ' ': 176 flags |= DP_F_SPACE; 177 ch = *format++; 178 break; 179 case '#': 180 flags |= DP_F_NUM; 181 ch = *format++; 182 break; 183 case '0': 184 flags |= DP_F_ZERO; 185 ch = *format++; 186 break; 187 default: 188 state = DP_S_MIN; 189 break; 190 } 191 break; 192 case DP_S_MIN: 193 if (isdigit((unsigned char)ch)) 194 { 195 min = 10*min + char_to_int (ch); 196 ch = *format++; 197 } 198 else if (ch == '*') 199 { 200 min = va_arg (args, int); 201 ch = *format++; 202 state = DP_S_DOT; 203 } 204 else 205 state = DP_S_DOT; 206 break; 207 case DP_S_DOT: 208 if (ch == '.') 209 { 210 state = DP_S_MAX; 211 ch = *format++; 212 } 213 else 214 state = DP_S_MOD; 215 break; 216 case DP_S_MAX: 217 if (isdigit((unsigned char)ch)) 218 { 219 if (max < 0) 220 max = 0; 221 max = 10*max + char_to_int (ch); 222 ch = *format++; 223 } 224 else if (ch == '*') 225 { 226 max = va_arg (args, int); 227 ch = *format++; 228 state = DP_S_MOD; 229 } 230 else 231 state = DP_S_MOD; 232 break; 233 case DP_S_MOD: 234 switch (ch) 235 { 236 case 'h': 237 cflags = DP_C_SHORT; 238 ch = *format++; 239 break; 240 case 'l': 241 cflags = DP_C_LONG; 242 ch = *format++; 243 if (ch == 'l') 244 { 245 cflags = DP_C_LONGLONG; 246 ch = *format++; 247 } 248 break; 249 case 'L': 250 cflags = DP_C_LDOUBLE; 251 ch = *format++; 252 break; 253 default: 254 break; 255 } 256 state = DP_S_CONV; 257 break; 258 case DP_S_CONV: 259 switch (ch) 260 { 261 case 'd': 262 case 'i': 263 if (cflags == DP_C_SHORT) 264 value = va_arg (args, short int); 265 else if (cflags == DP_C_LONG) 266 value = va_arg (args, long int); 267 else if (cflags == DP_C_LONGLONG) 268 value = va_arg (args, long long int); 269 else 270 value = va_arg (args, int); 271 fmtint (buffer, &currlen, maxlen, value, 10, min, max, flags); 272 break; 273 case 'o': 274 flags |= DP_F_UNSIGNED; 275 if (cflags == DP_C_SHORT) 276 value = va_arg (args, unsigned short int); 277 else if (cflags == DP_C_LONG) 278 value = va_arg (args, unsigned long int); 279 else if (cflags == DP_C_LONGLONG) 280 value = va_arg (args, unsigned long long int); 281 else 282 value = va_arg (args, unsigned int); 283 fmtint (buffer, &currlen, maxlen, value, 8, min, max, flags); 284 break; 285 case 'u': 286 flags |= DP_F_UNSIGNED; 287 if (cflags == DP_C_SHORT) 288 value = va_arg (args, unsigned short int); 289 else if (cflags == DP_C_LONG) 290 value = va_arg (args, unsigned long int); 291 else if (cflags == DP_C_LONGLONG) 292 value = va_arg (args, unsigned long long int); 293 else 294 value = va_arg (args, unsigned int); 295 fmtint (buffer, &currlen, maxlen, value, 10, min, max, flags); 296 break; 297 case 'X': 298 flags |= DP_F_UP; 299 case 'x': 300 flags |= DP_F_UNSIGNED; 301 if (cflags == DP_C_SHORT) 302 value = va_arg (args, unsigned short int); 303 else if (cflags == DP_C_LONG) 304 value = va_arg (args, unsigned long int); 305 else if (cflags == DP_C_LONGLONG) 306 value = va_arg (args, unsigned long long int); 307 else 308 value = va_arg (args, unsigned int); 309 fmtint (buffer, &currlen, maxlen, value, 16, min, max, flags); 310 break; 311 case 'f': 312 if (cflags == DP_C_LDOUBLE) 313 fvalue = va_arg (args, long double); 314 else 315 fvalue = va_arg (args, double); 316 /* um, floating point? */ 317 fmtfp (buffer, &currlen, maxlen, fvalue, min, max, flags); 318 break; 319 case 'E': 320 flags |= DP_F_UP; 321 case 'e': 322 if (cflags == DP_C_LDOUBLE) 323 fvalue = va_arg (args, long double); 324 else 325 fvalue = va_arg (args, double); 326 break; 327 case 'G': 328 flags |= DP_F_UP; 329 case 'g': 330 if (cflags == DP_C_LDOUBLE) 331 fvalue = va_arg (args, long double); 332 else 333 fvalue = va_arg (args, double); 334 break; 335 case 'c': 336 dopr_outch (buffer, &currlen, maxlen, va_arg (args, int)); 337 break; 338 case 's': 339 strvalue = va_arg (args, char *); 340 fmtstr (buffer, &currlen, maxlen, strvalue, flags, min, max); 341 break; 342 case 'p': 343 flags |= DP_F_UNSIGNED; 344 strvalue = va_arg (args, void *); 345 fmtint (buffer, &currlen, maxlen, (long) strvalue, 16, min, max, flags); 346 break; 347 case 'n': 348 if (cflags == DP_C_SHORT) 349 { 350 short int *num; 351 num = va_arg (args, short int *); 352 *num = currlen; 353 } 354 else if (cflags == DP_C_LONG) 355 { 356 long int *num; 357 num = va_arg (args, long int *); 358 *num = currlen; 359 } 360 else if (cflags == DP_C_LONGLONG) 361 { 362 long long int *num; 363 num = va_arg (args, long long int *); 364 *num = currlen; 365 } 366 else 367 { 368 int *num; 369 num = va_arg (args, int *); 370 *num = currlen; 371 } 372 break; 373 case '%': 374 dopr_outch (buffer, &currlen, maxlen, ch); 375 break; 376 case 'w': 377 /* not supported yet, treat as next char */ 378 ch = *format++; 379 break; 380 default: 381 /* Unknown, skip */ 382 break; 383 } 384 ch = *format++; 385 state = DP_S_DEFAULT; 386 flags = cflags = min = 0; 387 max = -1; 388 break; 389 case DP_S_DONE: 390 break; 391 default: 392 /* hmm? */ 393 break; /* some picky compilers need this */ 394 } 395 } 396 if (currlen < maxlen - 1) 397 buffer[currlen] = '\0'; 398 else 399 buffer[maxlen - 1] = '\0'; 400 401 return (int)currlen; 402} 403 404static void fmtstr (char *buffer, size_t *currlen, size_t maxlen, 405 char *value, int flags, int min, int max) 406{ 407 int padlen, strln; /* amount to pad */ 408 int cnt = 0; 409 410 if (!value) 411 { 412 value = "<NULL>"; 413 } 414 415 for (strln = 0; value[strln]; ++strln); /* strlen */ 416 padlen = min - strln; 417 if (padlen < 0) 418 padlen = 0; 419 if (flags & DP_F_MINUS) 420 padlen = -padlen; /* Left Justify */ 421 422 while ((padlen > 0) && (max == -1 || cnt < max)) 423 { 424 dopr_outch (buffer, currlen, maxlen, ' '); 425 --padlen; 426 ++cnt; 427 } 428 while (*value && (max == -1 || cnt < max)) 429 { 430 dopr_outch (buffer, currlen, maxlen, *value++); 431 ++cnt; 432 } 433 while ((padlen < 0) && (max == -1 || cnt < max)) 434 { 435 dopr_outch (buffer, currlen, maxlen, ' '); 436 ++padlen; 437 ++cnt; 438 } 439} 440 441/* Have to handle DP_F_NUM (ie 0x and 0 alternates) */ 442 443static void fmtint (char *buffer, size_t *currlen, size_t maxlen, 444 long value, int base, int min, int max, int flags) 445{ 446 int signvalue = 0; 447 unsigned long uvalue; 448 char convert[20]; 449 int place = 0; 450 int spadlen = 0; /* amount to space pad */ 451 int zpadlen = 0; /* amount to zero pad */ 452 int caps = 0; 453 454 if (max < 0) 455 max = 0; 456 457 uvalue = value; 458 459 if (!(flags & DP_F_UNSIGNED)) 460 { 461 if ( value < 0 ) 462 { 463 signvalue = '-'; 464 uvalue = -value; 465 } 466 else 467 if (flags & DP_F_PLUS) /* Do a sign (+/i) */ 468 signvalue = '+'; 469 else 470 if (flags & DP_F_SPACE) 471 signvalue = ' '; 472 } 473 474 if (flags & DP_F_UP) caps = 1; /* Should characters be upper case? */ 475 476 do 477 { 478 convert[place++] = 479 (caps? "0123456789ABCDEF":"0123456789abcdef") 480 [uvalue % (unsigned)base ]; 481 uvalue = (uvalue / (unsigned)base ); 482 } while (uvalue && (place < 20)); 483 if (place == 20) place--; 484 convert[place] = 0; 485 486 zpadlen = max - place; 487 spadlen = min - MAX (max, place) - (signvalue ? 1 : 0); 488 if (zpadlen < 0) zpadlen = 0; 489 if (spadlen < 0) spadlen = 0; 490 if (flags & DP_F_ZERO) 491 { 492 zpadlen = MAX(zpadlen, spadlen); 493 spadlen = 0; 494 } 495 if (flags & DP_F_MINUS) 496 spadlen = -spadlen; /* Left Justifty */ 497 498#ifdef DEBUG_SNPRINTF 499 dprint (1, (debugfile, "zpad: %d, spad: %d, min: %d, max: %d, place: %d\n", 500 zpadlen, spadlen, min, max, place)); 501#endif 502 503 /* Spaces */ 504 while (spadlen > 0) 505 { 506 dopr_outch (buffer, currlen, maxlen, ' '); 507 --spadlen; 508 } 509 510 /* Sign */ 511 if (signvalue) 512 dopr_outch (buffer, currlen, maxlen, signvalue); 513 514 /* Zeros */ 515 if (zpadlen > 0) 516 { 517 while (zpadlen > 0) 518 { 519 dopr_outch (buffer, currlen, maxlen, '0'); 520 --zpadlen; 521 } 522 } 523 524 /* Digits */ 525 while (place > 0) 526 dopr_outch (buffer, currlen, maxlen, convert[--place]); 527 528 /* Left Justified spaces */ 529 while (spadlen < 0) 530 { 531 dopr_outch (buffer, currlen, maxlen, ' '); 532 ++spadlen; 533 } 534} 535 536static long double abs_val (long double value) 537{ 538 long double result = value; 539 540 if (value < 0) 541 result = -value; 542 543 return result; 544} 545 546static long double pow10 (int exp) 547{ 548 long double result = 1; 549 550 while (exp) 551 { 552 result *= 10; 553 exp--; 554 } 555 556 return result; 557} 558 559static long round (long double value) 560{ 561 long intpart; 562 563 intpart = value; 564 value = value - intpart; 565 if (value >= 0.5) 566 intpart++; 567 568 return intpart; 569} 570 571static void fmtfp (char *buffer, size_t *currlen, size_t maxlen, 572 long double fvalue, int min, int max, int flags) 573{ 574 int signvalue = 0; 575 long double ufvalue; 576 char iconvert[20]; 577 char fconvert[20]; 578 int iplace = 0; 579 int fplace = 0; 580 int padlen = 0; /* amount to pad */ 581 int zpadlen = 0; 582 int caps = 0; 583 long intpart; 584 long fracpart; 585 586 /* 587 * AIX manpage says the default is 0, but Solaris says the default 588 * is 6, and sprintf on AIX defaults to 6 589 */ 590 if (max < 0) 591 max = 6; 592 593 ufvalue = abs_val (fvalue); 594 595 if (fvalue < 0) 596 signvalue = '-'; 597 else 598 if (flags & DP_F_PLUS) /* Do a sign (+/i) */ 599 signvalue = '+'; 600 else 601 if (flags & DP_F_SPACE) 602 signvalue = ' '; 603 604#if 0 605 if (flags & DP_F_UP) caps = 1; /* Should characters be upper case? */ 606#endif 607 608 intpart = ufvalue; 609 610 /* 611 * Sorry, we only support 9 digits past the decimal because of our 612 * conversion method 613 */ 614 if (max > 9) 615 max = 9; 616 617 /* We "cheat" by converting the fractional part to integer by 618 * multiplying by a factor of 10 619 */ 620 fracpart = round ((pow10 (max)) * (ufvalue - intpart)); 621 622 if (fracpart >= pow10 (max)) 623 { 624 intpart++; 625 fracpart -= pow10 (max); 626 } 627 628#ifdef DEBUG_SNPRINTF 629 dprint (1, (debugfile, "fmtfp: %f =? %d.%d\n", fvalue, intpart, fracpart)); 630#endif 631 632 /* Convert integer part */ 633 do 634 { 635 iconvert[iplace++] = 636 (caps? "0123456789ABCDEF":"0123456789abcdef")[intpart % 10]; 637 intpart = (intpart / 10); 638 } while (intpart && (iplace < 20)); 639 if (iplace == 20) iplace--; 640 iconvert[iplace] = 0; 641 642 /* Convert fractional part */ 643 do 644 { 645 fconvert[fplace++] = 646 (caps? "0123456789ABCDEF":"0123456789abcdef")[fracpart % 10]; 647 fracpart = (fracpart / 10); 648 } while (fracpart && (fplace < 20)); 649 if (fplace == 20) fplace--; 650 fconvert[fplace] = 0; 651 652 /* -1 for decimal point, another -1 if we are printing a sign */ 653 padlen = min - iplace - max - 1 - ((signvalue) ? 1 : 0); 654 zpadlen = max - fplace; 655 if (zpadlen < 0) 656 zpadlen = 0; 657 if (padlen < 0) 658 padlen = 0; 659 if (flags & DP_F_MINUS) 660 padlen = -padlen; /* Left Justifty */ 661 662 if ((flags & DP_F_ZERO) && (padlen > 0)) 663 { 664 if (signvalue) 665 { 666 dopr_outch (buffer, currlen, maxlen, signvalue); 667 --padlen; 668 signvalue = 0; 669 } 670 while (padlen > 0) 671 { 672 dopr_outch (buffer, currlen, maxlen, '0'); 673 --padlen; 674 } 675 } 676 while (padlen > 0) 677 { 678 dopr_outch (buffer, currlen, maxlen, ' '); 679 --padlen; 680 } 681 if (signvalue) 682 dopr_outch (buffer, currlen, maxlen, signvalue); 683 684 while (iplace > 0) 685 dopr_outch (buffer, currlen, maxlen, iconvert[--iplace]); 686 687 /* 688 * Decimal point. This should probably use locale to find the correct 689 * char to print out. 690 */ 691 dopr_outch (buffer, currlen, maxlen, '.'); 692 693 while (fplace > 0) 694 dopr_outch (buffer, currlen, maxlen, fconvert[--fplace]); 695 696 while (zpadlen > 0) 697 { 698 dopr_outch (buffer, currlen, maxlen, '0'); 699 --zpadlen; 700 } 701 702 while (padlen < 0) 703 { 704 dopr_outch (buffer, currlen, maxlen, ' '); 705 ++padlen; 706 } 707} 708 709static void dopr_outch (char *buffer, size_t *currlen, size_t maxlen, char c) 710{ 711 if (*currlen < maxlen) 712 buffer[*currlen] = c; 713 (*currlen)++; 714} 715#endif /* !defined(HAVE_SNPRINTF) || !defined(HAVE_VSNPRINTF) */ 716 717#ifndef HAVE_VSNPRINTF 718int vsnprintf (char *str, size_t count, const char *fmt, va_list args) 719{ 720 str[0] = 0; 721 return(dopr(str, count, fmt, args)); 722} 723#endif /* !HAVE_VSNPRINTF */ 724 725#ifndef HAVE_SNPRINTF 726/* VARARGS3 */ 727#ifdef HAVE_STDARGS 728int snprintf (char *str,size_t count,const char *fmt,...) 729#else 730int snprintf (va_alist) va_dcl 731#endif 732{ 733#ifndef HAVE_STDARGS 734 char *str; 735 size_t count; 736 char *fmt; 737#endif 738 int len; 739 VA_LOCAL_DECL; 740 741 VA_START (fmt); 742 VA_SHIFT (str, char *); 743 VA_SHIFT (count, size_t ); 744 VA_SHIFT (fmt, char *); 745 len = vsnprintf(str, count, fmt, ap); 746 VA_END; 747 return(len); 748} 749 750#ifdef TEST_SNPRINTF 751#ifndef LONG_STRING 752#define LONG_STRING 1024 753#endif 754int main (void) 755{ 756 char buf1[LONG_STRING]; 757 char buf2[LONG_STRING]; 758 char *fp_fmt[] = { 759 "%-1.5f", 760 "%1.5f", 761 "%123.9f", 762 "%10.5f", 763 "% 10.5f", 764 "%+22.9f", 765 "%+4.9f", 766 "%01.3f", 767 "%4f", 768 "%3.1f", 769 "%3.2f", 770 NULL 771 }; 772 double fp_nums[] = { -1.5, 134.21, 91340.2, 341.1234, 0203.9, 0.96, 0.996, 773 0.9996, 1.996, 4.136, 0}; 774 char *int_fmt[] = { 775 "%-1.5d", 776 "%1.5d", 777 "%123.9d", 778 "%5.5d", 779 "%10.5d", 780 "% 10.5d", 781 "%+22.33d", 782 "%01.3d", 783 "%4d", 784 NULL 785 }; 786 long int_nums[] = { -1, 134, 91340, 341, 0203, 0}; 787 int x, y; 788 int fail = 0; 789 int num = 0; 790 791 printf ("Testing snprintf format codes against system sprintf...\n"); 792 793 for (x = 0; fp_fmt[x] != NULL ; x++) 794 for (y = 0; fp_nums[y] != 0 ; y++) 795 { 796 snprintf (buf1, sizeof (buf1), fp_fmt[x], fp_nums[y]); 797 sprintf (buf2, fp_fmt[x], fp_nums[y]); 798 if (strcmp (buf1, buf2)) 799 { 800 printf("snprintf doesn't match Format: %s\n\tsnprintf = %s\n\tsprintf = %s\n", /* __SPRINTF_CHECKED__ */ 801 fp_fmt[x], buf1, buf2); 802 fail++; 803 } 804 num++; 805 } 806 807 for (x = 0; int_fmt[x] != NULL ; x++) 808 for (y = 0; int_nums[y] != 0 ; y++) 809 { 810 snprintf (buf1, sizeof (buf1), int_fmt[x], int_nums[y]); 811 sprintf (buf2, int_fmt[x], int_nums[y]); 812 if (strcmp (buf1, buf2)) 813 { 814 printf("snprintf doesn't match Format: %s\n\tsnprintf = %s\n\tsprintf = %s\n", /* __SPRINTF_CHECKED__ */ 815 int_fmt[x], buf1, buf2); 816 fail++; 817 } 818 num++; 819 } 820 printf ("%d tests failed out of %d.\n", fail, num); 821} 822#endif /* SNPRINTF_TEST */ 823 824#endif /* !HAVE_SNPRINTF */