Add custom fs implementation
This commit is contained in:
parent
1c61235b63
commit
15e418d8c1
57
compiler/fs.go
Normal file
57
compiler/fs.go
Normal file
@ -0,0 +1,57 @@
|
||||
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,
|
||||
}
|
||||
}
|
@ -20,10 +20,10 @@ type Resolver struct {
|
||||
Path []string
|
||||
}
|
||||
|
||||
// NewResolver creates a new resolver with os.DirFS("/").
|
||||
// NewResolver creates a new resolver with OsFS.
|
||||
func NewResolver (path ...string) *Resolver {
|
||||
return &Resolver {
|
||||
FS: os.DirFS("/"),
|
||||
FS: OsFS { },
|
||||
Path: path,
|
||||
}
|
||||
}
|
||||
@ -108,13 +108,6 @@ func (resolver *Resolver) ResolveCwd (address entity.Address) (string, error) {
|
||||
// paths, which the FSPL compiler runs on. It converts an absolute path to a
|
||||
// slash path relative to "/" and opens the file.
|
||||
func openAbsolute (filesystem fs.FS, path string) (fs.File, error) {
|
||||
rootName := "/"
|
||||
// FIXME: this does not distinguish between volumes on windows. this is
|
||||
// a limitation of os.DirFS, we might want our own DirFS implementation
|
||||
// that has volumes as subdirs of /.
|
||||
if volumeName := filepath.VolumeName(path); volumeName != "" {
|
||||
rootName = volumeName
|
||||
}
|
||||
path = strings.TrimPrefix(filepath.ToSlash(path), rootName)
|
||||
path = strings.TrimPrefix(filepath.ToSlash(path), "/")
|
||||
return filesystem.Open(path)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user