<commit_before>// Copyright (c) 2013 Conformal Systems LLC.
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.

package btcwire

import (
	"crypto/rand"
	"crypto/sha256"
	"encoding/binary"
	"io"
	"math"
)

// Maximum payload size for a variable length integer.
const maxVarIntPayload = 9

// readElement reads the next sequence of bytes from r using little endian
// depending on the concrete type of element pointed to.
func readElement(r io.Reader, element interface{}) error {
	return binary.Read(r, binary.LittleEndian, element)
}

// readElements reads multiple items from r.  It is equivalent to multiple
// calls to readElement.
func readElements(r io.Reader, elements ...interface{}) error {
	for _, element := range elements {
		err := readElement(r, element)
		if err != nil {
			return err
		}
	}
	return nil
}

// writeElement writes the little endian representation of element to w.
func writeElement(w io.Writer, element interface{}) error {
	return binary.Write(w, binary.LittleEndian, element)
}

// writeElements writes multiple items to w.  It is equivalent to multiple
// calls to writeElement.
func writeElements(w io.Writer, elements ...interface{}) error {
	for _, element := range elements {
		err := writeElement(w, element)
		if err != nil {
			return err
		}
	}
	return nil
}

// readVarInt reads a variable length integer from r and returns it as a uint64.
func readVarInt(r io.Reader, pver uint32) (uint64, error) {
	b := make([]byte, 1)
	_, err := r.Read(b)
	if err != nil {
		return 0, err
	}

	var rv uint64
	discriminant := uint8(b[0])
	switch discriminant {
	case 0xff:
		var u uint64
		err = binary.Read(r, binary.LittleEndian, &u)
		if err != nil {
			return 0, err
		}
		rv = u

	case 0xfe:
		var u uint32
		err = binary.Read(r, binary.LittleEndian, &u)
		if err != nil {
			return 0, err
		}
		rv = uint64(u)

	case 0xfd:
		var u uint16
		err = binary.Read(r, binary.LittleEndian, &u)
		if err != nil {
			return 0, err
		}
		rv = uint64(u)

	default:
		rv = uint64(discriminant)
	}

	return rv, nil
}

// writeVarInt serializes val to w using a variable number of bytes depending
// on its value.
func writeVarInt(w io.Writer, pver uint32, val uint64) error {
	if val > math.MaxUint32 {
		err := writeElements(w, []byte{0xff}, uint64(val))
		if err != nil {
			return err
		}
		return nil
	}
	if val > math.MaxUint16 {
		err := writeElements(w, []byte{0xfe}, uint32(val))
		if err != nil {
			return err
		}
		return nil
	}
	if val >= 0xfd {
		err := writeElements(w, []byte{0xfd}, uint16(val))
		if err != nil {
			return err
		}
		return nil
	}
	return writeElement(w, uint8(val))
}

// readVarString reads a variable length string from r and returns it as a Go
// string.  A varString is encoded as a varInt containing the length of the
// string, and the bytes that represent the string itself.
func readVarString(r io.Reader, pver uint32) (string, error) {
	slen, err := readVarInt(r, pver)
	if err != nil {
		return "", err
	}
	buf := make([]byte, slen)
	err = readElement(r, buf)
	if err != nil {
		return "", err
	}
	return string(buf), nil
}

// writeVarString serializes str to w as a varInt containing the length of the
// string followed by the bytes that represent the string itself.
func writeVarString(w io.Writer, pver uint32, str string) error {
	err := writeVarInt(w, pver, uint64(len(str)))
	if err != nil {
		return err
	}
	err = writeElement(w, []byte(str))
	if err != nil {
		return err
	}
	return nil
}

// randomUint64 returns a cryptographically random uint64 value.  This
// unexported version takes a reader primarily to ensure the error paths
// can be properly tested by passing a fake reader in the tests.
func randomUint64(r io.Reader) (uint64, error) {
	b := make([]byte, 8)
	n, err := r.Read(b)
	if n != len(b) {
		return 0, io.ErrShortBuffer
	}
	if err != nil {
		return 0, err
	}
	return binary.BigEndian.Uint64(b), nil
}

// RandomUint64 returns a cryptographically random uint64 value.
func RandomUint64() (uint64, error) {
	return randomUint64(rand.Reader)
}

// DoubleSha256 calculates sha256(sha256(b)) and returns the resulting bytes.
func DoubleSha256(b []byte) []byte {
	hasher := sha256.New()
	hasher.Write(b)
	sum := hasher.Sum(nil)
	hasher.Reset()
	hasher.Write(sum)
	sum = hasher.Sum(nil)
	return sum
}
<commit_msg>Ensure readVarInt handles short buf on first byte.<commit_after>// Copyright (c) 2013 Conformal Systems LLC.
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.

package btcwire

import (
	"crypto/rand"
	"crypto/sha256"
	"encoding/binary"
	"io"
	"math"
)

// Maximum payload size for a variable length integer.
const maxVarIntPayload = 9

// readElement reads the next sequence of bytes from r using little endian
// depending on the concrete type of element pointed to.
func readElement(r io.Reader, element interface{}) error {
	return binary.Read(r, binary.LittleEndian, element)
}

// readElements reads multiple items from r.  It is equivalent to multiple
// calls to readElement.
func readElements(r io.Reader, elements ...interface{}) error {
	for _, element := range elements {
		err := readElement(r, element)
		if err != nil {
			return err
		}
	}
	return nil
}

// writeElement writes the little endian representation of element to w.
func writeElement(w io.Writer, element interface{}) error {
	return binary.Write(w, binary.LittleEndian, element)
}

// writeElements writes multiple items to w.  It is equivalent to multiple
// calls to writeElement.
func writeElements(w io.Writer, elements ...interface{}) error {
	for _, element := range elements {
		err := writeElement(w, element)
		if err != nil {
			return err
		}
	}
	return nil
}

// readVarInt reads a variable length integer from r and returns it as a uint64.
func readVarInt(r io.Reader, pver uint32) (uint64, error) {
	b := make([]byte, 1)
	_, err := io.ReadFull(r, b)
	if err != nil {
		return 0, err
	}

	var rv uint64
	discriminant := uint8(b[0])
	switch discriminant {
	case 0xff:
		var u uint64
		err = binary.Read(r, binary.LittleEndian, &u)
		if err != nil {
			return 0, err
		}
		rv = u

	case 0xfe:
		var u uint32
		err = binary.Read(r, binary.LittleEndian, &u)
		if err != nil {
			return 0, err
		}
		rv = uint64(u)

	case 0xfd:
		var u uint16
		err = binary.Read(r, binary.LittleEndian, &u)
		if err != nil {
			return 0, err
		}
		rv = uint64(u)

	default:
		rv = uint64(discriminant)
	}

	return rv, nil
}

// writeVarInt serializes val to w using a variable number of bytes depending
// on its value.
func writeVarInt(w io.Writer, pver uint32, val uint64) error {
	if val > math.MaxUint32 {
		err := writeElements(w, []byte{0xff}, uint64(val))
		if err != nil {
			return err
		}
		return nil
	}
	if val > math.MaxUint16 {
		err := writeElements(w, []byte{0xfe}, uint32(val))
		if err != nil {
			return err
		}
		return nil
	}
	if val >= 0xfd {
		err := writeElements(w, []byte{0xfd}, uint16(val))
		if err != nil {
			return err
		}
		return nil
	}
	return writeElement(w, uint8(val))
}

// readVarString reads a variable length string from r and returns it as a Go
// string.  A varString is encoded as a varInt containing the length of the
// string, and the bytes that represent the string itself.
func readVarString(r io.Reader, pver uint32) (string, error) {
	slen, err := readVarInt(r, pver)
	if err != nil {
		return "", err
	}
	buf := make([]byte, slen)
	err = readElement(r, buf)
	if err != nil {
		return "", err
	}
	return string(buf), nil
}

// writeVarString serializes str to w as a varInt containing the length of the
// string followed by the bytes that represent the string itself.
func writeVarString(w io.Writer, pver uint32, str string) error {
	err := writeVarInt(w, pver, uint64(len(str)))
	if err != nil {
		return err
	}
	err = writeElement(w, []byte(str))
	if err != nil {
		return err
	}
	return nil
}

// randomUint64 returns a cryptographically random uint64 value.  This
// unexported version takes a reader primarily to ensure the error paths
// can be properly tested by passing a fake reader in the tests.
func randomUint64(r io.Reader) (uint64, error) {
	b := make([]byte, 8)
	n, err := r.Read(b)
	if n != len(b) {
		return 0, io.ErrShortBuffer
	}
	if err != nil {
		return 0, err
	}
	return binary.BigEndian.Uint64(b), nil
}

// RandomUint64 returns a cryptographically random uint64 value.
func RandomUint64() (uint64, error) {
	return randomUint64(rand.Reader)
}

// DoubleSha256 calculates sha256(sha256(b)) and returns the resulting bytes.
func DoubleSha256(b []byte) []byte {
	hasher := sha256.New()
	hasher.Write(b)
	sum := hasher.Sum(nil)
	hasher.Reset()
	hasher.Write(sum)
	sum = hasher.Sum(nil)
	return sum
}
<|endoftext|>


<commit_before>package QesyGo

import (
	"encoding/json"
	"errors"
	"fmt"
	"io/ioutil"
	"log"
	"math/rand"
	"net/http"
	"strconv"
	"strings"
	"time"
)

type RandWeiht struct {
	Name   string
	Weight int
}

type RandWeihtArr []RandWeiht

func Substr(str string, start int, end int) string {
	var endNum int
	s := []byte(str)
	if end > 0 {
		endNum = start + end
	} else {
		endNum = len(str) + end
	}
	return string(s[start:endNum])
}

func Rate(num int) bool {
	rand := rand.Intn(100) + 1
	if rand <= num {
		return true
	} else {
		return false
	}
}

/*
* RandWeihtArr := &lib.RandWeihtArr{{"user1",8}, {"user2",1},{"user3",1}}
* who := RandWeihtArr.RandWeight()
 */
func (arr *RandWeihtArr) RandWeight() string {
	var all int
	for _, v := range *arr {
		all += v.Weight
	}
	plusNum := 0
	tempArr := make(map[string][2]int)
	for _, v := range *arr {
		plusNum += v.Weight
		tempArr[v.Name] = [2]int{plusNum - v.Weight, plusNum}
	}
	randNum := rand.Intn(all) + 1
	var ret string
	for k, v := range tempArr {
		if randNum > v[0] && randNum <= v[1] {
			ret = k
			break
		}
	}
	return ret
}

func InArray(Arr interface{}, str string) bool {
	strArr, ok := Arr.([]string)
	if ok {
		for _, v := range strArr {
			if v == str {
				return true
			}
		}
		return false
	}
	mapArr, ok := Arr.(map[string]string)
	if ok {
		for _, v := range mapArr {
			if v == str {
				return true
			}
		}
		return false
	}
	intArr, ok := Arr.([]int)
	if ok {
		for _, v := range intArr {
			if strconv.Itoa(v) == str {
				return true
			}
		}
		return false
	}
	return false

}

func ReadFile(str string) ([]byte, error) {
	return ioutil.ReadFile(str)
}

func JsonEncode(arr interface{}) ([]byte, error) {
	return json.Marshal(arr)
}

func JsonDecode(str []byte, jsonArr interface{}) error {
	err := json.Unmarshal(str, jsonArr)
	return err

}

func Printf(format string, a ...interface{}) {
	fmt.Printf(format, a)
}

func Fprintf(w http.ResponseWriter, str string) {
	fmt.Fprintf(w, str)
}

func Die(v interface{}) {
	log.Fatal(v)
}

func Implode(arr []string, sep string) string {
	return strings.Join(arr, sep)
}

func Explode(str string, sep string) []string {
	if str == "" {
		return []string{}
	}
	return strings.Split(str, sep)
}

func Err(str string) error {
	return errors.New(str)
}

func Println(str ...interface{}) {
	fmt.Println(str)
}

func Time(str string) int64 {
	now := time.Now()
	t := now.UnixNano()
	switch str {
	case "Millisecond":
		t = now.UnixNano() / 1000
	case "Microsecond":
		t = now.UnixNano() / 1000000
	case "Second":
		t = now.UnixNano() / 1000000000
	}
	return t
}

//-- format : "2006-01-02 03:04:05 PM" --
/*
月份 1,01,Jan,January
日　 2,02,_2
时　 3,03,15,PM,pm,AM,am
分　 4,04
秒　 5,05
年　 06,2006
周几 Mon,Monday
时区时差表示 -07,-0700,Z0700,Z07:00,-07:00,MST
时区字母缩写 MST
*/
func Date(timestamp int64, format string) string {
	tm := time.Unix(timestamp, 0)
	return tm.Format(format)
}

//-- "01/02/2006", "02/08/2015" --
func StrToTime(format string, input string) int64 {
	tm2, _ := time.Parse(format, input)
	return tm2.Unix()
}

func Int64ToInt(num int64) (int, error) {
	str := strconv.FormatInt(num, 10)
	return strconv.Atoi(str)
}

func Unset(arr []string, str string) []string {
	newArr := []string{}
	for _, v := range arr {
		if v != str && v != "" {
			newArr = append(newArr, v)
		}
	}
	return newArr
}
<commit_msg>fix jsondecode<commit_after>package QesyGo

import (
	"encoding/json"
	"errors"
	"fmt"
	"io/ioutil"
	"log"
	"math/rand"
	"net/http"
	"strconv"
	"strings"
	"time"
)

type RandWeiht struct {
	Name   string
	Weight int
}

