<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.

// This file contains printing suppport for ASTs.

package ast

import (
	"fmt"
	"go/token"
	"io"
	"os"
	"reflect"
)

// A FieldFilter may be provided to Fprint to control the output.
type FieldFilter func(name string, value reflect.Value) bool

// NotNilFilter returns true for field values that are not nil;
// it returns false otherwise.
func NotNilFilter(_ string, value reflect.Value) bool {
	v, ok := value.(interface {
		IsNil() bool
	})
	return !ok || !v.IsNil()
}

// Fprint prints the (sub-)tree starting at AST node x to w.
//
// A non-nil FieldFilter f may be provided to control the output:
// struct fields for which f(fieldname, fieldvalue) is true are
// are printed; all others are filtered from the output.
//
func Fprint(w io.Writer, x interface{}, f FieldFilter) (n int, err os.Error) {
	// setup printer
	p := printer{
		output: w,
		filter: f,
		ptrmap: make(map[interface{}]int),
		last:   '\n', // force printing of line number on first line
	}

	// install error handler
	defer func() {
		n = p.written
		if e := recover(); e != nil {
			err = e.(localError).err // re-panics if it's not a localError
		}
	}()

	// print x
	if x == nil {
		p.printf("nil\n")
		return
	}
	p.print(reflect.NewValue(x))
	p.printf("\n")

	return
}

// Print prints x to standard output, skipping nil fields.
// Print(x) is the same as Fprint(os.Stdout, x, NotNilFilter).
func Print(x interface{}) (int, os.Error) {
	return Fprint(os.Stdout, x, NotNilFilter)
}

type printer struct {
	output  io.Writer
	filter  FieldFilter
	ptrmap  map[interface{}]int // *reflect.PtrValue -> line number
	written int                 // number of bytes written to output
	indent  int                 // current indentation level
	last    byte                // the last byte processed by Write
	line    int                 // current line number
}

var indent = []byte(".  ")

func (p *printer) Write(data []byte) (n int, err os.Error) {
	var m int
	for i, b := range data {
		// invariant: data[0:n] has been written
		if b == '\n' {
			m, err = p.output.Write(data[n : i+1])
			n += m
			if err != nil {
				return
			}
			p.line++
		} else if p.last == '\n' {
			_, err = fmt.Fprintf(p.output, "%6d  ", p.line)
			if err != nil {
				return
			}
			for j := p.indent; j > 0; j-- {
				_, err = p.output.Write(indent)
				if err != nil {
					return
				}
			}
		}
		p.last = b
	}
	m, err = p.output.Write(data[n:])
	n += m
	return
}

// localError wraps locally caught os.Errors so we can distinguish
// them from genuine panics which we don't want to return as errors.
type localError struct {
	err os.Error
}

// printf is a convenience wrapper that takes care of print errors.
func (p *printer) printf(format string, args ...interface{}) {
	n, err := fmt.Fprintf(p, format, args...)
	p.written += n
	if err != nil {
		panic(localError{err})
	}
}

// Implementation note: Print is written for AST nodes but could be
// used to print arbitrary data structures; such a version should
// probably be in a different package.

func (p *printer) print(x reflect.Value) {
	// Note: This test is only needed because AST nodes
	//       embed a token.Position, and thus all of them
	//       understand the String() method (but it only
	//       applies to the Position field).
	// TODO: Should reconsider this AST design decision.
	if pos, ok := x.Interface().(token.Position); ok {
		p.printf("%s", pos)
		return
	}

	if !NotNilFilter("", x) {
		p.printf("nil")
		return
	}

	switch v := x.(type) {
	case *reflect.InterfaceValue:
		p.print(v.Elem())

	case *reflect.MapValue:
		p.printf("%s (len = %d) {\n", x.Type().String(), v.Len())
		p.indent++
		for _, key := range v.Keys() {
			p.print(key)
			p.printf(": ")
			p.print(v.Elem(key))
		}
		p.indent--
		p.printf("}")

	case *reflect.PtrValue:
		p.printf("*")
		// type-checked ASTs may contain cycles - use ptrmap
		// to keep track of objects that have been printed
		// already and print the respective line number instead
		ptr := v.Interface()
		if line, exists := p.ptrmap[ptr]; exists {
			p.printf("(obj @ %d)", line)
		} else {
			p.ptrmap[ptr] = p.line
			p.print(v.Elem())
		}

	case *reflect.SliceValue:
		if s, ok := v.Interface().([]byte); ok {
			p.printf("%#q", s)
			return
		}
		p.printf("%s (len = %d) {\n", x.Type().String(), v.Len())
		p.indent++
		for i, n := 0, v.Len(); i < n; i++ {
			p.printf("%d: ", i)
			p.print(v.Elem(i))
			p.printf("\n")
		}
		p.indent--
		p.printf("}")

	case *reflect.StructValue:
		p.printf("%s {\n", x.Type().String())
		p.indent++
		t := v.Type().(*reflect.StructType)
		for i, n := 0, t.NumField(); i < n; i++ {
			name := t.Field(i).Name
			value := v.Field(i)
			if p.filter == nil || p.filter(name, value) {
				p.printf("%s: ", name)
				p.print(value)
				p.printf("\n")
			}
		}
		p.indent--
		p.printf("}")

	default:
		p.printf("%v", x.Interface())
	}
}
<commit_msg>go/ast: ast.Print needs a file set to print position values nicely<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.

// This file contains printing suppport for ASTs.

package ast

import (
	"fmt"
	"go/token"
	"io"
	"os"
	"reflect"
)

// A FieldFilter may be provided to Fprint to control the output.
type FieldFilter func(name string, value reflect.Value) bool

// NotNilFilter returns true for field values that are not nil;
// it returns false otherwise.
func NotNilFilter(_ string, value reflect.Value) bool {
	v, ok := value.(interface {
		IsNil() bool
	})
	return !ok || !v.IsNil()
}

// Fprint prints the (sub-)tree starting at AST node x to w.
// If fset != nil, position information is interpreted relative
// to that file set. Otherwise positions are printed as integer
// values (file set specific offsets).
//
// A non-nil FieldFilter f may be provided to control the output:
// struct fields for which f(fieldname, fieldvalue) is true are
// are printed; all others are filtered from the output.
//
func Fprint(w io.Writer, fset *token.FileSet, x interface{}, f FieldFilter) (n int, err os.Error) {
	// setup printer
	p := printer{
		output: w,
		fset:   fset,
		filter: f,
		ptrmap: make(map[interface{}]int),
		last:   '\n', // force printing of line number on first line
	}

	// install error handler
	defer func() {
		n = p.written
		if e := recover(); e != nil {
			err = e.(localError).err // re-panics if it's not a localError
		}
	}()

	// print x
	if x == nil {
		p.printf("nil\n")
		return
	}
	p.print(reflect.NewValue(x))
	p.printf("\n")

	return
}

// Print prints x to standard output, skipping nil fields.
// Print(fset, x) is the same as Fprint(os.Stdout, fset, x, NotNilFilter).
func Print(fset *token.FileSet, x interface{}) (int, os.Error) {
	return Fprint(os.Stdout, fset, x, NotNilFilter)
}

type printer struct {
	output  io.Writer
	fset    *token.FileSet
	filter  FieldFilter
	ptrmap  map[interface{}]int // *reflect.PtrValue -> line number
	written int                 // number of bytes written to output
	indent  int                 // current indentation level
	last    byte                // the last byte processed by Write
	line    int                 // current line number
}

var indent = []byte(".  ")

func (p *printer) Write(data []byte) (n int, err os.Error) {
	var m int
	for i, b := range data {
		// invariant: data[0:n] has been written
		if b == '\n' {
			m, err = p.output.Write(data[n : i+1])
			n += m
			if err != nil {
				return
			}
			p.line++
		} else if p.last == '\n' {
			_, err = fmt.Fprintf(p.output, "%6d  ", p.line)
			if err != nil {
				return
			}
			for j := p.indent; j > 0; j-- {
				_, err = p.output.Write(indent)
				if err != nil {
					return
				}
			}
		}
		p.last = b
	}
	m, err = p.output.Write(data[n:])
	n += m
	return
}

// localError wraps locally caught os.Errors so we can distinguish
// them from genuine panics which we don't want to return as errors.
type localError struct {
	err os.Error
}

// printf is a convenience wrapper that takes care of print errors.
func (p *printer) printf(format string, args ...interface{}) {
	n, err := fmt.Fprintf(p, format, args...)
	p.written += n
	if err != nil {
		panic(localError{err})
	}
}

// Implementation note: Print is written for AST nodes but could be
// used to print arbitrary data structures; such a version should
// probably be in a different package.

func (p *printer) print(x reflect.Value) {
	if !NotNilFilter("", x) {
		p.printf("nil")
		return
	}

	switch v := x.(type) {
	case *reflect.InterfaceValue:
		p.print(v.Elem())

	case *reflect.MapValue:
		p.printf("%s (len = %d) {\n", x.Type().String(), v.Len())
		p.indent++
		for _, key := range v.Keys() {
			p.print(key)
			p.printf(": ")
			p.print(v.Elem(key))
		}
		p.indent--
		p.printf("}")

	case *reflect.PtrValue:
		p.printf("*")
		// type-checked ASTs may contain cycles - use ptrmap
		// to keep track of objects that have been printed
		// already and print the respective line number instead
		ptr := v.Interface()
		if line, exists := p.ptrmap[ptr]; exists {
			p.printf("(obj @ %d)", line)
		} else {
			p.ptrmap[ptr] = p.line
			p.print(v.Elem())
		}

	case *reflect.SliceValue:
		if s, ok := v.Interface().([]byte); ok {
			p.printf("%#q", s)
			return
		}
		p.printf("%s (len = %d) {\n", x.Type().String(), v.Len())
		p.indent++
		for i, n := 0, v.Len(); i < n; i++ {
			p.printf("%d: ", i)
			p.print(v.Elem(i))
			p.printf("\n")
		}
		p.indent--
		p.printf("}")

	case *reflect.StructValue:
		p.printf("%s {\n", x.Type().String())
		p.indent++
		t := v.Type().(*reflect.StructType)
		for i, n := 0, t.NumField(); i < n; i++ {
			name := t.Field(i).Name
			value := v.Field(i)
			if p.filter == nil || p.filter(name, value) {
				p.printf("%s: ", name)
				p.print(value)
				p.printf("\n")
			}
		}
		p.indent--
		p.printf("}")

	default:
		value := x.Interface()
		// position values can be printed nicely if we have a file set
		if pos, ok := value.(token.Pos); ok && p.fset != nil {
			value = p.fset.Position(pos)
		}
		p.printf("%v", value)
	}
}
<|endoftext|>


<commit_before>// Copyright 2009 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.

// Binary to decimal floating point conversion.
// Algorithm:
//   1) store mantissa in multiprecision decimal
//   2) shift decimal by exponent
//   3) read digits out & format

package strconv

import "math"

// TODO: move elsewhere?
type floatInfo struct {
	mantbits uint
	expbits  uint
	bias     int
}

var float32info = floatInfo{23, 8, -127}
var float64info = floatInfo{52, 11, -1023}

// Ftoa32 converts the 32-bit floating-point number f to a string,
// according to the format fmt and precision prec.
//
// The format fmt is one of
// 'b' (-ddddp±ddd, a binary exponent),
// 'e' (-d.dddde±dd, a decimal exponent),
// 'E' (-d.ddddE±dd, a decimal exponent),
// 'f' (-ddd.dddd, no exponent),
// 'g' ('e' for large exponents, 'f' otherwise), or
// 'G' ('E' for large exponents, 'f' otherwise).
//
// The precision prec controls the number of digits
// (excluding the exponent) printed by the 'e', 'E', 'f', 'g', and 'G' formats.
// For 'e', 'E', and 'f' it is the number of digits after the decimal point.
// For 'g' and 'G' it is the total number of digits.
// The special precision -1 uses the smallest number of digits
// necessary such that Atof32 will return f exactly.
//
// Ftoa32(f) is not the same as Ftoa64(float32(f)),
// because correct rounding and the number of digits
// needed to identify f depend on the precision of the representation.
func Ftoa32(f float32, fmt byte, prec int) string {
	return genericFtoa(uint64(math.Float32bits(f)), fmt, prec, &float32info)
}

