forked from u-root/u-root
-
Notifications
You must be signed in to change notification settings - Fork 2
/
echo.go
101 lines (87 loc) · 2.02 KB
/
echo.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
// Copyright 2013-2017 the u-root Authors. All rights reserved
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Echo writes its arguments separated by blanks and terminated by a newline on
// the standard output.
//
// Synopsis:
// echo [-e] [-n] [-E] [STRING]...
package main
import (
"flag"
"fmt"
"io"
"os"
"strings"
)
type flags struct {
noNewline, interpretEscapes bool
}
func escapeString(s string) (string, error) {
if len(s) < 1 {
return "", nil
}
s = strings.Split(s, "\\c")[0]
s = strings.Replace(s, "\\0", "\\", -1)
// Quote the string and scan it through %q to interpret backslash escapes
s = fmt.Sprintf("\"%s\"", s)
_, err := fmt.Sscanf(s, "%q", &s)
if err != nil {
return "", err
}
return s, nil
}
func echo(f flags, w io.Writer, s ...string) error {
var err error
line := strings.Join(s, " ")
if f.interpretEscapes {
line, err = escapeString(line)
if err != nil {
return err
}
}
format := "%s"
if !f.noNewline {
format += "\n"
}
_, err = fmt.Fprintf(w, format, line)
return err
}
func init() {
defUsage := flag.Usage
flag.Usage = func() {
defUsage()
fmt.Println(`
If -e is in effect, the following sequences are recognized:
\\ backslash
\a alert (BEL)
\b backspace
\c produce no further output
\e escape
\f form feed
\n new line
\r carriage return
\t horizontal tab
\v vertical tab
\0NNN byte with octal value NNN (1 to 3 digits)
\xHH byte with hexadecimal value HH (1 to 2 digits)`)
}
}
func main() {
var (
f flags
E bool
)
flag.BoolVar(&f.noNewline, "n", false, "suppress newline")
flag.BoolVar(&f.interpretEscapes, "e", true, "enable interpretation of backslash escapes (default)")
flag.BoolVar(&E, "E", false, "disable interpretation of backslash escapes")
flag.Parse()
if E {
f.interpretEscapes = false
}
err := echo(f, os.Stdout, flag.Args()...)
if err != nil {
fmt.Fprintf(os.Stderr, "%s", err)
os.Exit(1)
}
}