fix(arch): narrow file names by go/build's suffix rule
Assisted-by: GLM 5.3 Flash
This commit is contained in:
1 parent
c107b45933
commit
a90ec84bee
2 files changed
+60
-12
No files matched your search
+31
-10
@@ -24,20 +24,41 @@ const (
|
||||
Unknown Arch = ""
|
||||
)
|
||||
|
||||
// FromFilename guesses the target architecture from a source file name. Go
|
||||
// assembly files conventionally carry a GOARCH suffix such as "_amd64.s",
|
||||
// "_arm64.s", "_riscv64.s" or "_loong64.s". It returns Unknown when no suffix
|
||||
// matches.
|
||||
// FromFilename guesses the target architecture from a source file name, by
|
||||
// go/build's goodOSArchFile rule: directories are stripped, the name is cut
|
||||
// at its first dot, everything before the first underscore is ignored and a
|
||||
// trailing _test segment is dropped; the name is per-architecture only when
|
||||
// its final underscore segment is an architecture name (foo_amd64.s,
|
||||
// sys_darwin_arm64.s, foo_amd64_test.s). Any other name narrows nothing:
|
||||
// not one whose last segment merely contains an architecture name
|
||||
// (x_loong64y.s), not one with no underscore at all (amd64.s, which
|
||||
// go/build also keeps generic), and not one differing in case
|
||||
// (foo_AMD64.s), because the segment match is case-sensitive as go/build's
|
||||
// is. A name carrying an operating system alone (foo_linux.s) narrows by
|
||||
// GOOS rather than architecture, and one carrying an architecture gasm
|
||||
// does not assemble for (vlop_arm.s) reports Unknown so the caller's own
|
||||
// port filter decides. It returns Unknown when the name narrows nothing.
|
||||
func FromFilename(name string) Arch {
|
||||
lower := strings.ToLower(name)
|
||||
switch {
|
||||
case strings.Contains(lower, "_amd64"):
|
||||
if i := strings.LastIndexByte(name, '/'); i >= 0 {
|
||||
name = name[i+1:]
|
||||
}
|
||||
name, _, _ = strings.Cut(name, ".")
|
||||
i := strings.Index(name, "_")
|
||||
if i < 0 {
|
||||
return Unknown
|
||||
}
|
||||
segs := strings.Split(name[i:], "_")
|
||||
if last := len(segs) - 1; segs[last] == "test" {
|
||||
segs = segs[:last]
|
||||
}
|
||||
switch segs[len(segs)-1] {
|
||||
case "amd64":
|
||||
return AMD64
|
||||
case strings.Contains(lower, "_arm64"):
|
||||
case "arm64":
|
||||
return ARM64
|
||||
case strings.Contains(lower, "_riscv64"), strings.Contains(lower, "_riscv"):
|
||||
case "riscv64":
|
||||
return RISCV
|
||||
case strings.Contains(lower, "_loong64"), strings.Contains(lower, "_loong"):
|
||||
case "loong64":
|
||||
return LOONG64
|
||||
default:
|
||||
return Unknown
|
||||
|
||||
+29
-2
@@ -7,13 +7,40 @@ import "testing"
|
||||
|
||||
func TestFromFilename(t *testing.T) {
|
||||
cases := map[string]Arch{
|
||||
// Positive: the final underscore segment is the architecture.
|
||||
"avx2_amd64.s": AMD64,
|
||||
"foo_arm64.s": ARM64,
|
||||
"portable.s": Unknown,
|
||||
"decode_ARM64.S": ARM64,
|
||||
"kernels_amd64.s": AMD64,
|
||||
"kernel_riscv64.s": RISCV,
|
||||
"kernel_loong64.s": LOONG64,
|
||||
"decode_arm64.S": ARM64, // the extension is cut with the first dot
|
||||
// OS before arch: the _<os>_<arch> pair form.
|
||||
"sys_darwin_arm64.s": ARM64,
|
||||
"rt0_linux_amd64.s": AMD64,
|
||||
// A trailing _test segment is dropped before the suffix rule.
|
||||
"foo_amd64_test.s": AMD64,
|
||||
// Trailing junk: a final segment that merely contains an
|
||||
// architecture name narrows nothing, exactly as go/build's
|
||||
// segment rule says.
|
||||
"x_loong64y.s": Unknown,
|
||||
"asm_amd64x.s": Unknown, // a real GOROOT name
|
||||
"asm_darwin_arm64_gc.s": Unknown, // the trailing _gc segment is junk
|
||||
"x_loong.s": Unknown,
|
||||
"foo_amd64x_test.s": Unknown,
|
||||
// Case sensitivity: the segment match is exact, as go/build's is.
|
||||
"foo_AMD64.s": Unknown,
|
||||
"decode_ARM64.S": Unknown,
|
||||
// No underscore at all: generic whatever the stem says.
|
||||
"amd64.s": Unknown,
|
||||
"portable.s": Unknown,
|
||||
// A GOOS-only name narrows by operating system, not architecture.
|
||||
"foo_linux.s": Unknown,
|
||||
// An architecture gasm does not assemble for: named, but Unknown.
|
||||
"vlop_arm.s": Unknown,
|
||||
"foo_riscv.s": Unknown,
|
||||
// Directories are stripped first, whatever dots they carry.
|
||||
"some/dir/kernel_loong64.s": LOONG64,
|
||||
"/a.b/x_amd64.s": AMD64,
|
||||
}
|
||||
for name, want := range cases {
|
||||
if got := FromFilename(name); got != want {
|
||||
|
||||
Reference in new issue
Block a user