<commit_before>package gcng

import (
	"fmt"

	"code.cloudfoundry.org/lager"
	"github.com/concourse/atc/dbng"
)

type WorkerCollector interface {
	Run() error
}

type workerCollector struct {
	logger        lager.Logger
	workerFactory dbng.WorkerFactory
}

func NewWorkerCollector(
	logger lager.Logger,
	workerFactory dbng.WorkerFactory,
) WorkerCollector {
	return &workerCollector{
		logger:        logger,
		workerFactory: workerFactory,
	}
}

func (wc *workerCollector) Run() error {
	affected, err := wc.workerFactory.StallUnresponsiveWorkers()
	if err != nil {
		wc.logger.Error("failed-to-mark-workers-as-stalled", err)
		return err
	}

	wc.logger.Debug(fmt.Sprintf("stalled-%d-workers", len(affected)), lager.Data{"stalled-workers": affected})

	err = wc.workerFactory.DeleteFinishedRetiringWorkers()
	if err != nil {
		wc.logger.Error("failed-to-delete-finished-retiring-workers", err)
		return err
	}

	err = wc.workerFactory.LandFinishedLandingWorkers()
	if err != nil {
		wc.logger.Error("failed-to-land-finished-landing-workers", err)
		return err
	}

	wc.logger.Debug("completed-deleting-finished-landing-workers")

	return nil
}
<commit_msg>better logging for worker collector<commit_after>package gcng

import (
	"code.cloudfoundry.org/lager"
	"github.com/concourse/atc/dbng"
)

type WorkerCollector interface {
	Run() error
}

type workerCollector struct {
	logger        lager.Logger
	workerFactory dbng.WorkerFactory
}

func NewWorkerCollector(
	logger lager.Logger,
	workerFactory dbng.WorkerFactory,
) WorkerCollector {
	return &workerCollector{
		logger:        logger,
		workerFactory: workerFactory,
	}
}

func (wc *workerCollector) Run() error {
	logger := wc.logger.Session("collect")

	affected, err := wc.workerFactory.StallUnresponsiveWorkers()
	if err != nil {
		logger.Error("failed-to-mark-workers-as-stalled", err)
		return err
	}

	if len(affected) > 0 {
		workerNames := make([]string, len(affected))
		for i, w := range affected {
			workerNames[i] = w.Name
		}

		logger.Debug("stalled", lager.Data{"count": len(affected), "workers": workerNames})
	}

	err = wc.workerFactory.DeleteFinishedRetiringWorkers()
	if err != nil {
		logger.Error("failed-to-delete-finished-retiring-workers", err)
		return err
	}

	logger.Debug("deleted-finished-retiring-workers")

	err = wc.workerFactory.LandFinishedLandingWorkers()
	if err != nil {
		logger.Error("failed-to-land-finished-landing-workers", err)
		return err
	}

	logger.Debug("landed-finished-landing-workers")

	return nil
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"os"
	"path/filepath"
	"strings"

	"github.com/alecthomas/kingpin"
	"github.com/johnsto/ocrpdf"
)

var (
	debug   = false
	verbose = false

	app = kingpin.New("ocrpdf", "Converts scanned documents into searchable PDFs")

	files  = app.Arg("files", "filename(s)").Required().Strings()
	output = app.Flag("output", "output filename").Short('o').String()
	force  = app.Flag("force", "overwrite output file").Short('f').Bool()

	// Tesseract configuration
	tessData = app.Flag("tess-data", "Tesseract data directory").String()
	tessLang = app.Flag("tess-lang", "Tesseract language").String()

	// Document configuration
	docSize = app.Flag("size", "document size").
		Short('s').Default("a4").String()
	docOrientation = app.Flag("orientation", "document orientation").
			Default("auto").Short('r').Enum("auto", "portrait", "landscape")
	docCompress = app.Flag("compress", "compress document").
			Default("true").Short('c').Bool()

	// Document metadata
	docTitle    = app.Flag("title", "document title").Short('t').String()
	docSubject  = app.Flag("subject", "document subject").Short('j').String()
	docKeywords = app.Flag("keywords", "space-separated document keywords").
			Short('t').String()
	docAuthor  = app.Flag("author", "document author").Short('a').String()
	docCreator = app.Flag("creator", "document creator").
			Default("ocrpdf").String()

	// Font settings
	fontName = app.Flag("font-name", "text font").
			Default("Arial").String()
	fontStyle = app.Flag("font-style", "font style, [B]old, [I]talic, [U]nderline").
			PlaceHolder(" ").Enum("B", "I", "U", "BI", "BU", "IU", "BIU")
	fontSize = app.Flag("font-size", "OCR layer font size").
			Default("10").Float()

	// Text settings
	textScaling = app.Flag("scaling", "Scale text to match word boundaries").
			Default("match").Enum("off", "contain", "match")

	// Image settings
	imgContrast = app.Flag("contrast", "automatic contrast amount").
			Default("0.5").Float()
	imgFormat = app.Flag("format", "format to use when storing images in PDF").
			Default("auto").Enum("auto", "jpg", "png")
)

func init() {
	app.Flag("debug", "enable debug mode").Short('d').BoolVar(&debug)
	app.Flag("verbose", "enable verbose mode").Short('v').BoolVar(&verbose)
}

func main() {
	kingpin.MustParse(app.Parse(os.Args[1:]))

	logv("Initialising Tesseract...")
	tess, err := ocrpdf.NewTess(*tessData, *tessLang)

	if err != nil {
		logef("could not initialise Tesseract: %s\n", err)
		os.Exit(1)
	}

	doc := ocrpdf.NewDocument(*docSize)
	doc.SetDebug(debug)
	doc.SetFont(*fontName, *fontStyle, *fontSize)
	doc.SetTextScaling(ocrpdf.TextScaling(*textScaling))
	doc.SetTitle(*docTitle, true)
	doc.SetSubject(*docSubject, true)
	doc.SetKeywords(*docKeywords, true)
	doc.SetAuthor(*docAuthor, true)
	doc.SetCompression(*docCompress)
	doc.SetOrientation(ocrpdf.Orientation(*docOrientation))

	outfn := *output
	infns := *files
	if outfn == "" {
		// Search input files for a .pdf file
		pos := -1
		for i, fn := range infns {
			ext := strings.ToLower(filepath.Ext(fn))
			if ext == ".pdf" {
				if pos >= 0 {
					// two output files specified?
					logef("Multiple .pdf output files specified. " +
						"Use -o to specify output file explicitly.\n")
					os.Exit(1)
				}
				pos = i
				outfn = fn
			}
		}

		if pos >= 0 {
			// Remove output file from list of input files
			infns = append(infns[:pos], infns[pos+1:]...)
		} else {
			// No .pdf file on command line, so use name of first input instead
			outfn = infns[0]
			ext := filepath.Ext(outfn)
			outfn = strings.TrimRight(outfn, ext) + ".pdf"
		}
	}

	logvf("Using '%s' as output file.\n", outfn)

	openFlags := os.O_RDWR | os.O_CREATE
	if *force {
		openFlags |= os.O_TRUNC
	} else {
		openFlags |= os.O_EXCL
	}

	outfile, err := os.OpenFile(outfn, openFlags, 0666)

	if os.IsExist(err) {
		logef("Output file '%s' already exists. Use -force to overwrite.\n", outfn)
		os.Exit(1)
	} else if err != nil {
		logef("Couldn't create output file '%s': %s\n", outfn, err)
		os.Exit(1)
	}

	// Iterate through each filename specified, adding a page for each
	for i, fn := range infns {
		pageno := i + 1

		logvf("[P%d] Reading '%s'...\n", pageno, fn)
		img, err := ocrpdf.NewImageFromFile(fn)
		if err != nil {
			logef("Unable to read image from file '%s'\n", fn)
			os.Exit(1)
		}
		img = img.Adjust(float32(*imgContrast))
		tess.SetImagePix(img.CPIX())

		logvf("[P%d] Recognising...", pageno)
		words := tess.Words()
		logvf(" %d words found.\n", len(words))

		logvf("[P%d] Adding page\n", pageno)
		err = doc.AddPage(*img, fn, words, *imgFormat)
		if err != nil {
			fmt.Println(err)
			os.Exit(1)
		}
	}

	logvf("Writing output to '%s'...\n", outfn)

	doc.OutputAndClose(outfile)
}
<commit_msg>Fix incorrect keywords shorthand name<commit_after>package main

import (
	"fmt"
	"os"
	"path/filepath"
	"strings"

	"github.com/johnsto/ocrpdf"
	"gopkg.in/alecthomas/kingpin.v2"
)

var (
	debug   = false
	verbose = false

	app = kingpin.New("ocrpdf", "Converts scanned documents into searchable PDFs")

	files  = app.Arg("files", "filename(s)").Required().Strings()
	output = app.Flag("output", "output filename").Short('o').String()
	force  = app.Flag("force", "overwrite output file").Short('f').Bool()

	// Tesseract configuration
	tessData = app.Flag("tess-data", "Tesseract data directory").String()
	tessLang = app.Flag("tess-lang", "Tesseract language").String()

	// Document configuration
	docSize = app.Flag("size", "document size").
		Short('s').Default("a4").String()
	docOrientation = app.Flag("orientation", "document orientation").
			Default("auto").Short('r').Enum("auto", "portrait", "landscape")
	docCompress = app.Flag("compress", "compress document").
			Default("true").Short('c').Bool()

	// Document metadata
	docTitle    = app.Flag("title", "document title").Short('t').String()
	docSubject  = app.Flag("subject", "document subject").Short('j').String()
	docKeywords = app.Flag("keywords", "space-separated document keywords").
			Short('k').String()
	docAuthor  = app.Flag("author", "document author").Short('a').String()
	docCreator = app.Flag("creator", "document creator").
			Default("ocrpdf").String()

	// Font settings
	fontName = app.Flag("font-name", "text font").
			Default("Arial").String()
	fontStyle = app.Flag("font-style", "font style, [B]old, [I]talic, [U]nderline").
			PlaceHolder(" ").Enum("B", "I", "U", "BI", "BU", "IU", "BIU")
	fontSize = app.Flag("font-size", "OCR layer font size").
			Default("10").Float()

	// Text settings
	textScaling = app.Flag("scaling", "Scale text to match word boundaries").
			Default("match").Enum("off", "contain", "match")

	// Image settings
	imgContrast = app.Flag("contrast", "automatic contrast amount").
			Default("0.5").Float()
	imgFormat = app.Flag("format", "format to use when storing images in PDF").
			Default("auto").Enum("auto", "jpg", "png")
)

func init() {
	app.Flag("debug", "enable debug mode").Short('d').BoolVar(&debug)
	app.Flag("verbose", "enable verbose mode").Short('v').BoolVar(&verbose)
}

func main() {
	kingpin.MustParse(app.Parse(os.Args[1:]))

	logv("Initialising Tesseract...")
	tess, err := ocrpdf.NewTess(*tessData, *tessLang)

	if err != nil {
		logef("could not initialise Tesseract: %s\n", err)
		os.Exit(1)
	}

	doc := ocrpdf.NewDocument(*docSize)
	doc.SetDebug(debug)
	doc.SetFont(*fontName, *fontStyle, *fontSize)
	doc.SetTextScaling(ocrpdf.TextScaling(*textScaling))
	doc.SetTitle(*docTitle, true)
	doc.SetSubject(*docSubject, true)
	doc.SetKeywords(*docKeywords, true)
	doc.SetAuthor(*docAuthor, true)
	doc.SetCompression(*docCompress)
	doc.SetOrientation(ocrpdf.Orientation(*docOrientation))

	outfn := *output
	infns := *files
	if outfn == "" {
		// Search input files for a .pdf file
		pos := -1
		for i, fn := range infns {
			ext := strings.ToLower(filepath.Ext(fn))
			if ext == ".pdf" {
				if pos >= 0 {
					// two output files specified?
					logef("Multiple .pdf output files specified. " +
						"Use -o to specify output file explicitly.\n")
					os.Exit(1)
				}
				pos = i
				outfn = fn
			}
		}

		if pos >= 0 {
			// Remove output file from list of input files
			infns = append(infns[:pos], infns[pos+1:]...)
		} else {
			// No .pdf file on command line, so use name of first input instead
			outfn = infns[0]
			ext := filepath.Ext(outfn)
			outfn = strings.TrimRight(outfn, ext) + ".pdf"
		}
	}

	logvf("Using '%s' as output file.\n", outfn)

	openFlags := os.O_RDWR | os.O_CREATE
	if *force {
		openFlags |= os.O_TRUNC
	} else {
		openFlags |= os.O_EXCL
	}

	outfile, err := os.OpenFile(outfn, openFlags, 0666)

	if os.IsExist(err) {
		logef("Output file '%s' already exists. Use -force to overwrite.\n", outfn)
		os.Exit(1)
	} else if err != nil {
		logef("Couldn't create output file '%s': %s\n", outfn, err)
		os.Exit(1)
	}

	// Iterate through each filename specified, adding a page for each
	for i, fn := range infns {
		pageno := i + 1

		logvf("[P%d] Reading '%s'...\n", pageno, fn)
		img, err := ocrpdf.NewImageFromFile(fn)
		if err != nil {
			logef("Unable to read image from file '%s'\n", fn)
			os.Exit(1)
		}
		img = img.Adjust(float32(*imgContrast))
		tess.SetImagePix(img.CPIX())

		logvf("[P%d] Recognising...", pageno)
		words := tess.Words()
		logvf(" %d words found.\n", len(words))

		logvf("[P%d] Adding page\n", pageno)
		err = doc.AddPage(*img, fn, words, *imgFormat)
		if err != nil {
			fmt.Println(err)
			os.Exit(1)
		}
	}

	logvf("Writing output to '%s'...\n", outfn)

	doc.OutputAndClose(outfile)
}
<|endoftext|>


