Mercurial > hg > xemacs-beta
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 |