<commit_before>// GoMySQL - A MySQL client library for Go
//
// Copyright 2010-2011 Phil Bayfield. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package mysql

import (
	"os"
	"bytes"
	"fmt"
)

// Packet type identifier
type packetType uint16

// Packet types
const (
	PACKET_INIT        packetType = 1 << iota
	PACKET_AUTH        packetType = 1 << iota
	PACKET_OK          packetType = 1 << iota
	PACKET_ERROR       packetType = 1 << iota
	PACKET_CMD         packetType = 1 << iota
	PACKET_RESULT      packetType = 1 << iota
	PACKET_FIELD       packetType = 1 << iota
	PACKET_ROW         packetType = 1 << iota
	PACKET_EOF         packetType = 1 << iota
	PACKET_OK_PREPARED packetType = 1 << iota
	PACKET_PARAM       packetType = 1 << iota
	PACKET_LONG_DATA   packetType = 1 << iota
	PACKET_EXECUTE     packetType = 1 << iota
	PACKET_ROW_BINARY  packetType = 1 << iota
)

// Readable packet interface
type packetReadable interface {
	read(data []byte) (err os.Error)
}

// Writable packet interface
type packetWriteable interface {
	write() (err os.Error)
}

// Generic packet interface (read/writable)
type packet interface {
	packetReadable
	packetWriteable
}

// Packet base struct
type packetBase struct {
	sequence uint8
}

// Read a slice from the data
func (p *packetBase) readSlice(data []byte, offset int, delim byte) (slice []byte, err os.Error) {
	 pos := bytes.IndexByte(data[offset:], delim)
	 if pos > -1 {
	 	slice = data[offset:pos+offset]
	 } else {
	 	slice = data[offset:]
	 	err = os.EOF
	 }
	 return
}

// Convert byte array into a number
func (p *packetBase) packNumber(data []byte) uint64 {
	num := uint64(0)
	for i := uint8(0); i < uint8(len(data)); i++ {
		num |= uint64(data[i]) << (i * 8)
	}
	return num
}

// Init packet
type packetInit struct {
	packetBase
	protocolVersion uint8
	serverVersion   string
	threadId        uint32
	scrambleBuff    []byte
	serverCaps      uint16
	serverLanguage  uint8
	serverStatus    uint16
}

// Init packet reader
func (p *packetInit) read(data []byte) (err os.Error) {
	// Position
	pos := 0
	// Recover from premature EOF
	defer func() {
		if e := recover(); e != nil {
			err = os.NewError(fmt.Sprintf("%v", e))
		}
	}()
	// Protocol version [8 bit uint]
	p.protocolVersion = data[pos]
	pos ++
	// Server version [null terminated string]
	slice, err := p.readSlice(data, pos, 0x00)
	if err != nil {
		return
	}
	p.serverVersion = string(slice)
	pos += len(slice) + 1
	// Thread id [32 bit uint]
	p.threadId = uint32(p.packNumber(data[pos:pos+4]))
	pos += 4
	// First part of scramble buffer [8 bytes]
	p.scrambleBuff = make([]byte, 8)
	p.scrambleBuff = data[pos:pos+8]
	pos += 9
	// Server capabilities [16 bit uint]
	p.serverCaps = uint16(p.packNumber(data[pos:pos+2]))
	pos += 2
	// Server language [8 bit uint]
	p.serverLanguage = data[pos]
	pos ++
	// Server status [16 bit uint]
	p.serverStatus = uint16(p.packNumber(data[pos:pos+2]))
	pos += 15
	// Second part of scramble buffer, if exists (4.1+) [13 bytes]
	if pos < len(data) {
		sBuff := p.scrambleBuff
		p.scrambleBuff = make([]byte, 20)
		copy(p.scrambleBuff[0:8], sBuff)
		copy(p.scrambleBuff[8:20], data[pos:])
	}
	fmt.Printf("This should panic! %#v\n", data[pos+15:pos+20])
	return
}
<commit_msg>remove test line<commit_after>// GoMySQL - A MySQL client library for Go
//
// Copyright 2010-2011 Phil Bayfield. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package mysql

import (
	"os"
	"bytes"
	"fmt"
)

// Packet type identifier
type packetType uint16

// Packet types
const (
	PACKET_INIT        packetType = 1 << iota
	PACKET_AUTH        packetType = 1 << iota
	PACKET_OK          packetType = 1 << iota
	PACKET_ERROR       packetType = 1 << iota
	PACKET_CMD         packetType = 1 << iota
	PACKET_RESULT      packetType = 1 << iota
	PACKET_FIELD       packetType = 1 << iota
	PACKET_ROW         packetType = 1 << iota
	PACKET_EOF         packetType = 1 << iota
	PACKET_OK_PREPARED packetType = 1 << iota
	PACKET_PARAM       packetType = 1 << iota
	PACKET_LONG_DATA   packetType = 1 << iota
	PACKET_EXECUTE     packetType = 1 << iota
	PACKET_ROW_BINARY  packetType = 1 << iota
)

// Readable packet interface
type packetReadable interface {
	read(data []byte) (err os.Error)
}

// Writable packet interface
type packetWriteable interface {
	write() (err os.Error)
}

// Generic packet interface (read/writable)
type packet interface {
	packetReadable
	packetWriteable
}

// Packet base struct
type packetBase struct {
	sequence uint8
}

// Read a slice from the data
func (p *packetBase) readSlice(data []byte, offset int, delim byte) (slice []byte, err os.Error) {
	 pos := bytes.IndexByte(data[offset:], delim)
	 if pos > -1 {
	 	slice = data[offset:pos+offset]
	 } else {
	 	slice = data[offset:]
	 	err = os.EOF
	 }
	 return
}

// Convert byte array into a number
func (p *packetBase) packNumber(data []byte) uint64 {
	num := uint64(0)
	for i := uint8(0); i < uint8(len(data)); i++ {
		num |= uint64(data[i]) << (i * 8)
	}
	return num
}

// Init packet
type packetInit struct {
	packetBase
	protocolVersion uint8
	serverVersion   string
	threadId        uint32
	scrambleBuff    []byte
	serverCaps      uint16
	serverLanguage  uint8
	serverStatus    uint16
}

// Init packet reader
func (p *packetInit) read(data []byte) (err os.Error) {
	// Recover errors
	defer func() {
		if e := recover(); e != nil {
			err = os.NewError(fmt.Sprintf("%s", e))
		}
	}()
	// Position
	pos := 0
	// Protocol version [8 bit uint]
	p.protocolVersion = data[pos]
	pos ++
	// Server version [null terminated string]
	slice, err := p.readSlice(data, pos, 0x00)
	if err != nil {
		return
	}
	p.serverVersion = string(slice)
	pos += len(slice) + 1
	// Thread id [32 bit uint]
	p.threadId = uint32(p.packNumber(data[pos:pos+4]))
	pos += 4
	// First part of scramble buffer [8 bytes]
	p.scrambleBuff = make([]byte, 8)
	p.scrambleBuff = data[pos:pos+8]
	pos += 9
	// Server capabilities [16 bit uint]
	p.serverCaps = uint16(p.packNumber(data[pos:pos+2]))
	pos += 2
	// Server language [8 bit uint]
	p.serverLanguage = data[pos]
	pos ++
	// Server status [16 bit uint]
	p.serverStatus = uint16(p.packNumber(data[pos:pos+2]))
	pos += 15
	// Second part of scramble buffer, if exists (4.1+) [13 bytes]
	if pos < len(data) {
		sBuff := p.scrambleBuff
		p.scrambleBuff = make([]byte, 20)
		copy(p.scrambleBuff[0:8], sBuff)
		copy(p.scrambleBuff[8:20], data[pos:])
	}
	return
}
<|endoftext|>


<commit_before>package roger

import (
	"errors"
	"strconv"

	"github.com/dareid/gore/sexp"
)

type Packet struct {
	cmd     int
	content []byte
	err     error
}

func newPacket(cmd int, content []byte) *Packet {
	return &Packet{
		cmd:     cmd,
		content: content,
	}
}

func newErrorPacket(err error) *Packet {
	return &Packet{
		err: err,
	}
}

func (p *Packet) IsError() bool {
	return p.err != nil || p.cmd&15 == 2
}

func (p *Packet) getStatusCode() int {
	return p.cmd >> 24 & 127
}

func (p *Packet) GetError() error {
	if p.err != nil {
		return p.err
	}
	return errors.New("Command error with status: " + strconv.Itoa(p.getStatusCode()))
}

func (p *Packet) GetResultObject() (interface{}, error) {
	if p.IsError() {
		return nil, p.GetError()
	}
	isSexp := p.content[0] == byte(dtSexp)
	if !isSexp {
		return nil, errors.New("Expected SEXP response")
	}
	return sexp.Parse(p.content[4:len(p.content)], 0)
}
<commit_msg>Adjusting for senseyeio changeover<commit_after>package roger

import (
	"errors"
	"strconv"

	"github.com/senseyeio/roger/sexp"
)

type Packet struct {
	cmd     int
	content []byte
	err     error
}

func newPacket(cmd int, content []byte) *Packet {
	return &Packet{
		cmd:     cmd,
		content: content,
	}
}

func newErrorPacket(err error) *Packet {
	return &Packet{
		err: err,
	}
}

func (p *Packet) IsError() bool {
	return p.err != nil || p.cmd&15 == 2
}

func (p *Packet) getStatusCode() int {
	return p.cmd >> 24 & 127
}

func (p *Packet) GetError() error {
	if p.err != nil {
		return p.err
	}
	return errors.New("Command error with status: " + strconv.Itoa(p.getStatusCode()))
}

func (p *Packet) GetResultObject() (interface{}, error) {
	if p.IsError() {
		return nil, p.GetError()
	}
	isSexp := p.content[0] == byte(dtSexp)
	if !isSexp {
		return nil, errors.New("Expected SEXP response")
	}
	return sexp.Parse(p.content[4:len(p.content)], 0)
}
<|endoftext|>


<commit_before>package pcap

import (
	"encoding/binary"
	"fmt"
	"reflect"
	"strings"
	"time"
)

type PacketTime struct {
	Sec  int32
	Usec int32
}

// Packet is a single packet parsed from a pcap file.
type Packet struct {
	// porting from 'pcap_pkthdr' struct
	Time   time.Time // packet send/receive time
	Caplen uint32    // bytes stored in the file (caplen <= len)
	Len    uint32    // bytes sent/received

	Data []byte // packet data

	Type    int // protocol type, see LINKTYPE_*
	DestMac uint64
	SrcMac  uint64

	Headers []interface{} // decoded headers, in order
	Payload []byte        // remaining non-header bytes
}

// Decode decodes the headers of a Packet.
func (p *Packet) Decode() {

	p.Type = int(binary.BigEndian.Uint16(p.Data[12:14]))
	p.DestMac = decodemac(p.Data[0:6])
	p.SrcMac = decodemac(p.Data[6:12])
	p.Payload = p.Data[14:]

	switch p.Type {
	case TYPE_IP:
		p.decodeIp()
	case TYPE_IP6:
		p.decodeIp6()
	case TYPE_ARP:
		p.decodeArp()
	}
}

func (p *Packet) headerString(headers []interface{}) string {
	// If there's just one header, return that.
	if len(headers) == 1 {
		if hdr, ok := headers[0].(fmt.Stringer); ok {
			return hdr.String()
		}
	}
	// If there are two headers (IPv4/IPv6 -> TCP/UDP/IP..)
	if len(headers) == 2 {
		// Commonly the first header is an address.
		if addr, ok := p.Headers[0].(addrHdr); ok {
			if hdr, ok := p.Headers[1].(addrStringer); ok {
				return fmt.Sprintf("%s %s", p.Time, hdr.String(addr))
			}
		}
	}
	// For IP in IP, we do a recursive call.
	if len(headers) >= 2 {
		if addr, ok := headers[0].(addrHdr); ok {
			if _, ok := headers[1].(addrHdr); ok {
				return fmt.Sprintf("%s > %s IP in IP: ",
					addr.SrcAddr(), addr.DestAddr(), p.headerString(headers[1:]))
			}
		}
	}

	var typeNames []string
	for _, hdr := range headers {
		typeNames = append(typeNames, reflect.TypeOf(hdr).String())
	}

	return fmt.Sprintf("unknown [%s]", strings.Join(typeNames, ","))
}

// String prints a one-line representation of the packet header.
// The output is suitable for use in a tcpdump program.
func (p *Packet) String() string {
	// If there are no headers, print "unsupported protocol".
	if len(p.Headers) == 0 {
		return fmt.Sprintf("%s unsupported protocol %d", p.Time, int(p.Type))
	}
	return fmt.Sprintf("%s %s", p.Time, p.headerString(p.Headers))
}

