<commit_before>/*
   Copyright 2012 the go.uik authors

   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 uik

import (
	"code.google.com/p/draw2d/draw2d"
	"github.com/skelterjohn/go.wde"
	"github.com/skelterjohn/go.wde/xgb"
	"image"
	"image/color"
	"image/draw"
)

func ClearPaint(gc draw2d.GraphicContext) {
	gc.Clear()
	gc.SetFillColor(color.RGBA{155, 0, 0, 255})
	gc.Fill()
}

func ZeroRGBA(rgba *image.RGBA) {
	for y := rgba.Rect.Min.Y; y < rgba.Rect.Max.Y; y++ {
		rowStart := (y-rgba.Rect.Min.Y)*rgba.Stride - rgba.Rect.Min.X*4
		rowEnd := rowStart + (rgba.Rect.Max.X-rgba.Rect.Min.X)*4
		row := rgba.Pix[rowStart:rowEnd]
		for i := range row {
			row[i] = 0
		}
	}
}

func ShowBuffer(title string, buffer image.Image) {
	if buffer == nil {
		return
	}
	width, height := int(buffer.Bounds().Max.X), int(buffer.Bounds().Max.Y)
	if width == 0 || height == 0 {
		return
	}
	w, err := xgb.NewWindow(width, height)
	if err != nil {
		return
	}
	w.SetTitle(title)
	for x := 0; x < width; x++ {
		for y := 0; y < height; y++ {
			if (x/10)%2 == (y/10)%2 {
				w.Screen().Set(x, y, color.White)
			} else {
				w.Screen().Set(x, y, color.RGBA{200, 200, 200, 255})
			}
		}
	}
	draw.Draw(w.Screen(), buffer.Bounds(), buffer, image.Point{0, 0}, draw.Over)
	w.FlushImage()
	w.Show()

loop:
	for e := range w.EventChan() {
		switch e.(type) {
		case wde.CloseEvent, wde.MouseDownEvent:
			break loop
		}
	}
	w.Close()
}
<commit_msg>removed accidental import of xgb<commit_after>/*
   Copyright 2012 the go.uik authors

   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 uik

import (
	"code.google.com/p/draw2d/draw2d"
	"image"
	"image/color"
)

func ClearPaint(gc draw2d.GraphicContext) {
	gc.Clear()
	gc.SetFillColor(color.RGBA{155, 0, 0, 255})
	gc.Fill()
}

func ZeroRGBA(rgba *image.RGBA) {
	for y := rgba.Rect.Min.Y; y < rgba.Rect.Max.Y; y++ {
		rowStart := (y-rgba.Rect.Min.Y)*rgba.Stride - rgba.Rect.Min.X*4
		rowEnd := rowStart + (rgba.Rect.Max.X-rgba.Rect.Min.X)*4
		row := rgba.Pix[rowStart:rowEnd]
		for i := range row {
			row[i] = 0
		}
	}
}

/*
func ShowBuffer(title string, buffer image.Image) {
	if buffer == nil {
		return
	}
	width, height := int(buffer.Bounds().Max.X), int(buffer.Bounds().Max.Y)
	if width == 0 || height == 0 {
		return
	}
	w, err := xgb.NewWindow(width, height)
	if err != nil {
		return
	}
	w.SetTitle(title)
	for x := 0; x < width; x++ {
		for y := 0; y < height; y++ {
			if (x/10)%2 == (y/10)%2 {
				w.Screen().Set(x, y, color.White)
			} else {
				w.Screen().Set(x, y, color.RGBA{200, 200, 200, 255})
			}
		}
	}
	draw.Draw(w.Screen(), buffer.Bounds(), buffer, image.Point{0, 0}, draw.Over)
	w.FlushImage()
	w.Show()

loop:
	for e := range w.EventChan() {
		switch e.(type) {
		case wde.CloseEvent, wde.MouseDownEvent:
			break loop
		}
	}
	w.Close()
}
*/
<|endoftext|>


<commit_before>package drop

import (
	"container/ring"
	"errors"
	"io"
	"io/ioutil"
	"log"
	"os"
	"path/filepath"
	"time"
)

const (
	maximumDropMessages = 32
	maxMsgSize          = 4096
)

type Drop struct {
	Id string
}

type Message struct {
	Drop      Drop
	Timestamp time.Time
	Path      string
}

func (msg *Message) discard() error {
	return os.Remove(msg.Path)
}

type DropServer struct {
	Capacity   int
	BaseDir    string
	MsgRing    *ring.Ring
	SubmitChan chan Message
}

func NewServer(capacity int, baseDir string) DropServer {
	msgRing := ring.New(capacity)
	return DropServer{
		Capacity:   capacity,
		BaseDir:    baseDir,
		MsgRing:    msgRing,
		SubmitChan: launchRingManager(msgRing),
	}
}

func launchRingManager(msgRing *ring.Ring) chan Message {
	submitChan := make(chan Message)
	go func() {
		for {
			msg := <-submitChan
			oldMsg, oldExisted := msgRing.Value.(Message)
			msgRing.Value = msg
			if oldExisted {
				err := oldMsg.discard()
				if err != nil {
					log.Panic("Failed to discard message")
				}
			}
			msgRing = msgRing.Next()
		}
	}()
	return submitChan
}

func (server *DropServer) submit(drop Drop, data io.Reader) error {
	msg := Message{
		Drop:      drop,
		Timestamp: time.Now(),
	}
	file, err := ioutil.TempFile(server.BaseDir, "")
	if err != nil {
		return err
	}
	defer file.Close()
	msg.Path = filepath.Join(server.BaseDir, file.Name())
	_, err = io.CopyN(file, data, maxMsgSize+1)
	if err != io.EOF {
		os.Remove(msg.Path)
		if err == nil {
			return errors.New("Maximum drop size exceeded")
		} else {
			// some other unforeseen error occurred
			return err
		}
	}
	server.SubmitChan <- msg

	return nil
}

func (server *DropServer) request(drop Drop, since time.Time) ([]string, error) {
	paths := make([]string, 0)
	server.MsgRing.Do(func(value interface{}) {
		msg, ok := value.(Message)
		if ok && msg.Drop.Id == drop.Id && msg.Timestamp.After(since) {
			paths = append(paths, msg.Path)
		}
	})
	return paths, nil
}
<commit_msg>Fixed file path construction<commit_after>package drop

import (
	"container/ring"
	"errors"
	"io"
	"io/ioutil"
	"log"
	"os"
	"time"
)

const (
	maximumDropMessages = 32
	maxMsgSize          = 4096
)

type Drop struct {
	Id string
}

type Message struct {
	Drop      Drop
	Timestamp time.Time
	Path      string
}

func (msg *Message) discard() error {
	return os.Remove(msg.Path)
}

type DropServer struct {
	Capacity   int
	BaseDir    string
	MsgRing    *ring.Ring
	SubmitChan chan Message
}

func NewServer(capacity int, baseDir string) DropServer {
	msgRing := ring.New(capacity)
	return DropServer{
		Capacity:   capacity,
		BaseDir:    baseDir,
		MsgRing:    msgRing,
		SubmitChan: launchRingManager(msgRing),
	}
}

func launchRingManager(msgRing *ring.Ring) chan Message {
	submitChan := make(chan Message)
	go func() {
		for {
			msg := <-submitChan
			oldMsg, oldExisted := msgRing.Value.(Message)
			msgRing.Value = msg
			if oldExisted {
				err := oldMsg.discard()
				if err != nil {
					log.Panic("Failed to discard message")
				}
			}
			msgRing = msgRing.Next()
		}
	}()
	return submitChan
}

func (server *DropServer) submit(drop Drop, data io.Reader) error {
	msg := Message{
		Drop:      drop,
		Timestamp: time.Now(),
	}
	file, err := ioutil.TempFile(server.BaseDir, "")
	if err != nil {
		return err
	}
	defer file.Close()
	msg.Path = file.Name()
	_, err = io.CopyN(file, data, maxMsgSize+1)
	if err != io.EOF {
		os.Remove(msg.Path)
		if err == nil {
			return errors.New("Maximum drop size exceeded")
		} else {
			// some other unforeseen error occurred
			return err
		}
	}
	server.SubmitChan <- msg

	return nil
}

func (server *DropServer) request(drop Drop, since time.Time) ([]string, error) {
	paths := make([]string, 0)
	server.MsgRing.Do(func(value interface{}) {
		msg, ok := value.(Message)
		if ok && msg.Drop.Id == drop.Id && msg.Timestamp.After(since) {
			paths = append(paths, msg.Path)
		}
	})
	return paths, nil
}
<|endoftext|>


<commit_before>// Package efmq provides basic MQTT like functionality for message
// publishing and subscriptions within a local area network
package efmq

import (
	"encoding/json"
	"errors"
	"log"
	"net"

	"github.com/mdlayher/ethernet"
	"github.com/mdlayher/raw"
)

// EFQM represents a connection
type EFMQ struct {
	netInterface *net.Interface
	connection   *net.PacketConn
	subscription []string
	listening    bool
	Message      chan Message
}

type Message struct {
	Topic   string `json:"tpc"`
	Payload string `json:"pyld`
}

const etherType = 0xcccc

// NewEFMQ is a factory functionm to create a value of EFMQ type
func NewEFMQ(networkInterface string) (*EFMQ, error) {
	mq := new(EFMQ)
	mq.Message = make(chan Message)
	// set network interface
	ni, err := net.InterfaceByName(networkInterface)
	if err != nil {
		return mq, errors.New("NewEFMQ: could not detect interface " + networkInterface)
	}
	// create connection/listener
	conn, err := connect(ni)
	if err != nil {
		return mq, err
	}
	// store in struct
	mq.netInterface = ni
	mq.connection = &conn
	return mq, nil
}

// connect opens network inteface to create connection for listening
func connect(ni *net.Interface) (net.PacketConn, error) {
	var conn net.PacketConn
	conn, err := raw.ListenPacket(ni, etherType)
	if err != nil {
		return conn, err
	}
	return conn, nil
}

// Subscribe takes a new subscription and stores it to slice
func (mq *EFMQ) Subscribe(topic string) {
	// add topic to subscriptions and start listener
	mq.subscription = append(mq.subscription, topic)
}

// Unsubscribe removes subscription from slice store
func (mq *EFMQ) Unsubscribe(topic string) error {
	// remove topic from subscriptions
	for i, v := range mq.subscription {
		if v == topic {
			mq.subscription = append(mq.subscription[:i], mq.subscription[i+1:]...)
		}
	}
	return nil
}

// Publish broadcasts a message on the network which comprises topic
// and payload
func (mq *EFMQ) Publish(topic string, payload string) error {
	// build a JSON object
	message := Message{
		Topic:   topic,
		Payload: payload,
	}
	// marshal to byte slice of JSON
	content, err := json.Marshal(&message)
	if err != nil {
		return errors.New("Publish: failed to marshal JSON")
	}
	// pass to despatcher
	if err := mq.despatcher(content); err != nil {
		return err
	}
	return nil
}

// despatcher handles the tranmission of message over ethernet frames
func (mq *EFMQ) despatcher(content []byte) error {
	// configure frame
	f := &ethernet.Frame{
		Destination: ethernet.Broadcast,
		Source:      mq.netInterface.HardwareAddr,
		EtherType:   etherType,
		Payload:     content,
	}
	// required for linux as mdlayher ethecho
	addr := &raw.Addr{
		HardwareAddr: ethernet.Broadcast,
	}
	// prepare
	binary, err := f.MarshalBinary()
	if err != nil {
		return errors.New("despatcher: failed to marshal ethernet frame")
	}
	// send
	conn := *mq.connection
	if _, err := conn.WriteTo(binary, addr); err != nil {
		return errors.New("despatcher: failed to send message")
	}
	return nil
}

func (mq *EFMQ) Subscriptions() []string {
	return mq.subscription
}

// Listen announces the subscriptions to which we are subscribed
// and then starts listener func in go routine
func (mq *EFMQ) Listen() {
	var subs string
	subsLen := len(mq.subscription)
	for i, v := range mq.subscription {
		subs += v
		if i < subsLen-1 {
			subs += ", "
		} else {
			subs += "."
		}
	}
	// listen & log
	log.Println("Subscribed to topic(s):", subs, "Now listening...")
	go mq.listener()
}

// listener filters messages before presenting to client using topic
func (mq *EFMQ) listener() {
	var f ethernet.Frame
	var conn net.PacketConn
	var subs []string
	conn = *mq.connection
	subs = mq.subscription
	b := make([]byte, mq.netInterface.MTU)
	// handle messages indefinitely
	for {
		n, _, err := conn.ReadFrom(b)
		if err != nil {
			log.Printf("listener: failed to receive message: %v", err)
		}
		if err := (&f).UnmarshalBinary(b[:n]); err != nil {
			log.Printf("listener: failed to unmarshal ethernet frame: %v", err)
		}
		// f.Payload could be padded with zeros, need to deal before unmarshal
		var payload []byte
		for _, v := range f.Payload {
			if v != 0 {
				payload = append(payload, v)
			}
		}
		// unmarshal JSON
		message := new(Message)
		err = json.Unmarshal(payload, message)
		if err != nil {
			log.Println(err)
		}

		for _, v := range subs {
			if message.Topic == v {
				// put message on channel if matches a subscription
				mq.Message <- *message
			}
		}
	}
}
<commit_msg>comment for exported method Subscriptions<commit_after>// Package efmq provides basic MQTT like functionality for message
// publishing and subscriptions within a local area network
package efmq

import (
	"encoding/json"
	"errors"
	"log"
	"net"

	"github.com/mdlayher/ethernet"
	"github.com/mdlayher/raw"
)

// EFQM represents a connection
type EFMQ struct {
	netInterface *net.Interface
	connection   *net.PacketConn
	subscription []string
	listening    bool
	Message      chan Message
}

