<commit_before>// EVH is designed to be a single-use file transfer system.  Its purpose is to replace
// aging methods of sharing files such as FTP.  With the advent of services like
// DropBox, Box, Google Drive and the like, this type of service is becoming more
// commonplace EVH has some differentiating features that make it an especially
// good tool for corporations and/or home use.
//
// EVH runs in two modes: server and client.  Server hosts a web server interface for
// uploading and downloading files.  The Client is for uploading only and runs
// in a terminal.  This app is designed to run on all platforms that Go supports.
package main

import (
	"flag"
	"html/template"
	"log"
	"net/http"
	"os"
)

// Flags
var ConfigFileFlag string
var DstEmailFlag string
var ExpirationFlag string
var FileDescrFlag string
var FilesFieldFlag string
var ProgressFlag bool
var ServerFlag bool
var SrcEmailFlag string
var UrlFlag string

// Global Variables
var UploadUrlPath = "/upload/"
var DownloadUrlPath = "/download/"
var Files []string
var HttpProto = "http"
var SiteDown bool
var Templates *template.Template

// Constants
const VERSION = "2.0.7"
const TimeLayout = "Jan 2, 2006 at 3:04pm (MST)"

func init() {
	flag.StringVar(&ConfigFileFlag, "c", "", "Location of the Configuration file")
	flag.BoolVar(&ServerFlag, "server", false, "Listen for incoming file uploads")

	// Client flags
	flag.StringVar(&UrlFlag, "url", "", "Remote server URL to send files to (client only)")
	flag.StringVar(&FilesFieldFlag, "field", "", "Field name of the form (client only)")
	flag.StringVar(&SrcEmailFlag, "from", "", "Email address of uploader (client only)")
	flag.StringVar(&DstEmailFlag, "to", "", "Comma separated set of email address(es) of file recipient(s) (client only)")
	flag.StringVar(&FileDescrFlag, "description", "", "File desription (use quotes) (client only)")
	flag.BoolVar(&ProgressFlag, "progress", true, "Show progress bar during upload (client only)")
	flag.StringVar(&ExpirationFlag, "expires", "", "Example 1:d for 1 day (client only)")
}

func homeHandler(w http.ResponseWriter, r *http.Request) {
	// Redirect to SSL if enabled
	if r.TLS == nil && Config.Server.Ssl {
		redirectToSsl(w, r)
		return
	}

	var page = NewPage()
	DisplayPage(w, r, "home", page)
}

func adminHandler(w http.ResponseWriter, r *http.Request) {
	// Redirect to SSL if enabled
	if r.TLS == nil && Config.Server.Ssl {
		redirectToSsl(w, r)
		return
	}

	var page = NewPage()
	if Config.Server.AllowAdmin {
		page.TrackerOfTrackers = NewTrackerOfTrackers()
	} else {
		page.Message = "Access denied."
	}

	DisplayPage(w, r, "admin", page)
}

func redirectToSsl(w http.ResponseWriter, r *http.Request) {
	http.Redirect(w, r, "https://"+Config.Server.Address+":"+Config.Server.SslPort+r.RequestURI, http.StatusTemporaryRedirect)
	return
}

func main() {
	flag.Parse()

	// Load in our Config
	Config = NewConfig(ConfigFileFlag)
	Config.ImportFlags()

	if ServerFlag {
		// Final sanity check
		if Config.Server.Assets == "" {
			log.Fatal("ERROR: Cannot continue without specifying assets path")
		}
		if Config.Server.Templates == "" {
			log.Fatal("ERROR: Cannot continue without specifying templates path")
		}
		if Config.Server.ListenAddr == "" {
			log.Fatal("ERROR: Cannot continue without specifying listenaddr value")
		}
		if Config.Server.Mailserver == "" {
			log.Println("WARNING: cannot send emails, mailserver not set")
		}

		// Set so all generated URLs use https if enabled
		if Config.Server.Ssl {
			HttpProto = "https"
		}

		// Setup our assets dir (if it don't already exist)
		err := os.MkdirAll(Config.Server.Assets, 0700)
		if err != nil {
			log.Fatal("Cannot setup assetdir as needed: " + err.Error())
		}

		// Parse our html templates
		go RefreshTemplates()
		go ScrubDownloads()

		// Register our handler functions
		http.HandleFunc(UploadUrlPath, uploadHandler)
		http.HandleFunc(DownloadUrlPath, assetHandler)
		http.HandleFunc("/admin/", BasicAuth(adminHandler))
		http.HandleFunc("/", homeHandler)

		// Listen
		log.Println("Listening...")

		// Spawn HTTPS listener in another thread
		go func() {
			if Config.Server.Ssl == false || Config.Server.SslPort == "" {
				return
			}
			var addrSsl = Config.Server.ListenAddr + ":" + Config.Server.SslPort
			listenErrSsl := http.ListenAndServeTLS(addrSsl, Config.Server.CertFile, Config.Server.KeyFile, nil)
			if listenErrSsl != nil {
				log.Fatal("ERROR: ssl listen problem: " + listenErrSsl.Error())
			}
		}()

		// Start non-SSL listener
		var addrNonSsl = Config.Server.ListenAddr + ":" + Config.Server.NonSslPort
		listenErr := http.ListenAndServe(addrNonSsl, nil)
		if listenErr != nil {
			log.Fatal("ERROR: non-ssl listen problem: " + listenErr.Error())
		}
	} else {
		// Final sanity check
		if Config.Client.DestEmail == "" {
			log.Println("WARNING: no -destemail value set, cannot send reciever an email")
		}
		if Config.Client.Email == "" {
			log.Println("WARNING: no -email value set, cannot send email to uploader")
		}
		if Config.Client.Field == "" {
			log.Println("WARNING: no -field value set, using \"file\" instead")
			Config.Client.Field = "file"
		}
		if Config.Client.Url == "" {
			log.Fatal("ERROR: Cannot continue without specifying -url value")
		}

		// All filenames are unflagged arguments, loop through them and uplod the file(s)
		for _, fname := range flag.Args() {
			fi, err := os.Stat(fname)
			if err != nil {
				log.Println("WARNING: Cannot read file, skipping ", fname, ": ", err.Error())
			} else {
				if fi.Mode().IsRegular() {
					Files = append(Files, fname)
				}
			}
		}

		Upload(Files)
	}
}
<commit_msg>Version bump to 2.1.0<commit_after>// EVH is designed to be a single-use file transfer system.  Its purpose is to replace
// aging methods of sharing files such as FTP.  With the advent of services like
// DropBox, Box, Google Drive and the like, this type of service is becoming more
// commonplace EVH has some differentiating features that make it an especially
// good tool for corporations and/or home use.
//
// EVH runs in two modes: server and client.  Server hosts a web server interface for
// uploading and downloading files.  The Client is for uploading only and runs
// in a terminal.  This app is designed to run on all platforms that Go supports.
package main

import (
	"flag"
	"html/template"
	"log"
	"net/http"
	"os"
)

// Flags
var ConfigFileFlag string
var DstEmailFlag string
var ExpirationFlag string
var FileDescrFlag string
var FilesFieldFlag string
var ProgressFlag bool
var ServerFlag bool
var SrcEmailFlag string
var UrlFlag string

// Global Variables
var UploadUrlPath = "/upload/"
var DownloadUrlPath = "/download/"
var Files []string
var HttpProto = "http"
var SiteDown bool
var Templates *template.Template

// Constants
const VERSION = "2.1.0"
const TimeLayout = "Jan 2, 2006 at 3:04pm (MST)"

func init() {
	flag.StringVar(&ConfigFileFlag, "c", "", "Location of the Configuration file")
	flag.BoolVar(&ServerFlag, "server", false, "Listen for incoming file uploads")

	// Client flags
	flag.StringVar(&UrlFlag, "url", "", "Remote server URL to send files to (client only)")
	flag.StringVar(&FilesFieldFlag, "field", "", "Field name of the form (client only)")
	flag.StringVar(&SrcEmailFlag, "from", "", "Email address of uploader (client only)")
	flag.StringVar(&DstEmailFlag, "to", "", "Comma separated set of email address(es) of file recipient(s) (client only)")
	flag.StringVar(&FileDescrFlag, "description", "", "File desription (use quotes) (client only)")
	flag.BoolVar(&ProgressFlag, "progress", true, "Show progress bar during upload (client only)")
	flag.StringVar(&ExpirationFlag, "expires", "", "Example 1:d for 1 day (client only)")
}

func homeHandler(w http.ResponseWriter, r *http.Request) {
	// Redirect to SSL if enabled
	if r.TLS == nil && Config.Server.Ssl {
		redirectToSsl(w, r)
		return
	}

	var page = NewPage()
	DisplayPage(w, r, "home", page)
}

func adminHandler(w http.ResponseWriter, r *http.Request) {
	// Redirect to SSL if enabled
	if r.TLS == nil && Config.Server.Ssl {
		redirectToSsl(w, r)
		return
	}

	var page = NewPage()
	if Config.Server.AllowAdmin {
		page.TrackerOfTrackers = NewTrackerOfTrackers()
	} else {
		page.Message = "Access denied."
	}

	DisplayPage(w, r, "admin", page)
}

func redirectToSsl(w http.ResponseWriter, r *http.Request) {
	http.Redirect(w, r, "https://"+Config.Server.Address+":"+Config.Server.SslPort+r.RequestURI, http.StatusTemporaryRedirect)
	return
}

func main() {
	flag.Parse()

	// Load in our Config
	Config = NewConfig(ConfigFileFlag)
	Config.ImportFlags()

	if ServerFlag {
		// Final sanity check
		if Config.Server.Assets == "" {
			log.Fatal("ERROR: Cannot continue without specifying assets path")
		}
		if Config.Server.Templates == "" {
			log.Fatal("ERROR: Cannot continue without specifying templates path")
		}
		if Config.Server.ListenAddr == "" {
			log.Fatal("ERROR: Cannot continue without specifying listenaddr value")
		}
		if Config.Server.Mailserver == "" {
			log.Println("WARNING: cannot send emails, mailserver not set")
		}

		// Set so all generated URLs use https if enabled
		if Config.Server.Ssl {
			HttpProto = "https"
		}

		// Setup our assets dir (if it don't already exist)
		err := os.MkdirAll(Config.Server.Assets, 0700)
		if err != nil {
			log.Fatal("Cannot setup assetdir as needed: " + err.Error())
		}

		// Parse our html templates
		go RefreshTemplates()
		go ScrubDownloads()

		// Register our handler functions
		http.HandleFunc(UploadUrlPath, uploadHandler)
		http.HandleFunc(DownloadUrlPath, assetHandler)
		http.HandleFunc("/admin/", BasicAuth(adminHandler))
		http.HandleFunc("/", homeHandler)

		// Listen
		log.Println("Listening...")

		// Spawn HTTPS listener in another thread
		go func() {
			if Config.Server.Ssl == false || Config.Server.SslPort == "" {
				return
			}
			var addrSsl = Config.Server.ListenAddr + ":" + Config.Server.SslPort
			listenErrSsl := http.ListenAndServeTLS(addrSsl, Config.Server.CertFile, Config.Server.KeyFile, nil)
			if listenErrSsl != nil {
				log.Fatal("ERROR: ssl listen problem: " + listenErrSsl.Error())
			}
		}()

		// Start non-SSL listener
		var addrNonSsl = Config.Server.ListenAddr + ":" + Config.Server.NonSslPort
		listenErr := http.ListenAndServe(addrNonSsl, nil)
		if listenErr != nil {
			log.Fatal("ERROR: non-ssl listen problem: " + listenErr.Error())
		}
	} else {
		// Final sanity check
		if Config.Client.DestEmail == "" {
			log.Println("WARNING: no -destemail value set, cannot send reciever an email")
		}
		if Config.Client.Email == "" {
			log.Println("WARNING: no -email value set, cannot send email to uploader")
		}
		if Config.Client.Field == "" {
			log.Println("WARNING: no -field value set, using \"file\" instead")
			Config.Client.Field = "file"
		}
		if Config.Client.Url == "" {
			log.Fatal("ERROR: Cannot continue without specifying -url value")
		}

		// All filenames are unflagged arguments, loop through them and uplod the file(s)
		for _, fname := range flag.Args() {
			fi, err := os.Stat(fname)
			if err != nil {
				log.Println("WARNING: Cannot read file, skipping ", fname, ": ", err.Error())
			} else {
				if fi.Mode().IsRegular() {
					Files = append(Files, fname)
				}
			}
		}

		Upload(Files)
	}
}
<|endoftext|>


<commit_before>// Copyright 2015 The etcd 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 stats

import (
	"encoding/json"
	"log"
	"sync"
	"time"

	"github.com/coreos/etcd/raft"
)

// ServerStats encapsulates various statistics about an EtcdServer and its
// communication with other members of the cluster
type ServerStats struct {
	serverStats
	sync.Mutex
}

func NewServerStats(name, id string) *ServerStats {
	ss := &ServerStats{
		serverStats: serverStats{
			Name: name,
			ID:   id,
		},
	}
	now := time.Now()
	ss.StartTime = now
	ss.LeaderInfo.StartTime = now
	ss.sendRateQueue = &statsQueue{back: -1}
	ss.recvRateQueue = &statsQueue{back: -1}
	return ss
}