<commit_before>package gqlerrors

import (
	"fmt"

	"github.com/graphql-go/graphql/language/ast"
	"github.com/graphql-go/graphql/language/location"
	"github.com/graphql-go/graphql/language/source"
)

type Error struct {
	Message       string
	Stack         string
	Nodes         []ast.Node
	Source        *source.Source
	Positions     []int
	Locations     []location.SourceLocation
	OriginalError error
}

// implements Golang's built-in `error` interface
func (g Error) Error() string {
	return fmt.Sprintf("%v", g.Message)
}

func NewError(message string, nodes []ast.Node, stack string, source *source.Source, positions []int, origError error) *Error {
	if stack == "" && message != "" {
		stack = message
	}
	if source == nil {
		for _, node := range nodes {
			// get source from first node
			if node.GetLoc() != nil {
				source = node.GetLoc().Source
			}
			break
		}
	}
	if len(positions) == 0 && len(nodes) > 0 {
		for _, node := range nodes {
			if node.GetLoc() == nil {
				continue
			}
			positions = append(positions, node.GetLoc().Start)
		}
	}
	locations := []location.SourceLocation{}
	for _, pos := range positions {
		loc := location.GetLocation(source, pos)
		locations = append(locations, loc)
	}
	return &Error{
		Message:       message,
		Stack:         stack,
		Nodes:         nodes,
		Source:        source,
		Positions:     positions,
		Locations:     locations,
		OriginalError: origError,
	}
}
<commit_msg>Add checking if node != nil - NewError, gqlerrors<commit_after>package gqlerrors

import (
	"fmt"
	"reflect"

	"github.com/graphql-go/graphql/language/ast"
	"github.com/graphql-go/graphql/language/location"
	"github.com/graphql-go/graphql/language/source"
)

type Error struct {
	Message       string
	Stack         string
	Nodes         []ast.Node
	Source        *source.Source
	Positions     []int
	Locations     []location.SourceLocation
	OriginalError error
}

// implements Golang's built-in `error` interface
func (g Error) Error() string {
	return fmt.Sprintf("%v", g.Message)
}

func NewError(message string, nodes []ast.Node, stack string, source *source.Source, positions []int, origError error) *Error {
	if stack == "" && message != "" {
		stack = message
	}
	if source == nil {
		for _, node := range nodes {
			// get source from first node
			if node == nil || reflect.ValueOf(node).IsNil() {
				continue
			}
			if node.GetLoc() != nil {
				source = node.GetLoc().Source
			}
			break
		}
	}
	if len(positions) == 0 && len(nodes) > 0 {
		for _, node := range nodes {
			if node == nil || reflect.ValueOf(node).IsNil() {
				continue
			}
			if node.GetLoc() == nil {
				continue
			}
			positions = append(positions, node.GetLoc().Start)
		}
	}
	locations := []location.SourceLocation{}
	for _, pos := range positions {
		loc := location.GetLocation(source, pos)
		locations = append(locations, loc)
	}
	return &Error{
		Message:       message,
		Stack:         stack,
		Nodes:         nodes,
		Source:        source,
		Positions:     positions,
		Locations:     locations,
		OriginalError: origError,
	}
}
<|endoftext|>


<commit_before>package ethchain

import (
	"fmt"
	"math/big"

	"github.com/ethereum/eth-go/ethstate"
	"github.com/ethereum/eth-go/ethtrie"
	"github.com/ethereum/eth-go/ethutil"
	"github.com/ethereum/eth-go/ethvm"
)

/*
 * The State transitioning model
 *
 * A state transition is a change made when a transaction is applied to the current world state
 * The state transitioning model does all all the necessary work to work out a valid new state root.
 * 1) Nonce handling
 * 2) Pre pay / buy gas of the coinbase (miner)
 * 3) Create a new state object if the recipient is \0*32
 * 4) Value transfer
 * == If contract creation ==
 * 4a) Attempt to run transaction data
 * 4b) If valid, use result as code for the new state object
 * == end ==
 * 5) Run Script section
 * 6) Derive new state root
 */
type StateTransition struct {
	coinbase, receiver []byte
	tx                 *Transaction
	gas, gasPrice      *big.Int
	value              *big.Int
	data               []byte
	state              *ethstate.State
	block              *Block

	cb, rec, sen *ethstate.StateObject
}

func NewStateTransition(coinbase *ethstate.StateObject, tx *Transaction, state *ethstate.State, block *Block) *StateTransition {
	return &StateTransition{coinbase.Address(), tx.Recipient, tx, new(big.Int), new(big.Int).Set(tx.GasPrice), tx.Value, tx.Data, state, block, coinbase, nil, nil}
}

func (self *StateTransition) Coinbase() *ethstate.StateObject {
	if self.cb != nil {
		return self.cb
	}

	self.cb = self.state.GetOrNewStateObject(self.coinbase)
	return self.cb
}
func (self *StateTransition) Sender() *ethstate.StateObject {
	if self.sen != nil {
		return self.sen
	}

	self.sen = self.state.GetOrNewStateObject(self.tx.Sender())

	return self.sen
}
func (self *StateTransition) Receiver() *ethstate.StateObject {
	if self.tx != nil && self.tx.CreatesContract() {
		return nil
	}

	if self.rec != nil {
		return self.rec
	}

	self.rec = self.state.GetOrNewStateObject(self.tx.Recipient)
	return self.rec
}

func (self *StateTransition) MakeStateObject(state *ethstate.State, tx *Transaction) *ethstate.StateObject {
	contract := MakeContract(tx, state)

	return contract
}

func (self *StateTransition) UseGas(amount *big.Int) error {
	if self.gas.Cmp(amount) < 0 {
		return OutOfGasError()
	}
	self.gas.Sub(self.gas, amount)

	return nil
}

func (self *StateTransition) AddGas(amount *big.Int) {
	self.gas.Add(self.gas, amount)
}

func (self *StateTransition) BuyGas() error {
	var err error

	sender := self.Sender()
	if sender.Balance.Cmp(self.tx.GasValue()) < 0 {
		return fmt.Errorf("Insufficient funds to pre-pay gas. Req %v, has %v", self.tx.GasValue(), sender.Balance)
	}

	coinbase := self.Coinbase()
	err = coinbase.BuyGas(self.tx.Gas, self.tx.GasPrice)
	if err != nil {
		return err
	}

	self.AddGas(self.tx.Gas)
	sender.SubAmount(self.tx.GasValue())

	return nil
}

func (self *StateTransition) RefundGas() {
	coinbase, sender := self.Coinbase(), self.Sender()
	coinbase.RefundGas(self.gas, self.tx.GasPrice)

	// Return remaining gas
	remaining := new(big.Int).Mul(self.gas, self.tx.GasPrice)
	sender.AddAmount(remaining)
}

func (self *StateTransition) preCheck() (err error) {
	var (
		tx     = self.tx
		sender = self.Sender()
	)

	// Make sure this transaction's nonce is correct
	if sender.Nonce != tx.Nonce {
		return NonceError(tx.Nonce, sender.Nonce)
	}

	// Pre-pay gas / Buy gas of the coinbase account
	if err = self.BuyGas(); err != nil {
		return err
	}

	return nil
}

func (self *StateTransition) TransitionState() (err error) {
	statelogger.Debugf("(~) %x\n", self.tx.Hash())

	defer func() {
		if r := recover(); r != nil {
			statelogger.Infoln(r)
			err = fmt.Errorf("state transition err %v", r)
		}
	}()

	// XXX Transactions after this point are considered valid.
	if err = self.preCheck(); err != nil {
		return
	}

	var (
		tx       = self.tx
		sender   = self.Sender()
		receiver *ethstate.StateObject
	)

	defer self.RefundGas()

	// Increment the nonce for the next transaction
	sender.Nonce += 1

	// Transaction gas
	if err = self.UseGas(ethvm.GasTx); err != nil {
		return
	}

	// Pay data gas
	dataPrice := big.NewInt(int64(len(self.data)))
	dataPrice.Mul(dataPrice, ethvm.GasData)
	if err = self.UseGas(dataPrice); err != nil {
		return
	}

	if sender.Balance.Cmp(self.value) < 0 {
		return fmt.Errorf("Insufficient funds to transfer value. Req %v, has %v", self.value, sender.Balance)
	}

	var snapshot *ethstate.State
	// If the receiver is nil it's a contract (\0*32).
	if tx.CreatesContract() {
		// Subtract the (irreversible) amount from the senders account
		sender.SubAmount(self.value)

		snapshot = self.state.Copy()

		// Create a new state object for the contract
		receiver = self.MakeStateObject(self.state, tx)
		self.rec = receiver
		if receiver == nil {
			return fmt.Errorf("Unable to create contract")
		}

		// Add the amount to receivers account which should conclude this transaction
		receiver.AddAmount(self.value)
	} else {
		receiver = self.Receiver()

		// Subtract the amount from the senders account
		sender.SubAmount(self.value)
		// Add the amount to receivers account which should conclude this transaction
		receiver.AddAmount(self.value)

		snapshot = self.state.Copy()
	}

	msg := self.state.Manifest().AddMessage(&ethstate.Message{
		To: receiver.Address(), From: sender.Address(),
		Input:  self.tx.Data,
		Origin: sender.Address(),
		Block:  self.block.Hash(), Timestamp: self.block.Time, Coinbase: self.block.Coinbase, Number: self.block.Number,
		Value: self.value,
	})

	// Process the init code and create 'valid' contract
	if IsContractAddr(self.receiver) {
		// Evaluate the initialization script
		// and use the return value as the
		// script section for the state object.
		self.data = nil

		code, err := self.Eval(msg, receiver.Init(), receiver)
		if err != nil {
			self.state.Set(snapshot)

			return fmt.Errorf("Error during init execution %v", err)
		}

		receiver.Code = code
		msg.Output = code
	} else {
		if len(receiver.Code) > 0 {
			ret, err := self.Eval(msg, receiver.Code, receiver)
			if err != nil {
				self.state.Set(snapshot)

				return fmt.Errorf("Error during code execution %v", err)
			}

			msg.Output = ret
		}
	}

	return
}

func (self *StateTransition) transferValue(sender, receiver *ethstate.StateObject) error {
	if sender.Balance.Cmp(self.value) < 0 {
		return fmt.Errorf("Insufficient funds to transfer value. Req %v, has %v", self.value, sender.Balance)
	}

	// Subtract the amount from the senders account
	sender.SubAmount(self.value)
	// Add the amount to receivers account which should conclude this transaction
	receiver.AddAmount(self.value)

	return nil
}

func (self *StateTransition) Eval(msg *ethstate.Message, script []byte, context *ethstate.StateObject) (ret []byte, err error) {
	var (
		transactor    = self.Sender()
		state         = self.state
		env           = NewEnv(state, self.tx, self.block)
		callerClosure = ethvm.NewClosure(msg, transactor, context, script, self.gas, self.gasPrice)
	)

	//vm := ethvm.New(env, ethvm.Type(ethutil.Config.VmType))
	vm := ethutil.New(env, ethvm.DebugVmTy)

	ret, _, err = callerClosure.Call(vm, self.tx.Data)

	return
}

// Converts an transaction in to a state object
func MakeContract(tx *Transaction, state *ethstate.State) *ethstate.StateObject {
	// Create contract if there's no recipient
	if tx.IsContract() {
		addr := tx.CreationAddress(state)

		contract := state.GetOrNewStateObject(addr)
		contract.InitCode = tx.Data
		contract.State = ethstate.New(ethtrie.New(ethutil.Config.Db, ""))

		return contract
	}

	return nil
}
<commit_msg>Corrected package ....<commit_after>package ethchain

import (
	"fmt"
	"math/big"

	"github.com/ethereum/eth-go/ethstate"
	"github.com/ethereum/eth-go/ethtrie"
	"github.com/ethereum/eth-go/ethutil"
	"github.com/ethereum/eth-go/ethvm"
)

/*
 * The State transitioning model
 *
 * A state transition is a change made when a transaction is applied to the current world state
 * The state transitioning model does all all the necessary work to work out a valid new state root.
 * 1) Nonce handling
 * 2) Pre pay / buy gas of the coinbase (miner)
 * 3) Create a new state object if the recipient is \0*32
 * 4) Value transfer
 * == If contract creation ==
 * 4a) Attempt to run transaction data
 * 4b) If valid, use result as code for the new state object
 * == end ==
 * 5) Run Script section
 * 6) Derive new state root
 */
type StateTransition struct {
	coinbase, receiver []byte
	tx                 *Transaction
	gas, gasPrice      *big.Int
	value              *big.Int
	data               []byte
	state              *ethstate.State
	block              *Block

	cb, rec, sen *ethstate.StateObject
}

func NewStateTransition(coinbase *ethstate.StateObject, tx *Transaction, state *ethstate.State, block *Block) *StateTransition {
	return &StateTransition{coinbase.Address(), tx.Recipient, tx, new(big.Int), new(big.Int).Set(tx.GasPrice), tx.Value, tx.Data, state, block, coinbase, nil, nil}
}

