diff --git a/guix/read-print.scm b/guix/read-print.scm index 6e1188e87e..a5a1b708bf 100644 --- a/guix/read-print.scm +++ b/guix/read-print.scm @@ -442,26 +442,40 @@ (define (print-multi-line-comment str indent port) (display (make-string indent #\space) port) (loop tail))))) -(define %symbols-followed-by-octal-integers - ;; Symbols for which the following integer must be printed as octal. - '(chmod umask mkdir mkstemp)) - -(define %symbols-followed-by-hexadecimal-integers - ;; Likewise, for hexadecimal integers. - '(logand logior logxor lognot)) +(define %integer-forms + ;; Forms that take an integer as their argument, where said integer should + ;; be printed in base other than decimal base. + (letrec-syntax ((vhashq (syntax-rules () + ((_) vlist-null) + ((_ (key value) rest ...) + (vhash-consq key value (vhashq rest ...)))))) + (vhashq + ('chmod 8) + ('umask 8) + ('mkdir 8) + ('mkstemp 8) + ('logand 16) + ('logior 16) + ('logxor 16) + ('lognot 16)))) (define (integer->string integer context) "Render INTEGER as a string using a base suitable based on CONTEXT." + (define (form-base form) + (match (vhash-assq form %integer-forms) + (#f 10) + ((_ . base) base))) + + (define (octal? form) + (= 8 (form-base form))) + (define base (match context ((head . tail) - (cond ((memq head %symbols-followed-by-octal-integers) 8) - ((memq head %symbols-followed-by-hexadecimal-integers) - (if (any (cut memq <> %symbols-followed-by-octal-integers) - tail) - 8 - 16)) - (else 10))) + (match (form-base head) + (8 8) + (16 (if (any octal? tail) 8 16)) + (10 10))) (_ 10))) (string-append (match base