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

package runtime

import "unsafe"

// NOTE: Func does not expose the actual unexported fields, because we return *Func
// values to users, and we want to keep them from being able to overwrite the data
// with (say) *f = Func{}.
// All code operating on a *Func must call raw to get the *_func instead.

// A Func represents a Go function in the running binary.
type Func struct {
	opaque struct{} // unexported field to disallow conversions
}

func (f *Func) raw() *_func {
	return (*_func)(unsafe.Pointer(f))
}

// funcdata.h
const (
	_PCDATA_ArgSize             = 0
	_PCDATA_StackMapIndex       = 1
	_FUNCDATA_ArgsPointerMaps   = 0
	_FUNCDATA_LocalsPointerMaps = 1
	_FUNCDATA_DeadValueMaps     = 2
	_ArgsSizeUnknown            = -0x80000000
)

var (
	pclntable []byte
	ftab      []functab
	filetab   []uint32

	pclntab, epclntab struct{} // linker symbols
)

type functab struct {
	entry   uintptr
	funcoff uintptr
}

func symtabinit() {
	// See golang.org/s/go12symtab for header: 0xfffffffb,
	// two zero bytes, a byte giving the PC quantum,
	// and a byte giving the pointer width in bytes.
	pcln := (*[8]byte)(unsafe.Pointer(&pclntab))
	pcln32 := (*[2]uint32)(unsafe.Pointer(&pclntab))
	if pcln32[0] != 0xfffffffb || pcln[4] != 0 || pcln[5] != 0 || pcln[6] != _PCQuantum || pcln[7] != ptrSize {
		println("runtime: function symbol table header:", hex(pcln32[0]), hex(pcln[4]), hex(pcln[5]), hex(pcln[6]), hex(pcln[7]))
		gothrow("invalid function symbol table\n")
	}

	// pclntable is all bytes of pclntab symbol.
	sp := (*sliceStruct)(unsafe.Pointer(&pclntable))
	sp.array = unsafe.Pointer(&pclntab)
	sp.len = int(uintptr(unsafe.Pointer(&epclntab)) - uintptr(unsafe.Pointer(&pclntab)))
	sp.cap = sp.len

	// ftab is lookup table for function by program counter.
	nftab := int(*(*uintptr)(add(unsafe.Pointer(pcln), 8)))
	p := add(unsafe.Pointer(pcln), 8+ptrSize)
	sp = (*sliceStruct)(unsafe.Pointer(&ftab))
	sp.array = p
	sp.len = nftab + 1
	sp.cap = sp.len
	for i := 0; i < nftab; i++ {
		// NOTE: ftab[nftab].entry is legal; it is the address beyond the final function.
		if ftab[i].entry > ftab[i+1].entry {
			f1 := (*_func)(unsafe.Pointer(&pclntable[ftab[i].funcoff]))
			f2 := (*_func)(unsafe.Pointer(&pclntable[ftab[i+1].funcoff]))
			f2name := "end"
			if i+1 < nftab {
				f2name = gofuncname(f2)
			}
			println("function symbol table not sorted by program counter:", hex(ftab[i].entry), gofuncname(f1), ">", hex(ftab[i+1].entry), f2name)
			for j := 0; j <= i; j++ {
				print("\t", hex(ftab[j].entry), " ", gofuncname((*_func)(unsafe.Pointer(&pclntable[ftab[j].funcoff]))))
			}
			gothrow("invalid runtime symbol table")
		}
	}

	// file table follows ftab.
	sp = (*sliceStruct)(unsafe.Pointer(&filetab))
	p = unsafe.Pointer(add(unsafe.Pointer(pcln), ftab[nftab].funcoff))
	sp.array = unsafe.Pointer(add(unsafe.Pointer(pcln), ftab[nftab].funcoff))
	// length is in first element of array.
	// set len to 1 so we can get first element.
	sp.len = 1
	sp.cap = 1
	sp.len = int(filetab[0])
	sp.cap = sp.len
}

// FuncForPC returns a *Func describing the function that contains the
// given program counter address, or else nil.
func FuncForPC(pc uintptr) *Func {
	return (*Func)(unsafe.Pointer(findfunc(pc)))
}

// Name returns the name of the function.
func (f *Func) Name() string {
	return gofuncname(f.raw())
}

// Entry returns the entry address of the function.
func (f *Func) Entry() uintptr {
	return f.raw().entry
}

// FileLine returns the file name and line number of the
// source code corresponding to the program counter pc.
// The result will not be accurate if pc is not a program
// counter within f.
func (f *Func) FileLine(pc uintptr) (file string, line int) {
	// Pass strict=false here, because anyone can call this function,
	// and they might just be wrong about targetpc belonging to f.
	line = int(funcline1(f.raw(), pc, &file, false))
	return file, line
}

func findfunc(pc uintptr) *_func {
	if len(ftab) == 0 {
		return nil
	}

	if pc < ftab[0].entry || pc >= ftab[len(ftab)-1].entry {
		return nil
	}

	// binary search to find func with entry <= pc.
	lo := 0
	nf := len(ftab) - 1 // last entry is sentinel
	for nf > 0 {
		n := nf / 2
		f := &ftab[lo+n]
		if f.entry <= pc && pc < ftab[lo+n+1].entry {
			return (*_func)(unsafe.Pointer(&pclntable[f.funcoff]))
		} else if pc < f.entry {
			nf = n
		} else {
			lo += n + 1
			nf -= n + 1
		}
	}

	gothrow("findfunc: binary search failed")
	return nil
}

func pcvalue(f *_func, off int32, targetpc uintptr, strict bool) int32 {
	if off == 0 {
		return -1
	}
	p := pclntable[off:]
	pc := f.entry
	val := int32(-1)
	for {
		var ok bool
		p, ok = step(p, &pc, &val, pc == f.entry)
		if !ok {
			break
		}
		if targetpc < pc {
			return val
		}
	}

	// If there was a table, it should have covered all program counters.
	// If not, something is wrong.
	if panicking != 0 || !strict {
		return -1
	}

	print("runtime: invalid pc-encoded table f=", gofuncname(f), " pc=", hex(pc), " targetpc=", hex(targetpc), " tab=", p, "\n")

	p = pclntable[off:]
	pc = f.entry
	val = -1
	for {
		var ok bool
		p, ok = step(p, &pc, &val, pc == f.entry)
		if !ok {
			break
		}
		print("\tvalue=", val, " until pc=", hex(pc), "\n")
	}

	gothrow("invalid runtime symbol table")
	return -1
}

func funcname(f *_func) *byte {
	if f == nil || f.nameoff == 0 {
		return nil
	}
	return (*byte)(unsafe.Pointer(&pclntable[f.nameoff]))
}

func gofuncname(f *_func) string {
	return gostringnocopy(funcname(f))
}

func funcline1(f *_func, targetpc uintptr, file *string, strict bool) int32 {
	*file = "?"
	fileno := int(pcvalue(f, f.pcfile, targetpc, strict))
	line := pcvalue(f, f.pcln, targetpc, strict)
	if fileno == -1 || line == -1 || fileno >= len(filetab) {
		// print("looking for ", hex(targetpc), " in ", gofuncname(f), " got file=", fileno, " line=", lineno, "\n")
		return 0
	}
	*file = gostringnocopy(&pclntable[filetab[fileno]])
	return line
}

func funcline(f *_func, targetpc uintptr, file *string) int32 {
	return funcline1(f, targetpc, file, true)
}

func funcspdelta(f *_func, targetpc uintptr) int32 {
	x := pcvalue(f, f.pcsp, targetpc, true)
	if x&(ptrSize-1) != 0 {
		print("invalid spdelta ", f.pcsp, " ", x, "\n")
	}
	return x
}

func pcdatavalue(f *_func, table int32, targetpc uintptr) int32 {
	if table < 0 || table >= f.npcdata {
		return -1
	}
	off := *(*int32)(add(unsafe.Pointer(&f.nfuncdata), unsafe.Sizeof(f.nfuncdata)+uintptr(table)*4))
	return pcvalue(f, off, targetpc, true)
}

func funcdata(f *_func, i int32) unsafe.Pointer {
	if i < 0 || i >= f.nfuncdata {
		return nil
	}
	p := add(unsafe.Pointer(&f.nfuncdata), unsafe.Sizeof(f.nfuncdata)+uintptr(f.npcdata)*4)
	if ptrSize == 8 && uintptr(p)&4 != 0 {
		if uintptr(unsafe.Pointer(f))&4 != 0 {
			println("runtime: misaligned func", f)
		}
		p = add(p, 4)
	}
	return *(*unsafe.Pointer)(add(p, uintptr(i)*ptrSize))
}

// step advances to the next pc, value pair in the encoded table.
func step(p []byte, pc *uintptr, val *int32, first bool) (newp []byte, ok bool) {
	p, uvdelta := readvarint(p)
	if uvdelta == 0 && !first {
		return nil, false
	}
	if uvdelta&1 != 0 {
		uvdelta = ^(uvdelta >> 1)
	} else {
		uvdelta >>= 1
	}
	vdelta := int32(uvdelta)
	p, pcdelta := readvarint(p)
	*pc += uintptr(pcdelta * _PCQuantum)
	*val += vdelta
	return p, true
}

// readvarint reads a varint from p.
func readvarint(p []byte) (newp []byte, val uint32) {
	var v, shift uint32
	for {
		b := p[0]
		p = p[1:]
		v |= (uint32(b) & 0x7F) << shift
		if b&0x80 == 0 {
			break
		}
		shift += 7
	}
	return p, v
}
<commit_msg>runtime: fix endianness assumption when decoding ftab<commit_after>// Copyright 2014 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package runtime

import "unsafe"

// NOTE: Func does not expose the actual unexported fields, because we return *Func
// values to users, and we want to keep them from being able to overwrite the data
// with (say) *f = Func{}.
// All code operating on a *Func must call raw to get the *_func instead.

// A Func represents a Go function in the running binary.
type Func struct {
	opaque struct{} // unexported field to disallow conversions
}

func (f *Func) raw() *_func {
	return (*_func)(unsafe.Pointer(f))
}

// funcdata.h
const (
	_PCDATA_ArgSize             = 0
	_PCDATA_StackMapIndex       = 1
	_FUNCDATA_ArgsPointerMaps   = 0
	_FUNCDATA_LocalsPointerMaps = 1
	_FUNCDATA_DeadValueMaps     = 2
	_ArgsSizeUnknown            = -0x80000000
)

var (
	pclntable []byte
	ftab      []functab
	filetab   []uint32

	pclntab, epclntab struct{} // linker symbols
)

type functab struct {
	entry   uintptr
	funcoff uintptr
}

func symtabinit() {
	// See golang.org/s/go12symtab for header: 0xfffffffb,
	// two zero bytes, a byte giving the PC quantum,
	// and a byte giving the pointer width in bytes.
	pcln := (*[8]byte)(unsafe.Pointer(&pclntab))
	pcln32 := (*[2]uint32)(unsafe.Pointer(&pclntab))
	if pcln32[0] != 0xfffffffb || pcln[4] != 0 || pcln[5] != 0 || pcln[6] != _PCQuantum || pcln[7] != ptrSize {
		println("runtime: function symbol table header:", hex(pcln32[0]), hex(pcln[4]), hex(pcln[5]), hex(pcln[6]), hex(pcln[7]))
		gothrow("invalid function symbol table\n")
	}

	// pclntable is all bytes of pclntab symbol.
	sp := (*sliceStruct)(unsafe.Pointer(&pclntable))
	sp.array = unsafe.Pointer(&pclntab)
	sp.len = int(uintptr(unsafe.Pointer(&epclntab)) - uintptr(unsafe.Pointer(&pclntab)))
	sp.cap = sp.len

	// ftab is lookup table for function by program counter.
	nftab := int(*(*uintptr)(add(unsafe.Pointer(pcln), 8)))
	p := add(unsafe.Pointer(pcln), 8+ptrSize)
	sp = (*sliceStruct)(unsafe.Pointer(&ftab))
	sp.array = p
	sp.len = nftab + 1
	sp.cap = sp.len
	for i := 0; i < nftab; i++ {
		// NOTE: ftab[nftab].entry is legal; it is the address beyond the final function.
		if ftab[i].entry > ftab[i+1].entry {
			f1 := (*_func)(unsafe.Pointer(&pclntable[ftab[i].funcoff]))
			f2 := (*_func)(unsafe.Pointer(&pclntable[ftab[i+1].funcoff]))
			f2name := "end"
			if i+1 < nftab {
				f2name = gofuncname(f2)
			}
			println("function symbol table not sorted by program counter:", hex(ftab[i].entry), gofuncname(f1), ">", hex(ftab[i+1].entry), f2name)
			for j := 0; j <= i; j++ {
				print("\t", hex(ftab[j].entry), " ", gofuncname((*_func)(unsafe.Pointer(&pclntable[ftab[j].funcoff]))))
			}
			gothrow("invalid runtime symbol table")
		}
	}

	// The ftab ends with a half functab consisting only of
	// 'entry', followed by a uint32 giving the pcln-relative
	// offset of the file table.
	sp = (*sliceStruct)(unsafe.Pointer(&filetab))
	end := unsafe.Pointer(&ftab[nftab].funcoff) // just beyond ftab
	fileoffset := *(*uint32)(end)
	sp.array = unsafe.Pointer(&pclntable[fileoffset])
	// length is in first element of array.
	// set len to 1 so we can get first element.
	sp.len = 1
	sp.cap = 1
	sp.len = int(filetab[0])
	sp.cap = sp.len
}

