3 /* _PDCLIB_print( const char *, struct _PDCLIB_status_t * )
5 This file is part of the Public Domain C Library (PDCLib).
6 Permission is granted to use, modify, and / or redistribute at will.
15 /* Using an integer's bits as flags for both the conversion flags and length
28 #define E_intmax 1<<10
30 #define E_ptrdiff 1<<12
31 #define E_intptr 1<<13
32 #define E_ldouble 1<<14
34 #define E_unsigned 1<<16
36 /* This macro delivers a given character to either a memory buffer or a stream,
37 depending on the contents of 'status' (struct _PDCLIB_status_t).
38 x - the character to be delivered
39 i - pointer to number of characters already delivered in this call
40 n - pointer to maximum number of characters to be delivered in this call
41 s - the buffer into which the character shall be delivered
43 #define DELIVER( x ) do { if ( status->i < status->n ) { if ( status->stream != NULL ) putc( x, status->stream ); else status->s[status->i] = x; } ++(status->i); } while ( 0 )
45 /* This function recursively converts a given integer value to a character
46 stream. The conversion is done under the control of a given status struct
47 and written either to a character string or a stream, depending on that
48 same status struct. The status struct also keeps the function from exceeding
49 snprintf() limits, and enables any necessary padding / prefixing of the
50 output once the number of characters to be printed is known, which happens
51 at the lowermost recursion level.
53 static void int2base( intmax_t value, struct _PDCLIB_status_t * status )
55 /* Registering the character being printed at the end of the function here
56 already so it will be taken into account when the deepestmost recursion
57 does the prefix / padding stuff.
60 if ( ( value / status->base ) != 0 )
62 /* More digits to be done - recurse deeper */
63 int2base( value / status->base, status );
67 /* We reached the last digit, the deepest point of our recursion, and
68 only now know how long the number to be printed actually is. Now we
69 have to do the sign, prefix, width, and precision padding stuff
70 before printing the numbers while we resurface from the recursion.
72 /* At worst, we need two prefix characters (hex prefix). */
73 char preface[3] = "\0";
75 if ( ( status->flags & E_alt ) && ( status->base == 16 || status->base == 8 ) )
77 /* Octal / hexadecimal prefix for "%#" conversions */
78 preface[ preidx++ ] = '0';
79 if ( status->base == 16 )
81 preface[ preidx++ ] = ( status->flags & E_lower ) ? 'x' : 'X';
86 /* Negative sign for negative values - at all times. */
87 preface[ preidx++ ] = '-';
89 else if ( ! ( status->flags & E_unsigned ) )
91 /* plus sign / extra space are only for unsigned conversions */
92 if ( status->flags & E_plus )
94 preface[ preidx++ ] = '+';
96 else if ( status->flags & E_space )
98 preface[ preidx++ ] = ' ';
102 size_t prec_pads = ( status->prec > status->this ) ? ( status->prec - status->this ) : 0;
103 if ( ! ( status->flags & ( E_minus | E_zero ) ) )
105 /* Space padding is only done if no zero padding or left alignment
106 is requested. Leave space for any prefixes determined above.
108 /* The number of characters to be printed, plus prefixes if any. */
109 /* This line contained probably the most stupid, time-wasting bug
110 I've ever perpetrated. Greetings to Samface, DevL, and all
111 sceners at Breakpoint 2006.
113 size_t characters = preidx + ( ( status->this > status->prec ) ? status->this : status->prec );
114 if ( status->width > characters )
116 for ( int i = 0; i < status->width - characters; ++i )
123 /* Now we did the padding, do the prefixes (if any). */
125 while ( preface[ preidx ] != '\0' )
127 DELIVER( preface[ preidx++ ] );
130 if ( ( ! ( status->flags & E_minus ) ) && ( status->flags & E_zero ) )
132 /* If field is not left aligned, and zero padding is requested, do
135 while ( status->this < status->width )
141 /* Do the precision padding if necessary. */
142 for ( int i = 0; i < prec_pads; ++i )
148 /* Recursion tail - print the current digit. */
150 int digit = value % status->base;
155 if ( status->flags & E_lower )
157 /* Lowercase letters. Same array used for strto...(). */
158 DELIVER( _PDCLIB_digits[ digit ] );
162 /* Uppercase letters. Array only used here, only 0-F. */
163 DELIVER( _PDCLIB_Xdigits[ digit ] );
168 const char * _PDCLIB_print( const char * spec, struct _PDCLIB_status_t * status )
170 const char * orig_spec = spec;
171 if ( *(++spec) == '%' )
173 /* %% -> print single '%' */
177 /* Initializing status structure */
184 /* First come 0..n flags */
190 /* left-aligned output */
191 status->flags |= E_minus;
195 /* positive numbers prefixed with '+' */
196 status->flags |= E_plus;
200 /* alternative format (leading 0x for hex, 0 for octal) */
201 status->flags |= E_alt;
205 /* positive numbers prefixed with ' ' */
206 status->flags |= E_space;
210 /* right-aligned padding done with '0' instead of ' ' */
211 status->flags |= E_zero;
215 /* not a flag, exit flag parsing */
216 status->flags |= E_done;
219 } while ( ! ( status->flags & E_done ) );
221 /* Optional field width */
224 /* Retrieve width value from argument stack */
225 if ( ( status->width = va_arg( status->arg, int ) ) < 0 )
227 /* Negative value is '-' flag plus absolute value */
228 status->flags |= E_minus;
235 /* If a width is given, strtol() will return its value. If not given,
236 strtol() will return zero. In both cases, endptr will point to the
237 rest of the conversion specifier - just what we need.
239 status->width = (int)strtol( spec, (char**)&spec, 10 );
242 /* Optional precision */
248 /* Retrieve precision value from argument stack. A negative value
249 is as if no precision is given - as precision is initalized to
250 EOF (negative), there is no need for testing for negative here.
252 status->prec = va_arg( status->arg, int );
257 status->prec = (int)strtol( spec, &endptr, 10 );
258 if ( spec == endptr )
260 /* Decimal point but no number - bad conversion specifier. */
265 /* Having a precision cancels out any zero flag. */
266 status->flags ^= E_zero;
269 /* Optional length modifier
270 We step one character ahead in any case, and step back only if we find
271 there has been no length modifier (or step ahead another character if it
272 has been "hh" or "ll").
280 status->flags |= E_char;
286 status->flags |= E_short;
292 /* ll -> long long */
293 status->flags |= E_llong;
299 status->flags |= E_long;
303 /* j -> intmax_t, which might or might not be long long */
304 status->flags |= E_intmax;
307 /* z -> size_t, which might or might not be unsigned int */
308 status->flags |= E_size;
311 /* t -> ptrdiff_t, which might or might not be long */
312 status->flags |= E_ptrdiff;
315 /* L -> long double */
316 status->flags |= E_ldouble;
323 /* Conversion specifier */
333 status->flags |= E_unsigned;
337 status->flags |= E_unsigned;
341 status->flags |= ( E_lower | E_unsigned );
345 status->flags |= E_unsigned;
358 /* TODO: Flags, wide chars. */
359 DELIVER( va_arg( status->arg, int ) );
362 /* TODO: Flags, wide chars. */
364 char * s = va_arg( status->arg, char * );
372 /* TODO: E_long -> E_intptr */
374 status->flags |= ( E_lower | E_unsigned | E_alt | E_long );
378 int * val = va_arg( status->arg, int * );
383 /* No conversion specifier. Bad conversion. */
387 /* Do the actual output based on our findings */
388 if ( status->base != 0 )
390 /* Integer conversions */
391 /* TODO: Check for invalid flag combinations. */
392 if ( status->flags & E_unsigned )
395 switch ( status->flags & ( E_char | E_short | E_long | E_llong | E_size ) )
398 value = (uintmax_t)(unsigned char)va_arg( status->arg, int );
401 value = (uintmax_t)(unsigned short)va_arg( status->arg, int );
404 value = (uintmax_t)va_arg( status->arg, unsigned int );
407 value = (uintmax_t)va_arg( status->arg, unsigned long );
410 value = (uintmax_t)va_arg( status->arg, unsigned long long );
413 value = (uintmax_t)va_arg( status->arg, size_t );
417 if ( ( value / status->base ) != 0 )
419 int2base( (intmax_t)(value / status->base), status );
421 int digit = value % status->base;
426 if ( status->flags & E_lower )
428 DELIVER( _PDCLIB_digits[ digit ] );
432 DELIVER( _PDCLIB_Xdigits[ digit ] );
437 switch ( status->flags & ( E_char | E_short | E_long | E_llong | E_intmax ) )
440 int2base( (intmax_t)(char)va_arg( status->arg, int ), status );
443 int2base( (intmax_t)(short)va_arg( status->arg, int ), status );
446 int2base( (intmax_t)va_arg( status->arg, int ), status );
449 int2base( (intmax_t)va_arg( status->arg, long ), status );
452 int2base( (intmax_t)va_arg( status->arg, long long ), status );
455 int2base( (intmax_t)va_arg( status->arg, ptrdiff_t ), status );
458 int2base( va_arg( status->arg, intmax_t ), status );
462 if ( status->flags & E_minus )
464 while ( status->this < status->width )
470 if ( status->i >= status->n )
472 status->s[status->n - 1] = '\0';
479 #include <_PDCLIB_test.h>
484 int testprintf( char * buffer, size_t n, const char * format, ... )
486 /* Members: base, flags, n, i, this, s, width, prec, stream, arg */
487 struct _PDCLIB_status_t status = { 0, 0, n, 0, 0, buffer, 0, 0, NULL, NULL };
488 va_start( status.arg, format );
489 if ( *(_PDCLIB_print( format, &status )) != '\0' )
491 printf( "_PDCLIB_print() did not return end-of-specifier on '%s'.\n", format );
494 va_end( status.arg );
501 TESTCASE( testprintf( buffer, 100, "%hhd", CHAR_MIN ) == 4 );
502 TESTCASE( strcmp( buffer, "-128" ) == 0 );
504 TESTCASE( testprintf( buffer, 100, "%hhd", CHAR_MAX ) == 3 );
505 TESTCASE( strcmp( buffer, "127" ) == 0 );
507 TESTCASE( testprintf( buffer, 100, "%hhd", 0 ) == 1 );
508 TESTCASE( strcmp( buffer, "0" ) == 0 );
510 TESTCASE( testprintf( buffer, 100, "%hd", SHRT_MIN ) == 6 );
511 TESTCASE( strcmp( buffer, "-32768" ) == 0 );
513 TESTCASE( testprintf( buffer, 100, "%hd", SHRT_MAX ) == 5 );
514 TESTCASE( strcmp( buffer, "32767" ) == 0 );
516 TESTCASE( testprintf( buffer, 100, "%hd", 0 ) == 1 );
517 TESTCASE( strcmp( buffer, "0" ) == 0 );
519 TESTCASE( testprintf( buffer, 100, "%d", INT_MIN ) == 11 );
520 TESTCASE( strcmp( buffer, "-2147483648" ) == 0 );
522 TESTCASE( testprintf( buffer, 100, "%d", INT_MAX ) == 10 );
523 TESTCASE( strcmp( buffer, "2147483647" ) == 0 );
525 TESTCASE( testprintf( buffer, 100, "%d", 0 ) == 1 );
526 TESTCASE( strcmp( buffer, "0" ) == 0 );
528 TESTCASE( testprintf( buffer, 100, "%ld", LONG_MIN ) == 11 );
529 TESTCASE( strcmp( buffer, "-2147483648" ) == 0 );
531 TESTCASE( testprintf( buffer, 100, "%ld", LONG_MAX ) == 10 );
532 TESTCASE( strcmp( buffer, "2147483647" ) == 0 );
534 TESTCASE( testprintf( buffer, 100, "%ld", 0l ) == 1 );
535 TESTCASE( strcmp( buffer, "0" ) == 0 );
537 TESTCASE( testprintf( buffer, 100, "%lld", LLONG_MIN ) == 20 );
538 TESTCASE( strcmp( buffer, "-9223372036854775808" ) == 0 );
540 TESTCASE( testprintf( buffer, 100, "%lld", LLONG_MAX ) == 19 );
541 TESTCASE( strcmp( buffer, "9223372036854775807" ) == 0 );
543 TESTCASE( testprintf( buffer, 100, "%lld", 0ll ) );
544 TESTCASE( strcmp( buffer, "0" ) == 0 );
546 TESTCASE( testprintf( buffer, 100, "%hhu", UCHAR_MAX ) == 3 );
547 TESTCASE( strcmp( buffer, "255" ) == 0 );
549 TESTCASE( testprintf( buffer, 100, "%hhu", (unsigned char)-1 ) == 3 );
550 TESTCASE( strcmp( buffer, "255" ) == 0 );
552 TESTCASE( testprintf( buffer, 100, "%hu", USHRT_MAX ) == 5 );
553 TESTCASE( strcmp( buffer, "65535" ) == 0 );
555 TESTCASE( testprintf( buffer, 100, "%hu", (unsigned short)-1 ) == 5 );
556 TESTCASE( strcmp( buffer, "65535" ) == 0 );
558 TESTCASE( testprintf( buffer, 100, "%u", UINT_MAX ) == 10 );
559 TESTCASE( strcmp( buffer, "4294967295" ) == 0 );
561 TESTCASE( testprintf( buffer, 100, "%u", -1u ) == 10 );
562 TESTCASE( strcmp( buffer, "4294967295" ) == 0 );
564 TESTCASE( testprintf( buffer, 100, "%lu", ULONG_MAX ) == 10 );
565 TESTCASE( strcmp( buffer, "4294967295" ) == 0 );
567 TESTCASE( testprintf( buffer, 100, "%lu", -1ul ) == 10 );
568 TESTCASE( strcmp( buffer, "4294967295" ) == 0 );
570 TESTCASE( testprintf( buffer, 100, "%llu", ULLONG_MAX ) == 20 );
571 TESTCASE( strcmp( buffer, "18446744073709551615" ) == 0 );
573 TESTCASE( testprintf( buffer, 100, "%llu", -1ull ) == 20 );
574 TESTCASE( strcmp( buffer, "18446744073709551615" ) == 0 );
576 TESTCASE( testprintf( buffer, 100, "%X", UINT_MAX ) == 8 );
577 TESTCASE( strcmp( buffer, "FFFFFFFF" ) == 0 );
579 TESTCASE( testprintf( buffer, 100, "%#X", -1u ) == 10 );
580 TESTCASE( strcmp( buffer, "0XFFFFFFFF" ) == 0 );
582 TESTCASE( testprintf( buffer, 100, "%x", UINT_MAX ) == 8 );
583 TESTCASE( strcmp( buffer, "ffffffff" ) == 0 );
585 TESTCASE( testprintf( buffer, 100, "%#x", -1u ) == 10 );
586 TESTCASE( strcmp( buffer, "0xffffffff" ) == 0 );
588 TESTCASE( testprintf( buffer, 100, "%o", UINT_MAX ) == 11 );
589 TESTCASE( strcmp( buffer, "37777777777" ) == 0 );
591 TESTCASE( testprintf( buffer, 100, "%#o", -1u ) == 12 );
592 TESTCASE( strcmp( buffer, "037777777777" ) == 0 );
594 /* TODO: This test case is broken, doesn't test what it was intended to. */
595 TESTCASE( testprintf( buffer, 100, "%.0#o", 0 ) == 5 );
596 TESTCASE( strcmp( buffer, "%.0#o" ) == 0 );
598 TESTCASE( testprintf( buffer, 100, "%+d", INT_MIN ) == 11 );
599 TESTCASE( strcmp( buffer, "-2147483648" ) == 0 );
601 TESTCASE( testprintf( buffer, 100, "%+d", INT_MAX ) == 11 );
602 TESTCASE( strcmp( buffer, "+2147483647" ) == 0 );
604 TESTCASE( testprintf( buffer, 100, "%+d", 0 ) == 2 );
605 TESTCASE( strcmp( buffer, "+0" ) == 0 );
607 TESTCASE( testprintf( buffer, 100, "%+u", UINT_MAX ) == 10 );
608 TESTCASE( strcmp( buffer, "4294967295" ) == 0 );
610 TESTCASE( testprintf( buffer, 100, "%+u", -1u ) == 10 );
611 TESTCASE( strcmp( buffer, "4294967295" ) == 0 );
613 TESTCASE( testprintf( buffer, 100, "% d", INT_MIN ) == 11 );
614 TESTCASE( strcmp( buffer, "-2147483648" ) == 0 );
616 TESTCASE( testprintf( buffer, 100, "% d", INT_MAX ) == 11 );
617 TESTCASE( strcmp( buffer, " 2147483647" ) == 0 );
619 TESTCASE( testprintf( buffer, 100, "% d", 0 ) == 2 );
620 TESTCASE( strcmp( buffer, " 0" ) == 0 );
622 TESTCASE( testprintf( buffer, 100, "% u", UINT_MAX ) == 10 );
623 TESTCASE( strcmp( buffer, "4294967295" ) == 0 );
625 TESTCASE( testprintf( buffer, 100, "% u", -1u ) == 10 );
626 TESTCASE( strcmp( buffer, "4294967295" ) == 0 );
628 TESTCASE( testprintf( buffer, 100, "%9d", INT_MIN ) == 11 );
629 TESTCASE( strcmp( buffer, "-2147483648" ) == 0 );
631 TESTCASE( testprintf( buffer, 100, "%9d", INT_MAX ) == 10 );
632 TESTCASE( strcmp( buffer, "2147483647" ) == 0 );
634 TESTCASE( testprintf( buffer, 100, "%10d", INT_MIN ) == 11 );
635 TESTCASE( strcmp( buffer, "-2147483648" ) == 0 );
637 TESTCASE( testprintf( buffer, 100, "%10d", INT_MAX ) == 10 );
638 TESTCASE( strcmp( buffer, "2147483647" ) == 0 );
640 TESTCASE( testprintf( buffer, 100, "%11d", INT_MIN ) == 11 );
641 TESTCASE( strcmp( buffer, "-2147483648" ) == 0 );
643 TESTCASE( testprintf( buffer, 100, "%11d", INT_MAX ) == 11 );
644 TESTCASE( strcmp( buffer, " 2147483647" ) == 0 );
646 TESTCASE( testprintf( buffer, 100, "%12d", INT_MIN ) == 12 );
647 TESTCASE( strcmp( buffer, " -2147483648" ) == 0 );
649 TESTCASE( testprintf( buffer, 100, "%12d", INT_MAX ) == 12 );
650 TESTCASE( strcmp( buffer, " 2147483647" ) == 0 );
652 TESTCASE( testprintf( buffer, 100, "%-9d", INT_MIN ) == 11 );
653 TESTCASE( strcmp( buffer, "-2147483648" ) == 0 );
655 TESTCASE( testprintf( buffer, 100, "%-9d", INT_MAX ) == 10 );
656 TESTCASE( strcmp( buffer, "2147483647" ) == 0 );
658 TESTCASE( testprintf( buffer, 100, "%-10d", INT_MIN ) == 11 );
659 TESTCASE( strcmp( buffer, "-2147483648" ) == 0 );
661 TESTCASE( testprintf( buffer, 100, "%-10d", INT_MAX ) == 10 );
662 TESTCASE( strcmp( buffer, "2147483647" ) == 0 );
664 TESTCASE( testprintf( buffer, 100, "%-11d", INT_MIN ) == 11 );
665 TESTCASE( strcmp( buffer, "-2147483648" ) == 0 );
667 TESTCASE( testprintf( buffer, 100, "%-11d", INT_MAX ) == 11 );
668 TESTCASE( strcmp( buffer, "2147483647 " ) == 0 );
670 TESTCASE( testprintf( buffer, 100, "%-12d", INT_MIN ) == 12 );
671 TESTCASE( strcmp( buffer, "-2147483648 " ) == 0 );
673 TESTCASE( testprintf( buffer, 100, "%-12d", INT_MAX ) == 12 );
674 TESTCASE( strcmp( buffer, "2147483647 " ) == 0 );
676 TESTCASE( testprintf( buffer, 100, "%09d", INT_MIN ) == 11 );
677 TESTCASE( strcmp( buffer, "-2147483648" ) == 0 );
679 TESTCASE( testprintf( buffer, 100, "%09d", INT_MAX ) == 10 );
680 TESTCASE( strcmp( buffer, "2147483647" ) == 0 );
682 TESTCASE( testprintf( buffer, 100, "%010d", INT_MIN ) == 11 );
683 TESTCASE( strcmp( buffer, "-2147483648" ) == 0 );
685 TESTCASE( testprintf( buffer, 100, "%010d", INT_MAX ) == 10 );
686 TESTCASE( strcmp( buffer, "2147483647" ) == 0 );
688 TESTCASE( testprintf( buffer, 100, "%011d", INT_MIN ) == 11 );
689 TESTCASE( strcmp( buffer, "-2147483648" ) == 0 );
691 TESTCASE( testprintf( buffer, 100, "%011d", INT_MAX ) == 11 );
692 TESTCASE( strcmp( buffer, "02147483647" ) == 0 );
694 TESTCASE( testprintf( buffer, 100, "%012d", INT_MIN ) == 12 );
695 TESTCASE( strcmp( buffer, "-02147483648" ) == 0 );
697 TESTCASE( testprintf( buffer, 100, "%012d", INT_MAX ) == 12 );
698 TESTCASE( strcmp( buffer, "002147483647" ) == 0 );
700 TESTCASE( testprintf( buffer, 100, "%-09d", INT_MIN ) == 11 );
701 TESTCASE( strcmp( buffer, "-2147483648" ) == 0 );
703 TESTCASE( testprintf( buffer, 100, "%-09d", INT_MAX ) == 10 );
704 TESTCASE( strcmp( buffer, "2147483647" ) == 0 );
706 TESTCASE( testprintf( buffer, 100, "%-010d", INT_MIN ) == 11 );
707 TESTCASE( strcmp( buffer, "-2147483648" ) == 0 );
709 TESTCASE( testprintf( buffer, 100, "%-010d", INT_MAX ) == 10 );
710 TESTCASE( strcmp( buffer, "2147483647" ) == 0 );
712 TESTCASE( testprintf( buffer, 100, "%-011d", INT_MIN ) == 11 );
713 TESTCASE( strcmp( buffer, "-2147483648" ) == 0 );
715 TESTCASE( testprintf( buffer, 100, "%-011d", INT_MAX ) == 11 );
716 TESTCASE( strcmp( buffer, "2147483647 " ) == 0 );
718 TESTCASE( testprintf( buffer, 100, "%-012d", INT_MIN ) == 12 );
719 TESTCASE( strcmp( buffer, "-2147483648 " ) == 0 );
721 TESTCASE( testprintf( buffer, 100, "%-012d", INT_MAX ) == 12 );
722 TESTCASE( strcmp( buffer, "2147483647 " ) == 0 );
724 TESTCASE( testprintf( buffer, 8, "%9d", INT_MAX ) == 10 );
725 TESTCASE( strcmp( buffer, "2147483" ) == 0 );
727 TESTCASE( testprintf( buffer, 8, "%9d", INT_MIN ) == 11 );
728 TESTCASE( strcmp( buffer, "-214748" ) == 0 );
730 TESTCASE( testprintf( buffer, 9, "%9d", INT_MAX ) == 10 );
731 TESTCASE( strcmp( buffer, "21474836" ) == 0 );
733 TESTCASE( testprintf( buffer, 9, "%9d", INT_MIN ) == 11 );
734 TESTCASE( strcmp( buffer, "-2147483" ) == 0 );
736 TESTCASE( testprintf( buffer, 10, "%9d", INT_MAX ) == 10 );
737 TESTCASE( strcmp( buffer, "214748364" ) == 0 );
739 TESTCASE( testprintf( buffer, 10, "%9d", INT_MIN ) == 11 );
740 TESTCASE( strcmp( buffer, "-21474836" ) == 0 );
742 TESTCASE( testprintf( buffer, 9, "%10d", INT_MAX ) == 10 );
743 TESTCASE( strcmp( buffer, "21474836" ) == 0 );
745 TESTCASE( testprintf( buffer, 9, "%10d", INT_MIN ) == 11 );
746 TESTCASE( strcmp( buffer, "-2147483" ) == 0 );
748 TESTCASE( testprintf( buffer, 10, "%10d", INT_MAX ) == 10 );
749 TESTCASE( strcmp( buffer, "214748364" ) == 0 );
751 TESTCASE( testprintf( buffer, 10, "%10d", INT_MIN ) == 11 );
752 TESTCASE( strcmp( buffer, "-21474836" ) == 0 );
754 TESTCASE( testprintf( buffer, 11, "%10d", INT_MAX ) == 10 );
755 TESTCASE( strcmp( buffer, "2147483647" ) == 0 );
757 TESTCASE( testprintf( buffer, 11, "%10d", INT_MIN ) == 11 );
758 TESTCASE( strcmp( buffer, "-214748364" ) == 0 );
760 TESTCASE( testprintf( buffer, 10, "%11d", INT_MAX ) == 11 );
761 TESTCASE( strcmp( buffer, " 21474836" ) == 0 );
763 TESTCASE( testprintf( buffer, 10, "%11d", INT_MIN ) == 11 );
764 TESTCASE( strcmp( buffer, "-21474836" ) == 0 );
766 TESTCASE( testprintf( buffer, 11, "%11d", INT_MAX ) == 11 );
767 TESTCASE( strcmp( buffer, " 214748364" ) == 0 );
769 TESTCASE( testprintf( buffer, 11, "%11d", INT_MIN ) == 11 );
770 TESTCASE( strcmp( buffer, "-214748364" ) == 0 );
772 TESTCASE( testprintf( buffer, 12, "%11d", INT_MAX ) == 11 );
773 TESTCASE( strcmp( buffer, " 2147483647" ) == 0 );
775 TESTCASE( testprintf( buffer, 12, "%11d", INT_MIN ) == 11 );
776 TESTCASE( strcmp( buffer, "-2147483648" ) == 0 );
778 TESTCASE( testprintf( buffer, 11, "%12d", INT_MAX ) == 12 );
779 TESTCASE( strcmp( buffer, " 21474836" ) == 0 );
781 TESTCASE( testprintf( buffer, 11, "%12d", INT_MIN ) == 12 );
782 TESTCASE( strcmp( buffer, " -21474836" ) == 0 );
784 TESTCASE( testprintf( buffer, 12, "%12d", INT_MAX ) == 12 );
785 TESTCASE( strcmp( buffer, " 214748364" ) == 0 );
787 TESTCASE( testprintf( buffer, 12, "%12d", INT_MIN ) == 12 );
788 TESTCASE( strcmp( buffer, " -214748364" ) == 0 );
790 TESTCASE( testprintf( buffer, 13, "%12d", INT_MAX ) == 12 );
791 TESTCASE( strcmp( buffer, " 2147483647" ) == 0 );
793 TESTCASE( testprintf( buffer, 13, "%12d", INT_MIN ) == 12 );
794 TESTCASE( strcmp( buffer, " -2147483648" ) == 0 );
796 TESTCASE( testprintf( buffer, 100, "%030.20d", INT_MAX ) == 30 );
797 TESTCASE( strcmp( buffer, " 00000000002147483647" ) == 0 );
799 TESTCASE( testprintf( buffer, 100, "%.6x", UINT_MAX ) == 8 );
800 TESTCASE( strcmp( buffer, "ffffffff" ) == 0 );
802 TESTCASE( testprintf( buffer, 100, "%#6.3x", UINT_MAX ) == 10 );
803 TESTCASE( strcmp( buffer, "0xffffffff" ) == 0 );
805 TESTCASE( testprintf( buffer, 100, "%#3.6x", UINT_MAX ) == 10 );
806 TESTCASE( strcmp( buffer, "0xffffffff" ) == 0 );
808 TESTCASE( testprintf( buffer, 100, "%.6d", INT_MIN ) == 11 );
809 TESTCASE( strcmp( buffer, "-2147483648" ) == 0 );
811 TESTCASE( testprintf( buffer, 100, "%6.3d", INT_MIN ) == 11 );
812 TESTCASE( strcmp( buffer, "-2147483648" ) == 0 );
814 TESTCASE( testprintf( buffer, 100, "%3.6d", INT_MIN ) == 11 );
815 TESTCASE( strcmp( buffer, "-2147483648" ) == 0 );
817 TESTCASE( testprintf( buffer, 100, "%#0.6x", UINT_MAX ) == 10 );
818 TESTCASE( strcmp( buffer, "0xffffffff" ) == 0 );
820 TESTCASE( testprintf( buffer, 100, "%#06.3x", UINT_MAX ) == 10 );
821 TESTCASE( strcmp( buffer, "0xffffffff" ) == 0 );
823 TESTCASE( testprintf( buffer, 100, "%#03.6x", UINT_MAX ) == 10 );
824 TESTCASE( strcmp( buffer, "0xffffffff" ) == 0 );
826 TESTCASE( testprintf( buffer, 100, "%#0.6d", INT_MAX ) == 10 );
827 TESTCASE( strcmp( buffer, "2147483647" ) == 0 );
829 TESTCASE( testprintf( buffer, 100, "%#06.3d", INT_MAX ) == 10 );
830 TESTCASE( strcmp( buffer, "2147483647" ) == 0 );
832 TESTCASE( testprintf( buffer, 100, "%#03.6d", INT_MAX ) == 10 );
833 TESTCASE( strcmp( buffer, "2147483647" ) == 0 );
835 TESTCASE( testprintf( buffer, 100, "%#+.6d", INT_MAX ) == 11 );
836 TESTCASE( strcmp( buffer, "+2147483647" ) == 0 );
838 TESTCASE( testprintf( buffer, 100, "%#+6.3d", INT_MAX ) == 11 );
839 TESTCASE( strcmp( buffer, "+2147483647" ) == 0 );
841 TESTCASE( testprintf( buffer, 100, "%#+3.6d", INT_MAX ) == 11 );
842 TESTCASE( strcmp( buffer, "+2147483647" ) == 0 );
844 TESTCASE( testprintf( buffer, 100, "%+0.6d", INT_MAX ) == 11 );
845 TESTCASE( strcmp( buffer, "+2147483647" ) == 0 );
847 TESTCASE( testprintf( buffer, 100, "%+06.3d", INT_MAX ) == 11 );
848 TESTCASE( strcmp( buffer, "+2147483647" ) == 0 );
850 TESTCASE( testprintf( buffer, 100, "%+03.6d", INT_MAX ) == 11 );
851 TESTCASE( strcmp( buffer, "+2147483647" ) == 0 );
853 TESTCASE( testprintf( buffer, 100, "%c", 'x' ) == 1 );
854 TESTCASE( strcmp( buffer, "x" ) == 0 );
856 TESTCASE( testprintf( buffer, 100, "%s", "abcdef" ) == 6 );
857 TESTCASE( strcmp( buffer, "abcdef" ) == 0 );
859 TESTCASE( testprintf( buffer, 100, "%p", (void *)0xdeadbeef ) == 10 );
860 TESTCASE( strcmp( buffer, "0xdeadbeef" ) == 0 );
864 TESTCASE( testprintf( buffer, 100, "123456%n789%n", &val1, &val2 ) == 9 );
865 TESTCASE( strcmp( buffer, "123456789" ) == 0 );
867 TESTCASE( val1 == 6 );
868 TESTCASE( val2 == 9 );
869 } return TEST_RESULTS;