env GOPRIVATE=test/main

# Unknown build flags should result in errors.
! garble reverse -badflag
stderr 'flag provided but not defined'

garble build
exec ./main
cp stderr main.stderr

# Ensure that the garbled panic output looks correct.
# This output is not reproducible between 'go test' runs,
# so we can't use a static golden file.
grep 'goroutine 1 \[running\]' main.stderr
! grep 'ExportedLibFunc|unexportedMainFunc|test/main|main\.go|lib\.go' main.stderr

stdin main.stderr
garble reverse
cmp stdout reverse.stdout

[short] stop # no need to verify this with -short

# Ensure that the reversed output matches the non-garbled output.
go build -trimpath
exec ./main
cmp stderr reverse.stdout

# Ensure that we can still reverse with -literals.
garble -literals build
exec ./main
cp stderr main-literals.stderr

stdin main-literals.stderr
garble -literals reverse
cmp stdout reverse.stdout

# Reversing a -literals output without the flag should fail.
stdin main-literals.stderr
! garble reverse
cmp stdout main-literals.stderr

-- go.mod --
module test/main

go 1.16
-- main.go --
package main

import (
	"os"

	"test/main/lib"
)

func main() {
	unexportedMainFunc()
}

func unexportedMainFunc() {
	anonFunc := func() {
		lt := lib.ExportedLibType{}
		if err := lt.ExportedLibMethod(os.Stderr); err != nil {
			panic(err)
		}
	}
	anonFunc()
}
-- lib/lib.go --
package lib

import (
	"io"
	"regexp"
	"runtime/debug"
)

type ExportedLibType struct{}

func (*ExportedLibType) ExportedLibMethod(w io.Writer) error {
	return printStackTrace(w)
}

func printStackTrace(w io.Writer) error {
	// Panic outputs include "0xNN" pointers and offsets which change
	// between platforms.
	// Strip them out here, to have portable static stdout files.
	rxVariableSuffix := regexp.MustCompile(`0x[0-9a-f]+`)

	// Keep this comment here, because comments affect line numbers.

	stack := debug.Stack()
	stack = rxVariableSuffix.ReplaceAll(stack, []byte("0x??"))
	_, err := w.Write(stack)
	return err
}
-- reverse.stdout --
goroutine 1 [running]:
runtime/debug.Stack(0x??, 0x??, 0x??)
	runtime/debug/stack.go:24 +0x??
test/main/lib.printStackTrace(0x??, 0x??, 0x??, 0x??)
	test/main/lib/lib.go:23 +0x??
test/main/lib.(*ExportedLibType).ExportedLibMethod(...)
	test/main/lib/lib.go:12
main.unexportedMainFunc.func1()
	test/main/main.go:16 +0x??
main.unexportedMainFunc()
	test/main/main.go:20 +0x??
main.main()
	test/main/main.go:10 +0x??
