diff --git a/format/format.go b/format/format.go index d6f0518..af80355 100644 --- a/format/format.go +++ b/format/format.go @@ -312,7 +312,7 @@ func spaceBetween(prev, cur token.Token) bool { return false case token.Comma: return false - case token.Star, token.Plus, token.Minus, token.Slash: + case token.Star, token.Plus, token.Minus, token.Slash, token.Pipe: return false case token.LShift, token.RShift, token.Arrow, token.At: return false @@ -328,7 +328,7 @@ func spaceBetween(prev, cur token.Token) bool { } } switch prev.Kind { - case token.LParen, token.Star, token.Plus, token.Minus, token.Slash: + case token.LParen, token.Star, token.Plus, token.Minus, token.Slash, token.Pipe: return false case token.Dollar: return false diff --git a/format/format_test.go b/format/format_test.go index b812690..2d08238 100644 --- a/format/format_test.go +++ b/format/format_test.go @@ -85,7 +85,7 @@ func TestBlankLines(t *testing.T) { "TEXT ·f(SB), NOSPLIT, $0\n" + "first:\n" + // first label: no blank after TEXT "XORQ AX, AX\n" + - "JMP next\n" + // unlabeled glue: fmt inserts a blank before next: + "JMP next\n" + // unlabelled glue: fmt inserts a blank before next: "next:\n" + "stacked:\n" + // stacked labels share an address: no blank between "INCQ AX\n" + @@ -143,6 +143,7 @@ func TestOperandSpacing(t *testing.T) { "swin_base+0(FP)": "swin_base+0(FP)", "mask24<>(SB)": "mask24<>(SB)", "·idx16+0(SB)/4": "·idx16+0(SB)/4", + "NOSPLIT|DUPOK": "NOSPLIT|DUPOK", } for in, want := range cases { toks := lexOperands(in) @@ -152,6 +153,36 @@ func TestOperandSpacing(t *testing.T) { } } +// TestFlagListRoundTrip pins the '|' flag separator and the +// marker through a full format pass: the bars the Go toolchain requires and +// the ABI bracket must survive byte for byte, on TEXT and GLOBL alike. +func TestFlagListRoundTrip(t *testing.T) { + for _, in := range []string{ + "TEXT ·f(SB), NOSPLIT|NOFRAME|DUPOK, $0\n\tRET\n", + "TEXT ·foo(SB), NOSPLIT, $-0-24\n\tRET\n", + "GLOBL ·mask(SB), RODATA|NOPTR, $8\n", + } { + if got := Source(in); got != in { + t.Fatalf("flag list did not round-trip:\n--- got ---\n%q\n--- want ---\n%q", got, in) + } + } +} + +// TestCRLFInputIsNormalisedToLF checks that a CRLF file comes out with +// uniform LF endings: a // comment must not carry its line's trailing \r +// into the output. +func TestCRLFInputIsNormalisedToLF(t *testing.T) { + in := "// func f()\r\nTEXT ·f(SB), NOSPLIT, $0\r\nRET\r\n" + want := "// func f()\nTEXT ·f(SB), NOSPLIT, $0\n\tRET\n" + got := Source(in) + if got != want { + t.Fatalf("CRLF formatting mismatch:\n--- got ---\n%q\n--- want ---\n%q", got, want) + } + if strings.Contains(got, "\r") { + t.Fatalf("output still contains CR: %q", got) + } +} + // lexOperands lexes a single operand string and drops the EOF token. func lexOperands(s string) []token.Token { toks := lexer.Tokenize(s)