41 static const char* duration_str =
"duration";
62 ods_log_error(
"[%s] cannot create: allocator failed", duration_str);
130 ods_log_error(
"[%s] cannot create from string %s: create failed",
138 P = strchr(str,
'P');
140 ods_log_error(
"[%s] cannot create from string %s: P not found",
146 T = strchr(str,
'T');
147 X = strchr(str,
'Y');
149 duration->
years = atoi(str+1);
153 X = strchr(str,
'M');
154 if (X && (!T || (
size_t) (X-P) < (
size_t) (T-P))) {
155 duration->
months = atoi(str+1);
159 X = strchr(str,
'D');
161 duration->
days = atoi(str+1);
169 X = strchr(str,
'H');
171 duration->
hours = atoi(str+1);
175 X = strrchr(str,
'M');
176 if (X && T && (
size_t) (X-P) > (
size_t) (T-P)) {
177 duration->
minutes = atoi(str+1);
181 X = strchr(str,
'S');
183 duration->
seconds = atoi(str+1);
188 W = strchr(str,
'W');
196 duration->
weeks = atoi(str+1);
209 digits_in_number(time_t duration)
211 uint32_t period = (uint32_t) duration;
231 char* str = NULL, *num = NULL;
239 if (duration->
years > 0) {
240 count = count + 1 + digits_in_number(duration->
years);
243 if (duration->
months > 0) {
244 count = count + 1 + digits_in_number(duration->
months);
247 if (duration->
weeks > 0) {
248 count = count + 1 + digits_in_number(duration->
weeks);
251 if (duration->
days > 0) {
252 count = count + 1 + digits_in_number(duration->
days);
255 if (duration->
hours > 0) {
256 count = count + 1 + digits_in_number(duration->
hours);
260 count = count + 1 + digits_in_number(duration->
minutes);
265 count = count + 1 + digits_in_number(duration->
seconds);
272 str = (
char*) calloc(count,
sizeof(
char));
276 if (duration->
years > 0) {
277 count = digits_in_number(duration->
years);
278 num = (
char*) calloc(count+2,
sizeof(
char));
280 snprintf(num, count+2,
"%uY", (uint32_t) duration->
years);
281 str = strncat(str, num, count+2);
284 goto duration2string_num_calloc_failed;
287 if (duration->
months > 0) {
288 count = digits_in_number(duration->
months);
289 num = (
char*) calloc(count+2,
sizeof(
char));
291 snprintf(num, count+2,
"%uM", (uint32_t) duration->
months);
292 str = strncat(str, num, count+2);
295 goto duration2string_num_calloc_failed;
298 if (duration->
weeks > 0) {
299 count = digits_in_number(duration->
weeks);
300 num = (
char*) calloc(count+2,
sizeof(
char));
302 snprintf(num, count+2,
"%uW", (uint32_t) duration->
weeks);
303 str = strncat(str, num, count+2);
306 goto duration2string_num_calloc_failed;
309 if (duration->
days > 0) {
310 count = digits_in_number(duration->
days);
311 num = (
char*) calloc(count+2,
sizeof(
char));
313 snprintf(num, count+2,
"%uD", (uint32_t) duration->
days);
314 str = strncat(str, num, count+2);
317 goto duration2string_num_calloc_failed;
321 str = strncat(str,
"T", 1);
323 if (duration->
hours > 0) {
324 count = digits_in_number(duration->
hours);
325 num = (
char*) calloc(count+2,
sizeof(
char));
327 snprintf(num, count+2,
"%uH", (uint32_t) duration->
hours);
328 str = strncat(str, num, count+2);
331 goto duration2string_num_calloc_failed;
335 count = digits_in_number(duration->
minutes);
336 num = (
char*) calloc(count+2,
sizeof(
char));
338 snprintf(num, count+2,
"%uM", (uint32_t) duration->
minutes);
339 str = strncat(str, num, count+2);
342 goto duration2string_num_calloc_failed;
347 count = digits_in_number(duration->
seconds);
348 num = (
char*) calloc(count+2,
sizeof(
char));
350 snprintf(num, count+2,
"%uS", (uint32_t) duration->
seconds);
351 str = strncat(str, num, count+2);
354 goto duration2string_num_calloc_failed;
359 duration2string_num_calloc_failed:
360 ods_log_error(
"[%s] cannot create string: malloc error", duration_str);
378 period += (duration->
minutes)*60;
379 period += (duration->
hours)*3600;
380 period += (duration->
days)*86400;
381 period += (duration->
weeks)*86400*7;
382 period += (duration->
months)*86400*31;
383 period += (duration->
years)*86400*365;
389 duration_str, dstr?dstr:
"(null)");
403 return (a < b ? a : b);
413 return (a > b ? a : b);
424 #ifdef HAVE_ARC4RANDOM_UNIFORM 425 return (time_t) (arc4random_uniform((uint32_t) mod+1));
426 #elif HAVE_ARC4RANDOM 427 return (time_t) (arc4random() % (unsigned) mod+1);
429 return (time_t) (random() % (unsigned) mod+1);
435 static const int mdays[] = {
436 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
441 is_leap_year(
int year)
443 return year % 4 == 0 && (year % 100 != 0 || year % 400 == 0);
448 leap_days(
int y1,
int y2)
452 return (y2/4 - y1/4) - (y2/100 - y1/100) + (y2/400 - y1/400);
456 #ifdef ENFORCER_TIMESHIFT 462 mktime_from_utc(
const struct tm *tm)
464 int year = 1900 + tm->tm_year;
465 time_t days = 365 * ((time_t) (year - 1970)) +
466 ((time_t) leap_days(1970, year));
472 for (i = 0; i < tm->tm_mon; ++i) {
475 if (tm->tm_mon > 1 && is_leap_year(year)) {
478 days += tm->tm_mday - 1;
480 hours = days * 24 + tm->tm_hour;
481 minutes = hours * 60 + tm->tm_min;
482 seconds = minutes * 60 + tm->tm_sec;
493 timeshift2time(
const char *time)
497 time_t timeshift = 0;
500 if (strptime(time,
"%Y%m%d%H%M%S", &tm)) {
501 timeshift = mktime_from_utc(&tm);
515 #ifdef ENFORCER_TIMESHIFT 516 const char* env = getenv(
"ENFORCER_TIMESHIFT");
518 return timeshift2time(env);
546 ods_log_error(
"[%s] time_datestamp: localtime() failed", duration_str);
550 if (strftime(outstr,
sizeof(outstr), format, tmp) == 0) {
551 ods_log_error(
"[%s] time_datestamp: strftime() failed", duration_str);
555 ut = (uint32_t) strtoul(outstr, NULL, 10);
557 *str = strdup(outstr);
563 time_itoa_reverse(
char* s)
568 for (i = 0, j = strlen(s)-1; i<j; i++, j--) {
587 s[i++] = n % 10 +
'0';
588 }
while ((n /= 10) > 0);
590 time_itoa_reverse(s);
uint32_t time_datestamp(time_t tt, const char *format, char **str)
void * allocator_alloc(allocator_type *allocator, size_t size)
duration_type * duration_create(void)
void ods_log_error(const char *format,...)
void duration_cleanup(duration_type *duration)
time_t time_maximum(time_t a, time_t b)
allocator_type * allocator_create(void *(*allocator)(size_t size), void(*deallocator)(void *))
char * duration2string(duration_type *duration)
time_t duration2time(duration_type *duration)
int duration_compare(duration_type *d1, duration_type *d2)
void allocator_cleanup(allocator_type *allocator)
void time_itoa(time_t n, char *s)
void allocator_deallocate(allocator_type *allocator, void *data)
allocator_type * allocator
duration_type * duration_create_from_string(const char *str)
time_t ods_rand(time_t mod)
time_t time_minimum(time_t a, time_t b)
void ods_log_warning(const char *format,...)