func (p *Packet) decodeArp() {
	pkt := p.Payload
	arp := new(Arphdr)
	arp.Addrtype = binary.BigEndian.Uint16(pkt[0:2])
	arp.Protocol = binary.BigEndian.Uint16(pkt[2:4])
	arp.HwAddressSize = pkt[4]
	arp.ProtAddressSize = pkt[5]
	arp.Operation = binary.BigEndian.Uint16(pkt[6:8])
	arp.SourceHwAddress = pkt[8 : 8+arp.HwAddressSize]
	arp.SourceProtAddress = pkt[8+arp.HwAddressSize : 8+arp.HwAddressSize+arp.ProtAddressSize]
	arp.DestHwAddress = pkt[8+arp.HwAddressSize+arp.ProtAddressSize : 8+2*arp.HwAddressSize+arp.ProtAddressSize]
	arp.DestProtAddress = pkt[8+2*arp.HwAddressSize+arp.ProtAddressSize : 8+2*arp.HwAddressSize+2*arp.ProtAddressSize]

	p.Headers = append(p.Headers, arp)
	p.Payload = p.Payload[8+2*arp.HwAddressSize+2*arp.ProtAddressSize:]
}

func (p *Packet) decodeIp() {
	if len(p.Payload) < 20 {
		return
	}
	pkt := p.Payload
	ip := new(Iphdr)

	ip.Version = uint8(pkt[0]) >> 4
	ip.Ihl = uint8(pkt[0]) & 0x0F
	ip.Tos = pkt[1]
	ip.Length = binary.BigEndian.Uint16(pkt[2:4])
	ip.Id = binary.BigEndian.Uint16(pkt[4:6])
	flagsfrags := binary.BigEndian.Uint16(pkt[6:8])
	ip.Flags = uint8(flagsfrags >> 13)
	ip.FragOffset = flagsfrags & 0x1FFF
	ip.Ttl = pkt[8]
	ip.Protocol = pkt[9]
	ip.Checksum = binary.BigEndian.Uint16(pkt[10:12])
	ip.SrcIp = pkt[12:16]
	ip.DestIp = pkt[16:20]
	pEnd := int(ip.Length)
	if pEnd > len(pkt) {
		pEnd = len(pkt)
	}
	pIhl := int(ip.Ihl) * 4
	if pIhl > pEnd {
		pIhl = pEnd
	}
	p.Payload = pkt[pIhl:pEnd]
	p.Headers = append(p.Headers, ip)

	switch ip.Protocol {
	case IP_TCP:
		p.decodeTcp()
	case IP_UDP:
		p.decodeUdp()
	case IP_ICMP:
		p.decodeIcmp()
	case IP_INIP:
		p.decodeIp()
	}
}

func (p *Packet) decodeTcp() {
	pLenPayload := len(p.Payload)
	if pLenPayload < 20 {
		return
	}
	pkt := p.Payload
	tcp := new(Tcphdr)
	tcp.Data = pkt
	tcp.SrcPort = binary.BigEndian.Uint16(pkt[0:2])
	tcp.DestPort = binary.BigEndian.Uint16(pkt[2:4])
	tcp.Seq = binary.BigEndian.Uint32(pkt[4:8])
	tcp.Ack = binary.BigEndian.Uint32(pkt[8:12])
	tcp.DataOffset = (pkt[12] & 0xF0) >> 4
	tcp.Flags = binary.BigEndian.Uint16(pkt[12:14]) & 0x1FF
	tcp.Window = binary.BigEndian.Uint16(pkt[14:16])
	tcp.Checksum = binary.BigEndian.Uint16(pkt[16:18])
	tcp.Urgent = binary.BigEndian.Uint16(pkt[18:20])
	pDataOffset := int(tcp.DataOffset * 4)
	if pDataOffset > pLenPayload {
		pDataOffset = pLenPayload
	}
	p.Payload = pkt[pDataOffset:]
	p.Headers = append(p.Headers, tcp)
}

func (p *Packet) decodeUdp() {
	if len(p.Payload) < 8 {
		return
	}
	pkt := p.Payload
	udp := new(Udphdr)
	udp.SrcPort = binary.BigEndian.Uint16(pkt[0:2])
	udp.DestPort = binary.BigEndian.Uint16(pkt[2:4])
	udp.Length = binary.BigEndian.Uint16(pkt[4:6])
	udp.Checksum = binary.BigEndian.Uint16(pkt[6:8])
	p.Headers = append(p.Headers, udp)
	p.Payload = pkt[8:]
}

func (p *Packet) decodeIcmp() *Icmphdr {
	if len(p.Payload) < 8 {
		return nil
	}
	pkt := p.Payload
	icmp := new(Icmphdr)
	icmp.Type = pkt[0]
	icmp.Code = pkt[1]
	icmp.Checksum = binary.BigEndian.Uint16(pkt[2:4])
	icmp.Id = binary.BigEndian.Uint16(pkt[4:6])
	icmp.Seq = binary.BigEndian.Uint16(pkt[6:8])
	p.Payload = pkt[8:]
	p.Headers = append(p.Headers, icmp)
	return icmp
}

func (p *Packet) decodeIp6() {
	if len(p.Payload) < 40 {
		return
	}
	pkt := p.Payload
	ip6 := new(Ip6hdr)
	ip6.Version = uint8(pkt[0]) >> 4
	ip6.TrafficClass = uint8((binary.BigEndian.Uint16(pkt[0:2]) >> 4) & 0x00FF)
	ip6.FlowLabel = binary.BigEndian.Uint32(pkt[0:4]) & 0x000FFFFF
	ip6.Length = binary.BigEndian.Uint16(pkt[4:6])
	ip6.NextHeader = pkt[6]
	ip6.HopLimit = pkt[7]
	ip6.SrcIp = pkt[8:24]
	ip6.DestIp = pkt[24:40]
	p.Payload = pkt[40:]
	p.Headers = append(p.Headers, ip6)

	switch ip6.NextHeader {
	case IP_TCP:
		p.decodeTcp()
	case IP_UDP:
		p.decodeUdp()
	case IP_ICMP:
		p.decodeIcmp()
	case IP_INIP:
		p.decodeIp()
	}
}
<commit_msg>add protection for invalid header<commit_after>package pcap

import (
	"encoding/binary"
	"errors"
	"fmt"
	"reflect"
	"strings"
	"time"
)

type PacketTime struct {
	Sec  int32
	Usec int32
}

// Packet is a single packet parsed from a pcap file.
type Packet struct {
	// porting from 'pcap_pkthdr' struct
	Time   time.Time // packet send/receive time
	Caplen uint32    // bytes stored in the file (caplen <= len)
	Len    uint32    // bytes sent/received

	Data []byte // packet data

	Type    int // protocol type, see LINKTYPE_*
	DestMac uint64
	SrcMac  uint64

	Headers []interface{} // decoded headers, in order
	Payload []byte        // remaining non-header bytes
}

// Decode decodes the headers of a Packet.
func (p *Packet) Decode() error {

	if len(p.Data) <= 14 {
		return errors.New("invalid header")
	}
	p.Type = int(binary.BigEndian.Uint16(p.Data[12:14]))
	p.DestMac = decodemac(p.Data[0:6])
	p.SrcMac = decodemac(p.Data[6:12])
	p.Payload = p.Data[14:]

	switch p.Type {
	case TYPE_IP:
		p.decodeIp()
	case TYPE_IP6:
		p.decodeIp6()
	case TYPE_ARP:
		p.decodeArp()
	}

	return nil
}

func (p *Packet) headerString(headers []interface{}) string {
	// If there's just one header, return that.
	if len(headers) == 1 {
		if hdr, ok := headers[0].(fmt.Stringer); ok {
			return hdr.String()
		}
	}
	// If there are two headers (IPv4/IPv6 -> TCP/UDP/IP..)
	if len(headers) == 2 {
		// Commonly the first header is an address.
		if addr, ok := p.Headers[0].(addrHdr); ok {
			if hdr, ok := p.Headers[1].(addrStringer); ok {
				return fmt.Sprintf("%s %s", p.Time, hdr.String(addr))
			}
		}
	}
	// For IP in IP, we do a recursive call.
	if len(headers) >= 2 {
		if addr, ok := headers[0].(addrHdr); ok {
			if _, ok := headers[1].(addrHdr); ok {
				return fmt.Sprintf("%s > %s IP in IP: ",
					addr.SrcAddr(), addr.DestAddr(), p.headerString(headers[1:]))
			}
		}
	}

	var typeNames []string
	for _, hdr := range headers {
		typeNames = append(typeNames, reflect.TypeOf(hdr).String())
	}

	return fmt.Sprintf("unknown [%s]", strings.Join(typeNames, ","))
}

// String prints a one-line representation of the packet header.
// The output is suitable for use in a tcpdump program.
func (p *Packet) String() string {
	// If there are no headers, print "unsupported protocol".
	if len(p.Headers) == 0 {
		return fmt.Sprintf("%s unsupported protocol %d", p.Time, int(p.Type))
	}
	return fmt.Sprintf("%s %s", p.Time, p.headerString(p.Headers))
}

func (p *Packet) decodeArp() {
	pkt := p.Payload
	arp := new(Arphdr)
	arp.Addrtype = binary.BigEndian.Uint16(pkt[0:2])
	arp.Protocol = binary.BigEndian.Uint16(pkt[2:4])
	arp.HwAddressSize = pkt[4]
	arp.ProtAddressSize = pkt[5]
	arp.Operation = binary.BigEndian.Uint16(pkt[6:8])
	arp.SourceHwAddress = pkt[8 : 8+arp.HwAddressSize]
	arp.SourceProtAddress = pkt[8+arp.HwAddressSize : 8+arp.HwAddressSize+arp.ProtAddressSize]
	arp.DestHwAddress = pkt[8+arp.HwAddressSize+arp.ProtAddressSize : 8+2*arp.HwAddressSize+arp.ProtAddressSize]
	arp.DestProtAddress = pkt[8+2*arp.HwAddressSize+arp.ProtAddressSize : 8+2*arp.HwAddressSize+2*arp.ProtAddressSize]

	p.Headers = append(p.Headers, arp)
	p.Payload = p.Payload[8+2*arp.HwAddressSize+2*arp.ProtAddressSize:]
}

func (p *Packet) decodeIp() {
	if len(p.Payload) < 20 {
		return
	}
	pkt := p.Payload
	ip := new(Iphdr)

	ip.Version = uint8(pkt[0]) >> 4
	ip.Ihl = uint8(pkt[0]) & 0x0F
	ip.Tos = pkt[1]
	ip.Length = binary.BigEndian.Uint16(pkt[2:4])
	ip.Id = binary.BigEndian.Uint16(pkt[4:6])
	flagsfrags := binary.BigEndian.Uint16(pkt[6:8])
	ip.Flags = uint8(flagsfrags >> 13)
	ip.FragOffset = flagsfrags & 0x1FFF
	ip.Ttl = pkt[8]
	ip.Protocol = pkt[9]
	ip.Checksum = binary.BigEndian.Uint16(pkt[10:12])
	ip.SrcIp = pkt[12:16]
	ip.DestIp = pkt[16:20]
	pEnd := int(ip.Length)
	if pEnd > len(pkt) {
		pEnd = len(pkt)
	}
	pIhl := int(ip.Ihl) * 4
	if pIhl > pEnd {
		pIhl = pEnd
	}
	p.Payload = pkt[pIhl:pEnd]
	p.Headers = append(p.Headers, ip)

	switch ip.Protocol {
	case IP_TCP:
		p.decodeTcp()
	case IP_UDP:
		p.decodeUdp()
	case IP_ICMP:
		p.decodeIcmp()
	case IP_INIP:
		p.decodeIp()
	}
}

func (p *Packet) decodeTcp() {
	pLenPayload := len(p.Payload)
	if pLenPayload < 20 {
		return
	}
	pkt := p.Payload
	tcp := new(Tcphdr)
	tcp.Data = pkt
	tcp.SrcPort = binary.BigEndian.Uint16(pkt[0:2])
	tcp.DestPort = binary.BigEndian.Uint16(pkt[2:4])
	tcp.Seq = binary.BigEndian.Uint32(pkt[4:8])
	tcp.Ack = binary.BigEndian.Uint32(pkt[8:12])
	tcp.DataOffset = (pkt[12] & 0xF0) >> 4
	tcp.Flags = binary.BigEndian.Uint16(pkt[12:14]) & 0x1FF
	tcp.Window = binary.BigEndian.Uint16(pkt[14:16])
	tcp.Checksum = binary.BigEndian.Uint16(pkt[16:18])
	tcp.Urgent = binary.BigEndian.Uint16(pkt[18:20])
	pDataOffset := int(tcp.DataOffset * 4)
	if pDataOffset > pLenPayload {
		pDataOffset = pLenPayload
	}
	p.Payload = pkt[pDataOffset:]
	p.Headers = append(p.Headers, tcp)
}

