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