From a466f0ca79e63d1f26369430a50d014937e866b6 Mon Sep 17 00:00:00 2001 From: Thomas Pelletier Date: Sat, 6 Feb 2021 08:01:38 -0500 Subject: [PATCH] Multiline literal strings --- toml.go | 33 +++++++++++++++++++++++++-------- toml_test.go | 13 ++++++++++++- 2 files changed, 37 insertions(+), 9 deletions(-) diff --git a/toml.go b/toml.go index bf6d290..353c8ad 100644 --- a/toml.go +++ b/toml.go @@ -92,25 +92,24 @@ func parseKeyval(b []byte) ([]byte, error) { func parseVal(b []byte) ([]byte, error) { // val = string / boolean / array / inline-table / date-time / float / integer + var err error c := b[0] switch c { // strings case '"': - var rest []byte - var err error if scanFollowsMultilineBasicStringDelimiter(b) { - _, rest, err = parseMultilineBasicString(b) + _, b, err = parseMultilineBasicString(b) } else { - _, rest, err = parseBasicString(b) + _, b, err = parseBasicString(b) } - return rest, err + return b, err case '\'': if scanFollowsMultilineLiteralStringDelimiter(b) { - return parseMultilineLiteralString(b) + _, b, err = parseMultilineLiteralString(b) } - _, rest, err := scanLiteralString(b) - return rest, err + _, b, err = scanLiteralString(b) + return b, err // TODO boolean // TODO array @@ -127,6 +126,24 @@ func parseVal(b []byte) ([]byte, error) { } } +func parseMultilineLiteralString(b []byte) (string, []byte, error) { + token, rest, err := scanMultilineLiteralString(b) + if err != nil { + return "", nil, err + } + + i := 3 + + // skip the immediate new line + if token[i] == '\n' { + i++ + } else if token[i] == '\r' && token[i+1] == '\n' { + i += 2 + } + + return string(token[i : len(b)-3]), rest, err +} + func parseMultilineBasicString(b []byte) (string, []byte, error) { //ml-basic-string = ml-basic-string-delim [ newline ] ml-basic-body //ml-basic-string-delim diff --git a/toml_test.go b/toml_test.go index 446b60a..f065c18 100644 --- a/toml_test.go +++ b/toml_test.go @@ -39,7 +39,7 @@ a = false`, `[[foo]]`, } -func TestParse(t *testing.T) { +func TestScan(t *testing.T) { for i, data := range inputs { t.Run(fmt.Sprintf("example %d", i), func(t *testing.T) { fmt.Printf("input:\n\t`%s`\n", data) @@ -55,6 +55,17 @@ func TestParse(t *testing.T) { } } +func TestParse(t *testing.T) { + for i, data := range inputs { + t.Run(fmt.Sprintf("example %d", i), func(t *testing.T) { + fmt.Printf("input:\n\t`%s`\n", data) + b := []byte(data) + err := parse(b) + require.NoError(t, err) + }) + } +} + type noopParser struct { }