34#if defined(__windows__)
43 ft.QuadPart = -(10 * usec);
45 timer = CreateWaitableTimer(NULL, TRUE, NULL);
46 SetWaitableTimer(timer, &ft, 0, NULL, NULL, 0);
47 WaitForSingleObject(timer, INFINITE);
66 printf(
"Press enter to continue...");
68 int n = scanf(
"%c", k);
72 }
else if (error != 0) {
73 n_log(
LOG_ERR,
"error %s when waiting for a key !", strerror(error));
90#if defined(__windows__)
91 if (QueryPerformanceFrequency((LARGE_INTEGER*)&timer->freq) == 0)
93 if (QueryPerformanceCounter(&timer->
startTime) == 0)
96 if (gettimeofday(&timer->
startTime, 0) != 0)
111 QueryPerformanceCounter((LARGE_INTEGER*)&timer->
currentTime);
132 QueryPerformanceCounter((LARGE_INTEGER*)&timer->
currentTime);
153 QueryPerformanceCounter((LARGE_INTEGER*)&timer->
currentTime);
170 unsigned yoe, doy, doe;
172 era = (y >= 0 ? y : y - 399) / 400;
173 yoe = (unsigned)(y - era * 400);
174 doy = (153 * (m + (m > 2 ? (unsigned)-3 : 9)) + 2) / 5 + d - 1;
175 doe = yoe * 365 + yoe / 4 - yoe / 100 + doy;
176 return era * 146097 + (
long long)doe - 719468;
181 unsigned doe, yoe, doy, mp;
183 era = (z >= 0 ? z : z - 146096) / 146097;
184 doe = (unsigned)(z - era * 146097);
185 yoe = (doe - doe / 1460 + doe / 36524 - doe / 146096) / 365;
186 doy = doe - (365 * yoe + yoe / 4 - yoe / 100);
187 mp = (5 * doy + 2) / 153;
188 *d = doy - (153 * mp + 2) / 5 + 1;
189 *m = mp < 10 ? mp + 3 : mp - 9;
190 *y = (
long long)yoe + era * 400 + (*m <= 2);
193static const char*
const _wday_names[7] = {
"Thu",
"Fri",
"Sat",
"Sun",
"Mon",
"Tue",
"Wed"};
194static const char*
const _month_names[12] = {
"Jan",
"Feb",
"Mar",
"Apr",
"May",
"Jun",
195 "Jul",
"Aug",
"Sep",
"Oct",
"Nov",
"Dec"};
198 return (y % 4 == 0 && y % 100 != 0) || y % 400 == 0;
202 static const unsigned md[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
203 return m == 2 &&
_leap(y) ? 29u : md[m - 1];
213 long long s = (
long long)t + offset, days, rem;
214 days = s >= 0 ? s / 86400 : -((-s + 86399) / 86400);
215 rem = s - days * 86400;
219 c->
hour = (unsigned)(rem / 3600);
220 c->
min = (unsigned)(rem % 3600 / 60);
221 c->
sec = (unsigned)(rem % 60);
222 c->
wday_idx = (unsigned)(((days % 7) + 7) % 7);
227 return offset > -86400 && offset < 86400 && offset % 60 == 0;
256 long a = offset < 0 ? -offset : offset;
274 long a = offset < 0 ? -offset : offset;
277 snprintf(out, size,
"%04lld-%02u-%02uT%02u:%02u:%02u%c%02ld:%02ld", c.
year, c.
mon, c.
mday, c.
hour, c.
min,
278 c.
sec, offset < 0 ?
'-' :
'+', a / 3600, a % 3600 / 60);
283static int _digits(
const char* s,
size_t n,
unsigned* v) {
286 for (i = 0; i < n; i++) {
287 if (s[i] <
'0' || s[i] >
'9')
289 *v = *v * 10 + (unsigned)(s[i] -
'0');
295static int _civil_to_time(
long long y,
unsigned mo,
unsigned d,
unsigned h,
unsigned mi,
unsigned se, time_t* t) {
297 if (y < 1 || y > 9999 || mo < 1 || mo > 12 || d < 1 || d >
_month_days(y, mo) ||
h > 23 || mi > 59 || se > 59)
300 if (
sizeof(time_t) < 8 && (v > INT_MAX || v < INT_MIN))
314 unsigned d, y,
h, mi, se, mo = 0, k;
318 if (!s || !t || len != 29 || s[3] !=
',' || s[4] !=
' ' || s[7] !=
' ' || s[11] !=
' ' || s[16] !=
' ' ||
319 s[19] !=
':' || s[22] !=
':' || s[25] !=
' ' || memcmp(s + 26,
"GMT", 3) != 0)
321 for (k = 0; k < 12; k++)
325 !
_digits(s + 20, 2, &mi) || !
_digits(s + 23, 2, &se) || !
_civil_to_time(y, mo, d,
h, mi, se, &v))
341 unsigned y, mo, d,
h, mi, se, oh = 0, om = 0;
344 if (!s || !t || len < 19 || s[4] !=
'-' || s[7] !=
'-' || (s[10] !=
'T' && s[10] !=
' ' && s[10] !=
't') ||
345 s[13] !=
':' || s[16] !=
':')
350 if (len == 20 && (s[19] ==
'Z' || s[19] ==
'z')) {
352 }
else if (len == 25 && (s[19] ==
'+' || s[19] ==
'-') && s[22] ==
':') {
353 if (!
_digits(s + 20, 2, &oh) || !
_digits(s + 23, 2, &om) || oh > 23 || om > 59)
355 offset = (long)(oh * 3600 + om * 60);
358 }
else if (len != 19) {
363 *t = (time_t)((
long long)v - offset);
static int h(void *ctx, const N_ROUTE_MATCH *m)
a handler that does nothing (the test only routes)
#define __n_assert(__ptr, __ret)
macro to assert things
#define n_log(__LEVEL__,...)
Logging function wrapper to get line and func.
#define LOG_DEBUG
debug-level messages
#define LOG_ERR
error conditions
struct timeval startTime
start time
time_t delta
time since last poll
struct timeval currentTime
current time
int n_time_parse_http_date(const char *s, size_t len, time_t *t)
parse an IMF-fixdate HTTP date strictly
int n_time_rfc2822(time_t t, long offset, char *out, size_t size)
format t as an RFC 2822 date at offset seconds east of UTC
int n_time_parse_rfc3339(const char *s, size_t len, time_t *t)
parse "YYYY-MM-DD[T| ]HH:MM:SS[Z|+hh:mm|-hh:mm]" (UTC without a zone)
void u_sleep(unsigned int usec)
wrapper around usleep for API consistency
int start_HiTimer(N_TIME *timer)
Initialize or restart from zero any N_TIME HiTimer.
#define N_TIME_RFC2822_LEN
buffer size for n_time_rfc2822(): "Thu, 01 Jan 1970 00:00:00 +0000" + NUL
#define N_TIME_HTTP_DATE_LEN
buffer size for n_time_http_date(): "Thu, 01 Jan 1970 00:00:00 GMT" + NUL
time_t get_usec(N_TIME *timer)
Poll any N_TIME HiTimer, returning usec, and moving currentTime to startTime.
time_t get_msec(N_TIME *timer)
Poll any N_TIME HiTimer, returning msec, and moving currentTime to startTime.
time_t get_sec(N_TIME *timer)
Poll any N_TIME HiTimer, returning sec, and moving currentTime to startTime.
int n_time_http_date(time_t t, char *out, size_t size)
format t as an HTTP date (RFC 9110 IMF-fixdate, always GMT)
int n_time_rfc3339(time_t t, long offset, char *out, size_t size)
format t as RFC 3339 at offset seconds east of UTC ("+00:00" for UTC)
void PAUSE(void)
make a pause in a terminal
#define N_TIME_RFC3339_LEN
buffer size for n_time_rfc3339(): "1970-01-01T00:00:00+00:00" + NUL
static int _offset_ok(long offset)
static int _civil_of(time_t t, long offset, _n_civil *c)
static const char *const _wday_names[7]
static long long _days_from_civil(long long y, unsigned m, unsigned d)
static int _civil_to_time(long long y, unsigned mo, unsigned d, unsigned h, unsigned mi, unsigned se, time_t *t)
static int _digits(const char *s, size_t n, unsigned *v)
static unsigned _month_days(long long y, unsigned m)
static void _civil_from_days(long long z, long long *y, unsigned *m, unsigned *d)
static int _leap(long long y)
static const char *const _month_names[12]