type Message struct {
	Topic   string `json:"tpc"`
	Payload string `json:"pyld`
}

const etherType = 0xcccc

// NewEFMQ is a factory functionm to create a value of EFMQ type
func NewEFMQ(networkInterface string) (*EFMQ, error) {
	mq := new(EFMQ)
	mq.Message = make(chan Message)
	// set network interface
	ni, err := net.InterfaceByName(networkInterface)
	if err != nil {
		return mq, errors.New("NewEFMQ: could not detect interface " + networkInterface)
	}
	// create connection/listener
	conn, err := connect(ni)
	if err != nil {
		return mq, err
	}
	// store in struct
	mq.netInterface = ni
	mq.connection = &conn
	return mq, nil
}

// connect opens network inteface to create connection for listening
func connect(ni *net.Interface) (net.PacketConn, error) {
	var conn net.PacketConn
	conn, err := raw.ListenPacket(ni, etherType)
	if err != nil {
		return conn, err
	}
	return conn, nil
}

// Subscribe takes a new subscription and stores it to slice
func (mq *EFMQ) Subscribe(topic string) {
	// add topic to subscriptions and start listener
	mq.subscription = append(mq.subscription, topic)
}

// Unsubscribe removes subscription from slice store
func (mq *EFMQ) Unsubscribe(topic string) error {
	// remove topic from subscriptions
	for i, v := range mq.subscription {
		if v == topic {
			mq.subscription = append(mq.subscription[:i], mq.subscription[i+1:]...)
		}
	}
	return nil
}

// Publish broadcasts a message on the network which comprises topic
// and payload
func (mq *EFMQ) Publish(topic string, payload string) error {
	// build a JSON object
	message := Message{
		Topic:   topic,
		Payload: payload,
	}
	// marshal to byte slice of JSON
	content, err := json.Marshal(&message)
	if err != nil {
		return errors.New("Publish: failed to marshal JSON")
	}
	// pass to despatcher
	if err := mq.despatcher(content); err != nil {
		return err
	}
	return nil
}

// despatcher handles the tranmission of message over ethernet frames
func (mq *EFMQ) despatcher(content []byte) error {
	// configure frame
	f := &ethernet.Frame{
		Destination: ethernet.Broadcast,
		Source:      mq.netInterface.HardwareAddr,
		EtherType:   etherType,
		Payload:     content,
	}
	// required for linux as mdlayher ethecho
	addr := &raw.Addr{
		HardwareAddr: ethernet.Broadcast,
	}
	// prepare
	binary, err := f.MarshalBinary()
	if err != nil {
		return errors.New("despatcher: failed to marshal ethernet frame")
	}
	// send
	conn := *mq.connection
	if _, err := conn.WriteTo(binary, addr); err != nil {
		return errors.New("despatcher: failed to send message")
	}
	return nil
}

// Subscriptions returns list of topics currently subscribed to
func (mq *EFMQ) Subscriptions() []string {
	return mq.subscription
}

// Listen announces the subscriptions to which we are subscribed
// and then starts listener func in go routine
func (mq *EFMQ) Listen() {
	var subs string
	subsLen := len(mq.subscription)
	for i, v := range mq.subscription {
		subs += v
		if i < subsLen-1 {
			subs += ", "
		} else {
			subs += "."
		}
	}
	// listen & log
	log.Println("Subscribed to topic(s):", subs, "Now listening...")
	go mq.listener()
}

// listener filters messages before presenting to client using topic
func (mq *EFMQ) listener() {
	var f ethernet.Frame
	var conn net.PacketConn
	var subs []string
	conn = *mq.connection
	subs = mq.subscription
	b := make([]byte, mq.netInterface.MTU)
	// handle messages indefinitely
	for {
		n, _, err := conn.ReadFrom(b)
		if err != nil {
			log.Printf("listener: failed to receive message: %v", err)
		}
		if err := (&f).UnmarshalBinary(b[:n]); err != nil {
			log.Printf("listener: failed to unmarshal ethernet frame: %v", err)
		}
		// f.Payload could be padded with zeros, need to deal before unmarshal
		var payload []byte
		for _, v := range f.Payload {
			if v != 0 {
				payload = append(payload, v)
			}
		}
		// unmarshal JSON
		message := new(Message)
		err = json.Unmarshal(payload, message)
		if err != nil {
			log.Println(err)
		}

		for _, v := range subs {
			if message.Topic == v {
				// put message on channel if matches a subscription
				mq.Message <- *message
			}
		}
	}
}
<|endoftext|>


<commit_before>/*
Copyright 2013 CoreOS Inc.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package main

import (
	"flag"
	"fmt"
	"io/ioutil"
	"os"
	"os/signal"
	"runtime/pprof"

	"github.com/coreos/etcd/log"
	"github.com/coreos/etcd/server"
	"github.com/coreos/etcd/store"
	"github.com/coreos/go-raft"
)

func main() {
	parseFlags()

	// Load configuration.
	var config = server.NewConfig()
	if err := config.Load(os.Args[1:]); err != nil {
		log.Fatal("Configuration error:", err)
	}

	// Turn on logging.
	if config.VeryVerbose {
		log.Verbose = true
		raft.SetLogLevel(raft.Debug)
	} else if config.Verbose {
		log.Verbose = true
	}

	// Load info object.
	info, err := config.Info()
	if err != nil {
		log.Fatal("info:", err)
	}
	if info.Name == "" {
		host, err := os.Hostname()
		if err != nil || host == "" {
			log.Fatal("Machine name required and hostname not set. e.g. '-n=machine_name'")
		}
		log.Warnf("Using hostname %s as the machine name. You must ensure this name is unique among etcd machines.", host)
		info.Name = host
	}

	// Setup a default directory based on the machine name
	if config.DataDir == "" {
		config.DataDir = info.Name + ".etcd"
		log.Warnf("Using the directory %s as the etcd configuration directory because a directory was not specified. ", config.DataDir)
	}

	// Create data directory if it doesn't already exist.
	if err := os.MkdirAll(config.DataDir, 0744); err != nil {
		log.Fatalf("Unable to create path: %s", err)
	}

	// Retrieve TLS configuration.
	tlsConfig, err := info.EtcdTLS.Config()
	if err != nil {
		log.Fatal("Client TLS:", err)
	}
	peerTLSConfig, err := info.RaftTLS.Config()
	if err != nil {
		log.Fatal("Peer TLS:", err)
	}

	// Create etcd key-value store and registry.
	store := store.New()
	registry := server.NewRegistry(store)

	// Create peer server.
	ps := server.NewPeerServer(info.Name, config.DataDir, info.RaftURL, info.RaftListenHost, &peerTLSConfig, &info.RaftTLS, registry, store, config.SnapCount)
	ps.MaxClusterSize = config.MaxClusterSize
	ps.RetryTimes = config.MaxRetryAttempts

	// Create client server.
	s := server.New(info.Name, info.EtcdURL, info.EtcdListenHost, &tlsConfig, &info.EtcdTLS, ps, registry, store)
	if err := s.AllowOrigins(config.Cors); err != nil {
		panic(err)
	}

	ps.SetServer(s)

	// Run peer server in separate thread while the client server blocks.
	go func() {
		log.Fatal(ps.ListenAndServe(config.Snapshot, config.Machines))
	}()
	log.Fatal(s.ListenAndServe())
}

// Parses non-configuration flags.
func parseFlags() {
	var versionFlag bool
	var cpuprofile string

	f := flag.NewFlagSet(os.Args[0], -1)
	f.SetOutput(ioutil.Discard)
	f.BoolVar(&versionFlag, "version", false, "print the version and exit")
	f.StringVar(&cpuprofile, "cpuprofile", "", "write cpu profile to file")
	f.Parse(os.Args[1:])

	// Print version if necessary.
	if versionFlag {
		fmt.Println(server.ReleaseVersion)
		os.Exit(0)
	}

	// Begin CPU profiling if specified.
	if cpuprofile != "" {
		f, err := os.Create(cpuprofile)
		if err != nil {
			log.Fatal(err)
		}
		pprof.StartCPUProfile(f)

		c := make(chan os.Signal, 1)
		signal.Notify(c, os.Interrupt)
		go func() {
			sig := <-c
			log.Infof("captured %v, stopping profiler and exiting..", sig)
			pprof.StopCPUProfile()
			os.Exit(1)
		}()
	}
}
<commit_msg>fix create folder before write info file<commit_after>/*
Copyright 2013 CoreOS Inc.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package main

import (
	"flag"
	"fmt"
	"io/ioutil"
	"os"
	"os/signal"
	"runtime/pprof"

	"github.com/coreos/etcd/log"
	"github.com/coreos/etcd/server"
	"github.com/coreos/etcd/store"
	"github.com/coreos/go-raft"
)

func main() {
	parseFlags()

	// Load configuration.
	var config = server.NewConfig()
	if err := config.Load(os.Args[1:]); err != nil {
		log.Fatal("Configuration error:", err)
	}

	// Turn on logging.
	if config.VeryVerbose {
		log.Verbose = true
		raft.SetLogLevel(raft.Debug)
	} else if config.Verbose {
		log.Verbose = true
	}

	// Setup a default directory based on the machine name
	if config.DataDir == "" {
		config.DataDir = config.Name + ".etcd"
		log.Warnf("Using the directory %s as the etcd configuration directory because a directory was not specified. ", config.DataDir)
	}

	// Create data directory if it doesn't already exist.
	if err := os.MkdirAll(config.DataDir, 0744); err != nil {
		log.Fatalf("Unable to create path: %s", err)
	}

	// Load info object.
	info, err := config.Info()
	if err != nil {
		log.Fatal("info:", err)
	}
	if info.Name == "" {
		host, err := os.Hostname()
		if err != nil || host == "" {
			log.Fatal("Machine name required and hostname not set. e.g. '-n=machine_name'")
		}
		log.Warnf("Using hostname %s as the machine name. You must ensure this name is unique among etcd machines.", host)
		info.Name = host
	}

	// Retrieve TLS configuration.
	tlsConfig, err := info.EtcdTLS.Config()
	if err != nil {
		log.Fatal("Client TLS:", err)
	}
	peerTLSConfig, err := info.RaftTLS.Config()
	if err != nil {
		log.Fatal("Peer TLS:", err)
	}

	// Create etcd key-value store and registry.
	store := store.New()
	registry := server.NewRegistry(store)

	// Create peer server.
	ps := server.NewPeerServer(info.Name, config.DataDir, info.RaftURL, info.RaftListenHost, &peerTLSConfig, &info.RaftTLS, registry, store, config.SnapCount)
	ps.MaxClusterSize = config.MaxClusterSize
	ps.RetryTimes = config.MaxRetryAttempts

	// Create client server.
	s := server.New(info.Name, info.EtcdURL, info.EtcdListenHost, &tlsConfig, &info.EtcdTLS, ps, registry, store)
	if err := s.AllowOrigins(config.Cors); err != nil {
		panic(err)
	}

	ps.SetServer(s)

	// Run peer server in separate thread while the client server blocks.
	go func() {
		log.Fatal(ps.ListenAndServe(config.Snapshot, config.Machines))
	}()
	log.Fatal(s.ListenAndServe())
}

// Parses non-configuration flags.
func parseFlags() {
	var versionFlag bool
	var cpuprofile string

	f := flag.NewFlagSet(os.Args[0], -1)
	f.SetOutput(ioutil.Discard)
	f.BoolVar(&versionFlag, "version", false, "print the version and exit")
	f.StringVar(&cpuprofile, "cpuprofile", "", "write cpu profile to file")
	f.Parse(os.Args[1:])

	// Print version if necessary.
	if versionFlag {
		fmt.Println(server.ReleaseVersion)
		os.Exit(0)
	}

	// Begin CPU profiling if specified.
	if cpuprofile != "" {
		f, err := os.Create(cpuprofile)
		if err != nil {
			log.Fatal(err)
		}
		pprof.StartCPUProfile(f)

		c := make(chan os.Signal, 1)
		signal.Notify(c, os.Interrupt)
		go func() {
			sig := <-c
			log.Infof("captured %v, stopping profiler and exiting..", sig)
			pprof.StopCPUProfile()
			os.Exit(1)
		}()
	}
}
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"exec"
	"fmt"
	"io/ioutil"
	"os"
	"runtime"
	"sort"
	"strings"
	"syscall"
)

type TaskResourceUsage struct {
	// User time, in nanoseconds
	userTime int64

	// System time, in nanoseconds
	systemTime int64

	// The number of times the command was executed
	numInvocations int

	dontPrintAverage bool
}

func (t *TaskResourceUsage) TotalTime() int64 {
	return t.userTime + t.systemTime
}

func (t *TaskResourceUsage) AverageTime() float {
	return float(t.TotalTime()) / float(t.numInvocations)
}

var taskStats = make(map[string]*TaskResourceUsage)

func addResourceUsage(taskName string, usage *syscall.Rusage) {
	taskRUsage := taskStats[taskName]
	if taskRUsage == nil {
		taskRUsage = &TaskResourceUsage{
			userTime:       0,
			systemTime:     0,
			numInvocations: 0,
		}

		taskStats[taskName] = taskRUsage
	}

	taskRUsage.systemTime += int64(usage.Utime.Sec)*1e9 + int64(usage.Utime.Usec)*1e3
	taskRUsage.userTime += int64(usage.Stime.Sec)*1e9 + int64(usage.Stime.Usec)*1e3
	taskRUsage.numInvocations += 1
}

func addSelf() {
	// Remove any previous stats
	taskStats["(self)"] = nil, false
	taskStats["(self.gc)"] = nil, false

	var usage syscall.Rusage
	errno := syscall.Getrusage(0, &usage)
	if errno == 0 {
		addResourceUsage("(self)", &usage)
	}

	taskStats["(self.gc)"] = &TaskResourceUsage{
		userTime:         int64(runtime.MemStats.PauseNs),
		systemTime:       0,
		numInvocations:   int(runtime.MemStats.NumGC),
		dontPrintAverage: true,
	}
}

func printTimings(out *os.File) {
	addSelf()

	sortedNames := make([]string, len(taskStats))
	maxNameLength := 0
	{
		i := 0
		for name, _ := range taskStats {
			sortedNames[i] = name
			if len(name) > maxNameLength {
				maxNameLength = len(name)
			}
			i++
		}

		sort.StringArray(sortedNames).Sort()
	}

	fmt.Fprintf(out, "Run times:\n")
	for _, name := range sortedNames {
		var buf bytes.Buffer
		fmt.Fprintf(&buf, "    %s:", name)
		for i := len(name); i < maxNameLength; i++ {
			buf.WriteString(" ")
		}
		taskRUsage := taskStats[name]
		fmt.Fprintf(&buf, " %.3f secs", float(taskRUsage.TotalTime())/1e9)
		if taskRUsage.numInvocations >= 2 {
			if !taskRUsage.dontPrintAverage {
				fmt.Fprintf(&buf, " (%d invocations, %.3f secs per invocation)",
					taskRUsage.numInvocations, taskRUsage.AverageTime()/1e9)
			} else {
				fmt.Fprintf(&buf, " (%d invocations)", taskRUsage.numInvocations)
			}
		}

		fmt.Fprintf(out, "%s\n", buf.String())
	}
}

type Executable struct {
	name     string
	noLookup bool
	fullPath string // Cached path obtained by calling 'exec.LookPath(name)'
}

type RunFlags struct {
	cmdChan_orNil         chan *exec.Cmd
	stdin, stdout, stderr int
	dontPrintCmd          bool
}

func (e *Executable) runSimply(argv []string, dir string, dontPrintCmd bool) os.Error {
	flags := RunFlags{
		cmdChan_orNil: nil,
		stdin:         exec.PassThrough,
		stdout:        exec.PassThrough,
		stderr:        exec.PassThrough,
		dontPrintCmd:  false,
	}

	return e.run_lowLevel(argv, dir, flags)
}

// Runs 'e' as separate process, waits until it finishes,
// and returns the data the process sent to its output(s).
// The argument 'in' comprises the command's input.
func (e *Executable) run(argv []string, dir string, in string, mergeStdoutAndStderr bool) (stdout string, stderr string, err os.Error) {
	cmdChan := make(chan *exec.Cmd)
	errChan := make(chan os.Error, 3)
	stdoutChan := make(chan []byte, 1)
	stderrChan := make(chan []byte, 1)
	go func() {
		cmd := <-cmdChan
		if cmd != nil {
			// A goroutine for feeding STDIN
			go func() {
				_, err := cmd.Stdin.WriteString(in)
				if err != nil {
					cmd.Stdin.Close()
				} else {
					err = cmd.Stdin.Close()
				}
				errChan <- err
			}()

			// A goroutine for consuming STDOUT.
			// Note: STDOUT is optionally merged with STDERR.
			go func() {
				stdout, err := ioutil.ReadAll(cmd.Stdout)
				if err != nil {
					cmd.Stdout.Close()
					errChan <- err
				} else {
					err = cmd.Stdout.Close()
					errChan <- err
					stdoutChan <- stdout
				}
			}()

			if cmd.Stderr != nil {
				// A goroutine for consuming STDERR
				go func() {
					stderr, err := ioutil.ReadAll(cmd.Stderr)
					if err != nil {
						cmd.Stderr.Close()
						errChan <- err
					} else {
						err = cmd.Stderr.Close()
						errChan <- err
						stderrChan <- stderr
					}
				}()
			} else {
				errChan <- nil
				stderrChan <- make([]byte, 0)
			}
		}
	}()

	var stderrHandling int
	if mergeStdoutAndStderr {
		stderrHandling = exec.MergeWithStdout
	} else {
		stderrHandling = exec.Pipe
	}

	flags := RunFlags{
		cmdChan_orNil: cmdChan,
		stdin:         exec.Pipe,
		stdout:        exec.Pipe,
		stderr:        stderrHandling,
		dontPrintCmd:  true,
	}

	err = e.run_lowLevel(argv, dir, flags)
	if err != nil {
		return "", "", err
	}

	err1 := <-errChan
	err2 := <-errChan
	err3 := <-errChan
	if (err1 != nil) || (err2 != nil) || (err3 != nil) {
		err = err1
		if err == nil {
			err = err2
		}
		if err == nil {
			err = err3
		}
		return "", "", err
	}

	stdout = string(<-stdoutChan)
	stderr = string(<-stderrChan)

	return stdout, stderr, nil
}

// Runs 'e' as separate process and waits until it finishes.
// If 'cmdChan_orNil' is not nil, it will receive the 'exec.Cmd' returned by 'exec.Run'.
func (e *Executable) run_lowLevel(argv []string, dir string, flags RunFlags) os.Error {
	// Resolve 'e.fullpath' (if not resolved yet)
	if len(e.fullPath) == 0 {
		if (e.noLookup == false) || !strings.HasPrefix(e.name, "./") {
			var err os.Error
			e.fullPath, err = exec.LookPath(e.name)
			if err != nil {
				msg := "failed to lookup executable \"" + e.name + "\": " + err.String()
				return os.NewError(msg)
			}
		} else {
			e.fullPath = e.name
		}
	}

	if dir == "." {
		dir = ""
	}

	if (*flag_verbose && !flags.dontPrintCmd) || *flag_debug {
		if len(dir) == 0 {
			fmt.Fprintf(os.Stdout, "(%s)\n", strings.Join(argv, " "))
		} else {
			fmt.Fprintf(os.Stdout, "(cd %s ; %s)\n", dir, strings.Join(argv, " "))
		}
	}

	cmd, err := exec.Run(e.fullPath, argv, os.Environ(), dir, flags.stdin, flags.stdout, flags.stderr)
	if err != nil {
		if flags.cmdChan_orNil != nil {
			flags.cmdChan_orNil <- nil
		}
		return err
	} else {
		if flags.cmdChan_orNil != nil {
			flags.cmdChan_orNil <- cmd
		}
	}

	waitMsg, err := cmd.Wait( /*options*/ os.WRUSAGE)
	if err != nil {
		return err
	}
	if *flag_timings {
		addResourceUsage(e.name, waitMsg.Rusage)
	}
	if !waitMsg.Exited() {
		return os.NewError("unable to obtain the exit status of \"" + e.name + "%s\"")
	}
	if waitMsg.ExitStatus() != 0 {
		var errMsg string
		if len(dir) == 0 {
			errMsg = fmt.Sprintf("command \"%s\" returned an error", strings.Join(argv, " "))
		} else {
			errMsg = fmt.Sprintf("command \"%s\" run in directory \"%s\" returned an error", strings.Join(argv, " "), dir)
		}
		return os.NewError(errMsg)
	}

	return nil
}
<commit_msg>Update in response to Go release.2011-01-20 (removal of the 'float' type)<commit_after>package main

