<commit_before>package netcode

import (
	"math"
	"io"
)

type Buffer struct {
	Buf []byte
	Pos int
}

func NewBuffer(size int) *Buffer {
	b := &Buffer{}
	b.Buf = make([]byte, size)
	return b
}

func NewBufferFromBytes(buf []byte) *Buffer {
	b := &Buffer{}
	b.Buf = buf
	return b
}

func (b *Buffer) Copy() *Buffer {
	c := NewBufferFromBytes(b.Buf)
	return c
}

func (b *Buffer) Len() int {
	return len(b.Buf)
}

func (b *Buffer) Bytes() []byte {
	return b.Buf
}

// GetByte decodes a little-endian byte
func (b *Buffer) GetByte() (byte, error) {
	return b.GetUint8()
}

// GetBytes returns a byte slice possibly smaller than length if bytes are not available from the
// reader.
func (b *Buffer) GetBytes(length int) ([]byte, error) {
	if len(b.Buf) < length {
		return nil, io.EOF
	}
	value := b.Buf[b.Pos:b.Pos+length]
	b.Pos += length
	return value, nil
}

// GetUint8 decodes a little-endian uint8 from the buffer
func (b *Buffer) GetUint8() (uint8, error) {
	if b.Pos + SizeUint8 > len(b.Buf) {
		return 0, io.EOF
	}
	buf := b.Buf[b.Pos:b.Pos+SizeUint8]
	b.Pos++
	return uint8(buf[0]), nil
}

// GetUint16 decodes a little-endian uint16 from the buffer
func (b *Buffer) GetUint16() (uint16, error) {
	var n uint16
	buf, err := b.GetBytes(SizeUint16)
	n |= uint16(buf[0])
	n |= uint16(buf[1]) << 8
	return n, err
}

// GetUint32 decodes a little-endian uint32 from the buffer
func (b *Buffer) GetUint32() (uint32, error) {
	var n uint32
	buf, err := b.GetBytes(SizeUint32)
	n |= uint32(buf[0])
	n |= uint32(buf[1]) << 8
	n |= uint32(buf[2]) << 16
	n |= uint32(buf[3]) << 24
	return n, err
}

// GetUint64 decodes a little-endian uint64 from the buffer
func (b *Buffer) GetUint64() (uint64, error) {
	var n uint64
	buf, err := b.GetBytes(SizeUint64)
	n |= uint64(buf[0])
	n |= uint64(buf[1]) << 8
	n |= uint64(buf[2]) << 16
	n |= uint64(buf[3]) << 24
	n |= uint64(buf[4]) << 32
	n |= uint64(buf[5]) << 40
	n |= uint64(buf[6]) << 48
	n |= uint64(buf[7]) << 56
	return n, err
}

// GetInt8 decodes a little-endian int8 from the buffer
func (b *Buffer)  GetInt8() (int8, error) {
	if b.Pos + 1 > len(b.Buf) {
		return 0, io.EOF
	}
	buf := b.Buf[b.Pos:b.Pos+SizeInt8]
	return int8(buf[0]), nil
}

// GetInt16 decodes a little-endian int16 from the buffer
func (b *Buffer) GetInt16() (int16, error) {
	var n int16
	buf, err := b.GetBytes(SizeInt16)
	n |= int16(buf[0])
	n |= int16(buf[1]) << 8
	return n, err
}

// GetInt32 decodes a little-endian int32 from the buffer
func (b *Buffer) GetInt32() (int32, error) {
	var n int32
	buf, err := b.GetBytes(SizeInt32)
	n |= int32(buf[0])
	n |= int32(buf[1]) << 8
	n |= int32(buf[2]) << 16
	n |= int32(buf[3]) << 24
	return n, err
}

// GetInt64 decodes a little-endian int64 from the buffer
func (b *Buffer) GetInt64() (int64, error) {
	var n int64
	buf, err := b.GetBytes(SizeInt64)
	n |= int64(buf[0])
	n |= int64(buf[1]) << 8
	n |= int64(buf[2]) << 16
	n |= int64(buf[3]) << 24
	n |= int64(buf[4]) << 32
	n |= int64(buf[5]) << 40
	n |= int64(buf[6]) << 48
	n |= int64(buf[7]) << 56
	return n, err
}

// WriteByte encodes a little-endian uint8 into the buffer.
func (b *Buffer) WriteByte(n byte) {
	b.Buf[b.Pos] = uint8(n)
	b.Pos++
}

// WriteBytes encodes a little-endian byte slice into the buffer
func (b *Buffer) WriteBytes(src []byte) {
	for i := 0; i < len(src); i+=1 {
		b.WriteByte(uint8(src[i]))
	}
}

// WriteBytes encodes a little-endian byte slice into the buffer
func (b *Buffer) WriteBytesN(src []byte, length int) {
	for i := 0; i < length; i+=1 {
		b.WriteByte(uint8(src[i]))
	}
}

// WriteUint8 encodes a little-endian uint8 into the buffer.
func (b *Buffer) WriteUint8(n uint8) {
	b.Buf[b.Pos] = byte(n)
	b.Pos++
}

// WriteUint16 encodes a little-endian uint16 into the buffer.
func (b *Buffer) WriteUint16(n uint16) {
	b.Buf[b.Pos] = byte(n)
	b.Pos++
	b.Buf[b.Pos] = byte(n >> 8)
	b.Pos++
}

// WriteUint32 encodes a little-endian uint32 into the buffer.
func (b *Buffer) WriteUint32(n uint32) {
	b.Buf[b.Pos] = byte(n)
	b.Pos++
	b.Buf[b.Pos] = byte(n >> 8)
	b.Pos++
	b.Buf[b.Pos] = byte(n >> 16)
	b.Pos++
	b.Buf[b.Pos] = byte(n >> 24)
	b.Pos++
}

// WriteUint64 encodes a little-endian uint64 into the buffer.
func (b *Buffer) WriteUint64(n uint64) {
	for i := uint(0); i < uint(SizeUint64); i++ {
		b.Buf[b.Pos] = byte(n >> (i * 8))
		b.Pos++
	}
}

// WriteInt8 encodes a little-endian int8 into the buffer.
func (b *Buffer) WriteInt8(n int8) {
	b.Buf[b.Pos] = byte(n)
	b.Pos++
}

// WriteInt16 encodes a little-endian int16 into the buffer.
func (b *Buffer) WriteInt16(n int16) {
	b.Buf[b.Pos] = byte(n)
	b.Pos++
	b.Buf[b.Pos] = byte(n >> 8)
	b.Pos++
}

// WriteInt32 encodes a little-endian int32 into the buffer.
func (b *Buffer) WriteInt32(n int32) {
	b.Buf[b.Pos] = byte(n)
	b.Pos++
	b.Buf[b.Pos] = byte(n >> 8)
	b.Pos++
	b.Buf[b.Pos] = byte(n >> 16)
	b.Pos++
	b.Buf[b.Pos] = byte(n >> 24)
	b.Pos++
}

// WriteInt64 encodes a little-endian int64 into the buffer.
func (b *Buffer) WriteInt64(n int64) {
	for i := uint(0); i < uint(SizeInt64); i++ {
		b.Buf[b.Pos] = byte(n >> (i * 8))
		b.Pos++
	}
}

// WriteFloat32 encodes a little-endian float32 into the buffer.
func (b *Buffer) WriteFloat32(n float32) {
	b.WriteUint32(math.Float32bits(n))
}

// WriteFloat64 encodes a little-endian float64 into the buffer.
func (b *Buffer)  WriteFloat64(buf []byte, n float64) {
	b.WriteUint64(math.Float64bits(n))
}
<commit_msg>fix buffer check for errors<commit_after>package netcode

import (
	"math"
	"io"
)

type Buffer struct {
	Buf []byte
	Pos int
}

func NewBuffer(size int) *Buffer {
	b := &Buffer{}
	b.Buf = make([]byte, size)
	return b
}

func NewBufferFromBytes(buf []byte) *Buffer {
	b := &Buffer{}
	b.Buf = buf
	return b
}

func (b *Buffer) Copy() *Buffer {
	c := NewBufferFromBytes(b.Buf)
	return c
}

func (b *Buffer) Len() int {
	return len(b.Buf)
}

func (b *Buffer) Bytes() []byte {
	return b.Buf
}

// GetByte decodes a little-endian byte
func (b *Buffer) GetByte() (byte, error) {
	return b.GetUint8()
}

// GetBytes returns a byte slice possibly smaller than length if bytes are not available from the
// reader.
func (b *Buffer) GetBytes(length int) ([]byte, error) {
	if len(b.Buf) < length {
		return nil, io.EOF
	}
	value := b.Buf[b.Pos:b.Pos+length]
	b.Pos += length
	return value, nil
}

// GetUint8 decodes a little-endian uint8 from the buffer
func (b *Buffer) GetUint8() (uint8, error) {
	if b.Pos + SizeUint8 > len(b.Buf) {
		return 0, io.EOF
	}
	buf := b.Buf[b.Pos:b.Pos+SizeUint8]
	b.Pos++
	return uint8(buf[0]), nil
}

// GetUint16 decodes a little-endian uint16 from the buffer
func (b *Buffer) GetUint16() (uint16, error) {
	var n uint16
	buf, err := b.GetBytes(SizeUint16)
	if err != nil {
		return 0, nil
	}
	n |= uint16(buf[0])
	n |= uint16(buf[1]) << 8
	return n, nil
}

// GetUint32 decodes a little-endian uint32 from the buffer
func (b *Buffer) GetUint32() (uint32, error) {
	var n uint32
	buf, err := b.GetBytes(SizeUint32)
	if err != nil {
		return 0, nil
	}
	n |= uint32(buf[0])
	n |= uint32(buf[1]) << 8
	n |= uint32(buf[2]) << 16
	n |= uint32(buf[3]) << 24
	return n, nil
}

// GetUint64 decodes a little-endian uint64 from the buffer
func (b *Buffer) GetUint64() (uint64, error) {
	var n uint64
	buf, err := b.GetBytes(SizeUint64)
	if err != nil {
		return 0, nil
	}
	n |= uint64(buf[0])
	n |= uint64(buf[1]) << 8
	n |= uint64(buf[2]) << 16
	n |= uint64(buf[3]) << 24
	n |= uint64(buf[4]) << 32
	n |= uint64(buf[5]) << 40
	n |= uint64(buf[6]) << 48
	n |= uint64(buf[7]) << 56
	return n, nil
}

// GetInt8 decodes a little-endian int8 from the buffer
func (b *Buffer)  GetInt8() (int8, error) {
	if b.Pos + 1 > len(b.Buf) {
		return 0, io.EOF
	}
	buf := b.Buf[b.Pos:b.Pos+SizeInt8]
	return int8(buf[0]), nil
}

// GetInt16 decodes a little-endian int16 from the buffer
func (b *Buffer) GetInt16() (int16, error) {
	var n int16
	buf, err := b.GetBytes(SizeInt16)
	if err != nil {
		return 0, nil
	}
	n |= int16(buf[0])
	n |= int16(buf[1]) << 8
	return n, nil
}

// GetInt32 decodes a little-endian int32 from the buffer
func (b *Buffer) GetInt32() (int32, error) {
	var n int32
	buf, err := b.GetBytes(SizeInt32)
	if err != nil {
		return 0, nil
	}
	n |= int32(buf[0])
	n |= int32(buf[1]) << 8
	n |= int32(buf[2]) << 16
	n |= int32(buf[3]) << 24
	return n, nil
}

// GetInt64 decodes a little-endian int64 from the buffer
func (b *Buffer) GetInt64() (int64, error) {
	var n int64
	buf, err := b.GetBytes(SizeInt64)
	if err != nil {
		return 0, nil
	}
	n |= int64(buf[0])
	n |= int64(buf[1]) << 8
	n |= int64(buf[2]) << 16
	n |= int64(buf[3]) << 24
	n |= int64(buf[4]) << 32
	n |= int64(buf[5]) << 40
	n |= int64(buf[6]) << 48
	n |= int64(buf[7]) << 56
	return n, nil
}

// WriteByte encodes a little-endian uint8 into the buffer.
func (b *Buffer) WriteByte(n byte) {
	b.Buf[b.Pos] = uint8(n)
	b.Pos++
}

// WriteBytes encodes a little-endian byte slice into the buffer
func (b *Buffer) WriteBytes(src []byte) {
	for i := 0; i < len(src); i+=1 {
		b.WriteByte(uint8(src[i]))
	}
}

// WriteBytes encodes a little-endian byte slice into the buffer
func (b *Buffer) WriteBytesN(src []byte, length int) {
	for i := 0; i < length; i+=1 {
		b.WriteByte(uint8(src[i]))
	}
}

// WriteUint8 encodes a little-endian uint8 into the buffer.
func (b *Buffer) WriteUint8(n uint8) {
	b.Buf[b.Pos] = byte(n)
	b.Pos++
}

// WriteUint16 encodes a little-endian uint16 into the buffer.
func (b *Buffer) WriteUint16(n uint16) {
	b.Buf[b.Pos] = byte(n)
	b.Pos++
	b.Buf[b.Pos] = byte(n >> 8)
	b.Pos++
}

// WriteUint32 encodes a little-endian uint32 into the buffer.
func (b *Buffer) WriteUint32(n uint32) {
	b.Buf[b.Pos] = byte(n)
	b.Pos++
	b.Buf[b.Pos] = byte(n >> 8)
	b.Pos++
	b.Buf[b.Pos] = byte(n >> 16)
	b.Pos++
	b.Buf[b.Pos] = byte(n >> 24)
	b.Pos++
}

// WriteUint64 encodes a little-endian uint64 into the buffer.
func (b *Buffer) WriteUint64(n uint64) {
	for i := uint(0); i < uint(SizeUint64); i++ {
		b.Buf[b.Pos] = byte(n >> (i * 8))
		b.Pos++
	}
}