type RandWeihtArr []RandWeiht

func Substr(str string, start int, end int) string {
	var endNum int
	s := []byte(str)
	if end > 0 {
		endNum = start + end
	} else {
		endNum = len(str) + end
	}
	return string(s[start:endNum])
}

func Rate(num int) bool {
	rand := rand.Intn(100) + 1
	if rand <= num {
		return true
	} else {
		return false
	}
}

/*
* RandWeihtArr := &lib.RandWeihtArr{{"user1",8}, {"user2",1},{"user3",1}}
* who := RandWeihtArr.RandWeight()
 */
func (arr *RandWeihtArr) RandWeight() string {
	var all int
	for _, v := range *arr {
		all += v.Weight
	}
	plusNum := 0
	tempArr := make(map[string][2]int)
	for _, v := range *arr {
		plusNum += v.Weight
		tempArr[v.Name] = [2]int{plusNum - v.Weight, plusNum}
	}
	randNum := rand.Intn(all) + 1
	var ret string
	for k, v := range tempArr {
		if randNum > v[0] && randNum <= v[1] {
			ret = k
			break
		}
	}
	return ret
}

func InArray(Arr interface{}, str string) bool {
	strArr, ok := Arr.([]string)
	if ok {
		for _, v := range strArr {
			if v == str {
				return true
			}
		}
		return false
	}
	mapArr, ok := Arr.(map[string]string)
	if ok {
		for _, v := range mapArr {
			if v == str {
				return true
			}
		}
		return false
	}
	intArr, ok := Arr.([]int)
	if ok {
		for _, v := range intArr {
			if strconv.Itoa(v) == str {
				return true
			}
		}
		return false
	}
	return false

}

func ReadFile(str string) ([]byte, error) {
	return ioutil.ReadFile(str)
}

func JsonEncode(arr interface{}) ([]byte, error) {
	return json.Marshal(arr)
}

func JsonDecode(str []byte, jsonArr interface{}) error {
	strNew := string(str)
	if strNew == "null" || strNew == "" {
		return nil
	}
	err := json.Unmarshal(str, jsonArr)
	return err

}

func Printf(format string, a ...interface{}) {
	fmt.Printf(format, a)
}

func Fprintf(w http.ResponseWriter, str string) {
	fmt.Fprintf(w, str)
}

func Die(v interface{}) {
	log.Fatal(v)
}

func Implode(arr []string, sep string) string {
	return strings.Join(arr, sep)
}

func Explode(str string, sep string) []string {
	if str == "" {
		return []string{}
	}
	return strings.Split(str, sep)
}

func Err(str string) error {
	return errors.New(str)
}

func Println(str ...interface{}) {
	fmt.Println(str)
}

func Time(str string) int64 {
	now := time.Now()
	t := now.UnixNano()
	switch str {
	case "Millisecond":
		t = now.UnixNano() / 1000
	case "Microsecond":
		t = now.UnixNano() / 1000000
	case "Second":
		t = now.UnixNano() / 1000000000
	}
	return t
}

//-- format : "2006-01-02 03:04:05 PM" --
/*
月份 1,01,Jan,January
日　 2,02,_2
时　 3,03,15,PM,pm,AM,am
分　 4,04
秒　 5,05
年　 06,2006
周几 Mon,Monday
时区时差表示 -07,-0700,Z0700,Z07:00,-07:00,MST
时区字母缩写 MST
*/
func Date(timestamp int64, format string) string {
	tm := time.Unix(timestamp, 0)
	return tm.Format(format)
}

//-- "01/02/2006", "02/08/2015" --
func StrToTime(format string, input string) int64 {
	tm2, _ := time.Parse(format, input)
	return tm2.Unix()
}

func Int64ToInt(num int64) (int, error) {
	str := strconv.FormatInt(num, 10)
	return strconv.Atoi(str)
}

func Unset(arr []string, str string) []string {
	newArr := []string{}
	for _, v := range arr {
		if v != str && v != "" {
			newArr = append(newArr, v)
		}
	}
	return newArr
}
<|endoftext|>


<commit_before>package main

import (
	"path"
	"reflect"
)

func builtinImport(ss []sexpr) sexpr {
	if len(ss) != 1 {
		panic("Invalid number of arguments")
	}

	pkgPath, ok := ss[0].(string)
	if !ok {
		panic("Invalid argument")
	}

	pkgName := path.Base(pkgPath)

	// find the package in _go_imports
	pkg, found := _go_imports[pkgPath]
	if !found {
		panic("Package not found")
	}

	// import each item
	for name, _go := range pkg {
		global[pkgName + "." + name] = wrapGo(_go)
	}
	return Nil
}

func wrapGo(_go interface{}) sexpr {
	typ := reflect.TypeOf(_go)
	kind := typ.Kind()
	switch kind {
	case reflect.Bool:
		b := _go.(bool)
		if b {
			return float64(1)
		} else {
			return Nil
		}
	case reflect.Int:
		return float64(_go.(int))
	case reflect.Int8:
		return float64(_go.(int8))
	case reflect.Int16:
		return float64(_go.(int16))
	case reflect.Int32:
		return float64(_go.(int32))
	case reflect.Int64:
		return float64(_go.(int64))
	case reflect.Uint:
		return float64(_go.(uint))
	case reflect.Uint8:
		return float64(_go.(uint8))
	case reflect.Uint16:
		return float64(_go.(uint16))
	case reflect.Uint32:
		return float64(_go.(uint32))
	case reflect.Uint64:
		return float64(_go.(uint64))
	case reflect.Uintptr:
		return Nil // TODO
	case reflect.Float32:
		return float64(_go.(float32))
	case reflect.Float64:
		return float64(_go.(float64))
	case reflect.Complex64:
		return Nil // TODO
	case reflect.Complex128:
		return Nil // TODO
	case reflect.Array:
		return Nil // TODO
	case reflect.Chan:
		return Nil // TODO
	case reflect.Func:
		return wrapFunc(_go)
	case reflect.Interface:
		return Nil // TODO
	case reflect.Map:
		return Nil // TODO
	case reflect.Ptr:
		return Nil // TODO
	case reflect.Slice:
		return Nil // TODO
	case reflect.String:
		return _go.(string)
	case reflect.Struct:
		return Nil // TODO
	case reflect.UnsafePointer:
		return Nil // can't handle this
	}
	return Nil
}

func wrapFunc(f interface{}) func([]sexpr) sexpr {
	// TODO patch reflect so we can do type compatibility-checking
	return func(ss []sexpr) sexpr {
		fun := reflect.ValueOf(f)
		vs := make([]reflect.Value, len(ss))
		for i, s := range ss {
			vs[i] = reflect.ValueOf(s)
		}
		r := fun.Call(vs)
		return wrapGo(r)
	}
}
<commit_msg>Adding TODO notice<commit_after>package main

import (
	"path"
	"reflect"
)

func builtinImport(ss []sexpr) sexpr {
	if len(ss) != 1 {
		panic("Invalid number of arguments")
	}

	pkgPath, ok := ss[0].(string)
	if !ok {
		panic("Invalid argument")
	}

	pkgName := path.Base(pkgPath)

	// find the package in _go_imports
	pkg, found := _go_imports[pkgPath]
	if !found {
		panic("Package not found")
	}

	// import each item
	for name, _go := range pkg {
		global[pkgName + "." + name] = wrapGo(_go)
	}
	return Nil
}

func wrapGo(_go interface{}) sexpr {
	typ := reflect.TypeOf(_go)
	kind := typ.Kind()
	switch kind {
	case reflect.Bool:
		b := _go.(bool)
		if b {
			return float64(1)
		} else {
			return Nil
		}
	case reflect.Int:
		return float64(_go.(int))
	case reflect.Int8:
		return float64(_go.(int8))
	case reflect.Int16:
		return float64(_go.(int16))
	case reflect.Int32:
		return float64(_go.(int32))
	case reflect.Int64:
		return float64(_go.(int64))
	case reflect.Uint:
		return float64(_go.(uint))
	case reflect.Uint8:
		return float64(_go.(uint8))
	case reflect.Uint16:
		return float64(_go.(uint16))
	case reflect.Uint32:
		return float64(_go.(uint32))
	case reflect.Uint64:
		return float64(_go.(uint64))
	case reflect.Uintptr:
		return Nil // TODO
	case reflect.Float32:
		return float64(_go.(float32))
	case reflect.Float64:
		return float64(_go.(float64))
	case reflect.Complex64:
		return Nil // TODO
	case reflect.Complex128:
		return Nil // TODO
	case reflect.Array:
		return Nil // TODO
	case reflect.Chan:
		return Nil // TODO
	case reflect.Func:
		return wrapFunc(_go)
	case reflect.Interface:
		return Nil // TODO
	case reflect.Map:
		return Nil // TODO
	case reflect.Ptr:
		return Nil // TODO
	case reflect.Slice:
		return Nil // TODO
	case reflect.String:
		return _go.(string)
	case reflect.Struct:
		return Nil // TODO
	case reflect.UnsafePointer:
		return Nil // can't handle this
	}
	return Nil
}

func wrapFunc(f interface{}) func([]sexpr) sexpr {
	// TODO patch reflect so we can do type compatibility-checking
	return func(ss []sexpr) sexpr {
		fun := reflect.ValueOf(f)
		vs := make([]reflect.Value, len(ss))
		for i, s := range ss {
			// TODO convert any cons and function arguments
			vs[i] = reflect.ValueOf(s)
		}
		r := fun.Call(vs)
		return wrapGo(r)
	}
}
<|endoftext|>


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

package nvim

import (
	"go/scanner"

	"github.com/garyburd/neovim-go/vim"
)

// QuickfixError represents an item in a quickfix list.
type LoclistError struct {
	// Buffer number
	Bufnr int `msgpack:"bufnr,omitempty"`
	// Name of a file; only used when bufnr is not present or it is invalid.
	FileName string `msgpack:"filename,omitempty"`
	// Line number in the file.
	LNum int `msgpack:"lnum,omitempty"`
	// Column number (first column is 1).
	Col int `msgpack:"col,omitempty"`
	// When Vcol is != 0,  Col is visual column.
	VCol int `msgpack:"vcol,omitempty"`
	// Error number.
	Nr int `msgpack:"nr,omitempty"`
	// Search pattern used to locate the error.
	Pattern string `msgpack:"pattern,omitempty"`
	// Description of the error.
	Text string `msgpack:"text,omitempty"`
	// Single-character error type, 'E', 'W', etc.
	Type string `msgpack:"type,omitempty"`
	// Valid is non-zero if this is a recognized error message.
	Valid int `msgpack:"valid,omitempty"`
}

func LoclistErrors(v *vim.Vim, b vim.Buffer, errors error) error {
	var loclist []*LoclistError

	if e, ok := errors.(scanner.Error); ok {
		loclist = append(loclist, &LoclistError{
			LNum: e.Pos.Line,
			Col:  e.Pos.Column,
			Text: e.Msg,
		})
	} else if el, ok := errors.(scanner.ErrorList); ok {
		for _, e := range el {
			loclist = append(loclist, &LoclistError{
				LNum: e.Pos.Line,
				Col:  e.Pos.Column,
				Text: e.Msg,
			})
		}
	}

	if len(loclist) == 0 {
		return errors
	}

	bufnr, err := v.BufferNumber(b)
	if err != nil {
		return err
	}
	for i := range loclist {
		loclist[i].Bufnr = bufnr
	}

	// setloclist({nr}, {list} [, {action}])
	// Call(fname string, result interface{}, args ...interface{}) error
	if err := v.Call("setloclist", nil, 0, loclist); err != nil {
		return err
	}

	return v.Command("lopen")
}

func LoclistClose(v *vim.Vim) error {
	return v.Command("lclose")
}
<commit_msg>Fix LocationList utility<commit_after>// Copyright 2016 Koichi Shiraishi. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package nvim

import (
	"strconv"
	"strings"

	"github.com/garyburd/neovim-go/vim"
)

// Loclist represents an item in a quickfix list.
type LoclistData struct {
	// Buffer number
	Bufnr int `msgpack:"bufnr,omitempty"`
	// Name of a file; only used when bufnr is not present or it is invalid.
	FileName string `msgpack:"filename,omitempty"`
	// Line number in the file.
	LNum int `msgpack:"lnum,omitempty"`
	// Column number (first column is 1).
	Col int `msgpack:"col,omitempty"`
	// When Vcol is != 0,  Col is visual column.
	VCol int `msgpack:"vcol,omitempty"`
	// Error number.
	Nr int `msgpack:"nr,omitempty"`
	// Search pattern used to locate the error.
	Pattern string `msgpack:"pattern,omitempty"`
	// Description of the error.
	Text string `msgpack:"text,omitempty"`
	// Single-character error type, 'E', 'W', etc.
	Type string `msgpack:"type,omitempty"`
	// Valid is non-zero if this is a recognized error message.
	Valid int `msgpack:"valid,omitempty"`
}

func Loclist(v *vim.Vim, b vim.Buffer, loclist []*LoclistData, open bool) error {
	// setloclist({nr}, {list} [, {action}])
	// Call(fname string, result interface{}, args ...interface{}) error
	if err := v.Call("setloclist", nil, 0, loclist); err != nil {
		return err
	}

	if open {
		return v.Command("lopen")
	} else {
		return nil
	}
}

func LoclistClose(v *vim.Vim) error {
	return v.Command("lclose")
}

