t_fmtcheck.c revision 1.6
11.6Srillig/*	$NetBSD: t_fmtcheck.c,v 1.6 2024/04/13 14:02:51 rillig Exp $	*/
21.1Spgoyette
31.1Spgoyette/*-
41.1Spgoyette * Copyright (c) 2000 The NetBSD Foundation, Inc.
51.1Spgoyette * All rights reserved.
61.1Spgoyette *
71.1Spgoyette * This code was contributed to The NetBSD Foundation by Allen Briggs.
81.1Spgoyette *
91.1Spgoyette * Redistribution and use in source and binary forms, with or without
101.1Spgoyette * modification, are permitted provided that the following conditions
111.1Spgoyette * are met:
121.1Spgoyette * 1. Redistributions of source code must retain the above copyright
131.1Spgoyette *    notice, this list of conditions and the following disclaimer.
141.1Spgoyette * 2. Redistributions in binary form must reproduce the above copyright
151.1Spgoyette *    notice, this list of conditions and the following disclaimer in the
161.1Spgoyette *    documentation and/or other materials provided with the distribution.
171.1Spgoyette *
181.1Spgoyette * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
191.1Spgoyette * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
201.1Spgoyette * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
211.1Spgoyette * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
221.1Spgoyette * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
231.1Spgoyette * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
241.1Spgoyette * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
251.1Spgoyette * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
261.1Spgoyette * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
271.1Spgoyette * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
281.1Spgoyette * POSSIBILITY OF SUCH DAMAGE.
291.1Spgoyette */
301.1Spgoyette
311.1Spgoyette#include <atf-c.h>
321.1Spgoyette
331.1Spgoyette#include <stdio.h>
341.1Spgoyette#include <stdlib.h>
351.1Spgoyette
361.1Spgoyetteconst char *fmtcheck(const char *f1, const char *f2)
371.1Spgoyette                __attribute__((__format_arg__(2)));
381.1Spgoyette
391.1Spgoyette#include <err.h>
401.1Spgoyette
411.1Spgoyettestruct test_fmt {
421.1Spgoyette	const char	*fmt1;
431.1Spgoyette	const char	*fmt2;
441.1Spgoyette	int		correct;
451.1Spgoyette} test_fmts[] = {
461.1Spgoyette	{ "%d", "%d", 1 },
471.1Spgoyette	{ "%2d", "%2.2d", 1 },
481.1Spgoyette	{ "%x", "%d", 1 },
491.1Spgoyette	{ "%u", "%d", 1 },
501.1Spgoyette	{ "%03d", "%d", 1 },
511.1Spgoyette	{ "%-2d", "%d", 1 },
521.1Spgoyette	{ "%d", "%-12.1d", 1 },
531.1Spgoyette	{ "%d", "%-01.3d", 1 },
541.1Spgoyette	{ "%X", "%-01.3d", 1 },
551.1Spgoyette	{ "%D", "%ld", 1 },
561.1Spgoyette	{ "%s", "%s", 1 },
571.1Spgoyette	{ "%s", "This is a %s test", 1 },
581.1Spgoyette	{ "Hi, there.  This is a %s test", "%s", 1 },
591.1Spgoyette	{ "%d", "%s", 2 },
601.1Spgoyette	{ "%e", "%s", 2 },
611.1Spgoyette	{ "%r", "%d", 2 },
621.1Spgoyette	{ "%*.2d", "%*d", 1 },
631.1Spgoyette	{ "%2.*d", "%*d", 2 },
641.1Spgoyette	{ "%*d", "%*d", 1 },
651.1Spgoyette	{ "%-3", "%d", 2 },
661.1Spgoyette	{ "%d %s", "%d", 2 },
671.1Spgoyette	{ "%*.*.*d", "%*.*.*d", 2 },
681.5Srin	{ "%d", "%d %s", 1 },
691.1Spgoyette	{ "%40s", "%20s", 1 },
701.1Spgoyette	{ "%x %x %x", "%o %u %d", 1 },
711.1Spgoyette	{ "%o %u %d", "%x %x %X", 1 },
721.1Spgoyette	{ "%#o %u %#-d", "%x %#x %X", 1 },
731.1Spgoyette	{ "%qd", "%llx", 1 },
741.5Srin	{ "%%", "%llx", 1 },
751.3Sapb	{ "%ld %30s %#llx %-10.*e", "This number %lu%% and string %s has %qd numbers and %.*g floats", 1 },
761.3Sapb	{ "%o", "%lx", 2 },
771.3Sapb	{ "%p", "%lu", 2 },
781.6Srillig	// When fmtcheck supports '$', it could be used in dcngettext.
791.6Srillig	{ "%1$s", "%s", 2 },
801.6Srillig	{ "%1$s %2$s", "%s %s", 2 },
811.6Srillig	{ "%2$d %1$s", "%s %d", 2 },
821.1Spgoyette};
831.1Spgoyette
841.2SjruohoATF_TC(fmtcheck_basic);
851.2SjruohoATF_TC_HEAD(fmtcheck_basic, tc)
861.1Spgoyette{
871.1Spgoyette
881.1Spgoyette	atf_tc_set_md_var(tc, "descr", "Test fmtcheck(3)");
891.1Spgoyette}
901.1Spgoyette
911.2SjruohoATF_TC_BODY(fmtcheck_basic, tc)
921.1Spgoyette{
931.1Spgoyette	unsigned int	i, r;
941.1Spgoyette	const char	*f, *cf, *f1, *f2;
951.1Spgoyette
961.1Spgoyette	r = 0;
971.1Spgoyette	for (i = 0 ; i < __arraycount(test_fmts); i++) {
981.1Spgoyette		f1 = test_fmts[i].fmt1;
991.1Spgoyette		f2 = test_fmts[i].fmt2;
1001.1Spgoyette		f = fmtcheck(f1, f2);
1011.1Spgoyette		if (test_fmts[i].correct == 1) {
1021.1Spgoyette			cf = f1;
1031.1Spgoyette		} else {
1041.1Spgoyette			cf = f2;
1051.1Spgoyette		}
1061.1Spgoyette		if (f != cf) {
1071.1Spgoyette			r++;
1081.1Spgoyette			atf_tc_fail_nonfatal("Test %d: (%s) vs. (%s) failed "
1091.1Spgoyette			    "(should have returned %s)", i, f1, f2,
1101.1Spgoyette			    (test_fmts[i].correct == 1) ? "1st" : "2nd");
1111.1Spgoyette		}
1121.1Spgoyette	}
1131.1Spgoyette}
1141.1Spgoyette
1151.1SpgoyetteATF_TP_ADD_TCS(tp)
1161.1Spgoyette{
1171.1Spgoyette
1181.2Sjruoho	ATF_TP_ADD_TC(tp, fmtcheck_basic);
1191.1Spgoyette
1201.1Spgoyette	return atf_no_error();
1211.1Spgoyette}
122