<commit_before>package main

import (
	"database/sql"
	"fmt"
	"log"
	"os"
	"strings"

	"github.com/codegangsta/cli"
	_ "github.com/go-sql-driver/mysql"
	"github.com/karamani/iostreams"
)

var (
	debugMode           bool
	queryArg            string
	connectionStringArg string
	throughMode         bool
	fakeMode            bool
)

func main() {
	app := cli.NewApp()
	app.Name = "massquery"
	app.Usage = "massquery"
	app.Flags = []cli.Flag{
		cli.BoolFlag{
			Name:        "debug",
			Usage:       "debug mode",
			EnvVar:      "MASSQUERY_DEBUG",
			Destination: &debugMode,
		},
		cli.StringFlag{
			Name:        "query",
			Usage:       "sql-query",
			Destination: &queryArg,
		},
		cli.StringFlag{
			Name:        "cnn",
			Usage:       "db connection string",
			Destination: &connectionStringArg,
		},
		cli.BoolFlag{
			Name:        "through",
			Usage:       "through mode",
			Destination: &throughMode,
		},
		cli.BoolFlag{
			Name:        "fake",
			Usage:       "fake mode",
			Destination: &fakeMode,
		},
	}

	app.Action = func(c *cli.Context) {

		// this func's called for each stdin's row
		process := func(row []byte) error {

			var (
				connectionString string
				resPrefix        string
			)

			debug(string(row))

			params := strings.Split(string(row), "\t")
			if len(connectionStringArg) == 0 && len(params) < 2 {
				log.Printf("[ERROR] Не хватает параметров в stdin. Нужно минимум 2. Получено %d\n", len(params))
			}

			if len(connectionStringArg) > 0 {
				connectionString = connectionStringArg
			} else {
				connectionString = params[1]
			}

			query := c.String("query")

			for i, param := range params {
				paramTpl := fmt.Sprintf("{%d}", i+1)
				query = strings.Replace(query, paramTpl, param, -1)
			}

			debug(query)

			if throughMode {
				resPrefix = string(row)
			} else {
				resPrefix = params[0]
			}

			res, err := runQuery(connectionString, query)
			if err != nil {
				fmt.Printf(resPrefix + "\terror\t\n")
				log.Println(err.Error())
			} else {
				fmt.Printf(resPrefix+"\tsuccess\t%s\n", res)
			}
			return nil
		}

		err := iostreams.ProcessStdin(process)
		if err != nil {
			log.Panicln(err.Error())
		}
	}

	app.Run(os.Args)
}

func runQuery(connectionString, query string) (string, error) {

	var res string

	db, err := sql.Open("mysql", connectionString)
	if err != nil {
		log.Println(err.Error())
		return "", err
	}
	defer db.Close()

	err = db.Ping()
	if err != nil {
		return "", err
	}

	if fakeMode {
		return "", nil
	}

	rows, err := db.Query(query)
	if err != nil {
		return "", err
	}
	defer rows.Close()

	for rows.Next() {
		if err := rows.Scan(&res); err != nil {
			return "", err
		}
		break
	}
	if err := rows.Err(); err != nil {
		return "", err
	}

	return res, nil
}

func debug(format string, args ...interface{}) {
	if debugMode {
		log.Printf("[DEBUG] "+format+"\n", args...)
	}
}
<commit_msg>MASSQUERY_CNN env var added<commit_after>package main

import (
	"database/sql"
	"fmt"
	"log"
	"os"
	"strings"

	"github.com/codegangsta/cli"
	_ "github.com/go-sql-driver/mysql"
	"github.com/karamani/iostreams"
)

var (
	debugMode           bool
	queryArg            string
	connectionStringArg string
	throughMode         bool
	fakeMode            bool
)

func main() {
	app := cli.NewApp()
	app.Name = "massquery"
	app.Usage = "massquery"
	app.Flags = []cli.Flag{
		cli.BoolFlag{
			Name:        "debug",
			Usage:       "debug mode",
			EnvVar:      "MASSQUERY_DEBUG",
			Destination: &debugMode,
		},
		cli.StringFlag{
			Name:        "query",
			Usage:       "sql-query",
			Destination: &queryArg,
		},
		cli.StringFlag{
			Name:        "cnn",
			Usage:       "db connection string",
			EnvVar:      "MASSQUERY_CNN",
			Destination: &connectionStringArg,
		},
		cli.BoolFlag{
			Name:        "through",
			Usage:       "through mode",
			Destination: &throughMode,
		},
		cli.BoolFlag{
			Name:        "fake",
			Usage:       "fake mode",
			Destination: &fakeMode,
		},
	}

	app.Action = func(c *cli.Context) {

		// this func's called for each stdin's row
		process := func(row []byte) error {

			var (
				connectionString string
				resPrefix        string
			)

			debug(string(row))

			params := strings.Split(string(row), "\t")
			if len(connectionStringArg) == 0 && len(params) < 2 {
				log.Printf("[ERROR] Не хватает параметров в stdin. Нужно минимум 2. Получено %d\n", len(params))
			}

			if len(connectionStringArg) > 0 {
				connectionString = connectionStringArg
			} else {
				connectionString = params[1]
			}

			query := c.String("query")

			for i, param := range params {
				paramTpl := fmt.Sprintf("{%d}", i+1)
				query = strings.Replace(query, paramTpl, param, -1)
			}

			debug(query)

			if throughMode {
				resPrefix = string(row)
			} else {
				resPrefix = params[0]
			}

			res, err := runQuery(connectionString, query)
			if err != nil {
				fmt.Printf(resPrefix + "\terror\t\n")
				log.Println(err.Error())
			} else {
				fmt.Printf(resPrefix+"\tsuccess\t%s\n", res)
			}
			return nil
		}

		err := iostreams.ProcessStdin(process)
		if err != nil {
			log.Panicln(err.Error())
		}
	}

	app.Run(os.Args)
}

func runQuery(connectionString, query string) (string, error) {

	var res string

	db, err := sql.Open("mysql", connectionString)
	if err != nil {
		log.Println(err.Error())
		return "", err
	}
	defer db.Close()

	err = db.Ping()
	if err != nil {
		return "", err
	}

	if fakeMode {
		return "", nil
	}

	rows, err := db.Query(query)
	if err != nil {
		return "", err
	}
	defer rows.Close()

	for rows.Next() {
		if err := rows.Scan(&res); err != nil {
			return "", err
		}
		break
	}
	if err := rows.Err(); err != nil {
		return "", err
	}

	return res, nil
}

