This is an education project that attempts to reimplement the GNU coreutils in Go. You can find the full manual here:
https://www.gnu.org/software/coreutils/manual/coreutils.html
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
73 lines
1.3 KiB
73 lines
1.3 KiB
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"flag"
|
|
"log"
|
|
"bufio"
|
|
)
|
|
|
|
func Fail(err error, format string, v ...any) {
|
|
err_format := fmt.Sprintf("ERROR: %v; %s", err, format)
|
|
log.Printf(err_format, v...)
|
|
os.Exit(1)
|
|
}
|
|
|
|
type Opts struct {
|
|
Width int
|
|
Filenames []string
|
|
Hex bool
|
|
Octal bool
|
|
Format string
|
|
}
|
|
|
|
func parse_opts() (Opts) {
|
|
var opts Opts
|
|
|
|
flag.IntVar(&opts.Width, "w", 16, "Width of output grid")
|
|
flag.BoolVar(&opts.Hex, "x", false, "Output hex bytes")
|
|
flag.BoolVar(&opts.Octal, "o", false, "Output octal bytes")
|
|
|
|
flag.Parse()
|
|
|
|
if flag.NArg() == 0 {
|
|
log.Fatal("USAGE: od [files]")
|
|
os.Exit(1)
|
|
}
|
|
|
|
if opts.Hex {
|
|
opts.Format = "%0.2x "
|
|
} else {
|
|
opts.Format = "%0.3o "
|
|
}
|
|
|
|
opts.Filenames = flag.Args()
|
|
return opts
|
|
}
|
|
|
|
func main() {
|
|
opts := parse_opts()
|
|
|
|
for _, filename := range opts.Filenames {
|
|
reader, err := os.Open(filename)
|
|
defer reader.Close()
|
|
if err != nil { Fail(err, "can't open: %s", filename) }
|
|
|
|
buf := bufio.NewReader(reader)
|
|
count := buf.Size()
|
|
|
|
fmt.Printf("%0.8o ", 0);
|
|
|
|
for index := 0; index < count; index++ {
|
|
data, err := buf.ReadByte()
|
|
if err != nil { break }
|
|
fmt.Printf(opts.Format, data);
|
|
|
|
if (index + 1) % opts.Width == 0 {
|
|
fmt.Print("\n")
|
|
fmt.Printf("%0.8o ", index);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|