func (h *HandlerWithErrorConfigurer) Handle(ctx context.Context, conn *Conn, req *Request) {
	result, err := h.handleFunc(ctx, conn, req)
	if req.Notif {
		if err != nil {
			log.Printf("jsonrpc2 handler: notification %q handling error: %s", req.Method, err)
		}
		return
	}

	resp := &Response{ID: req.ID}
	if err == nil {
		err = resp.SetResult(result)
	}
	if err != nil {
		if e, ok := err.(*Error); ok {
			resp.Error = e
		} else {
			resp.Error = &Error{Message: err.Error()}
		}
	}

	if !req.Notif {
		if err := conn.SendResponse(ctx, resp); err != nil {
			if err != ErrClosed || !h.suppressErrClosed {
				log.Printf("jsonrpc2 handler: sending response %s: %s", resp.ID, err)
			}
		}
	}
}

func ( h * HandlerWithErrorConfigurer ) Handle ( ctx context . Context , conn * Conn , req * Request ) { result , err := h . handleFunc ( ctx , conn , req ) if req . Notif { if err != nil { log . Printf ( " " , req . Method , err ) } return } resp := & Response { ID : req . ID } if err == nil { err = resp . SetResult ( result ) } if err != nil { if e , ok := err . ( * Error ) ; ok { resp . Error = e } else { resp . Error = & Error { Message : err . Error ( ) } } } if ! req . Notif { if err := conn . SendResponse ( ctx , resp ) ; err != nil { if err != ErrClosed || ! h . suppressErrClosed { log . Printf ( " " , resp . ID , err ) } } } }


func (t ObjectStream) ReadObject(v interface{}) error {
	err := t.conn.ReadJSON(v)
	if e, ok := err.(*websocket.CloseError); ok {
		if e.Code == websocket.CloseAbnormalClosure && e.Text == io.ErrUnexpectedEOF.Error() {
			// Suppress a noisy (but harmless) log message by
			// unwrapping this error.
			err = io.ErrUnexpectedEOF
		}
	}
	return err
}

// ReadObject implements jsonrpc2.ObjectStream.

ReadObject implements jsonrpc2 . ObjectStream .


func PickID(id ID) CallOption {
	return callOptionFunc(func(r *Request) error {
		r.ID = id
		return nil
	})
}

func PickID ( id ID ) CallOption { return callOptionFunc ( func ( r * Request ) error { r . ID = id return nil } ) }

// PickID returns a call option which sets the ID on a request. Care must be
// taken to ensure there are no conflicts with any previously picked ID, nor
// with the default sequence ID.

PickID returns a call option which sets the ID on a request . Care must be taken to ensure there are no conflicts with any previously picked ID nor with the default sequence ID .


func (me NodeAddr) String() string {
	if me.Port == 0 {
		return me.IP.String()
	}
	return net.JoinHostPort(me.IP.String(), strconv.FormatInt(int64(me.Port), 10))
}

func ( me NodeAddr ) String ( ) string { if me . Port == 0 { return me . IP . String ( ) } return net . JoinHostPort ( me . IP . String ( ) , strconv . FormatInt ( int64 ( me . Port ) , 10 ) ) }

// A zero Port is taken to mean no port provided, per BEP 7.

A zero Port is taken to mean no port provided per BEP 7 .


func crcIP(ip net.IP, rand uint8) uint32 {
	if ip4 := ip.To4(); ip4 != nil {
		ip = ip4
	}
	// Copy IP so we can make changes. Go sux at this.
	ip = append(make(net.IP, 0, len(ip)), ip...)
	mask := maskForIP(ip)
	for i := range mask {
		ip[i] &= mask[i]
	}
	r := rand & 7
	ip[0] |= r << 5
	return crc32.Checksum(ip[:len(mask)], crc32.MakeTable(crc32.Castagnoli))
}

// Generate the CRC used to make or validate secure node ID.

Generate the CRC used to make or validate secure node ID .


func (s *Server) Stats() ServerStats {
	s.mu.Lock()
	defer s.mu.Unlock()
	ss := s.stats
	ss.GoodNodes = s.numGoodNodes()
	ss.Nodes = s.numNodes()
	ss.OutstandingTransactions = len(s.transactions)
	return ss
}

func ( s * Server ) Stats ( ) ServerStats { s . mu . Lock ( ) defer s . mu . Unlock ( ) ss := s . stats ss . GoodNodes = s . numGoodNodes ( ) ss . Nodes = s . numNodes ( ) ss . OutstandingTransactions = len ( s . transactions ) return ss }

// Stats returns statistics for the server.

Stats returns statistics for the server .


func NewServer(c *ServerConfig) (s *Server, err error) {
	if c == nil {
		c = &ServerConfig{
			Conn:               mustListen(":0"),
			NoSecurity:         true,
			StartingNodes:      GlobalBootstrapAddrs,
			ConnectionTracking: conntrack.NewInstance(),
		}
	}
	if c.Conn == nil {
		return nil, errors.New("non-nil Conn required")
	}
	if missinggo.IsZeroValue(c.NodeId) {
		c.NodeId = RandomNodeID()
		if !c.NoSecurity && c.PublicIP != nil {
			SecureNodeId(&c.NodeId, c.PublicIP)
		}
	}
	s = &Server{
		config:      *c,
		ipBlockList: c.IPBlocklist,
		tokenServer: tokenServer{
			maxIntervalDelta: 2,
			interval:         5 * time.Minute,
			secret:           make([]byte, 20),
		},
		transactions: make(map[transactionKey]*Transaction),
		table: table{
			k: 8,
		},
	}
	if s.config.ConnectionTracking == nil {
		s.config.ConnectionTracking = conntrack.NewInstance()
	}
	rand.Read(s.tokenServer.secret)
	s.socket = c.Conn
	s.id = int160FromByteArray(c.NodeId)
	s.table.rootID = s.id
	go s.serveUntilClosed()
	return
}

func NewServer ( c * ServerConfig ) ( s * Server , err error ) { if c == nil { c = & ServerConfig { Conn : mustListen ( " " ) , NoSecurity : true , StartingNodes : GlobalBootstrapAddrs , ConnectionTracking : conntrack . NewInstance ( ) , } } if c . Conn == nil { return nil , errors . New ( " " ) } if missinggo . IsZeroValue ( c . NodeId ) { c . NodeId = RandomNodeID ( ) if ! c . NoSecurity && c . PublicIP != nil { SecureNodeId ( & c . NodeId , c . PublicIP ) } } s = & Server { config : * c , ipBlockList : c . IPBlocklist , tokenServer : tokenServer { maxIntervalDelta : 2 , interval : 5 * time . Minute , secret : make ( [ ] byte , 20 ) , } , transactions : make ( map [ transactionKey ] * Transaction ) , table : table { k : 8 , } , } if s . config . ConnectionTracking == nil { s . config . ConnectionTracking = conntrack . NewInstance ( ) } rand . Read ( s . tokenServer . secret ) s . socket = c . Conn s . id = int160FromByteArray ( c . NodeId ) s . table . rootID = s . id go s . serveUntilClosed ( ) return }

// NewServer initializes a new DHT node server.

NewServer initializes a new DHT node server .


func (s *Server) SetIPBlockList(list iplist.Ranger) {
	s.mu.Lock()
	defer s.mu.Unlock()
	s.ipBlockList = list
}

func ( s * Server ) SetIPBlockList ( list iplist . Ranger ) { s . mu . Lock ( ) defer s . mu . Unlock ( ) s . ipBlockList = list }

// Packets to and from any address matching a range in the list are dropped.

Packets to and from any address matching a range in the list are dropped .


func (s *Server) AddNode(ni krpc.NodeInfo) error {
	id := int160FromByteArray(ni.ID)
	if id.IsZero() {
		return s.Ping(ni.Addr.UDP(), nil)
	}
	_, err := s.getNode(NewAddr(ni.Addr.UDP()), int160FromByteArray(ni.ID), true)
	return err
}

func ( s * Server ) AddNode ( ni krpc . NodeInfo ) error { id := int160FromByteArray ( ni . ID ) if id . IsZero ( ) { return s . Ping ( ni . Addr . UDP ( ) , nil ) } _ , err := s . getNode ( NewAddr ( ni . Addr . UDP ( ) ) , int160FromByteArray ( ni . ID ) , true ) return err }


func (s *Server) getNode(addr Addr, id int160, tryAdd bool) (*node, error) {
	if n := s.table.getNode(addr, id); n != nil {
		return n, nil
	}
	n := &node{nodeKey: nodeKey{
		id:   id,
		addr: addr,
	}}
	// Check that the node would be good to begin with. (It might have a bad
	// ID or banned address, or we fucked up the initial node field
	// invariant.)
	if err := s.nodeErr(n); err != nil {
		return nil, err
	}
	if !tryAdd {
		return nil, errors.New("node not present and add flag false")
	}
	b := s.table.bucketForID(id)
	if b.Len() >= s.table.k {
		if b.EachNode(func(n *node) bool {
			if s.nodeIsBad(n) {
				s.table.dropNode(n)
			}
			return b.Len() >= s.table.k
		}) {
			return nil, errors.New("no room in bucket")
		}
	}
	if err := s.table.addNode(n); err != nil {
		panic(fmt.Sprintf("expected to add node: %s", err))
	}
	return n, nil
}

// Returns the node if it's in the routing table, adding it if appropriate.

Returns the node if it s in the routing table adding it if appropriate .


func (s *Server) Ping(node *net.UDPAddr, callback func(krpc.Msg, error)) error {
	s.mu.Lock()
	defer s.mu.Unlock()
	return s.ping(node, callback)
}

func ( s * Server ) Ping ( node * net . UDPAddr , callback func ( krpc . Msg , error ) ) error { s . mu . Lock ( ) defer s . mu . Unlock ( ) return s . ping ( node , callback ) }

// Sends a ping query to the address given.

Sends a ping query to the address given .


func (s *Server) addResponseNodes(d krpc.Msg) {
	if d.R == nil {
		return
	}
	d.R.ForAllNodes(func(ni krpc.NodeInfo) {
		s.getNode(NewAddr(ni.Addr.UDP()), int160FromByteArray(ni.ID), true)
	})
}

func ( s * Server ) addResponseNodes ( d krpc . Msg ) { if d . R == nil { return } d . R . ForAllNodes ( func ( ni krpc . NodeInfo ) { s . getNode ( NewAddr ( ni . Addr . UDP ( ) ) , int160FromByteArray ( ni . ID ) , true ) } ) }


func (s *Server) findNode(addr Addr, targetID int160, callback func(krpc.Msg, error)) (err error) {
	return s.query(addr, "find_node", &krpc.MsgArgs{
		Target: targetID.AsByteArray(),
		Want:   []krpc.Want{krpc.WantNodes, krpc.WantNodes6},
	}, func(m krpc.Msg, err error) {
		// Scrape peers from the response to put in the server's table before
		// handing the response back to the caller.
		s.mu.Lock()
		s.addResponseNodes(m)
		s.mu.Unlock()
		callback(m, err)
	})
}

// Sends a find_node query to addr. targetID is the node we're looking for.

Sends a find_node query to addr . targetID is the node we re looking for .


func (s *Server) Bootstrap() (ts TraversalStats, err error) {
	initialAddrs, err := s.traversalStartingNodes()
	if err != nil {
		return
	}
	var outstanding sync.WaitGroup
	triedAddrs := newBloomFilterForTraversal()
	var onAddr func(addr Addr)
	onAddr = func(addr Addr) {
		if triedAddrs.Test([]byte(addr.String())) {
			return
		}
		ts.NumAddrsTried++
		outstanding.Add(1)
		triedAddrs.AddString(addr.String())
		s.findNode(addr, s.id, func(m krpc.Msg, err error) {
			defer outstanding.Done()
			s.mu.Lock()
			defer s.mu.Unlock()
			if err != nil {
				return
			}
			ts.NumResponses++
			if r := m.R; r != nil {
				r.ForAllNodes(func(ni krpc.NodeInfo) {
					onAddr(NewAddr(ni.Addr.UDP()))
				})
			}
		})
	}
	s.mu.Lock()
	for _, addr := range initialAddrs {
		onAddr(NewAddr(addr.Addr.UDP()))
	}
	s.mu.Unlock()
	outstanding.Wait()
	return
}

func ( s * Server ) Bootstrap ( ) ( ts TraversalStats , err error ) { initialAddrs , err := s . traversalStartingNodes ( ) if err != nil { return } var outstanding sync . WaitGroup triedAddrs := newBloomFilterForTraversal ( ) var onAddr func ( addr Addr ) onAddr = func ( addr Addr ) { if triedAddrs . Test ( [ ] byte ( addr . String ( ) ) ) { return } ts . NumAddrsTried ++ outstanding . Add ( 1 ) triedAddrs . AddString ( addr . String ( ) ) s . findNode ( addr , s . id , func ( m krpc . Msg , err error ) { defer outstanding . Done ( ) s . mu . Lock ( ) defer s . mu . Unlock ( ) if err != nil { return } ts . NumResponses ++ if r := m . R ; r != nil { r . ForAllNodes ( func ( ni krpc . NodeInfo ) { onAddr ( NewAddr ( ni . Addr . UDP ( ) ) ) } ) } } ) } s . mu . Lock ( ) for _ , addr := range initialAddrs { onAddr ( NewAddr ( addr . Addr . UDP ( ) ) ) } s . mu . Unlock ( ) outstanding . Wait ( ) return }


func (s *Server) NumNodes() int {
	s.mu.Lock()
	defer s.mu.Unlock()
	return s.numNodes()
}

func ( s * Server ) NumNodes ( ) int { s . mu . Lock ( ) defer s . mu . Unlock ( ) return s . numNodes ( ) }

// Returns how many nodes are in the node table.

Returns how many nodes are in the node table .