type serverStats struct {
	Name string `json:"name"`
	// ID is the raft ID of the node.
	// TODO(jonboulle): use ID instead of name?
	ID        string         `json:"id"`
	State     raft.StateType `json:"state"`
	StartTime time.Time      `json:"startTime"`

	LeaderInfo struct {
		Name      string    `json:"leader"`
		Uptime    string    `json:"uptime"`
		StartTime time.Time `json:"startTime"`
	} `json:"leaderInfo"`

	RecvAppendRequestCnt uint64  `json:"recvAppendRequestCnt,"`
	RecvingPkgRate       float64 `json:"recvPkgRate,omitempty"`
	RecvingBandwidthRate float64 `json:"recvBandwidthRate,omitempty"`

	SendAppendRequestCnt uint64  `json:"sendAppendRequestCnt"`
	SendingPkgRate       float64 `json:"sendPkgRate,omitempty"`
	SendingBandwidthRate float64 `json:"sendBandwidthRate,omitempty"`

	sendRateQueue *statsQueue
	recvRateQueue *statsQueue
}

func (ss *ServerStats) JSON() []byte {
	ss.Lock()
	stats := ss.serverStats
	ss.Unlock()
	stats.LeaderInfo.Uptime = time.Since(stats.LeaderInfo.StartTime).String()
	stats.SendingPkgRate, stats.SendingBandwidthRate = stats.sendRateQueue.Rate()
	stats.RecvingPkgRate, stats.RecvingBandwidthRate = stats.recvRateQueue.Rate()
	b, err := json.Marshal(stats)
	// TODO(jonboulle): appropriate error handling?
	if err != nil {
		log.Printf("stats: error marshalling server stats: %v", err)
	}
	return b
}

// RecvAppendReq updates the ServerStats in response to an AppendRequest
// from the given leader being received
func (ss *ServerStats) RecvAppendReq(leader string, reqSize int) {
	ss.Lock()
	defer ss.Unlock()

	now := time.Now()

	ss.State = raft.StateFollower
	if leader != ss.LeaderInfo.Name {
		ss.LeaderInfo.Name = leader
		ss.LeaderInfo.StartTime = now
	}

	ss.recvRateQueue.Insert(
		&RequestStats{
			SendingTime: now,
			Size:        reqSize,
		},
	)
	ss.RecvAppendRequestCnt++
}

// SendAppendReq updates the ServerStats in response to an AppendRequest
// being sent by this server
func (ss *ServerStats) SendAppendReq(reqSize int) {
	ss.Lock()
	defer ss.Unlock()

	ss.becomeLeader()

	ss.sendRateQueue.Insert(
		&RequestStats{
			SendingTime: time.Now(),
			Size:        reqSize,
		},
	)

	ss.SendAppendRequestCnt++
}

func (ss *ServerStats) BecomeLeader() {
	ss.Lock()
	defer ss.Unlock()
	ss.becomeLeader()
}

func (ss *ServerStats) becomeLeader() {
	if ss.State != raft.StateLeader {
		ss.State = raft.StateLeader
		ss.LeaderInfo.Name = ss.ID
		ss.LeaderInfo.StartTime = time.Now()
	}
}
<commit_msg>etcdserver/stats: fix stats data race.<commit_after>// Copyright 2015 The etcd 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 stats

import (
	"encoding/json"
	"log"
	"sync"
	"time"

	"github.com/coreos/etcd/raft"
)

// ServerStats encapsulates various statistics about an EtcdServer and its
// communication with other members of the cluster
type ServerStats struct {
	serverStats
	sync.Mutex
}

func NewServerStats(name, id string) *ServerStats {
	ss := &ServerStats{
		serverStats: serverStats{
			Name: name,
			ID:   id,
		},
	}
	now := time.Now()
	ss.StartTime = now
	ss.LeaderInfo.StartTime = now
	ss.sendRateQueue = &statsQueue{back: -1}
	ss.recvRateQueue = &statsQueue{back: -1}
	return ss
}

type serverStats struct {
	Name string `json:"name"`
	// ID is the raft ID of the node.
	// TODO(jonboulle): use ID instead of name?
	ID        string         `json:"id"`
	State     raft.StateType `json:"state"`
	StartTime time.Time      `json:"startTime"`

	LeaderInfo struct {
		Name      string    `json:"leader"`
		Uptime    string    `json:"uptime"`
		StartTime time.Time `json:"startTime"`
	} `json:"leaderInfo"`

	RecvAppendRequestCnt uint64  `json:"recvAppendRequestCnt,"`
	RecvingPkgRate       float64 `json:"recvPkgRate,omitempty"`
	RecvingBandwidthRate float64 `json:"recvBandwidthRate,omitempty"`

	SendAppendRequestCnt uint64  `json:"sendAppendRequestCnt"`
	SendingPkgRate       float64 `json:"sendPkgRate,omitempty"`
	SendingBandwidthRate float64 `json:"sendBandwidthRate,omitempty"`

	sendRateQueue *statsQueue
	recvRateQueue *statsQueue
}

func (ss *ServerStats) JSON() []byte {
	ss.Lock()
	stats := ss.serverStats
	stats.SendingPkgRate, stats.SendingBandwidthRate = stats.sendRateQueue.Rate()
	stats.RecvingPkgRate, stats.RecvingBandwidthRate = stats.recvRateQueue.Rate()
	ss.Unlock()
	stats.LeaderInfo.Uptime = time.Since(stats.LeaderInfo.StartTime).String()
	b, err := json.Marshal(stats)
	// TODO(jonboulle): appropriate error handling?
	if err != nil {
		log.Printf("stats: error marshalling server stats: %v", err)
	}
	return b
}

// RecvAppendReq updates the ServerStats in response to an AppendRequest
// from the given leader being received
func (ss *ServerStats) RecvAppendReq(leader string, reqSize int) {
	ss.Lock()
	defer ss.Unlock()

	now := time.Now()

	ss.State = raft.StateFollower
	if leader != ss.LeaderInfo.Name {
		ss.LeaderInfo.Name = leader
		ss.LeaderInfo.StartTime = now
	}

	ss.recvRateQueue.Insert(
		&RequestStats{
			SendingTime: now,
			Size:        reqSize,
		},
	)
	ss.RecvAppendRequestCnt++
}

// SendAppendReq updates the ServerStats in response to an AppendRequest
// being sent by this server
func (ss *ServerStats) SendAppendReq(reqSize int) {
	ss.Lock()
	defer ss.Unlock()

	ss.becomeLeader()

	ss.sendRateQueue.Insert(
		&RequestStats{
			SendingTime: time.Now(),
			Size:        reqSize,
		},
	)

	ss.SendAppendRequestCnt++
}

func (ss *ServerStats) BecomeLeader() {
	ss.Lock()
	defer ss.Unlock()
	ss.becomeLeader()
}

func (ss *ServerStats) becomeLeader() {
	if ss.State != raft.StateLeader {
		ss.State = raft.StateLeader
		ss.LeaderInfo.Name = ss.ID
		ss.LeaderInfo.StartTime = time.Now()
	}
}
<|endoftext|>


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

package scanner

import (
	"fmt"
	"regexp"
	"strings"
	"unicode"
	"unicode/utf8"
)

// tokenType identifies the type of lexical tokens.
type tokenType int

// String returns a string representation of the token type.
func (t tokenType) String() string {
	return tokenNames[t]
}

// Token represents a token and the corresponding string.
type Token struct {
	Type   tokenType
	Value  string
	Line   int
	Column int
}

// String returns a string representation of the token.
func (t *Token) String() string {
	if len(t.Value) > 10 {
		return fmt.Sprintf("%s (line: %d, column: %d): %.10q...",
			t.Type, t.Line, t.Column, t.Value)
	}
	return fmt.Sprintf("%s (line: %d, column: %d): %q",
		t.Type, t.Line, t.Column, t.Value)
}

// All tokens -----------------------------------------------------------------

// The complete list of tokens in CSS3.
const (
	// Scanner flags.
	TokenError tokenType = iota
	TokenEOF
	// From now on, only tokens from the CSS specification.
	TokenIdent
	TokenAtKeyword
	TokenString
	TokenHash
	TokenNumber
	TokenPercentage
	TokenDimension
	TokenURI
	TokenUnicodeRange
	TokenCDO
	TokenCDC
	TokenS
	TokenComment
	TokenFunction
	TokenIncludes
	TokenDashMatch
	TokenPrefixMatch
	TokenSuffixMatch
	TokenSubstringMatch
	TokenChar
	TokenBOM
)

// tokenNames maps tokenType's to their names. Used for conversion to string.
var tokenNames = map[tokenType]string{
	TokenError:          "error",
	TokenEOF:            "EOF",
	TokenIdent:          "IDENT",
	TokenAtKeyword:      "ATKEYWORD",
	TokenString:         "STRING",
	TokenHash:           "HASH",
	TokenNumber:         "NUMBER",
	TokenPercentage:     "PERCENTAGE",
	TokenDimension:      "DIMENSION",
	TokenURI:            "URI",
	TokenUnicodeRange:   "UNICODE-RANGE",
	TokenCDO:            "CDO",
	TokenCDC:            "CDC",
	TokenS:              "S",
	TokenComment:        "COMMENT",
	TokenFunction:       "FUNCTION",
	TokenIncludes:       "INCLUDES",
	TokenDashMatch:      "DASHMATCH",
	TokenPrefixMatch:    "PREFIXMATCH",
	TokenSuffixMatch:    "SUFFIXMATCH",
	TokenSubstringMatch: "SUBSTRINGMATCH",
	TokenChar:           "CHAR",
	TokenBOM:            "BOM",
}

// Macros and productions -----------------------------------------------------
// http://www.w3.org/TR/css3-syntax/#tokenization

var macroRegexp = regexp.MustCompile(`\{[a-z]+\}`)

// macros maps macro names to patterns to be expanded.
var macros = map[string]string{
	// must be escaped: `\.+*?()|[]{}^$`
	"ident":      `-?{nmstart}{nmchar}*`,
	"name":       `{nmchar}+`,
	"nmstart":    `[a-zA-Z_]|{nonascii}|{escape}`,
	"nonascii":   "[\u0080-\uD7FF\uE000-\uFFFD\U00010000-\U0010FFFF]",
	"unicode":    `\\[0-9a-fA-F]{1,6}{wc}?`,
	"escape":     "{unicode}|\\[\u0020-\u007E\u0080-\uD7FF\uE000-\uFFFD\U00010000-\U0010FFFF]",
	"nmchar":     `[a-zA-Z0-9_-]|{nonascii}|{escape}`,
	"num":        `[0-9]+|[0-9]*\.[0-9]+`,
	"string":     `"(?:{stringchar}|')*"|'(?:{stringchar}|")*'`,
	"stringchar": `{urlchar}|[ ]|\\{nl}`,
	"urlchar":    "[\u0009\u0021\u0023-\u0026\u0027-\u007E]|{nonascii}|{escape}",
	"nl":         `[\n\r\f]|\r\n`,
	"w":          `{wc}*`,
	"wc":         `[\t\n\f\r ]`,
}

// productions maps the list of tokens to patterns to be expanded.
var productions = map[tokenType]string{
	TokenIdent:          `{ident}`,
	TokenAtKeyword:      `@{ident}`,
	TokenString:         `{string}`,
	TokenHash:           `#{name}`,
	TokenNumber:         `{num}`,
	TokenPercentage:     `{num}%`,
	TokenDimension:      `{num}{ident}`,
	TokenURI:            `url\({w}(?:{string}|{urlchar}*){w}\)`,
	TokenUnicodeRange:   `U\+[0-9A-F\?]{1,6}(?:-[0-9A-F]{1,6})?`,
	TokenCDO:            `<!--`,
	TokenCDC:            `-->`,
	TokenS:              `{wc}+`,
	TokenComment:        `/\*[^\*]*[\*]+(?:[^/][^\*]*[\*]+)*/`,
	TokenFunction:       `{ident}\(`,
	TokenIncludes:       `~=`,
	TokenDashMatch:      `\|=`,
	TokenPrefixMatch:    `\^=`,
	TokenSuffixMatch:    `\$=`,
	TokenSubstringMatch: `\*=`,
	TokenChar:           `[^"']`,
	TokenBOM:            "\uFEFF",
}

// matchers maps the list of tokens to compiled regular expressions.
//
// The map is filled on init() using the macros and productions defined in
// the CSS specification.
var matchers = map[tokenType]*regexp.Regexp{}

var matchOrder = []tokenType{
	// The ones scanned using first-char shortcut are commented out.
	//TokenS,
	TokenURI,
	TokenFunction,
	TokenUnicodeRange,
	TokenIdent,
	TokenDimension,
	TokenPercentage,
	TokenNumber,
	//TokenHash,
	TokenComment,
	//TokenString,
	TokenAtKeyword,
	//TokenIncludes,
	//TokenDashMatch,
	//TokenPrefixMatch,
	//TokenSuffixMatch,
	//TokenSubstringMatch,
	//TokenCDO,
	TokenCDC,
	TokenChar,
	//TokenBOM
}

func init() {
	// replace macros and compile regexps for productions.
	replaceMacro := func(s string) string {
		return "(?:" + macros[s[1:len(s)-1]] + ")"
	}
	for t, s := range productions {
		for macroRegexp.MatchString(s) {
			s = macroRegexp.ReplaceAllStringFunc(s, replaceMacro)
		}
		matchers[t] = regexp.MustCompile("^(?:" + s + ")")
	}
}

// Scanner --------------------------------------------------------------------

// New returns a new CSS scanner for the given input.
func New(input string) *Scanner {
	// Normalize newlines.
	input = strings.Replace(input, "\r\n", "\n", -1)
	return &Scanner{
		input:  input,
		line:   1,
		column: 1,
	}
}

// Scanner scans an input and emits tokens following the CSS3 specification.
type Scanner struct {
	input  string
	pos    int
	line   int
	column int
	last   *Token
}

