html_special(): move va_end() call outside the switch and make variables
[elinks.git] / src / util / time.c
blob4492b74e653868b995bd9d5e807820f0391b4071
1 /* Time operations */
3 #ifdef HAVE_CONFIG_H
4 #include "config.h"
5 #endif
7 #ifdef HAVE_SYS_TIME_H
8 #include <sys/time.h>
9 #endif
10 #ifdef HAVE_TIME_H
11 #include <time.h>
12 #endif
14 #include "elinks.h"
16 #include "osdep/osdep.h" /* For win32 gettimeofday() stub */
17 #include "util/error.h"
18 #include "util/time.h"
20 /* Get the current time.
21 * It attempts to use available functions, granularity
22 * may be as worse as 1 second if time() is used. */
23 timeval_T *
24 timeval_now(timeval_T *t)
26 #ifdef HAVE_GETTIMEOFDAY
27 struct timeval tv;
29 gettimeofday(&tv, NULL);
30 t->sec = (long) tv.tv_sec;
31 t->usec = (long) tv.tv_usec;
32 #else
33 #ifdef HAVE_CLOCK_GETTIME
34 struct timespec ts;
36 clock_gettime(CLOCK_REALTIME, &ts);
37 t->sec = (long) ts.tv_sec;
38 t->usec = (long) ts.tv_nsec / 1000;
39 #else
40 t->sec = (long) time(NULL);
41 t->usec = (long) 0;
42 #endif
43 #endif
45 return t;
48 /* Subtract an interval to a timeval, it ensures that
49 * result is never negative. */
50 timeval_T *
51 timeval_sub_interval(timeval_T *t, timeval_T *interval)
53 t->sec -= interval->sec;
54 if (t->sec < 0) {
55 t->sec = 0;
56 t->usec = 0;
57 return t;
60 t->usec -= interval->usec;
62 while (t->usec < 0) {
63 t->usec += 1000000;
64 t->sec--;
67 if (t->sec < 0) {
68 t->sec = 0;
69 t->usec = 0;
72 return t;
75 timeval_T *
76 timeval_sub(timeval_T *res, timeval_T *older, timeval_T *newer)
78 res->sec = newer->sec - older->sec;
79 res->usec = newer->usec - older->usec;
81 while (res->usec < 0) {
82 res->usec += 1000000;
83 res->sec--;
86 return res;
89 timeval_T *
90 timeval_add(timeval_T *res, timeval_T *base, timeval_T *t)
92 res->sec = base->sec + t->sec;
93 res->usec = base->usec + t->usec;
95 while (res->usec >= 1000000) {
96 res->usec -= 1000000;
97 res->sec++;
100 return res;
103 timeval_T *
104 timeval_add_interval(timeval_T *t, timeval_T *interval)
106 t->sec += interval->sec;
107 t->usec += interval->usec;
109 while (t->usec >= 1000000) {
110 t->usec -= 1000000;
111 t->sec++;
114 return t;
117 timeval_T *
118 timeval_from_double(timeval_T *t, double x)
120 t->sec = (long) x;
121 t->usec = (long) ((x - (double) t->sec) * 1000000);
123 return t;
126 timeval_T *
127 timeval_from_milliseconds(timeval_T *t, milliseconds_T milliseconds)
129 long ms = (long) milliseconds;
131 t->sec = ms / 1000;
132 t->usec = (ms % 1000) * 1000;
134 return t;
137 timeval_T *
138 timeval_from_seconds(timeval_T *t, long seconds)
140 t->sec = seconds;
141 t->usec = 0;
143 return t;
146 milliseconds_T
147 sec_to_ms(long sec)
149 assert(sec >= 0 && sec < LONG_MAX / 1000L);
150 if_assert_failed return (milliseconds_T) (LONG_MAX / 1000L);
152 return (milliseconds_T) (sec * 1000L);
155 milliseconds_T
156 add_ms_to_ms(milliseconds_T a, milliseconds_T b)
158 long la = (long) a;
159 long lb = (long) b;
161 assert(la >= 0 && lb >= 0 && lb < LONG_MAX - la);
162 if_assert_failed return (milliseconds_T) (LONG_MAX / 1000L);
164 return (milliseconds_T) (la + lb);
167 milliseconds_T
168 mult_ms(milliseconds_T a, long lb)
170 long la = (long) a;
172 assert(la >= 0 && lb >= 0 && la < LONG_MAX / lb);
173 if_assert_failed return (milliseconds_T) (LONG_MAX / 1000L);
175 return (milliseconds_T) (la * lb);
178 milliseconds_T
179 timeval_to_milliseconds(timeval_T *t)
181 milliseconds_T a = sec_to_ms(t->sec);
182 milliseconds_T b = (milliseconds_T) (t->usec / 1000L);
184 return add_ms_to_ms(a, b);
187 long
188 timeval_to_seconds(timeval_T *t)
190 return t->sec + t->usec / 1000000L;
194 timeval_is_positive(timeval_T *t)
196 return (t->sec > 0 || (t->sec == 0 && t->usec > 0));
199 /* Be sure timeval is not negative. */
200 void
201 timeval_limit_to_zero(timeval_T *t)
203 if (t->sec < 0) t->sec = 0;
204 if (t->usec < 0) t->usec = 0;
207 /* Returns 1 if t1 > t2
208 * -1 if t1 < t2
209 * 0 if t1 == t2 */
211 timeval_cmp(timeval_T *t1, timeval_T *t2)
213 if (t1->sec > t2->sec) return 1;
214 if (t1->sec < t2->sec) return -1;
216 return t1->usec - t2->usec;
220 timeval_div_off_t(off_t n, timeval_T *t)
222 longlong ln = 1000 * (longlong) n; /* FIXME: off_t -> longlong ??? Find a better way. --Zas */
223 longlong lsec = 1000 * (longlong) t->sec;
224 int lusec = t->usec / 1000;
226 if (lsec + lusec)
227 return (ln / (lsec + lusec));
228 else
229 return INT_MAX;