func SplitPos(pos string) (string, int, int) {
	file := strings.Split(pos, ":")
	line, _ := strconv.ParseInt(file[1], 10, 64)
	col, _ := strconv.ParseInt(file[2], 10, 64)

	return file[0], int(line), int(col)
}
<|endoftext|>


<commit_before>package main

import (
	"./prompt"
	"fmt"
	"gopkg.in/yaml.v2"
	"io/ioutil"
	"os"
	"strings"
)

type Config struct {
	Directory []string `yaml:"Directory"`
}

func removeDirectories(directories []string) {
	if ok := prompt.Confirm("Directories\n%s\n\nAre you sure you want to delete directories? ", strings.Join(directories, "\n")); !ok {
		println("Do nothing")
		return
	}

	for _, directory := range directories {
		if err := os.RemoveAll(directory); err != nil {
			fmt.Println(err)
		} else {
			os.Mkdir(directory, 0775)
		}
	}
	fmt.Println("Have cleaned")
}

func readConfigFile() Config {
	configFile := os.Getenv("HOME") + "/.houki.yml"

	buf, err := ioutil.ReadFile(configFile)
	if err != nil {
		panic(err)
	}

	var parsedMap Config
	if err = yaml.Unmarshal(buf, &parsedMap); err != nil {
		panic(err)
	}

	return parsedMap
}

func main() {
	config := readConfigFile()
	removeDirectories(config.Directory)

}
<commit_msg>use goroutine for remove directory<commit_after>package main

import (
	"./prompt"
	"fmt"
	"gopkg.in/yaml.v2"
	"io/ioutil"
	"os"
	"strings"
)

type Config struct {
	Directory []string `yaml:"Directory"`
}

func reCreateDirectory(directory string) {
	if err := os.RemoveAll(directory); err != nil {
		fmt.Println(err)
	} else {
		os.Mkdir(directory, 0775)
	}
}

func removeDirectories(directories []string) {
	if ok := prompt.Confirm("Directories\n%s\n\nAre you sure you want to delete directories? ", strings.Join(directories, "\n")); !ok {
		println("Do nothing")
		return
	}

	for _, directory := range directories {
		go reCreateDirectory(directory)
	}
	fmt.Println("Have cleaned")
}

func readConfigFile() Config {
	configFile := os.Getenv("HOME") + "/.houki.yml"

	buf, err := ioutil.ReadFile(configFile)
	if err != nil {
		panic(err)
	}

	var parsedMap Config
	if err = yaml.Unmarshal(buf, &parsedMap); err != nil {
		panic(err)
	}

	return parsedMap
}

func main() {
	config := readConfigFile()
	removeDirectories(config.Directory)

}
<|endoftext|>


<commit_before>// Copyright 2013-2014 Unknown
//
// 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 Hacker View provides APIs to analyze Go projects and generate AST-based source code view.
package hv

import (
	"bytes"
	"errors"
	"fmt"
	"html/template"
	"path"
	"strings"

	"github.com/Unknwon/com"
)

// Render renders source code to HTML.
// Note that you have to call Build before you call this method.
func (w *Walker) Render() (map[string][]byte, error) {
	htmls := make(map[string][]byte)
	files := make(map[string]File)
	srcs := w.SrcFiles
	imports := make([]string, 0, 10)

	for name, src := range srcs {
		pkg, err := w.Build(&WalkRes{
			WalkDepth: WD_All,
			WalkType:  WT_Memory,
			WalkMode:  WM_NoReadme | WM_NoExample,
			Srcs:      []*Source{src},
			BuildAll:  true,
		})

		if err != nil {
			return nil, errors.New("hv.Walker.Render -> " + err.Error())
		}

		files[name] = pkg.File

		for _, v := range w.Pdoc.Imports {
			imports = com.AppendStr(imports, v)
		}
	}

	r := Render{
		Links:     GetLinks(w.Pdoc.ImportPath, imports, files),
		FilteList: make(map[string]bool),
	}

	for name := range srcs {
		htmls[name] = r.Render(name, srcs[name].Data())
		//com.SaveFile(name+".hmtl", htmls[name])
	}
	return htmls, nil
}

// A link describes the (HTML) link information for an identifier.
// The zero value of a link represents "no link".
type Link struct {
	Path, Name, Comment string
}

type localVar struct {
	name, tp string
}

// A Render describles a code render.
type Render struct {
	recv       localVar
	blockLevel int

	Links     []*Link
	FilteList map[string]bool
}

// Render highlights code.
func (r *Render) Render(name string, data []byte) []byte {
	if len(data) == 0 {
		return nil
	}

	code := string(data)
	l := len(code)

	buf := new(bytes.Buffer)
	//buf.WriteString("
")

	strTag := uint8(0)
	isComment := false
	isBlockComment := false
	isString := false
	isFuncDecl := false
	isFuncBlock := false
	isHasRecv := false
	isTypeDecl := false
	last := 0
	pos := 0

	for {
	CutWords:
		for {
			curChar := code[pos]
			if !com.IsLetter(curChar) {
				if isComment {
					// Comment.
					if isBlockComment {
						// Check if in end of block comment.
						if curChar == '/' && code[pos-1] == '*' {
							break CutWords
						}
					} else {
						// Check if in start of block comment.
						if curChar == '*' && code[pos-1] == '/' {
							isBlockComment = true
						} else if curChar == '\n' {
							break CutWords
						}
					}
				} else {
					// String.
					if curChar == '\'' || curChar == '"' || curChar == '`' {
						if !isString {
							// Set string tag.
							strTag = curChar
							isString = true
						} else {
							// Check if it is end of string or escaped character.
							if (code[pos-1] == '\\' && code[pos-2] == '\\') || code[pos-1] != '\\' {
								// Check string tag.
								if curChar == strTag {
									// Handle string highlight.
									break CutWords
								}
							}
						}
					}

					if !isString {
						switch {
						case curChar == '/' && (code[pos+1] == '/' || code[pos+1] == '*'):
							isComment = true
						case curChar > 47 && curChar < 58: // Ends with number.
						case curChar == '_' && code[pos-1] != ' ': // Underline: _.
						case (curChar != '.' || curChar == '\n'):
							break CutWords
						}
					}
				}
			}

			if pos == l-1 {
				break CutWords
			}
			pos++
		}

		seg := code[last : pos+1]
	CheckLink:
		switch {
		case isComment:
			isComment = false
			isBlockComment = false
			fmt.Fprintf(buf, `<span class="com">%s</span>`, seg)
		case isString:
			isString = false
			fmt.Fprintf(buf, `<span class="str">%s</span>`, template.HTMLEscapeString(seg))
		case seg == "\t":
			fmt.Fprintf(buf, `%s`, "    ")
		case seg == "{":
			if isFuncDecl {
				isFuncDecl = false
				isFuncBlock = true
			}

			if isFuncBlock {
				r.blockLevel++
			}
			fmt.Fprintf(buf, "%s", seg)
		case seg == "}":
			if isFuncBlock {
				r.blockLevel--
			}
			if r.blockLevel == 0 {
				isFuncBlock = false
				r.recv.name = ""
			}
			fmt.Fprintf(buf, "%s", seg)
		case isFuncDecl:
			if isHasRecv {
				if seg != "(" && seg != " " && seg != "*" {
					if len(r.recv.name) == 0 {
						r.recv.name = seg[:len(seg)-1]
					} else {
						r.recv.tp = seg[:len(seg)-1]
						isHasRecv = false
					}
				}
			} else if len(seg) > 1 && code[pos] == '(' {
				if len(r.recv.name) > 0 {
					fmt.Fprintf(buf, "%s(", r.recv.tp, seg[:len(seg)-1], seg[:len(seg)-1])
				} else {
					fmt.Fprintf(buf, "%s(", seg[:len(seg)-1], seg[:len(seg)-1])
				}
				break CheckLink
			}
			fallthrough
		case pos-last > 1:
			// Check if the last word of the paragraphy.
			l := len(seg)
			keyword := seg
			if !com.IsLetter(seg[l-1]) {
				keyword = seg[:l-1]
			} else {
				l++
			}

			// Check keywords.
			switch keyword {
			case "return", "break":
				fmt.Fprintf(buf, `<span class="ret">%s</span>%s`, keyword, seg[l-1:])
				break CheckLink
			case "func":
				isFuncDecl = true
				if code[pos+1] == '(' {
					isHasRecv = true
				}
				fallthrough
			case "package", "import", "range", "for", "if", "else", "type", "struct", "select", "case", "var", "const", "switch", "default", "continue":
				if keyword == "type" {
					isTypeDecl = true
				}
				fmt.Fprintf(buf, `<span class="key">%s</span>%s`, keyword, seg[l-1:])
				break CheckLink
			case "new", "append", "make", "panic", "recover", "len", "cap", "copy", "close", "delete", "defer":
				fmt.Fprintf(buf, `<span class="bui">%s</span>%s`, keyword, seg[l-1:])
				break CheckLink
			}

			if isPredeclared(keyword) {
				fmt.Fprintf(buf, `<span class="boo">%s</span>%s`, keyword, seg[l-1:])
				break CheckLink
			}

			// Check links.
			link, ok := r.findType(seg)
			if ok {
				switch {
				case strings.HasSuffix(link.Path, name) && len(link.Name) > 0: // Current file.
					fmt.Fprintf(buf, `<a class="int" title="%s" href="#%s">%s</a>%s`,
						link.Comment, link.Name, link.Name, seg[l-1:])
				case len(link.Path) > 0 && len(link.Name) > 0:
					if strings.HasPrefix(link.Path, "#") {
						fmt.Fprintf(buf, `<a class="ext" title="%s" href="%s">%s</a>%s`,
							link.Comment, link.Path, link.Name, seg[l-1:])
					} else {
						if strings.Index(link.Path, "#") > -1 {
							fmt.Fprintf(buf, `<a class="ext" title="%s" target="_blank" href="%s">%s</a>%s`,
								link.Comment, link.Path, link.Name, seg[l-1:])
						} else {
							fmt.Fprintf(buf, `<a class="ext" title="%s" target="_blank" href="/%s#%s">%s</a>%s`,
								link.Comment, link.Path, link.Name, link.Name, seg[l-1:])
						}
					}
				}
			} else if seg[len(seg)-1] == ' ' || seg[len(seg)-1] == '\n' {
				if isFuncDecl || isTypeDecl {
					isTypeDecl = false
					fmt.Fprintf(buf, "%s%s", seg[:len(seg)-1], seg[:len(seg)-1], seg[l-1:])
				} else {
					fmt.Fprintf(buf, "%s", seg)
				}
			} else {
				fmt.Fprintf(buf, "%s", seg)
			}
		default:
			fmt.Fprintf(buf, "%s", seg)
		}

		last = pos + 1
		pos++
		// End of code.
		if pos == l {
			fmt.Fprintf(buf, "%s", code[last:])
			break
		}
	}

	return buf.Bytes()
}

func (r *Render) findType(name string) (*Link, bool) {
	if !com.IsLetter(name[0]) {
		return nil, false
	}

	// We cannot deal with struct field now.
	if name[len(name)-1] == '[' || name[len(name)-1] == ']' ||
		name[len(name)-1] == ' ' || name[len(name)-1] == ':' {
		return nil, false
	}

	// We cannot deal with chain operation.
	if name[0] == '.' {
		return nil, false
	}

	name = name[:len(name)-1]

	// This is for functions and types from imported packages.
	i := strings.Index(name, ".")
	// We cannot deal with struct field or chain operation now.
	if i != strings.LastIndex(name, ".") {
		return nil, false
	}

	if filte := r.FilteList[name]; filte {
		return nil, false
	}

	var left, right string
	if i > -1 {
		left = name[:i+1]
		right = name[i+1:]
	}

	for _, l := range r.Links {
		if i == -1 {
			// Exported types and functions in current package.
			if l.Name == name {
				return l, true
			}
		} else {
			// Functions and types from imported packages.
			if l.Name == left {
				if len(l.Path) > 0 {
					return &Link{Name: name, Path: "/" + l.Path + "#" + right}, true
				} else {
					return &Link{Name: name, Path: "#" + right}, true
				}
			} else if r.recv.name == left[:len(left)-1] {
				// fmt.Println(r.recv.tp + "." + right)
				// fmt.Println(r.findType(r.recv.tp + "." + right))
				return nil, false
			}
		}
	}

	r.FilteList[name] = true
	return nil, false
}

// GetLinks returns objects with its jump link.
func GetLinks(prefix string, imports []string, files map[string]File) []*Link {
	prefix += "?f="
	links := make([]*Link, 0, len(imports)+len(files)*20+10)
	for fname, f := range files {
		// Get all types, functions and import packages.
		for _, t := range f.Types {
			links = append(links, &Link{
				Name:    t.Name,
				Path:    prefix + fname,
				Comment: template.HTMLEscapeString(t.Doc),
			})

			for _, f := range t.Funcs {
				links = append(links, &Link{
					Name:    f.Name,
					Path:    prefix + fname,
					Comment: template.HTMLEscapeString(f.Doc),
				})
			}

			for _, f := range t.IFuncs {
				links = append(links, &Link{
					Name:    f.Name,
					Path:    prefix + fname,
					Comment: template.HTMLEscapeString(f.Doc),
				})
			}
		}

		for _, t := range f.Itypes {
			links = append(links, &Link{
				Name:    t.Name,
				Path:    prefix + fname,
				Comment: template.HTMLEscapeString(t.Doc),
			})

			for _, f := range t.Funcs {
				links = append(links, &Link{
					Name:    f.Name,
					Path:    prefix + fname,
					Comment: template.HTMLEscapeString(f.Doc),
				})
			}

			for _, f := range t.IFuncs {
				links = append(links, &Link{
					Name:    f.Name,
					Path:    prefix + fname,
					Comment: template.HTMLEscapeString(f.Doc),
				})
			}
		}

		for _, f := range f.Funcs {
			links = append(links, &Link{
				Name:    f.Name,
				Path:    prefix + fname,
				Comment: template.HTMLEscapeString(f.Doc),
			})
		}

		for _, f := range f.Ifuncs {
			links = append(links, &Link{
				Name:    f.Name,
				Path:    prefix + fname,
				Comment: template.HTMLEscapeString(f.Doc),
			})
		}
	}

	for _, v := range imports {
		if v != "C" {
			links = append(links, &Link{
				Name: path.Base(v) + ".",
				Path: v,
			})
		}
	}
	return links
}

