<commit_before>package terraform

import (
	"fmt"
	"log"
	"strings"
	"sync"

	"github.com/hashicorp/terraform/dag"
)

// RootModuleName is the name given to the root module implicitly.
const RootModuleName = "root"

// RootModulePath is the path for the root module.
var RootModulePath = []string{RootModuleName}

// Graph represents the graph that Terraform uses to represent resources
// and their dependencies. Each graph represents only one module, but it
// can contain further modules, which themselves have their own graph.
type Graph struct {
	// Graph is the actual DAG. This is embedded so you can call the DAG
	// methods directly.
	dag.AcyclicGraph

	// Path is the path in the module tree that this Graph represents.
	// The root is represented by a single element list containing
	// RootModuleName
	Path []string

	// annotations are the annotations that are added to vertices. Annotations
	// are arbitrary metadata taht is used for various logic. Annotations
	// should have unique keys that are referenced via constants.
	annotations map[dag.Vertex]map[string]interface{}

	// dependableMap is a lookaside table for fast lookups for connecting
	// dependencies by their GraphNodeDependable value to avoid O(n^3)-like
	// situations and turn them into O(1) with respect to the number of new
	// edges.
	dependableMap map[string]dag.Vertex

	once sync.Once
}

// Annotations returns the annotations that are configured for the
// given vertex. The map is guaranteed to be non-nil but may be empty.
//
// The returned map may be modified to modify the annotations of the
// vertex.
func (g *Graph) Annotations(v dag.Vertex) map[string]interface{} {
	g.once.Do(g.init)

	// If this vertex isn't in the graph, then just return an empty map
	if !g.HasVertex(v) {
		return map[string]interface{}{}
	}

	// Get the map, if it doesn't exist yet then initialize it
	m, ok := g.annotations[v]
	if !ok {
		m = make(map[string]interface{})
		g.annotations[v] = m
	}

	return m
}

// Add is the same as dag.Graph.Add.
func (g *Graph) Add(v dag.Vertex) dag.Vertex {
	g.once.Do(g.init)

	// Call upwards to add it to the actual graph
	g.Graph.Add(v)

	// If this is a depend-able node, then store the lookaside info
	if dv, ok := v.(GraphNodeDependable); ok {
		for _, n := range dv.DependableName() {
			g.dependableMap[n] = v
		}
	}

	// If this initializes annotations, then do that
	if av, ok := v.(GraphNodeAnnotationInit); ok {
		as := g.Annotations(v)
		for k, v := range av.AnnotationInit() {
			as[k] = v
		}
	}

	return v
}

// Remove is the same as dag.Graph.Remove
func (g *Graph) Remove(v dag.Vertex) dag.Vertex {
	g.once.Do(g.init)

	// If this is a depend-able node, then remove the lookaside info
	if dv, ok := v.(GraphNodeDependable); ok {
		for _, n := range dv.DependableName() {
			delete(g.dependableMap, n)
		}
	}

	// Remove the annotations
	delete(g.annotations, v)

	// Call upwards to remove it from the actual graph
	return g.Graph.Remove(v)
}

// Replace is the same as dag.Graph.Replace
func (g *Graph) Replace(o, n dag.Vertex) bool {
	g.once.Do(g.init)

	// Go through and update our lookaside to point to the new vertex
	for k, v := range g.dependableMap {
		if v == o {
			if _, ok := n.(GraphNodeDependable); ok {
				g.dependableMap[k] = n
			} else {
				delete(g.dependableMap, k)
			}
		}
	}

	// Move the annotation if it exists
	if m, ok := g.annotations[o]; ok {
		g.annotations[n] = m
		delete(g.annotations, o)
	}

	return g.Graph.Replace(o, n)
}

// ConnectDependent connects a GraphNodeDependent to all of its
// GraphNodeDependables. It returns the list of dependents it was
// unable to connect to.
func (g *Graph) ConnectDependent(raw dag.Vertex) []string {
	v, ok := raw.(GraphNodeDependent)
	if !ok {
		return nil
	}

	return g.ConnectTo(v, v.DependentOn())
}

// ConnectDependents goes through the graph, connecting all the
// GraphNodeDependents to GraphNodeDependables. This is safe to call
// multiple times.
//
// To get details on whether dependencies could be found/made, the more
// specific ConnectDependent should be used.
func (g *Graph) ConnectDependents() {
	for _, v := range g.Vertices() {
		if dv, ok := v.(GraphNodeDependent); ok {
			g.ConnectDependent(dv)
		}
	}
}

// ConnectFrom creates an edge by finding the source from a DependableName
// and connecting it to the specific vertex.
func (g *Graph) ConnectFrom(source string, target dag.Vertex) {
	g.once.Do(g.init)

	if source := g.dependableMap[source]; source != nil {
		g.Connect(dag.BasicEdge(source, target))
	}
}

// ConnectTo connects a vertex to a raw string of targets that are the
// result of DependableName, and returns the list of targets that are missing.
func (g *Graph) ConnectTo(v dag.Vertex, targets []string) []string {
	g.once.Do(g.init)

	var missing []string
	for _, t := range targets {
		if dest := g.dependableMap[t]; dest != nil {
			g.Connect(dag.BasicEdge(v, dest))
		} else {
			missing = append(missing, t)
		}
	}

	return missing
}

// Dependable finds the vertices in the graph that have the given dependable
// names and returns them.
func (g *Graph) Dependable(n string) dag.Vertex {
	// TODO: do we need this?
	return nil
}

// Walk walks the graph with the given walker for callbacks. The graph
// will be walked with full parallelism, so the walker should expect
// to be called in concurrently.
func (g *Graph) Walk(walker GraphWalker) error {
	return g.walk(walker)
}

func (g *Graph) init() {
	if g.annotations == nil {
		g.annotations = make(map[dag.Vertex]map[string]interface{})
	}

	if g.dependableMap == nil {
		g.dependableMap = make(map[string]dag.Vertex)
	}
}

func (g *Graph) walk(walker GraphWalker) error {
	// The callbacks for enter/exiting a graph
	ctx := walker.EnterPath(g.Path)
	defer walker.ExitPath(g.Path)

	// Get the path for logs
	path := strings.Join(ctx.Path(), ".")

	// Walk the graph.
	var walkFn dag.WalkFunc
	walkFn = func(v dag.Vertex) (rerr error) {
		log.Printf("[DEBUG] vertex %s.%s: walking", path, dag.VertexName(v))

		walker.EnterVertex(v)
		defer func() { walker.ExitVertex(v, rerr) }()

		// vertexCtx is the context that we use when evaluating. This
		// is normally the context of our graph but can be overridden
		// with a GraphNodeSubPath impl.
		vertexCtx := ctx
		if pn, ok := v.(GraphNodeSubPath); ok && len(pn.Path()) > 0 {
			vertexCtx = walker.EnterPath(normalizeModulePath(pn.Path()))
			defer walker.ExitPath(pn.Path())
		}

		// If the node is eval-able, then evaluate it.
		if ev, ok := v.(GraphNodeEvalable); ok {
			tree := ev.EvalTree()
			if tree == nil {
				panic(fmt.Sprintf(
					"%s.%s (%T): nil eval tree", path, dag.VertexName(v), v))
			}

			// Allow the walker to change our tree if needed. Eval,
			// then callback with the output.
			log.Printf("[DEBUG] vertex '%s.%s': evaluating", path, dag.VertexName(v))
			tree = walker.EnterEvalTree(v, tree)
			output, err := Eval(tree, vertexCtx)
			if rerr = walker.ExitEvalTree(v, output, err); rerr != nil {
				return
			}
		}

		// If the node is dynamically expanded, then expand it
		if ev, ok := v.(GraphNodeDynamicExpandable); ok {
			log.Printf(
				"[DEBUG] vertex '%s.%s': expanding/walking dynamic subgraph",
				path,
				dag.VertexName(v))
			g, err := ev.DynamicExpand(vertexCtx)
			if err != nil {
				rerr = err
				return
			}
			if g != nil {
				// Walk the subgraph
				if rerr = g.walk(walker); rerr != nil {
					return
				}
			}
		}

		// If the node has a subgraph, then walk the subgraph
		if sn, ok := v.(GraphNodeSubgraph); ok {
			log.Printf(
				"[DEBUG] vertex '%s.%s': walking subgraph",
				path,
				dag.VertexName(v))

			if rerr = sn.Subgraph().walk(walker); rerr != nil {
				return
			}
		}

		return nil
	}

	return g.AcyclicGraph.Walk(walkFn)
}

// GraphNodeAnnotationInit is an interface that allows a node to
// initialize it's annotations.
//
// AnnotationInit will be called _once_ when the node is added to a
// graph for the first time and is expected to return it's initial
// annotations.
type GraphNodeAnnotationInit interface {
	AnnotationInit() map[string]interface{}
}

// GraphNodeDependable is an interface which says that a node can be
// depended on (an edge can be placed between this node and another) according
// to the well-known name returned by DependableName.
//
// DependableName can return multiple names it is known by.
type GraphNodeDependable interface {
	DependableName() []string
}

// GraphNodeDependent is an interface which says that a node depends
// on another GraphNodeDependable by some name. By implementing this
// interface, Graph.ConnectDependents() can be called multiple times
// safely and efficiently.
type GraphNodeDependent interface {
	DependentOn() []string
}
<commit_msg>Missed a spot where panic: could still happen<commit_after>package terraform

import (
	"fmt"
	"log"
	"strings"
	"sync"

	"github.com/hashicorp/terraform/dag"
)

// RootModuleName is the name given to the root module implicitly.
const RootModuleName = "root"

// RootModulePath is the path for the root module.
var RootModulePath = []string{RootModuleName}

// Graph represents the graph that Terraform uses to represent resources
// and their dependencies. Each graph represents only one module, but it
// can contain further modules, which themselves have their own graph.
type Graph struct {
	// Graph is the actual DAG. This is embedded so you can call the DAG
	// methods directly.
	dag.AcyclicGraph

	// Path is the path in the module tree that this Graph represents.
	// The root is represented by a single element list containing
	// RootModuleName
	Path []string

	// annotations are the annotations that are added to vertices. Annotations
	// are arbitrary metadata taht is used for various logic. Annotations
	// should have unique keys that are referenced via constants.
	annotations map[dag.Vertex]map[string]interface{}

	// dependableMap is a lookaside table for fast lookups for connecting
	// dependencies by their GraphNodeDependable value to avoid O(n^3)-like
	// situations and turn them into O(1) with respect to the number of new
	// edges.
	dependableMap map[string]dag.Vertex

	once sync.Once
}

// Annotations returns the annotations that are configured for the
// given vertex. The map is guaranteed to be non-nil but may be empty.
//
// The returned map may be modified to modify the annotations of the
// vertex.
func (g *Graph) Annotations(v dag.Vertex) map[string]interface{} {
	g.once.Do(g.init)

	// If this vertex isn't in the graph, then just return an empty map
	if !g.HasVertex(v) {
		return map[string]interface{}{}
	}

	// Get the map, if it doesn't exist yet then initialize it
	m, ok := g.annotations[v]
	if !ok {
		m = make(map[string]interface{})
		g.annotations[v] = m
	}

	return m
}

// Add is the same as dag.Graph.Add.
func (g *Graph) Add(v dag.Vertex) dag.Vertex {
	g.once.Do(g.init)

	// Call upwards to add it to the actual graph
	g.Graph.Add(v)

	// If this is a depend-able node, then store the lookaside info
	if dv, ok := v.(GraphNodeDependable); ok {
		for _, n := range dv.DependableName() {
			g.dependableMap[n] = v
		}
	}

	// If this initializes annotations, then do that
	if av, ok := v.(GraphNodeAnnotationInit); ok {
		as := g.Annotations(v)
		for k, v := range av.AnnotationInit() {
			as[k] = v
		}
	}

	return v
}

// Remove is the same as dag.Graph.Remove
func (g *Graph) Remove(v dag.Vertex) dag.Vertex {
	g.once.Do(g.init)

	// If this is a depend-able node, then remove the lookaside info
	if dv, ok := v.(GraphNodeDependable); ok {
		for _, n := range dv.DependableName() {
			delete(g.dependableMap, n)
		}
	}

	// Remove the annotations
	delete(g.annotations, v)

	// Call upwards to remove it from the actual graph
	return g.Graph.Remove(v)
}

// Replace is the same as dag.Graph.Replace
func (g *Graph) Replace(o, n dag.Vertex) bool {
	g.once.Do(g.init)

	// Go through and update our lookaside to point to the new vertex
	for k, v := range g.dependableMap {
		if v == o {
			if _, ok := n.(GraphNodeDependable); ok {
				g.dependableMap[k] = n
			} else {
				delete(g.dependableMap, k)
			}
		}
	}

	// Move the annotation if it exists
	if m, ok := g.annotations[o]; ok {
		g.annotations[n] = m
		delete(g.annotations, o)
	}

	return g.Graph.Replace(o, n)
}