// WriteInt8 encodes a little-endian int8 into the buffer.
func (b *Buffer) WriteInt8(n int8) {
	b.Buf[b.Pos] = byte(n)
	b.Pos++
}

// WriteInt16 encodes a little-endian int16 into the buffer.
func (b *Buffer) WriteInt16(n int16) {
	b.Buf[b.Pos] = byte(n)
	b.Pos++
	b.Buf[b.Pos] = byte(n >> 8)
	b.Pos++
}

// WriteInt32 encodes a little-endian int32 into the buffer.
func (b *Buffer) WriteInt32(n int32) {
	b.Buf[b.Pos] = byte(n)
	b.Pos++
	b.Buf[b.Pos] = byte(n >> 8)
	b.Pos++
	b.Buf[b.Pos] = byte(n >> 16)
	b.Pos++
	b.Buf[b.Pos] = byte(n >> 24)
	b.Pos++
}

// WriteInt64 encodes a little-endian int64 into the buffer.
func (b *Buffer) WriteInt64(n int64) {
	for i := uint(0); i < uint(SizeInt64); i++ {
		b.Buf[b.Pos] = byte(n >> (i * 8))
		b.Pos++
	}
}

// WriteFloat32 encodes a little-endian float32 into the buffer.
func (b *Buffer) WriteFloat32(n float32) {
	b.WriteUint32(math.Float32bits(n))
}

// WriteFloat64 encodes a little-endian float64 into the buffer.
func (b *Buffer)  WriteFloat64(buf []byte, n float64) {
	b.WriteUint64(math.Float64bits(n))
}
<|endoftext|>


<commit_before>package main

import (
    "os"
    "fmt"
    "log"
    "net/http"
    "time"
    "strconv"
)

const (
    msgBuf = 50
)

type SSE struct{}

func (s *SSE) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
    f, ok := rw.(http.Flusher)
    if !ok {
        http.Error(rw, "cannot stream", http.StatusInternalServerError)
        return
    }

    rw.Header().Set("Content-Type", "text/event-stream")
    rw.Header().Set("Cache-Control", "no-cache")
    rw.Header().Set("Connection", "keep-alive")
    fmt.Fprintf(rw, ":ok\n\n")
    f.Flush()

    cn, ok := rw.(http.CloseNotifier)
    if !ok {
        http.Error(rw, "cannot stream", http.StatusInternalServerError)
        return
    }

    messages := msgBroker.Subscribe()

    for {
        select {
        case <-cn.CloseNotify():
            msgBroker.Unsubscribe(messages)
            return
        case msg := <-messages:
            fmt.Fprintf(rw, "data: %s\n\n", msg)
            f.Flush()
        }
    }
}

func main() {
    msgBroker = NewBroker()

    port := "1942"
    if len(os.Args) > 2 {
        port = os.Args[2]
    }

    http.Handle("/sse", &SSE{})
    http.HandleFunc("/connections", func(w http.ResponseWriter, req *http.Request) {
        w.Header().Set("Content-Type", "text/plain")
        w.Header().Set("Cache-Control", "no-cache")
        w.Header().Set("Connection", "close")
        fmt.Fprintf(w, strconv.Itoa(msgBroker.SubscriberCount()))
    })

    go func() {
        for {
            msg := strconv.FormatInt(time.Now().UnixNano() / 1000000, 10);
            msgBroker.Publish([]byte(msg))
            time.Sleep(time.Second)
        }
    }()

    fmt.Println("Listening on http://127.0.0.1:" + port + "/")
    log.Fatal(http.ListenAndServe(":" + port, nil))
}

type Broker struct {
    subscribers map[chan []byte]bool
}

func (b *Broker) Subscribe() chan []byte {
    ch := make(chan []byte, msgBuf)
    b.subscribers[ch] = true
    return ch
}

func (b *Broker) Unsubscribe(ch chan []byte) {
    delete(b.subscribers, ch)
}

func (b *Broker) SubscriberCount() int {
    return len(b.subscribers)
}

func (b *Broker) Publish(msg []byte) {
    for ch := range b.subscribers {
        ch <- msg
    }
}

func NewBroker() *Broker {
    return &Broker{make(map[chan []byte]bool)}
}

var msgBroker *Broker<commit_msg>Send CORS-headers<commit_after>package main

import (
    "os"
    "fmt"
    "log"
    "net/http"
    "time"
    "strconv"
)

const (
    msgBuf = 50
)

type SSE struct{}

func (s *SSE) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
    f, ok := rw.(http.Flusher)
    if !ok {
        http.Error(rw, "cannot stream", http.StatusInternalServerError)
        return
    }

    if req.Method == "OPTIONS" {
        rw.Header().Set("Access-Control-Allow-Origin", "*")
        rw.Header().Set("Connection", "close")
        rw.WriteHeader(204)
        return
    }

    rw.Header().Set("Content-Type", "text/event-stream")
    rw.Header().Set("Cache-Control", "no-cache")
    rw.Header().Set("Access-Control-Allow-Origin", "*")
    rw.Header().Set("Connection", "keep-alive")
    fmt.Fprintf(rw, ":ok\n\n")
    f.Flush()

    cn, ok := rw.(http.CloseNotifier)
    if !ok {
        http.Error(rw, "cannot stream", http.StatusInternalServerError)
        return
    }

    messages := msgBroker.Subscribe()

    for {
        select {
        case <-cn.CloseNotify():
            msgBroker.Unsubscribe(messages)
            return
        case msg := <-messages:
            fmt.Fprintf(rw, "data: %s\n\n", msg)
            f.Flush()
        }
    }
}

func main() {
    msgBroker = NewBroker()

    port := "1942"
    if len(os.Args) > 2 {
        port = os.Args[2]
    }

    http.Handle("/sse", &SSE{})
    http.HandleFunc("/connections", func(w http.ResponseWriter, req *http.Request) {
        w.Header().Set("Content-Type", "text/plain")
        w.Header().Set("Cache-Control", "no-cache")
        w.Header().Set("Access-Control-Allow-Origin", "*")
        w.Header().Set("Connection", "close")
        fmt.Fprintf(w, strconv.Itoa(msgBroker.SubscriberCount()))
    })

    go func() {
        for {
            msg := strconv.FormatInt(time.Now().UnixNano() / 1000000, 10);
            msgBroker.Publish([]byte(msg))
            time.Sleep(time.Second)
        }
    }()

    fmt.Println("Listening on http://127.0.0.1:" + port + "/")
    log.Fatal(http.ListenAndServe(":" + port, nil))
}

type Broker struct {
    subscribers map[chan []byte]bool
}

func (b *Broker) Subscribe() chan []byte {
    ch := make(chan []byte, msgBuf)
    b.subscribers[ch] = true
    return ch
}

func (b *Broker) Unsubscribe(ch chan []byte) {
    delete(b.subscribers, ch)
}

func (b *Broker) SubscriberCount() int {
    return len(b.subscribers)
}

func (b *Broker) Publish(msg []byte) {
    for ch := range b.subscribers {
        ch <- msg
    }
}

func NewBroker() *Broker {
    return &Broker{make(map[chan []byte]bool)}
}

var msgBroker *Broker<|endoftext|>


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

package main

import (
	"fmt"
	"go/ast"
	"go/token"
	"os/exec"
	"reflect"
	"strings"

	"github.com/petergtz/goextract/util"
)

type Selection struct {
	Begin, End Position
}

type Position struct {
	Line, Column int
}

type visitorContext struct {
	fset           *token.FileSet
	posParent      ast.Node
	endParent      ast.Node
	nodesToExtract []ast.Node
	shouldRecord   bool

	selection Selection
}

type astNodeVisitorForExpressions struct {
	parentNode ast.Node
	context    *visitorContext
}

func (visitor *astNodeVisitorForExpressions) Visit(node ast.Node) (w ast.Visitor) {
	if node != nil {
		_, isExpr := node.(ast.Expr)
		if visitor.context.fset.Position(node.Pos()).Line == visitor.context.selection.Begin.Line &&
			visitor.context.fset.Position(node.Pos()).Column == visitor.context.selection.Begin.Column &&
			visitor.context.fset.Position(node.End()).Line == visitor.context.selection.End.Line &&
			visitor.context.fset.Position(node.End()).Column == visitor.context.selection.End.Column &&
			isExpr {
			// fmt.Println("Starting with node at pos", visitor.context.fset.Position(node.Pos()), "and end", visitor.context.fset.Position(node.End()))
			// ast.Print(visitor.context.fset, node)
			// fmt.Println(node.Pos(), node)
			visitor.context.posParent = visitor.parentNode
			visitor.context.endParent = visitor.parentNode
			visitor.context.nodesToExtract = append(visitor.context.nodesToExtract, node)
			return nil
		}
	}
	return &astNodeVisitorForExpressions{
		parentNode: node,
		context:    visitor.context,
	}
}

type astNodeVisitorForMultipleStatements struct {
	parentNode ast.Node
	context    *visitorContext
}

func (visitor *astNodeVisitorForMultipleStatements) Visit(node ast.Node) (w ast.Visitor) {
	if node != nil {
		if visitor.context.fset.Position(node.Pos()).Line == visitor.context.selection.Begin.Line &&
			visitor.context.fset.Position(node.Pos()).Column == visitor.context.selection.Begin.Column &&
			!visitor.context.shouldRecord {
			fmt.Println("Starting with node at pos", visitor.context.fset.Position(node.Pos()), "and end", visitor.context.fset.Position(node.End()))
			ast.Print(visitor.context.fset, node)
			fmt.Println(node.Pos(), node)
			fmt.Println("Parent")
			ast.Print(visitor.context.fset, visitor.parentNode)
			visitor.context.posParent = visitor.parentNode
			visitor.context.shouldRecord = true
		}
		if visitor.context.shouldRecord && visitor.context.posParent == visitor.parentNode {
			visitor.context.nodesToExtract = append(visitor.context.nodesToExtract, node)
		}
		if visitor.context.fset.Position(node.End()).Line == visitor.context.selection.End.Line &&
			visitor.context.fset.Position(node.End()).Column == visitor.context.selection.End.Column {
			fmt.Println("Ending with node at pos", visitor.context.fset.Position(node.Pos()), "and end", visitor.context.fset.Position(node.End()))
			ast.Print(visitor.context.fset, node)
			fmt.Println("Parent")
			ast.Print(visitor.context.fset, visitor.parentNode)
			visitor.context.endParent = visitor.parentNode
			visitor.context.shouldRecord = false
			return nil
		}
	}
	return &astNodeVisitorForMultipleStatements{
		parentNode: node,
		context:    visitor.context,
	}
}

// 3 cases:
// 1. Pure expression
// 2. Pure procedural (implies side effects) -> list of statemtents -> no return value
// 3. Final assignment to local variable -> list of statements where final is an assignment

// fmt.Println(
// 	fileSet.Position(astFile.Decls[1].Pos()),
// 	fileSet.Position(astFile.Decls[1].End()),
// )

func ExtractFileToFile(inputFileName string, selection Selection, extractedFuncName string, outputFilename string) {
	fileSet, astFile := astFromFile(inputFileName)
	createAstFileDump(inputFileName+".ast", fileSet, astFile)
	doExtraction(fileSet, astFile, selection, extractedFuncName)
	util.WriteFileAsStringOrPanic(outputFilename, stringFrom(fileSet, astFile))
	err := exec.Command("gofmt", "-w", outputFilename).Run()
	util.PanicOnError(err)
}

func ExtractFileToString(inputFileName string, selection Selection, extractedFuncName string) string {
	fileSet, astFile := astFromFile(inputFileName)
	createAstFileDump(inputFileName+".ast", fileSet, astFile)
	doExtraction(fileSet, astFile, selection, extractedFuncName)
	return stringFrom(fileSet, astFile)
}

func ExtractStringToString(input string, selection Selection, extractedFuncName string) string {
	fileSet, astFile := astFromInput(input)
	doExtraction(fileSet, astFile, selection, extractedFuncName)
	return stringFrom(fileSet, astFile)
}

func doExtraction(fileSet *token.FileSet, astFile *ast.File, selection Selection, extractedFuncName string) {

	visitor := &astNodeVisitorForExpressions{parentNode: nil, context: &visitorContext{fset: fileSet, selection: selection}}
	ast.Walk(visitor, astFile)
	context := visitor.context
	if len(context.nodesToExtract) == 0 {
		v := &astNodeVisitorForMultipleStatements{parentNode: nil, context: &visitorContext{fset: fileSet, selection: selection}}
		ast.Walk(v, astFile)
		context = v.context
	}
	if context.posParent != context.endParent {
		panic(fmt.Sprintf("Selection is not valid. posParent: %v; endParent: %v",
			context.posParent, context.endParent))
	}
	if context.posParent == nil {
		panic(fmt.Sprintf("Selection is not valid. posParent: %v; endParent: %v",
			context.posParent, context.endParent))
	}
	if len(context.nodesToExtract) == 1 {
		extractExpression(astFile, fileSet, context, extractedFuncName)
	} else {
		extractMultipleStatements(astFile, fileSet, context, extractedFuncName)
	}

}

type varListerVisitor struct {
	fileSet *token.FileSet
	vars    map[string]string
}

func (visitor *varListerVisitor) Visit(node ast.Node) (w ast.Visitor) {
	if typedNode, ok := node.(*ast.Ident); ok &&
		typedNode.Obj != nil && typedNode.Obj.Kind == ast.Var {
		var typeString string
		switch typedDecl := typedNode.Obj.Decl.(type) {
		case *ast.AssignStmt:
			for i, lhs := range typedDecl.Lhs {
				if lhs.(*ast.Ident).Name == typedNode.Name {
					typeString = deduceReturnTypeString(typedDecl.Rhs[i].(ast.Expr))
				}
			}
		default:
			typeString = "UnresolvedType"
		}
		visitor.vars[typedNode.Name] = typeString
	}
	return visitor
}