func (self *StateTransition) Coinbase() *ethstate.StateObject {
	if self.cb != nil {
		return self.cb
	}

	self.cb = self.state.GetOrNewStateObject(self.coinbase)
	return self.cb
}
func (self *StateTransition) Sender() *ethstate.StateObject {
	if self.sen != nil {
		return self.sen
	}

	self.sen = self.state.GetOrNewStateObject(self.tx.Sender())

	return self.sen
}
func (self *StateTransition) Receiver() *ethstate.StateObject {
	if self.tx != nil && self.tx.CreatesContract() {
		return nil
	}

	if self.rec != nil {
		return self.rec
	}

	self.rec = self.state.GetOrNewStateObject(self.tx.Recipient)
	return self.rec
}

func (self *StateTransition) MakeStateObject(state *ethstate.State, tx *Transaction) *ethstate.StateObject {
	contract := MakeContract(tx, state)

	return contract
}

func (self *StateTransition) UseGas(amount *big.Int) error {
	if self.gas.Cmp(amount) < 0 {
		return OutOfGasError()
	}
	self.gas.Sub(self.gas, amount)

	return nil
}

func (self *StateTransition) AddGas(amount *big.Int) {
	self.gas.Add(self.gas, amount)
}

func (self *StateTransition) BuyGas() error {
	var err error

	sender := self.Sender()
	if sender.Balance.Cmp(self.tx.GasValue()) < 0 {
		return fmt.Errorf("Insufficient funds to pre-pay gas. Req %v, has %v", self.tx.GasValue(), sender.Balance)
	}

	coinbase := self.Coinbase()
	err = coinbase.BuyGas(self.tx.Gas, self.tx.GasPrice)
	if err != nil {
		return err
	}

	self.AddGas(self.tx.Gas)
	sender.SubAmount(self.tx.GasValue())

	return nil
}

func (self *StateTransition) RefundGas() {
	coinbase, sender := self.Coinbase(), self.Sender()
	coinbase.RefundGas(self.gas, self.tx.GasPrice)

	// Return remaining gas
	remaining := new(big.Int).Mul(self.gas, self.tx.GasPrice)
	sender.AddAmount(remaining)
}

func (self *StateTransition) preCheck() (err error) {
	var (
		tx     = self.tx
		sender = self.Sender()
	)

	// Make sure this transaction's nonce is correct
	if sender.Nonce != tx.Nonce {
		return NonceError(tx.Nonce, sender.Nonce)
	}

	// Pre-pay gas / Buy gas of the coinbase account
	if err = self.BuyGas(); err != nil {
		return err
	}

	return nil
}

func (self *StateTransition) TransitionState() (err error) {
	statelogger.Debugf("(~) %x\n", self.tx.Hash())

	defer func() {
		if r := recover(); r != nil {
			statelogger.Infoln(r)
			err = fmt.Errorf("state transition err %v", r)
		}
	}()

	// XXX Transactions after this point are considered valid.
	if err = self.preCheck(); err != nil {
		return
	}

	var (
		tx       = self.tx
		sender   = self.Sender()
		receiver *ethstate.StateObject
	)

	defer self.RefundGas()

	// Increment the nonce for the next transaction
	sender.Nonce += 1

	// Transaction gas
	if err = self.UseGas(ethvm.GasTx); err != nil {
		return
	}

	// Pay data gas
	dataPrice := big.NewInt(int64(len(self.data)))
	dataPrice.Mul(dataPrice, ethvm.GasData)
	if err = self.UseGas(dataPrice); err != nil {
		return
	}

	if sender.Balance.Cmp(self.value) < 0 {
		return fmt.Errorf("Insufficient funds to transfer value. Req %v, has %v", self.value, sender.Balance)
	}

	var snapshot *ethstate.State
	// If the receiver is nil it's a contract (\0*32).
	if tx.CreatesContract() {
		// Subtract the (irreversible) amount from the senders account
		sender.SubAmount(self.value)

		snapshot = self.state.Copy()

		// Create a new state object for the contract
		receiver = self.MakeStateObject(self.state, tx)
		self.rec = receiver
		if receiver == nil {
			return fmt.Errorf("Unable to create contract")
		}

		// Add the amount to receivers account which should conclude this transaction
		receiver.AddAmount(self.value)
	} else {
		receiver = self.Receiver()

		// Subtract the amount from the senders account
		sender.SubAmount(self.value)
		// Add the amount to receivers account which should conclude this transaction
		receiver.AddAmount(self.value)

		snapshot = self.state.Copy()
	}

	msg := self.state.Manifest().AddMessage(&ethstate.Message{
		To: receiver.Address(), From: sender.Address(),
		Input:  self.tx.Data,
		Origin: sender.Address(),
		Block:  self.block.Hash(), Timestamp: self.block.Time, Coinbase: self.block.Coinbase, Number: self.block.Number,
		Value: self.value,
	})

	// Process the init code and create 'valid' contract
	if IsContractAddr(self.receiver) {
		// Evaluate the initialization script
		// and use the return value as the
		// script section for the state object.
		self.data = nil

		code, err := self.Eval(msg, receiver.Init(), receiver)
		if err != nil {
			self.state.Set(snapshot)

			return fmt.Errorf("Error during init execution %v", err)
		}

		receiver.Code = code
		msg.Output = code
	} else {
		if len(receiver.Code) > 0 {
			ret, err := self.Eval(msg, receiver.Code, receiver)
			if err != nil {
				self.state.Set(snapshot)

				return fmt.Errorf("Error during code execution %v", err)
			}

			msg.Output = ret
		}
	}

	return
}

func (self *StateTransition) transferValue(sender, receiver *ethstate.StateObject) error {
	if sender.Balance.Cmp(self.value) < 0 {
		return fmt.Errorf("Insufficient funds to transfer value. Req %v, has %v", self.value, sender.Balance)
	}

	// Subtract the amount from the senders account
	sender.SubAmount(self.value)
	// Add the amount to receivers account which should conclude this transaction
	receiver.AddAmount(self.value)

	return nil
}

func (self *StateTransition) Eval(msg *ethstate.Message, script []byte, context *ethstate.StateObject) (ret []byte, err error) {
	var (
		transactor    = self.Sender()
		state         = self.state
		env           = NewEnv(state, self.tx, self.block)
		callerClosure = ethvm.NewClosure(msg, transactor, context, script, self.gas, self.gasPrice)
	)

	//vm := ethvm.New(env, ethvm.Type(ethutil.Config.VmType))
	vm := ethvm.New(env, ethvm.DebugVmTy)

	ret, _, err = callerClosure.Call(vm, self.tx.Data)

	return
}

// Converts an transaction in to a state object
func MakeContract(tx *Transaction, state *ethstate.State) *ethstate.StateObject {
	// Create contract if there's no recipient
	if tx.IsContract() {
		addr := tx.CreationAddress(state)

		contract := state.GetOrNewStateObject(addr)
		contract.InitCode = tx.Data
		contract.State = ethstate.New(ethtrie.New(ethutil.Config.Db, ""))

		return contract
	}

	return nil
}
<|endoftext|>


<commit_before>// Copyright 2012 Jesse van den Kieboom. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package flags

import (
	"bufio"
	"bytes"
	"fmt"
	"io"
	"reflect"
	"runtime"
	"strings"
	"unicode/utf8"
)

type alignmentInfo struct {
	maxLongLen      int
	hasShort        bool
	hasValueName    bool
	terminalColumns int
	indent          bool
}

const (
	paddingBeforeOption                 = 2
	distanceBetweenOptionAndDescription = 2
)

func (a *alignmentInfo) descriptionStart() int {
	ret := a.maxLongLen + distanceBetweenOptionAndDescription

	if a.hasShort {
		ret += 2
	}

	if a.maxLongLen > 0 {
		ret += 4
	}

	if a.hasValueName {
		ret += 3
	}

	return ret
}

func (a *alignmentInfo) updateLen(name string, indent bool) {
	l := utf8.RuneCountInString(name)

	if indent {
		l = l + 4
	}

	if l > a.maxLongLen {
		a.maxLongLen = l
	}
}

func (p *Parser) getAlignmentInfo() alignmentInfo {
	ret := alignmentInfo{
		maxLongLen:      0,
		hasShort:        false,
		hasValueName:    false,
		terminalColumns: getTerminalColumns(),
	}

	if ret.terminalColumns <= 0 {
		ret.terminalColumns = 80
	}

	var prevcmd *Command

	p.eachActiveGroup(func(c *Command, grp *Group) {
		if c != prevcmd {
			for _, arg := range c.args {
				ret.updateLen(arg.Name, c != p.Command)
			}
		}

		for _, info := range grp.options {
			if !info.canCli() {
				continue
			}

			if info.ShortName != 0 {
				ret.hasShort = true
			}

			if len(info.ValueName) > 0 {
				ret.hasValueName = true
			}

			ret.updateLen(info.LongNameWithNamespace()+info.ValueName, c != p.Command)
		}
	})

	return ret
}

func (p *Parser) writeHelpOption(writer *bufio.Writer, option *Option, info alignmentInfo) {
	line := &bytes.Buffer{}

	prefix := paddingBeforeOption

	if info.indent {
		prefix += 4
	}

	line.WriteString(strings.Repeat(" ", prefix))

	if option.ShortName != 0 {
		line.WriteRune(defaultShortOptDelimiter)
		line.WriteRune(option.ShortName)
	} else if info.hasShort {
		line.WriteString("  ")
	}

	descstart := info.descriptionStart() + paddingBeforeOption

	if len(option.LongName) > 0 {
		if option.ShortName != 0 {
			line.WriteString(", ")
		} else if info.hasShort {
			line.WriteString("  ")
		}

		line.WriteString(defaultLongOptDelimiter)
		line.WriteString(option.LongNameWithNamespace())
	}

	if option.canArgument() {
		line.WriteRune(defaultNameArgDelimiter)

		if len(option.ValueName) > 0 {
			line.WriteString(option.ValueName)
		}
	}

	written := line.Len()
	line.WriteTo(writer)

	if option.Description != "" {
		dw := descstart - written
		writer.WriteString(strings.Repeat(" ", dw))

		def := ""
		defs := option.Default

		if len(option.DefaultMask) != 0 {
			if option.DefaultMask != "-" {
				def = option.DefaultMask
			}
		} else if len(defs) == 0 && option.canArgument() {
			var showdef bool

			switch option.field.Type.Kind() {
			case reflect.Func, reflect.Ptr:
				showdef = !option.value.IsNil()
			case reflect.Slice, reflect.String, reflect.Array:
				showdef = option.value.Len() > 0
			case reflect.Map:
				showdef = !option.value.IsNil() && option.value.Len() > 0
			default:
				zeroval := reflect.Zero(option.field.Type)
				showdef = !reflect.DeepEqual(zeroval.Interface(), option.value.Interface())
			}

			if showdef {
				def, _ = convertToString(option.value, option.tag)
			}
		} else if len(defs) != 0 {
			if option.field.Type.Kind() == reflect.String {
				l := len(defs) - 1

				for i := 0; i < l; i++ {
					def += quoteIfNeeded(defs[i]) + ", "
				}

				def += quoteIfNeeded(defs[l])
			} else {
				def = strings.Join(defs, ", ")
			}
		}

		var envDef string
		if option.EnvDefaultKey != "" {
			var envPrintable string
			if runtime.GOOS == "windows" {
				envPrintable = "%" + option.EnvDefaultKey + "%"
			} else {
				envPrintable = "$" + option.EnvDefaultKey
			}
			envDef = fmt.Sprintf(" [%s]", envPrintable)
		}

		var desc string

		if def != "" {
			desc = fmt.Sprintf("%s (%v)%s", option.Description, def, envDef)
		} else {
			desc = option.Description + envDef
		}

		writer.WriteString(wrapText(desc,
			info.terminalColumns-descstart,
			strings.Repeat(" ", descstart)))
	}

	writer.WriteString("\n")
}

func maxCommandLength(s []*Command) int {
	if len(s) == 0 {
		return 0
	}

	ret := len(s[0].Name)

	for _, v := range s[1:] {
		l := len(v.Name)

		if l > ret {
			ret = l
		}
	}

	return ret
}