// Next returns the next token from the input.
//
// At the end of the input the token type is TokenEOF.
//
// If the input can't be tokenized the token type is TokenError. This occurs
// in case of unclosed quotation marks or comments.
func (s *Scanner) Next() *Token {
	if s.last != nil {
		return s.last
	}
	if s.pos >= len(s.input) {
		s.last = &Token{TokenEOF, "", -1, -1}
		return s.last
	}
	input := s.input[s.pos:]
	if s.pos == 0 {
		// Test BOM only at the beginning of the file.
		if strings.HasPrefix(input, "\uFEFF") {
			return s.emitToken(TokenBOM, "\uFEFF")
		}
	}
	// There's a lot we can guess based on the current rune so we'll take this
	// shortcut before testing multiple regexp's.
	r := input[0]
	switch r {
	case '\t', '\n', '\f', '\r', ' ':
		// Whitespace.
		return s.emitToken(TokenS, matchers[TokenS].FindString(input))
	case '.':
		// Dot is too common to not have a quick check.
		// We'll test if this is a Char; if it is followed by a number it is a
		// dimension/percentage/number, and this will be matched later.
		if len(input) > 1 && !unicode.IsDigit(rune(input[1])) {
			return s.emitToken(TokenChar, ".")
		}
	case '#':
		// Hash is also a common one. If the regexp doesn't match it is a Char.
		if match := matchers[TokenHash].FindString(input); match != "" {
			return s.emitToken(TokenHash, match)
		}
		return s.emitToken(TokenChar, "#")
	case ':', ',', ';', '%', '&', '+', '=', '>', '(', ')', '[', ']', '{', '}':
		// Other common chars.
		return s.emitToken(TokenChar, string(r))
	case '"', '\'':
		// String or error.
		match := matchers[TokenString].FindString(input)
		if match != "" {
			return s.emitToken(TokenString, match)
		} else {
			s.last = s.emitToken(TokenError, "unclosed quotation mark")
			return s.last
		}
	case '~':
		// Includes or Char.
		return s.emitPrefixOrChar(TokenIncludes, "~=")
	case '|':
		// DashMatch or Char.
		return s.emitPrefixOrChar(TokenDashMatch, "|=")
	case '^':
		// PrefixMatch or Char.
		return s.emitPrefixOrChar(TokenPrefixMatch, "^=")
	case '$':
		// SuffixMatch or Char.
		return s.emitPrefixOrChar(TokenSuffixMatch, "$=")
	case '*':
		// SubstringMatch or Char.
		return s.emitPrefixOrChar(TokenSubstringMatch, "*=")
	case '<':
		// CDO or Char.
		return s.emitPrefixOrChar(TokenCDO, "<!--")
	}
	// Test all regexps, in order.
	for _, token := range matchOrder {
		if match := matchers[token].FindString(input); match != "" {
			return s.emitToken(token, match)
		}
	}
	s.last = s.emitToken(TokenError, "impossible to tokenize")
	return s.last
}

// updatePosition updates input coordinates based on the consumed text.
func (s *Scanner) updatePosition(text string) {
	count := utf8.RuneCountInString(text)
	lines := strings.Count(text, "\n")
	s.line += lines
	if lines == 0 {
		s.column += count
	} else {
		s.column = utf8.RuneCountInString(text[strings.LastIndex(text, "\n"):])
	}
	s.pos += count
}

// emitToken returns a Token for the string v and updates the scanner position.
func (s *Scanner) emitToken(t tokenType, v string) *Token {
	token := &Token{t, v, s.line, s.column}
	s.updatePosition(v)
	return token
}

// emitPrefixOrChar returns a Token for type t if the current position
// matches the given prefix. Otherwise it returns a Char token using the
// first character from the prefix.
func (s *Scanner) emitPrefixOrChar(t tokenType, prefix string) *Token {
	if strings.HasPrefix(s.input[s.pos:], prefix) {
		return s.emitToken(t, prefix)
	}
	return s.emitToken(TokenChar, string(prefix[0]))
}
<commit_msg>css/scanner: added first-char shortcut for Comment and AtKeyword.<commit_after>// Copyright 2012 The Gorilla Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package scanner

import (
	"fmt"
	"regexp"
	"strings"
	"unicode"
	"unicode/utf8"
)

// tokenType identifies the type of lexical tokens.
type tokenType int

// String returns a string representation of the token type.
func (t tokenType) String() string {
	return tokenNames[t]
}

// Token represents a token and the corresponding string.
type Token struct {
	Type   tokenType
	Value  string
	Line   int
	Column int
}

// String returns a string representation of the token.
func (t *Token) String() string {
	if len(t.Value) > 10 {
		return fmt.Sprintf("%s (line: %d, column: %d): %.10q...",
			t.Type, t.Line, t.Column, t.Value)
	}
	return fmt.Sprintf("%s (line: %d, column: %d): %q",
		t.Type, t.Line, t.Column, t.Value)
}

// All tokens -----------------------------------------------------------------

// The complete list of tokens in CSS3.
const (
	// Scanner flags.
	TokenError tokenType = iota
	TokenEOF
	// From now on, only tokens from the CSS specification.
	TokenIdent
	TokenAtKeyword
	TokenString
	TokenHash
	TokenNumber
	TokenPercentage
	TokenDimension
	TokenURI
	TokenUnicodeRange
	TokenCDO
	TokenCDC
	TokenS
	TokenComment
	TokenFunction
	TokenIncludes
	TokenDashMatch
	TokenPrefixMatch
	TokenSuffixMatch
	TokenSubstringMatch
	TokenChar
	TokenBOM
)

// tokenNames maps tokenType's to their names. Used for conversion to string.
var tokenNames = map[tokenType]string{
	TokenError:          "error",
	TokenEOF:            "EOF",
	TokenIdent:          "IDENT",
	TokenAtKeyword:      "ATKEYWORD",
	TokenString:         "STRING",
	TokenHash:           "HASH",
	TokenNumber:         "NUMBER",
	TokenPercentage:     "PERCENTAGE",
	TokenDimension:      "DIMENSION",
	TokenURI:            "URI",
	TokenUnicodeRange:   "UNICODE-RANGE",
	TokenCDO:            "CDO",
	TokenCDC:            "CDC",
	TokenS:              "S",
	TokenComment:        "COMMENT",
	TokenFunction:       "FUNCTION",
	TokenIncludes:       "INCLUDES",
	TokenDashMatch:      "DASHMATCH",
	TokenPrefixMatch:    "PREFIXMATCH",
	TokenSuffixMatch:    "SUFFIXMATCH",
	TokenSubstringMatch: "SUBSTRINGMATCH",
	TokenChar:           "CHAR",
	TokenBOM:            "BOM",
}

// Macros and productions -----------------------------------------------------
// http://www.w3.org/TR/css3-syntax/#tokenization

var macroRegexp = regexp.MustCompile(`\{[a-z]+\}`)

// macros maps macro names to patterns to be expanded.
var macros = map[string]string{
	// must be escaped: `\.+*?()|[]{}^$`
	"ident":      `-?{nmstart}{nmchar}*`,
	"name":       `{nmchar}+`,
	"nmstart":    `[a-zA-Z_]|{nonascii}|{escape}`,
	"nonascii":   "[\u0080-\uD7FF\uE000-\uFFFD\U00010000-\U0010FFFF]",
	"unicode":    `\\[0-9a-fA-F]{1,6}{wc}?`,
	"escape":     "{unicode}|\\[\u0020-\u007E\u0080-\uD7FF\uE000-\uFFFD\U00010000-\U0010FFFF]",
	"nmchar":     `[a-zA-Z0-9_-]|{nonascii}|{escape}`,
	"num":        `[0-9]+|[0-9]*\.[0-9]+`,
	"string":     `"(?:{stringchar}|')*"|'(?:{stringchar}|")*'`,
	"stringchar": `{urlchar}|[ ]|\\{nl}`,
	"urlchar":    "[\u0009\u0021\u0023-\u0026\u0027-\u007E]|{nonascii}|{escape}",
	"nl":         `[\n\r\f]|\r\n`,
	"w":          `{wc}*`,
	"wc":         `[\t\n\f\r ]`,
}

// productions maps the list of tokens to patterns to be expanded.
var productions = map[tokenType]string{
	TokenIdent:          `{ident}`,
	TokenAtKeyword:      `@{ident}`,
	TokenString:         `{string}`,
	TokenHash:           `#{name}`,
	TokenNumber:         `{num}`,
	TokenPercentage:     `{num}%`,
	TokenDimension:      `{num}{ident}`,
	TokenURI:            `url\({w}(?:{string}|{urlchar}*){w}\)`,
	TokenUnicodeRange:   `U\+[0-9A-F\?]{1,6}(?:-[0-9A-F]{1,6})?`,
	TokenCDO:            `<!--`,
	TokenCDC:            `-->`,
	TokenS:              `{wc}+`,
	TokenComment:        `/\*[^\*]*[\*]+(?:[^/][^\*]*[\*]+)*/`,
	TokenFunction:       `{ident}\(`,
	TokenIncludes:       `~=`,
	TokenDashMatch:      `\|=`,
	TokenPrefixMatch:    `\^=`,
	TokenSuffixMatch:    `\$=`,
	TokenSubstringMatch: `\*=`,
	TokenChar:           `[^"']`,
	TokenBOM:            "\uFEFF",
}

// matchers maps the list of tokens to compiled regular expressions.
//
// The map is filled on init() using the macros and productions defined in
// the CSS specification.
var matchers = map[tokenType]*regexp.Regexp{}

// matchOrder is the order to test regexps when first-char shortcuts
// can't be used.
var matchOrder = []tokenType{
	TokenURI,
	TokenFunction,
	TokenUnicodeRange,
	TokenIdent,
	TokenDimension,
	TokenPercentage,
	TokenNumber,
	TokenCDC,
	TokenChar,
}

func init() {
	// replace macros and compile regexps for productions.
	replaceMacro := func(s string) string {
		return "(?:" + macros[s[1:len(s)-1]] + ")"
	}
	for t, s := range productions {
		for macroRegexp.MatchString(s) {
			s = macroRegexp.ReplaceAllStringFunc(s, replaceMacro)
		}
		matchers[t] = regexp.MustCompile("^(?:" + s + ")")
	}
}

// Scanner --------------------------------------------------------------------

// New returns a new CSS scanner for the given input.
func New(input string) *Scanner {
	// Normalize newlines.
	input = strings.Replace(input, "\r\n", "\n", -1)
	return &Scanner{
		input:  input,
		line:   1,
		column: 1,
	}
}

// Scanner scans an input and emits tokens following the CSS3 specification.
type Scanner struct {
	input  string
	pos    int
	line   int
	column int
	last   *Token
}

// Next returns the next token from the input.
//
// At the end of the input the token type is TokenEOF.
//
// If the input can't be tokenized the token type is TokenError. This occurs
// in case of unclosed quotation marks or comments.
func (s *Scanner) Next() *Token {
	if s.last != nil {
		return s.last
	}
	if s.pos >= len(s.input) {
		s.last = &Token{TokenEOF, "", -1, -1}
		return s.last
	}
	input := s.input[s.pos:]
	if s.pos == 0 {
		// Test BOM only at the beginning of the file.
		if strings.HasPrefix(input, "\uFEFF") {
			return s.emitToken(TokenBOM, "\uFEFF")
		}
	}
	// There's a lot we can guess based on the current rune so we'll take this
	// shortcut before testing multiple regexps.
	r := input[0]
	switch r {
	case '\t', '\n', '\f', '\r', ' ':
		// Whitespace.
		return s.emitToken(TokenS, matchers[TokenS].FindString(input))
	case '.':
		// Dot is too common to not have a quick check.
		// We'll test if this is a Char; if it is followed by a number it is a
		// dimension/percentage/number, and this will be matched later.
		if len(input) > 1 && !unicode.IsDigit(rune(input[1])) {
			return s.emitToken(TokenChar, ".")
		}
	case '#':
		// Hash is also a common one. If the regexp doesn't match it is a Char.
		if match := matchers[TokenHash].FindString(input); match != "" {
			return s.emitToken(TokenHash, match)
		}
		return s.emitToken(TokenChar, "#")
	case '@':
		// Another common one. If the regexp doesn't match it is a Char.
		if match := matchers[TokenAtKeyword].FindString(input); match != "" {
			return s.emitToken(TokenAtKeyword, match)
		}
		return s.emitToken(TokenChar, "@")
	case ':', ',', ';', '%', '&', '+', '=', '>', '(', ')', '[', ']', '{', '}':
		// More common chars.
		return s.emitToken(TokenChar, string(r))
	case '"', '\'':
		// String or error.
		match := matchers[TokenString].FindString(input)
		if match != "" {
			return s.emitToken(TokenString, match)
		} else {
			s.last = s.emitToken(TokenError, "unclosed quotation mark")
			return s.last
		}
	case '/':
		if len(input) > 1 && input[1] == '*' {
			// Comment or error.
			match := matchers[TokenComment].FindString(input)
			if match != "" {
				return s.emitToken(TokenComment, match)
			} else {
				s.last = s.emitToken(TokenError, "unclosed comment")
				return s.last
			}
		}
		// A simple char.
		return s.emitToken(TokenChar, "/")
	case '~':
		// Includes or Char.
		return s.emitPrefixOrChar(TokenIncludes, "~=")
	case '|':
		// DashMatch or Char.
		return s.emitPrefixOrChar(TokenDashMatch, "|=")
	case '^':
		// PrefixMatch or Char.
		return s.emitPrefixOrChar(TokenPrefixMatch, "^=")
	case '$':
		// SuffixMatch or Char.
		return s.emitPrefixOrChar(TokenSuffixMatch, "$=")
	case '*':
		// SubstringMatch or Char.
		return s.emitPrefixOrChar(TokenSubstringMatch, "*=")
	case '<':
		// CDO or Char.
		return s.emitPrefixOrChar(TokenCDO, "<!--")
	}
	// Test all regexps, in order.
	for _, token := range matchOrder {
		if match := matchers[token].FindString(input); match != "" {
			return s.emitToken(token, match)
		}
	}
	s.last = s.emitToken(TokenError, "impossible to tokenize")
	return s.last
}

