<commit_before>package segygo

import (
	"bytes"
	"encoding/binary"
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"unsafe"
)

const Version = "0.1"
const SEGY_DESC_HDR_LEN = 3200
const SEGY_BIN_HDR_LEN = 400
const SEGY_TRACE_HDR_LEN = 240

type BinHeader struct {
	Jobid, Lino, Reno                                                                                int32
	Ntrpr, Nart                                                                                int16
	Hdt, Dto, Hns, Nso                                                                                uint16
	Format, Fold, Tsort, Vscode, Hsfs, Hsfe, Hslen, Hstyp, Schn, Hstas, Hstae, Htatyp, Hcorr, Bgrcv, Rcvm, Mfeet, Polyt, Vgpol int16
	Hunass                                                                                [170]int16 // unassigned
}

type TraceHeader struct {
	Tracel                                                                                int32
	Tracer                                                                                int32
	Fldr                                                                                int32
	Tracf                                                                                int32
	Ep                                                                                int32
	CDP                                                                                int32
	CDPT                                                                                int32
	Trid                                                                                int16
	Nvs                                                                                int16
	Nhs                                                                                int16
	Duse                                                                                int16
	Offset                                                                                int32
	Gelev                                                                                int32
	Selev                                                                                int32
	Sdepth                                                                                int32
	Gdel                                                                                int32
	Sdel                                                                                int32
	SwDep                                                                                int32
	GwDep                                                                                int32
	Scalel                                                                                int16
	Scalco                                                                                int16
	Sx                                                                                int32
	Sy                                                                                int32
	Gx                                                                                int32
	Gy                                                                                int32
	CoUnit                                                                                int16
	WeVel                                                                                int16
	SweVel                                                                                int16
	Sut, Gut, Sstat, Gstat, Tstat, Laga, Lagb, Delrt, Muts, Mute                                                                                int16
	Ns, Dt                                                                                uint16
	Gain, Igc, Igi, Corr, Sfs, Sfe, Slen, Styp, Stas, Stae, Tatyp, Afilf, Afils, NoFilf, NoFils, Lcf, Hcf, Lcs, Hcs, Year, Day, Hour, Minute, Sec, Timbas, Trwf, Grnors, Grnofr, Grnlof, Gaps, Otrav int16
	D1, F1, D2, F2, Ungpow, Unscale                                                                                float32
	Ntr                                                                                int32
	Mark, Shortpad                                                                                int16
	Unass                                                                                [14]int16 // unassigned short array
}

type Trace struct {
	TraceHeader
	Data []float32
}

type SegyFile struct {
	Filename string
	Header   BinHeader
	NrTraces int64
	file     *os.File
}

func OpenFile(filename string) (SegyFile, error) {
	var s SegyFile
	var binHdr BinHeader
	b, err := ioutil.ReadFile(filename)
	if err != nil {
		return s, err
	}

	s.Filename = filename

	accum := []byte{}
	accum = append(accum, b...)

	accum2 := accum[3200:]
	r := bytes.NewReader(accum2)
	fmt.Println("Number of bytes:", r.Len())

	if err = binary.Read(r, binary.BigEndian, &binHdr); err != nil {
		fmt.Println("Error reading segy file (bigendian). ", err)
		return s, err
	}

	// Open and store the os.File object in our struct
	file, err := os.Open(s.Filename)
	s.file = file

	s.Header = binHdr
	s.NrTraces = s.GetNrTraces()

	return s, err
}

func (s *SegyFile) GetNrTraces() int64 {
	fi, err := s.file.Stat()
	if err != nil {
		fmt.Println("unable to get Stat()")
		log.Fatal(err)
	}
	size := fi.Size()
	nSamples := s.Header.Hns
	txtAndBinarySize := int64(SEGY_DESC_HDR_LEN + SEGY_BIN_HDR_LEN)
	nTraces := ((size - txtAndBinarySize) / (int64(SEGY_TRACE_HDR_LEN) + int64(nSamples)*int64(unsafe.Sizeof(float32(1)))))

	return nTraces
}

func (s *SegyFile) GetNrSamples() int32 {
	return int32(s.Header.Hns)
}

func (s *SegyFile) ReadTrace() (Trace, error) {
	// First read the TraceHeader
	//data := []byte{}
	//data = append(data,
	trace := Trace{}
	traceBuff := make([]float32, s.GetNrSamples())
	byteBuff := make([]byte, s.GetNrSamples()*4)
	trace.Data = traceBuff

	trcHdrBuff := make([]byte, SEGY_TRACE_HDR_LEN)
	bytesRead, err := s.file.Read(trcHdrBuff)
	if err != nil {
		log.Fatal(err)
		return trace, err
	}

	trcHdrReader := bytes.NewReader(trcHdrBuff)
	err = binary.Read(trcHdrReader, binary.BigEndian, &trace.TraceHeader)
	if err != nil {
		log.Fatal(err)
		return trace, err
	}

	bytesRead, err = s.file.Read(byteBuff)
	if err != nil {
		log.Fatal(err)
		return trace, err
	}

	for i := range trace.Data {
		trace.Data[i] = float32(binary.BigEndian.Uint32(byteBuff[i*4 : (i+1)*4]))
	}

	log.Println("ReadTrace read ", bytesRead, " bytes")

	// Then figure out the size of the data, and read it
	return trace, nil
}
<commit_msg>better formatting<commit_after>package segygo

import (
	"bytes"
	"encoding/binary"
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"unsafe"
)

const Version = "0.1"
const SEGY_DESC_HDR_LEN = 3200
const SEGY_BIN_HDR_LEN = 400
const SEGY_TRACE_HDR_LEN = 240

type BinHeader struct {
	Jobid, Lino, Reno                                                                                int32
	Ntrpr, Nart                                                                                int16
	Hdt, Dto, Hns, Nso                                                                                uint16
	Format, Fold, Tsort, Vscode, Hsfs, Hsfe, Hslen, Hstyp, Schn, Hstas, Hstae, Htatyp, Hcorr, Bgrcv, Rcvm, Mfeet, Polyt, Vgpol int16
	Hunass                                                                                [170]int16 // unassigned
}

type TraceHeader struct {
	Tracel                                                               int32
	Tracer                                                               int32
	Fldr                                                                 int32
	Tracf                                                                int32
	Ep                                                                   int32
	CDP                                                                  int32
	CDPT                                                                 int32
	Trid                                                                 int16
	Nvs                                                                  int16
	Nhs                                                                  int16
	Duse                                                                 int16
	Offset                                                               int32
	Gelev                                                                int32
	Selev                                                                int32
	Sdepth                                                               int32
	Gdel                                                                 int32
	Sdel                                                                 int32
	SwDep                                                                int32
	GwDep                                                                int32
	Scalel                                                               int16
	Scalco                                                               int16
	Sx                                                                   int32
	Sy                                                                   int32
	Gx                                                                   int32
	Gy                                                                   int32
	CoUnit                                                               int16
	WeVel                                                                int16
	SweVel                                                               int16
	Sut, Gut, Sstat, Gstat, Tstat, Laga, Lagb, Delrt, Muts, Mute         int16
	Ns, Dt                                                               uint16
	Gain, Igc, Igi, Corr, Sfs, Sfe, Slen, Styp, Stas, Stae, Tatyp        int16
	Afilf, Afils, NoFilf, NoFils, Lcf, Hcf, Lcs, Hcs, Year, Day          int16
	Hour, Minute, Sec, Timbas, Trwf, Grnors, Grnofr, Grnlof, Gaps, Otrav int16
	D1, F1, D2, F2, Ungpow, Unscale                                      float32
	Ntr                                                                  int32
	Mark, Shortpad                                                       int16
	Unass                                                                [14]int16 // unassigned short array
}

type Trace struct {
	TraceHeader
	Data []float32
}

type SegyFile struct {
	Filename string
	Header   BinHeader
	NrTraces int64
	file     *os.File
}

func OpenFile(filename string) (SegyFile, error) {
	var s SegyFile
	var binHdr BinHeader
	b, err := ioutil.ReadFile(filename)
	if err != nil {
		return s, err
	}

	s.Filename = filename

	accum := []byte{}
	accum = append(accum, b...)

	accum2 := accum[3200:]
	r := bytes.NewReader(accum2)
	fmt.Println("Number of bytes:", r.Len())

	if err = binary.Read(r, binary.BigEndian, &binHdr); err != nil {
		fmt.Println("Error reading segy file (bigendian). ", err)
		return s, err
	}

	// Open and store the os.File object in our struct
	file, err := os.Open(s.Filename)
	s.file = file

	s.Header = binHdr
	s.NrTraces = s.GetNrTraces()

	return s, err
}

func (s *SegyFile) GetNrTraces() int64 {
	fi, err := s.file.Stat()
	if err != nil {
		fmt.Println("unable to get Stat()")
		log.Fatal(err)
	}
	size := fi.Size()
	nSamples := s.Header.Hns
	txtAndBinarySize := int64(SEGY_DESC_HDR_LEN + SEGY_BIN_HDR_LEN)
	nTraces := ((size - txtAndBinarySize) / (int64(SEGY_TRACE_HDR_LEN) + int64(nSamples)*int64(unsafe.Sizeof(float32(1)))))

	return nTraces
}

func (s *SegyFile) GetNrSamples() int32 {
	return int32(s.Header.Hns)
}

func (s *SegyFile) ReadTrace() (Trace, error) {
	// First read the TraceHeader
	//data := []byte{}
	//data = append(data,
	trace := Trace{}
	traceBuff := make([]float32, s.GetNrSamples())
	byteBuff := make([]byte, s.GetNrSamples()*4)
	trace.Data = traceBuff

	trcHdrBuff := make([]byte, SEGY_TRACE_HDR_LEN)
	bytesRead, err := s.file.Read(trcHdrBuff)
	if err != nil {
		log.Fatal(err)
		return trace, err
	}

	trcHdrReader := bytes.NewReader(trcHdrBuff)
	err = binary.Read(trcHdrReader, binary.BigEndian, &trace.TraceHeader)
	if err != nil {
		log.Fatal(err)
		return trace, err
	}

	bytesRead, err = s.file.Read(byteBuff)
	if err != nil {
		log.Fatal(err)
		return trace, err
	}

	for i := range trace.Data {
		trace.Data[i] = float32(binary.BigEndian.Uint32(byteBuff[i*4 : (i+1)*4]))
	}

	log.Println("ReadTrace read ", bytesRead, " bytes")

	// Then figure out the size of the data, and read it
	return trace, nil
}
<|endoftext|>


<commit_before>// Package directEmail support direct send email from selected interface include SOCKS5 proxy server
package directEmail

import (
	"bytes"
	"errors"
	"fmt"
	"golang.org/x/net/proxy"
	"net"
	"net/smtp"
	"net/url"
	"strings"
	"time"
	"crypto/tls"
)