// WriteHelp writes a help message containing all the possible options and
// their descriptions to the provided writer. Note that the HelpFlag parser
// option provides a convenient way to add a -h/--help option group to the
// command line parser which will automatically show the help messages using
// this method.
func (p *Parser) WriteHelp(writer io.Writer) {
	if writer == nil {
		return
	}

	wr := bufio.NewWriter(writer)
	aligninfo := p.getAlignmentInfo()

	cmd := p.Command

	for cmd.Active != nil {
		cmd = cmd.Active
	}

	if p.Name != "" {
		wr.WriteString("Usage:\n")
		wr.WriteString(" ")

		allcmd := p.Command

		for allcmd != nil {
			var usage string

			if allcmd == p.Command {
				if len(p.Usage) != 0 {
					usage = p.Usage
				} else if p.Options&HelpFlag != 0 {
					usage = "[OPTIONS]"
				}
			} else if us, ok := allcmd.data.(Usage); ok {
				usage = us.Usage()
			} else if allcmd.hasCliOptions() {
				usage = fmt.Sprintf("[%s-OPTIONS]", allcmd.Name)
			}

			if len(usage) != 0 {
				fmt.Fprintf(wr, " %s %s", allcmd.Name, usage)
			} else {
				fmt.Fprintf(wr, " %s", allcmd.Name)
			}

			if len(allcmd.args) > 0 {
				fmt.Fprintf(wr, " ")
			}

			for i, arg := range allcmd.args {
				if i != 0 {
					fmt.Fprintf(wr, " ")
				}

				name := arg.Name

				if arg.isRemaining() {
					name = name + "..."
				}

				if !allcmd.ArgsRequired {
					fmt.Fprintf(wr, "[%s]", name)
				} else {
					fmt.Fprintf(wr, "%s", name)
				}
			}

			if allcmd.Active == nil && len(allcmd.commands) > 0 {
				var co, cc string

				if allcmd.SubcommandsOptional {
					co, cc = "[", "]"
				} else {
					co, cc = "<", ">"
				}

				if len(allcmd.commands) > 3 {
					fmt.Fprintf(wr, " %scommand%s", co, cc)
				} else {
					subcommands := allcmd.sortedCommands()
					names := make([]string, len(subcommands))

					for i, subc := range subcommands {
						names[i] = subc.Name
					}

					fmt.Fprintf(wr, " %s%s%s", co, strings.Join(names, " | "), cc)
				}
			}

			allcmd = allcmd.Active
		}

		fmt.Fprintln(wr)

		if len(cmd.LongDescription) != 0 {
			fmt.Fprintln(wr)

			t := wrapText(cmd.LongDescription,
				aligninfo.terminalColumns,
				"")

			fmt.Fprintln(wr, t)
		}
	}

	c := p.Command

	for c != nil {
		printcmd := c != p.Command

		c.eachGroup(func(grp *Group) {
			first := true

			// Skip built-in help group for all commands except the top-level
			// parser
			if grp.isBuiltinHelp && c != p.Command {
				return
			}

			for _, info := range grp.options {
				if !info.canCli() {
					continue
				}

				if printcmd {
					fmt.Fprintf(wr, "\n[%s command options]\n", c.Name)
					aligninfo.indent = true
					printcmd = false
				}

				if first && cmd.Group != grp {
					fmt.Fprintln(wr)

					if aligninfo.indent {
						wr.WriteString("    ")
					}

					fmt.Fprintf(wr, "%s:\n", grp.ShortDescription)
					first = false
				}

				p.writeHelpOption(wr, info, aligninfo)
			}
		})

		if len(c.args) > 0 {
			if c == p.Command {
				fmt.Fprintf(wr, "\nArguments:\n")
			} else {
				fmt.Fprintf(wr, "\n[%s command arguments]\n", c.Name)
			}

			maxlen := aligninfo.descriptionStart()

			for _, arg := range c.args {
				prefix := strings.Repeat(" ", paddingBeforeOption)
				fmt.Fprintf(wr, "%s%s", prefix, arg.Name)

				if len(arg.Description) > 0 {
					align := strings.Repeat(" ", maxlen-len(arg.Name)-1)
					fmt.Fprintf(wr, ":%s%s", align, arg.Description)
				}

				fmt.Fprintln(wr)
			}
		}

		c = c.Active
	}

	scommands := cmd.sortedCommands()

	if len(scommands) > 0 {
		maxnamelen := maxCommandLength(scommands)

		fmt.Fprintln(wr)
		fmt.Fprintln(wr, "Available commands:")

		for _, c := range scommands {
			fmt.Fprintf(wr, "  %s", c.Name)

			if len(c.ShortDescription) > 0 {
				pad := strings.Repeat(" ", maxnamelen-len(c.Name))
				fmt.Fprintf(wr, "%s  %s", pad, c.ShortDescription)

				if len(c.Aliases) > 0 {
					fmt.Fprintf(wr, " (aliases: %s)", strings.Join(c.Aliases, ", "))
				}

			}

			fmt.Fprintln(wr)
		}
	}

	wr.Flush()
}
<commit_msg>always check if default values need quotes<commit_after>// Copyright 2012 Jesse van den Kieboom. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package flags

import (
	"bufio"
	"bytes"
	"fmt"
	"io"
	"reflect"
	"runtime"
	"strings"
	"unicode/utf8"
)

type alignmentInfo struct {
	maxLongLen      int
	hasShort        bool
	hasValueName    bool
	terminalColumns int
	indent          bool
}

const (
	paddingBeforeOption                 = 2
	distanceBetweenOptionAndDescription = 2
)

func (a *alignmentInfo) descriptionStart() int {
	ret := a.maxLongLen + distanceBetweenOptionAndDescription

	if a.hasShort {
		ret += 2
	}

	if a.maxLongLen > 0 {
		ret += 4
	}

	if a.hasValueName {
		ret += 3
	}

	return ret
}

func (a *alignmentInfo) updateLen(name string, indent bool) {
	l := utf8.RuneCountInString(name)

	if indent {
		l = l + 4
	}

	if l > a.maxLongLen {
		a.maxLongLen = l
	}
}

func (p *Parser) getAlignmentInfo() alignmentInfo {
	ret := alignmentInfo{
		maxLongLen:      0,
		hasShort:        false,
		hasValueName:    false,
		terminalColumns: getTerminalColumns(),
	}

	if ret.terminalColumns <= 0 {
		ret.terminalColumns = 80
	}

	var prevcmd *Command

	p.eachActiveGroup(func(c *Command, grp *Group) {
		if c != prevcmd {
			for _, arg := range c.args {
				ret.updateLen(arg.Name, c != p.Command)
			}
		}

		for _, info := range grp.options {
			if !info.canCli() {
				continue
			}

			if info.ShortName != 0 {
				ret.hasShort = true
			}

			if len(info.ValueName) > 0 {
				ret.hasValueName = true
			}

			ret.updateLen(info.LongNameWithNamespace()+info.ValueName, c != p.Command)
		}
	})

	return ret
}

func (p *Parser) writeHelpOption(writer *bufio.Writer, option *Option, info alignmentInfo) {
	line := &bytes.Buffer{}

	prefix := paddingBeforeOption

	if info.indent {
		prefix += 4
	}

	line.WriteString(strings.Repeat(" ", prefix))

	if option.ShortName != 0 {
		line.WriteRune(defaultShortOptDelimiter)
		line.WriteRune(option.ShortName)
	} else if info.hasShort {
		line.WriteString("  ")
	}

	descstart := info.descriptionStart() + paddingBeforeOption

	if len(option.LongName) > 0 {
		if option.ShortName != 0 {
			line.WriteString(", ")
		} else if info.hasShort {
			line.WriteString("  ")
		}

		line.WriteString(defaultLongOptDelimiter)
		line.WriteString(option.LongNameWithNamespace())
	}

	if option.canArgument() {
		line.WriteRune(defaultNameArgDelimiter)

		if len(option.ValueName) > 0 {
			line.WriteString(option.ValueName)
		}
	}

	written := line.Len()
	line.WriteTo(writer)

	if option.Description != "" {
		dw := descstart - written
		writer.WriteString(strings.Repeat(" ", dw))

		def := ""
		defs := option.Default

		if len(option.DefaultMask) != 0 {
			if option.DefaultMask != "-" {
				def = option.DefaultMask
			}
		} else if len(defs) == 0 && option.canArgument() {
			var showdef bool

			switch option.field.Type.Kind() {
			case reflect.Func, reflect.Ptr:
				showdef = !option.value.IsNil()
			case reflect.Slice, reflect.String, reflect.Array:
				showdef = option.value.Len() > 0
			case reflect.Map:
				showdef = !option.value.IsNil() && option.value.Len() > 0
			default:
				zeroval := reflect.Zero(option.field.Type)
				showdef = !reflect.DeepEqual(zeroval.Interface(), option.value.Interface())
			}

			if showdef {
				def, _ = convertToString(option.value, option.tag)
			}
		} else if len(defs) != 0 {
			l := len(defs) - 1

			for i := 0; i < l; i++ {
				def += quoteIfNeeded(defs[i]) + ", "
			}

			def += quoteIfNeeded(defs[l])
		}

		var envDef string
		if option.EnvDefaultKey != "" {
			var envPrintable string
			if runtime.GOOS == "windows" {
				envPrintable = "%" + option.EnvDefaultKey + "%"
			} else {
				envPrintable = "$" + option.EnvDefaultKey
			}
			envDef = fmt.Sprintf(" [%s]", envPrintable)
		}

		var desc string

		if def != "" {
			desc = fmt.Sprintf("%s (%v)%s", option.Description, def, envDef)
		} else {
			desc = option.Description + envDef
		}

		writer.WriteString(wrapText(desc,
			info.terminalColumns-descstart,
			strings.Repeat(" ", descstart)))
	}

	writer.WriteString("\n")
}

func maxCommandLength(s []*Command) int {
	if len(s) == 0 {
		return 0
	}

	ret := len(s[0].Name)

	for _, v := range s[1:] {
		l := len(v.Name)

		if l > ret {
			ret = l
		}
	}

	return ret
}

// WriteHelp writes a help message containing all the possible options and
// their descriptions to the provided writer. Note that the HelpFlag parser
// option provides a convenient way to add a -h/--help option group to the
// command line parser which will automatically show the help messages using
// this method.
func (p *Parser) WriteHelp(writer io.Writer) {
	if writer == nil {
		return
	}

	wr := bufio.NewWriter(writer)
	aligninfo := p.getAlignmentInfo()

	cmd := p.Command

	for cmd.Active != nil {
		cmd = cmd.Active
	}

	if p.Name != "" {
		wr.WriteString("Usage:\n")
		wr.WriteString(" ")

		allcmd := p.Command

		for allcmd != nil {
			var usage string

			if allcmd == p.Command {
				if len(p.Usage) != 0 {
					usage = p.Usage
				} else if p.Options&HelpFlag != 0 {
					usage = "[OPTIONS]"
				}
			} else if us, ok := allcmd.data.(Usage); ok {
				usage = us.Usage()
			} else if allcmd.hasCliOptions() {
				usage = fmt.Sprintf("[%s-OPTIONS]", allcmd.Name)
			}

			if len(usage) != 0 {
				fmt.Fprintf(wr, " %s %s", allcmd.Name, usage)
			} else {
				fmt.Fprintf(wr, " %s", allcmd.Name)
			}

			if len(allcmd.args) > 0 {
				fmt.Fprintf(wr, " ")
			}

			for i, arg := range allcmd.args {
				if i != 0 {
					fmt.Fprintf(wr, " ")
				}

				name := arg.Name

				if arg.isRemaining() {
					name = name + "..."
				}

				if !allcmd.ArgsRequired {
					fmt.Fprintf(wr, "[%s]", name)
				} else {
					fmt.Fprintf(wr, "%s", name)
				}
			}

			if allcmd.Active == nil && len(allcmd.commands) > 0 {
				var co, cc string

				if allcmd.SubcommandsOptional {
					co, cc = "[", "]"
				} else {
					co, cc = "<", ">"
				}

				if len(allcmd.commands) > 3 {
					fmt.Fprintf(wr, " %scommand%s", co, cc)
				} else {
					subcommands := allcmd.sortedCommands()
					names := make([]string, len(subcommands))

					for i, subc := range subcommands {
						names[i] = subc.Name
					}

					fmt.Fprintf(wr, " %s%s%s", co, strings.Join(names, " | "), cc)
				}
			}

			allcmd = allcmd.Active
		}

		fmt.Fprintln(wr)

		if len(cmd.LongDescription) != 0 {
			fmt.Fprintln(wr)

			t := wrapText(cmd.LongDescription,
				aligninfo.terminalColumns,
				"")

			fmt.Fprintln(wr, t)
		}
	}

	c := p.Command

	for c != nil {
		printcmd := c != p.Command

		c.eachGroup(func(grp *Group) {
			first := true

			// Skip built-in help group for all commands except the top-level
			// parser
			if grp.isBuiltinHelp && c != p.Command {
				return
			}

			for _, info := range grp.options {
				if !info.canCli() {
					continue
				}

				if printcmd {
					fmt.Fprintf(wr, "\n[%s command options]\n", c.Name)
					aligninfo.indent = true
					printcmd = false
				}

				if first && cmd.Group != grp {
					fmt.Fprintln(wr)

					if aligninfo.indent {
						wr.WriteString("    ")
					}

					fmt.Fprintf(wr, "%s:\n", grp.ShortDescription)
					first = false
				}

				p.writeHelpOption(wr, info, aligninfo)
			}
		})

		if len(c.args) > 0 {
			if c == p.Command {
				fmt.Fprintf(wr, "\nArguments:\n")
			} else {
				fmt.Fprintf(wr, "\n[%s command arguments]\n", c.Name)
			}

			maxlen := aligninfo.descriptionStart()

			for _, arg := range c.args {
				prefix := strings.Repeat(" ", paddingBeforeOption)
				fmt.Fprintf(wr, "%s%s", prefix, arg.Name)

				if len(arg.Description) > 0 {
					align := strings.Repeat(" ", maxlen-len(arg.Name)-1)
					fmt.Fprintf(wr, ":%s%s", align, arg.Description)
				}

				fmt.Fprintln(wr)
			}
		}

		c = c.Active
	}

	scommands := cmd.sortedCommands()

	if len(scommands) > 0 {
		maxnamelen := maxCommandLength(scommands)

		fmt.Fprintln(wr)
		fmt.Fprintln(wr, "Available commands:")

		for _, c := range scommands {
			fmt.Fprintf(wr, "  %s", c.Name)

			if len(c.ShortDescription) > 0 {
				pad := strings.Repeat(" ", maxnamelen-len(c.Name))
				fmt.Fprintf(wr, "%s  %s", pad, c.ShortDescription)

				if len(c.Aliases) > 0 {
					fmt.Fprintf(wr, " (aliases: %s)", strings.Join(c.Aliases, ", "))
				}

			}

			fmt.Fprintln(wr)
		}
	}

	wr.Flush()
}
<|endoftext|>


<commit_before>package bookkeeping

import (
	"fmt"
	"net/http"
	"net/http/httptest"
	"reflect"
	"strconv"
	"strings"
	"testing"

	"github.com/davecgh/go-spew/spew"
	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"
)

