<commit_before>// Copyright 2017 The go-hep 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 rootio

import (
	"reflect"
)

type tgraph struct {
	rvers int16
	named tnamed

	maxsize int32
	npoints int32
	x       []float64
	y       []float64
	funcs   List
	histo   *H1F
	min     float64
	max     float64
}

func (g *tgraph) Class() string {
	return "TGraph"
}

func (g *tgraph) Name() string {
	return g.named.Name()
}

func (g *tgraph) Title() string {
	return g.named.Title()
}

func (g *tgraph) Len() int {
	return int(len(g.x))
}

func (g *tgraph) XY(i int) (float64, float64) {
	return g.x[i], g.y[i]
}

// ROOTUnmarshaler is the interface implemented by an object that can
// unmarshal itself from a ROOT buffer
func (g *tgraph) UnmarshalROOT(r *RBuffer) error {
	beg := r.Pos()

	vers, pos, bcnt := r.ReadVersion()
	g.rvers = vers

	for _, a := range []ROOTUnmarshaler{
		&g.named,
		&attline{},
		&attfill{},
		&attmarker{},
	} {
		err := a.UnmarshalROOT(r)
		if err != nil {
			return err
		}
	}

	g.npoints = r.ReadI32()
	g.maxsize = g.npoints
	if vers < 2 {
		_ = r.ReadI8()
		xs := r.ReadFastArrayF32(int(g.npoints))
		_ = r.ReadI8()
		ys := r.ReadFastArrayF32(int(g.npoints))
		g.x = make([]float64, len(xs))
		g.y = make([]float64, len(ys))
		for i := range xs {
			g.x[i] = float64(xs[i])
			g.y[i] = float64(ys[i])
		}

	} else {
		_ = r.ReadI8()
		g.x = r.ReadFastArrayF64(int(g.npoints))
		_ = r.ReadI8()
		g.y = r.ReadFastArrayF64(int(g.npoints))
	}

	funcs := r.ReadObjectAny()
	if funcs != nil {
		g.funcs = funcs.(List)
	}

	histo := r.ReadObjectAny()
	if histo != nil {
		g.histo = histo.(*H1F)
	}

	if vers < 2 {
		g.min = float64(r.ReadF32())
		g.max = float64(r.ReadF32())
	} else {
		g.min = r.ReadF64()
		g.max = r.ReadF64()
	}

	r.CheckByteCount(pos, bcnt, beg, "TGraph")
	return r.Err()
}

type tgrapherrs struct {
	rvers int16
	tgraph

	xerr []float64
	yerr []float64
}

func (g *tgrapherrs) Class() string {
	return "TGraphErrors"
}

func (g *tgrapherrs) XError(i int) (float64, float64) {
	return g.xerr[i], g.xerr[i]
}

func (g *tgrapherrs) YError(i int) (float64, float64) {
	return g.yerr[i], g.yerr[i]
}

// ROOTUnmarshaler is the interface implemented by an object that can
// unmarshal itself from a ROOT buffer
func (g *tgrapherrs) UnmarshalROOT(r *RBuffer) error {
	beg := r.Pos()

	vers, pos, bcnt := r.ReadVersion()
	g.rvers = vers

	err := g.tgraph.UnmarshalROOT(r)
	if err != nil {
		return err
	}

	if vers < 2 {
		_ = r.ReadI8()
		xerrs := r.ReadFastArrayF32(int(g.tgraph.npoints))
		_ = r.ReadI8()
		yerrs := r.ReadFastArrayF32(int(g.tgraph.npoints))
		g.xerr = make([]float64, len(xerrs))
		g.yerr = make([]float64, len(yerrs))
		for i := range xerrs {
			g.xerr[i] = float64(xerrs[i])
			g.yerr[i] = float64(yerrs[i])
		}

	} else {
		_ = r.ReadI8()
		g.xerr = r.ReadFastArrayF64(int(g.tgraph.npoints))
		_ = r.ReadI8()
		g.yerr = r.ReadFastArrayF64(int(g.tgraph.npoints))
	}
	r.CheckByteCount(pos, bcnt, beg, "TGraphErrors")
	return r.Err()
}

type tgraphasymmerrs struct {
	rvers int16
	tgraph

	xerrlo []float64
	xerrhi []float64
	yerrlo []float64
	yerrhi []float64
}

func (g *tgraphasymmerrs) Class() string {
	return "TGraphAsymmErrors"
}

func (g *tgraphasymmerrs) XError(i int) (float64, float64) {
	return g.xerrlo[i], g.xerrhi[i]
}

func (g *tgraphasymmerrs) YError(i int) (float64, float64) {
	return g.yerrlo[i], g.yerrhi[i]
}

// ROOTUnmarshaler is the interface implemented by an object that can
// unmarshal itself from a ROOT buffer
func (g *tgraphasymmerrs) UnmarshalROOT(r *RBuffer) error {
	beg := r.Pos()

	vers, pos, bcnt := r.ReadVersion()
	g.rvers = vers

	err := g.tgraph.UnmarshalROOT(r)
	if err != nil {
		return err
	}

	n := int(g.tgraph.npoints)
	switch {
	case vers < 2:
		// up to version 2, order is: xlo,ylo,xhi,yhi
		_ = r.ReadI8()
		xerrlo := r.ReadFastArrayF32(n)
		_ = r.ReadI8()
		yerrlo := r.ReadFastArrayF32(n)
		_ = r.ReadI8()
		xerrhi := r.ReadFastArrayF32(n)
		_ = r.ReadI8()
		yerrhi := r.ReadFastArrayF32(n)
		g.xerrlo = make([]float64, n)
		g.xerrhi = make([]float64, n)
		g.yerrlo = make([]float64, n)
		g.yerrhi = make([]float64, n)
		for i := range xerrlo {
			g.xerrlo[i] = float64(xerrlo[i])
			g.xerrhi[i] = float64(xerrhi[i])
			g.yerrlo[i] = float64(yerrlo[i])
			g.yerrhi[i] = float64(yerrhi[i])
		}
	case vers == 2:
		// version 2, order is: xlo,ylo,xhi,yhi (but in float64)
		_ = r.ReadI8()
		g.xerrlo = r.ReadFastArrayF64(n)
		_ = r.ReadI8()
		g.yerrlo = r.ReadFastArrayF64(n)
		_ = r.ReadI8()
		g.xerrhi = r.ReadFastArrayF64(n)
		_ = r.ReadI8()
		g.yerrhi = r.ReadFastArrayF64(n)
	default:
		// version 3 and higher: xlo,xhi,ylo,yhi
		// ie: the order of the fields in the TGraphAsymmErrors class.
		_ = r.ReadI8()
		g.xerrlo = r.ReadFastArrayF64(n)
		_ = r.ReadI8()
		g.xerrhi = r.ReadFastArrayF64(n)
		_ = r.ReadI8()
		g.yerrlo = r.ReadFastArrayF64(n)
		_ = r.ReadI8()
		g.yerrhi = r.ReadFastArrayF64(n)
	}
	r.CheckByteCount(pos, bcnt, beg, "TGraphAsymmErrors")
	return r.Err()
}

func init() {
	{
		f := func() reflect.Value {
			o := &tgraph{}
			return reflect.ValueOf(o)
		}
		Factory.add("TGraph", f)
		Factory.add("*rootio.tgraph", f)
	}
	{
		f := func() reflect.Value {
			o := &tgrapherrs{}
			return reflect.ValueOf(o)
		}
		Factory.add("TGraphErrors", f)
		Factory.add("*rootio.tgrapherrs", f)
	}
	{
		f := func() reflect.Value {
			o := &tgraphasymmerrs{}
			return reflect.ValueOf(o)
		}
		Factory.add("TGraphAsymmErrors", f)
		Factory.add("*rootio.tgraphasymmerrs", f)
	}
}

var _ Object = (*tgraph)(nil)
var _ Named = (*tgraph)(nil)
var _ Graph = (*tgraph)(nil)
var _ ROOTUnmarshaler = (*tgraph)(nil)

var _ Object = (*tgrapherrs)(nil)
var _ Named = (*tgrapherrs)(nil)
var _ Graph = (*tgrapherrs)(nil)
var _ GraphErrors = (*tgrapherrs)(nil)
var _ ROOTUnmarshaler = (*tgrapherrs)(nil)

var _ Object = (*tgraphasymmerrs)(nil)
var _ Named = (*tgraphasymmerrs)(nil)
var _ Graph = (*tgraphasymmerrs)(nil)
var _ GraphErrors = (*tgraphasymmerrs)(nil)
var _ ROOTUnmarshaler = (*tgraphasymmerrs)(nil)
<commit_msg>rootio: implement ROOTMarshaler for TGraph{,Errors,AsymmErrors}<commit_after>// Copyright 2017 The go-hep 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 rootio

import (
	"reflect"
)

type tgraph struct {
	rvers int16
	named tnamed

	maxsize int32
	npoints int32
	x       []float64
	y       []float64
	funcs   List
	histo   *H1F
	min     float64
	max     float64
}

func (g *tgraph) Class() string {
	return "TGraph"
}

func (g *tgraph) Name() string {
	return g.named.Name()
}

func (g *tgraph) Title() string {
	return g.named.Title()
}

func (g *tgraph) Len() int {
	return int(len(g.x))
}

func (g *tgraph) XY(i int) (float64, float64) {
	return g.x[i], g.y[i]
}

// ROOTMarshaler is the interface implemented by an object that can
// marshal itself to a ROOT buffer
func (g *tgraph) MarshalROOT(w *WBuffer) (int, error) {
	if w.err != nil {
		return 0, w.err
	}

	pos := w.Pos()

	w.WriteVersion(g.rvers)

	for _, a := range []ROOTMarshaler{
		&g.named,
		&attline{},
		&attfill{},
		&attmarker{},
	} {
		if _, err := a.MarshalROOT(w); err != nil {
			w.err = err
			return 0, w.err
		}
	}

	w.WriteI32(g.npoints)
	{
		w.WriteI8(0)
		w.WriteFastArrayF64(g.x)
		w.WriteI8(0)
		w.WriteFastArrayF64(g.y)
	}

	w.WriteObjectAny(g.funcs)
	w.WriteObjectAny(g.histo)
	{
		w.WriteF64(g.min)
		w.WriteF64(g.max)
	}

	return w.SetByteCount(pos, "TGraph")
}

// ROOTUnmarshaler is the interface implemented by an object that can
// unmarshal itself from a ROOT buffer
func (g *tgraph) UnmarshalROOT(r *RBuffer) error {
	beg := r.Pos()

	vers, pos, bcnt := r.ReadVersion()
	g.rvers = vers

	for _, a := range []ROOTUnmarshaler{
		&g.named,
		&attline{},
		&attfill{},
		&attmarker{},
	} {
		err := a.UnmarshalROOT(r)
		if err != nil {
			return err
		}
	}

	g.npoints = r.ReadI32()
	g.maxsize = g.npoints
	if vers < 2 {
		_ = r.ReadI8()
		xs := r.ReadFastArrayF32(int(g.npoints))
		_ = r.ReadI8()
		ys := r.ReadFastArrayF32(int(g.npoints))
		g.x = make([]float64, len(xs))
		g.y = make([]float64, len(ys))
		for i := range xs {
			g.x[i] = float64(xs[i])
			g.y[i] = float64(ys[i])
		}

	} else {
		_ = r.ReadI8()
		g.x = r.ReadFastArrayF64(int(g.npoints))
		_ = r.ReadI8()
		g.y = r.ReadFastArrayF64(int(g.npoints))
	}

	funcs := r.ReadObjectAny()
	if funcs != nil {
		g.funcs = funcs.(List)
	}

	histo := r.ReadObjectAny()
	if histo != nil {
		g.histo = histo.(*H1F)
	}

	if vers < 2 {
		g.min = float64(r.ReadF32())
		g.max = float64(r.ReadF32())
	} else {
		g.min = r.ReadF64()
		g.max = r.ReadF64()
	}

	r.CheckByteCount(pos, bcnt, beg, "TGraph")
	return r.Err()
}

type tgrapherrs struct {
	rvers int16
	tgraph

	xerr []float64
	yerr []float64
}

func (g *tgrapherrs) Class() string {
	return "TGraphErrors"
}

func (g *tgrapherrs) XError(i int) (float64, float64) {
	return g.xerr[i], g.xerr[i]
}

func (g *tgrapherrs) YError(i int) (float64, float64) {
	return g.yerr[i], g.yerr[i]
}

// ROOTMarshaler is the interface implemented by an object that can
// marshal itself to a ROOT buffer
func (g *tgrapherrs) MarshalROOT(w *WBuffer) (int, error) {
	if w.err != nil {
		return 0, nil
	}

	pos := w.Pos()
	w.WriteVersion(g.rvers)

	if n, err := g.tgraph.MarshalROOT(w); err != nil {
		w.err = err
		return n, w.err
	}

	{
		w.WriteI8(0)
		w.WriteFastArrayF64(g.xerr)
		w.WriteI8(0)
		w.WriteFastArrayF64(g.yerr)
	}

	return w.SetByteCount(pos, "TGraphErrors")
}

// ROOTUnmarshaler is the interface implemented by an object that can
// unmarshal itself from a ROOT buffer
func (g *tgrapherrs) UnmarshalROOT(r *RBuffer) error {
	beg := r.Pos()

	vers, pos, bcnt := r.ReadVersion()
	g.rvers = vers

	err := g.tgraph.UnmarshalROOT(r)
	if err != nil {
		return err
	}

	if vers < 2 {
		_ = r.ReadI8()
		xerrs := r.ReadFastArrayF32(int(g.tgraph.npoints))
		_ = r.ReadI8()
		yerrs := r.ReadFastArrayF32(int(g.tgraph.npoints))
		g.xerr = make([]float64, len(xerrs))
		g.yerr = make([]float64, len(yerrs))
		for i := range xerrs {
			g.xerr[i] = float64(xerrs[i])
			g.yerr[i] = float64(yerrs[i])
		}

	} else {
		_ = r.ReadI8()
		g.xerr = r.ReadFastArrayF64(int(g.tgraph.npoints))
		_ = r.ReadI8()
		g.yerr = r.ReadFastArrayF64(int(g.tgraph.npoints))
	}
	r.CheckByteCount(pos, bcnt, beg, "TGraphErrors")
	return r.Err()
}