// A Email contains options for send email.
type Email struct {
	// Ip contains local IP address wich use for send email
	// if blank use default interface
	// if use socks5 proxy "socks://123.124.125.126:8080"
	// and with auth "socks://user:password@123.124.125.126:8080"
	Ip string
	// Host is host name
	// if blank use DNS resolv for field fill
	Host string
	// Port SMTP server port
	Port uint16
	// MapIp use for translate local IP to global if NAT
	// if use Socks server translate IP SOCKS server to real IP
	MapIp map[string]string
	// FromEmail sender email (Required)
	FromEmail string
	// FromName sender name
	FromName string
	// ToEmail recipient email (Required)
	ToEmail string
	// ToName recipient name
	ToName string
	// Subject email subject
	Subject string

	headers         []string
	textPlain       []byte
	textHtml        []byte
	attachments     [][]byte
	raw             bytes.Buffer
	bodyLenght 		int
}

const debugIs = false

// New returns a new Email instance for create and send email
func New() Email {
	return Email{Port: 25}
}

// SendThroughServer send email from SMTP server
func (self *Email) SendThroughServer(host string, port uint16, username, password string) error {
	self.Port = port

	dialFunc,err := self.dialFunction()
	debug("Dialer selected, now dial to server\n")

	conn, err := dialFunc("tcp", net.JoinHostPort(host, fmt.Sprintf("%d", self.Port)))
	if err != nil {
		debug("Not connected\n")
		return err
	}
	debug("Connected\n")

	client, err := smtp.NewClient(conn, host)
	if err != nil {
		return err
	}

	auth := smtp.PlainAuth(
		"",
		username,
		password,
		host,
	)
	self.Host = "localhost"

	debug("Connected, now send email\n")
	return self.send(auth, host, client)
}

// Send email directly
func (self *Email) Send() error {
	var err error

	server, err := self.domainFromEmail(self.ToEmail)
	if err != nil {
		return errors.New("550 Bad ToEmail")
	}

	dialFunc,err := self.dialFunction()
	if err != nil {
		return errors.New(fmt.Sprintf("550 %v", err))
	}

	client, err := self.newClient(server, dialFunc)
	if err != nil {
		return errors.New(fmt.Sprintf("550 %v", err))
	}
	defer client.Close()

	return self.send(nil, "", client)
}

var testHookStartTLS func(*tls.Config)

// Send sending email message
func (self *Email) send(auth smtp.Auth, host string, client *smtp.Client) error {
	var	err error

	if err := client.Hello(strings.TrimRight(self.Host, ".")); err != nil {
		return err
	}

	if auth != nil {
		if ok, _ := client.Extension("STARTTLS"); ok {
			config := &tls.Config{ServerName: host}
			if testHookStartTLS != nil {
				testHookStartTLS(config)
			}
			if err = client.StartTLS(config); err != nil {
				return err
			}
		}
		if auth != nil {
			if err = client.Auth(auth); err != nil {
				return err
			}
		}
	}

	if err := client.Mail(self.FromEmail); err != nil {
		return err
	}

	if err := client.Rcpt(self.ToEmail); err != nil {
		return err
	}

	w, err := client.Data()
	if err != nil {
		return err
	}

	_, err = fmt.Fprint(w, self.raw.String())
	if err != nil {
		return err
	}

	err = w.Close()
	if err != nil {
		return err
	}

	return client.Quit()

}

type conn func(network, address string) (net.Conn, error)

func (self *Email) dialFunction() (conn, error){
	var dialFunc conn

	if self.Ip == "" {
		iface := net.Dialer{}
		dialFunc = iface.Dial
		debug("Dial function is default network interface\n")
	} else {
		if strings.ToLower(self.Ip[0:8]) == "socks://" {
			u, err := url.Parse(self.Ip)
			if err != nil {
				return nil, errors.New(fmt.Sprintf("Error parse socks: %s", err.Error()))
			}
			var iface proxy.Dialer
			if u.User != nil {
				auth := proxy.Auth{}
				auth.User = u.User.Username()
				auth.Password, _ = u.User.Password()
				iface, err = proxy.SOCKS5("tcp", u.Host, &auth, proxy.FromEnvironment())
				if err != nil {
					return dialFunc, err
				}
			} else {
				iface, err = proxy.SOCKS5("tcp", u.Host, nil, proxy.FromEnvironment())
				if err != nil {
					return dialFunc, err
				}
			}
			self.Ip = u.Host
			dialFunc = iface.Dial
			debug("Dial function is socks proxy from ", self.Ip[8:], "\n")
		} else {
			addr := &net.TCPAddr{
				IP: net.ParseIP(self.Ip),
			}
			iface := net.Dialer{LocalAddr: addr}
			dialFunc = iface.Dial
			debug("Dial function is ", addr.String(), " network interface\n")
		}
	}

	return dialFunc, nil
}

func (self *Email) newClient(server string, dialFunc conn) (client *smtp.Client, err error) {
	var	conn net.Conn

	records, err := net.LookupMX(server)
	if err != nil {
		return
	}
	debug("MX for domain:\n")
	for i := range records {
		debug(" - ", records[i].Pref, " ", records[i].Host, "\n")
	}

	for i := range records {
		server := strings.TrimRight(strings.TrimSpace(records[i].Host), ".")
		debug("Connect to server ", server, "\n")
		conn, err = dialFunc("tcp", net.JoinHostPort(server, fmt.Sprintf("%d", self.Port)))
		if err != nil {
			debug("Not connected\n")
			continue
		}
		debug("Connected\n")
		client, err = smtp.NewClient(conn, server)
		if err == nil {
			break
		}
	}
	if err != nil {
		return
	}

	conn.SetDeadline(time.Now().Add(5 * time.Minute)) // SMTP RFC

	if self.Ip == "" {
		self.Ip = conn.LocalAddr().String()
	}

	if self.Host == "" {
		var myGlobalIP string
		myIp, _, err := net.SplitHostPort(strings.TrimLeft(self.Ip, "socks://"))
		myGlobalIP, ok := self.MapIp[myIp]
		if !ok {
			myGlobalIP = myIp
		}
		names, err := net.LookupAddr(myGlobalIP)
		if err != nil && len(names) < 1 {
			return nil, err
		}
		debug("LookUp ", myGlobalIP, " this result ", names[0], "\n")
		self.Host = names[0]
	}

	return
}
<commit_msg>trim space in email address<commit_after>// Package directEmail support direct send email from selected interface include SOCKS5 proxy server
package directEmail

import (
	"bytes"
	"errors"
	"fmt"
	"golang.org/x/net/proxy"
	"net"
	"net/smtp"
	"net/url"
	"strings"
	"time"
	"crypto/tls"
)

// A Email contains options for send email.
type Email struct {
	// Ip contains local IP address wich use for send email
	// if blank use default interface
	// if use socks5 proxy "socks://123.124.125.126:8080"
	// and with auth "socks://user:password@123.124.125.126:8080"
	Ip string
	// Host is host name
	// if blank use DNS resolv for field fill
	Host string
	// Port SMTP server port
	Port uint16
	// MapIp use for translate local IP to global if NAT
	// if use Socks server translate IP SOCKS server to real IP
	MapIp map[string]string
	// FromEmail sender email (Required)
	FromEmail string
	// FromName sender name
	FromName string
	// ToEmail recipient email (Required)
	ToEmail string
	// ToName recipient name
	ToName string
	// Subject email subject
	Subject string

	headers         []string
	textPlain       []byte
	textHtml        []byte
	attachments     [][]byte
	raw             bytes.Buffer
	bodyLenght 		int
}

const debugIs = false

// New returns a new Email instance for create and send email
func New() Email {
	return Email{Port: 25}
}

// SendThroughServer send email from SMTP server
func (self *Email) SendThroughServer(host string, port uint16, username, password string) error {
	self.Port = port

	dialFunc,err := self.dialFunction()
	debug("Dialer selected, now dial to server\n")

	conn, err := dialFunc("tcp", net.JoinHostPort(host, fmt.Sprintf("%d", self.Port)))
	if err != nil {
		debug("Not connected\n")
		return err
	}
	debug("Connected\n")

	client, err := smtp.NewClient(conn, host)
	if err != nil {
		return err
	}

	auth := smtp.PlainAuth(
		"",
		username,
		password,
		host,
	)
	self.Host = "localhost"

	debug("Connected, now send email\n")
	return self.send(auth, host, client)
}

// Send email directly
func (self *Email) Send() error {
	var err error

	server, err := self.domainFromEmail(self.ToEmail)
	if err != nil {
		return errors.New("550 Bad ToEmail")
	}

	dialFunc,err := self.dialFunction()
	if err != nil {
		return errors.New(fmt.Sprintf("550 %v", err))
	}

	client, err := self.newClient(server, dialFunc)
	if err != nil {
		return errors.New(fmt.Sprintf("550 %v", err))
	}
	defer client.Close()

	return self.send(nil, "", client)
}

var testHookStartTLS func(*tls.Config)

// Send sending email message
func (self *Email) send(auth smtp.Auth, host string, client *smtp.Client) error {
	var	err error

	self.ToEmail = strings.TrimSpace(self.ToEmail)
	self.FromEmail = strings.TrimSpace(self.FromEmail)

	if err := client.Hello(strings.TrimRight(self.Host, ".")); err != nil {
		return err
	}

	if auth != nil {
		if ok, _ := client.Extension("STARTTLS"); ok {
			config := &tls.Config{ServerName: host}
			if testHookStartTLS != nil {
				testHookStartTLS(config)
			}
			if err = client.StartTLS(config); err != nil {
				return err
			}
		}
		if auth != nil {
			if err = client.Auth(auth); err != nil {
				return err
			}
		}
	}

	if err := client.Mail(self.FromEmail); err != nil {
		return err
	}

	if err := client.Rcpt(self.ToEmail); err != nil {
		return err
	}

	w, err := client.Data()
	if err != nil {
		return err
	}

	_, err = fmt.Fprint(w, self.raw.String())
	if err != nil {
		return err
	}

	err = w.Close()
	if err != nil {
		return err
	}

	return client.Quit()

}

type conn func(network, address string) (net.Conn, error)

func (self *Email) dialFunction() (conn, error){
	var dialFunc conn

	if self.Ip == "" {
		iface := net.Dialer{}
		dialFunc = iface.Dial
		debug("Dial function is default network interface\n")
	} else {
		if strings.ToLower(self.Ip[0:8]) == "socks://" {
			u, err := url.Parse(self.Ip)
			if err != nil {
				return nil, errors.New(fmt.Sprintf("Error parse socks: %s", err.Error()))
			}
			var iface proxy.Dialer
			if u.User != nil {
				auth := proxy.Auth{}
				auth.User = u.User.Username()
				auth.Password, _ = u.User.Password()
				iface, err = proxy.SOCKS5("tcp", u.Host, &auth, proxy.FromEnvironment())
				if err != nil {
					return dialFunc, err
				}
			} else {
				iface, err = proxy.SOCKS5("tcp", u.Host, nil, proxy.FromEnvironment())
				if err != nil {
					return dialFunc, err
				}
			}
			self.Ip = u.Host
			dialFunc = iface.Dial
			debug("Dial function is socks proxy from ", self.Ip[8:], "\n")
		} else {
			addr := &net.TCPAddr{
				IP: net.ParseIP(self.Ip),
			}
			iface := net.Dialer{LocalAddr: addr}
			dialFunc = iface.Dial
			debug("Dial function is ", addr.String(), " network interface\n")
		}
	}

	return dialFunc, nil
}