func isPredeclared(name string) bool {
	_, ok := predeclared[name]
	return ok
}
<commit_msg>try to fix bug<commit_after>// Copyright 2013-2014 Unknown
//
// 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 Hacker View provides APIs to analyze Go projects and generate AST-based source code view.
package hv

import (
	"bytes"
	"errors"
	"fmt"
	"html/template"
	"path"
	"strings"

	"github.com/Unknwon/com"
)

// Render renders source code to HTML.
// Note that you have to call Build before you call this method.
func (w *Walker) Render() (map[string][]byte, error) {
	htmls := make(map[string][]byte)
	files := make(map[string]File)
	srcs := w.SrcFiles
	imports := make([]string, 0, 10)

	for name, src := range srcs {
		pkg, err := w.Build(&WalkRes{
			WalkDepth: WD_All,
			WalkType:  WT_Memory,
			WalkMode:  WM_NoReadme | WM_NoExample,
			Srcs:      []*Source{src},
			BuildAll:  true,
		})

		if err != nil {
			return nil, errors.New("hv.Walker.Render -> " + err.Error())
		}

		files[name] = pkg.File

		for _, v := range w.Pdoc.Imports {
			imports = com.AppendStr(imports, v)
		}
	}

	r := Render{
		Links:     GetLinks(w.Pdoc.ImportPath, imports, files),
		FilteList: make(map[string]bool),
	}

	for name := range srcs {
		htmls[name] = r.Render(name, srcs[name].Data())
		//com.SaveFile(name+".hmtl", htmls[name])
	}
	return htmls, nil
}

// A link describes the (HTML) link information for an identifier.
// The zero value of a link represents "no link".
type Link struct {
	Path, Name, Comment string
}

type localVar struct {
	name, tp string
}

// A Render describles a code render.
type Render struct {
	recv       localVar
	blockLevel int

	Links     []*Link
	FilteList map[string]bool
}

// Render highlights code.
func (r *Render) Render(name string, data []byte) []byte {
	if len(data) == 0 {
		return nil
	}

	code := string(data)
	l := len(code)

	buf := new(bytes.Buffer)
	//buf.WriteString("
")

	strTag := uint8(0)
	isComment := false
	isBlockComment := false
	isString := false
	isFuncDecl := false
	isFuncBlock := false
	isHasRecv := false
	isTypeDecl := false
	last := 0
	pos := 0

	for {
	CutWords:
		for {
			curChar := code[pos]
			if !com.IsLetter(curChar) {
				if isComment {
					// Comment.
					if isBlockComment {
						// Check if in end of block comment.
						if curChar == '/' && code[pos-1] == '*' {
							break CutWords
						}
					} else {
						// Check if in start of block comment.
						if curChar == '*' && code[pos-1] == '/' {
							isBlockComment = true
						} else if curChar == '\n' {
							break CutWords
						}
					}
				} else {
					// String.
					if curChar == '\'' || curChar == '"' || curChar == '`' {
						if !isString {
							// Set string tag.
							strTag = curChar
							isString = true
						} else {
							// Check if it is end of string or escaped character.
							if (code[pos-1] == '\\' && code[pos-2] == '\\') || code[pos-1] != '\\' {
								// Check string tag.
								if curChar == strTag {
									// Handle string highlight.
									break CutWords
								}
							}
						}
					}

					// FIXME: index out of range
					if len(code) <= pos {
						break CutWords
					}
					if !isString {
						switch {
						case curChar == '/' && (code[pos+1] == '/' || code[pos+1] == '*'):
							isComment = true
						case curChar > 47 && curChar < 58: // Ends with number.
						case curChar == '_' && code[pos-1] != ' ': // Underline: _.
						case (curChar != '.' || curChar == '\n'):
							break CutWords
						}
					}
				}
			}

			if pos == l-1 {
				break CutWords
			}
			pos++
		}

		seg := code[last : pos+1]
	CheckLink:
		switch {
		case isComment:
			isComment = false
			isBlockComment = false
			fmt.Fprintf(buf, `<span class="com">%s</span>`, seg)
		case isString:
			isString = false
			fmt.Fprintf(buf, `<span class="str">%s</span>`, template.HTMLEscapeString(seg))
		case seg == "\t":
			fmt.Fprintf(buf, `%s`, "    ")
		case seg == "{":
			if isFuncDecl {
				isFuncDecl = false
				isFuncBlock = true
			}

			if isFuncBlock {
				r.blockLevel++
			}
			fmt.Fprintf(buf, "%s", seg)
		case seg == "}":
			if isFuncBlock {
				r.blockLevel--
			}
			if r.blockLevel == 0 {
				isFuncBlock = false
				r.recv.name = ""
			}
			fmt.Fprintf(buf, "%s", seg)
		case isFuncDecl:
			if isHasRecv {
				if seg != "(" && seg != " " && seg != "*" {
					if len(r.recv.name) == 0 {
						r.recv.name = seg[:len(seg)-1]
					} else {
						r.recv.tp = seg[:len(seg)-1]
						isHasRecv = false
					}
				}
			} else if len(seg) > 1 && code[pos] == '(' {
				if len(r.recv.name) > 0 {
					fmt.Fprintf(buf, "%s(", r.recv.tp, seg[:len(seg)-1], seg[:len(seg)-1])
				} else {
					fmt.Fprintf(buf, "%s(", seg[:len(seg)-1], seg[:len(seg)-1])
				}
				break CheckLink
			}
			fallthrough
		case pos-last > 1:
			// Check if the last word of the paragraphy.
			l := len(seg)
			keyword := seg
			if !com.IsLetter(seg[l-1]) {
				keyword = seg[:l-1]
			} else {
				l++
			}

			// Check keywords.
			switch keyword {
			case "return", "break":
				fmt.Fprintf(buf, `<span class="ret">%s</span>%s`, keyword, seg[l-1:])
				break CheckLink
			case "func":
				isFuncDecl = true
				if code[pos+1] == '(' {
					isHasRecv = true
				}
				fallthrough
			case "package", "import", "range", "for", "if", "else", "type", "struct", "select", "case", "var", "const", "switch", "default", "continue":
				if keyword == "type" {
					isTypeDecl = true
				}
				fmt.Fprintf(buf, `<span class="key">%s</span>%s`, keyword, seg[l-1:])
				break CheckLink
			case "new", "append", "make", "panic", "recover", "len", "cap", "copy", "close", "delete", "defer":
				fmt.Fprintf(buf, `<span class="bui">%s</span>%s`, keyword, seg[l-1:])
				break CheckLink
			}

			if isPredeclared(keyword) {
				fmt.Fprintf(buf, `<span class="boo">%s</span>%s`, keyword, seg[l-1:])
				break CheckLink
			}

			// Check links.
			link, ok := r.findType(seg)
			if ok {
				switch {
				case strings.HasSuffix(link.Path, name) && len(link.Name) > 0: // Current file.
					fmt.Fprintf(buf, `<a class="int" title="%s" href="#%s">%s</a>%s`,
						link.Comment, link.Name, link.Name, seg[l-1:])
				case len(link.Path) > 0 && len(link.Name) > 0:
					if strings.HasPrefix(link.Path, "#") {
						fmt.Fprintf(buf, `<a class="ext" title="%s" href="%s">%s</a>%s`,
							link.Comment, link.Path, link.Name, seg[l-1:])
					} else {
						if strings.Index(link.Path, "#") > -1 {
							fmt.Fprintf(buf, `<a class="ext" title="%s" target="_blank" href="%s">%s</a>%s`,
								link.Comment, link.Path, link.Name, seg[l-1:])
						} else {
							fmt.Fprintf(buf, `<a class="ext" title="%s" target="_blank" href="/%s#%s">%s</a>%s`,
								link.Comment, link.Path, link.Name, link.Name, seg[l-1:])
						}
					}
				}
			} else if seg[len(seg)-1] == ' ' || seg[len(seg)-1] == '\n' {
				if isFuncDecl || isTypeDecl {
					isTypeDecl = false
					fmt.Fprintf(buf, "%s%s", seg[:len(seg)-1], seg[:len(seg)-1], seg[l-1:])
				} else {
					fmt.Fprintf(buf, "%s", seg)
				}
			} else {
				fmt.Fprintf(buf, "%s", seg)
			}
		default:
			fmt.Fprintf(buf, "%s", seg)
		}

		last = pos + 1
		pos++
		// End of code.
		if pos == l {
			fmt.Fprintf(buf, "%s", code[last:])
			break
		}
	}

	return buf.Bytes()
}

func (r *Render) findType(name string) (*Link, bool) {
	if !com.IsLetter(name[0]) {
		return nil, false
	}

	// We cannot deal with struct field now.
	if name[len(name)-1] == '[' || name[len(name)-1] == ']' ||
		name[len(name)-1] == ' ' || name[len(name)-1] == ':' {
		return nil, false
	}

	// We cannot deal with chain operation.
	if name[0] == '.' {
		return nil, false
	}

	name = name[:len(name)-1]

	// This is for functions and types from imported packages.
	i := strings.Index(name, ".")
	// We cannot deal with struct field or chain operation now.
	if i != strings.LastIndex(name, ".") {
		return nil, false
	}

	if filte := r.FilteList[name]; filte {
		return nil, false
	}

	var left, right string
	if i > -1 {
		left = name[:i+1]
		right = name[i+1:]
	}

	for _, l := range r.Links {
		if i == -1 {
			// Exported types and functions in current package.
			if l.Name == name {
				return l, true
			}
		} else {
			// Functions and types from imported packages.
			if l.Name == left {
				if len(l.Path) > 0 {
					return &Link{Name: name, Path: "/" + l.Path + "#" + right}, true
				} else {
					return &Link{Name: name, Path: "#" + right}, true
				}
			} else if r.recv.name == left[:len(left)-1] {
				// fmt.Println(r.recv.tp + "." + right)
				// fmt.Println(r.findType(r.recv.tp + "." + right))
				return nil, false
			}
		}
	}

	r.FilteList[name] = true
	return nil, false
}

// GetLinks returns objects with its jump link.
func GetLinks(prefix string, imports []string, files map[string]File) []*Link {
	prefix += "?f="
	links := make([]*Link, 0, len(imports)+len(files)*20+10)
	for fname, f := range files {
		// Get all types, functions and import packages.
		for _, t := range f.Types {
			links = append(links, &Link{
				Name:    t.Name,
				Path:    prefix + fname,
				Comment: template.HTMLEscapeString(t.Doc),
			})

			for _, f := range t.Funcs {
				links = append(links, &Link{
					Name:    f.Name,
					Path:    prefix + fname,
					Comment: template.HTMLEscapeString(f.Doc),
				})
			}

			for _, f := range t.IFuncs {
				links = append(links, &Link{
					Name:    f.Name,
					Path:    prefix + fname,
					Comment: template.HTMLEscapeString(f.Doc),
				})
			}
		}

		for _, t := range f.Itypes {
			links = append(links, &Link{
				Name:    t.Name,
				Path:    prefix + fname,
				Comment: template.HTMLEscapeString(t.Doc),
			})

			for _, f := range t.Funcs {
				links = append(links, &Link{
					Name:    f.Name,
					Path:    prefix + fname,
					Comment: template.HTMLEscapeString(f.Doc),
				})
			}

			for _, f := range t.IFuncs {
				links = append(links, &Link{
					Name:    f.Name,
					Path:    prefix + fname,
					Comment: template.HTMLEscapeString(f.Doc),
				})
			}
		}

		for _, f := range f.Funcs {
			links = append(links, &Link{
				Name:    f.Name,
				Path:    prefix + fname,
				Comment: template.HTMLEscapeString(f.Doc),
			})
		}

		for _, f := range f.Ifuncs {
			links = append(links, &Link{
				Name:    f.Name,
				Path:    prefix + fname,
				Comment: template.HTMLEscapeString(f.Doc),
			})
		}
	}

	for _, v := range imports {
		if v != "C" {
			links = append(links, &Link{
				Name: path.Base(v) + ".",
				Path: v,
			})
		}
	}
	return links
}

func isPredeclared(name string) bool {
	_, ok := predeclared[name]
	return ok
}
<|endoftext|>


<commit_before>package main

import "encoding/json"
import "flag"
import "fmt"
import "io/ioutil"
import "math/rand"
import "time"
import "os"
import "runtime"

