1*e89934bbSchristos /* $NetBSD: timecmp.c,v 1.2 2017/02/14 01:16:49 christos Exp $ */
216d67a18Stron
316d67a18Stron /*++
416d67a18Stron /* NAME
516d67a18Stron /* timecmp 3
616d67a18Stron /* SUMMARY
716d67a18Stron /* compare two time_t values
816d67a18Stron /* SYNOPSIS
916d67a18Stron /* #include <timecmp.h>
1016d67a18Stron /*
1116d67a18Stron /* int timecmp(t1, t2)
1216d67a18Stron /* time_t t1;
1316d67a18Stron /* time_t t2;
1416d67a18Stron /* DESCRIPTION
1516d67a18Stron /* The timecmp() function return an integer greater than, equal to, or
1616d67a18Stron /* less than 0, according as the time t1 is greater than, equal to, or
1716d67a18Stron /* less than the time t2. The comparison is made in a manner that is
1816d67a18Stron /* insensitive to clock wrap-around, provided the underlying times are
1916d67a18Stron /* within half of the time interval between the smallest and largest
2016d67a18Stron /* representable time values.
2116d67a18Stron /* LICENSE
2216d67a18Stron /* .ad
2316d67a18Stron /* .fi
2416d67a18Stron /* The Secure Mailer license must be distributed with this software.
2516d67a18Stron /* AUTHOR(S)
2616d67a18Stron /* Wietse Venema
2716d67a18Stron /* IBM T.J. Watson Research
2816d67a18Stron /* P.O. Box 704
2916d67a18Stron /* Yorktown Heights, NY 10598, USA
3016d67a18Stron /*
3116d67a18Stron /* Viktor Dukhovni
3216d67a18Stron /*--*/
3316d67a18Stron
3416d67a18Stron #include "timecmp.h"
3516d67a18Stron
3616d67a18Stron /* timecmp - wrap-safe time_t comparison */
3716d67a18Stron
timecmp(time_t t1,time_t t2)3816d67a18Stron int timecmp(time_t t1, time_t t2)
3916d67a18Stron {
4016d67a18Stron time_t delta = t1 - t2;
4116d67a18Stron
4216d67a18Stron if (delta == 0)
4316d67a18Stron return 0;
4416d67a18Stron
4516d67a18Stron #define UNSIGNED(type) ( ((type)-1) > ((type)0) )
4616d67a18Stron
4716d67a18Stron /*
4816d67a18Stron * With a constant switch value, the compiler will emit only the code for
4916d67a18Stron * the correct case, so the signed/unsigned test happens at compile time.
5016d67a18Stron */
5116d67a18Stron switch (UNSIGNED(time_t) ? 0 : 1) {
5216d67a18Stron case 0:
5316d67a18Stron return ((2 * delta > delta) ? 1 : -1);
5416d67a18Stron case 1:
5516d67a18Stron return ((delta > (time_t) 0) ? 1 : -1);
5616d67a18Stron }
5716d67a18Stron }
5816d67a18Stron
5916d67a18Stron #ifdef TEST
6016d67a18Stron #include <assert.h>
6116d67a18Stron
6216d67a18Stron /*
6316d67a18Stron * Bit banging!! There is no official constant that defines the INT_MAX
6416d67a18Stron * equivalent of the off_t type. Wietse came up with the following macro
6516d67a18Stron * that works as long as off_t is some two's complement number.
6616d67a18Stron *
6716d67a18Stron * Note, however, that C99 permits signed integer representations other than
6816d67a18Stron * two's complement.
6916d67a18Stron */
7016d67a18Stron #include <limits.h>
7116d67a18Stron #define __MAXINT__(T) ((T) (((((T) 1) << ((sizeof(T) * CHAR_BIT) - 1)) ^ ((T) -1))))
7216d67a18Stron
main(void)73e262b48eSchristos int main(void)
7416d67a18Stron {
7516d67a18Stron time_t now = time((time_t *) 0);
7616d67a18Stron
7716d67a18Stron /* Test that it works for normal times */
7816d67a18Stron assert(timecmp(now + 10, now) > 0);
7916d67a18Stron assert(timecmp(now, now) == 0);
8016d67a18Stron assert(timecmp(now - 10, now) < 0);
8116d67a18Stron
8216d67a18Stron /* Test that it works at a boundary time */
8316d67a18Stron if (UNSIGNED(time_t))
8416d67a18Stron now = (time_t) -1;
8516d67a18Stron else
8616d67a18Stron now = __MAXINT__(time_t);
8716d67a18Stron
8816d67a18Stron assert(timecmp(now + 10, now) > 0);
8916d67a18Stron assert(timecmp(now, now) == 0);
9016d67a18Stron assert(timecmp(now - 10, now) < 0);
9116d67a18Stron
9216d67a18Stron return (0);
9316d67a18Stron }
9416d67a18Stron
9516d67a18Stron #endif
96