func (s *Server) Nodes() (nis []krpc.NodeInfo) {
	s.mu.Lock()
	defer s.mu.Unlock()
	s.table.forNodes(func(n *node) bool {
		nis = append(nis, krpc.NodeInfo{
			Addr: n.addr.KRPC(),
			ID:   n.id.AsByteArray(),
		})
		return true
	})
	return
}

func ( s * Server ) Nodes ( ) ( nis [ ] krpc . NodeInfo ) { s . mu . Lock ( ) defer s . mu . Unlock ( ) s . table . forNodes ( func ( n * node ) bool { nis = append ( nis , krpc . NodeInfo { Addr : n . addr . KRPC ( ) , ID : n . id . AsByteArray ( ) , } ) return true } ) return }


func (s *Server) Close() {
	s.mu.Lock()
	defer s.mu.Unlock()
	s.closed.Set()
	s.socket.Close()
}

func ( s * Server ) Close ( ) { s . mu . Lock ( ) defer s . mu . Unlock ( ) s . closed . Set ( ) s . socket . Close ( ) }

// Stops the server network activity. This is all that's required to clean-up a Server.

Stops the server network activity . This is all that s required to clean - up a Server .


func (n *node) IsGood() bool {
	if n.id.IsZero() {
		return false
	}
	if time.Since(n.lastGotResponse) < 15*time.Minute {
		return true
	}
	if !n.lastGotResponse.IsZero() && time.Since(n.lastGotQuery) < 15*time.Minute {
		return true
	}
	return false
}

func ( n * node ) IsGood ( ) bool { if n . id . IsZero ( ) { return false } if time . Since ( n . lastGotResponse ) < 15 * time . Minute { return true } if ! n . lastGotResponse . IsZero ( ) && time . Since ( n . lastGotQuery ) < 15 * time . Minute { return true } return false }


func (a *Announce) NumContacted() int {
	a.mu.Lock()
	defer a.mu.Unlock()
	return a.numContacted
}

func ( a * Announce ) NumContacted ( ) int { a . mu . Lock ( ) defer a . mu . Unlock ( ) return a . numContacted }

// Returns the number of distinct remote addresses the announce has queried.

Returns the number of distinct remote addresses the announce has queried .


func (s *Server) Announce(infoHash [20]byte, port int, impliedPort bool) (*Announce, error) {
	startAddrs, err := s.traversalStartingNodes()
	if err != nil {
		return nil, err
	}
	a := &Announce{
		Peers:               make(chan PeersValues, 100),
		values:              make(chan PeersValues),
		triedAddrs:          newBloomFilterForTraversal(),
		server:              s,
		infoHash:            int160FromByteArray(infoHash),
		announcePort:        port,
		announcePortImplied: impliedPort,
		contactRateLimiter:  make(chan struct{}, 10),
	}
	a.ctx, a.cancel = context.WithCancel(context.Background())
	a.stop = a.ctx.Done()
	a.nodesPendingContact.target = int160FromByteArray(infoHash)
	a.nodeContactorCond.L = &a.mu
	go a.rateUnlimiter()
	// Function ferries from values to Values until discovery is halted.
	go func() {
		defer close(a.Peers)
		for {
			select {
			case psv := <-a.values:
				select {
				case a.Peers <- psv:
				case <-a.stop:
					return
				}
			case <-a.stop:
				return
			}
		}
	}()
	for _, n := range startAddrs {
		a.pendContact(n)
	}
	a.maybeClose()
	go a.nodeContactor()
	return a, nil
}

// This is kind of the main thing you want to do with DHT. It traverses the
// graph toward nodes that store peers for the infohash, streaming them to the
// caller, and announcing the local node to each node if allowed and
// specified.

This is kind of the main thing you want to do with DHT . It traverses the graph toward nodes that store peers for the infohash streaming them to the caller and announcing the local node to each node if allowed and specified .


func (a *Announce) maybeAnnouncePeer(to Addr, token *string, peerId *krpc.ID) {
	if token == nil {
		return
	}
	if !a.server.config.NoSecurity && (peerId == nil || !NodeIdSecure(*peerId, to.IP())) {
		return
	}
	a.server.mu.Lock()
	defer a.server.mu.Unlock()
	a.server.announcePeer(to, a.infoHash, a.announcePort, *token, a.announcePortImplied, nil)
}

func ( a * Announce ) maybeAnnouncePeer ( to Addr , token * string , peerId * krpc . ID ) { if token == nil { return } if ! a . server . config . NoSecurity && ( peerId == nil || ! NodeIdSecure ( * peerId , to . IP ( ) ) ) { return } a . server . mu . Lock ( ) defer a . server . mu . Unlock ( ) a . server . announcePeer ( to , a . infoHash , a . announcePort , * token , a . announcePortImplied , nil ) }


func (a *Announce) Close() {
	a.mu.Lock()
	defer a.mu.Unlock()
	a.close()
}

func ( a * Announce ) Close ( ) { a . mu . Lock ( ) defer a . mu . Unlock ( ) a . close ( ) }


func NewUUID() (UUID, error) {
	nodeMu.Lock()
	if nodeID == zeroID {
		setNodeInterface("")
	}
	nodeMu.Unlock()

	var uuid UUID
	now, seq, err := GetTime()
	if err != nil {
		return uuid, err
	}

	timeLow := uint32(now & 0xffffffff)
	timeMid := uint16((now >> 32) & 0xffff)
	timeHi := uint16((now >> 48) & 0x0fff)
	timeHi |= 0x1000 // Version 1

	binary.BigEndian.PutUint32(uuid[0:], timeLow)
	binary.BigEndian.PutUint16(uuid[4:], timeMid)
	binary.BigEndian.PutUint16(uuid[6:], timeHi)
	binary.BigEndian.PutUint16(uuid[8:], seq)
	copy(uuid[10:], nodeID[:])

	return uuid, nil
}

func
NewUUID
(
)
(
UUID
,
error
)
{
nodeMu
.
Lock
(
)
if
nodeID
==
zeroID
{
setNodeInterface
(
"
"
)
}
nodeMu
.
Unlock
(
)
var
uuid
UUID
now
,
seq
,
err
:=
GetTime
(
)
if
err
!=
{
return
uuid
,
err
}
timeLow
:=
uint32
(
now
&
0xffffffff
)
timeMid
:=
uint16
(
(
now
>>
32
)
&
0xffff
)
timeHi
:=
uint16
(
(
now
>>
48
)
&
0x0fff
)
timeHi
|=
0x1000
// Version 1
binary
.
BigEndian
.
PutUint32
(
uuid
[
0
:
]
,
timeLow
)
binary
.
BigEndian
.
PutUint16
(
uuid
[
4
:
]
,
timeMid
)
binary
.
BigEndian
.
PutUint16
(
uuid
[
6
:
]
,
timeHi
)
binary
.
BigEndian
.
PutUint16
(
uuid
[
8
:
]
,
seq
)
copy
(
uuid
[
10
:
]
,
nodeID
[
:
]
)
return
uuid
,
}

// NewUUID returns a Version 1 UUID based on the current NodeID and clock
// sequence, and the current time.  If the NodeID has not been set by SetNodeID
// or SetNodeInterface then it will be set automatically.  If the NodeID cannot
// be set NewUUID returns nil.  If clock sequence has not been set by
// SetClockSequence then it will be set automatically.  If GetTime fails to
// return the current NewUUID returns nil and an error.
//
// In most cases, New should be used.

NewUUID returns a Version 1 UUID based on the current NodeID and clock sequence and the current time . If the NodeID has not been set by SetNodeID or SetNodeInterface then it will be set automatically . If the NodeID cannot be set NewUUID returns nil . If clock sequence has not been set by SetClockSequence then it will be set automatically . If GetTime fails to return the current NewUUID returns nil and an error . In most cases New should be used .


func SetNodeInterface(name string) bool {
	defer nodeMu.Unlock()
	nodeMu.Lock()
	return setNodeInterface(name)
}

func SetNodeInterface ( name string ) bool { defer nodeMu . Unlock ( ) nodeMu . Lock ( ) return setNodeInterface ( name ) }

// SetNodeInterface selects the hardware address to be used for Version 1 UUIDs.
// If name is "" then the first usable interface found will be used or a random
// Node ID will be generated.  If a named interface cannot be found then false
// is returned.
//
// SetNodeInterface never fails when name is "".

SetNodeInterface selects the hardware address to be used for Version 1 UUIDs . If name is then the first usable interface found will be used or a random Node ID will be generated . If a named interface cannot be found then false is returned . SetNodeInterface never fails when name is .


func NodeID() []byte {
	defer nodeMu.Unlock()
	nodeMu.Lock()
	if nodeID == zeroID {
		setNodeInterface("")
	}
	nid := nodeID
	return nid[:]
}

func NodeID ( ) [ ] byte { defer nodeMu . Unlock ( ) nodeMu . Lock ( ) if nodeID == zeroID { setNodeInterface ( " " ) } nid := nodeID return nid [ : ] }

// NodeID returns a slice of a copy of the current Node ID, setting the Node ID
// if not already set.

NodeID returns a slice of a copy of the current Node ID setting the Node ID if not already set .


func SetNodeID(id []byte) bool {
	if len(id) < 6 {
		return false
	}
	defer nodeMu.Unlock()
	nodeMu.Lock()
	copy(nodeID[:], id)
	ifname = "user"
	return true
}

func SetNodeID ( id [ ] byte ) bool { if len ( id ) < 6 { return false } defer nodeMu . Unlock ( ) nodeMu . Lock ( ) copy ( nodeID [ : ] , id ) ifname = " " return true }

// SetNodeID sets the Node ID to be used for Version 1 UUIDs.  The first 6 bytes
// of id are used.  If id is less than 6 bytes then false is returned and the
// Node ID is not set.

SetNodeID sets the Node ID to be used for Version 1 UUIDs . The first 6 bytes of id are used . If id is less than 6 bytes then false is returned and the Node ID is not set .


func (uuid UUID) NodeID() []byte {
	var node [6]byte
	copy(node[:], uuid[10:])
	return node[:]
}

func ( uuid UUID ) NodeID ( ) [ ] byte { var node [ 6 ] byte copy ( node [ : ] , uuid [ 10 : ] ) return node [ : ] }

// NodeID returns the 6 byte node id encoded in uuid.  It returns nil if uuid is
// not valid.  The NodeID is only well defined for version 1 and 2 UUIDs.

NodeID returns the 6 byte node id encoded in uuid . It returns nil if uuid is not valid . The NodeID is only well defined for version 1 and 2 UUIDs .


func ParseBytes(b []byte) (UUID, error) {
	var uuid UUID
	switch len(b) {
	case 36: // xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
	case 36 + 9: // urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
		if !bytes.Equal(bytes.ToLower(b[:9]), []byte("urn:uuid:")) {
			return uuid, fmt.Errorf("invalid urn prefix: %q", b[:9])
		}
		b = b[9:]
	case 36 + 2: // {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}
		b = b[1:]
	case 32: // xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
		var ok bool
		for i := 0; i < 32; i += 2 {
			uuid[i/2], ok = xtob(b[i], b[i+1])
			if !ok {
				return uuid, errors.New("invalid UUID format")
			}
		}
		return uuid, nil
	default:
		return uuid, fmt.Errorf("invalid UUID length: %d", len(b))
	}
	// s is now at least 36 bytes long
	// it must be of the form  xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
	if b[8] != '-' || b[13] != '-' || b[18] != '-' || b[23] != '-' {
		return uuid, errors.New("invalid UUID format")
	}
	for i, x := range [16]int{
		0, 2, 4, 6,
		9, 11,
		14, 16,
		19, 21,
		24, 26, 28, 30, 32, 34} {
		v, ok := xtob(b[x], b[x+1])
		if !ok {
			return uuid, errors.New("invalid UUID format")
		}
		uuid[i] = v
	}
	return uuid, nil
}

// ParseBytes is like Parse, except it parses a byte slice instead of a string.

ParseBytes is like Parse except it parses a byte slice instead of a string .


func MustParse(s string) UUID {
	uuid, err := Parse(s)
	if err != nil {
		panic(`uuid: Parse(` + s + `): ` + err.Error())
	}
	return uuid
}

func
MustParse
(
s
string
)
UUID
{
uuid
,
err
:=
Parse
(
s
)
if
err
!=
{
panic
(
`uuid: Parse(`
+
s
+
`): `
+
err
.
Error
(
)
)
}
return
uuid
}

// MustParse is like Parse but panics if the string cannot be parsed.
// It simplifies safe initialization of global variables holding compiled UUIDs.

MustParse is like Parse but panics if the string cannot be parsed . It simplifies safe initialization of global variables holding compiled UUIDs .


func FromBytes(b []byte) (uuid UUID, err error) {
	err = uuid.UnmarshalBinary(b)
	return uuid, err
}

func FromBytes ( b [ ] byte ) ( uuid UUID , err error ) { err = uuid . UnmarshalBinary ( b ) return uuid , err }

// FromBytes creates a new UUID from a byte slice. Returns an error if the slice
// does not have a length of 16. The bytes are copied from the slice.

FromBytes creates a new UUID from a byte slice . Returns an error if the slice does not have a length of 16 . The bytes are copied from the slice .


func Must(uuid UUID, err error) UUID {
	if err != nil {
		panic(err)
	}
	return uuid
}

func Must ( uuid UUID , err error ) UUID { if err != nil { panic ( err ) } return uuid }

// Must returns uuid if err is nil and panics otherwise.

Must returns uuid if err is nil and panics otherwise .


func (uuid UUID) Variant() Variant {
	switch {
	case (uuid[8] & 0xc0) == 0x80:
		return RFC4122
	case (uuid[8] & 0xe0) == 0xc0:
		return Microsoft
	case (uuid[8] & 0xe0) == 0xe0:
		return Future
	default:
		return Reserved
	}
}

func ( uuid UUID ) Variant ( ) Variant { switch { case ( uuid [ 8 ] & 0xc0 ) == 0x80 : return RFC4122 case ( uuid [ 8 ] & 0xe0 ) == 0xc0 : return Microsoft case ( uuid [ 8 ] & 0xe0 ) == 0xe0 : return Future default : return Reserved } }