// Ftoa64 is like Ftoa32 but converts a 64-bit floating-point number.
func Ftoa64(f float64, fmt byte, prec int) string {
	return genericFtoa(math.Float64bits(f), fmt, prec, &float64info)
}

// FtoaN converts the 64-bit floating-point number f to a string,
// according to the format fmt and precision prec, but it rounds the
// result assuming that it was obtained from a floating-point value
// of n bits (32 or 64).
func FtoaN(f float64, fmt byte, prec int, n int) string {
	if n == 32 {
		return Ftoa32(float32(f), fmt, prec)
	}
	return Ftoa64(f, fmt, prec)
}

func genericFtoa(bits uint64, fmt byte, prec int, flt *floatInfo) string {
	neg := bits>>flt.expbits>>flt.mantbits != 0
	exp := int(bits>>flt.mantbits) & (1<<flt.expbits - 1)
	mant := bits & (uint64(1)<<flt.mantbits - 1)

	switch exp {
	case 1<<flt.expbits - 1:
		// Inf, NaN
		if mant != 0 {
			return "NaN"
		}
		if neg {
			return "-Inf"
		}
		return "+Inf"

	case 0:
		// denormalized
		exp++

	default:
		// add implicit top bit
		mant |= uint64(1) << flt.mantbits
	}
	exp += flt.bias

	// Pick off easy binary format.
	if fmt == 'b' {
		return fmtB(neg, mant, exp, flt)
	}

	// Create exact decimal representation.
	// The shift is exp - flt.mantbits because mant is a 1-bit integer
	// followed by a flt.mantbits fraction, and we are treating it as
	// a 1+flt.mantbits-bit integer.
	d := newDecimal(mant).Shift(exp - int(flt.mantbits))

	// Round appropriately.
	// Negative precision means "only as much as needed to be exact."
	shortest := false
	if prec < 0 {
		shortest = true
		roundShortest(d, mant, exp, flt)
		switch fmt {
		case 'e', 'E':
			prec = d.nd - 1
		case 'f':
			prec = max(d.nd-d.dp, 0)
		case 'g', 'G':
			prec = d.nd
		}
	} else {
		switch fmt {
		case 'e', 'E':
			d.Round(prec + 1)
		case 'f':
			d.Round(d.dp + prec)
		case 'g', 'G':
			if prec == 0 {
				prec = 1
			}
			d.Round(prec)
		}
	}

	switch fmt {
	case 'e', 'E':
		return fmtE(neg, d, prec, fmt)
	case 'f':
		return fmtF(neg, d, prec)
	case 'g', 'G':
		// trailing fractional zeros in 'e' form will be trimmed.
		eprec := prec
		if eprec > d.nd && d.nd >= d.dp {
			eprec = d.nd
		}
		// %e is used if the exponent from the conversion
		// is less than -4 or greater than or equal to the precision.
		// if precision was the shortest possible, use precision 6 for this decision.
		if shortest {
			eprec = 6
		}
		exp := d.dp - 1
		if exp < -4 || exp >= eprec {
			if prec > d.nd {
				prec = d.nd
			}
			return fmtE(neg, d, prec-1, fmt+'e'-'g')
		}
		if prec > d.dp {
			prec = d.nd
		}
		return fmtF(neg, d, max(prec-d.dp, 0))
	}

	return "%" + string(fmt)
}

// Round d (= mant * 2^exp) to the shortest number of digits
// that will let the original floating point value be precisely
// reconstructed.  Size is original floating point size (64 or 32).
func roundShortest(d *decimal, mant uint64, exp int, flt *floatInfo) {
	// If mantissa is zero, the number is zero; stop now.
	if mant == 0 {
		d.nd = 0
		return
	}

	// TODO(rsc): Unless exp == minexp, if the number of digits in d
	// is less than 17, it seems likely that it would be
	// the shortest possible number already.  So maybe we can
	// bail out without doing the extra multiprecision math here.

	// Compute upper and lower such that any decimal number
	// between upper and lower (possibly inclusive)
	// will round to the original floating point number.

	// d = mant << (exp - mantbits)
	// Next highest floating point number is mant+1 << exp-mantbits.
	// Our upper bound is halfway inbetween, mant*2+1 << exp-mantbits-1.
	upper := newDecimal(mant*2 + 1).Shift(exp - int(flt.mantbits) - 1)

	// d = mant << (exp - mantbits)
	// Next lowest floating point number is mant-1 << exp-mantbits,
	// unless mant-1 drops the significant bit and exp is not the minimum exp,
	// in which case the next lowest is mant*2-1 << exp-mantbits-1.
	// Either way, call it mantlo << explo-mantbits.
	// Our lower bound is halfway inbetween, mantlo*2+1 << explo-mantbits-1.
	minexp := flt.bias + 1 // minimum possible exponent
	var mantlo uint64
	var explo int
	if mant > 1<<flt.mantbits || exp == minexp {
		mantlo = mant - 1
		explo = exp
	} else {
		mantlo = mant*2 - 1
		explo = exp - 1
	}
	lower := newDecimal(mantlo*2 + 1).Shift(explo - int(flt.mantbits) - 1)

	// The upper and lower bounds are possible outputs only if
	// the original mantissa is even, so that IEEE round-to-even
	// would round to the original mantissa and not the neighbors.
	inclusive := mant%2 == 0

	// Now we can figure out the minimum number of digits required.
	// Walk along until d has distinguished itself from upper and lower.
	for i := 0; i < d.nd; i++ {
		var l, m, u byte // lower, middle, upper digits
		if i < lower.nd {
			l = lower.d[i]
		} else {
			l = '0'
		}
		m = d.d[i]
		if i < upper.nd {
			u = upper.d[i]
		} else {
			u = '0'
		}

		// Okay to round down (truncate) if lower has a different digit
		// or if lower is inclusive and is exactly the result of rounding down.
		okdown := l != m || (inclusive && l == m && i+1 == lower.nd)

		// Okay to round up if upper has a different digit and
		// either upper is inclusive or upper is bigger than the result of rounding up.
		okup := m != u && (inclusive || i+1 < upper.nd)

		// If it's okay to do either, then round to the nearest one.
		// If it's okay to do only one, do it.
		switch {
		case okdown && okup:
			d.Round(i + 1)
			return
		case okdown:
			d.RoundDown(i + 1)
			return
		case okup:
			d.RoundUp(i + 1)
			return
		}
	}
}

// %e: -d.ddddde±dd
func fmtE(neg bool, d *decimal, prec int, fmt byte) string {
	buf := make([]byte, 3+max(prec, 0)+30) // "-0." + prec digits + exp
	w := 0                                 // write index

	// sign
	if neg {
		buf[w] = '-'
		w++
	}

	// first digit
	if d.nd == 0 {
		buf[w] = '0'
	} else {
		buf[w] = d.d[0]
	}
	w++

	// .moredigits
	if prec > 0 {
		buf[w] = '.'
		w++
		for i := 0; i < prec; i++ {
			if 1+i < d.nd {
				buf[w] = d.d[1+i]
			} else {
				buf[w] = '0'
			}
			w++
		}
	}

	// e±
	buf[w] = fmt
	w++
	exp := d.dp - 1
	if d.nd == 0 { // special case: 0 has exponent 0
		exp = 0
	}
	if exp < 0 {
		buf[w] = '-'
		exp = -exp
	} else {
		buf[w] = '+'
	}
	w++

	// dddd
	// count digits
	n := 0
	for e := exp; e > 0; e /= 10 {
		n++
	}
	// leading zeros
	for i := n; i < 2; i++ {
		buf[w] = '0'
		w++
	}
	// digits
	w += n
	n = 0
	for e := exp; e > 0; e /= 10 {
		n++
		buf[w-n] = byte(e%10 + '0')
	}

	return string(buf[0:w])
}

// %f: -ddddddd.ddddd
func fmtF(neg bool, d *decimal, prec int) string {
	buf := make([]byte, 1+max(d.dp, 1)+1+max(prec, 0))
	w := 0

	// sign
	if neg {
		buf[w] = '-'
		w++
	}

	// integer, padded with zeros as needed.
	if d.dp > 0 {
		var i int
		for i = 0; i < d.dp && i < d.nd; i++ {
			buf[w] = d.d[i]
			w++
		}
		for ; i < d.dp; i++ {
			buf[w] = '0'
			w++
		}
	} else {
		buf[w] = '0'
		w++
	}

	// fraction
	if prec > 0 {
		buf[w] = '.'
		w++
		for i := 0; i < prec; i++ {
			if d.dp+i < 0 || d.dp+i >= d.nd {
				buf[w] = '0'
			} else {
				buf[w] = d.d[d.dp+i]
			}
			w++
		}
	}

	return string(buf[0:w])
}

// %b: -ddddddddp+ddd
func fmtB(neg bool, mant uint64, exp int, flt *floatInfo) string {
	var buf [50]byte
	w := len(buf)
	exp -= int(flt.mantbits)
	esign := byte('+')
	if exp < 0 {
		esign = '-'
		exp = -exp
	}
	n := 0
	for exp > 0 || n < 1 {
		n++
		w--
		buf[w] = byte(exp%10 + '0')
		exp /= 10
	}
	w--
	buf[w] = esign
	w--
	buf[w] = 'p'
	n = 0
	for mant > 0 || n < 1 {
		n++
		w--
		buf[w] = byte(mant%10 + '0')
		mant /= 10
	}
	if neg {
		w--
		buf[w] = '-'
	}
	return string(buf[w:])
}

func max(a, b int) int {
	if a > b {
		return a
	}
	return b
}
<commit_msg>strconv/ftoa: avoid a double shift. (shifts by variables are expensive.)<commit_after>// Copyright 2009 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.

// Binary to decimal floating point conversion.
// Algorithm:
//   1) store mantissa in multiprecision decimal
//   2) shift decimal by exponent
//   3) read digits out & format

package strconv

import "math"

// TODO: move elsewhere?
type floatInfo struct {
	mantbits uint
	expbits  uint
	bias     int
}

var float32info = floatInfo{23, 8, -127}
var float64info = floatInfo{52, 11, -1023}

// Ftoa32 converts the 32-bit floating-point number f to a string,
// according to the format fmt and precision prec.
//
// The format fmt is one of
// 'b' (-ddddp±ddd, a binary exponent),
// 'e' (-d.dddde±dd, a decimal exponent),
// 'E' (-d.ddddE±dd, a decimal exponent),
// 'f' (-ddd.dddd, no exponent),
// 'g' ('e' for large exponents, 'f' otherwise), or
// 'G' ('E' for large exponents, 'f' otherwise).
//
// The precision prec controls the number of digits
// (excluding the exponent) printed by the 'e', 'E', 'f', 'g', and 'G' formats.
// For 'e', 'E', and 'f' it is the number of digits after the decimal point.
// For 'g' and 'G' it is the total number of digits.
// The special precision -1 uses the smallest number of digits
// necessary such that Atof32 will return f exactly.
//
// Ftoa32(f) is not the same as Ftoa64(float32(f)),
// because correct rounding and the number of digits
// needed to identify f depend on the precision of the representation.
func Ftoa32(f float32, fmt byte, prec int) string {
	return genericFtoa(uint64(math.Float32bits(f)), fmt, prec, &float32info)
}

// Ftoa64 is like Ftoa32 but converts a 64-bit floating-point number.
func Ftoa64(f float64, fmt byte, prec int) string {
	return genericFtoa(math.Float64bits(f), fmt, prec, &float64info)
}

// FtoaN converts the 64-bit floating-point number f to a string,
// according to the format fmt and precision prec, but it rounds the
// result assuming that it was obtained from a floating-point value
// of n bits (32 or 64).
func FtoaN(f float64, fmt byte, prec int, n int) string {
	if n == 32 {
		return Ftoa32(float32(f), fmt, prec)
	}
	return Ftoa64(f, fmt, prec)
}