func (p *Packet) decodeUdp() {
	if len(p.Payload) < 8 {
		return
	}
	pkt := p.Payload
	udp := new(Udphdr)
	udp.SrcPort = binary.BigEndian.Uint16(pkt[0:2])
	udp.DestPort = binary.BigEndian.Uint16(pkt[2:4])
	udp.Length = binary.BigEndian.Uint16(pkt[4:6])
	udp.Checksum = binary.BigEndian.Uint16(pkt[6:8])
	p.Headers = append(p.Headers, udp)
	p.Payload = pkt[8:]
}

func (p *Packet) decodeIcmp() *Icmphdr {
	if len(p.Payload) < 8 {
		return nil
	}
	pkt := p.Payload
	icmp := new(Icmphdr)
	icmp.Type = pkt[0]
	icmp.Code = pkt[1]
	icmp.Checksum = binary.BigEndian.Uint16(pkt[2:4])
	icmp.Id = binary.BigEndian.Uint16(pkt[4:6])
	icmp.Seq = binary.BigEndian.Uint16(pkt[6:8])
	p.Payload = pkt[8:]
	p.Headers = append(p.Headers, icmp)
	return icmp
}

func (p *Packet) decodeIp6() {
	if len(p.Payload) < 40 {
		return
	}
	pkt := p.Payload
	ip6 := new(Ip6hdr)
	ip6.Version = uint8(pkt[0]) >> 4
	ip6.TrafficClass = uint8((binary.BigEndian.Uint16(pkt[0:2]) >> 4) & 0x00FF)
	ip6.FlowLabel = binary.BigEndian.Uint32(pkt[0:4]) & 0x000FFFFF
	ip6.Length = binary.BigEndian.Uint16(pkt[4:6])
	ip6.NextHeader = pkt[6]
	ip6.HopLimit = pkt[7]
	ip6.SrcIp = pkt[8:24]
	ip6.DestIp = pkt[24:40]
	p.Payload = pkt[40:]
	p.Headers = append(p.Headers, ip6)

	switch ip6.NextHeader {
	case IP_TCP:
		p.decodeTcp()
	case IP_UDP:
		p.decodeUdp()
	case IP_ICMP:
		p.decodeIcmp()
	case IP_INIP:
		p.decodeIp()
	}
}
<|endoftext|>


<commit_before>package hcl2template

import (
	"bytes"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"os/exec"

	"github.com/hashicorp/hcl/v2"
	"github.com/hashicorp/hcl/v2/hclparse"
	"github.com/hashicorp/hcl/v2/hclwrite"
)

type HCL2Formatter struct {
	ShowDiff, Write bool
	Output          io.Writer
	parser          *hclparse.Parser
}

// NewHCL2Formatter creates a new formatter, ready to format configuration files.
func NewHCL2Formatter() *HCL2Formatter {
	return &HCL2Formatter{
		parser: hclparse.NewParser(),
	}
}

// Format all HCL2 files in path and return the total bytes formatted.
// If any error is encountered, zero bytes will be returned.
//
// Path can be a directory or a file.
func (f *HCL2Formatter) Format(path string) (int, hcl.Diagnostics) {

	var allHclFiles []string
	var diags []*hcl.Diagnostic

	if path == "-" {
		allHclFiles = []string{"-"}
	} else {
		hclFiles, _, diags := GetHCL2Files(path, hcl2FileExt, hcl2JsonFileExt)
		if diags.HasErrors() {
			return 0, diags
		}

		hclVarFiles, _, diags := GetHCL2Files(path, hcl2VarFileExt, hcl2VarJsonFileExt)
		if diags.HasErrors() {
			return 0, diags
		}

		allHclFiles = append(hclFiles, hclVarFiles...)

		if len(allHclFiles) == 0 {
			diags = append(diags, &hcl.Diagnostic{
				Severity: hcl.DiagError,
				Summary:  fmt.Sprintf("Cannot tell whether %s contains HCL2 configuration data", path),
			})

			return 0, diags
		}
	}

	if f.parser == nil {
		f.parser = hclparse.NewParser()
	}

	var bytesModified int
	for _, fn := range allHclFiles {
		data, err := f.processFile(fn)
		if err != nil {
			diags = append(diags, &hcl.Diagnostic{
				Severity: hcl.DiagError,
				Summary:  fmt.Sprintf("encountered an error while formatting %s", fn),
				Detail:   err.Error(),
			})
		}
		bytesModified += len(data)
	}

	return bytesModified, diags
}

// processFile formats the source contents of filename and return the formatted data.
// overwriting the contents of the original when the f.Write is true; a diff of the changes
// will be outputted if f.ShowDiff is true.
func (f *HCL2Formatter) processFile(filename string) ([]byte, error) {
	if f.Output == nil {
		f.Output = os.Stdout
	}

	var in io.Reader
	var err error

	if filename == "-" {
		in = os.Stdin
		f.ShowDiff = false
	} else {
		in, err = os.Open(filename)
		if err != nil {
			return nil, fmt.Errorf("failed to open %s: %s", filename, err)
		}
	}

	inSrc, err := ioutil.ReadAll(in)
	if err != nil {
		return nil, fmt.Errorf("failed to read %s: %s", filename, err)
	}

	_, diags := f.parser.ParseHCL(inSrc, filename)
	if diags.HasErrors() {
		return nil, fmt.Errorf("failed to parse HCL %s", filename)
	}

	outSrc := hclwrite.Format(inSrc)

	if bytes.Equal(inSrc, outSrc) {
		return nil, nil
	}

	s := []byte(fmt.Sprintf("%s\n", filename))
	_, _ = f.Output.Write(s)

	if f.Write {
		if filename == "-" {
			_, _ = f.Output.Write(outSrc)
		} else {
			if err := ioutil.WriteFile(filename, outSrc, 0644); err != nil {
				return nil, err
			}
		}
	}

	if f.ShowDiff {
		diff, err := bytesDiff(inSrc, outSrc, filename)
		if err != nil {
			return outSrc, fmt.Errorf("failed to generate diff for %s: %s", filename, err)
		}
		_, _ = f.Output.Write(diff)
	}

	return outSrc, nil
}

// bytesDiff returns the unified diff of b1 and b2
// Shamelessly copied from Terraform's fmt command.
func bytesDiff(b1, b2 []byte, path string) (data []byte, err error) {
	f1, err := ioutil.TempFile("", "")
	if err != nil {
		return
	}
	defer os.Remove(f1.Name())
	defer f1.Close()

	f2, err := ioutil.TempFile("", "")
	if err != nil {
		return
	}
	defer os.Remove(f2.Name())
	defer f2.Close()

	_, _ = f1.Write(b1)
	_, _ = f2.Write(b2)

	data, err = exec.Command("diff", "--label=old/"+path, "--label=new/"+path, "-u", f1.Name(), f2.Name()).CombinedOutput()
	if len(data) > 0 {
		// diff exits with a non-zero status when the files don't match.
		// Ignore that failure as long as we get output.
		err = nil
	}
	return
}
<commit_msg>dont print filename if its reading from stdin<commit_after>package hcl2template

import (
	"bytes"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"os/exec"

	"github.com/hashicorp/hcl/v2"
	"github.com/hashicorp/hcl/v2/hclparse"
	"github.com/hashicorp/hcl/v2/hclwrite"
)

type HCL2Formatter struct {
	ShowDiff, Write bool
	Output          io.Writer
	parser          *hclparse.Parser
}

// NewHCL2Formatter creates a new formatter, ready to format configuration files.
func NewHCL2Formatter() *HCL2Formatter {
	return &HCL2Formatter{
		parser: hclparse.NewParser(),
	}
}

// Format all HCL2 files in path and return the total bytes formatted.
// If any error is encountered, zero bytes will be returned.
//
// Path can be a directory or a file.
func (f *HCL2Formatter) Format(path string) (int, hcl.Diagnostics) {

	var allHclFiles []string
	var diags []*hcl.Diagnostic

	if path == "-" {
		allHclFiles = []string{"-"}
	} else {
		hclFiles, _, diags := GetHCL2Files(path, hcl2FileExt, hcl2JsonFileExt)
		if diags.HasErrors() {
			return 0, diags
		}

		hclVarFiles, _, diags := GetHCL2Files(path, hcl2VarFileExt, hcl2VarJsonFileExt)
		if diags.HasErrors() {
			return 0, diags
		}

		allHclFiles = append(hclFiles, hclVarFiles...)

		if len(allHclFiles) == 0 {
			diags = append(diags, &hcl.Diagnostic{
				Severity: hcl.DiagError,
				Summary:  fmt.Sprintf("Cannot tell whether %s contains HCL2 configuration data", path),
			})

			return 0, diags
		}
	}

	if f.parser == nil {
		f.parser = hclparse.NewParser()
	}

	var bytesModified int
	for _, fn := range allHclFiles {
		data, err := f.processFile(fn)
		if err != nil {
			diags = append(diags, &hcl.Diagnostic{
				Severity: hcl.DiagError,
				Summary:  fmt.Sprintf("encountered an error while formatting %s", fn),
				Detail:   err.Error(),
			})
		}
		bytesModified += len(data)
	}

	return bytesModified, diags
}

// processFile formats the source contents of filename and return the formatted data.
// overwriting the contents of the original when the f.Write is true; a diff of the changes
// will be outputted if f.ShowDiff is true.
func (f *HCL2Formatter) processFile(filename string) ([]byte, error) {
	if f.Output == nil {
		f.Output = os.Stdout
	}

	var in io.Reader
	var err error

	if filename == "-" {
		in = os.Stdin
		f.ShowDiff = false
	} else {
		in, err = os.Open(filename)
		if err != nil {
			return nil, fmt.Errorf("failed to open %s: %s", filename, err)
		}
	}

	inSrc, err := ioutil.ReadAll(in)
	if err != nil {
		return nil, fmt.Errorf("failed to read %s: %s", filename, err)
	}

	_, diags := f.parser.ParseHCL(inSrc, filename)
	if diags.HasErrors() {
		return nil, fmt.Errorf("failed to parse HCL %s", filename)
	}

	outSrc := hclwrite.Format(inSrc)

	if bytes.Equal(inSrc, outSrc) {
		return nil, nil
	}

	if filename != "-" {
		s := []byte(fmt.Sprintf("%s\n", filename))
		_, _ = f.Output.Write(s)
	}

	if f.Write {
		if filename == "-" {
			_, _ = f.Output.Write(outSrc)
		} else {
			if err := ioutil.WriteFile(filename, outSrc, 0644); err != nil {
				return nil, err
			}
		}
	}

	if f.ShowDiff {
		diff, err := bytesDiff(inSrc, outSrc, filename)
		if err != nil {
			return outSrc, fmt.Errorf("failed to generate diff for %s: %s", filename, err)
		}
		_, _ = f.Output.Write(diff)
	}

	return outSrc, nil
}

// bytesDiff returns the unified diff of b1 and b2
// Shamelessly copied from Terraform's fmt command.
func bytesDiff(b1, b2 []byte, path string) (data []byte, err error) {
	f1, err := ioutil.TempFile("", "")
	if err != nil {
		return
	}
	defer os.Remove(f1.Name())
	defer f1.Close()

	f2, err := ioutil.TempFile("", "")
	if err != nil {
		return
	}
	defer os.Remove(f2.Name())
	defer f2.Close()

	_, _ = f1.Write(b1)
	_, _ = f2.Write(b2)

	data, err = exec.Command("diff", "--label=old/"+path, "--label=new/"+path, "-u", f1.Name(), f2.Name()).CombinedOutput()
	if len(data) > 0 {
		// diff exits with a non-zero status when the files don't match.
		// Ignore that failure as long as we get output.
		err = nil
	}
	return
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"io"
	"strconv"
)

var (
	// stack is used to store variable names and values.
	stack map[string]Value
)

func init() {
	stack = make(map[string]Value)
}

// Parser represents a parser.
type Parser struct {
	s   *Scanner
	buf struct {
		t   Token  // last read token
		lit string // last read literal
		n   int    // buffer size (max=1)
	}
}

