Mercurial > hg > xemacs-beta
diff src/fns.c @ 5307:c096d8051f89
Have NATNUMP give t for positive bignums; check limits appropriately.
src/ChangeLog addition:
2010-11-20 Aidan Kehoe <kehoea@parhasard.net>
* abbrev.c (Fexpand_abbrev):
* alloc.c:
* alloc.c (Fmake_list):
* alloc.c (Fmake_vector):
* alloc.c (Fmake_bit_vector):
* alloc.c (Fmake_byte_code):
* alloc.c (Fmake_string):
* alloc.c (vars_of_alloc):
* bytecode.c (UNUSED):
* bytecode.c (Fbyte_code):
* chartab.c (decode_char_table_range):
* cmds.c (Fself_insert_command):
* data.c (check_integer_range):
* data.c (Fnatnump):
* data.c (Fnonnegativep):
* data.c (Fstring_to_number):
* elhash.c (hash_table_size_validate):
* elhash.c (decode_hash_table_size):
* eval.c (Fbacktrace_frame):
* event-stream.c (lisp_number_to_milliseconds):
* event-stream.c (Faccept_process_output):
* event-stream.c (Frecent_keys):
* event-stream.c (Fdispatch_event):
* events.c (Fmake_event):
* events.c (Fevent_timestamp):
* events.c (Fevent_timestamp_lessp):
* events.h:
* events.h (struct command_builder):
* file-coding.c (gzip_putprop):
* fns.c:
* fns.c (check_sequence_range):
* fns.c (Frandom):
* fns.c (Fnthcdr):
* fns.c (Flast):
* fns.c (Fnbutlast):
* fns.c (Fbutlast):
* fns.c (Fmember):
* fns.c (Ffill):
* fns.c (Freduce):
* fns.c (replace_string_range_1):
* fns.c (Freplace):
* font-mgr.c (Ffc_pattern_get):
* frame-msw.c (msprinter_set_frame_properties):
* glyphs.c (check_valid_xbm_inline):
* indent.c (Fmove_to_column):
* intl-win32.c (mswindows_multibyte_to_unicode_putprop):
* lisp.h:
* lisp.h (ARRAY_DIMENSION_LIMIT):
* lread.c (decode_mode_1):
* mule-ccl.c (ccl_get_compiled_code):
* number.h:
* process-unix.c (unix_open_multicast_group):
* process.c (Fset_process_window_size):
* profile.c (Fstart_profiling):
* unicode.c (Funicode_to_char):
Change NATNUMP to return 1 for positive bignums; changes uses of
it and of CHECK_NATNUM appropriately, usually by checking for an
integer in an appropriate range.
Add array-dimension-limit and use it in #'make-vector,
#'make-string. Add array-total-size-limit, array-rank-limit while
we're at it, for the sake of any Common Lisp-oriented code that
uses these limits.
Rename check_int_range to check_integer_range, have it take
Lisp_Objects (and thus bignums) instead.
Remove bignum_butlast(), just set int_n to an appropriately large
integer if N is a bignum.
Accept bignums in check_sequence_range(), change the functions
that use check_sequence_range() appropriately.
Move the definition of NATNUMP() to number.h; document why it's a
reasonable name, contradicting an old comment.
tests/ChangeLog addition:
2010-11-20 Aidan Kehoe <kehoea@parhasard.net>
* automated/lisp-tests.el:
* automated/lisp-tests.el (featurep):
* automated/lisp-tests.el (wrong-type-argument):
* automated/mule-tests.el (featurep):
Check for args-out-of-range errors instead of wrong-type-argument
errors in various places when code is handed a large bignum
instead of a fixnum.
Also check for the wrong-type-argument errors when giving the same
code a non-integer value.
author | Aidan Kehoe <kehoea@parhasard.net> |
---|---|
date | Sat, 20 Nov 2010 16:49:11 +0000 |
parents | cde1608596d0 |
children | c290121b0c3f 8d29f1c4bb98 |
line wrap: on
line diff
--- a/src/fns.c Wed Nov 17 14:37:26 2010 +0000 +++ b/src/fns.c Sat Nov 20 16:49:11 2010 +0000 @@ -78,13 +78,11 @@ check_sequence_range (Lisp_Object sequence, Lisp_Object start, Lisp_Object end, Lisp_Object length) { - Elemcount starting = XINT (start), ending, len = XINT (length); - - ending = NILP (end) ? XINT (length) : XINT (end); - - if (!(0 <= starting && starting <= ending && ending <= len)) - { - args_out_of_range_3 (sequence, start, make_int (ending)); + Lisp_Object args[] = { Qzero, start, NILP (end) ? length : end, length }; + + if (NILP (Fleq (countof (args), args))) + { + args_out_of_range_3 (sequence, start, end); } } @@ -228,6 +226,13 @@ seed_random (qxe_getpid () + time (NULL)); if (NATNUMP (limit) && !ZEROP (limit)) { +#ifdef HAVE_BIGNUM + if (BIGNUMP (limit)) + { + bignum_random (scratch_bignum, XBIGNUM_DATA (limit)); + return Fcanonicalize_number (make_bignum_bg (scratch_bignum)); + } +#endif /* Try to take our random number from the higher bits of VAL, not the lower, since (says Gentzel) the low bits of `random' are less random than the higher ones. We do this by using the @@ -240,13 +245,6 @@ val = get_random () / denominator; while (val >= XINT (limit)); } -#ifdef HAVE_BIGNUM - else if (BIGNUMP (limit)) - { - bignum_random (scratch_bignum, XBIGNUM_DATA (limit)); - return Fcanonicalize_number (make_bignum_bg (scratch_bignum)); - } -#endif else val = get_random (); @@ -1436,7 +1434,7 @@ REGISTER EMACS_INT i; REGISTER Lisp_Object tail = list; CHECK_NATNUM (n); - for (i = XINT (n); i; i--) + for (i = BIGNUMP (n) ? 1 + EMACS_INT_MAX : XINT (n); i; i--) { if (CONSP (tail)) tail = XCDR (tail); @@ -1556,7 +1554,7 @@ else { CHECK_NATNUM (n); - int_n = XINT (n); + int_n = BIGNUMP (n) ? 1 + EMACS_INT_MAX : XINT (n); } for (retval = tortoise = hare = list, count = 0; @@ -1576,9 +1574,6 @@ return retval; } -static Lisp_Object bignum_butlast (Lisp_Object list, Lisp_Object number, - Boolint copy); - DEFUN ("nbutlast", Fnbutlast, 1, 2, 0, /* Modify LIST to remove the last N (default 1) elements. @@ -1593,13 +1588,8 @@ if (!NILP (n)) { - if (BIGNUMP (n)) - { - return bignum_butlast (list, n, 0); - } - CHECK_NATNUM (n); - int_n = XINT (n); + int_n = BIGNUMP (n) ? 1 + EMACS_INT_MAX : XINT (n); } if (CONSP (list)) @@ -1646,13 +1636,8 @@ if (!NILP (n)) { - if (BIGNUMP (n)) - { - return bignum_butlast (list, n, 1); - } - CHECK_NATNUM (n); - int_n = XINT (n); + int_n = BIGNUMP (n) ? 1 + EMACS_INT_MAX : XINT (n); } if (CONSP (list)) @@ -1686,42 +1671,6 @@ return retval; } -/* This is sufficient to implement #'butlast and #'nbutlast with bignum N - under XEmacs, because #'list-length and #'safe-length can never return a - bignum. This means that #'nbutlast never has to modify and #'butlast - never has to copy. */ -static Lisp_Object -bignum_butlast (Lisp_Object list, Lisp_Object number, Boolint copy) -{ - Boolint malformed = EQ (Fsafe_length (list), Qzero); - Boolint circular = !malformed && EQ (Flist_length (list), Qnil); - - assert (BIGNUMP (number)); - -#ifdef HAVE_BIGNUM - - if (bignum_sign (XBIGNUM_DATA (number)) < 0) - { - dead_wrong_type_argument (Qnatnump, number); - } - - number = Fcanonicalize_number (number); - - if (INTP (number)) - { - return copy ? Fbutlast (list, number) : Fnbutlast (list, number); - } - -#endif - - if (circular) - { - signal_circular_list_error (list); - } - - return Qnil; -} - DEFUN ("member", Fmember, 2, 2, 0, /* Return non-nil if ELT is an element of LIST. Comparison done with `equal'. The value is actually the tail of LIST whose car is ELT. @@ -4224,17 +4173,15 @@ { Lisp_Object sequence = args[0]; Lisp_Object item = args[1]; - Elemcount starting = 0, ending = EMACS_INT_MAX, ii, len; + Elemcount starting = 0, ending = EMACS_INT_MAX + 1, ii, len; PARSE_KEYWORDS (Ffill, nargs, args, 2, (start, end), (start = Qzero)); CHECK_NATNUM (start); - starting = XINT (start); - if (!NILP (end)) { CHECK_NATNUM (end); - ending = XINT (end); + ending = BIGNUMP (end) ? EMACS_INT_MAX + 1 : XINT (end); } retry: @@ -4254,6 +4201,7 @@ check_sequence_range (sequence, start, end, make_int (len)); ending = min (ending, len); + starting = XINT (start); for (ii = starting; ii < ending; ++ii) { @@ -4272,6 +4220,7 @@ check_sequence_range (sequence, start, end, make_int (len)); ending = min (ending, len); + starting = XINT (start); for (ii = starting; ii < ending; ++ii) { @@ -4281,6 +4230,7 @@ else if (LISTP (sequence)) { Elemcount counting = 0; + starting = BIGNUMP (start) ? EMACS_INT_MAX + 1 : XINT (start); EXTERNAL_LIST_LOOP_3 (elt, sequence, tail) { @@ -5235,7 +5185,7 @@ (int nargs, Lisp_Object *args)) { Lisp_Object function = args[0], sequence = args[1], accum = Qunbound; - Elemcount starting, ending = EMACS_INT_MAX, ii = 0; + Elemcount starting, ending = EMACS_INT_MAX + 1, ii = 0; PARSE_KEYWORDS (Freduce, nargs, args, 5, (start, end, from_end, initial_value, key), @@ -5243,7 +5193,7 @@ CHECK_SEQUENCE (sequence); CHECK_NATNUM (start); - + starting = BIGNUMP (start) ? EMACS_INT_MAX + 1 : XINT (start); CHECK_KEY_ARGUMENT (key); #define KEY(key, item) (EQ (Qidentity, key) ? item : \ @@ -5251,16 +5201,10 @@ #define CALL2(function, accum, item) \ IGNORE_MULTIPLE_VALUES (call2 (function, accum, item)) - starting = XINT (start); if (!NILP (end)) { CHECK_NATNUM (end); - ending = XINT (end); - } - - if (!(starting <= ending)) - { - check_sequence_range (sequence, start, end, Flength (sequence)); + ending = BIGNUMP (end) ? EMACS_INT_MAX + 1 : XINT (end); } if (VECTORP (sequence)) @@ -5432,6 +5376,8 @@ check_sequence_range (sequence, start, end, make_int (len)); ending = min (ending, len); + starting = XINT (start); + cursor = string_char_addr (sequence, ending - 1); cursor_offset = cursor - XSTRING_DATA (sequence); @@ -5679,7 +5625,8 @@ Ibyte *destp = XSTRING_DATA (dest), *p = destp, *pend = p + XSTRING_LENGTH (dest), *pcursor, item_buf[MAX_ICHAR_LEN]; Bytecount prefix_bytecount, source_len = source_limit - source; - Charcount ii = 0, starting = XINT (start), ending, len; + Charcount ii = 0, ending, len; + Charcount starting = BIGNUMP (start) ? EMACS_INT_MAX + 1 : XINT (start); Elemcount delta; while (ii < starting && p < pend) @@ -5702,7 +5649,7 @@ } else { - ending = XINT (end); + ending = BIGNUMP (end) ? EMACS_INT_MAX + 1 : XINT (end); while (ii < ending && pcursor < pend) { INC_IBYTEPTR (pcursor); @@ -5782,8 +5729,8 @@ { Lisp_Object sequence1 = args[0], sequence2 = args[1], result = sequence1; - Elemcount starting1, ending1 = EMACS_INT_MAX, starting2; - Elemcount ending2 = EMACS_INT_MAX, counting = 0, startcounting; + Elemcount starting1, ending1 = EMACS_INT_MAX + 1, starting2; + Elemcount ending2 = EMACS_INT_MAX + 1, counting = 0, startcounting; Boolint sequence1_listp, sequence2_listp, overwriting = EQ (sequence1, sequence2); @@ -5796,30 +5743,20 @@ CHECK_SEQUENCE (sequence2); CHECK_NATNUM (start1); - starting1 = XINT (start1); + starting1 = BIGNUMP (start1) ? EMACS_INT_MAX + 1 : XINT (start1); CHECK_NATNUM (start2); - starting2 = XINT (start2); + starting2 = BIGNUMP (start2) ? EMACS_INT_MAX + 1 : XINT (start2); if (!NILP (end1)) { CHECK_NATNUM (end1); - ending1 = XINT (end1); - - if (!(starting1 <= ending1)) - { - args_out_of_range_3 (sequence1, start1, end1); - } + ending1 = BIGNUMP (end1) ? EMACS_INT_MAX + 1 : XINT (end1); } if (!NILP (end2)) { CHECK_NATNUM (end2); - ending2 = XINT (end2); - - if (!(starting2 <= ending2)) - { - args_out_of_range_3 (sequence1, start2, end2); - } + ending2 = BIGNUMP (end2) ? EMACS_INT_MAX + 1 : XINT (end2); } sequence1_listp = LISTP (sequence1);