home: hub: zuo

Download patch

ref: 22dc4268f62e3cc16b17525ec4c1f9e0e6ccdcb4
parent: 476b3ea3a5d3791c51daa633b800ec0c76435a33
author: Matthew Flatt <mflatt@racket-lang.org>
date: Fri Apr 22 02:05:18 CDT 2022

Zuo: parse `#` in as a comment in `config-file->hash`

--- a/lib/zuo/config.zuo
+++ b/lib/zuo/config.zuo
@@ -36,7 +36,7 @@
                [positions
                 (define var (string->symbol (substring line (car positions) (cadr positions))))
                 (define rhs (substring line (+ (list-ref positions 2) 1) (string-length line)))
-                (hash-set accum var (string-trim rhs))]
+                (hash-set accum var (string-trim (remove-makefile-comment rhs)))]
                [else accum]))
            (hash)
            lines))
@@ -44,3 +44,23 @@
            (hash-set config key (hash-ref vars key) ))
          config
          (hash-keys vars)))
+
+(define (remove-makefile-comment s)
+  (define l (string-split s "#"))
+  (cond
+    [(= (length l) 1) s]
+    [else
+     ;; A `\` just before `#` escapes the `#`
+     (let loop ([l l])
+       (cond
+         [(null? l) ""]
+         [else
+          (let* ([s (car l)]
+                 [len (string-length s)])
+            (cond
+              [(= len 0) ""]
+              [(= (char "\\") (string-ref s (- len 1)))
+               (~a (substring s 0 (- len 1))
+                   "#"
+                   (loop (cdr l)))]
+              [else s]))]))]))
--- /dev/null
+++ b/tests/config.zuo
@@ -1,0 +1,45 @@
+#lang zuo
+
+(require "harness.zuo")
+
+(alert "config")
+
+(define Mf-config (build-path tmp-dir "Mf-config"))
+
+(define (config->hash content [overrides (hash)])
+  (display-to-file content Mf-config :truncate)
+  (config-file->hash Mf-config overrides))
+
+(check (config->hash "") (hash))
+(check (config->hash "" (hash 'X "x")) (hash 'X "x"))
+(check (config->hash "This is not a confg line" (hash 'X "x")) (hash 'X "x"))
+(check (config->hash "Comment # no=6" (hash 'X "x")) (hash 'X "x"))
+
+(check (config->hash "X=5") (hash 'X "5"))
+(check (config->hash "X =5") (hash 'X "5"))
+(check (config->hash "X= 5   ") (hash 'X "5"))
+(check (config->hash "  X = 5   ") (hash 'X "5"))
+(check (config->hash "\n\n  X = 5   \n\n") (hash 'X "5"))
+(check (config->hash "X = 5\\\n1") (hash 'X "51"))
+
+(check (config->hash "X_1=5") (hash 'X_1 "5"))
+(check (config->hash "abcdefg_ZXSGFH_=5") (hash 'abcdefg_ZXSGFH_ "5"))
+(check (config->hash "123=5") (hash (string->symbol "123") "5"))
+(check (config->hash "1%23=5") (hash))
+(check (config->hash "x%23=5") (hash))
+
+(check (config->hash "X=5\nY=8") (hash 'X "5" 'Y "8"))
+(check (config->hash "X=5\nX=8") (hash 'X "8"))
+(check (config->hash "X=5\nX=8" (hash 'X "0")) (hash 'X "0"))
+(check (config->hash "X=5\nY=8" (hash 'X "0")) (hash 'X "0" 'Y "8"))
+
+(check (config->hash "X=5 # Comment after") (hash 'X "5"))
+(check (config->hash "X=5 # Comment after\nY=8") (hash 'X "5" 'Y "8"))
+(check (config->hash "X=5 \\# 7") (hash 'X "5 # 7"))
+(check (config->hash "X=5 \\\\# 7") (hash 'X "5 \\# 7"))
+(check (config->hash "X=5# \\\\# 7") (hash 'X "5"))
+(check (config->hash "X=# # #") (hash 'X ""))
+(check (config->hash "X = 5\\\n# 1 \\\n 2") (hash 'X "5"))
+(check (config->hash "X = 5\\\n 1 \\\n 2") (hash 'X "5 1  2"))
+
+(rm* Mf-config)
--- a/tests/main.zuo
+++ b/tests/main.zuo
@@ -21,6 +21,7 @@
 (require "cleanable.zuo")
 (require "image.zuo")
 (require "shell.zuo")
+(require "config.zuo")
 (require "c.zuo")
 (require "cycle.zuo")
 (require "form.zuo")
--- a/zuo-doc/zuo-lib.scrbl
+++ b/zuo-doc/zuo-lib.scrbl
@@ -304,15 +304,18 @@
 @nonterm{name} @litchar{=} @nonterm{value}, with any number of ignored
 spaces at the start of the line, end of the line, or around the
 @litchar{=}, and with a trailing @litchar{\} on a line deleted along
-with its newline (to create a single line). Each @nonterm{name}
-consists of alphanumeric characters and @litchar{_}; the symbol form
-of the name is used as a key in the resulting hash table, mapped to
-the @nonterm{value} as a string. Lines in @racket[file] that do not
-match the configuration format are ignored. If a same @nonterm{name}
-is configured multiple times, the last mapping overrides earlier
-ones.
+with its newline (to create a single line). A @litchar{#} character
+terminates a line to start a comment, unless the @litchar{#} is
+preceded by @litchar{\}, in which case the @litchar{\#} combination is
+parsed as a literal @litchar{#}.
 
+Each @nonterm{name} consists of alphanumeric characters and
+@litchar{_}; the symbol form of the name is used as a key in the
+resulting hash table, mapped to the @nonterm{value} as a string. Lines
+in @racket[file] that do not match the configuration format are
+ignored. If a same @nonterm{name} is configured multiple times, the
+last mapping overrides earlier ones.
+
 After reading @racket[file], keys from @racket[overrides] are merged
 to the result hash table, where values in @racket[overrides] replace
 ones read from @racket[file].}
-