func main() {
	numRenderJobs := flag.Int(
		"j", runtime.NumCPU(), "how many render jobs to spawn")

	flag.Parse()

	runtime.GOMAXPROCS(*numRenderJobs)

	seed := time.Now().UTC().UnixNano()
	rng := rand.New(rand.NewSource(seed))

	if flag.NArg() < 1 {
		fmt.Fprintf(
			os.Stderr, "%s [options] [scene.json...]\n",
			os.Args[0])
		flag.PrintDefaults()
		os.Exit(-1)
	}

	for i := 0; i < flag.NArg(); i++ {
		inputPath := flag.Arg(i)
		fmt.Printf(
			"Processing %s (%d/%d)...\n",
			inputPath, i+1, flag.NArg())
		configBytes, err := ioutil.ReadFile(inputPath)
		if err != nil {
			panic(err)
		}
		var config map[string]interface{}
		err = json.Unmarshal(configBytes, &config)
		if err != nil {
			panic(err)
		}
		sceneConfig := config["scene"].(map[string]interface{})
		scene := MakeScene(sceneConfig)
		rendererConfig := config["renderer"].(map[string]interface{})
		renderer := MakeRenderer(rendererConfig)
		renderer.Render(*numRenderJobs, rng, &scene)
	}
}
<commit_msg>Add flag to write a CPU profile<commit_after>package main

import "encoding/json"
import "flag"
import "fmt"
import "io/ioutil"
import "math/rand"
import "time"
import "os"
import "runtime"
import "runtime/pprof"

func main() {
	numRenderJobs := flag.Int(
		"j", runtime.NumCPU(), "how many render jobs to spawn")

	profilePath := flag.String(
		"p", "", "if non-empty, path to write the cpu profile to")

	flag.Parse()

	if len(*profilePath) > 0 {
		f, err := os.Create(*profilePath)
		if err != nil {
			panic(err)
		}
		defer func() {
			if err := f.Close(); err != nil {
				panic(err)
			}
		}()

		pprof.StartCPUProfile(f)
		defer pprof.StopCPUProfile()
	}

	runtime.GOMAXPROCS(*numRenderJobs)

	seed := time.Now().UTC().UnixNano()
	rng := rand.New(rand.NewSource(seed))

	if flag.NArg() < 1 {
		fmt.Fprintf(
			os.Stderr, "%s [options] [scene.json...]\n",
			os.Args[0])
		flag.PrintDefaults()
		os.Exit(-1)
	}

	for i := 0; i < flag.NArg(); i++ {
		inputPath := flag.Arg(i)
		fmt.Printf(
			"Processing %s (%d/%d)...\n",
			inputPath, i+1, flag.NArg())
		configBytes, err := ioutil.ReadFile(inputPath)
		if err != nil {
			panic(err)
		}
		var config map[string]interface{}
		err = json.Unmarshal(configBytes, &config)
		if err != nil {
			panic(err)
		}
		sceneConfig := config["scene"].(map[string]interface{})
		scene := MakeScene(sceneConfig)
		rendererConfig := config["renderer"].(map[string]interface{})
		renderer := MakeRenderer(rendererConfig)
		renderer.Render(*numRenderJobs, rng, &scene)
	}
}
<|endoftext|>


<commit_before>package indexer

import (
	"sync"
	"sort"
)

// Index is a single index.
type Index struct {
	keys []IndexElement
	m sync.RWMutex
}

//NewIndex creates an Index instance
func NewIndex() *Index {
	index := new(Index)
	index.keys = []IndexElement{}
	return index
}

//Len returns length of the index
func (in *Index) Len() int {
	return len(in.keys)
}

//Less inompares values
func (in *Index) Less(i, j int) bool {
	return in.keys[i].Less(in.keys[j])
}

//Swap swaps IndexElements in list
func (in *Index) Swap(i, j int) {
	in.keys[i], in.keys[j] = in.keys[j], in.keys[i]
}

//Add adds a single IndexElement
func (in *Index) Add(element IndexElement) {
	in.m.Lock()
	defer in.m.Unlock()
	location := 0
	for key, index := range in.keys {
		if element.Less(index) {
			location = key
		} else {
			in.keys = append(in.keys[:location], element, in.keys[key:]...)
			return
		}
	}
}

//Remove deletes a single IndexElement
func (in *Index) Remove(element IndexElement) {
	in.m.Lock()
	defer in.m.Unlock()
	for key, index := range in.keys {
		if element.Key() == index.Key() {
			in.keys = append(in.keys[:key], in.keys[key+1:]...)
			return
		}
	}
}

//Sort sorts IndexElement list
func (in *Index) Sort() {
	in.m.Lock()
	defer in.m.Unlock()
	sort.Sort(in)
}
<commit_msg>Fix "too many arguments to append" error<commit_after>package indexer

import (
	"sync"
	"sort"
)

// Index is a single index.
type Index struct {
	keys []IndexElement
	m sync.RWMutex
}

//NewIndex creates an Index instance
func NewIndex() *Index {
	index := new(Index)
	index.keys = []IndexElement{}
	return index
}

//Len returns length of the index
func (in *Index) Len() int {
	return len(in.keys)
}

//Less inompares values
func (in *Index) Less(i, j int) bool {
	return in.keys[i].Less(in.keys[j])
}

//Swap swaps IndexElements in list
func (in *Index) Swap(i, j int) {
	in.keys[i], in.keys[j] = in.keys[j], in.keys[i]
}

//Add adds a single IndexElement
func (in *Index) Add(element IndexElement) {
	in.m.Lock()
	defer in.m.Unlock()
	location := 0
	for key, index := range in.keys {
		if element.Less(index) {
			location = key
		} else {
			before := append(in.keys[:location], element)
			in.keys = append(before, in.keys[key:]...)
			return
		}
	}
}

//Remove deletes a single IndexElement
func (in *Index) Remove(element IndexElement) {
	in.m.Lock()
	defer in.m.Unlock()
	for key, index := range in.keys {
		if element.Key() == index.Key() {
			in.keys = append(in.keys[:key], in.keys[key+1:]...)
			return
		}
	}
}

//Sort sorts IndexElement list
func (in *Index) Sort() {
	in.m.Lock()
	defer in.m.Unlock()
	sort.Sort(in)
}
<|endoftext|>


<commit_before>package git

/*
#cgo pkg-config: libgit2
#include <git2.h>
#include <git2/errors.h>
*/
import "C"
import (
	"fmt"
	"runtime"
	"time"
	"unsafe"
)

type Index struct {
	ptr *C.git_index
}

type IndexEntry struct {
	Ctime time.Time
	Mtime time.Time
	Mode  uint
	Uid   uint
	Gid   uint
	Size  uint
	Oid   *Oid
	Path  string
}

func newIndexFromC(ptr *C.git_index) *Index {
	idx := &Index{ptr}
	runtime.SetFinalizer(idx, (*Index).Free)
	return idx
}

func (v *Index) AddByPath(path string) error {
	cstr := C.CString(path)
	defer C.free(unsafe.Pointer(cstr))

	ret := C.git_index_add_bypath(v.ptr, cstr)
	if ret < 0 {
		return LastError()
	}

	return nil
}

func (v *Index) WriteTree() (*Oid, error) {
	oid := new(Oid)
	ret := C.git_index_write_tree(oid.toC(), v.ptr)
	if ret < 0 {
		return nil, LastError()
	}

	return oid, nil
}

func (v *Index) Free() {
	runtime.SetFinalizer(v, nil)
	C.git_index_free(v.ptr)
}

func (v *Index) EntryCount() uint {
	return uint(C.git_index_entrycount(v.ptr))
}

func newIndexEntryFromC(entry *C.git_index_entry) *IndexEntry {
	return &IndexEntry{
		time.Unix(int64(entry.ctime.seconds), int64(entry.ctime.nanoseconds)),
		time.Unix(int64(entry.mtime.seconds), int64(entry.mtime.nanoseconds)),
		uint(entry.mode),
		uint(entry.uid),
		uint(entry.gid),
		uint(entry.file_size),
		newOidFromC(&entry.oid),
		C.GoString(entry.path),
	}
}

func (v *Index) EntryByIndex(index uint) (*IndexEntry, error) {
	centry := C.git_index_get_byindex(v.ptr, C.size_t(index))
	if centry == nil {
		return nil, fmt.Errorf("Index out of Bounds")
	}
	return newIndexEntryFromC(centry), nil
}
<commit_msg>Adjust to oid -> id<commit_after>package git

/*
#cgo pkg-config: libgit2
#include <git2.h>
#include <git2/errors.h>
*/
import "C"
import (
	"fmt"
	"runtime"
	"time"
	"unsafe"
)

type Index struct {
	ptr *C.git_index
}

type IndexEntry struct {
	Ctime time.Time
	Mtime time.Time
	Mode  uint
	Uid   uint
	Gid   uint
	Size  uint
	Id   *Oid
	Path  string
}

func newIndexFromC(ptr *C.git_index) *Index {
	idx := &Index{ptr}
	runtime.SetFinalizer(idx, (*Index).Free)
	return idx
}

func (v *Index) AddByPath(path string) error {
	cstr := C.CString(path)
	defer C.free(unsafe.Pointer(cstr))

	ret := C.git_index_add_bypath(v.ptr, cstr)
	if ret < 0 {
		return LastError()
	}

	return nil
}

func (v *Index) WriteTree() (*Oid, error) {
	oid := new(Oid)
	ret := C.git_index_write_tree(oid.toC(), v.ptr)
	if ret < 0 {
		return nil, LastError()
	}

	return oid, nil
}

func (v *Index) Free() {
	runtime.SetFinalizer(v, nil)
	C.git_index_free(v.ptr)
}

func (v *Index) EntryCount() uint {
	return uint(C.git_index_entrycount(v.ptr))
}

func newIndexEntryFromC(entry *C.git_index_entry) *IndexEntry {
	return &IndexEntry{
		time.Unix(int64(entry.ctime.seconds), int64(entry.ctime.nanoseconds)),
		time.Unix(int64(entry.mtime.seconds), int64(entry.mtime.nanoseconds)),
		uint(entry.mode),
		uint(entry.uid),
		uint(entry.gid),
		uint(entry.file_size),
		newOidFromC(&entry.id),
		C.GoString(entry.path),
	}
}

func (v *Index) EntryByIndex(index uint) (*IndexEntry, error) {
	centry := C.git_index_get_byindex(v.ptr, C.size_t(index))
	if centry == nil {
		return nil, fmt.Errorf("Index out of Bounds")
	}
	return newIndexEntryFromC(centry), nil
}
<|endoftext|>


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

// Utility functions.

package ioutil

import (
	"bytes"
	"io"
	"os"
	"sort"
)

// ReadAll reads from r until an error or EOF and returns the data it read.
func ReadAll(r io.Reader) ([]byte, os.Error) {
	var buf bytes.Buffer
	_, err := io.Copy(&buf, r)
	return buf.Bytes(), err
}

// ReadFile reads the file named by filename and returns the contents.
func ReadFile(filename string) ([]byte, os.Error) {
	f, err := os.Open(filename, os.O_RDONLY, 0)
	if err != nil {
		return nil, err
	}
	defer f.Close()
	// It's a good but not certain bet that Stat will tell us exactly how much to
	// read, so let's try it but be prepared for the answer to be wrong.
	dir, err := f.Stat()
	var n uint64
	if err != nil && dir.Size < 2e9 { // Don't preallocate a huge buffer, just in case.
		n = dir.Size
	}
	// Add a little extra in case Size is zero, and to avoid another allocation after
	// Read has filled the buffer.
	n += bytes.MinRead
	// Pre-allocate the correct size of buffer, then set its size to zero.  The
	// Buffer will read into the allocated space cheaply.  If the size was wrong,
	// we'll either waste some space off the end or reallocate as needed, but
	// in the overwhelmingly common case we'll get it just right.
	buf := bytes.NewBuffer(make([]byte, 0, n))
	_, err = buf.ReadFrom(f)
	return buf.Bytes(), err
}

// WriteFile writes data to a file named by filename.
// If the file does not exist, WriteFile creates it with permissions perm;
// otherwise WriteFile truncates it before writing.
func WriteFile(filename string, data []byte, perm int) os.Error {
	f, err := os.Open(filename, os.O_WRONLY|os.O_CREAT|os.O_TRUNC, perm)
	if err != nil {
		return err
	}
	n, err := f.Write(data)
	f.Close()
	if err == nil && n < len(data) {
		err = io.ErrShortWrite
	}
	return err
}

// A dirList implements sort.Interface.
type dirList []*os.Dir

func (d dirList) Len() int           { return len(d) }
func (d dirList) Less(i, j int) bool { return d[i].Name < d[j].Name }
func (d dirList) Swap(i, j int)      { d[i], d[j] = d[j], d[i] }

// ReadDir reads the directory named by dirname and returns
// a list of sorted directory entries.
func ReadDir(dirname string) ([]*os.Dir, os.Error) {
	f, err := os.Open(dirname, os.O_RDONLY, 0)
	if err != nil {
		return nil, err
	}
	list, err := f.Readdir(-1)
	f.Close()
	if err != nil {
		return nil, err
	}
	dirs := make(dirList, len(list))
	for i := range list {
		dirs[i] = &list[i]
	}
	sort.Sort(dirs)
	return dirs, nil
}
<commit_msg>io/ioutil: fix bug in ReadFile when Open succeeds but Stat fails<commit_after>// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Utility functions.

package ioutil

import (
	"bytes"
	"io"
	"os"
	"sort"
)

// ReadAll reads from r until an error or EOF and returns the data it read.
func ReadAll(r io.Reader) ([]byte, os.Error) {
	var buf bytes.Buffer
	_, err := io.Copy(&buf, r)
	return buf.Bytes(), err
}

