58 lines
1.2 KiB
Go
58 lines
1.2 KiB
Go
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,
|
|
}
|
|
}
|