diff options
| author | Paul Eggert | 2011-06-03 12:02:25 -0700 |
|---|---|---|
| committer | Paul Eggert | 2011-06-03 12:02:25 -0700 |
| commit | 201f31ae3de0b747b47863b93d6f6a747c36c960 (patch) | |
| tree | 800c2c66fc648660cb957df676ea59cc911ae0fa /src | |
| parent | be14b9ab109c8deb5745dc47cbc471e97be06486 (diff) | |
| download | emacs-201f31ae3de0b747b47863b93d6f6a747c36c960.tar.gz emacs-201f31ae3de0b747b47863b93d6f6a747c36c960.zip | |
Check for overflow when converting integer to cons and back.
* charset.c (Fdefine_charset_internal, Fdecode_char):
Use cons_to_unsigned to catch overflow.
(Fencode_char): Use INTEGER_TO_CONS.
* composite.h (LGLYPH_CODE): Use cons_to_unsigned.
(LGLYPH_SET_CODE): Use INTEGER_TO_CONS.
* data.c (long_to_cons, cons_to_long): Remove.
(cons_to_unsigned, cons_to_signed): New functions.
These signal an error for invalid or out-of-range values.
* dired.c (Ffile_attributes): Use INTEGER_TO_CONS.
* fileio.c (Fset_visited_file_modtime): Use CONS_TO_INTEGER.
* font.c (Ffont_variation_glyphs):
* fontset.c (Finternal_char_font): Use INTEGER_TO_CONS.
* lisp.h (INTEGER_TO_CONS, CONS_TO_INTEGER): New macros.
(cons_to_signed, cons_to_unsigned): New decls.
(long_to_cons, cons_to_long): Remove decls.
* undo.c (record_first_change): Use INTEGER_TO_CONS.
(Fprimitive_undo): Use CONS_TO_INTEGER.
* xfns.c (Fx_window_property): Likewise.
* xselect.c (x_own_selection, selection_data_to_lisp_data):
Use INTEGER_TO_CONS.
(x_handle_selection_request, x_handle_selection_clear)
(x_get_foreign_selection, Fx_disown_selection_internal)
(Fx_get_atom_name, x_send_client_event): Use CONS_TO_INTEGER.
(lisp_data_to_selection_data): Use cons_to_unsigned.
(x_fill_property_data): Use cons_to_signed. Report values out of range.
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 27 | ||||
| -rw-r--r-- | src/charset.c | 38 | ||||
| -rw-r--r-- | src/composite.h | 16 | ||||
| -rw-r--r-- | src/data.c | 100 | ||||
| -rw-r--r-- | src/dired.c | 39 | ||||
| -rw-r--r-- | src/fileio.c | 2 | ||||
| -rw-r--r-- | src/font.c | 10 | ||||
| -rw-r--r-- | src/fontset.c | 8 | ||||
| -rw-r--r-- | src/lisp.h | 28 | ||||
| -rw-r--r-- | src/undo.c | 15 | ||||
| -rw-r--r-- | src/xfns.c | 15 | ||||
| -rw-r--r-- | src/xselect.c | 87 |
12 files changed, 189 insertions, 196 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 857600fda0c..20308d40ab0 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,5 +1,32 @@ | |||
| 1 | 2011-06-03 Paul Eggert <eggert@cs.ucla.edu> | 1 | 2011-06-03 Paul Eggert <eggert@cs.ucla.edu> |
| 2 | 2 | ||
| 3 | Check for overflow when converting integer to cons and back. | ||
| 4 | * charset.c (Fdefine_charset_internal, Fdecode_char): | ||
| 5 | Use cons_to_unsigned to catch overflow. | ||
| 6 | (Fencode_char): Use INTEGER_TO_CONS. | ||
| 7 | * composite.h (LGLYPH_CODE): Use cons_to_unsigned. | ||
| 8 | (LGLYPH_SET_CODE): Use INTEGER_TO_CONS. | ||
| 9 | * data.c (long_to_cons, cons_to_long): Remove. | ||
| 10 | (cons_to_unsigned, cons_to_signed): New functions. | ||
| 11 | These signal an error for invalid or out-of-range values. | ||
| 12 | * dired.c (Ffile_attributes): Use INTEGER_TO_CONS. | ||
| 13 | * fileio.c (Fset_visited_file_modtime): Use CONS_TO_INTEGER. | ||
| 14 | * font.c (Ffont_variation_glyphs): | ||
| 15 | * fontset.c (Finternal_char_font): Use INTEGER_TO_CONS. | ||
| 16 | * lisp.h (INTEGER_TO_CONS, CONS_TO_INTEGER): New macros. | ||
| 17 | (cons_to_signed, cons_to_unsigned): New decls. | ||
| 18 | (long_to_cons, cons_to_long): Remove decls. | ||
| 19 | * undo.c (record_first_change): Use INTEGER_TO_CONS. | ||
| 20 | (Fprimitive_undo): Use CONS_TO_INTEGER. | ||
| 21 | * xfns.c (Fx_window_property): Likewise. | ||
| 22 | * xselect.c (x_own_selection, selection_data_to_lisp_data): | ||
| 23 | Use INTEGER_TO_CONS. | ||
| 24 | (x_handle_selection_request, x_handle_selection_clear) | ||
| 25 | (x_get_foreign_selection, Fx_disown_selection_internal) | ||
| 26 | (Fx_get_atom_name, x_send_client_event): Use CONS_TO_INTEGER. | ||
| 27 | (lisp_data_to_selection_data): Use cons_to_unsigned. | ||
| 28 | (x_fill_property_data): Use cons_to_signed. Report values out of range. | ||
| 29 | |||
| 3 | Fix doc for machines with wider system times such as time_t. | 30 | Fix doc for machines with wider system times such as time_t. |
| 4 | On such machines, it's now safe to assume that EMACS_INT is as | 31 | On such machines, it's now safe to assume that EMACS_INT is as |
| 5 | wide as the system times, so that shifting right by 16 will | 32 | wide as the system times, so that shifting right by 16 will |
diff --git a/src/charset.c b/src/charset.c index bfebe02f52e..770e98c99e1 100644 --- a/src/charset.c +++ b/src/charset.c | |||
| @@ -932,17 +932,8 @@ usage: (define-charset-internal ...) */) | |||
| 932 | val = args[charset_arg_min_code]; | 932 | val = args[charset_arg_min_code]; |
| 933 | if (! NILP (val)) | 933 | if (! NILP (val)) |
| 934 | { | 934 | { |
| 935 | unsigned code; | 935 | unsigned code = cons_to_unsigned (val, UINT_MAX); |
| 936 | 936 | ||
| 937 | if (INTEGERP (val)) | ||
| 938 | code = XINT (val); | ||
| 939 | else | ||
| 940 | { | ||
| 941 | CHECK_CONS (val); | ||
| 942 | CHECK_NUMBER_CAR (val); | ||
| 943 | CHECK_NUMBER_CDR (val); | ||
| 944 | code = (XINT (XCAR (val)) << 16) | (XINT (XCDR (val))); | ||
| 945 | } | ||
| 946 | if (code < charset.min_code | 937 | if (code < charset.min_code |
| 947 | || code > charset.max_code) | 938 | || code > charset.max_code) |
| 948 | args_out_of_range_3 (make_number (charset.min_code), | 939 | args_out_of_range_3 (make_number (charset.min_code), |
| @@ -954,17 +945,8 @@ usage: (define-charset-internal ...) */) | |||
| 954 | val = args[charset_arg_max_code]; | 945 | val = args[charset_arg_max_code]; |
| 955 | if (! NILP (val)) | 946 | if (! NILP (val)) |
| 956 | { | 947 | { |
| 957 | unsigned code; | 948 | unsigned code = cons_to_unsigned (val, UINT_MAX); |
| 958 | 949 | ||
| 959 | if (INTEGERP (val)) | ||
| 960 | code = XINT (val); | ||
| 961 | else | ||
| 962 | { | ||
| 963 | CHECK_CONS (val); | ||
| 964 | CHECK_NUMBER_CAR (val); | ||
| 965 | CHECK_NUMBER_CDR (val); | ||
| 966 | code = (XINT (XCAR (val)) << 16) | (XINT (XCDR (val))); | ||
| 967 | } | ||
| 968 | if (code < charset.min_code | 950 | if (code < charset.min_code |
| 969 | || code > charset.max_code) | 951 | || code > charset.max_code) |
| 970 | args_out_of_range_3 (make_number (charset.min_code), | 952 | 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 | struct charset *charsetp; | 1847 | struct charset *charsetp; |
| 1866 | 1848 | ||
| 1867 | CHECK_CHARSET_GET_ID (charset, id); | 1849 | CHECK_CHARSET_GET_ID (charset, id); |
| 1868 | if (CONSP (code_point)) | 1850 | code = cons_to_unsigned (code_point, UINT_MAX); |
| 1869 | { | ||
| 1870 | CHECK_NATNUM_CAR (code_point); | ||
| 1871 | CHECK_NATNUM_CDR (code_point); | ||
| 1872 | code = (XINT (XCAR (code_point)) << 16) | (XINT (XCDR (code_point))); | ||
| 1873 | } | ||
| 1874 | else | ||
| 1875 | { | ||
| 1876 | CHECK_NATNUM (code_point); | ||
| 1877 | code = XINT (code_point); | ||
| 1878 | } | ||
| 1879 | charsetp = CHARSET_FROM_ID (id); | 1851 | charsetp = CHARSET_FROM_ID (id); |
| 1880 | c = DECODE_CHAR (charsetp, code); | 1852 | c = DECODE_CHAR (charsetp, code); |
| 1881 | return (c >= 0 ? make_number (c) : Qnil); | 1853 | return (c >= 0 ? make_number (c) : Qnil); |
| @@ -1900,9 +1872,7 @@ code-point in CCS. Currently not supported and just ignored. */) | |||
| 1900 | code = ENCODE_CHAR (charsetp, XINT (ch)); | 1872 | code = ENCODE_CHAR (charsetp, XINT (ch)); |
| 1901 | if (code == CHARSET_INVALID_CODE (charsetp)) | 1873 | if (code == CHARSET_INVALID_CODE (charsetp)) |
| 1902 | return Qnil; | 1874 | return Qnil; |
| 1903 | if (code > 0x7FFFFFF) | 1875 | return INTEGER_TO_CONS (code); |
| 1904 | return Fcons (make_number (code >> 16), make_number (code & 0xFFFF)); | ||
| 1905 | return make_number (code); | ||
| 1906 | } | 1876 | } |
| 1907 | 1877 | ||
| 1908 | 1878 | ||
diff --git a/src/composite.h b/src/composite.h index cc8ca10a139..0f81911f0b0 100644 --- a/src/composite.h +++ b/src/composite.h | |||
| @@ -265,10 +265,7 @@ enum lglyph_indices | |||
| 265 | #define LGLYPH_CODE(g) \ | 265 | #define LGLYPH_CODE(g) \ |
| 266 | (NILP (AREF ((g), LGLYPH_IX_CODE)) \ | 266 | (NILP (AREF ((g), LGLYPH_IX_CODE)) \ |
| 267 | ? FONT_INVALID_CODE \ | 267 | ? FONT_INVALID_CODE \ |
| 268 | : CONSP (AREF ((g), LGLYPH_IX_CODE)) \ | 268 | : cons_to_unsigned (AREF (g, LGLYPH_IX_CODE), TYPE_MAXIMUM (unsigned))) |
| 269 | ? ((XFASTINT (XCAR (AREF ((g), LGLYPH_IX_CODE))) << 16) \ | ||
| 270 | | (XFASTINT (XCDR (AREF ((g), LGLYPH_IX_CODE))))) \ | ||
| 271 | : XFASTINT (AREF ((g), LGLYPH_IX_CODE))) | ||
| 272 | #define LGLYPH_WIDTH(g) XINT (AREF ((g), LGLYPH_IX_WIDTH)) | 269 | #define LGLYPH_WIDTH(g) XINT (AREF ((g), LGLYPH_IX_WIDTH)) |
| 273 | #define LGLYPH_LBEARING(g) XINT (AREF ((g), LGLYPH_IX_LBEARING)) | 270 | #define LGLYPH_LBEARING(g) XINT (AREF ((g), LGLYPH_IX_LBEARING)) |
| 274 | #define LGLYPH_RBEARING(g) XINT (AREF ((g), LGLYPH_IX_RBEARING)) | 271 | #define LGLYPH_RBEARING(g) XINT (AREF ((g), LGLYPH_IX_RBEARING)) |
| @@ -280,15 +277,8 @@ enum lglyph_indices | |||
| 280 | #define LGLYPH_SET_CHAR(g, val) ASET ((g), LGLYPH_IX_CHAR, make_number (val)) | 277 | #define LGLYPH_SET_CHAR(g, val) ASET ((g), LGLYPH_IX_CHAR, make_number (val)) |
| 281 | /* Callers must assure that VAL is not negative! */ | 278 | /* Callers must assure that VAL is not negative! */ |
| 282 | #define LGLYPH_SET_CODE(g, val) \ | 279 | #define LGLYPH_SET_CODE(g, val) \ |
| 283 | do { \ | 280 | ASET (g, LGLYPH_IX_CODE, \ |
| 284 | if (val == FONT_INVALID_CODE) \ | 281 | val == FONT_INVALID_CODE ? Qnil : INTEGER_TO_CONS (val)) |
| 285 | ASET ((g), LGLYPH_IX_CODE, Qnil); \ | ||
| 286 | else if ((EMACS_INT)val > MOST_POSITIVE_FIXNUM) \ | ||
| 287 | ASET ((g), LGLYPH_IX_CODE, Fcons (make_number ((val) >> 16), \ | ||
| 288 | make_number ((val) & 0xFFFF))); \ | ||
| 289 | else \ | ||
| 290 | ASET ((g), LGLYPH_IX_CODE, make_number (val)); \ | ||
| 291 | } while (0) | ||
| 292 | 282 | ||
| 293 | #define LGLYPH_SET_WIDTH(g, val) ASET ((g), LGLYPH_IX_WIDTH, make_number (val)) | 283 | #define LGLYPH_SET_WIDTH(g, val) ASET ((g), LGLYPH_IX_WIDTH, make_number (val)) |
| 294 | #define LGLYPH_SET_LBEARING(g, val) ASET ((g), LGLYPH_IX_LBEARING, make_number (val)) | 284 | #define LGLYPH_SET_LBEARING(g, val) ASET ((g), LGLYPH_IX_LBEARING, make_number (val)) |
diff --git a/src/data.c b/src/data.c index 522f0156ebd..408234f25cb 100644 --- a/src/data.c +++ b/src/data.c | |||
| @@ -2324,33 +2324,89 @@ DEFUN ("zerop", Fzerop, Szerop, 1, 1, 0, | |||
| 2324 | return Qnil; | 2324 | return Qnil; |
| 2325 | } | 2325 | } |
| 2326 | 2326 | ||
| 2327 | /* Convert between long values and pairs of Lisp integers. | 2327 | /* Convert the cons-of-integers, integer, or float value C to an |
| 2328 | Note that long_to_cons returns a single Lisp integer | 2328 | unsigned value with maximum value MAX. Signal an error if C does not |
| 2329 | when the value fits in one. */ | 2329 | have a valid format or is out of range. */ |
| 2330 | uintmax_t | ||
| 2331 | cons_to_unsigned (Lisp_Object c, uintmax_t max) | ||
| 2332 | { | ||
| 2333 | int valid = 0; | ||
| 2334 | uintmax_t val IF_LINT (= 0); | ||
| 2335 | if (INTEGERP (c)) | ||
| 2336 | { | ||
| 2337 | valid = 0 <= XINT (c); | ||
| 2338 | val = XINT (c); | ||
| 2339 | } | ||
| 2340 | else if (FLOATP (c)) | ||
| 2341 | { | ||
| 2342 | double d = XFLOAT_DATA (c); | ||
| 2343 | if (0 <= d | ||
| 2344 | && d < (max == UINTMAX_MAX ? (double) UINTMAX_MAX + 1 : max + 1)) | ||
| 2345 | { | ||
| 2346 | val = d; | ||
| 2347 | valid = 1; | ||
| 2348 | } | ||
| 2349 | } | ||
| 2350 | else if (CONSP (c)) | ||
| 2351 | { | ||
| 2352 | Lisp_Object top = XCAR (c); | ||
| 2353 | Lisp_Object bot = XCDR (c); | ||
| 2354 | if (CONSP (bot)) | ||
| 2355 | bot = XCAR (bot); | ||
| 2356 | if (NATNUMP (top) && XFASTINT (top) <= UINTMAX_MAX >> 16 && NATNUMP (bot)) | ||
| 2357 | { | ||
| 2358 | uintmax_t utop = XFASTINT (top); | ||
| 2359 | val = (utop << 16) | XFASTINT (bot); | ||
| 2360 | valid = 1; | ||
| 2361 | } | ||
| 2362 | } | ||
| 2330 | 2363 | ||
| 2331 | Lisp_Object | 2364 | if (! (valid && val <= max)) |
| 2332 | long_to_cons (long unsigned int i) | 2365 | error ("Not an in-range integer, float, or cons of integers"); |
| 2333 | { | 2366 | return val; |
| 2334 | unsigned long top = i >> 16; | ||
| 2335 | unsigned int bot = i & 0xFFFF; | ||
| 2336 | if (top == 0) | ||
| 2337 | return make_number (bot); | ||
| 2338 | if (top == (unsigned long)-1 >> 16) | ||
| 2339 | return Fcons (make_number (-1), make_number (bot)); | ||
| 2340 | return Fcons (make_number (top), make_number (bot)); | ||
| 2341 | } | 2367 | } |
| 2342 | 2368 | ||
| 2343 | unsigned long | 2369 | /* Convert the cons-of-integers, integer, or float value C to a signed |
| 2344 | cons_to_long (Lisp_Object c) | 2370 | value with extrema MIN and MAX. Signal an error if C does not have |
| 2371 | a valid format or is out of range. */ | ||
| 2372 | intmax_t | ||
| 2373 | cons_to_signed (Lisp_Object c, intmax_t min, intmax_t max) | ||
| 2345 | { | 2374 | { |
| 2346 | Lisp_Object top, bot; | 2375 | int valid = 0; |
| 2376 | intmax_t val IF_LINT (= 0); | ||
| 2347 | if (INTEGERP (c)) | 2377 | if (INTEGERP (c)) |
| 2348 | return XINT (c); | 2378 | { |
| 2349 | top = XCAR (c); | 2379 | val = XINT (c); |
| 2350 | bot = XCDR (c); | 2380 | valid = 1; |
| 2351 | if (CONSP (bot)) | 2381 | } |
| 2352 | bot = XCAR (bot); | 2382 | else if (FLOATP (c)) |
| 2353 | return ((XINT (top) << 16) | XINT (bot)); | 2383 | { |
| 2384 | double d = XFLOAT_DATA (c); | ||
| 2385 | if (min <= d | ||
| 2386 | && d < (max == INTMAX_MAX ? (double) INTMAX_MAX + 1 : max + 1)) | ||
| 2387 | { | ||
| 2388 | val = d; | ||
| 2389 | valid = 1; | ||
| 2390 | } | ||
| 2391 | } | ||
| 2392 | else if (CONSP (c)) | ||
| 2393 | { | ||
| 2394 | Lisp_Object top = XCAR (c); | ||
| 2395 | Lisp_Object bot = XCDR (c); | ||
| 2396 | if (CONSP (bot)) | ||
| 2397 | bot = XCAR (bot); | ||
| 2398 | if (INTEGERP (top) && INTMAX_MIN >> 16 <= XINT (top) | ||
| 2399 | && XINT (top) <= INTMAX_MAX >> 16 && INTEGERP (bot)) | ||
| 2400 | { | ||
| 2401 | intmax_t itop = XINT (top); | ||
| 2402 | val = (itop << 16) | XINT (bot); | ||
| 2403 | valid = 1; | ||
| 2404 | } | ||
| 2405 | } | ||
| 2406 | |||
| 2407 | if (! (valid && min <= val && val <= max)) | ||
| 2408 | error ("Not an in-range integer, float, or cons of integers"); | ||
| 2409 | return val; | ||
| 2354 | } | 2410 | } |
| 2355 | 2411 | ||
| 2356 | DEFUN ("number-to-string", Fnumber_to_string, Snumber_to_string, 1, 1, 0, | 2412 | DEFUN ("number-to-string", Fnumber_to_string, Snumber_to_string, 1, 1, 0, |
diff --git a/src/dired.c b/src/dired.c index 0fe2ead56ef..3bf4fd9a023 100644 --- a/src/dired.c +++ b/src/dired.c | |||
| @@ -900,12 +900,9 @@ Elements of the attribute list are: | |||
| 900 | This is a floating point number if the size is too large for an integer. | 900 | This is a floating point number if the size is too large for an integer. |
| 901 | 8. File modes, as a string of ten letters or dashes as in ls -l. | 901 | 8. File modes, as a string of ten letters or dashes as in ls -l. |
| 902 | 9. t if file's gid would change if file were deleted and recreated. | 902 | 9. t if file's gid would change if file were deleted and recreated. |
| 903 | 10. inode number. If inode number is larger than what Emacs integer | 903 | 10. inode number. If it is larger than what the Emacs integer |
| 904 | can hold, but all but the bottom 16 bits still fits, this is a cons cell | 904 | can hold, this is a cons cell containing two integers: first the |
| 905 | containing two integers: first the high part, then the low 16 bits. | 905 | high part, then the low 16 bits. |
| 906 | If the inode number is still wider, this is of the form | ||
| 907 | (HIGH MIDDLE . LOW): first the high bits, then the middle 24 bits, | ||
| 908 | and finally the low 16 bits. | ||
| 909 | 11. Filesystem device number. If it is larger than what the Emacs | 906 | 11. Filesystem device number. If it is larger than what the Emacs |
| 910 | integer can hold, this is a cons cell, similar to the inode number. | 907 | integer can hold, this is a cons cell, similar to the inode number. |
| 911 | 908 | ||
| @@ -998,34 +995,8 @@ so last access time will always be midnight of that day. */) | |||
| 998 | #else /* file gid will be egid */ | 995 | #else /* file gid will be egid */ |
| 999 | values[9] = (s.st_gid != getegid ()) ? Qt : Qnil; | 996 | values[9] = (s.st_gid != getegid ()) ? Qt : Qnil; |
| 1000 | #endif /* not BSD4_2 */ | 997 | #endif /* not BSD4_2 */ |
| 1001 | if (!FIXNUM_OVERFLOW_P (s.st_ino)) | 998 | values[10] = INTEGER_TO_CONS (s.st_ino); |
| 1002 | /* Keep the most common cases as integers. */ | 999 | values[11] = INTEGER_TO_CONS (s.st_dev); |
| 1003 | values[10] = make_number (s.st_ino); | ||
| 1004 | else if (!FIXNUM_OVERFLOW_P (s.st_ino >> 16)) | ||
| 1005 | /* To allow inode numbers larger than VALBITS, separate the bottom | ||
| 1006 | 16 bits. */ | ||
| 1007 | values[10] = Fcons (make_number ((EMACS_INT)(s.st_ino >> 16)), | ||
| 1008 | make_number ((EMACS_INT)(s.st_ino & 0xffff))); | ||
| 1009 | else | ||
| 1010 | { | ||
| 1011 | /* To allow inode numbers beyond what INTEGER_TO_CONS can handle, | ||
| 1012 | separate into 2 24-bit high parts and a 16-bit bottom part. | ||
| 1013 | The code on the next line avoids a compiler warning on | ||
| 1014 | systems where st_ino is 32 bit wide. (bug#766). */ | ||
| 1015 | EMACS_INT high_ino = s.st_ino >> 31 >> 1; | ||
| 1016 | |||
| 1017 | values[10] = Fcons (make_number (high_ino >> 8), | ||
| 1018 | Fcons (make_number (((high_ino & 0xff) << 16) | ||
| 1019 | + (s.st_ino >> 16 & 0xffff)), | ||
| 1020 | make_number (s.st_ino & 0xffff))); | ||
| 1021 | } | ||
| 1022 | |||
| 1023 | /* Likewise for device. */ | ||
| 1024 | if (FIXNUM_OVERFLOW_P (s.st_dev)) | ||
| 1025 | values[11] = Fcons (make_number (s.st_dev >> 16), | ||
| 1026 | make_number (s.st_dev & 0xffff)); | ||
| 1027 | else | ||
| 1028 | values[11] = make_number (s.st_dev); | ||
| 1029 | 1000 | ||
| 1030 | return Flist (sizeof(values) / sizeof(values[0]), values); | 1001 | return Flist (sizeof(values) / sizeof(values[0]), values); |
| 1031 | } | 1002 | } |
diff --git a/src/fileio.c b/src/fileio.c index 48dac80a39f..2f7716d5b54 100644 --- a/src/fileio.c +++ b/src/fileio.c | |||
| @@ -5005,7 +5005,7 @@ An argument specifies the modification time value to use | |||
| 5005 | { | 5005 | { |
| 5006 | if (!NILP (time_list)) | 5006 | if (!NILP (time_list)) |
| 5007 | { | 5007 | { |
| 5008 | current_buffer->modtime = cons_to_long (time_list); | 5008 | CONS_TO_INTEGER (time_list, time_t, current_buffer->modtime); |
| 5009 | current_buffer->modtime_size = -1; | 5009 | current_buffer->modtime_size = -1; |
| 5010 | } | 5010 | } |
| 5011 | else | 5011 | else |
diff --git a/src/font.c b/src/font.c index 398198324a4..326c9d80e44 100644 --- a/src/font.c +++ b/src/font.c | |||
| @@ -4388,16 +4388,8 @@ where | |||
| 4388 | for (i = 0; i < 255; i++) | 4388 | for (i = 0; i < 255; i++) |
| 4389 | if (variations[i]) | 4389 | if (variations[i]) |
| 4390 | { | 4390 | { |
| 4391 | Lisp_Object code; | ||
| 4392 | int vs = (i < 16 ? 0xFE00 + i : 0xE0100 + (i - 16)); | 4391 | int vs = (i < 16 ? 0xFE00 + i : 0xE0100 + (i - 16)); |
| 4393 | /* Stops GCC whining about limited range of data type. */ | 4392 | Lisp_Object code = INTEGER_TO_CONS (variations[i]); |
| 4394 | EMACS_INT var = variations[i]; | ||
| 4395 | |||
| 4396 | if (var > MOST_POSITIVE_FIXNUM) | ||
| 4397 | code = Fcons (make_number ((variations[i]) >> 16), | ||
| 4398 | make_number ((variations[i]) & 0xFFFF)); | ||
| 4399 | else | ||
| 4400 | code = make_number (variations[i]); | ||
| 4401 | val = Fcons (Fcons (make_number (vs), code), val); | 4393 | val = Fcons (Fcons (make_number (vs), code), val); |
| 4402 | } | 4394 | } |
| 4403 | return val; | 4395 | return val; |
diff --git a/src/fontset.c b/src/fontset.c index 46637b53b3e..fec3c56b036 100644 --- a/src/fontset.c +++ b/src/fontset.c | |||
| @@ -1859,17 +1859,11 @@ DEFUN ("internal-char-font", Finternal_char_font, Sinternal_char_font, 1, 2, 0, | |||
| 1859 | { | 1859 | { |
| 1860 | unsigned code = face->font->driver->encode_char (face->font, c); | 1860 | unsigned code = face->font->driver->encode_char (face->font, c); |
| 1861 | Lisp_Object font_object; | 1861 | Lisp_Object font_object; |
| 1862 | /* Assignment to EMACS_INT stops GCC whining about limited range | ||
| 1863 | of data type. */ | ||
| 1864 | EMACS_INT cod = code; | ||
| 1865 | 1862 | ||
| 1866 | if (code == FONT_INVALID_CODE) | 1863 | if (code == FONT_INVALID_CODE) |
| 1867 | return Qnil; | 1864 | return Qnil; |
| 1868 | XSETFONT (font_object, face->font); | 1865 | XSETFONT (font_object, face->font); |
| 1869 | if (cod <= MOST_POSITIVE_FIXNUM) | 1866 | return Fcons (font_object, INTEGER_TO_CONS (code)); |
| 1870 | return Fcons (font_object, make_number (code)); | ||
| 1871 | return Fcons (font_object, Fcons (make_number (code >> 16), | ||
| 1872 | make_number (code & 0xFFFF))); | ||
| 1873 | } | 1867 | } |
| 1874 | return Qnil; | 1868 | return Qnil; |
| 1875 | } | 1869 | } |
diff --git a/src/lisp.h b/src/lisp.h index e694bbcc58e..1defda151ae 100644 --- a/src/lisp.h +++ b/src/lisp.h | |||
| @@ -2405,9 +2405,33 @@ EXFUN (Fadd1, 1); | |||
| 2405 | EXFUN (Fsub1, 1); | 2405 | EXFUN (Fsub1, 1); |
| 2406 | EXFUN (Fmake_variable_buffer_local, 1); | 2406 | EXFUN (Fmake_variable_buffer_local, 1); |
| 2407 | 2407 | ||
| 2408 | /* Convert the integer I to an Emacs representation, either the integer | ||
| 2409 | itself, or a cons of two integers, or if all else fails a float. | ||
| 2410 | The float might lose information; this happens only in extreme cases | ||
| 2411 | such as 32-bit EMACS_INT and 64-bit time_t with outlandish time values, | ||
| 2412 | and these aren't worth complicating the interface. | ||
| 2413 | |||
| 2414 | I should not have side effects. */ | ||
| 2415 | #define INTEGER_TO_CONS(i) \ | ||
| 2416 | (! FIXNUM_OVERFLOW_P (i) \ | ||
| 2417 | ? make_number (i) \ | ||
| 2418 | : ! ((FIXNUM_OVERFLOW_P (INTMAX_MIN >> 16) \ | ||
| 2419 | || FIXNUM_OVERFLOW_P (UINTMAX_MAX >> 16)) \ | ||
| 2420 | && FIXNUM_OVERFLOW_P ((i) >> 16)) \ | ||
| 2421 | ? Fcons (make_number ((i) >> 16), make_number ((i) & 0xffff)) \ | ||
| 2422 | : make_float (i)) | ||
| 2423 | |||
| 2424 | /* Convert the Emacs representation CONS back to an integer of type | ||
| 2425 | TYPE, storing the result the variable VAR. Signal an error if CONS | ||
| 2426 | is not a valid representation or is out of range for TYPE. */ | ||
| 2427 | #define CONS_TO_INTEGER(cons, type, var) \ | ||
| 2428 | (TYPE_SIGNED (type) \ | ||
| 2429 | ? ((var) = cons_to_signed (cons, TYPE_MINIMUM (type), TYPE_MAXIMUM (type))) \ | ||
| 2430 | : ((var) = cons_to_unsigned (cons, TYPE_MAXIMUM (type)))) | ||
| 2431 | extern intmax_t cons_to_signed (Lisp_Object, intmax_t, intmax_t); | ||
| 2432 | extern uintmax_t cons_to_unsigned (Lisp_Object, uintmax_t); | ||
| 2433 | |||
| 2408 | extern struct Lisp_Symbol *indirect_variable (struct Lisp_Symbol *); | 2434 | extern struct Lisp_Symbol *indirect_variable (struct Lisp_Symbol *); |
| 2409 | extern Lisp_Object long_to_cons (unsigned long); | ||
| 2410 | extern unsigned long cons_to_long (Lisp_Object); | ||
| 2411 | extern void args_out_of_range (Lisp_Object, Lisp_Object) NO_RETURN; | 2435 | extern void args_out_of_range (Lisp_Object, Lisp_Object) NO_RETURN; |
| 2412 | extern void args_out_of_range_3 (Lisp_Object, Lisp_Object, | 2436 | extern void args_out_of_range_3 (Lisp_Object, Lisp_Object, |
| 2413 | Lisp_Object) NO_RETURN; | 2437 | Lisp_Object) NO_RETURN; |
diff --git a/src/undo.c b/src/undo.c index 142960545a7..e7e9ae5632e 100644 --- a/src/undo.c +++ b/src/undo.c | |||
| @@ -212,7 +212,6 @@ record_change (EMACS_INT beg, EMACS_INT length) | |||
| 212 | void | 212 | void |
| 213 | record_first_change (void) | 213 | record_first_change (void) |
| 214 | { | 214 | { |
| 215 | Lisp_Object high, low; | ||
| 216 | struct buffer *base_buffer = current_buffer; | 215 | struct buffer *base_buffer = current_buffer; |
| 217 | 216 | ||
| 218 | if (EQ (BVAR (current_buffer, undo_list), Qt)) | 217 | if (EQ (BVAR (current_buffer, undo_list), Qt)) |
| @@ -225,9 +224,9 @@ record_first_change (void) | |||
| 225 | if (base_buffer->base_buffer) | 224 | if (base_buffer->base_buffer) |
| 226 | base_buffer = base_buffer->base_buffer; | 225 | base_buffer = base_buffer->base_buffer; |
| 227 | 226 | ||
| 228 | XSETFASTINT (high, (base_buffer->modtime >> 16) & 0xffff); | 227 | BVAR (current_buffer, undo_list) = |
| 229 | XSETFASTINT (low, base_buffer->modtime & 0xffff); | 228 | Fcons (Fcons (Qt, INTEGER_TO_CONS (base_buffer->modtime)), |
| 230 | BVAR (current_buffer, undo_list) = Fcons (Fcons (Qt, Fcons (high, low)), BVAR (current_buffer, undo_list)); | 229 | BVAR (current_buffer, undo_list)); |
| 231 | } | 230 | } |
| 232 | 231 | ||
| 233 | /* Record a change in property PROP (whose old value was VAL) | 232 | /* Record a change in property PROP (whose old value was VAL) |
| @@ -499,13 +498,9 @@ Return what remains of the list. */) | |||
| 499 | if (EQ (car, Qt)) | 498 | if (EQ (car, Qt)) |
| 500 | { | 499 | { |
| 501 | /* Element (t high . low) records previous modtime. */ | 500 | /* Element (t high . low) records previous modtime. */ |
| 502 | Lisp_Object high, low; | ||
| 503 | time_t mod_time; | ||
| 504 | struct buffer *base_buffer = current_buffer; | 501 | struct buffer *base_buffer = current_buffer; |
| 505 | 502 | time_t mod_time; | |
| 506 | high = Fcar (cdr); | 503 | CONS_TO_INTEGER (cdr, time_t, mod_time); |
| 507 | low = Fcdr (cdr); | ||
| 508 | mod_time = (XFASTINT (high) << 16) + XFASTINT (low); | ||
| 509 | 504 | ||
| 510 | if (current_buffer->base_buffer) | 505 | if (current_buffer->base_buffer) |
| 511 | base_buffer = current_buffer->base_buffer; | 506 | base_buffer = current_buffer->base_buffer; |
diff --git a/src/xfns.c b/src/xfns.c index f3dc493ff85..1b425f602d9 100644 --- a/src/xfns.c +++ b/src/xfns.c | |||
| @@ -4295,18 +4295,9 @@ no value of TYPE (always string in the MS Windows case). */) | |||
| 4295 | 4295 | ||
| 4296 | if (! NILP (source)) | 4296 | if (! NILP (source)) |
| 4297 | { | 4297 | { |
| 4298 | if (NUMBERP (source)) | 4298 | CONS_TO_INTEGER (source, Window, target_window); |
| 4299 | { | 4299 | if (! target_window) |
| 4300 | if (FLOATP (source)) | 4300 | target_window = FRAME_X_DISPLAY_INFO (f)->root_window; |
| 4301 | target_window = (Window) XFLOAT (source); | ||
| 4302 | else | ||
| 4303 | target_window = XFASTINT (source); | ||
| 4304 | |||
| 4305 | if (target_window == 0) | ||
| 4306 | target_window = FRAME_X_DISPLAY_INFO (f)->root_window; | ||
| 4307 | } | ||
| 4308 | else if (CONSP (source)) | ||
| 4309 | target_window = cons_to_long (source); | ||
| 4310 | } | 4301 | } |
| 4311 | 4302 | ||
| 4312 | BLOCK_INPUT; | 4303 | BLOCK_INPUT; |
diff --git a/src/xselect.c b/src/xselect.c index ca2b1812a61..7545a44b1bc 100644 --- a/src/xselect.c +++ b/src/xselect.c | |||
| @@ -335,7 +335,7 @@ x_own_selection (Lisp_Object selection_name, Lisp_Object selection_value, | |||
| 335 | Lisp_Object prev_value; | 335 | Lisp_Object prev_value; |
| 336 | 336 | ||
| 337 | selection_data = list4 (selection_name, selection_value, | 337 | selection_data = list4 (selection_name, selection_value, |
| 338 | long_to_cons (timestamp), frame); | 338 | INTEGER_TO_CONS (timestamp), frame); |
| 339 | prev_value = LOCAL_SELECTION (selection_name, dpyinfo); | 339 | prev_value = LOCAL_SELECTION (selection_name, dpyinfo); |
| 340 | 340 | ||
| 341 | dpyinfo->terminal->Vselection_alist | 341 | dpyinfo->terminal->Vselection_alist |
| @@ -419,7 +419,7 @@ x_get_local_selection (Lisp_Object selection_symbol, Lisp_Object target_type, | |||
| 419 | || INTEGERP (check) | 419 | || INTEGERP (check) |
| 420 | || NILP (value)) | 420 | || NILP (value)) |
| 421 | return value; | 421 | return value; |
| 422 | /* Check for a value that cons_to_long could handle. */ | 422 | /* Check for a value that CONS_TO_INTEGER could handle. */ |
| 423 | else if (CONSP (check) | 423 | else if (CONSP (check) |
| 424 | && INTEGERP (XCAR (check)) | 424 | && INTEGERP (XCAR (check)) |
| 425 | && (INTEGERP (XCDR (check)) | 425 | && (INTEGERP (XCDR (check)) |
| @@ -782,8 +782,8 @@ x_handle_selection_request (struct input_event *event) | |||
| 782 | if (NILP (local_selection_data)) goto DONE; | 782 | if (NILP (local_selection_data)) goto DONE; |
| 783 | 783 | ||
| 784 | /* Decline requests issued prior to our acquiring the selection. */ | 784 | /* Decline requests issued prior to our acquiring the selection. */ |
| 785 | local_selection_time | 785 | CONS_TO_INTEGER (XCAR (XCDR (XCDR (local_selection_data))), |
| 786 | = (Time) cons_to_long (XCAR (XCDR (XCDR (local_selection_data)))); | 786 | Time, local_selection_time); |
| 787 | if (SELECTION_EVENT_TIME (event) != CurrentTime | 787 | if (SELECTION_EVENT_TIME (event) != CurrentTime |
| 788 | && local_selection_time > SELECTION_EVENT_TIME (event)) | 788 | && local_selection_time > SELECTION_EVENT_TIME (event)) |
| 789 | goto DONE; | 789 | goto DONE; |
| @@ -950,8 +950,8 @@ x_handle_selection_clear (struct input_event *event) | |||
| 950 | /* Well, we already believe that we don't own it, so that's just fine. */ | 950 | /* Well, we already believe that we don't own it, so that's just fine. */ |
| 951 | if (NILP (local_selection_data)) return; | 951 | if (NILP (local_selection_data)) return; |
| 952 | 952 | ||
| 953 | local_selection_time = (Time) | 953 | CONS_TO_INTEGER (XCAR (XCDR (XCDR (local_selection_data))), |
| 954 | cons_to_long (XCAR (XCDR (XCDR (local_selection_data)))); | 954 | Time, local_selection_time); |
| 955 | 955 | ||
| 956 | /* We have reasserted the selection since this SelectionClear was | 956 | /* We have reasserted the selection since this SelectionClear was |
| 957 | generated, so we can disregard it. */ | 957 | generated, so we can disregard it. */ |
| @@ -1213,16 +1213,7 @@ x_get_foreign_selection (Lisp_Object selection_symbol, Lisp_Object target_type, | |||
| 1213 | return Qnil; | 1213 | return Qnil; |
| 1214 | 1214 | ||
| 1215 | if (! NILP (time_stamp)) | 1215 | if (! NILP (time_stamp)) |
| 1216 | { | 1216 | CONS_TO_INTEGER (time_stamp, Time, requestor_time); |
| 1217 | if (CONSP (time_stamp)) | ||
| 1218 | requestor_time = (Time) cons_to_long (time_stamp); | ||
| 1219 | else if (INTEGERP (time_stamp)) | ||
| 1220 | requestor_time = (Time) XUINT (time_stamp); | ||
| 1221 | else if (FLOATP (time_stamp)) | ||
| 1222 | requestor_time = (Time) XFLOAT_DATA (time_stamp); | ||
| 1223 | else | ||
| 1224 | error ("TIME_STAMP must be cons or number"); | ||
| 1225 | } | ||
| 1226 | 1217 | ||
| 1227 | BLOCK_INPUT; | 1218 | BLOCK_INPUT; |
| 1228 | 1219 | ||
| @@ -1652,7 +1643,7 @@ selection_data_to_lisp_data (Display *display, const unsigned char *data, | |||
| 1652 | convert it to a cons of integers, 16 bits in each half. | 1643 | convert it to a cons of integers, 16 bits in each half. |
| 1653 | */ | 1644 | */ |
| 1654 | else if (format == 32 && size == sizeof (unsigned int)) | 1645 | else if (format == 32 && size == sizeof (unsigned int)) |
| 1655 | return long_to_cons (((unsigned int *) data) [0]); | 1646 | return INTEGER_TO_CONS (((unsigned int *) data) [0]); |
| 1656 | else if (format == 16 && size == sizeof (unsigned short)) | 1647 | else if (format == 16 && size == sizeof (unsigned short)) |
| 1657 | return make_number ((int) (((unsigned short *) data) [0])); | 1648 | return make_number ((int) (((unsigned short *) data) [0])); |
| 1658 | 1649 | ||
| @@ -1678,7 +1669,7 @@ selection_data_to_lisp_data (Display *display, const unsigned char *data, | |||
| 1678 | for (i = 0; i < size / 4; i++) | 1669 | for (i = 0; i < size / 4; i++) |
| 1679 | { | 1670 | { |
| 1680 | unsigned int j = ((unsigned int *) data) [i]; | 1671 | unsigned int j = ((unsigned int *) data) [i]; |
| 1681 | Faset (v, make_number (i), long_to_cons (j)); | 1672 | Faset (v, make_number (i), INTEGER_TO_CONS (j)); |
| 1682 | } | 1673 | } |
| 1683 | return v; | 1674 | return v; |
| 1684 | } | 1675 | } |
| @@ -1755,7 +1746,7 @@ lisp_data_to_selection_data (Display *display, Lisp_Object obj, | |||
| 1755 | *size_ret = 1; | 1746 | *size_ret = 1; |
| 1756 | *data_ret = (unsigned char *) xmalloc (sizeof (unsigned long) + 1); | 1747 | *data_ret = (unsigned char *) xmalloc (sizeof (unsigned long) + 1); |
| 1757 | (*data_ret) [sizeof (unsigned long)] = 0; | 1748 | (*data_ret) [sizeof (unsigned long)] = 0; |
| 1758 | (*(unsigned long **) data_ret) [0] = cons_to_long (obj); | 1749 | (*(unsigned long **) data_ret) [0] = cons_to_unsigned (obj, ULONG_MAX); |
| 1759 | if (NILP (type)) type = QINTEGER; | 1750 | if (NILP (type)) type = QINTEGER; |
| 1760 | } | 1751 | } |
| 1761 | else if (VECTORP (obj)) | 1752 | else if (VECTORP (obj)) |
| @@ -1803,11 +1794,11 @@ lisp_data_to_selection_data (Display *display, Lisp_Object obj, | |||
| 1803 | *data_ret = (unsigned char *) xmalloc (*size_ret * data_size); | 1794 | *data_ret = (unsigned char *) xmalloc (*size_ret * data_size); |
| 1804 | for (i = 0; i < *size_ret; i++) | 1795 | for (i = 0; i < *size_ret; i++) |
| 1805 | if (*format_ret == 32) | 1796 | if (*format_ret == 32) |
| 1806 | (*((unsigned long **) data_ret)) [i] | 1797 | (*((unsigned long **) data_ret)) [i] = |
| 1807 | = cons_to_long (XVECTOR (obj)->contents [i]); | 1798 | cons_to_unsigned (XVECTOR (obj)->contents [i], ULONG_MAX); |
| 1808 | else | 1799 | else |
| 1809 | (*((unsigned short **) data_ret)) [i] | 1800 | (*((unsigned short **) data_ret)) [i] = |
| 1810 | = (unsigned short) cons_to_long (XVECTOR (obj)->contents [i]); | 1801 | cons_to_unsigned (XVECTOR (obj)->contents [i], USHRT_MAX); |
| 1811 | } | 1802 | } |
| 1812 | } | 1803 | } |
| 1813 | else | 1804 | else |
| @@ -2025,8 +2016,10 @@ frame's display, or the first available X display. */) | |||
| 2025 | selection_atom = symbol_to_x_atom (dpyinfo, selection); | 2016 | selection_atom = symbol_to_x_atom (dpyinfo, selection); |
| 2026 | 2017 | ||
| 2027 | BLOCK_INPUT; | 2018 | BLOCK_INPUT; |
| 2028 | timestamp = (NILP (time_object) ? last_event_timestamp | 2019 | if (NILP (time_object)) |
| 2029 | : cons_to_long (time_object)); | 2020 | timestamp = last_event_timestamp; |
| 2021 | else | ||
| 2022 | CONS_TO_INTEGER (time_object, Time, timestamp); | ||
| 2030 | XSetSelectionOwner (dpyinfo->display, selection_atom, None, timestamp); | 2023 | XSetSelectionOwner (dpyinfo->display, selection_atom, None, timestamp); |
| 2031 | UNBLOCK_INPUT; | 2024 | UNBLOCK_INPUT; |
| 2032 | 2025 | ||
| @@ -2232,12 +2225,8 @@ x_fill_property_data (Display *dpy, Lisp_Object data, void *ret, int format) | |||
| 2232 | { | 2225 | { |
| 2233 | Lisp_Object o = XCAR (iter); | 2226 | Lisp_Object o = XCAR (iter); |
| 2234 | 2227 | ||
| 2235 | if (INTEGERP (o)) | 2228 | if (INTEGERP (o) || FLOATP (o) || CONSP (o)) |
| 2236 | val = (long) XFASTINT (o); | 2229 | val = cons_to_signed (o, LONG_MIN, LONG_MAX); |
| 2237 | else if (FLOATP (o)) | ||
| 2238 | val = (long) XFLOAT_DATA (o); | ||
| 2239 | else if (CONSP (o)) | ||
| 2240 | val = (long) cons_to_long (o); | ||
| 2241 | else if (STRINGP (o)) | 2230 | else if (STRINGP (o)) |
| 2242 | { | 2231 | { |
| 2243 | BLOCK_INPUT; | 2232 | BLOCK_INPUT; |
| @@ -2248,9 +2237,19 @@ x_fill_property_data (Display *dpy, Lisp_Object data, void *ret, int format) | |||
| 2248 | error ("Wrong type, must be string, number or cons"); | 2237 | error ("Wrong type, must be string, number or cons"); |
| 2249 | 2238 | ||
| 2250 | if (format == 8) | 2239 | if (format == 8) |
| 2251 | *d08++ = (char) val; | 2240 | { |
| 2241 | if (CHAR_MIN <= val && val <= CHAR_MAX) | ||
| 2242 | *d08++ = val; | ||
| 2243 | else | ||
| 2244 | error ("Out of 'char' range"); | ||
| 2245 | } | ||
| 2252 | else if (format == 16) | 2246 | else if (format == 16) |
| 2253 | *d16++ = (short) val; | 2247 | { |
| 2248 | if (SHRT_MIN <= val && val <= SHRT_MAX) | ||
| 2249 | *d16++ = val; | ||
| 2250 | else | ||
| 2251 | error ("Out of 'short' range"); | ||
| 2252 | } | ||
| 2254 | else | 2253 | else |
| 2255 | *d32++ = val; | 2254 | *d32++ = val; |
| 2256 | } | 2255 | } |
| @@ -2334,14 +2333,7 @@ If the value is 0 or the atom is not known, return the empty string. */) | |||
| 2334 | Atom atom; | 2333 | Atom atom; |
| 2335 | int had_errors; | 2334 | int had_errors; |
| 2336 | 2335 | ||
| 2337 | if (INTEGERP (value)) | 2336 | CONS_TO_INTEGER (value, Atom, atom); |
| 2338 | atom = (Atom) XUINT (value); | ||
| 2339 | else if (FLOATP (value)) | ||
| 2340 | atom = (Atom) XFLOAT_DATA (value); | ||
| 2341 | else if (CONSP (value)) | ||
| 2342 | atom = (Atom) cons_to_long (value); | ||
| 2343 | else | ||
| 2344 | error ("Wrong type, value must be number or cons"); | ||
| 2345 | 2337 | ||
| 2346 | BLOCK_INPUT; | 2338 | BLOCK_INPUT; |
| 2347 | x_catch_errors (dpy); | 2339 | x_catch_errors (dpy); |
| @@ -2531,17 +2523,8 @@ x_send_client_event (Lisp_Object display, Lisp_Object dest, Lisp_Object from, At | |||
| 2531 | else | 2523 | else |
| 2532 | error ("DEST as a string must be one of PointerWindow or InputFocus"); | 2524 | error ("DEST as a string must be one of PointerWindow or InputFocus"); |
| 2533 | } | 2525 | } |
| 2534 | else if (INTEGERP (dest)) | 2526 | else if (INTEGERP (dest) || FLOATP (dest) || CONSP (dest)) |
| 2535 | wdest = (Window) XFASTINT (dest); | 2527 | CONS_TO_INTEGER (dest, Window, wdest); |
| 2536 | else if (FLOATP (dest)) | ||
| 2537 | wdest = (Window) XFLOAT_DATA (dest); | ||
| 2538 | else if (CONSP (dest)) | ||
| 2539 | { | ||
| 2540 | if (! NUMBERP (XCAR (dest)) || ! NUMBERP (XCDR (dest))) | ||
| 2541 | error ("Both car and cdr for DEST must be numbers"); | ||
| 2542 | else | ||
| 2543 | wdest = (Window) cons_to_long (dest); | ||
| 2544 | } | ||
| 2545 | else | 2528 | else |
| 2546 | error ("DEST must be a frame, nil, string, number or cons"); | 2529 | error ("DEST must be a frame, nil, string, number or cons"); |
| 2547 | 2530 | ||