// ReadFile reads the file named by filename and returns the contents.
func ReadFile(filename string) ([]byte, os.Error) {
	f, err := os.Open(filename, os.O_RDONLY, 0)
	if err != nil {
		return nil, err
	}
	defer f.Close()
	// It's a good but not certain bet that Stat will tell us exactly how much to
	// read, so let's try it but be prepared for the answer to be wrong.
	dir, err := f.Stat()
	var n uint64
	if err == nil && dir.Size < 2e9 { // Don't preallocate a huge buffer, just in case.
		n = dir.Size
	}
	// Add a little extra in case Size is zero, and to avoid another allocation after
	// Read has filled the buffer.
	n += bytes.MinRead
	// Pre-allocate the correct size of buffer, then set its size to zero.  The
	// Buffer will read into the allocated space cheaply.  If the size was wrong,
	// we'll either waste some space off the end or reallocate as needed, but
	// in the overwhelmingly common case we'll get it just right.
	buf := bytes.NewBuffer(make([]byte, 0, n))
	_, err = buf.ReadFrom(f)
	return buf.Bytes(), err
}

// WriteFile writes data to a file named by filename.
// If the file does not exist, WriteFile creates it with permissions perm;
// otherwise WriteFile truncates it before writing.
func WriteFile(filename string, data []byte, perm int) os.Error {
	f, err := os.Open(filename, os.O_WRONLY|os.O_CREAT|os.O_TRUNC, perm)
	if err != nil {
		return err
	}
	n, err := f.Write(data)
	f.Close()
	if err == nil && n < len(data) {
		err = io.ErrShortWrite
	}
	return err
}

// A dirList implements sort.Interface.
type dirList []*os.Dir

func (d dirList) Len() int           { return len(d) }
func (d dirList) Less(i, j int) bool { return d[i].Name < d[j].Name }
func (d dirList) Swap(i, j int)      { d[i], d[j] = d[j], d[i] }

// ReadDir reads the directory named by dirname and returns
// a list of sorted directory entries.
func ReadDir(dirname string) ([]*os.Dir, os.Error) {
	f, err := os.Open(dirname, os.O_RDONLY, 0)
	if err != nil {
		return nil, err
	}
	list, err := f.Readdir(-1)
	f.Close()
	if err != nil {
		return nil, err
	}
	dirs := make(dirList, len(list))
	for i := range list {
		dirs[i] = &list[i]
	}
	sort.Sort(dirs)
	return dirs, nil
}
<|endoftext|>


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

package net_test

import (
	"io"
	"log"
	"net"
)

func ExampleListener() {
	// Listen on TCP port 2000 on all interfaces.
	l, err := net.Listen("tcp", ":2000")
	if err != nil {
		log.Fatal(err)
	}
	for {
		// Wait for a connection.
		conn, err := l.Accept()
		if err != nil {
			log.Fatal(err)
		}
		// Handle the connection in a new goroutine.
		// The loop then returns to accepting, so that
		// multiple connections may be served concurrently.
		go func(c net.Conn) {
			// Echo all incoming data.
			io.Copy(c, c)
			// Shut down the connection.
			c.Close()
		}(conn)
	}
}
<commit_msg>net: close TCPListener in example<commit_after>// Copyright 2012 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package net_test

import (
	"io"
	"log"
	"net"
)