func testHeaders(t *testing.T, originalHeader http.Header, headersToCopy []string, expectedKeyValues []interface{}) {
	var (
		assert  = assert.New(t)
		require = require.New(t)

		request = &http.Request{
			Header: originalHeader,
		}

		rf = RequestHeaders(headersToCopy...)
	)

	require.NotNil(rf)
	returnedKeyValuePair := rf(request)
	assert.Equal(expectedKeyValues, returnedKeyValuePair)
}

func TestBookkeepingHeaders(t *testing.T) {
	testData := []struct {
		originalHeader   http.Header
		headersToCopy    []string
		expectedResponse []interface{}
	}{
		{
			http.Header{"X-Test-1": []string{"foo"}, "X-Test-2": []string{"foo", "bar"}, "X-Test-3": []string{}},
			nil,
			[]interface{}{},
		},
		{
			http.Header{"X-Test-1": []string{"foo"}, "X-Test-2": []string{"foo", "bar"}, "X-Test-3": []string{}},
			[]string{"X-Does-Not-Exist"},
			[]interface{}{},
		},
		{
			http.Header{"X-Test-1": []string{"foo"}, "X-Test-2": []string{"foo", "bar"}, "X-Test-3": []string{}},
			[]string{"X-Does-Not-Exist", "X-Test-1"},
			[]interface{}{"X-Test-1", []string{"foo"}},
		},
		{
			http.Header{"X-Test-1": []string{"foo"}, "X-Test-2": []string{"foo", "bar"}, "X-Test-3": []string{}},
			[]string{"X-Does-Not-Exist", "x-test-1"},
			[]interface{}{"X-Test-1", []string{"foo"}},
		},
		{
			http.Header{"X-Test-1": []string{"foo"}, "X-Test-2": []string{"foo", "bar"}, "X-Test-3": []string{}},
			[]string{"X-Test-1"},
			[]interface{}{"X-Test-1", []string{"foo"}},
		},
		{
			http.Header{"X-Test-1": []string{"foo"}, "X-Test-2": []string{"foo", "bar"}, "X-Test-3": []string{}},
			[]string{"X-Test-3", "X-Test-1"},
			[]interface{}{"X-Test-1", []string{"foo"}},
		},
		{
			http.Header{"X-Test-1": []string{"foo"}, "X-Test-2": []string{"foo", "bar"}, "X-Test-3": []string{}},
			[]string{"x-TeST-3", "X-tESt-1"},
			[]interface{}{"X-Test-1", []string{"foo"}},
		},
		{
			http.Header{"X-Test-1": []string{"foo"}, "X-Test-2": []string{"foo", "bar"}, "X-Test-3": []string{}},
			[]string{"X-Test-3", "X-Test-1", "X-Test-2"},
			[]interface{}{"X-Test-1", []string{"foo"}, "X-Test-2", []string{"foo", "bar"}},
		},
		{
			http.Header{"X-Test-1": []string{"foo"}, "X-Test-2": []string{"foo", "bar"}, "X-Test-3": []string{}},
			[]string{"X-TEST-3", "x-TEsT-1", "x-TesT-2"},
			[]interface{}{"X-Test-1", []string{"foo"}, "X-Test-2", []string{"foo", "bar"}},
		},
	}

	for i, record := range testData {
		t.Run(fmt.Sprintf("%d", i), func(t *testing.T) {
			t.Logf("%#v", record)
			testHeaders(t, record.originalHeader, record.headersToCopy, record.expectedResponse)
		})
	}
}

func testReturnHeadersWithPrefix(t *testing.T, request *http.Request, headerPrefixToCopy []string, expectedKV []interface{}) {
	var (
		require = require.New(t)
		rf      = RequestHeadersWithPrefix(headerPrefixToCopy...)
	)

	require.NotNil(rf)
	kv := rf(request)

	expectedkvMap := make(map[int]interface{})
	for i, v := range expectedKV {
		expectedkvMap[i] = v
	}

	kvMap := make(map[int]interface{})
	for i, v := range kv {
		kvMap[i] = v
	}

	// for i, v := range expectedKV {
	if ok := reflect.DeepEqual(expectedKV, kv); !ok {
		t.Errorf("Expecting: %v\n but got: %v\n", spew.Sdump(expectedkvMap), spew.Sdump(kvMap))
	}
}

func TestReturnHeadersWithPrefix(t *testing.T) {
	testData := []struct {
		request    *http.Request
		prefixs    []string
		expectedKV []interface{}
	}{
		{
			nil,
			nil,
			[]interface{}{},
		},
		{
			&http.Request{},
			nil,
			[]interface{}{},
		},
		{
			&http.Request{Header: http.Header{"X-Test-1": []string{"foo"}}},
			nil,
			[]interface{}{},
		},
		{
			&http.Request{Header: http.Header{"X-Test-1": []string{"foo"}, "X-Test-2": []string{"foo", "bar"}, "X-Test-3": []string{}}},
			[]string{"X-Does-Not-Exist"},
			[]interface{}{},
		},
		{
			&http.Request{Header: http.Header{"X-Test-1": []string{"foo"}, "X-Test-2": []string{"foo", "bar"}, "X-Test-3": []string{}}},
			[]string{"X-Does-Not-Exist", "X-Test-1"},
			[]interface{}{"X-Test-1", []string{"foo"}},
		},
		{
			&http.Request{Header: http.Header{"X-Test-1": []string{"foo"}, "X-Test-2": []string{"foo", "bar"}, "X-Test-3": []string{}}},
			[]string{"X-Does-Not-Exist", "x-TeSt-1"},
			[]interface{}{"X-Test-1", []string{"foo"}},
		},
		{
			&http.Request{Header: http.Header{"X-Test-1": []string{"foo"}, "X-Test-2": []string{"foo", "bar"}, "X-Test-3": []string{}}},
			[]string{"X-Test-3", "X-Test-1"},
			[]interface{}{"X-Test-1", []string{"foo"}},
		},
		{
			&http.Request{Header: http.Header{"X-Test-1": []string{"foo"}, "X-Test-2": []string{"foo", "bar"}, "X-Test-3": []string{}}},
			[]string{"x-TeST-3", "X-tESt-1"},
			[]interface{}{"X-Test-1", []string{"foo"}},
		},
		{
			&http.Request{Header: http.Header{"X-Test-1": []string{"foo"}, "X-Test-2": []string{"foo", "bar"}, "X-Test-3": []string{}}},
			[]string{"X-Test-3", "X-Test-1", "X-Test-2"},
			[]interface{}{"X-Test-1", []string{"foo"}, "X-Test-2", []string{"foo", "bar"}},
		},
		{
			&http.Request{Header: http.Header{"X-Test-1": []string{"foo"}, "X-Test-2": []string{"foo", "bar"}, "X-Test-3": []string{}}},
			[]string{"X-TEST-3", "x-TEsT-1", "x-TesT-2"},
			[]interface{}{"X-Test-1", []string{"foo"}, "X-Test-2", []string{"foo", "bar"}},
		},
		{
			&http.Request{Header: http.Header{"X-Test-1": []string{"foo"}, "X-Test-2": []string{"foo", "bar"}, "X-Test-3": []string{}}},
			[]string{"X-TEST"},
			[]interface{}{"X-Test-1", []string{"foo"}, "X-Test-2", []string{"foo", "bar"}},
		},
	}

	for i, record := range testData {
		t.Run(fmt.Sprintf("%d", i), func(t *testing.T) {
			t.Logf("%#v", record)
			testReturnHeadersWithPrefix(t, record.request, record.prefixs, record.expectedKV)
		})
	}
}

func testRequestBody(t *testing.T, request *http.Request, expectedKV []interface{}) {
	assert := assert.New(t)

	var kv []interface{}
	assert.NotPanics(func() {
		kv = RequestBody(request)
	})
	assert.Equal(expectedKV, kv)
}

func TestRequestBody(t *testing.T) {
	testData := []struct {
		request  *http.Request
		expected []interface{}
	}{
		{httptest.NewRequest("POST", "http://foobar.com:8080", nil), []interface{}{"req-body", "empty body"}},
		{httptest.NewRequest("POST", "http://foobar.com:8080", strings.NewReader("payload")), []interface{}{"req-body", "payload"}},
	}
	for i, record := range testData {
		t.Run(strconv.Itoa(i), func(t *testing.T) {
			t.Logf("%#v", record)
			testRequestBody(t, record.request, record.expected)
		})
	}
}

func testResponseBody(t *testing.T, response CapturedResponse, expectedKV []interface{}) {
	assert := assert.New(t)

	var kv []interface{}
	assert.NotPanics(func() {
		kv = ResponseBody(response)
	})
	assert.Equal(expectedKV, kv)
}

func TestResponseBody(t *testing.T) {
	testData := []struct {
		response CapturedResponse
		expected []interface{}
	}{
		{CapturedResponse{}, []interface{}{"res-body", "empty body"}},
		{CapturedResponse{Payload: []byte("payload")}, []interface{}{"res-body", "payload"}},
	}
	for i, record := range testData {
		t.Run(strconv.Itoa(i), func(t *testing.T) {
			t.Logf("%#v", record)
			testResponseBody(t, record.response, record.expected)
		})
	}
}
<commit_msg>bookkeeping: request response bug<commit_after>package bookkeeping

import (
	"fmt"
	"net/http"
	"net/http/httptest"
	"reflect"
	"strconv"
	"strings"
	"testing"

	"github.com/davecgh/go-spew/spew"
	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"
)

func testHeaders(t *testing.T, originalHeader http.Header, headersToCopy []string, expectedKeyValues []interface{}) {
	var (
		assert  = assert.New(t)
		require = require.New(t)

		request = &http.Request{
			Header: originalHeader,
		}

		rf = RequestHeaders(headersToCopy...)
	)

	require.NotNil(rf)
	returnedKeyValuePair := rf(request)
	assert.Equal(expectedKeyValues, returnedKeyValuePair)
}

func TestBookkeepingHeaders(t *testing.T) {
	testData := []struct {
		originalHeader   http.Header
		headersToCopy    []string
		expectedResponse []interface{}
	}{
		{
			http.Header{"X-Test-1": []string{"foo"}, "X-Test-2": []string{"foo", "bar"}, "X-Test-3": []string{}},
			nil,
			[]interface{}{},
		},
		{
			http.Header{"X-Test-1": []string{"foo"}, "X-Test-2": []string{"foo", "bar"}, "X-Test-3": []string{}},
			[]string{"X-Does-Not-Exist"},
			[]interface{}{},
		},
		{
			http.Header{"X-Test-1": []string{"foo"}, "X-Test-2": []string{"foo", "bar"}, "X-Test-3": []string{}},
			[]string{"X-Does-Not-Exist", "X-Test-1"},
			[]interface{}{"X-Test-1", []string{"foo"}},
		},
		{
			http.Header{"X-Test-1": []string{"foo"}, "X-Test-2": []string{"foo", "bar"}, "X-Test-3": []string{}},
			[]string{"X-Does-Not-Exist", "x-test-1"},
			[]interface{}{"X-Test-1", []string{"foo"}},
		},
		{
			http.Header{"X-Test-1": []string{"foo"}, "X-Test-2": []string{"foo", "bar"}, "X-Test-3": []string{}},
			[]string{"X-Test-1"},
			[]interface{}{"X-Test-1", []string{"foo"}},
		},
		{
			http.Header{"X-Test-1": []string{"foo"}, "X-Test-2": []string{"foo", "bar"}, "X-Test-3": []string{}},
			[]string{"X-Test-3", "X-Test-1"},
			[]interface{}{"X-Test-1", []string{"foo"}},
		},
		{
			http.Header{"X-Test-1": []string{"foo"}, "X-Test-2": []string{"foo", "bar"}, "X-Test-3": []string{}},
			[]string{"x-TeST-3", "X-tESt-1"},
			[]interface{}{"X-Test-1", []string{"foo"}},
		},
		{
			http.Header{"X-Test-1": []string{"foo"}, "X-Test-2": []string{"foo", "bar"}, "X-Test-3": []string{}},
			[]string{"X-Test-3", "X-Test-1", "X-Test-2"},
			[]interface{}{"X-Test-1", []string{"foo"}, "X-Test-2", []string{"foo", "bar"}},
		},
		{
			http.Header{"X-Test-1": []string{"foo"}, "X-Test-2": []string{"foo", "bar"}, "X-Test-3": []string{}},
			[]string{"X-TEST-3", "x-TEsT-1", "x-TesT-2"},
			[]interface{}{"X-Test-1", []string{"foo"}, "X-Test-2", []string{"foo", "bar"}},
		},
	}

	for i, record := range testData {
		t.Run(fmt.Sprintf("%d", i), func(t *testing.T) {
			t.Logf("%#v", record)
			testHeaders(t, record.originalHeader, record.headersToCopy, record.expectedResponse)
		})
	}
}

func testReturnHeadersWithPrefix(t *testing.T, request *http.Request, headerPrefixToCopy []string, expectedKV []interface{}) {
	var (
		require = require.New(t)
		rf      = RequestHeadersWithPrefix(headerPrefixToCopy...)
	)

	require.NotNil(rf)
	kv := rf(request)

	f := func(i []interface{}, c chan<- map[string]interface{}) {
		m := make(map[string]interface{})
		for _, v := range i {
			m["test"] = v
		}

		c <- m
	}

	c1, c2 := make(chan map[string]interface{}), make(chan map[string]interface{})
	go f(kv, c1)
	go f(expectedKV, c2)

	kvMap, expectedkvMap := <-c1, <-c2

	if ok := reflect.DeepEqual(expectedKV, kv); !ok {
		t.Errorf("\nExpecting: %v\n but got: %v\n", spew.Sdump(expectedkvMap), spew.Sdump(kvMap))
	}
}

