Back to index

glibc  2.9
tst-printf.c
Go to the documentation of this file.
00001 /* Copyright (C) 1991,92,93,95,96,97,98,99, 2000, 2002, 2006
00002      Free Software Foundation, Inc.
00003    This file is part of the GNU C Library.
00004 
00005    The GNU C Library is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Lesser General Public
00007    License as published by the Free Software Foundation; either
00008    version 2.1 of the License, or (at your option) any later version.
00009 
00010    The GNU C Library is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013    Lesser General Public License for more details.
00014 
00015    You should have received a copy of the GNU Lesser General Public
00016    License along with the GNU C Library; if not, write to the Free
00017    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
00018    02111-1307 USA.  */
00019 
00020 #ifdef BSD
00021 #include </usr/include/stdio.h>
00022 #define EXIT_SUCCESS 0
00023 #else
00024 #include <limits.h>
00025 #include <stdio.h>
00026 #include <stdlib.h>
00027 #include <string.h>
00028 #endif
00029 
00030 #include <float.h>
00031 
00032 static void rfg1 (void);
00033 static void rfg2 (void);
00034 static void rfg3 (void);
00035 
00036 
00037 static void
00038 fmtchk (const char *fmt)
00039 {
00040   (void) fputs(fmt, stdout);
00041   (void) printf(":\t`");
00042   (void) printf(fmt, 0x12);
00043   (void) printf("'\n");
00044 }
00045 
00046 static void
00047 fmtst1chk (const char *fmt)
00048 {
00049   (void) fputs(fmt, stdout);
00050   (void) printf(":\t`");
00051   (void) printf(fmt, 4, 0x12);
00052   (void) printf("'\n");
00053 }
00054 
00055 static void
00056 fmtst2chk (const char *fmt)
00057 {
00058   (void) fputs(fmt, stdout);
00059   (void) printf(":\t`");
00060   (void) printf(fmt, 4, 4, 0x12);
00061   (void) printf("'\n");
00062 }
00063 
00064 /* This page is covered by the following copyright: */
00065 
00066 /* (C) Copyright C E Chew
00067  *
00068  * Feel free to copy, use and distribute this software provided:
00069  *
00070  *     1. you do not pretend that you wrote it
00071  *     2. you leave this copyright notice intact.
00072  */
00073 
00074 /*
00075  * Extracted from exercise.c for glibc-1.05 bug report by Bruce Evans.
00076  */
00077 
00078 #define DEC -123
00079 #define INT 255
00080 #define UNS (~0)
00081 
00082 /* Formatted Output Test
00083  *
00084  * This exercises the output formatting code.
00085  */
00086 
00087 static void
00088 fp_test (void)
00089 {
00090   int i, j, k, l;
00091   char buf[7];
00092   char *prefix = buf;
00093   char tp[20];
00094 
00095   puts("\nFormatted output test");
00096   printf("prefix  6d      6o      6x      6X      6u\n");
00097   strcpy(prefix, "%");
00098   for (i = 0; i < 2; i++) {
00099     for (j = 0; j < 2; j++) {
00100       for (k = 0; k < 2; k++) {
00101        for (l = 0; l < 2; l++) {
00102          strcpy(prefix, "%");
00103          if (i == 0) strcat(prefix, "-");
00104          if (j == 0) strcat(prefix, "+");
00105          if (k == 0) strcat(prefix, "#");
00106          if (l == 0) strcat(prefix, "0");
00107          printf("%5s |", prefix);
00108          strcpy(tp, prefix);
00109          strcat(tp, "6d |");
00110          printf(tp, DEC);
00111          strcpy(tp, prefix);
00112          strcat(tp, "6o |");
00113          printf(tp, INT);
00114          strcpy(tp, prefix);
00115          strcat(tp, "6x |");
00116          printf(tp, INT);
00117          strcpy(tp, prefix);
00118          strcat(tp, "6X |");
00119          printf(tp, INT);
00120          strcpy(tp, prefix);
00121          strcat(tp, "6u |");
00122          printf(tp, UNS);
00123          printf("\n");
00124        }
00125       }
00126     }
00127   }
00128   printf("%10s\n", (char *) NULL);
00129   printf("%-10s\n", (char *) NULL);
00130 }
00131 
00132 int
00133 main (int argc, char *argv[])
00134 {
00135   static char shortstr[] = "Hi, Z.";
00136   static char longstr[] = "Good morning, Doctor Chandra.  This is Hal.  \
00137 I am ready for my first lesson today.";
00138   int result = 0;
00139 
00140   fmtchk("%.4x");
00141   fmtchk("%04x");
00142   fmtchk("%4.4x");
00143   fmtchk("%04.4x");
00144   fmtchk("%4.3x");
00145   fmtchk("%04.3x");
00146 
00147   fmtst1chk("%.*x");
00148   fmtst1chk("%0*x");
00149   fmtst2chk("%*.*x");
00150   fmtst2chk("%0*.*x");
00151 
00152 #ifndef       BSD
00153   printf("bad format:\t\"%b\"\n");
00154   printf("nil pointer (padded):\t\"%10p\"\n", (void *) NULL);
00155 #endif
00156 
00157   printf("decimal negative:\t\"%d\"\n", -2345);
00158   printf("octal negative:\t\"%o\"\n", -2345);
00159   printf("hex negative:\t\"%x\"\n", -2345);
00160   printf("long decimal number:\t\"%ld\"\n", -123456L);
00161   printf("long octal negative:\t\"%lo\"\n", -2345L);
00162   printf("long unsigned decimal number:\t\"%lu\"\n", -123456L);
00163   printf("zero-padded LDN:\t\"%010ld\"\n", -123456L);
00164   printf("left-adjusted ZLDN:\t\"%-010ld\"\n", -123456L);
00165   printf("space-padded LDN:\t\"%10ld\"\n", -123456L);
00166   printf("left-adjusted SLDN:\t\"%-10ld\"\n", -123456L);
00167 
00168   printf("zero-padded string:\t\"%010s\"\n", shortstr);
00169   printf("left-adjusted Z string:\t\"%-010s\"\n", shortstr);
00170   printf("space-padded string:\t\"%10s\"\n", shortstr);
00171   printf("left-adjusted S string:\t\"%-10s\"\n", shortstr);
00172   printf("null string:\t\"%s\"\n", (char *)NULL);
00173   printf("limited string:\t\"%.22s\"\n", longstr);
00174 
00175   printf("e-style >= 1:\t\"%e\"\n", 12.34);
00176   printf("e-style >= .1:\t\"%e\"\n", 0.1234);
00177   printf("e-style < .1:\t\"%e\"\n", 0.001234);
00178   printf("e-style big:\t\"%.60e\"\n", 1e20);
00179   printf ("e-style == .1:\t\"%e\"\n", 0.1);
00180   printf("f-style >= 1:\t\"%f\"\n", 12.34);
00181   printf("f-style >= .1:\t\"%f\"\n", 0.1234);
00182   printf("f-style < .1:\t\"%f\"\n", 0.001234);
00183   printf("g-style >= 1:\t\"%g\"\n", 12.34);
00184   printf("g-style >= .1:\t\"%g\"\n", 0.1234);
00185   printf("g-style < .1:\t\"%g\"\n", 0.001234);
00186   printf("g-style big:\t\"%.60g\"\n", 1e20);
00187 
00188   printf (" %6.5f\n", .099999999860301614);
00189   printf (" %6.5f\n", .1);
00190   printf ("x%5.4fx\n", .5);
00191 
00192   printf ("%#03x\n", 1);
00193 
00194   printf ("something really insane: %.10000f\n", 1.0);
00195 
00196   {
00197     double d = FLT_MIN;
00198     int niter = 17;
00199 
00200     while (niter-- != 0)
00201       printf ("%.17e\n", d / 2);
00202     fflush (stdout);
00203   }
00204 
00205   printf ("%15.5e\n", 4.9406564584124654e-324);
00206 
00207 #define FORMAT "|%12.4f|%12.4e|%12.4g|\n"
00208   printf (FORMAT, 0.0, 0.0, 0.0);
00209   printf (FORMAT, 1.0, 1.0, 1.0);
00210   printf (FORMAT, -1.0, -1.0, -1.0);
00211   printf (FORMAT, 100.0, 100.0, 100.0);
00212   printf (FORMAT, 1000.0, 1000.0, 1000.0);
00213   printf (FORMAT, 10000.0, 10000.0, 10000.0);
00214   printf (FORMAT, 12345.0, 12345.0, 12345.0);
00215   printf (FORMAT, 100000.0, 100000.0, 100000.0);
00216   printf (FORMAT, 123456.0, 123456.0, 123456.0);
00217 #undef FORMAT
00218 
00219   {
00220     char buf[20];
00221     char buf2[512];
00222     printf ("snprintf (\"%%30s\", \"foo\") == %d, \"%.*s\"\n",
00223            snprintf (buf, sizeof (buf), "%30s", "foo"), (int) sizeof (buf),
00224            buf);
00225     printf ("snprintf (\"%%.999999u\", 10) == %d\n",
00226            snprintf(buf2, sizeof(buf2), "%.999999u", 10));
00227   }
00228 
00229   fp_test ();
00230 
00231   printf ("%e should be 1.234568e+06\n", 1234567.8);
00232   printf ("%f should be 1234567.800000\n", 1234567.8);
00233   printf ("%g should be 1.23457e+06\n", 1234567.8);
00234   printf ("%g should be 123.456\n", 123.456);
00235   printf ("%g should be 1e+06\n", 1000000.0);
00236   printf ("%g should be 10\n", 10.0);
00237   printf ("%g should be 0.02\n", 0.02);
00238 
00239 #if 0
00240   /* This test rather checks the way the compiler handles constant
00241      folding.  gcc behavior wrt to this changed in 3.2 so it is not a
00242      portable test.  */
00243   {
00244     double x=1.0;
00245     printf("%.17f\n",(1.0/x/10.0+1.0)*x-x);
00246   }
00247 #endif
00248 
00249   {
00250     char buf[200];
00251 
00252     sprintf(buf,"%*s%*s%*s",-1,"one",-20,"two",-30,"three");
00253 
00254     result |= strcmp (buf,
00255                     "onetwo                 three                         ");
00256 
00257     puts (result != 0 ? "Test failed!" : "Test ok.");
00258   }
00259 
00260   {
00261     char buf[200];
00262 
00263     sprintf (buf, "%07Lo", 040000000000ll);
00264     printf ("sprintf (buf, \"%%07Lo\", 040000000000ll) = %s", buf);
00265 
00266     if (strcmp (buf, "40000000000") != 0)
00267       {
00268        result = 1;
00269        fputs ("\tFAILED", stdout);
00270       }
00271     puts ("");
00272   }
00273 
00274   printf ("printf (\"%%hhu\", %u) = %hhu\n", UCHAR_MAX + 2, UCHAR_MAX + 2);
00275   printf ("printf (\"%%hu\", %u) = %hu\n", USHRT_MAX + 2, USHRT_MAX + 2);
00276   printf ("printf (\"%%hhi\", %i) = %hhi\n", UCHAR_MAX + 2, UCHAR_MAX + 2);
00277   printf ("printf (\"%%hi\", %i) = %hi\n", USHRT_MAX + 2, USHRT_MAX + 2);
00278 
00279   printf ("printf (\"%%1$hhu\", %2$u) = %1$hhu\n",
00280          UCHAR_MAX + 2, UCHAR_MAX + 2);
00281   printf ("printf (\"%%1$hu\", %2$u) = %1$hu\n", USHRT_MAX + 2, USHRT_MAX + 2);
00282   printf ("printf (\"%%1$hhi\", %2$i) = %1$hhi\n",
00283          UCHAR_MAX + 2, UCHAR_MAX + 2);
00284   printf ("printf (\"%%1$hi\", %2$i) = %1$hi\n", USHRT_MAX + 2, USHRT_MAX + 2);
00285 
00286   puts ("--- Should be no further output. ---");
00287   rfg1 ();
00288   rfg2 ();
00289   rfg3 ();
00290 
00291   {
00292     char bytes[7];
00293     char buf[20];
00294 
00295     memset (bytes, '\xff', sizeof bytes);
00296     sprintf (buf, "foo%hhn\n", &bytes[3]);
00297     if (bytes[0] != '\xff' || bytes[1] != '\xff' || bytes[2] != '\xff'
00298        || bytes[4] != '\xff' || bytes[5] != '\xff' || bytes[6] != '\xff')
00299       {
00300        puts ("%hhn overwrite more bytes");
00301        result = 1;
00302       }
00303     if (bytes[3] != 3)
00304       {
00305        puts ("%hhn wrote incorrect value");
00306        result = 1;
00307       }
00308   }
00309 
00310   return result != 0;
00311 }
00312 
00313 static void
00314 rfg1 (void)
00315 {
00316   char buf[100];
00317 
00318   sprintf (buf, "%5.s", "xyz");
00319   if (strcmp (buf, "     ") != 0)
00320     printf ("got: '%s', expected: '%s'\n", buf, "     ");
00321   sprintf (buf, "%5.f", 33.3);
00322   if (strcmp (buf, "   33") != 0)
00323     printf ("got: '%s', expected: '%s'\n", buf, "   33");
00324   sprintf (buf, "%8.e", 33.3e7);
00325   if (strcmp (buf, "   3e+08") != 0)
00326     printf ("got: '%s', expected: '%s'\n", buf, "   3e+08");
00327   sprintf (buf, "%8.E", 33.3e7);
00328   if (strcmp (buf, "   3E+08") != 0)
00329     printf ("got: '%s', expected: '%s'\n", buf, "   3E+08");
00330   sprintf (buf, "%.g", 33.3);
00331   if (strcmp (buf, "3e+01") != 0)
00332     printf ("got: '%s', expected: '%s'\n", buf, "3e+01");
00333   sprintf (buf, "%.G", 33.3);
00334   if (strcmp (buf, "3E+01") != 0)
00335     printf ("got: '%s', expected: '%s'\n", buf, "3E+01");
00336 }
00337 
00338 static void
00339 rfg2 (void)
00340 {
00341   int prec;
00342   char buf[100];
00343 
00344   prec = 0;
00345   sprintf (buf, "%.*g", prec, 3.3);
00346   if (strcmp (buf, "3") != 0)
00347     printf ("got: '%s', expected: '%s'\n", buf, "3");
00348   prec = 0;
00349   sprintf (buf, "%.*G", prec, 3.3);
00350   if (strcmp (buf, "3") != 0)
00351     printf ("got: '%s', expected: '%s'\n", buf, "3");
00352   prec = 0;
00353   sprintf (buf, "%7.*G", prec, 3.33);
00354   if (strcmp (buf, "      3") != 0)
00355     printf ("got: '%s', expected: '%s'\n", buf, "      3");
00356   prec = 3;
00357   sprintf (buf, "%04.*o", prec, 33);
00358   if (strcmp (buf, " 041") != 0)
00359     printf ("got: '%s', expected: '%s'\n", buf, " 041");
00360   prec = 7;
00361   sprintf (buf, "%09.*u", prec, 33);
00362   if (strcmp (buf, "  0000033") != 0)
00363     printf ("got: '%s', expected: '%s'\n", buf, "  0000033");
00364   prec = 3;
00365   sprintf (buf, "%04.*x", prec, 33);
00366   if (strcmp (buf, " 021") != 0)
00367     printf ("got: '%s', expected: '%s'\n", buf, " 021");
00368   prec = 3;
00369   sprintf (buf, "%04.*X", prec, 33);
00370   if (strcmp (buf, " 021") != 0)
00371     printf ("got: '%s', expected: '%s'\n", buf, " 021");
00372 }
00373 
00374 static void
00375 rfg3 (void)
00376 {
00377   char buf[100];
00378   double g = 5.0000001;
00379   unsigned long l = 1234567890;
00380   double d = 321.7654321;
00381   const char s[] = "test-string";
00382   int i = 12345;
00383   int h = 1234;
00384 
00385   sprintf (buf,
00386           "%1$*5$d %2$*6$hi %3$*7$lo %4$*8$f %9$*12$e %10$*13$g %11$*14$s",
00387           i, h, l, d, 8, 5, 14, 14, d, g, s, 14, 3, 14);
00388   if (strcmp (buf,
00389              "   12345  1234    11145401322     321.765432   3.217654e+02   5    test-string") != 0)
00390     printf ("got: '%s', expected: '%s'\n", buf,
00391            "   12345  1234    11145401322     321.765432   3.217654e+02   5    test-string");
00392 }