0.1: One binary file structure now.

This commit is contained in:
jienfak 2019-10-30 04:54:45 +05:00
parent 5ae91ab41d
commit 1e2a206297
8 changed files with 197 additions and 122 deletions

BIN
cat/cat

Binary file not shown.

View file

@ -5,29 +5,33 @@ import(
"os" "os"
"io" "io"
"log" "log"
"flag"
) )
type Catter struct { type Catter struct {
warn log.Logger warn *log.Logger
oup os.File out *os.File
bufSiz bufSiz int
buf []byte buf []byte
} }
func New(out os.File, warn log.Logger, bufSiz int) *Catter { func New(out *os.File, warn *log.Logger, bufSiz int) *Catter {
c := new(Catter) c := new(Catter)
c.out = out
c.warn = warn c.warn = warn
c.bufSiz = bufSiz c.bufSiz = bufSiz
c.buf = make([]byte, bufSiz) c.buf = make([]byte, c.bufSiz)
return c return c
} }
func (c Catter) Cat(files []os.File) error { func (c Catter) Cat(files []*os.File) error {
status = 0 for _, file := range files {
for _, file ;= range files {
for { for {
n, err := file.Read(buf) n, err := file.Read(c.buf)
if n>0 { if n>0 {
c.out.FPrintf("%s", buf[:n]) _, err := c.out.Write(c.buf[:n])
if err != nil {
return err
}
} }
if err == io.EOF { if err == io.EOF {
break break
@ -36,16 +40,31 @@ func (c Catter) Cat(files []os.File) error {
} }
} }
} }
return err return nil
} }
func (c Catter)Open(filePaths []string) []os.File { func (c Catter)OpenArr(filePaths []string) []*os.File {
files := make([]os.File, len(filepaths)) files := make([]*os.File, len(filePaths))
for i, filePath := range filePaths { for i, filePath := range filePaths {
files[i], err := os.Open(filePath) var err error
files[i], err = os.Open(filePath)
if err != nil { if err != nil {
c.warn.Println(err) c.warn.Println(err)
} }
} }
return files return files
}
func Run(args []string) int {
flagSet := flag.NewFlagSet(args[0], flag.ExitOnError)
flagSet.Parse(args[1:])
status := 0
warn := log.New(os.Stderr, args[0]+": ", 0)
c := New(os.Stdout, warn, 512)
files := c.OpenArr(flagSet.Args())
err := c.Cat(files)
if err != nil {
status = 1
}
return status
} }

View file

@ -1,17 +0,0 @@
package main
import(
"fmt"
"os"
"io"
"log"
"flag"
"cat"
)
func main() {
flag.Parse()
status := 0
c = cat.New(os.Stdout, warn, 512)
os.Exit(status)
}

75
echo/echo.go Normal file
View file

@ -0,0 +1,75 @@
/* Simple 'echo' implementation. */
package echo
import (
"os"
"flag"
"strings"
)
type Echoer struct {
out *os.File
backslashMap map[string] string
}
func (e Echoer)BackslashInterpret(str string) string {
for k, v := range e.backslashMap {
str = strings.ReplaceAll(str, k, v)
}
return str
}
func (e Echoer)Echo(str string) {
e.out.Write( []byte(str[:len(str)]) )
}
func New(out *os.File, backslashMap map[string] string) *Echoer {
e := new(Echoer)
e.out = out
e.backslashMap = backslashMap
return e
}
func Run(args []string) int {
var(
newLineStr string
newLineFlag bool
joinStr string
joinStrsFlag bool
backslashSeqFlag bool
)
seqs := map[string] string {
"\\\\" : "\\",
"\\a" : "\a",
"\\b" : "\b",
/*"\\c" : "\c",
"\\e" : "\e",*/
"\\f" : "\f",
"\\n" : "\n",
"\\r" : "\r",
"\\t" : "\t",
"\\v" : "\v",
}
e := New(os.Stdout, seqs)
flagSet := flag.NewFlagSet(args[0], flag.ExitOnError)
flagSet.BoolVar(&newLineFlag, "n", false,
"Don't add new line character('-N' is lower priority).")
flagSet.StringVar(&newLineStr, "N", "\n", "Use this instead new line character.")
flagSet.BoolVar(&joinStrsFlag, "j", false, "Join strings('-J' is lower priority).")
flagSet.StringVar(&joinStr, "J", " ", "Use instead of space as separator.")
flagSet.BoolVar(&backslashSeqFlag, "e", false, "Interpret backslash special terminal characters(Characters from join options will be interpreted too).")
flagSet.Parse(args[1:])
if newLineFlag {
newLineStr = ""
}
if joinStrsFlag {
joinStr = ""
}
printStr := strings.Join(flagSet.Args(), joinStr) +newLineStr
if backslashSeqFlag {
printStr = e.BackslashInterpret(printStr)
}
e.Echo(printStr)
return 0
}

View file

@ -1,48 +0,0 @@
/* Simple 'echo' implementation. */
package main
import (
"flag"
"fmt"
"strings"
)
func main() {
newLineFlagPtr := flag.Bool("n", false,
"Don't add new line character('-N' is lower priority).")
newLineStrPtr := flag.String("N", "\n", "Use this instead new line character.")
joinStrsFlagPtr := flag.Bool("j", false, "Join strings('-J' is lower priority).")
joinStrPtr := flag.String("J", " ", "Use instead of space as separator.")
backslashSeqFlagPtr := flag.Bool("e", false, "Interpret backslash special terminal characters.")
flag.Parse()
if *newLineFlagPtr {
*newLineStrPtr = ""
}
if *joinStrsFlagPtr {
*joinStrPtr = ""
}
printStr := strings.Join(flag.Args(), *joinStrPtr)
if *backslashSeqFlagPtr {
seqs := map[string] string {
"\\\\" : "\\",
"\\a" : "\a",
"\\b" : "\b",
/*"\\c" : "\c",
"\\e" : "\e",*/
"\\f" : "\f",
"\\n" : "\n",
"\\r" : "\r",
"\\t" : "\t",
"\\v" : "\v",
}
for k, v := range seqs {
printStr = strings.ReplaceAll(printStr, k, v)
}
}
fmt.Printf("%s%s",
printStr,
*newLineStrPtr,)
}

45
main.go Normal file
View file

@ -0,0 +1,45 @@
package main
import(
"fmt"
"os"
"path"
"github.com/jienfak/goblin/cat"
"github.com/jienfak/goblin/echo"
"github.com/jienfak/goblin/mkdir"
)
func main() {
var(
utilName string
args []string
)
utilsMap := map[string] interface{} {
"cat": cat.Run,
"mkdir" : mkdir.Run,
"echo" : echo.Run,
}
if binBase := path.Base(os.Args[0]) ; binBase != "goblin" {
utilName = binBase
args = os.Args[:]
} else {
if len(os.Args)<2 && binBase=="goblin" {
for k, _ := range utilsMap {
fmt.Printf("%s\n", k)
}
os.Exit(0)
}
utilName = os.Args[1]
args = os.Args[1:]
}
if _, ok := utilsMap[utilName] ; !ok {
fmt.Printf("%s: No such uitl as '%s'.", )
os.Exit(1)
}
status := utilsMap[utilName].(func([]string) int )(args)
os.Exit(status)
}

View file

@ -1,43 +0,0 @@
package main
import(
"os"
"flag"
"log"
)
func main() {
var (
parentFlag, verbFlag bool
modeArg int
)
status := 0
flag.BoolVar(&parentFlag, "p", false, "No error if existing, make parent as needed.")
flag.IntVar(&modeArg, "m", 0766, "Set file `mode`.")
flag.BoolVar(&verbFlag, "v", false, "Print a message for each created directory.")
if len(os.Args) < 2 {
flag.Usage()
}
flag.Parse()
mode := os.FileMode(modeArg)
var verb *log.Logger
if verbFlag {
verb = log.New(os.Stdout, os.Args[0]+": ", 0)
}
warn := log.New(os.Stderr, os.Args[0]+": ", 0)
for _, path := range flag.Args() {
var err error
if parentFlag {
err = os.MkdirAll(path, mode)
} else {
err = os.Mkdir(path, mode)
}
if err != nil {
warn.Println(err)
status = 1
} else if verbFlag {
verb.Printf("Created directory '%s'.", path)
}
}
os.Exit(status)
}

44
mkdir/mkdir.go Normal file
View file

@ -0,0 +1,44 @@
package mkdir
import(
"os"
"flag"
"log"
)
func Run(args []string) int {
var (
parentFlag, verbFlag bool
modeArg int
)
flagSet := flag.NewFlagSet(args[0], flag.ExitOnError)
status := 0
flagSet.BoolVar(&parentFlag, "p", false, "No error if existing, make parent as needed.")
flagSet.IntVar(&modeArg, "m", 0766, "Set file `mode`.")
flagSet.BoolVar(&verbFlag, "v", false, "Print a message for each created directory.")
if len(args) < 2 {
flagSet.Usage()
}
flagSet.Parse(args[1:])
mode := os.FileMode(modeArg)
var verb *log.Logger
if verbFlag {
verb = log.New(os.Stdout, flagSet.Args()[0]+": ", 0)
}
warn := log.New(os.Stderr, flagSet.Args()[0]+": ", 0)
for _, path := range flagSet.Args() {
var err error
if parentFlag {
err = os.MkdirAll(path, mode)
} else {
err = os.Mkdir(path, mode)
}
if err != nil {
warn.Println(err)
status = 1
} else if verbFlag {
verb.Printf("Created directory '%s'.", path)
}
}
return status
}