type tgraphasymmerrs struct {
	rvers int16
	tgraph

	xerrlo []float64
	xerrhi []float64
	yerrlo []float64
	yerrhi []float64
}

func (g *tgraphasymmerrs) Class() string {
	return "TGraphAsymmErrors"
}

func (g *tgraphasymmerrs) XError(i int) (float64, float64) {
	return g.xerrlo[i], g.xerrhi[i]
}

func (g *tgraphasymmerrs) YError(i int) (float64, float64) {
	return g.yerrlo[i], g.yerrhi[i]
}

// ROOTMarshaler is the interface implemented by an object that can
// marshal itself to a ROOT buffer
func (g *tgraphasymmerrs) MarshalROOT(w *WBuffer) (int, error) {
	if w.err != nil {
		return 0, w.err
	}

	pos := w.Pos()
	w.WriteVersion(g.rvers)

	if n, err := g.tgraph.MarshalROOT(w); err != nil {
		w.err = err
		return n, w.err
	}

	{
		w.WriteI8(0)
		w.WriteFastArrayF64(g.xerrlo)
		w.WriteI8(0)
		w.WriteFastArrayF64(g.xerrhi)
		w.WriteI8(0)
		w.WriteFastArrayF64(g.yerrlo)
		w.WriteI8(0)
		w.WriteFastArrayF64(g.yerrhi)
	}

	return w.SetByteCount(pos, "TGraphAsymmErrors")
}

// ROOTUnmarshaler is the interface implemented by an object that can
// unmarshal itself from a ROOT buffer
func (g *tgraphasymmerrs) UnmarshalROOT(r *RBuffer) error {
	beg := r.Pos()

	vers, pos, bcnt := r.ReadVersion()
	g.rvers = vers

	err := g.tgraph.UnmarshalROOT(r)
	if err != nil {
		return err
	}

	n := int(g.tgraph.npoints)
	switch {
	case vers < 2:
		// up to version 2, order is: xlo,ylo,xhi,yhi
		_ = r.ReadI8()
		xerrlo := r.ReadFastArrayF32(n)
		_ = r.ReadI8()
		yerrlo := r.ReadFastArrayF32(n)
		_ = r.ReadI8()
		xerrhi := r.ReadFastArrayF32(n)
		_ = r.ReadI8()
		yerrhi := r.ReadFastArrayF32(n)
		g.xerrlo = make([]float64, n)
		g.xerrhi = make([]float64, n)
		g.yerrlo = make([]float64, n)
		g.yerrhi = make([]float64, n)
		for i := range xerrlo {
			g.xerrlo[i] = float64(xerrlo[i])
			g.xerrhi[i] = float64(xerrhi[i])
			g.yerrlo[i] = float64(yerrlo[i])
			g.yerrhi[i] = float64(yerrhi[i])
		}
	case vers == 2:
		// version 2, order is: xlo,ylo,xhi,yhi (but in float64)
		_ = r.ReadI8()
		g.xerrlo = r.ReadFastArrayF64(n)
		_ = r.ReadI8()
		g.yerrlo = r.ReadFastArrayF64(n)
		_ = r.ReadI8()
		g.xerrhi = r.ReadFastArrayF64(n)
		_ = r.ReadI8()
		g.yerrhi = r.ReadFastArrayF64(n)
	default:
		// version 3 and higher: xlo,xhi,ylo,yhi
		// ie: the order of the fields in the TGraphAsymmErrors class.
		_ = r.ReadI8()
		g.xerrlo = r.ReadFastArrayF64(n)
		_ = r.ReadI8()
		g.xerrhi = r.ReadFastArrayF64(n)
		_ = r.ReadI8()
		g.yerrlo = r.ReadFastArrayF64(n)
		_ = r.ReadI8()
		g.yerrhi = r.ReadFastArrayF64(n)
	}
	r.CheckByteCount(pos, bcnt, beg, "TGraphAsymmErrors")
	return r.Err()
}

func init() {
	{
		f := func() reflect.Value {
			o := &tgraph{}
			return reflect.ValueOf(o)
		}
		Factory.add("TGraph", f)
		Factory.add("*rootio.tgraph", f)
	}
	{
		f := func() reflect.Value {
			o := &tgrapherrs{}
			return reflect.ValueOf(o)
		}
		Factory.add("TGraphErrors", f)
		Factory.add("*rootio.tgrapherrs", f)
	}
	{
		f := func() reflect.Value {
			o := &tgraphasymmerrs{}
			return reflect.ValueOf(o)
		}
		Factory.add("TGraphAsymmErrors", f)
		Factory.add("*rootio.tgraphasymmerrs", f)
	}
}

var (
	_ Object          = (*tgraph)(nil)
	_ Named           = (*tgraph)(nil)
	_ Graph           = (*tgraph)(nil)
	_ ROOTMarshaler   = (*tgraph)(nil)
	_ ROOTUnmarshaler = (*tgraph)(nil)

	_ Object          = (*tgrapherrs)(nil)
	_ Named           = (*tgrapherrs)(nil)
	_ Graph           = (*tgrapherrs)(nil)
	_ GraphErrors     = (*tgrapherrs)(nil)
	_ ROOTMarshaler   = (*tgrapherrs)(nil)
	_ ROOTUnmarshaler = (*tgrapherrs)(nil)

	_ Object          = (*tgraphasymmerrs)(nil)
	_ Named           = (*tgraphasymmerrs)(nil)
	_ Graph           = (*tgraphasymmerrs)(nil)
	_ GraphErrors     = (*tgraphasymmerrs)(nil)
	_ ROOTMarshaler   = (*tgraphasymmerrs)(nil)
	_ ROOTUnmarshaler = (*tgraphasymmerrs)(nil)
)
<|endoftext|>


<commit_before>// Copyright 2015 Pikkpoiss
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package main

import ()

type BlockState int32

const (
	_                      = iota
	BlockNormal BlockState = 1 << iota
	BlockScaring
)

type BlockPlacement struct {
	Pos     Ivec2
	Block   *Block
	Variant int
}

type BlockAnimations map[BlockState][]int

var (
	SkeletonAnimations = BlockAnimations{
		BlockNormal:  []int{0},
		BlockScaring: []int{1, 2, 3, 4},
	}
	SkeletonTemplate = &GridItemTemplate{
		false,
		"skeleton01_%02v",
		SkeletonAnimations,
	}
)

var (
	SpikesAnimations = BlockAnimations{
		BlockNormal: []int{0},
		BlockScaring: []int{
			1,
			2, 2, 2, 2, 2, 2, 2, 2, 2,
			3, 3,
			4, 4,
			0, 0, 0, 0, 0, 0, 0, 0,
		},
	}
	SpikesTemplate = &GridItemTemplate{
		false,
		"spikes01_%02v",
		SpikesAnimations,
	}
)

var (
	BoxAnimations = BlockAnimations{
		BlockNormal:  []int{0},
		BlockScaring: []int{0},
	}
	BoxTemplate = &GridItemTemplate{
		false,
		"box01_%02v",
		BoxAnimations,
	}
)

type GridItemTemplate struct {
	Passable bool
	Frame    string
	Frames   BlockAnimations
}

type BlockTemplate [][]*GridItemTemplate

// TODO: Introduce a cooldown for scaring people.
type Block struct {
	Variants   []BlockTemplate
	Offset     Ivec2
	Range      float32 // Radius of effectiveness.
	MaxTargets int     // -1 for infinite.
	FearPerSec float64 // Amount of fear added to target per second.
	Cost       int
	Title      string
}

var (
	SkellyBlock = Block{
		Variants: []BlockTemplate{
			BlockTemplate{
				[]*GridItemTemplate{
					SkeletonTemplate,
				},
			},
		},
		Offset:     Ivec2{0, 0},
		Range:      1.5,
		MaxTargets: 1,
		FearPerSec: 2.0,
		Cost:       10,
		Title:      "Mr. Bones",
	}

	SpikesBlock = Block{
		Variants: []BlockTemplate{
			BlockTemplate{
				[]*GridItemTemplate{SpikesTemplate, SpikesTemplate, SpikesTemplate},
				[]*GridItemTemplate{nil, nil, nil},
				[]*GridItemTemplate{SpikesTemplate, SpikesTemplate, SpikesTemplate},
			},
			BlockTemplate{
				[]*GridItemTemplate{SpikesTemplate, nil, SpikesTemplate},
				[]*GridItemTemplate{SpikesTemplate, nil, SpikesTemplate},
				[]*GridItemTemplate{SpikesTemplate, nil, SpikesTemplate},
			},
		},
		Offset:     Ivec2{-1, -1},
		Range:      5.0,
		MaxTargets: 3,
		FearPerSec: 0.5,
		Cost:       100,
		Title:      "Spiketron 5000",
	}

	CornerBlock = Block{
		Variants: []BlockTemplate{
			BlockTemplate{
				[]*GridItemTemplate{SpikesTemplate, SpikesTemplate, SpikesTemplate},
				[]*GridItemTemplate{nil, nil, SpikesTemplate},
				[]*GridItemTemplate{SpikesTemplate, nil, SpikesTemplate},
			},
			BlockTemplate{
				[]*GridItemTemplate{SpikesTemplate, nil, SpikesTemplate},
				[]*GridItemTemplate{nil, nil, SpikesTemplate},
				[]*GridItemTemplate{SpikesTemplate, SpikesTemplate, SpikesTemplate},
			},
			BlockTemplate{
				[]*GridItemTemplate{SpikesTemplate, nil, SpikesTemplate},
				[]*GridItemTemplate{SpikesTemplate, nil, nil},
				[]*GridItemTemplate{SpikesTemplate, SpikesTemplate, SpikesTemplate},
			},
			BlockTemplate{
				[]*GridItemTemplate{SpikesTemplate, SpikesTemplate, SpikesTemplate},
				[]*GridItemTemplate{SpikesTemplate, nil, nil},
				[]*GridItemTemplate{SpikesTemplate, nil, SpikesTemplate},
			},
		},
		Offset:     Ivec2{-1, -1},
		Range:      5.0,
		MaxTargets: 3,
		FearPerSec: 0.5,
		Cost:       100,
		Title:      "Spiketron 6000 GT",
	}

	ScaryBox = Block{
		Variants: []BlockTemplate{
			BlockTemplate{
				[]*GridItemTemplate{BoxTemplate},
			},
		},
		Offset:     Ivec2{0, 0},
		Range:      0.0,
		MaxTargets: 0,
		FearPerSec: 0.0,
		Cost:       50,
		Title:      "Scary?box",
	}
)

var (
	HudBlocks = []*Block{&SkellyBlock, &SpikesBlock, &CornerBlock, &ScaryBox}
)
<commit_msg>Make unscary box<commit_after>// Copyright 2015 Pikkpoiss
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package main

import ()

type BlockState int32

const (
	_                      = iota
	BlockNormal BlockState = 1 << iota
	BlockScaring
)

type BlockPlacement struct {
	Pos     Ivec2
	Block   *Block
	Variant int
}

type BlockAnimations map[BlockState][]int

var (
	SkeletonAnimations = BlockAnimations{
		BlockNormal:  []int{0},
		BlockScaring: []int{1, 2, 3, 4},
	}
	SkeletonTemplate = &GridItemTemplate{
		false,
		"skeleton01_%02v",
		SkeletonAnimations,
	}
)

var (
	SpikesAnimations = BlockAnimations{
		BlockNormal: []int{0},
		BlockScaring: []int{
			1,
			2, 2, 2, 2, 2, 2, 2, 2, 2,
			3, 3,
			4, 4,
			0, 0, 0, 0, 0, 0, 0, 0,
		},
	}
	SpikesTemplate = &GridItemTemplate{
		false,
		"spikes01_%02v",
		SpikesAnimations,
	}
)

var (
	BoxAnimations = BlockAnimations{
		BlockNormal:  []int{0},
		BlockScaring: []int{0},
	}
	BoxTemplate = &GridItemTemplate{
		false,
		"box01_%02v",
		BoxAnimations,
	}
)

type GridItemTemplate struct {
	Passable bool
	Frame    string
	Frames   BlockAnimations
}

type BlockTemplate [][]*GridItemTemplate

// TODO: Introduce a cooldown for scaring people.
type Block struct {
	Variants   []BlockTemplate
	Offset     Ivec2
	Range      float32 // Radius of effectiveness.
	MaxTargets int     // -1 for infinite.
	FearPerSec float64 // Amount of fear added to target per second.
	Cost       int
	Title      string
}

var (
	SkellyBlock = Block{
		Variants: []BlockTemplate{
			BlockTemplate{
				[]*GridItemTemplate{
					SkeletonTemplate,
				},
			},
		},
		Offset:     Ivec2{0, 0},
		Range:      1.5,
		MaxTargets: 1,
		FearPerSec: 2.0,
		Cost:       10,
		Title:      "Mr. Bones",
	}

	SpikesBlock = Block{
		Variants: []BlockTemplate{
			BlockTemplate{
				[]*GridItemTemplate{SpikesTemplate, SpikesTemplate, SpikesTemplate},
				[]*GridItemTemplate{nil, nil, nil},
				[]*GridItemTemplate{SpikesTemplate, SpikesTemplate, SpikesTemplate},
			},
			BlockTemplate{
				[]*GridItemTemplate{SpikesTemplate, nil, SpikesTemplate},
				[]*GridItemTemplate{SpikesTemplate, nil, SpikesTemplate},
				[]*GridItemTemplate{SpikesTemplate, nil, SpikesTemplate},
			},
		},
		Offset:     Ivec2{-1, -1},
		Range:      5.0,
		MaxTargets: 3,
		FearPerSec: 0.5,
		Cost:       100,
		Title:      "Spiketron 5000",
	}

	CornerBlock = Block{
		Variants: []BlockTemplate{
			BlockTemplate{
				[]*GridItemTemplate{SpikesTemplate, SpikesTemplate, SpikesTemplate},
				[]*GridItemTemplate{nil, nil, SpikesTemplate},
				[]*GridItemTemplate{SpikesTemplate, nil, SpikesTemplate},
			},
			BlockTemplate{
				[]*GridItemTemplate{SpikesTemplate, nil, SpikesTemplate},
				[]*GridItemTemplate{nil, nil, SpikesTemplate},
				[]*GridItemTemplate{SpikesTemplate, SpikesTemplate, SpikesTemplate},
			},
			BlockTemplate{
				[]*GridItemTemplate{SpikesTemplate, nil, SpikesTemplate},
				[]*GridItemTemplate{SpikesTemplate, nil, nil},
				[]*GridItemTemplate{SpikesTemplate, SpikesTemplate, SpikesTemplate},
			},
			BlockTemplate{
				[]*GridItemTemplate{SpikesTemplate, SpikesTemplate, SpikesTemplate},
				[]*GridItemTemplate{SpikesTemplate, nil, nil},
				[]*GridItemTemplate{SpikesTemplate, nil, SpikesTemplate},
			},
		},
		Offset:     Ivec2{-1, -1},
		Range:      5.0,
		MaxTargets: 3,
		FearPerSec: 0.5,
		Cost:       100,
		Title:      "Spiketron 6000 GT",
	}

	ScaryBox = Block{
		Variants: []BlockTemplate{
			BlockTemplate{
				[]*GridItemTemplate{BoxTemplate},
			},
		},
		Offset:     Ivec2{0, 0},
		Range:      1.5,
		MaxTargets: 1,
		FearPerSec: -2.0,
		Cost:       50,
		Title:      "Unscarybox",
	}
)