// FuncForPC returns a *Func describing the function that contains the
// given program counter address, or else nil.
func FuncForPC(pc uintptr) *Func {
	return (*Func)(unsafe.Pointer(findfunc(pc)))
}

// Name returns the name of the function.
func (f *Func) Name() string {
	return gofuncname(f.raw())
}

// Entry returns the entry address of the function.
func (f *Func) Entry() uintptr {
	return f.raw().entry
}

// FileLine returns the file name and line number of the
// source code corresponding to the program counter pc.
// The result will not be accurate if pc is not a program
// counter within f.
func (f *Func) FileLine(pc uintptr) (file string, line int) {
	// Pass strict=false here, because anyone can call this function,
	// and they might just be wrong about targetpc belonging to f.
	line = int(funcline1(f.raw(), pc, &file, false))
	return file, line
}

func findfunc(pc uintptr) *_func {
	if len(ftab) == 0 {
		return nil
	}

	if pc < ftab[0].entry || pc >= ftab[len(ftab)-1].entry {
		return nil
	}

	// binary search to find func with entry <= pc.
	lo := 0
	nf := len(ftab) - 1 // last entry is sentinel
	for nf > 0 {
		n := nf / 2
		f := &ftab[lo+n]
		if f.entry <= pc && pc < ftab[lo+n+1].entry {
			return (*_func)(unsafe.Pointer(&pclntable[f.funcoff]))
		} else if pc < f.entry {
			nf = n
		} else {
			lo += n + 1
			nf -= n + 1
		}
	}

	gothrow("findfunc: binary search failed")
	return nil
}

func pcvalue(f *_func, off int32, targetpc uintptr, strict bool) int32 {
	if off == 0 {
		return -1
	}
	p := pclntable[off:]
	pc := f.entry
	val := int32(-1)
	for {
		var ok bool
		p, ok = step(p, &pc, &val, pc == f.entry)
		if !ok {
			break
		}
		if targetpc < pc {
			return val
		}
	}

	// If there was a table, it should have covered all program counters.
	// If not, something is wrong.
	if panicking != 0 || !strict {
		return -1
	}

	print("runtime: invalid pc-encoded table f=", gofuncname(f), " pc=", hex(pc), " targetpc=", hex(targetpc), " tab=", p, "\n")

	p = pclntable[off:]
	pc = f.entry
	val = -1
	for {
		var ok bool
		p, ok = step(p, &pc, &val, pc == f.entry)
		if !ok {
			break
		}
		print("\tvalue=", val, " until pc=", hex(pc), "\n")
	}

	gothrow("invalid runtime symbol table")
	return -1
}

func funcname(f *_func) *byte {
	if f == nil || f.nameoff == 0 {
		return nil
	}
	return (*byte)(unsafe.Pointer(&pclntable[f.nameoff]))
}

func gofuncname(f *_func) string {
	return gostringnocopy(funcname(f))
}

func funcline1(f *_func, targetpc uintptr, file *string, strict bool) int32 {
	*file = "?"
	fileno := int(pcvalue(f, f.pcfile, targetpc, strict))
	line := pcvalue(f, f.pcln, targetpc, strict)
	if fileno == -1 || line == -1 || fileno >= len(filetab) {
		// print("looking for ", hex(targetpc), " in ", gofuncname(f), " got file=", fileno, " line=", lineno, "\n")
		return 0
	}
	*file = gostringnocopy(&pclntable[filetab[fileno]])
	return line
}

func funcline(f *_func, targetpc uintptr, file *string) int32 {
	return funcline1(f, targetpc, file, true)
}

func funcspdelta(f *_func, targetpc uintptr) int32 {
	x := pcvalue(f, f.pcsp, targetpc, true)
	if x&(ptrSize-1) != 0 {
		print("invalid spdelta ", hex(f.entry), " ", hex(targetpc), " ", hex(f.pcsp), " ", x, "\n")
	}
	return x
}

func pcdatavalue(f *_func, table int32, targetpc uintptr) int32 {
	if table < 0 || table >= f.npcdata {
		return -1
	}
	off := *(*int32)(add(unsafe.Pointer(&f.nfuncdata), unsafe.Sizeof(f.nfuncdata)+uintptr(table)*4))
	return pcvalue(f, off, targetpc, true)
}

func funcdata(f *_func, i int32) unsafe.Pointer {
	if i < 0 || i >= f.nfuncdata {
		return nil
	}
	p := add(unsafe.Pointer(&f.nfuncdata), unsafe.Sizeof(f.nfuncdata)+uintptr(f.npcdata)*4)
	if ptrSize == 8 && uintptr(p)&4 != 0 {
		if uintptr(unsafe.Pointer(f))&4 != 0 {
			println("runtime: misaligned func", f)
		}
		p = add(p, 4)
	}
	return *(*unsafe.Pointer)(add(p, uintptr(i)*ptrSize))
}

// step advances to the next pc, value pair in the encoded table.
func step(p []byte, pc *uintptr, val *int32, first bool) (newp []byte, ok bool) {
	p, uvdelta := readvarint(p)
	if uvdelta == 0 && !first {
		return nil, false
	}
	if uvdelta&1 != 0 {
		uvdelta = ^(uvdelta >> 1)
	} else {
		uvdelta >>= 1
	}
	vdelta := int32(uvdelta)
	p, pcdelta := readvarint(p)
	*pc += uintptr(pcdelta * _PCQuantum)
	*val += vdelta
	return p, true
}

// readvarint reads a varint from p.
func readvarint(p []byte) (newp []byte, val uint32) {
	var v, shift uint32
	for {
		b := p[0]
		p = p[1:]
		v |= (uint32(b) & 0x7F) << shift
		if b&0x80 == 0 {
			break
		}
		shift += 7
	}
	return p, v
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"os"
	"strings"
)

func main() {
	var ir interface{}
	var b []byte
	switch len(os.Args) {
	case 2:
		buf, err := ioutil.ReadFile(os.Args[1])
		if err != nil {
			fmt.Print(err)
			os.Exit(1)
		} else {
			b = buf
		}
	}
	err := json.Unmarshal(b, &ir)
	if err != nil {
		err := json.Unmarshal(b[strings.Index(string(b), "(")+1:len(b)-3], &ir)
		if err != nil {
			fmt.Print(err)
			os.Exit(1)
		}
	}
	json, _ := json.MarshalIndent(ir, "", "  ")
	fmt.Print(string(json))
}
<commit_msg>go: read from stdin<commit_after>package main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"os"
	"strings"
)

func main() {
	var ir interface{}
	var b []byte
	switch len(os.Args) {
	case 1:
		buf, err := ioutil.ReadAll(os.Stdin)
		if err != nil {
			fmt.Print(err)
			os.Exit(1)
		} else {
			b = buf
		}
	case 2:
		buf, err := ioutil.ReadFile(os.Args[1])
		if err != nil {
			fmt.Print(err)
			os.Exit(1)
		} else {
			b = buf
		}
	}
	err := json.Unmarshal(b, &ir)
	if err != nil {
		err := json.Unmarshal(b[strings.Index(string(b), "(")+1:len(b)-3], &ir)
		if err != nil {
			fmt.Print(err)
			os.Exit(1)
		}
	}
	json, _ := json.MarshalIndent(ir, "", "  ")
	fmt.Print(string(json))
}
<|endoftext|>


<commit_before>package ledger

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

type Entry struct {
	Date        string // "Y-m-d"
	Description string
	Change      int // in cents
}

func isValidCurrency(currency string) bool {
	return currency == "USD" || currency == "EUR"
}

func isValidLocale(locale string) bool {
	return locale == "en-US" || locale == "nl-NL"
}

func isValidDate(entries []Entry) bool {
	for _, entry := range entries {
		if len(entry.Date) != 10 {
			return false
		}
		_, d2, _, d4, _ := entry.Date[0:4], entry.Date[4], entry.Date[5:7], entry.Date[7], entry.Date[8:10]
		if d2 != '-' || d4 != '-' {
			return false
		}
	}
	return true
}

func formatDescription(description string) string {
	if len(description) > 25 {
		return description[:22] + "..."
	}
	return description + strings.Repeat(" ", 25-len(description))
}
func formatDate(locale string, date string) string {
	year, month, day := date[0:4], date[5:7], date[8:10]

	if locale == "nl-NL" {
		return fmt.Sprintf("%v-%v-%v", day, month, year)
	} else if locale == "en-US" {
		return fmt.Sprintf("%v/%v/%v", month, day, year)
	}
	panic("invalid locale")
}

func header(locale string) (output string) {
	if locale == "nl-NL" {
		return "Datum" +
			strings.Repeat(" ", 10-len("Datum")) +
			" | " +
			"Omschrijving" +
			strings.Repeat(" ", 25-len("Omschrijving")) +
			" | " + "Verandering" + "\n"
	} else if locale == "en-US" {
		return "Date" +
			strings.Repeat(" ", 10-len("Date")) +
			" | " +
			"Description" +
			strings.Repeat(" ", 25-len("Description")) +
			" | " + "Change" + "\n"
	}
	panic("invalid locale")
}

func FormatLedger(currency string, locale string, entries []Entry) (output string, e error) {
	if !isValidCurrency(currency) {
		return "", errors.New("invalid currency")
	}
	if !isValidLocale(locale) {
		return "", errors.New("invalid locale")
	}
	if !isValidDate(entries) {
		return "", errors.New("invalid date")
	}

	entriesCopy := append([]Entry{}, entries...)

	m1 := map[bool]int{true: 0, false: 1}
	m2 := map[bool]int{true: -1, false: 1}
	es := entriesCopy
	for len(es) > 1 {
		first, rest := es[0], es[1:]
		success := false
		for !success {
			success = true
			for i, e := range rest {
				if (m1[e.Date == first.Date]*m2[e.Date < first.Date]*4 +
					m1[e.Description == first.Description]*m2[e.Description < first.Description]*2 +
					m1[e.Change == first.Change]*m2[e.Change < first.Change]*1) < 0 {
					es[0], es[i+1] = es[i+1], es[0]
					success = false
				}
			}
		}
		es = es[1:]
	}

	output += header(locale)
	co := make(chan struct {
		s string
	})
	for _, et := range entriesCopy {
		go func(entry Entry) {
			de := formatDescription(entry.Description)
			d := formatDate(locale, entry.Date)
			negative := false
			cents := entry.Change
			if cents < 0 {
				cents = cents * -1
				negative = true
			}
			var a string
			if locale == "nl-NL" {
				if currency == "EUR" {
					a += "€"
				} else if currency == "USD" {
					a += "$"
				}
				a += " "
				centsStr := strconv.Itoa(cents)
				switch len(centsStr) {
				case 1:
					centsStr = "00" + centsStr
				case 2:
					centsStr = "0" + centsStr
				}
				rest := centsStr[:len(centsStr)-2]
				var parts []string
				for len(rest) > 3 {
					parts = append(parts, rest[len(rest)-3:])
					rest = rest[:len(rest)-3]
				}
				if len(rest) > 0 {
					parts = append(parts, rest)
				}
				for i := len(parts) - 1; i >= 0; i-- {
					a += parts[i] + "."
				}
				a = a[:len(a)-1]
				a += ","
				a += centsStr[len(centsStr)-2:]
				if negative {
					a += "-"
				} else {
					a += " "
				}
			} else if locale == "en-US" {
				if negative {
					a += "("
				}
				if currency == "EUR" {
					a += "€"
				} else if currency == "USD" {
					a += "$"
				}
				centsStr := strconv.Itoa(cents)
				switch len(centsStr) {
				case 1:
					centsStr = "00" + centsStr
				case 2:
					centsStr = "0" + centsStr
				}
				rest := centsStr[:len(centsStr)-2]
				var parts []string
				for len(rest) > 3 {
					parts = append(parts, rest[len(rest)-3:])
					rest = rest[:len(rest)-3]
				}
				if len(rest) > 0 {
					parts = append(parts, rest)
				}
				for i := len(parts) - 1; i >= 0; i-- {
					a += parts[i] + ","
				}
				a = a[:len(a)-1]
				a += "."
				a += centsStr[len(centsStr)-2:]
				if negative {
					a += ")"
				} else {
					a += " "
				}
			}
			co <- struct {
				s string
			}{s: d + strings.Repeat(" ", 10-len(d)) + " | " + de + " | " +
				strings.Repeat(" ", 13-len(a)) + a + "\n"}
		}(et)
	}
	for range entriesCopy {
		v := <-co
		output += v.s
	}
	return output, nil
}
<commit_msg>Remove channel<commit_after>package ledger

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

