One of the nastiest things left in the codebase is the code around the vint64 type, a workaround for pre-C99 toolchains in which the existence of int64_t/uint64_t was not guaranteed.
Presently vint64 is a union. I've sealed off access to the members behind macros, but for various good reasons I'd like to replace it with a scalar 64-bit type (so that, for example, native comparison operations can be used on it). Here's a patch that works: diff --git a/include/ntp_types.h b/include/ntp_types.h index f769132..f42cfec 100644 --- a/include/ntp_types.h +++ b/include/ntp_types.h @@ -43,36 +43,36 @@ /* * We now assume the platform supports a 64-bit scalar type (the ISC - * library wouldn't compile otherwise). Sadly, getting rid of vint64 - * is not as simple as turning it into a scalar due to same strange - * code in the calendar calculations. + * library wouldn't compile otherwise). */ -typedef union { -# ifdef WORDS_BIGENDIAN - struct { - uint32_t hi; uint32_t lo; - } h; -# else - struct { - uint32_t lo; uint32_t hi; - } h; -# endif - - int64_t s; /* signed quad scalar */ - uint64_t u; /* unsigned quad scalar */ -} vint64; /* variant int 64 */ - -/* hide the structure of a vint64 */ -#define vint64lo(n) (n).h.lo -#define setvint64lo(n,v) (n).h.lo = (v) -#define vint64hiu(n) (n).h.hi -#define setvint64hiu(n,v) (n).h.hi = (v) -#define vint64s(n) (n).s -#define setvint64s(n,v) (n).s = (v) -#define vint64u(n) (n).u -#define setvint64u(n,v) (n).u = (v) -#define negvint64(n) (n).s *= -1 +typedef uint64_t vint64; +#define LAST32MASK 0x00000000ffffffffUL +#define FIRST32MASK 0xffffffff00000000UL +#define GET32LAST(n) ((n) & LAST32MASK) +#define SET32LAST(n, v) (n) = (((n) & FIRST32MASK) | ((v) & LAST32MASK)) +#define GET32FIRST(n) ((n) >> 32) +#define SET32FIRST(n,v) (n) = ((((v) & LAST32MASK) << 32) | ((n) & LAST32MASK)) +#ifdef WORDS_BIGENDIAN +#define vint64lo(n) ((uint32_t)GET32FIRST(n)) +#define setvint64lo(n,v) SET32FIRST(n,v) +#define vint64his(n) ((int32_t)(GET32LAST(n))) +#define setvint64his(n,v) SET32LAST(n,v) +#define vint64hiu(n) ((uint32_t)(GET32LAST(n))) +#define setvint64hiu(n,v) SET32LAST(n,v) +#else +#define vint64lo(n) ((uint32_t)GET32LAST(n)) +#define setvint64lo(n,v) SET32LAST(n,v) +#define vint64his(n) ((int32_t)(GET32FIRST(n))) +#define setvint64his(n,v) SET32FIRST(n,v) +#define vint64hiu(n) ((uint32_t)(GET32FIRST(n))) +#define setvint64hiu(n,v) SET32FIRST(n,v) +#endif +#define vint64s(n) ((int64_t)(n)) +#define setvint64s(n,v) (n) = ((int64_t)(v)) +#define vint64u(n) (n) +#define setvint64u(n,v) (n) = (v) +#define negvint64(n) (n = ((uint64_t)((((int64_t)(n)) * -1)))) typedef uint16_t associd_t; /* association ID */ #define ASSOCID_MAX USHRT_MAX My problem is that this *shouldn't* work. Unless ia64 became big-endian while I wan't looking, it's backwards. The code enabled by WORDS_BIGENDIAN is actually doing little-endian extraction, and the code if WORDS_BIGENDIAN is not defined is doing big-endian. Or so it seens to me. Am I having an attack of teh stoopids here? Consequences: if I can change vint54 to be a typedef of uint64_t I can get rid of a bunch of grotty code. -- <a href="http://www.catb.org/~esr/">Eric S. Raymond</a> Morality is always the product of terror; its chains and strait-waistcoats are fashioned by those who dare not trust others, because they dare not trust themselves, to walk in liberty. -- Aldous Huxley _______________________________________________ devel mailing list devel@ntpsec.org http://lists.ntpsec.org/mailman/listinfo/devel