From bdfa619f77d3524470b80ee4b784b76fc213e7ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Mart=C3=AD?= Date: Mon, 25 Dec 2023 22:52:44 +0100 Subject: [PATCH] support inline comments in asm #include lines That is, the assembly line #include "foo.h" // bar would make garble run into an error, as we would try to parse the #include directive before we stripped comments, effectively trying to unquote the string "foo.h" // bar rather than just the included filename "foo.h" Add test cases for asm but also cgo, while at it. Fixes #812. --- main.go | 26 ++++++++++++++------------ testdata/script/asm.txtar | 2 +- testdata/script/cgo.txtar | 2 +- 3 files changed, 16 insertions(+), 14 deletions(-) diff --git a/main.go b/main.go index 716d5fb..7c25dfc 100644 --- a/main.go +++ b/main.go @@ -688,14 +688,24 @@ func (tf *transformer) transformAsm(args []string) ([]string, error) { for scanner.Scan() { line := scanner.Text() - // First, handle hash directives without leading whitespaces. + // Whole-line comments might be directives, leave them in place. + // For example: //go:build race + // Any other comment, including inline ones, can be discarded entirely. + line, comment, hasComment := strings.Cut(line, "//") + if hasComment && line == "" { + buf.WriteString("//") + buf.WriteString(comment) + buf.WriteByte('\n') + continue + } - // #include "foo.h" + // Preprocessor lines to include another file. + // For example: #include "foo.h" if quoted := strings.TrimPrefix(line, "#include"); quoted != line { quoted = strings.TrimSpace(quoted) path, err := strconv.Unquote(quoted) - if err != nil { - return nil, err + if err != nil { // note that strconv.Unquote errors do not include the input string + return nil, fmt.Errorf("cannot unquote %q: %v", quoted, err) } newPath := newHeaderPaths[path] switch newPath { @@ -734,16 +744,8 @@ func (tf *transformer) transformAsm(args []string) ([]string, error) { continue } - // Leave "//" comments unchanged; they might be directives. - line, comment, hasComment := strings.Cut(line, "//") - // Anything else is regular assembly; replace the names. tf.replaceAsmNames(&buf, []byte(line)) - - if hasComment { - buf.WriteString("//") - buf.WriteString(comment) - } buf.WriteByte('\n') } if err := scanner.Err(); err != nil { diff --git a/testdata/script/asm.txtar b/testdata/script/asm.txtar index 59e8a77..65f524e 100644 --- a/testdata/script/asm.txtar +++ b/testdata/script/asm.txtar @@ -65,7 +65,7 @@ func main() { -- garble_main_amd64.s -- #include "garble_define_amd64.h" -#include "extra/garble_define2_amd64.h" +#include "extra/garble_define2_amd64.h" // Inline: many·special∕asm·runes. // A comment may include many·special∕asm·runes and it's okay. //No space: many·special∕asm·runes. diff --git a/testdata/script/cgo.txtar b/testdata/script/cgo.txtar index c02fa95..ef9d44e 100644 --- a/testdata/script/cgo.txtar +++ b/testdata/script/cgo.txtar @@ -63,7 +63,7 @@ import ( ) /* -#include "separate.h" +#include "separate.h" // inline comment static int privateAdd(int a, int b) { return a + b;