func TestReturnHeadersWithPrefix(t *testing.T) {
	testData := []struct {
		request    *http.Request
		prefixs    []string
		expectedKV []interface{}
	}{
		{
			nil,
			nil,
			[]interface{}{},
		},
		{
			&http.Request{},
			nil,
			[]interface{}{},
		},
		{
			&http.Request{Header: http.Header{"X-Test-1": []string{"foo"}}},
			nil,
			[]interface{}{},
		},
		{
			&http.Request{Header: http.Header{"X-Test-1": []string{"foo"}, "X-Test-2": []string{"foo", "bar"}, "X-Test-3": []string{}}},
			[]string{"X-Does-Not-Exist"},
			[]interface{}{},
		},
		{
			&http.Request{Header: http.Header{"X-Test-1": []string{"foo"}, "X-Test-2": []string{"foo", "bar"}, "X-Test-3": []string{}}},
			[]string{"X-Does-Not-Exist", "X-Test-1"},
			[]interface{}{"X-Test-1", []string{"foo"}},
		},
		{
			&http.Request{Header: http.Header{"X-Test-1": []string{"foo"}, "X-Test-2": []string{"foo", "bar"}, "X-Test-3": []string{}}},
			[]string{"X-Does-Not-Exist", "x-TeSt-1"},
			[]interface{}{"X-Test-1", []string{"foo"}},
		},
		{
			&http.Request{Header: http.Header{"X-Test-1": []string{"foo"}, "X-Test-2": []string{"foo", "bar"}, "X-Test-3": []string{}}},
			[]string{"X-Test-3", "X-Test-1"},
			[]interface{}{"X-Test-1", []string{"foo"}},
		},
		{
			&http.Request{Header: http.Header{"X-Test-1": []string{"foo"}, "X-Test-2": []string{"foo", "bar"}, "X-Test-3": []string{}}},
			[]string{"x-TeST-3", "X-tESt-1"},
			[]interface{}{"X-Test-1", []string{"foo"}},
		},
		{
			&http.Request{Header: http.Header{"X-Test-1": []string{"foo"}, "X-Test-2": []string{"foo", "bar"}, "X-Test-3": []string{}}},
			[]string{"X-Test-3", "X-Test-1", "X-Test-2"},
			[]interface{}{"X-Test-1", []string{"foo"}, "X-Test-2", []string{"foo", "bar"}},
		},
		{
			&http.Request{Header: http.Header{"X-Test-1": []string{"foo"}, "X-Test-2": []string{"foo", "bar"}, "X-Test-3": []string{}}},
			[]string{"X-TEST-3", "x-TEsT-1", "x-TesT-2"},
			[]interface{}{"X-Test-1", []string{"foo"}, "X-Test-2", []string{"foo", "bar"}},
		},
		{
			&http.Request{Header: http.Header{"X-Test-1": []string{"foo"}, "X-Test-2": []string{"foo", "bar"}, "X-Test-3": []string{}}},
			[]string{"X-TEST"},
			[]interface{}{"X-Test-1", []string{"foo"}, "X-Test-2", []string{"foo", "bar"}},
		},
	}

	for i, record := range testData {
		t.Run(fmt.Sprintf("%d", i), func(t *testing.T) {
			t.Logf("%#v", record)
			testReturnHeadersWithPrefix(t, record.request, record.prefixs, record.expectedKV)
		})
	}
}

func testRequestBody(t *testing.T, request *http.Request, expectedKV []interface{}) {
	assert := assert.New(t)

	var kv []interface{}
	assert.NotPanics(func() {
		kv = RequestBody(request)
	})
	assert.Equal(expectedKV, kv)
}

func TestRequestBody(t *testing.T) {
	testData := []struct {
		request  *http.Request
		expected []interface{}
	}{
		{httptest.NewRequest("POST", "http://foobar.com:8080", nil), []interface{}{"req-body", "empty body"}},
		{httptest.NewRequest("POST", "http://foobar.com:8080", strings.NewReader("payload")), []interface{}{"req-body", "payload"}},
	}
	for i, record := range testData {
		t.Run(strconv.Itoa(i), func(t *testing.T) {
			t.Logf("%#v", record)
			testRequestBody(t, record.request, record.expected)
		})
	}
}

func testResponseBody(t *testing.T, response CapturedResponse, expectedKV []interface{}) {
	assert := assert.New(t)

	var kv []interface{}
	assert.NotPanics(func() {
		kv = ResponseBody(response)
	})
	assert.Equal(expectedKV, kv)
}

func TestResponseBody(t *testing.T) {
	testData := []struct {
		response CapturedResponse
		expected []interface{}
	}{
		{CapturedResponse{}, []interface{}{"res-body", "empty body"}},
		{CapturedResponse{Payload: []byte("payload")}, []interface{}{"res-body", "payload"}},
	}
	for i, record := range testData {
		t.Run(strconv.Itoa(i), func(t *testing.T) {
			t.Logf("%#v", record)
			testResponseBody(t, record.response, record.expected)
		})
	}
}
<|endoftext|>


<commit_before>// Copyright 2014 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package commands defines and manages the basic pprof commands
package commands

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

	"cmd/pprof/internal/plugin"
	"cmd/pprof/internal/report"
	"cmd/pprof/internal/svg"
	"cmd/pprof/internal/tempfile"
)

// Commands describes the commands accepted by pprof.
type Commands map[string]*Command

// Command describes the actions for a pprof command. Includes a
// function for command-line completion, the report format to use
// during report generation, any postprocessing functions, and whether
// the command expects a regexp parameter (typically a function name).
type Command struct {
	Complete    Completer     // autocomplete for interactive mode
	Format      int           // report format to generate
	PostProcess PostProcessor // postprocessing to run on report
	HasParam    bool          // Collect a parameter from the CLI
	Usage       string        // Help text
}

// Completer is a function for command-line autocompletion
type Completer func(prefix string) string

// PostProcessor is a function that applies post-processing to the report output
type PostProcessor func(input *bytes.Buffer, output io.Writer, ui plugin.UI) error

// PProf returns the basic pprof report-generation commands
func PProf(c Completer, interactive **bool, svgpan **string) Commands {
	return Commands{
		// Commands that require no post-processing.
		"tags":   {nil, report.Tags, nil, false, "Outputs all tags in the profile"},
		"raw":    {c, report.Raw, nil, false, "Outputs a text representation of the raw profile"},
		"dot":    {c, report.Dot, nil, false, "Outputs a graph in DOT format"},
		"top":    {c, report.Text, nil, false, "Outputs top entries in text form"},
		"tree":   {c, report.Tree, nil, false, "Outputs a text rendering of call graph"},
		"text":   {c, report.Text, nil, false, "Outputs top entries in text form"},
		"disasm": {c, report.Dis, nil, true, "Output annotated assembly for functions matching regexp or address"},
		"list":   {c, report.List, nil, true, "Output annotated source for functions matching regexp"},
		"peek":   {c, report.Tree, nil, true, "Output callers/callees of functions matching regexp"},

		// Save binary formats to a file
		"callgrind": {c, report.Callgrind, awayFromTTY("callgraph.out"), false, "Outputs a graph in callgrind format"},
		"proto":     {c, report.Proto, awayFromTTY("pb.gz"), false, "Outputs the profile in compressed protobuf format"},

		// Generate report in DOT format and postprocess with dot
		"gif": {c, report.Dot, invokeDot("gif"), false, "Outputs a graph image in GIF format"},
		"pdf": {c, report.Dot, invokeDot("pdf"), false, "Outputs a graph in PDF format"},
		"png": {c, report.Dot, invokeDot("png"), false, "Outputs a graph image in PNG format"},
		"ps":  {c, report.Dot, invokeDot("ps"), false, "Outputs a graph in PS format"},

		// Save SVG output into a file after including svgpan library
		"svg": {c, report.Dot, saveSVGToFile(svgpan), false, "Outputs a graph in SVG format"},

		// Visualize postprocessed dot output
		"eog":    {c, report.Dot, invokeVisualizer(interactive, invokeDot("svg"), "svg", []string{"eog"}), false, "Visualize graph through eog"},
		"evince": {c, report.Dot, invokeVisualizer(interactive, invokeDot("pdf"), "pdf", []string{"evince"}), false, "Visualize graph through evince"},
		"gv":     {c, report.Dot, invokeVisualizer(interactive, invokeDot("ps"), "ps", []string{"gv --noantialias"}), false, "Visualize graph through gv"},
		"web":    {c, report.Dot, invokeVisualizer(interactive, saveSVGToFile(svgpan), "svg", browsers), false, "Visualize graph through web browser"},

		// Visualize HTML directly generated by report.
		"weblist": {c, report.WebList, invokeVisualizer(interactive, awayFromTTY("html"), "html", browsers), true, "Output annotated source in HTML for functions matching regexp or address"},
	}
}

// List of web browsers to attempt for web visualization
var browsers = []string{"chrome", "google-chrome", "firefox", "/usr/bin/open"}

// NewCompleter creates an autocompletion function for a set of commands.
func NewCompleter(cs Commands) Completer {
	return func(line string) string {
		switch tokens := strings.Fields(line); len(tokens) {
		case 0:
			// Nothing to complete
		case 1:
			// Single token -- complete command name
			found := ""
			for c := range cs {
				if strings.HasPrefix(c, tokens[0]) {
					if found != "" {
						return line
					}
					found = c
				}
			}
			if found != "" {
				return found
			}
		default:
			// Multiple tokens -- complete using command completer
			if c, ok := cs[tokens[0]]; ok {
				if c.Complete != nil {
					lastTokenIdx := len(tokens) - 1
					lastToken := tokens[lastTokenIdx]
					if strings.HasPrefix(lastToken, "-") {
						lastToken = "-" + c.Complete(lastToken[1:])
					} else {
						lastToken = c.Complete(lastToken)
					}
					return strings.Join(append(tokens[:lastTokenIdx], lastToken), " ")
				}
			}
		}
		return line
	}
}

// awayFromTTY saves the output in a file if it would otherwise go to
// the terminal screen. This is used to avoid dumping binary data on
// the screen.
func awayFromTTY(format string) PostProcessor {
	return func(input *bytes.Buffer, output io.Writer, ui plugin.UI) error {
		if output == os.Stdout && ui.IsTerminal() {
			tempFile, err := tempfile.New("", "profile", "."+format)
			if err != nil {
				return err
			}
			ui.PrintErr("Generating report in ", tempFile.Name())
			_, err = fmt.Fprint(tempFile, input)
			return err
		}
		_, err := fmt.Fprint(output, input)
		return err
	}
}

func invokeDot(format string) PostProcessor {
	divert := awayFromTTY(format)
	return func(input *bytes.Buffer, output io.Writer, ui plugin.UI) error {
		cmd := exec.Command("dot", "-T"+format)
		var buf bytes.Buffer
		cmd.Stdin, cmd.Stdout, cmd.Stderr = input, &buf, os.Stderr
		if err := cmd.Run(); err != nil {
			return err
		}
		return divert(&buf, output, ui)
	}
}

func saveSVGToFile(svgpan **string) PostProcessor {
	generateSVG := invokeDot("svg")
	divert := awayFromTTY("svg")
	return func(input *bytes.Buffer, output io.Writer, ui plugin.UI) error {
		baseSVG := &bytes.Buffer{}
		generateSVG(input, baseSVG, ui)
		massaged := &bytes.Buffer{}
		fmt.Fprint(massaged, svg.Massage(*baseSVG, **svgpan))
		return divert(massaged, output, ui)
	}
}

func invokeVisualizer(interactive **bool, format PostProcessor, suffix string, visualizers []string) PostProcessor {
	return func(input *bytes.Buffer, output io.Writer, ui plugin.UI) error {
		tempFile, err := tempfile.New(os.Getenv("PPROF_TMPDIR"), "pprof", "."+suffix)
		if err != nil {
			return err
		}
		tempfile.DeferDelete(tempFile.Name())
		if err = format(input, tempFile, ui); err != nil {
			return err
		}
		// Try visualizers until one is successful
		for _, v := range visualizers {
			// Separate command and arguments for exec.Command.
			args := strings.Split(v, " ")
			if len(args) == 0 {
				continue
			}
			viewer := exec.Command(args[0], append(args[1:], tempFile.Name())...)
			viewer.Stderr = os.Stderr
			if err = viewer.Start(); err == nil {
				if !**interactive {
					// In command-line mode, wait for the viewer to be closed
					// before proceeding
					return viewer.Wait()
				}
				return nil
			}
		}
		return err
	}
}
<commit_msg>[release-branch.go1.4] cmd/pprof/internal/commands: add command to open browser on windows<commit_after>// Copyright 2014 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package commands defines and manages the basic pprof commands
package commands

import (
	"bytes"
	"fmt"
	"io"
	"os"
	"os/exec"
	"runtime"
	"strings"

	"cmd/pprof/internal/plugin"
	"cmd/pprof/internal/report"
	"cmd/pprof/internal/svg"
	"cmd/pprof/internal/tempfile"
)

// Commands describes the commands accepted by pprof.
type Commands map[string]*Command

// Command describes the actions for a pprof command. Includes a
// function for command-line completion, the report format to use
// during report generation, any postprocessing functions, and whether
// the command expects a regexp parameter (typically a function name).
type Command struct {
	Complete    Completer     // autocomplete for interactive mode
	Format      int           // report format to generate
	PostProcess PostProcessor // postprocessing to run on report
	HasParam    bool          // Collect a parameter from the CLI
	Usage       string        // Help text
}

// Completer is a function for command-line autocompletion
type Completer func(prefix string) string

