Merge: Cons<->int and similar integer overflow fixes.
This commit is contained in:
commit
0c1477cd00
26 changed files with 328 additions and 240 deletions
|
@ -1,3 +1,8 @@
|
|||
2011-06-06 Paul Eggert <eggert@cs.ucla.edu>
|
||||
|
||||
* Makefile.in (ALL_CFLAGS): Add -I$(srcdir)/../lib.
|
||||
This is needed because lisp.h includes intprops.h now (Bug#8794).
|
||||
|
||||
2011-04-16 Paul Eggert <eggert@cs.ucla.edu>
|
||||
|
||||
Static checks with GCC 4.6.0 and non-default toolkits.
|
||||
|
|
|
@ -1,18 +1,18 @@
|
|||
# Copyright (C) 1992, 1993 Lucid, Inc.
|
||||
# Copyright (C) 1994, 2001-2011 Free Software Foundation, Inc.
|
||||
#
|
||||
#
|
||||
# This file is part of the Lucid Widget Library.
|
||||
#
|
||||
#
|
||||
# The Lucid Widget Library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 1, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
#
|
||||
# The Lucid Widget Library is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with GNU Emacs; see the file COPYING. If not, write to
|
||||
# the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
|
@ -55,7 +55,8 @@ OBJS = lwlib.o $(TOOLKIT_OBJS) lwlib-utils.o
|
|||
ALL_CFLAGS= $(C_SWITCH_SYSTEM) $(C_SWITCH_X_SITE) \
|
||||
$(C_SWITCH_X_SYSTEM) $(C_SWITCH_MACHINE) \
|
||||
$(C_WARNINGS_SWITCH) $(PROFILING_CFLAGS) $(CFLAGS) \
|
||||
-DHAVE_CONFIG_H -Demacs -I../src -I$(srcdir) -I$(srcdir)/../src
|
||||
-DHAVE_CONFIG_H -Demacs -I../src \
|
||||
-I$(srcdir) -I$(srcdir)/../src -I$(srcdir)/../lib
|
||||
|
||||
.c.o:
|
||||
$(CC) -c $(CPPFLAGS) $(ALL_CFLAGS) $<
|
||||
|
|
|
@ -1,3 +1,82 @@
|
|||
2011-06-06 Paul Eggert <eggert@cs.ucla.edu>
|
||||
|
||||
Cons<->int and similar integer overflow fixes.
|
||||
|
||||
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.
|
||||
* alloc.c (Fmake_string):
|
||||
* character.c (string_escape_byte8):
|
||||
* coding.c (coding_alloc_by_realloc):
|
||||
* doprnt.c (doprnt):
|
||||
* editfns.c (Fformat):
|
||||
* eval.c (verror):
|
||||
Use STRING_BYTES_MAX, not MOST_POSITIVE_FIXNUM,
|
||||
since they may not be the same number.
|
||||
* editfns.c (Finsert_char):
|
||||
* fileio.c (Finsert_file_contents):
|
||||
Likewise for BUF_BYTES_MAX.
|
||||
|
||||
* image.c: Use ptrdiff_t, not int, for sizes.
|
||||
(slurp_file): Switch from int to ptrdiff_t.
|
||||
All uses changed.
|
||||
(slurp_file): Check that file size fits in both size_t (for
|
||||
malloc) and ptrdiff_t (for sanity and safety).
|
||||
|
||||
* fileio.c (Fverify_visited_file_modtime): Avoid time overflow
|
||||
if b->modtime has its maximal value.
|
||||
|
||||
* dired.c (Ffile_attributes): Don't assume EMACS_INT has >32 bits.
|
||||
|
||||
Don't assume time_t can fit into int.
|
||||
* buffer.h (struct buffer.modtime): Now time_t, not int.
|
||||
* fileio.c (Fvisited_file_modtime): No need for time_t cast now.
|
||||
* undo.c (Fprimitive_undo): Use time_t, not int, for time_t value.
|
||||
|
||||
Minor fixes for signed vs unsigned integers.
|
||||
* character.h (MAYBE_UNIFY_CHAR):
|
||||
* charset.c (maybe_unify_char):
|
||||
* keyboard.c (read_char, reorder_modifiers):
|
||||
XINT -> XFASTINT, since the integer must be nonnegative.
|
||||
* ftfont.c (ftfont_spec_pattern):
|
||||
* keymap.c (access_keymap, silly_event_symbol_error):
|
||||
XUINT -> XFASTINT, since the integer must be nonnegative.
|
||||
(Fsingle_key_description, preferred_sequence_p): XUINT -> XINT,
|
||||
since it makes no difference and we prefer signed.
|
||||
* keyboard.c (record_char): Use XUINT when all the neighbors do.
|
||||
(access_keymap): NATNUMP -> INTEGERP, since the integer must be
|
||||
nonnegative.
|
||||
|
||||
2011-06-06 Stefan Monnier <monnier@iro.umontreal.ca>
|
||||
|
||||
* window.h (Fwindow_frame): Declare.
|
||||
|
|
|
@ -2204,7 +2204,7 @@ INIT must be an integer that represents a character. */)
|
|||
int len = CHAR_STRING (c, str);
|
||||
EMACS_INT string_len = XINT (length);
|
||||
|
||||
if (string_len > MOST_POSITIVE_FIXNUM / len)
|
||||
if (string_len > STRING_BYTES_MAX / len)
|
||||
string_overflow ();
|
||||
nbytes = len * string_len;
|
||||
val = make_uninit_multibyte_string (string_len, nbytes);
|
||||
|
|
|
@ -306,6 +306,11 @@ do \
|
|||
} \
|
||||
while (0)
|
||||
|
||||
/* Maximum number of bytes in a buffer.
|
||||
A buffer cannot contain more bytes than a 1-origin fixnum can represent,
|
||||
nor can it be so large that C pointer arithmetic stops working. */
|
||||
#define BUF_BYTES_MAX min (MOST_POSITIVE_FIXNUM - 1, min (SIZE_MAX, PTRDIFF_MAX))
|
||||
|
||||
/* Return the address of byte position N in current buffer. */
|
||||
|
||||
#define BYTE_POS_ADDR(n) \
|
||||
|
@ -545,7 +550,7 @@ struct buffer
|
|||
-1 means visited file was nonexistent.
|
||||
0 means visited file modtime unknown; in no case complain
|
||||
about any mismatch on next save attempt. */
|
||||
int modtime;
|
||||
time_t modtime;
|
||||
/* Size of the file when modtime was set. This is used to detect the
|
||||
case where the file grew while we were reading it, so the modtime
|
||||
is still the same (since it's rounded up to seconds) but we're actually
|
||||
|
|
|
@ -838,7 +838,7 @@ string_escape_byte8 (Lisp_Object string)
|
|||
if (multibyte)
|
||||
{
|
||||
if ((MOST_POSITIVE_FIXNUM - nchars) / 3 < byte8_count
|
||||
|| (MOST_POSITIVE_FIXNUM - nbytes) / 2 < byte8_count)
|
||||
|| (STRING_BYTES_MAX - nbytes) / 2 < byte8_count)
|
||||
string_overflow ();
|
||||
|
||||
/* Convert 2-byte sequence of byte8 chars to 4-byte octal. */
|
||||
|
@ -847,7 +847,7 @@ string_escape_byte8 (Lisp_Object string)
|
|||
}
|
||||
else
|
||||
{
|
||||
if ((MOST_POSITIVE_FIXNUM - nchars) / 3 < byte8_count)
|
||||
if ((STRING_BYTES_MAX - nchars) / 3 < byte8_count)
|
||||
string_overflow ();
|
||||
|
||||
/* Convert 1-byte sequence of byte8 chars to 4-byte octal. */
|
||||
|
|
|
@ -544,7 +544,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
|
|||
Lisp_Object val; \
|
||||
val = CHAR_TABLE_REF (Vchar_unify_table, c); \
|
||||
if (INTEGERP (val)) \
|
||||
c = XINT (val); \
|
||||
c = XFASTINT (val); \
|
||||
else if (! NILP (val)) \
|
||||
c = maybe_unify_char (c, val); \
|
||||
} \
|
||||
|
|
|
@ -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),
|
||||
|
@ -1637,7 +1619,7 @@ maybe_unify_char (int c, Lisp_Object val)
|
|||
struct charset *charset;
|
||||
|
||||
if (INTEGERP (val))
|
||||
return XINT (val);
|
||||
return XFASTINT (val);
|
||||
if (NILP (val))
|
||||
return c;
|
||||
|
||||
|
@ -1647,7 +1629,7 @@ maybe_unify_char (int c, Lisp_Object val)
|
|||
{
|
||||
val = CHAR_TABLE_REF (Vchar_unify_table, c);
|
||||
if (! NILP (val))
|
||||
c = XINT (val);
|
||||
c = XFASTINT (val);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1071,8 +1071,8 @@ coding_set_destination (struct coding_system *coding)
|
|||
static void
|
||||
coding_alloc_by_realloc (struct coding_system *coding, EMACS_INT bytes)
|
||||
{
|
||||
if (coding->dst_bytes >= MOST_POSITIVE_FIXNUM - bytes)
|
||||
error ("Maximum size of buffer or string exceeded");
|
||||
if (STRING_BYTES_MAX - coding->dst_bytes < bytes)
|
||||
string_overflow ();
|
||||
coding->destination = (unsigned char *) xrealloc (coding->destination,
|
||||
coding->dst_bytes + bytes);
|
||||
coding->dst_bytes += bytes;
|
||||
|
|
|
@ -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,
|
||||
|
|
40
src/dired.c
40
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,35 +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;
|
||||
EMACS_INT low_ino = s.st_ino & 0xffffffff;
|
||||
|
||||
values[10] = Fcons (make_number (high_ino >> 8),
|
||||
Fcons (make_number (((high_ino & 0xff) << 16)
|
||||
+ (low_ino >> 16)),
|
||||
make_number (low_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);
|
||||
}
|
||||
|
|
|
@ -329,7 +329,7 @@ doprnt (char *buffer, register size_t bufsize, const char *format,
|
|||
minlen = atoi (&fmtcpy[1]);
|
||||
string = va_arg (ap, char *);
|
||||
tem = strlen (string);
|
||||
if (tem > MOST_POSITIVE_FIXNUM)
|
||||
if (tem > STRING_BYTES_MAX)
|
||||
error ("String for %%s or %%S format is too long");
|
||||
width = strwidth (string, tem);
|
||||
goto doit1;
|
||||
|
@ -338,7 +338,7 @@ doprnt (char *buffer, register size_t bufsize, const char *format,
|
|||
doit:
|
||||
/* Coming here means STRING contains ASCII only. */
|
||||
tem = strlen (string);
|
||||
if (tem > MOST_POSITIVE_FIXNUM)
|
||||
if (tem > STRING_BYTES_MAX)
|
||||
error ("Format width or precision too large");
|
||||
width = tem;
|
||||
doit1:
|
||||
|
|
|
@ -2342,7 +2342,7 @@ from adjoining text, if those properties are sticky. */)
|
|||
len = CHAR_STRING (XFASTINT (character), str);
|
||||
else
|
||||
str[0] = XFASTINT (character), len = 1;
|
||||
if (MOST_POSITIVE_FIXNUM / len < XINT (count))
|
||||
if (BUF_BYTES_MAX / len < XINT (count))
|
||||
error ("Maximum buffer size would be exceeded");
|
||||
n = XINT (count) * len;
|
||||
if (n <= 0)
|
||||
|
@ -3589,7 +3589,7 @@ usage: (format STRING &rest OBJECTS) */)
|
|||
char initial_buffer[4000];
|
||||
char *buf = initial_buffer;
|
||||
EMACS_INT bufsize = sizeof initial_buffer;
|
||||
EMACS_INT max_bufsize = min (MOST_POSITIVE_FIXNUM + 1, SIZE_MAX);
|
||||
EMACS_INT max_bufsize = STRING_BYTES_MAX + 1;
|
||||
char *p;
|
||||
Lisp_Object buf_save_value IF_LINT (= {0});
|
||||
register char *format, *end, *format_start;
|
||||
|
|
|
@ -1994,7 +1994,7 @@ verror (const char *m, va_list ap)
|
|||
{
|
||||
char buf[4000];
|
||||
size_t size = sizeof buf;
|
||||
size_t size_max = min (MOST_POSITIVE_FIXNUM + 1, SIZE_MAX);
|
||||
size_t size_max = STRING_BYTES_MAX + 1;
|
||||
size_t mlen = strlen (m);
|
||||
char *buffer = buf;
|
||||
size_t used;
|
||||
|
|
|
@ -3248,7 +3248,7 @@ variable `last-coding-system-used' to the coding system actually used. */)
|
|||
/* Check whether the size is too large or negative, which can happen on a
|
||||
platform that allows file sizes greater than the maximum off_t value. */
|
||||
if (! not_regular
|
||||
&& ! (0 <= st.st_size && st.st_size <= MOST_POSITIVE_FIXNUM))
|
||||
&& ! (0 <= st.st_size && st.st_size <= BUF_BYTES_MAX))
|
||||
error ("Maximum buffer size exceeded");
|
||||
|
||||
/* Prevent redisplay optimizations. */
|
||||
|
@ -4960,7 +4960,7 @@ See Info node `(elisp)Modification Time' for more details. */)
|
|||
if ((st.st_mtime == b->modtime
|
||||
/* If both are positive, accept them if they are off by one second. */
|
||||
|| (st.st_mtime > 0 && b->modtime > 0
|
||||
&& (st.st_mtime == b->modtime + 1
|
||||
&& (st.st_mtime - 1 == b->modtime
|
||||
|| st.st_mtime == b->modtime - 1)))
|
||||
&& (st.st_size == b->modtime_size
|
||||
|| b->modtime_size < 0))
|
||||
|
@ -4990,7 +4990,7 @@ See Info node `(elisp)Modification Time' for more details. */)
|
|||
{
|
||||
if (! current_buffer->modtime)
|
||||
return make_number (0);
|
||||
return make_time ((time_t) current_buffer->modtime);
|
||||
return make_time (current_buffer->modtime);
|
||||
}
|
||||
|
||||
DEFUN ("set-visited-file-modtime", Fset_visited_file_modtime,
|
||||
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -815,7 +815,7 @@ ftfont_spec_pattern (Lisp_Object spec, char *otlayout, struct OpenTypeSpec **ots
|
|||
goto err;
|
||||
for (chars = XCDR (chars); CONSP (chars); chars = XCDR (chars))
|
||||
if (CHARACTERP (XCAR (chars))
|
||||
&& ! FcCharSetAddChar (charset, XUINT (XCAR (chars))))
|
||||
&& ! FcCharSetAddChar (charset, XFASTINT (XCAR (chars))))
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
|
19
src/image.c
19
src/image.c
|
@ -2112,9 +2112,6 @@ x_put_x_image (struct frame *f, XImagePtr ximg, Pixmap pixmap, int width, int he
|
|||
File Handling
|
||||
***********************************************************************/
|
||||
|
||||
static unsigned char *slurp_file (char *, int *);
|
||||
|
||||
|
||||
/* Find image file FILE. Look in data-directory/images, then
|
||||
x-bitmap-file-path. Value is the encoded full name of the file
|
||||
found, or nil if not found. */
|
||||
|
@ -2151,7 +2148,7 @@ x_find_image_file (Lisp_Object file)
|
|||
occurred. *SIZE is set to the size of the file. */
|
||||
|
||||
static unsigned char *
|
||||
slurp_file (char *file, int *size)
|
||||
slurp_file (char *file, ptrdiff_t *size)
|
||||
{
|
||||
FILE *fp = NULL;
|
||||
unsigned char *buf = NULL;
|
||||
|
@ -2159,6 +2156,7 @@ slurp_file (char *file, int *size)
|
|||
|
||||
if (stat (file, &st) == 0
|
||||
&& (fp = fopen (file, "rb")) != NULL
|
||||
&& 0 <= st.st_size && st.st_size <= min (PTRDIFF_MAX, SIZE_MAX)
|
||||
&& (buf = (unsigned char *) xmalloc (st.st_size),
|
||||
fread (buf, 1, st.st_size, fp) == st.st_size))
|
||||
{
|
||||
|
@ -2814,7 +2812,7 @@ xbm_load (struct frame *f, struct image *img)
|
|||
{
|
||||
Lisp_Object file;
|
||||
unsigned char *contents;
|
||||
int size;
|
||||
ptrdiff_t size;
|
||||
|
||||
file = x_find_image_file (file_name);
|
||||
if (!STRINGP (file))
|
||||
|
@ -4039,7 +4037,7 @@ xpm_load (struct frame *f,
|
|||
{
|
||||
Lisp_Object file;
|
||||
unsigned char *contents;
|
||||
int size;
|
||||
ptrdiff_t size;
|
||||
|
||||
file = x_find_image_file (file_name);
|
||||
if (!STRINGP (file))
|
||||
|
@ -5021,6 +5019,7 @@ pbm_read_file (file, size)
|
|||
|
||||
if (stat (SDATA (file), &st) == 0
|
||||
&& (fp = fopen (SDATA (file), "rb")) != NULL
|
||||
&& 0 <= st.st_size && st.st_size <= min (PTRDIFF_MAX, SIZE_MAX)
|
||||
&& (buf = (char *) xmalloc (st.st_size),
|
||||
fread (buf, 1, st.st_size, fp) == st.st_size))
|
||||
{
|
||||
|
@ -5055,7 +5054,7 @@ pbm_load (struct frame *f, struct image *img)
|
|||
enum {PBM_MONO, PBM_GRAY, PBM_COLOR} type;
|
||||
unsigned char *contents = NULL;
|
||||
unsigned char *end, *p;
|
||||
int size;
|
||||
ptrdiff_t size;
|
||||
|
||||
specified_file = image_spec_value (img->spec, QCfile, NULL);
|
||||
|
||||
|
@ -7869,7 +7868,7 @@ static int svg_image_p (Lisp_Object object);
|
|||
static int svg_load (struct frame *f, struct image *img);
|
||||
|
||||
static int svg_load_image (struct frame *, struct image *,
|
||||
unsigned char *, unsigned int);
|
||||
unsigned char *, ptrdiff_t);
|
||||
|
||||
/* The symbol `svg' identifying images of this type. */
|
||||
|
||||
|
@ -8047,7 +8046,7 @@ svg_load (struct frame *f, struct image *img)
|
|||
{
|
||||
Lisp_Object file;
|
||||
unsigned char *contents;
|
||||
int size;
|
||||
ptrdiff_t size;
|
||||
|
||||
file = x_find_image_file (file_name);
|
||||
if (!STRINGP (file))
|
||||
|
@ -8096,7 +8095,7 @@ static int
|
|||
svg_load_image (struct frame *f, /* Pointer to emacs frame structure. */
|
||||
struct image *img, /* Pointer to emacs image structure. */
|
||||
unsigned char *contents, /* String containing the SVG XML data to be parsed. */
|
||||
unsigned int size) /* Size of data in bytes. */
|
||||
ptrdiff_t size) /* Size of data in bytes. */
|
||||
{
|
||||
RsvgHandle *rsvg_handle;
|
||||
RsvgDimensionData dimension_data;
|
||||
|
|
|
@ -2395,8 +2395,8 @@ read_char (int commandflag, int nmaps, Lisp_Object *maps, Lisp_Object prev_event
|
|||
|
||||
c = Faref (Vexecuting_kbd_macro, make_number (executing_kbd_macro_index));
|
||||
if (STRINGP (Vexecuting_kbd_macro)
|
||||
&& (XINT (c) & 0x80) && (XUINT (c) <= 0xff))
|
||||
XSETFASTINT (c, CHAR_META | (XINT (c) & ~0x80));
|
||||
&& (XFASTINT (c) & 0x80) && (XFASTINT (c) <= 0xff))
|
||||
XSETFASTINT (c, CHAR_META | (XFASTINT (c) & ~0x80));
|
||||
|
||||
executing_kbd_macro_index++;
|
||||
|
||||
|
@ -3321,7 +3321,7 @@ record_char (Lisp_Object c)
|
|||
if (INTEGERP (c))
|
||||
{
|
||||
if (XUINT (c) < 0x100)
|
||||
putc (XINT (c), dribble);
|
||||
putc (XUINT (c), dribble);
|
||||
else
|
||||
fprintf (dribble, " 0x%"pI"x", XUINT (c));
|
||||
}
|
||||
|
@ -6370,7 +6370,7 @@ reorder_modifiers (Lisp_Object symbol)
|
|||
Lisp_Object parsed;
|
||||
|
||||
parsed = parse_modifiers (symbol);
|
||||
return apply_modifiers ((int) XINT (XCAR (XCDR (parsed))),
|
||||
return apply_modifiers (XFASTINT (XCAR (XCDR (parsed))),
|
||||
XCAR (parsed));
|
||||
}
|
||||
|
||||
|
|
14
src/keymap.c
14
src/keymap.c
|
@ -462,7 +462,7 @@ access_keymap (Lisp_Object map, Lisp_Object idx, int t_ok, int noinherit, int au
|
|||
XSETFASTINT (idx, XINT (idx) & (CHAR_META | (CHAR_META - 1)));
|
||||
|
||||
/* Handle the special meta -> esc mapping. */
|
||||
if (INTEGERP (idx) && XUINT (idx) & meta_modifier)
|
||||
if (INTEGERP (idx) && XFASTINT (idx) & meta_modifier)
|
||||
{
|
||||
/* See if there is a meta-map. If there's none, there is
|
||||
no binding for IDX, unless a default binding exists in MAP. */
|
||||
|
@ -480,7 +480,7 @@ access_keymap (Lisp_Object map, Lisp_Object idx, int t_ok, int noinherit, int au
|
|||
if (CONSP (event_meta_map))
|
||||
{
|
||||
map = event_meta_map;
|
||||
idx = make_number (XUINT (idx) & ~meta_modifier);
|
||||
idx = make_number (XFASTINT (idx) & ~meta_modifier);
|
||||
}
|
||||
else if (t_ok)
|
||||
/* Set IDX to t, so that we only find a default binding. */
|
||||
|
@ -529,7 +529,7 @@ access_keymap (Lisp_Object map, Lisp_Object idx, int t_ok, int noinherit, int au
|
|||
}
|
||||
else if (VECTORP (binding))
|
||||
{
|
||||
if (NATNUMP (idx) && XFASTINT (idx) < ASIZE (binding))
|
||||
if (INTEGERP (idx) && XFASTINT (idx) < ASIZE (binding))
|
||||
val = AREF (binding, XFASTINT (idx));
|
||||
}
|
||||
else if (CHAR_TABLE_P (binding))
|
||||
|
@ -537,7 +537,7 @@ access_keymap (Lisp_Object map, Lisp_Object idx, int t_ok, int noinherit, int au
|
|||
/* Character codes with modifiers
|
||||
are not included in a char-table.
|
||||
All character codes without modifiers are included. */
|
||||
if (NATNUMP (idx) && (XFASTINT (idx) & CHAR_MODIFIER_MASK) == 0)
|
||||
if (INTEGERP (idx) && (XFASTINT (idx) & CHAR_MODIFIER_MASK) == 0)
|
||||
{
|
||||
val = Faref (binding, idx);
|
||||
/* `nil' has a special meaning for char-tables, so
|
||||
|
@ -1357,7 +1357,7 @@ silly_event_symbol_error (Lisp_Object c)
|
|||
int modifiers;
|
||||
|
||||
parsed = parse_modifiers (c);
|
||||
modifiers = (int) XUINT (XCAR (XCDR (parsed)));
|
||||
modifiers = XFASTINT (XCAR (XCDR (parsed)));
|
||||
base = XCAR (parsed);
|
||||
name = Fsymbol_name (base);
|
||||
/* This alist includes elements such as ("RET" . "\\r"). */
|
||||
|
@ -2416,7 +2416,7 @@ around function keys and event symbols. */)
|
|||
{
|
||||
char tem[KEY_DESCRIPTION_SIZE];
|
||||
|
||||
*push_key_description (XUINT (key), tem, 1) = 0;
|
||||
*push_key_description (XINT (key), tem, 1) = 0;
|
||||
return build_string (tem);
|
||||
}
|
||||
else if (SYMBOLP (key)) /* Function key or event-symbol */
|
||||
|
@ -2515,7 +2515,7 @@ preferred_sequence_p (Lisp_Object seq)
|
|||
return 0;
|
||||
else
|
||||
{
|
||||
int modifiers = XUINT (elt) & (CHAR_MODIFIER_MASK & ~CHAR_META);
|
||||
int modifiers = XINT (elt) & (CHAR_MODIFIER_MASK & ~CHAR_META);
|
||||
if (modifiers == where_is_preferred_modifier)
|
||||
result = 2;
|
||||
else if (modifiers)
|
||||
|
|
38
src/lisp.h
38
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. */
|
||||
|
||||
|
@ -763,6 +765,12 @@ extern EMACS_INT string_bytes (struct Lisp_String *);
|
|||
|
||||
#endif /* not GC_CHECK_STRING_BYTES */
|
||||
|
||||
/* A string cannot contain more bytes than a fixnum can represent,
|
||||
nor can it be so long that C pointer arithmetic stops working on
|
||||
the string plus a terminating null. */
|
||||
#define STRING_BYTES_MAX \
|
||||
min (MOST_POSITIVE_FIXNUM, min (SIZE_MAX, PTRDIFF_MAX) - 1)
|
||||
|
||||
/* Mark STR as a unibyte string. */
|
||||
#define STRING_SET_UNIBYTE(STR) \
|
||||
do { if (EQ (STR, empty_multibyte_string)) \
|
||||
|
@ -2402,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;
|
||||
int 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
Reference in a new issue