]> gitweb.factorcode.org Git - factor.git/commitdiff
ini-file: re-add escaping but wrap tokens containing quotes.
authorJohn Benediktsson <mrjbq7@gmail.com>
Wed, 24 May 2023 04:08:53 +0000 (21:08 -0700)
committerJohn Benediktsson <mrjbq7@gmail.com>
Wed, 31 May 2023 18:45:56 +0000 (11:45 -0700)
basis/ini-file/ini-file-tests.factor
basis/ini-file/ini-file.factor

index d1a2710741f9098beb033401a8359c3f2b8762f1..a9dc5abf0c775724683279ab34cc23a5c4ea0622 100644 (file)
@@ -7,7 +7,7 @@ USING: ini-file tools.test ;
 
 { H{ { "section" H{ } } } } [ "[section]" string>ini ] unit-test
 
-{ "[test \"section with quotes\"]\n\n" } [
+{ "[\"test \\\"section with quotes\\\"\"]\n\n" } [
     "[test \"section with quotes\"]" string>ini ini>string
 ] unit-test
 
@@ -116,6 +116,15 @@ USING: ini-file tools.test ;
     " string>ini
 ] unit-test
 
+{ H{ { "section with \n escape codes"
+    H{ { "a long key name" "a long value name" } } } } }
+[
+    "
+    [section with \\n escape codes]
+    a long key name=  a long value name
+    " string>ini
+] unit-test
+
 { H{ { "key with \n esc\ape \r codes \""
        "value with \t esc\ape codes" } } }
 [
@@ -125,8 +134,16 @@ USING: ini-file tools.test ;
 ] unit-test
 
 
-{ "key with \\n esc\\ape \\r codes \\\"=value with \\t esc\\ape codes\n" }
+{ "\"key with \\n esc\\ape \\r codes \\\"\"=value with \\t esc\\ape codes\n" }
 [
     H{ { "key with \n esc\ape \r codes \""
          "value with \t esc\ape codes" } } ini>string
 ] unit-test
+
+{ H{ { "save_path" "C:\\Temp\\" } } } [
+    "save_path = \"C:\\\\Temp\\\\\"" string>ini
+] unit-test
+
+{ "save_path=\"C\\:\\\\Temp\\\\\"\n" } [
+    H{ { "save_path" "C:\\Temp\\" } } ini>string
+] unit-test
index 7d00b42dae51093306c26e374170d61a73803c45..a9578c1b80d79d96066aacef619251bde2eae793 100644 (file)
@@ -7,10 +7,17 @@ quoting sequences splitting strings strings.parser ;
 
 IN: ini-file
 
+! FIXME: support "key: value" ?
+! FIXME: support "key value" ?
+! FIXME: escaped comments "\;" don't work
+! FIXME: \x???? for unicode character escapes
+! FIXME: optional value conversion (e.g., 1234, true, etc.)?
+
 <PRIVATE
 
 : escape ( ch -- ch' )
     H{
+        { CHAR: 0   CHAR: \0 }
         { CHAR: a   CHAR: \a }
         { CHAR: b   CHAR: \b }
         { CHAR: f   CHAR: \f }
@@ -23,9 +30,11 @@ IN: ini-file
         { CHAR: \\  CHAR: \\ }
         { CHAR: ?   CHAR: ? }
         { CHAR: ;   CHAR: ; }
+        { CHAR: #   CHAR: # }
         { CHAR: [   CHAR: [ }
         { CHAR: ]   CHAR: ] }
         { CHAR: =   CHAR: = }
+        { CHAR: :   CHAR: : }
     } ?at [ bad-escape ] unless ;
 
 : (unescape-string) ( str -- )
@@ -42,6 +51,7 @@ IN: ini-file
     [
         [
             H{
+                { CHAR: \0   "\\0"  }
                 { CHAR: \a   "\\a"  }
                 { CHAR: \b   "\\b"  }
                 { CHAR: \f   "\\f"  }
@@ -54,13 +64,24 @@ IN: ini-file
                 { CHAR: \\   "\\\\" }
                 { CHAR: ?    "\\?"  }
                 { CHAR: ;    "\\;"  }
+                { CHAR: #    "\\#"  }
                 { CHAR: [    "\\["  }
                 { CHAR: ]    "\\]"  }
                 { CHAR: =    "\\="  }
+                { CHAR: :    "\\:"  }
             } ?at [ % ] [ , ] if
         ] each
     ] "" make ;
 
+: should-quote? ( str -- ? )
+    {
+        [ CHAR: " swap index ]
+        [ last CHAR: \ = ]
+    } 1|| ;
+
+: escape-quoted ( str -- str' )
+    [ escape-string ] [ should-quote? ] bi [ "\"" 1surround ] when ;
+
 : space? ( ch -- ? )
     "\s\t\n\r\f\v" member-eq? ;
 
@@ -126,16 +147,14 @@ PRIVATE>
 : write-ini ( assoc -- )
     [
         dup string? [
-            [ escape-string ] bi@ "%s=%s\n" printf
+            [ escape-quoted ] bi@ "%s=%s\n" printf
         ] [
-            [ "[%s]\n" printf ] dip
-            [ [ escape-string ] bi@ "%s=%s\n" printf ]
+            [ escape-quoted "[%s]\n" printf ] dip
+            [ [ escape-quoted ] bi@ "%s=%s\n" printf ]
             assoc-each nl
         ] if
     ] assoc-each ;
 
-! FIXME: escaped comments "\;" don't work
-
 : string>ini ( str -- assoc )
     [ read-ini ] with-string-reader ;