Mercurial > hg > xemacs-beta
comparison src/fns.c @ 5437:002cb5224e4f
Merge with 21.5 trunk.
author | Mats Lidell <matsl@xemacs.org> |
---|---|
date | Mon, 15 Nov 2010 22:33:52 +0100 |
parents | 46491edfd94a 4c4085177ca5 |
children | 8d29f1c4bb98 |
comparison
equal
deleted
inserted
replaced
5436:da1365dd3f07 | 5437:002cb5224e4f |
---|---|
210 } | 210 } |
211 | 211 |
212 DEFUN ("random", Frandom, 0, 1, 0, /* | 212 DEFUN ("random", Frandom, 0, 1, 0, /* |
213 Return a pseudo-random number. | 213 Return a pseudo-random number. |
214 All fixnums are equally likely. On most systems, this is 31 bits' worth. | 214 All fixnums are equally likely. On most systems, this is 31 bits' worth. |
215 With positive integer argument N, return random number in interval [0,N). | 215 With positive integer argument LIMIT, return random number in interval [0, |
216 N can be a bignum, in which case the range of possible values is extended. | 216 LIMIT). LIMIT can be a bignum, in which case the range of possible values |
217 With argument t, set the random number seed from the current time and pid. | 217 is extended. With argument t, set the random number seed from the current |
218 time and pid. | |
218 */ | 219 */ |
219 (limit)) | 220 (limit)) |
220 { | 221 { |
221 EMACS_INT val; | 222 EMACS_INT val; |
222 unsigned long denominator; | 223 unsigned long denominator; |
1103 if (0 != ss) | 1104 if (0 != ss) |
1104 { | 1105 { |
1105 sequence = Fnthcdr (make_int (ss), sequence); | 1106 sequence = Fnthcdr (make_int (ss), sequence); |
1106 } | 1107 } |
1107 | 1108 |
1109 ii = ss + 1; | |
1110 | |
1108 if (ss < ee && !NILP (sequence)) | 1111 if (ss < ee && !NILP (sequence)) |
1109 { | 1112 { |
1110 result = result_tail = Fcons (Fcar (sequence), Qnil); | 1113 result = result_tail = Fcons (Fcar (sequence), Qnil); |
1111 sequence = Fcdr (sequence); | 1114 sequence = Fcdr (sequence); |
1112 ii = ss + 1; | |
1113 | 1115 |
1114 { | 1116 { |
1115 EXTERNAL_LIST_LOOP_2 (elt, sequence) | 1117 EXTERNAL_LIST_LOOP_2 (elt, sequence) |
1116 { | 1118 { |
1117 if (!(ii < ee)) | 1119 if (!(ii < ee)) |
2123 else if (VECTORP (sequence)) | 2125 else if (VECTORP (sequence)) |
2124 { | 2126 { |
2125 Elemcount length = XVECTOR_LENGTH (sequence), ii = length; | 2127 Elemcount length = XVECTOR_LENGTH (sequence), ii = length; |
2126 Elemcount half = length / 2; | 2128 Elemcount half = length / 2; |
2127 Lisp_Object swap = Qnil; | 2129 Lisp_Object swap = Qnil; |
2130 CHECK_LISP_WRITEABLE (sequence); | |
2128 | 2131 |
2129 while (ii > half) | 2132 while (ii > half) |
2130 { | 2133 { |
2131 swap = XVECTOR_DATA (sequence) [length - ii]; | 2134 swap = XVECTOR_DATA (sequence) [length - ii]; |
2132 XVECTOR_DATA (sequence) [length - ii] | 2135 XVECTOR_DATA (sequence) [length - ii] |
2139 { | 2142 { |
2140 Elemcount length = XSTRING_LENGTH (sequence); | 2143 Elemcount length = XSTRING_LENGTH (sequence); |
2141 Ibyte *staging = alloca_ibytes (length), *staging_end = staging + length; | 2144 Ibyte *staging = alloca_ibytes (length), *staging_end = staging + length; |
2142 Ibyte *cursor = XSTRING_DATA (sequence), *endp = cursor + length; | 2145 Ibyte *cursor = XSTRING_DATA (sequence), *endp = cursor + length; |
2143 | 2146 |
2147 CHECK_LISP_WRITEABLE (sequence); | |
2144 while (cursor < endp) | 2148 while (cursor < endp) |
2145 { | 2149 { |
2146 staging_end -= itext_ichar_len (cursor); | 2150 staging_end -= itext_ichar_len (cursor); |
2147 itext_copy_ichar (cursor, staging_end); | 2151 itext_copy_ichar (cursor, staging_end); |
2148 INC_IBYTEPTR (cursor); | 2152 INC_IBYTEPTR (cursor); |
2160 Lisp_Bit_Vector *bv = XBIT_VECTOR (sequence); | 2164 Lisp_Bit_Vector *bv = XBIT_VECTOR (sequence); |
2161 Elemcount length = bit_vector_length (bv), ii = length; | 2165 Elemcount length = bit_vector_length (bv), ii = length; |
2162 Elemcount half = length / 2; | 2166 Elemcount half = length / 2; |
2163 int swap = 0; | 2167 int swap = 0; |
2164 | 2168 |
2169 CHECK_LISP_WRITEABLE (sequence); | |
2165 while (ii > half) | 2170 while (ii > half) |
2166 { | 2171 { |
2167 swap = bit_vector_bit (bv, length - ii); | 2172 swap = bit_vector_bit (bv, length - ii); |
2168 set_bit_vector_bit (bv, length - ii, bit_vector_bit (bv, ii - 1)); | 2173 set_bit_vector_bit (bv, length - ii, bit_vector_bit (bv, ii - 1)); |
2169 set_bit_vector_bit (bv, ii - 1, swap); | 2174 set_bit_vector_bit (bv, ii - 1, swap); |
4445 Lisp_Object function, int nsequences, Lisp_Object *sequences, | 4450 Lisp_Object function, int nsequences, Lisp_Object *sequences, |
4446 Lisp_Object caller) | 4451 Lisp_Object caller) |
4447 { | 4452 { |
4448 Lisp_Object called, *args; | 4453 Lisp_Object called, *args; |
4449 struct gcpro gcpro1, gcpro2; | 4454 struct gcpro gcpro1, gcpro2; |
4450 Ibyte *lisp_vals_staging, *cursor; | 4455 Ibyte *lisp_vals_staging = NULL, *cursor = NULL; |
4451 int i, j; | 4456 int i, j; |
4452 | 4457 |
4453 assert ((EQ (caller, Qsome) || EQ (caller, Qevery)) ? vals == NULL : 1); | 4458 assert ((EQ (caller, Qsome) || EQ (caller, Qevery)) ? vals == NULL : 1); |
4454 | 4459 |
4455 args = alloca_array (Lisp_Object, nsequences + 1); | 4460 args = alloca_array (Lisp_Object, nsequences + 1); |
4492 vals[i] = IGNORE_MULTIPLE_VALUES (Ffuncall (nsequences + 1, args)); | 4497 vals[i] = IGNORE_MULTIPLE_VALUES (Ffuncall (nsequences + 1, args)); |
4493 } | 4498 } |
4494 } | 4499 } |
4495 else | 4500 else |
4496 { | 4501 { |
4497 enum lrecord_type lisp_vals_type; | 4502 enum lrecord_type lisp_vals_type = lrecord_type_symbol; |
4498 Binbyte *sequence_types = alloca_array (Binbyte, nsequences); | 4503 Binbyte *sequence_types = alloca_array (Binbyte, nsequences); |
4499 for (j = 0; j < nsequences; ++j) | 4504 for (j = 0; j < nsequences; ++j) |
4500 { | 4505 { |
4501 sequence_types[j] = XRECORD_LHEADER (sequences[j])->type; | 4506 sequence_types[j] = XRECORD_LHEADER (sequences[j])->type; |
4502 } | 4507 } |
4511 if (lrecord_type_string == lisp_vals_type) | 4516 if (lrecord_type_string == lisp_vals_type) |
4512 { | 4517 { |
4513 lisp_vals_staging = cursor | 4518 lisp_vals_staging = cursor |
4514 = alloca_ibytes (call_count * MAX_ICHAR_LEN); | 4519 = alloca_ibytes (call_count * MAX_ICHAR_LEN); |
4515 } | 4520 } |
4521 else if (ARRAYP (lisp_vals)) | |
4522 { | |
4523 CHECK_LISP_WRITEABLE (lisp_vals); | |
4524 } | |
4516 } | 4525 } |
4517 | 4526 |
4518 for (i = 0; i < call_count; ++i) | 4527 for (i = 0; i < call_count; ++i) |
4519 { | 4528 { |
4520 for (j = 0; j < nsequences; ++j) | 4529 for (j = 0; j < nsequences; ++j) |
4636 } | 4645 } |
4637 } | 4646 } |
4638 } | 4647 } |
4639 } | 4648 } |
4640 | 4649 |
4641 if (!EQ (caller, Qsome) && !EQ (caller, Qevery) && | 4650 if (lisp_vals_staging != NULL) |
4642 lrecord_type_string == lisp_vals_type) | 4651 { |
4643 { | 4652 CHECK_LISP_WRITEABLE (lisp_vals); |
4644 replace_string_range (lisp_vals, Qzero, make_int (call_count), | 4653 replace_string_range (lisp_vals, Qzero, make_int (call_count), |
4645 lisp_vals_staging, cursor); | 4654 lisp_vals_staging, cursor); |
4646 } | 4655 } |
4647 } | 4656 } |
4648 | 4657 |
4654 one of them is not a sequence. */ | 4663 one of them is not a sequence. */ |
4655 static Elemcount | 4664 static Elemcount |
4656 shortest_length_among_sequences (int nsequences, Lisp_Object *sequences) | 4665 shortest_length_among_sequences (int nsequences, Lisp_Object *sequences) |
4657 { | 4666 { |
4658 Elemcount len = EMACS_INT_MAX; | 4667 Elemcount len = EMACS_INT_MAX; |
4659 Lisp_Object length; | 4668 Lisp_Object length = Qnil; |
4660 int i; | 4669 int i; |
4661 | 4670 |
4662 for (i = 0; i < nsequences; ++i) | 4671 for (i = 0; i < nsequences; ++i) |
4663 { | 4672 { |
4664 if (CONSP (sequences[i])) | 4673 if (CONSP (sequences[i])) |
4947 | 4956 |
4948 If so, return the value (possibly multiple) given by PREDICATE. | 4957 If so, return the value (possibly multiple) given by PREDICATE. |
4949 | 4958 |
4950 With optional SEQUENCES, call PREDICATE each time with as many arguments as | 4959 With optional SEQUENCES, call PREDICATE each time with as many arguments as |
4951 there are SEQUENCES (plus one for the element from SEQUENCE). | 4960 there are SEQUENCES (plus one for the element from SEQUENCE). |
4961 | |
4962 See also `find-if', which returns the corresponding element of SEQUENCE, | |
4963 rather than the value given by PREDICATE, and accepts bounding index | |
4964 keywords. | |
4952 | 4965 |
4953 arguments: (PREDICATE SEQUENCE &rest SEQUENCES) | 4966 arguments: (PREDICATE SEQUENCE &rest SEQUENCES) |
4954 */ | 4967 */ |
4955 (int nargs, Lisp_Object *args)) | 4968 (int nargs, Lisp_Object *args)) |
4956 { | 4969 { |
5200 } | 5213 } |
5201 | 5214 |
5202 if (VECTORP (sequence)) | 5215 if (VECTORP (sequence)) |
5203 { | 5216 { |
5204 Lisp_Vector *vv = XVECTOR (sequence); | 5217 Lisp_Vector *vv = XVECTOR (sequence); |
5218 struct gcpro gcpro1; | |
5205 | 5219 |
5206 check_sequence_range (sequence, start, end, make_int (vv->size)); | 5220 check_sequence_range (sequence, start, end, make_int (vv->size)); |
5207 | 5221 |
5208 ending = min (ending, vv->size); | 5222 ending = min (ending, vv->size); |
5223 | |
5224 GCPRO1 (accum); | |
5209 | 5225 |
5210 if (!UNBOUNDP (initial_value)) | 5226 if (!UNBOUNDP (initial_value)) |
5211 { | 5227 { |
5212 accum = initial_value; | 5228 accum = initial_value; |
5213 } | 5229 } |
5237 for (ii = ending - 1; ii >= starting; --ii) | 5253 for (ii = ending - 1; ii >= starting; --ii) |
5238 { | 5254 { |
5239 accum = CALL2 (function, KEY (key, vv->contents[ii]), accum); | 5255 accum = CALL2 (function, KEY (key, vv->contents[ii]), accum); |
5240 } | 5256 } |
5241 } | 5257 } |
5258 | |
5259 UNGCPRO; | |
5242 } | 5260 } |
5243 else if (BIT_VECTORP (sequence)) | 5261 else if (BIT_VECTORP (sequence)) |
5244 { | 5262 { |
5245 Lisp_Bit_Vector *bv = XBIT_VECTOR (sequence); | 5263 Lisp_Bit_Vector *bv = XBIT_VECTOR (sequence); |
5264 struct gcpro gcpro1; | |
5246 | 5265 |
5247 check_sequence_range (sequence, start, end, make_int (bv->size)); | 5266 check_sequence_range (sequence, start, end, make_int (bv->size)); |
5248 | |
5249 ending = min (ending, bv->size); | 5267 ending = min (ending, bv->size); |
5268 | |
5269 GCPRO1 (accum); | |
5250 | 5270 |
5251 if (!UNBOUNDP (initial_value)) | 5271 if (!UNBOUNDP (initial_value)) |
5252 { | 5272 { |
5253 accum = initial_value; | 5273 accum = initial_value; |
5254 } | 5274 } |
5282 make_int (bit_vector_bit (bv, | 5302 make_int (bit_vector_bit (bv, |
5283 ii))), | 5303 ii))), |
5284 accum); | 5304 accum); |
5285 } | 5305 } |
5286 } | 5306 } |
5307 | |
5308 UNGCPRO; | |
5309 | |
5287 } | 5310 } |
5288 else if (STRINGP (sequence)) | 5311 else if (STRINGP (sequence)) |
5289 { | 5312 { |
5313 struct gcpro gcpro1; | |
5314 | |
5315 GCPRO1 (accum); | |
5316 | |
5290 if (NILP (from_end)) | 5317 if (NILP (from_end)) |
5291 { | 5318 { |
5292 Bytecount byte_len = XSTRING_LENGTH (sequence); | 5319 Bytecount byte_len = XSTRING_LENGTH (sequence); |
5293 Bytecount cursor_offset = 0; | 5320 Bytecount cursor_offset = 0; |
5294 const Ibyte *startp = XSTRING_DATA (sequence); | 5321 const Ibyte *startp = XSTRING_DATA (sequence); |
5302 | 5329 |
5303 if (!UNBOUNDP (initial_value)) | 5330 if (!UNBOUNDP (initial_value)) |
5304 { | 5331 { |
5305 accum = initial_value; | 5332 accum = initial_value; |
5306 } | 5333 } |
5307 else if (ending - starting) | 5334 else if (ending - starting && cursor_offset < byte_len) |
5308 { | 5335 { |
5309 accum = KEY (key, make_char (itext_ichar (cursor))); | 5336 accum = KEY (key, make_char (itext_ichar (cursor))); |
5310 starting++; | 5337 starting++; |
5311 startp = XSTRING_DATA (sequence); | 5338 startp = XSTRING_DATA (sequence); |
5312 cursor = startp + cursor_offset; | 5339 cursor = startp + cursor_offset; |
5317 mapping_interaction_error (Qreduce, sequence); | 5344 mapping_interaction_error (Qreduce, sequence); |
5318 } | 5345 } |
5319 | 5346 |
5320 INC_IBYTEPTR (cursor); | 5347 INC_IBYTEPTR (cursor); |
5321 cursor_offset = cursor - startp; | 5348 cursor_offset = cursor - startp; |
5349 ii++; | |
5322 } | 5350 } |
5323 | 5351 |
5324 while (cursor_offset < byte_len && ii < ending) | 5352 while (cursor_offset < byte_len && ii < ending) |
5325 { | 5353 { |
5326 accum = CALL2 (function, accum, | 5354 accum = CALL2 (function, accum, |
5341 } | 5369 } |
5342 | 5370 |
5343 if (ii < starting || (ii < ending && !NILP (end))) | 5371 if (ii < starting || (ii < ending && !NILP (end))) |
5344 { | 5372 { |
5345 check_sequence_range (sequence, start, end, Flength (sequence)); | 5373 check_sequence_range (sequence, start, end, Flength (sequence)); |
5346 ABORT (); | |
5347 } | 5374 } |
5348 } | 5375 } |
5349 else | 5376 else |
5350 { | 5377 { |
5351 Elemcount len = string_char_length (sequence); | 5378 Elemcount len = string_char_length (sequence); |
5352 Bytecount cursor_offset, byte_len = XSTRING_LENGTH (sequence); | 5379 Bytecount cursor_offset, byte_len = XSTRING_LENGTH (sequence); |
5353 const Ibyte *cursor; | 5380 const Ibyte *cursor; |
5354 | 5381 |
5355 check_sequence_range (sequence, start, end, make_int (len)); | 5382 check_sequence_range (sequence, start, end, make_int (len)); |
5356 | |
5357 ending = min (ending, len); | 5383 ending = min (ending, len); |
5358 cursor = string_char_addr (sequence, ending - 1); | 5384 cursor = string_char_addr (sequence, ending - 1); |
5359 cursor_offset = cursor - XSTRING_DATA (sequence); | 5385 cursor_offset = cursor - XSTRING_DATA (sequence); |
5360 | 5386 |
5361 if (!UNBOUNDP (initial_value)) | 5387 if (!UNBOUNDP (initial_value)) |
5398 DEC_IBYTEPTR (cursor); | 5424 DEC_IBYTEPTR (cursor); |
5399 cursor_offset = cursor - XSTRING_DATA (sequence); | 5425 cursor_offset = cursor - XSTRING_DATA (sequence); |
5400 } | 5426 } |
5401 } | 5427 } |
5402 } | 5428 } |
5429 | |
5430 UNGCPRO; | |
5403 } | 5431 } |
5404 else if (LISTP (sequence)) | 5432 else if (LISTP (sequence)) |
5405 { | 5433 { |
5406 if (NILP (from_end)) | 5434 if (NILP (from_end)) |
5407 { | 5435 { |
5408 struct gcpro gcpro1; | 5436 struct gcpro gcpro1, gcpro2; |
5409 Lisp_Object tailed = Qnil; | 5437 Lisp_Object tailed = Qnil; |
5410 | 5438 |
5411 GCPRO1 (tailed); | 5439 GCPRO2 (tailed, accum); |
5412 | 5440 |
5413 if (!UNBOUNDP (initial_value)) | 5441 if (!UNBOUNDP (initial_value)) |
5414 { | 5442 { |
5415 accum = initial_value; | 5443 accum = initial_value; |
5416 } | 5444 } |
5459 UNGCPRO; | 5487 UNGCPRO; |
5460 | 5488 |
5461 if (ii < starting || (ii < ending && !NILP (end))) | 5489 if (ii < starting || (ii < ending && !NILP (end))) |
5462 { | 5490 { |
5463 check_sequence_range (sequence, start, end, Flength (sequence)); | 5491 check_sequence_range (sequence, start, end, Flength (sequence)); |
5464 ABORT (); | |
5465 } | 5492 } |
5466 } | 5493 } |
5467 else | 5494 else |
5468 { | 5495 { |
5469 Boolint need_accum = 0; | 5496 Boolint need_accum = 0; |
5925 } | 5952 } |
5926 } | 5953 } |
5927 | 5954 |
5928 if (NILP (sequence1)) | 5955 if (NILP (sequence1)) |
5929 { | 5956 { |
5930 check_sequence_range (sequence1, start1, end1, | 5957 check_sequence_range (args[0], start1, end1, |
5931 make_int (XINT (start1) + shortest_len)); | 5958 make_int (XINT (start1) + shortest_len)); |
5932 } | 5959 } |
5933 else if (NILP (sequence2)) | 5960 else if (NILP (sequence2)) |
5934 { | 5961 { |
5935 check_sequence_range (sequence2, start2, end2, | 5962 check_sequence_range (args[1], start2, end2, |
5936 make_int (XINT (start2) + shortest_len)); | 5963 make_int (XINT (start2) + shortest_len)); |
5937 } | 5964 } |
5938 } | 5965 } |
5939 else if (sequence1_listp) | 5966 else if (sequence1_listp) |
5940 { | 5967 { |
5993 starting2++; | 6020 starting2++; |
5994 } | 6021 } |
5995 | 6022 |
5996 if (NILP (sequence1)) | 6023 if (NILP (sequence1)) |
5997 { | 6024 { |
5998 check_sequence_range (sequence1, start1, end1, | 6025 check_sequence_range (args[0], start1, end1, |
5999 make_int (XINT (start1) + starting1)); | 6026 make_int (XINT (start1) + starting1)); |
6000 } | 6027 } |
6001 } | 6028 } |
6002 } | 6029 } |
6003 else if (sequence2_listp) | 6030 else if (sequence2_listp) |
6050 starting2++; | 6077 starting2++; |
6051 } | 6078 } |
6052 | 6079 |
6053 if (NILP (sequence2)) | 6080 if (NILP (sequence2)) |
6054 { | 6081 { |
6055 check_sequence_range (sequence2, start2, end2, | 6082 check_sequence_range (args[1], start2, end2, |
6056 make_int (XINT (start2) + starting2)); | 6083 make_int (XINT (start2) + starting2)); |
6057 } | 6084 } |
6058 } | 6085 } |
6059 } | 6086 } |
6060 else | 6087 else |