func listAllUsedIdentifiersThatAreVars(nodes []ast.Node, fileSet *token.FileSet) map[string]string {
	result := make(map[string]string)
	for _, node := range nodes {
		v := &varListerVisitor{fileSet: fileSet, vars: make(map[string]string)}
		ast.Walk(v, node)
		mapStringStringAddAll(result, v.vars)
	}
	return result
}

func mapStringStringAddAll(dst, src map[string]string) {
	for k, v := range src {
		dst[k] = v
	}
}

func extractExpression(
	astFile *ast.File,
	fileSet *token.FileSet,
	context *visitorContext,
	extractedFuncName string) {

	// TODO: Ideally this would only list variables that are not available
	// outside of the scope where the expressions lives
	params := listAllUsedIdentifiersThatAreVars(context.nodesToExtract, fileSet)
	var stmts []ast.Stmt

	switch typedNode := context.posParent.(type) {
	case *ast.AssignStmt:
		for i, rhs := range typedNode.Rhs {
			if rhs == context.nodesToExtract[0] {
				typedNode.Rhs[i] = extractExprFrom(extractedFuncName, params)
			}
		}
	case *ast.CallExpr:
		for i, arg := range typedNode.Args {
			if arg == context.nodesToExtract[0] {
				typedNode.Args[i] = extractExprFrom(extractedFuncName, params)
			}
		}
	case *ast.ExprStmt:
		typedNode.X = extractExprFrom(extractedFuncName, params)

	// TODO:
	// Add more cases here

	default:
		panic(fmt.Sprintf("Type %v not supported yet", reflect.TypeOf(context.posParent)))
	}
	insertExtractedFuncInto(
		astFile,
		fileSet,
		extractedFuncName,
		argsAndTypesFrom(params),
		stmts,
		context.nodesToExtract[0].(ast.Expr))
}

func extractMultipleStatements(
	astFile *ast.File,
	fileSet *token.FileSet,
	context *visitorContext,
	extractedFuncName string) {
	params := listAllUsedIdentifiersThatAreVars(context.nodesToExtract, fileSet)
	var stmts []ast.Stmt

	switch typedNode := context.posParent.(type) {
	case *ast.BlockStmt:
		extractedExpressionNodes := astNodeSetFrom(context.nodesToExtract)
		replaced := false
		for i, stmt := range typedNode.List {
			if extractedExpressionNodes[stmt] {
				stmts = append(stmts, stmt)
				if !replaced {
					typedNode.List[i] = &ast.ExprStmt{X: extractExprFrom(extractedFuncName, params)}
					replaced = true
				} else {
					typedNode.List = append(typedNode.List[:i], typedNode.List[i+1:]...)
				}
			}
		}
	// TODO:
	// Add more cases here

	default:
		panic(fmt.Sprintf("Type %v not supported yet", reflect.TypeOf(context.posParent)))
	}

	insertExtractedFuncInto(
		astFile,
		fileSet,
		extractedFuncName,
		argsAndTypesFrom(params),
		stmts,
		nil,
	)
}

func astNodeSetFrom(nodes []ast.Node) map[ast.Node]bool {
	result := make(map[ast.Node]bool)
	for _, node := range nodes {
		result[node] = true
	}
	return result
}

func extractExprFrom(extractedFuncName string, params map[string]string) *ast.CallExpr {
	return &ast.CallExpr{
		Fun:  ast.NewIdent(extractedFuncName),
		Args: argsFrom(params),
	}
}

func argsFrom(params map[string]string) (result []ast.Expr) {
	for key := range params {
		result = append(result, ast.NewIdent(key))
	}
	return
}

func argsAndTypesFrom(params map[string]string) (result []*ast.Field) {
	for key, val := range params {
		result = append(result, &ast.Field{
			Names: []*ast.Ident{ast.NewIdent(key)},
			Type:  ast.NewIdent(val),
		})
	}
	return
}

func insertExtractedFuncInto(
	astFile *ast.File,
	fileSet *token.FileSet,
	extractedFuncName string,
	argsAndTypes []*ast.Field,
	stmts []ast.Stmt,
	returnExpr ast.Expr) {

	allStmts := make([]ast.Stmt, len(stmts), len(stmts)+1)
	copy(allStmts, stmts)
	var returnType *ast.FieldList
	if returnExpr != nil {
		returnTypeString := deduceReturnTypeString(returnExpr)
		if returnTypeString == "" {
			allStmts = append(allStmts, &ast.ExprStmt{X: returnExpr})
		} else {
			allStmts = append(allStmts, &ast.ReturnStmt{Results: []ast.Expr{returnExpr}})
		}
		returnType = &ast.FieldList{List: []*ast.Field{
			&ast.Field{Type: ast.NewIdent(returnTypeString)},
		}}
	}
	astFile.Decls = append(astFile.Decls, &ast.FuncDecl{
		Name: ast.NewIdent(extractedFuncName),
		Type: &ast.FuncType{
			Params:  &ast.FieldList{List: argsAndTypes},
			Results: returnType,
		},
		Body: &ast.BlockStmt{List: allStmts},
	})
}

func deduceReturnTypeString(expr ast.Expr) string {
	switch typedExpr := expr.(type) {
	case *ast.BasicLit:
		return strings.ToLower(typedExpr.Kind.String())
	case *ast.CallExpr:
		if typedExpr.Fun.(*ast.Ident).Obj.Decl.(*ast.FuncDecl).Type.Results == nil {
			return ""
		}
		result := ""
		for _, res := range typedExpr.Fun.(*ast.Ident).Obj.Decl.(*ast.FuncDecl).Type.Results.List {
			result += " " + res.Type.(*ast.Ident).Name
		}
		return result
	default:
		return "TODO"
	}
}
<commit_msg>Specify cases TODO  for multiple statements<commit_after>// Copyright 2015 Peter Goetz
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package main

import (
	"fmt"
	"go/ast"
	"go/token"
	"os/exec"
	"reflect"
	"strings"

	"github.com/petergtz/goextract/util"
)

type Selection struct {
	Begin, End Position
}

type Position struct {
	Line, Column int
}

type visitorContext struct {
	fset           *token.FileSet
	posParent      ast.Node
	endParent      ast.Node
	nodesToExtract []ast.Node
	shouldRecord   bool

	selection Selection
}

type astNodeVisitorForExpressions struct {
	parentNode ast.Node
	context    *visitorContext
}

func (visitor *astNodeVisitorForExpressions) Visit(node ast.Node) (w ast.Visitor) {
	if node != nil {
		_, isExpr := node.(ast.Expr)
		if visitor.context.fset.Position(node.Pos()).Line == visitor.context.selection.Begin.Line &&
			visitor.context.fset.Position(node.Pos()).Column == visitor.context.selection.Begin.Column &&
			visitor.context.fset.Position(node.End()).Line == visitor.context.selection.End.Line &&
			visitor.context.fset.Position(node.End()).Column == visitor.context.selection.End.Column &&
			isExpr {
			// fmt.Println("Starting with node at pos", visitor.context.fset.Position(node.Pos()), "and end", visitor.context.fset.Position(node.End()))
			// ast.Print(visitor.context.fset, node)
			// fmt.Println(node.Pos(), node)
			visitor.context.posParent = visitor.parentNode
			visitor.context.endParent = visitor.parentNode
			visitor.context.nodesToExtract = append(visitor.context.nodesToExtract, node)
			return nil
		}
	}
	return &astNodeVisitorForExpressions{
		parentNode: node,
		context:    visitor.context,
	}
}

type astNodeVisitorForMultipleStatements struct {
	parentNode ast.Node
	context    *visitorContext
}

func (visitor *astNodeVisitorForMultipleStatements) Visit(node ast.Node) (w ast.Visitor) {
	if node != nil {
		if visitor.context.fset.Position(node.Pos()).Line == visitor.context.selection.Begin.Line &&
			visitor.context.fset.Position(node.Pos()).Column == visitor.context.selection.Begin.Column &&
			!visitor.context.shouldRecord {
			fmt.Println("Starting with node at pos", visitor.context.fset.Position(node.Pos()), "and end", visitor.context.fset.Position(node.End()))
			ast.Print(visitor.context.fset, node)
			fmt.Println(node.Pos(), node)
			fmt.Println("Parent")
			ast.Print(visitor.context.fset, visitor.parentNode)
			visitor.context.posParent = visitor.parentNode
			visitor.context.shouldRecord = true
		}
		if visitor.context.shouldRecord && visitor.context.posParent == visitor.parentNode {
			visitor.context.nodesToExtract = append(visitor.context.nodesToExtract, node)
		}
		if visitor.context.fset.Position(node.End()).Line == visitor.context.selection.End.Line &&
			visitor.context.fset.Position(node.End()).Column == visitor.context.selection.End.Column {
			fmt.Println("Ending with node at pos", visitor.context.fset.Position(node.Pos()), "and end", visitor.context.fset.Position(node.End()))
			ast.Print(visitor.context.fset, node)
			fmt.Println("Parent")
			ast.Print(visitor.context.fset, visitor.parentNode)
			visitor.context.endParent = visitor.parentNode
			visitor.context.shouldRecord = false
			return nil
		}
	}
	return &astNodeVisitorForMultipleStatements{
		parentNode: node,
		context:    visitor.context,
	}
}

// 3 cases:
// 1. Pure expression
// 2. Pure procedural (implies side effects) -> list of statemtents -> no return value
// 3. Final assignment to local variable -> list of statements where final is an assignment

// fmt.Println(
// 	fileSet.Position(astFile.Decls[1].Pos()),
// 	fileSet.Position(astFile.Decls[1].End()),
// )

func ExtractFileToFile(inputFileName string, selection Selection, extractedFuncName string, outputFilename string) {
	fileSet, astFile := astFromFile(inputFileName)
	createAstFileDump(inputFileName+".ast", fileSet, astFile)
	doExtraction(fileSet, astFile, selection, extractedFuncName)
	util.WriteFileAsStringOrPanic(outputFilename, stringFrom(fileSet, astFile))
	err := exec.Command("gofmt", "-w", outputFilename).Run()
	util.PanicOnError(err)
}

func ExtractFileToString(inputFileName string, selection Selection, extractedFuncName string) string {
	fileSet, astFile := astFromFile(inputFileName)
	createAstFileDump(inputFileName+".ast", fileSet, astFile)
	doExtraction(fileSet, astFile, selection, extractedFuncName)
	return stringFrom(fileSet, astFile)
}

func ExtractStringToString(input string, selection Selection, extractedFuncName string) string {
	fileSet, astFile := astFromInput(input)
	doExtraction(fileSet, astFile, selection, extractedFuncName)
	return stringFrom(fileSet, astFile)
}

func doExtraction(fileSet *token.FileSet, astFile *ast.File, selection Selection, extractedFuncName string) {

	visitor := &astNodeVisitorForExpressions{parentNode: nil, context: &visitorContext{fset: fileSet, selection: selection}}
	ast.Walk(visitor, astFile)
	context := visitor.context
	if len(context.nodesToExtract) == 0 {
		v := &astNodeVisitorForMultipleStatements{parentNode: nil, context: &visitorContext{fset: fileSet, selection: selection}}
		ast.Walk(v, astFile)
		context = v.context
	}
	if context.posParent != context.endParent {
		panic(fmt.Sprintf("Selection is not valid. posParent: %v; endParent: %v",
			context.posParent, context.endParent))
	}
	if context.posParent == nil {
		panic(fmt.Sprintf("Selection is not valid. posParent: %v; endParent: %v",
			context.posParent, context.endParent))
	}
	if len(context.nodesToExtract) == 1 {
		extractExpression(astFile, fileSet, context, extractedFuncName)
	} else {
		extractMultipleStatements(astFile, fileSet, context, extractedFuncName)
	}

}

type varListerVisitor struct {
	fileSet *token.FileSet
	vars    map[string]string
}

func (visitor *varListerVisitor) Visit(node ast.Node) (w ast.Visitor) {
	if typedNode, ok := node.(*ast.Ident); ok &&
		typedNode.Obj != nil && typedNode.Obj.Kind == ast.Var {
		var typeString string
		switch typedDecl := typedNode.Obj.Decl.(type) {
		case *ast.AssignStmt:
			for i, lhs := range typedDecl.Lhs {
				if lhs.(*ast.Ident).Name == typedNode.Name {
					typeString = deduceReturnTypeString(typedDecl.Rhs[i].(ast.Expr))
				}
			}
		default:
			typeString = "UnresolvedType"
		}
		visitor.vars[typedNode.Name] = typeString
	}
	return visitor
}

func listAllUsedIdentifiersThatAreVars(nodes []ast.Node, fileSet *token.FileSet) map[string]string {
	result := make(map[string]string)
	for _, node := range nodes {
		v := &varListerVisitor{fileSet: fileSet, vars: make(map[string]string)}
		ast.Walk(v, node)
		mapStringStringAddAll(result, v.vars)
	}
	return result
}

func mapStringStringAddAll(dst, src map[string]string) {
	for k, v := range src {
		dst[k] = v
	}
}