// Variant returns the variant encoded in uuid.

Variant returns the variant encoded in uuid .


func (uuid UUID) Time() Time {
	time := int64(binary.BigEndian.Uint32(uuid[0:4]))
	time |= int64(binary.BigEndian.Uint16(uuid[4:6])) << 32
	time |= int64(binary.BigEndian.Uint16(uuid[6:8])&0xfff) << 48
	return Time(time)
}

func ( uuid UUID ) Time ( ) Time { time := int64 ( binary . BigEndian . Uint32 ( uuid [ 0 : 4 ] ) ) time |= int64 ( binary . BigEndian . Uint16 ( uuid [ 4 : 6 ] ) ) << 32 time |= int64 ( binary . BigEndian . Uint16 ( uuid [ 6 : 8 ] ) & 0xfff ) << 48 return Time ( time ) }

// Time returns the time in 100s of nanoseconds since 15 Oct 1582 encoded in
// uuid.  The time is only defined for version 1 and 2 UUIDs.

Time returns the time in 100s of nanoseconds since 15 Oct 1582 encoded in uuid . The time is only defined for version 1 and 2 UUIDs .


func (uuid UUID) MarshalText() ([]byte, error) {
	var js [36]byte
	encodeHex(js[:], uuid)
	return js[:], nil
}

func ( uuid UUID ) MarshalText ( ) ( [ ] byte , error ) { var js [ 36 ] byte encodeHex ( js [ : ] , uuid ) return js [ : ] , nil }

// MarshalText implements encoding.TextMarshaler.

MarshalText implements encoding . TextMarshaler .


func (uuid *UUID) UnmarshalText(data []byte) error {
	id, err := ParseBytes(data)
	if err == nil {
		*uuid = id
	}
	return err
}

func ( uuid * UUID ) UnmarshalText ( data [ ] byte ) error { id , err := ParseBytes ( data ) if err == nil { * uuid = id } return err }

// UnmarshalText implements encoding.TextUnmarshaler.

UnmarshalText implements encoding . TextUnmarshaler .


func (uuid *UUID) UnmarshalBinary(data []byte) error {
	if len(data) != 16 {
		return fmt.Errorf("invalid UUID (got %d bytes)", len(data))
	}
	copy(uuid[:], data)
	return nil
}

func ( uuid * UUID ) UnmarshalBinary ( data [ ] byte ) error { if len ( data ) != 16 { return fmt . Errorf ( " " , len ( data ) ) } copy ( uuid [ : ] , data ) return nil }

// UnmarshalBinary implements encoding.BinaryUnmarshaler.

UnmarshalBinary implements encoding . BinaryUnmarshaler .


func (s *Select) RunCursorAt(cursorPos, scroll int) (int, string, error) {
	if s.Size == 0 {
		s.Size = 5
	}

	l, err := list.New(s.Items, s.Size)
	if err != nil {
		return 0, "", err
	}
	l.Searcher = s.Searcher

	s.list = l

	s.setKeys()

	err = s.prepareTemplates()
	if err != nil {
		return 0, "", err
	}
	return s.innerRun(cursorPos, scroll, ' ')
}

func
(
s
*
Select
)
RunCursorAt
(
cursorPos
,
scroll
int
)
(
int
,
string
,
error
)
{
if
s
.
Size
==
0
{
s
.
Size
=
5
}
l
,
err
:=
list
.
New
(
s
.
Items
,
s
.
Size
)
if
err
!=
{
return
0
,
"
"
,
err
}
l
.
Searcher
=
s
.
Searcher
s
.
list
=
l
s
.
setKeys
(
)
err
=
s
.
prepareTemplates
(
)
if
err
!=
{
return
0
,
"
"
,
err
}
return
s
.
innerRun
(
cursorPos
,
scroll
,
' '
)
}

// RunCursorAt executes the select list, initializing the cursor to the given
// position. Invalid cursor positions will be clamped to valid values.  It
// displays the label and the list of items, asking the user to chose any value
// within to list. Run will keep the prompt alive until it has been canceled
// from the command prompt or it has received a valid value. It will return
// the value and an error if any occurred during the select's execution.

RunCursorAt executes the select list initializing the cursor to the given position . Invalid cursor positions will be clamped to valid values . It displays the label and the list of items asking the user to chose any value within to list . Run will keep the prompt alive until it has been canceled from the command prompt or it has received a valid value . It will return the value and an error if any occurred during the select s execution .


func (sa *SelectWithAdd) Run() (int, string, error) {
	if len(sa.Items) > 0 {
		newItems := append([]string{sa.AddLabel}, sa.Items...)

		list, err := list.New(newItems, 5)
		if err != nil {
			return 0, "", err
		}

		s := Select{
			Label:     sa.Label,
			Items:     newItems,
			IsVimMode: sa.IsVimMode,
			HideHelp:  sa.HideHelp,
			Size:      5,
			list:      list,
			Pointer:   sa.Pointer,
		}
		s.setKeys()

		err = s.prepareTemplates()
		if err != nil {
			return 0, "", err
		}

		selected, value, err := s.innerRun(1, 0, '+')
		if err != nil || selected != 0 {
			return selected - 1, value, err
		}

		// XXX run through terminal for windows
		os.Stdout.Write([]byte(upLine(1) + "\r" + clearLine))
	}

	p := Prompt{
		Label:     sa.AddLabel,
		Validate:  sa.Validate,
		IsVimMode: sa.IsVimMode,
		Pointer:   sa.Pointer,
	}
	value, err := p.Run()
	return SelectedAdd, value, err
}

func
(
sa
*
SelectWithAdd
)
Run
(
)
(
int
,
string
,
error
)
{
if
len
(
sa
.
Items
)
>
0
{
newItems
:=
append
(
[
]
string
{
sa
.
AddLabel
}
,
sa
.
Items
...
)
list
,
err
:=
list
.
New
(
newItems
,
5
)
if
err
!=
{
return
0
,
"
"
,
err
}
s
:=
Select
{
Label
:
sa
.
Label
,
Items
:
newItems
,
IsVimMode
:
sa
.
IsVimMode
,
HideHelp
:
sa
.
HideHelp
,
Size
:
5
,
list
:
list
,
Pointer
:
sa
.
Pointer
,
}
s
.
setKeys
(
)
err
=
s
.
prepareTemplates
(
)
if
err
!=
{
return
0
,
"
"
,
err
}
selected
,
value
,
err
:=
s
.
innerRun
(
1
,
0
,
'+'
)
if
err
!=
||
selected
!=
0
{
return
selected
1
,
value
,
err
}
// XXX run through terminal for windows
os
.
Stdout
.
Write
(
[
]
byte
(
upLine
(
1
)
+
"
\r
"
+
clearLine
)
)
}
p
:=
Prompt
{
Label
:
sa
.
AddLabel
,
Validate
:
sa
.
Validate
,
IsVimMode
:
sa
.
IsVimMode
,
Pointer
:
sa
.
Pointer
,
}
value
,
err
:=
p
.
Run
(
)
return
SelectedAdd
,
value
,
err
}

// Run executes the select list. Its displays the label and the list of items, asking the user to chose any
// value within to list or add his own. Run will keep the prompt alive until it has been canceled from
// the command prompt or it has received a valid value.
//
// If the addLabel is selected in the list, this function will return a -1 index with the added label and no error.
// Otherwise, it will return the index and the value of the selected item. In any case, if an error is triggered, it
// will also return the error as its third return value.

Run executes the select list . Its displays the label and the list of items asking the user to chose any value within to list or add his own . Run will keep the prompt alive until it has been canceled from the command prompt or it has received a valid value . If the addLabel is selected in the list this function will return a - 1 index with the added label and no error . Otherwise it will return the index and the value of the selected item . In any case if an error is triggered it will also return the error as its third return value .


func New(w io.Writer) *ScreenBuf {
	return &ScreenBuf{buf: &bytes.Buffer{}, w: w}
}

func New ( w io . Writer ) * ScreenBuf { return & ScreenBuf { buf : & bytes . Buffer { } , w : w } }

// New creates and initializes a new ScreenBuf.

New creates and initializes a new ScreenBuf .


func (s *ScreenBuf) Clear() error {
	for i := 0; i < s.height; i++ {
		_, err := s.buf.Write(moveUp)
		if err != nil {
			return err
		}
		_, err = s.buf.Write(clearLine)
		if err != nil {
			return err
		}
	}
	s.cursor = 0
	s.height = 0
	s.reset = false
	return nil
}

func ( s * ScreenBuf ) Clear ( ) error { for i := 0 ; i < s . height ; i ++ { _ , err := s . buf . Write ( moveUp ) if err != nil { return err } _ , err = s . buf . Write ( clearLine ) if err != nil { return err } } s . cursor = 0 s . height = 0 s . reset = false return nil }

// Clear clears all previous lines and the output starts from the top.

Clear clears all previous lines and the output starts from the top .


func (s *ScreenBuf) Write(b []byte) (int, error) {
	if bytes.ContainsAny(b, "\r\n") {
		return 0, fmt.Errorf("%q should not contain either \\r or \\n", b)
	}

	if s.reset {
		if err := s.Clear(); err != nil {
			return 0, err
		}
	}

	switch {
	case s.cursor == s.height:
		n, err := s.buf.Write(clearLine)
		if err != nil {
			return n, err
		}
		line := append(b, []byte("\n")...)
		n, err = s.buf.Write(line)
		if err != nil {
			return n, err
		}
		s.height++
		s.cursor++
		return n, nil
	case s.cursor < s.height:
		n, err := s.buf.Write(clearLine)
		if err != nil {
			return n, err
		}
		n, err = s.buf.Write(b)
		if err != nil {
			return n, err
		}
		n, err = s.buf.Write(moveDown)
		if err != nil {
			return n, err
		}
		s.cursor++
		return n, nil
	default:
		return 0, fmt.Errorf("Invalid write cursor position (%d) exceeded line height: %d", s.cursor, s.height)
	}
}

func ( s * ScreenBuf ) Write ( b [ ] byte ) ( int , error ) { if bytes . ContainsAny ( b , " \r \n " ) { return 0 , fmt . Errorf ( " \\ \\ " , b ) } if s . reset { if err := s . Clear ( ) ; err != nil { return 0 , err } } switch { case s . cursor == s . height : n , err := s . buf . Write ( clearLine ) if err != nil { return n , err } line := append ( b , [ ] byte ( " \n " ) ... ) n , err = s . buf . Write ( line ) if err != nil { return n , err } s . height ++ s . cursor ++ return n , nil case s . cursor < s . height : n , err := s . buf . Write ( clearLine ) if err != nil { return n , err } n , err = s . buf . Write ( b ) if err != nil { return n , err } n , err = s . buf . Write ( moveDown ) if err != nil { return n , err } s . cursor ++ return n , nil default : return 0 , fmt . Errorf ( " " , s . cursor , s . height ) } }

// Write writes a single line to the underlining buffer. If the ScreenBuf was
// previously reset, all previous lines are cleared and the output starts from
// the top. Lines with \r or \n will cause an error since they can interfere with the
// terminal ability to move between lines.

Write writes a single line to the underlining buffer . If the ScreenBuf was previously reset all previous lines are cleared and the output starts from the top . Lines with \ r or \ n will cause an error since they can interfere with the terminal ability to move between lines .


func (s *ScreenBuf) Flush() error {
	for i := s.cursor; i < s.height; i++ {
		if i < s.height {
			_, err := s.buf.Write(clearLine)
			if err != nil {
				return err
			}
		}
		_, err := s.buf.Write(moveDown)
		if err != nil {
			return err
		}
	}

	_, err := s.buf.WriteTo(s.w)
	if err != nil {
		return err
	}

	s.buf.Reset()

	for i := 0; i < s.height; i++ {
		_, err := s.buf.Write(moveUp)
		if err != nil {
			return err
		}
	}

	s.cursor = 0

	return nil
}

func ( s * ScreenBuf ) Flush ( ) error { for i := s . cursor ; i < s . height ; i ++ { if i < s . height { _ , err := s . buf . Write ( clearLine ) if err != nil { return err } } _ , err := s . buf . Write ( moveDown ) if err != nil { return err } } _ , err := s . buf . WriteTo ( s . w ) if err != nil { return err } s . buf . Reset ( ) for i := 0 ; i < s . height ; i ++ { _ , err := s . buf . Write ( moveUp ) if err != nil { return err } } s . cursor = 0 return nil }

// Flush writes any buffered data to the underlying io.Writer, ensuring that any pending data is displayed.

Flush writes any buffered data to the underlying io . Writer ensuring that any pending data is displayed .


func Styler(attrs ...attribute) func(interface{}) string {
	attrstrs := make([]string, len(attrs))
	for i, v := range attrs {
		attrstrs[i] = strconv.Itoa(int(v))
	}

	seq := strings.Join(attrstrs, ";")

	return func(v interface{}) string {
		end := ""
		s, ok := v.(string)
		if !ok || !strings.HasSuffix(s, ResetCode) {
			end = ResetCode
		}
		return fmt.Sprintf("%s%sm%v%s", esc, seq, v, end)
	}
}

func Styler ( attrs ... attribute ) func ( interface { } ) string { attrstrs := make ( [ ] string , len ( attrs ) ) for i , v := range attrs { attrstrs [ i ] = strconv . Itoa ( int ( v ) ) } seq := strings . Join ( attrstrs , " " ) return func ( v interface { } ) string { end := " " s , ok := v . ( string ) if ! ok || ! strings . HasSuffix ( s , ResetCode ) { end = ResetCode } return fmt . Sprintf ( " " , esc , seq , v , end ) } }

// Styler is a function that accepts multiple possible styling transforms from the state,
// color and background colors constants and transforms them into a templated string
// to apply those styles in the CLI.
//
// The returned styling function accepts a string that will be extended with
// the wrapping function's styling attributes.

