Commits

Sebastian Freundt committed c708d00 Merge

Merge branch 'code/hygiene' into next

* code/hygiene:
chore, lift inlining pressure from __offs() offset finder in tzraw
chore, lift inlining pressure from divrem() helper
hygiene, rewrite tuidiv()/tuimod() calls in dt_tadd() in terms of divrem() inline
chore, hygiene, eliminate __to_unix_epoch() copy in ltrcc, use public dt_to_unix_epoch() instead
minor, avoid c99 (reverse) inlines and provide a public dt_to_unix_epoch() and dt_to_gps_epoch()

Comments (0)

Files changed (7)

lib/dt-core-tz-glue.c

 	}
 
 	/* convert date/time part to unix stamp */
-	d_locl = __to_unix_epoch(d);
+	d_locl = dt_to_unix_epoch(d);
 	d_unix = zif_utc_time(zone, d_locl);
 	if (LIKELY((zdiff = d_unix - d_locl))) {
 		/* let dt_dtadd() do the magic */
 	}
 
 	/* convert date/time part to unix stamp */
-	d_unix = __to_unix_epoch(d);
+	d_unix = dt_to_unix_epoch(d);
 	d_locl = zif_local_time(zone, d_unix);
 	if (LIKELY((zdiff = d_locl - d_unix))) {
 		/* let dt_dtadd() do the magic */

lib/dt-core-tz-glue.h

  * In other words: convert from UTC represented DT to local ZONE time. */
 DECLF struct dt_dt_s dtz_enrichz(struct dt_dt_s dt, zif_t zone);
 
-extern inline dt_ssexy_t __to_unix_epoch(struct dt_dt_s);
-extern inline dt_ssexy_t __to_gps_epoch(struct dt_dt_s);
-
 
 #if defined INCLUDE_DT_CORE_TZ_GLUE_IMPL
 # include "dt-core-tz-glue.c"
 	return 0;
 }
 