// PostProcessor is a function that applies post-processing to the report output
type PostProcessor func(input *bytes.Buffer, output io.Writer, ui plugin.UI) error

// PProf returns the basic pprof report-generation commands
func PProf(c Completer, interactive **bool, svgpan **string) Commands {
	return Commands{
		// Commands that require no post-processing.
		"tags":   {nil, report.Tags, nil, false, "Outputs all tags in the profile"},
		"raw":    {c, report.Raw, nil, false, "Outputs a text representation of the raw profile"},
		"dot":    {c, report.Dot, nil, false, "Outputs a graph in DOT format"},
		"top":    {c, report.Text, nil, false, "Outputs top entries in text form"},
		"tree":   {c, report.Tree, nil, false, "Outputs a text rendering of call graph"},
		"text":   {c, report.Text, nil, false, "Outputs top entries in text form"},
		"disasm": {c, report.Dis, nil, true, "Output annotated assembly for functions matching regexp or address"},
		"list":   {c, report.List, nil, true, "Output annotated source for functions matching regexp"},
		"peek":   {c, report.Tree, nil, true, "Output callers/callees of functions matching regexp"},

		// Save binary formats to a file
		"callgrind": {c, report.Callgrind, awayFromTTY("callgraph.out"), false, "Outputs a graph in callgrind format"},
		"proto":     {c, report.Proto, awayFromTTY("pb.gz"), false, "Outputs the profile in compressed protobuf format"},

		// Generate report in DOT format and postprocess with dot
		"gif": {c, report.Dot, invokeDot("gif"), false, "Outputs a graph image in GIF format"},
		"pdf": {c, report.Dot, invokeDot("pdf"), false, "Outputs a graph in PDF format"},
		"png": {c, report.Dot, invokeDot("png"), false, "Outputs a graph image in PNG format"},
		"ps":  {c, report.Dot, invokeDot("ps"), false, "Outputs a graph in PS format"},

		// Save SVG output into a file after including svgpan library
		"svg": {c, report.Dot, saveSVGToFile(svgpan), false, "Outputs a graph in SVG format"},

		// Visualize postprocessed dot output
		"eog":    {c, report.Dot, invokeVisualizer(interactive, invokeDot("svg"), "svg", []string{"eog"}), false, "Visualize graph through eog"},
		"evince": {c, report.Dot, invokeVisualizer(interactive, invokeDot("pdf"), "pdf", []string{"evince"}), false, "Visualize graph through evince"},
		"gv":     {c, report.Dot, invokeVisualizer(interactive, invokeDot("ps"), "ps", []string{"gv --noantialias"}), false, "Visualize graph through gv"},
		"web":    {c, report.Dot, invokeVisualizer(interactive, saveSVGToFile(svgpan), "svg", browsers()), false, "Visualize graph through web browser"},

		// Visualize HTML directly generated by report.
		"weblist": {c, report.WebList, invokeVisualizer(interactive, awayFromTTY("html"), "html", browsers()), true, "Output annotated source in HTML for functions matching regexp or address"},
	}
}

// browsers returns a list of commands to attempt for web visualization
// on the current platform
func browsers() []string {
	cmds := []string{"chrome", "google-chrome", "firefox"}
	switch runtime.GOOS {
	case "darwin":
		cmds = append(cmds, "/usr/bin/open")
	case "windows":
		cmds = append(cmds, "cmd /c start")
	default:
		cmds = append(cmds, "xdg-open")
	}
	return cmds
}

// NewCompleter creates an autocompletion function for a set of commands.
func NewCompleter(cs Commands) Completer {
	return func(line string) string {
		switch tokens := strings.Fields(line); len(tokens) {
		case 0:
			// Nothing to complete
		case 1:
			// Single token -- complete command name
			found := ""
			for c := range cs {
				if strings.HasPrefix(c, tokens[0]) {
					if found != "" {
						return line
					}
					found = c
				}
			}
			if found != "" {
				return found
			}
		default:
			// Multiple tokens -- complete using command completer
			if c, ok := cs[tokens[0]]; ok {
				if c.Complete != nil {
					lastTokenIdx := len(tokens) - 1
					lastToken := tokens[lastTokenIdx]
					if strings.HasPrefix(lastToken, "-") {
						lastToken = "-" + c.Complete(lastToken[1:])
					} else {
						lastToken = c.Complete(lastToken)
					}
					return strings.Join(append(tokens[:lastTokenIdx], lastToken), " ")
				}
			}
		}
		return line
	}
}

// awayFromTTY saves the output in a file if it would otherwise go to
// the terminal screen. This is used to avoid dumping binary data on
// the screen.
func awayFromTTY(format string) PostProcessor {
	return func(input *bytes.Buffer, output io.Writer, ui plugin.UI) error {
		if output == os.Stdout && ui.IsTerminal() {
			tempFile, err := tempfile.New("", "profile", "."+format)
			if err != nil {
				return err
			}
			ui.PrintErr("Generating report in ", tempFile.Name())
			_, err = fmt.Fprint(tempFile, input)
			return err
		}
		_, err := fmt.Fprint(output, input)
		return err
	}
}

func invokeDot(format string) PostProcessor {
	divert := awayFromTTY(format)
	return func(input *bytes.Buffer, output io.Writer, ui plugin.UI) error {
		if _, err := exec.LookPath("dot"); err != nil {
			ui.PrintErr("Cannot find dot, have you installed Graphviz?")
			return err
		}
		cmd := exec.Command("dot", "-T"+format)
		var buf bytes.Buffer
		cmd.Stdin, cmd.Stdout, cmd.Stderr = input, &buf, os.Stderr
		if err := cmd.Run(); err != nil {
			return err
		}
		return divert(&buf, output, ui)
	}
}

func saveSVGToFile(svgpan **string) PostProcessor {
	generateSVG := invokeDot("svg")
	divert := awayFromTTY("svg")
	return func(input *bytes.Buffer, output io.Writer, ui plugin.UI) error {
		baseSVG := &bytes.Buffer{}
		generateSVG(input, baseSVG, ui)
		massaged := &bytes.Buffer{}
		fmt.Fprint(massaged, svg.Massage(*baseSVG, **svgpan))
		return divert(massaged, output, ui)
	}
}

func invokeVisualizer(interactive **bool, format PostProcessor, suffix string, visualizers []string) PostProcessor {
	return func(input *bytes.Buffer, output io.Writer, ui plugin.UI) error {
		tempFile, err := tempfile.New(os.Getenv("PPROF_TMPDIR"), "pprof", "."+suffix)
		if err != nil {
			return err
		}
		tempfile.DeferDelete(tempFile.Name())
		if err = format(input, tempFile, ui); err != nil {
			return err
		}
		tempFile.Close() // on windows, if the file is Open, start cannot access it.
		// Try visualizers until one is successful
		for _, v := range visualizers {
			// Separate command and arguments for exec.Command.
			args := strings.Split(v, " ")
			if len(args) == 0 {
				continue
			}
			viewer := exec.Command(args[0], append(args[1:], tempFile.Name())...)
			viewer.Stderr = os.Stderr
			if err = viewer.Start(); err == nil {
				if !**interactive {
					// In command-line mode, wait for the viewer to be closed
					// before proceeding
					return viewer.Wait()
				}
				return nil
			}
		}
		return err
	}
}
<|endoftext|>


<commit_before>//Package raygunHook provides the hook for logrus, to send errors to raygun.io
//for more details visit https://www.github.com/gsblue/raygunHook
package raygunHook

import (
	"github.com/Sirupsen/logrus"
	ray "github.com/gsblue/raygun4go"
	"net/http"
)

type hook struct {
	Client raygunClient
}

//HookConfig is the struct to hold the configuration values required for the hook.
type HookConfig struct {
	APIKey  string   //APIKey for your raygun account. This field is mandatory.
	AppName string   //AppName is your application name. This field is mandatory.
	Version string   //Version of your application
	Tags    []string //Tags which get added to all the error entries
}

type raygunClient interface {
	CreateErrorEntry(err error) *ray.ErrorEntry
	CreateErrorEntryFromMsg(msg string) *ray.ErrorEntry
	SubmitError(entry *ray.ErrorEntry) error
}

const (
	//ErrorFieldName is the name of the field in logrus.Entry.Data, which should hold the error
	ErrorFieldName = "error"
	//RequestFieldName is the name of the field in logrus.Entry.Data, which should hold the request
	RequestFieldName = "request"
	//UserFieldName is the name of the field in logrus.Entry.Data, which should hold the user identifier
	UserFieldName = "user"
	//CustomDataFieldName is the name of the field in logrus.Entry.Data, which should hold any custom data
	CustomDataFieldName = "customData"
)

//NewHook creates a new raygun logrus.Hook
func NewHook(config *HookConfig) (logrus.Hook, error) {
	c, err := ray.New(config.AppName, config.APIKey)
	if err != nil {
		return nil, err
	}
	c.Version(config.Version).Tags(config.Tags)

	return &hook{Client: c}, nil
}

//EntryWithRequest is a helper function to add request to a logrus.Entry
//This information eventually gets sent to raygun to.
func EntryWithRequest(e *logrus.Entry, r *http.Request) *logrus.Entry {
	return e.WithField(RequestFieldName, ray.NewRequestData(r))
}

//EntryWithUser is a helper function to add user identifier to a logrus Entry
//This information eventually gets sent to raygun to.
func EntryWithUser(e *logrus.Entry, user string) *logrus.Entry {
	return e.WithField(UserFieldName, user)
}

//EntryWithUser is a helper function to add custom data to a logrus Entry
//This information eventually gets sent to raygun to.
func EntryWithCustomData(e *logrus.Entry, data interface{}) *logrus.Entry {
	return e.WithField(UserFieldName, data)
}

//Fire sends the error from logrus.Entry to raygun
func (h *hook) Fire(e *logrus.Entry) error {
	var entry *ray.ErrorEntry

	if val, ok := e.Data[ErrorFieldName]; ok {
		if err, ok := val.(error); ok {
			entry = h.Client.CreateErrorEntry(err)
		}
	}

	if entry == nil {
		entry = h.Client.CreateErrorEntryFromMsg(e.Message)
	}

	if val, ok := e.Data[RequestFieldName]; ok {
		if req, ok := val.(*ray.RequestData); ok {
			entry.Request = req
		}
	}

	if val, ok := e.Data[UserFieldName]; ok {
		if user, ok := val.(string); ok {
			entry.SetUser(user)
		}
	}

	if val, ok := e.Data[CustomDataFieldName]; ok {
		entry.SetCustomData(val)
	}

	return h.Client.SubmitError(entry)
}

//Levels returns the logrus.Level which this raygung hook supports
func (h *hook) Levels() []logrus.Level {
	return []logrus.Level{
		logrus.ErrorLevel,
		logrus.FatalLevel,
		logrus.PanicLevel,
	}
}
<commit_msg>fixed function to use the correct field name<commit_after>//Package raygunHook provides the hook for logrus, to send errors to raygun.io
//for more details visit https://www.github.com/gsblue/raygunHook
package raygunHook

import (
	"github.com/Sirupsen/logrus"
	ray "github.com/gsblue/raygun4go"
	"net/http"
)

type hook struct {
	Client raygunClient
}

//HookConfig is the struct to hold the configuration values required for the hook.
type HookConfig struct {
	APIKey  string   //APIKey for your raygun account. This field is mandatory.
	AppName string   //AppName is your application name. This field is mandatory.
	Version string   //Version of your application
	Tags    []string //Tags which get added to all the error entries
}

type raygunClient interface {
	CreateErrorEntry(err error) *ray.ErrorEntry
	CreateErrorEntryFromMsg(msg string) *ray.ErrorEntry
	SubmitError(entry *ray.ErrorEntry) error
}

const (
	//ErrorFieldName is the name of the field in logrus.Entry.Data, which should hold the error
	ErrorFieldName = "error"
	//RequestFieldName is the name of the field in logrus.Entry.Data, which should hold the request
	RequestFieldName = "request"
	//UserFieldName is the name of the field in logrus.Entry.Data, which should hold the user identifier
	UserFieldName = "user"
	//CustomDataFieldName is the name of the field in logrus.Entry.Data, which should hold any custom data
	CustomDataFieldName = "customData"
)

//NewHook creates a new raygun logrus.Hook
func NewHook(config *HookConfig) (logrus.Hook, error) {
	c, err := ray.New(config.AppName, config.APIKey)
	if err != nil {
		return nil, err
	}
	c.Version(config.Version).Tags(config.Tags)

	return &hook{Client: c}, nil
}

//EntryWithRequest is a helper function to add request to a logrus.Entry
//This information eventually gets sent to raygun to.
func EntryWithRequest(e *logrus.Entry, r *http.Request) *logrus.Entry {
	return e.WithField(RequestFieldName, ray.NewRequestData(r))
}

//EntryWithUser is a helper function to add user identifier to a logrus Entry
//This information eventually gets sent to raygun to.
func EntryWithUser(e *logrus.Entry, user string) *logrus.Entry {
	return e.WithField(UserFieldName, user)
}

//EntryWithUser is a helper function to add custom data to a logrus Entry
//This information eventually gets sent to raygun to.
func EntryWithCustomData(e *logrus.Entry, data interface{}) *logrus.Entry {
	return e.WithField(CustomDataFieldName, data)
}