func genericFtoa(bits uint64, fmt byte, prec int, flt *floatInfo) string {
	neg := bits>>(flt.expbits+flt.mantbits) != 0
	exp := int(bits>>flt.mantbits) & (1<<flt.expbits - 1)
	mant := bits & (uint64(1)<<flt.mantbits - 1)

	switch exp {
	case 1<<flt.expbits - 1:
		// Inf, NaN
		if mant != 0 {
			return "NaN"
		}
		if neg {
			return "-Inf"
		}
		return "+Inf"

	case 0:
		// denormalized
		exp++

	default:
		// add implicit top bit
		mant |= uint64(1) << flt.mantbits
	}
	exp += flt.bias

	// Pick off easy binary format.
	if fmt == 'b' {
		return fmtB(neg, mant, exp, flt)
	}

	// Create exact decimal representation.
	// The shift is exp - flt.mantbits because mant is a 1-bit integer
	// followed by a flt.mantbits fraction, and we are treating it as
	// a 1+flt.mantbits-bit integer.
	d := newDecimal(mant).Shift(exp - int(flt.mantbits))

	// Round appropriately.
	// Negative precision means "only as much as needed to be exact."
	shortest := false
	if prec < 0 {
		shortest = true
		roundShortest(d, mant, exp, flt)
		switch fmt {
		case 'e', 'E':
			prec = d.nd - 1
		case 'f':
			prec = max(d.nd-d.dp, 0)
		case 'g', 'G':
			prec = d.nd
		}
	} else {
		switch fmt {
		case 'e', 'E':
			d.Round(prec + 1)
		case 'f':
			d.Round(d.dp + prec)
		case 'g', 'G':
			if prec == 0 {
				prec = 1
			}
			d.Round(prec)
		}
	}

	switch fmt {
	case 'e', 'E':
		return fmtE(neg, d, prec, fmt)
	case 'f':
		return fmtF(neg, d, prec)
	case 'g', 'G':
		// trailing fractional zeros in 'e' form will be trimmed.
		eprec := prec
		if eprec > d.nd && d.nd >= d.dp {
			eprec = d.nd
		}
		// %e is used if the exponent from the conversion
		// is less than -4 or greater than or equal to the precision.
		// if precision was the shortest possible, use precision 6 for this decision.
		if shortest {
			eprec = 6
		}
		exp := d.dp - 1
		if exp < -4 || exp >= eprec {
			if prec > d.nd {
				prec = d.nd
			}
			return fmtE(neg, d, prec-1, fmt+'e'-'g')
		}
		if prec > d.dp {
			prec = d.nd
		}
		return fmtF(neg, d, max(prec-d.dp, 0))
	}

	return "%" + string(fmt)
}

// Round d (= mant * 2^exp) to the shortest number of digits
// that will let the original floating point value be precisely
// reconstructed.  Size is original floating point size (64 or 32).
func roundShortest(d *decimal, mant uint64, exp int, flt *floatInfo) {
	// If mantissa is zero, the number is zero; stop now.
	if mant == 0 {
		d.nd = 0
		return
	}

	// TODO(rsc): Unless exp == minexp, if the number of digits in d
	// is less than 17, it seems likely that it would be
	// the shortest possible number already.  So maybe we can
	// bail out without doing the extra multiprecision math here.

	// Compute upper and lower such that any decimal number
	// between upper and lower (possibly inclusive)
	// will round to the original floating point number.

	// d = mant << (exp - mantbits)
	// Next highest floating point number is mant+1 << exp-mantbits.
	// Our upper bound is halfway inbetween, mant*2+1 << exp-mantbits-1.
	upper := newDecimal(mant*2 + 1).Shift(exp - int(flt.mantbits) - 1)

	// d = mant << (exp - mantbits)
	// Next lowest floating point number is mant-1 << exp-mantbits,
	// unless mant-1 drops the significant bit and exp is not the minimum exp,
	// in which case the next lowest is mant*2-1 << exp-mantbits-1.
	// Either way, call it mantlo << explo-mantbits.
	// Our lower bound is halfway inbetween, mantlo*2+1 << explo-mantbits-1.
	minexp := flt.bias + 1 // minimum possible exponent
	var mantlo uint64
	var explo int
	if mant > 1<<flt.mantbits || exp == minexp {
		mantlo = mant - 1
		explo = exp
	} else {
		mantlo = mant*2 - 1
		explo = exp - 1
	}
	lower := newDecimal(mantlo*2 + 1).Shift(explo - int(flt.mantbits) - 1)

	// The upper and lower bounds are possible outputs only if
	// the original mantissa is even, so that IEEE round-to-even
	// would round to the original mantissa and not the neighbors.
	inclusive := mant%2 == 0

	// Now we can figure out the minimum number of digits required.
	// Walk along until d has distinguished itself from upper and lower.
	for i := 0; i < d.nd; i++ {
		var l, m, u byte // lower, middle, upper digits
		if i < lower.nd {
			l = lower.d[i]
		} else {
			l = '0'
		}
		m = d.d[i]
		if i < upper.nd {
			u = upper.d[i]
		} else {
			u = '0'
		}

		// Okay to round down (truncate) if lower has a different digit
		// or if lower is inclusive and is exactly the result of rounding down.
		okdown := l != m || (inclusive && l == m && i+1 == lower.nd)

		// Okay to round up if upper has a different digit and
		// either upper is inclusive or upper is bigger than the result of rounding up.
		okup := m != u && (inclusive || i+1 < upper.nd)

		// If it's okay to do either, then round to the nearest one.
		// If it's okay to do only one, do it.
		switch {
		case okdown && okup:
			d.Round(i + 1)
			return
		case okdown:
			d.RoundDown(i + 1)
			return
		case okup:
			d.RoundUp(i + 1)
			return
		}
	}
}

// %e: -d.ddddde±dd
func fmtE(neg bool, d *decimal, prec int, fmt byte) string {
	buf := make([]byte, 3+max(prec, 0)+30) // "-0." + prec digits + exp
	w := 0                                 // write index

	// sign
	if neg {
		buf[w] = '-'
		w++
	}

	// first digit
	if d.nd == 0 {
		buf[w] = '0'
	} else {
		buf[w] = d.d[0]
	}
	w++

	// .moredigits
	if prec > 0 {
		buf[w] = '.'
		w++
		for i := 0; i < prec; i++ {
			if 1+i < d.nd {
				buf[w] = d.d[1+i]
			} else {
				buf[w] = '0'
			}
			w++
		}
	}

	// e±
	buf[w] = fmt
	w++
	exp := d.dp - 1
	if d.nd == 0 { // special case: 0 has exponent 0
		exp = 0
	}
	if exp < 0 {
		buf[w] = '-'
		exp = -exp
	} else {
		buf[w] = '+'
	}
	w++

	// dddd
	// count digits
	n := 0
	for e := exp; e > 0; e /= 10 {
		n++
	}
	// leading zeros
	for i := n; i < 2; i++ {
		buf[w] = '0'
		w++
	}
	// digits
	w += n
	n = 0
	for e := exp; e > 0; e /= 10 {
		n++
		buf[w-n] = byte(e%10 + '0')
	}

	return string(buf[0:w])
}

// %f: -ddddddd.ddddd
func fmtF(neg bool, d *decimal, prec int) string {
	buf := make([]byte, 1+max(d.dp, 1)+1+max(prec, 0))
	w := 0

	// sign
	if neg {
		buf[w] = '-'
		w++
	}

	// integer, padded with zeros as needed.
	if d.dp > 0 {
		var i int
		for i = 0; i < d.dp && i < d.nd; i++ {
			buf[w] = d.d[i]
			w++
		}
		for ; i < d.dp; i++ {
			buf[w] = '0'
			w++
		}
	} else {
		buf[w] = '0'
		w++
	}

	// fraction
	if prec > 0 {
		buf[w] = '.'
		w++
		for i := 0; i < prec; i++ {
			if d.dp+i < 0 || d.dp+i >= d.nd {
				buf[w] = '0'
			} else {
				buf[w] = d.d[d.dp+i]
			}
			w++
		}
	}

	return string(buf[0:w])
}

// %b: -ddddddddp+ddd
func fmtB(neg bool, mant uint64, exp int, flt *floatInfo) string {
	var buf [50]byte
	w := len(buf)
	exp -= int(flt.mantbits)
	esign := byte('+')
	if exp < 0 {
		esign = '-'
		exp = -exp
	}
	n := 0
	for exp > 0 || n < 1 {
		n++
		w--
		buf[w] = byte(exp%10 + '0')
		exp /= 10
	}
	w--
	buf[w] = esign
	w--
	buf[w] = 'p'
	n = 0
	for mant > 0 || n < 1 {
		n++
		w--
		buf[w] = byte(mant%10 + '0')
		mant /= 10
	}
	if neg {
		w--
		buf[w] = '-'
	}
	return string(buf[w:])
}

func max(a, b int) int {
	if a > b {
		return a
	}
	return b
}
<|endoftext|>


<commit_before>package storsimple

// Copyright (c) Microsoft and contributors.  All rights reserved.
//
// 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.
//
// Code generated by Microsoft (R) AutoRest Code Generator.
// Changes may cause incorrect behavior and will be lost if the code is regenerated.

import (
	"context"
	"github.com/Azure/go-autorest/autorest"
	"github.com/Azure/go-autorest/autorest/azure"
	"net/http"
)

// AvailableProviderOperationsClient is the client for the AvailableProviderOperations methods of the Storsimple
// service.
type AvailableProviderOperationsClient struct {
	BaseClient
}

// NewAvailableProviderOperationsClient creates an instance of the AvailableProviderOperationsClient client.
func NewAvailableProviderOperationsClient(subscriptionID string) AvailableProviderOperationsClient {
	return NewAvailableProviderOperationsClientWithBaseURI(DefaultBaseURI, subscriptionID)
}

// NewAvailableProviderOperationsClientWithBaseURI creates an instance of the AvailableProviderOperationsClient client.
func NewAvailableProviderOperationsClientWithBaseURI(baseURI string, subscriptionID string) AvailableProviderOperationsClient {
	return AvailableProviderOperationsClient{NewWithBaseURI(baseURI, subscriptionID)}
}

// List list of AvailableProviderOperations
func (client AvailableProviderOperationsClient) List(ctx context.Context) (result AvailableProviderOperationsPage, err error) {
	result.fn = client.listNextResults
	req, err := client.ListPreparer(ctx)
	if err != nil {
		err = autorest.NewErrorWithError(err, "storsimple.AvailableProviderOperationsClient", "List", nil, "Failure preparing request")
		return
	}

	resp, err := client.ListSender(req)
	if err != nil {
		result.apo.Response = autorest.Response{Response: resp}
		err = autorest.NewErrorWithError(err, "storsimple.AvailableProviderOperationsClient", "List", resp, "Failure sending request")
		return
	}

	result.apo, err = client.ListResponder(resp)
	if err != nil {
		err = autorest.NewErrorWithError(err, "storsimple.AvailableProviderOperationsClient", "List", resp, "Failure responding to request")
	}

	return
}

// ListPreparer prepares the List request.
func (client AvailableProviderOperationsClient) ListPreparer(ctx context.Context) (*http.Request, error) {
	pathParameters := map[string]interface{}{
		"subscriptionId": autorest.Encode("path", client.SubscriptionID),
	}

	const APIVersion = "2016-10-01"
	queryParameters := map[string]interface{}{
		"api-version": APIVersion,
	}

	preparer := autorest.CreatePreparer(
		autorest.AsGet(),
		autorest.WithBaseURL(client.BaseURI),
		autorest.WithPathParameters("/subscriptions/{subscriptionId}/providers/Microsoft.StorSimple/operations", pathParameters),
		autorest.WithQueryParameters(queryParameters))
	return preparer.Prepare((&http.Request{}).WithContext(ctx))
}

// ListSender sends the List request. The method will close the
// http.Response Body if it receives an error.
func (client AvailableProviderOperationsClient) ListSender(req *http.Request) (*http.Response, error) {
	return autorest.SendWithSender(client, req,
		azure.DoRetryWithRegistration(client.Client))
}

