forked from toolshed/abra
build: go 1.24
We were running behind and there were quite some deprecations to update. This was mostly in the upstream copy/pasta package but seems quite minimal.
This commit is contained in:
245
vendor/github.com/xo/terminfo/dec.go
generated
vendored
Normal file
245
vendor/github.com/xo/terminfo/dec.go
generated
vendored
Normal file
@ -0,0 +1,245 @@
|
||||
package terminfo
|
||||
|
||||
import (
|
||||
"sort"
|
||||
)
|
||||
|
||||
const (
|
||||
// maxFileLength is the max file length.
|
||||
maxFileLength = 4096
|
||||
// magic is the file magic for terminfo files.
|
||||
magic = 0o432
|
||||
// magicExtended is the file magic for terminfo files with the extended
|
||||
// number format.
|
||||
magicExtended = 0o1036
|
||||
)
|
||||
|
||||
// header fields.
|
||||
const (
|
||||
fieldMagic = iota
|
||||
fieldNameSize
|
||||
fieldBoolCount
|
||||
fieldNumCount
|
||||
fieldStringCount
|
||||
fieldTableSize
|
||||
)
|
||||
|
||||
// header extended fields.
|
||||
const (
|
||||
fieldExtBoolCount = iota
|
||||
fieldExtNumCount
|
||||
fieldExtStringCount
|
||||
fieldExtOffsetCount
|
||||
fieldExtTableSize
|
||||
)
|
||||
|
||||
// hasInvalidCaps determines if the capabilities in h are invalid.
|
||||
func hasInvalidCaps(h []int) bool {
|
||||
return h[fieldBoolCount] > CapCountBool ||
|
||||
h[fieldNumCount] > CapCountNum ||
|
||||
h[fieldStringCount] > CapCountString
|
||||
}
|
||||
|
||||
// capLength returns the total length of the capabilities in bytes.
|
||||
func capLength(h []int) int {
|
||||
return h[fieldNameSize] +
|
||||
h[fieldBoolCount] +
|
||||
(h[fieldNameSize]+h[fieldBoolCount])%2 + // account for word align
|
||||
h[fieldNumCount]*2 +
|
||||
h[fieldStringCount]*2 +
|
||||
h[fieldTableSize]
|
||||
}
|
||||
|
||||
// hasInvalidExtOffset determines if the extended offset field is valid.
|
||||
func hasInvalidExtOffset(h []int) bool {
|
||||
return h[fieldExtBoolCount]+
|
||||
h[fieldExtNumCount]+
|
||||
h[fieldExtStringCount]*2 != h[fieldExtOffsetCount]
|
||||
}
|
||||
|
||||
// extCapLength returns the total length of extended capabilities in bytes.
|
||||
func extCapLength(h []int, numWidth int) int {
|
||||
return h[fieldExtBoolCount] +
|
||||
h[fieldExtBoolCount]%2 + // account for word align
|
||||
h[fieldExtNumCount]*(numWidth/8) +
|
||||
h[fieldExtOffsetCount]*2 +
|
||||
h[fieldExtTableSize]
|
||||
}
|
||||
|
||||
// findNull finds the position of null in buf.
|
||||
func findNull(buf []byte, i int) int {
|
||||
for ; i < len(buf); i++ {
|
||||
if buf[i] == 0 {
|
||||
return i
|
||||
}
|
||||
}
|
||||
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) {
|
||||
var last int
|
||||
m := make(map[int][]byte)
|
||||
for i := 0; i < n; i++ {
|
||||
start := idx[i]
|
||||
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 m, last, nil
|
||||
}
|
||||
|
||||
// decoder holds state info while decoding a terminfo file.
|
||||
type decoder struct {
|
||||
buf []byte
|
||||
pos int
|
||||
n int
|
||||
}
|
||||
|
||||
// readBytes reads the next n bytes of buf, incrementing pos by n.
|
||||
func (d *decoder) readBytes(n int) ([]byte, error) {
|
||||
if d.n < d.pos+n {
|
||||
return nil, ErrUnexpectedFileEnd
|
||||
}
|
||||
n, d.pos = d.pos, d.pos+n
|
||||
return d.buf[n:d.pos], nil
|
||||
}
|
||||
|
||||
// readInts reads n number of ints with width w.
|
||||
func (d *decoder) readInts(n, w int) ([]int, error) {
|
||||
w /= 8
|
||||
l := n * w
|
||||
buf, err := d.readBytes(l)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// align
|
||||
d.pos += d.pos % 2
|
||||
z := make([]int, n)
|
||||
for i, j := 0, 0; i < l; i, j = i+w, j+1 {
|
||||
switch w {
|
||||
case 1:
|
||||
z[i] = int(buf[i])
|
||||
case 2:
|
||||
z[j] = int(int16(buf[i+1])<<8 | int16(buf[i]))
|
||||
case 4:
|
||||
z[j] = int(buf[i+3])<<24 | int(buf[i+2])<<16 | int(buf[i+1])<<8 | int(buf[i])
|
||||
}
|
||||
}
|
||||
return z, nil
|
||||
}
|
||||
|
||||
// readBools reads the next n bools.
|
||||
func (d *decoder) readBools(n int) (map[int]bool, map[int]bool, error) {
|
||||
buf, err := d.readInts(n, 8)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
// process
|
||||
bools, boolsM := make(map[int]bool), make(map[int]bool)
|
||||
for i, b := range buf {
|
||||
bools[i] = b == 1
|
||||
if int8(b) == -2 {
|
||||
boolsM[i] = true
|
||||
}
|
||||
}
|
||||
return bools, boolsM, nil
|
||||
}
|
||||
|
||||
// readNums reads the next n nums.
|
||||
func (d *decoder) readNums(n, w int) (map[int]int, map[int]bool, error) {
|
||||
buf, err := d.readInts(n, w)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
// process
|
||||
nums, numsM := make(map[int]int), make(map[int]bool)
|
||||
for i := 0; i < n; i++ {
|
||||
nums[i] = buf[i]
|
||||
if buf[i] == -2 {
|
||||
numsM[i] = true
|
||||
}
|
||||
}
|
||||
return nums, numsM, nil
|
||||
}
|
||||
|
||||
// readStringTable reads the string data for n strings and the accompanying data
|
||||
// table of length sz.
|
||||
func (d *decoder) readStringTable(n, sz int) ([][]byte, []int, error) {
|
||||
buf, err := d.readInts(n, 16)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
// read string data table
|
||||
data, err := d.readBytes(sz)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
// align
|
||||
d.pos += d.pos % 2
|
||||
// process
|
||||
s := make([][]byte, n)
|
||||
var m []int
|
||||
for i := 0; i < n; i++ {
|
||||
start := buf[i]
|
||||
if start == -2 {
|
||||
m = append(m, i)
|
||||
} else if start >= 0 {
|
||||
if end := findNull(data, start); end != -1 {
|
||||
s[i] = data[start:end]
|
||||
} else {
|
||||
return nil, nil, ErrInvalidStringTable
|
||||
}
|
||||
}
|
||||
}
|
||||
return s, m, nil
|
||||
}
|
||||
|
||||
// readStrings reads the next n strings and processes the string data table of
|
||||
// length sz.
|
||||
func (d *decoder) readStrings(n, sz int) (map[int][]byte, map[int]bool, error) {
|
||||
s, m, err := d.readStringTable(n, sz)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
strs := make(map[int][]byte)
|
||||
for k, v := range s {
|
||||
if k == AcsChars {
|
||||
v = canonicalizeAscChars(v)
|
||||
}
|
||||
strs[k] = v
|
||||
}
|
||||
strsM := make(map[int]bool, len(m))
|
||||
for _, k := range m {
|
||||
strsM[k] = true
|
||||
}
|
||||
return strs, strsM, nil
|
||||
}
|
||||
|
||||
// canonicalizeAscChars reorders chars to be unique, in order.
|
||||
//
|
||||
// see repair_ascc in ncurses-6.3/progs/dump_entry.c
|
||||
func canonicalizeAscChars(z []byte) []byte {
|
||||
var c []byte
|
||||
enc := make(map[byte]byte, len(z)/2)
|
||||
for i := 0; i < len(z); i += 2 {
|
||||
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
|
||||
}
|
||||
}
|
||||
sort.Slice(c, func(i, j int) bool {
|
||||
return c[i] < c[j]
|
||||
})
|
||||
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]]
|
||||
}
|
||||
return r
|
||||
}
|
Reference in New Issue
Block a user