From a55c206bd014e162fd6d3c4ed98f1b9ede5ee48e Mon Sep 17 00:00:00 2001 From: James Nugent Date: Mon, 11 Jul 2016 14:31:33 -0600 Subject: [PATCH] Support multiline string literals in HCL This allows multiline strings to be parsed in order to make HIL interpolations nicer in Terraform: ``` my_complex_thing = "${merge(var.list1, var.list2, var.list3)}" ``` --- decoder_test.go | 6 ++++++ hcl/scanner/scanner.go | 2 +- hcl/scanner/scanner_test.go | 4 ++-- hcl/strconv/quote.go | 3 --- hcl/strconv/quote_test.go | 2 -- test-fixtures/multiline_literal.hcl | 2 ++ 6 files changed, 11 insertions(+), 8 deletions(-) create mode 100644 test-fixtures/multiline_literal.hcl diff --git a/decoder_test.go b/decoder_test.go index a53b15b..c074981 100644 --- a/decoder_test.go +++ b/decoder_test.go @@ -79,6 +79,12 @@ func TestDecode_interface(t *testing.T) { true, nil, }, + { + "multiline_literal.hcl", + false, + map[string]interface{}{"multiline_literal": testhelper.Unix2dos(`hello + world`)}, + }, { "multiline_no_marker.hcl", true, diff --git a/hcl/scanner/scanner.go b/hcl/scanner/scanner.go index 174119a..b204165 100644 --- a/hcl/scanner/scanner.go +++ b/hcl/scanner/scanner.go @@ -469,7 +469,7 @@ func (s *Scanner) scanString() { // read character after quote ch := s.next() - if ch == '\n' || ch < 0 || ch == eof { + if ch < 0 || ch == eof { s.err("literal not terminated") return } diff --git a/hcl/scanner/scanner_test.go b/hcl/scanner/scanner_test.go index d787afd..f331896 100644 --- a/hcl/scanner/scanner_test.go +++ b/hcl/scanner/scanner_test.go @@ -10,7 +10,7 @@ import ( "github.com/hashicorp/hcl/hcl/token" ) -var f100 = "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" +var f100 = strings.Repeat("f", 100) type tokenPair struct { tok token.Type @@ -494,7 +494,7 @@ func TestError(t *testing.T) { testError(t, `"`, "1:2", "literal not terminated", token.STRING) testError(t, `"abc`, "1:5", "literal not terminated", token.STRING) - testError(t, `"abc`+"\n", "1:5", "literal not terminated", token.STRING) + testError(t, `"abc`+"\n", "2:1", "literal not terminated", token.STRING) testError(t, `/*/`, "1:4", "comment not terminated", token.COMMENT) } diff --git a/hcl/strconv/quote.go b/hcl/strconv/quote.go index 74e232e..956c899 100644 --- a/hcl/strconv/quote.go +++ b/hcl/strconv/quote.go @@ -27,9 +27,6 @@ func Unquote(s string) (t string, err error) { if quote != '"' { return "", ErrSyntax } - if contains(s, '\n') { - return "", ErrSyntax - } // Is it trivial? Avoid allocation. if !contains(s, '\\') && !contains(s, quote) && !contains(s, '$') { diff --git a/hcl/strconv/quote_test.go b/hcl/strconv/quote_test.go index c369144..af2d848 100644 --- a/hcl/strconv/quote_test.go +++ b/hcl/strconv/quote_test.go @@ -65,8 +65,6 @@ var misquoted = []string{ "`\"", `"\'"`, `'\"'`, - "\"\n\"", - "\"\\n\n\"", "'\n'", `"${"`, `"${foo{}"`, diff --git a/test-fixtures/multiline_literal.hcl b/test-fixtures/multiline_literal.hcl new file mode 100644 index 0000000..f89fdfc --- /dev/null +++ b/test-fixtures/multiline_literal.hcl @@ -0,0 +1,2 @@ +multiline_literal = "hello + world" \ No newline at end of file