diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2024-05-03 06:59:32 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2024-05-03 06:59:32 -0700 |
commit | 071225dcce0ac4ad8cc00e3208bd3848ee066eab (patch) | |
tree | 96f336826d1927dc870d54ef9eb146a51a975d78 | |
parent | 262cf47d2c701bf71143f312427b1f4fa140deb9 (diff) | |
download | txr-071225dcce0ac4ad8cc00e3208bd3848ee066eab.tar.gz txr-071225dcce0ac4ad8cc00e3208bd3848ee066eab.tar.bz2 txr-071225dcce0ac4ad8cc00e3208bd3848ee066eab.zip |
buf: pprint produces hex, not raw bytes.
The pprint semantics of buffers is that the
raw bytes are dumped into the stream. This is poor.
It was hastily designed based on analogy with
strings, which pprint by just sending their contents
to the stream; but for strings this is justified
because they represent text.
We also fix the semantics of buffer values being
rendered by quasiliteral notation. Currently, the
are treated as sequences, and so they explode into
individual decimal integers.
* buf.c (buf_pprint): Print the bytes as pairs of
lower-case hex digits, with no line breaks.
In 294 compatibility or lower, put out bytes as before.
* eval.c (fmt_cat): When not in 294 compatibility
mode, treat a buffer object via tostringp, which
will render it to hexadecimal via buf_pprintf.
In compatibility mode, treat it as before, which is
as a sequence: the individual values of the buffer
are converted to text, thus decimal values in the
range 0 to 255, catenated using the given separator.
* tests/012/readprint.tl: New tests.
* txr.1: Documented. Also expanding on what pretty printing
means in TXR.
-rw-r--r-- | buf.c | 9 | ||||
-rw-r--r-- | eval.c | 19 | ||||
-rw-r--r-- | tests/012/readprint.tl | 13 | ||||
-rw-r--r-- | txr.1 | 47 |
4 files changed, 73 insertions, 15 deletions
@@ -876,8 +876,13 @@ val buf_pprint(val buf, val stream_in) cnum len = c_num(b->len, self); mem_t *data = b->data; - while (len-- > 0) - put_byte(num_fast(*data++), stream); + if (opt_compat && opt_compat <= 294) { + while (len-- > 0) + put_byte(num_fast(*data++), stream); + } else { + while (len-- > 0) + format(stream, lit("~,02x"), num_fast(*data++), nao); + } return t; } @@ -2979,11 +2979,20 @@ static val fmt_tostring(val obj) static val fmt_cat(val obj, val sep) { - return if3(stringp(obj), - obj, - if3(if3(opt_compat && opt_compat <= 174, listp(obj), seqp(obj)), - cat_str(mapcar(func_n1(tostringp), obj), sep), - tostringp(obj))); + switch (type(obj)) { + case LIT: + case STR: + case LSTR: + return obj; + case BUF: + if (!opt_compat || opt_compat > 294) + return tostringp(obj); + /* fallthrough */ + default: + return if3(if3(opt_compat && opt_compat <= 174, listp(obj), seqp(obj)), + cat_str(mapcar(func_n1(tostringp), obj), sep), + tostringp(obj)); + } } static val do_format_field(val obj, val n, val sep, diff --git a/tests/012/readprint.tl b/tests/012/readprint.tl index 4298a85b..b3c2ff14 100644 --- a/tests/012/readprint.tl +++ b/tests/012/readprint.tl @@ -11,3 +11,16 @@ '(dwim) "[]" '(dwim . 3) "[. 3]" '(dwim 3 . 4) "[3 . 4]") + +(mtest + (tostring #b'ff') "#b'ff'" + (tostringp #b'ff') "ff") + +(let ((b #b'abcdef')) + (mtest + `@b` "abcdef" + `@{b [0..1]}` "ab" + `@{b [-1..:]}` "ef" + `@{b ":"}` "abcdef" + `@{b [0..2] ":"}` "abcd" + `@{b [-1]}` "239")) @@ -62457,8 +62457,25 @@ If .meta pretty-p is true, then .code print -does not strive for read-print consistency. -Strings are printed by sending their characters to the output +does not strive for read-print consistency. In \*(TX, the term +.I "pretty printing" +refers to rendering a printed representation of an object +without the notational details required to unambiguously delimit the object, +and represent its value and type without ambiguity. +For instance, the four-character string +.strn abcd , +the two-byte buffer object +.code #b'abcd' +as well as the symbol +.code abcd +all pretty-print as +.codn abcd . +To understand the meaning, the user has to refer to the documentation +of the specific application which produces that representation. + +When +.code pretty-p +is true, strings are printed by sending their characters to the output stream, as if by the .code put-string function, rather than being rendered in the string literal notation @@ -62467,13 +62484,20 @@ characters. Likewise, character objects are printed via .code put-char rather than the .code #\e -notation. Buffer objects are printed by sending their bytes to the -output stream using -.code put-byte -rather than being rendered in the -.code #b notation. -Symbols are printed without their package prefix, except that + +When +.code pretty-p +is true, buffer objects are printed as strings of hexadecimal +digit pairs, without being embedded in the +.code #b'...' +notation, and without any line breaks. +This behavior is new in \*(TX 275; see the COMPATIBILITY +section. + +The +.code pretty-p +flag causes symbols to be printed without their package prefix, except that symbols from the keyword package are still printed with the leading colon. Floating-point objects are printed as if using the .code format @@ -94405,6 +94429,13 @@ of these version values, the described behaviors are provided if is given an argument which is equal or lower. For instance .code "-C 103" selects the behaviors described below for version 105, but not those for 102. +.IP 294 +Until \*(TX 294, the +.code pprint +function rendered a buffer object simply by sending its raw bytes to +the destination stream, rather than rendering the object as a stream of +hexadecimal digit pairs. The old behavior is restored with compatibility +values of 294 or lower. .IP 289 Until \*(TX 289, the .code replace |