func extractExpression(
	astFile *ast.File,
	fileSet *token.FileSet,
	context *visitorContext,
	extractedFuncName string) {

	// TODO: Ideally this would only list variables that are not available
	// outside of the scope where the expressions lives
	params := listAllUsedIdentifiersThatAreVars(context.nodesToExtract, fileSet)
	var stmts []ast.Stmt

	switch typedNode := context.posParent.(type) {
	case *ast.AssignStmt:
		for i, rhs := range typedNode.Rhs {
			if rhs == context.nodesToExtract[0] {
				typedNode.Rhs[i] = extractExprFrom(extractedFuncName, params)
			}
		}
	case *ast.CallExpr:
		for i, arg := range typedNode.Args {
			if arg == context.nodesToExtract[0] {
				typedNode.Args[i] = extractExprFrom(extractedFuncName, params)
			}
		}
	case *ast.ExprStmt:
		typedNode.X = extractExprFrom(extractedFuncName, params)

	// TODO:
	// Add more cases here

	default:
		panic(fmt.Sprintf("Type %v not supported yet", reflect.TypeOf(context.posParent)))
	}
	insertExtractedFuncInto(
		astFile,
		fileSet,
		extractedFuncName,
		argsAndTypesFrom(params),
		stmts,
		context.nodesToExtract[0].(ast.Expr))
}

func extractMultipleStatements(
	astFile *ast.File,
	fileSet *token.FileSet,
	context *visitorContext,
	extractedFuncName string) {
	params := listAllUsedIdentifiersThatAreVars(context.nodesToExtract, fileSet)
	var stmts []ast.Stmt

	switch typedNode := context.posParent.(type) {
	case *ast.BlockStmt:
		extractedExpressionNodes := astNodeSetFrom(context.nodesToExtract)
		replaced := false
		for i, stmt := range typedNode.List {
			if extractedExpressionNodes[stmt] {
				stmts = append(stmts, stmt)
				if !replaced {
					typedNode.List[i] = &ast.ExprStmt{X: extractExprFrom(extractedFuncName, params)}
					replaced = true
				} else {
					typedNode.List = append(typedNode.List[:i], typedNode.List[i+1:]...)
				}
			}
		}
	// TODO: Add cases for CommClause and CaseClause here

	default:
		panic(fmt.Sprintf("Type %v not supported yet", reflect.TypeOf(context.posParent)))
	}

	insertExtractedFuncInto(
		astFile,
		fileSet,
		extractedFuncName,
		argsAndTypesFrom(params),
		stmts,
		nil,
	)
}

func astNodeSetFrom(nodes []ast.Node) map[ast.Node]bool {
	result := make(map[ast.Node]bool)
	for _, node := range nodes {
		result[node] = true
	}
	return result
}

func extractExprFrom(extractedFuncName string, params map[string]string) *ast.CallExpr {
	return &ast.CallExpr{
		Fun:  ast.NewIdent(extractedFuncName),
		Args: argsFrom(params),
	}
}

func argsFrom(params map[string]string) (result []ast.Expr) {
	for key := range params {
		result = append(result, ast.NewIdent(key))
	}
	return
}

func argsAndTypesFrom(params map[string]string) (result []*ast.Field) {
	for key, val := range params {
		result = append(result, &ast.Field{
			Names: []*ast.Ident{ast.NewIdent(key)},
			Type:  ast.NewIdent(val),
		})
	}
	return
}

func insertExtractedFuncInto(
	astFile *ast.File,
	fileSet *token.FileSet,
	extractedFuncName string,
	argsAndTypes []*ast.Field,
	stmts []ast.Stmt,
	returnExpr ast.Expr) {

	allStmts := make([]ast.Stmt, len(stmts), len(stmts)+1)
	copy(allStmts, stmts)
	var returnType *ast.FieldList
	if returnExpr != nil {
		returnTypeString := deduceReturnTypeString(returnExpr)
		if returnTypeString == "" {
			allStmts = append(allStmts, &ast.ExprStmt{X: returnExpr})
		} else {
			allStmts = append(allStmts, &ast.ReturnStmt{Results: []ast.Expr{returnExpr}})
		}
		returnType = &ast.FieldList{List: []*ast.Field{
			&ast.Field{Type: ast.NewIdent(returnTypeString)},
		}}
	}
	astFile.Decls = append(astFile.Decls, &ast.FuncDecl{
		Name: ast.NewIdent(extractedFuncName),
		Type: &ast.FuncType{
			Params:  &ast.FieldList{List: argsAndTypes},
			Results: returnType,
		},
		Body: &ast.BlockStmt{List: allStmts},
	})
}

func deduceReturnTypeString(expr ast.Expr) string {
	switch typedExpr := expr.(type) {
	case *ast.BasicLit:
		return strings.ToLower(typedExpr.Kind.String())
	case *ast.CallExpr:
		if typedExpr.Fun.(*ast.Ident).Obj.Decl.(*ast.FuncDecl).Type.Results == nil {
			return ""
		}
		result := ""
		for _, res := range typedExpr.Fun.(*ast.Ident).Obj.Decl.(*ast.FuncDecl).Type.Results.List {
			result += " " + res.Type.(*ast.Ident).Name
		}
		return result
	default:
		return "TODO"
	}
}
<|endoftext|>


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

import (
	"os"

	commands "github.com/fabric8io/gofabric8/cmds"
	"github.com/fabric8io/gofabric8/util"
	"github.com/jimmidyson/minishift/pkg/minikube/update"
	"github.com/kubernetes/minikube/pkg/minikube/config"
	"github.com/spf13/cobra"
	"github.com/spf13/viper"
	cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
)

const (
	batchFlag = "batch"

	githubOrg  = "fabric8io"
	githubRepo = "gofabric8"
	binaryName = githubRepo
)

func runHelp(cmd *cobra.Command, args []string) {
	cmd.Help()
}

