mirror of
				https://github.com/taigrr/wtf
				synced 2025-01-18 04:03:14 -08:00 
			
		
		
		
	
		
			
				
	
	
		
			889 lines
		
	
	
		
			25 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			889 lines
		
	
	
		
			25 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
// +build ignore
 | 
						|
 | 
						|
// Copyright 2019 The TCell Authors
 | 
						|
//
 | 
						|
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
						|
// you may not use file except in compliance with the License.
 | 
						|
// You may obtain a copy of the license at
 | 
						|
//
 | 
						|
//    http://www.apache.org/licenses/LICENSE-2.0
 | 
						|
//
 | 
						|
// Unless required by applicable law or agreed to in writing, software
 | 
						|
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
						|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
						|
// See the License for the specific language governing permissions and
 | 
						|
// limitations under the License.
 | 
						|
 | 
						|
// This command is used to generate suitable configuration files in either
 | 
						|
// go syntax or in JSON.  It defaults to JSON output on stdout.  If no
 | 
						|
// term values are specified on the command line, then $TERM is used.
 | 
						|
//
 | 
						|
// Usage is like this:
 | 
						|
//
 | 
						|
// mkinfo [-init] [-go file.go] [-json file.json] [-quiet] [-nofatal] [<term>...]
 | 
						|
//
 | 
						|
// -all      scan terminfo to determine database entries to use
 | 
						|
// -db       generate database entries (database/*), implied for -all
 | 
						|
// -gzip     specifies output should be compressed (json only)
 | 
						|
// -go       specifies Go output into the named file.  Use - for stdout.
 | 
						|
// -json     specifies JSON output in the named file.  Use - for stdout
 | 
						|
// -nofatal  indicates that errors loading definitions should not be fatal
 | 
						|
//
 | 
						|
 | 
						|
package main
 | 
						|
 | 
						|
import (
 | 
						|
	"bufio"
 | 
						|
	"bytes"
 | 
						|
	"compress/gzip"
 | 
						|
	"crypto/sha1"
 | 
						|
	"encoding/json"
 | 
						|
	"errors"
 | 
						|
	"flag"
 | 
						|
	"fmt"
 | 
						|
	"io"
 | 
						|
	"os"
 | 
						|
	"os/exec"
 | 
						|
	"path"
 | 
						|
	"regexp"
 | 
						|
	"strconv"
 | 
						|
	"strings"
 | 
						|
 | 
						|
	"github.com/gdamore/tcell/terminfo"
 | 
						|
)
 | 
						|
 | 
						|
type termcap struct {
 | 
						|
	name    string
 | 
						|
	desc    string
 | 
						|
	aliases []string
 | 
						|
	bools   map[string]bool
 | 
						|
	nums    map[string]int
 | 
						|
	strs    map[string]string
 | 
						|
}
 | 
						|
 | 
						|
func (tc *termcap) getnum(s string) int {
 | 
						|
	return (tc.nums[s])
 | 
						|
}
 | 
						|
 | 
						|
func (tc *termcap) getflag(s string) bool {
 | 
						|
	return (tc.bools[s])
 | 
						|
}
 | 
						|
 | 
						|
func (tc *termcap) getstr(s string) string {
 | 
						|
	return (tc.strs[s])
 | 
						|
}
 | 
						|
 | 
						|
const (
 | 
						|
	NONE = iota
 | 
						|
	CTRL
 | 
						|
	ESC
 | 
						|
)
 | 
						|
 | 
						|
var notaddressable = errors.New("terminal not cursor addressable")
 | 
						|
 | 
						|
func unescape(s string) string {
 | 
						|
	// Various escapes are in \x format.  Control codes are
 | 
						|
	// encoded as ^M (carat followed by ASCII equivalent).
 | 
						|
	// Escapes are: \e, \E - escape
 | 
						|
	//  \0 NULL, \n \l \r \t \b \f \s for equivalent C escape.
 | 
						|
	buf := &bytes.Buffer{}
 | 
						|
	esc := NONE
 | 
						|
 | 
						|
	for i := 0; i < len(s); i++ {
 | 
						|
		c := s[i]
 | 
						|
		switch esc {
 | 
						|
		case NONE:
 | 
						|
			switch c {
 | 
						|
			case '\\':
 | 
						|
				esc = ESC
 | 
						|
			case '^':
 | 
						|
				esc = CTRL
 | 
						|
			default:
 | 
						|
				buf.WriteByte(c)
 | 
						|
			}
 | 
						|
		case CTRL:
 | 
						|
			buf.WriteByte(c - 0x40)
 | 
						|
			esc = NONE
 | 
						|
		case ESC:
 | 
						|
			switch c {
 | 
						|
			case 'E', 'e':
 | 
						|
				buf.WriteByte(0x1b)
 | 
						|
			case '0', '1', '2', '3', '4', '5', '6', '7':
 | 
						|
				if i+2 < len(s) && s[i+1] >= '0' && s[i+1] <= '7' && s[i+2] >= '0' && s[i+2] <= '7' {
 | 
						|
					buf.WriteByte(((c - '0') * 64) + ((s[i+1] - '0') * 8) + (s[i+2] - '0'))
 | 
						|
					i = i + 2
 | 
						|
				} else if c == '0' {
 | 
						|
					buf.WriteByte(0)
 | 
						|
				}
 | 
						|
			case 'n':
 | 
						|
				buf.WriteByte('\n')
 | 
						|
			case 'r':
 | 
						|
				buf.WriteByte('\r')
 | 
						|
			case 't':
 | 
						|
				buf.WriteByte('\t')
 | 
						|
			case 'b':
 | 
						|
				buf.WriteByte('\b')
 | 
						|
			case 'f':
 | 
						|
				buf.WriteByte('\f')
 | 
						|
			case 's':
 | 
						|
				buf.WriteByte(' ')
 | 
						|
			case 'l':
 | 
						|
				panic("WTF: weird format: " + s)
 | 
						|
			default:
 | 
						|
				buf.WriteByte(c)
 | 
						|
			}
 | 
						|
			esc = NONE
 | 
						|
		}
 | 
						|
	}
 | 
						|
	return (buf.String())
 | 
						|
}
 | 
						|
 | 
						|
func getallterms() ([]string, error) {
 | 
						|
	out := []string{}
 | 
						|
	cmd := exec.Command("toe", "-a")
 | 
						|
	output := &bytes.Buffer{}
 | 
						|
	cmd.Stdout = output
 | 
						|
	err := cmd.Run()
 | 
						|
	if err != nil {
 | 
						|
		return nil, err
 | 
						|
	}
 | 
						|
	lines := strings.Split(output.String(), "\n")
 | 
						|
	for _, l := range lines {
 | 
						|
		fields := strings.Fields(l)
 | 
						|
		if len(fields) > 0 {
 | 
						|
			out = append(out, fields[0])
 | 
						|
		}
 | 
						|
	}
 | 
						|
	return out, nil
 | 
						|
}
 | 
						|
 | 
						|
