func readMode(src []byte, ext string) (string, []string, error) {
	if bytes.HasPrefix(src, BOM) {
		src = src[len(BOM):]
	}
	switch ext {
	case ".go", ".script":
		for _, l := range strings.Split(string(src), "\n") {
			l = strings.TrimSpace(l)
			if l == "" {
				continue
			}
			if isBuildConstraints(l) {
				continue
			}
			if !strings.HasPrefix(l, "//") {
				return "", nil, fmt.Errorf("not a valid directive: %s", l)
			}
			l = strings.TrimPrefix(l, "//")
			l = strings.TrimSpace(l)
			if strings.HasPrefix(l, "skip ") {
				return "skip", []string{}, nil
			}
			s := strings.Split(l, " ")
			return s[0], s[1:], nil
		}
	default:
		for _, l := range strings.Split(string(src), "\n") {
			l = strings.TrimSpace(l)
			if l == "" {
				continue
			}
			if strings.HasPrefix(l, "{#") && strings.HasSuffix(l, "#}") {
				l = strings.TrimPrefix(l, "{#")
				l = strings.TrimSuffix(l, "#}")
				l = strings.TrimSpace(l)
				if strings.HasPrefix(l, "skip ") {
					return "skip", []string{}, nil
				}
				s := strings.Split(l, " ")
				return s[0], s[1:], nil
			}
			return "", nil, fmt.Errorf("not a valid directive: %s", l)
		}
	}
	return "", nil, errors.New("mode not specified")
}
readMode reports the mode (and any options) associated to src.

Mode is specified in programs and scripts using a comment line (starting with
"//"):

// mode

templates must encapsulate mode in a line containing just a comment:

