{ 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
" 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" } } }
[
] 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
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 }
{ CHAR: \\ CHAR: \\ }
{ CHAR: ? CHAR: ? }
{ CHAR: ; CHAR: ; }
+ { CHAR: # CHAR: # }
{ CHAR: [ CHAR: [ }
{ CHAR: ] CHAR: ] }
{ CHAR: = CHAR: = }
+ { CHAR: : CHAR: : }
} ?at [ bad-escape ] unless ;
: (unescape-string) ( str -- )
[
[
H{
+ { CHAR: \0 "\\0" }
{ CHAR: \a "\\a" }
{ CHAR: \b "\\b" }
{ CHAR: \f "\\f" }
{ 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? ;
: 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 ;