type Entry struct {
	Date        string // "Y-m-d"
	Description string
	Change      int // in cents
}

func isValidCurrency(currency string) bool {
	return currency == "USD" || currency == "EUR"
}

func isValidLocale(locale string) bool {
	return locale == "en-US" || locale == "nl-NL"
}

func isValidDate(entries []Entry) bool {
	for _, entry := range entries {
		if len(entry.Date) != 10 {
			return false
		}
		_, d2, _, d4, _ := entry.Date[0:4], entry.Date[4], entry.Date[5:7], entry.Date[7], entry.Date[8:10]
		if d2 != '-' || d4 != '-' {
			return false
		}
	}
	return true
}

func formatDescription(description string) string {
	if len(description) > 25 {
		return description[:22] + "..."
	}
	return description + strings.Repeat(" ", 25-len(description))
}
func formatDate(locale string, date string) string {
	year, month, day := date[0:4], date[5:7], date[8:10]

	if locale == "nl-NL" {
		return fmt.Sprintf("%v-%v-%v", day, month, year)
	} else if locale == "en-US" {
		return fmt.Sprintf("%v/%v/%v", month, day, year)
	}
	panic("invalid locale")
}

func header(locale string) (output string) {
	if locale == "nl-NL" {
		return "Datum" +
			strings.Repeat(" ", 10-len("Datum")) +
			" | " +
			"Omschrijving" +
			strings.Repeat(" ", 25-len("Omschrijving")) +
			" | " + "Verandering" + "\n"
	} else if locale == "en-US" {
		return "Date" +
			strings.Repeat(" ", 10-len("Date")) +
			" | " +
			"Description" +
			strings.Repeat(" ", 25-len("Description")) +
			" | " + "Change" + "\n"
	}
	panic("invalid locale")
}

func FormatLedger(currency string, locale string, entries []Entry) (output string, e error) {
	if !isValidCurrency(currency) {
		return "", errors.New("invalid currency")
	}
	if !isValidLocale(locale) {
		return "", errors.New("invalid locale")
	}
	if !isValidDate(entries) {
		return "", errors.New("invalid date")
	}

	entriesCopy := append([]Entry{}, entries...)

	m1 := map[bool]int{true: 0, false: 1}
	m2 := map[bool]int{true: -1, false: 1}
	es := entriesCopy
	for len(es) > 1 {
		first, rest := es[0], es[1:]
		success := false
		for !success {
			success = true
			for i, e := range rest {
				if (m1[e.Date == first.Date]*m2[e.Date < first.Date]*4 +
					m1[e.Description == first.Description]*m2[e.Description < first.Description]*2 +
					m1[e.Change == first.Change]*m2[e.Change < first.Change]*1) < 0 {
					es[0], es[i+1] = es[i+1], es[0]
					success = false
				}
			}
		}
		es = es[1:]
	}

	output += header(locale)
	for _, entry := range entriesCopy {
		de := formatDescription(entry.Description)
		d := formatDate(locale, entry.Date)
		negative := false
		cents := entry.Change
		if cents < 0 {
			cents = cents * -1
			negative = true
		}
		var a string
		if locale == "nl-NL" {
			if currency == "EUR" {
				a += "€"
			} else if currency == "USD" {
				a += "$"
			}
			a += " "
			centsStr := strconv.Itoa(cents)
			switch len(centsStr) {
			case 1:
				centsStr = "00" + centsStr
			case 2:
				centsStr = "0" + centsStr
			}
			rest := centsStr[:len(centsStr)-2]
			var parts []string
			for len(rest) > 3 {
				parts = append(parts, rest[len(rest)-3:])
				rest = rest[:len(rest)-3]
			}
			if len(rest) > 0 {
				parts = append(parts, rest)
			}
			for i := len(parts) - 1; i >= 0; i-- {
				a += parts[i] + "."
			}
			a = a[:len(a)-1]
			a += ","
			a += centsStr[len(centsStr)-2:]
			if negative {
				a += "-"
			} else {
				a += " "
			}
		} else if locale == "en-US" {
			if negative {
				a += "("
			}
			if currency == "EUR" {
				a += "€"
			} else if currency == "USD" {
				a += "$"
			}
			centsStr := strconv.Itoa(cents)
			switch len(centsStr) {
			case 1:
				centsStr = "00" + centsStr
			case 2:
				centsStr = "0" + centsStr
			}
			rest := centsStr[:len(centsStr)-2]
			var parts []string
			for len(rest) > 3 {
				parts = append(parts, rest[len(rest)-3:])
				rest = rest[:len(rest)-3]
			}
			if len(rest) > 0 {
				parts = append(parts, rest)
			}
			for i := len(parts) - 1; i >= 0; i-- {
				a += parts[i] + ","
			}
			a = a[:len(a)-1]
			a += "."
			a += centsStr[len(centsStr)-2:]
			if negative {
				a += ")"
			} else {
				a += " "
			}
		}
		output += d + strings.Repeat(" ", 10-len(d)) + " | " + de + " | " +
			strings.Repeat(" ", 13-len(a)) + a + "\n"
	}
	return output, nil
}
<|endoftext|>


<commit_before>package libkb

import (
	"fmt"
)

// NOTE: This file is the source of truth for our version number, but we have a
//       script that reads it at packaging/version.sh. If you refactor this
//       file, update that script.

// Version as MAJOR.MINOR.PATCH
const Version = "1.0.0"

// Build number
const Build = "28"

// VersionString returns semantic version string.
func VersionString() string {
	return fmt.Sprintf("%s-%s", Version, Build)
}
<commit_msg>build number bump<commit_after>package libkb

import (
	"fmt"
)

// NOTE: This file is the source of truth for our version number, but we have a
//       script that reads it at packaging/version.sh. If you refactor this
//       file, update that script.

// Version as MAJOR.MINOR.PATCH
const Version = "1.0.0"

// Build number
const Build = "29"

// VersionString returns semantic version string.
func VersionString() string {
	return fmt.Sprintf("%s-%s", Version, Build)
}
<|endoftext|>


<commit_before>// Copyright 2015 Keybase, Inc. All rights reserved. Use of
// this source code is governed by the included BSD license.

package service

import (
	"errors"
	"sync"
	"time"

	"golang.org/x/net/context"

	"github.com/keybase/client/go/libkb"
	keybase1 "github.com/keybase/client/go/protocol"
	rpc "github.com/keybase/go-framed-msgpack-rpc"
)

type RekeyHandler struct {
	libkb.Contextified
	*BaseHandler
	gregor          *gregorHandler
	recheckMu       sync.Mutex
	recheckDeadline time.Time
}

func NewRekeyHandler(xp rpc.Transporter, g *libkb.GlobalContext, gregor *gregorHandler) *RekeyHandler {
	h := &RekeyHandler{
		BaseHandler:  NewBaseHandler(xp),
		gregor:       gregor,
		Contextified: libkb.NewContextified(g),
	}
	h.recheckRekeyStatusPeriodic()
	return h
}

func (h *RekeyHandler) ShowPendingRekeyStatus(ctx context.Context, sessionID int) error {
	psetDevices, err := h.GetPendingRekeyStatus(ctx, sessionID)
	if err != nil {
		return err
	}
	rekeyUI, err := h.G().UIRouter.GetRekeyUINoSessionID()
	if err != nil {
		return err
	}
	if rekeyUI == nil {
		return errors.New("no rekey ui")
	}
	arg := keybase1.RefreshArg{
		SessionID:         sessionID,
		ProblemSetDevices: psetDevices,
	}
	return rekeyUI.Refresh(ctx, arg)
}

func (h *RekeyHandler) GetPendingRekeyStatus(ctx context.Context, sessionID int) (keybase1.ProblemSetDevices, error) {
	me, err := libkb.LoadMe(libkb.NewLoadUserArg(h.G()))
	if err != nil {
		return keybase1.ProblemSetDevices{}, err
	}
	pset, err := scoreProblemFolders(h.G(), keybase1.ProblemSet{})
	if err != nil {
		return keybase1.ProblemSetDevices{}, err
	}
	return newProblemSetDevices(me, pset)
}

func (h *RekeyHandler) DebugShowRekeyStatus(ctx context.Context, sessionID int) error {
	if h.G().Env.GetRunMode() == libkb.ProductionRunMode {
		return errors.New("DebugShowRekeyStatus is a devel-only RPC")
	}

	me, err := libkb.LoadMe(libkb.NewLoadUserArg(h.G()))
	if err != nil {
		return err
	}

	arg := keybase1.RefreshArg{
		SessionID: sessionID,
		ProblemSetDevices: keybase1.ProblemSetDevices{
			ProblemSet: keybase1.ProblemSet{
				User: keybase1.User{
					Uid:      me.GetUID(),
					Username: me.GetName(),
				},
				Tlfs: []keybase1.ProblemTLF{
					keybase1.ProblemTLF{
						Tlf: keybase1.TLF{
							// this is only for debugging
							Name:      "/keybase/private/" + me.GetName(),
							Writers:   []string{me.GetName()},
							Readers:   []string{me.GetName()},
							IsPrivate: true,
						},
					},
				},
			},
		},
	}

	devices := me.GetComputedKeyFamily().GetAllActiveDevices()
	arg.ProblemSetDevices.Devices = make([]keybase1.Device, len(devices))
	for i, dev := range devices {
		arg.ProblemSetDevices.Devices[i] = *(dev.ProtExport())
	}

	rekeyUI, err := h.G().UIRouter.GetRekeyUINoSessionID()
	if err != nil {
		return err
	}
	if rekeyUI == nil {
		h.G().Log.Debug("no rekey ui, would have called refresh with this:")
		h.G().Log.Debug("arg: %+v", arg)
		return errors.New("no rekey ui")
	}

	return rekeyUI.Refresh(ctx, arg)
}

func (h *RekeyHandler) RekeyStatusFinish(ctx context.Context, sessionID int) (keybase1.Outcome, error) {
	outcome, err := h.gregor.RekeyStatusFinish(ctx, sessionID)
	if err == nil {
		// recheck rekey status 24h from now
		h.recheckMu.Lock()
		h.recheckDeadline = time.Now().Add(24 * time.Hour)
		h.recheckMu.Unlock()
	}
	return outcome, err
}

func (h *RekeyHandler) recheckRekeyStatusPeriodic() {
	h.G().Log.Debug("starting recheck rekey status loop")
	ticker := time.NewTicker(1 * time.Hour)
	h.G().PushShutdownHook(func() error {
		h.G().Log.Debug("stopping recheckRekeyStatus timer")
		ticker.Stop()
		return nil
	})
	go func() {
		for {
			<-ticker.C
			h.recheckMu.Lock()
			if h.recheckDeadline.IsZero() {
				h.recheckMu.Unlock()
				continue
			}
			if time.Now().Before(h.recheckDeadline) {
				h.recheckMu.Unlock()
				continue
			}
			h.recheckMu.Unlock()
			h.G().Log.Debug("rechecking rekey status")

			h.recheckRekeyStatus()

			h.recheckMu.Lock()
			h.recheckDeadline = time.Time{}
			h.recheckMu.Unlock()
		}
	}()
}