import (
	"bytes"
	"exec"
	"fmt"
	"io/ioutil"
	"os"
	"runtime"
	"sort"
	"strings"
	"syscall"
)

type TaskResourceUsage struct {
	// User time, in nanoseconds
	userTime int64

	// System time, in nanoseconds
	systemTime int64

	// The number of times the command was executed
	numInvocations int

	dontPrintAverage bool
}

func (t *TaskResourceUsage) TotalTime() int64 {
	return t.userTime + t.systemTime
}

func (t *TaskResourceUsage) AverageTime() float64 {
	return float64(t.TotalTime()) / float64(t.numInvocations)
}

var taskStats = make(map[string]*TaskResourceUsage)

func addResourceUsage(taskName string, usage *syscall.Rusage) {
	taskRUsage := taskStats[taskName]
	if taskRUsage == nil {
		taskRUsage = &TaskResourceUsage{
			userTime:       0,
			systemTime:     0,
			numInvocations: 0,
		}

		taskStats[taskName] = taskRUsage
	}

	taskRUsage.systemTime += int64(usage.Utime.Sec)*1e9 + int64(usage.Utime.Usec)*1e3
	taskRUsage.userTime += int64(usage.Stime.Sec)*1e9 + int64(usage.Stime.Usec)*1e3
	taskRUsage.numInvocations += 1
}

func addSelf() {
	// Remove any previous stats
	taskStats["(self)"] = nil, false
	taskStats["(self.gc)"] = nil, false

	var usage syscall.Rusage
	errno := syscall.Getrusage(0, &usage)
	if errno == 0 {
		addResourceUsage("(self)", &usage)
	}

	taskStats["(self.gc)"] = &TaskResourceUsage{
		userTime:         int64(runtime.MemStats.PauseTotalNs),
		systemTime:       0,
		numInvocations:   int(runtime.MemStats.NumGC),
		dontPrintAverage: true,
	}
}

func printTimings(out *os.File) {
	addSelf()

	sortedNames := make([]string, len(taskStats))
	maxNameLength := 0
	{
		i := 0
		for name, _ := range taskStats {
			sortedNames[i] = name
			if len(name) > maxNameLength {
				maxNameLength = len(name)
			}
			i++
		}

		sort.StringArray(sortedNames).Sort()
	}

	fmt.Fprintf(out, "Run times:\n")
	for _, name := range sortedNames {
		var buf bytes.Buffer
		fmt.Fprintf(&buf, "    %s:", name)
		for i := len(name); i < maxNameLength; i++ {
			buf.WriteString(" ")
		}
		taskRUsage := taskStats[name]
		fmt.Fprintf(&buf, " %.3f secs", float64(taskRUsage.TotalTime())/1e9)
		if taskRUsage.numInvocations >= 2 {
			if !taskRUsage.dontPrintAverage {
				fmt.Fprintf(&buf, " (%d invocations, %.3f secs per invocation)",
					taskRUsage.numInvocations, taskRUsage.AverageTime()/1e9)
			} else {
				fmt.Fprintf(&buf, " (%d invocations)", taskRUsage.numInvocations)
			}
		}

		fmt.Fprintf(out, "%s\n", buf.String())
	}
}

type Executable struct {
	name     string
	noLookup bool
	fullPath string // Cached path obtained by calling 'exec.LookPath(name)'
}

type RunFlags struct {
	cmdChan_orNil         chan *exec.Cmd
	stdin, stdout, stderr int
	dontPrintCmd          bool
}

func (e *Executable) runSimply(argv []string, dir string, dontPrintCmd bool) os.Error {
	flags := RunFlags{
		cmdChan_orNil: nil,
		stdin:         exec.PassThrough,
		stdout:        exec.PassThrough,
		stderr:        exec.PassThrough,
		dontPrintCmd:  false,
	}

	return e.run_lowLevel(argv, dir, flags)
}

// Runs 'e' as separate process, waits until it finishes,
// and returns the data the process sent to its output(s).
// The argument 'in' comprises the command's input.
func (e *Executable) run(argv []string, dir string, in string, mergeStdoutAndStderr bool) (stdout string, stderr string, err os.Error) {
	cmdChan := make(chan *exec.Cmd)
	errChan := make(chan os.Error, 3)
	stdoutChan := make(chan []byte, 1)
	stderrChan := make(chan []byte, 1)
	go func() {
		cmd := <-cmdChan
		if cmd != nil {
			// A goroutine for feeding STDIN
			go func() {
				_, err := cmd.Stdin.WriteString(in)
				if err != nil {
					cmd.Stdin.Close()
				} else {
					err = cmd.Stdin.Close()
				}
				errChan <- err
			}()

			// A goroutine for consuming STDOUT.
			// Note: STDOUT is optionally merged with STDERR.
			go func() {
				stdout, err := ioutil.ReadAll(cmd.Stdout)
				if err != nil {
					cmd.Stdout.Close()
					errChan <- err
				} else {
					err = cmd.Stdout.Close()
					errChan <- err
					stdoutChan <- stdout
				}
			}()

			if cmd.Stderr != nil {
				// A goroutine for consuming STDERR
				go func() {
					stderr, err := ioutil.ReadAll(cmd.Stderr)
					if err != nil {
						cmd.Stderr.Close()
						errChan <- err
					} else {
						err = cmd.Stderr.Close()
						errChan <- err
						stderrChan <- stderr
					}
				}()
			} else {
				errChan <- nil
				stderrChan <- make([]byte, 0)
			}
		}
	}()

	var stderrHandling int
	if mergeStdoutAndStderr {
		stderrHandling = exec.MergeWithStdout
	} else {
		stderrHandling = exec.Pipe
	}

	flags := RunFlags{
		cmdChan_orNil: cmdChan,
		stdin:         exec.Pipe,
		stdout:        exec.Pipe,
		stderr:        stderrHandling,
		dontPrintCmd:  true,
	}

	err = e.run_lowLevel(argv, dir, flags)
	if err != nil {
		return "", "", err
	}

	err1 := <-errChan
	err2 := <-errChan
	err3 := <-errChan
	if (err1 != nil) || (err2 != nil) || (err3 != nil) {
		err = err1
		if err == nil {
			err = err2
		}
		if err == nil {
			err = err3
		}
		return "", "", err
	}

	stdout = string(<-stdoutChan)
	stderr = string(<-stderrChan)

	return stdout, stderr, nil
}