// ListResponder handles the response to the List request. The method always
// closes the http.Response Body.
func (client AvailableProviderOperationsClient) ListResponder(resp *http.Response) (result AvailableProviderOperations, err error) {
	err = autorest.Respond(
		resp,
		client.ByInspecting(),
		azure.WithErrorUnlessStatusCode(http.StatusOK),
		autorest.ByUnmarshallingJSON(&result),
		autorest.ByClosing())
	result.Response = autorest.Response{Response: resp}
	return
}

// listNextResults retrieves the next set of results, if any.
func (client AvailableProviderOperationsClient) listNextResults(lastResults AvailableProviderOperations) (result AvailableProviderOperations, err error) {
	req, err := lastResults.availableProviderOperationsPreparer()
	if err != nil {
		return result, autorest.NewErrorWithError(err, "storsimple.AvailableProviderOperationsClient", "listNextResults", nil, "Failure preparing next results request")
	}
	if req == nil {
		return
	}
	resp, err := client.ListSender(req)
	if err != nil {
		result.Response = autorest.Response{Response: resp}
		return result, autorest.NewErrorWithError(err, "storsimple.AvailableProviderOperationsClient", "listNextResults", resp, "Failure sending next results request")
	}
	result, err = client.ListResponder(resp)
	if err != nil {
		err = autorest.NewErrorWithError(err, "storsimple.AvailableProviderOperationsClient", "listNextResults", resp, "Failure responding to next results request")
	}
	return
}

// ListComplete enumerates all values, automatically crossing page boundaries as required.
func (client AvailableProviderOperationsClient) ListComplete(ctx context.Context) (result AvailableProviderOperationsIterator, err error) {
	result.page, err = client.List(ctx)
	return
}
<commit_msg>[AutoPR storSimple1200Series/resource-manager] Fixed GetOperations route to not have subId (#2747)<commit_after>package storsimple

// Copyright (c) Microsoft and contributors.  All rights reserved.
//
// 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.
//
// Code generated by Microsoft (R) AutoRest Code Generator.
// Changes may cause incorrect behavior and will be lost if the code is regenerated.

import (
	"context"
	"github.com/Azure/go-autorest/autorest"
	"github.com/Azure/go-autorest/autorest/azure"
	"net/http"
)

// AvailableProviderOperationsClient is the client for the AvailableProviderOperations methods of the Storsimple
// service.
type AvailableProviderOperationsClient struct {
	BaseClient
}

// NewAvailableProviderOperationsClient creates an instance of the AvailableProviderOperationsClient client.
func NewAvailableProviderOperationsClient(subscriptionID string) AvailableProviderOperationsClient {
	return NewAvailableProviderOperationsClientWithBaseURI(DefaultBaseURI, subscriptionID)
}

// NewAvailableProviderOperationsClientWithBaseURI creates an instance of the AvailableProviderOperationsClient client.
func NewAvailableProviderOperationsClientWithBaseURI(baseURI string, subscriptionID string) AvailableProviderOperationsClient {
	return AvailableProviderOperationsClient{NewWithBaseURI(baseURI, subscriptionID)}
}

// List list of AvailableProviderOperations
func (client AvailableProviderOperationsClient) List(ctx context.Context) (result AvailableProviderOperationsPage, err error) {
	result.fn = client.listNextResults
	req, err := client.ListPreparer(ctx)
	if err != nil {
		err = autorest.NewErrorWithError(err, "storsimple.AvailableProviderOperationsClient", "List", nil, "Failure preparing request")
		return
	}

	resp, err := client.ListSender(req)
	if err != nil {
		result.apo.Response = autorest.Response{Response: resp}
		err = autorest.NewErrorWithError(err, "storsimple.AvailableProviderOperationsClient", "List", resp, "Failure sending request")
		return
	}

	result.apo, err = client.ListResponder(resp)
	if err != nil {
		err = autorest.NewErrorWithError(err, "storsimple.AvailableProviderOperationsClient", "List", resp, "Failure responding to request")
	}

	return
}

// ListPreparer prepares the List request.
func (client AvailableProviderOperationsClient) ListPreparer(ctx context.Context) (*http.Request, error) {
	const APIVersion = "2016-10-01"
	queryParameters := map[string]interface{}{
		"api-version": APIVersion,
	}

	preparer := autorest.CreatePreparer(
		autorest.AsGet(),
		autorest.WithBaseURL(client.BaseURI),
		autorest.WithPath("/providers/Microsoft.StorSimple/operations"),
		autorest.WithQueryParameters(queryParameters))
	return preparer.Prepare((&http.Request{}).WithContext(ctx))
}

// ListSender sends the List request. The method will close the
// http.Response Body if it receives an error.
func (client AvailableProviderOperationsClient) ListSender(req *http.Request) (*http.Response, error) {
	return autorest.SendWithSender(client, req,
		autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...))
}

// ListResponder handles the response to the List request. The method always
// closes the http.Response Body.
func (client AvailableProviderOperationsClient) ListResponder(resp *http.Response) (result AvailableProviderOperations, err error) {
	err = autorest.Respond(
		resp,
		client.ByInspecting(),
		azure.WithErrorUnlessStatusCode(http.StatusOK),
		autorest.ByUnmarshallingJSON(&result),
		autorest.ByClosing())
	result.Response = autorest.Response{Response: resp}
	return
}

// listNextResults retrieves the next set of results, if any.
func (client AvailableProviderOperationsClient) listNextResults(lastResults AvailableProviderOperations) (result AvailableProviderOperations, err error) {
	req, err := lastResults.availableProviderOperationsPreparer()
	if err != nil {
		return result, autorest.NewErrorWithError(err, "storsimple.AvailableProviderOperationsClient", "listNextResults", nil, "Failure preparing next results request")
	}
	if req == nil {
		return
	}
	resp, err := client.ListSender(req)
	if err != nil {
		result.Response = autorest.Response{Response: resp}
		return result, autorest.NewErrorWithError(err, "storsimple.AvailableProviderOperationsClient", "listNextResults", resp, "Failure sending next results request")
	}
	result, err = client.ListResponder(resp)
	if err != nil {
		err = autorest.NewErrorWithError(err, "storsimple.AvailableProviderOperationsClient", "listNextResults", resp, "Failure responding to next results request")
	}
	return
}

// ListComplete enumerates all values, automatically crossing page boundaries as required.
func (client AvailableProviderOperationsClient) ListComplete(ctx context.Context) (result AvailableProviderOperationsIterator, err error) {
	result.page, err = client.List(ctx)
	return
}
<|endoftext|>


<commit_before>package aws

import (
	"fmt"
	"testing"

	"github.com/aws/aws-sdk-go/service/ses"
	"github.com/hashicorp/terraform/helper/acctest"
	"github.com/hashicorp/terraform/helper/resource"
	"github.com/hashicorp/terraform/terraform"
)

func TestAccAWSSESEventDestination_basic(t *testing.T) {
	rString := acctest.RandString(8)

	bucketName := fmt.Sprintf("tf-acc-bucket-ses-event-dst-%s", rString)
	roleName := fmt.Sprintf("tf_acc_role_ses_event_dst_%s", rString)
	streamName := fmt.Sprintf("tf_acc_stream_ses_event_dst_%s", rString)
	policyName := fmt.Sprintf("tf_acc_policy_ses_event_dst_%s", rString)
	topicName := fmt.Sprintf("tf_acc_topic_ses_event_dst_%s", rString)
	sesCfgSetName := fmt.Sprintf("tf_acc_cfg_ses_event_dst_%s", rString)
	sesEventDstNameKinesis := fmt.Sprintf("tf_acc_event_dst_kinesis_%s", rString)
	sesEventDstNameCw := fmt.Sprintf("tf_acc_event_dst_cloudwatch_%s", rString)
	sesEventDstNameSns := fmt.Sprintf("tf_acc_event_dst_sns_%s", rString)

	resource.ParallelTest(t, resource.TestCase{
		PreCheck: func() {
			testAccPreCheck(t)
		},
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckSESEventDestinationDestroy,
		Steps: []resource.TestStep{
			{
				Config: testAccAWSSESEventDestinationConfig(bucketName, roleName, streamName, policyName, topicName,
					sesCfgSetName, sesEventDstNameKinesis, sesEventDstNameCw, sesEventDstNameSns),
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAwsSESEventDestinationExists("aws_ses_configuration_set.test"),
					resource.TestCheckResourceAttr(
						"aws_ses_event_destination.kinesis", "name", sesEventDstNameKinesis),
					resource.TestCheckResourceAttr(
						"aws_ses_event_destination.cloudwatch", "name", sesEventDstNameCw),
					resource.TestCheckResourceAttr(
						"aws_ses_event_destination.sns", "name", sesEventDstNameSns),
				),
			},
		},
	})
}

func testAccCheckSESEventDestinationDestroy(s *terraform.State) error {
	conn := testAccProvider.Meta().(*AWSClient).sesConn

	for _, rs := range s.RootModule().Resources {
		if rs.Type != "aws_ses_configuration_set" {
			continue
		}

		response, err := conn.ListConfigurationSets(&ses.ListConfigurationSetsInput{})
		if err != nil {
			return err
		}

		found := false
		for _, element := range response.ConfigurationSets {
			if *element.Name == rs.Primary.ID {
				found = true
			}
		}

		if found {
			return fmt.Errorf("The configuration set still exists")
		}

	}

	return nil

}

func testAccCheckAwsSESEventDestinationExists(n string) resource.TestCheckFunc {
	return func(s *terraform.State) error {
		rs, ok := s.RootModule().Resources[n]
		if !ok {
			return fmt.Errorf("SES event destination not found: %s", n)
		}

		if rs.Primary.ID == "" {
			return fmt.Errorf("SES event destination ID not set")
		}

		conn := testAccProvider.Meta().(*AWSClient).sesConn

		response, err := conn.ListConfigurationSets(&ses.ListConfigurationSetsInput{})
		if err != nil {
			return err
		}

		found := false
		for _, element := range response.ConfigurationSets {
			if *element.Name == rs.Primary.ID {
				found = true
			}
		}

		if !found {
			return fmt.Errorf("The configuration set was not created")
		}

		return nil
	}
}

func testAccAWSSESEventDestinationConfig(bucketName, roleName, streamName, policyName, topicName,
	sesCfgSetName, sesEventDstNameKinesis, sesEventDstNameCw, sesEventDstNameSns string) string {
	return fmt.Sprintf(`
resource "aws_s3_bucket" "bucket" {
  bucket = "%s"
  acl = "private"
}

resource "aws_iam_role" "firehose_role" {
   name = "%s"
   assume_role_policy = <<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": "sts:AssumeRole",
      "Principal": {
        "Service": "firehose.amazonaws.com"
      },
      "Effect": "Allow",
      "Sid": ""
    },
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "ses.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
EOF
}

resource "aws_kinesis_firehose_delivery_stream" "test_stream" {
  name = "%s"
  destination = "s3"
  s3_configuration {
    role_arn = "${aws_iam_role.firehose_role.arn}"
    bucket_arn = "${aws_s3_bucket.bucket.arn}"
  }
}

resource "aws_iam_role_policy" "firehose_delivery_policy" {
  name = "%s"
  role = "${aws_iam_role.firehose_role.id}"
  policy = "${data.aws_iam_policy_document.fh_felivery_document.json}"
}

data "aws_iam_policy_document" "fh_felivery_document" {
    statement {
        sid = "GiveSESPermissionToPutFirehose"
        actions = [
            "firehose:PutRecord",
            "firehose:PutRecordBatch",
        ]
        resources = [
            "*",
        ]
    }
}

resource "aws_sns_topic" "ses_destination" {
  name = "%s"
}

resource "aws_ses_configuration_set" "test" {
    name = "%s"
}

resource "aws_ses_event_destination" "kinesis" {
  name = "%s"
  configuration_set_name = "${aws_ses_configuration_set.test.name}"
  enabled = true
  matching_types = ["bounce", "send"]

  kinesis_destination {
    stream_arn = "${aws_kinesis_firehose_delivery_stream.test_stream.arn}"
    role_arn = "${aws_iam_role.firehose_role.arn}"
  }
}

resource "aws_ses_event_destination" "cloudwatch" {
  name = "%s",
  configuration_set_name = "${aws_ses_configuration_set.test.name}"
  enabled = true
  matching_types = ["bounce", "send"]

  cloudwatch_destination {
    default_value = "default"
	dimension_name = "dimension"
	value_source = "emailHeader"
  }

  cloudwatch_destination {
    default_value = "default"
	dimension_name = "ses:source-ip"
	value_source = "messageTag"
  }
}

resource "aws_ses_event_destination" "sns" {
  name = "%s"
  configuration_set_name = "${aws_ses_configuration_set.test.name}"
  enabled = true
  matching_types = ["bounce", "send"]

  sns_destination {
    topic_arn = "${aws_sns_topic.ses_destination.arn}"
  }
}
`, bucketName, roleName, streamName, policyName, topicName,
		sesCfgSetName, sesEventDstNameKinesis, sesEventDstNameCw, sesEventDstNameSns)
}
<commit_msg>tests/resource/aws_ses_event_destination: Fix Terraform 0.12 syntax<commit_after>package aws

