[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
bug#8794: (c) fix the cons<->int conversions
From: |
Paul Eggert |
Subject: |
bug#8794: (c) fix the cons<->int conversions |
Date: |
Fri, 03 Jun 2011 12:30:03 -0700 |
User-agent: |
Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.17) Gecko/20110428 Fedora/3.1.10-1.fc14 Thunderbird/3.1.10 |
=== modified file 'doc/lispref/ChangeLog'
--- doc/lispref/ChangeLog 2011-06-03 18:49:33 +0000
+++ doc/lispref/ChangeLog 2011-06-03 19:04:41 +0000
@@ -2,6 +2,8 @@
Document wide integers better.
* files.texi (File Attributes): Document ino_t values better.
+ ino_t values no longer map to anything larger than a single cons.
+
* numbers.texi (Integer Basics, Integer Basics, Arithmetic Operations):
(Bitwise Operations):
* objects.texi (Integer Type): Integers are typically 62 bits now.
=== modified file 'doc/lispref/files.texi'
--- doc/lispref/files.texi 2011-06-03 18:49:33 +0000
+++ doc/lispref/files.texi 2011-06-03 19:04:41 +0000
@@ -1237,13 +1237,9 @@
@item
The file's inode number. If possible, this is an integer. If the
inode number @math{N} is too large to be represented as an integer in
-Emacs Lisp, but @math{N / 2^16} is representable, then the value has
-the form @code{(@var{high} . @var{low})}, where @var{high} holds the
-high bits (i.e., excluding the low-order bits) and @var{low} the low
-16 bits. If the inode number is even larger, the value is of the form
-@code{(@var{high} @var{middle} . @var{low})}, where @code{high} holds
-the high bits, @var{middle} the next 24 bits, and @var{low} the low
-16 bits.
+Emacs Lisp, then the value has the form @code{(@var{high}
+. @var{low})}, where @var{high} holds the high bits (i.e., all but the
+low 16 bits) and @var{low} the low 16 bits.
@item
The filesystem number of the device that the file is on. Depending on
=== modified file 'src/ChangeLog'
--- src/ChangeLog 2011-06-03 18:42:59 +0000
+++ src/ChangeLog 2011-06-03 19:02:25 +0000
@@ -1,5 +1,32 @@
2011-06-03 Paul Eggert <eggert@cs.ucla.edu>
+ Check for overflow when converting integer to cons and back.
+ * charset.c (Fdefine_charset_internal, Fdecode_char):
+ Use cons_to_unsigned to catch overflow.
+ (Fencode_char): Use INTEGER_TO_CONS.
+ * composite.h (LGLYPH_CODE): Use cons_to_unsigned.
+ (LGLYPH_SET_CODE): Use INTEGER_TO_CONS.
+ * data.c (long_to_cons, cons_to_long): Remove.
+ (cons_to_unsigned, cons_to_signed): New functions.
+ These signal an error for invalid or out-of-range values.
+ * dired.c (Ffile_attributes): Use INTEGER_TO_CONS.
+ * fileio.c (Fset_visited_file_modtime): Use CONS_TO_INTEGER.
+ * font.c (Ffont_variation_glyphs):
+ * fontset.c (Finternal_char_font): Use INTEGER_TO_CONS.
+ * lisp.h (INTEGER_TO_CONS, CONS_TO_INTEGER): New macros.
+ (cons_to_signed, cons_to_unsigned): New decls.
+ (long_to_cons, cons_to_long): Remove decls.
+ * undo.c (record_first_change): Use INTEGER_TO_CONS.
+ (Fprimitive_undo): Use CONS_TO_INTEGER.
+ * xfns.c (Fx_window_property): Likewise.
+ * xselect.c (x_own_selection, selection_data_to_lisp_data):
+ Use INTEGER_TO_CONS.
+ (x_handle_selection_request, x_handle_selection_clear)
+ (x_get_foreign_selection, Fx_disown_selection_internal)
+ (Fx_get_atom_name, x_send_client_event): Use CONS_TO_INTEGER.
+ (lisp_data_to_selection_data): Use cons_to_unsigned.
+ (x_fill_property_data): Use cons_to_signed. Report values out of range.
+
Fix doc for machines with wider system times such as time_t.
On such machines, it's now safe to assume that EMACS_INT is as
wide as the system times, so that shifting right by 16 will
=== modified file 'src/charset.c'
--- src/charset.c 2011-06-03 18:11:17 +0000
+++ src/charset.c 2011-06-03 19:02:25 +0000
@@ -932,17 +932,8 @@
val = args[charset_arg_min_code];
if (! NILP (val))
{
- unsigned code;
+ unsigned code = cons_to_unsigned (val, UINT_MAX);
- if (INTEGERP (val))
- code = XINT (val);
- else
- {
- CHECK_CONS (val);
- CHECK_NUMBER_CAR (val);
- CHECK_NUMBER_CDR (val);
- code = (XINT (XCAR (val)) << 16) | (XINT (XCDR (val)));
- }
if (code < charset.min_code
|| code > charset.max_code)
args_out_of_range_3 (make_number (charset.min_code),
@@ -954,17 +945,8 @@
val = args[charset_arg_max_code];
if (! NILP (val))
{
- unsigned code;
+ unsigned code = cons_to_unsigned (val, UINT_MAX);
- if (INTEGERP (val))
- code = XINT (val);
- else
- {
- CHECK_CONS (val);
- CHECK_NUMBER_CAR (val);
- CHECK_NUMBER_CDR (val);
- code = (XINT (XCAR (val)) << 16) | (XINT (XCDR (val)));
- }
if (code < charset.min_code
|| code > charset.max_code)
args_out_of_range_3 (make_number (charset.min_code),
@@ -1865,17 +1847,7 @@
struct charset *charsetp;
CHECK_CHARSET_GET_ID (charset, id);
- if (CONSP (code_point))
- {
- CHECK_NATNUM_CAR (code_point);
- CHECK_NATNUM_CDR (code_point);
- code = (XINT (XCAR (code_point)) << 16) | (XINT (XCDR (code_point)));
- }
- else
- {
- CHECK_NATNUM (code_point);
- code = XINT (code_point);
- }
+ code = cons_to_unsigned (code_point, UINT_MAX);
charsetp = CHARSET_FROM_ID (id);
c = DECODE_CHAR (charsetp, code);
return (c >= 0 ? make_number (c) : Qnil);
@@ -1900,9 +1872,7 @@
code = ENCODE_CHAR (charsetp, XINT (ch));
if (code == CHARSET_INVALID_CODE (charsetp))
return Qnil;
- if (code > 0x7FFFFFF)
- return Fcons (make_number (code >> 16), make_number (code & 0xFFFF));
- return make_number (code);
+ return INTEGER_TO_CONS (code);
}
=== modified file 'src/composite.h'
--- src/composite.h 2011-05-31 06:05:00 +0000
+++ src/composite.h 2011-06-03 19:02:25 +0000
@@ -265,10 +265,7 @@
#define LGLYPH_CODE(g) \
(NILP (AREF ((g), LGLYPH_IX_CODE)) \
? FONT_INVALID_CODE \
- : CONSP (AREF ((g), LGLYPH_IX_CODE)) \
- ? ((XFASTINT (XCAR (AREF ((g), LGLYPH_IX_CODE))) << 16) \
- | (XFASTINT (XCDR (AREF ((g), LGLYPH_IX_CODE))))) \
- : XFASTINT (AREF ((g), LGLYPH_IX_CODE)))
+ : cons_to_unsigned (AREF (g, LGLYPH_IX_CODE), TYPE_MAXIMUM (unsigned)))
#define LGLYPH_WIDTH(g) XINT (AREF ((g), LGLYPH_IX_WIDTH))
#define LGLYPH_LBEARING(g) XINT (AREF ((g), LGLYPH_IX_LBEARING))
#define LGLYPH_RBEARING(g) XINT (AREF ((g), LGLYPH_IX_RBEARING))
@@ -280,15 +277,8 @@
#define LGLYPH_SET_CHAR(g, val) ASET ((g), LGLYPH_IX_CHAR, make_number (val))
/* Callers must assure that VAL is not negative! */
#define LGLYPH_SET_CODE(g, val)
\
- do { \
- if (val == FONT_INVALID_CODE) \
- ASET ((g), LGLYPH_IX_CODE, Qnil);
\
- else if ((EMACS_INT)val > MOST_POSITIVE_FIXNUM) \
- ASET ((g), LGLYPH_IX_CODE, Fcons (make_number ((val) >> 16), \
- make_number ((val) & 0xFFFF))); \
- else \
- ASET ((g), LGLYPH_IX_CODE, make_number (val)); \
- } while (0)
+ ASET (g, LGLYPH_IX_CODE, \
+ val == FONT_INVALID_CODE ? Qnil : INTEGER_TO_CONS (val))
#define LGLYPH_SET_WIDTH(g, val) ASET ((g), LGLYPH_IX_WIDTH, make_number (val))
#define LGLYPH_SET_LBEARING(g, val) ASET ((g), LGLYPH_IX_LBEARING, make_number
(val))
=== modified file 'src/data.c'
--- src/data.c 2011-06-02 06:17:35 +0000
+++ src/data.c 2011-06-03 19:02:25 +0000
@@ -2324,33 +2324,89 @@
return Qnil;
}
-/* Convert between long values and pairs of Lisp integers.
- Note that long_to_cons returns a single Lisp integer
- when the value fits in one. */
+/* 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. */
+uintmax_t
+cons_to_unsigned (Lisp_Object c, uintmax_t max)
+{
+ int valid = 0;
+ uintmax_t val IF_LINT (= 0);
+ if (INTEGERP (c))
+ {
+ valid = 0 <= XINT (c);
+ val = XINT (c);
+ }
+ else if (FLOATP (c))
+ {
+ double d = XFLOAT_DATA (c);
+ if (0 <= d
+ && d < (max == UINTMAX_MAX ? (double) UINTMAX_MAX + 1 : max + 1))
+ {
+ val = d;
+ valid = 1;
+ }
+ }
+ else if (CONSP (c))
+ {
+ Lisp_Object top = XCAR (c);
+ Lisp_Object bot = XCDR (c);
+ if (CONSP (bot))
+ bot = XCAR (bot);
+ if (NATNUMP (top) && XFASTINT (top) <= UINTMAX_MAX >> 16 && NATNUMP
(bot))
+ {
+ uintmax_t utop = XFASTINT (top);
+ val = (utop << 16) | XFASTINT (bot);
+ valid = 1;
+ }
+ }
-Lisp_Object
-long_to_cons (long unsigned int i)
-{
- unsigned long top = i >> 16;
- unsigned int bot = i & 0xFFFF;
- if (top == 0)
- return make_number (bot);
- if (top == (unsigned long)-1 >> 16)
- return Fcons (make_number (-1), make_number (bot));
- return Fcons (make_number (top), make_number (bot));
+ if (! (valid && val <= max))
+ error ("Not an in-range integer, float, or cons of integers");
+ return val;
}
-unsigned long
-cons_to_long (Lisp_Object c)
+/* 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. */
+intmax_t
+cons_to_signed (Lisp_Object c, intmax_t min, intmax_t max)
{
- Lisp_Object top, bot;
+ int valid = 0;
+ intmax_t val IF_LINT (= 0);
if (INTEGERP (c))
- return XINT (c);
- top = XCAR (c);
- bot = XCDR (c);
- if (CONSP (bot))
- bot = XCAR (bot);
- return ((XINT (top) << 16) | XINT (bot));
+ {
+ val = XINT (c);
+ valid = 1;
+ }
+ else if (FLOATP (c))
+ {
+ double d = XFLOAT_DATA (c);
+ if (min <= d
+ && d < (max == INTMAX_MAX ? (double) INTMAX_MAX + 1 : max + 1))
+ {
+ val = d;
+ valid = 1;
+ }
+ }
+ else if (CONSP (c))
+ {
+ Lisp_Object top = XCAR (c);
+ Lisp_Object bot = XCDR (c);
+ if (CONSP (bot))
+ bot = XCAR (bot);
+ if (INTEGERP (top) && INTMAX_MIN >> 16 <= XINT (top)
+ && XINT (top) <= INTMAX_MAX >> 16 && INTEGERP (bot))
+ {
+ intmax_t itop = XINT (top);
+ val = (itop << 16) | XINT (bot);
+ valid = 1;
+ }
+ }
+
+ if (! (valid && min <= val && val <= max))
+ error ("Not an in-range integer, float, or cons of integers");
+ return val;
}
DEFUN ("number-to-string", Fnumber_to_string, Snumber_to_string, 1, 1, 0,
=== modified file 'src/dired.c'
--- src/dired.c 2011-06-03 18:42:59 +0000
+++ src/dired.c 2011-06-03 19:02:25 +0000
@@ -900,12 +900,9 @@
This is a floating point number if the size is too large for an integer.
8. File modes, as a string of ten letters or dashes as in ls -l.
9. t if file's gid would change if file were deleted and recreated.
-10. inode number. If inode number is larger than what Emacs integer
- can hold, but all but the bottom 16 bits still fits, this is a cons cell
- containing two integers: first the high part, then the low 16 bits.
- If the inode number is still wider, this is of the form
- (HIGH MIDDLE . LOW): first the high bits, then the middle 24 bits,
- and finally the low 16 bits.
+10. inode number. If it is larger than what the Emacs integer
+ can hold, this is a cons cell containing two integers: first the
+ high part, then the low 16 bits.
11. Filesystem device number. If it is larger than what the Emacs
integer can hold, this is a cons cell, similar to the inode number.
@@ -998,34 +995,8 @@
#else /* file gid will be egid */
values[9] = (s.st_gid != getegid ()) ? Qt : Qnil;
#endif /* not BSD4_2 */
- if (!FIXNUM_OVERFLOW_P (s.st_ino))
- /* Keep the most common cases as integers. */
- values[10] = make_number (s.st_ino);
- else if (!FIXNUM_OVERFLOW_P (s.st_ino >> 16))
- /* To allow inode numbers larger than VALBITS, separate the bottom
- 16 bits. */
- values[10] = Fcons (make_number ((EMACS_INT)(s.st_ino >> 16)),
- make_number ((EMACS_INT)(s.st_ino & 0xffff)));
- else
- {
- /* To allow inode numbers beyond what INTEGER_TO_CONS can handle,
- separate into 2 24-bit high parts and a 16-bit bottom part.
- The code on the next line avoids a compiler warning on
- systems where st_ino is 32 bit wide. (bug#766). */
- EMACS_INT high_ino = s.st_ino >> 31 >> 1;
-
- values[10] = Fcons (make_number (high_ino >> 8),
- Fcons (make_number (((high_ino & 0xff) << 16)
- + (s.st_ino >> 16 & 0xffff)),
- make_number (s.st_ino & 0xffff)));
- }
-
- /* Likewise for device. */
- if (FIXNUM_OVERFLOW_P (s.st_dev))
- values[11] = Fcons (make_number (s.st_dev >> 16),
- make_number (s.st_dev & 0xffff));
- else
- values[11] = make_number (s.st_dev);
+ values[10] = INTEGER_TO_CONS (s.st_ino);
+ values[11] = INTEGER_TO_CONS (s.st_dev);
return Flist (sizeof(values) / sizeof(values[0]), values);
}
=== modified file 'src/fileio.c'
--- src/fileio.c 2011-06-02 06:23:20 +0000
+++ src/fileio.c 2011-06-03 19:02:25 +0000
@@ -5005,7 +5005,7 @@
{
if (!NILP (time_list))
{
- current_buffer->modtime = cons_to_long (time_list);
+ CONS_TO_INTEGER (time_list, time_t, current_buffer->modtime);
current_buffer->modtime_size = -1;
}
else
=== modified file 'src/font.c'
--- src/font.c 2011-05-29 19:04:01 +0000
+++ src/font.c 2011-06-03 19:02:25 +0000
@@ -4388,16 +4388,8 @@
for (i = 0; i < 255; i++)
if (variations[i])
{
- Lisp_Object code;
int vs = (i < 16 ? 0xFE00 + i : 0xE0100 + (i - 16));
- /* Stops GCC whining about limited range of data type. */
- EMACS_INT var = variations[i];
-
- if (var > MOST_POSITIVE_FIXNUM)
- code = Fcons (make_number ((variations[i]) >> 16),
- make_number ((variations[i]) & 0xFFFF));
- else
- code = make_number (variations[i]);
+ Lisp_Object code = INTEGER_TO_CONS (variations[i]);
val = Fcons (Fcons (make_number (vs), code), val);
}
return val;
=== modified file 'src/fontset.c'
--- src/fontset.c 2011-05-28 22:39:39 +0000
+++ src/fontset.c 2011-06-03 19:02:25 +0000
@@ -1859,17 +1859,11 @@
{
unsigned code = face->font->driver->encode_char (face->font, c);
Lisp_Object font_object;
- /* Assignment to EMACS_INT stops GCC whining about limited range
- of data type. */
- EMACS_INT cod = code;
if (code == FONT_INVALID_CODE)
return Qnil;
XSETFONT (font_object, face->font);
- if (cod <= MOST_POSITIVE_FIXNUM)
- return Fcons (font_object, make_number (code));
- return Fcons (font_object, Fcons (make_number (code >> 16),
- make_number (code & 0xFFFF)));
+ return Fcons (font_object, INTEGER_TO_CONS (code));
}
return Qnil;
}
=== modified file 'src/lisp.h'
--- src/lisp.h 2011-06-03 18:28:20 +0000
+++ src/lisp.h 2011-06-03 19:02:25 +0000
@@ -2405,9 +2405,33 @@
EXFUN (Fsub1, 1);
EXFUN (Fmake_variable_buffer_local, 1);
+/* Convert the integer I to an Emacs representation, either the integer
+ itself, or a cons of two integers, or if all else fails a float.
+ The float might lose information; this happens only in extreme cases
+ such as 32-bit EMACS_INT and 64-bit time_t with outlandish time values,
+ and these aren't worth complicating the interface.
+
+ I should not have side effects. */
+#define INTEGER_TO_CONS(i) \
+ (! FIXNUM_OVERFLOW_P (i) \
+ ? make_number (i) \
+ : ! ((FIXNUM_OVERFLOW_P (INTMAX_MIN >> 16) \
+ || FIXNUM_OVERFLOW_P (UINTMAX_MAX >> 16)) \
+ && FIXNUM_OVERFLOW_P ((i) >> 16)) \
+ ? Fcons (make_number ((i) >> 16), make_number ((i) & 0xffff)) \
+ : make_float (i))
+
+/* Convert the Emacs representation CONS back to an integer of type
+ TYPE, storing the result the variable VAR. Signal an error if CONS
+ is not a valid representation or is out of range for TYPE. */
+#define CONS_TO_INTEGER(cons, type, var) \
+ (TYPE_SIGNED (type) \
+ ? ((var) = cons_to_signed (cons, TYPE_MINIMUM (type), TYPE_MAXIMUM (type)))
\
+ : ((var) = cons_to_unsigned (cons, TYPE_MAXIMUM (type))))
+extern intmax_t cons_to_signed (Lisp_Object, intmax_t, intmax_t);
+extern uintmax_t cons_to_unsigned (Lisp_Object, uintmax_t);
+
extern struct Lisp_Symbol *indirect_variable (struct Lisp_Symbol *);
-extern Lisp_Object long_to_cons (unsigned long);
-extern unsigned long cons_to_long (Lisp_Object);
extern void args_out_of_range (Lisp_Object, Lisp_Object) NO_RETURN;
extern void args_out_of_range_3 (Lisp_Object, Lisp_Object,
Lisp_Object) NO_RETURN;
=== modified file 'src/undo.c'
--- src/undo.c 2011-06-02 06:15:15 +0000
+++ src/undo.c 2011-06-03 19:02:25 +0000
@@ -212,7 +212,6 @@
void
record_first_change (void)
{
- Lisp_Object high, low;
struct buffer *base_buffer = current_buffer;
if (EQ (BVAR (current_buffer, undo_list), Qt))
@@ -225,9 +224,9 @@
if (base_buffer->base_buffer)
base_buffer = base_buffer->base_buffer;
- XSETFASTINT (high, (base_buffer->modtime >> 16) & 0xffff);
- XSETFASTINT (low, base_buffer->modtime & 0xffff);
- BVAR (current_buffer, undo_list) = Fcons (Fcons (Qt, Fcons (high, low)),
BVAR (current_buffer, undo_list));
+ BVAR (current_buffer, undo_list) =
+ Fcons (Fcons (Qt, INTEGER_TO_CONS (base_buffer->modtime)),
+ BVAR (current_buffer, undo_list));
}
/* Record a change in property PROP (whose old value was VAL)
@@ -499,13 +498,9 @@
if (EQ (car, Qt))
{
/* Element (t high . low) records previous modtime. */
- Lisp_Object high, low;
+ struct buffer *base_buffer = current_buffer;
time_t mod_time;
- struct buffer *base_buffer = current_buffer;
-
- high = Fcar (cdr);
- low = Fcdr (cdr);
- mod_time = (XFASTINT (high) << 16) + XFASTINT (low);
+ CONS_TO_INTEGER (cdr, time_t, mod_time);
if (current_buffer->base_buffer)
base_buffer = current_buffer->base_buffer;
=== modified file 'src/xfns.c'
--- src/xfns.c 2011-04-19 06:34:43 +0000
+++ src/xfns.c 2011-06-03 19:02:25 +0000
@@ -4295,18 +4295,9 @@
if (! NILP (source))
{
- if (NUMBERP (source))
- {
- if (FLOATP (source))
- target_window = (Window) XFLOAT (source);
- else
- target_window = XFASTINT (source);
-
- if (target_window == 0)
- target_window = FRAME_X_DISPLAY_INFO (f)->root_window;
- }
- else if (CONSP (source))
- target_window = cons_to_long (source);
+ CONS_TO_INTEGER (source, Window, target_window);
+ if (! target_window)
+ target_window = FRAME_X_DISPLAY_INFO (f)->root_window;
}
BLOCK_INPUT;
=== modified file 'src/xselect.c'
--- src/xselect.c 2011-06-03 18:22:12 +0000
+++ src/xselect.c 2011-06-03 19:02:25 +0000
@@ -335,7 +335,7 @@
Lisp_Object prev_value;
selection_data = list4 (selection_name, selection_value,
- long_to_cons (timestamp), frame);
+ INTEGER_TO_CONS (timestamp), frame);
prev_value = LOCAL_SELECTION (selection_name, dpyinfo);
dpyinfo->terminal->Vselection_alist
@@ -419,7 +419,7 @@
|| INTEGERP (check)
|| NILP (value))
return value;
- /* Check for a value that cons_to_long could handle. */
+ /* Check for a value that CONS_TO_INTEGER could handle. */
else if (CONSP (check)
&& INTEGERP (XCAR (check))
&& (INTEGERP (XCDR (check))
@@ -782,8 +782,8 @@
if (NILP (local_selection_data)) goto DONE;
/* Decline requests issued prior to our acquiring the selection. */
- local_selection_time
- = (Time) cons_to_long (XCAR (XCDR (XCDR (local_selection_data))));
+ CONS_TO_INTEGER (XCAR (XCDR (XCDR (local_selection_data))),
+ Time, local_selection_time);
if (SELECTION_EVENT_TIME (event) != CurrentTime
&& local_selection_time > SELECTION_EVENT_TIME (event))
goto DONE;
@@ -950,8 +950,8 @@
/* Well, we already believe that we don't own it, so that's just fine. */
if (NILP (local_selection_data)) return;
- local_selection_time = (Time)
- cons_to_long (XCAR (XCDR (XCDR (local_selection_data))));
+ CONS_TO_INTEGER (XCAR (XCDR (XCDR (local_selection_data))),
+ Time, local_selection_time);
/* We have reasserted the selection since this SelectionClear was
generated, so we can disregard it. */
@@ -1213,16 +1213,7 @@
return Qnil;
if (! NILP (time_stamp))
- {
- if (CONSP (time_stamp))
- requestor_time = (Time) cons_to_long (time_stamp);
- else if (INTEGERP (time_stamp))
- requestor_time = (Time) XUINT (time_stamp);
- else if (FLOATP (time_stamp))
- requestor_time = (Time) XFLOAT_DATA (time_stamp);
- else
- error ("TIME_STAMP must be cons or number");
- }
+ CONS_TO_INTEGER (time_stamp, Time, requestor_time);
BLOCK_INPUT;
@@ -1652,7 +1643,7 @@
convert it to a cons of integers, 16 bits in each half.
*/
else if (format == 32 && size == sizeof (unsigned int))
- return long_to_cons (((unsigned int *) data) [0]);
+ return INTEGER_TO_CONS (((unsigned int *) data) [0]);
else if (format == 16 && size == sizeof (unsigned short))
return make_number ((int) (((unsigned short *) data) [0]));
@@ -1678,7 +1669,7 @@
for (i = 0; i < size / 4; i++)
{
unsigned int j = ((unsigned int *) data) [i];
- Faset (v, make_number (i), long_to_cons (j));
+ Faset (v, make_number (i), INTEGER_TO_CONS (j));
}
return v;
}
@@ -1755,7 +1746,7 @@
*size_ret = 1;
*data_ret = (unsigned char *) xmalloc (sizeof (unsigned long) + 1);
(*data_ret) [sizeof (unsigned long)] = 0;
- (*(unsigned long **) data_ret) [0] = cons_to_long (obj);
+ (*(unsigned long **) data_ret) [0] = cons_to_unsigned (obj, ULONG_MAX);
if (NILP (type)) type = QINTEGER;
}
else if (VECTORP (obj))
@@ -1803,11 +1794,11 @@
*data_ret = (unsigned char *) xmalloc (*size_ret * data_size);
for (i = 0; i < *size_ret; i++)
if (*format_ret == 32)
- (*((unsigned long **) data_ret)) [i]
- = cons_to_long (XVECTOR (obj)->contents [i]);
+ (*((unsigned long **) data_ret)) [i] =
+ cons_to_unsigned (XVECTOR (obj)->contents [i], ULONG_MAX);
else
- (*((unsigned short **) data_ret)) [i]
- = (unsigned short) cons_to_long (XVECTOR (obj)->contents [i]);
+ (*((unsigned short **) data_ret)) [i] =
+ cons_to_unsigned (XVECTOR (obj)->contents [i], USHRT_MAX);
}
}
else
@@ -2025,8 +2016,10 @@
selection_atom = symbol_to_x_atom (dpyinfo, selection);
BLOCK_INPUT;
- timestamp = (NILP (time_object) ? last_event_timestamp
- : cons_to_long (time_object));
+ if (NILP (time_object))
+ timestamp = last_event_timestamp;
+ else
+ CONS_TO_INTEGER (time_object, Time, timestamp);
XSetSelectionOwner (dpyinfo->display, selection_atom, None, timestamp);
UNBLOCK_INPUT;
@@ -2232,12 +2225,8 @@
{
Lisp_Object o = XCAR (iter);
- if (INTEGERP (o))
- val = (long) XFASTINT (o);
- else if (FLOATP (o))
- val = (long) XFLOAT_DATA (o);
- else if (CONSP (o))
- val = (long) cons_to_long (o);
+ if (INTEGERP (o) || FLOATP (o) || CONSP (o))
+ val = cons_to_signed (o, LONG_MIN, LONG_MAX);
else if (STRINGP (o))
{
BLOCK_INPUT;
@@ -2248,9 +2237,19 @@
error ("Wrong type, must be string, number or cons");
if (format == 8)
- *d08++ = (char) val;
+ {
+ if (CHAR_MIN <= val && val <= CHAR_MAX)
+ *d08++ = val;
+ else
+ error ("Out of 'char' range");
+ }
else if (format == 16)
- *d16++ = (short) val;
+ {
+ if (SHRT_MIN <= val && val <= SHRT_MAX)
+ *d16++ = val;
+ else
+ error ("Out of 'short' range");
+ }
else
*d32++ = val;
}
@@ -2334,14 +2333,7 @@
Atom atom;
int had_errors;
- if (INTEGERP (value))
- atom = (Atom) XUINT (value);
- else if (FLOATP (value))
- atom = (Atom) XFLOAT_DATA (value);
- else if (CONSP (value))
- atom = (Atom) cons_to_long (value);
- else
- error ("Wrong type, value must be number or cons");
+ CONS_TO_INTEGER (value, Atom, atom);
BLOCK_INPUT;
x_catch_errors (dpy);
@@ -2531,17 +2523,8 @@
else
error ("DEST as a string must be one of PointerWindow or InputFocus");
}
- else if (INTEGERP (dest))
- wdest = (Window) XFASTINT (dest);
- else if (FLOATP (dest))
- wdest = (Window) XFLOAT_DATA (dest);
- else if (CONSP (dest))
- {
- if (! NUMBERP (XCAR (dest)) || ! NUMBERP (XCDR (dest)))
- error ("Both car and cdr for DEST must be numbers");
- else
- wdest = (Window) cons_to_long (dest);
- }
+ else if (INTEGERP (dest) || FLOATP (dest) || CONSP (dest))
+ CONS_TO_INTEGER (dest, Window, wdest);
else
error ("DEST must be a frame, nil, string, number or cons");
bug#8794: (a) straightforward prerequisite fixes, Paul Eggert, 2011/06/03
bug#8794: (b) make the 64bit-on-32bit the default (if supported), Paul Eggert, 2011/06/03
bug#8794: (c) fix the cons<->int conversions,
Paul Eggert <=