// NewParser returns a new instance of Parser.
func NewParser(r io.Reader) *Parser {
	return &Parser{s: NewScanner(r)}
}

// scan returns the next token from the underlying scanner.
// if a token has been unscanned then read that instead.
func (p *Parser) scan() (t Token, lit string) {

	if p.buf.n != 0 {
		p.buf.n = 0
		return p.buf.t, p.buf.lit
	}

	t, lit = p.s.Scan()

	p.buf.t, p.buf.lit = t, lit
	return
}

// unscan pushes the previously read token back onto the buffer.
func (p *Parser) unscan() { p.buf.n = 1 }

// scanIgnoreWhitespace scans the next non-whitespace token.
func (p *Parser) scanIgnoreWhitespace() (t Token, lit string) {
	t, lit = p.scan()
	if t == Space {
		t, lit = p.scan()
	}
	return
}

func (p *Parser) numberOrVector() Value {
	_, lit := p.scanIgnoreWhitespace()

	var vector Vector
	vector = append(vector, ValueParse(lit))

	for {
		// Read a field.
		tok, lit := p.scanIgnoreWhitespace()
		if tok != Number {
			p.unscan()
			break
		}

		v := ValueParse(lit)
		vector = append(vector, Expression(v))
	}

	// todo(santiaago) do we need this?
	if len(vector) == 1 {
		return vector[0]
	}
	return vector
}

// Expression is the interface for an expression.
type Expression interface {
	String() string
	Evaluate() Value
}

// Statement represents a code statement a = 2.
type Statement struct {
	Left  Value
	Right Value
}

// String retuns the statement as a string.
func (s Statement) String() string {
	return fmt.Sprintf("%v%v", s.Left, s.Right)
}

// Evaluate evaluates the given statement.
func (s Statement) Evaluate() Value {
	// todo(santiaago): need to think what this should really do..
	return s.Left
}

// Num represents a number statement.
type Num struct {
	n string
}

// String returns the string of the number
func (n Num) String() string {
	return fmt.Sprintf("%v", n.n)
}

// Evaluate returns the number value
func (n Num) Evaluate() Value {
	return n
}

// Value is an interface to handle different types.
type Value interface {
	String() string
	Evaluate() Value
}

// Int is a type to handle integers
type Int int64

// String returns the string representation of an integer.
func (i Int) String() string {
	return fmt.Sprintf("%d", i)
}

// Evaluate returns the value of the given integer.
func (i Int) Evaluate() Value {
	return i
}

func tryIntString(s string) (Value, error) {
	i, err := strconv.ParseInt(s, 10, 64)
	return Int(i), err
}

// Vector is a type to handle vectors
type Vector []Value

// String returns the string representation of a vector
func (v Vector) String() string {
	ret := ""
	for i := range v {
		ret += fmt.Sprintf("%v ", v[i])
	}
	ret += fmt.Sprintf("\n")
	return ret
}

// Evaluate returns the value of a given vector.
func (v Vector) Evaluate() Value {
	return v
}

// Variable represents a variable.
type Variable struct {
	name string
}

// String returns the string representation of a variable.
func (v Variable) String() string {
	return v.name
}

// Evaluate returns the value holded by the variable v
func (v Variable) Evaluate() Value {
	if val, ok := stack[v.name]; ok {
		return val
	}
	return nil
}

// Binary represents a binary statement
// example: 12 + 3
type Binary struct {
	Left     Value
	Right    Value
	Operator string
}

// String returns the string of the number
func (b Binary) String() string {
	return fmt.Sprintf("%v %v %v", b.Left, b.Operator, b.Right)
}

// Evaluate returns the number value
func (b Binary) Evaluate() Value {
	if b.Operator == "+" {
		return add(b.Left, b.Right)
	} else if b.Operator == "-" {
		return minus(b.Left, b.Right)
	} else if b.Operator == "*" {
		return times(b.Left, b.Right)
	}
	return nil
}

func add(a, b Value) Value {
	// todo(santiaago): will have to check types at some point
	return Int(a.(Int) + b.(Int))
}

func minus(a, b Value) Value {
	// todo(santiaago): will have to check types at some point
	return Int(a.(Int) - b.(Int))
}

func times(a, b Value) Value {
	// todo(santiaago): will have to check types at some point
	return Int(a.(Int) * b.(Int))
}

// ValueParse parse the string in the proper value
// todo(santiaago): will have to try different types here...
func ValueParse(s string) Value {
	v, err := tryIntString(s)
	if err != nil {
		fmt.Println(err)
		return nil
	}
	return v
}

// Parse parse a assign statement a = b
func (p *Parser) Parse() (*Expression, error) {

	var numberOfVector Value

	// First token can be an identifier or number (for now)
	var left, right, operator string
	tok, lit := p.scanIgnoreWhitespace()
	lastTok := tok
	if tok == Identifier {
		left = lit
	} else if tok == Number {
		p.unscan()
		numberOfVector = p.numberOrVector()
	} else {
		return nil, fmt.Errorf("found %q, expected left", lit)
	}

	// Next it could be EOF, an operator or an assignment (for now)
	tok, lit = p.scanIgnoreWhitespace()
	if tok == EOF {
		if lastTok == Number {
			e := Expression(numberOfVector)
			return &e, nil
		} else if lastTok == Identifier {
			expr := Expression(Variable{name: left})
			if expr.Evaluate() == nil {
				return nil, fmt.Errorf("ERROR")
			}
			return &expr, nil
		} else {
			fmt.Println("jump", lastTok)
		}
	}

	isOperator := tok == Operator
	isAssign := tok == Assign
	if !isAssign && !isOperator {
		return nil, fmt.Errorf("found %q, expected '=' with tok: %v, expected %v", lit, tok, Assign)
	}

	if isOperator {
		operator = lit
	}

	// Next: Take care of assign case.
	if isAssign {
		tok, lit = p.scanIgnoreWhitespace()
		if tok == Number {
			// todo(santiaago):
			// we should print an error here if left is a number and not a variable
			stack[left] = ValueParse(lit)
			expr := Expression(Variable{name: left})
			return &expr, nil
		}
		right = lit
		var expr Expression
		var r Value
		if val, ok := stack[right]; ok {
			r = val
		} else {
			r = ValueParse(right)
		}
		stack[left] = r
		expr = Expression(Variable{name: left})
		return &expr, nil
	}

	// Next: Take care of operator case.
	// We should loop over all our operators.
	// todo(santiaago): need to handle vector operations ..
	var terms []string
	var operators []string

	// Initialize arrays with first term and first operator.
	terms = append(terms, left)
	operators = append(operators, operator)

	for {
		// Read a field.
		tok, lit = p.scanIgnoreWhitespace()
		if tok != Identifier && tok != Number {
			return nil, fmt.Errorf("found %q, expected number or identifier", lit)
		}
		terms = append(terms, lit)
		// Read operator
		tok, lit = p.scanIgnoreWhitespace()
		// If the next token is not an operator then break the loop
		if tok != Operator {
			p.unscan()
			break
		}
		operators = append(operators, lit)
	}

	// At this point we have terms and, operators.
	// We need now to process all of this.
	return buildOperatorExpression(terms, operators)
}

// At this point we have the following
// left, operator, terms, operators
// we need now to process all of this.
func buildOperatorExpression(terms, operators []string) (*Expression, error) {

	if len(terms)-1 != len(operators) {
		return nil, fmt.Errorf("ERROR terms and operators size mismatch")
	}

	var cumulExpr Expression

	first := terms[0]
	if _, ok := stack[first]; ok {
		cumulExpr = Expression(Variable{name: first})
	} else {
		cumulExpr = Expression(ValueParse(first))
	}

	for i := 0; i < len(operators); i++ {

		right := terms[i+1]
		op := operators[i]

		var r Value
		if val, ok := stack[right]; ok {
			r = val
		} else {
			r = ValueParse(right)
		}
		cumulExpr = Expression(Binary{Left: cumulExpr.Evaluate(), Right: r, Operator: op})
	}
	return &cumulExpr, nil
}
<commit_msg>Add vector logic<commit_after>package main

import (
	"fmt"
	"io"
	"strconv"
)

var (
	// stack is used to store variable names and values.
	stack map[string]Value
)

func init() {
	stack = make(map[string]Value)
}

// Parser represents a parser.
type Parser struct {
	s   *Scanner
	buf struct {
		t   Token  // last read token
		lit string // last read literal
		n   int    // buffer size (max=1)
	}
}

// NewParser returns a new instance of Parser.
func NewParser(r io.Reader) *Parser {
	return &Parser{s: NewScanner(r)}
}

// scan returns the next token from the underlying scanner.
// if a token has been unscanned then read that instead.
func (p *Parser) scan() (t Token, lit string) {

	if p.buf.n != 0 {
		p.buf.n = 0
		return p.buf.t, p.buf.lit
	}

	t, lit = p.s.Scan()

	p.buf.t, p.buf.lit = t, lit
	return
}

// unscan pushes the previously read token back onto the buffer.
func (p *Parser) unscan() { p.buf.n = 1 }

// scanIgnoreWhitespace scans the next non-whitespace token.
func (p *Parser) scanIgnoreWhitespace() (t Token, lit string) {
	t, lit = p.scan()
	if t == Space {
		t, lit = p.scan()
	}
	return
}

func (p *Parser) numberOrVector() Value {
	_, lit := p.scanIgnoreWhitespace()
	var vector Vector
	vector = append(vector, ValueParse(lit))

	for {
		// Read a field.
		tok, lit := p.scanIgnoreWhitespace()
		if tok != Number {
			p.unscan()
			break
		}
		v := ValueParse(lit)
		vector = append(vector, v)
	}

	// todo(santiaago) do we need this?
	if len(vector) == 1 {
		return vector[0]
	}
	return vector
}

// Expression is the interface for an expression.
type Expression interface {
	String() string
	Evaluate() Value
}

// Statement represents a code statement a = 2.
type Statement struct {
	Left  Value
	Right Value
}

// String retuns the statement as a string.
func (s Statement) String() string {
	return fmt.Sprintf("%v%v", s.Left, s.Right)
}

// Evaluate evaluates the given statement.
func (s Statement) Evaluate() Value {
	// todo(santiaago): need to think what this should really do..
	return s.Left
}

// Num represents a number statement.
type Num struct {
	n string
}

// String returns the string of the number
func (n Num) String() string {
	return fmt.Sprintf("%v", n.n)
}

// Evaluate returns the number value
func (n Num) Evaluate() Value {
	return n
}

// Value is an interface to handle different types.
type Value interface {
	String() string
	Evaluate() Value
}

// Int is a type to handle integers
type Int int64

// String returns the string representation of an integer.
func (i Int) String() string {
	return fmt.Sprintf("%d", i)
}

// Evaluate returns the value of the given integer.
func (i Int) Evaluate() Value {
	return i
}

func tryIntString(s string) (Value, error) {
	i, err := strconv.ParseInt(s, 10, 64)
	return Int(i), err
}

// Vector is a type to handle vectors
type Vector []Value

// String returns the string representation of a vector
func (v Vector) String() string {
	ret := ""
	for i := range v {
		ret += fmt.Sprintf("%v ", v[i])
	}
	ret += fmt.Sprintf("\n")
	return ret
}

// Evaluate returns the value of a given vector.
func (v Vector) Evaluate() Value {
	return v
}

// Variable represents a variable.
type Variable struct {
	name string
}

// String returns the string representation of a variable.
func (v Variable) String() string {
	return v.name
}

// Evaluate returns the value holded by the variable v
func (v Variable) Evaluate() Value {
	if val, ok := stack[v.name]; ok {
		return val
	}
	return nil
}

// Binary represents a binary statement
// example: 12 + 3
type Binary struct {
	Left     Value
	Right    Value
	Operator string
}

// String returns the string of the number
func (b Binary) String() string {
	return fmt.Sprintf("%v %v %v", b.Left, b.Operator, b.Right)
}

// Evaluate returns the number value
func (b Binary) Evaluate() Value {
	if b.Operator == "+" {
		return add(b.Left, b.Right)
	} else if b.Operator == "-" {
		return minus(b.Left, b.Right)
	} else if b.Operator == "*" {
		return times(b.Left, b.Right)
	}
	return nil
}

func add(a, b Value) Value {
	// todo(santiaago): will have to check types at some point
	return Int(a.(Int) + b.(Int))
}

func minus(a, b Value) Value {
	// todo(santiaago): will have to check types at some point
	return Int(a.(Int) - b.(Int))
}

func times(a, b Value) Value {
	// todo(santiaago): will have to check types at some point
	return Int(a.(Int) * b.(Int))
}