var (
	HudBlocks = []*Block{&SkellyBlock, &SpikesBlock, &CornerBlock, &ScaryBox}
)
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"encoding/json"
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"path/filepath"
	"strings"
	"time"
)

const (
	userAgent   = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36"
	timeLayout  = "02/01/2006"
	storagePath = ".local/share"
)

func main() {
	flag.Parse()

	currencies, err := GetCurrencies(flag.Args()...)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Println(prettyPrint(currencies...))
}

func GetCurrencies(codes ...string) ([]Currency, error) {
	c := &http.Client{Timeout: 10 * time.Second}

	const baseurl = "https://www.doviz.com/api/v1/currencies/all/latest"

	resp, err := c.Get(baseurl)
	if err != nil {
		return nil, fmt.Errorf("could not fetch currencies: %v", err)
	}
	defer resp.Body.Close()

	var currencies []Currency
	if err := json.NewDecoder(resp.Body).Decode(&currencies); err != nil {
		return nil, fmt.Errorf("could not decode json: %v", err)
	}

	if len(codes) == 0 {
		return currencies, nil
	}

	var selection []Currency
	for _, curr := range currencies {
		currcode := strings.ToLower(curr.Code)
		for _, code := range codes {
			code = strings.ToLower(code)
			if currcode == code {
				selection = append(selection, curr)
			}
		}

	}
	return selection, nil
}

type Currency struct {
	Selling    float64 `json:"selling"`
	UpdateDate float64 `json:"update_date"`
	Currency   int     `json:"currency"`
	Buying     float64 `json:"buying"`
	ChangeRate float64 `json:"change_rate"`
	Name       string  `json:"name"`
	FullName   string  `json:"full_name"`
	Code       string  `json:"code"`
}

func prettyPrint(currencies ...Currency) string {
	const (
		boldblack = "\x1b[30m"
		black     = "\x1b[1;30m"
		red       = "\x1b[35m"
		green     = "\x1b[32m"
		reset     = "\x1b[0m"
	)
	color := func(f float64) string {
		switch {
		case f < 0:
			return "red"
		case f > 0:
			return "green"
		default:
			return "black"
		}
	}

	var buf bytes.Buffer

	for _, c := range currencies {
		code := strings.ToUpper(c.Code)

		sethop(code, time.Now(), c.ChangeRate)

		// calculate the fall
		hop := gethop(code)
		var freefall string
		for _, h := range hop {
			if h.DailyChange < 0 {
				freefall += "◉ "
			} else {
				freefall = ""
			}
		}

		fmt.Fprintf(&buf, "%v <%.1f%%> \x1b[31;1;8m%v\x1b[0m | size=13 color=%v href=href=https://tr.investing.com/currencies/%v-try-commentary\n", code, c.ChangeRate, freefall, color(c.ChangeRate), code)
		fmt.Fprintf(&buf, "• Sell: %.4f | size=11 color=black\n", c.Selling)
		fmt.Fprintf(&buf, "• Buy: %.4f | size=11 color=black\n", c.Buying)
		fmt.Fprintf(&buf, "---\n")
	}
	return buf.String()
}

func sethop(code string, date time.Time, change float64) {
	home := os.Getenv("HOME")
	path := filepath.Join(home, storagePath)
	os.MkdirAll(path, 0755)
	fpath := filepath.Join(path, "currency.json")

	_, err := os.Stat(fpath)
	if os.IsNotExist(err) {
		ioutil.WriteFile(fpath, []byte("{}"), 0644)
	}

	allhops := gethops()

	datestr := date.Format(timeLayout)
	hop := Hop{Date: datestr, DailyChange: change}

	hops, ok := allhops[code]
	if !ok {
		hops = []Hop{hop}
	} else {
		var found bool
		for _, h := range hops {
			if h.Date == datestr {
				found = true
				break
			}
		}
		if !found {
			hops = append(hops, hop)
		}
	}

	// limit the size of the slice to 3
	if len(hops) >= 3 {
		hops = hops[len(hops)-3 : len(hops)]
	}

	allhops[code] = hops

	b, _ := json.Marshal(allhops)
	_ = ioutil.WriteFile(fpath, b, 0644)
}

func gethops() map[string][]Hop {
	home := os.Getenv("HOME")
	path := filepath.Join(home, storagePath)
	os.MkdirAll(path, 0755)
	fpath := filepath.Join(path, "currency.json")

	m := make(map[string][]Hop)

	content, _ := ioutil.ReadFile(fpath)
	_ = json.Unmarshal(content, &m)

	return m
}

func gethop(code string) []Hop {
	all := gethops()
	v, _ := all[code]
	return v
}

type Hop struct {
	Date        string
	DailyChange float64
}
<commit_msg>cnrrency: fix href<commit_after>package main

import (
	"bytes"
	"encoding/json"
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"path/filepath"
	"strings"
	"time"
)

const (
	userAgent   = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36"
	timeLayout  = "02/01/2006"
	storagePath = ".local/share"
)

func main() {
	flag.Parse()

	currencies, err := GetCurrencies(flag.Args()...)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Println(prettyPrint(currencies...))
}

func GetCurrencies(codes ...string) ([]Currency, error) {
	c := &http.Client{Timeout: 10 * time.Second}

	const baseurl = "https://www.doviz.com/api/v1/currencies/all/latest"

	resp, err := c.Get(baseurl)
	if err != nil {
		return nil, fmt.Errorf("could not fetch currencies: %v", err)
	}
	defer resp.Body.Close()

	var currencies []Currency
	if err := json.NewDecoder(resp.Body).Decode(&currencies); err != nil {
		return nil, fmt.Errorf("could not decode json: %v", err)
	}

	if len(codes) == 0 {
		return currencies, nil
	}

	var selection []Currency
	for _, curr := range currencies {
		currcode := strings.ToLower(curr.Code)
		for _, code := range codes {
			code = strings.ToLower(code)
			if currcode == code {
				selection = append(selection, curr)
			}
		}

	}
	return selection, nil
}

type Currency struct {
	Selling    float64 `json:"selling"`
	UpdateDate float64 `json:"update_date"`
	Currency   int     `json:"currency"`
	Buying     float64 `json:"buying"`
	ChangeRate float64 `json:"change_rate"`
	Name       string  `json:"name"`
	FullName   string  `json:"full_name"`
	Code       string  `json:"code"`
}

func prettyPrint(currencies ...Currency) string {
	const (
		boldblack = "\x1b[30m"
		black     = "\x1b[1;30m"
		red       = "\x1b[35m"
		green     = "\x1b[32m"
		reset     = "\x1b[0m"
	)
	color := func(f float64) string {
		switch {
		case f < 0:
			return "red"
		case f > 0:
			return "green"
		default:
			return "black"
		}
	}

	var buf bytes.Buffer

	for _, c := range currencies {
		code := strings.ToUpper(c.Code)

		sethop(code, time.Now(), c.ChangeRate)

		// calculate the fall
		hop := gethop(code)
		var freefall string
		for _, h := range hop {
			if h.DailyChange < 0 {
				freefall += "◉ "
			} else {
				freefall = ""
			}
		}

		fmt.Fprintf(&buf, "%v <%.2f%%> \x1b[31;1;8m%v\x1b[0m | size=13 color=%v href=https://tr.investing.com/currencies/%v-try-commentary\n", code, c.ChangeRate, freefall, color(c.ChangeRate), strings.ToLower(code))
		fmt.Fprintf(&buf, "• Sell: %.4f | size=11 color=black\n", c.Selling)
		fmt.Fprintf(&buf, "• Buy: %.4f | size=11 color=black\n", c.Buying)
		fmt.Fprintf(&buf, "---\n")
	}
	return buf.String()
}

func sethop(code string, date time.Time, change float64) {
	home := os.Getenv("HOME")
	path := filepath.Join(home, storagePath)
	os.MkdirAll(path, 0755)
	fpath := filepath.Join(path, "currency.json")

	_, err := os.Stat(fpath)
	if os.IsNotExist(err) {
		ioutil.WriteFile(fpath, []byte("{}"), 0644)
	}

	allhops := gethops()

	datestr := date.Format(timeLayout)
	hop := Hop{Date: datestr, DailyChange: change}

	hops, ok := allhops[code]
	if !ok {
		hops = []Hop{hop}
	} else {
		var found bool
		for _, h := range hops {
			if h.Date == datestr {
				found = true
				break
			}
		}
		if !found {
			hops = append(hops, hop)
		}
	}

	// limit the size of the slice to 3
	if len(hops) >= 3 {
		hops = hops[len(hops)-3 : len(hops)]
	}

	allhops[code] = hops

	b, _ := json.Marshal(allhops)
	_ = ioutil.WriteFile(fpath, b, 0644)
}

func gethops() map[string][]Hop {
	home := os.Getenv("HOME")
	path := filepath.Join(home, storagePath)
	os.MkdirAll(path, 0755)
	fpath := filepath.Join(path, "currency.json")

	m := make(map[string][]Hop)

	content, _ := ioutil.ReadFile(fpath)
	_ = json.Unmarshal(content, &m)

	return m
}

func gethop(code string) []Hop {
	all := gethops()
	v, _ := all[code]
	return v
}

type Hop struct {
	Date        string
	DailyChange float64
}
<|endoftext|>


<commit_before>package daemon

import (
    "os"
    "fmt"
    "github.com/sevlyar/go-daemon"
    "github.com/Sirupsen/logrus"
    "github.com/BluePecker/JwtAuth/pkg/storage"
    "github.com/BluePecker/JwtAuth/daemon/server"
    "syscall"
    "log"
)

const (
    TOKEN_TTL = 2 * 3600

    VERSION = "1.0.0"

    ALLOW_LOGIN_NUM = 3
)

type Storage struct {
    Driver string
    Opts   string
}

type TLS struct {
    Key  string
    Cert string
}

type Options struct {
    PidFile  string
    LogFile  string
    LogLevel string
    Port     int
    Host     string
    SockFile string
    Daemon   bool
    Version  bool
    TLS      TLS
    Storage  Storage
    Secret   string
}

type Daemon struct {
    Options  *Options

    shadow   *server.Shadow
    rosiness *server.Rosiness

    StorageE *storage.Engine
}

func Logger(level string) {
    logrus.SetFormatter(&logrus.TextFormatter{
        TimestampFormat: "2006-01-02 15:04:05",
    })
    Level, err := logrus.ParseLevel(level)
    if err != nil {
        logrus.Error(err)
        os.Exit(0)
    }
    logrus.SetLevel(Level)
}

func Version(version bool) {
    if version == true {
        fmt.Printf("JwtAuth version %s.\n", VERSION)
        os.Exit(0)
    }
}

func NewDaemon(background bool, args Options) *Daemon {
    if background {
        ctx := daemon.Context{
            PidFileName: args.PidFile,
            PidFilePerm: 0644,
            LogFilePerm: 0640,
            Umask:       027,
            WorkDir:     "/",
            LogFileName: args.LogFile,
        }
        if process, err := ctx.Reborn(); err == nil {

            log.Println(args.PidFile, process, err)

            defer ctx.Release()
            if process != nil {
                return nil
            }
        } else {
            if err == daemon.ErrWouldBlock {
                logrus.Error("daemon already exists.")
            } else {
                logrus.Errorf("Unable to run: ", err)
            }
            os.Exit(0)
        }
    }
    return &Daemon{Options: &args}
}

func NewStart(args Options) {

    Logger(args.LogLevel)
    Version(args.Version)

    if args.Secret == "" {
        fmt.Println("please specify secret for jwt encode.")
        os.Exit(0)
    }

    if progress := NewDaemon(args.Daemon, args); progress == nil {
        return
    } else {
        if err := progress.Storage(); err != nil {
            logrus.Error(err)
            os.Exit(0)
        }

        quit := make(chan struct{})
        go progress.Shadow(quit)
        go func() {
            go progress.Rosiness(quit)
            defer logrus.Infof("now listening on: http://%s:%d", args.Host, args.Port)
        }()
        daemon.SetSigHandler(func(sig os.Signal) error {
            close(quit)
            return daemon.ErrStop
        }, syscall.SIGTERM, syscall.SIGQUIT)

        if err := daemon.ServeSignals(); err != nil {
            logrus.Error(err)
        }
        logrus.Error("jwt daemon terminated.")
    }
}<commit_msg>debug<commit_after>package daemon

import (
    "os"
    "fmt"
    "github.com/sevlyar/go-daemon"
    "github.com/Sirupsen/logrus"
    "github.com/BluePecker/JwtAuth/pkg/storage"
    "github.com/BluePecker/JwtAuth/daemon/server"
    "syscall"
    "log"
)

const (
    TOKEN_TTL = 2 * 3600

    VERSION = "1.0.0"

    ALLOW_LOGIN_NUM = 3
)

type Storage struct {
    Driver string
    Opts   string
}

type TLS struct {
    Key  string
    Cert string
}

type Options struct {
    PidFile  string
    LogFile  string
    LogLevel string
    Port     int
    Host     string
    SockFile string
    Daemon   bool
    Version  bool
    TLS      TLS
    Storage  Storage
    Secret   string
}