import (
	"fmt"
	"testing"

	"github.com/aws/aws-sdk-go/service/ses"
	"github.com/hashicorp/terraform/helper/acctest"
	"github.com/hashicorp/terraform/helper/resource"
	"github.com/hashicorp/terraform/terraform"
)

func TestAccAWSSESEventDestination_basic(t *testing.T) {
	rString := acctest.RandString(8)

	bucketName := fmt.Sprintf("tf-acc-bucket-ses-event-dst-%s", rString)
	roleName := fmt.Sprintf("tf_acc_role_ses_event_dst_%s", rString)
	streamName := fmt.Sprintf("tf_acc_stream_ses_event_dst_%s", rString)
	policyName := fmt.Sprintf("tf_acc_policy_ses_event_dst_%s", rString)
	topicName := fmt.Sprintf("tf_acc_topic_ses_event_dst_%s", rString)
	sesCfgSetName := fmt.Sprintf("tf_acc_cfg_ses_event_dst_%s", rString)
	sesEventDstNameKinesis := fmt.Sprintf("tf_acc_event_dst_kinesis_%s", rString)
	sesEventDstNameCw := fmt.Sprintf("tf_acc_event_dst_cloudwatch_%s", rString)
	sesEventDstNameSns := fmt.Sprintf("tf_acc_event_dst_sns_%s", rString)

	resource.ParallelTest(t, resource.TestCase{
		PreCheck: func() {
			testAccPreCheck(t)
		},
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckSESEventDestinationDestroy,
		Steps: []resource.TestStep{
			{
				Config: testAccAWSSESEventDestinationConfig(bucketName, roleName, streamName, policyName, topicName,
					sesCfgSetName, sesEventDstNameKinesis, sesEventDstNameCw, sesEventDstNameSns),
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAwsSESEventDestinationExists("aws_ses_configuration_set.test"),
					resource.TestCheckResourceAttr(
						"aws_ses_event_destination.kinesis", "name", sesEventDstNameKinesis),
					resource.TestCheckResourceAttr(
						"aws_ses_event_destination.cloudwatch", "name", sesEventDstNameCw),
					resource.TestCheckResourceAttr(
						"aws_ses_event_destination.sns", "name", sesEventDstNameSns),
				),
			},
		},
	})
}

func testAccCheckSESEventDestinationDestroy(s *terraform.State) error {
	conn := testAccProvider.Meta().(*AWSClient).sesConn

	for _, rs := range s.RootModule().Resources {
		if rs.Type != "aws_ses_configuration_set" {
			continue
		}

		response, err := conn.ListConfigurationSets(&ses.ListConfigurationSetsInput{})
		if err != nil {
			return err
		}

		found := false
		for _, element := range response.ConfigurationSets {
			if *element.Name == rs.Primary.ID {
				found = true
			}
		}

		if found {
			return fmt.Errorf("The configuration set still exists")
		}

	}

	return nil

}

func testAccCheckAwsSESEventDestinationExists(n string) resource.TestCheckFunc {
	return func(s *terraform.State) error {
		rs, ok := s.RootModule().Resources[n]
		if !ok {
			return fmt.Errorf("SES event destination not found: %s", n)
		}

		if rs.Primary.ID == "" {
			return fmt.Errorf("SES event destination ID not set")
		}

		conn := testAccProvider.Meta().(*AWSClient).sesConn

		response, err := conn.ListConfigurationSets(&ses.ListConfigurationSetsInput{})
		if err != nil {
			return err
		}

		found := false
		for _, element := range response.ConfigurationSets {
			if *element.Name == rs.Primary.ID {
				found = true
			}
		}

		if !found {
			return fmt.Errorf("The configuration set was not created")
		}

		return nil
	}
}

func testAccAWSSESEventDestinationConfig(bucketName, roleName, streamName, policyName, topicName,
	sesCfgSetName, sesEventDstNameKinesis, sesEventDstNameCw, sesEventDstNameSns string) string {
	return fmt.Sprintf(`
resource "aws_s3_bucket" "bucket" {
  bucket = "%s"
  acl = "private"
}

resource "aws_iam_role" "firehose_role" {
   name = "%s"
   assume_role_policy = <<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": "sts:AssumeRole",
      "Principal": {
        "Service": "firehose.amazonaws.com"
      },
      "Effect": "Allow",
      "Sid": ""
    },
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "ses.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
EOF
}

resource "aws_kinesis_firehose_delivery_stream" "test_stream" {
  name = "%s"
  destination = "s3"
  s3_configuration {
    role_arn = "${aws_iam_role.firehose_role.arn}"
    bucket_arn = "${aws_s3_bucket.bucket.arn}"
  }
}

resource "aws_iam_role_policy" "firehose_delivery_policy" {
  name = "%s"
  role = "${aws_iam_role.firehose_role.id}"
  policy = "${data.aws_iam_policy_document.fh_felivery_document.json}"
}

data "aws_iam_policy_document" "fh_felivery_document" {
    statement {
        sid = "GiveSESPermissionToPutFirehose"
        actions = [
            "firehose:PutRecord",
            "firehose:PutRecordBatch",
        ]
        resources = [
            "*",
        ]
    }
}

resource "aws_sns_topic" "ses_destination" {
  name = "%s"
}

resource "aws_ses_configuration_set" "test" {
    name = "%s"
}

resource "aws_ses_event_destination" "kinesis" {
  name = "%s"
  configuration_set_name = "${aws_ses_configuration_set.test.name}"
  enabled = true
  matching_types = ["bounce", "send"]

  kinesis_destination {
    stream_arn = "${aws_kinesis_firehose_delivery_stream.test_stream.arn}"
    role_arn = "${aws_iam_role.firehose_role.arn}"
  }
}

resource "aws_ses_event_destination" "cloudwatch" {
  name = "%s"
  configuration_set_name = "${aws_ses_configuration_set.test.name}"
  enabled = true
  matching_types = ["bounce", "send"]

  cloudwatch_destination {
    default_value = "default"
	dimension_name = "dimension"
	value_source = "emailHeader"
  }

  cloudwatch_destination {
    default_value = "default"
	dimension_name = "ses:source-ip"
	value_source = "messageTag"
  }
}

resource "aws_ses_event_destination" "sns" {
  name = "%s"
  configuration_set_name = "${aws_ses_configuration_set.test.name}"
  enabled = true
  matching_types = ["bounce", "send"]

  sns_destination {
    topic_arn = "${aws_sns_topic.ses_destination.arn}"
  }
}
`, bucketName, roleName, streamName, policyName, topicName,
		sesCfgSetName, sesEventDstNameKinesis, sesEventDstNameCw, sesEventDstNameSns)
}
<|endoftext|>


<commit_before>/////
// build your own blockchain from scratch in go(lang)
//
//  references:
//  - https://jeiwan.cc/posts/building-blockchain-in-go-part-1/
//  - https://jeiwan.cc/posts/building-blockchain-in-go-part-2/
//  - https://medium.com/@mycoralhealth/code-your-own-blockchain-in-less-than-200-lines-of-go-e296282bcffc
//  - https://medium.com/@mycoralhealth/code-your-own-blockchain-mining-algorithm-in-go-82c6a71aba1f
//  - and (many) others
//
//  to run use:
//    $ go run blockchain_with_proof_of_work.go

package main

import (
  "fmt"
  "crypto/sha256"
  "encoding/hex"
  "time"
  "strconv"
  "strings"
)

type Block struct {
  Time          int64       // seconds since (unix) epoch (1970-01-01)
  Data          string
  Prev          string      // use []byte/int256/uint256 ??
  Hash          string      // use []byteint256/uint256 ??
  Nonce         int64       // number used once - lucky (mining) lottery number
}

// bin(ary) bytes and integer number to (conversion) string helpers
func binToStr( bytes []byte ) string {
  return hex.EncodeToString( bytes )
}

func intToStr( num int64 ) string {
  return strconv.FormatInt( num, 10 )
}

func calcHash( data string ) string {
  hashed := sha256.Sum256( []byte(data) )
  return binToStr( hashed[:] )   // note: [:] converts [32]byte to []byte
}

func computeHashWithProofOfWork( data string, difficulty string ) (int64,string) {
  //var nonce int64 = 0
  nonce := int64( 0 )
  for {
    hash := calcHash( intToStr(nonce) + data )
    if strings.HasPrefix( hash, difficulty ) {
        return nonce,hash    // bingo! proof of work if hash starts with leading zeros (00)
    } else {
        nonce += 1           // keep trying (and trying and trying)
    }
  }
}

func NewBlock( data string, prev string ) Block {
  t           := time.Now().Unix()
  difficulty  := "0000"
  nonce, hash := computeHashWithProofOfWork( intToStr(t) + prev + data, difficulty )

  return Block { t, data, prev, hash, nonce }
}

func main() {

  b0 := NewBlock( "Hello, Cryptos!", "0000000000000000000000000000000000000000000000000000000000000000" )
  b1 := NewBlock( "Hello, Cryptos! - Hello, Cryptos!", b0.Hash )

  fmt.Println( b0 )
  // {1522691756 Hello, Cryptos!
  //    0000000000000000000000000000000000000000000000000000000000000000
  //    00009f597a8e28fc42a450c0ed2eff1b6507f76f6a7d1e112686700ce37e3676
  //    42278}
  fmt.Println( len( b0.Hash ))
  // => 64
  fmt.Println( len( b0.Prev ))
  // => 64

  fmt.Println( b1 )
  // {1522691756 Hello, Cryptos! - Hello, Cryptos!
  //     00009f597a8e28fc42a450c0ed2eff1b6507f76f6a7d1e112686700ce37e3676
  //     00009ef5ea432f840c3fb23dbedb5cce4c72e2951a140c1289dda1fedbcd6e99
  //     105106}

  fmt.Println( len( b1.Hash ))
  // => 64
  fmt.Println( len( b1.Prev ))
  // => 64

  blockchain := []Block {b0, b1}
  fmt.Println( blockchain )
  // => [{1522691756 Hello, Cryptos!
  //        0000000000000000000000000000000000000000000000000000000000000000
  //        00009f597a8e28fc42a450c0ed2eff1b6507f76f6a7d1e112686700ce37e3676
  //        42278}
  //     {1522691756 Hello, Cryptos! - Hello, Cryptos!
  //        00009f597a8e28fc42a450c0ed2eff1b6507f76f6a7d1e112686700ce37e3676
  //        00009ef5ea432f840c3fb23dbedb5cce4c72e2951a140c1289dda1fedbcd6e99
  //        105106}]
}
<commit_msg>Update blockchain_with_proof_of_work.go<commit_after>/////
// build your own blockchain from scratch in go(lang)
//
//  references:
//  - https://jeiwan.cc/posts/building-blockchain-in-go-part-1/
//  - https://jeiwan.cc/posts/building-blockchain-in-go-part-2/
//  - https://medium.com/@mycoralhealth/code-your-own-blockchain-in-less-than-200-lines-of-go-e296282bcffc
//  - https://medium.com/@mycoralhealth/code-your-own-blockchain-mining-algorithm-in-go-82c6a71aba1f
//  - and (many) others
//
//  to run use:
//    $ go run blockchain_with_proof_of_work.go

