diff options
| author | Lars Ingebrigtsen | 2022-05-15 15:29:28 +0200 |
|---|---|---|
| committer | Lars Ingebrigtsen | 2022-05-15 15:29:38 +0200 |
| commit | aa95b2a47dce8cf74f70f43f72e35349782d1c74 (patch) | |
| tree | 169ef433c0b42ae69f09abf71e0d04c7c79ac925 /src | |
| parent | 22873b5415fbcc81f2d1e0e69cccd5dbeaac51ee (diff) | |
| download | emacs-aa95b2a47dce8cf74f70f43f72e35349782d1c74.tar.gz emacs-aa95b2a47dce8cf74f70f43f72e35349782d1c74.zip | |
Add OVERRIDES argument to prin1/prin1-to-string
* doc/lispref/streams.texi (Output Functions): Document it.
(Output Overrides): New node.
* src/process.c (Faccept_process_output):
* src/print.c (debug_print, print_error_message):
* src/pdumper.c (print_paths_to_root_1, decode_emacs_reloc):
* src/lread.c (readevalloop):
* src/eval.c (internal_lisp_condition_case):
* src/editfns.c (styled_format): Adjust prin1/prin1-to-string
callers.
* src/print.c (Fprin1): Take an OVERRIDES parameter.
(print_bind_overrides, print_bind_all_defaults): New functions.
(Fprin1_to_string): Take an OVERRIDES parameter.
Diffstat (limited to 'src')
| -rw-r--r-- | src/editfns.c | 2 | ||||
| -rw-r--r-- | src/eval.c | 2 | ||||
| -rw-r--r-- | src/lread.c | 2 | ||||
| -rw-r--r-- | src/pdumper.c | 4 | ||||
| -rw-r--r-- | src/print.c | 118 | ||||
| -rw-r--r-- | src/process.c | 2 |
6 files changed, 116 insertions, 14 deletions
diff --git a/src/editfns.c b/src/editfns.c index 6cb684d4d85..17f0252969e 100644 --- a/src/editfns.c +++ b/src/editfns.c | |||
| @@ -3327,7 +3327,7 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message) | |||
| 3327 | if (EQ (arg, args[n])) | 3327 | if (EQ (arg, args[n])) |
| 3328 | { | 3328 | { |
| 3329 | Lisp_Object noescape = conversion == 'S' ? Qnil : Qt; | 3329 | Lisp_Object noescape = conversion == 'S' ? Qnil : Qt; |
| 3330 | spec->argument = arg = Fprin1_to_string (arg, noescape); | 3330 | spec->argument = arg = Fprin1_to_string (arg, noescape, Qnil); |
| 3331 | if (STRING_MULTIBYTE (arg) && ! multibyte) | 3331 | if (STRING_MULTIBYTE (arg) && ! multibyte) |
| 3332 | { | 3332 | { |
| 3333 | multibyte = true; | 3333 | multibyte = true; |
diff --git a/src/eval.c b/src/eval.c index 29c122e2fb2..25ac8e45296 100644 --- a/src/eval.c +++ b/src/eval.c | |||
| @@ -1341,7 +1341,7 @@ internal_lisp_condition_case (Lisp_Object var, Lisp_Object bodyform, | |||
| 1341 | && (SYMBOLP (XCAR (tem)) | 1341 | && (SYMBOLP (XCAR (tem)) |
| 1342 | || CONSP (XCAR (tem)))))) | 1342 | || CONSP (XCAR (tem)))))) |
| 1343 | error ("Invalid condition handler: %s", | 1343 | error ("Invalid condition handler: %s", |
| 1344 | SDATA (Fprin1_to_string (tem, Qt))); | 1344 | SDATA (Fprin1_to_string (tem, Qt, Qnil))); |
| 1345 | if (CONSP (tem) && EQ (XCAR (tem), QCsuccess)) | 1345 | if (CONSP (tem) && EQ (XCAR (tem), QCsuccess)) |
| 1346 | success_handler = XCDR (tem); | 1346 | success_handler = XCDR (tem); |
| 1347 | else | 1347 | else |
diff --git a/src/lread.c b/src/lread.c index 409e97cdfa6..5f3d83a846b 100644 --- a/src/lread.c +++ b/src/lread.c | |||
| @@ -2349,7 +2349,7 @@ readevalloop (Lisp_Object readcharfun, | |||
| 2349 | { | 2349 | { |
| 2350 | Vvalues = Fcons (val, Vvalues); | 2350 | Vvalues = Fcons (val, Vvalues); |
| 2351 | if (EQ (Vstandard_output, Qt)) | 2351 | if (EQ (Vstandard_output, Qt)) |
| 2352 | Fprin1 (val, Qnil); | 2352 | Fprin1 (val, Qnil, Qnil); |
| 2353 | else | 2353 | else |
| 2354 | Fprint (val, Qnil); | 2354 | Fprint (val, Qnil); |
| 2355 | } | 2355 | } |
diff --git a/src/pdumper.c b/src/pdumper.c index 5923d9b1d82..88e7b311a89 100644 --- a/src/pdumper.c +++ b/src/pdumper.c | |||
| @@ -1383,7 +1383,7 @@ print_paths_to_root_1 (struct dump_context *ctx, | |||
| 1383 | { | 1383 | { |
| 1384 | Lisp_Object referrer = XCAR (referrers); | 1384 | Lisp_Object referrer = XCAR (referrers); |
| 1385 | referrers = XCDR (referrers); | 1385 | referrers = XCDR (referrers); |
| 1386 | Lisp_Object repr = Fprin1_to_string (referrer, Qnil); | 1386 | Lisp_Object repr = Fprin1_to_string (referrer, Qnil, Qnil); |
| 1387 | for (int i = 0; i < level; ++i) | 1387 | for (int i = 0; i < level; ++i) |
| 1388 | putc (' ', stderr); | 1388 | putc (' ', stderr); |
| 1389 | fwrite (SDATA (repr), 1, SBYTES (repr), stderr); | 1389 | fwrite (SDATA (repr), 1, SBYTES (repr), stderr); |
| @@ -3758,7 +3758,7 @@ decode_emacs_reloc (struct dump_context *ctx, Lisp_Object lreloc) | |||
| 3758 | reloc.u.dump_offset = dump_recall_object (ctx, target_value); | 3758 | reloc.u.dump_offset = dump_recall_object (ctx, target_value); |
| 3759 | if (reloc.u.dump_offset <= 0) | 3759 | if (reloc.u.dump_offset <= 0) |
| 3760 | { | 3760 | { |
| 3761 | Lisp_Object repr = Fprin1_to_string (target_value, Qnil); | 3761 | Lisp_Object repr = Fprin1_to_string (target_value, Qnil, Qnil); |
| 3762 | error ("relocation target was not dumped: %s", SDATA (repr)); | 3762 | error ("relocation target was not dumped: %s", SDATA (repr)); |
| 3763 | } | 3763 | } |
| 3764 | dump_check_dump_off (ctx, reloc.u.dump_offset); | 3764 | dump_check_dump_off (ctx, reloc.u.dump_offset); |
diff --git a/src/print.c b/src/print.c index d7583282b69..c9a9b868f9f 100644 --- a/src/print.c +++ b/src/print.c | |||
| @@ -620,7 +620,51 @@ If PRINTCHARFUN is omitted or nil, the value of `standard-output' is used. */) | |||
| 620 | return val; | 620 | return val; |
| 621 | } | 621 | } |
| 622 | 622 | ||
| 623 | DEFUN ("prin1", Fprin1, Sprin1, 1, 2, 0, | 623 | static void |
| 624 | print_bind_all_defaults (void) | ||
| 625 | { | ||
| 626 | for (Lisp_Object vars = Vprint__variable_mapping; !NILP (vars); | ||
| 627 | vars = XCDR (vars)) | ||
| 628 | { | ||
| 629 | Lisp_Object elem = XCDR (XCAR (vars)); | ||
| 630 | specbind (XCAR (elem), XCAR (XCDR (elem))); | ||
| 631 | } | ||
| 632 | } | ||
| 633 | |||
| 634 | static void | ||
| 635 | print_bind_overrides (Lisp_Object overrides) | ||
| 636 | { | ||
| 637 | if (EQ (overrides, Qt)) | ||
| 638 | print_bind_all_defaults (); | ||
| 639 | else if (!CONSP (overrides)) | ||
| 640 | xsignal (Qwrong_type_argument, Qconsp); | ||
| 641 | else | ||
| 642 | { | ||
| 643 | while (!NILP (overrides)) | ||
| 644 | { | ||
| 645 | Lisp_Object setting = XCAR (overrides); | ||
| 646 | if (EQ (setting, Qt)) | ||
| 647 | print_bind_all_defaults (); | ||
| 648 | else if (!CONSP (setting)) | ||
| 649 | xsignal (Qwrong_type_argument, Qconsp); | ||
| 650 | else | ||
| 651 | { | ||
| 652 | Lisp_Object key = XCAR (setting), | ||
| 653 | value = XCDR (setting); | ||
| 654 | Lisp_Object map = Fassq (key, Vprint__variable_mapping); | ||
| 655 | if (NILP (map)) | ||
| 656 | xsignal2 (Qwrong_type_argument, Qsymbolp, map); | ||
| 657 | specbind (XCAR (XCDR (map)), value); | ||
| 658 | } | ||
| 659 | |||
| 660 | if (!NILP (XCDR (overrides)) && !CONSP (XCDR (overrides))) | ||
| 661 | xsignal (Qwrong_type_argument, Qconsp); | ||
| 662 | overrides = XCDR (overrides); | ||
| 663 | } | ||
| 664 | } | ||
| 665 | } | ||
| 666 | |||
| 667 | DEFUN ("prin1", Fprin1, Sprin1, 1, 3, 0, | ||
| 624 | doc: /* Output the printed representation of OBJECT, any Lisp object. | 668 | doc: /* Output the printed representation of OBJECT, any Lisp object. |
| 625 | Quoting characters are printed when needed to make output that `read' | 669 | Quoting characters are printed when needed to make output that `read' |
| 626 | can handle, whenever this is possible. For complex objects, the behavior | 670 | can handle, whenever this is possible. For complex objects, the behavior |
| @@ -642,21 +686,43 @@ of these: | |||
| 642 | - t, in which case the output is displayed in the echo area. | 686 | - t, in which case the output is displayed in the echo area. |
| 643 | 687 | ||
| 644 | If PRINTCHARFUN is omitted, the value of `standard-output' (which see) | 688 | If PRINTCHARFUN is omitted, the value of `standard-output' (which see) |
| 645 | is used instead. */) | 689 | is used instead. |
| 646 | (Lisp_Object object, Lisp_Object printcharfun) | 690 | |
| 691 | OVERRIDES should be a list of settings. An element in this list be | ||
| 692 | the symbol t, which means "use all the defaults". If not, an element | ||
| 693 | should be a pair, where the `car' or the pair is the setting, and the | ||
| 694 | `cdr' of the pair is the value of printer-related settings to use for | ||
| 695 | this `prin1' call. | ||
| 696 | |||
| 697 | For instance: | ||
| 698 | |||
| 699 | (prin1 object nil \\='((length . 100) (circle . t))). | ||
| 700 | |||
| 701 | See the manual entry `(elisp)Output Overrides' for a list of possible | ||
| 702 | values. | ||
| 703 | |||
| 704 | As a special case, OVERRIDES can also simply be the symbol t, which | ||
| 705 | means "use all the defaults". */) | ||
| 706 | (Lisp_Object object, Lisp_Object printcharfun, Lisp_Object overrides) | ||
| 647 | { | 707 | { |
| 708 | specpdl_ref count = SPECPDL_INDEX (); | ||
| 709 | |||
| 648 | if (NILP (printcharfun)) | 710 | if (NILP (printcharfun)) |
| 649 | printcharfun = Vstandard_output; | 711 | printcharfun = Vstandard_output; |
| 712 | if (!NILP (overrides)) | ||
| 713 | print_bind_overrides (overrides); | ||
| 714 | |||
| 650 | PRINTPREPARE; | 715 | PRINTPREPARE; |
| 651 | print (object, printcharfun, 1); | 716 | print (object, printcharfun, 1); |
| 652 | PRINTFINISH; | 717 | PRINTFINISH; |
| 653 | return object; | 718 | |
| 719 | return unbind_to (count, object); | ||
| 654 | } | 720 | } |
| 655 | 721 | ||
| 656 | /* A buffer which is used to hold output being built by prin1-to-string. */ | 722 | /* A buffer which is used to hold output being built by prin1-to-string. */ |
| 657 | Lisp_Object Vprin1_to_string_buffer; | 723 | Lisp_Object Vprin1_to_string_buffer; |
| 658 | 724 | ||
| 659 | DEFUN ("prin1-to-string", Fprin1_to_string, Sprin1_to_string, 1, 2, 0, | 725 | DEFUN ("prin1-to-string", Fprin1_to_string, Sprin1_to_string, 1, 3, 0, |
| 660 | doc: /* Return a string containing the printed representation of OBJECT. | 726 | doc: /* Return a string containing the printed representation of OBJECT. |
| 661 | OBJECT can be any Lisp object. This function outputs quoting characters | 727 | OBJECT can be any Lisp object. This function outputs quoting characters |
| 662 | when necessary to make output that `read' can handle, whenever possible, | 728 | when necessary to make output that `read' can handle, whenever possible, |
| @@ -666,13 +732,18 @@ the behavior is controlled by `print-level' and `print-length', which see. | |||
| 666 | OBJECT is any of the Lisp data types: a number, a string, a symbol, | 732 | OBJECT is any of the Lisp data types: a number, a string, a symbol, |
| 667 | a list, a buffer, a window, a frame, etc. | 733 | a list, a buffer, a window, a frame, etc. |
| 668 | 734 | ||
| 735 | See `prin1' for the meaning of OVERRIDES. | ||
| 736 | |||
| 669 | A printed representation of an object is text which describes that object. */) | 737 | A printed representation of an object is text which describes that object. */) |
| 670 | (Lisp_Object object, Lisp_Object noescape) | 738 | (Lisp_Object object, Lisp_Object noescape, Lisp_Object overrides) |
| 671 | { | 739 | { |
| 672 | specpdl_ref count = SPECPDL_INDEX (); | 740 | specpdl_ref count = SPECPDL_INDEX (); |
| 673 | 741 | ||
| 674 | specbind (Qinhibit_modification_hooks, Qt); | 742 | specbind (Qinhibit_modification_hooks, Qt); |
| 675 | 743 | ||
| 744 | if (!NILP (overrides)) | ||
| 745 | print_bind_overrides (overrides); | ||
| 746 | |||
| 676 | /* Save and restore this: we are altering a buffer | 747 | /* Save and restore this: we are altering a buffer |
| 677 | but we don't want to deactivate the mark just for that. | 748 | but we don't want to deactivate the mark just for that. |
| 678 | No need for specbind, since errors deactivate the mark. */ | 749 | No need for specbind, since errors deactivate the mark. */ |
| @@ -847,7 +918,7 @@ append to existing target file. */) | |||
| 847 | void | 918 | void |
| 848 | debug_print (Lisp_Object arg) | 919 | debug_print (Lisp_Object arg) |
| 849 | { | 920 | { |
| 850 | Fprin1 (arg, Qexternal_debugging_output); | 921 | Fprin1 (arg, Qexternal_debugging_output, Qnil); |
| 851 | fputs ("\r\n", stderr); | 922 | fputs ("\r\n", stderr); |
| 852 | } | 923 | } |
| 853 | 924 | ||
| @@ -995,7 +1066,7 @@ print_error_message (Lisp_Object data, Lisp_Object stream, const char *context, | |||
| 995 | || EQ (errname, Qend_of_file) || EQ (errname, Quser_error)) | 1066 | || EQ (errname, Qend_of_file) || EQ (errname, Quser_error)) |
| 996 | Fprinc (obj, stream); | 1067 | Fprinc (obj, stream); |
| 997 | else | 1068 | else |
| 998 | Fprin1 (obj, stream); | 1069 | Fprin1 (obj, stream, Qnil); |
| 999 | } | 1070 | } |
| 1000 | } | 1071 | } |
| 1001 | } | 1072 | } |
| @@ -2571,4 +2642,35 @@ be printed. */); | |||
| 2571 | DEFSYM (Qprint_unreadable_function, "print-unreadable-function"); | 2642 | DEFSYM (Qprint_unreadable_function, "print-unreadable-function"); |
| 2572 | 2643 | ||
| 2573 | defsubr (&Sflush_standard_output); | 2644 | defsubr (&Sflush_standard_output); |
| 2645 | |||
| 2646 | DEFVAR_LISP ("print--variable-mapping", Vprint__variable_mapping, | ||
| 2647 | doc: /* Mapping for print variables in `prin1'. | ||
| 2648 | Do not modify this list. */); | ||
| 2649 | Vprint__variable_mapping = Qnil; | ||
| 2650 | Lisp_Object total[] = { | ||
| 2651 | list3 (intern ("length"), intern ("print-length"), Qnil), | ||
| 2652 | list3 (intern ("level"), intern ("print-level"), Qnil), | ||
| 2653 | list3 (intern ("circle"), intern ("print-circle"), Qnil), | ||
| 2654 | list3 (intern ("quoted"), intern ("print-quoted"), Qt), | ||
| 2655 | list3 (intern ("escape-newlines"), intern ("print-escape-newlines"), Qnil), | ||
| 2656 | list3 (intern ("escape-control-characters"), | ||
| 2657 | intern ("print-escape-control-characters"), Qnil), | ||
| 2658 | list3 (intern ("escape-nonascii"), intern ("print-escape-nonascii"), Qnil), | ||
| 2659 | list3 (intern ("escape-multibyte"), | ||
| 2660 | intern ("print-escape-multibyte"), Qnil), | ||
| 2661 | list3 (intern ("charset-text-property"), | ||
| 2662 | intern ("print-charset-text-property"), Qnil), | ||
| 2663 | list3 (intern ("unreadeable-function"), | ||
| 2664 | intern ("print-unreadable-function"), Qnil), | ||
| 2665 | list3 (intern ("gensym"), intern ("print-gensym"), Qnil), | ||
| 2666 | list3 (intern ("continuous-numbering"), | ||
| 2667 | intern ("print-continuous-numbering"), Qnil), | ||
| 2668 | list3 (intern ("number-table"), intern ("print-number-table"), Qnil), | ||
| 2669 | list3 (intern ("float-format"), intern ("float-output-format"), Qnil), | ||
| 2670 | list3 (intern ("integers-as-characters"), | ||
| 2671 | intern ("print-integers-as-characters"), Qnil), | ||
| 2672 | }; | ||
| 2673 | |||
| 2674 | Vprint__variable_mapping = CALLMANY (Flist, total); | ||
| 2675 | make_symbol_constant (intern_c_string ("print--variable-mapping")); | ||
| 2574 | } | 2676 | } |
diff --git a/src/process.c b/src/process.c index 2f8863aef25..fe3e12343f2 100644 --- a/src/process.c +++ b/src/process.c | |||
| @@ -4779,7 +4779,7 @@ corresponding connection was closed. */) | |||
| 4779 | SDATA (proc->name), | 4779 | SDATA (proc->name), |
| 4780 | STRINGP (proc_thread_name) | 4780 | STRINGP (proc_thread_name) |
| 4781 | ? SDATA (proc_thread_name) | 4781 | ? SDATA (proc_thread_name) |
| 4782 | : SDATA (Fprin1_to_string (proc->thread, Qt))); | 4782 | : SDATA (Fprin1_to_string (proc->thread, Qt, Qnil))); |
| 4783 | } | 4783 | } |
| 4784 | } | 4784 | } |
| 4785 | else | 4785 | else |