Discussion:
Change interpreter from octets to hex?
Joshua Datko
2018-08-20 05:54:17 UTC
Permalink
Hello,

Is it possible to change the default interpreter behavior to display
hex instead of octets for bytevectors and u8-lists? And if so, how to
do so?

The default, as y'all know is:

scheme@(guile-user)> #vu8(#x0a #xaa)
$6 = #vu8(10 170)

But I would like instead the output to be:
$6 = #vu8(#x0a #xaa)

It's easy enough to make a format function but it'd be more convenient
if this was the default for me.

Thanks,

Josh
Mark H Weaver
2018-08-21 04:32:16 UTC
Permalink
Hi Joshua,
Post by Joshua Datko
Is it possible to change the default interpreter behavior to display
hex instead of octets for bytevectors and u8-lists? And if so, how to
do so?
$6 = #vu8(10 170)
$6 = #vu8(#x0a #xaa)
The printer used by the Guile REPL can be customized using the ",option"
REPL command. For example:

--8<---------------cut here---------------start------------->8---
***@jojen ~$ guile
GNU Guile 2.2.3
Copyright (C) 1995-2017 Free Software Foundation, Inc.

Guile comes with ABSOLUTELY NO WARRANTY; for details type `,show w'.
This program is free software, and you are welcome to redistribute it
under certain conditions; type `,show c' for details.

Enter `,help' for help.
scheme@(guile-user)> ,help system
System Commands [abbrev]:

,gc - Garbage collection.
,statistics [,stat] - Display statistics.
,option [NAME] [EXP] [,o] - List/show/set options.
,quit [,q ,continue ,cont] - Quit this session.

scheme@(guile-user)> ,option
compile-options (#:warnings (unbound-variable macro-use-before-definition arity-mismatch format duplicate-case-datum bad-case-datum))
trace #f
interp #f
prompt #f
print #f
value-history #t
on-error debug
scheme@(guile-user)> (use-modules (rnrs bytevectors)
(ice-9 format))
scheme@(guile-user)> (define (format-octet octet)
(format #f "#x~2,'0x" octet))
scheme@(guile-user)> (define (print-bytevector bv)
(display "#vu8(")
(display (string-join (map format-octet (bytevector->u8-list bv))))
(display ")"))
scheme@(guile-user)> (define (my-repl-print repl val)
(if (bytevector? val)
(print-bytevector val)
(write val))
(newline))
scheme@(guile-user)> ,o print my-repl-print
scheme@(guile-user)> #vu8(0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20)
$1 = #vu8(#x00 #x01 #x02 #x03 #x04 #x05 #x06 #x07 #x08 #x09 #x0a #x0b #x0c #x0d #x0e #x0f #x10 #x11 #x12 #x13 #x14)
scheme@(guile-user)>
--8<---------------cut here---------------end--------------->8---

This simple strategy won't work for bytevectors nested within another
data structure. However, you could handle some specific cases by
supporting more data structures in your custom printer. For example, if
you enhanced the custom printer to print ordinary scheme lists and to
call itself recursively for the elements of those lists, then you could
support printing bytevectors in your preferred format as long as the
surrounding data structure is composed of normal list structure only.

Guile's built-in printer does not support customizing its formatting of
core data structures, so you cannot handle the general case here without
modifying Guile itself. If you wanted to do that,
'scm_i_print_bytevector' in bytevectors.c is the function to modify.

Another option would be to wrap your bytevectors within your own record
type, in which case you could install your own custom printer for that
type using 'set-record-type-printer!'.

Mark
Joshua Datko
2018-08-21 19:32:18 UTC
Permalink
Thanks Mark!

There are lots of good options! For now I just hacked bytevector.c,
thanks for that tip! It's just me on my local system dumping
bytevectors all over the place so this is perfectly acceptable.

Josh

Loading...