type Daemon struct {
    Options  *Options

    shadow   *server.Shadow
    rosiness *server.Rosiness

    StorageE *storage.Engine
}

func Logger(level string) {
    logrus.SetFormatter(&logrus.TextFormatter{
        TimestampFormat: "2006-01-02 15:04:05",
    })
    Level, err := logrus.ParseLevel(level)
    if err != nil {
        logrus.Error(err)
        os.Exit(0)
    }
    logrus.SetLevel(Level)
}

func Version(version bool) {
    if version == true {
        fmt.Printf("JwtAuth version %s.\n", VERSION)
        os.Exit(0)
    }
}

func NewDaemon(background bool, args Options) *Daemon {
    if background {
        ctx := &daemon.Context{
            PidFileName: args.PidFile,
            PidFilePerm: 0644,
            LogFilePerm: 0640,
            Umask:       027,
            WorkDir:     "/",
            LogFileName: args.LogFile,
        }
        if process, err := ctx.Reborn(); err == nil {

            log.Println(args.PidFile, process, err)

            defer ctx.Release()
            if process != nil {
                return nil
            }
        } else {
            if err == daemon.ErrWouldBlock {
                logrus.Error("daemon already exists.")
            } else {
                logrus.Errorf("Unable to run: ", err)
            }
            os.Exit(0)
        }
    }
    return &Daemon{Options: &args}
}

func NewStart(args Options) {

    Logger(args.LogLevel)
    Version(args.Version)

    if args.Secret == "" {
        fmt.Println("please specify secret for jwt encode.")
        os.Exit(0)
    }

    if progress := NewDaemon(args.Daemon, args); progress == nil {
        return
    } else {
        if err := progress.Storage(); err != nil {
            logrus.Error(err)
            os.Exit(0)
        }

        quit := make(chan struct{})
        go progress.Shadow(quit)
        go func() {
            go progress.Rosiness(quit)
            defer logrus.Infof("now listening on: http://%s:%d", args.Host, args.Port)
        }()
        daemon.SetSigHandler(func(sig os.Signal) error {
            close(quit)
            return daemon.ErrStop
        }, syscall.SIGTERM, syscall.SIGQUIT)

        if err := daemon.ServeSignals(); err != nil {
            logrus.Error(err)
        }
        logrus.Error("jwt daemon terminated.")
    }
}<|endoftext|>


<commit_before>package rpc

import (
	"encoding/json"
	"io"
	"log"
	"net"
	"os"

	"github.com/nsf/termbox-go"
)

type jsonMessage struct {
	ID       string
	Status   string
	Progress string
}

func showProgress(c net.Conn) {
	if err := termbox.Init(); err != nil {
		io.Copy(os.Stdout, c)
		return
	}
	defer termbox.Close()

	var ids []string
	progress := make(map[string]string)
	dec := json.NewDecoder(c)
	for {
		var msg jsonMessage
		if err := dec.Decode(&msg); err != nil {
			if err != io.EOF {
				log.Print(err)
			}
			return
		}
		if _, ok := progress[msg.ID]; !ok {
			ids = append(ids, msg.ID)
		}
		progress[msg.ID] = msg.Status + " " + msg.Progress

		termbox.Clear(termbox.ColorDefault, termbox.ColorDefault)
		for y, id := range ids {
			msg := id + " " + progress[id]
			for x := 0; x < len(msg); x++ {
				termbox.SetCell(x, y, rune(msg[x]), termbox.ColorDefault, termbox.ColorDefault)
			}
		}
		termbox.Flush()
	}
}
<commit_msg>Don't start termbox when pulling is not needed<commit_after>package rpc

import (
	"encoding/json"
	"fmt"
	"io"
	"log"
	"net"

	"github.com/nsf/termbox-go"
)

type jsonMessage struct {
	ID       string
	Status   string
	Progress string
}

func showProgress(c net.Conn) {
	var ids []string
	progress := make(map[string]string)
	update := func(msg *jsonMessage) {
		if _, ok := progress[msg.ID]; !ok {
			ids = append(ids, msg.ID)
		}
		progress[msg.ID] = msg.Status + " " + msg.Progress

		termbox.Clear(termbox.ColorDefault, termbox.ColorDefault)
		for y, id := range ids {
			msg := id + " " + progress[id]
			for x := 0; x < len(msg); x++ {
				termbox.SetCell(x, y, rune(msg[x]), termbox.ColorDefault, termbox.ColorDefault)
			}
		}
		termbox.Flush()
	}

	first := true
	dec := json.NewDecoder(c)
	for {
		var msg jsonMessage
		if err := dec.Decode(&msg); err != nil {
			if err != io.EOF {
				log.Print(err)
			}
			return
		}
		if first {
			first = false
			if err := termbox.Init(); err == nil {
				defer termbox.Close()
			} else {
				update = func(msg *jsonMessage) {
					fmt.Fprintln(c, msg.Progress)
				}
			}
		}
		update(&msg)
	}
}
<|endoftext|>


<commit_before>package gocassa

import (
	"bytes"
	"encoding/json"
	"fmt"
	"runtime"
	"strconv"
)

const (
	readOpType uint8 = iota
	singleReadOpType
	deleteOpType
	updateOpType
	insertOpType
)

type singleOp struct {
	options Options
	f       filter
	opType  uint8
	result  interface{}
	m       map[string]interface{} // map for updates, sets etc
	qe      QueryExecutor
}

func (o *singleOp) WithOptions(opts Options) Op {
	return &singleOp{
		options: o.options.Merge(opts),
		f:       o.f,
		opType:  o.opType,
		result:  o.result,
		m:       o.m,
		qe:      o.qe}
}

func (o *singleOp) Add(additions ...Op) Op {
	return multiOp{o}.Add(additions...)
}

func (o *singleOp) Preflight() error {
	return nil
}

func newWriteOp(qe QueryExecutor, f filter, opType uint8, m map[string]interface{}) *singleOp {
	return &singleOp{
		qe:     qe,
		f:      f,
		opType: opType,
		m:      m}
}

func (w *singleOp) read() error {
	stmt, params := w.generateRead(w.options)
	maps, err := w.qe.Query(stmt, params...)
	if err != nil {
		return err
	}
	bytes, err := json.Marshal(maps)
	if err != nil {
		return err
	}
	return json.Unmarshal(bytes, w.result)
}

func (w *singleOp) readOne() error {
	stmt, params := w.generateRead(w.options)
	maps, err := w.qe.Query(stmt, params...)
	if err != nil {
		return err
	}
	if len(maps) == 0 {
		_, f, n, _ := runtime.Caller(3)
		return RowNotFoundError{
			file: f,
			line: n,
		}
	}
	bytes, err := json.Marshal(maps[0])
	if err != nil {
		return err
	}
	return json.Unmarshal(bytes, w.result)
}

func (w *singleOp) write() error {
	stmt, params := w.generateWrite(w.options)
	return w.qe.Execute(stmt, params...)
}

func (o *singleOp) Run() error {
	switch o.opType {
	case updateOpType, insertOpType, deleteOpType:
		return o.write()
	case readOpType:
		return o.read()
	case singleReadOpType:
		return o.readOne()
	}
	return nil
}

func (o *singleOp) RunAtomically() error {
	return o.Run()
}

func (o *singleOp) GenerateStatement() (string, []interface{}) {
	switch o.opType {
	case updateOpType, insertOpType, deleteOpType:
		return o.generateWrite(o.options)
	case readOpType, singleReadOpType:
		return o.generateRead(o.options)
	}
	return "", []interface{}{}
}

func (o *singleOp) QueryExecutor() QueryExecutor {
	return o.qe
}

func (o *singleOp) generateWrite(opt Options) (string, []interface{}) {
	var str string
	var vals []interface{}
	switch o.opType {
	case updateOpType:
		stmt, uvals := updateStatement(o.f.t.keySpace.name, o.f.t.Name(), o.m, o.f.t.options.Merge(opt))
		whereStmt, whereVals := generateWhere(o.f.rs)
		str = stmt + whereStmt
		vals = append(uvals, whereVals...)
	case deleteOpType:
		str, vals = generateWhere(o.f.rs)
		str = fmt.Sprintf("DELETE FROM %s.%s%s", o.f.t.keySpace.name, o.f.t.Name(), str)
	case insertOpType:
		fields, insertVals := keyValues(o.m)
		str = insertStatement(o.f.t.keySpace.name, o.f.t.Name(), fields, o.f.t.options.Merge(opt))
		vals = insertVals
	}
	if o.f.t.keySpace.debugMode {
		fmt.Println(str, vals)
	}
	return str, vals
}

func (o *singleOp) generateRead(opt Options) (string, []interface{}) {
	w, wv := generateWhere(o.f.rs)
	ord, ov := o.generateOrderBy()
	lim, lv := o.generateLimit(o.f.t.options.Merge(opt))
	stmt := fmt.Sprintf("SELECT %s FROM %s.%s", o.f.t.generateFieldNames(), o.f.t.keySpace.name, o.f.t.Name())
	vals := []interface{}{}
	buf := new(bytes.Buffer)
	buf.WriteString(stmt)
	if w != "" {
		buf.WriteString(" ")
		buf.WriteString(w)
		vals = append(vals, wv...)
	}
	if ord != "" {
		buf.WriteString(" ")
		buf.WriteString(ord)
		vals = append(vals, ov...)
	}
	if lim != "" {
		buf.WriteString(" ")
		buf.WriteString(lim)
		vals = append(vals, lv...)
	}
	if o.f.t.keySpace.debugMode {
		fmt.Println(buf.String(), vals)
	}
	return buf.String(), vals
}

func (o *singleOp) generateOrderBy() (string, []interface{}) {
	return "", []interface{}{}
	// " ORDER BY %v"
}

func (o *singleOp) generateLimit(opt Options) (string, []interface{}) {
	if opt.Limit < 1 {
		return "", []interface{}{}
	}
	return "LIMIT ?", []interface{}{opt.Limit}
}

func generateWhere(rs []Relation) (string, []interface{}) {
	var (
		vals []interface{}
		buf  = new(bytes.Buffer)
	)

	if len(rs) > 0 {
		buf.WriteString(" WHERE ")
		for i, r := range rs {
			if i > 0 {
				buf.WriteString(" AND ")
			}
			s, v := r.cql()
			buf.WriteString(s)
			vals = append(vals, v...)
		}
	}
	return buf.String(), vals
}

// UPDATE keyspace.Movies SET col1 = val1, col2 = val2
func updateStatement(kn, cfName string, fields map[string]interface{}, opts Options) (string, []interface{}) {
	buf := new(bytes.Buffer)
	buf.WriteString(fmt.Sprintf("UPDATE %s.%s ", kn, cfName))

	// Apply options
	if opts.TTL != 0 {
		buf.WriteString("USING TTL ")
		buf.WriteString(strconv.FormatFloat(opts.TTL.Seconds(), 'f', 0, 64))
		buf.WriteRune(' ')
	}

	buf.WriteString("SET ")
	i := 0
	ret := []interface{}{}
	for k, v := range fields {
		if i > 0 {
			buf.WriteString(", ")
		}
		if mod, ok := v.(Modifier); ok {
			stmt, vals := mod.cql(k)
			buf.WriteString(stmt)
			ret = append(ret, vals...)
		} else {
			buf.WriteString(k + " = ?")
			ret = append(ret, v)
		}
		i++
	}

	return buf.String(), ret
}
<commit_msg>Support clustering order<commit_after>package gocassa

import (
	"bytes"
	"encoding/json"
	"fmt"
	"runtime"
	"strconv"
)

const (
	readOpType uint8 = iota
	singleReadOpType
	deleteOpType
	updateOpType
	insertOpType
)

type singleOp struct {
	options Options
	f       filter
	opType  uint8
	result  interface{}
	m       map[string]interface{} // map for updates, sets etc
	qe      QueryExecutor
}

func (o *singleOp) WithOptions(opts Options) Op {
	return &singleOp{
		options: o.options.Merge(opts),
		f:       o.f,
		opType:  o.opType,
		result:  o.result,
		m:       o.m,
		qe:      o.qe}
}

func (o *singleOp) Add(additions ...Op) Op {
	return multiOp{o}.Add(additions...)
}

func (o *singleOp) Preflight() error {
	return nil
}

func newWriteOp(qe QueryExecutor, f filter, opType uint8, m map[string]interface{}) *singleOp {
	return &singleOp{
		qe:     qe,
		f:      f,
		opType: opType,
		m:      m}
}

func (w *singleOp) read() error {
	stmt, params := w.generateRead(w.options)
	maps, err := w.qe.Query(stmt, params...)
	if err != nil {
		return err
	}
	bytes, err := json.Marshal(maps)
	if err != nil {
		return err
	}
	return json.Unmarshal(bytes, w.result)
}

func (w *singleOp) readOne() error {
	stmt, params := w.generateRead(w.options)
	maps, err := w.qe.Query(stmt, params...)
	if err != nil {
		return err
	}
	if len(maps) == 0 {
		_, f, n, _ := runtime.Caller(3)
		return RowNotFoundError{
			file: f,
			line: n,
		}
	}
	bytes, err := json.Marshal(maps[0])
	if err != nil {
		return err
	}
	return json.Unmarshal(bytes, w.result)
}

func (w *singleOp) write() error {
	stmt, params := w.generateWrite(w.options)
	return w.qe.Execute(stmt, params...)
}

func (o *singleOp) Run() error {
	switch o.opType {
	case updateOpType, insertOpType, deleteOpType:
		return o.write()
	case readOpType:
		return o.read()
	case singleReadOpType:
		return o.readOne()
	}
	return nil
}

func (o *singleOp) RunAtomically() error {
	return o.Run()
}

func (o *singleOp) GenerateStatement() (string, []interface{}) {
	switch o.opType {
	case updateOpType, insertOpType, deleteOpType:
		return o.generateWrite(o.options)
	case readOpType, singleReadOpType:
		return o.generateRead(o.options)
	}
	return "", []interface{}{}
}

func (o *singleOp) QueryExecutor() QueryExecutor {
	return o.qe
}

