summary refs log tree commit diff
diff options
context:
space:
mode:
authorLudovic Courtès <ludo@gnu.org>2022-09-01 15:54:08 +0200
committerLudovic Courtès <ludo@gnu.org>2022-09-01 18:31:26 +0200
commitc3b1cfe76b7038f4030d7d207ffc417fed9a7ead (patch)
treedd1e118336d2d1f915c003ac3af46b374fe9c043
parent8cf7997d7c068eb87eadbd28ac8be4e0aeddbba3 (diff)
downloadguix-c3b1cfe76b7038f4030d7d207ffc417fed9a7ead.tar.gz
read-print: Guess the base to use for integers being printed.
Fixes <https://issues.guix.gnu.org/57090>.
Reported by Christopher Rodriguez <yewscion@gmail.com>.

* guix/read-print.scm (%symbols-followed-by-octal-integers)
(%symbols-followed-by-hexadecimal-integers): New variables.
* guix/read-print.scm (integer->string): New procedure.
(pretty-print-with-comments): Use it.
* tests/read-print.scm: Add test.
-rw-r--r--guix/read-print.scm38
-rw-r--r--tests/read-print.scm8
2 files changed, 43 insertions, 3 deletions
diff --git a/guix/read-print.scm b/guix/read-print.scm
index 63ff9ca5bd..00dde870f4 100644
--- a/guix/read-print.scm
+++ b/guix/read-print.scm
@@ -22,6 +22,7 @@
   #:use-module (ice-9 rdelim)
   #:use-module (ice-9 vlist)
   #:use-module (srfi srfi-1)
+  #:use-module (srfi srfi-26)
   #:use-module (srfi srfi-34)
   #:use-module (srfi srfi-35)
   #:use-module (guix i18n)
@@ -426,6 +427,34 @@ each line except the first one (they're assumed to be already there)."
        (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->string integer context)
+  "Render INTEGER as a string using a base suitable based on CONTEXT."
+  (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)))
+      (_ 10)))
+
+  (string-append (match base
+                   (10 "")
+                   (16 "#x")
+                   (8  "#o"))
+                 (number->string integer base)))
+
 (define* (pretty-print-with-comments port obj
                                      #:key
                                      (format-comment
@@ -661,9 +690,12 @@ FORMAT-VERTICAL-SPACE; a useful value of 'canonicalize-vertical-space'."
              (display ")" port)
              (+ column 1)))))
       (_
-       (let* ((str (if (string? obj)
-                       (escaped-string obj)
-                       (object->string obj)))
+       (let* ((str (cond ((string? obj)
+                          (escaped-string obj))
+                         ((integer? obj)
+                          (integer->string obj context))
+                         (else
+                          (object->string obj))))
               (len (string-width str)))
          (if (and (> (+ column 1 len) max-width)
                   (not delimited?))
diff --git a/tests/read-print.scm b/tests/read-print.scm
index 4dabcc1e64..1b0d865972 100644
--- a/tests/read-print.scm
+++ b/tests/read-print.scm
@@ -248,6 +248,14 @@ mnopqrstuvwxyz.\")"
   (list x y z))")
 
 (test-pretty-print "\
+(begin
+  (chmod \"foo\" #o750)
+  (chmod port
+         (logand #o644
+                 (lognot (umask))))
+  (logand #x7f xyz))")
+
+(test-pretty-print "\
 (substitute-keyword-arguments (package-arguments x)
   ((#:phases phases)
    `(modify-phases ,phases