// updatePosition updates input coordinates based on the consumed text.
func (s *Scanner) updatePosition(text string) {
	count := utf8.RuneCountInString(text)
	lines := strings.Count(text, "\n")
	s.line += lines
	if lines == 0 {
		s.column += count
	} else {
		s.column = utf8.RuneCountInString(text[strings.LastIndex(text, "\n"):])
	}
	s.pos += count
}

// emitToken returns a Token for the string v and updates the scanner position.
func (s *Scanner) emitToken(t tokenType, v string) *Token {
	token := &Token{t, v, s.line, s.column}
	s.updatePosition(v)
	return token
}

// emitPrefixOrChar returns a Token for type t if the current position
// matches the given prefix. Otherwise it returns a Char token using the
// first character from the prefix.
func (s *Scanner) emitPrefixOrChar(t tokenType, prefix string) *Token {
	if strings.HasPrefix(s.input[s.pos:], prefix) {
		return s.emitToken(t, prefix)
	}
	return s.emitToken(TokenChar, string(prefix[0]))
}
<|endoftext|>


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

// +build linux netbsd openbsd dragonfly nacl

package os

import (
	"errors"
	"runtime"
)

// We query the executable path at init time to avoid the problem of
// readlink returns a path appended with " (deleted)" when the original
// binary gets deleted.
var executablePath, executablePathErr = func () (string, error) {
	var procfn string
	switch runtime.GOOS {
	default:
		return "", errors.New("Executable not implemented for " + runtime.GOOS)
	case "linux":
		procfn = "/proc/self/exe"
	case "netbsd":
		procfn = "/proc/curproc/exe"
	case "openbsd":
		procfn = "/proc/curproc/file"
	case "dragonfly":
		procfn = "/proc/curproc/file"
	}
	return Readlink(procfn)
}()

func executable() (string, error) {
	return executablePath, executablePathErr
}
<commit_msg>os: gofmt -w -s<commit_after>// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// +build linux netbsd openbsd dragonfly nacl

package os

import (
	"errors"
	"runtime"
)

// We query the executable path at init time to avoid the problem of
// readlink returns a path appended with " (deleted)" when the original
// binary gets deleted.
var executablePath, executablePathErr = func() (string, error) {
	var procfn string
	switch runtime.GOOS {
	default:
		return "", errors.New("Executable not implemented for " + runtime.GOOS)
	case "linux":
		procfn = "/proc/self/exe"
	case "netbsd":
		procfn = "/proc/curproc/exe"
	case "openbsd":
		procfn = "/proc/curproc/file"
	case "dragonfly":
		procfn = "/proc/curproc/file"
	}
	return Readlink(procfn)
}()

func executable() (string, error) {
	return executablePath, executablePathErr
}
<|endoftext|>


<commit_before>package generator

import (
	"bytes"
	"fmt"
	"io"
	"path/filepath"

	tl "github.com/xlab/c-for-go/translator"
)

func (gen *Generator) writeDefinesGroup(wr io.Writer, defines []*tl.CDecl) (n int) {
	writeStartConst(wr)
	for _, decl := range defines {
		if !decl.IsDefine {
			continue
		}
		name := gen.tr.TransformName(tl.TargetConst, decl.Name)
		if decl.Value == nil && string(name) == decl.Expression {
			continue
		}
		fmt.Fprintf(wr, "// %s as defined in %s\n", name,
			filepath.ToSlash(gen.tr.SrcLocation(tl.TargetConst, decl.Name, decl.Pos)))

		if decl.Value != nil {
			fmt.Fprintf(wr, "%s = %v", name, decl.Value)
		} else if len(decl.Expression) > 0 {
			fmt.Fprintf(wr, "%s = %s", name, decl.Expression)
		} else {
			fmt.Fprint(wr, name)
		}
		writeSpace(wr, 1)
		n++
	}
	writeEndConst(wr)
	return
}

func (gen *Generator) writeConstDeclaration(wr io.Writer, decl *tl.CDecl) {
	declName := gen.tr.TransformName(tl.TargetConst, decl.Name)
	if decl.Value == nil && string(declName) == decl.Expression {
		return
	}
	fmt.Fprintf(wr, "// %s as declared in %s\n", declName,
		filepath.ToSlash(gen.tr.SrcLocation(tl.TargetConst, decl.Name, decl.Pos)))
	goSpec := gen.tr.TranslateSpec(decl.Spec)

	if decl.Value != nil {
		fmt.Fprintf(wr, "const %s %s = %v", declName, goSpec, decl.Value)
		return
	} else if len(decl.Expression) > 0 {
		fmt.Fprintf(wr, "const %s %s = %s", declName, goSpec, decl.Expression)
		return
	}
	// const must have values, otherwise variable
	fmt.Fprintf(wr, "var %s %s", declName, goSpec)
}

func (gen *Generator) expandEnumAnonymous(wr io.Writer, decl *tl.CDecl, namesSeen map[string]bool) {
	var typeName []byte
	var hasType bool
	if decl.IsTypedef {
		if typeName = gen.tr.TransformName(tl.TargetType, decl.Name); len(typeName) > 0 {
			hasType = true
		}
	}

	spec := decl.Spec.(*tl.CEnumSpec)
	if hasType {
		enumType := gen.tr.TranslateSpec(&spec.Type)
		fmt.Fprintf(wr, "// %s as declared in %s\n", typeName,
			filepath.ToSlash(gen.tr.SrcLocation(tl.TargetConst, decl.Name, decl.Pos)))
		fmt.Fprintf(wr, "type %s %s\n", typeName, enumType)
		writeSpace(wr, 1)
		fmt.Fprintf(wr, "// %s enumeration from %s\n", typeName,
			filepath.ToSlash(gen.tr.SrcLocation(tl.TargetConst, decl.Name, decl.Pos)))
	}
	writeStartConst(wr)
	for i, m := range spec.Members {
		if !gen.tr.IsAcceptableName(tl.TargetConst, m.Name) {
			continue
		}
		mName := gen.tr.TransformName(tl.TargetConst, m.Name)
		if len(mName) == 0 {
			continue
		} else if namesSeen[string(mName)] {
			continue
		} else {
			namesSeen[string(mName)] = true
		}
		if !hasType {
			fmt.Fprintf(wr, "// %s as declared in %s\n", mName,
				filepath.ToSlash(gen.tr.SrcLocation(tl.TargetConst, m.Name, m.Pos)))
		}
		switch {
		case m.Value != nil:
			if hasType {
				fmt.Fprintf(wr, "%s %s = %s\n", mName, typeName, iotaOnZero(i, m.Value))
				continue
			}
			fmt.Fprintf(wr, "%s = %s\n", mName, iotaOnZero(i, m.Value))
		case len(m.Expression) > 0:
			if hasType {
				fmt.Fprintf(wr, "%s %s = %s\n", mName, typeName, iotaOnZero(i, m.Expression))
				continue
			}
			fmt.Fprintf(wr, "%s = %s\n", mName, iotaOnZero(i, m.Expression))
		default:
			if i == 0 && hasType {
				fmt.Fprintf(wr, "%s %s = iota\n", mName, typeName)
				continue
			} else if i == 0 {
				fmt.Fprintf(wr, "%s = iota\n", mName)
			}
			fmt.Fprintf(wr, "%s\n", mName)
		}
	}
	writeEndConst(wr)
	writeSpace(wr, 1)
}

func (gen *Generator) expandEnum(wr io.Writer, decl *tl.CDecl, namesSeen map[string]bool) {
	var declName []byte
	var isTypedef bool
	if decl.IsTypedef {
		if declName = gen.tr.TransformName(tl.TargetType, decl.Name); len(declName) > 0 {
			isTypedef = true
		}
	}

	spec := decl.Spec.(*tl.CEnumSpec)
	tagName := gen.tr.TransformName(tl.TargetType, decl.Spec.GetBase())
	enumType := gen.tr.TranslateSpec(&spec.Type)
	fmt.Fprintf(wr, "// %s as declared in %s\n", tagName,
		filepath.ToSlash(gen.tr.SrcLocation(tl.TargetConst, decl.Name, decl.Pos)))
	fmt.Fprintf(wr, "type %s %s\n", tagName, enumType)
	writeSpace(wr, 1)
	if isTypedef {
		if !bytes.Equal(tagName, declName) && len(declName) > 0 {
			// alias type decl name to the tag
			fmt.Fprintf(wr, "// %s as declared in %s\n", declName,
				filepath.ToSlash(gen.tr.SrcLocation(tl.TargetConst, decl.Name, decl.Pos)))
			fmt.Fprintf(wr, "type %s %s", declName, tagName)
			writeSpace(wr, 1)
		}
	}

	fmt.Fprintf(wr, "// %s enumeration from %s\n", tagName,
		filepath.ToSlash(gen.tr.SrcLocation(tl.TargetConst, decl.Name, decl.Pos)))
	writeStartConst(wr)
	for i, m := range spec.Members {
		if !gen.tr.IsAcceptableName(tl.TargetConst, m.Name) {
			continue
		}
		mName := gen.tr.TransformName(tl.TargetConst, m.Name)
		if len(mName) == 0 {
			continue
		} else if namesSeen[string(mName)] {
			continue
		} else {
			namesSeen[string(mName)] = true
		}
		switch {
		case m.Value != nil:
			fmt.Fprintf(wr, "%s %s = %v\n", mName, declName, iotaOnZero(i, m.Value))
		case len(m.Expression) > 0:
			fmt.Fprintf(wr, "%s %s = %v\n", mName, declName, iotaOnZero(i, m.Expression))
		default:
			if i == 0 {
				fmt.Fprintf(wr, "%s %s = iota\n", mName, declName)
				continue
			}
			fmt.Fprintf(wr, "%s\n", mName)
		}
	}
	writeEndConst(wr)
	writeSpace(wr, 1)
}

func iotaOnZero(i int, v interface{}) string {
	result := fmt.Sprintf("%v", v)
	if i == 0 {
		if result == "0" {
			return "iota"
		}
	}
	return result
}

func writeStartConst(wr io.Writer) {
	fmt.Fprintln(wr, "const (")
}

func writeEndConst(wr io.Writer) {
	fmt.Fprintln(wr, ")")
}
<commit_msg>Fix parse error for empty constants<commit_after>package generator

import (
	"bytes"
	"fmt"
	"io"
	"path/filepath"

	tl "github.com/xlab/c-for-go/translator"
)

func (gen *Generator) writeDefinesGroup(wr io.Writer, defines []*tl.CDecl) (n int) {
	writeStartConst(wr)
	for _, decl := range defines {
		if !decl.IsDefine {
			continue
		}
		name := gen.tr.TransformName(tl.TargetConst, decl.Name)
		if decl.Value == nil && string(name) == decl.Expression {
			continue
		}
		fmt.Fprintf(wr, "// %s as defined in %s\n", name,
			filepath.ToSlash(gen.tr.SrcLocation(tl.TargetConst, decl.Name, decl.Pos)))

		if decl.Value != nil {
			fmt.Fprintf(wr, "%s = %v", name, decl.Value)
		} else if len(decl.Expression) > 0 {
			fmt.Fprintf(wr, "%s = %s", name, decl.Expression)
		} else {
			// In this case, it's nil or the expression is zero length.
			// fmt.Fprint(wr, name)
		}
		writeSpace(wr, 1)
		n++
	}
	writeEndConst(wr)
	return
}

func (gen *Generator) writeConstDeclaration(wr io.Writer, decl *tl.CDecl) {
	declName := gen.tr.TransformName(tl.TargetConst, decl.Name)
	if decl.Value == nil && string(declName) == decl.Expression {
		return
	}
	fmt.Fprintf(wr, "// %s as declared in %s\n", declName,
		filepath.ToSlash(gen.tr.SrcLocation(tl.TargetConst, decl.Name, decl.Pos)))
	goSpec := gen.tr.TranslateSpec(decl.Spec)

	if decl.Value != nil {
		fmt.Fprintf(wr, "const %s %s = %v", declName, goSpec, decl.Value)
		return
	} else if len(decl.Expression) > 0 {
		fmt.Fprintf(wr, "const %s %s = %s", declName, goSpec, decl.Expression)
		return
	}
	// const must have values, otherwise variable
	fmt.Fprintf(wr, "var %s %s", declName, goSpec)
}