func (self *Email) newClient(server string, dialFunc conn) (client *smtp.Client, err error) {
	var	conn net.Conn

	records, err := net.LookupMX(server)
	if err != nil {
		return
	}
	debug("MX for domain:\n")
	for i := range records {
		debug(" - ", records[i].Pref, " ", records[i].Host, "\n")
	}

	for i := range records {
		server := strings.TrimRight(strings.TrimSpace(records[i].Host), ".")
		debug("Connect to server ", server, "\n")
		conn, err = dialFunc("tcp", net.JoinHostPort(server, fmt.Sprintf("%d", self.Port)))
		if err != nil {
			debug("Not connected\n")
			continue
		}
		debug("Connected\n")
		client, err = smtp.NewClient(conn, server)
		if err == nil {
			break
		}
	}
	if err != nil {
		return
	}

	conn.SetDeadline(time.Now().Add(5 * time.Minute)) // SMTP RFC

	if self.Ip == "" {
		self.Ip = conn.LocalAddr().String()
	}

	if self.Host == "" {
		var myGlobalIP string
		myIp, _, err := net.SplitHostPort(strings.TrimLeft(self.Ip, "socks://"))
		myGlobalIP, ok := self.MapIp[myIp]
		if !ok {
			myGlobalIP = myIp
		}
		names, err := net.LookupAddr(myGlobalIP)
		if err != nil && len(names) < 1 {
			return nil, err
		}
		debug("LookUp ", myGlobalIP, " this result ", names[0], "\n")
		self.Host = names[0]
	}

	return
}
<|endoftext|>


<commit_before>package web

import (
	"net/http"
	"strings"
)

// Site manages the handling of requests for a particular site.
// Site's methods are used to register handlers for different
// request paths. The handlers are tried in order, so if a given
// path would match multiple handlers, the first matching handler
// registered is used.
//
// Site must be created with NewSite or NewSecureSite.
type Site struct {
	Name     string
	Port     int
	auth     []string
	handlers []*Matcher
	notFound http.HandlerFunc
}

// NewSite builds a new HTTP Site, using the given domain name
// and port number. The provided handler is called when a request
// path does not match any handlers. If nil, http.NotFoundHandler
// is used instead.
//
//		// http://example.com
//		site := NewSite("example.com", 80, nil)
//
//		// http://example.com:8080
//		site := NewSite("example.com", 8080, nil)
func NewSite(name string, port int, notFound http.HandlerFunc) *Site {
	return &Site{
		Name:     name,
		Port:     port,
		handlers: make([]*Matcher, 0, 1),
		notFound: notFound,
	}
}

// NewSite builds a new HTTPS Site, using the given domain name,
// port number, and certificate files. The provided handler is
// called when a request path does not match any handlers. If
// nil, http.NotFoundHandler is used instead.
//
//		// https://example.com
//		site := NewSecureSite("example.com", 443, "cert.pem", "key.pem", nil)
//
//		// https://example.com:8080
//		site := NewSecureSite("example.com", 8080, "cert.pem", "key.pem", nil)
func NewSecureSite(name string, port int, certFile, keyFile string, notFound http.HandlerFunc) *Site {
	return &Site{
		Name:     name,
		Port:     port,
		auth:     []string{certFile, keyFile},
		handlers: make([]*Matcher, 0, 1),
		notFound: notFound,
	}
}

// Always uses the given handler for any request.
func (s *Site) Always(handler http.Handler) {
	matchFunc := func(_ string) bool { return true }
	s.handlers = append(s.handlers, &Matcher{matchFunc, handler})
}

// Contains uses the given handler when the request path contains
// any of the given pattern strings.
func (s *Site) Contains(handler http.Handler, patterns ...string) {
	for _, pattern := range patterns {
		matchFunc := makeMatchFunc(pattern, strings.Contains)
		s.handlers = append(s.handlers, &Matcher{matchFunc, handler})
	}
}

// Equals uses the given handler when the request path is the same
// as any of the given pattern strings.
func (s *Site) Equals(handler http.Handler, patterns ...string) {
	for _, pattern := range patterns {
		matchFunc := makeMatchFunc(pattern, stringEquals)
		s.handlers = append(s.handlers, &Matcher{matchFunc, handler})
	}
}

// EqualFold uses the given handler when the request path is the same
// as any of the given pattern strings (case insensitive).
func (s *Site) EqualFold(handler http.Handler, patterns ...string) {
	for _, pattern := range patterns {
		matchFunc := makeMatchFunc(pattern, strings.EqualFold)
		s.handlers = append(s.handlers, &Matcher{matchFunc, handler})
	}
}

// HasPrefix uses the given handler when the request path starts with
// any of the given pattern strings.
func (s *Site) HasPrefix(handler http.Handler, patterns ...string) {
	for _, pattern := range patterns {
		matchFunc := makeMatchFunc(pattern, strings.HasPrefix)
		s.handlers = append(s.handlers, &Matcher{matchFunc, handler})
	}
}

// HasSuffix uses the given handler when the request path ends with
// any of the given pattern strings.
func (s *Site) HasSuffix(handler http.Handler, patterns ...string) {
	for _, pattern := range patterns {
		matchFunc := makeMatchFunc(pattern, strings.HasSuffix)
		s.handlers = append(s.handlers, &Matcher{matchFunc, handler})
	}
}

// Match uses the given handler when the given pattern returns true
// when called with the request path.
func (s *Site) Match(handler http.Handler, matchFunc MatchFunc) {
	s.handlers = append(s.handlers, &Matcher{matchFunc, handler})
}

// ServeHTTP allows Site to fulfil the http.Handler interface.
func (s *Site) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	path := r.URL.Path
	for _, handler := range s.handlers {
		if handler.Match(path) {
			handler.Handler.ServeHTTP(w, r)
			return
		}
	}
	s.notFound(w, r)
}

// Matcher is used to detect and supply an http.Handler.
type Matcher struct {
	Match   MatchFunc
	Handler http.Handler
}

// MatchFunc is used to identify desired request paths.
type MatchFunc func(string) bool

func makeMatchFunc(s1 string, m func(string, string) bool) MatchFunc {
	return func(s2 string) bool {
		return m(s1, s2)
	}
}

func stringEquals(s1, s2 string) bool {
	return s1 == s2
}
<commit_msg>Bug fix: Corrected handling of Site.HasPrefix and Site.HasSuffix.<commit_after>package web

import (
	"net/http"
	"strings"
)

// Site manages the handling of requests for a particular site.
// Site's methods are used to register handlers for different
// request paths. The handlers are tried in order, so if a given
// path would match multiple handlers, the first matching handler
// registered is used.
//
// Site must be created with NewSite or NewSecureSite.
type Site struct {
	Name     string
	Port     int
	auth     []string
	handlers []*Matcher
	notFound http.HandlerFunc
}

// NewSite builds a new HTTP Site, using the given domain name
// and port number. The provided handler is called when a request
// path does not match any handlers. If nil, http.NotFoundHandler
// is used instead.
//
//		// http://example.com
//		site := NewSite("example.com", 80, nil)
//
//		// http://example.com:8080
//		site := NewSite("example.com", 8080, nil)
func NewSite(name string, port int, notFound http.HandlerFunc) *Site {
	return &Site{
		Name:     name,
		Port:     port,
		handlers: make([]*Matcher, 0, 1),
		notFound: notFound,
	}
}

// NewSite builds a new HTTPS Site, using the given domain name,
// port number, and certificate files. The provided handler is
// called when a request path does not match any handlers. If
// nil, http.NotFoundHandler is used instead.
//
//		// https://example.com
//		site := NewSecureSite("example.com", 443, "cert.pem", "key.pem", nil)
//
//		// https://example.com:8080
//		site := NewSecureSite("example.com", 8080, "cert.pem", "key.pem", nil)
func NewSecureSite(name string, port int, certFile, keyFile string, notFound http.HandlerFunc) *Site {
	return &Site{
		Name:     name,
		Port:     port,
		auth:     []string{certFile, keyFile},
		handlers: make([]*Matcher, 0, 1),
		notFound: notFound,
	}
}

// Always uses the given handler for any request.
func (s *Site) Always(handler http.Handler) {
	matchFunc := func(_ string) bool { return true }
	s.handlers = append(s.handlers, &Matcher{matchFunc, handler})
}

// Contains uses the given handler when the request path contains
// any of the given pattern strings.
func (s *Site) Contains(handler http.Handler, patterns ...string) {
	for _, pattern := range patterns {
		matchFunc := makeMatchFunc(pattern, strings.Contains)
		s.handlers = append(s.handlers, &Matcher{matchFunc, handler})
	}
}

// Equals uses the given handler when the request path is the same
// as any of the given pattern strings.
func (s *Site) Equals(handler http.Handler, patterns ...string) {
	for _, pattern := range patterns {
		matchFunc := makeMatchFunc(pattern, stringEquals)
		s.handlers = append(s.handlers, &Matcher{matchFunc, handler})
	}
}

// EqualFold uses the given handler when the request path is the same
// as any of the given pattern strings (case insensitive).
func (s *Site) EqualFold(handler http.Handler, patterns ...string) {
	for _, pattern := range patterns {
		matchFunc := makeMatchFunc(pattern, strings.EqualFold)
		s.handlers = append(s.handlers, &Matcher{matchFunc, handler})
	}
}

// HasPrefix uses the given handler when the request path starts with
// any of the given pattern strings.
func (s *Site) HasPrefix(handler http.Handler, patterns ...string) {
	for _, pattern := range patterns {
		matchFunc := makeMatchFunc(pattern, strings.HasPrefix)
		s.handlers = append(s.handlers, &Matcher{matchFunc, handler})
	}
}

// HasSuffix uses the given handler when the request path ends with
// any of the given pattern strings.
func (s *Site) HasSuffix(handler http.Handler, patterns ...string) {
	for _, pattern := range patterns {
		matchFunc := makeMatchFunc(pattern, strings.HasSuffix)
		s.handlers = append(s.handlers, &Matcher{matchFunc, handler})
	}
}

// Match uses the given handler when the given pattern returns true
// when called with the request path.
func (s *Site) Match(handler http.Handler, matchFunc MatchFunc) {
	s.handlers = append(s.handlers, &Matcher{matchFunc, handler})
}

// ServeHTTP allows Site to fulfil the http.Handler interface.
func (s *Site) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	path := r.URL.Path
	for _, handler := range s.handlers {
		if handler.Match(path) {
			handler.Handler.ServeHTTP(w, r)
			return
		}
	}
	s.notFound(w, r)
}

// Matcher is used to detect and supply an http.Handler.
type Matcher struct {
	Match   MatchFunc
	Handler http.Handler
}

// MatchFunc is used to identify desired request paths.
type MatchFunc func(string) bool

func makeMatchFunc(pattern string, m func(string, string) bool) MatchFunc {
	return func(path string) bool {
		return m(path, pattern)
	}
}

func stringEquals(s1, s2 string) bool {
	return s1 == s2
}
<|endoftext|>


<commit_before>package main

import (
    "os"
    "bufio"
    "strings"
    "bytes"
    "fmt"
    "path/filepath"
    "regexp"
)

//Structs used when parsing a song file
type Song struct {
    Title string
    Section string
    StanzaCount int
    SongNumber int
    Stanzas []Stanza
    BeforeComments []string
    AfterComments []string
    Transpose int
}