// ValueParse parse the string in the proper value
// todo(santiaago): will have to try different types here...
func ValueParse(s string) Value {
	v, err := tryIntString(s)
	if err != nil {
		fmt.Printf("failed to parse %v got error: %v\n", s, err)
		return nil
	}
	return v
}

// Parse parse a assign statement a = b
func (p *Parser) Parse() (*Expression, error) {

	var numberOfVector Value

	// First token can be an identifier or number (for now)
	var left, right, operator string
	tok, lit := p.scanIgnoreWhitespace()
	lastTok := tok
	if tok == Identifier {
		left = lit
	} else if tok == Number {
		p.unscan()
		numberOfVector = p.numberOrVector()
	} else {
		return nil, fmt.Errorf("found %q, expected left", lit)
	}

	// Next it could be EOF, an operator or an assignment (for now)
	tok, lit = p.scanIgnoreWhitespace()
	if tok == EOF {
		if lastTok == Number {
			e := Expression(numberOfVector)
			return &e, nil
		} else if lastTok == Identifier {
			expr := Expression(Variable{name: left})
			if expr.Evaluate() == nil {
				return nil, fmt.Errorf("ERROR")
			}
			return &expr, nil
		} else {
			fmt.Println("Not a number or identifier ", lastTok)
		}
	}

	isOperator := tok == Operator
	isAssign := tok == Assign
	if !isAssign && !isOperator {
		return nil, fmt.Errorf("found %q, expected '=' with tok: %v, expected %v", lit, tok, Assign)
	}

	if isOperator {
		operator = lit
	}

	// Next: Take care of assign case.
	if isAssign {
		tok, lit = p.scanIgnoreWhitespace()
		if tok == Number {
			// todo(santiaago):
			// we should print an error here if left is a number and not a variable
			stack[left] = ValueParse(lit)
			expr := Expression(Variable{name: left})
			return &expr, nil
		}
		right = lit
		var expr Expression
		var r Value
		if val, ok := stack[right]; ok {
			r = val
		} else {
			r = ValueParse(right)
		}
		stack[left] = r
		expr = Expression(Variable{name: left})
		return &expr, nil
	}

	// Next: Take care of operator case.
	// We should loop over all our operators.
	// todo(santiaago): need to handle vector operations ..
	var terms []Value
	var operators []string

	// Initialize arrays with first term and first operator.
	terms = append(terms, numberOfVector)
	operators = append(operators, operator)

	for {
		// Read a field.
		tok, lit = p.scanIgnoreWhitespace()
		if tok != Identifier && tok != Number {
			return nil, fmt.Errorf("found %q, expected number or identifier", lit)
		}
		p.unscan()
		term := p.numberOrVector()
		terms = append(terms, term)
		// Read operator
		tok, lit = p.scanIgnoreWhitespace()
		// If the next token is not an operator then break the loop
		if tok != Operator {
			p.unscan()
			break
		}
		operators = append(operators, lit)
	}

	// At this point we have terms and, operators.
	// We need now to process all of this.
	return buildOperatorExpression(terms, operators)
}

// At this point we have the following
// left, operator, terms, operators
// we need now to process all of this.
func buildOperatorExpression(terms []Value, operators []string) (*Expression, error) {

	if len(terms)-1 != len(operators) {
		return nil, fmt.Errorf("ERROR terms and operators size mismatch")
	}

	var cumulExpr Expression
	first := terms[0]
	// todo(santiaago):
	// you should be able to do:
	//     a = 1
	//     1 2 a
	// 1 2 1
	// This means that a vector can also contain identifiers.
	// we will ignore that case for now, we will only work with vector of numbers.
	// if _, ok := stack[first]; ok {
	// 	cumulExpr = Expression(Variable{name: first})
	// } else {
	cumulExpr = first
	//}

	for i := 0; i < len(operators); i++ {

		right := terms[i+1]
		op := operators[i]

		var r Value
		// if val, ok := stack[right]; ok {
		// 	r = val
		// } else {
		r = right.(Int)
		//}
		b := Binary{Left: cumulExpr.Evaluate(), Right: r, Operator: op}
		cumulExpr = Expression(b)
	}
	return &cumulExpr, nil
}
<|endoftext|>


<commit_before>package goparsify

import (
	"fmt"
	"regexp"
	"strings"
	"unicode/utf8"
)

// Parser is the workhorse of parsify. A parser takes a State and returns a result, consuming some
// of the State in the process.
// Given state is shared there are a few rules that should be followed:
//  - A parser that errors must set state.Error
//  - A parser that errors must not change state.Pos
//  - A parser that consumed some input should advance state.Pos
type Parser func(*State, *Result)

// Map shorthand for Map(p, func())
func (p Parser) Map(f func(n *Result)) Parser {
	return Map(p, f)
}

// VoidParser is a special type of parser that never returns anything but can still consume input
type VoidParser func(*State)

// Parserish types are any type that can be turned into a Parser by Parsify
// These currently include *Parser and string literals.
//
// This makes recursive grammars cleaner and allows string literals to be used directly in most contexts.
// eg, matching balanced paren:
//  var group Parser
//  group = Seq("(", Maybe(&group), ")")
// vs
//  var group ParserPtr{}
//  group.P = Seq(Exact("("), Maybe(group.Parse), Exact(")"))
type Parserish interface{}

// Parsify takes a Parserish and makes a Parser out of it. It should be called by
// any Parser that accepts a Parser as an argument. It should never be called during
// instead call it during parser creation so there is no runtime cost.
//
// See Parserish for details.
func Parsify(p Parserish) Parser {
	switch p := p.(type) {
	case func(*State, *Result):
		return p
	case Parser:
		return p
	case *Parser:
		// Todo: Maybe capture this stack and on nil show it? Is there a good error library to do this?
		return func(ptr *State, node *Result) {
			(*p)(ptr, node)
		}
	case string:
		return Exact(p)
	case func(*State):
		return func(ptr *State, node *Result) {
			p(ptr)
		}
	default:
		panic(fmt.Errorf("cant turn a `%T` into a parser", p))
	}
}

// ParsifyAll calls Parsify on all parsers
func ParsifyAll(parsers ...Parserish) []Parser {
	ret := make([]Parser, len(parsers))
	for i, parser := range parsers {
		ret[i] = Parsify(parser)
	}
	return ret
}

// Run applies some input to a parser and returns the result, failing if the input isnt fully consumed.
// It is a convenience method for the most common way to invoke a parser.
func Run(parser Parserish, input string, ws ...VoidParser) (result interface{}, err error) {
	p := Parsify(parser)
	ps := NewState(input)
	if len(ws) > 0 {
		ps.WS = ws[0]
	}

	ret := Result{}
	p(ps, &ret)
	ps.WS(ps)

	if ps.Error.expected != "" {
		return ret.Result, &ps.Error
	}

	if ps.Get() != "" {
		return ret.Result, UnparsedInputError{ps.Get()}
	}

	return ret.Result, nil
}

// Cut prevents backtracking beyond this point. Usually used after keywords when you
// are sure this is the correct path. Improves performance and error reporting.
func Cut() Parser {
	return func(ps *State, node *Result) {
		ps.Cut = ps.Pos
	}
}

// Regex returns a match if the regex successfully matches
func Regex(pattern string) Parser {
	re := regexp.MustCompile("^" + pattern)
	return NewParser(pattern, func(ps *State, node *Result) {
		ps.WS(ps)
		if match := re.FindString(ps.Get()); match != "" {
			ps.Advance(len(match))
			node.Token = match
			return
		}
		ps.ErrorHere(pattern)
	})
}

// Exact will fully match the exact string supplied, or error. The match will be stored in .Token
func Exact(match string) Parser {
	if len(match) == 1 {
		matchByte := match[0]
		return NewParser(match, func(ps *State, node *Result) {
			ps.WS(ps)
			if ps.Pos >= len(ps.Input) || ps.Input[ps.Pos] != matchByte {
				ps.ErrorHere(match)
				return
			}

			ps.Advance(1)

			node.Token = match
		})
	}

	return NewParser(match, func(ps *State, node *Result) {
		ps.WS(ps)
		if !strings.HasPrefix(ps.Get(), match) {
			ps.ErrorHere(match)
			return
		}

		ps.Advance(len(match))

		node.Token = match
	})
}

func parseRepetition(defaultMin, defaultMax int, repetition ...int) (min int, max int) {
	min = defaultMin
	max = defaultMax
	switch len(repetition) {
	case 0:
	case 1:
		min = repetition[0]
	case 2:
		min = repetition[0]
		max = repetition[1]
	default:
		panic(fmt.Errorf("Dont know what %d repetition args mean", len(repetition)))
	}
	return min, max
}

// parseMatcher turns a string in the format a-f01234A-F into:
//   - an alphabet of matches string(01234)
//   - a set of ranges [][]rune{{'a', 'f'}, {'A', 'F'}}
func parseMatcher(matcher string) (alphabet string, ranges [][]rune) {
	runes := []rune(matcher)

	for i := 0; i < len(runes); i++ {

		if i+2 < len(runes) && runes[i+1] == '-' && runes[i] != '\\' {
			start := runes[i]
			end := runes[i+2]
			if start <= end {
				ranges = append(ranges, []rune{start, end})
			} else {
				ranges = append(ranges, []rune{end, start})
			}
		} else if i+1 < len(runes) && runes[i] == '\\' {
			alphabet += string(runes[i+1])
		} else if runes[i] == '-' {
			continue
		} else {
			alphabet += string(runes[i])
		}

	}

	return alphabet, ranges
}

// Chars is the swiss army knife of character matches. It can match:
//  - ranges: Chars("a-z") will match one or more lowercase letter
//  - alphabets: Chars("abcd") will match one or more of the letters abcd in any order
//  - min and max: Chars("a-z0-9", 4, 6) will match 4-6 lowercase alphanumeric characters
// the above can be combined in any order
func Chars(matcher string, repetition ...int) Parser {
	return NewParser("["+matcher+"]", charsImpl(matcher, false, repetition...))
}

// NotChars accepts the full range of input from Chars, but it will stop when any
// character matches. If you need to match until you see a sequence use Until instead
func NotChars(matcher string, repetition ...int) Parser {
	return NewParser("!["+matcher+"]", charsImpl(matcher, true, repetition...))
}

func charsImpl(matcher string, stopOn bool, repetition ...int) Parser {
	min, max := parseRepetition(1, -1, repetition...)
	alphabet, ranges := parseMatcher(matcher)

	return func(ps *State, node *Result) {
		ps.WS(ps)
		matched := 0
		for ps.Pos+matched < len(ps.Input) {
			if max != -1 && matched >= max {
				break
			}

			r, w := utf8.DecodeRuneInString(ps.Input[ps.Pos+matched:])

			anyMatched := strings.ContainsRune(alphabet, r)
			if !anyMatched {
				for _, rng := range ranges {
					if r >= rng[0] && r <= rng[1] {
						anyMatched = true
					}
				}
			}

			if anyMatched == stopOn {
				break
			}

			matched += w
		}

		if matched < min {
			ps.ErrorHere(matcher)
			return
		}

		node.Token = ps.Input[ps.Pos : ps.Pos+matched]
		ps.Advance(matched)
	}
}

// Until will consume all input until one of the given terminator sequences is found. If you want to stop when seeing
// single characters see NotChars instead
func Until(terminators ...string) Parser {

	return NewParser("Until", func(ps *State, node *Result) {
		startPos := ps.Pos
	loop:
		for ps.Pos < len(ps.Input) {
			for _, terminator := range terminators {
				if ps.Pos+len(terminator) <= len(ps.Input) && ps.Input[ps.Pos:ps.Pos+len(terminator)] == terminator {
					break loop
				}
			}
			ps.Pos++
		}

		if ps.Pos == startPos {
			ps.ErrorHere("something")
		}
		node.Token = ps.Input[startPos:ps.Pos]
	})
}
<commit_msg>Only skip past hyphens that are truly part of ranges<commit_after>package goparsify

import (
	"fmt"
	"regexp"
	"strings"
	"unicode/utf8"
)

// Parser is the workhorse of parsify. A parser takes a State and returns a result, consuming some
// of the State in the process.
// Given state is shared there are a few rules that should be followed:
//  - A parser that errors must set state.Error
//  - A parser that errors must not change state.Pos
//  - A parser that consumed some input should advance state.Pos
type Parser func(*State, *Result)

// Map shorthand for Map(p, func())
func (p Parser) Map(f func(n *Result)) Parser {
	return Map(p, f)
}

// VoidParser is a special type of parser that never returns anything but can still consume input
type VoidParser func(*State)