package main

import (
  "fmt"
  "crypto/sha256"
  "encoding/hex"
  "time"
  "strconv"
  "strings"
)

type Block struct {
  Time          int64       // seconds since (unix) epoch (1970-01-01)
  Data          string
  Prev          string      // use []byte/int256/uint256 ??
  Hash          string      // use []byteint256/uint256 ??
  Nonce         int64       // number used once - lucky (mining) lottery number
}

// bin(ary) bytes and integer number to (conversion) string helpers
func binToStr( bytes []byte ) string {
  return hex.EncodeToString( bytes )
}

func intToStr( num int64 ) string {
  return strconv.FormatInt( num, 10 )
}

func calcHash( data string ) string {
  hashed := sha256.Sum256( []byte(data) )
  return binToStr( hashed[:] )   // note: [:] converts [32]byte to []byte
}

func computeHashWithProofOfWork( data string, difficulty string ) (int64,string) {
  nonce := int64( 0 )
  for {
    hash := calcHash( intToStr(nonce) + data )
    if strings.HasPrefix( hash, difficulty ) {
        return nonce,hash    // bingo! proof of work if hash starts with leading zeros (00)
    } else {
        nonce += 1           // keep trying (and trying and trying)
    }
  }
}

func NewBlock( data string, prev string ) Block {
  t           := time.Now().Unix()
  difficulty  := "0000"
  nonce, hash := computeHashWithProofOfWork( intToStr(t) + prev + data, difficulty )

  return Block { t, data, prev, hash, nonce }
}

func main() {
  b0 := NewBlock( "Hello, Cryptos!", "0000000000000000000000000000000000000000000000000000000000000000" )
  b1 := NewBlock( "Hello, Cryptos! - Hello, Cryptos!", b0.Hash )

  fmt.Println( b0 )
  // {1522691756 Hello, Cryptos!
  //    0000000000000000000000000000000000000000000000000000000000000000
  //    00009f597a8e28fc42a450c0ed2eff1b6507f76f6a7d1e112686700ce37e3676
  //    42278}
  fmt.Println( len( b0.Hash ))
  // => 64
  fmt.Println( len( b0.Prev ))
  // => 64

  fmt.Println( b1 )
  // {1522691756 Hello, Cryptos! - Hello, Cryptos!
  //     00009f597a8e28fc42a450c0ed2eff1b6507f76f6a7d1e112686700ce37e3676
  //     00009ef5ea432f840c3fb23dbedb5cce4c72e2951a140c1289dda1fedbcd6e99
  //     105106}

  fmt.Println( len( b1.Hash ))
  // => 64
  fmt.Println( len( b1.Prev ))
  // => 64

  blockchain := []Block {b0, b1}
  fmt.Println( blockchain )
  // => [{1522691756 Hello, Cryptos!
  //        0000000000000000000000000000000000000000000000000000000000000000
  //        00009f597a8e28fc42a450c0ed2eff1b6507f76f6a7d1e112686700ce37e3676
  //        42278}
  //     {1522691756 Hello, Cryptos! - Hello, Cryptos!
  //        00009f597a8e28fc42a450c0ed2eff1b6507f76f6a7d1e112686700ce37e3676
  //        00009ef5ea432f840c3fb23dbedb5cce4c72e2951a140c1289dda1fedbcd6e99
  //        105106}]
}
<|endoftext|>


<commit_before>// Copyright 2009 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.

// Page heap.
//
// See malloc.go for the general overview.
//
// Large spans are the subject of this file. Spans consisting of less than
// _MaxMHeapLists are held in lists of like sized spans. Larger spans
// are held in a treap. See https://en.wikipedia.org/wiki/Treap or
// https://faculty.washington.edu/aragon/pubs/rst89.pdf for an overview.
// sema.go also holds an implementation of a treap.
//
// Each treapNode holds a single span. The treap is sorted by page size
// and for spans of the same size a secondary sort based on start address
// is done.
// Spans are returned based on a best fit algorithm and for spans of the same
// size the one at the lowest address is selected.
//
// The primary routines are
// insert: adds a span to the treap
// remove: removes the span from that treap that best fits the required size
// removeSpan: which removes a specific span from the treap
//
// _mheap.lock must be held when manipulating this data structure.

package runtime

import (
	"unsafe"
)

//go:notinheap
type mTreap struct {
	treap *treapNode
}

//go:notinheap
type treapNode struct {
	right     *treapNode // all treapNodes > this treap node
	left      *treapNode // all treapNodes < this treap node
	parent    *treapNode // direct parent of this node, nil if root
	npagesKey uintptr    // number of pages in spanKey, used as primary sort key
	spanKey   *mspan     // span of size npagesKey, used as secondary sort key
	priority  uint32     // random number used by treap algorithm to keep tree probabilistically balanced
}

func (t *treapNode) pred() *treapNode {
	if t.left != nil {
		// If it has a left child, its predecessor will be
		// its right most left (grand)child.
		t = t.left
		for t.right != nil {
			t = t.right
		}
		return t
	}
	// If it has no left child, its predecessor will be
	// the first grandparent who's right child is its
	// ancestor.
	//
	// We compute this by walking up the treap until the
	// current node's parent is its parent's right child.
	//
	// If we find at any point walking up the treap
	// that the current node doesn't have a parent,
	// we've hit the root. This means that t is already
	// the left-most node in the treap and therefore
	// has no predecessor.
	for t.parent != nil && t.parent.right != t {
		if t.parent.left != t {
			println("runtime: predecessor t=", t, "t.spanKey=", t.spanKey)
			throw("node is not its parent's child")
		}
		t = t.parent
	}
	return t.parent
}

// isSpanInTreap is handy for debugging. One should hold the heap lock, usually
// mheap_.lock().
func (t *treapNode) isSpanInTreap(s *mspan) bool {
	if t == nil {
		return false
	}
	return t.spanKey == s || t.left.isSpanInTreap(s) || t.right.isSpanInTreap(s)
}

// walkTreap is handy for debugging.
// Starting at some treapnode t, for example the root, do a depth first preorder walk of
// the tree executing fn at each treap node. One should hold the heap lock, usually
// mheap_.lock().
func (t *treapNode) walkTreap(fn func(tn *treapNode)) {
	if t == nil {
		return
	}
	fn(t)
	t.left.walkTreap(fn)
	t.right.walkTreap(fn)
}

// checkTreapNode when used in conjunction with walkTreap can usually detect a
// poorly formed treap.
func checkTreapNode(t *treapNode) {
	// lessThan is used to order the treap.
	// npagesKey and npages are the primary keys.
	// spanKey and span are the secondary keys.
	// span == nil (0) will always be lessThan all
	// spans of the same size.
	lessThan := func(npages uintptr, s *mspan) bool {
		if t.npagesKey != npages {
			return t.npagesKey < npages
		}
		// t.npagesKey == npages
		return uintptr(unsafe.Pointer(t.spanKey)) < uintptr(unsafe.Pointer(s))
	}

	if t == nil {
		return
	}
	if t.spanKey.npages != t.npagesKey || t.spanKey.next != nil {
		println("runtime: checkTreapNode treapNode t=", t, "     t.npagesKey=", t.npagesKey,
			"t.spanKey.npages=", t.spanKey.npages)
		throw("why does span.npages and treap.ngagesKey do not match?")
	}
	if t.left != nil && lessThan(t.left.npagesKey, t.left.spanKey) {
		throw("t.lessThan(t.left.npagesKey, t.left.spanKey) is not false")
	}
	if t.right != nil && !lessThan(t.right.npagesKey, t.right.spanKey) {
		throw("!t.lessThan(t.left.npagesKey, t.left.spanKey) is not false")
	}
}

// insert adds span to the large span treap.
func (root *mTreap) insert(span *mspan) {
	npages := span.npages
	var last *treapNode
	pt := &root.treap
	for t := *pt; t != nil; t = *pt {
		last = t
		if t.npagesKey < npages {
			pt = &t.right
		} else if t.npagesKey > npages {
			pt = &t.left
		} else if uintptr(unsafe.Pointer(t.spanKey)) < uintptr(unsafe.Pointer(span)) {
			// t.npagesKey == npages, so sort on span addresses.
			pt = &t.right
		} else if uintptr(unsafe.Pointer(t.spanKey)) > uintptr(unsafe.Pointer(span)) {
			pt = &t.left
		} else {
			throw("inserting span already in treap")
		}
	}

	// Add t as new leaf in tree of span size and unique addrs.
	// The balanced tree is a treap using priority as the random heap priority.
	// That is, it is a binary tree ordered according to the npagesKey,
	// but then among the space of possible binary trees respecting those
	// npagesKeys, it is kept balanced on average by maintaining a heap ordering
	// on the priority: s.priority <= both s.right.priority and s.right.priority.
	// https://en.wikipedia.org/wiki/Treap
	// https://faculty.washington.edu/aragon/pubs/rst89.pdf

	t := (*treapNode)(mheap_.treapalloc.alloc())
	t.npagesKey = span.npages
	t.priority = fastrand()
	t.spanKey = span
	t.parent = last
	*pt = t // t now at a leaf.
	// Rotate up into tree according to priority.
	for t.parent != nil && t.parent.priority > t.priority {
		if t != nil && t.spanKey.npages != t.npagesKey {
			println("runtime: insert t=", t, "t.npagesKey=", t.npagesKey)
			println("runtime:      t.spanKey=", t.spanKey, "t.spanKey.npages=", t.spanKey.npages)
			throw("span and treap sizes do not match?")
		}
		if t.parent.left == t {
			root.rotateRight(t.parent)
		} else {
			if t.parent.right != t {
				throw("treap insert finds a broken treap")
			}
			root.rotateLeft(t.parent)
		}
	}
}

func (root *mTreap) removeNode(t *treapNode) {
	if t.spanKey.npages != t.npagesKey {
		throw("span and treap node npages do not match")
	}

	// Rotate t down to be leaf of tree for removal, respecting priorities.
	for t.right != nil || t.left != nil {
		if t.right == nil || t.left != nil && t.left.priority < t.right.priority {
			root.rotateRight(t)
		} else {
			root.rotateLeft(t)
		}
	}
	// Remove t, now a leaf.
	if t.parent != nil {
		if t.parent.left == t {
			t.parent.left = nil
		} else {
			t.parent.right = nil
		}
	} else {
		root.treap = nil
	}
	// Return the found treapNode's span after freeing the treapNode.
	mheap_.treapalloc.free(unsafe.Pointer(t))
}

// remove searches for, finds, removes from the treap, and returns the smallest
// span that can hold npages. If no span has at least npages return nil.
// This is slightly more complicated than a simple binary tree search
// since if an exact match is not found the next larger node is
// returned.
// If the last node inspected > npagesKey not holding
// a left node (a smaller npages) is the "best fit" node.
func (root *mTreap) remove(npages uintptr) *mspan {
	t := root.treap
	for t != nil {
		if t.spanKey == nil {
			throw("treap node with nil spanKey found")
		}
		if t.npagesKey < npages {
			t = t.right
		} else if t.left != nil && t.left.npagesKey >= npages {
			t = t.left
		} else {
			result := t.spanKey
			root.removeNode(t)
			return result
		}
	}
	return nil
}

// removeSpan searches for, finds, deletes span along with
// the associated treap node. If the span is not in the treap
// then t will eventually be set to nil and the t.spanKey
// will throw.
func (root *mTreap) removeSpan(span *mspan) {
	npages := span.npages
	t := root.treap
	for t.spanKey != span {
		if t.npagesKey < npages {
			t = t.right
		} else if t.npagesKey > npages {
			t = t.left
		} else if uintptr(unsafe.Pointer(t.spanKey)) < uintptr(unsafe.Pointer(span)) {
			t = t.right
		} else if uintptr(unsafe.Pointer(t.spanKey)) > uintptr(unsafe.Pointer(span)) {
			t = t.left
		}
	}
	root.removeNode(t)
}