func debug(format string, args ...interface{}) {
	if debugMode {
		log.Printf("[DEBUG] "+format+"\n", args...)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"html/template"

	"github.com/microcosm-cc/bluemonday"
	"github.com/russross/blackfriday"
)

func mdToHTML(md string) []byte {
	htmlFlags := 0
	htmlFlags |= blackfriday.HTML_USE_XHTML
	htmlFlags |= blackfriday.HTML_USE_SMARTYPANTS
	htmlFlags |= blackfriday.HTML_SMARTYPANTS_FRACTIONS
	htmlFlags |= blackfriday.HTML_SMARTYPANTS_LATEX_DASHES
	renderer := blackfriday.HtmlRenderer(htmlFlags, "", "")
	extensions := 0
	extensions |= blackfriday.EXTENSION_NO_INTRA_EMPHASIS
	extensions |= blackfriday.EXTENSION_TABLES
	extensions |= blackfriday.EXTENSION_FENCED_CODE
	extensions |= blackfriday.EXTENSION_AUTOLINK
	extensions |= blackfriday.EXTENSION_STRIKETHROUGH
	extensions |= blackfriday.EXTENSION_SPACE_HEADERS
	extensions |= blackfriday.EXTENSION_HEADER_IDS
	return blackfriday.Markdown([]byte(md), renderer, extensions)
}

func sanitizeTrustedHTML(html []byte) template.HTML {
	p := bluemonday.UGCPolicy()
	p.RequireNoFollowOnLinks(false)
	p.AllowAttrs("alt").OnElements("img")
	return template.HTML(p.SanitizeBytes(html))
}

func sanitizeHTML(html []byte) template.HTML {
	return template.HTML(bluemonday.UGCPolicy().SanitizeBytes(html))
}
<commit_msg>Add footnotes extension<commit_after>package main

import (
	"html/template"

	"github.com/microcosm-cc/bluemonday"
	"github.com/russross/blackfriday"
)

func mdToHTML(md string) []byte {
	htmlFlags := 0
	htmlFlags |= blackfriday.HTML_USE_XHTML
	htmlFlags |= blackfriday.HTML_USE_SMARTYPANTS
	htmlFlags |= blackfriday.HTML_SMARTYPANTS_FRACTIONS
	htmlFlags |= blackfriday.HTML_SMARTYPANTS_LATEX_DASHES
	renderer := blackfriday.HtmlRenderer(htmlFlags, "", "")
	extensions := 0
	extensions |= blackfriday.EXTENSION_NO_INTRA_EMPHASIS
	extensions |= blackfriday.EXTENSION_TABLES
	extensions |= blackfriday.EXTENSION_FENCED_CODE
	extensions |= blackfriday.EXTENSION_AUTOLINK
	extensions |= blackfriday.EXTENSION_STRIKETHROUGH
	extensions |= blackfriday.EXTENSION_SPACE_HEADERS
	extensions |= blackfriday.EXTENSION_HEADER_IDS
	extensions |= blackfriday.EXTENSION_FOOTNOTES
	return blackfriday.Markdown([]byte(md), renderer, extensions)
}

func sanitizeTrustedHTML(html []byte) template.HTML {
	p := bluemonday.UGCPolicy()
	p.RequireNoFollowOnLinks(false)
	p.AllowAttrs("alt").OnElements("img")
	return template.HTML(p.SanitizeBytes(html))
}

func sanitizeHTML(html []byte) template.HTML {
	return template.HTML(bluemonday.UGCPolicy().SanitizeBytes(html))
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"flag"
	"io/ioutil"

	log "github.com/Sirupsen/logrus"

	"github.com/GinjaNinja32/disgoirc/bot"
)

func main() {
	debug := flag.Bool("debug", false, "Debug mode")
	confLocation := flag.String("config", "conf.json", "Config file location")
	flag.Parse()

	if *debug {
		log.SetLevel(log.DebugLevel)
	} else {
		log.SetLevel(log.InfoLevel)
	}

	var conf bot.Config
	confJson, err := ioutil.ReadFile(*confLocation)
	if err != nil {
		log.Fatalf("Failed to read config file %s: %s", confLocation, err)
	}

	err = json.Unmarshal(confJson, &conf)
	if err != nil {
		log.Fatalf("Failed to parse config file: %s", err)
	}

	bot.Init(conf)

	log.Infof("Bot running.")
	<-make(chan struct{})
	return
}
<commit_msg>Change import path to match GitHub URL<commit_after>package main

import (
	"encoding/json"
	"flag"
	"io/ioutil"

	log "github.com/Sirupsen/logrus"

	"github.com/GinjaNinja32/DisGoIRC/bot"
)

func main() {
	debug := flag.Bool("debug", false, "Debug mode")
	confLocation := flag.String("config", "conf.json", "Config file location")
	flag.Parse()

	if *debug {
		log.SetLevel(log.DebugLevel)
	} else {
		log.SetLevel(log.InfoLevel)
	}

	var conf bot.Config
	confJson, err := ioutil.ReadFile(*confLocation)
	if err != nil {
		log.Fatalf("Failed to read config file %s: %s", confLocation, err)
	}

	err = json.Unmarshal(confJson, &conf)
	if err != nil {
		log.Fatalf("Failed to parse config file: %s", err)
	}

	bot.Init(conf)

	log.Infof("Bot running.")
	<-make(chan struct{})
	return
}
<|endoftext|>


<commit_before>// (c) 2012 Alexander Solovyov
// under terms of ISC license

package gostatic

import (
	"fmt"
	"io/ioutil"
	"os"
	"path/filepath"
	"regexp"
	"strings"
	"time"
)

// Command is a command belonging to a Rule. For example, `markdown', `directorify'.
type Command string

// CommandList is a slice of Commands.
type CommandList []Command

// Rule is a collection of a slice of dependencies, with a slice of commands in the
// form of a CommandList.
type Rule struct {
	Deps     []string
	Commands CommandList
}

type RuleMap map[string]([]*Rule)

// SiteConfig contains the data for a complete parsed site configuration file.
type SiteConfig struct {
	Templates []string
	Base      string
	Source    string
	Output    string
	Rules     RuleMap
	Other     map[string]string
	changedAt time.Time
}

// NewSiteConfig parses the given `path' file to a *SiteConfig. Will return a nil
// pointer plus the non-nil error if the parsing has failed.
func NewSiteConfig(path string) (*SiteConfig, error) {
	source, err := ioutil.ReadFile(path)
	if err != nil {
		return nil, err
	}

	stat, err := os.Stat(path)
	if err != nil {
		return nil, err
	}

	basepath, _ := filepath.Split(path)
	cfg := &SiteConfig{
		Rules:     make(RuleMap),
		Other:     make(map[string]string),
		Base:      basepath,
		changedAt: stat.ModTime(),
	}

	indent := 0
	level := 0
	prefix := regexp.MustCompile("^[ \t]*")
	comment := regexp.MustCompile(`(^|[^\\])#`)

	var current *Rule

	for i, line := range strings.Split(string(source), "\n") {
		// check indent
		indnew := len(prefix.FindString(line))
		switch {
		case indnew > indent:
			level++
		case indnew < indent:
			level--
		}
		indent = indnew

		// remove useless stuff from line
		line = line[indent:]
		commentloc := comment.FindIndex([]byte(line))
		if commentloc != nil {
			line = line[:commentloc[0]]
		}
		line = strings.Replace(line, "\\#", "#", -1)
		line = strings.TrimSpace(line)

		if len(line) == 0 {
			continue
		}

		// is this a constant declaration?
		if level == 0 && strings.Index(line, "=") != -1 {
			cfg.ParseVariable(basepath, line)
			continue
		}

		// not a constant, then a Rule start?
		if level == 0 {
			current = cfg.ParseRule(line)
			continue
		}

		if level == 1 {
			if current == nil {
				return nil, fmt.Errorf("indent without rules, line %d", i+1)
			}
			current.ParseCommand(cfg, line)
			continue
		}

		return nil, fmt.Errorf("unhandled situation on line %d: %s",
			i+1, line)
	}

	return cfg, nil
}

// *** Parsing methods

var VarRe = regexp.MustCompile(`\$\(([^\)]+)\)`)

func (cfg *SiteConfig) SubVars(s string) string {
	return VarRe.ReplaceAllStringFunc(s, func(m string) string {
		name := VarRe.FindStringSubmatch(m)[1]
		switch name {
		case "TEMPLATES":
			return strings.Join(cfg.Templates, ", ")
		case "SOURCE":
			return cfg.Source
		case "OUTPUT":
			return cfg.Output
		default:
			return cfg.Other[Capitalize(name)]
		}
	})
}

func (cfg *SiteConfig) ParseVariable(base string, line string) {
	bits := TrimSplitN(line, "=", 2)
	name := bits[0]
	value := cfg.SubVars(bits[1])

	switch name {
	case "TEMPLATES":
		templates := strings.Split(value, " ")
		for _, template := range templates {
			path := filepath.Join(base, template)
			isDir, err := IsDir(path)

			if err != nil {
				errexit(fmt.Errorf("template does not exist: %s", err))
			}

			if isDir {
				files, _ := filepath.Glob(filepath.Join(path, "*.tmpl"))
				for _, fn := range files {
					cfg.Templates = append(cfg.Templates, fn)
				}
			} else {
				cfg.Templates = append(cfg.Templates, path)
			}
		}
	case "SOURCE":
		cfg.Source = filepath.Join(base, value)
	case "OUTPUT":
		cfg.Output = filepath.Join(base, value)
	default:
		cfg.Other[Capitalize(name)] = value
	}
}

func (cfg *SiteConfig) ParseRule(line string) *Rule {
	bits := TrimSplitN(line, ":", 2)
	if len(bits) != 2 {
		errexit(fmt.Errorf("Cannot parse rule, ':' not found in '%s'", line))
	}
	deps := NonEmptySplit(cfg.SubVars(bits[1]), " ")
	rule := &Rule{
		Deps:     deps,
		Commands: make(CommandList, 0),
	}

	if _, ok := cfg.Rules[bits[0]]; !ok {
		cfg.Rules[bits[0]] = make([]*Rule, 0)
	}
	cfg.Rules[bits[0]] = append(cfg.Rules[bits[0]], rule)

	return rule
}

func (rule *Rule) ParseCommand(cfg *SiteConfig, line string) {
	line = cfg.SubVars(line)
	rule.Commands = append(rule.Commands, Command(line))
}

// *** Traversing methods

func (cmd Command) Matches(prefix Command) bool {
	return cmd == prefix || strings.HasPrefix(string(cmd), string(prefix)+" ")
}

func (rule *Rule) IsDep(page *Page) bool {
	for _, dep := range rule.Deps {
		matches, err := filepath.Match(dep, page.Source)
		if err == nil && matches {
			return true
		}
	}
	return false
}

func (rules RuleMap) MatchedRules(path string) (string, []*Rule) {
	if rules[path] != nil {
		return path, rules[path]
	}

	_, name := filepath.Split(path)
	if rules[name] != nil {
		return name, rules[name]
	}

	for pat, subset := range rules {
		matched, err := filepath.Match(pat, path)
		errhandle(err)
		if matched {
			return pat, subset
		}
	}

	for pat, subset := range rules {
		matched, err := filepath.Match(pat, name)
		errhandle(err)
		if matched {
			return pat, subset
		}
	}

	return "", nil
}
<commit_msg>Added doublestar support to config file.<commit_after>// (c) 2012 Alexander Solovyov
// under terms of ISC license

package gostatic

import (
	"fmt"
	"io/ioutil"
	"os"
	"path/filepath"
	"regexp"
	"strings"
	"time"
	"github.com/bmatcuk/doublestar/v2"
)

// Command is a command belonging to a Rule. For example, `markdown', `directorify'.
type Command string

// CommandList is a slice of Commands.
type CommandList []Command

// Rule is a collection of a slice of dependencies, with a slice of commands in the
// form of a CommandList.
type Rule struct {
	Deps     []string
	Commands CommandList
}

type RuleMap map[string]([]*Rule)

// SiteConfig contains the data for a complete parsed site configuration file.
type SiteConfig struct {
	Templates []string
	Base      string
	Source    string
	Output    string
	Rules     RuleMap
	Other     map[string]string
	changedAt time.Time
}

// NewSiteConfig parses the given `path' file to a *SiteConfig. Will return a nil
// pointer plus the non-nil error if the parsing has failed.
func NewSiteConfig(path string) (*SiteConfig, error) {
	source, err := ioutil.ReadFile(path)
	if err != nil {
		return nil, err
	}

	stat, err := os.Stat(path)
	if err != nil {
		return nil, err
	}

	basepath, _ := filepath.Split(path)
	cfg := &SiteConfig{
		Rules:     make(RuleMap),
		Other:     make(map[string]string),
		Base:      basepath,
		changedAt: stat.ModTime(),
	}

	indent := 0
	level := 0
	prefix := regexp.MustCompile("^[ \t]*")
	comment := regexp.MustCompile(`(^|[^\\])#`)

	var current *Rule

	for i, line := range strings.Split(string(source), "\n") {
		// check indent
		indnew := len(prefix.FindString(line))
		switch {
		case indnew > indent:
			level++
		case indnew < indent:
			level--
		}
		indent = indnew

		// remove useless stuff from line
		line = line[indent:]
		commentloc := comment.FindIndex([]byte(line))
		if commentloc != nil {
			line = line[:commentloc[0]]
		}
		line = strings.Replace(line, "\\#", "#", -1)
		line = strings.TrimSpace(line)

		if len(line) == 0 {
			continue
		}

		// is this a constant declaration?
		if level == 0 && strings.Index(line, "=") != -1 {
			cfg.ParseVariable(basepath, line)
			continue
		}

		// not a constant, then a Rule start?
		if level == 0 {
			current = cfg.ParseRule(line)
			continue
		}

		if level == 1 {
			if current == nil {
				return nil, fmt.Errorf("indent without rules, line %d", i+1)
			}
			current.ParseCommand(cfg, line)
			continue
		}

		return nil, fmt.Errorf("unhandled situation on line %d: %s",
			i+1, line)
	}

	return cfg, nil
}

// *** Parsing methods

var VarRe = regexp.MustCompile(`\$\(([^\)]+)\)`)

func (cfg *SiteConfig) SubVars(s string) string {
	return VarRe.ReplaceAllStringFunc(s, func(m string) string {
		name := VarRe.FindStringSubmatch(m)[1]
		switch name {
		case "TEMPLATES":
			return strings.Join(cfg.Templates, ", ")
		case "SOURCE":
			return cfg.Source
		case "OUTPUT":
			return cfg.Output
		default:
			return cfg.Other[Capitalize(name)]
		}
	})
}

func (cfg *SiteConfig) ParseVariable(base string, line string) {
	bits := TrimSplitN(line, "=", 2)
	name := bits[0]
	value := cfg.SubVars(bits[1])

	switch name {
	case "TEMPLATES":
		templates := strings.Split(value, " ")
		for _, template := range templates {
			path := filepath.Join(base, template)
			isDir, err := IsDir(path)

			if err != nil {
				errexit(fmt.Errorf("template does not exist: %s", err))
			}

			if isDir {
				files, _ := filepath.Glob(filepath.Join(path, "*.tmpl"))
				for _, fn := range files {
					cfg.Templates = append(cfg.Templates, fn)
				}
			} else {
				cfg.Templates = append(cfg.Templates, path)
			}
		}
	case "SOURCE":
		cfg.Source = filepath.Join(base, value)
	case "OUTPUT":
		cfg.Output = filepath.Join(base, value)
	default:
		cfg.Other[Capitalize(name)] = value
	}
}

func (cfg *SiteConfig) ParseRule(line string) *Rule {
	bits := TrimSplitN(line, ":", 2)
	if len(bits) != 2 {
		errexit(fmt.Errorf("Cannot parse rule, ':' not found in '%s'", line))
	}
	deps := NonEmptySplit(cfg.SubVars(bits[1]), " ")
	rule := &Rule{
		Deps:     deps,
		Commands: make(CommandList, 0),
	}

	if _, ok := cfg.Rules[bits[0]]; !ok {
		cfg.Rules[bits[0]] = make([]*Rule, 0)
	}
	cfg.Rules[bits[0]] = append(cfg.Rules[bits[0]], rule)

	return rule
}

func (rule *Rule) ParseCommand(cfg *SiteConfig, line string) {
	line = cfg.SubVars(line)
	rule.Commands = append(rule.Commands, Command(line))
}

// *** Traversing methods

func (cmd Command) Matches(prefix Command) bool {
	return cmd == prefix || strings.HasPrefix(string(cmd), string(prefix)+" ")
}

func (rule *Rule) IsDep(page *Page) bool {
	for _, dep := range rule.Deps {
		matches, err := doublestar.Match(dep, page.Source)
		if err == nil && matches {
			return true
		}
	}
	return false
}

func (rules RuleMap) MatchedRules(path string) (string, []*Rule) {
	if rules[path] != nil {
		return path, rules[path]
	}

	_, name := filepath.Split(path)
	if rules[name] != nil {
		return name, rules[name]
	}

	for pat, subset := range rules {
		matched, err := doublestar.Match(pat, path)
		errhandle(err)
		if matched {
			return pat, subset
		}
	}

	for pat, subset := range rules {
		matched, err := doublestar.Match(pat, name)
		errhandle(err)
		if matched {
			return pat, subset
		}
	}

	return "", nil
}
<|endoftext|>


<commit_before>package main

import (
	"github.com/BurntSushi/xgb"
	"github.com/BurntSushi/xgb/xproto"
	"log"
	"time"
)

func atom(X *xgb.Conn, aname string) *xproto.InternAtomReply {
	a, err := xproto.InternAtom(X, true, uint16(len(aname)), aname).Reply()
	if err != nil {
		log.Fatal(err)
	}
	return a
}

func prop(X *xgb.Conn, w xproto.Window, a *xproto.InternAtomReply) *xproto.GetPropertyReply {
	p, err := xproto.GetProperty(X, false, w, a.Atom, xproto.GetPropertyTypeAny, 0, (1<<32)-1).Reply()
	if err != nil {
		log.Fatal(err)
	}
	return p
}

func winName(X *xgb.Conn) string {
	setup := xproto.Setup(X)
	root := setup.DefaultScreen(X).Root

	activeAtom := atom(X, "_NET_ACTIVE_WINDOW")
	nameAtom := atom(X, "WM_NAME")

	reply := prop(X, root, activeAtom)
	windowId := xproto.Window(xgb.Get32(reply.Value))

	reply = prop(X, windowId, nameAtom)

	return string(reply.Value)
}

func main() {
	X, err := xgb.NewConn()
	if err != nil {
		log.Fatal(err)
	}
	defer X.Close()

	for {
		//X.WaitForEvent()
		log.Println(winName(X))
		time.Sleep(time.Second)

	}
}
<commit_msg>stub, just logging<commit_after>package main

import (
	"bytes"
	"fmt"
	"github.com/BurntSushi/xgb"
	"github.com/BurntSushi/xgb/xproto"
	"log"
)

type window struct {
	Class []string
	Name  string
}

func asciizToString(b []byte) (s []string) {
	for _, x := range bytes.Split(b, []byte{0}) {
		s = append(s, string(x))
	}
	if len(s) > 0 && s[len(s)-1] == "" {
		s = s[:len(s)-1]
	}
	return
}

func atom(X *xgb.Conn, aname string) *xproto.InternAtomReply {
	a, err := xproto.InternAtom(X, true, uint16(len(aname)), aname).Reply()
	if err != nil {
		log.Fatal(err)
	}
	return a
}

func prop(X *xgb.Conn, w xproto.Window, a *xproto.InternAtomReply) *xproto.GetPropertyReply {
	p, err := xproto.GetProperty(X, false, w, a.Atom, xproto.GetPropertyTypeAny, 0, (1<<32)-1).Reply()
	if err != nil {
		log.Fatal(err)
	}
	return p
}

func (w window) String() string {
	return fmt.Sprintf("%s (%s) %s", w.Class[0], w.Class[1], w.Name)
}

func winName(X *xgb.Conn, root xproto.Window) (window, bool) {
	activeAtom := atom(X, "_NET_ACTIVE_WINDOW")
	nameAtom := atom(X, "WM_NAME")
	classAtom := atom(X, "WM_CLASS")

	active := prop(X, root, activeAtom)
	windowId := xproto.Window(xgb.Get32(active.Value))

	/* skip root window */
	if windowId == 0 {
		return window{}, false
	}

	spy(X, windowId)

	name := prop(X, windowId, nameAtom)
	class := prop(X, windowId, classAtom)

	w := window{
		Class: asciizToString(class.Value),
		Name:  string(name.Value),
	}

	return w, true
}

func rootWin(X *xgb.Conn) xproto.Window {
	setup := xproto.Setup(X)
	return setup.DefaultScreen(X).Root
}

func spy(X *xgb.Conn, w xproto.Window) {
	xproto.ChangeWindowAttributes(X, w, xproto.CwEventMask,
		[]uint32{xproto.EventMaskPropertyChange})
}

func main() {
	X, err := xgb.NewConn()
	if err != nil {
		log.Fatal(err)
	}
	defer X.Close()

	root := rootWin(X)
	spy(X, root)

	for {
		if _, everr := X.WaitForEvent(); everr != nil {
			log.Fatal(err)
		}
		if name, ok := winName(X, root); ok {
			log.Println(name)
		}
	}
}
<|endoftext|>


<commit_before>package ydls

import (
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"sort"
	"sync"

	"github.com/wader/ydls/ffmpeg"
	"github.com/wader/ydls/youtubedl"
)

func writeID3v2FromYoutueDLInfo(w io.Writer, i *youtubedl.Info) {
	id3v2Frames := []id3v2Frame{
		&textFrame{"TPE1", firstNonEmpty(i.Artist, i.Creator, i.Uploader)},
		&textFrame{"TIT2", i.Title},
		&commFrame{"XXX", "", i.Description},
	}
	if i.Duration > 0 {
		id3v2Frames = append(id3v2Frames, &textFrame{"TLEN", fmt.Sprintf("%d", uint32(i.Duration*1000))})
	}
	if len(i.Thumbnail) > 0 {
		id3v2Frames = append(id3v2Frames, &apicFrame{
			http.DetectContentType(i.Thumbnail),
			id3v2PictureTypeOther,
			"",
			i.Thumbnail,
		})
	}

	id3v2WriteHeader(w, id3v2Frames)
}

func findFormat(formats []*youtubedl.Format, protocol string, aCodecs *prioStringSet, vCodecs *prioStringSet) *youtubedl.Format {
	var matched []*youtubedl.Format

	for _, f := range formats {
		if protocol != "*" && f.Protocol != protocol {
			continue
		}
		if !(aCodecs == nil || (f.NormACodec == "" && aCodecs.empty()) || aCodecs.member(f.NormACodec)) {
			continue
		}
		if !(vCodecs == nil || (f.NormVCodec == "" && vCodecs.empty()) || vCodecs.member(f.NormVCodec)) {
			continue
		}

		matched = append(matched, f)
	}

	sort.Sort(youtubedl.FormatByNormBR(matched))

	if len(matched) > 0 {
		return matched[0]
	}

	return nil
}

func findBestFormats(ydlFormats []*youtubedl.Format, format *Format) (aFormat *youtubedl.Format, vFormat *youtubedl.Format) {
	type neededFormat struct {
		aCodecs    *prioStringSet
		vCodecs    *prioStringSet
		aYDLFormat **youtubedl.Format
		vYDLFormat **youtubedl.Format
	}

	var neededFormats []*neededFormat

	// match exactly, both audio/video codecs found or not found
	neededFormats = append(neededFormats, &neededFormat{&format.ACodecs, &format.VCodecs, &aFormat, &vFormat})

	if !format.ACodecs.empty() {
		// matching audio codec with any video codec
		neededFormats = append(neededFormats, &neededFormat{&format.ACodecs, nil, &aFormat, nil})
		// match any audio codec and no video
		neededFormats = append(neededFormats, &neededFormat{nil, &prioStringSet{}, &aFormat, nil})
		// match any audio and video codec
		neededFormats = append(neededFormats, &neededFormat{nil, nil, &aFormat, nil})
	}
	if !format.VCodecs.empty() {
		// same logic as above
		neededFormats = append(neededFormats, &neededFormat{nil, &format.VCodecs, nil, &vFormat})
		neededFormats = append(neededFormats, &neededFormat{&prioStringSet{}, nil, nil, &vFormat})
		neededFormats = append(neededFormats, &neededFormat{nil, nil, nil, &vFormat})
	}

	// TODO: if only audio... choose stream with lowest video br?
	// TODO: rtmp only if mp4 etc?

	// prefer rtmp as it seems to send fragmented mp4 etc
	for _, proto := range []string{"rtmp", "*"} {
		for _, f := range neededFormats {
			m := findFormat(ydlFormats, proto, f.aCodecs, f.vCodecs)

			if m == nil {
				continue
			}

			if f.aYDLFormat != nil && *f.aYDLFormat == nil && m.NormACodec != "" {
				*f.aYDLFormat = m
			}
			if f.vYDLFormat != nil && *f.vYDLFormat == nil && m.NormVCodec != "" {
				*f.vYDLFormat = m
			}

			if (format.ACodecs.empty() || aFormat != nil) &&
				(format.VCodecs.empty() || vFormat != nil) {
				break
			}
		}
	}

	return aFormat, vFormat
}

func downloadAndProbeFormat(ydl *youtubedl.Info, filter string, debugLog *log.Logger) (r io.ReadCloser, pi *ffmpeg.ProbeInfo, err error) {
	var ydlStderr io.Writer
	if debugLog != nil {
		ydlStderr = &loggerWriter{Logger: debugLog, Prefix: "ydl 2> "}
	}
	r, err = ydl.Download(filter, ydlStderr)
	if err != nil {
		return nil, nil, err
	}

	rr := &reReadCloser{ReadCloser: r}

	var ffprobeStderr io.Writer
	if debugLog != nil {
		ffprobeStderr = &loggerWriter{Logger: debugLog, Prefix: fmt.Sprintf("ffprobe %s 2> ", filter)}
	}
	const maxProbeByteSize = 10 * 1024 * 1024
	pi, err = ffmpeg.FFprobe(io.LimitReader(rr, maxProbeByteSize), debugLog, ffprobeStderr)
	if err != nil {
		return nil, nil, err
	}
	// restart and replay buffer data used when probing
	rr.Restarted = true

	return rr, pi, nil
}

// YDLs youtubedl downloader with some extras
type YDLs struct {
	Formats Formats
}

// NewFromFile new YDLs using formats file
func NewFromFile(formatsPath string) (*YDLs, error) {
	formatsFile, err := os.Open(formatsPath)
	if err != nil {
		return nil, err
	}
	defer formatsFile.Close()
	formats, err := parseFormats(formatsFile)
	if err != nil {
		return nil, err
	}

	return &YDLs{Formats: formats}, nil
}

// Download downloads media from URL and makes sure output is in specified format
func (ydls *YDLs) Download(url string, formatName string, debugLog *log.Logger) (r io.ReadCloser, filename string, mimeType string, err error) {
	log := log.New(ioutil.Discard, "", 0)
	if debugLog != nil {
		log = debugLog
	}

	log.Printf("URL: %s", url)

	var ydlStdout io.Writer
	if debugLog != nil {
		ydlStdout = &loggerWriter{Logger: debugLog, Prefix: "ydl 1> "}
	}
	ydl, err := youtubedl.NewFromURL(url, ydlStdout)
	if err != nil {
		log.Printf("Failed to download: %s", err)
		return nil, "", "", fmt.Errorf("failed to download")
	}

	log.Printf("Title: %s", ydl.Title)
	log.Printf("Available youtubedl formats:")
	for _, f := range ydl.Formats {
		log.Printf("  %s", f)
	}

	var outFormat *Format

	if formatName == "" {
		var probedInfo *ffmpeg.ProbeInfo
		r, probedInfo, err = downloadAndProbeFormat(ydl, "best[protocol=rtmp]/best", debugLog)
		if err != nil {
			return nil, "", "", err
		}

		log.Printf("Probed format %s", probedInfo)

		// see if we know about the probed format, otherwise fallback to "raw"
		outFormat = ydls.Formats.Find(probedInfo.FormatName(), probedInfo.ACodec(), probedInfo.VCodec())
	} else {
		outFormat = ydls.Formats.FindByName(formatName)
		if outFormat == nil {
			return nil, "", "", fmt.Errorf("could not find format")
		}

		aYDLFormat, vYDLFormat := findBestFormats(ydl.Formats, outFormat)

		log.Printf("Best youtubedl match for %s a=%s v=%s", formatName, aYDLFormat, vYDLFormat)

		var aProbedFormat *ffmpeg.ProbeInfo
		var aReader io.ReadCloser
		var vProbedFormat *ffmpeg.ProbeInfo
		var vReader io.ReadCloser

		// FIXME: messy

		if aYDLFormat != nil && vYDLFormat != nil {
			if aYDLFormat != vYDLFormat {
				var probeWG sync.WaitGroup
				probeWG.Add(1)
				go func() {
					defer probeWG.Done()
					aReader, aProbedFormat, err = downloadAndProbeFormat(ydl, aYDLFormat.FormatID, debugLog)
				}()
				probeWG.Add(1)
				go func() {
					defer probeWG.Done()
					vReader, vProbedFormat, err = downloadAndProbeFormat(ydl, vYDLFormat.FormatID, debugLog)
				}()
				probeWG.Wait()
			} else {
				aReader, aProbedFormat, err = downloadAndProbeFormat(ydl, aYDLFormat.FormatID, debugLog)
				vReader, vProbedFormat = aReader, aProbedFormat
			}
		} else if aYDLFormat != nil && vYDLFormat == nil {
			aReader, aProbedFormat, err = downloadAndProbeFormat(ydl, aYDLFormat.FormatID, debugLog)
		} else {
			aReader, aProbedFormat, err = downloadAndProbeFormat(ydl, "best", debugLog)
			vReader, vProbedFormat = aReader, aProbedFormat
		}

		if err != nil {
			return nil, "", "", fmt.Errorf("failed to probe")
		}

		log.Printf("Stream mapping:")
		var maps []ffmpeg.Map
		if len(outFormat.ACodecs) > 0 && aProbedFormat != nil && aProbedFormat.ACodec() != "" {
			canCopy := outFormat.ACodecs.member(aProbedFormat.ACodec())
			ffmpegCodec := boolString(canCopy, "copy", outFormat.ACodecs.first())
			ydlACodec := "n/a"
			if aYDLFormat != nil {
				ydlACodec = aYDLFormat.NormACodec
			}

			maps = append(maps, ffmpeg.Map{
				Input:           aReader,
				Kind:            "audio",
				StreamSpecifier: "a:0",
				Codec:           ffmpegCodec,
				Flags:           outFormat.ACodecFlags,
			})
			log.Printf("  audio probed:%s ydl:%s -> %s", aProbedFormat.ACodec(), ydlACodec, ffmpegCodec)
		}
		if len(outFormat.VCodecs) > 0 && vProbedFormat != nil && vProbedFormat.VCodec() != "" {
			canCopy := outFormat.VCodecs.member(vProbedFormat.VCodec())
			ffmpegCodec := boolString(canCopy, "copy", outFormat.VCodecs.first())
			ydlVCodec := "n/a"
			if aYDLFormat != nil {
				ydlVCodec = vYDLFormat.NormVCodec
			}

			maps = append(maps, ffmpeg.Map{
				Input:           vReader,
				Kind:            "video",
				StreamSpecifier: "v:0",
				Codec:           ffmpegCodec,
				Flags:           outFormat.VCodecFlags,
			})
			log.Printf("  video probed:%s ydl:%s -> %s", vProbedFormat.VCodec(), ydlVCodec, ffmpegCodec)
		}
		var ffmpegStderr io.Writer
		if debugLog != nil {
			ffmpegStderr = &loggerWriter{Logger: debugLog, Prefix: "ffmpeg 2> "}
		}

		o, err := ffmpeg.FFmpeg(&ffmpeg.Args{
			Maps:     maps,
			Format:   ffmpeg.Format{Name: outFormat.Formats.first(), Flags: outFormat.FormatFlags},
			DebugLog: debugLog,
			Stderr:   ffmpegStderr,
		})
		if err != nil {
			return nil, "", "", err
		}

		var w io.WriteCloser
		r, w = io.Pipe()
		go func() {
			defer o.Close()
			if aReader != nil {
				defer aReader.Close()
			}
			if vReader != nil {
				defer vReader.Close()
			}
			defer w.Close()

			if outFormat.Prepend == "id3v2" {
				writeID3v2FromYoutueDLInfo(w, ydl)
			}
			io.Copy(w, o)
		}()
	}

	if outFormat == nil {
		mimeType = "application/octet-stream"
		filename = ydl.Title + ".raw"
	} else {
		mimeType = outFormat.MIMEType
		filename = ydl.Title + "." + outFormat.Ext
	}

	return r, filename, mimeType, nil
}
<commit_msg>Fix typo in ydl video format debug<commit_after>package ydls

import (
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"sort"
	"sync"

	"github.com/wader/ydls/ffmpeg"
	"github.com/wader/ydls/youtubedl"
)

func writeID3v2FromYoutueDLInfo(w io.Writer, i *youtubedl.Info) {
	id3v2Frames := []id3v2Frame{
		&textFrame{"TPE1", firstNonEmpty(i.Artist, i.Creator, i.Uploader)},
		&textFrame{"TIT2", i.Title},
		&commFrame{"XXX", "", i.Description},
	}
	if i.Duration > 0 {
		id3v2Frames = append(id3v2Frames, &textFrame{"TLEN", fmt.Sprintf("%d", uint32(i.Duration*1000))})
	}
	if len(i.Thumbnail) > 0 {
		id3v2Frames = append(id3v2Frames, &apicFrame{
			http.DetectContentType(i.Thumbnail),
			id3v2PictureTypeOther,
			"",
			i.Thumbnail,
		})
	}

	id3v2WriteHeader(w, id3v2Frames)
}

func findFormat(formats []*youtubedl.Format, protocol string, aCodecs *prioStringSet, vCodecs *prioStringSet) *youtubedl.Format {
	var matched []*youtubedl.Format

	for _, f := range formats {
		if protocol != "*" && f.Protocol != protocol {
			continue
		}
		if !(aCodecs == nil || (f.NormACodec == "" && aCodecs.empty()) || aCodecs.member(f.NormACodec)) {
			continue
		}
		if !(vCodecs == nil || (f.NormVCodec == "" && vCodecs.empty()) || vCodecs.member(f.NormVCodec)) {
			continue
		}

		matched = append(matched, f)
	}

	sort.Sort(youtubedl.FormatByNormBR(matched))

	if len(matched) > 0 {
		return matched[0]
	}

	return nil
}

func findBestFormats(ydlFormats []*youtubedl.Format, format *Format) (aFormat *youtubedl.Format, vFormat *youtubedl.Format) {
	type neededFormat struct {
		aCodecs    *prioStringSet
		vCodecs    *prioStringSet
		aYDLFormat **youtubedl.Format
		vYDLFormat **youtubedl.Format
	}

	var neededFormats []*neededFormat

	// match exactly, both audio/video codecs found or not found
	neededFormats = append(neededFormats, &neededFormat{&format.ACodecs, &format.VCodecs, &aFormat, &vFormat})

	if !format.ACodecs.empty() {
		// matching audio codec with any video codec
		neededFormats = append(neededFormats, &neededFormat{&format.ACodecs, nil, &aFormat, nil})
		// match any audio codec and no video
		neededFormats = append(neededFormats, &neededFormat{nil, &prioStringSet{}, &aFormat, nil})
		// match any audio and video codec
		neededFormats = append(neededFormats, &neededFormat{nil, nil, &aFormat, nil})
	}
	if !format.VCodecs.empty() {
		// same logic as above
		neededFormats = append(neededFormats, &neededFormat{nil, &format.VCodecs, nil, &vFormat})
		neededFormats = append(neededFormats, &neededFormat{&prioStringSet{}, nil, nil, &vFormat})
		neededFormats = append(neededFormats, &neededFormat{nil, nil, nil, &vFormat})
	}

	// TODO: if only audio... choose stream with lowest video br?
	// TODO: rtmp only if mp4 etc?

	// prefer rtmp as it seems to send fragmented mp4 etc
	for _, proto := range []string{"rtmp", "*"} {
		for _, f := range neededFormats {
			m := findFormat(ydlFormats, proto, f.aCodecs, f.vCodecs)

			if m == nil {
				continue
			}

			if f.aYDLFormat != nil && *f.aYDLFormat == nil && m.NormACodec != "" {
				*f.aYDLFormat = m
			}
			if f.vYDLFormat != nil && *f.vYDLFormat == nil && m.NormVCodec != "" {
				*f.vYDLFormat = m
			}

			if (format.ACodecs.empty() || aFormat != nil) &&
				(format.VCodecs.empty() || vFormat != nil) {
				break
			}
		}
	}

	return aFormat, vFormat
}

func downloadAndProbeFormat(ydl *youtubedl.Info, filter string, debugLog *log.Logger) (r io.ReadCloser, pi *ffmpeg.ProbeInfo, err error) {
	var ydlStderr io.Writer
	if debugLog != nil {
		ydlStderr = &loggerWriter{Logger: debugLog, Prefix: "ydl 2> "}
	}
	r, err = ydl.Download(filter, ydlStderr)
	if err != nil {
		return nil, nil, err
	}

	rr := &reReadCloser{ReadCloser: r}

	var ffprobeStderr io.Writer
	if debugLog != nil {
		ffprobeStderr = &loggerWriter{Logger: debugLog, Prefix: fmt.Sprintf("ffprobe %s 2> ", filter)}
	}
	const maxProbeByteSize = 10 * 1024 * 1024
	pi, err = ffmpeg.FFprobe(io.LimitReader(rr, maxProbeByteSize), debugLog, ffprobeStderr)
	if err != nil {
		return nil, nil, err
	}
	// restart and replay buffer data used when probing
	rr.Restarted = true

	return rr, pi, nil
}

// YDLs youtubedl downloader with some extras
type YDLs struct {
	Formats Formats
}

// NewFromFile new YDLs using formats file
func NewFromFile(formatsPath string) (*YDLs, error) {
	formatsFile, err := os.Open(formatsPath)
	if err != nil {
		return nil, err
	}
	defer formatsFile.Close()
	formats, err := parseFormats(formatsFile)
	if err != nil {
		return nil, err
	}

	return &YDLs{Formats: formats}, nil
}

// Download downloads media from URL and makes sure output is in specified format
func (ydls *YDLs) Download(url string, formatName string, debugLog *log.Logger) (r io.ReadCloser, filename string, mimeType string, err error) {
	log := log.New(ioutil.Discard, "", 0)
	if debugLog != nil {
		log = debugLog
	}

	log.Printf("URL: %s", url)

	var ydlStdout io.Writer
	if debugLog != nil {
		ydlStdout = &loggerWriter{Logger: debugLog, Prefix: "ydl 1> "}
	}
	ydl, err := youtubedl.NewFromURL(url, ydlStdout)
	if err != nil {
		log.Printf("Failed to download: %s", err)
		return nil, "", "", fmt.Errorf("failed to download")
	}

	log.Printf("Title: %s", ydl.Title)
	log.Printf("Available youtubedl formats:")
	for _, f := range ydl.Formats {
		log.Printf("  %s", f)
	}

	var outFormat *Format

	if formatName == "" {
		var probedInfo *ffmpeg.ProbeInfo
		r, probedInfo, err = downloadAndProbeFormat(ydl, "best[protocol=rtmp]/best", debugLog)
		if err != nil {
			return nil, "", "", err
		}

		log.Printf("Probed format %s", probedInfo)

		// see if we know about the probed format, otherwise fallback to "raw"
		outFormat = ydls.Formats.Find(probedInfo.FormatName(), probedInfo.ACodec(), probedInfo.VCodec())
	} else {
		outFormat = ydls.Formats.FindByName(formatName)
		if outFormat == nil {
			return nil, "", "", fmt.Errorf("could not find format")
		}

		aYDLFormat, vYDLFormat := findBestFormats(ydl.Formats, outFormat)

		log.Printf("Best youtubedl match for %s a=%s v=%s", formatName, aYDLFormat, vYDLFormat)

		var aProbedFormat *ffmpeg.ProbeInfo
		var aReader io.ReadCloser
		var vProbedFormat *ffmpeg.ProbeInfo
		var vReader io.ReadCloser

		// FIXME: messy

		if aYDLFormat != nil && vYDLFormat != nil {
			if aYDLFormat != vYDLFormat {
				var probeWG sync.WaitGroup
				probeWG.Add(1)
				go func() {
					defer probeWG.Done()
					aReader, aProbedFormat, err = downloadAndProbeFormat(ydl, aYDLFormat.FormatID, debugLog)
				}()
				probeWG.Add(1)
				go func() {
					defer probeWG.Done()
					vReader, vProbedFormat, err = downloadAndProbeFormat(ydl, vYDLFormat.FormatID, debugLog)
				}()
				probeWG.Wait()
			} else {
				aReader, aProbedFormat, err = downloadAndProbeFormat(ydl, aYDLFormat.FormatID, debugLog)
				vReader, vProbedFormat = aReader, aProbedFormat
			}
		} else if aYDLFormat != nil && vYDLFormat == nil {
			aReader, aProbedFormat, err = downloadAndProbeFormat(ydl, aYDLFormat.FormatID, debugLog)
		} else {
			aReader, aProbedFormat, err = downloadAndProbeFormat(ydl, "best", debugLog)
			vReader, vProbedFormat = aReader, aProbedFormat
		}

		if err != nil {
			return nil, "", "", fmt.Errorf("failed to probe")
		}

		log.Printf("Stream mapping:")
		var maps []ffmpeg.Map
		if len(outFormat.ACodecs) > 0 && aProbedFormat != nil && aProbedFormat.ACodec() != "" {
			canCopy := outFormat.ACodecs.member(aProbedFormat.ACodec())
			ffmpegCodec := boolString(canCopy, "copy", outFormat.ACodecs.first())
			ydlACodec := "n/a"
			if aYDLFormat != nil {
				ydlACodec = aYDLFormat.NormACodec
			}

			maps = append(maps, ffmpeg.Map{
				Input:           aReader,
				Kind:            "audio",
				StreamSpecifier: "a:0",
				Codec:           ffmpegCodec,
				Flags:           outFormat.ACodecFlags,
			})
			log.Printf("  audio probed:%s ydl:%s -> %s", aProbedFormat.ACodec(), ydlACodec, ffmpegCodec)
		}
		if len(outFormat.VCodecs) > 0 && vProbedFormat != nil && vProbedFormat.VCodec() != "" {
			canCopy := outFormat.VCodecs.member(vProbedFormat.VCodec())
			ffmpegCodec := boolString(canCopy, "copy", outFormat.VCodecs.first())
			ydlVCodec := "n/a"
			if vYDLFormat != nil {
				ydlVCodec = vYDLFormat.NormVCodec
			}

			maps = append(maps, ffmpeg.Map{
				Input:           vReader,
				Kind:            "video",
				StreamSpecifier: "v:0",
				Codec:           ffmpegCodec,
				Flags:           outFormat.VCodecFlags,
			})
			log.Printf("  video probed:%s ydl:%s -> %s", vProbedFormat.VCodec(), ydlVCodec, ffmpegCodec)
		}
		var ffmpegStderr io.Writer
		if debugLog != nil {
			ffmpegStderr = &loggerWriter{Logger: debugLog, Prefix: "ffmpeg 2> "}
		}

		o, err := ffmpeg.FFmpeg(&ffmpeg.Args{
			Maps:     maps,
			Format:   ffmpeg.Format{Name: outFormat.Formats.first(), Flags: outFormat.FormatFlags},
			DebugLog: debugLog,
			Stderr:   ffmpegStderr,
		})
		if err != nil {
			return nil, "", "", err
		}

		var w io.WriteCloser
		r, w = io.Pipe()
		go func() {
			defer o.Close()
			if aReader != nil {
				defer aReader.Close()
			}
			if vReader != nil {
				defer vReader.Close()
			}
			defer w.Close()

			if outFormat.Prepend == "id3v2" {
				writeID3v2FromYoutueDLInfo(w, ydl)
			}
			io.Copy(w, o)
		}()
	}

	if outFormat == nil {
		mimeType = "application/octet-stream"
		filename = ydl.Title + ".raw"
	} else {
		mimeType = outFormat.MIMEType
		filename = ydl.Title + "." + outFormat.Ext
	}

	return r, filename, mimeType, nil
}
<|endoftext|>


<commit_before>package azurerm

import (
	"fmt"
	"log"
	"strings"
	"testing"

	"github.com/Azure/azure-sdk-for-go/storage"
	"github.com/hashicorp/terraform/helper/acctest"
	"github.com/hashicorp/terraform/helper/resource"
	"github.com/hashicorp/terraform/terraform"
)

func TestAccAzureRMStorageTable_basic(t *testing.T) {
	var table storage.Table

	ri := acctest.RandInt()
	rs := strings.ToLower(acctest.RandString(11))
	config := fmt.Sprintf(testAccAzureRMStorageTable_basic, ri, rs, ri)

	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testCheckAzureRMStorageTableDestroy,
		Steps: []resource.TestStep{
			{
				Config: config,
				Check: resource.ComposeTestCheckFunc(
					testCheckAzureRMStorageTableExists("azurerm_storage_table.test", &table),
				),
			},
		},
	})
}

