diff --git a/go.mod b/go.mod index e822034ca..68aa39cea 100644 --- a/go.mod +++ b/go.mod @@ -39,7 +39,7 @@ require ( github.com/spkg/bom v1.0.1 github.com/stefanhaller/git-todo-parser v0.0.7-0.20250905083220-c50528f08304 github.com/stretchr/testify v1.12.1 - github.com/xo/terminfo v1.0.0 + github.com/xo/terminfo v1.2.0 golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 golang.org/x/sync v0.22.0 golang.org/x/sys v0.47.0 diff --git a/go.sum b/go.sum index 2198ae1bd..ec5f74c93 100644 --- a/go.sum +++ b/go.sum @@ -127,8 +127,8 @@ github.com/stretchr/testify v1.12.1/go.mod h1:MDEgiDPPsNp5cuIrHPPCyornHKgEVbtFUm github.com/urfave/cli v1.20.1-0.20180226030253-8e01ec4cd3e2/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/wk8/go-ordered-map/v2 v2.1.8 h1:5h/BUHu93oj4gIdvHHHGsScSTMijfx5PeYkE/fJgbpc= github.com/wk8/go-ordered-map/v2 v2.1.8/go.mod h1:5nJHM5DyteebpVlHnWMV0rPz6Zp7+xBAnxjb1X5vnTw= -github.com/xo/terminfo v1.0.0 h1:2ZpYzqWzyyytjk3TP6aJVDhkMAkc99/1xKQdA3TDTBY= -github.com/xo/terminfo v1.0.0/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM= +github.com/xo/terminfo v1.2.0 h1:d0ZTOCpuGE0lwSAOs0zcJjwz3jWQyqcRt9XbGJpCOl4= +github.com/xo/terminfo v1.2.0/go.mod h1:lGzkSo8Fe7IRh/w+Gqz7n5mDog4FVXCj3gy/DYTBqio= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= go.yaml.in/yaml/v3 v3.0.5 h1:N6y/pJk8buWs9NY5ERU2HSMfm+IuD/OtfdAnq6kESPw= go.yaml.in/yaml/v3 v3.0.5/go.mod h1:HVTZu1O7/Vkt2N+BFy8Zza+lnLsABggaTM2ZpNIGuKg= diff --git a/vendor/github.com/xo/terminfo/capvals.go b/vendor/github.com/xo/terminfo/capvals.go index 0c2274e3a..df6ad5089 100644 --- a/vendor/github.com/xo/terminfo/capvals.go +++ b/vendor/github.com/xo/terminfo/capvals.go @@ -353,9 +353,9 @@ const ( KeyStab // The KeyUp [key_up, kcuu1] string capability is the up-arrow key. KeyUp - // The KeypadLocal [keypad_local, rmkx] string capability is the leave 'keyboard_transmit' mode. + // The KeypadLocal [keypad_local, rmkx] string capability is the leave keypad transmit mode. KeypadLocal - // The KeypadXmit [keypad_xmit, smkx] string capability is the enter 'keyboard_transmit' mode. + // The KeypadXmit [keypad_xmit, smkx] string capability is the enter keypad transmit mode. KeypadXmit // The LabF0 [lab_f0, lf0] string capability is the label on function key f0 if not f0. LabF0 @@ -719,7 +719,7 @@ const ( ClrBol // The ClearMargins [clear_margins, mgc] string capability is the clear right and left soft margins. ClearMargins - // The SetLeftMargin [set_left_margin, smgl] string capability is the set left soft margin at current column. (ML is not in BSD termcap). + // The SetLeftMargin [set_left_margin, smgl] string capability is the set left soft margin at current column (not in BSD \fItermcap\fP). SetLeftMargin // The SetRightMargin [set_right_margin, smgr] string capability is the set right soft margin at current column. SetRightMargin @@ -901,7 +901,7 @@ const ( SetABackground // The PkeyPlab [pkey_plab, pfxl] string capability is the Program function key #1 to type string #2 and show string #3. PkeyPlab - // The DeviceType [device_type, devt] string capability is the Indicate language/codeset support. + // The DeviceType [device_type, devt] string capability is the Indicate language, codeset support. DeviceType // The CodeSetInit [code_set_init, csin] string capability is the Init sequence for multiple codesets. CodeSetInit diff --git a/vendor/github.com/xo/terminfo/dec.go b/vendor/github.com/xo/terminfo/dec.go index f650c2dd2..44b21d746 100644 --- a/vendor/github.com/xo/terminfo/dec.go +++ b/vendor/github.com/xo/terminfo/dec.go @@ -1,7 +1,7 @@ package terminfo import ( - "sort" + "slices" ) const ( @@ -29,7 +29,7 @@ const ( fieldExtBoolCount = iota fieldExtNumCount fieldExtStringCount - fieldExtOffsetCount + fieldExtOffsetUsed fieldExtTableSize ) @@ -50,11 +50,29 @@ func capLength(h []int) int { h[fieldTableSize] } +// extOffsetCount returns the number of offsets stored in the extended string +// data table index. +// +// An offset is written for every extended string cap, followed by one for the +// name of every extended bool, num and string cap. +func extOffsetCount(h []int) int { + return h[fieldExtBoolCount] + + h[fieldExtNumCount] + + h[fieldExtStringCount]*2 +} + // hasInvalidExtOffset determines if the extended offset field is valid. +// +// The field holds the number of offsets that are actually used (ie, that point +// into the string data table), which excludes any absent or cancelled extended +// string cap, and so is only ever less than or equal to the number of offsets +// present in the file. func hasInvalidExtOffset(h []int) bool { - return h[fieldExtBoolCount]+ - h[fieldExtNumCount]+ - h[fieldExtStringCount]*2 != h[fieldExtOffsetCount] + return h[fieldExtBoolCount] < 0 || + h[fieldExtNumCount] < 0 || + h[fieldExtStringCount] < 0 || + h[fieldExtOffsetUsed] < 0 || + h[fieldExtOffsetUsed] > extOffsetCount(h) } // extCapLength returns the total length of extended capabilities in bytes. @@ -62,7 +80,7 @@ func extCapLength(h []int, numWidth int) int { return h[fieldExtBoolCount] + h[fieldExtBoolCount]%2 + // account for word align h[fieldExtNumCount]*(numWidth/8) + - h[fieldExtOffsetCount]*2 + + extOffsetCount(h)*2 + h[fieldExtTableSize] } @@ -76,22 +94,28 @@ func findNull(buf []byte, i int) int { return -1 } -// readStrings decodes n strings from string data table buf using the indexes in idx. -func readStrings(idx []int, buf []byte, n int) (map[int][]byte, int, error) { +// readStrings decodes n strings from string data table buf using the indexes in +// idx, returning the decoded strings, the cancelled strings, and the offset of +// the end of the last decoded string. +func readStrings(idx []int, buf []byte, n int) (map[int][]byte, map[int]bool, int, error) { var last int - m := make(map[int][]byte) - for i := 0; i < n; i++ { + m, mm := make(map[int][]byte), make(map[int]bool) + for i := range n { start := idx[i] + if start == -2 { + mm[i] = true + continue + } if start < 0 { continue } if end := findNull(buf, start); end != -1 { m[i], last = buf[start:end], end+1 } else { - return nil, 0, ErrInvalidStringTable + return nil, nil, 0, ErrInvalidStringTable } } - return m, last, nil + return m, mm, last, nil } // decoder holds state info while decoding a terminfo file. @@ -124,11 +148,11 @@ func (d *decoder) readInts(n, w int) ([]int, error) { for i, j := 0, 0; i < l; i, j = i+w, j+1 { switch w { case 1: - z[i] = int(buf[i]) + z[j] = int(buf[i]) case 2: - z[j] = int(int16(buf[i+1])<<8 | int16(buf[i])) + z[j] = int(int16(uint16(buf[i+1])<<8 | uint16(buf[i]))) case 4: - z[j] = int(buf[i+3])<<24 | int(buf[i+2])<<16 | int(buf[i+1])<<8 | int(buf[i]) + z[j] = int(int32(uint32(buf[i+3])<<24 | uint32(buf[i+2])<<16 | uint32(buf[i+1])<<8 | uint32(buf[i]))) } } return z, nil @@ -159,7 +183,7 @@ func (d *decoder) readNums(n, w int) (map[int]int, map[int]bool, error) { } // process nums, numsM := make(map[int]int), make(map[int]bool) - for i := 0; i < n; i++ { + for i := range n { nums[i] = buf[i] if buf[i] == -2 { numsM[i] = true @@ -185,7 +209,7 @@ func (d *decoder) readStringTable(n, sz int) ([][]byte, []int, error) { // process s := make([][]byte, n) var m []int - for i := 0; i < n; i++ { + for i := range n { start := buf[i] if start == -2 { m = append(m, i) @@ -231,12 +255,10 @@ func canonicalizeAscChars(z []byte) []byte { if _, ok := enc[z[i]]; !ok { a, b := z[i], z[i+1] // log.Printf(">>> a: %d %c, b: %d %c", a, a, b, b) - c, enc[a] = append(c, b), b + c, enc[a] = append(c, a), b } } - sort.Slice(c, func(i, j int) bool { - return c[i] < c[j] - }) + slices.Sort(c) r := make([]byte, 2*len(c)) for i := 0; i < len(c); i++ { r[i*2], r[i*2+1] = c[i], enc[c[i]] diff --git a/vendor/github.com/xo/terminfo/param.go b/vendor/github.com/xo/terminfo/param.go index ed4cb86b6..6109c94b7 100644 --- a/vendor/github.com/xo/terminfo/param.go +++ b/vendor/github.com/xo/terminfo/param.go @@ -24,19 +24,19 @@ type parametizer struct { // buf is the result buffer. buf *bytes.Buffer // params are the parameters to interpolate. - params [9]interface{} + params [9]any // vars are dynamic variables. - vars [26]interface{} + vars [26]any } // staticVars are the static, global variables. var staticVars = struct { - vars [26]interface{} + vars [26]any sync.Mutex }{} var parametizerPool = sync.Pool{ - New: func() interface{} { + New: func() any { p := new(parametizer) p.buf = bytes.NewBuffer(make([]byte, 0, 45)) return p @@ -55,7 +55,7 @@ func (p *parametizer) reset() { p.pos, p.nest = 0, 0 p.s.reset() p.buf.Reset() - p.params, p.vars = [9]interface{}{}, [26]interface{}{} + p.params, p.vars = [9]any{}, [26]any{} parametizerPool.Put(p) } @@ -230,7 +230,8 @@ func (p *parametizer) scanFormatFn() stateFn { // the character was already read, so no need to check the error. ch, _ := p.peek() // 6 should be the maximum length of a format string, for example "%:-9.9d". - f := []byte{'%', ch, 0, 0, 0, 0} + f := make([]byte, 2, 6) + f[0], f[1] = '%', ch var err error for { p.pos++ @@ -242,17 +243,18 @@ func (p *parametizer) scanFormatFn() stateFn { switch ch { case 'o', 'd', 'x', 'X': fmt.Fprintf(p.buf, string(f), p.s.popInt()) - break + p.pos++ + return p.scanTextFn case 's': fmt.Fprintf(p.buf, string(f), p.s.popString()) - break + p.pos++ + return p.scanTextFn case 'c': fmt.Fprintf(p.buf, string(f), p.s.popByte()) - break + p.pos++ + return p.scanTextFn } } - p.pos++ - return p.scanTextFn } func (p *parametizer) pushParamFn() stateFn { @@ -291,15 +293,13 @@ func (p *parametizer) getDsVarFn() stateFn { if err != nil { return nil } - var a byte if ch >= 'A' && ch <= 'Z' { - a = 'A' + staticVars.Lock() + p.s.push(staticVars.vars[int(ch-'A')]) + staticVars.Unlock() } else if ch >= 'a' && ch <= 'z' { - a = 'a' + p.s.push(p.vars[int(ch-'a')]) } - staticVars.Lock() - p.s.push(staticVars.vars[int(ch-a)]) - staticVars.Unlock() p.pos++ return p.scanTextFn } @@ -387,7 +387,7 @@ func (p *parametizer) skipElseFn() stateFn { } // Printf evaluates a parameterized terminfo value z, interpolating params. -func Printf(z []byte, params ...interface{}) string { +func Printf(z []byte, params ...any) string { p := newParametizer(z) defer p.reset() // make sure we always have 9 parameters -- makes it easier @@ -400,6 +400,6 @@ func Printf(z []byte, params ...interface{}) string { // Fprintf evaluates a parameterized terminfo value z, interpolating params and // writing to w. -func Fprintf(w io.Writer, z []byte, params ...interface{}) { +func Fprintf(w io.Writer, z []byte, params ...any) { w.Write([]byte(Printf(z, params...))) } diff --git a/vendor/github.com/xo/terminfo/stack.go b/vendor/github.com/xo/terminfo/stack.go index a6de39503..08cf92a7f 100644 --- a/vendor/github.com/xo/terminfo/stack.go +++ b/vendor/github.com/xo/terminfo/stack.go @@ -1,12 +1,12 @@ package terminfo -type stack []interface{} +type stack []any -func (s *stack) push(v interface{}) { +func (s *stack) push(v any) { *s = append(*s, v) } -func (s *stack) pop() interface{} { +func (s *stack) pop() any { if len(*s) == 0 { return nil } diff --git a/vendor/github.com/xo/terminfo/terminfo.go b/vendor/github.com/xo/terminfo/terminfo.go index 69e3b6064..292b99c60 100644 --- a/vendor/github.com/xo/terminfo/terminfo.go +++ b/vendor/github.com/xo/terminfo/terminfo.go @@ -72,6 +72,8 @@ type Terminfo struct { ExtNumNames map[int][]byte // ExtStrings are the extended string capabilities. ExtStrings map[int][]byte + // ExtStringsM are the missing extended string capabilities. + ExtStringsM map[int]bool // ExtStringsNames is the map of extended string capabilities to their index. ExtStringNames map[int][]byte } @@ -173,7 +175,7 @@ func Decode(buf []byte) (*Terminfo, error) { return nil, err } // read extended string data table indexes - extIndexes, err := d.readInts(eh[fieldExtOffsetCount], 16) + extIndexes, err := d.readInts(extOffsetCount(eh), 16) if err != nil { return nil, err } @@ -188,25 +190,25 @@ func Decode(buf []byte) (*Terminfo, error) { } var last int // read extended string caps - ti.ExtStrings, last, err = readStrings(extIndexes, extData, eh[fieldExtStringCount]) + ti.ExtStrings, ti.ExtStringsM, last, err = readStrings(extIndexes, extData, eh[fieldExtStringCount]) if err != nil { return nil, err } extIndexes, extData = extIndexes[eh[fieldExtStringCount]:], extData[last:] // read extended bool names - ti.ExtBoolNames, _, err = readStrings(extIndexes, extData, eh[fieldExtBoolCount]) + ti.ExtBoolNames, _, _, err = readStrings(extIndexes, extData, eh[fieldExtBoolCount]) if err != nil { return nil, err } extIndexes = extIndexes[eh[fieldExtBoolCount]:] // read extended num names - ti.ExtNumNames, _, err = readStrings(extIndexes, extData, eh[fieldExtNumCount]) + ti.ExtNumNames, _, _, err = readStrings(extIndexes, extData, eh[fieldExtNumCount]) if err != nil { return nil, err } extIndexes = extIndexes[eh[fieldExtNumCount]:] // read extended string names - ti.ExtStringNames, _, err = readStrings(extIndexes, extData, eh[fieldExtStringCount]) + ti.ExtStringNames, _, _, err = readStrings(extIndexes, extData, eh[fieldExtStringCount]) if err != nil { return nil, err } @@ -377,12 +379,12 @@ func (ti *Terminfo) Num(i int) int { } // Printf formats the string cap i, interpolating parameters v. -func (ti *Terminfo) Printf(i int, v ...interface{}) string { +func (ti *Terminfo) Printf(i int, v ...any) string { return Printf(ti.Strings[i], v...) } // Fprintf prints the string cap i to writer w, interpolating parameters v. -func (ti *Terminfo) Fprintf(w io.Writer, i int, v ...interface{}) { +func (ti *Terminfo) Fprintf(w io.Writer, i int, v ...any) { Fprintf(w, ti.Strings[i], v...) } diff --git a/vendor/modules.txt b/vendor/modules.txt index 8e401aeb5..2030e1cb9 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -157,8 +157,8 @@ github.com/stretchr/testify/internal/spew # github.com/wk8/go-ordered-map/v2 v2.1.8 ## explicit; go 1.18 github.com/wk8/go-ordered-map/v2 -# github.com/xo/terminfo v1.0.0 -## explicit; go 1.19 +# github.com/xo/terminfo v1.2.0 +## explicit; go 1.25 github.com/xo/terminfo # go.yaml.in/yaml/v3 v3.0.5 ## explicit; go 1.16