Home | History | Annotate | Line # | Download | only in libntp
timespecops.c revision 1.1.1.4
      1 #include "config.h"
      2 
      3 #include "ntp_types.h"
      4 #include "ntp_fp.h"
      5 #include "timespecops.h"
      6 
      7 #include "unity.h"
      8 
      9 #include <math.h>
     10 #include <string.h>
     11 
     12 
     13 #define TEST_ASSERT_EQUAL_timespec(a, b) {				\
     14     TEST_ASSERT_EQUAL_MESSAGE(a.tv_sec, b.tv_sec, "Field tv_sec");	\
     15     TEST_ASSERT_EQUAL_MESSAGE(a.tv_nsec, b.tv_nsec, "Field tv_nsec");	\
     16 }
     17 
     18 
     19 #define TEST_ASSERT_EQUAL_l_fp(a, b) {					\
     20     TEST_ASSERT_EQUAL_MESSAGE(a.l_i, b.l_i, "Field l_i");		\
     21     TEST_ASSERT_EQUAL_UINT_MESSAGE(a.l_uf, b.l_uf, "Field l_uf");	\
     22 }
     23 
     24 
     25 static u_int32 my_tick_to_tsf(u_int32 ticks);
     26 static u_int32 my_tsf_to_tick(u_int32 tsf);
     27 
     28 
     29 // that's it...
     30 struct lfpfracdata {
     31 	long	nsec;
     32 	u_int32 frac;
     33 };
     34 
     35 
     36 void setUp(void);
     37 void test_Helpers1(void);
     38 void test_Normalise(void);
     39 void test_SignNoFrac(void);
     40 void test_SignWithFrac(void);
     41 void test_CmpFracEQ(void);
     42 void test_CmpFracGT(void);
     43 void test_CmpFracLT(void);
     44 void test_AddFullNorm(void);
     45 void test_AddFullOflow1(void);
     46 void test_AddNsecNorm(void);
     47 void test_AddNsecOflow1(void);
     48 void test_SubFullNorm(void);
     49 void test_SubFullOflow(void);
     50 void test_SubNsecNorm(void);
     51 void test_SubNsecOflow(void);
     52 void test_Neg(void);
     53 void test_AbsNoFrac(void);
     54 void test_AbsWithFrac(void);
     55 void test_Helpers2(void);
     56 void test_ToLFPbittest(void);
     57 void test_ToLFPrelPos(void);
     58 void test_ToLFPrelNeg(void);
     59 void test_ToLFPabs(void);
     60 void test_FromLFPbittest(void);
     61 void test_FromLFPrelPos(void);
     62 void test_FromLFPrelNeg(void);
     63 void test_LFProundtrip(void);
     64 void test_ToString(void);
     65 
     66 typedef int bool;
     67 
     68 const bool	timespec_isValid(struct timespec V);
     69 struct timespec timespec_init(time_t hi, long lo);
     70 l_fp		l_fp_init(int32 i, u_int32 f);
     71 bool		AssertFpClose(const l_fp m, const l_fp n, const l_fp limit);
     72 bool		AssertTimespecClose(const struct timespec m,
     73 				    const struct timespec n,
     74 				    const struct timespec limit);
     75 
     76 
     77 //***************************MY CUSTOM FUNCTIONS***************************
     78 
     79 
     80 void
     81 setUp(void)
     82 {
     83 	init_lib();
     84 
     85 	return;
     86 }
     87 
     88 
     89 const bool
     90 timespec_isValid(struct timespec V)
     91 {
     92 
     93 	return V.tv_nsec >= 0 && V.tv_nsec < 1000000000;
     94 }
     95 
     96 
     97 struct timespec
     98 timespec_init(time_t hi, long lo)
     99 {
    100 	struct timespec V;
    101 
    102 	V.tv_sec = hi;
    103 	V.tv_nsec = lo;
    104 
    105 	return V;
    106 }
    107 
    108 
    109 l_fp
    110 l_fp_init(int32 i, u_int32 f)
    111 {
    112 	l_fp temp;
    113 
    114 	temp.l_i  = i;
    115 	temp.l_uf = f;
    116 
    117 	return temp;
    118 }
    119 
    120 
    121 bool
    122 AssertFpClose(const l_fp m, const l_fp n, const l_fp limit)
    123 {
    124 	l_fp diff;
    125 
    126 	if (L_ISGEQ(&m, &n)) {
    127 		diff = m;
    128 		L_SUB(&diff, &n);
    129 	} else {
    130 		diff = n;
    131 		L_SUB(&diff, &m);
    132 	}
    133 	if (L_ISGEQ(&limit, &diff)) {
    134 		return TRUE;
    135 	}
    136 	else {
    137 		printf("m_expr which is %s \nand\nn_expr which is %s\nare not close; diff=%susec\n", lfptoa(&m, 10), lfptoa(&n, 10), lfptoa(&diff, 10));
    138 		return FALSE;
    139 	}
    140 }
    141 
    142 
    143 bool
    144 AssertTimespecClose(const struct timespec m, const struct timespec n,
    145 	const struct timespec limit)
    146 {
    147 	struct timespec diff;
    148 
    149 	diff = abs_tspec(sub_tspec(m, n));
    150 	if (cmp_tspec(limit, diff) >= 0)
    151 		return TRUE;
    152 	else
    153 	{
    154 		printf("m_expr which is %ld.%lu \nand\nn_expr which is %ld.%lu\nare not close; diff=%ld.%lunsec\n", m.tv_sec, m.tv_nsec, n.tv_sec, n.tv_nsec, diff.tv_sec, diff.tv_nsec);
    155 		return FALSE;
    156 	}
    157 }
    158 
    159 //-----------------------------------------------
    160 
    161 static const struct lfpfracdata fdata[] = {
    162 	{	  0, 0x00000000 }, {   2218896, 0x00916ae6 },
    163 	{  16408100, 0x0433523d }, { 125000000, 0x20000000 },
    164 	{ 250000000, 0x40000000 }, { 287455871, 0x4996b53d },
    165 	{ 375000000, 0x60000000 }, { 500000000, 0x80000000 },
    166 	{ 518978897, 0x84dbcd0e }, { 563730222, 0x90509fb3 },
    167 	{ 563788007, 0x9054692c }, { 583289882, 0x95527c57 },
    168 	{ 607074509, 0x9b693c2a }, { 625000000, 0xa0000000 },
    169 	{ 645184059, 0xa52ac851 }, { 676497788, 0xad2ef583 },
    170 	{ 678910895, 0xadcd1abb }, { 679569625, 0xadf84663 },
    171 	{ 690926741, 0xb0e0932d }, { 705656483, 0xb4a5e73d },
    172 	{ 723553854, 0xb93ad34c }, { 750000000, 0xc0000000 },
    173 	{ 763550253, 0xc3780785 }, { 775284917, 0xc6791284 },
    174 	{ 826190764, 0xd3813ce8 }, { 875000000, 0xe0000000 },
    175 	{ 956805507, 0xf4f134a9 }, { 982570733, 0xfb89c16c }
    176 	};
    177 
    178 
    179 u_int32
    180 my_tick_to_tsf(u_int32 ticks)
    181 {
    182 	// convert nanoseconds to l_fp fractional units, using double
    183 	// precision float calculations or, if available, 64bit integer
    184 	// arithmetic. This should give the precise fraction, rounded to
    185 	// the nearest representation.
    186 
    187 #ifdef HAVE_U_INT64
    188 	return (u_int32)((( ((u_int64)(ticks)) << 32) + 500000000) / 1000000000);
    189 #else
    190 	return (u_int32)((double(ticks)) * 4.294967296 + 0.5);
    191 #endif
    192 	// And before you ask: if ticks >= 1000000000, the result is
    193 	// truncated nonsense, so don't use it out-of-bounds.
    194 }
    195 
    196 
    197 u_int32
    198 my_tsf_to_tick(u_int32 tsf)
    199 {
    200 
    201 	// Inverse operation: converts fraction to microseconds.
    202 #ifdef HAVE_U_INT64
    203 	return (u_int32)(( ((u_int64)(tsf)) * 1000000000 + 0x80000000) >> 32);
    204 #else
    205 	return (u_int32)(double(tsf) / 4.294967296 + 0.5);
    206 #endif
    207 	// Beware: The result might be 10^9 due to rounding!
    208 }
    209 
    210 
    211 
    212 // ---------------------------------------------------------------------
    213 // test support stuff -- part 1
    214 // ---------------------------------------------------------------------
    215 
    216 void
    217 test_Helpers1(void)
    218 {
    219 	struct timespec x;
    220 
    221 	for (x.tv_sec = -2; x.tv_sec < 3; x.tv_sec++) {
    222 		x.tv_nsec = -1;
    223 		TEST_ASSERT_FALSE(timespec_isValid(x));
    224 		x.tv_nsec = 0;
    225 		TEST_ASSERT_TRUE(timespec_isValid(x));
    226 		x.tv_nsec = 999999999;
    227 		TEST_ASSERT_TRUE(timespec_isValid(x));
    228 		x.tv_nsec = 1000000000;
    229 		TEST_ASSERT_FALSE(timespec_isValid(x));
    230 	}
    231 
    232 	return;
    233 }
    234 
    235 
    236 //----------------------------------------------------------------------
    237 // test normalisation
    238 //----------------------------------------------------------------------
    239 
    240 void
    241 test_Normalise(void)
    242 {
    243 	long ns;
    244 
    245 	for ( ns = -2000000000; ns <= 2000000000; ns += 10000000) {
    246 		struct timespec x = timespec_init(0, ns);
    247 
    248 		x = normalize_tspec(x);
    249 		TEST_ASSERT_TRUE(timespec_isValid(x));
    250 	}
    251 
    252 	return;
    253 }
    254 
    255 //----------------------------------------------------------------------
    256 // test classification
    257 //----------------------------------------------------------------------
    258 
    259 void
    260 test_SignNoFrac(void)
    261 {
    262 	// sign test, no fraction
    263 	int i;
    264 
    265 	for (i = -4; i <= 4; ++i) {
    266 		struct timespec a = timespec_init(i, 0);
    267 		int E = (i > 0) - (i < 0);
    268 		int r = test_tspec(a);
    269 
    270 		TEST_ASSERT_EQUAL(E, r);
    271 	}
    272 
    273 	return;
    274 }
    275 
    276 
    277 void
    278 test_SignWithFrac(void)
    279 {
    280 	// sign test, with fraction
    281 	int i;
    282 
    283 	for (i = -4; i <= 4; ++i) {
    284 		struct timespec a = timespec_init(i, 10);
    285 		int E = (i >= 0) - (i < 0);
    286 		int r = test_tspec(a);
    287 
    288 		TEST_ASSERT_EQUAL(E, r);
    289 	}
    290 
    291 	return;
    292 }
    293 
    294 //----------------------------------------------------------------------
    295 // test compare
    296 //----------------------------------------------------------------------
    297 void
    298 test_CmpFracEQ(void)
    299 {
    300 	// fractions are equal
    301 	int i, j;
    302 	for (i = -4; i <= 4; ++i)
    303 		for (j = -4; j <= 4; ++j) {
    304 			struct timespec a = timespec_init( i , 200);
    305 			struct timespec b = timespec_init( j , 200);
    306 			int   E = (i > j) - (i < j);
    307 			int   r = cmp_tspec_denorm(a, b);
    308 
    309 			TEST_ASSERT_EQUAL(E, r);
    310 		}
    311 
    312 	return;
    313 }
    314 
    315 
    316 void
    317 test_CmpFracGT(void)
    318 {
    319 	// fraction a bigger fraction b
    320 	int i, j;
    321 
    322 	for (i = -4; i <= 4; ++i)
    323 		for (j = -4; j <= 4; ++j) {
    324 			struct timespec a = timespec_init(i, 999999800);
    325 			struct timespec b = timespec_init(j, 200);
    326 			int   E = (i >= j) - (i < j);
    327 			int   r = cmp_tspec_denorm(a, b);
    328 
    329 			TEST_ASSERT_EQUAL(E, r);
    330 		}
    331 
    332 	return;
    333 }
    334 
    335 
    336 void
    337 test_CmpFracLT(void)
    338 {
    339 	// fraction a less fraction b
    340 	int i, j;
    341 
    342 	for (i = -4; i <= 4; ++i)
    343 		for (j = -4; j <= 4; ++j) {
    344 			struct timespec a = timespec_init(i, 200);
    345 			struct timespec b = timespec_init(j, 999999800);
    346 			int   E = (i > j) - (i <= j);
    347 			int   r = cmp_tspec_denorm(a, b);
    348 
    349 			TEST_ASSERT_EQUAL(E, r);
    350 		}
    351 
    352 	return;
    353 }
    354 
    355 //----------------------------------------------------------------------
    356 // Test addition (sum)
    357 //----------------------------------------------------------------------
    358 
    359 void
    360 test_AddFullNorm(void)
    361 {
    362 	int i, j;
    363 
    364 	for (i = -4; i <= 4; ++i)
    365 		for (j = -4; j <= 4; ++j) {
    366 			struct timespec a = timespec_init(i, 200);
    367 			struct timespec b = timespec_init(j, 400);
    368 			struct timespec E = timespec_init(i + j, 200 + 400);
    369 			struct timespec c;
    370 
    371 			c = add_tspec(a, b);
    372 			TEST_ASSERT_EQUAL_timespec(E, c);
    373 		}
    374 
    375 	return;
    376 }
    377 
    378 
    379 void
    380 test_AddFullOflow1(void)
    381 {
    382 	int i, j;
    383 
    384 	for (i = -4; i <= 4; ++i)
    385 		for (j = -4; j <= 4; ++j) {
    386 			struct timespec a = timespec_init(i, 200);
    387 			struct timespec b = timespec_init(j, 999999900);
    388 			struct timespec E = timespec_init(i + j + 1, 100);
    389 			struct timespec c;
    390 
    391 			c = add_tspec(a, b);
    392 			TEST_ASSERT_EQUAL_timespec(E, c);
    393 		}
    394 
    395 	return;
    396 }
    397 
    398 
    399 void
    400 test_AddNsecNorm(void) {
    401 	int i;
    402 
    403 	for (i = -4; i <= 4; ++i) {
    404 		struct timespec a = timespec_init(i, 200);
    405 		struct timespec E = timespec_init(i, 600);
    406 		struct timespec c;
    407 
    408 		c = add_tspec_ns(a, 600 - 200);
    409 		TEST_ASSERT_EQUAL_timespec(E, c);
    410 	}
    411 
    412 	return;
    413 }
    414 
    415 
    416 void
    417 test_AddNsecOflow1(void)
    418 {
    419 	int i;
    420 
    421 	for (i = -4; i <= 4; ++i) {
    422 		struct timespec a = timespec_init(i, 200);
    423 		struct timespec E = timespec_init(i + 1, 100);
    424 		struct timespec c;
    425 
    426 		c = add_tspec_ns(a, NANOSECONDS - 100);
    427 		TEST_ASSERT_EQUAL_timespec(E, c);
    428 	}
    429 
    430 	return;
    431 }
    432 
    433 //----------------------------------------------------------------------
    434 // test subtraction (difference)
    435 //----------------------------------------------------------------------
    436 
    437 void
    438 test_SubFullNorm(void)
    439 {
    440 	int i, j;
    441 
    442 	for (i = -4; i <= 4; ++i)
    443 		for (j = -4; j <= 4; ++j) {
    444 			struct timespec a = timespec_init( i , 600);
    445 			struct timespec b = timespec_init( j , 400);
    446 			struct timespec E = timespec_init(i-j, 200);
    447 			struct timespec c;
    448 
    449 			c = sub_tspec(a, b);
    450 			TEST_ASSERT_EQUAL_timespec(E, c);
    451 		}
    452 
    453 	return;
    454 }
    455 
    456 
    457 void
    458 test_SubFullOflow(void)
    459 {
    460 	int i, j;
    461 
    462 	for (i = -4; i <= 4; ++i)
    463 		for (j = -4; j <= 4; ++j) {
    464 			struct timespec a = timespec_init(i, 100);
    465 			struct timespec b = timespec_init(j, 999999900);
    466 			struct timespec E = timespec_init(i - j - 1, 200);
    467 			struct timespec c;
    468 
    469 			c = sub_tspec(a, b);
    470 			TEST_ASSERT_EQUAL_timespec(E, c);
    471 		}
    472 
    473 	return;
    474 }
    475 
    476 
    477 void
    478 test_SubNsecNorm(void)
    479 {
    480 	int i;
    481 
    482 	for (i = -4; i <= 4; ++i) {
    483 		struct timespec a = timespec_init(i, 600);
    484 		struct timespec E = timespec_init(i, 200);
    485 		struct timespec c;
    486 
    487 		c = sub_tspec_ns(a, 600 - 200);
    488 		TEST_ASSERT_EQUAL_timespec(E, c);
    489 	}
    490 
    491 	return;
    492 }
    493 
    494 
    495 void
    496 test_SubNsecOflow(void)
    497 {
    498 	int i;
    499 
    500 	for (i = -4; i <= 4; ++i) {
    501 		struct timespec a = timespec_init( i , 100);
    502 		struct timespec E = timespec_init(i-1, 200);
    503 		struct timespec c;
    504 
    505 		c = sub_tspec_ns(a, NANOSECONDS - 100);
    506 		TEST_ASSERT_EQUAL_timespec(E, c);
    507 	}
    508 
    509 	return;
    510 }
    511 
    512 //----------------------------------------------------------------------
    513 // test negation
    514 //----------------------------------------------------------------------
    515 
    516 
    517 void
    518 test_Neg(void)
    519 {
    520 	int i;
    521 
    522 	for (i = -4; i <= 4; ++i) {
    523 		struct timespec a = timespec_init(i, 100);
    524 		struct timespec b;
    525 		struct timespec c;
    526 
    527 		b = neg_tspec(a);
    528 		c = add_tspec(a, b);
    529 		TEST_ASSERT_EQUAL(0, test_tspec(c));
    530 	}
    531 
    532 	return;
    533 }
    534 
    535 //----------------------------------------------------------------------
    536 // test abs value
    537 //----------------------------------------------------------------------
    538 
    539 void
    540 test_AbsNoFrac(void)
    541 {
    542 	int i;
    543 
    544 	for (i = -4; i <= 4; ++i) {
    545 		struct timespec a = timespec_init(i , 0);
    546 		struct timespec b;
    547 
    548 		b = abs_tspec(a);
    549 		TEST_ASSERT_EQUAL((i != 0), test_tspec(b));
    550 	}
    551 
    552 	return;
    553 }
    554 
    555 
    556 void
    557 test_AbsWithFrac(void)
    558 {
    559 	int i;
    560 
    561 	for (i = -4; i <= 4; ++i) {
    562 		struct timespec a = timespec_init(i, 100);
    563 		struct timespec b;
    564 
    565 		b = abs_tspec(a);
    566 		TEST_ASSERT_EQUAL(1, test_tspec(b));
    567 	}
    568 
    569 	return;
    570 }
    571 
    572 // ---------------------------------------------------------------------
    573 // test support stuff -- part 2
    574 // ---------------------------------------------------------------------
    575 
    576 void
    577 test_Helpers2(void)
    578 {
    579 	struct timespec limit = timespec_init(0, 2);
    580 	struct timespec x, y;
    581 	long i;
    582 
    583 	for (x.tv_sec = -2; x.tv_sec < 3; x.tv_sec++)
    584 		for (x.tv_nsec = 1;
    585 		     x.tv_nsec < 1000000000;
    586 		     x.tv_nsec += 499999999) {
    587 			for (i = -4; i < 5; ++i) {
    588 				y = x;
    589 				y.tv_nsec += i;
    590 				if (i >= -2 && i <= 2) {
    591 					TEST_ASSERT_TRUE(AssertTimespecClose(x, y, limit));
    592 				}
    593 				else
    594 				{
    595 					TEST_ASSERT_FALSE(AssertTimespecClose(x, y, limit));
    596 				}
    597 			}
    598 		}
    599 
    600 	return;
    601 }
    602 
    603 //----------------------------------------------------------------------
    604 // conversion to l_fp
    605 //----------------------------------------------------------------------
    606 
    607 void
    608 test_ToLFPbittest(void)
    609 {
    610 	l_fp lfpClose =  l_fp_init(0, 1);
    611 	u_int32 i;
    612 
    613 	for (i = 0; i < 1000000000; i+=1000) {
    614 		struct timespec a = timespec_init(1, i);
    615 		l_fp E= l_fp_init(1, my_tick_to_tsf(i));
    616 		l_fp r;
    617 
    618 		r = tspec_intv_to_lfp(a);
    619 		TEST_ASSERT_TRUE(AssertFpClose(E, r, lfpClose));
    620 	}
    621 
    622 	return;
    623 }
    624 
    625 
    626 void
    627 test_ToLFPrelPos(void)
    628 {
    629 	int i;
    630 
    631 	for (i = 0; i < COUNTOF(fdata); ++i) {
    632 		struct timespec a = timespec_init(1, fdata[i].nsec);
    633 		l_fp E = l_fp_init(1, fdata[i].frac);
    634 		l_fp r;
    635 
    636 		r = tspec_intv_to_lfp(a);
    637 		TEST_ASSERT_EQUAL_l_fp(E, r);
    638 	}
    639 
    640 	return;
    641 }
    642 
    643 
    644 void
    645 test_ToLFPrelNeg(void)
    646 {
    647 	int i;
    648 
    649 	for (i = 0; i < COUNTOF(fdata); ++i) {
    650 		struct timespec a = timespec_init(-1, fdata[i].nsec);
    651 		l_fp E = l_fp_init(~0, fdata[i].frac);
    652 		l_fp r;
    653 
    654 		r = tspec_intv_to_lfp(a);
    655 		TEST_ASSERT_EQUAL_l_fp(E, r);
    656 	}
    657 
    658 	return;
    659 }
    660 
    661 
    662 void
    663 test_ToLFPabs(void)
    664 {
    665 	int i;
    666 
    667 	for (i = 0; i < COUNTOF(fdata); ++i) {
    668 		struct timespec a = timespec_init(1, fdata[i].nsec);
    669 		l_fp E = l_fp_init(1 + JAN_1970, fdata[i].frac);
    670 		l_fp r;
    671 
    672 		r = tspec_stamp_to_lfp(a);
    673 		TEST_ASSERT_EQUAL_l_fp(E, r);
    674 	}
    675 
    676 	return;
    677 }
    678 
    679 //----------------------------------------------------------------------
    680 // conversion from l_fp
    681 //----------------------------------------------------------------------
    682 
    683 void
    684 test_FromLFPbittest(void)
    685 {
    686 	struct timespec limit = timespec_init(0, 2);
    687 
    688 	// Not *exactly* a bittest, because 2**32 tests would take a
    689 	// really long time even on very fast machines! So we do test
    690 	// every 1000 fractional units.
    691 	u_int32 tsf;
    692 	for (tsf = 0; tsf < ~((u_int32)(1000)); tsf += 1000) {
    693 		struct timespec E = timespec_init(1, my_tsf_to_tick(tsf));
    694 		l_fp a = l_fp_init(1, tsf);
    695 		struct timespec r;
    696 
    697 		r = lfp_intv_to_tspec(a);
    698 		// The conversion might be off by one nanosecond when
    699 		// comparing to calculated value.
    700 		TEST_ASSERT_TRUE(AssertTimespecClose(E, r, limit));
    701 	}
    702 
    703 	return;
    704 }
    705 
    706 
    707 void
    708 test_FromLFPrelPos(void)
    709 {
    710 	struct timespec limit = timespec_init(0, 2);
    711 	int i;
    712 
    713 	for (i = 0; i < COUNTOF(fdata); ++i) {
    714 		l_fp a = l_fp_init(1, fdata[i].frac);
    715 		struct timespec E = timespec_init(1, fdata[i].nsec);
    716 		struct timespec r;
    717 
    718 		r = lfp_intv_to_tspec(a);
    719 		TEST_ASSERT_TRUE(AssertTimespecClose(E, r, limit));
    720 	}
    721 
    722 	return;
    723 }
    724 
    725 
    726 void
    727 test_FromLFPrelNeg(void)
    728 {
    729 	struct timespec limit = timespec_init(0, 2);
    730 	int i;
    731 
    732 	for (i = 0; i < COUNTOF(fdata); ++i) {
    733 		l_fp a = l_fp_init(~0, fdata[i].frac);
    734 		struct timespec E = timespec_init(-1, fdata[i].nsec);
    735 		struct timespec r;
    736 
    737 		r = lfp_intv_to_tspec(a);
    738 		TEST_ASSERT_TRUE(AssertTimespecClose(E, r, limit));
    739 	}
    740 
    741 	return;
    742 }
    743 
    744 
    745 // nsec -> frac -> nsec roundtrip, using a prime start and increment
    746 void
    747 test_LFProundtrip(void)
    748 {
    749 	int32_t t;
    750 	u_int32 i;
    751 
    752 	for (t = -1; t < 2; ++t)
    753 		for (i = 4999; i < 1000000000; i += 10007) {
    754 			struct timespec E = timespec_init(t, i);
    755 			l_fp a;
    756 			struct timespec r;
    757 
    758 			a = tspec_intv_to_lfp(E);
    759 			r = lfp_intv_to_tspec(a);
    760 			TEST_ASSERT_EQUAL_timespec(E, r);
    761 		}
    762 
    763 	return;
    764 }
    765 
    766 //----------------------------------------------------------------------
    767 // string formatting
    768 //----------------------------------------------------------------------
    769 
    770 void
    771 test_ToString(void)
    772 {
    773 	static const struct {
    774 		time_t		sec;
    775 		long		nsec;
    776 		const char *	repr;
    777 	} data [] = {
    778 		{ 0, 0,	 "0.000000000" },
    779 		{ 2, 0,	 "2.000000000" },
    780 		{-2, 0, "-2.000000000" },
    781 		{ 0, 1,	 "0.000000001" },
    782 		{ 0,-1,	"-0.000000001" },
    783 		{ 1,-1,	 "0.999999999" },
    784 		{-1, 1, "-0.999999999" },
    785 		{-1,-1, "-1.000000001" },
    786 	};
    787 	int i;
    788 
    789 	for (i = 0; i < COUNTOF(data); ++i) {
    790 		struct timespec a = timespec_init(data[i].sec, data[i].nsec);
    791 		const char * E = data[i].repr;
    792 		const char * r = tspectoa(a);
    793 		TEST_ASSERT_EQUAL_STRING(E, r);
    794 	}
    795 
    796 	return;
    797 }
    798 
    799 // -*- EOF -*-
    800