func (h *RekeyHandler) recheckRekeyStatus() {
	ctx := context.Background()
	psetDevices, err := h.GetPendingRekeyStatus(ctx, 0)
	if err != nil {
		h.G().Log.Warning("recheckRekeyStatus: error getting pending rekey status: %s", err)
		return
	}

	numTLFs := len(psetDevices.ProblemSet.Tlfs)
	if numTLFs == 0 {
		h.G().Log.Debug("recheckRekeyStatus: empty problem set")
		return
	}

	h.G().Log.Debug("recheckRekeyStatus: need to harass user, %d TLFs need help", numTLFs)
	if err := h.gregor.RekeyReharass(ctx, psetDevices); err != nil {
		h.G().Log.Warning("recheckRekeyStatus: reharass error: %s", err)
	}
}

func newProblemSetDevices(u *libkb.User, pset keybase1.ProblemSet) (keybase1.ProblemSetDevices, error) {
	var set keybase1.ProblemSetDevices
	set.ProblemSet = pset

	ckf := u.GetComputedKeyFamily()

	dset := make(map[keybase1.DeviceID]bool)
	for _, f := range pset.Tlfs {
		for _, kid := range f.Solution_kids {
			dev, err := ckf.GetDeviceForKID(kid)
			if err != nil {
				return keybase1.ProblemSetDevices{}, err
			}
			if dset[dev.ID] {
				continue
			}
			dset[dev.ID] = true
			set.Devices = append(set.Devices, *(dev.ProtExport()))
		}
	}
	return set, nil
}
<commit_msg>PR feedback<commit_after>// Copyright 2015 Keybase, Inc. All rights reserved. Use of
// this source code is governed by the included BSD license.

package service

import (
	"errors"
	"sync"
	"time"

	"golang.org/x/net/context"

	"github.com/keybase/client/go/libkb"
	keybase1 "github.com/keybase/client/go/protocol"
	rpc "github.com/keybase/go-framed-msgpack-rpc"
)

type RekeyHandler struct {
	libkb.Contextified
	*BaseHandler
	gregor          *gregorHandler
	recheckMu       sync.Mutex
	recheckDeadline time.Time
}

func NewRekeyHandler(xp rpc.Transporter, g *libkb.GlobalContext, gregor *gregorHandler) *RekeyHandler {
	h := &RekeyHandler{
		BaseHandler:  NewBaseHandler(xp),
		gregor:       gregor,
		Contextified: libkb.NewContextified(g),
	}
	h.recheckRekeyStatusPeriodic()
	return h
}

func (h *RekeyHandler) ShowPendingRekeyStatus(ctx context.Context, sessionID int) error {
	psetDevices, err := h.GetPendingRekeyStatus(ctx, sessionID)
	if err != nil {
		return err
	}
	rekeyUI, err := h.G().UIRouter.GetRekeyUINoSessionID()
	if err != nil {
		return err
	}
	if rekeyUI == nil {
		return errors.New("no rekey ui")
	}
	arg := keybase1.RefreshArg{
		SessionID:         sessionID,
		ProblemSetDevices: psetDevices,
	}
	return rekeyUI.Refresh(ctx, arg)
}

func (h *RekeyHandler) GetPendingRekeyStatus(ctx context.Context, sessionID int) (keybase1.ProblemSetDevices, error) {
	me, err := libkb.LoadMe(libkb.NewLoadUserArg(h.G()))
	if err != nil {
		return keybase1.ProblemSetDevices{}, err
	}
	pset, err := scoreProblemFolders(h.G(), keybase1.ProblemSet{})
	if err != nil {
		return keybase1.ProblemSetDevices{}, err
	}
	return newProblemSetDevices(me, pset)
}

func (h *RekeyHandler) DebugShowRekeyStatus(ctx context.Context, sessionID int) error {
	if h.G().Env.GetRunMode() == libkb.ProductionRunMode {
		return errors.New("DebugShowRekeyStatus is a devel-only RPC")
	}

	me, err := libkb.LoadMe(libkb.NewLoadUserArg(h.G()))
	if err != nil {
		return err
	}

	arg := keybase1.RefreshArg{
		SessionID: sessionID,
		ProblemSetDevices: keybase1.ProblemSetDevices{
			ProblemSet: keybase1.ProblemSet{
				User: keybase1.User{
					Uid:      me.GetUID(),
					Username: me.GetName(),
				},
				Tlfs: []keybase1.ProblemTLF{
					keybase1.ProblemTLF{
						Tlf: keybase1.TLF{
							// this is only for debugging
							Name:      "/keybase/private/" + me.GetName(),
							Writers:   []string{me.GetName()},
							Readers:   []string{me.GetName()},
							IsPrivate: true,
						},
					},
				},
			},
		},
	}

	devices := me.GetComputedKeyFamily().GetAllActiveDevices()
	arg.ProblemSetDevices.Devices = make([]keybase1.Device, len(devices))
	for i, dev := range devices {
		arg.ProblemSetDevices.Devices[i] = *(dev.ProtExport())
	}

	rekeyUI, err := h.G().UIRouter.GetRekeyUINoSessionID()
	if err != nil {
		return err
	}
	if rekeyUI == nil {
		h.G().Log.Debug("no rekey ui, would have called refresh with this:")
		h.G().Log.Debug("arg: %+v", arg)
		return errors.New("no rekey ui")
	}

	return rekeyUI.Refresh(ctx, arg)
}

func (h *RekeyHandler) RekeyStatusFinish(ctx context.Context, sessionID int) (keybase1.Outcome, error) {
	outcome, err := h.gregor.RekeyStatusFinish(ctx, sessionID)
	if err == nil {
		// recheck rekey status 24h from now
		h.recheckMu.Lock()
		h.recheckDeadline = time.Now().Add(24 * time.Hour)
		h.recheckMu.Unlock()
	}
	return outcome, err
}

// recheckRekeyStatusPeriodic checks the recheckDeadline every hour.
// If it is set and the current time is after the deadline, then
// it will recheck the rekey status for this user.
func (h *RekeyHandler) recheckRekeyStatusPeriodic() {
	h.G().Log.Debug("starting recheck rekey status loop")
	ticker := time.NewTicker(1 * time.Hour)
	h.G().PushShutdownHook(func() error {
		h.G().Log.Debug("stopping recheckRekeyStatus timer")
		ticker.Stop()
		return nil
	})
	go func() {
		for {
			// this fires every hour
			<-ticker.C

			// continue if not at recheck deadline (or there
			// isn't a deadline set)
			if !h.atRecheckDeadline() {
				continue
			}

			// recheck rekey status
			h.G().Log.Debug("rechecking rekey status")
			h.recheckRekeyStatus()

			// clear the deadline
			h.clearRecheckDeadline()
		}
	}()
}

// atRecheckDeadline returns true if the current time is after
// recheckDeadline.  If recheckDeadline isn't set, it returns
// false.
func (h *RekeyHandler) atRecheckDeadline() bool {
	h.recheckMu.Lock()
	defer h.recheckMu.Unlock()

	if h.recheckDeadline.IsZero() {
		return false
	}

	if time.Now().Before(h.recheckDeadline) {
		return false
	}

	return true
}

// clearRecheckDeadline sets the recheck deadline to zero.
func (h *RekeyHandler) clearRecheckDeadline() {
	h.recheckMu.Lock()
	defer h.recheckMu.Unlock()

	h.recheckDeadline = time.Time{}
}

func (h *RekeyHandler) recheckRekeyStatus() {
	ctx := context.Background()
	psetDevices, err := h.GetPendingRekeyStatus(ctx, 0)
	if err != nil {
		h.G().Log.Warning("recheckRekeyStatus: error getting pending rekey status: %s", err)
		return
	}

	numTLFs := len(psetDevices.ProblemSet.Tlfs)
	if numTLFs == 0 {
		h.G().Log.Debug("recheckRekeyStatus: empty problem set")
		return
	}

	h.G().Log.Debug("recheckRekeyStatus: need to harass user, %d TLFs need help", numTLFs)
	if err := h.gregor.RekeyReharass(ctx, psetDevices); err != nil {
		h.G().Log.Warning("recheckRekeyStatus: reharass error: %s", err)
	}
}

func newProblemSetDevices(u *libkb.User, pset keybase1.ProblemSet) (keybase1.ProblemSetDevices, error) {
	var set keybase1.ProblemSetDevices
	set.ProblemSet = pset

	ckf := u.GetComputedKeyFamily()

	dset := make(map[keybase1.DeviceID]bool)
	for _, f := range pset.Tlfs {
		for _, kid := range f.Solution_kids {
			dev, err := ckf.GetDeviceForKID(kid)
			if err != nil {
				return keybase1.ProblemSetDevices{}, err
			}
			if dset[dev.ID] {
				continue
			}
			dset[dev.ID] = true
			set.Devices = append(set.Devices, *(dev.ProtExport()))
		}
	}
	return set, nil
}
<|endoftext|>


<commit_before>// Package goordinated provides a wire-compatible reimplementation of
// the Diffeo Coordinate daemon.  This is intended to be fully
// compatible with the existing Coordinate toolset at
// https://github.com/diffeo/coordinate.  This is purely a server-side
// daemon; it does not include application code or a worker
// implementation.
package main

import "bufio"
import "errors"
import "flag"
import "fmt"
import "io"
import "net"
import "reflect"
import "runtime"
import "strings"

import "github.com/dmaze/goordinate/backend"
import "github.com/dmaze/goordinate/cborrpc"
import "github.com/dmaze/goordinate/coordinate"
import "github.com/dmaze/goordinate/jobserver"
import "github.com/ugorji/go/codec"

func main() {
	bind := flag.String("bind", ":5932", "[ip]:port to listen on")
	backend := backend.Backend{Implementation: "memory", Address: ""}
	flag.Var(&backend, "backend", "impl[:address] of the storage backend")
	flag.Parse()

	coordinate := backend.Coordinate()
	namespace, err := coordinate.Namespace("")
	cbor := new(codec.CborHandle)
	if err == nil {
		err = cborrpc.SetExts(cbor)
	}
	if err != nil {
		panic(err)
	}
	jobd := &jobserver.JobServer{Namespace: namespace}

	ln, err := net.Listen("tcp", *bind)
	if err != nil {
		fmt.Printf("Could not listen to %v: %v\n", *bind, err)
		return
	}
	for {
		conn, err := ln.Accept()
		if err != nil {
			fmt.Printf("Could not accept connection: %v\n", err)
			return
		}
		go handleConnection(conn, jobd, cbor)
	}
}

// Convert a "snake case" name, like 'foo_bar_baz', to a "camel case" name
// with its first letter capitalized, like 'FooBarBaz'.
func snakeToCamel(s string) string {
	words := strings.Split(s, "_")
	for n := range words {
		words[n] = strings.Title(words[n])
	}
	return strings.Join(words, "")
}

func handleConnection(conn net.Conn, jobd *jobserver.JobServer, cbor *codec.CborHandle) {
	defer conn.Close()

	jobdv := reflect.ValueOf(jobd)

	reader := bufio.NewReader(conn)
	decoder := codec.NewDecoder(reader, cbor)
	writer := bufio.NewWriter(conn)
	encoder := codec.NewEncoder(writer, cbor)

	for {
		var request cborrpc.Request
		err := decoder.Decode(&request)
		if err == io.EOF {
			return
		} else if err != nil {
			fmt.Printf("Error reading message: %v\n", err)
			return
		}
		fmt.Printf("Request: %v\n", request)
		response := doRequest(jobdv, request)
		fmt.Printf("Response: %v\n", response)
		err = encoder.Encode(response)
		if err != nil {
			fmt.Printf("Error encoding response: %v\n", err)
			return
		}
		err = writer.Flush()
		if err != nil {
			fmt.Printf("Error writing response: %v\n", err)
			return
		}
	}
}