//Fire sends the error from logrus.Entry to raygun
func (h *hook) Fire(e *logrus.Entry) error {
	var entry *ray.ErrorEntry

	if val, ok := e.Data[ErrorFieldName]; ok {
		if err, ok := val.(error); ok {
			entry = h.Client.CreateErrorEntry(err)
		}
	}

	if entry == nil {
		entry = h.Client.CreateErrorEntryFromMsg(e.Message)
	}

	if val, ok := e.Data[RequestFieldName]; ok {
		if req, ok := val.(*ray.RequestData); ok {
			entry.Request = req
		}
	}

	if val, ok := e.Data[UserFieldName]; ok {
		if user, ok := val.(string); ok {
			entry.SetUser(user)
		}
	}

	if val, ok := e.Data[CustomDataFieldName]; ok {
		entry.SetCustomData(val)
	}

	return h.Client.SubmitError(entry)
}

//Levels returns the logrus.Level which this raygung hook supports
func (h *hook) Levels() []logrus.Level {
	return []logrus.Level{
		logrus.ErrorLevel,
		logrus.FatalLevel,
		logrus.PanicLevel,
	}
}
<|endoftext|>


<commit_before>package acgen

import (
	"io"
	"strings"
	"text/template"
)

func init() {
	RegisterGenerator("tcsh", generateTcshCompletion)
}

type tcsh struct {
	Name string
	Opt  string
}

func newTcsh(c *Command) (t *tcsh, err error) {
	opts := make([]string, 0)
	for _, flag := range c.Flags {
		for _, opt := range flag.Long {
			opts = append(opts, opt)
		}
	}
	return &tcsh{
		Name: c.Name,
		Opt:  strings.Join(opts, " "),
	}, nil
}

var tcshTemplate = template.Must(template.New("tcsh").Parse(`
complete {{.Name}} 'c/--/({{.Opt}})/'
`[1:]))

func generateTcshCompletion(w io.Writer, c *Command) error {
	t, err := newTcsh(c)
	if err != nil {
		return err
	}
	return tcshTemplate.Execute(w, t)
}
<commit_msg>Use var instead of make<commit_after>package acgen

import (
	"io"
	"strings"
	"text/template"
)

func init() {
	RegisterGenerator("tcsh", generateTcshCompletion)
}

type tcsh struct {
	Name string
	Opt  string
}

func newTcsh(c *Command) (t *tcsh, err error) {
	var opts []string
	for _, flag := range c.Flags {
		for _, opt := range flag.Long {
			opts = append(opts, opt)
		}
	}
	return &tcsh{
		Name: c.Name,
		Opt:  strings.Join(opts, " "),
	}, nil
}

var tcshTemplate = template.Must(template.New("tcsh").Parse(`
complete {{.Name}} 'c/--/({{.Opt}})/'
`[1:]))

func generateTcshCompletion(w io.Writer, c *Command) error {
	t, err := newTcsh(c)
	if err != nil {
		return err
	}
	return tcshTemplate.Execute(w, t)
}
<|endoftext|>


<commit_before>package abkleveldb

import (
  "github.com/jmhodges/levigo"

  golerror "github.com/abhishekkr/gol/golerror"
)

/*
Creates a db at provided pathname.
*/
func CreateDB(dbname string) (*levigo.DB) {
  opts := levigo.NewOptions()
  opts.SetCache(levigo.NewLRUCache(1<<10))
  opts.SetCreateIfMissing(true)
  db, err := levigo.Open(dbname, opts)
  if err != nil { golerror.Boohoo("DB " + dbname + " Creation failed.", true) }
  return db
}

/*
Push KeyVal in provided DB handle.
*/
func PushKeyVal(key string, val string, db *levigo.DB) bool{
  writer := levigo.NewWriteOptions()
  defer writer.Close()

  keyname := []byte(key)
  value := []byte(val)
  err := db.Put(writer, keyname, value)
  if err != nil {
    golerror.Boohoo("Key " + key + " insertion failed. It's value was " + val, false)
    return false
  }
  return true
}

/*
Get Value of Key from provided db handle.
*/
func GetVal(key string, db *levigo.DB) string {
  reader := levigo.NewReadOptions()
  defer reader.Close()

  data, err := db.Get(reader, []byte(key))
  if err != nil {
    golerror.Boohoo("Key " + key + " query failed.", false)
    return ""
  }
  return string(data)
}

/*
Del Key from provided DB handle.
*/
func DelKey(key string, db *levigo.DB) bool {
  writer := levigo.NewWriteOptions()
  defer writer.Close()

  err := db.Delete(writer, []byte(key))
  if err != nil {
    golerror.Boohoo("Key " + key + " query failed.", false)
    return false
  }
  return true
}
<commit_msg>updated abkleveldb; CloseAndDeleteDB is there<commit_after>package abkleveldb

import (
  "fmt"
  "os"

  "github.com/jmhodges/levigo"

  golerror "github.com/abhishekkr/gol/golerror"
)

/*
Creates a db at provided dbpath.
*/
func CreateDB(dbpath string) (*levigo.DB) {
  opts := levigo.NewOptions()
  opts.SetCache(levigo.NewLRUCache(1<<10))
  opts.SetCreateIfMissing(true)
  db, err := levigo.Open(dbpath, opts)
  if err != nil {
    err_msg := fmt.Sprintf("DB %s Creation failed. %q", dbpath, err)
    golerror.Boohoo(err_msg, true)
  }
  return db
}

/*
Closing and Deleting a db given handle and dbpath.
Useful in use and throw implementations. And also tests.
*/
func CloseAndDeleteDB(dbpath string, db *levigo.DB){
  db.Close()
  if os.RemoveAll(dbpath) != nil {
    panic("Fail: Temporary DB files are still present at: " + dbpath)
  }
}

/*
Push KeyVal in provided DB handle.
*/
func PushKeyVal(key string, val string, db *levigo.DB) bool{
  writer := levigo.NewWriteOptions()
  defer writer.Close()

  keyname := []byte(key)
  value := []byte(val)
  err := db.Put(writer, keyname, value)
  if err != nil {
    golerror.Boohoo("Key " + key + " insertion failed. It's value was " + val, false)
    return false
  }
  return true
}

/*
Get Value of Key from provided db handle.
*/
func GetVal(key string, db *levigo.DB) string {
  reader := levigo.NewReadOptions()
  defer reader.Close()

  data, err := db.Get(reader, []byte(key))
  if err != nil {
    golerror.Boohoo("Key " + key + " query failed.", false)
    return ""
  }
  return string(data)
}

/*
Del Key from provided DB handle.
*/
func DelKey(key string, db *levigo.DB) bool {
  writer := levigo.NewWriteOptions()
  defer writer.Close()

  err := db.Delete(writer, []byte(key))
  if err != nil {
    golerror.Boohoo("Key " + key + " query failed.", false)
    return false
  }
  return true
}
<|endoftext|>


<commit_before>/*-
 * Copyright (c) 2012 Caoimhe Chaos <caoimhechaos@protonmail.com>,
 *                    Ancient Solutions. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions  of source code must retain  the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions  in   binary  form  must   reproduce  the  above
 *    copyright  notice, this  list  of conditions  and the  following
 *    disclaimer in the  documentation and/or other materials provided
 *    with the distribution.
 *
 * THIS  SOFTWARE IS  PROVIDED BY  ANCIENT SOLUTIONS  AND CONTRIBUTORS
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO,  THE IMPLIED WARRANTIES OF  MERCHANTABILITY AND FITNESS
 * FOR A  PARTICULAR PURPOSE  ARE DISCLAIMED.  IN  NO EVENT  SHALL THE
 * FOUNDATION  OR CONTRIBUTORS  BE  LIABLE FOR  ANY DIRECT,  INDIRECT,
 * INCIDENTAL,   SPECIAL,    EXEMPLARY,   OR   CONSEQUENTIAL   DAMAGES
 * (INCLUDING, BUT NOT LIMITED  TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE,  DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT  LIABILITY,  OR  TORT  (INCLUDING NEGLIGENCE  OR  OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 */

package main

import (
	"flag"
	"fmt"
	"log"
	"net"
	"net/rpc"
	"os"
	"strings"

	"ancientsolutions.com/geocolo"
	"ancientsolutions.com/urlconnection"
)

func main() {
	var endpoint, uri, buri, origin, candidates string
	var req geocolo.GeoProximityRequest
	var res geocolo.GeoProximityResponse
	var client *rpc.Client
	var conn net.Conn
	var detailed bool
	var err error

	flag.StringVar(&endpoint, "endpoint", "",
		"The service URL to connect to")
	flag.StringVar(&uri, "doozer-uri", os.Getenv("DOOZER_URI"),
		"Doozer URI to connect to")
	flag.StringVar(&buri, "doozer-boot-uri", os.Getenv("DOOZER_BOOT_URI"),
		"Doozer Boot URI to find named clusters")
	flag.StringVar(&origin, "origin", "",
		"Country which we're looking for close countries for")
	flag.StringVar(&candidates, "candidates", "",
		"Comma separated list of countries to consider")
	flag.BoolVar(&detailed, "detailed", false,
		"Whether to give a detailed response")
	flag.Parse()

	if uri != "" {
		if err = urlconnection.SetupDoozer(buri, uri); err != nil {
			log.Fatal("Error initializing Doozer connection to ",
				uri, ": ", err.Error())
		}
	}

	conn, err = urlconnection.Connect(endpoint)
	if err != nil {
		log.Fatal("Error connecting to ", endpoint, ": ", err.Error())
	}

	if len(candidates) > 0 {
		req.Candidates = strings.Split(candidates, ",")
	}

	req.Origin = &origin
	req.DetailedResponse = &detailed

	client = rpc.NewClient(conn)
	err = client.Call("GeoProximityService.GetProximity", req, res)
	if err != nil {
		log.Fatal("Error sending proximity request: ", err.Error())
	}

	fmt.Printf("Closest country: %s\n", *res.Closest)

	for _, detail := range res.FullMap {
		fmt.Printf("Country %s: distance %f\n", *detail.Country,
			*detail.Distance)
	}
}
<commit_msg>Add some safety checks to the client.<commit_after>/*-
 * Copyright (c) 2012 Caoimhe Chaos <caoimhechaos@protonmail.com>,
 *                    Ancient Solutions. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions  of source code must retain  the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions  in   binary  form  must   reproduce  the  above
 *    copyright  notice, this  list  of conditions  and the  following
 *    disclaimer in the  documentation and/or other materials provided
 *    with the distribution.
 *
 * THIS  SOFTWARE IS  PROVIDED BY  ANCIENT SOLUTIONS  AND CONTRIBUTORS
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO,  THE IMPLIED WARRANTIES OF  MERCHANTABILITY AND FITNESS
 * FOR A  PARTICULAR PURPOSE  ARE DISCLAIMED.  IN  NO EVENT  SHALL THE
 * FOUNDATION  OR CONTRIBUTORS  BE  LIABLE FOR  ANY DIRECT,  INDIRECT,
 * INCIDENTAL,   SPECIAL,    EXEMPLARY,   OR   CONSEQUENTIAL   DAMAGES
 * (INCLUDING, BUT NOT LIMITED  TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE,  DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT  LIABILITY,  OR  TORT  (INCLUDING NEGLIGENCE  OR  OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 */

package main

import (
	"flag"
	"fmt"
	"log"
	"net"
	"net/rpc"
	"os"
	"strings"

	"ancientsolutions.com/geocolo"
	"ancientsolutions.com/urlconnection"
)

func main() {
	var endpoint, uri, buri, origin, candidates string
	var req geocolo.GeoProximityRequest
	var res geocolo.GeoProximityResponse
	var client *rpc.Client
	var conn net.Conn
	var detailed bool
	var err error

	flag.StringVar(&endpoint, "endpoint", "",
		"The service URL to connect to")
	flag.StringVar(&uri, "doozer-uri", os.Getenv("DOOZER_URI"),
		"Doozer URI to connect to")
	flag.StringVar(&buri, "doozer-boot-uri", os.Getenv("DOOZER_BOOT_URI"),
		"Doozer Boot URI to find named clusters")
	flag.StringVar(&origin, "origin", "",
		"Country which we're looking for close countries for")
	flag.StringVar(&candidates, "candidates", "",
		"Comma separated list of countries to consider")
	flag.BoolVar(&detailed, "detailed", false,
		"Whether to give a detailed response")
	flag.Parse()

	if uri != "" {
		if err = urlconnection.SetupDoozer(buri, uri); err != nil {
			log.Fatal("Error initializing Doozer connection to ",
				uri, ": ", err.Error())
		}
	}

	conn, err = urlconnection.Connect(endpoint)
	if err != nil {
		log.Fatal("Error connecting to ", endpoint, ": ", err.Error())
	}

	if len(candidates) > 0 {
		req.Candidates = strings.Split(candidates, ",")
	}

	req.Origin = &origin
	req.DetailedResponse = &detailed

	client = rpc.NewClient(conn)
	err = client.Call("GeoProximityService.GetProximity", req, &res)
	if err != nil {
		log.Fatal("Error sending proximity request: ", err.Error())
	}

	if res.Closest == nil {
		log.Fatal("Failed to fetch closest country")
	} else {
		fmt.Printf("Closest country: %s\n", *res.Closest)
	}

	for _, detail := range res.FullMap {
		if detail == nil {
			log.Print("Error: detail is nil?")
		} else if detail.Country == nil {
			log.Print("Error: country is nil?")
			if detail.Distance != nil {
				log.Printf("(distance was %f)",
					*detail.Distance)
			}
		} else if detail.Distance == nil {
			log.Print("Error: distance is nil?")
			if detail.Country != nil {
				log.Printf("(country was %s)", *detail.Country)
			}
		} else {
			fmt.Printf("Country %s: distance %f\n", *detail.Country,
				*detail.Distance)
		}
	}
}
<|endoftext|>