Home | History | Annotate | Line # | Download | only in util
      1 /*	$NetBSD: timecmp.c,v 1.2 2017/02/14 01:16:49 christos Exp $	*/
      2 
      3 /*++
      4 /* NAME
      5 /*	timecmp 3
      6 /* SUMMARY
      7 /*	compare two time_t values
      8 /* SYNOPSIS
      9 /*	#include <timecmp.h>
     10 /*
     11 /*	int	timecmp(t1, t2)
     12 /*	time_t	t1;
     13 /*	time_t	t2;
     14 /* DESCRIPTION
     15 /*	The timecmp() function return an integer greater than, equal to, or
     16 /*	less than 0, according as the time t1 is greater than, equal to, or
     17 /*	less than the time t2.  The comparison is made in a manner that is
     18 /*	insensitive to clock wrap-around, provided the underlying times are
     19 /*	within half of the time interval between the smallest and largest
     20 /*	representable time values.
     21 /* LICENSE
     22 /* .ad
     23 /* .fi
     24 /*	The Secure Mailer license must be distributed with this software.
     25 /* AUTHOR(S)
     26 /*	Wietse Venema
     27 /*	IBM T.J. Watson Research
     28 /*	P.O. Box 704
     29 /*	Yorktown Heights, NY 10598, USA
     30 /*
     31 /*	Viktor Dukhovni
     32 /*--*/
     33 
     34 #include "timecmp.h"
     35 
     36 /* timecmp - wrap-safe time_t comparison */
     37 
     38 int     timecmp(time_t t1, time_t t2)
     39 {
     40     time_t  delta = t1 - t2;
     41 
     42     if (delta == 0)
     43 	return 0;
     44 
     45 #define UNSIGNED(type) ( ((type)-1) > ((type)0) )
     46 
     47     /*
     48      * With a constant switch value, the compiler will emit only the code for
     49      * the correct case, so the signed/unsigned test happens at compile time.
     50      */
     51     switch (UNSIGNED(time_t) ? 0 : 1) {
     52     case 0:
     53 	return ((2 * delta > delta) ? 1 : -1);
     54     case 1:
     55 	return ((delta > (time_t) 0) ? 1 : -1);
     56     }
     57 }
     58 
     59 #ifdef TEST
     60 #include <assert.h>
     61 
     62  /*
     63   * Bit banging!! There is no official constant that defines the INT_MAX
     64   * equivalent of the off_t type. Wietse came up with the following macro
     65   * that works as long as off_t is some two's complement number.
     66   *
     67   * Note, however, that C99 permits signed integer representations other than
     68   * two's complement.
     69   */
     70 #include <limits.h>
     71 #define __MAXINT__(T) ((T) (((((T) 1) << ((sizeof(T) * CHAR_BIT) - 1)) ^ ((T) -1))))
     72 
     73 int     main(void)
     74 {
     75     time_t  now = time((time_t *) 0);
     76 
     77     /* Test that it works for normal times */
     78     assert(timecmp(now + 10, now) > 0);
     79     assert(timecmp(now, now) == 0);
     80     assert(timecmp(now - 10, now) < 0);
     81 
     82     /* Test that it works at a boundary time */
     83     if (UNSIGNED(time_t))
     84 	now = (time_t) -1;
     85     else
     86 	now = __MAXINT__(time_t);
     87 
     88     assert(timecmp(now + 10, now) > 0);
     89     assert(timecmp(now, now) == 0);
     90     assert(timecmp(now - 10, now) < 0);
     91 
     92     return (0);
     93 }
     94 
     95 #endif
     96