GNU bug report logs - #77387
[PATCH 0/2] man-db: Better parsing of man macros.

Previous Next

Package: guix-patches;

Reported by: Sergey Trofimov <sarg <at> sarg.org.ru>

Date: Sun, 30 Mar 2025 14:27:02 UTC

Severity: normal

Tags: patch

Done: Ludovic Courtès <ludo <at> gnu.org>

Bug is archived. No further changes may be made.

Full log


Message #32 received at 77387 <at> debbugs.gnu.org (full text, mbox):

From: Sergey Trofimov <sarg <at> sarg.org.ru>
To: 77387 <at> debbugs.gnu.org
Cc: Sergey Trofimov <sarg <at> sarg.org.ru>
Subject: [PATCH v2 1/2] man-db: Parse man macro arguments better.
Date: Wed,  9 Apr 2025 14:46:40 +0200
* guix/man-db.scm (man-macro-tokenize): New procedure to parse man
macros.
(man-page->entry): Parse macro line using man-macro-tokenize.

Change-Id: Iea0ffbc65290757df746138e0a6174646b5a3eb8
---
 guix/man-db.scm | 55 +++++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 46 insertions(+), 9 deletions(-)

diff --git a/guix/man-db.scm b/guix/man-db.scm
index bba90ed473..1259658f52 100644
--- a/guix/man-db.scm
+++ b/guix/man-db.scm
@@ -161,16 +161,51 @@ (define (read-synopsis port)
       (line
        (loop (cons line lines))))))
 
+(define (man-macro-tokenize input)
+  "Split INPUT string, a man macro invocation, into a list containing the macro's
+name followed by its arguments."
+  (let loop ((pos 0)
+             (tokens '())
+             (characters '())
+             (in-string? #f))
+    (if (>= pos (string-length input))
+        ;; End of input
+        (reverse (if (null? characters)
+                     tokens
+                     (cons (list->string (reverse characters)) tokens)))
+        (let ((c (string-ref input pos)))
+          (cond
+           ;; Inside a string
+           (in-string?
+            (if (char=? c #\")
+                (if (and (< (+ pos 1) (string-length input))
+                         (char=? (string-ref input (+ pos 1)) #\"))
+                    ;; Double quote inside string
+                    (loop (+ pos 2) tokens (cons #\" characters) #t)
+                    ;; End of string
+                    (loop (+ pos 1) (cons (list->string (reverse characters)) tokens) '() #f))
+                ;; Regular character in string
+                (loop (+ pos 1) tokens (cons c characters) #t)))
+
+           ;; Whitespace outside string
+           ((char-whitespace? c)
+            (if (null? characters)
+                (loop (+ pos 1) tokens '() #f)
+                (loop (+ pos 1) (cons (list->string (reverse characters)) tokens) '() #f)))
+
+           ;; Start of string
+           ((char=? c #\")
+            (if (null? characters)
+                (loop (+ pos 1) tokens '() #t)
+                (loop pos (cons (list->string (reverse characters)) tokens) '() #f)))
+
+           ;; Symbol character
+           (else
+            (loop (+ pos 1) tokens (cons c characters) #f)))))))
+
 (define* (man-page->entry file #:optional (resolve identity))
   "Parse FILE, a gzip or zstd compressed man page, and return a <mandb-entry>
 for it."
-  (define (string->number* str)
-    (if (and (string-prefix? "\"" str)
-             (> (string-length str) 1)
-             (string-suffix? "\"" str))
-        (string->number (string-drop (string-drop-right str 1) 1))
-        (string->number str)))
-
   (define call-with-input-port*
     (cond
      ((gzip-compressed? file) call-with-gzip-input-port)
@@ -189,8 +224,10 @@ (define* (man-page->entry file #:optional (resolve identity))
               (if (eof-object? line)
                   (mandb-entry file name (or section 0) (or synopsis "")
                                kind)
-                  (match (string-tokenize line)
-                    ((".TH" name (= string->number* section) _ ...)
+                  ;; man 7 groff groff_mdoc groff_man
+                  ;; look for metadata in macro invocations (lines starting with .)
+                  (match (and (string-prefix? "." line) (man-macro-tokenize line))
+                    ((".TH" name (= string->number section) _ ...)
                      (loop name section synopsis kind))
                     ((".SH" (or "NAME" "\"NAME\""))
                      (loop name section (read-synopsis port) kind))

base-commit: 621d09a185b106364fe7636923ab39c8bca35141
--
2.49.0





This bug report was last modified 39 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.