// ConnectDependent connects a GraphNodeDependent to all of its
// GraphNodeDependables. It returns the list of dependents it was
// unable to connect to.
func (g *Graph) ConnectDependent(raw dag.Vertex) []string {
	v, ok := raw.(GraphNodeDependent)
	if !ok {
		return nil
	}

	return g.ConnectTo(v, v.DependentOn())
}

// ConnectDependents goes through the graph, connecting all the
// GraphNodeDependents to GraphNodeDependables. This is safe to call
// multiple times.
//
// To get details on whether dependencies could be found/made, the more
// specific ConnectDependent should be used.
func (g *Graph) ConnectDependents() {
	for _, v := range g.Vertices() {
		if dv, ok := v.(GraphNodeDependent); ok {
			g.ConnectDependent(dv)
		}
	}
}

// ConnectFrom creates an edge by finding the source from a DependableName
// and connecting it to the specific vertex.
func (g *Graph) ConnectFrom(source string, target dag.Vertex) {
	g.once.Do(g.init)

	if source := g.dependableMap[source]; source != nil {
		g.Connect(dag.BasicEdge(source, target))
	}
}

// ConnectTo connects a vertex to a raw string of targets that are the
// result of DependableName, and returns the list of targets that are missing.
func (g *Graph) ConnectTo(v dag.Vertex, targets []string) []string {
	g.once.Do(g.init)

	var missing []string
	for _, t := range targets {
		if dest := g.dependableMap[t]; dest != nil {
			g.Connect(dag.BasicEdge(v, dest))
		} else {
			missing = append(missing, t)
		}
	}

	return missing
}

// Dependable finds the vertices in the graph that have the given dependable
// names and returns them.
func (g *Graph) Dependable(n string) dag.Vertex {
	// TODO: do we need this?
	return nil
}

// Walk walks the graph with the given walker for callbacks. The graph
// will be walked with full parallelism, so the walker should expect
// to be called in concurrently.
func (g *Graph) Walk(walker GraphWalker) error {
	return g.walk(walker)
}

func (g *Graph) init() {
	if g.annotations == nil {
		g.annotations = make(map[dag.Vertex]map[string]interface{})
	}

	if g.dependableMap == nil {
		g.dependableMap = make(map[string]dag.Vertex)
	}
}

func (g *Graph) walk(walker GraphWalker) error {
	// The callbacks for enter/exiting a graph
	ctx := walker.EnterPath(g.Path)
	defer walker.ExitPath(g.Path)

	// Get the path for logs
	path := strings.Join(ctx.Path(), ".")

	// Walk the graph.
	var walkFn dag.WalkFunc
	walkFn = func(v dag.Vertex) (rerr error) {
		log.Printf("[DEBUG] vertex '%s.%s': walking", path, dag.VertexName(v))

		walker.EnterVertex(v)
		defer func() { walker.ExitVertex(v, rerr) }()

		// vertexCtx is the context that we use when evaluating. This
		// is normally the context of our graph but can be overridden
		// with a GraphNodeSubPath impl.
		vertexCtx := ctx
		if pn, ok := v.(GraphNodeSubPath); ok && len(pn.Path()) > 0 {
			vertexCtx = walker.EnterPath(normalizeModulePath(pn.Path()))
			defer walker.ExitPath(pn.Path())
		}

		// If the node is eval-able, then evaluate it.
		if ev, ok := v.(GraphNodeEvalable); ok {
			tree := ev.EvalTree()
			if tree == nil {
				panic(fmt.Sprintf(
					"%s.%s (%T): nil eval tree", path, dag.VertexName(v), v))
			}

			// Allow the walker to change our tree if needed. Eval,
			// then callback with the output.
			log.Printf("[DEBUG] vertex '%s.%s': evaluating", path, dag.VertexName(v))
			tree = walker.EnterEvalTree(v, tree)
			output, err := Eval(tree, vertexCtx)
			if rerr = walker.ExitEvalTree(v, output, err); rerr != nil {
				return
			}
		}

		// If the node is dynamically expanded, then expand it
		if ev, ok := v.(GraphNodeDynamicExpandable); ok {
			log.Printf(
				"[DEBUG] vertex '%s.%s': expanding/walking dynamic subgraph",
				path,
				dag.VertexName(v))
			g, err := ev.DynamicExpand(vertexCtx)
			if err != nil {
				rerr = err
				return
			}
			if g != nil {
				// Walk the subgraph
				if rerr = g.walk(walker); rerr != nil {
					return
				}
			}
		}

		// If the node has a subgraph, then walk the subgraph
		if sn, ok := v.(GraphNodeSubgraph); ok {
			log.Printf(
				"[DEBUG] vertex '%s.%s': walking subgraph",
				path,
				dag.VertexName(v))

			if rerr = sn.Subgraph().walk(walker); rerr != nil {
				return
			}
		}

		return nil
	}

	return g.AcyclicGraph.Walk(walkFn)
}

// GraphNodeAnnotationInit is an interface that allows a node to
// initialize it's annotations.
//
// AnnotationInit will be called _once_ when the node is added to a
// graph for the first time and is expected to return it's initial
// annotations.
type GraphNodeAnnotationInit interface {
	AnnotationInit() map[string]interface{}
}

// GraphNodeDependable is an interface which says that a node can be
// depended on (an edge can be placed between this node and another) according
// to the well-known name returned by DependableName.
//
// DependableName can return multiple names it is known by.
type GraphNodeDependable interface {
	DependableName() []string
}

// GraphNodeDependent is an interface which says that a node depends
// on another GraphNodeDependable by some name. By implementing this
// interface, Graph.ConnectDependents() can be called multiple times
// safely and efficiently.
type GraphNodeDependent interface {
	DependentOn() []string
}
<|endoftext|>


<commit_before>package instructions

import (
    "jvmgo/rtda"
    rtc "jvmgo/rtda/class"
)

// Check whether object is of given type
type checkcast struct {Index16Instruction}
func (self *checkcast) Execute(frame *rtda.Frame) {
    stack := frame.OperandStack()
    ref := stack.PopRef()
    stack.PushRef(ref)

    cp := frame.Method().Class().ConstantPool()
    cClass := cp.GetConstant(self.index).(rtc.ConstantClass)
    class := cClass.Class()
    if class.InitializationNotStarted() {
        // todo init class
        panic("class not initialized!")
    }

    // todo
    if !_instanceof(ref, class) {
        // todo ClassCastException
        panic("ClassCastException")
    }
}
<commit_msg>fix checkcast<commit_after>package instructions

import (
    "jvmgo/rtda"
    rtc "jvmgo/rtda/class"
)

// Check whether object is of given type
type checkcast struct {Index16Instruction}
func (self *checkcast) Execute(frame *rtda.Frame) {
    stack := frame.OperandStack()
    ref := stack.PopRef()
    stack.PushRef(ref)

    cp := frame.Method().Class().ConstantPool()
    cClass := cp.GetConstant(self.index).(*rtc.ConstantClass)
    class := cClass.Class()
    if class.InitializationNotStarted() {
        // todo init class
        panic("class not initialized!")
    }

    // todo
    if !_instanceof(ref, class) {
        // todo ClassCastException
        panic("ClassCastException")
    }
}
<|endoftext|>


<commit_before>package desugar

import (
	"fmt"

	"github.com/tisp-lang/tisp/src/lib/ast"
	"github.com/tisp-lang/tisp/src/lib/debug"
	"github.com/tisp-lang/tisp/src/lib/gensym"
)

func desugarMutualRecursionStatement(s interface{}) []interface{} {
	switch s := s.(type) {
	case ast.MutualRecursion:
		return desugarMutualRecursion(s)
	default:
		return []interface{}{s}
	}
}

func desugarMutualRecursion(mr ast.MutualRecursion) []interface{} {
	fs := mr.LetFunctions()
	unrecs := make([]interface{}, 0, len(fs))

	for _, f := range fs {
		arg := gensym.GenSym("mr", "functions", "argument")
		nameToIndex := indexLetFunctions(fs...)

		unrecs = append(
			unrecs,
			ast.NewLetFunction(
				gensym.GenSym("mr", "unrec", f.Name()),
				prependPosReqsToSig([]string{arg}, f.Signature()),
				replaceNames(arg, nameToIndex, f.Lets(), mr.DebugInfo()).([]interface{}),
				replaceNames(arg, deleteNamesDefinedByLets(nameToIndex, f.Lets()), f.Body(), mr.DebugInfo()),
				f.DebugInfo()))
	}

	recsList := gensym.GenSym("ys", "mr", "functions")
	recs := make([]interface{}, 0, len(fs))

	for i, f := range fs {
		recs = append(
			recs,
			ast.NewLetVar(
				f.Name(),
				ast.NewPApp(recsList, []interface{}{fmt.Sprint(i)}, f.DebugInfo())))
	}

	return append(
		unrecs,
		append(
			[]interface{}{ast.NewLetVar(
				recsList,
				ast.NewPApp("$ys", stringsToAnys(letStatementsToNames(unrecs)), mr.DebugInfo()))},
			recs...)...)
}

func indexLetFunctions(fs ...ast.LetFunction) map[string]int {
	nameToIndex := make(map[string]int)

	for i, f := range fs {
		nameToIndex[f.Name()] = i
	}

	if len(nameToIndex) != len(fs) {
		panic(fmt.Errorf("Duplicate names were found among mutually-recursive functions"))
	}

	return nameToIndex
}

func replaceNames(funcList string, nameToIndex map[string]int, x interface{}, di debug.Info) interface{} {
	replaceWithNameToIndex := func(nameToIndex map[string]int) func(x interface{}) interface{} {
		return func(x interface{}) interface{} {
			return replaceNames(funcList, nameToIndex, x, di)
		}
	}

	replace := replaceWithNameToIndex(nameToIndex)

	switch x := x.(type) {
	case []interface{}:
		ys := make([]interface{}, 0, len(x))

		for _, x := range x {
			ys = append(ys, replace(x))
		}

		return ys
	case ast.LetFunction:
		nameToIndex := copyNameToIndex(nameToIndex)

		delete(nameToIndex, x.Name())
		for n := range signatureToNames(x.Signature()) {
			delete(nameToIndex, n)
		}

		return ast.NewLetFunction(
			x.Name(),
			x.Signature(),
			replaceWithNameToIndex(nameToIndex)(x.Lets()).([]interface{}),
			replaceWithNameToIndex(deleteNamesDefinedByLets(nameToIndex, x.Lets()))(x.Body()),
			x.DebugInfo())
	case ast.LetVar:
		nameToIndex := copyNameToIndex(nameToIndex)
		delete(nameToIndex, x.Name())
		return ast.NewLetVar(x.Name(), replaceWithNameToIndex(nameToIndex)(x.Expr()))
	case ast.App:
		return ast.NewApp(replace(x.Function()), replace(x.Arguments()).(ast.Arguments), x.DebugInfo())
	case ast.Arguments:
		ps := make([]ast.PositionalArgument, 0, len(x.Positionals()))

		for _, p := range x.Positionals() {
			ps = append(ps, ast.NewPositionalArgument(replace(p.Value()), p.Expanded()))
		}

		ks := make([]ast.KeywordArgument, 0, len(x.Keywords()))

		for _, k := range x.Keywords() {
			ks = append(ks, ast.NewKeywordArgument(k.Name(), replace(k.Value())))
		}

		ds := make([]interface{}, 0, len(x.ExpandedDicts()))

		for _, d := range x.ExpandedDicts() {
			ds = append(ds, replace(d))
		}

		return ast.NewArguments(ps, ks, ds)
	case string:
		if i, ok := nameToIndex[x]; ok {
			return ast.NewPApp(funcList, []interface{}{fmt.Sprint(i)}, di)
		}

		return x
	}

	panic(fmt.Errorf("Invalid value: %#v", x))
}

func copyNameToIndex(ni map[string]int) map[string]int {
	new := make(map[string]int)

	for k, v := range ni {
		new[k] = v
	}

	return new
}

func deleteNamesDefinedByLets(ni map[string]int, ls []interface{}) map[string]int {
	ni = copyNameToIndex(ni)

	for _, n := range letStatementsToNames(ls) {
		delete(ni, n)
	}

	return ni
}