func (o *singleOp) generateWrite(opt Options) (string, []interface{}) {
	var str string
	var vals []interface{}
	switch o.opType {
	case updateOpType:
		stmt, uvals := updateStatement(o.f.t.keySpace.name, o.f.t.Name(), o.m, o.f.t.options.Merge(opt))
		whereStmt, whereVals := generateWhere(o.f.rs)
		str = stmt + whereStmt
		vals = append(uvals, whereVals...)
	case deleteOpType:
		str, vals = generateWhere(o.f.rs)
		str = fmt.Sprintf("DELETE FROM %s.%s%s", o.f.t.keySpace.name, o.f.t.Name(), str)
	case insertOpType:
		fields, insertVals := keyValues(o.m)
		str = insertStatement(o.f.t.keySpace.name, o.f.t.Name(), fields, o.f.t.options.Merge(opt))
		vals = insertVals
	}
	if o.f.t.keySpace.debugMode {
		fmt.Println(str, vals)
	}
	return str, vals
}

func (o *singleOp) generateRead(opt Options) (string, []interface{}) {
	w, wv := generateWhere(o.f.rs)
	ord, ov := o.generateOrderBy()
	lim, lv := o.generateLimit(o.f.t.options.Merge(opt))
	stmt := fmt.Sprintf("SELECT %s FROM %s.%s", o.f.t.generateFieldNames(), o.f.t.keySpace.name, o.f.t.Name())
	vals := []interface{}{}
	buf := new(bytes.Buffer)
	buf.WriteString(stmt)
	if w != "" {
		buf.WriteRune(' ')
		buf.WriteString(w)
		vals = append(vals, wv...)
	}
	if ord != "" {
		buf.WriteRune(' ')
		buf.WriteString(ord)
		vals = append(vals, ov...)
	}
	if lim != "" {
		buf.WriteRune(' ')
		buf.WriteString(lim)
		vals = append(vals, lv...)
	}
	if o.f.t.keySpace.debugMode {
		fmt.Println(buf.String(), vals)
	}
	return buf.String(), vals
}

func (o *singleOp) generateOrderBy() (string, []interface{}) {
	buf := new(bytes.Buffer)
	for i, ord := range o.options.ClusteringOrder {
		if i == 0 {
			buf.WriteString("ORDER BY ")
		} else {
			buf.WriteString(", ")
		}
		buf.WriteString(ord.Column)
		if ord.Direction == DESC {
			buf.WriteString(" DESC")
		}
	}
	return buf.String(), []interface{}{}
}

func (o *singleOp) generateLimit(opt Options) (string, []interface{}) {
	if opt.Limit < 1 {
		return "", []interface{}{}
	}
	return "LIMIT ?", []interface{}{opt.Limit}
}

func generateWhere(rs []Relation) (string, []interface{}) {
	var (
		vals []interface{}
		buf  = new(bytes.Buffer)
	)

	if len(rs) > 0 {
		buf.WriteString(" WHERE ")
		for i, r := range rs {
			if i > 0 {
				buf.WriteString(" AND ")
			}
			s, v := r.cql()
			buf.WriteString(s)
			vals = append(vals, v...)
		}
	}
	return buf.String(), vals
}

// UPDATE keyspace.Movies SET col1 = val1, col2 = val2
func updateStatement(kn, cfName string, fields map[string]interface{}, opts Options) (string, []interface{}) {
	buf := new(bytes.Buffer)
	buf.WriteString(fmt.Sprintf("UPDATE %s.%s ", kn, cfName))

	// Apply options
	if opts.TTL != 0 {
		buf.WriteString("USING TTL ")
		buf.WriteString(strconv.FormatFloat(opts.TTL.Seconds(), 'f', 0, 64))
		buf.WriteRune(' ')
	}

	buf.WriteString("SET ")
	i := 0
	ret := []interface{}{}
	for k, v := range fields {
		if i > 0 {
			buf.WriteString(", ")
		}
		if mod, ok := v.(Modifier); ok {
			stmt, vals := mod.cql(k)
			buf.WriteString(stmt)
			ret = append(ret, vals...)
		} else {
			buf.WriteString(k + " = ?")
			ret = append(ret, v)
		}
		i++
	}

	return buf.String(), ret
}
<|endoftext|>


<commit_before>// Copyright (c) 2015, Ben Morgan. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package osutil

import (
	"bytes"
	"crypto/md5"
	"io"
	"os"
)

// CopyFile tries to copy src to dst. If dst already exists, it will be
// overwritten. If it does not exist, it will be created.
func CopyFile(src, dst string) (err error) {
	// Make sure that both files are regular.
	if _, err = FileExists(src); err != nil {
		return
	}
	if _, err = FileExists(dst); err != nil {
		return
	}

	in, err := os.Open(src)
	if err != nil {
		return
	}
	defer in.Close()

	out, err := os.Create(dst)
	if err != nil {
		return
	}
	defer func() {
		cerr := out.Close()
		if err == nil {
			err = cerr
		}
	}()
	if _, err = io.Copy(out, in); err != nil {
		return
	}
	err = out.Sync()
	return
}

// MoveFile tries to move src to dst. If dst already exists, it will be
// overwritten.
func MoveFile(src, dst string) error {
	// Make sure that both files are regular.
	if _, err := FileExists(src); err != nil {
		return err
	}
	if _, err := FileExists(dst); err != nil {
		return err
	}

	err := os.Rename(src, dst)
	if err != nil {
		err := CopyFile(src, dst)
		if err != nil {
			return err
		}
		return os.Remove(src)
	}

	return nil
}

// MoveFileLazy is the same as MoveFile, except that it avoids copying
// the file when the destination already has the same contents.
func MoveFileLazy(src, dst string) error {
	same, err := SameContents(src, dst)
	if err != nil {
		return err
	}
	if same {
		return os.Remove(src)
	}
	return MoveFile(src, dst)
}

// CopyFileLazy is the same as CopyFile, except that it avoids copying
// the file when the destination already has the same contents.
func CopyFileLazy(src, dst string) error {
	same, err := SameContents(src, dst)
	if err != nil {
		return err
	}
	if same {
		return nil
	}
	return CopyFile(src, dst)
}

// SameContents returns same = true if src and dst both exist and have the
// same file contents. Whether the file data is at the same place on
// disk is a different question, which is not answered.
//
// If either file is a directory, FileTypeError is returned.
func SameContents(src, dst string) (same bool, err error) {
	same, err = SameFile(src, dst)
	if err != nil {
		return same, err
	}

	// TODO: I could make this more efficient, based on the file size.
	ssum, err := sumFile(src)
	if err != nil {
		return false, err
	}
	dsum, err := sumFile(dst)
	if err != nil {
		return false, err
	}
	return bytes.Compare(ssum, dsum) == 0, nil
}

// sumFile creates an md5sum of a file
func sumFile(path string) (sum []byte, err error) {
	h := md5.New()
	f, err := os.Open(path)
	if err != nil {
		return sum, err
	}
	io.Copy(h, f)
	return h.Sum(nil), nil
}

func SameFile(src, dst string) (same bool, err error) {
	fs, err := os.Stat(src)
	if err != nil {
		return false, err
	}
	if fs.IsDir() {
		return false, FileTypeError{src}
	}

	fd, err := os.Stat(dst)
	if err != nil {
		if os.IsNotExist(err) {
			return false, nil
		}
		return false, err
	}
	if fd.IsDir() {
		return false, FileTypeError{dst}
	}

	return os.SameFile(fs, fd), nil
}

// Exists returns ex = true if the given file exists, regardless whether
// it is a file or a directory. Normally you will probably want to use the more
// specific versions: FileExists and DirectoryExists.
func Exists(path string) (ex bool, err error) {
	ex, _, err = exists(path)
	return ex, err
}

// FileExists returns ex = true if the file exists and is not
// a directory, and returns err != nil if any other error occured (such as
// permission denied).
func FileExists(path string) (ex bool, err error) {
	var stat os.FileInfo

	ex, stat, err = exists(path)
	if err == nil && stat.IsDir() {
		return false, FileTypeError{path}
	}
	return ex, err
}

// DirExists returns ex = true if the file exists and is
// a directory, and returns err != nil if any other error occured (such as
// permission denied).
func DirExists(path string) (ex bool, err error) {
	var stat os.FileInfo

	ex, stat, err = exists(path)
	if err == nil && !stat.IsDir() {
		return false, FileTypeError{path}
	}
	return ex, err
}

// exists does the hard work for Exists, FileExists, and DirExists,
// returning ex = true if the file given by path exists.
func exists(path string) (ex bool, stat os.FileInfo, err error) {
	stat, err = os.Stat(path)

	ex = true
	if err != nil {
		// ex = true if file exists
		ex = !os.IsNotExist(err)
		if !ex {
			err = nil
		}
	}
	return ex, stat, err
}
<commit_msg>Bugfix: same problem as last<commit_after>// Copyright (c) 2015, Ben Morgan. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package osutil

import (
	"bytes"
	"crypto/md5"
	"io"
	"os"
)

// CopyFile tries to copy src to dst. If dst already exists, it will be
// overwritten. If it does not exist, it will be created.
func CopyFile(src, dst string) (err error) {
	// Make sure that both files are regular.
	if _, err = FileExists(src); err != nil {
		return
	}
	if _, err = FileExists(dst); err != nil {
		return
	}

	in, err := os.Open(src)
	if err != nil {
		return
	}
	defer in.Close()

	out, err := os.Create(dst)
	if err != nil {
		return
	}
	defer func() {
		cerr := out.Close()
		if err == nil {
			err = cerr
		}
	}()
	if _, err = io.Copy(out, in); err != nil {
		return
	}
	err = out.Sync()
	return
}

// MoveFile tries to move src to dst. If dst already exists, it will be
// overwritten.
func MoveFile(src, dst string) error {
	// Make sure that both files are regular.
	if _, err := FileExists(src); err != nil {
		return err
	}
	if _, err := FileExists(dst); err != nil {
		return err
	}

	err := os.Rename(src, dst)
	if err != nil {
		err := CopyFile(src, dst)
		if err != nil {
			return err
		}
		return os.Remove(src)
	}

	return nil
}

// MoveFileLazy is the same as MoveFile, except that it avoids copying
// the file when the destination already has the same contents.
func MoveFileLazy(src, dst string) error {
	same, err := SameContents(src, dst)
	if err != nil {
		return err
	}
	if same {
		return os.Remove(src)
	}
	return MoveFile(src, dst)
}

// CopyFileLazy is the same as CopyFile, except that it avoids copying
// the file when the destination already has the same contents.
func CopyFileLazy(src, dst string) error {
	same, err := SameContents(src, dst)
	if err != nil {
		return err
	}
	if same {
		return nil
	}
	return CopyFile(src, dst)
}

// SameContents returns same = true if src and dst both exist and have the
// same file contents. Whether the file data is at the same place on
// disk is a different question, which is not answered.
//
// If either file is a directory, FileTypeError is returned.
func SameContents(src, dst string) (same bool, err error) {
	same, err = SameFile(src, dst)
	if err != nil {
		return same, err
	}

	// TODO: I could make this more efficient, based on the file size.
	ssum, err := sumFile(src)
	if err != nil {
		return false, err
	}
	dsum, err := sumFile(dst)
	if err != nil {
		return false, err
	}
	return bytes.Compare(ssum, dsum) == 0, nil
}

// sumFile creates an md5sum of a file
func sumFile(path string) (sum []byte, err error) {
	h := md5.New()
	f, err := os.Open(path)
	if err != nil {
		return sum, err
	}
	io.Copy(h, f)
	return h.Sum(nil), nil
}

func SameFile(src, dst string) (same bool, err error) {
	fs, err := os.Stat(src)
	if err != nil {
		return false, err
	}
	if fs.IsDir() {
		return false, FileTypeError{src}
	}

	fd, err := os.Stat(dst)
	if err != nil {
		if os.IsNotExist(err) {
			return false, nil
		}
		return false, err
	}
	if fd.IsDir() {
		return false, FileTypeError{dst}
	}

	return os.SameFile(fs, fd), nil
}

// Exists returns ex = true if the given file exists, regardless whether
// it is a file or a directory. Normally you will probably want to use the more
// specific versions: FileExists and DirectoryExists.
func Exists(path string) (ex bool, err error) {
	ex, _, err = exists(path)
	return ex, err
}

// FileExists returns ex = true if the file exists and is not
// a directory, and returns err != nil if any other error occured (such as
// permission denied).
func FileExists(path string) (ex bool, err error) {
	var stat os.FileInfo

	ex, stat, err = exists(path)
	if stat != nil && stat.IsDir() {
		return false, FileTypeError{path}
	}
	return ex, err
}

// DirExists returns ex = true if the file exists and is
// a directory, and returns err != nil if any other error occured (such as
// permission denied).
func DirExists(path string) (ex bool, err error) {
	var stat os.FileInfo

	ex, stat, err = exists(path)
	if stat != nil && !stat.IsDir() {
		return false, FileTypeError{path}
	}
	return ex, err
}

// exists does the hard work for Exists, FileExists, and DirExists,
// returning ex = true if the file given by path exists.
func exists(path string) (ex bool, stat os.FileInfo, err error) {
	stat, err = os.Stat(path)

	ex = true
	if err != nil {
		// ex = true if file exists
		ex = !os.IsNotExist(err)
		if !ex {
			err = nil
		}
	}
	return ex, stat, err
}
<|endoftext|>


<commit_before>// Simple console progress bars
package pb

import (
	"fmt"
	"io"
	"math"
	"strings"
	"sync"
	"sync/atomic"
	"time"
	"unicode/utf8"
)

const (
	// Default refresh rate - 200ms
	DEFAULT_REFRESH_RATE = time.Millisecond * 200
	FORMAT               = "[=>-]"
)

// DEPRECATED
// variables for backward compatibility, from now do not work
// use pb.Format and pb.SetRefreshRate
var (
	DefaultRefreshRate                         = DEFAULT_REFRESH_RATE
	BarStart, BarEnd, Empty, Current, CurrentN string
)

// Create new progress bar object
func New(total int) *ProgressBar {
	return New64(int64(total))
}

// Create new progress bar object uding int64 as total
func New64(total int64) *ProgressBar {
	pb := &ProgressBar{
		Total:         total,
		RefreshRate:   DEFAULT_REFRESH_RATE,
		ShowPercent:   true,
		ShowCounters:  true,
		ShowBar:       true,
		ShowTimeLeft:  true,
		ShowFinalTime: true,
		Units:         U_NO,
		ManualUpdate:  false,
		finish:        make(chan struct{}),
		currentValue:  -1,
		mu:            new(sync.Mutex),
	}
	return pb.Format(FORMAT)
}