{# readMode #}

After the mode keyword, some arguments may be provided using the syntax
accepted by function flag.Parse.

// run -time 10s

As a special case, the 'skip' comment can be followed by any sequence of
characters (after a whitespace character) that will be ignored. This is
useful to put an inline comment to the "skip" comment, explaining the reason
why a given test cannot be run. For example:

// skip because feature X is not supported
// skip : enable when bug Y will be fixed
package main
import (
	"bytes"
	"errors"
	"flag"
	"fmt"
	"math"
	"os"
	"os/exec"
	"path/filepath"
	"regexp"
	"runtime"
	"strconv"
	"strings"
	"sync"
	"sync/atomic"
	"time"
	"github.com/rogpeppe/go-internal/imports"
)
var BOM = []byte("\ufeff")
const (
	colorInfo  = "\033[1;34m"
	colorBad   = "\033[1;31m"
	colorGood  = "\033[1;32m"
	colorReset = "\033[0m"
)
func main() {
	start := time.Now()
	var (
		color             = flag.Bool("c", false, "enable colored output. output device must support ANSI escape sequences. require verbose or stats to take effect")
		keepTestingOnFail = flag.Bool("k", false, "keep testing on fail")
		parallel          = flag.Int("l", 4, "number of parallel tests to run")
		pattern           = flag.String("p", "", "executes test whose path is matched by the given pattern. regular expressions are supported, in the syntax of stdlib package 'regexp'")
		stat              = flag.Bool("s", false, "print some stats about executed tests. Parallelism is not influenced.")
		verbose           = flag.Bool("v", false, "verbose. if set, parallelism is set to 1 and keep testing on fail is set to false")
	)
	flag.Parse()
	if *verbose {
		*parallel = 1
		*keepTestingOnFail = false
	}
	if flag.NArg() > 0 {
		_, _ = fmt.Fprintf(os.Stderr, "too many arguments on the command line\n")
		flag.Usage()
		os.Exit(1)
	}
	var tags map[string]bool
	{
		goos := os.Getenv("GOOS")
		if goos == "" {
			goos = runtime.GOOS
		}
		goarch := os.Getenv("GOARCH")
		if goarch == "" {
			goarch = runtime.GOARCH
		}
		tags = map[string]bool{
			goos:   true,
			goarch: true,
			"cgo":  cgoEnabled,
		}
		goVersion := goBaseVersion(runtime.Version())
		subv, err := strconv.Atoi(goVersion[len("go1."):])
		if err != nil {
			_, _ = fmt.Fprintln(os.Stderr, err)
			os.Exit(1)
		}
		for i := 1; i <= subv; i++ {
			tags[fmt.Sprintf("go1.%d", i)] = true
		}
	}
	err := buildCmd()
	if err != nil {
		_, _ = fmt.Fprintf(os.Stderr, "cannot build cmd: %s\n", err)
		os.Exit(1)
	}
	paths, err := filePaths(*pattern)
	if err != nil {
		_, _ = fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}
	if len(paths) == 0 {
		_, _ = fmt.Fprintln(os.Stderr, "specified pattern does not match any path")
		os.Exit(1)
	}
	maxPathLen := 0
	for _, fp := range paths {
		if len(fp) > maxPathLen {
			maxPathLen = len(fp)
		}
	}
	if *verbose || *stat {
		fmt.Printf("%d tests found (including skipped and incompatible ones)\n", len(paths))
	}
	wg := sync.WaitGroup{}
	queue := make(chan bool, *parallel)
	countTotal := int64(0)
	countSkipped := int64(0)
	countIncompatible := int64(0)
	for _, path := range paths {
		wg.Add(1)
		go func(path string) {
			queue <- true
			atomic.AddInt64(&countTotal, 1)
			src, err := os.ReadFile(path)
			if err != nil {
				panic(err)
			}
			ext := filepath.Ext(path)
			if *stat && !*verbose {
				percentage := strconv.Itoa(int(math.Floor(float64(countTotal) / float64(len(paths)) * 100)))
				fmt.Printf("\r%s%% (test %d/%d)", percentage, countTotal, len(paths))
			}
			if *verbose {
				if *color {
					fmt.Print(colorInfo)
				}
				percentage := strconv.Itoa(int(math.Floor(float64(countTotal) / float64(len(paths)) * 100)))
				for i := len(percentage); i < 4; i++ {
					percentage = " " + percentage
				}
				fmt.Print("[" + percentage + "%  ] ")
				if *color {
					fmt.Print(colorReset)
				}
				fmt.Print(path)
				for i := len(path); i < maxPathLen+2; i++ {
					fmt.Print(" ")
				}
			}
			if !imports.ShouldBuild(src, tags) {
				atomic.AddInt64(&countIncompatible, 1)
				if *verbose {
					fmt.Println("[ skipped, not compatible ]")
				}
				<-queue
				wg.Done()
				return
			}
			mode, opts, err := readMode(src, ext)
			if err != nil {
				_, _ = fmt.Fprintf(os.Stderr, "cannot read mode: %s\n", err)
				os.Exit(1)
			}
			if mode == "skip" {
				atomic.AddInt64(&countSkipped, 1)
			} else {
				err = test(src, mode, path, opts, *keepTestingOnFail)
				if err != nil {
					_, _ = fmt.Fprintln(os.Stderr, err)
					os.Exit(1)
				}
			}
			if *verbose {
				if mode == "skip" {
					fmt.Println("[ skipped ]")
				} else {
					if *color {
						fmt.Printf(colorGood+"ok"+colorReset+"     (%s)", mode)
					} else {
						fmt.Printf("ok     (%s)", mode)
					}
					for i := len(mode); i < 15; i++ {
						fmt.Print(" ")
					}
					fmt.Println("")
				}
			}
			<-queue
			wg.Done()
		}(path)
	}
	wg.Wait()
	if *verbose || *stat {
		if *color {
			fmt.Print(colorGood)
		}
		countExecuted := countTotal - countSkipped - countIncompatible
		totalTime := time.Now().Sub(start).Truncate(time.Millisecond)
		if countIncompatible > 0 {
			fmt.Printf("\ndone!   %d tests executed, %d tests skipped (with %d not compatible) in %s\n",
				countExecuted, countSkipped+countIncompatible, countIncompatible, totalTime)
		} else {
			fmt.Printf("\ndone!   %d tests executed, %d tests skipped in %s\n",
				countExecuted, countSkipped, totalTime)
		}
		if *color {
			fmt.Print(colorReset)
		}
	}
}
func buildCmd() error {
	cmd := exec.Command("go", "build")
	cmd.Dir = "./cmd"
	var stderr bytes.Buffer
	cmd.Stderr = &stderr
	err := cmd.Run()
	if err != nil {
		return errors.New(stderr.String())
	}
	return nil
}
func cmd(stdin []byte, opts []string, args ...string) (int, []byte, []byte) {
	var cmdArgs []string
	cmdArgs = append(cmdArgs, opts...)
	cmdArgs = append(cmdArgs, args...)
	cmd := exec.Command("./cmd/cmd", cmdArgs...)
	var stdout bytes.Buffer
	var stderr bytes.Buffer
	cmd.Stdout = &stdout
	cmd.Stderr = &stderr
	cmd.Stdin = bytes.NewReader(stdin)
	err := cmd.Run()
	if err != nil {
		if ee, ok := err.(*exec.ExitError); ok {
			return ee.ProcessState.ExitCode(), stdout.Bytes(), stderr.Bytes()
		}
		panic(err)
	}
	return 0, stdout.Bytes(), stderr.Bytes()
}
var lf = []byte{'\n'}
var errorComment = []byte("// ERROR ")
func errorcheck(src []byte, filePath string, opts []string) error {
	ext := filepath.Ext(filePath)
	tests := differentiateSources(string(src))
	var srcWithoutErrors []byte
	for _, line := range bytes.SplitAfter(src, lf) {
		if bytes.Contains(line, errorComment) {
			srcWithoutErrors = append(srcWithoutErrors, '\n')
		} else {
			srcWithoutErrors = append(srcWithoutErrors, line...)
		}
	}
	exitCode, _, stderr := cmd(srcWithoutErrors, opts, "build", ext)
	if exitCode != 0 {
		if p := bytes.Index(stderr, []byte{':'}); p > 0 {
			return fmt.Errorf("%s%s", filePath, stderr[p:])
		}
		return fmt.Errorf("%s: %s", filePath, stderr)
	}
	if len(tests) == 0 {
		return errors.New("no // ERROR comments found")
	}
	for _, test := range tests {
		exitCode, stdout, stderr := cmd([]byte(test.src), opts, "build", ext)
		if exitCode == 0 {
			return fmt.Errorf("expecting error '%s' but exit code is 0", test.err)
		}
		if len(stdout) > 0 {
			return errors.New("stdout should be empty")
		}
		if len(stderr) == 0 {
			return fmt.Errorf("expected error '%s', got nothing", test.err)
		}
		re := regexp.MustCompile(test.err)
		stderr = []byte(removePrefixFromError(string(stderr)))
		if !re.Match(stderr) {
			return fmt.Errorf("output does not match with the given regular expression:\n\n\tregexp:    %s\n\toutput:    %s\n", test.err, stderr)
		}
	}
	return nil
}
func mustBeOK(exitCode int, stdout, stderr []byte) error {
	_, err := unwrapStdout(exitCode, stdout, stderr)
	if err != nil {
		return err
	}
	if len(stderr) > 0 {
		return errors.New("unexpected standard output: " + string(stderr))
	}
	return nil
}
func filePaths(pattern string) ([]string, error) {
	var paths []string
	var re *regexp.Regexp
	if pattern != "" {
		re = regexp.MustCompile(pattern)
	}
	err := filepath.Walk("testdata", func(path string, info os.FileInfo, err error) error {
		if err != nil {
			return err
		}
		if path[0] == '.' {
			return nil
		}
		switch filepath.Ext(path) {
		case ".go", ".script", ".html", ".css", ".js", ".json", ".md":
		default:
			return nil
		}
		if re != nil && !re.MatchString(path) {
			return nil
		}
		if strings.Contains(path, ".dir"+string(filepath.Separator)) {
			return nil
		}
		paths = append(paths, path)
		return nil
	})
	if err != nil {
		return nil, err
	}
	return paths, nil
}
func goldenCompare(testPath string, got []byte) error {
	ext := filepath.Ext(testPath)
	goldenPath := strings.TrimSuffix(testPath, ext) + ".golden"
	goldenData, err := os.ReadFile(goldenPath)
	if err != nil {
		return err
	}
	goldenData = regexp.MustCompile(`(?m)^ 
	expected := bytes.TrimSpace(goldenData)
	got = bytes.TrimSpace(got)
	{
		expectedLines := strings.Split(string(expected), "\n")
		gotLines := strings.Split(string(got), "\n")
		numLines := len(expectedLines)
		if len(gotLines) < numLines {
			numLines = len(gotLines)
		}
		for i := 0; i < numLines; i++ {
			if expectedLines[i] != gotLines[i] {
				return fmt.Errorf("difference at line %d\nexpecting:  %q\ngot:        %q.\n\nFull output: \n------------------------\n%s", i+1, expectedLines[i], gotLines[i], got)
			}
		}
		if len(expectedLines) != len(gotLines) {
			err := fmt.Sprintf("expecting an output of %d lines, got %d lines\n", len(expectedLines), len(gotLines))
			if len(expectedLines) > len(gotLines) {
				err += "expected lines (not returned by the test): \n"
				for i := len(gotLines); i < len(expectedLines); i++ {
					err += fmt.Sprintf("> " + expectedLines[i] + "\n")
				}
			}
			if len(expectedLines) < len(gotLines) {
				err += "additional lines returned by the test (not expected): \n"
				for i := len(expectedLines); i < len(gotLines); i++ {
					err += fmt.Sprintf("> " + gotLines[i] + "\n")
				}
			}
			return errors.New(err)
		}
	}
	if bytes.Compare(expected, got) != 0 {
		return fmt.Errorf("\n\nexpecting:  %s\ngot:        %s", expected, got)
	}
	return nil
}
func isBuildConstraints(line string) bool {
	line = strings.TrimSpace(line)
	if !strings.HasPrefix(line, "//") {
		return false
	}
	line = strings.TrimPrefix(line, "//")
	line = strings.TrimSpace(line)
	return strings.HasPrefix(line, "+build")
}