bb/src/tool/wc/main.go

102 lines
1.5 KiB
Go
Raw Normal View History

2022-06-17 11:21:19 +03:00
package wc
import (
"os"
"io"
"bufio"
"fmt"
"unicode"
"flag"
"strconv"
)
var (
vals [lastFlag]int
flags [lastFlag]bool
flagList []int
)
const (
wordsFlag = iota
runesFlag
charsFlag
linesFlag
lastFlag
)
func rdRune(rd *bufio.Reader) (rune, int) {
r, siz, err := rd.ReadRune()
if err == io.EOF {
finish()
} else if err != nil {
panic(err)
}
return r, siz
}
func finish() {
str := ""
for i, v := range flagList {
str += strconv.Itoa(vals[v])
if i != ( len(flagList)-1 ) {
str += "\t"
}
}
fmt.Print(str)
os.Exit(0)
}
func Run(args []string) {
var (
r rune
siz int
)
arg0 := args[0]
args = args[1:]
flagSet := flag.NewFlagSet(arg0, flag.ExitOnError)
flagSet.BoolVar(&flags[charsFlag], "c", false, "print amount of chars(bytes)")
flagSet.BoolVar(&flags[runesFlag], "r", false, "print amount of runes in UTF stream")
flagSet.BoolVar(&flags[wordsFlag], "w", false, "print amount of words")
flagSet.BoolVar(&flags[linesFlag], "l", false, "print amount of lines")
flagSet.Parse(args)
for i, v := range flags {
if v {
break;
} else if i == (len(flags) - 1){
flagSet.Usage()
os.Exit(1)
}
}
for i, v := range flags {
if v {
flagList = append(flagList, i)
}
}
rd := bufio.NewReader(os.Stdin)
inWord := false
for {
r, siz = rdRune(rd)
if inWord {
if unicode.IsSpace(r) {
inWord = false
}
} else {
if !unicode.IsSpace(r) {
vals[wordsFlag]++
inWord = true
}
}
vals[runesFlag]++
vals[charsFlag] += siz
if r == rune('\n') {
vals[linesFlag]++
}
}
finish()
}