// Parserish types are any type that can be turned into a Parser by Parsify
// These currently include *Parser and string literals.
//
// This makes recursive grammars cleaner and allows string literals to be used directly in most contexts.
// eg, matching balanced paren:
//  var group Parser
//  group = Seq("(", Maybe(&group), ")")
// vs
//  var group ParserPtr{}
//  group.P = Seq(Exact("("), Maybe(group.Parse), Exact(")"))
type Parserish interface{}

// Parsify takes a Parserish and makes a Parser out of it. It should be called by
// any Parser that accepts a Parser as an argument. It should never be called during
// instead call it during parser creation so there is no runtime cost.
//
// See Parserish for details.
func Parsify(p Parserish) Parser {
	switch p := p.(type) {
	case func(*State, *Result):
		return p
	case Parser:
		return p
	case *Parser:
		// Todo: Maybe capture this stack and on nil show it? Is there a good error library to do this?
		return func(ptr *State, node *Result) {
			(*p)(ptr, node)
		}
	case string:
		return Exact(p)
	case func(*State):
		return func(ptr *State, node *Result) {
			p(ptr)
		}
	default:
		panic(fmt.Errorf("cant turn a `%T` into a parser", p))
	}
}

// ParsifyAll calls Parsify on all parsers
func ParsifyAll(parsers ...Parserish) []Parser {
	ret := make([]Parser, len(parsers))
	for i, parser := range parsers {
		ret[i] = Parsify(parser)
	}
	return ret
}

// Run applies some input to a parser and returns the result, failing if the input isnt fully consumed.
// It is a convenience method for the most common way to invoke a parser.
func Run(parser Parserish, input string, ws ...VoidParser) (result interface{}, err error) {
	p := Parsify(parser)
	ps := NewState(input)
	if len(ws) > 0 {
		ps.WS = ws[0]
	}

	ret := Result{}
	p(ps, &ret)
	ps.WS(ps)

	if ps.Error.expected != "" {
		return ret.Result, &ps.Error
	}

	if ps.Get() != "" {
		return ret.Result, UnparsedInputError{ps.Get()}
	}

	return ret.Result, nil
}

// Cut prevents backtracking beyond this point. Usually used after keywords when you
// are sure this is the correct path. Improves performance and error reporting.
func Cut() Parser {
	return func(ps *State, node *Result) {
		ps.Cut = ps.Pos
	}
}

// Regex returns a match if the regex successfully matches
func Regex(pattern string) Parser {
	re := regexp.MustCompile("^" + pattern)
	return NewParser(pattern, func(ps *State, node *Result) {
		ps.WS(ps)
		if match := re.FindString(ps.Get()); match != "" {
			ps.Advance(len(match))
			node.Token = match
			return
		}
		ps.ErrorHere(pattern)
	})
}

// Exact will fully match the exact string supplied, or error. The match will be stored in .Token
func Exact(match string) Parser {
	if len(match) == 1 {
		matchByte := match[0]
		return NewParser(match, func(ps *State, node *Result) {
			ps.WS(ps)
			if ps.Pos >= len(ps.Input) || ps.Input[ps.Pos] != matchByte {
				ps.ErrorHere(match)
				return
			}

			ps.Advance(1)

			node.Token = match
		})
	}

	return NewParser(match, func(ps *State, node *Result) {
		ps.WS(ps)
		if !strings.HasPrefix(ps.Get(), match) {
			ps.ErrorHere(match)
			return
		}

		ps.Advance(len(match))

		node.Token = match
	})
}

func parseRepetition(defaultMin, defaultMax int, repetition ...int) (min int, max int) {
	min = defaultMin
	max = defaultMax
	switch len(repetition) {
	case 0:
	case 1:
		min = repetition[0]
	case 2:
		min = repetition[0]
		max = repetition[1]
	default:
		panic(fmt.Errorf("Dont know what %d repetition args mean", len(repetition)))
	}
	return min, max
}

// parseMatcher turns a string in the format a-f01234A-F into:
//   - an alphabet of matches string(01234)
//   - a set of ranges [][]rune{{'a', 'f'}, {'A', 'F'}}
func parseMatcher(matcher string) (alphabet string, ranges [][]rune) {
	runes := []rune(matcher)

	i := 0
	for {
		if i >= len(runes) {
			break
		}

		if i+2 < len(runes) && runes[i+1] == '-' && runes[i] != '\\' {
			start := runes[i]
			end := runes[i+2]
			if start <= end {
				ranges = append(ranges, []rune{start, end})
			} else {
				ranges = append(ranges, []rune{end, start})
			}
			i += 3 // we just consumed 3 bytes: range start, hyphen, and range end
			continue
		}

		if i+1 < len(runes) && runes[i] == '\\' {
			alphabet += string(runes[i+1])
		} else {
			alphabet += string(runes[i])
		}

		i++
	}

	return alphabet, ranges
}

// Chars is the swiss army knife of character matches. It can match:
//  - ranges: Chars("a-z") will match one or more lowercase letter
//  - alphabets: Chars("abcd") will match one or more of the letters abcd in any order
//  - min and max: Chars("a-z0-9", 4, 6) will match 4-6 lowercase alphanumeric characters
// the above can be combined in any order
func Chars(matcher string, repetition ...int) Parser {
	return NewParser("["+matcher+"]", charsImpl(matcher, false, repetition...))
}

// NotChars accepts the full range of input from Chars, but it will stop when any
// character matches. If you need to match until you see a sequence use Until instead
func NotChars(matcher string, repetition ...int) Parser {
	return NewParser("!["+matcher+"]", charsImpl(matcher, true, repetition...))
}

func charsImpl(matcher string, stopOn bool, repetition ...int) Parser {
	min, max := parseRepetition(1, -1, repetition...)
	alphabet, ranges := parseMatcher(matcher)

	return func(ps *State, node *Result) {
		ps.WS(ps)
		matched := 0
		for ps.Pos+matched < len(ps.Input) {
			if max != -1 && matched >= max {
				break
			}

			r, w := utf8.DecodeRuneInString(ps.Input[ps.Pos+matched:])

			anyMatched := strings.ContainsRune(alphabet, r)
			if !anyMatched {
				for _, rng := range ranges {
					if r >= rng[0] && r <= rng[1] {
						anyMatched = true
					}
				}
			}

			if anyMatched == stopOn {
				break
			}

			matched += w
		}

		if matched < min {
			ps.ErrorHere(matcher)
			return
		}

		node.Token = ps.Input[ps.Pos : ps.Pos+matched]
		ps.Advance(matched)
	}
}

// Until will consume all input until one of the given terminator sequences is found. If you want to stop when seeing
// single characters see NotChars instead
func Until(terminators ...string) Parser {

	return NewParser("Until", func(ps *State, node *Result) {
		startPos := ps.Pos
	loop:
		for ps.Pos < len(ps.Input) {
			for _, terminator := range terminators {
				if ps.Pos+len(terminator) <= len(ps.Input) && ps.Input[ps.Pos:ps.Pos+len(terminator)] == terminator {
					break loop
				}
			}
			ps.Pos++
		}

		if ps.Pos == startPos {
			ps.ErrorHere("something")
		}
		node.Token = ps.Input[startPos:ps.Pos]
	})
}
<|endoftext|>


<commit_before>package toscalib

import (
	"gopkg.in/yaml.v2"
	"io"
	"io/ioutil"
)

// Parse a TOSCA document and fill in the structure
// If the structure already contains data
func (toscaStructure *ToscaDefinition) Parse(r io.Reader) error {
	var tempStruct ToscaDefinition
	tempStruct.NodeTypes = make(map[string]NodeType)
	data, err := ioutil.ReadAll(r)
	if err != nil {
		return err
	}

	// Unmarshal the data in an interface
	err = yaml.Unmarshal(data, &tempStruct)
	if err != nil {
		return err
	}
	/*
		// for each node, add its corresponding notetype definition to the structure
		// if not present yet

		// index is the node name and nodeTemplate is the corresponding NodeTemplate
		for _, nodeTemplate := range tempStruct.TopologyTemplate.NodeTemplates {
			// nodeType is he node type of the current NodeTemplate
			nodeType := nodeTemplate.Type
			if _, typeIsPresent := tempStruct.NodeTypes[nodeType]; typeIsPresent == false {
				// Get the corresponding asset and add it to the global structure
				data, err := Asset(nodeType)
				if err != nil {
					//  For debuging purpode
					log.Printf("Cannot find the NodeType definition for %v", nodeType)
				}
				var nt map[string]NodeType
				// Unmarshal the data in an interface
				err = yaml.Unmarshal(data, &nt)
				if err != nil {
					return errors.New(fmt.Sprintf("cannot unmarshal %v (%v)", nodeType, err))
				}
				tempStruct.NodeTypes[nodeType] = nt[nodeType]
			}
		}
	*/
	// TODO: deal with the import files
	// Create the adjacency matrix
	// Every node state must be represented in the matrix
	// Suppose nodeA and nodeB where nodeA requires nodeB
	//
	// if nodeA and nodeB has a Configure relationship,
	// then the workflow is:
	// digraph WorkflowStart {
	//     nodeB:Create() -> nodeA:Create()
	//     nodeA:Create() -> nodeA:PreConfigureSource()
	//     nodeA:PreConfigureSource -> nodeB:PreConfigureTarget()
	//     nodeB:PreConfigureTarget -> nodeA:Configure()
	//     nodeB:PreConfigureTarget -> nodeB:Configure()
	//     nodeA:Configure() -> nodeA:PostConfigureSource()
	//     nodeB:Configure() -> nodeB:PostConfigureTarget()
	//     nodeA:PostConfigureSource() -> nodeA:Start()
	//     nodeB:PostConfigureTarget() -> nodeB:Start()
	//     nodeA:Start() -> nodeB:Start()
	// }
	// otherwise the workflow is
	// digraph WorkflowStart {
	// nodeB:Create() -> nodeB:Configure() -> nodeB:Start() -> nodeA:Create() -> nodeA:Configure() -> nodeA:Start()
	// }

	*toscaStructure = tempStruct
	return nil

}
<commit_msg>cleaned the comments<commit_after>package toscalib

import (
	"gopkg.in/yaml.v2"
	"io"
	"io/ioutil"
)

// Parse a TOSCA document and fill in the structure
// If the structure already contains data
func (toscaStructure *ToscaDefinition) Parse(r io.Reader) error {
	var tempStruct ToscaDefinition
	tempStruct.NodeTypes = make(map[string]NodeType)
	data, err := ioutil.ReadAll(r)
	if err != nil {
		return err
	}

	// Unmarshal the data in an interface
	err = yaml.Unmarshal(data, &tempStruct)
	if err != nil {
		return err
	}
	/*
		// for each node, add its corresponding notetype definition to the structure
		// if not present yet

		// index is the node name and nodeTemplate is the corresponding NodeTemplate
		for _, nodeTemplate := range tempStruct.TopologyTemplate.NodeTemplates {
			// nodeType is he node type of the current NodeTemplate
			nodeType := nodeTemplate.Type
			if _, typeIsPresent := tempStruct.NodeTypes[nodeType]; typeIsPresent == false {
				// Get the corresponding asset and add it to the global structure
				data, err := Asset(nodeType)
				if err != nil {
					//  For debuging purpode
					log.Printf("Cannot find the NodeType definition for %v", nodeType)
				}
				var nt map[string]NodeType
				// Unmarshal the data in an interface
				err = yaml.Unmarshal(data, &nt)
				if err != nil {
					return errors.New(fmt.Sprintf("cannot unmarshal %v (%v)", nodeType, err))
				}
				tempStruct.NodeTypes[nodeType] = nt[nodeType]
			}
		}
	*/
	// TODO: deal with the import files
	// Create the adjacency matrix
	// Every node state must be represented in the matrix
	// Suppose nodeA and nodeB where nodeA requires nodeB
	//
	// if nodeA and nodeB has a Configure relationship,
	// then the workflow is:
	// digraph WorkflowStart {
	//     nodeB:Create() -> nodeA:Create()
	//     nodeA:Create() -> nodeA:PreConfigureSource()
	//     nodeA:PreConfigureSource -> nodeB:PreConfigureTarget()
	//     nodeB:PreConfigureTarget -> nodeA:Configure()
	//     nodeB:PreConfigureTarget -> nodeB:Configure()
	//     nodeA:Configure() -> nodeA:PostConfigureSource()
	//     nodeB:Configure() -> nodeB:PostConfigureTarget()
	//     nodeA:PostConfigureSource() -> nodeA:Start()
	//     nodeB:PostConfigureTarget() -> nodeB:Start()
	//     nodeA:Start() -> nodeB:Start()
	// }
	// otherwise the workflow is
	// digraph WorkflowStart {
	// nodeB:Create() -> nodeB:Configure() -> nodeB:Start() -> nodeA:Create() -> nodeA:Configure() -> nodeA:Start()
	// }
	// let i be the index of nodeA in the adjacency matrix
	// i+i is the index of nodeA:Create()
	// i+2 is the index of nodeA:PreConfigureSource()
	// i+2 is the index of nodeA:PreConfigureTarget()
	// i+3 is the index of nodeA:Configure()
	// i+4 is the index of nodeA:PostConfigureSource()
	// i+5 is the index of nodeA:PostConfigureTarget()
	// i+6 is the index of Start()
	// i+7 is the index of Stop()
	// i+8 is the index of Delete()

	// For each nodeSource in the NodeTemplates structure
	// nodeSource.Id is the column Id (because it is a destination)
	// for each requirement req.Id is the row.Id

	*toscaStructure = tempStruct
	return nil

}
<|endoftext|>


