14137ff4cSJacques Vidrine /*
24137ff4cSJacques Vidrine  * Copyright (c) 2000 - 2001 Kungliga Tekniska Högskolan
34137ff4cSJacques Vidrine  * (Royal Institute of Technology, Stockholm, Sweden).
44137ff4cSJacques Vidrine  * All rights reserved.
54137ff4cSJacques Vidrine  *
64137ff4cSJacques Vidrine  * Redistribution and use in source and binary forms, with or without
74137ff4cSJacques Vidrine  * modification, are permitted provided that the following conditions
84137ff4cSJacques Vidrine  * are met:
94137ff4cSJacques Vidrine  *
104137ff4cSJacques Vidrine  * 1. Redistributions of source code must retain the above copyright
114137ff4cSJacques Vidrine  *    notice, this list of conditions and the following disclaimer.
124137ff4cSJacques Vidrine  *
134137ff4cSJacques Vidrine  * 2. Redistributions in binary form must reproduce the above copyright
144137ff4cSJacques Vidrine  *    notice, this list of conditions and the following disclaimer in the
154137ff4cSJacques Vidrine  *    documentation and/or other materials provided with the distribution.
164137ff4cSJacques Vidrine  *
174137ff4cSJacques Vidrine  * 3. Neither the name of KTH nor the names of its contributors may be
184137ff4cSJacques Vidrine  *    used to endorse or promote products derived from this software without
194137ff4cSJacques Vidrine  *    specific prior written permission.
204137ff4cSJacques Vidrine  *
214137ff4cSJacques Vidrine  * THIS SOFTWARE IS PROVIDED BY KTH AND ITS CONTRIBUTORS ``AS IS'' AND ANY
224137ff4cSJacques Vidrine  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
234137ff4cSJacques Vidrine  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
244137ff4cSJacques Vidrine  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL KTH OR ITS CONTRIBUTORS BE
254137ff4cSJacques Vidrine  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
264137ff4cSJacques Vidrine  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
274137ff4cSJacques Vidrine  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
284137ff4cSJacques Vidrine  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
294137ff4cSJacques Vidrine  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
304137ff4cSJacques Vidrine  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
314137ff4cSJacques Vidrine  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
324137ff4cSJacques Vidrine 
334137ff4cSJacques Vidrine #include <config.h>
344137ff4cSJacques Vidrine #include "roken.h"
354137ff4cSJacques Vidrine #include <limits.h>
36c19800e8SDoug Rabson 
374137ff4cSJacques Vidrine static int
try(const char * format,...)384137ff4cSJacques Vidrine try (const char *format, ...)
394137ff4cSJacques Vidrine {
40c19800e8SDoug Rabson     int ret;
414137ff4cSJacques Vidrine     va_list ap;
424137ff4cSJacques Vidrine     char buf1[256], buf2[256];
434137ff4cSJacques Vidrine 
444137ff4cSJacques Vidrine     va_start (ap, format);
454137ff4cSJacques Vidrine     ret = rk_vsnprintf (buf1, sizeof(buf1), format, ap);
464137ff4cSJacques Vidrine     if (ret >= sizeof(buf1))
474137ff4cSJacques Vidrine 	errx (1, "increase buf and try again");
484137ff4cSJacques Vidrine     va_end (ap);
494137ff4cSJacques Vidrine     va_start (ap, format);
504137ff4cSJacques Vidrine     vsprintf (buf2, format, ap);
514137ff4cSJacques Vidrine     ret = strcmp (buf1, buf2);
524137ff4cSJacques Vidrine     if (ret)
53c19800e8SDoug Rabson 	printf ("failed: format = \"%s\", \"%s\" != \"%s\"\n",
54c19800e8SDoug Rabson 		format, buf1, buf2);
554137ff4cSJacques Vidrine     va_end (ap);
564137ff4cSJacques Vidrine     return ret;
574137ff4cSJacques Vidrine }
584137ff4cSJacques Vidrine 
594137ff4cSJacques Vidrine static int
cmp_with_sprintf_int(void)604137ff4cSJacques Vidrine cmp_with_sprintf_int (void)
614137ff4cSJacques Vidrine {
624137ff4cSJacques Vidrine     int tot = 0;
634137ff4cSJacques Vidrine     int int_values[] = {INT_MIN, -17, -1, 0, 1, 17, 4711, 65535, INT_MAX};
644137ff4cSJacques Vidrine     int i;
654137ff4cSJacques Vidrine 
664137ff4cSJacques Vidrine     for (i = 0; i < sizeof(int_values) / sizeof(int_values[0]); ++i) {
674137ff4cSJacques Vidrine 	tot += try ("%d", int_values[i]);
684137ff4cSJacques Vidrine 	tot += try ("%x", int_values[i]);
694137ff4cSJacques Vidrine 	tot += try ("%X", int_values[i]);
704137ff4cSJacques Vidrine 	tot += try ("%o", int_values[i]);
714137ff4cSJacques Vidrine 	tot += try ("%#x", int_values[i]);
724137ff4cSJacques Vidrine 	tot += try ("%#X", int_values[i]);
734137ff4cSJacques Vidrine 	tot += try ("%#o", int_values[i]);
744137ff4cSJacques Vidrine 	tot += try ("%10d", int_values[i]);
754137ff4cSJacques Vidrine 	tot += try ("%10x", int_values[i]);
764137ff4cSJacques Vidrine 	tot += try ("%10X", int_values[i]);
774137ff4cSJacques Vidrine 	tot += try ("%10o", int_values[i]);
784137ff4cSJacques Vidrine 	tot += try ("%#10x", int_values[i]);
794137ff4cSJacques Vidrine 	tot += try ("%#10X", int_values[i]);
804137ff4cSJacques Vidrine 	tot += try ("%#10o", int_values[i]);
814137ff4cSJacques Vidrine 	tot += try ("%-10d", int_values[i]);
824137ff4cSJacques Vidrine 	tot += try ("%-10x", int_values[i]);
834137ff4cSJacques Vidrine 	tot += try ("%-10X", int_values[i]);
844137ff4cSJacques Vidrine 	tot += try ("%-10o", int_values[i]);
854137ff4cSJacques Vidrine 	tot += try ("%-#10x", int_values[i]);
864137ff4cSJacques Vidrine 	tot += try ("%-#10X", int_values[i]);
874137ff4cSJacques Vidrine 	tot += try ("%-#10o", int_values[i]);
884137ff4cSJacques Vidrine     }
894137ff4cSJacques Vidrine     return tot;
904137ff4cSJacques Vidrine }
914137ff4cSJacques Vidrine 
924137ff4cSJacques Vidrine static int
cmp_with_sprintf_long(void)934137ff4cSJacques Vidrine cmp_with_sprintf_long (void)
944137ff4cSJacques Vidrine {
954137ff4cSJacques Vidrine     int tot = 0;
964137ff4cSJacques Vidrine     long long_values[] = {LONG_MIN, -17, -1, 0, 1, 17, 4711, 65535, LONG_MAX};
974137ff4cSJacques Vidrine     int i;
984137ff4cSJacques Vidrine 
994137ff4cSJacques Vidrine     for (i = 0; i < sizeof(long_values) / sizeof(long_values[0]); ++i) {
1004137ff4cSJacques Vidrine 	tot += try ("%ld", long_values[i]);
1014137ff4cSJacques Vidrine 	tot += try ("%lx", long_values[i]);
1024137ff4cSJacques Vidrine 	tot += try ("%lX", long_values[i]);
1034137ff4cSJacques Vidrine 	tot += try ("%lo", long_values[i]);
1044137ff4cSJacques Vidrine 	tot += try ("%#lx", long_values[i]);
1054137ff4cSJacques Vidrine 	tot += try ("%#lX", long_values[i]);
1064137ff4cSJacques Vidrine 	tot += try ("%#lo", long_values[i]);
1074137ff4cSJacques Vidrine 	tot += try ("%10ld", long_values[i]);
1084137ff4cSJacques Vidrine 	tot += try ("%10lx", long_values[i]);
1094137ff4cSJacques Vidrine 	tot += try ("%10lX", long_values[i]);
1104137ff4cSJacques Vidrine 	tot += try ("%10lo", long_values[i]);
1114137ff4cSJacques Vidrine 	tot += try ("%#10lx", long_values[i]);
1124137ff4cSJacques Vidrine 	tot += try ("%#10lX", long_values[i]);
1134137ff4cSJacques Vidrine 	tot += try ("%#10lo", long_values[i]);
1144137ff4cSJacques Vidrine 	tot += try ("%-10ld", long_values[i]);
1154137ff4cSJacques Vidrine 	tot += try ("%-10lx", long_values[i]);
1164137ff4cSJacques Vidrine 	tot += try ("%-10lX", long_values[i]);
1174137ff4cSJacques Vidrine 	tot += try ("%-10lo", long_values[i]);
1184137ff4cSJacques Vidrine 	tot += try ("%-#10lx", long_values[i]);
1194137ff4cSJacques Vidrine 	tot += try ("%-#10lX", long_values[i]);
1204137ff4cSJacques Vidrine 	tot += try ("%-#10lo", long_values[i]);
1214137ff4cSJacques Vidrine     }
1224137ff4cSJacques Vidrine     return tot;
1234137ff4cSJacques Vidrine }
1244137ff4cSJacques Vidrine 
1254137ff4cSJacques Vidrine #ifdef HAVE_LONG_LONG
1264137ff4cSJacques Vidrine 
1274137ff4cSJacques Vidrine /* XXX doesn't work as expected on lp64 platforms with sizeof(long
1284137ff4cSJacques Vidrine  * long) == sizeof(long) */
1294137ff4cSJacques Vidrine 
1304137ff4cSJacques Vidrine static int
cmp_with_sprintf_long_long(void)1314137ff4cSJacques Vidrine cmp_with_sprintf_long_long (void)
132c19800e8SDoug Rabson {
133c19800e8SDoug Rabson     int tot = 0;
134c19800e8SDoug Rabson     long long long_long_values[] = {
1354137ff4cSJacques Vidrine 	((long long)LONG_MIN) -1, LONG_MIN, -17, -1,
1364137ff4cSJacques Vidrine 	0,
1374137ff4cSJacques Vidrine 	1, 17, 4711, 65535, LONG_MAX, ((long long)LONG_MAX) + 1};
1384137ff4cSJacques Vidrine     int i;
1394137ff4cSJacques Vidrine 
1404137ff4cSJacques Vidrine     for (i = 0; i < sizeof(long_long_values) / sizeof(long_long_values[0]); ++i) {
1414137ff4cSJacques Vidrine 	tot += try ("%lld", long_long_values[i]);
1424137ff4cSJacques Vidrine 	tot += try ("%llx", long_long_values[i]);
1434137ff4cSJacques Vidrine 	tot += try ("%llX", long_long_values[i]);
1444137ff4cSJacques Vidrine 	tot += try ("%llo", long_long_values[i]);
1454137ff4cSJacques Vidrine 	tot += try ("%#llx", long_long_values[i]);
1464137ff4cSJacques Vidrine 	tot += try ("%#llX", long_long_values[i]);
1474137ff4cSJacques Vidrine 	tot += try ("%#llo", long_long_values[i]);
1484137ff4cSJacques Vidrine 	tot += try ("%10lld", long_long_values[i]);
1494137ff4cSJacques Vidrine 	tot += try ("%10llx", long_long_values[i]);
1504137ff4cSJacques Vidrine 	tot += try ("%10llX", long_long_values[i]);
1514137ff4cSJacques Vidrine 	tot += try ("%10llo", long_long_values[i]);
1524137ff4cSJacques Vidrine 	tot += try ("%#10llx", long_long_values[i]);
1534137ff4cSJacques Vidrine 	tot += try ("%#10llX", long_long_values[i]);
1544137ff4cSJacques Vidrine 	tot += try ("%#10llo", long_long_values[i]);
1554137ff4cSJacques Vidrine 	tot += try ("%-10lld", long_long_values[i]);
1564137ff4cSJacques Vidrine 	tot += try ("%-10llx", long_long_values[i]);
1574137ff4cSJacques Vidrine 	tot += try ("%-10llX", long_long_values[i]);
1584137ff4cSJacques Vidrine 	tot += try ("%-10llo", long_long_values[i]);
1594137ff4cSJacques Vidrine 	tot += try ("%-#10llx", long_long_values[i]);
1604137ff4cSJacques Vidrine 	tot += try ("%-#10llX", long_long_values[i]);
1614137ff4cSJacques Vidrine 	tot += try ("%-#10llo", long_long_values[i]);
1624137ff4cSJacques Vidrine     }
1634137ff4cSJacques Vidrine     return tot;
1644137ff4cSJacques Vidrine }
1654137ff4cSJacques Vidrine 
1664137ff4cSJacques Vidrine #endif
1674137ff4cSJacques Vidrine 
1684137ff4cSJacques Vidrine #if 0
1694137ff4cSJacques Vidrine static int
1704137ff4cSJacques Vidrine cmp_with_sprintf_float (void)
1714137ff4cSJacques Vidrine {
1724137ff4cSJacques Vidrine     int tot = 0;
1734137ff4cSJacques Vidrine     double double_values[] = {-99999, -999, -17.4, -4.3, -3.0, -1.5, -1,
1744137ff4cSJacques Vidrine 			      0, 0.1, 0.2342374852, 0.2340007,
1754137ff4cSJacques Vidrine 			      3.1415926, 14.7845, 34.24758, 9999, 9999999};
1764137ff4cSJacques Vidrine     int i;
1774137ff4cSJacques Vidrine 
1784137ff4cSJacques Vidrine     for (i = 0; i < sizeof(double_values) / sizeof(double_values[0]); ++i) {
1794137ff4cSJacques Vidrine 	tot += try ("%f", double_values[i]);
1804137ff4cSJacques Vidrine 	tot += try ("%10f", double_values[i]);
1814137ff4cSJacques Vidrine 	tot += try ("%.2f", double_values[i]);
1824137ff4cSJacques Vidrine 	tot += try ("%7.0f", double_values[i]);
1834137ff4cSJacques Vidrine 	tot += try ("%5.2f", double_values[i]);
1844137ff4cSJacques Vidrine 	tot += try ("%0f", double_values[i]);
1854137ff4cSJacques Vidrine 	tot += try ("%#f", double_values[i]);
1864137ff4cSJacques Vidrine 	tot += try ("%e", double_values[i]);
1874137ff4cSJacques Vidrine 	tot += try ("%10e", double_values[i]);
1884137ff4cSJacques Vidrine 	tot += try ("%.2e", double_values[i]);
1894137ff4cSJacques Vidrine 	tot += try ("%7.0e", double_values[i]);
1904137ff4cSJacques Vidrine 	tot += try ("%5.2e", double_values[i]);
1914137ff4cSJacques Vidrine 	tot += try ("%0e", double_values[i]);
1924137ff4cSJacques Vidrine 	tot += try ("%#e", double_values[i]);
1934137ff4cSJacques Vidrine 	tot += try ("%E", double_values[i]);
1944137ff4cSJacques Vidrine 	tot += try ("%10E", double_values[i]);
1954137ff4cSJacques Vidrine 	tot += try ("%.2E", double_values[i]);
1964137ff4cSJacques Vidrine 	tot += try ("%7.0E", double_values[i]);
1974137ff4cSJacques Vidrine 	tot += try ("%5.2E", double_values[i]);
1984137ff4cSJacques Vidrine 	tot += try ("%0E", double_values[i]);
1994137ff4cSJacques Vidrine 	tot += try ("%#E", double_values[i]);
2004137ff4cSJacques Vidrine 	tot += try ("%g", double_values[i]);
2014137ff4cSJacques Vidrine 	tot += try ("%10g", double_values[i]);
2024137ff4cSJacques Vidrine 	tot += try ("%.2g", double_values[i]);
2034137ff4cSJacques Vidrine 	tot += try ("%7.0g", double_values[i]);
2044137ff4cSJacques Vidrine 	tot += try ("%5.2g", double_values[i]);
2054137ff4cSJacques Vidrine 	tot += try ("%0g", double_values[i]);
2064137ff4cSJacques Vidrine 	tot += try ("%#g", double_values[i]);
2074137ff4cSJacques Vidrine 	tot += try ("%G", double_values[i]);
2084137ff4cSJacques Vidrine 	tot += try ("%10G", double_values[i]);
2094137ff4cSJacques Vidrine 	tot += try ("%.2G", double_values[i]);
2104137ff4cSJacques Vidrine 	tot += try ("%7.0G", double_values[i]);
2114137ff4cSJacques Vidrine 	tot += try ("%5.2G", double_values[i]);
2124137ff4cSJacques Vidrine 	tot += try ("%0G", double_values[i]);
2134137ff4cSJacques Vidrine 	tot += try ("%#G", double_values[i]);
2144137ff4cSJacques Vidrine     }
2154137ff4cSJacques Vidrine     return tot;
2164137ff4cSJacques Vidrine }
2174137ff4cSJacques Vidrine #endif
2184137ff4cSJacques Vidrine 
2194137ff4cSJacques Vidrine static int
test_null(void)2204137ff4cSJacques Vidrine test_null (void)
2214137ff4cSJacques Vidrine {
2224137ff4cSJacques Vidrine     return rk_snprintf (NULL, 0, "foo") != 3;
2234137ff4cSJacques Vidrine }
2244137ff4cSJacques Vidrine 
2254137ff4cSJacques Vidrine static int
test_sizet(void)2264137ff4cSJacques Vidrine test_sizet (void)
2274137ff4cSJacques Vidrine {
2284137ff4cSJacques Vidrine     int tot = 0;
2294137ff4cSJacques Vidrine     size_t sizet_values[] = { 0, 1, 2, 200, 4294967295u }; /* SIZE_MAX */
230c19800e8SDoug Rabson     char *result[] = { "0", "1", "2", "200", "4294967295" };
231c19800e8SDoug Rabson     int i;
232c19800e8SDoug Rabson 
233c19800e8SDoug Rabson     for (i = 0; i < sizeof(sizet_values) / sizeof(sizet_values[0]); ++i) {
234c19800e8SDoug Rabson #if 0
235c19800e8SDoug Rabson 	tot += try("%zu", sizet_values[i]);
236c19800e8SDoug Rabson 	tot += try("%zx", sizet_values[i]);
237c19800e8SDoug Rabson 	tot += try("%zX", sizet_values[i]);
238c19800e8SDoug Rabson #else
239c19800e8SDoug Rabson 	char buf[256];
240c19800e8SDoug Rabson 	rk_snprintf(buf, sizeof(buf), "%zu", sizet_values[i]);
241c19800e8SDoug Rabson 	if (strcmp(buf, result[i]) != 0) {
242c19800e8SDoug Rabson 	    printf("%s != %s", buf, result[i]);
243c19800e8SDoug Rabson 	    tot++;
244c19800e8SDoug Rabson 	}
245c19800e8SDoug Rabson #endif
246c19800e8SDoug Rabson     }
247c19800e8SDoug Rabson     return tot;
248c19800e8SDoug Rabson }
249c19800e8SDoug Rabson 
250c19800e8SDoug Rabson 
251c19800e8SDoug Rabson int
main(int argc,char ** argv)252c19800e8SDoug Rabson main (int argc, char **argv)
253c19800e8SDoug Rabson {
254c19800e8SDoug Rabson     int ret = 0;
255c19800e8SDoug Rabson 
2564137ff4cSJacques Vidrine     ret += cmp_with_sprintf_int ();
2574137ff4cSJacques Vidrine     ret += cmp_with_sprintf_long ();
2584137ff4cSJacques Vidrine #ifdef HAVE_LONG_LONG
2594137ff4cSJacques Vidrine     ret += cmp_with_sprintf_long_long ();
2604137ff4cSJacques Vidrine #endif
2614137ff4cSJacques Vidrine     ret += test_null ();
2624137ff4cSJacques Vidrine     ret += test_sizet ();
2634137ff4cSJacques Vidrine     return ret;
2644137ff4cSJacques Vidrine }
2654137ff4cSJacques Vidrine