func TestAccAzureRMStorageTable_disappears(t *testing.T) {
	var table storage.Table

	ri := acctest.RandInt()
	rs := strings.ToLower(acctest.RandString(11))
	config := fmt.Sprintf(testAccAzureRMStorageTable_basic, ri, rs, ri)

	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testCheckAzureRMStorageTableDestroy,
		Steps: []resource.TestStep{
			{
				Config: config,
				Check: resource.ComposeTestCheckFunc(
					testCheckAzureRMStorageTableExists("azurerm_storage_table.test", &table),
					testAccARMStorageTableDisappears("azurerm_storage_table.test", &table),
				),
				ExpectNonEmptyPlan: true,
			},
		},
	})
}

func testCheckAzureRMStorageTableExists(name string, t *storage.Table) resource.TestCheckFunc {
	return func(s *terraform.State) error {

		rs, ok := s.RootModule().Resources[name]
		if !ok {
			return fmt.Errorf("Not found: %s", name)
		}

		name := rs.Primary.Attributes["name"]
		storageAccountName := rs.Primary.Attributes["storage_account_name"]
		resourceGroup, hasResourceGroup := rs.Primary.Attributes["resource_group_name"]
		if !hasResourceGroup {
			return fmt.Errorf("Bad: no resource group found in state for storage table: %s", name)
		}

		armClient := testAccProvider.Meta().(*ArmClient)
		tableClient, accountExists, err := armClient.getTableServiceClientForStorageAccount(resourceGroup, storageAccountName)
		if err != nil {
			return err
		}
		if !accountExists {
			return fmt.Errorf("Bad: Storage Account %q does not exist", storageAccountName)
		}

		options := &storage.QueryTablesOptions{}
		tables, err := tableClient.QueryTables(storage.MinimalMetadata, options)

		if len(tables.Tables) == 0 {
			return fmt.Errorf("Bad: Storage Table %q (storage account: %q) does not exist", name, storageAccountName)
		}

		var found bool
		for _, table := range tables.Tables {
			if table.Name == name {
				found = true
				*t = table
			}
		}

		if !found {
			return fmt.Errorf("Bad: Storage Table %q (storage account: %q) does not exist", name, storageAccountName)
		}

		return nil
	}
}