// Runs 'e' as separate process and waits until it finishes.
// If 'cmdChan_orNil' is not nil, it will receive the 'exec.Cmd' returned by 'exec.Run'.
func (e *Executable) run_lowLevel(argv []string, dir string, flags RunFlags) os.Error {
	// Resolve 'e.fullpath' (if not resolved yet)
	if len(e.fullPath) == 0 {
		if (e.noLookup == false) || !strings.HasPrefix(e.name, "./") {
			var err os.Error
			e.fullPath, err = exec.LookPath(e.name)
			if err != nil {
				msg := "failed to lookup executable \"" + e.name + "\": " + err.String()
				return os.NewError(msg)
			}
		} else {
			e.fullPath = e.name
		}
	}

	if dir == "." {
		dir = ""
	}

	if (*flag_verbose && !flags.dontPrintCmd) || *flag_debug {
		if len(dir) == 0 {
			fmt.Fprintf(os.Stdout, "(%s)\n", strings.Join(argv, " "))
		} else {
			fmt.Fprintf(os.Stdout, "(cd %s ; %s)\n", dir, strings.Join(argv, " "))
		}
	}

	cmd, err := exec.Run(e.fullPath, argv, os.Environ(), dir, flags.stdin, flags.stdout, flags.stderr)
	if err != nil {
		if flags.cmdChan_orNil != nil {
			flags.cmdChan_orNil <- nil
		}
		return err
	} else {
		if flags.cmdChan_orNil != nil {
			flags.cmdChan_orNil <- cmd
		}
	}

	waitMsg, err := cmd.Wait( /*options*/ os.WRUSAGE)
	if err != nil {
		return err
	}
	if *flag_timings {
		addResourceUsage(e.name, waitMsg.Rusage)
	}
	if !waitMsg.Exited() {
		return os.NewError("unable to obtain the exit status of \"" + e.name + "%s\"")
	}
	if waitMsg.ExitStatus() != 0 {
		var errMsg string
		if len(dir) == 0 {
			errMsg = fmt.Sprintf("command \"%s\" returned an error", strings.Join(argv, " "))
		} else {
			errMsg = fmt.Sprintf("command \"%s\" run in directory \"%s\" returned an error", strings.Join(argv, " "), dir)
		}
		return os.NewError(errMsg)
	}

	return nil
}
<|endoftext|>


<commit_before>/*
Package fake is the fake data generatror for go (Golang), heavily inspired by forgery and ffaker Ruby gems

Most data and methods are ported from forgery/ffaker Ruby gems.

Currently english and russian languages are available.

For the list of available methods please look at https://godoc.org/github.com/icrowley/fake.

Fake embeds samples data files unless you call UseExternalData(true) in order to be able to work without external files dependencies when compiled, so, if you add new data files or make changes to existing ones don't forget to regenerate data.go file using github.com/mjibson/esc tool and esc -o data.go -pkg fake data command (or you can just use go generate command if you are using Go 1.4 or later).

Examples:
	name := fake.FirstName()
	fullname = := fake.FullName()
	product := fake.Product()

Changing language:
	err := fake.SetLang("ru")
	if err != nil {
		panic(err)
	}
	password := fake.SimplePassword()

Using english fallback:
	err := fake.SetLang("ru")
	if err != nil {
		panic(err)
	}
	fake.EnFallback(true)
	password := fake.Paragraph()

Using external data:
	fake.UseExternalData(true)
	password := fake.Paragraph()
*/
package fake

import (
	"fmt"
	"io/ioutil"
	"math/rand"
	"strconv"
	"strings"
	"time"
)

//go:generate go get github.com/mjibson/esc
//go:generate esc -o data.go -pkg fake data

// cat/subcat/lang/samples
type samplesTree map[string]map[string][]string

var samplesCache = make(samplesTree)
var r = rand.New(rand.NewSource(time.Now().UnixNano()))
var lang = "en"
var useExternalData = false
var enFallback = true
var availLangs = GetLangs()

var (
	// ErrNoLanguageFn is the error that indicates that given language is not available
	ErrNoLanguageFn = func(lang string) error { return fmt.Errorf("The language passed (%s) is not available", lang) }
	// ErrNoSamplesFn is the error that indicates that there are no samples for the given language
	ErrNoSamplesFn = func(lang string) error { return fmt.Errorf("No samples found for language: %s", lang) }
)

// GetLangs returns a slice of available languages
func GetLangs() []string {
	var langs []string
	for k, v := range data {
		if v.isDir && k != "/" && k != "/data" {
			langs = append(langs, strings.Replace(k, "/data/", "", 1))
		}
	}
	return langs
}

// SetLang sets the language in which the data should be generated
// returns error if passed language is not available
func SetLang(newLang string) error {
	found := false
	for _, l := range availLangs {
		if newLang == l {
			found = true
			break
		}
	}
	if !found {
		return ErrNoLanguageFn(newLang)
	}
	lang = newLang
	return nil
}

// UseExternalData sets the flag that allows using of external files as data providers (fake uses embedded ones by default)
func UseExternalData(flag bool) {
	useExternalData = flag
}

// EnFallback sets the flag that allows fake to fallback to englsh samples if the ones for the used languaged are not available
func EnFallback(flag bool) {
	enFallback = flag
}

func (st samplesTree) hasKeyPath(lang, cat string) bool {
	if _, ok := st[lang]; ok {
		if _, ok = st[lang][cat]; ok {
			return true
		}
	}
	return false
}

func join(parts ...string) string {
	var filtered []string
	for _, part := range parts {
		if part != "" {
			filtered = append(filtered, part)
		}
	}
	return strings.Join(filtered, " ")
}

func generate(lag, cat string, fallback bool) string {
	format := lookup(lang, cat+"_format", fallback)
	var result string
	for _, ru := range format {
		if ru != '#' {
			result += string(ru)
		} else {
			result += strconv.Itoa(r.Intn(10))
		}
	}
	return result
}

func lookup(lang, cat string, fallback bool) string {
	var samples []string

	if samplesCache.hasKeyPath(lang, cat) {
		samples = samplesCache[lang][cat]
	} else {
		var err error
		samples, err = populateSamples(lang, cat)
		if err != nil {
			if lang != "en" && fallback && enFallback && err.Error() == ErrNoSamplesFn(lang).Error() {
				return lookup("en", cat, false)
			}
			return ""
		}
	}

	return samples[r.Intn(len(samples))]
}

func populateSamples(lang, cat string) ([]string, error) {
	data, err := readFile(lang, cat)
	if err != nil {
		return nil, err
	}

	if _, ok := samplesCache[lang]; !ok {
		samplesCache[lang] = make(map[string][]string)
	}

	samples := strings.Split(strings.TrimSpace(string(data)), "\n")

	samplesCache[lang][cat] = samples
	return samples, nil
}

func readFile(lang, cat string) ([]byte, error) {
	fullpath := fmt.Sprintf("/data/%s/%s", lang, cat)
	file, err := FS(useExternalData).Open(fullpath)
	if err != nil {
		return nil, ErrNoSamplesFn(lang)
	}
	defer file.Close()

	return ioutil.ReadAll(file)
}
<commit_msg>Parameter is misnamed<commit_after>/*
Package fake is the fake data generatror for go (Golang), heavily inspired by forgery and ffaker Ruby gems

Most data and methods are ported from forgery/ffaker Ruby gems.

Currently english and russian languages are available.

For the list of available methods please look at https://godoc.org/github.com/icrowley/fake.

Fake embeds samples data files unless you call UseExternalData(true) in order to be able to work without external files dependencies when compiled, so, if you add new data files or make changes to existing ones don't forget to regenerate data.go file using github.com/mjibson/esc tool and esc -o data.go -pkg fake data command (or you can just use go generate command if you are using Go 1.4 or later).

Examples:
	name := fake.FirstName()
	fullname = := fake.FullName()
	product := fake.Product()

Changing language:
	err := fake.SetLang("ru")
	if err != nil {
		panic(err)
	}
	password := fake.SimplePassword()

Using english fallback:
	err := fake.SetLang("ru")
	if err != nil {
		panic(err)
	}
	fake.EnFallback(true)
	password := fake.Paragraph()

Using external data:
	fake.UseExternalData(true)
	password := fake.Paragraph()
*/
package fake

import (
	"fmt"
	"io/ioutil"
	"math/rand"
	"strconv"
	"strings"
	"time"
)

//go:generate go get github.com/mjibson/esc
//go:generate esc -o data.go -pkg fake data

// cat/subcat/lang/samples
type samplesTree map[string]map[string][]string

var samplesCache = make(samplesTree)
var r = rand.New(rand.NewSource(time.Now().UnixNano()))
var lang = "en"
var useExternalData = false
var enFallback = true
var availLangs = GetLangs()

var (
	// ErrNoLanguageFn is the error that indicates that given language is not available
	ErrNoLanguageFn = func(lang string) error { return fmt.Errorf("The language passed (%s) is not available", lang) }
	// ErrNoSamplesFn is the error that indicates that there are no samples for the given language
	ErrNoSamplesFn = func(lang string) error { return fmt.Errorf("No samples found for language: %s", lang) }
)

// GetLangs returns a slice of available languages
func GetLangs() []string {
	var langs []string
	for k, v := range data {
		if v.isDir && k != "/" && k != "/data" {
			langs = append(langs, strings.Replace(k, "/data/", "", 1))
		}
	}
	return langs
}

// SetLang sets the language in which the data should be generated
// returns error if passed language is not available
func SetLang(newLang string) error {
	found := false
	for _, l := range availLangs {
		if newLang == l {
			found = true
			break
		}
	}
	if !found {
		return ErrNoLanguageFn(newLang)
	}
	lang = newLang
	return nil
}

// UseExternalData sets the flag that allows using of external files as data providers (fake uses embedded ones by default)
func UseExternalData(flag bool) {
	useExternalData = flag
}

// EnFallback sets the flag that allows fake to fallback to englsh samples if the ones for the used languaged are not available
func EnFallback(flag bool) {
	enFallback = flag
}

func (st samplesTree) hasKeyPath(lang, cat string) bool {
	if _, ok := st[lang]; ok {
		if _, ok = st[lang][cat]; ok {
			return true
		}
	}
	return false
}

func join(parts ...string) string {
	var filtered []string
	for _, part := range parts {
		if part != "" {
			filtered = append(filtered, part)
		}
	}
	return strings.Join(filtered, " ")
}

func generate(lang, cat string, fallback bool) string {
	format := lookup(lang, cat+"_format", fallback)
	var result string
	for _, ru := range format {
		if ru != '#' {
			result += string(ru)
		} else {
			result += strconv.Itoa(r.Intn(10))
		}
	}
	return result
}

func lookup(lang, cat string, fallback bool) string {
	var samples []string

	if samplesCache.hasKeyPath(lang, cat) {
		samples = samplesCache[lang][cat]
	} else {
		var err error
		samples, err = populateSamples(lang, cat)
		if err != nil {
			if lang != "en" && fallback && enFallback && err.Error() == ErrNoSamplesFn(lang).Error() {
				return lookup("en", cat, false)
			}
			return ""
		}
	}

	return samples[r.Intn(len(samples))]
}

func populateSamples(lang, cat string) ([]string, error) {
	data, err := readFile(lang, cat)
	if err != nil {
		return nil, err
	}

	if _, ok := samplesCache[lang]; !ok {
		samplesCache[lang] = make(map[string][]string)
	}

	samples := strings.Split(strings.TrimSpace(string(data)), "\n")

	samplesCache[lang][cat] = samples
	return samples, nil
}

func readFile(lang, cat string) ([]byte, error) {
	fullpath := fmt.Sprintf("/data/%s/%s", lang, cat)
	file, err := FS(useExternalData).Open(fullpath)
	if err != nil {
		return nil, ErrNoSamplesFn(lang)
	}
	defer file.Close()

	return ioutil.ReadAll(file)
}
<|endoftext|>


<commit_before>package fako

import (
	"log"
	"math/rand"
	"reflect"
	"time"

	"github.com/serenize/snaker"
	"github.com/wawandco/fako/Godeps/_workspace/src/github.com/icrowley/fake"
)

var typeMapping = map[string]func() string{
	"Brand":                    fake.Brand,
	"Character":                fake.Character,
	"Characters":               fake.Characters,
	"City":                     fake.City,
	"Color":                    fake.Color,
	"Company":                  fake.Company,
	"Continent":                fake.Continent,
	"Country":                  fake.Country,
	"CreditCardType":           fake.CreditCardType,
	"Currency":                 fake.Currency,
	"CurrencyCode":             fake.CurrencyCode,
	"Digits":                   fake.Digits,
	"DomainName":               fake.DomainName,
	"DomainZone":               fake.DomainZone,
	"EmailAddress":             fake.EmailAddress,
	"EmailBody":                fake.EmailBody,
	"EmailSubject":             fake.EmailSubject,
	"FemaleFirstName":          fake.FemaleFirstName,
	"FemaleFullName":           fake.FemaleFullName,
	"FemaleFullNameWithPrefix": fake.FemaleFullNameWithPrefix,
	"FemaleFullNameWithSuffix": fake.FemaleFullNameWithSuffix,
	"FemaleLastName":           fake.FemaleLastName,
	"FemalePatronymic":         fake.FemalePatronymic,
	"FirstName":                fake.FirstName,
	"FullName":                 fake.FullName,
	"FullNameWithPrefix":       fake.FullNameWithPrefix,
	"FullNameWithSuffix":       fake.FullNameWithSuffix,
	"Gender":                   fake.Gender,
	"GenderAbbrev":             fake.GenderAbbrev,
	"HexColor":                 fake.HexColor,
	"HexColorShort":            fake.HexColorShort,
	"IPv4":                     fake.IPv4,
	"Industry":                 fake.Industry,
	"JobTitle":                 fake.JobTitle,
	"Language":                 fake.Language,
	"LastName":                 fake.LastName,
	"LatitudeDirection":        fake.LatitudeDirection,
	"LongitudeDirection":       fake.LongitudeDirection,
	"MaleFirstName":            fake.MaleFirstName,
	"MaleFullName":             fake.MaleFullName,
	"MaleFullNameWithPrefix":   fake.MaleFullNameWithPrefix,
	"MaleFullNameWithSuffix":   fake.MaleFullNameWithSuffix,
	"MaleLastName":             fake.MaleLastName,
	"MalePatronymic":           fake.MalePatronymic,
	"Model":                    fake.Model,
	"Month":                    fake.Month,
	"MonthShort":               fake.MonthShort,
	"Paragraph":                fake.Paragraph,
	"Paragraphs":               fake.Paragraphs,
	"Patronymic":               fake.Patronymic,
	"Phone":                    fake.Phone,
	"Product":                  fake.Product,
	"ProductName":              fake.ProductName,
	"Sentence":                 fake.Sentence,
	"Sentences":                fake.Sentences,
	"SimplePassword":           fake.SimplePassword,
	"State":                    fake.State,
	"StateAbbrev":              fake.StateAbbrev,
	"Street":                   fake.Street,
	"StreetAddress":            fake.StreetAddress,
	"Title":                    fake.Title,
	"TopLevelDomain":           fake.TopLevelDomain,
	"UserName":                 fake.UserName,
	"WeekDay":                  fake.WeekDay,
	"WeekDayShort":             fake.WeekDayShort,
	"Word":                     fake.Word,
	"Words":                    fake.Words,
	"Zip":                      fake.Zip,
}