-static inline __attribute__((unused)) dt_ssexy_t
+/* public version */
+dt_ssexy_t
+dt_to_unix_epoch(struct dt_dt_s dt)
+{
+	return __to_unix_epoch(dt);
+}
+
+static inline dt_ssexy_t
 __to_gps_epoch(struct dt_dt_s dt)
 {
 	if (dt.typ == DT_SEXY) {
 	return 0;
 }
 
+/* public version */
+dt_ssexy_t
+dt_to_gps_epoch(struct dt_dt_s dt)
+{
+	return __to_gps_epoch(dt);
+}
+
 static inline struct dt_dt_s
 dt_conv_to_sexy(struct dt_dt_s dt)
 {
  * E.g. ymd -> %FT%T */
 DECLF void __trans_dtfmt(const char **fmt);
 
+/**
+ * Convert a dt_dt_s to an epoch difference, based on the Unix epoch. */
+extern dt_ssexy_t dt_to_unix_epoch(struct dt_dt_s);
+
+/**
+ * Convert a dt_dt_s to an epoch difference, based on the GPS epoch. */
+extern dt_ssexy_t dt_to_gps_epoch(struct dt_dt_s);
+
 
 /* some useful gimmicks, sort of */
 static inline __attribute__((pure, const)) struct dt_dt_s
 #include "dt-core.h"
 #include "nifty.h"
 
-static inline dt_ssexy_t
-__to_unix_epoch(struct dt_dt_s dt)
-{
-/* daisy is competing with the prevalent unix epoch, this is the offset */
-#define DAISY_UNIX_BASE		(19359)
-	if (dt.typ == DT_SEXY) {
-		/* no way to find out, is there */
-		return dt.sexy;
-	} else if (dt_sandwich_p(dt) || dt_sandwich_only_d_p(dt)) {
-		struct dt_d_s d = dt_dconv(DT_DAISY, dt.d);
-		dt_daisy_t dd = d.daisy;
-		dt_ssexy_t res = (dd - DAISY_UNIX_BASE) * SECS_PER_DAY;
-		if (dt_sandwich_p(dt)) {
-			res += (dt.t.hms.h * 60 + dt.t.hms.m) * 60 + dt.t.hms.s;
-		}
-		return res;
-	}
-	return 0;
-}
-
 
 #define PROLOGUE	(-1UL)
 #define EPILOGUE	(0UL)
 
 	/* fix up and convert to target type */
 	d.t.hms.s--;
-	val = __to_unix_epoch(d);
+	val = dt_to_unix_epoch(d);
 
 	if (!colp) {
 		switch (ep[1]) {
 }
 
 /* arithmetics helpers */
-static inline unsigned int
-__tuimod(signed int x, signed int m)
-{
-	int res = x % m;
-	return res >= 0 ? res : res + m;
-}
+struct divrem_s {
+	signed int div;
+	unsigned int rem;
+};
 
-static inline signed int
-__tuidiv(signed int x, signed int m)
+static struct divrem_s
+divrem(signed int n, unsigned int mod)
 {
-/* uidiv expects its counterpart (the mod) to be computed with __uimod */
-	int res = x / m;
-	return x >= 0 ? res : x % m ? res - 1 : res;
+	register signed int div;
+	register signed int rem;
+
+	div = n / (signed int)mod;
+	if ((rem = n % (signed int)mod) < 0) {
+		div--;
+		rem += mod;
+	}
+	return (struct divrem_s){div, (unsigned int)rem};
 }
 
 
 DEFUN struct dt_t_s
 dt_tadd(struct dt_t_s t, struct dt_t_s dur, int corr)
 {
-	unsigned int res;
-	signed int tmp;
+	signed int sec;
+	struct divrem_s tmp;
 
 	/* get both result in seconds since midnight */
-	res = (t.hms.h * MINS_PER_HOUR + t.hms.m) * SECS_PER_MIN + t.hms.s;
-	res = res + dur.sdur;
+	sec = (t.hms.h * MINS_PER_HOUR + t.hms.m) * SECS_PER_MIN + t.hms.s;
+	sec = sec + dur.sdur;
 
 	if (LIKELY(corr == 0)) {
-		tmp = __tuidiv(res, SECS_PER_DAY);
-		res = __tuimod(res, SECS_PER_DAY);
+		tmp = divrem(sec, SECS_PER_DAY);
 
 		/* fill up biggest first */
-		t.hms.h = res / SECS_PER_HOUR;
-		res = res % SECS_PER_HOUR;
-		t.hms.m = res / SECS_PER_MIN;
-		res = res % SECS_PER_MIN;
-		t.hms.s = res;
+		t.hms.h = tmp.rem / SECS_PER_HOUR;
+		tmp.rem %= SECS_PER_HOUR;
+		t.hms.m = tmp.rem / SECS_PER_MIN;
+		tmp.rem %= SECS_PER_MIN;
+		t.hms.s = tmp.rem;
 	} else {
 		/* doesn't work if we span more than 1 day */
-		tmp = __tuidiv(res, SECS_PER_DAY + corr);
-		res = __tuimod(res, SECS_PER_DAY + corr);
+		tmp = divrem(sec, SECS_PER_DAY + corr);
 
 		/* fill up biggest first */
-		if (res < SECS_PER_DAY) {
-			t.hms.h = res / SECS_PER_HOUR;
-			res = res % SECS_PER_HOUR;
-			t.hms.m = res / SECS_PER_MIN;
-			res = res % SECS_PER_MIN;
-			t.hms.s = res;
+		if (LIKELY(tmp.rem < SECS_PER_DAY)) {
+			t.hms.h = tmp.rem / SECS_PER_HOUR;
+			tmp.rem %= SECS_PER_HOUR;
+			t.hms.m = tmp.rem / SECS_PER_MIN;
+			tmp.rem %= SECS_PER_MIN;
+			t.hms.s = tmp.rem;
 		} else {
-			/* corr < 0 will always end up in the above case */
+			/* leap-second day case
+			 * corr < 0 will always end up in the above case */
 			t.hms.h = 23;
 			t.hms.m = 59;
 			t.hms.s = 59 + corr;
 	t.typ = DT_HMS;
 	t.dur = 0;
 	t.neg = 0;
-	t.carry = tmp;
+	t.carry = tmp.div;
 	return t;
 }
 
 	return __tai_offs(t) - gps_offs_epoch;
 }
 
-static inline int32_t
+static int32_t
 __offs(zif_t z, int32_t t)
 {
 /* return the offset of T in Z and cache the result. */