Added support for stdin input

main
oabrivard 2 years ago
parent a0cabd874d
commit f747fbad46

@ -0,0 +1,17 @@
{
// Utilisez IntelliSense pour en savoir plus sur les attributs possibles.
// Pointez pour afficher la description des attributs existants.
// Pour plus d'informations, visitez : https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Launch Package",
"type": "go",
"request": "launch",
"mode": "auto",
"program": "${fileDirname}",
"env": {},
"args": ["-c", "test.txt"]
}
]
}

BIN
gowc

Binary file not shown.

@ -11,18 +11,43 @@ import (
"unicode/utf8"
)
func byteCounter(f *os.File) {
func isInputFromPipe() bool {
fileInfo, _ := os.Stdin.Stat()
return fileInfo.Mode()&os.ModeCharDevice == 0
}
func fileByteCounter(f *os.File) int64 {
fileInfo, err := f.Stat()
if err != nil {
fmt.Fprintf(os.Stderr, "error: %v\n", err)
os.Exit(1)
}
fmt.Println(fileInfo.Size())
return fileInfo.Size()
}
func lineCounter(f io.Reader) {
func stdinByteCounter(f *os.File) int64 {
buf := make([]byte, 32*1024)
count := 0
count := int64(0)
for {
c, err := f.Read(buf) // c==0 if EOF
switch {
case err == io.EOF:
return count
case err != nil:
fmt.Fprintf(os.Stderr, "error: %v\n", err)
os.Exit(1)
}
count += int64(c)
}
}
func lineCounter(f io.Reader) int64 {
buf := make([]byte, 32*1024)
count := int64(0)
lineSep := []byte{'\n'}
for {
@ -30,21 +55,20 @@ func lineCounter(f io.Reader) {
switch {
case err == io.EOF:
fmt.Println(count)
return
return count
case err != nil:
fmt.Fprintf(os.Stderr, "error: %v\n", err)
os.Exit(1)
}
count += bytes.Count(buf[:c], lineSep)
count += int64(bytes.Count(buf[:c], lineSep))
}
}
func wordCounter(f io.Reader) {
func wordCounter(f io.Reader) int64 {
buf := make([]byte, 32*1024)
count := 0
count := int64(0)
wordSep := []byte{' ', '\t', '\n', '\r', '\f', '\v'}
inWord := false
@ -56,8 +80,7 @@ func wordCounter(f io.Reader) {
if inWord {
count++
}
fmt.Println(count)
return
return count
case err != nil:
fmt.Fprintf(os.Stderr, "error: %v\n", err)
@ -77,15 +100,15 @@ func wordCounter(f io.Reader) {
}
}
func charCounter(f *os.File) {
func charCounter(f *os.File) int64 {
var line string
var err error
r := bufio.NewReader(f)
count := 0
count := int64(0)
for err == nil {
line, err = r.ReadString('\n')
count += utf8.RuneCountInString(line)
count += int64(utf8.RuneCountInString(line))
}
if err != io.EOF {
@ -93,17 +116,32 @@ func charCounter(f *os.File) {
os.Exit(1)
}
fmt.Println(count)
return count
}
func main() {
var f *os.File
var fileName string
var byteCounter func(f *os.File) int64
cFlag := flag.Bool("c", false, "print the byte count")
lFlag := flag.Bool("l", false, "print the line count")
wFlag := flag.Bool("w", false, "print the word count")
mFlag := flag.Bool("m", false, "print the character count")
flag.Parse()
fileName := flag.Arg(0)
if isInputFromPipe() {
f = os.Stdin
if flag.NFlag() != 1 {
fmt.Fprintf(os.Stderr, "must provide a single flag to gowc when reading from stdin\n")
flag.Usage()
os.Exit(1)
}
byteCounter = stdinByteCounter
} else {
fileName = flag.Arg(0)
if len(fileName) == 0 {
fmt.Fprintf(os.Stderr, "gowc [flags] filename\n")
@ -111,21 +149,38 @@ func main() {
os.Exit(1)
}
f, err := os.Open(fileName)
var err error
f, err = os.Open(fileName)
if err != nil {
fmt.Fprintf(os.Stderr, "error: %v\n", err)
os.Exit(1)
}
defer f.Close()
byteCounter = fileByteCounter
}
switch {
case *cFlag:
byteCounter(f)
fmt.Print("\t", byteCounter(f))
case *lFlag:
lineCounter(f)
fmt.Print("\t", lineCounter(f))
case *wFlag:
wordCounter(f)
fmt.Print("\t", wordCounter(f))
case *mFlag:
charCounter(f)
fmt.Print("\t", charCounter(f))
default:
b := byteCounter(f)
f.Seek(0, 0)
l := lineCounter(f)
f.Seek(0, 0)
w := wordCounter(f)
fmt.Print("\t", l, "\t", w, "\t", b)
}
if len(fileName) > 0 {
fmt.Println("\t", fileName)
} else {
fmt.Println("")
}
}

Loading…
Cancel
Save