Styler is a function that accepts multiple possible styling transforms from the state color and background colors constants and transforms them into a templated string to apply those styles in the CLI . The returned styling function accepts a string that will be extended with the wrapping function s styling attributes .


func New(items interface{}, size int) (*List, error) {
	if size < 1 {
		return nil, fmt.Errorf("list size %d must be greater than 0", size)
	}

	if items == nil || reflect.TypeOf(items).Kind() != reflect.Slice {
		return nil, fmt.Errorf("items %v is not a slice", items)
	}

	slice := reflect.ValueOf(items)
	values := make([]*interface{}, slice.Len())

	for i := range values {
		item := slice.Index(i).Interface()
		values[i] = &item
	}

	return &List{size: size, items: values, scope: values}, nil
}

func New ( items interface { } , size int ) ( * List , error ) { if size < 1 { return nil , fmt . Errorf ( " " , size ) } if items == nil || reflect . TypeOf ( items ) . Kind ( ) != reflect . Slice { return nil , fmt . Errorf ( " " , items ) } slice := reflect . ValueOf ( items ) values := make ( [ ] * interface { } , slice . Len ( ) ) for i := range values { item := slice . Index ( i ) . Interface ( ) values [ i ] = & item } return & List { size : size , items : values , scope : values } , nil }

// New creates and initializes a list of searchable items. The items attribute must be a slice type with a
// size greater than 0. Error will be returned if those two conditions are not met.

New creates and initializes a list of searchable items . The items attribute must be a slice type with a size greater than 0 . Error will be returned if those two conditions are not met .


func (l *List) Prev() {
	if l.cursor > 0 {
		l.cursor--
	}

	if l.start > l.cursor {
		l.start = l.cursor
	}
}

func ( l * List ) Prev ( ) { if l . cursor > 0 { l . cursor -- } if l . start > l . cursor { l . start = l . cursor } }

// Prev moves the visible list back one item. If the selected item is out of
// view, the new select item becomes the last visible item. If the list is
// already at the top, nothing happens.

Prev moves the visible list back one item . If the selected item is out of view the new select item becomes the last visible item . If the list is already at the top nothing happens .


func (l *List) Search(term string) {
	term = strings.Trim(term, " ")
	l.cursor = 0
	l.start = 0
	l.search(term)
}

func ( l * List ) Search ( term string ) { term = strings . Trim ( term , " " ) l . cursor = 0 l . start = 0 l . search ( term ) }

// Search allows the list to be filtered by a given term. The list must
// implement the searcher function signature for this functionality to work.

Search allows the list to be filtered by a given term . The list must implement the searcher function signature for this functionality to work .


func (l *List) CancelSearch() {
	l.cursor = 0
	l.start = 0
	l.scope = l.items
}

func ( l * List ) CancelSearch ( ) { l . cursor = 0 l . start = 0 l . scope = l . items }

// CancelSearch stops the current search and returns the list to its
// original order.

CancelSearch stops the current search and returns the list to its original order .


func (l *List) SetStart(i int) {
	if i < 0 {
		i = 0
	}
	if i > l.cursor {
		l.start = l.cursor
	} else {
		l.start = i
	}
}

func ( l * List ) SetStart ( i int ) { if i < 0 { i = 0 } if i > l . cursor { l . start = l . cursor } else { l . start = i } }

// SetStart sets the current scroll position. Values out of bounds will be
// clamped.

SetStart sets the current scroll position . Values out of bounds will be clamped .


func (l *List) SetCursor(i int) {
	max := len(l.scope) - 1
	if i >= max {
		i = max
	}
	if i < 0 {
		i = 0
	}
	l.cursor = i

	if l.start > l.cursor {
		l.start = l.cursor
	} else if l.start+l.size <= l.cursor {
		l.start = l.cursor - l.size + 1
	}
}

func ( l * List ) SetCursor ( i int ) { max := len ( l . scope ) - 1 if i >= max { i = max } if i < 0 { i = 0 } l . cursor = i if l . start > l . cursor { l . start = l . cursor } else if l . start + l . size <= l . cursor { l . start = l . cursor - l . size + 1 } }

// SetCursor sets the position of the cursor in the list. Values out of bounds
// will be clamped.

SetCursor sets the position of the cursor in the list . Values out of bounds will be clamped .


func (l *List) Next() {
	max := len(l.scope) - 1

	if l.cursor < max {
		l.cursor++
	}

	if l.start+l.size <= l.cursor {
		l.start = l.cursor - l.size + 1
	}
}

func ( l * List ) Next ( ) { max := len ( l . scope ) - 1 if l . cursor < max { l . cursor ++ } if l . start + l . size <= l . cursor { l . start = l . cursor - l . size + 1 } }

// Next moves the visible list forward one item. If the selected item is out of
// view, the new select item becomes the first visible item. If the list is
// already at the bottom, nothing happens.

Next moves the visible list forward one item . If the selected item is out of view the new select item becomes the first visible item . If the list is already at the bottom nothing happens .


func (l *List) PageUp() {
	start := l.start - l.size
	if start < 0 {
		l.start = 0
	} else {
		l.start = start
	}

	cursor := l.start

	if cursor < l.cursor {
		l.cursor = cursor
	}
}

func ( l * List ) PageUp ( ) { start := l . start - l . size if start < 0 { l . start = 0 } else { l . start = start } cursor := l . start if cursor < l . cursor { l . cursor = cursor } }

// PageUp moves the visible list backward by x items. Where x is the size of the
// visible items on the list. The selected item becomes the first visible item.
// If the list is already at the bottom, the selected item becomes the last
// visible item.

PageUp moves the visible list backward by x items . Where x is the size of the visible items on the list . The selected item becomes the first visible item . If the list is already at the bottom the selected item becomes the last visible item .


func (l *List) PageDown() {
	start := l.start + l.size
	max := len(l.scope) - l.size

	switch {
	case len(l.scope) < l.size:
		l.start = 0
	case start > max:
		l.start = max
	default:
		l.start = start
	}

	cursor := l.start

	if cursor == l.cursor {
		l.cursor = len(l.scope) - 1
	} else if cursor > l.cursor {
		l.cursor = cursor
	}
}

func ( l * List ) PageDown ( ) { start := l . start + l . size max := len ( l . scope ) - l . size switch { case len ( l . scope ) < l . size : l . start = 0 case start > max : l . start = max default : l . start = start } cursor := l . start if cursor == l . cursor { l . cursor = len ( l . scope ) - 1 } else if cursor > l . cursor { l . cursor = cursor } }

// PageDown moves the visible list forward by x items. Where x is the size of
// the visible items on the list. The selected item becomes the first visible
// item.

PageDown moves the visible list forward by x items . Where x is the size of the visible items on the list . The selected item becomes the first visible item .


func (l *List) Items() ([]interface{}, int) {
	var result []interface{}
	max := len(l.scope)
	end := l.start + l.size

	if end > max {
		end = max
	}

	active := NotFound

	for i, j := l.start, 0; i < end; i, j = i+1, j+1 {
		if l.cursor == i {
			active = j
		}

		result = append(result, *l.scope[i])
	}

	return result, active
}

func ( l * List ) Items ( ) ( [ ] interface { } , int ) { var result [ ] interface { } max := len ( l . scope ) end := l . start + l . size if end > max { end = max } active := NotFound for i , j := l . start , 0 ; i < end ; i , j = i + 1 , j + 1 { if l . cursor == i { active = j } result = append ( result , * l . scope [ i ] ) } return result , active }

// Items returns a slice equal to the size of the list with the current visible
// items and the index of the active item in this list.

Items returns a slice equal to the size of the list with the current visible items and the index of the active item in this list .


func NewCursor(startinginput string, pointer Pointer, eraseDefault bool) Cursor {
	if pointer == nil {
		pointer = defaultCursor
	}
	cur := Cursor{Cursor: pointer, Position: len(startinginput), input: []rune(startinginput), erase: eraseDefault}
	if eraseDefault {
		cur.Start()
	} else {
		cur.End()
	}
	return cur
}

func NewCursor ( startinginput string , pointer Pointer , eraseDefault bool ) Cursor { if pointer == nil { pointer = defaultCursor } cur := Cursor { Cursor : pointer , Position : len ( startinginput ) , input : [ ] rune ( startinginput ) , erase : eraseDefault } if eraseDefault { cur . Start ( ) } else { cur . End ( ) } return cur }

// NewCursor create a new cursor, with the DefaultCursor, the specified input,
// and position at the end of the specified starting input.

NewCursor create a new cursor with the DefaultCursor the specified input and position at the end of the specified starting input .


func (c *Cursor) correctPosition() {
	if c.Position > len(c.input) {
		c.Position = len(c.input)
	}

	if c.Position < 0 {
		c.Position = 0
	}
}

func ( c * Cursor ) correctPosition ( ) { if c . Position > len ( c . input ) { c . Position = len ( c . input ) } if c . Position < 0 { c . Position = 0 } }


func format(a []rune, c *Cursor) string {
	i := c.Position
	var b []rune

	out := make([]rune, 0)
	if i < len(a) {
		b = c.Cursor([]rune(a[i : i+1]))
		out = append(out, a[:i]...)   // does not include i
		out = append(out, b...)       // add the cursor
		out = append(out, a[i+1:]...) // add the rest after i
	} else {
		b = c.Cursor([]rune{})
		out = append(out, a...)
		out = append(out, b...)
	}
	return string(out)
}

func
format
(
a
[
]
rune
,
c
*
Cursor
)
string
{
i
:=
c
.
Position
var
b
[
]
rune
out
:=
make
(
[
]
rune
,
0
)
if
i
<
len
(
a
)
{
b
=
c
.
Cursor
(
[
]
rune
(
a
[
i
:
i
+
1
]
)
)
out
=
append
(
out
,
a
[
:
i
]
...
)
// does not include i
out
=
append
(
out
,
b
...
)
// add the cursor
out
=
append
(
out
,
a
[
i
+
1
:
]
...
)
// add the rest after i
}
else
{
b
=
c
.
Cursor
(
[
]
rune
{
}
)
out
=
append
(
out
,
a
...
)
out
=
append
(
out
,
b
...
)
}
return
string
(
out
)
}

// insert the cursor rune array into r before the provided index


func (c *Cursor) Format() string {
	r := c.input
	// insert the cursor
	return format(r, c)
}

func
(
c
*
Cursor
)
Format
(
)
string
{
r
:=
c
.
input
// insert the cursor
return
format
(
r
,
c
)
}

// Format renders the input with the Cursor appropriately positioned.

Format renders the input with the Cursor appropriately positioned .


func (c *Cursor) FormatMask(mask rune) string {
	r := make([]rune, len(c.input))
	for i := range r {
		r[i] = mask
	}
	return format(r, c)
}

func ( c * Cursor ) FormatMask ( mask rune ) string { r := make ( [ ] rune , len ( c . input ) ) for i := range r { r [ i ] = mask } return format ( r , c ) }

// FormatMask replaces all input runes with the mask rune.

FormatMask replaces all input runes with the mask rune .


func (c *Cursor) Replace(input string) {
	c.input = []rune(input)
	c.End()
}

func ( c * Cursor ) Replace ( input string ) { c . input = [ ] rune ( input ) c . End ( ) }

// Replace replaces the previous input with whatever is specified, and moves the
// cursor to the end position

Replace replaces the previous input with whatever is specified and moves the cursor to the end position


func (c *Cursor) Place(position int) {
	c.Position = position
	c.correctPosition()
}

func ( c * Cursor ) Place ( position int ) { c . Position = position c . correctPosition ( ) }

// Place moves the cursor to the absolute array index specified by position


func (c *Cursor) Move(shift int) {
	// delete the current cursor
	c.Position = c.Position + shift
	c.correctPosition()
}

func
(
c
*
Cursor
)
Move
(
shift
int
)
{
// delete the current cursor
c
.
Position
=
c
.
Position
+
shift
c
.
correctPosition
(
)
}

// Move moves the cursor over in relative terms, by shift indices.

Move moves the cursor over in relative terms by shift indices .


func (c *Cursor) Backspace() {
	a := c.input
	i := c.Position
	if i == 0 {
		// Shrug
		return
	}
	if i == len(a) {
		c.input = a[:i-1]
	} else {
		c.input = append(a[:i-1], a[i:]...)
	}
	// now it's pointing to the i+1th element
	c.Move(-1)
}

// Backspace removes the rune that precedes the cursor
//
// It handles being at the beginning or end of the row, and moves the cursor to
// the appropriate position.

Backspace removes the rune that precedes the cursor It handles being at the beginning or end of the row and moves the cursor to the appropriate position .


func (c *Cursor) Listen(line []rune, pos int, key rune) ([]rune, int, bool) {
	if line != nil {
		// no matter what, update our internal representation.
		c.Update(string(line))
	}

	switch key {
	case 0: // empty
	case KeyEnter:
		return []rune(c.Get()), c.Position, false
	case KeyBackspace:
		if c.erase {
			c.erase = false
			c.Replace("")
		}
		c.Backspace()
	case KeyForward:
		// the user wants to edit the default, despite how we set it up. Let
		// them.
		c.erase = false
		c.Move(1)
	case KeyBackward:
		c.Move(-1)
	default:
		if c.erase {
			c.erase = false
			c.Replace("")
			c.Update(string(key))
		}
	}

	return []rune(c.Get()), c.Position, true
}

// Listen is a readline Listener that updates internal cursor state appropriately.

Listen is a readline Listener that updates internal cursor state appropriately .


func AggregateIssueChan(issues chan *Issue) chan *Issue {
	out := make(chan *Issue, 1000000)
	issueMap := make(map[issueKey]*multiIssue)
	go func() {
		for issue := range issues {
			key := issueKey{
				path:    issue.Path.String(),
				line:    issue.Line,
				col:     issue.Col,
				message: issue.Message,
			}
			if existing, ok := issueMap[key]; ok {
				existing.linterNames = append(existing.linterNames, issue.Linter)
			} else {
				issueMap[key] = &multiIssue{
					Issue:       issue,
					linterNames: []string{issue.Linter},
				}
			}
		}
		for _, multi := range issueMap {
			issue := multi.Issue
			sort.Strings(multi.linterNames)
			issue.Linter = strings.Join(multi.linterNames, ", ")
			out <- issue
		}
		close(out)
	}()
	return out
}

