diff --git a/cts/cli/regression.dates.exp b/cts/cli/regression.dates.exp index b72d92ae688..bb0378ab81d 100644 --- a/cts/cli/regression.dates.exp +++ b/cts/cli/regression.dates.exp @@ -64,7 +64,7 @@ iso8601: Invalid interval specified: P1Y/2019-02-29 00:00:00Z =#=#=#= End test: Invalid period - [P1Y/2019-02-29 00:00:00Z] - Invalid parameter (2) =#=#=#= * Passed: iso8601 - Invalid period - [P1Y/2019-02-29 00:00:00Z] =#=#=#= Begin test: Invalid period - [2019-01-01 00:00:00Z/P] =#=#=#= -crm_time_parse_duration error: 'P' is not a valid ISO 8601 time duration because nothing follows 'P' +pcmk__time_parse_duration error: 'P' is not a valid ISO 8601 time duration because nothing follows 'P' iso8601: Invalid interval specified: 2019-01-01 00:00:00Z/P =#=#=#= End test: Invalid period - [2019-01-01 00:00:00Z/P] - Invalid parameter (2) =#=#=#= * Passed: iso8601 - Invalid period - [2019-01-01 00:00:00Z/P] diff --git a/cts/cts-cli.in b/cts/cts-cli.in index 8f557ce4b45..b111a6055b7 100644 --- a/cts/cts-cli.in +++ b/cts/cts-cli.in @@ -251,7 +251,6 @@ def sanitize_output(s): (r'( -#include // time_t -#include // xmlNode -#include // GList, GHashTable +#include // bool +#include // uint64_t -#include // crm_time_t +#include // GList +#include // xmlNode -#include -#include -#include -#include -#include -#include +#include // pcmk_node_t, pcmk_scheduler_t #ifdef __cplusplus extern "C" { diff --git a/include/crm/pengine/status.h b/include/crm/pengine/status.h index 8d7722c72b0..d46428b6870 100644 --- a/include/crm/pengine/status.h +++ b/include/crm/pengine/status.h @@ -1,5 +1,5 @@ /* - * Copyright 2004-2025 the Pacemaker project contributors + * Copyright 2004-2026 the Pacemaker project contributors * * The version control history for this file may have further details. * @@ -12,7 +12,7 @@ # include // gboolean # include // bool -# include +# include // pe_find # include // pcmk_node_t, pcmk_resource_t, etc. # include diff --git a/include/pacemaker.h b/include/pacemaker.h index a766a964230..c474f2b18da 100644 --- a/include/pacemaker.h +++ b/include/pacemaker.h @@ -16,6 +16,7 @@ # include # include +# include // crm_time_t # include # include diff --git a/lib/common/crmcommon_private.h b/lib/common/crmcommon_private.h index a53ba60746e..55734a30e15 100644 --- a/lib/common/crmcommon_private.h +++ b/lib/common/crmcommon_private.h @@ -203,6 +203,14 @@ enum pcmk__time_component { pcmk__time_seconds, }; +G_GNUC_INTERNAL +void pcmk__time_get_timeofday(const crm_time_t *dt, uint32_t *hour, + uint32_t *minute, uint32_t *second); + +G_GNUC_INTERNAL +void pcmk__time_get_ymd(const crm_time_t *dt, uint32_t *year, uint32_t *month, + uint32_t *day); + G_GNUC_INTERNAL const char *pcmk__time_component_attr(enum pcmk__time_component component); diff --git a/lib/common/iso8601.c b/lib/common/iso8601.c index 083bc15dccb..363f2e7f503 100644 --- a/lib/common/iso8601.c +++ b/lib/common/iso8601.c @@ -74,20 +74,6 @@ ((QB_ABS(usec) < QB_TIME_US_IN_SEC) \ && (((sec) == 0) || ((usec) == 0) || (((sec) < 0) == ((usec) < 0)))) -/*! - * \brief Allocate memory for an uninitialized time object - * - * \return Newly allocated time object (guaranteed not to be \c NULL) - * - * \note The caller is responsible for freeing the return value using - * \c crm_time_free(). - */ -crm_time_t * -crm_time_new_undefined(void) -{ - return pcmk__assert_alloc(1, sizeof(crm_time_t)); -} - /*! * \internal * \brief Check whether a year is positive and representable by four digits @@ -454,7 +440,7 @@ valid_time(const crm_time_t *dt) static crm_time_t * parse_date(const char *date_str) { - const uint32_t flags = crm_time_log_date|crm_time_log_timeofday; + const uint32_t flags = pcmk__time_fmt_date|pcmk__time_fmt_time; const char *time_s = NULL; crm_time_t *dt = NULL; @@ -482,7 +468,7 @@ parse_date(const char *date_str) goto parse_time_segment; } - dt = crm_time_new_undefined(); + dt = pcmk__assert_alloc(1, sizeof(crm_time_t)); if ((strncasecmp(PCMK__VALUE_EPOCH, date_str, 5) == 0) && ((date_str[5] == '\0') @@ -633,14 +619,14 @@ parse_date(const char *date_str) static crm_time_t * copy_time_to_utc(const crm_time_t *dt) { - const uint32_t flags = crm_time_log_date - |crm_time_log_timeofday - |crm_time_log_with_timezone; + const uint32_t flags = pcmk__time_fmt_date + |pcmk__time_fmt_time + |pcmk__time_fmt_timezone; crm_time_t *utc = NULL; pcmk__assert(dt != NULL); - utc = crm_time_new_undefined(); + utc = pcmk__assert_alloc(1, sizeof(crm_time_t)); utc->years = dt->years; utc->days = dt->days; utc->seconds = dt->seconds; @@ -672,16 +658,21 @@ crm_time_new(const char *date_time) /*! * \brief Check whether a time object has been initialized yet * - * \param[in] t Time object to check + * \param[in] dt Time object to check * - * \return \c true if time object has been initialized, \c false otherwise + * \return \c true if time object has been initialized, or \c false otherwise */ bool -crm_time_is_defined(const crm_time_t *t) +pcmk__time_is_initialized(const crm_time_t *dt) { - // Any nonzero member indicates something has been done to t - return (t != NULL) && (t->years || t->months || t->days || t->seconds - || t->offset || t->duration); + // Any nonzero member indicates something has been done to dt + return (dt != NULL) + && ((dt->years != 0) + || (dt->months != 0) + || (dt->days != 0) + || (dt->seconds != 0) + || (dt->offset != 0) + || (dt->duration)); } void @@ -698,7 +689,7 @@ pcmk__time_log_as(const char *file, const char *function, int line, uint8_t level, const char *prefix, const crm_time_t *dt, uint32_t flags) { - char *date_s = crm_time_as_string(dt, flags); + char *date_s = pcmk__time_text(dt, flags); if (prefix != NULL) { char *old = date_s; @@ -715,18 +706,19 @@ pcmk__time_log_as(const char *file, const char *function, int line, free(date_s); } -int -crm_time_get_timeofday(const crm_time_t *dt, uint32_t *h, uint32_t *m, - uint32_t *s) +void +pcmk__time_get_timeofday(const crm_time_t *dt, uint32_t *hour, + uint32_t *minute, uint32_t *second) { - pcmk__assert((dt != NULL) && (h != NULL) && (m != NULL) && (s != NULL)); + pcmk__assert((dt != NULL) && (hour != NULL) && (minute != NULL) + && (second != NULL)); - seconds_to_hms(dt->seconds, h, m, s); - return TRUE; + seconds_to_hms(dt->seconds, hour, minute, second); } +// Time in seconds since 0000-01-01 00:00:00Z long long -crm_time_get_seconds(const crm_time_t *dt) +pcmk__time_get_seconds(const crm_time_t *dt) { crm_time_t *utc = NULL; long long days = 0; @@ -768,21 +760,22 @@ crm_time_get_seconds(const crm_time_t *dt) return seconds; } -#define EPOCH_SECONDS 62135596800ULL /* Calculated using crm_time_get_seconds() */ +#define EPOCH_SECONDS 62135596800ULL // Calculated using pcmk__time_get_seconds long long crm_time_get_seconds_since_epoch(const crm_time_t *dt) { - return (dt == NULL)? 0 : (crm_time_get_seconds(dt) - EPOCH_SECONDS); + return (dt == NULL)? 0 : (pcmk__time_get_seconds(dt) - EPOCH_SECONDS); } -int -crm_time_get_gregorian(const crm_time_t *dt, uint32_t *y, uint32_t *m, - uint32_t *d) +void +pcmk__time_get_ymd(const crm_time_t *dt, uint32_t *year, uint32_t *month, + uint32_t *day) { int months = 0; int days = dt->days; - pcmk__assert((dt != NULL) && (y != NULL) && (m != NULL) && (d != NULL)); + pcmk__assert((dt != NULL) && (year != NULL) && (month != NULL) + && (day != NULL)); if(dt->years != 0) { for (months = 1; months <= 12 && days > 0; months++) { @@ -803,22 +796,9 @@ crm_time_get_gregorian(const crm_time_t *dt, uint32_t *y, uint32_t *m, /* This is a duration not including months, still don't convert the days field */ } - *y = dt->years; - *m = months; - *d = days; - pcmk__trace("%.4d-%.3d -> %.4d-%.2d-%.2d", dt->years, dt->days, dt->years, - months, days); - return TRUE; -} - -int -crm_time_get_ordinal(const crm_time_t *dt, uint32_t *y, uint32_t *d) -{ - pcmk__assert((dt != NULL) && (y != NULL) && (d != NULL)); - - *y = dt->years; - *d = dt->days; - return TRUE; + *year = dt->years; + *month = months; + *day = days; } void @@ -1001,7 +981,7 @@ time_as_string_common(const crm_time_t *dt, int usec, uint32_t flags) GString *buf = NULL; char *result = NULL; - if (!crm_time_is_defined(dt)) { + if (!pcmk__time_is_initialized(dt)) { return pcmk__str_copy(""); } @@ -1013,21 +993,23 @@ time_as_string_common(const crm_time_t *dt, int usec, uint32_t flags) * These never depend on time zone. */ - if (pcmk__is_set(flags, crm_time_log_duration)) { - duration_as_string(dt, usec, pcmk__is_set(flags, crm_time_usecs), buf); + if (pcmk__is_set(flags, pcmk__time_fmt_duration)) { + duration_as_string(dt, usec, pcmk__is_set(flags, pcmk__time_fmt_usecs), + buf); goto done; } - if (pcmk__any_flags_set(flags, crm_time_seconds|crm_time_epoch)) { + if (pcmk__any_flags_set(flags, + pcmk__time_fmt_seconds|pcmk__time_fmt_epoch)) { long long seconds = 0; - if (pcmk__is_set(flags, crm_time_seconds)) { - seconds = crm_time_get_seconds(dt); + if (pcmk__is_set(flags, pcmk__time_fmt_seconds)) { + seconds = pcmk__time_get_seconds(dt); } else { seconds = crm_time_get_seconds_since_epoch(dt); } - if (pcmk__is_set(flags, crm_time_usecs)) { + if (pcmk__is_set(flags, pcmk__time_fmt_usecs)) { sec_usec_as_string(seconds, usec, buf); } else { g_string_append_printf(buf, "%lld", seconds); @@ -1036,15 +1018,15 @@ time_as_string_common(const crm_time_t *dt, int usec, uint32_t flags) } // Convert to UTC if local timezone was not requested - if ((dt->offset != 0) && !pcmk__is_set(flags, crm_time_log_with_timezone)) { + if ((dt->offset != 0) && !pcmk__is_set(flags, pcmk__time_fmt_timezone)) { utc = copy_time_to_utc(dt); dt = utc; } // As readable string - if (pcmk__is_set(flags, crm_time_log_date)) { - if (pcmk__is_set(flags, crm_time_weeks)) { // YYYY-WW-D + if (pcmk__is_set(flags, pcmk__time_fmt_date)) { + if (pcmk__is_set(flags, pcmk__time_fmt_weeks)) { // YYYY-WW-D if (dt->days > 0) { uint32_t y = 0; uint32_t w = 0; @@ -1056,47 +1038,37 @@ time_as_string_common(const crm_time_t *dt, int usec, uint32_t flags) y, w, d); } - } else if (pcmk__is_set(flags, crm_time_ordinal)) { // YYYY-DDD - uint32_t y = 0; - uint32_t d = 0; - - if (crm_time_get_ordinal(dt, &y, &d)) { - g_string_append_printf(buf, "%" PRIu32 "-%.3" PRIu32, y, d); - } + } else if (pcmk__is_set(flags, pcmk__time_fmt_ordinal)) { // YYYY-DDD + g_string_append_printf(buf, "%d-%.3d", dt->years, dt->days); } else { // YYYY-MM-DD uint32_t y = 0; uint32_t m = 0; uint32_t d = 0; - if (crm_time_get_gregorian(dt, &y, &m, &d)) { - g_string_append_printf(buf, - "%.4" PRIu32 "-%.2" PRIu32 "-%.2" PRIu32, - y, m, d); - } + pcmk__time_get_ymd(dt, &y, &m, &d); + g_string_append_printf(buf, + "%.4" PRIu32 "-%.2" PRIu32 "-%.2" PRIu32, + y, m, d); } } - if (pcmk__is_set(flags, crm_time_log_timeofday)) { + if (pcmk__is_set(flags, pcmk__time_fmt_time)) { uint32_t h = 0, m = 0, s = 0; if (buf->len > 0) { g_string_append_c(buf, ' '); } - if (crm_time_get_timeofday(dt, &h, &m, &s)) { - g_string_append_printf(buf, - "%.2" PRIu32 ":%.2" PRIu32 ":%.2" PRIu32, - h, m, s); + pcmk__time_get_timeofday(dt, &h, &m, &s); + g_string_append_printf(buf, "%.2" PRIu32 ":%.2" PRIu32 ":%.2" PRIu32, + h, m, s); - if (pcmk__is_set(flags, crm_time_usecs)) { - g_string_append_printf(buf, ".%06" PRIu32, QB_ABS(usec)); - } + if (pcmk__is_set(flags, pcmk__time_fmt_usecs)) { + g_string_append_printf(buf, ".%06" PRIu32, QB_ABS(usec)); } - if (pcmk__is_set(flags, crm_time_log_with_timezone) - && (dt->offset != 0)) { - + if (pcmk__is_set(flags, pcmk__time_fmt_timezone) && (dt->offset != 0)) { seconds_to_hms(dt->offset, &h, &m, NULL); g_string_append_printf(buf, " %c%.2" PRIu32 ":%.2" PRIu32, ((dt->offset < 0)? '-' : '+'), h, m); @@ -1114,15 +1086,16 @@ time_as_string_common(const crm_time_t *dt, int usec, uint32_t flags) } /*! - * \brief Get a string representation of a \p crm_time_t object + * \internal + * \brief Get a string representation of a \c crm_time_t object * - * \param[in] dt Time to convert to string - * \param[in] flags Group of \p crm_time_* string format options + * \param[in] dt Time to convert to string + * \param[in] flags Group of \c crm_time_* string format options * - * \note The caller is responsible for freeing the return value using \p free(). + * \note The caller is responsible for freeing the return value using \c free(). */ char * -crm_time_as_string(const crm_time_t *dt, int flags) +pcmk__time_text(const crm_time_t *dt, int flags) { return time_as_string_common(dt, 0, flags); } @@ -1282,18 +1255,19 @@ parse_duration_element(const char **element, const char *duration_s, } /*! + * \internal * \brief Parse a time duration from an ISO 8601 duration specification * * \param[in] period_s ISO 8601 duration specification (optionally followed by * whitespace, after which the rest of the string will be * ignored) * - * \return New time object on success, NULL (and set errno) otherwise - * \note It is the caller's responsibility to return the result using - * crm_time_free(). + * \return New time object on success, or \c NULL (and set \c errno) otherwise + * \note It is the caller's responsibility to free the result using + * \c crm_time_free(). */ crm_time_t * -crm_time_parse_duration(const char *period_s) +pcmk__time_parse_duration(const char *period_s) { bool is_time = false; crm_time_t *diff = NULL; @@ -1315,7 +1289,7 @@ crm_time_parse_duration(const char *period_s) goto invalid; } - diff = crm_time_new_undefined(); + diff = pcmk__assert_alloc(1, sizeof(crm_time_t)); for (const char *current = period_s + 1; current[0] && (current[0] != '/') && !isspace(current[0]); @@ -1337,17 +1311,20 @@ crm_time_parse_duration(const char *period_s) } } - if (!crm_time_is_defined(diff)) { + if (!pcmk__time_is_initialized(diff)) { pcmk__err("'%s' is not a valid ISO 8601 time duration because no " "amounts and units given", period_s); goto invalid; } - diff->duration = TRUE; + diff->duration = true; return diff; invalid: + /* @COMPAT Setting errno is required only for backward compatibility with + * crm_time_parse_duration() + */ crm_time_free(diff); errno = EINVAL; return NULL; @@ -1363,14 +1340,14 @@ crm_time_parse_duration(const char *period_s) void pcmk__set_time_if_earlier(crm_time_t *target, const crm_time_t *source) { - const int flags = crm_time_log_date - |crm_time_log_timeofday - |crm_time_log_with_timezone; + const int flags = pcmk__time_fmt_date + |pcmk__time_fmt_time + |pcmk__time_fmt_timezone; if ((target == NULL) || (source == NULL) - || (crm_time_is_defined(target) - && (crm_time_compare(source, target) >= 0))) { + || (pcmk__time_is_initialized(target) + && (pcmk__time_compare(source, target) >= 0))) { return; } @@ -1383,7 +1360,7 @@ pcmk__set_time_if_earlier(crm_time_t *target, const crm_time_t *source) crm_time_t * pcmk_copy_time(const crm_time_t *source) { - crm_time_t *target = crm_time_new_undefined(); + crm_time_t *target = pcmk__assert_alloc(1, sizeof(crm_time_t)); *target = *source; return target; @@ -1404,7 +1381,7 @@ crm_time_t * pcmk__copy_timet(time_t source_sec) { const struct tm *source = localtime(&source_sec); - crm_time_t *target = crm_time_new_undefined(); + crm_time_t *target = pcmk__assert_alloc(1, sizeof(crm_time_t)); int h_offset = 0; int m_offset = 0; @@ -1634,12 +1611,6 @@ subtract_time(const crm_time_t *dt1, const crm_time_t *dt2, bool as_duration) return result; } -crm_time_t * -crm_time_calculate_duration(const crm_time_t *dt, const crm_time_t *value) -{ - return subtract_time(dt, value, true); -} - crm_time_t * crm_time_subtract(const crm_time_t *dt, const crm_time_t *value) { @@ -1660,7 +1631,7 @@ crm_time_subtract(const crm_time_t *dt, const crm_time_t *value) } int -crm_time_compare(const crm_time_t *a, const crm_time_t *b) +pcmk__time_compare(const crm_time_t *a, const crm_time_t *b) { int rc = 0; crm_time_t *t1 = NULL; @@ -1765,7 +1736,7 @@ crm_time_add_months(crm_time_t *dt, int value) uint32_t day = 0; int days_in_month = 0; - crm_time_get_gregorian(dt, &year, &month, &day); + pcmk__time_get_ymd(dt, &year, &month, &day); if (value > 0) { for (int i = value; i > 0; i--) { @@ -2109,7 +2080,7 @@ pcmk__epoch2str(const time_t *source, uint32_t flags) } dt = pcmk__copy_timet(epoch_time); - result = crm_time_as_string(dt, flags); + result = pcmk__time_text(dt, flags); crm_time_free(dt); return result; @@ -2120,8 +2091,8 @@ pcmk__epoch2str(const time_t *source, uint32_t flags) * \brief Return a human-friendly string corresponding to seconds-and- * nanoseconds value * - * Time is shown with microsecond resolution if \p crm_time_usecs is in \p - * flags. + * Time is shown with microsecond resolution if \c pcmk__time_fmt_usecs is in + * \p flags. * * \param[in] ts Time in seconds and nanoseconds (or \p NULL for current * time) @@ -2251,9 +2222,9 @@ crm_time_january1_weekday(int year) void crm_time_set(crm_time_t *target, const crm_time_t *source) { - const uint32_t flags = crm_time_log_date - |crm_time_log_timeofday - |crm_time_log_with_timezone; + const uint32_t flags = pcmk__time_fmt_date + |pcmk__time_fmt_time + |pcmk__time_fmt_timezone; pcmk__trace("target=%p, source=%p", target, source); @@ -2335,7 +2306,7 @@ crm_time_parse_period(const char *period_str) period = pcmk__assert_alloc(1, sizeof(crm_time_period_t)); if (period_str[0] == 'P') { - period->diff = crm_time_parse_duration(period_str); + period->diff = pcmk__time_parse_duration(period_str); if (period->diff == NULL) { goto invalid; } @@ -2356,7 +2327,7 @@ crm_time_parse_period(const char *period_str) original); goto invalid; } - period->diff = crm_time_parse_duration(period_str); + period->diff = pcmk__time_parse_duration(period_str); if (period->diff == NULL) { goto invalid; } @@ -2412,5 +2383,73 @@ crm_time_parse_period(const char *period_str) return NULL; } +crm_time_t * +crm_time_calculate_duration(const crm_time_t *dt, const crm_time_t *value) +{ + return subtract_time(dt, value, true); +} + +crm_time_t * +crm_time_parse_duration(const char *period_s) +{ + return pcmk__time_parse_duration(period_s); +} + +crm_time_t * +crm_time_new_undefined(void) +{ + return pcmk__assert_alloc(1, sizeof(crm_time_t)); +} + +bool +crm_time_is_defined(const crm_time_t *t) +{ + return pcmk__time_is_initialized(t); +} + +char * +crm_time_as_string(const crm_time_t *dt, int flags) +{ + return pcmk__time_text(dt, flags); +} + +int +crm_time_compare(const crm_time_t *a, const crm_time_t *b) +{ + return pcmk__time_compare(a, b); +} + +int +crm_time_get_timeofday(const crm_time_t *dt, uint32_t *h, uint32_t *m, + uint32_t *s) +{ + pcmk__time_get_timeofday(dt, h, m, s); + return TRUE; +} + +int +crm_time_get_gregorian(const crm_time_t *dt, uint32_t *y, uint32_t *m, + uint32_t *d) +{ + pcmk__time_get_ymd(dt, y, m, d); + return TRUE; +} + +int +crm_time_get_ordinal(const crm_time_t *dt, uint32_t *y, uint32_t *d) +{ + pcmk__assert((dt != NULL) && (y != NULL) && (d != NULL)); + + *y = dt->years; + *d = dt->days; + return TRUE; +} + +long long +crm_time_get_seconds(const crm_time_t *dt) +{ + return pcmk__time_get_seconds(dt); +} + // LCOV_EXCL_STOP // End deprecated API diff --git a/lib/common/rules.c b/lib/common/rules.c index b840245bc4c..847a11b60ce 100644 --- a/lib/common/rules.c +++ b/lib/common/rules.c @@ -184,15 +184,15 @@ pcmk__evaluate_date_spec(const xmlNode *date_spec, const crm_time_t *now) } // Year, month, day - crm_time_get_gregorian(now, &(ranges[0].value), &(ranges[1].value), - &(ranges[2].value)); + pcmk__time_get_ymd(now, &(ranges[0].value), &(ranges[1].value), + &(ranges[2].value)); // Hour, minute, second - crm_time_get_timeofday(now, &(ranges[3].value), &(ranges[4].value), - &(ranges[5].value)); + pcmk__time_get_timeofday(now, &(ranges[3].value), &(ranges[4].value), + &(ranges[5].value)); - // Year (redundant) and day of year - crm_time_get_ordinal(now, &(ranges[0].value), &(ranges[6].value)); + // Day of year + ranges[6].value = now->days; // Week year, week of week year, day of week pcmk__time_get_ywd(now, &(ranges[7].value), &(ranges[8].value), @@ -332,7 +332,7 @@ evaluate_in_range(const xmlNode *date_expression, const char *id, } } - if ((start != NULL) && (crm_time_compare(now, start) < 0)) { + if ((start != NULL) && (pcmk__time_compare(now, start) < 0)) { pcmk__set_time_if_earlier(next_change, start); crm_time_free(start); crm_time_free(end); @@ -340,7 +340,7 @@ evaluate_in_range(const xmlNode *date_expression, const char *id, } if (end != NULL) { - if (crm_time_compare(now, end) > 0) { + if (pcmk__time_compare(now, end) > 0) { crm_time_free(start); crm_time_free(end); return pcmk_rc_after_range; @@ -392,7 +392,7 @@ evaluate_gt(const xmlNode *date_expression, const char *id, return pcmk_rc_unpack_error; } - if (crm_time_compare(now, start) > 0) { + if (pcmk__time_compare(now, start) > 0) { crm_time_free(start); return pcmk_rc_within_range; } @@ -437,7 +437,7 @@ evaluate_lt(const xmlNode *date_expression, const char *id, return pcmk_rc_unpack_error; } - if (crm_time_compare(now, end) < 0) { + if (pcmk__time_compare(now, end) < 0) { pcmk__set_time_if_earlier(next_change, end); crm_time_free(end); return pcmk_rc_within_range; diff --git a/lib/common/strings.c b/lib/common/strings.c index 72ea9f02213..0a6feff7b19 100644 --- a/lib/common/strings.c +++ b/lib/common/strings.c @@ -372,10 +372,10 @@ pcmk_parse_interval_spec(const char *input, unsigned int *result_ms) } if (input[0] == 'P') { - crm_time_t *period_s = crm_time_parse_duration(input); + crm_time_t *period_s = pcmk__time_parse_duration(input); if (period_s != NULL) { - msec = crm_time_get_seconds(period_s); + msec = pcmk__time_get_seconds(period_s); msec = QB_MIN(msec, UINT_MAX / 1000) * 1000; crm_time_free(period_s); } diff --git a/lib/common/tests/iso8601/Makefile.am b/lib/common/tests/iso8601/Makefile.am index 92ac3b5b273..8dd1ef06f48 100644 --- a/lib/common/tests/iso8601/Makefile.am +++ b/lib/common/tests/iso8601/Makefile.am @@ -15,10 +15,10 @@ include $(top_srcdir)/mk/unittest.mk check_PROGRAMS = crm_time_add_days_test check_PROGRAMS += crm_time_add_seconds_test check_PROGRAMS += crm_time_add_years_test -check_PROGRAMS += crm_time_parse_duration_test check_PROGRAMS += pcmk__add_time_from_xml_test check_PROGRAMS += pcmk__readable_interval_test check_PROGRAMS += pcmk__set_time_if_earlier_test check_PROGRAMS += pcmk__time_format_hr_test +check_PROGRAMS += pcmk__time_parse_duration_test TESTS = $(check_PROGRAMS) diff --git a/lib/common/tests/iso8601/crm_time_add_days_test.c b/lib/common/tests/iso8601/crm_time_add_days_test.c index c9ad3616d78..b7995355b48 100644 --- a/lib/common/tests/iso8601/crm_time_add_days_test.c +++ b/lib/common/tests/iso8601/crm_time_add_days_test.c @@ -1,5 +1,5 @@ /* - * Copyright 2024-2025 the Pacemaker project contributors + * Copyright 2024-2026 the Pacemaker project contributors * * The version control history for this file may have further details. * @@ -27,7 +27,7 @@ assert_add_days(const char *orig_date_time, int days, assert_non_null(expected); crm_time_add_days(orig, days); - assert_int_equal(crm_time_compare(orig, expected), 0); + assert_int_equal(pcmk__time_compare(orig, expected), 0); crm_time_free(orig); crm_time_free(expected); diff --git a/lib/common/tests/iso8601/crm_time_add_seconds_test.c b/lib/common/tests/iso8601/crm_time_add_seconds_test.c index 4315d7dcb5d..6cb957e689b 100644 --- a/lib/common/tests/iso8601/crm_time_add_seconds_test.c +++ b/lib/common/tests/iso8601/crm_time_add_seconds_test.c @@ -1,5 +1,5 @@ /* - * Copyright 2024 the Pacemaker project contributors + * Copyright 2024-2026 the Pacemaker project contributors * * The version control history for this file may have further details. * @@ -27,7 +27,7 @@ assert_add_seconds(const char *orig_date_time, int seconds, assert_non_null(expected); crm_time_add_seconds(orig, seconds); - assert_int_equal(crm_time_compare(orig, expected), 0); + assert_int_equal(pcmk__time_compare(orig, expected), 0); crm_time_free(orig); crm_time_free(expected); diff --git a/lib/common/tests/iso8601/crm_time_add_years_test.c b/lib/common/tests/iso8601/crm_time_add_years_test.c index 8ea6b4d1c46..35831673cdb 100644 --- a/lib/common/tests/iso8601/crm_time_add_years_test.c +++ b/lib/common/tests/iso8601/crm_time_add_years_test.c @@ -1,5 +1,5 @@ /* - * Copyright 2024-2025 the Pacemaker project contributors + * Copyright 2024-2026 the Pacemaker project contributors * * The version control history for this file may have further details. * @@ -27,7 +27,7 @@ assert_add_years(const char *orig_date_time, int years, assert_non_null(expected); crm_time_add_years(orig, years); - assert_int_equal(crm_time_compare(orig, expected), 0); + assert_int_equal(pcmk__time_compare(orig, expected), 0); crm_time_free(orig); crm_time_free(expected); diff --git a/lib/common/tests/iso8601/crm_time_parse_duration_test.c b/lib/common/tests/iso8601/crm_time_parse_duration_test.c deleted file mode 100644 index 58015e82422..00000000000 --- a/lib/common/tests/iso8601/crm_time_parse_duration_test.c +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright 2024 the Pacemaker project contributors - * - * The version control history for this file may have further details. - * - * This source code is licensed under the GNU General Public License version 2 - * or later (GPLv2+) WITHOUT ANY WARRANTY. - */ - -#include - -#include - -#include -#include "crmcommon_private.h" - -static void -empty_arg(void **state) -{ - assert_null(crm_time_parse_duration(NULL)); - assert_null(crm_time_parse_duration("")); -} - -static void -invalid_arg(void **state) -{ - // Valid except doesn't start with P - assert_null(crm_time_parse_duration("X3Y6M4DT12H30M5S")); - - // Illegal character after P - assert_null(crm_time_parse_duration("P")); - assert_null(crm_time_parse_duration("P 3Y6M4DT12H30M5S")); - assert_null(crm_time_parse_duration("PX3Y6M4DT12H30M5S")); - - // Missing or invalid units - assert_null(crm_time_parse_duration("P3Y6M4DT12H30M5")); - assert_null(crm_time_parse_duration("P3Y6M4DT12H30M5X")); - assert_null(crm_time_parse_duration("P3X6M4DT12H30M5S")); - assert_null(crm_time_parse_duration("PT")); - assert_null(crm_time_parse_duration("P/")); - -#if 0 - // @TODO The current implementation treats these as valid - - // Units out of order - assert_null(crm_time_parse_duration("P6M3Y4DT12H30M5S")); - assert_null(crm_time_parse_duration("P6M3DT12HY430M5S")); - - // Same unit specified multiple times - assert_null(crm_time_parse_duration("P6Y4M3D1MT12H30M5S")); - - // Weeks mixed with other units - assert_null(crm_time_parse_duration("P6Y4M3W3D1MT12H30M5S")); - assert_null(crm_time_parse_duration("P3WT12H30M5S")); -#endif -} - -static void -overflow(void **state) -{ - // Too large - assert_null(crm_time_parse_duration("P2147483648Y6M4DT12H30M5S")); - assert_null(crm_time_parse_duration("P3Y2147483648M4DT12H30M5S")); - assert_null(crm_time_parse_duration("P3Y6M2147483648DT12H30M5S")); - assert_null(crm_time_parse_duration("P3Y6M4DT2147483648H30M5S")); - assert_null(crm_time_parse_duration("P3Y6M4DT12H2147483648M5S")); - assert_null(crm_time_parse_duration("P3Y6M4DT12H30MP2147483648S")); - - // Too small - assert_null(crm_time_parse_duration("P-2147483648Y6M4DT12H30M5S")); - assert_null(crm_time_parse_duration("P3Y-2147483648M4DT12H30M5S")); - assert_null(crm_time_parse_duration("P3Y6M-2147483648DT12H30M5S")); - assert_null(crm_time_parse_duration("P3Y6M4DT-2147483648H30M5S")); - assert_null(crm_time_parse_duration("P3Y6M4DT12H-2147483648M5S")); - assert_null(crm_time_parse_duration("P3Y6M4DT12H30MP-2147483648S")); -} - -static void -valid_arg(void **state) -{ - // @TODO Check result value - assert_non_null(crm_time_parse_duration("P3Y6M4DT12H30M5S")); - assert_non_null(crm_time_parse_duration("P3Y6M4DT12H30M-5S")); - assert_non_null(crm_time_parse_duration("P3Y6M4DT12H-30M5S")); - assert_non_null(crm_time_parse_duration("P3Y6M4DT-12H30M5S")); - assert_non_null(crm_time_parse_duration("P3Y6M-4DT12H30M5S")); - assert_non_null(crm_time_parse_duration("P3Y-6M4DT12H30M5S")); - assert_non_null(crm_time_parse_duration("P3Y6M4DT12H30M")); - assert_non_null(crm_time_parse_duration("P3Y6M4D")); - assert_non_null(crm_time_parse_duration("P1M")); // 1 month - assert_non_null(crm_time_parse_duration("PT1M")); // 1 minute - assert_non_null(crm_time_parse_duration("P7W")); - -#if 0 - // @TODO Current implementation can't handle these cases - - // Fractional value for last unit - assert_non_null(crm_time_parse_duration("P3Y6M4DT12H30.5M")); - assert_non_null(crm_time_parse_duration("P3Y6M4DT12H30,5M")); - - // P--
T:: format - assert_non_null(crm_time_parse_duration("P0003-02-01T11:10:09"); -#endif -} - -PCMK__UNIT_TEST(NULL, NULL, - cmocka_unit_test(empty_arg), - cmocka_unit_test(invalid_arg), - cmocka_unit_test(overflow), - cmocka_unit_test(valid_arg)); diff --git a/lib/common/tests/iso8601/pcmk__add_time_from_xml_test.c b/lib/common/tests/iso8601/pcmk__add_time_from_xml_test.c index fa7f6ab183e..ebea2842ab6 100644 --- a/lib/common/tests/iso8601/pcmk__add_time_from_xml_test.c +++ b/lib/common/tests/iso8601/pcmk__add_time_from_xml_test.c @@ -1,5 +1,5 @@ /* - * Copyright 2024 the Pacemaker project contributors + * Copyright 2024-2026 the Pacemaker project contributors * * The version control history for this file may have further details. * @@ -45,7 +45,7 @@ null_xml_ok(void **state) assert_int_equal(pcmk__add_time_from_xml(t, pcmk__time_years, NULL), pcmk_rc_ok); - assert_int_equal(crm_time_compare(t, reference), 0); + assert_int_equal(pcmk__time_compare(t, reference), 0); crm_time_free(t); crm_time_free(reference); @@ -70,7 +70,7 @@ missing_attr(void **state) assert_int_equal(pcmk__add_time_from_xml(t, pcmk__time_months, xml), pcmk_rc_ok); - assert_int_equal(crm_time_compare(t, reference), 0); + assert_int_equal(pcmk__time_compare(t, reference), 0); crm_time_free(t); crm_time_free(reference); @@ -86,7 +86,7 @@ invalid_attr(void **state) assert_int_equal(pcmk__add_time_from_xml(t, pcmk__time_years, xml), pcmk_rc_unpack_error); - assert_int_equal(crm_time_compare(t, reference), 0); + assert_int_equal(pcmk__time_compare(t, reference), 0); crm_time_free(t); crm_time_free(reference); @@ -102,12 +102,12 @@ out_of_range_attr(void **state) xml = pcmk__xml_parse(YEARS_TOO_BIG); assert_int_equal(pcmk__add_time_from_xml(t, pcmk__time_years, xml), ERANGE); - assert_int_equal(crm_time_compare(t, reference), 0); + assert_int_equal(pcmk__time_compare(t, reference), 0); pcmk__xml_free(xml); xml = pcmk__xml_parse(YEARS_TOO_SMALL); assert_int_equal(pcmk__add_time_from_xml(t, pcmk__time_years, xml), ERANGE); - assert_int_equal(crm_time_compare(t, reference), 0); + assert_int_equal(pcmk__time_compare(t, reference), 0); pcmk__xml_free(xml); crm_time_free(t); @@ -123,7 +123,7 @@ add_years(void **state) assert_int_equal(pcmk__add_time_from_xml(t, pcmk__time_years, xml), pcmk_rc_ok); - assert_int_equal(crm_time_compare(t, reference), 0); + assert_int_equal(pcmk__time_compare(t, reference), 0); crm_time_free(t); crm_time_free(reference); @@ -139,7 +139,7 @@ add_months(void **state) assert_int_equal(pcmk__add_time_from_xml(t, pcmk__time_months, xml), pcmk_rc_ok); - assert_int_equal(crm_time_compare(t, reference), 0); + assert_int_equal(pcmk__time_compare(t, reference), 0); crm_time_free(t); crm_time_free(reference); @@ -155,7 +155,7 @@ add_weeks(void **state) assert_int_equal(pcmk__add_time_from_xml(t, pcmk__time_weeks, xml), pcmk_rc_ok); - assert_int_equal(crm_time_compare(t, reference), 0); + assert_int_equal(pcmk__time_compare(t, reference), 0); crm_time_free(t); crm_time_free(reference); @@ -171,7 +171,7 @@ add_days(void **state) assert_int_equal(pcmk__add_time_from_xml(t, pcmk__time_days, xml), pcmk_rc_ok); - assert_int_equal(crm_time_compare(t, reference), 0); + assert_int_equal(pcmk__time_compare(t, reference), 0); crm_time_free(t); crm_time_free(reference); @@ -187,7 +187,7 @@ add_hours(void **state) assert_int_equal(pcmk__add_time_from_xml(t, pcmk__time_hours, xml), pcmk_rc_ok); - assert_int_equal(crm_time_compare(t, reference), 0); + assert_int_equal(pcmk__time_compare(t, reference), 0); crm_time_free(t); crm_time_free(reference); @@ -203,7 +203,7 @@ add_minutes(void **state) assert_int_equal(pcmk__add_time_from_xml(t, pcmk__time_minutes, xml), pcmk_rc_ok); - assert_int_equal(crm_time_compare(t, reference), 0); + assert_int_equal(pcmk__time_compare(t, reference), 0); crm_time_free(t); crm_time_free(reference); @@ -219,7 +219,7 @@ add_seconds(void **state) assert_int_equal(pcmk__add_time_from_xml(t, pcmk__time_seconds, xml), pcmk_rc_ok); - assert_int_equal(crm_time_compare(t, reference), 0); + assert_int_equal(pcmk__time_compare(t, reference), 0); crm_time_free(t); crm_time_free(reference); diff --git a/lib/common/tests/iso8601/pcmk__set_time_if_earlier_test.c b/lib/common/tests/iso8601/pcmk__set_time_if_earlier_test.c index c4bf0140825..86d82cb8bab 100644 --- a/lib/common/tests/iso8601/pcmk__set_time_if_earlier_test.c +++ b/lib/common/tests/iso8601/pcmk__set_time_if_earlier_test.c @@ -1,5 +1,5 @@ /* - * Copyright 2024 the Pacemaker project contributors + * Copyright 2024-2026 the Pacemaker project contributors * * The version control history for this file may have further details. * @@ -26,7 +26,7 @@ null_ok(void **state) // Shouldn't assert, crash, or change target pcmk__set_time_if_earlier(target, NULL); - assert_int_equal(crm_time_compare(target, target_copy), 0); + assert_int_equal(pcmk__time_compare(target, target_copy), 0); crm_time_free(target); crm_time_free(target_copy); @@ -36,10 +36,10 @@ static void target_undefined(void **state) { crm_time_t *source = crm_time_new("2024-01-01 00:29:59 +01:00"); - crm_time_t *target = crm_time_new_undefined(); + crm_time_t *target = pcmk__assert_alloc(1, sizeof(crm_time_t)); pcmk__set_time_if_earlier(target, source); - assert_int_equal(crm_time_compare(target, source), 0); + assert_int_equal(pcmk__time_compare(target, source), 0); crm_time_free(source); crm_time_free(target); @@ -52,7 +52,7 @@ source_earlier(void **state) crm_time_t *target = crm_time_new("2024-01-01 00:30:00 +01:00"); pcmk__set_time_if_earlier(target, source); - assert_int_equal(crm_time_compare(target, source), 0); + assert_int_equal(pcmk__time_compare(target, source), 0); crm_time_free(source); crm_time_free(target); @@ -66,7 +66,7 @@ source_later(void **state) crm_time_t *target_copy = pcmk_copy_time(target); pcmk__set_time_if_earlier(target, source); - assert_int_equal(crm_time_compare(target, target_copy), 0); + assert_int_equal(pcmk__time_compare(target, target_copy), 0); crm_time_free(source); crm_time_free(target); diff --git a/lib/common/tests/iso8601/pcmk__time_parse_duration_test.c b/lib/common/tests/iso8601/pcmk__time_parse_duration_test.c new file mode 100644 index 00000000000..76acc590741 --- /dev/null +++ b/lib/common/tests/iso8601/pcmk__time_parse_duration_test.c @@ -0,0 +1,110 @@ +/* + * Copyright 2024-2026 the Pacemaker project contributors + * + * The version control history for this file may have further details. + * + * This source code is licensed under the GNU General Public License version 2 + * or later (GPLv2+) WITHOUT ANY WARRANTY. + */ + +#include + +#include + +#include +#include "crmcommon_private.h" + +static void +empty_arg(void **state) +{ + assert_null(pcmk__time_parse_duration(NULL)); + assert_null(pcmk__time_parse_duration("")); +} + +static void +invalid_arg(void **state) +{ + // Valid except doesn't start with P + assert_null(pcmk__time_parse_duration("X3Y6M4DT12H30M5S")); + + // Illegal character after P + assert_null(pcmk__time_parse_duration("P")); + assert_null(pcmk__time_parse_duration("P 3Y6M4DT12H30M5S")); + assert_null(pcmk__time_parse_duration("PX3Y6M4DT12H30M5S")); + + // Missing or invalid units + assert_null(pcmk__time_parse_duration("P3Y6M4DT12H30M5")); + assert_null(pcmk__time_parse_duration("P3Y6M4DT12H30M5X")); + assert_null(pcmk__time_parse_duration("P3X6M4DT12H30M5S")); + assert_null(pcmk__time_parse_duration("PT")); + assert_null(pcmk__time_parse_duration("P/")); + +#if 0 + // @TODO The current implementation treats these as valid + + // Units out of order + assert_null(pcmk__time_parse_duration("P6M3Y4DT12H30M5S")); + assert_null(pcmk__time_parse_duration("P6M3DT12HY430M5S")); + + // Same unit specified multiple times + assert_null(pcmk__time_parse_duration("P6Y4M3D1MT12H30M5S")); + + // Weeks mixed with other units + assert_null(pcmk__time_parse_duration("P6Y4M3W3D1MT12H30M5S")); + assert_null(pcmk__time_parse_duration("P3WT12H30M5S")); +#endif +} + +static void +overflow(void **state) +{ + // Too large + assert_null(pcmk__time_parse_duration("P2147483648Y6M4DT12H30M5S")); + assert_null(pcmk__time_parse_duration("P3Y2147483648M4DT12H30M5S")); + assert_null(pcmk__time_parse_duration("P3Y6M2147483648DT12H30M5S")); + assert_null(pcmk__time_parse_duration("P3Y6M4DT2147483648H30M5S")); + assert_null(pcmk__time_parse_duration("P3Y6M4DT12H2147483648M5S")); + assert_null(pcmk__time_parse_duration("P3Y6M4DT12H30MP2147483648S")); + + // Too small + assert_null(pcmk__time_parse_duration("P-2147483648Y6M4DT12H30M5S")); + assert_null(pcmk__time_parse_duration("P3Y-2147483648M4DT12H30M5S")); + assert_null(pcmk__time_parse_duration("P3Y6M-2147483648DT12H30M5S")); + assert_null(pcmk__time_parse_duration("P3Y6M4DT-2147483648H30M5S")); + assert_null(pcmk__time_parse_duration("P3Y6M4DT12H-2147483648M5S")); + assert_null(pcmk__time_parse_duration("P3Y6M4DT12H30MP-2147483648S")); +} + +static void +valid_arg(void **state) +{ + // @TODO Check result value + assert_non_null(pcmk__time_parse_duration("P3Y6M4DT12H30M5S")); + assert_non_null(pcmk__time_parse_duration("P3Y6M4DT12H30M-5S")); + assert_non_null(pcmk__time_parse_duration("P3Y6M4DT12H-30M5S")); + assert_non_null(pcmk__time_parse_duration("P3Y6M4DT-12H30M5S")); + assert_non_null(pcmk__time_parse_duration("P3Y6M-4DT12H30M5S")); + assert_non_null(pcmk__time_parse_duration("P3Y-6M4DT12H30M5S")); + assert_non_null(pcmk__time_parse_duration("P3Y6M4DT12H30M")); + assert_non_null(pcmk__time_parse_duration("P3Y6M4D")); + assert_non_null(pcmk__time_parse_duration("P1M")); // 1 month + assert_non_null(pcmk__time_parse_duration("PT1M")); // 1 minute + assert_non_null(pcmk__time_parse_duration("P7W")); + +#if 0 + // @TODO Current implementation can't handle these cases + + // Fractional value for last unit + assert_non_null(pcmk__time_parse_duration("P3Y6M4DT12H30.5M")); + assert_non_null(pcmk__time_parse_duration("P3Y6M4DT12H30,5M")); + + // P--
T:: format + assert_non_null(pcmk__time_parse_duration("P0003-02-01T11:10:09"); +#endif +} + +PCMK__UNIT_TEST(NULL, NULL, + cmocka_unit_test(empty_arg), + cmocka_unit_test(invalid_arg), + cmocka_unit_test(overflow), + cmocka_unit_test(valid_arg)); diff --git a/lib/common/tests/nvpair/pcmk__unpack_nvpair_blocks_test.c b/lib/common/tests/nvpair/pcmk__unpack_nvpair_blocks_test.c index 6bea483f134..c2e9e7a9e9a 100644 --- a/lib/common/tests/nvpair/pcmk__unpack_nvpair_blocks_test.c +++ b/lib/common/tests/nvpair/pcmk__unpack_nvpair_blocks_test.c @@ -144,7 +144,7 @@ rule_fails(void **state) assert_string_equal(g_hash_table_lookup(values, "name1"), "3"); assert_string_equal(g_hash_table_lookup(values, "name2"), "3"); assert_string_equal(g_hash_table_lookup(values, "name3"), "3"); - assert_int_equal(crm_time_compare(next_change, expected_next_change), 0); + assert_int_equal(pcmk__time_compare(next_change, expected_next_change), 0); pcmk__xml_free(xml); crm_time_free(now); diff --git a/lib/common/tests/rules/pcmk__evaluate_condition_test.c b/lib/common/tests/rules/pcmk__evaluate_condition_test.c index be0931a0267..32d1ab23048 100644 --- a/lib/common/tests/rules/pcmk__evaluate_condition_test.c +++ b/lib/common/tests/rules/pcmk__evaluate_condition_test.c @@ -42,7 +42,7 @@ static void null_invalid(void **state) { xmlNode *xml = NULL; - crm_time_t *next_change = crm_time_new_undefined(); + crm_time_t *next_change = pcmk__assert_alloc(1, sizeof(crm_time_t)); assert_int_equal(pcmk__evaluate_condition(NULL, NULL, next_change), EINVAL); @@ -63,7 +63,7 @@ static void invalid_expression(void **state) { xmlNode *xml = pcmk__xml_parse(EXPR_INVALID); - crm_time_t *next_change = crm_time_new_undefined(); + crm_time_t *next_change = pcmk__assert_alloc(1, sizeof(crm_time_t)); assert_int_equal(pcmk__evaluate_condition(xml, &rule_input, next_change), pcmk_rc_unpack_error); @@ -130,7 +130,7 @@ date_expression(void **state) rule_input.now = now; assert_int_equal(pcmk__evaluate_condition(xml, &rule_input, next_change), pcmk_rc_before_range); - assert_int_equal(crm_time_compare(next_change, reference), 0); + assert_int_equal(pcmk__time_compare(next_change, reference), 0); rule_input.now = NULL; crm_time_free(reference); diff --git a/lib/common/tests/rules/pcmk__evaluate_date_expression_test.c b/lib/common/tests/rules/pcmk__evaluate_date_expression_test.c index cfb6bdbf7f5..bed8fc3e998 100644 --- a/lib/common/tests/rules/pcmk__evaluate_date_expression_test.c +++ b/lib/common/tests/rules/pcmk__evaluate_date_expression_test.c @@ -1,5 +1,5 @@ /* - * Copyright 2024-2025 the Pacemaker project contributors + * Copyright 2024-2026 the Pacemaker project contributors * * The version control history for this file may have further details. * @@ -52,7 +52,7 @@ assert_date_expression(const xmlNode *xml, const char *now_s, if (check_next_change) { crm_time_t *reference = crm_time_new(reference_s); - assert_int_equal(crm_time_compare(next_change, reference), 0); + assert_int_equal(pcmk__time_compare(next_change, reference), 0); crm_time_free(reference); crm_time_free(next_change); } diff --git a/lib/common/tests/rules/pcmk__unpack_duration_test.c b/lib/common/tests/rules/pcmk__unpack_duration_test.c index 2eba68e24e7..978dd8d1bab 100644 --- a/lib/common/tests/rules/pcmk__unpack_duration_test.c +++ b/lib/common/tests/rules/pcmk__unpack_duration_test.c @@ -1,5 +1,5 @@ /* - * Copyright 2024 the Pacemaker project contributors + * Copyright 2024-2026 the Pacemaker project contributors * * The version control history for this file may have further details. * @@ -99,7 +99,7 @@ all_valid(void **state) crm_time_t *reference = crm_time_new("2025-03-21 16:01:01"); assert_int_equal(pcmk__unpack_duration(duration, start, &end), pcmk_rc_ok); - assert_int_equal(crm_time_compare(end, reference), 0); + assert_int_equal(pcmk__time_compare(end, reference), 0); crm_time_free(start); crm_time_free(end); diff --git a/lib/common/tests/rules/pcmk_evaluate_rule_test.c b/lib/common/tests/rules/pcmk_evaluate_rule_test.c index 0a028076c58..f0ce9d23b49 100644 --- a/lib/common/tests/rules/pcmk_evaluate_rule_test.c +++ b/lib/common/tests/rules/pcmk_evaluate_rule_test.c @@ -1,5 +1,5 @@ /* - * Copyright 2024-2025 the Pacemaker project contributors + * Copyright 2024-2026 the Pacemaker project contributors * * The version control history for this file may have further details. * @@ -43,7 +43,7 @@ static void null_invalid(void **state) { xmlNode *xml = NULL; - crm_time_t *next_change = crm_time_new_undefined(); + crm_time_t *next_change = pcmk__assert_alloc(1, sizeof(crm_time_t)); assert_int_equal(pcmk_evaluate_rule(NULL, NULL, next_change), EINVAL); @@ -69,7 +69,7 @@ static void id_missing(void **state) { xmlNode *xml = pcmk__xml_parse(RULE_OP_MISSING_ID); - crm_time_t *next_change = crm_time_new_undefined(); + crm_time_t *next_change = pcmk__assert_alloc(1, sizeof(crm_time_t)); assert_int_equal(pcmk_evaluate_rule(xml, &rule_input, next_change), pcmk_rc_unpack_error); @@ -85,7 +85,7 @@ good_idref(void **state) { xmlNode *parent_xml = pcmk__xml_parse(RULE_IDREF_PARENT); xmlNode *rule_xml = pcmk__xe_create(parent_xml, PCMK_XE_RULE); - crm_time_t *next_change = crm_time_new_undefined(); + crm_time_t *next_change = pcmk__assert_alloc(1, sizeof(crm_time_t)); pcmk__xe_set(rule_xml, PCMK_XA_ID_REF, "r"); assert_int_equal(pcmk_evaluate_rule(rule_xml, &rule_input, next_change), @@ -100,7 +100,7 @@ bad_idref(void **state) { xmlNode *parent_xml = pcmk__xml_parse(RULE_IDREF_PARENT); xmlNode *rule_xml = pcmk__xe_create(parent_xml, PCMK_XE_RULE); - crm_time_t *next_change = crm_time_new_undefined(); + crm_time_t *next_change = pcmk__assert_alloc(1, sizeof(crm_time_t)); pcmk__xe_set(rule_xml, PCMK_XA_ID_REF, "x"); assert_int_equal(pcmk_evaluate_rule(rule_xml, &rule_input, next_change), diff --git a/lib/common/tests/xml_element/pcmk__xe_get_datetime_test.c b/lib/common/tests/xml_element/pcmk__xe_get_datetime_test.c index bad68bffbf1..34c4103abd9 100644 --- a/lib/common/tests/xml_element/pcmk__xe_get_datetime_test.c +++ b/lib/common/tests/xml_element/pcmk__xe_get_datetime_test.c @@ -1,5 +1,5 @@ /* - * Copyright 2024 the Pacemaker project contributors + * Copyright 2024-2026 the Pacemaker project contributors * * The version control history for this file may have further details. * @@ -51,7 +51,7 @@ static void nonnull_time_invalid(void **state) { xmlNode *xml = pcmk__xml_parse(REFERENCE_XML); - crm_time_t *t = crm_time_new_undefined(); + crm_time_t *t = pcmk__assert_alloc(1, sizeof(crm_time_t)); assert_int_equal(pcmk__xe_get_datetime(xml, ATTR_PRESENT, &t), EINVAL); @@ -79,7 +79,7 @@ attr_valid(void **state) crm_time_t *reference = crm_time_new(REFERENCE_ISO8601); assert_int_equal(pcmk__xe_get_datetime(xml, ATTR_PRESENT, &t), pcmk_rc_ok); - assert_int_equal(crm_time_compare(t, reference), 0); + assert_int_equal(pcmk__time_compare(t, reference), 0); crm_time_free(t); crm_time_free(reference); diff --git a/lib/common/tls.c b/lib/common/tls.c index 3ba6aa94661..1d834a59812 100644 --- a/lib/common/tls.c +++ b/lib/common/tls.c @@ -27,7 +27,7 @@ #include // QB_XS #include -#include // crm_time_free, crm_time_log_date +#include // crm_time_* #include // CRM_CHECK #include // pcmk_rc_* @@ -474,7 +474,7 @@ pcmk__tls_check_cert_expiration(gnutls_session_t session) crm_time_t *expiry_t = pcmk__copy_timet(expiry); pcmk__time_log(LOG_WARNING, "TLS certificate will expire on", - expiry_t, crm_time_log_date|crm_time_log_timeofday); + expiry_t, pcmk__time_fmt_date|pcmk__time_fmt_time); crm_time_free(expiry_t); } } diff --git a/lib/fencing/st_output.c b/lib/fencing/st_output.c index 5e5ad1209fd..1395e3e2008 100644 --- a/lib/fencing/st_output.c +++ b/lib/fencing/st_output.c @@ -49,10 +49,10 @@ timespec_string(time_t sec, long nsec, bool show_usec) { }; return pcmk__timespec2str(&ts, - crm_time_log_date - |crm_time_log_timeofday - |crm_time_log_with_timezone - |(show_usec? crm_time_usecs : 0)); + pcmk__time_fmt_date + |pcmk__time_fmt_time + |pcmk__time_fmt_timezone + |(show_usec? pcmk__time_fmt_usecs : 0)); } /*! diff --git a/lib/pacemaker/pcmk_output.c b/lib/pacemaker/pcmk_output.c index 69d02d9087e..7df5120c3bf 100644 --- a/lib/pacemaker/pcmk_output.c +++ b/lib/pacemaker/pcmk_output.c @@ -755,9 +755,9 @@ pacemakerd_health(pcmk__output_t *out, va_list args) if (last_updated != 0) { last_updated_s = pcmk__epoch2str(&last_updated, - crm_time_log_date - |crm_time_log_timeofday - |crm_time_log_with_timezone); + pcmk__time_fmt_date + |pcmk__time_fmt_time + |pcmk__time_fmt_timezone); } rc = out->info(out, "Status of %s: '%s' (last updated %s)", @@ -796,9 +796,9 @@ pacemakerd_health_html(pcmk__output_t *out, va_list args) if (last_updated != 0) { last_updated_s = pcmk__epoch2str(&last_updated, - crm_time_log_date - |crm_time_log_timeofday - |crm_time_log_with_timezone); + pcmk__time_fmt_date + |pcmk__time_fmt_time + |pcmk__time_fmt_timezone); } msg = pcmk__assert_asprintf("Status of %s: '%s' (last updated %s)", @@ -860,9 +860,9 @@ pacemakerd_health_xml(pcmk__output_t *out, va_list args) if (last_updated != 0) { last_updated_s = pcmk__epoch2str(&last_updated, - crm_time_log_date - |crm_time_log_timeofday - |crm_time_log_with_timezone); + pcmk__time_fmt_date + |pcmk__time_fmt_time + |pcmk__time_fmt_timezone); } pcmk__output_create_xml_node(out, PCMK_XE_PACEMAKERD, diff --git a/lib/pacemaker/pcmk_sched_location.c b/lib/pacemaker/pcmk_sched_location.c index 641f7716c92..44891c98240 100644 --- a/lib/pacemaker/pcmk_sched_location.c +++ b/lib/pacemaker/pcmk_sched_location.c @@ -362,7 +362,7 @@ unpack_rsc_location(xmlNode *xml_obj, pcmk_resource_t *rsc, location->role_filter = role; } else { - crm_time_t *next_change = crm_time_new_undefined(); + crm_time_t *next_change = pcmk__assert_alloc(1, sizeof(crm_time_t)); xmlNode *rule_xml = pcmk__xe_first_child(xml_obj, PCMK_XE_RULE, NULL, NULL); pcmk_rule_input_t rule_input = { @@ -379,7 +379,7 @@ unpack_rsc_location(xmlNode *xml_obj, pcmk_resource_t *rsc, /* If there is a point in the future when the evaluation of a rule will * change, make sure the scheduler is re-run by that time. */ - if (crm_time_is_defined(next_change)) { + if (pcmk__time_is_initialized(next_change)) { time_t t = (time_t) crm_time_get_seconds_since_epoch(next_change); pcmk__update_recheck_time(t, rsc->priv->scheduler, diff --git a/lib/pacemaker/pcmk_simulate.c b/lib/pacemaker/pcmk_simulate.c index 4db2d34ef3d..be5c7da5ded 100644 --- a/lib/pacemaker/pcmk_simulate.c +++ b/lib/pacemaker/pcmk_simulate.c @@ -498,7 +498,7 @@ static void set_effective_date(pcmk_scheduler_t *scheduler, bool print_original, const char *use_date) { - static const uint32_t flags = crm_time_log_date|crm_time_log_timeofday; + static const uint32_t flags = pcmk__time_fmt_date|pcmk__time_fmt_time; pcmk__output_t *out = scheduler->priv->out; time_t original_date = 0; @@ -521,7 +521,7 @@ set_effective_date(pcmk_scheduler_t *scheduler, bool print_original, scheduler->priv->now = pcmk__copy_timet(original_date); if (print_original) { - char *when = crm_time_as_string(scheduler->priv->now, flags); + char *when = pcmk__time_text(scheduler->priv->now, flags); out->info(out, "Using the original execution date of: %s", when); free(when); diff --git a/lib/pengine/pe_actions.c b/lib/pengine/pe_actions.c index 2e8d3237c62..bd9b52dc5b3 100644 --- a/lib/pengine/pe_actions.c +++ b/lib/pengine/pe_actions.c @@ -593,7 +593,7 @@ unpack_interval_origin(const char *value, const xmlNode *xml_obj, } // Get seconds since origin (negative if origin is in the future) - result = crm_time_get_seconds(now) - crm_time_get_seconds(origin); + result = pcmk__time_get_seconds(now) - pcmk__time_get_seconds(origin); crm_time_free(origin); // Calculate seconds from closest interval to now diff --git a/lib/pengine/pe_output.c b/lib/pengine/pe_output.c index b351205fc75..86135a40582 100644 --- a/lib/pengine/pe_output.c +++ b/lib/pengine/pe_output.c @@ -1669,9 +1669,9 @@ failed_action_xml(pcmk__output_t *out, va_list args) { unsigned int interval_ms = 0; char *interval_ms_s = NULL; char *rc_change = pcmk__epoch2str(&epoch, - crm_time_log_date - |crm_time_log_timeofday - |crm_time_log_with_timezone); + pcmk__time_fmt_date + |pcmk__time_fmt_time + |pcmk__time_fmt_timezone); pcmk__xe_get_uint(xml_op, PCMK_META_INTERVAL, &interval_ms); interval_ms_s = pcmk__assert_asprintf("%u", interval_ms); diff --git a/lib/pengine/utils.c b/lib/pengine/utils.c index 37cdf3807dc..bb3d5c03b0d 100644 --- a/lib/pengine/utils.c +++ b/lib/pengine/utils.c @@ -727,11 +727,11 @@ pe__unpack_dataset_nvpairs(const xmlNode *xml_obj, const char *set_name, return; } - next_change = crm_time_new_undefined(); + next_change = pcmk__assert_alloc(1, sizeof(crm_time_t)); pcmk__unpack_nvpair_blocks(xml_obj, set_name, always_first, rule_input, hash, next_change, scheduler->input->doc); - if (crm_time_is_defined(next_change)) { + if (pcmk__time_is_initialized(next_change)) { time_t recheck = (time_t) crm_time_get_seconds_since_epoch(next_change); pcmk__update_recheck_time(recheck, scheduler, "rule evaluation"); diff --git a/tools/crm_resource_ban.c b/tools/crm_resource_ban.c index e52268b4335..656cb17cf4e 100644 --- a/tools/crm_resource_ban.c +++ b/tools/crm_resource_ban.c @@ -1,5 +1,5 @@ /* - * Copyright 2004-2025 the Pacemaker project contributors + * Copyright 2004-2026 the Pacemaker project contributors * * The version control history for this file may have further details. * @@ -24,14 +24,14 @@ parse_cli_lifetime(pcmk__output_t *out, const char *move_lifetime) crm_time_t *now = NULL; crm_time_t *later = NULL; crm_time_t *duration = NULL; - const uint32_t duration_flags = crm_time_log_date|crm_time_log_timeofday; - const uint32_t time_flags = duration_flags|crm_time_log_with_timezone; + const uint32_t duration_flags = pcmk__time_fmt_date|pcmk__time_fmt_time; + const uint32_t time_flags = duration_flags|pcmk__time_fmt_timezone; if (move_lifetime == NULL) { return NULL; } - duration = crm_time_parse_duration(move_lifetime); + duration = pcmk__time_parse_duration(move_lifetime); if (duration == NULL) { out->err(out, "Invalid duration specified: %s\n" "Please refer to https://en.wikipedia.org/wiki/ISO_8601#Durations " @@ -53,7 +53,7 @@ parse_cli_lifetime(pcmk__output_t *out, const char *move_lifetime) pcmk__time_log(LOG_INFO, "now ", now, time_flags); pcmk__time_log(LOG_INFO, "later ", later, time_flags); pcmk__time_log(LOG_INFO, "duration", duration, duration_flags); - later_s = crm_time_as_string(later, time_flags); + later_s = pcmk__time_text(later, time_flags); out->info(out, "Migration will take effect until: %s", later_s); crm_time_free(duration); @@ -496,7 +496,7 @@ cli_resource_clear_all_expired(xmlNode *root, cib_t *cib_conn, const char *rsc, continue; // Treat as unexpired } - if (crm_time_compare(now, end) == 1) { + if (pcmk__time_compare(now, end) > 0) { xmlNode *fragment = NULL; xmlNode *location = NULL; diff --git a/tools/iso8601.c b/tools/iso8601.c index 303d12ab520..fd2c27d91e7 100644 --- a/tools/iso8601.c +++ b/tools/iso8601.c @@ -55,15 +55,15 @@ modifier_cb(const char *option_name, const char *optarg, void *data, GError **error) { if (pcmk__str_any_of(option_name, "--seconds", "-s", NULL)) { - options.print_options |= crm_time_seconds; + options.print_options |= pcmk__time_fmt_seconds; } else if (pcmk__str_any_of(option_name, "--epoch", "-S", NULL)) { - options.print_options |= crm_time_epoch; + options.print_options |= pcmk__time_fmt_epoch; } else if (pcmk__str_any_of(option_name, "--local", "-L", NULL)) { - options.print_options |= crm_time_log_with_timezone; + options.print_options |= pcmk__time_fmt_timezone; } else if (pcmk__str_any_of(option_name, "--ordinal", "-O", NULL)) { - options.print_options |= crm_time_ordinal; + options.print_options |= pcmk__time_fmt_ordinal; } else if (pcmk__str_any_of(option_name, "--week", "-W", NULL)) { - options.print_options |= crm_time_weeks; + options.print_options |= pcmk__time_fmt_weeks; } return TRUE; @@ -130,8 +130,8 @@ date_default(pcmk__output_t *out, va_list args) char *date_s = NULL; - opts |= crm_time_log_date | crm_time_log_timeofday; - date_s = crm_time_as_string(date, opts); + opts |= pcmk__time_fmt_date|pcmk__time_fmt_time; + date_s = pcmk__time_text(date, opts); out->info(out, "%s: %s", prefix, date_s); @@ -149,8 +149,8 @@ date_xml(pcmk__output_t *out, va_list args) char *date_s = NULL; - opts |= crm_time_log_date | crm_time_log_timeofday; - date_s = crm_time_as_string(date, opts); + opts |= pcmk__time_fmt_date|pcmk__time_fmt_time; + date_s = pcmk__time_text(date, opts); pcmk__output_create_xml_text_node(out, PCMK_XE_DATE, date_s); free(date_s); @@ -164,7 +164,7 @@ duration_default(pcmk__output_t *out, va_list args) crm_time_t *time = va_arg(args, crm_time_t *); int opts = va_arg(args, int); - char *date_s = crm_time_as_string(time, opts | crm_time_log_duration); + char *date_s = pcmk__time_text(time, opts|pcmk__time_fmt_duration); out->info(out, "Duration: %s", date_s); @@ -179,7 +179,7 @@ duration_xml(pcmk__output_t *out, va_list args) crm_time_t *time = va_arg(args, crm_time_t *); int opts = va_arg(args, int); - char *date_s = crm_time_as_string(time, opts | crm_time_log_duration); + char *date_s = pcmk__time_text(time, opts|pcmk__time_fmt_duration); pcmk__output_create_xml_text_node(out, PCMK_XE_DURATION, date_s); free(date_s); @@ -195,8 +195,8 @@ duration_ends_default(pcmk__output_t *out, va_list args) char *date_s = NULL; - opts |= crm_time_log_date | crm_time_log_timeofday | crm_time_log_with_timezone; - date_s = crm_time_as_string(time, opts); + opts |= pcmk__time_fmt_date|pcmk__time_fmt_time|pcmk__time_fmt_timezone; + date_s = pcmk__time_text(time, opts); out->info(out, "Duration ends at: %s", date_s); @@ -213,8 +213,8 @@ duration_ends_xml(pcmk__output_t *out, va_list args) char *date_s = NULL; - opts |= crm_time_log_date | crm_time_log_timeofday | crm_time_log_with_timezone; - date_s = crm_time_as_string(time, opts); + opts |= pcmk__time_fmt_date|pcmk__time_fmt_time|pcmk__time_fmt_timezone; + date_s = pcmk__time_text(time, opts); pcmk__output_create_xml_text_node(out, PCMK_XE_DURATION_ENDS, date_s); free(date_s); @@ -232,14 +232,14 @@ period_default(pcmk__output_t *out, va_list args) char *start_s = NULL; char *end_s = NULL; - opts |= crm_time_log_date | crm_time_log_timeofday; + opts |= pcmk__time_fmt_date|pcmk__time_fmt_time; - start_s = crm_time_as_string(start, opts); + start_s = pcmk__time_text(start, opts); if (start_s == NULL) { return pcmk_rc_no_output; } - end_s = crm_time_as_string(end, opts); + end_s = pcmk__time_text(end, opts); if (end_s == NULL) { free(start_s); return pcmk_rc_no_output; @@ -263,14 +263,14 @@ period_xml(pcmk__output_t *out, va_list args) char *start_s = NULL; char *end_s = NULL; - opts |= crm_time_log_date | crm_time_log_timeofday; + opts |= pcmk__time_fmt_date|pcmk__time_fmt_time; - start_s = crm_time_as_string(start, opts); + start_s = pcmk__time_text(start, opts); if (start_s == NULL) { return pcmk_rc_no_output; } - end_s = crm_time_as_string(end, opts); + end_s = pcmk__time_text(end, opts); if (end_s == NULL) { free(start_s); return pcmk_rc_no_output; @@ -299,7 +299,7 @@ parse_period(const char *period_str, crm_time_t **start, crm_time_t **end) tzset(); if (period_str[0] == 'P') { - diff = crm_time_parse_duration(period_str); + diff = pcmk__time_parse_duration(period_str); if (diff == NULL) { goto invalid; } @@ -319,7 +319,7 @@ parse_period(const char *period_str, crm_time_t **start, crm_time_t **end) "has two durations", original); goto invalid; } - diff = crm_time_parse_duration(period_str); + diff = pcmk__time_parse_duration(period_str); if (diff == NULL) { goto invalid; } @@ -471,7 +471,7 @@ main(int argc, char **argv) } if (options.duration_s) { - duration = crm_time_parse_duration(options.duration_s); + duration = pcmk__time_parse_duration(options.duration_s); if (duration == NULL) { exit_code = CRM_EX_INVALID_PARAM; @@ -513,9 +513,10 @@ main(int argc, char **argv) out->message(out, "duration_ends", later, options.print_options); if (options.expected_s) { - char *dt_s = crm_time_as_string(later, - options.print_options | crm_time_log_date | - crm_time_log_timeofday); + char *dt_s = pcmk__time_text(later, + options.print_options + |pcmk__time_fmt_date + |pcmk__time_fmt_time); if (!pcmk__str_eq(options.expected_s, dt_s, pcmk__str_casei)) { exit_code = CRM_EX_ERROR; goto done; @@ -525,8 +526,10 @@ main(int argc, char **argv) crm_time_free(later); } else if (date_time && options.expected_s) { - char *dt_s = crm_time_as_string(date_time, - options.print_options | crm_time_log_date | crm_time_log_timeofday); + char *dt_s = pcmk__time_text(date_time, + options.print_options + |pcmk__time_fmt_date + |pcmk__time_fmt_time); if (!pcmk__str_eq(options.expected_s, dt_s, pcmk__str_casei)) { exit_code = CRM_EX_ERROR;