From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Paul Eggert Newsgroups: gmane.emacs.bugs Subject: bug#8794: (c) fix the cons<->int conversions Date: Fri, 03 Jun 2011 12:30:03 -0700 Organization: UCLA Computer Science Department Message-ID: <4DE9363B.7090504@cs.ucla.edu> References: <4DE89EB8.9020202@cs.ucla.edu> NNTP-Posting-Host: lo.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit X-Trace: dough.gmane.org 1307129847 22044 80.91.229.12 (3 Jun 2011 19:37:27 GMT) X-Complaints-To: usenet@dough.gmane.org NNTP-Posting-Date: Fri, 3 Jun 2011 19:37:27 +0000 (UTC) Cc: 8794@debbugs.gnu.org To: Stefan Monnier Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Fri Jun 03 21:37:22 2011 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([140.186.70.17]) by lo.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1QSaBN-000717-SE for geb-bug-gnu-emacs@m.gmane.org; Fri, 03 Jun 2011 21:37:22 +0200 Original-Received: from localhost ([::1]:45054 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QSaBM-0005c9-Ib for geb-bug-gnu-emacs@m.gmane.org; Fri, 03 Jun 2011 15:37:20 -0400 Original-Received: from eggs.gnu.org ([140.186.70.92]:37312) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QSa5L-00049U-QI for bug-gnu-emacs@gnu.org; Fri, 03 Jun 2011 15:31:10 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1QSa5G-0007QA-RW for bug-gnu-emacs@gnu.org; Fri, 03 Jun 2011 15:31:07 -0400 Original-Received: from debbugs.gnu.org ([140.186.70.43]:47445) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QSa5G-0007Py-Jb for bug-gnu-emacs@gnu.org; Fri, 03 Jun 2011 15:31:02 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.69) (envelope-from ) id 1QSa5F-00030B-TA; Fri, 03 Jun 2011 15:31:01 -0400 X-Loop: help-debbugs@gnu.org Resent-From: Paul Eggert Original-Sender: debbugs-submit-bounces@debbugs.gnu.org Resent-To: owner@debbugs.gnu.org Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Fri, 03 Jun 2011 19:31:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 8794 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: Original-Received: via spool by 8794-submit@debbugs.gnu.org id=B8794.130712941511480 (code B ref 8794); Fri, 03 Jun 2011 19:31:01 +0000 Original-Received: (at 8794) by debbugs.gnu.org; 3 Jun 2011 19:30:15 +0000 Original-Received: from localhost ([127.0.0.1] helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1QSa4T-0002z6-TR for submit@debbugs.gnu.org; Fri, 03 Jun 2011 15:30:15 -0400 Original-Received: from smtp.cs.ucla.edu ([131.179.128.62]) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1QSa4R-0002yt-40 for 8794@debbugs.gnu.org; Fri, 03 Jun 2011 15:30:13 -0400 Original-Received: from localhost (localhost.localdomain [127.0.0.1]) by smtp.cs.ucla.edu (Postfix) with ESMTP id 6B74739E80F8; Fri, 3 Jun 2011 12:30:05 -0700 (PDT) X-Virus-Scanned: amavisd-new at smtp.cs.ucla.edu Original-Received: from smtp.cs.ucla.edu ([127.0.0.1]) by localhost (smtp.cs.ucla.edu [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id MjuL-x4+4Dsv; Fri, 3 Jun 2011 12:30:03 -0700 (PDT) Original-Received: from [131.179.64.200] (Penguin.CS.UCLA.EDU [131.179.64.200]) by smtp.cs.ucla.edu (Postfix) with ESMTPSA id 9996B39E80F7; Fri, 3 Jun 2011 12:30:03 -0700 (PDT) User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.17) Gecko/20110428 Fedora/3.1.10-1.fc14 Thunderbird/3.1.10 In-Reply-To: X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.11 Precedence: list Resent-Date: Fri, 03 Jun 2011 15:31:01 -0400 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 3) X-Received-From: 140.186.70.43 X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Original-Sender: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.bugs:46931 Archived-At: === modified file 'doc/lispref/ChangeLog' --- doc/lispref/ChangeLog 2011-06-03 18:49:33 +0000 +++ doc/lispref/ChangeLog 2011-06-03 19:04:41 +0000 @@ -2,6 +2,8 @@ Document wide integers better. * files.texi (File Attributes): Document ino_t values better. + ino_t values no longer map to anything larger than a single cons. + * numbers.texi (Integer Basics, Integer Basics, Arithmetic Operations): (Bitwise Operations): * objects.texi (Integer Type): Integers are typically 62 bits now. === modified file 'doc/lispref/files.texi' --- doc/lispref/files.texi 2011-06-03 18:49:33 +0000 +++ doc/lispref/files.texi 2011-06-03 19:04:41 +0000 @@ -1237,13 +1237,9 @@ @item The file's inode number. If possible, this is an integer. If the inode number @math{N} is too large to be represented as an integer in -Emacs Lisp, but @math{N / 2^16} is representable, then the value has -the form @code{(@var{high} . @var{low})}, where @var{high} holds the -high bits (i.e., excluding the low-order bits) and @var{low} the low -16 bits. If the inode number is even larger, the value is of the form -@code{(@var{high} @var{middle} . @var{low})}, where @code{high} holds -the high bits, @var{middle} the next 24 bits, and @var{low} the low -16 bits. +Emacs Lisp, then the value has the form @code{(@var{high} +. @var{low})}, where @var{high} holds the high bits (i.e., all but the +low 16 bits) and @var{low} the low 16 bits. @item The filesystem number of the device that the file is on. Depending on === modified file 'src/ChangeLog' --- src/ChangeLog 2011-06-03 18:42:59 +0000 +++ src/ChangeLog 2011-06-03 19:02:25 +0000 @@ -1,5 +1,32 @@ 2011-06-03 Paul Eggert + Check for overflow when converting integer to cons and back. + * charset.c (Fdefine_charset_internal, Fdecode_char): + Use cons_to_unsigned to catch overflow. + (Fencode_char): Use INTEGER_TO_CONS. + * composite.h (LGLYPH_CODE): Use cons_to_unsigned. + (LGLYPH_SET_CODE): Use INTEGER_TO_CONS. + * data.c (long_to_cons, cons_to_long): Remove. + (cons_to_unsigned, cons_to_signed): New functions. + These signal an error for invalid or out-of-range values. + * dired.c (Ffile_attributes): Use INTEGER_TO_CONS. + * fileio.c (Fset_visited_file_modtime): Use CONS_TO_INTEGER. + * font.c (Ffont_variation_glyphs): + * fontset.c (Finternal_char_font): Use INTEGER_TO_CONS. + * lisp.h (INTEGER_TO_CONS, CONS_TO_INTEGER): New macros. + (cons_to_signed, cons_to_unsigned): New decls. + (long_to_cons, cons_to_long): Remove decls. + * undo.c (record_first_change): Use INTEGER_TO_CONS. + (Fprimitive_undo): Use CONS_TO_INTEGER. + * xfns.c (Fx_window_property): Likewise. + * xselect.c (x_own_selection, selection_data_to_lisp_data): + Use INTEGER_TO_CONS. + (x_handle_selection_request, x_handle_selection_clear) + (x_get_foreign_selection, Fx_disown_selection_internal) + (Fx_get_atom_name, x_send_client_event): Use CONS_TO_INTEGER. + (lisp_data_to_selection_data): Use cons_to_unsigned. + (x_fill_property_data): Use cons_to_signed. Report values out of range. + Fix doc for machines with wider system times such as time_t. On such machines, it's now safe to assume that EMACS_INT is as wide as the system times, so that shifting right by 16 will === modified file 'src/charset.c' --- src/charset.c 2011-06-03 18:11:17 +0000 +++ src/charset.c 2011-06-03 19:02:25 +0000 @@ -932,17 +932,8 @@ val = args[charset_arg_min_code]; if (! NILP (val)) { - unsigned code; + unsigned code = cons_to_unsigned (val, UINT_MAX); - if (INTEGERP (val)) - code = XINT (val); - else - { - CHECK_CONS (val); - CHECK_NUMBER_CAR (val); - CHECK_NUMBER_CDR (val); - code = (XINT (XCAR (val)) << 16) | (XINT (XCDR (val))); - } if (code < charset.min_code || code > charset.max_code) args_out_of_range_3 (make_number (charset.min_code), @@ -954,17 +945,8 @@ val = args[charset_arg_max_code]; if (! NILP (val)) { - unsigned code; + unsigned code = cons_to_unsigned (val, UINT_MAX); - if (INTEGERP (val)) - code = XINT (val); - else - { - CHECK_CONS (val); - CHECK_NUMBER_CAR (val); - CHECK_NUMBER_CDR (val); - code = (XINT (XCAR (val)) << 16) | (XINT (XCDR (val))); - } if (code < charset.min_code || code > charset.max_code) args_out_of_range_3 (make_number (charset.min_code), @@ -1865,17 +1847,7 @@ struct charset *charsetp; CHECK_CHARSET_GET_ID (charset, id); - if (CONSP (code_point)) - { - CHECK_NATNUM_CAR (code_point); - CHECK_NATNUM_CDR (code_point); - code = (XINT (XCAR (code_point)) << 16) | (XINT (XCDR (code_point))); - } - else - { - CHECK_NATNUM (code_point); - code = XINT (code_point); - } + code = cons_to_unsigned (code_point, UINT_MAX); charsetp = CHARSET_FROM_ID (id); c = DECODE_CHAR (charsetp, code); return (c >= 0 ? make_number (c) : Qnil); @@ -1900,9 +1872,7 @@ code = ENCODE_CHAR (charsetp, XINT (ch)); if (code == CHARSET_INVALID_CODE (charsetp)) return Qnil; - if (code > 0x7FFFFFF) - return Fcons (make_number (code >> 16), make_number (code & 0xFFFF)); - return make_number (code); + return INTEGER_TO_CONS (code); } === modified file 'src/composite.h' --- src/composite.h 2011-05-31 06:05:00 +0000 +++ src/composite.h 2011-06-03 19:02:25 +0000 @@ -265,10 +265,7 @@ #define LGLYPH_CODE(g) \ (NILP (AREF ((g), LGLYPH_IX_CODE)) \ ? FONT_INVALID_CODE \ - : CONSP (AREF ((g), LGLYPH_IX_CODE)) \ - ? ((XFASTINT (XCAR (AREF ((g), LGLYPH_IX_CODE))) << 16) \ - | (XFASTINT (XCDR (AREF ((g), LGLYPH_IX_CODE))))) \ - : XFASTINT (AREF ((g), LGLYPH_IX_CODE))) + : cons_to_unsigned (AREF (g, LGLYPH_IX_CODE), TYPE_MAXIMUM (unsigned))) #define LGLYPH_WIDTH(g) XINT (AREF ((g), LGLYPH_IX_WIDTH)) #define LGLYPH_LBEARING(g) XINT (AREF ((g), LGLYPH_IX_LBEARING)) #define LGLYPH_RBEARING(g) XINT (AREF ((g), LGLYPH_IX_RBEARING)) @@ -280,15 +277,8 @@ #define LGLYPH_SET_CHAR(g, val) ASET ((g), LGLYPH_IX_CHAR, make_number (val)) /* Callers must assure that VAL is not negative! */ #define LGLYPH_SET_CODE(g, val) \ - do { \ - if (val == FONT_INVALID_CODE) \ - ASET ((g), LGLYPH_IX_CODE, Qnil); \ - else if ((EMACS_INT)val > MOST_POSITIVE_FIXNUM) \ - ASET ((g), LGLYPH_IX_CODE, Fcons (make_number ((val) >> 16), \ - make_number ((val) & 0xFFFF))); \ - else \ - ASET ((g), LGLYPH_IX_CODE, make_number (val)); \ - } while (0) + ASET (g, LGLYPH_IX_CODE, \ + val == FONT_INVALID_CODE ? Qnil : INTEGER_TO_CONS (val)) #define LGLYPH_SET_WIDTH(g, val) ASET ((g), LGLYPH_IX_WIDTH, make_number (val)) #define LGLYPH_SET_LBEARING(g, val) ASET ((g), LGLYPH_IX_LBEARING, make_number (val)) === modified file 'src/data.c' --- src/data.c 2011-06-02 06:17:35 +0000 +++ src/data.c 2011-06-03 19:02:25 +0000 @@ -2324,33 +2324,89 @@ return Qnil; } -/* Convert between long values and pairs of Lisp integers. - Note that long_to_cons returns a single Lisp integer - when the value fits in one. */ +/* Convert the cons-of-integers, integer, or float value C to an + unsigned value with maximum value MAX. Signal an error if C does not + have a valid format or is out of range. */ +uintmax_t +cons_to_unsigned (Lisp_Object c, uintmax_t max) +{ + int valid = 0; + uintmax_t val IF_LINT (= 0); + if (INTEGERP (c)) + { + valid = 0 <= XINT (c); + val = XINT (c); + } + else if (FLOATP (c)) + { + double d = XFLOAT_DATA (c); + if (0 <= d + && d < (max == UINTMAX_MAX ? (double) UINTMAX_MAX + 1 : max + 1)) + { + val = d; + valid = 1; + } + } + else if (CONSP (c)) + { + Lisp_Object top = XCAR (c); + Lisp_Object bot = XCDR (c); + if (CONSP (bot)) + bot = XCAR (bot); + if (NATNUMP (top) && XFASTINT (top) <= UINTMAX_MAX >> 16 && NATNUMP (bot)) + { + uintmax_t utop = XFASTINT (top); + val = (utop << 16) | XFASTINT (bot); + valid = 1; + } + } -Lisp_Object -long_to_cons (long unsigned int i) -{ - unsigned long top = i >> 16; - unsigned int bot = i & 0xFFFF; - if (top == 0) - return make_number (bot); - if (top == (unsigned long)-1 >> 16) - return Fcons (make_number (-1), make_number (bot)); - return Fcons (make_number (top), make_number (bot)); + if (! (valid && val <= max)) + error ("Not an in-range integer, float, or cons of integers"); + return val; } -unsigned long -cons_to_long (Lisp_Object c) +/* Convert the cons-of-integers, integer, or float value C to a signed + value with extrema MIN and MAX. Signal an error if C does not have + a valid format or is out of range. */ +intmax_t +cons_to_signed (Lisp_Object c, intmax_t min, intmax_t max) { - Lisp_Object top, bot; + int valid = 0; + intmax_t val IF_LINT (= 0); if (INTEGERP (c)) - return XINT (c); - top = XCAR (c); - bot = XCDR (c); - if (CONSP (bot)) - bot = XCAR (bot); - return ((XINT (top) << 16) | XINT (bot)); + { + val = XINT (c); + valid = 1; + } + else if (FLOATP (c)) + { + double d = XFLOAT_DATA (c); + if (min <= d + && d < (max == INTMAX_MAX ? (double) INTMAX_MAX + 1 : max + 1)) + { + val = d; + valid = 1; + } + } + else if (CONSP (c)) + { + Lisp_Object top = XCAR (c); + Lisp_Object bot = XCDR (c); + if (CONSP (bot)) + bot = XCAR (bot); + if (INTEGERP (top) && INTMAX_MIN >> 16 <= XINT (top) + && XINT (top) <= INTMAX_MAX >> 16 && INTEGERP (bot)) + { + intmax_t itop = XINT (top); + val = (itop << 16) | XINT (bot); + valid = 1; + } + } + + if (! (valid && min <= val && val <= max)) + error ("Not an in-range integer, float, or cons of integers"); + return val; } DEFUN ("number-to-string", Fnumber_to_string, Snumber_to_string, 1, 1, 0, === modified file 'src/dired.c' --- src/dired.c 2011-06-03 18:42:59 +0000 +++ src/dired.c 2011-06-03 19:02:25 +0000 @@ -900,12 +900,9 @@ This is a floating point number if the size is too large for an integer. 8. File modes, as a string of ten letters or dashes as in ls -l. 9. t if file's gid would change if file were deleted and recreated. -10. inode number. If inode number is larger than what Emacs integer - can hold, but all but the bottom 16 bits still fits, this is a cons cell - containing two integers: first the high part, then the low 16 bits. - If the inode number is still wider, this is of the form - (HIGH MIDDLE . LOW): first the high bits, then the middle 24 bits, - and finally the low 16 bits. +10. inode number. If it is larger than what the Emacs integer + can hold, this is a cons cell containing two integers: first the + high part, then the low 16 bits. 11. Filesystem device number. If it is larger than what the Emacs integer can hold, this is a cons cell, similar to the inode number. @@ -998,34 +995,8 @@ #else /* file gid will be egid */ values[9] = (s.st_gid != getegid ()) ? Qt : Qnil; #endif /* not BSD4_2 */ - if (!FIXNUM_OVERFLOW_P (s.st_ino)) - /* Keep the most common cases as integers. */ - values[10] = make_number (s.st_ino); - else if (!FIXNUM_OVERFLOW_P (s.st_ino >> 16)) - /* To allow inode numbers larger than VALBITS, separate the bottom - 16 bits. */ - values[10] = Fcons (make_number ((EMACS_INT)(s.st_ino >> 16)), - make_number ((EMACS_INT)(s.st_ino & 0xffff))); - else - { - /* To allow inode numbers beyond what INTEGER_TO_CONS can handle, - separate into 2 24-bit high parts and a 16-bit bottom part. - The code on the next line avoids a compiler warning on - systems where st_ino is 32 bit wide. (bug#766). */ - EMACS_INT high_ino = s.st_ino >> 31 >> 1; - - values[10] = Fcons (make_number (high_ino >> 8), - Fcons (make_number (((high_ino & 0xff) << 16) - + (s.st_ino >> 16 & 0xffff)), - make_number (s.st_ino & 0xffff))); - } - - /* Likewise for device. */ - if (FIXNUM_OVERFLOW_P (s.st_dev)) - values[11] = Fcons (make_number (s.st_dev >> 16), - make_number (s.st_dev & 0xffff)); - else - values[11] = make_number (s.st_dev); + values[10] = INTEGER_TO_CONS (s.st_ino); + values[11] = INTEGER_TO_CONS (s.st_dev); return Flist (sizeof(values) / sizeof(values[0]), values); } === modified file 'src/fileio.c' --- src/fileio.c 2011-06-02 06:23:20 +0000 +++ src/fileio.c 2011-06-03 19:02:25 +0000 @@ -5005,7 +5005,7 @@ { if (!NILP (time_list)) { - current_buffer->modtime = cons_to_long (time_list); + CONS_TO_INTEGER (time_list, time_t, current_buffer->modtime); current_buffer->modtime_size = -1; } else === modified file 'src/font.c' --- src/font.c 2011-05-29 19:04:01 +0000 +++ src/font.c 2011-06-03 19:02:25 +0000 @@ -4388,16 +4388,8 @@ for (i = 0; i < 255; i++) if (variations[i]) { - Lisp_Object code; int vs = (i < 16 ? 0xFE00 + i : 0xE0100 + (i - 16)); - /* Stops GCC whining about limited range of data type. */ - EMACS_INT var = variations[i]; - - if (var > MOST_POSITIVE_FIXNUM) - code = Fcons (make_number ((variations[i]) >> 16), - make_number ((variations[i]) & 0xFFFF)); - else - code = make_number (variations[i]); + Lisp_Object code = INTEGER_TO_CONS (variations[i]); val = Fcons (Fcons (make_number (vs), code), val); } return val; === modified file 'src/fontset.c' --- src/fontset.c 2011-05-28 22:39:39 +0000 +++ src/fontset.c 2011-06-03 19:02:25 +0000 @@ -1859,17 +1859,11 @@ { unsigned code = face->font->driver->encode_char (face->font, c); Lisp_Object font_object; - /* Assignment to EMACS_INT stops GCC whining about limited range - of data type. */ - EMACS_INT cod = code; if (code == FONT_INVALID_CODE) return Qnil; XSETFONT (font_object, face->font); - if (cod <= MOST_POSITIVE_FIXNUM) - return Fcons (font_object, make_number (code)); - return Fcons (font_object, Fcons (make_number (code >> 16), - make_number (code & 0xFFFF))); + return Fcons (font_object, INTEGER_TO_CONS (code)); } return Qnil; } === modified file 'src/lisp.h' --- src/lisp.h 2011-06-03 18:28:20 +0000 +++ src/lisp.h 2011-06-03 19:02:25 +0000 @@ -2405,9 +2405,33 @@ EXFUN (Fsub1, 1); EXFUN (Fmake_variable_buffer_local, 1); +/* Convert the integer I to an Emacs representation, either the integer + itself, or a cons of two integers, or if all else fails a float. + The float might lose information; this happens only in extreme cases + such as 32-bit EMACS_INT and 64-bit time_t with outlandish time values, + and these aren't worth complicating the interface. + + I should not have side effects. */ +#define INTEGER_TO_CONS(i) \ + (! FIXNUM_OVERFLOW_P (i) \ + ? make_number (i) \ + : ! ((FIXNUM_OVERFLOW_P (INTMAX_MIN >> 16) \ + || FIXNUM_OVERFLOW_P (UINTMAX_MAX >> 16)) \ + && FIXNUM_OVERFLOW_P ((i) >> 16)) \ + ? Fcons (make_number ((i) >> 16), make_number ((i) & 0xffff)) \ + : make_float (i)) + +/* Convert the Emacs representation CONS back to an integer of type + TYPE, storing the result the variable VAR. Signal an error if CONS + is not a valid representation or is out of range for TYPE. */ +#define CONS_TO_INTEGER(cons, type, var) \ + (TYPE_SIGNED (type) \ + ? ((var) = cons_to_signed (cons, TYPE_MINIMUM (type), TYPE_MAXIMUM (type))) \ + : ((var) = cons_to_unsigned (cons, TYPE_MAXIMUM (type)))) +extern intmax_t cons_to_signed (Lisp_Object, intmax_t, intmax_t); +extern uintmax_t cons_to_unsigned (Lisp_Object, uintmax_t); + extern struct Lisp_Symbol *indirect_variable (struct Lisp_Symbol *); -extern Lisp_Object long_to_cons (unsigned long); -extern unsigned long cons_to_long (Lisp_Object); extern void args_out_of_range (Lisp_Object, Lisp_Object) NO_RETURN; extern void args_out_of_range_3 (Lisp_Object, Lisp_Object, Lisp_Object) NO_RETURN; === modified file 'src/undo.c' --- src/undo.c 2011-06-02 06:15:15 +0000 +++ src/undo.c 2011-06-03 19:02:25 +0000 @@ -212,7 +212,6 @@ void record_first_change (void) { - Lisp_Object high, low; struct buffer *base_buffer = current_buffer; if (EQ (BVAR (current_buffer, undo_list), Qt)) @@ -225,9 +224,9 @@ if (base_buffer->base_buffer) base_buffer = base_buffer->base_buffer; - XSETFASTINT (high, (base_buffer->modtime >> 16) & 0xffff); - XSETFASTINT (low, base_buffer->modtime & 0xffff); - BVAR (current_buffer, undo_list) = Fcons (Fcons (Qt, Fcons (high, low)), BVAR (current_buffer, undo_list)); + BVAR (current_buffer, undo_list) = + Fcons (Fcons (Qt, INTEGER_TO_CONS (base_buffer->modtime)), + BVAR (current_buffer, undo_list)); } /* Record a change in property PROP (whose old value was VAL) @@ -499,13 +498,9 @@ if (EQ (car, Qt)) { /* Element (t high . low) records previous modtime. */ - Lisp_Object high, low; + struct buffer *base_buffer = current_buffer; time_t mod_time; - struct buffer *base_buffer = current_buffer; - - high = Fcar (cdr); - low = Fcdr (cdr); - mod_time = (XFASTINT (high) << 16) + XFASTINT (low); + CONS_TO_INTEGER (cdr, time_t, mod_time); if (current_buffer->base_buffer) base_buffer = current_buffer->base_buffer; === modified file 'src/xfns.c' --- src/xfns.c 2011-04-19 06:34:43 +0000 +++ src/xfns.c 2011-06-03 19:02:25 +0000 @@ -4295,18 +4295,9 @@ if (! NILP (source)) { - if (NUMBERP (source)) - { - if (FLOATP (source)) - target_window = (Window) XFLOAT (source); - else - target_window = XFASTINT (source); - - if (target_window == 0) - target_window = FRAME_X_DISPLAY_INFO (f)->root_window; - } - else if (CONSP (source)) - target_window = cons_to_long (source); + CONS_TO_INTEGER (source, Window, target_window); + if (! target_window) + target_window = FRAME_X_DISPLAY_INFO (f)->root_window; } BLOCK_INPUT; === modified file 'src/xselect.c' --- src/xselect.c 2011-06-03 18:22:12 +0000 +++ src/xselect.c 2011-06-03 19:02:25 +0000 @@ -335,7 +335,7 @@ Lisp_Object prev_value; selection_data = list4 (selection_name, selection_value, - long_to_cons (timestamp), frame); + INTEGER_TO_CONS (timestamp), frame); prev_value = LOCAL_SELECTION (selection_name, dpyinfo); dpyinfo->terminal->Vselection_alist @@ -419,7 +419,7 @@ || INTEGERP (check) || NILP (value)) return value; - /* Check for a value that cons_to_long could handle. */ + /* Check for a value that CONS_TO_INTEGER could handle. */ else if (CONSP (check) && INTEGERP (XCAR (check)) && (INTEGERP (XCDR (check)) @@ -782,8 +782,8 @@ if (NILP (local_selection_data)) goto DONE; /* Decline requests issued prior to our acquiring the selection. */ - local_selection_time - = (Time) cons_to_long (XCAR (XCDR (XCDR (local_selection_data)))); + CONS_TO_INTEGER (XCAR (XCDR (XCDR (local_selection_data))), + Time, local_selection_time); if (SELECTION_EVENT_TIME (event) != CurrentTime && local_selection_time > SELECTION_EVENT_TIME (event)) goto DONE; @@ -950,8 +950,8 @@ /* Well, we already believe that we don't own it, so that's just fine. */ if (NILP (local_selection_data)) return; - local_selection_time = (Time) - cons_to_long (XCAR (XCDR (XCDR (local_selection_data)))); + CONS_TO_INTEGER (XCAR (XCDR (XCDR (local_selection_data))), + Time, local_selection_time); /* We have reasserted the selection since this SelectionClear was generated, so we can disregard it. */ @@ -1213,16 +1213,7 @@ return Qnil; if (! NILP (time_stamp)) - { - if (CONSP (time_stamp)) - requestor_time = (Time) cons_to_long (time_stamp); - else if (INTEGERP (time_stamp)) - requestor_time = (Time) XUINT (time_stamp); - else if (FLOATP (time_stamp)) - requestor_time = (Time) XFLOAT_DATA (time_stamp); - else - error ("TIME_STAMP must be cons or number"); - } + CONS_TO_INTEGER (time_stamp, Time, requestor_time); BLOCK_INPUT; @@ -1652,7 +1643,7 @@ convert it to a cons of integers, 16 bits in each half. */ else if (format == 32 && size == sizeof (unsigned int)) - return long_to_cons (((unsigned int *) data) [0]); + return INTEGER_TO_CONS (((unsigned int *) data) [0]); else if (format == 16 && size == sizeof (unsigned short)) return make_number ((int) (((unsigned short *) data) [0])); @@ -1678,7 +1669,7 @@ for (i = 0; i < size / 4; i++) { unsigned int j = ((unsigned int *) data) [i]; - Faset (v, make_number (i), long_to_cons (j)); + Faset (v, make_number (i), INTEGER_TO_CONS (j)); } return v; } @@ -1755,7 +1746,7 @@ *size_ret = 1; *data_ret = (unsigned char *) xmalloc (sizeof (unsigned long) + 1); (*data_ret) [sizeof (unsigned long)] = 0; - (*(unsigned long **) data_ret) [0] = cons_to_long (obj); + (*(unsigned long **) data_ret) [0] = cons_to_unsigned (obj, ULONG_MAX); if (NILP (type)) type = QINTEGER; } else if (VECTORP (obj)) @@ -1803,11 +1794,11 @@ *data_ret = (unsigned char *) xmalloc (*size_ret * data_size); for (i = 0; i < *size_ret; i++) if (*format_ret == 32) - (*((unsigned long **) data_ret)) [i] - = cons_to_long (XVECTOR (obj)->contents [i]); + (*((unsigned long **) data_ret)) [i] = + cons_to_unsigned (XVECTOR (obj)->contents [i], ULONG_MAX); else - (*((unsigned short **) data_ret)) [i] - = (unsigned short) cons_to_long (XVECTOR (obj)->contents [i]); + (*((unsigned short **) data_ret)) [i] = + cons_to_unsigned (XVECTOR (obj)->contents [i], USHRT_MAX); } } else @@ -2025,8 +2016,10 @@ selection_atom = symbol_to_x_atom (dpyinfo, selection); BLOCK_INPUT; - timestamp = (NILP (time_object) ? last_event_timestamp - : cons_to_long (time_object)); + if (NILP (time_object)) + timestamp = last_event_timestamp; + else + CONS_TO_INTEGER (time_object, Time, timestamp); XSetSelectionOwner (dpyinfo->display, selection_atom, None, timestamp); UNBLOCK_INPUT; @@ -2232,12 +2225,8 @@ { Lisp_Object o = XCAR (iter); - if (INTEGERP (o)) - val = (long) XFASTINT (o); - else if (FLOATP (o)) - val = (long) XFLOAT_DATA (o); - else if (CONSP (o)) - val = (long) cons_to_long (o); + if (INTEGERP (o) || FLOATP (o) || CONSP (o)) + val = cons_to_signed (o, LONG_MIN, LONG_MAX); else if (STRINGP (o)) { BLOCK_INPUT; @@ -2248,9 +2237,19 @@ error ("Wrong type, must be string, number or cons"); if (format == 8) - *d08++ = (char) val; + { + if (CHAR_MIN <= val && val <= CHAR_MAX) + *d08++ = val; + else + error ("Out of 'char' range"); + } else if (format == 16) - *d16++ = (short) val; + { + if (SHRT_MIN <= val && val <= SHRT_MAX) + *d16++ = val; + else + error ("Out of 'short' range"); + } else *d32++ = val; } @@ -2334,14 +2333,7 @@ Atom atom; int had_errors; - if (INTEGERP (value)) - atom = (Atom) XUINT (value); - else if (FLOATP (value)) - atom = (Atom) XFLOAT_DATA (value); - else if (CONSP (value)) - atom = (Atom) cons_to_long (value); - else - error ("Wrong type, value must be number or cons"); + CONS_TO_INTEGER (value, Atom, atom); BLOCK_INPUT; x_catch_errors (dpy); @@ -2531,17 +2523,8 @@ else error ("DEST as a string must be one of PointerWindow or InputFocus"); } - else if (INTEGERP (dest)) - wdest = (Window) XFASTINT (dest); - else if (FLOATP (dest)) - wdest = (Window) XFLOAT_DATA (dest); - else if (CONSP (dest)) - { - if (! NUMBERP (XCAR (dest)) || ! NUMBERP (XCDR (dest))) - error ("Both car and cdr for DEST must be numbers"); - else - wdest = (Window) cons_to_long (dest); - } + else if (INTEGERP (dest) || FLOATP (dest) || CONSP (dest)) + CONS_TO_INTEGER (dest, Window, wdest); else error ("DEST must be a frame, nil, string, number or cons");