func (gen *Generator) expandEnumAnonymous(wr io.Writer, decl *tl.CDecl, namesSeen map[string]bool) {
	var typeName []byte
	var hasType bool
	if decl.IsTypedef {
		if typeName = gen.tr.TransformName(tl.TargetType, decl.Name); len(typeName) > 0 {
			hasType = true
		}
	}

	spec := decl.Spec.(*tl.CEnumSpec)
	if hasType {
		enumType := gen.tr.TranslateSpec(&spec.Type)
		fmt.Fprintf(wr, "// %s as declared in %s\n", typeName,
			filepath.ToSlash(gen.tr.SrcLocation(tl.TargetConst, decl.Name, decl.Pos)))
		fmt.Fprintf(wr, "type %s %s\n", typeName, enumType)
		writeSpace(wr, 1)
		fmt.Fprintf(wr, "// %s enumeration from %s\n", typeName,
			filepath.ToSlash(gen.tr.SrcLocation(tl.TargetConst, decl.Name, decl.Pos)))
	}
	writeStartConst(wr)
	for i, m := range spec.Members {
		if !gen.tr.IsAcceptableName(tl.TargetConst, m.Name) {
			continue
		}
		mName := gen.tr.TransformName(tl.TargetConst, m.Name)
		if len(mName) == 0 {
			continue
		} else if namesSeen[string(mName)] {
			continue
		} else {
			namesSeen[string(mName)] = true
		}
		if !hasType {
			fmt.Fprintf(wr, "// %s as declared in %s\n", mName,
				filepath.ToSlash(gen.tr.SrcLocation(tl.TargetConst, m.Name, m.Pos)))
		}
		switch {
		case m.Value != nil:
			if hasType {
				fmt.Fprintf(wr, "%s %s = %s\n", mName, typeName, iotaOnZero(i, m.Value))
				continue
			}
			fmt.Fprintf(wr, "%s = %s\n", mName, iotaOnZero(i, m.Value))
		case len(m.Expression) > 0:
			if hasType {
				fmt.Fprintf(wr, "%s %s = %s\n", mName, typeName, iotaOnZero(i, m.Expression))
				continue
			}
			fmt.Fprintf(wr, "%s = %s\n", mName, iotaOnZero(i, m.Expression))
		default:
			if i == 0 && hasType {
				fmt.Fprintf(wr, "%s %s = iota\n", mName, typeName)
				continue
			} else if i == 0 {
				fmt.Fprintf(wr, "%s = iota\n", mName)
			}
			fmt.Fprintf(wr, "%s\n", mName)
		}
	}
	writeEndConst(wr)
	writeSpace(wr, 1)
}

func (gen *Generator) expandEnum(wr io.Writer, decl *tl.CDecl, namesSeen map[string]bool) {
	var declName []byte
	var isTypedef bool
	if decl.IsTypedef {
		if declName = gen.tr.TransformName(tl.TargetType, decl.Name); len(declName) > 0 {
			isTypedef = true
		}
	}

	spec := decl.Spec.(*tl.CEnumSpec)
	tagName := gen.tr.TransformName(tl.TargetType, decl.Spec.GetBase())
	enumType := gen.tr.TranslateSpec(&spec.Type)
	fmt.Fprintf(wr, "// %s as declared in %s\n", tagName,
		filepath.ToSlash(gen.tr.SrcLocation(tl.TargetConst, decl.Name, decl.Pos)))
	fmt.Fprintf(wr, "type %s %s\n", tagName, enumType)
	writeSpace(wr, 1)
	if isTypedef {
		if !bytes.Equal(tagName, declName) && len(declName) > 0 {
			// alias type decl name to the tag
			fmt.Fprintf(wr, "// %s as declared in %s\n", declName,
				filepath.ToSlash(gen.tr.SrcLocation(tl.TargetConst, decl.Name, decl.Pos)))
			fmt.Fprintf(wr, "type %s %s", declName, tagName)
			writeSpace(wr, 1)
		}
	}

	fmt.Fprintf(wr, "// %s enumeration from %s\n", tagName,
		filepath.ToSlash(gen.tr.SrcLocation(tl.TargetConst, decl.Name, decl.Pos)))
	writeStartConst(wr)
	for i, m := range spec.Members {
		if !gen.tr.IsAcceptableName(tl.TargetConst, m.Name) {
			continue
		}
		mName := gen.tr.TransformName(tl.TargetConst, m.Name)
		if len(mName) == 0 {
			continue
		} else if namesSeen[string(mName)] {
			continue
		} else {
			namesSeen[string(mName)] = true
		}
		switch {
		case m.Value != nil:
			fmt.Fprintf(wr, "%s %s = %v\n", mName, declName, iotaOnZero(i, m.Value))
		case len(m.Expression) > 0:
			fmt.Fprintf(wr, "%s %s = %v\n", mName, declName, iotaOnZero(i, m.Expression))
		default:
			if i == 0 {
				fmt.Fprintf(wr, "%s %s = iota\n", mName, declName)
				continue
			}
			fmt.Fprintf(wr, "%s\n", mName)
		}
	}
	writeEndConst(wr)
	writeSpace(wr, 1)
}

func iotaOnZero(i int, v interface{}) string {
	result := fmt.Sprintf("%v", v)
	if i == 0 {
		if result == "0" {
			return "iota"
		}
	}
	return result
}

func writeStartConst(wr io.Writer) {
	fmt.Fprintln(wr, "const (")
}

func writeEndConst(wr io.Writer) {
	fmt.Fprintln(wr, ")")
}
<|endoftext|>


<commit_before>package arangolite

import (
	"bytes"
	"encoding/json"
	"strings"
)

// Transaction represents an ArangoDB transaction.
type Transaction struct {
	readCol, writeCol []string
	resultVars        []string
	queries           []Query
	returnVar         string
	bindVars          map[string]string
}

// NewTransaction returns a new Transaction object.
func NewTransaction(readCol, writeCol []string) *Transaction {
	if readCol == nil {
		readCol = []string{}
	}

	if writeCol == nil {
		writeCol = []string{}
	}

	return &Transaction{readCol: readCol, writeCol: writeCol}
}

// AddQuery adds a new AQL query to the transaction. The result will be set in
// a temp variable named after the value of "resultVar".
// To use it from elsewhere in the transaction, use the Go templating convention.
//
// e.g. NewTransaction([]string{}, []string{}).
//      AddQuery("var1", "FOR d IN documents RETURN d").
//      AddQuery("var2", "FOR d IN {{.var1}} RETURN d._id").Run(db)
//
func (t *Transaction) AddQuery(resultVar, aql string, params ...interface{}) *Transaction {
	t.resultVars = append(t.resultVars, resultVar)
	t.queries = append(t.queries, *NewQuery(toES6Template(aql), params...))
	return t
}

// Bind sets the name and value of a bind parameter
// Binding parameters prevents AQL injection
// Example:
// transaction := arangolite.NewTransaction([]string{}, []string{}).
// 		AddQuery("var1", "FOR d IN nodes FILTER d._key == @key RETURN d._id").
// 		AddQuery("var2", "FOR n IN nodes FILTER n._id == {{.var1}}[0] RETURN n._key").Return("var2")
// transaction.Bind("key", 123)
//
func (t *Transaction) Bind(name string, value interface{}) *Transaction {
	if t.bindVars == nil {
		t.bindVars = make(map[string]string)
	}
	m, _ := json.Marshal(value)
	t.bindVars[name] = strings.Replace(string(m), `"`, "'", -1)
	return t
}

// Return sets the final "resultVar" that is returned at the end of the transaction.
func (t *Transaction) Return(resultVar string) *Transaction {
	t.returnVar = resultVar
	return t
}

func (t *Transaction) description() string {
	return "TRANSACTION"
}

func (t *Transaction) path() string {
	return "/_api/transaction"
}

func (t *Transaction) method() string {
	return "POST"
}

func (t *Transaction) generate() []byte {
	type TransactionFmt struct {
		Collections struct {
			Read  []string `json:"read"`
			Write []string `json:"write"`
		} `json:"collections"`
		Action string `json:"action"`
	}

	transactionFmt := &TransactionFmt{}
	transactionFmt.Collections.Read = t.readCol
	transactionFmt.Collections.Write = t.writeCol

	jsFunc := bytes.NewBufferString("function () { var db = require('internal').db; ")

	for name, value := range t.bindVars {
		jsFunc.WriteString("var ")
		jsFunc.WriteString(name)
		jsFunc.WriteString(" = ")
		jsFunc.WriteString(value)
		jsFunc.WriteString("; ")
	}

	for i, query := range t.queries {
		writeQuery(jsFunc, query.aql, t.resultVars[i])
	}

	if len(t.returnVar) > 0 {
		jsFunc.WriteString("return ")
		jsFunc.WriteString(t.returnVar)
		jsFunc.WriteString(";")
	}

	jsFunc.WriteRune('}')

	transactionFmt.Action = jsFunc.String()
	jsonTransaction, _ := json.Marshal(transactionFmt)

	return jsonTransaction
}

// writeQuery translate a given aql query to bytes
// buff the buffer containing the resulting bytes
// aql the AQL query
// resultVarName the name of the variable that will accept the query result, if any - may be empty
func writeQuery(buff *bytes.Buffer, aql string, resultVarName string) {
	if len(resultVarName) > 0 {
		buff.WriteString("var ")
		buff.WriteString(resultVarName)
		buff.WriteString(" = ")
	}

	buff.WriteString("db._query(aqlQuery`")
	buff.WriteString(aql)
	buff.WriteString("`).toArray(); ")
}

func toES6Template(query string) string {
	buf := bytes.NewBuffer(nil)
	lookingForEnd := false

	for _, b := range query {
		if lookingForEnd {
			if b == ' ' || b == '\n' || b == ',' || b == ';' {
				lookingForEnd = false
				buf.WriteString("} ")
				continue
			}
		} else {
			if b == '@' {
				lookingForEnd = true
				buf.WriteString("${")
				continue
			}
		}

		buf.WriteRune(b)
	}

	query = buf.String()

	query = strings.Replace(query, "{{.", "${", -1)
	return strings.Replace(query, "}}", "}", -1)
}
<commit_msg>Transaction bind parameters fixed.<commit_after>package arangolite

import (
	"bytes"
	"encoding/json"
	"strings"
)

// Transaction represents an ArangoDB transaction.
type Transaction struct {
	readCol, writeCol []string
	resultVars        []string
	queries           []Query
	returnVar         string
	bindVars          map[string]string
}

// NewTransaction returns a new Transaction object.
func NewTransaction(readCol, writeCol []string) *Transaction {
	if readCol == nil {
		readCol = []string{}
	}

	if writeCol == nil {
		writeCol = []string{}
	}

	return &Transaction{readCol: readCol, writeCol: writeCol}
}

// AddQuery adds a new AQL query to the transaction. The result will be set in
// a temp variable named after the value of "resultVar".
// To use it from elsewhere in the transaction, use the Go templating convention.
//
// e.g. NewTransaction([]string{}, []string{}).
//      AddQuery("var1", "FOR d IN documents RETURN d").
//      AddQuery("var2", "FOR d IN {{.var1}} RETURN d._id").Run(db)
//
func (t *Transaction) AddQuery(resultVar, aql string, params ...interface{}) *Transaction {
	t.resultVars = append(t.resultVars, resultVar)
	t.queries = append(t.queries, *NewQuery(toES6Template(aql), params...))
	return t
}

// Bind sets the name and value of a bind parameter
// Binding parameters prevents AQL injection
// Example:
// transaction := arangolite.NewTransaction([]string{}, []string{}).
// 		AddQuery("var1", "FOR d IN nodes FILTER d._key == @key RETURN d._id").
// 		AddQuery("var2", "FOR n IN nodes FILTER n._id == {{.var1}}[0] RETURN n._key").Return("var2")
// transaction.Bind("key", 123)
//
func (t *Transaction) Bind(name string, value interface{}) *Transaction {
	if t.bindVars == nil {
		t.bindVars = make(map[string]string)
	}
	m, _ := json.Marshal(value)
	t.bindVars[name] = strings.Replace(string(m), `"`, "'", -1)
	return t
}

// Return sets the final "resultVar" that is returned at the end of the transaction.
func (t *Transaction) Return(resultVar string) *Transaction {
	t.returnVar = resultVar
	return t
}

func (t *Transaction) description() string {
	return "TRANSACTION"
}

func (t *Transaction) path() string {
	return "/_api/transaction"
}

func (t *Transaction) method() string {
	return "POST"
}

func (t *Transaction) generate() []byte {
	type TransactionFmt struct {
		Collections struct {
			Read  []string `json:"read"`
			Write []string `json:"write"`
		} `json:"collections"`
		Action string `json:"action"`
	}

	transactionFmt := &TransactionFmt{}
	transactionFmt.Collections.Read = t.readCol
	transactionFmt.Collections.Write = t.writeCol

	jsFunc := bytes.NewBufferString("function () { var db = require('internal').db; ")

	for name, value := range t.bindVars {
		jsFunc.WriteString("var ")
		jsFunc.WriteString(name)
		jsFunc.WriteString(" = ")
		jsFunc.WriteString(value)
		jsFunc.WriteString("; ")
	}

	for i, query := range t.queries {
		writeQuery(jsFunc, query.aql, t.resultVars[i])
	}

	if len(t.returnVar) > 0 {
		jsFunc.WriteString("return ")
		jsFunc.WriteString(t.returnVar)
		jsFunc.WriteString(";")
	}

	jsFunc.WriteRune('}')

	transactionFmt.Action = jsFunc.String()
	jsonTransaction, _ := json.Marshal(transactionFmt)

	return jsonTransaction
}

// writeQuery translate a given aql query to bytes
// buff the buffer containing the resulting bytes
// aql the AQL query
// resultVarName the name of the variable that will accept the query result, if any - may be empty
func writeQuery(buff *bytes.Buffer, aql string, resultVarName string) {
	if len(resultVarName) > 0 {
		buff.WriteString("var ")
		buff.WriteString(resultVarName)
		buff.WriteString(" = ")
	}

	buff.WriteString("db._query(aqlQuery`")
	buff.WriteString(aql)
	buff.WriteString("`).toArray(); ")
}

func toES6Template(query string) string {
	buf := bytes.NewBuffer(nil)
	lookingForEnd := false

	for _, b := range query {
		if lookingForEnd {
			if b == ' ' || b == '\n' || b == ',' || b == ';' {
				lookingForEnd = false
				buf.WriteRune('}')
				buf.WriteRune(b)
				continue
			}
		} else {
			if b == '@' {
				lookingForEnd = true
				buf.WriteString("${")
				continue
			}
		}

		buf.WriteRune(b)
	}

	query = buf.String()

	query = strings.Replace(query, "{{.", "${", -1)
	return strings.Replace(query, "}}", "}", -1)
}
<|endoftext|>


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

