From 6117b40212f8f550356be953ef30905cb909e3bb Mon Sep 17 00:00:00 2001 From: Florian Prill <florian.prill@dwd.de> Date: Wed, 15 May 2019 17:01:39 +0200 Subject: [PATCH] timedelta divide: no negative divisor allowed; restructured return code. --- src/mtime_timedelta.c | 99 +++++++++++++++++++++++-------------------- 1 file changed, 53 insertions(+), 46 deletions(-) diff --git a/src/mtime_timedelta.c b/src/mtime_timedelta.c index 1adc9cfc..b072a57a 100644 --- a/src/mtime_timedelta.c +++ b/src/mtime_timedelta.c @@ -1177,63 +1177,70 @@ struct _divisionquotienttimespan* divideTimeDelta(struct _timedelta* dividend, struct _timedelta* divisor, struct _datetime* base_dt, struct _divisionquotienttimespan* quo_ret) { - if ((dividend == NULL) || (divisor == NULL) || (quo_ret == NULL)) return NULL; + struct _divisionquotienttimespan* ret = quo_ret; + struct _juliandelta *jd_dividend = NULL, *jd_divisor = NULL; + + if ((dividend == NULL) || (divisor == NULL) || (quo_ret == NULL)) ret = NULL; /* convert dividend and divisor into _juliandelta data type. */ - struct _juliandelta* jd_dividend = newJulianDelta('+', 0, 0); - if ( jd_dividend == NULL ) return NULL; - jd_dividend = timeDeltaToJulianDelta(dividend, base_dt, jd_dividend); - if ( jd_dividend == NULL ) - { - deallocateJulianDelta(jd_dividend); - return NULL; + if (ret != NULL) { + jd_dividend = newJulianDelta('+', 0, 0); + if ( jd_dividend == NULL ) + ret = NULL; + else { + jd_dividend = timeDeltaToJulianDelta(dividend, base_dt, jd_dividend); + if ( jd_dividend == NULL ) ret = NULL; } + } - struct _juliandelta* jd_divisor = newJulianDelta('+', 0, 0); - if ( jd_divisor == NULL ) return NULL; - jd_divisor = timeDeltaToJulianDelta(divisor, base_dt, jd_divisor); - if ( jd_divisor == NULL ) - { - deallocateJulianDelta(jd_divisor); - return NULL; + if (ret != NULL) { + jd_divisor = newJulianDelta('+', 0, 0); + if ( jd_divisor == NULL ) + ret = NULL; + else { + jd_divisor = timeDeltaToJulianDelta(divisor, base_dt, jd_divisor); + if (( jd_divisor == NULL ) || ( jd_divisor->sign == '-' )) ret = NULL; } - - /* perform large integer division. */ - t_int days1, day_fraction1, days2, day_fraction2; - t_int q_decimal = 0, remainder_days = 0, remainder_ms = 0; - - days1 = (t_int) jd_dividend->day; - day_fraction1 = (t_int) jd_dividend->ms; - days2 = (t_int) jd_divisor->day; - day_fraction2 = (t_int) jd_divisor->ms; - - int ret = divide_timespan(days1, day_fraction1, days2, day_fraction2, - &q_decimal, &remainder_days, &remainder_ms); - - quo_ret->quotient = (int64_t) 0; - quo_ret->remainder_days = (int64_t) 0; - quo_ret->remainder_in_ms = (int64_t) 0; - if (ret == 0) { - quo_ret->quotient = (int64_t) q_decimal; - quo_ret->remainder_days = (int64_t) remainder_days; - quo_ret->remainder_in_ms = (int64_t) remainder_ms; } - /* correct sign. */ - - /* TODO: maybe we should better remove negative time span division. Is it well-defined? */ - if (jd_dividend->sign != jd_divisor->sign) { - quo_ret->quotient *= -1; - quo_ret->remainder_days *= -1; - quo_ret->remainder_in_ms *= -1; + if (ret != NULL) { + /* perform large integer division. */ + t_int days1, day_fraction1, days2, day_fraction2; + t_int q_decimal = 0, remainder_days = 0, remainder_ms = 0; + + days1 = (t_int) jd_dividend->day; + day_fraction1 = (t_int) jd_dividend->ms; + days2 = (t_int) jd_divisor->day; + day_fraction2 = (t_int) jd_divisor->ms; + + int iret = divide_timespan(days1, day_fraction1, days2, day_fraction2, + &q_decimal, &remainder_days, &remainder_ms); + + quo_ret->quotient = (int64_t) 0; + quo_ret->remainder_days = (int64_t) 0; + quo_ret->remainder_in_ms = (int64_t) 0; + if (iret != 0) + ret = NULL; + else { + quo_ret->quotient = (int64_t) q_decimal; + quo_ret->remainder_days = (int64_t) remainder_days; + quo_ret->remainder_in_ms = (int64_t) remainder_ms; + } } - deallocateJulianDelta(jd_dividend); - deallocateJulianDelta(jd_divisor); + if (ret != NULL) { + if ( jd_dividend->sign == '-' ) { + /* correct sign. */ + quo_ret->quotient *= -1; + quo_ret->remainder_days *= -1; + quo_ret->remainder_in_ms *= -1; + } + } - if (ret != 0) return NULL; + if (jd_dividend != NULL) deallocateJulianDelta(jd_dividend); + if (jd_divisor != NULL) deallocateJulianDelta(jd_divisor); - return (quo_ret); + return ret; } -- GitLab