package compiler import "os" import "io/fs" import "runtime" import "strings" import "path/filepath" // OsFS returns an fs.FS that represents the operating system's filesystem. In // Windows, volume names (A:, B:, C:, etc.) are treated as subdirectories within // the root. type OsFS struct { } // win // C:/Something -> C:\Something // "" -> "" // unix // C:/Something -> /C:/Something // "" -> / func (this OsFS) Open (name string) (fs.File, error) { fullname, err := this.nativize(name) if err != nil { return nil, this.err("open", name, err) } file, err := os.Open(fullname) if err != nil { return nil, this.err("open", name, err.(*os.PathError).Err) } return file, nil } func (this OsFS) nativize (name string) (string, error) { if !fs.ValidPath(name) { return "", fs.ErrInvalid } if filepath.Separator != '/' { if strings.Contains(name, string(filepath.Separator)) { return "", fs.ErrInvalid } } if runtime.GOOS != "windows" { // TODO is this correct for all non-windows systems? name = "/" + name } name = filepath.FromSlash(name) return name, nil } func (this OsFS) err (op, path string, err error) error { return &fs.PathError { Op: "open", Path: path, Err: err, } }