func testAccARMStorageTableDisappears(name string, t *storage.Table) resource.TestCheckFunc {
	return func(s *terraform.State) error {
		rs, ok := s.RootModule().Resources[name]
		if !ok {
			return fmt.Errorf("Not found: %s", name)
		}

		armClient := testAccProvider.Meta().(*ArmClient)

		storageAccountName := rs.Primary.Attributes["storage_account_name"]
		resourceGroup, hasResourceGroup := rs.Primary.Attributes["resource_group_name"]
		if !hasResourceGroup {
			return fmt.Errorf("Bad: no resource group found in state for storage table: %s", t.Name)
		}

		tableClient, accountExists, err := armClient.getTableServiceClientForStorageAccount(resourceGroup, storageAccountName)
		if err != nil {
			return err
		}
		if !accountExists {
			log.Printf("[INFO]Storage Account %q doesn't exist so the table won't exist", storageAccountName)
			return nil
		}

		table := tableClient.GetTableReference(t.Name)
		timeout := uint(60)
		options := &storage.TableOptions{}
		err = table.Delete(timeout, options)
		if err != nil {
			return err
		}

		return nil
	}
}

func testCheckAzureRMStorageTableDestroy(s *terraform.State) error {
	for _, rs := range s.RootModule().Resources {
		if rs.Type != "azurerm_storage_table" {
			continue
		}

		name := rs.Primary.Attributes["name"]
		storageAccountName := rs.Primary.Attributes["storage_account_name"]
		resourceGroup, hasResourceGroup := rs.Primary.Attributes["resource_group_name"]
		if !hasResourceGroup {
			return fmt.Errorf("Bad: no resource group found in state for storage table: %s", name)
		}

		armClient := testAccProvider.Meta().(*ArmClient)
		tableClient, accountExists, err := armClient.getTableServiceClientForStorageAccount(resourceGroup, storageAccountName)
		if err != nil {
			//If we can't get keys then the table can't exist
			return nil
		}
		if !accountExists {
			return nil
		}

		options := &storage.QueryTablesOptions{}
		tables, err := tableClient.QueryTables(storage.NoMetadata, options)

		if err != nil {
			return nil
		}

		var found bool
		for _, table := range tables.Tables {
			if table.Name == name {
				found = true
			}
		}

		if found {
			return fmt.Errorf("Bad: Storage Table %q (storage account: %q) still exist", name, storageAccountName)
		}
	}

	return nil
}

