[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
bug#44155: Print integers as characters
From: |
Juri Linkov |
Subject: |
bug#44155: Print integers as characters |
Date: |
Wed, 28 Oct 2020 21:41:46 +0200 |
User-agent: |
Gnus/5.13 (Gnus v5.13) Emacs/28.0.50 (x86_64-pc-linux-gnu) |
>> > Alternatively, we could print raw bytes in some special way. But not
>> > treating them as characters sounds some subtlety that will be hard to
>> > explain.
>>
>> The existing 'prin1-char' used as a reference implementation
>> doesn't print integers like 4194176 as characters, so the patch
>> does the same.
>
> I don't think it's right, FWIW. Displaying something like \100 would
> be better, IMO.
Sorry, I don't understand why 4194176 could be printed as \100.
>> +@defvar integer-output-format
>> +This variable specifies how to print integer numbers. The default is
>> +@code{nil}, meaning use the decimal format. When bound to @code{t},
>> +print integers as characters when an integer represents a character
>> +(@pxref{Basic Char Syntax}). When bound to the number @code{16},
>> +print non-negative integers in the hexadecimal format.
>
> This should mention the functions affected by the variable.
>
>> +** New variable 'integer-output-format' defines the format of integers.
> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> "determines how to print integer values"
>
>> +When this variable is bound to the value 't', integers are printed by
>> +printing functions as characters when an integer represents a character.
>
> Please give at least one example of a function affected by this.
Ok, fixed:
diff --git a/doc/lispref/streams.texi b/doc/lispref/streams.texi
index 2cd61ad04f..08d8032e6f 100644
--- a/doc/lispref/streams.texi
+++ b/doc/lispref/streams.texi
@@ -902,3 +902,12 @@ Output Variables
in the C function @code{sprintf}. For further restrictions on what
you can use, see the variable's documentation string.
@end defvar
+
+@defvar integer-output-format
+This variable specifies how to print integer numbers. The default is
+@code{nil}, meaning use the decimal format. When bound to @code{t},
+print integers as characters when an integer represents a character
+(@pxref{Basic Char Syntax}). When bound to the number @code{16},
+print non-negative integers in the hexadecimal format.
+This variable affects all print functions.
+@end defvar
diff --git a/etc/NEWS b/etc/NEWS
index 5e159480e0..202e449b16 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -1641,6 +1641,12 @@ ledit.el, lmenu.el, lucid.el and old-whitespace.el.
* Lisp Changes in Emacs 28.1
+** New variable 'integer-output-format' determines how to print integer values.
+When this variable is bound to the value 't', integers are printed by
+printing functions as characters when an integer represents a character.
+When bound to the number 16, non-negative integers are printed in the
+hexadecimal format.
+
+++
** 'define-globalized-minor-mode' now takes a :predicate parameter.
This can be used to control which major modes the minor mode should be
diff --git a/src/print.c b/src/print.c
index 53aa353769..7b3dc61065 100644
--- a/src/print.c
+++ b/src/print.c
@@ -1908,8 +1908,31 @@ print_object (Lisp_Object obj, Lisp_Object printcharfun,
bool escapeflag)
{
case_Lisp_Int:
{
- int len = sprintf (buf, "%"pI"d", XFIXNUM (obj));
- strout (buf, len, len, printcharfun);
+ int c;
+ intmax_t i;
+
+ if (EQ (Vinteger_output_format, Qt) && CHARACTERP (obj)
+ && (c = XFIXNUM (obj)) && ! CHAR_BYTE8_P (c))
+ {
+ printchar ('?', printcharfun);
+ if (escapeflag
+ && (c == ';' || c == '(' || c == ')' || c == '{' || c == '}'
+ || c == '[' || c == ']' || c == '\"' || c == '\'' || c ==
'\\'))
+ printchar ('\\', printcharfun);
+ printchar (c, printcharfun);
+ }
+ else if (INTEGERP (Vinteger_output_format)
+ && integer_to_intmax (Vinteger_output_format, &i)
+ && i == 16 && Fnatnump (obj))
+ {
+ int len = sprintf (buf, "#x%"pI"x", (EMACS_UINT) XFIXNUM (obj));
+ strout (buf, len, len, printcharfun);
+ }
+ else
+ {
+ int len = sprintf (buf, "%"pI"d", XFIXNUM (obj));
+ strout (buf, len, len, printcharfun);
+ }
}
break;
@@ -2247,6 +2270,15 @@ syms_of_print (void)
that represents the number without losing information. */);
Vfloat_output_format = Qnil;
+ DEFVAR_LISP ("integer-output-format", Vinteger_output_format,
+ doc: /* The format used to print integers.
+When t, print characters from integers that represent a character.
+When a number 16, print non-negative integers in the hexadecimal format.
+Otherwise, by default print integers in the decimal format.
+This variable affects all print functions, for example, such function
+as `print'. */);
+ Vinteger_output_format = Qnil;
+
DEFVAR_LISP ("print-length", Vprint_length,
doc: /* Maximum length of list to print before abbreviating.
A value of nil means no limit. See also `eval-expression-print-length'. */);
diff --git a/test/src/print-tests.el b/test/src/print-tests.el
index eb9572dbdf..7b026b6b21 100644
--- a/test/src/print-tests.el
+++ b/test/src/print-tests.el
@@ -383,5 +383,25 @@ print-hash-table-test
(let ((print-length 1))
(format "%S" h))))))
+(print-tests--deftest print-integer-output-format ()
+ ;; Bug#44155.
+ (let ((integer-output-format t)
+ (syms (list ?? ?\; ?\( ?\) ?\{ ?\} ?\[ ?\] ?\" ?\' ?\\ ?Á)))
+ (should (equal (read (print-tests--prin1-to-string syms)) syms))
+ (should (equal (print-tests--prin1-to-string syms)
+ (concat "(" (mapconcat #'prin1-char syms " ") ")"))))
+ (let ((integer-output-format t)
+ (syms (list -1 0 1 ?\120 4194175 4194176 (max-char) (1+ (max-char)))))
+ (should (equal (read (print-tests--prin1-to-string syms)) syms)))
+ (let ((integer-output-format 16)
+ (syms (list -1 0 1 most-positive-fixnum (1+ most-positive-fixnum))))
+ (should (equal (read (print-tests--prin1-to-string syms)) syms))
+ (should (equal (print-tests--prin1-to-string syms)
+ (concat "(" (mapconcat
+ (lambda (i)
+ (if (and (>= i 0) (<= i
most-positive-fixnum))
+ (format "#x%x" i) (format "%d" i)))
+ syms " ") ")")))))
+
(provide 'print-tests)
;;; print-tests.el ends here
- bug#44155: Print integers as characters, (continued)
- bug#44155: Print integers as characters, Juri Linkov, 2020/10/22
- bug#44155: Print integers as characters, Andreas Schwab, 2020/10/22
- bug#44155: Print integers as characters, Juri Linkov, 2020/10/23
- bug#44155: Print integers as characters, Juri Linkov, 2020/10/23
- bug#44155: Print integers as characters, Juri Linkov, 2020/10/24
- bug#44155: Print integers as characters, Eli Zaretskii, 2020/10/25
- bug#44155: Print integers as characters, Juri Linkov, 2020/10/25
- bug#44155: Print integers as characters, Eli Zaretskii, 2020/10/25
- bug#44155: Print integers as characters, Juri Linkov, 2020/10/27
- bug#44155: Print integers as characters, Eli Zaretskii, 2020/10/28
- bug#44155: Print integers as characters,
Juri Linkov <=
- bug#44155: Print integers as characters, Eli Zaretskii, 2020/10/29
- bug#44155: Print integers as characters, Juri Linkov, 2020/10/29
- bug#44155: Print integers as characters, Eli Zaretskii, 2020/10/30
- bug#44155: Print integers as characters, Juri Linkov, 2020/10/31
- bug#44155: Print integers as characters, Glenn Morris, 2020/10/31
- bug#43866: 26.3; italian postfix additions, Richard Stallman, 2020/10/14
- bug#43866: 26.3; italian postfix additions, Richard Stallman, 2020/10/14
- bug#43866: 26.3; italian postfix additions, Juri Linkov, 2020/10/14
- bug#43866: 26.3; italian postfix additions, Robert Pluim, 2020/10/14
- bug#43866: 26.3; italian postfix additions, Richard Stallman, 2020/10/14