// scavengetreap visits each node in the treap and scavenges the
// treapNode's span.
func scavengetreap(treap *treapNode, now, limit uint64) uintptr {
	if treap == nil {
		return 0
	}
	return scavengeTreapNode(treap, now, limit) +
		scavengetreap(treap.left, now, limit) +
		scavengetreap(treap.right, now, limit)
}

// rotateLeft rotates the tree rooted at node x.
// turning (x a (y b c)) into (y (x a b) c).
func (root *mTreap) rotateLeft(x *treapNode) {
	// p -> (x a (y b c))
	p := x.parent
	a, y := x.left, x.right
	b, c := y.left, y.right

	y.left = x
	x.parent = y
	y.right = c
	if c != nil {
		c.parent = y
	}
	x.left = a
	if a != nil {
		a.parent = x
	}
	x.right = b
	if b != nil {
		b.parent = x
	}

	y.parent = p
	if p == nil {
		root.treap = y
	} else if p.left == x {
		p.left = y
	} else {
		if p.right != x {
			throw("large span treap rotateLeft")
		}
		p.right = y
	}
}

// rotateRight rotates the tree rooted at node y.
// turning (y (x a b) c) into (x a (y b c)).
func (root *mTreap) rotateRight(y *treapNode) {
	// p -> (y (x a b) c)
	p := y.parent
	x, c := y.left, y.right
	a, b := x.left, x.right

	x.left = a
	if a != nil {
		a.parent = x
	}
	x.right = y
	y.parent = x
	y.left = b
	if b != nil {
		b.parent = y
	}
	y.right = c
	if c != nil {
		c.parent = y
	}

	x.parent = p
	if p == nil {
		root.treap = x
	} else if p.left == y {
		p.left = x
	} else {
		if p.right != y {
			throw("large span treap rotateRight")
		}
		p.right = x
	}
}
<commit_msg>runtime: add successor method to treap<commit_after>// Copyright 2009 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.

// Page heap.
//
// See malloc.go for the general overview.
//
// Large spans are the subject of this file. Spans consisting of less than
// _MaxMHeapLists are held in lists of like sized spans. Larger spans
// are held in a treap. See https://en.wikipedia.org/wiki/Treap or
// https://faculty.washington.edu/aragon/pubs/rst89.pdf for an overview.
// sema.go also holds an implementation of a treap.
//
// Each treapNode holds a single span. The treap is sorted by page size
// and for spans of the same size a secondary sort based on start address
// is done.
// Spans are returned based on a best fit algorithm and for spans of the same
// size the one at the lowest address is selected.
//
// The primary routines are
// insert: adds a span to the treap
// remove: removes the span from that treap that best fits the required size
// removeSpan: which removes a specific span from the treap
//
// _mheap.lock must be held when manipulating this data structure.

package runtime

import (
	"unsafe"
)

//go:notinheap
type mTreap struct {
	treap *treapNode
}

//go:notinheap
type treapNode struct {
	right     *treapNode // all treapNodes > this treap node
	left      *treapNode // all treapNodes < this treap node
	parent    *treapNode // direct parent of this node, nil if root
	npagesKey uintptr    // number of pages in spanKey, used as primary sort key
	spanKey   *mspan     // span of size npagesKey, used as secondary sort key
	priority  uint32     // random number used by treap algorithm to keep tree probabilistically balanced
}

func (t *treapNode) pred() *treapNode {
	if t.left != nil {
		// If it has a left child, its predecessor will be
		// its right most left (grand)child.
		t = t.left
		for t.right != nil {
			t = t.right
		}
		return t
	}
	// If it has no left child, its predecessor will be
	// the first grandparent who's right child is its
	// ancestor.
	//
	// We compute this by walking up the treap until the
	// current node's parent is its parent's right child.
	//
	// If we find at any point walking up the treap
	// that the current node doesn't have a parent,
	// we've hit the root. This means that t is already
	// the left-most node in the treap and therefore
	// has no predecessor.
	for t.parent != nil && t.parent.right != t {
		if t.parent.left != t {
			println("runtime: predecessor t=", t, "t.spanKey=", t.spanKey)
			throw("node is not its parent's child")
		}
		t = t.parent
	}
	return t.parent
}

func (t *treapNode) succ() *treapNode {
	if t.right != nil {
		// If it has a right child, its successor will be
		// its left-most right (grand)child.
		t = t.right
		for t.left != nil {
			t = t.left
		}
		return t
	}
	// See pred.
	for t.parent != nil && t.parent.left != t {
		if t.parent.right != t {
			println("runtime: predecessor t=", t, "t.spanKey=", t.spanKey)
			throw("node is not its parent's child")
		}
		t = t.parent
	}
	return t.parent
}

// isSpanInTreap is handy for debugging. One should hold the heap lock, usually
// mheap_.lock().
func (t *treapNode) isSpanInTreap(s *mspan) bool {
	if t == nil {
		return false
	}
	return t.spanKey == s || t.left.isSpanInTreap(s) || t.right.isSpanInTreap(s)
}

// walkTreap is handy for debugging.
// Starting at some treapnode t, for example the root, do a depth first preorder walk of
// the tree executing fn at each treap node. One should hold the heap lock, usually
// mheap_.lock().
func (t *treapNode) walkTreap(fn func(tn *treapNode)) {
	if t == nil {
		return
	}
	fn(t)
	t.left.walkTreap(fn)
	t.right.walkTreap(fn)
}

// checkTreapNode when used in conjunction with walkTreap can usually detect a
// poorly formed treap.
func checkTreapNode(t *treapNode) {
	// lessThan is used to order the treap.
	// npagesKey and npages are the primary keys.
	// spanKey and span are the secondary keys.
	// span == nil (0) will always be lessThan all
	// spans of the same size.
	lessThan := func(npages uintptr, s *mspan) bool {
		if t.npagesKey != npages {
			return t.npagesKey < npages
		}
		// t.npagesKey == npages
		return uintptr(unsafe.Pointer(t.spanKey)) < uintptr(unsafe.Pointer(s))
	}

	if t == nil {
		return
	}
	if t.spanKey.npages != t.npagesKey || t.spanKey.next != nil {
		println("runtime: checkTreapNode treapNode t=", t, "     t.npagesKey=", t.npagesKey,
			"t.spanKey.npages=", t.spanKey.npages)
		throw("why does span.npages and treap.ngagesKey do not match?")
	}
	if t.left != nil && lessThan(t.left.npagesKey, t.left.spanKey) {
		throw("t.lessThan(t.left.npagesKey, t.left.spanKey) is not false")
	}
	if t.right != nil && !lessThan(t.right.npagesKey, t.right.spanKey) {
		throw("!t.lessThan(t.left.npagesKey, t.left.spanKey) is not false")
	}
}

// insert adds span to the large span treap.
func (root *mTreap) insert(span *mspan) {
	npages := span.npages
	var last *treapNode
	pt := &root.treap
	for t := *pt; t != nil; t = *pt {
		last = t
		if t.npagesKey < npages {
			pt = &t.right
		} else if t.npagesKey > npages {
			pt = &t.left
		} else if uintptr(unsafe.Pointer(t.spanKey)) < uintptr(unsafe.Pointer(span)) {
			// t.npagesKey == npages, so sort on span addresses.
			pt = &t.right
		} else if uintptr(unsafe.Pointer(t.spanKey)) > uintptr(unsafe.Pointer(span)) {
			pt = &t.left
		} else {
			throw("inserting span already in treap")
		}
	}

	// Add t as new leaf in tree of span size and unique addrs.
	// The balanced tree is a treap using priority as the random heap priority.
	// That is, it is a binary tree ordered according to the npagesKey,
	// but then among the space of possible binary trees respecting those
	// npagesKeys, it is kept balanced on average by maintaining a heap ordering
	// on the priority: s.priority <= both s.right.priority and s.right.priority.
	// https://en.wikipedia.org/wiki/Treap
	// https://faculty.washington.edu/aragon/pubs/rst89.pdf

	t := (*treapNode)(mheap_.treapalloc.alloc())
	t.npagesKey = span.npages
	t.priority = fastrand()
	t.spanKey = span
	t.parent = last
	*pt = t // t now at a leaf.
	// Rotate up into tree according to priority.
	for t.parent != nil && t.parent.priority > t.priority {
		if t != nil && t.spanKey.npages != t.npagesKey {
			println("runtime: insert t=", t, "t.npagesKey=", t.npagesKey)
			println("runtime:      t.spanKey=", t.spanKey, "t.spanKey.npages=", t.spanKey.npages)
			throw("span and treap sizes do not match?")
		}
		if t.parent.left == t {
			root.rotateRight(t.parent)
		} else {
			if t.parent.right != t {
				throw("treap insert finds a broken treap")
			}
			root.rotateLeft(t.parent)
		}
	}
}

func (root *mTreap) removeNode(t *treapNode) {
	if t.spanKey.npages != t.npagesKey {
		throw("span and treap node npages do not match")
	}

	// Rotate t down to be leaf of tree for removal, respecting priorities.
	for t.right != nil || t.left != nil {
		if t.right == nil || t.left != nil && t.left.priority < t.right.priority {
			root.rotateRight(t)
		} else {
			root.rotateLeft(t)
		}
	}
	// Remove t, now a leaf.
	if t.parent != nil {
		if t.parent.left == t {
			t.parent.left = nil
		} else {
			t.parent.right = nil
		}
	} else {
		root.treap = nil
	}
	// Return the found treapNode's span after freeing the treapNode.
	mheap_.treapalloc.free(unsafe.Pointer(t))
}

// remove searches for, finds, removes from the treap, and returns the smallest
// span that can hold npages. If no span has at least npages return nil.
// This is slightly more complicated than a simple binary tree search
// since if an exact match is not found the next larger node is
// returned.
// If the last node inspected > npagesKey not holding
// a left node (a smaller npages) is the "best fit" node.
func (root *mTreap) remove(npages uintptr) *mspan {
	t := root.treap
	for t != nil {
		if t.spanKey == nil {
			throw("treap node with nil spanKey found")
		}
		if t.npagesKey < npages {
			t = t.right
		} else if t.left != nil && t.left.npagesKey >= npages {
			t = t.left
		} else {
			result := t.spanKey
			root.removeNode(t)
			return result
		}
	}
	return nil
}

// removeSpan searches for, finds, deletes span along with
// the associated treap node. If the span is not in the treap
// then t will eventually be set to nil and the t.spanKey
// will throw.
func (root *mTreap) removeSpan(span *mspan) {
	npages := span.npages
	t := root.treap
	for t.spanKey != span {
		if t.npagesKey < npages {
			t = t.right
		} else if t.npagesKey > npages {
			t = t.left
		} else if uintptr(unsafe.Pointer(t.spanKey)) < uintptr(unsafe.Pointer(span)) {
			t = t.right
		} else if uintptr(unsafe.Pointer(t.spanKey)) > uintptr(unsafe.Pointer(span)) {
			t = t.left
		}
	}
	root.removeNode(t)
}

// scavengetreap visits each node in the treap and scavenges the
// treapNode's span.
func scavengetreap(treap *treapNode, now, limit uint64) uintptr {
	if treap == nil {
		return 0
	}
	return scavengeTreapNode(treap, now, limit) +
		scavengetreap(treap.left, now, limit) +
		scavengetreap(treap.right, now, limit)
}

// rotateLeft rotates the tree rooted at node x.
// turning (x a (y b c)) into (y (x a b) c).
func (root *mTreap) rotateLeft(x *treapNode) {
	// p -> (x a (y b c))
	p := x.parent
	a, y := x.left, x.right
	b, c := y.left, y.right

	y.left = x
	x.parent = y
	y.right = c
	if c != nil {
		c.parent = y
	}
	x.left = a
	if a != nil {
		a.parent = x
	}
	x.right = b
	if b != nil {
		b.parent = x
	}

	y.parent = p
	if p == nil {
		root.treap = y
	} else if p.left == x {
		p.left = y
	} else {
		if p.right != x {
			throw("large span treap rotateLeft")
		}
		p.right = y
	}
}