func TestValidateArmStorageTableName(t *testing.T) {
	validNames := []string{
		"mytable01",
		"mytable",
		"myTable",
		"MYTABLE",
	}
	for _, v := range validNames {
		_, errors := validateArmStorageTableName(v, "name")
		if len(errors) != 0 {
			t.Fatalf("%q should be a valid Storage Table Name: %q", v, errors)
		}
	}

	invalidNames := []string{
		"table",
		"-invalidname1",
		"invalid_name",
		"invalid!",
		"ww",
		strings.Repeat("w", 65),
	}
	for _, v := range invalidNames {
		_, errors := validateArmStorageTableName(v, "name")
		if len(errors) == 0 {
			t.Fatalf("%q should be an invalid Storage Table Name", v)
		}
	}
}

var testAccAzureRMStorageTable_basic = `
resource "azurerm_resource_group" "test" {
    name = "acctestRG-%d"
    location = "westus"
}

resource "azurerm_storage_account" "test" {
    name = "acctestacc%s"
    resource_group_name = "${azurerm_resource_group.test.name}"
    location = "westus"
    account_type = "Standard_LRS"

    tags {
        environment = "staging"
    }
}

resource "azurerm_storage_table" "test" {
    name = "tfacceptancetest%d"
    resource_group_name = "${azurerm_resource_group.test.name}"
    storage_account_name = "${azurerm_storage_account.test.name}"
}
`
<commit_msg>Add some boundary tests around storage table name length requirements.<commit_after>package azurerm

import (
	"fmt"
	"log"
	"strings"
	"testing"

	"github.com/Azure/azure-sdk-for-go/storage"
	"github.com/hashicorp/terraform/helper/acctest"
	"github.com/hashicorp/terraform/helper/resource"
	"github.com/hashicorp/terraform/terraform"
)

func TestAccAzureRMStorageTable_basic(t *testing.T) {
	var table storage.Table

	ri := acctest.RandInt()
	rs := strings.ToLower(acctest.RandString(11))
	config := fmt.Sprintf(testAccAzureRMStorageTable_basic, ri, rs, ri)

	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testCheckAzureRMStorageTableDestroy,
		Steps: []resource.TestStep{
			{
				Config: config,
				Check: resource.ComposeTestCheckFunc(
					testCheckAzureRMStorageTableExists("azurerm_storage_table.test", &table),
				),
			},
		},
	})
}

func TestAccAzureRMStorageTable_disappears(t *testing.T) {
	var table storage.Table

	ri := acctest.RandInt()
	rs := strings.ToLower(acctest.RandString(11))
	config := fmt.Sprintf(testAccAzureRMStorageTable_basic, ri, rs, ri)

	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testCheckAzureRMStorageTableDestroy,
		Steps: []resource.TestStep{
			{
				Config: config,
				Check: resource.ComposeTestCheckFunc(
					testCheckAzureRMStorageTableExists("azurerm_storage_table.test", &table),
					testAccARMStorageTableDisappears("azurerm_storage_table.test", &table),
				),
				ExpectNonEmptyPlan: true,
			},
		},
	})
}

func testCheckAzureRMStorageTableExists(name string, t *storage.Table) resource.TestCheckFunc {
	return func(s *terraform.State) error {

		rs, ok := s.RootModule().Resources[name]
		if !ok {
			return fmt.Errorf("Not found: %s", name)
		}

		name := rs.Primary.Attributes["name"]
		storageAccountName := rs.Primary.Attributes["storage_account_name"]
		resourceGroup, hasResourceGroup := rs.Primary.Attributes["resource_group_name"]
		if !hasResourceGroup {
			return fmt.Errorf("Bad: no resource group found in state for storage table: %s", name)
		}

		armClient := testAccProvider.Meta().(*ArmClient)
		tableClient, accountExists, err := armClient.getTableServiceClientForStorageAccount(resourceGroup, storageAccountName)
		if err != nil {
			return err
		}
		if !accountExists {
			return fmt.Errorf("Bad: Storage Account %q does not exist", storageAccountName)
		}

		options := &storage.QueryTablesOptions{}
		tables, err := tableClient.QueryTables(storage.MinimalMetadata, options)

		if len(tables.Tables) == 0 {
			return fmt.Errorf("Bad: Storage Table %q (storage account: %q) does not exist", name, storageAccountName)
		}

		var found bool
		for _, table := range tables.Tables {
			if table.Name == name {
				found = true
				*t = table
			}
		}

		if !found {
			return fmt.Errorf("Bad: Storage Table %q (storage account: %q) does not exist", name, storageAccountName)
		}

		return nil
	}
}

func testAccARMStorageTableDisappears(name string, t *storage.Table) resource.TestCheckFunc {
	return func(s *terraform.State) error {
		rs, ok := s.RootModule().Resources[name]
		if !ok {
			return fmt.Errorf("Not found: %s", name)
		}

		armClient := testAccProvider.Meta().(*ArmClient)

		storageAccountName := rs.Primary.Attributes["storage_account_name"]
		resourceGroup, hasResourceGroup := rs.Primary.Attributes["resource_group_name"]
		if !hasResourceGroup {
			return fmt.Errorf("Bad: no resource group found in state for storage table: %s", t.Name)
		}

		tableClient, accountExists, err := armClient.getTableServiceClientForStorageAccount(resourceGroup, storageAccountName)
		if err != nil {
			return err
		}
		if !accountExists {
			log.Printf("[INFO]Storage Account %q doesn't exist so the table won't exist", storageAccountName)
			return nil
		}

		table := tableClient.GetTableReference(t.Name)
		timeout := uint(60)
		options := &storage.TableOptions{}
		err = table.Delete(timeout, options)
		if err != nil {
			return err
		}

		return nil
	}
}

func testCheckAzureRMStorageTableDestroy(s *terraform.State) error {
	for _, rs := range s.RootModule().Resources {
		if rs.Type != "azurerm_storage_table" {
			continue
		}

		name := rs.Primary.Attributes["name"]
		storageAccountName := rs.Primary.Attributes["storage_account_name"]
		resourceGroup, hasResourceGroup := rs.Primary.Attributes["resource_group_name"]
		if !hasResourceGroup {
			return fmt.Errorf("Bad: no resource group found in state for storage table: %s", name)
		}

		armClient := testAccProvider.Meta().(*ArmClient)
		tableClient, accountExists, err := armClient.getTableServiceClientForStorageAccount(resourceGroup, storageAccountName)
		if err != nil {
			//If we can't get keys then the table can't exist
			return nil
		}
		if !accountExists {
			return nil
		}

		options := &storage.QueryTablesOptions{}
		tables, err := tableClient.QueryTables(storage.NoMetadata, options)

		if err != nil {
			return nil
		}

		var found bool
		for _, table := range tables.Tables {
			if table.Name == name {
				found = true
			}
		}

		if found {
			return fmt.Errorf("Bad: Storage Table %q (storage account: %q) still exist", name, storageAccountName)
		}
	}

	return nil
}

func TestValidateArmStorageTableName(t *testing.T) {
	validNames := []string{
		"mytable01",
		"mytable",
		"myTable",
		"MYTABLE",
		"tbl",
		strings.Repeat("w", 63),
	}
	for _, v := range validNames {
		_, errors := validateArmStorageTableName(v, "name")
		if len(errors) != 0 {
			t.Fatalf("%q should be a valid Storage Table Name: %q", v, errors)
		}
	}

	invalidNames := []string{
		"table",
		"-invalidname1",
		"invalid_name",
		"invalid!",
		"ww",
		strings.Repeat("w", 64),
	}
	for _, v := range invalidNames {
		_, errors := validateArmStorageTableName(v, "name")
		if len(errors) == 0 {
			t.Fatalf("%q should be an invalid Storage Table Name", v)
		}
	}
}

var testAccAzureRMStorageTable_basic = `
resource "azurerm_resource_group" "test" {
    name = "acctestRG-%d"
    location = "westus"
}

resource "azurerm_storage_account" "test" {
    name = "acctestacc%s"
    resource_group_name = "${azurerm_resource_group.test.name}"
    location = "westus"
    account_type = "Standard_LRS"

    tags {
        environment = "staging"
    }
}

resource "azurerm_storage_table" "test" {
    name = "tfacceptancetest%d"
    resource_group_name = "${azurerm_resource_group.test.name}"
    storage_account_name = "${azurerm_storage_account.test.name}"
}
`
<|endoftext|>


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

package main

import (
	"flag"
	"os"
	"runtime"
	"strings"
	"time"

	log "github.com/Sirupsen/logrus"
	"github.com/zmap/zdns"
	_ "github.com/zmap/zdns/modules/a"
	_ "github.com/zmap/zdns/modules/aaaa"
	_ "github.com/zmap/zdns/modules/alookup"
	_ "github.com/zmap/zdns/modules/any"
	_ "github.com/zmap/zdns/modules/axfr"
	_ "github.com/zmap/zdns/modules/caa"
	_ "github.com/zmap/zdns/modules/cname"
	_ "github.com/zmap/zdns/modules/dmarc"
	_ "github.com/zmap/zdns/modules/mx"
	_ "github.com/zmap/zdns/modules/mxlookup"
	_ "github.com/zmap/zdns/modules/ns"
	_ "github.com/zmap/zdns/modules/nslookup"
	_ "github.com/zmap/zdns/modules/ptr"
	_ "github.com/zmap/zdns/modules/soa"
	_ "github.com/zmap/zdns/modules/spf"
	_ "github.com/zmap/zdns/modules/spfrr"
	_ "github.com/zmap/zdns/modules/txt"
	_ "github.com/zmap/zdns/modules/zone"
)

