Back to index

glibc  2.9
tst-strtoll.c
Go to the documentation of this file.
00001 /* My bet is this was written by Chris Torek.
00002    I reformatted and ansidecl-ized it, and tweaked it a little.  */
00003 
00004 #include <ctype.h>
00005 #include <stdio.h>
00006 #include <errno.h>
00007 #include <stdlib.h>
00008 #include <string.h>
00009 #include <limits.h>
00010 
00011 struct ltest
00012   {
00013     const char *str;        /* Convert this.  */
00014     unsigned long long int expect; /* To get this.  */
00015     int base;               /* Use this base.  */
00016     char left;                     /* With this left over.  */
00017     int err;                /* And this in errno.  */
00018   };
00019 static const struct ltest tests[] =
00020   {
00021   /* First, signed numbers:  */
00022   /* simple... */
00023   {"123", 123, 0, 0, 0},
00024   {"+123", 123, 0, 0, 0},
00025   {"  123", 123, 0, 0, 0},
00026   {" 123 ", 123, 0, ' ', 0},
00027   {"   -17", -17, 0, 0, 0},
00028 
00029   /* implicit base... */
00030   {"0123", 0123, 0, 0, 0},
00031   {"0123a", 0123, 0, 'a', 0},
00032   {"01239", 0123, 0, '9', 0},
00033   {"0x123", 0x123, 0, 0, 0},
00034   {"-0x123", -0x123, 0, 0, 0},
00035   {"0x0xc", 0, 0, 'x', 0},
00036   {" +0x123fg", 0x123f, 0, 'g', 0},
00037 
00038   /* explicit base... */
00039   {"123", 0x123, 16, 0, 0},
00040   {"0x123", 0x123, 16, 0, 0},
00041   {"123", 0123, 8, 0, 0},
00042   {"0123", 0123, 8, 0, 0},
00043   {"0123", 123, 10, 0, 0},
00044   {"0x123", 0, 10, 'x', 0},
00045 
00046   /* case insensitivity... */
00047   {"abcd", 0xabcd, 16, 0, 0},
00048   {"AbCd", 0xabcd, 16, 0, 0},
00049   {"0xABCD", 0xabcd, 16, 0, 0},
00050   {"0Xabcd", 0xabcd, 16, 0, 0},
00051 
00052   /* odd bases... */
00053   {"0xyz", 33 * 35 + 34, 35, 'z', 0},
00054   {"yz!", 34 * 36 + 35, 36, '!', 0},
00055   {"-yz", -(34*36 + 35), 36, 0, 0},
00056   {"GhI4", ((16*20 + 17)*20 + 18)*20 + 4, 20, 0, 0},
00057 
00058   /* special case for the 32-bit version of strtoll,
00059      from a ncftp configure test */
00060   {"99000000001", 1000000000ll * 99ll + 1ll, 0, 0},
00061 
00062   /* extremes... */
00063   {"9223372036854775807", 9223372036854775807ll, 0, 0, 0},
00064   {"9223372036854775808", 9223372036854775807ll, 0, 0, ERANGE},
00065   {"922337203685477580777", 9223372036854775807ll, 0, 0, ERANGE},
00066   {"9223372036854775810", 9223372036854775807ll, 0, 0, ERANGE},
00067   {"-2147483648", -2147483648ll, 0, 0, 0},
00068   {"-9223372036854775808", -9223372036854775807ll - 1, 0, 0, 0},
00069   {"-9223372036854775809", -9223372036854775807ll - 1, 0, 0, ERANGE},
00070   {"0x112233445566778899z", 9223372036854775807ll, 16, 'z', ERANGE},
00071   {"0xFFFFFFFFFFFF00FF" , 9223372036854775807ll, 0, 0, ERANGE},
00072   {NULL, 0, 0, 0, 0},
00073 
00074   /* Then unsigned.  */
00075   {"  0", 0, 0, 0, 0},
00076   {"0xffffffffg", 0xffffffff, 0, 'g', 0},
00077   {"0xffffffffffffffffg", 0xffffffffffffffffull, 0, 'g', 0},
00078   {"-0xfedcba987654321", 0xf0123456789abcdfull, 0, 0, 0},
00079   {"0xf1f2f3f4f5f6f7f8f9", 0xffffffffffffffffull, 0, 0, ERANGE},
00080   {"-0x123456789abcdef01", 0xffffffffffffffffull, 0, 0, ERANGE},
00081   {NULL, 0, 0, 0, 0},
00082   };
00083 
00084 /* Prototypes for local functions.  */
00085 static void expand (char *dst, int c);
00086 
00087 int
00088 main (void)
00089 {
00090   register const struct ltest *lt;
00091   char *ep;
00092   int status = 0;
00093   int save_errno;
00094 
00095   for (lt = tests; lt->str != NULL; ++lt)
00096     {
00097       register long long int l;
00098 
00099       errno = 0;
00100       l = strtoll (lt->str, &ep, lt->base);
00101       save_errno = errno;
00102       printf ("strtoll(\"%s\", , %d) test %u",
00103              lt->str, lt->base, (unsigned int) (lt - tests));
00104       if (l == (long long int) lt->expect && *ep == lt->left
00105          && save_errno == lt->err)
00106        puts("\tOK");
00107       else
00108        {
00109          puts("\tBAD");
00110          if (l != (long long int) lt->expect)
00111            printf("  returns %lld, expected %lld\n",
00112                  l, (long long int) lt->expect);
00113          if (lt->left != *ep)
00114            {
00115              char exp1[5], exp2[5];
00116              expand (exp1, *ep);
00117              expand (exp2, lt->left);
00118              printf ("  leaves '%s', expected '%s'\n", exp1, exp2);
00119            }
00120          if (save_errno != lt->err)
00121            printf ("  errno %d (%s)  instead of %d (%s)\n",
00122                   save_errno, strerror (save_errno),
00123                   lt->err, strerror (lt->err));
00124          status = 1;
00125        }
00126     }
00127 
00128   for (++lt; lt->str != NULL; lt++)
00129     {
00130       register unsigned long long int ul;
00131 
00132       errno = 0;
00133       ul = strtoull (lt->str, &ep, lt->base);
00134       save_errno = errno;
00135       printf ("strtoull(\"%s\", , %d) test %u",
00136              lt->str, lt->base, (unsigned int) (lt - tests));
00137       if (ul == lt->expect && *ep == lt->left && save_errno == lt->err)
00138        puts("\tOK");
00139       else
00140        {
00141          puts ("\tBAD");
00142          if (ul != lt->expect)
00143            printf ("  returns %llu, expected %llu\n",
00144                   ul, lt->expect);
00145          if (lt->left != *ep)
00146            {
00147              char exp1[5], exp2[5];
00148              expand (exp1, *ep);
00149              expand (exp2, lt->left);
00150              printf ("  leaves '%s', expected '%s'\n", exp1, exp2);
00151            }
00152          if (save_errno != lt->err)
00153            printf ("  errno %d (%s) instead of %d (%s)\n",
00154                   save_errno, strerror (save_errno),
00155                   lt->err, strerror (lt->err));
00156          status = 1;
00157        }
00158     }
00159 
00160   return status ? EXIT_FAILURE : EXIT_SUCCESS;
00161 }
00162 
00163 static void
00164 expand (dst, c)
00165      char *dst;
00166      int c;
00167 {
00168   if (isprint (c))
00169     {
00170       dst[0] = c;
00171       dst[1] = '\0';
00172     }
00173   else
00174     (void) sprintf (dst, "%#.3o", (unsigned int) c);
00175 }