func letStatementsToNames(ls []interface{}) []string {
	ns := make([]string, 0, len(ls))

	for _, l := range ls {
		switch l := l.(type) {
		case ast.LetFunction:
			ns = append(ns, l.Name())
		case ast.LetVar:
			ns = append(ns, l.Name())
		default:
			panic("Unreachable")
		}
	}

	return ns
}

func stringsToAnys(ss []string) []interface{} {
	xs := make([]interface{}, 0, len(ss))

	for _, s := range ss {
		xs = append(xs, s)
	}

	return xs
}
<commit_msg>s/nameToIndex/n2i/g<commit_after>package desugar

import (
	"fmt"

	"github.com/tisp-lang/tisp/src/lib/ast"
	"github.com/tisp-lang/tisp/src/lib/debug"
	"github.com/tisp-lang/tisp/src/lib/gensym"
)

func desugarMutualRecursionStatement(s interface{}) []interface{} {
	switch s := s.(type) {
	case ast.MutualRecursion:
		return desugarMutualRecursion(s)
	default:
		return []interface{}{s}
	}
}

func desugarMutualRecursion(mr ast.MutualRecursion) []interface{} {
	fs := mr.LetFunctions()
	unrecs := make([]interface{}, 0, len(fs))

	for _, f := range fs {
		arg := gensym.GenSym("mr", "functions", "argument")
		n2i := indexLetFunctions(fs...)

		unrecs = append(
			unrecs,
			ast.NewLetFunction(
				gensym.GenSym("mr", "unrec", f.Name()),
				prependPosReqsToSig([]string{arg}, f.Signature()),
				replaceNames(arg, n2i, f.Lets(), mr.DebugInfo()).([]interface{}),
				replaceNames(arg, deleteNamesDefinedByLets(n2i, f.Lets()), f.Body(), mr.DebugInfo()),
				f.DebugInfo()))
	}

	recsList := gensym.GenSym("ys", "mr", "functions")
	recs := make([]interface{}, 0, len(fs))

	for i, f := range fs {
		recs = append(
			recs,
			ast.NewLetVar(
				f.Name(),
				ast.NewPApp(recsList, []interface{}{fmt.Sprint(i)}, f.DebugInfo())))
	}

	return append(
		unrecs,
		append(
			[]interface{}{ast.NewLetVar(
				recsList,
				ast.NewPApp("$ys", stringsToAnys(letStatementsToNames(unrecs)), mr.DebugInfo()))},
			recs...)...)
}

func indexLetFunctions(fs ...ast.LetFunction) map[string]int {
	n2i := make(map[string]int)

	for i, f := range fs {
		n2i[f.Name()] = i
	}

	if len(n2i) != len(fs) {
		panic(fmt.Errorf("Duplicate names were found among mutually-recursive functions"))
	}

	return n2i
}

func replaceNames(funcList string, n2i map[string]int, x interface{}, di debug.Info) interface{} {
	replaceWithNameToIndex := func(n2i map[string]int) func(x interface{}) interface{} {
		return func(x interface{}) interface{} {
			return replaceNames(funcList, n2i, x, di)
		}
	}

	replace := replaceWithNameToIndex(n2i)

	switch x := x.(type) {
	case []interface{}:
		ys := make([]interface{}, 0, len(x))

		for _, x := range x {
			ys = append(ys, replace(x))
		}

		return ys
	case ast.LetFunction:
		n2i := copyNameToIndex(n2i)

		delete(n2i, x.Name())
		for n := range signatureToNames(x.Signature()) {
			delete(n2i, n)
		}

		return ast.NewLetFunction(
			x.Name(),
			x.Signature(),
			replaceWithNameToIndex(n2i)(x.Lets()).([]interface{}),
			replaceWithNameToIndex(deleteNamesDefinedByLets(n2i, x.Lets()))(x.Body()),
			x.DebugInfo())
	case ast.LetVar:
		n2i := copyNameToIndex(n2i)
		delete(n2i, x.Name())
		return ast.NewLetVar(x.Name(), replaceWithNameToIndex(n2i)(x.Expr()))
	case ast.App:
		return ast.NewApp(replace(x.Function()), replace(x.Arguments()).(ast.Arguments), x.DebugInfo())
	case ast.Arguments:
		ps := make([]ast.PositionalArgument, 0, len(x.Positionals()))

		for _, p := range x.Positionals() {
			ps = append(ps, ast.NewPositionalArgument(replace(p.Value()), p.Expanded()))
		}

		ks := make([]ast.KeywordArgument, 0, len(x.Keywords()))

		for _, k := range x.Keywords() {
			ks = append(ks, ast.NewKeywordArgument(k.Name(), replace(k.Value())))
		}

		ds := make([]interface{}, 0, len(x.ExpandedDicts()))

		for _, d := range x.ExpandedDicts() {
			ds = append(ds, replace(d))
		}

		return ast.NewArguments(ps, ks, ds)
	case string:
		if i, ok := n2i[x]; ok {
			return ast.NewPApp(funcList, []interface{}{fmt.Sprint(i)}, di)
		}

		return x
	}

	panic(fmt.Errorf("Invalid value: %#v", x))
}

func copyNameToIndex(ni map[string]int) map[string]int {
	new := make(map[string]int)

	for k, v := range ni {
		new[k] = v
	}

	return new
}

func deleteNamesDefinedByLets(ni map[string]int, ls []interface{}) map[string]int {
	ni = copyNameToIndex(ni)

	for _, n := range letStatementsToNames(ls) {
		delete(ni, n)
	}

	return ni
}

func letStatementsToNames(ls []interface{}) []string {
	ns := make([]string, 0, len(ls))

	for _, l := range ls {
		switch l := l.(type) {
		case ast.LetFunction:
			ns = append(ns, l.Name())
		case ast.LetVar:
			ns = append(ns, l.Name())
		default:
			panic("Unreachable")
		}
	}

	return ns
}

func stringsToAnys(ss []string) []interface{} {
	xs := make([]interface{}, 0, len(ss))

	for _, s := range ss {
		xs = append(xs, s)
	}

	return xs
}
<|endoftext|>


<commit_before>package cache

import (
	"sync"

	"github.com/lomik/go-carbon/points"
)

type WriteoutQueue struct {
	sync.RWMutex
	cache *Cache

	// Writeout queue. Usage:
	// q := <- queue
	// p := cache.Pop(q.Metric)
	queue   chan *points.Points
	rebuild func() chan bool // return chan waiting for complete
}

func NewWriteoutQueue(cache *Cache) *WriteoutQueue {
	q := &WriteoutQueue{
		cache: cache,
		queue: nil,
	}
	q.rebuild = q.makeRebuildCallback()
	return q
}

func (q *WriteoutQueue) makeRebuildCallback() func() chan bool {
	var nextRebuildOnce sync.Once
	nextRebuildComplete := make(chan bool)

	nextRebuild := func() chan bool {
		// next rebuild
		nextRebuildOnce.Do(func() {
			q.update()
			close(nextRebuildComplete)
		})

		return nextRebuildComplete
	}

	return nextRebuild
}

func (q *WriteoutQueue) update() {
	queue := q.cache.makeQueue()

	q.Lock()
	q.queue = queue
	q.rebuild = q.makeRebuildCallback()
	q.Unlock()
}

func (q *WriteoutQueue) Get(abort chan bool) *points.Points {
QueueLoop:
	for {
		q.RLock()
		queue := q.queue
		rebuild := q.rebuild
		q.RUnlock()

	FetchLoop:
		for {
			select {
			case qp := <-queue:
				// pop from cache
				if p, exists := q.cache.Pop(qp.Metric); exists {
					return p
				}
				continue FetchLoop
			case <-abort:
				return nil
			default:
				// queue is empty, create new
				select {
				case <-rebuild():
					// wait for rebuild
					continue QueueLoop
				case <-abort:
					return nil
				}
			}
		}
	}
}
<commit_msg>fix huge cpu usage on empty cache<commit_after>package cache

import (
	"sync"
	"time"

	"github.com/Sirupsen/logrus"
	"github.com/lomik/go-carbon/points"
)

type WriteoutQueue struct {
	sync.RWMutex
	cache *Cache

	// Writeout queue. Usage:
	// q := <- queue
	// p := cache.Pop(q.Metric)
	queue   chan *points.Points
	rebuild func() chan bool // return chan waiting for complete
}

func NewWriteoutQueue(cache *Cache) *WriteoutQueue {
	q := &WriteoutQueue{
		cache: cache,
		queue: nil,
	}
	q.rebuild = q.makeRebuildCallback(time.Time{})
	return q
}

func (q *WriteoutQueue) makeRebuildCallback(nextRebuildTime time.Time) func() chan bool {
	var nextRebuildOnce sync.Once
	nextRebuildComplete := make(chan bool)

	nextRebuild := func() chan bool {
		// next rebuild
		nextRebuildOnce.Do(func() {
			now := time.Now()
			logrus.Debugf("nextRebuildOnce.Do: %#v %#v", now.String(), nextRebuildTime.String())
			if now.Before(nextRebuildTime) {
				sleepTime := nextRebuildTime.Sub(now)
				logrus.Debugf("sleep %s before rebuild", sleepTime.String())
				time.Sleep(sleepTime)
			}
			q.update()
			close(nextRebuildComplete)
		})

		return nextRebuildComplete
	}

	return nextRebuild
}

func (q *WriteoutQueue) update() {
	queue := q.cache.makeQueue()

	q.Lock()
	q.queue = queue
	q.rebuild = q.makeRebuildCallback(time.Now().Add(100 * time.Millisecond))
	q.Unlock()
}

func (q *WriteoutQueue) Get(abort chan bool) *points.Points {
QueueLoop:
	for {
		q.RLock()
		queue := q.queue
		rebuild := q.rebuild
		q.RUnlock()

	FetchLoop:
		for {
			select {
			case qp := <-queue:
				// pop from cache
				if p, exists := q.cache.Pop(qp.Metric); exists {
					return p
				}
				continue FetchLoop
			case <-abort:
				return nil
			default:
				// queue is empty, create new
				select {
				case <-rebuild():
					// wait for rebuild
					continue QueueLoop
				case <-abort:
					return nil
				}
			}
		}
	}
}
<|endoftext|>


<commit_before>// run

// Check conversion of constant to float32/float64 near min/max boundaries.

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

package main

import (
	"fmt"
)

const (
	m32bits   = 23  // number of float32 mantissa bits
	e32max    = 127 // max. float32 exponent
	maxExp32  = e32max - m32bits
	maxMant32 = 1<<(m32bits+1) - 1

	maxFloat32_0 = (maxMant32 - 0) << maxExp32
	maxFloat32_1 = (maxMant32 - 1) << maxExp32
	maxFloat32_2 = (maxMant32 - 2) << maxExp32
)

func init() {
	if maxExp32 != 104 {
		panic("incorrect maxExp32")
	}
	if maxMant32 != 16777215 {
		panic("incorrect maxMant32")
	}
	if maxFloat32_0 != 340282346638528859811704183484516925440 {
		panic("incorrect maxFloat32_0")
	}
}

const (
	m64bits   = 52   // number of float64 mantissa bits
	e64max    = 1023 // max. float64 exponent
	maxExp64  = e64max - m64bits
	maxMant64 = 1<<(m64bits+1) - 1

	// These expressions are not permitted due to implementation restrictions.
	// maxFloat64_0 = (maxMant64-0) << maxExp64
	// maxFloat64_1 = (maxMant64-1) << maxExp64
	// maxFloat64_2 = (maxMant64-2) << maxExp64

	// These equivalent values were computed using math/big.
	maxFloat64_0 = 1.7976931348623157e308
	maxFloat64_1 = 1.7976931348623155e308
	maxFloat64_2 = 1.7976931348623153e308
)

func init() {
	if maxExp64 != 971 {
		panic("incorrect maxExp64")
	}
	if maxMant64 != 9007199254740991 {
		panic("incorrect maxMant64")
	}
}

var cvt = []struct {
	val    interface{}
	binary string
}{

	{float32(maxFloat32_0), fmt.Sprintf("%dp+%d", maxMant32-0, maxExp32)},
	{float32(maxFloat32_1), fmt.Sprintf("%dp+%d", maxMant32-1, maxExp32)},
	{float32(maxFloat32_2), fmt.Sprintf("%dp+%d", maxMant32-2, maxExp32)},

	{float64(maxFloat64_0), fmt.Sprintf("%dp+%d", maxMant64-0, maxExp64)},
	{float64(maxFloat64_1), fmt.Sprintf("%dp+%d", maxMant64-1, maxExp64)},
	{float64(maxFloat64_2), fmt.Sprintf("%dp+%d", maxMant64-2, maxExp64)},

	{float32(-maxFloat32_0), fmt.Sprintf("-%dp+%d", maxMant32-0, maxExp32)},
	{float32(-maxFloat32_1), fmt.Sprintf("-%dp+%d", maxMant32-1, maxExp32)},
	{float32(-maxFloat32_2), fmt.Sprintf("-%dp+%d", maxMant32-2, maxExp32)},

	{float64(-maxFloat64_0), fmt.Sprintf("-%dp+%d", maxMant64-0, maxExp64)},
	{float64(-maxFloat64_1), fmt.Sprintf("-%dp+%d", maxMant64-1, maxExp64)},
	{float64(-maxFloat64_2), fmt.Sprintf("-%dp+%d", maxMant64-2, maxExp64)},
}