func main() {

	var gc zdns.GlobalConf
	// global flags relevant to every lookup module
	flags := flag.NewFlagSet("flags", flag.ExitOnError)
	flags.IntVar(&gc.Threads, "threads", 1000, "number of lightweight go threads")
	flags.IntVar(&gc.GoMaxProcs, "go-processes", 0, "number of OS processes (GOMAXPROCS)")
	flags.StringVar(&gc.NamePrefix, "prefix", "", "name to be prepended to what's passed in (e.g., www.)")
	flags.BoolVar(&gc.AlexaFormat, "alexa", false, "is input file from Alexa Top Million download")
	flags.StringVar(&gc.InputFilePath, "input-file", "-", "names to read")
	flags.StringVar(&gc.OutputFilePath, "output-file", "-", "comma-delimited list of DNS servers to use")
	flags.StringVar(&gc.MetadataFilePath, "metadata-file", "", "where should JSON metadata be saved")
	flags.StringVar(&gc.LogFilePath, "log-file", "", "where should JSON metadata be saved")
	flags.IntVar(&gc.Verbosity, "verbosity", 3, "log verbosity: 1--5")
	servers_string := flags.String("name-servers", "", "comma-delimited list of DNS servers to use")
	config_file := flags.String("conf-file", "/etc/resolv.conf", "config file for DNS servers")
	timeout := flags.Int("timeout", 10, "timeout for resolving an individual name")
	// allow module to initialize and add its own flags before we parse
	if len(os.Args) < 2 {
		log.Fatal("No lookup module specified. Valid modules: ", zdns.ValidlookupsString())
	}
	gc.Module = strings.ToUpper(os.Args[1])
	factory := zdns.GetLookup(gc.Module)
	if factory == nil {
		log.Fatal("Invalid lookup module specified. Valid modules: ", zdns.ValidlookupsString())
	}
	factory.AddFlags(flags)
	flags.Parse(os.Args[2:])
	// Do some basic sanity checking
	// setup global logging
	if gc.LogFilePath != "" {
		f, err := os.Open(gc.LogFilePath)
		if err != nil {
			log.Fatalf("Unable to open log file (%s): %s", gc.LogFilePath, err.Error())
		}
		log.SetOutput(f)
	}
	// complete post facto global initialization based on command line arguments
	gc.Timeout = time.Duration(time.Second * time.Duration(*timeout))
	if *servers_string == "" {
		// figure out default OS name servers
		ns, err := zdns.GetDNSServers(*config_file)
		if err != nil {
			log.Fatal("Unable to fetch correct name servers:", err.Error())
		}
		gc.NameServers = ns
		gc.NameServersSpecified = false
		log.Info("no name servers specified. will use: ", strings.Join(gc.NameServers, ", "))
	} else {
		gc.NameServers = strings.Split(*servers_string, ",")
		gc.NameServersSpecified = true
	}
	if gc.GoMaxProcs < 0 {
		log.Fatal("Invalid argument for --go-processes. Must be >1.")
	}
	if gc.GoMaxProcs != 0 {
		runtime.GOMAXPROCS(gc.GoMaxProcs)
	}
	// some modules require multiple passes over a file (this is really just the case for zone files)
	if !factory.AllowStdIn() && gc.InputFilePath == "-" {
		log.Fatal("Specified module does not allow reading from stdin")
	}

	// allow the factory to initialize itself
	if err := factory.Initialize(&gc); err != nil {
		log.Fatal("Factory was unable to initialize:", err.Error())
	}
	// run it.
	if err := zdns.DoLookups(&factory, &gc); err != nil {
		log.Fatal("Unable to run lookups:", err.Error())
	}
	// allow the factory to initialize itself
	if err := factory.Finalize(); err != nil {
		log.Fatal("Factory was unable to finalize:", err.Error())
	}
}
<commit_msg>set log verbosity<commit_after>/*
 * ZDNS Copyright 2016 Regents of the University of Michigan
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy
 * of the License at http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 * implied. See the License for the specific language governing
 * permissions and limitations under the License.
 */

package main

import (
	"flag"
	"os"
	"runtime"
	"strings"
	"time"

	log "github.com/Sirupsen/logrus"
	"github.com/zmap/zdns"
	_ "github.com/zmap/zdns/modules/a"
	_ "github.com/zmap/zdns/modules/aaaa"
	_ "github.com/zmap/zdns/modules/alookup"
	_ "github.com/zmap/zdns/modules/any"
	_ "github.com/zmap/zdns/modules/axfr"
	_ "github.com/zmap/zdns/modules/caa"
	_ "github.com/zmap/zdns/modules/cname"
	_ "github.com/zmap/zdns/modules/dmarc"
	_ "github.com/zmap/zdns/modules/mx"
	_ "github.com/zmap/zdns/modules/mxlookup"
	_ "github.com/zmap/zdns/modules/ns"
	_ "github.com/zmap/zdns/modules/nslookup"
	_ "github.com/zmap/zdns/modules/ptr"
	_ "github.com/zmap/zdns/modules/soa"
	_ "github.com/zmap/zdns/modules/spf"
	_ "github.com/zmap/zdns/modules/spfrr"
	_ "github.com/zmap/zdns/modules/txt"
	_ "github.com/zmap/zdns/modules/zone"
)

func main() {

	var gc zdns.GlobalConf
	// global flags relevant to every lookup module
	flags := flag.NewFlagSet("flags", flag.ExitOnError)
	flags.IntVar(&gc.Threads, "threads", 1000, "number of lightweight go threads")
	flags.IntVar(&gc.GoMaxProcs, "go-processes", 0, "number of OS processes (GOMAXPROCS)")
	flags.StringVar(&gc.NamePrefix, "prefix", "", "name to be prepended to what's passed in (e.g., www.)")
	flags.BoolVar(&gc.AlexaFormat, "alexa", false, "is input file from Alexa Top Million download")
	flags.StringVar(&gc.InputFilePath, "input-file", "-", "names to read")
	flags.StringVar(&gc.OutputFilePath, "output-file", "-", "comma-delimited list of DNS servers to use")
	flags.StringVar(&gc.MetadataFilePath, "metadata-file", "", "where should JSON metadata be saved")
	flags.StringVar(&gc.LogFilePath, "log-file", "", "where should JSON metadata be saved")
	flags.IntVar(&gc.Verbosity, "verbosity", 3, "log verbosity: 1 (lowest)--5 (highest)")
	servers_string := flags.String("name-servers", "", "comma-delimited list of DNS servers to use")
	config_file := flags.String("conf-file", "/etc/resolv.conf", "config file for DNS servers")
	timeout := flags.Int("timeout", 10, "timeout for resolving an individual name")
	// allow module to initialize and add its own flags before we parse
	if len(os.Args) < 2 {
		log.Fatal("No lookup module specified. Valid modules: ", zdns.ValidlookupsString())
	}
	gc.Module = strings.ToUpper(os.Args[1])
	factory := zdns.GetLookup(gc.Module)
	if factory == nil {
		log.Fatal("Invalid lookup module specified. Valid modules: ", zdns.ValidlookupsString())
	}
	factory.AddFlags(flags)
	flags.Parse(os.Args[2:])
	// Do some basic sanity checking
	// setup global logging
	if gc.LogFilePath != "" {
		f, err := os.Open(gc.LogFilePath)
		if err != nil {
			log.Fatalf("Unable to open log file (%s): %s", gc.LogFilePath, err.Error())
		}
		log.SetOutput(f)
	}
	// Translate the assigned verbosity level to a logrus log level.
	switch gc.Verbosity {
	case 1: // Fatal
		log.SetLevel(log.FatalLevel)
	case 2: // Error
		log.SetLevel(log.ErrorLevel)
	case 3: // Warnings
		log.SetLevel(log.WarnLevel)
	case 4: // Information (default)
		log.SetLevel(log.InfoLevel)
	case 5: // Debugging
		log.SetLevel(log.DebugLevel)
	default:
		log.Fatal("Unknown verbosity level specified. Must be between 1 (lowest)--5 (highest)")
	}
	// complete post facto global initialization based on command line arguments
	gc.Timeout = time.Duration(time.Second * time.Duration(*timeout))
	if *servers_string == "" {
		// figure out default OS name servers
		ns, err := zdns.GetDNSServers(*config_file)
		if err != nil {
			log.Fatal("Unable to fetch correct name servers:", err.Error())
		}
		gc.NameServers = ns
		gc.NameServersSpecified = false
		log.Info("no name servers specified. will use: ", strings.Join(gc.NameServers, ", "))
	} else {
		gc.NameServers = strings.Split(*servers_string, ",")
		gc.NameServersSpecified = true
	}
	if gc.GoMaxProcs < 0 {
		log.Fatal("Invalid argument for --go-processes. Must be >1.")
	}
	if gc.GoMaxProcs != 0 {
		runtime.GOMAXPROCS(gc.GoMaxProcs)
	}
	// some modules require multiple passes over a file (this is really just the case for zone files)
	if !factory.AllowStdIn() && gc.InputFilePath == "-" {
		log.Fatal("Specified module does not allow reading from stdin")
	}

	// allow the factory to initialize itself
	if err := factory.Initialize(&gc); err != nil {
		log.Fatal("Factory was unable to initialize:", err.Error())
	}
	// run it.
	if err := zdns.DoLookups(&factory, &gc); err != nil {
		log.Fatal("Unable to run lookups:", err.Error())
	}
	// allow the factory to initialize itself
	if err := factory.Finalize(); err != nil {
		log.Fatal("Factory was unable to finalize:", err.Error())
	}
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"github.com/alexjohnj/flasher/tbutils"
	"github.com/codegangsta/cli"
	"github.com/nsf/termbox-go"
	"log"
	"os"
)

func main() {
	app := cli.NewApp()
	app.Name = "flasher"
	app.Version = "0.3.0-DEV"
	app.Author = "Alex Jackson"
	app.Email = "alex@alexj.org"

	app.Commands = []cli.Command{
		{
			Name:      "flash",
			ShortName: "f",
			Usage:     "flasher flash [flashcard-file.json]",
			Action:    cliFlash,
			Flags: []cli.Flag{
				cli.BoolFlag{
					Name:  "no-shuffle, n",
					Usage: "Presents flashcards in the order they are written in the source JSON file.",
				},
			},
		},
		{
			Name:      "info",
			ShortName: "i",
			Usage:     "flasher info [flashcard-file.json]",
			Action:    cliInfo,
		},
	}
	app.Run(os.Args)
}

func cliFlash(c *cli.Context) {
	// Load flashcards

	if len(c.Args()) != 1 {
		log.Printf("Incorrect usage\n")
		cli.ShowCommandHelp(c, "flash")
		os.Exit(1)
	}

	flashcardStack := new(cardStack)
	err := flashcardStack.loadFlashcardStack(c.Args()[0])

	if err != nil {
		log.Fatal(err)
	}

	if !c.Bool("no-shuffle") {
		flashcardStack.shuffle()
	}

	// Init termbox
	err = termbox.Init()
	if err != nil {
		panic(err)
	}
	defer termbox.Close()
	drawAll(flashcardStack)

	//Main Run loop
mainloop:
	for {
		switch event := termbox.PollEvent(); event.Type {
		case termbox.EventKey:
			switch event.Key {
			case termbox.KeyEsc, termbox.KeyCtrlC:
				break mainloop
			case termbox.KeyEnter, termbox.KeyArrowRight:
				flashcardStack.advanceStack()
				drawAll(flashcardStack)
			case termbox.KeyBackspace2, termbox.KeyArrowLeft:
				flashcardStack.revertStack()
				drawAll(flashcardStack)
			}
		case termbox.EventResize:
			drawAll(flashcardStack)
		}
		drawAll(flashcardStack)
	}
}

func cliInfo(c *cli.Context) {
	if len(c.Args()) != 1 {
		log.Printf("Incorrect usage\n")
		cli.ShowCommandHelp(c, "info")
		os.Exit(1)
	}

	flashcardStack := new(cardStack)
	err := flashcardStack.loadFlashcardStack(c.Args()[0])

	if err != nil {
		log.Fatalf("%s is an invalid file: %s", c.Args()[0], err.Error())
	}

	fmt.Printf("Deck Name: %s\nAuthor: %s\nNumber of Cards: %d\n", flashcardStack.Title, flashcardStack.Author, len(flashcardStack.Flashcards))
}

func drawAll(stack *cardStack) {
	termbox.Clear(termbox.ColorDefault, termbox.ColorDefault)
	w, h := termbox.Size()
	endOfStack := stack.StackIndex+1 == len(stack.Flashcards) && stack.ShowAnswer

	// Draw termbox border
	termbox.SetCell(0, 0, '+', termbox.ColorDefault, termbox.ColorDefault)
	termbox.SetCell(w-1, 0, '+', termbox.ColorDefault, termbox.ColorDefault)
	termbox.SetCell(0, h-1, '+', termbox.ColorDefault, termbox.ColorDefault)
	termbox.SetCell(w-1, h-1, '+', termbox.ColorDefault, termbox.ColorDefault)

	for x := 1; x < w-1; x++ {
		termbox.SetCell(x, 0, '-', termbox.ColorDefault, termbox.ColorDefault)
		termbox.SetCell(x, h-1, '-', termbox.ColorDefault, termbox.ColorDefault)
	}

	// Draw the Stack's title
	titleXCoord := tbutils.CalculateXCenterCoord(stack.Title)
	tbutils.DrawText(titleXCoord, 1, stack.Title)

	// Draw the current card
	currentQuestion := stack.getCurrentFlashcard()
	currentQuestion.drawQuestion()
	if stack.ShowAnswer {
		currentQuestion.drawAnswer()
		// Draw the Q/A divider
		for x := 0; x < w; x++ {
			termbox.SetCell(x, (3 * h / 8), '-', termbox.ColorBlue, termbox.ColorDefault)
		}
	}

	// Draw end of stack message
	if endOfStack {
		endOfStackMessageLine1 := "End of Stack..."
		endOfStackMessageLine2 := "(q)Quit (r)Restart (x)Reshuffle & Restart."
		eosXCoord1, eosYCoord1 := tbutils.CalculateXCenterCoord(endOfStackMessageLine1), (3 * (h / 4))
		eosXCoord2, eosYCoord2 := tbutils.CalculateXCenterCoord(endOfStackMessageLine2), (3*h/4)+1
		tbutils.DrawText(eosXCoord1, eosYCoord1, endOfStackMessageLine1)
		tbutils.DrawText(eosXCoord2, eosYCoord2, endOfStackMessageLine2)
	}

	// Draw the current index
	indexStr := fmt.Sprintf("(%d/%d)", stack.StackIndex+1, len(stack.Flashcards))
	indexXCoord, indexYCoord := tbutils.CalculateXCenterCoord(indexStr), h-1
	tbutils.DrawText(indexXCoord, indexYCoord, indexStr)

	// Write out the back buffer
	termbox.Flush()
}
<commit_msg>The 'q' key will now quit flasher<commit_after>package main

import (
	"fmt"
	"github.com/alexjohnj/flasher/tbutils"
	"github.com/codegangsta/cli"
	"github.com/nsf/termbox-go"
	"log"
	"os"
)

func main() {
	app := cli.NewApp()
	app.Name = "flasher"
	app.Version = "0.3.0-DEV"
	app.Author = "Alex Jackson"
	app.Email = "alex@alexj.org"

	app.Commands = []cli.Command{
		{
			Name:      "flash",
			ShortName: "f",
			Usage:     "flasher flash [flashcard-file.json]",
			Action:    cliFlash,
			Flags: []cli.Flag{
				cli.BoolFlag{
					Name:  "no-shuffle, n",
					Usage: "Presents flashcards in the order they are written in the source JSON file.",
				},
			},
		},
		{
			Name:      "info",
			ShortName: "i",
			Usage:     "flasher info [flashcard-file.json]",
			Action:    cliInfo,
		},
	}
	app.Run(os.Args)
}

