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