func AggregateIssueChan ( issues chan * Issue ) chan * Issue { out := make ( chan * Issue , 1000000 ) issueMap := make ( map [ issueKey ] * multiIssue ) go func ( ) { for issue := range issues { key := issueKey { path : issue . Path . String ( ) , line : issue . Line , col : issue . Col , message : issue . Message , } if existing , ok := issueMap [ key ] ; ok { existing . linterNames = append ( existing . linterNames , issue . Linter ) } else { issueMap [ key ] = & multiIssue { Issue : issue , linterNames : [ ] string { issue . Linter } , } } } for _ , multi := range issueMap { issue := multi . Issue sort . Strings ( multi . linterNames ) issue . Linter = strings . Join ( multi . linterNames , " " ) out <- issue } close ( out ) } ( ) return out }

// AggregateIssueChan reads issues from a channel, aggregates issues which have
// the same file, line, vol, and message, and returns aggregated issues on
// a new channel.

AggregateIssueChan reads issues from a channel aggregates issues which have the same file line vol and message and returns aggregated issues on a new channel .


func (c *CallCommon) StaticCallee() *Function {
	switch fn := c.Value.(type) {
	case *Function:
		return fn
	case *MakeClosure:
		return fn.Fn.(*Function)
	}
	return nil
}

func ( c * CallCommon ) StaticCallee ( ) * Function { switch fn := c . Value . ( type ) { case * Function : return fn case * MakeClosure : return fn . Fn . ( * Function ) } return nil }

// StaticCallee returns the callee if this is a trivially static
// "call"-mode call to a function.

StaticCallee returns the callee if this is a trivially static call - mode call to a function .


func (p *Package) Func(name string) (f *Function) {
	f, _ = p.Members[name].(*Function)
	return
}

func ( p * Package ) Func ( name string ) ( f * Function ) { f , _ = p . Members [ name ] . ( * Function ) return }

// Func returns the package-level function of the specified name,
// or nil if not found.
//

Func returns the package - level function of the specified name or nil if not found .


func (p *Package) Var(name string) (g *Global) {
	g, _ = p.Members[name].(*Global)
	return
}

func ( p * Package ) Var ( name string ) ( g * Global ) { g , _ = p . Members [ name ] . ( * Global ) return }

// Var returns the package-level variable of the specified name,
// or nil if not found.
//

Var returns the package - level variable of the specified name or nil if not found .


func (p *Package) Const(name string) (c *NamedConst) {
	c, _ = p.Members[name].(*NamedConst)
	return
}

func ( p * Package ) Const ( name string ) ( c * NamedConst ) { c , _ = p . Members [ name ] . ( * NamedConst ) return }

// Const returns the package-level constant of the specified name,
// or nil if not found.
//

Const returns the package - level constant of the specified name or nil if not found .


func (p *Package) Type(name string) (t *Type) {
	t, _ = p.Members[name].(*Type)
	return
}

func ( p * Package ) Type ( name string ) ( t * Type ) { t , _ = p . Members [ name ] . ( * Type ) return }

// Type returns the package-level type of the specified name,
// or nil if not found.
//

Type returns the package - level type of the specified name or nil if not found .


func getGoPath() string {
	path := os.Getenv("GOPATH")
	if path == "" {
		user, err := user.Current()
		kingpin.FatalIfError(err, "")
		path = filepath.Join(user.HomeDir, "go")
	}
	return path
}

func getGoPath ( ) string { path := os . Getenv ( " " ) if path == " " { user , err := user . Current ( ) kingpin . FatalIfError ( err , " " ) path = filepath . Join ( user . HomeDir , " " ) } return path }


func addPath(paths []string, path string) []string {
	for _, existingpath := range paths {
		if path == existingpath {
			return paths
		}
	}
	return append(paths, path)
}

func addPath ( paths [ ] string , path string ) [ ] string { for _ , existingpath := range paths { if path == existingpath { return paths } } return append ( paths , path ) }

// addPath appends path to paths if path does not already exist in paths. Returns
// the new paths.

addPath appends path to paths if path does not already exist in paths . Returns the new paths .


func configureEnvironmentForInstall() {
	if config.Update {
		warning(`Linters are now vendored by default, --update ignored. The original
behaviour can be re-enabled with --no-vendored-linters.

To request an update for a vendored linter file an issue at:
https://github.com/alecthomas/gometalinter/issues/new
`)
	}
	gopaths := getGoPathList()
	vendorRoot := findVendoredLinters()
	if vendorRoot == "" {
		kingpin.Fatalf("could not find vendored linters in GOPATH=%q", getGoPath())
	}
	debug("found vendored linters at %s, updating environment", vendorRoot)

	gobin := os.Getenv("GOBIN")
	if gobin == "" {
		gobin = filepath.Join(gopaths[0], "bin")
	}
	setEnv("GOBIN", gobin)

	// "go install" panics when one GOPATH element is beneath another, so set
	// GOPATH to the vendor root
	setEnv("GOPATH", vendorRoot)
	debugPrintEnv()
}

// configureEnvironmentForInstall sets GOPATH and GOBIN so that vendored linters
// can be installed

configureEnvironmentForInstall sets GOPATH and GOBIN so that vendored linters can be installed


func UnmarshalStrict(in []byte, out interface{}) (err error) {
	return unmarshal(in, out, true)
}

func UnmarshalStrict ( in [ ] byte , out interface { } ) ( err error ) { return unmarshal ( in , out , true ) }

// UnmarshalStrict is like Unmarshal except that any fields that are found
// in the data that do not have corresponding struct members, or mapping
// keys that are duplicates, will result in
// an error.

UnmarshalStrict is like Unmarshal except that any fields that are found in the data that do not have corresponding struct members or mapping keys that are duplicates will result in an error .


func (dec *Decoder) Decode(v interface{}) (err error) {
	d := newDecoder(dec.strict)
	defer handleErr(&err)
	node := dec.parser.parse()
	if node == nil {
		return io.EOF
	}
	out := reflect.ValueOf(v)
	if out.Kind() == reflect.Ptr && !out.IsNil() {
		out = out.Elem()
	}
	d.unmarshal(node, out)
	if len(d.terrors) > 0 {
		return &TypeError{d.terrors}
	}
	return nil
}

func ( dec * Decoder ) Decode ( v interface { } ) ( err error ) { d := newDecoder ( dec . strict ) defer handleErr ( & err ) node := dec . parser . parse ( ) if node == nil { return io . EOF } out := reflect . ValueOf ( v ) if out . Kind ( ) == reflect . Ptr && ! out . IsNil ( ) { out = out . Elem ( ) } d . unmarshal ( node , out ) if len ( d . terrors ) > 0 { return & TypeError { d . terrors } } return nil }

// Decode reads the next YAML-encoded value from its input
// and stores it in the value pointed to by v.
//
// See the documentation for Unmarshal for details about the
// conversion of YAML into a Go value.

Decode reads the next YAML - encoded value from its input and stores it in the value pointed to by v . See the documentation for Unmarshal for details about the conversion of YAML into a Go value .


func (e *Encoder) Close() (err error) {
	defer handleErr(&err)
	e.encoder.finish()
	return nil
}

func ( e * Encoder ) Close ( ) ( err error ) { defer handleErr ( & err ) e . encoder . finish ( ) return nil }

// Close closes the encoder by writing any remaining data.
// It does not write a stream terminating string "...".

Close closes the encoder by writing any remaining data . It does not write a stream terminating string ... .


func yaml_parser_save_simple_key(parser *yaml_parser_t) bool {
	// A simple key is required at the current position if the scanner is in
	// the block context and the current column coincides with the indentation
	// level.

	required := parser.flow_level == 0 && parser.indent == parser.mark.column

	//
	// If the current position may start a simple key, save it.
	//
	if parser.simple_key_allowed {
		simple_key := yaml_simple_key_t{
			possible:     true,
			required:     required,
			token_number: parser.tokens_parsed + (len(parser.tokens) - parser.tokens_head),
		}
		simple_key.mark = parser.mark

		if !yaml_parser_remove_simple_key(parser) {
			return false
		}
		parser.simple_keys[len(parser.simple_keys)-1] = simple_key
	}
	return true
}

// Check if a simple key may start at the current position and add it if
// needed.

Check if a simple key may start at the current position and add it if needed .


func align(x, a int64) int64 {
	y := x + a - 1
	return y - y%a
}

func align ( x , a int64 ) int64 { y := x + a - 1 return y - y % a }

// align returns the smallest y >= x such that y % a == 0.

align returns the smallest y > = x such that y % a == 0 .


func lintName(name string, initialisms map[string]bool) (should string) {
	// A large part of this function is copied from
	// github.com/golang/lint, Copyright (c) 2013 The Go Authors,
	// licensed under the BSD 3-clause license.

	// Fast path for simple cases: "_" and all lowercase.
	if name == "_" {
		return name
	}
	if strings.IndexFunc(name, func(r rune) bool { return !unicode.IsLower(r) }) == -1 {
		return name
	}

	// Split camelCase at any lower->upper transition, and split on underscores.
	// Check each word for common initialisms.
	runes := []rune(name)
	w, i := 0, 0 // index of start of word, scan
	for i+1 <= len(runes) {
		eow := false // whether we hit the end of a word
		if i+1 == len(runes) {
			eow = true
		} else if runes[i+1] == '_' && i+1 != len(runes)-1 {
			// underscore; shift the remainder forward over any run of underscores
			eow = true
			n := 1
			for i+n+1 < len(runes) && runes[i+n+1] == '_' {
				n++
			}

			// Leave at most one underscore if the underscore is between two digits
			if i+n+1 < len(runes) && unicode.IsDigit(runes[i]) && unicode.IsDigit(runes[i+n+1]) {
				n--
			}

			copy(runes[i+1:], runes[i+n+1:])
			runes = runes[:len(runes)-n]
		} else if unicode.IsLower(runes[i]) && !unicode.IsLower(runes[i+1]) {
			// lower->non-lower
			eow = true
		}
		i++
		if !eow {
			continue
		}

		// [w,i) is a word.
		word := string(runes[w:i])
		if u := strings.ToUpper(word); initialisms[u] {
			// Keep consistent case, which is lowercase only at the start.
			if w == 0 && unicode.IsLower(runes[w]) {
				u = strings.ToLower(u)
			}
			// All the common initialisms are ASCII,
			// so we can replace the bytes exactly.
			// TODO(dh): this won't be true once we allow custom initialisms
			copy(runes[w:], []rune(u))
		} else if w > 0 && strings.ToLower(word) == word {
			// already all lowercase, and not the first word, so uppercase the first character.
			runes[w] = unicode.ToUpper(runes[w])
		}
		w = i
	}
	return string(runes)
}

// lintName returns a different name if it should be different.

lintName returns a different name if it should be different .


func sanityCheck(fn *Function, reporter io.Writer) bool {
	if reporter == nil {
		reporter = os.Stderr
	}
	return (&sanity{reporter: reporter}).checkFunction(fn)
}

func sanityCheck ( fn * Function , reporter io . Writer ) bool { if reporter == nil { reporter = os . Stderr } return ( & sanity { reporter : reporter } ) . checkFunction ( fn ) }

// sanityCheck performs integrity checking of the SSA representation
// of the function fn and returns true if it was valid.  Diagnostics
// are written to reporter if non-nil, os.Stderr otherwise.  Some
// diagnostics are only warnings and do not imply a negative result.
//
// Sanity-checking is intended to facilitate the debugging of code
// transformation passes.
//

sanityCheck performs integrity checking of the SSA representation of the function fn and returns true if it was valid . Diagnostics are written to reporter if non - nil os . Stderr otherwise . Some diagnostics are only warnings and do not imply a negative result . Sanity - checking is intended to facilitate the debugging of code transformation passes .


func mustSanityCheck(fn *Function, reporter io.Writer) {
	if !sanityCheck(fn, reporter) {
		fn.WriteTo(os.Stderr)
		panic("SanityCheck failed")
	}
}

func mustSanityCheck ( fn * Function , reporter io . Writer ) { if ! sanityCheck ( fn , reporter ) { fn . WriteTo ( os . Stderr ) panic ( " " ) } }

// mustSanityCheck is like sanityCheck but panics instead of returning
// a negative result.
//

mustSanityCheck is like sanityCheck but panics instead of returning a negative result .


func findDuplicate(blocks []*BasicBlock) *BasicBlock {
	if len(blocks) < 2 {
		return nil
	}
	if blocks[0] == blocks[1] {
		return blocks[0]
	}
	// Slow path:
	m := make(map[*BasicBlock]bool)
	for _, b := range blocks {
		if m[b] {
			return b
		}
		m[b] = true
	}
	return nil
}

func
findDuplicate
(
blocks
[
]
*
BasicBlock
)
*
BasicBlock
{
if
len
(
blocks
)
<
2
{
return
}
if
blocks
[
0
]
==
blocks
[
1
]
{
return
blocks
[
0
]
}
// Slow path:
m
:=
make
(
map
[
*
BasicBlock
]
bool
)
for
_
,
b
:=
range
blocks
{
if
m
[
b
]
{
return
b
}
m
[
b
]
=
true
}
return
}

// findDuplicate returns an arbitrary basic block that appeared more
// than once in blocks, or nil if all were unique.

findDuplicate returns an arbitrary basic block that appeared more than once in blocks or nil if all were unique .


func newIssuePathFromAbsPath(root, path string) (IssuePath, error) {
	resolvedRoot, err := filepath.EvalSymlinks(root)
	if err != nil {
		return newIssuePath(root, path), err
	}

	resolvedPath, err := filepath.EvalSymlinks(path)
	if err != nil {
		return newIssuePath(root, path), err
	}

	if !filepath.IsAbs(path) {
		return newIssuePath(resolvedRoot, resolvedPath), nil
	}

	relPath, err := filepath.Rel(resolvedRoot, resolvedPath)
	return newIssuePath(resolvedRoot, relPath), err
}

