Compare commits

...
Author SHA1 Message Date
dependabot[bot] 2585c4b3ec Bump github.com/xo/terminfo from 1.0.0 to 1.2.0
Bumps [github.com/xo/terminfo](https://github.com/xo/terminfo) from 1.0.0 to 1.2.0.
- [Release notes](https://github.com/xo/terminfo/releases)
- [Commits](https://github.com/xo/terminfo/compare/v1.0.0...v1.2.0)

---
updated-dependencies:
- dependency-name: github.com/xo/terminfo
  dependency-version: 1.2.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-09-23 00:03:23 +00:00
8 changed files with 83 additions and 59 deletions
+1 -1
View File
@@ -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
+2 -2
View File
@@ -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=
+4 -4
View File
@@ -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
+43 -21
View File
@@ -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]]
+19 -19
View File
@@ -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...)))
}
+3 -3
View File
@@ -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
}
+9 -7
View File
@@ -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...)
}
+2 -2
View File
@@ -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