func doRequest(jobdv reflect.Value, request cborrpc.Request) (response cborrpc.Response) {
	response.ID = request.ID

	// If we panic in the middle of this, turn it into a response
	defer func() {
		if oops := recover(); oops != nil {
			buf := make([]byte, 65536)
			runtime.Stack(buf, false)
			fmt.Printf("%v\n%v\n", oops, string(buf))
			response.Error = fmt.Sprintf("%v", oops)
		}
	}()

	method := snakeToCamel(request.Method)
	var err error
	var params, returns []reflect.Value
	var returnsString, returnsError bool
	funcv := jobdv.MethodByName(method)
	if !funcv.IsValid() {
		err = fmt.Errorf("no such method %v", method)
	}
	if err == nil {
		funct := funcv.Type()
		numOut := funct.NumOut()
		if numOut > 0 {
			lastt := funct.Out(numOut - 1)
			returnsError = lastt.PkgPath() == "" && lastt.Name() == "error"
		}
		if numOut > 1 {
			secondt := funct.Out(numOut - 2)
			returnsString = secondt.PkgPath() == "" && secondt.Name() == "string"
		}

		// In theory, the wire format could have a map
		// of kwargs instead
		params, err = cborrpc.CreateParamList(funcv, request.Params)
	}
	if err == nil {
		// The wire format has an explicit error
		// return, which gets mapped to Python
		// Exception, plus most methods return a pair
		// of (response, error message).  Deal with
		// this on the Go side by having functions
		// return both kinds of errors (if
		// appropriate).
		returns = funcv.Call(params)
		if len(returns) == 0 {
			err = errors.New("empty return from method")
		} else if returnsError {
			errV := returns[len(returns)-1].Interface()
			if errV != nil {
				err = errV.(error)
			}
			returns = returns[0 : len(returns)-1]
		}
	}

	// If we are expecting to return a string message, and there
	// is no error, remap an empty string to nil
	if returnsString {
		msg := returns[len(returns) - 1].String()
		if msg == "" {
			returns[len(returns) - 1] = reflect.ValueOf(nil)
		}

		// If we got back a NoSuchWorkSpec error, report that
		// as a string (most RPC calls that take a work spec
		// parameter can produce this and return it as a string
		// error, not an exception)
		if err != nil {
			if nsws, ok := err.(coordinate.ErrNoSuchWorkSpec); ok {
				err = nil
				returns[len(returns) - 1] = reflect.ValueOf(nsws.Error())
			}
		}
	}

	if err != nil {
		response.Error = err.Error()
	} else if len(returns) == 1 {
		response.Result = returns[0].Interface()
	} else {
		results := make([]interface{}, len(returns))
		for i, retval := range returns {
			if retval.IsValid() {
				results[i] = retval.Interface()
			}
		}
		response.Result = results
	}

	return
}
<commit_msg>goordinated/main.go formatting<commit_after>// Package goordinated provides a wire-compatible reimplementation of
// the Diffeo Coordinate daemon.  This is intended to be fully
// compatible with the existing Coordinate toolset at
// https://github.com/diffeo/coordinate.  This is purely a server-side
// daemon; it does not include application code or a worker
// implementation.
package main

import (
	"bufio"
	"errors"
	"flag"
	"fmt"
	"io"
	"net"
	"reflect"
	"runtime"
	"strings"

	"github.com/dmaze/goordinate/backend"
	"github.com/dmaze/goordinate/cborrpc"
	"github.com/dmaze/goordinate/coordinate"
	"github.com/dmaze/goordinate/jobserver"
	"github.com/ugorji/go/codec"
)

func main() {
	bind := flag.String("bind", ":5932", "[ip]:port to listen on")
	backend := backend.Backend{Implementation: "memory", Address: ""}
	flag.Var(&backend, "backend", "impl[:address] of the storage backend")
	flag.Parse()

	coordinate := backend.Coordinate()
	namespace, err := coordinate.Namespace("")
	cbor := new(codec.CborHandle)
	if err == nil {
		err = cborrpc.SetExts(cbor)
	}
	if err != nil {
		panic(err)
	}
	jobd := &jobserver.JobServer{Namespace: namespace}

	ln, err := net.Listen("tcp", *bind)
	if err != nil {
		fmt.Printf("Could not listen to %v: %v\n", *bind, err)
		return
	}
	for {
		conn, err := ln.Accept()
		if err != nil {
			fmt.Printf("Could not accept connection: %v\n", err)
			return
		}
		go handleConnection(conn, jobd, cbor)
	}
}

// Convert a "snake case" name, like 'foo_bar_baz', to a "camel case" name
// with its first letter capitalized, like 'FooBarBaz'.
func snakeToCamel(s string) string {
	words := strings.Split(s, "_")
	for n := range words {
		words[n] = strings.Title(words[n])
	}
	return strings.Join(words, "")
}

func handleConnection(conn net.Conn, jobd *jobserver.JobServer, cbor *codec.CborHandle) {
	defer conn.Close()

	jobdv := reflect.ValueOf(jobd)

	reader := bufio.NewReader(conn)
	decoder := codec.NewDecoder(reader, cbor)
	writer := bufio.NewWriter(conn)
	encoder := codec.NewEncoder(writer, cbor)

	for {
		var request cborrpc.Request
		err := decoder.Decode(&request)
		if err == io.EOF {
			return
		} else if err != nil {
			fmt.Printf("Error reading message: %v\n", err)
			return
		}
		fmt.Printf("Request: %v\n", request)
		response := doRequest(jobdv, request)
		fmt.Printf("Response: %v\n", response)
		err = encoder.Encode(response)
		if err != nil {
			fmt.Printf("Error encoding response: %v\n", err)
			return
		}
		err = writer.Flush()
		if err != nil {
			fmt.Printf("Error writing response: %v\n", err)
			return
		}
	}
}

func doRequest(jobdv reflect.Value, request cborrpc.Request) (response cborrpc.Response) {
	response.ID = request.ID

	// If we panic in the middle of this, turn it into a response
	defer func() {
		if oops := recover(); oops != nil {
			buf := make([]byte, 65536)
			runtime.Stack(buf, false)
			fmt.Printf("%v\n%v\n", oops, string(buf))
			response.Error = fmt.Sprintf("%v", oops)
		}
	}()

	method := snakeToCamel(request.Method)
	var err error
	var params, returns []reflect.Value
	var returnsString, returnsError bool
	funcv := jobdv.MethodByName(method)
	if !funcv.IsValid() {
		err = fmt.Errorf("no such method %v", method)
	}
	if err == nil {
		funct := funcv.Type()
		numOut := funct.NumOut()
		if numOut > 0 {
			lastt := funct.Out(numOut - 1)
			returnsError = lastt.PkgPath() == "" && lastt.Name() == "error"
		}
		if numOut > 1 {
			secondt := funct.Out(numOut - 2)
			returnsString = secondt.PkgPath() == "" && secondt.Name() == "string"
		}

		// In theory, the wire format could have a map
		// of kwargs instead
		params, err = cborrpc.CreateParamList(funcv, request.Params)
	}
	if err == nil {
		// The wire format has an explicit error
		// return, which gets mapped to Python
		// Exception, plus most methods return a pair
		// of (response, error message).  Deal with
		// this on the Go side by having functions
		// return both kinds of errors (if
		// appropriate).
		returns = funcv.Call(params)
		if len(returns) == 0 {
			err = errors.New("empty return from method")
		} else if returnsError {
			errV := returns[len(returns)-1].Interface()
			if errV != nil {
				err = errV.(error)
			}
			returns = returns[0 : len(returns)-1]
		}
	}

	// If we are expecting to return a string message, and there
	// is no error, remap an empty string to nil
	if returnsString {
		msg := returns[len(returns)-1].String()
		if msg == "" {
			returns[len(returns)-1] = reflect.ValueOf(nil)
		}

		// If we got back a NoSuchWorkSpec error, report that
		// as a string (most RPC calls that take a work spec
		// parameter can produce this and return it as a string
		// error, not an exception)
		if err != nil {
			if nsws, ok := err.(coordinate.ErrNoSuchWorkSpec); ok {
				err = nil
				returns[len(returns)-1] = reflect.ValueOf(nsws.Error())
			}
		}
	}

	if err != nil {
		response.Error = err.Error()
	} else if len(returns) == 1 {
		response.Result = returns[0].Interface()
	} else {
		results := make([]interface{}, len(returns))
		for i, retval := range returns {
			if retval.IsValid() {
				results[i] = retval.Interface()
			}
		}
		response.Result = results
	}

	return
}
<|endoftext|>


<commit_before>package chart

import (
	"fmt"
	"time"

	"github.com/wcharczuk/go-chart/date"
)

// NYSEMarketHoursRange is a special type of range that compresses a time range into just the
// market (i.e. NYSE operating hours and days) range.
type NYSEMarketHoursRange struct {
	Min    time.Time
	Max    time.Time
	Domain int
}

// GetMin returns the min value.
func (mhr NYSEMarketHoursRange) GetMin() float64 {
	return TimeToFloat64(mhr.Min)
}

// GetMax returns the max value.
func (mhr NYSEMarketHoursRange) GetMax() float64 {
	return TimeToFloat64(mhr.Max)
}

// SetMin sets the min value.
func (mhr *NYSEMarketHoursRange) SetMin(min float64) {
	mhr.Min = Float64ToTime(min)
}

// SetMax sets the max value.
func (mhr *NYSEMarketHoursRange) SetMax(max float64) {
	mhr.Max = Float64ToTime(max)
}

// GetDelta gets the delta.
func (mhr NYSEMarketHoursRange) GetDelta() float64 {
	min := TimeToFloat64(mhr.Min)
	max := TimeToFloat64(mhr.Min)
	return max - min
}

// GetDomain gets the domain.
func (mhr NYSEMarketHoursRange) GetDomain() int {
	return mhr.Domain
}

// SetDomain sets the domain.
func (mhr *NYSEMarketHoursRange) SetDomain(domain int) {
	mhr.Domain = domain
}

func (mhr NYSEMarketHoursRange) String() string {
	return fmt.Sprintf("MarketHoursRange [%s, %s] => %d", mhr.Min.Format(DefaultDateFormat), mhr.Max.Format(DefaultDateFormat), mhr.Domain)
}

// Translate maps a given value into the ContinuousRange space.
func (mhr NYSEMarketHoursRange) Translate(value float64) int {
	valueTime := Float64ToTime(value)
	deltaSeconds := date.CalculateMarketSecondsBetween(mhr.Min, mhr.Max)
	valueDelta := date.CalculateMarketSecondsBetween(mhr.Min, valueTime)
	return int(float64(valueDelta) / float64(deltaSeconds))
}
<commit_msg>making this pass range interface.<commit_after>package chart

import (
	"fmt"
	"time"

	"github.com/wcharczuk/go-chart/date"
)

// NYSEMarketHoursRange is a special type of range that compresses a time range into just the
// market (i.e. NYSE operating hours and days) range.
type NYSEMarketHoursRange struct {
	Min    time.Time
	Max    time.Time
	Domain int
}

// IsZero returns if the range is setup or not.
func (mhr NYSEMarketHoursRange) IsZero() bool {
	return mhr.Min.IsZero() && mhr.Max.IsZero()
}

// GetMin returns the min value.
func (mhr NYSEMarketHoursRange) GetMin() float64 {
	return TimeToFloat64(mhr.Min)
}

// GetMax returns the max value.
func (mhr NYSEMarketHoursRange) GetMax() float64 {
	return TimeToFloat64(mhr.Max)
}

// SetMin sets the min value.
func (mhr *NYSEMarketHoursRange) SetMin(min float64) {
	mhr.Min = Float64ToTime(min)
}

// SetMax sets the max value.
func (mhr *NYSEMarketHoursRange) SetMax(max float64) {
	mhr.Max = Float64ToTime(max)
}

// GetDelta gets the delta.
func (mhr NYSEMarketHoursRange) GetDelta() float64 {
	min := TimeToFloat64(mhr.Min)
	max := TimeToFloat64(mhr.Min)
	return max - min
}

// GetDomain gets the domain.
func (mhr NYSEMarketHoursRange) GetDomain() int {
	return mhr.Domain
}

// SetDomain sets the domain.
func (mhr *NYSEMarketHoursRange) SetDomain(domain int) {
	mhr.Domain = domain
}

func (mhr NYSEMarketHoursRange) String() string {
	return fmt.Sprintf("MarketHoursRange [%s, %s] => %d", mhr.Min.Format(DefaultDateFormat), mhr.Max.Format(DefaultDateFormat), mhr.Domain)
}

// Translate maps a given value into the ContinuousRange space.
func (mhr NYSEMarketHoursRange) Translate(value float64) int {
	valueTime := Float64ToTime(value)
	deltaSeconds := date.CalculateMarketSecondsBetween(mhr.Min, mhr.Max)
	valueDelta := date.CalculateMarketSecondsBetween(mhr.Min, valueTime)
	return int(float64(valueDelta) / float64(deltaSeconds))
}
<|endoftext|>