func main() {
	bug := false
	for i, c := range cvt {
		s := fmt.Sprintf("%b", c.val)
		if s != c.binary {
			if !bug {
				bug = true
				fmt.Println("BUG")
			}
			fmt.Printf("#%d: have %s, want %s\n", i, s, c.binary)
		}
	}
}
<commit_msg>test/float_lit2.go: fix constants for 386 platforms (fix build)<commit_after>// run

// Check conversion of constant to float32/float64 near min/max boundaries.

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

package main

import (
	"fmt"
)

const (
	m32bits   = 23  // number of float32 mantissa bits
	e32max    = 127 // max. float32 exponent
	maxExp32  = e32max - m32bits
	maxMant32 = 1<<(m32bits+1) - 1

	maxFloat32_0 = (maxMant32 - 0) << maxExp32
	maxFloat32_1 = (maxMant32 - 1) << maxExp32
	maxFloat32_2 = (maxMant32 - 2) << maxExp32
)

func init() {
	if maxExp32 != 104 {
		panic("incorrect maxExp32")
	}
	if maxMant32 != 16777215 {
		panic("incorrect maxMant32")
	}
	if maxFloat32_0 != 340282346638528859811704183484516925440 {
		panic("incorrect maxFloat32_0")
	}
}

const (
	m64bits   = 52   // number of float64 mantissa bits
	e64max    = 1023 // max. float64 exponent
	maxExp64  = e64max - m64bits
	maxMant64 = 1<<(m64bits+1) - 1

	// These expressions are not permitted due to implementation restrictions.
	// maxFloat64_0 = (maxMant64-0) << maxExp64
	// maxFloat64_1 = (maxMant64-1) << maxExp64
	// maxFloat64_2 = (maxMant64-2) << maxExp64

	// These equivalent values were computed using math/big.
	maxFloat64_0 = 1.7976931348623157e308
	maxFloat64_1 = 1.7976931348623155e308
	maxFloat64_2 = 1.7976931348623153e308
)

func init() {
	if maxExp64 != 971 {
		panic("incorrect maxExp64")
	}
	if maxMant64 != 9007199254740991 {
		panic("incorrect maxMant64")
	}
}

var cvt = []struct {
	val    interface{}
	binary string
}{

	{float32(maxFloat32_0), fmt.Sprintf("%dp+%d", int32(maxMant32-0), maxExp32)},
	{float32(maxFloat32_1), fmt.Sprintf("%dp+%d", int32(maxMant32-1), maxExp32)},
	{float32(maxFloat32_2), fmt.Sprintf("%dp+%d", int32(maxMant32-2), maxExp32)},

	{float64(maxFloat64_0), fmt.Sprintf("%dp+%d", int64(maxMant64-0), maxExp64)},
	{float64(maxFloat64_1), fmt.Sprintf("%dp+%d", int64(maxMant64-1), maxExp64)},
	{float64(maxFloat64_2), fmt.Sprintf("%dp+%d", int64(maxMant64-2), maxExp64)},

	{float32(-maxFloat32_0), fmt.Sprintf("-%dp+%d", int32(maxMant32-0), maxExp32)},
	{float32(-maxFloat32_1), fmt.Sprintf("-%dp+%d", int32(maxMant32-1), maxExp32)},
	{float32(-maxFloat32_2), fmt.Sprintf("-%dp+%d", int32(maxMant32-2), maxExp32)},

	{float64(-maxFloat64_0), fmt.Sprintf("-%dp+%d", int64(maxMant64-0), maxExp64)},
	{float64(-maxFloat64_1), fmt.Sprintf("-%dp+%d", int64(maxMant64-1), maxExp64)},
	{float64(-maxFloat64_2), fmt.Sprintf("-%dp+%d", int64(maxMant64-2), maxExp64)},
}

func main() {
	bug := false
	for i, c := range cvt {
		s := fmt.Sprintf("%b", c.val)
		if s != c.binary {
			if !bug {
				bug = true
				fmt.Println("BUG")
			}
			fmt.Printf("#%d: have %s, want %s\n", i, s, c.binary)
		}
	}
}
<|endoftext|>


<commit_before>package parse_test

import (
	. "github.com/eaciit/hdc/hive"
	"log"
	"testing"
	"time"
)

var h *Hive

type Sample7 struct {
	Code        string `tag_name:"code"`
	Description string `tag_name:"description"`
	Total_emp   int    `tag_name:"total_emp"`
	Salary      int    `tag_name:"salary"`
}

type SampleParse struct {
	Code        string    `tag_name:"code"`
	Description string    `tag_name:"description"`
	Total_emp   int       `tag_name:"total_emp"`
	Salary      int       `tag_name:"salary"`
	Date        time.Time `tag_name:"date"`
}

func TestParseOutput(t *testing.T) {
	res := []string{"'00-0000','All Occupations CSV','134354250','40690','2014-05-01'", "'00-0000','All Occupations NEXT','134354250','40690','2014-05-01'"}
	tmp := []SampleParse{}
	e := Parse([]string{}, res, &tmp, "csv", "yyyy-MM-dd")
	log.Println(tmp)

	if e != nil {
		t.Error(e)
	}

	res = []string{"00-0000,All Occupations CSV2,134354250,40690,2014-Oct-01", "00-0000,All Occupations CSV2 NEXT,134354250,40690,2014-Dec-01"}
	tmp = []SampleParse{}
	e = Parse([]string{}, res, &tmp, "csv", "yyyy-MMM-dd")
	log.Println(tmp)

	if e != nil {
		t.Error(e)
	}

	res = []string{"'00-0000'\t'All Occupations TSV'\t'134354250'\t'40690'\t'2014-Dec-05'", "'00-0000'\t'All Occupations TSV NEXT'\t'134354250'\t'40690'\t'2014-Dec-05'"}
	tmp = []SampleParse{}
	e = Parse([]string{}, res, &tmp, "tsv", "yyyy-MMM-dd")
	log.Println(tmp)

	if e != nil {
		t.Error(e)
	}

	resj := []string{"{ \"code\" : \"00-0000\" , \"description\" : \"All Occupations JSON\" "}
	tmpj := []SampleParse{}
	e = Parse([]string{}, resj, &tmpj, "json", "")
	log.Println(tmpj)

	if e != nil {
		t.Error(e)
	}

	resj = []string{", \"total_emp\" : 134354, \"salary\" : 40690,\"Date\" : \"2012-04-23T18:25:43Z\" },{ \"code\" : \"00-2222\""}
	tmpj = []SampleParse{}
	e = Parse([]string{}, resj, &tmpj, "json", "")
	log.Println(tmpj)

	if e != nil {
		t.Error(e)
	}

	resj = []string{",\"description\" : \"All Occupations INTERFACE\" , \"total_emp\" : 222, \"salary\" : 2222,\"Date\" : \"2012-05-23T18:25:43Z\" },{ \"code\" : \"00-2222\",\"description\" : \"All Occupations NEXT\" , \"total_emp\" : 222, \"salary\" : 2222,\"Date\" : \"2012-05-23T18:25:43Z\" }", "{ \"code\" : \"00-2222\",\"description\" : \"All Occupations Last\" , \"total_emp\" : 222, \"salary\" : 2222,\"Date\" : \"2012-05-23T18:25:43Z\" }"}
	var tmpx interface{}
	e = Parse([]string{}, resj, &tmpx, "json", "")
	log.Println(tmpx)

	if e != nil {
		t.Error(e)
	}

}

func TestParseOutputOneStruct(t *testing.T) {

	res := "'00-0000','All Occupations CSV','134354250','40690','2014-05-01'"
	var tmp interface{}
	e := Parse([]string{"code", "desc", "emp", "sal", "date"}, res, &tmp, "csv", "yyyy-MM-dd")
	log.Println(tmp)

	if e != nil {
		t.Error(e)
	}

	res = "00-0000,All Occupations CSV2,134354250,40690,2014-05-01"
	tmpt := SampleParse{}
	e = Parse([]string{}, res, &tmpt, "csv", "yyyy-MM-dd")
	log.Println(tmpt)

	if e != nil {
		t.Error(e)
	}

	res = "'00-0000'\t'All Occupations TSV'\t'13.4354.250'\t'40690'\t'2014-Dec-05'"
	var tmpz interface{}
	e = Parse([]string{"code", "desc", "emp", "sal", "date"}, res, &tmpz, "tsv", "yyyy-MM-dd")
	log.Println(tmpz)

	if e != nil {
		t.Error(e)
	}

	//try to parse json with different line
	resj := "{ \"code\" : \"00-0000\" , \"description\" : \"All Occupations JSON\" "
	tmpj := SampleParse{}
	e = Parse([]string{}, resj, &tmpj, "json", "")
	log.Println(tmpj)

	if e != nil {
		t.Error(e)
	}

	resj = ", \"total_emp\" : 134354, \"salary\" : 40690,\"Date\" : \"2012-04-23T18:25:43Z\" },{ \"code\" : \"00-2222\""
	tmpj = SampleParse{}
	e = Parse([]string{}, resj, &tmpj, "json", "")
	log.Println(tmpj)

	if e != nil {
		t.Error(e)
	}

	resj = ",\"description\" : \"All Occupations INTERFACE\" , \"total_emp\" : 222, \"salary\" : 2222,\"Date\" : \"2012-05-23T18:25:43Z\" },{ \"code\" : \"00-2222\",\"description\" : \"All Occupations NEXT\" , \"total_emp\" : 222, \"salary\" : 2222,\"Date\" : \"2012-05-23T18:25:43Z\" }"
	var tmpx interface{}
	e = Parse([]string{}, resj, &tmpx, "json", "")
	log.Println(tmpx)

	if e != nil {
		t.Error(e)
	}

}
<commit_msg>add note<commit_after>package parse_test

import (
	. "github.com/eaciit/hdc/hive"
	"log"
	"testing"
	"time"
)

var h *Hive

type SampleParse struct {
	Code        string    `tag_name:"code"`
	Description string    `tag_name:"description"`
	Total_emp   int       `tag_name:"total_emp"`
	Salary      int       `tag_name:"salary"`
	Date        time.Time `tag_name:"date"`
}

func TestParseOutput(t *testing.T) {
	res := []string{"'00-0000','All Occupations CSV','134354250','40690','2014-05-01'", "'00-0000','All Occupations NEXT','134354250','40690','2014-05-01'"}
	tmp := []SampleParse{}
	e := Parse([]string{}, res, &tmp, "csv", "yyyy-MM-dd")
	log.Println(tmp)

	if e != nil {
		t.Error(e)
	}

	res = []string{"00-0000,All Occupations CSV2,134354250,40690,2014-Oct-01", "00-0000,All Occupations CSV2 NEXT,134354250,40690,2014-Dec-01"}
	tmp = []SampleParse{}
	e = Parse([]string{}, res, &tmp, "csv", "yyyy-MMM-dd")
	log.Println(tmp)

	if e != nil {
		t.Error(e)
	}

	res = []string{"'00-0000'\t'All Occupations TSV'\t'134354250'\t'40690'\t'2014-Dec-05'", "'00-0000'\t'All Occupations TSV NEXT'\t'134354250'\t'40690'\t'2014-Dec-05'"}
	tmp = []SampleParse{}
	e = Parse([]string{}, res, &tmp, "tsv", "yyyy-MMM-dd")
	log.Println(tmp)

	if e != nil {
		t.Error(e)
	}

	resj := []string{"{ \"code\" : \"00-0000\" , \"description\" : \"All Occupations JSON\" "}
	tmpj := []SampleParse{}
	e = Parse([]string{}, resj, &tmpj, "json", "")
	log.Println(tmpj)

	if e != nil {
		t.Error(e)
	}

	resj = []string{", \"total_emp\" : 134354, \"salary\" : 40690,\"Date\" : \"2012-04-23T18:25:43Z\" },{ \"code\" : \"00-2222\""}
	tmpj = []SampleParse{}
	e = Parse([]string{}, resj, &tmpj, "json", "")
	log.Println(tmpj)

	if e != nil {
		t.Error(e)
	}

	resj = []string{",\"description\" : \"All Occupations INTERFACE\" , \"total_emp\" : 222, \"salary\" : 2222,\"Date\" : \"2012-05-23T18:25:43Z\" },{ \"code\" : \"00-2222\",\"description\" : \"All Occupations NEXT\" , \"total_emp\" : 222, \"salary\" : 2222,\"Date\" : \"2012-05-23T18:25:43Z\" }", "{ \"code\" : \"00-2222\",\"description\" : \"All Occupations Last\" , \"total_emp\" : 222, \"salary\" : 2222,\"Date\" : \"2012-05-23T18:25:43Z\" }"}
	var tmpx interface{}
	e = Parse([]string{}, resj, &tmpx, "json", "")
	log.Println(tmpx)

	if e != nil {
		t.Error(e)
	}

}