func ExampleListener() {
	// Listen on TCP port 2000 on all interfaces.
	l, err := net.Listen("tcp", ":2000")
	if err != nil {
		log.Fatal(err)
	}
	defer l.Close()
	for {
		// Wait for a connection.
		conn, err := l.Accept()
		if err != nil {
			log.Fatal(err)
		}
		// Handle the connection in a new goroutine.
		// The loop then returns to accepting, so that
		// multiple connections may be served concurrently.
		go func(c net.Conn) {
			// Echo all incoming data.
			io.Copy(c, c)
			// Shut down the connection.
			c.Close()
		}(conn)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"code.cloudfoundry.org/bytefmt"
	"net"
	"time"
)

var last_ring_time time.Time

type busyFunc func() bool

// Is the network connection inbound or outbound
const (
	INBOUND = iota
	OUTBOUND
)

// Interface specification for a connection
type connection interface {
	Read(p []byte) (int, error)
	Write(p []byte) (int, error)
	Close() error
	RemoteAddr() net.Addr
	Direction() int // INBOUND or OUTBOUND
	Mode() bool      // What command mode to be in after connection
	SetMode(bool)
	Stats() (uint64, uint64)
	String() string
	SetDeadline(t time.Time) error
}

// How many rings before giving up
const __MAX_RINGS = 15

// How long to wait for the remote to answer.  6 seconds is the default
// ring-silence time
const __CONNECT_TIMEOUT = __MAX_RINGS * 6 * time.Second

func answerIncomming(conn connection) bool {
	const __DELAY_MS = 20

	zero := make([]byte, 1)
	zero[0] = 0

	r := registers
	for i := 0; i < __MAX_RINGS; i++ {
		last_ring_time = time.Now()
		conn.Write([]byte("Ringing...\n\r"))
		logger.Print("Ringing")
		if offHook() { // computer has issued 'ATA'
			goto answered
		}

		// Simulate the "2-4" pattern for POTS ring signal (2
		// seconds of high voltage ring signal, 4 seconds
		// of silence)

		// Ring for 2s
		d := 0
		raiseRI()
		for onHook() && d < 2000 {
			if _, err := conn.Write(zero); err != nil {
				goto no_answer
			}
			time.Sleep(__DELAY_MS * time.Millisecond)
			d += __DELAY_MS
			if offHook() { // computer has issued 'ATA'
				goto answered
			}
		}
		lowerRI()

		// By verification, the Hayes Ultra 96 displays the
		// "RING" text /after/ the RI signal is lowered.  So
		// do this here so we behave the same.
		serial.Println(RING)

		// If Auto Answer is enabled and we've exceeded the
		// configured number of rings to wait before
		// answering, answer the call.  We do this here before
		// the 4s delay as I think it feels more correct.
		ringCount := r.Inc(REG_RING_COUNT)
		aaCount := r.Read(REG_AUTO_ANSWER)
		if aaCount > 0 {
			if ringCount >= aaCount {
				logger.Print("Auto answering")
				answer()
			}
		}

		// Silence for 4s
		d = 0
		for onHook() && d < 4000 {
			// Test for closed connection
			if _, err := conn.Write(zero); err != nil {
				goto no_answer
			}

			time.Sleep(__DELAY_MS * time.Millisecond)
			d += __DELAY_MS
			if offHook() { // computer has issued 'ATA'
				goto answered
			}
		}
	}

no_answer:
	// At this point we've not answered and have timed out, or the
	// caller hung up before we answered.
	logger.Print("No answer")
	conn.Write([]byte("No answer, closing connection\n\r"))
	lowerRI()
	return false

answered:
	// if we're here, the computer answered.
	logger.Print("Answered")
	conn.Write([]byte("Answered\n\r"))
	registers.Write(REG_RING_COUNT, 0)
	lowerRI()
	return true
}

func startAcceptingCalls() {
	started_ok := make(chan error)

	if flags.skipTelnet {
		logger.Print("Telnet server not started by command line flag")
	} else {
		go acceptTelnet(callChannel, checkBusy, logger, started_ok)
		if err := <-started_ok; err != nil {
			logger.Printf("Telnet server failed to start: %s", err)
		} else {
			logger.Print("Telnet server started")
		}
	}

	if flags.skipSSH {
		logger.Print("SSH server not started by command line flag")
	} else {
		go acceptSSH(callChannel, flags.privateKey, checkBusy, logger,
			started_ok)
		if err := <-started_ok; err != nil {
			logger.Printf("SSH server failed to start: %s", err)
		} else {
			logger.Print("SSH server started")
		}
	}
}

// Clear the ring counter after 8s
// Must be a goroutine
func clearRingCounter() {
	delay := 8 * time.Second
	t := time.Tick(delay)
	for range t {
		if time.Since(last_ring_time) >= delay {
			registers.Write(REG_RING_COUNT, 0)
		}
	}
}

// Pass bytes from the remote dialer to the serial port (for now,
// stdout) as long as we're offhook, we're in DATA MODE and we have
// valid carrier (m.comm != nil)
func serviceConnection() {
	var t time.Time
	var timeout time.Duration

	logger.Printf("Servicing connection with remote %s", m.conn.RemoteAddr())

	buf := make([]byte, 1)
	for {
		// If S30 is non-zero, set a timeout
		b := registers.Read(REG_INACTIVITY_TIMER)
		timeout = time.Duration(b) * 10 * time.Second
		if timeout == time.Duration(0) {
			t = time.Time{}
		} else {
			t = time.Now().Add(timeout)
		}
		if err := m.conn.SetDeadline(t); err != nil {
			logger.Printf("conn.SetDeadline(): %s", err)
			return
		}

		if _, err := m.conn.Read(buf); err != nil { // Remote hung up or ...
			nerr, ok := err.(net.Error)	    // we timed out.
			switch {
			case ok && nerr.Timeout():
				logger.Printf("conn.Read(): S30 timeout: %s",
					timeout)
			case ok && nerr.Temporary():
				logger.Printf("conn.Read(): temporary errory")
				continue
			default:
				logger.Print("conn.Read(): ", err)
			}
			return
		}

		if m.dcd == false {
			logger.Print("conn.Read(): No carrier at network read")
			return
		}

		if onHook() {
			logger.Print("conn.Read(): On hook at network read")
			return
		}

		// Send the byte to the DTE, blink the RD LED
		if m.mode == DATAMODE {
			led_RD_on()
			serial.Write(buf)
			led_RD_off()
		}
	}
}

// Accept connection's from dial*() and accept*() functions.
func handleCalls() {
	go clearRingCounter()
	startAcceptingCalls()

	// Wait for a connection.  If it's an incoming call, answer
	// it.  If it's an outgoing call or an answered incoming call,
	// service it
	var conn connection
	for {
		conn = <-callChannel
		setLineBusy(true)

		switch conn.Direction() {
		case INBOUND:
			logger.Printf("Incomming call from %s", conn.RemoteAddr())
			if !answerIncomming(conn) {
				conn.Close()
				continue
			}
		case OUTBOUND:
			logger.Printf("Outgoing call to %s ", conn.RemoteAddr())
		}

		// We now have an established connection (either answered or dialed)
		// so service it.
		m.conn = conn
		m.mode = conn.Mode()
		m.connectSpeed = 38400
		m.dcd = true	// Force DCD "up" here.
		serviceConnection()

		if m.dcd == true { // User didn't hang up, so print status
			serial.Printf("\n")
			prstatus(NO_CARRIER)
		}
		sent, recv := m.conn.Stats()
		conn.Close()
		m.conn = nil
		hangup()
		setLineBusy(false)
		logger.Printf("Connection closed, sent %s recv %s",
			bytefmt.ByteSize(sent), bytefmt.ByteSize(recv))

	}
}
<commit_msg>Proposed fix for issue #36, untested<commit_after>package main

import (
	"code.cloudfoundry.org/bytefmt"
	"net"
	"time"
)

var last_ring_time time.Time

type busyFunc func() bool

// Is the network connection inbound or outbound
const (
	INBOUND = iota
	OUTBOUND
)

// Interface specification for a connection
type connection interface {
	Read(p []byte) (int, error)
	Write(p []byte) (int, error)
	Close() error
	RemoteAddr() net.Addr
	Direction() int // INBOUND or OUTBOUND
	Mode() bool      // What command mode to be in after connection
	SetMode(bool)
	Stats() (uint64, uint64)
	String() string
	SetDeadline(t time.Time) error
}

// How many rings before giving up
const __MAX_RINGS = 15

// How long to wait for the remote to answer.  6 seconds is the default
// ring-silence time
const __CONNECT_TIMEOUT = __MAX_RINGS * 6 * time.Second

func answerIncomming(conn connection) bool {
	const __DELAY_MS = 20

	zero := make([]byte, 1)
	zero[0] = 0

	r := registers
	for i := 0; i < __MAX_RINGS; i++ {
		last_ring_time = time.Now()
		conn.Write([]byte("Ringing...\n\r"))
		logger.Print("Ringing")
		if offHook() { // computer has issued 'ATA'
			goto answered
		}

		// Simulate the "2-4" pattern for POTS ring signal (2
		// seconds of high voltage ring signal, 4 seconds
		// of silence)

		// Ring for 2s
		d := 0
		raiseRI()
		for onHook() && d < 2000 {
			if _, err := conn.Write(zero); err != nil {
				goto no_answer
			}
			time.Sleep(__DELAY_MS * time.Millisecond)
			d += __DELAY_MS
			if offHook() { // computer has issued 'ATA'
				goto answered
			}
		}
		lowerRI()

		// By verification, the Hayes Ultra 96 displays the
		// "RING" text /after/ the RI signal is lowered.  So
		// do this here so we behave the same.
		serial.Println(RING)

		// If Auto Answer is enabled and we've exceeded the
		// configured number of rings to wait before
		// answering, answer the call.  We do this here before
		// the 4s delay as I think it feels more correct.
		ringCount := r.Inc(REG_RING_COUNT)
		aaCount := r.Read(REG_AUTO_ANSWER)
		if aaCount > 0 {
			if ringCount >= aaCount {
				logger.Print("Auto answering")
				answer()
			}
		}

		// Silence for 4s
		d = 0
		for onHook() && d < 4000 {
			// Test for closed connection
			if _, err := conn.Write(zero); err != nil {
				goto no_answer
			}

			time.Sleep(__DELAY_MS * time.Millisecond)
			d += __DELAY_MS
			if offHook() { // computer has issued 'ATA'
				goto answered
			}
		}
	}

no_answer:
	// At this point we've not answered and have timed out, or the
	// caller hung up before we answered.
	logger.Print("No answer")
	conn.Write([]byte("No answer, closing connection\n\r"))
	lowerRI()
	return false

answered:
	// if we're here, the computer answered.
	logger.Print("Answered")
	conn.Write([]byte("Answered\n\r"))
	registers.Write(REG_RING_COUNT, 0)
	lowerRI()
	raiseDSR()
	raiseCTS()
	return true
}

func startAcceptingCalls() {
	started_ok := make(chan error)

	if flags.skipTelnet {
		logger.Print("Telnet server not started by command line flag")
	} else {
		go acceptTelnet(callChannel, checkBusy, logger, started_ok)
		if err := <-started_ok; err != nil {
			logger.Printf("Telnet server failed to start: %s", err)
		} else {
			logger.Print("Telnet server started")
		}
	}

	if flags.skipSSH {
		logger.Print("SSH server not started by command line flag")
	} else {
		go acceptSSH(callChannel, flags.privateKey, checkBusy, logger,
			started_ok)
		if err := <-started_ok; err != nil {
			logger.Printf("SSH server failed to start: %s", err)
		} else {
			logger.Print("SSH server started")
		}
	}
}

// Clear the ring counter after 8s
// Must be a goroutine
func clearRingCounter() {
	delay := 8 * time.Second
	t := time.Tick(delay)
	for range t {
		if time.Since(last_ring_time) >= delay {
			registers.Write(REG_RING_COUNT, 0)
		}
	}
}

// Pass bytes from the remote dialer to the serial port (for now,
// stdout) as long as we're offhook, we're in DATA MODE and we have
// valid carrier (m.comm != nil)
func serviceConnection() {
	var t time.Time
	var timeout time.Duration

	logger.Printf("Servicing connection with remote %s", m.conn.RemoteAddr())

	buf := make([]byte, 1)
	for {
		// If S30 is non-zero, set a timeout
		b := registers.Read(REG_INACTIVITY_TIMER)
		timeout = time.Duration(b) * 10 * time.Second
		if timeout == time.Duration(0) {
			t = time.Time{}
		} else {
			t = time.Now().Add(timeout)
		}
		if err := m.conn.SetDeadline(t); err != nil {
			logger.Printf("conn.SetDeadline(): %s", err)
			return
		}

		if _, err := m.conn.Read(buf); err != nil { // Remote hung up or ...
			nerr, ok := err.(net.Error)	    // we timed out.
			switch {
			case ok && nerr.Timeout():
				logger.Printf("conn.Read(): S30 timeout: %s",
					timeout)
			case ok && nerr.Temporary():
				logger.Printf("conn.Read(): temporary errory")
				continue
			default:
				logger.Print("conn.Read(): ", err)
			}
			return
		}

		if m.dcd == false {
			logger.Print("conn.Read(): No carrier at network read")
			return
		}

		if onHook() {
			logger.Print("conn.Read(): On hook at network read")
			return
		}

		// Send the byte to the DTE, blink the RD LED
		if m.mode == DATAMODE {
			led_RD_on()
			serial.Write(buf)
			led_RD_off()
		}
	}
}

// Accept connection's from dial*() and accept*() functions.
func handleCalls() {
	go clearRingCounter()
	startAcceptingCalls()

	// Wait for a connection.  If it's an incoming call, answer
	// it.  If it's an outgoing call or an answered incoming call,
	// service it
	var conn connection
	for {
		conn = <-callChannel
		setLineBusy(true)

		switch conn.Direction() {
		case INBOUND:
			logger.Printf("Incomming call from %s", conn.RemoteAddr())
			if !answerIncomming(conn) {
				conn.Close()
				continue
			}
		case OUTBOUND:
			logger.Printf("Outgoing call to %s ", conn.RemoteAddr())
		}

		// We now have an established connection (either answered or dialed)
		// so service it.
		m.conn = conn
		m.mode = conn.Mode()
		m.connectSpeed = 38400
		m.dcd = true	// Force DCD "up" here.
		serviceConnection()

		if m.dcd == true { // User didn't hang up, so print status
			serial.Printf("\n")
			prstatus(NO_CARRIER)
		}
		sent, recv := m.conn.Stats()
		conn.Close()
		m.conn = nil
		hangup()
		setLineBusy(false)
		logger.Printf("Connection closed, sent %s recv %s",
			bytefmt.ByteSize(sent), bytefmt.ByteSize(recv))

	}
}
<|endoftext|>


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

// Package build gathers information about Go packages.
//
// Go Path
//
// The Go path is a list of directory trees containing Go source code.
// It is consulted to resolve imports that cannot be found in the standard
// Go tree.  The default path is the value of the GOPATH environment
// variable, interpreted as a path list appropriate to the operating system
// (on Unix, the variable is a colon-separated string;
// on Windows, a semicolon-separated string;
// on Plan 9, a list).
//
// Each directory listed in the Go path must have a prescribed structure:
//
// The src/ directory holds source code.  The path below 'src' determines
// the import path or executable name.
//
// The pkg/ directory holds installed package objects.
// As in the Go tree, each target operating system and
// architecture pair has its own subdirectory of pkg
// (pkg/GOOS_GOARCH).
//
// If DIR is a directory listed in the Go path, a package with
// source in DIR/src/foo/bar can be imported as "foo/bar" and
// has its compiled form installed to "DIR/pkg/GOOS_GOARCH/foo/bar.a"
// (or, for gccgo, "DIR/pkg/gccgo/foo/libbar.a").
//
// The bin/ directory holds compiled commands.
// Each command is named for its source directory, but only
// using the final element, not the entire path.  That is, the
// command with source in DIR/src/foo/quux is installed into
// DIR/bin/quux, not DIR/bin/foo/quux.  The foo/ is stripped
// so that you can add DIR/bin to your PATH to get at the
// installed commands.
//
// Here's an example directory layout:
//
//	GOPATH=/home/user/gocode
//
//	/home/user/gocode/
//	    src/
//	        foo/
//	            bar/               (go code in package bar)
//	                x.go
//	            quux/              (go code in package main)
//	                y.go
//	    bin/
//	        quux                   (installed command)
//	    pkg/
//	        linux_amd64/
//	            foo/
//	                bar.a          (installed package object)
//
// Build Constraints
//
// A build constraint is a line comment beginning with the directive +build
// that lists the conditions under which a file should be included in the package.
// Constraints may appear in any kind of source file (not just Go), but
// they must be appear near the top of the file, preceded
// only by blank lines and other line comments.
//
// A build constraint is evaluated as the OR of space-separated options;
// each option evaluates as the AND of its comma-separated terms;
// and each term is an alphanumeric word or, preceded by !, its negation.
// That is, the build constraint:
//
//	// +build linux,386 darwin,!cgo
//
// corresponds to the boolean formula:
//
//	(linux AND 386) OR (darwin AND (NOT cgo))
//
// During a particular build, the following words are satisfied:
//
//	- the target operating system, as spelled by runtime.GOOS
//	- the target architecture, as spelled by runtime.GOARCH
//	- "cgo", if ctxt.CgoEnabled is true
//	- any additional words listed in ctxt.BuildTags
//
// If a file's name, after stripping the extension and a possible _test suffix,
// matches *_GOOS, *_GOARCH, or *_GOOS_GOARCH for any known operating
// system and architecture values, then the file is considered to have an implicit
// build constraint requiring those terms.
//
// To keep a file from being considered for the build:
//
//	// +build ignore
//
// (any other unsatisfied word will work as well, but ``ignore'' is conventional.)
//
// To build a file only when using cgo, and only on Linux and OS X:
//
//	// +build linux,cgo darwin,cgo
//
// Such a file is usually paired with another file implementing the
// default functionality for other systems, which in this case would
// carry the constraint:
//
//	// +build !linux !darwin !cgo
//
// Naming a file dns_windows.go will cause it to be included only when
// building the package for Windows; similarly, math_386.s will be included
// only when building the package for 32-bit x86.
//
package build
<commit_msg>go/build: fix boolean negation<commit_after>// Copyright 2011 The Go Authors.  All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package build gathers information about Go packages.
//
// Go Path
//
// The Go path is a list of directory trees containing Go source code.
// It is consulted to resolve imports that cannot be found in the standard
// Go tree.  The default path is the value of the GOPATH environment
// variable, interpreted as a path list appropriate to the operating system
// (on Unix, the variable is a colon-separated string;
// on Windows, a semicolon-separated string;
// on Plan 9, a list).
//
// Each directory listed in the Go path must have a prescribed structure:
//
// The src/ directory holds source code.  The path below 'src' determines
// the import path or executable name.
//
// The pkg/ directory holds installed package objects.
// As in the Go tree, each target operating system and
// architecture pair has its own subdirectory of pkg
// (pkg/GOOS_GOARCH).
//
// If DIR is a directory listed in the Go path, a package with
// source in DIR/src/foo/bar can be imported as "foo/bar" and
// has its compiled form installed to "DIR/pkg/GOOS_GOARCH/foo/bar.a"
// (or, for gccgo, "DIR/pkg/gccgo/foo/libbar.a").
//
// The bin/ directory holds compiled commands.
// Each command is named for its source directory, but only
// using the final element, not the entire path.  That is, the
// command with source in DIR/src/foo/quux is installed into
// DIR/bin/quux, not DIR/bin/foo/quux.  The foo/ is stripped
// so that you can add DIR/bin to your PATH to get at the
// installed commands.
//
// Here's an example directory layout:
//
//	GOPATH=/home/user/gocode
//
//	/home/user/gocode/
//	    src/
//	        foo/
//	            bar/               (go code in package bar)
//	                x.go
//	            quux/              (go code in package main)
//	                y.go
//	    bin/
//	        quux                   (installed command)
//	    pkg/
//	        linux_amd64/
//	            foo/
//	                bar.a          (installed package object)
//
// Build Constraints
//
// A build constraint is a line comment beginning with the directive +build
// that lists the conditions under which a file should be included in the package.
// Constraints may appear in any kind of source file (not just Go), but
// they must be appear near the top of the file, preceded
// only by blank lines and other line comments.
//
// A build constraint is evaluated as the OR of space-separated options;
// each option evaluates as the AND of its comma-separated terms;
// and each term is an alphanumeric word or, preceded by !, its negation.
// That is, the build constraint:
//
//	// +build linux,386 darwin,!cgo
//
// corresponds to the boolean formula:
//
//	(linux AND 386) OR (darwin AND (NOT cgo))
//
// During a particular build, the following words are satisfied:
//
//	- the target operating system, as spelled by runtime.GOOS
//	- the target architecture, as spelled by runtime.GOARCH
//	- "cgo", if ctxt.CgoEnabled is true
//	- any additional words listed in ctxt.BuildTags
//
// If a file's name, after stripping the extension and a possible _test suffix,
// matches *_GOOS, *_GOARCH, or *_GOOS_GOARCH for any known operating
// system and architecture values, then the file is considered to have an implicit
// build constraint requiring those terms.
//
// To keep a file from being considered for the build:
//
//	// +build ignore
//
// (any other unsatisfied word will work as well, but ``ignore'' is conventional.)
//
// To build a file only when using cgo, and only on Linux and OS X:
//
//	// +build linux,cgo darwin,cgo
//
// Such a file is usually paired with another file implementing the
// default functionality for other systems, which in this case would
// carry the constraint:
//
//	// +build !linux,!darwin !cgo
//
// Naming a file dns_windows.go will cause it to be included only when
// building the package for Windows; similarly, math_386.s will be included
// only when building the package for 32-bit x86.
//
package build
<|endoftext|>


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

// +build !netgo
// +build darwin dragonfly freebsd linux netbsd openbsd

package net

/*
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
*/
import "C"

import (
	"syscall"
	"unsafe"
)

func cgoLookupHost(name string) (addrs []string, err error, completed bool) {
	ip, err, completed := cgoLookupIP(name)
	for _, p := range ip {
		addrs = append(addrs, p.String())
	}
	return
}

func cgoLookupPort(net, service string) (port int, err error, completed bool) {
	acquireThread()
	defer releaseThread()

	var res *C.struct_addrinfo
	var hints C.struct_addrinfo

	switch net {
	case "":
		// no hints
	case "tcp", "tcp4", "tcp6":
		hints.ai_socktype = C.SOCK_STREAM
		hints.ai_protocol = C.IPPROTO_TCP
	case "udp", "udp4", "udp6":
		hints.ai_socktype = C.SOCK_DGRAM
		hints.ai_protocol = C.IPPROTO_UDP
	default:
		return 0, UnknownNetworkError(net), true
	}
	if len(net) >= 4 {
		switch net[3] {
		case '4':
			hints.ai_family = C.AF_INET
		case '6':
			hints.ai_family = C.AF_INET6
		}
	}

	s := C.CString(service)
	defer C.free(unsafe.Pointer(s))
	if C.getaddrinfo(nil, s, &hints, &res) == 0 {
		defer C.freeaddrinfo(res)
		for r := res; r != nil; r = r.ai_next {
			switch r.ai_family {
			default:
				continue
			case C.AF_INET:
				sa := (*syscall.RawSockaddrInet4)(unsafe.Pointer(r.ai_addr))
				p := (*[2]byte)(unsafe.Pointer(&sa.Port))
				return int(p[0])<<8 | int(p[1]), nil, true
			case C.AF_INET6:
				sa := (*syscall.RawSockaddrInet6)(unsafe.Pointer(r.ai_addr))
				p := (*[2]byte)(unsafe.Pointer(&sa.Port))
				return int(p[0])<<8 | int(p[1]), nil, true
			}
		}
	}
	return 0, &AddrError{"unknown port", net + "/" + service}, true
}

func cgoLookupIPCNAME(name string) (addrs []IP, cname string, err error, completed bool) {
	acquireThread()
	defer releaseThread()

	var res *C.struct_addrinfo
	var hints C.struct_addrinfo

	hints.ai_flags = cgoAddrInfoFlags()
	hints.ai_socktype = C.SOCK_STREAM

	h := C.CString(name)
	defer C.free(unsafe.Pointer(h))
	gerrno, err := C.getaddrinfo(h, nil, &hints, &res)
	if gerrno != 0 {
		var str string
		if gerrno == C.EAI_NONAME {
			str = noSuchHost
		} else if gerrno == C.EAI_SYSTEM {
			str = err.Error()
		} else {
			str = C.GoString(C.gai_strerror(gerrno))
		}
		return nil, "", &DNSError{Err: str, Name: name}, true
	}
	defer C.freeaddrinfo(res)
	if res != nil {
		cname = C.GoString(res.ai_canonname)
		if cname == "" {
			cname = name
		}
		if len(cname) > 0 && cname[len(cname)-1] != '.' {
			cname += "."
		}
	}
	for r := res; r != nil; r = r.ai_next {
		// We only asked for SOCK_STREAM, but check anyhow.
		if r.ai_socktype != C.SOCK_STREAM {
			continue
		}
		switch r.ai_family {
		default:
			continue
		case C.AF_INET:
			sa := (*syscall.RawSockaddrInet4)(unsafe.Pointer(r.ai_addr))
			addrs = append(addrs, copyIP(sa.Addr[:]))
		case C.AF_INET6:
			sa := (*syscall.RawSockaddrInet6)(unsafe.Pointer(r.ai_addr))
			addrs = append(addrs, copyIP(sa.Addr[:]))
		}
	}
	return addrs, cname, nil, true
}

func cgoLookupIP(name string) (addrs []IP, err error, completed bool) {
	addrs, _, err, completed = cgoLookupIPCNAME(name)
	return
}

func cgoLookupCNAME(name string) (cname string, err error, completed bool) {
	_, cname, err, completed = cgoLookupIPCNAME(name)
	return
}

func copyIP(x IP) IP {
	y := make(IP, len(x))
	copy(y, x)
	return y
}
<commit_msg>net: defend against broken getaddrinfo on Linux<commit_after>// Copyright 2011 The Go Authors.  All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// +build !netgo
// +build darwin dragonfly freebsd linux netbsd openbsd

package net

/*
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
*/
import "C"

import (
	"syscall"
	"unsafe"
)

func cgoLookupHost(name string) (addrs []string, err error, completed bool) {
	ip, err, completed := cgoLookupIP(name)
	for _, p := range ip {
		addrs = append(addrs, p.String())
	}
	return
}

func cgoLookupPort(net, service string) (port int, err error, completed bool) {
	acquireThread()
	defer releaseThread()

	var res *C.struct_addrinfo
	var hints C.struct_addrinfo

	switch net {
	case "":
		// no hints
	case "tcp", "tcp4", "tcp6":
		hints.ai_socktype = C.SOCK_STREAM
		hints.ai_protocol = C.IPPROTO_TCP
	case "udp", "udp4", "udp6":
		hints.ai_socktype = C.SOCK_DGRAM
		hints.ai_protocol = C.IPPROTO_UDP
	default:
		return 0, UnknownNetworkError(net), true
	}
	if len(net) >= 4 {
		switch net[3] {
		case '4':
			hints.ai_family = C.AF_INET
		case '6':
			hints.ai_family = C.AF_INET6
		}
	}

	s := C.CString(service)
	defer C.free(unsafe.Pointer(s))
	if C.getaddrinfo(nil, s, &hints, &res) == 0 {
		defer C.freeaddrinfo(res)
		for r := res; r != nil; r = r.ai_next {
			switch r.ai_family {
			default:
				continue
			case C.AF_INET:
				sa := (*syscall.RawSockaddrInet4)(unsafe.Pointer(r.ai_addr))
				p := (*[2]byte)(unsafe.Pointer(&sa.Port))
				return int(p[0])<<8 | int(p[1]), nil, true
			case C.AF_INET6:
				sa := (*syscall.RawSockaddrInet6)(unsafe.Pointer(r.ai_addr))
				p := (*[2]byte)(unsafe.Pointer(&sa.Port))
				return int(p[0])<<8 | int(p[1]), nil, true
			}
		}
	}
	return 0, &AddrError{"unknown port", net + "/" + service}, true
}

func cgoLookupIPCNAME(name string) (addrs []IP, cname string, err error, completed bool) {
	acquireThread()
	defer releaseThread()

	var res *C.struct_addrinfo
	var hints C.struct_addrinfo

	hints.ai_flags = cgoAddrInfoFlags()
	hints.ai_socktype = C.SOCK_STREAM

	h := C.CString(name)
	defer C.free(unsafe.Pointer(h))
	gerrno, err := C.getaddrinfo(h, nil, &hints, &res)
	if gerrno != 0 {
		var str string
		if gerrno == C.EAI_NONAME {
			str = noSuchHost
		} else if gerrno == C.EAI_SYSTEM {
			if err == nil {
				// err should not be nil, but sometimes getaddrinfo returns
				// gerrno == C.EAI_SYSTEM with err == nil on Linux.
				// The report claims that it happens when we have too many
				// open files, so use syscall.EMFILE (too many open files in system).
				// Most system calls would return ENFILE (too many open files),
				// so at the least EMFILE should be easy to recognize if this
				// comes up again. golang.org/issue/6232.
				err = syscall.EMFILE
			}
			str = err.Error()
		} else {
			str = C.GoString(C.gai_strerror(gerrno))
		}
		return nil, "", &DNSError{Err: str, Name: name}, true
	}
	defer C.freeaddrinfo(res)
	if res != nil {
		cname = C.GoString(res.ai_canonname)
		if cname == "" {
			cname = name
		}
		if len(cname) > 0 && cname[len(cname)-1] != '.' {
			cname += "."
		}
	}
	for r := res; r != nil; r = r.ai_next {
		// We only asked for SOCK_STREAM, but check anyhow.
		if r.ai_socktype != C.SOCK_STREAM {
			continue
		}
		switch r.ai_family {
		default:
			continue
		case C.AF_INET:
			sa := (*syscall.RawSockaddrInet4)(unsafe.Pointer(r.ai_addr))
			addrs = append(addrs, copyIP(sa.Addr[:]))
		case C.AF_INET6:
			sa := (*syscall.RawSockaddrInet6)(unsafe.Pointer(r.ai_addr))
			addrs = append(addrs, copyIP(sa.Addr[:]))
		}
	}
	return addrs, cname, nil, true
}

func cgoLookupIP(name string) (addrs []IP, err error, completed bool) {
	addrs, _, err, completed = cgoLookupIPCNAME(name)
	return
}

func cgoLookupCNAME(name string) (cname string, err error, completed bool) {
	_, cname, err, completed = cgoLookupIPCNAME(name)
	return
}

func copyIP(x IP) IP {
	y := make(IP, len(x))
	copy(y, x)
	return y
}
<|endoftext|>


<commit_before>package task

import (
	"context"
	"testing"

	"github.com/satori/go.uuid"
	"github.com/stretchr/testify/mock"
)

type mockedStorage struct {
	mock.Mock
}

func newMockedStorage() *mockedStorage {
	return &mockedStorage{}
}

func (m *mockedStorage) Save(task *Task) error {
	args := m.Called(task)
	return args.Error(0)
}

func (m *mockedStorage) Load(uuid uuid.UUID) (*Task, error) {
	args := m.Called(uuid)
	return args.Get(0).(*Task), args.Error(1)
}

func Test_SavedToStorage(t *testing.T) {
	task := NewTask("T", nil, nil, dumpDoFunc, nil)
	storage := new(mockedStorage)
	storage.On("Save", task).Return(nil)

	ctx, cancelFunc := context.WithCancel(context.Background())
	Do(ctx, cancelFunc, task, storage)

	storage.AssertExpectations(t)
}
<commit_msg>Default mocked storage creation fixed<commit_after>package task

import (
	"context"
	"testing"

	"github.com/satori/go.uuid"
	"github.com/stretchr/testify/mock"
)

type mockedStorage struct {
	mock.Mock
}

func newMockedStorage() *mockedStorage {
	storage := mockedStorage{}
	storage.On("Save", mock.Anything).Return(nil)
	return &storage
}

func (m *mockedStorage) Save(task *Task) error {
	args := m.Called(task)
	return args.Error(0)
}

func (m *mockedStorage) Load(uuid uuid.UUID) (*Task, error) {
	args := m.Called(uuid)
	return args.Get(0).(*Task), args.Error(1)
}

func Test_SavedToStorage(t *testing.T) {
	task := NewTask("T", nil, nil, dumpDoFunc, nil)
	storage := new(mockedStorage)
	storage.On("Save", task).Return(nil)

	ctx, cancelFunc := context.WithCancel(context.Background())
	Do(ctx, cancelFunc, task, storage)

	storage.AssertExpectations(t)
}
<|endoftext|>


<commit_before>package taskpool

import (
	"context"
	"log"
)

type task func() error

// TaskPool manages concurrent processes. No more than size tasks run at once,
// and when a task returns an error, the Pool's context is cancelled.
type TaskPool struct {
	add  chan task
	wait chan error
}

// New returns a TaskPool waiting for tasks to run.
func New(ctx context.Context, size int) (TaskPool, context.Context) {
	ctx, cancel := context.WithCancel(ctx)

	t := TaskPool{
		add:  make(chan task),
		wait: make(chan error),
	}
	go t.start(ctx, cancel, size)
	return t, ctx
}

func (tp TaskPool) start(ctx context.Context, cancel context.CancelFunc, size int) {
	result := make(chan error)
	workerC := make(chan task)

	defer cancel()
	defer close(workerC) // Make sure worker goroutines get cleaned up
	defer close(tp.add)  // Closing this is pointless unless there's a bug

	// Start worker pool
	for i := 0; i < size; i++ {
		go func() {
			for t := range workerC {
				select {
				case <-ctx.Done():
					log.Println("37")
					return
				case result <- t():
				}
			}
		}()
	}

	var (
		nextTask task
		tasks    []task
		taskC    chan task
		waitC    = tp.wait
		running  int
	)

	for {
		select {
		case <-ctx.Done():
			tp.wait <- ctx.Err()
			log.Println("58")
			return

		case t := <-tp.add:
			tasks = append(tasks, t)

		case taskC <- nextTask:
			tasks = tasks[1:]
			running++

		case waitC <- nil:
			return

		case err := <-result:
			if err != nil {
				tp.wait <- err
				log.Println("72")
				return
			}
			running--
		}

		waitC = nil
		if len(tasks) > 0 {
			nextTask = tasks[0]
			taskC = workerC
		} else {
			if running == 0 {
				waitC = tp.wait
			}
			nextTask = nil
			taskC = nil
		}
	}
}

// Go adds a task to the pool of tasks to complete.
func (tp TaskPool) Go(t func() error) {
	tp.add <- t
}

// Wait waits for all tasks added to the pool to finish running.
func (tp TaskPool) Wait() error {
	return <-tp.wait
}
<commit_msg>Taskpool: remove stray debug logging<commit_after>package taskpool

import (
	"context"
	"log"
)

type task func() error

// TaskPool manages concurrent processes. No more than size tasks run at once,
// and when a task returns an error, the Pool's context is cancelled.
type TaskPool struct {
	add  chan task
	wait chan error
}

// New returns a TaskPool waiting for tasks to run.
func New(ctx context.Context, size int) (TaskPool, context.Context) {
	ctx, cancel := context.WithCancel(ctx)

	t := TaskPool{
		add:  make(chan task),
		wait: make(chan error),
	}
	go t.start(ctx, cancel, size)
	return t, ctx
}

func (tp TaskPool) start(ctx context.Context, cancel context.CancelFunc, size int) {
	result := make(chan error)
	workerC := make(chan task)

	defer cancel()
	defer close(workerC) // Make sure worker goroutines get cleaned up
	defer close(tp.add)  // Closing this is pointless unless there's a bug

	// Start worker pool
	for i := 0; i < size; i++ {
		go func() {
			for t := range workerC {
				select {
				case <-ctx.Done():
					log.Println("37")
					return
				case result <- t():
				}
			}
		}()
	}

	var (
		nextTask task
		tasks    []task
		taskC    chan task
		waitC    = tp.wait
		running  int
	)

	for {
		select {
		case <-ctx.Done():
			tp.wait <- ctx.Err()
			return

		case t := <-tp.add:
			tasks = append(tasks, t)

		case taskC <- nextTask:
			tasks = tasks[1:]
			running++

		case waitC <- nil:
			return

		case err := <-result:
			if err != nil {
				tp.wait <- err
				return
			}
			running--
		}

		waitC = nil
		if len(tasks) > 0 {
			nextTask = tasks[0]
			taskC = workerC
		} else {
			if running == 0 {
				waitC = tp.wait
			}
			nextTask = nil
			taskC = nil
		}
	}
}

// Go adds a task to the pool of tasks to complete.
func (tp TaskPool) Go(t func() error) {
	tp.add <- t
}

// Wait waits for all tasks added to the pool to finish running.
func (tp TaskPool) Wait() error {
	return <-tp.wait
}
<|endoftext|>