var customGenerators = map[string]func() string{}

//Fill fill all the fields that have a fako: tag
func Fill(elems ...interface{}) {
	for _, elem := range elems {
		log.Println(elem)
		FillElem(elem)
	}
}

func FillElem(strukt interface{}) {
	fillWithDetails(strukt, []string{}, []string{})
}

//FillOnly fill fields that have a fako: tag and its name is on the second argument array
func FillOnly(strukt interface{}, fields ...string) {
	fillWithDetails(strukt, fields, []string{})
}

//FillExcept fill fields that have a fako: tag and its name is not on the second argument array
func FillExcept(strukt interface{}, fields ...string) {
	fillWithDetails(strukt, []string{}, fields)
}

// Register allows user to add his own data generators for special cases
// that we could not cover with the generators that fako includes by default.
func Register(identifier string, generator func() string) {
	fakeType := snaker.SnakeToCamel(identifier)
	customGenerators[fakeType] = generator
}

func fillWithDetails(strukt interface{}, only []string, except []string) {
	elem := reflect.ValueOf(strukt).Elem()
	elemT := reflect.TypeOf(strukt).Elem()

	for i := 0; i < elem.NumField(); i++ {
		field := elem.Field(i)
		fieldt := elemT.Field(i)
		fakeType := fieldt.Tag.Get("fako")

		if fakeType != "" {
			fakeType = snaker.SnakeToCamel(fakeType)
			function := findFakeFunctionFor(fakeType)

			inOnly := len(only) == 0 || (len(only) > 0 && contains(only, fieldt.Name))
			notInExcept := len(except) == 0 || (len(except) > 0 && !contains(except, fieldt.Name))

			if field.CanSet() && fakeType != "" && inOnly && notInExcept {
				field.SetString(function())
			}
		}

	}
}

func allGenerators() map[string]func() string {
	dst := typeMapping
	for k, v := range customGenerators {
		dst[k] = v
	}

	return dst
}

func findFakeFunctionFor(fako string) func() string {
	result := func() string { return "" }

	for kind, function := range allGenerators() {
		if fako == kind {
			result = function
			break
		}
	}

	return result
}

// Fuzz Fills passed interface with random data based on the struct field type,
// take a look at fuzzValueFor for details on supported data types.
func Fuzz(e interface{}) {
	ty := reflect.TypeOf(e)

	if ty.Kind() == reflect.Ptr {
		ty = ty.Elem()
	}

	if ty.Kind() == reflect.Struct {
		value := reflect.ValueOf(e).Elem()
		for i := 0; i < ty.NumField(); i++ {
			field := value.Field(i)

			if field.CanSet() {
				field.Set(fuzzValueFor(field.Kind()))
			}
		}

	}
}

// fuzzValueFor Generates random values for the following types:
// string, bool, int, int32, int64, float32, float64
func fuzzValueFor(kind reflect.Kind) reflect.Value {
	r := rand.New(rand.NewSource(time.Now().UnixNano()))
	switch kind {
	case reflect.String:
		return reflect.ValueOf(randomString(25))
	case reflect.Int:
		return reflect.ValueOf(r.Int())
	case reflect.Int32:
		return reflect.ValueOf(r.Int31())
	case reflect.Int64:
		return reflect.ValueOf(r.Int63())
	case reflect.Float32:
		return reflect.ValueOf(r.Float32())
	case reflect.Float64:
		return reflect.ValueOf(r.Float64())
	case reflect.Bool:
		val := r.Intn(2) > 0
		return reflect.ValueOf(val)
	}

	return reflect.ValueOf("")
}
<commit_msg>commented out unnecessary logging statement that was spamming the console<commit_after>package fako

import (
	"log"
	"math/rand"
	"reflect"
	"time"

	"github.com/serenize/snaker"
	"github.com/wawandco/fako/Godeps/_workspace/src/github.com/icrowley/fake"
)

var typeMapping = map[string]func() string{
	"Brand":                    fake.Brand,
	"Character":                fake.Character,
	"Characters":               fake.Characters,
	"City":                     fake.City,
	"Color":                    fake.Color,
	"Company":                  fake.Company,
	"Continent":                fake.Continent,
	"Country":                  fake.Country,
	"CreditCardType":           fake.CreditCardType,
	"Currency":                 fake.Currency,
	"CurrencyCode":             fake.CurrencyCode,
	"Digits":                   fake.Digits,
	"DomainName":               fake.DomainName,
	"DomainZone":               fake.DomainZone,
	"EmailAddress":             fake.EmailAddress,
	"EmailBody":                fake.EmailBody,
	"EmailSubject":             fake.EmailSubject,
	"FemaleFirstName":          fake.FemaleFirstName,
	"FemaleFullName":           fake.FemaleFullName,
	"FemaleFullNameWithPrefix": fake.FemaleFullNameWithPrefix,
	"FemaleFullNameWithSuffix": fake.FemaleFullNameWithSuffix,
	"FemaleLastName":           fake.FemaleLastName,
	"FemalePatronymic":         fake.FemalePatronymic,
	"FirstName":                fake.FirstName,
	"FullName":                 fake.FullName,
	"FullNameWithPrefix":       fake.FullNameWithPrefix,
	"FullNameWithSuffix":       fake.FullNameWithSuffix,
	"Gender":                   fake.Gender,
	"GenderAbbrev":             fake.GenderAbbrev,
	"HexColor":                 fake.HexColor,
	"HexColorShort":            fake.HexColorShort,
	"IPv4":                     fake.IPv4,
	"Industry":                 fake.Industry,
	"JobTitle":                 fake.JobTitle,
	"Language":                 fake.Language,
	"LastName":                 fake.LastName,
	"LatitudeDirection":        fake.LatitudeDirection,
	"LongitudeDirection":       fake.LongitudeDirection,
	"MaleFirstName":            fake.MaleFirstName,
	"MaleFullName":             fake.MaleFullName,
	"MaleFullNameWithPrefix":   fake.MaleFullNameWithPrefix,
	"MaleFullNameWithSuffix":   fake.MaleFullNameWithSuffix,
	"MaleLastName":             fake.MaleLastName,
	"MalePatronymic":           fake.MalePatronymic,
	"Model":                    fake.Model,
	"Month":                    fake.Month,
	"MonthShort":               fake.MonthShort,
	"Paragraph":                fake.Paragraph,
	"Paragraphs":               fake.Paragraphs,
	"Patronymic":               fake.Patronymic,
	"Phone":                    fake.Phone,
	"Product":                  fake.Product,
	"ProductName":              fake.ProductName,
	"Sentence":                 fake.Sentence,
	"Sentences":                fake.Sentences,
	"SimplePassword":           fake.SimplePassword,
	"State":                    fake.State,
	"StateAbbrev":              fake.StateAbbrev,
	"Street":                   fake.Street,
	"StreetAddress":            fake.StreetAddress,
	"Title":                    fake.Title,
	"TopLevelDomain":           fake.TopLevelDomain,
	"UserName":                 fake.UserName,
	"WeekDay":                  fake.WeekDay,
	"WeekDayShort":             fake.WeekDayShort,
	"Word":                     fake.Word,
	"Words":                    fake.Words,
	"Zip":                      fake.Zip,
}

var customGenerators = map[string]func() string{}

//Fill fill all the fields that have a fako: tag
func Fill(elems ...interface{}) {
	for _, elem := range elems {
		//log.Println(elem)
		FillElem(elem)
	}
}

func FillElem(strukt interface{}) {
	fillWithDetails(strukt, []string{}, []string{})
}

//FillOnly fill fields that have a fako: tag and its name is on the second argument array
func FillOnly(strukt interface{}, fields ...string) {
	fillWithDetails(strukt, fields, []string{})
}

//FillExcept fill fields that have a fako: tag and its name is not on the second argument array
func FillExcept(strukt interface{}, fields ...string) {
	fillWithDetails(strukt, []string{}, fields)
}

// Register allows user to add his own data generators for special cases
// that we could not cover with the generators that fako includes by default.
func Register(identifier string, generator func() string) {
	fakeType := snaker.SnakeToCamel(identifier)
	customGenerators[fakeType] = generator
}

func fillWithDetails(strukt interface{}, only []string, except []string) {
	elem := reflect.ValueOf(strukt).Elem()
	elemT := reflect.TypeOf(strukt).Elem()

	for i := 0; i < elem.NumField(); i++ {
		field := elem.Field(i)
		fieldt := elemT.Field(i)
		fakeType := fieldt.Tag.Get("fako")

		if fakeType != "" {
			fakeType = snaker.SnakeToCamel(fakeType)
			function := findFakeFunctionFor(fakeType)

			inOnly := len(only) == 0 || (len(only) > 0 && contains(only, fieldt.Name))
			notInExcept := len(except) == 0 || (len(except) > 0 && !contains(except, fieldt.Name))

			if field.CanSet() && fakeType != "" && inOnly && notInExcept {
				field.SetString(function())
			}
		}

	}
}

func allGenerators() map[string]func() string {
	dst := typeMapping
	for k, v := range customGenerators {
		dst[k] = v
	}

	return dst
}

func findFakeFunctionFor(fako string) func() string {
	result := func() string { return "" }

	for kind, function := range allGenerators() {
		if fako == kind {
			result = function
			break
		}
	}

	return result
}

// Fuzz Fills passed interface with random data based on the struct field type,
// take a look at fuzzValueFor for details on supported data types.
func Fuzz(e interface{}) {
	ty := reflect.TypeOf(e)

	if ty.Kind() == reflect.Ptr {
		ty = ty.Elem()
	}

	if ty.Kind() == reflect.Struct {
		value := reflect.ValueOf(e).Elem()
		for i := 0; i < ty.NumField(); i++ {
			field := value.Field(i)

			if field.CanSet() {
				field.Set(fuzzValueFor(field.Kind()))
			}
		}

	}
}

// fuzzValueFor Generates random values for the following types:
// string, bool, int, int32, int64, float32, float64
func fuzzValueFor(kind reflect.Kind) reflect.Value {
	r := rand.New(rand.NewSource(time.Now().UnixNano()))
	switch kind {
	case reflect.String:
		return reflect.ValueOf(randomString(25))
	case reflect.Int:
		return reflect.ValueOf(r.Int())
	case reflect.Int32:
		return reflect.ValueOf(r.Int31())
	case reflect.Int64:
		return reflect.ValueOf(r.Int63())
	case reflect.Float32:
		return reflect.ValueOf(r.Float32())
	case reflect.Float64:
		return reflect.ValueOf(r.Float64())
	case reflect.Bool:
		val := r.Intn(2) > 0
		return reflect.ValueOf(val)
	}

	return reflect.ValueOf("")
}
<|endoftext|>


<commit_before>// +build windows

package winio

import (
	"errors"
	"io"
	"runtime"
	"sync"
	"sync/atomic"
	"syscall"
	"time"
)

//sys cancelIoEx(file syscall.Handle, o *syscall.Overlapped) (err error) = CancelIoEx
//sys createIoCompletionPort(file syscall.Handle, port syscall.Handle, key uintptr, threadCount uint32) (newport syscall.Handle, err error) = CreateIoCompletionPort
//sys getQueuedCompletionStatus(port syscall.Handle, bytes *uint32, key *uintptr, o **ioOperation, timeout uint32) (err error) = GetQueuedCompletionStatus
//sys setFileCompletionNotificationModes(h syscall.Handle, flags uint8) (err error) = SetFileCompletionNotificationModes
//sys timeBeginPeriod(period uint32) (n int32) = winmm.timeBeginPeriod

type atomicBool int32

func (b *atomicBool) isSet() bool { return atomic.LoadInt32((*int32)(b)) != 0 }
func (b *atomicBool) setFalse()   { atomic.StoreInt32((*int32)(b), 0) }
func (b *atomicBool) setTrue()    { atomic.StoreInt32((*int32)(b), 1) }

const (
	cFILE_SKIP_COMPLETION_PORT_ON_SUCCESS = 1
	cFILE_SKIP_SET_EVENT_ON_HANDLE        = 2
)

var (
	ErrFileClosed = errors.New("file has already been closed")
	ErrTimeout    = &timeoutError{}
)

type timeoutError struct{}

func (e *timeoutError) Error() string   { return "i/o timeout" }
func (e *timeoutError) Timeout() bool   { return true }
func (e *timeoutError) Temporary() bool { return true }

type timeoutChan chan struct{}

var ioInitOnce sync.Once
var ioCompletionPort syscall.Handle

// ioResult contains the result of an asynchronous IO operation
type ioResult struct {
	bytes uint32
	err   error
}

// ioOperation represents an outstanding asynchronous Win32 IO
type ioOperation struct {
	o  syscall.Overlapped
	ch chan ioResult
}