func TestParseOutputOneStruct(t *testing.T) {

	//require fill header, because using interface as parameter
	res := "'00-0000','All Occupations CSV','134354250','40690','2014-05-01'"
	var tmp interface{}
	e := Parse([]string{"code", "desc", "emp", "sal", "date"}, res, &tmp, "csv", "yyyy-MM-dd")
	log.Println(tmp)

	if e != nil {
		t.Error(e)
	}

	res = "00-0000,All Occupations CSV2,134354250,40690,2014-05-01"
	tmpt := SampleParse{}
	e = Parse([]string{}, res, &tmpt, "csv", "yyyy-MM-dd")
	log.Println(tmpt)

	if e != nil {
		t.Error(e)
	}

	res = "'00-0000'\t'All Occupations TSV'\t'13.4354.250'\t'40690'\t'2014-Dec-05'"
	var tmpz interface{}
	e = Parse([]string{"code", "desc", "emp", "sal", "date"}, res, &tmpz, "tsv", "yyyy-MM-dd")
	log.Println(tmpz)

	if e != nil {
		t.Error(e)
	}

	//try to parse json with different line
	resj := "{ \"code\" : \"00-0000\" , \"description\" : \"All Occupations JSON\" "
	tmpj := SampleParse{}
	e = Parse([]string{}, resj, &tmpj, "json", "")
	log.Println(tmpj)

	if e != nil {
		t.Error(e)
	}

	resj = ", \"total_emp\" : 134354, \"salary\" : 40690,\"Date\" : \"2012-04-23T18:25:43Z\" },{ \"code\" : \"00-2222\""
	tmpj = SampleParse{}
	e = Parse([]string{}, resj, &tmpj, "json", "")
	log.Println(tmpj)

	if e != nil {
		t.Error(e)
	}

	resj = ",\"description\" : \"All Occupations INTERFACE\" , \"total_emp\" : 222, \"salary\" : 2222,\"Date\" : \"2012-05-23T18:25:43Z\" },{ \"code\" : \"00-2222\",\"description\" : \"All Occupations NEXT\" , \"total_emp\" : 222, \"salary\" : 2222,\"Date\" : \"2012-05-23T18:25:43Z\" }"
	var tmpx interface{}
	e = Parse([]string{}, resj, &tmpx, "json", "")
	log.Println(tmpx)

	if e != nil {
		t.Error(e)
	}

}
<|endoftext|>


<commit_before>package goar

import (
	"fmt"
	"strings"
)

type Select struct {
	table   string
	columns []string
	where   *condition
}

func (s *Select) Table(table string) *Select {
	s.table = table
	return s
}

func (s *Select) Columns(columns []string) *Select {
	s.columns = columns
	return s
}

func (s *Select) Where(cond string, args ...interface{}) *Select {
	if s.where == nil {
		s.where = &condition{phrase: "WHERE"}
	}
	s.where.addExpression(cond, args...)
	return s
}

func (s *Select) And(cond string, args ...interface{}) *Select {
	return s.Where(cond, args...)
}

func (s *Select) Build() (query string, binds []interface{}) {
	baseQuery := fmt.Sprintf("SELECT %s FROM %s", strings.Join(s.columns, ", "), s.table)
	whereQuery, whereBinds := s.where.build()
	return baseQuery + whereQuery, whereBinds
}
<commit_msg>Changed columns parameter type.<commit_after>package goar

import (
	"fmt"
	"strings"
)

type Select struct {
	table   string
	columns []string
	where   *condition
}

func (s *Select) Table(table string) *Select {
	s.table = table
	return s
}

func (s *Select) Columns(columns ...string) *Select {
	s.columns = columns
	return s
}

func (s *Select) Where(cond string, args ...interface{}) *Select {
	if s.where == nil {
		s.where = &condition{phrase: "WHERE"}
	}
	s.where.addExpression(cond, args...)
	return s
}

func (s *Select) And(cond string, args ...interface{}) *Select {
	return s.Where(cond, args...)
}

func (s *Select) Build() (query string, binds []interface{}) {
	baseQuery := fmt.Sprintf("SELECT %s FROM %s", strings.Join(s.columns, ", "), s.table)
	whereQuery, whereBinds := s.where.build()
	return baseQuery + whereQuery, whereBinds
}
<|endoftext|>


<commit_before>package semver

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

// Represents a semantic version.
// http://semver.org/

// Version represents a Semantic Version.
type Version interface {
	// Major gets the major version.
	Major() int

	// Minor gets the minor version.
	Minor() int

	// Patch gets the patch version.
	Patch() int

	// PreRelease gets the pre-release build metadata.
	PreRelease() []string

	// Build gets the build metadata.
	Build() []string

	// Same determines whether or not this version is equal to another version. Note: build metadata may differ.
	Same(v Version) bool

	// Before determines whether or not this version is a precursor to another version.
	Before(v Version) bool

	// After determines whether or not this version is a successor to another version.
	After(v Version) bool

	// String gets the string representation of this version.
	String() string
}

// Regex used for parsing a semantic version (2.0) as specified by http://semver.org/
var version20Regexp = regexp.MustCompile("^(\\d+)\\.(\\d+)\\.(\\d+)(\\-(([0-9A-Za-z-]+)(\\.)?)+)?(\\+(([0-9A-Za-z-]+)(\\.)?)+)?$")

// Version represents the structure of the Semantic Versioning 2.0 scheme.
type version20 struct {
	major      int
	minor      int
	patch      int
	preRelease []string
	build      []string
}

// Parse metadata such as pre-release and build of a version.
func parseMetadata(metadata string) ([]string, error) {
	if len(metadata) == 0 {
		return []string{}, nil
	}

	if metadata[0] != '-' && metadata[0] != '+' {
		return nil, errors.New("Invalid metadata indicator sign '" + string(metadata[0]) + "'.")
	}

	if metadata[len(metadata)-1] == '.' {
		return nil, errors.New("Metadata cannot end with dot.")
	}

	return strings.Split(metadata[1:], "."), nil
}

// Parse tries to parse a raw value. Returns error if it fails.
func Parse(value string) (Version, error) {
	groups := version20Regexp.FindAllStringSubmatch(value, -1)

	if len(groups) == 0 {
		return nil, errors.New("Invalid version format.")
	}

	matches := groups[0]

	major, _ := strconv.ParseInt(matches[1], 10, 32)
	minor, _ := strconv.ParseInt(matches[2], 10, 32)
	patch, _ := strconv.ParseInt(matches[3], 10, 32)

	preRelease, err := parseMetadata(matches[4])

	if err != nil {
		return nil, errors.New("Invalid version format.")
	}

	build, err := parseMetadata(matches[8])

	if err != nil {
		return nil, errors.New("Invalid version format.")
	}

	// Version cannot be zero.
	if (major + minor + patch) == 0 {
		return nil, errors.New("Invalid version format.")
	}

	return &version20{
		major:      int(major),
		minor:      int(minor),
		patch:      int(patch),
		preRelease: preRelease,
		build:      build,
	}, nil
}

// New creates a new version given a raw value. Panics if wrong format.
func New(version string) Version {
	result, err := Parse(version)

	if err != nil {
		panic(err.Error())
	}

	return result
}

func (v *version20) Major() int {
	return v.major
}

func (v *version20) Minor() int {
	return v.minor
}

func (v *version20) Patch() int {
	return v.patch
}

func (v *version20) PreRelease() []string {
	return v.preRelease
}

func (v *version20) Build() []string {
	return v.build
}

// Compares pre-releases from one version with pre-releases of another.
func comparePreReleases(a []string, b []string) int {
	lenA := len(a)
	lenB := len(b)

	if lenA == 0 && lenB == 0 {
		return 0
	} else if lenA == 0 {
		return 1
	} else if lenB == 0 {
		return -1
	}

	lim := lenA

	if lenB < lenA {
		lim = lenB
	}

	for i := 0; i < lim; i++ {
		preA := a[i]
		preB := b[i]
		if preA == preB {
			continue
		} else if preA > preB {
			return 1
		} else { // preA < preB
			return -1
		}
	}

	if lenA > lenB {
		return 1
	}

	return 0
}

// Compares two versions and returns an int indicating the relation of A to B.
// The result will be 0 if a==b, -1 if a < b, and +1 if a > b.
func compareVersions(a Version, b Version) int {
	if a.Major() < b.Major() {
		return -1
	} else if a.Major() > b.Major() {
		return 1
	}

	if a.Minor() < b.Minor() {
		return -1
	} else if a.Minor() > b.Minor() {
		return 1
	}

	if a.Patch() < b.Patch() {
		return -1
	} else if a.Patch() > b.Patch() {
		return 1
	}

	return comparePreReleases(a.PreRelease(), b.PreRelease())
}

func (v *version20) Same(t Version) bool {
	return compareVersions(v, t) == 0
}

func (v *version20) Before(t Version) bool {
	return compareVersions(v, t) < 0
}

func (v *version20) After(t Version) bool {
	return compareVersions(v, t) > 0
}

func (v *version20) String() string {
	result := fmt.Sprintf("%d.%d.%d", v.major, v.minor, v.patch)

	if len(v.preRelease) > 0 {
		result += "-" + strings.Join(v.preRelease, ".")
	}

	if len(v.build) > 0 {
		result += "+" + strings.Join(v.build, ".")
	}

	return result
}
<commit_msg>docs(godoc): fixed typo<commit_after>package semver

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

// Represents a semantic version.
// http://semver.org/

// Version represents a Semantic Version.
type Version interface {
	// Major gets the major version.
	Major() int

	// Minor gets the minor version.
	Minor() int

	// Patch gets the patch version.
	Patch() int

	// PreRelease gets the pre-release metadata.
	PreRelease() []string

	// Build gets the build metadata.
	Build() []string

	// Same determines whether or not this version is equal to another version. Note: build metadata may differ.
	Same(v Version) bool

	// Before determines whether or not this version is a precursor to another version.
	Before(v Version) bool

	// After determines whether or not this version is a successor to another version.
	After(v Version) bool

	// String gets the string representation of this version.
	String() string
}

// Regex used for parsing a semantic version (2.0) as specified by http://semver.org/
var version20Regexp = regexp.MustCompile("^(\\d+)\\.(\\d+)\\.(\\d+)(\\-(([0-9A-Za-z-]+)(\\.)?)+)?(\\+(([0-9A-Za-z-]+)(\\.)?)+)?$")

// Version represents the structure of the Semantic Versioning 2.0 scheme.
type version20 struct {
	major      int
	minor      int
	patch      int
	preRelease []string
	build      []string
}

// Parse metadata such as pre-release and build of a version.
func parseMetadata(metadata string) ([]string, error) {
	if len(metadata) == 0 {
		return []string{}, nil
	}

	if metadata[0] != '-' && metadata[0] != '+' {
		return nil, errors.New("Invalid metadata indicator sign '" + string(metadata[0]) + "'.")
	}

	if metadata[len(metadata)-1] == '.' {
		return nil, errors.New("Metadata cannot end with dot.")
	}

	return strings.Split(metadata[1:], "."), nil
}

// Parse tries to parse a raw value. Returns error if it fails.
func Parse(value string) (Version, error) {
	groups := version20Regexp.FindAllStringSubmatch(value, -1)

	if len(groups) == 0 {
		return nil, errors.New("Invalid version format.")
	}

	matches := groups[0]

	major, _ := strconv.ParseInt(matches[1], 10, 32)
	minor, _ := strconv.ParseInt(matches[2], 10, 32)
	patch, _ := strconv.ParseInt(matches[3], 10, 32)

	preRelease, err := parseMetadata(matches[4])

	if err != nil {
		return nil, errors.New("Invalid version format.")
	}

	build, err := parseMetadata(matches[8])

	if err != nil {
		return nil, errors.New("Invalid version format.")
	}

	// Version cannot be zero.
	if (major + minor + patch) == 0 {
		return nil, errors.New("Invalid version format.")
	}

	return &version20{
		major:      int(major),
		minor:      int(minor),
		patch:      int(patch),
		preRelease: preRelease,
		build:      build,
	}, nil
}

