Improved error handling
This commit is contained in:
9
src/build/fs/File.go
Normal file
9
src/build/fs/File.go
Normal file
@ -0,0 +1,9 @@
|
||||
package fs
|
||||
|
||||
import "git.akyoto.dev/cli/q/src/build/token"
|
||||
|
||||
// File represents a single source file.
|
||||
type File struct {
|
||||
Tokens token.List
|
||||
Path string
|
||||
}
|
63
src/build/fs/Walk.go
Normal file
63
src/build/fs/Walk.go
Normal file
@ -0,0 +1,63 @@
|
||||
package fs
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
const blockSize = 4096
|
||||
|
||||
// Walk calls your callback function for every file name inside the directory.
|
||||
// It doesn't distinguish between files and directories.
|
||||
func Walk(directory string, callBack func(string)) error {
|
||||
fd, err := syscall.Open(directory, 0, 0)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
defer syscall.Close(fd)
|
||||
buffer := make([]byte, blockSize)
|
||||
|
||||
for {
|
||||
n, err := syscall.ReadDirent(fd, buffer)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if n <= 0 {
|
||||
break
|
||||
}
|
||||
|
||||
readBuffer := buffer[:n]
|
||||
|
||||
for len(readBuffer) > 0 {
|
||||
dirent := (*syscall.Dirent)(unsafe.Pointer(&readBuffer[0]))
|
||||
readBuffer = readBuffer[dirent.Reclen:]
|
||||
|
||||
// Skip deleted files
|
||||
if dirent.Ino == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
// Skip hidden files
|
||||
if dirent.Name[0] == '.' {
|
||||
continue
|
||||
}
|
||||
|
||||
for i, c := range dirent.Name {
|
||||
if c != 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
bytePointer := (*byte)(unsafe.Pointer(&dirent.Name[0]))
|
||||
name := unsafe.String(bytePointer, i)
|
||||
callBack(name)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
24
src/build/fs/Walk_test.go
Normal file
24
src/build/fs/Walk_test.go
Normal file
@ -0,0 +1,24 @@
|
||||
package fs_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"git.akyoto.dev/cli/q/src/build/fs"
|
||||
"git.akyoto.dev/go/assert"
|
||||
)
|
||||
|
||||
func TestWalk(t *testing.T) {
|
||||
var files []string
|
||||
|
||||
fs.Walk(".", func(file string) {
|
||||
files = append(files, file)
|
||||
})
|
||||
|
||||
assert.Contains(t, files, "Walk.go")
|
||||
assert.Contains(t, files, "Walk_test.go")
|
||||
}
|
||||
|
||||
func TestNonExisting(t *testing.T) {
|
||||
err := fs.Walk("does-not-exist", func(file string) {})
|
||||
assert.NotNil(t, err)
|
||||
}
|
Reference in New Issue
Block a user