aboutsummaryrefslogtreecommitdiffstats
path: root/src/callint.c
diff options
context:
space:
mode:
authorPaul Eggert2018-01-29 09:42:42 -0800
committerPaul Eggert2018-01-29 09:45:04 -0800
commit29abae3572090a86beedb66822ccf34356c8a00c (patch)
tree0ee7184012c3dc00b9c546e4b4204b503d46a4fa /src/callint.c
parent81c2c2fa319b27550a2eb5021618c5eef3e813fd (diff)
downloademacs-29abae3572090a86beedb66822ccf34356c8a00c.tar.gz
emacs-29abae3572090a86beedb66822ccf34356c8a00c.zip
Simplify Fcall_interactively
* src/callint.c (Fcall_interactively): Use C99 constructs to simplify the code a bit. Stop worrying about circa-1990 compiler bugs.
Diffstat (limited to 'src/callint.c')
-rw-r--r--src/callint.c286
1 files changed, 109 insertions, 177 deletions
diff --git a/src/callint.c b/src/callint.c
index 3d2ed0016cc..08a8bba4646 100644
--- a/src/callint.c
+++ b/src/callint.c
@@ -271,45 +271,16 @@ invoke it. If KEYS is omitted or nil, the return value of
271`this-command-keys-vector' is used. */) 271`this-command-keys-vector' is used. */)
272 (Lisp_Object function, Lisp_Object record_flag, Lisp_Object keys) 272 (Lisp_Object function, Lisp_Object record_flag, Lisp_Object keys)
273{ 273{
274 /* `args' will contain the array of arguments to pass to the function.
275 `visargs' will contain the same list but in a nicer form, so that if we
276 pass it to Fformat_message it will be understandable to a human. */
277 Lisp_Object *args, *visargs;
278 Lisp_Object specs;
279 Lisp_Object filter_specs;
280 Lisp_Object teml;
281 Lisp_Object up_event;
282 Lisp_Object enable;
283 USE_SAFE_ALLOCA;
284 ptrdiff_t speccount = SPECPDL_INDEX (); 274 ptrdiff_t speccount = SPECPDL_INDEX ();
285 275
286 /* The index of the next element of this_command_keys to examine for 276 bool arg_from_tty = false;
287 the 'e' interactive code. */
288 ptrdiff_t next_event;
289
290 Lisp_Object prefix_arg;
291 char *string, *string_end;
292 ptrdiff_t string_len;
293 const char *tem;
294
295 /* If varies[i] > 0, the i'th argument shouldn't just have its value
296 in this call quoted in the command history. It should be
297 recorded as a call to the function named callint_argfuns[varies[i]]. */
298 signed char *varies;
299
300 ptrdiff_t i, nargs;
301 ptrdiff_t mark;
302 bool arg_from_tty = 0;
303 ptrdiff_t key_count; 277 ptrdiff_t key_count;
304 bool record_then_fail = 0; 278 bool record_then_fail = false;
305 279
306 Lisp_Object save_this_command, save_last_command; 280 Lisp_Object save_this_command = Vthis_command;
307 Lisp_Object save_this_original_command, save_real_this_command; 281 Lisp_Object save_this_original_command = Vthis_original_command;
308 282 Lisp_Object save_real_this_command = Vreal_this_command;
309 save_this_command = Vthis_command; 283 Lisp_Object save_last_command = KVAR (current_kboard, Vlast_command);
310 save_this_original_command = Vthis_original_command;
311 save_real_this_command = Vreal_this_command;
312 save_last_command = KVAR (current_kboard, Vlast_command);
313 284
314 if (NILP (keys)) 285 if (NILP (keys))
315 keys = this_command_keys, key_count = this_command_key_count; 286 keys = this_command_keys, key_count = this_command_key_count;
@@ -320,55 +291,44 @@ invoke it. If KEYS is omitted or nil, the return value of
320 } 291 }
321 292
322 /* Save this now, since use of minibuffer will clobber it. */ 293 /* Save this now, since use of minibuffer will clobber it. */
323 prefix_arg = Vcurrent_prefix_arg; 294 Lisp_Object prefix_arg = Vcurrent_prefix_arg;
324
325 if (SYMBOLP (function))
326 enable = Fget (function, Qenable_recursive_minibuffers);
327 else
328 enable = Qnil;
329 295
330 specs = Qnil; 296 Lisp_Object enable = (SYMBOLP (function)
331 string = 0; 297 ? Fget (function, Qenable_recursive_minibuffers)
332 /* The idea of FILTER_SPECS is to provide a way to 298 : Qnil);
333 specify how to represent the arguments in command history.
334 The feature is not fully implemented. */
335 filter_specs = Qnil;
336 299
337 /* If k or K discard an up-event, save it here so it can be retrieved with 300 /* If k or K discard an up-event, save it here so it can be retrieved with
338 U. */ 301 U. */
339 up_event = Qnil; 302 Lisp_Object up_event = Qnil;
340 303
341 /* Set SPECS to the interactive form, or barf if not interactive. */ 304 /* Set SPECS to the interactive form, or barf if not interactive. */
342 { 305 Lisp_Object form = Finteractive_form (function);
343 Lisp_Object form; 306 if (! CONSP (form))
344 form = Finteractive_form (function); 307 wrong_type_argument (Qcommandp, function);
345 if (CONSP (form)) 308 Lisp_Object specs = Fcar (XCDR (form));
346 specs = filter_specs = Fcar (XCDR (form)); 309
347 else 310 /* At this point the value of SPECS could help provide a way to
348 wrong_type_argument (Qcommandp, function); 311 specify how to represent the arguments in command history.
349 } 312 The feature is not fully implemented. */
350 313
351 /* If SPECS is not a string, invent one. */ 314 /* If SPECS is not a string, invent one. */
352 if (! STRINGP (specs)) 315 if (! STRINGP (specs))
353 { 316 {
354 Lisp_Object input;
355 Lisp_Object funval = Findirect_function (function, Qt); 317 Lisp_Object funval = Findirect_function (function, Qt);
356 uintmax_t events = num_input_events; 318 uintmax_t events = num_input_events;
357 input = specs; 319 Lisp_Object input = specs;
358 /* Compute the arg values using the user's expression. */ 320 /* Compute the arg values using the user's expression. */
359 specs = Feval (specs, 321 specs = Feval (specs,
360 CONSP (funval) && EQ (Qclosure, XCAR (funval)) 322 CONSP (funval) && EQ (Qclosure, XCAR (funval))
361 ? CAR_SAFE (XCDR (funval)) : Qnil); 323 ? CAR_SAFE (XCDR (funval)) : Qnil);
362 if (events != num_input_events || !NILP (record_flag)) 324 if (events != num_input_events || !NILP (record_flag))
363 { 325 {
364 /* We should record this command on the command history. */ 326 /* We should record this command on the command history.
365 Lisp_Object values; 327 Make a copy of the list of values, for the command history,
366 Lisp_Object this_cmd;
367 /* Make a copy of the list of values, for the command history,
368 and turn them into things we can eval. */ 328 and turn them into things we can eval. */
369 values = quotify_args (Fcopy_sequence (specs)); 329 Lisp_Object values = quotify_args (Fcopy_sequence (specs));
370 fix_command (input, values); 330 fix_command (input, values);
371 this_cmd = Fcons (function, values); 331 Lisp_Object this_cmd = Fcons (function, values);
372 if (history_delete_duplicates) 332 if (history_delete_duplicates)
373 Vcommand_history = Fdelete (this_cmd, Vcommand_history); 333 Vcommand_history = Fdelete (this_cmd, Vcommand_history);
374 Vcommand_history = Fcons (this_cmd, Vcommand_history); 334 Vcommand_history = Fcons (this_cmd, Vcommand_history);
@@ -376,7 +336,7 @@ invoke it. If KEYS is omitted or nil, the return value of
376 /* Don't keep command history around forever. */ 336 /* Don't keep command history around forever. */
377 if (INTEGERP (Vhistory_length) && XINT (Vhistory_length) > 0) 337 if (INTEGERP (Vhistory_length) && XINT (Vhistory_length) > 0)
378 { 338 {
379 teml = Fnthcdr (Vhistory_length, Vcommand_history); 339 Lisp_Object teml = Fnthcdr (Vhistory_length, Vcommand_history);
380 if (CONSP (teml)) 340 if (CONSP (teml))
381 XSETCDR (teml, Qnil); 341 XSETCDR (teml, Qnil);
382 } 342 }
@@ -387,48 +347,42 @@ invoke it. If KEYS is omitted or nil, the return value of
387 Vreal_this_command = save_real_this_command; 347 Vreal_this_command = save_real_this_command;
388 kset_last_command (current_kboard, save_last_command); 348 kset_last_command (current_kboard, save_last_command);
389 349
390 Lisp_Object result 350 return unbind_to (speccount, CALLN (Fapply, Qfuncall_interactively,
391 = unbind_to (speccount, CALLN (Fapply, Qfuncall_interactively, 351 function, specs));
392 function, specs));
393 SAFE_FREE ();
394 return result;
395 } 352 }
396 353
397 /* SPECS is set to a string; use it as an interactive prompt. 354 /* SPECS is set to a string; use it as an interactive prompt.
398 Copy it so that STRING will be valid even if a GC relocates SPECS. */ 355 Copy it so that STRING will be valid even if a GC relocates SPECS. */
399 SAFE_ALLOCA_STRING (string, specs); 356 USE_SAFE_ALLOCA;
400 string_len = SBYTES (specs); 357 ptrdiff_t string_len = SBYTES (specs);
401 string_end = string + string_len; 358 char *string = SAFE_ALLOCA (string_len + 1);
402 359 memcpy (string, SDATA (specs), string_len + 1);
403 /* Here if function specifies a string to control parsing the defaults. */ 360 char *string_end = string + string_len;
404 361
405 /* Set next_event to point to the first event with parameters. */ 362 /* The index of the next element of this_command_keys to examine for
363 the 'e' interactive code. Initialize it to point to the first
364 event with parameters. */
365 ptrdiff_t next_event;
406 for (next_event = 0; next_event < key_count; next_event++) 366 for (next_event = 0; next_event < key_count; next_event++)
407 if (EVENT_HAS_PARAMETERS (AREF (keys, next_event))) 367 if (EVENT_HAS_PARAMETERS (AREF (keys, next_event)))
408 break; 368 break;
409 369
410 /* Handle special starting chars `*' and `@'. Also `-'. */ 370 /* Handle special starting chars `*' and `@'. Also `-'. */
411 /* Note that `+' is reserved for user extensions. */ 371 /* Note that `+' is reserved for user extensions. */
412 while (1) 372 for (;; string++)
413 { 373 {
414 if (*string == '+') 374 if (*string == '+')
415 error ("`+' is not used in `interactive' for ordinary commands"); 375 error ("`+' is not used in `interactive' for ordinary commands");
416 else if (*string == '*') 376 else if (*string == '*')
417 { 377 {
418 string++;
419 if (!NILP (BVAR (current_buffer, read_only))) 378 if (!NILP (BVAR (current_buffer, read_only)))
420 { 379 {
421 if (!NILP (record_flag)) 380 if (!NILP (record_flag))
422 { 381 {
423 char *p = string; 382 for (char *p = string + 1; p < string_end; p++)
424 while (p < string_end) 383 if (! (*p == 'r' || *p == 'p' || *p == 'P' || *p == '\n'))
425 { 384 Fbarf_if_buffer_read_only (Qnil);
426 if (! (*p == 'r' || *p == 'p' || *p == 'P' 385 record_then_fail = true;
427 || *p == '\n'))
428 Fbarf_if_buffer_read_only (Qnil);
429 p++;
430 }
431 record_then_fail = 1;
432 } 386 }
433 else 387 else
434 Fbarf_if_buffer_read_only (Qnil); 388 Fbarf_if_buffer_read_only (Qnil);
@@ -436,14 +390,12 @@ invoke it. If KEYS is omitted or nil, the return value of
436 } 390 }
437 /* Ignore this for semi-compatibility with Lucid. */ 391 /* Ignore this for semi-compatibility with Lucid. */
438 else if (*string == '-') 392 else if (*string == '-')
439 string++; 393 ;
440 else if (*string == '@') 394 else if (*string == '@')
441 { 395 {
442 Lisp_Object event, w; 396 Lisp_Object w, event = (next_event < key_count
443 397 ? AREF (keys, next_event)
444 event = (next_event < key_count 398 : Qnil);
445 ? AREF (keys, next_event)
446 : Qnil);
447 if (EVENT_HAS_PARAMETERS (event) 399 if (EVENT_HAS_PARAMETERS (event)
448 && (w = XCDR (event), CONSP (w)) 400 && (w = XCDR (event), CONSP (w))
449 && (w = XCAR (w), CONSP (w)) 401 && (w = XCAR (w), CONSP (w))
@@ -458,32 +410,23 @@ invoke it. If KEYS is omitted or nil, the return value of
458 410
459 Fselect_window (w, Qnil); 411 Fselect_window (w, Qnil);
460 } 412 }
461 string++;
462 } 413 }
463 else if (*string == '^') 414 else if (*string == '^')
464 { 415 call0 (Qhandle_shift_selection);
465 call0 (Qhandle_shift_selection);
466 string++;
467 }
468 else break; 416 else break;
469 } 417 }
470 418
471 /* Count the number of arguments, which is two (the function itself and 419 /* Count the number of arguments, which is two (the function itself and
472 `funcall-interactively') plus the number of arguments the interactive spec 420 `funcall-interactively') plus the number of arguments the interactive spec
473 would have us give to the function. */ 421 would have us give to the function. */
474 tem = string; 422 ptrdiff_t nargs = 2;
475 for (nargs = 2; tem < string_end; ) 423 for (char const *tem = string; tem < string_end; tem++)
476 { 424 {
477 /* 'r' specifications ("point and mark as 2 numeric args") 425 /* 'r' specifications ("point and mark as 2 numeric args")
478 produce *two* arguments. */ 426 produce *two* arguments. */
479 if (*tem == 'r') 427 nargs += 1 + (*tem == 'r');
480 nargs += 2;
481 else
482 nargs++;
483 tem = memchr (tem, '\n', string_len - (tem - string)); 428 tem = memchr (tem, '\n', string_len - (tem - string));
484 if (tem) 429 if (!tem)
485 ++tem;
486 else
487 break; 430 break;
488 } 431 }
489 432
@@ -491,11 +434,18 @@ invoke it. If KEYS is omitted or nil, the return value of
491 && MOST_POSITIVE_FIXNUM < nargs) 434 && MOST_POSITIVE_FIXNUM < nargs)
492 memory_full (SIZE_MAX); 435 memory_full (SIZE_MAX);
493 436
494 /* Allocate them all at one go. This wastes a bit of memory, but 437 /* ARGS will contain the array of arguments to pass to the function.
438 VISARGS will contain the same list but in a nicer form, so that if we
439 pass it to Fformat_message it will be understandable to a human.
440 Allocate them all at one go. This wastes a bit of memory, but
495 it's OK to trade space for speed. */ 441 it's OK to trade space for speed. */
442 Lisp_Object *args;
496 SAFE_NALLOCA (args, 3, nargs); 443 SAFE_NALLOCA (args, 3, nargs);
497 visargs = args + nargs; 444 Lisp_Object *visargs = args + nargs;
498 varies = (signed char *) (visargs + nargs); 445 /* If varies[I] > 0, the Ith argument shouldn't just have its value
446 in this call quoted in the command history. It should be
447 recorded as a call to the function named callint_argfuns[varies[I]]. */
448 signed char *varies = (signed char *) (visargs + nargs);
499 449
500 memclear (args, nargs * (2 * word_size + 1)); 450 memclear (args, nargs * (2 * word_size + 1));
501 args = ptr_bounds_clip (args, nargs * sizeof *args); 451 args = ptr_bounds_clip (args, nargs * sizeof *args);
@@ -505,8 +455,8 @@ invoke it. If KEYS is omitted or nil, the return value of
505 if (!NILP (enable)) 455 if (!NILP (enable))
506 specbind (Qenable_recursive_minibuffers, Qt); 456 specbind (Qenable_recursive_minibuffers, Qt);
507 457
508 tem = string; 458 char const *tem = string;
509 for (i = 2; tem < string_end; i++) 459 for (ptrdiff_t i = 2; tem < string_end; i++)
510 { 460 {
511 char *pnl = memchr (tem + 1, '\n', string_len - (tem + 1 - string)); 461 char *pnl = memchr (tem + 1, '\n', string_len - (tem + 1 - string));
512 ptrdiff_t sz = pnl ? pnl - (tem + 1) : string_end - (tem + 1); 462 ptrdiff_t sz = pnl ? pnl - (tem + 1) : string_end - (tem + 1);
@@ -520,9 +470,7 @@ invoke it. If KEYS is omitted or nil, the return value of
520 visargs[i] = Fcompleting_read (callint_message, 470 visargs[i] = Fcompleting_read (callint_message,
521 Vobarray, Qfboundp, Qt, 471 Vobarray, Qfboundp, Qt,
522 Qnil, Qnil, Qnil, Qnil); 472 Qnil, Qnil, Qnil, Qnil);
523 /* Passing args[i] directly stimulates compiler bug. */ 473 args[i] = Fintern (visargs[i], Qnil);
524 teml = visargs[i];
525 args[i] = Fintern (teml, Qnil);
526 break; 474 break;
527 475
528 case 'b': /* Name of existing buffer. */ 476 case 'b': /* Name of existing buffer. */
@@ -534,7 +482,8 @@ invoke it. If KEYS is omitted or nil, the return value of
534 482
535 case 'B': /* Name of buffer, possibly nonexistent. */ 483 case 'B': /* Name of buffer, possibly nonexistent. */
536 args[i] = Fread_buffer (callint_message, 484 args[i] = Fread_buffer (callint_message,
537 Fother_buffer (Fcurrent_buffer (), Qnil, Qnil), 485 Fother_buffer (Fcurrent_buffer (),
486 Qnil, Qnil),
538 Qnil, Qnil); 487 Qnil, Qnil);
539 break; 488 break;
540 489
@@ -545,20 +494,17 @@ invoke it. If KEYS is omitted or nil, the return value of
545 Qface, Qminibuffer_prompt, callint_message); 494 Qface, Qminibuffer_prompt, callint_message);
546 args[i] = Fread_char (callint_message, Qnil, Qnil); 495 args[i] = Fread_char (callint_message, Qnil, Qnil);
547 message1_nolog (0); 496 message1_nolog (0);
548 /* Passing args[i] directly stimulates compiler bug. */
549 teml = args[i];
550 /* See bug#8479. */ 497 /* See bug#8479. */
551 if (! CHARACTERP (teml)) error ("Non-character input-event"); 498 if (! CHARACTERP (args[i]))
552 visargs[i] = Fchar_to_string (teml); 499 error ("Non-character input-event");
500 visargs[i] = Fchar_to_string (args[i]);
553 break; 501 break;
554 502
555 case 'C': /* Command: symbol with interactive function. */ 503 case 'C': /* Command: symbol with interactive function. */
556 visargs[i] = Fcompleting_read (callint_message, 504 visargs[i] = Fcompleting_read (callint_message,
557 Vobarray, Qcommandp, 505 Vobarray, Qcommandp,
558 Qt, Qnil, Qnil, Qnil, Qnil); 506 Qt, Qnil, Qnil, Qnil, Qnil);
559 /* Passing args[i] directly stimulates compiler bug. */ 507 args[i] = Fintern (visargs[i], Qnil);
560 teml = visargs[i];
561 args[i] = Fintern (teml, Qnil);
562 break; 508 break;
563 509
564 case 'd': /* Value of point. Does not do I/O. */ 510 case 'd': /* Value of point. Does not do I/O. */
@@ -569,8 +515,8 @@ invoke it. If KEYS is omitted or nil, the return value of
569 break; 515 break;
570 516
571 case 'D': /* Directory name. */ 517 case 'D': /* Directory name. */
572 args[i] = read_file_name (BVAR (current_buffer, directory), Qlambda, Qnil, 518 args[i] = read_file_name (BVAR (current_buffer, directory), Qlambda,
573 Qfile_directory_p); 519 Qnil, Qfile_directory_p);
574 break; 520 break;
575 521
576 case 'f': /* Existing file name. */ 522 case 'f': /* Existing file name. */
@@ -601,21 +547,19 @@ invoke it. If KEYS is omitted or nil, the return value of
601 args[i] = Fread_key_sequence (callint_message, 547 args[i] = Fread_key_sequence (callint_message,
602 Qnil, Qnil, Qnil, Qnil); 548 Qnil, Qnil, Qnil, Qnil);
603 unbind_to (speccount1, Qnil); 549 unbind_to (speccount1, Qnil);
604 teml = args[i]; 550 visargs[i] = Fkey_description (args[i], Qnil);
605 visargs[i] = Fkey_description (teml, Qnil);
606 551
607 /* If the key sequence ends with a down-event, 552 /* If the key sequence ends with a down-event,
608 discard the following up-event. */ 553 discard the following up-event. */
609 teml = Faref (args[i], make_number (XINT (Flength (args[i])) - 1)); 554 Lisp_Object teml
555 = Faref (args[i], make_number (XINT (Flength (args[i])) - 1));
610 if (CONSP (teml)) 556 if (CONSP (teml))
611 teml = XCAR (teml); 557 teml = XCAR (teml);
612 if (SYMBOLP (teml)) 558 if (SYMBOLP (teml))
613 { 559 {
614 Lisp_Object tem2;
615
616 teml = Fget (teml, Qevent_symbol_elements); 560 teml = Fget (teml, Qevent_symbol_elements);
617 /* Ignore first element, which is the base key. */ 561 /* Ignore first element, which is the base key. */
618 tem2 = Fmemq (Qdown, Fcdr (teml)); 562 Lisp_Object tem2 = Fmemq (Qdown, Fcdr (teml));
619 if (! NILP (tem2)) 563 if (! NILP (tem2))
620 up_event = Fread_event (Qnil, Qnil, Qnil); 564 up_event = Fread_event (Qnil, Qnil, Qnil);
621 } 565 }
@@ -632,22 +576,20 @@ invoke it. If KEYS is omitted or nil, the return value of
632 Qface, Qminibuffer_prompt, callint_message); 576 Qface, Qminibuffer_prompt, callint_message);
633 args[i] = Fread_key_sequence_vector (callint_message, 577 args[i] = Fread_key_sequence_vector (callint_message,
634 Qnil, Qt, Qnil, Qnil); 578 Qnil, Qt, Qnil, Qnil);
635 teml = args[i]; 579 visargs[i] = Fkey_description (args[i], Qnil);
636 visargs[i] = Fkey_description (teml, Qnil);
637 unbind_to (speccount1, Qnil); 580 unbind_to (speccount1, Qnil);
638 581
639 /* If the key sequence ends with a down-event, 582 /* If the key sequence ends with a down-event,
640 discard the following up-event. */ 583 discard the following up-event. */
641 teml = Faref (args[i], make_number (XINT (Flength (args[i])) - 1)); 584 Lisp_Object teml
585 = Faref (args[i], make_number (XINT (Flength (args[i])) - 1));
642 if (CONSP (teml)) 586 if (CONSP (teml))
643 teml = XCAR (teml); 587 teml = XCAR (teml);
644 if (SYMBOLP (teml)) 588 if (SYMBOLP (teml))
645 { 589 {
646 Lisp_Object tem2;
647
648 teml = Fget (teml, Qevent_symbol_elements); 590 teml = Fget (teml, Qevent_symbol_elements);
649 /* Ignore first element, which is the base key. */ 591 /* Ignore first element, which is the base key. */
650 tem2 = Fmemq (Qdown, Fcdr (teml)); 592 Lisp_Object tem2 = Fmemq (Qdown, Fcdr (teml));
651 if (! NILP (tem2)) 593 if (! NILP (tem2))
652 up_event = Fread_event (Qnil, Qnil, Qnil); 594 up_event = Fread_event (Qnil, Qnil, Qnil);
653 } 595 }
@@ -659,8 +601,7 @@ invoke it. If KEYS is omitted or nil, the return value of
659 { 601 {
660 args[i] = Fmake_vector (make_number (1), up_event); 602 args[i] = Fmake_vector (make_number (1), up_event);
661 up_event = Qnil; 603 up_event = Qnil;
662 teml = args[i]; 604 visargs[i] = Fkey_description (args[i], Qnil);
663 visargs[i] = Fkey_description (teml, Qnil);
664 } 605 }
665 break; 606 break;
666 607
@@ -671,18 +612,18 @@ invoke it. If KEYS is omitted or nil, the return value of
671 ? SSDATA (SYMBOL_NAME (function)) 612 ? SSDATA (SYMBOL_NAME (function))
672 : "command")); 613 : "command"));
673 args[i] = AREF (keys, next_event); 614 args[i] = AREF (keys, next_event);
674 next_event++;
675 varies[i] = -1; 615 varies[i] = -1;
676 616
677 /* Find the next parameterized event. */ 617 /* Find the next parameterized event. */
678 while (next_event < key_count 618 do
679 && !(EVENT_HAS_PARAMETERS (AREF (keys, next_event))))
680 next_event++; 619 next_event++;
620 while (next_event < key_count
621 && ! EVENT_HAS_PARAMETERS (AREF (keys, next_event)));
681 622
682 break; 623 break;
683 624
684 case 'm': /* Value of mark. Does not do I/O. */ 625 case 'm': /* Value of mark. Does not do I/O. */
685 check_mark (0); 626 check_mark (false);
686 /* visargs[i] = Qnil; */ 627 /* visargs[i] = Qnil; */
687 args[i] = BVAR (current_buffer, mark); 628 args[i] = BVAR (current_buffer, mark);
688 varies[i] = 2; 629 varies[i] = 2;
@@ -700,9 +641,7 @@ invoke it. If KEYS is omitted or nil, the return value of
700 FALLTHROUGH; 641 FALLTHROUGH;
701 case 'n': /* Read number from minibuffer. */ 642 case 'n': /* Read number from minibuffer. */
702 args[i] = call1 (Qread_number, callint_message); 643 args[i] = call1 (Qread_number, callint_message);
703 /* Passing args[i] directly stimulates compiler bug. */ 644 visargs[i] = Fnumber_to_string (args[i]);
704 teml = args[i];
705 visargs[i] = Fnumber_to_string (teml);
706 break; 645 break;
707 646
708 case 'P': /* Prefix arg in raw form. Does no I/O. */ 647 case 'P': /* Prefix arg in raw form. Does no I/O. */
@@ -719,15 +658,16 @@ invoke it. If KEYS is omitted or nil, the return value of
719 break; 658 break;
720 659
721 case 'r': /* Region, point and mark as 2 args. */ 660 case 'r': /* Region, point and mark as 2 args. */
722 check_mark (1); 661 {
723 set_marker_both (point_marker, Qnil, PT, PT_BYTE); 662 check_mark (true);
724 /* visargs[i+1] = Qnil; */ 663 set_marker_both (point_marker, Qnil, PT, PT_BYTE);
725 mark = marker_position (BVAR (current_buffer, mark)); 664 ptrdiff_t mark = marker_position (BVAR (current_buffer, mark));
726 /* visargs[i] = Qnil; */ 665 /* visargs[i] = visargs[i + 1] = Qnil; */
727 args[i] = PT < mark ? point_marker : BVAR (current_buffer, mark); 666 args[i] = PT < mark ? point_marker : BVAR (current_buffer, mark);
728 varies[i] = 3; 667 varies[i] = 3;
729 args[++i] = PT > mark ? point_marker : BVAR (current_buffer, mark); 668 args[++i] = PT > mark ? point_marker : BVAR (current_buffer, mark);
730 varies[i] = 4; 669 varies[i] = 4;
670 }
731 break; 671 break;
732 672
733 case 's': /* String read via minibuffer without 673 case 's': /* String read via minibuffer without
@@ -739,9 +679,7 @@ invoke it. If KEYS is omitted or nil, the return value of
739 case 'S': /* Any symbol. */ 679 case 'S': /* Any symbol. */
740 visargs[i] = Fread_string (callint_message, 680 visargs[i] = Fread_string (callint_message,
741 Qnil, Qnil, Qnil, Qnil); 681 Qnil, Qnil, Qnil, Qnil);
742 /* Passing args[i] directly stimulates compiler bug. */ 682 args[i] = Fintern (visargs[i], Qnil);
743 teml = visargs[i];
744 args[i] = Fintern (teml, Qnil);
745 break; 683 break;
746 684
747 case 'v': /* Variable name: symbol that is 685 case 'v': /* Variable name: symbol that is
@@ -798,13 +736,14 @@ invoke it. If KEYS is omitted or nil, the return value of
798 else 736 else
799 letter = *((unsigned char *) tem); 737 letter = *((unsigned char *) tem);
800 738
801 error ("Invalid control letter `%c' (#o%03o, #x%04x) in interactive calling string", 739 error (("Invalid control letter `%c' (#o%03o, #x%04x)"
740 " in interactive calling string"),
802 (int) letter, letter, letter); 741 (int) letter, letter, letter);
803 } 742 }
804 } 743 }
805 744
806 if (varies[i] == 0) 745 if (varies[i] == 0)
807 arg_from_tty = 1; 746 arg_from_tty = true;
808 747
809 if (NILP (visargs[i]) && STRINGP (args[i])) 748 if (NILP (visargs[i]) && STRINGP (args[i]))
810 visargs[i] = args[i]; 749 visargs[i] = args[i];
@@ -825,19 +764,16 @@ invoke it. If KEYS is omitted or nil, the return value of
825 /* We don't need `visargs' any more, so let's recycle it since we need 764 /* We don't need `visargs' any more, so let's recycle it since we need
826 an array of just the same size. */ 765 an array of just the same size. */
827 visargs[1] = function; 766 visargs[1] = function;
828 for (i = 2; i < nargs; i++) 767 for (ptrdiff_t i = 2; i < nargs; i++)
829 { 768 visargs[i] = (varies[i] > 0
830 if (varies[i] > 0) 769 ? list1 (intern (callint_argfuns[varies[i]]))
831 visargs[i] = list1 (intern (callint_argfuns[varies[i]])); 770 : quotify_arg (args[i]));
832 else
833 visargs[i] = quotify_arg (args[i]);
834 }
835 Vcommand_history = Fcons (Flist (nargs - 1, visargs + 1), 771 Vcommand_history = Fcons (Flist (nargs - 1, visargs + 1),
836 Vcommand_history); 772 Vcommand_history);
837 /* Don't keep command history around forever. */ 773 /* Don't keep command history around forever. */
838 if (INTEGERP (Vhistory_length) && XINT (Vhistory_length) > 0) 774 if (INTEGERP (Vhistory_length) && XINT (Vhistory_length) > 0)
839 { 775 {
840 teml = Fnthcdr (Vhistory_length, Vcommand_history); 776 Lisp_Object teml = Fnthcdr (Vhistory_length, Vcommand_history);
841 if (CONSP (teml)) 777 if (CONSP (teml))
842 XSETCDR (teml, Qnil); 778 XSETCDR (teml, Qnil);
843 } 779 }
@@ -845,7 +781,7 @@ invoke it. If KEYS is omitted or nil, the return value of
845 781
846 /* If we used a marker to hold point, mark, or an end of the region, 782 /* If we used a marker to hold point, mark, or an end of the region,
847 temporarily, convert it to an integer now. */ 783 temporarily, convert it to an integer now. */
848 for (i = 2; i < nargs; i++) 784 for (ptrdiff_t i = 2; i < nargs; i++)
849 if (varies[i] >= 1 && varies[i] <= 4) 785 if (varies[i] >= 1 && varies[i] <= 4)
850 XSETINT (args[i], marker_position (args[i])); 786 XSETINT (args[i], marker_position (args[i]));
851 787
@@ -857,15 +793,11 @@ invoke it. If KEYS is omitted or nil, the return value of
857 Vreal_this_command = save_real_this_command; 793 Vreal_this_command = save_real_this_command;
858 kset_last_command (current_kboard, save_last_command); 794 kset_last_command (current_kboard, save_last_command);
859 795
860 { 796 specbind (Qcommand_debug_status, Qnil);
861 Lisp_Object val;
862 specbind (Qcommand_debug_status, Qnil);
863 797
864 val = Ffuncall (nargs, args); 798 Lisp_Object val = Ffuncall (nargs, args);
865 val = unbind_to (speccount, val); 799 SAFE_FREE ();
866 SAFE_FREE (); 800 return unbind_to (speccount, val);
867 return val;
868 }
869} 801}
870 802
871DEFUN ("prefix-numeric-value", Fprefix_numeric_value, Sprefix_numeric_value, 803DEFUN ("prefix-numeric-value", Fprefix_numeric_value, Sprefix_numeric_value,