<commit_before>// +build go1.8

package oci8

import (
	"database/sql"
	"database/sql/driver"

	"context"
)

// Ping implement Pinger.
func (c *OCI8Conn) Ping(ctx context.Context) error {
	return c.ping(ctx)
}

func toNamedValue(nv driver.NamedValue) namedValue {
	mv := namedValue(nv)
	// FIXME
	// This is my fault that I've add code using sql.Out until next release.
	//if out, ok := mv.Value.(sql.Out); ok {
	//	mv.Value = outValue{Dest: out.Dest, In: out.In}
	//}
	return mv
}

// QueryContext implement QueryerContext.
func (c *OCI8Conn) QueryContext(ctx context.Context, query string, args []driver.NamedValue) (driver.Rows, error) {
	list := make([]namedValue, len(args))
	for i, nv := range args {
		list[i] = toNamedValue(nv)
	}
	return c.query(ctx, query, list)
}

// ExecContext implement ExecerContext.
func (c *OCI8Conn) ExecContext(ctx context.Context, query string, args []driver.NamedValue) (driver.Result, error) {
	list := make([]namedValue, len(args))
	for i, nv := range args {
		list[i] = toNamedValue(nv)
	}
	return c.exec(ctx, query, list)
}

// PrepareContext implement ConnPrepareContext.
func (c *OCI8Conn) PrepareContext(ctx context.Context, query string) (driver.Stmt, error) {
	return c.prepare(ctx, query)
}

// BeginTx implement ConnBeginTx.
func (c *OCI8Conn) BeginTx(ctx context.Context, opts driver.TxOptions) (driver.Tx, error) {
	return c.begin(ctx)
}

// QueryContext implement QueryerContext.
func (s *OCI8Stmt) QueryContext(ctx context.Context, args []driver.NamedValue) (driver.Rows, error) {
	list := make([]namedValue, len(args))
	for i, nv := range args {
		list[i] = toNamedValue(nv)
	}
	return s.query(ctx, list)
}

// ExecContext implement ExecerContext.
func (s *OCI8Stmt) ExecContext(ctx context.Context, args []driver.NamedValue) (driver.Result, error) {
	list := make([]namedValue, len(args))
	for i, nv := range args {
		list[i] = toNamedValue(nv)
	}
	return s.exec(ctx, list)
}

func (c *OCI8Conn) CheckNamedValue(nv *driver.NamedValue) error {
	switch nv.Value.(type) {
	default:
		return driver.ErrSkip
	case sql.Out:
		return nil
	}
}
<commit_msg>revert sql.Out<commit_after>// +build go1.8

package oci8

import (
	"database/sql/driver"

	"context"
)

// Ping implement Pinger.
func (c *OCI8Conn) Ping(ctx context.Context) error {
	return c.ping(ctx)
}

func toNamedValue(nv driver.NamedValue) namedValue {
	mv := namedValue(nv)
	// FIXME
	// This is my fault that I've add code using sql.Out until next release.
	//if out, ok := mv.Value.(sql.Out); ok {
	//	mv.Value = outValue{Dest: out.Dest, In: out.In}
	//}
	return mv
}

// QueryContext implement QueryerContext.
func (c *OCI8Conn) QueryContext(ctx context.Context, query string, args []driver.NamedValue) (driver.Rows, error) {
	list := make([]namedValue, len(args))
	for i, nv := range args {
		list[i] = toNamedValue(nv)
	}
	return c.query(ctx, query, list)
}

// ExecContext implement ExecerContext.
func (c *OCI8Conn) ExecContext(ctx context.Context, query string, args []driver.NamedValue) (driver.Result, error) {
	list := make([]namedValue, len(args))
	for i, nv := range args {
		list[i] = toNamedValue(nv)
	}
	return c.exec(ctx, query, list)
}

// PrepareContext implement ConnPrepareContext.
func (c *OCI8Conn) PrepareContext(ctx context.Context, query string) (driver.Stmt, error) {
	return c.prepare(ctx, query)
}

// BeginTx implement ConnBeginTx.
func (c *OCI8Conn) BeginTx(ctx context.Context, opts driver.TxOptions) (driver.Tx, error) {
	return c.begin(ctx)
}

// QueryContext implement QueryerContext.
func (s *OCI8Stmt) QueryContext(ctx context.Context, args []driver.NamedValue) (driver.Rows, error) {
	list := make([]namedValue, len(args))
	for i, nv := range args {
		list[i] = toNamedValue(nv)
	}
	return s.query(ctx, list)
}

// ExecContext implement ExecerContext.
func (s *OCI8Stmt) ExecContext(ctx context.Context, args []driver.NamedValue) (driver.Result, error) {
	list := make([]namedValue, len(args))
	for i, nv := range args {
		list[i] = toNamedValue(nv)
	}
	return s.exec(ctx, list)
}

/* FIXME
This is my fault that I've add code using sql.Out until next release.
func (c *OCI8Conn) CheckNamedValue(nv *driver.NamedValue) error {
	switch nv.Value.(type) {
	default:
		return driver.ErrSkip
	case sql.Out:
		return nil
	}
}
*/
<|endoftext|>


<commit_before>// Copyright 2010 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 ocsp parses OCSP responses as specified in RFC 2560. OCSP responses
// are signed messages attesting to the validity of a certificate for a small
// period of time. This is used to manage revocation for X.509 certificates.
package ocsp

import (
	"crypto"
	"crypto/rsa"
	_ "crypto/sha1"
	"crypto/x509"
	"crypto/x509/pkix"
	"encoding/asn1"
	"time"
)

var idPKIXOCSPBasic = asn1.ObjectIdentifier([]int{1, 3, 6, 1, 5, 5, 7, 48, 1, 1})
var idSHA1WithRSA = asn1.ObjectIdentifier([]int{1, 2, 840, 113549, 1, 1, 5})

// These are internal structures that reflect the ASN.1 structure of an OCSP
// response. See RFC 2560, section 4.2.

const (
	ocspSuccess       = 0
	ocspMalformed     = 1
	ocspInternalError = 2
	ocspTryLater      = 3
	ocspSigRequired   = 4
	ocspUnauthorized  = 5
)

type certID struct {
	HashAlgorithm pkix.AlgorithmIdentifier
	NameHash      []byte
	IssuerKeyHash []byte
	SerialNumber  asn1.RawValue
}

type responseASN1 struct {
	Status   asn1.Enumerated
	Response responseBytes `asn1:"explicit,tag:0"`
}

type responseBytes struct {
	ResponseType asn1.ObjectIdentifier
	Response     []byte
}

type basicResponse struct {
	TBSResponseData    responseData
	SignatureAlgorithm pkix.AlgorithmIdentifier
	Signature          asn1.BitString
	Certificates       []asn1.RawValue `asn1:"explicit,tag:0,optional"`
}

type responseData struct {
	Raw           asn1.RawContent
	Version       int              `asn1:"optional,default:1,explicit,tag:0"`
	RequestorName pkix.RDNSequence `asn1:"optional,explicit,tag:1"`
	KeyHash       []byte           `asn1:"optional,explicit,tag:2"`
	ProducedAt    time.Time
	Responses     []singleResponse
}

type singleResponse struct {
	CertID     certID
	Good       asn1.Flag   `asn1:"explicit,tag:0,optional"`
	Revoked    revokedInfo `asn1:"explicit,tag:1,optional"`
	Unknown    asn1.Flag   `asn1:"explicit,tag:2,optional"`
	ThisUpdate time.Time
	NextUpdate time.Time `asn1:"explicit,tag:0,optional"`
}

type revokedInfo struct {
	RevocationTime time.Time
	Reason         int `asn1:"explicit,tag:0,optional"`
}

// This is the exposed reflection of the internal OCSP structures.

const (
	// Good means that the certificate is valid.
	Good = iota
	// Revoked means that the certificate has been deliberately revoked.
	Revoked = iota
	// Unknown means that the OCSP responder doesn't know about the certificate.
	Unknown = iota
	// ServerFailed means that the OCSP responder failed to process the request.
	ServerFailed = iota
)

// Response represents an OCSP response. See RFC 2560.
type Response struct {
	// Status is one of {Good, Revoked, Unknown, ServerFailed}
	Status                                        int
	SerialNumber                                  []byte
	ProducedAt, ThisUpdate, NextUpdate, RevokedAt time.Time
	RevocationReason                              int
	Certificate                                   *x509.Certificate
}

// ParseError results from an invalid OCSP response.
type ParseError string

func (p ParseError) Error() string {
	return string(p)
}

// ParseResponse parses an OCSP response in DER form. It only supports
// responses for a single certificate and only those using RSA signatures.
// Non-RSA responses will result in an x509.UnsupportedAlgorithmError.
// Signature errors or parse failures will result in a ParseError.
func ParseResponse(bytes []byte) (*Response, error) {
	var resp responseASN1
	rest, err := asn1.Unmarshal(bytes, &resp)
	if err != nil {
		return nil, err
	}
	if len(rest) > 0 {
		return nil, ParseError("trailing data in OCSP response")
	}

	ret := new(Response)
	if resp.Status != ocspSuccess {
		ret.Status = ServerFailed
		return ret, nil
	}

	if !resp.Response.ResponseType.Equal(idPKIXOCSPBasic) {
		return nil, ParseError("bad OCSP response type")
	}

	var basicResp basicResponse
	rest, err = asn1.Unmarshal(resp.Response.Response, &basicResp)
	if err != nil {
		return nil, err
	}

	if len(basicResp.Certificates) != 1 {
		return nil, ParseError("OCSP response contains bad number of certificates")
	}

	if len(basicResp.TBSResponseData.Responses) != 1 {
		return nil, ParseError("OCSP response contains bad number of responses")
	}

	ret.Certificate, err = x509.ParseCertificate(basicResp.Certificates[0].FullBytes)
	if err != nil {
		return nil, err
	}

	if ret.Certificate.PublicKeyAlgorithm != x509.RSA || !basicResp.SignatureAlgorithm.Algorithm.Equal(idSHA1WithRSA) {
		return nil, x509.UnsupportedAlgorithmError{}
	}

	hashType := crypto.SHA1
	h := hashType.New()

	pub := ret.Certificate.PublicKey.(*rsa.PublicKey)
	h.Write(basicResp.TBSResponseData.Raw)
	digest := h.Sum(nil)
	signature := basicResp.Signature.RightAlign()

	if rsa.VerifyPKCS1v15(pub, hashType, digest, signature) != nil {
		return nil, ParseError("bad OCSP signature")
	}

	r := basicResp.TBSResponseData.Responses[0]

	ret.SerialNumber = r.CertID.SerialNumber.Bytes

	switch {
	case bool(r.Good):
		ret.Status = Good
	case bool(r.Unknown):
		ret.Status = Unknown
	default:
		ret.Status = Revoked
		ret.RevokedAt = r.Revoked.RevocationTime
		ret.RevocationReason = r.Revoked.Reason
	}

	ret.ProducedAt = basicResp.TBSResponseData.ProducedAt
	ret.ThisUpdate = r.ThisUpdate
	ret.NextUpdate = r.NextUpdate

	return ret, nil
}
<commit_msg>go.crypto: Update for new crypto/x509 error.<commit_after>// Copyright 2010 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 ocsp parses OCSP responses as specified in RFC 2560. OCSP responses
// are signed messages attesting to the validity of a certificate for a small
// period of time. This is used to manage revocation for X.509 certificates.
package ocsp

import (
	"crypto"
	"crypto/rsa"
	_ "crypto/sha1"
	"crypto/x509"
	"crypto/x509/pkix"
	"encoding/asn1"
	"time"
)

var idPKIXOCSPBasic = asn1.ObjectIdentifier([]int{1, 3, 6, 1, 5, 5, 7, 48, 1, 1})
var idSHA1WithRSA = asn1.ObjectIdentifier([]int{1, 2, 840, 113549, 1, 1, 5})

// These are internal structures that reflect the ASN.1 structure of an OCSP
// response. See RFC 2560, section 4.2.

const (
	ocspSuccess       = 0
	ocspMalformed     = 1
	ocspInternalError = 2
	ocspTryLater      = 3
	ocspSigRequired   = 4
	ocspUnauthorized  = 5
)

