aboutsummaryrefslogtreecommitdiff
path: root/vendor/github.com/mattn/go-colorable
diff options
context:
space:
mode:
authorMitja Felicijan <mitja.felicijan@gmail.com>2026-02-05 00:37:32 +0100
committerMitja Felicijan <mitja.felicijan@gmail.com>2026-02-05 00:37:32 +0100
commit6960aecc25400320adee1b8802a86839326e15b6 (patch)
tree334f7ca9491080a5e6f9a9747da77281c4958ba2 /vendor/github.com/mattn/go-colorable
downloadhepi-6960aecc25400320adee1b8802a86839326e15b6.tar.gz
Engage!
Diffstat (limited to 'vendor/github.com/mattn/go-colorable')
-rw-r--r--vendor/github.com/mattn/go-colorable/LICENSE21
-rw-r--r--vendor/github.com/mattn/go-colorable/README.md48
-rw-r--r--vendor/github.com/mattn/go-colorable/colorable_others.go38
-rw-r--r--vendor/github.com/mattn/go-colorable/colorable_windows.go1047
-rw-r--r--vendor/github.com/mattn/go-colorable/go.test.sh12
-rw-r--r--vendor/github.com/mattn/go-colorable/noncolorable.go57
6 files changed, 1223 insertions, 0 deletions
diff --git a/vendor/github.com/mattn/go-colorable/LICENSE b/vendor/github.com/mattn/go-colorable/LICENSE
new file mode 100644
index 0000000..91b5cef
--- /dev/null
+++ b/vendor/github.com/mattn/go-colorable/LICENSE
@@ -0,0 +1,21 @@
1The MIT License (MIT)
2
3Copyright (c) 2016 Yasuhiro Matsumoto
4
5Permission is hereby granted, free of charge, to any person obtaining a copy
6of this software and associated documentation files (the "Software"), to deal
7in the Software without restriction, including without limitation the rights
8to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9copies of the Software, and to permit persons to whom the Software is
10furnished to do so, subject to the following conditions:
11
12The above copyright notice and this permission notice shall be included in all
13copies or substantial portions of the Software.
14
15THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21SOFTWARE.
diff --git a/vendor/github.com/mattn/go-colorable/README.md b/vendor/github.com/mattn/go-colorable/README.md
new file mode 100644
index 0000000..ca04837
--- /dev/null
+++ b/vendor/github.com/mattn/go-colorable/README.md
@@ -0,0 +1,48 @@
1# go-colorable
2
3[![Build Status](https://github.com/mattn/go-colorable/workflows/test/badge.svg)](https://github.com/mattn/go-colorable/actions?query=workflow%3Atest)
4[![Codecov](https://codecov.io/gh/mattn/go-colorable/branch/master/graph/badge.svg)](https://codecov.io/gh/mattn/go-colorable)
5[![GoDoc](https://godoc.org/github.com/mattn/go-colorable?status.svg)](http://godoc.org/github.com/mattn/go-colorable)
6[![Go Report Card](https://goreportcard.com/badge/mattn/go-colorable)](https://goreportcard.com/report/mattn/go-colorable)
7
8Colorable writer for windows.
9
10For example, most of logger packages doesn't show colors on windows. (I know we can do it with ansicon. But I don't want.)
11This package is possible to handle escape sequence for ansi color on windows.
12
13## Too Bad!
14
15![](https://raw.githubusercontent.com/mattn/go-colorable/gh-pages/bad.png)
16
17
18## So Good!
19
20![](https://raw.githubusercontent.com/mattn/go-colorable/gh-pages/good.png)
21
22## Usage
23
24```go
25logrus.SetFormatter(&logrus.TextFormatter{ForceColors: true})
26logrus.SetOutput(colorable.NewColorableStdout())
27
28logrus.Info("succeeded")
29logrus.Warn("not correct")
30logrus.Error("something error")
31logrus.Fatal("panic")
32```
33
34You can compile above code on non-windows OSs.
35
36## Installation
37
38```
39$ go get github.com/mattn/go-colorable
40```
41
42# License
43
44MIT
45
46# Author
47
48Yasuhiro Matsumoto (a.k.a mattn)
diff --git a/vendor/github.com/mattn/go-colorable/colorable_others.go b/vendor/github.com/mattn/go-colorable/colorable_others.go
new file mode 100644
index 0000000..c1a78aa
--- /dev/null
+++ b/vendor/github.com/mattn/go-colorable/colorable_others.go
@@ -0,0 +1,38 @@
1//go:build !windows || appengine
2// +build !windows appengine
3
4package colorable
5
6import (
7 "io"
8 "os"
9
10 _ "github.com/mattn/go-isatty"
11)
12
13// NewColorable returns new instance of Writer which handles escape sequence.
14func NewColorable(file *os.File) io.Writer {
15 if file == nil {
16 panic("nil passed instead of *os.File to NewColorable()")
17 }
18
19 return file
20}
21
22// NewColorableStdout returns new instance of Writer which handles escape sequence for stdout.
23func NewColorableStdout() io.Writer {
24 return os.Stdout
25}
26
27// NewColorableStderr returns new instance of Writer which handles escape sequence for stderr.
28func NewColorableStderr() io.Writer {
29 return os.Stderr
30}
31
32// EnableColorsStdout enable colors if possible.
33func EnableColorsStdout(enabled *bool) func() {
34 if enabled != nil {
35 *enabled = true
36 }
37 return func() {}
38}
diff --git a/vendor/github.com/mattn/go-colorable/colorable_windows.go b/vendor/github.com/mattn/go-colorable/colorable_windows.go
new file mode 100644
index 0000000..2df7b85
--- /dev/null
+++ b/vendor/github.com/mattn/go-colorable/colorable_windows.go
@@ -0,0 +1,1047 @@
1//go:build windows && !appengine
2// +build windows,!appengine
3
4package colorable
5
6import (
7 "bytes"
8 "io"
9 "math"
10 "os"
11 "strconv"
12 "strings"
13 "sync"
14 syscall "golang.org/x/sys/windows"
15 "unsafe"
16
17 "github.com/mattn/go-isatty"
18)
19
20const (
21 foregroundBlue = 0x1
22 foregroundGreen = 0x2
23 foregroundRed = 0x4
24 foregroundIntensity = 0x8
25 foregroundMask = (foregroundRed | foregroundBlue | foregroundGreen | foregroundIntensity)
26 backgroundBlue = 0x10
27 backgroundGreen = 0x20
28 backgroundRed = 0x40
29 backgroundIntensity = 0x80
30 backgroundMask = (backgroundRed | backgroundBlue | backgroundGreen | backgroundIntensity)
31 commonLvbUnderscore = 0x8000
32
33 cENABLE_VIRTUAL_TERMINAL_PROCESSING = 0x4
34)
35
36const (
37 genericRead = 0x80000000
38 genericWrite = 0x40000000
39)
40
41const (
42 consoleTextmodeBuffer = 0x1
43)
44
45type wchar uint16
46type short int16
47type dword uint32
48type word uint16
49
50type coord struct {
51 x short
52 y short
53}
54
55type smallRect struct {
56 left short
57 top short
58 right short
59 bottom short
60}
61
62type consoleScreenBufferInfo struct {
63 size coord
64 cursorPosition coord
65 attributes word
66 window smallRect
67 maximumWindowSize coord
68}
69
70type consoleCursorInfo struct {
71 size dword
72 visible int32
73}
74
75var (
76 kernel32 = syscall.NewLazySystemDLL("kernel32.dll")
77 procGetConsoleScreenBufferInfo = kernel32.NewProc("GetConsoleScreenBufferInfo")
78 procSetConsoleTextAttribute = kernel32.NewProc("SetConsoleTextAttribute")
79 procSetConsoleCursorPosition = kernel32.NewProc("SetConsoleCursorPosition")
80 procFillConsoleOutputCharacter = kernel32.NewProc("FillConsoleOutputCharacterW")
81 procFillConsoleOutputAttribute = kernel32.NewProc("FillConsoleOutputAttribute")
82 procGetConsoleCursorInfo = kernel32.NewProc("GetConsoleCursorInfo")
83 procSetConsoleCursorInfo = kernel32.NewProc("SetConsoleCursorInfo")
84 procSetConsoleTitle = kernel32.NewProc("SetConsoleTitleW")
85 procGetConsoleMode = kernel32.NewProc("GetConsoleMode")
86 procSetConsoleMode = kernel32.NewProc("SetConsoleMode")
87 procCreateConsoleScreenBuffer = kernel32.NewProc("CreateConsoleScreenBuffer")
88)
89
90// writer provides colorable Writer to the console
91type writer struct {
92 out io.Writer
93 handle syscall.Handle
94 althandle syscall.Handle
95 oldattr word
96 oldpos coord
97 rest bytes.Buffer
98 mutex sync.Mutex
99}
100
101// NewColorable returns new instance of writer which handles escape sequence from File.
102func NewColorable(file *os.File) io.Writer {
103 if file == nil {
104 panic("nil passed instead of *os.File to NewColorable()")
105 }
106
107 if isatty.IsTerminal(file.Fd()) {
108 var mode uint32
109 if r, _, _ := procGetConsoleMode.Call(file.Fd(), uintptr(unsafe.Pointer(&mode))); r != 0 && mode&cENABLE_VIRTUAL_TERMINAL_PROCESSING != 0 {
110 return file
111 }
112 var csbi consoleScreenBufferInfo
113 handle := syscall.Handle(file.Fd())
114 procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi)))
115 return &writer{out: file, handle: handle, oldattr: csbi.attributes, oldpos: coord{0, 0}}
116 }
117 return file
118}
119
120// NewColorableStdout returns new instance of writer which handles escape sequence for stdout.
121func NewColorableStdout() io.Writer {
122 return NewColorable(os.Stdout)
123}
124
125// NewColorableStderr returns new instance of writer which handles escape sequence for stderr.
126func NewColorableStderr() io.Writer {
127 return NewColorable(os.Stderr)
128}
129
130var color256 = map[int]int{
131 0: 0x000000,
132 1: 0x800000,
133 2: 0x008000,
134 3: 0x808000,
135 4: 0x000080,
136 5: 0x800080,
137 6: 0x008080,
138 7: 0xc0c0c0,
139 8: 0x808080,
140 9: 0xff0000,
141 10: 0x00ff00,
142 11: 0xffff00,
143 12: 0x0000ff,
144 13: 0xff00ff,
145 14: 0x00ffff,
146 15: 0xffffff,
147 16: 0x000000,
148 17: 0x00005f,
149 18: 0x000087,
150 19: 0x0000af,
151 20: 0x0000d7,
152 21: 0x0000ff,
153 22: 0x005f00,
154 23: 0x005f5f,
155 24: 0x005f87,
156 25: 0x005faf,
157 26: 0x005fd7,
158 27: 0x005fff,
159 28: 0x008700,
160 29: 0x00875f,
161 30: 0x008787,
162 31: 0x0087af,
163 32: 0x0087d7,
164 33: 0x0087ff,
165 34: 0x00af00,
166 35: 0x00af5f,
167 36: 0x00af87,
168 37: 0x00afaf,
169 38: 0x00afd7,
170 39: 0x00afff,
171 40: 0x00d700,
172 41: 0x00d75f,
173 42: 0x00d787,
174 43: 0x00d7af,
175 44: 0x00d7d7,
176 45: 0x00d7ff,
177 46: 0x00ff00,
178 47: 0x00ff5f,
179 48: 0x00ff87,
180 49: 0x00ffaf,
181 50: 0x00ffd7,
182 51: 0x00ffff,
183 52: 0x5f0000,
184 53: 0x5f005f,
185 54: 0x5f0087,
186 55: 0x5f00af,
187 56: 0x5f00d7,
188 57: 0x5f00ff,
189 58: 0x5f5f00,
190 59: 0x5f5f5f,
191 60: 0x5f5f87,
192 61: 0x5f5faf,
193 62: 0x5f5fd7,
194 63: 0x5f5fff,
195 64: 0x5f8700,
196 65: 0x5f875f,
197 66: 0x5f8787,
198 67: 0x5f87af,
199 68: 0x5f87d7,
200 69: 0x5f87ff,
201 70: 0x5faf00,
202 71: 0x5faf5f,
203 72: 0x5faf87,
204 73: 0x5fafaf,
205 74: 0x5fafd7,
206 75: 0x5fafff,
207 76: 0x5fd700,
208 77: 0x5fd75f,
209 78: 0x5fd787,
210 79: 0x5fd7af,
211 80: 0x5fd7d7,
212 81: 0x5fd7ff,
213 82: 0x5fff00,
214 83: 0x5fff5f,
215 84: 0x5fff87,
216 85: 0x5fffaf,
217 86: 0x5fffd7,
218 87: 0x5fffff,
219 88: 0x870000,
220 89: 0x87005f,
221 90: 0x870087,
222 91: 0x8700af,
223 92: 0x8700d7,
224 93: 0x8700ff,
225 94: 0x875f00,
226 95: 0x875f5f,
227 96: 0x875f87,
228 97: 0x875faf,
229 98: 0x875fd7,
230 99: 0x875fff,
231 100: 0x878700,
232 101: 0x87875f,
233 102: 0x878787,
234 103: 0x8787af,
235 104: 0x8787d7,
236 105: 0x8787ff,
237 106: 0x87af00,
238 107: 0x87af5f,
239 108: 0x87af87,
240 109: 0x87afaf,
241 110: 0x87afd7,
242 111: 0x87afff,
243 112: 0x87d700,
244 113: 0x87d75f,
245 114: 0x87d787,
246 115: 0x87d7af,
247 116: 0x87d7d7,
248 117: 0x87d7ff,
249 118: 0x87ff00,
250 119: 0x87ff5f,
251 120: 0x87ff87,
252 121: 0x87ffaf,
253 122: 0x87ffd7,
254 123: 0x87ffff,
255 124: 0xaf0000,
256 125: 0xaf005f,
257 126: 0xaf0087,
258 127: 0xaf00af,
259 128: 0xaf00d7,
260 129: 0xaf00ff,
261 130: 0xaf5f00,
262 131: 0xaf5f5f,
263 132: 0xaf5f87,
264 133: 0xaf5faf,
265 134: 0xaf5fd7,
266 135: 0xaf5fff,
267 136: 0xaf8700,
268 137: 0xaf875f,
269 138: 0xaf8787,
270 139: 0xaf87af,
271 140: 0xaf87d7,
272 141: 0xaf87ff,
273 142: 0xafaf00,
274 143: 0xafaf5f,
275 144: 0xafaf87,
276 145: 0xafafaf,
277 146: 0xafafd7,
278 147: 0xafafff,
279 148: 0xafd700,
280 149: 0xafd75f,
281 150: 0xafd787,
282 151: 0xafd7af,
283 152: 0xafd7d7,
284 153: 0xafd7ff,
285 154: 0xafff00,
286 155: 0xafff5f,
287 156: 0xafff87,
288 157: 0xafffaf,
289 158: 0xafffd7,
290 159: 0xafffff,
291 160: 0xd70000,
292 161: 0xd7005f,
293 162: 0xd70087,
294 163: 0xd700af,
295 164: 0xd700d7,
296 165: 0xd700ff,
297 166: 0xd75f00,
298 167: 0xd75f5f,
299 168: 0xd75f87,
300 169: 0xd75faf,
301 170: 0xd75fd7,
302 171: 0xd75fff,
303 172: 0xd78700,
304 173: 0xd7875f,
305 174: 0xd78787,
306 175: 0xd787af,
307 176: 0xd787d7,
308 177: 0xd787ff,
309 178: 0xd7af00,
310 179: 0xd7af5f,
311 180: 0xd7af87,
312 181: 0xd7afaf,
313 182: 0xd7afd7,
314 183: 0xd7afff,
315 184: 0xd7d700,
316 185: 0xd7d75f,
317 186: 0xd7d787,
318 187: 0xd7d7af,
319 188: 0xd7d7d7,
320 189: 0xd7d7ff,
321 190: 0xd7ff00,
322 191: 0xd7ff5f,
323 192: 0xd7ff87,
324 193: 0xd7ffaf,
325 194: 0xd7ffd7,
326 195: 0xd7ffff,
327 196: 0xff0000,
328 197: 0xff005f,
329 198: 0xff0087,
330 199: 0xff00af,
331 200: 0xff00d7,
332 201: 0xff00ff,
333 202: 0xff5f00,
334 203: 0xff5f5f,
335 204: 0xff5f87,
336 205: 0xff5faf,
337 206: 0xff5fd7,
338 207: 0xff5fff,
339 208: 0xff8700,
340 209: 0xff875f,
341 210: 0xff8787,
342 211: 0xff87af,
343 212: 0xff87d7,
344 213: 0xff87ff,
345 214: 0xffaf00,
346 215: 0xffaf5f,
347 216: 0xffaf87,
348 217: 0xffafaf,
349 218: 0xffafd7,
350 219: 0xffafff,
351 220: 0xffd700,
352 221: 0xffd75f,
353 222: 0xffd787,
354 223: 0xffd7af,
355 224: 0xffd7d7,
356 225: 0xffd7ff,
357 226: 0xffff00,
358 227: 0xffff5f,
359 228: 0xffff87,
360 229: 0xffffaf,
361 230: 0xffffd7,
362 231: 0xffffff,
363 232: 0x080808,
364 233: 0x121212,
365 234: 0x1c1c1c,
366 235: 0x262626,
367 236: 0x303030,
368 237: 0x3a3a3a,
369 238: 0x444444,
370 239: 0x4e4e4e,
371 240: 0x585858,
372 241: 0x626262,
373 242: 0x6c6c6c,
374 243: 0x767676,
375 244: 0x808080,
376 245: 0x8a8a8a,
377 246: 0x949494,
378 247: 0x9e9e9e,
379 248: 0xa8a8a8,
380 249: 0xb2b2b2,
381 250: 0xbcbcbc,
382 251: 0xc6c6c6,
383 252: 0xd0d0d0,
384 253: 0xdadada,
385 254: 0xe4e4e4,
386 255: 0xeeeeee,
387}
388
389// `\033]0;TITLESTR\007`
390func doTitleSequence(er *bytes.Reader) error {
391 var c byte
392 var err error
393
394 c, err = er.ReadByte()
395 if err != nil {
396 return err
397 }
398 if c != '0' && c != '2' {
399 return nil
400 }
401 c, err = er.ReadByte()
402 if err != nil {
403 return err
404 }
405 if c != ';' {
406 return nil
407 }
408 title := make([]byte, 0, 80)
409 for {
410 c, err = er.ReadByte()
411 if err != nil {
412 return err
413 }
414 if c == 0x07 || c == '\n' {
415 break
416 }
417 title = append(title, c)
418 }
419 if len(title) > 0 {
420 title8, err := syscall.UTF16PtrFromString(string(title))
421 if err == nil {
422 procSetConsoleTitle.Call(uintptr(unsafe.Pointer(title8)))
423 }
424 }
425 return nil
426}
427
428// returns Atoi(s) unless s == "" in which case it returns def
429func atoiWithDefault(s string, def int) (int, error) {
430 if s == "" {
431 return def, nil
432 }
433 return strconv.Atoi(s)
434}
435
436// Write writes data on console
437func (w *writer) Write(data []byte) (n int, err error) {
438 w.mutex.Lock()
439 defer w.mutex.Unlock()
440 var csbi consoleScreenBufferInfo
441 procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi)))
442
443 handle := w.handle
444
445 var er *bytes.Reader
446 if w.rest.Len() > 0 {
447 var rest bytes.Buffer
448 w.rest.WriteTo(&rest)
449 w.rest.Reset()
450 rest.Write(data)
451 er = bytes.NewReader(rest.Bytes())
452 } else {
453 er = bytes.NewReader(data)
454 }
455 var plaintext bytes.Buffer
456loop:
457 for {
458 c1, err := er.ReadByte()
459 if err != nil {
460 plaintext.WriteTo(w.out)
461 break loop
462 }
463 if c1 != 0x1b {
464 plaintext.WriteByte(c1)
465 continue
466 }
467 _, err = plaintext.WriteTo(w.out)
468 if err != nil {
469 break loop
470 }
471 c2, err := er.ReadByte()
472 if err != nil {
473 break loop
474 }
475
476 switch c2 {
477 case '>':
478 continue
479 case ']':
480 w.rest.WriteByte(c1)
481 w.rest.WriteByte(c2)
482 er.WriteTo(&w.rest)
483 if bytes.IndexByte(w.rest.Bytes(), 0x07) == -1 {
484 break loop
485 }
486 er = bytes.NewReader(w.rest.Bytes()[2:])
487 err := doTitleSequence(er)
488 if err != nil {
489 break loop
490 }
491 w.rest.Reset()
492 continue
493 // https://github.com/mattn/go-colorable/issues/27
494 case '7':
495 procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi)))
496 w.oldpos = csbi.cursorPosition
497 continue
498 case '8':
499 procSetConsoleCursorPosition.Call(uintptr(handle), *(*uintptr)(unsafe.Pointer(&w.oldpos)))
500 continue
501 case 0x5b:
502 // execute part after switch
503 default:
504 continue
505 }
506
507 w.rest.WriteByte(c1)
508 w.rest.WriteByte(c2)
509 er.WriteTo(&w.rest)
510
511 var buf bytes.Buffer
512 var m byte
513 for i, c := range w.rest.Bytes()[2:] {
514 if ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || c == '@' {
515 m = c
516 er = bytes.NewReader(w.rest.Bytes()[2+i+1:])
517 w.rest.Reset()
518 break
519 }
520 buf.Write([]byte(string(c)))
521 }
522 if m == 0 {
523 break loop
524 }
525
526 switch m {
527 case 'A':
528 n, err = atoiWithDefault(buf.String(), 1)
529 if err != nil {
530 continue
531 }
532 procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi)))
533 csbi.cursorPosition.y -= short(n)
534 procSetConsoleCursorPosition.Call(uintptr(handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition)))
535 case 'B':
536 n, err = atoiWithDefault(buf.String(), 1)
537 if err != nil {
538 continue
539 }
540 procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi)))
541 csbi.cursorPosition.y += short(n)
542 procSetConsoleCursorPosition.Call(uintptr(handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition)))
543 case 'C':
544 n, err = atoiWithDefault(buf.String(), 1)
545 if err != nil {
546 continue
547 }
548 procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi)))
549 csbi.cursorPosition.x += short(n)
550 procSetConsoleCursorPosition.Call(uintptr(handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition)))
551 case 'D':
552 n, err = atoiWithDefault(buf.String(), 1)
553 if err != nil {
554 continue
555 }
556 procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi)))
557 csbi.cursorPosition.x -= short(n)
558 if csbi.cursorPosition.x < 0 {
559 csbi.cursorPosition.x = 0
560 }
561 procSetConsoleCursorPosition.Call(uintptr(handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition)))
562 case 'E':
563 n, err = atoiWithDefault(buf.String(), 1)
564 if err != nil {
565 continue
566 }
567 procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi)))
568 csbi.cursorPosition.x = 0
569 csbi.cursorPosition.y += short(n)
570 procSetConsoleCursorPosition.Call(uintptr(handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition)))
571 case 'F':
572 n, err = atoiWithDefault(buf.String(), 1)
573 if err != nil {
574 continue
575 }
576 procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi)))
577 csbi.cursorPosition.x = 0
578 csbi.cursorPosition.y -= short(n)
579 procSetConsoleCursorPosition.Call(uintptr(handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition)))
580 case 'G':
581 n, err = strconv.Atoi(buf.String())
582 if err != nil {
583 continue
584 }
585 if n < 1 {
586 n = 1
587 }
588 procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi)))
589 csbi.cursorPosition.x = short(n - 1)
590 procSetConsoleCursorPosition.Call(uintptr(handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition)))
591 case 'H', 'f':
592 procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi)))
593 if buf.Len() > 0 {
594 token := strings.Split(buf.String(), ";")
595 switch len(token) {
596 case 1:
597 n1, err := strconv.Atoi(token[0])
598 if err != nil {
599 continue
600 }
601 csbi.cursorPosition.y = short(n1 - 1)
602 case 2:
603 n1, err := strconv.Atoi(token[0])
604 if err != nil {
605 continue
606 }
607 n2, err := strconv.Atoi(token[1])
608 if err != nil {
609 continue
610 }
611 csbi.cursorPosition.x = short(n2 - 1)
612 csbi.cursorPosition.y = short(n1 - 1)
613 }
614 } else {
615 csbi.cursorPosition.y = 0
616 }
617 procSetConsoleCursorPosition.Call(uintptr(handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition)))
618 case 'J':
619 n := 0
620 if buf.Len() > 0 {
621 n, err = strconv.Atoi(buf.String())
622 if err != nil {
623 continue
624 }
625 }
626 var count, written dword
627 var cursor coord
628 procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi)))
629 switch n {
630 case 0:
631 cursor = coord{x: csbi.cursorPosition.x, y: csbi.cursorPosition.y}
632 count = dword(csbi.size.x) - dword(csbi.cursorPosition.x) + dword(csbi.size.y-csbi.cursorPosition.y)*dword(csbi.size.x)
633 case 1:
634 cursor = coord{x: csbi.window.left, y: csbi.window.top}
635 count = dword(csbi.size.x) - dword(csbi.cursorPosition.x) + dword(csbi.window.top-csbi.cursorPosition.y)*dword(csbi.size.x)
636 case 2:
637 cursor = coord{x: csbi.window.left, y: csbi.window.top}
638 count = dword(csbi.size.x) - dword(csbi.cursorPosition.x) + dword(csbi.size.y-csbi.cursorPosition.y)*dword(csbi.size.x)
639 }
640 procFillConsoleOutputCharacter.Call(uintptr(handle), uintptr(' '), uintptr(count), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written)))
641 procFillConsoleOutputAttribute.Call(uintptr(handle), uintptr(csbi.attributes), uintptr(count), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written)))
642 case 'K':
643 n := 0
644 if buf.Len() > 0 {
645 n, err = strconv.Atoi(buf.String())
646 if err != nil {
647 continue
648 }
649 }
650 procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi)))
651 var cursor coord
652 var count, written dword
653 switch n {
654 case 0:
655 cursor = coord{x: csbi.cursorPosition.x, y: csbi.cursorPosition.y}
656 count = dword(csbi.size.x - csbi.cursorPosition.x)
657 case 1:
658 cursor = coord{x: csbi.window.left, y: csbi.cursorPosition.y}
659 count = dword(csbi.size.x - csbi.cursorPosition.x)
660 case 2:
661 cursor = coord{x: csbi.window.left, y: csbi.cursorPosition.y}
662 count = dword(csbi.size.x)
663 }
664 procFillConsoleOutputCharacter.Call(uintptr(handle), uintptr(' '), uintptr(count), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written)))
665 procFillConsoleOutputAttribute.Call(uintptr(handle), uintptr(csbi.attributes), uintptr(count), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written)))
666 case 'X':
667 n := 0
668 if buf.Len() > 0 {
669 n, err = strconv.Atoi(buf.String())
670 if err != nil {
671 continue
672 }
673 }
674 procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi)))
675 var cursor coord
676 var written dword
677 cursor = coord{x: csbi.cursorPosition.x, y: csbi.cursorPosition.y}
678 procFillConsoleOutputCharacter.Call(uintptr(handle), uintptr(' '), uintptr(n), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written)))
679 procFillConsoleOutputAttribute.Call(uintptr(handle), uintptr(csbi.attributes), uintptr(n), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written)))
680 case 'm':
681 procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi)))
682 attr := csbi.attributes
683 cs := buf.String()
684 if cs == "" {
685 procSetConsoleTextAttribute.Call(uintptr(handle), uintptr(w.oldattr))
686 continue
687 }
688 token := strings.Split(cs, ";")
689 for i := 0; i < len(token); i++ {
690 ns := token[i]
691 if n, err = strconv.Atoi(ns); err == nil {
692 switch {
693 case n == 0 || n == 100:
694 attr = w.oldattr
695 case n == 4:
696 attr |= commonLvbUnderscore
697 case (1 <= n && n <= 3) || n == 5:
698 attr |= foregroundIntensity
699 case n == 7 || n == 27:
700 attr =
701 (attr &^ (foregroundMask | backgroundMask)) |
702 ((attr & foregroundMask) << 4) |
703 ((attr & backgroundMask) >> 4)
704 case n == 22:
705 attr &^= foregroundIntensity
706 case n == 24:
707 attr &^= commonLvbUnderscore
708 case 30 <= n && n <= 37:
709 attr &= backgroundMask
710 if (n-30)&1 != 0 {
711 attr |= foregroundRed
712 }
713 if (n-30)&2 != 0 {
714 attr |= foregroundGreen
715 }
716 if (n-30)&4 != 0 {
717 attr |= foregroundBlue
718 }
719 case n == 38: // set foreground color.
720 if i < len(token)-2 && (token[i+1] == "5" || token[i+1] == "05") {
721 if n256, err := strconv.Atoi(token[i+2]); err == nil {
722 if n256foreAttr == nil {
723 n256setup()
724 }
725 attr &= backgroundMask
726 attr |= n256foreAttr[n256%len(n256foreAttr)]
727 i += 2
728 }
729 } else if len(token) == 5 && token[i+1] == "2" {
730 var r, g, b int
731 r, _ = strconv.Atoi(token[i+2])
732 g, _ = strconv.Atoi(token[i+3])
733 b, _ = strconv.Atoi(token[i+4])
734 i += 4
735 if r > 127 {
736 attr |= foregroundRed
737 }
738 if g > 127 {
739 attr |= foregroundGreen
740 }
741 if b > 127 {
742 attr |= foregroundBlue
743 }
744 } else {
745 attr = attr & (w.oldattr & backgroundMask)
746 }
747 case n == 39: // reset foreground color.
748 attr &= backgroundMask
749 attr |= w.oldattr & foregroundMask
750 case 40 <= n && n <= 47:
751 attr &= foregroundMask
752 if (n-40)&1 != 0 {
753 attr |= backgroundRed
754 }
755 if (n-40)&2 != 0 {
756 attr |= backgroundGreen
757 }
758 if (n-40)&4 != 0 {
759 attr |= backgroundBlue
760 }
761 case n == 48: // set background color.
762 if i < len(token)-2 && token[i+1] == "5" {
763 if n256, err := strconv.Atoi(token[i+2]); err == nil {
764 if n256backAttr == nil {
765 n256setup()
766 }
767 attr &= foregroundMask
768 attr |= n256backAttr[n256%len(n256backAttr)]
769 i += 2
770 }
771 } else if len(token) == 5 && token[i+1] == "2" {
772 var r, g, b int
773 r, _ = strconv.Atoi(token[i+2])
774 g, _ = strconv.Atoi(token[i+3])
775 b, _ = strconv.Atoi(token[i+4])
776 i += 4
777 if r > 127 {
778 attr |= backgroundRed
779 }
780 if g > 127 {
781 attr |= backgroundGreen
782 }
783 if b > 127 {
784 attr |= backgroundBlue
785 }
786 } else {
787 attr = attr & (w.oldattr & foregroundMask)
788 }
789 case n == 49: // reset foreground color.
790 attr &= foregroundMask
791 attr |= w.oldattr & backgroundMask
792 case 90 <= n && n <= 97:
793 attr = (attr & backgroundMask)
794 attr |= foregroundIntensity
795 if (n-90)&1 != 0 {
796 attr |= foregroundRed
797 }
798 if (n-90)&2 != 0 {
799 attr |= foregroundGreen
800 }
801 if (n-90)&4 != 0 {
802 attr |= foregroundBlue
803 }
804 case 100 <= n && n <= 107:
805 attr = (attr & foregroundMask)
806 attr |= backgroundIntensity
807 if (n-100)&1 != 0 {
808 attr |= backgroundRed
809 }
810 if (n-100)&2 != 0 {
811 attr |= backgroundGreen
812 }
813 if (n-100)&4 != 0 {
814 attr |= backgroundBlue
815 }
816 }
817 procSetConsoleTextAttribute.Call(uintptr(handle), uintptr(attr))
818 }
819 }
820 case 'h':
821 var ci consoleCursorInfo
822 cs := buf.String()
823 if cs == "5>" {
824 procGetConsoleCursorInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&ci)))
825 ci.visible = 0
826 procSetConsoleCursorInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&ci)))
827 } else if cs == "?25" {
828 procGetConsoleCursorInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&ci)))
829 ci.visible = 1
830 procSetConsoleCursorInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&ci)))
831 } else if cs == "?1049" {
832 if w.althandle == 0 {
833 h, _, _ := procCreateConsoleScreenBuffer.Call(uintptr(genericRead|genericWrite), 0, 0, uintptr(consoleTextmodeBuffer), 0, 0)
834 w.althandle = syscall.Handle(h)
835 if w.althandle != 0 {
836 handle = w.althandle
837 }
838 }
839 }
840 case 'l':
841 var ci consoleCursorInfo
842 cs := buf.String()
843 if cs == "5>" {
844 procGetConsoleCursorInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&ci)))
845 ci.visible = 1
846 procSetConsoleCursorInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&ci)))
847 } else if cs == "?25" {
848 procGetConsoleCursorInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&ci)))
849 ci.visible = 0
850 procSetConsoleCursorInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&ci)))
851 } else if cs == "?1049" {
852 if w.althandle != 0 {
853 syscall.CloseHandle(w.althandle)
854 w.althandle = 0
855 handle = w.handle
856 }
857 }
858 case 's':
859 procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi)))
860 w.oldpos = csbi.cursorPosition
861 case 'u':
862 procSetConsoleCursorPosition.Call(uintptr(handle), *(*uintptr)(unsafe.Pointer(&w.oldpos)))
863 }
864 }
865
866 return len(data), nil
867}
868
869type consoleColor struct {
870 rgb int
871 red bool
872 green bool
873 blue bool
874 intensity bool
875}
876
877func (c consoleColor) foregroundAttr() (attr word) {
878 if c.red {
879 attr |= foregroundRed
880 }
881 if c.green {
882 attr |= foregroundGreen
883 }
884 if c.blue {
885 attr |= foregroundBlue
886 }
887 if c.intensity {
888 attr |= foregroundIntensity
889 }
890 return
891}
892
893func (c consoleColor) backgroundAttr() (attr word) {
894 if c.red {
895 attr |= backgroundRed
896 }
897 if c.green {
898 attr |= backgroundGreen
899 }
900 if c.blue {
901 attr |= backgroundBlue
902 }
903 if c.intensity {
904 attr |= backgroundIntensity
905 }
906 return
907}
908
909var color16 = []consoleColor{
910 {0x000000, false, false, false, false},
911 {0x000080, false, false, true, false},
912 {0x008000, false, true, false, false},
913 {0x008080, false, true, true, false},
914 {0x800000, true, false, false, false},
915 {0x800080, true, false, true, false},
916 {0x808000, true, true, false, false},
917 {0xc0c0c0, true, true, true, false},
918 {0x808080, false, false, false, true},
919 {0x0000ff, false, false, true, true},
920 {0x00ff00, false, true, false, true},
921 {0x00ffff, false, true, true, true},
922 {0xff0000, true, false, false, true},
923 {0xff00ff, true, false, true, true},
924 {0xffff00, true, true, false, true},
925 {0xffffff, true, true, true, true},
926}
927
928type hsv struct {
929 h, s, v float32
930}
931
932func (a hsv) dist(b hsv) float32 {
933 dh := a.h - b.h
934 switch {
935 case dh > 0.5:
936 dh = 1 - dh
937 case dh < -0.5:
938 dh = -1 - dh
939 }
940 ds := a.s - b.s
941 dv := a.v - b.v
942 return float32(math.Sqrt(float64(dh*dh + ds*ds + dv*dv)))
943}
944
945func toHSV(rgb int) hsv {
946 r, g, b := float32((rgb&0xFF0000)>>16)/256.0,
947 float32((rgb&0x00FF00)>>8)/256.0,
948 float32(rgb&0x0000FF)/256.0
949 min, max := minmax3f(r, g, b)
950 h := max - min
951 if h > 0 {
952 if max == r {
953 h = (g - b) / h
954 if h < 0 {
955 h += 6
956 }
957 } else if max == g {
958 h = 2 + (b-r)/h
959 } else {
960 h = 4 + (r-g)/h
961 }
962 }
963 h /= 6.0
964 s := max - min
965 if max != 0 {
966 s /= max
967 }
968 v := max
969 return hsv{h: h, s: s, v: v}
970}
971
972type hsvTable []hsv
973
974func toHSVTable(rgbTable []consoleColor) hsvTable {
975 t := make(hsvTable, len(rgbTable))
976 for i, c := range rgbTable {
977 t[i] = toHSV(c.rgb)
978 }
979 return t
980}
981
982func (t hsvTable) find(rgb int) consoleColor {
983 hsv := toHSV(rgb)
984 n := 7
985 l := float32(5.0)
986 for i, p := range t {
987 d := hsv.dist(p)
988 if d < l {
989 l, n = d, i
990 }
991 }
992 return color16[n]
993}
994
995func minmax3f(a, b, c float32) (min, max float32) {
996 if a < b {
997 if b < c {
998 return a, c
999 } else if a < c {
1000 return a, b
1001 } else {
1002 return c, b
1003 }
1004 } else {
1005 if a < c {
1006 return b, c
1007 } else if b < c {
1008 return b, a
1009 } else {
1010 return c, a
1011 }
1012 }
1013}
1014
1015var n256foreAttr []word
1016var n256backAttr []word
1017
1018func n256setup() {
1019 n256foreAttr = make([]word, 256)
1020 n256backAttr = make([]word, 256)
1021 t := toHSVTable(color16)
1022 for i, rgb := range color256 {
1023 c := t.find(rgb)
1024 n256foreAttr[i] = c.foregroundAttr()
1025 n256backAttr[i] = c.backgroundAttr()
1026 }
1027}
1028
1029// EnableColorsStdout enable colors if possible.
1030func EnableColorsStdout(enabled *bool) func() {
1031 var mode uint32
1032 h := os.Stdout.Fd()
1033 if r, _, _ := procGetConsoleMode.Call(h, uintptr(unsafe.Pointer(&mode))); r != 0 {
1034 if r, _, _ = procSetConsoleMode.Call(h, uintptr(mode|cENABLE_VIRTUAL_TERMINAL_PROCESSING)); r != 0 {
1035 if enabled != nil {
1036 *enabled = true
1037 }
1038 return func() {
1039 procSetConsoleMode.Call(h, uintptr(mode))
1040 }
1041 }
1042 }
1043 if enabled != nil {
1044 *enabled = true
1045 }
1046 return func() {}
1047}
diff --git a/vendor/github.com/mattn/go-colorable/go.test.sh b/vendor/github.com/mattn/go-colorable/go.test.sh
new file mode 100644
index 0000000..012162b
--- /dev/null
+++ b/vendor/github.com/mattn/go-colorable/go.test.sh
@@ -0,0 +1,12 @@
1#!/usr/bin/env bash
2
3set -e
4echo "" > coverage.txt
5
6for d in $(go list ./... | grep -v vendor); do
7 go test -race -coverprofile=profile.out -covermode=atomic "$d"
8 if [ -f profile.out ]; then
9 cat profile.out >> coverage.txt
10 rm profile.out
11 fi
12done
diff --git a/vendor/github.com/mattn/go-colorable/noncolorable.go b/vendor/github.com/mattn/go-colorable/noncolorable.go
new file mode 100644
index 0000000..05d6f74
--- /dev/null
+++ b/vendor/github.com/mattn/go-colorable/noncolorable.go
@@ -0,0 +1,57 @@
1package colorable
2
3import (
4 "bytes"
5 "io"
6)
7
8// NonColorable holds writer but removes escape sequence.
9type NonColorable struct {
10 out io.Writer
11}
12
13// NewNonColorable returns new instance of Writer which removes escape sequence from Writer.
14func NewNonColorable(w io.Writer) io.Writer {
15 return &NonColorable{out: w}
16}
17
18// Write writes data on console
19func (w *NonColorable) Write(data []byte) (n int, err error) {
20 er := bytes.NewReader(data)
21 var plaintext bytes.Buffer
22loop:
23 for {
24 c1, err := er.ReadByte()
25 if err != nil {
26 plaintext.WriteTo(w.out)
27 break loop
28 }
29 if c1 != 0x1b {
30 plaintext.WriteByte(c1)
31 continue
32 }
33 _, err = plaintext.WriteTo(w.out)
34 if err != nil {
35 break loop
36 }
37 c2, err := er.ReadByte()
38 if err != nil {
39 break loop
40 }
41 if c2 != 0x5b {
42 continue
43 }
44
45 for {
46 c, err := er.ReadByte()
47 if err != nil {
48 break loop
49 }
50 if ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || c == '@' {
51 break
52 }
53 }
54 }
55
56 return len(data), nil
57}