func cliFlash(c *cli.Context) {
	// Load flashcards

	if len(c.Args()) != 1 {
		log.Printf("Incorrect usage\n")
		cli.ShowCommandHelp(c, "flash")
		os.Exit(1)
	}

	flashcardStack := new(cardStack)
	err := flashcardStack.loadFlashcardStack(c.Args()[0])

	if err != nil {
		log.Fatal(err)
	}

	if !c.Bool("no-shuffle") {
		flashcardStack.shuffle()
	}

	// Init termbox
	err = termbox.Init()
	if err != nil {
		panic(err)
	}
	defer termbox.Close()
	drawAll(flashcardStack)

	//Main Run loop
mainloop:
	for {
		switch event := termbox.PollEvent(); event.Type {
		case termbox.EventKey:
			switch event.Key {
			case termbox.KeyEsc, termbox.KeyCtrlC:
				break mainloop
			case termbox.KeyEnter, termbox.KeyArrowRight:
				flashcardStack.advanceStack()
				drawAll(flashcardStack)
			case termbox.KeyBackspace2, termbox.KeyArrowLeft:
				flashcardStack.revertStack()
				drawAll(flashcardStack)
			}

			switch event.Ch {
			case 'q':
				break mainloop
			}

		case termbox.EventResize:
			drawAll(flashcardStack)
		}
		drawAll(flashcardStack)
	}
}

func cliInfo(c *cli.Context) {
	if len(c.Args()) != 1 {
		log.Printf("Incorrect usage\n")
		cli.ShowCommandHelp(c, "info")
		os.Exit(1)
	}

	flashcardStack := new(cardStack)
	err := flashcardStack.loadFlashcardStack(c.Args()[0])

	if err != nil {
		log.Fatalf("%s is an invalid file: %s", c.Args()[0], err.Error())
	}

	fmt.Printf("Deck Name: %s\nAuthor: %s\nNumber of Cards: %d\n", flashcardStack.Title, flashcardStack.Author, len(flashcardStack.Flashcards))
}

func drawAll(stack *cardStack) {
	termbox.Clear(termbox.ColorDefault, termbox.ColorDefault)
	w, h := termbox.Size()
	endOfStack := stack.StackIndex+1 == len(stack.Flashcards) && stack.ShowAnswer

	// Draw termbox border
	termbox.SetCell(0, 0, '+', termbox.ColorDefault, termbox.ColorDefault)
	termbox.SetCell(w-1, 0, '+', termbox.ColorDefault, termbox.ColorDefault)
	termbox.SetCell(0, h-1, '+', termbox.ColorDefault, termbox.ColorDefault)
	termbox.SetCell(w-1, h-1, '+', termbox.ColorDefault, termbox.ColorDefault)

	for x := 1; x < w-1; x++ {
		termbox.SetCell(x, 0, '-', termbox.ColorDefault, termbox.ColorDefault)
		termbox.SetCell(x, h-1, '-', termbox.ColorDefault, termbox.ColorDefault)
	}

	// Draw the Stack's title
	titleXCoord := tbutils.CalculateXCenterCoord(stack.Title)
	tbutils.DrawText(titleXCoord, 1, stack.Title)

	// Draw the current card
	currentQuestion := stack.getCurrentFlashcard()
	currentQuestion.drawQuestion()
	if stack.ShowAnswer {
		currentQuestion.drawAnswer()
		// Draw the Q/A divider
		for x := 0; x < w; x++ {
			termbox.SetCell(x, (3 * h / 8), '-', termbox.ColorBlue, termbox.ColorDefault)
		}
	}

	// Draw end of stack message
	if endOfStack {
		endOfStackMessageLine1 := "End of Stack..."
		endOfStackMessageLine2 := "(q)Quit (r)Restart (x)Reshuffle & Restart."
		eosXCoord1, eosYCoord1 := tbutils.CalculateXCenterCoord(endOfStackMessageLine1), (3 * (h / 4))
		eosXCoord2, eosYCoord2 := tbutils.CalculateXCenterCoord(endOfStackMessageLine2), (3*h/4)+1
		tbutils.DrawText(eosXCoord1, eosYCoord1, endOfStackMessageLine1)
		tbutils.DrawText(eosXCoord2, eosYCoord2, endOfStackMessageLine2)
	}

	// Draw the current index
	indexStr := fmt.Sprintf("(%d/%d)", stack.StackIndex+1, len(stack.Flashcards))
	indexXCoord, indexYCoord := tbutils.CalculateXCenterCoord(indexStr), h-1
	tbutils.DrawText(indexXCoord, indexYCoord, indexStr)

	// Write out the back buffer
	termbox.Flush()
}
<|endoftext|>


<commit_before>package jet

import (
	_ "github.com/bmizerany/pq"
	"testing"
)

func TestQuery(t *testing.T) {
	db, err := Open("postgres", "user=jet dbname=jet sslmode=disable")
	if err != nil {
		t.Fatalf(err.Error())
	}
	err = db.Exec(`DROP TABLE IF EXISTS "table"`)
	if err != nil {
		t.Fatal(err.Error())
	}
	err = db.Exec(`CREATE TABLE "table" ( "a" text, "b" integer )`)
	if err != nil {
		t.Fatal(err.Error())
	}
	var mv map[string]interface{}
	err = db.Query(&mv, `INSERT INTO "table" ( "a", "b" ) VALUES ( $1, $2 ) RETURNING "a"`, "hello", 7)
	if err != nil {
		t.Fatal(err.Error())
	}
	x, ok := mv["a"].([]uint8)
	if !ok || string(x) != "hello" {
		t.Fatal(x)
	}
	var sv struct{ A string }
	err = db.Query(&sv, `INSERT INTO "table" ( "a", "b" ) VALUES ( $1, $2 ) RETURNING "a"`, "hello2", 8)
	if err != nil {
		t.Fatal(err.Error())
	}
	if x := sv.A; x != "hello2" {
		t.Fatal(x)
	}
}
<commit_msg>test select<commit_after>package jet

import (
	_ "github.com/bmizerany/pq"
	"testing"
)

func TestQuery(t *testing.T) {
	db, err := Open("postgres", "user=jet dbname=jet sslmode=disable")
	if err != nil {
		t.Fatalf(err.Error())
	}
	err = db.Exec(`DROP TABLE IF EXISTS "table"`)
	if err != nil {
		t.Fatal(err.Error())
	}
	err = db.Exec(`CREATE TABLE "table" ( "a" text, "b" integer )`)
	if err != nil {
		t.Fatal(err.Error())
	}
	var mv map[string]interface{}
	err = db.Query(&mv, `INSERT INTO "table" ( "a", "b" ) VALUES ( $1, $2 ) RETURNING "a"`, "hello", 7)
	if err != nil {
		t.Fatal(err.Error())
	}
	x, ok := mv["a"].([]uint8)
	if !ok || string(x) != "hello" {
		t.Fatal(x)
	}
	var sv struct{ A string }
	err = db.Query(&sv, `INSERT INTO "table" ( "a", "b" ) VALUES ( $1, $2 ) RETURNING "a"`, "hello2", 8)
	if err != nil {
		t.Fatal(err.Error())
	}
	if x := sv.A; x != "hello2" {
		t.Fatal(x)
	}
	type data struct {
		A string
		B int64
	}
	var sv2 []data
	err = db.Query(&sv2, `SELECT * FROM "table"`)
	if err != nil {
		t.Fatal(err.Error())
	}
	if x := len(sv2); x != 2 {
		t.Fatal(x)
	}
	if x := sv2[0]; x.A != "hello" || x.B != 7 {
		t.Fatal(x)
	}
	if x := sv2[1]; x.A != "hello2" || x.B != 8 {
		t.Fatal(x)
	}
}
<|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.

// Govet is a simple checker for static errors in Go source code.
// See doc.go for more information.
package main

import (
	"bytes"
	"flag"
	"fmt"
	"io"
	"go/ast"
	"go/parser"
	"go/token"
	"os"
	"strconv"
	"strings"
)

var verbose = flag.Bool("v", false, "verbose")
var printfuncs = flag.String("printfuncs", "", "comma-separated list of print function names to check")
var exitCode = 0

// Usage is a replacement usage function for the flags package.
func Usage() {
	fmt.Fprintf(os.Stderr, "Usage of %s:\n", os.Args[0])
	flag.PrintDefaults()
	os.Exit(2)
}

// File is a wrapper for the state of a file used in the parser.
// The parse tree walkers are all methods of this type.
type File struct {
	file *token.File
}

func main() {
	flag.Usage = Usage
	flag.Parse()

	if *printfuncs != "" {
		for _, name := range strings.Split(*printfuncs, ",", -1) {
			if len(name) == 0 {
				flag.Usage()
			}
			skip := 0
			if colon := strings.LastIndex(name, ":"); colon > 0 {
				var err os.Error
				skip, err = strconv.Atoi(name[colon+1:])
				if err != nil {
					die(`illegal format for "Func:N" argument %q; %s`, name, err)
				}
				name = name[:colon]
			}
			if name[len(name)-1] == 'f' {
				printfList[name] = skip
			} else {
				printList[name] = skip
			}
		}
	}

	if flag.NArg() == 0 {
		doFile("stdin", os.Stdin)
	} else {
		for _, arg := range flag.Args() {
			doFile(arg, nil)
		}
	}
	os.Exit(exitCode)
}

// doFile analyzes one file.  If the reader is nil, the source code is read from the
// named file.
func doFile(name string, reader io.Reader) {
	// TODO: process directories?
	fs := token.NewFileSet()
	parsedFile, err := parser.ParseFile(fs, name, reader, 0)
	if err != nil {
		die("%s: %s", name, err)
	}
	file := &File{fs.File(parsedFile.Pos())}
	file.checkFile(name, parsedFile)
}

// die formats the error to standard error, adding program identification
// and a newline, and exits the program.
func die(format string, args ...interface{}) {
	fmt.Fprintf(os.Stderr, "govet: "+format+"\n", args...)
	os.Exit(2)
}

// Println is fmt.Println guarded by -v.
func Println(args ...interface{}) {
	if !*verbose {
		return
	}
	fmt.Println(args...)
}

// Printf is fmt.Printf guarded by -v.
func Printf(format string, args ...interface{}) {
	if !*verbose {
		return
	}
	fmt.Printf(format+"\n", args...)
}

// Bad reports an error and sets the exit code..
func (f *File) Bad(pos token.Pos, args ...interface{}) {
	f.Warn(pos, args...)
	exitCode = 1
}

// Badf reports a formatted error and sets the exit code.
func (f *File) Badf(pos token.Pos, format string, args ...interface{}) {
	f.Warnf(pos, format, args...)
	exitCode = 1
}

// Warn reports an error but does not set the exit code.
func (f *File) Warn(pos token.Pos, args ...interface{}) {
	loc := f.file.Position(pos).String() + ": "
	fmt.Fprint(os.Stderr, loc+fmt.Sprintln(args...))
}

// Warnf reports a formatted error but does not set the exit code.
func (f *File) Warnf(pos token.Pos, format string, args ...interface{}) {
	loc := f.file.Position(pos).String() + ": "
	fmt.Fprintf(os.Stderr, loc+format+"\n", args...)
}

// checkFile checks all the top-level declarations in a file.
func (f *File) checkFile(name string, file *ast.File) {
	Println("Checking", name)
	ast.Walk(f, file)
}

// Visit implements the ast.Visitor interface.
func (f *File) Visit(node ast.Node) ast.Visitor {
	// TODO: could return nil for nodes that cannot contain a CallExpr -
	// will shortcut traversal.  Worthwhile?
	switch n := node.(type) {
	case *ast.CallExpr:
		f.checkCallExpr(n)
	}
	return f
}

// checkCallExpr checks a call expression.
func (f *File) checkCallExpr(call *ast.CallExpr) {
	switch x := call.Fun.(type) {
	case *ast.Ident:
		f.checkCall(call, x.Name)
	case *ast.SelectorExpr:
		f.checkCall(call, x.Sel.Name)
	}
}

// printfList records the formatted-print functions. The value is the location
// of the format parameter.
var printfList = map[string]int{
	"Errorf":  0,
	"Fatalf":  0,
	"Fprintf": 1,
	"Printf":  0,
	"Sprintf": 0,
}

// printList records the unformatted-print functions. The value is the location
// of the first parameter to be printed.
var printList = map[string]int{
	"Error":  0,
	"Fatal":  0,
	"Fprint": 1, "Fprintln": 1,
	"Print": 0, "Println": 0,
	"Sprint": 0, "Sprintln": 0,
}

// checkCall triggers the print-specific checks if the call invokes a print function.
func (f *File) checkCall(call *ast.CallExpr, name string) {
	if skip, ok := printfList[name]; ok {
		f.checkPrintf(call, name, skip)
		return
	}
	if skip, ok := printList[name]; ok {
		f.checkPrint(call, name, skip)
		return
	}
}