package rand

import (
	"errors"
	"io"
	"math/big"
)

// smallPrimes is a list of small, prime numbers that allows us to rapidly
// exclude some fraction of composite candidates when searching for a random
// prime. This list is truncated at the point where smallPrimesProduct exceeds
// a uint64. It does not include two because we ensure that the candidates are
// odd by construction.
var smallPrimes = []uint8{
	3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53,
}

// smallPrimesProduct is the product of the values in smallPrimes and allows us
// to reduce a candidate prime by this number and then determine whether it's
// coprime to all the elements of smallPrimes without further big.Int
// operations.
var smallPrimesProduct = new(big.Int).SetUint64(16294579238595022365)

// Prime returns a number, p, of the given size, such that p is prime
// with high probability.
func Prime(rand io.Reader, bits int) (p *big.Int, err error) {
	if bits < 1 {
		err = errors.New("crypto/rand: prime size must be positive")
	}

	b := uint(bits % 8)
	if b == 0 {
		b = 8
	}

	bytes := make([]byte, (bits+7)/8)
	p = new(big.Int)

	bigMod := new(big.Int)

	for {
		_, err = io.ReadFull(rand, bytes)
		if err != nil {
			return nil, err
		}

		// Clear bits in the first byte to make sure the candidate has a size <= bits.
		bytes[0] &= uint8(int(1<<b) - 1)
		// Don't let the value be too small, i.e, set the most significant two bits.
		// Setting the top two bits, rather than just the top bit,
		// means that when two of these values are multiplied together,
		// the result isn't ever one bit short.
		if b >= 2 {
			bytes[0] |= 3 << (b - 2)
		} else {
			// Here b==1, because b cannot be zero.
			bytes[0] |= 1
			if len(bytes) > 1 {
				bytes[1] |= 0x80
			}
		}
		// Make the value odd since an even number this large certainly isn't prime.
		bytes[len(bytes)-1] |= 1

		p.SetBytes(bytes)

		// Calculate the value mod the product of smallPrimes.  If it's
		// a multiple of any of these primes we add two until it isn't.
		// The probability of overflowing is minimal and can be ignored
		// because we still perform Miller-Rabin tests on the result.
		bigMod.Mod(p, smallPrimesProduct)
		mod := bigMod.Uint64()

	NextDelta:
		for delta := uint64(0); delta < 1<<20; delta += 2 {
			m := mod + delta
			for _, prime := range smallPrimes {
				if m%uint64(prime) == 0 {
					continue NextDelta
				}
			}

			if delta > 0 {
				bigMod.SetUint64(delta)
				p.Add(p, bigMod)
			}
			break
		}

		// There is a tiny possibility that, by adding delta, we caused
		// the number to be one bit too long. Thus we check BitLen
		// here.
		if p.ProbablyPrime(20) && p.BitLen() == bits {
			return
		}
	}
}

// Int returns a uniform random value in [0, max).
func Int(rand io.Reader, max *big.Int) (n *big.Int, err error) {
	k := (max.BitLen() + 7) / 8

	// b is the number of bits in the most significant byte of max.
	b := uint(max.BitLen() % 8)
	if b == 0 {
		b = 8
	}

	bytes := make([]byte, k)
	n = new(big.Int)

	for {
		_, err = io.ReadFull(rand, bytes)
		if err != nil {
			return nil, err
		}

		// Clear bits in the first byte to increase the probability
		// that the candidate is < max.
		bytes[0] &= uint8(int(1<<b) - 1)

		n.SetBytes(bytes)
		if n.Cmp(max) < 0 {
			return
		}
	}
}
<commit_msg>crypto/rand: better panic message for invalid Int argument.<commit_after>// Copyright 2011 The Go Authors.  All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package rand

import (
	"errors"
	"io"
	"math/big"
)

// smallPrimes is a list of small, prime numbers that allows us to rapidly
// exclude some fraction of composite candidates when searching for a random
// prime. This list is truncated at the point where smallPrimesProduct exceeds
// a uint64. It does not include two because we ensure that the candidates are
// odd by construction.
var smallPrimes = []uint8{
	3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53,
}

// smallPrimesProduct is the product of the values in smallPrimes and allows us
// to reduce a candidate prime by this number and then determine whether it's
// coprime to all the elements of smallPrimes without further big.Int
// operations.
var smallPrimesProduct = new(big.Int).SetUint64(16294579238595022365)

// Prime returns a number, p, of the given size, such that p is prime
// with high probability.
func Prime(rand io.Reader, bits int) (p *big.Int, err error) {
	if bits < 1 {
		err = errors.New("crypto/rand: prime size must be positive")
	}

	b := uint(bits % 8)
	if b == 0 {
		b = 8
	}

	bytes := make([]byte, (bits+7)/8)
	p = new(big.Int)

	bigMod := new(big.Int)

	for {
		_, err = io.ReadFull(rand, bytes)
		if err != nil {
			return nil, err
		}

		// Clear bits in the first byte to make sure the candidate has a size <= bits.
		bytes[0] &= uint8(int(1<<b) - 1)
		// Don't let the value be too small, i.e, set the most significant two bits.
		// Setting the top two bits, rather than just the top bit,
		// means that when two of these values are multiplied together,
		// the result isn't ever one bit short.
		if b >= 2 {
			bytes[0] |= 3 << (b - 2)
		} else {
			// Here b==1, because b cannot be zero.
			bytes[0] |= 1
			if len(bytes) > 1 {
				bytes[1] |= 0x80
			}
		}
		// Make the value odd since an even number this large certainly isn't prime.
		bytes[len(bytes)-1] |= 1

		p.SetBytes(bytes)

		// Calculate the value mod the product of smallPrimes.  If it's
		// a multiple of any of these primes we add two until it isn't.
		// The probability of overflowing is minimal and can be ignored
		// because we still perform Miller-Rabin tests on the result.
		bigMod.Mod(p, smallPrimesProduct)
		mod := bigMod.Uint64()

	NextDelta:
		for delta := uint64(0); delta < 1<<20; delta += 2 {
			m := mod + delta
			for _, prime := range smallPrimes {
				if m%uint64(prime) == 0 {
					continue NextDelta
				}
			}

			if delta > 0 {
				bigMod.SetUint64(delta)
				p.Add(p, bigMod)
			}
			break
		}

		// There is a tiny possibility that, by adding delta, we caused
		// the number to be one bit too long. Thus we check BitLen
		// here.
		if p.ProbablyPrime(20) && p.BitLen() == bits {
			return
		}
	}
}

// Int returns a uniform random value in [0, max). It panics if max <= 0.
func Int(rand io.Reader, max *big.Int) (n *big.Int, err error) {
	if max.Sign() <= 0 {
		panic("crypto/rand: argument to Int is <= 0")
	}
	k := (max.BitLen() + 7) / 8

	// b is the number of bits in the most significant byte of max.
	b := uint(max.BitLen() % 8)
	if b == 0 {
		b = 8
	}

	bytes := make([]byte, k)
	n = new(big.Int)

	for {
		_, err = io.ReadFull(rand, bytes)
		if err != nil {
			return nil, err
		}

		// Clear bits in the first byte to increase the probability
		// that the candidate is < max.
		bytes[0] &= uint8(int(1<<b) - 1)

		n.SetBytes(bytes)
		if n.Cmp(max) < 0 {
			return
		}
	}
}
<|endoftext|>


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

package sort

import "testing"

func f(a []int, x int) func(int) bool {
	return func(i int) bool {
		return a[i] <= x
	}
}

var data = []int{0: -10, 1: -5, 2: 0, 3: 1, 4: 2, 5: 3, 6: 5, 7: 7, 8: 11, 9: 100, 10: 100, 11: 100, 12: 1000, 13: 10000}

var tests = []struct {
	name string
	n    int
	f    func(int) bool
	i    int
}{
	{"empty", 0, nil, 0},
	{"1 1", 1, func(i int) bool { return i <= 1 }, 0},
	{"1 false", 1, func(i int) bool { return false }, 0},
	{"1 true", 1, func(i int) bool { return true }, 0},
	{"1e9 991", 1e9, func(i int) bool { return i <= 991 }, 991},
	{"1e9 false", 1e9, func(i int) bool { return false }, 0},
	{"1e9 true", 1e9, func(i int) bool { return true }, 1e9 - 1},
	{"data -20", len(data), f(data, -20), 0},
	{"data -10", len(data), f(data, -10), 0},
	{"data -9", len(data), f(data, -9), 0},
	{"data -6", len(data), f(data, -6), 0},
	{"data -5", len(data), f(data, -5), 1},
	{"data 3", len(data), f(data, 3), 5},
	{"data 99", len(data), f(data, 99), 8},
	{"data 100", len(data), f(data, 100), 11},
	{"data 101", len(data), f(data, 101), 11},
	{"data 10000", len(data), f(data, 10000), 13},
	{"data 10001", len(data), f(data, 10001), 13},
	{"descending a", 7, func(i int) bool { return []int{99, 99, 59, 42, 7, 0, -1, -1}[i] >= 7 }, 4},
	{"descending 7", 1e9, func(i int) bool { return 1e9-i >= 7 }, 1e9 - 7},
}

func TestSearch(t *testing.T) {
	for _, e := range tests {
		i := Search(e.n, e.f)
		if i != e.i {
			t.Errorf("%s: expected index %d; got %d", e.name, e.i, i)
		}
	}
}

// Smoke tests for convenience wrappers - not comprehensive.

var fdata = []float{0: -3.14, 1: 0, 2: 1, 3: 2, 4: 1000.7}
var sdata = []string{0: "f", 1: "foo", 2: "foobar", 3: "x"}

var wrappertests = []struct {
	name   string
	result int
	i      int
}{
	{"SearchInts", SearchInts(data, 11), 8},
	{"SearchFloats", SearchFloats(fdata, 2.1), 3},
	{"SearchStrings", SearchStrings(sdata, ""), 0},
	{"IntArray.Search", IntArray(data).Search(0), 2},
	{"FloatArray.Search", FloatArray(fdata).Search(2.0), 3},
	{"StringArray.Search", StringArray(sdata).Search("x"), 3},
}

func TestSearchWrappers(t *testing.T) {
	for _, e := range wrappertests {
		if e.result != e.i {
			t.Errorf("%s: expected index %d; got %d", e.name, e.i, e.result)
		}
	}
}
<commit_msg>sort.Search: added extra test to verify efficiency<commit_after>// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package sort

import "testing"

func f(a []int, x int) func(int) bool {
	return func(i int) bool {
		return a[i] <= x
	}
}

var data = []int{0: -10, 1: -5, 2: 0, 3: 1, 4: 2, 5: 3, 6: 5, 7: 7, 8: 11, 9: 100, 10: 100, 11: 100, 12: 1000, 13: 10000}

var tests = []struct {
	name string
	n    int
	f    func(int) bool
	i    int
}{
	{"empty", 0, nil, 0},
	{"1 1", 1, func(i int) bool { return i <= 1 }, 0},
	{"1 false", 1, func(i int) bool { return false }, 0},
	{"1 true", 1, func(i int) bool { return true }, 0},
	{"1e9 991", 1e9, func(i int) bool { return i <= 991 }, 991},
	{"1e9 false", 1e9, func(i int) bool { return false }, 0},
	{"1e9 true", 1e9, func(i int) bool { return true }, 1e9 - 1},
	{"data -20", len(data), f(data, -20), 0},
	{"data -10", len(data), f(data, -10), 0},
	{"data -9", len(data), f(data, -9), 0},
	{"data -6", len(data), f(data, -6), 0},
	{"data -5", len(data), f(data, -5), 1},
	{"data 3", len(data), f(data, 3), 5},
	{"data 99", len(data), f(data, 99), 8},
	{"data 100", len(data), f(data, 100), 11},
	{"data 101", len(data), f(data, 101), 11},
	{"data 10000", len(data), f(data, 10000), 13},
	{"data 10001", len(data), f(data, 10001), 13},
	{"descending a", 7, func(i int) bool { return []int{99, 99, 59, 42, 7, 0, -1, -1}[i] >= 7 }, 4},
	{"descending 7", 1e9, func(i int) bool { return 1e9-i >= 7 }, 1e9 - 7},
}

func TestSearch(t *testing.T) {
	for _, e := range tests {
		i := Search(e.n, e.f)
		if i != e.i {
			t.Errorf("%s: expected index %d; got %d", e.name, e.i, i)
		}
	}
}

// log2 computes the binary logarithm of x, rounded up to the next integer.
// (log2(0) == 0, log2(1) == 0, log2(2) == 1, log2(3) == 2, etc.)
//
func log2(x int) int {
	n := 0
	for p := 1; p < x; p += p {
		// p == 2**n
		n++
	}
	// p/2 < x <= p == 2**n
	return n
}

func TestSearchEfficiency(t *testing.T) {
	n := 100
	step := 1
	for exp := 2; exp < 10; exp++ {
		// n == 10**exp
		// step == 10**(exp-2)
		max := log2(n)
		for x := 0; x < n; x += step {
			count := 0
			i := Search(n, func(i int) bool { count++; return i <= x })
			if i != x {
				t.Errorf("n = %d: expected index %d; got %d", n, x, i)
			}
			if count > max {
				t.Errorf("n = %d, x = %d: expected <= %d calls; got %d", n, x, max, count)
			}
		}
		n *= 10
		step *= 10
	}
}

// Smoke tests for convenience wrappers - not comprehensive.

