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
|
// SPDX-License-Identifier: GPL-3.0-or-later
package main
import (
"fmt"
"strings"
"unicode/utf8"
)
// display makes s safe to print to a terminal (spec §15.1). File names,
// paths, reasons and tool messages come from outside krino: a control
// character in one could move the cursor, recolour or erase what krino
// prints, and a bidirectional control could reorder it, so a name could
// hide a step or fake one. Every C0 control, DEL, C1 control, Unicode
// bidirectional embedding, override or isolate, and every byte that is not
// valid UTF-8 is shown as an escape instead - \x1b for a byte, \u202e for
// a rune. Everything else, backslash included, is printed as it is. Text
// that is plain printable ASCII is returned without copying.
func display(s string) string {
plain := true
for i := 0; i < len(s); i++ {
if c := s[i]; c < 0x20 || c >= 0x7f {
plain = false
break
}
}
if plain {
return s
}
var b strings.Builder
for i := 0; i < len(s); {
r, size := utf8.DecodeRuneInString(s[i:])
switch {
case r == utf8.RuneError && size == 1:
fmt.Fprintf(&b, `\x%02x`, s[i])
case r < 0x20 || r == 0x7f:
fmt.Fprintf(&b, `\x%02x`, r)
case controlRune(r):
fmt.Fprintf(&b, `\u%04x`, r)
default:
b.WriteString(s[i : i+size])
}
i += size
}
return b.String()
}
// controlRune reports whether r is a C1 control or a Unicode bidirectional
// embedding, override or isolate: printable-looking code points a terminal
// acts on.
func controlRune(r rune) bool {
return (r >= 0x80 && r <= 0x9f) || (r >= 0x202a && r <= 0x202e) || (r >= 0x2066 && r <= 0x2069)
}
|