type certID struct {
	HashAlgorithm pkix.AlgorithmIdentifier
	NameHash      []byte
	IssuerKeyHash []byte
	SerialNumber  asn1.RawValue
}

type responseASN1 struct {
	Status   asn1.Enumerated
	Response responseBytes `asn1:"explicit,tag:0"`
}

type responseBytes struct {
	ResponseType asn1.ObjectIdentifier
	Response     []byte
}

type basicResponse struct {
	TBSResponseData    responseData
	SignatureAlgorithm pkix.AlgorithmIdentifier
	Signature          asn1.BitString
	Certificates       []asn1.RawValue `asn1:"explicit,tag:0,optional"`
}

type responseData struct {
	Raw           asn1.RawContent
	Version       int              `asn1:"optional,default:1,explicit,tag:0"`
	RequestorName pkix.RDNSequence `asn1:"optional,explicit,tag:1"`
	KeyHash       []byte           `asn1:"optional,explicit,tag:2"`
	ProducedAt    time.Time
	Responses     []singleResponse
}

type singleResponse struct {
	CertID     certID
	Good       asn1.Flag   `asn1:"explicit,tag:0,optional"`
	Revoked    revokedInfo `asn1:"explicit,tag:1,optional"`
	Unknown    asn1.Flag   `asn1:"explicit,tag:2,optional"`
	ThisUpdate time.Time
	NextUpdate time.Time `asn1:"explicit,tag:0,optional"`
}

type revokedInfo struct {
	RevocationTime time.Time
	Reason         int `asn1:"explicit,tag:0,optional"`
}

// This is the exposed reflection of the internal OCSP structures.

const (
	// Good means that the certificate is valid.
	Good = iota
	// Revoked means that the certificate has been deliberately revoked.
	Revoked = iota
	// Unknown means that the OCSP responder doesn't know about the certificate.
	Unknown = iota
	// ServerFailed means that the OCSP responder failed to process the request.
	ServerFailed = iota
)

// Response represents an OCSP response. See RFC 2560.
type Response struct {
	// Status is one of {Good, Revoked, Unknown, ServerFailed}
	Status                                        int
	SerialNumber                                  []byte
	ProducedAt, ThisUpdate, NextUpdate, RevokedAt time.Time
	RevocationReason                              int
	Certificate                                   *x509.Certificate
}

// ParseError results from an invalid OCSP response.
type ParseError string

func (p ParseError) Error() string {
	return string(p)
}

// ParseResponse parses an OCSP response in DER form. It only supports
// responses for a single certificate and only those using RSA signatures.
// Non-RSA responses will result in an x509.UnsupportedAlgorithmError.
// Signature errors or parse failures will result in a ParseError.
func ParseResponse(bytes []byte) (*Response, error) {
	var resp responseASN1
	rest, err := asn1.Unmarshal(bytes, &resp)
	if err != nil {
		return nil, err
	}
	if len(rest) > 0 {
		return nil, ParseError("trailing data in OCSP response")
	}

	ret := new(Response)
	if resp.Status != ocspSuccess {
		ret.Status = ServerFailed
		return ret, nil
	}

	if !resp.Response.ResponseType.Equal(idPKIXOCSPBasic) {
		return nil, ParseError("bad OCSP response type")
	}

	var basicResp basicResponse
	rest, err = asn1.Unmarshal(resp.Response.Response, &basicResp)
	if err != nil {
		return nil, err
	}

	if len(basicResp.Certificates) != 1 {
		return nil, ParseError("OCSP response contains bad number of certificates")
	}

	if len(basicResp.TBSResponseData.Responses) != 1 {
		return nil, ParseError("OCSP response contains bad number of responses")
	}

	ret.Certificate, err = x509.ParseCertificate(basicResp.Certificates[0].FullBytes)
	if err != nil {
		return nil, err
	}

	if ret.Certificate.PublicKeyAlgorithm != x509.RSA || !basicResp.SignatureAlgorithm.Algorithm.Equal(idSHA1WithRSA) {
		return nil, x509.ErrUnsupportedAlgorithm
	}

	hashType := crypto.SHA1
	h := hashType.New()

	pub := ret.Certificate.PublicKey.(*rsa.PublicKey)
	h.Write(basicResp.TBSResponseData.Raw)
	digest := h.Sum(nil)
	signature := basicResp.Signature.RightAlign()

	if rsa.VerifyPKCS1v15(pub, hashType, digest, signature) != nil {
		return nil, ParseError("bad OCSP signature")
	}

	r := basicResp.TBSResponseData.Responses[0]

	ret.SerialNumber = r.CertID.SerialNumber.Bytes

	switch {
	case bool(r.Good):
		ret.Status = Good
	case bool(r.Unknown):
		ret.Status = Unknown
	default:
		ret.Status = Revoked
		ret.RevokedAt = r.Revoked.RevocationTime
		ret.RevocationReason = r.Revoked.Reason
	}

	ret.ProducedAt = basicResp.TBSResponseData.ProducedAt
	ret.ThisUpdate = r.ThisUpdate
	ret.NextUpdate = r.NextUpdate

	return ret, nil
}
<|endoftext|>


<commit_before>package grifts

import (
	"fmt"
	"html/template"
	"os"
	"os/exec"
	"path"
	"sort"
	"strings"

	"github.com/gobuffalo/envy"
	"github.com/markbates/deplist"
	"github.com/markbates/grift/grift"
)

var _ = grift.Desc("shoulders", "Prints a listing all of the 3rd party packages used by buffalo.")
var _ = grift.Add("shoulders:list", func(c *grift.Context) error {
	giants, _ := deplist.List("examples")
	for _, k := range []string{
		"github.com/markbates/refresh",
		"github.com/markbates/grift",
		"github.com/markbates/pop",
		"github.com/spf13/cobra",
		"github.com/motemen/gore",
		"golang.org/x/tools/cmd/goimports",
		"github.com/nicksnyder/go-i18n",
	} {
		giants[k] = k
	}

	deps := make([]string, 0, len(giants))
	for k := range giants {
		if !strings.Contains(k, "github.com/gobuffalo/buffalo") {
			deps = append(deps, k)
		}
	}
	sort.Strings(deps)
	fmt.Println(strings.Join(deps, "\n"))
	c.Set("giants", deps)
	return nil
})

var _ = grift.Desc("shoulders", "Generates a file listing all of the 3rd party packages used by buffalo.")
var _ = grift.Add("shoulders", func(c *grift.Context) error {
	err := grift.Run("shoulders:list", c)
	if err != nil {
		return err
	}
	f, err := os.Create(path.Join(envy.GoPath(), "src", "github.com", "gobuffalo", "buffalo", "SHOULDERS.md"))
	if err != nil {
		return err
	}
	t, err := template.New("").Parse(shouldersTemplate)
	if err != nil {
		return err
	}
	err = t.Execute(f, c.Value("giants"))
	if err != nil {
		return err
	}

	return commitAndPushShoulders()
})

func commitAndPushShoulders() error {
	cmd := exec.Command("git", "commit", "SHOULDERS.md", "-m", "Updated SHOULDERS.md")
	cmd.Stdin = os.Stdin
	cmd.Stderr = os.Stderr
	cmd.Stdout = os.Stdout
	err := cmd.Run()
	if err != nil {
		return err
	}

	cmd = exec.Command("git", "push", "origin")
	cmd.Stdin = os.Stdin
	cmd.Stderr = os.Stderr
	cmd.Stdout = os.Stdout
	return cmd.Run()
}

var shouldersTemplate = `
# Buffalo Stands on the Shoulders of Giants

Buffalo does not try to reinvent the wheel! Instead, it uses the already great wheels developed by the Go community and puts them altogether in the best way possible. Without these giants this project would not be possible. Please make sure to check them out and thank them for all of their hard work.

Thank you to the following **GIANTS**:

{{ range $v := .}}
* [{{$v}}](https://{{$v}})
{{ end }}
`
<commit_msg>fixed a bug in getting the correct deps list for SHOULDERS.md<commit_after>package grifts

import (
	"fmt"
	"html/template"
	"os"
	"os/exec"
	"path"
	"sort"
	"strings"

	"github.com/gobuffalo/envy"
	"github.com/markbates/deplist"
	"github.com/markbates/grift/grift"
)

var _ = grift.Desc("shoulders", "Prints a listing all of the 3rd party packages used by buffalo.")
var _ = grift.Add("shoulders:list", func(c *grift.Context) error {
	giants, _ := deplist.List("examples")
	for _, k := range []string{
		"github.com/motemen/gore",
		"golang.org/x/tools/cmd/goimports",
	} {
		giants[k] = k
	}

	deps := make([]string, 0, len(giants))
	for k := range giants {
		if !strings.Contains(k, "github.com/gobuffalo/buffalo") {
			deps = append(deps, k)
		}
	}
	sort.Strings(deps)
	fmt.Println(strings.Join(deps, "\n"))
	c.Set("giants", deps)
	return nil
})

var _ = grift.Desc("shoulders", "Generates a file listing all of the 3rd party packages used by buffalo.")
var _ = grift.Add("shoulders", func(c *grift.Context) error {
	err := grift.Run("shoulders:list", c)
	if err != nil {
		return err
	}
	f, err := os.Create(path.Join(envy.GoPath(), "src", "github.com", "gobuffalo", "buffalo", "SHOULDERS.md"))
	if err != nil {
		return err
	}
	t, err := template.New("").Parse(shouldersTemplate)
	if err != nil {
		return err
	}
	err = t.Execute(f, c.Value("giants"))
	if err != nil {
		return err
	}

	return commitAndPushShoulders()
})

func commitAndPushShoulders() error {
	cmd := exec.Command("git", "commit", "SHOULDERS.md", "-m", "Updated SHOULDERS.md")
	cmd.Stdin = os.Stdin
	cmd.Stderr = os.Stderr
	cmd.Stdout = os.Stdout
	err := cmd.Run()
	if err != nil {
		return err
	}

	cmd = exec.Command("git", "push", "origin")
	cmd.Stdin = os.Stdin
	cmd.Stderr = os.Stderr
	cmd.Stdout = os.Stdout
	return cmd.Run()
}

var shouldersTemplate = `
# Buffalo Stands on the Shoulders of Giants

Buffalo does not try to reinvent the wheel! Instead, it uses the already great wheels developed by the Go community and puts them altogether in the best way possible. Without these giants this project would not be possible. Please make sure to check them out and thank them for all of their hard work.

Thank you to the following **GIANTS**:

{{ range $v := .}}
* [{{$v}}](https://{{$v}})
{{ end }}
`
<|endoftext|>


<commit_before>// Package parser implements a parser and parse tree dumper for Dockerfiles.
package parser

import (
	"bufio"
	"bytes"
	"fmt"
	"io"
	"regexp"
	"strings"
	"unicode"

	"github.com/docker/docker/builder/dockerfile/command"
)

// Node is a structure used to represent a parse tree.
//
// In the node there are three fields, Value, Next, and Children. Value is the
// current token's string value. Next is always the next non-child token, and
// children contains all the children. Here's an example:
//
// (value next (child child-next child-next-next) next-next)
//
// This data structure is frankly pretty lousy for handling complex languages,
// but lucky for us the Dockerfile isn't very complicated. This structure
// works a little more effectively than a "proper" parse tree for our needs.
//
type Node struct {
	Value      string          // actual content
	Next       *Node           // the next item in the current sexp
	Children   []*Node         // the children of this sexp
	Attributes map[string]bool // special attributes for this node
	Original   string          // original line used before parsing
	Flags      []string        // only top Node should have this set
	StartLine  int             // the line in the original dockerfile where the node begins
	EndLine    int             // the line in the original dockerfile where the node ends
}

// Directive is the structure used during a build run to hold the state of
// parsing directives.
type Directive struct {
	EscapeToken           rune           // Current escape token
	LineContinuationRegex *regexp.Regexp // Current line contination regex
	LookingForDirectives  bool           // Whether we are currently looking for directives
	EscapeSeen            bool           // Whether the escape directive has been seen
}

var (
	dispatch           map[string]func(string, *Directive) (*Node, map[string]bool, error)
	tokenWhitespace    = regexp.MustCompile(`[\t\v\f\r ]+`)
	tokenEscapeCommand = regexp.MustCompile(`^#[ \t]*escape[ \t]*=[ \t]*(?P<escapechar>.).*$`)
	tokenComment       = regexp.MustCompile(`^#.*$`)
)