func initIo() {
	h, err := createIoCompletionPort(syscall.InvalidHandle, 0, 0, 0xffffffff)
	if err != nil {
		panic(err)
	}
	ioCompletionPort = h
	go ioCompletionProcessor(h)
}

// win32File implements Reader, Writer, and Closer on a Win32 handle without blocking in a syscall.
// It takes ownership of this handle and will close it if it is garbage collected.
type win32File struct {
	handle        syscall.Handle
	wg            sync.WaitGroup
	closing       bool
	readDeadline  deadlineHandler
	writeDeadline deadlineHandler
}

type deadlineHandler struct {
	setLock     sync.Mutex
	channel     timeoutChan
	channelLock sync.RWMutex
	timer       *time.Timer
	timedout    atomicBool
}

// makeWin32File makes a new win32File from an existing file handle
func makeWin32File(h syscall.Handle) (*win32File, error) {
	f := &win32File{handle: h}
	ioInitOnce.Do(initIo)
	_, err := createIoCompletionPort(h, ioCompletionPort, 0, 0xffffffff)
	if err != nil {
		return nil, err
	}
	err = setFileCompletionNotificationModes(h, cFILE_SKIP_COMPLETION_PORT_ON_SUCCESS|cFILE_SKIP_SET_EVENT_ON_HANDLE)
	if err != nil {
		return nil, err
	}
	f.readDeadline.channel = make(timeoutChan)
	f.writeDeadline.channel = make(timeoutChan)
	return f, nil
}

func MakeOpenFile(h syscall.Handle) (io.ReadWriteCloser, error) {
	return makeWin32File(h)
}

// closeHandle closes the resources associated with a Win32 handle
func (f *win32File) closeHandle() {
	if !f.closing {
		// cancel all IO and wait for it to complete
		f.closing = true
		cancelIoEx(f.handle, nil)
		f.wg.Wait()
		// at this point, no new IO can start
		syscall.Close(f.handle)
		f.handle = 0
	}
}

// Close closes a win32File.
func (f *win32File) Close() error {
	f.closeHandle()
	return nil
}

// prepareIo prepares for a new IO operation.
// The caller must call f.wg.Done() when the IO is finished, prior to Close() returning.
func (f *win32File) prepareIo() (*ioOperation, error) {
	f.wg.Add(1)
	if f.closing {
		return nil, ErrFileClosed
	}
	c := &ioOperation{}
	c.ch = make(chan ioResult)
	return c, nil
}

// ioCompletionProcessor processes completed async IOs forever
func ioCompletionProcessor(h syscall.Handle) {
	// Set the timer resolution to 1. This fixes a performance regression in golang 1.6.
	timeBeginPeriod(1)
	for {
		var bytes uint32
		var key uintptr
		var op *ioOperation
		err := getQueuedCompletionStatus(h, &bytes, &key, &op, syscall.INFINITE)
		if op == nil {
			panic(err)
		}
		op.ch <- ioResult{bytes, err}
	}
}

// asyncIo processes the return value from ReadFile or WriteFile, blocking until
// the operation has actually completed.
func (f *win32File) asyncIo(c *ioOperation, d *deadlineHandler, bytes uint32, err error) (int, error) {
	if err != syscall.ERROR_IO_PENDING {
		return int(bytes), err
	}

	if f.closing {
		cancelIoEx(f.handle, &c.o)
	}

	var timeout timeoutChan
	if d != nil {
		d.channelLock.Lock()
		timeout = d.channel
		d.channelLock.Unlock()
	}

	var r ioResult
	select {
	case r = <-c.ch:
		err = r.err
		if err == syscall.ERROR_OPERATION_ABORTED {
			if f.closing {
				err = ErrFileClosed
			}
		}
	case <-timeout:
		cancelIoEx(f.handle, &c.o)
		r = <-c.ch
		err = r.err
		if err == syscall.ERROR_OPERATION_ABORTED {
			err = ErrTimeout
		}
	}

	// runtime.KeepAlive is needed, as c is passed via native
	// code to ioCompletionProcessor, c must remain alive
	// until the channel read is complete.
	runtime.KeepAlive(c)
	return int(r.bytes), err
}

// Read reads from a file handle.
func (f *win32File) Read(b []byte) (int, error) {
	c, err := f.prepareIo()
	if err != nil {
		return 0, err
	}
	defer f.wg.Done()

	if f.readDeadline.timedout.isSet() {
		return 0, ErrTimeout
	}

	var bytes uint32
	err = syscall.ReadFile(f.handle, b, &bytes, &c.o)
	n, err := f.asyncIo(c, &f.readDeadline, bytes, err)
	runtime.KeepAlive(b)

	// Handle EOF conditions.
	if err == nil && n == 0 && len(b) != 0 {
		return 0, io.EOF
	} else if err == syscall.ERROR_BROKEN_PIPE {
		return 0, io.EOF
	} else {
		return n, err
	}
}

// Write writes to a file handle.
func (f *win32File) Write(b []byte) (int, error) {
	c, err := f.prepareIo()
	if err != nil {
		return 0, err
	}
	defer f.wg.Done()

	if f.writeDeadline.timedout.isSet() {
		return 0, ErrTimeout
	}

	var bytes uint32
	err = syscall.WriteFile(f.handle, b, &bytes, &c.o)
	n, err := f.asyncIo(c, &f.writeDeadline, bytes, err)
	runtime.KeepAlive(b)
	return n, err
}

func (f *win32File) SetReadDeadline(deadline time.Time) error {
	return f.readDeadline.set(deadline)
}

func (f *win32File) SetWriteDeadline(deadline time.Time) error {
	return f.writeDeadline.set(deadline)
}

func (f *win32File) Flush() error {
	return syscall.FlushFileBuffers(f.handle)
}

func (d *deadlineHandler) set(deadline time.Time) error {
	d.setLock.Lock()
	defer d.setLock.Unlock()

	if d.timer != nil {
		if !d.timer.Stop() {
			<-d.channel
		}
		d.timer = nil
	}
	d.timedout.setFalse()

	select {
	case <-d.channel:
		d.channelLock.Lock()
		d.channel = make(chan struct{})
		d.channelLock.Unlock()
	default:
	}

	if deadline.IsZero() {
		return nil
	}

	timeoutIO := func() {
		d.timedout.setTrue()
		close(d.channel)
	}

	now := time.Now()
	duration := deadline.Sub(now)
	if deadline.After(now) {
		// Deadline is in the future, set a timer to wait
		d.timer = time.AfterFunc(duration, timeoutIO)
	} else {
		// Deadline is in the past. Cancel all pending IO now.
		timeoutIO()
	}
	return nil
}
<commit_msg>Don't increment the wait count if the file is closing<commit_after>// +build windows

package winio

import (
	"errors"
	"io"
	"runtime"
	"sync"
	"sync/atomic"
	"syscall"
	"time"
)

//sys cancelIoEx(file syscall.Handle, o *syscall.Overlapped) (err error) = CancelIoEx
//sys createIoCompletionPort(file syscall.Handle, port syscall.Handle, key uintptr, threadCount uint32) (newport syscall.Handle, err error) = CreateIoCompletionPort
//sys getQueuedCompletionStatus(port syscall.Handle, bytes *uint32, key *uintptr, o **ioOperation, timeout uint32) (err error) = GetQueuedCompletionStatus
//sys setFileCompletionNotificationModes(h syscall.Handle, flags uint8) (err error) = SetFileCompletionNotificationModes
//sys timeBeginPeriod(period uint32) (n int32) = winmm.timeBeginPeriod

type atomicBool int32

func (b *atomicBool) isSet() bool { return atomic.LoadInt32((*int32)(b)) != 0 }
func (b *atomicBool) setFalse()   { atomic.StoreInt32((*int32)(b), 0) }
func (b *atomicBool) setTrue()    { atomic.StoreInt32((*int32)(b), 1) }

const (
	cFILE_SKIP_COMPLETION_PORT_ON_SUCCESS = 1
	cFILE_SKIP_SET_EVENT_ON_HANDLE        = 2
)

var (
	ErrFileClosed = errors.New("file has already been closed")
	ErrTimeout    = &timeoutError{}
)

type timeoutError struct{}

func (e *timeoutError) Error() string   { return "i/o timeout" }
func (e *timeoutError) Timeout() bool   { return true }
func (e *timeoutError) Temporary() bool { return true }

type timeoutChan chan struct{}

var ioInitOnce sync.Once
var ioCompletionPort syscall.Handle

// ioResult contains the result of an asynchronous IO operation
type ioResult struct {
	bytes uint32
	err   error
}

// ioOperation represents an outstanding asynchronous Win32 IO
type ioOperation struct {
	o  syscall.Overlapped
	ch chan ioResult
}

func initIo() {
	h, err := createIoCompletionPort(syscall.InvalidHandle, 0, 0, 0xffffffff)
	if err != nil {
		panic(err)
	}
	ioCompletionPort = h
	go ioCompletionProcessor(h)
}

// win32File implements Reader, Writer, and Closer on a Win32 handle without blocking in a syscall.
// It takes ownership of this handle and will close it if it is garbage collected.
type win32File struct {
	handle        syscall.Handle
	wg            sync.WaitGroup
	closing       bool
	readDeadline  deadlineHandler
	writeDeadline deadlineHandler
}

type deadlineHandler struct {
	setLock     sync.Mutex
	channel     timeoutChan
	channelLock sync.RWMutex
	timer       *time.Timer
	timedout    atomicBool
}

// makeWin32File makes a new win32File from an existing file handle
func makeWin32File(h syscall.Handle) (*win32File, error) {
	f := &win32File{handle: h}
	ioInitOnce.Do(initIo)
	_, err := createIoCompletionPort(h, ioCompletionPort, 0, 0xffffffff)
	if err != nil {
		return nil, err
	}
	err = setFileCompletionNotificationModes(h, cFILE_SKIP_COMPLETION_PORT_ON_SUCCESS|cFILE_SKIP_SET_EVENT_ON_HANDLE)
	if err != nil {
		return nil, err
	}
	f.readDeadline.channel = make(timeoutChan)
	f.writeDeadline.channel = make(timeoutChan)
	return f, nil
}

func MakeOpenFile(h syscall.Handle) (io.ReadWriteCloser, error) {
	return makeWin32File(h)
}

// closeHandle closes the resources associated with a Win32 handle
func (f *win32File) closeHandle() {
	if !f.closing {
		// cancel all IO and wait for it to complete
		f.closing = true
		cancelIoEx(f.handle, nil)
		f.wg.Wait()
		// at this point, no new IO can start
		syscall.Close(f.handle)
		f.handle = 0
	}
}

// Close closes a win32File.
func (f *win32File) Close() error {
	f.closeHandle()
	return nil
}

// prepareIo prepares for a new IO operation.
// The caller must call f.wg.Done() when the IO is finished, prior to Close() returning.
func (f *win32File) prepareIo() (*ioOperation, error) {
	if f.closing {
		return nil, ErrFileClosed
	}
	f.wg.Add(1)
	c := &ioOperation{}
	c.ch = make(chan ioResult)
	return c, nil
}

// ioCompletionProcessor processes completed async IOs forever
func ioCompletionProcessor(h syscall.Handle) {
	// Set the timer resolution to 1. This fixes a performance regression in golang 1.6.
	timeBeginPeriod(1)
	for {
		var bytes uint32
		var key uintptr
		var op *ioOperation
		err := getQueuedCompletionStatus(h, &bytes, &key, &op, syscall.INFINITE)
		if op == nil {
			panic(err)
		}
		op.ch <- ioResult{bytes, err}
	}
}

// asyncIo processes the return value from ReadFile or WriteFile, blocking until
// the operation has actually completed.
func (f *win32File) asyncIo(c *ioOperation, d *deadlineHandler, bytes uint32, err error) (int, error) {
	if err != syscall.ERROR_IO_PENDING {
		return int(bytes), err
	}

	if f.closing {
		cancelIoEx(f.handle, &c.o)
	}

	var timeout timeoutChan
	if d != nil {
		d.channelLock.Lock()
		timeout = d.channel
		d.channelLock.Unlock()
	}

	var r ioResult
	select {
	case r = <-c.ch:
		err = r.err
		if err == syscall.ERROR_OPERATION_ABORTED {
			if f.closing {
				err = ErrFileClosed
			}
		}
	case <-timeout:
		cancelIoEx(f.handle, &c.o)
		r = <-c.ch
		err = r.err
		if err == syscall.ERROR_OPERATION_ABORTED {
			err = ErrTimeout
		}
	}

	// runtime.KeepAlive is needed, as c is passed via native
	// code to ioCompletionProcessor, c must remain alive
	// until the channel read is complete.
	runtime.KeepAlive(c)
	return int(r.bytes), err
}

// Read reads from a file handle.
func (f *win32File) Read(b []byte) (int, error) {
	c, err := f.prepareIo()
	if err != nil {
		return 0, err
	}
	defer f.wg.Done()

	if f.readDeadline.timedout.isSet() {
		return 0, ErrTimeout
	}

	var bytes uint32
	err = syscall.ReadFile(f.handle, b, &bytes, &c.o)
	n, err := f.asyncIo(c, &f.readDeadline, bytes, err)
	runtime.KeepAlive(b)

	// Handle EOF conditions.
	if err == nil && n == 0 && len(b) != 0 {
		return 0, io.EOF
	} else if err == syscall.ERROR_BROKEN_PIPE {
		return 0, io.EOF
	} else {
		return n, err
	}
}

// Write writes to a file handle.
func (f *win32File) Write(b []byte) (int, error) {
	c, err := f.prepareIo()
	if err != nil {
		return 0, err
	}
	defer f.wg.Done()

	if f.writeDeadline.timedout.isSet() {
		return 0, ErrTimeout
	}

	var bytes uint32
	err = syscall.WriteFile(f.handle, b, &bytes, &c.o)
	n, err := f.asyncIo(c, &f.writeDeadline, bytes, err)
	runtime.KeepAlive(b)
	return n, err
}

