mirror of
git://git.sv.gnu.org/emacs.git
synced 2025-12-26 07:11:34 -08:00
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.
This commit is contained in:
parent
d1f3d2afe1
commit
be44ca6cd4
12 changed files with 219 additions and 195 deletions
|
|
@ -1,5 +1,35 @@
|
|||
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.
|
||||
* buffer.h (BUF_BYTES_MAX): New macro.
|
||||
* lisp.h (STRING_BYTES_MAX): New macro.
|
||||
|
|
|
|||
|
|
@ -932,17 +932,8 @@ usage: (define-charset-internal ...) */)
|
|||
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 @@ usage: (define-charset-internal ...) */)
|
|||
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 @@ and CODE-POINT to a character. Currently not supported and just ignored. */)
|
|||
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-point in CCS. Currently not supported and just ignored. */)
|
|||
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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -265,10 +265,7 @@ enum lglyph_indices
|
|||
#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 @@ enum lglyph_indices
|
|||
#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))
|
||||
|
|
|
|||
121
src/data.c
121
src/data.c
|
|
@ -2326,33 +2326,110 @@ DEFUN ("zerop", Fzerop, Szerop, 1, 1, 0,
|
|||
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. */
|
||||
|
||||
Lisp_Object
|
||||
long_to_cons (long unsigned int 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. */
|
||||
uintmax_t
|
||||
cons_to_unsigned (Lisp_Object c, uintmax_t max)
|
||||
{
|
||||
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));
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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) && 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,
|
||||
|
|
|
|||
39
src/dired.c
39
src/dired.c
|
|
@ -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.
|
||||
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 still fits into a 32-bit number, this is a cons cell
|
||||
containing two integers: first the high part, then the low 16 bits.
|
||||
If the inode number is wider than 32 bits, this is of the form
|
||||
(HIGH MIDDLE . LOW): first the high 24 bits, then middle 24 bits,
|
||||
10. inode number. If it is larger than what an Emacs integer can hold,
|
||||
this is of the form (HIGH . LOW): first the high bits, then the low 16 bits.
|
||||
If even HIGH is too large for an Emacs integer, this is instead of the form
|
||||
(HIGH MIDDLE . LOW): first the high bits, then the middle 24 bits,
|
||||
and finally 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 +997,8 @@ so last access time will always be midnight of that day. */)
|
|||
#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 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);
|
||||
values[10] = INTEGER_TO_CONS (s.st_ino);
|
||||
values[11] = INTEGER_TO_CONS (s.st_dev);
|
||||
|
||||
return Flist (sizeof(values) / sizeof(values[0]), values);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5005,7 +5005,7 @@ An argument specifies the modification time value to use
|
|||
{
|
||||
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
|
||||
|
|
|
|||
10
src/font.c
10
src/font.c
|
|
@ -4388,16 +4388,8 @@ where
|
|||
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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
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;
|
||||
}
|
||||
|
|
|
|||
32
src/lisp.h
32
src/lisp.h
|
|
@ -24,6 +24,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
|
|||
#include <stddef.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#include <intprops.h>
|
||||
|
||||
/* Use the configure flag --enable-checking[=LIST] to enable various
|
||||
types of run time checks for Lisp objects. */
|
||||
|
||||
|
|
@ -2408,9 +2410,35 @@ EXFUN (Fadd1, 1);
|
|||
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 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 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;
|
||||
|
|
|
|||
15
src/undo.c
15
src/undo.c
|
|
@ -212,7 +212,6 @@ record_change (EMACS_INT beg, EMACS_INT length)
|
|||
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 @@ record_first_change (void)
|
|||
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 @@ Return what remains of the list. */)
|
|||
if (EQ (car, Qt))
|
||||
{
|
||||
/* Element (t high . low) records previous modtime. */
|
||||
Lisp_Object high, low;
|
||||
time_t mod_time;
|
||||
struct buffer *base_buffer = current_buffer;
|
||||
|
||||
high = Fcar (cdr);
|
||||
low = Fcdr (cdr);
|
||||
mod_time = (XFASTINT (high) << 16) + XFASTINT (low);
|
||||
time_t mod_time;
|
||||
CONS_TO_INTEGER (cdr, time_t, mod_time);
|
||||
|
||||
if (current_buffer->base_buffer)
|
||||
base_buffer = current_buffer->base_buffer;
|
||||
|
|
|
|||
15
src/xfns.c
15
src/xfns.c
|
|
@ -4299,18 +4299,9 @@ no value of TYPE (always string in the MS Windows case). */)
|
|||
|
||||
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;
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
|
|||
/* Rewritten by jwz */
|
||||
|
||||
#include <config.h>
|
||||
#include <limits.h>
|
||||
#include <stdio.h> /* termhooks.h needs this */
|
||||
#include <setjmp.h>
|
||||
|
||||
|
|
@ -335,7 +336,7 @@ x_own_selection (Lisp_Object selection_name, Lisp_Object selection_value,
|
|||
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 +420,7 @@ x_get_local_selection (Lisp_Object selection_symbol, Lisp_Object target_type,
|
|||
|| 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 +783,8 @@ x_handle_selection_request (struct input_event *event)
|
|||
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 +951,8 @@ x_handle_selection_clear (struct input_event *event)
|
|||
/* 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. */
|
||||
|
|
@ -1212,16 +1213,7 @@ x_get_foreign_selection (Lisp_Object selection_symbol, Lisp_Object target_type,
|
|||
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;
|
||||
TRACE2 ("Get selection %s, type %s",
|
||||
|
|
@ -1639,7 +1631,7 @@ selection_data_to_lisp_data (Display *display, const unsigned char *data,
|
|||
convert it to a cons of integers, 16 bits in each half.
|
||||
*/
|
||||
else if (format == 32 && size == sizeof (int))
|
||||
return long_to_cons (((unsigned int *) data) [0]);
|
||||
return INTEGER_TO_CONS (((unsigned int *) data) [0]);
|
||||
else if (format == 16 && size == sizeof (short))
|
||||
return make_number ((int) (((unsigned short *) data) [0]));
|
||||
|
||||
|
|
@ -1665,7 +1657,7 @@ selection_data_to_lisp_data (Display *display, const unsigned char *data,
|
|||
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;
|
||||
}
|
||||
|
|
@ -1742,7 +1734,7 @@ lisp_data_to_selection_data (Display *display, Lisp_Object obj,
|
|||
*size_ret = 1;
|
||||
*data_ret = (unsigned char *) xmalloc (sizeof (long) + 1);
|
||||
(*data_ret) [sizeof (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))
|
||||
|
|
@ -1790,11 +1782,11 @@ lisp_data_to_selection_data (Display *display, Lisp_Object obj,
|
|||
*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
|
||||
|
|
@ -2012,8 +2004,10 @@ frame's display, or the first available X display. */)
|
|||
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;
|
||||
|
||||
|
|
@ -2250,12 +2244,8 @@ x_fill_property_data (Display *dpy, Lisp_Object data, void *ret, int format)
|
|||
{
|
||||
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;
|
||||
|
|
@ -2266,9 +2256,19 @@ x_fill_property_data (Display *dpy, Lisp_Object data, void *ret, int format)
|
|||
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;
|
||||
}
|
||||
|
|
@ -2352,14 +2352,7 @@ If the value is 0 or the atom is not known, return the empty string. */)
|
|||
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);
|
||||
|
|
@ -2549,17 +2542,8 @@ x_send_client_event (Lisp_Object display, Lisp_Object dest, Lisp_Object from, At
|
|||
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");
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue