Source file src/simd/archsimd/_gen/sgutil/paths.go

     1  // Copyright 2026 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package sgutil
     6  
     7  import (
     8  	"flag"
     9  	"fmt"
    10  	"os"
    11  	"path/filepath"
    12  	"strings"
    13  )
    14  
    15  type PathList struct {
    16  	paths     []string
    17  	fromShell bool // if false, perform our own shell var expansion
    18  }
    19  
    20  func FlagPathList(name string, usage string, value ...string) *PathList {
    21  	p := &PathList{paths: value, fromShell: false}
    22  	flag.Var(p, name, usage)
    23  	return p
    24  }
    25  
    26  func (l *PathList) String() string {
    27  	return strings.Join(l.paths, string(filepath.ListSeparator))
    28  }
    29  
    30  func (l *PathList) Set(val string) error {
    31  	l.paths = filepath.SplitList(val)
    32  	l.fromShell = true
    33  	return nil
    34  }
    35  
    36  // Find returns the first element of l containing a file by the given name. If
    37  // file is not found in the path list, it returns a descriptive error.
    38  func (l *PathList) Find(file string) (string, error) {
    39  	for _, path := range l.paths {
    40  		if !l.fromShell {
    41  			path = os.ExpandEnv(path)
    42  		}
    43  		if path == "" {
    44  			// Probably an unknown shell variable. Ignore.
    45  			continue
    46  		}
    47  		if _, err := os.Stat(filepath.Join(path, file)); err == nil {
    48  			return filepath.Abs(path)
    49  		}
    50  	}
    51  	var errMsg strings.Builder
    52  	fmt.Fprintf(&errMsg, "%q not found in any of:", file)
    53  	for _, path := range l.paths {
    54  		errMsg.WriteString("\n\t")
    55  		errMsg.WriteString(path)
    56  	}
    57  	return "", fmt.Errorf("%s", errMsg.String())
    58  }
    59  
    60  // FlagXEDPath registers and returns a global -xedPath flag.
    61  func FlagXEDPath(genRoot string) *PathList {
    62  	return FlagPathList("xedPath", "`list` of directories to search for XED data (must be an XED obj/dgen directory)",
    63  		"$XEDPATH", genRoot+"/extern/xed/obj/dgen", "$HOME/xed/obj/dgen")
    64  }
    65  
    66  func ResolveXEDPath(flag *PathList) (string, error) {
    67  	xedPath, err := flag.Find("all-dec-instructions.txt")
    68  	if err != nil {
    69  		return "", fmt.Errorf(`%s
    70  Could not find XED data. Use fetch-xed.sh to download it, or set
    71  $XEDPATH or -xedPath to the XED obj/dgen directory.`, err)
    72  	}
    73  	return xedPath, nil
    74  }
    75  
    76  // FlagARM64Path registers and returns a global -arm64Path flag.
    77  func FlagARM64Path(genRoot string) *PathList {
    78  	const isaDir = "ISA_A64_xml_A_profile_2026-03_96-2026-03_rel"
    79  	return FlagPathList("arm64Path", "`list` of directories to search for ARM64 ISA data",
    80  		"$ARM64_ISA_PATH", genRoot+"/extern/"+isaDir, "$HOME/Downloads/"+isaDir)
    81  }
    82  
    83  func ResolveARM64Path(flag *PathList) (string, error) {
    84  	arm64Path, err := flag.Find("abs_advsimd.xml")
    85  	if err != nil {
    86  		return "", fmt.Errorf(`%s
    87  Could not find ARM64 ISA data. Use fetch-arm64.sh to download it, or set
    88  $ARM64_ISA_PATH or -arm64Path to the ARM64 ISA specification directory.`, err)
    89  	}
    90  	return arm64Path, nil
    91  
    92  }
    93  

View as plain text