// New creates a new version given a raw value. Panics if wrong format.
func New(version string) Version {
	result, err := Parse(version)

	if err != nil {
		panic(err.Error())
	}

	return result
}

func (v *version20) Major() int {
	return v.major
}

func (v *version20) Minor() int {
	return v.minor
}

func (v *version20) Patch() int {
	return v.patch
}

func (v *version20) PreRelease() []string {
	return v.preRelease
}

func (v *version20) Build() []string {
	return v.build
}

// Compares pre-releases from one version with pre-releases of another.
func comparePreReleases(a []string, b []string) int {
	lenA := len(a)
	lenB := len(b)

	if lenA == 0 && lenB == 0 {
		return 0
	} else if lenA == 0 {
		return 1
	} else if lenB == 0 {
		return -1
	}

	lim := lenA

	if lenB < lenA {
		lim = lenB
	}

	for i := 0; i < lim; i++ {
		preA := a[i]
		preB := b[i]
		if preA == preB {
			continue
		} else if preA > preB {
			return 1
		} else { // preA < preB
			return -1
		}
	}

	if lenA > lenB {
		return 1
	}

	return 0
}

// Compares two versions and returns an int indicating the relation of A to B.
// The result will be 0 if a==b, -1 if a < b, and +1 if a > b.
func compareVersions(a Version, b Version) int {
	if a.Major() < b.Major() {
		return -1
	} else if a.Major() > b.Major() {
		return 1
	}

	if a.Minor() < b.Minor() {
		return -1
	} else if a.Minor() > b.Minor() {
		return 1
	}

	if a.Patch() < b.Patch() {
		return -1
	} else if a.Patch() > b.Patch() {
		return 1
	}

	return comparePreReleases(a.PreRelease(), b.PreRelease())
}

func (v *version20) Same(t Version) bool {
	return compareVersions(v, t) == 0
}

func (v *version20) Before(t Version) bool {
	return compareVersions(v, t) < 0
}

func (v *version20) After(t Version) bool {
	return compareVersions(v, t) > 0
}

func (v *version20) String() string {
	result := fmt.Sprintf("%d.%d.%d", v.major, v.minor, v.patch)

	if len(v.preRelease) > 0 {
		result += "-" + strings.Join(v.preRelease, ".")
	}

	if len(v.build) > 0 {
		result += "+" + strings.Join(v.build, ".")
	}

	return result
}
<|endoftext|>


<commit_before>package semver

import (
	"fmt"
	"regexp"
	"strings"
)

// Version represents a semantic version of a crate package.
type SemVer struct {
	// The major version. This is an integer that increments when a backward-
	// incompatible change is made to a project's API.
	Major string

	// The minor version. Used to indicate feature addition.
	Minor string

	// The patch number. This is typically used to indicate bug fixes that
	// enhance existing functionality without changing or adding any API's.
	Patch string

	// The (optional) pre-release version from point 9 of semver 2.0.
	PreRel string

	// A string of optional build metadata per point 10 of semver 2.0.
	Build string
}

// String will return a flat string representing the semantic version
func (s *SemVer) String() string {
	res := fmt.Sprintf("%s.%s.%s", s.Major, s.Minor, s.Patch)
	if s.PreRel != "" {
		res = fmt.Sprintf("%s-%s", res, s.PreRel)
	}
	if s.Build != "" {
		res = fmt.Sprintf("%s+%s", res, s.Build)
	}
	return res
}

// parts will return all version components as a slice of strings.
func (s *SemVer) parts() []string {
	return []string{s.Major, s.Minor, s.Patch, s.PreRel, s.Build}
}

// New will create a new semantic versioning object from a flat
// string and populate all struct fields.
func New(vstr string) (*SemVer, error) {
	s := &SemVer{
		Build:  takeR(&vstr, "+"),
		PreRel: takeR(&vstr, "-"),
		Patch:  takeR(&vstr, "."),
		Minor:  takeR(&vstr, "."),
		Major:  vstr,
	}
	if err := s.verify(); err != nil {
		return nil, err
	}
	return s, nil
}

// verify is used to ensure that a semver object complies with the format
// defined by semver.org.
func (s *SemVer) verify() error {
	baseRe, err := regexp.Compile("^[0-9]+$")
	extRe, err := regexp.Compile("^([0-9a-zA-Z-]+)?$")
	if err != nil {
		return err
	}

	if !(baseRe.MatchString(s.Major) &&
		baseRe.MatchString(s.Minor) &&
		baseRe.MatchString(s.Patch) &&
		extRe.MatchString(s.PreRel) &&
		extRe.MatchString(s.Build)) {

		return fmt.Errorf("semver: invalid version: %s", s.String())
	}

	return nil
}

// takeR will take all characters in a string from the right side of the subject
// until sep is encountered. The subject will be pruned in-place of both sep and
// the taken string.
func takeR(subj *string, sep string) string {
	parts := strings.Split(*subj, sep)
	l := len(parts)
	if l == 1 {
		return ""
	}
	*subj = strings.Join(parts[0:l-1], sep)
	return parts[l-1]
}

// Compare is used to in dependency resolution to compare two versions of
// software. The return value is an integer, either -1, 0, or 1. The result may
// be compared against '0' with standard operators to determine greater than,
// less than, etc.
func (v1 *SemVer) Compare(v2 *SemVer) int {
	return vcomp(v1.parts(), v2.parts())
}

// vcomp is a recursive function which will compare two slices of version
// components and return an integer representing which is greater. The result
// is intended to be compared against integer 0 using standard operators.
func vcomp(v1, v2 []string) int {
	switch {
	case len(v1) == 0 && len(v2) == 0:
		return 0
	case v1[0] > v2[0]:
		return 1
	case v1[0] < v2[0]:
		return -1
	default:
		return vcomp(v1[1:], v2[1:])
	}
}

// GreaterThan determines if one version is larger than another
func (v1 *SemVer) GreaterThan(v2 *SemVer) bool {
	return v1.Compare(v2) > 0
}

// LessThan is the inverse of the Greater than function
func (v1 *SemVer) LessThan(v2 *SemVer) bool {
	return v1.Compare(v2) < 0
}

// EqualTo determines if two versions are equivalent.
func (v1 *SemVer) EqualTo(v2 *SemVer) bool {
	return v1.Compare(v2) == 0
}
<commit_msg>Clean up verification<commit_after>package semver

import (
	"fmt"
	"regexp"
	"strings"
)

// Version represents a semantic version of a crate package.
type SemVer struct {
	// The major version. This is an integer that increments when a backward-
	// incompatible change is made to a project's API.
	Major string

	// The minor version. Used to indicate feature addition.
	Minor string

	// The patch number. This is typically used to indicate bug fixes that
	// enhance existing functionality without changing or adding any API's.
	Patch string

	// The (optional) pre-release version from point 9 of semver 2.0.
	PreRel string

	// A string of optional build metadata per point 10 of semver 2.0.
	Build string
}

// String will return a flat string representing the semantic version
func (s *SemVer) String() string {
	res := fmt.Sprintf("%s.%s.%s", s.Major, s.Minor, s.Patch)
	if s.PreRel != "" {
		res = fmt.Sprintf("%s-%s", res, s.PreRel)
	}
	if s.Build != "" {
		res = fmt.Sprintf("%s+%s", res, s.Build)
	}
	return res
}

// parts will return all version components as a slice of strings.
func (s *SemVer) parts() []string {
	return []string{s.Major, s.Minor, s.Patch, s.PreRel, s.Build}
}

// New will create a new semantic versioning object from a flat
// string and populate all struct fields.
func New(vstr string) (*SemVer, error) {
	s := &SemVer{
		Build:  takeR(&vstr, "+"),
		PreRel: takeR(&vstr, "-"),
		Patch:  takeR(&vstr, "."),
		Minor:  takeR(&vstr, "."),
		Major:  vstr,
	}
	if err := s.verify(); err != nil {
		return nil, err
	}
	return s, nil
}

// verify is used to ensure that a semver object complies with the format
// defined by semver.org.
func (s *SemVer) verify() error {
	baseRe, err := regexp.Compile("^[0-9]+$")
	extRe, err := regexp.Compile("^([0-9a-zA-Z-]+)?$")
	if err != nil {
		return err
	}

	if !(baseRe.MatchString(s.Major) && baseRe.MatchString(s.Minor) &&
		baseRe.MatchString(s.Patch) && extRe.MatchString(s.PreRel) &&
		extRe.MatchString(s.Build)) {

		return fmt.Errorf("semver: invalid version: %s", s.String())
	}

	return nil
}

// takeR will take all characters in a string from the right side of the subject
// until sep is encountered. The subject will be pruned in-place of both sep and
// the taken string.
func takeR(subj *string, sep string) string {
	parts := strings.Split(*subj, sep)
	l := len(parts)
	if l == 1 {
		return ""
	}
	*subj = strings.Join(parts[0:l-1], sep)
	return parts[l-1]
}

// Compare is used to in dependency resolution to compare two versions of
// software. The return value is an integer, either -1, 0, or 1. The result may
// be compared against '0' with standard operators to determine greater than,
// less than, etc.
func (v1 *SemVer) Compare(v2 *SemVer) int {
	return vcomp(v1.parts(), v2.parts())
}

// vcomp is a recursive function which will compare two slices of version
// components and return an integer representing which is greater. The result
// is intended to be compared against integer 0 using standard operators.
func vcomp(v1, v2 []string) int {
	switch {
	case len(v1) == 0 && len(v2) == 0:
		return 0
	case v1[0] > v2[0]:
		return 1
	case v1[0] < v2[0]:
		return -1
	default:
		return vcomp(v1[1:], v2[1:])
	}
}

// GreaterThan determines if one version is larger than another
func (v1 *SemVer) GreaterThan(v2 *SemVer) bool {
	return v1.Compare(v2) > 0
}

// LessThan is the inverse of the Greater than function
func (v1 *SemVer) LessThan(v2 *SemVer) bool {
	return v1.Compare(v2) < 0
}

// EqualTo determines if two versions are equivalent.
func (v1 *SemVer) EqualTo(v2 *SemVer) bool {
	return v1.Compare(v2) == 0
}
<|endoftext|>


<commit_before>// Copyright 2014 Hajime Hoshi
//
// 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.

// +build example

package blocks

import (
	"image/color"
	_ "image/jpeg"
	"math/rand"
	"strconv"
	"time"

	"github.com/hajimehoshi/ebiten"
	"github.com/hajimehoshi/ebiten/ebitenutil"
	"github.com/hajimehoshi/ebiten/examples/common"
)

var (
	imageGameBG   *ebiten.Image
	imageWindows  *ebiten.Image
	imageGameover *ebiten.Image
)

func fieldWindowPosition() (x, y int) {
	return 20, 20
}

func nextWindowLabelPosition() (x, y int) {
	x, y = fieldWindowPosition()
	return x + fieldWidth + 2*blockWidth, y
}

func nextWindowPosition() (x, y int) {
	x, y = nextWindowLabelPosition()
	return x, y + blockHeight
}

func textBoxWidth() int {
	x, _ := nextWindowPosition()
	return ScreenWidth - 2*blockWidth - x
}

func scoreTextBoxPosition() (x, y int) {
	x, y = nextWindowPosition()
	return x, y + 6*blockHeight
}

func levelTextBoxPosition() (x, y int) {
	x, y = scoreTextBoxPosition()
	return x, y + 4*blockHeight
}

func linesTextBoxPosition() (x, y int) {
	x, y = levelTextBoxPosition()
	return x, y + 4*blockHeight
}

func init() {
	// Background
	var err error
	imageGameBG, _, err = ebitenutil.NewImageFromFile(ebitenutil.JoinStringsIntoFilePath("_resources", "images", "gophers.jpg"), ebiten.FilterLinear)
	if err != nil {
		panic(err)
	}

	// Windows
	imageWindows, _ = ebiten.NewImage(ScreenWidth, ScreenHeight, ebiten.FilterNearest)

	// Windows: Field
	x, y := fieldWindowPosition()
	drawWindow(imageWindows, x, y, fieldWidth, fieldHeight)

	// Windows: Next
	x, y = nextWindowLabelPosition()
	common.ArcadeFont.DrawTextWithShadow(imageWindows, "NEXT", x, y, 1, fontColor)
	x, y = nextWindowPosition()
	drawWindow(imageWindows, x, y, 5*blockWidth, 5*blockHeight)

	// Windows: Score
	x, y = scoreTextBoxPosition()
	drawTextBox(imageWindows, "SCORE", x, y, textBoxWidth())

	// Windows: Level
	x, y = levelTextBoxPosition()
	drawTextBox(imageWindows, "LEVEL", x, y, textBoxWidth())

	// Windows: Lines
	x, y = linesTextBoxPosition()
	drawTextBox(imageWindows, "LINES", x, y, textBoxWidth())

	// Gameover
	imageGameover, _ = ebiten.NewImage(ScreenWidth, ScreenHeight, ebiten.FilterNearest)
	imageGameover.Fill(color.NRGBA{0x00, 0x00, 0x00, 0x80})
	y = (ScreenHeight - blockHeight) / 2
	drawTextWithShadowCenter(imageGameover, "GAME OVER", 0, y, 1, color.White, ScreenWidth)
}