// Create new object and start
func StartNew(total int) *ProgressBar {
	return New(total).Start()
}

// Callback for custom output
// For example:
// bar.Callback = func(s string) {
//     mySuperPrint(s)
// }
//
type Callback func(out string)

type ProgressBar struct {
	current int64 // current must be first member of struct (https://code.google.com/p/go/issues/detail?id=5278)

	Total                            int64
	RefreshRate                      time.Duration
	ShowPercent, ShowCounters        bool
	ShowSpeed, ShowTimeLeft, ShowBar bool
	ShowFinalTime                    bool
	Output                           io.Writer
	Callback                         Callback
	NotPrint                         bool
	Units                            Units
	Width                            int
	ForceWidth                       bool
	ManualUpdate                     bool

	// default width for unit numbers and time box
	UnitsWidth   int
	TimeBoxWidth int

	finishOnce sync.Once //Guards isFinish
	finish     chan struct{}
	isFinish   bool

	startTime    time.Time
	startValue   int64
	currentValue int64

	prefix, postfix string

	mu        *sync.Mutex
	lastPrint string

	BarStart string
	BarEnd   string
	Empty    string
	Current  string
	CurrentN string

	AlwaysUpdate bool
}

// Start print
func (pb *ProgressBar) Start() *ProgressBar {
	pb.startTime = time.Now()
	pb.startValue = pb.current
	if pb.Total == 0 {
		pb.ShowTimeLeft = false
		pb.ShowPercent = false
	}
	if !pb.ManualUpdate {
		go pb.writer()
	}
	return pb
}

// Increment current value
func (pb *ProgressBar) Increment() int {
	return pb.Add(1)
}

// Set current value
func (pb *ProgressBar) Set(current int) *ProgressBar {
	return pb.Set64(int64(current))
}

// Set64 sets the current value as int64
func (pb *ProgressBar) Set64(current int64) *ProgressBar {
	atomic.StoreInt64(&pb.current, current)
	return pb
}

// Add to current value
func (pb *ProgressBar) Add(add int) int {
	return int(pb.Add64(int64(add)))
}

func (pb *ProgressBar) Add64(add int64) int64 {
	return atomic.AddInt64(&pb.current, add)
}

// Set prefix string
func (pb *ProgressBar) Prefix(prefix string) *ProgressBar {
	pb.prefix = prefix
	return pb
}

// Set postfix string
func (pb *ProgressBar) Postfix(postfix string) *ProgressBar {
	pb.postfix = postfix
	return pb
}

// Set custom format for bar
// Example: bar.Format("[=>_]")
// Example: bar.Format("[\x00=\x00>\x00-\x00]") // \x00 is the delimiter
func (pb *ProgressBar) Format(format string) *ProgressBar {
	var formatEntries []string
	if len(format) == 5 {
		formatEntries = strings.Split(format, "")
	} else {
		formatEntries = strings.Split(format, "\x00")
	}
	if len(formatEntries) == 5 {
		pb.BarStart = formatEntries[0]
		pb.BarEnd = formatEntries[4]
		pb.Empty = formatEntries[3]
		pb.Current = formatEntries[1]
		pb.CurrentN = formatEntries[2]
	}
	return pb
}

// Set bar refresh rate
func (pb *ProgressBar) SetRefreshRate(rate time.Duration) *ProgressBar {
	pb.RefreshRate = rate
	return pb
}

// Set units
// bar.SetUnits(U_NO) - by default
// bar.SetUnits(U_BYTES) - for Mb, Kb, etc
func (pb *ProgressBar) SetUnits(units Units) *ProgressBar {
	pb.Units = units
	return pb
}

// Set max width, if width is bigger than terminal width, will be ignored
func (pb *ProgressBar) SetMaxWidth(width int) *ProgressBar {
	pb.Width = width
	pb.ForceWidth = false
	return pb
}

// Set bar width
func (pb *ProgressBar) SetWidth(width int) *ProgressBar {
	pb.Width = width
	pb.ForceWidth = true
	return pb
}

// End print
func (pb *ProgressBar) Finish() {
	//Protect multiple calls
	pb.finishOnce.Do(func() {
		close(pb.finish)
		pb.write(atomic.LoadInt64(&pb.current))
		if !pb.NotPrint {
			fmt.Println()
		}
		pb.isFinish = true
	})
}

// End print and write string 'str'
func (pb *ProgressBar) FinishPrint(str string) {
	pb.Finish()
	fmt.Println(str)
}

// implement io.Writer
func (pb *ProgressBar) Write(p []byte) (n int, err error) {
	n = len(p)
	pb.Add(n)
	return
}

// implement io.Reader
func (pb *ProgressBar) Read(p []byte) (n int, err error) {
	n = len(p)
	pb.Add(n)
	return
}

// Create new proxy reader over bar
func (pb *ProgressBar) NewProxyReader(r io.Reader) *Reader {
	return &Reader{r, pb}
}

func (pb *ProgressBar) write(current int64) {
	width := pb.GetWidth()

	var percentBox, countersBox, timeLeftBox, speedBox, barBox, end, out string

	// percents
	if pb.ShowPercent {
		percent := float64(current) / (float64(pb.Total) / float64(100))
		percentBox = fmt.Sprintf(" %6.02f %% ", percent)
	}

	// counters
	if pb.ShowCounters {
		if pb.Total > 0 {
			countersBox = fmt.Sprintf("%s / %s ", Format(current, pb.Units, pb.UnitsWidth), Format(pb.Total, pb.Units, pb.UnitsWidth))
		} else {
			countersBox = Format(current, pb.Units, pb.UnitsWidth) + " / ? "
		}
	}

	// time left
	fromStart := time.Now().Sub(pb.startTime)
	currentFromStart := current - pb.startValue
	select {
	case <-pb.finish:
		if pb.ShowFinalTime {
			left := (fromStart / time.Second) * time.Second
			timeLeftBox = left.String()
		}
	default:
		if pb.ShowTimeLeft && currentFromStart > 0 {
			perEntry := fromStart / time.Duration(currentFromStart)
			left := time.Duration(pb.Total-currentFromStart) * perEntry
			left = (left / time.Second) * time.Second
			timeLeftBox = FormatDuration(left)
		}
	}

	if len(timeLeftBox) < pb.TimeBoxWidth {
		timeLeftBox = fmt.Sprintf("%s%s", strings.Repeat(" ", pb.TimeBoxWidth-len(timeLeftBox)), timeLeftBox)
	}

	// speed
	if pb.ShowSpeed && currentFromStart > 0 {
		fromStart := time.Now().Sub(pb.startTime)
		speed := float64(currentFromStart) / (float64(fromStart) / float64(time.Second))
		speedBox = Format(int64(speed), pb.Units, pb.UnitsWidth) + "/s "
	}

	barWidth := escapeAwareRuneCountInString(countersBox + pb.BarStart + pb.BarEnd + percentBox + timeLeftBox + speedBox + pb.prefix + pb.postfix)
	// bar
	if pb.ShowBar {
		size := width - barWidth
		if size > 0 {
			if pb.Total > 0 {
				curCount := int(math.Ceil((float64(current) / float64(pb.Total)) * float64(size)))
				emptCount := size - curCount
				barBox = pb.BarStart
				if emptCount < 0 {
					emptCount = 0
				}
				if curCount > size {
					curCount = size
				}
				if emptCount <= 0 {
					barBox += strings.Repeat(pb.Current, curCount)
				} else if curCount > 0 {
					barBox += strings.Repeat(pb.Current, curCount-1) + pb.CurrentN
				}

				barBox += strings.Repeat(pb.Empty, emptCount) + pb.BarEnd
			} else {

				barBox = pb.BarStart
				pos := size - int(current)%int(size)
				if pos-1 > 0 {
					barBox += strings.Repeat(pb.Empty, pos-1)
				}
				barBox += pb.Current
				if size-pos-1 > 0 {
					barBox += strings.Repeat(pb.Empty, size-pos-1)
				}
				barBox += pb.BarEnd
			}
		}
	}

	// check len
	out = pb.prefix + countersBox + barBox + percentBox + speedBox + timeLeftBox + pb.postfix
	if escapeAwareRuneCountInString(out) < width {
		end = strings.Repeat(" ", width-utf8.RuneCountInString(out))
	}

	// and print!
	pb.mu.Lock()
	pb.lastPrint = out + end
	pb.mu.Unlock()
	switch {
	case pb.Output != nil:
		fmt.Fprint(pb.Output, "\r"+out+end)
	case pb.Callback != nil:
		pb.Callback(out + end)
	case !pb.NotPrint:
		fmt.Print("\r" + out + end)
	}
}

func (pb *ProgressBar) GetWidth() int {
	if pb.ForceWidth {
		return pb.Width
	}

	width := pb.Width
	termWidth, _ := terminalWidth()
	if width == 0 || termWidth <= width {
		width = termWidth
	}

	return width
}

// Write the current state of the progressbar
func (pb *ProgressBar) Update() {
	c := atomic.LoadInt64(&pb.current)
	if pb.AlwaysUpdate || c != pb.currentValue {
		pb.write(c)
		pb.currentValue = c
	}
}

func (pb *ProgressBar) String() string {
	return pb.lastPrint
}

// Internal loop for writing progressbar
func (pb *ProgressBar) writer() {
	pb.Update()
	for {
		select {
		case <-pb.finish:
			return
		case <-time.After(pb.RefreshRate):
			pb.Update()
		}
	}
}

type window struct {
	Row    uint16
	Col    uint16
	Xpixel uint16
	Ypixel uint16
}
<commit_msg>Fix double printing issue for short-lived bars.<commit_after>// Simple console progress bars
package pb

import (
	"fmt"
	"io"
	"math"
	"strings"
	"sync"
	"sync/atomic"
	"time"
	"unicode/utf8"
)

const (
	// Default refresh rate - 200ms
	DEFAULT_REFRESH_RATE = time.Millisecond * 200
	FORMAT               = "[=>-]"
)

// DEPRECATED
// variables for backward compatibility, from now do not work
// use pb.Format and pb.SetRefreshRate
var (
	DefaultRefreshRate                         = DEFAULT_REFRESH_RATE
	BarStart, BarEnd, Empty, Current, CurrentN string
)

// Create new progress bar object
func New(total int) *ProgressBar {
	return New64(int64(total))
}

// Create new progress bar object uding int64 as total
func New64(total int64) *ProgressBar {
	pb := &ProgressBar{
		Total:         total,
		RefreshRate:   DEFAULT_REFRESH_RATE,
		ShowPercent:   true,
		ShowCounters:  true,
		ShowBar:       true,
		ShowTimeLeft:  true,
		ShowFinalTime: true,
		Units:         U_NO,
		ManualUpdate:  false,
		finish:        make(chan struct{}),
		currentValue:  -1,
		mu:            new(sync.Mutex),
	}
	return pb.Format(FORMAT)
}

// Create new object and start
func StartNew(total int) *ProgressBar {
	return New(total).Start()
}

// Callback for custom output
// For example:
// bar.Callback = func(s string) {
//     mySuperPrint(s)
// }
//
type Callback func(out string)

type ProgressBar struct {
	current int64 // current must be first member of struct (https://code.google.com/p/go/issues/detail?id=5278)

	Total                            int64
	RefreshRate                      time.Duration
	ShowPercent, ShowCounters        bool
	ShowSpeed, ShowTimeLeft, ShowBar bool
	ShowFinalTime                    bool
	Output                           io.Writer
	Callback                         Callback
	NotPrint                         bool
	Units                            Units
	Width                            int
	ForceWidth                       bool
	ManualUpdate                     bool

	// default width for unit numbers and time box
	UnitsWidth   int
	TimeBoxWidth int

	finishOnce sync.Once //Guards isFinish
	finish     chan struct{}
	isFinish   bool

	startTime    time.Time
	startValue   int64
	currentValue int64

	prefix, postfix string

	mu        *sync.Mutex
	lastPrint string

	BarStart string
	BarEnd   string
	Empty    string
	Current  string
	CurrentN string

	AlwaysUpdate bool
}

// Start print
func (pb *ProgressBar) Start() *ProgressBar {
	pb.startTime = time.Now()
	pb.startValue = pb.current
	if pb.Total == 0 {
		pb.ShowTimeLeft = false
		pb.ShowPercent = false
	}
	if !pb.ManualUpdate {
		pb.Update() // Initial printing of the bar before running the bar refresher.
		go pb.refresher()
	}
	return pb
}

// Increment current value
func (pb *ProgressBar) Increment() int {
	return pb.Add(1)
}

// Set current value
func (pb *ProgressBar) Set(current int) *ProgressBar {
	return pb.Set64(int64(current))
}

// Set64 sets the current value as int64
func (pb *ProgressBar) Set64(current int64) *ProgressBar {
	atomic.StoreInt64(&pb.current, current)
	return pb
}

// Add to current value
func (pb *ProgressBar) Add(add int) int {
	return int(pb.Add64(int64(add)))
}

func (pb *ProgressBar) Add64(add int64) int64 {
	return atomic.AddInt64(&pb.current, add)
}

// Set prefix string
func (pb *ProgressBar) Prefix(prefix string) *ProgressBar {
	pb.prefix = prefix
	return pb
}

// Set postfix string
func (pb *ProgressBar) Postfix(postfix string) *ProgressBar {
	pb.postfix = postfix
	return pb
}

// Set custom format for bar
// Example: bar.Format("[=>_]")
// Example: bar.Format("[\x00=\x00>\x00-\x00]") // \x00 is the delimiter
func (pb *ProgressBar) Format(format string) *ProgressBar {
	var formatEntries []string
	if len(format) == 5 {
		formatEntries = strings.Split(format, "")
	} else {
		formatEntries = strings.Split(format, "\x00")
	}
	if len(formatEntries) == 5 {
		pb.BarStart = formatEntries[0]
		pb.BarEnd = formatEntries[4]
		pb.Empty = formatEntries[3]
		pb.Current = formatEntries[1]
		pb.CurrentN = formatEntries[2]
	}
	return pb
}

// Set bar refresh rate
func (pb *ProgressBar) SetRefreshRate(rate time.Duration) *ProgressBar {
	pb.RefreshRate = rate
	return pb
}