<commit_before>// Copyright 2016 Steven Oud. All rights reserved.
// Use of this source code is governed by a MIT-style license that can be found
// in the LICENSE file.

package mathcat

import (
	"errors"
	"fmt"
	"math"
	"strconv"
	"strings"
)

// Parser holds the lexed tokens, token position and declared variables. By
// default, variables always contains the constants defined below. These can
// however be overwritten.
type Parser struct {
	tokens    []*Token
	pos       int
	Variables map[string]float64
	tok       *Token
}

var (
	errDivionByZero         = errors.New("Divison by zero")
	errUnmatchedParentheses = errors.New("Unmatched parentheses")
	errInvalidSyntax        = errors.New("Invalid syntax")
)

// Some useful predefined variables that can be used in expressions. These
// can be overwritten.
var constants = map[string]float64{
	"pi":  math.Pi,
	"tau": math.Pi / 2,
	"phi": math.Phi,
	"e":   math.E,
}

// New initializes a new Parser instance, useful when you want to run multiple
// expression and/or use variables.
func New() *Parser {
	return &Parser{
		pos:       0,
		Variables: constants,
	}
}

// Eval evaluates an expression and returns its result and any errors found.
//
// Example:
//     res, err := mathcat.Eval("2 * 2 * 2") // 8
func Eval(expr string) (float64, error) {
	tokens, err := Lex(expr)

	// If a lexer error occured don't parse
	if err != nil {
		return -1, err
	}

	p := &Parser{
		tokens:    tokens,
		pos:       0,
		Variables: constants,
	}

	return p.parse()
}

// Run executes an expression on an existing parser instance. Useful for
// variable assignment.
//
// Example:
//     p.Run("a = 555")
//     p.Run("a += 45")
//     res, err := p.Run("a + a") // 1200
func (p *Parser) Run(expr string) (float64, error) {
	tokens, err := Lex(expr)

	if err != nil {
		return -1, err
	}

	p.reset()
	p.tokens = tokens

	return p.parse()
}

// Exec executes an expression with a given map of variables.
//
// Example:
//     res, err := mathcat.Exec("a + b * b", map[string]float64{
//         "a": 1,
//         "b": 3,
//     }) // 10
func Exec(expr string, vars map[string]float64) (float64, error) {
	tokens, err := Lex(expr)

	if err != nil {
		return -1, err
	}

	p := &Parser{
		tokens:    tokens,
		pos:       0,
		Variables: constants,
	}

	isValidIdent := func(c rune) bool { return isIdent(c) || isNumber(c) }

	for k, v := range vars {
		if !isIdent(rune(k[0])) || strings.IndexFunc(k, isValidIdent) == -1 {
			return -1, fmt.Errorf("Invalid variable name: '%s'")
		}
		p.Variables[k] = v
	}

	p.tokens = tokens

	return p.parse()
}

// GetVar gets an existing variable.
func (p *Parser) GetVar(index string) (float64, error) {
	if val, ok := p.Variables[index]; ok {
		return val, nil
	}

	return -1, fmt.Errorf("Undefined variable '%s'", index)
}

func (p *Parser) parse() (float64, error) {
	var (
		operands, operators stack
		o1, o2              *operator
	)

	p.tok = p.tokens[0]

	for p.eat().Type != EOL {
		switch {
		case p.tok.IsLiteral():
			if p.peek().Type == LPAREN {
				// It's a function call, push to operators stack instead
				operators.Push(p.tok)
				break
			}
			operands.Push(p.tok)
		case p.tok.Type == LPAREN:
			operators.Push(p.tok)
		case p.tok.Type == COMMA:
			for {
				if operators.Empty() {
					return -1, errors.New("Misplaced ','")
				}

				if operators.Top().(*Token).Type == LPAREN {
					break
				}

				val, err := p.evaluate(operators.Pop().(*Token), &operands)
				if err != nil {
					return -1, err
				}

				operands.Push(val)
			}
		case p.tok.IsOperator():
			o1 = ops[p.tok.Type]

			if !operators.Empty() {
				var ok bool
				if o2, ok = ops[operators.Top().(*Token).Type]; !ok {
					operators.Push(p.tok)
					break
				}

				if o2.hasHigherPrecThan(o1) {
					operator := operators.Pop().(*Token)
					val, err := p.evaluateOp(operator, &operands)
					if err != nil {
						return -1, err
					}
					operands.Push(val)
				}
			}
			operators.Push(p.tok)
		case p.tok.Type == RPAREN:
			for {
				if operators.Empty() {
					return -1, errUnmatchedParentheses
				}

				top := operators.Pop().(*Token)
				if top.Type == LPAREN {
					break
				}

				val, err := p.evaluate(top, &operands)
				if err != nil {
					return -1, err
				}

				operands.Push(val)
			}
		}
	}

	// Evaluate remaining operators
	for !operators.Empty() {
		top := operators.Pop().(*Token)

		if top.Type == LPAREN {
			return -1, errUnmatchedParentheses
		}

		val, err := p.evaluate(top, &operands)
		if err != nil {
			return -1, err
		}

		operands.Push(val)
	}

	// If there are no operands, the expression is useless and doesn't do
	// anything, for example `()` or an empty string
	if operands.Empty() {
		return 0, nil
	}

	// Single operand left means the expression was evaluated successful
	if len(operands) == 1 {
		return p.lookup(operands[0])
	}

	// Leftover token on operand stack indicates invalid syntax
	return -1, errInvalidSyntax
}

// Evaluate gets called when an operator or function call has to be evaluated
// for a result. In case of a function, evaluateFunc is called and in case of
// an operator evaluateOp is called.
func (p *Parser) evaluate(tok *Token, operands *stack) (float64, error) {
	var err error
	var val float64

	if tok.Type == IDENT {
		// Function call
		val, err = p.evaluateFunc(tok, operands)
	} else {
		// Operator
		val, err = p.evaluateOp(tok, operands)
	}

	if err != nil {
		return -1, err
	}

	return val, nil
}

func (p *Parser) evaluateFunc(tok *Token, operands *stack) (float64, error) {
	var (
		function *function
		ok       bool
		i        int
	)

	if function, ok = functions[tok.Value]; !ok {
		return -1, fmt.Errorf("Undefined function '%s'", tok.Value)
	}

	// Start popping off arguments for the function call
	args := make([]float64, function.nargs)
	for i = 0; i < function.nargs; i++ {
		if operands.Empty() {
			return -1, fmt.Errorf("Invalid argument count for '%s' (expected %d, got %d)", tok.Value, function.nargs, i)
		}

		arg, err := p.lookup(operands.Pop())
		if err != nil {
			return -1, err
		}

		args[i] = arg
	}

	// XXX: This doesn't catch all cases, some still error 'Invalid syntax'
	if len(*operands) > 1 {
		return -1, fmt.Errorf("Invalid argument count for '%s' (expected %d, got %d)", tok.Value, function.nargs, i+1)
	}

	return function.operation(args), nil
}

func (p *Parser) evaluateOp(operator *Token, operands *stack) (float64, error) {
	var (
		result      float64
		left, right float64
		err         error
		lhsToken    interface{}
	)

	if operands.Empty() {
		return -1, fmt.Errorf("Unexpected '%s'", operator.Type)
	}

	if right, err = p.lookup(operands.Pop()); err != nil {
		return -1, err
	}

	// Unary operators have no left hand side
	if op := ops[operator.Type]; !op.unary {
		if operands.Empty() {
			return -1, errInvalidSyntax
		}
		// Save the token in case of a assignment variable is used and we need to
		// save the result in a variable
		lhsToken = operands.Pop()

		// Don't lookup the left hand side if = is used so we can do initial
		// assignment
		if operator.Type != EQ {
			left, err = p.lookup(lhsToken)
			if err != nil {
				return -1, err
			}
		}
	}

	result, err = execute(operator, left, right)
	if err != nil {
		return -1, err
	}

	if operator.IsAssignment() {
		// Save result in variable
		if lhsToken.(*Token).Type != IDENT {
			return -1, errors.New("Can't assign to literal")
		}
		p.Variables[lhsToken.(*Token).Value] = result
	}

	return result, nil
}

func execute(operator *Token, lhs, rhs float64) (float64, error) {
	var result float64

	// Both lhs and rhs have to be whole numbers for bitwise operations
	if operator.IsBitwise() && (!IsWholeNumber(lhs) || !IsWholeNumber(rhs)) {
		return -1, fmt.Errorf("Unsupported type (float) for '%s'", operator.Type)
	}

	switch operator.Type {
	case ADD, ADD_EQ:
		result = lhs + rhs
	case SUB, SUB_EQ:
		result = lhs - rhs
	case UNARY_MIN:
		result = -rhs
	case DIV, DIV_EQ:
		if rhs == 0 {
			return -1, errDivionByZero
		}
		result = lhs / rhs
	case MUL, MUL_EQ:
		result = lhs * rhs
	case POW, POW_EQ:
		result = math.Pow(lhs, rhs)
	case REM, REM_EQ:
		if rhs == 0 {
			return -1, errDivionByZero
		}
		result = math.Mod(lhs, rhs)
	case AND, AND_EQ:
		result = float64(int64(lhs) & int64(rhs))
	case OR, OR_EQ:
		result = float64(int64(lhs) | int64(rhs))
	case XOR, XOR_EQ:
		result = float64(int64(lhs) ^ int64(rhs))
	case LSH, LSH_EQ:
		result = float64(uint64(lhs) << uint64(rhs))
	case RSH, RSH_EQ:
		result = float64(uint64(lhs) >> uint64(rhs))
	case NOT:
		result = float64(^int64(rhs))
	case EQ:
		result = rhs
	case EQ_EQ:
		result = bool2float(lhs == rhs)
	case GT:
		result = bool2float(lhs > rhs)
	case GT_EQ:
		result = bool2float(lhs >= rhs)
	case LT:
		result = bool2float(lhs < rhs)
	case LT_EQ:
		result = bool2float(lhs <= rhs)
	default:
		return -1, fmt.Errorf("Invalid operator '%s'", operator.Type)
	}

	return result, nil
}

// Look up a literal. If it's an identifier, check the parser's variables map,
// otherwise convert the tokenized string to a float64.
func (p *Parser) lookup(val interface{}) (float64, error) {
	// val can be a token or a float64, if it's a float64 it has been already
	// evaluated and we don't need to do anything
	if v, ok := val.(float64); ok {
		return v, nil
	}

	tok := val.(*Token)
	switch tok.Type {
	case NUMBER:
		res, err := strconv.ParseFloat(tok.Value, 64)
		if err != nil {
			return -1, fmt.Errorf("Error parsing '%s': invalid syntax", tok.Value)
		}

		return res, nil
	case HEX:
		// Remove 0x part of hex literal and convert to uint first
		res, err := strconv.ParseUint(tok.Value[2:], 16, 64)
		if err != nil {
			return -1, fmt.Errorf("Error parsing '%s': invalid syntax", tok.Value)
		}

		// Then convert to float
		return float64(res), nil
	case BINARY:
		// Remove 0b part of binary literal and convert to uint first
		res, err := strconv.ParseUint(tok.Value[2:], 2, 64)
		if err != nil {
			return -1, fmt.Errorf("Error parsing '%s': invalid syntax", tok.Value)
		}

		// Then convert to float
		return float64(res), nil
	case IDENT:
		res, err := p.GetVar(tok.Value)
		if err != nil {
			return -1, err
		}

		return res, nil
	}

	return -1, fmt.Errorf("Invalid lookup type: %s", tok.Type)
}