func drawWindow(r *ebiten.Image, x, y, width, height int) {
	ebitenutil.DrawRect(r, float64(x), float64(y), float64(width), float64(height), color.RGBA{0, 0, 0, 0xc0})
}

var fontColor = color.NRGBA{0x40, 0x40, 0xff, 0xff}

func drawTextBox(r *ebiten.Image, label string, x, y, width int) {
	common.ArcadeFont.DrawTextWithShadow(r, label, x, y, 1, fontColor)
	y += blockWidth
	drawWindow(r, x, y, width, 2*blockHeight)
}

func drawTextBoxContent(r *ebiten.Image, content string, x, y, width int) {
	y += blockWidth
	drawTextWithShadowRight(r, content, x, y+blockHeight*3/4, 1, color.White, width-blockWidth/2)
}

type GameScene struct {
	field              *Field
	rand               *rand.Rand
	currentPiece       *Piece
	currentPieceX      int
	currentPieceY      int
	currentPieceYCarry int
	currentPieceAngle  Angle
	nextPiece          *Piece
	landingCount       int
	currentFrame       int
	score              int
	lines              int
	gameover           bool
}

func NewGameScene() *GameScene {
	return &GameScene{
		field: &Field{},
		rand:  rand.New(rand.NewSource(time.Now().UnixNano())),
	}
}

func (s *GameScene) drawBackground(r *ebiten.Image) {
	r.Fill(color.White)

	w, h := imageGameBG.Size()
	scaleW := ScreenWidth / float64(w)
	scaleH := ScreenHeight / float64(h)
	scale := scaleW
	if scale < scaleH {
		scale = scaleH
	}

	op := &ebiten.DrawImageOptions{}
	op.GeoM.Translate(-float64(w)/2, -float64(h)/2)
	op.GeoM.Scale(scale, scale)
	op.GeoM.Translate(ScreenWidth/2, ScreenHeight/2)

	a := 0.7
	m := ebiten.Monochrome()
	m.Scale(a, a, a, a)
	op.ColorM.Scale(1-a, 1-a, 1-a, 1-a)
	op.ColorM.Add(m)
	op.ColorM.Translate(0.3, 0.3, 0.3, 0)
	r.DrawImage(imageGameBG, op)
}

const (
	fieldWidth  = blockWidth * fieldBlockNumX
	fieldHeight = blockHeight * fieldBlockNumY
)

func (s *GameScene) choosePiece() *Piece {
	num := int(BlockTypeMax)
	blockType := BlockType(s.rand.Intn(num) + 1)
	return Pieces[blockType]
}

func (s *GameScene) initCurrentPiece(piece *Piece) {
	s.currentPiece = piece
	x, y := s.currentPiece.InitialPosition()
	s.currentPieceX = x
	s.currentPieceY = y
	s.currentPieceYCarry = 0
	s.currentPieceAngle = Angle0
}

func (s *GameScene) level() int {
	return s.lines / 10
}

func (s *GameScene) addScore(lines int) {
	base := 0
	switch lines {
	case 1:
		base = 100
	case 2:
		base = 300
	case 3:
		base = 600
	case 4:
		base = 1000
	default:
		panic("not reach")
	}
	s.score += (s.level() + 1) * base
}

func (s *GameScene) Update(state *GameState) error {
	s.field.Update()

	if s.gameover {
		// TODO: Gamepad key?
		if state.Input.StateForKey(ebiten.KeySpace) == 1 {
			state.SceneManager.GoTo(&TitleScene{})
		}
		return nil
	}

	s.currentFrame++

	const maxLandingCount = ebiten.FPS
	if s.currentPiece == nil {
		s.initCurrentPiece(s.choosePiece())
	}
	if s.nextPiece == nil {
		s.nextPiece = s.choosePiece()
	}

	moved := false
	piece := s.currentPiece
	angle := s.currentPieceAngle

	// Move piece by user input.
	if !s.field.IsFlushAnimating() {
		piece := s.currentPiece
		x := s.currentPieceX
		y := s.currentPieceY
		if state.Input.IsRotateRightJustPressed() {
			s.currentPieceAngle = s.field.RotatePieceRight(piece, x, y, angle)
			moved = angle != s.currentPieceAngle
		} else if state.Input.IsRotateLeftJustPressed() {
			s.currentPieceAngle = s.field.RotatePieceLeft(piece, x, y, angle)
			moved = angle != s.currentPieceAngle
		} else if l := state.Input.StateForLeft(); l == 1 || (10 <= l && l%2 == 0) {
			s.currentPieceX = s.field.MovePieceToLeft(piece, x, y, angle)
			moved = x != s.currentPieceX
		} else if r := state.Input.StateForRight(); r == 1 || (10 <= r && r%2 == 0) {
			s.currentPieceX = s.field.MovePieceToRight(piece, x, y, angle)
			moved = y != s.currentPieceX
		} else if d := state.Input.StateForDown(); (d-1)%2 == 0 {
			s.currentPieceY = s.field.DropPiece(piece, x, y, angle)
			moved = y != s.currentPieceY
			if moved {
				s.score++
			}
		}
	}

	// Drop the current piece with gravity.
	if !s.field.IsFlushAnimating() {
		angle := s.currentPieceAngle
		s.currentPieceYCarry += 2*s.level() + 1
		const maxCarry = 60
		for maxCarry <= s.currentPieceYCarry {
			s.currentPieceYCarry -= maxCarry
			s.currentPieceY = s.field.DropPiece(piece, s.currentPieceX, s.currentPieceY, angle)
		}
	}

	if !s.field.IsFlushAnimating() && !s.field.PieceDroppable(piece, s.currentPieceX, s.currentPieceY, angle) {
		if 0 < state.Input.StateForDown() {
			s.landingCount += 10
		} else {
			s.landingCount++
		}
		if maxLandingCount <= s.landingCount {
			s.field.AbsorbPiece(piece, s.currentPieceX, s.currentPieceY, angle)
			if s.field.IsFlushAnimating() {
				s.field.SetEndFlushAnimating(func(lines int) {
					s.lines += lines
					if 0 < lines {
						s.addScore(lines)
					}
					s.goNextPiece()
				})
			} else {
				s.goNextPiece()
			}

		}
	}
	return nil
}

func (s *GameScene) goNextPiece() {
	s.initCurrentPiece(s.nextPiece)
	s.nextPiece = s.choosePiece()
	s.landingCount = 0
	if s.currentPiece.collides(s.field, s.currentPieceX, s.currentPieceY, s.currentPieceAngle) {
		s.gameover = true
	}
}

func (s *GameScene) Draw(r *ebiten.Image) {
	s.drawBackground(r)

	r.DrawImage(imageWindows, nil)

	// Draw score
	x, y := scoreTextBoxPosition()
	drawTextBoxContent(r, strconv.Itoa(s.score), x, y, textBoxWidth())

	// Draw level
	x, y = levelTextBoxPosition()
	drawTextBoxContent(r, strconv.Itoa(s.level()), x, y, textBoxWidth())

	// Draw lines
	x, y = linesTextBoxPosition()
	drawTextBoxContent(r, strconv.Itoa(s.lines), x, y, textBoxWidth())

	// Draw blocks
	fieldX, fieldY := fieldWindowPosition()
	s.field.Draw(r, fieldX, fieldY)
	if s.currentPiece != nil && !s.field.IsFlushAnimating() {
		x := fieldX + s.currentPieceX*blockWidth
		y := fieldY + s.currentPieceY*blockHeight
		s.currentPiece.Draw(r, x, y, s.currentPieceAngle)
	}
	if s.nextPiece != nil {
		// TODO: Make functions to get these values.
		x := fieldX + fieldWidth + blockWidth*2
		y := fieldY + blockHeight
		s.nextPiece.DrawAtCenter(r, x, y, blockWidth*5, blockHeight*5, 0)
	}

	if s.gameover {
		r.DrawImage(imageGameover, nil)
	}
}
<commit_msg>examples/blocks: Reduce members from GameScene<commit_after>// Copyright 2014 Hajime Hoshi
//
// 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.

// +build example

package blocks

import (
	"image/color"
	_ "image/jpeg"
	"math/rand"
	"strconv"
	"time"

	"github.com/hajimehoshi/ebiten"
	"github.com/hajimehoshi/ebiten/ebitenutil"
	"github.com/hajimehoshi/ebiten/examples/common"
)

var (
	imageGameBG   *ebiten.Image
	imageWindows  *ebiten.Image
	imageGameover *ebiten.Image
)

func fieldWindowPosition() (x, y int) {
	return 20, 20
}

func nextWindowLabelPosition() (x, y int) {
	x, y = fieldWindowPosition()
	return x + fieldWidth + 2*blockWidth, y
}

func nextWindowPosition() (x, y int) {
	x, y = nextWindowLabelPosition()
	return x, y + blockHeight
}

func textBoxWidth() int {
	x, _ := nextWindowPosition()
	return ScreenWidth - 2*blockWidth - x
}

func scoreTextBoxPosition() (x, y int) {
	x, y = nextWindowPosition()
	return x, y + 6*blockHeight
}

func levelTextBoxPosition() (x, y int) {
	x, y = scoreTextBoxPosition()
	return x, y + 4*blockHeight
}

func linesTextBoxPosition() (x, y int) {
	x, y = levelTextBoxPosition()
	return x, y + 4*blockHeight
}

func init() {
	// Background
	var err error
	imageGameBG, _, err = ebitenutil.NewImageFromFile(ebitenutil.JoinStringsIntoFilePath("_resources", "images", "gophers.jpg"), ebiten.FilterLinear)
	if err != nil {
		panic(err)
	}

	// Windows
	imageWindows, _ = ebiten.NewImage(ScreenWidth, ScreenHeight, ebiten.FilterNearest)

	// Windows: Field
	x, y := fieldWindowPosition()
	drawWindow(imageWindows, x, y, fieldWidth, fieldHeight)

	// Windows: Next
	x, y = nextWindowLabelPosition()
	common.ArcadeFont.DrawTextWithShadow(imageWindows, "NEXT", x, y, 1, fontColor)
	x, y = nextWindowPosition()
	drawWindow(imageWindows, x, y, 5*blockWidth, 5*blockHeight)

	// Windows: Score
	x, y = scoreTextBoxPosition()
	drawTextBox(imageWindows, "SCORE", x, y, textBoxWidth())

	// Windows: Level
	x, y = levelTextBoxPosition()
	drawTextBox(imageWindows, "LEVEL", x, y, textBoxWidth())

	// Windows: Lines
	x, y = linesTextBoxPosition()
	drawTextBox(imageWindows, "LINES", x, y, textBoxWidth())

	// Gameover
	imageGameover, _ = ebiten.NewImage(ScreenWidth, ScreenHeight, ebiten.FilterNearest)
	imageGameover.Fill(color.NRGBA{0x00, 0x00, 0x00, 0x80})
	y = (ScreenHeight - blockHeight) / 2
	drawTextWithShadowCenter(imageGameover, "GAME OVER", 0, y, 1, color.White, ScreenWidth)
}

func drawWindow(r *ebiten.Image, x, y, width, height int) {
	ebitenutil.DrawRect(r, float64(x), float64(y), float64(width), float64(height), color.RGBA{0, 0, 0, 0xc0})
}

var fontColor = color.NRGBA{0x40, 0x40, 0xff, 0xff}

func drawTextBox(r *ebiten.Image, label string, x, y, width int) {
	common.ArcadeFont.DrawTextWithShadow(r, label, x, y, 1, fontColor)
	y += blockWidth
	drawWindow(r, x, y, width, 2*blockHeight)
}

func drawTextBoxContent(r *ebiten.Image, content string, x, y, width int) {
	y += blockWidth
	drawTextWithShadowRight(r, content, x, y+blockHeight*3/4, 1, color.White, width-blockWidth/2)
}

