comparison src/callint.c @ 73441:82ed0adffca9

* callint.c (callint_message): Convert to a Lisp string. (syms_of_callint): Initialize it. (callint_message_size): Var deleted. (Fcall_interactively): Use Fformat instead of doprnt to construct prompt string.
author Chong Yidong <cyd@stupidchicken.com>
date Thu, 19 Oct 2006 14:13:52 +0000
parents 6d481bdb9779
children 4c1d868b634b 034f67f59091 7eeafaaa9eab
comparison
equal deleted inserted replaced
73440:334af48d9710 73441:82ed0adffca9
56 static Lisp_Object preserved_fns; 56 static Lisp_Object preserved_fns;
57 57
58 /* Marker used within call-interactively to refer to point. */ 58 /* Marker used within call-interactively to refer to point. */
59 static Lisp_Object point_marker; 59 static Lisp_Object point_marker;
60 60
61 /* Buffer for the prompt text used in Fcall_interactively. */ 61 /* String for the prompt text used in Fcall_interactively. */
62 static char *callint_message; 62 static Lisp_Object callint_message;
63
64 /* Allocated length of that buffer. */
65 static int callint_message_size;
66 63
67 /* ARGSUSED */ 64 /* ARGSUSED */
68 DEFUN ("interactive", Finteractive, Sinteractive, 0, UNEVALLED, 0, 65 DEFUN ("interactive", Finteractive, Sinteractive, 0, UNEVALLED, 0,
69 doc: /* Specify a way of parsing arguments for interactive use of a function. 66 doc: /* Specify a way of parsing arguments for interactive use of a function.
70 For example, write 67 For example, write
264 `this-command-keys-vector' is used. */) 261 `this-command-keys-vector' is used. */)
265 (function, record_flag, keys) 262 (function, record_flag, keys)
266 Lisp_Object function, record_flag, keys; 263 Lisp_Object function, record_flag, keys;
267 { 264 {
268 Lisp_Object *args, *visargs; 265 Lisp_Object *args, *visargs;
269 unsigned char **argstrings;
270 Lisp_Object fun; 266 Lisp_Object fun;
271 Lisp_Object specs; 267 Lisp_Object specs;
272 Lisp_Object filter_specs; 268 Lisp_Object filter_specs;
273 Lisp_Object teml; 269 Lisp_Object teml;
274 Lisp_Object up_event; 270 Lisp_Object up_event;
490 } 486 }
491 count = j; 487 count = j;
492 488
493 args = (Lisp_Object *) alloca ((count + 1) * sizeof (Lisp_Object)); 489 args = (Lisp_Object *) alloca ((count + 1) * sizeof (Lisp_Object));
494 visargs = (Lisp_Object *) alloca ((count + 1) * sizeof (Lisp_Object)); 490 visargs = (Lisp_Object *) alloca ((count + 1) * sizeof (Lisp_Object));
495 argstrings = (unsigned char **) alloca ((count + 1) * sizeof (char *));
496 varies = (int *) alloca ((count + 1) * sizeof (int)); 491 varies = (int *) alloca ((count + 1) * sizeof (int));
497 492
498 for (i = 0; i < (count + 1); i++) 493 for (i = 0; i < (count + 1); i++)
499 { 494 {
500 args[i] = Qnil; 495 args[i] = Qnil;
514 { 509 {
515 strncpy (prompt1, tem + 1, sizeof prompt1 - 1); 510 strncpy (prompt1, tem + 1, sizeof prompt1 - 1);
516 prompt1[sizeof prompt1 - 1] = 0; 511 prompt1[sizeof prompt1 - 1] = 0;
517 tem1 = (char *) index (prompt1, '\n'); 512 tem1 = (char *) index (prompt1, '\n');
518 if (tem1) *tem1 = 0; 513 if (tem1) *tem1 = 0;
519 /* Fill argstrings with a vector of C strings 514
520 corresponding to the Lisp strings in visargs. */ 515 visargs[0] = build_string (prompt1);
521 for (j = 1; j < i; j++) 516 if (index (prompt1, '%'))
522 argstrings[j] 517 callint_message = Fformat (i, visargs);
523 = (EQ (visargs[j], Qnil) 518 else
524 ? (unsigned char *) "" 519 callint_message = visargs[0];
525 : SDATA (visargs[j]));
526
527 /* Process the format-string in prompt1, putting the output
528 into callint_message. Make callint_message bigger if necessary.
529 We don't use a buffer on the stack, because the contents
530 need to stay stable for a while. */
531 while (1)
532 {
533 int nchars = doprnt (callint_message, callint_message_size,
534 prompt1, (char *)0,
535 j - 1, (char **) argstrings + 1);
536 if (nchars < callint_message_size - 1)
537 break;
538 callint_message_size *= 2;
539 callint_message
540 = (char *) xrealloc (callint_message, callint_message_size);
541 }
542 520
543 switch (*tem) 521 switch (*tem)
544 { 522 {
545 case 'a': /* Symbol defined as a function */ 523 case 'a': /* Symbol defined as a function */
546 visargs[i] = Fcompleting_read (build_string (callint_message), 524 visargs[i] = Fcompleting_read (callint_message,
547 Vobarray, Qfboundp, Qt, 525 Vobarray, Qfboundp, Qt,
548 Qnil, Qnil, Qnil, Qnil); 526 Qnil, Qnil, Qnil, Qnil);
549 /* Passing args[i] directly stimulates compiler bug */ 527 /* Passing args[i] directly stimulates compiler bug */
550 teml = visargs[i]; 528 teml = visargs[i];
551 args[i] = Fintern (teml, Qnil); 529 args[i] = Fintern (teml, Qnil);
553 531
554 case 'b': /* Name of existing buffer */ 532 case 'b': /* Name of existing buffer */
555 args[i] = Fcurrent_buffer (); 533 args[i] = Fcurrent_buffer ();
556 if (EQ (selected_window, minibuf_window)) 534 if (EQ (selected_window, minibuf_window))
557 args[i] = Fother_buffer (args[i], Qnil, Qnil); 535 args[i] = Fother_buffer (args[i], Qnil, Qnil);
558 args[i] = Fread_buffer (build_string (callint_message), args[i], Qt); 536 args[i] = Fread_buffer (callint_message, args[i], Qt);
559 break; 537 break;
560 538
561 case 'B': /* Name of buffer, possibly nonexistent */ 539 case 'B': /* Name of buffer, possibly nonexistent */
562 args[i] = Fread_buffer (build_string (callint_message), 540 args[i] = Fread_buffer (callint_message,
563 Fother_buffer (Fcurrent_buffer (), Qnil, Qnil), 541 Fother_buffer (Fcurrent_buffer (), Qnil, Qnil),
564 Qnil); 542 Qnil);
565 break; 543 break;
566 544
567 case 'c': /* Character */ 545 case 'c': /* Character */
568 args[i] = Fread_char (build_string (callint_message), Qnil, Qnil); 546 args[i] = Fread_char (callint_message, Qnil, Qnil);
569 message1_nolog ((char *) 0); 547 message1_nolog ((char *) 0);
570 /* Passing args[i] directly stimulates compiler bug */ 548 /* Passing args[i] directly stimulates compiler bug */
571 teml = args[i]; 549 teml = args[i];
572 visargs[i] = Fchar_to_string (teml); 550 visargs[i] = Fchar_to_string (teml);
573 break; 551 break;
574 552
575 case 'C': /* Command: symbol with interactive function */ 553 case 'C': /* Command: symbol with interactive function */
576 visargs[i] = Fcompleting_read (build_string (callint_message), 554 visargs[i] = Fcompleting_read (callint_message,
577 Vobarray, Qcommandp, 555 Vobarray, Qcommandp,
578 Qt, Qnil, Qnil, Qnil, Qnil); 556 Qt, Qnil, Qnil, Qnil, Qnil);
579 /* Passing args[i] directly stimulates compiler bug */ 557 /* Passing args[i] directly stimulates compiler bug */
580 teml = visargs[i]; 558 teml = visargs[i];
581 args[i] = Fintern (teml, Qnil); 559 args[i] = Fintern (teml, Qnil);
587 /* visargs[i] = Qnil; */ 565 /* visargs[i] = Qnil; */
588 varies[i] = 1; 566 varies[i] = 1;
589 break; 567 break;
590 568
591 case 'D': /* Directory name. */ 569 case 'D': /* Directory name. */
592 args[i] = Fread_file_name (build_string (callint_message), Qnil, 570 args[i] = Fread_file_name (callint_message, Qnil,
593 current_buffer->directory, Qlambda, Qnil, 571 current_buffer->directory, Qlambda, Qnil,
594 Qfile_directory_p); 572 Qfile_directory_p);
595 break; 573 break;
596 574
597 case 'f': /* Existing file name. */ 575 case 'f': /* Existing file name. */
598 args[i] = Fread_file_name (build_string (callint_message), 576 args[i] = Fread_file_name (callint_message,
599 Qnil, Qnil, Qlambda, Qnil, Qnil); 577 Qnil, Qnil, Qlambda, Qnil, Qnil);
600 break; 578 break;
601 579
602 case 'F': /* Possibly nonexistent file name. */ 580 case 'F': /* Possibly nonexistent file name. */
603 args[i] = Fread_file_name (build_string (callint_message), 581 args[i] = Fread_file_name (callint_message,
604 Qnil, Qnil, Qnil, Qnil, Qnil); 582 Qnil, Qnil, Qnil, Qnil, Qnil);
605 break; 583 break;
606 584
607 case 'G': /* Possibly nonexistent file name, 585 case 'G': /* Possibly nonexistent file name,
608 default to directory alone. */ 586 default to directory alone. */
609 args[i] = Fread_file_name (build_string (callint_message), 587 args[i] = Fread_file_name (callint_message,
610 Qnil, Qnil, Qnil, build_string (""), Qnil); 588 Qnil, Qnil, Qnil, build_string (""), Qnil);
611 break; 589 break;
612 590
613 case 'i': /* Ignore an argument -- Does not do I/O */ 591 case 'i': /* Ignore an argument -- Does not do I/O */
614 varies[i] = -1; 592 varies[i] = -1;
616 594
617 case 'k': /* Key sequence. */ 595 case 'k': /* Key sequence. */
618 { 596 {
619 int speccount1 = SPECPDL_INDEX (); 597 int speccount1 = SPECPDL_INDEX ();
620 specbind (Qcursor_in_echo_area, Qt); 598 specbind (Qcursor_in_echo_area, Qt);
621 args[i] = Fread_key_sequence (build_string (callint_message), 599 args[i] = Fread_key_sequence (callint_message,
622 Qnil, Qnil, Qnil, Qnil); 600 Qnil, Qnil, Qnil, Qnil);
623 unbind_to (speccount1, Qnil); 601 unbind_to (speccount1, Qnil);
624 teml = args[i]; 602 teml = args[i];
625 visargs[i] = Fkey_description (teml, Qnil); 603 visargs[i] = Fkey_description (teml, Qnil);
626 604
644 622
645 case 'K': /* Key sequence to be defined. */ 623 case 'K': /* Key sequence to be defined. */
646 { 624 {
647 int speccount1 = SPECPDL_INDEX (); 625 int speccount1 = SPECPDL_INDEX ();
648 specbind (Qcursor_in_echo_area, Qt); 626 specbind (Qcursor_in_echo_area, Qt);
649 args[i] = Fread_key_sequence (build_string (callint_message), 627 args[i] = Fread_key_sequence (callint_message,
650 Qnil, Qt, Qnil, Qnil); 628 Qnil, Qt, Qnil, Qnil);
651 teml = args[i]; 629 teml = args[i];
652 visargs[i] = Fkey_description (teml, Qnil); 630 visargs[i] = Fkey_description (teml, Qnil);
653 unbind_to (speccount1, Qnil); 631 unbind_to (speccount1, Qnil);
654 632
704 varies[i] = 2; 682 varies[i] = 2;
705 break; 683 break;
706 684
707 case 'M': /* String read via minibuffer with 685 case 'M': /* String read via minibuffer with
708 inheriting the current input method. */ 686 inheriting the current input method. */
709 args[i] = Fread_string (build_string (callint_message), 687 args[i] = Fread_string (callint_message,
710 Qnil, Qnil, Qnil, Qt); 688 Qnil, Qnil, Qnil, Qt);
711 break; 689 break;
712 690
713 case 'N': /* Prefix arg, else number from minibuffer */ 691 case 'N': /* Prefix arg, else number from minibuffer */
714 if (!NILP (prefix_arg)) 692 if (!NILP (prefix_arg))
724 message ("Please enter a number."); 702 message ("Please enter a number.");
725 sit_for (make_number (1), 0, 0); 703 sit_for (make_number (1), 0, 0);
726 } 704 }
727 first = 0; 705 first = 0;
728 706
729 tem = Fread_from_minibuffer (build_string (callint_message), 707 tem = Fread_from_minibuffer (callint_message,
730 Qnil, Qnil, Qnil, Qnil, Qnil, 708 Qnil, Qnil, Qnil, Qnil, Qnil,
731 Qnil); 709 Qnil);
732 if (! STRINGP (tem) || SCHARS (tem) == 0) 710 if (! STRINGP (tem) || SCHARS (tem) == 0)
733 args[i] = Qnil; 711 args[i] = Qnil;
734 else 712 else
735 args[i] = Fread (tem); 713 args[i] = Fread (tem);
736 } 714 }
737 while (! NUMBERP (args[i])); 715 while (! NUMBERP (args[i]));
738 } 716 }
739 visargs[i] = last_minibuf_string; 717 visargs[i] = args[i];
740 break; 718 break;
741 719
742 case 'P': /* Prefix arg in raw form. Does no I/O. */ 720 case 'P': /* Prefix arg in raw form. Does no I/O. */
743 args[i] = prefix_arg; 721 args[i] = prefix_arg;
744 /* visargs[i] = Qnil; */ 722 /* visargs[i] = Qnil; */
764 varies[i] = 4; 742 varies[i] = 4;
765 break; 743 break;
766 744
767 case 's': /* String read via minibuffer without 745 case 's': /* String read via minibuffer without
768 inheriting the current input method. */ 746 inheriting the current input method. */
769 args[i] = Fread_string (build_string (callint_message), 747 args[i] = Fread_string (callint_message,
770 Qnil, Qnil, Qnil, Qnil); 748 Qnil, Qnil, Qnil, Qnil);
771 break; 749 break;
772 750
773 case 'S': /* Any symbol. */ 751 case 'S': /* Any symbol. */
774 visargs[i] = Fread_string (build_string (callint_message), 752 visargs[i] = Fread_string (callint_message,
775 Qnil, Qnil, Qnil, Qnil); 753 Qnil, Qnil, Qnil, Qnil);
776 /* Passing args[i] directly stimulates compiler bug */ 754 /* Passing args[i] directly stimulates compiler bug */
777 teml = visargs[i]; 755 teml = visargs[i];
778 args[i] = Fintern (teml, Qnil); 756 args[i] = Fintern (teml, Qnil);
779 break; 757 break;
780 758
781 case 'v': /* Variable name: symbol that is 759 case 'v': /* Variable name: symbol that is
782 user-variable-p. */ 760 user-variable-p. */
783 args[i] = Fread_variable (build_string (callint_message), Qnil); 761 args[i] = Fread_variable (callint_message, Qnil);
784 visargs[i] = last_minibuf_string; 762 visargs[i] = last_minibuf_string;
785 break; 763 break;
786 764
787 case 'x': /* Lisp expression read but not evaluated */ 765 case 'x': /* Lisp expression read but not evaluated */
788 args[i] = Fread_minibuffer (build_string (callint_message), Qnil); 766 args[i] = Fread_minibuffer (callint_message, Qnil);
789 visargs[i] = last_minibuf_string; 767 visargs[i] = last_minibuf_string;
790 break; 768 break;
791 769
792 case 'X': /* Lisp expression read and evaluated */ 770 case 'X': /* Lisp expression read and evaluated */
793 args[i] = Feval_minibuffer (build_string (callint_message), Qnil); 771 args[i] = Feval_minibuffer (callint_message, Qnil);
794 visargs[i] = last_minibuf_string; 772 visargs[i] = last_minibuf_string;
795 break; 773 break;
796 774
797 case 'Z': /* Coding-system symbol, or ignore the 775 case 'Z': /* Coding-system symbol, or ignore the
798 argument if no prefix */ 776 argument if no prefix */
802 varies[i] = -1; 780 varies[i] = -1;
803 } 781 }
804 else 782 else
805 { 783 {
806 args[i] 784 args[i]
807 = Fread_non_nil_coding_system (build_string (callint_message)); 785 = Fread_non_nil_coding_system (callint_message);
808 visargs[i] = last_minibuf_string; 786 visargs[i] = last_minibuf_string;
809 } 787 }
810 break; 788 break;
811 789
812 case 'z': /* Coding-system symbol or nil */ 790 case 'z': /* Coding-system symbol or nil */
813 args[i] = Fread_coding_system (build_string (callint_message), Qnil); 791 args[i] = Fread_coding_system (callint_message, Qnil);
814 visargs[i] = last_minibuf_string; 792 visargs[i] = last_minibuf_string;
815 break; 793 break;
816 794
817 /* We have a case for `+' so we get an error 795 /* We have a case for `+' so we get an error
818 if anyone tries to define one here. */ 796 if anyone tries to define one here. */
913 syms_of_callint () 891 syms_of_callint ()
914 { 892 {
915 point_marker = Fmake_marker (); 893 point_marker = Fmake_marker ();
916 staticpro (&point_marker); 894 staticpro (&point_marker);
917 895
896 callint_message = Qnil;
897 staticpro (&callint_message);
898
918 preserved_fns = Fcons (intern ("region-beginning"), 899 preserved_fns = Fcons (intern ("region-beginning"),
919 Fcons (intern ("region-end"), 900 Fcons (intern ("region-end"),
920 Fcons (intern ("point"), 901 Fcons (intern ("point"),
921 Fcons (intern ("mark"), Qnil)))); 902 Fcons (intern ("mark"), Qnil))));
922 staticpro (&preserved_fns); 903 staticpro (&preserved_fns);
952 staticpro (&Qenable_recursive_minibuffers); 933 staticpro (&Qenable_recursive_minibuffers);
953 934
954 Qmouse_leave_buffer_hook = intern ("mouse-leave-buffer-hook"); 935 Qmouse_leave_buffer_hook = intern ("mouse-leave-buffer-hook");
955 staticpro (&Qmouse_leave_buffer_hook); 936 staticpro (&Qmouse_leave_buffer_hook);
956 937
957 callint_message_size = 100;
958 callint_message = (char *) xmalloc (callint_message_size);
959
960
961 DEFVAR_KBOARD ("prefix-arg", Vprefix_arg, 938 DEFVAR_KBOARD ("prefix-arg", Vprefix_arg,
962 doc: /* The value of the prefix argument for the next editing command. 939 doc: /* The value of the prefix argument for the next editing command.
963 It may be a number, or the symbol `-' for just a minus sign as arg, 940 It may be a number, or the symbol `-' for just a minus sign as arg,
964 or a list whose car is a number for just one or more C-u's 941 or a list whose car is a number for just one or more C-u's
965 or nil if no argument has been specified. 942 or nil if no argument has been specified.