func (f *win32File) SetReadDeadline(deadline time.Time) error {
	return f.readDeadline.set(deadline)
}

func (f *win32File) SetWriteDeadline(deadline time.Time) error {
	return f.writeDeadline.set(deadline)
}

func (f *win32File) Flush() error {
	return syscall.FlushFileBuffers(f.handle)
}

func (d *deadlineHandler) set(deadline time.Time) error {
	d.setLock.Lock()
	defer d.setLock.Unlock()

	if d.timer != nil {
		if !d.timer.Stop() {
			<-d.channel
		}
		d.timer = nil
	}
	d.timedout.setFalse()

	select {
	case <-d.channel:
		d.channelLock.Lock()
		d.channel = make(chan struct{})
		d.channelLock.Unlock()
	default:
	}

	if deadline.IsZero() {
		return nil
	}

	timeoutIO := func() {
		d.timedout.setTrue()
		close(d.channel)
	}

	now := time.Now()
	duration := deadline.Sub(now)
	if deadline.After(now) {
		// Deadline is in the future, set a timer to wait
		d.timer = time.AfterFunc(duration, timeoutIO)
	} else {
		// Deadline is in the past. Cancel all pending IO now.
		timeoutIO()
	}
	return nil
}
<|endoftext|>


<commit_before>package pipe

import (
	"os"
	"path/filepath"
)

// FindFilter is a filter that produces matching nodes under a filesystem
// directory.
type FindFilter struct {
	dir                        string
	seentype                   bool
	files, dirs, symlinks, all bool
	skipdir                    map[string]bool
}

// Find returns a filter that produces matching nodes under a
// filesystem directory.  If no type constraining methods (Files,
// Dirs, Symlinks) are called, all nodes are printed. Otherwise, just
// nodes with a type corresponding to at least one of the called
// methods are printed.
func Find(dir string) *FindFilter {
	return &FindFilter{dir: dir}
}

// Files adjusts f so it matches all regular files.
func (f *FindFilter) Files() *FindFilter {
	f.seentype = true
	f.files = true
	return f
}

// Dirs adjusts f so it matches all directories.
func (f *FindFilter) Dirs() *FindFilter {
	f.seentype = true
	f.dirs = true
	return f
}

// Symlinks adjusts f so it matches all symbolic links.
func (f *FindFilter) Symlinks() *FindFilter {
	f.seentype = true
	f.symlinks = true
	return f
}

// All adjusts f so it matches all types of nodes.
func (f *FindFilter) All() *FindFilter {
	f.seentype = true
	f.all = true
	return f
}

// SkipDir adjusts f so that any node that is one of dirs or a
// descendant of one of the dirs is skipped.
func (f *FindFilter) SkipDir(dirs ...string) *FindFilter {
	if f.skipdir == nil {
		f.skipdir = make(map[string]bool)
	}
	for _, d := range dirs {
		f.skipdir[d] = true
	}
	return f
}

func (f *FindFilter) shouldYield(s os.FileInfo) bool {
	switch {
	case !f.seentype:
		// If no types are specified, match everything
		return true
	case f.all:
		return true
	case f.files && s.Mode().IsRegular():
		return true
	case f.dirs && s.Mode().IsDir():
		return true
	case f.symlinks && s.Mode()&os.ModeSymlink != 0:
		return true
	default:
		return false
	}
}

func (f *FindFilter) RunFilter(arg Arg) error {
	return filepath.Walk(f.dir, func(n string, s os.FileInfo, e error) error {
		if e != nil {
			return e
		}
		if f.shouldYield(s) {
			arg.Out <- n
		}
		if f.skipdir != nil && f.skipdir[n] && s.Mode().IsDir() {
			return filepath.SkipDir
		}
		return nil
	})
}
<commit_msg>make SkipDir skip the specified directory itself as specified<commit_after>package pipe

import (
	"os"
	"path/filepath"
)

// FindFilter is a filter that produces matching nodes under a filesystem
// directory.
type FindFilter struct {
	dir                        string
	seentype                   bool
	files, dirs, symlinks, all bool
	skipdir                    map[string]bool
}

// Find returns a filter that produces matching nodes under a
// filesystem directory.  If no type constraining methods (Files,
// Dirs, Symlinks) are called, all nodes are printed. Otherwise, just
// nodes with a type corresponding to at least one of the called
// methods are printed.
func Find(dir string) *FindFilter {
	return &FindFilter{dir: dir}
}

// Files adjusts f so it matches all regular files.
func (f *FindFilter) Files() *FindFilter {
	f.seentype = true
	f.files = true
	return f
}

// Dirs adjusts f so it matches all directories.
func (f *FindFilter) Dirs() *FindFilter {
	f.seentype = true
	f.dirs = true
	return f
}

// Symlinks adjusts f so it matches all symbolic links.
func (f *FindFilter) Symlinks() *FindFilter {
	f.seentype = true
	f.symlinks = true
	return f
}

// All adjusts f so it matches all types of nodes.
func (f *FindFilter) All() *FindFilter {
	f.seentype = true
	f.all = true
	return f
}

// SkipDir adjusts f so that any node that is one of dirs or a
// descendant of one of the dirs is skipped.
func (f *FindFilter) SkipDir(dirs ...string) *FindFilter {
	if f.skipdir == nil {
		f.skipdir = make(map[string]bool)
	}
	for _, d := range dirs {
		f.skipdir[d] = true
	}
	return f
}

func (f *FindFilter) shouldYield(s os.FileInfo) bool {
	switch {
	case !f.seentype:
		// If no types are specified, match everything
		return true
	case f.all:
		return true
	case f.files && s.Mode().IsRegular():
		return true
	case f.dirs && s.Mode().IsDir():
		return true
	case f.symlinks && s.Mode()&os.ModeSymlink != 0:
		return true
	default:
		return false
	}
}

func (f *FindFilter) RunFilter(arg Arg) error {
	return filepath.Walk(f.dir, func(n string, s os.FileInfo, e error) error {
		if e != nil {
			return e
		}
		if f.skipdir != nil && f.skipdir[n] && s.Mode().IsDir() {
			return filepath.SkipDir
		}
		if f.shouldYield(s) {
			arg.Out <- n
		}
		return nil
	})
}
<|endoftext|>


<commit_before>// Copyright (c) 2014 Soichiro Kashima
// Licensed under MIT license.

package fint

import (
	"bufio"
	"encoding/json"
	"errors"
	"flag"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"path/filepath"
	"regexp"
)

const (
	errPrefix = "fint: "
	bufSize   = 4096
)

type Opt struct {
	SrcRoot    string
	ConfigPath string
	Locale     string
	Id         string
}

type Rule struct {
	Pattern string
	Args    []interface{}
	Message map[string]string
}

type Module struct {
	Id    string
	Rules []Rule
}

type RuleSet struct {
	Id          string
	Description string
	Pattern     string
	Modules     []Module
}

type Config struct {
	RuleSets []RuleSet
}

type Violation struct {
	Filename string
	Line     int
	Message  string
}

var (
	opt        *Opt
	config     *Config
	violations []Violation
	term       string
)

func newError(message string) error {
	return errors.New(errPrefix + message)
}

func getOpts() (err error) {
	srcRoot := flag.String("s", "", "Source directory")
	configPath := flag.String("c", "conf/config.json", "Config file path")
	locale := flag.String("l", "default", "Message locale")
	id := flag.String("i", "", "ID of the rule set")
	flag.Parse()
	if *srcRoot == "" {
		err = newError("source directory is required.")
		return
	}
	if *id == "" {
		err = newError("ID of the rule set is required.")
		return
	}
	opt = &Opt{SrcRoot: *srcRoot, ConfigPath: *configPath, Locale: *locale, Id: *id}
	return
}

func printViolation(v Violation) {
	var format string
	if term == "dumb" {
		format = "%s:%d:1: warning: %s\n"
	} else {
		format = "%s:%d:1: warning: %s\n"
	}
	fmt.Printf(format, v.Filename, v.Line, v.Message)
}

func LoadConfig(file []byte) *Config {
	var c Config
	json.Unmarshal(file, &c)
	return &c
}

func checkSourceFile(filename string, rs RuleSet) (vs []Violation, err error) {
	var f *os.File
	f, err = os.Open(filename)
	if err != nil {
		err = newError("fint: cannot open " + filename)
		return
	}
	defer f.Close()
	r := bufio.NewReaderSize(f, bufSize)
	for n := 1; true; n++ {
		var (
			lineBytes []byte
			isPrefix  bool
		)
		lineBytes, isPrefix, err = r.ReadLine()
		if isPrefix {
			err = newError(fmt.Sprintf("too long line: %s", filename))
			return
		}
		line := string(lineBytes)
		if err != io.EOF && err != nil {
			return
		}
		for i := range rs.Modules {
			switch rs.Modules[i].Id {
			case "pattern_match":
				for j := range rs.Modules[i].Rules {
					if matched, _ := regexp.MatchString(rs.Modules[i].Rules[j].Pattern, line); matched {
						vs = append(vs, Violation{Filename: filename, Line: n, Message: rs.Modules[i].Rules[j].Message[opt.Locale]})
					}
				}
			case "max_length":
				for j := range rs.Modules[i].Rules {
					if matched, _ := regexp.MatchString(rs.Modules[i].Rules[j].Pattern, line); matched {
						max_len := int(rs.Modules[i].Rules[j].Args[0].(float64))
						if too_long := max_len < len(line); too_long {
							vs = append(vs, Violation{Filename: filename, Line: n, Message: fmt.Sprintf(rs.Modules[i].Rules[j].Message[opt.Locale], max_len)})
						}
					}
				}
			}
		}
		if err == io.EOF {
			err = nil
			break
		}
	}
	return
}

func findRuleSet() (rs RuleSet, err error) {
	for i := range config.RuleSets {
		r := config.RuleSets[i]
		if r.Id == opt.Id {
			rs = r
		}
	}
	if rs.Id == "" {
		err = newError("no matching ruleset to [" + opt.Id + "]")
	}
	return
}

func checkFile(path string, f os.FileInfo, err error) error {
	if err != nil {
		return err
	}

	rs, errRs := findRuleSet()
	if errRs != nil {
		return errRs
	}

	if matched, _ := regexp.MatchString(rs.Pattern, path); matched {
		v, e := checkSourceFile(path, rs)
		if e != nil {
			return e
		}
		violations = append(violations, v...)
	}
	return nil
}

func pluralize(value int, singular, plural string) string {
	if value < 2 {
		return singular
	}
	return plural
}

func Execute() (err error) {
	conf, err := ioutil.ReadFile(opt.ConfigPath)
	if err != nil {
		return
	}
	config = LoadConfig(conf)

	err = filepath.Walk(opt.SrcRoot, checkFile)
	return
}

func ExecuteAsCommand() {
	err := getOpts()
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	term = os.Getenv("TERM")

	err = Execute()
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}
	for i := range violations {
		printViolation(violations[i])
	}

	if 0 < len(violations) {
		fmt.Printf("\n%d %s generated.\n",
			len(violations), pluralize(len(violations), "warning", "warnings"))
		os.Exit(1)
	}
}
<commit_msg>Fixed wrong error message prefix.<commit_after>// Copyright (c) 2014 Soichiro Kashima
// Licensed under MIT license.

package fint

import (
	"bufio"
	"encoding/json"
	"errors"
	"flag"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"path/filepath"
	"regexp"
)

const (
	errPrefix = "fint: "
	bufSize   = 4096
)

type Opt struct {
	SrcRoot    string
	ConfigPath string
	Locale     string
	Id         string
}

type Rule struct {
	Pattern string
	Args    []interface{}
	Message map[string]string
}

type Module struct {
	Id    string
	Rules []Rule
}

type RuleSet struct {
	Id          string
	Description string
	Pattern     string
	Modules     []Module
}

type Config struct {
	RuleSets []RuleSet
}

type Violation struct {
	Filename string
	Line     int
	Message  string
}

var (
	opt        *Opt
	config     *Config
	violations []Violation
	term       string
)

func newError(message string) error {
	return errors.New(errPrefix + message)
}

func getOpts() (err error) {
	srcRoot := flag.String("s", "", "Source directory")
	configPath := flag.String("c", "conf/config.json", "Config file path")
	locale := flag.String("l", "default", "Message locale")
	id := flag.String("i", "", "ID of the rule set")
	flag.Parse()
	if *srcRoot == "" {
		err = newError("source directory is required.")
		return
	}
	if *id == "" {
		err = newError("ID of the rule set is required.")
		return
	}
	opt = &Opt{SrcRoot: *srcRoot, ConfigPath: *configPath, Locale: *locale, Id: *id}
	return
}

func printViolation(v Violation) {
	var format string
	if term == "dumb" {
		format = "%s:%d:1: warning: %s\n"
	} else {
		format = "%s:%d:1: warning: %s\n"
	}
	fmt.Printf(format, v.Filename, v.Line, v.Message)
}

func LoadConfig(file []byte) *Config {
	var c Config
	json.Unmarshal(file, &c)
	return &c
}