func ParseSongFile(filename string, transpose int) (*Song, error) {
    file, err := os.Open(filename)
    if err != nil {
        return nil, err
    }
    defer file.Close()

    var (
        lines []Line
        stanzas []Stanza
        stanza_count = 1
        is_chorus = false
        title = filepath.Base(filename)[0:len(filepath.Base(filename))-5]
        section = ""
        scanner = bufio.NewScanner(file)
    )

    //We need to handle /r only as Mac OS <= 9 uses this as end-of-line marker
    //This is based on bufio/scan.go ScanLines function
    split := func(data []byte, atEOF bool) (advance int, token []byte, err error) {
        if atEOF && len(data) == 0 {
            return 0, nil, nil
        }
        i := bytes.IndexByte(data, '\n');

        if i < 0 {
            i = bytes.IndexByte(data, '\r');
        }

        ind := 0
        if i > 0 && data[i-1] == '\r' {
            ind = -1
        }

        if i >= 0 {

            // We have a full newline-terminated line.
            return i + 1, data[0:i + ind], nil
        }
        // If we're at EOF, we have a final, non-terminated line. Return it.
        if atEOF {
            return len(data), data[0:len(data)+ind], nil
        }
        // Request more data.
        return 0, nil, nil
    }
    scanner.Split(split)

    stanza_before_comments := make([]string, 0)
    stanza_after_comments := make([]string, 0)
    song_before_comments := make([]string, 0)
    //song_after_comments := make([]string, 0)
    //
    chord_regex := regexp.MustCompile("\\[.*?\\]")

    for scanner.Scan() {
        line := scanner.Text()

        //is this a command
        if strings.HasPrefix(line, "{") {
            if (strings.HasPrefix(line, "{start_of_chorus}")) {
                is_chorus = true
            } else if (strings.HasPrefix(line,"{end_of_chorus}")) {

            } else if (strings.HasPrefix(line, "{title:")) {
                title = parseCommand(line)
            } else if (strings.HasPrefix(line, "{section:")) {
                section = parseCommand(line)
            } else if (strings.HasPrefix(line, "{comments:")) {
                if (len(stanzas) == 0) {
                    song_before_comments = append(song_before_comments, parseCommand(line))
                } else {
                    if (len(lines) > 0) {
                        stanza_after_comments = append(stanza_after_comments, parseCommand(line))
                    } else {
                        stanza_before_comments = append(stanza_before_comments, parseCommand(line))
                    }
                }
            }
        //blank line separates stanzas
        } else if len(line) == 0 {
            if len(lines) > 0 {
                stanzas = append(stanzas, *&Stanza{
                    Lines: lines,
                    Number: stanza_count,
                    IsChorus: is_chorus,
                    BeforeComments: stanza_before_comments,
                    AfterComments: stanza_after_comments})

                stanza_count++
                is_chorus = false
                lines = make([]Line, 0)
                stanza_before_comments = make([]string, 0)
                stanza_after_comments = make([]string, 0)

                if (is_chorus) {
                    stanza_count++
                }
            }
        } else {
            chords_pos := chord_regex.FindAllStringIndex(line, -1)
            chord_len := 0
            chords := make([]Chord, 0)

            for _, pos := range chords_pos {
                chord_text := line[pos[0]+1:pos[1]-1]
                chord_len += pos[1] - pos[0]
                position := pos[1] - chord_len

                chord_text = transposeKey(chord_text, transpose)

                chords = append(chords, Chord{Text: chord_text, Position: position})
            }

            //remove all chord markers
            line = chord_regex.ReplaceAllString(line, "")
            lines = append(lines, Line{Text: line, Chords: chords})
        }
    }

    //check for last stanza
    if len(lines) > 0 {
        stanzas = append(stanzas, *&Stanza{
            Lines: lines,
            Number: stanza_count,
            IsChorus: is_chorus})
    }

    return &Song{
        Title: title,
        Section: section,
        StanzaCount: 0,
        SongNumber: -1,
        Stanzas: stanzas,
        BeforeComments: song_before_comments,
        Transpose: transpose},
        nil
}

func parseCommand(command string) string {
    return strings.TrimSpace(command[strings.Index(command, ":")+1:strings.Index(command, "}")])
}

func (song Song) String() string {
    var buffer bytes.Buffer

    if len(song.Section) > 0 {
        buffer.WriteString(fmt.Sprintf("Section: %s\n", song.Section))
    }

    if len(song.BeforeComments) > 0 {
        buffer.WriteString(fmt.Sprintf("/%s/\n", song.BeforeComments))
    }

    for _,s := range song.Stanzas {
        if s.IsChorus {
            buffer.WriteString("---CHORUS--\n")
        }
        buffer.WriteString(fmt.Sprintf("STANZA: %d\n", s.Number))
        for _,l := range s.Lines {
            buffer.WriteString(fmt.Sprintf("%s\n", l.Text))
        }
        if s.IsChorus {
            buffer.WriteString(fmt.Sprintln("---END CHORUS--"))
        }

        buffer.WriteString("\n")
    }

    return buffer.String()
}

func (song Song) HasBeforeComments() bool {
    return len(song.BeforeComments) > 0
}
<commit_msg>GoImported song file, also added support for Song AfterComments<commit_after>package main

import (
	"bufio"
	"bytes"
	"fmt"
	"os"
	"path/filepath"
	"regexp"
	"strings"
)

//Structs used when parsing a song file
type Song struct {
	Title          string
	Section        string
	StanzaCount    int
	SongNumber     int
	Stanzas        []Stanza
	BeforeComments []string
	AfterComments  []string
	Transpose      int
}

func ParseSongFile(filename string, transpose int) (*Song, error) {
	file, err := os.Open(filename)
	if err != nil {
		return nil, err
	}
	defer file.Close()

	var (
		lines        []Line
		stanzas      []Stanza
		stanza_count = 1
		is_chorus    = false
		title        = filepath.Base(filename)[0 : len(filepath.Base(filename))-5]
		section      = ""
		scanner      = bufio.NewScanner(file)
	)

	//We need to handle /r only as Mac OS <= 9 uses this as end-of-line marker
	//This is based on bufio/scan.go ScanLines function
	split := func(data []byte, atEOF bool) (advance int, token []byte, err error) {
		if atEOF && len(data) == 0 {
			return 0, nil, nil
		}
		i := bytes.IndexByte(data, '\n')

		if i < 0 {
			i = bytes.IndexByte(data, '\r')
		}

		ind := 0
		if i > 0 && data[i-1] == '\r' {
			ind = -1
		}

		if i >= 0 {

			// We have a full newline-terminated line.
			return i + 1, data[0 : i+ind], nil
		}
		// If we're at EOF, we have a final, non-terminated line. Return it.
		if atEOF {
			return len(data), data[0 : len(data)+ind], nil
		}
		// Request more data.
		return 0, nil, nil
	}
	scanner.Split(split)

	stanza_before_comments := make([]string, 0)
	stanza_after_comments := make([]string, 0)
	song_before_comments := make([]string, 0)
	song_after_comments := make([]string, 0)

	chord_regex := regexp.MustCompile("\\[.*?\\]")

	for scanner.Scan() {
		line := scanner.Text()

		//is this a command
		if strings.HasPrefix(line, "{") {
			if strings.HasPrefix(line, "{start_of_chorus}") {
				is_chorus = true
			} else if strings.HasPrefix(line, "{end_of_chorus}") {

			} else if strings.HasPrefix(line, "{title:") {
				title = parseCommand(line)
			} else if strings.HasPrefix(line, "{section:") {
				section = parseCommand(line)
			} else if strings.HasPrefix(line, "{comments:") {
				if len(stanzas) == 0 && !is_chorus {
					song_before_comments = append(song_before_comments, parseCommand(line))
				} else {
					if len(lines) > 0 {
						stanza_after_comments = append(stanza_after_comments, parseCommand(line))
					} else {
						stanza_before_comments = append(stanza_before_comments, parseCommand(line))
					}
				}
			}
			//blank line separates stanzas
		} else if len(line) == 0 {
			if len(lines) > 0 {
				stanzas = append(stanzas, *&Stanza{
					Lines:          lines,
					Number:         stanza_count,
					IsChorus:       is_chorus,
					ShowNumber:     true,
					BeforeComments: stanza_before_comments,
					AfterComments:  stanza_after_comments})

				//Choruses do not get stanza numbers
				if !is_chorus {
					stanza_count++
				}

				is_chorus = false
				lines = make([]Line, 0)
				stanza_before_comments = make([]string, 0)
				stanza_after_comments = make([]string, 0)
			}
		} else {
			chords_pos := chord_regex.FindAllStringIndex(line, -1)
			chord_len := 0
			chords := make([]Chord, 0)

			for _, pos := range chords_pos {
				chord_text := line[pos[0]+1 : pos[1]-1]
				chord_len += pos[1] - pos[0]
				position := pos[1] - chord_len

				chord_text = transposeKey(chord_text, transpose)

				chords = append(chords, Chord{Text: chord_text, Position: position})
			}

			//remove all chord markers
			line = chord_regex.ReplaceAllString(line, "")
			lines = append(lines, Line{Text: line, Chords: chords})
		}
	}

	//check for last stanza
	if len(lines) > 0 {
		stanzas = append(stanzas, Stanza{
			Lines:          lines,
			Number:         stanza_count,
			IsChorus:       is_chorus,
			ShowNumber:     true,
			BeforeComments: stanza_before_comments,
			AfterComments:  stanza_after_comments})
	} else if len(stanza_before_comments) > 0 {
		song_after_comments = stanza_before_comments
	}

	return &Song{
			Title:          title,
			Section:        section,
			StanzaCount:    0,
			SongNumber:     -1,
			Stanzas:        stanzas,
			BeforeComments: song_before_comments,
			AfterComments:  song_after_comments,
			Transpose:      transpose},
		nil
}

func parseCommand(command string) string {
	return strings.TrimSpace(command[strings.Index(command, ":")+1 : strings.Index(command, "}")])
}

func (song Song) String() string {
	var buffer bytes.Buffer

	if len(song.Section) > 0 {
		buffer.WriteString(fmt.Sprintf("Section: %s\n", song.Section))
	}

	if len(song.BeforeComments) > 0 {
		buffer.WriteString(fmt.Sprintf("/%s/\n", song.BeforeComments))
	}

	for _, s := range song.Stanzas {
		if s.IsChorus {
			buffer.WriteString("---CHORUS--\n")
		}
		buffer.WriteString(fmt.Sprintf("STANZA: %d\n", s.Number))
		for _, l := range s.Lines {
			buffer.WriteString(fmt.Sprintf("%s\n", l.Text))
		}
		if s.IsChorus {
			buffer.WriteString(fmt.Sprintln("---END CHORUS--"))
		}

		buffer.WriteString("\n")
	}

	return buffer.String()
}

func (song Song) HasBeforeComments() bool {
	return len(song.BeforeComments) > 0
}
<|endoftext|>