func main() {
	cmds := &cobra.Command{
		Use:   "gofabric8",
		Short: "gofabric8 is used to validate & deploy fabric8 components on to your Kubernetes or OpenShift environment",
		Long: `gofabric8 is used to validate & deploy fabric8 components on to your Kubernetes or OpenShift environment
								Find more information at http://fabric8.io.`,
		Run: runHelp,
	}

	cmds.PersistentFlags().String("fabric8-version", "latest", "fabric8 version")
	cmds.PersistentFlags().BoolP("yes", "y", false, "assume yes")
	cmds.PersistentFlags().BoolP(batchFlag, "b", false, "Run in batch mode to avoid prompts")

	f := cmdutil.NewFactory(nil)
	f.BindFlags(cmds.PersistentFlags())

	oldHandler := cmds.PersistentPreRun
	cmds.PersistentPreRun = func(cmd *cobra.Command, args []string) {
		flag := cmds.Flags().Lookup(batchFlag)
		batch := false
		if flag != nil {
			batch = flag.Value.String() == "true"
		}

		if !batch {
			viper.SetDefault(config.WantUpdateNotification, true)
			update.MaybeUpdate(os.Stdout, githubOrg, githubRepo, binaryName, "")

		}
		if oldHandler != nil {
			oldHandler(cmd, args)
		}
	}

	cmds.AddCommand(commands.NewCmdValidate(f))
	cmds.AddCommand(commands.NewCmdDeploy(f))
	cmds.AddCommand(commands.NewCmdRun(f))
	cmds.AddCommand(commands.NewCmdPull(f))
	cmds.AddCommand(commands.NewCmdIngress(f))
	cmds.AddCommand(commands.NewCmdRoutes(f))
	cmds.AddCommand(commands.NewCmdSecrets(f))
	cmds.AddCommand(commands.NewCmdService(f))
	cmds.AddCommand(commands.NewCmdVolumes(f))
	cmds.AddCommand(commands.NewCmdVersion())

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

import (
	"os"

	commands "github.com/fabric8io/gofabric8/cmds"
	"github.com/jimmidyson/minishift/pkg/minikube/update"
	"github.com/kubernetes/minikube/pkg/minikube/config"
	"github.com/spf13/cobra"
	"github.com/spf13/viper"
	cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
)

const (
	batchFlag = "batch"

	githubOrg  = "fabric8io"
	githubRepo = "gofabric8"
	binaryName = githubRepo
)

func runHelp(cmd *cobra.Command, args []string) {
	cmd.Help()
}

func main() {
	cmds := &cobra.Command{
		Use:   "gofabric8",
		Short: "gofabric8 is used to validate & deploy fabric8 components on to your Kubernetes or OpenShift environment",
		Long: `gofabric8 is used to validate & deploy fabric8 components on to your Kubernetes or OpenShift environment
								Find more information at http://fabric8.io.`,
		Run: runHelp,
	}

	cmds.PersistentFlags().String("fabric8-version", "latest", "fabric8 version")
	cmds.PersistentFlags().BoolP("yes", "y", false, "assume yes")
	cmds.PersistentFlags().BoolP(batchFlag, "b", false, "Run in batch mode to avoid prompts")

	f := cmdutil.NewFactory(nil)
	f.BindFlags(cmds.PersistentFlags())

	oldHandler := cmds.PersistentPreRun
	cmds.PersistentPreRun = func(cmd *cobra.Command, args []string) {
		flag := cmds.Flags().Lookup(batchFlag)
		batch := false
		if flag != nil {
			batch = flag.Value.String() == "true"
		}

		if !batch {
			viper.SetDefault(config.WantUpdateNotification, true)
			update.MaybeUpdate(os.Stdout, githubOrg, githubRepo, binaryName, "")

		}
		if oldHandler != nil {
			oldHandler(cmd, args)
		}
	}

	cmds.AddCommand(commands.NewCmdValidate(f))
	cmds.AddCommand(commands.NewCmdDeploy(f))
	cmds.AddCommand(commands.NewCmdRun(f))
	cmds.AddCommand(commands.NewCmdPull(f))
	cmds.AddCommand(commands.NewCmdIngress(f))
	cmds.AddCommand(commands.NewCmdRoutes(f))
	cmds.AddCommand(commands.NewCmdSecrets(f))
	cmds.AddCommand(commands.NewCmdService(f))
	cmds.AddCommand(commands.NewCmdVolumes(f))
	cmds.AddCommand(commands.NewCmdVersion())

	cmds.Execute()
}
<|endoftext|>


<commit_before>package main

import (
	"../libgolb"
	"github.com/docopt/docopt-go"
	"github.com/gorilla/mux"
	"io"
	"net/http"
	"os"
	"strconv"
	"strings"
)

func getServer() (server string) {
	server = libgolb.Conf.BackServers[libgolb.RoundRobin]
	libgolb.RoundRobin++
	if libgolb.RoundRobin >= libgolb.NumberBack {
		libgolb.RoundRobin = 0
	}
	return
}

func golbGet(w http.ResponseWriter, req *http.Request) {
	var secondResp *http.Response
	var errsp error

	defer secondResp.Body.Close()
	serv := strings.Split(req.RemoteAddr, ":") // extract just IP without port
	libgolb.Log("misc", "Access From :"+serv[0])
	server, errGS := libgolb.RadixGetString(libgolb.LBClient, serv[0])
	if errGS != nil {
		server = getServer()
	}
	limit := 0
	for limit < libgolb.NumberBack {
		resp, _ := http.NewRequest(req.Method, "http://"+server+req.RequestURI, nil)
		for k, v := range req.Header {
			resp.Header[k] = v
		}
		resp.Header.Set("X-Forwarded-For", req.RemoteAddr)
		secondResp, errsp = http.DefaultClient.Do(resp)
		if errsp != nil {
			libgolb.Log("error", "Connection with the HTTP file server failed: "+errsp.Error())
			server = getServer()
			limit++
		} else {
			break
		}
	}
	if limit >= libgolb.NumberBack {
		libgolb.HttpResponse(w, 500, "Internal server error\n")
		libgolb.Log("error", "No Backend Server avalaible")
		return
	}
	for k, v := range secondResp.Header {
		w.Header().Add(k, strings.Join(v, ""))
	}
	w.Header().Set("Status", "200")
	io.Copy(w, secondResp.Body)
	libgolb.RadixSet(libgolb.LBClient, serv[0], server)
	libgolb.Log("ok", "Answer From :"+serv[0])
	//TTL
	libgolb.RadixExpire(libgolb.LBClient, serv[0], strconv.Itoa(libgolb.Conf.TTL))
	libgolb.LogW3C(w, req, false)
}

func parseArgument(configuration string) {

	// Load configuration
	libgolb.ConfLoad(configuration)
	// Check Redis connection
	redis := libgolb.ConnectToRedis()
	if redis != nil {
		libgolb.Log("error", "Redis connection failed")
		os.Exit(1)
	}

	// Router
	rtr := mux.NewRouter()
	rtr.HandleFunc("/", golbGet).Methods("GET")
	http.Handle("/", rtr)

	// Listening
	libgolb.Log("ok", "Listening on "+libgolb.Conf.Server.Hostname+":"+libgolb.Conf.Server.Port)
	err := http.ListenAndServe(libgolb.Conf.Server.Hostname+":"+libgolb.Conf.Server.Port, nil)
	libgolb.ErrCatcher("ListenAndServe: ", err)
}

func main() {
	usage := `Golb.

Usage:
  golb <configuration>
  golb -h | --help
  golb --version

Options:
  -h --help     Show this screen.
  --version     Show version.`

	arguments, _ := docopt.Parse(usage, nil, true, "GoLB 0.1", false)
	parseArgument(arguments["<configuration>"].(string))
}
<commit_msg>Fix CLose Again !!!<commit_after>package main

import (
	"../libgolb"
	"github.com/docopt/docopt-go"
	"github.com/gorilla/mux"
	"io"
	"net/http"
	"os"
	"strconv"
	"strings"
)

func getServer() (server string) {
	server = libgolb.Conf.BackServers[libgolb.RoundRobin]
	libgolb.RoundRobin++
	if libgolb.RoundRobin >= libgolb.NumberBack {
		libgolb.RoundRobin = 0
	}
	return
}

func golbGet(w http.ResponseWriter, req *http.Request) {
	var secondResp *http.Response
	var errsp error

	serv := strings.Split(req.RemoteAddr, ":") // extract just IP without port
	libgolb.Log("misc", "Access From :"+serv[0])
	server, errGS := libgolb.RadixGetString(libgolb.LBClient, serv[0])
	if errGS != nil {
		server = getServer()
	}
	limit := 0
	for limit < libgolb.NumberBack {
		resp, _ := http.NewRequest(req.Method, "http://"+server+req.RequestURI, nil)
		for k, v := range req.Header {
			resp.Header[k] = v
		}
		resp.Header.Set("X-Forwarded-For", req.RemoteAddr)
		secondResp, errsp = http.DefaultClient.Do(resp)
		defer secondResp.Body.Close()
		if errsp != nil {
			libgolb.Log("error", "Connection with the HTTP file server failed: "+errsp.Error())
			server = getServer()
			limit++
		} else {
			break
		}
	}
	if limit >= libgolb.NumberBack {
		libgolb.HttpResponse(w, 500, "Internal server error\n")
		libgolb.Log("error", "No Backend Server avalaible")
		return
	}
	for k, v := range secondResp.Header {
		w.Header().Add(k, strings.Join(v, ""))
	}
	w.Header().Set("Status", "200")
	io.Copy(w, secondResp.Body)
	libgolb.RadixSet(libgolb.LBClient, serv[0], server)
	libgolb.Log("ok", "Answer From :"+serv[0])
	//TTL
	libgolb.RadixExpire(libgolb.LBClient, serv[0], strconv.Itoa(libgolb.Conf.TTL))
	libgolb.LogW3C(w, req, false)
}

func parseArgument(configuration string) {

	// Load configuration
	libgolb.ConfLoad(configuration)
	// Check Redis connection
	redis := libgolb.ConnectToRedis()
	if redis != nil {
		libgolb.Log("error", "Redis connection failed")
		os.Exit(1)
	}

	// Router
	rtr := mux.NewRouter()
	rtr.HandleFunc("/", golbGet).Methods("GET")
	http.Handle("/", rtr)

	// Listening
	libgolb.Log("ok", "Listening on "+libgolb.Conf.Server.Hostname+":"+libgolb.Conf.Server.Port)
	err := http.ListenAndServe(libgolb.Conf.Server.Hostname+":"+libgolb.Conf.Server.Port, nil)
	libgolb.ErrCatcher("ListenAndServe: ", err)
}

func main() {
	usage := `Golb.

Usage:
  golb <configuration>
  golb -h | --help
  golb --version

Options:
  -h --help     Show this screen.
  --version     Show version.`

	arguments, _ := docopt.Parse(usage, nil, true, "GoLB 0.1", false)
	parseArgument(arguments["<configuration>"].(string))
}
<|endoftext|>


<commit_before>package navitia

import (
	"flag"
)

const skipNoKey string = "No api key supplied, skipping (provide one using -key flag)"

var (
	apiKey      = flag.String("key", "", "API Key to use for testing")
	testSession *Session
)

// Initialise testing function
func init() {
	// Populate flags
	flag.Parse()

	// Create session
	if *apiKey != "" {
		var err error
		testSession, err = New(*apiKey)
		if err != nil {
			panic(err)
		}
	}
}
<commit_msg>Change the test session to use http instead of https for easier debugging.<commit_after>package navitia

import (
	"flag"
	"net/http"
)

const skipNoKey string = "No api key supplied, skipping (provide one using -key flag)"

var (
	apiKey      = flag.String("key", "", "API Key to use for testing")
	testSession *Session
)

// Initialise testing function
func init() {
	// Populate flags
	flag.Parse()

	// Create session
	if *apiKey != "" {
		var err error
		testSession, err = NewCustom(*apiKey, "http://api.navitia.io/v1", http.DefaultClient)
		if err != nil {
			panic(err)
		}
	}
}
<|endoftext|>


<commit_before><commit_msg>insertion: insertion sorting algoritm is added<commit_after>package sorter

func InsertionSort(arr []int) []int {
	var key int
	var j int
	var resultArr []int

	for i := 1; i < len(arr); i++ {
		key = arr[i]
		j = i - 1
		for j >= 0 && arr[j] > key {
			arr[j+1] = arr[j]
			j--
			arr[j+1] = key
		}
	}

	resultArr = arr
	return resultArr
}
<|endoftext|>


<commit_before>package gitignore

import (
	"bufio"
	"io"
	"os"
	"path/filepath"
	"strings"
)

type IgnoreMatcher interface {
	Match(path string, isDir bool) bool
}

type DummyIgnoreMatcher bool

func (d DummyIgnoreMatcher) Match(path string, isDir bool) bool {
	return bool(d)
}

type gitIgnore struct {
	ignorePatterns scanStrategy
	acceptPatterns scanStrategy
	path           string
}

func NewGitIgnore(gitignore string, base ...string) (IgnoreMatcher, error) {
	var path string
	if len(base) > 0 {
		path = base[0]
	} else {
		path = filepath.Dir(gitignore)
	}

	file, err := os.Open(gitignore)
	if err != nil {
		return DummyIgnoreMatcher(false), err
	}
	defer file.Close()

	return NewGitIgnoreFromReader(path, file), nil
}

func NewGitIgnoreFromReader(path string, r io.Reader) gitIgnore {
	g := gitIgnore{
		ignorePatterns: newIndexScanPatterns(),
		acceptPatterns: newIndexScanPatterns(),
		path:           path,
	}
	scanner := bufio.NewScanner(r)
	for scanner.Scan() {
		line := strings.Trim(scanner.Text(), " ")
		if len(line) == 0 || strings.HasPrefix(line, "#") {
			continue
		}
		if strings.HasPrefix(line, `\#`) {
			line = strings.TrimPrefix(line, `\`)
		}

		if strings.HasPrefix(line, "!") {
			g.acceptPatterns.add(strings.TrimPrefix(line, "!"))
		} else {
			g.ignorePatterns.add(line)
		}
	}
	return g
}

func (g gitIgnore) Match(path string, isDir bool) bool {
	relativePath, err := filepath.Rel(g.path, path)
	if err != nil {
		return false
	}

	if g.acceptPatterns.match(relativePath, isDir) {
		return false
	}
	return g.ignorePatterns.match(relativePath, isDir)
}
<commit_msg>add laod file failover ignore all<commit_after>package gitignore

import (
	"bufio"
	"io"
	"os"
	"path/filepath"
	"strings"
)

type IgnoreMatcher interface {
	Match(path string, isDir bool) bool
}

type DummyIgnoreMatcher bool

func (d DummyIgnoreMatcher) Match(path string, isDir bool) bool {
	return bool(d)
}

type gitIgnore struct {
	ignorePatterns scanStrategy
	acceptPatterns scanStrategy
	path           string
}

func NewGitIgnore(gitignore string, base ...string) (IgnoreMatcher, error) {
	var path string
	if len(base) > 0 {
		path = base[0]
	} else {
		path = filepath.Dir(gitignore)
	}

	file, err := os.Open(gitignore)
	if err != nil {
		return DummyIgnoreMatcher(true), err
	}
	defer file.Close()

	return NewGitIgnoreFromReader(path, file), nil
}

func NewGitIgnoreFromReader(path string, r io.Reader) gitIgnore {
	g := gitIgnore{
		ignorePatterns: newIndexScanPatterns(),
		acceptPatterns: newIndexScanPatterns(),
		path:           path,
	}
	scanner := bufio.NewScanner(r)
	for scanner.Scan() {
		line := strings.Trim(scanner.Text(), " ")
		if len(line) == 0 || strings.HasPrefix(line, "#") {
			continue
		}
		if strings.HasPrefix(line, `\#`) {
			line = strings.TrimPrefix(line, `\`)
		}

		if strings.HasPrefix(line, "!") {
			g.acceptPatterns.add(strings.TrimPrefix(line, "!"))
		} else {
			g.ignorePatterns.add(line)
		}
	}
	return g
}

func (g gitIgnore) Match(path string, isDir bool) bool {
	relativePath, err := filepath.Rel(g.path, path)
	if err != nil {
		return false
	}

	if g.acceptPatterns.match(relativePath, isDir) {
		return false
	}
	return g.ignorePatterns.match(relativePath, isDir)
}
<|endoftext|>


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

package gl

// #include <GLES3/gl3.h>
// #include <stdlib.h>
import "C"
import (
	"fmt"
	"unsafe"
)

type Shader C.GLuint
type ShaderType C.GLenum
type ShaderBinaryFormat C.GLint

const (
	VERTEX_SHADER   ShaderType = C.GL_VERTEX_SHADER
	FRAGMENT_SHADER            = C.GL_FRAGMENT_SHADER
)

type Program struct {
	id C.GLuint

	shadersValid bool
	shaders      []Shader

	Uniforms   map[string]Uniform
	Attributes map[string]VertexAttrib
}

func CreateProgram() Program {
	return Program{id: C.glCreateProgram()}
}

func CreateShader(stype ShaderType) Shader {
	return Shader(C.glCreateShader(C.GLenum(stype)))
}

func (program *Program) Shaders() []Shader {
	if !program.shadersValid {
		nshaders := C.GLint(0)
		C.glGetProgramiv(program.id, C.GL_ATTACHED_SHADERS, &nshaders)
		program.shaders = make([]Shader, nshaders)
		C.glGetAttachedShaders(program.id, C.GLsizei(nshaders), nil, (*C.GLuint)(&program.shaders[0]))
		program.shadersValid = true
	}
	return program.shaders
}

func (program *Program) AttachShader(shader Shader) {
	C.glAttachShader(program.id, C.GLuint(shader))
	program.shadersValid = false
}

func (program *Program) BindAttribLocation(attrib VertexAttrib, name string) {

	cstr := C.CString(name)
	defer C.free(unsafe.Pointer(cstr))

	C.glBindAttribLocation(program.id, attrib.Index(), (*C.GLchar)(cstr))
}

func (program *Program) Delete() {
	C.glDeleteProgram(program.id)
}

func (shader Shader) Delete() {
	C.glDeleteShader(C.GLuint(shader))
}

func (program *Program) DetachShader(shader Shader) {
	C.glDetachShader(program.id, C.GLuint(shader))
	program.shadersValid = false
}

// func (program *Program) GetActiveAttrib(index uint) (size int, atype int, name string) {

// 	nameBuf := make([]byte, MAX_ATTRIBUTE_LENGTH)
// 	sizeBuf := C.GLint(0)
// 	typeBuf := C.GLenum(0)

// 	C.glGetActiveAttrib(program.id, C.GLuint(index), C.GLsizei(len(nameBuf)), C.NULL, &sizeBuf, &typeBuf, (*C.GLchar)(&nameBuf[0]))

// 	size = int(sizeBuf)
// 	atype = int(typeBuf)
// 	name = string(nameBuf)
// }

// func (program *Program) GetActiveUniform(index uint) (size int, utype int, name string) {

// 	nameBuf := make([]byte, MAX_UNIFORM_LENGTH)
// 	sizeBuf := C.GLint(0)
// 	typeBuf := C.GLenum(0)

// 	C.glGetActiveUniform(program.id, C.GLuint(index), C.GLsizei(len(nameBuf)), C.NULL, &sizeBuf, &typeBuf, (*C.GLchar)(&nameBuf[0]))

// 	size = int(sizeBuf)
// 	utype = int(typeBuf)
// 	name = string(nameBuf)
// }

// func (program *Program) GetAttachedShaders(GLsizei maxcount, GLsizei* count) []uint {
// 	C.glGetAttachedShaders(program.id, GLsizei maxcount, GLsizei* count, GLuint* shaders)
// }

// func (program *Program) GetProgramiv(pname int,  params int) {
// 	C.glGetProgramiv(program.id, GLenum pname, GLint* params)
// }

// func (program *Program) InfoLog(GLsizei bufsize, GLsizei* length, GLchar* infolog) {
// 	C.glGetProgramInfoLog(program.id, GLsizei bufsize, GLsizei* length, GLchar* infolog)
// }

// func GetShaderiv(shader Shader, pname int, params int) {
// 	C.glGetShaderiv(C.GLuint(shader), GLenum pname, GLint* params)
// }

// func GetShaderInfoLog(shader Shader, GLsizei bufsize, GLsizei* length, GLchar* infolog) {
// 	C.glGetShaderInfoLog(C.GLuint(shader), GLsizei bufsize, GLsizei* length, GLchar* infolog)
// }

// func GetShaderPrecisionFormat(shadertype ShaderType, precisiontype int, GLint* range,  precision int) {
// 	C.glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
// }

// func GetShaderSource(shader Shader, GLsizei bufsize, GLsizei* length, GLchar* source) {
// 	C.glGetShaderSource(C.GLuint(shader), GLsizei bufsize, GLsizei* length, GLchar* source)
// }

// func (program *Program) GetUniformfv(location int, GLfloat* params) {
// 	C.glGetUniformfv(program.id, GLint location, GLfloat* params)
// }

// func (program *Program) GetUniformiv(GLint location,  params int) {
// 	C.glGetUniformiv(program.id, GLint location, GLint* params)
// }

// GL_APICALL int          GL_APIENTRY glGetAttribLocation (GLuint program, const GLchar* name);
// GL_APICALL int          GL_APIENTRY glGetUniformLocation (GLuint program, const GLchar* name);

// func ShaderBinary(GLsizei n, shaders []uint, binaryformat int, const GLvoid* binary, GLsizei length) {
// 	C.glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length)
// }

func GetShaderBinaryFormats() (formats []ShaderBinaryFormat) {
	numFormats := C.GLint(0)
	C.glGetIntegerv(C.GL_NUM_SHADER_BINARY_FORMATS, &numFormats)
	if numFormats > 0 {
		formats = make([]ShaderBinaryFormat, numFormats)
		C.glGetIntegerv(C.GL_SHADER_BINARY_FORMATS, (*C.GLint)(&formats[0]))
	}
	return
}

func ShaderBinary(shaders []Shader, format ShaderBinaryFormat, binary []byte) {
	C.glShaderBinary(C.GLsizei(len(shaders)), (*C.GLuint)(&shaders[0]), C.GLenum(format), unsafe.Pointer(&binary[0]), C.GLsizei(len(binary)))
}

func (shader Shader) Source(src string) {
	cstr := (*C.GLchar)(C.CString(src))
	defer C.free(unsafe.Pointer(cstr))
	slen := C.GLint(len(src))
	C.glShaderSource(C.GLuint(shader), 1, &cstr, &slen)
}

func (shader Shader) Compile() {
	C.glCompileShader(C.GLuint(shader))

	status := C.GLint(0)
	C.glGetShaderiv(C.GLuint(shader), C.GL_COMPILE_STATUS, &status)

	if status != C.GL_TRUE {
		loglen := C.GLint(0)
		C.glGetShaderiv(C.GLuint(shader), C.GL_INFO_LOG_LENGTH, &loglen)
		log := (*C.GLchar)(C.malloc(C.size_t(loglen)))
		defer C.free(unsafe.Pointer(log))
		C.glGetShaderInfoLog(C.GLuint(shader), C.GLsizei(loglen), nil, log)
		panic(fmt.Errorf("Failed to compile shader: %s", C.GoString((*C.char)(log))))
	}
}

func setupProgramAttributes(program *Program) {
	nattribs := C.GLint(0)
	C.glGetProgramiv(program.id, C.GL_ACTIVE_ATTRIBUTES, &nattribs)
	maxattriblen := C.GLint(0)
	C.glGetProgramiv(program.id, C.GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &maxattriblen)
	program.Attributes = make(map[string]VertexAttrib, nattribs)

	for i := 0; i < int(nattribs); i++ {
		name := make([]C.char, maxattriblen)
		namelen := C.GLsizei(0)
		datatype := C.GLenum(0)
		C.glGetActiveAttrib(program.id, C.GLuint(i), C.GLsizei(len(name)), &namelen, nil, &datatype, (*C.GLchar)(&name[0]))

		switch datatype {
		case C.GL_FLOAT:
			program.Attributes[C.GoString(&name[0])] = FloatAttrib{Attrib{C.GLuint(i)}}
		case C.GL_FLOAT_VEC2:
			program.Attributes[C.GoString(&name[0])] = Vec2Attrib{FloatAttrib{Attrib{C.GLuint(i)}}}
		case C.GL_FLOAT_VEC3:
			program.Attributes[C.GoString(&name[0])] = Vec3Attrib{FloatAttrib{Attrib{C.GLuint(i)}}}
		case C.GL_FLOAT_VEC4:
			program.Attributes[C.GoString(&name[0])] = Vec4Attrib{FloatAttrib{Attrib{C.GLuint(i)}}}
		}
	}
}

func setupProgramUniforms(program *Program) {
	nuniforms := C.GLint(0)
	C.glGetProgramiv(program.id, C.GL_ACTIVE_UNIFORMS, &nuniforms)
	maxuniformlen := C.GLint(0)
	C.glGetProgramiv(program.id, C.GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxuniformlen)
	program.Uniforms = make(map[string]Uniform, nuniforms)

	for i := 0; i < int(nuniforms); i++ {
		name := make([]C.char, maxuniformlen)
		namelen := C.GLsizei(0)
		datatype := C.GLenum(0)
		size := C.GLint(0)
		C.glGetActiveUniform(program.id, C.GLuint(i), C.GLsizei(len(name)), &namelen, &size, &datatype, (*C.GLchar)(&name[0]))

		switch datatype {
		case C.GL_FLOAT:
			program.Uniforms[C.GoString(&name[0])] = Uniform1f{uniformBase{C.GLint(i)}}
		case C.GL_FLOAT_VEC2:
			program.Uniforms[C.GoString(&name[0])] = Uniform2f{uniformBase{C.GLint(i)}}
		case C.GL_FLOAT_VEC3:
			program.Uniforms[C.GoString(&name[0])] = Uniform3f{uniformBase{C.GLint(i)}}
		case C.GL_FLOAT_VEC4:
			program.Uniforms[C.GoString(&name[0])] = Uniform4f{uniformBase{C.GLint(i)}}
		case C.GL_INT:
			program.Uniforms[C.GoString(&name[0])] = Uniform1i{uniformBase{C.GLint(i)}}
		case C.GL_INT_VEC2:
			program.Uniforms[C.GoString(&name[0])] = Uniform2i{uniformBase{C.GLint(i)}}
		case C.GL_INT_VEC3:
			program.Uniforms[C.GoString(&name[0])] = Uniform3i{uniformBase{C.GLint(i)}}
		case C.GL_INT_VEC4:
			program.Uniforms[C.GoString(&name[0])] = Uniform4i{uniformBase{C.GLint(i)}}
		case C.GL_BOOL:
			program.Uniforms[C.GoString(&name[0])] = Uniform1i{uniformBase{C.GLint(i)}}
		case C.GL_BOOL_VEC2:
			program.Uniforms[C.GoString(&name[0])] = Uniform2i{uniformBase{C.GLint(i)}}
		case C.GL_BOOL_VEC3:
			program.Uniforms[C.GoString(&name[0])] = Uniform3i{uniformBase{C.GLint(i)}}
		case C.GL_BOOL_VEC4:
			program.Uniforms[C.GoString(&name[0])] = Uniform4i{uniformBase{C.GLint(i)}}
		case C.GL_FLOAT_MAT2:
			program.Uniforms[C.GoString(&name[0])] = UniformMatrix2f{uniformBase{C.GLint(i)}}
		case C.GL_FLOAT_MAT3:
			program.Uniforms[C.GoString(&name[0])] = UniformMatrix3f{uniformBase{C.GLint(i)}}
		case C.GL_FLOAT_MAT4:
			program.Uniforms[C.GoString(&name[0])] = UniformMatrix4f{uniformBase{C.GLint(i)}}
		case C.GL_SAMPLER_2D:
			program.Uniforms[C.GoString(&name[0])] = Uniform1i{uniformBase{C.GLint(i)}}
		case C.GL_SAMPLER_CUBE:
			program.Uniforms[C.GoString(&name[0])] = Uniform1i{uniformBase{C.GLint(i)}}
		}
	}
}

func (program *Program) Link() {
	C.glLinkProgram(program.id)

	status := C.GLint(0)
	C.glGetProgramiv(program.id, C.GL_LINK_STATUS, &status)

	if status != C.GL_TRUE {
		loglen := C.GLint(0)
		C.glGetProgramiv(program.id, C.GL_INFO_LOG_LENGTH, &loglen)
		log := (*C.GLchar)(C.malloc(C.size_t(loglen)))
		defer C.free(unsafe.Pointer(log))
		C.glGetProgramInfoLog(program.id, C.GLsizei(loglen), nil, log)
		panic(fmt.Errorf("Failed to link shader: %s", C.GoString((*C.char)(log))))
	} else {
		setupProgramAttributes(program)
		setupProgramUniforms(program)
	}
}

func (program *Program) Use() {
	C.glUseProgram(program.id)
}

func (program *Program) Validate() {
	C.glValidateProgram(program.id)
}

func ReleaseShaderCompiler() {
	C.glReleaseShaderCompiler()
}

func (t ShaderType) String() string {
	switch t {
	case VERTEX_SHADER:
		return "VERTEX_SHADER"
	case FRAGMENT_SHADER:
		return "FRAGMENT_SHADER"
	default:
		return fmt.Sprintf("ShaderType(%#x)", t)
	}
}
<commit_msg>remove program maps for uniforms and attributes<commit_after>// Copyright 2014 Mathias Fiedler
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package gl

// #include <GLES3/gl3.h>
// #include <stdlib.h>
import "C"
import (
	"fmt"
	"unsafe"
)

type Shader C.GLuint
type ShaderType C.GLenum
type ShaderBinaryFormat C.GLint

const (
	VERTEX_SHADER   ShaderType = C.GL_VERTEX_SHADER
	FRAGMENT_SHADER            = C.GL_FRAGMENT_SHADER
)

type Program struct {
	id C.GLuint

	shadersValid bool
	shaders      []Shader
}

func CreateProgram() Program {
	return Program{id: C.glCreateProgram()}
}

func CreateShader(stype ShaderType) Shader {
	return Shader(C.glCreateShader(C.GLenum(stype)))
}

func (program *Program) Shaders() []Shader {
	if !program.shadersValid {
		nshaders := C.GLint(0)
		C.glGetProgramiv(program.id, C.GL_ATTACHED_SHADERS, &nshaders)
		program.shaders = make([]Shader, nshaders)
		C.glGetAttachedShaders(program.id, C.GLsizei(nshaders), nil, (*C.GLuint)(&program.shaders[0]))
		program.shadersValid = true
	}
	return program.shaders
}

func (program *Program) AttachShader(shader Shader) {
	C.glAttachShader(program.id, C.GLuint(shader))
	program.shadersValid = false
}

func (program *Program) BindAttribLocation(attrib VertexAttrib, name string) {

	cstr := C.CString(name)
	defer C.free(unsafe.Pointer(cstr))

	C.glBindAttribLocation(program.id, attrib.Index(), (*C.GLchar)(cstr))
}

func (program *Program) Delete() {
	C.glDeleteProgram(program.id)
}

func (shader Shader) Delete() {
	C.glDeleteShader(C.GLuint(shader))
}

func (program *Program) DetachShader(shader Shader) {
	C.glDetachShader(program.id, C.GLuint(shader))
	program.shadersValid = false
}

// func (program *Program) GetActiveAttrib(index uint) (size int, atype int, name string) {

// 	nameBuf := make([]byte, MAX_ATTRIBUTE_LENGTH)
// 	sizeBuf := C.GLint(0)
// 	typeBuf := C.GLenum(0)

// 	C.glGetActiveAttrib(program.id, C.GLuint(index), C.GLsizei(len(nameBuf)), C.NULL, &sizeBuf, &typeBuf, (*C.GLchar)(&nameBuf[0]))

// 	size = int(sizeBuf)
// 	atype = int(typeBuf)
// 	name = string(nameBuf)
// }

// func (program *Program) GetActiveUniform(index uint) (size int, utype int, name string) {

// 	nameBuf := make([]byte, MAX_UNIFORM_LENGTH)
// 	sizeBuf := C.GLint(0)
// 	typeBuf := C.GLenum(0)

// 	C.glGetActiveUniform(program.id, C.GLuint(index), C.GLsizei(len(nameBuf)), C.NULL, &sizeBuf, &typeBuf, (*C.GLchar)(&nameBuf[0]))

// 	size = int(sizeBuf)
// 	utype = int(typeBuf)
// 	name = string(nameBuf)
// }

// func (program *Program) GetAttachedShaders(GLsizei maxcount, GLsizei* count) []uint {
// 	C.glGetAttachedShaders(program.id, GLsizei maxcount, GLsizei* count, GLuint* shaders)
// }

// func (program *Program) GetProgramiv(pname int,  params int) {
// 	C.glGetProgramiv(program.id, GLenum pname, GLint* params)
// }

// func (program *Program) InfoLog(GLsizei bufsize, GLsizei* length, GLchar* infolog) {
// 	C.glGetProgramInfoLog(program.id, GLsizei bufsize, GLsizei* length, GLchar* infolog)
// }

// func GetShaderiv(shader Shader, pname int, params int) {
// 	C.glGetShaderiv(C.GLuint(shader), GLenum pname, GLint* params)
// }

// func GetShaderInfoLog(shader Shader, GLsizei bufsize, GLsizei* length, GLchar* infolog) {
// 	C.glGetShaderInfoLog(C.GLuint(shader), GLsizei bufsize, GLsizei* length, GLchar* infolog)
// }

// func GetShaderPrecisionFormat(shadertype ShaderType, precisiontype int, GLint* range,  precision int) {
// 	C.glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
// }

// func GetShaderSource(shader Shader, GLsizei bufsize, GLsizei* length, GLchar* source) {
// 	C.glGetShaderSource(C.GLuint(shader), GLsizei bufsize, GLsizei* length, GLchar* source)
// }

// func (program *Program) GetUniformfv(location int, GLfloat* params) {
// 	C.glGetUniformfv(program.id, GLint location, GLfloat* params)
// }

// func (program *Program) GetUniformiv(GLint location,  params int) {
// 	C.glGetUniformiv(program.id, GLint location, GLint* params)
// }

// GL_APICALL int          GL_APIENTRY glGetAttribLocation (GLuint program, const GLchar* name);
// GL_APICALL int          GL_APIENTRY glGetUniformLocation (GLuint program, const GLchar* name);

// func ShaderBinary(GLsizei n, shaders []uint, binaryformat int, const GLvoid* binary, GLsizei length) {
// 	C.glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length)
// }

func GetShaderBinaryFormats() (formats []ShaderBinaryFormat) {
	numFormats := C.GLint(0)
	C.glGetIntegerv(C.GL_NUM_SHADER_BINARY_FORMATS, &numFormats)
	if numFormats > 0 {
		formats = make([]ShaderBinaryFormat, numFormats)
		C.glGetIntegerv(C.GL_SHADER_BINARY_FORMATS, (*C.GLint)(&formats[0]))
	}
	return
}

func ShaderBinary(shaders []Shader, format ShaderBinaryFormat, binary []byte) {
	C.glShaderBinary(C.GLsizei(len(shaders)), (*C.GLuint)(&shaders[0]), C.GLenum(format), unsafe.Pointer(&binary[0]), C.GLsizei(len(binary)))
}

func (shader Shader) Source(src string) {
	cstr := (*C.GLchar)(C.CString(src))
	defer C.free(unsafe.Pointer(cstr))
	slen := C.GLint(len(src))
	C.glShaderSource(C.GLuint(shader), 1, &cstr, &slen)
}

func (shader Shader) Compile() {
	C.glCompileShader(C.GLuint(shader))

	status := C.GLint(0)
	C.glGetShaderiv(C.GLuint(shader), C.GL_COMPILE_STATUS, &status)

	if status != C.GL_TRUE {
		loglen := C.GLint(0)
		C.glGetShaderiv(C.GLuint(shader), C.GL_INFO_LOG_LENGTH, &loglen)
		log := (*C.GLchar)(C.malloc(C.size_t(loglen)))
		defer C.free(unsafe.Pointer(log))
		C.glGetShaderInfoLog(C.GLuint(shader), C.GLsizei(loglen), nil, log)
		panic(fmt.Errorf("Failed to compile shader: %s", C.GoString((*C.char)(log))))
	}
}

func (program *Program) Link() {
	C.glLinkProgram(program.id)

	status := C.GLint(0)
	C.glGetProgramiv(program.id, C.GL_LINK_STATUS, &status)

	if status != C.GL_TRUE {
		loglen := C.GLint(0)
		C.glGetProgramiv(program.id, C.GL_INFO_LOG_LENGTH, &loglen)
		log := (*C.GLchar)(C.malloc(C.size_t(loglen)))
		defer C.free(unsafe.Pointer(log))
		C.glGetProgramInfoLog(program.id, C.GLsizei(loglen), nil, log)
		panic(fmt.Errorf("Failed to link shader: %s", C.GoString((*C.char)(log))))
	}
}

func (program *Program) Use() {
	C.glUseProgram(program.id)
}

func (program *Program) Validate() {
	C.glValidateProgram(program.id)
}

func ReleaseShaderCompiler() {
	C.glReleaseShaderCompiler()
}

func (t ShaderType) String() string {
	switch t {
	case VERTEX_SHADER:
		return "VERTEX_SHADER"
	case FRAGMENT_SHADER:
		return "FRAGMENT_SHADER"
	default:
		return fmt.Sprintf("ShaderType(%#x)", t)
	}
}
<|endoftext|>


<commit_before>package bosh

type sharedDeploymentVarsYAML struct {
	AWSYAML          AWSYAML                `yaml:",inline"`
	GCPYAML          GCPYAML                `yaml:",inline"`
	AzureYAML        AzureYAML              `yaml:",inline"`
	VSphereYAML      VSphereYAML            `yaml:",inline"`
	TerraformOutputs map[string]interface{} `yaml:",inline"`
}

type AWSYAML struct {
	AccessKeyID     string `yaml:"access_key_id,omitempty"`
	SecretAccessKey string `yaml:"secret_access_key,omitempty"`
}

type GCPYAML struct {
	Zone           string `yaml:"zone,omitempty"`
	ProjectID      string `yaml:"project_id,omitempty"`
	CredentialJSON string `yaml:"gcp_credentials_json,omitempty"`
}

type AzureYAML struct {
	SubscriptionID string `yaml:"subscription_id,omitempty"`
	TenantID       string `yaml:"tenant_id,omitempty"`
	ClientID       string `yaml:"client_id,omitempty"`
	ClientSecret   string `yaml:"client_secret,omitempty"`
}

type VSphereYAML struct {
	VCenterUser     string `yaml:"vcenter_user,omitempty"`
	VCenterPassword string `yaml:"vcenter_password,omitempty"`
}
<commit_msg>Remove old parts of deployment vars YAML struct<commit_after>package bosh

type sharedDeploymentVarsYAML struct {
	TerraformOutputs map[string]interface{} `yaml:",inline"`
}
<|endoftext|>


<commit_before>package cidrutil

import "testing"

func TestCIDRUtil_IPBelongsToCIDR(t *testing.T) {
	ip := "192.168.25.30"
	cidr := "192.168.26.30/16"

	belongs, err := IPBelongsToCIDR(ip, cidr)
	if err != nil {
		t.Fatal(err)
	}
	if !belongs {
		t.Fatalf("expected IP %q to belong to CIDR %q", ip, cidr)
	}

	ip = "192.168.25.30"
	cidr = "192.168.26.30/24"
	belongs, err = IPBelongsToCIDR(ip, cidr)
	if err != nil {
		t.Fatal(err)
	}
	if belongs {
		t.Fatalf("expected IP %q to not belong to CIDR %q", ip, cidr)
	}

	ip = "192.168.25.30.100"
	cidr = "192.168.26.30/24"
	belongs, err = IPBelongsToCIDR(ip, cidr)
	if err == nil {
		t.Fatalf("expected an error")
	}
}

func TestCIDRUtil_IPBelongsToCIDRBlocksString(t *testing.T) {
	ip := "192.168.27.29"
	cidrList := "172.169.100.200/18,192.168.0.0/16,10.10.20.20/24"

	belongs, err := IPBelongsToCIDRBlocksString(ip, cidrList, ",")
	if err != nil {
		t.Fatal(err)
	}
	if !belongs {
		t.Fatalf("expected IP %q to belong to one of the CIDRs in %q", ip, cidrList)
	}

	ip = "192.168.27.29"
	cidrList = "172.169.100.200/18,192.168.0.0.0/16,10.10.20.20/24"

	belongs, err = IPBelongsToCIDRBlocksString(ip, cidrList, ",")
	if err == nil {
		t.Fatalf("expected an error")
	}

	ip = "30.40.50.60"
	cidrList = "172.169.100.200/18,192.168.0.0/16,10.10.20.20/24"

	belongs, err = IPBelongsToCIDRBlocksString(ip, cidrList, ",")
	if err != nil {
		t.Fatal(err)
	}
	if belongs {
		t.Fatalf("expected IP %q to not belong to one of the CIDRs in %q", ip, cidrList)
	}

}

func TestCIDRUtil_IPBelongsToCIDRBlocksSlice(t *testing.T) {
	ip := "192.168.27.29"
	cidrList := []string{"172.169.100.200/18", "192.168.0.0/16", "10.10.20.20/24"}

	belongs, err := IPBelongsToCIDRBlocksSlice(ip, cidrList)
	if err != nil {
		t.Fatal(err)
	}
	if !belongs {
		t.Fatalf("expected IP %q to belong to one of the CIDRs in %q", ip, cidrList)
	}

	ip = "192.168.27.29"
	cidrList = []string{"172.169.100.200/18", "192.168.0.0.0/16", "10.10.20.20/24"}

	belongs, err = IPBelongsToCIDRBlocksSlice(ip, cidrList)
	if err == nil {
		t.Fatalf("expected an error")
	}

	ip = "30.40.50.60"
	cidrList = []string{"172.169.100.200/18", "192.168.0.0/16", "10.10.20.20/24"}

	belongs, err = IPBelongsToCIDRBlocksSlice(ip, cidrList)
	if err != nil {
		t.Fatal(err)
	}
	if belongs {
		t.Fatalf("expected IP %q to not belong to one of the CIDRs in %q", ip, cidrList)
	}
}

func TestCIDRUtil_ValidateCIDRListString(t *testing.T) {
	cidrList := "172.169.100.200/18,192.168.0.0/16,10.10.20.20/24"

	valid, err := ValidateCIDRListString(cidrList, ",")
	if err != nil {
		t.Fatal(err)
	}
	if !valid {
		t.Fatalf("expected CIDR list %q to be valid")
	}

	cidrList = "172.169.100.200,192.168.0.0/16,10.10.20.20/24"
	valid, err = ValidateCIDRListString(cidrList, ",")
	if err == nil {
		t.Fatal("expected an error")
	}

	cidrList = "172.169.100.200/18,192.168.0.0.0/16,10.10.20.20/24"
	valid, err = ValidateCIDRListString(cidrList, ",")
	if err == nil {
		t.Fatal("expected an error")
	}
}

func TestCIDRUtil_ValidateCIDRListSlice(t *testing.T) {
	cidrList := []string{"172.169.100.200/18", "192.168.0.0/16", "10.10.20.20/24"}

	valid, err := ValidateCIDRListSlice(cidrList)
	if err != nil {
		t.Fatal(err)
	}
	if !valid {
		t.Fatalf("expected CIDR list %q to be valid")
	}

	cidrList = []string{"172.169.100.200", "192.168.0.0/16", "10.10.20.20/24"}
	valid, err = ValidateCIDRListSlice(cidrList)
	if err == nil {
		t.Fatal("expected an error")
	}

	cidrList = []string{"172.169.100.200/18", "192.168.0.0.0/16", "10.10.20.20/24"}
	valid, err = ValidateCIDRListSlice(cidrList)
	if err == nil {
		t.Fatal("expected an error")
	}
}

func TestCIDRUtil_Subset(t *testing.T) {
	cidr1 := "192.168.27.29/24"
	cidr2 := "192.168.27.29/24"
	subset, err := Subset(cidr1, cidr2)
	if err != nil {
		t.Fatal(err)
	}
	if !subset {
		t.Fatalf("expected CIDR %q to be a subset of CIDR %q", cidr2, cidr1)
	}

	cidr1 = "192.168.27.29/16"
	cidr2 = "192.168.27.29/24"
	subset, err = Subset(cidr1, cidr2)
	if err != nil {
		t.Fatal(err)
	}
	if !subset {
		t.Fatalf("expected CIDR %q to be a subset of CIDR %q", cidr2, cidr1)
	}

	cidr1 = "192.168.27.29/24"
	cidr2 = "192.168.27.29/16"
	subset, err = Subset(cidr1, cidr2)
	if err != nil {
		t.Fatal(err)
	}
	if subset {
		t.Fatalf("expected CIDR %q to not be a subset of CIDR %q", cidr2, cidr1)
	}
}

func TestCIDRUtil_SubsetBlocks(t *testing.T) {
	cidrBlocks1 := []string{"192.168.27.29/16", "172.245.30.40/24", "10.20.30.40/30"}
	cidrBlocks2 := []string{"192.168.27.29/20", "172.245.30.40/25", "10.20.30.40/32"}

	subset, err := SubsetBlocks(cidrBlocks1, cidrBlocks2)
	if err != nil {
		t.Fatal(err)
	}
	if !subset {
		t.Fatalf("expected CIDR blocks %q to be a subset of CIDR blocks %q", cidrBlocks2, cidrBlocks1)
	}

	cidrBlocks1 = []string{"192.168.27.29/16", "172.245.30.40/25", "10.20.30.40/30"}
	cidrBlocks2 = []string{"192.168.27.29/20", "172.245.30.40/24", "10.20.30.40/32"}

	subset, err = SubsetBlocks(cidrBlocks1, cidrBlocks2)
	if err != nil {
		t.Fatal(err)
	}
	if subset {
		t.Fatalf("expected CIDR blocks %q to not be a subset of CIDR blocks %q", cidrBlocks2, cidrBlocks1)
	}
}
<commit_msg>Added a few checks to the CIDR Subset checking util<commit_after>package cidrutil

import "testing"

func TestCIDRUtil_IPBelongsToCIDR(t *testing.T) {
	ip := "192.168.25.30"
	cidr := "192.168.26.30/16"

	belongs, err := IPBelongsToCIDR(ip, cidr)
	if err != nil {
		t.Fatal(err)
	}
	if !belongs {
		t.Fatalf("expected IP %q to belong to CIDR %q", ip, cidr)
	}

	ip = "192.168.25.30"
	cidr = "192.168.26.30/24"
	belongs, err = IPBelongsToCIDR(ip, cidr)
	if err != nil {
		t.Fatal(err)
	}
	if belongs {
		t.Fatalf("expected IP %q to not belong to CIDR %q", ip, cidr)
	}

	ip = "192.168.25.30.100"
	cidr = "192.168.26.30/24"
	belongs, err = IPBelongsToCIDR(ip, cidr)
	if err == nil {
		t.Fatalf("expected an error")
	}
}

func TestCIDRUtil_IPBelongsToCIDRBlocksString(t *testing.T) {
	ip := "192.168.27.29"
	cidrList := "172.169.100.200/18,192.168.0.0/16,10.10.20.20/24"

	belongs, err := IPBelongsToCIDRBlocksString(ip, cidrList, ",")
	if err != nil {
		t.Fatal(err)
	}
	if !belongs {
		t.Fatalf("expected IP %q to belong to one of the CIDRs in %q", ip, cidrList)
	}

	ip = "192.168.27.29"
	cidrList = "172.169.100.200/18,192.168.0.0.0/16,10.10.20.20/24"

	belongs, err = IPBelongsToCIDRBlocksString(ip, cidrList, ",")
	if err == nil {
		t.Fatalf("expected an error")
	}

	ip = "30.40.50.60"
	cidrList = "172.169.100.200/18,192.168.0.0/16,10.10.20.20/24"

	belongs, err = IPBelongsToCIDRBlocksString(ip, cidrList, ",")
	if err != nil {
		t.Fatal(err)
	}
	if belongs {
		t.Fatalf("expected IP %q to not belong to one of the CIDRs in %q", ip, cidrList)
	}

}

func TestCIDRUtil_IPBelongsToCIDRBlocksSlice(t *testing.T) {
	ip := "192.168.27.29"
	cidrList := []string{"172.169.100.200/18", "192.168.0.0/16", "10.10.20.20/24"}

	belongs, err := IPBelongsToCIDRBlocksSlice(ip, cidrList)
	if err != nil {
		t.Fatal(err)
	}
	if !belongs {
		t.Fatalf("expected IP %q to belong to one of the CIDRs in %q", ip, cidrList)
	}

	ip = "192.168.27.29"
	cidrList = []string{"172.169.100.200/18", "192.168.0.0.0/16", "10.10.20.20/24"}

	belongs, err = IPBelongsToCIDRBlocksSlice(ip, cidrList)
	if err == nil {
		t.Fatalf("expected an error")
	}

	ip = "30.40.50.60"
	cidrList = []string{"172.169.100.200/18", "192.168.0.0/16", "10.10.20.20/24"}

	belongs, err = IPBelongsToCIDRBlocksSlice(ip, cidrList)
	if err != nil {
		t.Fatal(err)
	}
	if belongs {
		t.Fatalf("expected IP %q to not belong to one of the CIDRs in %q", ip, cidrList)
	}
}

func TestCIDRUtil_ValidateCIDRListString(t *testing.T) {
	cidrList := "172.169.100.200/18,192.168.0.0/16,10.10.20.20/24"

	valid, err := ValidateCIDRListString(cidrList, ",")
	if err != nil {
		t.Fatal(err)
	}
	if !valid {
		t.Fatalf("expected CIDR list %q to be valid")
	}

	cidrList = "172.169.100.200,192.168.0.0/16,10.10.20.20/24"
	valid, err = ValidateCIDRListString(cidrList, ",")
	if err == nil {
		t.Fatal("expected an error")
	}

	cidrList = "172.169.100.200/18,192.168.0.0.0/16,10.10.20.20/24"
	valid, err = ValidateCIDRListString(cidrList, ",")
	if err == nil {
		t.Fatal("expected an error")
	}
}

func TestCIDRUtil_ValidateCIDRListSlice(t *testing.T) {
	cidrList := []string{"172.169.100.200/18", "192.168.0.0/16", "10.10.20.20/24"}

	valid, err := ValidateCIDRListSlice(cidrList)
	if err != nil {
		t.Fatal(err)
	}
	if !valid {
		t.Fatalf("expected CIDR list %q to be valid")
	}

	cidrList = []string{"172.169.100.200", "192.168.0.0/16", "10.10.20.20/24"}
	valid, err = ValidateCIDRListSlice(cidrList)
	if err == nil {
		t.Fatal("expected an error")
	}

	cidrList = []string{"172.169.100.200/18", "192.168.0.0.0/16", "10.10.20.20/24"}
	valid, err = ValidateCIDRListSlice(cidrList)
	if err == nil {
		t.Fatal("expected an error")
	}
}

func TestCIDRUtil_Subset(t *testing.T) {
	cidr1 := "192.168.27.29/24"
	cidr2 := "192.168.27.29/24"
	subset, err := Subset(cidr1, cidr2)
	if err != nil {
		t.Fatal(err)
	}
	if !subset {
		t.Fatalf("expected CIDR %q to be a subset of CIDR %q", cidr2, cidr1)
	}

	cidr1 = "192.168.27.29/16"
	cidr2 = "192.168.27.29/24"
	subset, err = Subset(cidr1, cidr2)
	if err != nil {
		t.Fatal(err)
	}
	if !subset {
		t.Fatalf("expected CIDR %q to be a subset of CIDR %q", cidr2, cidr1)
	}

	cidr1 = "192.168.27.29/24"
	cidr2 = "192.168.27.29/16"
	subset, err = Subset(cidr1, cidr2)
	if err != nil {
		t.Fatal(err)
	}
	if subset {
		t.Fatalf("expected CIDR %q to not be a subset of CIDR %q", cidr2, cidr1)
	}

	cidr1 = "192.168.0.128/25"
	cidr2 = "192.168.0.0/24"
	subset, err = Subset(cidr1, cidr2)
	if err != nil {
		t.Fatal(err)
	}
	if subset {
		t.Fatalf("expected CIDR %q to not be a subset of CIDR %q", cidr2, cidr1)
	}
	subset, err = Subset(cidr2, cidr1)
	if err != nil {
		t.Fatal(err)
	}
	if !subset {
		t.Fatal("expected CIDR %q to be a subset of CIDR %q", cidr1, cidr2)
	}
}

func TestCIDRUtil_SubsetBlocks(t *testing.T) {
	cidrBlocks1 := []string{"192.168.27.29/16", "172.245.30.40/24", "10.20.30.40/30"}
	cidrBlocks2 := []string{"192.168.27.29/20", "172.245.30.40/25", "10.20.30.40/32"}

	subset, err := SubsetBlocks(cidrBlocks1, cidrBlocks2)
	if err != nil {
		t.Fatal(err)
	}
	if !subset {
		t.Fatalf("expected CIDR blocks %q to be a subset of CIDR blocks %q", cidrBlocks2, cidrBlocks1)
	}

	cidrBlocks1 = []string{"192.168.27.29/16", "172.245.30.40/25", "10.20.30.40/30"}
	cidrBlocks2 = []string{"192.168.27.29/20", "172.245.30.40/24", "10.20.30.40/32"}

	subset, err = SubsetBlocks(cidrBlocks1, cidrBlocks2)
	if err != nil {
		t.Fatal(err)
	}
	if subset {
		t.Fatalf("expected CIDR blocks %q to not be a subset of CIDR blocks %q", cidrBlocks2, cidrBlocks1)
	}
}
<|endoftext|>


<commit_before>// Go support for leveled logs, analogous to https://code.google.com/p/google-glog/
//
// Copyright 2013 Google Inc. 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.

// File I/O for logs.

package glog

import (
	"flag"
	"fmt"
	"os"
	"os/user"
	"path/filepath"
	"strings"
	"time"
)

// MaxSize is the maximum size of a log file in bytes.
var MaxSize uint64 = 1024 * 1024 * 1800

// If non-empty, overrides the choice of directory in which to write logs.
// See createLogDirs for the full list of possible destinations.
var LogDir string

var (
	pid      = os.Getpid()
	program  = filepath.Base(os.Args[0])
	host     = "unknownhost"
	userName = "unknownuser"
)

func init() {
	h, err := os.Hostname()
	if err == nil {
		host = shortHostname(h)
	}

	current, err := user.Current()
	if err == nil {
		userName = current.Username
	}

	// Sanitize userName since it may contain filepath separators on Windows.
	userName = strings.Replace(userName, `\`, "_", -1)

	flag.StringVar(&LogDir, "log_dir", "", "If non-empty, write log files in this directory")
}

// shortHostname returns its argument, truncating at the first period.
// For instance, given "www.google.com" it returns "www".
func shortHostname(hostname string) string {
	if i := strings.Index(hostname, "."); i >= 0 {
		return hostname[:i]
	}
	return hostname
}

// logName returns a new log file name containing tag, with start time t, and
// the name for the symlink for tag.
func logName(tag string, t time.Time) (name, link string) {
	name = fmt.Sprintf("%s.%s.%s.log.%s.%04d%02d%02d-%02d%02d%02d.%d",
		program,
		host,
		userName,
		tag,
		t.Year(),
		t.Month(),
		t.Day(),
		t.Hour(),
		t.Minute(),
		t.Second(),
		pid)
	return name, program + "." + tag
}

// create creates a new log file and returns the file and its filename, which
// contains tag ("INFO", "FATAL", etc.) and t.  If the file is created
// successfully, create also attempts to update the symlink for that tag, ignoring
// errors.
func create(tag string, t time.Time, lrc bool) (f *os.File, filename string, err error) {
	var lastErr error
	if len(LogDir) > 0 {
		name, link := logName(tag, t)
		if !lrc {
			fname := filepath.Join(LogDir, name)
			f, err := os.Create(fname)
			if err == nil {
				symlink := filepath.Join(LogDir, link)
				os.Remove(symlink)        // ignore err
				os.Symlink(name, symlink) // ignore err
				return f, fname, nil
			}
			lastErr = err
		} else {
			fname := filepath.Join(LogDir, link)
			f, err := os.OpenFile(fname, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0660)
			if err == nil {
				return f, fname, nil
			}
			lastErr = err
		}
	} else {
		// in the future better dup2 stdout/err and return fd
		lastErr = fmt.Errorf("no -log_dir")
	}
	return nil, "", fmt.Errorf("log: cannot create log: %v", lastErr)
}
<commit_msg>make LogName func public handler<commit_after>// Go support for leveled logs, analogous to https://code.google.com/p/google-glog/
//
// Copyright 2013 Google Inc. 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.

// File I/O for logs.

package glog

import (
	"flag"
	"fmt"
	"os"
	"os/user"
	"path/filepath"
	"strings"
	"time"
)

// MaxSize is the maximum size of a log file in bytes.
var MaxSize uint64 = 1024 * 1024 * 1800

// If non-empty, overrides the choice of directory in which to write logs.
// See createLogDirs for the full list of possible destinations.
var LogDir string

var (
	pid      = os.Getpid()
	program  = filepath.Base(os.Args[0])
	host     = "unknownhost"
	userName = "unknownuser"
)

func init() {
	h, err := os.Hostname()
	if err == nil {
		host = shortHostname(h)
	}

	current, err := user.Current()
	if err == nil {
		userName = current.Username
	}

	// Sanitize userName since it may contain filepath separators on Windows.
	userName = strings.Replace(userName, `\`, "_", -1)

	flag.StringVar(&LogDir, "log_dir", "", "If non-empty, write log files in this directory")
}

// shortHostname returns its argument, truncating at the first period.
// For instance, given "www.google.com" it returns "www".
func shortHostname(hostname string) string {
	if i := strings.Index(hostname, "."); i >= 0 {
		return hostname[:i]
	}
	return hostname
}

// LogName returns a new log file name containing tag, with start time t, and
// the name for the symlink for tag.
var LogName = func (tag string, t time.Time) (name, link string) {
	name = fmt.Sprintf("%s.%s.%s.log.%s.%04d%02d%02d-%02d%02d%02d.%d",
		program,
		host,
		userName,
		tag,
		t.Year(),
		t.Month(),
		t.Day(),
		t.Hour(),
		t.Minute(),
		t.Second(),
		pid)
	return name, program + "." + tag
}

// create creates a new log file and returns the file and its filename, which
// contains tag ("INFO", "FATAL", etc.) and t.  If the file is created
// successfully, create also attempts to update the symlink for that tag, ignoring
// errors.
func create(tag string, t time.Time, lrc bool) (f *os.File, filename string, err error) {
	var lastErr error
	if len(LogDir) > 0 {
		name, link := LogName(tag, t)
		if !lrc {
			fname := filepath.Join(LogDir, name)
			f, err := os.Create(fname)
			if err == nil {
				symlink := filepath.Join(LogDir, link)
				os.Remove(symlink)        // ignore err
				os.Symlink(name, symlink) // ignore err
				return f, fname, nil
			}
			lastErr = err
		} else {
			fname := filepath.Join(LogDir, link)
			f, err := os.OpenFile(fname, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0660)
			if err == nil {
				return f, fname, nil
			}
			lastErr = err
		}
	} else {
		// in the future better dup2 stdout/err and return fd
		lastErr = fmt.Errorf("no -log_dir")
	}
	return nil, "", fmt.Errorf("log: cannot create log: %v", lastErr)
}
<|endoftext|>


<commit_before>package command

import (
	"fmt"
	"log"

	tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api"
)

//Handler defines handle func
type Handler func(msg *tgbotapi.Message) tgbotapi.MessageConfig

//CommanderName defines command's literal name
type CommanderName string

//Commander defines command obj
type Commander struct {
	Name     CommanderName
	Usage    string
	behavior Handler
}

const (
	//CommandSayhi == /sayhi
	CommandSayhi CommanderName = "sayhi"
	//CommandTodayAnime == /today_anime,combine all animes from all srcs.
	CommandTodayAnime CommanderName = "today_anime"
)

//DefaultBehavior defines the  default behavior of commander
var DefaultBehavior = func(msg *tgbotapi.Message) tgbotapi.MessageConfig {
	defaultText := fmt.Sprintf("%s 命中了,但是作者什么都没有实现哦😞", msg.Command())
	return tgbotapi.NewMessage(msg.Chat.ID, defaultText)
}

//NewCommand init a command
func NewCommand(name CommanderName, u string, handler Handler) *Commander {
	if handler == nil {

	}
	return &Commander{
		Name:     name,
		Usage:    u,
		behavior: handler,
	}
}

//Do will run the command behavior
func (c *Commander) Do(msg *tgbotapi.Message) tgbotapi.MessageConfig {
	if msg.Command() != string(c.Name) {
		log.Printf("%s skiped command %s", msg.Command(), string(c.Name))
		return tgbotapi.MessageConfig{}
	}
	if c.behavior == nil {
		c.behavior = DefaultBehavior
	}
	return c.behavior(msg)
}
<commit_msg>rename command<commit_after>package command

import (
	"fmt"
	"log"

	tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api"
)

//Handler defines handle func
type Handler func(msg *tgbotapi.Message) tgbotapi.MessageConfig

//CommanderName defines command's literal name
type CommanderName string

//Commander defines command obj
type Commander struct {
	Name     CommanderName
	Usage    string
	behavior Handler
}

const (
	//CommandSayhi == /sayhi
	CommandSayhi CommanderName = "sayhi"
	//CommandTodayAnime == /today_anime,combine all animes from all srcs.
	CommandTodayAnime CommanderName = "todayanime"
)

//DefaultBehavior defines the  default behavior of commander
var DefaultBehavior = func(msg *tgbotapi.Message) tgbotapi.MessageConfig {
	defaultText := fmt.Sprintf("%s 命中了,但是作者什么都没有实现哦😞", msg.Command())
	return tgbotapi.NewMessage(msg.Chat.ID, defaultText)
}

//NewCommand init a command
func NewCommand(name CommanderName, u string, handler Handler) *Commander {
	if handler == nil {

	}
	return &Commander{
		Name:     name,
		Usage:    u,
		behavior: handler,
	}
}

//Do will run the command behavior
func (c *Commander) Do(msg *tgbotapi.Message) tgbotapi.MessageConfig {
	if msg.Command() != string(c.Name) {
		log.Printf("%s skiped command %s", msg.Command(), string(c.Name))
		return tgbotapi.MessageConfig{}
	}
	if c.behavior == nil {
		c.behavior = DefaultBehavior
	}
	return c.behavior(msg)
}
<|endoftext|>