func newIssuePathFromAbsPath ( root , path string ) ( IssuePath , error ) { resolvedRoot , err := filepath . EvalSymlinks ( root ) if err != nil { return newIssuePath ( root , path ) , err } resolvedPath , err := filepath . EvalSymlinks ( path ) if err != nil { return newIssuePath ( root , path ) , err } if ! filepath . IsAbs ( path ) { return newIssuePath ( resolvedRoot , resolvedPath ) , nil } relPath , err := filepath . Rel ( resolvedRoot , resolvedPath ) return newIssuePath ( resolvedRoot , relPath ) , err }

// newIssuePathFromAbsPath returns a new issuePath from a path that may be
// an absolute path. root must be an absolute path.

newIssuePathFromAbsPath returns a new issuePath from a path that may be an absolute path . root must be an absolute path .


func NewIssue(linter string, formatTmpl *template.Template) (*Issue, error) {
	issue := &Issue{
		Line:       1,
		Severity:   Warning,
		Linter:     linter,
		formatTmpl: formatTmpl,
	}
	err := formatTmpl.Execute(ioutil.Discard, issue)
	return issue, err
}

func NewIssue ( linter string , formatTmpl * template . Template ) ( * Issue , error ) { issue := & Issue { Line : 1 , Severity : Warning , Linter : linter , formatTmpl : formatTmpl , } err := formatTmpl . Execute ( ioutil . Discard , issue ) return issue , err }

// NewIssue returns a new issue. Returns an error if formatTmpl is not a valid
// template for an Issue.

NewIssue returns a new issue . Returns an error if formatTmpl is not a valid template for an Issue .


func SortIssueChan(issues chan *Issue, order []string) chan *Issue {
	out := make(chan *Issue, 1000000)
	sorted := &sortedIssues{
		issues: []*Issue{},
		order:  order,
	}
	go func() {
		for issue := range issues {
			sorted.issues = append(sorted.issues, issue)
		}
		sort.Sort(sorted)
		for _, issue := range sorted.issues {
			out <- issue
		}
		close(out)
	}()
	return out
}

func SortIssueChan ( issues chan * Issue , order [ ] string ) chan * Issue { out := make ( chan * Issue , 1000000 ) sorted := & sortedIssues { issues : [ ] * Issue { } , order : order , } go func ( ) { for issue := range issues { sorted . issues = append ( sorted . issues , issue ) } sort . Sort ( sorted ) for _ , issue := range sorted . issues { out <- issue } close ( out ) } ( ) return out }

// SortIssueChan reads issues from one channel, sorts them, and returns them to another
// channel

SortIssueChan reads issues from one channel sorts them and returns them to another channel


func (b *builder) logicalBinop(fn *Function, e *ast.BinaryExpr) Value {
	rhs := fn.newBasicBlock("binop.rhs")
	done := fn.newBasicBlock("binop.done")

	// T(e) = T(e.X) = T(e.Y) after untyped constants have been
	// eliminated.
	// TODO(adonovan): not true; MyBool==MyBool yields UntypedBool.
	t := fn.Pkg.typeOf(e)

	var short Value // value of the short-circuit path
	switch e.Op {
	case token.LAND:
		b.cond(fn, e.X, rhs, done)
		short = NewConst(exact.MakeBool(false), t)

	case token.LOR:
		b.cond(fn, e.X, done, rhs)
		short = NewConst(exact.MakeBool(true), t)
	}

	// Is rhs unreachable?
	if rhs.Preds == nil {
		// Simplify false&&y to false, true||y to true.
		fn.currentBlock = done
		return short
	}

	// Is done unreachable?
	if done.Preds == nil {
		// Simplify true&&y (or false||y) to y.
		fn.currentBlock = rhs
		return b.expr(fn, e.Y)
	}

	// All edges from e.X to done carry the short-circuit value.
	var edges []Value
	for range done.Preds {
		edges = append(edges, short)
	}

	// The edge from e.Y to done carries the value of e.Y.
	fn.currentBlock = rhs
	edges = append(edges, b.expr(fn, e.Y))
	emitJump(fn, done)
	fn.currentBlock = done

	phi := &Phi{Edges: edges, Comment: e.Op.String()}
	phi.pos = e.OpPos
	phi.typ = t
	return done.emit(phi)
}

// logicalBinop emits code to fn to evaluate e, a &&- or
// ||-expression whose reified boolean value is wanted.
// The value is returned.
//

logicalBinop emits code to fn to evaluate e a && - or || - expression whose reified boolean value is wanted . The value is returned .


func (b *builder) expr(fn *Function, e ast.Expr) Value {
	e = unparen(e)

	tv := fn.Pkg.info.Types[e]

	// Is expression a constant?
	if tv.Value != nil {
		return NewConst(tv.Value, tv.Type)
	}

	var v Value
	if tv.Addressable() {
		// Prefer pointer arithmetic ({Index,Field}Addr) followed
		// by Load over subelement extraction (e.g. Index, Field),
		// to avoid large copies.
		v = b.addr(fn, e, false).load(fn)
	} else {
		v = b.expr0(fn, e, tv)
	}
	if fn.debugInfo() {
		emitDebugRef(fn, e, v, false)
	}
	return v
}

// expr lowers a single-result expression e to SSA form, emitting code
// to fn and returning the Value defined by the expression.
//

expr lowers a single - result expression e to SSA form emitting code to fn and returning the Value defined by the expression .


func (b *builder) stmtList(fn *Function, list []ast.Stmt) {
	for _, s := range list {
		b.stmt(fn, s)
	}
}

func ( b * builder ) stmtList ( fn * Function , list [ ] ast . Stmt ) { for _ , s := range list { b . stmt ( fn , s ) } }

// stmtList emits to fn code for all statements in list.

stmtList emits to fn code for all statements in list .


func (b *builder) assignOp(fn *Function, loc lvalue, incr Value, op token.Token, pos token.Pos) {
	oldv := loc.load(fn)
	loc.store(fn, emitArith(fn, op, oldv, emitConv(fn, incr, oldv.Type()), loc.typ(), pos))
}

func ( b * builder ) assignOp ( fn * Function , loc lvalue , incr Value , op token . Token , pos token . Pos ) { oldv := loc . load ( fn ) loc . store ( fn , emitArith ( fn , op , oldv , emitConv ( fn , incr , oldv . Type ( ) ) , loc . typ ( ) , pos ) ) }

// assignOp emits to fn code to perform loc += incr or loc -= incr.

assignOp emits to fn code to perform loc + = incr or loc - = incr .


func (b *builder) localValueSpec(fn *Function, spec *ast.ValueSpec) {
	switch {
	case len(spec.Values) == len(spec.Names):
		// e.g. var x, y = 0, 1
		// 1:1 assignment
		for i, id := range spec.Names {
			if !isBlankIdent(id) {
				fn.addLocalForIdent(id)
			}
			lval := b.addr(fn, id, false) // non-escaping
			b.assign(fn, lval, spec.Values[i], true, nil)
		}

	case len(spec.Values) == 0:
		// e.g. var x, y int
		// Locals are implicitly zero-initialized.
		for _, id := range spec.Names {
			if !isBlankIdent(id) {
				lhs := fn.addLocalForIdent(id)
				if fn.debugInfo() {
					emitDebugRef(fn, id, lhs, true)
				}
			}
		}

	default:
		// e.g. var x, y = pos()
		tuple := b.exprN(fn, spec.Values[0])
		for i, id := range spec.Names {
			if !isBlankIdent(id) {
				fn.addLocalForIdent(id)
				lhs := b.addr(fn, id, false) // non-escaping
				lhs.store(fn, emitExtract(fn, tuple, i))
			}
		}
	}
}

// localValueSpec emits to fn code to define all of the vars in the
// function-local ValueSpec, spec.
//

localValueSpec emits to fn code to define all of the vars in the function - local ValueSpec spec .


func (b *builder) arrayLen(fn *Function, elts []ast.Expr) int64 {
	var max int64 = -1
	var i int64 = -1
	for _, e := range elts {
		if kv, ok := e.(*ast.KeyValueExpr); ok {
			i = b.expr(fn, kv.Key).(*Const).Int64()
		} else {
			i++
		}
		if i > max {
			max = i
		}
	}
	return max + 1
}

func ( b * builder ) arrayLen ( fn * Function , elts [ ] ast . Expr ) int64 { var max int64 = - 1 var i int64 = - 1 for _ , e := range elts { if kv , ok := e . ( * ast . KeyValueExpr ) ; ok { i = b . expr ( fn , kv . Key ) . ( * Const ) . Int64 ( ) } else { i ++ } if i > max { max = i } } return max + 1 }

// arrayLen returns the length of the array whose composite literal elements are elts.

arrayLen returns the length of the array whose composite literal elements are elts .


func (b *builder) switchStmt(fn *Function, s *ast.SwitchStmt, label *lblock) {
	// We treat SwitchStmt like a sequential if-else chain.
	// Multiway dispatch can be recovered later by ssautil.Switches()
	// to those cases that are free of side effects.
	if s.Init != nil {
		b.stmt(fn, s.Init)
	}
	var tag Value = vTrue
	if s.Tag != nil {
		tag = b.expr(fn, s.Tag)
	}
	done := fn.newBasicBlock("switch.done")
	if label != nil {
		label._break = done
	}
	// We pull the default case (if present) down to the end.
	// But each fallthrough label must point to the next
	// body block in source order, so we preallocate a
	// body block (fallthru) for the next case.
	// Unfortunately this makes for a confusing block order.
	var dfltBody *[]ast.Stmt
	var dfltFallthrough *BasicBlock
	var fallthru, dfltBlock *BasicBlock
	ncases := len(s.Body.List)
	for i, clause := range s.Body.List {
		body := fallthru
		if body == nil {
			body = fn.newBasicBlock("switch.body") // first case only
		}

		// Preallocate body block for the next case.
		fallthru = done
		if i+1 < ncases {
			fallthru = fn.newBasicBlock("switch.body")
		}

		cc := clause.(*ast.CaseClause)
		if cc.List == nil {
			// Default case.
			dfltBody = &cc.Body
			dfltFallthrough = fallthru
			dfltBlock = body
			continue
		}

		var nextCond *BasicBlock
		for _, cond := range cc.List {
			nextCond = fn.newBasicBlock("switch.next")
			// TODO(adonovan): opt: when tag==vTrue, we'd
			// get better code if we use b.cond(cond)
			// instead of BinOp(EQL, tag, b.expr(cond))
			// followed by If.  Don't forget conversions
			// though.
			cond := emitCompare(fn, token.EQL, tag, b.expr(fn, cond), cond.Pos())
			emitIf(fn, cond, body, nextCond)
			fn.currentBlock = nextCond
		}
		fn.currentBlock = body
		fn.targets = &targets{
			tail:         fn.targets,
			_break:       done,
			_fallthrough: fallthru,
		}
		b.stmtList(fn, cc.Body)
		fn.targets = fn.targets.tail
		emitJump(fn, done)
		fn.currentBlock = nextCond
	}
	if dfltBlock != nil {
		emitJump(fn, dfltBlock)
		fn.currentBlock = dfltBlock
		fn.targets = &targets{
			tail:         fn.targets,
			_break:       done,
			_fallthrough: dfltFallthrough,
		}
		b.stmtList(fn, *dfltBody)
		fn.targets = fn.targets.tail
	}
	emitJump(fn, done)
	fn.currentBlock = done
}

// switchStmt emits to fn code for the switch statement s, optionally
// labelled by label.
//

switchStmt emits to fn code for the switch statement s optionally labelled by label .


func (b *builder) typeSwitchStmt(fn *Function, s *ast.TypeSwitchStmt, label *lblock) {
	// We treat TypeSwitchStmt like a sequential if-else chain.
	// Multiway dispatch can be recovered later by ssautil.Switches().

	// Typeswitch lowering:
	//
	// var x X
	// switch y := x.(type) {
	// case T1, T2: S1                  // >1 	(y := x)
	// case nil:    SN                  // nil 	(y := x)
	// default:     SD                  // 0 types 	(y := x)
	// case T3:     S3                  // 1 type 	(y := x.(T3))
	// }
	//
	//      ...s.Init...
	// 	x := eval x
	// .caseT1:
	// 	t1, ok1 := typeswitch,ok x <T1>
	// 	if ok1 then goto S1 else goto .caseT2
	// .caseT2:
	// 	t2, ok2 := typeswitch,ok x <T2>
	// 	if ok2 then goto S1 else goto .caseNil
	// .S1:
	//      y := x
	// 	...S1...
	// 	goto done
	// .caseNil:
	// 	if t2, ok2 := typeswitch,ok x <T2>
	// 	if x == nil then goto SN else goto .caseT3
	// .SN:
	//      y := x
	// 	...SN...
	// 	goto done
	// .caseT3:
	// 	t3, ok3 := typeswitch,ok x <T3>
	// 	if ok3 then goto S3 else goto default
	// .S3:
	//      y := t3
	// 	...S3...
	// 	goto done
	// .default:
	//      y := x
	// 	...SD...
	// 	goto done
	// .done:

	if s.Init != nil {
		b.stmt(fn, s.Init)
	}

	var x Value
	switch ass := s.Assign.(type) {
	case *ast.ExprStmt: // x.(type)
		x = b.expr(fn, unparen(ass.X).(*ast.TypeAssertExpr).X)
	case *ast.AssignStmt: // y := x.(type)
		x = b.expr(fn, unparen(ass.Rhs[0]).(*ast.TypeAssertExpr).X)
	}

	done := fn.newBasicBlock("typeswitch.done")
	if label != nil {
		label._break = done
	}
	var default_ *ast.CaseClause
	for _, clause := range s.Body.List {
		cc := clause.(*ast.CaseClause)
		if cc.List == nil {
			default_ = cc
			continue
		}
		body := fn.newBasicBlock("typeswitch.body")
		var next *BasicBlock
		var casetype types.Type
		var ti Value // ti, ok := typeassert,ok x <Ti>
		for _, cond := range cc.List {
			next = fn.newBasicBlock("typeswitch.next")
			casetype = fn.Pkg.typeOf(cond)
			var condv Value
			if casetype == tUntypedNil {
				condv = emitCompare(fn, token.EQL, x, nilConst(x.Type()), token.NoPos)
				ti = x
			} else {
				yok := emitTypeTest(fn, x, casetype, cc.Case)
				ti = emitExtract(fn, yok, 0)
				condv = emitExtract(fn, yok, 1)
			}
			emitIf(fn, condv, body, next)
			fn.currentBlock = next
		}
		if len(cc.List) != 1 {
			ti = x
		}
		fn.currentBlock = body
		b.typeCaseBody(fn, cc, ti, done)
		fn.currentBlock = next
	}
	if default_ != nil {
		b.typeCaseBody(fn, default_, x, done)
	} else {
		emitJump(fn, done)
	}
	fn.currentBlock = done
}

