Implemented directory walk
This commit is contained in:
parent
0fe419da86
commit
886ea27d54
@ -5,9 +5,12 @@ import (
|
||||
"bytes"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"git.akyoto.dev/cli/q/build/elf"
|
||||
"git.akyoto.dev/cli/q/cli/log"
|
||||
"git.akyoto.dev/cli/q/directory"
|
||||
"git.akyoto.dev/cli/q/elf"
|
||||
"git.akyoto.dev/cli/q/errors"
|
||||
"git.akyoto.dev/cli/q/log"
|
||||
)
|
||||
|
||||
// Build describes a compiler build.
|
||||
@ -43,30 +46,26 @@ func (build *Build) Run() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Executable returns the path to the executable.
|
||||
func (build *Build) Executable() string {
|
||||
return filepath.Join(build.Directory, build.Name)
|
||||
}
|
||||
|
||||
// Compile compiles all the functions.
|
||||
func (build *Build) Compile() error {
|
||||
file, err := os.Open(build.Directory)
|
||||
stat, err := os.Stat(build.Directory)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
defer file.Close()
|
||||
files, err := file.Readdirnames(0)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
if !stat.IsDir() {
|
||||
return &errors.InvalidDirectory{Path: build.Directory}
|
||||
}
|
||||
|
||||
for _, name := range files {
|
||||
log.Info.Println(name)
|
||||
directory.Walk(build.Directory, func(file string) {
|
||||
if !strings.HasSuffix(file, ".q") {
|
||||
return
|
||||
}
|
||||
|
||||
log.Info.Println(file)
|
||||
})
|
||||
|
||||
build.Code.Write([]byte{
|
||||
0xb8, 0x01, 0x00, 0x00, 0x00, // mov eax, 1
|
||||
0xbf, 0x01, 0x00, 0x00, 0x00, // mov edi, 1
|
||||
@ -83,6 +82,11 @@ func (build *Build) Compile() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Executable returns the path to the executable.
|
||||
func (build *Build) Executable() string {
|
||||
return filepath.Join(build.Directory, build.Name)
|
||||
}
|
||||
|
||||
// writeToDisk writes the executable file to disk.
|
||||
func writeToDisk(filePath string, code []byte, data []byte) error {
|
||||
file, err := os.Create(filePath)
|
||||
|
@ -2,7 +2,7 @@ package cli
|
||||
|
||||
import (
|
||||
"git.akyoto.dev/cli/q/build"
|
||||
"git.akyoto.dev/cli/q/cli/log"
|
||||
"git.akyoto.dev/cli/q/log"
|
||||
)
|
||||
|
||||
// Build builds an executable.
|
||||
|
@ -1,7 +1,7 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"git.akyoto.dev/cli/q/cli/log"
|
||||
"git.akyoto.dev/cli/q/log"
|
||||
)
|
||||
|
||||
// Help shows the command line argument usage.
|
||||
|
@ -4,7 +4,7 @@ import (
|
||||
"os"
|
||||
"runtime"
|
||||
|
||||
"git.akyoto.dev/cli/q/cli/log"
|
||||
"git.akyoto.dev/cli/q/log"
|
||||
)
|
||||
|
||||
// System shows system information.
|
||||
|
@ -6,7 +6,7 @@ import (
|
||||
"testing"
|
||||
|
||||
"git.akyoto.dev/cli/q/cli"
|
||||
"git.akyoto.dev/cli/q/cli/log"
|
||||
"git.akyoto.dev/cli/q/log"
|
||||
"git.akyoto.dev/go/assert"
|
||||
)
|
||||
|
||||
|
61
directory/Walk.go
Normal file
61
directory/Walk.go
Normal file
@ -0,0 +1,61 @@
|
||||
package directory
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
const blockSize = 8 << 10
|
||||
|
||||
// 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)) {
|
||||
fd, err := syscall.Open(directory, 0, 0)
|
||||
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
defer syscall.Close(fd)
|
||||
buffer := make([]byte, blockSize)
|
||||
|
||||
for {
|
||||
n, err := syscall.ReadDirent(fd, buffer)
|
||||
|
||||
if err != nil {
|
||||
panic(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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
15
errors/InvalidPath.go
Normal file
15
errors/InvalidPath.go
Normal file
@ -0,0 +1,15 @@
|
||||
package errors
|
||||
|
||||
import "fmt"
|
||||
|
||||
type InvalidDirectory struct {
|
||||
Path string
|
||||
}
|
||||
|
||||
func (err *InvalidDirectory) Error() string {
|
||||
if err.Path == "" {
|
||||
return "Invalid directory"
|
||||
}
|
||||
|
||||
return fmt.Sprintf("Invalid directory '%s'", err.Path)
|
||||
}
|
Loading…
Reference in New Issue
Block a user