1/*	$NetBSD: bug-2803.c,v 1.2 2020/05/25 20:47:37 christos Exp $	*/
2
3#include <config.h>
4
5#include <stdio.h>
6#include <sys/time.h>
7
8#include <ntp_fp.h>
9#include <timevalops.h>
10
11/* microseconds per second */
12#define MICROSECONDS 1000000
13
14
15static int verbose = 1;        // if not 0, also print results if test passed
16static int exit_on_err = 0;    // if not 0, exit if test failed
17
18
19/*
20 * Test function calling the old and new code mentioned in
21 * http://bugs.ntp.org/show_bug.cgi?id=2803#c22
22 */
23static
24int do_test( struct timeval timetv, struct timeval tvlast )
25{
26	struct timeval tvdiff_old;
27	struct timeval tvdiff_new;
28
29	int cond_old;
30	int cond_new;
31	int failed;
32
33	cond_old = 0;
34	cond_new = 0;
35
36	// Here is the old code:
37	tvdiff_old = abs_tval(sub_tval(timetv, tvlast));
38	if (tvdiff_old.tv_sec > 0) {
39		cond_old = 1;
40	}
41
42	// Here is the new code:
43	tvdiff_new = sub_tval(timetv, tvlast);
44	if (tvdiff_new.tv_sec != 0) {
45		cond_new = 1;
46	}
47
48	failed = cond_new != cond_old;
49
50	if ( failed || verbose )
51		printf( "timetv %lli|%07li, tvlast  %lli|%07li: tvdiff_old: %lli|%07li -> %i, tvdiff_new: %lli|%07li -> %i, same cond: %s\n",
52			(long long) timetv.tv_sec, timetv.tv_usec,
53			(long long) tvlast.tv_sec, tvlast.tv_usec,
54			(long long) tvdiff_old.tv_sec, tvdiff_old.tv_usec, cond_old,
55			(long long) tvdiff_new.tv_sec, tvdiff_new.tv_usec, cond_new,
56			failed ? "NO <<" : "yes" );
57
58	return failed ? -1 : 0;
59}
60
61
62
63/*
64 * Call the test function in a loop for a given set of parameters.
65 * Both timetv and tvlast iterate over the given range, in all combinations.
66 */
67static
68int test_loop( long long start_sec, long start_usec,
69	       long long stop_sec, long stop_usec,
70	       long long step_sec, long step_usec )
71{
72	struct timeval timetv;
73	struct timeval tvlast;
74
75	for ( timetv.tv_sec = start_sec; timetv.tv_sec <= stop_sec; timetv.tv_sec += step_sec )
76	  for ( timetv.tv_usec = start_usec; timetv.tv_usec <= stop_usec; timetv.tv_usec += step_usec )
77	    for ( tvlast.tv_sec = start_sec; tvlast.tv_sec <= stop_sec; tvlast.tv_sec += step_sec )
78	      for ( tvlast.tv_usec = start_usec; tvlast.tv_usec <= stop_usec; tvlast.tv_usec += step_usec )
79	      {
80		int rc = do_test( timetv, tvlast );
81		if (rc < 0 && exit_on_err )
82			return rc;
83	      }
84
85	return 0;
86}
87
88
89
90int main2( void )
91{
92
93	// loop from {0.0} to {1.1000000} stepping by tv_sec by 1 and tv_usec by 100000
94	test_loop( 0, 0,   1,  MICROSECONDS,   1,  MICROSECONDS / 10 );
95
96	// test_loop( 0, 0,   5,  MICROSECONDS,   1,  MICROSECONDS / 1000 );
97	// test_loop( 0, 0,  -5, -MICROSECONDS,  -1, -MICROSECONDS / 1000 );
98
99	return 0;
100}
101
102