func (tc *termcap) setupterm(name string) error {
 | 
						|
	cmd := exec.Command("infocmp", "-1", name)
 | 
						|
	output := &bytes.Buffer{}
 | 
						|
	cmd.Stdout = output
 | 
						|
 | 
						|
	tc.strs = make(map[string]string)
 | 
						|
	tc.bools = make(map[string]bool)
 | 
						|
	tc.nums = make(map[string]int)
 | 
						|
 | 
						|
	err := cmd.Run()
 | 
						|
	if err != nil {
 | 
						|
		return err
 | 
						|
	}
 | 
						|
 | 
						|
	// Now parse the output.
 | 
						|
	// We get comment lines (starting with "#"), followed by
 | 
						|
	// a header line that looks like "<name>|<alias>|...|<desc>"
 | 
						|
	// then capabilities, one per line, starting with a tab and ending
 | 
						|
	// with a comma and newline.
 | 
						|
	lines := strings.Split(output.String(), "\n")
 | 
						|
	for len(lines) > 0 && strings.HasPrefix(lines[0], "#") {
 | 
						|
		lines = lines[1:]
 | 
						|
	}
 | 
						|
 | 
						|
	// Ditch trailing empty last line
 | 
						|
	if lines[len(lines)-1] == "" {
 | 
						|
		lines = lines[:len(lines)-1]
 | 
						|
	}
 | 
						|
	header := lines[0]
 | 
						|
	if strings.HasSuffix(header, ",") {
 | 
						|
		header = header[:len(header)-1]
 | 
						|
	}
 | 
						|
	names := strings.Split(header, "|")
 | 
						|
	tc.name = names[0]
 | 
						|
	names = names[1:]
 | 
						|
	if len(names) > 0 {
 | 
						|
		tc.desc = names[len(names)-1]
 | 
						|
		names = names[:len(names)-1]
 | 
						|
	}
 | 
						|
	tc.aliases = names
 | 
						|
	for _, val := range lines[1:] {
 | 
						|
		if (!strings.HasPrefix(val, "\t")) ||
 | 
						|
			(!strings.HasSuffix(val, ",")) {
 | 
						|
			return (errors.New("malformed infocmp: " + val))
 | 
						|
		}
 | 
						|
 | 
						|
		val = val[1:]
 | 
						|
		val = val[:len(val)-1]
 | 
						|
 | 
						|
		if k := strings.SplitN(val, "=", 2); len(k) == 2 {
 | 
						|
			tc.strs[k[0]] = unescape(k[1])
 | 
						|
		} else if k := strings.SplitN(val, "#", 2); len(k) == 2 {
 | 
						|
			if u, err := strconv.ParseUint(k[1], 0, 0); err != nil {
 | 
						|
				return (err)
 | 
						|
			} else {
 | 
						|
				tc.nums[k[0]] = int(u)
 | 
						|
			}
 | 
						|
		} else {
 | 
						|
			tc.bools[val] = true
 | 
						|
		}
 | 
						|
	}
 | 
						|
	return nil
 | 
						|
}
 | 
						|
 | 
						|
// This program is used to collect data from the system's terminfo library,
 | 
						|
// and write it into Go source code.  That is, we maintain our terminfo
 | 
						|
// capabilities encoded in the program.  It should never need to be run by
 | 
						|
// an end user, but developers can use this to add codes for additional
 | 
						|
// terminal types.
 | 
						|