<commit_before>/*
Copyright 2019 The logr Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

// Package stdr implements github.com/go-logr/logr.Logger in terms of
// Go's standard log package.
package stdr

import (
	"log"

	"github.com/go-logr/logr"
	"github.com/go-logr/logr/funcr"
)

// The global verbosity level.  See SetVerbosity().
var globalVerbosity int

// SetVerbosity sets the global level against which all info logs will be
// compared.  If this is greater than or equal to the "V" of the logger, the
// message will be logged.  A higher value here means more logs will be written.
// The previous verbosity value is returned.  This is not concurrent-safe -
// callers must be sure to call it from only one goroutine.
func SetVerbosity(v int) int {
	old := globalVerbosity
	globalVerbosity = v
	return old
}

// New returns a logr.Logger which is implemented by Go's standard log package,
// or something like it.  If std is nil, this will call functions in the log
// package instead.
//
// Example: stdr.New(log.New(os.Stderr, "", log.LstdFlags)))
func New(std StdLogger) logr.Logger {
	return NewWithOptions(std, Options{})
}

// NewWithOptions returns a logr.Logger which is implemented by Go's standard
// log package, or something like it.  See New for details.
func NewWithOptions(std StdLogger, opts Options) logr.Logger {
	if opts.Depth < 0 {
		opts.Depth = 0
	}

	fopts := funcr.Options{
		LogCaller: funcr.MessageClass(opts.LogCaller),
	}

	sl := &logger{
		Formatter: funcr.NewFormatter(fopts),
		std:       std,
	}

	// For skipping our own logger.Info/Error.
	sl.Formatter.AddCallDepth(1 + opts.Depth)

	return logr.New(sl)
}

// Options carries parameters which influence the way logs are generated.
type Options struct {
	// Depth biases the assumed number of call frames to the "true" caller.
	// This is useful when the calling code calls a function which then calls
	// stdr (e.g. a logging shim to another API).  Values less than zero will
	// be treated as zero.
	Depth int

	// LogCaller tells glogr to add a "caller" key to some or all log lines.
	// The glog implementation always logs this information in its per-line
	// header, whether this option is set or not.
	LogCaller MessageClass

	// TODO: add an option to log the date/time
}

// MessageClass indicates which category or categories of messages to consider.
type MessageClass int

const (
	// None ignores all message classes.
	None MessageClass = iota
	// All considers all message classes.
	All
	// Info only considers info messages.
	Info
	// Error only considers error messages.
	Error
)

// StdLogger is the subset of the Go stdlib log.Logger API that is needed for
// this adapter.
type StdLogger interface {
	// Output is the same as log.Output and log.Logger.Output.
	Output(calldepth int, logline string) error
}

type logger struct {
	funcr.Formatter
	std StdLogger
}

var _ logr.LogSink = &logger{}
var _ logr.CallDepthLogSink = &logger{}

func (l logger) Enabled(level int) bool {
	return globalVerbosity >= level
}

func (l logger) Info(level int, msg string, kvList ...interface{}) {
	prefix, args := l.FormatInfo(level, msg, kvList)
	if prefix != "" {
		args = prefix + ": " + args
	}
	l.output(args)
}

func (l logger) Error(err error, msg string, kvList ...interface{}) {
	prefix, args := l.FormatError(err, msg, kvList)
	if prefix != "" {
		args = prefix + ": " + args
	}
	l.output(args)
}

func (l logger) WithName(name string) logr.LogSink {
	l.Formatter.AddName(name)
	return &l
}

func (l logger) WithValues(kvList ...interface{}) logr.LogSink {
	l.Formatter.AddValues(kvList)
	return &l
}

func (l logger) WithCallDepth(depth int) logr.LogSink {
	l.Formatter.AddCallDepth(depth)
	return &l
}

func (l logger) output(s string) {
	depth := l.Formatter.GetDepth() + 2 // offset for this adapter

	// ignore errors - what can we really do about them?
	if l.std != nil {
		_ = l.std.Output(depth, s)
	} else {
		_ = log.Output(depth, s)
	}
}

// Underlier exposes access to the underlying logging implementation.  Since
// callers only have a logr.Logger, they have to know which implementation is
// in use, so this interface is less of an abstraction and more of way to test
// type conversion.
type Underlier interface {
	GetUnderlying() StdLogger
}

// GetUnderlying returns the StdLogger underneath this logger.  Since StdLogger
// is itself an interface, the result may or may not be a Go log.Logger.
func (l logger) GetUnderlying() StdLogger {
	return l.std
}
<commit_msg>Ensure the stdlog.Logger is never nil<commit_after>/*
Copyright 2019 The logr Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

// Package stdr implements github.com/go-logr/logr.Logger in terms of
// Go's standard log package.
package stdr

import (
	"log"
	"os"

	"github.com/go-logr/logr"
	"github.com/go-logr/logr/funcr"
)

// The global verbosity level.  See SetVerbosity().
var globalVerbosity int

// SetVerbosity sets the global level against which all info logs will be
// compared.  If this is greater than or equal to the "V" of the logger, the
// message will be logged.  A higher value here means more logs will be written.
// The previous verbosity value is returned.  This is not concurrent-safe -
// callers must be sure to call it from only one goroutine.
func SetVerbosity(v int) int {
	old := globalVerbosity
	globalVerbosity = v
	return old
}

// New returns a logr.Logger which is implemented by Go's standard log package,
// or something like it.  If std is nil, this will use a default logger
// instead.
//
// Example: stdr.New(log.New(os.Stderr, "", log.LstdFlags|log.Lshortfile)))
func New(std StdLogger) logr.Logger {
	return NewWithOptions(std, Options{})
}

// NewWithOptions returns a logr.Logger which is implemented by Go's standard
// log package, or something like it.  See New for details.
func NewWithOptions(std StdLogger, opts Options) logr.Logger {
	if std == nil {
		// Go's log.Default() is only available in 1.16 and higher.
		std = log.New(os.Stderr, "", log.LstdFlags)
	}

	if opts.Depth < 0 {
		opts.Depth = 0
	}

	fopts := funcr.Options{
		LogCaller: funcr.MessageClass(opts.LogCaller),
	}

	sl := &logger{
		Formatter: funcr.NewFormatter(fopts),
		std:       std,
	}

	// For skipping our own logger.Info/Error.
	sl.Formatter.AddCallDepth(1 + opts.Depth)

	return logr.New(sl)
}

// Options carries parameters which influence the way logs are generated.
type Options struct {
	// Depth biases the assumed number of call frames to the "true" caller.
	// This is useful when the calling code calls a function which then calls
	// stdr (e.g. a logging shim to another API).  Values less than zero will
	// be treated as zero.
	Depth int

	// LogCaller tells glogr to add a "caller" key to some or all log lines.
	// The glog implementation always logs this information in its per-line
	// header, whether this option is set or not.
	LogCaller MessageClass

	// TODO: add an option to log the date/time
}

// MessageClass indicates which category or categories of messages to consider.
type MessageClass int

const (
	// None ignores all message classes.
	None MessageClass = iota
	// All considers all message classes.
	All
	// Info only considers info messages.
	Info
	// Error only considers error messages.
	Error
)

// StdLogger is the subset of the Go stdlib log.Logger API that is needed for
// this adapter.
type StdLogger interface {
	// Output is the same as log.Output and log.Logger.Output.
	Output(calldepth int, logline string) error
}

type logger struct {
	funcr.Formatter
	std StdLogger
}

var _ logr.LogSink = &logger{}
var _ logr.CallDepthLogSink = &logger{}

func (l logger) Enabled(level int) bool {
	return globalVerbosity >= level
}

func (l logger) Info(level int, msg string, kvList ...interface{}) {
	prefix, args := l.FormatInfo(level, msg, kvList)
	if prefix != "" {
		args = prefix + ": " + args
	}
	_ = l.std.Output(l.Formatter.GetDepth()+1, args)
}

func (l logger) Error(err error, msg string, kvList ...interface{}) {
	prefix, args := l.FormatError(err, msg, kvList)
	if prefix != "" {
		args = prefix + ": " + args
	}
	_ = l.std.Output(l.Formatter.GetDepth()+1, args)
}

func (l logger) WithName(name string) logr.LogSink {
	l.Formatter.AddName(name)
	return &l
}

func (l logger) WithValues(kvList ...interface{}) logr.LogSink {
	l.Formatter.AddValues(kvList)
	return &l
}

func (l logger) WithCallDepth(depth int) logr.LogSink {
	l.Formatter.AddCallDepth(depth)
	return &l
}

// Underlier exposes access to the underlying logging implementation.  Since
// callers only have a logr.Logger, they have to know which implementation is
// in use, so this interface is less of an abstraction and more of way to test
// type conversion.
type Underlier interface {
	GetUnderlying() StdLogger
}

// GetUnderlying returns the StdLogger underneath this logger.  Since StdLogger
// is itself an interface, the result may or may not be a Go log.Logger.
func (l logger) GetUnderlying() StdLogger {
	return l.std
}
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"encoding/csv"
	"flag"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"os"
)

func main() {

	flag.Parse()
	if flag.NArg() < 3 {
		fmt.Println("Please specifiy: index input output")
		return
	}

	// TODO A no write, stdout only option is necessary for sanity

	// Read and build the master replace index
	indexFile, err := os.Open(flag.Arg(0))
	if err != nil {
		log.Fatal(err)
		return
	}
	defer indexFile.Close()

	c := csv.NewReader(indexFile)

	// fmt.Printf("Master index: Building\n")

	masterIndex, err := newReplaceIndex(c)
	if err != nil {
		switch err {
		case io.EOF:
			fmt.Printf("The index file is empty, can't continue.\n")
			return
		default:
			log.Fatal(err)
			return
		}
	}

	// fmt.Printf("Master index: Done\n")

	// Read in the input file
	inputFile, err := os.Open(flag.Arg(1))
	if err != nil {
		log.Fatal(err)
		return
	}
	defer inputFile.Close()

	inputData, err := ioutil.ReadAll(inputFile)
	if err != nil {
		log.Fatal(err)
		return
	}

	buf := bytes.NewBuffer(inputData)
	inputChan := make(chan workTask)
	var lineCount int

	// Feed the producer line at a time
	go func() {
		for {
			b, err := buf.ReadBytes('\n')
			if err != nil {
				break
			}
			inputChan <- workTask{b, lineCount}
			lineCount++
		}
		close(inputChan)
	}()

	// Collect the resultant deltas
	deltas := producer(inputChan, &masterIndex)
	fmt.Printf("Final deltas: %v\n", deltas)

	buf = bytes.NewBuffer(inputData)

	// Output the file, applying the deltas
	for i := 0; i < len(inputData); i++ {
		b, err := buf.ReadBytes('\n')
		if err != nil {
			break
		}
		// TODO Apply delta to []byte and output
		fmt.Sprintf("%v\n", b)
	}

	//	err := writeNewFile(inputData, deltas, flag.Arg(1))
	//	if err != nil {
	//		log.Fatal(err)
	//		return
	//	}

	//	out := csv.NewWriter(os.Stdout)
	//	out.Write(headerRow)
	//	out.Flush()
}
<commit_msg>Didn't need var c, no errors passed or generated.<commit_after>package main

import (
	"bytes"
	"encoding/csv"
	"flag"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"os"
)

func main() {

	flag.Parse()
	if flag.NArg() < 3 {
		fmt.Println("Please specifiy: index input output")
		return
	}

	// TODO A no write, stdout only option is necessary for sanity

	// Read and build the master replace index
	indexFile, err := os.Open(flag.Arg(0))
	if err != nil {
		log.Fatal(err)
		return
	}
	defer indexFile.Close()

	// fmt.Printf("Master index: Building\n")

	masterIndex, err := newReplaceIndex(csv.NewReader(indexFile))
	if err != nil {
		switch err {
		case io.EOF:
			fmt.Printf("The index file is empty, can't continue.\n")
			return
		default:
			log.Fatal(err)
			return
		}
	}

	// fmt.Printf("Master index: Done\n")

	// Read in the input file
	inputFile, err := os.Open(flag.Arg(1))
	if err != nil {
		log.Fatal(err)
		return
	}
	defer inputFile.Close()

	inputData, err := ioutil.ReadAll(inputFile)
	if err != nil {
		log.Fatal(err)
		return
	}

	buf := bytes.NewBuffer(inputData)
	inputChan := make(chan workTask)
	var lineCount int

	// Feed the producer line at a time
	go func() {
		for {
			b, err := buf.ReadBytes('\n')
			if err != nil {
				break
			}
			inputChan <- workTask{b, lineCount}
			lineCount++
		}
		close(inputChan)
	}()

	// Collect the resultant deltas
	deltas := producer(inputChan, &masterIndex)
	fmt.Printf("Final deltas: %v\n", deltas)

	buf = bytes.NewBuffer(inputData)

	// Output the file, applying the deltas
	for i := 0; i < len(inputData); i++ {
		b, err := buf.ReadBytes('\n')
		if err != nil {
			break
		}
		// TODO Apply delta to []byte and output
		fmt.Sprintf("%v\n", b)
	}

	//	err := writeNewFile(inputData, deltas, flag.Arg(1))
	//	if err != nil {
	//		log.Fatal(err)
	//		return
	//	}

	//	out := csv.NewWriter(os.Stdout)
	//	out.Write(headerRow)
	//	out.Flush()
}
<|endoftext|>


<commit_before>package metre

// task needs to be atomic. How can we achieve it.
// task can exist in both schedule and process, how do we handle it.

// track Messages and Schedules are possible for it.
// Track messages update task and schedules update
// Kill task if it hits timeout.
// Only one task can be scheduled at a time.

import (
	log "github.com/Sirupsen/logrus"

	"sync"
	"time"
)

type Task struct {
	// This is metre's message channel.
	TaskLock          sync.Mutex
	MessageChannel    chan string
	StartTime         time.Time
	TimeOut           time.Duration
	MessageCountLock  sync.Mutex
	MessageCount      int
	ScheduleCountLock sync.Mutex
	ScheduleCount     int
	ScheduleDoneLock  sync.Mutex
	ScheduleDone      bool
	ID                string // Type Type of task (user as class prefix in cache)
	Interval          string // Schedule String in cron notation
	Schedule          func(t TaskRecord, s Scheduler, c Cache, q Queue)
	Process           func(t TaskRecord, s Scheduler, c Cache, q Queue)
}

func (t Task) GetID() string {
	return t.ID
}

func (t Task) GetInterval() string {
	return t.Interval
}

// Zeros the parameters that may change in a run()
func (t *Task) Zero() {
	t.MessageCountLock.Lock()
	t.MessageCount = 0
	t.MessageCountLock.Unlock()
	t.ScheduleCountLock.Lock()
	t.ScheduleCount = 0
	t.ScheduleCountLock.Unlock()
	t.StartTime = time.Now()
	t.ScheduleDoneLock.Lock()
	t.ScheduleDone = false
	t.ScheduleDoneLock.Unlock()
}
func (t *Task) checkComplete() bool {
	t.MessageCountLock.Lock()
	t.ScheduleCountLock.Lock()
	t.ScheduleDoneLock.Lock()
	status := t.MessageCount == t.ScheduleCount && t.ScheduleDone
	t.MessageCountLock.Unlock()
	t.ScheduleCountLock.Unlock()
	t.ScheduleDoneLock.Unlock()
	return status
}

func (t *Task) SendMessage(msg string) {
	t.MessageChannel <- msg
}

func (t *Task) TestTimeOut() {
	if t.TimeOut != 0 {
		time.Sleep(t.TimeOut)
		if !t.checkComplete() {
			t.SendMessage("Task hit timeout in " + t.TimeOut.String())
		}
	}
}

func (t *Task) Track(trackMsg *trackMessage) {
	switch trackMsg.MessageType {
	case Status:
		t.MessageCountLock.Lock()
		t.MessageCount++
		t.MessageCountLock.Unlock()
		if t.checkComplete() {
			t.SendMessage(trackMsg.TaskId + ": Complete")
			t.SendMessage(trackMsg.TaskId + ": Time taken " + time.Since(t.StartTime).String())
			t.TaskLock.Unlock()
		}
	case Debug:
		t.SendMessage("DEBUG:" + trackMsg.TaskId + ":" + trackMsg.Message)
	case Error:
		t.SendMessage("ERROR:" + trackMsg.TaskId + ":" + trackMsg.Message)
	default:
		log.Warn("Unknown message type")
	}
}
<commit_msg>Removing confused comments<commit_after>package metre

import (
	log "github.com/Sirupsen/logrus"

	"sync"
	"time"
)

type Task struct {
	// This is metre's message channel.
	TaskLock          sync.Mutex
	MessageChannel    chan string
	StartTime         time.Time
	TimeOut           time.Duration
	MessageCountLock  sync.Mutex
	MessageCount      int
	ScheduleCountLock sync.Mutex
	ScheduleCount     int
	ScheduleDoneLock  sync.Mutex
	ScheduleDone      bool
	ID                string // Type Type of task (user as class prefix in cache)
	Interval          string // Schedule String in cron notation
	Schedule          func(t TaskRecord, s Scheduler, c Cache, q Queue)
	Process           func(t TaskRecord, s Scheduler, c Cache, q Queue)
}

func (t Task) GetID() string {
	return t.ID
}

func (t Task) GetInterval() string {
	return t.Interval
}

// Zeros the parameters that may change in a run()
func (t *Task) Zero() {
	t.MessageCountLock.Lock()
	t.MessageCount = 0
	t.MessageCountLock.Unlock()
	t.ScheduleCountLock.Lock()
	t.ScheduleCount = 0
	t.ScheduleCountLock.Unlock()
	t.StartTime = time.Now()
	t.ScheduleDoneLock.Lock()
	t.ScheduleDone = false
	t.ScheduleDoneLock.Unlock()
}
func (t *Task) checkComplete() bool {
	t.MessageCountLock.Lock()
	t.ScheduleCountLock.Lock()
	t.ScheduleDoneLock.Lock()
	status := t.MessageCount == t.ScheduleCount && t.ScheduleDone
	t.MessageCountLock.Unlock()
	t.ScheduleCountLock.Unlock()
	t.ScheduleDoneLock.Unlock()
	return status
}

func (t *Task) SendMessage(msg string) {
	t.MessageChannel <- msg
}

func (t *Task) TestTimeOut() {
	if t.TimeOut != 0 {
		time.Sleep(t.TimeOut)
		if !t.checkComplete() {
			t.SendMessage("Task hit timeout in " + t.TimeOut.String())
		}
	}
}

func (t *Task) Track(trackMsg *trackMessage) {
	switch trackMsg.MessageType {
	case Status:
		t.MessageCountLock.Lock()
		t.MessageCount++
		t.MessageCountLock.Unlock()
		if t.checkComplete() {
			t.SendMessage(trackMsg.TaskId + ": Complete")
			t.SendMessage(trackMsg.TaskId + ": Time taken " + time.Since(t.StartTime).String())
			t.TaskLock.Unlock()
		}
	case Debug:
		t.SendMessage("DEBUG:" + trackMsg.TaskId + ":" + trackMsg.Message)
	case Error:
		t.SendMessage("ERROR:" + trackMsg.TaskId + ":" + trackMsg.Message)
	default:
		log.Warn("Unknown message type")
	}
}
<|endoftext|>


<commit_before>package main

import (
	bolt "github.com/johnnadratowski/golang-neo4j-bolt-driver"
	"fmt"
)

func main() {
	driver := bolt.NewDriver()
	conn, _ := driver.OpenNeo("bolt://neo4j:antares1@139.59.143.205:7687")
	defer conn.Close()

	for {
		// Lets get the node
    	data, err := conn.QueryNeo("MATCH (i:Item) return count(i);", nil)

	fmt.Printf("%v", data)
	fmt.Printf("%v", err)

		data.All()
		data.Close()
	}

}

<commit_msg>test file deleted<commit_after><|endoftext|>


<commit_before>package main

import (
	"./mysql";
	"fmt";
)

func main() {
	err := mysql.Connect("127.0.0.1:3306", "test", "test", "test");
	if err != nil {
		fmt.Printf("%s\n", err);
	}
}
<commit_msg>Change test to use instance of mysql<commit_after>package main

import (
	"./mysql";
	"fmt";
)

func main() {
	dbh, err := mysql.Connect("127.0.0.1:3306", "test", "test", "test");
	if err != nil {
		fmt.Printf("%s\n", err);
	}
	fmt.Printf("Connected to %s\n", dbh.ServerVersion);
}
<|endoftext|>


<commit_before>package leakybucket

import (
	"math"
	"sync"
	"testing"
	"time"
)

// CreateTest returns a test of bucket creation for a given storage backend.
// It is meant to be used by leakybucket implementers who wish to test this.
func CreateTest(s Storage) func(*testing.T) {
	return func(t *testing.T) {
		now := time.Now()
		bucket, err := s.Create("testbucket", 100, time.Minute)
		if err != nil {
			t.Fatal(err)
		}
		if capacity := bucket.Capacity(); capacity != 100 {
			t.Fatalf("expected capacity of %d, got %d", 100, capacity)
		}
		e := float64(1 * time.Second) // margin of error
		if error := float64(bucket.Reset().Sub(now.Add(time.Minute))); math.Abs(error) > e {
			t.Fatalf("expected reset time close to %s, got %s", now.Add(time.Minute),
				bucket.Reset())
		}
	}
}

// AddTest returns a test that adding to a single bucket works.
// It is meant to be used by leakybucket implementers who wish to test this.
func AddTest(s Storage) func(*testing.T) {
	return func(t *testing.T) {
		bucket, err := s.Create("testbucket", 100, time.Minute)
		if err != nil {
			t.Fatal(err)
		}

		if state, err := bucket.Add(1); err != nil {
			t.Fatal(err)
		} else if bucket.Remaining() != state.Remaining {
			t.Fatalf("expected bucket and state remaining to match, bucket is %d, state is %d",
				bucket.Remaining(), state.Remaining)
		} else if remaining := bucket.Remaining(); remaining != 99 {
			t.Fatalf("expected 99 remaining, got %d", remaining)
		}

		if state, err := bucket.Add(3); err != nil {
			t.Fatal(err)
		} else if bucket.Remaining() != state.Remaining {
			t.Fatalf("expected bucket and state remaining to match, bucket is %d, state is %d",
				bucket.Remaining(), state.Remaining)
		} else if remaining := bucket.Remaining(); remaining != 96 {
			t.Fatalf("expected 96 remaining, got %d", remaining)
		}
	}
}

// ThreadSafeAddTest returns a test that adding to a single bucket is thread-safe.
// It is meant to be used by leakybucket implementers who wish to test this.
func ThreadSafeAddTest(s Storage) func(*testing.T) {
	return func(t *testing.T) {
		// Make a bucket of size `n`. Spawn `n+1` goroutines that each try to take one token.
		// We should see the bucket transition through having `n-1`, `n-2`, ... 0 remaining capacity.
		// We should also witness one error when the bucket has reached capacity.
		n := 100
		bucket, err := s.Create("testbucket", uint(n), time.Minute)
		if err != nil {
			t.Fatal(err)
		}
		remaining := map[uint]bool{}     // record observed "remaining" counts. (ab)using map as set here
		remainingMutex := sync.RWMutex{} // maps are not threadsafe
		errors := []error{}              // record observed errors
		var wg sync.WaitGroup
		for i := 0; i < n+1; i++ {
			wg.Add(1)
			go func() {
				defer wg.Done()
				state, err := bucket.Add(1)
				if err != nil {
					errors = append(errors, err)
				} else {
					remainingMutex.Lock()
					defer remainingMutex.Unlock()
					remaining[state.Remaining] = true
				}
			}()
		}
		wg.Wait()
		if len(remaining) != n {
			t.Fatalf("Did not observe correct bucket states: %#v, %#v", remaining, errors)
		}
		if len(errors) != 1 && errors[0] != ErrorFull {
			t.Fatalf("Did not observe one full error: %#v", errors)
		}
	}
}
<commit_msg>test: AddTest: test error state<commit_after>package leakybucket

import (
	"fmt"
	"math"
	"sync"
	"testing"
	"time"
)

// CreateTest returns a test of bucket creation for a given storage backend.
// It is meant to be used by leakybucket implementers who wish to test this.
func CreateTest(s Storage) func(*testing.T) {
	return func(t *testing.T) {
		now := time.Now()
		bucket, err := s.Create("testbucket", 100, time.Minute)
		if err != nil {
			t.Fatal(err)
		}
		if capacity := bucket.Capacity(); capacity != 100 {
			t.Fatalf("expected capacity of %d, got %d", 100, capacity)
		}
		e := float64(1 * time.Second) // margin of error
		if error := float64(bucket.Reset().Sub(now.Add(time.Minute))); math.Abs(error) > e {
			t.Fatalf("expected reset time close to %s, got %s", now.Add(time.Minute),
				bucket.Reset())
		}
	}
}

// AddTest returns a test that adding to a single bucket works.
// It is meant to be used by leakybucket implementers who wish to test this.
func AddTest(s Storage) func(*testing.T) {
	return func(t *testing.T) {
		bucket, err := s.Create("testbucket", 10, time.Minute)
		if err != nil {
			t.Fatal(err)
		}

		if state, err := bucket.Add(1); err != nil {
			t.Fatal(err)
		} else if bucket.Remaining() != state.Remaining {
			t.Fatalf("expected bucket and state remaining to match, bucket is %d, state is %d",
				bucket.Remaining(), state.Remaining)
		} else if state.Remaining != 9 {
			t.Fatalf("expected 9 remaining, got %d", state.Remaining)
		}

		if state, err := bucket.Add(3); err != nil {
			t.Fatal(err)
		} else if bucket.Remaining() != state.Remaining {
			t.Fatalf("expected bucket and state remaining to match, bucket is %d, state is %d",
				bucket.Remaining(), state.Remaining)
		} else if state.Remaining != 6 {
			t.Fatalf("expected 6 remaining, got %d", state.Remaining)
		}

		if state, err := bucket.Add(6); err != nil {
			t.Fatal(err)
		} else if bucket.Remaining() != state.Remaining {
			t.Fatalf("expected bucket and state remaining to match, bucket is %d, state is %d",
				bucket.Remaining(), state.Remaining)
		} else if state.Remaining != 0 {
			t.Fatalf("expected 0 remaining, got %d", state.Remaining)
		}

		if _, err := bucket.Add(1); err == nil {
			t.Fatalf("expected ErrorFull, received no error")
		} else if fmt.Sprint(err) != "add exceeds free capacity" {
			t.Fatalf("expected ErrorFull, received %v", err)
		}
	}
}

// ThreadSafeAddTest returns a test that adding to a single bucket is thread-safe.
// It is meant to be used by leakybucket implementers who wish to test this.
func ThreadSafeAddTest(s Storage) func(*testing.T) {
	return func(t *testing.T) {
		// Make a bucket of size `n`. Spawn `n+1` goroutines that each try to take one token.
		// We should see the bucket transition through having `n-1`, `n-2`, ... 0 remaining capacity.
		// We should also witness one error when the bucket has reached capacity.
		n := 100
		bucket, err := s.Create("testbucket", uint(n), time.Minute)
		if err != nil {
			t.Fatal(err)
		}
		remaining := map[uint]bool{}     // record observed "remaining" counts. (ab)using map as set here
		remainingMutex := sync.RWMutex{} // maps are not threadsafe
		errors := []error{}              // record observed errors
		var wg sync.WaitGroup
		for i := 0; i < n+1; i++ {
			wg.Add(1)
			go func() {
				defer wg.Done()
				state, err := bucket.Add(1)
				if err != nil {
					errors = append(errors, err)
				} else {
					remainingMutex.Lock()
					defer remainingMutex.Unlock()
					remaining[state.Remaining] = true
				}
			}()
		}
		wg.Wait()
		if len(remaining) != n {
			t.Fatalf("Did not observe correct bucket states: %#v, %#v", remaining, errors)
		}
		if len(errors) != 1 && errors[0] != ErrorFull {
			t.Fatalf("Did not observe one full error: %#v", errors)
		}
	}
}
<|endoftext|>


<commit_before>package main

import (
	"code.google.com/p/go.tools/go/exact"
	"code.google.com/p/go.tools/go/types"
	"fmt"
	"github.com/neelance/gopherjs/translator"
	"go/build"
	"go/parser"
	"go/token"
	"os"
	"os/exec"
	"path"
)

func main() {
	b := &Builder{
		BuildContext: &build.Context{
			GOROOT:        build.Default.GOROOT,
			GOPATH:        build.Default.GOPATH,
			GOOS:          build.Default.GOOS,
			GOARCH:        build.Default.GOARCH,
			Compiler:      "gc",
			InstallSuffix: "js",
		},
		TypesConfig: &types.Config{
			Packages: make(map[string]*types.Package),
		},
		FileSet:  token.NewFileSet(),
		Packages: make(map[string]*BuilderPackage),
	}

	var pkg *BuilderPackage
	cmd := "help"
	if len(os.Args) >= 2 {
		cmd = os.Args[1]
	}
	switch cmd {
	case "install":
		buildPkg, err := b.BuildContext.Import(os.Args[2], "", 0)
		if err != nil {
			fmt.Fprintln(os.Stderr, err)
			os.Exit(1)
		}
		pkg = &BuilderPackage{Package: buildPkg}
		if pkg.IsCommand() {
			pkg.PkgObj = pkg.BinDir + "/" + path.Base(pkg.ImportPath) + ".js"
		}

	case "build", "run":
		filename := os.Args[2]
		file, err := parser.ParseFile(b.FileSet, filename, nil, parser.ImportsOnly)
		if err != nil {
			fmt.Fprintln(os.Stderr, err)
			os.Exit(1)
		}

		imports := make([]string, len(file.Imports))
		for i, imp := range file.Imports {
			imports[i] = imp.Path.Value[1 : len(imp.Path.Value)-1]
		}

		basename := path.Base(filename)
		pkgObj := ""
		if cmd == "build" {
			pkgObj = basename[:len(basename)-3] + ".js"
		}
		pkg = &BuilderPackage{
			Package: &build.Package{
				Name:       "main",
				ImportPath: "main",
				Imports:    imports,
				Dir:        path.Dir(filename),
				GoFiles:    []string{basename},
				PkgObj:     pkgObj,
			},
		}

	case "help":
		os.Stderr.WriteString(`GopherJS is a tool for compiling Go source code to JavaScript.

Usage:

    gopherjs command [arguments]

The commands are:

    build       compile packages and dependencies
    install     compile and install packages and dependencies
    run         compile and run Go program

`)
		os.Exit(0)

	default:
		fmt.Fprintf(os.Stderr, "gopherjs: unknown subcommand \"%s\"\nRun 'gopherjs help' for usage.\n", cmd)
		os.Exit(1)
	}

	err := b.BuildPackage(pkg)
	if err != nil {
		if err == PkgObjUpToDate {
			os.Exit(0)
		}
		if list, isList := err.(translator.ErrorList); isList {
			for _, entry := range list {
				fmt.Fprintln(os.Stderr, entry)
			}
			os.Exit(1)
		}
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}

	switch cmd {
	case "build", "install":
		if !pkg.IsCommand() {
			os.Exit(0) // already stored by BuildPackage
		}

		webMode := false
		webModeConst := b.TypesConfig.Packages[pkg.ImportPath].Scope().Lookup("gopherjsWebMode")
		if webModeConst != nil {
			webMode = exact.BoolVal(webModeConst.(*types.Const).Val())
		}

		if err := os.MkdirAll(path.Dir(pkg.PkgObj), 0777); err != nil {
			fmt.Fprintln(os.Stderr, err)
			os.Exit(1)
		}
		var perm os.FileMode = 0666
		if !webMode {
			perm = 0777
		}
		file, err := os.OpenFile(pkg.PkgObj, os.O_RDWR|os.O_CREATE|os.O_TRUNC, perm)
		if err != nil {
			fmt.Fprintln(os.Stderr, err)
			os.Exit(1)
		}
		if !webMode {
			fmt.Fprintln(file, "#!/usr/bin/env node")
		}
		fmt.Fprintln(file, `"use strict";`)
		fmt.Fprintf(file, "var Go$webMode = %t;\n", webMode)
		file.Write(pkg.JavaScriptCode)
		file.Close()
	case "run":
		node := exec.Command("node")
		pipe, _ := node.StdinPipe()
		node.Stdout = os.Stdout
		node.Stderr = os.Stderr
		err = node.Start()
		if err != nil {
			fmt.Fprintln(os.Stderr, err)
			os.Exit(1)
		}
		fmt.Fprintln(pipe, `"use strict";`)
		fmt.Fprintln(pipe, "var Go$webMode = false;")
		pipe.Write(pkg.JavaScriptCode)
		pipe.Close()
		node.Wait()
	}

	os.Exit(0)
}
<commit_msg>Improved tool CLI.<commit_after>package main

import (
	"code.google.com/p/go.tools/go/exact"
	"code.google.com/p/go.tools/go/types"
	"flag"
	"fmt"
	"github.com/neelance/gopherjs/translator"
	"go/build"
	"go/parser"
	"go/token"
	"os"
	"os/exec"
	"path"
)

type Mode int

const (
	Build Mode = iota
	Run
	Install
)

func main() {
	flag.Parse()

	cmd := flag.Arg(0)
	switch cmd {
	case "build":
		err := Do(Build, flag.Arg(1))
		HandleError(err)
		os.Exit(0)

	case "install":
		err := Do(Install, flag.Arg(1))
		HandleError(err)
		os.Exit(0)

	case "run":
		err := Do(Run, flag.Arg(1))
		HandleError(err)
		os.Exit(0)

	case "tool":
		tool := flag.Arg(1)
		toolFlags := flag.NewFlagSet("tool", flag.ContinueOnError)
		toolFlags.Bool("e", false, "")
		toolFlags.Parse(flag.Args()[2:])
		if len(tool) == 2 {
			switch tool[1] {
			case 'g':
				err := Do(Build, toolFlags.Arg(0))
				HandleError(err)
				os.Exit(0)
			}
		}
		fmt.Fprintln(os.Stderr, "Tool not supported: "+tool)
		os.Exit(1)

	case "help", "":
		os.Stderr.WriteString(`GopherJS is a tool for compiling Go source code to JavaScript.

Usage:

    gopherjs command [arguments]

The commands are:

    build       compile packages and dependencies
    install     compile and install packages and dependencies
    run         compile and run Go program

`)
		os.Exit(0)

	default:
		fmt.Fprintf(os.Stderr, "gopherjs: unknown subcommand \"%s\"\nRun 'gopherjs help' for usage.\n", cmd)
		os.Exit(1)
	}
}

func HandleError(err error) {
	if err == nil {
		return
	}
	if list, isList := err.(translator.ErrorList); isList {
		for _, entry := range list {
			fmt.Fprintln(os.Stderr, entry)
		}
		os.Exit(1)
	}
	fmt.Fprintln(os.Stderr, err.Error())
	os.Exit(1)
}

func Do(mode Mode, filename string) error {
	b := &Builder{
		BuildContext: &build.Context{
			GOROOT:        build.Default.GOROOT,
			GOPATH:        build.Default.GOPATH,
			GOOS:          build.Default.GOOS,
			GOARCH:        build.Default.GOARCH,
			Compiler:      "gc",
			InstallSuffix: "js",
		},
		TypesConfig: &types.Config{
			Packages: make(map[string]*types.Package),
		},
		FileSet:  token.NewFileSet(),
		Packages: make(map[string]*BuilderPackage),
	}

	var pkg *BuilderPackage
	switch mode {
	case Install:
		buildPkg, err := b.BuildContext.Import(filename, "", 0)
		if err != nil {
			return err
		}
		pkg = &BuilderPackage{Package: buildPkg}
		if pkg.IsCommand() {
			pkg.PkgObj = pkg.BinDir + "/" + path.Base(pkg.ImportPath) + ".js"
		}

	case Build, Run:
		file, err := parser.ParseFile(b.FileSet, filename, nil, parser.ImportsOnly)
		if err != nil {
			return err
		}

		imports := make([]string, len(file.Imports))
		for i, imp := range file.Imports {
			imports[i] = imp.Path.Value[1 : len(imp.Path.Value)-1]
		}

		basename := path.Base(filename)
		pkgObj := ""
		if mode == Build {
			pkgObj = basename[:len(basename)-3] + ".js"
		}
		pkg = &BuilderPackage{
			Package: &build.Package{
				Name:       "main",
				ImportPath: "main",
				Imports:    imports,
				Dir:        path.Dir(filename),
				GoFiles:    []string{basename},
				PkgObj:     pkgObj,
			},
		}
	}

	err := b.BuildPackage(pkg)
	if err != nil {
		if err == PkgObjUpToDate {
			return nil
		}
		return err
	}

	switch mode {
	case Build, Install:
		if !pkg.IsCommand() {
			return nil // already stored by BuildPackage
		}

		webMode := false
		webModeConst := b.TypesConfig.Packages[pkg.ImportPath].Scope().Lookup("gopherjsWebMode")
		if webModeConst != nil {
			webMode = exact.BoolVal(webModeConst.(*types.Const).Val())
		}

		if err := os.MkdirAll(path.Dir(pkg.PkgObj), 0777); err != nil {
			return err
		}
		var perm os.FileMode = 0666
		if !webMode {
			perm = 0777
		}
		file, err := os.OpenFile(pkg.PkgObj, os.O_RDWR|os.O_CREATE|os.O_TRUNC, perm)
		if err != nil {
			return err
		}
		if !webMode {
			fmt.Fprintln(file, "#!/usr/bin/env node")
		}
		fmt.Fprintln(file, `"use strict";`)
		fmt.Fprintf(file, "var Go$webMode = %t;\n", webMode)
		file.Write(pkg.JavaScriptCode)
		file.Close()

	case Run:
		node := exec.Command("node")
		pipe, _ := node.StdinPipe()
		node.Stdout = os.Stdout
		node.Stderr = os.Stderr
		err = node.Start()
		if err != nil {
			return err
		}
		fmt.Fprintln(pipe, `"use strict";`)
		fmt.Fprintln(pipe, "var Go$webMode = false;")
		pipe.Write(pkg.JavaScriptCode)
		pipe.Close()
		node.Wait()
	}

	return nil
}
<|endoftext|>


<commit_before>package boom

import (
	"bytes"
	"container/heap"
)

type element struct {
	data []byte
	freq uint64
}

// An elementHeap is a min-heap of elements.
type elementHeap []*element

func (e elementHeap) Len() int           { return len(e) }
func (e elementHeap) Less(i, j int) bool { return e[i].freq < e[j].freq }
func (e elementHeap) Swap(i, j int)      { e[i], e[j] = e[j], e[i] }

func (e *elementHeap) Push(x interface{}) {
	*e = append(*e, x.(*element))
}

func (e *elementHeap) Pop() interface{} {
	old := *e
	n := len(old)
	x := old[n-1]
	*e = old[0 : n-1]
	return x
}

// TopK uses a Count-Min Sketch to calculate the top-K frequent elements in a
// stream.
type TopK struct {
	cms      *CountMinSketch
	k        uint
	n        uint
	elements *elementHeap
}

// NewTopK creates a new TopK backed by a Count-Min sketch whose relative
// accuracy is within a factor of epsilon with probability delta. It tracks the
// k-most frequent elements.
func NewTopK(epsilon, delta float64, k uint) *TopK {
	elements := make(elementHeap, 0, k)
	heap.Init(&elements)
	return &TopK{
		cms:      NewCountMinSketch(epsilon, delta),
		k:        k,
		elements: &elements,
	}
}

// Add will add the data to the Count-Min Sketch and update the top-k heap if
// applicable. Returns the TopK to allow for chaining.
func (t *TopK) Add(data []byte) *TopK {
	t.cms.Add(data)
	t.n++

	freq := t.cms.Count(data)
	if t.isTop(freq) {
		t.insert(data, freq)
	}

	return t
}

// Elements returns the top-k elements from lowest to highest frequency.
func (t *TopK) Elements() [][]byte {
	if t.elements.Len() == 0 {
		return [][]byte{}
	}

	elements := make(elementHeap, t.k)
	copy(elements, *t.elements)
	heap.Init(&elements)
	topK := make([][]byte, 0, t.k)

	for elements.Len() > 0 {
		topK = append(topK, heap.Pop(&elements).(*element).data)
	}

	return topK
}

// Reset restores the TopK to its original state. It returns itself to allow
// for chaining.
func (t *TopK) Reset() *TopK {
	t.cms.Reset()
	elements := make(elementHeap, 0, t.k)
	heap.Init(&elements)
	t.elements = &elements
	t.n = 0
	return t
}

// isTop indicates if the given frequency falls within the top-k heap.
func (t *TopK) isTop(freq uint64) bool {
	if t.elements.Len() < int(t.k) {
		return true
	}

	return freq >= (*t.elements)[0].freq
}

// insert adds the data to the top-k heap. If the data is already an element,
// the frequency is updated. If the heap already has k elements, the element
// with the minimum frequency is removed.
func (t *TopK) insert(data []byte, freq uint64) {
	for _, element := range *t.elements {
		if bytes.Compare(data, element.data) == 0 {
			// Element already in top-k.
			element.freq = freq
			return
		}
	}

	if t.elements.Len() == int(t.k) {
		// Remove minimum-frequency element.
		heap.Pop(t.elements)
	}

	// Add element to top-k.
	heap.Push(t.elements, &element{data: data, freq: freq})
}
<commit_msg>change to topk<commit_after>package boom

import (
	"bytes"
	"container/heap"
)

type element struct {
	Data []byte
	Freq uint64
}

// An elementHeap is a min-heap of elements.
type elementHeap []*element

func (e elementHeap) Len() int           { return len(e) }
func (e elementHeap) Less(i, j int) bool { return e[i].Freq < e[j].Freq }
func (e elementHeap) Swap(i, j int)      { e[i], e[j] = e[j], e[i] }

func (e *elementHeap) Push(x interface{}) {
	*e = append(*e, x.(*element))
}

func (e *elementHeap) Pop() interface{} {
	old := *e
	n := len(old)
	x := old[n-1]
	*e = old[0 : n-1]
	return x
}

// TopK uses a Count-Min Sketch to calculate the top-K frequent elements in a
// stream.
type TopK struct {
	cms      *CountMinSketch
	k        int
	n        uint
	elements *elementHeap
}

// NewTopK creates a new TopK backed by a Count-Min sketch whose relative
// accuracy is within a factor of epsilon with probability delta. It tracks the
// k-most frequent elements.
func NewTopK(epsilon, delta float64, k int) *TopK {
	elements := make(elementHeap, 0, k)
	heap.Init(&elements)
	return &TopK{
		cms:      NewCountMinSketch(epsilon, delta),
		k:        k,
		elements: &elements,
	}
}

// Add will add the data to the Count-Min Sketch and update the top-k heap if
// applicable. Returns the TopK to allow for chaining.
func (t *TopK) Add(data []byte) *TopK {
	t.cms.Add(data)
	t.n++

	freq := t.cms.Count(data)
	if t.isTop(freq) {
		t.insert(data, freq)
	}

	return t
}

// Elements returns the top-k elements from lowest to highest frequency.
func (t *TopK) Elements() []*element {
	if t.elements.Len() == 0 {
		return []*element{}
	}
//        if t.elements.Len()<t.k {
  //      t.k=t.elements.Len()
//}
	elements := make(elementHeap, t.k)
	copy(elements, *t.elements)
	heap.Init(&elements)
	topK := make([]*element, 0, t.k)

	for elements.Len() > 0 {
		topK = append(topK, heap.Pop(&elements).(*element))
	}

	return topK
}

// Reset restores the TopK to its original state. It returns itself to allow
// for chaining.
func (t *TopK) Reset() *TopK {
	t.cms.Reset()
	elements := make(elementHeap, 0, t.k)
	heap.Init(&elements)
	t.elements = &elements
	t.n = 0
	return t
}

// isTop indicates if the given frequency falls within the top-k heap.
func (t *TopK) isTop(freq uint64) bool {
	if t.elements.Len() < int(t.k) {
		return true
	}

	return freq >= (*t.elements)[0].Freq
}

// insert adds the data to the top-k heap. If the data is already an element,
// the frequency is updated. If the heap already has k elements, the element
// with the minimum frequency is removed.
func (t *TopK) insert(data []byte, freq uint64) {
	for _, element := range *t.elements {
		if bytes.Compare(data, element.Data) == 0 {
			// Element already in top-k.
			element.Freq = freq
			return
		}
	}

	if t.elements.Len() == int(t.k) {
		// Remove minimum-frequency element.
		heap.Pop(t.elements)
	}

	// Add element to top-k.
	heap.Push(t.elements, &element{Data: data, Freq: freq})
}
<|endoftext|>