// Set units
// bar.SetUnits(U_NO) - by default
// bar.SetUnits(U_BYTES) - for Mb, Kb, etc
func (pb *ProgressBar) SetUnits(units Units) *ProgressBar {
	pb.Units = units
	return pb
}

// Set max width, if width is bigger than terminal width, will be ignored
func (pb *ProgressBar) SetMaxWidth(width int) *ProgressBar {
	pb.Width = width
	pb.ForceWidth = false
	return pb
}

// Set bar width
func (pb *ProgressBar) SetWidth(width int) *ProgressBar {
	pb.Width = width
	pb.ForceWidth = true
	return pb
}

// End print
func (pb *ProgressBar) Finish() {
	//Protect multiple calls
	pb.finishOnce.Do(func() {
		close(pb.finish)
		pb.write(atomic.LoadInt64(&pb.current))
		if !pb.NotPrint {
			fmt.Println()
		}
		pb.isFinish = true
	})
}

// End print and write string 'str'
func (pb *ProgressBar) FinishPrint(str string) {
	pb.Finish()
	fmt.Println(str)
}

// implement io.Writer
func (pb *ProgressBar) Write(p []byte) (n int, err error) {
	n = len(p)
	pb.Add(n)
	return
}

// implement io.Reader
func (pb *ProgressBar) Read(p []byte) (n int, err error) {
	n = len(p)
	pb.Add(n)
	return
}

// Create new proxy reader over bar
func (pb *ProgressBar) NewProxyReader(r io.Reader) *Reader {
	return &Reader{r, pb}
}

func (pb *ProgressBar) write(current int64) {
	width := pb.GetWidth()

	var percentBox, countersBox, timeLeftBox, speedBox, barBox, end, out string

	// percents
	if pb.ShowPercent {
		percent := float64(current) / (float64(pb.Total) / float64(100))
		percentBox = fmt.Sprintf(" %6.02f %% ", percent)
	}

	// counters
	if pb.ShowCounters {
		if pb.Total > 0 {
			countersBox = fmt.Sprintf("%s / %s ", Format(current, pb.Units, pb.UnitsWidth), Format(pb.Total, pb.Units, pb.UnitsWidth))
		} else {
			countersBox = Format(current, pb.Units, pb.UnitsWidth) + " / ? "
		}
	}

	// time left
	fromStart := time.Now().Sub(pb.startTime)
	currentFromStart := current - pb.startValue
	select {
	case <-pb.finish:
		if pb.ShowFinalTime {
			left := (fromStart / time.Second) * time.Second
			timeLeftBox = left.String()
		}
	default:
		if pb.ShowTimeLeft && currentFromStart > 0 {
			perEntry := fromStart / time.Duration(currentFromStart)
			left := time.Duration(pb.Total-currentFromStart) * perEntry
			left = (left / time.Second) * time.Second
			timeLeftBox = FormatDuration(left)
		}
	}

	if len(timeLeftBox) < pb.TimeBoxWidth {
		timeLeftBox = fmt.Sprintf("%s%s", strings.Repeat(" ", pb.TimeBoxWidth-len(timeLeftBox)), timeLeftBox)
	}

	// speed
	if pb.ShowSpeed && currentFromStart > 0 {
		fromStart := time.Now().Sub(pb.startTime)
		speed := float64(currentFromStart) / (float64(fromStart) / float64(time.Second))
		speedBox = Format(int64(speed), pb.Units, pb.UnitsWidth) + "/s "
	}

	barWidth := escapeAwareRuneCountInString(countersBox + pb.BarStart + pb.BarEnd + percentBox + timeLeftBox + speedBox + pb.prefix + pb.postfix)
	// bar
	if pb.ShowBar {
		size := width - barWidth
		if size > 0 {
			if pb.Total > 0 {
				curCount := int(math.Ceil((float64(current) / float64(pb.Total)) * float64(size)))
				emptCount := size - curCount
				barBox = pb.BarStart
				if emptCount < 0 {
					emptCount = 0
				}
				if curCount > size {
					curCount = size
				}
				if emptCount <= 0 {
					barBox += strings.Repeat(pb.Current, curCount)
				} else if curCount > 0 {
					barBox += strings.Repeat(pb.Current, curCount-1) + pb.CurrentN
				}

				barBox += strings.Repeat(pb.Empty, emptCount) + pb.BarEnd
			} else {

				barBox = pb.BarStart
				pos := size - int(current)%int(size)
				if pos-1 > 0 {
					barBox += strings.Repeat(pb.Empty, pos-1)
				}
				barBox += pb.Current
				if size-pos-1 > 0 {
					barBox += strings.Repeat(pb.Empty, size-pos-1)
				}
				barBox += pb.BarEnd
			}
		}
	}

	// check len
	out = pb.prefix + countersBox + barBox + percentBox + speedBox + timeLeftBox + pb.postfix
	if escapeAwareRuneCountInString(out) < width {
		end = strings.Repeat(" ", width-utf8.RuneCountInString(out))
	}

	// and print!
	pb.mu.Lock()
	pb.lastPrint = out + end
	pb.mu.Unlock()
	switch {
	case pb.isFinish:
		return
	case pb.Output != nil:
		fmt.Fprint(pb.Output, "\r"+out+end)
	case pb.Callback != nil:
		pb.Callback(out + end)
	case !pb.NotPrint:
		fmt.Print("\r" + out + end)
	}
}

func (pb *ProgressBar) GetWidth() int {
	if pb.ForceWidth {
		return pb.Width
	}

	width := pb.Width
	termWidth, _ := terminalWidth()
	if width == 0 || termWidth <= width {
		width = termWidth
	}

	return width
}

// Write the current state of the progressbar
func (pb *ProgressBar) Update() {
	c := atomic.LoadInt64(&pb.current)
	if pb.AlwaysUpdate || c != pb.currentValue {
		pb.write(c)
		pb.currentValue = c
	}
}

func (pb *ProgressBar) String() string {
	return pb.lastPrint
}

// Internal loop for refreshing the progressbar
func (pb *ProgressBar) refresher() {
	for {
		select {
		case <-pb.finish:
			return
		case <-time.After(pb.RefreshRate):
			pb.Update()
		}
	}
}

type window struct {
	Row    uint16
	Col    uint16
	Xpixel uint16
	Ypixel uint16
}
<|endoftext|>


<commit_before>package eval

import (
	"fmt"
	"reflect"
	"strconv"

	"go/ast"
)

// Annotated ast.Expr nodes
type Expr interface {
	ast.Expr

	// The type of this expression if known. Certain expr types have special interpretations
	// Constant expr: a ConstType will be returned if constant is untyped
	// Ellipsis expr: a single reflect.Type represents the type of all unpacked values
	KnownType() []reflect.Type

	// Returns true if this expression evaluates to a constant. In this
	// case, Value() will return the evalutated constant. Nodes below
	// this expression can be ignored.
	IsConst() bool

	// Returns the const value, if known.
	Const() reflect.Value

	// String() matches the print format of expressions in go errors
	String() string
}

type knownType []reflect.Type
type constValue reflect.Value

type BadExpr struct {
	*ast.BadExpr
}

type Ident struct {
	*ast.Ident
	knownType
	constValue
}

type Ellipsis struct {
	*ast.Ellipsis
	knownType
}

type BasicLit struct {
	*ast.BasicLit
	knownType
	constValue
}

type FuncLit struct {
	*ast.FuncLit
}

type CompositeLit struct {
	*ast.CompositeLit
	knownType
}

type ParenExpr struct {
	*ast.ParenExpr
	knownType
	constValue
}

type SelectorExpr struct {
	*ast.SelectorExpr
	knownType
}

type IndexExpr struct {
	*ast.IndexExpr
	knownType

	// Const value only relevant for strings.
	// "abc"[2] is a const expr
	// []int{1}[2] or [1]int{1}[2] are not
	constValue
}

type SliceExpr struct {
	*ast.SliceExpr
	knownType
}

type TypeAssertExpr struct {
	*ast.TypeAssertExpr
	knownType
}

type CallExpr struct {
	*ast.CallExpr

	// Is this a type conversion. If true, 't' will be non-nil
	isTypeConversion bool
	knownType
	constValue

	// Does this function take  single, multivalued expession that is unpacked as its arguments
	isSplat bool

	// Is the function type variadic
	isVariadic bool

	// Is an ellipsis expression used to unpack variadic arguments
	hasEllipsis bool
}

type StarExpr struct {
	*ast.StarExpr
	knownType
}

type UnaryExpr struct {
	*ast.UnaryExpr
	knownType
	constValue
}

type BinaryExpr struct {
	*ast.BinaryExpr
	knownType
	constValue
}

type KeyValueExpr struct {
	*ast.KeyValueExpr
}

type ArrayType struct {
	*ast.ArrayType
	knownType
}

type StructType struct {
	*ast.StructType
	knownType
}

type FuncType struct {
	*ast.FuncType
	knownType
}

type InterfaceType struct {
	*ast.InterfaceType
	knownType
}

type MapType struct {
	*ast.MapType
	knownType
}

type ChanType struct {
	*ast.ChanType
	knownType
}

func (t knownType) KnownType() []reflect.Type {
	return []reflect.Type(t)
}

func (c constValue) IsConst() bool {
	return reflect.Value(c).IsValid()
}

func (c constValue) Const() reflect.Value {
	return reflect.Value(c)
}

func (*BadExpr) KnownType() []reflect.Type      { return nil }
func (*FuncLit) KnownType() []reflect.Type      { return nil }
func (*KeyValueExpr) KnownType() []reflect.Type { return nil }

func (*BadExpr) IsConst() bool        { return false }
func (*Ellipsis) IsConst() bool       { return false }
func (*FuncLit) IsConst() bool        { return false }
func (*CompositeLit) IsConst() bool   { return false }
func (*SelectorExpr) IsConst() bool   { return false }
func (*IndexExpr) IsConst() bool      { return false }
func (*SliceExpr) IsConst() bool      { return false }
func (*TypeAssertExpr) IsConst() bool { return false }
func (*StarExpr) IsConst() bool       { return false }
func (*KeyValueExpr) IsConst() bool   { return false }
func (*ArrayType) IsConst() bool      { return false }
func (*StructType) IsConst() bool     { return false }
func (*FuncType) IsConst() bool       { return false }
func (*InterfaceType) IsConst() bool  { return false }
func (*MapType) IsConst() bool        { return false }
func (*ChanType) IsConst() bool       { return false }

func (*BadExpr) Const() reflect.Value        { return reflect.Value{} }
func (*Ellipsis) Const() reflect.Value       { return reflect.Value{} }
func (*FuncLit) Const() reflect.Value        { return reflect.Value{} }
func (*CompositeLit) Const() reflect.Value   { return reflect.Value{} }
func (*SelectorExpr) Const() reflect.Value   { return reflect.Value{} }
func (*IndexExpr) Const() reflect.Value      { return reflect.Value{} }
func (*SliceExpr) Const() reflect.Value      { return reflect.Value{} }
func (*TypeAssertExpr) Const() reflect.Value { return reflect.Value{} }
func (*StarExpr) Const() reflect.Value       { return reflect.Value{} }
func (*KeyValueExpr) Const() reflect.Value   { return reflect.Value{} }
func (*ArrayType) Const() reflect.Value      { return reflect.Value{} }
func (*StructType) Const() reflect.Value     { return reflect.Value{} }
func (*FuncType) Const() reflect.Value       { return reflect.Value{} }
func (*InterfaceType) Const() reflect.Value  { return reflect.Value{} }
func (*MapType) Const() reflect.Value        { return reflect.Value{} }
func (*ChanType) Const() reflect.Value       { return reflect.Value{} }

// Does not assert that c is a valid const value type
// Should be *BigComplex, bool, or string
func constValueOf(i interface{}) constValue {
	return constValue(reflect.ValueOf(i))
}

func (badExpr *BadExpr) String() string {
	return "BadExpr"
}

func (ident *Ident) String() string {
	if ident.IsConst() {
		return sprintConstValue(ident.KnownType()[0], ident.Const(), true)
	}
	return ident.Ident.String()
}

func (ellipsis *Ellipsis) String() string { return "TODO  ellipsis.Ellipsis" }

func (basicLit *BasicLit) String() string {
	if basicLit.IsConst() {
		return sprintConstValue(basicLit.KnownType()[0], basicLit.Const(), true)
	}
	return basicLit.Value
}

func (funcLit *FuncLit) String() string { return "TODO  funcLit.FuncLit" }
func (compositeLit *CompositeLit) String() string { return "TODO  compositeLit.CompositeLit" }

func (parenExpr *ParenExpr) String() string {
	if parenExpr.IsConst() {
		return sprintConstValue(parenExpr.KnownType()[0], parenExpr.Const(), true)
	}
	return skipSuperfluousParens(parenExpr).String()
}

func (selectorExpr *SelectorExpr) String() string { return "TODO  selectorExpr.SelectorExpr" }
func (indexExpr *IndexExpr) String() string { return "TODO  indexExpr.IndexExpr" }
func (sliceExpr *SliceExpr) String() string { return "TODO  sliceExpr.SliceExpr" }
func (typeAssertExpr *TypeAssertExpr) String() string { return "TODO  typeAssertExpr.TypeAssertExpr" }

func (callExpr *CallExpr) String() string {
	if callExpr.IsConst() {
		return sprintConstValue(callExpr.KnownType()[0], callExpr.Const(), true)
	}
	return "TODO  callExpr.CallExpr"
}

func (starExpr *StarExpr) String() string { return "TODO  starExpr.StarExpr" }

func (unary *UnaryExpr) String() string {
	operand := skipSuperfluousParens(unary.X.(Expr))
	return fmt.Sprintf("%v %v", unary.Op, operand)
}

func (binary *BinaryExpr) String() string {
	left := simplifyBinaryChildExpr(binary, binary.X.(Expr))
	right := simplifyBinaryChildExpr(binary, binary.Y.(Expr))

	return fmt.Sprintf("%v %v %v", left, binary.Op, right)
}

func (keyValueExpr *KeyValueExpr) String() string { return "TODO  keyValueExpr.KeyValueExpr" }
func (arrayType *ArrayType) String() string { return "TODO  arrayType.ArrayType" }
func (structType *StructType) String() string { return "TODO  structType.StructType" }
func (funcType *FuncType) String() string { return "TODO  funcType.FuncType" }
func (interfaceType *InterfaceType) String() string { return "TODO  interfaceType.InterfaceType" }
func (mapType *MapType) String() string { return "TODO  mapType.MapType" }
func (chanType *ChanType) String() string { return "TODO  chanType.ChanType" }