func getinfo(name string) (*terminfo.Terminfo, string, error) {
 | 
						|
	var tc termcap
 | 
						|
	if err := tc.setupterm(name); err != nil {
 | 
						|
		if err != nil {
 | 
						|
			return nil, "", err
 | 
						|
		}
 | 
						|
	}
 | 
						|
	t := &terminfo.Terminfo{}
 | 
						|
	// If this is an alias record, then just emit the alias
 | 
						|
	t.Name = tc.name
 | 
						|
	if t.Name != name {
 | 
						|
		return t, "", nil
 | 
						|
	}
 | 
						|
	t.Aliases = tc.aliases
 | 
						|
	t.Colors = tc.getnum("colors")
 | 
						|
	t.Columns = tc.getnum("cols")
 | 
						|
	t.Lines = tc.getnum("lines")
 | 
						|
	t.Bell = tc.getstr("bel")
 | 
						|
	t.Clear = tc.getstr("clear")
 | 
						|
	t.EnterCA = tc.getstr("smcup")
 | 
						|
	t.ExitCA = tc.getstr("rmcup")
 | 
						|
	t.ShowCursor = tc.getstr("cnorm")
 | 
						|
	t.HideCursor = tc.getstr("civis")
 | 
						|
	t.AttrOff = tc.getstr("sgr0")
 | 
						|
	t.Underline = tc.getstr("smul")
 | 
						|
	t.Bold = tc.getstr("bold")
 | 
						|
	t.Blink = tc.getstr("blink")
 | 
						|
	t.Dim = tc.getstr("dim")
 | 
						|
	t.Reverse = tc.getstr("rev")
 | 
						|
	t.EnterKeypad = tc.getstr("smkx")
 | 
						|
	t.ExitKeypad = tc.getstr("rmkx")
 | 
						|
	t.SetFg = tc.getstr("setaf")
 | 
						|
	t.SetBg = tc.getstr("setab")
 | 
						|
	t.SetCursor = tc.getstr("cup")
 | 
						|
	t.CursorBack1 = tc.getstr("cub1")
 | 
						|
	t.CursorUp1 = tc.getstr("cuu1")
 | 
						|
	t.KeyF1 = tc.getstr("kf1")
 | 
						|
	t.KeyF2 = tc.getstr("kf2")
 | 
						|
	t.KeyF3 = tc.getstr("kf3")
 | 
						|
	t.KeyF4 = tc.getstr("kf4")
 | 
						|
	t.KeyF5 = tc.getstr("kf5")
 | 
						|
	t.KeyF6 = tc.getstr("kf6")
 | 
						|
	t.KeyF7 = tc.getstr("kf7")
 | 
						|
	t.KeyF8 = tc.getstr("kf8")
 | 
						|
	t.KeyF9 = tc.getstr("kf9")
 | 
						|
	t.KeyF10 = tc.getstr("kf10")
 | 
						|
	t.KeyF11 = tc.getstr("kf11")
 | 
						|
	t.KeyF12 = tc.getstr("kf12")
 | 
						|
	t.KeyF13 = tc.getstr("kf13")
 | 
						|
	t.KeyF14 = tc.getstr("kf14")
 | 
						|
	t.KeyF15 = tc.getstr("kf15")
 | 
						|
	t.KeyF16 = tc.getstr("kf16")
 | 
						|
	t.KeyF17 = tc.getstr("kf17")
 | 
						|
	t.KeyF18 = tc.getstr("kf18")
 | 
						|
	t.KeyF19 = tc.getstr("kf19")
 | 
						|
	t.KeyF20 = tc.getstr("kf20")
 | 
						|
	t.KeyF21 = tc.getstr("kf21")
 | 
						|
	t.KeyF22 = tc.getstr("kf22")
 | 
						|
	t.KeyF23 = tc.getstr("kf23")
 | 
						|
	t.KeyF24 = tc.getstr("kf24")
 | 
						|
	t.KeyF25 = tc.getstr("kf25")
 | 
						|
	t.KeyF26 = tc.getstr("kf26")
 | 
						|
	t.KeyF27 = tc.getstr("kf27")
 | 
						|
	t.KeyF28 = tc.getstr("kf28")
 | 
						|
	t.KeyF29 = tc.getstr("kf29")
 | 
						|
	t.KeyF30 = tc.getstr("kf30")
 | 
						|
	t.KeyF31 = tc.getstr("kf31")
 | 
						|
	t.KeyF32 = tc.getstr("kf32")
 | 
						|
	t.KeyF33 = tc.getstr("kf33")
 | 
						|
	t.KeyF34 = tc.getstr("kf34")
 | 
						|
	t.KeyF35 = tc.getstr("kf35")
 | 
						|
	t.KeyF36 = tc.getstr("kf36")
 | 
						|
	t.KeyF37 = tc.getstr("kf37")
 | 
						|
	t.KeyF38 = tc.getstr("kf38")
 | 
						|
	t.KeyF39 = tc.getstr("kf39")
 | 
						|
	t.KeyF40 = tc.getstr("kf40")
 | 
						|
	t.KeyF41 = tc.getstr("kf41")
 | 
						|
	t.KeyF42 = tc.getstr("kf42")
 | 
						|
	t.KeyF43 = tc.getstr("kf43")
 | 
						|
	t.KeyF44 = tc.getstr("kf44")
 | 
						|
	t.KeyF45 = tc.getstr("kf45")
 | 
						|
	t.KeyF46 = tc.getstr("kf46")
 | 
						|
	t.KeyF47 = tc.getstr("kf47")
 | 
						|
	t.KeyF48 = tc.getstr("kf48")
 | 
						|
	t.KeyF49 = tc.getstr("kf49")
 | 
						|
	t.KeyF50 = tc.getstr("kf50")
 | 
						|
	t.KeyF51 = tc.getstr("kf51")
 | 
						|
	t.KeyF52 = tc.getstr("kf52")
 | 
						|
	t.KeyF53 = tc.getstr("kf53")
 | 
						|
	t.KeyF54 = tc.getstr("kf54")
 | 
						|
	t.KeyF55 = tc.getstr("kf55")
 | 
						|
	t.KeyF56 = tc.getstr("kf56")
 | 
						|
	t.KeyF57 = tc.getstr("kf57")
 | 
						|
	t.KeyF58 = tc.getstr("kf58")
 | 
						|
	t.KeyF59 = tc.getstr("kf59")
 | 
						|
	t.KeyF60 = tc.getstr("kf60")
 | 
						|
	t.KeyF61 = tc.getstr("kf61")
 | 
						|
	t.KeyF62 = tc.getstr("kf62")
 | 
						|
	t.KeyF63 = tc.getstr("kf63")
 | 
						|
	t.KeyF64 = tc.getstr("kf64")
 | 
						|
	t.KeyInsert = tc.getstr("kich1")
 | 
						|
	t.KeyDelete = tc.getstr("kdch1")
 | 
						|
	t.KeyBackspace = tc.getstr("kbs")
 | 
						|
	t.KeyHome = tc.getstr("khome")
 | 
						|
	t.KeyEnd = tc.getstr("kend")
 | 
						|
	t.KeyUp = tc.getstr("kcuu1")
 | 
						|
	t.KeyDown = tc.getstr("kcud1")
 | 
						|
	t.KeyRight = tc.getstr("kcuf1")
 | 
						|
	t.KeyLeft = tc.getstr("kcub1")
 | 
						|
	t.KeyPgDn = tc.getstr("knp")
 | 
						|
	t.KeyPgUp = tc.getstr("kpp")
 | 
						|
	t.KeyBacktab = tc.getstr("kcbt")
 | 
						|
	t.KeyExit = tc.getstr("kext")
 | 
						|
	t.KeyCancel = tc.getstr("kcan")
 | 
						|
	t.KeyPrint = tc.getstr("kprt")
 | 
						|
	t.KeyHelp = tc.getstr("khlp")
 | 
						|
	t.KeyClear = tc.getstr("kclr")
 | 
						|
	t.AltChars = tc.getstr("acsc")
 | 
						|
	t.EnterAcs = tc.getstr("smacs")
 | 
						|
	t.ExitAcs = tc.getstr("rmacs")
 | 
						|
	t.EnableAcs = tc.getstr("enacs")
 | 
						|
	t.Mouse = tc.getstr("kmous")
 | 
						|
	t.KeyShfRight = tc.getstr("kRIT")
 | 
						|
	t.KeyShfLeft = tc.getstr("kLFT")
 | 
						|
	t.KeyShfHome = tc.getstr("kHOM")
 | 
						|
	t.KeyShfEnd = tc.getstr("kEND")
 | 
						|
 | 
						|
	// Terminfo lacks descriptions for a bunch of modified keys,
 | 
						|
	// but modern XTerm and emulators often have them.  Let's add them,
 | 
						|
	// if the shifted right and left arrows are defined.
 | 
						|
	if t.KeyShfRight == "\x1b[1;2C" && t.KeyShfLeft == "\x1b[1;2D" {
 | 
						|
		t.KeyShfUp = "\x1b[1;2A"
 | 
						|
		t.KeyShfDown = "\x1b[1;2B"
 | 
						|
		t.KeyMetaUp = "\x1b[1;9A"
 | 
						|
		t.KeyMetaDown = "\x1b[1;9B"
 | 
						|
		t.KeyMetaRight = "\x1b[1;9C"
 | 
						|
		t.KeyMetaLeft = "\x1b[1;9D"
 | 
						|
		t.KeyAltUp = "\x1b[1;3A"
 | 
						|
		t.KeyAltDown = "\x1b[1;3B"
 | 
						|
		t.KeyAltRight = "\x1b[1;3C"
 | 
						|
		t.KeyAltLeft = "\x1b[1;3D"
 | 
						|
		t.KeyCtrlUp = "\x1b[1;5A"
 | 
						|
		t.KeyCtrlDown = "\x1b[1;5B"
 | 
						|
		t.KeyCtrlRight = "\x1b[1;5C"
 | 
						|
		t.KeyCtrlLeft = "\x1b[1;5D"
 | 
						|
		t.KeyAltShfUp = "\x1b[1;4A"
 | 
						|
		t.KeyAltShfDown = "\x1b[1;4B"
 | 
						|
		t.KeyAltShfRight = "\x1b[1;4C"
 | 
						|
		t.KeyAltShfLeft = "\x1b[1;4D"
 | 
						|
 | 
						|
		t.KeyMetaShfUp = "\x1b[1;10A"
 | 
						|
		t.KeyMetaShfDown = "\x1b[1;10B"
 | 
						|
		t.KeyMetaShfRight = "\x1b[1;10C"
 | 
						|
		t.KeyMetaShfLeft = "\x1b[1;10D"
 | 
						|
 | 
						|
		t.KeyCtrlShfUp = "\x1b[1;6A"
 | 
						|
		t.KeyCtrlShfDown = "\x1b[1;6B"
 | 
						|
		t.KeyCtrlShfRight = "\x1b[1;6C"
 | 
						|
		t.KeyCtrlShfLeft = "\x1b[1;6D"
 | 
						|
	}
 | 
						|
	// And also for Home and End
 | 
						|
	if t.KeyShfHome == "\x1b[1;2H" && t.KeyShfEnd == "\x1b[1;2F" {
 | 
						|
		t.KeyCtrlHome = "\x1b[1;5H"
 | 
						|
		t.KeyCtrlEnd = "\x1b[1;5F"
 | 
						|
		t.KeyAltHome = "\x1b[1;9H"
 | 
						|
		t.KeyAltEnd = "\x1b[1;9F"
 | 
						|
		t.KeyCtrlShfHome = "\x1b[1;6H"
 | 
						|
		t.KeyCtrlShfEnd = "\x1b[1;6F"
 | 
						|
		t.KeyAltShfHome = "\x1b[1;4H"
 | 
						|
		t.KeyAltShfEnd = "\x1b[1;4F"
 | 
						|
		t.KeyMetaShfHome = "\x1b[1;10H"
 | 
						|
		t.KeyMetaShfEnd = "\x1b[1;10F"
 | 
						|
	}
 | 
						|
 | 
						|
	// And the same thing for rxvt and workalikes (Eterm, aterm, etc.)
 | 
						|
	// It seems that urxvt at least send ESC as ALT prefix for these,
 | 
						|
	// although some places seem to indicate a separate ALT key sesquence.
 | 
						|
	if t.KeyShfRight == "\x1b[c" && t.KeyShfLeft == "\x1b[d" {
 | 
						|
		t.KeyShfUp = "\x1b[a"
 | 
						|
		t.KeyShfDown = "\x1b[b"
 | 
						|
		t.KeyCtrlUp = "\x1b[Oa"
 | 
						|
		t.KeyCtrlDown = "\x1b[Ob"
 | 
						|
		t.KeyCtrlRight = "\x1b[Oc"
 | 
						|
		t.KeyCtrlLeft = "\x1b[Od"
 | 
						|
	}
 | 
						|
	if t.KeyShfHome == "\x1b[7$" && t.KeyShfEnd == "\x1b[8$" {
 | 
						|
		t.KeyCtrlHome = "\x1b[7^"
 | 
						|
		t.KeyCtrlEnd = "\x1b[8^"
 | 
						|
	}
 | 
						|
 | 
						|
	// If the kmous entry is present, then we need to record the
 | 
						|
	// the codes to enter and exit mouse mode.  Sadly, this is not
 | 
						|
	// part of the terminfo databases anywhere that I've found, but
 | 
						|
	// is an extension.  The escape codes are documented in the XTerm
 | 
						|
	// manual, and all terminals that have kmous are expected to
 | 
						|
	// use these same codes, unless explicitly configured otherwise
 | 
						|
	// vi XM.  Note that in any event, we only known how to parse either
 | 
						|
	// x11 or SGR mouse events -- if your terminal doesn't support one
 | 
						|
	// of these two forms, you maybe out of luck.
 | 
						|
	t.MouseMode = tc.getstr("XM")
 | 
						|
	if t.Mouse != "" && t.MouseMode == "" {
 | 
						|
		// we anticipate that all xterm mouse tracking compatible
 | 
						|
		// terminals understand mouse tracking (1000), but we hope
 | 
						|
		// that those that don't understand any-event tracking (1003)
 | 
						|
		// will at least ignore it.  Likewise we hope that terminals
 | 
						|
		// that don't understand SGR reporting (1006) just ignore it.
 | 
						|
		t.MouseMode = "%?%p1%{1}%=%t%'h'%Pa%e%'l'%Pa%;" +
 | 
						|
			"\x1b[?1000%ga%c\x1b[?1002%ga%c\x1b[?1003%ga%c\x1b[?1006%ga%c"
 | 
						|
	}
 | 
						|
 | 
						|
	// We only support colors in ANSI 8 or 256 color mode.
 | 
						|
	if t.Colors < 8 || t.SetFg == "" {
 | 
						|
		t.Colors = 0
 | 
						|
	}
 | 
						|
	if t.SetCursor == "" {
 | 
						|
		return nil, "", notaddressable
 | 
						|
	}
 | 
						|
 | 
						|
	// For padding, we lookup the pad char.  If that isn't present,
 | 
						|
	// and npc is *not* set, then we assume a null byte.
 | 
						|
	t.PadChar = tc.getstr("pad")
 | 
						|
	if t.PadChar == "" {
 | 
						|
		if !tc.getflag("npc") {
 | 
						|
			t.PadChar = "\u0000"
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	// For terminals that use "standard" SGR sequences, lets combine the
 | 
						|
	// foreground and background together.
 | 
						|
	if strings.HasPrefix(t.SetFg, "\x1b[") &&
 | 
						|
		strings.HasPrefix(t.SetBg, "\x1b[") &&
 | 
						|
		strings.HasSuffix(t.SetFg, "m") &&
 | 
						|
		strings.HasSuffix(t.SetBg, "m") {
 | 
						|
		fg := t.SetFg[:len(t.SetFg)-1]
 | 
						|
		r := regexp.MustCompile("%p1")
 | 
						|
		bg := r.ReplaceAllString(t.SetBg[2:], "%p2")
 | 
						|
		t.SetFgBg = fg + ";" + bg
 | 
						|
	}
 | 
						|
 | 
						|
	return t, tc.desc, nil
 | 
						|
}
 | 
						|
 | 
						|
func dotGoAddInt(w io.Writer, n string, i int) {
 | 
						|
	if i == 0 {
 | 
						|
		// initialized to 0, ignore
 | 
						|
		return
 | 
						|
	}
 | 
						|
	fmt.Fprintf(w, "\t\t%-13s %d,\n", n+":", i)
 | 
						|
}
 | 
						|
func dotGoAddStr(w io.Writer, n string, s string) {
 | 
						|
	if s == "" {
 | 
						|
		return
 | 
						|
	}
 | 
						|
	fmt.Fprintf(w, "\t\t%-13s %q,\n", n+":", s)
 | 
						|
}
 | 
						|
 | 
						|
func dotGoAddArr(w io.Writer, n string, a []string) {
 | 
						|
	if len(a) == 0 {
 | 
						|
		return
 | 
						|
	}
 | 
						|
	fmt.Fprintf(w, "\t\t%-13s []string{", n+":")
 | 
						|
	did := false
 | 
						|
	for _, b := range a {
 | 
						|
		if did {
 | 
						|
			fmt.Fprint(w, ", ")
 | 
						|
		}
 | 
						|
		did = true
 | 
						|
		fmt.Fprintf(w, "%q", b)
 | 
						|
	}
 | 
						|
	fmt.Fprintln(w, "},")
 | 
						|
}
 | 
						|
 | 
						|
func dotGoHeader(w io.Writer, packname string) {
 | 
						|
	fmt.Fprintln(w, "// Generated automatically.  DO NOT HAND-EDIT.")
 | 
						|
	fmt.Fprintln(w, "")
 | 
						|
	fmt.Fprintf(w, "package %s\n", packname)
 | 
						|
	fmt.Fprintln(w, "")
 | 
						|
}
 | 
						|
 | 
						|
func dotGoTrailer(w io.Writer) {
 | 
						|
}
 | 
						|
 | 
						|
func dotGoInfo(w io.Writer, t *terminfo.Terminfo, desc string) {
 | 
						|
 | 
						|
	fmt.Fprintln(w, "")
 | 
						|
	fmt.Fprintln(w, "func init() {")
 | 
						|
	fmt.Fprintf(w, "\t// %s\n", desc)
 | 
						|
	fmt.Fprintln(w, "\tAddTerminfo(&Terminfo{")
 | 
						|
	dotGoAddStr(w, "Name", t.Name)
 | 
						|
	dotGoAddArr(w, "Aliases", t.Aliases)
 | 
						|
	dotGoAddInt(w, "Columns", t.Columns)
 | 
						|
	dotGoAddInt(w, "Lines", t.Lines)
 | 
						|
	dotGoAddInt(w, "Colors", t.Colors)
 | 
						|
	dotGoAddStr(w, "Bell", t.Bell)
 | 
						|
	dotGoAddStr(w, "Clear", t.Clear)
 | 
						|
	dotGoAddStr(w, "EnterCA", t.EnterCA)
 | 
						|
	dotGoAddStr(w, "ExitCA", t.ExitCA)
 | 
						|
	dotGoAddStr(w, "ShowCursor", t.ShowCursor)
 | 
						|
	dotGoAddStr(w, "HideCursor", t.HideCursor)
 | 
						|
	dotGoAddStr(w, "AttrOff", t.AttrOff)
 | 
						|
	dotGoAddStr(w, "Underline", t.Underline)
 | 
						|
	dotGoAddStr(w, "Bold", t.Bold)
 | 
						|
	dotGoAddStr(w, "Dim", t.Dim)
 | 
						|
	dotGoAddStr(w, "Blink", t.Blink)
 | 
						|
	dotGoAddStr(w, "Reverse", t.Reverse)
 | 
						|
	dotGoAddStr(w, "EnterKeypad", t.EnterKeypad)
 | 
						|
	dotGoAddStr(w, "ExitKeypad", t.ExitKeypad)
 | 
						|
	dotGoAddStr(w, "SetFg", t.SetFg)
 | 
						|
	dotGoAddStr(w, "SetBg", t.SetBg)
 | 
						|
	dotGoAddStr(w, "SetFgBg", t.SetFgBg)
 | 
						|
	dotGoAddStr(w, "PadChar", t.PadChar)
 | 
						|
	dotGoAddStr(w, "AltChars", t.AltChars)
 | 
						|
	dotGoAddStr(w, "EnterAcs", t.EnterAcs)
 | 
						|
	dotGoAddStr(w, "ExitAcs", t.ExitAcs)
 | 
						|
	dotGoAddStr(w, "EnableAcs", t.EnableAcs)
 | 
						|
	dotGoAddStr(w, "SetFgRGB", t.SetFgRGB)
 | 
						|
	dotGoAddStr(w, "SetBgRGB", t.SetBgRGB)
 | 
						|
	dotGoAddStr(w, "SetFgBgRGB", t.SetFgBgRGB)
 | 
						|
	dotGoAddStr(w, "Mouse", t.Mouse)
 | 
						|
	dotGoAddStr(w, "MouseMode", t.MouseMode)
 | 
						|
	dotGoAddStr(w, "SetCursor", t.SetCursor)
 | 
						|
	dotGoAddStr(w, "CursorBack1", t.CursorBack1)
 | 
						|
	dotGoAddStr(w, "CursorUp1", t.CursorUp1)
 | 
						|
	dotGoAddStr(w, "KeyUp", t.KeyUp)
 | 
						|
	dotGoAddStr(w, "KeyDown", t.KeyDown)
 | 
						|
	dotGoAddStr(w, "KeyRight", t.KeyRight)
 | 
						|
	dotGoAddStr(w, "KeyLeft", t.KeyLeft)
 | 
						|
	dotGoAddStr(w, "KeyInsert", t.KeyInsert)
 | 
						|
	dotGoAddStr(w, "KeyDelete", t.KeyDelete)
 | 
						|
	dotGoAddStr(w, "KeyBackspace", t.KeyBackspace)
 | 
						|
	dotGoAddStr(w, "KeyHome", t.KeyHome)
 | 
						|
	dotGoAddStr(w, "KeyEnd", t.KeyEnd)
 | 
						|
	dotGoAddStr(w, "KeyPgUp", t.KeyPgUp)
 | 
						|
	dotGoAddStr(w, "KeyPgDn", t.KeyPgDn)
 | 
						|
	dotGoAddStr(w, "KeyF1", t.KeyF1)
 | 
						|
	dotGoAddStr(w, "KeyF2", t.KeyF2)
 | 
						|
	dotGoAddStr(w, "KeyF3", t.KeyF3)
 | 
						|
	dotGoAddStr(w, "KeyF4", t.KeyF4)
 | 
						|
	dotGoAddStr(w, "KeyF5", t.KeyF5)
 | 
						|
	dotGoAddStr(w, "KeyF6", t.KeyF6)
 | 
						|
	dotGoAddStr(w, "KeyF7", t.KeyF7)
 | 
						|
	dotGoAddStr(w, "KeyF8", t.KeyF8)
 | 
						|
	dotGoAddStr(w, "KeyF9", t.KeyF9)
 | 
						|
	dotGoAddStr(w, "KeyF10", t.KeyF10)
 | 
						|
	dotGoAddStr(w, "KeyF11", t.KeyF11)
 | 
						|
	dotGoAddStr(w, "KeyF12", t.KeyF12)
 | 
						|
	dotGoAddStr(w, "KeyF13", t.KeyF13)
 | 
						|
	dotGoAddStr(w, "KeyF14", t.KeyF14)
 | 
						|
	dotGoAddStr(w, "KeyF15", t.KeyF15)
 | 
						|
	dotGoAddStr(w, "KeyF16", t.KeyF16)
 | 
						|
	dotGoAddStr(w, "KeyF17", t.KeyF17)
 | 
						|
	dotGoAddStr(w, "KeyF18", t.KeyF18)
 | 
						|
	dotGoAddStr(w, "KeyF19", t.KeyF19)
 | 
						|
	dotGoAddStr(w, "KeyF20", t.KeyF20)
 | 
						|
	dotGoAddStr(w, "KeyF21", t.KeyF21)
 | 
						|
	dotGoAddStr(w, "KeyF22", t.KeyF22)
 | 
						|
	dotGoAddStr(w, "KeyF23", t.KeyF23)
 | 
						|
	dotGoAddStr(w, "KeyF24", t.KeyF24)
 | 
						|
	dotGoAddStr(w, "KeyF25", t.KeyF25)
 | 
						|
	dotGoAddStr(w, "KeyF26", t.KeyF26)
 | 
						|
	dotGoAddStr(w, "KeyF27", t.KeyF27)
 | 
						|
	dotGoAddStr(w, "KeyF28", t.KeyF28)
 | 
						|
	dotGoAddStr(w, "KeyF29", t.KeyF29)
 | 
						|
	dotGoAddStr(w, "KeyF30", t.KeyF30)
 | 
						|
	dotGoAddStr(w, "KeyF31", t.KeyF31)
 | 
						|
	dotGoAddStr(w, "KeyF32", t.KeyF32)
 | 
						|
	dotGoAddStr(w, "KeyF33", t.KeyF33)
 | 
						|
	dotGoAddStr(w, "KeyF34", t.KeyF34)
 | 
						|
	dotGoAddStr(w, "KeyF35", t.KeyF35)
 | 
						|
	dotGoAddStr(w, "KeyF36", t.KeyF36)
 | 
						|
	dotGoAddStr(w, "KeyF37", t.KeyF37)
 | 
						|
	dotGoAddStr(w, "KeyF38", t.KeyF38)
 | 
						|
	dotGoAddStr(w, "KeyF39", t.KeyF39)
 | 
						|
	dotGoAddStr(w, "KeyF40", t.KeyF40)
 | 
						|
	dotGoAddStr(w, "KeyF41", t.KeyF41)
 | 
						|
	dotGoAddStr(w, "KeyF42", t.KeyF42)
 | 
						|
	dotGoAddStr(w, "KeyF43", t.KeyF43)
 | 
						|
	dotGoAddStr(w, "KeyF44", t.KeyF44)
 | 
						|
	dotGoAddStr(w, "KeyF45", t.KeyF45)
 | 
						|
	dotGoAddStr(w, "KeyF46", t.KeyF46)
 | 
						|
	dotGoAddStr(w, "KeyF47", t.KeyF47)
 | 
						|
	dotGoAddStr(w, "KeyF48", t.KeyF48)
 | 
						|
	dotGoAddStr(w, "KeyF49", t.KeyF49)
 | 
						|
	dotGoAddStr(w, "KeyF50", t.KeyF50)
 | 
						|
	dotGoAddStr(w, "KeyF51", t.KeyF51)
 | 
						|
	dotGoAddStr(w, "KeyF52", t.KeyF52)
 | 
						|
	dotGoAddStr(w, "KeyF53", t.KeyF53)
 | 
						|
	dotGoAddStr(w, "KeyF54", t.KeyF54)
 | 
						|
	dotGoAddStr(w, "KeyF55", t.KeyF55)
 | 
						|
	dotGoAddStr(w, "KeyF56", t.KeyF56)
 | 
						|
	dotGoAddStr(w, "KeyF57", t.KeyF57)
 | 
						|
	dotGoAddStr(w, "KeyF58", t.KeyF58)
 | 
						|
	dotGoAddStr(w, "KeyF59", t.KeyF59)
 | 
						|
	dotGoAddStr(w, "KeyF60", t.KeyF60)
 | 
						|
	dotGoAddStr(w, "KeyF61", t.KeyF61)
 | 
						|
	dotGoAddStr(w, "KeyF62", t.KeyF62)
 | 
						|
	dotGoAddStr(w, "KeyF63", t.KeyF63)
 | 
						|
	dotGoAddStr(w, "KeyF64", t.KeyF64)
 | 
						|
	dotGoAddStr(w, "KeyCancel", t.KeyCancel)
 | 
						|
	dotGoAddStr(w, "KeyPrint", t.KeyPrint)
 | 
						|
	dotGoAddStr(w, "KeyExit", t.KeyExit)
 | 
						|
	dotGoAddStr(w, "KeyHelp", t.KeyHelp)
 | 
						|
	dotGoAddStr(w, "KeyClear", t.KeyClear)
 | 
						|
	dotGoAddStr(w, "KeyBacktab", t.KeyBacktab)
 | 
						|
	dotGoAddStr(w, "KeyShfLeft", t.KeyShfLeft)
 | 
						|
	dotGoAddStr(w, "KeyShfRight", t.KeyShfRight)
 | 
						|
	dotGoAddStr(w, "KeyShfUp", t.KeyShfUp)
 | 
						|
	dotGoAddStr(w, "KeyShfDown", t.KeyShfDown)
 | 
						|
	dotGoAddStr(w, "KeyCtrlLeft", t.KeyCtrlLeft)
 | 
						|
	dotGoAddStr(w, "KeyCtrlRight", t.KeyCtrlRight)
 | 
						|
	dotGoAddStr(w, "KeyCtrlUp", t.KeyCtrlUp)
 | 
						|
	dotGoAddStr(w, "KeyCtrlDown", t.KeyCtrlDown)
 | 
						|
	dotGoAddStr(w, "KeyMetaLeft", t.KeyMetaLeft)
 | 
						|
	dotGoAddStr(w, "KeyMetaRight", t.KeyMetaRight)
 | 
						|
	dotGoAddStr(w, "KeyMetaUp", t.KeyMetaUp)
 | 
						|
	dotGoAddStr(w, "KeyMetaDown", t.KeyMetaDown)
 | 
						|
	dotGoAddStr(w, "KeyAltLeft", t.KeyAltLeft)
 | 
						|
	dotGoAddStr(w, "KeyAltRight", t.KeyAltRight)
 | 
						|
	dotGoAddStr(w, "KeyAltUp", t.KeyAltUp)
 | 
						|
	dotGoAddStr(w, "KeyAltDown", t.KeyAltDown)
 | 
						|
	dotGoAddStr(w, "KeyAltShfLeft", t.KeyAltShfLeft)
 | 
						|
	dotGoAddStr(w, "KeyAltShfRight", t.KeyAltShfRight)
 | 
						|
	dotGoAddStr(w, "KeyAltShfUp", t.KeyAltShfUp)
 | 
						|
	dotGoAddStr(w, "KeyAltShfDown", t.KeyAltShfDown)
 | 
						|
	dotGoAddStr(w, "KeyMetaShfLeft", t.KeyMetaShfLeft)
 | 
						|
	dotGoAddStr(w, "KeyMetaShfRight", t.KeyMetaShfRight)
 | 
						|
	dotGoAddStr(w, "KeyMetaShfUp", t.KeyMetaShfUp)
 | 
						|
	dotGoAddStr(w, "KeyMetaShfDown", t.KeyMetaShfDown)
 | 
						|
	dotGoAddStr(w, "KeyCtrlShfLeft", t.KeyCtrlShfLeft)
 | 
						|
	dotGoAddStr(w, "KeyCtrlShfRight", t.KeyCtrlShfRight)
 | 
						|
	dotGoAddStr(w, "KeyCtrlShfUp", t.KeyCtrlShfUp)
 | 
						|
	dotGoAddStr(w, "KeyCtrlShfDown", t.KeyCtrlShfDown)
 | 
						|
	dotGoAddStr(w, "KeyShfHome", t.KeyShfHome)
 | 
						|
	dotGoAddStr(w, "KeyShfEnd", t.KeyShfEnd)
 | 
						|
	dotGoAddStr(w, "KeyCtrlHome", t.KeyCtrlHome)
 | 
						|
	dotGoAddStr(w, "KeyCtrlEnd", t.KeyCtrlEnd)
 | 
						|
	dotGoAddStr(w, "KeyMetaHome", t.KeyMetaHome)
 | 
						|
	dotGoAddStr(w, "KeyMetaEnd", t.KeyMetaEnd)
 | 
						|
	dotGoAddStr(w, "KeyAltHome", t.KeyAltHome)
 | 
						|
	dotGoAddStr(w, "KeyAltEnd", t.KeyAltEnd)
 | 
						|
	dotGoAddStr(w, "KeyCtrlShfHome", t.KeyCtrlShfHome)
 | 
						|
	dotGoAddStr(w, "KeyCtrlShfEnd", t.KeyCtrlShfEnd)
 | 
						|
	dotGoAddStr(w, "KeyMetaShfHome", t.KeyMetaShfHome)
 | 
						|
	dotGoAddStr(w, "KeyMetaShfEnd", t.KeyMetaShfEnd)
 | 
						|
	dotGoAddStr(w, "KeyAltShfHome", t.KeyAltShfHome)
 | 
						|
	dotGoAddStr(w, "KeyAltShfEnd", t.KeyAltShfEnd)
 | 
						|
	fmt.Fprintln(w, "\t})")
 | 
						|
	fmt.Fprintln(w, "}")
 | 
						|
}
 | 
						|
 | 
						|
var packname = "terminfo"
 | 
						|
 | 
						|
func dotGoFile(fname string, term *terminfo.Terminfo, desc string, makeDir bool) error {
 | 
						|
	w := os.Stdout
 | 
						|
	var e error
 | 
						|
	if fname != "-" && fname != "" {
 | 
						|
		if makeDir {
 | 
						|
			dname := path.Dir(fname)
 | 
						|
			_ = os.Mkdir(dname, 0777)
 | 
						|
		}
 | 
						|
		if w, e = os.Create(fname); e != nil {
 | 
						|
			return e
 | 
						|
		}
 | 
						|
	}
 | 
						|
	dotGoHeader(w, packname)
 | 
						|
	dotGoInfo(w, term, desc)
 | 
						|
	dotGoTrailer(w)
 | 
						|
	if w != os.Stdout {
 | 
						|
		w.Close()
 | 
						|
	}
 | 
						|
	cmd := exec.Command("go", "fmt", fname)
 | 
						|
	cmd.Run()
 | 
						|
	return nil
 | 
						|
}
 | 
						|
 | 
						|
func dotGzFile(fname string, term *terminfo.Terminfo, makeDir bool) error {
 | 
						|
 | 
						|
	var w io.WriteCloser = os.Stdout
 | 
						|
	var e error
 | 
						|
	if fname != "-" && fname != "" {
 | 
						|
		if makeDir {
 | 
						|
			dname := path.Dir(fname)
 | 
						|
			_ = os.Mkdir(dname, 0777)
 | 
						|
		}
 | 
						|
		if w, e = os.Create(fname); e != nil {
 | 
						|
			return e
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	w = gzip.NewWriter(w)
 | 
						|
 | 
						|
	js, e := json.Marshal(term)
 | 
						|
	fmt.Fprintln(w, string(js))
 | 
						|
 | 
						|
	if w != os.Stdout {
 | 
						|
		w.Close()
 | 
						|
	}
 | 
						|
	return nil
 | 
						|
}
 | 
						|
 | 
						|
func jsonFile(fname string, term *terminfo.Terminfo, makeDir bool) error {
 | 
						|
	w := os.Stdout
 | 
						|
	var e error
 | 
						|
	if fname != "-" && fname != "" {
 | 
						|
		if makeDir {
 | 
						|
			dname := path.Dir(fname)
 | 
						|
			_ = os.Mkdir(dname, 0777)
 | 
						|
		}
 | 
						|
		if w, e = os.Create(fname); e != nil {
 | 
						|
			return e
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	js, e := json.Marshal(term)
 | 
						|
	fmt.Fprintln(w, string(js))
 | 
						|
 | 
						|
	if w != os.Stdout {
 | 
						|
		w.Close()
 | 
						|
	}
 | 
						|
	return nil
 | 
						|
}
 | 
						|
 | 
						|
func dumpDatabase(terms map[string]*terminfo.Terminfo, descs map[string]string) {
 | 
						|
 | 
						|
	// Load models .text
 | 
						|
	mfile, e := os.Open("models.txt")
 | 
						|
	models := make(map[string]bool)
 | 
						|
	if e != nil {
 | 
						|
		fmt.Fprintf(os.Stderr, "Failed reading models.txt: %v", e)
 | 
						|
	}
 | 
						|
	scanner := bufio.NewScanner(mfile)
 | 
						|
	for scanner.Scan() {
 | 
						|
		models[scanner.Text()] = true
 | 
						|
	}
 | 
						|
 | 
						|
	for name, t := range terms {
 | 
						|
 | 
						|
		// If this is one of our builtin models, generate the GO file
 | 
						|
		if models[name] {
 | 
						|
			desc := descs[name]
 | 
						|
			safename := strings.Replace(name, "-", "_", -1)
 | 
						|
			goname := fmt.Sprintf("term_%s.go", safename)
 | 
						|
			e = dotGoFile(goname, t, desc, true)
 | 
						|
			if e != nil {
 | 
						|
				fmt.Fprintf(os.Stderr, "Failed creating %s: %v", goname, e)
 | 
						|
				os.Exit(1)
 | 
						|
			}
 | 
						|
			continue
 | 
						|
		}
 | 
						|
 | 
						|
		hash := fmt.Sprintf("%x", sha1.Sum([]byte(name)))
 | 
						|
		fname := fmt.Sprintf("%s.gz", hash[0:8])
 | 
						|
		fname = path.Join("database", hash[0:2], fname)
 | 
						|
		e = dotGzFile(fname, t, true)
 | 
						|
		if e != nil {
 | 
						|
			fmt.Fprintf(os.Stderr, "Failed creating %s: %v", fname, e)
 | 
						|
			os.Exit(1)
 | 
						|
		}
 | 
						|
 | 
						|
		for _, a := range t.Aliases {
 | 
						|
			hash = fmt.Sprintf("%x", sha1.Sum([]byte(a)))
 | 
						|
			fname = path.Join("database", hash[0:2], hash[0:8])
 | 
						|
			e = jsonFile(fname, &terminfo.Terminfo{Name: t.Name}, true)
 | 
						|
			if e != nil {
 | 
						|
				fmt.Fprintf(os.Stderr, "Failed creating %s: %v", fname, e)
 | 
						|
				os.Exit(1)
 | 
						|
			}
 | 
						|
		}
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func main() {
 | 
						|
	gofile := ""
 | 
						|
	jsonfile := ""
 | 
						|
	nofatal := false
 | 
						|
	quiet := false
 | 
						|
	dogzip := false
 | 
						|
	all := false
 | 
						|
	db := false
 | 
						|
 | 
						|
	flag.StringVar(&gofile, "go", "", "generate go source in named file")
 | 
						|
	flag.StringVar(&jsonfile, "json", "", "generate json in named file")
 | 
						|
	flag.StringVar(&packname, "P", packname, "package name (go source)")
 | 
						|
	flag.BoolVar(&nofatal, "nofatal", false, "errors are not fatal")
 | 
						|
	flag.BoolVar(&quiet, "quiet", false, "suppress error messages")
 | 
						|
	flag.BoolVar(&dogzip, "gzip", false, "compress json output")
 | 
						|
	flag.BoolVar(&all, "all", false, "load all terminals from terminfo")
 | 
						|
	flag.BoolVar(&db, "db", false, "generate json db file in place")
 | 
						|
	flag.Parse()
 | 
						|
	var e error
 | 
						|
 | 
						|
	args := flag.Args()
 | 
						|
	if all {
 | 
						|
		db = true // implied
 | 
						|
		allterms, e := getallterms()
 | 
						|
		if e != nil {
 | 
						|
			fmt.Fprintf(os.Stderr, "Failed: %v", e)
 | 
						|
			os.Exit(1)
 | 
						|
		}
 | 
						|
		args = append(args, allterms...)
 | 
						|
	}
 | 
						|
	if len(args) == 0 {
 | 
						|
		args = []string{os.Getenv("TERM")}
 | 
						|
	}
 | 
						|
 | 
						|
	tdata := make(map[string]*terminfo.Terminfo)
 | 
						|
	descs := make(map[string]string)
 | 
						|
 | 
						|
	for _, term := range args {
 | 
						|
		if t, desc, e := getinfo(term); e != nil {
 | 
						|
			if all && e == notaddressable {
 | 
						|
				continue
 | 
						|
			}
 | 
						|
			if !quiet {
 | 
						|
				fmt.Fprintf(os.Stderr,
 | 
						|
					"Failed loading %s: %v\n", term, e)
 | 
						|
			}
 | 
						|
			if !nofatal {
 | 
						|
				os.Exit(1)
 | 
						|
			}
 | 
						|
		} else {
 | 
						|
			tdata[term] = t
 | 
						|
			descs[term] = desc
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	if len(tdata) == 0 {
 | 
						|
		// No data.
 | 
						|
		os.Exit(0)
 | 
						|
	}
 | 
						|
 | 
						|
	if db {
 | 
						|
		dumpDatabase(tdata, descs)
 | 
						|
	} else if gofile != "" {
 | 
						|
		for term, t := range tdata {
 | 
						|
			if t.Name == term {
 | 
						|
				e = dotGoFile(gofile, t, descs[term], false)
 | 
						|
				if e != nil {
 | 
						|
					fmt.Fprintf(os.Stderr, "Failed %s: %v", gofile, e)
 | 
						|
					os.Exit(1)
 | 
						|
				}
 | 
						|
			}
 | 
						|
		}
 | 
						|
 | 
						|
	} else {
 | 
						|
		for _, t := range tdata {
 | 
						|
			if dogzip {
 | 
						|
				if e = dotGzFile(jsonfile, t, false); e != nil {
 | 
						|
					fmt.Fprintf(os.Stderr, "Failed %s: %v", gofile, e)
 | 
						|
					os.Exit(1)
 | 
						|
				}
 | 
						|
			} else {
 | 
						|
				if e = jsonFile(jsonfile, t, false); e != nil {
 | 
						|
					fmt.Fprintf(os.Stderr, "Failed %s: %v", gofile, e)
 | 
						|
					os.Exit(1)
 | 
						|
				}
 | 
						|
			}
 | 
						|
		}
 | 
						|
	}
 | 
						|
}
 |