// checkPrintf checks a call to a formatted print routine such as Printf.
// The skip argument records how many arguments to ignore; that is,
// call.Args[skip] is (well, should be) the format argument.
func (f *File) checkPrintf(call *ast.CallExpr, name string, skip int) {
	if len(call.Args) <= skip {
		return
	}
	// Common case: literal is first argument.
	arg := call.Args[skip]
	lit, ok := arg.(*ast.BasicLit)
	if !ok {
		// Too hard to check.
		if *verbose {
			f.Warn(call.Pos(), "can't check args for call to", name)
		}
		return
	}
	if lit.Kind == token.STRING {
		if bytes.IndexByte(lit.Value, '%') < 0 {
			if len(call.Args) > skip+1 {
				f.Badf(call.Pos(), "no formatting directive in %s call", name)
			}
			return
		}
	}
	// Hard part: check formats against args.
	// Trivial but useful test: count.
	numPercent := 0
	for i := 0; i < len(lit.Value); i++ {
		if lit.Value[i] == '%' {
			if i+1 < len(lit.Value) && lit.Value[i+1] == '%' {
				// %% doesn't count.
				i++
			} else {
				numPercent++
			}
		}
	}
	expect := len(call.Args) - (skip + 1)
	if numPercent != expect {
		f.Badf(call.Pos(), "wrong number of formatting directives in %s call: %d percent(s) for %d args", name, numPercent, expect)
	}
}

var terminalNewline = []byte(`\n"`) // \n at end of interpreted string

// checkPrint checks a call to an unformatted print routine such as Println.
// The skip argument records how many arguments to ignore; that is,
// call.Args[skip] is the first argument to be printed.
func (f *File) checkPrint(call *ast.CallExpr, name string, skip int) {
	isLn := strings.HasSuffix(name, "ln")
	args := call.Args
	if len(args) <= skip {
		if *verbose && !isLn {
			f.Badf(call.Pos(), "no args in %s call", name)
		}
		return
	}
	arg := args[skip]
	if lit, ok := arg.(*ast.BasicLit); ok && lit.Kind == token.STRING {
		if bytes.IndexByte(lit.Value, '%') >= 0 {
			f.Badf(call.Pos(), "possible formatting directive in %s call", name)
		}
	}
	if isLn {
		// The last item, if a string, should not have a newline.
		arg = args[len(call.Args)-1]
		if lit, ok := arg.(*ast.BasicLit); ok && lit.Kind == token.STRING {
			if bytes.HasSuffix(lit.Value, terminalNewline) {
				f.Badf(call.Pos(), "%s call ends with newline", name)
			}
		}
	}
}

// This function never executes, but it serves as a simple test for the program.
// Test with govet --funcs="Bad:1,Badf:1,Warn:1,Warnf:1" govet.go
func BadFunctionUsedInTests() {
	fmt.Println()                      // niladic call
	fmt.Println("%s", "hi")            // % in call to Println
	fmt.Printf("%s", "hi", 3)          // wrong # percents
	fmt.Printf("%s%%%d", "hi", 3)      // right # percents
	Printf("now is the time", "buddy") // no %s
	f := new(File)
	f.Warn(0, "%s", "hello", 3)  // % in call to added function
	f.Warnf(0, "%s", "hello", 3) // wrong # %s in call to added function
}
<commit_msg>govet: on error continue to the next file<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.

// Govet is a simple checker for static errors in Go source code.
// See doc.go for more information.
package main

import (
	"bytes"
	"flag"
	"fmt"
	"io"
	"go/ast"
	"go/parser"
	"go/token"
	"os"
	"strconv"
	"strings"
)

var verbose = flag.Bool("v", false, "verbose")
var printfuncs = flag.String("printfuncs", "", "comma-separated list of print function names to check")
var exitCode = 0

// setExit sets the value for os.Exit when it is called, later.  It
// remembers the highest value.
func setExit(err int) {
	if err > exitCode {
		exitCode = err
	}
}

// Usage is a replacement usage function for the flags package.
func Usage() {
	fmt.Fprintf(os.Stderr, "Usage of %s:\n", os.Args[0])
	flag.PrintDefaults()
	os.Exit(2)
}

// File is a wrapper for the state of a file used in the parser.
// The parse tree walkers are all methods of this type.
type File struct {
	file *token.File
}

func main() {
	flag.Usage = Usage
	flag.Parse()

	if *printfuncs != "" {
		for _, name := range strings.Split(*printfuncs, ",", -1) {
			if len(name) == 0 {
				flag.Usage()
			}
			skip := 0
			if colon := strings.LastIndex(name, ":"); colon > 0 {
				var err os.Error
				skip, err = strconv.Atoi(name[colon+1:])
				if err != nil {
					error(`illegal format for "Func:N" argument %q; %s`, name, err)
				}
				name = name[:colon]
			}
			if name[len(name)-1] == 'f' {
				printfList[name] = skip
			} else {
				printList[name] = skip
			}
		}
	}

	if flag.NArg() == 0 {
		doFile("stdin", os.Stdin)
	} else {
		for _, arg := range flag.Args() {
			doFile(arg, nil)
		}
	}
	os.Exit(exitCode)
}

// doFile analyzes one file.  If the reader is nil, the source code is read from the
// named file.
func doFile(name string, reader io.Reader) {
	// TODO: process directories?
	fs := token.NewFileSet()
	parsedFile, err := parser.ParseFile(fs, name, reader, 0)
	if err != nil {
		error("%s: %s", name, err)
		return
	}
	file := &File{fs.File(parsedFile.Pos())}
	file.checkFile(name, parsedFile)
}

// error formats the error to standard error, adding program
// identification and a newline
func error(format string, args ...interface{}) {
	fmt.Fprintf(os.Stderr, "govet: "+format+"\n", args...)
	setExit(2)
}

// Println is fmt.Println guarded by -v.
func Println(args ...interface{}) {
	if !*verbose {
		return
	}
	fmt.Println(args...)
}

// Printf is fmt.Printf guarded by -v.
func Printf(format string, args ...interface{}) {
	if !*verbose {
		return
	}
	fmt.Printf(format+"\n", args...)
}

// Bad reports an error and sets the exit code..
func (f *File) Bad(pos token.Pos, args ...interface{}) {
	f.Warn(pos, args...)
	setExit(1)
}

// Badf reports a formatted error and sets the exit code.
func (f *File) Badf(pos token.Pos, format string, args ...interface{}) {
	f.Warnf(pos, format, args...)
	setExit(1)
}

// Warn reports an error but does not set the exit code.
func (f *File) Warn(pos token.Pos, args ...interface{}) {
	loc := f.file.Position(pos).String() + ": "
	fmt.Fprint(os.Stderr, loc+fmt.Sprintln(args...))
}

// Warnf reports a formatted error but does not set the exit code.
func (f *File) Warnf(pos token.Pos, format string, args ...interface{}) {
	loc := f.file.Position(pos).String() + ": "
	fmt.Fprintf(os.Stderr, loc+format+"\n", args...)
}

// checkFile checks all the top-level declarations in a file.
func (f *File) checkFile(name string, file *ast.File) {
	Println("Checking", name)
	ast.Walk(f, file)
}

// Visit implements the ast.Visitor interface.
func (f *File) Visit(node ast.Node) ast.Visitor {
	// TODO: could return nil for nodes that cannot contain a CallExpr -
	// will shortcut traversal.  Worthwhile?
	switch n := node.(type) {
	case *ast.CallExpr:
		f.checkCallExpr(n)
	}
	return f
}

// checkCallExpr checks a call expression.
func (f *File) checkCallExpr(call *ast.CallExpr) {
	switch x := call.Fun.(type) {
	case *ast.Ident:
		f.checkCall(call, x.Name)
	case *ast.SelectorExpr:
		f.checkCall(call, x.Sel.Name)
	}
}

// printfList records the formatted-print functions. The value is the location
// of the format parameter.
var printfList = map[string]int{
	"Errorf":  0,
	"Fatalf":  0,
	"Fprintf": 1,
	"Printf":  0,
	"Sprintf": 0,
}

// printList records the unformatted-print functions. The value is the location
// of the first parameter to be printed.
var printList = map[string]int{
	"Error":  0,
	"Fatal":  0,
	"Fprint": 1, "Fprintln": 1,
	"Print": 0, "Println": 0,
	"Sprint": 0, "Sprintln": 0,
}

// checkCall triggers the print-specific checks if the call invokes a print function.
func (f *File) checkCall(call *ast.CallExpr, name string) {
	if skip, ok := printfList[name]; ok {
		f.checkPrintf(call, name, skip)
		return
	}
	if skip, ok := printList[name]; ok {
		f.checkPrint(call, name, skip)
		return
	}
}

// checkPrintf checks a call to a formatted print routine such as Printf.
// The skip argument records how many arguments to ignore; that is,
// call.Args[skip] is (well, should be) the format argument.
func (f *File) checkPrintf(call *ast.CallExpr, name string, skip int) {
	if len(call.Args) <= skip {
		return
	}
	// Common case: literal is first argument.
	arg := call.Args[skip]
	lit, ok := arg.(*ast.BasicLit)
	if !ok {
		// Too hard to check.
		if *verbose {
			f.Warn(call.Pos(), "can't check args for call to", name)
		}
		return
	}
	if lit.Kind == token.STRING {
		if bytes.IndexByte(lit.Value, '%') < 0 {
			if len(call.Args) > skip+1 {
				f.Badf(call.Pos(), "no formatting directive in %s call", name)
			}
			return
		}
	}
	// Hard part: check formats against args.
	// Trivial but useful test: count.
	numPercent := 0
	for i := 0; i < len(lit.Value); i++ {
		if lit.Value[i] == '%' {
			if i+1 < len(lit.Value) && lit.Value[i+1] == '%' {
				// %% doesn't count.
				i++
			} else {
				numPercent++
			}
		}
	}
	expect := len(call.Args) - (skip + 1)
	if numPercent != expect {
		f.Badf(call.Pos(), "wrong number of formatting directives in %s call: %d percent(s) for %d args", name, numPercent, expect)
	}
}

var terminalNewline = []byte(`\n"`) // \n at end of interpreted string

// checkPrint checks a call to an unformatted print routine such as Println.
// The skip argument records how many arguments to ignore; that is,
// call.Args[skip] is the first argument to be printed.
func (f *File) checkPrint(call *ast.CallExpr, name string, skip int) {
	isLn := strings.HasSuffix(name, "ln")
	args := call.Args
	if len(args) <= skip {
		if *verbose && !isLn {
			f.Badf(call.Pos(), "no args in %s call", name)
		}
		return
	}
	arg := args[skip]
	if lit, ok := arg.(*ast.BasicLit); ok && lit.Kind == token.STRING {
		if bytes.IndexByte(lit.Value, '%') >= 0 {
			f.Badf(call.Pos(), "possible formatting directive in %s call", name)
		}
	}
	if isLn {
		// The last item, if a string, should not have a newline.
		arg = args[len(call.Args)-1]
		if lit, ok := arg.(*ast.BasicLit); ok && lit.Kind == token.STRING {
			if bytes.HasSuffix(lit.Value, terminalNewline) {
				f.Badf(call.Pos(), "%s call ends with newline", name)
			}
		}
	}
}

// This function never executes, but it serves as a simple test for the program.
// Test with govet --funcs="Bad:1,Badf:1,Warn:1,Warnf:1" govet.go
func BadFunctionUsedInTests() {
	fmt.Println()                      // niladic call
	fmt.Println("%s", "hi")            // % in call to Println
	fmt.Printf("%s", "hi", 3)          // wrong # percents
	fmt.Printf("%s%%%d", "hi", 3)      // right # percents
	Printf("now is the time", "buddy") // no %s
	f := new(File)
	f.Warn(0, "%s", "hello", 3)  // % in call to added function
	f.Warnf(0, "%s", "hello", 3) // wrong # %s in call to added function
}
<|endoftext|>


<commit_before>/*
Copyright 2015 Nodetemple <hostmaster@nodetemple.com>

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 command

import (
	"github.com/codegangsta/cli"
	"github.com/nodetemple/nodetemple/nodectl/util"
)

func DemoCmd() cli.Command{
	return cli.Command{
		Name:  "demo",
		Usage: "a simple `hello world` demo",
		Description: "a simple `hello world` demo\n\twith output of flags, args, etc.",
		Flags: []cli.Flag{
			cli.StringFlag{Name: "demo-flag, d", Value: "", Usage: "demo flag usage"},
			cli.BoolFlag{Name: "demo-bool", Usage: "demo bool usage"},
		},
		Action: func(c *cli.Context) {
			if c.String("demo-flag") == "" {
				util.Err("missing '--demo-flag'")
			} else {
				util.Out("result:\n\targs: %v\n\tprovider: %v\n\tdemo-flag: %v\n\tdemo-bool: %v", c.Args().Get(0), c.GlobalString("provider"), c.String("demo-flag"), c.String("demo-bool"))
			}
		},
	}
}
<commit_msg>Spacing desc<commit_after>/*
Copyright 2015 Nodetemple <hostmaster@nodetemple.com>

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 command

import (
	"github.com/codegangsta/cli"
	"github.com/nodetemple/nodetemple/nodectl/util"
)

func DemoCmd() cli.Command{
	return cli.Command{
		Name:  "demo",
		Usage: "a simple `hello world` demo",
		Description: "a simple `hello world` demo\n   with output of flags, args, etc.",
		Flags: []cli.Flag{
			cli.StringFlag{Name: "demo-flag, d", Value: "", Usage: "demo flag usage"},
			cli.BoolFlag{Name: "demo-bool", Usage: "demo bool usage"},
		},
		Action: func(c *cli.Context) {
			if c.String("demo-flag") == "" {
				util.Err("missing '--demo-flag'")
			} else {
				util.Out("result:\n\targs: %v\n\tprovider: %v\n\tdemo-flag: %v\n\tdemo-bool: %v", c.Args().Get(0), c.GlobalString("provider"), c.String("demo-flag"), c.String("demo-bool"))
			}
		},
	}
}
<|endoftext|>


<commit_before><commit_msg>input/size: define witness constants needed<commit_after><|endoftext|>