comparison src/fns.c @ 5438:8d29f1c4bb98

Merge with 21.5 trunk.
author Mats Lidell <matsl@xemacs.org>
date Fri, 26 Nov 2010 06:43:36 +0100
parents 002cb5224e4f c096d8051f89
children 771bf922ab2b
comparison
equal deleted inserted replaced
5437:002cb5224e4f 5438:8d29f1c4bb98
74 74
75 static void 75 static void
76 check_sequence_range (Lisp_Object sequence, Lisp_Object start, 76 check_sequence_range (Lisp_Object sequence, Lisp_Object start,
77 Lisp_Object end, Lisp_Object length) 77 Lisp_Object end, Lisp_Object length)
78 { 78 {
79 Elemcount starting = XINT (start), ending, len = XINT (length); 79 Lisp_Object args[] = { Qzero, start, NILP (end) ? length : end, length };
80 80
81 ending = NILP (end) ? XINT (length) : XINT (end); 81 if (NILP (Fleq (countof (args), args)))
82 82 {
83 if (!(0 <= starting && starting <= ending && ending <= len)) 83 args_out_of_range_3 (sequence, start, end);
84 {
85 args_out_of_range_3 (sequence, start, make_int (ending));
86 } 84 }
87 } 85 }
88 86
89 static Lisp_Object 87 static Lisp_Object
90 mark_bit_vector (Lisp_Object UNUSED (obj)) 88 mark_bit_vector (Lisp_Object UNUSED (obj))
224 222
225 if (EQ (limit, Qt)) 223 if (EQ (limit, Qt))
226 seed_random (qxe_getpid () + time (NULL)); 224 seed_random (qxe_getpid () + time (NULL));
227 if (NATNUMP (limit) && !ZEROP (limit)) 225 if (NATNUMP (limit) && !ZEROP (limit))
228 { 226 {
227 #ifdef HAVE_BIGNUM
228 if (BIGNUMP (limit))
229 {
230 bignum_random (scratch_bignum, XBIGNUM_DATA (limit));
231 return Fcanonicalize_number (make_bignum_bg (scratch_bignum));
232 }
233 #endif
229 /* Try to take our random number from the higher bits of VAL, 234 /* Try to take our random number from the higher bits of VAL,
230 not the lower, since (says Gentzel) the low bits of `random' 235 not the lower, since (says Gentzel) the low bits of `random'
231 are less random than the higher ones. We do this by using the 236 are less random than the higher ones. We do this by using the
232 quotient rather than the remainder. At the high end of the RNG 237 quotient rather than the remainder. At the high end of the RNG
233 it's possible to get a quotient larger than limit; discarding 238 it's possible to get a quotient larger than limit; discarding
236 denominator = ((unsigned long)1 << INT_VALBITS) / XINT (limit); 241 denominator = ((unsigned long)1 << INT_VALBITS) / XINT (limit);
237 do 242 do
238 val = get_random () / denominator; 243 val = get_random () / denominator;
239 while (val >= XINT (limit)); 244 while (val >= XINT (limit));
240 } 245 }
241 #ifdef HAVE_BIGNUM
242 else if (BIGNUMP (limit))
243 {
244 bignum_random (scratch_bignum, XBIGNUM_DATA (limit));
245 return Fcanonicalize_number (make_bignum_bg (scratch_bignum));
246 }
247 #endif
248 else 246 else
249 val = get_random (); 247 val = get_random ();
250 248
251 return make_int (val); 249 return make_int (val);
252 } 250 }
1432 { 1430 {
1433 /* This function can GC */ 1431 /* This function can GC */
1434 REGISTER EMACS_INT i; 1432 REGISTER EMACS_INT i;
1435 REGISTER Lisp_Object tail = list; 1433 REGISTER Lisp_Object tail = list;
1436 CHECK_NATNUM (n); 1434 CHECK_NATNUM (n);
1437 for (i = XINT (n); i; i--) 1435 for (i = BIGNUMP (n) ? 1 + EMACS_INT_MAX : XINT (n); i; i--)
1438 { 1436 {
1439 if (CONSP (tail)) 1437 if (CONSP (tail))
1440 tail = XCDR (tail); 1438 tail = XCDR (tail);
1441 else if (NILP (tail)) 1439 else if (NILP (tail))
1442 return Qnil; 1440 return Qnil;
1552 if (NILP (n)) 1550 if (NILP (n))
1553 int_n = 1; 1551 int_n = 1;
1554 else 1552 else
1555 { 1553 {
1556 CHECK_NATNUM (n); 1554 CHECK_NATNUM (n);
1557 int_n = XINT (n); 1555 int_n = BIGNUMP (n) ? 1 + EMACS_INT_MAX : XINT (n);
1558 } 1556 }
1559 1557
1560 for (retval = tortoise = hare = list, count = 0; 1558 for (retval = tortoise = hare = list, count = 0;
1561 CONSP (hare); 1559 CONSP (hare);
1562 hare = XCDR (hare), 1560 hare = XCDR (hare),
1587 CHECK_LIST (list); 1585 CHECK_LIST (list);
1588 1586
1589 if (!NILP (n)) 1587 if (!NILP (n))
1590 { 1588 {
1591 CHECK_NATNUM (n); 1589 CHECK_NATNUM (n);
1592 int_n = XINT (n); 1590 int_n = BIGNUMP (n) ? 1 + EMACS_INT_MAX : XINT (n);
1593 } 1591 }
1594 1592
1595 if (CONSP (list)) 1593 if (CONSP (list))
1596 { 1594 {
1597 Lisp_Object last_cons = list; 1595 Lisp_Object last_cons = list;
1635 CHECK_LIST (list); 1633 CHECK_LIST (list);
1636 1634
1637 if (!NILP (n)) 1635 if (!NILP (n))
1638 { 1636 {
1639 CHECK_NATNUM (n); 1637 CHECK_NATNUM (n);
1640 int_n = XINT (n); 1638 int_n = BIGNUMP (n) ? 1 + EMACS_INT_MAX : XINT (n);
1641 } 1639 }
1642 1640
1643 if (CONSP (list)) 1641 if (CONSP (list))
1644 { 1642 {
1645 Lisp_Object tail = list; 1643 Lisp_Object tail = list;
4171 */ 4169 */
4172 (int nargs, Lisp_Object *args)) 4170 (int nargs, Lisp_Object *args))
4173 { 4171 {
4174 Lisp_Object sequence = args[0]; 4172 Lisp_Object sequence = args[0];
4175 Lisp_Object item = args[1]; 4173 Lisp_Object item = args[1];
4176 Elemcount starting = 0, ending = EMACS_INT_MAX, ii, len; 4174 Elemcount starting = 0, ending = EMACS_INT_MAX + 1, ii, len;
4177 4175
4178 PARSE_KEYWORDS (Ffill, nargs, args, 2, (start, end), (start = Qzero)); 4176 PARSE_KEYWORDS (Ffill, nargs, args, 2, (start, end), (start = Qzero));
4179 4177
4180 CHECK_NATNUM (start); 4178 CHECK_NATNUM (start);
4181 starting = XINT (start);
4182
4183 if (!NILP (end)) 4179 if (!NILP (end))
4184 { 4180 {
4185 CHECK_NATNUM (end); 4181 CHECK_NATNUM (end);
4186 ending = XINT (end); 4182 ending = BIGNUMP (end) ? EMACS_INT_MAX + 1 : XINT (end);
4187 } 4183 }
4188 4184
4189 retry: 4185 retry:
4190 if (STRINGP (sequence)) 4186 if (STRINGP (sequence))
4191 { 4187 {
4201 CHECK_LISP_WRITEABLE (sequence); 4197 CHECK_LISP_WRITEABLE (sequence);
4202 len = XVECTOR_LENGTH (sequence); 4198 len = XVECTOR_LENGTH (sequence);
4203 4199
4204 check_sequence_range (sequence, start, end, make_int (len)); 4200 check_sequence_range (sequence, start, end, make_int (len));
4205 ending = min (ending, len); 4201 ending = min (ending, len);
4202 starting = XINT (start);
4206 4203
4207 for (ii = starting; ii < ending; ++ii) 4204 for (ii = starting; ii < ending; ++ii)
4208 { 4205 {
4209 p[ii] = item; 4206 p[ii] = item;
4210 } 4207 }
4219 CHECK_LISP_WRITEABLE (sequence); 4216 CHECK_LISP_WRITEABLE (sequence);
4220 len = bit_vector_length (v); 4217 len = bit_vector_length (v);
4221 4218
4222 check_sequence_range (sequence, start, end, make_int (len)); 4219 check_sequence_range (sequence, start, end, make_int (len));
4223 ending = min (ending, len); 4220 ending = min (ending, len);
4221 starting = XINT (start);
4224 4222
4225 for (ii = starting; ii < ending; ++ii) 4223 for (ii = starting; ii < ending; ++ii)
4226 { 4224 {
4227 set_bit_vector_bit (v, ii, bit); 4225 set_bit_vector_bit (v, ii, bit);
4228 } 4226 }
4229 } 4227 }
4230 else if (LISTP (sequence)) 4228 else if (LISTP (sequence))
4231 { 4229 {
4232 Elemcount counting = 0; 4230 Elemcount counting = 0;
4231 starting = BIGNUMP (start) ? EMACS_INT_MAX + 1 : XINT (start);
4233 4232
4234 EXTERNAL_LIST_LOOP_3 (elt, sequence, tail) 4233 EXTERNAL_LIST_LOOP_3 (elt, sequence, tail)
4235 { 4234 {
4236 if (counting >= starting) 4235 if (counting >= starting)
4237 { 4236 {
5182 arguments: (FUNCTION SEQUENCE &key (START 0) (END (length SEQUENCE)) FROM-END INITIAL-VALUE (KEY #'identity)) 5181 arguments: (FUNCTION SEQUENCE &key (START 0) (END (length SEQUENCE)) FROM-END INITIAL-VALUE (KEY #'identity))
5183 */ 5182 */
5184 (int nargs, Lisp_Object *args)) 5183 (int nargs, Lisp_Object *args))
5185 { 5184 {
5186 Lisp_Object function = args[0], sequence = args[1], accum = Qunbound; 5185 Lisp_Object function = args[0], sequence = args[1], accum = Qunbound;
5187 Elemcount starting, ending = EMACS_INT_MAX, ii = 0; 5186 Elemcount starting, ending = EMACS_INT_MAX + 1, ii = 0;
5188 5187
5189 PARSE_KEYWORDS (Freduce, nargs, args, 5, 5188 PARSE_KEYWORDS (Freduce, nargs, args, 5,
5190 (start, end, from_end, initial_value, key), 5189 (start, end, from_end, initial_value, key),
5191 (start = Qzero, initial_value = Qunbound)); 5190 (start = Qzero, initial_value = Qunbound));
5192 5191
5193 CHECK_SEQUENCE (sequence); 5192 CHECK_SEQUENCE (sequence);
5194 CHECK_NATNUM (start); 5193 CHECK_NATNUM (start);
5195 5194 starting = BIGNUMP (start) ? EMACS_INT_MAX + 1 : XINT (start);
5196 CHECK_KEY_ARGUMENT (key); 5195 CHECK_KEY_ARGUMENT (key);
5197 5196
5198 #define KEY(key, item) (EQ (Qidentity, key) ? item : \ 5197 #define KEY(key, item) (EQ (Qidentity, key) ? item : \
5199 IGNORE_MULTIPLE_VALUES (call1 (key, item))) 5198 IGNORE_MULTIPLE_VALUES (call1 (key, item)))
5200 #define CALL2(function, accum, item) \ 5199 #define CALL2(function, accum, item) \
5201 IGNORE_MULTIPLE_VALUES (call2 (function, accum, item)) 5200 IGNORE_MULTIPLE_VALUES (call2 (function, accum, item))
5202 5201
5203 starting = XINT (start);
5204 if (!NILP (end)) 5202 if (!NILP (end))
5205 { 5203 {
5206 CHECK_NATNUM (end); 5204 CHECK_NATNUM (end);
5207 ending = XINT (end); 5205 ending = BIGNUMP (end) ? EMACS_INT_MAX + 1 : XINT (end);
5208 }
5209
5210 if (!(starting <= ending))
5211 {
5212 check_sequence_range (sequence, start, end, Flength (sequence));
5213 } 5206 }
5214 5207
5215 if (VECTORP (sequence)) 5208 if (VECTORP (sequence))
5216 { 5209 {
5217 Lisp_Vector *vv = XVECTOR (sequence); 5210 Lisp_Vector *vv = XVECTOR (sequence);
5379 Bytecount cursor_offset, byte_len = XSTRING_LENGTH (sequence); 5372 Bytecount cursor_offset, byte_len = XSTRING_LENGTH (sequence);
5380 const Ibyte *cursor; 5373 const Ibyte *cursor;
5381 5374
5382 check_sequence_range (sequence, start, end, make_int (len)); 5375 check_sequence_range (sequence, start, end, make_int (len));
5383 ending = min (ending, len); 5376 ending = min (ending, len);
5377 starting = XINT (start);
5378
5384 cursor = string_char_addr (sequence, ending - 1); 5379 cursor = string_char_addr (sequence, ending - 1);
5385 cursor_offset = cursor - XSTRING_DATA (sequence); 5380 cursor_offset = cursor - XSTRING_DATA (sequence);
5386 5381
5387 if (!UNBOUNDP (initial_value)) 5382 if (!UNBOUNDP (initial_value))
5388 { 5383 {
5626 Lisp_Object item) 5621 Lisp_Object item)
5627 { 5622 {
5628 Ibyte *destp = XSTRING_DATA (dest), *p = destp, 5623 Ibyte *destp = XSTRING_DATA (dest), *p = destp,
5629 *pend = p + XSTRING_LENGTH (dest), *pcursor, item_buf[MAX_ICHAR_LEN]; 5624 *pend = p + XSTRING_LENGTH (dest), *pcursor, item_buf[MAX_ICHAR_LEN];
5630 Bytecount prefix_bytecount, source_len = source_limit - source; 5625 Bytecount prefix_bytecount, source_len = source_limit - source;
5631 Charcount ii = 0, starting = XINT (start), ending, len; 5626 Charcount ii = 0, ending, len;
5627 Charcount starting = BIGNUMP (start) ? EMACS_INT_MAX + 1 : XINT (start);
5632 Elemcount delta; 5628 Elemcount delta;
5633 5629
5634 while (ii < starting && p < pend) 5630 while (ii < starting && p < pend)
5635 { 5631 {
5636 INC_IBYTEPTR (p); 5632 INC_IBYTEPTR (p);
5649 5645
5650 ending = len = ii; 5646 ending = len = ii;
5651 } 5647 }
5652 else 5648 else
5653 { 5649 {
5654 ending = XINT (end); 5650 ending = BIGNUMP (end) ? EMACS_INT_MAX + 1 : XINT (end);
5655 while (ii < ending && pcursor < pend) 5651 while (ii < ending && pcursor < pend)
5656 { 5652 {
5657 INC_IBYTEPTR (pcursor); 5653 INC_IBYTEPTR (pcursor);
5658 ii++; 5654 ii++;
5659 } 5655 }
5729 */ 5725 */
5730 (int nargs, Lisp_Object *args)) 5726 (int nargs, Lisp_Object *args))
5731 { 5727 {
5732 Lisp_Object sequence1 = args[0], sequence2 = args[1], 5728 Lisp_Object sequence1 = args[0], sequence2 = args[1],
5733 result = sequence1; 5729 result = sequence1;
5734 Elemcount starting1, ending1 = EMACS_INT_MAX, starting2; 5730 Elemcount starting1, ending1 = EMACS_INT_MAX + 1, starting2;
5735 Elemcount ending2 = EMACS_INT_MAX, counting = 0, startcounting; 5731 Elemcount ending2 = EMACS_INT_MAX + 1, counting = 0, startcounting;
5736 Boolint sequence1_listp, sequence2_listp, 5732 Boolint sequence1_listp, sequence2_listp,
5737 overwriting = EQ (sequence1, sequence2); 5733 overwriting = EQ (sequence1, sequence2);
5738 5734
5739 PARSE_KEYWORDS (Freplace, nargs, args, 4, (start1, end1, start2, end2), 5735 PARSE_KEYWORDS (Freplace, nargs, args, 4, (start1, end1, start2, end2),
5740 (start1 = start2 = Qzero)); 5736 (start1 = start2 = Qzero));
5743 CHECK_LISP_WRITEABLE (sequence1); 5739 CHECK_LISP_WRITEABLE (sequence1);
5744 5740
5745 CHECK_SEQUENCE (sequence2); 5741 CHECK_SEQUENCE (sequence2);
5746 5742
5747 CHECK_NATNUM (start1); 5743 CHECK_NATNUM (start1);
5748 starting1 = XINT (start1); 5744 starting1 = BIGNUMP (start1) ? EMACS_INT_MAX + 1 : XINT (start1);
5749 CHECK_NATNUM (start2); 5745 CHECK_NATNUM (start2);
5750 starting2 = XINT (start2); 5746 starting2 = BIGNUMP (start2) ? EMACS_INT_MAX + 1 : XINT (start2);
5751 5747
5752 if (!NILP (end1)) 5748 if (!NILP (end1))
5753 { 5749 {
5754 CHECK_NATNUM (end1); 5750 CHECK_NATNUM (end1);
5755 ending1 = XINT (end1); 5751 ending1 = BIGNUMP (end1) ? EMACS_INT_MAX + 1 : XINT (end1);
5756
5757 if (!(starting1 <= ending1))
5758 {
5759 args_out_of_range_3 (sequence1, start1, end1);
5760 }
5761 } 5752 }
5762 5753
5763 if (!NILP (end2)) 5754 if (!NILP (end2))
5764 { 5755 {
5765 CHECK_NATNUM (end2); 5756 CHECK_NATNUM (end2);
5766 ending2 = XINT (end2); 5757 ending2 = BIGNUMP (end2) ? EMACS_INT_MAX + 1 : XINT (end2);
5767
5768 if (!(starting2 <= ending2))
5769 {
5770 args_out_of_range_3 (sequence1, start2, end2);
5771 }
5772 } 5758 }
5773 5759
5774 sequence1_listp = LISTP (sequence1); 5760 sequence1_listp = LISTP (sequence1);
5775 sequence2_listp = LISTP (sequence2); 5761 sequence2_listp = LISTP (sequence2);
5776 5762