// Returns a printable interface{} which replaces constant expressions with their constants
func simplifyBinaryChildExpr(parent *BinaryExpr, expr Expr) interface{} {
        if expr.IsConst() {
		return sprintConstValue(expr.KnownType()[0], expr.Const(), true)
	}
	expr = skipSuperfluousParens(expr)
	if p, ok := expr.(*ParenExpr); ok {
		// Remove parens all together from 1 + (2 * 3)
		if b, ok := p.X.(*BinaryExpr); ok && b.Op.Precedence() > parent.Op.Precedence() {
			return p.X
		}
	}
	return expr
}

// Walk the ast of expressions like (((x))) and return the inner *ParenExpr.
// Returns input Expr if it is not a *ParenExpr
func skipSuperfluousParens(expr Expr) Expr {
	if p, ok := expr.(*ParenExpr); ok {
		// Remove useless parens from (((x))) expressions
		var tmp *ParenExpr
		for ; ok; tmp, ok = p.X.(*ParenExpr) {
			p = tmp
		}

		// Remove parens from all expressions where order of evaluation is irrelevant
		switch p.X.(type) {
		case *BinaryExpr:
			return p
		default:
			return p.X.(Expr)
		}
	}
	return expr
}

func sprintConstValue(t reflect.Type, v reflect.Value, showZeroComponents bool) string {
	i := v.Interface()
	switch x := i.(type) {
	case *ConstNumber:
                // This is hear to print overflowing typed runes, which
                // are represented by a *ConstNumber and a RuneType
                if t == RuneType {
                        r := *x
                        r.Type = ConstInt
		        return "rune(" + r.StringShow0i(false) + ")"
                }
		return x.StringShow0i(false)
        case rune:
                if t == RuneType {
		        return fmt.Sprintf("rune(%v)", x)
                }
	case float32, float64:
		return fmt.Sprintf("%.6g", x)
	case complex64:
		re := real(x)
		im := imag(x)
		if re == 0 && !showZeroComponents {
			return fmt.Sprintf("%.6gi", im)
		} else if im == 0 && !showZeroComponents {
			return fmt.Sprintf("%.6g", re)
		} else {
			return fmt.Sprintf("(%.6g+%.6gi)", re, im)
		}
	case complex128:
		re := real(x)
		im := imag(x)
		if re == 0 && !showZeroComponents {
			return fmt.Sprintf("%.6gi", im)
		} else if im == 0 && !showZeroComponents {
			return fmt.Sprintf("%.6g", re)
		} else {
			return fmt.Sprintf("(%.6g+%.6gi)", re, im)
		}
	}

	return fmt.Sprint(quoteString(i))
}

func quoteString(i interface{}) interface{} {
	if s, ok := i.(string); ok {
		return strconv.Quote(s)
	} else {
		return i
	}
}

func (c constValue) String() string {
        return reflect.Value(c).String()
}
<commit_msg>Spelling homonym typo.<commit_after>package eval

import (
	"fmt"
	"reflect"
	"strconv"

	"go/ast"
)

// Annotated ast.Expr nodes
type Expr interface {
	ast.Expr

	// The type of this expression if known. Certain expr types have special interpretations
	// Constant expr: a ConstType will be returned if constant is untyped
	// Ellipsis expr: a single reflect.Type represents the type of all unpacked values
	KnownType() []reflect.Type

	// Returns true if this expression evaluates to a constant. In this
	// case, Value() will return the evalutated constant. Nodes below
	// this expression can be ignored.
	IsConst() bool

	// Returns the const value, if known.
	Const() reflect.Value

	// String() matches the print format of expressions in go errors
	String() string
}

type knownType []reflect.Type
type constValue reflect.Value

type BadExpr struct {
	*ast.BadExpr
}

type Ident struct {
	*ast.Ident
	knownType
	constValue
}

type Ellipsis struct {
	*ast.Ellipsis
	knownType
}

type BasicLit struct {
	*ast.BasicLit
	knownType
	constValue
}

type FuncLit struct {
	*ast.FuncLit
}

type CompositeLit struct {
	*ast.CompositeLit
	knownType
}

type ParenExpr struct {
	*ast.ParenExpr
	knownType
	constValue
}

type SelectorExpr struct {
	*ast.SelectorExpr
	knownType
}

type IndexExpr struct {
	*ast.IndexExpr
	knownType

	// Const value only relevant for strings.
	// "abc"[2] is a const expr
	// []int{1}[2] or [1]int{1}[2] are not
	constValue
}

type SliceExpr struct {
	*ast.SliceExpr
	knownType
}

type TypeAssertExpr struct {
	*ast.TypeAssertExpr
	knownType
}

type CallExpr struct {
	*ast.CallExpr

	// Is this a type conversion. If true, 't' will be non-nil
	isTypeConversion bool
	knownType
	constValue

	// Does this function take  single, multivalued expession that is unpacked as its arguments
	isSplat bool

	// Is the function type variadic
	isVariadic bool

	// Is an ellipsis expression used to unpack variadic arguments
	hasEllipsis bool
}

type StarExpr struct {
	*ast.StarExpr
	knownType
}

type UnaryExpr struct {
	*ast.UnaryExpr
	knownType
	constValue
}

type BinaryExpr struct {
	*ast.BinaryExpr
	knownType
	constValue
}

type KeyValueExpr struct {
	*ast.KeyValueExpr
}

type ArrayType struct {
	*ast.ArrayType
	knownType
}

type StructType struct {
	*ast.StructType
	knownType
}

type FuncType struct {
	*ast.FuncType
	knownType
}

type InterfaceType struct {
	*ast.InterfaceType
	knownType
}

type MapType struct {
	*ast.MapType
	knownType
}

type ChanType struct {
	*ast.ChanType
	knownType
}

func (t knownType) KnownType() []reflect.Type {
	return []reflect.Type(t)
}

func (c constValue) IsConst() bool {
	return reflect.Value(c).IsValid()
}

func (c constValue) Const() reflect.Value {
	return reflect.Value(c)
}

func (*BadExpr) KnownType() []reflect.Type      { return nil }
func (*FuncLit) KnownType() []reflect.Type      { return nil }
func (*KeyValueExpr) KnownType() []reflect.Type { return nil }

func (*BadExpr) IsConst() bool        { return false }
func (*Ellipsis) IsConst() bool       { return false }
func (*FuncLit) IsConst() bool        { return false }
func (*CompositeLit) IsConst() bool   { return false }
func (*SelectorExpr) IsConst() bool   { return false }
func (*IndexExpr) IsConst() bool      { return false }
func (*SliceExpr) IsConst() bool      { return false }
func (*TypeAssertExpr) IsConst() bool { return false }
func (*StarExpr) IsConst() bool       { return false }
func (*KeyValueExpr) IsConst() bool   { return false }
func (*ArrayType) IsConst() bool      { return false }
func (*StructType) IsConst() bool     { return false }
func (*FuncType) IsConst() bool       { return false }
func (*InterfaceType) IsConst() bool  { return false }
func (*MapType) IsConst() bool        { return false }
func (*ChanType) IsConst() bool       { return false }

func (*BadExpr) Const() reflect.Value        { return reflect.Value{} }
func (*Ellipsis) Const() reflect.Value       { return reflect.Value{} }
func (*FuncLit) Const() reflect.Value        { return reflect.Value{} }
func (*CompositeLit) Const() reflect.Value   { return reflect.Value{} }
func (*SelectorExpr) Const() reflect.Value   { return reflect.Value{} }
func (*IndexExpr) Const() reflect.Value      { return reflect.Value{} }
func (*SliceExpr) Const() reflect.Value      { return reflect.Value{} }
func (*TypeAssertExpr) Const() reflect.Value { return reflect.Value{} }
func (*StarExpr) Const() reflect.Value       { return reflect.Value{} }
func (*KeyValueExpr) Const() reflect.Value   { return reflect.Value{} }
func (*ArrayType) Const() reflect.Value      { return reflect.Value{} }
func (*StructType) Const() reflect.Value     { return reflect.Value{} }
func (*FuncType) Const() reflect.Value       { return reflect.Value{} }
func (*InterfaceType) Const() reflect.Value  { return reflect.Value{} }
func (*MapType) Const() reflect.Value        { return reflect.Value{} }
func (*ChanType) Const() reflect.Value       { return reflect.Value{} }

// Does not assert that c is a valid const value type
// Should be *BigComplex, bool, or string
func constValueOf(i interface{}) constValue {
	return constValue(reflect.ValueOf(i))
}

func (badExpr *BadExpr) String() string {
	return "BadExpr"
}

func (ident *Ident) String() string {
	if ident.IsConst() {
		return sprintConstValue(ident.KnownType()[0], ident.Const(), true)
	}
	return ident.Ident.String()
}

func (ellipsis *Ellipsis) String() string { return "TODO  ellipsis.Ellipsis" }

func (basicLit *BasicLit) String() string {
	if basicLit.IsConst() {
		return sprintConstValue(basicLit.KnownType()[0], basicLit.Const(), true)
	}
	return basicLit.Value
}

func (funcLit *FuncLit) String() string { return "TODO  funcLit.FuncLit" }
func (compositeLit *CompositeLit) String() string { return "TODO  compositeLit.CompositeLit" }

func (parenExpr *ParenExpr) String() string {
	if parenExpr.IsConst() {
		return sprintConstValue(parenExpr.KnownType()[0], parenExpr.Const(), true)
	}
	return skipSuperfluousParens(parenExpr).String()
}

func (selectorExpr *SelectorExpr) String() string { return "TODO  selectorExpr.SelectorExpr" }
func (indexExpr *IndexExpr) String() string { return "TODO  indexExpr.IndexExpr" }
func (sliceExpr *SliceExpr) String() string { return "TODO  sliceExpr.SliceExpr" }
func (typeAssertExpr *TypeAssertExpr) String() string { return "TODO  typeAssertExpr.TypeAssertExpr" }

func (callExpr *CallExpr) String() string {
	if callExpr.IsConst() {
		return sprintConstValue(callExpr.KnownType()[0], callExpr.Const(), true)
	}
	return "TODO  callExpr.CallExpr"
}

func (starExpr *StarExpr) String() string { return "TODO  starExpr.StarExpr" }

func (unary *UnaryExpr) String() string {
	operand := skipSuperfluousParens(unary.X.(Expr))
	return fmt.Sprintf("%v %v", unary.Op, operand)
}

func (binary *BinaryExpr) String() string {
	left := simplifyBinaryChildExpr(binary, binary.X.(Expr))
	right := simplifyBinaryChildExpr(binary, binary.Y.(Expr))

	return fmt.Sprintf("%v %v %v", left, binary.Op, right)
}

func (keyValueExpr *KeyValueExpr) String() string { return "TODO  keyValueExpr.KeyValueExpr" }
func (arrayType *ArrayType) String() string { return "TODO  arrayType.ArrayType" }
func (structType *StructType) String() string { return "TODO  structType.StructType" }
func (funcType *FuncType) String() string { return "TODO  funcType.FuncType" }
func (interfaceType *InterfaceType) String() string { return "TODO  interfaceType.InterfaceType" }
func (mapType *MapType) String() string { return "TODO  mapType.MapType" }
func (chanType *ChanType) String() string { return "TODO  chanType.ChanType" }

// Returns a printable interface{} which replaces constant expressions with their constants
func simplifyBinaryChildExpr(parent *BinaryExpr, expr Expr) interface{} {
        if expr.IsConst() {
		return sprintConstValue(expr.KnownType()[0], expr.Const(), true)
	}
	expr = skipSuperfluousParens(expr)
	if p, ok := expr.(*ParenExpr); ok {
		// Remove parens all together from 1 + (2 * 3)
		if b, ok := p.X.(*BinaryExpr); ok && b.Op.Precedence() > parent.Op.Precedence() {
			return p.X
		}
	}
	return expr
}

// Walk the ast of expressions like (((x))) and return the inner *ParenExpr.
// Returns input Expr if it is not a *ParenExpr
func skipSuperfluousParens(expr Expr) Expr {
	if p, ok := expr.(*ParenExpr); ok {
		// Remove useless parens from (((x))) expressions
		var tmp *ParenExpr
		for ; ok; tmp, ok = p.X.(*ParenExpr) {
			p = tmp
		}

		// Remove parens from all expressions where order of evaluation is irrelevant
		switch p.X.(type) {
		case *BinaryExpr:
			return p
		default:
			return p.X.(Expr)
		}
	}
	return expr
}

func sprintConstValue(t reflect.Type, v reflect.Value, showZeroComponents bool) string {
	i := v.Interface()
	switch x := i.(type) {
	case *ConstNumber:
                // This is here to print overflowing typed runes, which
                // are represented by a *ConstNumber and a RuneType
                if t == RuneType {
                        r := *x
                        r.Type = ConstInt
		        return "rune(" + r.StringShow0i(false) + ")"
                }
		return x.StringShow0i(false)
        case rune:
                if t == RuneType {
		        return fmt.Sprintf("rune(%v)", x)
                }
	case float32, float64:
		return fmt.Sprintf("%.6g", x)
	case complex64:
		re := real(x)
		im := imag(x)
		if re == 0 && !showZeroComponents {
			return fmt.Sprintf("%.6gi", im)
		} else if im == 0 && !showZeroComponents {
			return fmt.Sprintf("%.6g", re)
		} else {
			return fmt.Sprintf("(%.6g+%.6gi)", re, im)
		}
	case complex128:
		re := real(x)
		im := imag(x)
		if re == 0 && !showZeroComponents {
			return fmt.Sprintf("%.6gi", im)
		} else if im == 0 && !showZeroComponents {
			return fmt.Sprintf("%.6g", re)
		} else {
			return fmt.Sprintf("(%.6g+%.6gi)", re, im)
		}
	}

	return fmt.Sprint(quoteString(i))
}

func quoteString(i interface{}) interface{} {
	if s, ok := i.(string); ok {
		return strconv.Quote(s)
	} else {
		return i
	}
}

func (c constValue) String() string {
        return reflect.Value(c).String()
}
<|endoftext|>