Implemented directory walk
This commit is contained in:
parent
0fe419da86
commit
886ea27d54
@ -5,9 +5,12 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"git.akyoto.dev/cli/q/build/elf"
|
"git.akyoto.dev/cli/q/directory"
|
||||||
"git.akyoto.dev/cli/q/cli/log"
|
"git.akyoto.dev/cli/q/elf"
|
||||||
|
"git.akyoto.dev/cli/q/errors"
|
||||||
|
"git.akyoto.dev/cli/q/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Build describes a compiler build.
|
// Build describes a compiler build.
|
||||||
@ -43,29 +46,25 @@ func (build *Build) Run() error {
|
|||||||
return nil
|
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.
|
// Compile compiles all the functions.
|
||||||
func (build *Build) Compile() error {
|
func (build *Build) Compile() error {
|
||||||
file, err := os.Open(build.Directory)
|
stat, err := os.Stat(build.Directory)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
defer file.Close()
|
if !stat.IsDir() {
|
||||||
files, err := file.Readdirnames(0)
|
return &errors.InvalidDirectory{Path: build.Directory}
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, name := range files {
|
directory.Walk(build.Directory, func(file string) {
|
||||||
log.Info.Println(name)
|
if !strings.HasSuffix(file, ".q") {
|
||||||
}
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Info.Println(file)
|
||||||
|
})
|
||||||
|
|
||||||
build.Code.Write([]byte{
|
build.Code.Write([]byte{
|
||||||
0xb8, 0x01, 0x00, 0x00, 0x00, // mov eax, 1
|
0xb8, 0x01, 0x00, 0x00, 0x00, // mov eax, 1
|
||||||
@ -83,6 +82,11 @@ func (build *Build) Compile() error {
|
|||||||
return nil
|
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.
|
// writeToDisk writes the executable file to disk.
|
||||||
func writeToDisk(filePath string, code []byte, data []byte) error {
|
func writeToDisk(filePath string, code []byte, data []byte) error {
|
||||||
file, err := os.Create(filePath)
|
file, err := os.Create(filePath)
|
||||||
|
@ -2,7 +2,7 @@ package cli
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"git.akyoto.dev/cli/q/build"
|
"git.akyoto.dev/cli/q/build"
|
||||||
"git.akyoto.dev/cli/q/cli/log"
|
"git.akyoto.dev/cli/q/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Build builds an executable.
|
// Build builds an executable.
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package cli
|
package cli
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"git.akyoto.dev/cli/q/cli/log"
|
"git.akyoto.dev/cli/q/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Help shows the command line argument usage.
|
// Help shows the command line argument usage.
|
||||||
|
@ -4,7 +4,7 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
|
||||||
"git.akyoto.dev/cli/q/cli/log"
|
"git.akyoto.dev/cli/q/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
// System shows system information.
|
// System shows system information.
|
||||||
|
@ -6,7 +6,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"git.akyoto.dev/cli/q/cli"
|
"git.akyoto.dev/cli/q/cli"
|
||||||
"git.akyoto.dev/cli/q/cli/log"
|
"git.akyoto.dev/cli/q/log"
|
||||||
"git.akyoto.dev/go/assert"
|
"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