From e16cfd61f96155ba5d42df4af92c09a39abb3ee4 Mon Sep 17 00:00:00 2001 From: Florian Pelz Date: Mon, 15 Sep 2025 14:52:36 +0200 Subject: [PATCH] po: Don't replace newline escapes that are escaped themselves. Otherwise the cookbook is read incorrectly at msgid "" "(display (string-append \"Hello \" \"Guix\" \"\\n\"))\n" This can be seen at the `git diff` when beginning to run `make download-po`. * guix/build/po.scm (final-character-escapes?): New procedure. (interpret-newline-escape): Use it. Change-Id: I2b036000173b1e282e2aeceffe3491e0917e51ca --- guix/build/po.scm | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/guix/build/po.scm b/guix/build/po.scm index 4d153478c9a..de11d85e54d 100644 --- a/guix/build/po.scm +++ b/guix/build/po.scm @@ -48,8 +48,15 @@ (and (ignore "\"") (* str-chr) (ignore "\"") (? (and (ignore (* whitespace)) content)))) +(define (final-character-escapes? str last-index) + "Check if STR ends in an incomplete escape sequence, that is ends in an uneven +number of backslashes. LAST-INDEX is the index of its last character." + (and (>= last-index 0) + (eqv? (string-ref str last-index) #\\) + (not (final-character-escapes? str (- last-index 1))))) + (define (interpret-newline-escape str) - "Replace '\\n' sequences in STR with a newline character." + "Replace unescaped '\\n' sequences in STR with a newline character." (let loop ((str str) (result '())) (match (string-contains str "\\n") @@ -57,7 +64,10 @@ (index (let ((prefix (string-take str index))) (loop (string-drop str (+ 2 index)) - (append (list "\n" prefix) result))))))) + ;; Only add a newline when the backslash is not escaped itself. + (if (final-character-escapes? str (- index 1)) + (cons (string-take str (+ 2 index)) result) + (append (list "\n" prefix) result)))))))) (define (parse-tree->assoc parse-tree) "Converts a po PARSE-TREE to an association list, where the key is the msgid