// case nil:    SN                  // nil 	(y := x)

// default:     SD                  // 0 types 	(y := x)

// typeSwitchStmt emits to fn code for the type switch statement s, optionally
// labelled by label.
//

typeSwitchStmt emits to fn code for the type switch statement s optionally labelled by label .


func (b *builder) forStmt(fn *Function, s *ast.ForStmt, label *lblock) {
	//	...init...
	//      jump loop
	// loop:
	//      if cond goto body else done
	// body:
	//      ...body...
	//      jump post
	// post:				 (target of continue)
	//      ...post...
	//      jump loop
	// done:                                 (target of break)
	if s.Init != nil {
		b.stmt(fn, s.Init)
	}
	body := fn.newBasicBlock("for.body")
	done := fn.newBasicBlock("for.done") // target of 'break'
	loop := body                         // target of back-edge
	if s.Cond != nil {
		loop = fn.newBasicBlock("for.loop")
	}
	cont := loop // target of 'continue'
	if s.Post != nil {
		cont = fn.newBasicBlock("for.post")
	}
	if label != nil {
		label._break = done
		label._continue = cont
	}
	emitJump(fn, loop)
	fn.currentBlock = loop
	if loop != body {
		b.cond(fn, s.Cond, body, done)
		fn.currentBlock = body
	}
	fn.targets = &targets{
		tail:      fn.targets,
		_break:    done,
		_continue: cont,
	}
	b.stmt(fn, s.Body)
	fn.targets = fn.targets.tail
	emitJump(fn, cont)

	if s.Post != nil {
		fn.currentBlock = cont
		b.stmt(fn, s.Post)
		emitJump(fn, loop) // back-edge
	}
	fn.currentBlock = done
}

// done:                                 (target of break)

// forStmt emits to fn code for the for statement s, optionally
// labelled by label.
//

forStmt emits to fn code for the for statement s optionally labelled by label .


func (b *builder) rangeStmt(fn *Function, s *ast.RangeStmt, label *lblock) {
	var tk, tv types.Type
	if s.Key != nil && !isBlankIdent(s.Key) {
		tk = fn.Pkg.typeOf(s.Key)
	}
	if s.Value != nil && !isBlankIdent(s.Value) {
		tv = fn.Pkg.typeOf(s.Value)
	}

	// If iteration variables are defined (:=), this
	// occurs once outside the loop.
	//
	// Unlike a short variable declaration, a RangeStmt
	// using := never redeclares an existing variable; it
	// always creates a new one.
	if s.Tok == token.DEFINE {
		if tk != nil {
			fn.addLocalForIdent(s.Key.(*ast.Ident))
		}
		if tv != nil {
			fn.addLocalForIdent(s.Value.(*ast.Ident))
		}
	}

	x := b.expr(fn, s.X)

	var k, v Value
	var loop, done *BasicBlock
	switch rt := x.Type().Underlying().(type) {
	case *types.Slice, *types.Array, *types.Pointer: // *array
		k, v, loop, done = b.rangeIndexed(fn, x, tv, s.For)

	case *types.Chan:
		k, loop, done = b.rangeChan(fn, x, tk, s.For)

	case *types.Map, *types.Basic: // string
		k, v, loop, done = b.rangeIter(fn, x, tk, tv, s.For)

	default:
		panic("Cannot range over: " + rt.String())
	}

	// Evaluate both LHS expressions before we update either.
	var kl, vl lvalue
	if tk != nil {
		kl = b.addr(fn, s.Key, false) // non-escaping
	}
	if tv != nil {
		vl = b.addr(fn, s.Value, false) // non-escaping
	}
	if tk != nil {
		kl.store(fn, k)
	}
	if tv != nil {
		vl.store(fn, v)
	}

	if label != nil {
		label._break = done
		label._continue = loop
	}

	fn.targets = &targets{
		tail:      fn.targets,
		_break:    done,
		_continue: loop,
	}
	b.stmt(fn, s.Body)
	fn.targets = fn.targets.tail
	emitJump(fn, loop) // back-edge
	fn.currentBlock = done
}

// rangeStmt emits to fn code for the range statement s, optionally
// labelled by label.
//

rangeStmt emits to fn code for the range statement s optionally labelled by label .


func (b *builder) buildFunction(fn *Function) {
	if fn.Blocks != nil {
		return // building already started
	}

	var recvField *ast.FieldList
	var body *ast.BlockStmt
	var functype *ast.FuncType
	switch n := fn.syntax.(type) {
	case nil:
		return // not a Go source function.  (Synthetic, or from object file.)
	case *ast.FuncDecl:
		functype = n.Type
		recvField = n.Recv
		body = n.Body
	case *ast.FuncLit:
		functype = n.Type
		body = n.Body
	default:
		panic(n)
	}

	if body == nil {
		// External function.
		if fn.Params == nil {
			// This condition ensures we add a non-empty
			// params list once only, but we may attempt
			// the degenerate empty case repeatedly.
			// TODO(adonovan): opt: don't do that.

			// We set Function.Params even though there is no body
			// code to reference them.  This simplifies clients.
			if recv := fn.Signature.Recv(); recv != nil {
				fn.addParamObj(recv)
			}
			params := fn.Signature.Params()
			for i, n := 0, params.Len(); i < n; i++ {
				fn.addParamObj(params.At(i))
			}
		}
		return
	}
	if fn.Prog.mode&LogSource != 0 {
		defer logStack("build function %s @ %s", fn, fn.Prog.Fset.Position(fn.pos))()
	}
	fn.startBody()
	fn.createSyntacticParams(recvField, functype)
	b.stmt(fn, body)
	if cb := fn.currentBlock; cb != nil && (cb == fn.Blocks[0] || cb == fn.Recover || cb.Preds != nil) {
		// Control fell off the end of the function's body block.
		//
		// Block optimizations eliminate the current block, if
		// unreachable.  It is a builder invariant that
		// if this no-arg return is ill-typed for
		// fn.Signature.Results, this block must be
		// unreachable.  The sanity checker checks this.
		fn.emit(new(RunDefers))
		fn.emit(new(Return))
	}
	fn.finishBody()
}

// buildFunction builds SSA code for the body of function fn.  Idempotent.

buildFunction builds SSA code for the body of function fn . Idempotent .


func (b *builder) buildFuncDecl(pkg *Package, decl *ast.FuncDecl) {
	id := decl.Name
	if isBlankIdent(id) {
		return // discard
	}
	fn := pkg.values[pkg.info.Defs[id]].(*Function)
	if decl.Recv == nil && id.Name == "init" {
		var v Call
		v.Call.Value = fn
		v.setType(types.NewTuple())
		pkg.init.emit(&v)
	}
	b.buildFunction(fn)
}

func
(
b
*
builder
)
buildFuncDecl
(
pkg
*
Package
,
decl
*
ast
.
FuncDecl
)
{
id
:=
decl
.
Name
if
isBlankIdent
(
id
)
{
return
// discard
}
fn
:=
pkg
.
values
[
pkg
.
info
.
Defs
[
id
]
]
.
(
*
Function
)
if
decl
.
Recv
==
&&
id
.
Name
==
"
"
{
var
v
Call
v
.
Call
.
Value
=
fn
v
.
setType
(
types
.
NewTuple
(
)
)
pkg
.
init
.
emit
(
&
v
)
}
b
.
buildFunction
(
fn
)
}

// buildFuncDecl builds SSA code for the function or method declared
// by decl in package pkg.
//

buildFuncDecl builds SSA code for the function or method declared by decl in package pkg .


func (prog *Program) Build() {
	var wg sync.WaitGroup
	for _, p := range prog.packages {
		if prog.mode&BuildSerially != 0 {
			p.Build()
		} else {
			wg.Add(1)
			go func(p *Package) {
				p.Build()
				wg.Done()
			}(p)
		}
	}
	wg.Wait()
}

func ( prog * Program ) Build ( ) { var wg sync . WaitGroup for _ , p := range prog . packages { if prog . mode & BuildSerially != 0 { p . Build ( ) } else { wg . Add ( 1 ) go func ( p * Package ) { p . Build ( ) wg . Done ( ) } ( p ) } } wg . Wait ( ) }

// Build calls Package.Build for each package in prog.
// Building occurs in parallel unless the BuildSerially mode flag was set.
//
// Build is intended for whole-program analysis; a typical compiler
// need only build a single package.
//
// Build is idempotent and thread-safe.
//

Build calls Package . Build for each package in prog . Building occurs in parallel unless the BuildSerially mode flag was set . Build is intended for whole - program analysis ; a typical compiler need only build a single package . Build is idempotent and thread - safe .


func (p *Package) objectOf(id *ast.Ident) types.Object {
	if o := p.info.ObjectOf(id); o != nil {
		return o
	}
	panic(fmt.Sprintf("no types.Object for ast.Ident %s @ %s",
		id.Name, p.Prog.Fset.Position(id.Pos())))
}

func ( p * Package ) objectOf ( id * ast . Ident ) types . Object { if o := p . info . ObjectOf ( id ) ; o != nil { return o } panic ( fmt . Sprintf ( " " , id . Name , p . Prog . Fset . Position ( id . Pos ( ) ) ) ) }

// Like ObjectOf, but panics instead of returning nil.
// Only valid during p's create and build phases.

Like ObjectOf but panics instead of returning nil . Only valid during p s create and build phases .


func (p *Package) typeOf(e ast.Expr) types.Type {
	if T := p.info.TypeOf(e); T != nil {
		return T
	}
	panic(fmt.Sprintf("no type for %T @ %s",
		e, p.Prog.Fset.Position(e.Pos())))
}

func ( p * Package ) typeOf ( e ast . Expr ) types . Type { if T := p . info . TypeOf ( e ) ; T != nil { return T } panic ( fmt . Sprintf ( " " , e , p . Prog . Fset . Position ( e . Pos ( ) ) ) ) }

// Like TypeOf, but panics instead of returning nil.
// Only valid during p's create and build phases.

Like TypeOf but panics instead of returning nil . Only valid during p s create and build phases .


func (p *parser) expect(e yaml_event_type_t) {
	if p.event.typ == yaml_NO_EVENT {
		if !yaml_parser_parse(&p.parser, &p.event) {
			p.fail()
		}
	}
	if p.event.typ == yaml_STREAM_END_EVENT {
		failf("attempted to go past the end of stream; corrupted value?")
	}
	if p.event.typ != e {
		p.parser.problem = fmt.Sprintf("expected %s event but got %s", e, p.event.typ)
		p.fail()
	}
	yaml_event_delete(&p.event)
	p.event.typ = yaml_NO_EVENT
}

func ( p * parser ) expect ( e yaml_event_type_t ) { if p . event . typ == yaml_NO_EVENT { if ! yaml_parser_parse ( & p . parser , & p . event ) { p . fail ( ) } } if p . event . typ == yaml_STREAM_END_EVENT { failf ( " " ) } if p . event . typ != e { p . parser . problem = fmt . Sprintf ( " " , e , p . event . typ ) p . fail ( ) } yaml_event_delete ( & p . event ) p . event . typ = yaml_NO_EVENT }

// expect consumes an event from the event stream and
// checks that it's of the expected type.

expect consumes an event from the event stream and checks that it s of the expected type .


func (p *parser) peek() yaml_event_type_t {
	if p.event.typ != yaml_NO_EVENT {
		return p.event.typ
	}
	if !yaml_parser_parse(&p.parser, &p.event) {
		p.fail()
	}
	return p.event.typ
}

func ( p * parser ) peek ( ) yaml_event_type_t { if p . event . typ != yaml_NO_EVENT { return p . event . typ } if ! yaml_parser_parse ( & p . parser , & p . event ) { p . fail ( ) } return p . event . typ }

// peek peeks at the next event in the event stream,
// puts the results into p.event and returns the event type.

peek peeks at the next event in the event stream puts the results into p . event and returns the event type .


func (d *decoder) prepare(n *node, out reflect.Value) (newout reflect.Value, unmarshaled, good bool) {
	if n.tag == yaml_NULL_TAG || n.kind == scalarNode && n.tag == "" && (n.value == "null" || n.value == "~" || n.value == "" && n.implicit) {
		return out, false, false
	}
	again := true
	for again {
		again = false
		if out.Kind() == reflect.Ptr {
			if out.IsNil() {
				out.Set(reflect.New(out.Type().Elem()))
			}
			out = out.Elem()
			again = true
		}
		if out.CanAddr() {
			if u, ok := out.Addr().Interface().(Unmarshaler); ok {
				good = d.callUnmarshaler(n, u)
				return out, true, good
			}
		}
	}
	return out, false, false
}