type GameScene struct {
	field              *Field
	currentPiece       *Piece
	currentPieceX      int
	currentPieceY      int
	currentPieceYCarry int
	currentPieceAngle  Angle
	nextPiece          *Piece
	landingCount       int
	score              int
	lines              int
	gameover           bool
}

func init() {
	rand.Seed(time.Now().UnixNano())
}

func NewGameScene() *GameScene {
	return &GameScene{
		field: &Field{},
	}
}

func (s *GameScene) drawBackground(r *ebiten.Image) {
	r.Fill(color.White)

	w, h := imageGameBG.Size()
	scaleW := ScreenWidth / float64(w)
	scaleH := ScreenHeight / float64(h)
	scale := scaleW
	if scale < scaleH {
		scale = scaleH
	}

	op := &ebiten.DrawImageOptions{}
	op.GeoM.Translate(-float64(w)/2, -float64(h)/2)
	op.GeoM.Scale(scale, scale)
	op.GeoM.Translate(ScreenWidth/2, ScreenHeight/2)

	a := 0.7
	m := ebiten.Monochrome()
	m.Scale(a, a, a, a)
	op.ColorM.Scale(1-a, 1-a, 1-a, 1-a)
	op.ColorM.Add(m)
	op.ColorM.Translate(0.3, 0.3, 0.3, 0)
	r.DrawImage(imageGameBG, op)
}

const (
	fieldWidth  = blockWidth * fieldBlockNumX
	fieldHeight = blockHeight * fieldBlockNumY
)

func (s *GameScene) choosePiece() *Piece {
	num := int(BlockTypeMax)
	blockType := BlockType(rand.Intn(num) + 1)
	return Pieces[blockType]
}

func (s *GameScene) initCurrentPiece(piece *Piece) {
	s.currentPiece = piece
	x, y := s.currentPiece.InitialPosition()
	s.currentPieceX = x
	s.currentPieceY = y
	s.currentPieceYCarry = 0
	s.currentPieceAngle = Angle0
}

func (s *GameScene) level() int {
	return s.lines / 10
}

func (s *GameScene) addScore(lines int) {
	base := 0
	switch lines {
	case 1:
		base = 100
	case 2:
		base = 300
	case 3:
		base = 600
	case 4:
		base = 1000
	default:
		panic("not reach")
	}
	s.score += (s.level() + 1) * base
}

func (s *GameScene) Update(state *GameState) error {
	s.field.Update()

	if s.gameover {
		// TODO: Gamepad key?
		if state.Input.StateForKey(ebiten.KeySpace) == 1 {
			state.SceneManager.GoTo(&TitleScene{})
		}
		return nil
	}

	const maxLandingCount = ebiten.FPS
	if s.currentPiece == nil {
		s.initCurrentPiece(s.choosePiece())
	}
	if s.nextPiece == nil {
		s.nextPiece = s.choosePiece()
	}

	moved := false
	piece := s.currentPiece
	angle := s.currentPieceAngle

	// Move piece by user input.
	if !s.field.IsFlushAnimating() {
		piece := s.currentPiece
		x := s.currentPieceX
		y := s.currentPieceY
		if state.Input.IsRotateRightJustPressed() {
			s.currentPieceAngle = s.field.RotatePieceRight(piece, x, y, angle)
			moved = angle != s.currentPieceAngle
		} else if state.Input.IsRotateLeftJustPressed() {
			s.currentPieceAngle = s.field.RotatePieceLeft(piece, x, y, angle)
			moved = angle != s.currentPieceAngle
		} else if l := state.Input.StateForLeft(); l == 1 || (10 <= l && l%2 == 0) {
			s.currentPieceX = s.field.MovePieceToLeft(piece, x, y, angle)
			moved = x != s.currentPieceX
		} else if r := state.Input.StateForRight(); r == 1 || (10 <= r && r%2 == 0) {
			s.currentPieceX = s.field.MovePieceToRight(piece, x, y, angle)
			moved = y != s.currentPieceX
		} else if d := state.Input.StateForDown(); (d-1)%2 == 0 {
			s.currentPieceY = s.field.DropPiece(piece, x, y, angle)
			moved = y != s.currentPieceY
			if moved {
				s.score++
			}
		}
	}

	// Drop the current piece with gravity.
	if !s.field.IsFlushAnimating() {
		angle := s.currentPieceAngle
		s.currentPieceYCarry += 2*s.level() + 1
		const maxCarry = 60
		for maxCarry <= s.currentPieceYCarry {
			s.currentPieceYCarry -= maxCarry
			s.currentPieceY = s.field.DropPiece(piece, s.currentPieceX, s.currentPieceY, angle)
		}
	}

	if !s.field.IsFlushAnimating() && !s.field.PieceDroppable(piece, s.currentPieceX, s.currentPieceY, angle) {
		if 0 < state.Input.StateForDown() {
			s.landingCount += 10
		} else {
			s.landingCount++
		}
		if maxLandingCount <= s.landingCount {
			s.field.AbsorbPiece(piece, s.currentPieceX, s.currentPieceY, angle)
			if s.field.IsFlushAnimating() {
				s.field.SetEndFlushAnimating(func(lines int) {
					s.lines += lines
					if 0 < lines {
						s.addScore(lines)
					}
					s.goNextPiece()
				})
			} else {
				s.goNextPiece()
			}

		}
	}
	return nil
}

func (s *GameScene) goNextPiece() {
	s.initCurrentPiece(s.nextPiece)
	s.nextPiece = s.choosePiece()
	s.landingCount = 0
	if s.currentPiece.collides(s.field, s.currentPieceX, s.currentPieceY, s.currentPieceAngle) {
		s.gameover = true
	}
}

func (s *GameScene) Draw(r *ebiten.Image) {
	s.drawBackground(r)

	r.DrawImage(imageWindows, nil)

	// Draw score
	x, y := scoreTextBoxPosition()
	drawTextBoxContent(r, strconv.Itoa(s.score), x, y, textBoxWidth())

	// Draw level
	x, y = levelTextBoxPosition()
	drawTextBoxContent(r, strconv.Itoa(s.level()), x, y, textBoxWidth())

	// Draw lines
	x, y = linesTextBoxPosition()
	drawTextBoxContent(r, strconv.Itoa(s.lines), x, y, textBoxWidth())

	// Draw blocks
	fieldX, fieldY := fieldWindowPosition()
	s.field.Draw(r, fieldX, fieldY)
	if s.currentPiece != nil && !s.field.IsFlushAnimating() {
		x := fieldX + s.currentPieceX*blockWidth
		y := fieldY + s.currentPieceY*blockHeight
		s.currentPiece.Draw(r, x, y, s.currentPieceAngle)
	}
	if s.nextPiece != nil {
		// TODO: Make functions to get these values.
		x := fieldX + fieldWidth + blockWidth*2
		y := fieldY + blockHeight
		s.nextPiece.DrawAtCenter(r, x, y, blockWidth*5, blockHeight*5, 0)
	}

	if s.gameover {
		r.DrawImage(imageGameover, nil)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"log"
	"net/http"
	"os"
	"path/filepath"
	"runtime/pprof"
)

func main() {
	log.SetFlags(0)

	var cpuprofile = flag.String("cpuprofile", "", "write CPU profile to file")
	var listen = flag.String("listen", ":8000", "listen address")
	var path = flag.String("path", "/tmp/restic", "data directory")
	var tls = flag.Bool("tls", false, "turn on TLS support")
	flag.Parse()

	if *cpuprofile != "" {
		f, err := os.Create(*cpuprofile)
		if err != nil {
			log.Fatal(err)
		}
		if err := pprof.StartCPUProfile(f); err != nil {
			log.Fatal(err)
		}
		log.Println("CPU profiling enabled")
		defer pprof.StopCPUProfile()
	}

	log.Println("Creating repository directories")
	dirs := []string{
		"data",
		"index",
		"keys",
		"locks",
		"snapshots",
		"tmp",
	}
	for _, d := range dirs {
		if err := os.MkdirAll(filepath.Join(*path, d), 0700); err != nil {
			log.Fatal(err)
		}
	}
	for i := 0; i < 256; i++ {
		if err := os.MkdirAll(filepath.Join(*path, "data", fmt.Sprintf("%02x", i)), 0700); err != nil {
			log.Fatal(err)
		}
	}

	context := &Context{*path}
	router := NewRouter()
	router.HeadFunc("/config", CheckConfig(context))
	router.GetFunc("/config", GetConfig(context))
	router.PostFunc("/config", SaveConfig(context))
	router.GetFunc("/:dir/", ListBlobs(context))
	router.HeadFunc("/:dir/:name", CheckBlob(context))
	router.GetFunc("/:type/:name", GetBlob(context))
	router.PostFunc("/:type/:name", SaveBlob(context))
	router.DeleteFunc("/:type/:name", DeleteBlob(context))

	var handler http.Handler
	htpasswdFile, err := NewHtpasswdFromFile(filepath.Join(*path, ".htpasswd"))
	if err != nil {
		log.Println("Authentication disabled")
		handler = router
	} else {
		log.Println("Authentication enabled")
		handler = AuthHandler(htpasswdFile, router)
	}

	if !*tls {
		log.Printf("Starting server on %s\n", *listen)
		err = http.ListenAndServe(*listen, handler)
	} else {
		privateKey := filepath.Join(*path, "private_key")
		publicKey := filepath.Join(*path, "public_key")
		log.Println("TLS enabled")
		log.Printf("Private key: %s", privateKey)
		log.Printf("Public key: %s", publicKey)
		log.Printf("Starting server on %s\n", *listen)
		err = http.ListenAndServeTLS(*listen, publicKey, privateKey, handler)
	}
	if err != nil {
		log.Fatal(err)
	}
}
<commit_msg>Refactor server.go<commit_after>package main

import (
	"flag"
	"fmt"
	"log"
	"net/http"
	"os"
	"path/filepath"
	"runtime/pprof"
)

func createDirectories(path string) {
	log.Println("Creating repository directories")

	dirs := []string{
		"data",
		"index",
		"keys",
		"locks",
		"snapshots",
		"tmp",
	}

	for _, d := range dirs {
		if err := os.MkdirAll(filepath.Join(path, d), 0700); err != nil {
			log.Fatal(err)
		}
	}

	for i := 0; i < 256; i++ {
		if err := os.MkdirAll(filepath.Join(path, "data", fmt.Sprintf("%02x", i)), 0700); err != nil {
			log.Fatal(err)
		}
	}
}

func setupRoutes(path string) *Router {
	context := &Context{path}

	router := NewRouter()
	router.HeadFunc("/config", CheckConfig(context))
	router.GetFunc("/config", GetConfig(context))
	router.PostFunc("/config", SaveConfig(context))
	router.GetFunc("/:dir/", ListBlobs(context))
	router.HeadFunc("/:dir/:name", CheckBlob(context))
	router.GetFunc("/:type/:name", GetBlob(context))
	router.PostFunc("/:type/:name", SaveBlob(context))
	router.DeleteFunc("/:type/:name", DeleteBlob(context))

	return router
}

func main() {
	log.SetFlags(0)

	var cpuprofile = flag.String("cpuprofile", "", "write CPU profile to file")
	var listen = flag.String("listen", ":8000", "listen address")
	var path = flag.String("path", "/tmp/restic", "data directory")
	var tls = flag.Bool("tls", false, "turn on TLS support")
	flag.Parse()

	if *cpuprofile != "" {
		f, err := os.Create(*cpuprofile)
		if err != nil {
			log.Fatal(err)
		}
		if err := pprof.StartCPUProfile(f); err != nil {
			log.Fatal(err)
		}
		log.Println("CPU profiling enabled")
		defer pprof.StopCPUProfile()
	}

	createDirectories(*path)

	router := setupRoutes(*path)

	var handler http.Handler
	htpasswdFile, err := NewHtpasswdFromFile(filepath.Join(*path, ".htpasswd"))
	if err != nil {
		handler = router
		log.Println("Authentication disabled")
	} else {
		handler = AuthHandler(htpasswdFile, router)
		log.Println("Authentication enabled")
	}

	if !*tls {
		log.Printf("Starting server on %s\n", *listen)
		err = http.ListenAndServe(*listen, handler)
	} else {
		privateKey := filepath.Join(*path, "private_key")
		publicKey := filepath.Join(*path, "public_key")
		log.Println("TLS enabled")
		log.Printf("Private key: %s", privateKey)
		log.Printf("Public key: %s", publicKey)
		log.Printf("Starting server on %s\n", *listen)
		err = http.ListenAndServeTLS(*listen, publicKey, privateKey, handler)
	}
	if err != nil {
		log.Fatal(err)
	}
}
<|endoftext|>