diff options
author | Paul Eggert <eggert@cs.ucla.edu> | 2017-03-04 23:14:52 -0800 |
---|---|---|
committer | Paul Eggert <eggert@cs.ucla.edu> | 2017-03-04 23:18:39 -0800 |
commit | 0d55c44a9a00da3b8542e92586654adeb2bcf228 (patch) | |
tree | 1105e60b43ef80d105ca613ece1c8cfc6ee64f07 /src | |
parent | 44e7ee2e356452139156e8175c46f646835d27ff (diff) | |
download | emacs-0d55c44a9a00da3b8542e92586654adeb2bcf228.tar.gz |
Compare and round more carefully
* etc/NEWS: Document this.
* src/data.c (store_symval_forwarding):
* src/sound.c (parse_sound):
Do not botch NaN comparison.
* src/data.c (cons_to_unsigned, cons_to_signed):
Signal an error if a floating-point arg is not integral.
* src/data.c (cons_to_unsigned, cons_to_signed):
* src/fileio.c (file_offset):
Use simpler overflow check.
* src/dbusbind.c (xd_extract_signed, xd_extract_unsigned):
Avoid rounding error in overflow check.
(Fcar_less_than_car): Use arithcompare directly.
* test/src/charset-tests.el: New file.
Diffstat (limited to 'src')
-rw-r--r-- | src/data.c | 45 | ||||
-rw-r--r-- | src/dbusbind.c | 4 | ||||
-rw-r--r-- | src/fileio.c | 13 | ||||
-rw-r--r-- | src/sound.c | 8 |
4 files changed, 35 insertions, 35 deletions
diff --git a/src/data.c b/src/data.c index 88d86697e42..66f4c9c738d 100644 --- a/src/data.c +++ b/src/data.c @@ -1110,10 +1110,8 @@ store_symval_forwarding (union Lisp_Fwd *valcontents, register Lisp_Object newva else if ((prop = Fget (predicate, Qrange), !NILP (prop))) { Lisp_Object min = XCAR (prop), max = XCDR (prop); - - if (!NUMBERP (newval) - || !NILP (arithcompare (newval, min, ARITH_LESS)) - || !NILP (arithcompare (newval, max, ARITH_GRTR))) + if (! NUMBERP (newval) + || NILP (CALLN (Fleq, min, newval, max))) wrong_range (min, max, newval); } else if (FUNCTIONP (predicate)) @@ -2554,12 +2552,13 @@ uintbig_to_lisp (uintmax_t i) } /* Convert the cons-of-integers, integer, or float value C to an - unsigned value with maximum value MAX. Signal an error if C does not - have a valid format or is out of range. */ + unsigned value with maximum value MAX, where MAX is one less than a + power of 2. Signal an error if C does not have a valid format or + is out of range. */ uintmax_t cons_to_unsigned (Lisp_Object c, uintmax_t max) { - bool valid = 0; + bool valid = false; uintmax_t val; if (INTEGERP (c)) { @@ -2569,11 +2568,10 @@ cons_to_unsigned (Lisp_Object c, uintmax_t max) else if (FLOATP (c)) { double d = XFLOAT_DATA (c); - if (0 <= d - && d < (max == UINTMAX_MAX ? (double) UINTMAX_MAX + 1 : max + 1)) + if (0 <= d && d < 1.0 + max) { val = d; - valid = 1; + valid = val == d; } } else if (CONSP (c) && NATNUMP (XCAR (c))) @@ -2587,7 +2585,7 @@ cons_to_unsigned (Lisp_Object c, uintmax_t max) { uintmax_t mid = XFASTINT (XCAR (rest)); val = top << 24 << 16 | mid << 16 | XFASTINT (XCDR (rest)); - valid = 1; + valid = true; } else if (top <= UINTMAX_MAX >> 16) { @@ -2596,37 +2594,38 @@ cons_to_unsigned (Lisp_Object c, uintmax_t max) if (NATNUMP (rest) && XFASTINT (rest) < 1 << 16) { val = top << 16 | XFASTINT (rest); - valid = 1; + valid = true; } } } if (! (valid && val <= max)) - error ("Not an in-range integer, float, or cons of integers"); + error ("Not an in-range integer, integral float, or cons of integers"); return val; } /* Convert the cons-of-integers, integer, or float value C to a signed - value with extrema MIN and MAX. Signal an error if C does not have - a valid format or is out of range. */ + value with extrema MIN and MAX. MAX should be one less than a + power of 2, and MIN should be zero or the negative of a power of 2. + Signal an error if C does not have a valid format or is out of + range. */ intmax_t cons_to_signed (Lisp_Object c, intmax_t min, intmax_t max) { - bool valid = 0; + bool valid = false; intmax_t val; if (INTEGERP (c)) { val = XINT (c); - valid = 1; + valid = true; } else if (FLOATP (c)) { double d = XFLOAT_DATA (c); - if (min <= d - && d < (max == INTMAX_MAX ? (double) INTMAX_MAX + 1 : max + 1)) + if (min <= d && d < 1.0 + max) { val = d; - valid = 1; + valid = val == d; } } else if (CONSP (c) && INTEGERP (XCAR (c))) @@ -2640,7 +2639,7 @@ cons_to_signed (Lisp_Object c, intmax_t min, intmax_t max) { intmax_t mid = XFASTINT (XCAR (rest)); val = top << 24 << 16 | mid << 16 | XFASTINT (XCDR (rest)); - valid = 1; + valid = true; } else if (INTMAX_MIN >> 16 <= top && top <= INTMAX_MAX >> 16) { @@ -2649,13 +2648,13 @@ cons_to_signed (Lisp_Object c, intmax_t min, intmax_t max) if (NATNUMP (rest) && XFASTINT (rest) < 1 << 16) { val = top << 16 | XFASTINT (rest); - valid = 1; + valid = true; } } } if (! (valid && min <= val && val <= max)) - error ("Not an in-range integer, float, or cons of integers"); + error ("Not an in-range integer, integral float, or cons of integers"); return val; } diff --git a/src/dbusbind.c b/src/dbusbind.c index e7c3251c14b..d2460fd886e 100644 --- a/src/dbusbind.c +++ b/src/dbusbind.c @@ -526,7 +526,7 @@ xd_extract_signed (Lisp_Object x, intmax_t lo, intmax_t hi) else { double d = XFLOAT_DATA (x); - if (lo <= d && d <= hi) + if (lo <= d && d < 1.0 + hi) { intmax_t n = d; if (n == d) @@ -554,7 +554,7 @@ xd_extract_unsigned (Lisp_Object x, uintmax_t hi) else { double d = XFLOAT_DATA (x); - if (0 <= d && d <= hi) + if (0 <= d && d < 1.0 + hi) { uintmax_t n = d; if (n == d) diff --git a/src/fileio.c b/src/fileio.c index 38400623793..acbf76e0d81 100644 --- a/src/fileio.c +++ b/src/fileio.c @@ -3426,11 +3426,12 @@ file_offset (Lisp_Object val) if (FLOATP (val)) { double v = XFLOAT_DATA (val); - if (0 <= v - && (sizeof (off_t) < sizeof v - ? v <= TYPE_MAXIMUM (off_t) - : v < TYPE_MAXIMUM (off_t))) - return v; + if (0 <= v && v < 1.0 + TYPE_MAXIMUM (off_t)) + { + off_t o = v; + if (o == v) + return o; + } } wrong_type_argument (intern ("file-offset"), val); @@ -5163,7 +5164,7 @@ DEFUN ("car-less-than-car", Fcar_less_than_car, Scar_less_than_car, 2, 2, 0, doc: /* Return t if (car A) is numerically less than (car B). */) (Lisp_Object a, Lisp_Object b) { - return CALLN (Flss, Fcar (a), Fcar (b)); + return arithcompare (Fcar (a), Fcar (b), ARITH_LESS); } /* Build the complete list of annotations appropriate for writing out diff --git a/src/sound.c b/src/sound.c index 84754165db5..4714ac1796b 100644 --- a/src/sound.c +++ b/src/sound.c @@ -387,14 +387,14 @@ parse_sound (Lisp_Object sound, Lisp_Object *attrs) { if (INTEGERP (attrs[SOUND_VOLUME])) { - if (XINT (attrs[SOUND_VOLUME]) < 0 - || XINT (attrs[SOUND_VOLUME]) > 100) + EMACS_INT volume = XINT (attrs[SOUND_VOLUME]); + if (! (0 <= volume && volume <= 100)) return 0; } else if (FLOATP (attrs[SOUND_VOLUME])) { - if (XFLOAT_DATA (attrs[SOUND_VOLUME]) < 0 - || XFLOAT_DATA (attrs[SOUND_VOLUME]) > 1) + double volume = XFLOAT_DATA (attrs[SOUND_VOLUME]); + if (! (0 <= volume && volume <= 1)) return 0; } else |