func ( d * decoder ) prepare ( n * node , out reflect . Value ) ( newout reflect . Value , unmarshaled , good bool ) { if n . tag == yaml_NULL_TAG || n . kind == scalarNode && n . tag == " " && ( n . value == " " || n . value == " " || n . value == " " && n . implicit ) { return out , false , false } again := true for again { again = false if out . Kind ( ) == reflect . Ptr { if out . IsNil ( ) { out . Set ( reflect . New ( out . Type ( ) . Elem ( ) ) ) } out = out . Elem ( ) again = true } if out . CanAddr ( ) { if u , ok := out . Addr ( ) . Interface ( ) . ( Unmarshaler ) ; ok { good = d . callUnmarshaler ( n , u ) return out , true , good } } } return out , false , false }

// d.prepare initializes and dereferences pointers and calls UnmarshalYAML
// if a value is found to implement it.
// It returns the initialized and dereferenced out value, whether
// unmarshalling was already done by UnmarshalYAML, and if so whether
// its types unmarshalled appropriately.
//
// If n holds a null value, prepare returns before doing anything.

d . prepare initializes and dereferences pointers and calls UnmarshalYAML if a value is found to implement it . It returns the initialized and dereferenced out value whether unmarshalling was already done by UnmarshalYAML and if so whether its types unmarshalled appropriately . If n holds a null value prepare returns before doing anything .


func Parse(f string) ([]interface{}, error) {
	var out []interface{}
	for len(f) > 0 {
		if f[0] == '%' {
			v, n, err := ParseVerb(f)
			if err != nil {
				return nil, err
			}
			f = f[n:]
			out = append(out, v)
		} else {
			n := strings.IndexByte(f, '%')
			if n > -1 {
				out = append(out, f[:n])
				f = f[n:]
			} else {
				out = append(out, f)
				f = ""
			}
		}
	}

	return out, nil
}

func Parse ( f string ) ( [ ] interface { } , error ) { var out [ ] interface { } for len ( f ) > 0 { if f [ 0 ] == '%' { v , n , err := ParseVerb ( f ) if err != nil { return nil , err } f = f [ n : ] out = append ( out , v ) } else { n := strings . IndexByte ( f , '%' ) if n > - 1 { out = append ( out , f [ : n ] ) f = f [ n : ] } else { out = append ( out , f ) f = " " } } } return out , nil }

// Parse parses f and returns a list of actions.
// An action may either be a literal string, or a Verb.

Parse parses f and returns a list of actions . An action may either be a literal string or a Verb .


func ParseVerb(f string) (Verb, int, error) {
	if len(f) < 2 {
		return Verb{}, 0, ErrInvalid
	}
	const (
		flags = 1

		width      = 2
		widthStar  = 3
		widthIndex = 5

		dot       = 6
		prec      = 7
		precStar  = 8
		precIndex = 10

		verbIndex = 11
		verb      = 12
	)

	m := re.FindStringSubmatch(f)
	if m == nil {
		return Verb{}, 0, ErrInvalid
	}

	v := Verb{
		Letter: []rune(m[verb])[0],
		Flags:  m[flags],
		Raw:    m[0],
	}

	if m[width] != "" {
		// Literal width
		v.Width = Literal(atoi(m[width]))
	} else if m[widthStar] != "" {
		// Star width
		if m[widthIndex] != "" {
			v.Width = Star{atoi(m[widthIndex])}
		} else {
			v.Width = Star{-1}
		}
	} else {
		// Default width
		v.Width = Default{}
	}

	if m[dot] == "" {
		// default precision
		v.Precision = Default{}
	} else {
		if m[prec] != "" {
			// Literal precision
			v.Precision = Literal(atoi(m[prec]))
		} else if m[precStar] != "" {
			// Star precision
			if m[precIndex] != "" {
				v.Precision = Star{atoi(m[precIndex])}
			} else {
				v.Precision = Star{-1}
			}
		} else {
			// Zero precision
			v.Precision = Zero{}
		}
	}

	if m[verb] == "%" {
		v.Value = 0
	} else if m[verbIndex] != "" {
		v.Value = atoi(m[verbIndex])
	} else {
		v.Value = -1
	}

	return v, len(m[0]), nil
}

func
ParseVerb
(
f
string
)
(
Verb
,
int
,
error
)
{
if
len
(
f
)
<
2
{
return
Verb
{
}
,
0
,
ErrInvalid
}
const
(
flags
=
1
width
=
2
widthStar
=
3
widthIndex
=
5
dot
=
6
prec
=
7
precStar
=
8
precIndex
=
10
verbIndex
=
11
verb
=
12
)
m
:=
re
.
FindStringSubmatch
(
f
)
if
m
==
{
return
Verb
{
}
,
0
,
ErrInvalid
}
v
:=
Verb
{
Letter
:
[
]
rune
(
m
[
verb
]
)
[
0
]
,
Flags
:
m
[
flags
]
,
Raw
:
m
[
0
]
,
}
if
m
[
width
]
!=
"
"
{
// Literal width
v
.
Width
=
Literal
(
atoi
(
m
[
width
]
)
)
}
else
if
m
[
widthStar
]
!=
"
"
{
// Star width
if
m
[
widthIndex
]
!=
"
"
{
v
.
Width
=
Star
{
atoi
(
m
[
widthIndex
]
)
}
}
else
{
v
.
Width
=
Star
{
1
}
}
}
else
{
// Default width
v
.
Width
=
Default
{
}
}
if
m
[
dot
]
==
"
"
{
// default precision
v
.
Precision
=
Default
{
}
}
else
{
if
m
[
prec
]
!=
"
"
{
// Literal precision
v
.
Precision
=
Literal
(
atoi
(
m
[
prec
]
)
)
}
else
if
m
[
precStar
]
!=
"
"
{
// Star precision
if
m
[
precIndex
]
!=
"
"
{
v
.
Precision
=
Star
{
atoi
(
m
[
precIndex
]
)
}
}
else
{
v
.
Precision
=
Star
{
1
}
}
}
else
{
// Zero precision
v
.
Precision
=
Zero
{
}
}
}
if
m
[
verb
]
==
"
"
{
v
.
Value
=
0
}
else
if
m
[
verbIndex
]
!=
"
"
{
v
.
Value
=
atoi
(
m
[
verbIndex
]
)
}
else
{
v
.
Value
=
1
}
return
v
,
len
(
m
[
0
]
)
,
}

// ParseVerb parses the verb at the beginning of f.
// It returns the verb, how much of the input was consumed, and an error, if any.

ParseVerb parses the verb at the beginning of f . It returns the verb how much of the input was consumed and an error if any .


func terminates(fn *ssa.Function) bool {
	if fn.Blocks == nil {
		// assuming that a function terminates is the conservative
		// choice
		return true
	}

	for _, block := range fn.Blocks {
		if len(block.Instrs) == 0 {
			continue
		}
		if _, ok := block.Instrs[len(block.Instrs)-1].(*ssa.Return); ok {
			return true
		}
	}
	return false
}

// terminates reports whether fn is supposed to return, that is if it
// has at least one theoretic path that returns from the function.
// Explicit panics do not count as terminating.

terminates reports whether fn is supposed to return that is if it has at least one theoretic path that returns from the function . Explicit panics do not count as terminating .


func yaml_reader_read_handler(parser *yaml_parser_t, buffer []byte) (n int, err error) {
	return parser.input_reader.Read(buffer)
}

func yaml_reader_read_handler ( parser * yaml_parser_t , buffer [ ] byte ) ( n int , err error ) { return parser . input_reader . Read ( buffer ) }


func yaml_parser_set_input_reader(parser *yaml_parser_t, r io.Reader) {
	if parser.read_handler != nil {
		panic("must set the input source only once")
	}
	parser.read_handler = yaml_reader_read_handler
	parser.input_reader = r
}

func yaml_parser_set_input_reader ( parser * yaml_parser_t , r io . Reader ) { if parser . read_handler != nil { panic ( " " ) } parser . read_handler = yaml_reader_read_handler parser . input_reader = r }


func yaml_emitter_initialize(emitter *yaml_emitter_t) {
	*emitter = yaml_emitter_t{
		buffer:     make([]byte, output_buffer_size),
		raw_buffer: make([]byte, 0, output_raw_buffer_size),
		states:     make([]yaml_emitter_state_t, 0, initial_stack_size),
		events:     make([]yaml_event_t, 0, initial_queue_size),
	}
}

func yaml_emitter_initialize ( emitter * yaml_emitter_t ) { * emitter = yaml_emitter_t { buffer : make ( [ ] byte , output_buffer_size ) , raw_buffer : make ( [ ] byte , 0 , output_raw_buffer_size ) , states : make ( [ ] yaml_emitter_state_t , 0 , initial_stack_size ) , events : make ( [ ] yaml_event_t , 0 , initial_queue_size ) , } }


func yaml_writer_write_handler(emitter *yaml_emitter_t, buffer []byte) error {
	_, err := emitter.output_writer.Write(buffer)
	return err
}

func yaml_writer_write_handler ( emitter * yaml_emitter_t , buffer [ ] byte ) error { _ , err := emitter . output_writer . Write ( buffer ) return err }

// yaml_writer_write_handler uses emitter.output_writer to write the
// emitted text.

yaml_writer_write_handler uses emitter . output_writer to write the emitted text .


func yaml_emitter_set_output_writer(emitter *yaml_emitter_t, w io.Writer) {
	if emitter.write_handler != nil {
		panic("must set the output target only once")
	}
	emitter.write_handler = yaml_writer_write_handler
	emitter.output_writer = w
}

func yaml_emitter_set_output_writer ( emitter * yaml_emitter_t , w io . Writer ) { if emitter . write_handler != nil { panic ( " " ) } emitter . write_handler = yaml_writer_write_handler emitter . output_writer = w }


func yaml_mapping_start_event_initialize(event *yaml_event_t, anchor, tag []byte, implicit bool, style yaml_mapping_style_t) {
	*event = yaml_event_t{
		typ:      yaml_MAPPING_START_EVENT,
		anchor:   anchor,
		tag:      tag,
		implicit: implicit,
		style:    yaml_style_t(style),
	}
}

func yaml_mapping_start_event_initialize ( event * yaml_event_t , anchor , tag [ ] byte , implicit bool , style yaml_mapping_style_t ) { * event = yaml_event_t { typ : yaml_MAPPING_START_EVENT , anchor : anchor , tag : tag , implicit : implicit , style : yaml_style_t ( style ) , } }


func yaml_emitter_flush(emitter *yaml_emitter_t) bool {
	if emitter.write_handler == nil {
		panic("write handler not set")
	}

	// Check if the buffer is empty.
	if emitter.buffer_pos == 0 {
		return true
	}

	if err := emitter.write_handler(emitter, emitter.buffer[:emitter.buffer_pos]); err != nil {
		return yaml_emitter_set_writer_error(emitter, "write error: "+err.Error())
	}
	emitter.buffer_pos = 0
	return true
}

func
yaml_emitter_flush
(
emitter
*
yaml_emitter_t
)
bool
{
if
emitter
.
write_handler
==
{
panic
(
"
"
)
}
// Check if the buffer is empty.
if
emitter
.
buffer_pos
==
0
{
return
true
}
if
err
:=
emitter
.
write_handler
(
emitter
,
emitter
.
buffer
[
:
emitter
.
buffer_pos
]
)
;
err
!=
{
return
yaml_emitter_set_writer_error
(
emitter
,
"
"
+
err
.
Error
(
)
)
}
emitter
.
buffer_pos
=
0
return
true
}


func (c *Checker) processConversion(pkg *lint.Pkg, node ast.Node) {
	if node, ok := node.(*ast.CallExpr); ok {
		callTyp := pkg.TypesInfo.TypeOf(node.Fun)
		var typDst *types.Struct
		var ok bool
		switch typ := callTyp.(type) {
		case *types.Named:
			typDst, ok = typ.Underlying().(*types.Struct)
		case *types.Pointer:
			typDst, ok = typ.Elem().Underlying().(*types.Struct)
		default:
			return
		}
		if !ok {
			return
		}

		if typ, ok := pkg.TypesInfo.TypeOf(node.Args[0]).(*types.Basic); ok && typ.Kind() == types.UnsafePointer {
			// This is an unsafe conversion. Assume that all the
			// fields are relevant (they are, because of memory
			// layout)
			n := typDst.NumFields()
			for i := 0; i < n; i++ {
				c.graph.markUsedBy(typDst.Field(i), typDst)
			}
			return
		}

		typSrc, ok := dereferenceType(pkg.TypesInfo.TypeOf(node.Args[0])).Underlying().(*types.Struct)
		if !ok {
			return
		}

		// When we convert from type t1 to t2, were t1 and t2 are
		// structs, all fields are relevant, as otherwise the
		// conversion would fail.
		//
		// We mark t2's fields as used by t1's fields, and vice
		// versa. That way, if no code actually refers to a field
		// in either type, it's still correctly marked as unused.
		// If a field is used in either struct, it's implicitly
		// relevant in the other one, too.
		//
		// It works in a similar way for conversions between types
		// of two packages, only that the extra information in the
		// graph is redundant unless we're in whole program mode.
		n := typDst.NumFields()
		for i := 0; i < n; i++ {
			fDst := typDst.Field(i)
			fSrc := typSrc.Field(i)
			c.graph.markUsedBy(fDst, fSrc)
			c.graph.markUsedBy(fSrc, fDst)
		}
	}
}

// processConversion marks fields as used if they're part of a type conversion.

processConversion marks fields as used if they re part of a type conversion .


func (c *Checker) processCompositeLiteral(pkg *lint.Pkg, node ast.Node) {
	// XXX how does this actually work? wouldn't it match t{}?
	if node, ok := node.(*ast.CompositeLit); ok {
		typ := pkg.TypesInfo.TypeOf(node)
		if _, ok := typ.(*types.Named); ok {
			typ = typ.Underlying()
		}
		if _, ok := typ.(*types.Struct); !ok {
			return
		}

		if isBasicStruct(node.Elts) {
			c.markFields(typ)
		}
	}
}

// processCompositeLiteral marks fields as used if the struct is used
// in a composite literal.

processCompositeLiteral marks fields as used if the struct is used in a composite literal .