// DefaultEscapeToken is the default escape token
const DefaultEscapeToken = "\\"

// SetEscapeToken sets the default token for escaping characters in a Dockerfile.
func SetEscapeToken(s string, d *Directive) error {
	if s != "`" && s != "\\" {
		return fmt.Errorf("invalid ESCAPE '%s'. Must be ` or \\", s)
	}
	d.EscapeToken = rune(s[0])
	d.LineContinuationRegex = regexp.MustCompile(`\` + s + `[ \t]*$`)
	return nil
}

func init() {
	// Dispatch Table. see line_parsers.go for the parse functions.
	// The command is parsed and mapped to the line parser. The line parser
	// receives the arguments but not the command, and returns an AST after
	// reformulating the arguments according to the rules in the parser
	// functions. Errors are propagated up by Parse() and the resulting AST can
	// be incorporated directly into the existing AST as a next.
	dispatch = map[string]func(string, *Directive) (*Node, map[string]bool, error){
		command.Add:         parseMaybeJSONToList,
		command.Arg:         parseNameOrNameVal,
		command.Cmd:         parseMaybeJSON,
		command.Copy:        parseMaybeJSONToList,
		command.Entrypoint:  parseMaybeJSON,
		command.Env:         parseEnv,
		command.Expose:      parseStringsWhitespaceDelimited,
		command.From:        parseString,
		command.Healthcheck: parseHealthConfig,
		command.Label:       parseLabel,
		command.Maintainer:  parseString,
		command.Onbuild:     parseSubCommand,
		command.Run:         parseMaybeJSON,
		command.Shell:       parseMaybeJSON,
		command.StopSignal:  parseString,
		command.User:        parseString,
		command.Volume:      parseMaybeJSONToList,
		command.Workdir:     parseString,
	}
}

// ParseLine parses a line and returns the remainder.
func ParseLine(line string, d *Directive, ignoreCont bool) (string, *Node, error) {
	// Handle the parser directive '# escape=<char>. Parser directives must precede
	// any builder instruction or other comments, and cannot be repeated.
	if d.LookingForDirectives {
		tecMatch := tokenEscapeCommand.FindStringSubmatch(strings.ToLower(line))
		if len(tecMatch) > 0 {
			if d.EscapeSeen == true {
				return "", nil, fmt.Errorf("only one escape parser directive can be used")
			}
			for i, n := range tokenEscapeCommand.SubexpNames() {
				if n == "escapechar" {
					if err := SetEscapeToken(tecMatch[i], d); err != nil {
						return "", nil, err
					}
					d.EscapeSeen = true
					return "", nil, nil
				}
			}
		}
	}

	d.LookingForDirectives = false

	if line = stripComments(line); line == "" {
		return "", nil, nil
	}

	if !ignoreCont && d.LineContinuationRegex.MatchString(line) {
		line = d.LineContinuationRegex.ReplaceAllString(line, "")
		return line, nil, nil
	}

	cmd, flags, args, err := splitCommand(line)
	if err != nil {
		return "", nil, err
	}

	node := &Node{}
	node.Value = cmd

	sexp, attrs, err := fullDispatch(cmd, args, d)
	if err != nil {
		return "", nil, err
	}

	node.Next = sexp
	node.Attributes = attrs
	node.Original = line
	node.Flags = flags

	return "", node, nil
}

// Parse is the main parse routine.
// It handles an io.ReadWriteCloser and returns the root of the AST.
func Parse(rwc io.Reader, d *Directive) (*Node, error) {
	currentLine := 0
	root := &Node{}
	root.StartLine = -1
	scanner := bufio.NewScanner(rwc)

	utf8bom := []byte{0xEF, 0xBB, 0xBF}
	for scanner.Scan() {
		scannedBytes := scanner.Bytes()
		// We trim UTF8 BOM
		if currentLine == 0 {
			scannedBytes = bytes.TrimPrefix(scannedBytes, utf8bom)
		}
		scannedLine := strings.TrimLeftFunc(string(scannedBytes), unicode.IsSpace)
		currentLine++
		line, child, err := ParseLine(scannedLine, d, false)
		if err != nil {
			return nil, err
		}
		startLine := currentLine

		if line != "" && child == nil {
			for scanner.Scan() {
				newline := scanner.Text()
				currentLine++

				if stripComments(strings.TrimSpace(newline)) == "" {
					continue
				}

				line, child, err = ParseLine(line+newline, d, false)
				if err != nil {
					return nil, err
				}

				if child != nil {
					break
				}
			}
			if child == nil && line != "" {
				// When we call ParseLine we'll pass in 'true' for
				// the ignoreCont param if we're at the EOF. This will
				// prevent the func from returning immediately w/o
				// parsing the line thinking that there's more input
				// to come.

				_, child, err = ParseLine(line, d, scanner.Err() == nil)
				if err != nil {
					return nil, err
				}
			}
		}

		if child != nil {
			// Update the line information for the current child.
			child.StartLine = startLine
			child.EndLine = currentLine
			// Update the line information for the root. The starting line of the root is always the
			// starting line of the first child and the ending line is the ending line of the last child.
			if root.StartLine < 0 {
				root.StartLine = currentLine
			}
			root.EndLine = currentLine
			root.Children = append(root.Children, child)
		}
	}

	return root, nil
}
<commit_msg>why there are so many mistakes in our repo (up to /cmd)<commit_after>// Package parser implements a parser and parse tree dumper for Dockerfiles.
package parser

import (
	"bufio"
	"bytes"
	"fmt"
	"io"
	"regexp"
	"strings"
	"unicode"

	"github.com/docker/docker/builder/dockerfile/command"
)

// Node is a structure used to represent a parse tree.
//
// In the node there are three fields, Value, Next, and Children. Value is the
// current token's string value. Next is always the next non-child token, and
// children contains all the children. Here's an example:
//
// (value next (child child-next child-next-next) next-next)
//
// This data structure is frankly pretty lousy for handling complex languages,
// but lucky for us the Dockerfile isn't very complicated. This structure
// works a little more effectively than a "proper" parse tree for our needs.
//
type Node struct {
	Value      string          // actual content
	Next       *Node           // the next item in the current sexp
	Children   []*Node         // the children of this sexp
	Attributes map[string]bool // special attributes for this node
	Original   string          // original line used before parsing
	Flags      []string        // only top Node should have this set
	StartLine  int             // the line in the original dockerfile where the node begins
	EndLine    int             // the line in the original dockerfile where the node ends
}

// Directive is the structure used during a build run to hold the state of
// parsing directives.
type Directive struct {
	EscapeToken           rune           // Current escape token
	LineContinuationRegex *regexp.Regexp // Current line continuation regex
	LookingForDirectives  bool           // Whether we are currently looking for directives
	EscapeSeen            bool           // Whether the escape directive has been seen
}

var (
	dispatch           map[string]func(string, *Directive) (*Node, map[string]bool, error)
	tokenWhitespace    = regexp.MustCompile(`[\t\v\f\r ]+`)
	tokenEscapeCommand = regexp.MustCompile(`^#[ \t]*escape[ \t]*=[ \t]*(?P<escapechar>.).*$`)
	tokenComment       = regexp.MustCompile(`^#.*$`)
)

// DefaultEscapeToken is the default escape token
const DefaultEscapeToken = "\\"

// SetEscapeToken sets the default token for escaping characters in a Dockerfile.
func SetEscapeToken(s string, d *Directive) error {
	if s != "`" && s != "\\" {
		return fmt.Errorf("invalid ESCAPE '%s'. Must be ` or \\", s)
	}
	d.EscapeToken = rune(s[0])
	d.LineContinuationRegex = regexp.MustCompile(`\` + s + `[ \t]*$`)
	return nil
}

func init() {
	// Dispatch Table. see line_parsers.go for the parse functions.
	// The command is parsed and mapped to the line parser. The line parser
	// receives the arguments but not the command, and returns an AST after
	// reformulating the arguments according to the rules in the parser
	// functions. Errors are propagated up by Parse() and the resulting AST can
	// be incorporated directly into the existing AST as a next.
	dispatch = map[string]func(string, *Directive) (*Node, map[string]bool, error){
		command.Add:         parseMaybeJSONToList,
		command.Arg:         parseNameOrNameVal,
		command.Cmd:         parseMaybeJSON,
		command.Copy:        parseMaybeJSONToList,
		command.Entrypoint:  parseMaybeJSON,
		command.Env:         parseEnv,
		command.Expose:      parseStringsWhitespaceDelimited,
		command.From:        parseString,
		command.Healthcheck: parseHealthConfig,
		command.Label:       parseLabel,
		command.Maintainer:  parseString,
		command.Onbuild:     parseSubCommand,
		command.Run:         parseMaybeJSON,
		command.Shell:       parseMaybeJSON,
		command.StopSignal:  parseString,
		command.User:        parseString,
		command.Volume:      parseMaybeJSONToList,
		command.Workdir:     parseString,
	}
}

// ParseLine parses a line and returns the remainder.
func ParseLine(line string, d *Directive, ignoreCont bool) (string, *Node, error) {
	// Handle the parser directive '# escape=<char>. Parser directives must precede
	// any builder instruction or other comments, and cannot be repeated.
	if d.LookingForDirectives {
		tecMatch := tokenEscapeCommand.FindStringSubmatch(strings.ToLower(line))
		if len(tecMatch) > 0 {
			if d.EscapeSeen == true {
				return "", nil, fmt.Errorf("only one escape parser directive can be used")
			}
			for i, n := range tokenEscapeCommand.SubexpNames() {
				if n == "escapechar" {
					if err := SetEscapeToken(tecMatch[i], d); err != nil {
						return "", nil, err
					}
					d.EscapeSeen = true
					return "", nil, nil
				}
			}
		}
	}

	d.LookingForDirectives = false

	if line = stripComments(line); line == "" {
		return "", nil, nil
	}

	if !ignoreCont && d.LineContinuationRegex.MatchString(line) {
		line = d.LineContinuationRegex.ReplaceAllString(line, "")
		return line, nil, nil
	}

	cmd, flags, args, err := splitCommand(line)
	if err != nil {
		return "", nil, err
	}

	node := &Node{}
	node.Value = cmd

	sexp, attrs, err := fullDispatch(cmd, args, d)
	if err != nil {
		return "", nil, err
	}

	node.Next = sexp
	node.Attributes = attrs
	node.Original = line
	node.Flags = flags

	return "", node, nil
}

// Parse is the main parse routine.
// It handles an io.ReadWriteCloser and returns the root of the AST.
func Parse(rwc io.Reader, d *Directive) (*Node, error) {
	currentLine := 0
	root := &Node{}
	root.StartLine = -1
	scanner := bufio.NewScanner(rwc)

	utf8bom := []byte{0xEF, 0xBB, 0xBF}
	for scanner.Scan() {
		scannedBytes := scanner.Bytes()
		// We trim UTF8 BOM
		if currentLine == 0 {
			scannedBytes = bytes.TrimPrefix(scannedBytes, utf8bom)
		}
		scannedLine := strings.TrimLeftFunc(string(scannedBytes), unicode.IsSpace)
		currentLine++
		line, child, err := ParseLine(scannedLine, d, false)
		if err != nil {
			return nil, err
		}
		startLine := currentLine

		if line != "" && child == nil {
			for scanner.Scan() {
				newline := scanner.Text()
				currentLine++

				if stripComments(strings.TrimSpace(newline)) == "" {
					continue
				}

				line, child, err = ParseLine(line+newline, d, false)
				if err != nil {
					return nil, err
				}

				if child != nil {
					break
				}
			}
			if child == nil && line != "" {
				// When we call ParseLine we'll pass in 'true' for
				// the ignoreCont param if we're at the EOF. This will
				// prevent the func from returning immediately w/o
				// parsing the line thinking that there's more input
				// to come.

				_, child, err = ParseLine(line, d, scanner.Err() == nil)
				if err != nil {
					return nil, err
				}
			}
		}

		if child != nil {
			// Update the line information for the current child.
			child.StartLine = startLine
			child.EndLine = currentLine
			// Update the line information for the root. The starting line of the root is always the
			// starting line of the first child and the ending line is the ending line of the last child.
			if root.StartLine < 0 {
				root.StartLine = currentLine
			}
			root.EndLine = currentLine
			root.Children = append(root.Children, child)
		}
	}

	return root, nil
}
<|endoftext|>