func (p *Parser) reset() {
	p.tokens = nil
	p.pos = 0
}

func (p *Parser) peek() *Token {
	return p.tokens[p.pos]
}

func (p *Parser) eat() *Token {
	p.tok = p.peek()
	p.pos++
	return p.tok
}

// IsWholeNumber checks if a float is a whole number
func IsWholeNumber(n float64) bool {
	epsilon := 1e-9
	_, frac := math.Modf(math.Abs(n))

	return frac < epsilon || frac > 1.0-epsilon
}

func bool2float(b bool) float64 {
	if b {
		return 1
	}
	return 0
}
<commit_msg>Fix arguments order passed to functions and missing argument in invalid variable name in Exec<commit_after>// Copyright 2016 Steven Oud. All rights reserved.
// Use of this source code is governed by a MIT-style license that can be found
// in the LICENSE file.

package mathcat

import (
	"errors"
	"fmt"
	"math"
	"strconv"
	"strings"
)

// Parser holds the lexed tokens, token position and declared variables. By
// default, variables always contains the constants defined below. These can
// however be overwritten.
type Parser struct {
	tokens    []*Token
	pos       int
	Variables map[string]float64
	tok       *Token
}

var (
	errDivionByZero         = errors.New("Divison by zero")
	errUnmatchedParentheses = errors.New("Unmatched parentheses")
	errInvalidSyntax        = errors.New("Invalid syntax")
)

// Some useful predefined variables that can be used in expressions. These
// can be overwritten.
var constants = map[string]float64{
	"pi":  math.Pi,
	"tau": math.Pi / 2,
	"phi": math.Phi,
	"e":   math.E,
}

// New initializes a new Parser instance, useful when you want to run multiple
// expression and/or use variables.
func New() *Parser {
	return &Parser{
		pos:       0,
		Variables: constants,
	}
}

// Eval evaluates an expression and returns its result and any errors found.
//
// Example:
//     res, err := mathcat.Eval("2 * 2 * 2") // 8
func Eval(expr string) (float64, error) {
	tokens, err := Lex(expr)

	// If a lexer error occured don't parse
	if err != nil {
		return -1, err
	}

	p := &Parser{
		tokens:    tokens,
		pos:       0,
		Variables: constants,
	}

	return p.parse()
}

// Run executes an expression on an existing parser instance. Useful for
// variable assignment.
//
// Example:
//     p.Run("a = 555")
//     p.Run("a += 45")
//     res, err := p.Run("a + a") // 1200
func (p *Parser) Run(expr string) (float64, error) {
	tokens, err := Lex(expr)

	if err != nil {
		return -1, err
	}

	p.reset()
	p.tokens = tokens

	return p.parse()
}

// Exec executes an expression with a given map of variables.
//
// Example:
//     res, err := mathcat.Exec("a + b * b", map[string]float64{
//         "a": 1,
//         "b": 3,
//     }) // 10
func Exec(expr string, vars map[string]float64) (float64, error) {
	tokens, err := Lex(expr)

	if err != nil {
		return -1, err
	}

	p := &Parser{
		tokens:    tokens,
		pos:       0,
		Variables: constants,
	}

	isValidIdent := func(c rune) bool { return isIdent(c) || isNumber(c) }

	for k, v := range vars {
		if !isIdent(rune(k[0])) || strings.IndexFunc(k, isValidIdent) == -1 {
			return -1, fmt.Errorf("Invalid variable name: '%s'", k)
		}
		p.Variables[k] = v
	}

	p.tokens = tokens

	return p.parse()
}

// GetVar gets an existing variable.
func (p *Parser) GetVar(index string) (float64, error) {
	if val, ok := p.Variables[index]; ok {
		return val, nil
	}

	return -1, fmt.Errorf("Undefined variable '%s'", index)
}

func (p *Parser) parse() (float64, error) {
	var (
		operands, operators stack
		o1, o2              *operator
	)

	p.tok = p.tokens[0]

	for p.eat().Type != EOL {
		switch {
		case p.tok.IsLiteral():
			if p.peek().Type == LPAREN {
				// It's a function call, push to operators stack instead
				operators.Push(p.tok)
				break
			}
			operands.Push(p.tok)
		case p.tok.Type == LPAREN:
			operators.Push(p.tok)
		case p.tok.Type == COMMA:
			for {
				if operators.Empty() {
					return -1, errors.New("Misplaced ','")
				}

				if operators.Top().(*Token).Type == LPAREN {
					break
				}

				val, err := p.evaluate(operators.Pop().(*Token), &operands)
				if err != nil {
					return -1, err
				}

				operands.Push(val)
			}
		case p.tok.IsOperator():
			o1 = ops[p.tok.Type]

			if !operators.Empty() {
				var ok bool
				if o2, ok = ops[operators.Top().(*Token).Type]; !ok {
					operators.Push(p.tok)
					break
				}

				if o2.hasHigherPrecThan(o1) {
					operator := operators.Pop().(*Token)
					val, err := p.evaluateOp(operator, &operands)
					if err != nil {
						return -1, err
					}
					operands.Push(val)
				}
			}
			operators.Push(p.tok)
		case p.tok.Type == RPAREN:
			for {
				if operators.Empty() {
					return -1, errUnmatchedParentheses
				}

				top := operators.Pop().(*Token)
				if top.Type == LPAREN {
					break
				}

				val, err := p.evaluate(top, &operands)
				if err != nil {
					return -1, err
				}

				operands.Push(val)
			}
		}
	}

	// Evaluate remaining operators
	for !operators.Empty() {
		top := operators.Pop().(*Token)

		if top.Type == LPAREN {
			return -1, errUnmatchedParentheses
		}

		val, err := p.evaluate(top, &operands)
		if err != nil {
			return -1, err
		}

		operands.Push(val)
	}

	// If there are no operands, the expression is useless and doesn't do
	// anything, for example `()` or an empty string
	if operands.Empty() {
		return 0, nil
	}

	// Single operand left means the expression was evaluated successful
	if len(operands) == 1 {
		return p.lookup(operands[0])
	}

	// Leftover token on operand stack indicates invalid syntax
	return -1, errInvalidSyntax
}

// Evaluate gets called when an operator or function call has to be evaluated
// for a result. In case of a function, evaluateFunc is called and in case of
// an operator evaluateOp is called.
func (p *Parser) evaluate(tok *Token, operands *stack) (float64, error) {
	var err error
	var val float64

	if tok.Type == IDENT {
		// Function call
		val, err = p.evaluateFunc(tok, operands)
	} else {
		// Operator
		val, err = p.evaluateOp(tok, operands)
	}

	if err != nil {
		return -1, err
	}

	return val, nil
}

func (p *Parser) evaluateFunc(tok *Token, operands *stack) (float64, error) {
	var (
		function *function
		ok       bool
		i        int
	)

	var count = 0

	if function, ok = functions[tok.Value]; !ok {
		return -1, fmt.Errorf("Undefined function '%s'", tok.Value)
	}

	// Start popping off arguments for the function call
	args := make([]float64, function.nargs)
	for i = function.nargs - 1; i >= 0; i, count = i-1, count+1 {
		if operands.Empty() {
			return -1, fmt.Errorf("Invalid argument count for '%s' (expected %d, got %d)", tok.Value, function.nargs, count)
		}

		arg, err := p.lookup(operands.Pop())
		if err != nil {
			return -1, err
		}

		args[i] = arg
	}

	return function.operation(args), nil
}

func (p *Parser) evaluateOp(operator *Token, operands *stack) (float64, error) {
	var (
		result      float64
		left, right float64
		err         error
		lhsToken    interface{}
	)

	if operands.Empty() {
		return -1, fmt.Errorf("Unexpected '%s'", operator.Type)
	}

	if right, err = p.lookup(operands.Pop()); err != nil {
		return -1, err
	}

	// Unary operators have no left hand side
	if op := ops[operator.Type]; !op.unary {
		if operands.Empty() {
			return -1, errInvalidSyntax
		}
		// Save the token in case of a assignment variable is used and we need to
		// save the result in a variable
		lhsToken = operands.Pop()

		// Don't lookup the left hand side if = is used so we can do initial
		// assignment
		if operator.Type != EQ {
			left, err = p.lookup(lhsToken)
			if err != nil {
				return -1, err
			}
		}
	}

	result, err = execute(operator, left, right)
	if err != nil {
		return -1, err
	}

	if operator.IsAssignment() {
		// Save result in variable
		if lhsToken.(*Token).Type != IDENT {
			return -1, errors.New("Can't assign to literal")
		}
		p.Variables[lhsToken.(*Token).Value] = result
	}

	return result, nil
}

func execute(operator *Token, lhs, rhs float64) (float64, error) {
	var result float64

	// Both lhs and rhs have to be whole numbers for bitwise operations
	if operator.IsBitwise() && (!IsWholeNumber(lhs) || !IsWholeNumber(rhs)) {
		return -1, fmt.Errorf("Unsupported type (float) for '%s'", operator.Type)
	}

	switch operator.Type {
	case ADD, ADD_EQ:
		result = lhs + rhs
	case SUB, SUB_EQ:
		result = lhs - rhs
	case UNARY_MIN:
		result = -rhs
	case DIV, DIV_EQ:
		if rhs == 0 {
			return -1, errDivionByZero
		}
		result = lhs / rhs
	case MUL, MUL_EQ:
		result = lhs * rhs
	case POW, POW_EQ:
		result = math.Pow(lhs, rhs)
	case REM, REM_EQ:
		if rhs == 0 {
			return -1, errDivionByZero
		}
		result = math.Mod(lhs, rhs)
	case AND, AND_EQ:
		result = float64(int64(lhs) & int64(rhs))
	case OR, OR_EQ:
		result = float64(int64(lhs) | int64(rhs))
	case XOR, XOR_EQ:
		result = float64(int64(lhs) ^ int64(rhs))
	case LSH, LSH_EQ:
		result = float64(uint64(lhs) << uint64(rhs))
	case RSH, RSH_EQ:
		result = float64(uint64(lhs) >> uint64(rhs))
	case NOT:
		result = float64(^int64(rhs))
	case EQ:
		result = rhs
	case EQ_EQ:
		result = bool2float(lhs == rhs)
	case GT:
		result = bool2float(lhs > rhs)
	case GT_EQ:
		result = bool2float(lhs >= rhs)
	case LT:
		result = bool2float(lhs < rhs)
	case LT_EQ:
		result = bool2float(lhs <= rhs)
	default:
		return -1, fmt.Errorf("Invalid operator '%s'", operator.Type)
	}

	return result, nil
}

// Look up a literal. If it's an identifier, check the parser's variables map,
// otherwise convert the tokenized string to a float64.
func (p *Parser) lookup(val interface{}) (float64, error) {
	// val can be a token or a float64, if it's a float64 it has been already
	// evaluated and we don't need to do anything
	if v, ok := val.(float64); ok {
		return v, nil
	}

	tok := val.(*Token)
	switch tok.Type {
	case NUMBER:
		res, err := strconv.ParseFloat(tok.Value, 64)
		if err != nil {
			return -1, fmt.Errorf("Error parsing '%s': invalid syntax", tok.Value)
		}

		return res, nil
	case HEX:
		// Remove 0x part of hex literal and convert to uint first
		res, err := strconv.ParseUint(tok.Value[2:], 16, 64)
		if err != nil {
			return -1, fmt.Errorf("Error parsing '%s': invalid syntax", tok.Value)
		}

		// Then convert to float
		return float64(res), nil
	case BINARY:
		// Remove 0b part of binary literal and convert to uint first
		res, err := strconv.ParseUint(tok.Value[2:], 2, 64)
		if err != nil {
			return -1, fmt.Errorf("Error parsing '%s': invalid syntax", tok.Value)
		}

		// Then convert to float
		return float64(res), nil
	case IDENT:
		res, err := p.GetVar(tok.Value)
		if err != nil {
			return -1, err
		}

		return res, nil
	}

	return -1, fmt.Errorf("Invalid lookup type: %s", tok.Type)
}

func (p *Parser) reset() {
	p.tokens = nil
	p.pos = 0
}

func (p *Parser) peek() *Token {
	return p.tokens[p.pos]
}

func (p *Parser) eat() *Token {
	p.tok = p.peek()
	p.pos++
	return p.tok
}

// IsWholeNumber checks if a float is a whole number
func IsWholeNumber(n float64) bool {
	epsilon := 1e-9
	_, frac := math.Modf(math.Abs(n))

	return frac < epsilon || frac > 1.0-epsilon
}

func bool2float(b bool) float64 {
	if b {
		return 1
	}
	return 0
}
<|endoftext|>