190926Snectar/* 2233294Sstas * Copyright (c) 2000 - 2001 Kungliga Tekniska H��gskolan 3233294Sstas * (Royal Institute of Technology, Stockholm, Sweden). 4233294Sstas * All rights reserved. 590926Snectar * 6233294Sstas * Redistribution and use in source and binary forms, with or without 7233294Sstas * modification, are permitted provided that the following conditions 8233294Sstas * are met: 990926Snectar * 10233294Sstas * 1. Redistributions of source code must retain the above copyright 11233294Sstas * notice, this list of conditions and the following disclaimer. 1290926Snectar * 13233294Sstas * 2. Redistributions in binary form must reproduce the above copyright 14233294Sstas * notice, this list of conditions and the following disclaimer in the 15233294Sstas * documentation and/or other materials provided with the distribution. 1690926Snectar * 1790926Snectar * 3. Neither the name of KTH nor the names of its contributors may be 1890926Snectar * used to endorse or promote products derived from this software without 1990926Snectar * specific prior written permission. 2090926Snectar * 2190926Snectar * THIS SOFTWARE IS PROVIDED BY KTH AND ITS CONTRIBUTORS ``AS IS'' AND ANY 2290926Snectar * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2390926Snectar * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 2490926Snectar * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL KTH OR ITS CONTRIBUTORS BE 2590926Snectar * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 2690926Snectar * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 2790926Snectar * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 2890926Snectar * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 2990926Snectar * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 3090926Snectar * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 3190926Snectar * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 3290926Snectar 3390926Snectar#include <config.h> 3490926Snectar#include "roken.h" 3590926Snectar#include <limits.h> 3690926Snectar 3790926Snectarstatic int 3890926Snectartry (const char *format, ...) 3990926Snectar{ 4090926Snectar int ret; 4190926Snectar va_list ap; 4290926Snectar char buf1[256], buf2[256]; 4390926Snectar 4490926Snectar va_start (ap, format); 45233294Sstas ret = rk_vsnprintf (buf1, sizeof(buf1), format, ap); 4690926Snectar if (ret >= sizeof(buf1)) 4790926Snectar errx (1, "increase buf and try again"); 48178825Sdfr va_end (ap); 49178825Sdfr va_start (ap, format); 5090926Snectar vsprintf (buf2, format, ap); 5190926Snectar ret = strcmp (buf1, buf2); 5290926Snectar if (ret) 5390926Snectar printf ("failed: format = \"%s\", \"%s\" != \"%s\"\n", 5490926Snectar format, buf1, buf2); 5590926Snectar va_end (ap); 5690926Snectar return ret; 5790926Snectar} 5890926Snectar 5990926Snectarstatic int 6090926Snectarcmp_with_sprintf_int (void) 6190926Snectar{ 6290926Snectar int tot = 0; 6390926Snectar int int_values[] = {INT_MIN, -17, -1, 0, 1, 17, 4711, 65535, INT_MAX}; 6490926Snectar int i; 6590926Snectar 6690926Snectar for (i = 0; i < sizeof(int_values) / sizeof(int_values[0]); ++i) { 6790926Snectar tot += try ("%d", int_values[i]); 6890926Snectar tot += try ("%x", int_values[i]); 6990926Snectar tot += try ("%X", int_values[i]); 7090926Snectar tot += try ("%o", int_values[i]); 7190926Snectar tot += try ("%#x", int_values[i]); 7290926Snectar tot += try ("%#X", int_values[i]); 7390926Snectar tot += try ("%#o", int_values[i]); 7490926Snectar tot += try ("%10d", int_values[i]); 7590926Snectar tot += try ("%10x", int_values[i]); 7690926Snectar tot += try ("%10X", int_values[i]); 7790926Snectar tot += try ("%10o", int_values[i]); 7890926Snectar tot += try ("%#10x", int_values[i]); 7990926Snectar tot += try ("%#10X", int_values[i]); 8090926Snectar tot += try ("%#10o", int_values[i]); 8190926Snectar tot += try ("%-10d", int_values[i]); 8290926Snectar tot += try ("%-10x", int_values[i]); 8390926Snectar tot += try ("%-10X", int_values[i]); 8490926Snectar tot += try ("%-10o", int_values[i]); 8590926Snectar tot += try ("%-#10x", int_values[i]); 8690926Snectar tot += try ("%-#10X", int_values[i]); 8790926Snectar tot += try ("%-#10o", int_values[i]); 8890926Snectar } 8990926Snectar return tot; 9090926Snectar} 9190926Snectar 9290926Snectarstatic int 9390926Snectarcmp_with_sprintf_long (void) 9490926Snectar{ 9590926Snectar int tot = 0; 9690926Snectar long long_values[] = {LONG_MIN, -17, -1, 0, 1, 17, 4711, 65535, LONG_MAX}; 9790926Snectar int i; 9890926Snectar 9990926Snectar for (i = 0; i < sizeof(long_values) / sizeof(long_values[0]); ++i) { 10090926Snectar tot += try ("%ld", long_values[i]); 10190926Snectar tot += try ("%lx", long_values[i]); 10290926Snectar tot += try ("%lX", long_values[i]); 10390926Snectar tot += try ("%lo", long_values[i]); 10490926Snectar tot += try ("%#lx", long_values[i]); 10590926Snectar tot += try ("%#lX", long_values[i]); 10690926Snectar tot += try ("%#lo", long_values[i]); 10790926Snectar tot += try ("%10ld", long_values[i]); 10890926Snectar tot += try ("%10lx", long_values[i]); 10990926Snectar tot += try ("%10lX", long_values[i]); 11090926Snectar tot += try ("%10lo", long_values[i]); 11190926Snectar tot += try ("%#10lx", long_values[i]); 11290926Snectar tot += try ("%#10lX", long_values[i]); 11390926Snectar tot += try ("%#10lo", long_values[i]); 11490926Snectar tot += try ("%-10ld", long_values[i]); 11590926Snectar tot += try ("%-10lx", long_values[i]); 11690926Snectar tot += try ("%-10lX", long_values[i]); 11790926Snectar tot += try ("%-10lo", long_values[i]); 11890926Snectar tot += try ("%-#10lx", long_values[i]); 11990926Snectar tot += try ("%-#10lX", long_values[i]); 12090926Snectar tot += try ("%-#10lo", long_values[i]); 12190926Snectar } 12290926Snectar return tot; 12390926Snectar} 12490926Snectar 12590926Snectar#ifdef HAVE_LONG_LONG 12690926Snectar 127178825Sdfr/* XXX doesn't work as expected on lp64 platforms with sizeof(long 128178825Sdfr * long) == sizeof(long) */ 129178825Sdfr 13090926Snectarstatic int 13190926Snectarcmp_with_sprintf_long_long (void) 13290926Snectar{ 13390926Snectar int tot = 0; 13490926Snectar long long long_long_values[] = { 13590926Snectar ((long long)LONG_MIN) -1, LONG_MIN, -17, -1, 13690926Snectar 0, 13790926Snectar 1, 17, 4711, 65535, LONG_MAX, ((long long)LONG_MAX) + 1}; 13890926Snectar int i; 13990926Snectar 14090926Snectar for (i = 0; i < sizeof(long_long_values) / sizeof(long_long_values[0]); ++i) { 14190926Snectar tot += try ("%lld", long_long_values[i]); 14290926Snectar tot += try ("%llx", long_long_values[i]); 14390926Snectar tot += try ("%llX", long_long_values[i]); 14490926Snectar tot += try ("%llo", long_long_values[i]); 14590926Snectar tot += try ("%#llx", long_long_values[i]); 14690926Snectar tot += try ("%#llX", long_long_values[i]); 14790926Snectar tot += try ("%#llo", long_long_values[i]); 14890926Snectar tot += try ("%10lld", long_long_values[i]); 14990926Snectar tot += try ("%10llx", long_long_values[i]); 15090926Snectar tot += try ("%10llX", long_long_values[i]); 15190926Snectar tot += try ("%10llo", long_long_values[i]); 15290926Snectar tot += try ("%#10llx", long_long_values[i]); 15390926Snectar tot += try ("%#10llX", long_long_values[i]); 15490926Snectar tot += try ("%#10llo", long_long_values[i]); 15590926Snectar tot += try ("%-10lld", long_long_values[i]); 15690926Snectar tot += try ("%-10llx", long_long_values[i]); 15790926Snectar tot += try ("%-10llX", long_long_values[i]); 15890926Snectar tot += try ("%-10llo", long_long_values[i]); 15990926Snectar tot += try ("%-#10llx", long_long_values[i]); 16090926Snectar tot += try ("%-#10llX", long_long_values[i]); 16190926Snectar tot += try ("%-#10llo", long_long_values[i]); 16290926Snectar } 16390926Snectar return tot; 16490926Snectar} 16590926Snectar 16690926Snectar#endif 16790926Snectar 16890926Snectar#if 0 16990926Snectarstatic int 17090926Snectarcmp_with_sprintf_float (void) 17190926Snectar{ 17290926Snectar int tot = 0; 17390926Snectar double double_values[] = {-99999, -999, -17.4, -4.3, -3.0, -1.5, -1, 17490926Snectar 0, 0.1, 0.2342374852, 0.2340007, 17590926Snectar 3.1415926, 14.7845, 34.24758, 9999, 9999999}; 17690926Snectar int i; 17790926Snectar 17890926Snectar for (i = 0; i < sizeof(double_values) / sizeof(double_values[0]); ++i) { 17990926Snectar tot += try ("%f", double_values[i]); 18090926Snectar tot += try ("%10f", double_values[i]); 18190926Snectar tot += try ("%.2f", double_values[i]); 18290926Snectar tot += try ("%7.0f", double_values[i]); 18390926Snectar tot += try ("%5.2f", double_values[i]); 18490926Snectar tot += try ("%0f", double_values[i]); 18590926Snectar tot += try ("%#f", double_values[i]); 18690926Snectar tot += try ("%e", double_values[i]); 18790926Snectar tot += try ("%10e", double_values[i]); 18890926Snectar tot += try ("%.2e", double_values[i]); 18990926Snectar tot += try ("%7.0e", double_values[i]); 19090926Snectar tot += try ("%5.2e", double_values[i]); 19190926Snectar tot += try ("%0e", double_values[i]); 19290926Snectar tot += try ("%#e", double_values[i]); 19390926Snectar tot += try ("%E", double_values[i]); 19490926Snectar tot += try ("%10E", double_values[i]); 19590926Snectar tot += try ("%.2E", double_values[i]); 19690926Snectar tot += try ("%7.0E", double_values[i]); 19790926Snectar tot += try ("%5.2E", double_values[i]); 19890926Snectar tot += try ("%0E", double_values[i]); 19990926Snectar tot += try ("%#E", double_values[i]); 20090926Snectar tot += try ("%g", double_values[i]); 20190926Snectar tot += try ("%10g", double_values[i]); 20290926Snectar tot += try ("%.2g", double_values[i]); 20390926Snectar tot += try ("%7.0g", double_values[i]); 20490926Snectar tot += try ("%5.2g", double_values[i]); 20590926Snectar tot += try ("%0g", double_values[i]); 20690926Snectar tot += try ("%#g", double_values[i]); 20790926Snectar tot += try ("%G", double_values[i]); 20890926Snectar tot += try ("%10G", double_values[i]); 20990926Snectar tot += try ("%.2G", double_values[i]); 21090926Snectar tot += try ("%7.0G", double_values[i]); 21190926Snectar tot += try ("%5.2G", double_values[i]); 21290926Snectar tot += try ("%0G", double_values[i]); 21390926Snectar tot += try ("%#G", double_values[i]); 21490926Snectar } 21590926Snectar return tot; 21690926Snectar} 21790926Snectar#endif 21890926Snectar 21990926Snectarstatic int 22090926Snectartest_null (void) 22190926Snectar{ 222233294Sstas return rk_snprintf (NULL, 0, "foo") != 3; 22390926Snectar} 22490926Snectar 225178825Sdfrstatic int 226178825Sdfrtest_sizet (void) 227178825Sdfr{ 228178825Sdfr int tot = 0; 229178825Sdfr size_t sizet_values[] = { 0, 1, 2, 200, 4294967295u }; /* SIZE_MAX */ 230178825Sdfr char *result[] = { "0", "1", "2", "200", "4294967295" }; 231178825Sdfr int i; 232178825Sdfr 233178825Sdfr for (i = 0; i < sizeof(sizet_values) / sizeof(sizet_values[0]); ++i) { 234178825Sdfr#if 0 235178825Sdfr tot += try("%zu", sizet_values[i]); 236178825Sdfr tot += try("%zx", sizet_values[i]); 237178825Sdfr tot += try("%zX", sizet_values[i]); 238178825Sdfr#else 239178825Sdfr char buf[256]; 240233294Sstas rk_snprintf(buf, sizeof(buf), "%zu", sizet_values[i]); 241178825Sdfr if (strcmp(buf, result[i]) != 0) { 242178825Sdfr printf("%s != %s", buf, result[i]); 243178825Sdfr tot++; 244178825Sdfr } 245178825Sdfr#endif 246178825Sdfr } 247178825Sdfr return tot; 248178825Sdfr} 249178825Sdfr 250178825Sdfr 25190926Snectarint 25290926Snectarmain (int argc, char **argv) 25390926Snectar{ 25490926Snectar int ret = 0; 25590926Snectar 25690926Snectar ret += cmp_with_sprintf_int (); 25790926Snectar ret += cmp_with_sprintf_long (); 25890926Snectar#ifdef HAVE_LONG_LONG 25990926Snectar ret += cmp_with_sprintf_long_long (); 26090926Snectar#endif 26190926Snectar ret += test_null (); 262178825Sdfr ret += test_sizet (); 26390926Snectar return ret; 26490926Snectar} 265