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