Commit be44ca6c authored by Paul Eggert's avatar Paul Eggert
Browse files

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: Include <intprops.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: Include <limits.h>.
(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.
parent d1f3d2af
2011-06-06 Paul Eggert <eggert@cs.ucla.edu> 2011-06-06 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: Include <intprops.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: Include <limits.h>.
(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.
Check for buffer and string overflow more precisely. Check for buffer and string overflow more precisely.
* buffer.h (BUF_BYTES_MAX): New macro. * buffer.h (BUF_BYTES_MAX): New macro.
* lisp.h (STRING_BYTES_MAX): New macro. * lisp.h (STRING_BYTES_MAX): New macro.
......
...@@ -932,17 +932,8 @@ usage: (define-charset-internal ...) */) ...@@ -932,17 +932,8 @@ usage: (define-charset-internal ...) */)
val = args[charset_arg_min_code]; val = args[charset_arg_min_code];
if (! NILP (val)) 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 if (code < charset.min_code
|| code > charset.max_code) || code > charset.max_code)
args_out_of_range_3 (make_number (charset.min_code), args_out_of_range_3 (make_number (charset.min_code),
...@@ -954,17 +945,8 @@ usage: (define-charset-internal ...) */) ...@@ -954,17 +945,8 @@ usage: (define-charset-internal ...) */)
val = args[charset_arg_max_code]; val = args[charset_arg_max_code];
if (! NILP (val)) 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 if (code < charset.min_code
|| code > charset.max_code) || code > charset.max_code)
args_out_of_range_3 (make_number (charset.min_code), args_out_of_range_3 (make_number (charset.min_code),
...@@ -1865,17 +1847,7 @@ and CODE-POINT to a character. Currently not supported and just ignored. */) ...@@ -1865,17 +1847,7 @@ and CODE-POINT to a character. Currently not supported and just ignored. */)
struct charset *charsetp; struct charset *charsetp;
CHECK_CHARSET_GET_ID (charset, id); CHECK_CHARSET_GET_ID (charset, id);
if (CONSP (code_point)) code = cons_to_unsigned (code_point, UINT_MAX);
{
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);
}
charsetp = CHARSET_FROM_ID (id); charsetp = CHARSET_FROM_ID (id);
c = DECODE_CHAR (charsetp, code); c = DECODE_CHAR (charsetp, code);
return (c >= 0 ? make_number (c) : Qnil); return (c >= 0 ? make_number (c) : Qnil);
...@@ -1900,9 +1872,7 @@ code-point in CCS. Currently not supported and just ignored. */) ...@@ -1900,9 +1872,7 @@ code-point in CCS. Currently not supported and just ignored. */)
code = ENCODE_CHAR (charsetp, XINT (ch)); code = ENCODE_CHAR (charsetp, XINT (ch));
if (code == CHARSET_INVALID_CODE (charsetp)) if (code == CHARSET_INVALID_CODE (charsetp))
return Qnil; return Qnil;
if (code > 0x7FFFFFF) return INTEGER_TO_CONS (code);
return Fcons (make_number (code >> 16), make_number (code & 0xFFFF));
return make_number (code);
} }
......
...@@ -265,10 +265,7 @@ enum lglyph_indices ...@@ -265,10 +265,7 @@ enum lglyph_indices
#define LGLYPH_CODE(g) \ #define LGLYPH_CODE(g) \
(NILP (AREF ((g), LGLYPH_IX_CODE)) \ (NILP (AREF ((g), LGLYPH_IX_CODE)) \
? FONT_INVALID_CODE \ ? FONT_INVALID_CODE \
: CONSP (AREF ((g), LGLYPH_IX_CODE)) \ : cons_to_unsigned (AREF (g, LGLYPH_IX_CODE), TYPE_MAXIMUM (unsigned)))
? ((XFASTINT (XCAR (AREF ((g), LGLYPH_IX_CODE))) << 16) \
| (XFASTINT (XCDR (AREF ((g), LGLYPH_IX_CODE))))) \
: XFASTINT (AREF ((g), LGLYPH_IX_CODE)))
#define LGLYPH_WIDTH(g) XINT (AREF ((g), LGLYPH_IX_WIDTH)) #define LGLYPH_WIDTH(g) XINT (AREF ((g), LGLYPH_IX_WIDTH))
#define LGLYPH_LBEARING(g) XINT (AREF ((g), LGLYPH_IX_LBEARING)) #define LGLYPH_LBEARING(g) XINT (AREF ((g), LGLYPH_IX_LBEARING))
#define LGLYPH_RBEARING(g) XINT (AREF ((g), LGLYPH_IX_RBEARING)) #define LGLYPH_RBEARING(g) XINT (AREF ((g), LGLYPH_IX_RBEARING))
...@@ -280,15 +277,8 @@ enum lglyph_indices ...@@ -280,15 +277,8 @@ enum lglyph_indices
#define LGLYPH_SET_CHAR(g, val) ASET ((g), LGLYPH_IX_CHAR, make_number (val)) #define LGLYPH_SET_CHAR(g, val) ASET ((g), LGLYPH_IX_CHAR, make_number (val))
/* Callers must assure that VAL is not negative! */ /* Callers must assure that VAL is not negative! */
#define LGLYPH_SET_CODE(g, val) \ #define LGLYPH_SET_CODE(g, val) \
do { \ ASET (g, LGLYPH_IX_CODE, \
if (val == FONT_INVALID_CODE) \ val == FONT_INVALID_CODE ? Qnil : INTEGER_TO_CONS (val))
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)
#define LGLYPH_SET_WIDTH(g, val) ASET ((g), LGLYPH_IX_WIDTH, make_number (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)) #define LGLYPH_SET_LBEARING(g, val) ASET ((g), LGLYPH_IX_LBEARING, make_number (val))
......
...@@ -2326,33 +2326,110 @@ DEFUN ("zerop", Fzerop, Szerop, 1, 1, 0, ...@@ -2326,33 +2326,110 @@ DEFUN ("zerop", Fzerop, Szerop, 1, 1, 0,
return Qnil; return Qnil;
} }
/* Convert between long values and pairs of Lisp integers. /* Convert the cons-of-integers, integer, or float value C to an
Note that long_to_cons returns a single Lisp integer unsigned value with maximum value MAX. Signal an error if C does not
when the value fits in one. */ 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) && NATNUMP (XCAR (c)))
{
uintmax_t top = XFASTINT (XCAR (c));
Lisp_Object rest = XCDR (c);
if (top <= UINTMAX_MAX >> 24 >> 16
&& CONSP (rest)
&& NATNUMP (XCAR (rest)) && XFASTINT (XCAR (rest)) < 1 << 24
&& NATNUMP (XCDR (rest)) && XFASTINT (XCDR (rest)) < 1 << 16)
{
uintmax_t mid = XFASTINT (XCAR (rest));
val = top << 24 << 16 | mid << 16 | XFASTINT (XCDR (rest));
valid = 1;
}
else if (top <= UINTMAX_MAX >> 16)
{
if (CONSP (rest))
rest = XCAR (rest);
if (NATNUMP (rest) && XFASTINT (rest) < 1 << 16)
{
val = top << 16 | XFASTINT (rest);
valid = 1;
}
}
}
Lisp_Object if (! (valid && val <= max))
long_to_cons (long unsigned int i) error ("Not an in-range integer, float, or cons of integers");
{ return val;
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));
} }
unsigned long /* Convert the cons-of-integers, integer, or float value C to a signed
cons_to_long (Lisp_Object c) 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)) if (INTEGERP (c))
return XINT (c); {
top = XCAR (c); val = XINT (c);
bot = XCDR (c); valid = 1;
if (CONSP (bot)) }
bot = XCAR (bot); else if (FLOATP (c))
return ((XINT (top) << 16) | XINT (bot)); {
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) && INTEGERP (XCAR (c)))
{
intmax_t top = XINT (XCAR (c));
Lisp_Object rest = XCDR (c);
if (INTMAX_MIN >> 24 >> 16 <= top && top <= INTMAX_MAX >> 24 >> 16
&& CONSP (rest)
&& NATNUMP (XCAR (rest)) && XFASTINT (XCAR (rest)) < 1 << 24
&& NATNUMP (XCDR (rest)) && XFASTINT (XCDR (rest)) < 1 << 16)
{
intmax_t mid = XFASTINT (XCAR (rest));
val = top << 24 << 16 | mid << 16 | XFASTINT (XCDR (rest));
valid = 1;
}
else if (INTMAX_MIN >> 16 <= top && top <= INTMAX_MAX >> 16)
{
if (CONSP (rest))
rest = XCAR (rest);
if (NATNUMP (rest) && XFASTINT (rest) < 1 << 16)
{
val = top << 16 | XFASTINT (rest);
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, DEFUN ("number-to-string", Fnumber_to_string, Snumber_to_string, 1, 1, 0,
......
...@@ -900,11 +900,10 @@ Elements of the attribute list are: ...@@ -900,11 +900,10 @@ Elements of the attribute list are:
This is a floating point number if the size is too large for an integer. 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. 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. 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 10. inode number. If it is larger than what an Emacs integer can hold,
can hold, but still fits into a 32-bit number, this is a cons cell this is of the form (HIGH . LOW): first the high bits, then the low 16 bits.
containing two integers: first the high part, then the low 16 bits. If even HIGH is too large for an Emacs integer, this is instead of the form
If the inode number is wider than 32 bits, this is of the form (HIGH MIDDLE . LOW): first the high bits, then the middle 24 bits,
(HIGH MIDDLE . LOW): first the high 24 bits, then middle 24 bits,
and finally the low 16 bits. and finally the low 16 bits.
11. Filesystem device number. If it is larger than what the Emacs 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. integer can hold, this is a cons cell, similar to the inode number.
...@@ -998,34 +997,8 @@ so last access time will always be midnight of that day. */) ...@@ -998,34 +997,8 @@ so last access time will always be midnight of that day. */)
#else /* file gid will be egid */ #else /* file gid will be egid */
values[9] = (s.st_gid != getegid ()) ? Qt : Qnil; values[9] = (s.st_gid != getegid ()) ? Qt : Qnil;
#endif /* not BSD4_2 */ #endif /* not BSD4_2 */
if (!FIXNUM_OVERFLOW_P (s.st_ino)) values[10] = INTEGER_TO_CONS (s.st_ino);
/* Keep the most common cases as integers. */ values[11] = INTEGER_TO_CONS (s.st_dev);
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 32 bits, 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);
return Flist (sizeof(values) / sizeof(values[0]), values); return Flist (sizeof(values) / sizeof(values[0]), values);
} }
......
...@@ -5005,7 +5005,7 @@ An argument specifies the modification time value to use ...@@ -5005,7 +5005,7 @@ An argument specifies the modification time value to use
{ {
if (!NILP (time_list)) 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; current_buffer->modtime_size = -1;
} }
else else
......
...@@ -4388,16 +4388,8 @@ where ...@@ -4388,16 +4388,8 @@ where
for (i = 0; i < 255; i++) for (i = 0; i < 255; i++)
if (variations[i]) if (variations[i])
{ {
Lisp_Object code;
int vs = (i < 16 ? 0xFE00 + i : 0xE0100 + (i - 16)); int vs = (i < 16 ? 0xFE00 + i : 0xE0100 + (i - 16));
/* Stops GCC whining about limited range of data type. */ Lisp_Object code = INTEGER_TO_CONS (variations[i]);
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]);
val = Fcons (Fcons (make_number (vs), code), val); val = Fcons (Fcons (make_number (vs), code), val);
} }
return val; return val;
......
...@@ -1859,17 +1859,11 @@ DEFUN ("internal-char-font", Finternal_char_font, Sinternal_char_font, 1, 2, 0, ...@@ -1859,17 +1859,11 @@ DEFUN ("internal-char-font", Finternal_char_font, Sinternal_char_font, 1, 2, 0,
{ {
unsigned code = face->font->driver->encode_char (face->font, c); unsigned code = face->font->driver->encode_char (face->font, c);
Lisp_Object font_object; 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) if (code == FONT_INVALID_CODE)
return Qnil; return Qnil;
XSETFONT (font_object, face->font); XSETFONT (font_object, face->font);
if (cod <= MOST_POSITIVE_FIXNUM) return Fcons (font_object, INTEGER_TO_CONS (code));
return Fcons (font_object, make_number (code));
return Fcons (font_object, Fcons (make_number (code >> 16),
make_number (code & 0xFFFF)));
} }
return Qnil; return Qnil;
} }
......
...@@ -24,6 +24,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ ...@@ -24,6 +24,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include <stddef.h> #include <stddef.h>
#include <inttypes.h> #include <inttypes.h>
#include <intprops.h>
/* Use the configure flag --enable-checking[=LIST] to enable various /* Use the configure flag --enable-checking[=LIST] to enable various
types of run time checks for Lisp objects. */ types of run time checks for Lisp objects. */
...@@ -2408,9 +2410,35 @@ EXFUN (Fadd1, 1); ...@@ -2408,9 +2410,35 @@ EXFUN (Fadd1, 1);
EXFUN (Fsub1, 1); EXFUN (Fsub1, 1);
EXFUN (Fmake_variable_buffer_local, 1); EXFUN (Fmake_variable_buffer_local, 1);
/* Convert the integer I to an Emacs representation, either the integer
itself, or a cons of two or three integers, or if all else fails a float.
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)) \
: ! ((FIXNUM_OVERFLOW_P (INTMAX_MIN >> 16 >> 24) \
|| FIXNUM_OVERFLOW_P (UINTMAX_MAX >> 16 >> 24)) \
&& FIXNUM_OVERFLOW_P ((i) >> 16 >> 24)) \
? Fcons (make_number ((i) >> 16 >> 24), \
Fcons (make_number ((i) >> 16 & 0xffffff), \
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 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 (Lisp_Object, Lisp_Object) NO_RETURN;
extern void args_out_of_range_3 (Lisp_Object, Lisp_Object, extern void args_out_of_range_3 (Lisp_Object, Lisp_Object,
Lisp_Object) NO_RETURN; Lisp_Object) NO_RETURN;
......
...@@ -212,7 +212,6 @@ record_change (EMACS_INT beg, EMACS_INT length) ...@@ -212,7 +212,6 @@ record_change (EMACS_INT beg, EMACS_INT length)
void void
record_first_change (void) record_first_change (void)
{ {
Lisp_Object high, low;
struct buffer *base_buffer = current_buffer; struct buffer *base_buffer = current_buffer;
if (EQ (BVAR (current_buffer, undo_list), Qt)) if (EQ (BVAR (current_buffer, undo_list), Qt))
...@@ -225,9 +224,9 @@ record_first_change (void) ...@@ -225,9 +224,9 @@ record_first_change (void)
if (base_buffer->base_buffer) if (base_buffer->base_buffer)
base_buffer = base_buffer->base_buffer; base_buffer = base_buffer->base_buffer;
XSETFASTINT (high, (base_buffer->modtime >> 16) & 0xffff); BVAR (current_buffer, undo_list) =
XSETFASTINT (low, base_buffer->modtime & 0xffff); Fcons (Fcons (Qt, INTEGER_TO_CONS (base_buffer->modtime)),
BVAR (current_buffer, undo_list) = Fcons (Fcons (Qt, Fcons (high, low)), BVAR (current_buffer, undo_list)); BVAR (current_buffer, undo_list));
} }
/* Record a change in property PROP (whose old value was VAL) /* Record a change in property PROP (whose old value was VAL)
...@@ -499,13 +498,9 @@ Return what remains of the list. */) ...@@ -499,13 +498,9 @@ Return what remains of the list. */)
if (EQ (car, Qt)) if (EQ (car, Qt))
{ {
/* Element (t high . low) records previous modtime. */ /* Element (t high . low) records previous modtime. */
Lisp_Object high, low;
time_t mod_time;
struct buffer *base_buffer = current_buffer; struct buffer *base_buffer = current_buffer;
time_t mod_time;
high = Fcar (cdr); CONS_TO_INTEGER (cdr, time_t, mod_time);
low = Fcdr (cdr);
mod_time = (XFASTINT (high) << 16) + XFASTINT (low);
if (current_buffer->base_buffer) if (current_buffer->base_buffer)
base_buffer = current_buffer->base_buffer; base_buffer = current_buffer->base_buffer;
......
...@@ -4299,18 +4299,9 @@ no value of TYPE (always string in the MS Windows case). */) ...@@ -4299,18 +4299,9 @@ no value of TYPE (always string in the MS Windows case). */)
if (! NILP (source)) if (! NILP (source))
{ {
if (NUMBERP (source)) CONS_TO_INTEGER (source, Window, target_window);
{ if (! target_window)
if (FLOATP (source)) target_window = FRAME_X_DISPLAY_INFO (f)->root_window;
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);
} }
BLOCK_INPUT; BLOCK_INPUT;
......
...@@ -20,6 +20,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ ...@@ -20,6 +20,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
/* Rewritten by jwz */ /* Rewritten by jwz */
#include <config.h> #include <config.h>
#include <limits.h>
#include <stdio.h> /* termhooks.h needs this */ #include <stdio.h> /* termhooks.h needs this */
#include <setjmp.h> #include <setjmp.h>
...@@ -335,7 +336,7 @@ x_own_selection (Lisp_Object selection_name, Lisp_Object selection_value, ...@@ -335,7 +336,7 @@ x_own_selection (Lisp_Object selection_name, Lisp_Object selection_value,
Lisp_Object prev_value; Lisp_Object prev_value;
selection_data = list4 (selection_name, selection_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); prev_value = LOCAL_SELECTION (selection_name, dpyinfo);
dpyinfo->terminal->Vselection_alist dpyinfo->terminal->Vselection_alist
...@@ -419,7 +420,7 @@ x_get_local_selection (Lisp_Object selection_symbol, Lisp_Object target_type, ...@@ -419,7 +420,7 @@ x_get_local_selection (Lisp_Object selection_symbol, Lisp_Object target_type,
|| INTEGERP (check) || INTEGERP (check)
|| NILP (value)) || NILP (value))
return 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) else if (CONSP (check)
&& INTEGERP (XCAR (check)) && INTEGERP (XCAR (check))
&& (INTEGERP (XCDR (check)) && (INTEGERP (XCDR (check))
...@@ -782,8 +783,8 @@ x_handle_selection_request (struct input_event *event) ...@@ -782,8 +783,8 @@ x_handle_selection_request (struct input_event *event)
if (NILP (local_selection_data)) goto DONE; if (NILP (local_selection_data)) goto DONE;
/* Decline requests issued prior to our acquiring the selection. */ /* Decline requests issued prior to our acquiring the selection. */
local_selection_time CONS_TO_INTEGER (XCAR (XCDR (XCDR (local_selection_data))),
= (Time) cons_to_long (XCAR (XCDR (XCDR (local_selection_data)))); Time, local_selection_time);