var fdata = []float{0: -3.14, 1: 0, 2: 1, 3: 2, 4: 1000.7}
var sdata = []string{0: "f", 1: "foo", 2: "foobar", 3: "x"}

var wrappertests = []struct {
	name   string
	result int
	i      int
}{
	{"SearchInts", SearchInts(data, 11), 8},
	{"SearchFloats", SearchFloats(fdata, 2.1), 3},
	{"SearchStrings", SearchStrings(sdata, ""), 0},
	{"IntArray.Search", IntArray(data).Search(0), 2},
	{"FloatArray.Search", FloatArray(fdata).Search(2.0), 3},
	{"StringArray.Search", StringArray(sdata).Search("x"), 3},
}

func TestSearchWrappers(t *testing.T) {
	for _, e := range wrappertests {
		if e.result != e.i {
			t.Errorf("%s: expected index %d; got %d", e.name, e.i, e.result)
		}
	}
}
<|endoftext|>


<commit_before>package main_test

import (
	"strings"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	. "github.com/onsi/gomega/gexec"

	"github.com/cloudfoundry-incubator/cf-test-helpers/generator"

	"time"

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

var _ = Describe("Pushing an app", func() {
	It("stops the time for pushing an app", func() {
		for index := 0; index < loopCount; index++ {
			startTime := time.Now()

			appName := generator.PrefixedRandomName("APP")
			Expect(
				cf.Cf("push", appName, "-p", "assets/golang", "-b", "go_buildpack").Wait(cfPushTimeout)).
				To(Exit(0))

			metricsService.SendTimingMetric(asSparseMetric("cf-push"), time.Since(startTime))

			Expect(
				cf.Cf("delete", appName, "-f").Wait(cfPushTimeout)).
				To(Exit(0))
		}

		Expect(metricsService.filename).To(BeAnExistingFile())

		lastLine, err := lastLine(metricsService.filename)
		Expect(err).NotTo(HaveOccurred())

		parts := strings.Split(lastLine, ",")
		Expect(parts).To(HaveLen(4))

		_, err = time.Parse(time.RFC3339, parts[0])
		Expect(err).NotTo(HaveOccurred())

		Expect(parts[1]).To(Equal("cf-push_sparse-avg"))
		Expect(parts[2]).To(MatchRegexp("\\d+"))
		Expect(parts[3]).To(MatchRegexp("ms"))
	})
})

func asSparseMetric(metricName string) string {
	return metricsPrefix + metricName + "_sparse-avg"
}
<commit_msg>Ignore metrics prefix<commit_after>package main_test

import (
	"strings"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	. "github.com/onsi/gomega/gexec"

	"github.com/cloudfoundry-incubator/cf-test-helpers/generator"

	"time"

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

var _ = Describe("Pushing an app", func() {
	It("stops the time for pushing an app", func() {
		for index := 0; index < loopCount; index++ {
			startTime := time.Now()

			appName := generator.PrefixedRandomName("APP")
			Expect(
				cf.Cf("push", appName, "-p", "assets/golang", "-b", "go_buildpack").Wait(cfPushTimeout)).
				To(Exit(0))

			metricsService.SendTimingMetric(asSparseMetric("cf-push"), time.Since(startTime))

			Expect(
				cf.Cf("delete", appName, "-f").Wait(cfPushTimeout)).
				To(Exit(0))
		}

		Expect(metricsService.filename).To(BeAnExistingFile())

		lastLine, err := lastLine(metricsService.filename)
		Expect(err).NotTo(HaveOccurred())

		parts := strings.Split(lastLine, ",")
		Expect(parts).To(HaveLen(4))

		_, err = time.Parse(time.RFC3339, parts[0])
		Expect(err).NotTo(HaveOccurred())

		Expect(parts[1]).To(HaveSuffix("cf-push_sparse-avg"))
		Expect(parts[2]).To(MatchRegexp("\\d+"))
		Expect(parts[3]).To(MatchRegexp("ms"))
	})
})

func asSparseMetric(metricName string) string {
	return metricsPrefix + metricName + "_sparse-avg"
}
<|endoftext|>


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

// Package repl contains the implementation of the command that prints the
// BQL version.
package repl

import (
	"bufio"
	"fmt"
	"io"
	"os"
	"strings"
	"time"

	"golang.org/x/net/context"

	"github.com/google/badwolf/bql/grammar"
	"github.com/google/badwolf/bql/planner"
	"github.com/google/badwolf/bql/semantic"
	"github.com/google/badwolf/bql/table"
	"github.com/google/badwolf/bql/version"
	"github.com/google/badwolf/storage"
	"github.com/google/badwolf/tools/vcli/bw/command"
	"github.com/google/badwolf/tools/vcli/bw/export"
	bio "github.com/google/badwolf/tools/vcli/bw/io"
	"github.com/google/badwolf/tools/vcli/bw/load"
)

const prompt = "bql> "

// New create the version command.
func New(driver storage.Store, chanSize, bulkSize, builderSize int, rl ReadLiner, done chan bool) *command.Command {
	return &command.Command{
		Run: func(ctx context.Context, args []string) int {
			REPL(driver, os.Stdin, rl, chanSize, bulkSize, builderSize, done)
			return 0
		},
		UsageLine: "bql",
		Short:     "starts a REPL to run BQL statements.",
		Long:      "Starts a REPL from the command line to accept BQL statements. Type quit; to leave the REPL.",
	}
}

// ReadLiner returns a channel with the imput to be used for the REPL.
type ReadLiner func(done chan bool) <-chan string

// SimpleReadLine reads a line from the provided file. This does not support
// any advanced terminal capabilities.
//
// This function can be replaced with more advanced functionality, as shown
// https://github.com/xllora/bwdrivers/blob/master/bw/main.go.
func SimpleReadLine(done chan bool) <-chan string {
	c := make(chan string)
	go func() {
		defer close(c)
		scanner := bufio.NewScanner(os.Stdin)
		cmd := ""
		fmt.Print("bql> ")
		for {
			if !scanner.Scan() {
				break
			}
			cmd = strings.TrimSpace(cmd + " " + strings.TrimSpace(scanner.Text()))
			if strings.HasSuffix(cmd, ";") {
				c <- cmd
				if <-done {
					break
				}
				cmd = ""
				fmt.Print("bql> ")
			}
		}
	}()
	return c
}

// REPL starts a read-evaluation-print-loop to run BQL commands.
func REPL(driver storage.Store, input *os.File, rl ReadLiner, chanSize, bulkSize, builderSize int, done chan bool) int {
	var tracer io.Writer
	ctx, isTracingToFile, sessionStart := context.Background(), false, time.Now()

	stopTracing := func() {
		if tracer != nil {
			if isTracingToFile {
				fmt.Println("Closing tracing file.")
				tracer.(*os.File).Close()
			}
			tracer, isTracingToFile = nil, false
		}
	}
	defer stopTracing()

	fmt.Printf("Welcome to BadWolf vCli (%d.%d.%d-%s)\n", version.Major, version.Minor, version.Patch, version.Release)
	fmt.Printf("Using driver %q. Type quit; to exit\n", driver.Name(ctx))
	fmt.Printf("Session started at %v\n\n", sessionStart)
	defer func() {
		fmt.Printf("\n\nThanks for all those BQL queries!\nSession duration: %v\n\n", time.Now().Sub(sessionStart))
	}()

	for l := range rl(done) {
		if strings.HasPrefix(l, "quit") {
			done <- true
			break
		}
		if strings.HasPrefix(l, "help") {
			printHelp()
			done <- false
			continue
		}
		if strings.HasPrefix(l, "start tracing") {
			args := strings.Split(strings.TrimSpace(l)[:len(l)-1], " ")
			switch len(args) {
			case 2:
				// Start tracing to the console.
				stopTracing()
				tracer, isTracingToFile = os.Stdout, false
				fmt.Println("[WARNING] Tracing is on. This may slow your BQL queries.")
			case 3:
				// Start tracing to file.
				stopTracing()
				f, err := os.Create(args[2])
				if err != nil {
					fmt.Println(err)
				} else {
					tracer, isTracingToFile = f, true
					fmt.Println("[WARNING] Tracing is on. This may slow your BQL queries.")
				}
			default:
				fmt.Println("Invalid syntax\n\tstart tracing [trace_file]")
			}
			done <- false
			continue
		}
		if strings.HasPrefix(l, "stop tracing") {
			stopTracing()
			fmt.Println("Tracing is off.")
			done <- false
			continue
		}
		if strings.HasPrefix(l, "export") {
			now := time.Now()
			args := strings.Split("bw "+strings.TrimSpace(l)[:len(l)-1], " ")
			usage := "Wrong syntax\n\n\tload <graph_names_separated_by_commas> <file_path>\n"
			export.Eval(ctx, usage, args, driver, bulkSize)
			fmt.Println("[OK] Time spent: ", time.Now().Sub(now))
			done <- false
			continue
		}
		if strings.HasPrefix(l, "load") {
			now := time.Now()
			args := strings.Split("bw "+strings.TrimSpace(l[:len(l)-1]), " ")
			usage := "Wrong syntax\n\n\tload <file_path> <graph_names_separated_by_commas>\n"
			load.Eval(ctx, usage, args, driver, bulkSize, builderSize)
			fmt.Println("[OK] Time spent: ", time.Now().Sub(now))
			done <- false
			continue
		}
		if strings.HasPrefix(l, "desc") {
			pln, err := planBQL(ctx, l[4:], driver, chanSize, bulkSize, nil)
			if err != nil {
				fmt.Printf("[ERROR] %s\n\n", err)
			} else {
				fmt.Println(pln.String())
				fmt.Println("[OK]")
			}
			done <- false
			continue
		}
		if strings.HasPrefix(l, "run") {
			now := time.Now()
			path, cmds, err := runBQLFromFile(ctx, driver, chanSize, bulkSize, strings.TrimSpace(l[:len(l)-1]), tracer)
			if err != nil {
				fmt.Printf("[ERROR] %s\n\n", err)
			} else {
				fmt.Printf("Loaded %q and run %d BQL commands successfully\n\n", path, cmds)
			}
			fmt.Println("Time spent: ", time.Now().Sub(now))
			done <- false
			continue
		}

		now := time.Now()
		table, err := runBQL(ctx, l, driver, chanSize, bulkSize, tracer)
		if err != nil {
			fmt.Printf("[ERROR] %s\n", err)
			fmt.Println("Time spent: ", time.Now().Sub(now))
			fmt.Println()
		} else {
			if len(table.Bindings()) > 0 {
				fmt.Println(table.String())
			}
			fmt.Printf("[OK] %d rows retrived. Time spent: %v.\n", table.NumRows(), time.Now().Sub(now))
		}
		done <- false
	}
	return 0
}

// printHelp prints help for the console commands.
func printHelp() {
	fmt.Println("help                                                  - prints help for the bw console.")
	fmt.Println("export <graph_names_separated_by_commas> <file_path>  - dumps triples from graphs into a file path.")
	fmt.Println("desc <BQL>                                            - prints the execution plan for a BQL statement.")
	fmt.Println("load <file_path> <graph_names_separated_by_commas>    - load triples into the specified graphs.")
	fmt.Println("run <file_with_bql_statements>                        - runs all the BQL statements in the file.")
	fmt.Println("start tracing [trace_file]                            - starts tracing queries.")
	fmt.Println("stop tracing                                          - stops tracing queries.")
	fmt.Println("quit                                                  - quits the console.")
	fmt.Println()
}

// runBQLFromFile loads all the statements in the file and runs them.
func runBQLFromFile(ctx context.Context, driver storage.Store, chanSize, bulkSize int, line string, w io.Writer) (string, int, error) {
	ss := strings.Split(strings.TrimSpace(line), " ")
	if len(ss) != 2 {
		return "", 0, fmt.Errorf("wrong syntax: run <file_with_bql_statements>")
	}
	path := ss[1]
	lines, err := bio.GetStatementsFromFile(path)
	if err != nil {
		return "", 0, fmt.Errorf("failed to read file %q with error %v on\n", path, err)
	}
	for idx, stm := range lines {
		fmt.Printf("Processing statement (%d/%d)\n", idx+1, len(lines))
		_, err := runBQL(ctx, stm, driver, chanSize, bulkSize, w)
		if err != nil {
			return "", 0, fmt.Errorf("%v on\n%s\n", err, stm)
		}
	}
	fmt.Println()
	return path, len(lines), nil
}

// runBQL attempts to execute the provided query against the given store.
func runBQL(ctx context.Context, bql string, s storage.Store, chanSize, bulkSize int, w io.Writer) (*table.Table, error) {
	pln, err := planBQL(ctx, bql, s, chanSize, bulkSize, w)
	if err != nil {
		return nil, err
	}
	res, err := pln.Execute(ctx)
	if err != nil {
		return nil, fmt.Errorf("planner.Execute: failed to execute query plan with error %v", err)
	}
	return res, nil
}

// planBQL attempts to create the execution plan for the provided query against the given store.
func planBQL(ctx context.Context, bql string, s storage.Store, chanSize, bulkSize int, w io.Writer) (planner.Executor, error) {
	p, err := grammar.NewParser(grammar.SemanticBQL())
	if err != nil {
		return nil, fmt.Errorf("failed to initilize a valid BQL parser")
	}
	stm := &semantic.Statement{}
	if err := p.Parse(grammar.NewLLk(bql, 1), stm); err != nil {
		return nil, fmt.Errorf("failed to parse BQL statement with error %v", err)
	}
	pln, err := planner.New(ctx, s, stm, chanSize, bulkSize, w)
	if err != nil {
		return nil, fmt.Errorf("should have not failed to create a plan using memory.DefaultStorage for statement %v with error %v", stm, err)
	}
	return pln, nil
}
<commit_msg>Split time shown at the end uf the REPL<commit_after>// Copyright 2016 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Package repl contains the implementation of the command that prints the
// BQL version.
package repl

import (
	"bufio"
	"fmt"
	"io"
	"os"
	"strings"
	"time"

	"golang.org/x/net/context"

	"github.com/google/badwolf/bql/grammar"
	"github.com/google/badwolf/bql/planner"
	"github.com/google/badwolf/bql/semantic"
	"github.com/google/badwolf/bql/table"
	"github.com/google/badwolf/bql/version"
	"github.com/google/badwolf/storage"
	"github.com/google/badwolf/tools/vcli/bw/command"
	"github.com/google/badwolf/tools/vcli/bw/export"
	bio "github.com/google/badwolf/tools/vcli/bw/io"
	"github.com/google/badwolf/tools/vcli/bw/load"
)

const prompt = "bql> "

// New create the version command.
func New(driver storage.Store, chanSize, bulkSize, builderSize int, rl ReadLiner, done chan bool) *command.Command {
	return &command.Command{
		Run: func(ctx context.Context, args []string) int {
			REPL(driver, os.Stdin, rl, chanSize, bulkSize, builderSize, done)
			return 0
		},
		UsageLine: "bql",
		Short:     "starts a REPL to run BQL statements.",
		Long:      "Starts a REPL from the command line to accept BQL statements. Type quit; to leave the REPL.",
	}
}

// ReadLiner returns a channel with the imput to be used for the REPL.
type ReadLiner func(done chan bool) <-chan string

// SimpleReadLine reads a line from the provided file. This does not support
// any advanced terminal capabilities.
//
// This function can be replaced with more advanced functionality, as shown
// https://github.com/xllora/bwdrivers/blob/master/bw/main.go.
func SimpleReadLine(done chan bool) <-chan string {
	c := make(chan string)
	go func() {
		defer close(c)
		scanner := bufio.NewScanner(os.Stdin)
		cmd := ""
		fmt.Print("bql> ")
		for {
			if !scanner.Scan() {
				break
			}
			cmd = strings.TrimSpace(cmd + " " + strings.TrimSpace(scanner.Text()))
			if strings.HasSuffix(cmd, ";") {
				c <- cmd
				if <-done {
					break
				}
				cmd = ""
				fmt.Print("bql> ")
			}
		}
	}()
	return c
}

// REPL starts a read-evaluation-print-loop to run BQL commands.
func REPL(driver storage.Store, input *os.File, rl ReadLiner, chanSize, bulkSize, builderSize int, done chan bool) int {
	var tracer io.Writer
	ctx, isTracingToFile, sessionStart := context.Background(), false, time.Now()

	stopTracing := func() {
		if tracer != nil {
			if isTracingToFile {
				fmt.Println("Closing tracing file.")
				tracer.(*os.File).Close()
			}
			tracer, isTracingToFile = nil, false
		}
	}
	defer stopTracing()

	fmt.Printf("Welcome to BadWolf vCli (%d.%d.%d-%s)\n", version.Major, version.Minor, version.Patch, version.Release)
	fmt.Printf("Using driver %q. Type quit; to exit\n", driver.Name(ctx))
	fmt.Printf("Session started at %v\n\n", sessionStart)
	defer func() {
		fmt.Printf("\n\nThanks for all those BQL queries!\nSession duration: %v\n\n", time.Now().Sub(sessionStart))
	}()

	for l := range rl(done) {
		if strings.HasPrefix(l, "quit") {
			done <- true
			break
		}
		if strings.HasPrefix(l, "help") {
			printHelp()
			done <- false
			continue
		}
		if strings.HasPrefix(l, "start tracing") {
			args := strings.Split(strings.TrimSpace(l)[:len(l)-1], " ")
			switch len(args) {
			case 2:
				// Start tracing to the console.
				stopTracing()
				tracer, isTracingToFile = os.Stdout, false
				fmt.Println("[WARNING] Tracing is on. This may slow your BQL queries.")
			case 3:
				// Start tracing to file.
				stopTracing()
				f, err := os.Create(args[2])
				if err != nil {
					fmt.Println(err)
				} else {
					tracer, isTracingToFile = f, true
					fmt.Println("[WARNING] Tracing is on. This may slow your BQL queries.")
				}
			default:
				fmt.Println("Invalid syntax\n\tstart tracing [trace_file]")
			}
			done <- false
			continue
		}
		if strings.HasPrefix(l, "stop tracing") {
			stopTracing()
			fmt.Println("Tracing is off.")
			done <- false
			continue
		}
		if strings.HasPrefix(l, "export") {
			now := time.Now()
			args := strings.Split("bw "+strings.TrimSpace(l)[:len(l)-1], " ")
			usage := "Wrong syntax\n\n\tload <graph_names_separated_by_commas> <file_path>\n"
			export.Eval(ctx, usage, args, driver, bulkSize)
			fmt.Println("[OK] Time spent: ", time.Now().Sub(now))
			done <- false
			continue
		}
		if strings.HasPrefix(l, "load") {
			now := time.Now()
			args := strings.Split("bw "+strings.TrimSpace(l[:len(l)-1]), " ")
			usage := "Wrong syntax\n\n\tload <file_path> <graph_names_separated_by_commas>\n"
			load.Eval(ctx, usage, args, driver, bulkSize, builderSize)
			fmt.Println("[OK] Time spent: ", time.Now().Sub(now))
			done <- false
			continue
		}
		if strings.HasPrefix(l, "desc") {
			pln, err := planBQL(ctx, l[4:], driver, chanSize, bulkSize, nil)
			if err != nil {
				fmt.Printf("[ERROR] %s\n\n", err)
			} else {
				fmt.Println(pln.String())
				fmt.Println("[OK]")
			}
			done <- false
			continue
		}
		if strings.HasPrefix(l, "run") {
			now := time.Now()
			path, cmds, err := runBQLFromFile(ctx, driver, chanSize, bulkSize, strings.TrimSpace(l[:len(l)-1]), tracer)
			if err != nil {
				fmt.Printf("[ERROR] %s\n\n", err)
			} else {
				fmt.Printf("Loaded %q and run %d BQL commands successfully\n\n", path, cmds)
			}
			fmt.Println("Time spent: ", time.Now().Sub(now))
			done <- false
			continue
		}

		now := time.Now()
		table, err := runBQL(ctx, l, driver, chanSize, bulkSize, tracer)
		bqlDiff := time.Now().Sub(now)
		if err != nil {
			fmt.Printf("[ERROR] %s\n", err)
			fmt.Println("Time spent: ", time.Now().Sub(now))
			fmt.Println()
		} else {
			if len(table.Bindings()) > 0 {
				fmt.Println(table.String())
			}
			fmt.Printf("[OK] %d rows retrived. BQL time: %v. Display time: %v\n",
				table.NumRows(), bqlDiff, time.Now().Sub(now)-bqlDiff)
		}
		done <- false
	}
	return 0
}

// printHelp prints help for the console commands.
func printHelp() {
	fmt.Println("help                                                  - prints help for the bw console.")
	fmt.Println("export <graph_names_separated_by_commas> <file_path>  - dumps triples from graphs into a file path.")
	fmt.Println("desc <BQL>                                            - prints the execution plan for a BQL statement.")
	fmt.Println("load <file_path> <graph_names_separated_by_commas>    - load triples into the specified graphs.")
	fmt.Println("run <file_with_bql_statements>                        - runs all the BQL statements in the file.")
	fmt.Println("start tracing [trace_file]                            - starts tracing queries.")
	fmt.Println("stop tracing                                          - stops tracing queries.")
	fmt.Println("quit                                                  - quits the console.")
	fmt.Println()
}

// runBQLFromFile loads all the statements in the file and runs them.
func runBQLFromFile(ctx context.Context, driver storage.Store, chanSize, bulkSize int, line string, w io.Writer) (string, int, error) {
	ss := strings.Split(strings.TrimSpace(line), " ")
	if len(ss) != 2 {
		return "", 0, fmt.Errorf("wrong syntax: run <file_with_bql_statements>")
	}
	path := ss[1]
	lines, err := bio.GetStatementsFromFile(path)
	if err != nil {
		return "", 0, fmt.Errorf("failed to read file %q with error %v on\n", path, err)
	}
	for idx, stm := range lines {
		fmt.Printf("Processing statement (%d/%d)\n", idx+1, len(lines))
		_, err := runBQL(ctx, stm, driver, chanSize, bulkSize, w)
		if err != nil {
			return "", 0, fmt.Errorf("%v on\n%s\n", err, stm)
		}
	}
	fmt.Println()
	return path, len(lines), nil
}

// runBQL attempts to execute the provided query against the given store.
func runBQL(ctx context.Context, bql string, s storage.Store, chanSize, bulkSize int, w io.Writer) (*table.Table, error) {
	pln, err := planBQL(ctx, bql, s, chanSize, bulkSize, w)
	if err != nil {
		return nil, err
	}
	res, err := pln.Execute(ctx)
	if err != nil {
		return nil, fmt.Errorf("planner.Execute: failed to execute query plan with error %v", err)
	}
	return res, nil
}

// planBQL attempts to create the execution plan for the provided query against the given store.
func planBQL(ctx context.Context, bql string, s storage.Store, chanSize, bulkSize int, w io.Writer) (planner.Executor, error) {
	p, err := grammar.NewParser(grammar.SemanticBQL())
	if err != nil {
		return nil, fmt.Errorf("failed to initilize a valid BQL parser")
	}
	stm := &semantic.Statement{}
	if err := p.Parse(grammar.NewLLk(bql, 1), stm); err != nil {
		return nil, fmt.Errorf("failed to parse BQL statement with error %v", err)
	}
	pln, err := planner.New(ctx, s, stm, chanSize, bulkSize, w)
	if err != nil {
		return nil, fmt.Errorf("should have not failed to create a plan using memory.DefaultStorage for statement %v with error %v", stm, err)
	}
	return pln, nil
}
<|endoftext|>


<commit_before>package main

import (
	"log"
	"regexp"
	"sort"

	"github.com/shirou/gopsutil/process"
)

var javaRegexp = regexp.MustCompile(`javaw?(\.exe)?`)

type byMemoryUsage []*process.Process

func (a byMemoryUsage) Len() int { return len(a) }

func (a byMemoryUsage) Swap(i, j int) { a[i], a[j] = a[j], a[i] }

func (a byMemoryUsage) Less(i, j int) bool {
	iMU, err := a[i].MemoryPercent()
	if err != nil {
		log.Panic(err)
	}

	jMU, err := a[j].MemoryPercent()
	if err != nil {
		log.Panic(err)
	}

	return iMU < jMU
}

func killJava() {
	log.Println("=== killJava ===")
	defer log.Println("================")

	pids, err := process.Pids()
	if err != nil {
		log.Panic(err)
	}

	var procs []*process.Process
	for _, pid := range pids {
		proc, err := process.NewProcess(pid)
		if err != nil {
			log.Panic(err)
		}

		name, err := proc.Name()
		if err != nil {
			log.Panic(err)
		}

		if javaRegexp.MatchString(name) {
			procs = append(procs, proc)
		}
	}

	sort.Sort(byMemoryUsage(procs))
	log.Println("Found", len(procs), "Java processes.")
	if len(procs) == 0 {
		return
	}

	log.Println("procs:", procs)
	log.Println("Killing top memory user:", procs[0])
	if err := procs[0].Kill(); err != nil {
		log.Println(err)
	}
}
<commit_msg>Fixes client for Windows.<commit_after>package main

import (
	"log"
	"os"
	"regexp"
	"sort"

	"github.com/shirou/gopsutil/process"
)

var javaRegexp = regexp.MustCompile(`javaw?(\.exe)?`)

type byMemoryUsage []*process.Process

func (a byMemoryUsage) Len() int { return len(a) }

func (a byMemoryUsage) Swap(i, j int) { a[i], a[j] = a[j], a[i] }

func (a byMemoryUsage) Less(i, j int) bool {
	iMU, err := a[i].MemoryPercent()
	if err != nil {
		log.Panic(err)
	}

	jMU, err := a[j].MemoryPercent()
	if err != nil {
		log.Panic(err)
	}

	return iMU < jMU
}

func killJava() {
	log.Println("=== killJava ===")
	defer log.Println("================")

	pids, err := process.Pids()
	if err != nil {
		log.Panic(err)
	}

	var procs []*process.Process
	for _, pid := range pids {
		proc, err := process.NewProcess(pid)
		if err != nil {
			log.Panic(err)
		}

		name, err := proc.Name()
		if err != nil {
			log.Println(err)
			continue
		}

		if javaRegexp.MatchString(name) {
			procs = append(procs, proc)
		}
	}

	sort.Sort(byMemoryUsage(procs))
	log.Println("Found", len(procs), "Java processes.")
	if len(procs) == 0 {
		return
	}

	log.Println("procs:", procs)
	log.Println("Killing top memory user:", procs[0])
	osProc, err := os.FindProcess(int(procs[0].Pid))
	if err != nil {
		log.Panic(err)
	}
	if err = osProc.Kill(); err != nil {
		log.Panic(err)
	}
}
<|endoftext|>


<commit_before>package cwriter

import (
	"bytes"
	"fmt"
	"testing"
)

func TestWriter(t *testing.T) {
	b := &bytes.Buffer{}
	w := New(b)
	for i := 0; i < 2; i++ {
		fmt.Fprintln(w, "foo")
	}
	w.Flush()
	want := "foo\nfoo\n"
	if b.String() != want {
		t.Fatalf("want %q, got %q", want, b.String())
	}
}
<commit_msg>Remove duplicate test<commit_after><|endoftext|>