func checkSourceFile(filename string, rs RuleSet) (vs []Violation, err error) {
	var f *os.File
	f, err = os.Open(filename)
	if err != nil {
		err = newError("cannot open " + filename)
		return
	}
	defer f.Close()
	r := bufio.NewReaderSize(f, bufSize)
	for n := 1; true; n++ {
		var (
			lineBytes []byte
			isPrefix  bool
		)
		lineBytes, isPrefix, err = r.ReadLine()
		if isPrefix {
			err = newError(fmt.Sprintf("too long line: %s", filename))
			return
		}
		line := string(lineBytes)
		if err != io.EOF && err != nil {
			return
		}
		for i := range rs.Modules {
			switch rs.Modules[i].Id {
			case "pattern_match":
				for j := range rs.Modules[i].Rules {
					if matched, _ := regexp.MatchString(rs.Modules[i].Rules[j].Pattern, line); matched {
						vs = append(vs, Violation{Filename: filename, Line: n, Message: rs.Modules[i].Rules[j].Message[opt.Locale]})
					}
				}
			case "max_length":
				for j := range rs.Modules[i].Rules {
					if matched, _ := regexp.MatchString(rs.Modules[i].Rules[j].Pattern, line); matched {
						max_len := int(rs.Modules[i].Rules[j].Args[0].(float64))
						if too_long := max_len < len(line); too_long {
							vs = append(vs, Violation{Filename: filename, Line: n, Message: fmt.Sprintf(rs.Modules[i].Rules[j].Message[opt.Locale], max_len)})
						}
					}
				}
			}
		}
		if err == io.EOF {
			err = nil
			break
		}
	}
	return
}

func findRuleSet() (rs RuleSet, err error) {
	for i := range config.RuleSets {
		r := config.RuleSets[i]
		if r.Id == opt.Id {
			rs = r
		}
	}
	if rs.Id == "" {
		err = newError("no matching ruleset to [" + opt.Id + "]")
	}
	return
}

func checkFile(path string, f os.FileInfo, err error) error {
	if err != nil {
		return err
	}

	rs, errRs := findRuleSet()
	if errRs != nil {
		return errRs
	}

	if matched, _ := regexp.MatchString(rs.Pattern, path); matched {
		v, e := checkSourceFile(path, rs)
		if e != nil {
			return e
		}
		violations = append(violations, v...)
	}
	return nil
}

func pluralize(value int, singular, plural string) string {
	if value < 2 {
		return singular
	}
	return plural
}

func Execute() (err error) {
	conf, err := ioutil.ReadFile(opt.ConfigPath)
	if err != nil {
		return
	}
	config = LoadConfig(conf)

	err = filepath.Walk(opt.SrcRoot, checkFile)
	return
}

func ExecuteAsCommand() {
	err := getOpts()
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	term = os.Getenv("TERM")

	err = Execute()
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}
	for i := range violations {
		printViolation(violations[i])
	}

	if 0 < len(violations) {
		fmt.Printf("\n%d %s generated.\n",
			len(violations), pluralize(len(violations), "warning", "warnings"))
		os.Exit(1)
	}
}
<|endoftext|>


<commit_before>package gonvim

import (
	"math"

	"github.com/dzhou121/ui"
)

// Font is
type Font struct {
	font       *ui.Font
	width      int
	truewidth  float64
	height     int
	lineHeight int
	lineSpace  int
	shift      int
}

func newFont(family string, size int) *ui.Font {
	fontDesc := &ui.FontDescriptor{
		Family:  family,
		Size:    float64(size),
		Weight:  ui.TextWeightNormal,
		Italic:  ui.TextItalicNormal,
		Stretch: ui.TextStretchNormal,
	}
	font := ui.LoadClosestFont(fontDesc)
	return font
}

func fontSize(font *ui.Font) (int, int, float64) {
	textLayout := ui.NewTextLayout("W", font, -1)
	w, h := textLayout.Extents()
	width := int(math.Ceil(w))
	height := int(math.Ceil(h))
	textLayout.Free()
	return width, height, w
}

func initFont(family string, size int, lineSpace int) *Font {
	font := newFont(family, size)
	width, height, truewidth := fontSize(font)
	shift := lineSpace / 2
	return &Font{
		font:       font,
		width:      width,
		truewidth:  truewidth,
		height:     height,
		lineHeight: height + lineSpace,
		lineSpace:  lineSpace,
		shift:      shift,
	}
}

func (f *Font) change(family string, size int) {
	f.font.Free()
	font := newFont(family, size)
	width, height, truewidth := fontSize(font)
	lineHeight := height + f.lineSpace
	shift := (lineHeight - height) / 2
	f.font = font
	f.width = width
	f.height = height
	f.truewidth = truewidth
	f.lineHeight = lineHeight
	f.shift = shift
}

func (f *Font) changeLineSpace(lineSpace int) {
	f.lineSpace = lineSpace
	f.lineHeight = f.height + lineSpace
	shift := lineSpace / 2
	f.shift = shift
}
<commit_msg>font free place change<commit_after>package gonvim

import (
	"math"

	"github.com/dzhou121/ui"
)

// Font is
type Font struct {
	font       *ui.Font
	width      int
	truewidth  float64
	height     int
	lineHeight int
	lineSpace  int
	shift      int
}

func newFont(family string, size int) *ui.Font {
	fontDesc := &ui.FontDescriptor{
		Family:  family,
		Size:    float64(size),
		Weight:  ui.TextWeightNormal,
		Italic:  ui.TextItalicNormal,
		Stretch: ui.TextStretchNormal,
	}
	font := ui.LoadClosestFont(fontDesc)
	return font
}

func fontSize(font *ui.Font) (int, int, float64) {
	textLayout := ui.NewTextLayout("W", font, -1)
	w, h := textLayout.Extents()
	width := int(math.Ceil(w))
	height := int(math.Ceil(h))
	textLayout.Free()
	return width, height, w
}

func initFont(family string, size int, lineSpace int) *Font {
	font := newFont(family, size)
	width, height, truewidth := fontSize(font)
	shift := lineSpace / 2
	return &Font{
		font:       font,
		width:      width,
		truewidth:  truewidth,
		height:     height,
		lineHeight: height + lineSpace,
		lineSpace:  lineSpace,
		shift:      shift,
	}
}

func (f *Font) change(family string, size int) {
	oldFont := f.font
	font := newFont(family, size)
	width, height, truewidth := fontSize(font)
	lineHeight := height + f.lineSpace
	shift := (lineHeight - height) / 2
	f.font = font
	f.width = width
	f.height = height
	f.truewidth = truewidth
	f.lineHeight = lineHeight
	f.shift = shift
	oldFont.Free()
}

func (f *Font) changeLineSpace(lineSpace int) {
	f.lineSpace = lineSpace
	f.lineHeight = f.height + lineSpace
	shift := lineSpace / 2
	f.shift = shift
}
<|endoftext|>


<commit_before>package builder

// nginx
const (
	NginxVersion           = "1.17.3"
	NginxDownloadURLPrefix = "https://nginx.org/download"
)

// pcre
const (
	PcreVersion           = "8.43"
	PcreDownloadURLPrefix = "https://ftp.pcre.org/pub/pcre"
)

// openssl
const (
	OpenSSLVersion           = "1.0.2s"
	OpenSSLDownloadURLPrefix = "https://www.openssl.org/source"
)

// libressl
const (
	LibreSSLVersion           = "2.8.3"
	LibreSSLDownloadURLPrefix = "https://ftp.openbsd.org/pub/OpenBSD/LibreSSL"
)

// zlib
const (
	ZlibVersion           = "1.2.11"
	ZlibDownloadURLPrefix = "https://zlib.net/fossils"
)

// openResty
const (
	OpenRestyVersion           = "1.15.8.1"
	OpenRestyDownloadURLPrefix = "https://openresty.org/download"
)

// tengine
const (
	TengineVersion           = "2.3.0"
	TengineDownloadURLPrefix = "https://tengine.taobao.org/download"
)

// component enumerations
const (
	ComponentNginx = iota
	ComponentOpenResty
	ComponentTengine
	ComponentPcre
	ComponentOpenSSL
	ComponentLibreSSL
	ComponentZlib
	ComponentMax
)
<commit_msg>bumped openresty version to 1.15.8.2.<commit_after>package builder

// nginx
const (
	NginxVersion           = "1.17.3"
	NginxDownloadURLPrefix = "https://nginx.org/download"
)

// pcre
const (
	PcreVersion           = "8.43"
	PcreDownloadURLPrefix = "https://ftp.pcre.org/pub/pcre"
)

// openssl
const (
	OpenSSLVersion           = "1.0.2s"
	OpenSSLDownloadURLPrefix = "https://www.openssl.org/source"
)

// libressl
const (
	LibreSSLVersion           = "2.8.3"
	LibreSSLDownloadURLPrefix = "https://ftp.openbsd.org/pub/OpenBSD/LibreSSL"
)

// zlib
const (
	ZlibVersion           = "1.2.11"
	ZlibDownloadURLPrefix = "https://zlib.net/fossils"
)

// openResty
const (
	OpenRestyVersion           = "1.15.8.2"
	OpenRestyDownloadURLPrefix = "https://openresty.org/download"
)

// tengine
const (
	TengineVersion           = "2.3.0"
	TengineDownloadURLPrefix = "https://tengine.taobao.org/download"
)

// component enumerations
const (
	ComponentNginx = iota
	ComponentOpenResty
	ComponentTengine
	ComponentPcre
	ComponentOpenSSL
	ComponentLibreSSL
	ComponentZlib
	ComponentMax
)
<|endoftext|>


<commit_before>package builder

// nginx
const (
	NginxVersion           = "1.11.13"
	NginxDownloadURLPrefix = "http://nginx.org/download"
)

// pcre
const (
	PcreVersion           = "8.40"
	PcreDownloadURLPrefix = "http://ftp.csx.cam.ac.uk/pub/software/programming/pcre"
)

// openssl
const (
	OpenSSLVersion           = "1.0.2k"
	OpenSSLDownloadURLPrefix = "http://www.openssl.org/source"
)

// zlib
const (
	ZlibVersion           = "1.2.11"
	ZlibDownloadURLPrefix = "http://zlib.net/fossils"
)

// openResty
const (
	OpenRestyVersion           = "1.11.2.2"
	OpenRestyDownloadURLPrefix = "https://openresty.org/download"
)

// tengine
const (
	TengineVersion           = "2.2.0"
	TengineDownloadURLPrefix = "http://tengine.taobao.org/download"
)

// component enumerations
const (
	ComponentNginx = iota
	ComponentOpenResty
	ComponentTengine
	ComponentPcre
	ComponentOpenSSL
	ComponentZlib
	ComponentMax
)
<commit_msg>bumped openresty version to 1.11.2.3 by default.<commit_after>package builder

// nginx
const (
	NginxVersion           = "1.11.13"
	NginxDownloadURLPrefix = "http://nginx.org/download"
)

// pcre
const (
	PcreVersion           = "8.40"
	PcreDownloadURLPrefix = "http://ftp.csx.cam.ac.uk/pub/software/programming/pcre"
)

// openssl
const (
	OpenSSLVersion           = "1.0.2k"
	OpenSSLDownloadURLPrefix = "http://www.openssl.org/source"
)

// zlib
const (
	ZlibVersion           = "1.2.11"
	ZlibDownloadURLPrefix = "http://zlib.net/fossils"
)

// openResty
const (
	OpenRestyVersion           = "1.11.2.3"
	OpenRestyDownloadURLPrefix = "https://openresty.org/download"
)

// tengine
const (
	TengineVersion           = "2.2.0"
	TengineDownloadURLPrefix = "http://tengine.taobao.org/download"
)

// component enumerations
const (
	ComponentNginx = iota
	ComponentOpenResty
	ComponentTengine
	ComponentPcre
	ComponentOpenSSL
	ComponentZlib
	ComponentMax
)
<|endoftext|>


<commit_before>package builtin

import (
	// "github.com/oleiade/lane"
	// "log"
	"math/rand"
	// "strconv"
	// "sync"
	"time"

	"github.com/wanliu/flow/context"

	flow "github.com/wanliu/goflow"
)

func NewFinal() interface{} {
	return new(Final)
}

type Final struct {
	// sync.RWMutex

	flow.Component

	delayMin int
	delayMax int

	In       <-chan context.Request
	DelayMin <-chan float64
	DelayMax <-chan float64
}

func (s *Final) OnIn(req context.Request) {
	req.Ctx.Post(req.Res.Reply, req.Res.Data, req)
}

func (s *Final) OnDelayMin(min float64) {
	s.delayMin = int(min)
}

func (s *Final) OnDelayMax(max float64) {
	s.delayMax = int(max)
}

func (s Final) DelayRange() int {
	rand.Seed(time.Now().UnixNano())

	if s.delayMin == 0 {
		return 3 + rand.Intn(2)
	} else {
		if s.delayMax > s.delayMin {
			return s.delayMin + rand.Intn(s.delayMax-s.delayMin)
		} else {
			return s.delayMin + rand.Intn(3)
		}
	}
}
<commit_msg>fix json recursive<commit_after>package builtin

import (
	// "github.com/oleiade/lane"
	// "log"
	"math/rand"
	// "strconv"
	// "sync"
	"time"

	"github.com/wanliu/flow/context"

	flow "github.com/wanliu/goflow"
)

func NewFinal() interface{} {
	return new(Final)
}

type Final struct {
	// sync.RWMutex

	flow.Component

	delayMin int
	delayMax int

	In       <-chan context.Request
	DelayMin <-chan float64
	DelayMax <-chan float64
}

func (s *Final) OnIn(req context.Request) {
	ctx := req.Ctx
	req.Ctx = nil
	ctx.Post(req.Res.Reply, req.Res.Data, req)
}

func (s *Final) OnDelayMin(min float64) {
	s.delayMin = int(min)
}

func (s *Final) OnDelayMax(max float64) {
	s.delayMax = int(max)
}

func (s Final) DelayRange() int {
	rand.Seed(time.Now().UnixNano())

	if s.delayMin == 0 {
		return 3 + rand.Intn(2)
	} else {
		if s.delayMax > s.delayMin {
			return s.delayMin + rand.Intn(s.delayMax-s.delayMin)
		} else {
			return s.delayMin + rand.Intn(3)
		}
	}
}
<|endoftext|>