// rotateRight rotates the tree rooted at node y.
// turning (y (x a b) c) into (x a (y b c)).
func (root *mTreap) rotateRight(y *treapNode) {
	// p -> (y (x a b) c)
	p := y.parent
	x, c := y.left, y.right
	a, b := x.left, x.right

	x.left = a
	if a != nil {
		a.parent = x
	}
	x.right = y
	y.parent = x
	y.left = b
	if b != nil {
		b.parent = y
	}
	y.right = c
	if c != nil {
		c.parent = y
	}

	x.parent = p
	if p == nil {
		root.treap = x
	} else if p.left == y {
		p.left = x
	} else {
		if p.right != y {
			throw("large span treap rotateRight")
		}
		p.right = x
	}
}
<|endoftext|>


<commit_before>package helpers

import (
	"encoding/json"
	"fmt"
	"os"
	"path/filepath"
	"reflect"
	"time"

	"github.com/cloudfoundry-incubator/cf-test-helpers/runner"
)

type Config struct {
	ApiEndpoint string `json:"api"`
	AppsDomain  string `json:"apps_domain"`
	UseHttp     bool   `json:"use_http"`

	AdminUser     string `json:"admin_user"`
	AdminPassword string `json:"admin_password"`

	UseExistingUser      bool   `json:"use_existing_user"`
	ShouldKeepUser       bool   `json:"keep_user_at_suite_end"`
	ExistingUser         string `json:"existing_user"`
	ExistingUserPassword string `json:"existing_user_password"`

	ConfigurableTestPassword string `json:"test_password"`

	PersistentAppHost      string `json:"persistent_app_host"`
	PersistentAppSpace     string `json:"persistent_app_space"`
	PersistentAppOrg       string `json:"persistent_app_org"`
	PersistentAppQuotaName string `json:"persistent_app_quota_name"`

	SkipSSLValidation                 bool   `json:"skip_ssl_validation"`
	Backend                           string `json:"backend"`
	IncludeDiegoDocker                bool   `json:"include_diego_docker"`
	IncludeTasks                      bool   `json:"include_tasks"`
	IncludePrivilegedContainerSupport bool   `json:"include_privileged_container_support"`

	ArtifactsDirectory string `json:"artifacts_directory"`

	DefaultTimeout     time.Duration `json:"default_timeout"`
	SleepTimeout       time.Duration `json:"sleep_timeout"`
	DetectTimeout      time.Duration `json:"detect_timeout"`
	CfPushTimeout      time.Duration `json:"cf_push_timeout"`
	LongCurlTimeout    time.Duration `json:"long_curl_timeout"`
	BrokerStartTimeout time.Duration `json:"broker_start_timeout"`

	TimeoutScale float64 `json:"timeout_scale"`

	SecureAddress string `json:"secure_address"`

	DockerExecutable      string   `json:"docker_executable"`
	DockerParameters      []string `json:"docker_parameters"`
	DockerRegistryAddress string   `json:"docker_registry_address"`
	DockerPrivateImage    string   `json:"docker_private_image"`
	DockerUser            string   `json:"docker_user"`
	DockerPassword        string   `json:"docker_password"`
	DockerEmail           string   `json:"docker_email"`

	StaticFileBuildpackName string `json:"staticfile_buildpack_name"`
	JavaBuildpackName       string `json:"java_buildpack_name"`
	RubyBuildpackName       string `json:"ruby_buildpack_name"`
	NodejsBuildpackName     string `json:"nodejs_buildpack_name"`
	GoBuildpackName         string `json:"go_buildpack_name"`
	PythonBuildpackName     string `json:"python_buildpack_name"`
	PhpBuildpackName        string `json:"php_buildpack_name"`
	BinaryBuildpackName     string `json:"binary_buildpack_name"`

	NamePrefix string `json:"name_prefix"`
}

var defaults = Config{
	PersistentAppHost:      "CATS-persistent-app",
	PersistentAppSpace:     "CATS-persistent-space",
	PersistentAppOrg:       "CATS-persistent-org",
	PersistentAppQuotaName: "CATS-persistent-quota",

	StaticFileBuildpackName: "staticfile_buildpack",
	JavaBuildpackName:       "java_buildpack",
	RubyBuildpackName:       "ruby_buildpack",
	NodejsBuildpackName:     "nodejs_buildpack",
	GoBuildpackName:         "go_buildpack",
	PythonBuildpackName:     "python_buildpack",
	PhpBuildpackName:        "php_buildpack",
	BinaryBuildpackName:     "binary_buildpack",

	ArtifactsDirectory: filepath.Join("..", "results"),

	NamePrefix: "CATS",
}

func (c Config) ScaledTimeout(timeout time.Duration) time.Duration {
	return time.Duration(float64(timeout) * c.TimeoutScale)
}

var loadedConfig *Config

func Load(path string, config interface{}) error {
	c, ok := config.(*Config)
	if !ok {
		val := reflect.ValueOf(config).Elem().FieldByName("Config").Addr()
		c = val.Interface().(*Config)
	}

	*c = defaults
	err := loadConfigFromPath(path, config)
	if err != nil {
		return err
	}

	if c.ApiEndpoint == "" {
		return fmt.Errorf("missing configuration 'api'")
	}

	if c.AdminUser == "" {
		return fmt.Errorf("missing configuration 'admin_user'")
	}

	if c.AdminPassword == "" {
		return fmt.Errorf("missing configuration 'admin_password'")
	}

	if c.TimeoutScale <= 0 {
		c.TimeoutScale = 1.0
	}

	runner.SkipSSLValidation = c.SkipSSLValidation
	return nil
}

func LoadConfig() Config {
	if loadedConfig != nil {
		return *loadedConfig
	}

	var config Config

	err := Load(ConfigPath(), &config)
	if err != nil {
		panic(err)
	}

	loadedConfig = &config
	return config
}

func (c Config) Protocol() string {
	if c.UseHttp {
		return "http://"
	} else {
		return "https://"
	}
}

func loadConfigFromPath(path string, config interface{}) error {
	configFile, err := os.Open(path)
	if err != nil {
		return err
	}
	defer configFile.Close()

	decoder := json.NewDecoder(configFile)
	return decoder.Decode(config)
}

func ConfigPath() string {
	path := os.Getenv("CONFIG")
	if path == "" {
		panic("Must set $CONFIG to point to an integration config .json file.")
	}

	return path
}
<commit_msg>Add new include_sso property to config helper<commit_after>package helpers

import (
	"encoding/json"
	"fmt"
	"os"
	"path/filepath"
	"reflect"
	"time"

	"github.com/cloudfoundry-incubator/cf-test-helpers/runner"
)

type Config struct {
	ApiEndpoint string `json:"api"`
	AppsDomain  string `json:"apps_domain"`
	UseHttp     bool   `json:"use_http"`

	AdminUser     string `json:"admin_user"`
	AdminPassword string `json:"admin_password"`

	UseExistingUser      bool   `json:"use_existing_user"`
	ShouldKeepUser       bool   `json:"keep_user_at_suite_end"`
	ExistingUser         string `json:"existing_user"`
	ExistingUserPassword string `json:"existing_user_password"`

	ConfigurableTestPassword string `json:"test_password"`

	PersistentAppHost      string `json:"persistent_app_host"`
	PersistentAppSpace     string `json:"persistent_app_space"`
	PersistentAppOrg       string `json:"persistent_app_org"`
	PersistentAppQuotaName string `json:"persistent_app_quota_name"`

	SkipSSLValidation                 bool   `json:"skip_ssl_validation"`
	Backend                           string `json:"backend"`
	IncludeDiegoDocker                bool   `json:"include_diego_docker"`
	IncludeTasks                      bool   `json:"include_tasks"`
	IncludePrivilegedContainerSupport bool   `json:"include_privileged_container_support"`
	IncludeSSO                        bool   `json:"include_sso"`

	ArtifactsDirectory string `json:"artifacts_directory"`

	DefaultTimeout     time.Duration `json:"default_timeout"`
	SleepTimeout       time.Duration `json:"sleep_timeout"`
	DetectTimeout      time.Duration `json:"detect_timeout"`
	CfPushTimeout      time.Duration `json:"cf_push_timeout"`
	LongCurlTimeout    time.Duration `json:"long_curl_timeout"`
	BrokerStartTimeout time.Duration `json:"broker_start_timeout"`

	TimeoutScale float64 `json:"timeout_scale"`

	SecureAddress string `json:"secure_address"`

	DockerExecutable      string   `json:"docker_executable"`
	DockerParameters      []string `json:"docker_parameters"`
	DockerRegistryAddress string   `json:"docker_registry_address"`
	DockerPrivateImage    string   `json:"docker_private_image"`
	DockerUser            string   `json:"docker_user"`
	DockerPassword        string   `json:"docker_password"`
	DockerEmail           string   `json:"docker_email"`

	StaticFileBuildpackName string `json:"staticfile_buildpack_name"`
	JavaBuildpackName       string `json:"java_buildpack_name"`
	RubyBuildpackName       string `json:"ruby_buildpack_name"`
	NodejsBuildpackName     string `json:"nodejs_buildpack_name"`
	GoBuildpackName         string `json:"go_buildpack_name"`
	PythonBuildpackName     string `json:"python_buildpack_name"`
	PhpBuildpackName        string `json:"php_buildpack_name"`
	BinaryBuildpackName     string `json:"binary_buildpack_name"`

	NamePrefix string `json:"name_prefix"`
}

var defaults = Config{
	PersistentAppHost:      "CATS-persistent-app",
	PersistentAppSpace:     "CATS-persistent-space",
	PersistentAppOrg:       "CATS-persistent-org",
	PersistentAppQuotaName: "CATS-persistent-quota",

	StaticFileBuildpackName: "staticfile_buildpack",
	JavaBuildpackName:       "java_buildpack",
	RubyBuildpackName:       "ruby_buildpack",
	NodejsBuildpackName:     "nodejs_buildpack",
	GoBuildpackName:         "go_buildpack",
	PythonBuildpackName:     "python_buildpack",
	PhpBuildpackName:        "php_buildpack",
	BinaryBuildpackName:     "binary_buildpack",

	ArtifactsDirectory: filepath.Join("..", "results"),

	NamePrefix: "CATS",
}

func (c Config) ScaledTimeout(timeout time.Duration) time.Duration {
	return time.Duration(float64(timeout) * c.TimeoutScale)
}

var loadedConfig *Config

func Load(path string, config interface{}) error {
	c, ok := config.(*Config)
	if !ok {
		val := reflect.ValueOf(config).Elem().FieldByName("Config").Addr()
		c = val.Interface().(*Config)
	}

	*c = defaults
	err := loadConfigFromPath(path, config)
	if err != nil {
		return err
	}

	if c.ApiEndpoint == "" {
		return fmt.Errorf("missing configuration 'api'")
	}

	if c.AdminUser == "" {
		return fmt.Errorf("missing configuration 'admin_user'")
	}

	if c.AdminPassword == "" {
		return fmt.Errorf("missing configuration 'admin_password'")
	}

	if c.TimeoutScale <= 0 {
		c.TimeoutScale = 1.0
	}

	runner.SkipSSLValidation = c.SkipSSLValidation
	return nil
}

func LoadConfig() Config {
	if loadedConfig != nil {
		return *loadedConfig
	}

	var config Config

	err := Load(ConfigPath(), &config)
	if err != nil {
		panic(err)
	}

	loadedConfig = &config
	return config
}

func (c Config) Protocol() string {
	if c.UseHttp {
		return "http://"
	} else {
		return "https://"
	}
}

func loadConfigFromPath(path string, config interface{}) error {
	configFile, err := os.Open(path)
	if err != nil {
		return err
	}
	defer configFile.Close()

	decoder := json.NewDecoder(configFile)
	return decoder.Decode(config)
}

func ConfigPath() string {
	path := os.Getenv("CONFIG")
	if path == "" {
		panic("Must set $CONFIG to point to an integration config .json file.")
	}

	return path
}
<|endoftext|>